/create-pr
Take working-tree changes (uncommitted, or recently committed to the default branch), derive an appropriate branch name + commit message + PR title from the diff, run /drain so pending learnings ride along in the same PR, run an AI review chain (generic baseline + any team-declared specialists), commit + push, and open a PR. Optionally enable GitHub auto-merge with a bounded polling + auto-fix loop. Always return the user to the target branch at end-of-work.
This skill is the deterministic "ship a piece of work" flow — it applies the branch-hygiene, learning-capture, and karpathy-guidelines rules, so you don't re-derive them every PR.
Ships as a global skill in the atl monorepo.
Flags
| Flag | Default | Effect |
|---|---|---|
--auto-merge | OFF | Enable GitHub auto-merge (gh pr merge --auto --squash); poll + auto-fix until merged or terminal failure |
--no-review | OFF (review on) | Skip the entire review chain (generic + every team reviewer) |
--no-auto-fix | OFF (fix on) | During the polling loop, do not attempt to fix CI/merge failures; surface to the user instead |
--no-drain | OFF (drain on) | Skip folding pending learnings into the knowledge base |
--timeout {min} | 10 | Polling timeout in minutes; 1-minute interval, applies to both --auto-merge and manual-merge wait |
Flow
The flow runs sequentially. Each step has a clear precondition and postcondition; if a precondition fails, the skill surfaces the issue and stops instead of proceeding.
Step 1 — Pre-checks
- Current directory is inside a git repo
- Working tree has changes OR the current branch has unpushed commits (if neither: "Nothing to do — working tree clean and branch up-to-date")
- Determine the repo's default branch (
main/master)
Step 2 — Determine target branch
The "target branch" is what the PR merges into AND what the user returns to at end-of-work.
- On the default branch → target = default branch.
- On a non-default branch →
AskUserQuestionwith three choices: upstream branch (auto-detected), the default branch, or a free-text Other.
Step 3 — Generate branch name + commit message
Analyze staged + unstaged + untracked changes:
- Type — one of
feat,fix,docs,chore,refactor,test,perf(heuristic-derived from the diff: new agent/skill/rule or feature →feat; bug-fix language →fix; only*.md→docs; etc.) - Scope — most-specific scope covering the change (skill name, rule name, agent name, CLI command, repo area)
- Slug — kebab-case, ≤ 50 chars, ASCII
Outputs:
- Branch name —
{type}/{slug}(e.g.,feat/create-pr-skill,fix/install-404,docs/translate-tr-en) - Commit subject —
{type}({scope}): {one-line summary}under 70 chars - Commit body — 2–4 bullets describing the change
The skill does not ask the user to confirm names — it generates and proceeds.
Step 4 — Drain pending learnings (unless --no-drain)
Invokes /drain so any learnings captured during the session ride along in the same PR:
/drainreads the durable learning queue, routes each pending item to the wiki / journal / agent knowledge base, and acks it.- An empty queue is a no-op.
- If
/drainisn't installed, the step is skipped with a one-line notice — it never fails the skill.
v2's marker is plain prose (<!-- learning: free text -->); /drain infers where each learning belongs, so there's no separate doc-draft step to review. See atl learnings and the /drain skill.
Step 5 — Review chain (unless --no-review)
Two layers, executed sequentially:
5a — Generic reviewer (always)
Spawns a fresh-context sub-agent over the staged diff (fresh context so the review isn't biased by the model that wrote the diff), prompted with the four Karpathy guidelines:
- Think Before Coding (assumptions explicit?)
- Simplicity First (over-engineering?)
- Surgical Changes (drive-by edits? orphans?)
- Goal-Driven Execution (verifies against the goal? success criteria?)
Plus general code quality (naming, scope creep, security smells — secrets in logs, injection, hardcoded credentials — dead code, test coverage). Reports as 🔴 issues / 🟡 concerns / 🟢 good.
5b — Team specialists (per installed team)
For each installed team (look under .claude/agents/ then ~/.claude/agents/ — project shadows global), the skill reads team.json capabilities.review:
- If it names an agent (e.g.,
capabilities.review: "code-reviewer"), that team agent runs against the same diff and produces a domain-specific review. - If not declared, the team is skipped — 5a is the platform-wide baseline.
The consolidated report is shown to the user: continue / abort / edit.
Step 6 — Commit + push
git checkout -b {branch-name}
git add -A
git commit -m "{commit-subject}
{commit-body}"
git push -u origin {branch-name}Step 7 — Open PR
gh pr create \
--base {target-branch} \
--title "{commit-subject}" \
--body "<Summary bullets + Test plan checklist>"The skill does not pass --assignee or --reviewer.
Step 8 — --auto-merge (only if the flag is set)
gh pr merge {N} --auto --squashThis is the only allowed merge invocation in the entire skill set. It does not merge immediately — GitHub waits for required checks, then merges, so the branch-protection gate is preserved. The user opted in by passing the flag.
Step 9 — Polling + auto-fix loop (if --auto-merge)
Polls PR state at 1-minute intervals, up to {timeout} attempts (default 10). State machine:
| State | Action |
|---|---|
MERGED | Success — proceed to end-of-work |
CLOSED | User closed without merge — exit cleanly, no end-of-work |
*CLEAN / *HAS_HOOKS | Healthy state, just waiting for checks — continue polling |
*BLOCKED / *UNSTABLE / *DIRTY / *BEHIND | CI failure or merge conflict — handle_failure |
handle_failure classification
In-scope (auto-fix attempted, max 3):
- Merge conflicts — fetch latest target, attempt 3-way merge
- Lint / format failures — run the project's formatter (auto-detected:
package.json scripts.lint,.prettierrc,gofmt,cargo fmt, etc.) - Trivial type errors / missing imports — apply compiler-suggested fixes
Out-of-scope (notify and stop):
- Real test failures (assertions, regressions in existing tests)
- Non-trivial build errors
- Infrastructure / CI config issues
- Missing required reviews (human reviewers blocking)
After 3 in-scope fix attempts, the skill stops and reports.
Step 10 — Manual-merge polling (only if --auto-merge was NOT set)
The skill polls for merge anyway — the user might merge manually within {timeout} minutes. Same MERGED / CLOSED / timeout exits.
Step 11 — End-of-work (universal)
Reached only when the PR was merged successfully:
git checkout {target-branch}
git pullThe user ends the skill on the target branch, with the merged change incorporated, ready for the next task.
Step 12 — Final report
✅ /create-pr complete
Branch: feat/create-pr-skill
PR: https://github.com/.../pull/N
Review: generic + 1 team reviewer (software-project-team)
3 issues, 1 concern, all addressed
Drain: /drain ran — 2 wiki pages updated, 1 journal entry
Auto-merge: enabled, merged after 4 min (1 auto-fix: prettier formatting)
End-of-work: returned to main, pulled latestImportant constraints
- Never merge directly. The skill uses
gh pr merge --auto --squash(auto-merge enable) only when--auto-mergeis passed. An immediategh pr merge --squash/--merge/--rebase(without--auto) is always forbidden — auto-merge preserves the required-check gate, and the user opted in by typing the flag. - Idempotent drain. Running
/drainhere is safe — it processes only unacknowledged queue entries. - team.json validation. If the staged diff touches a
team.json, the skill verifies that the file parses, has anamefield, and all declared assets exist on disk before push. - Branch hygiene before start. Before deriving the new branch, the skill verifies the local default branch is current with origin; if behind, it fast-forwards first (per
branch-hygiene). - No silent partial failures. If any step fails, the skill stops and reports — the user always knows where they are.
Related
/drain— invoked at Step 4 to fold pending learnings into the knowledge basebranch-hygienerule — keep the base branch current before branchingkarpathy-guidelinesrule — the review prompt's foundation