openlore 2.0.6 → 2.0.8

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 (97) hide show
  1. package/README.md +140 -23
  2. package/dist/cli/commands/decisions.d.ts.map +1 -1
  3. package/dist/cli/commands/decisions.js +187 -174
  4. package/dist/cli/commands/decisions.js.map +1 -1
  5. package/dist/cli/commands/mcp.d.ts +694 -0
  6. package/dist/cli/commands/mcp.d.ts.map +1 -1
  7. package/dist/cli/commands/mcp.js +417 -203
  8. package/dist/cli/commands/mcp.js.map +1 -1
  9. package/dist/constants.d.ts +6 -0
  10. package/dist/constants.d.ts.map +1 -1
  11. package/dist/constants.js +14 -0
  12. package/dist/constants.js.map +1 -1
  13. package/dist/core/analyzer/artifact-generator.d.ts.map +1 -1
  14. package/dist/core/analyzer/artifact-generator.js +59 -4
  15. package/dist/core/analyzer/artifact-generator.js.map +1 -1
  16. package/dist/core/analyzer/call-graph.d.ts +19 -1
  17. package/dist/core/analyzer/call-graph.d.ts.map +1 -1
  18. package/dist/core/analyzer/call-graph.js +128 -28
  19. package/dist/core/analyzer/call-graph.js.map +1 -1
  20. package/dist/core/architecture/check.d.ts +63 -0
  21. package/dist/core/architecture/check.d.ts.map +1 -0
  22. package/dist/core/architecture/check.js +192 -0
  23. package/dist/core/architecture/check.js.map +1 -0
  24. package/dist/core/architecture/rules.d.ts +73 -0
  25. package/dist/core/architecture/rules.d.ts.map +1 -0
  26. package/dist/core/architecture/rules.js +201 -0
  27. package/dist/core/architecture/rules.js.map +1 -0
  28. package/dist/core/decisions/lock.d.ts +10 -0
  29. package/dist/core/decisions/lock.d.ts.map +1 -0
  30. package/dist/core/decisions/lock.js +77 -0
  31. package/dist/core/decisions/lock.js.map +1 -0
  32. package/dist/core/decisions/project.d.ts +59 -0
  33. package/dist/core/decisions/project.d.ts.map +1 -0
  34. package/dist/core/decisions/project.js +68 -0
  35. package/dist/core/decisions/project.js.map +1 -0
  36. package/dist/core/decisions/verifier.d.ts +10 -0
  37. package/dist/core/decisions/verifier.d.ts.map +1 -1
  38. package/dist/core/decisions/verifier.js +48 -5
  39. package/dist/core/decisions/verifier.js.map +1 -1
  40. package/dist/core/provenance/change-coupling.d.ts +68 -0
  41. package/dist/core/provenance/change-coupling.d.ts.map +1 -0
  42. package/dist/core/provenance/change-coupling.js +134 -0
  43. package/dist/core/provenance/change-coupling.js.map +1 -0
  44. package/dist/core/provenance/git-provenance.d.ts +67 -0
  45. package/dist/core/provenance/git-provenance.d.ts.map +1 -0
  46. package/dist/core/provenance/git-provenance.js +177 -0
  47. package/dist/core/provenance/git-provenance.js.map +1 -0
  48. package/dist/core/provenance/project.d.ts +37 -0
  49. package/dist/core/provenance/project.d.ts.map +1 -0
  50. package/dist/core/provenance/project.js +46 -0
  51. package/dist/core/provenance/project.js.map +1 -0
  52. package/dist/core/services/edge-store.d.ts +41 -0
  53. package/dist/core/services/edge-store.d.ts.map +1 -1
  54. package/dist/core/services/edge-store.js +251 -3
  55. package/dist/core/services/edge-store.js.map +1 -1
  56. package/dist/core/services/llm-service.d.ts +9 -0
  57. package/dist/core/services/llm-service.d.ts.map +1 -1
  58. package/dist/core/services/llm-service.js +15 -4
  59. package/dist/core/services/llm-service.js.map +1 -1
  60. package/dist/core/services/mcp-handlers/architecture.d.ts +19 -0
  61. package/dist/core/services/mcp-handlers/architecture.d.ts.map +1 -0
  62. package/dist/core/services/mcp-handlers/architecture.js +104 -0
  63. package/dist/core/services/mcp-handlers/architecture.js.map +1 -0
  64. package/dist/core/services/mcp-handlers/change-coupling.d.ts +16 -0
  65. package/dist/core/services/mcp-handlers/change-coupling.d.ts.map +1 -0
  66. package/dist/core/services/mcp-handlers/change-coupling.js +57 -0
  67. package/dist/core/services/mcp-handlers/change-coupling.js.map +1 -0
  68. package/dist/core/services/mcp-handlers/graph.d.ts +27 -0
  69. package/dist/core/services/mcp-handlers/graph.d.ts.map +1 -1
  70. package/dist/core/services/mcp-handlers/graph.js +98 -16
  71. package/dist/core/services/mcp-handlers/graph.js.map +1 -1
  72. package/dist/core/services/mcp-handlers/orient.d.ts.map +1 -1
  73. package/dist/core/services/mcp-handlers/orient.js +122 -2
  74. package/dist/core/services/mcp-handlers/orient.js.map +1 -1
  75. package/dist/core/services/mcp-handlers/reachability.d.ts +30 -0
  76. package/dist/core/services/mcp-handlers/reachability.d.ts.map +1 -0
  77. package/dist/core/services/mcp-handlers/reachability.js +222 -0
  78. package/dist/core/services/mcp-handlers/reachability.js.map +1 -0
  79. package/dist/core/services/mcp-handlers/structural-diff.d.ts +31 -0
  80. package/dist/core/services/mcp-handlers/structural-diff.d.ts.map +1 -0
  81. package/dist/core/services/mcp-handlers/structural-diff.js +268 -0
  82. package/dist/core/services/mcp-handlers/structural-diff.js.map +1 -0
  83. package/dist/core/services/mcp-handlers/test-impact.d.ts +34 -0
  84. package/dist/core/services/mcp-handlers/test-impact.d.ts.map +1 -0
  85. package/dist/core/services/mcp-handlers/test-impact.js +221 -0
  86. package/dist/core/services/mcp-handlers/test-impact.js.map +1 -0
  87. package/dist/core/services/mcp-handlers/tool-guard.d.ts +45 -0
  88. package/dist/core/services/mcp-handlers/tool-guard.d.ts.map +1 -0
  89. package/dist/core/services/mcp-handlers/tool-guard.js +81 -0
  90. package/dist/core/services/mcp-handlers/tool-guard.js.map +1 -0
  91. package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -1
  92. package/dist/core/services/mcp-handlers/utils.js +15 -1
  93. package/dist/core/services/mcp-handlers/utils.js.map +1 -1
  94. package/dist/core/services/mcp-watcher.d.ts.map +1 -1
  95. package/dist/core/services/mcp-watcher.js +9 -0
  96. package/dist/core/services/mcp-watcher.js.map +1 -1
  97. package/package.json +9 -8
