@trashcodermaker/pr-review-handler 1.1.3 → 1.2.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trashcodermaker/pr-review-handler",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Systematically process GitHub PR review comments: triage for validity, fix code, and post replies. Agent skill usable from any agent harness (Pi, Claude Code, Cursor, Gemini CLI, OpenCode, etc.).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,7 +41,7 @@ Agent specs live in `agents/` relative to this skill (`agents/triage-agent.md`,
|
|
|
41
41
|
|
|
42
42
|
| Platform | Dispatch mechanism |
|
|
43
43
|
|----------|-------------------|
|
|
44
|
-
| Pi |
|
|
44
|
+
| Pi | `subagent` tool if [pi-subagents](https://www.npmjs.com/package/pi-subagents) is installed, else inline fallback |
|
|
45
45
|
| Claude Code | Task tool |
|
|
46
46
|
| Cursor | background agent |
|
|
47
47
|
| Gemini CLI / OpenCode / others | native subtask mechanism if available |
|
|
@@ -49,7 +49,9 @@ Agent specs live in `agents/` relative to this skill (`agents/triage-agent.md`,
|
|
|
49
49
|
|
|
50
50
|
**Dispatch pattern**: read the relevant agent spec, embed its instructions into the task prompt along with the thread-specific input data (thread info for triage, verdict data for implementation), and launch one subtask per thread. Triage is read-only so subtasks run in parallel; implementation writes files so it runs serially.
|
|
51
51
|
|
|
52
|
-
**
|
|
52
|
+
**Pi dispatch capability**: Pi does not bundle a subtask mechanism — it depends on the optional `pi-subagents` package (recommended in the project README). Check at runtime whether the `subagent` tool is present in your tool list: if present, use it (PARALLEL mode for triage, SINGLE mode serially for implementation); if absent, fall back to inline execution. Do not assume pi-subagents is installed, and do not error if it is missing — the skill degrades gracefully either way.
|
|
53
|
+
|
|
54
|
+
**Inline fallback**: if the `subagent` tool is not available (e.g. pi-subagents not installed) or the platform has no subtask mechanism, you (the orchestrator) read each spec and perform its steps yourself, one thread at a time. The specs are written as direct instructions, so inline execution is straightforward.
|
|
53
55
|
|
|
54
56
|
## Phase 0: Setup
|
|
55
57
|
|
|
@@ -100,7 +102,7 @@ Filter `isResolved: false`. Include full thread (not just top-level) — follow-
|
|
|
100
102
|
|
|
101
103
|
```bash
|
|
102
104
|
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
|
|
103
|
-
--jq 'group_by(.path, .original_commit_id) | map({
|
|
105
|
+
--jq 'group_by([.path, (.original_commit_id // "HEAD")]) | map({
|
|
104
106
|
thread_id: .[0].id, path: .[0].path,
|
|
105
107
|
comments: [.[] | {id, body, user: .user.login, line, in_reply_to_id}]
|
|
106
108
|
})'
|
|
@@ -117,16 +119,44 @@ gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews \
|
|
|
117
119
|
--jq 'sort_by(.submitted_at) | reverse | .[:5] | .[] | {id, state, user: .user.login, body}'
|
|
118
120
|
```
|
|
119
121
|
|
|
120
|
-
|
|
122
|
+
Present any non-empty review bodies in Checkpoint 1 (Phase 1) as a
|
|
123
|
+
separate **Review-level feedback** section. These are summary comments
|
|
124
|
+
without line references, so they do not go through the Triage Agent
|
|
125
|
+
automatically — the user decides how to handle each one (ignore / reply
|
|
126
|
+
only / needs code change). If the user marks one as needing a code change,
|
|
127
|
+
convert it into an Implementation task with `path: <overall PR>` and no
|
|
128
|
+
specific line; the Implementation Agent then works from the review body
|
|
129
|
+
text and the PR diff.
|
|
130
|
+
|
|
131
|
+
### Fetch PR diff
|
|
132
|
+
|
|
133
|
+
Triage needs to see what the PR actually changed — without it, the agent cannot
|
|
134
|
+
distinguish a problem the PR introduced from one that already existed in the
|
|
135
|
+
base branch.
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
gh pr diff {pr_number} > /tmp/pr-{pr_number}.diff
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Cache the diff to a temp file. When dispatching each Triage Agent in Phase 1,
|
|
142
|
+
pass only the hunks relevant to that thread's `path` as `pr_diff_context`. If
|
|
143
|
+
the total diff is small (< 500 lines), pass the full diff to every agent for
|
|
144
|
+
broader context.
|
|
121
145
|
|
|
122
146
|
## Phase 1: Triage (parallel dispatch)
|
|
123
147
|
|
|
124
148
|
### Dispatch strategy
|
|
125
149
|
|
|
126
|
-
Triage is read-only — safe to parallelize.
|
|
150
|
+
Triage is read-only — safe to parallelize. First detect dispatch capability:
|
|
151
|
+
|
|
152
|
+
- **Pi with `subagent` tool available** (pi-subagents installed): use PARALLEL mode — spawn one Triage Agent subtask per thread simultaneously. For implementation (Phase 2), use SINGLE mode serially — each fix is a separate subtask, one at a time, because fixes write files.
|
|
153
|
+
- **No `subagent` tool / no subtask mechanism**: run inline, same logic, one thread at a time.
|
|
154
|
+
|
|
155
|
+
Then choose a strategy based on thread count:
|
|
127
156
|
|
|
128
157
|
- **≥3 threads + parallel capability**: spawn one Triage Agent per thread simultaneously
|
|
129
158
|
- **≤2 threads or no parallel capability**: run inline, same logic
|
|
159
|
+
- **Large PR (> 15 threads)**: batch by file path to keep context manageable. Group threads sharing the same `path` into the same batch (they share `pr_diff_context`, saving tokens). Dispatch one batch at a time, 8–10 threads per batch. Collect verdicts across batches before presenting Checkpoint 1. This avoids spawning dozens of subagents at once, which can hit API rate limits and produce a verdict table too long for the user to review.
|
|
130
160
|
|
|
131
161
|
If unsure about parallel capability, default to inline.
|
|
132
162
|
|
|
@@ -142,13 +172,14 @@ comments:
|
|
|
142
172
|
- <top-level comment text>
|
|
143
173
|
- <reply 1, if any>
|
|
144
174
|
- <reply 2, if any>
|
|
175
|
+
pr_diff_context: <diff hunks for {path} from /tmp/pr-{pr_number}.diff, or full diff if PR is small>
|
|
145
176
|
```
|
|
146
177
|
|
|
147
178
|
Embed the Triage Agent spec (`agents/triage-agent.md`) into the task prompt so the subtask has the full role instructions and output format, then append the thread-specific data above. Collect structured verdicts from all agents.
|
|
148
179
|
|
|
149
180
|
### Checkpoint 1: User confirmation
|
|
150
181
|
|
|
151
|
-
Present verdicts as a summary table:
|
|
182
|
+
Present thread verdicts as a summary table:
|
|
152
183
|
|
|
153
184
|
| # | File:Line | Reviewer | Summary | Verdict | Affected Files |
|
|
154
185
|
|---|-----------|----------|---------|---------|----------------|
|
|
@@ -156,7 +187,21 @@ Present verdicts as a summary table:
|
|
|
156
187
|
| 2 | src/ui/Button.tsx:18 | bob | Rename for clarity | valid-fix | Button.tsx |
|
|
157
188
|
| 3 | src/api/handler.ts:99 | alice | Add rate limiting | invalid | — |
|
|
158
189
|
|
|
159
|
-
|
|
190
|
+
Then present the **Review-level feedback** section (summary comments
|
|
191
|
+
without line references, fetched in Phase 0):
|
|
192
|
+
|
|
193
|
+
| # | Reviewer | State | Body (excerpt) |
|
|
194
|
+
|---|----------|-------|----------------|
|
|
195
|
+
| R1 | alice | CHANGES_REQUESTED | "Overall solid, but the auth module needs a refactor — see thread #1" |
|
|
196
|
+
| R2 | bob | COMMENTED | "Please add tests for the token expiry edge case" |
|
|
197
|
+
|
|
198
|
+
For each review-level item, ask the user to choose:
|
|
199
|
+
|
|
200
|
+
- **Ignore** — no action needed (e.g. summary of already-addressed threads)
|
|
201
|
+
- **Reply only** — draft a clarification in Phase 3, no code change
|
|
202
|
+
- **Needs code change** — convert to an Implementation task: `path: <overall PR>`, no line, `summary: <review body>`, `affected_files: <user-specified or all PR files>`, `suggested_fix: <user describes>`. Dispatch in Phase 2.
|
|
203
|
+
|
|
204
|
+
User can adjust thread verdicts or skip threads. Proceed with confirmed plan.
|
|
160
205
|
|
|
161
206
|
### Quick exits
|
|
162
207
|
|
|
@@ -191,6 +236,8 @@ prior_changes: <list of previous fixes in this PR, if any>
|
|
|
191
236
|
|
|
192
237
|
Embed the Implementation Agent spec (`agents/implementation-agent.md`) into the task prompt so the subtask has the full role instructions, then append the verdict data above.
|
|
193
238
|
|
|
239
|
+
**Pi dispatch**: if the `subagent` tool is available, use SINGLE mode — one subtask per fix, awaited in turn (serial). Pass `prior_changes` by collecting each completed subtask's output and appending it to the next subtask's input. If `subagent` is unavailable, execute the Implementation Agent spec inline, one thread at a time.
|
|
240
|
+
|
|
194
241
|
After each agent completes:
|
|
195
242
|
|
|
196
243
|
```bash
|
|
@@ -202,15 +249,23 @@ If commit is empty (agent made no changes), skip.
|
|
|
202
249
|
|
|
203
250
|
### After all fixes
|
|
204
251
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
```
|
|
252
|
+
Run the project's type checker or equivalent verification. Detect the
|
|
253
|
+
project type and run the matching command — do not assume TypeScript:
|
|
208
254
|
|
|
209
|
-
|
|
255
|
+
| Project marker | Command |
|
|
256
|
+
| --- | --- |
|
|
257
|
+
| `tsconfig.json` | `npx tsc --noEmit` |
|
|
258
|
+
| `package.json` (no tsconfig) | `npm run lint --if-present` and `npm test --if-present` |
|
|
259
|
+
| `pyproject.toml` / `setup.py` | `ruff check .` then `mypy .` (if configured) |
|
|
260
|
+
| `go.mod` | `go build ./...` |
|
|
261
|
+
| `Cargo.toml` | `cargo check` |
|
|
262
|
+
| none recognized | skip; tell user to run the project's check manually |
|
|
263
|
+
|
|
264
|
+
If the check fails:
|
|
210
265
|
|
|
211
266
|
- Identify which commit introduced the error (`git bisect` or check error file paths)
|
|
212
267
|
- `git revert --no-commit {commit}` → fix the error → recommit
|
|
213
|
-
- Re-run
|
|
268
|
+
- Re-run the check until clean
|
|
214
269
|
|
|
215
270
|
Also check:
|
|
216
271
|
|
|
@@ -236,12 +291,38 @@ Draft one reply per thread, using `git diff origin/{branch}...HEAD` as ground tr
|
|
|
236
291
|
|
|
237
292
|
**valid-fix (succeeded)**: describe what was changed, referencing the reviewer's concern. If the fix differs from what the reviewer suggested, explain why.
|
|
238
293
|
|
|
294
|
+
Examples:
|
|
295
|
+
|
|
296
|
+
> Good (EN): "Added the null check at line 42 as you suggested — `user` can indeed be undefined when the session expires."
|
|
297
|
+
>
|
|
298
|
+
> Good (中文): "已在 42 行加了空值判断,session 过期时 `user` 确实可能为 undefined。"
|
|
299
|
+
>
|
|
300
|
+
> Good (EN, diverged from suggestion): "Your point about rate limiting is valid. Instead of a fixed window I used a token bucket in `rateLimit.ts` — it handles burst traffic better and the existing tests cover it."
|
|
301
|
+
|
|
239
302
|
**valid-fix (failed)**: acknowledge the concern was valid. Explain why the fix couldn't be applied (type conflict, dependency issue). Suggest next steps if possible ("will address in a follow-up PR"). Don't be apologetic — just factual.
|
|
240
303
|
|
|
304
|
+
Examples:
|
|
305
|
+
|
|
306
|
+
> Good (EN): "You're right that this should be typed more strictly, but the `User` interface is shared with the legacy auth module which expects `any`. I'll extract a `StrictUser` type in a follow-up PR to avoid breaking that module here."
|
|
307
|
+
>
|
|
308
|
+
> Good (中文): "这里确实该用更严格的类型,但 `User` 接口被旧 auth 模块共用且依赖 `any`。我会在后续 PR 里拆出 `StrictUser` 类型,避免这里改动波及该模块。"
|
|
309
|
+
|
|
241
310
|
**valid-nofix**: acknowledge the concern is valid. Explain why no code change is needed. Provide clarification if the reviewer misunderstood the code.
|
|
242
311
|
|
|
312
|
+
Examples:
|
|
313
|
+
|
|
314
|
+
> Good (EN): "Fair point on the naming — `handleX` is a bit vague. It's part of the public API documented in `docs/api.md`, so renaming would be a breaking change. I'll add a deprecation alias in the next major."
|
|
315
|
+
>
|
|
316
|
+
> Good (中文): "命名确实不够清晰,不过 `handleX` 是 `docs/api.md` 里记录的公开 API,重命名属于破坏性变更,下个大版本会加弃用别名。"
|
|
317
|
+
|
|
243
318
|
**invalid**: explain clearly why the premise doesn't apply. Reference specific code that already handles the concern. Acknowledge the reviewer's intent ("I see why you'd think X, but..."). Be respectful but direct — don't hedge if the concern is genuinely wrong.
|
|
244
319
|
|
|
320
|
+
Examples:
|
|
321
|
+
|
|
322
|
+
> Good (EN): "I see why you'd think the count could overflow here, but `items` is already capped at `MAX_ITEMS` (line 15) before this loop runs, so `i` stays well within `Number.MAX_SAFE_INTEGER`."
|
|
323
|
+
>
|
|
324
|
+
> Good (中文): "能理解你担心这里 count 溢出,但进入循环前 `items` 已在 15 行被 `MAX_ITEMS` 截断,`i` 始终远小于 `Number.MAX_SAFE_INTEGER`。"
|
|
325
|
+
|
|
245
326
|
### Reply guidelines
|
|
246
327
|
|
|
247
328
|
- Match the reviewer's language (Chinese reviewer → Chinese reply)
|
|
@@ -310,7 +391,7 @@ Output final summary:
|
|
|
310
391
|
| API rate limit | Wait for `X-RateLimit-Reset`, retry |
|
|
311
392
|
| PR closed/merged | Warn user — replies have no effect |
|
|
312
393
|
| GraphQL unsupported | Fall back to REST with resolved-thread caveat |
|
|
313
|
-
|
|
|
394
|
+
| Type check fails after all fixes | Fix before posting replies |
|
|
314
395
|
|
|
315
396
|
## Key Principles
|
|
316
397
|
|
|
@@ -23,14 +23,17 @@ comments:
|
|
|
23
23
|
- [top-level comment]
|
|
24
24
|
- [reply 1, if any]
|
|
25
25
|
- [reply 2, if any]
|
|
26
|
+
pr_diff_context: [diff hunks for this file from the PR, or full diff if PR is small]
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
## Steps
|
|
29
30
|
|
|
30
|
-
### 1. Read the referenced code
|
|
31
|
+
### 1. Read the referenced code and PR diff context
|
|
31
32
|
|
|
32
33
|
Open `{path}` and examine the code at `{line}` plus surrounding context (±20 lines minimum). Understand what the code does, what it depends on, and what depends on it.
|
|
33
34
|
|
|
35
|
+
Then read `pr_diff_context` — the diff hunks for this file from the PR. This tells you whether the code the reviewer commented on was introduced by this PR, modified by it, or already existed in the base branch. A concern about code the PR didn't touch is usually out of scope for this review.
|
|
36
|
+
|
|
34
37
|
### 2. Read the full thread carefully
|
|
35
38
|
|
|
36
39
|
The top-level comment may be refined, overridden, or clarified by follow-up replies. The actual concern may be in a reply, not the original comment. Weight later comments appropriately — they often represent the reviewer's evolved thinking.
|