|
| 1 | +--- |
| 2 | +name: cursor-bugbot |
| 3 | +description: Drive the Cursor Bugbot review-and-fix loop on a PR. Inventories open Bugbot threads, classifies each (real bug / false positive / already fixed), fixes the real ones, replies on the inline thread (never as a detached PR comment), updates the PR title/body if scope shifted, and pushes. Use when reviewing a PR you just authored, after `gh pr create`, or after a new Bugbot pass on an existing PR. |
| 4 | +user-invocable: true |
| 5 | +allowed-tools: Read, Edit, Write, Grep, Glob, AskUserQuestion, Bash(gh:*), Bash(git:*), Bash(pnpm run:*), Bash(rg:*), Bash(grep:*) |
| 6 | +--- |
| 7 | + |
| 8 | +# cursor-bugbot |
| 9 | + |
| 10 | +Drive the Cursor Bugbot fix-and-respond loop end-to-end. This is the canonical flow every PR author should run after Bugbot posts findings. |
| 11 | + |
| 12 | +## Modes |
| 13 | + |
| 14 | +- `/cursor-bugbot <PR#>` — full audit-and-fix on one PR (default). |
| 15 | +- `/cursor-bugbot check <PR#>` — list Bugbot findings, classify them, but don't fix or reply. |
| 16 | +- `/cursor-bugbot reply <comment-id> <state>` — single-comment reply where `<state>` is `fixed`, `false-positive`, or `wont-fix`. |
| 17 | +- `/cursor-bugbot scope <PR#>` — re-evaluate the PR title and body against the actual commits and rewrite them when out of step. |
| 18 | + |
| 19 | +## Why a skill |
| 20 | + |
| 21 | +Cursor Bugbot's review surface is easy to mis-handle: |
| 22 | + |
| 23 | +- **Replies must thread on the inline review-comment**, not as a detached PR comment. A detached `gh pr comment` doesn't mark the thread resolved and the bot doesn't see it as a response. The right call is `gh api repos/{owner}/{repo}/pulls/{pr}/comments/{comment_id}/replies -X POST -f body=…`. |
| 24 | +- **Findings stale after fixes land.** Bugbot reviews a specific commit SHA. When you push a fix, the comment still references the old commit; the thread stays open until you reply marking it resolved. |
| 25 | +- **Stale findings vs. live bugs vs. false positives** all read the same on the API surface. Triaging needs a process, not vibes. |
| 26 | +- **Scope creep on PRs**. CLAUDE.md mandates "When adding commits to an OPEN PR, update the PR title and description to match the new scope." Easy to forget when you're heads-down fixing Bugbot findings. |
| 27 | + |
| 28 | +This skill makes all of the above mechanical. |
| 29 | + |
| 30 | +## Process |
| 31 | + |
| 32 | +### Phase 1 — Inventory |
| 33 | + |
| 34 | +```bash |
| 35 | +gh api "repos/{owner}/{repo}/pulls/<PR#>/comments" \ |
| 36 | + --jq '.[] | select(.user.login | test("cursor|bugbot"; "i")) | {id, path, line, body: (.body | split("\n")[0])}' |
| 37 | +``` |
| 38 | + |
| 39 | +Lists Bugbot findings as one-liners. Each finding has: |
| 40 | + |
| 41 | +- `id` — comment ID (used for replies and resolution) |
| 42 | +- `path` — file the finding is on |
| 43 | +- `line` — line number on that file |
| 44 | +- `body` — first line is the title (`### Title`) |
| 45 | +- `body` (full) — `Description` block, severity (Low/Medium/High), and rule (when triggered by a learned rule) |
| 46 | + |
| 47 | +For each finding, fetch the full body to read the description: |
| 48 | + |
| 49 | +```bash |
| 50 | +gh api "repos/{owner}/{repo}/pulls/comments/<id>" \ |
| 51 | + --jq '{path, line, body: (.body | split("<!-- BUGBOT")[0])}' |
| 52 | +``` |
| 53 | + |
| 54 | +The `<!-- BUGBOT` marker separates the human-readable finding from the bot's metadata. Strip everything after it for clean reading. |
| 55 | + |
| 56 | +### Phase 2 — Classify |
| 57 | + |
| 58 | +Sort each finding into one of four buckets: |
| 59 | + |
| 60 | +| Bucket | Meaning | Action | |
| 61 | +|---|---|---| |
| 62 | +| **real** | Live bug; reproducible against current PR HEAD. | Fix the code, push, reply with the fix commit SHA. | |
| 63 | +| **already-fixed** | Bugbot reviewed an old commit; the bug was fixed by a later commit on the same PR. | Reply with the fix commit SHA referencing the existing fix. No new code change. | |
| 64 | +| **false-positive** | Bugbot misread the code. Common patterns: hash length miscount, regex backtracking false-flag, JSDoc-example mistaken for runtime code. Often confirmed by a `Bugbot Autofix` reply on the same thread saying "false positive." | Reply explaining why it's a false positive. Cite a counter-example or the autofix verdict. | |
| 65 | +| **wont-fix** | Real but out of scope (would re-open already-resolved arguments, blocked on upstream change, intentional design choice the PR makes). | Reply with the rationale and link to a follow-up issue if applicable. Do not auto-close the thread; reviewer decides. | |
| 66 | + |
| 67 | +To check `already-fixed`: read `git log` on the PR branch since the comment's `commit_id` and look for a commit that touches the file at that line. |
| 68 | + |
| 69 | +### Phase 3 — Fix the real ones |
| 70 | + |
| 71 | +For each `real` finding: |
| 72 | + |
| 73 | +1. Read the file at the indicated line. |
| 74 | +2. Implement the fix. |
| 75 | +3. **Propagate to canonical** when the file lives under `.claude/hooks/`, `.claude/skills/`, or `.git-hooks/` — the same file probably exists in `socket-repo-template/template/` and 8+ other fleet repos. Fix it once at canonical, then sync to all consumers. (See `.claude/skills/_shared/canonical-sync.md` for the standard sync pattern.) |
| 76 | +4. Stage + commit the fix with a message that names the finding (e.g., `fix(hooks): address Cursor Bugbot finding on scanSocketApiKeys lineNumber`). |
| 77 | +5. Note the new commit SHA — the reply needs it. |
| 78 | + |
| 79 | +### Phase 4 — Reply on each thread |
| 80 | + |
| 81 | +**Critical**: replies go on the inline review-comment thread, not as a detached PR comment. The CLI form: |
| 82 | + |
| 83 | +```bash |
| 84 | +gh api "repos/{owner}/{repo}/pulls/<PR#>/comments/<comment-id>/replies" \ |
| 85 | + -X POST -f body="…" |
| 86 | +``` |
| 87 | + |
| 88 | +Reply templates: |
| 89 | + |
| 90 | +- **Real, fixed**: `Fixed in <commit-sha>. <one-sentence what changed>. <propagation note if any>.` |
| 91 | + - Example: `Fixed in a63d29105. Restored the Linear team-key + linear.app URL blocking from the deleted .sh hook as scanLinearRefs() in _helpers.mts. Synced from canonical socket-repo-template.` |
| 92 | + |
| 93 | +- **Already fixed**: `Already fixed in <commit-sha> (current PR HEAD). <one-sentence what changed>.` |
| 94 | + |
| 95 | +- **False positive**: `False positive — <one-sentence why>. <evidence: counter-example, Autofix reply ID, etc.>.` |
| 96 | + - Example: `False positive — confirmed by Bugbot Autofix in the sibling thread. The hash is exactly 128 hex chars: \`echo -n '<hash>' | wc -c\` returns 128.` |
| 97 | + |
| 98 | +- **Won't fix**: `Out of scope for this PR — <rationale>. Tracking as <issue/PR ref> if a follow-up is appropriate.` |
| 99 | + |
| 100 | +Keep replies short. Bugbot doesn't read them, but the human reviewer does. |
| 101 | + |
| 102 | +### Phase 5 — Update PR title + body if scope shifted |
| 103 | + |
| 104 | +CLAUDE.md rule: "When adding commits to an OPEN PR, update the PR title and description to match the new scope." |
| 105 | + |
| 106 | +After fixing Bugbot findings the scope often expands: |
| 107 | + |
| 108 | +- Original PR: `chore(hooks): sync .claude/hooks fleet` |
| 109 | +- After fixes: now also covers Linear-ref blocker restoration, errorMessage helper adoption, scanSocketApiKeys lineNumber bug, async safeDelete migration |
| 110 | + |
| 111 | +Re-read the PR commits and rewrite title/body when warranted: |
| 112 | + |
| 113 | +```bash |
| 114 | +gh pr view <PR#> --json title,body |
| 115 | +gh log origin/main..HEAD --oneline # what's actually in the PR now |
| 116 | +gh pr edit <PR#> --title "…" --body "…" |
| 117 | +``` |
| 118 | + |
| 119 | +Conventional-commit-style PR titles: `<type>(<scope>): <description>`. When fixes broaden scope, add the new scope to the parens (`chore(hooks, helpers)` instead of `chore(hooks)`). |
| 120 | + |
| 121 | +### Phase 6 — Push |
| 122 | + |
| 123 | +Push the fix commits to the PR branch: |
| 124 | + |
| 125 | +```bash |
| 126 | +git push |
| 127 | +``` |
| 128 | + |
| 129 | +Bugbot will re-review the new HEAD automatically. New findings → loop back to Phase 1. No new findings → the existing threads' resolution status will reflect your replies (Phase 4). |
| 130 | + |
| 131 | +## Constraints |
| 132 | + |
| 133 | +- **Reply on the inline thread**, never a detached PR comment. The hook for this is `gh api .../pulls/<PR#>/comments/<comment-id>/replies`, not `gh pr comment`. |
| 134 | +- **Thread the conversation**: when Bugbot Autofix has already responded on a finding (often labeling it false positive or auto-fixing it), reference the sibling reply ID in your response. Reviewers triage threads top-to-bottom; redundant traffic dilutes signal. |
| 135 | +- **Match the scope of your actions to what was actually requested.** Bugbot findings are advisory — fix the real ones, reject the false positives, don't be afraid to push back. "Bugbot says X" is not a mandate to do X. |
| 136 | +- **Propagate canonical fixes.** When a Bugbot finding is on a file that's synced fleet-wide (hooks, skills, helpers), fix the canonical at `socket-repo-template/template/` first, then sync to all consumers in the same logical change. Drifting fleet copies is the larger bug. |
| 137 | + |
| 138 | +## When to use |
| 139 | + |
| 140 | +- **After `gh pr create`** — Bugbot reviews most PRs within ~1 minute of creation. |
| 141 | +- **After pushing a Bugbot-related fix** — re-running the skill confirms the new HEAD didn't introduce new findings and lets you reply to the resolved threads. |
| 142 | +- **Before merging** — sweep open Bugbot threads as a final gate. The CLAUDE.md merge protocol depends on Bugbot threads being resolved (replied to, not necessarily approved). |
| 143 | + |
| 144 | +## Success criteria |
| 145 | + |
| 146 | +- Every Bugbot finding on the PR has a reply on its inline thread. |
| 147 | +- Every `real` finding has a corresponding fix commit on the PR branch. |
| 148 | +- The PR title and body match the actual commits. |
| 149 | +- The PR branch is pushed. |
| 150 | + |
| 151 | +## Anti-patterns |
| 152 | + |
| 153 | +- ❌ Replying via `gh pr comment` (detached). Doesn't thread, doesn't notify the reviewer. |
| 154 | +- ❌ Force-rewriting a Bugbot's finding by editing the comment via `--method PATCH`. The bot may re-post. |
| 155 | +- ❌ Closing Bugbot threads via the GitHub UI without a written reply. Future you (or the reviewer) won't know what happened. |
| 156 | +- ❌ Fixing a Bugbot finding by deleting the offending code without understanding *why* the code was there. Bugbot doesn't know about your domain; the human reviewer does. |
| 157 | +- ❌ Treating "Bugbot Autofix determined this is a false positive" as a definitive verdict without checking. The autofix bot is right ~95% of the time but verifying takes 10 seconds. |
0 commit comments