agentsystemlabs/essentials/ship-pr

Claude Code and agent skill by agentsystemlabs/essentials

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

One-shot "ship it" — split a dirty working tree into logically grouped commits, create/push the branch if needed, and open a GitHub pull request with a senior-engineer-quality title, high-level (non-technical) description, auto-applied labels matched against the repo's existing label set, and "might address #X" links to plausibly-related open issues. Use when the user says "ship it", "ship this", "ship-pr", "/ship-pr", "commit and open a PR", "wrap this up into a PR", "turn these changes into a PR", "send it", "open a PR for this work", or finishes a feature with many changed files and wants commits + branch + PR in one pass. Skip for — single-file copy tweaks, work the user has already committed (use `open-pr`), branches already pushed with an open PR (use `gh pr edit`), amend/fixup workflows, force-push requests, or repos without a GitHub remote.

Install

npx vskill@latest install agentsystemlabs/essentials/ship-pr

SKILL.md

ship-pr

Take a dirty working tree to a merge-ready GitHub PR in one pass: grouped commits → branch pushed → PR opened with a clear title, high-level description, accurate labels, and links to related issues.

A reviewer should understand the change in under a minute. Granularity is judgment; safety is mechanical. When confidence drops, reduce granularity rather than fabricate intent.


When NOT to run

  • Working tree is clean and the branch is already pushed → use open-pr.
  • Fewer than ~3 changed files with one obvious purpose → one commit + open-pr is faster.
  • Branch already has an open PR → use gh pr edit or address-pr-comments.
  • User asked to amend, squash, or force-push → different workflow.
  • No GitHub remote (gh repo view fails) → stop and tell the user.

Workflow

Phase 1 — Inventory (parallel)

Run your reflexive checks (git status, git diff, current branch, recent git log for message style) plus these non-obvious ones in one batch:

gh repo view --json defaultBranchRef -q .defaultBranchRef.name # base branch (do NOT assume main)
git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null # has upstream?
gh label list --limit 200 --json name,description # existing labels — only valid label source
gh issue list --state open --limit 50 --json number,title,labels,body

Exit conditions:

  • You know every changed file and its status (M/A/D/R/??).
  • You know the repo's commit-message convention.
  • You know the base branch (do not assume main).
  • You have the existing label catalog (do not invent labels).
  • You have open issues (for "might address #X" matching).

If git status shows already-staged files: ask before git reset. Don't silently undo the user's staging.

Phase 2 — Risk scan

Before grouping, scan paths and diffs for risky areas. Flag any of these in the PR description's "Things to look out for" section:

  • auth, session, login, password, token, oauth, permission, rbac
  • payment, billing, stripe, subscription, invoice, charge
  • migration, schema, drizzle, prisma, alembic, raw SQL changes
  • .env, secrets, key material, credential handling
  • Public API surface: route handlers, exported library entry points, server functions
  • Anything > 400 lines changed in one file (potential rewrite, deserves a callout)

This is a flag, not a block. Note what was touched and why a reviewer should look closely.

Phase 3 — Group

MANDATORY — READ [`references/grouping-heuristics.md`](references/grouping-heuristics.md) before drawing group boundaries. It catalogs the relatedness signals (shared module, feature slice, test+impl, rename+edit, config+consumer) and the low-confidence fallback rules. Do NOT load when ≤3 changed files with one obvious purpose — group is trivially "one commit".

Produce a draft grouping as a numbered list:

Group N — <one-line theme>
Files:
path/to/file.ts
path/to/file.test.ts
Rationale: <why these belong together>
Depends on: Group <M> | none
Risk flags: <auth/payment/migration/none>

Show the grouping to the user and wait for approval before staging anything. This is the only judgment-heavy step; do not skip the checkpoint.

If confidence on a boundary is low → merge groups, don't split harder. One coarser commit beats two commits that imply a story that isn't there.

