zugzbot 1.0.38 → 1.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -66,7 +66,7 @@ Eres el Programador de Código (sdd-coder) del arnés SDD. Tu trabajo es codific
66
66
  </bootstrap_obligatorio>
67
67
 
68
68
  <consolidar_instalaciones>
69
- Si necesitas paquetes adicionales o componentes shadcn, instálalos agrupados en un solo comando de terminal o llamada de herramienta (`npm install a b` o `npx shadcn@2.1.8 add x y --yes`). No los instales uno a uno.
69
+ Si necesitas paquetes adicionales o componentes shadcn, instálalos agrupados en un solo comando de terminal o llamada de herramienta (`npm install a b` o `npx shadcn@latest add x y --yes`). No los instales uno a uno.
70
70
  </consolidar_instalaciones>
71
71
 
72
72
  <tests_y_contratos>
@@ -85,7 +85,12 @@ Eres el Programador de Código (sdd-coder) del arnés SDD. Tu trabajo es codific
85
85
  <coding_cheatsheet>
86
86
  - **Linear/Brand tokens**: Los tokens se inyectan en `globals.css` vía CSS vars. PROHIBIDO reescribir `globals.css` desde cero o usar colores Hex manuales en componentes. Usa variables como `var(--color-brand-primary)`.
87
87
  - **Estado**: Declara estados centralizados con `useState` en el componente padre (`owner` o `AppLayout`) y pásalos como props. Evita declarar estados compartidos en hijos.
88
- - **Instalación de Shadcn Segura**: La herramienta de shadcn a utilizar en F2 es ESTRICTAMENTE `npx shadcn@2.1.8 add <componentes>`. TIENES PROHIBIDO USAR `@latest` (ej. `npx shadcn@latest add`). Usar `@latest` rompe la aplicación instalando dependencias en pre-release de base-ui. Usa siempre `npx shadcn@2.1.8`.
88
+ - **Instalación de Shadcn Segura**: La herramienta de shadcn a utilizar en F2 es `npx shadcn@latest add <componentes>` (o simplemente `npx shadcn add`). Utiliza siempre la última versión final estable de Shadcn para garantizar la compatibilidad con Tailwind v4 y permitir la descarga de bloques complejos de la comunidad y del registro oficial (como dashboards, sidebars y formularios modernos) sin errores 404.
89
+ - **Next.js & Tailwind v4 Style Resolution**: En Tailwind v4, si `globals.css` importa `@import "shadcn/tailwind.css";`, debes asegurarte de instalar el paquete ejecutable `shadcn` ejecutando `npm install shadcn` o el compilador fallará.
90
+ - **Next.js Auth Redirects robustas (Evitar bucles/parpadeo)**:
91
+ - Usa siempre `router.replace("/")` en lugar de `push` para redirecciones de login.
92
+ - Para evitar efectos concurrentes o solapados en Strict Mode, usa un `useRef(false)` en redirecciones asíncronas para dispararlas solo una vez.
93
+ - En layouts protegidos por SSR, para evitar que parpadeen spinners o modales antes de hidratar la sesión en cliente, declara un estado `mounted` (`useEffect` asignando `setMounted(true)`) y retorna `null` si `!mounted`.
89
94
  - **Iconos**: Importa desde `lucide-react`. Usa `data-icon="inline-start"` para espaciados automáticos.
90
95
  </coding_cheatsheet>
91
96
 
@@ -46,6 +46,10 @@ Eres el Validador de Contratos (sdd-tester) del flujo SDD. Tu trabajo es ejecuta
46
46
  - **Minimizar Lecturas/Búsquedas**: No realices búsquedas ciegas (`glob` repetidos) ni lecturas innecesarias. Guíate estrictamente por la lista `files_affected` provista en tu sección del brief activo para conocer qué archivos de producción se han modificado y dónde están ubicados los tests correspondientes.
47
47
  - **Memoria de Errores**: Tienes PROHIBIDO llamar a `brain_read_memory`. Toda la información histórica sobre fallos técnicos ha sido inyectada directamente en `.opencode/active-brief.md`. Consúltala allí.
48
48
  - **Restricción de Archivos**: Solo se te permite modificar/escribir archivos en la fase 'F3_VERIFICATION', y únicamente archivos que contengan 'test', 'spec', 'tests/' o '.openspec/' en su ruta. Tienes estrictamente prohibido modificar el código fuente de producción.
49
+ - **Extensión JSX en Tests**: Todo archivo de pruebas que contenga JSX, monte componentes o simule iconos (mocks de Lucide con `<svg>`) **DEBE** tener la extensión `.tsx` obligatoriamente (nunca `.ts` ya que esbuild/Vitest fallarán en la compilación).
50
+ - **Selectores de Formularios Robustos**: Evita usar `getByLabelText(/password/i)` si hay botones con aria-label que coincidan de forma ambigua. Prefiere placeholders como `getByPlaceholderText()` o expresiones regulares con anclajes estrictos como `/^Password$/` para aislar el input deseado.
51
+ - **Ocultamiento CSS vs Presencia DOM**: Para barras de navegación o sidebars colapsados por CSS (`hidden`, `w-0`), evita usar `.not.toBeInTheDocument()`. El texto sigue existiendo físicamente en el DOM, por lo que el test fallará. Verifica clases CSS de visibilidad directamente o usa `.not.toBeVisible()` de `@testing-library/jest-dom`.
52
+ - **Mocks Dinámicos de Hooks**: Mocks de hooks que controlan toggles (como `useTheme` de `next-themes`) deben usar getters locales reactivos en la definición del mock, o las pruebas sucesivas de clics de toggle reportarán el mismo valor (el mock estático no retiene el cambio).
49
53
  - **PROHIBIDO EL USO DE `todowrite`**: Tienes ESTRICTAMENTE PROHIBIDO usar la herramienta `todowrite`. El seguimiento de progreso está centralizado en el Orquestador. No la invoques en absoluto.
50
54
  - **Batcheo Extremo de ESCRITURA/EDICIÓN (CRÍTICO)**: NO modifiques ni crees archivos de tests uno a uno para luego correr el test runner cada vez en un bucle lento. Debes usar BATCH EXTREMO. Si tienes que modificar o crear 5 archivos de pruebas, debes enviar en TU MISMA respuesta todas las llamadas a `write` o `edit` necesarias al mismo tiempo (concurrencia). Solo después de enviar todos los cambios corres `vitest run` o `pytest`.
51
55
  </constraints>
