convert-site
El orquestador. Hace una ronda de preguntas, luego ejecuta todas las demás skills en orden sin detenerse de nuevo, y termina con un pull request que la persona fusiona y un runbook desde el que lanzan.
Las reglas de oro
- Un único mensaje de entrada, luego sin paradas. Cada pregunta tiene un valor por defecto. Todo lo que luego necesite una cuenta, un inicio de sesión o un token que no tengas va a la lista "te necesita" (
state.needsYouydocs/LAUNCH.mdsección A) y la ejecución continúa. - El sitio en vivo es de solo lectura. Solo estos lo leen, con ritmo: los scripts de captura,
shoot.mjsystyles.mjsen vivo,css-coverage.mjs,launch-audit --old-urlypre-launch --predecessor-url. Las analíticas están bloqueadas en sus cargas de páginas en vivo, por lo que no se cuenta ninguna visita. Nunca envíes un formulario en él, inicies sesión ni obtengas una página manualmente para llenar un vacío. - La compilación por defecto es igual al sitio en vivo, fallos incluidos. El contenido se toma del marcado capturado, nunca se vuelve a escribir ni se ordena. Cada rareza es una fila de decisión que dice "reproducir el sitio en vivo por defecto". Una diferencia forzada es una excepción; una mejora es una propuesta (
PROPOSALS=onsolamente). - Compuertas en cada commit, nunca suavizadas. Nunca edites
baseline/para pasar (solo las banderaskeepenbaseline/scripts.json). Un salto no es un pase; "No cubierto" nunca es un pase. mainrecibe el commit del andamiaje y nada más. En un repositorio nuevo y vacío,init-sitehace un commit enmain, la excepción a "nunca hacer commit en main": el PR necesita una base. Todo lo demás está enastro-rebuild, un único PR. Nunca hagas force-push, nunca fusiones, nunca toques DNS, el host antiguo ni una configuración de panel.- Sin secretos en el chat ni en el repositorio. Nunca le pidas a la persona que pegue un token. Las credenciales vienen del entorno o del propio inicio de sesión de una CLI.
Nombres utilizados a continuación
KIT es la ruta absoluta de este kit (la carpeta que contiene skills/ y package.json).
LIVE es el origen en vivo. SITE es la ruta absoluta del repositorio del nuevo sitio (por defecto <carpeta actual>/<slug>); la captura y el estado de la ejecución se escriben en él desde el principio, y init-site.mjs los rodea. Ejecuta cada comando desde SITE. Cada script imprime --help; ejecútalo en lugar de leer el código fuente. Cada comando de Node en un shell nuevo comienza con source ~/.nvm/nvm.sh && nvm use 22.23.4 (o se ejecuta en un shell que lee .nvmrc).
Paso 0a: un kit que pueda ejecutarse
Los scripts importan parse5, playwright y el resto desde node_modules del kit. Si falta $KIT/package.json o $KIT/node_modules (una instalación que copió solo las carpetas de skill no tiene ninguno), clona el kit e instálalo, luego usa el clon como KIT:
git clone https://github.com/ethanplusai/astro-conversion-kit <carpeta>/astro-conversion-kit
npm install --prefix <carpeta>/astro-conversion-kit
Paso 0: verificación previa y huella digital (antes del mensaje de entrada)
node $KIT/skills/convert-site/scripts/preflight.mjs --json
node $KIT/skills/capture-site/scripts/fingerprint.mjs $LIVE
Instala lo que falte que puedas instalar tú mismo, sin preguntar: npx playwright install chromium cuando playwright.chromium sea falso; vercel y wrangler se ejecutan a través de npx. Una CLI que esté presente pero no haya iniciado sesión es responsabilidad de la persona: nombra el comando (gh auth login, npx vercel login, npx wrangler login) en el mensaje de entrada y vuelve a comprobarlo en el andamiaje.
experience determina cómo hablas, no lo que haces. new: una frase simple por fase sobre lo que hace y por qué, cada término explicado una vez, las instalaciones se hacen en silencio. some: una línea por fase. experienced: solo comandos y resultados. Una huella digital de Shopify es una tienda: detente y dilo.
Paso 1: entrada (el único mensaje)
Envía la plantilla de references/intake.md, completada con lo que encontraron la verificación previa y la huella digital: cada pregunta con su valor por defecto, y la lista "qué falta y qué pasa". Si la persona no responde, los valores por defecto se mantienen. Nunca envíes un segundo mensaje de pregunta.
Las fases
El orden es el de docs/process.md; references/phases.md tiene cada comando y cada prueba. En cada límite, ejecuta node $KIT/skills/convert-site/scripts/state.mjs --dir $SITE phase <nombre>; no comiences una fase hasta que se cumpla la prueba de la anterior. Ejecuta las llamadas a state.mjs una a la vez, nunca encadenadas con &&: cada una reescribe state.json, y una cadena que falle a medio camino lo deja desincronizado.
| # | Fase (<nombre>) | Qué pasa | Terminada cuando |
|---|---|---|---|
| 1 | intake | Verificación previa, huella digital, el único mensaje | Respondida, o los valores por defecto se mantienen |
| 2 | capture | capture-site en $SITE/capture/, cobertura CSS | Cada URL guardada o registrada con su estado; Notas escritas |
| 3 | plan | Decidir alojamiento, formato de URL, modo de medios, plantillas; decisiones en el estado; borradores bajo .conversion/ | Cada plantilla, recuento, rareza y característica fuera del alcance tiene una decisión |
| 4 | scaffold | Repo, init-site.mjs alrededor de la captura, luego docs/plan.md y docs/media-plan.json | Se compila vacío; main tiene el único commit del andamiaje |
| 5 | baseline | npm run baseline (templates.json ya existe) | build-baseline.mjs --check sale con 0 |
| 6 | build | Diseños y partes compartidas, una página por plantilla, bloqueo de diseño en las plantillas, luego cada página | npm run build pasa; las compuertas de plantilla pasan ruta por ruta |
| 7 | gates | Las compuertas completas | npm run verify sale con 0 |
| 8 | visual | Cada plantilla a 390, 768, 1440; cada página a 390 y 1440 | Cada par pasa |
| 9 | components | Opcional, desactivado por defecto (references/components-optional.md) | Las compuertas y las diferencias aún pasan, un commit separado |
| 10 | prelaunch | pre-launch, despliegue de staging, verify-live, launch-audit, un envío de prueba | prelaunch-reconcile.mjs sale con 0 (references/phases.md §10); bloqueos de auditoría corregidos o listados |
| 11 | suggestions | suggest-improvements con gates.json y review/ | docs/suggestions.md con su sección "De la revisión" |
| 12 | pr | Runbook, push, PR, informe final | El PR cita la salida de las compuertas y cada sección "No cubierto" |
| 13 | launch | Lo hace la persona, desde docs/LAUNCH.md | post-launch verifica el cambio y observa 30 días |
Las skills que utiliza cada fase, con sus propias reglas: capture-site (2), parity-gates (5 a 7), visual-review (6, 8), pre-launch y launch-audit (10), suggest-improvements (11), post-launch (en el runbook). Lee el SKILL.md de cada skill antes de su fase.
La compilación, en un párrafo
references/build-rules.md es vinculante. Los diseños y el encabezado, navegación y pie de página compartidos son siempre componentes; los bloques de contenido son el marcado capturado, movido por un script. Los medios en sus rutas originales, las fuentes autoalojadas, el CSS mediante poda de cobertura (css-coverage.mjs luego css-prune.mjs), nunca una reescritura. Los formularios según references/forms.md, los scripts de terceros según references/third-party.md. redirects.csv es la única fuente de redirecciones: una nueva redirección es una fila cuyo source es decision y cuyo note nombra el id de la decisión, luego npm run redirects:build; nunca edites manualmente las reglas generadas. Un commit por plantilla (feat: <plantilla> template, una vez que sus compuertas de ámbito de ruta pasen), nunca uno para toda la compilación. El diseño se bloquea en las plantillas (visual-review) antes del despliegue a todas las páginas. Con subagentes, un implementador por plantilla o corrección de compuerta, nunca dos en un mismo archivo; cada resumen lleva rutas absolutas y build-rules.md, y tú revisas sus commits antes de la siguiente fase.
Decisiones, excepciones, propuestas
Esta sección es la regla; las referencias enlazan aquí.
- Decisión. Cualquier cosa que el sitio en vivo haga de manera extraña, y cada valor por defecto que apliques, recibe
state.mjs decision '{"topic":…,"choice":…,"default":…,"reason":…,"costIfWrong":…}', que imprime su id (d1,d2, …). El único registro es la tabla de Decisiones endocs/plan.md: id, fecha, tema, elección, valor por defecto, razón, costo si es incorrecto. Antes del andamiaje, las decisiones viven en.conversion/state.json; la tabla del plan se escribe a partir de ellas justo después deinit-site. El valor por defecto es siempre "reproducir el sitio en vivo". - Excepción (
exceptions.json,{ path, field, from, to, reason, approvedBy, date }): una diferencia que la compilación estática no puede evitar; las compuertas sustituyentoporfrompara ese campo en esa ruta.approvedByes"default, <id-de-decisión>"hasta que una persona lo apruebe en el PR. Los formularios y scripts no son campos de excepción (tienen sus propias banderas).routeses: una ruta que la captura no pudo leer:fromes su estado como cadena,toes"skip"o la ruta de reemplazo compilada. - Propuesta (
proposals.json, la misma forma másid, el id de la decisión, yapprovedBy: "proposed"; varios registros pueden compartir un mismo id): una mejora. El código la cambia conproposalOn(id); se envía solo en una compilaciónPROPOSALS=on, controlada pornpm run verify:proposals. Un cambio que ninguna compuerta mide (hrefs reescritos) esfield: "markup", nunca comparado. Cuando una persona lo aprueba, los registros se mueven aexceptions.json(approvedBy).
Alojamiento
Vercel por defecto, Cloudflare Pages a solicitud: references/hosting-vercel.md y references/hosting-cloudflare.md. Cada página lleva noindex a menos que la compilación de producción establezca PUBLIC_INDEXABLE=true. Los medios son repo, store (media-upload.mjs) o live-temporary (solo staging; desaparece antes de que DNS se mueva), según lo que decida media-plan.mjs (references/phases.md §3).
El único mensaje después del plan
Después de la fase 3, envía un estado breve (no una pregunta): plataforma, recuentos de páginas y plantillas, la decisión de medios, características fuera del alcance y las opciones, las decisiones tomadas por defecto y la lista de necesidades hasta el momento. Es obligatorio también en una ejecución no interactiva (respuestas fijas, nadie responde): las líneas de progreso no lo reemplazan. Luego continúa sin esperar.
El pull request (fase 12)
Haz push de astro-rebuild (main se subió en el andamiaje), luego gh pr create --base main --head astro-rebuild --title "Reconstrucción Astro de <host>" --body-file .conversion/pr-body.md. Mientras que pre-launch falle con placeholders.form-id (sin id de formulario aún), añade --draft, y el informe final nombra eso como el bloqueador. Sin un inicio de sesión de gh, el cuerpo se queda en ese archivo y "hacer push y abrir el PR" va a la lista de necesidades. El cuerpo, en este orden:
## Qué cambió un párrafo: plataforma, qué se convirtió, host, modo de medios
## Recuentos páginas, plantillas, redirecciones, archivos multimedia y tamaño, formularios, proveedores mantenidos/eliminados
## Excepciones aplicadas cada entrada de exceptions.json: ruta, campo, razón, id de decisión
## Propuestas abiertas cada id de proposals.json: rutas, qué, por qué (se envía solo con PROPOSALS=on)
## Decisiones la tabla de Decisiones de docs/plan.md, y cada elección no predeterminada
## Salida de compuertas salida de `npm run verify`, textual, en un bloque de código, con cada línea de salto;
luego cada fila que prelaunch-reconcile aceptó, como "reproducido desde el sitio en vivo (dN)"
## Revisión visual salida de `npm run review:check`, cada entrada de docs/visual-overrides.json
(ruta, id, umbral, razón), cada bannerClosed y heightMismatch; las hojas de contacto están en
review/index.html y review/all.html (local; npm run review:sheet)
## Staging la URL de staging, resultado de verify-live, los bloqueadores de launch-audit y su estado
## Sugerencias recuentos por categoría, los elementos de riesgo medio y alto, los ids aplicables
## No cubierto las secciones "No cubierto" de pre-launch y launch-audit, textuales, cada una
bajo su propio encabezado; luego las de capture-site, visual-review y suggestions
## Esperando por ti cada elemento de state.needsYou, en el orden del runbook
El informe final (para la persona)
Comienza con el enlace del PR (y "borrador: esperando el id del formulario" cuando sea uno), luego: qué se convirtió (recuentos), compuertas y revisión visual en una línea cada una, la URL de staging, la lista de necesidades bajo Esperando por ti leída de state.mjs --dir $SITE get needsYou (cada elemento con el comando o clic exacto, en el orden del runbook), luego cada sección "No cubierto" textual. Di "PR abierto, esperando tu fusión", nunca "terminado" o "en vivo". Detén cualquier servidor de revisión que hayas iniciado (npm run review:serve -- --stop, y npx astro preview stop si usaste la vista previa), luego detente.
Reanudar
En una nueva sesión, lee node $KIT/skills/convert-site/scripts/state.mjs --dir $SITE get y continúa desde phase: vuelve a ejecutar la prueba de esa fase primero; si se cumple, comienza la siguiente fase. La captura se reanuda con --resume. Nunca repitas la entrada. Aplicar una sugerencia más tarde es convert-site --apply <id> (references/apply-suggestion.md), nunca parte de la ejecución en sí.
Referencias
| Archivo | Cubre |
|---|---|
references/intake.md | El único mensaje: preguntas, valores por defecto, qué falta y qué pasa |
references/phases.md | Cada fase: comandos exactos, la prueba de que está terminada, qué registrar |
references/build-rules.md | Cómo se construyen diseños, contenido, CSS, medios, fuentes, imágenes perezosas y redirecciones |
references/forms.md | Cableado de Formspree, nombres de campo, honeypot, agradecimiento, el id del formulario, el único envío de prueba |
references/third-party.md | La lista de permitidos keep en baseline/scripts.json y docs/third-party.md |
references/hosting-vercel.md | Proyecto, staging público sin indexar, indexación, medios Blob, protección opt-in |
references/hosting-cloudflare.md | Proyecto Pages, _redirects, _headers, función de medios R2, redirecciones de consulta |
references/runbook.md | docs/LAUNCH.md: A te necesita, B cierre, C día de lanzamiento, D vigilancia de 30 días |
references/components-optional.md | El pase de componentes opcionales |
references/apply-suggestion.md | --apply <id>: registros de propuestas, commit de rama, compuertas, hoja |