Extend setup-sites to publish to Netlify, Vercel, and Cloudflare

High todo
2026-06-22 agentics feature High effort

Make setup-sites a multi-host publisher — keep the proven GitHub Pages path and add runtime-selectable Netlify, Vercel, and Cloudflare Pages targets that deploy docs/ via each host's CLI. The Vercel target also publishes a Next.js static export ( output: 'export' → next build → upload out/ ) as the one build-requiring variant, still served as prebuilt static files with no host-side build.

Implement Read and implement all steps in the plan at docs/plans/extend-setup-sites-multi-host-publishing.md — Extend setup-sites to publish to Netlify, Vercel, and Cloudflare. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/extend-setup-sites-multi-host-publishing.md — tick each step's [x] marker and each criterion's - [x], set status: completed — and re-render the HTML from the spec. If any check failed, leave status: in-progress and say which.
More ways to run this plan — goal & workflow prompts, file path
Pursue as goal — optimize for the outcome, in parallel
Achieve this goal: Extend setup-sites to publish to Netlify, Vercel, and Cloudflare. The plan at docs/plans/extend-setup-sites-multi-host-publishing.md describes one approach — use it as reference, but optimize for the outcome. Fan out across parallel subagents where that serves the outcome. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/extend-setup-sites-multi-host-publishing.md — tick each step's [x] marker and each criterion's - [x], set status: completed — and re-render the HTML from the spec. If any check failed, leave status: in-progress and say which.
Run as workflow — launch parallel subagents
Run a workflow to implement the plan at docs/plans/extend-setup-sites-multi-host-publishing.md — Extend setup-sites to publish to Netlify, Vercel, and Cloudflare. Brief subagents with the plan file at docs/plans/extend-setup-sites-multi-host-publishing.md. Reserve a final verification phase for the lead agent, not a subagent. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/extend-setup-sites-multi-host-publishing.md — tick each step's [x] marker and each criterion's - [x], set status: completed — and re-render the HTML from the spec. If any check failed, leave status: in-progress and say which.
File extend-setup-sites-multi-host-publishing.html
Path docs/plans/extend-setup-sites-multi-host-publishing.html
Spec docs/plans/extend-setup-sites-multi-host-publishing.md
Definition of done 0 / 9 done

Context

The story behind this plan — what prompted the work and why it matters now.

The setup-sites skill currently scaffolds only GitHub Pages : an Actions workflow, a .nojekyll marker, the one-time Settings → Pages → Source step, and project-site path-prefix URL math. Its name is already host-agnostic, and three of its four artifacts — the landing hub docs/index.html , the scripts/serve-docs.sh preview, and the docs/ layout — work for any static host. Only the workflow, the .nojekyll marker, and the path-prefix URL are GitHub-specific.

Extending the skill to Netlify, Vercel, and Cloudflare Pages lets the same one-command setup publish wherever a project hosts its docs. The design was settled in the clarify + interview rounds: progressive disclosure via per-host reference files; CLI-based deploys ( netlify / vercel / wrangler ); a runtime host picker defaulting to GitHub Pages; straight-to-production after one explicit confirmation; detect-guide-stop on a missing or unauthenticated CLI (never auto-install); and project names that default to the repo basename with override. Straight-to-production was a deliberate choice over preview-first; the compensating safeguards are showing the exact command and resolved project name before the confirmation, documenting how to unpublish in each reference, and noting each host's dashboard rollback.

Files that change

Every file this plan touches, and what happens to each one.

