@in-the-loop-labs/pair-review 3.8.0 → 3.9.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 +175 -3
- 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/js/local.js +27 -8
- package/public/js/utils/provider-model.js +9 -2
- package/src/ai/claude-provider.js +27 -27
- package/src/ai/index.js +8 -0
- package/src/ai/provider.js +225 -27
- package/src/councils/headless-council.js +13 -3
- package/src/database.js +52 -0
- package/src/git/worktree.js +7 -1
- package/src/interactive-analysis-config.js +152 -0
- package/src/local-review.js +43 -21
- package/src/main.js +951 -45
- package/src/mcp-stdio.js +40 -5
- package/src/review-config.js +164 -0
- package/src/routes/bulk-analysis-configs.js +45 -15
- package/src/routes/config.js +9 -4
- package/src/routes/executable-analysis.js +10 -1
- package/src/routes/local.js +170 -109
- package/src/routes/mcp.js +28 -31
- package/src/routes/pr.js +118 -56
- package/src/single-port.js +116 -6
- package/src/utils/logger.js +25 -4
package/src/local-review.js
CHANGED
|
@@ -14,6 +14,7 @@ const execAsync = promisify(exec);
|
|
|
14
14
|
const { STOPS, scopeIncludes, includesBranch, DEFAULT_SCOPE, scopeLabel, reviewScope } = require('./local-scope');
|
|
15
15
|
const { initializeDatabase, ReviewRepository, RepoSettingsRepository } = require('./database');
|
|
16
16
|
const { resolveCouncilHandle } = require('./councils/resolve-council');
|
|
17
|
+
const { prepareInteractiveAnalysisConfig } = require('./interactive-analysis-config');
|
|
17
18
|
const { startServer } = require('./server');
|
|
18
19
|
const { localReviewDiffs } = require('./routes/shared');
|
|
19
20
|
const summaryGenerator = require('./ai/summary-generator');
|
|
@@ -703,9 +704,14 @@ async function generateLocalDiff(repoPath, options = {}) {
|
|
|
703
704
|
* @param {Object} params.config - Loaded config
|
|
704
705
|
* @param {string} params.repoPath - Path to the working tree (already validated)
|
|
705
706
|
* @param {Object} [params.flags] - CLI flags / options
|
|
707
|
+
* @param {boolean} [params.startBackgroundJobs=true] - When false, skip the
|
|
708
|
+
* fire-and-forget summary/tour generation jobs. The interactive UI wants them
|
|
709
|
+
* (they populate the review while the human reads the diff), but a one-shot
|
|
710
|
+
* headless run does not: they would spend provider budget after the JSON
|
|
711
|
+
* result is already printed and keep the event loop alive (CLI hang).
|
|
706
712
|
* @returns {Promise<{sessionId: number, repoPath: string, branch: string, repository: string, headSha: string, diff: string, stats: Object, digest: string|null, branchInfo: Object|null, scopeStart: string, scopeEnd: string, baseBranch: string|null}>}
|
|
707
713
|
*/
|
|
708
|
-
async function setupLocalReviewSession({ db, config, repoPath, flags = {} }) {
|
|
714
|
+
async function setupLocalReviewSession({ db, config, repoPath, flags = {}, startBackgroundJobs = true }) {
|
|
709
715
|
const headSha = await module.exports.getHeadSha(repoPath);
|
|
710
716
|
console.log(`HEAD SHA: ${headSha}`);
|
|
711
717
|
|
|
@@ -837,25 +843,30 @@ async function setupLocalReviewSession({ db, config, repoPath, flags = {} }) {
|
|
|
837
843
|
logger.warn(`Could not persist diff to database: ${persistError.message}`);
|
|
838
844
|
}
|
|
839
845
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
846
|
+
// Fire-and-forget summary/tour generation. Skipped for headless one-shot runs
|
|
847
|
+
// (startBackgroundJobs:false) — they would spend provider budget after the
|
|
848
|
+
// result is reported and keep the event loop alive, hanging the CLI.
|
|
849
|
+
if (startBackgroundJobs) {
|
|
850
|
+
summaryGenerator.kickOffSummaryJob({
|
|
851
|
+
db,
|
|
852
|
+
config,
|
|
853
|
+
reviewId: sessionId,
|
|
854
|
+
diffText: diff,
|
|
855
|
+
worktreePath: repoPath,
|
|
856
|
+
reviewContext: { prTitle: branch },
|
|
857
|
+
trigger: 'auto'
|
|
858
|
+
})?.catch((err) => logger.warn(`Hunk summary job failed for review ${sessionId}: ${err.message}`));
|
|
859
|
+
|
|
860
|
+
tourGenerator.kickOffTourJob({
|
|
861
|
+
db,
|
|
862
|
+
config,
|
|
863
|
+
reviewId: sessionId,
|
|
864
|
+
diffText: diff,
|
|
865
|
+
worktreePath: repoPath,
|
|
866
|
+
reviewContext: { prTitle: branch },
|
|
867
|
+
trigger: 'auto'
|
|
868
|
+
})?.catch((err) => logger.warn(`Tour job failed for review ${sessionId}: ${err.message}`));
|
|
869
|
+
}
|
|
859
870
|
|
|
860
871
|
return {
|
|
861
872
|
sessionId,
|
|
@@ -928,7 +939,18 @@ async function handleLocalReview(targetPath, flags = {}) {
|
|
|
928
939
|
let url = `http://localhost:${port}/local/${session.sessionId}`;
|
|
929
940
|
const shouldAnalyze = flags.ai || flags.council;
|
|
930
941
|
if (shouldAnalyze) url += '?analyze=true';
|
|
931
|
-
|
|
942
|
+
// When the run carries --instructions, stash the resolved analysis config and
|
|
943
|
+
// thread its id so the browser-side auto-analyze honors the instructions
|
|
944
|
+
// instead of silently dropping them (mirrors handlePullRequest). The id
|
|
945
|
+
// encodes the council selection, so prefer it over the bare &council= param.
|
|
946
|
+
const analysisConfigId = shouldAnalyze
|
|
947
|
+
? await prepareInteractiveAnalysisConfig({ db, config, flags, repository: session.repository })
|
|
948
|
+
: null;
|
|
949
|
+
if (analysisConfigId) {
|
|
950
|
+
url += `&analysisConfigId=${analysisConfigId}`;
|
|
951
|
+
} else if (councilSelection) {
|
|
952
|
+
url += `&council=${councilSelection.id}`;
|
|
953
|
+
}
|
|
932
954
|
console.log(`\nOpening browser to: ${url}`);
|
|
933
955
|
await open(url);
|
|
934
956
|
|