Skill · Gestión de Monorepos

Monorepo CULTIVA IA

Arquitectura, configuración y pipelines para el ecosistema de productos digitales de CULTIVA IA usando pnpm workspaces + Turborepo.

Turborepo 1.13 📦pnpm 9 workspaces 🔖Changesets 🏗️3 apps · 5 packages 🚀CI/CD GitHub Actions + Vercel
3
Apps
5
Packages
~85%
Cache Hit Rate
12s
Build incremental
2
Pkgs publicados npm
Estructura del repositorio
cultiva-ia/monorepo
├── apps/← aplicaciones desplegables
├── web/Next.js 14← web marketing principal
├── app/
└── package.json
├── dashboard/Next.js 14← panel de clientes / reporting
├── app/
└── package.json
└── docs/Astro← documentación arsenal skills
├── packages/← código compartido
├── ui/@cultiva/ui← componentes React + Tailwind
├── ai-toolkit/@cultiva/ai-toolkit← wrappers Claude API
├── analytics/@cultiva/analytics← utilidades tracking
├── tsconfig/@cultiva/tsconfig← configs TS compartidas
└── eslint-config/@cultiva/eslint-config← ESLint base
├── turbo.json← pipeline Turborepo
├── package.json← root workspace
├── pnpm-workspace.yaml← declaración de workspaces
├── .changeset/← versionado semántico
└── .github/workflows/← CI/CD
Paquetes del workspace
App
apps/web
Web marketing principal. SSR + ISR, blog de contenido, landing pages de servicios.
Next.js 14 App Router Tailwind
App
apps/dashboard
Panel de clientes. Reporting de campañas, métricas IA, gestión de proyectos activos.
Next.js 14 Recharts tRPC
App
apps/docs
Documentación técnica del arsenal de 2.000+ skills. Búsqueda full-text, categorías.
Astro 4 MDX Pagefind
Package
@cultiva/ui
Librería de componentes compartidos. Button, Card, Badge, Modal, DataTable, Charts.
React 18 tsup Storybook
Package
@cultiva/ai-toolkit
Wrappers sobre Claude API. Streaming, tool use, agentes multi-step, rate limiting.
Anthropic SDK Zod TypeScript
Package
@cultiva/analytics
Utilidades de tracking: eventos GA4, Plausible, atribución de campañas, GTM helpers.
GA4 Plausible TypeScript
Package
@cultiva/tsconfig
Presets TypeScript: base, next, astro, library. Strict mode habilitado en todos.
TypeScript 5 strict
Package
@cultiva/eslint-config
Configuración ESLint base con reglas Next.js, React Hooks, import ordering y accesibilidad.
ESLint 9 Flat Config
Configuraciones clave
turbo.json JSON
{ "$schema": "https://turbo.build/schema.json", "remoteCache": { "enabled": true // cache remota en Vercel }, "pipeline": { "build": { "dependsOn": ["^build"], // deps primero "outputs": [ "dist/**", ".next/**", "!.next/cache/**" ] }, "test": { "dependsOn": ["build"], "outputs": ["coverage/**"] }, "lint": { "outputs": [] // sin output, solo status }, "type-check": { "dependsOn": ["^build"], "outputs": [] }, "dev": { "cache": false, // dev nunca se cachea "persistent": true // proceso continuo } } }
pnpm-workspace.yaml YAML
packages: - "apps/*" - "packages/*"
package.json (root) JSON
{ "name": "cultiva-ia", "private": true, "packageManager": "pnpm@9.4.0", "scripts": { "build": "turbo run build", "dev": "turbo run dev", "test": "turbo run test", "lint": "turbo run lint", "type-check": "turbo run type-check", "release": "changeset publish" }, "devDependencies": { "turbo": "^1.13.0", "@changesets/cli": "^2.27.0", "typescript": "^5.4.0" } }
packages/ui/package.json — @cultiva/ui JSON
{ "name": "@cultiva/ui", "version": "1.2.0", "private": false, // publicado en npm privado "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" }, "./button": { "import": "./dist/button.js", "types": "./dist/button.d.ts" }, "./data-table": { "import": "./dist/data-table.js", "types": "./dist/data-table.d.ts" } }, "scripts": { "build": "tsup src/index.ts --format esm,cjs --dts", "dev": "tsup src/index.ts --format esm,cjs --dts --watch" }, "devDependencies": { "@cultiva/tsconfig": "workspace:*", "tsup": "^8.0.0", "typescript": "^5.4.0" }, "peerDependencies": { "react": "^18.0.0" } }
Pipeline de tareas Turborepo
Tarea Depende de Cache Outputs Modo
build ^build (deps primero) SI dist/** .next/** Paralelo por paquete
test build (mismo paquete) SI coverage/** Paralelo
lint — (ninguna) SI — (solo status) Paralelo
type-check ^build (deps primero) SI — (solo status) Paralelo
dev — (ninguna) NO — (proceso vivo) PERSISTENT
Grafo de dependencias de build
📦
@cultiva/tsconfig
Sin deps
Capa 0
🎨
@cultiva/ui
← tsconfig
Capa 1
🤖
@cultiva/ai-toolkit
← tsconfig
Capa 1
📊
@cultiva/analytics
← tsconfig
Capa 1
🌐
apps/web
← ui, analytics
Capa 2
🏠
apps/dashboard
← ui, ai-toolkit, analytics
Capa 2
📚
apps/docs
← ui
Capa 2
CI/CD — GitHub Actions
.github/workflows/ci.yml YAML
name: CI on: push: branches: [main, develop] pull_request: branches: [main] jobs: build-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v3 with: version: 9 - uses: actions/setup-node@v4 with: node-version: 20 cache: pnpm - name: Install deps run: pnpm install --frozen-lockfile - name: Build + Test (Turbo) run: pnpm turbo run build test lint type-check env: # Cache remota en Vercel TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: cultiva-ia
.github/workflows/release.yml YAML
name: Release on: push: branches: [main] jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: pnpm/action-setup@v3 - run: pnpm install --frozen-lockfile - run: pnpm turbo run build - name: Create Release PR or Publish uses: changesets/action@v1 with: publish: pnpm release title: "chore: release packages" commit: "chore: version packages" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
1

pnpm install --frozen-lockfile

Instala dependencias exactas del lockfile. Node modules cacheados por pnpm action.

2

turbo run build (cache remota)

Builds cacheados en Vercel Remote Cache. Solo reconstruye paquetes afectados por el PR.

3

turbo run test lint type-check

Paralelo. Sólo ejecuta los paquetes que cambiaron vs. caché anterior.

4

changesets/action → PR de release

Crea un PR "Version Packages" automático o publica en npm si el PR se mergea.

Flujo de publicación con Changesets
1. Developer pnpm changeset
2. Commit .changeset feat: new Button variant
3. PR → main changeset/action crea PR
4. Merge release PR bump @cultiva/ui 1.2.0→1.3.0
5. npm publish @cultiva/ui@1.3.0 ✓
Errores frecuentes a evitar
🔄

Dependencias circulares

@cultiva/ui no puede importar @cultiva/ai-toolkit si este importa @cultiva/ui. Usar madge para detectarlas.

👻

Phantom dependencies

Usar una librería instalada en la raíz sin declararla en el package.json del paquete. Siempre declarar explícitamente.

💾

Cache inputs mal configurados

Si .env no está en globalDependencies, cambiar secrets no invalida el cache. Resultado: builds con valores obsoletos.

🔗

workspace:* en producción

Las referencias workspace:* deben reemplazarse por versiones reales antes de publicar. Changesets lo hace automáticamente.

dev sin --filter en repos grandes

pnpm dev arranca todas las apps. Usar turbo run dev --filter=web para levantar solo lo necesario.

📦

tsup sin --dts en paquetes

Sin la flag --dts, los consumidores del paquete no tienen tipos TypeScript. Siempre incluir en el build de packages.

Comandos de referencia rápida
Comandos frecuentes BASH
# ─── DESARROLLO ───────────────────────────────────────────────────── pnpm dev # arranca todas las apps en paralelo pnpm dev --filter=web # solo apps/web pnpm dev --filter=dashboard # solo el dashboard # ─── BUILD ────────────────────────────────────────────────────────── pnpm build # build de todo (Turborepo, cacheado) pnpm build --filter=@cultiva/ui # solo el paquete UI # ─── TESTS ────────────────────────────────────────────────────────── pnpm test # tests de todo el monorepo pnpm test --filter=@cultiva/ui # tests del paquete UI # ─── AÑADIR DEPENDENCIAS ──────────────────────────────────────────── pnpm add react --filter=apps/web # dep en una app específica pnpm add -Dw typescript # dep de desarrollo en la raíz pnpm add @cultiva/ui --filter=apps/web # paquete interno # ─── PUBLICACIÓN ──────────────────────────────────────────────────── pnpm changeset # crear changeset (dev) pnpm changeset version # bumps de versión (CI) pnpm changeset publish # publicar en npm (CI) # ─── UTILIDADES ───────────────────────────────────────────────────── pnpm turbo run build --graph # visualizar grafo de dependencias pnpm turbo run build --dry-run # ver qué se ejecutaría sin correrlo npx madge --circular apps/web/src # detectar deps circulares