Creates a pull request from current changes, monitors GitHub CI, and debugs any failures until CI passes. Activate when the user says "create pr", "make a pr", "open pull request", "submit pr", "pr for these changes", or wants to get their current work into a reviewable PR. Assumes the project uses git, is hosted on GitHub, and has GitHub Actions CI with automated checks (lint, build, tests, etc.). Does NOT merge - stops when CI passes and provides the PR link.
[Main Task] "Create PR: [branch-name]"
└── [CI Task] "CI Run #1" (status: failed, reason: lint)
└── [Fix Task] "Fix: lint"
└── [CI Task] "CI Run #2" (status: failed, reason: test failures)
└── [Fix Task] "Fix: test failures"
└── [CI Task] "CI Run #3" (status: passed)
--reviewer argument in the user's message. If present, store the value for use in Step 5. It may be a GitHub handle (@username) or a name (Jane Doe).TaskCreate:
- subject: "Create PR: [branch-name or 'pending']"
- description: "Create pull request from current changes."
- activeForm: "Checking git status"
TaskUpdate:
- taskId: [pr task ID]
- status: "in_progress"
git status
git diff --stat
# Detect the default branch (main, master, develop, etc.)
gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
git log --oneline <base-branch>..HEAD
gh pr view 2>/dev/null
| State | Next Step |
|---|---|
| On base branch with uncommitted changes | Step 2 (create branch) |
| On feature branch with uncommitted changes | Step 3 (commit) |
| On feature branch with commits, nothing uncommitted | Step 4 (sync) |
| PR already exists for this branch | Inform user, ask whether to update or monitor CI |
| No changes anywhere | Inform user "No changes detected. Nothing to do." and stop |
TaskUpdate:
- taskId: [pr task ID]
- subject: "Create PR: [actual-branch-name]"
- metadata: {"branch": "[branch-name]", "baseBranch": "[base-branch]"}
git checkout -b <descriptive-branch-name>
feat/short-description for featuresfix/short-description for bug fixesrefactor/short-description for refactoringdocs/short-description for documentationgit add -A:git status
git add <file1> <file2> ...
git diff --cached --stat
git commit -m "$(cat <<'EOF'
<type>: <short summary>
<optional longer description>
EOF
)"
feat:, fix:, refactor:, docs:, test:, chore:.git fetch origin
git log --oneline HEAD..origin/<base-branch> | head -20
AskUserQuestion:git log --oneline <base-branch>..HEAD
git diff <base-branch>...HEAD --stat
Closes #45), then a structured description:[issue references: Fixes #...]
## Summary
<summary>
## Verification
<how to verify>
AskUserQuestion to show the user the proposed PR title and body. Also include a reviewer question in this same interaction:--reviewer was provided, resolve and confirm the GitHub handle (see below), then show it as part of the preview.AskUserQuestion call whether they want to request a review from anyone (free-text, optional).@, not clearly a username), look up the correct handle from collaborators with push access:scripts/find-collaborator.sh {owner}/{repo} "<name>"
TaskUpdate:
- taskId: [pr task ID]
- metadata: {"reviewer": "<github-handle>"}
plannotator-annotate skill is available, write the PR draft to a temporary file and use the skill to request feedback from the user on the title, body, and reviewer.AskUserQuestion call to confirm before moving forward.Here's what I'll do next:
- Run local checks (if available for this project)
- Push the branch to origin
- Create the PR as a draft with the approved title and body
- Monitor CI and fix any failures
- Publish the PR (remove draft status) once CI passes
- Request a review from
@<reviewer>(if applicable)I'll auto-fix small issues (formatting, lint, type errors, test failures). If anything bigger comes up, I'll check with you first.
AskUserQuestion to confirm before proceeding to Step 6.package.json (scripts), Makefile, pyproject.toml, DESCRIPTION, Justfile, Taskfile.yml, etc..github/workflows/ to understand what CI will runnpm run lint, ruff check, air format, biome check, etc.npm run build, pip install -e ., devtools::check(), etc.npm run check-types, mypy, pyright, etc.npm test, pytest, devtools::test(), cargo test, etc.prettier, black, air)git add -A)AskUserQuestion to present the issue and offer resolution optionsgit push -u origin <branch-name>
gh pr create --draft --title "<approved-title>" --body "$(cat <<'EOF'
<approved-body>
EOF
)"
TaskUpdate:
- taskId: [pr task ID]
- metadata: {"prUrl": "<url>", "prNumber": <N>, "prTitle": "<title>", "commits": <count>}
TaskCreate:
- subject: "CI Run #[N]: monitoring"
- description: "Monitoring CI run for PR #[number]"
- activeForm: "Monitoring CI Run #[N]"
TaskUpdate:
- taskId: [ci task ID]
- addBlockedBy: [pr task ID]
- status: "in_progress"
# List workflow runs for this PR
gh run list --branch <branch-name> --limit 5
# Watch a specific run silently until completion
# --exit-status returns exit code 0 on success, non-zero on failure
gh run watch <run-id> --exit-status > /dev/null 2>&1
echo "Exit: $?"
# Or check status without blocking
gh run view <run-id>
gh run watch without redirecting output. It generates thousands of lines of repeated status updates. Always redirect to /dev/null and rely on the exit code.TaskUpdate:
- taskId: [ci task ID]
- metadata: {"runId": "[run-id]", "status": "running"}
TaskUpdate:
- taskId: [ci task ID]
- subject: "CI Run #[N]: passed"
- status: "completed"
- metadata: {"status": "passed"}
gh pr ready <pr-number>
gh pr edit <pr-number> --add-reviewer <github-handle>
TaskUpdate:
- taskId: [ci task ID]
- subject: "CI Run #[N]: failed"
- status: "completed"
- metadata: {"status": "failed", "failureReason": "[brief reason]"}
--log-failed can produce thousands of lines. Use a targeted approach:# Summary of which jobs/steps failed
gh run view <run-id>
# Failed logs, limited to the last 40 lines (where the error usually is)
gh run view <run-id> --log-failed 2>&1 | tail -40
# Search for specific errors if needed
gh run view <run-id> --log-failed 2>&1 | grep -A 5 -B 5 "error\|Error\|FAIL\|failed"
TaskCreate:
- subject: "Fix: [failure reason]"
- description: "Fixing CI failure from Run #[N]: [detailed error]"
- activeForm: "Fixing [failure reason]"
TaskUpdate:
- taskId: [fix task ID]
- addBlockedBy: [ci task ID]
- status: "in_progress"
git add <specific-files>
git commit -m "$(cat <<'EOF'
fix: <what was fixed>
EOF
)"
git push
TaskUpdate:
- taskId: [fix task ID]
- status: "completed"
TaskList to gather all CI run and fix tasks, then generate the summary:## PR Ready for Review
**PR:** [#<number> <title>](<url>)
**Branch:** `<branch-name>` -> `<base-branch>`
**Commits:** <count>
**CI Status:** All checks passed
**Reviewer:** @<handle> (if requested)
### CI Runs
- Run #1: Failed (lint) -> Fixed in [hash]
- Run #2: Passed
**Note:** This PR has NOT been merged. Please review and merge manually.
TaskList shows:
├── PR task in_progress, no CI tasks
│ └── PR was created, start monitoring CI (Step 9)
├── PR task in_progress, CI task in_progress
│ └── Resume monitoring CI run from task metadata runId
├── PR task in_progress, CI task failed, no fix task
│ └── Analyze failure and create fix task (Step 10)
├── PR task in_progress, fix task in_progress
│ └── Continue fixing, then push and monitor new CI run
├── PR task completed
│ └── PR is done, show final report
└── No tasks exist
└── Fresh start (Step 1)
gh run view <runId> from CI task metadata to check if the run is still active, completed, or superseded. Inform the user of the current state before resuming.git add -A or git add .gh pr create --draft; publish with gh pr ready only after CI passesgh commands fail with auth errors, inform the user to run gh auth login.