Add a ship-pages skill — one-command publish for plans & media galleries

High todo
2026-06-18 agentics feature High effort

Ship a one-command /git-agent:ship-pages that takes a user's plans gallery ( docs/plans/ ) and social-share gallery ( docs/media/social/ ) live on GitHub Pages — or any static host — scaffolding every first-run prerequisite so publishing works in any repo with zero manual setup.

Implement Read and implement all steps in the plan at docs/plans/add-ship-pages-skill.md — Add a ship-pages skill — one-command publish for plans & media galleries. Verify against the plan's Tests, Verification, and Acceptance Criteria before reporting done. If everything passed, mark completion in docs/plans/add-ship-pages-skill.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: Add a ship-pages skill — one-command publish for plans & media galleries. The plan at docs/plans/add-ship-pages-skill.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/add-ship-pages-skill.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/add-ship-pages-skill.md — Add a ship-pages skill — one-command publish for plans & media galleries. Brief subagents with the plan file at docs/plans/add-ship-pages-skill.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/add-ship-pages-skill.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 add-ship-pages-skill.html
Path docs/plans/add-ship-pages-skill.html
Spec docs/plans/add-ship-pages-skill.md
Definition of done 0 / 8 done

Context

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

Publishing today is a three-stage pipeline split across plugins: plan-agent + social-media-tools generate gallery HTML into docs/ , git-agent commits and pushes, and a GitHub Actions workflow auto-deploys docs/ to Pages. No single tool chains generate → commit → push → deploy .

Worse, that automatic deploy only works because this repo already ships .github/workflows/deploy-pages.yml and docs/.nojekyll . A plugin user's own repo has none of that scaffolding — so "just push docs/" silently fails to publish.

ship-pages closes the gap by orchestrating the existing gallery and git skills and scaffolding the missing Pages prerequisites, with a --static escape hatch that treats docs/ as a portable bundle for Netlify, Vercel, Cloudflare Pages, or S3. It lives in git-agent (next to ship ) and is command-only, mirroring ship 's deliberate, manual-invoke posture. It locates the plans gallery through the same plansDirectory resolution as plans-library (project → global settings, fallback docs/plans/ ), so it publishes from wherever plans are configured to live.

Files that change

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

