ethanplusai/astro-conversion-kit/convert-site

Claude Code and agent skill by ethanplusai/astro-conversion-kit

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Convert a live website (WordPress first; Drupal, Webflow, Squarespace, Wix and static sites too) into a static Astro site with the same URLs, content, head tags, media, redirects and look, proven by parity gates and a pixel-level visual review, ending in one pull request, a noindexed staging deploy and a launch runbook. Use when asked to convert, rebuild, migrate or clone a site to Astro, when handed a site URL with this kit's link, to resume a conversion from .conversion/state.json, or with --…

Install

npx vskill@latest install ethanplusai/astro-conversion-kit/convert-site

SKILL.md

convert-site

The orchestrator. It asks one message of questions, then runs every other skill in order without stopping again, and ends with a pull request the person merges and a runbook they launch from.

The golden rules

  1. One intake message, then no stops. Every question carries a default. Anything that later

needs an account, a login or a token you do not have goes on the "needs you" list (state.needsYou and docs/LAUNCH.md section A) and the run carries on.

  1. The live site is read-only. Only these read it, paced: the capture scripts, shoot.mjs

and styles.mjs on live, css-coverage.mjs, launch-audit --old-url and pre-launch --predecessor-url. Analytics are blocked on their live page loads, so no visit is counted. Never submit a form on it, log in, or fetch a page by hand to fill a gap.

  1. The default build equals live, faults included. Content is moved from captured markup,

never retyped or tidied. Every oddity is a decision row that says "reproduce live by default". A forced difference is an exception; an improvement is a proposal (PROPOSALS=on only).

  1. Gates on every commit, never softened. Never edit baseline/ to pass (only the keep

flags in baseline/scripts.json). A skip is not a pass; "Not covered" is never a pass.

  1. `main` gets the scaffold commit and nothing else. On a new, empty repository init-site

makes one commit on main, the exception to "never commit to main": the PR needs a base. Everything after it is on astro-rebuild, one PR. Never force-push, never merge, never touch DNS, the old host or a dashboard setting.

  1. No secrets in chat or in the repository. Never ask the person to paste a token.

Credentials come from the environment or a CLI's own login.

Names used below

KIT is the absolute path of this kit (the folder holding skills/ and package.json). LIVE is the live origin. SITE is the absolute path of the new site repository (default <current folder>/<slug>); the capture and the run state are written into it from the start, and init-site.mjs scaffolds around them. Run every command from SITE. Every script prints --help; run that rather than reading the source. Every Node command in a fresh shell starts with source ~/.nvm/nvm.sh && nvm use 22.23.4 (or runs in a shell that reads .nvmrc).

Step 0a: a kit that can run

The scripts import parse5, playwright and the rest from the kit's node_modules. If $KIT/package.json or $KIT/node_modules is missing (an install that copied only the skill folders has neither), clone the kit and install it, then use the clone as KIT:

git clone https://github.com/ethanplusai/astro-conversion-kit <folder>/astro-conversion-kit npm install --prefix <folder>/astro-conversion-kit

Step 0: preflight and fingerprint (before the intake message)

node $KIT/skills/convert-site/scripts/preflight.mjs --json node $KIT/skills/capture-site/scripts/fingerprint.mjs $LIVE

Install what is missing that you can install yourself, without asking: npx playwright install chromium when playwright.chromium is false; vercel and wrangler run through npx. A CLI that is present but not logged in is the person's to log in: name the command (gh auth login, npx vercel login, npx wrangler login) in the intake message and check again at the scaffold.

experience sets how you talk, not what you do. new: one plain sentence per phase on what it does and why, every term explained once, installs done silently. some: one line per phase. experienced: commands and results only. A Shopify fingerprint is a store: stop and say so.

Step 1: intake (the one message)

Send references/intake.md's template, filled in with what preflight and the fingerprint found: every question with its default, and the "what is missing and what happens" list. If the person does not answer, the defaults stand. Never send a second question message.

The phases

The order is docs/process.md's; references/phases.md has every command and each proof. At each boundary run node $KIT/skills/convert-site/scripts/state.mjs --dir $SITE phase <name>; do not start a phase until the previous one's proof holds. Run state.mjs calls one at a time, never chained with &&: each rewrites state.json, and a chain failing partway leaves it out of step.

#Phase (<name>)What happensDone when
1intakePreflight, fingerprint, the one messageAnswered, or defaults stand
2capturecapture-site into $SITE/capture/, CSS coverageEvery URL saved or recorded with its status; Notes written
3planDecide hosting, URL form, media mode, templates; decisions in state; drafts under .conversion/Every template, count, oddity and out-of-scope feature has a decision
4scaffoldRepo, init-site.mjs around the capture, then docs/plan.md and docs/media-plan.jsonIt builds empty; main holds the one scaffold commit
5baselinenpm run baseline (templates.json already exists)build-baseline.mjs --check exits 0
6buildLayouts and shared parts, one page per template, design lock on the templates, then every pagenpm run build passes; template gates pass path by path
7gatesThe full gatesnpm run verify exits 0
8visualEvery template at 390, 768, 1440; every page at 390 and 1440Every pair passes
9componentsOptional, off by default (references/components-optional.md)Gates and diffs still pass, one separate commit
10prelaunchpre-launch, staging deploy, verify-live, launch-audit, one test submissionprelaunch-reconcile.mjs exits 0 (references/phases.md §10); audit blockers fixed or listed
11suggestionssuggest-improvements with gates.json and review/docs/suggestions.md with its "From the review" section
12prRunbook, push, PR, final reportThe PR quotes gate output and every "Not covered" section
13launchThe person's, from docs/LAUNCH.mdpost-launch checks the cutover and watches 30 days

