@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 +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin-code-critic/.claude-plugin/plugin.json +1 -1
- package/public/css/pr.css +12 -60
- package/public/js/components/CouncilProgressModal.js +0 -10
- package/public/js/local.js +0 -49
- package/public/js/pr.js +0 -114
- package/public/local.html +0 -7
- package/public/pr.html +0 -7
- package/src/ai/claude-provider.js +29 -7
- package/src/main.js +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pair-review",
|
|
3
|
-
"version": "3.9.
|
|
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.
|
|
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);
|
package/public/js/local.js
CHANGED
|
@@ -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
|
|
30
|
-
* low|medium|high|xhigh|max; Opus 4.6 & Sonnet 4.6 support
|
|
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: '
|
|
128
|
-
description: '
|
|
129
|
-
badge: '
|
|
130
|
-
badgeClass: 'badge-
|
|
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-
|
|
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
|