@kernlang/review 3.2.3 → 3.3.5

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 (92) hide show
  1. package/dist/cache.js +140 -3
  2. package/dist/cache.js.map +1 -1
  3. package/dist/call-graph.d.ts +4 -1
  4. package/dist/call-graph.js +290 -25
  5. package/dist/call-graph.js.map +1 -1
  6. package/dist/concept-rules/contract-drift.d.ts +21 -0
  7. package/dist/concept-rules/contract-drift.js +66 -0
  8. package/dist/concept-rules/contract-drift.js.map +1 -0
  9. package/dist/concept-rules/cross-stack-utils.d.ts +50 -0
  10. package/dist/concept-rules/cross-stack-utils.js +98 -0
  11. package/dist/concept-rules/cross-stack-utils.js.map +1 -0
  12. package/dist/concept-rules/index.js +12 -1
  13. package/dist/concept-rules/index.js.map +1 -1
  14. package/dist/concept-rules/tainted-across-wire.d.ts +33 -0
  15. package/dist/concept-rules/tainted-across-wire.js +98 -0
  16. package/dist/concept-rules/tainted-across-wire.js.map +1 -0
  17. package/dist/concept-rules/untyped-api-response.d.ts +30 -0
  18. package/dist/concept-rules/untyped-api-response.js +71 -0
  19. package/dist/concept-rules/untyped-api-response.js.map +1 -0
  20. package/dist/external-tools.d.ts +36 -4
  21. package/dist/external-tools.js +79 -12
  22. package/dist/external-tools.js.map +1 -1
  23. package/dist/graph.js +149 -39
  24. package/dist/graph.js.map +1 -1
  25. package/dist/index.d.ts +29 -4
  26. package/dist/index.js +329 -47
  27. package/dist/index.js.map +1 -1
  28. package/dist/inferrer.d.ts +5 -0
  29. package/dist/inferrer.js +1 -1
  30. package/dist/inferrer.js.map +1 -1
  31. package/dist/llm-bridge.d.ts +26 -1
  32. package/dist/llm-bridge.js +42 -6
  33. package/dist/llm-bridge.js.map +1 -1
  34. package/dist/llm-review.js +29 -11
  35. package/dist/llm-review.js.map +1 -1
  36. package/dist/mappers/ts-concepts.js +278 -7
  37. package/dist/mappers/ts-concepts.js.map +1 -1
  38. package/dist/public-api.d.ts +73 -0
  39. package/dist/public-api.js +351 -0
  40. package/dist/public-api.js.map +1 -0
  41. package/dist/reporter.d.ts +5 -0
  42. package/dist/reporter.js +119 -84
  43. package/dist/reporter.js.map +1 -1
  44. package/dist/review-health.d.ts +38 -0
  45. package/dist/review-health.js +60 -0
  46. package/dist/review-health.js.map +1 -0
  47. package/dist/rules/async.js +4 -16
  48. package/dist/rules/async.js.map +1 -1
  49. package/dist/rules/base.js +112 -87
  50. package/dist/rules/base.js.map +1 -1
  51. package/dist/rules/confidence.d.ts +2 -2
  52. package/dist/rules/confidence.js +32 -15
  53. package/dist/rules/confidence.js.map +1 -1
  54. package/dist/rules/dead-code.d.ts +2 -1
  55. package/dist/rules/dead-code.js +49 -3
  56. package/dist/rules/dead-code.js.map +1 -1
  57. package/dist/rules/index.js +131 -0
  58. package/dist/rules/index.js.map +1 -1
  59. package/dist/rules/kern-source-cross-file.d.ts +2 -0
  60. package/dist/rules/kern-source-cross-file.js +102 -0
  61. package/dist/rules/kern-source-cross-file.js.map +1 -0
  62. package/dist/rules/kern-source.js +86 -9
  63. package/dist/rules/kern-source.js.map +1 -1
  64. package/dist/rules/nextjs-app-router.js +936 -31
  65. package/dist/rules/nextjs-app-router.js.map +1 -1
  66. package/dist/rules/nextjs.js +193 -10
  67. package/dist/rules/nextjs.js.map +1 -1
  68. package/dist/rules/react-composition.js +442 -61
  69. package/dist/rules/react-composition.js.map +1 -1
  70. package/dist/rules/react-hooks.js +51 -2
  71. package/dist/rules/react-hooks.js.map +1 -1
  72. package/dist/rules/react.js +265 -49
  73. package/dist/rules/react.js.map +1 -1
  74. package/dist/rules/utils.d.ts +37 -2
  75. package/dist/rules/utils.js +113 -0
  76. package/dist/rules/utils.js.map +1 -1
  77. package/dist/semantic-diff.js +1 -1
  78. package/dist/semantic-diff.js.map +1 -1
  79. package/dist/taint-ast.js +228 -4
  80. package/dist/taint-ast.js.map +1 -1
  81. package/dist/taint-crossfile.d.ts +30 -2
  82. package/dist/taint-crossfile.js +280 -59
  83. package/dist/taint-crossfile.js.map +1 -1
  84. package/dist/taint-types.d.ts +2 -1
  85. package/dist/taint-types.js +32 -2
  86. package/dist/taint-types.js.map +1 -1
  87. package/dist/taint.d.ts +1 -1
  88. package/dist/taint.js +1 -1
  89. package/dist/taint.js.map +1 -1
  90. package/dist/types.d.ts +80 -0
  91. package/dist/types.js.map +1 -1
  92. package/package.json +3 -3
