Ir al contenido

Trabajar con un agente

Un agente de código se maneja bien con Kevin CMS: el modelo de contenido es un fichero TypeScript, los tipos se generan solos y todo lo demás son cuatro comandos. Lo que necesita es saber dónde está el límite, porque dos de esos comandos escriben ficheros y otro toca una base de datos de producción.

Esta página es para que se lo escribas una vez.

El sitio publica tres ficheros pensados para eso:

Ruta Qué lleva
/llms.txt Medio kilobyte: la portada del sitio y los enlaces a los otros dos. No es un índice de páginas
/llms-small.txt El sitio entero sin lo accesorio, en un solo fichero de texto. Es el más pequeño de los dos
/llms-full.txt El sitio entero tal cual, en un solo fichero de texto
https://kevin-cms.pages.dev/llms.txt
https://kevin-cms.pages.dev/llms-small.txt
https://kevin-cms.pages.dev/llms-full.txt

/llms.txt es el punto de entrada: un agente que sepa seguir enlaces lo lee primero y decide. Si lo pegas tú a mano, pega uno de los otros dos —el pequeño es el que cabe en más ventanas de contexto—. Con cualquiera de ellos delante, un agente deja de inventarse tipos de campo. Es la diferencia entre que escriba richText —que no existe— y que escriba textarea.

Un fichero en la raíz del proyecto, que es lo que casi todos los agentes leen antes de tocar nada. Esto es lo mínimo que merece la pena:

AGENTS.md
## Kevin CMS
El modelo de contenido vive en `cms.config.ts`. Es la única fuente de verdad: el schema, los tipos y
las migraciones salen de ahí.
- Hay **nueve** tipos de campo: `text`, `textarea`, `number`, `checkbox`, `date`, `select`, `json`,
`relationship`, `upload`. No hay `richText`, ni `array`, ni `blocks`. Texto largo es `textarea` con
Markdown dentro; estructuras a medida son `json`.
- `.cms/` está generado. No lo edites: se reescribe en cada arranque de `astro dev`.
- Tras cambiar `cms.config.ts`, ejecuta `pnpm cms db:migrate` y **enséñame el SQL** que aparezca
en `migrations/` antes de aplicar nada.
- No ejecutes `db:apply --remote` nunca. Eso lo lanzo yo.
- Toda página de Astro que lea contenido necesita `export const prerender = false`.
- `findOne` devuelve `null`; `findByID` lanza `NotFoundError`. No son intercambiables.

Ajústalo a tu gestor de paquetes y a tu flujo. Lo importante son las dos últimas líneas de contenido y la de --remote.

Comando ¿Sin supervisión? Por qué
cms db:generate Solo escribe .cms/, que ya se regenera solo en cada arranque
cms db:migrate Escribe un .sql en migrations/. No toca ninguna base de datos
cms db:pop Borra la última migración generada. No revierte nada en la base
cms db:apply Con criterio Aplica sobre la D1 local, que es una copia en .wrangler/
cms db:apply --remote No Aplica en producción

La línea está en si el comando escribe ficheros que un humano lee después, o si cambia algo que ya existe fuera de tu máquina. db:generate y db:migrate están del lado bueno: producen un diff, y un diff se revisa.

Lo mismo vale para db:migrate cuando la migración es destructiva: con terminal avisa de que va a quitar o cambiar columnas y pide confirmación; sin terminal la genera igual. Sigue siendo seguro —escribe un fichero, no lo aplica— pero es una razón más para leer el SQL antes de db:apply.

Si el agente quita title y añade heading, ni Kevin CMS ni drizzle-kit pueden saber si querías un renombrado o un borrado más un alta. En vez de elegir por ti, drizzle-kit se planta:

missing_hints: 1 unresolved decisions
1. Rename or create — column public.posts.heading

db:migrate sale con código 2 y no genera ninguna migración. Un agente que vea eso tenderá a reintentar o a inventarse una migración; lo correcto es escribir el ALTER TABLE a mano:

ALTER TABLE posts RENAME COLUMN title TO heading;

Ver Renombrar un campo no está soportado.

.cms/schema.ts y .cms/types.d.ts los escribe el codegen a partir de cms.config.ts, y la integración de Astro los regenera en cada arranque además de vigilar el config mientras corre el dev. Cualquier edición a mano ahí desaparece en el siguiente pnpm dev.

Es un síntoma que se reconoce fácil: si el arreglo que propone un agente consiste en tocar un tipo dentro de .cms/, el arreglo de verdad estaba en cms.config.ts. Ese directorio va en el .gitignore; lo que se commitea es migrations/.

Ventana de terminal
pnpm cms db:generate --check

Sale con código 1 si cms.config.ts se ha movido más allá de la última migración, enumerando qué cambió. Compara contra los snapshot.json de migrations/, que están commiteados, así que funciona sobre un clon limpio y también en integración continua.

Es la comprobación que cierra el bucle: el agente edita el config, y esto dice si se olvidó de generar la migración.