@@ -14,7 +14,7 @@
14
14
  import type { ImportMap } from './import-resolver-bridge.js';
15
15
  export type EdgeConfidence = 'self_cls' | 'type_inference' | 'import' | 'http_endpoint' | 'same_file' | 'name_only' | 'type_name' | 'external';
16
16
  /** Broad relationship kind */
17
- export type EdgeKind = 'calls' | 'tested_by' | 'references' | 'depends_on';
17
+ export type EdgeKind = 'calls' | 'tested_by' | 'references' | 'depends_on' | 'affects' | 'authored_by' | 'changed_in_pr';
18
18
  /** Semantic nature of the call at the call site */
19
19
  export type CallType = 'direct' | 'method' | 'awaited' | 'constructor';
20
20
  export interface FunctionNode {
@@ -73,6 +73,24 @@ export interface LayerViolation {
73
73
  calleeLayer: string;
74
74
  reason: string;
75
75
  }
76
+ /**
77
+ * The layer a file belongs to, by the first matching prefix in declared order.
78
+ * Shared by the call-graph layer detector and the architecture guardrail (spec-23)
79
+ * so both agree on one layering convention.
80
+ */
81
+ export declare function layerOf(filePath: string, layers: Record<string, string[]>): string | undefined;
82
+ /**
83
+ * Classify a single directed edge (from → to) against a layer ordering. Declared
84
+ * key order is top → bottom; a lower layer depending on an upper layer is a
85
+ * violation. Returns the offending layer pair, or null when the edge is legal,
86
+ * unclassified, or intra-layer. The canonical layer-direction primitive — reused
87
+ * by `detectLayerViolations` (call edges) and the spec-23 architecture checker
88
+ * (file dependency edges).
89
+ */
90
+ export declare function classifyLayerEdge(fromFile: string, toFile: string, layers: Record<string, string[]>): {
91
+ fromLayer: string;
92
+ toLayer: string;
93
+ } | null;
76
94
  /**
77
95
  * A class or interface as a structural unit, grouping its methods.
78
96
  * Derived from FunctionNode.className after the call graph is built.
@@ -1 +1 @@
1
- {"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../../../src/core/analyzer/call-graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../../../src/core/analyzer/call-graph.ts"],"names":[],"mappings":"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"}
@@ -11,13 +11,46 @@
11
11
  * - Entry points — functions with no internal callers
12
12
  * - Layer violations — cross-layer calls in the wrong direction
13
13
  */
14
- import { dirname, resolve as resolvePath } from 'node:path';
14
+ import { dirname, join as joinPath } from 'node:path';
15
15
  import Parser from 'tree-sitter';
16
16
  import { FunctionRegistryTrie } from './function-registry-trie.js';
17
17
  import { inferTypesFromSource, resolveViaTypeInference } from './type-inference-engine.js';
18
18
  import { extractAllHttpEdges } from './http-route-parser.js';
19
19
  import { buildProjectedIac } from './iac/index.js';
20
+ import { isIacLanguage } from './iac/types.js';
20
21
  import { logger } from '../../utils/logger.js';
22
+ /**
23
+ * The layer a file belongs to, by the first matching prefix in declared order.
24
+ * Shared by the call-graph layer detector and the architecture guardrail (spec-23)
25
+ * so both agree on one layering convention.
26
+ */
27
+ export function layerOf(filePath, layers) {
28
+ for (const [layerName, prefixes] of Object.entries(layers)) {
29
+ if (prefixes.some(p => filePath.includes(p)))
30
+ return layerName;
31
+ }
32
+ return undefined;
33
+ }
34
+ /**
35
+ * Classify a single directed edge (from → to) against a layer ordering. Declared
36
+ * key order is top → bottom; a lower layer depending on an upper layer is a
37
+ * violation. Returns the offending layer pair, or null when the edge is legal,
38
+ * unclassified, or intra-layer. The canonical layer-direction primitive — reused
39
+ * by `detectLayerViolations` (call edges) and the spec-23 architecture checker
40
+ * (file dependency edges).
41
+ */
42
+ export function classifyLayerEdge(fromFile, toFile, layers) {
43
+ const order = Object.keys(layers);
44
+ const fromLayer = layerOf(fromFile, layers);
45
+ const toLayer = layerOf(toFile, layers);
46
+ if (!fromLayer || !toLayer || fromLayer === toLayer)
47
+ return null;
48
+ const fi = order.indexOf(fromLayer);
49
+ const ti = order.indexOf(toLayer);
50
+ if (fi === -1 || ti === -1)
51
+ return null;
52
+ return fi > ti ? { fromLayer, toLayer } : null;
53
+ }
21
54
  // ============================================================================
22
55
  // CONSTANTS
23
56
  // ============================================================================
@@ -186,6 +219,79 @@ function findEnclosingFunction(nodes, callPos) {
186
219
  }
187
220
  return best;
188
221
  }
