Comprehensive PR creation with validation. All output goes directly to GitHub PR.
Quick Start
create-pr
create-pr "Add user authentication"
CC ≥ 2.1.119 multi-host note (M122): PR creation works against GitHub, GitLab, Bitbucket, and GitHub Enterprise. Detect the target host from the configured remote (
git remote -v) and branch on the host family for the right CLI:
Host family CLI github / github-enterprise gh pr create(withGH_HOST=<host>for GHE)gitlab / gitlab-self glab mr createbitbucket bb pr createCustom enterprise URLs:
prUrlTemplatesetting (seesrc/skills/configure/andsrc/skills/chain-patterns/references/pr-from-platform.md).
Argument Resolution
TITLE = "$ARGUMENTS" # Optional PR title, e.g., "Add user authentication"
# If provided, use as PR title. If empty, generate from branch/commits.
# $ARGUMENTS[0] is the first token (CC 2.1.59 indexed access)
Base Branch Resolution
Derive the base branch from the remote. Never hardcode dev or main; repos differ.
BASE=$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')
BASE=${BASE:-main} # ref missing (fresh/shallow clone)? run: git remote set-head origin -a
Every $BASE below refers to this value.
Stacked on another open PR
When the work depends on an open PR ("a PR that depends on PR #50"), that PR's head branch is
the base, not $BASE:
PARENT=50
PARENT_BRANCH=$(gh pr view "$PARENT" --json headRefName -q .headRefName)
git fetch origin && git rebase "origin/$PARENT_BRANCH" # pre-flight: sync with the parent
gh pr create --base "$PARENT_BRANCH" --title "$TYPE(#$ISSUE): ... [2/3]" \
--body "Stacked on #$PARENT. Do not merge into the parent branch."
Phase 1's guard still applies: never open from main or dev, never with a dirty tree. Record
git rev-parse "origin/$PARENT_BRANCH" in the body; after the parent is squash-merged that sha
is the upstream argument that git rebase --onto "origin/$BASE" <that-sha> <branch> needs, and
the branch itself is gone. Squash recovery, depth cap, draft trap: Read("references/stacked-pr.md").
STEP 0: Verify User Intent
BEFORE creating tasks, clarify PR type:
AskUserQuestion(
questions=[{
"question": "What type of PR is this?",
"header": "PR Type",
"options": [
{"label": "Feature (Recommended)", "description": "Full validation: security + quality + tests"},
{"label": "Bug fix", "description": "Focus on test verification"},
{"label": "Refactor", "description": "Code quality review, skip security"},
{"label": "Quick", "description": "Skip validation, just create PR"}
],
"multiSelect": false
}]
)
Based on answer, adjust workflow:
- Feature: Full Phase 2 with 3 parallel agents + local tests
- Bug fix: Phase 2 with test-generator only + local tests
- Refactor: Phase 2 with code-quality-reviewer only + local tests
- Quick: Skip Phase 2, jump to Phase 3
Optional pre-flight: claude ultrareview (CC 2.1.120+, #1542)
If claude ultrareview --help succeeds, optionally run it before opening the PR and surface findings in the PR body's ## Pre-flight section. The CLI subcommand returns structured --json output that can be filtered to high/medium severity for the body and full results posted as a follow-up comment.
if claude ultrareview --help >/dev/null 2>&1; then
claude ultrareview "origin/$BASE..HEAD" --json > /tmp/ultra.json
# Bucket by severity, put HIGH in PR body, MEDIUM/LOW as comment
fi
Skip on CC < 2.1.120 (the subcommand doesn't exist there). The .github/workflows/ultrareview.yml workflow runs the same command on PR open as a backstop, so this pre-flight is purely a feedback-loop accelerant.
Progressive Output (CC 2.1.76)
Output results incrementally during PR creation:
| After Step | Show User |
|---|---|
| Pre-flight | Branch status, remote sync result |
| Each agent | Agent validation result as it returns |
| Tests | Test results, lint/typecheck status |
| PR created | PR URL, CI status link |
For feature PRs with 3 parallel agents, show each agent's result as it returns — don't wait for all agents before running local tests.
STEP 1: Create Tasks (MANDATORY)
BEFORE doing ANYTHING else, create tasks to track progress:
# 1. Create main task IMMEDIATELY
TaskCreate(subject="Create PR for {branch}", description="PR creation with validation", activeForm="Creating pull request")
# 2. Create subtasks for each phase
TaskCreate(subject="Pre-flight checks", activeForm="Running pre-flight checks") # id=2
TaskCreate(subject="Run validation agents", activeForm="Validating with agents") # id=3
TaskCreate(subject="Run local tests", activeForm="Running local tests") # id=4
TaskCreate(subject="Create PR on GitHub", activeForm="Creating GitHub PR") # id=5
TaskCreate(subject="Generate PR playground", activeForm="Generating playground") # id=6
# 3. Set dependencies for sequential phases
TaskUpdate(taskId="3", addBlockedBy=["2"]) # Agents need pre-flight to pass
TaskUpdate(taskId="4", addBlockedBy=["3"]) # Tests run after agent validation
TaskUpdate(taskId="5", addBlockedBy=["4"]) # PR creation needs tests to pass
TaskUpdate(taskId="6", addBlockedBy=["5"]) # Playground after PR (needs title/summary)
# 4. Update status as you progress
TaskUpdate(taskId="2", status="in_progress") # When starting
TaskUpdate(taskId="2", status="completed") # When done — repeat for each subtask
Workflow
Phase 1: Pre-Flight Checks
Load: Read("rules/preflight-validation.md") for the full checklist.
BRANCH=$(git branch --show-current)
[[ "$BRANCH" == "dev" || "$BRANCH" == "main" ]] && echo "Cannot PR from dev/main" && exit 1
[[ -n $(git status --porcelain) ]] && echo "Uncommitted changes" && exit 1
git fetch origin
git rev-parse --verify "origin/$BRANCH" &>/dev/null || git push -u origin "$BRANCH"
Phase 2: Parallel Validation (Feature/Bug fix PRs)
Launch agents in ONE message. Load Read("references/parallel-validation.md") for full agent configs.
| PR Type | Agents to launch |
|---|---|
| Feature | security-auditor + test-generator + code-quality-reviewer |
| Bug fix | test-generator only |
| Refactor | code-quality-reviewer only |
| Quick | None |
After agents complete, run local validation:
# Adapt to project stack
npm run lint && npm run typecheck && npm test -- --bail
# or: ruff check . && pytest tests/unit/ -v --tb=short -x
Phase 3: Gather Context
BRANCH=$(git branch --show-current)
ISSUE=$(echo "$BRANCH" | grep -oE '[0-9]+' | head -1)
git log --oneline "origin/$BASE..HEAD"
git diff "origin/$BASE...HEAD" --stat
Phase 3b: Agent Attribution (automatic)
Before creating the PR, check for the branch activity ledger at .claude/agents/activity/{branch}.jsonl.
If it exists, generate agent attribution sections for the PR body:
- Read
.claude/agents/activity/{branch}.jsonl(one JSON object per line, full branch history) - Deduplicate by agent type (keep the entry with longest duration for each agent)
- Generate the following sections to append to the PR body:
- Badge row: shields.io badges for agent count, tests generated, vulnerabilities
- Agent Team Sheet: Markdown table with Agent, Role, Stage (Lead/⚡ Parallel/Follow-up), Time
- Credits Roll: Collapsible
<details>section grouped by execution stage (Lead/Parallel/Follow-up)
- Each agent entry has:
agent(type),stage(0=lead, 1=parallel, 2=follow-up),duration_ms,summary
If the ledger doesn't exist or is empty, skip this step — create PR normally.
CC 2.1.183 —
attribution.sessionUrl: Web and Remote Control sessions append a claude.ai session link to the PR body. For public repos where that link should not be exposed, setattribution.sessionUrl: false(/config attribution.sessionUrl=false) before creating the PR. ork's agent-attribution sections above are independent of this setting.
Phase 3c: CodeRabbit CLI pre-review (before gh pr create)
CodeRabbit PR reviews are rate limited per GitHub identity (Essentials: 5/hour refill under 30 reviews in 7 days, 1/hour at 60+), and every push to an open PR spends one. The CLI has a separate allowance, so review the branch diff locally first. Advisory only, never blocks.
CR_BIN=$(command -v coderabbit || true) # `cr` is also helm chart-releaser: accept it only by --help
[ -z "$CR_BIN" ] && command -v cr >/dev/null 2>&1 && grep -q CodeRabbit <<<"$(cr --help 2>&1)" && CR_BIN=cr
CR_OUT=$(mktemp "${TMPDIR:-/tmp}/cr-prereview.XXXXXX")
[ -n "$CR_BIN" ] && perl -e 'alarm shift; exec @ARGV' 600 \
"$CR_BIN" review --agent --base "origin/$BASE" </dev/null > "$CR_OUT" 2>&1 \
|| echo "CodeRabbit CLI pre-review skipped (not installed, not signed in, timed out, or errored): $CR_OUT"
Fix clear defects in lines this branch changed, commit, re-run Phase 2 local validation, then go
to Phase 4 without re-running the CLI. Omitting --use-credits avoids spend only when the org's usage-based add-on is On demand or Off; Automatic bills overages.
Detection, degrade table, billing modes, triage: Read("references/coderabbit-cli-prereview.md").
Phase 4: Create PR
Follow Read("rules/pr-title-format.md") and Read("rules/pr-body-structure.md"). Use HEREDOC pattern from Read("references/pr-body-templates.md").
Include agent attribution sections (from Phase 3b) after the Test Plan section in the PR body.
TYPE="feat" # Determine: feat/fix/refactor/docs/test/chore
gh pr create --base "$BASE" \
--title "$TYPE(#$ISSUE): Brief description" \
--body "$(cat <<'EOF'
## Summary
[1-2 sentence description]
## Changes
- [Change 1]
- [Change 2]
## Test Plan
- [x] Unit tests pass
- [x] Lint/type checks pass
## Agent Team Sheet
| Agent | Role | Stage | Time |
|-------|------|-------|------|
| 🏗️ **backend-system-architect** | API design | Lead | 2m14s |
| 🛡️ **security-auditor** | Dependency audit | ⚡ Parallel | 0m42s |
| 🧪 **test-generator** | 47 tests, 94% coverage | ⚡ Parallel | 2m01s |
<details>
<summary><strong>🎬 Agent Credits</strong> — 3 agents collaborated on this PR</summary>
**Lead**
- 🏗️ **backend-system-architect** — API design (2m14s)
**⚡ Parallel** (ran simultaneously)
- 🛡️ **security-auditor** — Dependency audit (0m42s)
- 🧪 **test-generator** — 47 tests, 94% coverage (2m01s)
---
<sub>Orchestrated by <a href="https://github.com/yonatangross/orchestkit">OrchestKit</a> — 3 agents, 4m57s total</sub>
</details>
Closes #$ISSUE
---
Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
Phase 4b: PR Playground (REQUIRED, CI blocks without it)
On every non-bot PR, after Phase 4: Read("references/pr-playground.md") and follow it (archetype, commit to docs/{branch-dir}/, SHA-pinned Live Preview link in the body).
Phase 5: Verify
PR_URL=$(gh pr view --json url -q .url)
echo "PR created: $PR_URL"
CI Monitoring (CC 2.1.71)
After PR creation, schedule CI status monitoring.
Budget: 60 minutes of CI polling (a 5-minute cron, so at most 12 fires). A cron job repeats one fixed prompt and cannot count its own fires, so the prompt carries a wall-clock deadline computed once at creation; stop when every check has finished or at the deadline, whichever comes first, and CronDelete the job at either stop.
# Guard: Skip cron in headless/CI (CLAUDE_CODE_DISABLE_CRON)
# if env CLAUDE_CODE_DISABLE_CRON is set, run a single check instead
# deadline_iso = creation time + 60 minutes, in UTC, filled in ONCE here
CronCreate(
schedule="*/5 * * * *",
prompt="Check CI for PR #{pr_number}: gh pr checks {pr_number} --repo {repo}. Deadline {deadline_iso}.
All pass → CronDelete this job, report success.
Any fail → CronDelete this job, alert with failure details.
Still pending and `date -u` is at or past the deadline → CronDelete this job, report the pending checks."
)
CodeRabbit harvest
After CI is green and before gh pr merge or --auto, when the repo has .coderabbit.yaml and the PR is not a draft: Read("references/coderabbit-harvest.md").
Handoff File
Write PR details for downstream skills:
Write(".claude/chain/pr-created.json", JSON.stringify({
"phase": "create-pr", "pr_number": N, "pr_url": "...",
"branch": "...", "files_changed": [...], "related_issues": [...]
}))
Rules
- NO junk files — Don't create files in repo root
- Run validation locally — Don't spawn agents for lint/test
- All content goes to GitHub — PR body via
gh pr create --body - Keep it simple — One command to create PR
- Respect the
ghrate-limit hint (CC ≥ 2.1.116) — when the Bash tool surfaces a GitHub rate-limit hint after aghcall (e.g. in a/loop 5m gh pr checks …watcher), stop the loop and wait for reset — do not blind-retry. Seeork:github-operationsfor the full guidance.
Next Steps (suggest to user after PR creation)
review-pr {PR_NUMBER} # Self-review before requesting reviews
gh pr checks {PR_NUMBER} # one-shot status; the CI Monitoring cron polls up to its 60-minute deadline
/loop 1h gh pr view {PR_NUMBER} --json reviewDecision # Monitor review status
Verification Gate
Before claiming PR is ready, apply: Read("${CLAUDE_PLUGIN_ROOT}/shared/rules/verification-gate.md"). All tests must pass with fresh evidence. All CI checks green. No "should be fine."
Quality Bar
Done means all of these hold:
- PR opened from a feature branch with a clean working tree against the correct base (
$BASE, derived fromorigin/HEAD, or the detected host equivalent) - Title uses conventional
type(#issue): ...format matching the change - Body carries Summary, Changes, and Test Plan sections; every closed issue has its own
Closes #Nkeyword - Pre-flight validation for the chosen PR type passed locally before creation (skipped only for the Quick type)
- CodeRabbit CLI pre-review ran once before
gh pr create(Phase 3c), or its one-line skip reason is in the Test Plan - Playground HTML exists at docs/{branch-dir}/*.html and the body links it, per
references/pr-playground.md(required for non-bot PRs) gh pr view --json urlreturns the created PR URL- On repos with
.coderabbit.yamland a non-draft PR: every CodeRabbit thread is resolved perreferences/coderabbit-harvest.md, with a reply naming the fix sha or the dismissal reason (scripts/coderabbit-harvest.sh --unresolvedprints[])
Related Skills
ork:commit— Create commits before PRsork:review-pr— Review PRs after creation
Picker fallback (#1795)
If the AskUserQuestion picker stalls (schema break, not a CC input bug — orchestkit#1795, now guarded by tests/skills/structure/test-askuserquestion-schema.sh), set ORK_ASK_FALLBACK=text before starting CC. The lifecycle/ask-fallback-injector hook injects a reminder telling the assistant to pose options inline as a numbered list and ask the user to reply with the option number.
References
Load on demand with Read("references/<file>"):
| File | Content |
|---|---|
references/pr-body-templates.md |
PR body templates |
references/parallel-validation.md |
Parallel validation agent configs |
references/ci-integration.md |
CI integration patterns |
references/multi-commit-pr.md |
Multi-commit PR guidance |
assets/pr-template.md |
PR template (legacy) |
scripts/coderabbit-harvest.sh |
CodeRabbit threads: read (one GraphQL call), --reply, --resolve |
references/coderabbit-zero-reviews.md |
Harvest returned zero: reviewed clean, or never reviewed? |
references/coderabbit-cli-prereview.md |
Phase 3c: why the PR review allowance is scarce, CLI command, degrade table, triage |
references/pr-playground.md |
Phase 4b: PR playground archetype, commit path, SHA-pinned Live Preview link (CI gate) |
references/coderabbit-harvest.md |
After CI green: read, refute, fix or dismiss, resolve every CodeRabbit thread |