Un comando para que un proyecto nuevo arranque con contexto
agent-kits resuelve un problema concreto y repetido: cada vez que empiezo un proyecto con asistencia de
IA, el agente arranca sin saber nada — ni qué stack hay, ni qué convenciones se usan, ni qué flujos de
trabajo existen. La respuesta habitual es improvisar un par de archivos de contexto a mano, distintos en
cada repo. Acá el punto de entrada es un solo comando, /kits-init, que hace ese armado de forma
reproducible.
Al invocarlo dentro de cualquier proyecto, guía por preguntas estructuradas hasta dejar una carpeta
.agents/ con su workspace.json, sus agentes, sus skills y sus workflows: los que el proyecto necesita,
elegidos por quien responde, no un template fijo copiado entero.
El catálogo del que se sirve son 7 packs (context, design, backend-design, fullstack-design,
frontend, backend, tools), 50 skills y 4 agentes globales (artifact-validator,
design-critic, research-scout, wireframe-renderer). Y no hay una sola línea de código ejecutable en
el repositorio: es Markdown de punta a punta.
agent-kits/
├── SKILL.md, README.md, PROJECT-CONTEXT.md,
│ workspace-schema.md, repair-upgrade.md, catalog-index.md
├── skills/ → 50 · skills/<id>/SKILL.md
├── agents/ → 4 agentes globales
├── meta/ → catalog-author.md (autoría del propio sistema, no se distribuye)
└── packs/ → 7Skill, pack y workflow — y ningún motor que los ejecute
La decisión que ordena todo el proyecto está escrita textualmente en su PROJECT-CONTEXT.md:
“El agente ES el runtime. No hay un motor desplegado, ni servidor, ni proceso. Todo es Markdown que un agente lee e interpreta.”
Eso obliga a que la composición sea declarativa: si no hay proceso que resuelva dependencias en tiempo de ejecución, la estructura tiene que ser legible tal cual está escrita. De ahí salen los tres conceptos centrales:
Skill — la unidad de capacidad
Vive en skills/<id>/SKILL.md y declara en su frontmatter qué consume y qué produce. Lo importante es lo que NO sabe: una skill no sabe en qué flujo corre. Esa ignorancia deliberada es lo que la hace componible en más de un pack.
Pack — la composición por dominio
packs/<id>/pack.md más sus agents/ y workflows/. El pack no contiene las skills: las referencia por id, y las skills viven en un pool global único. Instalar dos packs que comparten una skill no duplica nada.
Workflow — la secuencia
Define qué skill corre, en qué orden y con qué modo. Es el único lugar donde vive el orden; sacarlo de las skills es lo que permite que la misma skill entre en flujos distintos sin tocarse.
Lo que se gana con esto es que el sistema se lee entero sin ejecutarlo: no hay estado oculto, no hay build, no hay versión instalada que difiera del repositorio. Un cambio en una skill es un cambio en un archivo de texto, y se revisa como cualquier otro diff.
Lo que se pierde es toda garantía automática. No hay nada que valide que una referencia por id apunta a una skill que existe, ni que un workflow nombre fases coherentes: no hay compilador que lo verifique porque no hay compilación. La consistencia depende de la disciplina de escritura y de que el agente que lo lee interprete bien lo que hay. Es el intercambio que se paga por no tener runtime propio.
El propio sistema aplica esa regla a sí mismo: meta/catalog-author.md es el agente que se usa para
escribir el catálogo, y está explícitamente marcado como no distribuible — la herramienta de autoría no
viaja con el producto.
Primero mirar el proyecto, después preguntar
/kits-init no arranca preguntando. La Fase 1 es de detección, y recién con eso resuelto se abre la
conversación — la diferencia entre un cuestionario genérico y uno que ya sabe dónde está parado.
Lo que detecta antes de abrir la boca:
- El stack del proyecto anfitrión, buscando en orden
package.json,pyproject.toml/requirements.txt,pom.xml/build.gradle,Cargo.toml,go.mod,composer.json. - Señales de disciplinas, sin preguntar todavía:
**/*.featuresugiere BDD; unopenapi.yamlo una carpetaproto/sugieren contract-first; la config de un test runner sugiere TDD. - El runtime en el que está corriendo — de eso se ocupa la zona siguiente.
Con eso resuelto, la Fase 2 ramifica en tres escenarios que no son variantes cosméticas del mismo camino:
proyecto vacío sin stack (Greenfield), stack ya detectado (proyecto existente), o un
.agents/workspace.json que ya está ahí (Repair/Upgrade). Ese tercer caso es el que más lógica se
llevó: está documentado aparte, en su propio repair-upgrade.md, y es la Fase 6 del flujo.
Que exista un camino de reparación separado dice algo sobre para qué se usa el sistema: la instalación
inicial es la parte fácil. El caso difícil es volver a un proyecto que ya tiene un .agents/ armado,
posiblemente con una versión anterior del catálogo, y actualizarlo sin pisar lo que se editó a mano.
Preguntar bien en tres entornos distintos
Un sistema que se apoya en preguntas estructuradas depende de una tool que no existe igual en todas
partes. Claude Code expone AskUserQuestion; OpenCode expone question; y un chat plano no expone nada.
La salida no fue elegir uno. En la Fase 1, junto con la detección de stack, /kits-init lee las variables
de entorno $CLAUDECODE y $OPENCODE para decidir qué tool usar, y SKILL.md documenta esa
correspondencia como una tabla de tools por runtime, con un fallback explícito a chat plano para runtimes
desconocidos.
Lo que me interesa marcar de esto es cuándo se decidió. La cross-compatibilidad no se parchó después de que algo se rompiera en otro entorno: la feature de runtime-awareness entró durante la misma sesión de diseño en la que se armó el sistema, con el resto de la arquitectura todavía en movimiento. Es una decisión de diseño, no una compatibilidad retroactiva.
El costo es que el flujo no puede apoyarse en ninguna capacidad avanzada de una tool concreta: todo lo que
/kits-init pregunta tiene que poder expresarse también como una pregunta de chat plano. El denominador
común lo fija el runtime más pobre.
Una sesión de diseño, no una serie de retoques
Todo el repositorio son 22 commits del 2026-05-22, entre las 17:10 y las 23:46: una sola sesión de unas seis horas y media, íntegramente mía, sin fork ni plantilla de terceros. Y el historial no se lee como una implementación lineal de algo ya decidido, sino como el diseño ocurriendo:
La arquitectura se renombró a mitad de camino
El primer commit dice feat: initial commit — app-init skill system: el skill todavía se llamaba app-init y la carpeta que generaba era .my-system/. Los dos nombres cambiaron durante la misma sesión, a kits-init y .agents/. Renombrar el concepto central mientras se lo está construyendo es incómodo, pero es más barato ahí que después, cuando ya hay proyectos con esa carpeta creada.
El último commit borra una capa entera
refactor: merge agent.md into SKILL.md (drop thin launcher pattern) — así cierra el repositorio. Había un archivo agent.md que solo servía para lanzar el skill, y se eliminó fusionándolo en SKILL.md. En el camino también se extrajeron el schema del workspace y el flujo de repair-upgrade a archivos propios: menos indirección donde no aportaba, más separación donde sí.
Sin tests y sin CI verificables
No hay carpeta de tests ni workflow de integración continua en el repositorio. PROJECT-CONTEXT.md documenta en su árbol una carpeta tests/ con sandboxes de prueba, pero esa carpeta no está en el clon actual: no puedo afirmar que exista una suite. Lo que sostiene el caso es la estructura del catálogo y su documentación, no una red de pruebas que no puedo mostrar.
El proyecto figura como en proceso y no tiene cambios recientes — sigue en uso activo, sin que eso haya exigido tocarlo. Es la consecuencia razonable de lo que es: una herramienta de bootstrapping se usa mucho más de lo que se modifica, y el trabajo real quedó en decidir qué unidades existen y cómo se componen, que es lo que un catálogo en Markdown deja a la vista.
Un detalle menor que prefiero decir yo antes de que alguien cuente: el README.md publicado declara 51
skills, y las carpetas reales bajo skills/ son 50. La cifra que uso en este caso es la de las carpetas.