ai-ship/SKILL.md
Pick the next ready AFK GitHub issue, implement it with TDD, run the full Next.js quality gate, call /simplify, create a PR, call /review + /security-review, and verify the app at runtime with Chrome DevTools MCP. Use when the user wants to process the backlog, implement the next issue, or run the dev loop. Trigger phrases - "/ship", "ship the next issue", "work through the backlog".
npx skillsauth add paulund/ai ai-shipInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Process the next ready autonomous issue end-to-end: implement it, prove it works, open a PR with automated review, and leave it ready for the user to merge.
Intended to run repeatedly via /loop /ship until no issues remain.
next build passing doesn't mean the app runs — Chrome DevTools MCP proves it does./review + /security-review; fixes happen back in the parent where implementation memory is still loaded.gh issue list --label "planned,afk" --state open --json number,title,labels,body
Then verify blockers with open/closed state — never assume a referenced issue is open without checking:
import json, sys, re, subprocess
data = json.load(sys.stdin)
def get_blockers(body):
m = re.search(r'##\s+Blocked by\s*\n(.*?)(?=\n##|\Z)', body or '', re.DOTALL | re.IGNORECASE)
if not m:
return []
return re.findall(r'#(\d+)', m.group(1))
def is_open(num):
r = subprocess.run(['gh', 'issue', 'view', num, '--json', 'state'], capture_output=True, text=True)
return r.returncode == 0 and json.loads(r.stdout).get('state') == 'OPEN'
for issue in sorted(data, key=lambda i: next((l['name'] for l in i['labels'] if re.match(r'^p[123]$', l['name'])), 'p9')):
labels = [l['name'] for l in issue['labels']]
if 'hitl' in labels or 'blocked' in labels:
continue
open_blockers = [b for b in get_blockers(issue['body']) if is_open(b)]
if not open_blockers:
print(f"PICK: #{issue['number']} — {issue['title']}")
break
Rules:
hitlblockedBlocked by #N references have open state — always query gh issue view N --json state to confirm; a merged/closed blocker does NOT blockp1 > p2 > p3)Read the issue body fully — the acceptance criteria drive the TDD cycles.
main)claude/issue-<N>-<slug>planned, add in-progressFor each acceptance criterion, run a RED → GREEN → REFACTOR cycle:
Tests verify behaviour through public interfaces, not implementation. They should survive internal refactors.
Run in this order. Each step must pass before moving on.
pnpm lint # or: npx next lint
pnpm types # tsc --noEmit
pnpm build # or: npx next build
On failure — Stop-the-Line:
Max 2 diagnose-fix cycles per issue. If still failing, stop and leave the branch for the user — do NOT open a broken PR.
Invoke the built-in /simplify skill to review recently changed code for clarity, unused code, and consistency. Apply its suggestions before the PR.
Re-run the quality gate if /simplify made non-trivial changes.
Push the branch and create the PR:
gh pr create \
--base "main" \
--title "<short descriptive title>" \
--body "$(cat <<'EOF'
## What this does
[Plain-English summary of the change.]
Closes #<issue-number>
EOF
)"
Rules:
Closes #N. No AI output, no checklists, no screenshots.Spawn /review and /security-review as sub-agents (fresh context, read-only) so they read the PR diff without implementation bias.
~/.agents/skills/review/SKILL.md, run against PR #<N>, return findings as severity | file:line | category | description | suggested fix~/.agents/skills/security-review/SKILL.md, run against branch vs origin/HEAD, return report per that skillFix loop (parent context — implementation memory is still loaded):
Create GitHub issues for every accepted-as-is item that isn't already tracked by an open issue. Do this before posting the PR comments so you can reference issue numbers inline.
For each deferred item:
gh issue list --state open for an existing issue covering it — skip if one exists, note its numbergh issue create \
--title "chore: <short description of the deferred finding>" \
--body "$(cat <<'EOF'
## Context
Deferred from PR #<N> review — accepted as-is because <reason>.
## What to do
<concrete description of the fix needed, with file:line reference>
## Acceptance criteria
- [ ] <specific, testable criterion>
EOF
)" \
--label "planned"
Post two separate PR comments so each can be resolved independently on GitHub:
gh pr comment <pr-number> --body "$(cat <<'EOF'
## Automated review
### Fixed
- [list of issues fixed with file:line reference]
### Accepted as-is (Low only — Critical/High/Medium must always be fixed)
- [item — reason — tracked in #N]
EOF
)"
gh pr comment <pr-number> --body "$(cat <<'EOF'
## Security review
### Fixed
- [list of issues fixed with file:line reference]
### Accepted as-is (Low only — Critical/High/Medium must always be fixed)
- [item — reason — tracked in #N]
EOF
)"
in-progress, add in-reviewIf no more planned AFK issues exist, stop and report:
Backlog processed.
- Shipped: <list of PR URLs>
- Still in-review: <list>
- HITL issues waiting for you: <list>
Stop and leave the branch for the user in these cases:
hitl) — flag the issue and stopAlways better to leave a clean branch than to push a broken PR.
Before implementing, always read the repo's CLAUDE.md if present. It overrides generic guidance.
Framework rules apply automatically via global skills:
~/.claude/skills/dev-nextjs.md~/.claude/skills/dev-typescript.mdIf you repeatedly see a pattern these skills don't cover, tell the user — the rule belongs in one of those files.
hitl issues autonomouslydevelopment
Use when implementing any logic, fixing any bug, or changing any behaviour. Use when you need to prove code works, when a bug report arrives, or when modifying existing functionality. Do NOT use for config changes, data migrations, or dependency updates.
development
Use when starting a new feature, when requirements are unclear, when asked to write code without a clear spec, or before any non-trivial implementation. Do NOT use for trivial bug fixes or one-line changes.
development
Use when you want authoritative, source-cited code free from outdated patterns. Use when building with any framework or library where correctness matters. Detects the stack from dependency files, fetches official documentation, implements following documented patterns, and cites sources for every framework-specific decision.
development
Use when preparing to ship a feature, release, or deployment. Use before merging to main, creating a release, or deploying to production. Do NOT use for CI-only changes or internal refactors that don't reach production.