--- name: ship description: Commit, push, and create a PR for staged changes, with confirmation at each step. Use when your work is done and you want to ship. argument-hint: "[optional commit message or PR title]" disable-model-invocation: true allowed-tools: - Bash(git status) - Bash(git diff *) - Bash(git log *) - Bash(git add *) - Bash(git commit *) - Bash(git push *) - Bash(git checkout *) - Bash(git branch *) - Bash(gh pr create *) - Bash(gh pr view *) - Bash(git fetch *) - Bash(git for-each-ref *) --- Ship the current changes through commit, push, and PR creation. Confirm with the user before each step using the AskUserQuestion tool. ## Step 1: Scan Current scan state (injected read-only below — no need to re-run these to gather it): - Status: !`git -C "${CLAUDE_PROJECT_DIR:-.}" status --short 2>/dev/null || echo "(no git repo or no changes)"` - Change summary: !`git -C "${CLAUDE_PROJECT_DIR:-.}" diff --stat HEAD 2>/dev/null || echo "(no diff)"` - Recent commit style: !`git -C "${CLAUDE_PROJECT_DIR:-.}" log --oneline -5 2>/dev/null || echo "(no commits yet)"` For the full patch of a specific file before committing, run `git diff -- ` on demand (kept out of the injection to hold the render small). - Present a clear summary to the user: - Files modified - Files added - Files deleted - Untracked files - If there are no changes, tell the user and stop ## Step 2: Stage & Commit - Propose which files to stage. **Never stage** these: - Secrets: `.env*`, `*.pem`, `*.key`, `credentials.json` - Lock files: `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml` (unless intentionally updated) - Generated: `*.gen.ts`, `*.generated.*`, `*.min.js`, `*.min.css` - Build output: `dist/`, `build/`, `.next/`, `__pycache__/` - Dependencies: `node_modules/`, `vendor/`, `.venv/` - OS/editor: `.DS_Store`, `Thumbs.db`, `*.swp`, `.idea/`, `.vscode/settings.json` - Draft a commit message based on the changes, matching the repo's existing commit style - **ASK the user to confirm or edit**: show the exact files to stage and the proposed commit message - Only after confirmation: stage the files and create the commit - If the commit fails (e.g., pre-commit hook), fix the issue and try again with a NEW commit ## Step 3: Push - Check if the current branch has an upstream remote - If not, propose creating one with `git push -u origin ` - **ASK the user to confirm** before pushing - Only after confirmation: push to remote ## Step 4: Pull Request - Check if a PR already exists for this branch (`gh pr view`. If it exists, show the URL and stop) - Analyze ALL commits on this branch vs the base branch (not just the latest commit) - Draft a PR title (under 72 chars) and body with: - Summary: 2-4 bullet points - Test plan: how to verify - **ASK the user to confirm or edit** the title and body - Only after confirmation: create the PR with `gh pr create` - Show the PR URL when done ## Step 5: Branch cleanup (optional) After the PR is created (or if invoked when everything is already shipped), offer to clean up stale local branches: - `git fetch --prune`, then find branches whose upstream is gone: `git for-each-ref --format '%(refname:short) %(upstream:track)' refs/heads | grep '\[gone\]'` - Show the list and **ASK before deleting**. Delete with `git branch -d` only. - If a branch isn't fully merged (`-d` refuses), list it separately — deleting unmerged branches needs the user to explicitly say so, every time. ## Rules - NEVER skip a confirmation step. Each step requires explicit user approval - NEVER force-push - NEVER commit .env, secrets, or credential files - If the user says "skip" at any step, skip that step and move to the next - If $ARGUMENTS is provided, use it as the commit message / PR title