@in-the-loop-labs/pair-review 3.9.1 → 4.1.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 +92 -17
- package/package.json +6 -9
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin-code-critic/.claude-plugin/plugin.json +3 -4
- package/plugin-pair-loop/.claude-plugin/plugin.json +19 -0
- package/plugin-pair-loop/skills/loop/SKILL.md +233 -0
- package/public/js/components/AdvancedConfigTab.js +1 -1
- package/public/js/components/AnalysisConfigModal.js +2 -2
- package/public/js/index.js +87 -10
- package/public/js/local.js +20 -10
- package/public/js/pr.js +67 -39
- package/public/js/repo-links.js +11 -3
- package/public/js/utils/analyze-params.js +69 -0
- package/public/js/utils/provider-model.js +67 -2
- package/public/js/vendor/pierre-diffs-worker.js +16158 -0
- package/public/js/vendor/pierre-diffs.js +1880 -0
- package/public/local.html +1 -0
- package/public/pr.html +1 -0
- package/public/setup.html +35 -16
- package/src/ai/analyzer.js +4 -4
- package/src/ai/antigravity-provider.js +594 -0
- package/src/ai/index.js +1 -1
- package/src/ai/opencode-provider.js +1 -1
- package/src/ai/provider.js +5 -5
- package/src/ai/stream-parser.js +1 -52
- package/src/chat/acp-bridge.js +1 -1
- package/src/chat/chat-providers.js +1 -9
- package/src/config.js +153 -31
- package/src/database.js +128 -4
- package/src/external/github-adapter.js +18 -3
- package/src/github/client.js +37 -0
- package/src/github/parser.js +41 -7
- package/src/interactive-analysis-config.js +2 -2
- package/src/links/repo-links.js +66 -28
- package/src/local-review.js +134 -5
- package/src/local-scope.js +38 -0
- package/src/main.js +203 -37
- package/src/routes/config.js +49 -14
- package/src/routes/external-comments.js +13 -1
- package/src/routes/github-collections.js +175 -13
- package/src/routes/local.js +11 -20
- package/src/routes/pr.js +63 -36
- package/src/routes/setup.js +63 -8
- package/src/routes/shared.js +85 -0
- package/src/routes/stack-analysis.js +39 -3
- package/src/server.js +74 -3
- package/src/setup/local-setup.js +23 -7
- package/src/setup/pr-setup.js +237 -39
- package/src/setup/stack-setup.js +7 -2
- package/src/single-port.js +73 -18
- package/src/utils/host-resolution.js +157 -0
- package/plugin-code-critic/skills/loop/SKILL.md +0 -373
- package/src/ai/gemini-provider.js +0 -752
package/public/local.html
CHANGED
|
@@ -591,6 +591,7 @@
|
|
|
591
591
|
<!-- Shared storage-key and provider/model helpers -->
|
|
592
592
|
<script src="/js/utils/storage-keys.js"></script>
|
|
593
593
|
<script src="/js/utils/provider-model.js"></script>
|
|
594
|
+
<script src="/js/utils/analyze-params.js"></script>
|
|
594
595
|
|
|
595
596
|
<!-- Category emoji mapping -->
|
|
596
597
|
<script src="/js/utils/category-emoji.js"></script>
|
package/public/pr.html
CHANGED
|
@@ -394,6 +394,7 @@
|
|
|
394
394
|
<!-- Shared storage-key and provider/model helpers -->
|
|
395
395
|
<script src="/js/utils/storage-keys.js"></script>
|
|
396
396
|
<script src="/js/utils/provider-model.js"></script>
|
|
397
|
+
<script src="/js/utils/analyze-params.js"></script>
|
|
397
398
|
|
|
398
399
|
<!-- Category emoji mapping -->
|
|
399
400
|
<script src="/js/utils/category-emoji.js"></script>
|
package/public/setup.html
CHANGED
|
@@ -530,6 +530,7 @@
|
|
|
530
530
|
<script src="/js/ws-client.js"></script>
|
|
531
531
|
<script src="/js/components/UpdateBanner.js"></script>
|
|
532
532
|
<script src="/js/utils/notification-sounds.js"></script>
|
|
533
|
+
<script src="/js/utils/analyze-params.js"></script>
|
|
533
534
|
|
|
534
535
|
<script>
|
|
535
536
|
// Copyright 2026 Tim Perkins (tjwp) | SPDX-License-Identifier: Apache-2.0
|
|
@@ -611,6 +612,14 @@
|
|
|
611
612
|
context.path = params.get('path');
|
|
612
613
|
}
|
|
613
614
|
}
|
|
615
|
+
// Forward a delegated --scope/--base selection (the CLI carries them
|
|
616
|
+
// on the /local?path=... URL when delegating to a running server).
|
|
617
|
+
// The server re-validates; this only relays the request.
|
|
618
|
+
if (mode === 'local') {
|
|
619
|
+
const scopeParams = new URLSearchParams(window.location.search);
|
|
620
|
+
if (scopeParams.get('scope')) context.scope = scopeParams.get('scope');
|
|
621
|
+
if (scopeParams.get('base')) context.base = scopeParams.get('base');
|
|
622
|
+
}
|
|
614
623
|
|
|
615
624
|
const steps = mode === 'local' ? LOCAL_STEPS : PR_STEPS;
|
|
616
625
|
const stepStates = {};
|
|
@@ -751,7 +760,23 @@
|
|
|
751
760
|
var fetchOptions = { method: 'POST' };
|
|
752
761
|
if (mode === 'local') {
|
|
753
762
|
fetchOptions.headers = { 'Content-Type': 'application/json' };
|
|
754
|
-
|
|
763
|
+
var localBody = { path: context.path };
|
|
764
|
+
if (context.scope) localBody.scope = context.scope;
|
|
765
|
+
if (context.base) localBody.base = context.base;
|
|
766
|
+
fetchOptions.body = JSON.stringify(localBody);
|
|
767
|
+
} else if (mode === 'pr') {
|
|
768
|
+
// A `host` query param (set when opening a PR from a dashboard
|
|
769
|
+
// collection row or a pasted URL) tells setup which system the
|
|
770
|
+
// PR lives on, so the fetch binds there directly instead of
|
|
771
|
+
// probing. Sentinel: the literal "github" means github.com and
|
|
772
|
+
// maps to body host null; any other value is an api_host URL
|
|
773
|
+
// string (alt host) — an api_host is always a URL, so "github"
|
|
774
|
+
// is unambiguous. Absent = unknown; the server derives the host.
|
|
775
|
+
var setupHost = new URLSearchParams(window.location.search).get('host');
|
|
776
|
+
if (setupHost) {
|
|
777
|
+
fetchOptions.headers = { 'Content-Type': 'application/json' };
|
|
778
|
+
fetchOptions.body = JSON.stringify({ host: setupHost === 'github' ? null : setupHost });
|
|
779
|
+
}
|
|
755
780
|
}
|
|
756
781
|
|
|
757
782
|
var response = await fetch(postUrl, fetchOptions);
|
|
@@ -764,16 +789,13 @@
|
|
|
764
789
|
|
|
765
790
|
var data = await response.json();
|
|
766
791
|
|
|
767
|
-
// If the review already exists, redirect immediately
|
|
792
|
+
// If the review already exists, redirect immediately.
|
|
793
|
+
// Relay the full auto-analyze intent bundle (analyze /
|
|
794
|
+
// analysisConfigId / council / provider / model) so a delegated
|
|
795
|
+
// override or CLI council survives this hop to the review page.
|
|
768
796
|
if (data.existing && data.reviewUrl) {
|
|
769
797
|
var targetUrl = new URL(data.reviewUrl, window.location.origin);
|
|
770
|
-
|
|
771
|
-
if (qs.get('analyze') === 'true') targetUrl.searchParams.set('analyze', qs.get('analyze'));
|
|
772
|
-
if (qs.get('analysisConfigId')) targetUrl.searchParams.set('analysisConfigId', qs.get('analysisConfigId'));
|
|
773
|
-
// Forward the CLI-supplied council selection (PR & local cold-start
|
|
774
|
-
// and delegated paths route through here); the review page keys
|
|
775
|
-
// council auto-analysis on this param.
|
|
776
|
-
if (qs.get('council')) targetUrl.searchParams.set('council', qs.get('council'));
|
|
798
|
+
window.carryAnalyzeParams(window.location.search, targetUrl);
|
|
777
799
|
window.location.href = targetUrl.toString();
|
|
778
800
|
return;
|
|
779
801
|
}
|
|
@@ -832,13 +854,10 @@
|
|
|
832
854
|
setTimeout(function() {
|
|
833
855
|
if (msg.reviewUrl) {
|
|
834
856
|
var targetUrl = new URL(msg.reviewUrl, window.location.origin);
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
// and delegated paths route through here); the review page keys
|
|
840
|
-
// council auto-analysis on this param.
|
|
841
|
-
if (qs.get('council')) targetUrl.searchParams.set('council', qs.get('council'));
|
|
857
|
+
// Relay the full auto-analyze intent bundle (analyze /
|
|
858
|
+
// analysisConfigId / council / provider / model) so a
|
|
859
|
+
// delegated override or CLI council survives the hop.
|
|
860
|
+
window.carryAnalyzeParams(window.location.search, targetUrl);
|
|
842
861
|
window.location.href = targetUrl.toString();
|
|
843
862
|
}
|
|
844
863
|
}, 400);
|
package/src/ai/analyzer.js
CHANGED
|
@@ -342,8 +342,8 @@ A suggestion is a duplicate if it targets the same file and overlapping lines an
|
|
|
342
342
|
class Analyzer {
|
|
343
343
|
/**
|
|
344
344
|
* @param {Object} database - Database instance
|
|
345
|
-
* @param {string} model - Model to use (e.g., 'opus', 'gemini-
|
|
346
|
-
* @param {string} provider - Provider ID (e.g., 'claude', '
|
|
345
|
+
* @param {string} model - Model to use (e.g., 'opus', 'gemini-3.1-pro-low')
|
|
346
|
+
* @param {string} provider - Provider ID (e.g., 'claude', 'antigravity'). Defaults to 'claude'.
|
|
347
347
|
* @param {Object} providerOverrides - Per-call config overrides passed to createProvider (optional)
|
|
348
348
|
* @param {Object|null} providerOverridesMap - Per-provider overrides map for council mode (provider ID → overrides)
|
|
349
349
|
*/
|
|
@@ -860,8 +860,8 @@ class Analyzer {
|
|
|
860
860
|
*
|
|
861
861
|
* Uses the bare command name since BIN_DIR is added to PATH in all
|
|
862
862
|
* providers. Using the absolute path causes issues with AI providers
|
|
863
|
-
* that pattern-match allowed
|
|
864
|
-
* 'git-diff-lines', not the full path).
|
|
863
|
+
* that pattern-match allowed shell commands by their bare command name
|
|
864
|
+
* (matching 'git-diff-lines', not the full path).
|
|
865
865
|
*
|
|
866
866
|
* @param {string|null} worktreePath - Path to the git worktree
|
|
867
867
|
* @returns {string} e.g. `git-diff-lines` or `git-diff-lines --cwd "/path"`
|