@@ -7,24 +7,56 @@
7
7
  * Phase 3 of the review pipeline.
8
8
  */
9
9
  import type { Project } from 'ts-morph';
10
+ import { type ReviewHealthBuilder } from './review-health.js';
10
11
  import type { InferResult, ReviewFinding } from './types.js';
11
12
  /**
12
13
  * Run ESLint on given file paths using the Node API.
13
14
  * Returns normalized ReviewFinding[] with source='eslint'.
14
- * Returns empty array if ESLint is not installed.
15
+ *
16
+ * ESLint is an optional peer dep. If it's not installed, we record a `skipped` health
17
+ * note (no findings). If it IS installed but fails at load or lint time — that's a real
18
+ * infrastructure problem: we record an `error` health note so the caller can surface
19
+ * "ran in degraded mode" rather than silently returning an empty findings array that
20
+ * looks identical to a clean run.
15
21
  */
16
- export declare function runESLint(filePaths: string[], cwd: string): Promise<ReviewFinding[]>;
22
+ export declare function runESLint(filePaths: string[], cwd: string, health?: ReviewHealthBuilder): Promise<ReviewFinding[]>;
23
+ export interface RunTSCDiagnosticsOptions {
24
+ /**
25
+ * When true, suppress TS diagnostics that fire as kern-review infrastructure noise when we inject
26
+ * ad-hoc files into a Project that carries a host tsconfig. Suppressed codes fall into two classes:
27
+ *
28
+ * Project membership (in-memory Project vs host rootDir):
29
+ * - TS6059 — "File is not listed within the file list of project"
30
+ * - TS6307 — "File is not under 'rootDir'"
31
+ *
32
+ * Environmental (in-memory Project doesn't mirror host compilerOptions — moduleResolution, jsx, lib):
33
+ * - TS2792 — "Cannot find module X. Did you mean to set 'moduleResolution' to 'nodenext'?"
34
+ * - TS17004 — "Cannot use JSX unless the '--jsx' flag is provided"
35
+ * - TS2580 / TS2591 — "Cannot find name 'process'/'require'/'module'" (@types/node missing)
36
+ *
37
+ * The dev already sees the environmental class in their IDE / local `tsc --noEmit` when real.
38
+ * Set this only for the standard review path. The --lint path must leave it false so real
39
+ * tsconfig misconfigurations still surface as errors.
40
+ *
41
+ * The name is kept for backward compatibility; scope broadened deliberately.
42
+ */
43
+ downgradeProjectLoadingErrors?: boolean;
44
+ }
17
45
  /**
18
46
  * Run TypeScript compiler diagnostics using ts-morph's existing Project.
19
47
  * Reuses the Project already created by the inferrer — no extra compilation.
20
48
  */
21
- export declare function runTSCDiagnostics(project: Project): ReviewFinding[];
49
+ export declare function runTSCDiagnostics(project: Project, options?: RunTSCDiagnosticsOptions, health?: ReviewHealthBuilder): ReviewFinding[];
22
50
  /**
23
51
  * Run TypeScript compiler diagnostics from file paths (no pre-existing Project).
24
52
  * Creates a real-filesystem Project, adds files, runs diagnostics.
25
53
  * Used by the CLI --lint path where only file paths are available.
54
+ *
55
+ * If the Project fails to construct (missing tsconfig, bad compilerOptions), we record an
56
+ * `error` health note rather than silently returning []. Per-file addSourceFileAtPath
57
+ * failures are normal for unreadable/unparseable files and are intentionally skipped.
26
58
  */
