@optave/codegraph 3.9.1 → 3.9.2

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 (123) hide show
  1. package/README.md +12 -14
  2. package/dist/cli/commands/batch.d.ts.map +1 -1
  3. package/dist/cli/commands/batch.js +5 -17
  4. package/dist/cli/commands/batch.js.map +1 -1
  5. package/dist/cli/commands/structure.d.ts.map +1 -1
  6. package/dist/cli/commands/structure.js +18 -1
  7. package/dist/cli/commands/structure.js.map +1 -1
  8. package/dist/db/connection.d.ts +2 -0
  9. package/dist/db/connection.d.ts.map +1 -1
  10. package/dist/db/connection.js +2 -2
  11. package/dist/db/connection.js.map +1 -1
  12. package/dist/db/index.d.ts +1 -1
  13. package/dist/db/index.d.ts.map +1 -1
  14. package/dist/db/index.js +1 -1
  15. package/dist/db/index.js.map +1 -1
  16. package/dist/domain/analysis/context.d.ts.map +1 -1
  17. package/dist/domain/analysis/context.js +5 -15
  18. package/dist/domain/analysis/context.js.map +1 -1
  19. package/dist/domain/analysis/dependencies.d.ts +5 -5
  20. package/dist/domain/analysis/dependencies.d.ts.map +1 -1
  21. package/dist/domain/analysis/dependencies.js +6 -16
  22. package/dist/domain/analysis/dependencies.js.map +1 -1
  23. package/dist/domain/analysis/fn-impact.js +2 -2
  24. package/dist/domain/analysis/fn-impact.js.map +1 -1
  25. package/dist/domain/analysis/implementations.d.ts.map +1 -1
  26. package/dist/domain/analysis/implementations.js +3 -13
  27. package/dist/domain/analysis/implementations.js.map +1 -1
  28. package/dist/domain/graph/builder/context.d.ts +4 -0
  29. package/dist/domain/graph/builder/context.d.ts.map +1 -1
  30. package/dist/domain/graph/builder/context.js +4 -0
  31. package/dist/domain/graph/builder/context.js.map +1 -1
  32. package/dist/domain/graph/builder/native-db-proxy.d.ts +24 -0
  33. package/dist/domain/graph/builder/native-db-proxy.d.ts.map +1 -0
  34. package/dist/domain/graph/builder/native-db-proxy.js +87 -0
  35. package/dist/domain/graph/builder/native-db-proxy.js.map +1 -0
  36. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  37. package/dist/domain/graph/builder/pipeline.js +133 -69
  38. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  39. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  40. package/dist/domain/graph/builder/stages/build-edges.js +15 -2
  41. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  42. package/dist/domain/graph/builder/stages/build-structure.js +2 -2
  43. package/dist/domain/graph/builder/stages/build-structure.js.map +1 -1
  44. package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
  45. package/dist/domain/graph/builder/stages/detect-changes.js +6 -28
  46. package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
  47. package/dist/domain/graph/builder/stages/finalize.js +1 -1
  48. package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
  49. package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
  50. package/dist/domain/graph/builder/stages/insert-nodes.js +16 -12
  51. package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
  52. package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
  53. package/dist/domain/graph/builder/stages/resolve-imports.js +2 -3
  54. package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
  55. package/dist/domain/parser.d.ts.map +1 -1
  56. package/dist/domain/parser.js +5 -2
  57. package/dist/domain/parser.js.map +1 -1
  58. package/dist/domain/queries.d.ts +1 -1
  59. package/dist/domain/queries.d.ts.map +1 -1
  60. package/dist/domain/queries.js +1 -1
  61. package/dist/domain/queries.js.map +1 -1
  62. package/dist/features/audit.d.ts.map +1 -1
  63. package/dist/features/audit.js +3 -2
  64. package/dist/features/audit.js.map +1 -1
  65. package/dist/features/boundaries.d.ts.map +1 -1
  66. package/dist/features/boundaries.js +3 -5
  67. package/dist/features/boundaries.js.map +1 -1
  68. package/dist/features/branch-compare.d.ts.map +1 -1
  69. package/dist/features/branch-compare.js +2 -1
  70. package/dist/features/branch-compare.js.map +1 -1
  71. package/dist/features/flow.d.ts.map +1 -1
  72. package/dist/features/flow.js +2 -1
  73. package/dist/features/flow.js.map +1 -1
  74. package/dist/features/manifesto.d.ts.map +1 -1
  75. package/dist/features/manifesto.js +15 -1
  76. package/dist/features/manifesto.js.map +1 -1
  77. package/dist/infrastructure/config.d.ts +1 -0
  78. package/dist/infrastructure/config.d.ts.map +1 -1
  79. package/dist/infrastructure/config.js +1 -0
  80. package/dist/infrastructure/config.js.map +1 -1
  81. package/dist/presentation/batch.d.ts.map +1 -1
  82. package/dist/presentation/batch.js +1 -0
  83. package/dist/presentation/batch.js.map +1 -1
  84. package/dist/presentation/structure.d.ts +1 -1
  85. package/dist/presentation/structure.d.ts.map +1 -1
  86. package/dist/presentation/structure.js +1 -1
  87. package/dist/presentation/structure.js.map +1 -1
  88. package/dist/shared/normalize.d.ts +12 -0
  89. package/dist/shared/normalize.d.ts.map +1 -1
  90. package/dist/shared/normalize.js +4 -0
  91. package/dist/shared/normalize.js.map +1 -1
  92. package/dist/types.d.ts +1 -0
  93. package/dist/types.d.ts.map +1 -1
  94. package/package.json +7 -7
  95. package/src/cli/commands/batch.ts +5 -26
  96. package/src/cli/commands/structure.ts +21 -1
  97. package/src/db/connection.ts +2 -2
  98. package/src/db/index.ts +2 -0
  99. package/src/domain/analysis/context.ts +5 -15
  100. package/src/domain/analysis/dependencies.ts +6 -16
  101. package/src/domain/analysis/fn-impact.ts +2 -2
  102. package/src/domain/analysis/implementations.ts +3 -13
  103. package/src/domain/graph/builder/context.ts +4 -0
  104. package/src/domain/graph/builder/native-db-proxy.ts +98 -0
  105. package/src/domain/graph/builder/pipeline.ts +135 -67
  106. package/src/domain/graph/builder/stages/build-edges.ts +15 -2
  107. package/src/domain/graph/builder/stages/build-structure.ts +2 -2
  108. package/src/domain/graph/builder/stages/detect-changes.ts +11 -33
  109. package/src/domain/graph/builder/stages/finalize.ts +1 -1
  110. package/src/domain/graph/builder/stages/insert-nodes.ts +17 -14
  111. package/src/domain/graph/builder/stages/resolve-imports.ts +2 -3
  112. package/src/domain/parser.ts +6 -2
  113. package/src/domain/queries.ts +1 -1
  114. package/src/features/audit.ts +3 -2
  115. package/src/features/boundaries.ts +3 -5
  116. package/src/features/branch-compare.ts +2 -3
  117. package/src/features/flow.ts +2 -1
  118. package/src/features/manifesto.ts +15 -1
  119. package/src/infrastructure/config.ts +1 -0
  120. package/src/presentation/batch.ts +1 -0
  121. package/src/presentation/structure.ts +2 -2
  122. package/src/shared/normalize.ts +10 -0
  123. package/src/types.ts +1 -0