Phase 4 — Order & commit

Topological sort by Depends on. Tie-breakers in order: schema → shared types → backend → frontend → tests-with-their-layer → chore/format last.

Each commit must be buildable in isolation. If reordering would break that, merge the two groups.

For each group, run these as separate Bash calls (not chained — Claude Code's safety check can interrupt mid-chain):

  1. git reset (clears prior staging from this run).
  2. git add -- <exact paths> (never git add -A / git add .).
  3. git status — verify only intended files are staged.
  4. git diff --cached --stat — sanity-check size.
  5. Compose message in repo's style (from Phase 1 git log sample). One-line subject; body only when why is non-obvious.
  6. Commit with HEREDOC:

``` git commit -m "$(cat <<'EOF' <subject>

<optional body> EOF )" ```

  1. git status — confirm tree shrank by exactly that group.

If a hook fails: do not --no-verify, do not --amend. Fix it, re-stage, new commit.

Phase 5 — Branch & push

This phase only decides the branch — pushing happens in Phase 8 after the confirmation gate.

If current branch == base branch (main / master / trunk):

  1. Synthesize a branch name from the cumulative diff: <type>/<short-slug> where type ∈ {feat, fix, chore, refactor, docs, perf}. ≤50 chars, kebab-case.
  2. Show it to the user. Wait for y / edit / cancel.
  3. git checkout -b <branch> — local only, no push yet.

If branch ≠ base: keep the current branch.

Determine the push command for Phase 8 (do not run it yet):

  • No upstream → git push -u origin <branch> will run in Phase 8.
  • Has upstream → git push will run in Phase 8.

Never force-push. If the Phase 8 push fails non-fast-forward, surface the error; do not -f.

Phase 6 — PR synthesis

MANDATORY — READ [`references/pr-description-template.md`](references/pr-description-template.md) for the exact body template, tone rules, and the "no code snippets unless fundamental" rule. Do NOT load when the user supplies their own body verbatim — use it as-is (still prepend the Drafted using line).

MANDATORY — READ [`references/label-and-issue-matching.md`](references/label-and-issue-matching.md) for how to pick labels from the existing catalog and how to phrase issue links.

Synthesize from the cumulative diff (git diff <base>...HEAD — three dots), not the last commit:

  • Title — ≤70 chars, imperative, no trailing period, no issue numbers unless the user added them. For 1-commit branches use the subject verbatim. For multi-commit, synthesize.
  • Body — follow references/pr-description-template.md. High level only. No code snippets unless the change introduces a new pattern the whole codebase should follow. Body must begin with > Drafted using [agentsystem.dev](https://agentsystem.dev) as the first line, before ## What changed.
  • Labels — pick from gh label list output only. Apply bug / feature / chore / refactor / docs based on the dominant change type, plus needs review if the repo has it. Match against existing names case-insensitively. Skip labels that don't exist.
  • Linked issues — for each open issue, check title + body for keyword overlap with the changed paths and commit subjects. Strong matches → "this pull request might address #N — _<issue title>_". Never use `Closes #N` / `Fixes #N` unless the user explicitly said so.
  • Draft — open as draft if any commit subject contains WIP, wip, [WIP], draft, or the user asked.
Phase 7 — Confirm (mandatory gate)

Show the user a single block:

Base: <base-branch>
Branch: <current-branch> [will push with -u] ← only if no upstream
Draft: yes/no
Title: <title>
Labels: <label1>, <label2>
Linked: #<n> (might address), #<m> (might address) ← may be empty
Body:
<body>
Commits to land (in order):
1. <subject>
2. <subject>
...
Open PR? (y / edit / cancel)
  • y → push then gh pr create.
  • edit → ask which field; redraft; re-show.
  • cancel → stop; commits stay local.

Do not skip this gate even if the user said "ship it" — title, body, labels, and issue links are your synthesis and a published PR notifies reviewers.

Phase 8 — Push & create
bash
# push only if needed (decided in Phase 5)
git push -u origin <branch> # or: git push
gh pr create \
--base <base> \
--title "<title>" \
[--draft] \
[--label "<label1>" --label "<label2>"] \
--body "$(cat <<'EOF'
<body>
EOF
)"

Always HEREDOC the body. Print the PR URL on success.

If gh pr create fails on a label that doesn't exist: drop that label and retry. Do not auto-create labels.


Output to the user

Committed N groups, pushed <branch>, opened PR:
<PR URL>
1. <subject> (<file count> files)
2. <subject> (<file count> files)
...
Labels: <label1>, <label2>
Linked: #<n>, #<m> ← omit line if none
Risk flags noted: <auth/payment/migration/none>

NEVER

  • NEVER fabricate intent or split aggressively when grouping is ambiguous

Instead: Merge into a coarser group; one honest commit beats two commits that invent a story. Why: A clean-looking log that misrepresents the change is worse than a messy one — reviewers and git bisect both rely on commit subjects being true.

  • NEVER modify files outside the user's working tree to "tidy up" before committing

Instead: Commit only what the user already changed. If unrelated files appear staged, ask. Why: Silent edits — reformatting, lint-fixes, drive-by renames — bury the user's actual change and break their mental model of the diff.

  • NEVER pass a `--label` flag to `gh pr create` for a label not in `gh label list`

Instead: Match candidates case-insensitively against the catalog from Phase 1; drop unmatched. If gh pr create fails on a missing label, drop that label and retry — do not let the agent or gh create it. Why: gh pr create --label X silently auto-creates X with a default grey color when it doesn't exist. That pollutes the repo's label taxonomy permanently and can trigger automation (auto-assign, project-board moves, Slack alerts) the maintainers never opted into.

  • NEVER auto-close an issue the agent matched heuristically

Instead: Only emit GitHub closing keywords (Closes, Fixes, Resolves) when the user explicitly says "this fixes #N" — never on agent-derived matches. Why: Heuristic path/keyword matches are wrong often enough that auto-closing the wrong issue silently dismisses a real bug report and burns the original reporter's goodwill. Notification cost is irreversible — the close email still goes out even if you later reopen.

  • NEVER use `Closes #N` / `Fixes #N` / `Resolves #N` for "might address" links

Instead: Use the literal phrase Might address #N — _<issue title>_. Why: GitHub treats those keywords as closing intent regardless of surrounding prose ("this might address Closes #482" still closes 482 on merge).

  • NEVER include code snippets in the PR description for routine changes

Instead: Stay high-level. Code snippet is allowed only when the change introduces a new pattern the whole codebase should adopt going forward (new helper, new convention) — and then exactly one snippet, captioned "new pattern to follow". Why: Reviewers read the diff for code; the description is for why and what to look at. Snippets in the description duplicate the diff and bury the reasoning.

  • NEVER force-push to make the push or PR succeed

Instead: Surface the error and let the user decide. Why: Non-fast-forward usually means upstream has commits the user hasn't pulled — force-push destroys them.

  • NEVER skip the Phase 7 confirmation gate

Instead: Show title + body + labels + linked issues; wait for y / edit / cancel. Why: PR opens trigger reviewer notifications, CI runs, and Slack/webhook fanout. The synthesis is yours, not the user's — they need to see it before it ships.

  • NEVER use two-dot `git diff <base>..HEAD` for PR synthesis

Instead: Three dots: git diff <base>...HEAD. Why: Two-dot includes upstream changes the branch hasn't merged, polluting the diff and the resulting description.

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 93 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
87
Repository forks
7
7-day trend score
22

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 30 Aug 2026, 2 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/agentsystemlabs/essentials/ship-pr/badge)](https://verified-skill.com/skills/agentsystemlabs/essentials/ship-pr)

Something wrong with this skill or its page? Tell us.