@in-the-loop-labs/pair-review 3.9.0 → 3.9.1

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": "@in-the-loop-labs/pair-review",
3
- "version": "3.9.0",
3
+ "version": "3.9.1",
4
4
  "description": "Your AI-powered code review partner - Close the feedback loop with AI coding agents",
5
5
  "main": "src/server.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pair-review",
3
- "version": "3.9.0",
3
+ "version": "3.9.1",
4
4
  "description": "pair-review app integration — Open PRs and local changes in the pair-review web UI, run server-side AI analysis, and address review feedback. Requires the pair-review MCP server.",
5
5
  "author": {
6
6
  "name": "in-the-loop-labs",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-critic",
3
- "version": "3.9.0",
3
+ "version": "3.9.1",
4
4
  "description": "AI-powered code review analysis — Run three-level AI analysis and implement-review-fix loops directly in your coding agent. Works standalone, no server required.",
5
5
  "author": {
6
6
  "name": "in-the-loop-labs",
package/public/css/pr.css CHANGED
@@ -6939,66 +6939,6 @@ body:not([data-theme="dark"]) .theme-icon-light {
6939
6939
  border-color: var(--color-border-secondary);
6940
6940
  }
6941
6941
 
6942
- /* ============================================
6943
- Analysis Progress Dots
6944
- ============================================ */
6945
-
6946
- .analysis-progress-dots {
6947
- display: flex;
6948
- align-items: center;
6949
- gap: 6px;
6950
- margin-right: 8px;
6951
- }
6952
-
6953
- .progress-dot {
6954
- width: 8px;
6955
- height: 8px;
6956
- border-radius: 50%;
6957
- border: 1.5px solid var(--color-accent-ai);
6958
- background: transparent;
6959
- transition: all 0.3s ease;
6960
- }
6961
-
6962
- .progress-dot.active {
6963
- animation: pulse-dot 1.2s ease-in-out infinite;
6964
- }
6965
-
6966
- .progress-dot.completed {
6967
- background: var(--color-accent-ai);
6968
- border-color: var(--color-accent-ai);
6969
- }
6970
-
6971
- .progress-dot.error {
6972
- background: #ef4444;
6973
- border-color: #ef4444;
6974
- }
6975
-
6976
- @keyframes pulse-dot {
6977
- 0%, 100% {
6978
- transform: scale(1);
6979
- opacity: 1;
6980
- }
6981
- 50% {
6982
- transform: scale(1.3);
6983
- opacity: 0.9;
6984
- }
6985
- }
6986
-
6987
- /* Dark theme for progress dots */
6988
- [data-theme="dark"] .progress-dot {
6989
- border-color: var(--color-accent-ai-dark);
6990
- }
6991
-
6992
- [data-theme="dark"] .progress-dot.completed {
6993
- background: var(--color-accent-ai-dark);
6994
- border-color: var(--color-accent-ai-dark);
6995
- }
6996
-
6997
- [data-theme="dark"] .progress-dot.error {
6998
- background: #f87171;
6999
- border-color: #f87171;
7000
- }
7001
-
7002
6942
  /* Magical Analyze Button - Amber AI CTA */
7003
6943
  #analyze-btn {
7004
6944
  background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
@@ -12959,6 +12899,18 @@ body.resizing * {
12959
12899
  animation: pulse-dot 1.2s ease-in-out infinite;
12960
12900
  }
12961
12901
 
12902
+ /* Pulse used by the running/setting-up stack-progress status icons above. */
12903
+ @keyframes pulse-dot {
12904
+ 0%, 100% {
12905
+ transform: scale(1);
12906
+ opacity: 1;
12907
+ }
12908
+ 50% {
12909
+ transform: scale(1.3);
12910
+ opacity: 0.9;
12911
+ }
12912
+ }
12913
+
12962
12914
  .status-pending .stack-progress-status-icon {
12963
12915
  color: var(--color-text-muted, #d1d9e0);
12964
12916
  }
@@ -304,16 +304,6 @@ class CouncilProgressModal {
304
304
  }
305
305
  }
306
306
 
307
- // Update toolbar progress dots
308
- const manager = window.prManager || window.localManager;
309
- if (manager?.updateProgressDot) {
310
- for (let level = 1; level <= 4; level++) {
311
- if (status.levels[level]) {
312
- manager.updateProgressDot(level, status.levels[level].status);
313
- }
314
- }
315
- }
316
-
317
307
  // Terminal states
318
308
  if (status.status === 'completed') {
319
309
  this._handleCompletion(status);
@@ -1893,55 +1893,6 @@ class LocalManager {
1893
1893
  };
1894
1894
  document.addEventListener('keydown', keyHandler);
1895
1895
  }
1896
-
1897
- /**
1898
- * Get the progress dots container element
1899
- * @returns {HTMLElement|null}
1900
- */
1901
- getProgressDotsContainer() {
1902
- return document.getElementById('analysis-progress-dots');
1903
- }
1904
-
1905
- /**
1906
- * Update a specific progress dot during analysis
1907
- * Maps level numbers to phase names:
1908
- * - Level 4 -> orchestration (finalization)
1909
- * - Level 1 -> level1
1910
- * - Level 2 -> level2
1911
- * - Level 3 -> level3
1912
- * @param {number} level - The level number (1, 2, 3, or 4)
1913
- * @param {string} status - The status ('running', 'completed', 'failed')
1914
- */
1915
- updateProgressDot(level, status) {
1916
- const container = this.getProgressDotsContainer();
1917
- if (!container) return;
1918
-
1919
- // Map levels to dot phases
1920
- const phaseMap = {
1921
- 4: 'orchestration', // Orchestration/finalization is level 4 in progress modal
1922
- 1: 'level1',
1923
- 2: 'level2',
1924
- 3: 'level3'
1925
- };
1926
-
1927
- const phase = phaseMap[level];
1928
- if (!phase) return;
1929
-
1930
- const dot = container.querySelector(`[data-phase="${phase}"]`);
1931
- if (!dot) return;
1932
-
1933
- // Remove existing states
1934
- dot.classList.remove('active', 'completed', 'error');
1935
-
1936
- // Apply new state
1937
- if (status === 'running') {
1938
- dot.classList.add('active');
1939
- } else if (status === 'completed') {
1940
- dot.classList.add('completed');
1941
- } else if (status === 'failed') {
1942
- dot.classList.add('error');
1943
- }
1944
- }
1945
1896
  }
1946
1897
 
1947
1898
  // Initialize LocalManager when in local mode
package/public/js/pr.js CHANGED
@@ -6588,9 +6588,6 @@ class PRManager {
6588
6588
  } else {
6589
6589
  btn.innerHTML = '<span class="analyzing-icon">✨</span> Analyzing...';
6590
6590
  }
6591
-
6592
- // Show progress dots
6593
- this.showProgressDots();
6594
6591
  }
