convert-site
O orquestrador. Ele faz uma única mensagem de perguntas, então executa todas as outras skills em ordem sem parar novamente, e termina com um pull request que a pessoa mescla e um runbook que ela usa para lançar.
As regras de ouro
- Uma única mensagem de perguntas, depois sem paradas. Toda pergunta tem um valor padrão. Qualquer coisa que depois precise de uma conta, um login ou um token que você não tenha vai para a lista "precisa de você" (
state.needsYouedocs/LAUNCH.mdseção A) e a execução continua. - O site ativo é somente leitura. Apenas estes o leem, de forma ritmada: os scripts de captura,
shoot.mjsestyles.mjsno ativo,css-coverage.mjs,launch-audit --old-urlepre-launch --predecessor-url. As análises são bloqueadas nos carregamentos das páginas ativas, então nenhuma visita é contada. Nunca envie um formulário nele, faça login ou busque uma página manualmente para preencher uma lacuna. - O build padrão é igual ao ativo, falhas incluídas. O conteúdo é movido da marcação capturada, nunca redigitado ou arrumado. Qualquer peculiaridade é uma linha de decisão que diz "reproduzir o ativo por padrão". Uma diferença forçada é uma exceção; uma melhoria é uma proposta (
PROPOSTAS=onapenas). - Gates em todo commit, nunca flexibilizados. Nunca edite
baseline/para passar (apenas os flagskeepembaseline/scripts.json). Um pulo não é um passe; "Não coberto" nunca é um passe. mainrecebe o commit do scaffold e nada mais. Em um repositório novo e vazio, o init-site faz um commit emmain, a exceção a "nunca commitar em main": o PR precisa de uma base. Todo o resto é emastro-rebuild, um PR. Nunca force push, nunca mescle, nunca mexa no DNS, no host antigo ou em configurações de painel.- Sem segredos no chat ou no repositório. Nunca peça para a pessoa colar um token. As credenciais vêm do ambiente ou de um login próprio da CLI.
Nomes usados abaixo
KIT é o caminho absoluto deste kit (a pasta que contém skills/ e package.json). LIVE é a origem ativa. SITE é o caminho absoluto do novo repositório do site (padrão <pasta_atual>/<slug>); a captura e o estado da execução são gravados nele desde o início, e init-site.mjs cria o scaffold ao redor deles. Execute todo comando a partir de SITE. Todo script imprime --help; execute isso em vez de ler o código fonte. Todo comando Node em um shell novo começa com source ~/.nvm/nvm.sh && nvm use 22.23.4 (ou é executado em um shell que lê .nvmrc).
Passo 0a: um kit que pode executar
Os scripts importam parse5, playwright e o resto dos node_modules do kit. Se $KIT/package.json ou $KIT/node_modules estiver faltando (uma instalação que copiou apenas as pastas de skill não tem nenhum dos dois), clone o kit e instale-o, então use o clone como KIT:
git clone https://github.com/ethanplusai/astro-conversion-kit <pasta>/astro-conversion-kit
npm install --prefix <pasta>/astro-conversion-kit
Passo 0: pré-verificação e fingerprint (antes da mensagem de perguntas)
node $KIT/skills/convert-site/scripts/preflight.mjs --json
node $KIT/skills/capture-site/scripts/fingerprint.mjs $LIVE
Instale o que estiver faltando e que você pode instalar sozinho, sem perguntar: npx playwright install chromium quando playwright.chromium for falso; vercel e wrangler executam via npx. Uma CLI que está presente mas não está logada é responsabilidade da pessoa fazer login: nomeie o comando (gh auth login, npx vercel login, npx wrangler login) na mensagem de perguntas e verifique novamente no scaffold.
experience define como você fala, não o que você faz. new: uma frase simples por fase sobre o que faz e por quê, cada termo explicado uma vez, instalações feitas silenciosamente. some: uma linha por fase. experienced: apenas comandos e resultados. Um fingerprint de Shopify é uma loja: pare e avise.
Passo 1: perguntas (a única mensagem)
Envie o template de references/intake.md, preenchido com o que a pré-verificação e o fingerprint encontraram: cada pergunta com seu padrão, e a lista "o que está faltando e o que acontece". Se a pessoa não responder, os padrões prevalecem. Nunca envie uma segunda mensagem de perguntas.
As fases
A ordem é a de docs/process.md; references/phases.md tem todo comando e cada prova. Em cada limite execute node $KIT/skills/convert-site/scripts/state.mjs --dir $SITE phase <nome>; não inicie uma fase até que a prova da fase anterior seja válida. Execute chamadas state.mjs uma de cada vez, nunca encadeadas com &&: cada uma reescreve state.json, e uma cadeia que falha no meio deixa-o fora de sincronia.
| # | Fase (<nome>) | O que acontece | Feito quando |
|---|---|---|---|
| 1 | intake | Pré-verificação, fingerprint, a única mensagem | Respondida, ou padrões prevalecem |
| 2 | capture | capture-site em $SITE/capture/, cobertura CSS | Toda URL salva ou registrada com seu status; Notas escritas |
| 3 | plan | Decidir hospedagem, formato de URL, modo de mídia, templates; decisões no estado; rascunhos em .conversion/ | Todo template, contagem, peculiaridade e recurso fora do escopo tem uma decisão |
| 4 | scaffold | Repo, init-site.mjs ao redor da captura, depois docs/plan.md e docs/media-plan.json | Ele compila vazio; main contém o único commit do scaffold |
| 5 | baseline | npm run baseline (templates.json já existe) | build-baseline.mjs --check sai com 0 |
| 6 | build | Layouts e partes compartilhadas, uma página por template, trava de design nos templates, depois toda página | npm run build passa; gates de template passam caminho por caminho |
| 7 | gates | Os gates completos | npm run verify sai com 0 |
| 8 | visual | Cada template em 390, 768, 1440; cada página em 390 e 1440 | Cada par passa |
| 9 | components | Opcional, desligado por padrão (references/components-optional.md) | Gates e diffs ainda passam, um commit separado |
| 10 | prelaunch | pre-launch, deploy de staging, verify-live, launch-audit, um envio de teste | prelaunch-reconcile.mjs sai com 0 (references/phases.md §10); bloqueadores de auditoria corrigidos ou listados |
| 11 | suggestions | suggest-improvements com gates.json e review/ | docs/suggestions.md com sua seção "Da revisão" |
| 12 | pr | Runbook, push, PR, relatório final | O PR cita a saída do gate e toda seção "Não coberto" |
| 13 | launch | Da pessoa, a partir de docs/LAUNCH.md | post-launch verifica a migração e monitora por 30 dias |
As skills que cada fase usa, com suas próprias regras: capture-site (2), parity-gates (5 a 7), visual-review (6, 8), pre-launch e launch-audit (10), suggest-improvements (11), post-launch (no runbook). Leia o SKILL.md de cada skill antes de sua fase.
O build, em um parágrafo
references/build-rules.md é vinculativo. Layouts e o cabeçalho, navegação e rodapé compartilhados são sempre componentes; blocos de conteúdo são a marcação capturada, movida por um script. Mídia em seus caminhos originais, fontes auto-hospedadas, CSS por poda de cobertura (css-coverage.mjs depois css-prune.mjs), nunca uma reescrita. Formulários conforme references/forms.md, scripts de terceiros conforme references/third-party.md. redirects.csv é a única fonte de redirecionamento: um novo redirecionamento é uma linha cujo source é decision e cujo note nomeia o id da decisão, então npm run redirects:build; nunca edite manualmente as regras geradas. Um commit por template (feat: template do <template>, assim que seus gates de escopo de caminho passarem), nunca um para o build inteiro. O design é travado nos templates (visual-review) antes da distribuição para todas as páginas. Com subagentes, um implementador por template ou correção de gate, nunca dois em um mesmo arquivo; cada briefing carrega caminhos absolutos e build-rules.md, e você revisa seus commits antes da próxima fase.
Decisões, exceções, propostas
Esta seção é a regra; as referências linkam para cá.
- Decisão. Qualquer coisa que o site ativo faça de forma estranha, e todo padrão que você aplicar, recebe
state.mjs decision '{"topic":…,"choice":…,"default":…,"reason":…,"costIfWrong":…}', que imprime seu id (d1,d2, …). O único registro é a tabela de Decisões emdocs/plan.md: id, data, tópico, escolha, padrão, motivo, custo se errado. Antes do scaffold as decisões vivem em.conversion/state.json; a tabela do plano é escrita a partir delas logo após oinit-site. O padrão é sempre "reproduzir o ativo". - Exceção (
exceptions.json,{ path, field, from, to, reason, approvedBy, date }): uma diferença que o build estático não pode evitar; os gates substituemtoporfrompara aquele campo naquele caminho.approvedByé"default, <decision id>"até que uma pessoa o aprove no PR. Formulários e scripts não são campos de exceção (eles têm seus próprios flags).routesé: uma rota que a captura não pôde ler:fromé seu status como string,toé"skip"ou o caminho substituto construído. - Proposta (
proposals.json, mesma forma maisid, o id da decisão, eapprovedBy: "proposed"; vários registros podem compartilhar um id): uma melhoria. O código a ativa comproposalOn(id); ela é enviada apenas em um buildPROPOSTAS=on, validado pornpm run verify:proposals. Uma mudança que nenhum gate mede (hrefs reescritos) éfield: "markup", nunca comparada. Quando uma pessoa a aprova, os registros vão paraexceptions.json(approvedBy).
Hospedagem
Vercel por padrão, Cloudflare Pages sob solicitação: references/hosting-vercel.md e references/hosting-cloudflare.md. Toda página carrega noindex a menos que o build de produção defina PUBLIC_INDEXABLE=true. Mídia é repo, store (media-upload.mjs) ou live-temporary (apenas staging; removida antes do DNS ser movido), conforme media-plan.mjs decide (references/phases.md §3).
A única mensagem após o plano
Após a fase 3, envie um status curto (não uma pergunta): plataforma, contagens de páginas e templates, a decisão de mídia, recursos fora do escopo e as opções, as decisões tomadas por padrão e a lista precisa-de-você até agora. É obrigatório também em uma execução não interativa (respostas permanentes, ninguém respondendo): linhas de progresso não o substituem. Depois continue sem esperar.
O pull request (fase 12)
Faça push de astro-rebuild (main foi enviado no scaffold), então gh pr create --base main --head astro-rebuild --title "Recriação Astro de <host>" --body-file .conversion/pr-body.md. Enquanto pre-launch falhar em placeholders.form-id (sem id de formulário ainda), adicione --draft, e o relatório final nomeará isso como o bloqueador. Sem um login gh, o corpo fica nesse arquivo e "fazer push e abrir o PR" vai para a lista precisa-de-você. O corpo, nesta ordem:
## O que mudou um parágrafo: plataforma, o que foi convertido, host, modo de mídia
## Contagens páginas, templates, redirecionamentos, arquivos de mídia e tamanho, formulários, fornecedores mantidos/removidos
## Exceções aplicadas toda entrada de exceptions.json: path, field, reason, decision id
## Propostas abertas todo id de proposals.json: caminhos, o quê, porquê (enviado apenas com PROPOSTAS=on)
## Decisões a tabela de Decisões de docs/plan.md, e toda escolha não padrão
## Saída do gate saída de `npm run verify`, literal, em um bloco de código, com toda linha de pulo;
então toda linha que prelaunch-reconcile aceitou, como "reproduzido do ativo (dN)"
## Revisão visual saída de `npm run review:check`, toda entrada de docs/visual-overrides.json
(route, id, threshold, reason), todo bannerClosed e heightMismatch; as folhas de contato são
review/index.html e review/all.html (local; npm run review:sheet)
## Staging a URL de staging, resultado do verify-live, os bloqueadores do launch-audit e seu estado
## Sugestões contagens por categoria, os itens de risco médio e alto, os ids aplicáveis
## Não coberto as seções "Não coberto" do pre-launch e launch-audit, literais, cada
uma sob seu próprio título; depois as do capture-site, visual-review e suggestions
## Aguardando você todo item de state.needsYou, na ordem do runbook
O relatório final (para a pessoa)
Comece com o link do PR (e "draft: aguardando o id do formulário" quando for o caso), então: o que foi convertido (contagens), gates e revisão visual em uma linha cada, a URL de staging, a lista precisa-de-você em Aguardando você lida de state.mjs --dir $SITE get needsYou (cada item com o comando ou clique exato, na ordem do runbook), então toda seção "Não coberto" literal. Diga "PR aberto, aguardando sua mesclagem", nunca "pronto" ou "ao vivo". Pare qualquer servidor de revisão que você iniciou (npm run review:serve -- --stop, e npx astro preview stop se usou o preview), então pare.
Retomando
Em uma nova sessão, leia node $KIT/skills/convert-site/scripts/state.mjs --dir $SITE get e continue a partir de phase: execute a prova daquela fase primeiro; se for válida, inicie a próxima fase. A captura retoma com --resume. Nunca repita as perguntas. Aplicar uma sugestão depois é convert-site --apply <id> (references/apply-suggestion.md), nunca parte da execução em si.
Referências
| Arquivo | Cobre |
|---|---|
references/intake.md | A única mensagem: perguntas, padrões, o que está faltando e o que acontece |
references/phases.md | Toda fase: comandos exatos, a prova de que está feito, o que registrar |
references/build-rules.md | Como layouts, conteúdo, CSS, mídia, fontes, imagens lazy e redirecionamentos são construídos |
references/forms.md | Conexão Formspree, nomes de campos, honeypot, página de agradecimento, o id do formulário, o único envio de teste |
references/third-party.md | A lista de permissões keep em baseline/scripts.json e docs/third-party.md |
references/hosting-vercel.md | Projeto, staging público com noindex, indexação, mídia Blob, proteção opt-in |
references/hosting-cloudflare.md | Projeto Pages, _redirects, _headers, função de mídia R2, redirecionamentos de consulta |
references/runbook.md | docs/LAUNCH.md: A precisa de você, B conclusão, C dia do lançamento, D monitoramento de 30 dias |
references/components-optional.md | A passagem opcional de componentes |
references/apply-suggestion.md | --apply <id>: registros de proposta, commit de branch, gates, folha |