@in-the-loop-labs/pair-review 1.3.3 → 1.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.
- package/README.md +67 -38
- 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/index.html +270 -623
- package/public/js/index.js +1071 -0
- package/public/js/local.js +80 -0
- package/public/js/modules/analysis-history.js +5 -1
- package/public/local.html +45 -2
- package/src/ai/index.js +1 -0
- package/src/ai/pi-provider.js +859 -0
- package/src/ai/provider.js +32 -8
- package/src/ai/stream-parser.js +171 -2
- package/src/config.js +1 -1
- package/src/database.js +170 -40
- package/src/local-review.js +9 -0
- package/src/routes/local.js +390 -41
package/public/js/local.js
CHANGED
|
@@ -1361,10 +1361,90 @@ class LocalManager {
|
|
|
1361
1361
|
});
|
|
1362
1362
|
}
|
|
1363
1363
|
|
|
1364
|
+
/**
|
|
1365
|
+
* Initialize inline name editing for the review title in the header
|
|
1366
|
+
*/
|
|
1367
|
+
initNameEditing() {
|
|
1368
|
+
const nameEl = document.getElementById('local-review-name');
|
|
1369
|
+
if (!nameEl || nameEl.dataset.listenerAttached) return;
|
|
1370
|
+
nameEl.dataset.listenerAttached = 'true';
|
|
1371
|
+
|
|
1372
|
+
const reviewId = this.reviewId;
|
|
1373
|
+
|
|
1374
|
+
nameEl.addEventListener('click', () => {
|
|
1375
|
+
if (nameEl.querySelector('input')) return; // already editing
|
|
1376
|
+
|
|
1377
|
+
const currentName = nameEl.dataset.currentName || '';
|
|
1378
|
+
const input = document.createElement('input');
|
|
1379
|
+
input.type = 'text';
|
|
1380
|
+
input.className = 'local-review-name-input';
|
|
1381
|
+
input.value = currentName;
|
|
1382
|
+
input.placeholder = 'Untitled';
|
|
1383
|
+
|
|
1384
|
+
nameEl.textContent = '';
|
|
1385
|
+
nameEl.appendChild(input);
|
|
1386
|
+
input.focus();
|
|
1387
|
+
input.select();
|
|
1388
|
+
|
|
1389
|
+
let saved = false;
|
|
1390
|
+
|
|
1391
|
+
async function save() {
|
|
1392
|
+
if (saved) return;
|
|
1393
|
+
saved = true;
|
|
1394
|
+
const newName = input.value.trim() || null;
|
|
1395
|
+
try {
|
|
1396
|
+
const response = await fetch(`/api/local/${reviewId}/name`, {
|
|
1397
|
+
method: 'PATCH',
|
|
1398
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1399
|
+
body: JSON.stringify({ name: newName })
|
|
1400
|
+
});
|
|
1401
|
+
if (!response.ok) throw new Error('Save failed');
|
|
1402
|
+
nameEl.dataset.currentName = newName || '';
|
|
1403
|
+
nameEl.textContent = newName || 'Untitled';
|
|
1404
|
+
nameEl.classList.toggle('unnamed', !newName);
|
|
1405
|
+
nameEl.title = 'Click to rename';
|
|
1406
|
+
} catch (error) {
|
|
1407
|
+
// Revert the display to the previous name on failure
|
|
1408
|
+
cancel();
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
function cancel() {
|
|
1413
|
+
nameEl.textContent = currentName || 'Untitled';
|
|
1414
|
+
nameEl.classList.toggle('unnamed', !currentName);
|
|
1415
|
+
nameEl.title = 'Click to rename';
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
input.addEventListener('blur', save);
|
|
1419
|
+
input.addEventListener('keydown', function(e) {
|
|
1420
|
+
if (e.key === 'Enter') {
|
|
1421
|
+
e.preventDefault();
|
|
1422
|
+
input.removeEventListener('blur', save);
|
|
1423
|
+
save();
|
|
1424
|
+
} else if (e.key === 'Escape') {
|
|
1425
|
+
e.preventDefault();
|
|
1426
|
+
input.removeEventListener('blur', save);
|
|
1427
|
+
cancel();
|
|
1428
|
+
}
|
|
1429
|
+
});
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1364
1433
|
/**
|
|
1365
1434
|
* Update local header with review info
|
|
1366
1435
|
*/
|
|
1367
1436
|
updateLocalHeader(reviewData) {
|
|
1437
|
+
// Update review name/title in header
|
|
1438
|
+
const nameEl = document.getElementById('local-review-name');
|
|
1439
|
+
if (nameEl) {
|
|
1440
|
+
const name = reviewData.name || '';
|
|
1441
|
+
nameEl.textContent = name || 'Untitled';
|
|
1442
|
+
nameEl.dataset.currentName = name;
|
|
1443
|
+
nameEl.classList.toggle('unnamed', !name);
|
|
1444
|
+
nameEl.title = 'Click to rename';
|
|
1445
|
+
this.initNameEditing();
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1368
1448
|
// Update repository name
|
|
1369
1449
|
const repoName = document.getElementById('local-repo-name');
|
|
1370
1450
|
if (repoName) {
|
|
@@ -748,7 +748,11 @@ class AnalysisHistoryManager {
|
|
|
748
748
|
'o1': 'thorough',
|
|
749
749
|
'o1-mini': 'balanced',
|
|
750
750
|
// Copilot models
|
|
751
|
-
'gpt-4': 'balanced'
|
|
751
|
+
'gpt-4': 'balanced',
|
|
752
|
+
// Pi models
|
|
753
|
+
'default': 'balanced',
|
|
754
|
+
'multi-model': 'thorough',
|
|
755
|
+
'review-roulette': 'thorough'
|
|
752
756
|
};
|
|
753
757
|
|
|
754
758
|
return modelTiers[modelId] || null;
|
package/public/local.html
CHANGED
|
@@ -165,6 +165,49 @@
|
|
|
165
165
|
unicode-bidi: bidi-override;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
/* Editable review name in header */
|
|
169
|
+
.local-review-name {
|
|
170
|
+
font-size: 15px;
|
|
171
|
+
font-weight: 500;
|
|
172
|
+
color: var(--color-text-primary);
|
|
173
|
+
cursor: text;
|
|
174
|
+
padding: 2px 6px;
|
|
175
|
+
border-radius: 4px;
|
|
176
|
+
border: 1px dashed var(--color-border-primary);
|
|
177
|
+
transition: all 0.15s ease;
|
|
178
|
+
max-width: 360px;
|
|
179
|
+
overflow: hidden;
|
|
180
|
+
text-overflow: ellipsis;
|
|
181
|
+
white-space: nowrap;
|
|
182
|
+
position: relative;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.local-review-name:hover {
|
|
186
|
+
background: var(--color-bg-secondary);
|
|
187
|
+
border-color: var(--ai-primary);
|
|
188
|
+
border-style: solid;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.local-review-name.unnamed {
|
|
192
|
+
color: var(--color-text-tertiary);
|
|
193
|
+
font-style: italic;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.local-review-name-input {
|
|
197
|
+
font-family: 'DM Sans', -apple-system, sans-serif;
|
|
198
|
+
font-size: 15px;
|
|
199
|
+
font-weight: 500;
|
|
200
|
+
padding: 2px 6px;
|
|
201
|
+
border: 1px solid #d97706;
|
|
202
|
+
border-radius: 4px;
|
|
203
|
+
background: var(--color-bg-primary);
|
|
204
|
+
color: var(--color-text-primary);
|
|
205
|
+
outline: none;
|
|
206
|
+
box-shadow: 0 0 0 2px rgba(217, 119, 6, 0.15);
|
|
207
|
+
width: 280px;
|
|
208
|
+
max-width: 360px;
|
|
209
|
+
}
|
|
210
|
+
|
|
168
211
|
</style>
|
|
169
212
|
</head>
|
|
170
213
|
<body>
|
|
@@ -205,8 +248,8 @@
|
|
|
205
248
|
</div>
|
|
206
249
|
</div>
|
|
207
250
|
<div class="header-center">
|
|
208
|
-
<!--
|
|
209
|
-
|
|
251
|
+
<!-- Editable review name/title -->
|
|
252
|
+
<span class="local-review-name" id="local-review-name" title="Click to rename">Untitled</span>
|
|
210
253
|
</div>
|
|
211
254
|
<div class="header-right">
|
|
212
255
|
<div class="header-icon-group">
|