@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.1.3",
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 | inline fallback (no native subtask mechanism) |
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
- **Inline fallback**: if your 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.
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
- Include any non-empty review bodies alongside the thread data when presenting to the user in Phase 2.
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
- User can adjust verdicts or skip threads. Proceed with confirmed plan.
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
- ```bash
206
- npx tsc --noEmit
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
- If tsc fails:
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 tsc until clean
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
- | tsc fails after all fixes | Fix before posting replies |
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.