From e0e81f4637e26c43609b1a470628a8bdcb5a6492 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Thu, 5 Mar 2026 07:05:42 -0500 Subject: [PATCH 1/4] feat(finalize-pr): expand to support repo-wide and org-wide modes with bot PR support Adds Phase 0 (PR discovery/targeting) and Phase 5 (aggregate report) to /finalize-pr, enabling `all` (repo-wide) and `org` (org-wide) modes in addition to the existing single-PR behavior. Bot-authored PRs are included in all modes and tagged in the report. Removes the separate `finalize-prs` description from plugin.json. (claude) --- github-workflows/.claude-plugin/plugin.json | 2 +- github-workflows/README.md | 7 +- github-workflows/skills/finalize-pr/SKILL.md | 152 +++++++++++++++++-- 3 files changed, 148 insertions(+), 13 deletions(-) diff --git a/github-workflows/.claude-plugin/plugin.json b/github-workflows/.claude-plugin/plugin.json index 651e9f4..e40cb11 100644 --- a/github-workflows/.claude-plugin/plugin.json +++ b/github-workflows/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "github-workflows", "version": "1.1.0", - "description": "PR management, multi-repo PR finalization, and issue shaping with Shape Up methodology", + "description": "PR finalization (single, repo-wide, or org-wide including bots), squash-merge, review thread resolution, and issue shaping", "author": { "name": "JacobPEvans" }, diff --git a/github-workflows/README.md b/github-workflows/README.md index 1362574..1438d78 100644 --- a/github-workflows/README.md +++ b/github-workflows/README.md @@ -4,7 +4,7 @@ Claude Code plugin for PR management and issue shaping with Shape Up methodology ## Skills -- **`/finalize-pr`** - Automatically finalize pull requests for merge (CodeQL checks, CI, review threads) +- **`/finalize-pr`** - Finalize PRs for merge: single PR, all repo PRs (`all`), or all org PRs (`org`). Includes bot-authored PRs in all modes. - **`/squash-merge-pr`** - Validate PR readiness and squash merge into main (errors if not ready) - **`/resolve-pr-threads`** - Orchestrate resolution of PR review threads (requires superpowers plugin) - **`/shape-issues`** - Shape raw ideas into actionable GitHub Issues using Shape Up methodology @@ -19,7 +19,10 @@ claude plugins add jacobpevans-cc-plugins/github-workflows ## Usage ```text -/finalize-pr # Automatic PR finalization workflow +/finalize-pr # Finalize PR on current branch +/finalize-pr 42 # Finalize specific PR by number +/finalize-pr all # Finalize all open PRs in repo (including bots) +/finalize-pr org # Finalize all open PRs across org (including bots) /squash-merge-pr # Validate and squash merge /resolve-pr-threads # Batch resolve review threads /shape-issues # Shape ideas into GitHub issues diff --git a/github-workflows/skills/finalize-pr/SKILL.md b/github-workflows/skills/finalize-pr/SKILL.md index 0e3f1eb..93e2340 100644 --- a/github-workflows/skills/finalize-pr/SKILL.md +++ b/github-workflows/skills/finalize-pr/SKILL.md @@ -2,17 +2,17 @@ name: finalize-pr description: >- Automatically finalize pull requests for merge by resolving CodeQL violations, - review threads, merge conflicts, and CI failures. Assumes PR already exists. - Use when a PR needs to be prepared for merge. Handles single PR from argument - or current branch. -argument-hint: "[PR_NUMBER]" + review threads, merge conflicts, and CI failures. Handles single PR (current + branch or by number), all open PRs in the repo, or all open PRs across the org. + Includes bot-authored PRs in all modes. +argument-hint: "[PR_NUMBER | all | org]" --- # Finalize PR -**FULLY AUTOMATIC** - Finalizes YOUR PRs as author: monitor, fix, prepare for merge. Assumes PR already exists. +**FULLY AUTOMATIC** - Finalizes PRs as author: monitor, fix, prepare for merge. Assumes PR already exists. No manual intervention required. For reviewing others' PRs, use `/review-pr`. ## Critical Rules @@ -26,6 +26,81 @@ No manual intervention required. For reviewing others' PRs, use `/review-pr`. 7. **Monitor CI early, block last** - Start CI monitoring in background immediately, but fix other issues while it runs 8. **Update PR metadata automatically** - Before reporting ready, update title, description, and linked issues via haiku subagent 9. **Take direct action** - Identify issues and fix them automatically (except merge decisions) +10. **Include bot PRs** - Never filter by author. All modes include dependabot, release-please, claude, github-actions, etc. +11. **Never cross org boundaries** - Org mode derives owner from current repo only + +## Phase 0: PR Discovery and Targeting + +Parse the argument to determine mode, then discover and confirm the target set. + +### 0.1 Parse Argument + +| Argument | Mode | Target | +|---|---|---| +| _(none)_ | Current branch | Single PR on current branch | +| `42` (a number) | Single PR | PR #42 | +| `all` | Repo-wide | All open PRs in current repo | +| `org` | Org-wide | All open PRs across all repos in current org | + +### 0.2 Discover PRs + +**Single/current-branch mode**: Resolve to one PR number, then skip to Phase 1. + +```bash +# If no argument — resolve from current branch +gh pr view --json number --jq '.number' +``` + +**Repo-wide (`all`) mode**: + +```bash +gh pr list --state open --json number,title,author,headRefName +``` + +**Org-wide (`org`) mode**: + +```bash +OWNER=$(gh repo view --json owner --jq '.owner.login') +gh repo list "$OWNER" --limit 100 --json name --jq '.[].name' | \ + xargs -I{} gh pr list --repo "$OWNER/{}" --state open \ + --json number,title,author,headRefName,repository 2>/dev/null +``` + +Cap at 50 PRs. If more exist, warn the user and process only the first 50. + +### 0.3 Tag Bot PRs + +For each discovered PR, check if `author.login` matches bot patterns +(`*[bot]`, `app/*`, `dependabot`, `release-please`, `github-actions`, `claude`). +Tag these as `[bot]` in the discovery list for reporting purposes only — they are +processed identically to human-authored PRs. + +### 0.4 Confirm Batch (Multi-PR Only) + +For `all` and `org` modes, display the discovery list before proceeding: + +```text +Found N open PRs: + #42 feat: add user auth (alice) + #43 chore: bump dependencies [bot] (dependabot) + #58 fix: resolve edge case [bot] (claude) + +Proceeding to finalize all N PRs sequentially. +``` + +Check for a clean working tree before multi-PR modes: + +```bash +git status --porcelain +``` + +If the working tree is dirty, report and ask the user to commit or stash before proceeding. + +Record the current branch for restoration after each iteration: + +```bash +ORIGINAL_BRANCH=$(git branch --show-current) +``` ## Phase 1: Resolution Loop (AUTOMATIC — PARALLEL) @@ -33,6 +108,14 @@ No manual intervention required. For reviewing others' PRs, use `/review-pr`. the background FIRST, then fix all other issues in parallel while CI runs. Never block on CI when other work is available. +_For multi-PR modes, this phase and Phases 2-4 execute once per PR in sequence. +At the start of each iteration, check out the PR branch:_ + +```bash +# Multi-PR only — not needed for single/current-branch mode +gh pr checkout +``` + ### 1.1 Start CI Monitoring (BACKGROUND) Launch CI monitoring in a background Task agent (`run_in_background: true` on @@ -109,6 +192,10 @@ Verify ALL conditions automatically and proceed directly: **Only if ALL six pass**: Proceed to Phase 3 to update PR metadata. +**Multi-PR handling**: If a PR needs human intervention (unresolvable conflict, +unrecoverable CI failure, etc.), log it with reason and continue to the next PR. +Do not stop the batch for one blocked PR. + ## Phase 3: Update PR Metadata Delegate to a **haiku subagent** to keep full diff out of main context. @@ -160,9 +247,9 @@ gh pr edit --title "..." --body-file /tmp/pr-body.md Proceed to Phase 4. -## Phase 4: Report Ready Status +## Phase 4: Record Result -After verifying all conditions pass and updating PR metadata, report: +**Single/current-branch mode**: Report ready status and wait for user: ```text ✅ PR #{NUMBER} ready for final review! @@ -173,17 +260,62 @@ To merge, invoke one of: /rebase-pr # Rebase commits onto main (preserves history) ``` -Wait for explicit user merge command. +**Multi-PR mode**: Record the per-PR result (ready / blocked / needs-human). +After recording, restore the original branch and continue to the next PR: + +```bash +git switch "$ORIGINAL_BRANCH" +``` + +Do NOT emit a ready report here in multi-PR mode — that happens in Phase 5. + +## Phase 5: Aggregate Report (Multi-PR Only) + +After processing all PRs, emit a summary: + +```text +PR Finalization Summary +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + ✅ #42 feat: add user auth (alice) + ✅ #58 fix: resolve edge case [bot] (claude) + ⛔ #43 chore: bump dependencies [bot] (dependabot) — unresolvable conflict + +Ready to merge (2): + gh pr merge 42 --squash + gh pr merge 58 --squash + +Blocked — needs human (1): + #43 chore: bump dependencies — unresolvable conflict in package-lock.json +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +``` + +Wait for explicit user merge commands. ## Workflow ```text -/init-worktree → [implement] → gh pr create → /finalize-pr +Single PR: +/init-worktree → [implement] → gh pr create → /finalize-pr [number] ↓ + Phase 0: Resolve PR number Phase 1: Resolution Loop (automatic fixes) Phase 2: Pre-Handoff Verification - Phase 3: Update PR Metadata (title, description, linked issues) + Phase 3: Update PR Metadata Phase 4: Report ready (wait for user) ↓ User invokes: /squash-merge-pr or /rebase-pr + +Repo-wide: +/finalize-pr all + ↓ +Phase 0: Discover all open PRs (including bots), confirm batch +Phase 1-4: Loop over each PR sequentially +Phase 5: Aggregate report with merge commands for ready PRs + +Org-wide: +/finalize-pr org + ↓ +Phase 0: Derive org owner, enumerate repos, collect all open PRs +Phase 1-4: Loop over each PR sequentially +Phase 5: Aggregate report with merge commands for ready PRs ``` From a5c9a2282848f8a904840bf51c34c95ea9ae52b2 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Thu, 5 Mar 2026 07:20:49 -0500 Subject: [PATCH 2/4] fix(finalize-pr): address review feedback on numbering, org-wide correctness, and bot detection - Renumber phases starting from 1 (Phase 0 removed per conventions) - Add explicit sequential/parallel labels to all child step groups - Reword intro to remove author-only implication (copilot) - Add --limit 50 to repo-wide gh pr list (copilot) - Replace xargs+2>/dev/null with while-read+warning for org-wide discovery (gemini, copilot, greptile) - Merge per-repo JSON arrays with jq -s flatten and combine into single jq call (greptile, simplify) - Fix bot detection to use [bot] suffix pattern instead of glob/allowlist (copilot) - Add --repo to gh pr checkout for org-wide mode (greptile) - Add --repo to Phase 6 merge commands for org-wide mode (greptile) (claude) --- github-workflows/skills/finalize-pr/SKILL.md | 138 +++++++++++-------- 1 file changed, 79 insertions(+), 59 deletions(-) diff --git a/github-workflows/skills/finalize-pr/SKILL.md b/github-workflows/skills/finalize-pr/SKILL.md index 93e2340..578ea20 100644 --- a/github-workflows/skills/finalize-pr/SKILL.md +++ b/github-workflows/skills/finalize-pr/SKILL.md @@ -12,8 +12,8 @@ argument-hint: "[PR_NUMBER | all | org]" # Finalize PR -**FULLY AUTOMATIC** - Finalizes PRs as author: monitor, fix, prepare for merge. Assumes PR already exists. -No manual intervention required. For reviewing others' PRs, use `/review-pr`. +**FULLY AUTOMATIC** - Fully automates PR finalization: monitor, fix, prepare for merge. Assumes PR already exists. +No manual intervention required. For manual review-focused workflows, use `/review-pr`. ## Critical Rules @@ -29,11 +29,12 @@ No manual intervention required. For reviewing others' PRs, use `/review-pr`. 10. **Include bot PRs** - Never filter by author. All modes include dependabot, release-please, claude, github-actions, etc. 11. **Never cross org boundaries** - Org mode derives owner from current repo only -## Phase 0: PR Discovery and Targeting +## Phase 1: PR Discovery and Targeting Parse the argument to determine mode, then discover and confirm the target set. +Steps 1.1 through 1.4 run sequentially. -### 0.1 Parse Argument +### 1.1 Parse Argument | Argument | Mode | Target | |---|---|---| @@ -42,9 +43,9 @@ Parse the argument to determine mode, then discover and confirm the target set. | `all` | Repo-wide | All open PRs in current repo | | `org` | Org-wide | All open PRs across all repos in current org | -### 0.2 Discover PRs +### 1.2 Discover PRs -**Single/current-branch mode**: Resolve to one PR number, then skip to Phase 1. +**Single/current-branch mode**: Resolve to one PR number, then skip to Phase 2. ```bash # If no argument — resolve from current branch @@ -54,36 +55,44 @@ gh pr view --json number --jq '.number' **Repo-wide (`all`) mode**: ```bash -gh pr list --state open --json number,title,author,headRefName +gh pr list --state open --limit 50 --json number,title,author,headRefName ``` -**Org-wide (`org`) mode**: +**Org-wide (`org`) mode**: Each `gh pr list` call outputs a separate JSON array. +Use `jq -s` to merge them. If a repo cannot be listed, emit a warning and continue. ```bash OWNER=$(gh repo view --json owner --jq '.owner.login') gh repo list "$OWNER" --limit 100 --json name --jq '.[].name' | \ - xargs -I{} gh pr list --repo "$OWNER/{}" --state open \ - --json number,title,author,headRefName,repository 2>/dev/null + while read -r REPO_NAME; do + if ! out=$(gh pr list --repo "$OWNER/$REPO_NAME" --state open \ + --limit 50 \ + --json number,title,author,headRefName,repository); then + echo "Warning: unable to list PRs for $OWNER/$REPO_NAME" >&2 + else + echo "$out" + fi + done | jq -s 'flatten | sort_by(.number) | .[0:50]' ``` Cap at 50 PRs. If more exist, warn the user and process only the first 50. -### 0.3 Tag Bot PRs +### 1.3 Tag Bot PRs -For each discovered PR, check if `author.login` matches bot patterns -(`*[bot]`, `app/*`, `dependabot`, `release-please`, `github-actions`, `claude`). +For each discovered PR, check if `author.login` ends with `[bot]` +(e.g., `dependabot[bot]`, `github-actions[bot]`, `claude[bot]`). Tag these as `[bot]` in the discovery list for reporting purposes only — they are processed identically to human-authored PRs. -### 0.4 Confirm Batch (Multi-PR Only) +### 1.4 Confirm Batch (Multi-PR Only) For `all` and `org` modes, display the discovery list before proceeding: ```text Found N open PRs: #42 feat: add user auth (alice) - #43 chore: bump dependencies [bot] (dependabot) - #58 fix: resolve edge case [bot] (claude) + #43 chore: bump dependencies [bot] (dependabot[bot]) + #58 fix: resolve edge case [bot] (claude[bot]) Proceeding to finalize all N PRs sequentially. ``` @@ -102,21 +111,28 @@ Record the current branch for restoration after each iteration: ORIGINAL_BRANCH=$(git branch --show-current) ``` -## Phase 1: Resolution Loop (AUTOMATIC — PARALLEL) +## Phase 2: Resolution Loop (AUTOMATIC) **Execution strategy**: CI checks take 10+ minutes. Start monitoring them in the background FIRST, then fix all other issues in parallel while CI runs. Never block on CI when other work is available. -_For multi-PR modes, this phase and Phases 2-4 execute once per PR in sequence. -At the start of each iteration, check out the PR branch:_ +_For multi-PR modes, Phases 2-5 execute once per PR in sequence. +At the start of each iteration, check out the PR branch. +For repo-wide mode (all PRs in the same repo), the bare number suffices. +For org-wide mode, include `--repo` because PRs may belong to other repos:_ ```bash -# Multi-PR only — not needed for single/current-branch mode +# Repo-wide mode gh pr checkout + +# Org-wide mode — use the repository field from Phase 1 discovery +gh pr checkout --repo "/" ``` -### 1.1 Start CI Monitoring (BACKGROUND) +Steps 2.1 and 2.2 start concurrently (2.1 is non-blocking). Steps 2.3 and 2.4 run sequentially after 2.2. + +### 2.1 Start CI Monitoring (BACKGROUND) Launch CI monitoring in a background Task agent (`run_in_background: true` on the Task tool). The agent runs this blocking command in its own context: @@ -125,10 +141,10 @@ the Task tool). The agent runs this blocking command in its own context: gh pr checks --watch ``` -Do NOT wait for the Task to complete — proceed to 1.2 immediately. Check the -background task's output after completing other fixes in 1.2. +Do NOT wait for the Task to complete — proceed to 2.2 immediately. Check the +background task's output after completing other fixes in 2.2. -### 1.2 Parallel Fixes +### 2.2 Parallel Fixes Run these checks simultaneously. Launch independent fixes in parallel via Task agents when they touch different files. Invoke `superpowers:dispatching-parallel-agents` for dispatch patterns. @@ -160,16 +176,16 @@ gh pr view --json mergeable **If conflicts**: Fetch main, attempt merge, report unresolvable conflicts for user. After resolution, invoke /simplify and validate locally. -### 1.3 CI Failure Fixes +### 2.3 CI Failure Fixes -Check background CI results from 1.1: +Check background CI results from 2.1: -- **All passing**: Proceed to Phase 2 +- **All passing**: Proceed to Phase 3 - **Failures**: Get logs via `gh run view --log-failed`, fix locally, invoke /simplify, validate, commit and push. Restart background CI - monitoring and loop back to 1.2 if new issues emerged. + monitoring and loop back to 2.2 if new issues emerged. -### 1.4 Health Check +### 2.4 Health Check Verify final PR status after all fixes: @@ -177,9 +193,9 @@ Verify final PR status after all fixes: gh pr view --json state,mergeable,statusCheckRollup ``` -If fixes introduced new issues, loop back to 1.2. +If fixes introduced new issues, loop back to 2.2. -## Phase 2: Pre-Handoff Verification +## Phase 3: Pre-Handoff Verification Verify ALL conditions automatically and proceed directly: @@ -190,18 +206,18 @@ Verify ALL conditions automatically and proceed directly: 5. ✅ **All checks pass**: `gh pr checks ` all green 6. ✅ **Local validation**: Project linters pass -**Only if ALL six pass**: Proceed to Phase 3 to update PR metadata. +**Only if ALL six pass**: Proceed to Phase 4 to update PR metadata. **Multi-PR handling**: If a PR needs human intervention (unresolvable conflict, unrecoverable CI failure, etc.), log it with reason and continue to the next PR. Do not stop the batch for one blocked PR. -## Phase 3: Update PR Metadata +## Phase 4: Update PR Metadata Delegate to a **haiku subagent** to keep full diff out of main context. -Sub-steps 3.1 and 3.2 can run in parallel within the agent. +Steps 4.1 and 4.2 can run in parallel within the agent. Step 4.3 runs after both. -### 3.1 Update PR Title and Description +### 4.1 Update PR Title and Description 1. Run compact summary commands: @@ -220,7 +236,7 @@ Sub-steps 3.1 and 3.2 can run in parallel within the agent. 3. Generate updated title (conventional commit format, <70 chars) and description with sections: **Summary**, **Changes**, **Test Plan**. -### 3.2 Link Related Issues and PRs +### 4.2 Link Related Issues and PRs 1. Extract keywords from branch name and commit messages. 2. Search for related items: @@ -233,9 +249,9 @@ Sub-steps 3.1 and 3.2 can run in parallel within the agent. 3. Add `Closes #X` (directly related issues) or `Related: #X` (adjacent PRs) to description. Only link clearly related items — no guessing. -### 3.3 Apply Updates +### 4.3 Apply Updates -After 3.1 and 3.2 complete, apply using a multiline-safe pattern: +After 4.1 and 4.2 complete, apply using a multiline-safe pattern: ```bash cat <<'EOF' > /tmp/pr-body.md @@ -245,9 +261,9 @@ EOF gh pr edit --title "..." --body-file /tmp/pr-body.md ``` -Proceed to Phase 4. +Proceed to Phase 5. -## Phase 4: Record Result +## Phase 5: Record Result **Single/current-branch mode**: Report ready status and wait for user: @@ -267,28 +283,32 @@ After recording, restore the original branch and continue to the next PR: git switch "$ORIGINAL_BRANCH" ``` -Do NOT emit a ready report here in multi-PR mode — that happens in Phase 5. +Do NOT emit a ready report here in multi-PR mode — that happens in Phase 6. -## Phase 5: Aggregate Report (Multi-PR Only) +## Phase 6: Aggregate Report (Multi-PR Only) -After processing all PRs, emit a summary: +After processing all PRs, emit a summary. +For org-wide mode, include `--repo` in merge commands since PR numbers are +scoped per-repository and the current repo may differ from the PR's repo. ```text PR Finalization Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ✅ #42 feat: add user auth (alice) - ✅ #58 fix: resolve edge case [bot] (claude) - ⛔ #43 chore: bump dependencies [bot] (dependabot) — unresolvable conflict + ✅ #42 feat: add user auth (alice) [owner/repo] + ✅ #58 fix: resolve edge case [bot] (claude[bot]) [owner/repo] + ⛔ #43 chore: bump dependencies [bot] (dependabot[bot]) — unresolvable conflict Ready to merge (2): - gh pr merge 42 --squash - gh pr merge 58 --squash + gh pr merge 42 --squash --repo owner/repo + gh pr merge 58 --squash --repo owner/repo Blocked — needs human (1): #43 chore: bump dependencies — unresolvable conflict in package-lock.json ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` +For repo-wide (`all`) mode, `--repo` may be omitted from merge commands since all PRs share the current repo. + Wait for explicit user merge commands. ## Workflow @@ -297,25 +317,25 @@ Wait for explicit user merge commands. Single PR: /init-worktree → [implement] → gh pr create → /finalize-pr [number] ↓ - Phase 0: Resolve PR number - Phase 1: Resolution Loop (automatic fixes) - Phase 2: Pre-Handoff Verification - Phase 3: Update PR Metadata - Phase 4: Report ready (wait for user) + Phase 1: Resolve PR number + Phase 2: Resolution Loop (automatic fixes) + Phase 3: Pre-Handoff Verification + Phase 4: Update PR Metadata + Phase 5: Report ready (wait for user) ↓ User invokes: /squash-merge-pr or /rebase-pr Repo-wide: /finalize-pr all ↓ -Phase 0: Discover all open PRs (including bots), confirm batch -Phase 1-4: Loop over each PR sequentially -Phase 5: Aggregate report with merge commands for ready PRs +Phase 1: Discover all open PRs (including bots), confirm batch +Phases 2-5: Loop over each PR sequentially +Phase 6: Aggregate report with merge commands for ready PRs Org-wide: /finalize-pr org ↓ -Phase 0: Derive org owner, enumerate repos, collect all open PRs -Phase 1-4: Loop over each PR sequentially -Phase 5: Aggregate report with merge commands for ready PRs +Phase 1: Derive org owner, enumerate repos, collect and merge all open PRs +Phases 2-5: Loop over each PR sequentially +Phase 6: Aggregate report with --repo-qualified merge commands for ready PRs ``` From 9fee936fcb90a2380548e586839586321361dbb6 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Thu, 5 Mar 2026 07:25:40 -0500 Subject: [PATCH 3/4] chore(finalize-pr): simplify review fixes and bump plugin to 1.2.0 - Add repository.nameWithOwner extraction note for org-wide checkout loop - Fix Phase 6 report: add [owner/repo] to blocked PR entry for consistency - Bump github-workflows plugin version 1.1.0 -> 1.2.0 (new multi-PR modes) (claude) --- github-workflows/.claude-plugin/plugin.json | 2 +- github-workflows/skills/finalize-pr/SKILL.md | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/github-workflows/.claude-plugin/plugin.json b/github-workflows/.claude-plugin/plugin.json index e40cb11..d825dc9 100644 --- a/github-workflows/.claude-plugin/plugin.json +++ b/github-workflows/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-workflows", - "version": "1.1.0", + "version": "1.2.0", "description": "PR finalization (single, repo-wide, or org-wide including bots), squash-merge, review thread resolution, and issue shaping", "author": { "name": "JacobPEvans" diff --git a/github-workflows/skills/finalize-pr/SKILL.md b/github-workflows/skills/finalize-pr/SKILL.md index 578ea20..841c456 100644 --- a/github-workflows/skills/finalize-pr/SKILL.md +++ b/github-workflows/skills/finalize-pr/SKILL.md @@ -120,14 +120,15 @@ Never block on CI when other work is available. _For multi-PR modes, Phases 2-5 execute once per PR in sequence. At the start of each iteration, check out the PR branch. For repo-wide mode (all PRs in the same repo), the bare number suffices. -For org-wide mode, include `--repo` because PRs may belong to other repos:_ +For org-wide mode, each PR object from Phase 1 carries a `repository` field +(`repository.nameWithOwner`); extract and pass it as `--repo`:_ ```bash # Repo-wide mode gh pr checkout -# Org-wide mode — use the repository field from Phase 1 discovery -gh pr checkout --repo "/" +# Org-wide mode — extract repository.nameWithOwner from Phase 1 discovery JSON +gh pr checkout --repo "" ``` Steps 2.1 and 2.2 start concurrently (2.1 is non-blocking). Steps 2.3 and 2.4 run sequentially after 2.2. @@ -296,7 +297,7 @@ PR Finalization Summary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ #42 feat: add user auth (alice) [owner/repo] ✅ #58 fix: resolve edge case [bot] (claude[bot]) [owner/repo] - ⛔ #43 chore: bump dependencies [bot] (dependabot[bot]) — unresolvable conflict + ⛔ #43 chore: bump dependencies [bot] (dependabot[bot]) [owner/repo] — unresolvable conflict Ready to merge (2): gh pr merge 42 --squash --repo owner/repo From ddfdae4b18b14219870a096eae7398c2b86993c8 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Thu, 5 Mar 2026 07:58:22 -0500 Subject: [PATCH 4/4] docs(agents): add skill authoring guidance; remove trivial bash from finalize-pr Add "Skill and Command Authoring" section to AGENTS.md explaining that skill files should describe what to accomplish in prose, reserving code blocks for non-obvious things (GraphQL, API endpoints, complex jq, output formats). Apply this principle to finalize-pr/SKILL.md by replacing ~60 lines of trivial bash blocks with clear prose descriptions throughout all phases. Retains only the non-obvious code-scanning alerts API call as a code block. (claude) --- AGENTS.md | 37 +++++ github-workflows/skills/finalize-pr/SKILL.md | 163 ++++--------------- 2 files changed, 70 insertions(+), 130 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 595e9c8..899bcc8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -141,6 +141,43 @@ It must always be clear whether child phases/steps can run in parallel or not. B sub-steps are assumed to be sequential. If they can run in parallel, this should be explicitly stated (e.g., "Steps 3.1 and 3.2 can be run in parallel."). +### Skill and Command Authoring + +Skill files should describe **what** to accomplish and any non-obvious constraints — let the AI +determine the implementation. + +**Do** state goals, required field names, important flags, and API paths in prose. +**Do** use `text` blocks to show expected output formats so the AI knows what to produce. +**Do** use code blocks for GraphQL mutations, non-obvious API endpoints, or complex queries that +cannot be reasonably inferred. + +**Why this matters**: Spelling out trivial bash trains the AI to reach for shell scripts even when +native tools (Read, Edit, Glob, Write) are faster and safer. Prose-based instructions let AIs choose +the most appropriate tool and improve their approach as capabilities grow. + +Prefer: + +> List all open PRs (limit 50) with number, title, author, and headRefName. + +Over: + +```bash +gh pr list --state open --limit 50 --json number,title,author,headRefName +``` + +Prefer: + +> Verify the working tree is clean before proceeding. + +Over: + +```bash +git status --porcelain +``` + +Reserve code blocks for non-obvious things: GraphQL mutations, specific API endpoint paths, complex +jq pipelines, and expected output formats. + ### Hook Implementation Language Selection Choose the implementation language based on complexity: diff --git a/github-workflows/skills/finalize-pr/SKILL.md b/github-workflows/skills/finalize-pr/SKILL.md index 841c456..462bcc7 100644 --- a/github-workflows/skills/finalize-pr/SKILL.md +++ b/github-workflows/skills/finalize-pr/SKILL.md @@ -45,37 +45,13 @@ Steps 1.1 through 1.4 run sequentially. ### 1.2 Discover PRs -**Single/current-branch mode**: Resolve to one PR number, then skip to Phase 2. +**Single/current-branch mode**: Resolve the PR number from the current branch, then skip to Phase 2. -```bash -# If no argument — resolve from current branch -gh pr view --json number --jq '.number' -``` - -**Repo-wide (`all`) mode**: - -```bash -gh pr list --state open --limit 50 --json number,title,author,headRefName -``` +**Repo-wide (`all`) mode**: List all open PRs (limit 50) with number, title, author, and headRefName. -**Org-wide (`org`) mode**: Each `gh pr list` call outputs a separate JSON array. -Use `jq -s` to merge them. If a repo cannot be listed, emit a warning and continue. - -```bash -OWNER=$(gh repo view --json owner --jq '.owner.login') -gh repo list "$OWNER" --limit 100 --json name --jq '.[].name' | \ - while read -r REPO_NAME; do - if ! out=$(gh pr list --repo "$OWNER/$REPO_NAME" --state open \ - --limit 50 \ - --json number,title,author,headRefName,repository); then - echo "Warning: unable to list PRs for $OWNER/$REPO_NAME" >&2 - else - echo "$out" - fi - done | jq -s 'flatten | sort_by(.number) | .[0:50]' -``` - -Cap at 50 PRs. If more exist, warn the user and process only the first 50. +**Org-wide (`org`) mode**: Enumerate all repos in the org, then for each repo list open PRs (limit 50 +per repo) including the `repository` field (needed for checkout and merge commands). Merge all results +sorted by PR number, capped at 50 total. Emit a warning and continue if any repo cannot be listed. ### 1.3 Tag Bot PRs @@ -97,19 +73,8 @@ Found N open PRs: Proceeding to finalize all N PRs sequentially. ``` -Check for a clean working tree before multi-PR modes: - -```bash -git status --porcelain -``` - -If the working tree is dirty, report and ask the user to commit or stash before proceeding. - -Record the current branch for restoration after each iteration: - -```bash -ORIGINAL_BRANCH=$(git branch --show-current) -``` +Verify the working tree is clean before proceeding. If dirty, report and ask the user to commit or +stash. Note the current branch for restoration after each PR iteration. ## Phase 2: Resolution Loop (AUTOMATIC) @@ -117,33 +82,18 @@ ORIGINAL_BRANCH=$(git branch --show-current) the background FIRST, then fix all other issues in parallel while CI runs. Never block on CI when other work is available. -_For multi-PR modes, Phases 2-5 execute once per PR in sequence. -At the start of each iteration, check out the PR branch. -For repo-wide mode (all PRs in the same repo), the bare number suffices. -For org-wide mode, each PR object from Phase 1 carries a `repository` field -(`repository.nameWithOwner`); extract and pass it as `--repo`:_ - -```bash -# Repo-wide mode -gh pr checkout - -# Org-wide mode — extract repository.nameWithOwner from Phase 1 discovery JSON -gh pr checkout --repo "" -``` +_For multi-PR modes, Phases 2-5 execute once per PR in sequence. Check out each PR branch at the +start of each iteration. For org-wide mode, use `repository.nameWithOwner` from Phase 1 as the +`--repo` argument when checking out._ Steps 2.1 and 2.2 start concurrently (2.1 is non-blocking). Steps 2.3 and 2.4 run sequentially after 2.2. ### 2.1 Start CI Monitoring (BACKGROUND) -Launch CI monitoring in a background Task agent (`run_in_background: true` on -the Task tool). The agent runs this blocking command in its own context: - -```bash -gh pr checks --watch -``` +Launch CI monitoring in a background Task agent (`run_in_background: true` on the Task tool). +Monitor CI checks using `--watch` so the agent blocks until all complete. -Do NOT wait for the Task to complete — proceed to 2.2 immediately. Check the -background task's output after completing other fixes in 2.2. +Do NOT wait for the agent to finish — proceed to 2.2 immediately. ### 2.2 Parallel Fixes @@ -152,16 +102,14 @@ Task agents when they touch different files. Invoke `superpowers:dispatching-par #### CodeQL Violations -```bash -OWNER=${OWNER:-$(gh repo view --json owner --jq '.owner.login')} -REPO=${REPO:-$(gh repo view --json name --jq '.name')} +Check for open code-scanning alerts: +```bash gh api repos/${OWNER}/${REPO}/code-scanning/alerts --paginate \ --jq '[.[] | select(.state == "open")] | length' ``` -**If violations found**: Invoke `/resolve-codeql fix`, then /simplify, -validate locally. +**If violations found**: Invoke `/resolve-codeql fix`, then /simplify, validate locally. #### Review Threads @@ -170,31 +118,20 @@ After completion, invoke /simplify and validate locally. #### Merge Conflicts -```bash -gh pr view --json mergeable -``` - -**If conflicts**: Fetch main, attempt merge, report unresolvable conflicts for -user. After resolution, invoke /simplify and validate locally. +Check if the PR is mergeable. **If conflicts**: Fetch main, attempt merge, report unresolvable +conflicts for user. After resolution, invoke /simplify and validate locally. ### 2.3 CI Failure Fixes Check background CI results from 2.1: - **All passing**: Proceed to Phase 3 -- **Failures**: Get logs via `gh run view --log-failed`, fix locally, - invoke /simplify, validate, commit and push. Restart background CI - monitoring and loop back to 2.2 if new issues emerged. +- **Failures**: Fetch failed run logs, fix locally, invoke /simplify, validate, commit and push. + Restart background CI monitoring and loop back to 2.2 if new issues emerged. ### 2.4 Health Check -Verify final PR status after all fixes: - -```bash -gh pr view --json state,mergeable,statusCheckRollup -``` - -If fixes introduced new issues, loop back to 2.2. +Verify final PR state, mergeability, and check status. If fixes introduced new issues, loop back to 2.2. ## Phase 3: Pre-Handoff Verification @@ -220,47 +157,20 @@ Steps 4.1 and 4.2 can run in parallel within the agent. Step 4.3 runs after both ### 4.1 Update PR Title and Description -1. Run compact summary commands: - - ```bash - git fetch origin main - git log --oneline origin/main..HEAD - git diff --stat origin/main...HEAD - ``` - -2. Read current PR title and body: - - ```bash - gh pr view --json title,body - ``` - -3. Generate updated title (conventional commit format, <70 chars) and - description with sections: **Summary**, **Changes**, **Test Plan**. +1. Summarize branch history and diff stats against main; read current PR title and body. +2. Generate updated title (conventional commit format, <70 chars) and description with sections: + **Summary**, **Changes**, **Test Plan**. ### 4.2 Link Related Issues and PRs 1. Extract keywords from branch name and commit messages. -2. Search for related items: - - ```bash - gh issue list --search "" --json number,title --limit 5 - gh pr list --search "" --json number,title --limit 5 - ``` - -3. Add `Closes #X` (directly related issues) or `Related: #X` (adjacent PRs) - to description. Only link clearly related items — no guessing. +2. Search GitHub issues and PRs for related items (limit 5 each). +3. Add `Closes #X` (directly related issues) or `Related: #X` (adjacent PRs) — no guessing. ### 4.3 Apply Updates -After 4.1 and 4.2 complete, apply using a multiline-safe pattern: - -```bash -cat <<'EOF' > /tmp/pr-body.md -... -EOF - -gh pr edit --title "..." --body-file /tmp/pr-body.md -``` +After 4.1 and 4.2 complete, write the body to a temp file and apply with `gh pr edit --body-file` +(safer than inline for multiline content). Proceed to Phase 5. @@ -277,20 +187,13 @@ To merge, invoke one of: /rebase-pr # Rebase commits onto main (preserves history) ``` -**Multi-PR mode**: Record the per-PR result (ready / blocked / needs-human). -After recording, restore the original branch and continue to the next PR: - -```bash -git switch "$ORIGINAL_BRANCH" -``` - -Do NOT emit a ready report here in multi-PR mode — that happens in Phase 6. +**Multi-PR mode**: Record the per-PR result (ready / blocked / needs-human). Restore the original +branch and continue to the next PR. Do NOT emit a ready report — that happens in Phase 6. ## Phase 6: Aggregate Report (Multi-PR Only) -After processing all PRs, emit a summary. -For org-wide mode, include `--repo` in merge commands since PR numbers are -scoped per-repository and the current repo may differ from the PR's repo. +After processing all PRs, emit a summary. For org-wide mode, merge commands must include `--repo` +since PR numbers are scoped per-repository; use `repository.nameWithOwner` from Phase 1 discovery. ```text PR Finalization Summary @@ -308,7 +211,7 @@ Blocked — needs human (1): ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` -For repo-wide (`all`) mode, `--repo` may be omitted from merge commands since all PRs share the current repo. +For repo-wide (`all`) mode, `--repo` may be omitted since all PRs share the current repo. Wait for explicit user merge commands.