Skip to content

Commit d1a95db

Browse files
authored
chore(skills): sync cursor-bugbot from canonical (#1304)
Drives the Cursor Bugbot review-and-fix loop end-to-end: inventory findings, classify (real/already-fixed/false-positive/wont-fix), fix the real ones, reply on the inline review-comment thread (not as a detached PR comment), update PR title/body when scope shifted, push. Synced from socket-repo-template canonical (855d634).
1 parent e342ee2 commit d1a95db

1 file changed

Lines changed: 157 additions & 0 deletions

File tree

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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

Comments
 (0)