222
+ /**
223
+ * Cross-domain code↔infra edges (spec-17).
224
+ *
225
+ * For each embedded IaC resource (Pulumi/CDK/CDKTF, declared inside a code file),
226
+ * find the narrowest enclosing code function in the same file by line containment
227
+ * and emit a `references` edge: enclosing function → resource. This is the single
228
+ * deterministic link that crosses the code↔infra boundary, so the existing graph
229
+ * traversal (which already walks `references` edges) answers "what infrastructure
230
+ * does this code provision?" and the reverse, end-to-end.
231
+ *
232
+ * Resources with no enclosing function (e.g. Pulumi declared at module top level)
233
+ * are left unlinked — there is no code unit to attribute them to. Standalone IaC
234
+ * (.tf/.yaml) has no co-located code functions, so nothing matches.
235
+ */
236
+ function linkCodeToInfra(iacNodes, allNodes) {
237
+ // Index code (non-IaC, non-external) function nodes with known line ranges by file.
238
+ const codeByFile = new Map();
239
+ for (const n of allNodes.values()) {
240
+ if (n.isExternal)
241
+ continue;
242
+ if (isIacLanguage(n.language))
243
+ continue;
244
+ if (n.startLine === undefined || n.endLine === undefined)
245
+ continue;
246
+ const arr = codeByFile.get(n.filePath);
247
+ if (arr)
248
+ arr.push(n);
249
+ else
250
+ codeByFile.set(n.filePath, [n]);
251
+ }
252
+ if (codeByFile.size === 0)
253
+ return [];
254
+ const edges = [];
255
+ const seen = new Set();
256
+ // Deterministic: iterate resources in id order.
257
+ const sorted = [...iacNodes].sort((a, b) => a.id.localeCompare(b.id));
258
+ for (const res of sorted) {
259
+ if (!isIacLanguage(res.language))
260
+ continue;
261
+ if (res.startLine === undefined)
262
+ continue;
263
+ const candidates = codeByFile.get(res.filePath);
264
+ if (!candidates)
265
+ continue;
266
+ // Narrowest code function whose line range encloses the resource declaration.
267
+ let best;
268
+ let bestSpan = Infinity;
269
+ for (const fn of candidates) {
270
+ if (fn.startLine <= res.startLine && res.startLine <= fn.endLine) {
271
+ const span = fn.endLine - fn.startLine;
272
+ if (span < bestSpan) {
273
+ bestSpan = span;
274
+ best = fn;
275
+ }
276
+ }
277
+ }
278
+ if (!best || best.id === res.id)
279
+ continue;
280
+ const key = `${best.id}\0${res.id}`;
281
+ if (seen.has(key))
282
+ continue;
283
+ seen.add(key);
284
+ edges.push({
285
+ callerId: best.id,
286
+ calleeId: res.id,
287
+ calleeName: res.name,
288
+ line: res.startLine,
289
+ confidence: 'import',
290
+ kind: 'references',
291
+ });
292
+ }
293
+ return edges;
294
+ }
189
295
  // ============================================================================
