@in-the-loop-labs/pair-review 1.6.1 → 2.0.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 (68) hide show
  1. package/README.md +77 -4
  2. package/package.json +1 -1
  3. package/plugin/.claude-plugin/plugin.json +1 -1
  4. package/plugin/skills/review-requests/SKILL.md +4 -1
  5. package/plugin-code-critic/.claude-plugin/plugin.json +1 -1
  6. package/plugin-code-critic/skills/analyze/SKILL.md +4 -3
  7. package/public/css/pr.css +1875 -144
  8. package/public/js/CONVENTIONS.md +16 -0
  9. package/public/js/components/AIPanel.js +66 -0
  10. package/public/js/components/AnalysisConfigModal.js +2 -2
  11. package/public/js/components/ChatPanel.js +2952 -0
  12. package/public/js/components/CouncilProgressModal.js +28 -18
  13. package/public/js/components/KeyboardShortcuts.js +3 -0
  14. package/public/js/components/PanelGroup.js +723 -0
  15. package/public/js/components/PreviewModal.js +3 -8
  16. package/public/js/components/StatusIndicator.js +2 -2
  17. package/public/js/components/Toast.js +22 -1
  18. package/public/js/components/VoiceCentricConfigTab.js +2 -2
  19. package/public/js/index.js +8 -0
  20. package/public/js/local.js +25 -682
  21. package/public/js/modules/analysis-history.js +19 -66
  22. package/public/js/modules/comment-manager.js +57 -19
  23. package/public/js/modules/diff-context.js +176 -0
  24. package/public/js/modules/diff-renderer.js +30 -0
  25. package/public/js/modules/file-comment-manager.js +126 -105
  26. package/public/js/modules/file-list-merger.js +64 -0
  27. package/public/js/modules/panel-resizer.js +25 -6
  28. package/public/js/modules/suggestion-manager.js +40 -125
  29. package/public/js/pr.js +974 -178
  30. package/public/js/repo-settings.js +36 -6
  31. package/public/js/utils/category-emoji.js +44 -0
  32. package/public/js/utils/time.js +32 -0
  33. package/public/local.html +107 -71
  34. package/public/pr.html +107 -71
  35. package/public/repo-settings.html +32 -0
  36. package/src/ai/analyzer.js +8 -4
  37. package/src/ai/claude-provider.js +22 -11
  38. package/src/ai/copilot-provider.js +39 -9
  39. package/src/ai/cursor-agent-provider.js +36 -7
  40. package/src/ai/gemini-provider.js +17 -4
  41. package/src/ai/prompts/config.js +7 -1
  42. package/src/ai/provider-availability.js +1 -1
  43. package/src/ai/provider.js +25 -37
  44. package/src/ai/stream-parser.js +1 -1
  45. package/src/chat/CONVENTIONS.md +18 -0
  46. package/src/chat/pi-bridge.js +491 -0
  47. package/src/chat/prompt-builder.js +262 -0
  48. package/src/chat/session-manager.js +619 -0
  49. package/src/config.js +14 -0
  50. package/src/database.js +322 -15
  51. package/src/main.js +4 -17
  52. package/src/routes/analyses.js +721 -0
  53. package/src/routes/chat.js +655 -0
  54. package/src/routes/config.js +29 -8
  55. package/src/routes/context-files.js +223 -0
  56. package/src/routes/local.js +225 -1133
  57. package/src/routes/mcp.js +39 -30
  58. package/src/routes/pr.js +410 -52
  59. package/src/routes/reviews.js +1035 -0
  60. package/src/routes/shared.js +5 -30
  61. package/src/server.js +34 -12
  62. package/src/sse/review-events.js +46 -0
  63. package/src/utils/auto-context.js +88 -0
  64. package/src/utils/category-emoji.js +33 -0
  65. package/src/utils/diff-file-list.js +57 -0
  66. package/public/js/components/ProgressModal.js +0 -705
  67. package/src/routes/analysis.js +0 -1600
  68. package/src/routes/comments.js +0 -534
@@ -7,8 +7,7 @@
7
7
  * - Voice participants as child rows under each level
8
8
  * - Consolidation section at the bottom
9
9
  *
10
- * Replaces ProgressModal when a council analysis is running.
11
- * The existing ProgressModal remains for single-model analysis.
10
+ * Handles both council and single-model analysis modes.
12
11
  */