agentics/
  • .claude-plugin/marketplace.json modified bump plan-agent to 2.9.0, description, tags
  • docs/guides/publish-docs-to-github-pages.md modified add "other hosts" cross-reference
  • kit/plugins/plan-agent/
    • CHANGELOG.md modified 2.9.0 entry
    • README.md modified table row, section, structure tree
  • kit/plugins/plan-agent/.claude-plugin/plugin.json modified description names new hosts
  • kit/plugins/plan-agent/skills/setup-sites/SKILL.md modified host picker + common/host split
  • kit/plugins/plan-agent/skills/setup-sites/references/
    • cloudflare-pages.md new Wrangler Pages deploy
    • netlify.md new Netlify CLI deploy
    • vercel.md new Vercel CLI deploy
  • kit/plugins/plan-agent/templates/pages/serve-docs.sh modified generalize the GitHub-Pages-only comment
  • tests/plugins/test-setup-sites.sh modified multi-host smoke assertions

Steps

The step-by-step work, in order — each step says what to do, why it matters, and how to check it worked.

1
todo Add a host-selection entry step and host-agnostic frontmatter to SKILL.md .
Why
A single entry point that routes by host is what turns a GitHub-only skill into a multi-host one; defaulting to GitHub Pages preserves current behavior for existing users.
Verify
Re-read SKILL.md — the frontmatter description names Netlify/Vercel/Cloudflare, stays ≤200 chars, and keeps the three-part shape (≥2 sentences, ≤80-char short label, a "Use when" trigger) so the existing smoke-test check #3 still passes — e.g. Scaffolds GitHub Pages, Netlify, Vercel, or Cloudflare Pages publishing into any repo. Adds the deploy workflow, hub, and preview script. Use when asked to set up or publish a docs site. (182 chars); the new Step 1 lists four host options and sets $HOST ; allowed-tools still includes Bash , Read , Write , AskUserQuestion , ToolSearch , and ExitPlanMode (Bash is load-bearing for the CLI deploys).
2
todo Restructure the SKILL.md body into a common flow plus per-host dispatch, keeping exactly 7 numbered steps.
Why
Progressive disclosure keeps the body under 500 lines and isolates the new hosts from the battle-tested GitHub path (low regression risk); holding at 7 step headings keeps the existing smoke test's structure assertion valid. The 7→7 mapping (so the count never changes): ① Choose host (new) · ② Preflight git + host-aware URL · ③ Resolve docs/ + plansDirectory , absorbing the old "locate templates" step · ④ Common scaffold (hub + serve-docs.sh, all hosts) · ⑤ Host publish (GitHub workflow/.nojekyll/Pages-source inline; else read the host reference) · ⑥ Verify · ⑦ Deliver .
Verify
grep -cE '^## Step [1-7] —' SKILL.md returns 7; the body is under 500 lines; Step 5 dispatches each host token to its reference file — netlify → references/netlify.md , vercel → references/vercel.md , cloudflare → references/cloudflare-pages.md (note the -pages suffix: the token is cloudflare but the file is cloudflare-pages.md ) — and keeps the GitHub workflow / .nojekyll / Pages-source logic inline; the .nojekyll marker and the Actions workflow are scaffolded only on the GitHub path (the other hosts do not run Jekyll); references/<host>.md are read relative to the skill's own directory; an outward-facing confirmation precedes any CLI deploy.
3
todo Write references/netlify.md for the Netlify CLI deploy path.
Why
Netlify deploys a static directory straight from the CLI with --dir , so the reference captures the exact auth-gated, confirm-first command sequence the skill follows.
Verify
references/netlify.md exists and makes the publish deterministic: link or name the site to the repo basename first ( netlify link , or netlify sites:create --name <repo> ), then netlify deploy --dir=docs --prod --no-build — --no-build forces a static upload so the CLI never runs a Netlify build. Includes a netlify status auth check (run without echoing any token value), an npm i -g netlify-cli install hint that is printed, never executed (detect-guide-stop), and a confirmation gate that shows the exact command and the resolved site name before deploy; plus an unpublish note ( netlify sites:delete or the dashboard) and a mention of Netlify's instant dashboard rollback.
4
todo Write references/vercel.md for the Vercel CLI deploy path.
Why
Vercel is build-oriented, so the reference must pin the no-build / static-directory invocation and first-run project linking to avoid surprising framework detection.
Verify
references/vercel.md exists and makes the publish deterministic: link/name the project to the repo basename before deploying (e.g. vercel link --project <repo> ) so the project is not named after the docs folder, then run cd docs && vercel deploy --prod (deploys docs/ as the site root so framework auto-detection never builds the repo root; framework=Other, no build). It warns that a bare --yes infers the project name from the docs folder, so the link/name step must come first. Includes a vercel whoami auth check (no token echo), an npm i -g vercel install hint that is printed, never executed , and a confirmation gate that shows the exact command and the resolved project name (default: repo basename, overridable) before deploy; plus an unpublish note ( vercel project rm <name> ). It also documents a Next.js static-export path : detect a next.config.{js,mjs,ts} declaring output: 'export' , run next build locally (produces out/ ), then cd out && vercel link --project <repo> --yes && vercel deploy --prod — the publish dir is out/ instead of docs/ , framework still Other (Vercel uploads the prebuilt static files; no host-side build), reusing the same vercel whoami auth check and the confirmation gate (which shows the resolved publish dir). The vercel link inside out/ is load-bearing: a freshly built out/ carries no .vercel/project.json , so deploying without it would create/prompt a separate out project instead of the confirmed repo-basename one; the link (or an equivalent --project <repo> / VERCEL_PROJECT_ID ) carries the project identity into the prebuilt deploy.
5
todo Write references/cloudflare-pages.md for the Wrangler Pages deploy path.
Why
Cloudflare Pages deploys via wrangler pages deploy <dir> and needs a named project, so the reference captures the create-then-deploy sequence and the login / token auth options.
Verify
references/cloudflare-pages.md exists and contains wrangler pages deploy docs --project-name=<name> , the first-run wrangler pages project create note, a wrangler whoami auth check (no token echo), an npm i -g wrangler install hint that is printed, never executed , and a confirmation gate that shows the exact command and the resolved project name (default: repo basename, overridable) before deploy; plus an unpublish note (dashboard or wrangler ).
6
todo Wire the docs and plugin metadata for the new capability.
Why
The marketplace, README, and CHANGELOG are the discovery surface; bumping the version (MINOR for a new capability) and updating prose is required by the project's versioning rules and keeps the smoke test's description/version checks green.
Verify
marketplace.json parses; plan-agent is at 2.9.0 (> 2.8.1) with a description naming the new hosts that still contains setup-sites (trim it to stay within the 1024-char limit); plugin.json has no version key and names the hosts; in README the setup-sites table row, the setup-sites section prose, and the directory tree (which gains references/ with the three host files) are all updated; CHANGELOG has a Keep-a-Changelog 2.9.0 entry; the guide gains an "other hosts" section with a heading and a pointer/link to each of the three references. (The JSON auto-validation hook fires on the marketplace.json write.)
7
todo Extend tests/plugins/test-setup-sites.sh to cover multi-host.
Why
This committed smoke test is the objective-verification — it asserts the skill now offers all four hosts with working per-host references; extending the existing test rather than adding a new file keeps one source of truth.
Verify
bash tests/plugins/test-setup-sites.sh exits 0 with new checks using explicit grep targets: (a) SKILL.md Step 1 names all four hosts and contains a routing line mapping each host token to its reference file ( netlify→references/netlify.md , vercel→references/vercel.md , cloudflare→references/cloudflare-pages.md ); (b) each reference greps for its deploy command ( netlify deploy --dir=docs --prod , vercel deploy --prod , wrangler pages deploy docs --project-name ), its auth check ( netlify status / vercel whoami / wrangler whoami ), and a confirmation marker; references/vercel.md additionally greps for the Next.js static-export branch ( output: 'export' , next build , and a cd out && vercel deploy --prod line); (c) SKILL.md stays under 500 lines and at 7 steps; (d) the marketplace version is ≥ 2.9.0 and the description names the hosts. The test is structural (grep over files) — it cannot exercise the runtime confirmation gate, so "no deploy without confirmation" is covered by the manual per-host trace in the Verification section, noted explicitly in the test.

