CLI
Esta página está transcrita de la ayuda del propio binario, no escrita de memoria: cada bloque de
ayuda es una copia de lo que imprime cms <comando> -h.
Los comandos con prefijo operan sobre un subsistema: db: es el ciclo del esquema —de tu
cms.config.ts a las tablas de D1, y de vuelta si te arrepientes—, settings: los ajustes
guardados en KV, secret: el secreto con el que se firman las sesiones, y resources: los recursos
de Cloudflare contra los que el proyecto está declarado. Los sueltos —init, deploy, update y
doctor— no llevan prefijo precisamente porque no operan sobre ningún subsistema: operan sobre el
proyecto entero, y son el ciclo de vida de una instalación: crearla, subirla, actualizarla y
diagnosticarla.
pnpm cms --helpUsage: cms [options] [command]
Genera el schema, los tipos y las migraciones de Kevin CMS
Options: -V, --version Muestra la versión del CMS -h, --help Muestra esta ayuda
Commands: db:generate [options] Escribe .cms/ desde cms.config.ts y avisa si hay deriva db:migrate [options] Ejecuta db:generate y después drizzle-kit generate db:apply [options] Aplica las migraciones pendientes a D1, en local salvo --remote db:pop [options] Borra la última migración generada deploy [options] Prepara el repositorio, aplica las migraciones remotas y abre el dashboard doctor [options] Diagnostica el cableado del proyecto y dice cómo arreglar cada fallo secret:set [options] [nombre] Genera el secreto de sesión y lo guarda en .dev.vars, o en el Worker con --remote resources:create [options] Crea la D1, el bucket de R2 y los dos KV que falten, y wrangler escribe los ids resources:list [options] Dice qué binding tiene id y cuál sigue siendo solo local init [options] [dir] Crea un proyecto Astro en Cloudflare con Kevin CMS ya cableado update [options] Actualiza el CMS, enseña lo que rompe y alinea las peers de la versión destino settings:reset-site-url [options] Quita el siteUrl guardado en KV para recuperar el acceso al paneldb:generate lleva el prefijo aunque no toque la base de datos: un solo grupo se lee mejor que un grupo más
una excepción suelta.
db:generate
Sección titulada «db:generate»Lee tu configuración y escribe .cms/schema.ts y .cms/types.d.ts.
Usage: cms db:generate [options]
Escribe .cms/ desde cms.config.ts y avisa si hay deriva
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --watch Regenera cada vez que cambia el config --check Convierte la deriva en un fallo y sale con código 1 -h, --help Muestra esta ayudaUna ejecución normal:
✔ Cargando config✔ Emitiendo .cms/3 colecciones desde /mi-sitio/cms.config.ts /mi-sitio/.cms/schema.ts /mi-sitio/.cms/types.d.tsCon globals declarados la línea los cuenta aparte —3 colecciones y 1 globals—, y aun así schema.ts sale igual: un global vive en KV y no genera tabla.
No pregunta nada, así que sin terminal se comporta exactamente igual que con ella.
--watch
Sección titulada «--watch»Se queda escuchando y regenera cada vez que guardas el config. Útil si trabajas sin astro dev; con él no
hace falta, porque la integración ya lo vigila.
No genera migraciones. Nunca.
--check
Sección titulada «--check»Para integración continua. Igual que sin flag, pero si hay deriva sale con código 1 en vez de limitarse a avisar:
El schema ha cambiado desde la última migración: + posts.views (integer)Ejecuta `cms db:migrate` para generar la migración.Compara contra los snapshot.json de migrations/, que están commiteados, así que funciona sobre un clon
limpio. Sin ninguna migración todavía no hay nada que comparar y pasa.
--config
Sección titulada «--config»pnpm cms db:generate --config ./config/cms.config.tsSin este flag busca en el directorio actual, en este orden: cms.config.ts, cms.config.js,
cms.config.mjs. Si no encuentra ninguno, el error te dice los tres nombres que buscó y dónde miró.
.cms/ se escribe junto al config, no en el directorio desde el que lanzas el comando, para que los
tipos queden donde su tsconfig.json los va a buscar.
Todos los comandos de esta página aceptan --config con este mismo significado, y por eso no se
repite en cada sección: lo que resuelve no es solo dónde está el config, sino cuál es la carpeta
del proyecto sobre la que van a trabajar.
db:migrate
Sección titulada «db:migrate»Usage: cms db:migrate [options]
Ejecuta db:generate y después drizzle-kit generate
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual -h, --help Muestra esta ayudaRegenera .cms/ y después llama a drizzle-kit, que escribe el SQL en migrations/. Si la migración va a
ser destructiva —recrear una tabla, borrar una columna— pide confirmación antes.
Ahí se para. Aplicarla es db:apply, y es un comando aparte a propósito.
drizzle-kit lo instalas tú, con la versión que el CMS declara como peer
(pnpm add -D drizzle-kit@1.0.0-rc.4). La CLI lo lanza como subproceso y te pasa su salida
y su código tal cual, así que lo que ves es drizzle-kit hablando, sin intermediarios. Si no está instalado,
el error te da el comando exacto en vez de un ENOENT.
Sin terminal, la confirmación de una migración destructiva se da por aceptada y el SQL se 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.
db:apply
Sección titulada «db:apply»Usage: cms db:apply [options]
Aplica las migraciones pendientes a D1, en local salvo --remote
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --db <binding> Binding de la base D1, en vez del primero de wrangler.jsonc --remote Aplica en producción en vez de en local -h, --help Muestra esta ayudapnpm cms db:apply # localpnpm cms db:apply --remote # producción, tras confirmarAplicando en local sobre el binding DB🚣 8 commands executed successfully.Aplica lo que ya haya en migrations/. No genera nada: si encuentra deriva sin migrar, te lo dice antes
de aplicar y sigue con lo que hay. Encadenar generar y aplicar en un solo comando es justo lo que no quieres
que ocurra sin querer.
Cómo encuentra la base
Sección titulada «Cómo encuentra la base»No hace falta que le digas cuál es. Lee tu wrangler.jsonc —o wrangler.json, o wrangler.toml— y usa el
binding de la primera D1 que encuentre, que es el mismo nombre con el que tu código habla con ella
(env.DB).
Con varias bases declaradas usa la primera y te avisa de cuál eligió. --db <binding> manda sobre todo eso:
pnpm cms db:apply --db ANALYTICSUsage: cms db:pop [options]
Borra la última migración generada
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --db <binding> Binding de la base D1, en vez del primero de wrangler.jsonc -h, --help Muestra esta ayudaDeshace la última migración generada: borra su directorio con el migration.sql y el snapshot.json.
Para el caso que pasa de verdad — generas, lees el SQL, no te convence, y lo quieres fuera antes de que lo
vea nadie más.
Borrada la migración 20260730051522_smooth_exilesLa línea base de la deriva vuelve a la migración anterior.Después de un pop, db:generate vuelve a avisarte de la deriva que esa migración cubría, porque la
comparación pasa a hacerse contra la migración anterior. El ciclo queda como si nunca la hubieras generado.
Sólo mira la base local. Comprobar remoto metería una llamada de red en cada pop, y quien haya aplicado en
producción lo que ahora quiere tirar tiene un problema más gordo que este aviso.
Sin ninguna migración que borrar, te lo dice y sale con 0.
Usage: cms deploy [options]
Prepara el repositorio, aplica las migraciones remotas y abre el dashboard
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --repo <owner/nombre> Nombre del repositorio a crear, en vez del name de wrangler.jsonc --public Crea el repositorio público en vez de privado --no-migrate No aplica las migraciones remotas antes de empujar --no-open No abre el dashboard en el navegador, solo imprime la URL --yes No pregunta: acepta las confirmaciones de este comando -h, --help Muestra esta ayudaDeja el proyecto listo para que lo despliegue Workers Builds, en este orden: el diagnóstico de
cms doctor como puerta, los ids de los bindings, el .npmrc, gh y git en el PATH con sesión
de GitHub iniciada, las migraciones remotas, el repositorio en GitHub y el primer push, y al final el
dashboard abierto con los cuatro clics que quedan escritos en la terminal.
Esas cuatro comprobaciones van antes de la primera migración remota, así que en una máquina sin
gh el comando para sin haber tocado nada.
El paso que este comando no puede hacer por ti es conectar el repositorio con Workers Builds: es una GitHub App con OAuth y no hay API ni CLI para ello (workers-sdk#12058). Así que lo escribe en vez de disimularlo.
--repo <owner/nombre>
Sección titulada «--repo <owner/nombre>»El nombre del repositorio a crear. Sin él se usa el name del wrangler.jsonc. Si el proyecto ya
tiene un origin, se empuja ahí y este flag se ignora avisando.
--public
Sección titulada «--public»El repositorio se crea privado salvo que pases esto.
--no-migrate
Sección titulada «--no-migrate»Salta cms db:apply --remote. El aviso sale dos veces —antes de empujar y en el resumen— porque el
build de Cloudflare no aplica migraciones: si las saltas aquí, las aplicas tú antes de que ese push
despliegue.
--no-open
Sección titulada «--no-open»No abre el navegador; la URL del dashboard se imprime igual.
Acepta las confirmaciones de este comando: el repositorio que engloba al proyecto, el git add -A
y la creación del repositorio en GitHub. No silencia la confirmación de PRODUCCIÓN de
db:apply --remote: esa la pone apply, y deploy no la puede tocar.
Al terminar imprime los cuatro clics, el repositorio, el Worker y si las migraciones remotas se
aplicaron o se saltaron. Sin terminal, todas sus confirmaciones se dan por aceptadas: un cms deploy
en un pipeline crea el repositorio y empuja sin preguntar.
Usage: cms doctor [options]
Diagnostica el cableado del proyecto y dice cómo arreglar cada fallo
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --fix Arregla lo trivial: las líneas que falten en .gitignore y el include del tsconfig.json -h, --help Muestra esta ayudaLee el proyecto de disco y dice qué está bien, qué está degradado y qué está roto, con el comando o la
edición exacta para salir de cada fallo. No toca la red ni lanza ningún proceso, y por eso
init, deploy y update lo usan como puerta antes de su propio trabajo: es la misma función,
no una copia.
✔ Node 24.18.0 (se pide >= 24).✔ drizzle-orm 1.0.0-rc.4 satisface 1.0.0-rc.4.✔ Binding SESSION declarado en kv_namespaces.⚠ El id de DB, SESSION, KV parece un marcador de posición, no un id real. → Ejecuta `cms resources:create`: wrangler escribe los ids él mismo en "/mi-sitio/wrangler.jsonc". Si ya existen, cópialos del panel de Cloudflare.✔ nodejs_compat en compatibility_flags.✔ assets.directory sirve ./dist/client.✔ El esquema y la última migración coinciden.31 comprobaciones: 28 bien, 2 avisos, 1 errores.Arregla los errores de arriba y vuelve a ejecutar `cms doctor`.Los tres niveles
Sección titulada «Los tres niveles»✔ok: eso está como tiene que estar.⚠warn: funciona, pero algo está degradado o no se ha podido comprobar. No cambia el código de salida.✖error: está roto o es inseguro. Un solo error deja el código de salida en 1, y es lo que para el preflight decms deploy.
Que SESSION falte y que tu config esté en TOML no son el mismo problema: el primero rompe en
silencio y pierde datos, el segundo solo limita lo que la CLI puede hacer por ti. Por eso hay tres
niveles y no dos.
Cada check tiene un id estable en kebab-case —node, peer-drizzle-orm, ids,
migrations-pattern, compat-flags, assets-directory, tsconfig-include, astro-config,
npmrc-token, npmrc-ignored, gitignore, dev-vars, drift…—. El de npmrc-token es el que
vigila que no haya un token de GitHub escrito literalmente en un .npmrc, que es el fichero que
Despliegue manda commitear.
Toca dos cosas y solo dos, y las dos son reversibles de un vistazo:
- Las líneas que le falten a tu
.gitignore(.cmsy.dev.vars). - La entrada
./.cms/types.d.tsen elincludedeltsconfig.json.
Sin nada que arreglar lo dice y no escribe nada. Lo que no puede tocar —un tsconfig.json que no
parsea, un fichero sin permisos— lo dice en amarillo y te deja la edición a mano.
No pregunta nada, así que sin terminal se comporta igual que con ella.
secret:set
Sección titulada «secret:set»Usage: cms secret:set [options] [nombre]
Genera el secreto de sesión y lo guarda en .dev.vars, o en el Worker con--remote
Arguments: nombre Nombre de la variable, BETTER_AUTH_SECRET por defecto
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --remote Lo sube al Worker de producción en vez de escribir .dev.vars --force Rota el secreto que ya existe, invalidando las sesiones abiertas --yes No pregunta antes de rotar o de subir a producción -h, --help Muestra esta ayudaGenera BETTER_AUTH_SECRET —la única variable de entorno que el CMS necesita— con randomBytes(32)
de node:crypto en base64. La misma fuerza que los 32 bytes que antes había que sacar de OpenSSL a
mano, sin depender de que haya ese binario en la máquina ni de que nadie copie bien 44 caracteres.
Sin --remote escribe el .dev.vars que hay junto al cms.config.ts, conservando byte a byte
todo lo demás —comentarios y claves ajenas incluidos—, y lo crea con modo 0600 si no existía:
Secreto BETTER_AUTH_SECRET escrito en /mi-sitio/.dev.varsEl valor no se imprime a propósito. `.dev.vars` no se commitea: compruébalo antes de subir nada.Si la clave ya está puesta no la pisa: sale nombrando --force. Una clave presente pero vacía
cuenta como ausente y se rellena sin más.
--force
Sección titulada «--force»Rota el secreto que ya existe. Rotar invalida todas las sesiones abiertas —hay que volver a entrar
en /admin—, que es exactamente lo que quieres si sospechas una filtración. Pide confirmación antes,
y solo cuando hay algo que invalidar.
--remote
Sección titulada «--remote»Sube el secreto al Worker de producción con wrangler secret put, y no toca el .dev.vars: local
y remoto son dos secretos distintos a propósito, porque una sesión abierta contra wrangler dev no
tiene por qué valer contra producción.
El valor viaja por la entrada estándar, nunca en el argv: en la línea de comandos quedaría en
la tabla de procesos y en el historial del shell para siempre.
Da por aceptada la confirmación, la de rotar y la de subir a producción.
Sin terminal las confirmaciones se dan por aceptadas: un secret:set --remote en un pipeline sube un
secreto nuevo y tira todas las sesiones sin preguntar.
resources:create
Sección titulada «resources:create»Usage: cms resources:create [options]
Crea la D1, el bucket de R2 y los dos KV que falten, y wrangler escribe los ids
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --name <prefijo> Nombre de la base y del bucket, en vez del "name" de wrangler.jsonc --yes No pregunta antes de crear -h, --help Muestra esta ayudaMira cuáles de los cuatro bindings que el CMS necesita —DB, R2, KV y SESSION— faltan, y crea
solo esos, en serie. Es idempotente: lo que ya existe no se crea dos veces.
Un wrangler.toml no se puede tocar: el comando para diciendo que pases el fichero a wrangler.jsonc
—el mismo contenido en JSON, con comentarios— en vez de reescribir un formato que no sabe editar.
Si un create choca con un recurso que ya existe —lo habitual en un segundo proyecto de la misma
cuenta, donde el título de un KV es único—, la salida de wrangler llega tal cual, debajo aparece el
trozo exacto a pegar, y sigue con los demás. Al terminar dice qué quedó sin id y sale con 1.
--name <prefijo>
Sección titulada «--name <prefijo>»Cómo se llamarán la base y el bucket. Sin él se usa el name del wrangler.jsonc; si el fichero ya
declara un database_name propio, ese se respeta. Los dos namespaces de KV conservan siempre su
título (KV y SESSION).
Da por aceptada la confirmación de crear los recursos.
Sin terminal esa confirmación se da por aceptada y los recursos se crean.
resources:list
Sección titulada «resources:list»Usage: cms resources:list [options]
Dice qué binding tiene id y cuál sigue siendo solo local
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --remote Añade la salida cruda de wrangler d1/kv/r2 list -h, --help Muestra esta ayudaDB localR2 kevin-cms-demo (declarado, sin comprobar)KV localSESSION local«local» significa que ese recurso todavía no existe en Cloudflare: el proyecto funciona con `wrangler dev` y `cms db:apply`, pero no se puede desplegar. Créalos con `cms resources:create`.«declarado, sin comprobar» es el bucket de R2: su identidad es su propio nombre, así que el fichero dice cómo se llama, pero no si existe en tu cuenta. Míralo con `cms resources:list --remote`, o ejecuta `cms resources:create`: lo crea si falta y no hace nada si ya está.local no es un fallo, es un estado: un proyecto cuyos bindings no llevan id corre
perfectamente bajo wrangler dev y cms db:apply —el modo local no necesita ids—, solo que todavía
no se puede desplegar. Un binding que ni siquiera aparece en el fichero sale como sin declarar.
La fila de R2 no dice lo mismo que las otras tres: lo que enseña no es un id que Cloudflare
haya emitido, sino el bucket_name que hay en el wrangler.jsonc —arriba, kevin-cms-demo—, y ese
nombre está ahí exista o no el bucket. Por eso sale con el (declarado, sin comprobar) a cuestas:
sin --remote este comando no toca la red, y sin red no hay forma de saberlo. Quien lo sabe es tu
cuenta:
cms resources:list --remote # la lista de buckets, debajo de la tablacms resources:create # lo crea si falta, y no hace nada si ya está--remote
Sección titulada «--remote»Añade debajo la salida cruda de wrangler d1 list, wrangler kv namespace list y
wrangler r2 bucket list, cada una precedida de su orden, para comparar a ojo. Nada de eso se
parsea.
Sin --remote este comando no toca la red: lee tu wrangler.jsonc y nada más. No pregunta nada,
así que sin terminal se comporta igual.
Usage: cms init [options] [dir]
Crea un proyecto Astro en Cloudflare con Kevin CMS ya cableado
Arguments: dir Directorio del proyecto, por defecto el actual
Options: --cloud Crea los recursos en Cloudflare (D1, R2 y los dos KV) --local No toca tu cuenta de Cloudflare; los recursos se crean después --name <nombre> Nombre del Worker y de los recursos, en vez del del directorio --pm <gestor> pnpm, npm, yarn o bun, en vez de deducirlo del lockfile --skip-create No invoca create-cloudflare aunque no haya proyecto Astro --no-install No instala dependencias --no-migrate No genera ni aplica migraciones --yes No pregunta nada (no responde por ti la pregunta del modo) -h, --help Muestra esta ayudaLos catorce pasos manuales de la instalación en un comando. Compone las
capas que ya existen —resources:create, secret:set, db:migrate y db:apply— y añade lo único
que no estaba: invocar create-cloudflare, invocar astro add, y escribir las plantillas.
Es el único comando que se sirve también desde otro paquete: pnpm create @kevolution-co/cms
—y npm, yarn y bun create— resuelve @kevolution-co/create-cms, cuyo binario create-cms es
este mismo init, con los mismos flags y construido desde la misma fuente. Existe porque
pnpm dlx @kevolution-co/cms init no llegaba a arrancar: dlx instala las peers de la librería
—astro, wrangler, drizzle-kit— y esas traen esbuild y workerd con build scripts que pnpm ≥ 10 se
niega a ejecutar sin aprobación, cosa que en un dlx nadie puede dar. create-cms no declara peers
y su árbol no tiene un solo build script. Los demás comandos no lo necesitan: se ejecutan desde el
proyecto, y ahí la aprobación de los build scripts sí tiene dónde declararse —el allowBuilds del
pnpm-workspace.yaml de la raíz, que create-cloudflare deja escrito—, cosa que en la caché de un
dlx no existe.
--cloud y --local
Sección titulada «--cloud y --local»La única diferencia entre los dos modos es el paso de crear recursos, y nada más: con --cloud se
crean la D1 y los dos namespaces de KV en tu cuenta; con --local no se toca tu cuenta de Cloudflare
y los subes después con cms resources:create. El bucket de R2 entra en los dos igual que los otros
tres: quien dice si existe es tu cuenta, no el fichero — ver el aviso de
resources:create.
--name <nombre>
Sección titulada «--name <nombre>»El nombre del Worker y de los recursos. Sin él se usa el del directorio, y tiene que valer para Cloudflare: minúsculas, dígitos y guiones, sin empezar ni acabar en guion y como mucho 63 caracteres.
--pm <gestor>
Sección titulada «--pm <gestor>»pnpm, npm, yarn o bun. Sin él se deduce del lockfile que haya, y pnpm cuando no hay ninguno.
--skip-create
Sección titulada «--skip-create»No invoca create-cloudflare aunque el directorio no sea un proyecto Astro. Es lo que se usa para
cablear un proyecto Astro que ya existe.
--no-install y --no-migrate
Sección titulada «--no-install y --no-migrate»Saltan la instalación de dependencias y el ciclo db:migrate → db:apply local. Lo saltado sale en
la lista del final.
No pregunta nada… con una excepción, que es la única de toda esta CLI: no responde por ti la pregunta del modo. Ver abajo.
Al terminar imprime lo escrito, lo saltado, los avisos de lo que quedó a medias, y cómo arrancar. Ningún aviso aborta lo que quedaba por hacer, pero no todos cuentan igual para el código de salida, y la diferencia dice de qué tipo es el problema:
- Un paso que el comando intentó y falló deja el código en 1: los recursos de Cloudflare, el secreto de sesión, las migraciones.
- Un paso que el comando decidió no tocar por no arriesgarse deja el código en 0: un
astro.config.mjscuya forma no reconoce, elincludede tutsconfig.json, unwrangler.toml, unwrangler.jsoncque no se puede leer como JSON, unassets.directoryque apunta a otro sitio. Ahí el aviso trae debajo el bloque exacto a pegar.
Así que un cms init con avisos amarillos puede salir con 0, y de hecho es lo normal sobre un
proyecto Astro preexistente. Si lo llamas desde un pipeline o desde un agente, la puerta es
cms doctor —que sí sale con 1 cuando algo está en rojo—, no el código de init.
Usage: cms update [options]
Actualiza el CMS, enseña lo que rompe y alinea las peers de la versión destino
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --to <version> La versión exacta a la que ir, en vez de la última del registro --dry-run Enseña el salto y el plan de peers sin tocar nada --no-regen No regenera .cms/ al terminar --yes No pregunta: instala y se queda con la versión -h, --help Muestra esta ayudaActualiza @kevolution-co/cms, enseña lo que rompe antes de que te quedes con la versión, y
alinea las peers que la versión destino declara. La página con el detalle es
Actualizar.
De dónde sale cada dato, que es lo que importa:
- La versión instalada es la del proyecto, no la del binario que corre: con
pnpm dlx @kevolution-co/cms updateson distintas. - La versión destino y sus peers salen del registro, que es lo único que sabe qué exige una
versión que todavía no tienes. Se pregunta con
npm view, porque npm viene con Node y lee el mismo.npmrcque autentica contra GitHub Packages. - Lo que rompe sale del
CHANGELOG.mddel paquete ya instalado: el repositorio es privado y un token con soloread:packagesno puede leerlo de ninguna otra forma.
@kevolution-co/cms 0.7.0 → 0.8.0 drizzle-orm 1.0.0-rc.4 → 1.0.0-rc.5 drizzle-kit 1.0.0-rc.4 → 1.0.0-rc.5 (-D)Las dos confirmaciones
Sección titulada «Las dos confirmaciones»Son dos a propósito, y la segunda llega después de enseñar el CHANGELOG: se instala, se lee lo
que rompe, y solo entonces se pregunta si te la quedas. Decir que no restaura el package.json
byte a byte —el rango que tenías escrito, ^0.7.0 y no 0.7.0, el orden de las claves y la
indentación— y reinstala. El lockfile no se restaura.
--to <version>
Sección titulada «--to <version>»Una versión exacta, no un rango ni una etiqueta. Es también la forma de bajar de versión: sin él
el comando no baja nunca por su cuenta, porque la latest del registro puede ser más vieja que una
precandidata instalada.
--dry-run
Sección titulada «--dry-run»Enseña el salto y el plan de peers y no escribe nada: lo único que corre es el npm view, que es
de lectura. Es el modo para un pipeline.
--no-regen
Sección titulada «--no-regen»No regenera .cms/ al terminar. Sin el flag, se regenera lanzando el binario recién instalado,
nunca en este proceso: Node no recarga un módulo ESM porque sus bytes hayan cambiado en disco, y el
codegen viejo emitiría un .cms/ que no corresponde a la versión del manifiesto.
Acepta las dos confirmaciones: instala y se queda con la versión.
Las migraciones no las ejecuta este comando. Si el CHANGELOG habla del esquema, lo avisa y te
manda al ciclo de siempre: cms db:migrate, leer el SQL, cms db:apply.
settings:reset-site-url
Sección titulada «settings:reset-site-url»Usage: cms settings:reset-site-url [options]
Quita el siteUrl guardado en KV para recuperar el acceso al panel
Options: --config <ruta> Ruta al cms.config.ts, en vez de buscarlo en el directorio actual --kv <binding> Binding del namespace de KV, en vez del llamado "KV" de wrangler.jsonc --remote Opera sobre el KV de producción en vez del local -h, --help Muestra esta ayudaBorra el siteUrl guardado en KV —el ajuste del sitio del que salen los
enlaces de los correos y contra el que better-auth valida—, para recuperar el acceso al panel cuando
el valor guardado apunta a una URL a la que no llegas. Sin siteUrl, el CMS vuelve a deducirlo del
origen de cada petición.
Limpia los dos sitios donde puede estar: su clave propia, settings:site:siteUrl, y la entrada
siteUrl dentro del blob antiguo settings:site —del que solo se quita esa entrada; el resto se
escribe de vuelta tal cual—.
Quitando siteUrl en local sobre el binding KVsiteUrl quitado: vuelve a deducirse del origen de cada petición.Ojo: cada isolate que ya esté sirviendo —incluido un wrangler dev en marcha— conserva el siteUrl viejo en su caché hasta 60 s. El panel vuelve a responder en torno a un minuto, no al instante.Sin ningún siteUrl guardado lo dice, no escribe nada y sale con 0.
--kv <binding>
Sección titulada «--kv <binding>»El namespace sobre el que operar. Sin él se usa el que tu wrangler.jsonc llama KV.
--remote
Sección titulada «--remote»Opera sobre el KV de producción. Como db:apply --remote, exige el flag más la confirmación:
dos cosas a propósito antes de escribir en un KV vivo. Sin terminal esa confirmación se da por
aceptada.
Códigos de salida
Sección titulada «Códigos de salida»| Situación | Salida | Código |
|---|---|---|
| Sin argumentos | Ayuda | 0 |
-h, <comando> -h |
Ayuda | 0 |
| Comando desconocido | El comando que no existe, y la ayuda | 1 |
db:generate correcto, con o sin deriva |
Resumen de lo escrito | 0 |
db:generate --check con deriva |
El listado de la deriva | 1 |
| Config no encontrado, o config inválido | El error, con el motivo | 1 |
db:migrate con drizzle-kit fallando |
Lo que imprima drizzle-kit | El suyo |
db:apply con wrangler fallando |
Lo que imprima wrangler | El suyo |
db:apply --remote cancelado en el prompt |
Aviso de cancelación | 0 |
db:pop correcto, o sin nada que borrar |
Qué borró, o que no había nada | 0 |
Binding no resoluble y sin --db |
El error, nombrando los ficheros que buscó | 1 |
doctor con algún check en error |
El diagnóstico entero, y el recuento | 1 |
doctor sin errores, con o sin avisos |
El diagnóstico entero, y el recuento | 0 |
init con un error de validación |
El error, y ningún fichero escrito | 1 |
init con create-cloudflare o la instalación fallando |
Lo que imprima el proceso | El suyo |
init con un paso que intentó y falló: recursos, secreto, migraciones |
El aviso, sin abortar lo que quedaba | 1 |
init con un paso que decidió no tocar: astro.config, tsconfig, un wrangler que no sabe editar |
El aviso, con el bloque exacto a pegar | 0 |
deploy sin .npmrc, o con el token escrito dentro |
El error, antes de lanzar ni un proceso | 1 |
deploy con el .npmrc ignorado por git |
El error, después del git init y de las migraciones remotas |
1 |
deploy con las migraciones remotas fallando |
El error, sin haber creado ni empujado nada | El de wrangler |
secret:set --remote con wrangler fallando |
Lo que imprima wrangler, y qué comprobar | El suyo |
resources:create dejando algún recurso sin id |
El estado final, y qué pegar | 1 |
update --dry-run |
El salto y el plan de peers | 0 |
update cancelado en cualquiera de las dos confirmaciones |
Qué se restauró | 0 |
update con db:generate fallando después de instalar |
El aviso: la versión quedó instalada | 1 |
| Una confirmación rechazada, en cualquier comando | Aviso de cancelación | 0 |
Pedir ayuda no es un error: sin argumentos sale con 0. Equivocarse de comando sí. Cancelar un prompt tampoco: dijiste que no y se te hizo caso.
En integración continua
Sección titulada «En integración continua»Eso vale, tal cual, para la confirmación de una migración destructiva en db:migrate, para la de
PRODUCCIÓN de db:apply --remote, para la de db:pop sobre una migración ya aplicada, para la de
secret:set --remote y para las dos de update — y de esas dos conviene decirlo explícito: un
cms update en un pipeline instala y se queda con la versión, porque nadie está ahí para leer el
CHANGELOG y decir que no. El modo de CI de ese comando es --dry-run, que no escribe nada.
La excepción: cms init
Sección titulada «La excepción: cms init»cms init es la única excepción deliberada. Sin TTY —y también con --yes— exige --cloud o
--local, y sin ninguno de los dos sale con 1 sin haber escrito ni un fichero:
no puedo preguntarte si crear los recursos en Cloudflare, así que no lo adivino. Vuelve a ejecutarlo con `--cloud` … o con `--local` … No se ha escrito ningún fichero.El porqué: crear recursos de pago en una cuenta ajena por omisión no es lo mismo que aplicar una migración que el usuario ya generó. Una confirmación asumida es «sigue con lo que te pedí»; aquí no hay nada pedido que seguir, y la única respuesta por omisión posible costaría dinero.
Lo mínimo que merece la pena en un pipeline:
- run: pnpm cms db:generate --checkFalla la build si alguien cambió cms.config.ts y se olvidó de generar la migración, que es el despiste que
más caro sale después.