agentics/
  • kit/plugins/git-agent/skills/ship-pages/SKILL.md new the command-only ship-pages skill
  • assets/deploy-pages.yml new bundled Pages workflow template
  • kit/plugins/git-agent/
    • CHANGELOG.md modified v3.12.0 entry
    • README.md modified document /git-agent:ship-pages
  • .claude-plugin/marketplace.json modified bump git-agent to 3.12.0
  • tests/plugins/test-ship-pages.sh new smoke + scaffold tests
  • CLAUDE.md modified update git-agent row in plugins table

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 Scaffold the skill directory and SKILL.md frontmatter
Why
Establishes one command-only entry point ( /git-agent:ship-pages ), mirroring ship so Claude never auto-publishes from loose intent. Create kit/plugins/git-agent/skills/ship-pages/SKILL.md with a three-part description, disable-model-invocation: true , and allowed-tools limited to Bash(git *) , Bash(gh *) , Bash(python3 *) , Read, Write, Skill, ToolSearch, ExitPlanMode.
Verify
head -8 of the SKILL.md shows name: ship-pages and disable-model-invocation: true ; the file resolves under git-agent/skills/ship-pages/ .
2
todo Write pre-flight + gallery auto-detection (skill Steps 0–2)
Why
The skill must run with zero required args by detecting what exists, and refuse early when there is nothing to publish. Step 0 exits plan mode (deferred ExitPlanMode); Step 1 verifies a git repo + gh auth status , resolves owner/repo via gh repo view --json owner,name , and parses --static , --plans-only , --media-only , --dir ; Step 2 resolves the plans gallery directory via the plansDirectory pattern — read plansDirectory from project .claude/settings.json , then global ~/.claude/settings.json , falling back to docs/plans/ (the exact resolution plans-library uses) — and detects *.html there (excl index.html ); cards are detected under docs/media/social/ . STOP with guidance if neither gallery exists.
Verify
Step 2 resolves the plans dir via the plansDirectory pattern (project → global → docs/plans ) rather than a hard-coded path, detects both galleries, and includes a STOP branch when both are empty.
3
todo Write the stale-aware rebuild step reusing plans-library / media-library
Why
Keeps the published index current without paying a rebuild every run, and reuses gallery logic instead of duplicating it. For each detected gallery, rebuild only when index.html is missing or older than the newest plan/card (mtime compare), invoking Skill(plan-agent:plans-library) and/or Skill(social-media-tools:media-library) .
Verify
Step 3 names both library skills and includes the mtime/staleness check; nothing in the skill re-implements gallery HTML.
4
todo Write the Pages scaffold + auto-enable step and the bundled workflow asset
Why
Closes the core gap — a user's repo lacks the workflow, .nojekyll , and a root index. Create assets/deploy-pages.yml (the repo's proven workflow with pinned SHAs). When not --static : write the workflow if absent, create docs/.nojekyll if absent, scaffold a minimal docs/index.html linking both galleries if absent (never overwrite), then enable Pages via gh api --method POST repos/{owner}/{repo}/pages -f build_type=workflow , falling back to printed Settings → Pages steps on any error (already-enabled, missing scope). Deploy-source guard: the workflow uploads path: docs , so if the resolved plansDirectory falls outside docs/ , warn that the docs-based Pages workflow won't include it and recommend moving plansDirectory under docs/ or using --static pointed at the gallery dir (media always lives under docs/media/social/ ).
Verify
assets/deploy-pages.yml is valid YAML containing path: docs and the .nojekyll assertion; Step 4 covers all four scaffold artifacts plus the fallback path.
5
todo Write the scoped publish step reusing branch-agent + pr-agent
Why
Honors the "scope to publish paths" + "branch + PR" decisions while still reusing git-agent's branch/PR skills. Stage ONLY publish paths — always git add docs/ , and stage .github/workflows/deploy-pages.yml only in Pages mode when it exists (in --static mode no workflow is scaffolded, so adding that pathspec would abort git add with a pathspec error before the docs bundle is staged); warn about and leave unrelated changes uncommitted; if on main / master create a branch via Skill(git-agent:branch-agent) ; make a scoped conventional commit ( docs(pages): publish plans/media galleries ); push + open a PR via Skill(git-agent:pr-agent) . Explicitly do NOT call ship — its git add -A would defeat scoped staging.
Verify
Step 5 stages docs/ (plus the workflow file only in Pages mode, when present), calls branch-agent and pr-agent , and carries a note explaining why ship is bypassed.
6
todo Write the confirm + static-host export step (skill Steps 6–7)
Why
Gives a definitive "where is it" answer for Pages and a host-agnostic export satisfying "any static host" with no extra build. Pages mode: print https://{owner}.github.io/{repo}/ (handle the {owner}.github.io root-site case), noting it goes live after merge + the Actions run. --static mode: skip scaffolding/enable, treat docs/ as the bundle, and print deploy commands for Netlify ( netlify deploy --dir=docs --prod ), Vercel ( vercel deploy docs --prod ), Cloudflare ( npx wrangler pages deploy docs ), and S3 ( aws s3 sync docs s3://<bucket> --delete ).
Verify
Step 6 prints the github.io URL; Step 7 lists at least the four host commands, all pointing at docs/ .
7
todo Register the skill and sync docs (marketplace, CHANGELOG, README, CLAUDE.md)
Why
For relative-path plugins the marketplace version is what ships, and repo rules require docs + changelog updated in the same PR. Bump git-agent version 3.11.0 → 3.12.0 (minor, new skill) in .claude-plugin/marketplace.json ; add a v3.12.0 entry to kit/plugins/git-agent/CHANGELOG.md ; document /git-agent:ship-pages in kit/plugins/git-agent/README.md ; update the git-agent row in the root CLAUDE.md plugins table.
Verify
git-agent reads 3.12.0 in marketplace.json (JSON-validation hook passes) and grep -l ship-pages lists CHANGELOG.md, README.md, and CLAUDE.md.
8
todo Add smoke + scaffold tests
Why
Locks in the objective with executable tests that ship with the repo. Create tests/plugins/test-ship-pages.sh following the repo's shell-test convention: assert SKILL.md frontmatter (name, disable-model-invocation), validate the bundled deploy-pages.yml parses as YAML and contains path: docs , assert marketplace registration ≥ 3.12.0, and run a scaffold dry-run against a temp git fixture asserting the three Pages artifacts and a scoped branch/commit are produced without pushing.
Verify
bash tests/plugins/test-ship-pages.sh exits 0.