6595
6592
 
6596
6593
  /**
@@ -6615,9 +6612,6 @@ class PRManager {
6615
6612
  }
6616
6613
  btn.disabled = true;
6617
6614
 
6618
- // Complete all progress dots (they'll be hidden when button resets)
6619
- this.completeAllProgressDots();
6620
-
6621
6615
  // Revert to normal after 2 seconds
6622
6616
  setTimeout(() => this.resetButton(), 2000);
6623
6617
  }
@@ -6645,114 +6639,6 @@ class PRManager {
6645
6639
  } else {
6646
6640
  btn.innerHTML = 'Analyze with AI';
6647
6641
  }
6648
-
6649
- // Hide progress dots when resetting
6650
- this.hideProgressDots();
6651
- }
6652
-
6653
- // ============================================
6654
- // Progress Dots Controller
6655
- // ============================================
6656
-
6657
- /**
6658
- * Get the progress dots container
6659
- * @returns {HTMLElement|null}
6660
- */
6661
- getProgressDotsContainer() {
6662
- return document.getElementById('analysis-progress-dots');
6663
- }
6664
-
6665
- /**
6666
- * Show progress dots (called when analysis starts)
6667
- */
6668
- showProgressDots() {
6669
- const container = this.getProgressDotsContainer();
6670
- if (!container) return;
6671
-
6672
- container.style.display = 'flex';
6673
-
6674
- // Reset all dots to initial state
6675
- const dots = container.querySelectorAll('.progress-dot');
6676
- dots.forEach(dot => {
6677
- dot.classList.remove('active', 'completed', 'error');
6678
- });
6679
-
6680
- // Set first dot (orchestration) as active
6681
- const firstDot = container.querySelector('[data-phase="orchestration"]');
6682
- if (firstDot) {
6683
- firstDot.classList.add('active');
6684
- }
6685
- }
6686
-
6687
- /**
6688
- * Hide progress dots (called when analysis completes or is cancelled)
6689
- */
6690
- hideProgressDots() {
6691
- const container = this.getProgressDotsContainer();
6692
- if (!container) return;
6693
-
6694
- container.style.display = 'none';
6695
-
6696
- // Reset all dots
6697
- const dots = container.querySelectorAll('.progress-dot');
6698
- dots.forEach(dot => {
6699
- dot.classList.remove('active', 'completed', 'error');
6700
- });
6701
- }
6702
-
6703
- /**
6704
- * Update progress dots based on level status
6705
- * Maps level numbers to phases:
6706
- * - Level 4 (orchestration/finalization) -> orchestration
6707
- * - Level 1 -> level1
6708
- * - Level 2 -> level2
6709
- * - Level 3 -> level3
6710
- * @param {number} level - The level number (1, 2, 3, or 4)
6711
- * @param {string} status - The status ('running', 'completed', 'failed')
6712
- */
6713
- updateProgressDot(level, status) {
6714
- const container = this.getProgressDotsContainer();
6715
- if (!container) return;
6716
-
6717
- // Map levels to dot phases
6718
- const phaseMap = {
6719
- 4: 'orchestration', // Orchestration/finalization is level 4 in progress modal
6720
- 1: 'level1',
6721
- 2: 'level2',
6722
- 3: 'level3'
6723
- };
6724
-
6725
- const phase = phaseMap[level];
6726
- if (!phase) return;
6727
-
6728
- const dot = container.querySelector(`[data-phase="${phase}"]`);
6729
- if (!dot) return;
6730
-
6731
- // Remove existing states
6732
- dot.classList.remove('active', 'completed', 'error');
6733
-
6734
- // Apply new state
6735
- if (status === 'running') {
6736
- dot.classList.add('active');
6737
- } else if (status === 'completed') {
6738
- dot.classList.add('completed');
6739
- } else if (status === 'failed') {
6740
- dot.classList.add('error');
6741
- }
6742
- }
6743
-
6744
- /**
6745
- * Complete all progress dots (called briefly before hiding)
6746
- */
6747
- completeAllProgressDots() {
6748
- const container = this.getProgressDotsContainer();
6749
- if (!container) return;
6750
-
6751
- const dots = container.querySelectorAll('.progress-dot');
6752
- dots.forEach(dot => {
6753
- dot.classList.remove('active', 'error');
6754
- dot.classList.add('completed');
6755
- });
6756
6642
  }
