projscan 1.4.0 → 1.6.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 +24 -7
- package/dist/cli/commands/applyFix.d.ts +7 -0
- package/dist/cli/commands/applyFix.js +113 -0
- package/dist/cli/commands/applyFix.js.map +1 -0
- package/dist/cli/commands/coverage.js +13 -0
- package/dist/cli/commands/coverage.js.map +1 -1
- package/dist/cli/commands/doctor.js +18 -2
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/explain.js +1 -0
- package/dist/cli/commands/explain.js.map +1 -1
- package/dist/cli/commands/impact.js +25 -1
- package/dist/cli/commands/impact.js.map +1 -1
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.js +70 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/installHook.d.ts +9 -0
- package/dist/cli/commands/installHook.js +90 -0
- package/dist/cli/commands/installHook.js.map +1 -0
- package/dist/cli/commands/memory.d.ts +11 -0
- package/dist/cli/commands/memory.js +175 -0
- package/dist/cli/commands/memory.js.map +1 -0
- package/dist/cli/commands/taint.d.ts +6 -0
- package/dist/cli/commands/taint.js +74 -0
- package/dist/cli/commands/taint.js.map +1 -0
- package/dist/cli/commands/workspace.d.ts +11 -0
- package/dist/cli/commands/workspace.js +115 -0
- package/dist/cli/commands/workspace.js.map +1 -0
- package/dist/cli/index.js +12 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/applyFix.d.ts +52 -0
- package/dist/core/applyFix.js +220 -0
- package/dist/core/applyFix.js.map +1 -0
- package/dist/core/ast.d.ts +9 -0
- package/dist/core/ast.js +35 -4
- package/dist/core/ast.js.map +1 -1
- package/dist/core/codeGraph.js +190 -241
- package/dist/core/codeGraph.js.map +1 -1
- package/dist/core/fileInspector.js +40 -44
- package/dist/core/fileInspector.js.map +1 -1
- package/dist/core/fixSuggest.d.ts +6 -0
- package/dist/core/fixSuggest.js +195 -0
- package/dist/core/fixSuggest.js.map +1 -1
- package/dist/core/hotspotAnalyzer.js +65 -19
- package/dist/core/hotspotAnalyzer.js.map +1 -1
- package/dist/core/impact.d.ts +8 -0
- package/dist/core/impact.js +41 -3
- package/dist/core/impact.js.map +1 -1
- package/dist/core/indexCache.js +4 -1
- package/dist/core/indexCache.js.map +1 -1
- package/dist/core/issueEngine.js +24 -0
- package/dist/core/issueEngine.js.map +1 -1
- package/dist/core/languages/csharpImports.js +6 -4
- package/dist/core/languages/csharpImports.js.map +1 -1
- package/dist/core/memory.d.ts +154 -0
- package/dist/core/memory.js +277 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/review.d.ts +25 -1
- package/dist/core/review.js +133 -2
- package/dist/core/review.js.map +1 -1
- package/dist/core/taint.d.ts +91 -0
- package/dist/core/taint.js +185 -0
- package/dist/core/taint.js.map +1 -0
- package/dist/core/workspace.d.ts +62 -0
- package/dist/core/workspace.js +127 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/mcp/prompts.js +274 -0
- package/dist/mcp/prompts.js.map +1 -1
- package/dist/mcp/server.js +162 -146
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tokenBudget.d.ts +22 -0
- package/dist/mcp/tokenBudget.js +26 -0
- package/dist/mcp/tokenBudget.js.map +1 -1
- package/dist/mcp/tools/applyFix.d.ts +16 -0
- package/dist/mcp/tools/applyFix.js +91 -0
- package/dist/mcp/tools/applyFix.js.map +1 -0
- package/dist/mcp/tools/doctor.js +65 -2
- package/dist/mcp/tools/doctor.js.map +1 -1
- package/dist/mcp/tools/explain.js +4 -3
- package/dist/mcp/tools/explain.js.map +1 -1
- package/dist/mcp/tools/explainIssue.js +3 -2
- package/dist/mcp/tools/explainIssue.js.map +1 -1
- package/dist/mcp/tools/file.js +3 -2
- package/dist/mcp/tools/file.js.map +1 -1
- package/dist/mcp/tools/graph.js +16 -11
- package/dist/mcp/tools/graph.js.map +1 -1
- package/dist/mcp/tools/impact.js +36 -3
- package/dist/mcp/tools/impact.js.map +1 -1
- package/dist/mcp/tools/memory.d.ts +19 -0
- package/dist/mcp/tools/memory.js +134 -0
- package/dist/mcp/tools/memory.js.map +1 -0
- package/dist/mcp/tools/review.js +25 -4
- package/dist/mcp/tools/review.js.map +1 -1
- package/dist/mcp/tools/taint.d.ts +15 -0
- package/dist/mcp/tools/taint.js +67 -0
- package/dist/mcp/tools/taint.js.map +1 -0
- package/dist/mcp/tools/upgrade.js +3 -2
- package/dist/mcp/tools/upgrade.js.map +1 -1
- package/dist/mcp/tools/workspaceGraph.d.ts +18 -0
- package/dist/mcp/tools/workspaceGraph.js +188 -0
- package/dist/mcp/tools/workspaceGraph.js.map +1 -0
- package/dist/mcp/tools.js +8 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/reporters/consoleReporter.d.ts +12 -1
- package/dist/reporters/consoleReporter.js +289 -179
- package/dist/reporters/consoleReporter.js.map +1 -1
- package/dist/reporters/markdownReporter.js +185 -128
- package/dist/reporters/markdownReporter.js.map +1 -1
- package/dist/tool-manifest.json +129 -6
- package/dist/types.d.ts +67 -0
- package/dist/utils/config.js +93 -53
- package/dist/utils/config.js.map +1 -1
- package/package.json +9 -2
package/dist/core/impact.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impact.js","sourceRoot":"","sources":["../../src/core/impact.ts"],"names":[],"mappings":"AAGA,MAAM,oBAAoB,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"impact.js","sourceRoot":"","sources":["../../src/core/impact.ts"],"names":[],"mappings":"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"}
|
package/dist/core/indexCache.js
CHANGED
|
@@ -7,7 +7,10 @@ const CACHE_FILE = 'graph.json';
|
|
|
7
7
|
// caches are discarded on load so we never read back missing CC as 0.
|
|
8
8
|
// v4: added `functions: [{name, line, endLine, cyclomaticComplexity}]` per
|
|
9
9
|
// file (0.13 "Agent Review"). v3 caches are discarded on first 0.13 run.
|
|
10
|
-
|
|
10
|
+
// v5: added `references` to per-function entries (1.6 "Operator" — taint
|
|
11
|
+
// analysis needs property-shaped reads). v4 caches are discarded on first
|
|
12
|
+
// 1.6 run so taint sees populated references on every parsed function.
|
|
13
|
+
const CACHE_VERSION = 5;
|
|
11
14
|
/**
|
|
12
15
|
* Load a previously cached code graph, if present and valid. Returns undefined
|
|
13
16
|
* when there's no cache or the cache is incompatible - caller should rebuild.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexCache.js","sourceRoot":"","sources":["../../src/core/indexCache.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"indexCache.js","sourceRoot":"","sources":["../../src/core/indexCache.ts"],"names":[],"mappings":"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"}
|
package/dist/core/issueEngine.js
CHANGED
|
@@ -13,6 +13,7 @@ import { check as pythonTestCheck } from '../analyzers/pythonTestCheck.js';
|
|
|
13
13
|
import { check as pythonLinterCheck } from '../analyzers/pythonLinterCheck.js';
|
|
14
14
|
import { check as pythonDependencyRiskCheck } from '../analyzers/pythonDependencyRiskCheck.js';
|
|
15
15
|
import { check as pythonUnusedDependencyCheck } from '../analyzers/pythonUnusedDependencyCheck.js';
|
|
16
|
+
import { loadMemory, recordRun, saveMemory } from './memory.js';
|
|
16
17
|
const checkers = [
|
|
17
18
|
eslintCheck,
|
|
18
19
|
prettierCheck,
|
|
@@ -50,6 +51,29 @@ export async function collectIssues(rootPath, files) {
|
|
|
50
51
|
if (preview)
|
|
51
52
|
issue.suggestedAction = preview;
|
|
52
53
|
}
|
|
54
|
+
// 1.5.0: Project Memory. Record this run's issue ids so projscan can
|
|
55
|
+
// surface "stable across N runs" suggestions on future invocations.
|
|
56
|
+
// Best-effort: any disk failure here is swallowed and does not affect
|
|
57
|
+
// the returned issues. The user-visible output is unchanged at this
|
|
58
|
+
// layer; the memory is consumed by the projscan_memory tool / CLI.
|
|
59
|
+
void recordRunInMemory(rootPath, issues);
|
|
53
60
|
return issues;
|
|
54
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* 1.5.0 — fire-and-forget memory recording. Loads the on-disk memory,
|
|
64
|
+
* folds in this run's rule ids (and any rule ids the user has
|
|
65
|
+
* suppressed via .projscanrc disableRules), and persists. Errors are
|
|
66
|
+
* swallowed; the analyzer pipeline never fails because of memory.
|
|
67
|
+
*/
|
|
68
|
+
async function recordRunInMemory(rootPath, issues) {
|
|
69
|
+
try {
|
|
70
|
+
const memory = await loadMemory(rootPath);
|
|
71
|
+
const ids = issues.map((i) => i.id).filter((id) => typeof id === 'string');
|
|
72
|
+
recordRun(memory, ids);
|
|
73
|
+
await saveMemory(rootPath, memory);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// best-effort
|
|
77
|
+
}
|
|
78
|
+
}
|
|
55
79
|
//# sourceMappingURL=issueEngine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issueEngine.js","sourceRoot":"","sources":["../../src/core/issueEngine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,KAAK,IAAI,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EAAE,KAAK,IAAI,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,KAAK,IAAI,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AACvF,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,KAAK,IAAI,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAC3F,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,KAAK,IAAI,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,KAAK,IAAI,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EAAE,KAAK,IAAI,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AAC/F,OAAO,EAAE,KAAK,IAAI,2BAA2B,EAAE,MAAM,6CAA6C,CAAC;
|
|
1
|
+
{"version":3,"file":"issueEngine.js","sourceRoot":"","sources":["../../src/core/issueEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,8 +39,12 @@ function collectUsing(node, out) {
|
|
|
39
39
|
if (named.length === 0)
|
|
40
40
|
return;
|
|
41
41
|
let alias;
|
|
42
|
-
let pathNode
|
|
43
|
-
if (named.length >= 2 &&
|
|
42
|
+
let pathNode;
|
|
43
|
+
if (named.length >= 2 &&
|
|
44
|
+
named[0].type === 'identifier' &&
|
|
45
|
+
(named[1].type === 'qualified_name' ||
|
|
46
|
+
named[1].type === 'identifier' ||
|
|
47
|
+
named[1].type === 'generic_name')) {
|
|
44
48
|
alias = named[0].text;
|
|
45
49
|
pathNode = named[1];
|
|
46
50
|
}
|
|
@@ -49,8 +53,6 @@ function collectUsing(node, out) {
|
|
|
49
53
|
// grammar may surface as a name).
|
|
50
54
|
pathNode = named[named.length - 1];
|
|
51
55
|
}
|
|
52
|
-
if (!pathNode)
|
|
53
|
-
return;
|
|
54
56
|
const source = readPath(pathNode);
|
|
55
57
|
if (!source)
|
|
56
58
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csharpImports.js","sourceRoot":"","sources":["../../../src/core/languages/csharpImports.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;YAAE,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;aAC9D,IAAI,KAAK,CAAC,IAAI,KAAK,mCAAmC,IAAI,KAAK,CAAC,IAAI,KAAK,uBAAuB,EAAE,CAAC;YACtG,8CAA8C;YAC9C,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;gBACxC,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;oBAAE,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,GAAgB;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC;IACxC,8DAA8D;IAC9D,mEAAmE;IACnE,gFAAgF;IAChF,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE/B,IAAI,KAAyB,CAAC;IAC9B,IAAI,
|
|
1
|
+
{"version":3,"file":"csharpImports.js","sourceRoot":"","sources":["../../../src/core/languages/csharpImports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Memory — a local feedback loop that learns which issues the
|
|
3
|
+
* user has effectively accepted (by leaving them open across many
|
|
4
|
+
* `projscan ci` / `projscan doctor` runs) and surfaces that signal so
|
|
5
|
+
* projscan can lower the noise on this specific repo over time.
|
|
6
|
+
*
|
|
7
|
+
* Stored at `.projscan-memory/memory.json` (sibling of the existing
|
|
8
|
+
* graph + session caches). Local-only; never phones home; honours
|
|
9
|
+
* .gitignore by living under the same directory family.
|
|
10
|
+
*
|
|
11
|
+
* Schema versioned so future evolutions can detect and migrate.
|
|
12
|
+
*
|
|
13
|
+
* Design principles:
|
|
14
|
+
* - Best-effort writes: a transient disk error never breaks a tool.
|
|
15
|
+
* - Idempotent recording: replaying the same observation is safe.
|
|
16
|
+
* - Bounded growth: per-rule history caps; rules unseen for 90 days
|
|
17
|
+
* are aged out.
|
|
18
|
+
* - Privacy: only stores rule ids and timestamps. No source content,
|
|
19
|
+
* no agent identity, no machine identifiers.
|
|
20
|
+
*/
|
|
21
|
+
export declare const MEMORY_SCHEMA_VERSION = 1;
|
|
22
|
+
/** Drop rules unseen for this many days. */
|
|
23
|
+
export declare const STALE_RULE_DAYS = 90;
|
|
24
|
+
/**
|
|
25
|
+
* "Stable" threshold: an issue that has appeared in ≥ this many runs
|
|
26
|
+
* over ≥ STABLE_RULE_DAYS days without being addressed is treated as
|
|
27
|
+
* accepted by the user. Tunable per-project via `.projscanrc.memory`
|
|
28
|
+
* in a future release.
|
|
29
|
+
*/
|
|
30
|
+
export declare const STABLE_RULE_RUN_COUNT = 3;
|
|
31
|
+
export declare const STABLE_RULE_DAYS = 7;
|
|
32
|
+
/**
|
|
33
|
+
* "Accepted hotspot" thresholds — a file ranked top-K in hotspots for
|
|
34
|
+
* ≥ HOT_RUN_COUNT runs over ≥ HOT_DAYS days, without its CC or churn
|
|
35
|
+
* dropping, is treated as accepted load-bearing debt. The hotspot
|
|
36
|
+
* reporter will tag it as `[accepted]` instead of repeated noise.
|
|
37
|
+
*/
|
|
38
|
+
export declare const HOT_RUN_COUNT = 5;
|
|
39
|
+
export declare const HOT_DAYS = 7;
|
|
40
|
+
export interface HotspotObservation {
|
|
41
|
+
/** Repo-relative path. */
|
|
42
|
+
file: string;
|
|
43
|
+
/** ISO 8601 of first time we saw this file in the top-K hotspots. */
|
|
44
|
+
firstSeenAt: string;
|
|
45
|
+
/** ISO 8601 of most recent sighting. */
|
|
46
|
+
lastSeenAt: string;
|
|
47
|
+
/** Total runs that put this file in the top-K. */
|
|
48
|
+
runCount: number;
|
|
49
|
+
/** Last-recorded CC (file-level). Used to detect "the file is improving." */
|
|
50
|
+
lastCc: number | null;
|
|
51
|
+
/** Last-recorded churn count. */
|
|
52
|
+
lastChurn: number;
|
|
53
|
+
}
|
|
54
|
+
export interface RuleObservation {
|
|
55
|
+
/** Stable rule id (e.g. `unused-dependency-foo`, `cycle-detected-3`). */
|
|
56
|
+
ruleId: string;
|
|
57
|
+
/** ISO 8601 timestamp of first time we saw this rule. */
|
|
58
|
+
firstSeenAt: string;
|
|
59
|
+
/** ISO 8601 timestamp of most recent time we saw this rule. */
|
|
60
|
+
lastSeenAt: string;
|
|
61
|
+
/** Total number of distinct runs that surfaced this rule. */
|
|
62
|
+
runCount: number;
|
|
63
|
+
/**
|
|
64
|
+
* Heuristic: the rule WAS surfaced in run N but NOT in run N+1.
|
|
65
|
+
* Increments whenever we observe that disappearance. High values
|
|
66
|
+
* signal "user actively fixes these"; zero signals "this is
|
|
67
|
+
* background noise to them."
|
|
68
|
+
*/
|
|
69
|
+
fixedCount: number;
|
|
70
|
+
/**
|
|
71
|
+
* True if the user explicitly suppressed the rule via .projscanrc
|
|
72
|
+
* `disableRules`. Recorded so `projscan memory forget` can surface
|
|
73
|
+
* them as already-quieted.
|
|
74
|
+
*/
|
|
75
|
+
suppressedInConfig: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface ProjectMemory {
|
|
78
|
+
schemaVersion: number;
|
|
79
|
+
/** ISO 8601. Updated on every save. */
|
|
80
|
+
lastUpdatedAt: string;
|
|
81
|
+
/**
|
|
82
|
+
* Per-rule history keyed by rule id. Rules unseen for STALE_RULE_DAYS
|
|
83
|
+
* are dropped on next save.
|
|
84
|
+
*/
|
|
85
|
+
rules: Record<string, RuleObservation>;
|
|
86
|
+
/**
|
|
87
|
+
* 1.5+ — per-hotspot history keyed by repo-relative path. Files
|
|
88
|
+
* unseen for STALE_RULE_DAYS are aged out alongside rules.
|
|
89
|
+
*/
|
|
90
|
+
hotspots?: Record<string, HotspotObservation>;
|
|
91
|
+
/**
|
|
92
|
+
* Total runs of `projscan doctor` / `projscan ci` against this repo
|
|
93
|
+
* since memory began. Used to compute fix-rate: a rule's fixedCount
|
|
94
|
+
* vs. the run count over its lifetime.
|
|
95
|
+
*/
|
|
96
|
+
totalRuns: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Load the project memory for `rootPath`. Returns a fresh empty
|
|
100
|
+
* memory object if the file is missing, corrupt, or has an
|
|
101
|
+
* unrecognised schema version. Never throws.
|
|
102
|
+
*/
|
|
103
|
+
export declare function loadMemory(rootPath: string): Promise<ProjectMemory>;
|
|
104
|
+
/**
|
|
105
|
+
* Persist the memory back to disk. Best-effort: failures are
|
|
106
|
+
* swallowed. Mirrors the session module's last-write-wins semantics.
|
|
107
|
+
*/
|
|
108
|
+
export declare function saveMemory(rootPath: string, memory: ProjectMemory): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Record one analyzer run's worth of issues. Called by the issue
|
|
111
|
+
* engine once per `projscan doctor` / `projscan ci` execution.
|
|
112
|
+
*
|
|
113
|
+
* `currentIds` is the set of rule ids surfaced in this run.
|
|
114
|
+
* `suppressedIds` is the set of rule ids the user has explicitly
|
|
115
|
+
* silenced via `.projscanrc disableRules`. Both lists are intersected
|
|
116
|
+
* with the existing memory to compute fix events: any rule in memory
|
|
117
|
+
* that was active last run but is now absent counts as "fixed."
|
|
118
|
+
*
|
|
119
|
+
* Mutates the memory in place; caller is responsible for `saveMemory`.
|
|
120
|
+
*/
|
|
121
|
+
export declare function recordRun(memory: ProjectMemory, currentIds: Iterable<string>, suppressedIds?: Iterable<string>): void;
|
|
122
|
+
/**
|
|
123
|
+
* Identify rules the user has "effectively accepted" — surfaced
|
|
124
|
+
* across ≥ STABLE_RULE_RUN_COUNT runs spanning ≥ STABLE_RULE_DAYS days
|
|
125
|
+
* without ever being fixed (fixedCount = 0) and not already suppressed.
|
|
126
|
+
*
|
|
127
|
+
* These are the suggestions to surface in the doctor's "Tip" line.
|
|
128
|
+
*/
|
|
129
|
+
export declare function findStableRules(memory: ProjectMemory): RuleObservation[];
|
|
130
|
+
/** Drop a single rule's history. Returns true if the rule existed. */
|
|
131
|
+
export declare function forgetRule(memory: ProjectMemory, ruleId: string): boolean;
|
|
132
|
+
/**
|
|
133
|
+
* 1.5+ — record a hotspot run. `topFiles` is the list of paths
|
|
134
|
+
* currently in the top-K of `projscan hotspots` along with their
|
|
135
|
+
* file-level CC and churn counts. We track each file's appearance
|
|
136
|
+
* history and the most-recent CC/churn so `findAcceptedHotspots` can
|
|
137
|
+
* decide whether the file is genuinely stuck or actively improving.
|
|
138
|
+
*
|
|
139
|
+
* Mutates memory in place; caller is responsible for `saveMemory`.
|
|
140
|
+
*/
|
|
141
|
+
export declare function recordHotspots(memory: ProjectMemory, topFiles: ReadonlyArray<{
|
|
142
|
+
file: string;
|
|
143
|
+
cc: number | null;
|
|
144
|
+
churn: number;
|
|
145
|
+
}>): void;
|
|
146
|
+
/**
|
|
147
|
+
* 1.5+ — files that have ranked in the top-K hotspots for ≥
|
|
148
|
+
* HOT_RUN_COUNT runs over ≥ HOT_DAYS days. The hotspot reporter
|
|
149
|
+
* surfaces these as `[accepted]` so the user isn't repeatedly
|
|
150
|
+
* pestered about the same load-bearing debt.
|
|
151
|
+
*/
|
|
152
|
+
export declare function findAcceptedHotspots(memory: ProjectMemory): HotspotObservation[];
|
|
153
|
+
/** 1.5+ — drop a single hotspot's history (analogue of forgetRule). */
|
|
154
|
+
export declare function forgetHotspot(memory: ProjectMemory, file: string): boolean;
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Project Memory — a local feedback loop that learns which issues the
|
|
5
|
+
* user has effectively accepted (by leaving them open across many
|
|
6
|
+
* `projscan ci` / `projscan doctor` runs) and surfaces that signal so
|
|
7
|
+
* projscan can lower the noise on this specific repo over time.
|
|
8
|
+
*
|
|
9
|
+
* Stored at `.projscan-memory/memory.json` (sibling of the existing
|
|
10
|
+
* graph + session caches). Local-only; never phones home; honours
|
|
11
|
+
* .gitignore by living under the same directory family.
|
|
12
|
+
*
|
|
13
|
+
* Schema versioned so future evolutions can detect and migrate.
|
|
14
|
+
*
|
|
15
|
+
* Design principles:
|
|
16
|
+
* - Best-effort writes: a transient disk error never breaks a tool.
|
|
17
|
+
* - Idempotent recording: replaying the same observation is safe.
|
|
18
|
+
* - Bounded growth: per-rule history caps; rules unseen for 90 days
|
|
19
|
+
* are aged out.
|
|
20
|
+
* - Privacy: only stores rule ids and timestamps. No source content,
|
|
21
|
+
* no agent identity, no machine identifiers.
|
|
22
|
+
*/
|
|
23
|
+
export const MEMORY_SCHEMA_VERSION = 1;
|
|
24
|
+
const MEMORY_DIR = '.projscan-memory';
|
|
25
|
+
const MEMORY_FILENAME = 'memory.json';
|
|
26
|
+
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
27
|
+
/** Drop rules unseen for this many days. */
|
|
28
|
+
export const STALE_RULE_DAYS = 90;
|
|
29
|
+
/**
|
|
30
|
+
* "Stable" threshold: an issue that has appeared in ≥ this many runs
|
|
31
|
+
* over ≥ STABLE_RULE_DAYS days without being addressed is treated as
|
|
32
|
+
* accepted by the user. Tunable per-project via `.projscanrc.memory`
|
|
33
|
+
* in a future release.
|
|
34
|
+
*/
|
|
35
|
+
export const STABLE_RULE_RUN_COUNT = 3;
|
|
36
|
+
export const STABLE_RULE_DAYS = 7;
|
|
37
|
+
/**
|
|
38
|
+
* "Accepted hotspot" thresholds — a file ranked top-K in hotspots for
|
|
39
|
+
* ≥ HOT_RUN_COUNT runs over ≥ HOT_DAYS days, without its CC or churn
|
|
40
|
+
* dropping, is treated as accepted load-bearing debt. The hotspot
|
|
41
|
+
* reporter will tag it as `[accepted]` instead of repeated noise.
|
|
42
|
+
*/
|
|
43
|
+
export const HOT_RUN_COUNT = 5;
|
|
44
|
+
export const HOT_DAYS = 7;
|
|
45
|
+
/**
|
|
46
|
+
* Load the project memory for `rootPath`. Returns a fresh empty
|
|
47
|
+
* memory object if the file is missing, corrupt, or has an
|
|
48
|
+
* unrecognised schema version. Never throws.
|
|
49
|
+
*/
|
|
50
|
+
export async function loadMemory(rootPath) {
|
|
51
|
+
const filePath = memoryFilePath(rootPath);
|
|
52
|
+
let raw;
|
|
53
|
+
try {
|
|
54
|
+
raw = await fs.readFile(filePath, 'utf-8');
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return createFresh();
|
|
58
|
+
}
|
|
59
|
+
let parsed;
|
|
60
|
+
try {
|
|
61
|
+
parsed = JSON.parse(raw);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return createFresh();
|
|
65
|
+
}
|
|
66
|
+
if (!isMemoryShape(parsed) || parsed.schemaVersion !== MEMORY_SCHEMA_VERSION) {
|
|
67
|
+
return createFresh();
|
|
68
|
+
}
|
|
69
|
+
// 1.5+ — older saves predate the hotspots field. Backfill it so
|
|
70
|
+
// callers can rely on the property being present.
|
|
71
|
+
if (!parsed.hotspots)
|
|
72
|
+
parsed.hotspots = {};
|
|
73
|
+
return parsed;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Persist the memory back to disk. Best-effort: failures are
|
|
77
|
+
* swallowed. Mirrors the session module's last-write-wins semantics.
|
|
78
|
+
*/
|
|
79
|
+
export async function saveMemory(rootPath, memory) {
|
|
80
|
+
try {
|
|
81
|
+
const dir = path.join(rootPath, MEMORY_DIR);
|
|
82
|
+
await fs.mkdir(dir, { recursive: true });
|
|
83
|
+
const filePath = memoryFilePath(rootPath);
|
|
84
|
+
memory.lastUpdatedAt = new Date().toISOString();
|
|
85
|
+
await fs.writeFile(filePath, JSON.stringify(memory, null, 2), 'utf-8');
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// best-effort
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Record one analyzer run's worth of issues. Called by the issue
|
|
93
|
+
* engine once per `projscan doctor` / `projscan ci` execution.
|
|
94
|
+
*
|
|
95
|
+
* `currentIds` is the set of rule ids surfaced in this run.
|
|
96
|
+
* `suppressedIds` is the set of rule ids the user has explicitly
|
|
97
|
+
* silenced via `.projscanrc disableRules`. Both lists are intersected
|
|
98
|
+
* with the existing memory to compute fix events: any rule in memory
|
|
99
|
+
* that was active last run but is now absent counts as "fixed."
|
|
100
|
+
*
|
|
101
|
+
* Mutates the memory in place; caller is responsible for `saveMemory`.
|
|
102
|
+
*/
|
|
103
|
+
export function recordRun(memory, currentIds, suppressedIds = []) {
|
|
104
|
+
const nowIso = new Date().toISOString();
|
|
105
|
+
const currentSet = new Set(currentIds);
|
|
106
|
+
const suppressedSet = new Set(suppressedIds);
|
|
107
|
+
// Increment fixedCount for any previously-tracked rule that did NOT
|
|
108
|
+
// appear in this run AND wasn't merely suppressed.
|
|
109
|
+
for (const [ruleId, obs] of Object.entries(memory.rules)) {
|
|
110
|
+
const wasActiveLastRun = Date.parse(obs.lastSeenAt) >= Date.parse(memory.lastUpdatedAt) - MS_PER_DAY;
|
|
111
|
+
if (!currentSet.has(ruleId) && !suppressedSet.has(ruleId) && wasActiveLastRun) {
|
|
112
|
+
obs.fixedCount += 1;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Insert / update each currently-active rule.
|
|
116
|
+
for (const ruleId of currentSet) {
|
|
117
|
+
const existing = memory.rules[ruleId];
|
|
118
|
+
if (existing) {
|
|
119
|
+
existing.lastSeenAt = nowIso;
|
|
120
|
+
existing.runCount += 1;
|
|
121
|
+
existing.suppressedInConfig = suppressedSet.has(ruleId);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
memory.rules[ruleId] = {
|
|
125
|
+
ruleId,
|
|
126
|
+
firstSeenAt: nowIso,
|
|
127
|
+
lastSeenAt: nowIso,
|
|
128
|
+
runCount: 1,
|
|
129
|
+
fixedCount: 0,
|
|
130
|
+
suppressedInConfig: suppressedSet.has(ruleId),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Mark any rules that the user just suppressed via config (even if
|
|
135
|
+
// they didn't fire this run).
|
|
136
|
+
for (const ruleId of suppressedSet) {
|
|
137
|
+
const existing = memory.rules[ruleId];
|
|
138
|
+
if (existing)
|
|
139
|
+
existing.suppressedInConfig = true;
|
|
140
|
+
}
|
|
141
|
+
memory.totalRuns += 1;
|
|
142
|
+
ageOutStaleRules(memory);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Identify rules the user has "effectively accepted" — surfaced
|
|
146
|
+
* across ≥ STABLE_RULE_RUN_COUNT runs spanning ≥ STABLE_RULE_DAYS days
|
|
147
|
+
* without ever being fixed (fixedCount = 0) and not already suppressed.
|
|
148
|
+
*
|
|
149
|
+
* These are the suggestions to surface in the doctor's "Tip" line.
|
|
150
|
+
*/
|
|
151
|
+
export function findStableRules(memory) {
|
|
152
|
+
const now = Date.now();
|
|
153
|
+
const stableMs = STABLE_RULE_DAYS * MS_PER_DAY;
|
|
154
|
+
const out = [];
|
|
155
|
+
for (const obs of Object.values(memory.rules)) {
|
|
156
|
+
if (obs.suppressedInConfig)
|
|
157
|
+
continue;
|
|
158
|
+
if (obs.fixedCount > 0)
|
|
159
|
+
continue;
|
|
160
|
+
if (obs.runCount < STABLE_RULE_RUN_COUNT)
|
|
161
|
+
continue;
|
|
162
|
+
const ageMs = now - Date.parse(obs.firstSeenAt);
|
|
163
|
+
if (Number.isFinite(ageMs) && ageMs >= stableMs)
|
|
164
|
+
out.push(obs);
|
|
165
|
+
}
|
|
166
|
+
// Most-stable first (longest-running and most-seen).
|
|
167
|
+
out.sort((a, b) => b.runCount - a.runCount);
|
|
168
|
+
return out;
|
|
169
|
+
}
|
|
170
|
+
/** Drop a single rule's history. Returns true if the rule existed. */
|
|
171
|
+
export function forgetRule(memory, ruleId) {
|
|
172
|
+
if (!memory.rules[ruleId])
|
|
173
|
+
return false;
|
|
174
|
+
delete memory.rules[ruleId];
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* 1.5+ — record a hotspot run. `topFiles` is the list of paths
|
|
179
|
+
* currently in the top-K of `projscan hotspots` along with their
|
|
180
|
+
* file-level CC and churn counts. We track each file's appearance
|
|
181
|
+
* history and the most-recent CC/churn so `findAcceptedHotspots` can
|
|
182
|
+
* decide whether the file is genuinely stuck or actively improving.
|
|
183
|
+
*
|
|
184
|
+
* Mutates memory in place; caller is responsible for `saveMemory`.
|
|
185
|
+
*/
|
|
186
|
+
export function recordHotspots(memory, topFiles) {
|
|
187
|
+
if (!memory.hotspots)
|
|
188
|
+
memory.hotspots = {};
|
|
189
|
+
const nowIso = new Date().toISOString();
|
|
190
|
+
const seen = new Set();
|
|
191
|
+
for (const entry of topFiles) {
|
|
192
|
+
seen.add(entry.file);
|
|
193
|
+
const existing = memory.hotspots[entry.file];
|
|
194
|
+
if (existing) {
|
|
195
|
+
existing.lastSeenAt = nowIso;
|
|
196
|
+
existing.runCount += 1;
|
|
197
|
+
existing.lastCc = entry.cc;
|
|
198
|
+
existing.lastChurn = entry.churn;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
memory.hotspots[entry.file] = {
|
|
202
|
+
file: entry.file,
|
|
203
|
+
firstSeenAt: nowIso,
|
|
204
|
+
lastSeenAt: nowIso,
|
|
205
|
+
runCount: 1,
|
|
206
|
+
lastCc: entry.cc,
|
|
207
|
+
lastChurn: entry.churn,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
memory.lastUpdatedAt = nowIso;
|
|
212
|
+
// Age out hotspots not seen recently — same window as rules.
|
|
213
|
+
const cutoff = Date.now() - STALE_RULE_DAYS * MS_PER_DAY;
|
|
214
|
+
for (const [file, obs] of Object.entries(memory.hotspots)) {
|
|
215
|
+
if (Date.parse(obs.lastSeenAt) < cutoff)
|
|
216
|
+
delete memory.hotspots[file];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* 1.5+ — files that have ranked in the top-K hotspots for ≥
|
|
221
|
+
* HOT_RUN_COUNT runs over ≥ HOT_DAYS days. The hotspot reporter
|
|
222
|
+
* surfaces these as `[accepted]` so the user isn't repeatedly
|
|
223
|
+
* pestered about the same load-bearing debt.
|
|
224
|
+
*/
|
|
225
|
+
export function findAcceptedHotspots(memory) {
|
|
226
|
+
if (!memory.hotspots)
|
|
227
|
+
return [];
|
|
228
|
+
const now = Date.now();
|
|
229
|
+
const minMs = HOT_DAYS * MS_PER_DAY;
|
|
230
|
+
const out = [];
|
|
231
|
+
for (const obs of Object.values(memory.hotspots)) {
|
|
232
|
+
if (obs.runCount < HOT_RUN_COUNT)
|
|
233
|
+
continue;
|
|
234
|
+
const ageMs = now - Date.parse(obs.firstSeenAt);
|
|
235
|
+
if (Number.isFinite(ageMs) && ageMs >= minMs)
|
|
236
|
+
out.push(obs);
|
|
237
|
+
}
|
|
238
|
+
out.sort((a, b) => b.runCount - a.runCount);
|
|
239
|
+
return out;
|
|
240
|
+
}
|
|
241
|
+
/** 1.5+ — drop a single hotspot's history (analogue of forgetRule). */
|
|
242
|
+
export function forgetHotspot(memory, file) {
|
|
243
|
+
if (!memory.hotspots || !memory.hotspots[file])
|
|
244
|
+
return false;
|
|
245
|
+
delete memory.hotspots[file];
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
function ageOutStaleRules(memory) {
|
|
249
|
+
const cutoff = Date.now() - STALE_RULE_DAYS * MS_PER_DAY;
|
|
250
|
+
for (const [ruleId, obs] of Object.entries(memory.rules)) {
|
|
251
|
+
if (Date.parse(obs.lastSeenAt) < cutoff)
|
|
252
|
+
delete memory.rules[ruleId];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function createFresh() {
|
|
256
|
+
const iso = new Date().toISOString();
|
|
257
|
+
return {
|
|
258
|
+
schemaVersion: MEMORY_SCHEMA_VERSION,
|
|
259
|
+
lastUpdatedAt: iso,
|
|
260
|
+
rules: {},
|
|
261
|
+
hotspots: {},
|
|
262
|
+
totalRuns: 0,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
function memoryFilePath(rootPath) {
|
|
266
|
+
return path.join(rootPath, MEMORY_DIR, MEMORY_FILENAME);
|
|
267
|
+
}
|
|
268
|
+
function isMemoryShape(value) {
|
|
269
|
+
if (!value || typeof value !== 'object')
|
|
270
|
+
return false;
|
|
271
|
+
const v = value;
|
|
272
|
+
return (typeof v.schemaVersion === 'number' &&
|
|
273
|
+
typeof v.lastUpdatedAt === 'string' &&
|
|
274
|
+
typeof v.totalRuns === 'number' &&
|
|
275
|
+
typeof v.rules === 'object');
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/core/memory.ts"],"names":[],"mappings":"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"}
|
package/dist/core/review.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReviewReport } from '../types.js';
|
|
1
|
+
import type { ReviewReport, ReviewTier } from '../types.js';
|
|
2
2
|
export interface ReviewOptions {
|
|
3
3
|
/** Base ref. Default: origin/main → main → origin/master → master → HEAD~1. */
|
|
4
4
|
base?: string;
|
|
@@ -19,3 +19,27 @@ export interface ReviewOptions {
|
|
|
19
19
|
* ok - otherwise
|
|
20
20
|
*/
|
|
21
21
|
export declare function computeReview(rootPath: string, options?: ReviewOptions): Promise<ReviewReport>;
|
|
22
|
+
/**
|
|
23
|
+
* 1.5+ — pick a review tier based on the caller's token budget.
|
|
24
|
+
*
|
|
25
|
+
* <3000 → 'verdict-only' (verdict + summary + totals)
|
|
26
|
+
* <7000 → 'summary' (verdict + summary + top files / top cycles / etc.)
|
|
27
|
+
* else → 'full' (everything)
|
|
28
|
+
*
|
|
29
|
+
* `0`, `undefined`, and any non-positive value all mean "no budget given"
|
|
30
|
+
* — the caller wants the full report. The tier names are stable (clients
|
|
31
|
+
* can read them off the response and key behavior off them).
|
|
32
|
+
*/
|
|
33
|
+
export declare function selectReviewTier(maxCostTokens: number | undefined): ReviewTier;
|
|
34
|
+
/**
|
|
35
|
+
* Reshape a full ReviewReport for the chosen tier. The caller passes a
|
|
36
|
+
* fully-populated report from `computeReview`; we return a plain object
|
|
37
|
+
* sized for the tier. Returning `Record<string, unknown>` (rather than
|
|
38
|
+
* narrowing the ReviewReport type) keeps the type contract simple for
|
|
39
|
+
* the dispatcher and avoids an over-engineered union.
|
|
40
|
+
*
|
|
41
|
+
* `unavailable` reports (no diff, missing base, etc.) pass through as-is
|
|
42
|
+
* — there's nothing to shape; the verdict + reason already convey
|
|
43
|
+
* everything the agent needs.
|
|
44
|
+
*/
|
|
45
|
+
export declare function shapeReviewForTier(report: ReviewReport, tier: ReviewTier): Record<string, unknown>;
|