@in-the-loop-labs/pair-review 2.3.2 → 2.4.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.
Files changed (47) hide show
  1. package/.pi/skills/review-model-guidance/SKILL.md +1 -1
  2. package/.pi/skills/review-roulette/SKILL.md +1 -1
  3. package/README.md +15 -1
  4. package/package.json +2 -1
  5. package/plugin/.claude-plugin/plugin.json +1 -1
  6. package/plugin/skills/review-requests/SKILL.md +1 -1
  7. package/plugin-code-critic/.claude-plugin/plugin.json +1 -1
  8. package/public/css/pr.css +296 -15
  9. package/public/index.html +121 -57
  10. package/public/js/components/AIPanel.js +2 -1
  11. package/public/js/components/AdvancedConfigTab.js +2 -2
  12. package/public/js/components/AnalysisConfigModal.js +2 -2
  13. package/public/js/components/ChatPanel.js +187 -28
  14. package/public/js/components/CouncilProgressModal.js +4 -7
  15. package/public/js/components/SplitButton.js +66 -1
  16. package/public/js/components/VoiceCentricConfigTab.js +2 -2
  17. package/public/js/index.js +274 -21
  18. package/public/js/modules/comment-manager.js +16 -12
  19. package/public/js/modules/file-comment-manager.js +8 -6
  20. package/public/js/pr.js +194 -5
  21. package/public/local.html +8 -1
  22. package/public/pr.html +17 -2
  23. package/src/ai/codex-provider.js +14 -2
  24. package/src/ai/copilot-provider.js +1 -10
  25. package/src/ai/cursor-agent-provider.js +1 -10
  26. package/src/ai/gemini-provider.js +8 -17
  27. package/src/chat/acp-bridge.js +442 -0
  28. package/src/chat/api-reference.js +539 -0
  29. package/src/chat/chat-providers.js +290 -0
  30. package/src/chat/claude-code-bridge.js +499 -0
  31. package/src/chat/codex-bridge.js +601 -0
  32. package/src/chat/pi-bridge.js +56 -3
  33. package/src/chat/prompt-builder.js +12 -11
  34. package/src/chat/session-manager.js +110 -29
  35. package/src/config.js +4 -2
  36. package/src/database.js +50 -2
  37. package/src/github/client.js +43 -0
  38. package/src/routes/chat.js +60 -27
  39. package/src/routes/config.js +24 -1
  40. package/src/routes/github-collections.js +126 -0
  41. package/src/routes/mcp.js +2 -1
  42. package/src/routes/pr.js +166 -2
  43. package/src/routes/reviews.js +2 -1
  44. package/src/routes/shared.js +70 -49
  45. package/src/server.js +27 -1
  46. package/src/utils/safe-parse-json.js +19 -0
  47. package/.pi/skills/pair-review-api/SKILL.md +0 -448