Tests

The tests that prove the change does what it promises.

Tier 1 — Code-touching plan
Objective ship-pages publishes galleries end-to-end with no manual setup File: tests/plugins/test-ship-pages.sh Type: smoke test Asserts: against a temp git repo seeded with docs/plans/ + docs/media/social/ and no pre-existing Pages config, the scaffold+publish path writes .github/workflows/deploy-pages.yml , docs/.nojekyll , and docs/index.html , creates a publish branch with a commit touching only docs/ + the workflow, and prints the owner.github.io/repo URL. Run: bash tests/plugins/test-ship-pages.sh
Unit Bundled deploy-pages.yml is valid and correct File: tests/plugins/test-ship-pages.sh (asset-validation section) Targets: kit/plugins/git-agent/skills/ship-pages/assets/deploy-pages.yml Key cases: parses as YAML; triggers on push to docs/** ; declares pages: write + id-token: write ; asserts docs/.nojekyll ; uploads path: docs .
Integration Skill registered + plugin structure valid File: tests/plugins/test-ship-pages.sh (registration section) Targets: .claude-plugin/marketplace.json + kit/plugins/git-agent/ structure Key cases: marketplace.json is valid JSON; git-agent version ≥ 3.12.0 and higher than main ; SKILL.md frontmatter has name: ship-pages + disable-model-invocation: true .
E2E Scaffold + scoped publish + static mode in a temp repo File: tests/plugins/test-ship-pages.sh (e2e section, mocked gh ) Targets: the full Pages-mode and --static flows against a throwaway git fixture Key cases: first run scaffolds all three Pages artifacts + opens a PR; an unrelated uncommitted file is left unstaged; a second run skips scaffolding and rebuilds only the stale gallery; --static prints docs/-based host commands and writes no workflow.

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.

Load git-agent locally ( claude --plugin-dir ./kit/plugins/git-agent ) in a checkout that has docs/plans/ plans and docs/media/social/ cards. Run /git-agent:ship-pages and confirm it: (1) rebuilds only stale galleries, (2) scaffolds deploy-pages.yml , docs/.nojekyll , and docs/index.html when absent, (3) enables Pages via gh api or prints fallback steps, (4) opens a PR whose diff is limited to docs/ + the workflow file, and (5) prints https://<owner>.github.io/<repo>/ . Run /git-agent:ship-pages --static and confirm it skips all scaffolding and prints docs/ -based Netlify/Vercel/Cloudflare/S3 commands. Finally run bash tests/plugins/test-ship-pages.sh and confirm it exits 0.

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 a ship-pages-bg background variant

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

Add a `ship-pages-bg` background command to the git-agent plugin that fires the ship-pages publish flow via a background subagent, mirroring the existing commit-bg / pr-bg / ship-bg commands in kit/plugins/git-agent/commands/. Reuse the ship-pages skill; return control immediately with an ack. Bump git-agent's version in .claude-plugin/marketplace.json and add a CHANGELOG entry.
Add a --watch flag that polls the Pages deploy and reports the live URL

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

Add a `--watch` flag to the git-agent ship-pages skill (kit/plugins/git-agent/skills/ship-pages/SKILL.md) that, after opening the publish PR, polls the GitHub Actions "Deploy to GitHub Pages" run with `gh run watch` and reports the live https://<owner>.github.io/<repo>/ URL once the deploy succeeds. Document the flag in the README and bump the git-agent version in marketplace.json.
Generate per-host config files (netlify.toml / vercel.json) 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:

Extend the git-agent ship-pages skill with an opt-in `--emit-host-config` flag that writes netlify.toml, vercel.json, and a Cloudflare Pages config pointing at docs/ as the publish directory, so users can connect those hosts with zero manual config. Keep it off by default; document the generated files in the README.
Share a reusable docs/ "site hub" landing template 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:

Design a reusable docs/index.html "site hub" template shared between the agentics landing hub (docs/index.html) and the ship-pages scaffolded landing page, linking the Plans gallery and Media library with consistent dark-mode styling. Factor it into the git-agent ship-pages skill assets and have ship-pages scaffold from it.