The skills each phase uses, with their own rules: capture-site (2), parity-gates (5 to 7), visual-review (6, 8), pre-launch and launch-audit (10), suggest-improvements (11), post-launch (in the runbook). Read each skill's SKILL.md before its phase.

The build, in one paragraph

references/build-rules.md is binding. Layouts and the shared header, navigation and footer are always components; content blocks are the captured markup, moved by a script. Media at its original paths, fonts self-hosted, CSS by coverage pruning (css-coverage.mjs then css-prune.mjs), never a rewrite. Forms per references/forms.md, third-party scripts per references/third-party.md. redirects.csv is the single redirect source: a new redirect is a row whose source is decision and whose note names the decision id, then npm run redirects:build; never hand-edit the generated rules. One commit per template (feat: <template> template, once its path-scoped gates pass), never one for the whole build. The design is locked on the templates (visual-review) before the rollout to every page. With subagents, one implementer per template or gate fix, never two on one file; each brief carries absolute paths and build-rules.md, and you review their commits before the next phase.

Decisions, exceptions, proposals

This section is the rule; the references link here.

  • Decision. Anything the live site does oddly, and every default you apply, gets

state.mjs decision '{"topic":…,"choice":…,"default":…,"reason":…,"costIfWrong":…}', which prints its id (d1, d2, …). The one ledger is the Decisions table in docs/plan.md: id, date, topic, choice, default, reason, cost if wrong. Before the scaffold the decisions live in .conversion/state.json; the plan table is written from them right after init-site. The default is always "reproduce live".

  • Exception (exceptions.json, { path, field, from, to, reason, approvedBy, date }): a

difference the static build cannot avoid; the gates substitute to for from for that one field on that one path. approvedBy is "default, <decision id>" until a person signs it off in the PR. Forms and scripts are not exception fields (they have their own flags). routes is: a route the capture could not read: from is its status as a string, to is "skip" or the built replacement path.

  • Proposal (proposals.json, the same shape plus id, the decision id, and

approvedBy: "proposed"; several records may share one id): an improvement. Code switches it with proposalOn(id); it ships only in a PROPOSALS=on build, gated by npm run verify:proposals. A change no gate measures (rewritten hrefs) is field: "markup", never compared. When a person approves it, the records move to exceptions.json (approvedBy).

Hosting

Vercel by default, Cloudflare Pages on request: references/hosting-vercel.md and references/hosting-cloudflare.md. Every page carries noindex unless the production build sets PUBLIC_INDEXABLE=true. Media is repo, store (media-upload.mjs) or live-temporary (staging only; gone before DNS moves), as media-plan.mjs decides (references/phases.md §3).

The one message after the plan

After phase 3, send one short status (not a question): platform, page and template counts, the media decision, out-of-scope features and the options, the decisions taken by default, and the needs-you list so far. It is required in a non-interactive run too (standing answers, nobody replying): progress lines do not replace it. Then carry on without waiting.

The pull request (phase 12)

Push astro-rebuild (main was pushed at the scaffold), then gh pr create --base main --head astro-rebuild --title "Astro rebuild of <host>" --body-file .conversion/pr-body.md. While pre-launch fails placeholders.form-id (no form id yet), add --draft, and the final report names that as the blocker. Without a gh login, the body stays in that file and "push and open the PR" goes on the needs-you list. The body, in this order:

## What changed one paragraph: platform, what was converted, host, media mode ## Counts pages, templates, redirects, media files and size, forms, vendors kept/dropped ## Exceptions applied every exceptions.json entry: path, field, reason, decision id ## Proposals open every proposals.json id: paths, what, why (ships only with PROPOSALS=on) ## Decisions the docs/plan.md Decisions table, and every non-default choice ## Gate output npm run verify output, verbatim, in a code block, with every skip line; then every row prelaunch-reconcile accepted, as "reproduced from live (dN)" ## Visual review npm run review:check output, every docs/visual-overrides.json entry (route, id, threshold, reason), every bannerClosed and heightMismatch; the contact sheets are review/index.html and review/all.html (local; npm run review:sheet) ## Staging the staging URL, verify-live result, the launch-audit blockers and their state ## Suggestions counts per category, the medium and high risk items, the applyable ids ## Not covered pre-launch's and launch-audit's "Not covered" sections, verbatim, each under its own heading; then capture-site's, visual-review's and suggestions' ## Waiting on you every state.needsYou item, in runbook order

The final report (to the person)

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
5
Repository forks
3
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/ethanplusai/astro-conversion-kit/convert-site/badge)](https://verified-skill.com/skills/ethanplusai/astro-conversion-kit/convert-site)

Something wrong with this skill or its page? Tell us.