@@ -1,448 +0,0 @@
1
- ---
2
- name: pair-review-api
3
- description: Reference for the pair-review HTTP API. Load this skill to create, update, and delete review comments, adopt or dismiss AI suggestions, manage context files, expand diff hunks, and trigger or monitor analyses via curl.
4
- ---
5
-
6
- # Pair-Review API Skill
7
-
8
- You have **read-only access to the filesystem**. To modify the review (create comments, adopt suggestions, trigger analysis) or interact with the pair-review app, you MUST use the pair-review API via `curl`.
9
-
10
- The pair-review server base URL (including port) is provided **per-turn** in the message context (e.g., `[Server port: 7247] The pair-review API is at http://localhost:7247`). The port may change between server restarts, so always use the port from the most recent message context. All endpoints accept and return JSON.
11
-
12
- ## Comments
13
-
14
- All comment operations use a single set of unified endpoints.
15
-
16
- ### List all comments
17
-
18
- ```bash
19
- curl -s http://localhost:PORT/api/reviews/REVIEW_ID/comments
20
- ```
21
-
22
- Optional query param: `includeDismissed=true` to include soft-deleted (inactive) comments.
23
-
24
- **Response:** `{ "success": true, "comments": [...] }`
25
-
26
- ### Create a comment
27
-
28
- A single endpoint handles both line-level and file-level comments. If `line_start` is present, it creates a line-level comment; if omitted, it creates a file-level comment.
29
-
30
- **Line-level comment:**
31
- ```bash
32
- curl -s -X POST http://localhost:PORT/api/reviews/REVIEW_ID/comments \
33
- -H 'Content-Type: application/json' \
34
- -d '{
35
- "file": "src/example.js",
36
- "line_start": 42,
37
- "line_end": 42,
38
- "side": "right",
39
- "body": "This variable should be renamed for clarity.",
40
- "type": "suggestion",
41
- "title": "Rename variable"
42
- }'
43
- ```
44
-
45
- **File-level comment (omit `line_start`):**
46
- ```bash
47
- curl -s -X POST http://localhost:PORT/api/reviews/REVIEW_ID/comments \
48
- -H 'Content-Type: application/json' \
49
- -d '{
50
- "file": "src/example.js",
51
- "body": "This file needs better error handling throughout.",
52
- "type": "suggestion",
53
- "title": "Error handling"
54
- }'
55
- ```
56
-
57
- **Response:** `{ "success": true, "commentId": 123, "message": "Comment saved successfully" }`
58
-
59
- Required fields: `file`, `body`.
60
- Optional fields: `line_start`, `line_end`, `side` ("left" or "right"), `diff_position`, `commit_sha`, `parent_id`, `type`, `title`.
61
-
62
- ### Get a single comment
63
-
64
- ```bash
65
- curl -s http://localhost:PORT/api/reviews/REVIEW_ID/comments/COMMENT_ID
66
- ```
67
-
68
- ### Update a comment
69
-
70
- ```bash
71
- curl -s -X PUT http://localhost:PORT/api/reviews/REVIEW_ID/comments/COMMENT_ID \
72
- -H 'Content-Type: application/json' \
73
- -d '{ "body": "Updated comment text." }'
74
- ```
75
-
76
- **Response:** `{ "success": true, "message": "Comment updated successfully" }`
77
-
78
- ### Delete a comment
79
-
80
- > **Terminology note:** The UI refers to this operation as "dismiss." When a user asks to "dismiss a comment," use this DELETE endpoint.
81
-
82
- Soft-deletes the comment. If the comment was adopted from an AI suggestion, the parent suggestion is automatically transitioned to "dismissed" status.
83
-
84
- ```bash
85
- curl -s -X DELETE http://localhost:PORT/api/reviews/REVIEW_ID/comments/COMMENT_ID
86
- ```
87
-
88
- **Response:** `{ "success": true, "message": "Comment deleted successfully", "dismissedSuggestionId": null }`
89
-
90
- ### Restore a deleted comment
91
-
92
- ```bash
93
- curl -s -X PUT http://localhost:PORT/api/reviews/REVIEW_ID/comments/COMMENT_ID/restore
94
- ```
95
-
96
- **Response:** `{ "success": true, "message": "Comment restored successfully", "comment": {...} }`
97
-
98
- ### Bulk delete all comments
99
-
100
- Deletes all user comments for a review. Also dismisses any parent AI suggestions.
101
-
102
- ```bash
103
- curl -s -X DELETE http://localhost:PORT/api/reviews/REVIEW_ID/comments
104
- ```
105
-
106
- **Response:** `{ "success": true, "deletedCount": 5, "dismissedSuggestionIds": [...], "message": "Deleted 5 user comments" }`
107
-
108
- ---
109
-
110
- ## Suggestions
111
-
112
- All suggestion operations use unified endpoints. These work identically for both PR and local reviews.
113
-
114
- ### List AI suggestions
115
-
116
- ```bash
117
- curl -s 'http://localhost:PORT/api/reviews/REVIEW_ID/suggestions'
118
- ```
119
-
120
- Optional query params:
121
- - `levels` — comma-separated list of levels: `"final"`, `"1"`, `"2"`, `"3"`. Default: `"final"` (orchestrated suggestions only).
122
- - `runId` — specific analysis run UUID. Default: latest run.
123
-
124
- **Response:** `{ "suggestions": [{ "id": 1, "file": "...", "line_start": 10, "type": "bug", "title": "...", "body": "...", "status": "active", ... }] }`
125
-
126
- ### Check if suggestions exist
127
-
128
- ```bash
129
- curl -s 'http://localhost:PORT/api/reviews/REVIEW_ID/suggestions/check'
130
- ```
131
-
132
- Optional query param: `runId` (specific analysis run UUID).
133
-
134
- **Response:** `{ "hasSuggestions": true, "analysisHasRun": true, "summary": "...", "stats": { "issues": 2, "suggestions": 3, "praise": 1 } }`
135
-
136
- ### Update AI suggestion status
137
-
138
- ```bash
139
- curl -s -X POST http://localhost:PORT/api/reviews/REVIEW_ID/suggestions/SUGGESTION_ID/status \
140
- -H 'Content-Type: application/json' \
141
- -d '{ "status": "dismissed" }'
142
- ```
143
-
144
- Valid statuses: `"dismissed"`, `"active"` (restore).
145
-
146
- > **Note:** Setting status to `"adopted"` directly is not allowed. Adoption must create a linked user comment via `parent_id`, which is why raw status-setting cannot do it. Use `POST /suggestions/:id/adopt` for adopt-as-is or `POST /suggestions/:id/edit` for adopt-with-edits.
147
-
148
- **Response:** `{ "success": true, "status": "dismissed" }`
149
-
150
- ### Adopt an AI suggestion as-is
151
-
152
- Atomically creates a user comment from the suggestion's body/type/title (with category prefix), sets `parent_id` linkage, and updates suggestion status to `adopted`.
153
-
154
- ```bash
155
- curl -s -X POST http://localhost:PORT/api/reviews/REVIEW_ID/suggestions/SUGGESTION_ID/adopt
156
- ```
157
-
158
- No request body required.
159
-
160
- **Response:** `{ "success": true, "userCommentId": 124, "message": "Suggestion adopted as user comment" }`
161
-
162
- ### Adopt an AI suggestion with edits
163
-
164
- Edits the suggestion text and adopts it as a new user comment.
165
-
166
- ```bash
167
- curl -s -X POST http://localhost:PORT/api/reviews/REVIEW_ID/suggestions/SUGGESTION_ID/edit \
168
- -H 'Content-Type: application/json' \
169
- -d '{
170
- "action": "adopt_edited",
171
- "editedText": "The edited comment body to adopt as a user comment."
172
- }'
173
- ```
174
-
175
- **Response:** `{ "success": true, "userCommentId": 125, "message": "Suggestion edited and adopted as user comment" }`
176
-
177
- ---
178
-
179
- ## Analysis Launch
180
-
181
- Analysis launch endpoints are **mode-specific** because starting an analysis requires mode-specific context (worktree paths for PRs, local directory paths for local reviews). Once launched, all subsequent analysis management uses the shared endpoints below.
182
-
183
- ### Trigger AI analysis (PR mode)
184
-
185
- ```bash
186
- curl -s -X POST http://localhost:PORT/api/pr/OWNER/REPO/PR_NUMBER/analyses \
187
- -H 'Content-Type: application/json' \
188
- -d '{
189
- "provider": "claude",
190
- "model": "claude-sonnet-4-5-20250929",
191
- "tier": "balanced",
192
- "customInstructions": "Focus on security issues."
193
- }'
194
- ```
195
-
196
- ### Trigger AI analysis (local mode)
197
-
198
- ```bash
199
- curl -s -X POST http://localhost:PORT/api/local/REVIEW_ID/analyses \
200
- -H 'Content-Type: application/json' \
201
- -d '{
202
- "provider": "claude",
203
- "tier": "balanced",
204
- "customInstructions": "Focus on security issues."
205
- }'
206
- ```
207
-
208
- **Response (both modes):** `{ "analysisId": "uuid", "runId": "uuid", "status": "started", "message": "AI analysis started in background" }`
209
-
210
- Optional body fields: `provider`, `model`, `tier` ("fast", "balanced", "thorough"), `customInstructions`, `skipLevel3` (boolean), `enabledLevels` (object like `{"1": true, "2": true, "3": false}`).
211
-
212
- ### Trigger council analysis (PR mode)
213
-
214
- ```bash
215
- curl -s -X POST http://localhost:PORT/api/pr/OWNER/REPO/PR_NUMBER/analyses/council \
216
- -H 'Content-Type: application/json' \
217
- -d '{
218
- "councilId": "COUNCIL_UUID",
219
- "customInstructions": "Focus on security."
220
- }'
221
- ```
222
-
223
- ### Trigger council analysis (local mode)
224
-
225
- ```bash
226
- curl -s -X POST http://localhost:PORT/api/local/REVIEW_ID/analyses/council \
227
- -H 'Content-Type: application/json' \
228
- -d '{
229
- "councilId": "COUNCIL_UUID",
230
- "customInstructions": "Focus on security."
231
- }'
232
- ```
233
-
234
- **Response (both modes):** `{ "analysisId": "uuid", "runId": "uuid", "status": "started", "message": "Council analysis started in background", "isCouncil": true }`
235
-
236
- Required: either `councilId` (UUID of a saved council config) or `councilConfig` (inline config object).
237
- Optional: `customInstructions`, `configType` ("advanced" or "council").
238
-
239
- ---
240
-
241
- ## Analysis Status (Review-Level)
242
-
243
- Check whether an analysis is currently running for a review. This is a unified endpoint that works for both PR and local reviews.
244
-
245
- ```bash
246
- curl -s http://localhost:PORT/api/reviews/REVIEW_ID/analyses/status
247
- ```
248
-
249
- **Response (running):** `{ "running": true, "analysisId": "uuid", "status": {...} }`
250
- **Response (idle):** `{ "running": false, "analysisId": null, "status": null }`
251
-
252
- ---
253
-
254
- ## Analysis Management
255
-
256
- These shared endpoints operate on analysis UUIDs (returned when you launch an analysis). They work for both PR and local reviews.
257
-
258
- ### Get analysis status by ID
259
-
260
- ```bash
261
- curl -s http://localhost:PORT/api/analyses/ANALYSIS_ID/status
262
- ```
263
-
264
- **Response:** `{ "id": "...", "status": "running"|"completed"|"failed"|"cancelled", "levels": {...}, "progress": "...", ... }`
265
-
266
- ### Cancel an analysis
267
-
268
- ```bash
269
- curl -s -X POST http://localhost:PORT/api/analyses/ANALYSIS_ID/cancel
270
- ```
271
-
272
- **Response:** `{ "success": true, "message": "Analysis cancelled", "processesKilled": 2, "status": "cancelled" }`
273
-
274
- ### SSE progress stream
275
-
276
- Connect to receive real-time progress events for a running analysis:
277
-
278
- ```bash
279
- curl -s -N http://localhost:PORT/api/analyses/ANALYSIS_ID/progress
280
- ```
281
-
282
- This is a Server-Sent Events (SSE) stream. Events are JSON objects with `type`, `status`, `levels`, `progress`, etc.
283
-
284
- ### List analysis runs for a review
285
-
286
- ```bash
287
- curl -s 'http://localhost:PORT/api/analyses/runs?reviewId=REVIEW_ID'
288
- ```
289
-
290
- **Response:** `{ "runs": [{ "id": "uuid", "review_id": 1, "provider": "claude", "status": "completed", ... }] }`
291
-
292
- ### Get latest analysis run for a review
293
-
294
- ```bash
295
- curl -s 'http://localhost:PORT/api/analyses/runs/latest?reviewId=REVIEW_ID'
296
- ```
297
-
298
- **Response:** `{ "run": { "id": "uuid", "review_id": 1, "provider": "claude", "status": "completed", ... } }`
299
-
300
- ### Get a specific analysis run by ID
301
-
302
- ```bash
303
- curl -s http://localhost:PORT/api/analyses/runs/RUN_ID
304
- ```
305
-
306
- **Response:** `{ "run": { "id": "uuid", ... } }`
307
-
308
- ### Import external analysis results
309
-
310
- Submit analysis results produced outside pair-review (e.g., by a coding agent):
311
-
312
- ```bash
313
- curl -s -X POST http://localhost:PORT/api/analyses/results \
314
- -H 'Content-Type: application/json' \
315
- -d '{
316
- "path": "/absolute/path/to/repo",
317
- "headSha": "abc123",
318
- "provider": "claude",
319
- "summary": "Analysis summary text",
320
- "suggestions": [
321
- {
322
- "file": "src/example.js",
323
- "line_start": 10,
324
- "line_end": 15,
325
- "type": "bug",
326
- "title": "Potential null reference",
327
- "description": "This could throw if input is null."
328
- }
329
- ],
330
- "fileLevelSuggestions": []
331
- }'
332
- ```
333
-
334
- Required: either `path` + `headSha` (local mode) or `repo` + `prNumber` (PR mode).
335
- Each suggestion requires: `file`, `type`, `title`, `description`.
336
-
337
- **Response (HTTP 201):** `{ "runId": "uuid", "reviewId": 1, "totalSuggestions": 5, "status": "completed" }`
338
-
339
- ---
340
-
341
- ## Comment Types
342
-
343
- The `type` field on comments and suggestions can be one of:
344
- - `"bug"` - Bug or defect
345
- - `"suggestion"` - General suggestion
346
- - `"improvement"` - Code improvement
347
- - `"security"` - Security concern
348
- - `"performance"` - Performance issue
349
- - `"design"` - Design/architecture concern
350
- - `"praise"` - Positive feedback
351
- - `"style"` or `"code-style"` - Style/formatting
352
- - `"nitpick"` - Minor nitpick
353
- - `"question"` - Question for the author
354
-
355
- ---
356
-
357
- ## Context Files
358
-
359
- Add non-diff files to the review's diff panel for reference during discussion. Each context file shows a specific line range from a file that isn't part of the PR/local changes.
360
-
361
- ### Add a context file
362
-
363
- ```bash
364
- curl -s -X POST http://localhost:PORT/api/reviews/REVIEW_ID/context-files \
365
- -H 'Content-Type: application/json' \
366
- -d '{
367
- "file": "src/utils/helpers.js",
368
- "line_start": 42,
369
- "line_end": 78,
370
- "label": "Helper function used by the changed code"
371
- }'
372
- ```
373
-
374
- **Response (HTTP 201):** `{ "success": true, "contextFile": { "id": 1, "review_id": 1, "file": "...", "line_start": 42, "line_end": 78, "label": "..." } }`
375
-
376
- Required fields: `file` (must be a relative path without `..` segments), `line_start`, `line_end`.
377
- Optional fields: `label`.
378
-
379
- ### List context files
380
-
381
- ```bash
382
- curl -s http://localhost:PORT/api/reviews/REVIEW_ID/context-files
383
- ```
384
-
385
- **Response:** `{ "success": true, "contextFiles": [...] }`
386
-
387
- ### Remove a context file
388
-
389
- ```bash
390
- curl -s -X DELETE http://localhost:PORT/api/reviews/REVIEW_ID/context-files/CONTEXT_FILE_ID
391
- ```
392
-
393
- **Response:** `{ "success": true, "message": "Context file removed" }`
394
-
395
- ### Remove all context files
396
-
397
- ```bash
398
- curl -s -X DELETE http://localhost:PORT/api/reviews/REVIEW_ID/context-files
399
- ```
400
-
401
- **Response:** `{ "success": true, "deletedCount": 3, "message": "Removed 3 context files" }`
402
-
403
- ### Guidelines
404
-
405
- - Use judiciously -- only add files that are directly relevant to the discussion.
406
- - Keep ranges focused on specific functions/blocks (max 500 lines).
407
- - Use the `label` field to explain why the file is relevant.
408
- - Context files appear in the diff panel below the actual changes.
409
- - Reference context files in chat using backtick notation: `` `src/utils/helpers.js:42-78` ``.
410
-
411
- ---
412
-
413
- ## Diff Hunk Expansion
414
-
415
- Expand collapsed diff gaps to reveal hidden lines. Useful when you need to show the user lines that are inside a collapsed hunk. This is a transient UI command — expansions are not persisted.
416
-
417
- ### Expand a hunk
418
-
419
- ```bash
420
- curl -X POST http://localhost:PORT/api/reviews/REVIEW_ID/expand-hunk \
421
- -H "Content-Type: application/json" \
422
- -d '{
423
- "file": "src/app.js",
424
- "line_start": 10,
425
- "line_end": 20,
426
- "side": "right"
427
- }'
428
- ```
429
-
430
- **Required fields:**
431
- - `file` (string): Path of the changed file in the diff
432
- - `line_start` (integer): First line to reveal (≥ 1)
433
- - `line_end` (integer): Last line to reveal (≥ `line_start`)
434
-
435
- **Optional fields:**
436
- - `side` (string): `"left"` or `"right"` (default: `"right"`)
437
-
438
- **Response:** `{ "success": true }`
439
-
440
- ---
441
-
442
- ## Notes
443
-
444
- - Replace `PORT`, `REVIEW_ID`, `OWNER`, `REPO`, `PR_NUMBER`, `COMMENT_ID`, `SUGGESTION_ID`, `ANALYSIS_ID`, `RUN_ID`, and `CONTEXT_FILE_ID` with actual values from the review context.
445
- - `REVIEW_ID` is the integer review ID from the `reviews` table. It is the same for both PR and local reviews and is provided in your system prompt context.
446
- - `ANALYSIS_ID` and `RUN_ID` are UUIDs returned when an analysis is launched.
447
- - All POST/PUT/DELETE endpoints return `{ "success": true, ... }` on success.
448
- - Error responses have the shape `{ "error": "description" }` with appropriate HTTP status codes.