6757
6643
 
6758
6644
  /**
package/public/local.html CHANGED
@@ -435,13 +435,6 @@
435
435
  </div>
436
436
  <div class="diff-stats" id="diff-stats"></div>
437
437
  <div class="toolbar-actions">
438
- <!-- Progress Dots (visible during analysis) -->
439
- <div class="analysis-progress-dots" id="analysis-progress-dots" style="display: none;">
440
- <span class="progress-dot" data-phase="level1" title="Level 1: Diff"></span>
441
- <span class="progress-dot" data-phase="level2" title="Level 2: File"></span>
442
- <span class="progress-dot" data-phase="level3" title="Level 3: Codebase"></span>
443
- <span class="progress-dot" data-phase="orchestration" title="Consolidation"></span>
444
- </div>
445
438
  <button class="btn btn-sm btn-secondary" id="analyze-btn" title="Analyze with AI">
446
439
  <svg class="analyze-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14">
447
440
  <path d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z"/>
package/public/pr.html CHANGED
@@ -231,13 +231,6 @@
231
231
  </div>
232
232
  <div class="diff-stats" id="diff-stats"></div>
233
233
  <div class="toolbar-actions">
234
- <!-- Progress Dots (visible during analysis) -->
235
- <div class="analysis-progress-dots" id="analysis-progress-dots" style="display: none;">
236
- <span class="progress-dot" data-phase="level1" title="Level 1: Diff"></span>
237
- <span class="progress-dot" data-phase="level2" title="Level 2: File"></span>
238
- <span class="progress-dot" data-phase="level3" title="Level 3: Codebase"></span>
239
- <span class="progress-dot" data-phase="orchestration" title="Consolidation"></span>
240
- </div>
241
234
  <button class="btn btn-sm btn-secondary" id="analyze-btn" title="Analyze with AI">
242
235
  <svg class="analyze-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14">
243
236
  <path d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09z"/>
@@ -26,9 +26,9 @@ const BIN_DIR = path.join(__dirname, '..', '..', 'bin');
26
26
  * in the constructor's base args; individual models can override this via extra_args
27
27
  * (e.g., Haiku uses adaptive thinking for efficiency).
28
28
  *
29
- * Effort support by model (newest CLIs): Fable 5 and Opus 4.8 / 4.7 support
30
- * low|medium|high|xhigh|max; Opus 4.6 & Sonnet 4.6 support low|medium|high|max
31
- * (no xhigh); Haiku has no effort levels.
29
+ * Effort support by model (newest CLIs): Fable 5, Opus 4.8 / 4.7, and Sonnet 5
30
+ * support low|medium|high|xhigh|max; Opus 4.6 & Sonnet 4.6 support
31
+ * low|medium|high|max (no xhigh); Haiku has no effort levels.
32
32
  */