190
296
  // DOCSTRING / SIGNATURE EXTRACTION HELPERS
191
297
  // ============================================================================
@@ -2274,6 +2380,13 @@ export class CallGraphBuilder {
2274
2380
  allNodes.set(n.id, n);
2275
2381
  edges.push(...iac.edges);
2276
2382
  iacClasses = iac.classes;
2383
+ // Pass 2c.1: Cross-domain code↔infra edges (spec-17).
2384
+ // Embedded IaC (Pulumi/CDK/CDKTF) declares resources *inside* code files.
2385
+ // Link the enclosing code function → the resource it provisions with a
2386
+ // `references` edge, so analyze_impact/get_subgraph traverse the code↔infra
2387
+ // boundary end-to-end. Standalone IaC (.tf/.yaml) has no co-located code, so
2388
+ // no edge is created — those stay infra-only components, exactly as today.
2389
+ edges.push(...linkCodeToInfra(iac.nodes, allNodes));
2277
2390
  }
2278
2391
  catch {
2279
2392
  // IaC extraction is best-effort; never fail the whole build
@@ -2338,7 +2451,10 @@ export class CallGraphBuilder {
2338
2451
  const resolveSource = (rel) => {
2339
2452
  // Strip .js extension: TS ESM imports use './foo.js' to refer to './foo.ts'
2340
2453
  const stripped = rel.replace(/\.js$/, '');
2341
- const base = resolvePath(dir, stripped);
2454
+ // Form-preserving join (NOT resolve): the analyze pipeline passes repo-relative
2455
+ // paths, so resolve() would force an absolute path that never matches the
2456
+ // relative allFilePaths — silently zeroing out import-based tested_by edges.
2457
+ const base = joinPath(dir, stripped);
2342
2458
  return allFilePaths.find(p => p === base || p === `${base}.ts` || p === `${base}.tsx` ||
2343
2459
  p === `${base}.js` || p === `${base}.jsx` || p === `${base}/index.ts`);
2344
2460
  };
@@ -2518,39 +2634,23 @@ export class CallGraphBuilder {
2518
2634
  };
2519
2635
  }
2520
2636
  detectLayerViolations(edges, nodes, layers) {
2521
- // Build ordered layer list (index 0 = top layer, higher index = lower layer)
2522
- const layerOrder = Object.keys(layers);
2523
- const getLayer = (filePath) => {
2524
- for (const [layerName, prefixes] of Object.entries(layers)) {
2525
- if (prefixes.some(p => filePath.includes(p)))
2526
- return layerName;
2527
- }
2528
- return undefined;
2529
- };
2530
2637
  const violations = [];
2531
2638
  for (const edge of edges) {
2532
2639
  const caller = nodes.get(edge.callerId);
2533
2640
  const callee = nodes.get(edge.calleeId);
2534
2641
  if (!caller || !callee)
2535
2642
  continue;
2536
- const callerLayer = getLayer(caller.filePath);
2537
- const calleeLayer = getLayer(callee.filePath);
2538
- if (!callerLayer || !calleeLayer || callerLayer === calleeLayer)
2643
+ // Lower layer calling upper layer — violation (canonical primitive).
2644
+ const cls = classifyLayerEdge(caller.filePath, callee.filePath, layers);
2645
+ if (!cls)
2539
2646
  continue;
2540
- const callerIdx = layerOrder.indexOf(callerLayer);
2541
- const calleeIdx = layerOrder.indexOf(calleeLayer);
2542
- if (callerIdx === -1 || calleeIdx === -1)
2543
- continue;
2544
- if (callerIdx > calleeIdx) {
2545
- // Lower layer calling upper layer — violation
2546
- violations.push({
2547
- callerId: edge.callerId,
2548
- calleeId: edge.calleeId,
2549
- callerLayer,
2550
- calleeLayer,
2551
- reason: `${callerLayer} calls ${calleeLayer} (${caller.name} → ${callee.name})`,
2552
- });
2553
- }
2647
+ violations.push({
2648
+ callerId: edge.callerId,
2649
+ calleeId: edge.calleeId,
2650
+ callerLayer: cls.fromLayer,
2651
+ calleeLayer: cls.toLayer,
2652
+ reason: `${cls.fromLayer} calls ${cls.toLayer} (${caller.name} ${callee.name})`,
2653
+ });
2554
2654
  }
2555
2655
  return violations;
2556
2656
  }