projscan 0.12.0 → 0.16.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 +20 -14
- package/dist/analyzers/crossPackageImportCheck.d.ts +13 -0
- package/dist/analyzers/crossPackageImportCheck.js +136 -0
- package/dist/analyzers/crossPackageImportCheck.js.map +1 -0
- package/dist/analyzers/cycleCheck.d.ts +12 -0
- package/dist/analyzers/cycleCheck.js +65 -0
- package/dist/analyzers/cycleCheck.js.map +1 -0
- package/dist/cli/_shared.js +2 -2
- package/dist/cli/_shared.js.map +1 -1
- package/dist/cli/commands/audit.js +8 -2
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/coupling.js +4 -0
- package/dist/cli/commands/coupling.js.map +1 -1
- package/dist/cli/commands/dependencies.js +4 -3
- package/dist/cli/commands/dependencies.js.map +1 -1
- package/dist/cli/commands/doctor.js +4 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/explainIssue.d.ts +1 -0
- package/dist/cli/commands/explainIssue.js +49 -0
- package/dist/cli/commands/explainIssue.js.map +1 -0
- package/dist/cli/commands/fixSuggest.d.ts +1 -0
- package/dist/cli/commands/fixSuggest.js +71 -0
- package/dist/cli/commands/fixSuggest.js.map +1 -0
- package/dist/cli/commands/hotspots.js +4 -0
- package/dist/cli/commands/hotspots.js.map +1 -1
- package/dist/cli/commands/impact.d.ts +1 -0
- package/dist/cli/commands/impact.js +59 -0
- package/dist/cli/commands/impact.js.map +1 -0
- package/dist/cli/commands/review.d.ts +1 -0
- package/dist/cli/commands/review.js +70 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/search.js +6 -2
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/watch.d.ts +1 -0
- package/dist/cli/commands/watch.js +58 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/index.js +10 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/ast.d.ts +28 -0
- package/dist/core/ast.js +190 -0
- package/dist/core/ast.js.map +1 -1
- package/dist/core/auditRunner.d.ts +8 -0
- package/dist/core/auditRunner.js +50 -1
- package/dist/core/auditRunner.js.map +1 -1
- package/dist/core/codeGraph.d.ts +23 -1
- package/dist/core/codeGraph.js +198 -0
- package/dist/core/codeGraph.js.map +1 -1
- package/dist/core/dependencyAnalyzer.d.ts +15 -1
- package/dist/core/dependencyAnalyzer.js +115 -18
- package/dist/core/dependencyAnalyzer.js.map +1 -1
- package/dist/core/explainIssue.d.ts +9 -0
- package/dist/core/explainIssue.js +106 -0
- package/dist/core/explainIssue.js.map +1 -0
- package/dist/core/fileInspector.js +13 -0
- package/dist/core/fileInspector.js.map +1 -1
- package/dist/core/fixSuggest.d.ts +41 -0
- package/dist/core/fixSuggest.js +327 -0
- package/dist/core/fixSuggest.js.map +1 -0
- package/dist/core/impact.d.ts +27 -0
- package/dist/core/impact.js +169 -0
- package/dist/core/impact.js.map +1 -0
- package/dist/core/indexCache.js +5 -1
- package/dist/core/indexCache.js.map +1 -1
- package/dist/core/issueEngine.js +18 -0
- package/dist/core/issueEngine.js.map +1 -1
- package/dist/core/languages/goAdapter.js +5 -0
- package/dist/core/languages/goAdapter.js.map +1 -1
- package/dist/core/languages/goFunctions.d.ts +24 -0
- package/dist/core/languages/goFunctions.js +99 -0
- package/dist/core/languages/goFunctions.js.map +1 -0
- package/dist/core/languages/javaAdapter.js +5 -0
- package/dist/core/languages/javaAdapter.js.map +1 -1
- package/dist/core/languages/javaFunctions.d.ts +22 -0
- package/dist/core/languages/javaFunctions.js +87 -0
- package/dist/core/languages/javaFunctions.js.map +1 -0
- package/dist/core/languages/pythonAdapter.js +5 -0
- package/dist/core/languages/pythonAdapter.js.map +1 -1
- package/dist/core/languages/pythonFunctions.d.ts +23 -0
- package/dist/core/languages/pythonFunctions.js +87 -0
- package/dist/core/languages/pythonFunctions.js.map +1 -0
- package/dist/core/languages/rubyAdapter.js +5 -0
- package/dist/core/languages/rubyAdapter.js.map +1 -1
- package/dist/core/languages/rubyFunctions.d.ts +22 -0
- package/dist/core/languages/rubyFunctions.js +91 -0
- package/dist/core/languages/rubyFunctions.js.map +1 -0
- package/dist/core/review.d.ts +21 -0
- package/dist/core/review.js +457 -0
- package/dist/core/review.js.map +1 -0
- package/dist/core/searchIndex.d.ts +9 -0
- package/dist/core/searchIndex.js.map +1 -1
- package/dist/core/semanticSearch.d.ts +69 -2
- package/dist/core/semanticSearch.js +113 -55
- package/dist/core/semanticSearch.js.map +1 -1
- package/dist/core/watcher.d.ts +37 -0
- package/dist/core/watcher.js +126 -0
- package/dist/core/watcher.js.map +1 -0
- package/dist/index.d.ts +11 -2
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/tools/audit.js +7 -2
- package/dist/mcp/tools/audit.js.map +1 -1
- package/dist/mcp/tools/dependencies.js +11 -5
- package/dist/mcp/tools/dependencies.js.map +1 -1
- package/dist/mcp/tools/explainIssue.d.ts +2 -0
- package/dist/mcp/tools/explainIssue.js +30 -0
- package/dist/mcp/tools/explainIssue.js.map +1 -0
- package/dist/mcp/tools/file.js +1 -1
- package/dist/mcp/tools/file.js.map +1 -1
- package/dist/mcp/tools/fixSuggest.d.ts +2 -0
- package/dist/mcp/tools/fixSuggest.js +57 -0
- package/dist/mcp/tools/fixSuggest.js.map +1 -0
- package/dist/mcp/tools/hotspots.js +40 -1
- package/dist/mcp/tools/hotspots.js.map +1 -1
- package/dist/mcp/tools/impact.d.ts +2 -0
- package/dist/mcp/tools/impact.js +59 -0
- package/dist/mcp/tools/impact.js.map +1 -0
- package/dist/mcp/tools/review.d.ts +2 -0
- package/dist/mcp/tools/review.js +54 -0
- package/dist/mcp/tools/review.js.map +1 -0
- package/dist/mcp/tools/search.js +9 -2
- package/dist/mcp/tools/search.js.map +1 -1
- package/dist/mcp/tools.js +8 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/reporters/consoleReporter.d.ts +10 -1
- package/dist/reporters/consoleReporter.js +218 -0
- package/dist/reporters/consoleReporter.js.map +1 -1
- package/dist/reporters/htmlReporter.d.ts +8 -0
- package/dist/reporters/htmlReporter.js +287 -0
- package/dist/reporters/htmlReporter.js.map +1 -0
- package/dist/reporters/jsonReporter.d.ts +10 -1
- package/dist/reporters/jsonReporter.js +12 -0
- package/dist/reporters/jsonReporter.js.map +1 -1
- package/dist/reporters/markdownReporter.d.ts +10 -1
- package/dist/reporters/markdownReporter.js +173 -0
- package/dist/reporters/markdownReporter.js.map +1 -1
- package/dist/tool-manifest.json +133 -8
- package/dist/types.d.ts +276 -1
- package/dist/utils/config.js +27 -0
- package/dist/utils/config.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FunctionInfo } from '../ast.js';
|
|
2
|
+
interface TsNode {
|
|
3
|
+
type: string;
|
|
4
|
+
text: string;
|
|
5
|
+
startPosition: {
|
|
6
|
+
row: number;
|
|
7
|
+
column: number;
|
|
8
|
+
};
|
|
9
|
+
endPosition: {
|
|
10
|
+
row: number;
|
|
11
|
+
column: number;
|
|
12
|
+
};
|
|
13
|
+
namedChildren: TsNode[];
|
|
14
|
+
childForFieldName?: (name: string) => TsNode | null;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Per-method McCabe CC for Ruby. Walks `method` (def) and `singleton_method`
|
|
18
|
+
* (def self.foo) nodes inside class/module bodies. Methods are named
|
|
19
|
+
* `Class.method` (or `Module.method`).
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractRubyFunctions(root: TsNode): FunctionInfo[];
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const RUBY_DECISION_NODES = new Set([
|
|
2
|
+
'if',
|
|
3
|
+
'elsif',
|
|
4
|
+
'unless',
|
|
5
|
+
'while',
|
|
6
|
+
'until',
|
|
7
|
+
'for',
|
|
8
|
+
'when',
|
|
9
|
+
'rescue',
|
|
10
|
+
'conditional',
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* Per-method McCabe CC for Ruby. Walks `method` (def) and `singleton_method`
|
|
14
|
+
* (def self.foo) nodes inside class/module bodies. Methods are named
|
|
15
|
+
* `Class.method` (or `Module.method`).
|
|
16
|
+
*/
|
|
17
|
+
export function extractRubyFunctions(root) {
|
|
18
|
+
const out = [];
|
|
19
|
+
walk(root, null, out);
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
function walk(node, className, out) {
|
|
23
|
+
if (node.type === 'class' || node.type === 'module') {
|
|
24
|
+
const nameNode = node.childForFieldName ? node.childForFieldName('name') : findChild(node, 'constant');
|
|
25
|
+
const cls = nameNode?.text ?? null;
|
|
26
|
+
const body = node.childForFieldName ? node.childForFieldName('body') : null;
|
|
27
|
+
if (body) {
|
|
28
|
+
for (const child of body.namedChildren)
|
|
29
|
+
walk(child, cls, out);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
for (const child of node.namedChildren)
|
|
33
|
+
walk(child, cls, out);
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (node.type === 'method' || node.type === 'singleton_method') {
|
|
38
|
+
const nameNode = node.childForFieldName ? node.childForFieldName('name') : findChild(node, 'identifier');
|
|
39
|
+
const baseName = nameNode?.text ?? '<anonymous>';
|
|
40
|
+
const fnName = className ? `${className}.${baseName}` : baseName;
|
|
41
|
+
const line = node.startPosition.row + 1;
|
|
42
|
+
const endLine = node.endPosition.row + 1;
|
|
43
|
+
const cc = countDecisions(node);
|
|
44
|
+
out.push({ name: fnName, line, endLine, cyclomaticComplexity: cc });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
for (const child of node.namedChildren)
|
|
48
|
+
walk(child, className, out);
|
|
49
|
+
}
|
|
50
|
+
function countDecisions(fnNode) {
|
|
51
|
+
let count = 0;
|
|
52
|
+
const body = fnNode.childForFieldName ? fnNode.childForFieldName('body') : null;
|
|
53
|
+
if (!body)
|
|
54
|
+
return 1;
|
|
55
|
+
walkSkipNested(body, (n) => {
|
|
56
|
+
if (RUBY_DECISION_NODES.has(n.type)) {
|
|
57
|
+
count++;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (n.type === 'binary') {
|
|
61
|
+
if (/(\s|^)(\|\||&&)(\s|$)/.test(n.text) || /\b(and|or)\b/.test(n.text))
|
|
62
|
+
count++;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return count + 1;
|
|
66
|
+
}
|
|
67
|
+
function walkSkipNested(node, visit) {
|
|
68
|
+
visit(node);
|
|
69
|
+
for (const child of node.namedChildren) {
|
|
70
|
+
if (child.type === 'method' ||
|
|
71
|
+
child.type === 'singleton_method' ||
|
|
72
|
+
child.type === 'class' ||
|
|
73
|
+
child.type === 'module' ||
|
|
74
|
+
child.type === 'lambda' ||
|
|
75
|
+
child.type === 'block') {
|
|
76
|
+
// Skip blocks too: in Ruby, `each { |x| ... }` is a block; treating it
|
|
77
|
+
// as opaque keeps method CC tight to the method's own logic. (This is
|
|
78
|
+
// a tradeoff - some style guides include block branches. We pick the
|
|
79
|
+
// more conservative reading.)
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
walkSkipNested(child, visit);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function findChild(node, type) {
|
|
86
|
+
for (const c of node.namedChildren)
|
|
87
|
+
if (c.type === type)
|
|
88
|
+
return c;
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=rubyFunctions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rubyFunctions.js","sourceRoot":"","sources":["../../../src/core/languages/rubyFunctions.ts"],"names":[],"mappings":"AAWA,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,IAAI;IACJ,OAAO;IACP,QAAQ;IACR,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;IACN,QAAQ;IACR,aAAa;CACd,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACtB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,SAAwB,EAAE,GAAmB;IACvE,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACvG,MAAM,GAAG,GAAG,QAAQ,EAAE,IAAI,IAAI,IAAI,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5E,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;gBAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;gBAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAChE,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACzG,MAAM,QAAQ,GAAG,QAAQ,EAAE,IAAI,IAAI,aAAa,CAAC;QACjD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;QACzC,MAAM,EAAE,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,CAAC,CAAC;QACpE,OAAO;IACT,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,cAAc,CAAC,MAAc;IACpC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChF,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACzB,IAAI,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,KAAK,EAAE,CAAC;YACR,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxB,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,KAAK,EAAE,CAAC;QACnF,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,KAA0B;IAC9D,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,IACE,KAAK,CAAC,IAAI,KAAK,QAAQ;YACvB,KAAK,CAAC,IAAI,KAAK,kBAAkB;YACjC,KAAK,CAAC,IAAI,KAAK,OAAO;YACtB,KAAK,CAAC,IAAI,KAAK,QAAQ;YACvB,KAAK,CAAC,IAAI,KAAK,QAAQ;YACvB,KAAK,CAAC,IAAI,KAAK,OAAO,EACtB,CAAC;YACD,uEAAuE;YACvE,sEAAsE;YACtE,qEAAqE;YACrE,8BAA8B;YAC9B,SAAS;QACX,CAAC;QACD,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,IAAY;IAC3C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,CAAC,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReviewReport } from '../types.js';
|
|
2
|
+
export interface ReviewOptions {
|
|
3
|
+
/** Base ref. Default: origin/main → main → origin/master → master → HEAD~1. */
|
|
4
|
+
base?: string;
|
|
5
|
+
/** Head ref. Default: HEAD. */
|
|
6
|
+
head?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Compose a one-shot PR review. Builds head + base graphs (worktree dance),
|
|
10
|
+
* joins the structural diff with hotspot risk scores, surfaces cycles
|
|
11
|
+
* introduced by the PR, flags newly-risky functions, and reports
|
|
12
|
+
* package.json deltas. Output is shaped for an agent to read once and decide
|
|
13
|
+
* whether to merge, request changes, or escalate.
|
|
14
|
+
*
|
|
15
|
+
* Verdict heuristic (rough; tune with usage):
|
|
16
|
+
* block - max changed-file risk >= 80 OR a new cycle includes added files
|
|
17
|
+
* review - max changed-file risk >= 40 OR new high-CC functions OR
|
|
18
|
+
* major-dep-bump
|
|
19
|
+
* ok - otherwise
|
|
20
|
+
*/
|
|
21
|
+
export declare function computeReview(rootPath: string, options?: ReviewOptions): Promise<ReviewReport>;
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { scanRepository } from './repositoryScanner.js';
|
|
6
|
+
import { collectIssues } from './issueEngine.js';
|
|
7
|
+
import { buildCodeGraph } from './codeGraph.js';
|
|
8
|
+
import { analyzeHotspots } from './hotspotAnalyzer.js';
|
|
9
|
+
import { computeCoupling } from './couplingAnalyzer.js';
|
|
10
|
+
import { diffGraphs } from './prDiff.js';
|
|
11
|
+
const HIGH_CC_THRESHOLD = 10;
|
|
12
|
+
const CC_JUMP_THRESHOLD = 5;
|
|
13
|
+
const RISK_VERDICT_BLOCK_SCORE = 80;
|
|
14
|
+
const RISK_VERDICT_REVIEW_SCORE = 40;
|
|
15
|
+
/**
|
|
16
|
+
* Compose a one-shot PR review. Builds head + base graphs (worktree dance),
|
|
17
|
+
* joins the structural diff with hotspot risk scores, surfaces cycles
|
|
18
|
+
* introduced by the PR, flags newly-risky functions, and reports
|
|
19
|
+
* package.json deltas. Output is shaped for an agent to read once and decide
|
|
20
|
+
* whether to merge, request changes, or escalate.
|
|
21
|
+
*
|
|
22
|
+
* Verdict heuristic (rough; tune with usage):
|
|
23
|
+
* block - max changed-file risk >= 80 OR a new cycle includes added files
|
|
24
|
+
* review - max changed-file risk >= 40 OR new high-CC functions OR
|
|
25
|
+
* major-dep-bump
|
|
26
|
+
* ok - otherwise
|
|
27
|
+
*/
|
|
28
|
+
export async function computeReview(rootPath, options = {}) {
|
|
29
|
+
const isRepo = await isGitRepository(rootPath);
|
|
30
|
+
if (!isRepo) {
|
|
31
|
+
return unavailable('Not a git repository - PR review requires git history.', options);
|
|
32
|
+
}
|
|
33
|
+
const headRef = options.head ?? 'HEAD';
|
|
34
|
+
const baseRef = options.base ?? (await pickDefaultBase(rootPath));
|
|
35
|
+
const headSha = await resolveSha(rootPath, headRef);
|
|
36
|
+
const baseSha = await resolveSha(rootPath, baseRef);
|
|
37
|
+
if (!baseSha) {
|
|
38
|
+
return unavailable(`Could not resolve base ref "${baseRef}".`, options, baseRef, headRef, headSha);
|
|
39
|
+
}
|
|
40
|
+
// Head-side data: scan + graph + issues + hotspots.
|
|
41
|
+
const headScan = await scanRepository(rootPath);
|
|
42
|
+
const headGraph = await buildCodeGraph(rootPath, headScan.files);
|
|
43
|
+
const headIssues = await collectIssues(rootPath, headScan.files);
|
|
44
|
+
const headHotspots = await analyzeHotspots(rootPath, headScan.files, headIssues, {
|
|
45
|
+
limit: 200,
|
|
46
|
+
graph: headGraph,
|
|
47
|
+
});
|
|
48
|
+
// Base-side: spin up a worktree, scan, build graph. Best-effort cleanup.
|
|
49
|
+
const worktreeDir = await mkTempWorktreeDir();
|
|
50
|
+
let baseGraph;
|
|
51
|
+
let basePackageManifests;
|
|
52
|
+
try {
|
|
53
|
+
await runGit(rootPath, ['worktree', 'add', '--detach', worktreeDir, baseSha]);
|
|
54
|
+
const baseScan = await scanRepository(worktreeDir);
|
|
55
|
+
baseGraph = await buildCodeGraph(worktreeDir, baseScan.files);
|
|
56
|
+
basePackageManifests = await readManifests(worktreeDir);
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
await runGit(rootPath, ['worktree', 'remove', '--force', worktreeDir]).catch(() => { });
|
|
60
|
+
await fs.rm(worktreeDir, { recursive: true, force: true }).catch(() => { });
|
|
61
|
+
}
|
|
62
|
+
const headPackageManifests = await readManifests(rootPath);
|
|
63
|
+
const prDiff = diffGraphs(baseRef, baseSha, headRef, headSha, baseGraph, headGraph);
|
|
64
|
+
// Build the per-file enriched view. Index head hotspots by path for O(1) lookup.
|
|
65
|
+
const hotspotByPath = new Map();
|
|
66
|
+
for (const h of headHotspots.hotspots)
|
|
67
|
+
hotspotByPath.set(h.relativePath, h.riskScore);
|
|
68
|
+
const changedFiles = [];
|
|
69
|
+
for (const f of prDiff.filesAdded) {
|
|
70
|
+
const headFile = headGraph.files.get(f);
|
|
71
|
+
changedFiles.push({
|
|
72
|
+
relativePath: f,
|
|
73
|
+
status: 'added',
|
|
74
|
+
riskScore: hotspotByPath.get(f) ?? null,
|
|
75
|
+
cyclomaticComplexity: headFile?.parseOk ? headFile.cyclomaticComplexity : null,
|
|
76
|
+
cyclomaticDelta: null,
|
|
77
|
+
exportsAdded: headFile?.exports.length ?? 0,
|
|
78
|
+
exportsRemoved: 0,
|
|
79
|
+
importsAdded: headFile?.imports.length ?? 0,
|
|
80
|
+
importsRemoved: 0,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
for (const f of prDiff.filesRemoved) {
|
|
84
|
+
const baseFile = baseGraph.files.get(f);
|
|
85
|
+
changedFiles.push({
|
|
86
|
+
relativePath: f,
|
|
87
|
+
status: 'removed',
|
|
88
|
+
riskScore: null,
|
|
89
|
+
cyclomaticComplexity: null,
|
|
90
|
+
cyclomaticDelta: null,
|
|
91
|
+
exportsAdded: 0,
|
|
92
|
+
exportsRemoved: baseFile?.exports.length ?? 0,
|
|
93
|
+
importsAdded: 0,
|
|
94
|
+
importsRemoved: baseFile?.imports.length ?? 0,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
for (const f of prDiff.filesModified) {
|
|
98
|
+
const headFile = headGraph.files.get(f.relativePath);
|
|
99
|
+
changedFiles.push({
|
|
100
|
+
relativePath: f.relativePath,
|
|
101
|
+
status: 'modified',
|
|
102
|
+
riskScore: hotspotByPath.get(f.relativePath) ?? null,
|
|
103
|
+
cyclomaticComplexity: headFile?.parseOk ? headFile.cyclomaticComplexity : null,
|
|
104
|
+
cyclomaticDelta: f.cyclomaticDelta,
|
|
105
|
+
exportsAdded: f.exportsAdded.length,
|
|
106
|
+
exportsRemoved: f.exportsRemoved.length,
|
|
107
|
+
importsAdded: f.importsAdded.length,
|
|
108
|
+
importsRemoved: f.importsRemoved.length,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
changedFiles.sort((a, b) => (b.riskScore ?? 0) - (a.riskScore ?? 0));
|
|
112
|
+
// Cycles: compute on both sides; classify head cycles as new/expanded based
|
|
113
|
+
// on overlap with base cycles.
|
|
114
|
+
const headCoupling = computeCoupling(headGraph);
|
|
115
|
+
const baseCoupling = computeCoupling(baseGraph);
|
|
116
|
+
const newCycles = classifyNewCycles(baseCoupling.cycles, headCoupling.cycles, prDiff.filesAdded);
|
|
117
|
+
// Risky functions: compare per-file function lists between base and head.
|
|
118
|
+
const riskyFunctions = findRiskyFunctions(baseGraph, headGraph, prDiff);
|
|
119
|
+
// Dependency changes across root + workspaces.
|
|
120
|
+
const dependencyChanges = diffManifests(basePackageManifests, headPackageManifests);
|
|
121
|
+
// Verdict.
|
|
122
|
+
const { verdict, summary } = decideVerdict(changedFiles, newCycles, riskyFunctions, dependencyChanges);
|
|
123
|
+
return {
|
|
124
|
+
available: true,
|
|
125
|
+
base: { ref: baseRef, resolvedSha: baseSha },
|
|
126
|
+
head: { ref: headRef, resolvedSha: headSha },
|
|
127
|
+
prDiff,
|
|
128
|
+
changedFiles,
|
|
129
|
+
newCycles,
|
|
130
|
+
riskyFunctions,
|
|
131
|
+
dependencyChanges,
|
|
132
|
+
verdict,
|
|
133
|
+
summary,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// ── cycle classification ──────────────────────────────────
|
|
137
|
+
function classifyNewCycles(baseCycles, headCycles, filesAddedInPr) {
|
|
138
|
+
const added = new Set(filesAddedInPr);
|
|
139
|
+
const out = [];
|
|
140
|
+
for (const head of headCycles) {
|
|
141
|
+
const headSet = new Set(head.files);
|
|
142
|
+
let bestOverlap = 0;
|
|
143
|
+
for (const base of baseCycles) {
|
|
144
|
+
let overlap = 0;
|
|
145
|
+
for (const f of base.files)
|
|
146
|
+
if (headSet.has(f))
|
|
147
|
+
overlap++;
|
|
148
|
+
if (overlap > bestOverlap)
|
|
149
|
+
bestOverlap = overlap;
|
|
150
|
+
}
|
|
151
|
+
if (bestOverlap === 0) {
|
|
152
|
+
out.push({ files: [...head.files].sort(), size: head.files.length, classification: 'new' });
|
|
153
|
+
}
|
|
154
|
+
else if (bestOverlap < head.files.length) {
|
|
155
|
+
// cycle existed but grew
|
|
156
|
+
out.push({
|
|
157
|
+
files: [...head.files].sort(),
|
|
158
|
+
size: head.files.length,
|
|
159
|
+
classification: 'expanded',
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// bestOverlap === head.files.length means the cycle is identical at base.
|
|
163
|
+
}
|
|
164
|
+
// Bump cycles where any file is newly added to the very front.
|
|
165
|
+
out.sort((a, b) => {
|
|
166
|
+
const aTouchesAdded = a.files.some((f) => added.has(f)) ? 0 : 1;
|
|
167
|
+
const bTouchesAdded = b.files.some((f) => added.has(f)) ? 0 : 1;
|
|
168
|
+
if (aTouchesAdded !== bTouchesAdded)
|
|
169
|
+
return aTouchesAdded - bTouchesAdded;
|
|
170
|
+
return b.size - a.size;
|
|
171
|
+
});
|
|
172
|
+
return out;
|
|
173
|
+
}
|
|
174
|
+
// ── risky function detection ──────────────────────────────
|
|
175
|
+
function findRiskyFunctions(baseGraph, headGraph, prDiff) {
|
|
176
|
+
const out = [];
|
|
177
|
+
for (const file of prDiff.filesAdded) {
|
|
178
|
+
const head = headGraph.files.get(file);
|
|
179
|
+
if (!head)
|
|
180
|
+
continue;
|
|
181
|
+
for (const fn of head.functions ?? []) {
|
|
182
|
+
if (fn.cyclomaticComplexity >= HIGH_CC_THRESHOLD) {
|
|
183
|
+
out.push({
|
|
184
|
+
file,
|
|
185
|
+
name: fn.name,
|
|
186
|
+
line: fn.line,
|
|
187
|
+
endLine: fn.endLine,
|
|
188
|
+
cyclomaticComplexity: fn.cyclomaticComplexity,
|
|
189
|
+
baseCc: null,
|
|
190
|
+
reason: 'added',
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
for (const f of prDiff.filesModified) {
|
|
196
|
+
const head = headGraph.files.get(f.relativePath);
|
|
197
|
+
const base = baseGraph.files.get(f.relativePath);
|
|
198
|
+
if (!head || !base)
|
|
199
|
+
continue;
|
|
200
|
+
const baseByName = new Map();
|
|
201
|
+
for (const fn of base.functions ?? [])
|
|
202
|
+
baseByName.set(fn.name, fn.cyclomaticComplexity);
|
|
203
|
+
for (const fn of head.functions ?? []) {
|
|
204
|
+
const baseCc = baseByName.get(fn.name);
|
|
205
|
+
if (baseCc === undefined) {
|
|
206
|
+
// Newly added function. Flag if high CC.
|
|
207
|
+
if (fn.cyclomaticComplexity >= HIGH_CC_THRESHOLD) {
|
|
208
|
+
out.push({
|
|
209
|
+
file: f.relativePath,
|
|
210
|
+
name: fn.name,
|
|
211
|
+
line: fn.line,
|
|
212
|
+
endLine: fn.endLine,
|
|
213
|
+
cyclomaticComplexity: fn.cyclomaticComplexity,
|
|
214
|
+
baseCc: null,
|
|
215
|
+
reason: 'added',
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
// Existed: flag if it newly crossed the threshold.
|
|
221
|
+
if (baseCc < HIGH_CC_THRESHOLD &&
|
|
222
|
+
fn.cyclomaticComplexity >= HIGH_CC_THRESHOLD) {
|
|
223
|
+
out.push({
|
|
224
|
+
file: f.relativePath,
|
|
225
|
+
name: fn.name,
|
|
226
|
+
line: fn.line,
|
|
227
|
+
endLine: fn.endLine,
|
|
228
|
+
cyclomaticComplexity: fn.cyclomaticComplexity,
|
|
229
|
+
baseCc,
|
|
230
|
+
reason: 'crossed-threshold',
|
|
231
|
+
});
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
// Or: jumped by JUMP threshold even if both sides under HIGH_CC_THRESHOLD.
|
|
235
|
+
if (fn.cyclomaticComplexity - baseCc >= CC_JUMP_THRESHOLD) {
|
|
236
|
+
out.push({
|
|
237
|
+
file: f.relativePath,
|
|
238
|
+
name: fn.name,
|
|
239
|
+
line: fn.line,
|
|
240
|
+
endLine: fn.endLine,
|
|
241
|
+
cyclomaticComplexity: fn.cyclomaticComplexity,
|
|
242
|
+
baseCc,
|
|
243
|
+
reason: 'jumped',
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
out.sort((a, b) => b.cyclomaticComplexity - a.cyclomaticComplexity);
|
|
249
|
+
return out;
|
|
250
|
+
}
|
|
251
|
+
async function readManifests(rootPath) {
|
|
252
|
+
// Use detectWorkspaces to enumerate; if no workspaces just read the root.
|
|
253
|
+
const { detectWorkspaces } = await import('./monorepo.js');
|
|
254
|
+
const ws = await detectWorkspaces(rootPath);
|
|
255
|
+
const out = new Map();
|
|
256
|
+
const all = ws.kind === 'none' ? [] : ws.packages;
|
|
257
|
+
if (all.length === 0) {
|
|
258
|
+
const root = await readOneManifest(rootPath, 'package.json', '');
|
|
259
|
+
if (root)
|
|
260
|
+
out.set('package.json', root);
|
|
261
|
+
return out;
|
|
262
|
+
}
|
|
263
|
+
for (const p of all) {
|
|
264
|
+
const manifestRel = p.relativePath ? `${p.relativePath}/package.json` : 'package.json';
|
|
265
|
+
const dir = path.join(rootPath, p.relativePath);
|
|
266
|
+
const m = await readOneManifest(dir, manifestRel, p.name);
|
|
267
|
+
if (m)
|
|
268
|
+
out.set(manifestRel, m);
|
|
269
|
+
}
|
|
270
|
+
return out;
|
|
271
|
+
}
|
|
272
|
+
async function readOneManifest(dir, manifestFile, workspaceName) {
|
|
273
|
+
const p = path.join(dir, 'package.json');
|
|
274
|
+
let raw;
|
|
275
|
+
try {
|
|
276
|
+
raw = await fs.readFile(p, 'utf-8');
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
let parsed;
|
|
282
|
+
try {
|
|
283
|
+
parsed = JSON.parse(raw);
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
workspace: workspaceName,
|
|
290
|
+
manifestFile,
|
|
291
|
+
dependencies: parsed.dependencies ?? {},
|
|
292
|
+
devDependencies: parsed.devDependencies ?? {},
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function diffManifests(base, head) {
|
|
296
|
+
const out = [];
|
|
297
|
+
const allManifests = new Set([...base.keys(), ...head.keys()]);
|
|
298
|
+
for (const manifestFile of allManifests) {
|
|
299
|
+
const b = base.get(manifestFile);
|
|
300
|
+
const h = head.get(manifestFile);
|
|
301
|
+
if (!b && !h)
|
|
302
|
+
continue;
|
|
303
|
+
const change = diffOneManifest(b, h, manifestFile);
|
|
304
|
+
if (change.added.length || change.removed.length || change.bumped.length) {
|
|
305
|
+
out.push(change);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
out.sort((a, b) => a.manifestFile.localeCompare(b.manifestFile));
|
|
309
|
+
return out;
|
|
310
|
+
}
|
|
311
|
+
function diffOneManifest(base, head, manifestFile) {
|
|
312
|
+
const workspace = head?.workspace ?? base?.workspace ?? '';
|
|
313
|
+
const baseDeps = base?.dependencies ?? {};
|
|
314
|
+
const baseDev = base?.devDependencies ?? {};
|
|
315
|
+
const headDeps = head?.dependencies ?? {};
|
|
316
|
+
const headDev = head?.devDependencies ?? {};
|
|
317
|
+
const added = [];
|
|
318
|
+
const removed = [];
|
|
319
|
+
const bumped = [];
|
|
320
|
+
for (const [name, version] of Object.entries(headDeps)) {
|
|
321
|
+
if (!(name in baseDeps))
|
|
322
|
+
added.push({ name, version, kind: 'dep' });
|
|
323
|
+
else if (baseDeps[name] !== version)
|
|
324
|
+
bumped.push({ name, from: baseDeps[name], to: version, kind: 'dep' });
|
|
325
|
+
}
|
|
326
|
+
for (const [name, version] of Object.entries(baseDeps)) {
|
|
327
|
+
if (!(name in headDeps))
|
|
328
|
+
removed.push({ name, version, kind: 'dep' });
|
|
329
|
+
}
|
|
330
|
+
for (const [name, version] of Object.entries(headDev)) {
|
|
331
|
+
if (!(name in baseDev))
|
|
332
|
+
added.push({ name, version, kind: 'dev' });
|
|
333
|
+
else if (baseDev[name] !== version)
|
|
334
|
+
bumped.push({ name, from: baseDev[name], to: version, kind: 'dev' });
|
|
335
|
+
}
|
|
336
|
+
for (const [name, version] of Object.entries(baseDev)) {
|
|
337
|
+
if (!(name in headDev))
|
|
338
|
+
removed.push({ name, version, kind: 'dev' });
|
|
339
|
+
}
|
|
340
|
+
added.sort((a, b) => a.name.localeCompare(b.name));
|
|
341
|
+
removed.sort((a, b) => a.name.localeCompare(b.name));
|
|
342
|
+
bumped.sort((a, b) => a.name.localeCompare(b.name));
|
|
343
|
+
return { workspace, manifestFile, added, removed, bumped };
|
|
344
|
+
}
|
|
345
|
+
// ── verdict ───────────────────────────────────────────────
|
|
346
|
+
function decideVerdict(changedFiles, newCycles, riskyFunctions, depChanges) {
|
|
347
|
+
const summary = [];
|
|
348
|
+
let verdict = 'ok';
|
|
349
|
+
const maxRisk = Math.max(0, ...changedFiles.map((f) => f.riskScore ?? 0));
|
|
350
|
+
if (maxRisk >= RISK_VERDICT_BLOCK_SCORE) {
|
|
351
|
+
verdict = 'block';
|
|
352
|
+
summary.push(`Maximum changed-file risk score is ${maxRisk.toFixed(1)} (>= ${RISK_VERDICT_BLOCK_SCORE}).`);
|
|
353
|
+
}
|
|
354
|
+
else if (maxRisk >= RISK_VERDICT_REVIEW_SCORE) {
|
|
355
|
+
verdict = bumpTo(verdict, 'review');
|
|
356
|
+
summary.push(`Maximum changed-file risk score is ${maxRisk.toFixed(1)} (>= ${RISK_VERDICT_REVIEW_SCORE}).`);
|
|
357
|
+
}
|
|
358
|
+
if (newCycles.length > 0) {
|
|
359
|
+
const newOnly = newCycles.filter((c) => c.classification === 'new');
|
|
360
|
+
if (newOnly.length > 0) {
|
|
361
|
+
verdict = 'block';
|
|
362
|
+
summary.push(`${newOnly.length} new import cycle(s) introduced.`);
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
verdict = bumpTo(verdict, 'review');
|
|
366
|
+
summary.push(`${newCycles.length} cycle(s) expanded.`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (riskyFunctions.length > 0) {
|
|
370
|
+
verdict = bumpTo(verdict, 'review');
|
|
371
|
+
summary.push(`${riskyFunctions.length} function(s) flagged: high CC added or jumped.`);
|
|
372
|
+
}
|
|
373
|
+
if (depChanges.length > 0) {
|
|
374
|
+
const totals = depChanges.reduce((acc, d) => {
|
|
375
|
+
acc.added += d.added.length;
|
|
376
|
+
acc.removed += d.removed.length;
|
|
377
|
+
acc.bumped += d.bumped.length;
|
|
378
|
+
return acc;
|
|
379
|
+
}, { added: 0, removed: 0, bumped: 0 });
|
|
380
|
+
if (totals.added + totals.removed + totals.bumped > 0) {
|
|
381
|
+
summary.push(`Dependency changes: +${totals.added} -${totals.removed} ~${totals.bumped}.`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (changedFiles.length === 0 && summary.length === 0) {
|
|
385
|
+
summary.push('No structural changes detected between base and head.');
|
|
386
|
+
}
|
|
387
|
+
else if (verdict === 'ok' && summary.length === 0) {
|
|
388
|
+
summary.push(`${changedFiles.length} file(s) changed; no risk signals.`);
|
|
389
|
+
}
|
|
390
|
+
return { verdict, summary };
|
|
391
|
+
}
|
|
392
|
+
function bumpTo(current, target) {
|
|
393
|
+
const order = { ok: 0, review: 1, block: 2 };
|
|
394
|
+
return order[target] > order[current] ? target : current;
|
|
395
|
+
}
|
|
396
|
+
// ── git helpers (mirror prDiff.ts; kept private to keep coupling low) ──
|
|
397
|
+
function unavailable(reason, options, baseRef = options.base ?? '', headRef = options.head ?? 'HEAD', headSha = null) {
|
|
398
|
+
return {
|
|
399
|
+
available: false,
|
|
400
|
+
reason,
|
|
401
|
+
base: { ref: baseRef, resolvedSha: null },
|
|
402
|
+
head: { ref: headRef, resolvedSha: headSha },
|
|
403
|
+
prDiff: {
|
|
404
|
+
available: false,
|
|
405
|
+
reason,
|
|
406
|
+
base: { ref: baseRef, resolvedSha: null },
|
|
407
|
+
head: { ref: headRef, resolvedSha: headSha },
|
|
408
|
+
filesAdded: [],
|
|
409
|
+
filesRemoved: [],
|
|
410
|
+
filesModified: [],
|
|
411
|
+
totalFilesChanged: 0,
|
|
412
|
+
},
|
|
413
|
+
changedFiles: [],
|
|
414
|
+
newCycles: [],
|
|
415
|
+
riskyFunctions: [],
|
|
416
|
+
dependencyChanges: [],
|
|
417
|
+
verdict: 'ok',
|
|
418
|
+
summary: [reason],
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
async function isGitRepository(rootPath) {
|
|
422
|
+
const { code } = await runGit(rootPath, ['rev-parse', '--is-inside-work-tree']).catch(() => ({
|
|
423
|
+
code: 1,
|
|
424
|
+
stdout: '',
|
|
425
|
+
stderr: '',
|
|
426
|
+
}));
|
|
427
|
+
return code === 0;
|
|
428
|
+
}
|
|
429
|
+
async function resolveSha(rootPath, ref) {
|
|
430
|
+
const { code, stdout } = await runGit(rootPath, ['rev-parse', '--verify', `${ref}^{commit}`]).catch(() => ({ code: 1, stdout: '', stderr: '' }));
|
|
431
|
+
if (code !== 0)
|
|
432
|
+
return null;
|
|
433
|
+
const sha = stdout.trim();
|
|
434
|
+
return sha || null;
|
|
435
|
+
}
|
|
436
|
+
async function pickDefaultBase(rootPath) {
|
|
437
|
+
for (const candidate of ['origin/main', 'main', 'origin/master', 'master']) {
|
|
438
|
+
if (await resolveSha(rootPath, candidate))
|
|
439
|
+
return candidate;
|
|
440
|
+
}
|
|
441
|
+
return 'HEAD~1';
|
|
442
|
+
}
|
|
443
|
+
async function mkTempWorktreeDir() {
|
|
444
|
+
return fs.mkdtemp(path.join(os.tmpdir(), 'projscan-review-'));
|
|
445
|
+
}
|
|
446
|
+
function runGit(cwd, args) {
|
|
447
|
+
return new Promise((resolve, reject) => {
|
|
448
|
+
const child = spawn('git', args, { cwd, env: process.env });
|
|
449
|
+
let stdout = '';
|
|
450
|
+
let stderr = '';
|
|
451
|
+
child.stdout.on('data', (d) => (stdout += d.toString()));
|
|
452
|
+
child.stderr.on('data', (d) => (stderr += d.toString()));
|
|
453
|
+
child.on('error', reject);
|
|
454
|
+
child.on('close', (code) => resolve({ code: code ?? 1, stdout, stderr }));
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/core/review.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,15 @@ export interface SearchHit {
|
|
|
24
24
|
pathMatch: boolean;
|
|
25
25
|
excerpt: string;
|
|
26
26
|
line: number;
|
|
27
|
+
/**
|
|
28
|
+
* Function context, set when the hit came from a sub-file semantic chunk
|
|
29
|
+
* (0.15.0+). Absent for file-level / lexical hits.
|
|
30
|
+
*/
|
|
31
|
+
function?: {
|
|
32
|
+
name: string;
|
|
33
|
+
startLine: number;
|
|
34
|
+
endLine: number;
|
|
35
|
+
};
|
|
27
36
|
}
|
|
28
37
|
export interface SearchOptions {
|
|
29
38
|
limit?: number;
|