13
12
  class CouncilProgressModal {
14
13
  constructor() {
@@ -22,9 +21,6 @@ class CouncilProgressModal {
22
21
 
23
22
  // Track per-voice completion state
24
23
  this._voiceStates = {};
25
- // Track SSE endpoint mode
26
- this._useLocalEndpoint = false;
27
- this._localReviewId = null;
28
24
 
29
25
  this._createModal();
30
26
  this._setupEventListeners();
@@ -132,7 +128,7 @@ class CouncilProgressModal {
132
128
  }
133
129
 
134
130
  try {
135
- await fetch(`/api/analyze/cancel/${this.currentAnalysisId}`, { method: 'POST' });
131
+ await fetch(`/api/analyses/${this.currentAnalysisId}/cancel`, { method: 'POST' });
136
132
  } catch (error) {
137
133
  console.warn('Cancel not available on server:', error.message);
138
134
  }
@@ -149,20 +145,21 @@ class CouncilProgressModal {
149
145
  }
150
146
 
151
147
  /**
152
- * Configure for local mode SSE endpoint.
153
- * @param {string|number} reviewId
148
+ * Configure for local mode.
149
+ * Retained as a public method since callers invoke it, but the SSE endpoint
150
+ * is now unified so no per-mode state is needed.
154
151
  */
155
- setLocalMode(reviewId) {
156
- this._useLocalEndpoint = true;
157
- this._localReviewId = reviewId;
152
+ setLocalMode(_reviewId) {
153
+ // no-op: SSE endpoint is unified
158
154
  }
159
155
 
160
156
  /**
161
- * Configure for PR mode SSE endpoint (default).
157
+ * Configure for PR mode (default).
158
+ * Retained as a public method since callers invoke it, but the SSE endpoint
159
+ * is now unified so no per-mode state is needed.
162
160
  */
163
161
  setPRMode() {
164
- this._useLocalEndpoint = false;
165
- this._localReviewId = null;
162
+ // no-op: SSE endpoint is unified
166
163
  }
167
164
 
168
165
  // ---------------------------------------------------------------------------
@@ -175,9 +172,7 @@ class CouncilProgressModal {
175
172
  }
176
173
  if (!this.currentAnalysisId) return;
177
174
 
178
- const sseUrl = this._useLocalEndpoint
179
- ? `/api/local/${this._localReviewId}/ai-suggestions/status`
180
- : `/api/pr/${this.currentAnalysisId}/ai-suggestions/status`;
175
+ const sseUrl = `/api/analyses/${this.currentAnalysisId}/progress`;
181
176
 
182
177
  this.eventSource = new EventSource(sseUrl);
183
178
 
@@ -229,7 +224,7 @@ class CouncilProgressModal {
229
224
  this.statusCheckInterval = setInterval(async () => {
230
225
  if (!this.currentAnalysisId) return;
231
226
  try {
232
- const response = await fetch(`/api/analyze/status/${this.currentAnalysisId}`);
227
+ const response = await fetch(`/api/analyses/${this.currentAnalysisId}/status`);
233
228
  if (!response.ok) throw new Error('Failed to fetch status');
234
229
  const status = await response.json();
235
230
  this.updateProgress(status);
@@ -673,6 +668,17 @@ class CouncilProgressModal {
673
668
 
674
669
  // Derive the parent header state from children
675
670
  this._refreshConsolidationHeader(iconEl, statusEl, state);
671
+
672
+ // Show stream event text in the snippet element (mirrors _updateSingleModelLevel logic)
673
+ const snippetEl = section.querySelector('.council-level-snippet');
674
+ if (snippetEl) {
675
+ if (state === 'running' && level4Status.streamEvent?.text) {
676
+ snippetEl.textContent = level4Status.streamEvent.text;
677
+ snippetEl.style.display = 'block';
678
+ } else if (state !== 'running') {
679
+ snippetEl.style.display = 'none';
680
+ }
681
+ }
676
682
  }
677
683
 
678
684
  /**
@@ -1128,6 +1134,7 @@ class CouncilProgressModal {
1128
1134
  <span class="council-level-title">Cross-Reviewer Consolidation</span>
1129
1135
  <span class="council-level-status pending">Pending</span>
1130
1136
  </div>
1137
+ <div class="council-level-snippet" style="display: none;"></div>
1131
1138
  </div>
1132
1139
  `;
1133
1140
 
@@ -1188,6 +1195,7 @@ class CouncilProgressModal {
1188
1195
  <span class="council-level-title">Consolidation</span>
1189
1196
  <span class="council-level-status pending">Pending</span>
1190
1197
  </div>
1198
+ <div class="council-level-snippet" style="display: none;"></div>
1191
1199
  </div>
1192
1200
  `;
1193
1201
 
@@ -1327,6 +1335,7 @@ class CouncilProgressModal {
1327
1335
  <span class="council-level-title">Consolidation</span>
1328
1336
  <span class="council-level-status pending">Pending</span>
1329
1337
  </div>
1338
+ <div class="council-level-snippet" style="display: none;"></div>
1330
1339
  </div>
1331
1340
  `;
1332
1341
  }
@@ -1338,6 +1347,7 @@ class CouncilProgressModal {
1338
1347
  <span class="council-level-title">Consolidation</span>
1339
1348
  <span class="council-level-status pending">Pending</span>
1340
1349
  </div>
1350
+ <div class="council-level-snippet" style="display: none;"></div>
1341
1351
  <div class="council-level-children">
1342
1352
  `;
1343
1353
 
@@ -142,6 +142,7 @@ class KeyboardShortcuts {
142
142
  const groups = {
143
143
  navigation: { title: 'Navigation', shortcuts: [] },
144
144
  comments: { title: 'Comments', shortcuts: [] },
145
+ panels: { title: 'Panels', shortcuts: [] },
145
146
  general: { title: 'General', shortcuts: [] }
146
147
  };
147
148
 
@@ -154,6 +155,8 @@ class KeyboardShortcuts {
154
155
  groups.navigation.shortcuts.push(item);
155
156
  } else if (keys[0] === 'c') {
156
157
  groups.comments.shortcuts.push(item);
158
+ } else if (keys[0] === 'p') {
159
+ groups.panels.shortcuts.push(item);
157
160
  } else {
158
161
  groups.general.shortcuts.push(item);
159
162
  }