27
- export declare function runTSCDiagnosticsFromPaths(filePaths: string[]): ReviewFinding[];
59
+ export declare function runTSCDiagnosticsFromPaths(filePaths: string[], health?: ReviewHealthBuilder): ReviewFinding[];
28
60
  /**
29
61
  * For each external finding, find the inferred node whose sourceSpan contains it.
30
62
  * Attaches nodeId to the finding for cross-referencing.
@@ -7,21 +7,55 @@
7
7
  * Phase 3 of the review pipeline.
8
8
  */
9
9
  import { createProject } from './inferrer.js';
10
+ import { debugDetail } from './review-health.js';
10
11
  import { createFingerprint } from './types.js';
12
+ /**
13
+ * Node-style error check — used to distinguish "optional peer dep missing" (quietly skip)
14
+ * from "the peer dep is installed but failed to load" (surface as degraded-mode health note).
15
+ * Matches both the standard MODULE_NOT_FOUND on require() and the ERR_MODULE_NOT_FOUND
16
+ * emitted by native ESM dynamic import.
17
+ */
18
+ function isModuleNotFound(err) {
19
+ if (!err || typeof err !== 'object')
20
+ return false;
21
+ const code = err.code;
22
+ return code === 'MODULE_NOT_FOUND' || code === 'ERR_MODULE_NOT_FOUND';
23
+ }
11
24
  // ── ESLint via Node API ──────────────────────────────────────────────────
12
25
  /**
13
26
  * Run ESLint on given file paths using the Node API.
14
27
  * Returns normalized ReviewFinding[] with source='eslint'.
15
- * Returns empty array if ESLint is not installed.
28
+ *
29
+ * ESLint is an optional peer dep. If it's not installed, we record a `skipped` health
30
+ * note (no findings). If it IS installed but fails at load or lint time — that's a real
31
+ * infrastructure problem: we record an `error` health note so the caller can surface
32
+ * "ran in degraded mode" rather than silently returning an empty findings array that
33
+ * looks identical to a clean run.
16
34
  */
