smithery/schuettc

feature-ship

Complete a feature by writing shipped.md, committing to the feature branch, and merging the PR. Use when external reviews are done and the feature is ready to ship.

Installation

$ npx skills add smithery/schuettc --skill feature-ship

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/schuettc.

npx skills add smithery/schuettc

Browse all from smithery/schuettc

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 9,209 B
  • docs SUMMARY.md 219 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

Ship Feature

You are executing the SHIP FEATURE workflow — writing the completion record, committing it to the feature branch, and merging the PR.

Branch Configuration

Before doing anything else, read .feature-workflow.yml in the project root for branch settings. See [../shared/config.md](../shared/config.md) for details.

Multi-repo workspace? If the root has a .feature-workspace.yml, ship from inside the member repo — cd <member> first, so the branch/PR/merge target that member's own remote and config. See [../shared/workspace.md](../shared/workspace.md).

Setting Default Used for
branch.prefix feature/ Branch naming: <prefix><id>
branch.target dev Merge target, checkout after merge
merge_method merge How Phase 4 merges the PR: squash / merge / rebase. Ignored when the base branch requires a merge queue — the queue's own configured method wins, so keep them aligned.

Throughout this skill, replace feature/<id> with <prefix><id> and dev with <target> based on the config.

First Step (Do This Now)

Read the file at path: docs/features/DASHBOARD.md

This file shows in-progress features. Look at the "In Progress" section to find features ready to ship.

Feature Target

$ARGUMENTS

If no specific feature ID was provided above, you will help the user select from in-progress items.


Workflow Overview

Phase Name Purpose
1 Pre-flight Verify feature is in-progress and has a PR
2 Write shipped.md Create completion record on the feature branch
3 Prepare PR Remove review labels + commit and push shipped.md
4 Merge PR Mark PR ready, merge into dev, clean up branches
5 Update Dashboard Regenerate dashboard and clear statusline

Phase 1: Pre-flight

  1. Read the feature's idea.md and plan.md for context
  2. Verify feature is in-progress (has plan.md, no shipped.md)
  3. Check for the PR:

``bash gh api "repos/{owner}/{repo}/pulls?state=open&perpage=100" \ --jq '[.[] | select(.head.ref == "feature/<id>")] | .[0] | {number, url: .htmlurl, state, draft, base_ref: .base.ref}' ``

  1. Verify you're on the feature/<id> branch — if not, switch to it:

``bash git checkout feature/<id> ``

If there's no PR, warn the user — they may want to run /feature-review-impl first, or proceed with a local merge.


Phase 2: Write shipped.md

Write docs/features/<id>/shipped.md with the following format:

---
shipped: YYYY-MM-DD
---

# Shipped: [Feature Name]

## Summary
Brief summary of what was delivered...

## Key Changes
- Change 1
- Change 2
- Change 3

## Files Changed
- `path/to/file1.ts`
- `path/to/file2.ts`

## Testing
How the feature was tested and verified...

## Notes
Any follow-up items, known limitations, or context for future maintainers...

Populate this from the plan.md, commit messages, and git diff.


Phase 3: Prepare PR (labels first, then commit + push)

Order matters here. The review workflow (feature-review.yml) triggers on pull_request: types: [labeled, synchronize]. If review labels (plan-review, impl-review) are still on the PR when the shipped.md push fires a synchronize event, the workflow runs a pointless extra review on a docs-only commit, spending API quota and posting irrelevant review comments on a PR that's about to merge.

Remove the labels before pushing shipped.md:

  1. Remove review labels (must be first — prevents the

push-triggered re-review): ``bash gh pr edit <pr-number> --remove-label plan-review --remove-label impl-review 2>/dev/null || true ``

  1. Commit shipped.md to the feature branch and push:

``bash git add docs/features/<id>/shipped.md git commit -m "docs(<id>): mark feature as shipped" git push ``

After writing shipped.md, regenerate the dashboard by running:

python3 ${CLAUDE_PLUGIN_ROOT}/skills/shared/lib/run_dashboard.py <project_root>

DASHBOARD.md is auto-resolved on merge via CI — no need to commit it from feature branches.


Phase 4: Merge PR

