@neat.is/core 0.9.12-dev.20260831 → 0.9.13-dev.20260901

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.
@@ -1252,7 +1252,7 @@ function buildServiceHostIndex(services) {
1252
1252
  async function walkSourceFiles(dir, excludeDirs = []) {
1253
1253
  const excluded = new Set(excludeDirs.map((d) => path5.resolve(d)));
1254
1254
  const out = [];
1255
- async function walk10(current) {
1255
+ async function walk11(current) {
1256
1256
  const entries = await fs5.readdir(current, { withFileTypes: true }).catch(() => []);
1257
1257
  for (const entry of entries) {
1258
1258
  const full = path5.join(current, entry.name);
@@ -1260,7 +1260,7 @@ async function walkSourceFiles(dir, excludeDirs = []) {
1260
1260
  if (IGNORED_DIRS.has(entry.name)) continue;
1261
1261
  if (excluded.has(path5.resolve(full))) continue;
1262
1262
  if (await isPythonVenvDir(full)) continue;
1263
- await walk10(full);
1263
+ await walk11(full);
1264
1264
  } else if (entry.isFile() && SERVICE_FILE_EXTENSIONS.has(path5.extname(entry.name)) && // Skip NEAT's own generated `otel-init.*` bootstrap — extracting it
1265
1265
  // would attribute our instrumentation imports to the user's service.
1266
1266
  !isNeatAuthoredSourceFile(entry.name)) {
@@ -1268,7 +1268,7 @@ async function walkSourceFiles(dir, excludeDirs = []) {
1268
1268
  }
1269
1269
  }
1270
1270
  }
1271
- await walk10(dir);
1271
+ await walk11(dir);
1272
1272
  return out;
1273
1273
  }
1274
1274
  async function loadSourceFiles(dir, excludeDirs = []) {
@@ -1869,8 +1869,8 @@ function chiRoutesFromSource(source, parser) {
1869
1869
  chiWalk(tree.rootNode, "", out);
1870
1870
  return out;
1871
1871
  }
1872
- function stripChiRegex(path72) {
1873
- return path72.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
1872
+ function stripChiRegex(path73) {
1873
+ return path73.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
1874
1874
  }
1875
1875
  function chiWalk(node, prefix, out) {
1876
1876
  for (let i = 0; i < node.namedChildCount; i++) {
@@ -2542,9 +2542,9 @@ function rubyRocketRoute(args) {
2542
2542
  if (!pair || pair.type !== "pair") continue;
2543
2543
  const k = pair.childForFieldName("key");
2544
2544
  if (k?.type !== "string") continue;
2545
- const path72 = rubyLiteral(k);
2546
- if (path72 === null) continue;
2547
- return { path: path72, target: rubyLiteral(pair.childForFieldName("value")) };
2545
+ const path73 = rubyLiteral(k);
2546
+ if (path73 === null) continue;
2547
+ return { path: path73, target: rubyLiteral(pair.childForFieldName("value")) };
2548
2548
  }
2549
2549
  return null;
2550
2550
  }
@@ -5096,29 +5096,29 @@ function promoteFrontierNodes(graph, opts = {}) {
5096
5096
  toPromote.push({ frontierId: id, serviceId: target });
5097
5097
  });
5098
5098
  let promoted = 0;
5099
- for (const { frontierId: frontierId2, serviceId: serviceId16 } of toPromote) {
5099
+ for (const { frontierId: frontierId2, serviceId: serviceId17 } of toPromote) {
5100
5100
  if (opts.policies && opts.policies.length > 0 && opts.policyCtx) {
5101
5101
  const gate = canPromoteFrontier(graph, frontierId2, opts.policies, opts.policyCtx);
5102
5102
  if (!gate.allowed) {
5103
5103
  continue;
5104
5104
  }
5105
5105
  }
5106
- rewireFrontierEdges(graph, frontierId2, serviceId16);
5106
+ rewireFrontierEdges(graph, frontierId2, serviceId17);
5107
5107
  graph.dropNode(frontierId2);
5108
5108
  promoted++;
5109
5109
  }
5110
5110
  return promoted;
5111
5111
  }
5112
- function rewireFrontierEdges(graph, frontierId2, serviceId16) {
5112
+ function rewireFrontierEdges(graph, frontierId2, serviceId17) {
5113
5113
  const inbound = [...graph.inboundEdges(frontierId2)];
5114
5114
  const outbound = [...graph.outboundEdges(frontierId2)];
5115
5115
  for (const edgeId of inbound) {
5116
5116
  const edge = graph.getEdgeAttributes(edgeId);
5117
- rebuildEdge(graph, edge, edge.source, serviceId16, edgeId);
5117
+ rebuildEdge(graph, edge, edge.source, serviceId17, edgeId);
5118
5118
  }
5119
5119
  for (const edgeId of outbound) {
5120
5120
  const edge = graph.getEdgeAttributes(edgeId);
5121
- rebuildEdge(graph, edge, serviceId16, edge.target, edgeId);
5121
+ rebuildEdge(graph, edge, serviceId17, edge.target, edgeId);
5122
5122
  }
5123
5123
  }
5124
5124
  function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
@@ -5471,19 +5471,19 @@ function confidenceFromMix(edges, now = Date.now()) {
5471
5471
  function longestIncomingWalk(graph, start, maxDepth) {
5472
5472
  let best = { path: [start], edges: [] };
5473
5473
  const visited = /* @__PURE__ */ new Set([start]);
5474
- function step(node, path72, edges) {
5475
- if (path72.length > best.path.length) {
5476
- best = { path: [...path72], edges: [...edges] };
5474
+ function step(node, path73, edges) {
5475
+ if (path73.length > best.path.length) {
5476
+ best = { path: [...path73], edges: [...edges] };
5477
5477
  }
5478
- if (path72.length - 1 >= maxDepth) return;
5478
+ if (path73.length - 1 >= maxDepth) return;
5479
5479
  const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
5480
5480
  for (const [srcId, edge] of incoming) {
5481
5481
  if (visited.has(srcId)) continue;
5482
5482
  visited.add(srcId);
5483
- path72.push(srcId);
5483
+ path73.push(srcId);
5484
5484
  edges.push(edge);
5485
- step(srcId, path72, edges);
5486
- path72.pop();
5485
+ step(srcId, path73, edges);
5486
+ path73.pop();
5487
5487
  edges.pop();
5488
5488
  visited.delete(srcId);
5489
5489
  }
@@ -5491,14 +5491,14 @@ function longestIncomingWalk(graph, start, maxDepth) {
5491
5491
  step(start, [start], []);
5492
5492
  return best;
5493
5493
  }
5494
- function databaseRootCauseShape(graph, origin, walk10) {
5494
+ function databaseRootCauseShape(graph, origin, walk11) {
5495
5495
  const targetDb = origin;
5496
5496
  const candidatePairs = compatPairs().filter((p) => p.engine === targetDb.engine);
5497
5497
  if (candidatePairs.length === 0) return null;
5498
- for (const id of walk10.path) {
5498
+ for (const id of walk11.path) {
5499
5499
  const owner = resolveOwningService(graph, id);
5500
5500
  if (!owner) continue;
5501
- const { id: serviceId16, svc } = owner;
5501
+ const { id: serviceId17, svc } = owner;
5502
5502
  const deps = svc.dependencies ?? {};
5503
5503
  for (const pair of candidatePairs) {
5504
5504
  const declared = deps[pair.driver];
@@ -5511,7 +5511,7 @@ function databaseRootCauseShape(graph, origin, walk10) {
5511
5511
  );
5512
5512
  if (!result.compatible) {
5513
5513
  return {
5514
- rootCauseNode: serviceId16,
5514
+ rootCauseNode: serviceId17,
5515
5515
  rootCauseReason: result.reason ?? "incompatible driver",
5516
5516
  ...result.minDriverVersion ? {
5517
5517
  fixRecommendation: `Upgrade ${svc.name} ${pair.driver} driver to >= ${result.minDriverVersion}`
@@ -5522,11 +5522,11 @@ function databaseRootCauseShape(graph, origin, walk10) {
5522
5522
  }
5523
5523
  return null;
5524
5524
  }
5525
- function serviceRootCauseShape(graph, _origin, walk10) {
5526
- for (const id of walk10.path) {
5525
+ function serviceRootCauseShape(graph, _origin, walk11) {
5526
+ for (const id of walk11.path) {
5527
5527
  const owner = resolveOwningService(graph, id);
5528
5528
  if (!owner) continue;
5529
- const { id: serviceId16, svc } = owner;
5529
+ const { id: serviceId17, svc } = owner;
5530
5530
  const deps = svc.dependencies ?? {};
5531
5531
  const serviceNodeEngine = svc.nodeEngine;
5532
5532
  for (const constraint of nodeEngineConstraints()) {
@@ -5535,7 +5535,7 @@ function serviceRootCauseShape(graph, _origin, walk10) {
5535
5535
  const result = checkNodeEngineConstraint(constraint, declared, serviceNodeEngine);
5536
5536
  if (!result.compatible && result.reason) {
5537
5537
  return {
5538
- rootCauseNode: serviceId16,
5538
+ rootCauseNode: serviceId17,
5539
5539
  rootCauseReason: result.reason,
5540
5540
  ...result.requiredNodeVersion ? {
5541
5541
  fixRecommendation: `Bump ${svc.name}'s engines.node to >= ${result.requiredNodeVersion}`
@@ -5550,7 +5550,7 @@ function serviceRootCauseShape(graph, _origin, walk10) {
5550
5550
  const result = checkPackageConflict(conflict, declared, requiredDeclared);
5551
5551
  if (!result.compatible && result.reason) {
5552
5552
  return {
5553
- rootCauseNode: serviceId16,
5553
+ rootCauseNode: serviceId17,
5554
5554
  rootCauseReason: result.reason,
5555
5555
  fixRecommendation: `Upgrade ${svc.name}'s ${conflict.requires.name} to >= ${conflict.requires.minVersion}`
5556
5556
  };
@@ -5559,15 +5559,15 @@ function serviceRootCauseShape(graph, _origin, walk10) {
5559
5559
  }
5560
5560
  return null;
5561
5561
  }
5562
- function fileRootCauseShape(graph, origin, walk10) {
5562
+ function fileRootCauseShape(graph, origin, walk11) {
5563
5563
  const owner = resolveOwningService(graph, origin.id);
5564
5564
  if (!owner) return null;
5565
- return serviceRootCauseShape(graph, owner.svc, walk10);
5565
+ return serviceRootCauseShape(graph, owner.svc, walk11);
5566
5566
  }
5567
- function symbolRootCauseShape(graph, origin, walk10) {
5567
+ function symbolRootCauseShape(graph, origin, walk11) {
5568
5568
  const owner = resolveOwningService(graph, origin.id);
5569
5569
  if (!owner) return null;
5570
- return serviceRootCauseShape(graph, owner.svc, walk10);
5570
+ return serviceRootCauseShape(graph, owner.svc, walk11);
5571
5571
  }
5572
5572
  var rootCauseShapes = {
5573
5573
  [NodeType5.DatabaseNode]: databaseRootCauseShape,
@@ -5580,8 +5580,8 @@ function legacyRootCause(graph, errorNodeId, errorEvent, incidents) {
5580
5580
  const origin = graph.getNodeAttributes(errorNodeId);
5581
5581
  const shape = rootCauseShapes[origin.type];
5582
5582
  if (shape) {
5583
- const walk10 = longestIncomingWalk(graph, errorNodeId, ROOT_CAUSE_MAX_DEPTH);
5584
- const match = shape(graph, origin, walk10);
5583
+ const walk11 = longestIncomingWalk(graph, errorNodeId, ROOT_CAUSE_MAX_DEPTH);
5584
+ const match = shape(graph, origin, walk11);
5585
5585
  if (match) {
5586
5586
  const reason = errorEvent ? `${match.rootCauseReason} (observed error: ${errorEvent.errorMessage})` : match.rootCauseReason;
5587
5587
  return {
@@ -5589,9 +5589,9 @@ function legacyRootCause(graph, errorNodeId, errorEvent, incidents) {
5589
5589
  result: RootCauseResultSchema.parse({
5590
5590
  rootCauseNode: match.rootCauseNode,
5591
5591
  rootCauseReason: reason,
5592
- traversalPath: walk10.path,
5593
- edgeProvenances: walk10.edges.map((e) => e.provenance),
5594
- confidence: confidenceFromMix(walk10.edges),
5592
+ traversalPath: walk11.path,
5593
+ edgeProvenances: walk11.edges.map((e) => e.provenance),
5594
+ confidence: confidenceFromMix(walk11.edges),
5595
5595
  fixRecommendation: match.fixRecommendation
5596
5596
  })
5597
5597
  };
@@ -5655,9 +5655,9 @@ function rootCauseFromIncidents(nodeId, incidents, errorEvent) {
5655
5655
  function isFailingCallEdge(e) {
5656
5656
  return e.type === EdgeType6.CALLS && (e.signal?.errorCount ?? 0) > 0;
5657
5657
  }
5658
- function callSourcesForService(graph, serviceId16) {
5659
- const ids = [serviceId16];
5660
- for (const edgeId of graph.outboundEdges(serviceId16)) {
5658
+ function callSourcesForService(graph, serviceId17) {
5659
+ const ids = [serviceId17];
5660
+ for (const edgeId of graph.outboundEdges(serviceId17)) {
5661
5661
  const e = graph.getEdgeAttributes(edgeId);
5662
5662
  if (e.type !== EdgeType6.CONTAINS) continue;
5663
5663
  const tgt = graph.getNodeAttributes(e.target);
@@ -5681,9 +5681,9 @@ function failingCallDominates(e, id, curEdge, curId) {
5681
5681
  }
5682
5682
  return id < curId;
5683
5683
  }
5684
- function dominantFailingCall(graph, serviceId16, visited) {
5684
+ function dominantFailingCall(graph, serviceId17, visited) {
5685
5685
  let best = null;
5686
- for (const src of callSourcesForService(graph, serviceId16)) {
5686
+ for (const src of callSourcesForService(graph, serviceId17)) {
5687
5687
  for (const edgeId of graph.outboundEdges(src)) {
5688
5688
  const e = graph.getEdgeAttributes(edgeId);
5689
5689
  if (!isFailingCallEdge(e)) continue;
@@ -5698,20 +5698,20 @@ function dominantFailingCall(graph, serviceId16, visited) {
5698
5698
  return best;
5699
5699
  }
5700
5700
  function followFailingCallChain(graph, originServiceId, maxDepth) {
5701
- const path72 = [originServiceId];
5701
+ const path73 = [originServiceId];
5702
5702
  const edges = [];
5703
5703
  const visited = /* @__PURE__ */ new Set([originServiceId]);
5704
5704
  let current = originServiceId;
5705
5705
  for (let depth = 0; depth < maxDepth; depth++) {
5706
5706
  const hop = dominantFailingCall(graph, current, visited);
5707
5707
  if (!hop) break;
5708
- path72.push(hop.nextService);
5708
+ path73.push(hop.nextService);
5709
5709
  edges.push(hop.edge);
5710
5710
  visited.add(hop.nextService);
5711
5711
  current = hop.nextService;
5712
5712
  }
5713
5713
  if (edges.length === 0) return null;
5714
- return { path: path72, edges, culprit: current };
5714
+ return { path: path73, edges, culprit: current };
5715
5715
  }
5716
5716
  function isStaleCallEdge(e) {
5717
5717
  return e.type === EdgeType6.CALLS && e.provenance === Provenance6.STALE;
@@ -5722,9 +5722,9 @@ function staleCallDominates(e, id, curEdge, curId) {
5722
5722
  if (ev !== cv) return ev > cv;
5723
5723
  return id < curId;
5724
5724
  }
5725
- function dominantStaleCall(graph, serviceId16, visited) {
5725
+ function dominantStaleCall(graph, serviceId17, visited) {
5726
5726
  const bestByCallee = /* @__PURE__ */ new Map();
5727
- for (const src of callSourcesForService(graph, serviceId16)) {
5727
+ for (const src of callSourcesForService(graph, serviceId17)) {
5728
5728
  for (const edgeId of graph.outboundEdges(src)) {
5729
5729
  const e = graph.getEdgeAttributes(edgeId);
5730
5730
  if (e.type !== EdgeType6.CALLS) continue;
@@ -5747,26 +5747,26 @@ function dominantStaleCall(graph, serviceId16, visited) {
5747
5747
  return best;
5748
5748
  }
5749
5749
  function followStaleCallChain(graph, originServiceId, maxDepth) {
5750
- const path72 = [originServiceId];
5750
+ const path73 = [originServiceId];
5751
5751
  const edges = [];
5752
5752
  const visited = /* @__PURE__ */ new Set([originServiceId]);
5753
5753
  let current = originServiceId;
5754
5754
  for (let depth = 0; depth < maxDepth; depth++) {
5755
5755
  const hop = dominantStaleCall(graph, current, visited);
5756
5756
  if (!hop) break;
5757
- path72.push(hop.nextService);
5757
+ path73.push(hop.nextService);
5758
5758
  edges.push(hop.edge);
5759
5759
  visited.add(hop.nextService);
5760
5760
  current = hop.nextService;
5761
5761
  }
5762
5762
  if (edges.length === 0) return null;
5763
- return { path: path72, edges, culprit: current };
5763
+ return { path: path73, edges, culprit: current };
5764
5764
  }
5765
5765
  function crossServiceRootCause(graph, originId, incidents, errorEvent) {
5766
5766
  const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
5767
5767
  if (!chain) return null;
5768
5768
  const culprit = chain.culprit;
5769
- const path72 = [...chain.path];
5769
+ const path73 = [...chain.path];
5770
5770
  const edgeProvenances = chain.edges.map((e) => e.provenance);
5771
5771
  const baseConfidence = confidenceFromMix(chain.edges);
5772
5772
  const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
@@ -5774,14 +5774,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
5774
5774
  if (loc) {
5775
5775
  let rootCauseNode = culprit;
5776
5776
  if (loc.fileNode) {
5777
- path72.push(loc.fileNode);
5777
+ path73.push(loc.fileNode);
5778
5778
  edgeProvenances.push(Provenance6.OBSERVED);
5779
5779
  rootCauseNode = loc.fileNode;
5780
5780
  }
5781
5781
  return RootCauseResultSchema.parse({
5782
5782
  rootCauseNode,
5783
5783
  rootCauseReason: loc.rootCauseReason,
5784
- traversalPath: path72,
5784
+ traversalPath: path73,
5785
5785
  edgeProvenances,
5786
5786
  confidence,
5787
5787
  ...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
@@ -5793,7 +5793,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
5793
5793
  return RootCauseResultSchema.parse({
5794
5794
  rootCauseNode: culprit,
5795
5795
  rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
5796
- traversalPath: path72,
5796
+ traversalPath: path73,
5797
5797
  edgeProvenances,
5798
5798
  confidence,
5799
5799
  fixRecommendation: `Inspect ${culpritName}'s failing handler`
@@ -6406,10 +6406,10 @@ function enrichWithNavigation(graph, errorNodeId, tagged, incidents, now) {
6406
6406
  traversalPath = staleChain.path;
6407
6407
  edgeProvenances = staleChain.edges.map((e) => e.provenance);
6408
6408
  } else if (top.node !== seedNode) {
6409
- const path72 = findPath(graph, errorNodeId, top.node, "up", ROOT_CAUSE_MAX_DEPTH);
6410
- if (path72) {
6411
- traversalPath = path72.nodes;
6412
- edgeProvenances = path72.edges.map((e) => e.provenance);
6409
+ const path73 = findPath(graph, errorNodeId, top.node, "up", ROOT_CAUSE_MAX_DEPTH);
6410
+ if (path73) {
6411
+ traversalPath = path73.nodes;
6412
+ edgeProvenances = path73.edges.map((e) => e.provenance);
6413
6413
  } else {
6414
6414
  traversalPath = [errorNodeId, top.node];
6415
6415
  edgeProvenances = [top.provenance ?? Provenance6.OBSERVED];
@@ -7334,9 +7334,9 @@ var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
7334
7334
  "StatefulSet",
7335
7335
  "DaemonSet"
7336
7336
  ]);
7337
- function addAliases(graph, serviceId16, candidates) {
7338
- if (!graph.hasNode(serviceId16)) return;
7339
- const node = graph.getNodeAttributes(serviceId16);
7337
+ function addAliases(graph, serviceId17, candidates) {
7338
+ if (!graph.hasNode(serviceId17)) return;
7339
+ const node = graph.getNodeAttributes(serviceId17);
7340
7340
  if (node.type !== NodeType16.ServiceNode) return;
7341
7341
  const set = new Set(node.aliases ?? []);
7342
7342
  for (const c of candidates) {
@@ -7346,7 +7346,7 @@ function addAliases(graph, serviceId16, candidates) {
7346
7346
  }
7347
7347
  if (set.size === 0) return;
7348
7348
  const updated = { ...node, aliases: [...set].sort() };
7349
- graph.replaceNodeAttributes(serviceId16, updated);
7349
+ graph.replaceNodeAttributes(serviceId17, updated);
7350
7350
  }
7351
7351
  function indexServicesByName(services) {
7352
7352
  const map = /* @__PURE__ */ new Map();
@@ -7379,12 +7379,12 @@ async function collectComposeAliases(graph, scanPath, serviceIndex) {
7379
7379
  }
7380
7380
  if (!compose?.services) return;
7381
7381
  for (const [composeName, svc] of Object.entries(compose.services)) {
7382
- const serviceId16 = serviceIndex.get(composeName);
7383
- if (!serviceId16) continue;
7382
+ const serviceId17 = serviceIndex.get(composeName);
7383
+ if (!serviceId17) continue;
7384
7384
  const aliases = /* @__PURE__ */ new Set([composeName]);
7385
7385
  if (svc.container_name) aliases.add(svc.container_name);
7386
7386
  if (svc.hostname) aliases.add(svc.hostname);
7387
- addAliases(graph, serviceId16, aliases);
7387
+ addAliases(graph, serviceId17, aliases);
7388
7388
  }
7389
7389
  }
7390
7390
  var LABEL_KEYS = /* @__PURE__ */ new Set([
@@ -8506,7 +8506,7 @@ async function addSymbolEdges(graph, services) {
8506
8506
  return best;
8507
8507
  };
8508
8508
  const requests = [];
8509
- const walk10 = (node) => {
8509
+ const walk11 = (node) => {
8510
8510
  if (node.type === "class_declaration" || node.type === "abstract_class_declaration" || node.type === "class") {
8511
8511
  const self = localBySpan.get(`${node.startPosition.row + 1}:${node.endPosition.row + 1}`);
8512
8512
  if (self && self.kind === "class") {
@@ -8552,10 +8552,10 @@ async function addSymbolEdges(graph, services) {
8552
8552
  }
8553
8553
  for (let i = 0; i < node.namedChildCount; i++) {
8554
8554
  const child = node.namedChild(i);
8555
- if (child) walk10(child);
8555
+ if (child) walk11(child);
8556
8556
  }
8557
8557
  };
8558
- walk10(root);
8558
+ walk11(root);
8559
8559
  for (const req of requests) {
8560
8560
  const targetSid = resolveTarget(req.targetName, req.wantKind);
8561
8561
  if (!targetSid) continue;
@@ -9733,7 +9733,7 @@ import {
9733
9733
  async function walkConfigFiles(dir, excludeDirs = []) {
9734
9734
  const excluded = new Set(excludeDirs.map((d) => path35.resolve(d)));
9735
9735
  const out = [];
9736
- async function walk10(current) {
9736
+ async function walk11(current) {
9737
9737
  const entries = await fs23.readdir(current, { withFileTypes: true });
9738
9738
  for (const entry of entries) {
9739
9739
  const full = path35.join(current, entry.name);
@@ -9741,13 +9741,13 @@ async function walkConfigFiles(dir, excludeDirs = []) {
9741
9741
  if (IGNORED_DIRS.has(entry.name)) continue;
9742
9742
  if (excluded.has(path35.resolve(full))) continue;
9743
9743
  if (await isPythonVenvDir(full)) continue;
9744
- await walk10(full);
9744
+ await walk11(full);
9745
9745
  } else if (entry.isFile() && isConfigFile(entry.name).match) {
9746
9746
  out.push(full);
9747
9747
  }
9748
9748
  }
9749
9749
  }
9750
- await walk10(dir);
9750
+ await walk11(dir);
9751
9751
  return out;
9752
9752
  }
9753
9753
  async function addConfigNodes(graph, services, scanPath) {
@@ -9844,7 +9844,7 @@ function grpcMethodsFromProto(content, fqPackage) {
9844
9844
  async function walkProtoFiles(dir, excludeDirs = []) {
9845
9845
  const excluded = new Set(excludeDirs.map((d) => path36.resolve(d)));
9846
9846
  const out = [];
9847
- async function walk10(current) {
9847
+ async function walk11(current) {
9848
9848
  const entries = await fs24.readdir(current, { withFileTypes: true }).catch(() => []);
9849
9849
  for (const entry of entries) {
9850
9850
  const full = path36.join(current, entry.name);
@@ -9852,13 +9852,13 @@ async function walkProtoFiles(dir, excludeDirs = []) {
9852
9852
  if (IGNORED_DIRS.has(entry.name)) continue;
9853
9853
  if (excluded.has(path36.resolve(full))) continue;
9854
9854
  if (await isPythonVenvDir(full)) continue;
9855
- await walk10(full);
9855
+ await walk11(full);
9856
9856
  } else if (entry.isFile() && path36.extname(entry.name) === PROTO_EXTENSION) {
9857
9857
  out.push(full);
9858
9858
  }
9859
9859
  }
9860
9860
  }
9861
- await walk10(dir);
9861
+ await walk11(dir);
9862
9862
  return out;
9863
9863
  }
9864
9864
  async function addGrpcMethods(graph, services) {
@@ -10870,7 +10870,7 @@ function isFirestoreClientFactory(node) {
10870
10870
  }
10871
10871
  function firestoreClientVars(root) {
10872
10872
  const vars = /* @__PURE__ */ new Set();
10873
- const walk10 = (node) => {
10873
+ const walk11 = (node) => {
10874
10874
  if (node.type === "variable_declarator") {
10875
10875
  const name = node.childForFieldName("name");
10876
10876
  let value = node.childForFieldName("value");
@@ -10879,9 +10879,9 @@ function firestoreClientVars(root) {
10879
10879
  vars.add(name.text);
10880
10880
  }
10881
10881
  }
10882
- for (const c of namedChildren(node)) walk10(c);
10882
+ for (const c of namedChildren(node)) walk11(c);
10883
10883
  };
10884
- walk10(root);
10884
+ walk11(root);
10885
10885
  return vars;
10886
10886
  }
10887
10887
  function isClientExpr(node, clientVars) {
@@ -11036,7 +11036,7 @@ function firestoreEndpointsFromFile(file, serviceDir) {
11036
11036
  }
11037
11037
  s.add(field);
11038
11038
  };
11039
- const walk10 = (node) => {
11039
+ const walk11 = (node) => {
11040
11040
  if (node.type === "call_expression") {
11041
11041
  const fn = node.childForFieldName("function");
11042
11042
  const line = node.startPosition.row + 1;
@@ -11076,9 +11076,9 @@ function firestoreEndpointsFromFile(file, serviceDir) {
11076
11076
  }
11077
11077
  }
11078
11078
  }
11079
- for (const c of namedChildren(node)) walk10(c);
11079
+ for (const c of namedChildren(node)) walk11(c);
11080
11080
  };
11081
- walk10(tree.rootNode);
11081
+ walk11(tree.rootNode);
11082
11082
  const out = [];
11083
11083
  for (const [collPath, line] of collLine) {
11084
11084
  const byField = writes.get(collPath);
@@ -11692,12 +11692,12 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
11692
11692
  return out;
11693
11693
  }
11694
11694
 
11695
- // src/extract/calls/django-orm.ts
11695
+ // src/extract/calls/socket.ts
11696
11696
  import path47 from "path";
11697
11697
  import Parser10 from "tree-sitter";
11698
11698
  import Python6 from "tree-sitter-python";
11699
11699
  import { infraId as infraId10 } from "@neat.is/types";
11700
- var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
11700
+ var SOCKET_IMPORT_RE = /(?:^|\n)\s*(?:import\s+socket\b|from\s+socket\s+import\b)/;
11701
11701
  var PARSE_CHUNK7 = 16384;
11702
11702
  function makePyParser4() {
11703
11703
  const p = new Parser10();
@@ -11717,22 +11717,108 @@ function namedChildren3(node) {
11717
11717
  }
11718
11718
  return out;
11719
11719
  }
11720
+ function walk4(node, visit) {
11721
+ visit(node);
11722
+ for (const c of namedChildren3(node)) walk4(c, visit);
11723
+ }
11720
11724
  function pyStaticStringText3(node) {
11721
11725
  if (node.type !== "string") return null;
11722
- for (const c of namedChildren3(node)) {
11726
+ for (const child of namedChildren3(node)) {
11727
+ if (child.type === "interpolation") return null;
11728
+ if (child.type === "string_content") return child.text;
11729
+ }
11730
+ return "";
11731
+ }
11732
+ function hasSocketConstructor(root) {
11733
+ let found = false;
11734
+ walk4(root, (n) => {
11735
+ if (found || n.type !== "call") return;
11736
+ const t = n.childForFieldName("function")?.text;
11737
+ if (t === "socket.socket" || t === "socket") found = true;
11738
+ });
11739
+ return found;
11740
+ }
11741
+ function socketEndpointsFromFile(file, serviceDir) {
11742
+ if (!SOCKET_IMPORT_RE.test(file.content)) return [];
11743
+ const tree = parseSource7(makePyParser4(), file.content);
11744
+ if (!hasSocketConstructor(tree.rootNode)) return [];
11745
+ const out = [];
11746
+ const seen = /* @__PURE__ */ new Set();
11747
+ walk4(tree.rootNode, (node) => {
11748
+ if (node.type !== "call") return;
11749
+ const fn = node.childForFieldName("function");
11750
+ if (fn?.type !== "attribute" || fn.childForFieldName("attribute")?.text !== "connect") return;
11751
+ const args = node.childForFieldName("arguments");
11752
+ const first = args ? namedChildren3(args).find((a) => a.type !== "keyword_argument") : void 0;
11753
+ if (!first || first.type !== "tuple") return;
11754
+ const elems = namedChildren3(first);
11755
+ if (elems.length < 2) return;
11756
+ const hostNode = elems[0];
11757
+ const host = hostNode.type === "string" ? pyStaticStringText3(hostNode) : null;
11758
+ const portNode = elems[1];
11759
+ const port = portNode.type === "integer" ? portNode.text : null;
11760
+ const name = host ? port ? `${host}:${port}` : host : "env";
11761
+ if (seen.has(name)) return;
11762
+ seen.add(name);
11763
+ const line = node.startPosition.row + 1;
11764
+ out.push({
11765
+ infraId: infraId10("socket", name),
11766
+ name,
11767
+ kind: "socket",
11768
+ edgeType: "CALLS",
11769
+ // A verified `socket.socket(...)` + `.connect((host, port))` call site.
11770
+ confidenceKind: "verified-call-site",
11771
+ evidence: {
11772
+ file: path47.relative(serviceDir, file.path),
11773
+ line,
11774
+ snippet: snippet(file.content, line)
11775
+ }
11776
+ });
11777
+ });
11778
+ return out;
11779
+ }
11780
+
11781
+ // src/extract/calls/django-orm.ts
11782
+ import path48 from "path";
11783
+ import Parser11 from "tree-sitter";
11784
+ import Python7 from "tree-sitter-python";
11785
+ import { infraId as infraId11 } from "@neat.is/types";
11786
+ var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
11787
+ var PARSE_CHUNK8 = 16384;
11788
+ function makePyParser5() {
11789
+ const p = new Parser11();
11790
+ p.setLanguage(Python7);
11791
+ return p;
11792
+ }
11793
+ function parseSource8(parser, source) {
11794
+ return parser.parse(
11795
+ (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK8)
11796
+ );
11797
+ }
11798
+ function namedChildren4(node) {
11799
+ const out = [];
11800
+ for (let i = 0; i < node.namedChildCount; i++) {
11801
+ const c = node.namedChild(i);
11802
+ if (c) out.push(c);
11803
+ }
11804
+ return out;
11805
+ }
11806
+ function pyStaticStringText4(node) {
11807
+ if (node.type !== "string") return null;
11808
+ for (const c of namedChildren4(node)) {
11723
11809
  if (c.type === "interpolation") return null;
11724
11810
  if (c.type === "string_content") return c.text;
11725
11811
  }
11726
11812
  return "";
11727
11813
  }
11728
- function walk4(node, visit) {
11814
+ function walk5(node, visit) {
11729
11815
  visit(node);
11730
- for (const c of namedChildren3(node)) walk4(c, visit);
11816
+ for (const c of namedChildren4(node)) walk5(c, visit);
11731
11817
  }
11732
11818
  function extendsDjangoModel(cls) {
11733
11819
  const supers = cls.childForFieldName("superclasses");
11734
11820
  if (!supers) return false;
11735
- for (const a of namedChildren3(supers)) {
11821
+ for (const a of namedChildren4(supers)) {
11736
11822
  const t = a.text;
11737
11823
  if (t === "models.Model" || t === "Model" || t.endsWith(".Model")) return true;
11738
11824
  }
@@ -11740,31 +11826,31 @@ function extendsDjangoModel(cls) {
11740
11826
  }
11741
11827
  function readMeta(body) {
11742
11828
  const out = {};
11743
- for (const stmt of namedChildren3(body)) {
11829
+ for (const stmt of namedChildren4(body)) {
11744
11830
  if (stmt.type !== "class_definition") continue;
11745
11831
  if (stmt.childForFieldName("name")?.text !== "Meta") continue;
11746
11832
  const metaBody = stmt.childForFieldName("body");
11747
11833
  if (!metaBody) continue;
11748
- for (const ms of namedChildren3(metaBody)) {
11834
+ for (const ms of namedChildren4(metaBody)) {
11749
11835
  if (ms.type !== "expression_statement") continue;
11750
11836
  const a = ms.namedChild(0);
11751
11837
  if (a?.type !== "assignment") continue;
11752
11838
  const l = a.childForFieldName("left")?.text;
11753
11839
  const r = a.childForFieldName("right");
11754
11840
  if (r?.type !== "string") continue;
11755
- if (l === "db_table") out.dbTable = pyStaticStringText3(r) ?? void 0;
11756
- if (l === "app_label") out.appLabel = pyStaticStringText3(r) ?? void 0;
11841
+ if (l === "db_table") out.dbTable = pyStaticStringText4(r) ?? void 0;
11842
+ if (l === "app_label") out.appLabel = pyStaticStringText4(r) ?? void 0;
11757
11843
  }
11758
11844
  }
11759
11845
  return out;
11760
11846
  }
11761
11847
  function djangoOrmEndpointsFromFile(file, serviceDir) {
11762
11848
  if (!DJANGO_IMPORT_RE.test(file.content)) return [];
11763
- const tree = parseSource7(makePyParser4(), file.content);
11849
+ const tree = parseSource8(makePyParser5(), file.content);
11764
11850
  const out = [];
11765
11851
  const seen = /* @__PURE__ */ new Set();
11766
- const defaultAppLabel = path47.basename(path47.dirname(file.path));
11767
- walk4(tree.rootNode, (node) => {
11852
+ const defaultAppLabel = path48.basename(path48.dirname(file.path));
11853
+ walk5(tree.rootNode, (node) => {
11768
11854
  if (node.type !== "class_definition") return;
11769
11855
  if (!extendsDjangoModel(node)) return;
11770
11856
  const nameNode = node.childForFieldName("name");
@@ -11776,30 +11862,30 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
11776
11862
  seen.add(table);
11777
11863
  const line = node.startPosition.row + 1;
11778
11864
  out.push({
11779
- infraId: infraId10("sql-table", table),
11865
+ infraId: infraId11("sql-table", table),
11780
11866
  name: table,
11781
11867
  kind: "sql-table",
11782
11868
  edgeType: "CALLS",
11783
11869
  confidenceKind: "verified-call-site",
11784
- evidence: { file: path47.relative(serviceDir, file.path), line, snippet: snippet(file.content, line) }
11870
+ evidence: { file: path48.relative(serviceDir, file.path), line, snippet: snippet(file.content, line) }
11785
11871
  });
11786
11872
  });
11787
11873
  return out;
11788
11874
  }
11789
11875
 
11790
11876
  // src/extract/calls/drizzle.ts
11791
- import path48 from "path";
11792
- import Parser11 from "tree-sitter";
11877
+ import path49 from "path";
11878
+ import Parser12 from "tree-sitter";
11793
11879
  import JavaScript7 from "tree-sitter-javascript";
11794
- import { infraId as infraId11 } from "@neat.is/types";
11880
+ import { infraId as infraId12 } from "@neat.is/types";
11795
11881
  var DRIZZLE_IMPORT_RE = /drizzle-orm/;
11796
11882
  var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
11797
11883
  function parserForExt3(ext) {
11798
- const p = new Parser11();
11884
+ const p = new Parser12();
11799
11885
  p.setLanguage(GRAMMAR_BY_EXT[ext] ?? JavaScript7);
11800
11886
  return p;
11801
11887
  }
11802
- function namedChildren4(node) {
11888
+ function namedChildren5(node) {
11803
11889
  const out = [];
11804
11890
  for (let i = 0; i < node.namedChildCount; i++) {
11805
11891
  const c = node.namedChild(i);
@@ -11809,7 +11895,7 @@ function namedChildren4(node) {
11809
11895
  }
11810
11896
  function stringLiteralText4(node) {
11811
11897
  if (!node || node.type !== "string") return null;
11812
- for (const child of namedChildren4(node)) {
11898
+ for (const child of namedChildren5(node)) {
11813
11899
  if (child.type === "string_fragment") return child.text;
11814
11900
  }
11815
11901
  return "";
@@ -11817,7 +11903,7 @@ function stringLiteralText4(node) {
11817
11903
  function firstStringArg(call) {
11818
11904
  const args = call.childForFieldName("arguments");
11819
11905
  if (!args) return null;
11820
- for (const arg of namedChildren4(args)) {
11906
+ for (const arg of namedChildren5(args)) {
11821
11907
  if (arg.type === "string") return stringLiteralText4(arg);
11822
11908
  return null;
11823
11909
  }
@@ -11852,7 +11938,7 @@ function keyName2(key) {
11852
11938
  function columnsFromObject(obj) {
11853
11939
  const out = [];
11854
11940
  const seen = /* @__PURE__ */ new Set();
11855
- for (const child of namedChildren4(obj)) {
11941
+ for (const child of namedChildren5(obj)) {
11856
11942
  if (child.type !== "pair") continue;
11857
11943
  const value = child.childForFieldName("value");
11858
11944
  const key = keyName2(child.childForFieldName("key"));
@@ -11866,15 +11952,15 @@ function columnsFromObject(obj) {
11866
11952
  }
11867
11953
  function drizzleEndpointsFromFile(file, serviceDir) {
11868
11954
  if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
11869
- const tree = parseSource3(parserForExt3(path48.extname(file.path)), file.content);
11955
+ const tree = parseSource3(parserForExt3(path49.extname(file.path)), file.content);
11870
11956
  const out = [];
11871
11957
  const seen = /* @__PURE__ */ new Set();
11872
- const walk10 = (node) => {
11958
+ const walk11 = (node) => {
11873
11959
  if (node.type === "call_expression") {
11874
11960
  const fn = node.childForFieldName("function");
11875
11961
  if (fn?.type === "identifier" && TABLE_BUILDERS.has(fn.text)) {
11876
11962
  const args = node.childForFieldName("arguments");
11877
- const argNodes = args ? namedChildren4(args) : [];
11963
+ const argNodes = args ? namedChildren5(args) : [];
11878
11964
  const tableName = stringLiteralText4(argNodes[0] ?? null);
11879
11965
  const obj = argNodes[1];
11880
11966
  if (tableName && obj?.type === "object" && !seen.has(tableName)) {
@@ -11882,14 +11968,14 @@ function drizzleEndpointsFromFile(file, serviceDir) {
11882
11968
  const columns = columnsFromObject(obj);
11883
11969
  const line = node.startPosition.row + 1;
11884
11970
  out.push({
11885
- infraId: infraId11("sql-table", tableName),
11971
+ infraId: infraId12("sql-table", tableName),
11886
11972
  name: tableName,
11887
11973
  kind: "sql-table",
11888
11974
  edgeType: "CALLS",
11889
11975
  confidenceKind: "structural",
11890
11976
  columns,
11891
11977
  evidence: {
11892
- file: path48.relative(serviceDir, file.path),
11978
+ file: path49.relative(serviceDir, file.path),
11893
11979
  line,
11894
11980
  snippet: snippet(file.content, line)
11895
11981
  }
@@ -11897,9 +11983,9 @@ function drizzleEndpointsFromFile(file, serviceDir) {
11897
11983
  }
11898
11984
  }
11899
11985
  }
11900
- for (const c of namedChildren4(node)) walk10(c);
11986
+ for (const c of namedChildren5(node)) walk11(c);
11901
11987
  };
11902
- walk10(tree.rootNode);
11988
+ walk11(tree.rootNode);
11903
11989
  return out;
11904
11990
  }
11905
11991
  function enclosingVarName(call) {
@@ -11921,12 +12007,12 @@ function enclosingVarName(call) {
11921
12007
  function collectDrizzleTables(root) {
11922
12008
  const tables = [];
11923
12009
  const varToTable = /* @__PURE__ */ new Map();
11924
- const walk10 = (node) => {
12010
+ const walk11 = (node) => {
11925
12011
  if (node.type === "call_expression") {
11926
12012
  const fn = node.childForFieldName("function");
11927
12013
  if (fn?.type === "identifier" && TABLE_BUILDERS.has(fn.text)) {
11928
12014
  const args = node.childForFieldName("arguments");
11929
- const argNodes = args ? namedChildren4(args) : [];
12015
+ const argNodes = args ? namedChildren5(args) : [];
11930
12016
  const tableName = stringLiteralText4(argNodes[0] ?? null);
11931
12017
  const obj = argNodes[1]?.type === "object" ? argNodes[1] : null;
11932
12018
  if (tableName) {
@@ -11936,9 +12022,9 @@ function collectDrizzleTables(root) {
11936
12022
  }
11937
12023
  }
11938
12024
  }
11939
- for (const c of namedChildren4(node)) walk10(c);
12025
+ for (const c of namedChildren5(node)) walk11(c);
11940
12026
  };
11941
- walk10(root);
12027
+ walk11(root);
11942
12028
  return { tables, varToTable };
11943
12029
  }
11944
12030
  function referencesTargetVar(call) {
@@ -11946,7 +12032,7 @@ function referencesTargetVar(call) {
11946
12032
  if (fn?.type !== "member_expression") return null;
11947
12033
  if (fn.childForFieldName("property")?.text !== "references") return null;
11948
12034
  const args = call.childForFieldName("arguments");
11949
- const first = args ? namedChildren4(args)[0] ?? null : null;
12035
+ const first = args ? namedChildren5(args)[0] ?? null : null;
11950
12036
  if (first?.type !== "arrow_function") return null;
11951
12037
  const body = first.childForFieldName("body");
11952
12038
  if (body?.type !== "member_expression") return null;
@@ -11955,13 +12041,13 @@ function referencesTargetVar(call) {
11955
12041
  }
11956
12042
  function drizzleForeignKeys(file, serviceDir) {
11957
12043
  if (!DRIZZLE_IMPORT_RE.test(file.content)) return [];
11958
- const tree = parseSource3(parserForExt3(path48.extname(file.path)), file.content);
12044
+ const tree = parseSource3(parserForExt3(path49.extname(file.path)), file.content);
11959
12045
  const { tables, varToTable } = collectDrizzleTables(tree.rootNode);
11960
12046
  const out = [];
11961
12047
  const seen = /* @__PURE__ */ new Set();
11962
12048
  for (const table of tables) {
11963
12049
  if (!table.object) continue;
11964
- const walk10 = (node) => {
12050
+ const walk11 = (node) => {
11965
12051
  if (node.type === "call_expression") {
11966
12052
  const targetVar = referencesTargetVar(node);
11967
12053
  const parentTable = targetVar ? varToTable.get(targetVar) : void 0;
@@ -11974,7 +12060,7 @@ function drizzleForeignKeys(file, serviceDir) {
11974
12060
  childTable: table.tableName,
11975
12061
  parentTable,
11976
12062
  evidence: {
11977
- file: path48.relative(serviceDir, file.path),
12063
+ file: path49.relative(serviceDir, file.path),
11978
12064
  line,
11979
12065
  snippet: snippet(file.content, line)
11980
12066
  }
@@ -11982,16 +12068,16 @@ function drizzleForeignKeys(file, serviceDir) {
11982
12068
  }
11983
12069
  }
11984
12070
  }
11985
- for (const c of namedChildren4(node)) walk10(c);
12071
+ for (const c of namedChildren5(node)) walk11(c);
11986
12072
  };
11987
- walk10(table.object);
12073
+ walk11(table.object);
11988
12074
  }
11989
12075
  return out;
11990
12076
  }
11991
12077
 
11992
12078
  // src/extract/calls/prisma.ts
11993
- import path49 from "path";
11994
- import { infraId as infraId12 } from "@neat.is/types";
12079
+ import path50 from "path";
12080
+ import { infraId as infraId13 } from "@neat.is/types";
11995
12081
  var SCALAR_TYPES = /* @__PURE__ */ new Set([
11996
12082
  "Int",
11997
12083
  "String",
@@ -12039,14 +12125,14 @@ function prismaColumnsFromSchema(file, serviceDir) {
12039
12125
  if (seenTable.has(b.tableName)) return;
12040
12126
  seenTable.add(b.tableName);
12041
12127
  out.push({
12042
- infraId: infraId12("sql-table", b.tableName),
12128
+ infraId: infraId13("sql-table", b.tableName),
12043
12129
  name: b.tableName,
12044
12130
  kind: "sql-table",
12045
12131
  edgeType: "CALLS",
12046
12132
  confidenceKind: "structural",
12047
12133
  columns: b.columns,
12048
12134
  evidence: {
12049
- file: path49.relative(serviceDir, file.path),
12135
+ file: path50.relative(serviceDir, file.path),
12050
12136
  line: b.startLine,
12051
12137
  snippet: snippet(content, b.startLine)
12052
12138
  }
@@ -12107,7 +12193,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
12107
12193
  }
12108
12194
  async function prismaColumnEndpoints(serviceDir) {
12109
12195
  const schemaPath = await findFirst(serviceDir, [
12110
- path49.join("prisma", "schema.prisma"),
12196
+ path50.join("prisma", "schema.prisma"),
12111
12197
  "schema.prisma"
12112
12198
  ]);
12113
12199
  if (!schemaPath) return [];
@@ -12182,7 +12268,7 @@ function prismaForeignKeysFromSchema(file, serviceDir) {
12182
12268
  childTable: current.table,
12183
12269
  parentTable,
12184
12270
  evidence: {
12185
- file: path49.relative(serviceDir, file.path),
12271
+ file: path50.relative(serviceDir, file.path),
12186
12272
  line: lineNo,
12187
12273
  snippet: snippet(content, lineNo)
12188
12274
  }
@@ -12197,7 +12283,7 @@ function prismaForeignKeysFromSchema(file, serviceDir) {
12197
12283
  }
12198
12284
  async function prismaForeignKeys(serviceDir) {
12199
12285
  const schemaPath = await findFirst(serviceDir, [
12200
- path49.join("prisma", "schema.prisma"),
12286
+ path50.join("prisma", "schema.prisma"),
12201
12287
  "schema.prisma"
12202
12288
  ]);
12203
12289
  if (!schemaPath) return [];
@@ -12207,27 +12293,27 @@ async function prismaForeignKeys(serviceDir) {
12207
12293
  }
12208
12294
 
12209
12295
  // src/extract/calls/activerecord.ts
12210
- import path50 from "path";
12211
- import Parser12 from "tree-sitter";
12296
+ import path51 from "path";
12297
+ import Parser13 from "tree-sitter";
12212
12298
  import Ruby3 from "tree-sitter-ruby";
12213
- import { infraId as infraId13 } from "@neat.is/types";
12299
+ import { infraId as infraId14 } from "@neat.is/types";
12214
12300
  var AR_SCHEMA_RE = /ActiveRecord::Schema/;
12215
- var PARSE_CHUNK8 = 16384;
12301
+ var PARSE_CHUNK9 = 16384;
12216
12302
  function makeRubyParser2() {
12217
- const p = new Parser12();
12303
+ const p = new Parser13();
12218
12304
  p.setLanguage(Ruby3);
12219
12305
  return p;
12220
12306
  }
12221
- function parseSource8(parser, source) {
12307
+ function parseSource9(parser, source) {
12222
12308
  return parser.parse(
12223
- (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK8)
12309
+ (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK9)
12224
12310
  );
12225
12311
  }
12226
- function walk5(node, visit) {
12312
+ function walk6(node, visit) {
12227
12313
  visit(node);
12228
12314
  for (let i = 0; i < node.namedChildCount; i++) {
12229
12315
  const c = node.namedChild(i);
12230
- if (c) walk5(c, visit);
12316
+ if (c) walk6(c, visit);
12231
12317
  }
12232
12318
  }
12233
12319
  function rubyLiteral2(node) {
@@ -12398,24 +12484,24 @@ function readCreateTable(call) {
12398
12484
  }
12399
12485
  function railsSchemaEndpointsFromFile(file, serviceDir) {
12400
12486
  if (!AR_SCHEMA_RE.test(file.content)) return [];
12401
- const tree = parseSource8(makeRubyParser2(), file.content);
12487
+ const tree = parseSource9(makeRubyParser2(), file.content);
12402
12488
  const out = [];
12403
12489
  const seen = /* @__PURE__ */ new Set();
12404
- walk5(tree.rootNode, (node) => {
12490
+ walk6(tree.rootNode, (node) => {
12405
12491
  if (node.type !== "call") return;
12406
12492
  if (blockCallMethod(node) !== "create_table") return;
12407
12493
  const table = readCreateTable(node);
12408
12494
  if (!table || seen.has(table.name)) return;
12409
12495
  seen.add(table.name);
12410
12496
  out.push({
12411
- infraId: infraId13("sql-table", table.name),
12497
+ infraId: infraId14("sql-table", table.name),
12412
12498
  name: table.name,
12413
12499
  kind: "sql-table",
12414
12500
  edgeType: "CALLS",
12415
12501
  confidenceKind: "structural",
12416
12502
  ...table.columns.length > 0 ? { columns: table.columns } : {},
12417
12503
  evidence: {
12418
- file: path50.relative(serviceDir, file.path),
12504
+ file: path51.relative(serviceDir, file.path),
12419
12505
  line: table.line,
12420
12506
  snippet: snippet(file.content, table.line)
12421
12507
  }
@@ -12425,7 +12511,7 @@ function railsSchemaEndpointsFromFile(file, serviceDir) {
12425
12511
  }
12426
12512
  function railsSchemaForeignKeys(file, serviceDir) {
12427
12513
  if (!AR_SCHEMA_RE.test(file.content)) return [];
12428
- const tree = parseSource8(makeRubyParser2(), file.content);
12514
+ const tree = parseSource9(makeRubyParser2(), file.content);
12429
12515
  const out = [];
12430
12516
  const seen = /* @__PURE__ */ new Set();
12431
12517
  const emit = (childTable, parentTable, line) => {
@@ -12437,13 +12523,13 @@ function railsSchemaForeignKeys(file, serviceDir) {
12437
12523
  childTable,
12438
12524
  parentTable,
12439
12525
  evidence: {
12440
- file: path50.relative(serviceDir, file.path),
12526
+ file: path51.relative(serviceDir, file.path),
12441
12527
  line,
12442
12528
  snippet: snippet(file.content, line)
12443
12529
  }
12444
12530
  });
12445
12531
  };
12446
- walk5(tree.rootNode, (node) => {
12532
+ walk6(tree.rootNode, (node) => {
12447
12533
  if (node.type !== "call") return;
12448
12534
  const method = blockCallMethod(node);
12449
12535
  if (method === "add_foreign_key") {
@@ -12504,23 +12590,23 @@ function modelTable(cls) {
12504
12590
  return tableize(nameNode.text);
12505
12591
  }
12506
12592
  function railsModelEndpointsFromFile(file, serviceDir) {
12507
- const tree = parseSource8(makeRubyParser2(), file.content);
12593
+ const tree = parseSource9(makeRubyParser2(), file.content);
12508
12594
  const out = [];
12509
12595
  const seen = /* @__PURE__ */ new Set();
12510
- walk5(tree.rootNode, (node) => {
12596
+ walk6(tree.rootNode, (node) => {
12511
12597
  if (node.type !== "class" || !isActiveRecordModel(node)) return;
12512
12598
  const table = modelTable(node);
12513
12599
  if (!table || seen.has(table)) return;
12514
12600
  seen.add(table);
12515
12601
  const line = node.startPosition.row + 1;
12516
12602
  out.push({
12517
- infraId: infraId13("sql-table", table),
12603
+ infraId: infraId14("sql-table", table),
12518
12604
  name: table,
12519
12605
  kind: "sql-table",
12520
12606
  edgeType: "CALLS",
12521
12607
  confidenceKind: "verified-call-site",
12522
12608
  evidence: {
12523
- file: path50.relative(serviceDir, file.path),
12609
+ file: path51.relative(serviceDir, file.path),
12524
12610
  line,
12525
12611
  snippet: snippet(file.content, line)
12526
12612
  }
@@ -12530,10 +12616,10 @@ function railsModelEndpointsFromFile(file, serviceDir) {
12530
12616
  }
12531
12617
  var AR_ASSOCIATIONS = /* @__PURE__ */ new Set(["belongs_to", "has_many", "has_one"]);
12532
12618
  function railsModelForeignKeys(file, serviceDir) {
12533
- const tree = parseSource8(makeRubyParser2(), file.content);
12619
+ const tree = parseSource9(makeRubyParser2(), file.content);
12534
12620
  const out = [];
12535
12621
  const seen = /* @__PURE__ */ new Set();
12536
- walk5(tree.rootNode, (node) => {
12622
+ walk6(tree.rootNode, (node) => {
12537
12623
  if (node.type !== "class" || !isActiveRecordModel(node)) return;
12538
12624
  const thisTable = modelTable(node);
12539
12625
  if (!thisTable) return;
@@ -12557,7 +12643,7 @@ function railsModelForeignKeys(file, serviceDir) {
12557
12643
  childTable,
12558
12644
  parentTable,
12559
12645
  evidence: {
12560
- file: path50.relative(serviceDir, file.path),
12646
+ file: path51.relative(serviceDir, file.path),
12561
12647
  line,
12562
12648
  snippet: snippet(file.content, line)
12563
12649
  }
@@ -12568,27 +12654,27 @@ function railsModelForeignKeys(file, serviceDir) {
12568
12654
  }
12569
12655
 
12570
12656
  // src/extract/calls/eloquent.ts
12571
- import path51 from "path";
12572
- import Parser13 from "tree-sitter";
12657
+ import path52 from "path";
12658
+ import Parser14 from "tree-sitter";
12573
12659
  import Php3 from "tree-sitter-php";
12574
- import { infraId as infraId14 } from "@neat.is/types";
12660
+ import { infraId as infraId15 } from "@neat.is/types";
12575
12661
  var LARAVEL_SCHEMA_RE = /\bSchema::(create|createIfNotExists|table)\b/;
12576
- var PARSE_CHUNK9 = 16384;
12662
+ var PARSE_CHUNK10 = 16384;
12577
12663
  function makePhpParser2() {
12578
- const p = new Parser13();
12664
+ const p = new Parser14();
12579
12665
  p.setLanguage(Php3.php_only);
12580
12666
  return p;
12581
12667
  }
12582
- function parseSource9(parser, source) {
12668
+ function parseSource10(parser, source) {
12583
12669
  return parser.parse(
12584
- (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK9)
12670
+ (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK10)
12585
12671
  );
12586
12672
  }
12587
- function walk6(node, visit) {
12673
+ function walk7(node, visit) {
12588
12674
  visit(node);
12589
12675
  for (let i = 0; i < node.namedChildCount; i++) {
12590
12676
  const c = node.namedChild(i);
12591
- if (c) walk6(c, visit);
12677
+ if (c) walk7(c, visit);
12592
12678
  }
12593
12679
  }
12594
12680
  function phpStaticString2(node) {
@@ -12799,9 +12885,9 @@ function columnsFromCall(chain, blueprintVar) {
12799
12885
  }
12800
12886
  function laravelMigrationEndpointsFromFile(file, serviceDir) {
12801
12887
  if (!LARAVEL_SCHEMA_RE.test(file.content)) return [];
12802
- const tree = parseSource9(makePhpParser2(), file.content);
12888
+ const tree = parseSource10(makePhpParser2(), file.content);
12803
12889
  const out = [];
12804
- walk6(tree.rootNode, (node) => {
12890
+ walk7(tree.rootNode, (node) => {
12805
12891
  if (!isSchemaCall(node)) return;
12806
12892
  const bp = readBlueprint(node);
12807
12893
  if (!bp) return;
@@ -12818,14 +12904,14 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
12818
12904
  }
12819
12905
  }
12820
12906
  out.push({
12821
- infraId: infraId14("sql-table", bp.table),
12907
+ infraId: infraId15("sql-table", bp.table),
12822
12908
  name: bp.table,
12823
12909
  kind: "sql-table",
12824
12910
  edgeType: "CALLS",
12825
12911
  confidenceKind: "structural",
12826
12912
  ...columns.length > 0 ? { columns } : {},
12827
12913
  evidence: {
12828
- file: path51.relative(serviceDir, file.path),
12914
+ file: path52.relative(serviceDir, file.path),
12829
12915
  line: bp.line,
12830
12916
  snippet: snippet(file.content, bp.line)
12831
12917
  }
@@ -12835,7 +12921,7 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
12835
12921
  }
12836
12922
  function laravelMigrationForeignKeys(file, serviceDir) {
12837
12923
  if (!LARAVEL_SCHEMA_RE.test(file.content)) return [];
12838
- const tree = parseSource9(makePhpParser2(), file.content);
12924
+ const tree = parseSource10(makePhpParser2(), file.content);
12839
12925
  const out = [];
12840
12926
  const seen = /* @__PURE__ */ new Set();
12841
12927
  const emit = (childTable, parentTable, line) => {
@@ -12847,13 +12933,13 @@ function laravelMigrationForeignKeys(file, serviceDir) {
12847
12933
  childTable,
12848
12934
  parentTable,
12849
12935
  evidence: {
12850
- file: path51.relative(serviceDir, file.path),
12936
+ file: path52.relative(serviceDir, file.path),
12851
12937
  line,
12852
12938
  snippet: snippet(file.content, line)
12853
12939
  }
12854
12940
  });
12855
12941
  };
12856
- walk6(tree.rootNode, (node) => {
12942
+ walk7(tree.rootNode, (node) => {
12857
12943
  if (!isSchemaCall(node)) return;
12858
12944
  const bp = readBlueprint(node);
12859
12945
  if (!bp || !bp.closureBody) return;
@@ -12951,23 +13037,23 @@ function walkWithinClass(cls, visit) {
12951
13037
  recur(body);
12952
13038
  }
12953
13039
  function laravelModelEndpointsFromFile(file, serviceDir) {
12954
- const tree = parseSource9(makePhpParser2(), file.content);
13040
+ const tree = parseSource10(makePhpParser2(), file.content);
12955
13041
  const out = [];
12956
13042
  const seen = /* @__PURE__ */ new Set();
12957
- walk6(tree.rootNode, (node) => {
13043
+ walk7(tree.rootNode, (node) => {
12958
13044
  if (node.type !== "class_declaration" || !isEloquentModel(node)) return;
12959
13045
  const table = modelTable2(node);
12960
13046
  if (!table || seen.has(table)) return;
12961
13047
  seen.add(table);
12962
13048
  const line = node.startPosition.row + 1;
12963
13049
  out.push({
12964
- infraId: infraId14("sql-table", table),
13050
+ infraId: infraId15("sql-table", table),
12965
13051
  name: table,
12966
13052
  kind: "sql-table",
12967
13053
  edgeType: "CALLS",
12968
13054
  confidenceKind: "verified-call-site",
12969
13055
  evidence: {
12970
- file: path51.relative(serviceDir, file.path),
13056
+ file: path52.relative(serviceDir, file.path),
12971
13057
  line,
12972
13058
  snippet: snippet(file.content, line)
12973
13059
  }
@@ -12977,10 +13063,10 @@ function laravelModelEndpointsFromFile(file, serviceDir) {
12977
13063
  }
12978
13064
  var ELOQUENT_RELATIONS = /* @__PURE__ */ new Set(["belongsTo", "hasMany", "hasOne"]);
12979
13065
  function laravelModelForeignKeys(file, serviceDir) {
12980
- const tree = parseSource9(makePhpParser2(), file.content);
13066
+ const tree = parseSource10(makePhpParser2(), file.content);
12981
13067
  const out = [];
12982
13068
  const seen = /* @__PURE__ */ new Set();
12983
- walk6(tree.rootNode, (node) => {
13069
+ walk7(tree.rootNode, (node) => {
12984
13070
  if (node.type !== "class_declaration" || !isEloquentModel(node)) return;
12985
13071
  const thisTable = modelTable2(node);
12986
13072
  if (!thisTable) return;
@@ -13003,7 +13089,7 @@ function laravelModelForeignKeys(file, serviceDir) {
13003
13089
  childTable,
13004
13090
  parentTable,
13005
13091
  evidence: {
13006
- file: path51.relative(serviceDir, file.path),
13092
+ file: path52.relative(serviceDir, file.path),
13007
13093
  line,
13008
13094
  snippet: snippet(file.content, line)
13009
13095
  }
@@ -13014,11 +13100,11 @@ function laravelModelForeignKeys(file, serviceDir) {
13014
13100
  }
13015
13101
 
13016
13102
  // src/extract/calls/go.ts
13017
- import path52 from "path";
13018
- import Parser14 from "tree-sitter";
13103
+ import path53 from "path";
13104
+ import Parser15 from "tree-sitter";
13019
13105
  import Go4 from "tree-sitter-go";
13020
- import { infraId as infraId15 } from "@neat.is/types";
13021
- var PARSE_CHUNK10 = 16384;
13106
+ import { infraId as infraId16 } from "@neat.is/types";
13107
+ var PARSE_CHUNK11 = 16384;
13022
13108
  var DATABASE_SQL_METHODS = /* @__PURE__ */ new Set([
13023
13109
  "Query",
13024
13110
  "QueryContext",
@@ -13044,20 +13130,20 @@ var SQLX_METHODS = /* @__PURE__ */ new Set([
13044
13130
  var DATABASE_SQL_IMPORT = "database/sql";
13045
13131
  var SQLX_IMPORT = "github.com/jmoiron/sqlx";
13046
13132
  function makeGoParser3() {
13047
- const p = new Parser14();
13133
+ const p = new Parser15();
13048
13134
  p.setLanguage(Go4);
13049
13135
  return p;
13050
13136
  }
13051
- function parseSource10(parser, source) {
13137
+ function parseSource11(parser, source) {
13052
13138
  return parser.parse(
13053
- (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK10)
13139
+ (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK11)
13054
13140
  );
13055
13141
  }
13056
- function walk7(node, visit) {
13142
+ function walk8(node, visit) {
13057
13143
  visit(node);
13058
13144
  for (let i = 0; i < node.namedChildCount; i++) {
13059
13145
  const child = node.namedChild(i);
13060
- if (child) walk7(child, visit);
13146
+ if (child) walk8(child, visit);
13061
13147
  }
13062
13148
  }
13063
13149
  function goStringLiteralValue(node) {
@@ -13070,7 +13156,7 @@ function goStringLiteralValue(node) {
13070
13156
  }
13071
13157
  function goImportsAny(root, names) {
13072
13158
  let found = false;
13073
- walk7(root, (node) => {
13159
+ walk8(root, (node) => {
13074
13160
  if (found || node.type !== "import_spec") return;
13075
13161
  for (let i = 0; i < node.namedChildCount; i++) {
13076
13162
  const value = goStringLiteralValue(node.namedChild(i));
@@ -13088,14 +13174,14 @@ function firstStringLiteralArg(argsNode) {
13088
13174
  return null;
13089
13175
  }
13090
13176
  function goSqlEndpointsFromFile(file, serviceDir) {
13091
- if (path52.extname(file.path) !== ".go") return [];
13177
+ if (path53.extname(file.path) !== ".go") return [];
13092
13178
  if (!file.content.includes(DATABASE_SQL_IMPORT) && !file.content.includes(SQLX_IMPORT)) return [];
13093
- const tree = parseSource10(makeGoParser3(), file.content);
13179
+ const tree = parseSource11(makeGoParser3(), file.content);
13094
13180
  const importsDatabaseSql = goImportsAny(tree.rootNode, /* @__PURE__ */ new Set([DATABASE_SQL_IMPORT]));
13095
13181
  const importsSqlx = goImportsAny(tree.rootNode, /* @__PURE__ */ new Set([SQLX_IMPORT]));
13096
13182
  if (!importsDatabaseSql && !importsSqlx) return [];
13097
13183
  const out = [];
13098
- walk7(tree.rootNode, (node) => {
13184
+ walk8(tree.rootNode, (node) => {
13099
13185
  if (node.type !== "call_expression") return;
13100
13186
  const fn = node.childForFieldName("function");
13101
13187
  if (fn?.type !== "selector_expression") return;
@@ -13110,14 +13196,14 @@ function goSqlEndpointsFromFile(file, serviceDir) {
13110
13196
  const columns = columnsFromSqlStatement(sql);
13111
13197
  const line = node.startPosition.row + 1;
13112
13198
  out.push({
13113
- infraId: infraId15("sql-table", table),
13199
+ infraId: infraId16("sql-table", table),
13114
13200
  name: table,
13115
13201
  kind: "sql-table",
13116
13202
  edgeType: "CALLS",
13117
13203
  confidenceKind: "verified-call-site",
13118
13204
  ...columns.length > 0 ? { columns } : {},
13119
13205
  evidence: {
13120
- file: toPosix(path52.relative(serviceDir, file.path)),
13206
+ file: toPosix(path53.relative(serviceDir, file.path)),
13121
13207
  line,
13122
13208
  snippet: snippet(file.content, line)
13123
13209
  }
@@ -13127,27 +13213,27 @@ function goSqlEndpointsFromFile(file, serviceDir) {
13127
13213
  }
13128
13214
 
13129
13215
  // src/extract/calls/gorm.ts
13130
- import path53 from "path";
13131
- import Parser15 from "tree-sitter";
13216
+ import path54 from "path";
13217
+ import Parser16 from "tree-sitter";
13132
13218
  import Go5 from "tree-sitter-go";
13133
- import { infraId as infraId16 } from "@neat.is/types";
13219
+ import { infraId as infraId17 } from "@neat.is/types";
13134
13220
  var GORM_IMPORT_RE = /gorm\.io\/gorm/;
13135
- var PARSE_CHUNK11 = 16384;
13221
+ var PARSE_CHUNK12 = 16384;
13136
13222
  function makeGoParser4() {
13137
- const p = new Parser15();
13223
+ const p = new Parser16();
13138
13224
  p.setLanguage(Go5);
13139
13225
  return p;
13140
13226
  }
13141
- function parseSource11(parser, source) {
13227
+ function parseSource12(parser, source) {
13142
13228
  return parser.parse(
13143
- (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK11)
13229
+ (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK12)
13144
13230
  );
13145
13231
  }
13146
- function walk8(node, visit) {
13232
+ function walk9(node, visit) {
13147
13233
  visit(node);
13148
13234
  for (let i = 0; i < node.namedChildCount; i++) {
13149
13235
  const c = node.namedChild(i);
13150
- if (c) walk8(c, visit);
13236
+ if (c) walk9(c, visit);
13151
13237
  }
13152
13238
  }
13153
13239
  var COMMON_INITIALISMS = [
@@ -13380,7 +13466,7 @@ function readField(fieldDecl) {
13380
13466
  }
13381
13467
  function collectStructs(tree) {
13382
13468
  const structs = /* @__PURE__ */ new Map();
13383
- walk8(tree.rootNode, (node) => {
13469
+ walk9(tree.rootNode, (node) => {
13384
13470
  if (node.type !== "type_spec") return;
13385
13471
  const nameNode = node.childForFieldName("name");
13386
13472
  const typeNode = node.childForFieldName("type");
@@ -13429,7 +13515,7 @@ function compositeStructName(arg) {
13429
13515
  }
13430
13516
  function collectCallModels(tree) {
13431
13517
  const models = /* @__PURE__ */ new Set();
13432
- walk8(tree.rootNode, (node) => {
13518
+ walk9(tree.rootNode, (node) => {
13433
13519
  if (node.type !== "call_expression") return;
13434
13520
  const fn = node.childForFieldName("function");
13435
13521
  if (fn?.type !== "selector_expression") return;
@@ -13449,7 +13535,7 @@ function collectCallModels(tree) {
13449
13535
  function collectTableNameOverrides(tree) {
13450
13536
  const overrides = /* @__PURE__ */ new Map();
13451
13537
  const declarers = /* @__PURE__ */ new Set();
13452
- walk8(tree.rootNode, (node) => {
13538
+ walk9(tree.rootNode, (node) => {
13453
13539
  if (node.type !== "method_declaration") return;
13454
13540
  if (node.childForFieldName("name")?.text !== "TableName") return;
13455
13541
  const receiver = node.childForFieldName("receiver");
@@ -13466,7 +13552,7 @@ function collectTableNameOverrides(tree) {
13466
13552
  const body = node.childForFieldName("body");
13467
13553
  if (!body) return;
13468
13554
  let literal = null;
13469
- walk8(body, (n) => {
13555
+ walk9(body, (n) => {
13470
13556
  if (literal !== null) return;
13471
13557
  if (n.type !== "return_statement") return;
13472
13558
  const exprList = n.namedChild(0);
@@ -13560,9 +13646,9 @@ function collectColumns(struct, structs, seen, prefix, out, emitted) {
13560
13646
  seen.delete(struct.name);
13561
13647
  }
13562
13648
  function gormEndpointsFromFile(file, serviceDir) {
13563
- if (path53.extname(file.path) !== ".go") return [];
13649
+ if (path54.extname(file.path) !== ".go") return [];
13564
13650
  if (!GORM_IMPORT_RE.test(file.content)) return [];
13565
- const tree = parseSource11(makeGoParser4(), file.content);
13651
+ const tree = parseSource12(makeGoParser4(), file.content);
13566
13652
  const { structs, models, tableFor } = analyze(tree);
13567
13653
  const out = [];
13568
13654
  const seenTables = /* @__PURE__ */ new Set();
@@ -13575,14 +13661,14 @@ function gormEndpointsFromFile(file, serviceDir) {
13575
13661
  const columns = [];
13576
13662
  collectColumns(struct, structs, /* @__PURE__ */ new Set(), "", columns, /* @__PURE__ */ new Set());
13577
13663
  out.push({
13578
- infraId: infraId16("sql-table", table),
13664
+ infraId: infraId17("sql-table", table),
13579
13665
  name: table,
13580
13666
  kind: "sql-table",
13581
13667
  edgeType: "CALLS",
13582
13668
  confidenceKind: "structural",
13583
13669
  ...columns.length > 0 ? { columns } : {},
13584
13670
  evidence: {
13585
- file: toPosix(path53.relative(serviceDir, file.path)),
13671
+ file: toPosix(path54.relative(serviceDir, file.path)),
13586
13672
  line: struct.line,
13587
13673
  snippet: snippet(file.content, struct.line)
13588
13674
  }
@@ -13591,9 +13677,9 @@ function gormEndpointsFromFile(file, serviceDir) {
13591
13677
  return out;
13592
13678
  }
13593
13679
  function gormForeignKeys(file, serviceDir) {
13594
- if (path53.extname(file.path) !== ".go") return [];
13680
+ if (path54.extname(file.path) !== ".go") return [];
13595
13681
  if (!GORM_IMPORT_RE.test(file.content)) return [];
13596
- const tree = parseSource11(makeGoParser4(), file.content);
13682
+ const tree = parseSource12(makeGoParser4(), file.content);
13597
13683
  const { structs, models, tableFor } = analyze(tree);
13598
13684
  const out = [];
13599
13685
  const seen = /* @__PURE__ */ new Set();
@@ -13606,7 +13692,7 @@ function gormForeignKeys(file, serviceDir) {
13606
13692
  childTable,
13607
13693
  parentTable,
13608
13694
  evidence: {
13609
- file: toPosix(path53.relative(serviceDir, file.path)),
13695
+ file: toPosix(path54.relative(serviceDir, file.path)),
13610
13696
  line,
13611
13697
  snippet: snippet(file.content, line)
13612
13698
  }
@@ -13642,27 +13728,27 @@ function gormForeignKeys(file, serviceDir) {
13642
13728
  }
13643
13729
 
13644
13730
  // src/extract/calls/efcore.ts
13645
- import path54 from "path";
13646
- import Parser16 from "tree-sitter";
13731
+ import path55 from "path";
13732
+ import Parser17 from "tree-sitter";
13647
13733
  import CSharp2 from "tree-sitter-c-sharp";
13648
- import { infraId as infraId17 } from "@neat.is/types";
13734
+ import { infraId as infraId18 } from "@neat.is/types";
13649
13735
  var EFCORE_GATE = /Microsoft\.EntityFrameworkCore|DataAnnotations\.Schema|\bDbContext\b|\bDbSet\s*</;
13650
- var PARSE_CHUNK12 = 16384;
13736
+ var PARSE_CHUNK13 = 16384;
13651
13737
  function makeCsParser() {
13652
- const p = new Parser16();
13738
+ const p = new Parser17();
13653
13739
  p.setLanguage(CSharp2);
13654
13740
  return p;
13655
13741
  }
13656
- function parseSource12(parser, source) {
13742
+ function parseSource13(parser, source) {
13657
13743
  return parser.parse(
13658
- (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK12)
13744
+ (index) => index >= source.length ? "" : source.slice(index, index + PARSE_CHUNK13)
13659
13745
  );
13660
13746
  }
13661
- function walk9(node, visit) {
13747
+ function walk10(node, visit) {
13662
13748
  visit(node);
13663
13749
  for (let i = 0; i < node.namedChildCount; i++) {
13664
13750
  const c = node.namedChild(i);
13665
- if (c) walk9(c, visit);
13751
+ if (c) walk10(c, visit);
13666
13752
  }
13667
13753
  }
13668
13754
  function firstChildOfType(node, type) {
@@ -13721,28 +13807,28 @@ function tableFromToTable(call) {
13721
13807
  return value ? csStringLiteral(value) : null;
13722
13808
  }
13723
13809
  function efcoreEndpointsFromFile(file, serviceDir) {
13724
- if (path54.extname(file.path) !== ".cs") return [];
13810
+ if (path55.extname(file.path) !== ".cs") return [];
13725
13811
  if (!EFCORE_GATE.test(file.content)) return [];
13726
- const tree = parseSource12(makeCsParser(), file.content);
13812
+ const tree = parseSource13(makeCsParser(), file.content);
13727
13813
  const out = [];
13728
13814
  const seen = /* @__PURE__ */ new Set();
13729
13815
  const push = (name, line) => {
13730
13816
  if (!name || seen.has(name)) return;
13731
13817
  seen.add(name);
13732
13818
  out.push({
13733
- infraId: infraId17("sql-table", name),
13819
+ infraId: infraId18("sql-table", name),
13734
13820
  name,
13735
13821
  kind: "sql-table",
13736
13822
  edgeType: "CALLS",
13737
13823
  confidenceKind: "structural",
13738
13824
  evidence: {
13739
- file: toPosix(path54.relative(serviceDir, file.path)),
13825
+ file: toPosix(path55.relative(serviceDir, file.path)),
13740
13826
  line,
13741
13827
  snippet: snippet(file.content, line)
13742
13828
  }
13743
13829
  });
13744
13830
  };
13745
- walk9(tree.rootNode, (node) => {
13831
+ walk10(tree.rootNode, (node) => {
13746
13832
  if (node.type === "attribute") {
13747
13833
  const table = tableFromAttribute(node);
13748
13834
  if (table) push(table, node.startPosition.row + 1);
@@ -13819,6 +13905,11 @@ async function addExternalEndpointEdges(graph, services) {
13819
13905
  } catch (err) {
13820
13906
  recordExtractionError("efcore data-axis extraction", file.path, err);
13821
13907
  }
13908
+ try {
13909
+ endpoints.push(...socketEndpointsFromFile(file, service.dir));
13910
+ } catch (err) {
13911
+ recordExtractionError("python socket call extraction", file.path, err);
13912
+ }
13822
13913
  }
13823
13914
  endpoints.push(...await mongooseCrossFileEndpoints(maskedFiles, service.dir));
13824
13915
  endpoints.push(...pythonOrmCrossFileEndpoints(maskedFiles, service.dir));
@@ -13922,7 +14013,7 @@ import {
13922
14013
  Provenance as Provenance16,
13923
14014
  confidenceForExtracted as confidenceForExtracted13,
13924
14015
  extractedEdgeId as extractedEdgeId10,
13925
- infraId as infraId18
14016
+ infraId as infraId19
13926
14017
  } from "@neat.is/types";
13927
14018
  async function addTableEdges(graph, services) {
13928
14019
  let nodesAdded = 0;
@@ -13951,8 +14042,8 @@ async function addTableEdges(graph, services) {
13951
14042
  }
13952
14043
  refs.push(...modelRefs);
13953
14044
  for (const ref of refs) {
13954
- const childId = infraId18("sql-table", ref.childTable);
13955
- const parentId = infraId18("sql-table", ref.parentTable);
14045
+ const childId = infraId19("sql-table", ref.childTable);
14046
+ const parentId = infraId19("sql-table", ref.parentTable);
13956
14047
  if (childId === parentId) continue;
13957
14048
  nodesAdded += ensureTableNode(graph, childId, ref.childTable);
13958
14049
  nodesAdded += ensureTableNode(graph, parentId, ref.parentTable);
@@ -13987,14 +14078,14 @@ function ensureTableNode(graph, id, name) {
13987
14078
  }
13988
14079
 
13989
14080
  // src/extract/infra/docker-compose.ts
13990
- import path55 from "path";
14081
+ import path56 from "path";
13991
14082
  import { EdgeType as EdgeType17, Provenance as Provenance18, confidenceForExtracted as confidenceForExtracted15 } from "@neat.is/types";
13992
14083
 
13993
14084
  // src/extract/infra/shared.ts
13994
- import { NodeType as NodeType26, Provenance as Provenance17, confidenceForExtracted as confidenceForExtracted14, infraId as infraId19 } from "@neat.is/types";
14085
+ import { NodeType as NodeType26, Provenance as Provenance17, confidenceForExtracted as confidenceForExtracted14, infraId as infraId20 } from "@neat.is/types";
13995
14086
  function makeInfraNode(kind, name, provider = "self", extras) {
13996
14087
  return {
13997
- id: infraId19(kind, name),
14088
+ id: infraId20(kind, name),
13998
14089
  type: NodeType26.InfraNode,
13999
14090
  name,
14000
14091
  provider,
@@ -14057,7 +14148,7 @@ function dependsOnList(value) {
14057
14148
  }
14058
14149
  function serviceNameToServiceNode(name, services) {
14059
14150
  for (const s of services) {
14060
- if (s.node.name === name || path55.basename(s.dir) === name) return s.node.id;
14151
+ if (s.node.name === name || path56.basename(s.dir) === name) return s.node.id;
14061
14152
  }
14062
14153
  return null;
14063
14154
  }
@@ -14066,7 +14157,7 @@ async function addComposeInfra(graph, scanPath, services) {
14066
14157
  let edgesAdded = 0;
14067
14158
  let composePath = null;
14068
14159
  for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
14069
- const abs = path55.join(scanPath, name);
14160
+ const abs = path56.join(scanPath, name);
14070
14161
  if (await exists(abs)) {
14071
14162
  composePath = abs;
14072
14163
  break;
@@ -14079,13 +14170,13 @@ async function addComposeInfra(graph, scanPath, services) {
14079
14170
  } catch (err) {
14080
14171
  recordExtractionError(
14081
14172
  "infra docker-compose",
14082
- path55.relative(scanPath, composePath),
14173
+ path56.relative(scanPath, composePath),
14083
14174
  err
14084
14175
  );
14085
14176
  return { nodesAdded, edgesAdded };
14086
14177
  }
14087
14178
  if (!compose?.services) return { nodesAdded, edgesAdded };
14088
- const evidenceFile = path55.relative(scanPath, composePath).split(path55.sep).join("/");
14179
+ const evidenceFile = path56.relative(scanPath, composePath).split(path56.sep).join("/");
14089
14180
  const composeNameToNodeId = /* @__PURE__ */ new Map();
14090
14181
  for (const [composeName, svc] of Object.entries(compose.services)) {
14091
14182
  const matchedServiceId = serviceNameToServiceNode(composeName, services);
@@ -14126,7 +14217,7 @@ async function addComposeInfra(graph, scanPath, services) {
14126
14217
  }
14127
14218
 
14128
14219
  // src/extract/infra/dockerfile.ts
14129
- import path56 from "path";
14220
+ import path57 from "path";
14130
14221
  import { promises as fs25 } from "fs";
14131
14222
  import { EdgeType as EdgeType18, Provenance as Provenance19, confidenceForExtracted as confidenceForExtracted16 } from "@neat.is/types";
14132
14223
  function readDockerfile(content) {
@@ -14157,7 +14248,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
14157
14248
  let nodesAdded = 0;
14158
14249
  let edgesAdded = 0;
14159
14250
  for (const service of services) {
14160
- const dockerfilePath = path56.join(service.dir, "Dockerfile");
14251
+ const dockerfilePath = path57.join(service.dir, "Dockerfile");
14161
14252
  if (!await exists(dockerfilePath)) continue;
14162
14253
  let content;
14163
14254
  try {
@@ -14165,7 +14256,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
14165
14256
  } catch (err) {
14166
14257
  recordExtractionError(
14167
14258
  "infra dockerfile",
14168
- path56.relative(scanPath, dockerfilePath),
14259
+ path57.relative(scanPath, dockerfilePath),
14169
14260
  err
14170
14261
  );
14171
14262
  continue;
@@ -14177,8 +14268,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
14177
14268
  graph.addNode(node.id, node);
14178
14269
  nodesAdded++;
14179
14270
  }
14180
- const relDockerfile = toPosix(path56.relative(service.dir, dockerfilePath));
14181
- const evidenceFile = toPosix(path56.relative(scanPath, dockerfilePath));
14271
+ const relDockerfile = toPosix(path57.relative(service.dir, dockerfilePath));
14272
+ const evidenceFile = toPosix(path57.relative(scanPath, dockerfilePath));
14182
14273
  const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
14183
14274
  graph,
14184
14275
  service.pkg.name,
@@ -14230,7 +14321,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
14230
14321
 
14231
14322
  // src/extract/infra/terraform.ts
14232
14323
  import { promises as fs26 } from "fs";
14233
- import path57 from "path";
14324
+ import path58 from "path";
14234
14325
  import { EdgeType as EdgeType19, Provenance as Provenance20, confidenceForExtracted as confidenceForExtracted17 } from "@neat.is/types";
14235
14326
  var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
14236
14327
  var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
@@ -14241,11 +14332,11 @@ async function walkTfFiles(start, depth = 0, max = 5) {
14241
14332
  for (const entry of entries) {
14242
14333
  if (entry.isDirectory()) {
14243
14334
  if (IGNORED_DIRS.has(entry.name) || entry.name === ".terraform") continue;
14244
- const child = path57.join(start, entry.name);
14335
+ const child = path58.join(start, entry.name);
14245
14336
  if (await isPythonVenvDir(child)) continue;
14246
14337
  out.push(...await walkTfFiles(child, depth + 1, max));
14247
14338
  } else if (entry.isFile() && entry.name.endsWith(".tf")) {
14248
- out.push(path57.join(start, entry.name));
14339
+ out.push(path58.join(start, entry.name));
14249
14340
  }
14250
14341
  }
14251
14342
  return out;
@@ -14277,7 +14368,7 @@ async function addTerraformResources(graph, scanPath) {
14277
14368
  const files = await walkTfFiles(scanPath);
14278
14369
  for (const file of files) {
14279
14370
  const content = await fs26.readFile(file, "utf8");
14280
- const evidenceFile = toPosix(path57.relative(scanPath, file));
14371
+ const evidenceFile = toPosix(path58.relative(scanPath, file));
14281
14372
  const resources = [];
14282
14373
  const byKey = /* @__PURE__ */ new Map();
14283
14374
  RESOURCE_RE.lastIndex = 0;
@@ -14334,8 +14425,9 @@ async function addTerraformResources(graph, scanPath) {
14334
14425
 
14335
14426
  // src/extract/infra/k8s.ts
14336
14427
  import { promises as fs27 } from "fs";
14337
- import path58 from "path";
14428
+ import path59 from "path";
14338
14429
  import { parseAllDocuments as parseAllDocuments2 } from "yaml";
14430
+ import { EdgeType as EdgeType20, serviceId as serviceId13 } from "@neat.is/types";
14339
14431
  var K8S_KIND_TO_INFRA_KIND = {
14340
14432
  Service: "k8s-service",
14341
14433
  Deployment: "k8s-deployment",
@@ -14345,6 +14437,7 @@ var K8S_KIND_TO_INFRA_KIND = {
14345
14437
  Job: "k8s-job",
14346
14438
  Ingress: "k8s-ingress"
14347
14439
  };
14440
+ var WORKLOAD_KINDS = /* @__PURE__ */ new Set(["Deployment", "StatefulSet", "DaemonSet"]);
14348
14441
  async function walkYamlFiles2(start, depth = 0, max = 5) {
14349
14442
  if (depth > max) return [];
14350
14443
  const out = [];
@@ -14352,17 +14445,18 @@ async function walkYamlFiles2(start, depth = 0, max = 5) {
14352
14445
  for (const entry of entries) {
14353
14446
  if (entry.isDirectory()) {
14354
14447
  if (IGNORED_DIRS.has(entry.name)) continue;
14355
- const child = path58.join(start, entry.name);
14448
+ const child = path59.join(start, entry.name);
14356
14449
  if (await isPythonVenvDir(child)) continue;
14357
14450
  out.push(...await walkYamlFiles2(child, depth + 1, max));
14358
- } else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(path58.extname(entry.name))) {
14359
- out.push(path58.join(start, entry.name));
14451
+ } else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(path59.extname(entry.name))) {
14452
+ out.push(path59.join(start, entry.name));
14360
14453
  }
14361
14454
  }
14362
14455
  return out;
14363
14456
  }
14364
14457
  async function addK8sResources(graph, scanPath) {
14365
14458
  let nodesAdded = 0;
14459
+ let edgesAdded = 0;
14366
14460
  const files = await walkYamlFiles2(scanPath);
14367
14461
  for (const file of files) {
14368
14462
  const content = await fs27.readFile(file, "utf8");
@@ -14372,30 +14466,62 @@ async function addK8sResources(graph, scanPath) {
14372
14466
  } catch {
14373
14467
  continue;
14374
14468
  }
14469
+ const relFile = toPosix(path59.relative(scanPath, file));
14375
14470
  for (const doc of docs) {
14376
14471
  if (!doc?.kind || !doc.metadata?.name) continue;
14377
14472
  const infraKind = K8S_KIND_TO_INFRA_KIND[doc.kind];
14378
14473
  if (!infraKind) continue;
14379
- const namespaced = doc.metadata.namespace ? `${doc.metadata.namespace}/${doc.metadata.name}` : doc.metadata.name;
14380
- const node = makeInfraNode(infraKind, namespaced, "kubernetes");
14474
+ const name = doc.metadata.name;
14475
+ const isWorkload = WORKLOAD_KINDS.has(doc.kind);
14476
+ const image = isWorkload ? doc.spec?.template?.spec?.containers?.[0]?.image : void 0;
14477
+ const replicas = isWorkload && typeof doc.spec?.replicas === "number" ? doc.spec.replicas : void 0;
14478
+ const base = makeInfraNode(infraKind, name, "kubernetes");
14479
+ const node = {
14480
+ ...base,
14481
+ ...doc.metadata.namespace ? { namespace: doc.metadata.namespace } : {},
14482
+ ...image ? { image } : {},
14483
+ ...replicas !== void 0 ? { replicas } : {}
14484
+ };
14381
14485
  if (!graph.hasNode(node.id)) {
14382
14486
  graph.addNode(node.id, node);
14383
14487
  nodesAdded++;
14384
14488
  }
14489
+ if (isWorkload) {
14490
+ const svcId = serviceId13(name);
14491
+ if (graph.hasNode(svcId)) {
14492
+ const svc = graph.getNodeAttributes(svcId);
14493
+ graph.replaceNodeAttributes(svcId, {
14494
+ ...svc,
14495
+ platform: svc.platform ?? "kubernetes",
14496
+ ...image ? { declaredImage: image } : {},
14497
+ ...replicas !== void 0 ? { declaredReplicas: replicas } : {}
14498
+ });
14499
+ edgesAdded += emitPlatformResourceEdge(
14500
+ graph,
14501
+ svcId,
14502
+ EdgeType20.RUNS_ON,
14503
+ infraKind,
14504
+ name,
14505
+ "kubernetes",
14506
+ relFile,
14507
+ lineContaining(content, image)
14508
+ ).edgesAdded;
14509
+ }
14510
+ }
14385
14511
  }
14386
14512
  }
14387
- return { nodesAdded, edgesAdded: 0 };
14513
+ return { nodesAdded, edgesAdded };
14388
14514
  }
14389
14515
 
14390
14516
  // src/extract/infra/cloudflare.ts
14391
14517
  import { promises as fs28 } from "fs";
14392
- import path59 from "path";
14518
+ import path60 from "path";
14393
14519
  import { parse as parseToml3 } from "smol-toml";
14394
- import { EdgeType as EdgeType20, Provenance as Provenance21, confidenceForExtracted as confidenceForExtracted18 } from "@neat.is/types";
14520
+ import { EdgeType as EdgeType21, Provenance as Provenance21, confidenceForExtracted as confidenceForExtracted18 } from "@neat.is/types";
14395
14521
  var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
14396
14522
  async function readWranglerConfig(dir) {
14397
14523
  for (const filename of WRANGLER_FILENAMES) {
14398
- const abs = path59.join(dir, filename);
14524
+ const abs = path60.join(dir, filename);
14399
14525
  if (!await exists(abs)) continue;
14400
14526
  const raw = await fs28.readFile(abs, "utf8");
14401
14527
  const config = filename === "wrangler.toml" ? parseToml3(raw) : JSON.parse(maskCommentsInSource(raw));
@@ -14458,11 +14584,11 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14458
14584
  try {
14459
14585
  read = await readWranglerConfig(service.dir);
14460
14586
  } catch (err) {
14461
- recordExtractionError("infra cloudflare", path59.relative(scanPath, service.dir), err);
14587
+ recordExtractionError("infra cloudflare", path60.relative(scanPath, service.dir), err);
14462
14588
  continue;
14463
14589
  }
14464
14590
  if (!read || !read.config.name) continue;
14465
- const evidenceFile = toPosix(path59.relative(scanPath, path59.join(service.dir, read.relFile)));
14591
+ const evidenceFile = toPosix(path60.relative(scanPath, path60.join(service.dir, read.relFile)));
14466
14592
  discovered.push({ service, config: read.config, relFile: read.relFile, raw: read.raw, evidenceFile });
14467
14593
  }
14468
14594
  for (const worker of discovered) {
@@ -14474,7 +14600,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14474
14600
  }
14475
14601
  let anchorId = service.node.id;
14476
14602
  if (config.main) {
14477
- const entryRelPath = toPosix(path59.normalize(config.main));
14603
+ const entryRelPath = toPosix(path60.normalize(config.main));
14478
14604
  const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
14479
14605
  graph,
14480
14606
  service.pkg.name,
@@ -14501,13 +14627,13 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14501
14627
  nodesAdded++;
14502
14628
  }
14503
14629
  if (runtimeNode.id !== anchorId) {
14504
- const runsOnId = extractedEdgeId(anchorId, runtimeNode.id, EdgeType20.RUNS_ON);
14630
+ const runsOnId = extractedEdgeId(anchorId, runtimeNode.id, EdgeType21.RUNS_ON);
14505
14631
  if (!graph.hasEdge(runsOnId)) {
14506
14632
  const edge = {
14507
14633
  id: runsOnId,
14508
14634
  source: anchorId,
14509
14635
  target: runtimeNode.id,
14510
- type: EdgeType20.RUNS_ON,
14636
+ type: EdgeType21.RUNS_ON,
14511
14637
  provenance: Provenance21.EXTRACTED,
14512
14638
  confidence: confidenceForExtracted18("structural"),
14513
14639
  evidence: {
@@ -14523,7 +14649,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14523
14649
  const result = addResourceEdge(
14524
14650
  graph,
14525
14651
  anchorId,
14526
- EdgeType20.CONNECTS_TO,
14652
+ EdgeType21.CONNECTS_TO,
14527
14653
  "cloudflare-route",
14528
14654
  route,
14529
14655
  evidenceFile,
@@ -14547,7 +14673,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14547
14673
  const result = addResourceEdge(
14548
14674
  graph,
14549
14675
  anchorId,
14550
- EdgeType20.DEPENDS_ON,
14676
+ EdgeType21.DEPENDS_ON,
14551
14677
  group.kind,
14552
14678
  name,
14553
14679
  evidenceFile,
@@ -14561,7 +14687,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14561
14687
  const result = addResourceEdge(
14562
14688
  graph,
14563
14689
  anchorId,
14564
- EdgeType20.DEPENDS_ON,
14690
+ EdgeType21.DEPENDS_ON,
14565
14691
  "cloudflare-cron",
14566
14692
  cron,
14567
14693
  evidenceFile,
@@ -14574,7 +14700,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14574
14700
  const result = addResourceEdge(
14575
14701
  graph,
14576
14702
  anchorId,
14577
- EdgeType20.DEPENDS_ON,
14703
+ EdgeType21.DEPENDS_ON,
14578
14704
  "cloudflare-env-var",
14579
14705
  varName,
14580
14706
  evidenceFile,
@@ -14587,13 +14713,13 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14587
14713
  if (!svc.service) continue;
14588
14714
  const target = workerIndex.get(svc.service);
14589
14715
  if (target && target.anchorId !== anchorId) {
14590
- const edgeId = extractedEdgeId(anchorId, target.anchorId, EdgeType20.CALLS);
14716
+ const edgeId = extractedEdgeId(anchorId, target.anchorId, EdgeType21.CALLS);
14591
14717
  if (!graph.hasEdge(edgeId)) {
14592
14718
  const edge = {
14593
14719
  id: edgeId,
14594
14720
  source: anchorId,
14595
14721
  target: target.anchorId,
14596
- type: EdgeType20.CALLS,
14722
+ type: EdgeType21.CALLS,
14597
14723
  provenance: Provenance21.EXTRACTED,
14598
14724
  confidence: confidenceForExtracted18("structural"),
14599
14725
  evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
@@ -14606,7 +14732,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14606
14732
  const result = addResourceEdge(
14607
14733
  graph,
14608
14734
  anchorId,
14609
- EdgeType20.DEPENDS_ON,
14735
+ EdgeType21.DEPENDS_ON,
14610
14736
  "cloudflare-service-binding",
14611
14737
  svc.service,
14612
14738
  evidenceFile,
@@ -14621,12 +14747,12 @@ async function addCloudflareWorkers(graph, services, scanPath) {
14621
14747
 
14622
14748
  // src/extract/infra/vercel.ts
14623
14749
  import { promises as fs29 } from "fs";
14624
- import path60 from "path";
14625
- import { EdgeType as EdgeType21 } from "@neat.is/types";
14750
+ import path61 from "path";
14751
+ import { EdgeType as EdgeType22 } from "@neat.is/types";
14626
14752
  var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
14627
14753
  async function readVercelConfig(dir) {
14628
14754
  for (const filename of VERCEL_CONFIG_FILENAMES) {
14629
- const abs = path60.join(dir, filename);
14755
+ const abs = path61.join(dir, filename);
14630
14756
  if (!await exists(abs)) continue;
14631
14757
  const raw = await fs29.readFile(abs, "utf8");
14632
14758
  const config = JSON.parse(maskCommentsInSource(raw));
@@ -14635,7 +14761,7 @@ async function readVercelConfig(dir) {
14635
14761
  return null;
14636
14762
  }
14637
14763
  async function readLinkedProjectName(dir) {
14638
- const abs = path60.join(dir, ".vercel", "project.json");
14764
+ const abs = path61.join(dir, ".vercel", "project.json");
14639
14765
  if (!await exists(abs)) return void 0;
14640
14766
  const parsed = JSON.parse(await fs29.readFile(abs, "utf8"));
14641
14767
  return typeof parsed.projectName === "string" ? parsed.projectName : void 0;
@@ -14653,7 +14779,7 @@ async function addVercelServices(graph, services, scanPath) {
14653
14779
  read = await readVercelConfig(service.dir);
14654
14780
  projectName = await readLinkedProjectName(service.dir);
14655
14781
  } catch (err) {
14656
- recordExtractionError("infra vercel", path60.relative(scanPath, service.dir), err);
14782
+ recordExtractionError("infra vercel", path61.relative(scanPath, service.dir), err);
14657
14783
  continue;
14658
14784
  }
14659
14785
  if (!read && !projectName) continue;
@@ -14669,7 +14795,7 @@ async function addVercelServices(graph, services, scanPath) {
14669
14795
  const anchorId = service.node.id;
14670
14796
  if (!read) continue;
14671
14797
  const { config, relFile, raw } = read;
14672
- const evidenceFile = toPosix(path60.relative(scanPath, path60.join(service.dir, relFile)));
14798
+ const evidenceFile = toPosix(path61.relative(scanPath, path61.join(service.dir, relFile)));
14673
14799
  const add = (edgeType, kind, name) => {
14674
14800
  if (!name) return;
14675
14801
  const result = emitPlatformResourceEdge(
@@ -14685,12 +14811,12 @@ async function addVercelServices(graph, services, scanPath) {
14685
14811
  nodesAdded += result.nodesAdded;
14686
14812
  edgesAdded += result.edgesAdded;
14687
14813
  };
14688
- add(EdgeType21.RUNS_ON, "vercel", "vercel");
14689
- for (const cron of config.crons ?? []) add(EdgeType21.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
14690
- for (const varName of Object.keys(config.env ?? {})) add(EdgeType21.DEPENDS_ON, "vercel-env-var", varName);
14691
- for (const varName of Object.keys(config.build?.env ?? {})) add(EdgeType21.DEPENDS_ON, "vercel-env-var", varName);
14814
+ add(EdgeType22.RUNS_ON, "vercel", "vercel");
14815
+ for (const cron of config.crons ?? []) add(EdgeType22.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
14816
+ for (const varName of Object.keys(config.env ?? {})) add(EdgeType22.DEPENDS_ON, "vercel-env-var", varName);
14817
+ for (const varName of Object.keys(config.build?.env ?? {})) add(EdgeType22.DEPENDS_ON, "vercel-env-var", varName);
14692
14818
  for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
14693
- add(EdgeType21.CONNECTS_TO, "vercel-route", routeSource(route));
14819
+ add(EdgeType22.CONNECTS_TO, "vercel-route", routeSource(route));
14694
14820
  }
14695
14821
  }
14696
14822
  return { nodesAdded, edgesAdded };
@@ -14698,13 +14824,13 @@ async function addVercelServices(graph, services, scanPath) {
14698
14824
 
14699
14825
  // src/extract/infra/railway.ts
14700
14826
  import { promises as fs30 } from "fs";
14701
- import path61 from "path";
14827
+ import path62 from "path";
14702
14828
  import { parse as parseToml4 } from "smol-toml";
14703
- import { EdgeType as EdgeType22 } from "@neat.is/types";
14829
+ import { EdgeType as EdgeType23 } from "@neat.is/types";
14704
14830
  var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
14705
14831
  async function readRailwayConfig(dir) {
14706
14832
  for (const filename of RAILWAY_FILENAMES) {
14707
- const abs = path61.join(dir, filename);
14833
+ const abs = path62.join(dir, filename);
14708
14834
  if (!await exists(abs)) continue;
14709
14835
  const raw = await fs30.readFile(abs, "utf8");
14710
14836
  const config = filename === "railway.toml" ? parseToml4(raw) : JSON.parse(maskCommentsInSource(raw));
@@ -14720,7 +14846,7 @@ async function addRailwayServices(graph, services, scanPath) {
14720
14846
  try {
14721
14847
  read = await readRailwayConfig(service.dir);
14722
14848
  } catch (err) {
14723
- recordExtractionError("infra railway", path61.relative(scanPath, service.dir), err);
14849
+ recordExtractionError("infra railway", path62.relative(scanPath, service.dir), err);
14724
14850
  continue;
14725
14851
  }
14726
14852
  if (!read) continue;
@@ -14730,7 +14856,7 @@ async function addRailwayServices(graph, services, scanPath) {
14730
14856
  }
14731
14857
  const anchorId = service.node.id;
14732
14858
  const { config, relFile, raw } = read;
14733
- const evidenceFile = toPosix(path61.relative(scanPath, path61.join(service.dir, relFile)));
14859
+ const evidenceFile = toPosix(path62.relative(scanPath, path62.join(service.dir, relFile)));
14734
14860
  const add = (edgeType, kind, name) => {
14735
14861
  if (!name) return;
14736
14862
  const result = emitPlatformResourceEdge(
@@ -14746,21 +14872,21 @@ async function addRailwayServices(graph, services, scanPath) {
14746
14872
  nodesAdded += result.nodesAdded;
14747
14873
  edgesAdded += result.edgesAdded;
14748
14874
  };
14749
- add(EdgeType22.RUNS_ON, "railway", "railway");
14750
- add(EdgeType22.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
14751
- add(EdgeType22.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
14875
+ add(EdgeType23.RUNS_ON, "railway", "railway");
14876
+ add(EdgeType23.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
14877
+ add(EdgeType23.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
14752
14878
  }
14753
14879
  return { nodesAdded, edgesAdded };
14754
14880
  }
14755
14881
 
14756
14882
  // src/extract/infra/supabase.ts
14757
14883
  import { promises as fs31 } from "fs";
14758
- import path62 from "path";
14884
+ import path63 from "path";
14759
14885
  import { parse as parseToml5 } from "smol-toml";
14760
- import { EdgeType as EdgeType23 } from "@neat.is/types";
14886
+ import { EdgeType as EdgeType24 } from "@neat.is/types";
14761
14887
  async function readSupabaseConfig(dir) {
14762
- const relFile = path62.join("supabase", "config.toml");
14763
- const abs = path62.join(dir, relFile);
14888
+ const relFile = path63.join("supabase", "config.toml");
14889
+ const abs = path63.join(dir, relFile);
14764
14890
  if (!await exists(abs)) return null;
14765
14891
  const raw = await fs31.readFile(abs, "utf8");
14766
14892
  const config = parseToml5(raw);
@@ -14774,7 +14900,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
14774
14900
  try {
14775
14901
  read = await readSupabaseConfig(service.dir);
14776
14902
  } catch (err) {
14777
- recordExtractionError("infra supabase", path62.relative(scanPath, service.dir), err);
14903
+ recordExtractionError("infra supabase", path63.relative(scanPath, service.dir), err);
14778
14904
  continue;
14779
14905
  }
14780
14906
  if (!read) continue;
@@ -14789,7 +14915,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
14789
14915
  });
14790
14916
  }
14791
14917
  const anchorId = service.node.id;
14792
- const evidenceFile = toPosix(path62.relative(scanPath, path62.join(service.dir, relFile)));
14918
+ const evidenceFile = toPosix(path63.relative(scanPath, path63.join(service.dir, relFile)));
14793
14919
  const add = (edgeType, kind, name) => {
14794
14920
  if (!name) return;
14795
14921
  const result = emitPlatformResourceEdge(
@@ -14805,10 +14931,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
14805
14931
  nodesAdded += result.nodesAdded;
14806
14932
  edgesAdded += result.edgesAdded;
14807
14933
  };
14808
- add(EdgeType23.RUNS_ON, "supabase", "supabase");
14809
- for (const fn of Object.keys(config.functions ?? {})) add(EdgeType23.DEPENDS_ON, "supabase-function", fn);
14810
- if (config.storage) add(EdgeType23.DEPENDS_ON, "supabase-storage", "storage");
14811
- if (config.auth) add(EdgeType23.DEPENDS_ON, "supabase-auth", "auth");
14934
+ add(EdgeType24.RUNS_ON, "supabase", "supabase");
14935
+ for (const fn of Object.keys(config.functions ?? {})) add(EdgeType24.DEPENDS_ON, "supabase-function", fn);
14936
+ if (config.storage) add(EdgeType24.DEPENDS_ON, "supabase-storage", "storage");
14937
+ if (config.auth) add(EdgeType24.DEPENDS_ON, "supabase-auth", "auth");
14812
14938
  }
14813
14939
  return { nodesAdded, edgesAdded };
14814
14940
  }
@@ -14830,25 +14956,25 @@ async function addInfra(graph, scanPath, services) {
14830
14956
  }
14831
14957
 
14832
14958
  // src/extract/zod-shapes.ts
14833
- import path63 from "path";
14834
- import Parser17 from "tree-sitter";
14959
+ import path64 from "path";
14960
+ import Parser18 from "tree-sitter";
14835
14961
  import JavaScript8 from "tree-sitter-javascript";
14836
14962
  import {
14837
- EdgeType as EdgeType24,
14963
+ EdgeType as EdgeType25,
14838
14964
  NodeType as NodeType27,
14839
14965
  Provenance as Provenance22,
14840
14966
  confidenceForExtracted as confidenceForExtracted19,
14841
14967
  extractedEdgeId as extractedEdgeId11,
14842
- infraId as infraId20
14968
+ infraId as infraId21
14843
14969
  } from "@neat.is/types";
14844
14970
  var ZOD_IMPORT_RE = /\bzod\b/;
14845
14971
  var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
14846
14972
  function parserForExt4(ext) {
14847
- const p = new Parser17();
14973
+ const p = new Parser18();
14848
14974
  p.setLanguage(GRAMMAR_BY_EXT[ext] ?? JavaScript8);
14849
14975
  return p;
14850
14976
  }
14851
- function namedChildren5(node) {
14977
+ function namedChildren6(node) {
14852
14978
  const out = [];
14853
14979
  for (let i = 0; i < node.namedChildCount; i++) {
14854
14980
  const c = node.namedChild(i);
@@ -14858,7 +14984,7 @@ function namedChildren5(node) {
14858
14984
  }
14859
14985
  function stringLiteralText5(node) {
14860
14986
  if (!node || node.type !== "string") return null;
14861
- for (const child of namedChildren5(node)) {
14987
+ for (const child of namedChildren6(node)) {
14862
14988
  if (child.type === "string_fragment") return child.text;
14863
14989
  }
14864
14990
  return "";
@@ -14883,12 +15009,12 @@ function zodCallKind(call) {
14883
15009
  function firstArg(call) {
14884
15010
  const args = call.childForFieldName("arguments");
14885
15011
  if (!args) return null;
14886
- return namedChildren5(args)[0] ?? null;
15012
+ return namedChildren6(args)[0] ?? null;
14887
15013
  }
14888
15014
  function fieldsFromObject(obj) {
14889
15015
  const out = [];
14890
15016
  const seen = /* @__PURE__ */ new Set();
14891
- for (const child of namedChildren5(obj)) {
15017
+ for (const child of namedChildren6(obj)) {
14892
15018
  if (child.type === "spread_element") return null;
14893
15019
  if (child.type !== "pair") continue;
14894
15020
  const key = child.childForFieldName("key");
@@ -14904,7 +15030,7 @@ function fieldsFromObject(obj) {
14904
15030
  function membersFromEnum(arr) {
14905
15031
  const out = [];
14906
15032
  const seen = /* @__PURE__ */ new Set();
14907
- for (const child of namedChildren5(arr)) {
15033
+ for (const child of namedChildren6(arr)) {
14908
15034
  if (child.type !== "string") return null;
14909
15035
  const value = stringLiteralText5(child);
14910
15036
  if (value !== null && value !== "" && !seen.has(value)) {
@@ -14916,10 +15042,10 @@ function membersFromEnum(arr) {
14916
15042
  }
14917
15043
  function topLevelSchemas(root) {
14918
15044
  const out = [];
14919
- for (const stmt of namedChildren5(root)) {
15045
+ for (const stmt of namedChildren6(root)) {
14920
15046
  const decl = stmt.type === "export_statement" ? stmt.childForFieldName("declaration") : stmt;
14921
15047
  if (decl?.type !== "lexical_declaration" && decl?.type !== "variable_declaration") continue;
14922
- for (const declarator of namedChildren5(decl)) {
15048
+ for (const declarator of namedChildren6(decl)) {
14923
15049
  if (declarator.type !== "variable_declarator") continue;
14924
15050
  const name = declarator.childForFieldName("name");
14925
15051
  const value = declarator.childForFieldName("value");
@@ -14932,7 +15058,7 @@ function topLevelSchemas(root) {
14932
15058
  }
14933
15059
  function zodShapesFromFile(file, serviceDir) {
14934
15060
  if (!ZOD_IMPORT_RE.test(file.content)) return [];
14935
- const tree = parseSource3(parserForExt4(path63.extname(file.path)), file.content);
15061
+ const tree = parseSource3(parserForExt4(path64.extname(file.path)), file.content);
14936
15062
  const out = [];
14937
15063
  const seen = /* @__PURE__ */ new Set();
14938
15064
  for (const { name, call } of topLevelSchemas(tree.rootNode)) {
@@ -14946,11 +15072,11 @@ function zodShapesFromFile(file, serviceDir) {
14946
15072
  seen.add(name);
14947
15073
  const line = call.startPosition.row + 1;
14948
15074
  out.push({
14949
- infraId: infraId20("zod-schema", name),
15075
+ infraId: infraId21("zod-schema", name),
14950
15076
  name,
14951
15077
  fields,
14952
15078
  evidence: {
14953
- file: path63.relative(serviceDir, file.path),
15079
+ file: path64.relative(serviceDir, file.path),
14954
15080
  line,
14955
15081
  snippet: snippet(file.content, line)
14956
15082
  }
@@ -15012,13 +15138,13 @@ async function addZodShapes(graph, services) {
15012
15138
  );
15013
15139
  nodesAdded += n;
15014
15140
  edgesAdded += e;
15015
- const edgeId = extractedEdgeId11(fileNodeId, shape.infraId, EdgeType24.CONTAINS);
15141
+ const edgeId = extractedEdgeId11(fileNodeId, shape.infraId, EdgeType25.CONTAINS);
15016
15142
  if (!graph.hasEdge(edgeId)) {
15017
15143
  const edge = {
15018
15144
  id: edgeId,
15019
15145
  source: fileNodeId,
15020
15146
  target: shape.infraId,
15021
- type: EdgeType24.CONTAINS,
15147
+ type: EdgeType25.CONTAINS,
15022
15148
  provenance: Provenance22.EXTRACTED,
15023
15149
  confidence: confidenceForExtracted19("structural"),
15024
15150
  evidence: shape.evidence
@@ -15186,11 +15312,11 @@ async function addFirestoreRules(graph, services) {
15186
15312
  }
15187
15313
 
15188
15314
  // src/extract/index.ts
15189
- import path65 from "path";
15315
+ import path66 from "path";
15190
15316
 
15191
15317
  // src/extract/retire.ts
15192
15318
  import { existsSync as existsSync2 } from "fs";
15193
- import path64 from "path";
15319
+ import path65 from "path";
15194
15320
  import { NodeType as NodeType29, Provenance as Provenance23 } from "@neat.is/types";
15195
15321
  function dropOrphanedFileNodes(graph) {
15196
15322
  const orphans = [];
@@ -15224,11 +15350,11 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
15224
15350
  if (edge.provenance !== Provenance23.EXTRACTED) return;
15225
15351
  const evidenceFile = edge.evidence?.file;
15226
15352
  if (!evidenceFile) return;
15227
- if (path64.isAbsolute(evidenceFile)) {
15353
+ if (path65.isAbsolute(evidenceFile)) {
15228
15354
  if (!existsSync2(evidenceFile)) toDrop.push(id);
15229
15355
  return;
15230
15356
  }
15231
- const found = bases.some((base) => existsSync2(path64.join(base, evidenceFile)));
15357
+ const found = bases.some((base) => existsSync2(path65.join(base, evidenceFile)));
15232
15358
  if (!found) toDrop.push(id);
15233
15359
  });
15234
15360
  for (const id of toDrop) graph.dropEdge(id);
@@ -15285,7 +15411,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
15285
15411
  }
15286
15412
  const droppedEntries = drainDroppedExtracted();
15287
15413
  if (isRejectedLogEnabled() && opts.errorsPath && droppedEntries.length > 0) {
15288
- const rejectedPath = path65.join(path65.dirname(opts.errorsPath), "rejected.ndjson");
15414
+ const rejectedPath = path66.join(path66.dirname(opts.errorsPath), "rejected.ndjson");
15289
15415
  try {
15290
15416
  await writeRejectedExtracted(droppedEntries, rejectedPath);
15291
15417
  } catch (err) {
@@ -15321,24 +15447,24 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
15321
15447
  import {
15322
15448
  databaseId as databaseId3,
15323
15449
  DivergenceResultSchema,
15324
- EdgeType as EdgeType25,
15450
+ EdgeType as EdgeType26,
15325
15451
  NodeType as NodeType30,
15326
15452
  parseEdgeId,
15327
15453
  parseFileId,
15328
15454
  parseSymbolId as parseSymbolId2,
15329
15455
  Provenance as Provenance24,
15330
- serviceId as serviceId13
15456
+ serviceId as serviceId14
15331
15457
  } from "@neat.is/types";
15332
15458
  function bucketKey(source, target, type) {
15333
15459
  return `${type}|${source}|${target}`;
15334
15460
  }
15335
15461
  function bucketSourceFor(graph, edge) {
15336
- if (edge.type !== EdgeType25.CONNECTS_TO) return edge.source;
15462
+ if (edge.type !== EdgeType26.CONNECTS_TO) return edge.source;
15337
15463
  const parsed = parseFileId(edge.source);
15338
15464
  if (!parsed || !graph.hasNode(edge.target)) return edge.source;
15339
15465
  const target = graph.getNodeAttributes(edge.target);
15340
15466
  if (target.type !== NodeType30.DatabaseNode) return edge.source;
15341
- return serviceId13(parsed.service);
15467
+ return serviceId14(parsed.service);
15342
15468
  }
15343
15469
  function bucketEdges(graph) {
15344
15470
  const buckets2 = /* @__PURE__ */ new Map();
@@ -15404,14 +15530,14 @@ function gradedConfidence(edge) {
15404
15530
  return clampConfidence(confidenceForEdge(edge));
15405
15531
  }
15406
15532
  var OBSERVABLE_EDGE_TYPES = /* @__PURE__ */ new Set([
15407
- EdgeType25.CALLS,
15408
- EdgeType25.CONNECTS_TO,
15409
- EdgeType25.PUBLISHES_TO,
15410
- EdgeType25.CONSUMES_FROM
15533
+ EdgeType26.CALLS,
15534
+ EdgeType26.CONNECTS_TO,
15535
+ EdgeType26.PUBLISHES_TO,
15536
+ EdgeType26.CONSUMES_FROM
15411
15537
  ]);
15412
15538
  function detectMissingDivergences(graph, bucket) {
15413
15539
  const out = [];
15414
- if (bucket.type === EdgeType25.CONTAINS) return out;
15540
+ if (bucket.type === EdgeType26.CONTAINS) return out;
15415
15541
  if (nodeIsSymbol(graph, bucket.source) || nodeIsSymbol(graph, bucket.target)) return out;
15416
15542
  if (bucket.extracted && !bucket.observed && OBSERVABLE_EDGE_TYPES.has(bucket.type)) {
15417
15543
  if (!nodeIsFrontier(graph, bucket.target) && !nodeIsServerAction(graph, bucket.target)) {
@@ -15453,7 +15579,7 @@ function declaredHostFor(svc) {
15453
15579
  function hasExtractedConfiguredBy(graph, svcId) {
15454
15580
  for (const edgeId of graph.outboundEdges(svcId)) {
15455
15581
  const e = graph.getEdgeAttributes(edgeId);
15456
- if (e.type === EdgeType25.CONFIGURED_BY && e.provenance === Provenance24.EXTRACTED) {
15582
+ if (e.type === EdgeType26.CONFIGURED_BY && e.provenance === Provenance24.EXTRACTED) {
15457
15583
  return true;
15458
15584
  }
15459
15585
  }
@@ -15466,7 +15592,7 @@ function detectHostMismatch(graph, svcId, svc) {
15466
15592
  const out = [];
15467
15593
  for (const edgeId of graph.outboundEdges(svcId)) {
15468
15594
  const edge = graph.getEdgeAttributes(edgeId);
15469
- if (edge.type !== EdgeType25.CONNECTS_TO) continue;
15595
+ if (edge.type !== EdgeType26.CONNECTS_TO) continue;
15470
15596
  if (edge.provenance !== Provenance24.OBSERVED) continue;
15471
15597
  const target = graph.getNodeAttributes(edge.target);
15472
15598
  if (target.type !== NodeType30.DatabaseNode) continue;
@@ -15491,7 +15617,7 @@ function detectCompatDivergences(graph, svcId, svc) {
15491
15617
  const deps = svc.dependencies ?? {};
15492
15618
  for (const edgeId of graph.outboundEdges(svcId)) {
15493
15619
  const edge = graph.getEdgeAttributes(edgeId);
15494
- if (edge.type !== EdgeType25.CONNECTS_TO) continue;
15620
+ if (edge.type !== EdgeType26.CONNECTS_TO) continue;
15495
15621
  if (edge.provenance !== Provenance24.OBSERVED) continue;
15496
15622
  const target = graph.getNodeAttributes(edge.target);
15497
15623
  if (target.type !== NodeType30.DatabaseNode) continue;
@@ -15642,7 +15768,7 @@ function symbolLocus(graph, ev) {
15642
15768
  if (affectedIsCode) return { node: affected, ...location ? { location } : {} };
15643
15769
  if (!location) return null;
15644
15770
  if (affectedInGraph) return { node: affected, location };
15645
- const svc = serviceId13(ev.service);
15771
+ const svc = serviceId14(ev.service);
15646
15772
  if (graph.hasNode(svc)) return { node: svc, location };
15647
15773
  return null;
15648
15774
  }
@@ -15845,10 +15971,10 @@ function datastoreEverObserved(graph, nodeId) {
15845
15971
  }
15846
15972
  return false;
15847
15973
  }
15848
- function serviceHasObservedSameEngineStore(graph, buckets2, serviceId16, engine, excludeTarget) {
15974
+ function serviceHasObservedSameEngineStore(graph, buckets2, serviceId17, engine, excludeTarget) {
15849
15975
  for (const bucket of buckets2.values()) {
15850
- if (bucket.type !== EdgeType25.CONNECTS_TO) continue;
15851
- if (bucket.source !== serviceId16) continue;
15976
+ if (bucket.type !== EdgeType26.CONNECTS_TO) continue;
15977
+ if (bucket.source !== serviceId17) continue;
15852
15978
  if (bucket.target === excludeTarget) continue;
15853
15979
  if (!graph.hasNode(bucket.target)) continue;
15854
15980
  const target = graph.getNodeAttributes(bucket.target);
@@ -15862,7 +15988,7 @@ var DEAD_CODE_PROBE_CONFIDENCE = 0.1;
15862
15988
  function dampenDeadCodeProbes(graph, buckets2, all) {
15863
15989
  return all.map((d) => {
15864
15990
  if (d.type !== "missing-observed") return d;
15865
- if (!d.extracted || d.edgeType !== EdgeType25.CONNECTS_TO) return d;
15991
+ if (!d.extracted || d.edgeType !== EdgeType26.CONNECTS_TO) return d;
15866
15992
  if (!graph.hasNode(d.target)) return d;
15867
15993
  const target = graph.getNodeAttributes(d.target);
15868
15994
  if (target.type !== NodeType30.DatabaseNode) return d;
@@ -15980,7 +16106,7 @@ function computeDivergences(graph, opts = {}) {
15980
16106
 
15981
16107
  // src/persist.ts
15982
16108
  import { promises as fs32 } from "fs";
15983
- import path66 from "path";
16109
+ import path67 from "path";
15984
16110
  import { NodeType as NodeType31, Provenance as Provenance25, observedEdgeId as observedEdgeId2 } from "@neat.is/types";
15985
16111
  var SCHEMA_VERSION = 7;
15986
16112
  function migrateV1ToV2(payload) {
@@ -16035,7 +16161,7 @@ function migrateV2ToV3(payload) {
16035
16161
  return { ...payload, schemaVersion: 3 };
16036
16162
  }
16037
16163
  async function ensureDir(filePath) {
16038
- await fs32.mkdir(path66.dirname(filePath), { recursive: true });
16164
+ await fs32.mkdir(path67.dirname(filePath), { recursive: true });
16039
16165
  }
16040
16166
  async function saveGraphToDisk(graph, outPath) {
16041
16167
  await ensureDir(outPath);
@@ -16200,23 +16326,23 @@ function canonicalJson(value) {
16200
16326
  }
16201
16327
 
16202
16328
  // src/projects.ts
16203
- import path67 from "path";
16329
+ import path68 from "path";
16204
16330
  function pathsForProject(project, baseDir) {
16205
16331
  if (project === DEFAULT_PROJECT) {
16206
16332
  return {
16207
- snapshotPath: path67.join(baseDir, "graph.json"),
16208
- errorsPath: path67.join(baseDir, "errors.ndjson"),
16209
- staleEventsPath: path67.join(baseDir, "stale-events.ndjson"),
16210
- embeddingsCachePath: path67.join(baseDir, "embeddings.json"),
16211
- policyViolationsPath: path67.join(baseDir, "policy-violations.ndjson")
16333
+ snapshotPath: path68.join(baseDir, "graph.json"),
16334
+ errorsPath: path68.join(baseDir, "errors.ndjson"),
16335
+ staleEventsPath: path68.join(baseDir, "stale-events.ndjson"),
16336
+ embeddingsCachePath: path68.join(baseDir, "embeddings.json"),
16337
+ policyViolationsPath: path68.join(baseDir, "policy-violations.ndjson")
16212
16338
  };
16213
16339
  }
16214
16340
  return {
16215
- snapshotPath: path67.join(baseDir, `${project}.json`),
16216
- errorsPath: path67.join(baseDir, `errors.${project}.ndjson`),
16217
- staleEventsPath: path67.join(baseDir, `stale-events.${project}.ndjson`),
16218
- embeddingsCachePath: path67.join(baseDir, `embeddings.${project}.json`),
16219
- policyViolationsPath: path67.join(baseDir, `policy-violations.${project}.ndjson`)
16341
+ snapshotPath: path68.join(baseDir, `${project}.json`),
16342
+ errorsPath: path68.join(baseDir, `errors.${project}.ndjson`),
16343
+ staleEventsPath: path68.join(baseDir, `stale-events.${project}.ndjson`),
16344
+ embeddingsCachePath: path68.join(baseDir, `embeddings.${project}.json`),
16345
+ policyViolationsPath: path68.join(baseDir, `policy-violations.${project}.ndjson`)
16220
16346
  };
16221
16347
  }
16222
16348
  var Projects = class {
@@ -16257,7 +16383,7 @@ function parseExtraProjects(raw) {
16257
16383
  // src/registry.ts
16258
16384
  import { promises as fs34 } from "fs";
16259
16385
  import os2 from "os";
16260
- import path68 from "path";
16386
+ import path69 from "path";
16261
16387
  import {
16262
16388
  RegistryFileSchema
16263
16389
  } from "@neat.is/types";
@@ -16265,20 +16391,20 @@ var LOCK_TIMEOUT_MS = 5e3;
16265
16391
  var LOCK_RETRY_MS = 50;
16266
16392
  function neatHome() {
16267
16393
  const override = process.env.NEAT_HOME;
16268
- if (override && override.length > 0) return path68.resolve(override);
16269
- return path68.join(os2.homedir(), ".neat");
16394
+ if (override && override.length > 0) return path69.resolve(override);
16395
+ return path69.join(os2.homedir(), ".neat");
16270
16396
  }
16271
16397
  function registryPath() {
16272
- return path68.join(neatHome(), "projects.json");
16398
+ return path69.join(neatHome(), "projects.json");
16273
16399
  }
16274
16400
  function registryLockPath() {
16275
- return path68.join(neatHome(), "projects.json.lock");
16401
+ return path69.join(neatHome(), "projects.json.lock");
16276
16402
  }
16277
16403
  function daemonPidPath() {
16278
- return path68.join(neatHome(), "neatd.pid");
16404
+ return path69.join(neatHome(), "neatd.pid");
16279
16405
  }
16280
16406
  function daemonsDir() {
16281
- return path68.join(neatHome(), "daemons");
16407
+ return path69.join(neatHome(), "daemons");
16282
16408
  }
16283
16409
  function isFiniteInt(v) {
16284
16410
  return typeof v === "number" && Number.isFinite(v);
@@ -16319,7 +16445,7 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
16319
16445
  const out = [];
16320
16446
  for (const name of names) {
16321
16447
  if (!name.endsWith(".json")) continue;
16322
- const file = path68.join(dir, name);
16448
+ const file = path69.join(dir, name);
16323
16449
  let raw;
16324
16450
  try {
16325
16451
  raw = await fs34.readFile(file, "utf8");
@@ -16440,7 +16566,7 @@ function lockHolderMessage(holder, lockPath, timeoutMs) {
16440
16566
  }
16441
16567
  }
16442
16568
  async function normalizeProjectPath(input) {
16443
- const resolved = path68.resolve(input);
16569
+ const resolved = path69.resolve(input);
16444
16570
  try {
16445
16571
  return await fs34.realpath(resolved);
16446
16572
  } catch {
@@ -16448,7 +16574,7 @@ async function normalizeProjectPath(input) {
16448
16574
  }
16449
16575
  }
16450
16576
  async function writeAtomically(target, contents) {
16451
- await fs34.mkdir(path68.dirname(target), { recursive: true });
16577
+ await fs34.mkdir(path69.dirname(target), { recursive: true });
16452
16578
  const tmp = `${target}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
16453
16579
  const fd = await fs34.open(tmp, "w");
16454
16580
  try {
@@ -16461,7 +16587,7 @@ async function writeAtomically(target, contents) {
16461
16587
  }
16462
16588
  async function acquireLock(lockPath, timeoutMs = LOCK_TIMEOUT_MS, probe = defaultLockHolderProbe) {
16463
16589
  const deadline = Date.now() + timeoutMs;
16464
- await fs34.mkdir(path68.dirname(lockPath), { recursive: true });
16590
+ await fs34.mkdir(path69.dirname(lockPath), { recursive: true });
16465
16591
  let probedHolder = false;
16466
16592
  while (true) {
16467
16593
  try {
@@ -16657,13 +16783,13 @@ import { DivergenceTypeSchema, PoliciesCheckBodySchema, PolicySeveritySchema } f
16657
16783
 
16658
16784
  // src/extend/index.ts
16659
16785
  import { promises as fs36 } from "fs";
16660
- import path70 from "path";
16786
+ import path71 from "path";
16661
16787
  import os3 from "os";
16662
16788
  import { resolve as registryResolve, list as registryList } from "@neat.is/instrumentation-registry";
16663
16789
 
16664
16790
  // src/installers/package-manager.ts
16665
16791
  import { promises as fs35 } from "fs";
16666
- import path69 from "path";
16792
+ import path70 from "path";
16667
16793
  import { spawn } from "child_process";
16668
16794
  var LOCKFILE_PRIORITY = [
16669
16795
  { lockfile: "bun.lockb", pm: "bun", args: ["install", "--no-summary"] },
@@ -16685,22 +16811,22 @@ async function exists2(p) {
16685
16811
  }
16686
16812
  }
16687
16813
  async function detectPackageManager(serviceDir) {
16688
- let dir = path69.resolve(serviceDir);
16814
+ let dir = path70.resolve(serviceDir);
16689
16815
  const stops = /* @__PURE__ */ new Set();
16690
16816
  for (let i = 0; i < 64; i++) {
16691
16817
  if (stops.has(dir)) break;
16692
16818
  stops.add(dir);
16693
16819
  for (const candidate of LOCKFILE_PRIORITY) {
16694
- const lockPath = path69.join(dir, candidate.lockfile);
16820
+ const lockPath = path70.join(dir, candidate.lockfile);
16695
16821
  if (await exists2(lockPath)) {
16696
16822
  return { pm: candidate.pm, cwd: dir, args: [...candidate.args] };
16697
16823
  }
16698
16824
  }
16699
- const parent = path69.dirname(dir);
16825
+ const parent = path70.dirname(dir);
16700
16826
  if (parent === dir) break;
16701
16827
  dir = parent;
16702
16828
  }
16703
- return { pm: "npm", cwd: path69.resolve(serviceDir), args: [...NPM_FALLBACK_ARGS] };
16829
+ return { pm: "npm", cwd: path70.resolve(serviceDir), args: [...NPM_FALLBACK_ARGS] };
16704
16830
  }
16705
16831
  async function runPackageManagerInstall(cmd) {
16706
16832
  return new Promise((resolve) => {
@@ -16749,7 +16875,7 @@ async function fileExists2(p) {
16749
16875
  }
16750
16876
  }
16751
16877
  async function readPackageJson(scanPath) {
16752
- const pkgPath = path70.join(scanPath, "package.json");
16878
+ const pkgPath = path71.join(scanPath, "package.json");
16753
16879
  const raw = await fs36.readFile(pkgPath, "utf8");
16754
16880
  return JSON.parse(raw);
16755
16881
  }
@@ -16763,27 +16889,27 @@ var HOOK_WALK_SKIP_DIRS = /* @__PURE__ */ new Set([
16763
16889
  ]);
16764
16890
  async function findHookFiles(scanPath) {
16765
16891
  const found = [];
16766
- const walk10 = async (dir) => {
16892
+ const walk11 = async (dir) => {
16767
16893
  const entries = await fs36.readdir(dir, { withFileTypes: true }).catch(() => []);
16768
16894
  for (const entry of entries) {
16769
16895
  if (entry.isDirectory()) {
16770
16896
  if (entry.name.startsWith(".") || HOOK_WALK_SKIP_DIRS.has(entry.name)) continue;
16771
- await walk10(path70.join(dir, entry.name));
16897
+ await walk11(path71.join(dir, entry.name));
16772
16898
  } else if (entry.isFile()) {
16773
16899
  if ((entry.name.startsWith("instrumentation") || entry.name.startsWith("otel-init")) && /\.(ts|js|cjs|mjs)$/.test(entry.name)) {
16774
- const rel = path70.relative(scanPath, path70.join(dir, entry.name));
16775
- found.push(rel.split(path70.sep).join("/"));
16900
+ const rel = path71.relative(scanPath, path71.join(dir, entry.name));
16901
+ found.push(rel.split(path71.sep).join("/"));
16776
16902
  }
16777
16903
  }
16778
16904
  }
16779
16905
  };
16780
- await walk10(scanPath);
16906
+ await walk11(scanPath);
16781
16907
  return found.sort();
16782
16908
  }
16783
16909
  async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
16784
16910
  let fallback = null;
16785
16911
  for (const file of hookFiles) {
16786
- const content = await fs36.readFile(path70.join(scanPath, file), "utf8");
16912
+ const content = await fs36.readFile(path71.join(scanPath, file), "utf8");
16787
16913
  const patched = splicedContent(content, snippet2);
16788
16914
  if (patched !== null) return { file, content, patched };
16789
16915
  if (fallback === null) fallback = { file, content };
@@ -16791,11 +16917,11 @@ async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
16791
16917
  return { file: fallback.file, content: fallback.content, patched: null };
16792
16918
  }
16793
16919
  function extendLogPath() {
16794
- return process.env.NEAT_EXTEND_LOG ?? path70.join(os3.homedir(), ".neat", "extend-log.ndjson");
16920
+ return process.env.NEAT_EXTEND_LOG ?? path71.join(os3.homedir(), ".neat", "extend-log.ndjson");
16795
16921
  }
16796
16922
  async function appendExtendLog(entry) {
16797
16923
  const logPath = extendLogPath();
16798
- await fs36.mkdir(path70.dirname(logPath), { recursive: true });
16924
+ await fs36.mkdir(path71.dirname(logPath), { recursive: true });
16799
16925
  await fs36.appendFile(logPath, JSON.stringify(entry) + "\n", "utf8");
16800
16926
  }
16801
16927
  function splicedContent(fileContent, snippet2) {
@@ -16854,7 +16980,7 @@ function lookupInstrumentation(library, installedVersion) {
16854
16980
  }
16855
16981
  async function describeProjectInstrumentation(ctx) {
16856
16982
  const hookFiles = await findHookFiles(ctx.scanPath);
16857
- const envNeat = await fileExists2(path70.join(ctx.scanPath, ".env.neat"));
16983
+ const envNeat = await fileExists2(path71.join(ctx.scanPath, ".env.neat"));
16858
16984
  const registryInstrPackages = new Set(
16859
16985
  registryList().map((e) => e.instrumentation_package).filter((p) => !!p)
16860
16986
  );
@@ -16876,7 +17002,7 @@ async function applyExtension(ctx, args, options) {
16876
17002
  );
16877
17003
  }
16878
17004
  for (const file of hookFiles) {
16879
- const content = await fs36.readFile(path70.join(ctx.scanPath, file), "utf8");
17005
+ const content = await fs36.readFile(path71.join(ctx.scanPath, file), "utf8");
16880
17006
  if (content.includes(args.registration_snippet)) {
16881
17007
  return { library: args.library, filesTouched: [], depsAdded: [], installOutput: "", alreadyApplied: true };
16882
17008
  }
@@ -16888,10 +17014,10 @@ async function applyExtension(ctx, args, options) {
16888
17014
  );
16889
17015
  }
16890
17016
  const primaryFile = primary.file;
16891
- const primaryPath = path70.join(ctx.scanPath, primaryFile);
17017
+ const primaryPath = path71.join(ctx.scanPath, primaryFile);
16892
17018
  const filesTouched = [];
16893
17019
  const depsAdded = [];
16894
- const pkgPath = path70.join(ctx.scanPath, "package.json");
17020
+ const pkgPath = path71.join(ctx.scanPath, "package.json");
16895
17021
  const pkg = await readPackageJson(ctx.scanPath);
16896
17022
  if (!(pkg.dependencies ?? {})[args.instrumentation_package]) {
16897
17023
  pkg.dependencies = { ...pkg.dependencies ?? {}, [args.instrumentation_package]: args.version };
@@ -16930,7 +17056,7 @@ async function dryRunExtension(ctx, args) {
16930
17056
  };
16931
17057
  }
16932
17058
  for (const file of hookFiles) {
16933
- const content = await fs36.readFile(path70.join(ctx.scanPath, file), "utf8");
17059
+ const content = await fs36.readFile(path71.join(ctx.scanPath, file), "utf8");
16934
17060
  if (content.includes(args.registration_snippet)) {
16935
17061
  return {
16936
17062
  library: args.library,
@@ -16971,7 +17097,7 @@ async function rollbackExtension(ctx, args) {
16971
17097
  if (!match) {
16972
17098
  return { undone: false, message: "no apply found for library" };
16973
17099
  }
16974
- const pkgPath = path70.join(ctx.scanPath, "package.json");
17100
+ const pkgPath = path71.join(ctx.scanPath, "package.json");
16975
17101
  if (await fileExists2(pkgPath)) {
16976
17102
  const pkg = await readPackageJson(ctx.scanPath);
16977
17103
  if (pkg.dependencies?.[match.instrumentation_package]) {
@@ -16982,7 +17108,7 @@ async function rollbackExtension(ctx, args) {
16982
17108
  }
16983
17109
  const hookFiles = await findHookFiles(ctx.scanPath);
16984
17110
  for (const file of hookFiles) {
16985
- const filePath = path70.join(ctx.scanPath, file);
17111
+ const filePath = path71.join(ctx.scanPath, file);
16986
17112
  const content = await fs36.readFile(filePath, "utf8");
16987
17113
  if (content.includes(match.registration_snippet)) {
16988
17114
  const filtered = content.split("\n").filter((line) => !line.includes(match.registration_snippet)).join("\n");
@@ -17195,7 +17321,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
17195
17321
  }
17196
17322
 
17197
17323
  // src/ask.ts
17198
- import { AskResultSchema, NodeType as NodeType32, Provenance as Provenance27, serviceId as serviceId14 } from "@neat.is/types";
17324
+ import { AskResultSchema, NodeType as NodeType32, Provenance as Provenance27, serviceId as serviceId15 } from "@neat.is/types";
17199
17325
  var DEFAULT_MAX_NODES = 3;
17200
17326
  var MAX_FACTS_PER_SECTION = 6;
17201
17327
  var INTENT_RULES = [
@@ -17618,7 +17744,7 @@ function buildGlobalIncidentsSection(incidents) {
17618
17744
  }
17619
17745
  const byKey = /* @__PURE__ */ new Map();
17620
17746
  for (const ev of incidents) {
17621
- const key = ev.affectedNode || serviceId14(ev.service);
17747
+ const key = ev.affectedNode || serviceId15(ev.service);
17622
17748
  const cur = byKey.get(key);
17623
17749
  if (!cur) {
17624
17750
  byKey.set(key, { key, count: 1, latest: ev.timestamp, sampleMsg: ev.errorMessage });
@@ -17678,7 +17804,7 @@ function buildOverviewSections(graph, incidents) {
17678
17804
  if (incidents && incidents.length > 0) {
17679
17805
  const incCount = /* @__PURE__ */ new Map();
17680
17806
  for (const ev of incidents) {
17681
- const key = ev.affectedNode || serviceId14(ev.service);
17807
+ const key = ev.affectedNode || serviceId15(ev.service);
17682
17808
  incCount.set(key, (incCount.get(key) ?? 0) + 1);
17683
17809
  }
17684
17810
  const top = [...incCount.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_FACTS_PER_SECTION);
@@ -17892,7 +18018,7 @@ data: ${JSON.stringify(envelope.payload)}
17892
18018
 
17893
18019
  // src/connectors-config.ts
17894
18020
  import os4 from "os";
17895
- import path71 from "path";
18021
+ import path72 from "path";
17896
18022
  import { promises as fs37 } from "fs";
17897
18023
  var CONNECTORS_CONFIG_VERSION = 1;
17898
18024
  var EnvRefUnsetError = class extends Error {
@@ -17907,11 +18033,11 @@ var EnvRefUnsetError = class extends Error {
17907
18033
  };
17908
18034
  function neatHome2() {
17909
18035
  const override = process.env.NEAT_HOME;
17910
- if (override && override.length > 0) return path71.resolve(override);
17911
- return path71.join(os4.homedir(), ".neat");
18036
+ if (override && override.length > 0) return path72.resolve(override);
18037
+ return path72.join(os4.homedir(), ".neat");
17912
18038
  }
17913
18039
  function connectorsConfigPath(home = neatHome2()) {
17914
- return path71.join(home, "connectors.json");
18040
+ return path72.join(home, "connectors.json");
17915
18041
  }
17916
18042
  var MODE_MASK_LOOSER_THAN_0600 = 63;
17917
18043
  async function warnIfModeLooserThan0600(file) {
@@ -18042,7 +18168,7 @@ function connectorMatchesProject(entry, project) {
18042
18168
  var CONNECTORS_LOCK_TIMEOUT_MS = 5e3;
18043
18169
  var CONNECTORS_LOCK_RETRY_MS = 50;
18044
18170
  function connectorsConfigLockPath(home = neatHome2()) {
18045
- return path71.join(home, "connectors.json.lock");
18171
+ return path72.join(home, "connectors.json.lock");
18046
18172
  }
18047
18173
  function isEnvRef(value) {
18048
18174
  return value.length > 1 && value.startsWith("$");
@@ -18055,7 +18181,7 @@ function redactCredentialRef(ref) {
18055
18181
  return out;
18056
18182
  }
18057
18183
  async function writeConfigAtomically0600(file, contents) {
18058
- await fs37.mkdir(path71.dirname(file), { recursive: true });
18184
+ await fs37.mkdir(path72.dirname(file), { recursive: true });
18059
18185
  const tmp = `${file}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
18060
18186
  const fd = await fs37.open(tmp, "w", 384);
18061
18187
  try {
@@ -18069,7 +18195,7 @@ async function writeConfigAtomically0600(file, contents) {
18069
18195
  }
18070
18196
  async function acquireConnectorsLock(lockPath, timeoutMs = CONNECTORS_LOCK_TIMEOUT_MS) {
18071
18197
  const deadline = Date.now() + timeoutMs;
18072
- await fs37.mkdir(path71.dirname(lockPath), { recursive: true });
18198
+ await fs37.mkdir(path72.dirname(lockPath), { recursive: true });
18073
18199
  for (; ; ) {
18074
18200
  try {
18075
18201
  const fd = await fs37.open(lockPath, "wx");
@@ -18721,10 +18847,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
18721
18847
  // src/connectors/supabase/map.ts
18722
18848
  var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
18723
18849
  var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
18724
- function targetFromRestPath(path72) {
18725
- const rpcMatch = REST_RPC_PATH_RE.exec(path72);
18850
+ function targetFromRestPath(path73) {
18851
+ const rpcMatch = REST_RPC_PATH_RE.exec(path73);
18726
18852
  if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
18727
- const tableMatch = REST_TABLE_PATH_RE.exec(path72);
18853
+ const tableMatch = REST_TABLE_PATH_RE.exec(path73);
18728
18854
  if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
18729
18855
  return null;
18730
18856
  }
@@ -18833,23 +18959,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
18833
18959
  }
18834
18960
 
18835
18961
  // src/connectors/supabase/resolve.ts
18836
- import { EdgeType as EdgeType26, infraId as infraId21 } from "@neat.is/types";
18962
+ import { EdgeType as EdgeType27, infraId as infraId22 } from "@neat.is/types";
18837
18963
  function createSupabaseResolveTarget(graph, config) {
18838
18964
  return (signal, _ctx) => {
18839
18965
  if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
18840
18966
  return null;
18841
18967
  }
18842
- const subResourceId = infraId21(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
18968
+ const subResourceId = infraId22(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
18843
18969
  if (graph.hasNode(subResourceId)) {
18844
- return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: EdgeType26.CALLS };
18970
+ return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: EdgeType27.CALLS };
18845
18971
  }
18846
- const bareResourceId = infraId21(signal.targetKind, signal.targetName);
18972
+ const bareResourceId = infraId22(signal.targetKind, signal.targetName);
18847
18973
  if (graph.hasNode(bareResourceId)) {
18848
- return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: EdgeType26.CALLS };
18974
+ return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: EdgeType27.CALLS };
18849
18975
  }
18850
- const projectLevelId = infraId21("supabase", config.nodeRef);
18976
+ const projectLevelId = infraId22("supabase", config.nodeRef);
18851
18977
  if (graph.hasNode(projectLevelId)) {
18852
- return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: EdgeType26.CALLS };
18978
+ return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: EdgeType27.CALLS };
18853
18979
  }
18854
18980
  return null;
18855
18981
  };
@@ -18941,7 +19067,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
18941
19067
  }
18942
19068
 
18943
19069
  // src/connectors/railway/index.ts
18944
- import { EdgeType as EdgeType27, NodeType as NodeType34, serviceId as serviceId15 } from "@neat.is/types";
19070
+ import { EdgeType as EdgeType28, NodeType as NodeType34, serviceId as serviceId16 } from "@neat.is/types";
18945
19071
 
18946
19072
  // src/connectors/railway/client.ts
18947
19073
  var DEFAULT_RAILWAY_API_URL = "https://backboard.railway.com/graphql/v2";
@@ -19195,12 +19321,12 @@ function createRailwayResolveTarget(config) {
19195
19321
  const serviceName = config.serviceNameById[config.serviceId];
19196
19322
  if (!serviceName) return null;
19197
19323
  if (signal.targetKind === ROUTE_TARGET_KIND) {
19198
- return { targetNodeId: signal.targetName, serviceName, edgeType: EdgeType27.CALLS };
19324
+ return { targetNodeId: signal.targetName, serviceName, edgeType: EdgeType28.CALLS };
19199
19325
  }
19200
19326
  if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
19201
19327
  const peerName = config.serviceNameById[signal.targetName];
19202
19328
  if (!peerName) return null;
19203
- return { targetNodeId: serviceId15(peerName), serviceName, edgeType: EdgeType27.CONNECTS_TO };
19329
+ return { targetNodeId: serviceId16(peerName), serviceName, edgeType: EdgeType28.CONNECTS_TO };
19204
19330
  }
19205
19331
  return null;
19206
19332
  };
@@ -19319,9 +19445,9 @@ function parseFirebaseTargetName(targetName) {
19319
19445
  const secondSep = rest.indexOf(FIELD_SEP);
19320
19446
  if (secondSep === -1) return null;
19321
19447
  const method = rest.slice(0, secondSep);
19322
- const path72 = rest.slice(secondSep + 1);
19323
- if (!resourceName || !method || !path72) return null;
19324
- return { resourceName, method, path: path72 };
19448
+ const path73 = rest.slice(secondSep + 1);
19449
+ if (!resourceName || !method || !path73) return null;
19450
+ return { resourceName, method, path: path73 };
19325
19451
  }
19326
19452
  function resourceNameFor(type, labels) {
19327
19453
  if (!labels) return null;
@@ -19359,14 +19485,14 @@ function mapLogEntryToSignal(entry) {
19359
19485
  if (!req) return null;
19360
19486
  if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
19361
19487
  const method = req.requestMethod.toUpperCase();
19362
- const path72 = pathFromRequestUrl(req.requestUrl);
19363
- if (path72 === null) return null;
19488
+ const path73 = pathFromRequestUrl(req.requestUrl);
19489
+ if (path73 === null) return null;
19364
19490
  const timestamp = entry.timestamp;
19365
19491
  if (typeof timestamp !== "string" || timestamp.length === 0) return null;
19366
19492
  const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
19367
19493
  return {
19368
19494
  targetKind: resourceType,
19369
- targetName: packFirebaseTargetName({ resourceName, method, path: path72 }),
19495
+ targetName: packFirebaseTargetName({ resourceName, method, path: path73 }),
19370
19496
  callCount: 1,
19371
19497
  errorCount: isError ? 1 : 0,
19372
19498
  lastObservedIso: timestamp
@@ -19382,7 +19508,7 @@ function mapLogEntriesToSignals(entries) {
19382
19508
  }
19383
19509
 
19384
19510
  // src/connectors/firebase/resolve.ts
19385
- import { NodeType as NodeType35, EdgeType as EdgeType28 } from "@neat.is/types";
19511
+ import { NodeType as NodeType35, EdgeType as EdgeType29 } from "@neat.is/types";
19386
19512
  function neatServiceNameFor(resourceType, resourceName, serviceMap) {
19387
19513
  switch (resourceType) {
19388
19514
  case "cloud_function":
@@ -19429,7 +19555,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
19429
19555
  return {
19430
19556
  targetNodeId: match.routeNodeId,
19431
19557
  serviceName,
19432
- edgeType: EdgeType28.CALLS
19558
+ edgeType: EdgeType29.CALLS
19433
19559
  };
19434
19560
  };
19435
19561
  }
@@ -19452,7 +19578,7 @@ function createFirebaseConnector(graph, serviceMap) {
19452
19578
  }
19453
19579
 
19454
19580
  // src/connectors/cloudflare/connector.ts
19455
- import { EdgeType as EdgeType29, NodeType as NodeType36, fileId as fileId5, infraId as infraId22 } from "@neat.is/types";
19581
+ import { EdgeType as EdgeType30, NodeType as NodeType36, fileId as fileId5, infraId as infraId23 } from "@neat.is/types";
19456
19582
 
19457
19583
  // src/connectors/cloudflare/client.ts
19458
19584
  import { randomUUID } from "crypto";
@@ -19563,7 +19689,7 @@ function mapEventToSignal(event) {
19563
19689
  if (Number.isNaN(observedAt.getTime())) return null;
19564
19690
  const statusCode = metadata?.statusCode;
19565
19691
  const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
19566
- const path72 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
19692
+ const path73 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
19567
19693
  return {
19568
19694
  targetKind: CLOUDFLARE_TARGET_KIND,
19569
19695
  targetName: scriptName,
@@ -19571,7 +19697,7 @@ function mapEventToSignal(event) {
19571
19697
  errorCount: isError ? 1 : 0,
19572
19698
  lastObservedIso: observedAt.toISOString(),
19573
19699
  method,
19574
- ...path72 ? { path: path72 } : {},
19700
+ ...path73 ? { path: path73 } : {},
19575
19701
  ...typeof statusCode === "number" ? { statusCode } : {},
19576
19702
  ...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
19577
19703
  };
@@ -19617,8 +19743,8 @@ function findTaggedWorkerFileNode(graph, workerName) {
19617
19743
  });
19618
19744
  return found;
19619
19745
  }
19620
- function findMatchingRouteNode(graph, serviceName, method, path72) {
19621
- const normalizedPath = normalizePathTemplate(path72);
19746
+ function findMatchingRouteNode(graph, serviceName, method, path73) {
19747
+ const normalizedPath = normalizePathTemplate(path73);
19622
19748
  let found = null;
19623
19749
  graph.forEachNode((id, attrs) => {
19624
19750
  if (found) return;
@@ -19635,10 +19761,10 @@ function createCloudflareResolveTarget(config, graph) {
19635
19761
  return (signal) => {
19636
19762
  if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
19637
19763
  const scriptName = signal.targetName;
19638
- const { method, path: path72 } = signal;
19764
+ const { method, path: path73 } = signal;
19639
19765
  const resolveRouteGrain = (serviceName, wholeFileId) => {
19640
- if (!method || !path72) return wholeFileId;
19641
- return findMatchingRouteNode(graph, serviceName, method, path72) ?? wholeFileId;
19766
+ if (!method || !path73) return wholeFileId;
19767
+ return findMatchingRouteNode(graph, serviceName, method, path73) ?? wholeFileId;
19642
19768
  };
19643
19769
  const mapping = config.workers?.[scriptName];
19644
19770
  if (mapping) {
@@ -19646,7 +19772,7 @@ function createCloudflareResolveTarget(config, graph) {
19646
19772
  return {
19647
19773
  targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
19648
19774
  serviceName: mapping.service,
19649
- edgeType: EdgeType29.CALLS
19775
+ edgeType: EdgeType30.CALLS
19650
19776
  };
19651
19777
  }
19652
19778
  const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
@@ -19655,13 +19781,13 @@ function createCloudflareResolveTarget(config, graph) {
19655
19781
  return {
19656
19782
  targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
19657
19783
  serviceName: fileNode.service,
19658
- edgeType: EdgeType29.CALLS
19784
+ edgeType: EdgeType30.CALLS
19659
19785
  };
19660
19786
  }
19661
19787
  return {
19662
- targetNodeId: infraId22("cloudflare-worker", scriptName),
19788
+ targetNodeId: infraId23("cloudflare-worker", scriptName),
19663
19789
  serviceName: scriptName,
19664
- edgeType: EdgeType29.CALLS,
19790
+ edgeType: EdgeType30.CALLS,
19665
19791
  ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
19666
19792
  };
19667
19793
  };
@@ -19843,14 +19969,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
19843
19969
  }
19844
19970
 
19845
19971
  // src/connectors/neon/resolve.ts
19846
- import { EdgeType as EdgeType30, infraId as infraId23 } from "@neat.is/types";
19972
+ import { EdgeType as EdgeType31, infraId as infraId24 } from "@neat.is/types";
19847
19973
  function createNeonResolveTarget(config) {
19848
19974
  return (signal) => {
19849
19975
  if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
19850
19976
  return {
19851
- targetNodeId: infraId23("sql-table", signal.targetName),
19977
+ targetNodeId: infraId24("sql-table", signal.targetName),
19852
19978
  serviceName: config.serviceName,
19853
- edgeType: EdgeType30.CALLS,
19979
+ edgeType: EdgeType31.CALLS,
19854
19980
  ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
19855
19981
  };
19856
19982
  };
@@ -19968,9 +20094,9 @@ function parseCloudRunTargetName(targetName) {
19968
20094
  const secondSep = rest.indexOf(FIELD_SEP2);
19969
20095
  if (secondSep === -1) return null;
19970
20096
  const method = rest.slice(0, secondSep);
19971
- const path72 = rest.slice(secondSep + 1);
19972
- if (!serviceName || !method || !path72) return null;
19973
- return { serviceName, method, path: path72 };
20097
+ const path73 = rest.slice(secondSep + 1);
20098
+ if (!serviceName || !method || !path73) return null;
20099
+ return { serviceName, method, path: path73 };
19974
20100
  }
19975
20101
 
19976
20102
  // src/connectors/cloud-run/map.ts
@@ -19999,14 +20125,14 @@ function mapLogEntryToSignal2(entry) {
19999
20125
  if (!req) return null;
20000
20126
  if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
20001
20127
  const method = req.requestMethod.toUpperCase();
20002
- const path72 = pathFromRequestUrl2(req.requestUrl);
20003
- if (path72 === null) return null;
20128
+ const path73 = pathFromRequestUrl2(req.requestUrl);
20129
+ if (path73 === null) return null;
20004
20130
  const timestamp = entry.timestamp;
20005
20131
  if (typeof timestamp !== "string" || timestamp.length === 0) return null;
20006
20132
  const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD4;
20007
20133
  return {
20008
20134
  targetKind: CLOUD_RUN_TARGET_KIND,
20009
- targetName: packCloudRunTargetName({ serviceName, method, path: path72 }),
20135
+ targetName: packCloudRunTargetName({ serviceName, method, path: path73 }),
20010
20136
  callCount: 1,
20011
20137
  errorCount: isError ? 1 : 0,
20012
20138
  lastObservedIso: timestamp
@@ -20022,7 +20148,7 @@ function mapLogEntriesToSignals2(entries) {
20022
20148
  }
20023
20149
 
20024
20150
  // src/connectors/cloud-run/resolve.ts
20025
- import { EdgeType as EdgeType31, NodeType as NodeType37, infraId as infraId24 } from "@neat.is/types";
20151
+ import { EdgeType as EdgeType32, NodeType as NodeType37, infraId as infraId25 } from "@neat.is/types";
20026
20152
  var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
20027
20153
  function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
20028
20154
  let found = null;
@@ -20044,23 +20170,23 @@ function createCloudRunResolveTarget(graph, config) {
20044
20170
  if (signal.targetKind !== CLOUD_RUN_TARGET_KIND) return null;
20045
20171
  const identity = parseCloudRunTargetName(signal.targetName);
20046
20172
  if (!identity) return null;
20047
- const { serviceName: gcpServiceName, method, path: path72 } = identity;
20173
+ const { serviceName: gcpServiceName, method, path: path73 } = identity;
20048
20174
  const mappedService = config.serviceMap?.[gcpServiceName];
20049
20175
  if (mappedService) {
20050
20176
  const routeNodeId = findMatchingRouteNode2(
20051
20177
  graph,
20052
20178
  mappedService,
20053
20179
  method,
20054
- normalizePathTemplate(path72)
20180
+ normalizePathTemplate(path73)
20055
20181
  );
20056
20182
  if (routeNodeId) {
20057
- return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: EdgeType31.CALLS };
20183
+ return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: EdgeType32.CALLS };
20058
20184
  }
20059
20185
  }
20060
20186
  return {
20061
- targetNodeId: infraId24(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
20187
+ targetNodeId: infraId25(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
20062
20188
  serviceName: mappedService ?? gcpServiceName,
20063
- edgeType: EdgeType31.CALLS,
20189
+ edgeType: EdgeType32.CALLS,
20064
20190
  ensureInfraNode: {
20065
20191
  kind: CLOUD_RUN_SERVICE_INFRA_KIND,
20066
20192
  name: gcpServiceName,
@@ -20179,9 +20305,9 @@ function parseGcpLbTargetName(targetName) {
20179
20305
  const secondSep = rest.indexOf(FIELD_SEP3);
20180
20306
  if (secondSep === -1) return null;
20181
20307
  const method = rest.slice(0, secondSep);
20182
- const path72 = rest.slice(secondSep + 1);
20183
- if (!backendServiceName || !method || !path72) return null;
20184
- return { backendServiceName, method, path: path72 };
20308
+ const path73 = rest.slice(secondSep + 1);
20309
+ if (!backendServiceName || !method || !path73) return null;
20310
+ return { backendServiceName, method, path: path73 };
20185
20311
  }
20186
20312
 
20187
20313
  // src/connectors/gcp-lb/map.ts
@@ -20210,14 +20336,14 @@ function mapLogEntryToSignal3(entry) {
20210
20336
  if (!req) return null;
20211
20337
  if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
20212
20338
  const method = req.requestMethod.toUpperCase();
20213
- const path72 = pathFromRequestUrl3(req.requestUrl);
20214
- if (path72 === null) return null;
20339
+ const path73 = pathFromRequestUrl3(req.requestUrl);
20340
+ if (path73 === null) return null;
20215
20341
  const timestamp = entry.timestamp;
20216
20342
  if (typeof timestamp !== "string" || timestamp.length === 0) return null;
20217
20343
  const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD5;
20218
20344
  return {
20219
20345
  targetKind: GCP_LB_TARGET_KIND,
20220
- targetName: packGcpLbTargetName({ backendServiceName, method, path: path72 }),
20346
+ targetName: packGcpLbTargetName({ backendServiceName, method, path: path73 }),
20221
20347
  callCount: 1,
20222
20348
  errorCount: isError ? 1 : 0,
20223
20349
  lastObservedIso: timestamp
@@ -20233,7 +20359,7 @@ function mapLogEntriesToSignals3(entries) {
20233
20359
  }
20234
20360
 
20235
20361
  // src/connectors/gcp-lb/resolve.ts
20236
- import { EdgeType as EdgeType32, NodeType as NodeType38, infraId as infraId25 } from "@neat.is/types";
20362
+ import { EdgeType as EdgeType33, NodeType as NodeType38, infraId as infraId26 } from "@neat.is/types";
20237
20363
  var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
20238
20364
  function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
20239
20365
  let found = null;
@@ -20255,23 +20381,23 @@ function createGcpLbResolveTarget(graph, config) {
20255
20381
  if (signal.targetKind !== GCP_LB_TARGET_KIND) return null;
20256
20382
  const identity = parseGcpLbTargetName(signal.targetName);
20257
20383
  if (!identity) return null;
20258
- const { backendServiceName, method, path: path72 } = identity;
20384
+ const { backendServiceName, method, path: path73 } = identity;
20259
20385
  const mappedService = config.backendServiceMap?.[backendServiceName];
20260
20386
  if (mappedService) {
20261
20387
  const routeNodeId = findMatchingRouteNode3(
20262
20388
  graph,
20263
20389
  mappedService,
20264
20390
  method,
20265
- normalizePathTemplate(path72)
20391
+ normalizePathTemplate(path73)
20266
20392
  );
20267
20393
  if (routeNodeId) {
20268
- return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: EdgeType32.CALLS };
20394
+ return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: EdgeType33.CALLS };
20269
20395
  }
20270
20396
  }
20271
20397
  return {
20272
- targetNodeId: infraId25(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
20398
+ targetNodeId: infraId26(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
20273
20399
  serviceName: mappedService ?? backendServiceName,
20274
- edgeType: EdgeType32.CALLS,
20400
+ edgeType: EdgeType33.CALLS,
20275
20401
  ensureInfraNode: {
20276
20402
  kind: GCP_LB_BACKEND_INFRA_KIND,
20277
20403
  name: backendServiceName,
@@ -20311,7 +20437,7 @@ function createGcpLbConnector(graph, config = {}) {
20311
20437
  }
20312
20438
 
20313
20439
  // src/connectors/render/index.ts
20314
- import { EdgeType as EdgeType33, NodeType as NodeType39 } from "@neat.is/types";
20440
+ import { EdgeType as EdgeType34, NodeType as NodeType39 } from "@neat.is/types";
20315
20441
 
20316
20442
  // src/connectors/render/types.ts
20317
20443
  function readRenderToken(credentials) {
@@ -20472,7 +20598,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
20472
20598
  function createRenderResolveTarget(config) {
20473
20599
  return (signal) => {
20474
20600
  if (signal.targetKind === ROUTE_TARGET_KIND2) {
20475
- return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: EdgeType33.CALLS };
20601
+ return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: EdgeType34.CALLS };
20476
20602
  }
20477
20603
  return null;
20478
20604
  };
@@ -20601,21 +20727,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
20601
20727
  }
20602
20728
 
20603
20729
  // src/connectors/planetscale/resolve.ts
20604
- import { EdgeType as EdgeType34, infraId as infraId26 } from "@neat.is/types";
20730
+ import { EdgeType as EdgeType35, infraId as infraId27 } from "@neat.is/types";
20605
20731
  var PLANETSCALE_DATABASE_KIND = "planetscale-database";
20606
20732
  function createPlanetscaleResolveTarget(graph, config) {
20607
20733
  const databaseName = `${config.organization}/${config.database}`;
20608
20734
  return (signal, _ctx) => {
20609
20735
  if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
20610
- const tableId = infraId26("sql-table", signal.targetName);
20736
+ const tableId = infraId27("sql-table", signal.targetName);
20611
20737
  if (graph.hasNode(tableId)) {
20612
- return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: EdgeType34.CALLS };
20738
+ return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: EdgeType35.CALLS };
20613
20739
  }
20614
- const providerId = infraId26(PLANETSCALE_DATABASE_KIND, databaseName);
20740
+ const providerId = infraId27(PLANETSCALE_DATABASE_KIND, databaseName);
20615
20741
  return {
20616
20742
  targetNodeId: providerId,
20617
20743
  serviceName: config.serviceName,
20618
- edgeType: EdgeType34.CALLS,
20744
+ edgeType: EdgeType35.CALLS,
20619
20745
  ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
20620
20746
  };
20621
20747
  };
@@ -20871,7 +20997,7 @@ function mapBuildsToSignals(builds, serviceName) {
20871
20997
  }
20872
20998
 
20873
20999
  // src/connectors/eas/resolve.ts
20874
- import { EdgeType as EdgeType35, NodeType as NodeType40, parseFileId as parseFileId3 } from "@neat.is/types";
21000
+ import { EdgeType as EdgeType36, NodeType as NodeType40, parseFileId as parseFileId3 } from "@neat.is/types";
20875
21001
  var NO_ENV2 = "unknown";
20876
21002
  var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
20877
21003
  var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
@@ -20887,7 +21013,7 @@ function configBasenamesForPhase(phase) {
20887
21013
  function configNodeService(graph, configNodeId) {
20888
21014
  for (const edgeId of graph.inboundEdges(configNodeId)) {
20889
21015
  const edge = graph.getEdgeAttributes(edgeId);
20890
- if (edge.type !== EdgeType35.CONFIGURED_BY) continue;
21016
+ if (edge.type !== EdgeType36.CONFIGURED_BY) continue;
20891
21017
  const parsed = parseFileId3(edge.source);
20892
21018
  if (parsed) return parsed.service;
20893
21019
  }
@@ -20916,13 +21042,13 @@ function createEasResolveTarget(graph) {
20916
21042
  if (basenames.length > 0) {
20917
21043
  const configNodeId = findConfigNode(graph, basenames, serviceName);
20918
21044
  if (configNodeId) {
20919
- return { targetNodeId: configNodeId, serviceName, edgeType: EdgeType35.CALLS };
21045
+ return { targetNodeId: configNodeId, serviceName, edgeType: EdgeType36.CALLS };
20920
21046
  }
20921
21047
  }
20922
21048
  return {
20923
21049
  targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
20924
21050
  serviceName,
20925
- edgeType: EdgeType35.CALLS
21051
+ edgeType: EdgeType36.CALLS
20926
21052
  };
20927
21053
  };
20928
21054
  }
@@ -22538,6 +22664,7 @@ export {
22538
22664
  addImports,
22539
22665
  addRoutes,
22540
22666
  thresholdForEdgeType,
22667
+ resolveFusedServiceId,
22541
22668
  stitchTrace,
22542
22669
  makeErrorSpanWriter,
22543
22670
  handleSpan,
@@ -22588,11 +22715,15 @@ export {
22588
22715
  removeProject,
22589
22716
  pruneRegistry,
22590
22717
  readConnectorsConfig,
22718
+ resolveCredential,
22591
22719
  isEnvRef,
22592
22720
  upsertConnectorEntry,
22593
22721
  removeConnectorEntry,
22594
22722
  autoSlugConnectorId,
22595
22723
  describeCredential,
22724
+ startConnectorPollLoop,
22725
+ bearerAuthHeader,
22726
+ junctionFetch,
22596
22727
  isPushProvider,
22597
22728
  getProviderFieldSchema,
22598
22729
  knownProviderNames,
@@ -22602,4 +22733,4 @@ export {
22602
22733
  deprovisionConnector,
22603
22734
  buildApi
22604
22735
  };
22605
- //# sourceMappingURL=chunk-3UAUMPIY.js.map
22736
+ //# sourceMappingURL=chunk-RBZNXA5L.js.map