17
- export async function runESLint(filePaths, cwd) {
35
+ export async function runESLint(filePaths, cwd, health) {
36
+ // Dynamic import — ESLint is an optional peer dep. MODULE_NOT_FOUND at this step means
37
+ // "not installed" (quiet skip); anything else is a real load failure worth surfacing.
38
+ const eslintModuleName = 'eslint';
39
+ let ESLint;
18
40
  try {
19
- // Dynamic import — ESLint is an optional peer dep
20
- const eslintModuleName = 'eslint';
21
41
  const eslintModule = (await import(eslintModuleName));
22
- const ESLint = eslintModule.ESLint || eslintModule.default?.ESLint;
23
- if (!ESLint)
42
+ ESLint = eslintModule.ESLint || eslintModule.default?.ESLint;
43
+ }
44
+ catch (err) {
45
+ if (isModuleNotFound(err)) {
46
+ health?.noteKind('eslint', 'skipped', 'ESLint not installed — skipped');
24
47
  return [];
48
+ }
49
+ health?.noteKind('eslint', 'error', 'ESLint failed to load', debugDetail(err));
50
+ if (process.env.KERN_DEBUG)
51
+ console.error('ESLint load error:', err.message);
52
+ return [];
53
+ }
54
+ if (!ESLint) {
55
+ health?.noteKind('eslint', 'skipped', 'ESLint package present but missing ESLint export — skipped');
56
+ return [];
57
+ }
58
+ try {
25
59
  const eslint = new ESLint({ cwd });
26
60
  const results = await eslint.lintFiles(filePaths);
27
61
  const findings = [];
@@ -49,8 +83,13 @@ export async function runESLint(filePaths, cwd) {
49
83
  }
50
84
  return findings;
51
85
  }
52
- catch {
53
- // ESLint not installed or failed to load
86
+ catch (err) {
87
+ // ESLint loaded but lintFiles threw typically a malformed eslint.config or unreadable
88
+ // files. This is a real failure: surface it on health rather than letting a silent []
89
+ // look like "ESLint ran and found nothing."
90
+ health?.noteKind('eslint', 'error', 'ESLint failed during lint run', debugDetail(err));
91
+ if (process.env.KERN_DEBUG)
92
+ console.error('ESLint lint error:', err.message);
54
93
  return [];
55
94
  }
56
95
  }
@@ -68,12 +107,11 @@ function categorizeESLintRule(ruleId) {
68
107
  return 'structure';
69
108
  return 'pattern';
70
109
  }
71
- // ── tsc Diagnostics via ts-morph ─────────────────────────────────────────
72
110
  /**
73
111
  * Run TypeScript compiler diagnostics using ts-morph's existing Project.
74
112
  * Reuses the Project already created by the inferrer — no extra compilation.
75
113
  */
76
- export function runTSCDiagnostics(project) {
114
+ export function runTSCDiagnostics(project, options = {}, health) {
77
115
  const findings = [];
78
116
  try {
79
117
  const diagnostics = project.getPreEmitDiagnostics();
@@ -107,6 +145,27 @@ export function runTSCDiagnostics(project) {
107
145
  const code = diag.getCode();
108
146
  const message = diag.getMessageText();
109
147
  const messageStr = typeof message === 'string' ? message : message.getMessageText();
148
+ // ts6059 / ts6307 fire both for real tsconfig misconfigurations and for kern-review's
149
+ // ad-hoc file injection into a host tsconfig (noise). The caller decides which mode we're in
150
+ // via options.downgradeProjectLoadingErrors. In review mode we drop them entirely; surfacing
151
+ // them as info still pollutes every barrel/re-export report in composite monorepos.
152
+ // ts6059 — "File is not listed within the file list of project"
153
+ // ts6307 — "File is not under 'rootDir'"
154
+ // The following codes are environmental: they reflect ts-morph's in-memory Project not
155
+ // perfectly mirroring the host's compilerOptions (moduleResolution, jsx, lib). The dev
156
+ // already sees them in their IDE / local `tsc --noEmit` if real; the review's value-add
157
+ // is KERN-relevant findings, not duplicating compiler output. A sweep of the agon repo
158
+ // (451 files) emitted 1869 of these as errors — pure noise drowning real findings.
159
+ // ts2792 — "Cannot find module X. Did you mean to set 'moduleResolution' to 'nodenext'?"
160
+ // ts17004 — "Cannot use JSX unless the '--jsx' flag is provided"
161
+ // ts2580 / ts2591 — "Cannot find name 'process'/'require'/'module'. Install @types/node?"
162
+ // (TS emits 2580 when the name resolves via global lib shims, 2591 when it doesn't —
163
+ // both point at the same user-side remedy, both are environmental from review's POV.)
164
+ const isLoadingNoise = code === 6059 || code === 6307;
165
+ const isEnvironmentalNoise = code === 2792 || code === 17004 || code === 2580 || code === 2591;
166
+ if ((isLoadingNoise || isEnvironmentalNoise) && options.downgradeProjectLoadingErrors) {
167
+ continue;
168
+ }
110
169
  findings.push({
111
170
  source: 'tsc',
112
171
  ruleId: `ts${code}`,
@@ -126,6 +185,7 @@ export function runTSCDiagnostics(project) {
126
185
  }
127
186
  catch (err) {
128
187
  // ts-morph diagnostics can fail on malformed source — return what we have
188
+ health?.noteKind('tsc', 'error', 'tsc diagnostics failed mid-run', debugDetail(err));
129
189
  if (process.env.KERN_DEBUG)
130
190
  console.error('tsc diagnostics error:', err.message);
131
191
  }
@@ -136,8 +196,12 @@ export function runTSCDiagnostics(project) {
136
196
  * Run TypeScript compiler diagnostics from file paths (no pre-existing Project).
137
197
  * Creates a real-filesystem Project, adds files, runs diagnostics.
138
198
  * Used by the CLI --lint path where only file paths are available.
199
+ *
200
+ * If the Project fails to construct (missing tsconfig, bad compilerOptions), we record an
201
+ * `error` health note rather than silently returning []. Per-file addSourceFileAtPath
202
+ * failures are normal for unreadable/unparseable files and are intentionally skipped.
139
203
  */
140
- export function runTSCDiagnosticsFromPaths(filePaths) {
204
+ export function runTSCDiagnosticsFromPaths(filePaths, health) {
141
205
  if (filePaths.length === 0)
142
206
  return [];
143
207
  try {
@@ -152,7 +216,10 @@ export function runTSCDiagnosticsFromPaths(filePaths) {
152
216
  }
153
217
  return runTSCDiagnostics(project);
154
218
  }
155
- catch {
219
+ catch (err) {
220
+ health?.noteKind('tsc', 'error', 'tsc diagnostics could not build a ts-morph Project', debugDetail(err));
221
+ if (process.env.KERN_DEBUG)
222
+ console.error('tsc project build error:', err.message);
156
223
  return [];
157
224
  }
158
225
  }
@@ -1 +1 @@
1
- {"version":3,"file":"external-tools.js","sourceRoot":"","sources":["../src/external-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"external-tools.js","sourceRoot":"","sources":["../src/external-tools.ts"],"names":[],"mappings":"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"}
package/dist/graph.js CHANGED
@@ -7,6 +7,8 @@
7
7
  *
8
8
  * Codex contributions: extension fallback, shortest-distance tracking, skip counters.
9
9
  */
10
+ import { existsSync } from 'fs';
11
+ import { resolve } from 'path';
10
12
  import { Project } from 'ts-morph';
11
13
  /** Extension fallback map: .js→.ts, .jsx→.tsx (Codex idea) */
12
14
  const EXT_FALLBACK = {
@@ -42,13 +44,20 @@ export function resolveImportGraph(entryFiles, options = {}) {
42
44
  sf = project.addSourceFileAtPath(entry);
43
45
  }
44
46
  catch {
45
- skipped++;
47
+ const entryPath = resolve(entry);
48
+ if (!existsSync(entryPath)) {
49
+ skipped++;
50
+ continue;
51
+ }
52
+ if (!fileMap.has(entryPath)) {
53
+ fileMap.set(entryPath, makeGraphFile(entryPath, 0));
54
+ }
46
55
  continue;
47
56
  }
48
57
  }
49
58
  const p = sf.getFilePath();
50
59
  if (!fileMap.has(p)) {
51
- fileMap.set(p, { path: p, distance: 0, imports: [], importedBy: [] });
60
+ fileMap.set(p, makeGraphFile(p, 0));
52
61
  queue.push({ path: p, distance: 0 });
53
62
  }
54
63
  }
@@ -65,31 +74,9 @@ export function resolveImportGraph(entryFiles, options = {}) {
65
74
  continue;
66
75
  const current = fileMap.get(filePath);
67
76
  // Collect module references from imports and re-exports (barrel file support)
68
- const refs = [];
69
- for (const decl of sf.getImportDeclarations()) {
70
- try {
71
- refs.push({
72
- specifier: decl.getModuleSpecifierValue(),
73
- resolved: decl.getModuleSpecifierSourceFile(),
74
- });
75
- }
76
- catch {
77
- /* skip dynamic imports with non-literal specifiers */
78
- }
79
- }
80
- for (const decl of sf.getExportDeclarations()) {
81
- const spec = decl.getModuleSpecifierValue();
82
- if (spec) {
83
- refs.push({ specifier: spec, resolved: decl.getModuleSpecifierSourceFile() });
84
- }
85
- }
86
- for (const { specifier, resolved } of refs) {
87
- // Try ts-morph resolution first (handles path aliases via tsconfig)
88
- let resolvedFile = resolved;
89
- // For relative imports that weren't resolved, try extension fallback
90
- if (!resolvedFile && (specifier.startsWith('.') || specifier.startsWith('/'))) {
91
- resolvedFile = tryExtensionFallback(project, sf, specifier);
92
- }
77
+ const refs = collectModuleEdgeRefs(sf);
78
+ for (const ref of refs) {
79
+ const { sourceFile: resolvedFile, via } = resolveModuleReference(project, sf, ref.specifier, ref.resolved);
93
80
  if (!resolvedFile) {
94
81
  skipped++;
95
82
  continue;
@@ -104,16 +91,24 @@ export function resolveImportGraph(entryFiles, options = {}) {
104
91
  skipped++;
105
92
  continue;
106
93
  }
94
+ const edge = {
95
+ from: filePath,
96
+ to: resolvedPath,
97
+ specifier: ref.specifier,
98
+ kind: ref.kind,
99
+ importedName: ref.importedName,
100
+ localName: ref.localName,
101
+ via,
102
+ };
103
+ pushUniqueEdge(current.importEdges, edge);
107
104
  if (!current.imports.includes(resolvedPath)) {
108
105
  current.imports.push(resolvedPath);
109
106
  }
110
107
  if (!fileMap.has(resolvedPath)) {
111
- fileMap.set(resolvedPath, {
112
- path: resolvedPath,
113
- distance: distance + 1,
114
- imports: [],
115
- importedBy: [filePath],
116
- });
108
+ const nextFile = makeGraphFile(resolvedPath, distance + 1);
109
+ nextFile.importedBy.push(filePath);
110
+ nextFile.incomingEdges.push(edge);
111
+ fileMap.set(resolvedPath, nextFile);
117
112
  queue.push({ path: resolvedPath, distance: distance + 1 });
118
113
  }
119
114
  else {
@@ -125,6 +120,7 @@ export function resolveImportGraph(entryFiles, options = {}) {
125
120
  if (!existing.importedBy.includes(filePath)) {
126
121
  existing.importedBy.push(filePath);
127
122
  }
123
+ pushUniqueEdge(existing.incomingEdges, edge);
128
124
  }
129
125
  }
130
126
  }
@@ -134,6 +130,7 @@ export function resolveImportGraph(entryFiles, options = {}) {
134
130
  entryFiles: files.filter((f) => f.distance === 0).map((f) => f.path),
135
131
  totalFiles: files.length,
136
132
  skipped,
133
+ project,
137
134
  };
138
135
  }
139
136
  /**
@@ -147,14 +144,127 @@ function tryExtensionFallback(project, fromFile, specifier) {
147
144
  const base = specifier.slice(0, -jsExt.length);
148
145
  for (const tsExt of tsExts) {
149
146
  const candidate = base + tsExt;
150
- // Try resolving relative to the importing file's directory
151
- const fromDir = fromFile.getDirectoryPath();
152
- const fullPath = `${fromDir}/${candidate.replace(/^\.\//, '')}`;
153
- const sf = project.getSourceFile(fullPath);
154
- if (sf)
155
- return sf;
147
+ const fullPath = resolve(fromFile.getDirectoryPath(), candidate);
148
+ const existing = project.getSourceFile(fullPath);
149
+ if (existing)
150
+ return existing;
151
+ if (!existsSync(fullPath))
152
+ continue;
153
+ try {
154
+ return project.addSourceFileAtPath(fullPath);
155
+ }
156
+ catch {
157
+ /* ignore unreadable candidates */
158
+ }
156
159
  }
157
160
  }
158
161
  return undefined;
159
162
  }
163
+ function makeGraphFile(path, distance) {
164
+ return {
165
+ path,
166
+ distance,
167
+ imports: [],
168
+ importedBy: [],
169
+ importEdges: [],
170
+ incomingEdges: [],
171
+ };
172
+ }
173
+ function resolveModuleReference(project, fromFile, specifier, resolved) {
174
+ if (resolved)
175
+ return { sourceFile: resolved, via: 'ts-morph' };
176
+ if (specifier.startsWith('.') || specifier.startsWith('/')) {
177
+ const fallback = tryExtensionFallback(project, fromFile, specifier);
178
+ if (fallback)
179
+ return { sourceFile: fallback, via: 'extension-fallback' };
180
+ }
181
+ return { sourceFile: undefined, via: 'ts-morph' };
182
+ }
183
+ function collectModuleEdgeRefs(sourceFile) {
184
+ const refs = [];
185
+ for (const decl of sourceFile.getImportDeclarations()) {
186
+ try {
187
+ const specifier = decl.getModuleSpecifierValue();
188
+ const resolved = decl.getModuleSpecifierSourceFile();
189
+ let recorded = false;
190
+ const defaultImport = decl.getDefaultImport();
191
+ if (defaultImport) {
192
+ refs.push({
193
+ specifier,
194
+ resolved,
195
+ kind: 'default-import',
196
+ importedName: 'default',
197
+ localName: defaultImport.getText(),
198
+ });
199
+ recorded = true;
200
+ }
201
+ for (const named of decl.getNamedImports()) {
202
+ refs.push({
203
+ specifier,
204
+ resolved,
205
+ kind: 'named-import',
206
+ importedName: named.getName(),
207
+ localName: named.getAliasNode()?.getText() ?? named.getName(),
208
+ });
209
+ recorded = true;
210
+ }
211
+ const namespaceImport = decl.getNamespaceImport();
212
+ if (namespaceImport) {
213
+ refs.push({
214
+ specifier,
215
+ resolved,
216
+ kind: 'namespace-import',
217
+ importedName: '*',
218
+ localName: namespaceImport.getText(),
219
+ });
220
+ recorded = true;
221
+ }
222
+ if (!recorded) {
223
+ refs.push({ specifier, resolved, kind: 'side-effect-import' });
224
+ }
225
+ }
226
+ catch {
227
+ /* skip dynamic imports with non-literal specifiers */
228
+ }
229
+ }
230
+ for (const decl of sourceFile.getExportDeclarations()) {
231
+ let specifier;
232
+ let resolved;
233
+ try {
234
+ specifier = decl.getModuleSpecifierValue();
235
+ if (!specifier)
236
+ continue;
237
+ resolved = decl.getModuleSpecifierSourceFile() ?? undefined;
238
+ }
239
+ catch {
240
+ continue;
241
+ }
242
+ const namedExports = decl.getNamedExports();
243
+ if (namedExports.length === 0) {
244
+ refs.push({ specifier, resolved, kind: 'export-all' });
245
+ continue;
246
+ }
247
+ for (const named of namedExports) {
248
+ refs.push({
249
+ specifier,
250
+ resolved,
251
+ kind: 'named-reexport',
252
+ importedName: named.getName(),
253
+ localName: named.getAliasNode()?.getText() ?? named.getName(),
254
+ });
255
+ }
256
+ }
257
+ return refs;
258
+ }
259
+ function pushUniqueEdge(edges, edge) {
260
+ const exists = edges.some((existing) => existing.from === edge.from &&
261
+ existing.to === edge.to &&
262
+ existing.specifier === edge.specifier &&
263
+ existing.kind === edge.kind &&
264
+ existing.importedName === edge.importedName &&
265
+ existing.localName === edge.localName &&
266
+ existing.via === edge.via);
267
+ if (!exists)
268
+ edges.push(edge);
269
+ }
160
270
  //# sourceMappingURL=graph.js.map
package/dist/graph.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -21,10 +21,10 @@ export { linkToNodes, runESLint, runTSCDiagnostics, runTSCDiagnosticsFromPaths }
21
21
  export { buildFileContextMap, clearFileContextCache } from './file-context.js';
22
22
  export { classifyFileRole } from './file-role.js';
23
23
  export { resolveImportGraph } from './graph.js';
24
- export { inferFromFile, inferFromSource } from './inferrer.js';
24
+ export { findTsConfig, inferFromFile, inferFromSource } from './inferrer.js';
25
25
  export type { KernLintRule } from './kern-lint.js';
26
26
  export { flattenIR, lintKernIR } from './kern-lint.js';
27
- export type { LLMBridgeConfig, LLMReviewInput, ReviewInstructionOptions } from './llm-bridge.js';
27
+ export type { LLMBridgeConfig, LLMCallResult, LLMReviewInput, LLMReviewResult, LLMUsage, ReviewInstructionOptions, } from './llm-bridge.js';
28
28
  export { buildReviewInstructions, isLLMAvailable, runLLMReview } from './llm-bridge.js';
29
29
  export type { LLMGraphContext } from './llm-review.js';
30
30
  export { buildLLMPrompt, exportKernIR, parseLLMResponse } from './llm-review.js';
@@ -33,8 +33,11 @@ export type { NormViolation } from './norm-miner.js';
33
33
  export { mineNorms } from './norm-miner.js';
34
34
  export type { ObligationType, ProofObligation } from './obligations.js';
35
35
  export { obligationsFromNorms, obligationsFromStructure, synthesizeObligations } from './obligations.js';
36
+ export type { PublicApiMap, PublicApiOverrides } from './public-api.js';
37
+ export { buildPublicApiMap, EMPTY_PUBLIC_API, expandPublicApiThroughReExports, isPublicApi, resolvePackageEntryFiles, resolveSpecifierToSrc, } from './public-api.js';
36
38
  export { runQualityRules } from './quality-rules.js';
37
- export { assignDefaultConfidence, calculateStats, checkEnforcement, dedup, formatEnforcement, formatReport, formatReportJSON, formatSARIF, formatSARIFWithSuppressions, formatSummary, sortAndDedup, sortFindings, } from './reporter.js';
39
+ export { assignDefaultConfidence, calculateStats, checkEnforcement, dedup, formatEnforcement, formatReport, formatReportJSON, formatSARIF, formatSARIFWithMetadata, formatSARIFWithSuppressions, formatSummary, sortAndDedup, sortFindings, } from './reporter.js';
40
+ export { debugDetail, ReviewHealthBuilder } from './review-health.js';
38
41
  export { CONFIDENCE_RULES, lintConfidenceGraph, lintMultiFileConfidenceGraph } from './rules/confidence.js';
39
42
  export { actionMissingIdempotent, assumeLowTrust, branchNonExhaustive, collectUnbounded, expectRangeInverted, GROUND_LAYER_RULES, guardWithoutElse, reasonWithoutBasis, } from './rules/ground-layer.js';
40
43
  export type { RuleInfo } from './rules/index.js';
@@ -49,7 +52,7 @@ export { applySuppression, configDirectives, isConceptRule, parseDirectives } fr
49
52
  export type { CrossFileTaintResult, ExportedFunction, TaintPath, TaintResult, TaintSink, TaintSource, } from './taint.js';
50
53
  export { analyzeTaint, analyzeTaintCrossFile, buildExportMap, buildImportMap, crossFileTaintToFindings, isSanitizerSufficient, taintToFindings, } from './taint.js';
51
54
  export { detectTemplates } from './template-detector.js';
52
- export type { AnalysisContext, Confidence, EnforceResult, FileContext, FileRole, GraphFile, GraphOptions, GraphResult, InferResult, ReviewConfig, ReviewFinding, ReviewReport, ReviewRule, ReviewStats, RuleContext, RuntimeBoundary, SourceSpan, TemplateMatch, } from './types.js';
55
+ export type { AnalysisContext, Confidence, EnforceResult, FileContext, FileRole, GraphEdge, GraphEdgeKind, GraphFile, GraphOptions, GraphResult, InferResult, ReviewConfig, ReviewFinding, ReviewHealth, ReviewHealthEntry, ReviewHealthKind, ReviewHealthSubsystem, ReviewReport, ReviewRule, ReviewStats, RuleContext, RuntimeBoundary, SourceSpan, TemplateMatch, } from './types.js';
53
56
  export { createFingerprint } from './types.js';
54
57
  import { clearReviewCache } from './cache.js';
55
58
  export type { ImplRoute, SpecCheckResult, SpecContract, SpecViolation, ViolationKind } from './spec-checker.js';
@@ -57,6 +60,28 @@ export { checkSpec, checkSpecFiles, extractImplRoutes, extractSpecContracts, mat
57
60
  export { clearReviewCache };
58
61
  /** Reset the shared project (for tests / watch mode) */
59
62
  export declare function resetFsProject(): void;
63
+ /**
64
+ * Refresh stale source files in the shared fs Project from disk.
65
+ *
66
+ * The singleton caches every source file it has ever loaded — including transitive imports
67
+ * followed by cross-file taint and call-graph analysis. In a long-running process (watch mode,
68
+ * IDE extension, repeated CLI invocations) those cached ASTs go stale whenever the underlying
69
+ * file changes on disk outside our own `replaceWithText` path. Cross-file findings would then
70
+ * reflect the OLD imported source, not the current one.
71
+ *
72
+ * This helper is the lightweight counterpart to resetFsProject(): instead of throwing the
73
+ * whole Project away, it stat-checks each loaded source file and calls ts-morph's
74
+ * refreshFromFileSystemSync only on the ones whose mtime moved. Use it between reviews in
75
+ * watch-mode callers. One-shot CLI runs don't need it — the process exits before stale
76
+ * reads matter.
77
+ *
78
+ * Returns the number of source files actually refreshed, so callers can log "reloaded N
79
+ * files" or decide not to re-review when the count is zero.
80
+ */
81
+ export declare function refreshFsProjectFromDisk(): number;
82
+ /** True when the file is codegen output — detected via common path patterns or a @generated header. */
83
+ export declare function isGeneratedFile(filePath: string, source?: string): boolean;
84
+ export declare function isReviewableFile(filePath: string): boolean;
60
85
  /**
61
86
  * Review a single file. Auto-detects language from extension.
62
87
  * Uses a filesystem-backed ts-morph Project for type-aware analysis.