PRs are opened as non-draft (since v9.5.2), so no draft → ready conversion is needed.

  1. Confirm with user: "Merge PR #<number> for feature/<id> into dev?"
  2. If you encounter a draft PR (legacy / opened externally): convert with gh pr ready <pr-number> once. This is a GraphQL mutation, used at most once per stuck PR. Don't retry on rate-limit failure — wait for the GraphQL window to reset (gh api rate_limit --jq '.resources.graphql.reset').
  3. Detect whether the base branch requires a merge queue, then merge accordingly.

A queue-protected branch rejects a direct merge — the only way in is the queue — so the merge path forks on this: ``bash # true when the base branch has a mergequeue rule (via ruleset). QUEUED=$(gh api "repos/{owner}/{repo}/rules/branches/<base>" \ --jq 'any(.[]; .type == "mergequeue")' 2>/dev/null || echo false) ``

No queue (QUEUED = false) — direct REST merge (the common path). Use the mergemethod read from .feature-workflow.yml (default merge if unset). For example maxwell sets mergemethod: squash so features land as one clean commit: ```bash # <mergemethod> = the mergemethod from .feature-workflow.yml (squash | merge | rebase; default merge) gh api "repos/{owner}/{repo}/pulls/<pr-number>/merge" \ --method PUT \ --field mergemethod=<mergemethod>

# Delete the remote branch (REST): gh api "repos/{owner}/{repo}/git/refs/heads/feature/<id>" --method DELETE ```

> Why REST merge: gh pr merge uses GraphQL mergePullRequest. The REST endpoint PUT /pulls/{n}/merge is functionally equivalent, doesn't count against the GraphQL points budget, and isn't subject to the secondary mutation rate limit. The 405 "still a draft" failure mode no longer applies because we never open as draft.

Queue required (QUEUED = true) — enqueue, then wait for the queue to merge. A direct REST merge returns 405 here; gh pr merge enters the queue natively (no merge-strategy flag — the queue's own configured method governs the merge, so the .feature-workflow.yml merge_method is ignored on this path; keep the two in sync). If required checks haven't passed yet it enables auto-merge instead, so the same command is correct either way: ```bash gh pr merge <pr-number> # enqueues (GraphQL, once); queue's merge method applies

# The queue re-runs the required checks against the queued branch and merges # asynchronously. Poll until the PR is MERGED before declaring shipped: until [ "$(gh pr view <pr-number> --json state -q .state)" = "MERGED" ]; do sleep 30 done

# The queue deletes the head branch on merge; tolerate an already-gone ref. gh api "repos/{owner}/{repo}/git/refs/heads/feature/<id>" --method DELETE 2>/dev/null || true ```

> If the queue is slow and you don't want to block, you may stop after gh pr merge > and report the PR as enqueued — it merges when the queue drains. Phase 5 > cleanup (dashboard, local branch delete) only applies once it has actually merged.

  1. Switch to the base branch, pull, and delete the local feature branch (after the

merge has landed — for a queued PR that's after the poll above): ``bash git checkout dev && git pull && git branch -d feature/<id> ``


Phase 5: Update Dashboard and Cleanup

  1. Regenerate the dashboard on dev (shipped.md is now merged):

``bash python3 ${CLAUDEPLUGINROOT}/skills/shared/lib/rundashboard.py <projectroot> ``

  1. Clear the statusline:

``bash python3 ${CLAUDEPLUGINROOT}/skills/shared/lib/statusline.py clear ``

  1. Display completion summary:
## Feature Shipped

**Feature**: [name]
**ID**: <id>
**PR**: <pr-url> (merged)
**Shipped**: YYYY-MM-DD

The feature is now in dev. Dashboard updated.

Error Handling

Error Resolution
Feature not in-progress Direct user to correct command or status
No PR exists Suggest /feature-review-impl first, or offer local merge
Not on feature branch Switch to feature/<id>
Already completed Feature has shipped.md — nothing to do
Direct merge returns 405 / "merge queue required" The base branch requires a merge queue — use the queue path in Phase 4 step 3 (gh pr merge <pr>, then poll for MERGED) instead of the REST merge

Fallback: Manual Ship

If shipped.md wasn't created, you can use the ship script:

python3 ${CLAUDE_PLUGIN_ROOT}/skills/feature-ship/scripts/ship_feature.py <project_root> <feature-id> "Summary message"

After creating shipped.md, regenerate the dashboard:

python3 ${CLAUDE_PLUGIN_ROOT}/skills/shared/lib/run_dashboard.py <project_root>