@neat.is/core 0.10.6-dev.20261010 → 0.10.6

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.
package/dist/cli.cjs CHANGED
@@ -3039,7 +3039,7 @@ var PolicyViolationsLog = class {
3039
3039
  };
3040
3040
 
3041
3041
  // src/ingest.ts
3042
- var import_types9 = require("@neat.is/types");
3042
+ var import_types10 = require("@neat.is/types");
3043
3043
 
3044
3044
  // src/extract/routes.ts
3045
3045
  init_cjs_shims();
@@ -5816,9 +5816,95 @@ async function addRoutes(graph, services) {
5816
5816
  return { nodesAdded, edgesAdded };
5817
5817
  }
5818
5818
 
5819
- // src/columns.ts
5819
+ // src/extract/source-baseline.ts
5820
5820
  init_cjs_shims();
5821
5821
  var import_types8 = require("@neat.is/types");
5822
+ var states = /* @__PURE__ */ new WeakMap();
5823
+ var REPOSITORY = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
5824
+ function validCommit(commit, repository) {
5825
+ return !!commit && commit.repository === repository && /^[0-9a-f]{40}$/.test(commit.sha);
5826
+ }
5827
+ function stateOf(graph) {
5828
+ let state = states.get(graph);
5829
+ if (!state) {
5830
+ state = { repos: /* @__PURE__ */ new Map(), active: /* @__PURE__ */ new Set(), conflicted: /* @__PURE__ */ new Set() };
5831
+ states.set(graph, state);
5832
+ }
5833
+ return state;
5834
+ }
5835
+ function setEntry(state, repository, baseline, generation = /* @__PURE__ */ Symbol()) {
5836
+ state.repos.set(repository, {
5837
+ baseline,
5838
+ generation,
5839
+ services: state.repos.get(repository)?.services ?? /* @__PURE__ */ new Set()
5840
+ });
5841
+ }
5842
+ function readSourceBaselines(graph) {
5843
+ const state = states.get(graph);
5844
+ if (!state) return [];
5845
+ return [...state.repos.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([, entry2]) => ({ ...entry2.baseline }));
5846
+ }
5847
+ function invalidateSourceBaseline(graph, repository, status2 = "unavailable") {
5848
+ if (repository !== void 0) {
5849
+ if (REPOSITORY.test(repository)) setEntry(stateOf(graph), repository, { status: status2, repository });
5850
+ return;
5851
+ }
5852
+ const state = states.get(graph);
5853
+ if (!state) return;
5854
+ for (const generation of state.active) state.conflicted.add(generation);
5855
+ for (const name of state.repos.keys()) {
5856
+ setEntry(state, name, { status: "unavailable", repository: name });
5857
+ }
5858
+ }
5859
+ function beginSourceExtraction(graph, source, commit) {
5860
+ const generation = /* @__PURE__ */ Symbol();
5861
+ const state = stateOf(graph);
5862
+ if (source === void 0) {
5863
+ invalidateSourceBaseline(graph);
5864
+ state.active.add(generation);
5865
+ return generation;
5866
+ }
5867
+ state.active.add(generation);
5868
+ if (!REPOSITORY.test(source)) return generation;
5869
+ setEntry(
5870
+ state,
5871
+ source,
5872
+ validCommit(commit, source) ? { status: "syncing", repository: source } : { status: "unavailable", repository: source },
5873
+ generation
5874
+ );
5875
+ return generation;
5876
+ }
5877
+ function servicesOf(graph, repository) {
5878
+ const services = /* @__PURE__ */ new Set();
5879
+ graph.forEachNode((_id, attrs) => {
5880
+ const node = attrs;
5881
+ if (node.type === import_types8.NodeType.FileNode && node.source === repository && node.service) {
5882
+ services.add(node.service);
5883
+ }
5884
+ });
5885
+ return services;
5886
+ }
5887
+ function finishSourceExtraction(graph, generation, source, commit, result) {
5888
+ const state = states.get(graph);
5889
+ if (!state) return;
5890
+ state.active.delete(generation);
5891
+ const conflicted = state.conflicted.delete(generation);
5892
+ if (source === void 0 || !REPOSITORY.test(source)) return;
5893
+ const entry2 = state.repos.get(source);
5894
+ if (!entry2 || entry2.generation !== generation) return;
5895
+ entry2.services = servicesOf(graph, source);
5896
+ let shared = false;
5897
+ for (const [name, other] of state.repos) {
5898
+ if (name === source || ![...entry2.services].some((s) => other.services.has(s))) continue;
5899
+ shared = true;
5900
+ setEntry(state, name, { status: "unavailable", repository: name }, other.generation);
5901
+ }
5902
+ entry2.baseline = !conflicted && !shared && validCommit(commit, source) && result.extractionErrors === 0 && result.skippedFiles === 0 ? { status: "ready", repository: source, sha: commit.sha } : { status: "unavailable", repository: source };
5903
+ }
5904
+
5905
+ // src/columns.ts
5906
+ init_cjs_shims();
5907
+ var import_types9 = require("@neat.is/types");
5822
5908
  var OBSERVED_COLUMN_CONFIDENCE = 0.9;
5823
5909
  function normalizeProvenances(provenances) {
5824
5910
  return [...new Set(provenances)].sort();
@@ -5861,10 +5947,10 @@ function foldSdkWrites(existing, writes) {
5861
5947
  return out;
5862
5948
  }
5863
5949
  function columnIsDeclared(col) {
5864
- return col.provenances.includes(import_types8.Provenance.EXTRACTED);
5950
+ return col.provenances.includes(import_types9.Provenance.EXTRACTED);
5865
5951
  }
5866
5952
  function columnIsObserved(col) {
5867
- return col.provenances.includes(import_types8.Provenance.OBSERVED);
5953
+ return col.provenances.includes(import_types9.Provenance.OBSERVED);
5868
5954
  }
5869
5955
 
5870
5956
  // src/latency-digest.ts
@@ -6328,11 +6414,11 @@ function callSiteFromSpan(span, serviceNode, scanPath) {
6328
6414
  };
6329
6415
  }
