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.
What this skill does
# 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&per_page=100" \
--jq '[.[] | select(.head.ref == "feature/<id>")] | .[0] | {number, url: .html_url, state, draft, base_ref: .base.ref}'
```
4. 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:
```markdown
---
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
```
2. 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:
```bash
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 merge_queue rule (via ruleset).
QUEUED=$(gh api "repos/{owner}/{repo}/rules/branches/<base>" \
--jq 'any(.[]; .type == "merge_queue")' 2>/dev/null || echo false)
```
**No queue (`QUEUED` = false) — direct REST merge** (the common path). Use the
`merge_method` read from `.feature-workflow.yml` (default `merge` if unset). For
example maxwell sets `merge_method: squash` so features land as one clean commit:
```bash
# <merge_method> = the merge_method from .feature-workflow.yml (squash | merge | rebase; default merge)
gh api "repos/{owner}/{repo}/pulls/<pr-number>/merge" \
--method PUT \
--field merge_method=<merge_method>
# 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.
4. 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 ${CLAUDE_PLUGIN_ROOT}/skills/shared/lib/run_dashboard.py <project_root>
```
2. Clear the statusline:
```bash
python3 ${CLAUDE_PLUGIN_ROOT}/skills/shared/lib/statusline.py clear
```
3. Display completion summary:
```
## Feature Shipped
**Feature**: [name]
**ID**: <id>
**PR**: <pr-url> (merged)
**Shipped**: YYYY-MM-DD
The feature Related in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.