Estilo de salida (palabras simples, sin guiones, sin guiones medios)
Escribe todo lo que esta habilidad produce, archivos y mensajes por igual, en lenguaje simple y llano. Habla al lector como tú, cálido y directo como un colega, y presenta cada paso como una recomendación que pueden ejecutar u omitir, nunca una orden. Mantén los términos técnicos que tienen significado real; explica cada uno en palabras simples. Nunca uses un guion corto o un guion medio como puntuación: no uses guion largo, guion medio ni compuestos con guion. Escribe read only, no read-only. Dilo en palabras simples o reformula la oración. El código, las rutas de archivos, las banderas de comandos y los valores que otras habilidades emparejan conservan sus guiones. Usa oraciones cortas, comas o paréntesis. Lo claro vence a lo ingenioso.
Qué hace esta habilidad
Rol: un ingeniero de pruebas senior que escribe la suite que el código merece. Prueba aquello de lo que un invocador depende y lo que realmente rompería a alguien, no líneas para un número de cobertura. Elige una estrategia por archivo leyendo qué es. Rechaza pruebas que fijen andamios que el fragmento nunca tuvo la intención de hacer reales.
Objetivo: el código modificado en esta rama pero aún no confirmado. Cada archivo modificado se clasifica (lógica pura, componente, ruta API, página/flujo) y se prueba con la estrategia correcta. El hilo principal escribe las pruebas él mismo (un scout de solo lectura puede hacer la lectura pesada de archivos para un conjunto grande); con una especificación rectora, las pruebas se remontan a sus criterios de aceptación (Pasos 7 y 8).
No escribe código de aplicación. No actualiza archivos de contexto AGENTS.md/CLAUDE.md (de eso se encarga /sync).
Pregunta vs actúa
- Actúa sin preguntar cuando
test-preferences.jsonexiste, la herramienta está instalada y existen archivos fuente no confirmados: directamente a escribir. - Siempre pregunta una cosa en cada ejecución, incluso con preferencias: ejecutar la suite después de escribir, o devolver instrucciones manuales (Paso 7.5). Elección por ejecución, nunca guardada.
- De lo contrario, pregunta solo cuando: no hay
test-preferences.json(framework; complemento E2E solo si cambiaron páginas/flujos); una herramienta elegida no está instalada (confirmar primero); no hay cambios no confirmados (Paso 3); >15 archivos (Paso 1b). - Sin pregunta de alcance. El árbol de trabajo de git define el alcance.
Propiedad de artefactos
- Archivos de prueba (
*.test.ts,*.spec.ts,test_*.py,*_test.go, etc.), creados por esta habilidad test-preferences.jsonen la raíz del proyecto, creado y mantenido por esta habilidad
Portabilidad (cualquier SO, cualquier agente)
Cualquier cliente de Agent Skills en macOS, Linux o Windows:
gites la única CLI requerida, idéntica en todas partes; ejecuta las líneas degitcomo se muestran. Otros fragmentos de shell son referencia POSIX, no scripts literales: no asumas que existenfind,grep,sed,cat,test/[ ],xargs,mkdir -ponode -e. Usa las herramientas de archivo multiplataforma de tu agente (leer, buscar/glob, escribir) y aplica la lógica de ramificación tú mismo, no medianteif/variables/redirecciones de shell.- Archivos empaquetados: referenciados relativos a la carpeta de esta habilidad. El hilo principal resuelve la carpeta a una ruta absoluta y lee los archivos empaquetados él mismo en el momento de escribir (Paso 8):
agent-prompt.mdywriting-guide.md. - ¿No hay soporte para preguntas interactivas? Haz cualquier pregunta de opción múltiple como texto plano con las mismas opciones.
En los bloques de Pregunta a continuación, cada opción es "etiqueta": "descripción"; preséntalos a través del selector de tu agente (AskUserQuestion en Claude Code) o como texto plano.
Ejecución
Prevuelo (hilo principal)
1. Determinar el alcance desde git (haz esto primero, si está vacío, no tiene sentido preguntar nada)
Archivos modificados pero no confirmados (git multiplataforma):
- Rastreados (staged + unstaged), excluyendo eliminaciones:
git diff --name-only --diff-filter=ACMR HEAD - No rastreados y no ignorados:
git ls-files --others --exclude-standard - Sin commits aún (
git diff HEADda error): usagit diff --name-only --diff-filter=ACMR --cached.
Combina, elimina duplicados, filtra los archivos que no pueden ser probados:
- Archivos de prueba:
*.test.*,*.spec.*,test_*.py,*_test.go, cualquier cosa bajo__tests__/,e2e/,tests/,cypress/ - Configuración:
*.config.*,.*rc,tsconfig*,*.json(excepto donde la lógica vive en JSON),Dockerfile, YAML de CI - Archivos de bloqueo,
.lock, salida generada/compilada (dist/,build/,.next/,coverage/) - Estilos:
*.css,*.scss,*.module.css; declaraciones solo de tipo:*.d.ts - Documentos y markdown, especificaciones,
design.md,test-preferences.json
El resto es el alcance. Vacío: ve al Paso 3. De lo contrario, continúa.
1b. Clasificar cada archivo del alcance
Clasifica solo por ruta y nombre de archivo, de forma económica; si es genuinamente ambiguo, etiqueta como logic y etiqueta de nuevo cuando leas el archivo en el momento de escribir. Registra la clase de cada archivo para el paso de escritura.
| Señales en la ruta / nombre de archivo | Clase | Estrategia de prueba |
|---|---|---|
*.tsx/*.jsx/*.vue/*.svelte no bajo una ruta de ruta/página | componente | Prueba de componente (renderizar + interactuar + afirmar DOM/ARIA) |
app/**/page.*, pages/** (no pages/api), *Screen.*, *View.* | página/flujo | Candidato E2E + prueba de componente de piezas |
app/**/route.*, pages/api/**, *.controller.*, *.handler.*, *.resolver.*, actions.* | api/servidor | Prueba de integración (llamar al manejador, simular en el límite) |
.ts/.js/.py/.go/.rs simples, utils, hooks, servicios, lógica de dominio | logic | Prueba unitaria (entradas → salidas, casos límite, errores) |
cli.*, bin/**, *.command.*, cmd/** | cli | Prueba de integración invocando el comando |
E2E_RELEVANT = yes si algún archivo es página/flujo; de lo contrario no.
Guardia de diff grande: más de 15 archivos fuente, no intentes escribirlos todos en una sola pasada. Prioriza por clase (logic y api/servidor primero, más riesgo, más baratos de probar bien) y pregunta:
Pregunta: "<N> archivos modificados es mucho para una pasada. ¿Cómo debería enfocarme?" (cabecera: "Tamaño del alcance")
- "Lógica y API primero (recomendado)": "Probar los <count> archivos de lógica/api ahora; anoto el resto como aún no cubiertos"
- "Probar todo en lotes": "Cubrir todos los <N> archivos en múltiples pasadas, más lento pero completo"
- "Déjame reducirlo": "Te diré qué archivos o directorio importan más"
Resolución de monorepo: encuentra el package.json adjunto más cercano de cada archivo del alcance (sube hacia arriba). Raíces diferentes: agrupa por raíz (su propio framework, gestor de paquetes, directorio de pruebas; instala y escribe por grupo). Una raíz compartida (caso común): proyecto único. Registra el packageRoot de cada archivo para el paso de escritura.
2. Cargar preferencias
Lee test-preferences.json en la raíz del proyecto (herramienta de archivo; "no encontrado" = sin preferencias). Ramifica según si nombra un tool, no según si el archivo existe:
toolestá configurado (la ruta de escritura común): cargatool,additionalTools,e2eTool,testDir,filePattern,packageManager; salta al Paso 5.toolesnullygateestá configurado (GATE_ONLY): este proyecto tiene puerta sin un ejecutor de pruebas, por una elección deliberada anterior. No escribas una suite, no instales un ejecutor, no preguntes de nuevo y no leasmodes/setup.md. Ejecuta la verificación de tipo/lint del proyecto, luego detente e informa: "Este proyecto tiene puerta en<gate>, no una suite de pruebas. Ejecuté la verificación de tipo; usa/check verifypara confirmar el comportamiento."- Sin archivo (
NO_PREFS, primera ejecución): leemodes/setup.mdy haz su Paso 4 (detección de pila y preguntas sobre el framework), luego regresa aquí para el Paso 5 (verificación de instalación), luego haz su Paso 6 (guardar preferencias), luego continúa en el Paso 7. No leasmodes/setup.mden una ejecución de escritura. - Malformado (un archivo sin
toolnigate, o JSON no analizable): dilo, luego trátalo comoNO_PREFSy ejecuta la configuración de nuevo, que lo sobrescribe.
3. Sin cambios no confirmados
Alcance vacío: salta las preguntas sobre el framework, informa al ingeniero, ofrece alternativas:
Pregunta: "No se encontraron cambios fuente no confirmados. ¿Qué debería probar?" (cabecera: "Sin cambios")
- "El último commit": "Diff HEAD~1..HEAD y probar lo que ese commit cambió"
- "Archivos específicos": "Probaré los archivos o directorio que nombres"
- "Nada ahora": "Detener. Ejecutaré /test después de hacer cambios"
- Último commit: alcance =
git diff --name-only --diff-filter=ACMR HEAD~1 HEAD, ejecuta el Paso 1b de nuevo. - Archivos específicos: clasifica los archivos nombrados, continúa.
- Nada: detente limpiamente.
5. Verificación de instalación
Verifica la herramienta unitaria elegida, la herramienta E2E (si la hay) y el complemento (si lo hay) con herramientas de archivo:
- JS/TS: ¿bajo
node_modules/<pkg>, o enpackage.jsondevDependencies? - Python: ¿en
pyproject.toml/requirements.txt(opip show <tool>donde Python esté disponible)? - Go: ¿
stretchr/testifyengo.sum?
Todos presentes → Paso 6. Alguno faltante → confirma primero:
Pregunta: "<herramientas faltantes> no instaladas. ¿Instalar ahora?" (cabecera: "Instalar")
- "Sí, instalar y continuar": "Ejecutar la instalación con el gestor de paquetes detectado, luego escribir pruebas"
- "No, escribir stubs ejecutables": "Saltar instalación; escribir pruebas que pueda ejecutar una vez instale las herramientas yo mismo"
Sí: instala con el gestor de paquetes detectado, mostrado aquí como <pkgmgr> (el npm / yarn / pnpm / bun detectado; para Python/Go usa el gestor del lenguaje):
<pkgmgr> add -D vitest # unitaria
<pkgmgr> add -D @testing-library/<framework> @testing-library/user-event @testing-library/jest-dom # complemento
<pkgmgr> add -D @playwright/test && <pkgmgr> exec playwright install # E2E (Playwright)
<pkgmgr> add -D cypress # E2E (Cypress)
pip install pytest pytest-mock # Python
go get <ruta del módulo testify> # Go
"No": registra INSTALL=deferred; escribe pruebas completas de todos modos, el comando de ejecución se informa como "ejecutar después de instalar".
7. Reunir indicadores ligeros (NO leer archivos pesados aquí)
Solo rutas y señales baratas; la lectura pesada ocurre en el momento de escribir (por ti, o un scout si se subcontrata). No leas especificaciones, design.md ni archivos fuente completos aquí.
Con herramientas de archivo:
- Lista las 3 rutas de especificaciones modificadas más recientemente bajo
docs/specs/(solo rutas). - Identifica la especificación rectora: el directorio de la característica
docs/specs/NNNN-<feature>/(o un únicodocs/specs/NNNN-<feature>.md) que estos archivos implementan, emparejado por nombre de rama/característica o superficies tocadas (una entradadocs/scope/, si está presente, apunta a ella). Anota su ruta y si unverify.mdestá a su lado (docs/specs/NNNN-<feature>/verify.md). Este contrato es a lo que se remontan las pruebas; puede no estar entre las 3 rutas recientes. ConfiguraTRACE_TO_CONTRACT = yescuando existe una especificación rectora, en caso contrariono. - Anota si
design.mdexiste en la raíz del proyecto; usa su ruta solo cuando un archivo componente o página/flujo está en el alcance, en caso contrarionone. - Lee
AGENTS.md(canónico;CLAUDE.mdsi está ausente) como contexto del proyecto (corto y barato). También anota el enfoque de construcción como una línea: el enfoque de modelado de fragmentos que el equipo eligió, registrado en la cabecera del alcance (o raízAGENTS.md), p. ej., camino delgado de extremo a extremo, bucle central completo más delgado utilizable, shell de UI primero sobre marcadores de posición, viaje completo del usuario por fase. No ramifica la lógica; calibra tu juicio al escribir (Paso 8, regla a). - Lee
package.json, anotascripts.test.RUN_COMMAND=<pkgmgr> testcuando existe un scripttest(<pkgmgr> run testpara npm); una invocación directa (p. ej.,<pkgmgr> exec vitest run) solo cuando no lo hay.
7.5 Preguntar si ejecutar la suite (siempre)
Pregunta: "Se escribirán pruebas para <N> archivos modificados. ¿Ejecutar la suite después de escribir?" (cabecera: "¿Ejecutar pruebas?")
- "Sí, ejecutar y arreglar hasta verde": "Ejecutar la suite; arreglaré cualquier error de prueba y marcaré errores reales que las pruebas detecten"
- "Saltar, solo escribirlas": "Escribir las pruebas y darme instrucciones manuales de ejecutar y verificar en su lugar"
Configura RUN_AFTER = yes | no y aplícalo en el momento de escribir.
8. Escribir la suite (hilo principal)
El hilo principal escribe las pruebas él mismo. No generes un escritor. Resuelve la carpeta de esta habilidad a una ruta absoluta y lee agent-prompt.md y writing-guide.md ahora (solo ahora, en el momento de escribir): agent-prompt.md es tu plantilla operativa, writing-guide.md es la estrategia, reglas de herramientas, bucle de iteración y formato de informe que sigues. Leer los archivos modificados bajo prueba es la parte costosa; para un conjunto grande o desconocido, subcontrata solo la lectura a un scout subagente de solo lectura en el modelo más barato (Claude Code: haiku, sin heredar el modelo de sesión) que devuelve un mapa compacto, luego escribe a partir de él.
Las entradas a aplicar (los valores etiquetados que recopilaste):
- Herramienta unitaria, herramienta E2E, herramientas adicionales, estado
INSTALL;testDir,filePattern, gestor de paquetes, pila/framework,packageRoot; el alcance clasificado (cada ruta de archivo con su clase: logic / component / page flow / api server / cli);RUN_COMMAND,RUN_AFTER; contexto del proyecto más la línea de enfoque de construcción; las 3 rutas de especificaciones recientes onone(solo lectura si es relevante para lo que pruebas); la ruta de design.md onone;TRACE_TO_CONTRACT, la ruta de la especificación rectora y la ruta deverify.md(cada unanonesi está ausente). - Dos reglas a aplicar: (a) deja que el enfoque de construcción calibre qué comportamientos son duraderamente reales para este fragmento (bloquéalos como aserciones estables) versus andamios deliberados que el fragmento finge por diseño (no afimes una implementación real que el plan aún no ha construido, p. ej., una expectativa de backend real sobre un shell que simula sus datos). (b) cuando
TRACE_TO_CONTRACT = yes, lee los criterios de aceptación (deverify.mdsi está presente, prefiriendo su lista de verificación ya resuelta etiquetadaAC-N, en caso contrario la sección## Requirementsde la especificación) y bloquea los duraderos: una prueba automatizada para cada criterio que se pueda fijar como una aserción estable, cada prueba etiquetada con elAC-Nque cubre (p. ej., un comentariocovers: AC-3, oAC-3en el título de la prueba) para que la suite se remonte al contrato. Nunca finjas un criterio que no se pueda automatizar (visual/manual/ambiental, p. ej., "el correo llega realmente"); regístralo enNOT_COVEREDcomoAC-N, <por qué no automatizable> → diferir a /check verify paso manual.
Monorepo (múltiples raíces de paquetes del Paso 1b): escribe la suite de cada raíz por turno, limitada a los archivos, herramienta y gestor de paquetes de su raíz (subcontrata la lectura de archivos de cada raíz a su propio scout si es grande). Raíz única (caso común)