@@ -7,6 +7,7 @@ import { loadConfig } from '../infrastructure/config.js';
7
7
  import { debug } from '../infrastructure/logger.js';
8
8
  import { isTestFile } from '../infrastructure/test-filter.js';
9
9
  import { toErrorMessage } from '../shared/errors.js';
10
+ import { toSymbolRef } from '../shared/normalize.js';
10
11
  import type { BetterSqlite3Database, CodegraphConfig } from '../types.js';
11
12
  import { RULE_DEFS } from './manifesto.js';
12
13
 
@@ -317,7 +318,7 @@ function enrichSymbol(
317
318
  WHERE e.source_id = ? AND e.kind = 'calls'`,
318
319
  )
319
320
  .all(nodeId) as SymbolRef[]
320
- ).map((c) => ({ name: c.name, kind: c.kind, file: c.file, line: c.line }));
321
+ ).map(toSymbolRef);
321
322
 
322
323
  callers = (
323
324
  db
@@ -327,7 +328,7 @@ function enrichSymbol(
327
328
  WHERE e.target_id = ? AND e.kind = 'calls'`,
328
329
  )
329
330
  .all(nodeId) as SymbolRef[]
330
- ).map((c) => ({ name: c.name, kind: c.kind, file: c.file, line: c.line }));
331
+ ).map(toSymbolRef);
331
332
  if (noTests) callers = callers.filter((c) => !isTestFile(c.file));