@@ -25,8 +25,9 @@ Cuando el estado del sistema tiene `loopMode === true` (activado mediante el com
25
25
  ## 3. Uso Mandatorio de Bloques Prehechos de Shadcn UI (dashboard, sidebar, login, etc.)
26
26
  Para optimizar el tiempo de desarrollo, garantizar una experiencia visual premium y evitar la invención de layouts o formularios comunes desde cero:
27
27
  - **Prioridad de Bloques**: Al diseñar cualquier interfaz de usuario (Layouts, Dashboards, Paneles de Control, Vistas de Configuración, Páginas de Autenticación, Tablas de Datos, Gráficos), los agentes **deben** buscar y utilizar de forma prioritaria los bloques prehechos del registro oficial `@shadcn` (como `dashboard-01`, `sidebar-01` al `16`, `login-01` al `05`, `signup-01` al `05`).
28
- - **Búsqueda Proactiva**: El Spec-Writer **debe** consultar el registro utilizando las herramientas del MCP `shadcn` (`shadcn_search_items_in_registries`, `shadcn_list_items_in_registries`) al redactar el contrato (F1) para identificar qué bloques se ajustan a la necesidad, y declararlos en `frontend.components` y `files_affected` de `contract.json`.
29
- - **Implementación por Distribución y Composición**: El Coder (F2) **debe** instalar estos bloques usando `npx shadcn@latest add <block-name>` (ej: `dashboard-01`, `login-03`) en su proyecto, integrando y distribuyendo los elementos con el estado y lógica del backend, sin rediseñar o codificar layouts que ya existen de forma oficial.
28
+ - **Búsqueda Proactiva**: El Spec-Writer **debe** consultar el registro utilizando las herramientas del MCP `shadcn` (`shadcn_search_items_in_registries`, `shadcn_list_items_in_registries`) al redactar el contrato (F1) para identificar qué bloques se ajustan a la necesidad, y declararlos en `frontend.components` y `files_affected` de `contract.json`. Además, el Spec-Writer **debe** invocar `shadcn_view_items_in_registries` sobre los bloques complejos seleccionados para inspeccionar por adelantado sus archivos, rutas y dependencias inyectadas por defecto, anticipando cualquier colisión de ruteo y documentándolo con precisión en el contrato.
29
+ - **Implementación por Distribución y Composición**: El Coder (F2) **debe** instalar estos bloques usando `npx shadcn@latest add <block-name>` (ej: `dashboard-01`, `login-03`) en su proyecto, integrando y distribuyendo los elementos con el estado y lógica del backend, sin rediseñar o codificar layouts que ya existen de forma oficial. El Coder puede usar `shadcn_get_item_examples_from_registries` para ver ejemplos de implementación realistas y aplicarlos limpiamente a la primera, reduciendo el desvío visual.
30
+ - **Resolución Activa de Conflictos de Ruteo por Inyección de Bloques**: Si la CLI de Shadcn inyecta automáticamente una estructura de rutas (ej: `src/app/dashboard/page.tsx`) que compite con las rutas del contrato (como un route group `(dashboard)` o una ruta raíz), el Coder **debe** borrar o refactorizar de inmediato el código inyectado por defecto para evitar bucles de redirección infinitos o colisiones en el router.
30
31
 
31
32
  ## 4. Soporte para Subdirectorios, Monorepos (targetDir) y Estándar Corporativo `src/`
32
33
  Si el proyecto o aplicación principal vive en un subdirectorio (ej. `next-app`, `frontend`, `backend`), se deben seguir estas directivas estrictas para mantener la consistencia y el "estándar corporativo con carpeta `src/`":
@@ -42,6 +43,9 @@ Cualquier desarrollo de interfaz de usuario (Dashboards, Landings, Formularios,
42
43
  - Se deben mapear obligatoriamente a variables semánticas de Shadcn/Tailwind que soporten modo claro/oscuro dinámico por defecto (ej. `bg-background`, `bg-muted/50`, `bg-accent`, `text-foreground`, `text-muted-foreground`, `border-border`).
43
44
  - **Gráficos Dinámicos y Reactivos (SVG/Recharts Theme Sync):**
44
45
  - Cualquier componente de gráficos (como Recharts o visores vectoriales SVG) que use atributos de pintado inline (`stroke`, `fill`, `color`) debe resolver sus colores mediante un custom hook o variables dinámicas que consuman el estado del tema actual (`useTheme` de `next-themes` u homólogo), previniendo que líneas o textos queden invisibles en modo oscuro.
46
+ - Está estrictamente prohibido usar variables CSS puras directamente en `stroke` o `fill` de SVG si estas no son resueltas de forma dinámica. Si es necesario, utiliza una paleta de colores hexadecimales fija de alto contraste y compatible con ambos modos claro y oscuro (ej: `#0072f5` para líneas y barras, o una paleta de sectores sólida para PieCharts) que garantice legibilidad 100% en fondos claros y oscuros, manteniendo solo los ejes y rejillas de fondo (grids) referenciando variables semánticas.
47
+ - **Evitar Solapamiento de Sidebar (Sidebar Overlap Prevention):**
48
+ - Al implementar barras laterales colapsables de Shadcn (`Sidebar`), el Coder debe asegurarse de que el contenedor del contenido principal use de forma robusta `<SidebarInset>` o una estructura flexbox flexible (ej: `flex flex-1 flex-col`) que responda al estado del sidebar. Está estrictamente prohibido usar posicionamiento fijo o absoluto en el sidebar sin un espaciador o contenedor dinámico que evite que el sidebar se sobreponga al contenido en pantallas anchas.
45
49
  - **Robustez HTML y Regla de No-Nesting en Triggers:**
46
50
  - Al utilizar componentes contenedores de Radix/Shadcn UI (como `TooltipTrigger`, `DropdownMenuTrigger`, `DialogTrigger`, `SheetTrigger`), está estrictamente PROHIBIDO anidar un elemento interactivo nativo (como `<button>` o `<a>`) directamente dentro de otro trigger que ya renderice un botón por defecto.
47
51
  - Para evitar la hidratación rota y HTML inválido, se debe usar siempre el prop `asChild` en el trigger de Radix o delegar los props correctamente usando las directivas del componente de base.
@@ -49,8 +53,21 @@ Cualquier desarrollo de interfaz de usuario (Dashboards, Landings, Formularios,
49
53
  - **Tooltips:** Todo botón que contenga únicamente un icono de acción debe estar envuelto en un componente `Tooltip` con su descripción respectiva.
50
54
  - **Skeletons y Empty States:** Las vistas de carga deben contar con animaciones de `Skeleton` fluidas. Las listas o tablas vacías deben presentar un `Empty State` visual y explicativo agradable con iconos y un botón de acción alternativo, nunca una página o cuadro en blanco.
51
55
 
52
- ## 6. Mockups Visuales y Validación Temprana de Layout (F0/F1)
56
+ ## 6. Estándar de Robustez en Autenticación, Ruteo y SSR (Next.js)
57
+ Para evitar bucles de redirección ("redirect loops") y pantallas parpadeantes (flickers/blinking) tras iniciar sesión:
58
+ - **Evitar Race Conditions en Redirecciones:** En el formulario de login, usa siempre `router.replace("/")` en lugar de `push` tras un login exitoso para evitar empujar estados duplicados al historial.
59
+ - **Evitar useEffects Cruzados Activos:** Si usas un guard de redirección en `LoginPage` o similar para usuarios ya autenticados, utiliza un `useRef(false)` para controlar que la redirección asíncrona solo se dispare una vez y no se encadene con re-renderizados concurrentes de React.
60
+ - **Evitar Flash de Carga SSR en Layouts:** Para layouts o guards protegidos, nunca asumas estados por defecto que pinten elementos cargando (spinners) durante el servidor. Comprueba si el componente está montado (`mounted === true`) antes de evaluar la sesión en el cliente y renderizar el contenido. Retorna `null` antes de montar para evitar desajustes de hidratación (hydration mismatch).
61
+ - **Eliminación Obligatoria de Placeholders de Página Raíz:**
62
+ - El Coder debe asegurar que la página de entrada de la aplicación (`src/app/page.tsx` o similar) no se quede con el texto placeholder por defecto. Debe ser reemplazada por el componente principal especificado o contener una redirección limpia (`redirect("/dashboard")`) hacia la vista principal protegida o pública definida por el contrato.
63
+
64
+ ## 7. Mockups Visuales y Validación Temprana de Layout (F0/F1)
53
65
  Para optimizar el diseño, evitar cambios de arquitectura estructurales a mitad del desarrollo (como rediseñar pestañas a layouts de sidebar lateral) y garantizar alineación inmediata con las expectativas del usuario:
54
66
  - **Propuesta de Layout Visual:** Durante la transición de F0 a F1, el `@sdd-spec-writer` **debe** proponer un mockup textual o diagrama de cajas ASCII detallando la distribución estructural de la pantalla (Layout general, barras laterales sticky, contenedores de contenido responsivos y anchos de pantalla recomendados, ej. `max-w-6xl` vs `w-full`).
55
67
  - **Ancho y Densidad Modernos:** Por defecto, los layouts complejos deben evitar contenedores angostos restrictivos como `max-w-3xl` para maximizar el aprovechamiento de pantallas de escritorio modernas mediante rejillas responsivas (`grid grid-cols-1 md:grid-cols-X gap-6`).
56
68
  - **Aprobación Temprana:** El orquestador presentará esta propuesta visual al usuario en la fase F1. Una vez aprobada la disposición espacial y la estructura de navegación local (ej: sidebar split vs horizontal tabs), el `@sdd-coder` la ejecutará exactamente como se acordó, previniendo loops redundantes de maquetación en fases tardías.
69
+
70
+ ## 8. Abstracción y Prohibición de Parchar Código en F3/Orquestador
71
+ Para mantener la limpieza y disciplina en la ventana de contexto de la sesión:
72
+ - **Orquestador No-Coder:** El orquestador principal (`sdd-orchestrator`) tiene estrictamente prohibido usar herramientas de edición (`edit` o `write`) para modificar código de producción o archivos de test.
73
+ - **Rollback Disciplinado:** Si en la fase `F3_VERIFICATION` el linter o los tests reportan errores, el orquestador **debe** transicionar el estado a `F2_IMPLEMENTATION` mediante `sdd_core_set_phase` y re-invocar al subagente experto (`sdd-coder`) para que realice la corrección cleanly. No se permiten parches rápidos a mitad de fase de test.
@@ -63,6 +63,13 @@ ENV HOSTNAME="0.0.0.0"
63
63
  CMD ["node", "server.js"]
64
64
  ```
65
65
 
66
+ #### 🛠️ **Manejo de Conflictos de Dependencias y Sincronización de Lockfile**
67
+ En proyectos donde las dependencias cambian con frecuencia por la adición automática de componentes de Shadcn, es muy común que el comando estricto `npm ci --frozen-lockfile` falle dentro de Docker con errores de desincronización de lockfile (ej: `Invalid: lock file's picomatch... does not satisfy`).
68
+
69
+ Para solucionar esto de manera robusta:
70
+ 1. **Solución Local Primaria**: El Coder debe añadir de manera explícita la dependencia par conflictiva en su `package.json` (ej: `"picomatch": "^4.0.4"`) y ejecutar `npm install` localmente para regenerar y sincronizar un `package-lock.json` limpio antes de intentar compilar el contenedor.
71
+ 2. **Estrategia Fallback en Dockerfile**: Si la sincronización del lockfile sigue presentando conflictos intermitentes e inestabilidad insalvable, el Deployer tiene autorización para modificar el paso de instalación del Dockerfile de un estricto `npm ci` a un dinámico `npm install --no-audit --no-fund` para permitir que el motor de resolución de Node resuelva las dependencias pares de forma adaptativa.
72
+
66
73
  #### **.dockerignore**
67
74
  ```ignore
68
75
  node_modules
@@ -41,65 +41,53 @@ Cada fase tiene un **gate explícito** (HIL del usuario) antes de transicionar a
41
41
 
42
42
  ---
43
43
 
44
- ## 3. Trampas conocidas (EVITAR siempre)
44
+ ## 3. Trampas del Flujo Maestro (EVITAR siempre)
45
45
 
46
46
  ### Trampa 1: Listar marcas de diseño una por una
47
- **NO HAGAS**: 4 llamadas a `oh-my-design_list_references` con `category: "saas"`, "fintech", "ecommerce", "consumer" solo para mostrar opciones.
48
- **HAZ**: 1 llamada a `sdd_list_design_recommendations({ use_case: "all", max_per_category: 3 })`. Si el usuario quiere "Personalizar", ahí sí usa `oh-my-design_search_by_vibe`.
47
+ **NO HAGAS**: Hacer múltiples llamadas a `oh-my-design_list_references` para mostrar opciones al usuario en F0.
48
+ **HAZ**: Haz una única llamada consolidada a `sdd_list_design_recommendations({ use_case: "all", max_per_category: 3 })`.
49
49
 
50
50
  ### Trampa 2: Crear la carpeta del spec en 2 steps
51
- **NO HAGAS**: `sdd_create_spec_folder("mi-spec")` + `sdd_set_phase("F1_CONTRACT", ...)` en 2 calls (race condition de timestamp, observado en sesión 137a).
52
- **HAZ**: 1 sola call: `sdd_set_phase({ phase: "F1_CONTRACT", spec_name: "mi-spec" })`. Devuelve `activeContract` listo.
51
+ **NO HAGAS**: Llamar a `sdd_create_spec_folder("mi-spec")` y luego a `sdd_set_phase("F1_CONTRACT", ...)` por separado (causa race conditions en el timestamp).
52
+ **HAZ**: Transiciona en un solo paso: `sdd_set_phase({ phase: "F1_CONTRACT", spec_name: "mi-spec" })`.
53
53
 
54
- ### Trampa 3: Reescribir `globals.css` desde cero
55
- **NO HAGAS**: Sobrescribir `src/app/globals.css` quitando las variables shadcn (`--color-border: var(--border)`, etc.) al aplicar tokens de marca. Build falla con `Cannot apply unknown utility class 'border-border'` (observado en sesión 137a).
56
- **HAZ**: Usar `sdd_apply_brand_tokens` que inyecta en un bloque `@theme inline` aparte, preservando las variables shadcn.
54
+ ### Trampa 3: Cargar `next-devtools` MCP en sesión normal
55
+ **NO HAGAS**: Activar `next-devtools` por defecto. Inyecta miles de palabras de instrucciones redundantes al contexto, desperdiciando tokens de razonamiento.
56
+ **HAZ**: Mantenerlo deshabilitado en `opencode.json` y activarlo únicamente bajo demanda si se depura un error muy específico del runtime de Next.js.
57
57
 
58
- ### Trampa 4: Cargar `next-devtools` MCP en sesión normal
59
- **NO HAGAS**: Dejar `next-devtools` habilitado. Su tool `init` inyecta 1000+ palabras de "FORGET ALL PRIOR KNOWLEDGE" (~8K tokens de reasoning desperdiciado — el coder tuvo el mayor consumo de tokens de la sesión 137a por esta razón).
60
- **HAZ**: Está deshabilitado por defecto en `opencode.json`. Solo activarlo on-demand si un subagente reporta un error específico de Next 16.
58
+ ### Trampa 4: Escribir el contrato desde cero en F1
59
+ **NO HAGAS**: Redactar cientos de líneas de `contract.json` de forma manual.
60
+ **HAZ**: Cargar la skill `sdd-quickstart` y rellenar los huecos `{{...}}` de su plantilla preconfigurada.
61
61
 
62
- ### Trampa 5: Escribir el contrato desde cero
63
- **NO HAGAS**: Redactar 600+ líneas de `contract.json` en cada sesión. Riesgo alto de inconsistencia.
64
- **HAZ**: Cargar la skill `sdd-quickstart` y usar la plantilla pre-rellenada. Solo rellenar `{{...}}`.
62
+ ### Trampa 5: Permitir que el Coder escriba los tests en F2
63
+ **NO HAGAS**: Desarrollar la lógica y luego redactar las pruebas (causa bucles redundantes entre Coder y Tester).
64
+ **HAZ**: Que el Spec-Writer declare las aserciones en el contrato en F1. El Coder solo implementa el código de negocio necesario para que pasen.
65
65
 
66
- ### Trampa 6: Tests en F2
67
- **NO HAGAS**: Que el coder escriba los tests después de implementar (loop Coder Tester Coder, observado en sesión 137a).
68
- **HAZ**: Que el spec-writer (en F1) cree los tests con assertions reales basadas en `test_scenarios`. El coder solo implementa el código de producción para hacerlos pasar.
66
+ ### Trampa 6: Exceso de actualizaciones de TODOs con `todowrite`
67
+ **NO HAGAS**: Llamar a `todowrite` para actualizar el estado del arnés tras cada pequeño cambio o fase.
68
+ **HAZ**: Inicializar la lista al inicio, marcar `in_progress` al arrancar una fase, y marcar los TODOs completados en bloque al final.
69
69
 
70
- ### Trampa 7: 5+ llamadas a `todowrite` durante la sesión
71
- **NO HAGAS**: Actualizar la lista de TODOs cada vez que cambias de fase (observado 5 veces en sesión 137a).
72
- **HAZ**: Crear la lista al inicio. Marcar `in_progress` solo cuando arrancas la fase. Marcar `completed` **en bloque** al final.
70
+ ### Trampa 7: Cargar skills duplicadas en subagentes
71
+ **NO HAGAS**: Cargar skills generales (como `sdd-methodology`) de manera redundante en subagentes especializados (como `@sdd-deployer` o `@sdd-tester`) que ya la tienen incorporada en su prompt base.
72
+ **HAZ**: Limitar la carga de skills estrictamente a tareas que requieran sus plantillas específicas.
73
73
 
74
- ### Trampa 8: `lint: false` en el orquestador
75
- **NO HAGAS**: Dejar que el tester descubra imports no usados en tests.
76
- **HAZ**: El self-audit del coder (F2) y el auto-lint gate de `sdd_set_phase("F3_VERIFICATION")` ya lo previenen. El orquestador debe **reportar el `lintWarning`** al usuario antes de delegar al tester.
74
+ ### Trampa 8: Invocar Playwright en modo Console
75
+ **NO HAGAS**: Abrir navegadores o tomar snapshots si `verificationMode` es `"console"`.
76
+ **HAZ**: Confiar plenamente en Vitest/Pytest y curls rápidos desde la terminal.
77
77
 
78
- ### Trampa 9: Cargar skills duplicadas
79
- **NO HAGAS**: Cargar skills de forma genérica en subagentes si su contenido ya está integrado en su prompt de identidad (ej. cargar `sdd-methodology` en `@sdd-deployer` o `@sdd-tester`). Esto duplica los tokens de input consumidos.
80
- **HAZ**: Limitar la carga de skills a los casos proactivos indicados o cuando se requieran plantillas/recursos específicos de la skill (ej. `sdd-quickstart` en `@sdd-spec-writer`).
78
+ ### Trampa 9: Orquestador usurpador (Ruptura de Abstracción)
79
+ **NO HAGAS**: Editar código de producción o escribir/ejecutar tests directamente desde el orquestador si un subagente falla o se queda sin pasos.
80
+ **HAZ**: Re-invocar al subagente experto (`sdd-coder` o `sdd-tester`) mediante la herramienta `task` pasándole el `task_id` original para que continúe limpiamente.
81
81
 
82
- ### Trampa 10: Playwright en modo Console
83
- **NO HAGAS**: Invocar herramientas de Playwright (`playwright_browser_navigate`, `playwright_browser_snapshot`, etc.) si `verificationMode` está configurado en `"console"`. Esto consume tiempo y reasoning innecesarios.
84
- **HAZ**: En modo `console`, confía en pruebas unitarias/integración (Vitest) y verificaciones directas con curls/logs. No abras navegadores.
85
-
86
- ### Trampa 11: Orquestador usurpador (Ruptura de Abstracción)
87
- **NO HAGAS**: Permitir que el Orquestador principal (`sdd-orchestrator`) tome el rol de escribir el código de producción o escribir/ejecutar tests directamente si un subagent (ej. `@sdd-coder`) falla o alcanza el límite de pasos ("Maximum Steps Reached"). Esto ensucia la ventana de contexto principal de la sesión.
88
- **HAZ**: Re-invoca al mismo subagente usando la herramienta `task`, pasando el `task_id` original del subagente interrumpido e instruyéndole: "Te quedaste sin pasos. Continúa y finaliza los archivos pendientes".
89
-
90
- ### Trampa 12: Obsesión por alineación de consola (Pixel-Peeping)
91
- **NO HAGAS**: Gastar múltiples iteraciones o miles de tokens en el razonamiento de `@sdd-coder` tratando de lograr una alineación perfecta de columnas con espacios exactos en salidas CLI o tablas ASCII.
92
- **HAZ**: Usa funciones estándar de formateo de strings de tu lenguaje (como `ljust()`, `rjust()` o `center()` en Python; o formateadores sencillos en JS/TS) para lograr una presentación razonable de forma inmediata y avanzar directamente a la creación de pruebas.
93
-
94
- ### Trampa 13: Omitir la disposición espacial y propuesta de Layout en F1
95
- **NO HAGAS**: Redactar el contrato en F1 listando únicamente archivos de forma abstracta sin definir o validar la geometría estructural y distribución de la UI (ej. si se requieren Sidebars locales de navegación vs pestañas horizontales planas), asumiendo anchos angostos y estáticos (como `max-w-3xl`) o rompiendo el soporte de modo oscuro con colores absolutos (`bg-white`).
96
- **HAZ**: El spec-writer debe proponer proactivamente en F1 un bosquejo textual o diagrama ASCII de la interfaz y validar con el usuario un layout responsivo amplio (`max-w-6xl` o superior). Además, el coder debe implementar soporte semántico dinámico de temas de entrada (sin colores duros) y sincronizar colores SVG/gráficos dinámicamente con el tema actual.
82
+ ### Trampa 10: Obsesión por alineación exacta en consola (Pixel-Peeping)
83
+ **NO HAGAS**: Consumir iteraciones intentando alinear espacios exactos en salidas CLI o tablas ASCII.
84
+ **HAZ**: Usar funciones estándar de formateo de strings de tu lenguaje (`ljust()`, `rjust()`) y priorizar la lógica de negocio y las pruebas.
97
85
 
98
86
  ---
99
87
 
100
88
  ## 4. Stack cerrado (NO abrir)
101
89
 
102
- - **Frontend**: Next.js 15/16 + React 19 + TypeScript + Tailwind v4 + Shadcn UI v2.1.8 (Radix UI) + lucide-react + Vitest. **PROHIBIDO**: Shadcn v4/Base-UI (por inestabilidad y falta de soporte actual), HeroUI, Chakra, Material-UI.
90
+ - **Frontend**: Next.js 15/16 + React 19 + TypeScript + Tailwind v4 + Shadcn UI @latest (Radix UI) + lucide-react + Vitest. **PROHIBIDO**: Shadcn v4/Base-UI (por inestabilidad y falta de soporte actual), HeroUI, Chakra, Material-UI.
103
91
  - **Backend**: Python 3.11+ + FastAPI + Pydantic v2 + Uvicorn + Pytest + Ruff. **PROHIBIDO**: Django, Flask, sync SQLAlchemy.
104
92
  - **Persistencia**: localStorage (frontend-only) o PostgreSQL con pgvector. **PROHIBIDO**: MongoDB (excepto si se justifica), Redis como primary store.
105
93
  - **Containerización**: Docker multi-stage con `node:20-alpine` (Next) o `python:3.11-slim` (FastAPI). Usuario no-root. Healthcheck via `node -e` (no wget en alpine).
@@ -160,6 +160,7 @@ Copia y adapta los IDs y descripciones que apliquen. Borra los que no apliquen.
160
160
  - **NO escribas más de 5-6 `test_scenarios`** para modo `console`. Más de eso no acelera la entrega, solo retrasa F2.
161
161
  - **NO incluyas escenarios `visual` o `e2e` si `verificationMode` es `console`.** El tester los rechazará.
162
162
  - **NO omitas la disposición espacial y propuesta de Layout**: El spec-writer DEBE proponer un bosquejo textual o diagrama ASCII de la disposición espacial de la UI en F1 (ej. layouts con sidebar lateral para configuración o paneles complejos en lugar de simples pestañas tradicionales planas) y acordar anchos de pantalla generosos (`max-w-6xl` o superior, evitando el limitante `max-w-3xl`) con el usuario antes de transicionar a F2. Esto previene reestructuraciones estéticas costosas y asegura entregas de alta gama a la primera.
163
+ - **NO omitas la página raíz (`src/app/page.tsx`) en el mapeo de archivos afectados**: El spec-writer DEBE asegurar que `src/app/page.tsx` quede registrado explícitamente y que el contrato aclare si la ruta raíz `/` servirá el contenido principal de la aplicación, o si simplemente ejecutará una redirección limpia (`redirect("/dashboard")`) hacia el panel principal. Esto evita que el Coder conserve el placeholder por defecto de bootstrap y cause inconsistencias visuales o de navegación.
163
164
 
164
165
  ---
165
166
 
@@ -19,12 +19,14 @@ Esta habilidad proporciona un **flujo de trabajo estructurado en 4 pasos** para
19
19
  - En el **Paso 3**, no aplican los mocks de React, Lucide ni `crypto.randomUUID` en JS. Si necesitas mockear en Python, usa `unittest.mock` (como `patch` o `MagicMock`).
20
20
  - En el **Paso 4**, ejecuta `ruff check src/` o similar para linting, y `python -m pytest tests/ -v` para ejecutar toda la suite de pruebas de una sola llamada consolidada.
21
21
 
22
- ### Paso 1: Leer solo lo indispensable (Máximo 3 reads)
22
+ ### Paso 1: Leer solo lo indispensable (Máximo 3 reads) y asegurar entorno
23
23
  1. **Contrato**: Lee únicamente `contract.json` para extraer los `test_scenarios` y el `verificationMode`.
24
24
  2. **Setup**: Lee `src/test/setup.ts` o `vitest.config.ts` para confirmar si ya hay polyfills.
25
25
  3. **Breve examen**: Lee el componente principal (`AppLayout` o similar) para confirmar el `stateFlow`.
26
26
  *NO uses `glob` ciegos para buscar archivos del proyecto.*
27
27
 
28
+ **VERIFICACIÓN CLAVE DE DEPENDENCIAS**: Asegúrate de que `package.json` tenga instaladas las devDependencies necesarias para pruebas de React: `happy-dom`, `@testing-library/jest-dom` y `@testing-library/dom`. Si no están presentes, instálalas en un solo comando unificado: `npm install --save-dev happy-dom @testing-library/jest-dom @testing-library/dom`.
29
+
28
30
  ### Paso 2: Autogenerar plantillas de tests (BLOQUEANTE)
29
31
  Antes de escribir cualquier test a mano, **DEBES** ejecutar:
30
32
  ```bash
@@ -35,17 +37,24 @@ Esto creará automáticamente las plantillas correspondientes en base a los `tes
35
37
  ### Paso 3: Completar aserciones usando Mocks Estandarizados (Evitar fallos de librerías)
36
38
  Completa los tests importando los componentes reales. Si Vitest o happy-dom fallan por dependencias externas de Shadcn UI o Lucide, aplica estos mocks centralizados:
37
39
 
38
- #### Mock de Lucide Icons (si fallan por SVG/React)
40
+ #### Mock Dinámico de Lucide Icons (Recomendado para evitar fallos de iconos faltantes)
41
+ Para evitar que tests fallen porque falta mockear un icono específico (ej. `PanelLeft`, `Search`, etc.), usa un Proxy que mockea dinámicamente CUALQUIER icono exportado por `lucide-react`:
39
42
  ```typescript
40
- vi.mock('lucide-react', () => ({
41
- Sun: () => <div data-testid="icon-sun" />,
42
- Moon: () => <div data-testid="icon-moon" />,
43
- Plus: () => <div data-testid="icon-plus" />,
44
- Trash2: () => <div data-testid="icon-trash" />,
45
- History: () => <div data-testid="icon-history" />,
46
- Clock: () => <div data-testid="icon-clock" />,
47
- Calculator: () => <div data-testid="icon-calculator" />
48
- }));
43
+ vi.mock('lucide-react', () => {
44
+ return new Proxy(
45
+ {},
46
+ {
47
+ get: (target, prop) => {
48
+ // Retorna un componente funcional con el testid del icono solicitado
49
+ const IconComponent = (props: any) => (
50
+ <span data-testid={`icon-${String(prop).toLowerCase()}`} {...props} />
51
+ );
52
+ IconComponent.displayName = String(prop);
53
+ return IconComponent;
54
+ },
55
+ }
56
+ );
57
+ });
49
58
  ```
50
59
 
51
60
  #### Mock de Base UI / Shadcn Radix Primitives
@@ -74,6 +83,38 @@ if (!globalThis.crypto) {
74
83
  }
75
84
  ```
76
85
 
86
+ #### Mock de `next-themes` (Soporte reactivo de Tema)
87
+ Para probar toggles de tema sin que fallen en clics sucesivos:
88
+ ```typescript
89
+ let currentTheme = 'light';
90
+ const mockSetTheme = vi.fn((newTheme: string) => {
91
+ currentTheme = newTheme;
92
+ });
93
+
94
+ vi.mock('next-themes', () => ({
95
+ useTheme: () => ({
96
+ get theme() { return currentTheme; },
97
+ setTheme: mockSetTheme,
98
+ get resolvedTheme() { return currentTheme; },
99
+ }),
100
+ }));
101
+ ```
102
+
103
+ #### Mock de `next/navigation` (Router y Pathname)
104
+ ```typescript
105
+ const mockPush = vi.fn();
106
+ const mockReplace = vi.fn();
107
+
108
+ vi.mock('next/navigation', () => ({
109
+ useRouter: () => ({
110
+ push: mockPush,
111
+ replace: mockReplace,
112
+ prefetch: vi.fn(),
113
+ }),
114
+ usePathname: () => '/',
115
+ }));
116
+ ```
117
+
77
118
  ### Paso 4: Ejecutar Lint y Tests consolidando comandos
78
119
  1. Corre el linter enfocado en el código fuente:
79
120
  ```bash
@@ -91,3 +132,24 @@ npx vitest run
91
132
  1. **PROHIBIDO Playwright en modo Console**: Si `verificationMode === "console"`, no instancies ni corras ningún test de Playwright, ni navegues con tools de Playwright. Solo corre tests de Vitest.
92
133
  2. **PROHIBIDO modificar código de features para "hacer pasar" el test**: Si el código tiene un bug, haz rollback a `F2_IMPLEMENTATION` reportando el error exacto al coder. No parches la lógica del negocio en F3.
93
134
  3. **Consolidación**: No corras `vitest` archivo por archivo. Corre la suite completa en una sola llamada a `bash`.
135
+ 4. **REGLA DE ORO DE ASERCIONES DE TEXTO (Acentos y Encoding)**: Para evitar fallos tontos de aserción por diferencias de codificación en caracteres con tildes (ej: `ó` vs `\u00f3`, `ñ` vs `\u00f1`), usa siempre expresiones regulares insensibles a mayúsculas y comodines (ej: `screen.getByText(/Inicia sesi.n/i)` o `screen.getByText(/contrase.a/i)`). Nunca utilices comparaciones estrictas de cadenas de texto acentuadas.
136
+
137
+ ---
138
+
139
+ ## ⚠️ Trampas Comunes de Pruebas (Testing Gotchas)
140
+
141
+ ### 1. Extensión incorrecta en archivos de pruebas con JSX
142
+ * **No hagas**: Usar la extensión `.ts` para archivos de tests que renderizan primitivas de HTML o JSX o que mockean componentes de interfaz (causa fallos de compilación inmediatos en Vitest).
143
+ * **Haz**: Toda suite de pruebas que monte componentes o contenga JSX debe grabarse con la extensión `.tsx` obligatoriamente.
144
+
145
+ ### 2. Selectores ambiguos para campos interactivos comunes
146
+ * **No hagas**: Usar queries genéricas e insensibles como `screen.getByLabelText(/password/i)` si existen múltiples elementos en el DOM que contengan esa palabra (ej: botones de "Show password"). Esto lanzará un error de "Found multiple elements".
147
+ * **Haz**: Usa selectores de coincidencia exacta como `screen.getByLabelText(/^Password$/)` o busca mediante placeholders específicos (`screen.getByPlaceholderText(...)`).
148
+
149
+ ### 3. Validar ausencia de elementos ocultos por CSS con `not.toBeInTheDocument()`
150
+ * **No hagas**: Tratar de validar que un menú o modal colapsado/oculto ya no es visible utilizando `expect(queryByText("...")).not.toBeInTheDocument()`. Si el elemento simplemente se oculta con clases de CSS (como `hidden`, `w-0` u `opacity-0`), el nodo sigue existiendo físicamente en el DOM.
151
+ * **Haz**: Verifica la visibilidad real usando `.not.toBeVisible()` de `@testing-library/jest-dom`, o comprueba directamente las clases CSS de colapso.
152
+
153
+ ### 4. Mocks estáticos de hooks con estado
154
+ * **No hagas**: Mockear hooks que controlan toggles (como `useTheme` de `next-themes`) usando un retorno fijo estático. Al simular el clic en el botón de toggle, el test fallará o entrará en bucles porque el valor del estado simulado permanece congelado.
155
+ * **Haz**: Declara variables mutables locales a nivel de archivo de pruebas y usa getters dinámicos en la definición del mock de Vitest para simular los cambios de estado correctamente.
@@ -9,19 +9,19 @@ compatibility: opencode
9
9
 
10
10
  A framework for building ui, components and design systems. Components are added as source code to the user's project via the CLI.
11
11
 
12
- > **IMPORTANT:** Run all CLI commands using the project's package runner: `npx shadcn@2.1.8`, `pnpm dlx shadcn@2.1.8`, or `bunx --bun shadcn@2.1.8` — based on the project's `packageManager`. Examples below use `npx shadcn@2.1.8` but substitute the correct runner for the project.
12
+ > **IMPORTANT:** Run all CLI commands using the project's package runner: `npx shadcn@latest`, `pnpm dlx shadcn@latest`, or `bunx --bun shadcn@latest` — based on the project's `packageManager`. Examples below use `npx shadcn@latest` but substitute the correct runner for the project.
13
13
 
14
14
  ## Current Project Context
15
15
 
16
16
  ```json
17
- !`npx shadcn@2.1.8 info --json`
17
+ !`npx shadcn@latest info --json`
18
18
  ```
19
19
 
20
- The JSON above contains the project config and installed components. Use `npx shadcn@2.1.8 docs <component>` to get documentation and example URLs for any component.
20
+ The JSON above contains the project config and installed components. Use `npx shadcn@latest docs <component>` to get documentation and example URLs for any component.
21
21
 
22
22
  ## Principles
23
23
 
24
- 1. **Use existing components first.** Use `npx shadcn@2.1.8 search` to check registries before writing custom UI. Check community registries too.
24
+ 1. **Use existing components first.** Use `npx shadcn@latest search` to check registries before writing custom UI. Check community registries too.
25
25
  2. **Compose, don't reinvent.** Settings page = Tabs + Card + form controls. Dashboard = Sidebar + Card + Chart + Table.
26
26
  3. **Use built-in variants before custom styles.** `variant="outline"`, `size="sm"`, etc.
27
27
  4. **Use semantic colors.** `bg-primary`, `text-muted-foreground` — never raw values like `bg-blue-500`.
@@ -52,7 +52,7 @@ These rules are **always enforced**. Each links to a file with Incorrect/Correct
52
52
  ### Component Structure → [composition.md](../../docs/shadcn/rules/composition.md)
53
53
 
54
54
  - **Items always inside their Group.** `SelectItem` → `SelectGroup`. `DropdownMenuItem` → `DropdownMenuGroup`. `CommandItem` → `CommandGroup`.
55
- - **Use `asChild` (radix) or `render` (base) for custom triggers.** Check `base` field from `npx shadcn@2.1.8 info`. → [base-vs-radix.md](../../docs/shadcn/rules/base-vs-radix.md)
55
+ - **Use `asChild` (radix) or `render` (base) for custom triggers.** Check `base` field from `npx shadcn@latest info`. → [base-vs-radix.md](../../docs/shadcn/rules/base-vs-radix.md)
56
56
  - **Dialog, Sheet, and Drawer always need a Title.** `DialogTitle`, `SheetTitle`, `DrawerTitle` required for accessibility. Use `className="sr-only"` if visually hidden.
57
57
  - **Use full Card composition.** `CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`. Don't dump everything in `CardContent`.
58
58
  - **Button has no `isPending`/`isLoading`.** Compose with `Spinner` + `data-icon` + `disabled`.
@@ -77,8 +77,8 @@ These rules are **always enforced**. Each links to a file with Incorrect/Correct
77
77
 
78
78
  ### CLI
79
79
 
80
- - **Never decode preset codes or build preset URLs manually.** Use `npx shadcn@2.1.8 preset decode <code>`, `preset url <code>`, or `preset open <code>`. For project-aware preset detection, use `npx shadcn@2.1.8 preset resolve`.
81
- - **Apply preset codes directly with the CLI.** Use `npx shadcn@2.1.8 apply <code>` for existing projects, or `npx shadcn@2.1.8 init --preset <code>` when initializing.
80
+ - **Never decode preset codes or build preset URLs manually.** Use `npx shadcn@latest preset decode <code>`, `preset url <code>`, or `preset open <code>`. For project-aware preset detection, use `npx shadcn@latest preset resolve`.
81
+ - **Apply preset codes directly with the CLI.** Use `npx shadcn@latest apply <code>` for existing projects, or `npx shadcn@latest init --preset <code>` when initializing.
82
82
 
83
83
  ## Key Patterns
84
84
 
@@ -151,7 +151,7 @@ The injected project context contains these key fields:
151
151
  - **`resolvedPaths`** → exact file-system destinations for components, utils, hooks, etc.
152
152
  - **`framework`** → routing and file conventions (e.g. Next.js App Router vs Vite SPA).
153
153
  - **`packageManager`** → use this for any non-shadcn dependency installs (e.g. `pnpm add date-fns` vs `npm install date-fns`).
154
- - **`preset`** → resolved preset code and values for the current project. Use `npx shadcn@2.1.8 preset resolve --json` when you only need preset information.
154
+ - **`preset`** → resolved preset code and values for the current project. Use `npx shadcn@latest preset resolve --json` when you only need preset information.
155
155
 
156
156
  See [cli.md — `info` command](../../docs/shadcn/cli.md) for the full field reference.
157
157
 
@@ -166,29 +166,29 @@ DO NOT run bash commands to view docs. Instead, explicitly use the built-in MCP
166
166
 
167
167
  ## Workflow
168
168
 
169
- 1. **Get project context** — already injected above. Run `npx shadcn@2.1.8 info` again if you need to refresh.
169
+ 1. **Get project context** — already injected above. Run `npx shadcn@latest info` again if you need to refresh.
170
170
  2. **Check installed components first** — before running `add`, always check the `components` list from project context or list the `resolvedPaths.ui` directory. Don't import components that haven't been added, and don't re-add ones already installed.
171
- 3. **Find components** — `npx shadcn@2.1.8 search`.
172
- 4. **Get docs and examples** — use the MCP tool `shadcn_get_item_examples_from_registries` with query strings like `'button demo'` or `'login block example'` to see exact implementations. To preview changes to installed components, use `npx shadcn@2.1.8 add --diff`.
173
- 5. **Install or update** — `npx shadcn@2.1.8 add`. When updating existing components, use `--dry-run` and `--diff` to preview changes first (see [Updating Components](#updating-components) below).
174
- 6. **Fix imports in third-party components** — After adding components from community registries (e.g. `@bundui`, `@magicui`), check the added non-UI files for hardcoded import paths like `@/components/ui/...`. These won't match the project's actual aliases. Use `npx shadcn@2.1.8 info` to get the correct `ui` alias (e.g. `@workspace/ui/components`) and rewrite the imports accordingly. The CLI rewrites imports for its own UI files, but third-party registry components may use default paths that don't match the project.
171
+ 3. **Find components** — `npx shadcn@latest search`.
172
+ 4. **Get docs and examples** — use the MCP tool `shadcn_get_item_examples_from_registries` with query strings like `'button demo'` or `'login block example'` to see exact implementations. To preview changes to installed components, use `npx shadcn@latest add --diff`.
173
+ 5. **Install or update** — `npx shadcn@latest add`. When updating existing components, use `--dry-run` and `--diff` to preview changes first (see [Updating Components](#updating-components) below).
174
+ 6. **Fix imports in third-party components** — After adding components from community registries (e.g. `@bundui`, `@magicui`), check the added non-UI files for hardcoded import paths like `@/components/ui/...`. These won't match the project's actual aliases. Use `npx shadcn@latest info` to get the correct `ui` alias (e.g. `@workspace/ui/components`) and rewrite the imports accordingly. The CLI rewrites imports for its own UI files, but third-party registry components may use default paths that don't match the project.
175
175
  7. **Review added components** — After adding a component or block from any registry, **always read the added files and verify they are correct**. Check for missing sub-components (e.g. `SelectItem` without `SelectGroup`), missing imports, incorrect composition, or violations of the [Critical Rules](#critical-rules). Also replace any icon imports with the project's `iconLibrary` from the project context (e.g. if the registry item uses `lucide-react` but the project uses `hugeicons`, swap the imports and icon names accordingly). Fix all issues before moving on.
176
176
  8. **Registry must be explicit** — When the user asks to add a block or component, **do not guess the registry**. If no registry is specified (e.g. user says "add a login block" without specifying `@shadcn`, `@tailark`, `owner/repo`, etc.), ask which registry to use. Never default to a registry on behalf of the user.
177
177
  9. **Switching presets** — Ask the user first: **overwrite**, **partial**, **merge**, or **skip**?
178
- - **Inspect current preset**: `npx shadcn@2.1.8 preset resolve`. Use `--json` when you need structured values.
179
- - **Inspect incoming preset**: `npx shadcn@2.1.8 preset decode <code>`. Use `preset url <code>` or `preset open <code>` to share or open the preset builder.
180
- - **Overwrite**: `npx shadcn@2.1.8 apply <code>`. Overwrites detected components, fonts, and CSS variables.
181
- - **Partial**: `npx shadcn@2.1.8 apply <code> --only theme,font`. Updates only the selected preset parts without reinstalling UI components. Supported values are `theme` and `font`; comma-separated combinations are allowed. `icon` is intentionally not supported, because icon changes may require full component reinstall and transforms.
182
- - **Merge**: `npx shadcn@2.1.8 init --preset <code> --force --no-reinstall`, then run `npx shadcn@2.1.8 info` to list installed components, then for each installed component use `--dry-run` and `--diff` to [smart merge](#updating-components) it individually.
183
- - **Skip**: `npx shadcn@2.1.8 init --preset <code> --force --no-reinstall`. Only updates config and CSS, leaves components as-is.
178
+ - **Inspect current preset**: `npx shadcn@latest preset resolve`. Use `--json` when you need structured values.
179
+ - **Inspect incoming preset**: `npx shadcn@latest preset decode <code>`. Use `preset url <code>` or `preset open <code>` to share or open the preset builder.
180
+ - **Overwrite**: `npx shadcn@latest apply <code>`. Overwrites detected components, fonts, and CSS variables.
181
+ - **Partial**: `npx shadcn@latest apply <code> --only theme,font`. Updates only the selected preset parts without reinstalling UI components. Supported values are `theme` and `font`; comma-separated combinations are allowed. `icon` is intentionally not supported, because icon changes may require full component reinstall and transforms.
182
+ - **Merge**: `npx shadcn@latest init --preset <code> --force --no-reinstall`, then run `npx shadcn@latest info` to list installed components, then for each installed component use `--dry-run` and `--diff` to [smart merge](#updating-components) it individually.
183
+ - **Skip**: `npx shadcn@latest init --preset <code> --force --no-reinstall`. Only updates config and CSS, leaves components as-is.
184
184
  - **Important**: Always run preset commands inside the user's project directory. `apply` only works in an existing project with a `components.json` file. The CLI automatically preserves the current base (`base` vs `radix`) from `components.json`. If you must use a scratch/temp directory (e.g. for `--dry-run` comparisons), pass `--base <current-base>` explicitly — preset codes do not encode the base.
185
185
 
186
186
  ## Updating Components
187
187
 
188
188
  When the user asks to update a component from upstream while keeping their local changes, use `--dry-run` and `--diff` to intelligently merge. **NEVER fetch raw files from GitHub manually — always use the CLI.**
189
189
 
190
- 1. Run `npx shadcn@2.1.8 add <component> --dry-run` to see all files that would be affected.
191
- 2. For each file, run `npx shadcn@2.1.8 add <component> --diff <file>` to see what changed upstream vs local.
190
+ 1. Run `npx shadcn@latest add <component> --dry-run` to see all files that would be affected.
191
+ 2. For each file, run `npx shadcn@latest add <component> --diff <file>` to see what changed upstream vs local.
192
192
  3. Decide per file based on the diff:
193
193
  - No local changes → safe to overwrite.
194
194
  - Has local changes → read the local file, analyze the diff, and apply upstream updates while preserving local modifications.
@@ -199,55 +199,55 @@ When the user asks to update a component from upstream while keeping their local
199
199
 
200
200
  ```bash
201
201
  # Create a new project.
202
- npx shadcn@2.1.8 init --name my-app --preset base-nova
203
- npx shadcn@2.1.8 init --name my-app --preset a2r6bw --template vite
202
+ npx shadcn@latest init --name my-app --preset base-nova
203
+ npx shadcn@latest init --name my-app --preset a2r6bw --template vite
204
204
 
205
205
  # Create a monorepo project.
206
- npx shadcn@2.1.8 init --name my-app --preset base-nova --monorepo
207
- npx shadcn@2.1.8 init --name my-app --preset base-nova --template next --monorepo
206
+ npx shadcn@latest init --name my-app --preset base-nova --monorepo
207
+ npx shadcn@latest init --name my-app --preset base-nova --template next --monorepo
208
208
 
209
209
  # Initialize existing project.
210
- npx shadcn@2.1.8 init --preset base-nova
211
- npx shadcn@2.1.8 init --defaults # shortcut: --template=next --preset=nova (base style implied)
210
+ npx shadcn@latest init --preset base-nova
211
+ npx shadcn@latest init --defaults # shortcut: --template=next --preset=nova (base style implied)
212
212
 
213
213
  # Apply a preset to an existing project.
214
- npx shadcn@2.1.8 apply a2r6bw
215
- npx shadcn@2.1.8 apply a2r6bw --only theme
216
- npx shadcn@2.1.8 apply a2r6bw --only font
217
- npx shadcn@2.1.8 apply a2r6bw --only theme,font
214
+ npx shadcn@latest apply a2r6bw
215
+ npx shadcn@latest apply a2r6bw --only theme
216
+ npx shadcn@latest apply a2r6bw --only font
217
+ npx shadcn@latest apply a2r6bw --only theme,font
218
218
 
219
219
  # Inspect preset codes and project preset state.
220
- npx shadcn@2.1.8 preset decode a2r6bw
221
- npx shadcn@2.1.8 preset url a2r6bw
222
- npx shadcn@2.1.8 preset open a2r6bw
223
- npx shadcn@2.1.8 preset resolve
224
- npx shadcn@2.1.8 preset resolve --json
220
+ npx shadcn@latest preset decode a2r6bw
221
+ npx shadcn@latest preset url a2r6bw
222
+ npx shadcn@latest preset open a2r6bw
223
+ npx shadcn@latest preset resolve
224
+ npx shadcn@latest preset resolve --json
225
225
 
226
226
  # Add components.
227
- npx shadcn@2.1.8 add button card dialog
228
- npx shadcn@2.1.8 add @magicui/shimmer-button
229
- npx shadcn@2.1.8 add owner/repo/item
230
- npx shadcn@2.1.8 add --all
227
+ npx shadcn@latest add button card dialog
228
+ npx shadcn@latest add @magicui/shimmer-button
229
+ npx shadcn@latest add owner/repo/item
230
+ npx shadcn@latest add --all
231
231
 
232
232
  # Preview changes before adding/updating.
233
- npx shadcn@2.1.8 add button --dry-run
234
- npx shadcn@2.1.8 add button --diff button.tsx
235
- npx shadcn@2.1.8 add @acme/form --view button.tsx
236
- npx shadcn@2.1.8 add owner/repo/item --dry-run
233
+ npx shadcn@latest add button --dry-run
234
+ npx shadcn@latest add button --diff button.tsx
235
+ npx shadcn@latest add @acme/form --view button.tsx
236
+ npx shadcn@latest add owner/repo/item --dry-run
237
237
 
238
238
  # Search registries.
239
- npx shadcn@2.1.8 search @shadcn -q "sidebar"
240
- npx shadcn@2.1.8 search @tailark -q "stats"
241
- npx shadcn@2.1.8 search owner/repo -q "login"
242
- npx shadcn@2.1.8 search # all configured registries
243
- npx shadcn@2.1.8 search @shadcn -q "menu" -t ui # filter by item type
239
+ npx shadcn@latest search @shadcn -q "sidebar"
240
+ npx shadcn@latest search @tailark -q "stats"
241
+ npx shadcn@latest search owner/repo -q "login"
242
+ npx shadcn@latest search # all configured registries
243
+ npx shadcn@latest search @shadcn -q "menu" -t ui # filter by item type
244
244
 
245
245
  # Get component docs and example URLs.
246
246
  # ALWAYS use your MCP Tools (shadcn_get_item_examples_from_registries) instead of bash for docs.
247
247
 
248
248
  # View registry item details (for items not yet installed).
249
- npx shadcn@2.1.8 view @shadcn/button
250
- npx shadcn@2.1.8 view owner/repo/item
249
+ npx shadcn@latest view @shadcn/button
250
+ npx shadcn@latest view owner/repo/item
251
251
  ```
252
252
 
253
253
  **Named presets:** `nova`, `vega`, `maia`, `lyra`, `mira`, `luma`
@@ -73,13 +73,16 @@ npx shadcn@latest add <component-name>
73
73
  Al diseñar o codificar páginas con Shadcn UI, sigue estas reglas estrictas:
74
74
 
75
75
  ### 3.1 Componer, no reinventar (MANDATORIO)
76
- Utiliza las plantillas y bloques existentes de Shadcn como el estándar absoluto de tu interfaz. Queda **estrictamente prohibido** escribir layouts, páginas de autenticación o cuadros de mando desde cero si ya existe un bloque oficial que resuelva el caso de uso:
77
- - **Dashboards**: Utiliza `dashboard-01` como base para cualquier panel de control interactivo.
76
+ Utiliza las plantillas y bloques existentes de Shadcn como el estándar absoluto de tu interfaz. Queda **estrictamente prohibido** escribir layouts, páginas de autenticación o cuadros de mando desde cero si ya existe un bloque oficial que resuelva el caso de uso. **No estás restringido a ningún subconjunto fijo de componentes**: tienes total libertad para buscar en el catálogo completo de 97+ bloques oficiales y componentes primitivos de Shadcn:
77
+ - **Dashboards**: Utiliza `dashboard-01` o cualquier variante de panel de control interactivo oficial.
78
78
  - **Sidebars / Barras de Navegación**: Utiliza `sidebar-01` al `16` para paneles laterales funcionales, colapsables, dinámicos o anidados. No programes componentes de navegación complejos a mano.
79
79
  - **Login / Registro**: Utiliza `login-01` al `05` y `signup-01` al `05` para flujos de login y registro de usuarios.
80
80
  - **Gráficos y Métricas**: Busca y añade bloques de gráficos oficiales de Recharts (`chart-area-*`, `chart-bar-*`, `chart-pie-*`, `chart-radar-*`) para dar vida a la visualización de datos.
81
81
 
82
- Busca layouts de dashboards o formularios complejos en el registro mediante el MCP `shadcn` antes de escribir cualquier código personalizado. Una vez agregado el bloque, distribuye y adapta sus elementos con el estado y la lógica de tu aplicación.
82
+ Busca layouts de dashboards o formularios complejos en el registro mediante el MCP `shadcn` antes de escribir cualquier código personalizado. Una vez agregado el bloque, distribuye y adapta sus elementos con el estado y la lógica de tu aplicación. Te motivamos a explorar todo el ecosistema de bloques pre-creados por Shadcn para armar una UI robusta y moderna.
83
+
84
+ **REGLA CRÍTICA DE RUTAS DUPLICADAS POR SHADCN CLI**:
85
+ Al agregar un bloque interactivo complejo (como `dashboard-01`), el CLI de Shadcn puede inyectar automáticamente archivos en directorios fijos (como `src/app/dashboard/page.tsx`). El Coder **debe** verificar inmediatamente si existe una colisión con la estructura de rutas establecida por el contrato (`contract.json`) —por ejemplo, si el contrato establece un Route Group `src/app/(dashboard)/page.tsx` que sirve en la raíz `/`—. Si ocurre esto, el Coder tiene la obligación de **borrar, mover o refactorizar de inmediato el archivo inyectado automáticamente** para eliminar la duplicidad de rutas, evitando así bucles infinitos de redirección o errores fatales de compilación del router de Next.js.
83
86
 
84
87
  ### 3.2 Form Layouts (FieldGroup + Field)
85
88
  Para estructurar campos de formularios, no uses `div`s arbitrarios con clases de espaciado complejas. Usa las composiciones semánticas oficiales de Shadcn:
@@ -109,25 +112,19 @@ Para estructurar campos de formularios, no uses `div`s arbitrarios con clases de
109
112
  ### 3.4 Sin Placeholders en Producción
110
113
  Los datos dummy y placeholders deben reemplazarse inmediatamente por estados y hooks reales en el frontend que llamen a las APIs del backend (ej. estados de carga, manejo de errores de llamada, y datos dinámicos).
111
114
 
112
- ### 3.5 Estética de Diseño Premium y Layouts (OBLIGATORIO)
113
- Queda **estrictamente prohibido** generar interfaces visualmente planas, vacías o que parezcan un "mínimo producto viable" básico (por ejemplo, una sola caja minimalista en el centro de un fondo blanco plano con un botón gris).
114
-
115
- El diseño debe ser profesional y generar impacto visual instantáneo. Sigue estas directrices:
116
- - **Estructura de Layout Completa**: Toda herramienta, calculadora o pantalla debe estar contenida en un layout profesional. Usa barras de navegación superiores (`Header`), paneles laterales colapsables (`Sidebar`), menús de usuario con avatares, y una barra de estado o pie de página.
117
- - **Grids de KPIs y Métricas**: Añade tarjetas estadísticas en la parte superior de la página para resumir datos clave (ej. número de cálculos realizados, tiempo de respuesta promedio, tasa de éxito) utilizando iconos, números destacados y pequeños indicadores porcentuales.
118
- - **Gráficos e Historiales**: Si hay tablas o historiales, hazlos interactivos. Usa bordes redondeados (`rounded-xl`), sombras suaves, efectos de hover en las filas y, de ser posible, integra gráficos modernos (ej. utilizando `@/components/ui/chart` o Recharts) para representar tendencias.
119
- - **Colores Semánticos y Gradientes**: Utiliza gradientes sutiles y la paleta de colores HSL/OKLCH del tema en lugar de colores puros. Asegúrate de que el botón de cambiar tema (Modo Claro/Oscuro) esté visible en la barra de navegación y funcione de manera impecable.
120
- - **Estados Dinámicos y Micro-animaciones**: Añade pequeños efectos de transición y hover (`transition-all duration-200`) en botones, inputs y tarjetas para que la interfaz se sienta "viva" y responda a las acciones del usuario.
115
+ ### 3.5 Reglas de Diseño y Estándares de Calidad (Consolidadas)
116
+ * **Estándar Semántico**: Consulta y aplica estrictamente la **Sección 5 de `.opencode/rules/sdd-global.md`** para la prevención de colores fijos (hardcoded light/dark), sincronización de temas en gráficos Recharts, prevención de solapamientos del sidebar (Sidebar Overlap) y la regla de no anidamiento en triggers de Radix.
117
+ * **Componentes de Calidad**: Toda interfaz debe estar pulida con skeletons de carga fluidos, empty states agradables con iconos ilustrativos, y tooltips descriptivos para cualquier botón basado únicamente en iconos.
121
118
 
122
119
  ---
123
120
 
124
121
  ## 4. Flujo de Trabajo en SDD
125
122
 
126
123
  ### Fase F1 (Spec-Driven Contract)
127
- El `@sdd-spec-writer` utiliza el MCP `shadcn` (`mcp__shadcn__search_items`, `mcp__shadcn__get_item`) para documentar en el contrato (`contract.json`) qué componentes y bloques se usarán para la UI y verificar sus APIs/propiedades expuestas.
124
+ El `@sdd-spec-writer` utiliza de manera proactiva el MCP `shadcn` (`shadcn_search_items_in_registries`, `shadcn_list_items_in_registries`) para encontrar bloques. **Es obligatorio** usar la herramienta `shadcn_view_items_in_registries` para inspeccionar el contenido completo, la estructura de archivos y las dependencias del bloque seleccionado antes de cerrar el contrato. Esto le permite al Spec-Writer mapear con exactitud los archivos que se generarán en `files_affected` y documentar explícitamente cualquier potencial colisión de ruteo en el `contract.json`.
128
125
 
129
126
  ### Fase F2 (Implementation)
130
- El `@sdd-coder` utiliza el template base `nextjs-shadcn` y ejecuta `npx shadcn@latest add` para instalar los componentes requeridos para la interfaz. Implementa las vistas componiendo dichos bloques y vinculando el estado con el backend.
127
+ El `@sdd-coder` utiliza el template base `nextjs-shadcn`. Si el contrato no detalla todos los sub-componentes o el Coder necesita verificar el comportamiento de un bloque antes de acoplarlo con el backend, debe ejecutar `shadcn_get_item_examples_from_registries` para ver ejemplos funcionales del componente real. Tras ejecutar la instalación con `npx shadcn@latest add`, el Coder debe contrastar los archivos inyectados con el mapa del contrato y limpiar de inmediato cualquier archivo redundante (como una página de inicio duplicada) que no coincida con el router oficial.
131
128
 
132
129
  ### Fase F3 (Verification)
133
130
  El `@sdd-tester` ejecuta las pruebas según el modo de verificación especificado en el contrato (`settings.verificationMode`):
@@ -66,11 +66,12 @@ Para garantizar consistencia y escalabilidad en todos los proyectos, la estructu
66
66
  className={cn("base-classes", condition && "extra", className)}
67
67
  ```
68
68
  5. **Iconos**: usar `lucide-react` (`import { Icon } from "lucide-react"`).
69
- 6. **Block/Template installation**: usar el MCP `shadcn` para browse/search/install:
70
- - Dashboards → `mcp__shadcn__get_item` con `@shadcn/dashboard-01`
69
+ 6. **Block/Template installation**: usar el MCP `shadcn` para browse/search/install. **NOTA CRÍTICA: NO existe ninguna restricción de lista fija**. Tienes libertad absoluta y la obligación proactiva de buscar e instalar CUALQUIER componente primitivo o bloque del catálogo oficial de Shadcn UI que se adapte al caso de uso de la aplicación (entre los 97+ bloques disponibles como dashboards, sidebars colapsables, login, charts, etc.):
70
+ - Dashboards → `@shadcn/dashboard-01`
71
71
  - Landings → `@shadcn/landing-hero`, `@shadcn/pricing`, etc.
72
- - Auth flows → `@shadcn/login-01`, `@shadcn/signup-01`
72
+ - Auth flows → `@shadcn/login-01` al `05`, `@shadcn/signup-01` al `05`
73
73
  - Forms complejos → `@shadcn/settings`, `@shadcn/data-table`
74
+ - Sidebars → `@shadcn/sidebar-01` al `16`
74
75
  7. **Shadcn v4 (Base UI)**: En Shadcn UI v4.11.0+, la biblioteca primitiva es `@base-ui/react` (no Radix UI). La propiedad `asChild` **no existe**. Para evitar HTML inválido y problemas de SEO/accesibilidad, no anides interactives (`<Button><Link>`). Aplica las clases de estilo del botón directamente sobre el elemento `<Link>` de Next.js.
75
76
  8. **Compatibilidad Turbopack + CSS**: Turbopack no resuelve directivas `@import` para archivos CSS de `node_modules` (ej. `@import "tw-animate-css"` o `@import "shadcn/tailwind.css"`). En Tailwind CSS v4, define las variables y estilos inline en `globals.css` en lugar de importar desde `node_modules`.
76
77
  9. **Despliegue y Next Config**: Todo proyecto de Next.js debe estar configurado para Docker standalone en `next.config.ts`:
@@ -75,7 +75,7 @@ const writeBrainFile = (filePath: string, title: string, sections: Record<string
75
75
  }
76
76
 
77
77
  export const save_memory = tool({
78
- description: "Guarda un aprendizaje, decisión de diseño, ruta concreta, resolución de error o memoria del proyecto en el archivo .openspec/brain.md. Es acumulativo y añade una marca de tiempo.",
78
+ description: "Guarda una memoria o aprendizaje clave en .openspec/brain.md de forma acumulativa.",
79
79
  args: {
80
80
  category: tool.schema.string().describe("Categoría o sección donde clasificar la memoria (ej: 'design', 'learnings', 'routing', 'errors')"),
81
81
  content: tool.schema.string().describe("El contenido o aprendizaje exacto que se desea guardar. Se recomienda ser conciso y claro.")
@@ -115,7 +115,7 @@ export const save_memory = tool({
115
115
  })
116
116
 
117
117
  export const read_memory = tool({
118
- description: "Recupera la memoria y los aprendizajes del proyecto del archivo .openspec/brain.md. Si se especifica una categoría, solo lee esa sección para optimizar tokens y contexto. Si no se especifica, lista las categorías disponibles.",
118
+ description: "Recupera la memoria y los aprendizajes del proyecto de .openspec/brain.md.",
119
119
  args: {
120
120
  category: tool.schema.string().optional().describe("La categoría específica a leer (ej: 'design', 'learnings', 'routing', 'errors'). Si no se provee, se listarán las categorías disponibles.")
121
121
  },
@@ -101,7 +101,7 @@ function detectPythonPackageManager(root: string): "uv" | "pip" {
101
101
 
102
102
  // Tool: sdd_bootstrap_status
103
103
  export const bootstrap_status = tool({
104
- description: "Reporta el estado de bootstrap del proyecto (qué plantilla se usó, cuándo, qué componentes shadcn están instalados, versión de Node y package manager). Si el proyecto no está bootstrapped, retorna NOT_BOOTSTRAPPED. Útil para que el coder verifique antes de empezar a codear.",
104
+ description: "Reporta el estado de bootstrap del proyecto.",
105
105
  args: {},
106
106
  async execute(args, context) {
107
107
  const root = getRoot(context)
@@ -143,7 +143,7 @@ export const bootstrap_status = tool({
143
143
 
144
144
  // Tool: sdd_bootstrap_nextjs_shadcn
145
145
  export const bootstrap_nextjs_shadcn = tool({
146
- description: "Inicializa un proyecto Next.js 16 + Shadcn UI + Tailwind v4 + Vitest a partir de la plantilla canónica en .opencode/templates/nextjs-shadcn/. Es IDEMPOTENTE: si el proyecto ya está inicializado y no se pasa force=true, no toca nada. Copia archivo-por-archivo (sin pisar los existentes), mergea package.json, y opcionalmente instala dependencias y shadcn components.",
146
+ description: "Inicializa un proyecto Next.js 16 + Shadcn UI + Tailwind v4 + Vitest.",
147
147
  args: {
148
148
  targetDir: tool.schema.string().default(".").describe("Subdirectorio donde se inicializará el proyecto Next.js (ej: 'next-app' o '.')."),
149
149
  components: tool.schema.array(tool.schema.string()).default([]).describe("Lista de shadcn components a instalar (ej: ['button','input','table']). Vacío = no instalar shadcn components."),
@@ -297,7 +297,7 @@ export const bootstrap_nextjs_shadcn = tool({
297
297
  let componentsError: string | null = null
298
298
  if (args.components && args.components.length > 0) {
299
299
  try {
300
- const cmd = `npx shadcn@2.1.8 add ${args.components.join(" ")} --yes --overwrite`
300
+ const cmd = `npx shadcn@latest add ${args.components.join(" ")} --yes --overwrite`
301
301
  execSync(cmd, {
302
302
  cwd: targetPath,
303
303
  stdio: "ignore",
@@ -353,7 +353,7 @@ export const bootstrap_nextjs_shadcn = tool({
353
353
 
354
354
  // Tool: sdd_bootstrap_fastapi
355
355
  export const bootstrap_fastapi = tool({
356
- description: "Inicializa un proyecto FastAPI + Pydantic + Uvicorn + Pytest + Ruff a partir de la plantilla canónica en .opencode/templates/fastapi-sdd/. Es IDEMPOTENTE: si el proyecto ya está inicializado y no se pasa force=true, no toca nada. Copia archivo-por-archivo (sin pisar los existentes), opcionalmente instala dependencias con uv (fallback pip).",
356
+ description: "Inicializa un proyecto FastAPI + Pydantic + Uvicorn + Pytest + Ruff.",
357
357
  args: {
358
358
  targetDir: tool.schema.string().default(".").describe("Subdirectorio donde se inicializará el proyecto FastAPI (ej: 'backend' o '.')."),
359
359
  extras: tool.schema.array(tool.schema.string()).default([]).describe("Lista de paquetes Python adicionales a instalar (ej: ['sqlalchemy','pydantic-settings','pytest-asyncio']). Vacío = no instalar extras extra."),
@@ -543,7 +543,7 @@ export const bootstrap_fastapi = tool({
543
543
 
544
544
  // Tool: sdd_bootstrap_agnostic
545
545
  export const bootstrap_agnostic = tool({
546
- description: "Inicializa un proyecto de tipo script, tooling o agnóstico de forma idempotente (crea un package.json básico, requirements.txt, o estructura plana de archivos según sea necesario). Evita la sobrecarga de frameworks pesados.",
546
+ description: "Inicializa un proyecto de tipo script, tooling o agnóstico de forma idempotente.",
547
547
  args: {
548
548
  language: tool.schema.enum(["javascript", "python", "bash", "google-apps-script", "plano"]).default("plano").describe("El lenguaje o entorno para inicializar"),
549
549
  install: tool.schema.boolean().default(true).describe("Si true, ejecuta npm init -y o uv init de forma básica si aplica.")
@@ -248,7 +248,7 @@ const getPidFilePath = (root: string) => {
248
248
 
249
249
  // Tool: sdd_set_phase (file sdd_core.ts, export set_phase -> sdd_set_phase)
250
250
  export const set_phase = tool({
251
- description: "Establece la fase activa del ciclo de desarrollo SDD (F0_DETECT, F1_CONTRACT, F2_IMPLEMENTATION, F3_VERIFICATION, F4_DEPLOYMENT). Si phase=F1_CONTRACT y se pasa spec_name, crea la carpeta del spec atómicamente y devuelve la ruta absoluta. Si phase=F3_VERIFICATION, ejecuta auto-lint (no bloqueante, solo informativo) y aborta si hay errores de lint.",
251
+ description: "Establece la fase activa del ciclo de desarrollo SDD.",
252
252
  args: {
253
253
  phase: tool.schema.enum(["F0_DETECT", "F1_CONTRACT", "F2_IMPLEMENTATION", "F3_VERIFICATION", "F4_DEPLOYMENT"]).describe("La fase a establecer"),
254
254
  activeContract: tool.schema.string().optional().describe("La ruta o nombre del archivo de contrato JSON activo (.openspec/specs/XXXX_TIMESTAMP_NAME/contract.json)"),
@@ -431,7 +431,7 @@ export const set_phase = tool({
431
431
 
432
432
  // Tool: sdd_get_state (file sdd_core.ts, export get_state -> sdd_get_state)
433
433
  export const get_state = tool({
434
- description: "Obtiene el estado de desarrollo actual (fase activa, contrato seleccionado, stack validado)",
434
+ description: "Obtiene el estado de desarrollo actual.",
435
435
  args: {},
436
436
  async execute(args, context) {
437
437
  const filePath = getStateFilePath(context)
@@ -442,7 +442,7 @@ export const get_state = tool({
442
442
 
443
443
  // Tool: sdd_get_initial_session_data
444
444
  export const get_initial_session_data = tool({
445
- description: "Obtiene atómicamente todos los datos de inicio de sesión: el estado actual del arnés, las memorias históricas clave del Brain ('learnings', 'design', 'routing'), y la lista curada de recomendaciones de diseño de Oh My Design. Reemplaza las llamadas secuenciales a sdd_get_state, brain_read_memory y sdd_list_design_recommendations.",
445
+ description: "Obtiene de forma atómica el estado actual, memorias del Brain y recomendaciones Oh My Design.",
446
446
  args: {},
447
447
  async execute(args, context) {
448
448
  const root = getRoot(context)
@@ -498,7 +498,7 @@ export const get_initial_session_data = tool({
498
498
 
499
499
  // Tool: sdd_save_active_brief
500
500
  export const save_active_brief = tool({
501
- description: "Guarda un resumen breve y estructurado del spec o contrato activo en .openspec/active-brief.md para que sirva de anclaje de contexto de sistema (System State Anchoring) para el subagente sdd-coder o sdd-tester.",
501
+ description: "Guarda un resumen del spec activo en .openspec/active-brief.md como anclaje de contexto.",
502
502
  args: {
503
503
  brief: tool.schema.string().describe("Contenido en formato Markdown con el resumen del spec activo, componentes, diseño y dependencias.")
504
504
  },
@@ -558,7 +558,7 @@ export const save_active_brief = tool({
558
558
 
559
559
  // Tool: sdd_create_spec_folder (file sdd_core.ts, export create_spec_folder -> sdd_create_spec_folder)
560
560
  export const create_spec_folder = tool({
561
- description: "Crea una nueva carpeta ordenada para la especificación del cambio (formato: yyyy-mm-dd__hh-mm-ss_nombre)",
561
+ description: "Crea una nueva carpeta ordenada para la especificación del cambio.",
562
562
  args: {
563
563
  name: tool.schema.string().describe("Nombre del cambio en minúsculas y separado por guiones (ej. sumar-endpoint)")
564
564
  },
@@ -593,7 +593,7 @@ export const create_spec_folder = tool({
593
593
 
594
594
  // Tool: sdd_validate_contract
595
595
  export const validate_contract = tool({
596
- description: "Valida de forma estricta el archivo contract.json contra el contract-schema.json oficial para detectar errores de tipos, alucinaciones o campos faltantes antes de avanzar.",
596
+ description: "Valida contract.json contra el contract-schema.json oficial.",
597
597
  args: {
598
598
  contractPath: tool.schema.string().describe("Ruta relativa al contract.json (ej. '.openspec/specs/XXXX/contract.json')")
599
599
  },
@@ -41,7 +41,7 @@ export const RECOMMENDED_BRANDS: Record<string, { id: string; name: string; cate
41
41
 
42
42
  // Tool: sdd_select_design
43
43
  export const select_design = tool({
44
- description: "Copia fielmente el archivo DESIGN.md y sus ejemplos y recursos interactivos asociados desde el catálogo original de oh-my-design a la carpeta .openspec/ del proyecto.",
44
+ description: "Copia fielmente el archivo DESIGN.md y ejemplos de la marca a .openspec/",
45
45
  args: {
46
46
  brandId: tool.schema.string().describe("ID exacto del diseño en oh-my-design (ej: 'linear.app', 'vercel', 'stripe')")
47
47
  },
@@ -128,7 +128,7 @@ async function selectDesignHelper(brandId: string, context: any) {
128
128
 
129
129
  // Tool: sdd_list_design_recommendations
130
130
  export const list_design_recommendations = tool({
131
- description: "Devuelve una lista curada y corta de marcas de diseño recomendadas (con assets HTML+CSS interactivos), filtrada por categoría de uso. Reemplaza 3-4 llamadas a oh-my-design_list_references en F0.",
131
+ description: "Devuelve una lista curada de marcas de diseño recomendadas.",
132
132
  args: {
133
133
  use_case: tool.schema.enum(["saas", "fintech", "ecommerce", "consumer", "all"]).default("all").describe("Categoría del proyecto para filtrar marcas relevantes"),
134
134
  max_per_category: tool.schema.number().default(3).describe("Máximo de marcas a devolver por categoría"),
@@ -162,7 +162,7 @@ export const list_design_recommendations = tool({
162
162
 
163
163
  // Tool: sdd_apply_brand_tokens
164
164
  export const apply_brand_tokens = tool({
165
- description: "Inyecta tokens de diseño de marca (colores, tipografía, radius) en src/app/globals.css preservando las variables shadcn (--color-border, --color-background, etc.). Usar en F2 cuando se necesite aplicar el tema de marca.",
165
+ description: "Inyecta tokens de diseño de marca en src/app/globals.css.",
166
166
  args: {
167
167
  tokens: tool.schema.string().describe("JSON stringificado con {colors: {...}, typography: {...}, radius: {...}} extraído de contract.json design.tokens"),
168
168
  },
@@ -232,7 +232,7 @@ ${brandVarLines.join("\n")}
232
232
 
233
233
  // Tool: sdd_validate_lucide_icons_batch
234
234
  export const validate_lucide_icons_batch = tool({
235
- description: "Valida un lote de nombres de iconos de Lucide React de forma rápida e idempotente. Si node_modules/lucide-react existe, verifica contra los exports reales; de lo contrario, valida contra un listado estático de los iconos más comunes.",
235
+ description: "Valida un lote de nombres de iconos de Lucide React de forma rápida.",
236
236
  args: {
237
237
  icons: tool.schema.array(tool.schema.string()).describe("Lista de nombres de iconos a validar (ej: ['Sun', 'Moon', 'Plus'])"),
238
238
  },
@@ -34,7 +34,7 @@ const getTargetDir = (root: string): string => {
34
34
 
35
35
  // Tool: sdd_clean_docker_environment
36
36
  export const clean_docker_environment = tool({
37
- description: "Asegura que Docker esté abierto y realiza una limpieza total y agresiva: detiene y elimina TODOS los contenedores (activos o inactivos), remueve TODAS las imágenes, volúmenes y redes para garantizar un lienzo en blanco absoluto antes de desplegar.",
37
+ description: "Asegura que Docker esté abierto y realiza una limpieza total y agresiva.",
38
38
  args: {},
39
39
  async execute(args, context) {
40
40
  const results: Record<string, string> = {}
@@ -114,7 +114,7 @@ export const clean_docker_environment = tool({
114
114
 
115
115
  // Tool: sdd_generate_dockerfile
116
116
  export const generate_dockerfile = tool({
117
- description: "Genera Dockerfile multi-stage, .dockerignore y docker-compose.yml optimizados a partir del stack del proyecto (nextjs|fastapi|agnostic). Detecta package manager desde package.json.",
117
+ description: "Genera Dockerfile, .dockerignore y docker-compose.yml optimizados para el stack.",
118
118
  args: {
119
119
  stack: tool.schema.enum(["nextjs", "fastapi", "agnostic"]).describe("Stack del proyecto"),
120
120
  port: tool.schema.number().default(3000).describe("Puerto de la aplicación"),
@@ -39,7 +39,7 @@ const getPidFilePath = (root: string) => {
39
39
 
40
40
  // Tool: sdd_free_port
41
41
  export const free_port = tool({
42
- description: "Busca y termina de manera forzada cualquier proceso que esté escuchando en un puerto específico",
42
+ description: "Libera un puerto específico de forma forzada.",
43
43
  args: {
44
44
  port: tool.schema.number().describe("El puerto a liberar (ej. 3000 o 8000)")
45
45
  },
@@ -69,7 +69,7 @@ export const free_port = tool({
69
69
 
70
70
  // Tool: sdd_start_server
71
71
  export const start_server = tool({
72
- description: "Inicia un servidor de desarrollo o producción en segundo plano y registra su PID para limpieza posterior",
72
+ description: "Inicia un servidor en segundo plano y registra su PID.",
73
73
  args: {
74
74
  command: tool.schema.string().describe("Comando para iniciar el servidor (ej. 'yarn dev' o 'npm run dev')"),
75
75
  port: tool.schema.number().optional().default(3000).describe("Puerto esperado del servidor (default: 3000)"),
@@ -132,7 +132,7 @@ export const start_server = tool({
132
132
 
133
133
  // Tool: sdd_stop_server
134
134
  export const stop_server = tool({
135
- description: "Detiene el servidor en segundo plano usando el PID registrado",
135
+ description: "Detiene el servidor en segundo plano registrado.",
136
136
  args: {},
137
137
  async execute(args, context) {
138
138
  const root = getRoot(context)
@@ -10,7 +10,7 @@ const getRoot = (context: any) => {
10
10
  };
11
11
 
12
12
  export default tool({
13
- description: "Obtiene de forma nativa y unificada el estado del ciclo SDD (.openspec/sdd_state.json) junto con un resumen de las categorías de memoria del cerebro (Brain). Evita llamadas lentas de consola y es multiplataforma.",
13
+ description: "Obtiene el estado unificado del ciclo SDD y un resumen de las categorías del Brain.",
14
14
  args: {},
15
15
  async execute(args, context) {
16
16
  const root = getRoot(context)
@@ -71,7 +71,7 @@ const parseSemanticErrors = (rawOutput: string, type: "eslint" | "tsc"): any[] =
71
71
 
72
72
  // Tool: sdd_quick_lint
73
73
  export const quick_lint = tool({
74
- description: "Ejecuta el linter del proyecto (eslint) restringido a src/. Devuelve exit code y warnings. Usado como gate automático antes de transicionar a F3.",
74
+ description: "Ejecuta el linter del proyecto (eslint) restringido a src/.",
75
75
  args: {},
76
76
  async execute(args, context) {
77
77
  const root = getRoot(context)
@@ -140,7 +140,7 @@ export const quick_lint = tool({
140
140
 
141
141
  // Tool: sdd_shift_left_verify
142
142
  export const shift_left_verify = tool({
143
- description: "Ejecuta validaciones estáticas Shift-Left completas en el proyecto: ejecuta el compilador de TypeScript (tsc) y el linter (eslint) de manera combinada. Limpia y parsea semánticamente los stack traces y logs de error crudos, devolviendo un JSON limpio y estructurado de errores que el LLM puede digerir y solucionar de inmediato sin perder atención.",
143
+ description: "Ejecuta validaciones estáticas Shift-Left completas (tsc + eslint) combinadas.",
144
144
  args: {},
145
145
  async execute(args, context) {
146
146
  const root = getRoot(context)
@@ -323,7 +323,7 @@ export const shift_left_verify = tool({
323
323
 
324
324
  // Tool: sdd_generate_tests
325
325
  export const generate_tests = tool({
326
- description: "Autogenera plantillas de pruebas unitarias/integración en el directorio corporativo de pruebas a partir de los escenarios de prueba descritos en el contrato activo de sdd_state.json. No pisa archivos de pruebas existentes.",
326
+ description: "Autogenera plantillas de pruebas a partir de los escenarios del contrato activo.",
327
327
  args: {},
328
328
  async execute(args, context) {
329
329
  const root = getRoot(context)
@@ -442,7 +442,7 @@ export const generate_tests = tool({
442
442
 
443
443
  // Tool: sdd_save_playwright_artifacts
444
444
  export const save_playwright_artifacts = tool({
445
- description: "Promueve y archiva los artefactos de captura visual/videos (.openspec/.playwright/) generados por Playwright a la carpeta del spec/contrato activo de forma ordenada, evitando ensuciar la raíz.",
445
+ description: "Promueve y archiva los artefactos de Playwright a la carpeta del contrato activo.",
446
446
  args: {
447
447
  callId: tool.schema.string().optional().describe("ID de llamada de Playwright MCP específica. Si no se pasa, toma la última ejecución de forma automática."),
448
448
  move: tool.schema.boolean().default(false).describe("Si true, mueve los archivos en lugar de copiarlos.")
@@ -9,7 +9,7 @@ DB_PATH = "/Users/wavesbyte/.local/share/opencode/opencode.db"
9
9
 
10
10
  # Escribe aquí el ID de la sesión que deseas exportar (ejemplo: "ses_1234...")
11
11
  # Si se deja vacío, el script requerirá el ID como argumento al ejecutarlo
12
- TARGET_SESSION_ID = "ses_11d2"
12
+ TARGET_SESSION_ID = "ses_11a7"
13
13
 
14
14
 
15
15
  def format_timestamp(ts):
package/opencode.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "./.opencode/oh-my-design/packages/mcp/dist/index.mjs"
44
44
  ],
45
45
  "enabled": true,
46
- "purpose": "MCP oficial de Oh My Design para buscar, consultar y aplicar temas de diseño (Toss, Stripe, Supabase, etc.)."
46
+ "purpose": "Busca, consulta y aplica temas de diseño (Toss, Stripe, Supabase, etc.)."
47
47
  },
48
48
  "shadcn": {
49
49
  "type": "local",
@@ -54,7 +54,7 @@
54
54
  "mcp"
55
55
  ],
56
56
  "enabled": true,
57
- "purpose": "Librería UI objetivo. Usar para browse/search/install de componentes y blocks (dashboards, landings, auth, forms)."
57
+ "purpose": "Usa para browse/search/install de componentes y blocks oficiales de Shadcn UI."
58
58
  },
59
59
  "context7": {
60
60
  "type": "local",
@@ -76,7 +76,7 @@
76
76
  "--isolated"
77
77
  ],
78
78
  "enabled": true,
79
- "purpose": "Playwright MCP. Artefactos (screenshots, traces, videos, downloads) van a .openspec/.playwright/<call-id>/. Para evidencia por sesión SDD, promueve los artefactos relevantes a .openspec/specs/<activeContract>/playwright/ con .opencode/tools/save-playwright-artifacts.sh. --isolated evita ensuciar el perfil del browser en disco."
79
+ "purpose": "Ejecuta pruebas de regresión visual y capturas de pantalla de Playwright."
80
80
  },
81
81
  "next-devtools": {
82
82
  "type": "local",
@@ -89,7 +89,7 @@
89
89
  "environment": {
90
90
  "NEXT_TELEMETRY_DISABLED": "1"
91
91
  },
92
- "purpose": "Toolchain oficial Vercel para Next.js 16. Provee init, nextjs_docs, nextjs_index/nextjs_call (errores, logs, rutas, Server Actions en runtime), browser_eval, upgrade_nextjs_16 y enable_cache_components. Complementa context7 (docs genérico) con docs y runtime específicos de Next 16 (dev server expone /_next/mcp). Telemetría desactivada explícitamente. **DESHABILITADO por defecto** — solo activar on-demand cuando un subagente reporte un error específico de Next 16 que requiera docs oficiales. La razón: el tool `init` inyecta 1000+ palabras de 'FORGET ALL PRIOR KNOWLEDGE' en el contexto del coder (~8K tokens de reasoning desperdiciado en sesiones normales)."
92
+ "purpose": "Toolchain oficial para depurar Next.js 16 (deshabilitado por defecto)."
93
93
  },
94
94
  "lucide-icons": {
95
95
  "type": "local",
@@ -100,7 +100,7 @@
100
100
  "--stdio"
101
101
  ],
102
102
  "enabled": true,
103
- "purpose": "Permite buscar, filtrar y obtener ejemplos de uso JSX de más de 1,500 iconos de Lucide React de forma exacta mediante herramientas del MCP."
103
+ "purpose": "Busca y obtiene ejemplos de uso de iconos de Lucide React."
104
104
  }
105
105
  }
106
106
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zugzbot",
3
- "version": "1.0.38",
3
+ "version": "1.0.40",
4
4
  "description": "Fácil instalador del arnés SDD de Zugzbot para proyectos OpenCode",
5
5
  "type": "module",
6
6
  "bin": {