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.
Files changed (112) hide show
  1. package/README.md +24 -7
  2. package/dist/cli/commands/applyFix.d.ts +7 -0
  3. package/dist/cli/commands/applyFix.js +113 -0
  4. package/dist/cli/commands/applyFix.js.map +1 -0
  5. package/dist/cli/commands/coverage.js +13 -0
  6. package/dist/cli/commands/coverage.js.map +1 -1
  7. package/dist/cli/commands/doctor.js +18 -2
  8. package/dist/cli/commands/doctor.js.map +1 -1
  9. package/dist/cli/commands/explain.js +1 -0
  10. package/dist/cli/commands/explain.js.map +1 -1
  11. package/dist/cli/commands/impact.js +25 -1
  12. package/dist/cli/commands/impact.js.map +1 -1
  13. package/dist/cli/commands/init.d.ts +6 -0
  14. package/dist/cli/commands/init.js +70 -0
  15. package/dist/cli/commands/init.js.map +1 -0
  16. package/dist/cli/commands/installHook.d.ts +9 -0
  17. package/dist/cli/commands/installHook.js +90 -0
  18. package/dist/cli/commands/installHook.js.map +1 -0
  19. package/dist/cli/commands/memory.d.ts +11 -0
  20. package/dist/cli/commands/memory.js +175 -0
  21. package/dist/cli/commands/memory.js.map +1 -0
  22. package/dist/cli/commands/taint.d.ts +6 -0
  23. package/dist/cli/commands/taint.js +74 -0
  24. package/dist/cli/commands/taint.js.map +1 -0
  25. package/dist/cli/commands/workspace.d.ts +11 -0
  26. package/dist/cli/commands/workspace.js +115 -0
  27. package/dist/cli/commands/workspace.js.map +1 -0
  28. package/dist/cli/index.js +12 -0
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/core/applyFix.d.ts +52 -0
  31. package/dist/core/applyFix.js +220 -0
  32. package/dist/core/applyFix.js.map +1 -0
  33. package/dist/core/ast.d.ts +9 -0
  34. package/dist/core/ast.js +35 -4
  35. package/dist/core/ast.js.map +1 -1
  36. package/dist/core/codeGraph.js +190 -241
  37. package/dist/core/codeGraph.js.map +1 -1
  38. package/dist/core/fileInspector.js +40 -44
  39. package/dist/core/fileInspector.js.map +1 -1
  40. package/dist/core/fixSuggest.d.ts +6 -0
  41. package/dist/core/fixSuggest.js +195 -0
  42. package/dist/core/fixSuggest.js.map +1 -1
  43. package/dist/core/hotspotAnalyzer.js +65 -19
  44. package/dist/core/hotspotAnalyzer.js.map +1 -1
  45. package/dist/core/impact.d.ts +8 -0
  46. package/dist/core/impact.js +41 -3
  47. package/dist/core/impact.js.map +1 -1
  48. package/dist/core/indexCache.js +4 -1
  49. package/dist/core/indexCache.js.map +1 -1
  50. package/dist/core/issueEngine.js +24 -0
  51. package/dist/core/issueEngine.js.map +1 -1
  52. package/dist/core/languages/csharpImports.js +6 -4
  53. package/dist/core/languages/csharpImports.js.map +1 -1
  54. package/dist/core/memory.d.ts +154 -0
  55. package/dist/core/memory.js +277 -0
  56. package/dist/core/memory.js.map +1 -0
  57. package/dist/core/review.d.ts +25 -1
  58. package/dist/core/review.js +133 -2
  59. package/dist/core/review.js.map +1 -1
  60. package/dist/core/taint.d.ts +91 -0
  61. package/dist/core/taint.js +185 -0
  62. package/dist/core/taint.js.map +1 -0
  63. package/dist/core/workspace.d.ts +62 -0
  64. package/dist/core/workspace.js +127 -0
  65. package/dist/core/workspace.js.map +1 -0
  66. package/dist/mcp/prompts.js +274 -0
  67. package/dist/mcp/prompts.js.map +1 -1
  68. package/dist/mcp/server.js +162 -146
  69. package/dist/mcp/server.js.map +1 -1
  70. package/dist/mcp/tokenBudget.d.ts +22 -0
  71. package/dist/mcp/tokenBudget.js +26 -0
  72. package/dist/mcp/tokenBudget.js.map +1 -1
  73. package/dist/mcp/tools/applyFix.d.ts +16 -0
  74. package/dist/mcp/tools/applyFix.js +91 -0
  75. package/dist/mcp/tools/applyFix.js.map +1 -0
  76. package/dist/mcp/tools/doctor.js +65 -2
  77. package/dist/mcp/tools/doctor.js.map +1 -1
  78. package/dist/mcp/tools/explain.js +4 -3
  79. package/dist/mcp/tools/explain.js.map +1 -1
  80. package/dist/mcp/tools/explainIssue.js +3 -2
  81. package/dist/mcp/tools/explainIssue.js.map +1 -1
  82. package/dist/mcp/tools/file.js +3 -2
  83. package/dist/mcp/tools/file.js.map +1 -1
  84. package/dist/mcp/tools/graph.js +16 -11
  85. package/dist/mcp/tools/graph.js.map +1 -1
  86. package/dist/mcp/tools/impact.js +36 -3
  87. package/dist/mcp/tools/impact.js.map +1 -1
  88. package/dist/mcp/tools/memory.d.ts +19 -0
  89. package/dist/mcp/tools/memory.js +134 -0
  90. package/dist/mcp/tools/memory.js.map +1 -0
  91. package/dist/mcp/tools/review.js +25 -4
  92. package/dist/mcp/tools/review.js.map +1 -1
  93. package/dist/mcp/tools/taint.d.ts +15 -0
  94. package/dist/mcp/tools/taint.js +67 -0
  95. package/dist/mcp/tools/taint.js.map +1 -0
  96. package/dist/mcp/tools/upgrade.js +3 -2
  97. package/dist/mcp/tools/upgrade.js.map +1 -1
  98. package/dist/mcp/tools/workspaceGraph.d.ts +18 -0
  99. package/dist/mcp/tools/workspaceGraph.js +188 -0
  100. package/dist/mcp/tools/workspaceGraph.js.map +1 -0
  101. package/dist/mcp/tools.js +8 -0
  102. package/dist/mcp/tools.js.map +1 -1
  103. package/dist/reporters/consoleReporter.d.ts +12 -1
  104. package/dist/reporters/consoleReporter.js +289 -179
  105. package/dist/reporters/consoleReporter.js.map +1 -1
  106. package/dist/reporters/markdownReporter.js +185 -128
  107. package/dist/reporters/markdownReporter.js.map +1 -1
  108. package/dist/tool-manifest.json +129 -6
  109. package/dist/types.d.ts +67 -0
  110. package/dist/utils/config.js +93 -53
  111. package/dist/utils/config.js.map +1 -1
  112. package/package.json +9 -2