332
333
 
333
334
  const testCallerRows = db
@@ -1,5 +1,5 @@
1
- import { debug } from '../infrastructure/logger.js';
2
1
  import { isTestFile } from '../infrastructure/test-filter.js';
2
+ import { BoundaryError } from '../shared/errors.js';
3
3
  import type { BetterSqlite3Database } from '../types.js';
4
4
 
5
5
  // ─── Glob-to-Regex ───────────────────────────────────────────────────
@@ -269,8 +269,7 @@ export function evaluateBoundaries(
269
269
 
270
270
  const { valid, errors } = validateBoundaryConfig(boundaryConfig);
271
271
  if (!valid) {
272
- debug(`boundary config validation failed: ${errors.join('; ')}`);
273
- return { violations: [], violationCount: 0 };
272
+ throw new BoundaryError(`Invalid boundary configuration: ${errors.join('; ')}`);
274
273
  }
275
274
 
276
275
  const modules = resolveModules(boundaryConfig);
@@ -297,8 +296,7 @@ export function evaluateBoundaries(
297
296
  )
298
297
  .all() as Array<{ source: string; target: string }>;
299
298
  } catch (err) {
300
- debug(`boundary edge query failed: ${(err as Error).message}`);
301
- return { violations: [], violationCount: 0 };
299
+ throw new BoundaryError('Boundary evaluation failed', { cause: err as Error });
302
300
  }
303
301
 
304
302
  if (opts.noTests) {
@@ -9,6 +9,7 @@ import { debug } from '../infrastructure/logger.js';
9
9
  import { getNative, isNativeAvailable } from '../infrastructure/native.js';
10
10
  import { isTestFile } from '../infrastructure/test-filter.js';
11
11
  import { toErrorMessage } from '../shared/errors.js';
12
+ import { toSymbolRef } from '../shared/normalize.js';
12
13
  import type { EngineMode, NativeDatabase } from '../types.js';
13
14
 
14
15
  // ─── Git Helpers ────────────────────────────────────────────────────────
@@ -255,9 +256,7 @@ function loadCallersFromDb(
255
256
  if (!visited.has(c.id) && (!noTests || !isTestFile(c.file))) {
256
257
  visited.add(c.id);
257
258
  nextFrontier.push(c.id);
258
- allCallers.add(
259
- JSON.stringify({ name: c.name, kind: c.kind, file: c.file, line: c.line }),
260
- );
259
+ allCallers.add(JSON.stringify(toSymbolRef(c)));
261
260
  }
262
261
  }
263
262
  }
@@ -8,6 +8,7 @@
8
8
  import { openReadonlyOrFail } from '../db/index.js';
9
9
  import { CORE_SYMBOL_KINDS, findMatchingNodes } from '../domain/queries.js';
10
10
  import { isTestFile } from '../infrastructure/test-filter.js';
11
+ import { toSymbolRef } from '../shared/normalize.js';
11
12
  import { paginateResult } from '../shared/paginate.js';
12
13
  import { FRAMEWORK_ENTRY_PREFIXES } from './structure.js';
13
14
 
