claude-dev-env 1.37.1 → 1.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +3 -0
- package/_shared/pr-loop/audit-contract.md +4 -3
- package/_shared/pr-loop/fix-protocol.md +2 -0
- package/_shared/pr-loop/gh-payloads.md +38 -37
- package/_shared/pr-loop/scripts/README.md +0 -1
- package/_shared/pr-loop/scripts/preflight.py +2 -1
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +2 -2
- package/_shared/pr-loop/scripts/tests/test_preflight.py +22 -0
- package/_shared/pr-loop/state-schema.md +10 -10
- package/agents/clean-coder.md +4 -0
- package/agents/code-quality-agent.md +23 -85
- package/agents/groq-coder.md +8 -6
- package/hooks/blocking/__init__.py +0 -0
- package/hooks/blocking/hedging_language_blocker.py +2 -2
- package/hooks/blocking/state_description_blocker.py +243 -0
- package/hooks/blocking/tdd_enforcer.py +94 -0
- package/hooks/blocking/test_hedging_language_blocker.py +1 -1
- package/hooks/blocking/test_state_description_blocker.py +618 -0
- package/hooks/blocking/test_tdd_enforcer.py +152 -0
- package/hooks/config/state_description_blocker_constants.py +130 -0
- package/hooks/hooks.json +10 -0
- package/package.json +1 -1
- package/rules/no-historical-clutter.md +31 -10
- package/scripts/config/groq_bugteam_config.py +13 -5
- package/skills/bugteam/CONSTRAINTS.md +20 -27
- package/skills/bugteam/EXAMPLES.md +1 -1
- package/skills/bugteam/PROMPTS.md +60 -31
- package/skills/bugteam/SKILL.md +47 -47
- package/skills/bugteam/SKILL_EVALS.md +8 -8
- package/skills/bugteam/reference/github-pr-reviews.md +31 -31
- package/skills/bugteam/reference/team-setup.md +1 -1
- package/skills/bugteam/reference/teardown-publish-permissions.md +4 -4
- package/skills/copilot-review/SKILL.md +7 -14
- package/skills/findbugs/SKILL.md +2 -2
- package/skills/fixbugs/SKILL.md +1 -1
- package/skills/monitor-open-prs/SKILL.md +6 -6
- package/skills/pr-converge/SKILL.md +7 -6
- package/skills/pr-converge/reference/convergence-gates.md +28 -30
- package/skills/pr-converge/reference/examples.md +4 -4
- package/skills/pr-converge/reference/fix-protocol.md +6 -8
- package/skills/pr-converge/reference/multi-pr-orchestration.md +10 -10
- package/skills/pr-converge/reference/per-tick.md +18 -33
- package/skills/pr-converge/reference/stop-conditions.md +7 -7
- package/skills/pr-converge/scripts/README.md +65 -117
- package/skills/pr-review-responder/EXAMPLES.md +2 -2
- package/skills/pr-review-responder/PRINCIPLES.md +2 -8
- package/skills/pr-review-responder/README.md +7 -48
- package/skills/pr-review-responder/SKILL.md +2 -3
- package/skills/pr-review-responder/TESTING.md +8 -65
- package/skills/qbug/SKILL.md +10 -16
- package/_shared/pr-loop/scripts/config/gh_util_constants.py +0 -31
- package/_shared/pr-loop/scripts/gh_util.py +0 -193
- package/_shared/pr-loop/scripts/tests/test_gh_util.py +0 -257
- package/_shared/pr-loop/scripts/tests/test_gh_util_constants.py +0 -61
- package/skills/pr-converge/scripts/check_pr_mergeability.py +0 -78
- package/skills/pr-converge/scripts/config/pr_converge_constants.py +0 -134
- package/skills/pr-converge/scripts/config/test_pr_converge_constants.py +0 -152
- package/skills/pr-converge/scripts/fetch_bugbot_inline_comments.py +0 -70
- package/skills/pr-converge/scripts/fetch_bugbot_reviews.py +0 -57
- package/skills/pr-converge/scripts/fetch_claude_inline_comments.py +0 -70
- package/skills/pr-converge/scripts/fetch_claude_reviews.py +0 -61
- package/skills/pr-converge/scripts/fetch_copilot_inline_comments.py +0 -70
- package/skills/pr-converge/scripts/fetch_copilot_reviews.py +0 -61
- package/skills/pr-converge/scripts/mark_pr_ready.py +0 -54
- package/skills/pr-converge/scripts/post-bugbot-run.helpers.ps1 +0 -49
- package/skills/pr-converge/scripts/post-bugbot-run.ps1 +0 -33
- package/skills/pr-converge/scripts/reply_to_inline_comment.py +0 -84
- package/skills/pr-converge/scripts/request_copilot_review.py +0 -71
- package/skills/pr-converge/scripts/resolve_pr_head.py +0 -58
- package/skills/pr-converge/scripts/review_field_helpers.py +0 -43
- package/skills/pr-converge/scripts/reviewer_fetch_core.py +0 -153
- package/skills/pr-converge/scripts/reviewer_specs.py +0 -98
- package/skills/pr-converge/scripts/test_check_pr_mergeability.py +0 -126
- package/skills/pr-converge/scripts/test_fetch_bugbot_inline_comments.py +0 -443
- package/skills/pr-converge/scripts/test_fetch_bugbot_reviews.py +0 -299
- package/skills/pr-converge/scripts/test_fetch_claude_inline_comments.py +0 -485
- package/skills/pr-converge/scripts/test_fetch_claude_reviews.py +0 -368
- package/skills/pr-converge/scripts/test_fetch_copilot_inline_comments.py +0 -440
- package/skills/pr-converge/scripts/test_fetch_copilot_reviews.py +0 -366
- package/skills/pr-converge/scripts/test_mark_pr_ready.py +0 -69
- package/skills/pr-converge/scripts/test_post_bugbot_run.py +0 -195
- package/skills/pr-converge/scripts/test_reply_to_inline_comment.py +0 -159
- package/skills/pr-converge/scripts/test_request_copilot_review.py +0 -101
- package/skills/pr-converge/scripts/test_resolve_pr_head.py +0 -79
- package/skills/pr-converge/scripts/test_review_field_helpers.py +0 -80
- package/skills/pr-converge/scripts/test_reviewer_fetch_core.py +0 -448
- package/skills/pr-converge/scripts/test_reviewer_specs.py +0 -107
- package/skills/pr-converge/scripts/test_trigger_bugbot.py +0 -139
- package/skills/pr-converge/scripts/test_view_pr_context.py +0 -155
- package/skills/pr-converge/scripts/trigger_bugbot.py +0 -77
- package/skills/pr-converge/scripts/view_pr_context.py +0 -78
- package/skills/pr-review-responder/scripts/respond_to_reviews.py +0 -376
|
@@ -15,16 +15,35 @@ Keep the spawn prompt self-contained: reference only the PR scope, audit rubric,
|
|
|
15
15
|
<worktree_path>absolute path from Step 1 per-PR workspace</worktree_path>
|
|
16
16
|
</context>
|
|
17
17
|
|
|
18
|
-
cd into `<worktree_path>` before any git
|
|
18
|
+
cd into `<worktree_path>` before any git or file operation.
|
|
19
19
|
|
|
20
20
|
<scope>
|
|
21
21
|
<diff_path>Absolute path to the per-PR patch file: <run_temp_dir>/pr-<N>/loop-<L>.patch (same path as gh pr diff redirect in AUDIT)</diff_path>
|
|
22
22
|
<scope_rule>Audit only lines added or modified in the diff. Pre-existing code on untouched lines is out of scope.</scope_rule>
|
|
23
|
+
<changed_files_rule>Build the list of changed file paths from the diff. Open each one with Read and audit cross-file consistency. Read every changed test file and cross-reference test assertions, expected values, and mock setup against the production code's config constants and function signatures. When a test file asserts a value that diverges from config, file a finding under category J.</changed_files_rule>
|
|
23
24
|
</scope>
|
|
24
25
|
|
|
25
26
|
<bug_categories>
|
|
26
|
-
Investigate each
|
|
27
|
-
one finding OR a verified-clean entry with the
|
|
27
|
+
Investigate each of the eleven categories (A–K) explicitly. For each,
|
|
28
|
+
return either at least one finding OR a verified-clean entry with the
|
|
29
|
+
evidence used to clear it. A category is verified-clean only when one
|
|
30
|
+
complete execution path through the changed code has been traced from
|
|
31
|
+
entry to exit. Surface-level scanning is insufficient evidence. The
|
|
32
|
+
evidence field must name (1) the specific function examined, (2) the
|
|
33
|
+
code path traced from entry to exit, and (3) the specific check performed.
|
|
34
|
+
Generic phrases such as "verified clean", "no issues found",
|
|
35
|
+
"pattern appears correct", "looks good", "seems fine", and
|
|
36
|
+
"no problems detected" do not satisfy the verified-clean requirement.
|
|
37
|
+
When evidence contains any of these phrases, the category is not
|
|
38
|
+
verified-clean -- re-audit with a concrete trace.
|
|
39
|
+
|
|
40
|
+
Categories A–K (one-line summary; full rubric and sub-bucket decomposition
|
|
41
|
+
for each is in `packages/claude-dev-env/audit-rubrics/category_rubrics/`;
|
|
42
|
+
ready-to-send Variant C prompts — each with a PR/repo-independent
|
|
43
|
+
generalized skeleton above a `---` separator and a worked example against
|
|
44
|
+
an authentic PR below — are in
|
|
45
|
+
`packages/claude-dev-env/audit-rubrics/prompts/`):
|
|
46
|
+
|
|
28
47
|
A. API contract verification (signatures, return types, async/await correctness)
|
|
29
48
|
B. Selector / query / engine compatibility
|
|
30
49
|
C. Resource cleanup and lifecycle (file handles, connections, processes, locks)
|
|
@@ -35,6 +54,10 @@ cd into `<worktree_path>` before any git, gh, or file operation.
|
|
|
35
54
|
H. Security boundaries (injection, path traversal, auth bypass, secret leakage)
|
|
36
55
|
I. Concurrency hazards (race conditions, missing awaits, shared mutable state)
|
|
37
56
|
J. Magic values and configuration drift
|
|
57
|
+
K. Codebase conflicts — a change updates one site of a pattern but a parallel
|
|
58
|
+
site in unchanged code stays stale, producing contradictory behavior;
|
|
59
|
+
the diff is internally consistent, the bug emerges only against unchanged
|
|
60
|
+
code (canonical example: jl-cmd/claude-code-config PR #397 r3210166636)
|
|
38
61
|
</bug_categories>
|
|
39
62
|
|
|
40
63
|
<constraints>
|
|
@@ -42,26 +65,26 @@ cd into `<worktree_path>` before any git, gh, or file operation.
|
|
|
42
65
|
- Cite file:line for every finding.
|
|
43
66
|
- When the diff alone does not provide enough context to confirm a bug,
|
|
44
67
|
list it under "Open questions" rather than assert it.
|
|
68
|
+
- For every finding, search `git grep` for all callers of the targeted function. When the obvious fix would silently change behavior for other call paths, include a fix constraint that preserves them.
|
|
45
69
|
</constraints>
|
|
46
70
|
|
|
47
71
|
<comment_posting>
|
|
48
|
-
Sibling auditors (-b through -k): run only steps 1–
|
|
72
|
+
Sibling auditors (-b through -k): run only steps 1–2 (audit, assign IDs,
|
|
49
73
|
capture excerpt, validate anchors), then write outcome XML per <output_format> and return.
|
|
50
|
-
Skip steps
|
|
74
|
+
Skip steps 3–5 — sibling auditors do not post PR reviews.
|
|
51
75
|
|
|
52
76
|
Validator (-a) and single-opus auditors: run all steps below.
|
|
53
77
|
|
|
54
|
-
1. Audit the diff against the
|
|
55
|
-
in memory; all posting happens at step
|
|
78
|
+
1. Audit the diff against the 11 categories above. Buffer the findings
|
|
79
|
+
in memory; all posting happens at step 4 once anchors are validated.
|
|
56
80
|
2. Assign each finding a stable finding_id of exactly the form `loop<L>-<K>`
|
|
57
81
|
where <K> is 1-based within this loop.
|
|
58
|
-
3. For each finding, capture a verbatim excerpt from the target file at the cited
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
5. For each anchored finding, write its body to its own temp file:
|
|
82
|
+
3. For each finding, capture a verbatim excerpt from the target file at the cited
|
|
83
|
+
line. Populate the `<excerpt>` element in the outcome XML with it. Validate
|
|
84
|
+
every finding's (file, line) against the captured diff. Split findings into two
|
|
85
|
+
buckets: anchored (line is in the diff) and unanchored (line is not in the diff
|
|
86
|
+
— goes into the review body's "Findings without a diff anchor" section per
|
|
87
|
+
Step 2.5). Format each finding body as:
|
|
65
88
|
|
|
66
89
|
**[severity] one-line title**
|
|
67
90
|
Category: <letter> (<category name>)
|
|
@@ -69,16 +92,16 @@ cd into `<worktree_path>` before any git, gh, or file operation.
|
|
|
69
92
|
|
|
70
93
|
_From /bugteam audit loop <L>._
|
|
71
94
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
95
|
+
4. Post ONE review via `pull_request_review_write(method="create",
|
|
96
|
+
event="COMMENT", body=<review_body>, owner=<O>, repo=<R>,
|
|
97
|
+
pullNumber=<N>, comments=[...])`. See Step 2.5 in SKILL.md for the full
|
|
98
|
+
parameter shape. Harvest the parent review `html_url` from the response
|
|
99
|
+
and the `comments[]` child entries (each with its own `id` and `html_url`).
|
|
100
|
+
Match child entries to anchored findings in index order.
|
|
101
|
+
5. If the review POST fails, use `add_issue_comment(owner=<O>, repo=<R>,
|
|
102
|
+
issueNumber=<N>, body=<full_text>)` as fallback.
|
|
103
|
+
Body text is passed directly as string parameters to the MCP tool calls —
|
|
104
|
+
no temp files, no jq, no shell pipes.
|
|
82
105
|
</comment_posting>
|
|
83
106
|
|
|
84
107
|
<output_format>
|
|
@@ -126,7 +149,7 @@ After the teammate writes the XML and returns, the lead reads `.bugteam-pr<N>-lo
|
|
|
126
149
|
<worktree_path>absolute path from Step 1 per-PR workspace</worktree_path>
|
|
127
150
|
</context>
|
|
128
151
|
|
|
129
|
-
cd into `<worktree_path>` before any git
|
|
152
|
+
cd into `<worktree_path>` before any git or file operation.
|
|
130
153
|
|
|
131
154
|
<bugs_to_fix>
|
|
132
155
|
[for each P0/P1/P2 finding from last_findings:]
|
|
@@ -147,19 +170,22 @@ cd into `<worktree_path>` before any git, gh, or file operation.
|
|
|
147
170
|
1. Read each referenced file before editing.
|
|
148
171
|
2. Apply each fix you can address.
|
|
149
172
|
3. Run `python -m py_compile` (or language-equivalent) on every modified file.
|
|
150
|
-
4.
|
|
173
|
+
4. Run the project's test suite and confirm all existing tests pass. If a test fails, diagnose the regression and fix it before committing.
|
|
174
|
+
5. Read the previous loop's outcome XML (`<worktree_path>/.bugteam-pr<N>-loop<L-1>.outcomes.xml`) and obtain its total finding count. If this is the first loop (L <= 1) or the file does not exist, skip this comparison. Otherwise, re-read each changed file and count any new violations. Compute the post-fix total: previous total minus bugs fixed in this round plus new violations. If the post-fix total exceeds the previous total, flag all new findings as same-loop fix-targets and revise before committing.
|
|
175
|
+
6. git add by explicit path, then git commit with a message summarizing the bugs fixed.
|
|
151
176
|
- If the commit fails because a git hook (pre-commit, commit-msg, etc.) blocked it,
|
|
152
177
|
capture the hook's stderr, write status=hook_blocked for every finding in this loop
|
|
153
178
|
(the commit was atomic; if it failed, no finding was applied), populate hook_output
|
|
154
179
|
on each outcome, and return WITHOUT retrying. The lead will treat this loop as no-progress.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
180
|
+
7. git push with a plain fast-forward push (the default, no flag overrides).
|
|
181
|
+
8. For each bug, post a fix reply to its finding_comment_id via
|
|
182
|
+
`add_reply_to_pull_request_comment(commentId=<id>, body=<reply_text>,
|
|
183
|
+
owner=<O>, repo=<R>, pullNumber=<N>)`:
|
|
158
184
|
- "Fixed in <commit_sha>" if the bug was addressed by your commit
|
|
159
185
|
- "Could not address this loop: <one-line reason>" if you skipped or failed it
|
|
160
186
|
- "Hook blocked the fix commit: <one-line summary>" if the commit was hook-blocked
|
|
161
|
-
|
|
162
|
-
|
|
187
|
+
Body text is passed directly as string parameters -- no temp files, no jq, no shell pipes.
|
|
188
|
+
9. Write `.bugteam-pr<N>-loop<L>.fix-outcomes.xml` inside `<worktree_path>` (schema below) and return its path.
|
|
163
189
|
</execution>
|
|
164
190
|
|
|
165
191
|
<outcome_xml_schema>
|
|
@@ -186,5 +212,8 @@ cd into `<worktree_path>` before any git, gh, or file operation.
|
|
|
186
212
|
- git add by explicit path — name each file being staged.
|
|
187
213
|
- Preserve existing comments on lines you do not modify.
|
|
188
214
|
- Type hints on every signature you touch.
|
|
215
|
+
- **Narrow scope.** Fix only the exact defect at the specified file:line. No restructuring, no inlining helpers, no renames, no "while I'm here" cleanup.
|
|
216
|
+
- **Preserve helpers.** Do not remove or inline existing helper functions unless the finding explicitly names the helper as the problem.
|
|
217
|
+
- **No regression.** Before committing, re-read each changed file and count any new violations. Compare the post-fix total (previous total minus bugs fixed plus new violations) against the previous loop's total finding count (from `<worktree_path>/.bugteam-pr<N>-loop<L-1>.outcomes.xml`). On the first loop (L <= 1) or when the file does not exist, skip this guard. The post-fix total must be flat or decreased relative to the previous loop. An increase means the fix introduced new bugs — revise before committing. Do not commit a regression.
|
|
189
218
|
</constraints>
|
|
190
219
|
```
|
package/skills/bugteam/SKILL.md
CHANGED
|
@@ -120,9 +120,9 @@ Non-zero → stop. Revoke in Step 5 on every exit path.
|
|
|
120
120
|
|
|
121
121
|
### Step 1: Resolve PR scope (once)
|
|
122
122
|
|
|
123
|
-
Accept one or more PR numbers from the invocation. For each PR,
|
|
124
|
-
|
|
125
|
-
path when no PR exists). Capture `all_prs = [{number, owner, repo, baseRef,
|
|
123
|
+
Accept one or more PR numbers from the invocation. For each PR, call
|
|
124
|
+
`pull_request_read(method="get", pullNumber=N, owner=O, repo=R)` (falling back
|
|
125
|
+
to the merge-base diff path when no PR exists). Capture `all_prs = [{number, owner, repo, baseRef,
|
|
126
126
|
headRef, url}, ...]`. A single-PR invocation produces a one-element list and
|
|
127
127
|
follows the same downstream rules.
|
|
128
128
|
|
|
@@ -186,41 +186,34 @@ Order: audit → buffer → validate anchors vs diff → single review POST.
|
|
|
186
186
|
Review body states counts; zero findings → still one review, `comments: []`,
|
|
187
187
|
body `## /bugteam loop <L> audit: 0P0 / 0P1 / 0P2 → clean`.
|
|
188
188
|
|
|
189
|
-
**Payloads:**
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
**Payloads:** Use MCP tool calls (see below). Body text with markdown (backticks,
|
|
190
|
+
newlines, quotes) passes through safely as string parameters — no temp files, no
|
|
191
|
+
jq, no shell pipes.
|
|
192
192
|
|
|
193
193
|
**Review POST** (one `comments[]` object per anchored finding; single-line
|
|
194
194
|
`{path, line, side: "RIGHT", body}`; multi-line add `start_line`, `start_side:
|
|
195
195
|
"RIGHT"`):
|
|
196
196
|
|
|
197
197
|
```
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
[
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
comments: [
|
|
210
|
-
{path: $path_1, line: $line_1, side: "RIGHT", body: $finding_body_1}
|
|
211
|
-
[, ... ]
|
|
212
|
-
]
|
|
213
|
-
}' \
|
|
214
|
-
| gh api repos/<owner>/<repo>/pulls/<number>/reviews -X POST --input -
|
|
198
|
+
pull_request_review_write(
|
|
199
|
+
method="create",
|
|
200
|
+
event="COMMENT",
|
|
201
|
+
body=<review_body_text>,
|
|
202
|
+
commitID=<head_sha_at_post_time>,
|
|
203
|
+
owner=<owner>, repo=<repo>, pullNumber=<number>,
|
|
204
|
+
comments=[
|
|
205
|
+
{path: <path_1>, line: <line_1>, side: "RIGHT", body: <finding_body_1>}
|
|
206
|
+
[, ... ]
|
|
207
|
+
]
|
|
208
|
+
)
|
|
215
209
|
```
|
|
216
210
|
|
|
217
|
-
**Fix reply:** `
|
|
218
|
-
|
|
219
|
-
POST --input -`
|
|
211
|
+
**Fix reply:** `add_reply_to_pull_request_comment(commentId=<finding_comment_id>,
|
|
212
|
+
body=<reply_text>, owner=<owner>, repo=<repo>, pullNumber=<number>)`
|
|
220
213
|
|
|
221
|
-
**Review POST fails:** issue comment fallback:
|
|
222
|
-
|
|
223
|
-
|
|
214
|
+
**Review POST fails:** issue comment fallback:
|
|
215
|
+
`add_issue_comment(owner=<owner>, repo=<repo>, issueNumber=<number>,
|
|
216
|
+
body=<fallback_text>)`
|
|
224
217
|
|
|
225
218
|
`<head_sha_at_post_time>`: `git rev-parse HEAD` in subagent cwd immediately
|
|
226
219
|
before POST.
|
|
@@ -263,10 +256,16 @@ and before iteration begins, when `last_action == "fresh"`). A re-invocation of
|
|
|
263
256
|
cleaned this HEAD (short-circuit) and otherwise records that prior loops were
|
|
264
257
|
dirty so the AUDIT runs against the latest diff with that signal in mind:
|
|
265
258
|
|
|
266
|
-
```
|
|
267
|
-
dirty_review_count=0
|
|
268
|
-
|
|
269
|
-
|
|
259
|
+
```python
|
|
260
|
+
dirty_review_count = 0
|
|
261
|
+
all_reviews = pull_request_read(
|
|
262
|
+
method="get_reviews", pullNumber=N, owner=O, repo=R
|
|
263
|
+
)
|
|
264
|
+
prior_reviews = [
|
|
265
|
+
rev for rev in all_reviews
|
|
266
|
+
if rev.get("body", "").startswith("## /bugteam loop ")
|
|
267
|
+
]
|
|
268
|
+
prior_reviews.sort(key=lambda rev: rev["submitted_at"], reverse=True)
|
|
270
269
|
```
|
|
271
270
|
|
|
272
271
|
Iterate from index 0 (most recent) toward older entries:
|
|
@@ -313,7 +312,7 @@ Iterate from index 0 (most recent) toward older entries:
|
|
|
313
312
|
Lead only; merge-base / diff semantics:
|
|
314
313
|
[`../../_shared/pr-loop/code-rules-gate.md`][path-code-rules]; shared script
|
|
315
314
|
inventory: [`../../_shared/pr-loop/scripts/README.md`][path-scripts-readme].
|
|
316
|
-
Non-zero → spawn **clean-coder** standards-fix (read stderr, edit, re-run
|
|
315
|
+
Non-zero → spawn **clean-coder** standards-fix (`mode="bypassPermissions"`) (read stderr, edit, re-run
|
|
317
316
|
**this same** command, one commit, `git push`, shutdown) until exit **0** or
|
|
318
317
|
**5**
|
|
319
318
|
failed gate rounds → `error: code rules gate failed pre-audit`. After **0**:
|
|
@@ -335,12 +334,10 @@ before the next AUDIT.
|
|
|
335
334
|
|
|
336
335
|
### AUDIT action
|
|
337
336
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
**Spawn:**
|
|
337
|
+
1. Create the directory: `mkdir -p "<run_temp_dir>/pr-<N>"`.
|
|
338
|
+
2. Call `pull_request_read(method="get_diff", pullNumber=N, owner=O, repo=R)`
|
|
339
|
+
to capture the diff text, then write it to
|
|
340
|
+
`"<run_temp_dir>/pr-<N>/loop-<L>.patch"` using the `Write` tool.
|
|
344
341
|
|
|
345
342
|
```
|
|
346
343
|
Agent(
|
|
@@ -411,6 +408,8 @@ advanced; `git -C "<run_temp_dir>/pr-<N>/worktree" fetch origin <branch> && git
|
|
|
411
408
|
`HEAD`. Unchanged HEAD →
|
|
412
409
|
`stuck — bugfix subagent could not address findings`.
|
|
413
410
|
|
|
411
|
+
**Scope verification.** Run `git diff HEAD~1 --name-only` and compare against the set of files referenced in bugs_to_fix. When the commit touches any file NOT in the bugs_to_fix list, downgrade the outcome to `unverified_fixed` with reason "commit touched unexpected files: <list>".
|
|
412
|
+
|
|
414
413
|
### Step 4: Teardown
|
|
415
414
|
|
|
416
415
|
1. For each PR in `all_prs`: `git worktree remove
|
|
@@ -431,16 +430,17 @@ else {'onerror': h}))"
|
|
|
431
430
|
### Step 4.5: PR description
|
|
432
431
|
|
|
433
432
|
Lead only; cumulative product narrative (not process). Delegate body to
|
|
434
|
-
`pr-description-writer` via `Agent` (else `general-purpose`) so the
|
|
435
|
-
mandatory-pr-description hook accepts `
|
|
433
|
+
`pr-description-writer` via `Agent` (`mode="bypassPermissions"`) (else `general-purpose`) so the
|
|
434
|
+
mandatory-pr-description hook accepts `update_pull_request`.
|
|
436
435
|
|
|
437
|
-
1. `
|
|
438
|
-
|
|
439
|
-
|
|
436
|
+
1. `pull_request_read(method="get_diff", pullNumber=N, owner=O, repo=R)` → write
|
|
437
|
+
output to `.bugteam-final.diff` with `Write` tool.
|
|
438
|
+
2. `pull_request_read(method="get", pullNumber=N, owner=O, repo=R)` → extract
|
|
439
|
+
`.body` from response, write to `.bugteam-original-body.md` with `Write` tool.
|
|
440
440
|
3. Agent brief: paths + branch names; describe merge-ready change from diff;
|
|
441
441
|
keep curated original sections intact; return markdown body.
|
|
442
|
-
4. Write `.bugteam-final-body.md`; `
|
|
443
|
-
|
|
442
|
+
4. Write `.bugteam-final-body.md`; `update_pull_request(pullNumber=N, owner=O,
|
|
443
|
+
repo=R, body=<body_text>)`.
|
|
444
444
|
5. Delete the three temp files.
|
|
445
445
|
|
|
446
446
|
On failure: log in final report; continue to Step 5.
|
|
@@ -68,7 +68,7 @@ The harness does not yet exist; this document defines its contract.
|
|
|
68
68
|
**Scenario.** Current branch is `main` with no PR and no upstream difference.
|
|
69
69
|
|
|
70
70
|
**Layer B predicted trace.**
|
|
71
|
-
1. `
|
|
71
|
+
1. `pull_request_read(method="get", pullNumber=N, owner=O, repo=R)` → fails / no matching PR.
|
|
72
72
|
2. `Bash("git merge-base HEAD origin/main")` → empty.
|
|
73
73
|
3. No grant script.
|
|
74
74
|
|
|
@@ -103,10 +103,10 @@ The harness does not yet exist; this document defines its contract.
|
|
|
103
103
|
| # | Tool call | Source |
|
|
104
104
|
|---|---|---|
|
|
105
105
|
| 1 | `Bash("python .../scripts/grant_project_claude_permissions.py")` | `SKILL.md` § Step 0 |
|
|
106
|
-
| 2 | `
|
|
106
|
+
| 2 | `pull_request_read(method="get", pullNumber=42, owner=..., repo=...)` | `SKILL.md` § Step 1 |
|
|
107
107
|
| 3 | `Bash("git -C \"<run_temp_dir>/pr-42/worktree\" rev-parse HEAD")` → captures `starting_sha` | `SKILL.md` § Step 2 — **Loop state** block |
|
|
108
108
|
| 4 | `Bash("mkdir -p <run_temp_dir>/pr-42")` | `SKILL.md` § AUDIT action |
|
|
109
|
-
| 5 | `
|
|
109
|
+
| 5 | `pull_request_read(method="get_diff", pullNumber=42, owner=..., repo=...)` → write to `<run_temp_dir>/pr-42/loop-1.patch` | `SKILL.md` § AUDIT action |
|
|
110
110
|
| 6 | `Agent(subagent_type="code-quality-agent", name="bugfind-pr42-loop1", run_in_background=true, model="opus", description=..., prompt=<audit XML loop 1>)` | `SKILL.md` § AUDIT action |
|
|
111
111
|
| 7 | Lead awaits background-completion notification | `SKILL.md` § AUDIT action |
|
|
112
112
|
| 8 | `Read(".bugteam-pr42-loop1.outcomes.xml")` | `SKILL.md` § AUDIT action |
|
|
@@ -116,17 +116,17 @@ The harness does not yet exist; this document defines its contract.
|
|
|
116
116
|
| 12 | `Bash("git -C \"<run_temp_dir>/pr-42/worktree\" rev-parse HEAD")` → verify HEAD advanced | `SKILL.md` § FIX action (**Verify**) |
|
|
117
117
|
| 13 | `Bash("git -C \"<run_temp_dir>/pr-42/worktree\" fetch origin <branch>")` → fetch remote state | `SKILL.md` § FIX action (**Verify**) |
|
|
118
118
|
| 14 | `Bash("git -C \"<run_temp_dir>/pr-42/worktree\" rev-parse origin/<branch>")` → confirm matches HEAD | `SKILL.md` § FIX action (**Verify**) |
|
|
119
|
-
| 15 | `
|
|
119
|
+
| 15 | `pull_request_read(method="get_diff", pullNumber=42, owner=..., repo=...)` → write to `<run_temp_dir>/pr-42/loop-2.patch` | `SKILL.md` § AUDIT action |
|
|
120
120
|
| 16 | `Agent(subagent_type="code-quality-agent", name="bugfind-pr42-loop2", run_in_background=true, ...)` (loop 2) | `SKILL.md` § AUDIT action |
|
|
121
121
|
| 17 | Lead awaits background-completion notification | `SKILL.md` § AUDIT action |
|
|
122
122
|
| 18 | `Read(".bugteam-pr42-loop2.outcomes.xml")` — zero findings | `SKILL.md` § AUDIT action |
|
|
123
123
|
| 19 | `Bash("git worktree remove \"<run_temp_dir>/pr-42/worktree\"")` | `SKILL.md` § Step 4 step 1 |
|
|
124
124
|
| 20 | `Bash("python -c \"...shutil.rmtree(r'<run_temp_dir>', ...)\"")` | `SKILL.md` § Step 4 step 2 (Windows-safe teardown) |
|
|
125
|
-
| 21 | `
|
|
126
|
-
| 22 | `
|
|
125
|
+
| 21 | `pull_request_read(method="get_diff", pullNumber=42, owner=..., repo=...)` → write to `.bugteam-final.diff` | `SKILL.md` § Step 4.5 step 1 |
|
|
126
|
+
| 22 | `pull_request_read(method="get", pullNumber=42, owner=..., repo=...)` → extract `.body`, write to `.bugteam-original-body.md` | `SKILL.md` § Step 4.5 step 2 |
|
|
127
127
|
| 23 | `Agent(subagent_type="pr-description-writer", description=..., prompt=<brief>)` | `SKILL.md` § Step 4.5 |
|
|
128
128
|
| 24 | `Write(".bugteam-final-body.md", <returned body>)` | `SKILL.md` § Step 4.5 step 4 |
|
|
129
|
-
| 25 | `
|
|
129
|
+
| 25 | `update_pull_request(pullNumber=42, owner=..., repo=..., body=...)` | `SKILL.md` § Step 4.5 step 4 |
|
|
130
130
|
| 26 | `Bash("rm .bugteam-final.diff .bugteam-original-body.md .bugteam-final-body.md")` | `SKILL.md` § Step 4.5 step 5 |
|
|
131
131
|
| 27 | `Bash("python .../scripts/revoke_project_claude_permissions.py")` | `SKILL.md` § Step 5 |
|
|
132
132
|
|
|
@@ -224,7 +224,7 @@ Patch this table to match observation and annotate each correction.
|
|
|
224
224
|
- Every finding's outcome XML carries `used_fallback="true"` and the issue-comment URL as `finding_comment_url`.
|
|
225
225
|
- Cycle continues to the FIX action without aborting.
|
|
226
226
|
|
|
227
|
-
**Open item for the real run.** The issue-comments fallback
|
|
227
|
+
**Open item for the real run.** The issue-comments fallback uses `add_issue_comment(owner=..., repo=..., issueNumber=42, body=...)` (`SKILL.md` § Step 2.5 **Review POST fails**; full narrative in `reference/github-pr-reviews.md` § **Review POST failure fallback**). Before running Eval 10 for real, confirm the teammate obeys this shape — the fixture must assert the `add_issue_comment` tool call.
|
|
228
228
|
|
|
229
229
|
---
|
|
230
230
|
|
|
@@ -8,55 +8,55 @@ Per-loop pull-request reviews: findings render as a tree under one parent review
|
|
|
8
8
|
|
|
9
9
|
**Ordering:** Bugfind audits first, buffers findings, validates anchors against the captured diff, then posts the review **once** at the end. The review body states the finding count authoritatively. Keep all posting in that single end-of-loop review POST.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## MCP tool shapes (teammate)
|
|
12
12
|
|
|
13
|
-
All three POSTs use
|
|
13
|
+
All three POSTs use MCP tool calls. Body text with markdown (backticks, newlines, quotes) passes through safely as string parameters — no temp files, no jq, no shell pipes.
|
|
14
14
|
|
|
15
15
|
### Per-loop review (one POST creates parent + children)
|
|
16
16
|
|
|
17
17
|
Build `comments[]` programmatically from buffered, diff-anchored findings. Single-line shape: `{path, line, side: "RIGHT", body: <finding markdown>}`. Multi-line: `{path, start_line, start_side: "RIGHT", line, side: "RIGHT", body: ...}` (all four anchor fields required).
|
|
18
18
|
|
|
19
19
|
```
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
[
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
comments: [
|
|
32
|
-
{path: $path_1, line: $line_1, side: "RIGHT", body: $finding_body_1}
|
|
33
|
-
[, ... one object per anchored finding ...]
|
|
34
|
-
]
|
|
35
|
-
}' \
|
|
36
|
-
| gh api repos/<owner>/<repo>/pulls/<number>/reviews -X POST --input -
|
|
20
|
+
pull_request_review_write(
|
|
21
|
+
method="create",
|
|
22
|
+
event="COMMENT",
|
|
23
|
+
body=<review_body_markdown>,
|
|
24
|
+
commitID=<head_sha_at_post_time>,
|
|
25
|
+
owner=<owner>, repo=<repo>, pullNumber=<pull_number>,
|
|
26
|
+
comments=[
|
|
27
|
+
{path: <file_1>, line: <line_1>, side: "RIGHT", body: <finding_1_markdown>}
|
|
28
|
+
[, ... one object per anchored finding ...]
|
|
29
|
+
]
|
|
30
|
+
)
|
|
37
31
|
```
|
|
38
32
|
|
|
39
|
-
Response
|
|
33
|
+
Response includes the parent review `html_url` and a `comments` array of child comments (`id`, `html_url`). Harvest children in index order and align with the finding list.
|
|
40
34
|
|
|
41
35
|
### Fix reply
|
|
42
36
|
|
|
43
37
|
```
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
add_reply_to_pull_request_comment(
|
|
39
|
+
commentId=<finding_comment_id>,
|
|
40
|
+
body=<reply_markdown>,
|
|
41
|
+
owner=<owner>, repo=<repo>, pullNumber=<pull_number>
|
|
42
|
+
)
|
|
46
43
|
```
|
|
47
44
|
|
|
48
45
|
### Review POST failure fallback
|
|
49
46
|
|
|
50
|
-
Top-level PR comment via issue-comments (`
|
|
47
|
+
Top-level PR comment via issue-comments (`issue_number` is the PR number):
|
|
51
48
|
|
|
52
49
|
```
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
add_issue_comment(
|
|
51
|
+
owner=<owner>, repo=<repo>,
|
|
52
|
+
issueNumber=<pull_number>,
|
|
53
|
+
body=<full_fallback_markdown>
|
|
54
|
+
)
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
`<head_sha_at_post_time>` is the SHA at post time (`git rev-parse HEAD` in the teammate’s working directory immediately before the POST). The review anchors finding comments to the head SHA at audit time (before this loop’s fix lands).
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
Body text is passed directly as string parameters to the MCP tool calls — no temp files, no jq, no shell pipes.
|
|
60
60
|
|
|
61
61
|
## Review body template (`<tmp_review_body.md>`)
|
|
62
62
|
|
|
@@ -77,10 +77,10 @@ GitHub rejects the entire review POST if any `comments[]` entry targets a line n
|
|
|
77
77
|
|
|
78
78
|
## Review POST failure fallback
|
|
79
79
|
|
|
80
|
-
If the review POST fails (rate limit, network, malformed payload), fall back to one top-level issue comment containing the review body plus every finding inline (severity, file:line, description). Every finding in that run: `used_fallback="true"`, `finding_comment_url` = issue-comment URL. Use
|
|
80
|
+
If the review POST fails (rate limit, network, malformed payload), fall back to one top-level issue comment containing the review body plus every finding inline (severity, file:line, description). Every finding in that run: `used_fallback="true"`, `finding_comment_url` = issue-comment URL. Use `add_issue_comment` (see MCP tool reference below).
|
|
81
81
|
|
|
82
|
-
##
|
|
82
|
+
## MCP tool reference
|
|
83
83
|
|
|
84
|
-
- Per-loop batched review: `POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews`
|
|
85
|
-
- Fix reply: `POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies`
|
|
86
|
-
- Review-POST failure fallback: `POST /repos/{owner}/{repo}/issues/{issue_number}/comments`
|
|
84
|
+
- Per-loop batched review: `pull_request_review_write(method="create", event="COMMENT", body=..., commitID=..., owner=..., repo=..., pullNumber=..., comments=[...])` — wraps `POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews`
|
|
85
|
+
- Fix reply: `add_reply_to_pull_request_comment(commentId=..., body=..., owner=..., repo=..., pullNumber=...)` — wraps `POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies`
|
|
86
|
+
- Review-POST failure fallback: `add_issue_comment(owner=..., repo=..., issueNumber=..., body=...)` — wraps `POST /repos/{owner}/{repo}/issues/{issue_number}/comments`
|
|
@@ -14,7 +14,7 @@ This is the **first** action of every `/bugteam` invocation, before any subagent
|
|
|
14
14
|
|
|
15
15
|
Same resolution path as `/findbugs`:
|
|
16
16
|
|
|
17
|
-
1. `
|
|
17
|
+
1. `pull_request_read(method="get", pullNumber=N, owner=O, repo=R)` — extracts `number`, `baseRefName`, `headRefName`, `url` from response (`N` comes from the parent skill's PR context, or fall back to `pull_request_read` with the default branch lookup to recover the PR number).
|
|
18
18
|
2. Fall back to `git merge-base HEAD origin/<default>` then `git diff <merge-base>...HEAD`.
|
|
19
19
|
3. Neither → refuse per refusal cases in `SKILL.md`.
|
|
20
20
|
|
|
@@ -34,15 +34,15 @@ If that subagent is missing, fall back to `general-purpose` with the same brief
|
|
|
34
34
|
|
|
35
35
|
**Steps:**
|
|
36
36
|
|
|
37
|
-
1. Capture cumulative diff: `
|
|
38
|
-
2. Capture original body: `
|
|
37
|
+
1. Capture cumulative diff: `pull_request_read(method="get_diff", pullNumber=N, owner=O, repo=R)` → write output to `.bugteam-final.diff` with `Write` tool.
|
|
38
|
+
2. Capture original body: `pull_request_read(method="get", pullNumber=N, owner=O, repo=R)` → extract `.body` from response, write to `.bugteam-original-body.md` with `Write` tool.
|
|
39
39
|
3. Agent brief:
|
|
40
40
|
- **Inputs:** diff path, original body path, head branch, base branch.
|
|
41
41
|
- **Constraint:** describe what the PR delivers from the cumulative diff — behavior, user-visible effect, merge rationale. Process metadata (loops, fix counts, findings) stays in review comments.
|
|
42
|
-
- **Preservation rule:** if the original body has manually curated sections (linked issues, screenshots, test plan,
|
|
42
|
+
- **Preservation rule:** if the original body has manually curated sections (linked issues, screenshots, test plan, "Risk Assessment", etc.), preserve them verbatim and only rewrite narrative around them.
|
|
43
43
|
- **Output:** new body markdown.
|
|
44
44
|
4. Write `.bugteam-final-body.md`.
|
|
45
|
-
5. `
|
|
45
|
+
5. `update_pull_request(pullNumber=N, owner=O, repo=R, body=<body_text>)`.
|
|
46
46
|
6. Delete `.bugteam-final.diff`, `.bugteam-original-body.md`, `.bugteam-final-body.md`.
|
|
47
47
|
|
|
48
48
|
If Step 4.5 fails (agent error, hook block, network), report in the final report and continue to Step 5. The original PR body remains; commits and comments are unaffected.
|
|
@@ -26,10 +26,10 @@ The user is on a PR branch, wants Copilot (the GitHub Copilot reviewer bot) to k
|
|
|
26
26
|
From the current repo:
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
|
|
29
|
+
# MCP: pull_request_read(method="get") returns {number, url, head.sha, base.ref, head.ref, isDraft}
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Capture `number`, `
|
|
32
|
+
Capture `number`, `head.sha`, owner/repo (from `url`), and branch name. Pass these to the subagent so it does not rediscover them.
|
|
33
33
|
|
|
34
34
|
### Step 2: Spawn the background subagent
|
|
35
35
|
|
|
@@ -57,23 +57,16 @@ Pass this verbatim to the subagent (substituting the bracketed values):
|
|
|
57
57
|
>
|
|
58
58
|
> **Per-tick work** (do this now, then on each wakeup):
|
|
59
59
|
>
|
|
60
|
-
> 1. Resolve current HEAD: `
|
|
61
|
-
> 2. Fetch latest Copilot review
|
|
62
|
-
> ```bash
|
|
63
|
-
> gh api repos/[OWNER]/[REPO]/pulls/[NUMBER]/reviews \
|
|
64
|
-
> --jq '[.[] | select(.user.login=="copilot-pull-request-reviewer[bot]")] | sort_by(.submitted_at) | last'
|
|
65
|
-
> ```
|
|
60
|
+
> 1. Resolve current HEAD: `pull_request_read(method="get", pullNumber=[NUMBER], owner="[OWNER]", repo="[REPO]")` and extract `.head.sha`.
|
|
61
|
+
> 2. Fetch latest Copilot review via `pull_request_read(method="get_reviews", pullNumber=[NUMBER], owner="[OWNER]", repo="[REPO]")`.
|
|
66
62
|
> Capture `commit_id`, `state`, `submitted_at`, `id`.
|
|
67
63
|
> 3. Decide the branch:
|
|
68
64
|
> - **No review exists:** re-request (step 4), schedule next wakeup, return.
|
|
69
65
|
> - **Latest review's `commit_id` != current HEAD:** re-request (step 4), schedule next wakeup, return.
|
|
70
66
|
> - **Latest review's `commit_id` == current HEAD with unresolved inline findings:** TDD-fix them, push, reply inline on each thread, re-request (step 4), schedule next wakeup, return.
|
|
71
67
|
> - **Latest review's `commit_id` == current HEAD and clean:** report convergence to the parent with a one-sentence summary and terminate. The loop is done; skip the ScheduleWakeup call.
|
|
72
|
-
> 4. Re-request Copilot
|
|
73
|
-
>
|
|
74
|
-
> gh api -X POST repos/[OWNER]/[REPO]/pulls/[NUMBER]/requested_reviewers \
|
|
75
|
-
> -f 'reviewers[]=copilot-pull-request-reviewer[bot]'
|
|
76
|
-
> ```
|
|
68
|
+
> 4. Re-request Copilot via `request_copilot_review(owner="[OWNER]", repo="[REPO]", pullNumber=[NUMBER])`.
|
|
69
|
+
> The reviewer ID **must** be `copilot-pull-request-reviewer[bot]` with the `[bot]` suffix — empirically verified: `Copilot`, `copilot`, and `github-copilot` all return `requested_reviewers: []` with no error, silently no-op.
|
|
77
70
|
> 5. Schedule the next wakeup with `ScheduleWakeup`:
|
|
78
71
|
> - `delaySeconds: 300`
|
|
79
72
|
> - `reason`: one short sentence on what you are waiting for.
|
|
@@ -86,7 +79,7 @@ Pass this verbatim to the subagent (substituting the bracketed values):
|
|
|
86
79
|
> - Implement the fix.
|
|
87
80
|
> - Stage the fix and create one new commit on the existing branch: `git add <files> && git commit -m "fix(review): ..."`.
|
|
88
81
|
> - Push the new commit: `git push origin [BRANCH]`.
|
|
89
|
-
> - Reply inline on each comment thread with `
|
|
82
|
+
> - Reply inline on each comment thread with `add_reply_to_pull_request_comment(owner="[OWNER]", repo="[REPO]", pullNumber=[NUMBER], body="...", commentId=<comment_id>)`, referencing the new commit SHA.
|
|
90
83
|
>
|
|
91
84
|
> When a pre-push, pre-commit, or other hook rejects the change, solve it. Read the hook's error message, diagnose the root cause in the code or test, and fix that. Then rerun the commit or push. Hooks exist to catch real problems; treat each rejection as new evidence to act on.
|
|
92
85
|
>
|
package/skills/findbugs/SKILL.md
CHANGED
|
@@ -24,7 +24,7 @@ If the current branch has no associated PR and no diff against the default branc
|
|
|
24
24
|
|
|
25
25
|
Determine the audit target in this order:
|
|
26
26
|
|
|
27
|
-
1. **Open PR for current branch.**
|
|
27
|
+
1. **Open PR for current branch.** Call `pull_request_read(method="get", pullNumber=N, owner=O, repo=R)` for the current branch (`N` comes from the parent skill's context, or fall back to `search_issues` MCP with the current branch name to recover the PR number). If a PR exists, capture its number, base ref, head ref, and URL.
|
|
28
28
|
2. **No PR but a remote default branch exists.** Diff against the default branch's merge-base: `git merge-base HEAD origin/<default>` then `git diff <merge-base>...HEAD`. Treat this as the audit scope.
|
|
29
29
|
3. **Neither.** Respond exactly: `No PR or upstream diff found. Push the branch or open a PR first.` and stop.
|
|
30
30
|
|
|
@@ -39,7 +39,7 @@ diff_temp_path = Path(tempfile.gettempdir()) / f"findbugs-pr-{os.getpid()}.patch
|
|
|
39
39
|
|
|
40
40
|
`os.getpid()` supplies the per-invocation suffix that prevents collisions with parallel `/findbugs` runs (a UUID or timestamp is equally acceptable). Capture the resolved absolute path as `<diff_temp_path>` and pass that **literal** path to every shell command that follows. Shell-side parameter expansion (`${TMPDIR:-/tmp}`, `$$`, `%TEMP%`) is forbidden because cmd.exe and PowerShell do not honor it.
|
|
41
41
|
|
|
42
|
-
When a PR exists: `
|
|
42
|
+
When a PR exists: call `pull_request_read(method="get_diff", pullNumber=N, owner=O, repo=R)` and save the returned diff content to `"<diff_temp_path>"`.
|
|
43
43
|
|
|
44
44
|
When falling back to merge-base diff: `git diff <merge-base>...HEAD > "<diff_temp_path>"`.
|
|
45
45
|
|
package/skills/fixbugs/SKILL.md
CHANGED
|
@@ -49,7 +49,7 @@ If the filtered set is empty, refuse per the refusal cases above.
|
|
|
49
49
|
|
|
50
50
|
Re-establish the same PR target `/findbugs` used:
|
|
51
51
|
|
|
52
|
-
1. `
|
|
52
|
+
1. `pull_request_read(method="get", pullNumber=N, owner=O, repo=R)` for the current branch (`N` comes from the parent skill's PR context, or fall back to `search_issues` MCP with the current branch name to recover the PR number).
|
|
53
53
|
2. Fall back to `git merge-base HEAD origin/<default>` then `git diff <merge-base>...HEAD`.
|
|
54
54
|
3. Neither → respond `No PR or upstream diff. Cannot scope fixes.` and stop.
|
|
55
55
|
|