@@ -1 +1 @@
1
- {"version":3,"file":"impact.js","sourceRoot":"","sources":["../../src/core/impact.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"impact.js","sourceRoot":"","sources":["../../src/core/impact.ts"],"names":[],"mappings":"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"}
@@ -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
- const CACHE_VERSION = 4;
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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"}
@@ -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;AAInG,MAAM,QAAQ,GAAc;IAC1B,WAAW;IACX,aAAa;IACb,SAAS;IACT,iBAAiB;IACjB,mBAAmB;IACnB,aAAa;IACb,qBAAqB;IACrB,aAAa;IACb,uEAAuE;IACvE,0EAA0E;IAC1E,UAAU;IACV,wEAAwE;IACxE,qEAAqE;IACrE,uBAAuB;IACvB,uEAAuE;IACvE,uBAAuB;IACvB,eAAe;IACf,iBAAiB;IACjB,yBAAyB;IACzB,2BAA2B;CAC5B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,KAAkB;IACtE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAE9B,2CAA2C;IAC3C,MAAM,aAAa,GAA2B,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAChF,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE3F,qEAAqE;IACrE,sEAAsE;IACtE,qEAAqE;IACrE,oEAAoE;IACpE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;QACjD,IAAI,OAAO;YAAE,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC;IAC/C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,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 = null;
43
- if (named.length >= 2 && named[0].type === 'identifier' && (named[1].type === 'qualified_name' || named[1].type === 'identifier' || named[1].type === 'generic_name')) {
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":"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"}
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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"}
@@ -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>;