ship-it
Wrap up a finished round of work — verify README and CHANGELOG are current, cut a version if warranted, move completed task files into the completed/ folder…
Skill by tbeack
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/tbeack-ship-it-04f830
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions: not checked yet.
What's inside
- Skill name
ship-it- Description
- Wrap up a finished round of work — verify README and CHANGELOG are current, cut a version if warranted, move completed task files into the completed/ folder, then create a feature branch if needed, commit, push, and open a PR. Run after `/fsad-harness:do-task` has marked one or more tasks done. Takes no arguments.
- License
- MIT
- Allowed tools
- Bash(git, worktree:*),, Bash(git, -C:*),, Bash(git, merge:*),, Bash(git, merge-base:*),, Bash(git, add:*),, Bash(git, commit:*),, Bash(git, branch:*),, Bash(git, mv:*),, Bash(git, rev-parse:*),, Bash(git, checkout:*),, Bash(git, push:*),, Bash(git, pull:*),, Bash(git, status:*),, Bash(git, log:*),, Bash(git, remote:*),, Bash(git, ls-remote:*),, Bash(gh, pr, create:*),, Bash(gh, pr, view:*),, Bash(gh, pr, list:*)
- Instructions
- 182 lines in SKILL.md · view on GitHub
Before installing
- Pre-approves some shell commands
Agent Skills spec issues
- name: missing
Files (1)
- SKILL.md
SKILL.md (first lines)
# fsad-harness:ship-it — wrap up and ship
You run four sequential phases to close out a batch of completed work: worktree merge (Step 0.5), pre-flight audits — README/CHANGELOG/version/completed-task cleanup (Step 1), commit + push + PR (Step 2), and verify-shipped (Step 3). Do not skip phases or reorder them.
"Shipped" means all three of the following verifiable predicates hold — not that a phase list was walked:
1. **Remote-HEAD parity** — the pushed branch's remote SHA (`git ls-remote`) equals local `HEAD`.
2. **PR existence** — `gh pr view` confirms a PR exists for this branch and targets the default branch.
3. **Version-string consistency** — every file in `cfg.version_files` carries the identical new version string (when a version was cut).
Step 3 (Verify shipped) checks all three explicitly before the skill reports success — see that step for details.
## Step 0 — Detect the project
1. Determine the current working directory.
2. Read `~/.claude/commands/fsd/projects.yaml`.
3. Match cwd against each project's `match_paths` (expand `~`). Prefer the longest (most specific) match if multiple match.
4. If a project matches, refer to its entry as `cfg` and the resolved project root as `project_root`. Proceed.
5. If **no project matches**:
- Tell the user the project is not registered.
- Suggest running `/fsad-harness:add-task` from the project to register it.
- Stop.
## Step 0.5 — Merge pending worktrees
1. Run `git worktree list --porcelain` from `project_root`. Parse the output to get all worktrees (each block starts with `worktree <path>`).
2. Filter out the main worktree — the one whose path equals `project_root`.
3. If **no additional worktrees** exist: skip this step entirely and proceed to Step 1.
4. If additional worktrees exist:
- List them for the user: path and branch name (the `branch` field from the porcelain output), plus each branch's uncommitted-changes status (`git -C <path> status --porcelain`, summarized as "clean" or "N uncommitted files").
- **Stop and ask for explicit confirmation** before touching anything:
> "About to merge {N} worktree branch(es) into `{project_root}`: {list}. For each: commit any uncommitted changes, `git merge --no-ff <branch>`, verify the merge landed, then force-remove the worktree and delete the branch. Proceed? (y/n)"
- If the user declines: stop here. Do not modify or remove any worktree. Report which worktrees remain pending.
- On confirmation, for each worktree in order:
a. Check for uncommitted changes: `git -C <path> status --porcelain`. If any are present, commit them: `git -C <path> add -A && git -C <path> commit -m "<branch-name>: parallel do-task changes"`.
b. Merge the branch into the main worktree: `git merge --no-ff <branch>`.
c. If the merge produces a conflict: **stop immediately**. Tell the user which file(s) conflict and provide these resolution steps:
1. Open each conflicting file and locate the conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`).
2. Edit the file to keep the correct content and remove all conflict markers.
3. Stage each resolved file: `git add <file>`.
4. Complete the merge commit: `git commit`.
5. Re-run `fsad-harness:ship-it` to continue from where it left off.
Do not proceed to Step 1. Do not remove the worktree — it may still hold the only copy of unmerged work.
d. **Verify the merge landed before removing anything**: run `git merge-base --is-ancestor <branch> HEAD`. Exit code `0` means the branch tip is now reachable from `HEAD` — the merge is confirmed in the main tree.
- If this check **fails** (non-zero exit): **stop immediately**. Do not remove the worktree or delete the branch — the merge did not land as expected and the worktree is the only safe copy of that work. Report the branch name and ask the user how to proceed.
- If this check **passes**: only now remove the worktree (`git worktree remove --force <path>`) and delete the branch (`git branch -d <branch>`).
5. After all worktrees are merged, verified, and removed: tell the user "Worktrees merged." and proceed to Step 1.
## Step 1 — Pre-flight audits (run concurrently)
These three checks are read-only and independent of each other — none needs another's output. Dispatch them as concurrent subagents (or, if subagents aren't available in the current context, run the three read passes back-to-back with no dependency ordering between them) rather than sequentially:
- **Audit A — README ↔ skills-table consistency:** List all subdirectories in `{project_root}/skills/` (each is a skill). Read `{project_root}/README.md`. For every skill directory, check a corresponding row exists in the README skills table (match on directory name). Report any skills missing from the README.
- **Audit B — CHANGELOG/version derivation:** Read `{project_root}/CHANGELOG.md`. Find the `## [Unreleased]` section and collect everything between that heading and the next `## [` heading (the pending content). Read `cfg.version_scheme` and `cfg.version_files`; if set, read the first file in the list and extract the current version string (JSON `"version"` field, README version-table row, or HTML `<title>`). Report: pending CHANGELOG content (or "empty"), current version scheme, and current version string.
- **Audit C — completed-task cross-reference:** Scan `{project_root}/{cfg.task_dir}/` for files matching the task filename pattern (e.g. `task-proj-NNN.md`) not already inside `completed/`. For each, look up the corresponding identifier in `cfg.todo_file`: `- [x]` → candidate to move; `- [ ]` or not found → leave in place. Report the candidate list.
Once all three audits report back, apply their results serially (writes must stay serial even though the reads were concurrent):
### 1a — README check
- If Audit A found missing skills: tell the user which ones (e.g. `ship-it`, `next`). Ask them to update the README before continuing. Stop — do not proceed until the user confirms it's done and re-invokes.
- If clean: tell the user "README check passed." and proceed.
### 1b — CHANGELOG + version
1. If Audit B's pending content is **empty** (no bullets/subsections):
- Tell the user: "The [Unreleased] section has no content — there may be nothing to release. Proceed anyway? (y/n)"
- No → stop. Yes → skip the version-bump sub-steps and go to 1c.
2. If Audit B's pending content is **non-empty**:
- Show the user the pending content.
- **Propose next version** based on `cfg.version_scheme` (from Audit B):
- `semver`: bump the **patch** component by default (e.g., `v3.2.0 → v3.2.1`). Tell the user they can type `minor` or `major` for a different bump level.
- `integer`: increment the integer suffix by 1 (e.g., `v36 → v37`).
- `calver`: use today's date in `YYYY.MM.DD` format.
- **No `version_scheme` configured:** ask "Cut a new version? If yes, what tag? (e.g. v4)" and use whatever they provide.
- **Confirm:** Present "Suggested version: **[tag]** — confirm, type a different tag, or type `no` to skip."
- `no`/skip → proceed to 1c without modifying CHANGELOG or version files.
- `minor`/`major` (semver only) → recompute at that level and re-present.
- Confirmed/different tag → use that tag and continue.
- **Write version files:** update every file in `cfg.version_files` with the new version string, preserving each file's existing format (JSON `"version"` field, README table row, HTML `<title>`).
- **Update CHANGELOG:** replace `## [Unreleased]` with `## [vN] — YYYY-MM-DD` (today's date), insert a fresh empty `## [Unreleased]` block above it, write the file. Tell the user "CHANGELOG updated — [vN] cut."
### 1c — Move completed task files
- If Audit C found no candidates: tell the user "No completed task files to move." and proceed to Step 2.
- If candidates exist: tell the user "Moving these to `completed/`:" followed by the list, then `git mv` each file into `{project_root}/{cfg.task_dir}/completed/`.
## Step 2 — Commit, push, PR
### 2.0 — Branch guard
1. Run `git rev-parse --abbrev-ref HEAD` to get the current branch name.
2. If the branch is `main` or `master`:
- Propose a feature branch name:
- If a version was cut in Step 1: suggest `release/{version}` (e.g. `release/v4`).
- Otherwise: suggest `task/{task-ids}` using any task IDs marked done during this session (e.g. `task/proj-007`), or `ship/{YYYY-MM-DD}` if no IDs are in scope.
- Ask the user: "Create and switch to `{branch}`? (y/n or type a different name)"
- On confirmation: run `git checkout -b {branch}`.
3. If already on a non-default branch:
- Tell the user "Already on branch `{branch}`."
- If a version was cut in Step 1 **and** the current branch matches the pattern `release/vX.Y.Z` **and** `vX.Y.Z` does not equal the newly cut version:
- Propose renaming: "Branch name `{branch}` is stale — rename to `release/{version}`? (y/n)"
- If yes:
a. `git branch -m {branch} release/{version}` — rename locally.
b. `git push origin release/{version}` — push the new name.
c. `git push origin --delete {branch}` — delete the old remote branch (ignore error if it didn't exist remotely).
d. `git branch -u origin/release/{version}` — update tracking ref.
e. Tell the user "Branch renamed to `release/{version}`."
- If no: continue on the current branch name.
- Otherwise: continue without renaming.
### 2.1 — Independent pre-PR checklist verifier
Before committing, run one more fresh, independent read pass over the three Pre-PR Checklist items (README, CHANGELOG, version files — see `CLAUDE.md`'s Pre-PR Checklist section if present). This pass must **re-read the files from disk**, not reuse conclusions from Step 1 — the point is to catch a mistake the same pass that wrote them could have missed:
1. Re-read `{project_root}/CHANGELOG.md`: confirm the change has an entry either under `## [Unreleased]` or in a freshly cut version block.
2. Re-read `{project_root}/README.md`: confirm the version table's **Current version** and **Date** match what's being shipped (if a version was cut).
3. Re-read every file in `cfg.version_files`: confirm all carry the identical new version string (if a version was cut).
4. If any mismatch is found: report it to the user and stop — do not commit with a known Pre-PR Checklist violation. Ask whether to fix it now or abort.From tbeack/fsad_training, MIT.
Signals
- Stars
- 4
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Aug 31, 2026 (1 month ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/tbeack/fsad_training
- Website
- fsad-training.vercel.app
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
Same skill elsewhere
Copies of this SKILL.md published by others; search shows only one of them.
More from tbeack
- 0.626score
set-context
tbeack
Gather codebase and initiative context before planning starts — runs a graphify build or query when graphify is available locally, falls back to a manual repo…
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
sec-review-fixes
tbeack
Companion to `sec-review-team`.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
plan
tbeack
Guide the user through planning a significant project, a large epic/initiative spanning multiple epics, or a codebase refactor.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
add-task
tbeack
Add a new task to any of your local projects.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
next
tbeack
Pick the next open task from the current project's todo file and invoke `/fsad-harness:do-task` with that task ID.
SkillAFreshness: A★ 8Claude Code +9 - 0.623score
init
tbeack
Initialize a new project with a standard directory structure, template files, and a git repository.
SkillAFreshness: A★ 8Claude Code +9
Cite this page
ship-it skill. Agent Mart. https://agentmart.dev/skills/tbeack-ship-it-04f830 (last updated 2026-10-24)