# Ship

> 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.

- Skill: `poshan0126/ship` (Agent Skill)
- Install (CLI): `npx skillmds@latest add poshan0126/ship`
- Raw SKILL.md: https://api.skillmd.com/api/skills/poshan0126/ship/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: poshan0126 (https://skillmd.com/u/poshan0126)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/poshan0126/ship

---


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 -- <file>` 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 <branch>`
- **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