@@ -175,7 +176,7 @@ function bfsCallees(
175
176
 
176
177
  visited.add(c.id);
177
178
  nextFrontier.push(c.id);
178
- const nodeInfo: NodeInfo = { name: c.name, kind: c.kind, file: c.file, line: c.line };
179
+ const nodeInfo: NodeInfo = toSymbolRef(c);
179
180
  levelNodes.push(nodeInfo);
180
181
  nodeDepths.set(c.id, d);
181
182
  idToNode.set(c.id, nodeInfo);
@@ -5,6 +5,7 @@ import { loadConfig } from '../infrastructure/config.js';
5
5
  import { debug } from '../infrastructure/logger.js';
6
6
  import { paginateResult } from '../shared/paginate.js';
7
7
  import type { BetterSqlite3Database, CodegraphConfig, ThresholdRule } from '../types.js';
8
+ import type { BoundaryViolation } from './boundaries.js';
8
9
  import { evaluateBoundaries } from './boundaries.js';
9
10
 
10
11
  // ─── Rule Definitions ─────────────────────────────────────────────────
@@ -416,7 +417,20 @@ function evaluateBoundaryRules(
416
417
  return;
417
418
  }
418
419
 
419
- const result = evaluateBoundaries(db, boundaryConfig, { noTests: opts.noTests || false });
420
+ let result: { violations: BoundaryViolation[]; violationCount: number };
421
+ try {
422
+ result = evaluateBoundaries(db, boundaryConfig, { noTests: opts.noTests || false });
423
+ } catch (e: unknown) {
424
+ debug(`boundary check failed: ${(e as Error).message}`);
425
+ ruleResults.push({
426
+ name: 'boundaries',
427
+ level: 'graph',
428
+ status: 'warn',
429
+ thresholds: effectiveThresholds,
430
+ violationCount: 0,
431
+ });
432
+ return;
433
+ }
420
434
  const hasBoundaryViolations = result.violationCount > 0;
421
435
 
422
436
  if (!hasBoundaryViolations) {
@@ -23,6 +23,7 @@ export const DEFAULTS = {
23
23
  incremental: true,
24
24
  dbPath: '.codegraph/graph.db',
25
25
  driftThreshold: 0.2,
26
+ smallFilesThreshold: 5,
26
27
  },
27
28
  query: {
28
29
  defaultDepth: 3,
@@ -36,6 +36,7 @@ export function batchQuery(
36
36
  const { command: defaultCommand = 'where', ...rest } = opts;
37
37
  const isMulti =
38
38
  targets.length > 0 &&
39
+ targets[0] !== null &&
39
40
  typeof targets[0] === 'object' &&
40
41
  !!(targets[0] as MultiBatchTarget).command;
41
42
 
@@ -75,7 +75,7 @@ export function formatHotspots(data: HotspotsResult): string {
75
75
 
76
76
  interface ModuleBoundaryEntry {
77
77
  directory: string;
78
- cohesion: number;
78
+ cohesion: number | null;
79
79
  fileCount: number;
80
80
  symbolCount: number;
81
81
  fanIn: number;
@@ -95,7 +95,7 @@ export function formatModuleBoundaries(data: ModuleBoundariesResult): string {
95
95
  const lines = [`\nModule boundaries (cohesion >= ${data.threshold}, ${data.count} modules):\n`];
96
96
  for (const m of data.modules) {
97
97
  lines.push(
98
- ` ${m.directory}/ cohesion=${m.cohesion.toFixed(2)} (${m.fileCount} files, ${m.symbolCount} symbols)`,
98
+ ` ${m.directory}/ cohesion=${m.cohesion !== null ? m.cohesion.toFixed(2) : 'n/a'} (${m.fileCount} files, ${m.symbolCount} symbols)`,
99
99
  );
100
100
  lines.push(` Incoming: ${m.fanIn} edges Outgoing: ${m.fanOut} edges`);
101
101
  if (m.files.length > 0) {
@@ -19,6 +19,16 @@ export function getFileHash(db: DbHandle, file: string): string | null {
19
19
  return row ? row.hash : null;
20
20
  }
21
21
 
22
+ /** Pick the 4-field symbol reference from any row that carries at least {name, kind, file, line}. */
23
+ export function toSymbolRef(row: { name: string; kind: string; file: string; line: number }): {
24
+ name: string;
25
+ kind: string;
26
+ file: string;
27
+ line: number;
28
+ } {
29
+ return { name: row.name, kind: row.kind, file: row.file, line: row.line };
30
+ }
31
+
22
32
  export function kindIcon(kind: string): string {
23
33
  switch (kind) {
24
34
  case 'function':
package/src/types.ts CHANGED
@@ -1085,6 +1085,7 @@ export interface CodegraphConfig {
1085
1085
  incremental: boolean;
1086
1086
  dbPath: string;
1087
1087
  driftThreshold: number;
1088
+ smallFilesThreshold: number;
1088
1089
  };
1089
1090
 
1090
1091
  query: {