Tests

The tests that prove the change does what it promises.

Tier 2 — Non-code plan
Objective setup-sites offers all four hosts with working per-host CLI references File: tests/plugins/test-setup-sites.sh (extended) Type: structural smoke test Asserts (structural greps): SKILL.md Step 1 names all four hosts and routes each host token to its reference file (including cloudflare → references/cloudflare-pages.md ); references/netlify.md , references/vercel.md , and references/cloudflare-pages.md each contain their exact deploy command, auth check, and a confirmation marker; references/vercel.md also contains the Next.js static-export branch ( output: 'export' , next build , cd out && vercel deploy --prod ); SKILL.md stays under 500 lines and at 7 numbered steps; marketplace.json bumps plan-agent to ≥ 2.9.0 with a description naming the new hosts. Out of scope: a grep-over-files smoke test cannot prove the runtime confirmation gate actually pauses before deploying — that behavioral guarantee is covered by the manual per-host trace in the Verification section, not by this test. Run: bash tests/plugins/test-setup-sites.sh

Definition of done

The plan counts as done when every statement below is true — check each one off as you verify it.

Final check

One last pass to confirm the whole change works end to end.

Run bash tests/plugins/test-setup-sites.sh and confirm it exits 0. Then trace the skill once per host without deploying : github runs the inline workflow / .nojekyll / Pages path; netlify , vercel , and cloudflare each Read the matching references/<host>.md and stop at the confirmation gate before any deploy. Diff SKILL.md to confirm the GitHub-specific blocks are byte-for-byte unchanged where kept inline. Confirm marketplace.json parses and plan-agent 's version is above the value on origin/main . Optionally run /validate-plugin plan-agent .