6330
6416
  function reconcileObservedRelPath(graph, serviceName, relPath) {
6331
- if (graph.hasNode((0, import_types9.fileId)(serviceName, relPath))) return relPath;
6417
+ if (graph.hasNode((0, import_types10.fileId)(serviceName, relPath))) return relPath;
6332
6418
  let best = null;
6333
6419
  graph.forEachNode((_id, attrs) => {
6334
6420
  const a = attrs;
6335
- if (a.type !== import_types9.NodeType.FileNode || a.service !== serviceName) return;
6421
+ if (a.type !== import_types10.NodeType.FileNode || a.service !== serviceName) return;
6336
6422
  if (a.discoveredVia === "otel") return;
6337
6423
  const p = a.path;
6338
6424
  if (!p) return;
@@ -6344,14 +6430,14 @@ function reconcileObservedRelPath(graph, serviceName, relPath) {
6344
6430
  }
6345
6431
  function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
6346
6432
  const svcAttrs = graph.hasNode(serviceNodeId) ? graph.getNodeAttributes(serviceNodeId) : void 0;
6347
- const canonicalService = svcAttrs && svcAttrs.type === import_types9.NodeType.ServiceNode && typeof svcAttrs.name === "string" ? svcAttrs.name : serviceName;
6433
+ const canonicalService = svcAttrs && svcAttrs.type === import_types10.NodeType.ServiceNode && typeof svcAttrs.name === "string" ? svcAttrs.name : serviceName;
6348
6434
  const relPath = reconcileObservedRelPath(graph, canonicalService, callSite.relPath);
6349
- const fileNodeId = (0, import_types9.fileId)(canonicalService, relPath);
6435
+ const fileNodeId = (0, import_types10.fileId)(canonicalService, relPath);
6350
6436
  if (!graph.hasNode(fileNodeId)) {
6351
6437
  const language = languageForExt(relPath);
6352
6438
  const node = {
6353
6439
  id: fileNodeId,
6354
- type: import_types9.NodeType.FileNode,
6440
+ type: import_types10.NodeType.FileNode,
6355
6441
  service: canonicalService,
6356
6442
  path: relPath,
6357
6443
  ...language ? { language } : {},
@@ -6360,14 +6446,14 @@ function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
6360
6446
  };
6361
6447
  graph.addNode(fileNodeId, node);
6362
6448
  }
6363
- const containsId = makeObservedEdgeId(import_types9.EdgeType.CONTAINS, serviceNodeId, fileNodeId);
6449
+ const containsId = makeObservedEdgeId(import_types10.EdgeType.CONTAINS, serviceNodeId, fileNodeId);
6364
6450
  if (!graph.hasEdge(containsId)) {
6365
6451
  const edge = {
6366
6452
  id: containsId,
6367
6453
  source: serviceNodeId,
6368
6454
  target: fileNodeId,
6369
- type: import_types9.EdgeType.CONTAINS,
6370
- provenance: import_types9.Provenance.OBSERVED
6455
+ type: import_types10.EdgeType.CONTAINS,
6456
+ provenance: import_types10.Provenance.OBSERVED
6371
6457
  };
6372
6458
  graph.addEdgeWithKey(containsId, serviceNodeId, fileNodeId, edge);
6373
6459
  }
@@ -6391,11 +6477,11 @@ function pickContainingSymbol(candidates, fn) {
6391
6477
  return [...candidates].sort(bySpan)[0].id;
6392
6478
  }
6393
6479
  function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line) {
6394
- const sid = (0, import_types9.symbolId)(service, relPath, fn);
6480
+ const sid = (0, import_types10.symbolId)(service, relPath, fn);
6395
6481
  if (!graph.hasNode(sid)) {
6396
6482
  const node = {
6397
6483
  id: sid,
6398
- type: import_types9.NodeType.SymbolNode,
6484
+ type: import_types10.NodeType.SymbolNode,
6399
6485
  kind: "function",
6400
6486
  qualname: fn,
6401
6487
  span: { startLine: line, endLine: line },
@@ -6405,14 +6491,14 @@ function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line)
6405
6491
  };
6406
6492
  graph.addNode(sid, node);
6407
6493
  }
6408
- const containsId = makeObservedEdgeId(import_types9.EdgeType.CONTAINS, fileNodeId, sid);
6494
+ const containsId = makeObservedEdgeId(import_types10.EdgeType.CONTAINS, fileNodeId, sid);
6409
6495
  if (!graph.hasEdge(containsId)) {
6410
6496
  const edge = {
6411
6497
  id: containsId,
6412
6498
  source: fileNodeId,
6413
6499
  target: sid,
6414
- type: import_types9.EdgeType.CONTAINS,
6415
- provenance: import_types9.Provenance.OBSERVED
6500
+ type: import_types10.EdgeType.CONTAINS,
6501
+ provenance: import_types10.Provenance.OBSERVED
6416
6502
  };
6417
6503
  graph.addEdgeWithKey(containsId, fileNodeId, sid, edge);
6418
6504
  }
@@ -6424,9 +6510,9 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
6424
6510
  let sawSymbol = false;
6425
6511
  const candidates = [];
6426
6512
  graph.forEachOutboundEdge(fileNodeId, (_edge, edgeAttrs, _source, target) => {
6427
- if (edgeAttrs.type !== import_types9.EdgeType.CONTAINS) return;
6513
+ if (edgeAttrs.type !== import_types10.EdgeType.CONTAINS) return;
6428
6514
  const t = graph.getNodeAttributes(target);
6429
- if (t.type !== import_types9.NodeType.SymbolNode) return;
6515
+ if (t.type !== import_types10.NodeType.SymbolNode) return;
6430
6516
  sawSymbol = true;
6431
6517
  if (line >= t.span.startLine && line <= t.span.endLine) {
6432
6518
  candidates.push({ id: target, symbol: t });
@@ -6439,17 +6525,17 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
6439
6525
  return fileNodeId;
6440
6526
  }
6441
6527
  function makeObservedEdgeId(type, source, target) {
6442
- return (0, import_types9.observedEdgeId)(source, target, type);
6528
+ return (0, import_types10.observedEdgeId)(source, target, type);
6443
6529
  }
6444
6530
  function makeInferredEdgeId(type, source, target) {
6445
- return (0, import_types9.inferredEdgeId)(source, target, type);
6531
+ return (0, import_types10.inferredEdgeId)(source, target, type);
6446
6532
  }
6447
6533
  var INFERRED_CONFIDENCE = 0.6;
6448
6534
  var STITCH_MAX_DEPTH = 2;
6449
6535
  var STITCH_EDGE_TYPES = /* @__PURE__ */ new Set([
6450
- import_types9.EdgeType.CALLS,
6451
- import_types9.EdgeType.CONNECTS_TO,
6452
- import_types9.EdgeType.DEPENDS_ON
6536
+ import_types10.EdgeType.CALLS,
6537
+ import_types10.EdgeType.CONNECTS_TO,
6538
+ import_types10.EdgeType.DEPENDS_ON
6453
6539
  ]);
6454
6540
  var WIRE_SPAN_KIND_CLIENT = 3;
6455
6541
  var WIRE_SPAN_KIND_PRODUCER = 4;
@@ -6465,11 +6551,11 @@ function spanServesGraphqlOperation(kind) {
6465
6551
  return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
6466
6552
  }
6467
6553
  function ensureGraphqlOperationNode(graph, serviceName, operationType, operationName) {
6468
- const id = (0, import_types9.graphqlOperationId)(serviceName, operationType, operationName);
6554
+ const id = (0, import_types10.graphqlOperationId)(serviceName, operationType, operationName);
6469
6555
  if (graph.hasNode(id)) return id;
6470
6556
  const node = {
6471
6557
  id,
6472
- type: import_types9.NodeType.GraphQLOperationNode,
6558
+ type: import_types10.NodeType.GraphQLOperationNode,
6473
6559
  name: operationName,
6474
6560
  service: serviceName,
6475
6561
  operationType: operationType.toLowerCase(),
@@ -6483,11 +6569,11 @@ function spanServesGrpcMethod(kind) {
6483
6569
  return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
6484
6570
  }
6485
6571
  function ensureGrpcMethodNode(graph, rpcService, rpcMethod) {
6486
- const id = (0, import_types9.grpcMethodId)(rpcService, rpcMethod);
6572
+ const id = (0, import_types10.grpcMethodId)(rpcService, rpcMethod);
6487
6573
  if (graph.hasNode(id)) return id;
6488
6574
  const node = {
6489
6575
  id,
6490
- type: import_types9.NodeType.GrpcMethodNode,
6576
+ type: import_types10.NodeType.GrpcMethodNode,
6491
6577
  name: `${rpcService}/${rpcMethod}`,
6492
6578
  rpcService,
6493
6579
  rpcMethod,
@@ -6500,11 +6586,11 @@ function spanServesWebsocketChannel(kind) {
6500
6586
  return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
6501
6587
  }
6502
6588
  function ensureWebsocketChannelNode(graph, serviceName, channel) {
6503
- const id = (0, import_types9.websocketChannelId)(serviceName, channel);
6589
+ const id = (0, import_types10.websocketChannelId)(serviceName, channel);
6504
6590
  if (graph.hasNode(id)) return id;
6505
6591
  const node = {
6506
6592
  id,
6507
- type: import_types9.NodeType.WebSocketChannelNode,
6593
+ type: import_types10.NodeType.WebSocketChannelNode,
6508
6594
  name: channel,
6509
6595
  service: serviceName,
6510
6596
  channel,
@@ -6517,11 +6603,11 @@ function messagingDestinationKind(system) {
6517
6603
  return `${system}-topic`;
6518
6604
  }
6519
6605
  function ensureMessagingDestinationNode(graph, system, destination) {
6520
- const id = (0, import_types9.infraId)(messagingDestinationKind(system), destination);
6606
+ const id = (0, import_types10.infraId)(messagingDestinationKind(system), destination);
6521
6607
  if (graph.hasNode(id)) return id;
6522
6608
  const node = {
6523
6609
  id,
6524
- type: import_types9.NodeType.InfraNode,
6610
+ type: import_types10.NodeType.InfraNode,
6525
6611
  name: destination,
6526
6612
  provider: "self",
6527
6613
  kind: messagingDestinationKind(system)
@@ -6565,9 +6651,9 @@ function lookupParentSpan(traceId, parentSpanId, now) {
6565
6651
  };
6566
6652
  }
6567
6653
  function resolveServiceId(graph, host, env) {
6568
- const envTagged = (0, import_types9.serviceId)(host, env);
6654
+ const envTagged = (0, import_types10.serviceId)(host, env);
6569
6655
  if (graph.hasNode(envTagged)) return envTagged;
6570
- const envLess = (0, import_types9.serviceId)(host);
6656
+ const envLess = (0, import_types10.serviceId)(host);
6571
6657
  if (envLess !== envTagged && graph.hasNode(envLess)) return envLess;
6572
6658
  let sameEnv = null;
6573
6659
  let envLessMatch = null;
@@ -6575,7 +6661,7 @@ function resolveServiceId(graph, host, env) {
6575
6661
  graph.forEachNode((id, attrs) => {
6576
6662
  if (sameEnv) return;
6577
6663
  const a = attrs;
6578
- if (a.type !== import_types9.NodeType.ServiceNode) return;
6664
+ if (a.type !== import_types10.NodeType.ServiceNode) return;
6579
6665
  const matchesByName = a.name === host;
6580
6666
  const matchesByAlias = a.aliases ? a.aliases.includes(host) : false;
6581
6667
  if (!matchesByName && !matchesByAlias) return;
@@ -6590,14 +6676,14 @@ function resolveServiceId(graph, host, env) {
6590
6676
  return sameEnv ?? envLessMatch ?? anyMatch;
6591
6677
  }
6592
6678
  function frontierIdFor(host) {
6593
- return (0, import_types9.frontierId)(host);
6679
+ return (0, import_types10.frontierId)(host);
6594
6680
  }
6595
6681
  function resolveFusedServiceId(graph, serviceName, env) {
6596
- const id = (0, import_types9.serviceId)(serviceName, env);
6682
+ const id = (0, import_types10.serviceId)(serviceName, env);
6597
6683
  if (graph.hasNode(id)) return id;
6598
6684
  const wanted = serviceName.toLowerCase();
6599
6685
  const extractedId = graph.findNode((_nid, attrs) => {
6600
- if (attrs.type !== import_types9.NodeType.ServiceNode) return false;
6686
+ if (attrs.type !== import_types10.NodeType.ServiceNode) return false;
6601
6687
  const svc = attrs;
6602
6688
  if (svc.discoveredVia === "otel") return false;
6603
6689
  return typeof svc.name === "string" && svc.name.toLowerCase() === wanted;
@@ -6609,7 +6695,7 @@ function ensureServiceNode(graph, serviceName, env) {
6609
6695
  if (graph.hasNode(resolved)) return resolved;
6610
6696
  const node = {
6611
6697
  id: resolved,
6612
- type: import_types9.NodeType.ServiceNode,
6698
+ type: import_types10.NodeType.ServiceNode,
6613
6699
  name: serviceName,
6614
6700
  language: "unknown",
6615
6701
  discoveredVia: "otel",
@@ -6619,11 +6705,11 @@ function ensureServiceNode(graph, serviceName, env) {
6619
6705
  return resolved;
6620
6706
  }
6621
6707
  function ensureInfraNode(graph, kind, name, provider) {
6622
- const id = (0, import_types9.infraId)(kind, name);
6708
+ const id = (0, import_types10.infraId)(kind, name);
6623
6709
  if (graph.hasNode(id)) return id;
6624
6710
  const node = {
6625
6711
  id,
6626
- type: import_types9.NodeType.InfraNode,
6712
+ type: import_types10.NodeType.InfraNode,
6627
6713
  name,
6628
6714
  provider,
6629
6715
  kind
@@ -6635,7 +6721,7 @@ var COLUMN_BEARING_INFRA_KINDS = /* @__PURE__ */ new Set(["sql-table", "supabase
6635
6721
  function mergeColumnsAt(graph, tableNodeId, columns, provenance2, confidence) {
6636
6722
  if (!columns || columns.length === 0 || !graph.hasNode(tableNodeId)) return;
6637
6723
  const node = graph.getNodeAttributes(tableNodeId);
6638
- if (node.type !== import_types9.NodeType.InfraNode || !node.kind || !COLUMN_BEARING_INFRA_KINDS.has(node.kind)) {
6724
+ if (node.type !== import_types10.NodeType.InfraNode || !node.kind || !COLUMN_BEARING_INFRA_KINDS.has(node.kind)) {
6639
6725
  return;
6640
6726
  }
6641
6727
  graph.replaceNodeAttributes(tableNodeId, {
@@ -6644,7 +6730,7 @@ function mergeColumnsAt(graph, tableNodeId, columns, provenance2, confidence) {
6644
6730
  });
6645
6731
  }
6646
6732
  function mergeObservedColumns(graph, tableNodeId, columns) {
6647
- mergeColumnsAt(graph, tableNodeId, columns, import_types9.Provenance.OBSERVED, OBSERVED_COLUMN_CONFIDENCE);
6733
+ mergeColumnsAt(graph, tableNodeId, columns, import_types10.Provenance.OBSERVED, OBSERVED_COLUMN_CONFIDENCE);
6648
6734
  }
6649
6735
  function mergeObservedDeployState(graph, serviceNodeId, state) {
6650
6736
  if (!graph.hasNode(serviceNodeId)) return;
@@ -6655,11 +6741,11 @@ function mergeObservedDeployState(graph, serviceNodeId, state) {
6655
6741
  graph.mergeNodeAttributes(serviceNodeId, attrs);
6656
6742
  }
6657
6743
  function ensureDatabaseNode(graph, host, engine) {
6658
- const id = (0, import_types9.databaseId)(host);
6744
+ const id = (0, import_types10.databaseId)(host);
6659
6745
  if (graph.hasNode(id)) return id;
6660
6746
  const node = {
6661
6747
  id,
6662
- type: import_types9.NodeType.DatabaseNode,
6748
+ type: import_types10.NodeType.DatabaseNode,
6663
6749
  name: host,
6664
6750
  engine,
6665
6751
  engineVersion: "unknown",
@@ -6671,11 +6757,11 @@ function ensureDatabaseNode(graph, host, engine) {
6671
6757
  return id;
6672
6758
  }
6673
6759
  function ensureLocalDatabaseNode(graph, serviceName, name, engine) {
6674
- const id = (0, import_types9.localDatabaseId)(serviceName, name);
6760
+ const id = (0, import_types10.localDatabaseId)(serviceName, name);
6675
6761
  if (graph.hasNode(id)) return id;
6676
6762
  const node = {
6677
6763
  id,
6678
- type: import_types9.NodeType.DatabaseNode,
6764
+ type: import_types10.NodeType.DatabaseNode,
6679
6765
  name,
6680
6766
  engine,
6681
6767
  engineVersion: "unknown",
@@ -6690,17 +6776,17 @@ function findDeclaredDatabaseForService(graph, serviceNodeId, engine) {
6690
6776
  const sources = [serviceNodeId];
6691
6777
  for (const edgeId of graph.outboundEdges(serviceNodeId)) {
6692
6778
  const e = graph.getEdgeAttributes(edgeId);
6693
- if (e.type === import_types9.EdgeType.CONTAINS) sources.push(e.target);
6779
+ if (e.type === import_types10.EdgeType.CONTAINS) sources.push(e.target);
6694
6780
  }
6695
6781
  const matches = /* @__PURE__ */ new Set();
6696
6782
  for (const src of sources) {
6697
6783
  if (!graph.hasNode(src)) continue;
6698
6784
  for (const edgeId of graph.outboundEdges(src)) {
6699
6785
  const edge = graph.getEdgeAttributes(edgeId);
6700
- if (edge.type !== import_types9.EdgeType.CONNECTS_TO || edge.provenance !== import_types9.Provenance.EXTRACTED) continue;
6786
+ if (edge.type !== import_types10.EdgeType.CONNECTS_TO || edge.provenance !== import_types10.Provenance.EXTRACTED) continue;
6701
6787
  if (!graph.hasNode(edge.target)) continue;
6702
6788
  const target = graph.getNodeAttributes(edge.target);
6703
- if (target.type !== import_types9.NodeType.DatabaseNode || target.engine !== engine) continue;
6789
+ if (target.type !== import_types10.NodeType.DatabaseNode || target.engine !== engine) continue;
6704
6790
  matches.add(edge.target);
6705
6791
  }
6706
6792
  }
@@ -6715,7 +6801,7 @@ function ensureFrontierNode(graph, host, ts) {
6715
6801
  }
6716
6802
  const node = {
6717
6803
  id,
6718
- type: import_types9.NodeType.FrontierNode,
6804
+ type: import_types10.NodeType.FrontierNode,
6719
6805
  name: host,
6720
6806
  host,
6721
6807
  firstObserved: ts,
@@ -6768,11 +6854,11 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
6768
6854
  };
6769
6855
  const updated = {
6770
6856
  ...existing,
6771
- provenance: import_types9.Provenance.OBSERVED,
6857
+ provenance: import_types10.Provenance.OBSERVED,
6772
6858
  lastObserved: ts,
6773
6859
  callCount: newSpanCount,
6774
6860
  signal: newSignal,
6775
- confidence: (0, import_types9.confidenceForObservedSignal)(newSignal),
6861
+ confidence: (0, import_types10.confidenceForObservedSignal)(newSignal),
6776
6862
  grain
6777
6863
  // backfills legacy edges that predate ADR-142
6778
6864
  };
@@ -6795,8 +6881,8 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
6795
6881
  source,
6796
6882
  target,
6797
6883
  type,
6798
- provenance: import_types9.Provenance.OBSERVED,
6799
- confidence: (0, import_types9.confidenceForObservedSignal)(signal),
6884
+ provenance: import_types10.Provenance.OBSERVED,
6885
+ confidence: (0, import_types10.confidenceForObservedSignal)(signal),
6800
6886
  lastObserved: ts,
6801
6887
  callCount: 1,
6802
6888
  signal,
@@ -6818,9 +6904,9 @@ function stitchTrace(graph, sourceServiceId, ts) {
6818
6904
  const outbound = graph.outboundEdges(nodeId);
6819
6905
  for (const edgeId of outbound) {
6820
6906
  const edge = graph.getEdgeAttributes(edgeId);
6821
- if (edge.provenance !== import_types9.Provenance.EXTRACTED) continue;
6907
+ if (edge.provenance !== import_types10.Provenance.EXTRACTED) continue;
6822
6908
  if (!STITCH_EDGE_TYPES.has(edge.type)) continue;
6823
- if (graph.hasEdge((0, import_types9.observedEdgeId)(edge.source, edge.target, edge.type))) continue;
6909
+ if (graph.hasEdge((0, import_types10.observedEdgeId)(edge.source, edge.target, edge.type))) continue;
6824
6910
  upsertInferredEdge(graph, edge.type, edge.source, edge.target, ts);
6825
6911
  if (!visited.has(edge.target)) {
6826
6912
  visited.add(edge.target);
@@ -6842,7 +6928,7 @@ function upsertInferredEdge(graph, type, source, target, ts) {
6842
6928
  source,
6843
6929
  target,
6844
6930
  type,
6845
- provenance: import_types9.Provenance.INFERRED,
6931
+ provenance: import_types10.Provenance.INFERRED,
6846
6932
  confidence: INFERRED_CONFIDENCE,
6847
6933
  lastObserved: ts
6848
6934
  };
@@ -6856,7 +6942,7 @@ function emitIncidentEvent(project, ev) {
6856
6942
  incidentId: ev.id,
6857
6943
  affectedNode: ev.affectedNode,
6858
6944
  service: ev.service,
6859
- incidentKind: (0, import_types9.incidentKindOf)(ev),
6945
+ incidentKind: (0, import_types10.incidentKindOf)(ev),
6860
6946
  at: ev.timestamp
6861
6947
  }
6862
6948
  });
@@ -6885,7 +6971,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
6885
6971
  const canonicalService = serviceNodeName(graph, span) ?? span.service;
6886
6972
  const recovered = !trusted;
6887
6973
  if (graph) {
6888
- const fusedFileId = (0, import_types9.fileId)(canonicalService, relPath);
6974
+ const fusedFileId = (0, import_types10.fileId)(canonicalService, relPath);
6889
6975
  if (graph.hasNode(fusedFileId)) {
6890
6976
  const node = landObservedSymbol(
6891
6977
  graph,
@@ -6905,7 +6991,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
6905
6991
  }
6906
6992
  if (recovered) return null;
6907
6993
  }
6908
- return { affectedNode: (0, import_types9.fileId)(span.service, relPath) };
6994
+ return { affectedNode: (0, import_types10.fileId)(span.service, relPath) };
6909
6995
  }
6910
6996
  function serviceNodeName(graph, span) {
6911
6997
  if (!graph) return void 0;
@@ -6922,7 +7008,7 @@ function stacktraceCallSite(span, serviceNode, scanPath) {
6922
7008
  return { relPath, line: frame.line, ...frame.fn ? { fn: frame.fn } : {} };
6923
7009
  }
6924
7010
  function incidentLocus(span, graph, scanPath) {
6925
- const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0, import_types9.serviceId)(span.service, span.env);
7011
+ const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0, import_types10.serviceId)(span.service, span.env);
6926
7012
  const serviceNode = graph && graph.hasNode(sid) ? graph.getNodeAttributes(sid) : void 0;
6927
7013
  const callSite = callSiteFromSpan(span, serviceNode, scanPath);
6928
7014
  if (callSite) {
@@ -7113,7 +7199,7 @@ function findRouteNodeByHttpRoute(graph, serviceName, method, httpRoute) {
7113
7199
  graph.forEachNode((id, attrs) => {
7114
7200
  if (found) return;
7115
7201
  const a = attrs;
7116
- if (a.type !== import_types9.NodeType.RouteNode || a.service !== serviceName) return;
7202
+ if (a.type !== import_types10.NodeType.RouteNode || a.service !== serviceName) return;
7117
7203
  if (m && a.method !== "ALL" && a.method !== m) return;
7118
7204
  if (normalizePathTemplate(a.pathTemplate) === target) found = id;
7119
7205
  });
@@ -7146,7 +7232,7 @@ async function handleSpan(ctx, span) {
7146
7232
  let targetId;
7147
7233
  if (host) {
7148
7234
  ensureDatabaseNode(ctx.graph, host, span.dbSystem);
7149
- targetId = (0, import_types9.databaseId)(host);
7235
+ targetId = (0, import_types10.databaseId)(host);
7150
7236
  } else {
7151
7237
  const declared = findDeclaredDatabaseForService(ctx.graph, sourceId, span.dbSystem);
7152
7238
  if (declared) {
@@ -7163,7 +7249,7 @@ async function handleSpan(ctx, span) {
7163
7249
  }
7164
7250
  const result = upsertObservedEdge(
7165
7251
  ctx.graph,
7166
- import_types9.EdgeType.CONNECTS_TO,
7252
+ import_types10.EdgeType.CONNECTS_TO,
7167
7253
  observedSource(),
7168
7254
  targetId,
7169
7255
  ts,
@@ -7177,7 +7263,7 @@ async function handleSpan(ctx, span) {
7177
7263
  const collectionId = ensureInfraNode(ctx.graph, "mongodb-collection", span.dbCollection, "self");
7178
7264
  upsertObservedEdge(
7179
7265
  ctx.graph,
7180
- import_types9.EdgeType.CALLS,
7266
+ import_types10.EdgeType.CALLS,
7181
7267
  observedSource(),
7182
7268
  collectionId,
7183
7269
  ts,
@@ -7191,7 +7277,7 @@ async function handleSpan(ctx, span) {
7191
7277
  const tableId = ensureInfraNode(ctx.graph, "sql-table", span.dbTable, "self");
7192
7278
  upsertObservedEdge(
7193
7279
  ctx.graph,
7194
- import_types9.EdgeType.CALLS,
7280
+ import_types10.EdgeType.CALLS,
7195
7281
  observedSource(),
7196
7282
  tableId,
7197
7283
  ts,
@@ -7209,7 +7295,7 @@ async function handleSpan(ctx, span) {
7209
7295
  span.messagingSystem,
7210
7296
  span.messagingDestination
7211
7297
  );
7212
- const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ? import_types9.EdgeType.CONSUMES_FROM : import_types9.EdgeType.PUBLISHES_TO;
7298
+ const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ? import_types10.EdgeType.CONSUMES_FROM : import_types10.EdgeType.PUBLISHES_TO;
7213
7299
  const result = upsertObservedEdge(
7214
7300
  ctx.graph,
7215
7301
  edgeType,
@@ -7231,7 +7317,7 @@ async function handleSpan(ctx, span) {
7231
7317
  );
7232
7318
  const result = upsertObservedEdge(
7233
7319
  ctx.graph,
7234
- import_types9.EdgeType.CONTAINS,
7320
+ import_types10.EdgeType.CONTAINS,
7235
7321
  observedSource(),
7236
7322
  targetId,
7237
7323
  ts,
@@ -7245,7 +7331,7 @@ async function handleSpan(ctx, span) {
7245
7331
  const targetId = ensureGrpcMethodNode(ctx.graph, span.rpcService, span.rpcMethod);
7246
7332
  const result = upsertObservedEdge(
7247
7333
  ctx.graph,
7248
- import_types9.EdgeType.CONTAINS,
7334
+ import_types10.EdgeType.CONTAINS,
7249
7335
  observedSource(),
7250
7336
  targetId,
7251
7337
  ts,
@@ -7263,7 +7349,7 @@ async function handleSpan(ctx, span) {
7263
7349
  );
7264
7350
  const result = upsertObservedEdge(
7265
7351
  ctx.graph,
7266
- import_types9.EdgeType.CONNECTS_TO,
7352
+ import_types10.EdgeType.CONNECTS_TO,
7267
7353
  observedSource(),
7268
7354
  targetId,
7269
7355
  ts,
@@ -7281,7 +7367,7 @@ async function handleSpan(ctx, span) {
7281
7367
  if (targetId && targetId !== sourceId) {
7282
7368
  upsertObservedEdge(
7283
7369
  ctx.graph,
7284
- import_types9.EdgeType.CALLS,
7370
+ import_types10.EdgeType.CALLS,
7285
7371
  observedSource(),
7286
7372
  targetId,
7287
7373
  ts,
@@ -7296,7 +7382,7 @@ async function handleSpan(ctx, span) {
7296
7382
  const frontierNodeId = ensureFrontierNode(ctx.graph, host, ts);
7297
7383
  upsertObservedEdge(
7298
7384
  ctx.graph,
7299
- import_types9.EdgeType.CALLS,
7385
+ import_types10.EdgeType.CALLS,
7300
7386
  observedSource(),
7301
7387
  frontierNodeId,
7302
7388
  ts,
@@ -7324,7 +7410,7 @@ async function handleSpan(ctx, span) {
7324
7410
  } : void 0;
7325
7411
  upsertObservedEdge(
7326
7412
  ctx.graph,
7327
- import_types9.EdgeType.CALLS,
7413
+ import_types10.EdgeType.CALLS,
7328
7414
  fallbackSource,
7329
7415
  sourceId,
7330
7416
  ts,
@@ -7346,7 +7432,7 @@ async function handleSpan(ctx, span) {
7346
7432
  );
7347
7433
  if (routeNodeId) {
7348
7434
  const routeSvc = ctx.graph.getNodeAttributes(routeNodeId).service;
7349
- upsertObservedEdge(ctx.graph, import_types9.EdgeType.CONTAINS, (0, import_types9.serviceId)(routeSvc), routeNodeId, ts, isError, void 0, durationMs, errorDetail);
7435
+ upsertObservedEdge(ctx.graph, import_types10.EdgeType.CONTAINS, (0, import_types10.serviceId)(routeSvc), routeNodeId, ts, isError, void 0, durationMs, errorDetail);
7350
7436
  }
7351
7437
  }
7352
7438
  if (span.statusCode === 2) {
@@ -7376,7 +7462,7 @@ function promoteFrontierNodes(graph, opts = {}) {
7376
7462
  const aliasIndex = /* @__PURE__ */ new Map();
7377
7463
  graph.forEachNode((id, attrs) => {
7378
7464
  const a = attrs;
7379
- if (a.type !== import_types9.NodeType.ServiceNode) return;
7465
+ if (a.type !== import_types10.NodeType.ServiceNode) return;
7380
7466
  aliasIndex.set(a.name, id);
7381
7467
  if (a.aliases) {
7382
7468
  for (const alias of a.aliases) aliasIndex.set(alias, id);
@@ -7385,7 +7471,7 @@ function promoteFrontierNodes(graph, opts = {}) {
7385
7471
  const toPromote = [];
7386
7472
  graph.forEachNode((id, attrs) => {
7387
7473
  const a = attrs;
7388
- if (a.type !== import_types9.NodeType.FrontierNode) return;
7474
+ if (a.type !== import_types10.NodeType.FrontierNode) return;
7389
7475
  const target = aliasIndex.get(a.host);
7390
7476
  if (!target) return;
7391
7477
  if (target === id) return;
@@ -7407,15 +7493,15 @@ function promoteFrontierNodes(graph, opts = {}) {
7407
7493
  }
7408
7494
  function stageFrontierEdge(graph, source, target, type) {
7409
7495
  if (!graph.hasNode(source) || !graph.hasNode(target)) return false;
7410
- if (graph.hasEdge((0, import_types9.observedEdgeId)(source, target, type))) return false;
7411
- const key = (0, import_types9.frontierEdgeId)(source, target, type);
7496
+ if (graph.hasEdge((0, import_types10.observedEdgeId)(source, target, type))) return false;
7497
+ const key = (0, import_types10.frontierEdgeId)(source, target, type);
7412
7498
  if (graph.hasEdge(key)) return false;
7413
7499
  graph.addEdgeWithKey(key, source, target, {
7414
7500
  id: key,
7415
7501
  source,
7416
7502
  target,
7417
7503
  type,
7418
- provenance: import_types9.Provenance.FRONTIER
7504
+ provenance: import_types10.Provenance.FRONTIER
7419
7505
  });
7420
7506
  return true;
7421
7507
  }
@@ -7423,8 +7509,8 @@ function promoteFrontierEdges(graph) {
7423
7509
  const graduated = [];
7424
7510
  graph.forEachEdge((edgeId, attrs) => {
7425
7511
  const e = attrs;
7426
- if (e.provenance !== import_types9.Provenance.FRONTIER) return;
7427
- if (graph.hasEdge((0, import_types9.observedEdgeId)(e.source, e.target, e.type))) {
7512
+ if (e.provenance !== import_types10.Provenance.FRONTIER) return;
7513
+ if (graph.hasEdge((0, import_types10.observedEdgeId)(e.source, e.target, e.type))) {
7428
7514
  graduated.push(edgeId);
7429
7515
  }
7430
7516
  });
@@ -7445,7 +7531,7 @@ function rewireFrontierEdges(graph, frontierId2, serviceId17) {
7445
7531
  }
7446
7532
  function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
7447
7533
  graph.dropEdge(oldEdgeId);
7448
- const newId = edge.provenance === import_types9.Provenance.OBSERVED ? (0, import_types9.observedEdgeId)(newSource, newTarget, edge.type) : edge.provenance === import_types9.Provenance.INFERRED ? (0, import_types9.inferredEdgeId)(newSource, newTarget, edge.type) : (0, import_types9.extractedEdgeId)(newSource, newTarget, edge.type);
7534
+ const newId = edge.provenance === import_types10.Provenance.OBSERVED ? (0, import_types10.observedEdgeId)(newSource, newTarget, edge.type) : edge.provenance === import_types10.Provenance.INFERRED ? (0, import_types10.inferredEdgeId)(newSource, newTarget, edge.type) : (0, import_types10.extractedEdgeId)(newSource, newTarget, edge.type);
7449
7535
  if (graph.hasEdge(newId)) {
7450
7536
  const existing = graph.getEdgeAttributes(newId);
7451
7537
  const merged = {
@@ -7479,12 +7565,12 @@ async function markStaleEdges(graph, options = {}) {
7479
7565
  const project = options.project ?? DEFAULT_PROJECT;
7480
7566
  graph.forEachEdge((id, attrs) => {
7481
7567
  const e = attrs;
7482
- if (e.provenance !== import_types9.Provenance.OBSERVED) return;
7568
+ if (e.provenance !== import_types10.Provenance.OBSERVED) return;
7483
7569
  if (!e.lastObserved) return;
7484
7570
  const threshold = thresholdForEdgeType(e.type, thresholds);
7485
7571
  const age = now - new Date(e.lastObserved).getTime();
7486
7572
  if (age > threshold) {
7487
- const updated = { ...e, provenance: import_types9.Provenance.STALE, confidence: 0.3 };
7573
+ const updated = { ...e, provenance: import_types10.Provenance.STALE, confidence: 0.3 };
7488
7574
  graph.replaceEdgeAttributes(id, updated);
7489
7575
  events.push({
7490
7576
  edgeId: id,
@@ -7501,8 +7587,8 @@ async function markStaleEdges(graph, options = {}) {
7501
7587
  project,
7502
7588
  payload: {
7503
7589
  edgeId: id,
7504
- from: import_types9.Provenance.OBSERVED,
7505
- to: import_types9.Provenance.STALE
7590
+ from: import_types10.Provenance.OBSERVED,
7591
+ to: import_types10.Provenance.STALE
7506
7592
  }
7507
7593
  });
7508
7594
  }
@@ -7650,6 +7736,7 @@ function describeZodIssues(error2) {
7650
7736
  return error2.issues.map((issue) => issue.path.length > 0 ? `${issue.path.join(".")}: ${issue.message}` : issue.message).join("; ");
7651
7737
  }
7652
7738
  function mergeSnapshot(graph, snapshot) {
7739
+ invalidateSourceBaseline(graph);
7653
7740
  const exported = snapshot.graph;
7654
7741
  const incomingNodes = Array.isArray(exported.nodes) ? exported.nodes : [];
7655
7742
  const incomingEdges = Array.isArray(exported.edges) ? exported.edges : [];
@@ -7658,7 +7745,7 @@ function mergeSnapshot(graph, snapshot) {
7658
7745
  const validEdges = [];
7659
7746
  for (const node of incomingNodes) {
7660
7747
  if (node.attributes === void 0) continue;
7661
- const parsed = import_types9.GraphNodeSchema.safeParse(node.attributes);
7748
+ const parsed = import_types10.GraphNodeSchema.safeParse(node.attributes);
7662
7749
  if (!parsed.success) {
7663
7750
  issues.push(`node "${node.key}": ${describeZodIssues(parsed.error)}`);
7664
7751
  continue;
@@ -7667,7 +7754,7 @@ function mergeSnapshot(graph, snapshot) {
7667
7754
  }
7668
7755
  for (const edge of incomingEdges) {
7669
7756
  if (edge.attributes === void 0) continue;
7670
- const parsed = import_types9.GraphEdgeSchema.safeParse(edge.attributes);
7757
+ const parsed = import_types10.GraphEdgeSchema.safeParse(edge.attributes);
7671
7758
  if (!parsed.success) {
7672
7759
  const label = edge.key ?? `${edge.source}->${edge.target}`;
7673
7760
  issues.push(`edge "${label}": ${describeZodIssues(parsed.error)}`);
@@ -7701,7 +7788,7 @@ var import_node_fs21 = require("fs");
7701
7788
  var import_node_path23 = __toESM(require("path"), 1);
7702
7789
  var import_ignore2 = __toESM(require("ignore"), 1);
7703
7790
  var import_minimatch2 = require("minimatch");
7704
- var import_types19 = require("@neat.is/types");
7791
+ var import_types20 = require("@neat.is/types");
7705
7792
 
7706
7793
  // src/extract/python.ts
7707
7794
  init_cjs_shims();
@@ -7774,7 +7861,7 @@ function pythonToPackage(service) {
7774
7861
  init_cjs_shims();
7775
7862
  var import_node_fs12 = require("fs");
7776
7863
  var import_node_path13 = __toESM(require("path"), 1);
7777
- var import_types10 = require("@neat.is/types");
7864
+ var import_types11 = require("@neat.is/types");
7778
7865
  function parseGoMod(source) {
7779
7866
  const module2 = source.match(/^\s*module\s+(\S+)\s*$/m)?.[1];
7780
7867
  if (!module2) return null;
@@ -7810,8 +7897,8 @@ async function discoverGoService(scanPath, dir) {
7810
7897
  const pkg = { name, dependencies: mod.dependencies };
7811
7898
  const framework = goFramework(mod.dependencies);
7812
7899
  const node = {
7813
- id: (0, import_types10.serviceId)(name),
7814
- type: import_types10.NodeType.ServiceNode,
7900
+ id: (0, import_types11.serviceId)(name),
7901
+ type: import_types11.NodeType.ServiceNode,
7815
7902
  name,
7816
7903
  language: "go",
7817
7904
  dependencies: mod.dependencies,
@@ -7825,7 +7912,7 @@ async function discoverGoService(scanPath, dir) {
7825
7912
  init_cjs_shims();
7826
7913
  var import_node_fs13 = require("fs");
7827
7914
  var import_node_path14 = __toESM(require("path"), 1);
7828
- var import_types11 = require("@neat.is/types");
7915
+ var import_types12 = require("@neat.is/types");
7829
7916
  function parseGemfile(source) {
7830
7917
  const dependencies = {};
7831
7918
  for (const raw of source.split(/\r?\n/)) {
@@ -7849,8 +7936,8 @@ async function discoverRubyService(scanPath, dir) {
7849
7936
  const name = import_node_path14.default.basename(dir);
7850
7937
  const pkg = { name, dependencies: gemfile.dependencies };
7851
7938
  const node = {
7852
- id: (0, import_types11.serviceId)(name),
7853
- type: import_types11.NodeType.ServiceNode,
7939
+ id: (0, import_types12.serviceId)(name),
7940
+ type: import_types12.NodeType.ServiceNode,
7854
7941
  name,
7855
7942
  language: "ruby",
7856
7943
  dependencies: gemfile.dependencies,
@@ -7863,7 +7950,7 @@ async function discoverRubyService(scanPath, dir) {
7863
7950
  // src/extract/php.ts
7864
7951
  init_cjs_shims();
7865
7952
  var import_node_path15 = __toESM(require("path"), 1);
7866
- var import_types12 = require("@neat.is/types");
7953
+ var import_types13 = require("@neat.is/types");
7867
7954
  function parseComposerJson(composer) {
7868
7955
  return {
7869
7956
  dependencies: {
@@ -7883,8 +7970,8 @@ async function discoverPhpService(scanPath, dir) {
7883
7970
  const name = import_node_path15.default.basename(dir);
7884
7971
  const pkg = { name, dependencies };
7885
7972
  const node = {
7886
- id: (0, import_types12.serviceId)(name),
7887
- type: import_types12.NodeType.ServiceNode,
7973
+ id: (0, import_types13.serviceId)(name),
7974
+ type: import_types13.NodeType.ServiceNode,
7888
7975
  name,
7889
7976
  language: "php",
7890
7977
  dependencies,
@@ -7898,7 +7985,7 @@ async function discoverPhpService(scanPath, dir) {
7898
7985
  init_cjs_shims();
7899
7986
  var import_node_fs14 = require("fs");
7900
7987
  var import_node_path16 = __toESM(require("path"), 1);
7901
- var import_types13 = require("@neat.is/types");
7988
+ var import_types14 = require("@neat.is/types");
7902
7989
  var CSHARP_PROJECT_EXTS = /* @__PURE__ */ new Set([".csproj", ".sln"]);
7903
7990
  async function projectFiles(dir) {
7904
7991
  const entries = await import_node_fs14.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
@@ -7945,8 +8032,8 @@ async function discoverCsharpService(scanPath, dir) {
7945
8032
  }
7946
8033
  const pkg = { name, dependencies };
7947
8034
  const node = {
7948
- id: (0, import_types13.serviceId)(name),
7949
- type: import_types13.NodeType.ServiceNode,
8035
+ id: (0, import_types14.serviceId)(name),
8036
+ type: import_types14.NodeType.ServiceNode,
7950
8037
  name,
7951
8038
  language: "csharp",
7952
8039
  dependencies,
@@ -7961,7 +8048,7 @@ async function discoverCsharpService(scanPath, dir) {
7961
8048
  init_cjs_shims();
7962
8049
  var import_node_fs15 = require("fs");
7963
8050
  var import_node_path17 = __toESM(require("path"), 1);
7964
- var import_types14 = require("@neat.is/types");
8051
+ var import_types15 = require("@neat.is/types");
7965
8052
  var JAVA_MANIFESTS = ["pom.xml", "build.gradle", "build.gradle.kts"];
7966
8053
  async function hasJavaManifest(dir) {
7967
8054
  for (const manifest of JAVA_MANIFESTS) {
@@ -8016,8 +8103,8 @@ async function discoverJavaService(scanPath, dir) {
8016
8103
  const dependencies = manifest.dependencies;
8017
8104
  const pkg = { name, dependencies };
8018
8105
  const node = {
8019
- id: (0, import_types14.serviceId)(name),
8020
- type: import_types14.NodeType.ServiceNode,
8106
+ id: (0, import_types15.serviceId)(name),
8107
+ type: import_types15.NodeType.ServiceNode,
8021
8108
  name,
8022
8109
  language: "java",
8023
8110
  dependencies,
@@ -8030,7 +8117,7 @@ async function discoverJavaService(scanPath, dir) {
8030
8117
  init_cjs_shims();
8031
8118
  var import_node_fs16 = require("fs");
8032
8119
  var import_node_path18 = __toESM(require("path"), 1);
8033
- var import_types15 = require("@neat.is/types");
8120
+ var import_types16 = require("@neat.is/types");
8034
8121
  var KOTLIN_SOURCE_EXT = ".kt";
8035
8122
  var JAVA_SOURCE_EXT = ".java";
8036
8123
  var SOURCE_PROBE_MAX_DEPTH = 8;
@@ -8081,8 +8168,8 @@ async function discoverKotlinService(scanPath, dir) {
8081
8168
  const dependencies = manifest.dependencies;
8082
8169
  const pkg = { name, dependencies };
8083
8170
  const node = {
8084
- id: (0, import_types15.serviceId)(name),
8085
- type: import_types15.NodeType.ServiceNode,
8171
+ id: (0, import_types16.serviceId)(name),
8172
+ type: import_types16.NodeType.ServiceNode,
8086
8173
  name,
8087
8174
  language: "kotlin",
8088
8175
  dependencies,
@@ -8096,7 +8183,7 @@ init_cjs_shims();
8096
8183
  var import_node_fs17 = require("fs");
8097
8184
  var import_node_path19 = __toESM(require("path"), 1);
8098
8185
  var import_smol_toml2 = require("smol-toml");
8099
- var import_types16 = require("@neat.is/types");
8186
+ var import_types17 = require("@neat.is/types");
8100
8187
  var CARGO_MANIFEST = "Cargo.toml";
8101
8188
  async function hasRustManifest(dir) {
8102
8189
  return exists(import_node_path19.default.join(dir, CARGO_MANIFEST));
@@ -8131,8 +8218,8 @@ async function discoverRustService(scanPath, dir) {
8131
8218
  const dependencies = manifest.dependencies;
8132
8219
  const pkg = { name, dependencies };
8133
8220
  const node = {
8134
- id: (0, import_types16.serviceId)(name),
8135
- type: import_types16.NodeType.ServiceNode,
8221
+ id: (0, import_types17.serviceId)(name),
8222
+ type: import_types17.NodeType.ServiceNode,
8136
8223
  name,
8137
8224
  language: "rust",
8138
8225
  dependencies,
@@ -8145,7 +8232,7 @@ async function discoverRustService(scanPath, dir) {
8145
8232
  init_cjs_shims();
8146
8233
  var import_node_fs18 = require("fs");
8147
8234
  var import_node_path20 = __toESM(require("path"), 1);
8148
- var import_types17 = require("@neat.is/types");
8235
+ var import_types18 = require("@neat.is/types");
8149
8236
  var CMAKE_MANIFEST = "CMakeLists.txt";
8150
8237
  async function hasCppManifest(dir) {
8151
8238
  return exists(import_node_path20.default.join(dir, CMAKE_MANIFEST));
@@ -8163,8 +8250,8 @@ async function discoverCppService(scanPath, dir) {
8163
8250
  const dependencies = {};
8164
8251
  const pkg = { name, dependencies };
8165
8252
  const node = {
8166
- id: (0, import_types17.serviceId)(name),
8167
- type: import_types17.NodeType.ServiceNode,
8253
+ id: (0, import_types18.serviceId)(name),
8254
+ type: import_types18.NodeType.ServiceNode,
8168
8255
  name,
8169
8256
  language: "cpp",
8170
8257
  dependencies,
@@ -8177,7 +8264,7 @@ async function discoverCppService(scanPath, dir) {
8177
8264
  init_cjs_shims();
8178
8265
  var import_node_fs19 = require("fs");
8179
8266
  var import_node_path21 = __toESM(require("path"), 1);
8180
- var import_types18 = require("@neat.is/types");
8267
+ var import_types19 = require("@neat.is/types");
8181
8268
  function languageForSourceExt(ext) {
8182
8269
  switch (ext) {
8183
8270
  case ".py":
@@ -8263,8 +8350,8 @@ async function discoverDockerfileService(scanPath, dir) {
8263
8350
  const name = import_node_path21.default.basename(dir);
8264
8351
  const pkg = { name, dependencies: {} };
8265
8352
  const node = {
8266
- id: (0, import_types18.serviceId)(name),
8267
- type: import_types18.NodeType.ServiceNode,
8353
+ id: (0, import_types19.serviceId)(name),
8354
+ type: import_types19.NodeType.ServiceNode,
8268
8355
  name,
8269
8356
  language,
8270
8357
  dependencies: {},
@@ -8458,8 +8545,8 @@ async function discoverNodeService(scanPath, dir) {
8458
8545
  const framework = detectJsFramework(pkg);
8459
8546
  const language = await detectJsServiceLanguage(dir, pkg);
8460
8547
  const node = {
8461
- id: (0, import_types19.serviceId)(pkg.name),
8462
- type: import_types19.NodeType.ServiceNode,
8548
+ id: (0, import_types20.serviceId)(pkg.name),
8549
+ type: import_types20.NodeType.ServiceNode,
8463
8550
  name: pkg.name,
8464
8551
  language,
8465
8552
  version: pkg.version,
@@ -8475,8 +8562,8 @@ async function discoverPyService(scanPath, dir) {
8475
8562
  if (!py) return null;
8476
8563
  const pkg = pythonToPackage(py);
8477
8564
  const node = {
8478
- id: (0, import_types19.serviceId)(py.name),
8479
- type: import_types19.NodeType.ServiceNode,
8565
+ id: (0, import_types20.serviceId)(py.name),
8566
+ type: import_types20.NodeType.ServiceNode,
8480
8567
  name: py.name,
8481
8568
  language: "python",
8482
8569
  version: py.version,
@@ -8595,7 +8682,7 @@ init_cjs_shims();
8595
8682
  var import_node_path24 = __toESM(require("path"), 1);
8596
8683
  var import_node_fs22 = require("fs");
8597
8684
  var import_yaml2 = require("yaml");
8598
- var import_types20 = require("@neat.is/types");
8685
+ var import_types21 = require("@neat.is/types");
8599
8686
  var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
8600
8687
  "Service",
8601
8688
  "Deployment",
@@ -8605,7 +8692,7 @@ var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
8605
8692
  function addAliases(graph, serviceId17, candidates) {
8606
8693
  if (!graph.hasNode(serviceId17)) return;
8607
8694
  const node = graph.getNodeAttributes(serviceId17);
8608
- if (node.type !== import_types20.NodeType.ServiceNode) return;
8695
+ if (node.type !== import_types21.NodeType.ServiceNode) return;
8609
8696
  const set = new Set(node.aliases ?? []);
8610
8697
  for (const c of candidates) {
8611
8698
  if (!c) continue;
@@ -8795,7 +8882,7 @@ var import_tree_sitter_java = __toESM(require("tree-sitter-java"), 1);
8795
8882
  var import_tree_sitter_kotlin = __toESM(require("tree-sitter-kotlin"), 1);
8796
8883
  var import_tree_sitter_rust2 = __toESM(require("tree-sitter-rust"), 1);
8797
8884
  var import_tree_sitter_cpp = __toESM(require("tree-sitter-cpp"), 1);
8798
- var import_types21 = require("@neat.is/types");
8885
+ var import_types22 = require("@neat.is/types");
8799
8886
  var PARSE_CHUNK3 = 16384;
8800
8887
  var GRAMMAR_BY_EXT = {
8801
8888
  ".ts": import_tree_sitter_typescript.default.typescript,
@@ -8848,7 +8935,9 @@ function collectSymbolDefs(root) {
8848
8935
  kind,
8849
8936
  qualname,
8850
8937
  startLine: node.startPosition.row + 1,
8851
- endLine: node.endPosition.row + 1
8938
+ endLine: node.endPosition.row + 1,
8939
+ startIndex: node.startIndex,
8940
+ endIndex: node.endIndex
8852
8941
  });
8853
8942
  };
8854
8943
  const visit = (node, classCtx) => {
@@ -8907,7 +8996,9 @@ function collectPythonSymbolDefs(root) {
8907
8996
  kind,
8908
8997
  qualname,
8909
8998
  startLine: node.startPosition.row + 1,
8910
- endLine: node.endPosition.row + 1
8999
+ endLine: node.endPosition.row + 1,
9000
+ startIndex: node.startIndex,
9001
+ endIndex: node.endIndex
8911
9002
  });
8912
9003
  };
8913
9004
  const visit = (node, classCtx) => {
@@ -8980,7 +9071,9 @@ function collectGoSymbolDefs(root) {
8980
9071
  kind,
8981
9072
  qualname,
8982
9073
  startLine: node.startPosition.row + 1,
8983
- endLine: node.endPosition.row + 1
9074
+ endLine: node.endPosition.row + 1,
9075
+ startIndex: node.startIndex,
9076
+ endIndex: node.endIndex
8984
9077
  });
8985
9078
  };
8986
9079
  const visit = (node) => {
@@ -9014,7 +9107,9 @@ function collectRubySymbolDefs(root) {
9014
9107
  kind,
9015
9108
  qualname,
9016
9109
  startLine: node.startPosition.row + 1,
9017
- endLine: node.endPosition.row + 1
9110
+ endLine: node.endPosition.row + 1,
9111
+ startIndex: node.startIndex,
9112
+ endIndex: node.endIndex
9018
9113
  });
9019
9114
  };
9020
9115
  const nameText = (node) => node.childForFieldName("name")?.text.replace(/::/g, ".");
@@ -9065,7 +9160,9 @@ function collectPhpSymbolDefs(root) {
9065
9160
  kind,
9066
9161
  qualname,
9067
9162
  startLine: node.startPosition.row + 1,
9068
- endLine: node.endPosition.row + 1
9163
+ endLine: node.endPosition.row + 1,
9164
+ startIndex: node.startIndex,
9165
+ endIndex: node.endIndex
9069
9166
  });
9070
9167
  };
9071
9168
  const dot = (s) => s.replace(/\\/g, ".").replace(/::/g, ".").replace(/^\.+/, "");
@@ -9131,7 +9228,9 @@ function collectCsharpSymbolDefs(root) {
9131
9228
  kind,
9132
9229
  qualname,
9133
9230
  startLine: node.startPosition.row + 1,
9134
- endLine: node.endPosition.row + 1
9231
+ endLine: node.endPosition.row + 1,
9232
+ startIndex: node.startIndex,
9233
+ endIndex: node.endIndex
9135
9234
  });
9136
9235
  };
9137
9236
  const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
@@ -9193,7 +9292,9 @@ function collectJavaSymbolDefs(root) {
9193
9292
  kind,
9194
9293
  qualname,
9195
9294
  startLine: node.startPosition.row + 1,
9196
- endLine: node.endPosition.row + 1
9295
+ endLine: node.endPosition.row + 1,
9296
+ startIndex: node.startIndex,
9297
+ endIndex: node.endIndex
9197
9298
  });
9198
9299
  };
9199
9300
  const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
@@ -9250,7 +9351,9 @@ function collectKotlinSymbolDefs(root) {
9250
9351
  kind,
9251
9352
  qualname,
9252
9353
  startLine: node.startPosition.row + 1,
9253
- endLine: node.endPosition.row + 1
9354
+ endLine: node.endPosition.row + 1,
9355
+ startIndex: node.startIndex,
9356
+ endIndex: node.endIndex
9254
9357
  });
9255
9358
  };
9256
9359
  const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
@@ -9320,7 +9423,9 @@ function collectRustSymbolDefs(root) {
9320
9423
  kind,
9321
9424
  qualname,
9322
9425
  startLine: node.startPosition.row + 1,
9323
- endLine: node.endPosition.row + 1
9426
+ endLine: node.endPosition.row + 1,
9427
+ startIndex: node.startIndex,
9428
+ endIndex: node.endIndex
9324
9429
  });
9325
9430
  };
9326
9431
  const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
@@ -9388,7 +9493,9 @@ function collectCppSymbolDefs(root) {
9388
9493
  kind,
9389
9494
  qualname,
9390
9495
  startLine: node.startPosition.row + 1,
9391
- endLine: node.endPosition.row + 1
9496
+ endLine: node.endPosition.row + 1,
9497
+ startIndex: node.startIndex,
9498
+ endIndex: node.endIndex
9392
9499
  });
9393
9500
  };
9394
9501
  const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
@@ -9516,6 +9623,22 @@ function disambiguate(defs) {
9516
9623
  return { def, disambiguator: ordinal };
9517
9624
  });
9518
9625
  }
9626
+ function utf8Offsets(content, defs) {
9627
+ if (content.includes("\uFFFD")) return /* @__PURE__ */ new Map();
9628
+ const indices = [...new Set(defs.flatMap(({ startIndex, endIndex }) => [startIndex, endIndex]))].sort(
9629
+ (a, b) => a - b
9630
+ );
9631
+ const offsets = /* @__PURE__ */ new Map();
9632
+ let cursor = 0;
9633
+ let bytes = 0;
9634
+ for (const index of indices) {
9635
+ if (index < cursor || index > content.length) return /* @__PURE__ */ new Map();
9636
+ bytes += Buffer.byteLength(content.slice(cursor, index), "utf8");
9637
+ offsets.set(index, bytes);
9638
+ cursor = index;
9639
+ }
9640
+ return offsets;
9641
+ }
9519
9642
  async function addSymbols(graph, services) {
9520
9643
  const parsers = /* @__PURE__ */ new Map();
9521
9644
  const parserForExt5 = (ext) => {
@@ -9539,47 +9662,59 @@ async function addSymbols(graph, services) {
9539
9662
  if (!parser) continue;
9540
9663
  const relPath = toPosix(import_node_path26.default.relative(service.dir, file.path));
9541
9664
  let defs;
9665
+ let completeParse;
9542
9666
  try {
9543
9667
  const tree = parseSource3(parser, file.content);
9544
9668
  defs = collectSymbolDefsForExt(ext, tree.rootNode);
9669
+ completeParse = !tree.rootNode.hasError;
9545
9670
  } catch (err) {
9546
9671
  recordExtractionError("symbol extraction", file.path, err);
9547
9672
  continue;
9548
9673
  }
9549
9674
  if (defs.length === 0) continue;
9550
- const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
9551
- graph,
9552
- service.pkg.name,
9553
- service.node.id,
9554
- relPath
9555
- );
9675
+ const offsets = completeParse ? utf8Offsets(file.content, defs) : /* @__PURE__ */ new Map();
9676
+ const {
9677
+ fileNodeId,
9678
+ nodesAdded: fn,
9679
+ edgesAdded: fe
9680
+ } = ensureFileNode(graph, service.pkg.name, service.node.id, relPath);
9556
9681
  nodesAdded += fn;
9557
9682
  edgesAdded += fe;
9558
9683
  for (const { def, disambiguator } of disambiguate(defs)) {
9559
- const sid = (0, import_types21.symbolId)(service.pkg.name, relPath, def.qualname, disambiguator);
9684
+ const sid = (0, import_types22.symbolId)(service.pkg.name, relPath, def.qualname, disambiguator);
9685
+ const startByte = offsets.get(def.startIndex);
9686
+ const endByte = offsets.get(def.endIndex);
9687
+ const precise = startByte !== void 0 && endByte !== void 0 && endByte > startByte ? { startByte, endByte } : {};
9688
+ const node = {
9689
+ id: sid,
9690
+ type: import_types22.NodeType.SymbolNode,
9691
+ kind: def.kind,
9692
+ qualname: def.qualname,
9693
+ span: { startLine: def.startLine, endLine: def.endLine, ...precise },
9694
+ service: service.pkg.name,
9695
+ relPath,
9696
+ discoveredVia: "static"
9697
+ };
9560
9698
  if (!graph.hasNode(sid)) {
9561
- const node = {
9562
- id: sid,
9563
- type: import_types21.NodeType.SymbolNode,
9564
- kind: def.kind,
9565
- qualname: def.qualname,
9566
- span: { startLine: def.startLine, endLine: def.endLine },
9567
- service: service.pkg.name,
9568
- relPath,
9569
- discoveredVia: "static"
9570
- };
9571
9699
  graph.addNode(sid, node);
9572
9700
  nodesAdded++;
9701
+ } else {
9702
+ const previous = graph.getNodeAttributes(sid);
9703
+ const discoveredVia = previous.discoveredVia === "otel" || previous.discoveredVia === "merged" ? "merged" : "static";
9704
+ const moved = previous.span.startLine !== node.span.startLine || previous.span.endLine !== node.span.endLine || previous.span.startByte !== node.span.startByte || previous.span.endByte !== node.span.endByte;
9705
+ if (moved || previous.kind !== node.kind || previous.qualname !== node.qualname || previous.discoveredVia !== discoveredVia || previous.service !== node.service || previous.relPath !== node.relPath) {
9706
+ graph.replaceNodeAttributes(sid, { ...previous, ...node, discoveredVia });
9707
+ }
9573
9708
  }
9574
- const containsId = (0, import_types21.extractedEdgeId)(fileNodeId, sid, import_types21.EdgeType.CONTAINS);
9709
+ const containsId = (0, import_types22.extractedEdgeId)(fileNodeId, sid, import_types22.EdgeType.CONTAINS);
9575
9710
  if (!graph.hasEdge(containsId)) {
9576
9711
  const edge = {
9577
9712
  id: containsId,
9578
9713
  source: fileNodeId,
9579
9714
  target: sid,
9580
- type: import_types21.EdgeType.CONTAINS,
9581
- provenance: import_types21.Provenance.EXTRACTED,
9582
- confidence: (0, import_types21.confidenceForExtracted)("structural"),
9715
+ type: import_types22.EdgeType.CONTAINS,
9716
+ provenance: import_types22.Provenance.EXTRACTED,
9717
+ confidence: (0, import_types22.confidenceForExtracted)("structural"),
9583
9718
  evidence: {
9584
9719
  file: relPath,
9585
9720
  line: def.startLine,
@@ -9599,7 +9734,7 @@ async function addSymbols(graph, services) {
9599
9734
  init_cjs_shims();
9600
9735
  var import_node_path27 = __toESM(require("path"), 1);
9601
9736
  var import_tree_sitter4 = __toESM(require("tree-sitter"), 1);
9602
- var import_types22 = require("@neat.is/types");
9737
+ var import_types23 = require("@neat.is/types");
9603
9738
  function extendsInfo(classHeritage) {
9604
9739
  for (let i = 0; i < classHeritage.namedChildCount; i++) {
9605
9740
  const child = classHeritage.namedChild(i);
@@ -9717,7 +9852,7 @@ async function addSymbolEdges(graph, services) {
9717
9852
  }
9718
9853
  const disambiguated = disambiguate(collectSymbolDefs(root));
9719
9854
  const locals = disambiguated.map(({ def, disambiguator }) => ({
9720
- sid: (0, import_types22.symbolId)(serviceName, relPath, def.qualname, disambiguator),
9855
+ sid: (0, import_types23.symbolId)(serviceName, relPath, def.qualname, disambiguator),
9721
9856
  qualname: def.qualname,
9722
9857
  kind: def.kind,
9723
9858
  startLine: def.startLine,
@@ -9746,10 +9881,10 @@ async function addSymbolEdges(graph, services) {
9746
9881
  if (local) return local.kind === wantKind ? local.sid : null;
9747
9882
  const imp = resolvedImports.get(name);
9748
9883
  if (imp) {
9749
- const candidate = (0, import_types22.symbolId)(serviceName, imp.targetRelPath, imp.importedName);
9884
+ const candidate = (0, import_types23.symbolId)(serviceName, imp.targetRelPath, imp.importedName);
9750
9885
  if (graph.hasNode(candidate)) {
9751
9886
  const node = graph.getNodeAttributes(candidate);
9752
- if (node.type === import_types22.NodeType.SymbolNode && node.kind === wantKind) return candidate;
9887
+ if (node.type === import_types23.NodeType.SymbolNode && node.kind === wantKind) return candidate;
9753
9888
  }
9754
9889
  }
9755
9890
  return null;
@@ -9776,7 +9911,7 @@ async function addSymbolEdges(graph, services) {
9776
9911
  sourceSid: self.sid,
9777
9912
  targetName: ext.name,
9778
9913
  wantKind: "class",
9779
- edgeType: import_types22.EdgeType.INHERITS,
9914
+ edgeType: import_types23.EdgeType.INHERITS,
9780
9915
  line: ext.line
9781
9916
  });
9782
9917
  }
@@ -9785,7 +9920,7 @@ async function addSymbolEdges(graph, services) {
9785
9920
  sourceSid: self.sid,
9786
9921
  targetName: impl.name,
9787
9922
  wantKind: "class",
9788
- edgeType: import_types22.EdgeType.IMPLEMENTS,
9923
+ edgeType: import_types23.EdgeType.IMPLEMENTS,
9789
9924
  line: impl.line
9790
9925
  });
9791
9926
  }
@@ -9801,7 +9936,7 @@ async function addSymbolEdges(graph, services) {
9801
9936
  sourceSid: caller.sid,
9802
9937
  targetName: fn.text,
9803
9938
  wantKind: "function",
9804
- edgeType: import_types22.EdgeType.CALLS,
9939
+ edgeType: import_types23.EdgeType.CALLS,
9805
9940
  line
9806
9941
  });
9807
9942
  }
@@ -9817,15 +9952,15 @@ async function addSymbolEdges(graph, services) {
9817
9952
  const targetSid = resolveTarget(req.targetName, req.wantKind);
9818
9953
  if (!targetSid) continue;
9819
9954
  if (targetSid === req.sourceSid) continue;
9820
- const edgeId = (0, import_types22.extractedEdgeId)(req.sourceSid, targetSid, req.edgeType);
9955
+ const edgeId = (0, import_types23.extractedEdgeId)(req.sourceSid, targetSid, req.edgeType);
9821
9956
  if (graph.hasEdge(edgeId)) continue;
9822
9957
  const edge = {
9823
9958
  id: edgeId,
9824
9959
  source: req.sourceSid,
9825
9960
  target: targetSid,
9826
9961
  type: req.edgeType,
9827
- provenance: import_types22.Provenance.EXTRACTED,
9828
- confidence: (0, import_types22.confidenceForExtracted)("structural"),
9962
+ provenance: import_types23.Provenance.EXTRACTED,
9963
+ confidence: (0, import_types23.confidenceForExtracted)("structural"),
9829
9964
  evidence: {
9830
9965
  file: relPath,
9831
9966
  line: req.line,
@@ -9844,7 +9979,7 @@ async function addSymbolEdges(graph, services) {
9844
9979
  init_cjs_shims();
9845
9980
  var import_node_path28 = __toESM(require("path"), 1);
9846
9981
  var import_tree_sitter5 = __toESM(require("tree-sitter"), 1);
9847
- var import_types23 = require("@neat.is/types");
9982
+ var import_types24 = require("@neat.is/types");
9848
9983
  function stringLiteralText2(node) {
9849
9984
  for (let i = 0; i < node.childCount; i++) {
9850
9985
  const child = node.child(i);
@@ -10014,11 +10149,11 @@ async function addServerActions(graph, services) {
10014
10149
  nodesAdded += fn;
10015
10150
  edgesAdded += fe;
10016
10151
  for (const action of actions) {
10017
- const aid = (0, import_types23.serverActionId)(service.pkg.name, relPath, action.exportName);
10152
+ const aid = (0, import_types24.serverActionId)(service.pkg.name, relPath, action.exportName);
10018
10153
  if (!graph.hasNode(aid)) {
10019
10154
  const node = {
10020
10155
  id: aid,
10021
- type: import_types23.NodeType.ServerActionNode,
10156
+ type: import_types24.NodeType.ServerActionNode,
10022
10157
  name: action.exportName,
10023
10158
  service: service.pkg.name,
10024
10159
  module: relPath,
@@ -10030,15 +10165,15 @@ async function addServerActions(graph, services) {
10030
10165
  graph.addNode(aid, node);
10031
10166
  nodesAdded++;
10032
10167
  }
10033
- const containsId = (0, import_types23.extractedEdgeId)(fileNodeId, aid, import_types23.EdgeType.CONTAINS);
10168
+ const containsId = (0, import_types24.extractedEdgeId)(fileNodeId, aid, import_types24.EdgeType.CONTAINS);
10034
10169
  if (!graph.hasEdge(containsId)) {
10035
10170
  const edge = {
10036
10171
  id: containsId,
10037
10172
  source: fileNodeId,
10038
10173
  target: aid,
10039
- type: import_types23.EdgeType.CONTAINS,
10040
- provenance: import_types23.Provenance.EXTRACTED,
10041
- confidence: (0, import_types23.confidenceForExtracted)("structural"),
10174
+ type: import_types24.EdgeType.CONTAINS,
10175
+ provenance: import_types24.Provenance.EXTRACTED,
10176
+ confidence: (0, import_types24.confidenceForExtracted)("structural"),
10042
10177
  evidence: {
10043
10178
  file: relPath,
10044
10179
  line: action.line,
@@ -10068,7 +10203,7 @@ async function addServerActions(graph, services) {
10068
10203
  for (const [local, binding] of bindings) {
10069
10204
  const target = await resolveJsImport(binding.specifier, fileDir, service.dir, tsPaths);
10070
10205
  if (!target) continue;
10071
- const aid = (0, import_types23.serverActionId)(service.pkg.name, target, binding.importedName);
10206
+ const aid = (0, import_types24.serverActionId)(service.pkg.name, target, binding.importedName);
10072
10207
  if (graph.hasNode(aid)) actionBindings.set(local, aid);
10073
10208
  }
10074
10209
  if (actionBindings.size === 0) continue;
@@ -10083,15 +10218,15 @@ async function addServerActions(graph, services) {
10083
10218
  nodesAdded += ensured.nodesAdded;
10084
10219
  edgesAdded += ensured.edgesAdded;
10085
10220
  }
10086
- const callsId = (0, import_types23.extractedEdgeId)(clientFileId, aid, import_types23.EdgeType.CALLS);
10221
+ const callsId = (0, import_types24.extractedEdgeId)(clientFileId, aid, import_types24.EdgeType.CALLS);
10087
10222
  if (graph.hasEdge(callsId)) continue;
10088
10223
  const edge = {
10089
10224
  id: callsId,
10090
10225
  source: clientFileId,
10091
10226
  target: aid,
10092
- type: import_types23.EdgeType.CALLS,
10093
- provenance: import_types23.Provenance.EXTRACTED,
10094
- confidence: (0, import_types23.confidenceForExtracted)("structural"),
10227
+ type: import_types24.EdgeType.CALLS,
10228
+ provenance: import_types24.Provenance.EXTRACTED,
10229
+ confidence: (0, import_types24.confidenceForExtracted)("structural"),
10095
10230
  evidence: {
10096
10231
  file: relPath,
10097
10232
  line,
@@ -10109,7 +10244,7 @@ async function addServerActions(graph, services) {
10109
10244
  // src/extract/databases/index.ts
10110
10245
  init_cjs_shims();
10111
10246
  var import_node_path37 = __toESM(require("path"), 1);
10112
- var import_types24 = require("@neat.is/types");
10247
+ var import_types25 = require("@neat.is/types");
10113
10248
 
10114
10249
  // src/extract/databases/db-config-yaml.ts
10115
10250
  init_cjs_shims();
@@ -10768,8 +10903,8 @@ function compatibleDriversFor(engine) {
10768
10903
  }
10769
10904
  function toDatabaseNode(config) {
10770
10905
  return {
10771
- id: (0, import_types24.databaseId)(config.host),
10772
- type: import_types24.NodeType.DatabaseNode,
10906
+ id: (0, import_types25.databaseId)(config.host),
10907
+ type: import_types25.NodeType.DatabaseNode,
10773
10908
  name: config.database || config.host,
10774
10909
  engine: config.engine,
10775
10910
  engineVersion: config.engineVersion,
@@ -10910,12 +11045,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
10910
11045
  edgesAdded += fe;
10911
11046
  const evidenceFile = toPosix(import_node_path37.default.relative(scanPath, config.sourceFile));
10912
11047
  const edge = {
10913
- id: (0, import_types4.extractedEdgeId)(fileNodeId, dbNode.id, import_types24.EdgeType.CONNECTS_TO),
11048
+ id: (0, import_types4.extractedEdgeId)(fileNodeId, dbNode.id, import_types25.EdgeType.CONNECTS_TO),
10914
11049
  source: fileNodeId,
10915
11050
  target: dbNode.id,
10916
- type: import_types24.EdgeType.CONNECTS_TO,
10917
- provenance: import_types24.Provenance.EXTRACTED,
10918
- confidence: (0, import_types24.confidenceForExtracted)("structural"),
11051
+ type: import_types25.EdgeType.CONNECTS_TO,
11052
+ provenance: import_types25.Provenance.EXTRACTED,
11053
+ confidence: (0, import_types25.confidenceForExtracted)("structural"),
10919
11054
  // Carry how the host was recovered (ADR-213) so the divergence ranker
10920
11055
  // can tell a real declared store from a hardcoded fault-injection /
10921
11056
  // flag-gated probe. Only set when the parser distinguished the two.
@@ -10930,11 +11065,11 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
10930
11065
  const primary = allConfigs[0];
10931
11066
  service.node.dbConnectionTarget = primary.port ? `${primary.host}:${primary.port}` : primary.host;
10932
11067
  const relPath = import_node_path37.default.relative(scanPath, primary.sourceFile);
10933
- const cfgId = (0, import_types24.configId)(relPath);
11068
+ const cfgId = (0, import_types25.configId)(relPath);
10934
11069
  if (!graph.hasNode(cfgId)) {
10935
11070
  const cfgNode = {
10936
11071
  id: cfgId,
10937
- type: import_types24.NodeType.ConfigNode,
11072
+ type: import_types25.NodeType.ConfigNode,
10938
11073
  name: import_node_path37.default.basename(primary.sourceFile),
10939
11074
  path: relPath,
10940
11075
  fileType: isConfigFile(import_node_path37.default.basename(primary.sourceFile)).fileType || "config"
@@ -10943,12 +11078,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
10943
11078
  nodesAdded++;
10944
11079
  }
10945
11080
  const cfgEdge = {
10946
- id: (0, import_types4.extractedEdgeId)(service.node.id, cfgId, import_types24.EdgeType.CONFIGURED_BY),
11081
+ id: (0, import_types4.extractedEdgeId)(service.node.id, cfgId, import_types25.EdgeType.CONFIGURED_BY),
10947
11082
  source: service.node.id,
10948
11083
  target: cfgId,
10949
- type: import_types24.EdgeType.CONFIGURED_BY,
10950
- provenance: import_types24.Provenance.EXTRACTED,
10951
- confidence: (0, import_types24.confidenceForExtracted)("structural"),
11084
+ type: import_types25.EdgeType.CONFIGURED_BY,
11085
+ provenance: import_types25.Provenance.EXTRACTED,
11086
+ confidence: (0, import_types25.confidenceForExtracted)("structural"),
10952
11087
  evidence: { file: toPosix(relPath) }
10953
11088
  };
10954
11089
  if (!graph.hasEdge(cfgEdge.id)) {
@@ -10980,7 +11115,7 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
10980
11115
  init_cjs_shims();
10981
11116
  var import_node_fs26 = require("fs");
10982
11117
  var import_node_path38 = __toESM(require("path"), 1);
10983
- var import_types25 = require("@neat.is/types");
11118
+ var import_types26 = require("@neat.is/types");
10984
11119
  async function walkConfigFiles(dir, excludeDirs = []) {
10985
11120
  const excluded = new Set(excludeDirs.map((d) => import_node_path38.default.resolve(d)));
10986
11121
  const out = [];
@@ -11009,8 +11144,8 @@ async function addConfigNodes(graph, services, scanPath) {
11009
11144
  for (const file of configFiles) {
11010
11145
  const relPath = import_node_path38.default.relative(scanPath, file);
11011
11146
  const node = {
11012
- id: (0, import_types25.configId)(relPath),
11013
- type: import_types25.NodeType.ConfigNode,
11147
+ id: (0, import_types26.configId)(relPath),
11148
+ type: import_types26.NodeType.ConfigNode,
11014
11149
  name: import_node_path38.default.basename(file),
11015
11150
  path: relPath,
11016
11151
  fileType: isConfigFile(import_node_path38.default.basename(file)).fileType
@@ -11029,12 +11164,12 @@ async function addConfigNodes(graph, services, scanPath) {
11029
11164
  nodesAdded += fn;
11030
11165
  edgesAdded += fe;
11031
11166
  const edge = {
11032
- id: (0, import_types4.extractedEdgeId)(fileNodeId, node.id, import_types25.EdgeType.CONFIGURED_BY),
11167
+ id: (0, import_types4.extractedEdgeId)(fileNodeId, node.id, import_types26.EdgeType.CONFIGURED_BY),
11033
11168
  source: fileNodeId,
11034
11169
  target: node.id,
11035
- type: import_types25.EdgeType.CONFIGURED_BY,
11036
- provenance: import_types25.Provenance.EXTRACTED,
11037
- confidence: (0, import_types25.confidenceForExtracted)("structural"),
11170
+ type: import_types26.EdgeType.CONFIGURED_BY,
11171
+ provenance: import_types26.Provenance.EXTRACTED,
11172
+ confidence: (0, import_types26.confidenceForExtracted)("structural"),
11038
11173
  evidence: { file: relPath.split(import_node_path38.default.sep).join("/") }
11039
11174
  };
11040
11175
  if (!graph.hasEdge(edge.id)) {
@@ -11050,7 +11185,7 @@ async function addConfigNodes(graph, services, scanPath) {
11050
11185
  init_cjs_shims();
11051
11186
  var import_node_fs27 = require("fs");
11052
11187
  var import_node_path39 = __toESM(require("path"), 1);
11053
- var import_types26 = require("@neat.is/types");
11188
+ var import_types27 = require("@neat.is/types");
11054
11189
  var PROTO_EXTENSION = ".proto";
11055
11190
  function packageOf(content) {
11056
11191
  const m = content.match(/^\s*package\s+([A-Za-z_][A-Za-z0-9_.]*)\s*;/m);
@@ -11130,11 +11265,11 @@ async function addGrpcMethods(graph, services) {
11130
11265
  }
11131
11266
  if (methods.length === 0) continue;
11132
11267
  for (const method of methods) {
11133
- const mid = (0, import_types26.grpcMethodId)(method.rpcService, method.rpcMethod);
11268
+ const mid = (0, import_types27.grpcMethodId)(method.rpcService, method.rpcMethod);
11134
11269
  if (!graph.hasNode(mid)) {
11135
11270
  const node = {
11136
11271
  id: mid,
11137
- type: import_types26.NodeType.GrpcMethodNode,
11272
+ type: import_types27.NodeType.GrpcMethodNode,
11138
11273
  name: `${method.rpcService}/${method.rpcMethod}`,
11139
11274
  rpcService: method.rpcService,
11140
11275
  rpcMethod: method.rpcMethod,
@@ -11145,15 +11280,15 @@ async function addGrpcMethods(graph, services) {
11145
11280
  graph.addNode(mid, node);
11146
11281
  nodesAdded++;
11147
11282
  }
11148
- const containsId = (0, import_types26.extractedEdgeId)(service.node.id, mid, import_types26.EdgeType.CONTAINS);
11283
+ const containsId = (0, import_types27.extractedEdgeId)(service.node.id, mid, import_types27.EdgeType.CONTAINS);
11149
11284
  if (!graph.hasEdge(containsId)) {
11150
11285
  const edge = {
11151
11286
  id: containsId,
11152
11287
  source: service.node.id,
11153
11288
  target: mid,
11154
- type: import_types26.EdgeType.CONTAINS,
11155
- provenance: import_types26.Provenance.EXTRACTED,
11156
- confidence: (0, import_types26.confidenceForExtracted)("structural"),
11289
+ type: import_types27.EdgeType.CONTAINS,
11290
+ provenance: import_types27.Provenance.EXTRACTED,
11291
+ confidence: (0, import_types27.confidenceForExtracted)("structural"),
11157
11292
  evidence: {
11158
11293
  file: relFile,
11159
11294
  line: method.line,
@@ -11171,7 +11306,7 @@ async function addGrpcMethods(graph, services) {
11171
11306
 
11172
11307
  // src/extract/calls/index.ts
11173
11308
  init_cjs_shims();
11174
- var import_types46 = require("@neat.is/types");
11309
+ var import_types47 = require("@neat.is/types");
11175
11310
 
11176
11311
  // src/extract/calls/http.ts
11177
11312
  init_cjs_shims();
@@ -11180,7 +11315,7 @@ var import_tree_sitter6 = __toESM(require("tree-sitter"), 1);
11180
11315
  var import_tree_sitter_javascript4 = __toESM(require("tree-sitter-javascript"), 1);
11181
11316
  var import_tree_sitter_typescript2 = __toESM(require("tree-sitter-typescript"), 1);
11182
11317
  var import_tree_sitter_python4 = __toESM(require("tree-sitter-python"), 1);
11183
- var import_types27 = require("@neat.is/types");
11318
+ var import_types28 = require("@neat.is/types");
11184
11319
  var STRING_LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["string_fragment", "string_content"]);
11185
11320
  var JSX_EXTERNAL_LINK_TAGS = /* @__PURE__ */ new Set(["a", "Link", "NavLink", "ExternalLink", "Anchor"]);
11186
11321
  function isInsideJsxExternalLink(node) {
@@ -11274,7 +11409,7 @@ async function addHttpCallEdges(graph, services) {
11274
11409
  const dedupKey = `${relFile}|${targetId}`;
11275
11410
  if (seen.has(dedupKey)) continue;
11276
11411
  seen.add(dedupKey);
11277
- const confidence = (0, import_types27.confidenceForExtracted)("url-literal-service-target");
11412
+ const confidence = (0, import_types28.confidenceForExtracted)("url-literal-service-target");
11278
11413
  const ev = {
11279
11414
  file: relFile,
11280
11415
  line: site.line,
@@ -11288,25 +11423,25 @@ async function addHttpCallEdges(graph, services) {
11288
11423
  );
11289
11424
  nodesAdded += n;
11290
11425
  edgesAdded += e;
11291
- if (!(0, import_types27.passesExtractedFloor)(confidence)) {
11426
+ if (!(0, import_types28.passesExtractedFloor)(confidence)) {
11292
11427
  noteExtractedDropped({
11293
11428
  source: fileNodeId,
11294
11429
  target: targetId,
11295
- type: import_types27.EdgeType.CALLS,
11430
+ type: import_types28.EdgeType.CALLS,
11296
11431
  confidence,
11297
11432
  confidenceKind: "url-literal-service-target",
11298
11433
  evidence: ev
11299
11434
  });
11300
11435
  continue;
11301
11436
  }
11302
- const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, targetId, import_types27.EdgeType.CALLS);
11437
+ const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, targetId, import_types28.EdgeType.CALLS);
11303
11438
  if (!graph.hasEdge(edgeId)) {
11304
11439
  const edge = {
11305
11440
  id: edgeId,
11306
11441
  source: fileNodeId,
11307
11442
  target: targetId,
11308
- type: import_types27.EdgeType.CALLS,
11309
- provenance: import_types27.Provenance.EXTRACTED,
11443
+ type: import_types28.EdgeType.CALLS,
11444
+ provenance: import_types28.Provenance.EXTRACTED,
11310
11445
  confidence,
11311
11446
  evidence: ev
11312
11447
  };
@@ -11324,7 +11459,7 @@ init_cjs_shims();
11324
11459
  var import_node_path41 = __toESM(require("path"), 1);
11325
11460
  var import_tree_sitter7 = __toESM(require("tree-sitter"), 1);
11326
11461
  var import_tree_sitter_javascript5 = __toESM(require("tree-sitter-javascript"), 1);
11327
- var import_types28 = require("@neat.is/types");
11462
+ var import_types29 = require("@neat.is/types");
11328
11463
  var PARSE_CHUNK5 = 16384;
11329
11464
  function parseSource5(parser, source) {
11330
11465
  return parser.parse(
@@ -11568,9 +11703,9 @@ function buildRouteIndex(graph) {
11568
11703
  const index = /* @__PURE__ */ new Map();
11569
11704
  graph.forEachNode((_id, attrs) => {
11570
11705
  const node = attrs;
11571
- if (node.type !== import_types28.NodeType.RouteNode) return;
11706
+ if (node.type !== import_types29.NodeType.RouteNode) return;
11572
11707
  const route = attrs;
11573
- const owner = (0, import_types28.serviceId)(route.service);
11708
+ const owner = (0, import_types29.serviceId)(route.service);
11574
11709
  const entry2 = {
11575
11710
  method: route.method.toUpperCase(),
11576
11711
  normalizedPath: normalizePathTemplate(route.pathTemplate),
@@ -11625,8 +11760,8 @@ async function addRouteCallEdges(graph, services) {
11625
11760
  noteExtractedDropped({
11626
11761
  source: fileNodeId2,
11627
11762
  target: "route:unresolved",
11628
- type: import_types28.EdgeType.CALLS,
11629
- confidence: (0, import_types28.confidenceForExtracted)("reconstructed-approximate"),
11763
+ type: import_types29.EdgeType.CALLS,
11764
+ confidence: (0, import_types29.confidenceForExtracted)("reconstructed-approximate"),
11630
11765
  confidenceKind: "reconstructed-approximate",
11631
11766
  evidence: {
11632
11767
  file: relFile,
@@ -11659,7 +11794,7 @@ async function addRouteCallEdges(graph, services) {
11659
11794
  edgesAdded += e;
11660
11795
  const anchored = pathHasLiteralAnchor(site.pathTemplate);
11661
11796
  const confidenceKind = site.approximate && !anchored ? "reconstructed-approximate" : "verified-call-site";
11662
- const confidence = (0, import_types28.confidenceForExtracted)(confidenceKind);
11797
+ const confidence = (0, import_types29.confidenceForExtracted)(confidenceKind);
11663
11798
  const ev = {
11664
11799
  file: relFile,
11665
11800
  line: site.line,
@@ -11668,25 +11803,25 @@ async function addRouteCallEdges(graph, services) {
11668
11803
  pathTemplate: site.pathTemplate,
11669
11804
  ...confidenceKind === "reconstructed-approximate" ? { approximate: true, reason: site.reason } : {}
11670
11805
  };
11671
- if (!(0, import_types28.passesExtractedFloor)(confidence)) {
11806
+ if (!(0, import_types29.passesExtractedFloor)(confidence)) {
11672
11807
  noteExtractedDropped({
11673
11808
  source: fileNodeId,
11674
11809
  target: match.routeNodeId,
11675
- type: import_types28.EdgeType.CALLS,
11810
+ type: import_types29.EdgeType.CALLS,
11676
11811
  confidence,
11677
11812
  confidenceKind,
11678
11813
  evidence: ev
11679
11814
  });
11680
11815
  continue;
11681
11816
  }
11682
- const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, match.routeNodeId, import_types28.EdgeType.CALLS);
11817
+ const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, match.routeNodeId, import_types29.EdgeType.CALLS);
11683
11818
  if (!graph.hasEdge(edgeId)) {
11684
11819
  const edge = {
11685
11820
  id: edgeId,
11686
11821
  source: fileNodeId,
11687
11822
  target: match.routeNodeId,
11688
- type: import_types28.EdgeType.CALLS,
11689
- provenance: import_types28.Provenance.EXTRACTED,
11823
+ type: import_types29.EdgeType.CALLS,
11824
+ provenance: import_types29.Provenance.EXTRACTED,
11690
11825
  confidence,
11691
11826
  evidence: ev
11692
11827
  };
@@ -11702,7 +11837,7 @@ async function addRouteCallEdges(graph, services) {
11702
11837
  // src/extract/calls/kafka.ts
11703
11838
  init_cjs_shims();
11704
11839
  var import_node_path42 = __toESM(require("path"), 1);
11705
- var import_types29 = require("@neat.is/types");
11840
+ var import_types30 = require("@neat.is/types");
11706
11841
  var PRODUCER_TOPIC_RE = /(?:producer|kafkaProducer)[\s\S]{0,40}?\.send\s*\(\s*\{[\s\S]{0,200}?topic\s*:\s*['"`]([^'"`]+)['"`]/g;
11707
11842
  var CONSUMER_TOPIC_RE = /(?:consumer|kafkaConsumer)[\s\S]{0,40}?\.(?:subscribe|run)\s*\(\s*\{[\s\S]{0,200}?topic[s]?\s*:\s*(?:\[\s*)?['"`]([^'"`]+)['"`]/g;
11708
11843
  var SARAMA_IMPORT_RE = /"[^"]*\/sarama"/;
@@ -11779,7 +11914,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
11779
11914
  seen.add(key);
11780
11915
  const line = anchor !== void 0 ? file.content.slice(0, anchor).split("\n").length : lineOf(file.content, topic);
11781
11916
  out.push({
11782
- infraId: (0, import_types29.infraId)("kafka-topic", topic),
11917
+ infraId: (0, import_types30.infraId)("kafka-topic", topic),
11783
11918
  name: topic,
11784
11919
  kind: "kafka-topic",
11785
11920
  edgeType,
@@ -11807,7 +11942,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
11807
11942
  // src/extract/calls/redis.ts
11808
11943
  init_cjs_shims();
11809
11944
  var import_node_path43 = __toESM(require("path"), 1);
11810
- var import_types30 = require("@neat.is/types");
11945
+ var import_types31 = require("@neat.is/types");
11811
11946
  var REDIS_URL_RE = /redis(?:s)?:\/\/(?:[^@'"`\s]+@)?([^:/'"`\s]+)(?::(\d+))?/g;
11812
11947
  function redisEndpointsFromFile(file, serviceDir) {
11813
11948
  const out = [];
@@ -11820,7 +11955,7 @@ function redisEndpointsFromFile(file, serviceDir) {
11820
11955
  seen.add(host);
11821
11956
  const line = lineOf(file.content, host);
11822
11957
  out.push({
11823
- infraId: (0, import_types30.infraId)("redis", host),
11958
+ infraId: (0, import_types31.infraId)("redis", host),
11824
11959
  name: host,
11825
11960
  kind: "redis",
11826
11961
  edgeType: "CALLS",
@@ -11841,7 +11976,7 @@ function redisEndpointsFromFile(file, serviceDir) {
11841
11976
  // src/extract/calls/aws.ts
11842
11977
  init_cjs_shims();
11843
11978
  var import_node_path44 = __toESM(require("path"), 1);
11844
- var import_types31 = require("@neat.is/types");
11979
+ var import_types32 = require("@neat.is/types");
11845
11980
  var S3_BUCKET_RE = /Bucket\s*:\s*['"`]([^'"`]+)['"`]/g;
11846
11981
  var DYNAMO_TABLE_RE = /TableName\s*:\s*['"`]([^'"`]+)['"`]/g;
11847
11982
  function hasMarker(text, markers) {
@@ -11865,7 +12000,7 @@ function awsEndpointsFromFile(file, serviceDir) {
11865
12000
  seen.add(key);
11866
12001
  const line = lineOf(file.content, name);
11867
12002
  out.push({
11868
- infraId: (0, import_types31.infraId)(kind, name),
12003
+ infraId: (0, import_types32.infraId)(kind, name),
11869
12004
  name,
11870
12005
  kind,
11871
12006
  edgeType: "CALLS",
@@ -11900,7 +12035,7 @@ function awsEndpointsFromFile(file, serviceDir) {
11900
12035
  // src/extract/calls/grpc.ts
11901
12036
  init_cjs_shims();
11902
12037
  var import_node_path45 = __toESM(require("path"), 1);
11903
- var import_types32 = require("@neat.is/types");
12038
+ var import_types33 = require("@neat.is/types");
11904
12039
  var GRPC_CLIENT_RE = /new\s+([A-Z][A-Za-z0-9_]*)Client\s*\(\s*['"`]?([^,'"`)]+)?/g;
11905
12040
  var AWS_SDK_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@aws-sdk\/client-([a-z0-9-]+)['"`]/g;
11906
12041
  var GRPC_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@grpc\/grpc-js['"`]|_grpc_pb['"`]/;
@@ -11949,7 +12084,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
11949
12084
  const { kind } = classified;
11950
12085
  const line = lineOf(file.content, m[0]);
11951
12086
  out.push({
11952
- infraId: (0, import_types32.infraId)(kind, name),
12087
+ infraId: (0, import_types33.infraId)(kind, name),
11953
12088
  name,
11954
12089
  kind,
11955
12090
  edgeType: "CALLS",
@@ -11970,7 +12105,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
11970
12105
  // src/extract/calls/supabase.ts
11971
12106
  init_cjs_shims();
11972
12107
  var import_node_path46 = __toESM(require("path"), 1);
11973
- var import_types33 = require("@neat.is/types");
12108
+ var import_types34 = require("@neat.is/types");
11974
12109
  var SUPABASE_JS_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/supabase-js['"`]/;
11975
12110
  var SUPABASE_SSR_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/ssr['"`]/;
11976
12111
  var SUPABASE_CLIENT_RE = /\b(createClient|createServerClient|createBrowserClient)\s*\(\s*(?:['"`]([^'"`]*)['"`])?/g;
@@ -12018,7 +12153,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
12018
12153
  seen.add(name);
12019
12154
  const line = lineOf(file.content, m[0]);
12020
12155
  out.push({
12021
- infraId: (0, import_types33.infraId)("supabase", name),
12156
+ infraId: (0, import_types34.infraId)("supabase", name),
12022
12157
  name,
12023
12158
  kind: "supabase",
12024
12159
  edgeType: "CALLS",
@@ -12049,7 +12184,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
12049
12184
  seen.add(key);
12050
12185
  const line = lineOf(file.content, am[0]);
12051
12186
  out.push({
12052
- infraId: (0, import_types33.infraId)(kind, resource),
12187
+ infraId: (0, import_types34.infraId)(kind, resource),
12053
12188
  name: resource,
12054
12189
  kind,
12055
12190
  edgeType: "CALLS",
@@ -12070,7 +12205,7 @@ init_cjs_shims();
12070
12205
  var import_node_path47 = __toESM(require("path"), 1);
12071
12206
  var import_tree_sitter8 = __toESM(require("tree-sitter"), 1);
12072
12207
  var import_tree_sitter_javascript6 = __toESM(require("tree-sitter-javascript"), 1);
12073
- var import_types34 = require("@neat.is/types");
12208
+ var import_types35 = require("@neat.is/types");
12074
12209
  var FIRESTORE_CLIENT_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase\/firestore['"`]/;
12075
12210
  var FIRESTORE_ADMIN_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase-admin(?:\/firestore)?['"`]/;
12076
12211
  function parserForExt2(ext) {
@@ -12334,7 +12469,7 @@ function firestoreEndpointsFromFile(file, serviceDir, imported) {
12334
12469
  }
12335
12470
  }
12336
12471
  out.push({
12337
- infraId: (0, import_types34.infraId)("firestore-collection", collPath),
12472
+ infraId: (0, import_types35.infraId)("firestore-collection", collPath),
12338
12473
  name: collPath,
12339
12474
  kind: "firestore-collection",
12340
12475
  edgeType: "CALLS",
@@ -12450,7 +12585,7 @@ async function firestoreCrossFileEndpoints(files, serviceDir) {
12450
12585
  // src/extract/calls/mongoose.ts
12451
12586
  init_cjs_shims();
12452
12587
  var import_node_path48 = __toESM(require("path"), 1);
12453
- var import_types35 = require("@neat.is/types");
12588
+ var import_types36 = require("@neat.is/types");
12454
12589
  var MONGOOSE_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongoose['"`]/;
12455
12590
  var MONGODB_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongodb['"`]/;
12456
12591
  var PLURALIZE_DISABLED_RE = /\bpluralize\s*\(\s*(?:null|false)\s*\)/;
@@ -12595,7 +12730,7 @@ function collectModelDefs(content, pluralizeOn) {
12595
12730
  function endpoint(r, file, serviceDir, matchText) {
12596
12731
  const line = lineOf(file.content, matchText);
12597
12732
  return {
12598
- infraId: (0, import_types35.infraId)(r.kind, r.name),
12733
+ infraId: (0, import_types36.infraId)(r.kind, r.name),
12599
12734
  name: r.name,
12600
12735
  kind: r.kind,
12601
12736
  edgeType: "CALLS",
@@ -12748,7 +12883,7 @@ init_cjs_shims();
12748
12883
  var import_node_path49 = __toESM(require("path"), 1);
12749
12884
  var import_tree_sitter9 = __toESM(require("tree-sitter"), 1);
12750
12885
  var import_tree_sitter_python5 = __toESM(require("tree-sitter-python"), 1);
12751
- var import_types36 = require("@neat.is/types");
12886
+ var import_types37 = require("@neat.is/types");
12752
12887
  var SQLALCHEMY_IMPORT_RE = /(?:from|import)\s+(?:flask_sqlalchemy|sqlalchemy)\b/;
12753
12888
  var PARSE_CHUNK6 = 16384;
12754
12889
  function makePyParser3() {
@@ -12902,7 +13037,7 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
12902
13037
  if (seen.has(name)) return;
12903
13038
  seen.add(name);
12904
13039
  out.push({
12905
- infraId: (0, import_types36.infraId)("sql-table", name),
13040
+ infraId: (0, import_types37.infraId)("sql-table", name),
12906
13041
  name,
12907
13042
  kind: "sql-table",
12908
13043
  edgeType: "CALLS",
@@ -13010,7 +13145,7 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
13010
13145
  if (seen.has(key)) continue;
13011
13146
  seen.add(key);
13012
13147
  out.push({
13013
- infraId: (0, import_types36.infraId)("sql-table", t),
13148
+ infraId: (0, import_types37.infraId)("sql-table", t),
13014
13149
  name: t,
13015
13150
  kind: "sql-table",
13016
13151
  edgeType: "CALLS",
@@ -13031,7 +13166,7 @@ init_cjs_shims();
13031
13166
  var import_node_path50 = __toESM(require("path"), 1);
13032
13167
  var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
13033
13168
  var import_tree_sitter_python6 = __toESM(require("tree-sitter-python"), 1);
13034
- var import_types37 = require("@neat.is/types");
13169
+ var import_types38 = require("@neat.is/types");
13035
13170
  var SOCKET_IMPORT_RE = /(?:^|\n)\s*(?:import\s+socket\b|from\s+socket\s+import\b)/;
13036
13171
  var PARSE_CHUNK7 = 16384;
13037
13172
  function makePyParser4() {
@@ -13097,7 +13232,7 @@ function socketEndpointsFromFile(file, serviceDir) {
13097
13232
  seen.add(name);
13098
13233
  const line = node.startPosition.row + 1;
13099
13234
  out.push({
13100
- infraId: (0, import_types37.infraId)("socket", name),
13235
+ infraId: (0, import_types38.infraId)("socket", name),
13101
13236
  name,
13102
13237
  kind: "socket",
13103
13238
  edgeType: "CALLS",
@@ -13118,7 +13253,7 @@ init_cjs_shims();
13118
13253
  var import_node_path51 = __toESM(require("path"), 1);
13119
13254
  var import_tree_sitter11 = __toESM(require("tree-sitter"), 1);
13120
13255
  var import_tree_sitter_python7 = __toESM(require("tree-sitter-python"), 1);
13121
- var import_types38 = require("@neat.is/types");
13256
+ var import_types39 = require("@neat.is/types");
13122
13257
  var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
13123
13258
  var PARSE_CHUNK8 = 16384;
13124
13259
  function makePyParser5() {
@@ -13198,7 +13333,7 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
13198
13333
  seen.add(table2);
13199
13334
  const line = node.startPosition.row + 1;
13200
13335
  out.push({
13201
- infraId: (0, import_types38.infraId)("sql-table", table2),
13336
+ infraId: (0, import_types39.infraId)("sql-table", table2),
13202
13337
  name: table2,
13203
13338
  kind: "sql-table",
13204
13339
  edgeType: "CALLS",
@@ -13214,7 +13349,7 @@ init_cjs_shims();
13214
13349
  var import_node_path52 = __toESM(require("path"), 1);
13215
13350
  var import_tree_sitter12 = __toESM(require("tree-sitter"), 1);
13216
13351
  var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"), 1);
13217
- var import_types39 = require("@neat.is/types");
13352
+ var import_types40 = require("@neat.is/types");
13218
13353
  var DRIZZLE_IMPORT_RE = /drizzle-orm/;
13219
13354
  var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
13220
13355
  function parserForExt3(ext) {
@@ -13305,7 +13440,7 @@ function drizzleEndpointsFromFile(file, serviceDir) {
13305
13440
  const columns = columnsFromObject(obj);
13306
13441
  const line = node.startPosition.row + 1;
13307
13442
  out.push({
13308
- infraId: (0, import_types39.infraId)("sql-table", tableName2),
13443
+ infraId: (0, import_types40.infraId)("sql-table", tableName2),
13309
13444
  name: tableName2,
13310
13445
  kind: "sql-table",
13311
13446
  edgeType: "CALLS",
@@ -13415,7 +13550,7 @@ function drizzleForeignKeys(file, serviceDir) {
13415
13550
  // src/extract/calls/prisma.ts
13416
13551
  init_cjs_shims();
13417
13552
  var import_node_path53 = __toESM(require("path"), 1);
13418
- var import_types40 = require("@neat.is/types");
13553
+ var import_types41 = require("@neat.is/types");
13419
13554
  var SCALAR_TYPES = /* @__PURE__ */ new Set([
13420
13555
  "Int",
13421
13556
  "String",
@@ -13463,7 +13598,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
13463
13598
  if (seenTable.has(b.tableName)) return;
13464
13599
  seenTable.add(b.tableName);
13465
13600
  out.push({
13466
- infraId: (0, import_types40.infraId)("sql-table", b.tableName),
13601
+ infraId: (0, import_types41.infraId)("sql-table", b.tableName),
13467
13602
  name: b.tableName,
13468
13603
  kind: "sql-table",
13469
13604
  edgeType: "CALLS",
@@ -13635,7 +13770,7 @@ init_cjs_shims();
13635
13770
  var import_node_path54 = __toESM(require("path"), 1);
13636
13771
  var import_tree_sitter13 = __toESM(require("tree-sitter"), 1);
13637
13772
  var import_tree_sitter_ruby3 = __toESM(require("tree-sitter-ruby"), 1);
13638
- var import_types41 = require("@neat.is/types");
13773
+ var import_types42 = require("@neat.is/types");
13639
13774
  var AR_SCHEMA_RE = /ActiveRecord::Schema/;
13640
13775
  var PARSE_CHUNK9 = 16384;
13641
13776
  function makeRubyParser2() {
@@ -13833,7 +13968,7 @@ function railsSchemaEndpointsFromFile(file, serviceDir) {
13833
13968
  if (!table2 || seen.has(table2.name)) return;
13834
13969
  seen.add(table2.name);
13835
13970
  out.push({
13836
- infraId: (0, import_types41.infraId)("sql-table", table2.name),
13971
+ infraId: (0, import_types42.infraId)("sql-table", table2.name),
13837
13972
  name: table2.name,
13838
13973
  kind: "sql-table",
13839
13974
  edgeType: "CALLS",
@@ -13939,7 +14074,7 @@ function railsModelEndpointsFromFile(file, serviceDir) {
13939
14074
  seen.add(table2);
13940
14075
  const line = node.startPosition.row + 1;
13941
14076
  out.push({
13942
- infraId: (0, import_types41.infraId)("sql-table", table2),
14077
+ infraId: (0, import_types42.infraId)("sql-table", table2),
13943
14078
  name: table2,
13944
14079
  kind: "sql-table",
13945
14080
  edgeType: "CALLS",
@@ -13997,7 +14132,7 @@ init_cjs_shims();
13997
14132
  var import_node_path55 = __toESM(require("path"), 1);
13998
14133
  var import_tree_sitter14 = __toESM(require("tree-sitter"), 1);
13999
14134
  var import_tree_sitter_php3 = __toESM(require("tree-sitter-php"), 1);
14000
- var import_types42 = require("@neat.is/types");
14135
+ var import_types43 = require("@neat.is/types");
14001
14136
  var LARAVEL_SCHEMA_RE = /\bSchema::(create|createIfNotExists|table)\b/;
14002
14137
  var PARSE_CHUNK10 = 16384;
14003
14138
  function makePhpParser2() {
@@ -14244,7 +14379,7 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
14244
14379
  }
14245
14380
  }
14246
14381
  out.push({
14247
- infraId: (0, import_types42.infraId)("sql-table", bp.table),
14382
+ infraId: (0, import_types43.infraId)("sql-table", bp.table),
14248
14383
  name: bp.table,
14249
14384
  kind: "sql-table",
14250
14385
  edgeType: "CALLS",
@@ -14387,7 +14522,7 @@ function laravelModelEndpointsFromFile(file, serviceDir) {
14387
14522
  seen.add(table2);
14388
14523
  const line = node.startPosition.row + 1;
14389
14524
  out.push({
14390
- infraId: (0, import_types42.infraId)("sql-table", table2),
14525
+ infraId: (0, import_types43.infraId)("sql-table", table2),
14391
14526
  name: table2,
14392
14527
  kind: "sql-table",
14393
14528
  edgeType: "CALLS",
@@ -14444,7 +14579,7 @@ init_cjs_shims();
14444
14579
  var import_node_path58 = __toESM(require("path"), 1);
14445
14580
  var import_tree_sitter15 = __toESM(require("tree-sitter"), 1);
14446
14581
  var import_tree_sitter_go4 = __toESM(require("tree-sitter-go"), 1);
14447
- var import_types43 = require("@neat.is/types");
14582
+ var import_types44 = require("@neat.is/types");
14448
14583
  init_otel();
14449
14584
  var PARSE_CHUNK11 = 16384;
14450
14585
  var DATABASE_SQL_METHODS = /* @__PURE__ */ new Set([
@@ -14538,7 +14673,7 @@ function goSqlEndpointsFromFile(file, serviceDir) {
14538
14673
  const columns = columnsFromSqlStatement(sql);
14539
14674
  const line = node.startPosition.row + 1;
14540
14675
  out.push({
14541
- infraId: (0, import_types43.infraId)("sql-table", table2),
14676
+ infraId: (0, import_types44.infraId)("sql-table", table2),
14542
14677
  name: table2,
14543
14678
  kind: "sql-table",
14544
14679
  edgeType: "CALLS",
@@ -14559,7 +14694,7 @@ init_cjs_shims();
14559
14694
  var import_node_path59 = __toESM(require("path"), 1);
14560
14695
  var import_tree_sitter16 = __toESM(require("tree-sitter"), 1);
14561
14696
  var import_tree_sitter_go5 = __toESM(require("tree-sitter-go"), 1);
14562
- var import_types44 = require("@neat.is/types");
14697
+ var import_types45 = require("@neat.is/types");
14563
14698
  var GORM_IMPORT_RE = /gorm\.io\/gorm/;
14564
14699
  var PARSE_CHUNK12 = 16384;
14565
14700
  function makeGoParser4() {
@@ -15004,7 +15139,7 @@ function gormEndpointsFromFile(file, serviceDir) {
15004
15139
  const columns = [];
15005
15140
  collectColumns(struct, structs, /* @__PURE__ */ new Set(), "", columns, /* @__PURE__ */ new Set());
15006
15141
  out.push({
15007
- infraId: (0, import_types44.infraId)("sql-table", table2),
15142
+ infraId: (0, import_types45.infraId)("sql-table", table2),
15008
15143
  name: table2,
15009
15144
  kind: "sql-table",
15010
15145
  edgeType: "CALLS",
@@ -15075,7 +15210,7 @@ init_cjs_shims();
15075
15210
  var import_node_path60 = __toESM(require("path"), 1);
15076
15211
  var import_tree_sitter17 = __toESM(require("tree-sitter"), 1);
15077
15212
  var import_tree_sitter_c_sharp2 = __toESM(require("tree-sitter-c-sharp"), 1);
15078
- var import_types45 = require("@neat.is/types");
15213
+ var import_types46 = require("@neat.is/types");
15079
15214
  var EFCORE_GATE = /Microsoft\.EntityFrameworkCore|DataAnnotations\.Schema|\bDbContext\b|\bDbSet\s*</;
15080
15215
  var PARSE_CHUNK13 = 16384;
15081
15216
  function makeCsParser() {
@@ -15160,7 +15295,7 @@ function efcoreEndpointsFromFile(file, serviceDir) {
15160
15295
  if (!name || seen.has(name)) return;
15161
15296
  seen.add(name);
15162
15297
  out.push({
15163
- infraId: (0, import_types45.infraId)("sql-table", name),
15298
+ infraId: (0, import_types46.infraId)("sql-table", name),
15164
15299
  name,
15165
15300
  kind: "sql-table",
15166
15301
  edgeType: "CALLS",
@@ -15190,11 +15325,11 @@ function efcoreEndpointsFromFile(file, serviceDir) {
15190
15325
  function edgeTypeFromEndpoint(ep) {
15191
15326
  switch (ep.edgeType) {
15192
15327
  case "PUBLISHES_TO":
15193
- return import_types46.EdgeType.PUBLISHES_TO;
15328
+ return import_types47.EdgeType.PUBLISHES_TO;
15194
15329
  case "CONSUMES_FROM":
15195
- return import_types46.EdgeType.CONSUMES_FROM;
15330
+ return import_types47.EdgeType.CONSUMES_FROM;
15196
15331
  default:
15197
- return import_types46.EdgeType.CALLS;
15332
+ return import_types47.EdgeType.CALLS;
15198
15333
  }
15199
15334
  }
15200
15335
  function isAwsKind(kind) {
@@ -15265,7 +15400,7 @@ async function addExternalEndpointEdges(graph, services) {
15265
15400
  if (!graph.hasNode(ep.infraId)) {
15266
15401
  const node = {
15267
15402
  id: ep.infraId,
15268
- type: import_types46.NodeType.InfraNode,
15403
+ type: import_types47.NodeType.InfraNode,
15269
15404
  name: ep.name,
15270
15405
  // #238 — `aws-*` covers AWS-SDK client kinds (aws-s3, aws-dynamodb,
15271
15406
  // aws-cognito-identity-provider, …); `s3-` / `dynamodb-` cover the
@@ -15278,21 +15413,21 @@ async function addExternalEndpointEdges(graph, services) {
15278
15413
  }
15279
15414
  if (ep.columns && ep.columns.length > 0) {
15280
15415
  const node = graph.getNodeAttributes(ep.infraId);
15281
- if (node.type === import_types46.NodeType.InfraNode) {
15416
+ if (node.type === import_types47.NodeType.InfraNode) {
15282
15417
  graph.replaceNodeAttributes(ep.infraId, {
15283
15418
  ...node,
15284
15419
  columns: foldColumns(
15285
15420
  node.columns,
15286
15421
  ep.columns,
15287
- import_types46.Provenance.EXTRACTED,
15288
- (0, import_types46.confidenceForExtracted)(ep.confidenceKind)
15422
+ import_types47.Provenance.EXTRACTED,
15423
+ (0, import_types47.confidenceForExtracted)(ep.confidenceKind)
15289
15424
  )
15290
15425
  });
15291
15426
  }
15292
15427
  }
15293
15428
  if (ep.sdkWrites && Object.keys(ep.sdkWrites).length > 0) {
15294
15429
  const node = graph.getNodeAttributes(ep.infraId);
15295
- if (node.type === import_types46.NodeType.InfraNode) {
15430
+ if (node.type === import_types47.NodeType.InfraNode) {
15296
15431
  graph.replaceNodeAttributes(ep.infraId, {
15297
15432
  ...node,
15298
15433
  columns: foldSdkWrites(node.columns, ep.sdkWrites)
@@ -15300,7 +15435,7 @@ async function addExternalEndpointEdges(graph, services) {
15300
15435
  }
15301
15436
  }
15302
15437
  const edgeType = edgeTypeFromEndpoint(ep);
15303
- const confidence = (0, import_types46.confidenceForExtracted)(ep.confidenceKind);
15438
+ const confidence = (0, import_types47.confidenceForExtracted)(ep.confidenceKind);
15304
15439
  const relFile = toPosix(ep.evidence.file);
15305
15440
  const { fileNodeId, nodesAdded: n, edgesAdded: e } = ensureFileNode(
15306
15441
  graph,
@@ -15310,7 +15445,7 @@ async function addExternalEndpointEdges(graph, services) {
15310
15445
  );
15311
15446
  nodesAdded += n;
15312
15447
  edgesAdded += e;
15313
- if (!(0, import_types46.passesExtractedFloor)(confidence)) {
15448
+ if (!(0, import_types47.passesExtractedFloor)(confidence)) {
15314
15449
  noteExtractedDropped({
15315
15450
  source: fileNodeId,
15316
15451
  target: ep.infraId,
@@ -15330,7 +15465,7 @@ async function addExternalEndpointEdges(graph, services) {
15330
15465
  source: fileNodeId,
15331
15466
  target: ep.infraId,
15332
15467
  type: edgeType,
15333
- provenance: import_types46.Provenance.EXTRACTED,
15468
+ provenance: import_types47.Provenance.EXTRACTED,
15334
15469
  confidence,
15335
15470
  evidence: ep.evidence
15336
15471
  };
@@ -15353,7 +15488,7 @@ async function addCallEdges(graph, services) {
15353
15488
 
15354
15489
  // src/extract/table-edges.ts
15355
15490
  init_cjs_shims();
15356
- var import_types47 = require("@neat.is/types");
15491
+ var import_types48 = require("@neat.is/types");
15357
15492
  async function addTableEdges(graph, services) {
15358
15493
  let nodesAdded = 0;
15359
15494
  let edgesAdded = 0;
@@ -15381,20 +15516,20 @@ async function addTableEdges(graph, services) {
15381
15516
  }
15382
15517
  refs.push(...modelRefs);
15383
15518
  for (const ref of refs) {
15384
- const childId = (0, import_types47.infraId)("sql-table", ref.childTable);
15385
- const parentId = (0, import_types47.infraId)("sql-table", ref.parentTable);
15519
+ const childId = (0, import_types48.infraId)("sql-table", ref.childTable);
15520
+ const parentId = (0, import_types48.infraId)("sql-table", ref.parentTable);
15386
15521
  if (childId === parentId) continue;
15387
15522
  nodesAdded += ensureTableNode(graph, childId, ref.childTable);
15388
15523
  nodesAdded += ensureTableNode(graph, parentId, ref.parentTable);
15389
- const edgeId = (0, import_types47.extractedEdgeId)(childId, parentId, import_types47.EdgeType.REFERENCES);
15524
+ const edgeId = (0, import_types48.extractedEdgeId)(childId, parentId, import_types48.EdgeType.REFERENCES);
15390
15525
  if (graph.hasEdge(edgeId)) continue;
15391
15526
  const edge = {
15392
15527
  id: edgeId,
15393
15528
  source: childId,
15394
15529
  target: parentId,
15395
- type: import_types47.EdgeType.REFERENCES,
15396
- provenance: import_types47.Provenance.EXTRACTED,
15397
- confidence: (0, import_types47.confidenceForExtracted)("structural"),
15530
+ type: import_types48.EdgeType.REFERENCES,
15531
+ provenance: import_types48.Provenance.EXTRACTED,
15532
+ confidence: (0, import_types48.confidenceForExtracted)("structural"),
15398
15533
  evidence: ref.evidence
15399
15534
  };
15400
15535
  graph.addEdgeWithKey(edgeId, childId, parentId, edge);
@@ -15407,7 +15542,7 @@ function ensureTableNode(graph, id, name) {
15407
15542
  if (graph.hasNode(id)) return 0;
15408
15543
  const node = {
15409
15544
  id,
15410
- type: import_types47.NodeType.InfraNode,
15545
+ type: import_types48.NodeType.InfraNode,
15411
15546
  name,
15412
15547
  provider: "self",
15413
15548
  kind: "sql-table"
@@ -15422,15 +15557,15 @@ init_cjs_shims();
15422
15557
  // src/extract/infra/docker-compose.ts
15423
15558
  init_cjs_shims();
15424
15559
  var import_node_path61 = __toESM(require("path"), 1);
15425
- var import_types49 = require("@neat.is/types");
15560
+ var import_types50 = require("@neat.is/types");
15426
15561
 
15427
15562
  // src/extract/infra/shared.ts
15428
15563
  init_cjs_shims();
15429
- var import_types48 = require("@neat.is/types");
15564
+ var import_types49 = require("@neat.is/types");
15430
15565
  function makeInfraNode(kind, name, provider = "self", extras) {
15431
15566
  return {
15432
- id: (0, import_types48.infraId)(kind, name),
15433
- type: import_types48.NodeType.InfraNode,
15567
+ id: (0, import_types49.infraId)(kind, name),
15568
+ type: import_types49.NodeType.InfraNode,
15434
15569
  name,
15435
15570
  provider,
15436
15571
  kind,
@@ -15474,8 +15609,8 @@ function emitPlatformResourceEdge(graph, anchorId, edgeType, kind, name, provide
15474
15609
  source: anchorId,
15475
15610
  target: node.id,
15476
15611
  type: edgeType,
15477
- provenance: import_types48.Provenance.EXTRACTED,
15478
- confidence: (0, import_types48.confidenceForExtracted)("structural"),
15612
+ provenance: import_types49.Provenance.EXTRACTED,
15613
+ confidence: (0, import_types49.confidenceForExtracted)("structural"),
15479
15614
  evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
15480
15615
  };
15481
15616
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -15542,15 +15677,15 @@ async function addComposeInfra(graph, scanPath, services) {
15542
15677
  for (const dep of dependsOnList(svc.depends_on)) {
15543
15678
  const targetId = composeNameToNodeId.get(dep);
15544
15679
  if (!targetId) continue;
15545
- const edgeId = (0, import_types4.extractedEdgeId)(sourceId, targetId, import_types49.EdgeType.DEPENDS_ON);
15680
+ const edgeId = (0, import_types4.extractedEdgeId)(sourceId, targetId, import_types50.EdgeType.DEPENDS_ON);
15546
15681
  if (graph.hasEdge(edgeId)) continue;
15547
15682
  const edge = {
15548
15683
  id: edgeId,
15549
15684
  source: sourceId,
15550
15685
  target: targetId,
15551
- type: import_types49.EdgeType.DEPENDS_ON,
15552
- provenance: import_types49.Provenance.EXTRACTED,
15553
- confidence: (0, import_types49.confidenceForExtracted)("structural"),
15686
+ type: import_types50.EdgeType.DEPENDS_ON,
15687
+ provenance: import_types50.Provenance.EXTRACTED,
15688
+ confidence: (0, import_types50.confidenceForExtracted)("structural"),
15554
15689
  evidence: { file: evidenceFile }
15555
15690
  };
15556
15691
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -15564,7 +15699,7 @@ async function addComposeInfra(graph, scanPath, services) {
15564
15699
  init_cjs_shims();
15565
15700
  var import_node_path62 = __toESM(require("path"), 1);
15566
15701
  var import_node_fs28 = require("fs");
15567
- var import_types50 = require("@neat.is/types");
15702
+ var import_types51 = require("@neat.is/types");
15568
15703
  function readDockerfile(content) {
15569
15704
  let image = null;
15570
15705
  const ports = [];
@@ -15623,15 +15758,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
15623
15758
  );
15624
15759
  nodesAdded += fn;
15625
15760
  edgesAdded += fe;
15626
- const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, node.id, import_types50.EdgeType.RUNS_ON);
15761
+ const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, node.id, import_types51.EdgeType.RUNS_ON);
15627
15762
  if (!graph.hasEdge(edgeId)) {
15628
15763
  const edge = {
15629
15764
  id: edgeId,
15630
15765
  source: fileNodeId,
15631
15766
  target: node.id,
15632
- type: import_types50.EdgeType.RUNS_ON,
15633
- provenance: import_types50.Provenance.EXTRACTED,
15634
- confidence: (0, import_types50.confidenceForExtracted)("structural"),
15767
+ type: import_types51.EdgeType.RUNS_ON,
15768
+ provenance: import_types51.Provenance.EXTRACTED,
15769
+ confidence: (0, import_types51.confidenceForExtracted)("structural"),
15635
15770
  evidence: {
15636
15771
  file: evidenceFile,
15637
15772
  ...facts.entrypoint ? { snippet: facts.entrypoint.slice(0, 120) } : {}
@@ -15646,15 +15781,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
15646
15781
  graph.addNode(portNode.id, portNode);
15647
15782
  nodesAdded++;
15648
15783
  }
15649
- const portEdgeId = (0, import_types4.extractedEdgeId)(fileNodeId, portNode.id, import_types50.EdgeType.CONNECTS_TO);
15784
+ const portEdgeId = (0, import_types4.extractedEdgeId)(fileNodeId, portNode.id, import_types51.EdgeType.CONNECTS_TO);
15650
15785
  if (graph.hasEdge(portEdgeId)) continue;
15651
15786
  const portEdge = {
15652
15787
  id: portEdgeId,
15653
15788
  source: fileNodeId,
15654
15789
  target: portNode.id,
15655
- type: import_types50.EdgeType.CONNECTS_TO,
15656
- provenance: import_types50.Provenance.EXTRACTED,
15657
- confidence: (0, import_types50.confidenceForExtracted)("structural"),
15790
+ type: import_types51.EdgeType.CONNECTS_TO,
15791
+ provenance: import_types51.Provenance.EXTRACTED,
15792
+ confidence: (0, import_types51.confidenceForExtracted)("structural"),
15658
15793
  evidence: { file: evidenceFile, snippet: `EXPOSE ${port}` }
15659
15794
  };
15660
15795
  graph.addEdgeWithKey(portEdgeId, portEdge.source, portEdge.target, portEdge);
@@ -15668,7 +15803,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
15668
15803
  init_cjs_shims();
15669
15804
  var import_node_fs29 = require("fs");
15670
15805
  var import_node_path63 = __toESM(require("path"), 1);
15671
- var import_types51 = require("@neat.is/types");
15806
+ var import_types52 = require("@neat.is/types");
15672
15807
  var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
15673
15808
  var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
15674
15809
  async function walkTfFiles(start, depth = 0, max = 5) {
@@ -15749,16 +15884,16 @@ async function addTerraformResources(graph, scanPath) {
15749
15884
  if (!target) continue;
15750
15885
  if (seen.has(target.nodeId)) continue;
15751
15886
  seen.add(target.nodeId);
15752
- const edgeId = (0, import_types4.extractedEdgeId)(resource.nodeId, target.nodeId, import_types51.EdgeType.DEPENDS_ON);
15887
+ const edgeId = (0, import_types4.extractedEdgeId)(resource.nodeId, target.nodeId, import_types52.EdgeType.DEPENDS_ON);
15753
15888
  if (graph.hasEdge(edgeId)) continue;
15754
15889
  const line = lineAt2(content, resource.bodyOffset + ref.index);
15755
15890
  const edge = {
15756
15891
  id: edgeId,
15757
15892
  source: resource.nodeId,
15758
15893
  target: target.nodeId,
15759
- type: import_types51.EdgeType.DEPENDS_ON,
15760
- provenance: import_types51.Provenance.EXTRACTED,
15761
- confidence: (0, import_types51.confidenceForExtracted)("structural"),
15894
+ type: import_types52.EdgeType.DEPENDS_ON,
15895
+ provenance: import_types52.Provenance.EXTRACTED,
15896
+ confidence: (0, import_types52.confidenceForExtracted)("structural"),
15762
15897
  evidence: { file: evidenceFile, line, snippet: key }
15763
15898
  };
15764
15899
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -15774,7 +15909,7 @@ init_cjs_shims();
15774
15909
  var import_node_fs30 = require("fs");
15775
15910
  var import_node_path64 = __toESM(require("path"), 1);
15776
15911
  var import_yaml3 = require("yaml");
15777
- var import_types52 = require("@neat.is/types");
15912
+ var import_types53 = require("@neat.is/types");
15778
15913
  var K8S_KIND_TO_INFRA_KIND = {
15779
15914
  Service: "k8s-service",
15780
15915
  Deployment: "k8s-deployment",
@@ -15834,7 +15969,7 @@ async function addK8sResources(graph, scanPath) {
15834
15969
  nodesAdded++;
15835
15970
  }
15836
15971
  if (isWorkload) {
15837
- const svcId = (0, import_types52.serviceId)(name);
15972
+ const svcId = (0, import_types53.serviceId)(name);
15838
15973
  if (graph.hasNode(svcId)) {
15839
15974
  const svc = graph.getNodeAttributes(svcId);
15840
15975
  graph.replaceNodeAttributes(svcId, {
@@ -15846,7 +15981,7 @@ async function addK8sResources(graph, scanPath) {
15846
15981
  edgesAdded += emitPlatformResourceEdge(
15847
15982
  graph,
15848
15983
  svcId,
15849
- import_types52.EdgeType.RUNS_ON,
15984
+ import_types53.EdgeType.RUNS_ON,
15850
15985
  infraKind,
15851
15986
  name,
15852
15987
  "kubernetes",
@@ -15865,7 +16000,7 @@ init_cjs_shims();
15865
16000
  var import_node_fs31 = require("fs");
15866
16001
  var import_node_path65 = __toESM(require("path"), 1);
15867
16002
  var import_smol_toml3 = require("smol-toml");
15868
- var import_types53 = require("@neat.is/types");
16003
+ var import_types54 = require("@neat.is/types");
15869
16004
  var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
15870
16005
  async function readWranglerConfig(dir) {
15871
16006
  for (const filename of WRANGLER_FILENAMES) {
@@ -15913,8 +16048,8 @@ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, li
15913
16048
  source: anchorId,
15914
16049
  target: node.id,
15915
16050
  type: edgeType,
15916
- provenance: import_types53.Provenance.EXTRACTED,
15917
- confidence: (0, import_types53.confidenceForExtracted)("structural"),
16051
+ provenance: import_types54.Provenance.EXTRACTED,
16052
+ confidence: (0, import_types54.confidenceForExtracted)("structural"),
15918
16053
  evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
15919
16054
  };
15920
16055
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -15975,15 +16110,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
15975
16110
  nodesAdded++;
15976
16111
  }
15977
16112
  if (runtimeNode.id !== anchorId) {
15978
- const runsOnId = (0, import_types4.extractedEdgeId)(anchorId, runtimeNode.id, import_types53.EdgeType.RUNS_ON);
16113
+ const runsOnId = (0, import_types4.extractedEdgeId)(anchorId, runtimeNode.id, import_types54.EdgeType.RUNS_ON);
15979
16114
  if (!graph.hasEdge(runsOnId)) {
15980
16115
  const edge = {
15981
16116
  id: runsOnId,
15982
16117
  source: anchorId,
15983
16118
  target: runtimeNode.id,
15984
- type: import_types53.EdgeType.RUNS_ON,
15985
- provenance: import_types53.Provenance.EXTRACTED,
15986
- confidence: (0, import_types53.confidenceForExtracted)("structural"),
16119
+ type: import_types54.EdgeType.RUNS_ON,
16120
+ provenance: import_types54.Provenance.EXTRACTED,
16121
+ confidence: (0, import_types54.confidenceForExtracted)("structural"),
15987
16122
  evidence: {
15988
16123
  file: evidenceFile,
15989
16124
  ...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
@@ -15997,7 +16132,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
15997
16132
  const result = addResourceEdge(
15998
16133
  graph,
15999
16134
  anchorId,
16000
- import_types53.EdgeType.CONNECTS_TO,
16135
+ import_types54.EdgeType.CONNECTS_TO,
16001
16136
  "cloudflare-route",
16002
16137
  route,
16003
16138
  evidenceFile,
@@ -16021,7 +16156,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
16021
16156
  const result = addResourceEdge(
16022
16157
  graph,
16023
16158
  anchorId,
16024
- import_types53.EdgeType.DEPENDS_ON,
16159
+ import_types54.EdgeType.DEPENDS_ON,
16025
16160
  group.kind,
16026
16161
  name,
16027
16162
  evidenceFile,
@@ -16035,7 +16170,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
16035
16170
  const result = addResourceEdge(
16036
16171
  graph,
16037
16172
  anchorId,
16038
- import_types53.EdgeType.DEPENDS_ON,
16173
+ import_types54.EdgeType.DEPENDS_ON,
16039
16174
  "cloudflare-cron",
16040
16175
  cron,
16041
16176
  evidenceFile,
@@ -16048,7 +16183,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
16048
16183
  const result = addResourceEdge(
16049
16184
  graph,
16050
16185
  anchorId,
16051
- import_types53.EdgeType.DEPENDS_ON,
16186
+ import_types54.EdgeType.DEPENDS_ON,
16052
16187
  "cloudflare-env-var",
16053
16188
  varName,
16054
16189
  evidenceFile,
@@ -16061,15 +16196,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
16061
16196
  if (!svc.service) continue;
16062
16197
  const target = workerIndex.get(svc.service);
16063
16198
  if (target && target.anchorId !== anchorId) {
16064
- const edgeId = (0, import_types4.extractedEdgeId)(anchorId, target.anchorId, import_types53.EdgeType.CALLS);
16199
+ const edgeId = (0, import_types4.extractedEdgeId)(anchorId, target.anchorId, import_types54.EdgeType.CALLS);
16065
16200
  if (!graph.hasEdge(edgeId)) {
16066
16201
  const edge = {
16067
16202
  id: edgeId,
16068
16203
  source: anchorId,
16069
16204
  target: target.anchorId,
16070
- type: import_types53.EdgeType.CALLS,
16071
- provenance: import_types53.Provenance.EXTRACTED,
16072
- confidence: (0, import_types53.confidenceForExtracted)("structural"),
16205
+ type: import_types54.EdgeType.CALLS,
16206
+ provenance: import_types54.Provenance.EXTRACTED,
16207
+ confidence: (0, import_types54.confidenceForExtracted)("structural"),
16073
16208
  evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
16074
16209
  };
16075
16210
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -16080,7 +16215,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
16080
16215
  const result = addResourceEdge(
16081
16216
  graph,
16082
16217
  anchorId,
16083
- import_types53.EdgeType.DEPENDS_ON,
16218
+ import_types54.EdgeType.DEPENDS_ON,
16084
16219
  "cloudflare-service-binding",
16085
16220
  svc.service,
16086
16221
  evidenceFile,
@@ -16097,7 +16232,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
16097
16232
  init_cjs_shims();
16098
16233
  var import_node_fs32 = require("fs");
16099
16234
  var import_node_path66 = __toESM(require("path"), 1);
16100
- var import_types54 = require("@neat.is/types");
16235
+ var import_types55 = require("@neat.is/types");
16101
16236
  var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
16102
16237
  async function readVercelConfig(dir) {
16103
16238
  for (const filename of VERCEL_CONFIG_FILENAMES) {
@@ -16160,12 +16295,12 @@ async function addVercelServices(graph, services, scanPath) {
16160
16295
  nodesAdded += result.nodesAdded;
16161
16296
  edgesAdded += result.edgesAdded;
16162
16297
  };
16163
- add(import_types54.EdgeType.RUNS_ON, "vercel", "vercel");
16164
- for (const cron of config.crons ?? []) add(import_types54.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
16165
- for (const varName of Object.keys(config.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
16166
- for (const varName of Object.keys(config.build?.env ?? {})) add(import_types54.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
16298
+ add(import_types55.EdgeType.RUNS_ON, "vercel", "vercel");
16299
+ for (const cron of config.crons ?? []) add(import_types55.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
16300
+ for (const varName of Object.keys(config.env ?? {})) add(import_types55.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
16301
+ for (const varName of Object.keys(config.build?.env ?? {})) add(import_types55.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
16167
16302
  for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
16168
- add(import_types54.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
16303
+ add(import_types55.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
16169
16304
  }
16170
16305
  }
16171
16306
  return { nodesAdded, edgesAdded };
@@ -16176,7 +16311,7 @@ init_cjs_shims();
16176
16311
  var import_node_fs33 = require("fs");
16177
16312
  var import_node_path67 = __toESM(require("path"), 1);
16178
16313
  var import_smol_toml4 = require("smol-toml");
16179
- var import_types55 = require("@neat.is/types");
16314
+ var import_types56 = require("@neat.is/types");
16180
16315
  var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
16181
16316
  async function readRailwayConfig(dir) {
16182
16317
  for (const filename of RAILWAY_FILENAMES) {
@@ -16222,9 +16357,9 @@ async function addRailwayServices(graph, services, scanPath) {
16222
16357
  nodesAdded += result.nodesAdded;
16223
16358
  edgesAdded += result.edgesAdded;
16224
16359
  };
16225
- add(import_types55.EdgeType.RUNS_ON, "railway", "railway");
16226
- add(import_types55.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
16227
- add(import_types55.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
16360
+ add(import_types56.EdgeType.RUNS_ON, "railway", "railway");
16361
+ add(import_types56.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
16362
+ add(import_types56.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
16228
16363
  }
16229
16364
  return { nodesAdded, edgesAdded };
16230
16365
  }
@@ -16234,7 +16369,7 @@ init_cjs_shims();
16234
16369
  var import_node_fs34 = require("fs");
16235
16370
  var import_node_path68 = __toESM(require("path"), 1);
16236
16371
  var import_smol_toml5 = require("smol-toml");
16237
- var import_types56 = require("@neat.is/types");
16372
+ var import_types57 = require("@neat.is/types");
16238
16373
  async function readSupabaseConfig(dir) {
16239
16374
  const relFile = import_node_path68.default.join("supabase", "config.toml");
16240
16375
  const abs = import_node_path68.default.join(dir, relFile);
@@ -16282,10 +16417,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
16282
16417
  nodesAdded += result.nodesAdded;
16283
16418
  edgesAdded += result.edgesAdded;
16284
16419
  };
16285
- add(import_types56.EdgeType.RUNS_ON, "supabase", "supabase");
16286
- for (const fn of Object.keys(config.functions ?? {})) add(import_types56.EdgeType.DEPENDS_ON, "supabase-function", fn);
16287
- if (config.storage) add(import_types56.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
16288
- if (config.auth) add(import_types56.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
16420
+ add(import_types57.EdgeType.RUNS_ON, "supabase", "supabase");
16421
+ for (const fn of Object.keys(config.functions ?? {})) add(import_types57.EdgeType.DEPENDS_ON, "supabase-function", fn);
16422
+ if (config.storage) add(import_types57.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
16423
+ if (config.auth) add(import_types57.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
16289
16424
  }
16290
16425
  return { nodesAdded, edgesAdded };
16291
16426
  }
@@ -16311,7 +16446,7 @@ init_cjs_shims();
16311
16446
  var import_node_path69 = __toESM(require("path"), 1);
16312
16447
  var import_tree_sitter18 = __toESM(require("tree-sitter"), 1);
16313
16448
  var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"), 1);
16314
- var import_types57 = require("@neat.is/types");
16449
+ var import_types58 = require("@neat.is/types");
16315
16450
  var ZOD_IMPORT_RE = /\bzod\b/;
16316
16451
  var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
16317
16452
  function parserForExt4(ext) {
@@ -16417,7 +16552,7 @@ function zodShapesFromFile(file, serviceDir) {
16417
16552
  seen.add(name);
16418
16553
  const line = call.startPosition.row + 1;
16419
16554
  out.push({
16420
- infraId: (0, import_types57.infraId)("zod-schema", name),
16555
+ infraId: (0, import_types58.infraId)("zod-schema", name),
16421
16556
  name,
16422
16557
  fields,
16423
16558
  evidence: {
@@ -16452,7 +16587,7 @@ async function addZodShapes(graph, services) {
16452
16587
  if (!graph.hasNode(shape.infraId)) {
16453
16588
  const node = {
16454
16589
  id: shape.infraId,
16455
- type: import_types57.NodeType.InfraNode,
16590
+ type: import_types58.NodeType.InfraNode,
16456
16591
  name: shape.name,
16457
16592
  provider: "self",
16458
16593
  kind: "zod-schema"
@@ -16462,14 +16597,14 @@ async function addZodShapes(graph, services) {
16462
16597
  }
16463
16598
  if (shape.fields.length > 0) {
16464
16599
  const node = graph.getNodeAttributes(shape.infraId);
16465
- if (node.type === import_types57.NodeType.InfraNode) {
16600
+ if (node.type === import_types58.NodeType.InfraNode) {
16466
16601
  graph.replaceNodeAttributes(shape.infraId, {
16467
16602
  ...node,
16468
16603
  columns: foldColumns(
16469
16604
  node.columns,
16470
16605
  shape.fields,
16471
- import_types57.Provenance.EXTRACTED,
16472
- (0, import_types57.confidenceForExtracted)("structural")
16606
+ import_types58.Provenance.EXTRACTED,
16607
+ (0, import_types58.confidenceForExtracted)("structural")
16473
16608
  )
16474
16609
  });
16475
16610
  }
@@ -16483,15 +16618,15 @@ async function addZodShapes(graph, services) {
16483
16618
  );
16484
16619
  nodesAdded += n;
16485
16620
  edgesAdded += e;
16486
- const edgeId = (0, import_types57.extractedEdgeId)(fileNodeId, shape.infraId, import_types57.EdgeType.CONTAINS);
16621
+ const edgeId = (0, import_types58.extractedEdgeId)(fileNodeId, shape.infraId, import_types58.EdgeType.CONTAINS);
16487
16622
  if (!graph.hasEdge(edgeId)) {
16488
16623
  const edge = {
16489
16624
  id: edgeId,
16490
16625
  source: fileNodeId,
16491
16626
  target: shape.infraId,
16492
- type: import_types57.EdgeType.CONTAINS,
16493
- provenance: import_types57.Provenance.EXTRACTED,
16494
- confidence: (0, import_types57.confidenceForExtracted)("structural"),
16627
+ type: import_types58.EdgeType.CONTAINS,
16628
+ provenance: import_types58.Provenance.EXTRACTED,
16629
+ confidence: (0, import_types58.confidenceForExtracted)("structural"),
16495
16630
  evidence: shape.evidence
16496
16631
  };
16497
16632
  graph.addEdgeWithKey(edgeId, fileNodeId, shape.infraId, edge);
@@ -16505,7 +16640,7 @@ async function addZodShapes(graph, services) {
16505
16640
 
16506
16641
  // src/extract/firestore-rules.ts
16507
16642
  init_cjs_shims();
16508
- var import_types58 = require("@neat.is/types");
16643
+ var import_types59 = require("@neat.is/types");
16509
16644
  var FIRESTORE_COLLECTION_KIND = "firestore-collection";
16510
16645
  var WRITE_METHODS = /* @__PURE__ */ new Set(["write", "create", "update"]);
16511
16646
  function stripComments(src) {
@@ -16676,7 +16811,7 @@ async function addFirestoreRules(graph, services) {
16676
16811
  if (guards.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
16677
16812
  graph.forEachNode((id, attrs) => {
16678
16813
  const node = attrs;
16679
- if (node.type !== import_types58.NodeType.InfraNode) return;
16814
+ if (node.type !== import_types59.NodeType.InfraNode) return;
16680
16815
  if (node.kind !== FIRESTORE_COLLECTION_KIND) return;
16681
16816
  const fields = guards.get(collectionKeyFromName(node.name));
16682
16817
  if (!fields || fields.size === 0) return;
@@ -16695,12 +16830,12 @@ var import_node_path71 = __toESM(require("path"), 1);
16695
16830
  init_cjs_shims();
16696
16831
  var import_node_fs35 = require("fs");
16697
16832
  var import_node_path70 = __toESM(require("path"), 1);
16698
- var import_types59 = require("@neat.is/types");
16833
+ var import_types60 = require("@neat.is/types");
16699
16834
  function dropOrphanedFileNodes(graph, source) {
16700
16835
  const orphans = [];
16701
16836
  graph.forEachNode((id, attrs) => {
16702
16837
  const node = attrs;
16703
- if (node.type !== import_types59.NodeType.FileNode) return;
16838
+ if (node.type !== import_types60.NodeType.FileNode) return;
16704
16839
  if (source && node.source !== source) return;
16705
16840
  if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
16706
16841
  orphans.push(id);
@@ -16714,7 +16849,7 @@ function retireEdgesByFile(graph, file) {
16714
16849
  const toDrop = [];
16715
16850
  graph.forEachEdge((id, attrs) => {
16716
16851
  const edge = attrs;
16717
- if (edge.provenance !== import_types59.Provenance.EXTRACTED) return;
16852
+ if (edge.provenance !== import_types60.Provenance.EXTRACTED) return;
16718
16853
  if (!edge.evidence?.file) return;
16719
16854
  if (edge.evidence.file === normalized) toDrop.push(id);
16720
16855
  });
@@ -16727,7 +16862,7 @@ function outOfScope(graph, edge, source) {
16727
16862
  for (const endpoint2 of [edge.source, edge.target]) {
16728
16863
  if (!graph.hasNode(endpoint2)) continue;
16729
16864
  const node = graph.getNodeAttributes(endpoint2);
16730
- if (node.type !== import_types59.NodeType.FileNode) continue;
16865
+ if (node.type !== import_types60.NodeType.FileNode) continue;
16731
16866
  return node.source !== source;
16732
16867
  }
16733
16868
  return false;
@@ -16737,7 +16872,7 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
16737
16872
  const bases = [scanPath, ...serviceDirs];
16738
16873
  graph.forEachEdge((id, attrs) => {
16739
16874
  const edge = attrs;
16740
- if (edge.provenance !== import_types59.Provenance.EXTRACTED) return;
16875
+ if (edge.provenance !== import_types60.Provenance.EXTRACTED) return;
16741
16876
  if (outOfScope(graph, edge, source)) return;
16742
16877
  const evidenceFile = edge.evidence?.file;
16743
16878
  if (!evidenceFile) return;
@@ -16756,7 +16891,23 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
16756
16891
  // src/extract/index.ts
16757
16892
  var passQueue = Promise.resolve();
16758
16893
  function extractFromDirectory(graph, scanPath, opts = {}) {
16759
- const pass = passQueue.then(() => runExtractionPass(graph, scanPath, opts));
16894
+ invalidateSourceBaseline(graph, opts.source, "syncing");
16895
+ const pass = passQueue.then(async () => {
16896
+ const sourceGeneration = beginSourceExtraction(graph, opts.source, opts.sourceCommit);
16897
+ let result;
16898
+ try {
16899
+ result = await runExtractionPass(graph, scanPath, opts);
16900
+ return result;
16901
+ } finally {
16902
+ finishSourceExtraction(
16903
+ graph,
16904
+ sourceGeneration,
16905
+ opts.source,
16906
+ opts.sourceCommit,
16907
+ result ?? { extractionErrors: 1, skippedFiles: 0 }
16908
+ );
16909
+ }
16910
+ });
16760
16911
  passQueue = pass.catch(() => {
16761
16912
  });
16762
16913
  return pass;
@@ -16850,39 +17001,39 @@ async function runExtractionPass(graph, scanPath, opts) {
16850
17001
 
16851
17002
  // src/divergences.ts
16852
17003
  init_cjs_shims();
16853
- var import_types60 = require("@neat.is/types");
17004
+ var import_types61 = require("@neat.is/types");
16854
17005
  function bucketKey(source, target, type) {
16855
17006
  return `${type}|${source}|${target}`;
16856
17007
  }
16857
17008
  function bucketSourceFor(graph, edge) {
16858
- if (edge.type !== import_types60.EdgeType.CONNECTS_TO) return edge.source;
16859
- const parsed = (0, import_types60.parseFileId)(edge.source);
17009
+ if (edge.type !== import_types61.EdgeType.CONNECTS_TO) return edge.source;
17010
+ const parsed = (0, import_types61.parseFileId)(edge.source);
16860
17011
  if (!parsed || !graph.hasNode(edge.target)) return edge.source;
16861
17012
  const target = graph.getNodeAttributes(edge.target);
16862
- if (target.type !== import_types60.NodeType.DatabaseNode) return edge.source;
16863
- return (0, import_types60.serviceId)(parsed.service);
17013
+ if (target.type !== import_types61.NodeType.DatabaseNode) return edge.source;
17014
+ return (0, import_types61.serviceId)(parsed.service);
16864
17015
  }
16865
17016
  function bucketEdges(graph) {
16866
17017
  const buckets2 = /* @__PURE__ */ new Map();
16867
17018
  graph.forEachEdge((id, attrs) => {
16868
17019
  const e = attrs;
16869
- const parsed = (0, import_types60.parseEdgeId)(id);
17020
+ const parsed = (0, import_types61.parseEdgeId)(id);
16870
17021
  const provenance2 = parsed?.provenance ?? e.provenance;
16871
17022
  const source = bucketSourceFor(graph, e);
16872
17023
  const key = bucketKey(source, e.target, e.type);
16873
17024
  const cur = buckets2.get(key) ?? { source, target: e.target, type: e.type };
16874
17025
  switch (provenance2) {
16875
- case import_types60.Provenance.EXTRACTED:
17026
+ case import_types61.Provenance.EXTRACTED:
16876
17027
  cur.extracted = e;
16877
17028
  break;
16878
- case import_types60.Provenance.OBSERVED:
17029
+ case import_types61.Provenance.OBSERVED:
16879
17030
  cur.observed = e;
16880
17031
  break;
16881
- case import_types60.Provenance.INFERRED:
17032
+ case import_types61.Provenance.INFERRED:
16882
17033
  cur.inferred = e;
16883
17034
  break;
16884
17035
  default:
16885
- if (e.provenance === import_types60.Provenance.STALE) cur.stale = e;
17036
+ if (e.provenance === import_types61.Provenance.STALE) cur.stale = e;
16886
17037
  }
16887
17038
  buckets2.set(key, cur);
16888
17039
  });
@@ -16891,22 +17042,22 @@ function bucketEdges(graph) {
16891
17042
  function nodeIsFrontier(graph, nodeId) {
16892
17043
  if (!graph.hasNode(nodeId)) return false;
16893
17044
  const attrs = graph.getNodeAttributes(nodeId);
16894
- return attrs.type === import_types60.NodeType.FrontierNode;
17045
+ return attrs.type === import_types61.NodeType.FrontierNode;
16895
17046
  }
16896
17047
  function nodeIsWebsocketChannel(graph, nodeId) {
16897
17048
  if (!graph.hasNode(nodeId)) return false;
16898
17049
  const attrs = graph.getNodeAttributes(nodeId);
16899
- return attrs.type === import_types60.NodeType.WebSocketChannelNode;
17050
+ return attrs.type === import_types61.NodeType.WebSocketChannelNode;
16900
17051
  }
16901
17052
  function nodeIsServerAction(graph, nodeId) {
16902
17053
  if (!graph.hasNode(nodeId)) return false;
16903
17054
  const attrs = graph.getNodeAttributes(nodeId);
16904
- return attrs.type === import_types60.NodeType.ServerActionNode;
17055
+ return attrs.type === import_types61.NodeType.ServerActionNode;
16905
17056
  }
16906
17057
  function nodeIsSymbol(graph, nodeId) {
16907
17058
  if (!graph.hasNode(nodeId)) return false;
16908
17059
  const attrs = graph.getNodeAttributes(nodeId);
16909
- return attrs.type === import_types60.NodeType.SymbolNode;
17060
+ return attrs.type === import_types61.NodeType.SymbolNode;
16910
17061
  }
16911
17062
  function clampConfidence(n) {
16912
17063
  if (!Number.isFinite(n)) return 0;
@@ -16926,14 +17077,14 @@ function gradedConfidence(edge) {
16926
17077
  return clampConfidence(confidenceForEdge(edge));
16927
17078
  }
16928
17079
  var OBSERVABLE_EDGE_TYPES = /* @__PURE__ */ new Set([
16929
- import_types60.EdgeType.CALLS,
16930
- import_types60.EdgeType.CONNECTS_TO,
16931
- import_types60.EdgeType.PUBLISHES_TO,
16932
- import_types60.EdgeType.CONSUMES_FROM
17080
+ import_types61.EdgeType.CALLS,
17081
+ import_types61.EdgeType.CONNECTS_TO,
17082
+ import_types61.EdgeType.PUBLISHES_TO,
17083
+ import_types61.EdgeType.CONSUMES_FROM
16933
17084
  ]);
16934
17085
  function detectMissingDivergences(graph, bucket) {
16935
17086
  const out = [];
16936
- if (bucket.type === import_types60.EdgeType.CONTAINS) return out;
17087
+ if (bucket.type === import_types61.EdgeType.CONTAINS) return out;
16937
17088
  if (nodeIsSymbol(graph, bucket.source) || nodeIsSymbol(graph, bucket.target)) return out;
16938
17089
  if (bucket.extracted && !bucket.observed && OBSERVABLE_EDGE_TYPES.has(bucket.type)) {
16939
17090
  if (!nodeIsFrontier(graph, bucket.target) && !nodeIsServerAction(graph, bucket.target)) {
@@ -16975,7 +17126,7 @@ function declaredHostFor(svc) {
16975
17126
  function hasExtractedConfiguredBy(graph, svcId) {
16976
17127
  for (const edgeId of graph.outboundEdges(svcId)) {
16977
17128
  const e = graph.getEdgeAttributes(edgeId);
16978
- if (e.type === import_types60.EdgeType.CONFIGURED_BY && e.provenance === import_types60.Provenance.EXTRACTED) {
17129
+ if (e.type === import_types61.EdgeType.CONFIGURED_BY && e.provenance === import_types61.Provenance.EXTRACTED) {
16979
17130
  return true;
16980
17131
  }
16981
17132
  }
@@ -16988,10 +17139,10 @@ function detectHostMismatch(graph, svcId, svc) {
16988
17139
  const out = [];
16989
17140
  for (const edgeId of graph.outboundEdges(svcId)) {
16990
17141
  const edge = graph.getEdgeAttributes(edgeId);
16991
- if (edge.type !== import_types60.EdgeType.CONNECTS_TO) continue;
16992
- if (edge.provenance !== import_types60.Provenance.OBSERVED) continue;
17142
+ if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
17143
+ if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
16993
17144
  const target = graph.getNodeAttributes(edge.target);
16994
- if (target.type !== import_types60.NodeType.DatabaseNode) continue;
17145
+ if (target.type !== import_types61.NodeType.DatabaseNode) continue;
16995
17146
  const observedHost = target.host?.trim();
16996
17147
  if (!observedHost) continue;
16997
17148
  if (observedHost === declaredHost) continue;
@@ -17013,10 +17164,10 @@ function detectCompatDivergences(graph, svcId, svc) {
17013
17164
  const deps = svc.dependencies ?? {};
17014
17165
  for (const edgeId of graph.outboundEdges(svcId)) {
17015
17166
  const edge = graph.getEdgeAttributes(edgeId);
17016
- if (edge.type !== import_types60.EdgeType.CONNECTS_TO) continue;
17017
- if (edge.provenance !== import_types60.Provenance.OBSERVED) continue;
17167
+ if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
17168
+ if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
17018
17169
  const target = graph.getNodeAttributes(edge.target);
17019
- if (target.type !== import_types60.NodeType.DatabaseNode) continue;
17170
+ if (target.type !== import_types61.NodeType.DatabaseNode) continue;
17020
17171
  for (const pair of compatPairs()) {
17021
17172
  if (pair.engine !== target.engine) continue;
17022
17173
  const declared = deps[pair.driver];
@@ -17179,11 +17330,11 @@ function symbolLocus(graph, ev) {
17179
17330
  const location = filepath ? `${filepath}${lineno !== void 0 ? `:${lineno}` : ""}` : void 0;
17180
17331
  const affected = ev.affectedNode;
17181
17332
  const affectedInGraph = affected.length > 0 && graph.hasNode(affected);
17182
- const affectedIsCode = affectedInGraph && ((0, import_types60.parseSymbolId)(affected) !== null || (0, import_types60.parseFileId)(affected) !== null);
17333
+ const affectedIsCode = affectedInGraph && ((0, import_types61.parseSymbolId)(affected) !== null || (0, import_types61.parseFileId)(affected) !== null);
17183
17334
  if (affectedIsCode) return { node: affected, ...location ? { location } : {} };
17184
17335
  if (!location) return null;
17185
17336
  if (affectedInGraph) return { node: affected, location };
17186
- const svc = (0, import_types60.serviceId)(ev.service);
17337
+ const svc = (0, import_types61.serviceId)(ev.service);
17187
17338
  if (graph.hasNode(svc)) return { node: svc, location };
17188
17339
  return null;
17189
17340
  }
@@ -17226,7 +17377,7 @@ function detectSymbolMismatches(graph, incidents) {
17226
17377
  mismatchKind: g.kind,
17227
17378
  ...g.symbol ? { symbol: g.symbol } : {},
17228
17379
  ...g.location ? { location: g.location } : {},
17229
- provenance: import_types60.Provenance.INFERRED,
17380
+ provenance: import_types61.Provenance.INFERRED,
17230
17381
  incidentId: g.latest.id,
17231
17382
  errorMessage: g.latest.errorMessage,
17232
17383
  incidentCount: g.count,
@@ -17243,7 +17394,7 @@ var OBSERVED_FAILING_CONFIDENCE = 0.6;
17243
17394
  function detectObservedFailingEdge(graph, bucket) {
17244
17395
  if (!bucket.extracted || !bucket.observed) return [];
17245
17396
  if (!OBSERVABLE_EDGE_TYPES.has(bucket.type)) return [];
17246
- if (bucket.observed.provenance !== import_types60.Provenance.OBSERVED) return [];
17397
+ if (bucket.observed.provenance !== import_types61.Provenance.OBSERVED) return [];
17247
17398
  const signal = bucket.observed.signal;
17248
17399
  if (!signal) return [];
17249
17400
  const { spanCount, errorCount } = signal;
@@ -17257,7 +17408,7 @@ function detectObservedFailingEdge(graph, bucket) {
17257
17408
  source: bucket.source,
17258
17409
  target: bucket.target,
17259
17410
  failureKind: "error-rate",
17260
- provenance: import_types60.Provenance.INFERRED,
17411
+ provenance: import_types61.Provenance.INFERRED,
17261
17412
  edgeType: bucket.type,
17262
17413
  observed: bucket.observed,
17263
17414
  spanCount,
@@ -17362,7 +17513,7 @@ function detectObservedFailingIncidents(graph, incidents) {
17362
17513
  source: g.node,
17363
17514
  target: g.node,
17364
17515
  failureKind: g.kind,
17365
- provenance: import_types60.Provenance.INFERRED,
17516
+ provenance: import_types61.Provenance.INFERRED,
17366
17517
  ...g.location ? { location: g.location } : {},
17367
17518
  incidentId: g.latest.id,
17368
17519
  errorMessage: g.latest.errorMessage,
@@ -17381,24 +17532,24 @@ function involvesNode(d, nodeId) {
17381
17532
  function datastoreEverObserved(graph, nodeId) {
17382
17533
  if (!graph.hasNode(nodeId)) return false;
17383
17534
  const n = graph.getNodeAttributes(nodeId);
17384
- if (n.type === import_types60.NodeType.DatabaseNode) {
17535
+ if (n.type === import_types61.NodeType.DatabaseNode) {
17385
17536
  const via = n.discoveredVia;
17386
17537
  if (via === "otel" || via === "merged") return true;
17387
17538
  }
17388
17539
  for (const edgeId of graph.inboundEdges(nodeId)) {
17389
17540
  const e = graph.getEdgeAttributes(edgeId);
17390
- if (e.provenance === import_types60.Provenance.OBSERVED || e.provenance === import_types60.Provenance.STALE) return true;
17541
+ if (e.provenance === import_types61.Provenance.OBSERVED || e.provenance === import_types61.Provenance.STALE) return true;
17391
17542
  }
17392
17543
  return false;
17393
17544
  }
17394
17545
  function serviceHasObservedSameEngineStore(graph, buckets2, serviceId17, engine, excludeTarget) {
17395
17546
  for (const bucket of buckets2.values()) {
17396
- if (bucket.type !== import_types60.EdgeType.CONNECTS_TO) continue;
17547
+ if (bucket.type !== import_types61.EdgeType.CONNECTS_TO) continue;
17397
17548
  if (bucket.source !== serviceId17) continue;
17398
17549
  if (bucket.target === excludeTarget) continue;
17399
17550
  if (!graph.hasNode(bucket.target)) continue;
17400
17551
  const target = graph.getNodeAttributes(bucket.target);
17401
- if (target.type !== import_types60.NodeType.DatabaseNode) continue;
17552
+ if (target.type !== import_types61.NodeType.DatabaseNode) continue;
17402
17553
  if (target.engine !== engine) continue;
17403
17554
  if (bucket.observed || datastoreEverObserved(graph, bucket.target)) return true;
17404
17555
  }
@@ -17408,10 +17559,10 @@ var DEAD_CODE_PROBE_CONFIDENCE = 0.1;
17408
17559
  function dampenDeadCodeProbes(graph, buckets2, all) {
17409
17560
  return all.map((d) => {
17410
17561
  if (d.type !== "missing-observed") return d;
17411
- if (!d.extracted || d.edgeType !== import_types60.EdgeType.CONNECTS_TO) return d;
17562
+ if (!d.extracted || d.edgeType !== import_types61.EdgeType.CONNECTS_TO) return d;
17412
17563
  if (!graph.hasNode(d.target)) return d;
17413
17564
  const target = graph.getNodeAttributes(d.target);
17414
- if (target.type !== import_types60.NodeType.DatabaseNode) return d;
17565
+ if (target.type !== import_types61.NodeType.DatabaseNode) return d;
17415
17566
  if (d.extracted.evidence?.hostSource !== "literal") return d;
17416
17567
  if (datastoreEverObserved(graph, d.target)) return d;
17417
17568
  const engine = target.engine;
@@ -17431,7 +17582,7 @@ function suppressHostMismatchHalves(all) {
17431
17582
  for (const d of all) {
17432
17583
  if (d.type !== "host-mismatch") continue;
17433
17584
  observedHalf.add(`${d.source}->${d.target}`);
17434
- declaredHalf.add((0, import_types60.databaseId)(d.extractedHost));
17585
+ declaredHalf.add((0, import_types61.databaseId)(d.extractedHost));
17435
17586
  }
17436
17587
  if (observedHalf.size === 0) return all;
17437
17588
  return all.filter((d) => {
@@ -17451,14 +17602,14 @@ function computeDivergences(graph, opts = {}) {
17451
17602
  }
17452
17603
  graph.forEachNode((nodeId, attrs) => {
17453
17604
  const n = attrs;
17454
- if (n.type === import_types60.NodeType.ServiceNode) {
17605
+ if (n.type === import_types61.NodeType.ServiceNode) {
17455
17606
  const svc = n;
17456
17607
  for (const d of detectHostMismatch(graph, nodeId, svc)) all.push(d);
17457
17608
  for (const d of detectCompatDivergences(graph, nodeId, svc)) all.push(d);
17458
17609
  for (const d of detectDeployDivergence(svc)) all.push(d);
17459
17610
  return;
17460
17611
  }
17461
- if (n.type === import_types60.NodeType.InfraNode && n.kind === "sql-table") {
17612
+ if (n.type === import_types61.NodeType.InfraNode && n.kind === "sql-table") {
17462
17613
  for (const d of detectColumnDrift(n)) all.push(d);
17463
17614
  }
17464
17615
  });
@@ -17523,7 +17674,7 @@ function computeDivergences(graph, opts = {}) {
17523
17674
  const bloc = "location" in b && b.location ? b.location : "";
17524
17675
  return aloc.localeCompare(bloc);
17525
17676
  });
17526
- return import_types60.DivergenceResultSchema.parse({
17677
+ return import_types61.DivergenceResultSchema.parse({
17527
17678
  divergences: filtered,
17528
17679
  totalAffected: filtered.length,
17529
17680
  computedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -17534,7 +17685,7 @@ function computeDivergences(graph, opts = {}) {
17534
17685
  init_cjs_shims();
17535
17686
  var import_node_fs36 = require("fs");
17536
17687
  var import_node_path72 = __toESM(require("path"), 1);
17537
- var import_types61 = require("@neat.is/types");
17688
+ var import_types62 = require("@neat.is/types");
17538
17689
  var SCHEMA_VERSION = 7;
17539
17690
  function migrateV1ToV2(payload) {
17540
17691
  const nodes = payload.graph.nodes;
@@ -17558,7 +17709,7 @@ function migrateV5ToV6(payload) {
17558
17709
  if (Array.isArray(nodes)) {
17559
17710
  for (const node of nodes) {
17560
17711
  const attrs = node.attributes;
17561
- if (!attrs || attrs.type !== import_types61.NodeType.InfraNode) continue;
17712
+ if (!attrs || attrs.type !== import_types62.NodeType.InfraNode) continue;
17562
17713
  if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
17563
17714
  if (!Array.isArray(attrs.columns)) attrs.columns = [];
17564
17715
  }
@@ -17574,12 +17725,12 @@ function migrateV2ToV3(payload) {
17574
17725
  for (const edge of edges) {
17575
17726
  const attrs = edge.attributes;
17576
17727
  if (!attrs || attrs.provenance !== "FRONTIER") continue;
17577
- attrs.provenance = import_types61.Provenance.OBSERVED;
17728
+ attrs.provenance = import_types62.Provenance.OBSERVED;
17578
17729
  const type = typeof attrs.type === "string" ? attrs.type : void 0;
17579
17730
  const source = typeof attrs.source === "string" ? attrs.source : void 0;
17580
17731
  const target = typeof attrs.target === "string" ? attrs.target : void 0;
17581
17732
  if (type && source && target) {
17582
- const newId = (0, import_types61.observedEdgeId)(source, target, type);
17733
+ const newId = (0, import_types62.observedEdgeId)(source, target, type);
17583
17734
  attrs.id = newId;
17584
17735
  if (edge.key) edge.key = newId;
17585
17736
  }
@@ -17767,7 +17918,7 @@ ${NEAT_OUT_LINE}
17767
17918
 
17768
17919
  // src/summary.ts
17769
17920
  init_cjs_shims();
17770
- var import_types62 = require("@neat.is/types");
17921
+ var import_types63 = require("@neat.is/types");
17771
17922
 
17772
17923
  // src/otlp-headers.ts
17773
17924
  init_cjs_shims();
@@ -17786,19 +17937,19 @@ function renderOtelEnvBlock() {
17786
17937
  }
17787
17938
  function findIncompatServices(nodes) {
17788
17939
  return nodes.filter(
17789
- (n) => n.type === import_types62.NodeType.ServiceNode && Array.isArray(n.incompatibilities) && (n.incompatibilities ?? []).length > 0
17940
+ (n) => n.type === import_types63.NodeType.ServiceNode && Array.isArray(n.incompatibilities) && (n.incompatibilities ?? []).length > 0
17790
17941
  );
17791
17942
  }
17792
17943
  function servicesWithoutObserved(nodes, edges) {
17793
17944
  const seen = /* @__PURE__ */ new Set();
17794
17945
  for (const e of edges) {
17795
- if (e.provenance === import_types62.Provenance.OBSERVED) {
17946
+ if (e.provenance === import_types63.Provenance.OBSERVED) {
17796
17947
  seen.add(e.source);
17797
17948
  seen.add(e.target);
17798
17949
  }
17799
17950
  }
17800
17951
  return nodes.filter(
17801
- (n) => n.type === import_types62.NodeType.ServiceNode && !seen.has(n.id)
17952
+ (n) => n.type === import_types63.NodeType.ServiceNode && !seen.has(n.id)
17802
17953
  );
17803
17954
  }
17804
17955
  function formatDivergence(d) {
@@ -17821,8 +17972,8 @@ function computeLanguageCoverage(nodes, edges) {
17821
17972
  const nodeById = /* @__PURE__ */ new Map();
17822
17973
  for (const n of nodes) {
17823
17974
  nodeById.set(n.id, n);
17824
- if (n.type === import_types62.NodeType.ServiceNode) serviceLang.set(n.name, n.language);
17825
- else if (n.type === import_types62.NodeType.FileNode) fileService.set(n.id, n.service);
17975
+ if (n.type === import_types63.NodeType.ServiceNode) serviceLang.set(n.name, n.language);
17976
+ else if (n.type === import_types63.NodeType.FileNode) fileService.set(n.id, n.service);
17826
17977
  }
17827
17978
  const cov = /* @__PURE__ */ new Map();
17828
17979
  const ensure = (lang) => {
@@ -17835,25 +17986,25 @@ function computeLanguageCoverage(nodes, edges) {
17835
17986
  };
17836
17987
  for (const lang of serviceLang.values()) ensure(lang);
17837
17988
  for (const n of nodes) {
17838
- if (n.type === import_types62.NodeType.SymbolNode) {
17989
+ if (n.type === import_types63.NodeType.SymbolNode) {
17839
17990
  if (n.discoveredVia === "otel") continue;
17840
17991
  const lang = serviceLang.get(n.service);
17841
17992
  if (lang) ensure(lang).symbols = true;
17842
- } else if (n.type === import_types62.NodeType.RouteNode) {
17993
+ } else if (n.type === import_types63.NodeType.RouteNode) {
17843
17994
  if (n.discoveredVia === "otel") continue;
17844
17995
  const lang = serviceLang.get(n.service);
17845
17996
  if (lang) ensure(lang).routes = true;
17846
17997
  }
17847
17998
  }
17848
17999
  for (const e of edges) {
17849
- if (e.type !== import_types62.EdgeType.CALLS || e.provenance !== import_types62.Provenance.EXTRACTED) continue;
18000
+ if (e.type !== import_types63.EdgeType.CALLS || e.provenance !== import_types63.Provenance.EXTRACTED) continue;
17850
18001
  const svc = fileService.get(e.source);
17851
18002
  const lang = svc ? serviceLang.get(svc) : void 0;
17852
18003
  if (!lang) continue;
17853
18004
  const target = nodeById.get(e.target);
17854
18005
  if (!target) continue;
17855
- if (target.type === import_types62.NodeType.RouteNode) ensure(lang).crossServiceCalls = true;
17856
- else if (target.type === import_types62.NodeType.InfraNode && isTableInfra(target.kind)) ensure(lang).data = true;
18006
+ if (target.type === import_types63.NodeType.RouteNode) ensure(lang).crossServiceCalls = true;
18007
+ else if (target.type === import_types63.NodeType.InfraNode && isTableInfra(target.kind)) ensure(lang).data = true;
17857
18008
  }
17858
18009
  return cov;
17859
18010
  }
@@ -17953,7 +18104,7 @@ init_cjs_shims();
17953
18104
  var import_fastify2 = __toESM(require("fastify"), 1);
17954
18105
  var import_node_crypto6 = require("crypto");
17955
18106
  var import_cors = __toESM(require("@fastify/cors"), 1);
17956
- var import_types105 = require("@neat.is/types");
18107
+ var import_types106 = require("@neat.is/types");
17957
18108
 
17958
18109
  // src/extend/index.ts
17959
18110
  init_cjs_shims();
@@ -18345,7 +18496,7 @@ function queryLogEntries(opts) {
18345
18496
 
18346
18497
  // src/goodybag.ts
18347
18498
  init_cjs_shims();
18348
- var import_types63 = require("@neat.is/types");
18499
+ var import_types64 = require("@neat.is/types");
18349
18500
  var CODE_FILEPATH_ATTR2 = "code.filepath";
18350
18501
  var CODE_LINENO_ATTR2 = "code.lineno";
18351
18502
  var BLAST_NEAREST_LIMIT = 5;
@@ -18371,7 +18522,7 @@ function locusOf(graph, ev) {
18371
18522
  ...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
18372
18523
  ...symbol ? { symbol } : {},
18373
18524
  service: node?.service ?? ev.service,
18374
- provenance: import_types63.Provenance.OBSERVED
18525
+ provenance: import_types64.Provenance.OBSERVED
18375
18526
  };
18376
18527
  }
18377
18528
  function locusFromNode(graph, nodeId) {
@@ -18387,7 +18538,7 @@ function locusFromNode(graph, nodeId) {
18387
18538
  ...typeof end === "number" ? { lineEnd: end } : {},
18388
18539
  ...n.qualname ? { symbol: shortLabel(graph, nodeId) } : {},
18389
18540
  ...n.service ? { service: n.service } : {},
18390
- provenance: import_types63.Provenance.INFERRED
18541
+ provenance: import_types64.Provenance.INFERRED
18391
18542
  };
18392
18543
  }
18393
18544
  function promoteCauseLocus(graph, causeNode, incidents) {
@@ -18396,7 +18547,7 @@ function promoteCauseLocus(graph, causeNode, incidents) {
18396
18547
  );
18397
18548
  if (native) {
18398
18549
  const l = locusOf(graph, native);
18399
- if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance: import_types63.Provenance.INFERRED };
18550
+ if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance: import_types64.Provenance.INFERRED };
18400
18551
  }
18401
18552
  return locusFromNode(graph, causeNode);
18402
18553
  }
@@ -18445,7 +18596,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
18445
18596
  const chain = (rc.traversalPath ?? []).map((node, i) => ({
18446
18597
  node,
18447
18598
  grain: grainOf2(graph, node),
18448
- provenance: provs[i] ?? provs[provs.length - 1] ?? import_types63.Provenance.INFERRED
18599
+ provenance: provs[i] ?? provs[provs.length - 1] ?? import_types64.Provenance.INFERRED
18449
18600
  }));
18450
18601
  rootCause = {
18451
18602
  node: rc.rootCauseNode,
@@ -18476,7 +18627,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
18476
18627
  kind: "incident",
18477
18628
  id: errorEvent.id,
18478
18629
  at: errorEvent.timestamp,
18479
- incidentKind: (0, import_types63.incidentKindOf)(errorEvent),
18630
+ incidentKind: (0, import_types64.incidentKindOf)(errorEvent),
18480
18631
  service: errorEvent.service,
18481
18632
  affectedNode: affected,
18482
18633
  message: errorEvent.errorMessage,
@@ -18494,7 +18645,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
18494
18645
  headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
18495
18646
  };
18496
18647
  card.grade = gradeIncidentCard(card);
18497
- return import_types63.IncidentCardSchema.parse(card);
18648
+ return import_types64.IncidentCardSchema.parse(card);
18498
18649
  }
18499
18650
  var GRADE_PRIORS_VERSION = "sniper-architecture-priors-2026-10-08";
18500
18651
  var GRADE_WEIGHTS = {
@@ -18601,7 +18752,7 @@ function gradeIncidentCard(card) {
18601
18752
 
18602
18753
  // src/ask.ts
18603
18754
  init_cjs_shims();
18604
- var import_types64 = require("@neat.is/types");
18755
+ var import_types65 = require("@neat.is/types");
18605
18756
  var DEFAULT_MAX_NODES = 3;
18606
18757
  var MAX_FACTS_PER_SECTION = 6;
18607
18758
  var INTENT_RULES = [
@@ -18837,11 +18988,11 @@ function idBody(id) {
18837
18988
  return colon >= 0 ? id.slice(colon + 1) : id;
18838
18989
  }
18839
18990
  var TYPE_NOUNS = [
18840
- { nouns: ["database", "db", "table"], type: import_types64.NodeType.DatabaseNode },
18841
- { nouns: ["service", "api", "backend"], type: import_types64.NodeType.ServiceNode },
18842
- { nouns: ["route", "endpoint"], type: import_types64.NodeType.RouteNode },
18843
- { nouns: ["file"], type: import_types64.NodeType.FileNode },
18844
- { nouns: ["config"], type: import_types64.NodeType.ConfigNode }
18991
+ { nouns: ["database", "db", "table"], type: import_types65.NodeType.DatabaseNode },
18992
+ { nouns: ["service", "api", "backend"], type: import_types65.NodeType.ServiceNode },
18993
+ { nouns: ["route", "endpoint"], type: import_types65.NodeType.RouteNode },
18994
+ { nouns: ["file"], type: import_types65.NodeType.FileNode },
18995
+ { nouns: ["config"], type: import_types65.NodeType.ConfigNode }
18845
18996
  ];
18846
18997
  var EMBED_MIN_SCORE = 0.35;
18847
18998
  async function resolveEntities(graph, question, searchIndex, maxNodes) {
@@ -18855,7 +19006,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
18855
19006
  };
18856
19007
  graph.forEachNode((id, attrs) => {
18857
19008
  const node = attrs;
18858
- if (node.type === import_types64.NodeType.FrontierNode) return;
19009
+ if (node.type === import_types65.NodeType.FrontierNode) return;
18859
19010
  const name = nodeName(node);
18860
19011
  const body = idBody(id);
18861
19012
  const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
@@ -18874,7 +19025,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
18874
19025
  const res = await searchIndex.search(question, 10);
18875
19026
  if (res.provider !== "substring") {
18876
19027
  for (const m of res.matches) {
18877
- if (m.node.type === import_types64.NodeType.FrontierNode) continue;
19028
+ if (m.node.type === import_types65.NodeType.FrontierNode) continue;
18878
19029
  if (!graph.hasNode(m.node.id)) continue;
18879
19030
  const already = best.get(m.node.id);
18880
19031
  if (!already && m.score < EMBED_MIN_SCORE) continue;
@@ -18934,7 +19085,7 @@ function edgeSignalNote(e) {
18934
19085
  function buildRootCauseSection(graph, node, incidents, now) {
18935
19086
  const result = getRootCause(graph, node, void 0, incidents, { now });
18936
19087
  if (!result) return null;
18937
- const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ?? import_types64.Provenance.OBSERVED;
19088
+ const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ?? import_types65.Provenance.OBSERVED;
18938
19089
  const facts = [
18939
19090
  {
18940
19091
  text: `Root cause: ${result.rootCauseNode} \u2014 ${result.rootCauseReason}`,
@@ -18984,7 +19135,7 @@ function buildObservedSection(graph, node) {
18984
19135
  if (result.observed && result.inboundObservedCount > 0) {
18985
19136
  facts.push({
18986
19137
  text: `no outbound runtime calls, but OTel observed ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 a pure receiver`,
18987
- provenance: import_types64.Provenance.OBSERVED
19138
+ provenance: import_types65.Provenance.OBSERVED
18988
19139
  });
18989
19140
  } else {
18990
19141
  return null;
@@ -19007,10 +19158,10 @@ function buildBlastSection(graph, node) {
19007
19158
  }
19008
19159
  function buildDatabaseCallersSection(graph, node) {
19009
19160
  const callers = getBlastRadius(graph, node).affectedNodes.filter((item) => {
19010
- if (graph.getNodeAttributes(item.nodeId).type !== import_types64.NodeType.ServiceNode) return false;
19161
+ if (graph.getNodeAttributes(item.nodeId).type !== import_types65.NodeType.ServiceNode) return false;
19011
19162
  return item.path.slice(1, -1).every((id) => {
19012
19163
  const type = graph.getNodeAttributes(id).type;
19013
- return type === import_types64.NodeType.FileNode || type === import_types64.NodeType.SymbolNode;
19164
+ return type === import_types65.NodeType.FileNode || type === import_types65.NodeType.SymbolNode;
19014
19165
  });
19015
19166
  });
19016
19167
  return {
@@ -19029,7 +19180,7 @@ function buildIncidentsSection(node, incidents) {
19029
19180
  const facts = ordered.map((ev) => ({
19030
19181
  text: `${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`,
19031
19182
  // ErrorEvents are observation records — OBSERVED by definition.
19032
- provenance: import_types64.Provenance.OBSERVED
19183
+ provenance: import_types65.Provenance.OBSERVED
19033
19184
  }));
19034
19185
  return { heading: `Recent incidents (OBSERVED) \u2014 ${relevant.length} recorded`, facts };
19035
19186
  }
@@ -19052,8 +19203,8 @@ function runtimeEdgeState(graph) {
19052
19203
  let observed = false;
19053
19204
  let stale = false;
19054
19205
  graph.forEachEdge((_id, attrs) => {
19055
- if (attrs.provenance === import_types64.Provenance.OBSERVED) observed = true;
19056
- if (attrs.provenance === import_types64.Provenance.STALE) stale = true;
19206
+ if (attrs.provenance === import_types65.Provenance.OBSERVED) observed = true;
19207
+ if (attrs.provenance === import_types65.Provenance.STALE) stale = true;
19057
19208
  });
19058
19209
  return { observed, stale };
19059
19210
  }
@@ -19121,7 +19272,7 @@ function buildGlobalIncidentsSection(incidents) {
19121
19272
  }
19122
19273
  const byKey = /* @__PURE__ */ new Map();
19123
19274
  for (const ev of incidents) {
19124
- const key = ev.affectedNode || (0, import_types64.serviceId)(ev.service);
19275
+ const key = ev.affectedNode || (0, import_types65.serviceId)(ev.service);
19125
19276
  const cur = byKey.get(key);
19126
19277
  if (!cur) {
19127
19278
  byKey.set(key, { key, count: 1, latest: ev.timestamp, sampleMsg: ev.errorMessage });
@@ -19136,7 +19287,7 @@ function buildGlobalIncidentsSection(incidents) {
19136
19287
  const rows = [...byKey.values()].sort((a, b) => b.count - a.count || b.latest.localeCompare(a.latest) || a.key.localeCompare(b.key)).slice(0, MAX_FACTS_PER_SECTION);
19137
19288
  const facts = rows.map((r) => ({
19138
19289
  text: `${r.key} \u2014 ${r.count} incident${r.count === 1 ? "" : "s"}, latest ${r.latest}: ${r.sampleMsg}`,
19139
- provenance: import_types64.Provenance.OBSERVED
19290
+ provenance: import_types65.Provenance.OBSERVED
19140
19291
  }));
19141
19292
  return {
19142
19293
  heading: `Incidents across the system \u2014 ${incidents.length} recorded`,
@@ -19149,7 +19300,7 @@ function buildOverviewSections(graph, incidents) {
19149
19300
  graph.forEachNode((_id, attrs) => {
19150
19301
  const node = attrs;
19151
19302
  nodeByType.set(node.type, (nodeByType.get(node.type) ?? 0) + 1);
19152
- if (node.type === import_types64.NodeType.ServiceNode) services.push(node.id);
19303
+ if (node.type === import_types65.NodeType.ServiceNode) services.push(node.id);
19153
19304
  });
19154
19305
  const edgeByProv = /* @__PURE__ */ new Map();
19155
19306
  graph.forEachEdge((_id, attrs) => {
@@ -19161,10 +19312,10 @@ function buildOverviewSections(graph, incidents) {
19161
19312
  const shapeFacts = [
19162
19313
  { text: `${graph.order} nodes, ${graph.size} edges` },
19163
19314
  {
19164
- text: `${count(import_types64.NodeType.ServiceNode)} services, ${count(import_types64.NodeType.FileNode)} files, ${count(import_types64.NodeType.SymbolNode)} symbols, ${count(import_types64.NodeType.DatabaseNode)} databases`
19315
+ text: `${count(import_types65.NodeType.ServiceNode)} services, ${count(import_types65.NodeType.FileNode)} files, ${count(import_types65.NodeType.SymbolNode)} symbols, ${count(import_types65.NodeType.DatabaseNode)} databases`
19165
19316
  }
19166
19317
  ];
19167
- for (const p of [import_types64.Provenance.EXTRACTED, import_types64.Provenance.OBSERVED, import_types64.Provenance.INFERRED, import_types64.Provenance.STALE]) {
19318
+ for (const p of [import_types65.Provenance.EXTRACTED, import_types65.Provenance.OBSERVED, import_types65.Provenance.INFERRED, import_types65.Provenance.STALE]) {
19168
19319
  const n = edgeByProv.get(p) ?? 0;
19169
19320
  if (n > 0) shapeFacts.push({ text: `${n} ${p} edge${n === 1 ? "" : "s"}`, provenance: p });
19170
19321
  }
@@ -19181,7 +19332,7 @@ function buildOverviewSections(graph, incidents) {
19181
19332
  if (incidents && incidents.length > 0) {
19182
19333
  const incCount = /* @__PURE__ */ new Map();
19183
19334
  for (const ev of incidents) {
19184
- const key = ev.affectedNode || (0, import_types64.serviceId)(ev.service);
19335
+ const key = ev.affectedNode || (0, import_types65.serviceId)(ev.service);
19185
19336
  incCount.set(key, (incCount.get(key) ?? 0) + 1);
19186
19337
  }
19187
19338
  const top = [...incCount.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_FACTS_PER_SECTION);
@@ -19189,7 +19340,7 @@ function buildOverviewSections(graph, incidents) {
19189
19340
  heading: `Nodes with incidents \u2014 ${incidents.length} recorded`,
19190
19341
  facts: top.map(([k, n]) => ({
19191
19342
  text: `${k} \u2014 ${n} incident${n === 1 ? "" : "s"}`,
19192
- provenance: import_types64.Provenance.OBSERVED
19343
+ provenance: import_types65.Provenance.OBSERVED
19193
19344
  }))
19194
19345
  });
19195
19346
  }
@@ -19320,7 +19471,7 @@ async function askGraph(graph, question, opts = {}) {
19320
19471
  let scope;
19321
19472
  if (primary) {
19322
19473
  scope = "node";
19323
- const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type === import_types64.NodeType.DatabaseNode && /\b(?:which|what)\s+services?\s+(?:talks?\s+to|connects?\s+to|uses?|hits?|calls?|reads?\s+from|writes?\s+to)\b/i.test(question);
19474
+ const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type === import_types65.NodeType.DatabaseNode && /\b(?:which|what)\s+services?\s+(?:talks?\s+to|connects?\s+to|uses?|hits?|calls?|reads?\s+from|writes?\s+to)\b/i.test(question);
19324
19475
  if (callersQuestion) sections.push(buildDatabaseCallersSection(graph, primary));
19325
19476
  for (const kind of SECTION_ORDER[intent]) {
19326
19477
  if (callersQuestion && kind === "blast") continue;
@@ -19338,7 +19489,7 @@ async function askGraph(graph, question, opts = {}) {
19338
19489
  const provSet = /* @__PURE__ */ new Set();
19339
19490
  for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
19340
19491
  const confidence = sections[0]?.facts[0]?.confidence;
19341
- return import_types64.AskResultSchema.parse({
19492
+ return import_types65.AskResultSchema.parse({
19342
19493
  question,
19343
19494
  intent,
19344
19495
  matched,
@@ -19485,7 +19636,7 @@ init_cjs_shims();
19485
19636
  var import_node_fs41 = require("fs");
19486
19637
  var import_node_os3 = __toESM(require("os"), 1);
19487
19638
  var import_node_path77 = __toESM(require("path"), 1);
19488
- var import_types65 = require("@neat.is/types");
19639
+ var import_types66 = require("@neat.is/types");
19489
19640
  var LOCK_TIMEOUT_MS = 5e3;
19490
19641
  var LOCK_RETRY_MS = 50;
19491
19642
  function neatHome() {
@@ -19755,10 +19906,10 @@ async function readRegistry() {
19755
19906
  throw err;
19756
19907
  }
19757
19908
  const parsed = JSON.parse(raw);
19758
- return import_types65.RegistryFileSchema.parse(parsed);
19909
+ return import_types66.RegistryFileSchema.parse(parsed);
19759
19910
  }
19760
19911
  async function writeRegistry(reg) {
19761
- const validated = import_types65.RegistryFileSchema.parse(reg);
19912
+ const validated = import_types66.RegistryFileSchema.parse(reg);
19762
19913
  await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
19763
19914
  }
19764
19915
  var RegistryError = class extends Error {
@@ -19908,11 +20059,11 @@ async function pruneRegistry(opts = {}) {
19908
20059
  init_cjs_shims();
19909
20060
  var import_node_fs42 = require("fs");
19910
20061
  var import_zod = require("zod");
19911
- var import_types66 = require("@neat.is/types");
20062
+ var import_types67 = require("@neat.is/types");
19912
20063
  var SSE_HEARTBEAT_MS = 3e4;
19913
20064
  var SSE_BACKPRESSURE_CAP = 1e3;
19914
20065
  var INCIDENT_TRIGGER_STREAM_SCOPE = "incident-only-v1";
19915
- var IncidentTriggerSchema = import_types66.IncidentEventPayloadSchema.extend({
20066
+ var IncidentTriggerSchema = import_types67.IncidentEventPayloadSchema.extend({
19916
20067
  incidentId: import_zod.z.string().regex(/^[A-Za-z0-9:_-]{1,100}$/),
19917
20068
  affectedNode: import_zod.z.string().min(1).max(512),
19918
20069
  service: import_zod.z.string().min(1).max(256),
@@ -19940,12 +20091,12 @@ function loadIncidentReplay(errorsPath, cursor) {
19940
20091
  if (!isExtractionFailure(row)) throw new Error("incident replay unavailable");
19941
20092
  continue;
19942
20093
  }
19943
- const event = import_types66.ErrorEventSchema.parse(row);
20094
+ const event = import_types67.ErrorEventSchema.parse(row);
19944
20095
  const trigger = IncidentTriggerSchema.parse({
19945
20096
  incidentId: event.id,
19946
20097
  affectedNode: event.affectedNode,
19947
20098
  service: event.service,
19948
- incidentKind: (0, import_types66.incidentKindOf)(event),
20099
+ incidentKind: (0, import_types67.incidentKindOf)(event),
19949
20100
  at: event.timestamp
19950
20101
  });
19951
20102
  const prior = seen.get(trigger.incidentId), encoded = JSON.stringify(trigger);
@@ -20320,7 +20471,7 @@ function renderVerdict({
20320
20471
  }
20321
20472
 
20322
20473
  // src/pr-verdict.ts
20323
- var import_types67 = require("@neat.is/types");
20474
+ var import_types68 = require("@neat.is/types");
20324
20475
 
20325
20476
  // src/connectors/hosted-repos.ts
20326
20477
  init_cjs_shims();
@@ -20393,7 +20544,7 @@ var PrVerdictError = class extends Error {
20393
20544
  details;
20394
20545
  };
20395
20546
  function parsePrVerdictRequest(body) {
20396
- const parsed = import_types67.PrVerdictBodySchema.safeParse(body);
20547
+ const parsed = import_types68.PrVerdictBodySchema.safeParse(body);
20397
20548
  if (!parsed.success) {
20398
20549
  throw new PrVerdictError("invalid pr-verdict body", 400, void 0, parsed.error.issues);
20399
20550
  }
@@ -20863,15 +21014,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
20863
21014
 
20864
21015
  // src/connectors/index.ts
20865
21016
  init_cjs_shims();
20866
- var import_types68 = require("@neat.is/types");
21017
+ var import_types69 = require("@neat.is/types");
20867
21018
  var NO_ENV = "unknown";
20868
21019
  function staticCallSiteFor(graph, serviceName, targetNodeId) {
20869
21020
  if (!graph.hasNode(targetNodeId)) return void 0;
20870
21021
  const sites = [];
20871
21022
  for (const edgeId of graph.inboundEdges(targetNodeId)) {
20872
21023
  const edge = graph.getEdgeAttributes(edgeId);
20873
- if (edge.provenance !== import_types68.Provenance.EXTRACTED) continue;
20874
- const parsed = (0, import_types68.parseFileId)(edge.source);
21024
+ if (edge.provenance !== import_types69.Provenance.EXTRACTED) continue;
21025
+ const parsed = (0, import_types69.parseFileId)(edge.source);
20875
21026
  if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
20876
21027
  const site = { relPath: edge.evidence.file };
20877
21028
  if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
@@ -20882,7 +21033,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
20882
21033
  function routeCallSiteFor(graph, targetNodeId) {
20883
21034
  if (!graph.hasNode(targetNodeId)) return void 0;
20884
21035
  const attrs = graph.getNodeAttributes(targetNodeId);
20885
- if (attrs.type !== import_types68.NodeType.RouteNode || !attrs.path) return void 0;
21036
+ if (attrs.type !== import_types69.NodeType.RouteNode || !attrs.path) return void 0;
20886
21037
  const site = { relPath: attrs.path };
20887
21038
  if (attrs.line !== void 0) site.line = attrs.line;
20888
21039
  return site;
@@ -21606,23 +21757,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
21606
21757
 
21607
21758
  // src/connectors/supabase/resolve.ts
21608
21759
  init_cjs_shims();
21609
- var import_types70 = require("@neat.is/types");
21760
+ var import_types71 = require("@neat.is/types");
21610
21761
  function createSupabaseResolveTarget(graph, config) {
21611
21762
  return (signal, _ctx) => {
21612
21763
  if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
21613
21764
  return null;
21614
21765
  }
21615
- const subResourceId = (0, import_types70.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
21766
+ const subResourceId = (0, import_types71.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
21616
21767
  if (graph.hasNode(subResourceId)) {
21617
- return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types70.EdgeType.CALLS };
21768
+ return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types71.EdgeType.CALLS };
21618
21769
  }
21619
- const bareResourceId = (0, import_types70.infraId)(signal.targetKind, signal.targetName);
21770
+ const bareResourceId = (0, import_types71.infraId)(signal.targetKind, signal.targetName);
21620
21771
  if (graph.hasNode(bareResourceId)) {
21621
- return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types70.EdgeType.CALLS };
21772
+ return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types71.EdgeType.CALLS };
21622
21773
  }
21623
- const projectLevelId = (0, import_types70.infraId)("supabase", config.nodeRef);
21774
+ const projectLevelId = (0, import_types71.infraId)("supabase", config.nodeRef);
21624
21775
  if (graph.hasNode(projectLevelId)) {
21625
- return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types70.EdgeType.CALLS };
21776
+ return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types71.EdgeType.CALLS };
21626
21777
  }
21627
21778
  return null;
21628
21779
  };
@@ -21715,7 +21866,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
21715
21866
 
21716
21867
  // src/connectors/railway/index.ts
21717
21868
  init_cjs_shims();
21718
- var import_types74 = require("@neat.is/types");
21869
+ var import_types75 = require("@neat.is/types");
21719
21870
 
21720
21871
  // src/connectors/railway/client.ts
21721
21872
  init_cjs_shims();
@@ -21866,7 +22017,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
21866
22017
  const out = [];
21867
22018
  graph.forEachNode((_id, attrs) => {
21868
22019
  const node = attrs;
21869
- if (node.type !== import_types74.NodeType.RouteNode) return;
22020
+ if (node.type !== import_types75.NodeType.RouteNode) return;
21870
22021
  const route = attrs;
21871
22022
  if (route.service !== serviceName) return;
21872
22023
  out.push({
@@ -21970,12 +22121,12 @@ function createRailwayResolveTarget(config) {
21970
22121
  const serviceName = config.serviceNameById[config.serviceId];
21971
22122
  if (!serviceName) return null;
21972
22123
  if (signal.targetKind === ROUTE_TARGET_KIND) {
21973
- return { targetNodeId: signal.targetName, serviceName, edgeType: import_types74.EdgeType.CALLS };
22124
+ return { targetNodeId: signal.targetName, serviceName, edgeType: import_types75.EdgeType.CALLS };
21974
22125
  }
21975
22126
  if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
21976
22127
  const peerName = config.serviceNameById[signal.targetName];
21977
22128
  if (!peerName) return null;
21978
- return { targetNodeId: (0, import_types74.serviceId)(peerName), serviceName, edgeType: import_types74.EdgeType.CONNECTS_TO };
22129
+ return { targetNodeId: (0, import_types75.serviceId)(peerName), serviceName, edgeType: import_types75.EdgeType.CONNECTS_TO };
21979
22130
  }
21980
22131
  return null;
21981
22132
  };
@@ -22163,11 +22314,11 @@ function mapLogEntriesToSignals(entries) {
22163
22314
 
22164
22315
  // src/connectors/firebase/resolve.ts
22165
22316
  init_cjs_shims();
22166
- var import_types76 = require("@neat.is/types");
22317
+ var import_types77 = require("@neat.is/types");
22167
22318
 
22168
22319
  // src/connectors/infer-service.ts
22169
22320
  init_cjs_shims();
22170
- var import_types75 = require("@neat.is/types");
22321
+ var import_types76 = require("@neat.is/types");
22171
22322
  function normalizeName(name) {
22172
22323
  return name.toLowerCase().replace(/[^a-z0-9]/g, "");
22173
22324
  }
@@ -22178,11 +22329,11 @@ function inferServiceName(graph, resourceName, method, path104) {
22178
22329
  const owners = /* @__PURE__ */ new Set();
22179
22330
  graph.forEachNode((_id, attrs) => {
22180
22331
  const node = attrs;
22181
- if (node.type === import_types75.NodeType.ServiceNode && typeof node.name === "string") {
22332
+ if (node.type === import_types76.NodeType.ServiceNode && typeof node.name === "string") {
22182
22333
  services.push(node.name);
22183
22334
  return;
22184
22335
  }
22185
- if (node.type !== import_types75.NodeType.RouteNode) return;
22336
+ if (node.type !== import_types76.NodeType.RouteNode) return;
22186
22337
  const route = attrs;
22187
22338
  if (!route.pathTemplate || normalizePathTemplate(route.pathTemplate) !== wantedPath) return;
22188
22339
  const routeMethod = route.method.toUpperCase();
@@ -22209,7 +22360,7 @@ function routeEntriesFor(graph, serviceName) {
22209
22360
  const entries = [];
22210
22361
  graph.forEachNode((_id, attrs) => {
22211
22362
  const node = attrs;
22212
- if (node.type !== import_types76.NodeType.RouteNode) return;
22363
+ if (node.type !== import_types77.NodeType.RouteNode) return;
22213
22364
  const route = attrs;
22214
22365
  if (route.service !== serviceName) return;
22215
22366
  entries.push({
@@ -22241,7 +22392,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
22241
22392
  return {
22242
22393
  targetNodeId: match.routeNodeId,
22243
22394
  serviceName,
22244
- edgeType: import_types76.EdgeType.CALLS
22395
+ edgeType: import_types77.EdgeType.CALLS
22245
22396
  };
22246
22397
  };
22247
22398
  }
@@ -22274,7 +22425,7 @@ init_cjs_shims();
22274
22425
 
22275
22426
  // src/connectors/cloudflare/connector.ts
22276
22427
  init_cjs_shims();
22277
- var import_types78 = require("@neat.is/types");
22428
+ var import_types79 = require("@neat.is/types");
22278
22429
 
22279
22430
  // src/connectors/cloudflare/client.ts
22280
22431
  init_cjs_shims();
@@ -22438,7 +22589,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
22438
22589
  graph.forEachNode((id, attrs) => {
22439
22590
  if (found) return;
22440
22591
  const a = attrs;
22441
- if (a.type === import_types78.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
22592
+ if (a.type === import_types79.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
22442
22593
  found = id;
22443
22594
  }
22444
22595
  });
@@ -22450,7 +22601,7 @@ function findMatchingRouteNode(graph, serviceName, method, path104) {
22450
22601
  graph.forEachNode((id, attrs) => {
22451
22602
  if (found) return;
22452
22603
  const a = attrs;
22453
- if (a.type !== import_types78.NodeType.RouteNode || a.service !== serviceName) return;
22604
+ if (a.type !== import_types79.NodeType.RouteNode || a.service !== serviceName) return;
22454
22605
  if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
22455
22606
  const routeMethod = (a.method ?? "").toUpperCase();
22456
22607
  if (routeMethod !== "ALL" && routeMethod !== method) return;
@@ -22469,11 +22620,11 @@ function createCloudflareResolveTarget(config, graph) {
22469
22620
  };
22470
22621
  const mapping = config.workers?.[scriptName];
22471
22622
  if (mapping) {
22472
- const wholeFileId = (0, import_types78.fileId)(mapping.service, mapping.entryFile);
22623
+ const wholeFileId = (0, import_types79.fileId)(mapping.service, mapping.entryFile);
22473
22624
  return {
22474
22625
  targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
22475
22626
  serviceName: mapping.service,
22476
- edgeType: import_types78.EdgeType.CALLS
22627
+ edgeType: import_types79.EdgeType.CALLS
22477
22628
  };
22478
22629
  }
22479
22630
  const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
@@ -22482,13 +22633,13 @@ function createCloudflareResolveTarget(config, graph) {
22482
22633
  return {
22483
22634
  targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
22484
22635
  serviceName: fileNode.service,
22485
- edgeType: import_types78.EdgeType.CALLS
22636
+ edgeType: import_types79.EdgeType.CALLS
22486
22637
  };
22487
22638
  }
22488
22639
  return {
22489
- targetNodeId: (0, import_types78.infraId)("cloudflare-worker", scriptName),
22640
+ targetNodeId: (0, import_types79.infraId)("cloudflare-worker", scriptName),
22490
22641
  serviceName: scriptName,
22491
- edgeType: import_types78.EdgeType.CALLS,
22642
+ edgeType: import_types79.EdgeType.CALLS,
22492
22643
  ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
22493
22644
  };
22494
22645
  };
@@ -22684,14 +22835,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
22684
22835
 
22685
22836
  // src/connectors/neon/resolve.ts
22686
22837
  init_cjs_shims();
22687
- var import_types82 = require("@neat.is/types");
22838
+ var import_types83 = require("@neat.is/types");
22688
22839
  function createNeonResolveTarget(config) {
22689
22840
  return (signal) => {
22690
22841
  if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
22691
22842
  return {
22692
- targetNodeId: (0, import_types82.infraId)("sql-table", signal.targetName),
22843
+ targetNodeId: (0, import_types83.infraId)("sql-table", signal.targetName),
22693
22844
  serviceName: config.serviceName,
22694
- edgeType: import_types82.EdgeType.CALLS,
22845
+ edgeType: import_types83.EdgeType.CALLS,
22695
22846
  ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
22696
22847
  };
22697
22848
  };
@@ -22872,14 +23023,14 @@ function mapLogEntriesToSignals2(entries) {
22872
23023
 
22873
23024
  // src/connectors/cloud-run/resolve.ts
22874
23025
  init_cjs_shims();
22875
- var import_types86 = require("@neat.is/types");
23026
+ var import_types87 = require("@neat.is/types");
22876
23027
  var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
22877
23028
  function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
22878
23029
  let found = null;
22879
23030
  graph.forEachNode((_id, attrs) => {
22880
23031
  if (found) return;
22881
23032
  const node = attrs;
22882
- if (node.type !== import_types86.NodeType.RouteNode) return;
23033
+ if (node.type !== import_types87.NodeType.RouteNode) return;
22883
23034
  const route = attrs;
22884
23035
  if (route.service !== serviceName || !route.pathTemplate) return;
22885
23036
  if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
@@ -22904,13 +23055,13 @@ function createCloudRunResolveTarget(graph, config) {
22904
23055
  normalizePathTemplate(path104)
22905
23056
  );
22906
23057
  if (routeNodeId) {
22907
- return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types86.EdgeType.CALLS };
23058
+ return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types87.EdgeType.CALLS };
22908
23059
  }
22909
23060
  }
22910
23061
  return {
22911
- targetNodeId: (0, import_types86.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
23062
+ targetNodeId: (0, import_types87.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
22912
23063
  serviceName: mappedService ?? gcpServiceName,
22913
- edgeType: import_types86.EdgeType.CALLS,
23064
+ edgeType: import_types87.EdgeType.CALLS,
22914
23065
  ensureInfraNode: {
22915
23066
  kind: CLOUD_RUN_SERVICE_INFRA_KIND,
22916
23067
  name: gcpServiceName,
@@ -23092,14 +23243,14 @@ function mapLogEntriesToSignals3(entries) {
23092
23243
 
23093
23244
  // src/connectors/gcp-lb/resolve.ts
23094
23245
  init_cjs_shims();
23095
- var import_types90 = require("@neat.is/types");
23246
+ var import_types91 = require("@neat.is/types");
23096
23247
  var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
23097
23248
  function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
23098
23249
  let found = null;
23099
23250
  graph.forEachNode((_id, attrs) => {
23100
23251
  if (found) return;
23101
23252
  const node = attrs;
23102
- if (node.type !== import_types90.NodeType.RouteNode) return;
23253
+ if (node.type !== import_types91.NodeType.RouteNode) return;
23103
23254
  const route = attrs;
23104
23255
  if (route.service !== serviceName || !route.pathTemplate) return;
23105
23256
  if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
@@ -23124,13 +23275,13 @@ function createGcpLbResolveTarget(graph, config) {
23124
23275
  normalizePathTemplate(path104)
23125
23276
  );
23126
23277
  if (routeNodeId) {
23127
- return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types90.EdgeType.CALLS };
23278
+ return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types91.EdgeType.CALLS };
23128
23279
  }
23129
23280
  }
23130
23281
  return {
23131
- targetNodeId: (0, import_types90.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
23282
+ targetNodeId: (0, import_types91.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
23132
23283
  serviceName: mappedService ?? backendServiceName,
23133
- edgeType: import_types90.EdgeType.CALLS,
23284
+ edgeType: import_types91.EdgeType.CALLS,
23134
23285
  ensureInfraNode: {
23135
23286
  kind: GCP_LB_BACKEND_INFRA_KIND,
23136
23287
  name: backendServiceName,
@@ -23171,7 +23322,7 @@ function createGcpLbConnector(graph, config = {}) {
23171
23322
 
23172
23323
  // src/connectors/render/index.ts
23173
23324
  init_cjs_shims();
23174
- var import_types93 = require("@neat.is/types");
23325
+ var import_types94 = require("@neat.is/types");
23175
23326
 
23176
23327
  // src/connectors/render/types.ts
23177
23328
  init_cjs_shims();
@@ -23249,7 +23400,7 @@ function buildRenderRouteIndex(graph, serviceName) {
23249
23400
  const out = [];
23250
23401
  graph.forEachNode((_id, attrs) => {
23251
23402
  const node = attrs;
23252
- if (node.type !== import_types93.NodeType.RouteNode) return;
23403
+ if (node.type !== import_types94.NodeType.RouteNode) return;
23253
23404
  const route = attrs;
23254
23405
  if (route.service !== serviceName) return;
23255
23406
  out.push({
@@ -23334,7 +23485,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
23334
23485
  function createRenderResolveTarget(config) {
23335
23486
  return (signal) => {
23336
23487
  if (signal.targetKind === ROUTE_TARGET_KIND2) {
23337
- return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types93.EdgeType.CALLS };
23488
+ return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types94.EdgeType.CALLS };
23338
23489
  }
23339
23490
  return null;
23340
23491
  };
@@ -23472,21 +23623,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
23472
23623
 
23473
23624
  // src/connectors/planetscale/resolve.ts
23474
23625
  init_cjs_shims();
23475
- var import_types97 = require("@neat.is/types");
23626
+ var import_types98 = require("@neat.is/types");
23476
23627
  var PLANETSCALE_DATABASE_KIND = "planetscale-database";
23477
23628
  function createPlanetscaleResolveTarget(graph, config) {
23478
23629
  const databaseName = `${config.organization}/${config.database}`;
23479
23630
  return (signal, _ctx) => {
23480
23631
  if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
23481
- const tableId = (0, import_types97.infraId)("sql-table", signal.targetName);
23632
+ const tableId = (0, import_types98.infraId)("sql-table", signal.targetName);
23482
23633
  if (graph.hasNode(tableId)) {
23483
- return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types97.EdgeType.CALLS };
23634
+ return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types98.EdgeType.CALLS };
23484
23635
  }
23485
- const providerId = (0, import_types97.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
23636
+ const providerId = (0, import_types98.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
23486
23637
  return {
23487
23638
  targetNodeId: providerId,
23488
23639
  serviceName: config.serviceName,
23489
- edgeType: import_types97.EdgeType.CALLS,
23640
+ edgeType: import_types98.EdgeType.CALLS,
23490
23641
  ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
23491
23642
  };
23492
23643
  };
@@ -23751,7 +23902,7 @@ function mapBuildsToSignals(builds, serviceName) {
23751
23902
 
23752
23903
  // src/connectors/eas/resolve.ts
23753
23904
  init_cjs_shims();
23754
- var import_types102 = require("@neat.is/types");
23905
+ var import_types103 = require("@neat.is/types");
23755
23906
  var NO_ENV2 = "unknown";
23756
23907
  var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
23757
23908
  var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
@@ -23767,8 +23918,8 @@ function configBasenamesForPhase(phase) {
23767
23918
  function configNodeService(graph, configNodeId) {
23768
23919
  for (const edgeId of graph.inboundEdges(configNodeId)) {
23769
23920
  const edge = graph.getEdgeAttributes(edgeId);
23770
- if (edge.type !== import_types102.EdgeType.CONFIGURED_BY) continue;
23771
- const parsed = (0, import_types102.parseFileId)(edge.source);
23921
+ if (edge.type !== import_types103.EdgeType.CONFIGURED_BY) continue;
23922
+ const parsed = (0, import_types103.parseFileId)(edge.source);
23772
23923
  if (parsed) return parsed.service;
23773
23924
  }
23774
23925
  return null;
@@ -23779,7 +23930,7 @@ function findConfigNode(graph, basenames, serviceName) {
23779
23930
  graph.forEachNode((id, attrs) => {
23780
23931
  if (scoped) return;
23781
23932
  const node = attrs;
23782
- if (node.type !== import_types102.NodeType.ConfigNode) return;
23933
+ if (node.type !== import_types103.NodeType.ConfigNode) return;
23783
23934
  if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
23784
23935
  if (anyMatch === null) anyMatch = id;
23785
23936
  if (configNodeService(graph, id) === serviceName) scoped = id;
@@ -23796,13 +23947,13 @@ function createEasResolveTarget(graph) {
23796
23947
  if (basenames.length > 0) {
23797
23948
  const configNodeId = findConfigNode(graph, basenames, serviceName);
23798
23949
  if (configNodeId) {
23799
- return { targetNodeId: configNodeId, serviceName, edgeType: import_types102.EdgeType.CALLS };
23950
+ return { targetNodeId: configNodeId, serviceName, edgeType: import_types103.EdgeType.CALLS };
23800
23951
  }
23801
23952
  }
23802
23953
  return {
23803
23954
  targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
23804
23955
  serviceName,
23805
- edgeType: import_types102.EdgeType.CALLS
23956
+ edgeType: import_types103.EdgeType.CALLS
23806
23957
  };
23807
23958
  };
23808
23959
  }
@@ -24521,7 +24672,7 @@ function serializeGraph(graph) {
24521
24672
  graph.forEachEdge((_id, attrs) => {
24522
24673
  edges.push(attrs);
24523
24674
  });
24524
- return { nodes, edges };
24675
+ return { nodes, edges, sourceBaselines: readSourceBaselines(graph) };
24525
24676
  }
24526
24677
  function projectFromReq(req, singleProject, registry) {
24527
24678
  const params = req.params;
@@ -24704,11 +24855,11 @@ function registerRoutes(scope, ctx) {
24704
24855
  const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
24705
24856
  const parsed = [];
24706
24857
  for (const c of candidates) {
24707
- const r = import_types105.DivergenceTypeSchema.safeParse(c);
24858
+ const r = import_types106.DivergenceTypeSchema.safeParse(c);
24708
24859
  if (!r.success) {
24709
24860
  return reply.code(400).send({
24710
24861
  error: `unknown divergence type "${c}"`,
24711
- allowed: import_types105.DivergenceTypeSchema.options
24862
+ allowed: import_types106.DivergenceTypeSchema.options
24712
24863
  });
24713
24864
  }
24714
24865
  parsed.push(r.data);
@@ -25145,7 +25296,7 @@ function registerRoutes(scope, ctx) {
25145
25296
  const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
25146
25297
  let violations = await log.readAll();
25147
25298
  if (req.query.severity) {
25148
- const sev = import_types105.PolicySeveritySchema.safeParse(req.query.severity);
25299
+ const sev = import_types106.PolicySeveritySchema.safeParse(req.query.severity);
25149
25300
  if (!sev.success) {
25150
25301
  return reply.code(400).send({
25151
25302
  error: "invalid severity",
@@ -25184,7 +25335,7 @@ function registerRoutes(scope, ctx) {
25184
25335
  scope.post("/policies/check", async (req, reply) => {
25185
25336
  const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
25186
25337
  if (!proj) return;
25187
- const parsed = import_types105.PoliciesCheckBodySchema.safeParse(req.body ?? {});
25338
+ const parsed = import_types106.PoliciesCheckBodySchema.safeParse(req.body ?? {});
25188
25339
  if (!parsed.success) {
25189
25340
  return reply.code(400).send({
25190
25341
  error: "invalid /policies/check body",
@@ -25545,7 +25696,7 @@ init_auth();
25545
25696
 
25546
25697
  // src/hang-sensor.ts
25547
25698
  init_cjs_shims();
25548
- var import_types106 = require("@neat.is/types");
25699
+ var import_types107 = require("@neat.is/types");
25549
25700
  var RECONCILE_INCIDENT_LIMIT = 500;
25550
25701
  function stageHangSurfaces(graph, incidents) {
25551
25702
  const boundaries = /* @__PURE__ */ new Set();
@@ -25558,7 +25709,7 @@ function stageHangSurfaces(graph, incidents) {
25558
25709
  if (!isBoundaryTimeoutSymptom(ctx)) continue;
25559
25710
  const hop = resolveHangHop(graph, boundary, incidents);
25560
25711
  if (!hop) continue;
25561
- if (stageFrontierEdge(graph, hop.source, hop.target, import_types106.EdgeType.CALLS)) staged++;
25712
+ if (stageFrontierEdge(graph, hop.source, hop.target, import_types107.EdgeType.CALLS)) staged++;
25562
25713
  }
25563
25714
  return staged;
25564
25715
  }
@@ -25691,6 +25842,15 @@ async function fetchPodLog(transport, namespace, podName, opts = {}) {
25691
25842
  return void 0;
25692
25843
  }
25693
25844
  }
25845
+ function hasLogContent(text) {
25846
+ return typeof text === "string" && text.trim().length > 0;
25847
+ }
25848
+ async function fetchPodProcessLog(transport, namespace, podName, opts = {}) {
25849
+ const previous = await fetchPodLog(transport, namespace, podName, { ...opts, previous: true });
25850
+ if (hasLogContent(previous)) return previous;
25851
+ const current = await fetchPodLog(transport, namespace, podName, { ...opts, previous: false });
25852
+ return hasLogContent(current) ? current : void 0;
25853
+ }
25694
25854
 
25695
25855
  // src/connectors/kubernetes/kubeconfig.ts
25696
25856
  init_cjs_shims();
@@ -26116,7 +26276,7 @@ function mapWorkloadsToSignals(deployments, pods, config, logs) {
26116
26276
 
26117
26277
  // src/connectors/kubernetes/resolve.ts
26118
26278
  init_cjs_shims();
26119
- var import_types108 = require("@neat.is/types");
26279
+ var import_types109 = require("@neat.is/types");
26120
26280
  var NO_ENV3 = "unknown";
26121
26281
  function createK8sResolveTarget(graph) {
26122
26282
  return (signal) => {
@@ -26127,7 +26287,7 @@ function createK8sResolveTarget(graph) {
26127
26287
  return {
26128
26288
  targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV3),
26129
26289
  serviceName,
26130
- edgeType: import_types108.EdgeType.CALLS
26290
+ edgeType: import_types109.EdgeType.CALLS
26131
26291
  };
26132
26292
  };
26133
26293
  }
@@ -26237,11 +26397,10 @@ var KubernetesConnector = class {
26237
26397
  const targets = faultedPods(deployments, pods, this.config);
26238
26398
  await Promise.all(
26239
26399
  targets.map(async (t) => {
26240
- const text = await fetchPodLog(transport, namespace, t.podName, {
26400
+ const text = await fetchPodProcessLog(transport, namespace, t.podName, {
26241
26401
  ...t.container ? { container: t.container } : {},
26242
26402
  tailLines: PROCESS_LOG_TAIL_LINES,
26243
26403
  limitBytes: PROCESS_LOG_LIMIT_BYTES,
26244
- previous: true,
26245
26404
  ...opts
26246
26405
  });
26247
26406
  if (typeof text === "string" && text.length > 0) logs.set(podLogKey(t.podName, t.container), text);
@@ -26281,7 +26440,7 @@ var import_node_fs47 = require("fs");
26281
26440
  var import_node_path83 = __toESM(require("path"), 1);
26282
26441
 
26283
26442
  // src/daemon.ts
26284
- var import_types111 = require("@neat.is/types");
26443
+ var import_types112 = require("@neat.is/types");
26285
26444
  function daemonJsonPath(scanPath) {
26286
26445
  return import_node_path84.default.join(scanPath, "neat-out", "daemon.json");
26287
26446
  }
@@ -32420,7 +32579,7 @@ var import_node_path96 = __toESM(require("path"), 1);
32420
32579
 
32421
32580
  // src/cli-client.ts
32422
32581
  init_cjs_shims();
32423
- var import_types112 = require("@neat.is/types");
32582
+ var import_types113 = require("@neat.is/types");
32424
32583
  var HttpError = class extends Error {
32425
32584
  constructor(status2, message, responseBody = "") {
32426
32585
  super(message);
@@ -32562,7 +32721,7 @@ async function runBlastRadius(client, input) {
32562
32721
  }
32563
32722
  }
32564
32723
  function formatBlastEntry(n) {
32565
- const tag = n.edgeProvenance === import_types112.Provenance.STALE ? " [STALE \u2014 last seen too long ago]" : "";
32724
+ const tag = n.edgeProvenance === import_types113.Provenance.STALE ? " [STALE \u2014 last seen too long ago]" : "";
32566
32725
  return ` \u2022 ${n.nodeId} (distance ${n.distance}, ${n.edgeProvenance})${tag}`;
32567
32726
  }
32568
32727
  async function runDependencies(client, input) {
@@ -32619,7 +32778,7 @@ async function runObservedDependencies(client, input) {
32619
32778
  if (result.observed) {
32620
32779
  return {
32621
32780
  summary: `${input.nodeId} makes no outbound runtime calls, but OTel has observed it receiving traffic on ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 it's a pure receiver.`,
32622
- provenance: import_types112.Provenance.OBSERVED
32781
+ provenance: import_types113.Provenance.OBSERVED
32623
32782
  };
32624
32783
  }
32625
32784
  const note = result.hasExtractedOutbound ? " Static (EXTRACTED) dependencies exist but no runtime traffic has been seen \u2014 is OTel running?" : "";
@@ -32629,7 +32788,7 @@ async function runObservedDependencies(client, input) {
32629
32788
  return {
32630
32789
  summary: `${input.nodeId} has ${result.dependencies.length} runtime dependenc${result.dependencies.length === 1 ? "y" : "ies"} confirmed by OTel.`,
32631
32790
  block: blockLines.join("\n"),
32632
- provenance: import_types112.Provenance.OBSERVED
32791
+ provenance: import_types113.Provenance.OBSERVED
32633
32792
  };
32634
32793
  } catch (err) {
32635
32794
  if (err instanceof HttpError && err.status === 404) {
@@ -32683,7 +32842,7 @@ async function runIncidents(client, input) {
32683
32842
  return {
32684
32843
  summary: `${target} has ${body.total} recorded incident${body.total === 1 ? "" : "s"}; showing the ${ordered.length} most recent.`,
32685
32844
  block: blockLines.join("\n"),
32686
- provenance: import_types112.Provenance.OBSERVED
32845
+ provenance: import_types113.Provenance.OBSERVED
32687
32846
  };
32688
32847
  } catch (err) {
32689
32848
  if (err instanceof HttpError && err.status === 404) {
@@ -32792,7 +32951,7 @@ async function runStaleEdges(client, input) {
32792
32951
  return {
32793
32952
  summary: `${events.length} stale-edge transition${events.length === 1 ? "" : "s"} recorded${input.edgeType ? ` for ${input.edgeType}` : ""}.`,
32794
32953
  block: blockLines.join("\n"),
32795
- provenance: import_types112.Provenance.STALE
32954
+ provenance: import_types113.Provenance.STALE
32796
32955
  };
32797
32956
  }
32798
32957
  async function runPolicies(client, input) {
@@ -34802,12 +34961,12 @@ async function runEditorCommand(clientId, args, projectDir = process.cwd()) {
34802
34961
 
34803
34962
  // src/monitor.ts
34804
34963
  init_cjs_shims();
34805
- var import_types113 = require("@neat.is/types");
34964
+ var import_types114 = require("@neat.is/types");
34806
34965
  var OBSERVED_DEP_EDGE_TYPES = /* @__PURE__ */ new Set([
34807
- import_types113.EdgeType.CALLS,
34808
- import_types113.EdgeType.CONNECTS_TO,
34809
- import_types113.EdgeType.PUBLISHES_TO,
34810
- import_types113.EdgeType.CONSUMES_FROM
34966
+ import_types114.EdgeType.CALLS,
34967
+ import_types114.EdgeType.CONNECTS_TO,
34968
+ import_types114.EdgeType.PUBLISHES_TO,
34969
+ import_types114.EdgeType.CONSUMES_FROM
34811
34970
  ]);
34812
34971
  function divergenceKey(d) {
34813
34972
  const column = "column" in d && d.column ? d.column : "";
@@ -34877,7 +35036,7 @@ function formatDivergenceLine2(d) {
34877
35036
  }
34878
35037
  }
34879
35038
  function formatStaleLine(edgeId) {
34880
- const parsed = (0, import_types113.parseEdgeId)(edgeId);
35039
+ const parsed = (0, import_types114.parseEdgeId)(edgeId);
34881
35040
  if (parsed) {
34882
35041
  return `\u22EF stale ${parsed.source} \u2192 ${parsed.target} (observed edge went quiet)`;
34883
35042
  }
@@ -34890,7 +35049,7 @@ function divergenceJson(d) {
34890
35049
  return JSON.stringify({ kind: "divergence", ...d });
34891
35050
  }
34892
35051
  function staleJson(edgeId) {
34893
- const parsed = (0, import_types113.parseEdgeId)(edgeId);
35052
+ const parsed = (0, import_types114.parseEdgeId)(edgeId);
34894
35053
  return JSON.stringify({
34895
35054
  kind: "stale",
34896
35055
  edgeId,
@@ -34974,7 +35133,7 @@ var MonitorEmitter = class {
34974
35133
  // ignores non-OBSERVED edges and non-dependency edge types (structural
34975
35134
  // ownership), so only real runtime dependencies reach stdout.
34976
35135
  emitObservedEdge(edge) {
34977
- if (edge.provenance !== import_types113.Provenance.OBSERVED) return false;
35136
+ if (edge.provenance !== import_types114.Provenance.OBSERVED) return false;
34978
35137
  if (!OBSERVED_DEP_EDGE_TYPES.has(edge.type)) return false;
34979
35138
  const key = `edge|${edge.id}`;
34980
35139
  if (this.seen.has(key)) return false;
@@ -35155,7 +35314,7 @@ async function runMonitor(opts) {
35155
35314
  case "edge-added": {
35156
35315
  const payload = safeParse(frame.data);
35157
35316
  const edge = payload?.edge;
35158
- if (edge && edge.provenance === import_types113.Provenance.OBSERVED) {
35317
+ if (edge && edge.provenance === import_types114.Provenance.OBSERVED) {
35159
35318
  emitter.emitObservedEdge(edge);
35160
35319
  divergences.schedule();
35161
35320
  }
@@ -35426,7 +35585,7 @@ async function runSync(opts) {
35426
35585
  }
35427
35586
 
35428
35587
  // src/cli.ts
35429
- var import_types114 = require("@neat.is/types");
35588
+ var import_types115 = require("@neat.is/types");
35430
35589
  init_auth();
35431
35590
  function usage5() {
35432
35591
  const neat = commandPrefix();
@@ -36659,10 +36818,10 @@ async function runQueryVerb(cmd, parsed) {
36659
36818
  const parts = parsed.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
36660
36819
  const out = [];
36661
36820
  for (const p of parts) {
36662
- const r = import_types114.DivergenceTypeSchema.safeParse(p);
36821
+ const r = import_types115.DivergenceTypeSchema.safeParse(p);
36663
36822
  if (!r.success) {
36664
36823
  console.error(
36665
- `neat divergences: unknown --type "${p}". allowed: ${import_types114.DivergenceTypeSchema.options.join(", ")}`
36824
+ `neat divergences: unknown --type "${p}". allowed: ${import_types115.DivergenceTypeSchema.options.join(", ")}`
36666
36825
  );
36667
36826
  return 2;
36668
36827
  }