33
33
  const CLAUDE_MODELS = [
34
34
  // ── Thorough tier ───────────────────────────────────────────────────────
@@ -119,15 +119,37 @@ const CLAUDE_MODELS = [
119
119
  badgeClass: 'badge-power'
120
120
  },
121
121
  // ── Balanced tier ───────────────────────────────────────────────────────
122
+ {
123
+ id: 'sonnet-5-xhigh',
124
+ cli_model: 'claude-sonnet-5',
125
+ env: { CLAUDE_CODE_EFFORT_LEVEL: 'xhigh' },
126
+ name: 'Sonnet 5 XHigh',
127
+ tier: 'balanced',
128
+ tagline: 'Best Balance',
129
+ description: 'Sonnet 5 (newest) with extra-high effort — recommended for most reviews',
130
+ badge: 'Recommended',
131
+ badgeClass: 'badge-recommended'
132
+ },
133
+ {
134
+ id: 'sonnet-5-high',
135
+ cli_model: 'claude-sonnet-5',
136
+ env: { CLAUDE_CODE_EFFORT_LEVEL: 'high' },
137
+ name: 'Sonnet 5 High',
138
+ tier: 'balanced',
139
+ tagline: 'Faster',
140
+ description: 'Sonnet 5 with high effort — quicker than XHigh, still sharp',
141
+ badge: 'Quick & Sharp',
142
+ badgeClass: 'badge-speed'
143
+ },
122
144
  {
123
145
  id: 'sonnet-4.6',
124
146
  cli_model: 'claude-sonnet-4-6',
125
147
  name: 'Sonnet 4.6',
126
148
  tier: 'balanced',
127
- tagline: 'Best Balance',
128
- description: 'Recommended for most reviews',
129
- badge: 'Standard',
130
- badgeClass: 'badge-recommended'
149
+ tagline: 'Previous Gen',
150
+ description: 'Sonnet 4.6 previous generation balanced model',
151
+ badge: 'Previous Gen',
152
+ badgeClass: 'badge-balanced'
131
153
  },
132
154
  {
133
155
  id: 'opus-4.6-1m',
package/src/main.js CHANGED
@@ -196,7 +196,8 @@ OPTIONS:
196
196
  Available models: opus, sonnet, haiku (Claude Code);
197
197
  also: fable-5-xhigh, fable-5-high, opus-4.8-xhigh,
198
198
  opus-4.8-high, opus-4.7-xhigh, opus-4.7-high,
199
- opus-4.6-high, opus-4.6-1m, sonnet-4.6
199
+ opus-4.6-high, opus-4.6-1m, sonnet-5-xhigh,
200
+ sonnet-5-high, sonnet-4.6
200
201
  (opus is Opus 4.8 XHigh, the default)
201
202
  or use provider-specific models with Gemini/Codex
202
203
  --council <handle> Run analysis with a saved council (multi-voice). Handle is a