Wrapping up

Three gates that must all pass before this plan is marked completed.

Required

Completion Report

No items to report — all requirements met.

Next steps

Follow-up ideas that came up along the way — none of them are required to finish this plan.

Add committed host config files for Git-integration auto-deploy

Paste this prompt into Claude to execute this follow-up:

In the agentics repo, extend kit/plugins/plan-agent/skills/setup-sites so each non-GitHub host can optionally scaffold a committed config file (netlify.toml with publish="docs"; vercel.json with outputDirectory="docs" and framework=null; wrangler.toml for Pages) that enables auto-deploy on git push via the host's Git integration. Put the config templates under kit/plugins/plan-agent/templates/hosts/<host>/, gate them behind an AskUserQuestion ("CLI deploy now" vs "commit config for Git-based deploys"), document them in the matching references/<host>.md, and update tests/plugins/test-setup-sites.sh. Bump plan-agent's minor version in .claude-plugin/marketplace.json and add a CHANGELOG entry.
Write a standalone multi-host publishing guide

Paste this prompt into Claude to execute this follow-up:

Write docs/guides/publish-docs-to-static-hosts.md in the agentics repo: a reference guide for how the setup-sites skill publishes docs/ to Netlify, Vercel, and Cloudflare Pages via CLI — covering install, auth, the deploy command, the resulting live URL, and per-host troubleshooting — mirroring the structure of docs/guides/publish-docs-to-github-pages.md. Cross-link it from the GitHub Pages guide and from kit/plugins/plan-agent/README.md.
Auto-detect the target host from existing repo config Wish List

Speculative / blue-sky idea — not on the critical path. Paste into Claude when ready to explore:

Paste this prompt into Claude to execute this follow-up:

Add host auto-detection to kit/plugins/plan-agent/skills/setup-sites/SKILL.md: before prompting, sniff the repo for an existing host signal (netlify.toml, vercel.json, wrangler.toml or .wrangler/, .github/workflows/deploy-pages.yml, or a docs/CNAME) and pre-select that host as the AskUserQuestion default, falling back to GitHub Pages when no signal is found. Update tests/plugins/test-setup-sites.sh accordingly and bump the plan-agent version with a CHANGELOG entry.