@neat.is/core 0.4.31-dev.20260718 → 0.5.1-dev.20260719

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
@@ -1283,7 +1283,7 @@ function databaseRootCauseShape(graph, origin, walk3) {
1283
1283
  for (const id of walk3.path) {
1284
1284
  const owner = resolveOwningService(graph, id);
1285
1285
  if (!owner) continue;
1286
- const { id: serviceId5, svc } = owner;
1286
+ const { id: serviceId6, svc } = owner;
1287
1287
  const deps = svc.dependencies ?? {};
1288
1288
  for (const pair of candidatePairs) {
1289
1289
  const declared = deps[pair.driver];
@@ -1296,7 +1296,7 @@ function databaseRootCauseShape(graph, origin, walk3) {
1296
1296
  );
1297
1297
  if (!result.compatible) {
1298
1298
  return {
1299
- rootCauseNode: serviceId5,
1299
+ rootCauseNode: serviceId6,
1300
1300
  rootCauseReason: result.reason ?? "incompatible driver",
1301
1301
  ...result.minDriverVersion ? {
1302
1302
  fixRecommendation: `Upgrade ${svc.name} ${pair.driver} driver to >= ${result.minDriverVersion}`
@@ -1311,7 +1311,7 @@ function serviceRootCauseShape(graph, _origin, walk3) {
1311
1311
  for (const id of walk3.path) {
1312
1312
  const owner = resolveOwningService(graph, id);
1313
1313
  if (!owner) continue;
1314
- const { id: serviceId5, svc } = owner;
1314
+ const { id: serviceId6, svc } = owner;
1315
1315
  const deps = svc.dependencies ?? {};
1316
1316
  const serviceNodeEngine = svc.nodeEngine;
1317
1317
  for (const constraint of nodeEngineConstraints()) {
@@ -1320,7 +1320,7 @@ function serviceRootCauseShape(graph, _origin, walk3) {
1320
1320
  const result = checkNodeEngineConstraint(constraint, declared, serviceNodeEngine);
1321
1321
  if (!result.compatible && result.reason) {
1322
1322
  return {
1323
- rootCauseNode: serviceId5,
1323
+ rootCauseNode: serviceId6,
1324
1324
  rootCauseReason: result.reason,
1325
1325
  ...result.requiredNodeVersion ? {
1326
1326
  fixRecommendation: `Bump ${svc.name}'s engines.node to >= ${result.requiredNodeVersion}`
@@ -1335,7 +1335,7 @@ function serviceRootCauseShape(graph, _origin, walk3) {
1335
1335
  const result = checkPackageConflict(conflict, declared, requiredDeclared);
1336
1336
  if (!result.compatible && result.reason) {
1337
1337
  return {
1338
- rootCauseNode: serviceId5,
1338
+ rootCauseNode: serviceId6,
1339
1339
  rootCauseReason: result.reason,
1340
1340
  fixRecommendation: `Upgrade ${svc.name}'s ${conflict.requires.name} to >= ${conflict.requires.minVersion}`
1341
1341
  };
@@ -1426,9 +1426,9 @@ function rootCauseFromIncidents(nodeId, incidents, errorEvent) {
1426
1426
  function isFailingCallEdge(e) {
1427
1427
  return e.type === import_types.EdgeType.CALLS && (e.signal?.errorCount ?? 0) > 0;
1428
1428
  }
1429
- function callSourcesForService(graph, serviceId5) {
1430
- const ids = [serviceId5];
1431
- for (const edgeId of graph.outboundEdges(serviceId5)) {
1429
+ function callSourcesForService(graph, serviceId6) {
1430
+ const ids = [serviceId6];
1431
+ for (const edgeId of graph.outboundEdges(serviceId6)) {
1432
1432
  const e = graph.getEdgeAttributes(edgeId);
1433
1433
  if (e.type !== import_types.EdgeType.CONTAINS) continue;
1434
1434
  const tgt = graph.getNodeAttributes(e.target);
@@ -1445,9 +1445,9 @@ function failingCallDominates(e, id, curEdge, curId) {
1445
1445
  }
1446
1446
  return id < curId;
1447
1447
  }
1448
- function dominantFailingCall(graph, serviceId5, visited) {
1448
+ function dominantFailingCall(graph, serviceId6, visited) {
1449
1449
  let best = null;
1450
- for (const src of callSourcesForService(graph, serviceId5)) {
1450
+ for (const src of callSourcesForService(graph, serviceId6)) {
1451
1451
  for (const edgeId of graph.outboundEdges(src)) {
1452
1452
  const e = graph.getEdgeAttributes(edgeId);
1453
1453
  if (!isFailingCallEdge(e)) continue;
@@ -2616,6 +2616,27 @@ function ensureLocalDatabaseNode(graph, serviceName, name, engine) {
2616
2616
  graph.addNode(id, node);
2617
2617
  return id;
2618
2618
  }
2619
+ function findDeclaredDatabaseForService(graph, serviceNodeId, engine) {
2620
+ if (!graph.hasNode(serviceNodeId)) return null;
2621
+ const sources = [serviceNodeId];
2622
+ for (const edgeId of graph.outboundEdges(serviceNodeId)) {
2623
+ const e = graph.getEdgeAttributes(edgeId);
2624
+ if (e.type === import_types3.EdgeType.CONTAINS) sources.push(e.target);
2625
+ }
2626
+ const matches = /* @__PURE__ */ new Set();
2627
+ for (const src of sources) {
2628
+ if (!graph.hasNode(src)) continue;
2629
+ for (const edgeId of graph.outboundEdges(src)) {
2630
+ const edge = graph.getEdgeAttributes(edgeId);
2631
+ if (edge.type !== import_types3.EdgeType.CONNECTS_TO || edge.provenance !== import_types3.Provenance.EXTRACTED) continue;
2632
+ if (!graph.hasNode(edge.target)) continue;
2633
+ const target = graph.getNodeAttributes(edge.target);
2634
+ if (target.type !== import_types3.NodeType.DatabaseNode || target.engine !== engine) continue;
2635
+ matches.add(edge.target);
2636
+ }
2637
+ }
2638
+ return matches.size === 1 ? [...matches][0] : null;
2639
+ }
2619
2640
  function ensureFrontierNode(graph, host, ts) {
2620
2641
  const id = frontierIdFor(host);
2621
2642
  if (graph.hasNode(id)) {
@@ -2636,6 +2657,7 @@ function ensureFrontierNode(graph, host, ts) {
2636
2657
  }
2637
2658
  function upsertObservedEdge(graph, type, source, target, ts, isError = false, evidence) {
2638
2659
  if (!graph.hasNode(source) || !graph.hasNode(target)) return null;
2660
+ const grain = source.startsWith("file:") ? "file" : "service";
2639
2661
  const id = makeObservedEdgeId(type, source, target);
2640
2662
  if (graph.hasEdge(id)) {
2641
2663
  const existing = graph.getEdgeAttributes(id);
@@ -2652,7 +2674,9 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
2652
2674
  lastObserved: ts,
2653
2675
  callCount: newSpanCount,
2654
2676
  signal: newSignal,
2655
- confidence: (0, import_types3.confidenceForObservedSignal)(newSignal)
2677
+ confidence: (0, import_types3.confidenceForObservedSignal)(newSignal),
2678
+ grain
2679
+ // backfills legacy edges that predate ADR-142
2656
2680
  };
2657
2681
  graph.replaceEdgeAttributes(id, updated);
2658
2682
  return { edge: updated, created: false };
@@ -2672,6 +2696,7 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
2672
2696
  lastObserved: ts,
2673
2697
  callCount: 1,
2674
2698
  signal,
2699
+ grain,
2675
2700
  // Call-site evidence from span code.* semconv (file-awareness.md §4 + §6).
2676
2701
  // Only set when code.filepath was present on the span — never fabricated.
2677
2702
  ...evidence ? { evidence } : {}
@@ -2874,13 +2899,18 @@ async function handleSpan(ctx, span) {
2874
2899
  ensureDatabaseNode(ctx.graph, host, span.dbSystem);
2875
2900
  targetId = (0, import_types3.databaseId)(host);
2876
2901
  } else {
2877
- const localName = span.dbName ?? span.dbSystem;
2878
- targetId = ensureLocalDatabaseNode(
2879
- ctx.graph,
2880
- span.service,
2881
- localName,
2882
- span.dbSystem
2883
- );
2902
+ const declared = findDeclaredDatabaseForService(ctx.graph, sourceId, span.dbSystem);
2903
+ if (declared) {
2904
+ targetId = declared;
2905
+ } else {
2906
+ const localName = span.dbName ?? span.dbSystem;
2907
+ targetId = ensureLocalDatabaseNode(
2908
+ ctx.graph,
2909
+ span.service,
2910
+ localName,
2911
+ span.dbSystem
2912
+ );
2913
+ }
2884
2914
  }
2885
2915
  const result = upsertObservedEdge(
2886
2916
  ctx.graph,
@@ -3064,29 +3094,29 @@ function promoteFrontierNodes(graph, opts = {}) {
3064
3094
  toPromote.push({ frontierId: id, serviceId: target });
3065
3095
  });
3066
3096
  let promoted = 0;
3067
- for (const { frontierId: frontierId2, serviceId: serviceId5 } of toPromote) {
3097
+ for (const { frontierId: frontierId2, serviceId: serviceId6 } of toPromote) {
3068
3098
  if (opts.policies && opts.policies.length > 0 && opts.policyCtx) {
3069
3099
  const gate = canPromoteFrontier(graph, frontierId2, opts.policies, opts.policyCtx);
3070
3100
  if (!gate.allowed) {
3071
3101
  continue;
3072
3102
  }
3073
3103
  }
3074
- rewireFrontierEdges(graph, frontierId2, serviceId5);
3104
+ rewireFrontierEdges(graph, frontierId2, serviceId6);
3075
3105
  graph.dropNode(frontierId2);
3076
3106
  promoted++;
3077
3107
  }
3078
3108
  return promoted;
3079
3109
  }
3080
- function rewireFrontierEdges(graph, frontierId2, serviceId5) {
3110
+ function rewireFrontierEdges(graph, frontierId2, serviceId6) {
3081
3111
  const inbound = [...graph.inboundEdges(frontierId2)];
3082
3112
  const outbound = [...graph.outboundEdges(frontierId2)];
3083
3113
  for (const edgeId of inbound) {
3084
3114
  const edge = graph.getEdgeAttributes(edgeId);
3085
- rebuildEdge(graph, edge, edge.source, serviceId5, edgeId);
3115
+ rebuildEdge(graph, edge, edge.source, serviceId6, edgeId);
3086
3116
  }
3087
3117
  for (const edgeId of outbound) {
3088
3118
  const edge = graph.getEdgeAttributes(edgeId);
3089
- rebuildEdge(graph, edge, serviceId5, edge.target, edgeId);
3119
+ rebuildEdge(graph, edge, serviceId6, edge.target, edgeId);
3090
3120
  }
3091
3121
  }
3092
3122
  function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
@@ -3894,9 +3924,9 @@ var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
3894
3924
  "StatefulSet",
3895
3925
  "DaemonSet"
3896
3926
  ]);
3897
- function addAliases(graph, serviceId5, candidates) {
3898
- if (!graph.hasNode(serviceId5)) return;
3899
- const node = graph.getNodeAttributes(serviceId5);
3927
+ function addAliases(graph, serviceId6, candidates) {
3928
+ if (!graph.hasNode(serviceId6)) return;
3929
+ const node = graph.getNodeAttributes(serviceId6);
3900
3930
  if (node.type !== import_types6.NodeType.ServiceNode) return;
3901
3931
  const set = new Set(node.aliases ?? []);
3902
3932
  for (const c of candidates) {
@@ -3906,7 +3936,7 @@ function addAliases(graph, serviceId5, candidates) {
3906
3936
  }
3907
3937
  if (set.size === 0) return;
3908
3938
  const updated = { ...node, aliases: [...set].sort() };
3909
- graph.replaceNodeAttributes(serviceId5, updated);
3939
+ graph.replaceNodeAttributes(serviceId6, updated);
3910
3940
  }
3911
3941
  function indexServicesByName(services) {
3912
3942
  const map = /* @__PURE__ */ new Map();
@@ -3939,12 +3969,12 @@ async function collectComposeAliases(graph, scanPath, serviceIndex) {
3939
3969
  }
3940
3970
  if (!compose?.services) return;
3941
3971
  for (const [composeName, svc] of Object.entries(compose.services)) {
3942
- const serviceId5 = serviceIndex.get(composeName);
3943
- if (!serviceId5) continue;
3972
+ const serviceId6 = serviceIndex.get(composeName);
3973
+ if (!serviceId6) continue;
3944
3974
  const aliases = /* @__PURE__ */ new Set([composeName]);
3945
3975
  if (svc.container_name) aliases.add(svc.container_name);
3946
3976
  if (svc.hostname) aliases.add(svc.hostname);
3947
- addAliases(graph, serviceId5, aliases);
3977
+ addAliases(graph, serviceId6, aliases);
3948
3978
  }
3949
3979
  }
3950
3980
  var LABEL_KEYS = /* @__PURE__ */ new Set([
@@ -4594,6 +4624,29 @@ async function readIfExists(filePath) {
4594
4624
  return null;
4595
4625
  }
4596
4626
  }
4627
+ async function resolveEnvVar(serviceDir, name) {
4628
+ const entries = await import_node_fs13.promises.readdir(serviceDir, { withFileTypes: true }).catch(() => []);
4629
+ const envNames = entries.filter((e) => e.isFile() && (e.name === ".env" || e.name.startsWith(".env."))).map((e) => e.name);
4630
+ const rank = (n) => n === ".env.local" ? 0 : n === ".env" ? 1 : 2;
4631
+ envNames.sort((a, b) => rank(a) - rank(b) || a.localeCompare(b));
4632
+ for (const fileName of envNames) {
4633
+ const content = await readIfExists(import_node_path15.default.join(serviceDir, fileName));
4634
+ if (!content) continue;
4635
+ for (const line of content.split("\n")) {
4636
+ const trimmed = line.trim();
4637
+ if (!trimmed || trimmed.startsWith("#")) continue;
4638
+ const eq = trimmed.indexOf("=");
4639
+ if (eq < 0) continue;
4640
+ if (trimmed.slice(0, eq).trim() !== name) continue;
4641
+ let value = trimmed.slice(eq + 1).trim();
4642
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
4643
+ value = value.slice(1, -1);
4644
+ }
4645
+ return value || null;
4646
+ }
4647
+ }
4648
+ return null;
4649
+ }
4597
4650
  async function findFirst(serviceDir, candidates) {
4598
4651
  for (const rel of candidates) {
4599
4652
  const abs = import_node_path15.default.join(serviceDir, rel);
@@ -4691,6 +4744,14 @@ async function parse3(serviceDir) {
4691
4744
  const config = parseConnectionString(urlMatch[1]);
4692
4745
  if (config) return [{ ...config, sourceFile: schemaPath }];
4693
4746
  }
4747
+ const envMatch = body.match(/url\s*=\s*env\(\s*"([^"]+)"\s*\)/);
4748
+ if (envMatch) {
4749
+ const resolved = await resolveEnvVar(serviceDir, envMatch[1]);
4750
+ if (resolved) {
4751
+ const config = parseConnectionString(resolved);
4752
+ if (config) return [{ ...config, sourceFile: schemaPath }];
4753
+ }
4754
+ }
4694
4755
  return [
4695
4756
  {
4696
4757
  host: `${engine}-prisma`,
@@ -4734,6 +4795,15 @@ async function parse4(serviceDir) {
4734
4795
  const config = parseConnectionString(urlMatch[1]);
4735
4796
  if (config) return [{ ...config, sourceFile: filePath }];
4736
4797
  }
4798
+ const urlEnvMatch = content.match(
4799
+ /(?:url|connectionString)\s*:\s*process\.env(?:\.([A-Za-z_$][\w$]*)|\[\s*['"]([^'"]+)['"]\s*\])/
4800
+ );
4801
+ if (urlEnvMatch) {
4802
+ const varName = urlEnvMatch[1] ?? urlEnvMatch[2];
4803
+ const resolved = varName ? await resolveEnvVar(serviceDir, varName) : null;
4804
+ const config = resolved ? parseConnectionString(resolved) : null;
4805
+ if (config) return [{ ...config, sourceFile: filePath }];
4806
+ }
4737
4807
  const hostMatch = content.match(/host\s*:\s*['"`]([^'"`]+)['"`]/);
4738
4808
  if (hostMatch) {
4739
4809
  const portMatch = content.match(/port\s*:\s*(\d+)/);
@@ -4787,6 +4857,15 @@ async function parse5(serviceDir) {
4787
4857
  const config = parseConnectionString(urlMatch[1]);
4788
4858
  if (config) return [{ ...config, sourceFile: filePath }];
4789
4859
  }
4860
+ const urlEnvMatch = content.match(
4861
+ /connection\s*:\s*process\.env(?:\.([A-Za-z_$][\w$]*)|\[\s*['"]([^'"]+)['"]\s*\])/
4862
+ );
4863
+ if (urlEnvMatch) {
4864
+ const varName = urlEnvMatch[1] ?? urlEnvMatch[2];
4865
+ const resolved = varName ? await resolveEnvVar(serviceDir, varName) : null;
4866
+ const config = resolved ? parseConnectionString(resolved) : null;
4867
+ if (config) return [{ ...config, sourceFile: filePath }];
4868
+ }
4790
4869
  const host = content.match(/host\s*:\s*['"`]([^'"`]+)['"`]/)?.[1];
4791
4870
  if (host) {
4792
4871
  const port = content.match(/port\s*:\s*(\d+)/)?.[1];
@@ -6335,6 +6414,16 @@ function constructorMatchesImport(name, ctx) {
6335
6414
  if (name === "createClient") return ctx.hasSupabaseJs;
6336
6415
  return ctx.hasSupabaseSsr;
6337
6416
  }
6417
+ var SUPABASE_CLIENT_ASSIGN_RE = /(?:const|let|var)\s+(\w+)\s*=\s*(?:await\s+)?(createClient|createServerClient|createBrowserClient)\s*\(/g;
6418
+ function supabaseClientVars(content, ctx) {
6419
+ const vars = /* @__PURE__ */ new Set();
6420
+ SUPABASE_CLIENT_ASSIGN_RE.lastIndex = 0;
6421
+ let m;
6422
+ while ((m = SUPABASE_CLIENT_ASSIGN_RE.exec(content)) !== null) {
6423
+ if (constructorMatchesImport(m[2], ctx)) vars.add(m[1]);
6424
+ }
6425
+ return vars;
6426
+ }
6338
6427
  function supabaseEndpointsFromFile(file, serviceDir) {
6339
6428
  const ctx = readImports2(file.content);
6340
6429
  if (!ctx.hasSupabaseJs && !ctx.hasSupabaseSsr) return [];
@@ -6367,6 +6456,34 @@ function supabaseEndpointsFromFile(file, serviceDir) {
6367
6456
  }
6368
6457
  });
6369
6458
  }
6459
+ const clientVars = supabaseClientVars(file.content, ctx);
6460
+ for (const clientVar of clientVars) {
6461
+ const accessRe = new RegExp(
6462
+ `\\b${clientVar}\\s*\\.\\s*(from|rpc)\\s*\\(\\s*['"\`]([\\w.-]+)['"\`]`,
6463
+ "g"
6464
+ );
6465
+ let am;
6466
+ while ((am = accessRe.exec(file.content)) !== null) {
6467
+ const kind = am[1] === "rpc" ? "supabase-rpc" : "supabase-table";
6468
+ const resource = am[2];
6469
+ const key = `${kind}/${resource}`;
6470
+ if (seen.has(key)) continue;
6471
+ seen.add(key);
6472
+ const line = lineOf(file.content, am[0]);
6473
+ out.push({
6474
+ infraId: (0, import_types19.infraId)(kind, resource),
6475
+ name: resource,
6476
+ kind,
6477
+ edgeType: "CALLS",
6478
+ confidenceKind: "verified-call-site",
6479
+ evidence: {
6480
+ file: import_node_path31.default.relative(serviceDir, file.path),
6481
+ line,
6482
+ snippet: snippet(file.content, line)
6483
+ }
6484
+ });
6485
+ }
6486
+ }
6370
6487
  return out;
6371
6488
  }
6372
6489
 
@@ -7448,14 +7565,23 @@ var import_types30 = require("@neat.is/types");
7448
7565
  function bucketKey(source, target, type) {
7449
7566
  return `${type}|${source}|${target}`;
7450
7567
  }
7568
+ function bucketSourceFor(graph, edge) {
7569
+ if (edge.type !== import_types30.EdgeType.CONNECTS_TO) return edge.source;
7570
+ const parsed = (0, import_types30.parseFileId)(edge.source);
7571
+ if (!parsed || !graph.hasNode(edge.target)) return edge.source;
7572
+ const target = graph.getNodeAttributes(edge.target);
7573
+ if (target.type !== import_types30.NodeType.DatabaseNode) return edge.source;
7574
+ return (0, import_types30.serviceId)(parsed.service);
7575
+ }
7451
7576
  function bucketEdges(graph) {
7452
7577
  const buckets2 = /* @__PURE__ */ new Map();
7453
7578
  graph.forEachEdge((id, attrs) => {
7454
7579
  const e = attrs;
7455
7580
  const parsed = (0, import_types30.parseEdgeId)(id);
7456
7581
  const provenance = parsed?.provenance ?? e.provenance;
7457
- const key = bucketKey(e.source, e.target, e.type);
7458
- const cur = buckets2.get(key) ?? { source: e.source, target: e.target, type: e.type };
7582
+ const source = bucketSourceFor(graph, e);
7583
+ const key = bucketKey(source, e.target, e.type);
7584
+ const cur = buckets2.get(key) ?? { source, target: e.target, type: e.type };
7459
7585
  switch (provenance) {
7460
7586
  case import_types30.Provenance.EXTRACTED:
7461
7587
  cur.extracted = e;
@@ -9955,6 +10081,7 @@ init_otel();
9955
10081
 
9956
10082
  // src/connectors/index.ts
9957
10083
  init_cjs_shims();
10084
+ var import_types35 = require("@neat.is/types");
9958
10085
 
9959
10086
  // src/connectors/registry.ts
9960
10087
  init_cjs_shims();
@@ -10430,19 +10557,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
10430
10557
 
10431
10558
  // src/connectors/supabase/resolve.ts
10432
10559
  init_cjs_shims();
10433
- var import_types36 = require("@neat.is/types");
10560
+ var import_types37 = require("@neat.is/types");
10434
10561
  function createSupabaseResolveTarget(graph, config) {
10435
10562
  return (signal, _ctx) => {
10436
10563
  if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
10437
10564
  return null;
10438
10565
  }
10439
- const subResourceId = (0, import_types36.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
10566
+ const subResourceId = (0, import_types37.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
10440
10567
  if (graph.hasNode(subResourceId)) {
10441
- return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types36.EdgeType.CALLS };
10568
+ return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types37.EdgeType.CALLS };
10442
10569
  }
10443
- const projectLevelId = (0, import_types36.infraId)("supabase", config.nodeRef);
10570
+ const bareResourceId = (0, import_types37.infraId)(signal.targetKind, signal.targetName);
10571
+ if (graph.hasNode(bareResourceId)) {
10572
+ return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types37.EdgeType.CALLS };
10573
+ }
10574
+ const projectLevelId = (0, import_types37.infraId)("supabase", config.nodeRef);
10444
10575
  if (graph.hasNode(projectLevelId)) {
10445
- return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types36.EdgeType.CALLS };
10576
+ return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types37.EdgeType.CALLS };
10446
10577
  }
10447
10578
  return null;
10448
10579
  };
@@ -10535,7 +10666,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
10535
10666
 
10536
10667
  // src/connectors/railway/index.ts
10537
10668
  init_cjs_shims();
10538
- var import_types40 = require("@neat.is/types");
10669
+ var import_types41 = require("@neat.is/types");
10539
10670
 
10540
10671
  // src/connectors/railway/client.ts
10541
10672
  init_cjs_shims();
@@ -10661,7 +10792,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
10661
10792
  const out = [];
10662
10793
  graph.forEachNode((_id, attrs) => {
10663
10794
  const node = attrs;
10664
- if (node.type !== import_types40.NodeType.RouteNode) return;
10795
+ if (node.type !== import_types41.NodeType.RouteNode) return;
10665
10796
  const route = attrs;
10666
10797
  if (route.service !== serviceName) return;
10667
10798
  out.push({
@@ -10757,12 +10888,12 @@ function createRailwayResolveTarget(config) {
10757
10888
  const serviceName = config.serviceNameById[config.serviceId];
10758
10889
  if (!serviceName) return null;
10759
10890
  if (signal.targetKind === ROUTE_TARGET_KIND) {
10760
- return { targetNodeId: signal.targetName, serviceName, edgeType: import_types40.EdgeType.CALLS };
10891
+ return { targetNodeId: signal.targetName, serviceName, edgeType: import_types41.EdgeType.CALLS };
10761
10892
  }
10762
10893
  if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
10763
10894
  const peerName = config.serviceNameById[signal.targetName];
10764
10895
  if (!peerName) return null;
10765
- return { targetNodeId: (0, import_types40.serviceId)(peerName), serviceName, edgeType: import_types40.EdgeType.CONNECTS_TO };
10896
+ return { targetNodeId: (0, import_types41.serviceId)(peerName), serviceName, edgeType: import_types41.EdgeType.CONNECTS_TO };
10766
10897
  }
10767
10898
  return null;
10768
10899
  };
@@ -10949,7 +11080,7 @@ function mapLogEntriesToSignals(entries) {
10949
11080
 
10950
11081
  // src/connectors/firebase/resolve.ts
10951
11082
  init_cjs_shims();
10952
- var import_types41 = require("@neat.is/types");
11083
+ var import_types42 = require("@neat.is/types");
10953
11084
  function neatServiceNameFor(resourceType, resourceName, serviceMap) {
10954
11085
  switch (resourceType) {
10955
11086
  case "cloud_function":
@@ -10964,7 +11095,7 @@ function routeEntriesFor(graph, serviceName) {
10964
11095
  const entries = [];
10965
11096
  graph.forEachNode((_id, attrs) => {
10966
11097
  const node = attrs;
10967
- if (node.type !== import_types41.NodeType.RouteNode) return;
11098
+ if (node.type !== import_types42.NodeType.RouteNode) return;
10968
11099
  const route = attrs;
10969
11100
  if (route.service !== serviceName) return;
10970
11101
  entries.push({
@@ -10996,7 +11127,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
10996
11127
  return {
10997
11128
  targetNodeId: match.routeNodeId,
10998
11129
  serviceName,
10999
- edgeType: import_types41.EdgeType.CALLS
11130
+ edgeType: import_types42.EdgeType.CALLS
11000
11131
  };
11001
11132
  };
11002
11133
  }
@@ -11023,7 +11154,7 @@ init_cjs_shims();
11023
11154
 
11024
11155
  // src/connectors/cloudflare/connector.ts
11025
11156
  init_cjs_shims();
11026
- var import_types43 = require("@neat.is/types");
11157
+ var import_types44 = require("@neat.is/types");
11027
11158
 
11028
11159
  // src/connectors/cloudflare/client.ts
11029
11160
  init_cjs_shims();
@@ -11184,7 +11315,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
11184
11315
  graph.forEachNode((id, attrs) => {
11185
11316
  if (found) return;
11186
11317
  const a = attrs;
11187
- if (a.type === import_types43.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
11318
+ if (a.type === import_types44.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
11188
11319
  found = id;
11189
11320
  }
11190
11321
  });
@@ -11196,7 +11327,7 @@ function findMatchingRouteNode(graph, serviceName, method, path61) {
11196
11327
  graph.forEachNode((id, attrs) => {
11197
11328
  if (found) return;
11198
11329
  const a = attrs;
11199
- if (a.type !== import_types43.NodeType.RouteNode || a.service !== serviceName) return;
11330
+ if (a.type !== import_types44.NodeType.RouteNode || a.service !== serviceName) return;
11200
11331
  if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
11201
11332
  const routeMethod = (a.method ?? "").toUpperCase();
11202
11333
  if (routeMethod !== "ALL" && routeMethod !== method) return;
@@ -11215,11 +11346,11 @@ function createCloudflareResolveTarget(config, graph) {
11215
11346
  };
11216
11347
  const mapping = config.workers?.[scriptName];
11217
11348
  if (mapping) {
11218
- const wholeFileId = (0, import_types43.fileId)(mapping.service, mapping.entryFile);
11349
+ const wholeFileId = (0, import_types44.fileId)(mapping.service, mapping.entryFile);
11219
11350
  return {
11220
11351
  targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
11221
11352
  serviceName: mapping.service,
11222
- edgeType: import_types43.EdgeType.CALLS
11353
+ edgeType: import_types44.EdgeType.CALLS
11223
11354
  };
11224
11355
  }
11225
11356
  const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
@@ -11228,13 +11359,13 @@ function createCloudflareResolveTarget(config, graph) {
11228
11359
  return {
11229
11360
  targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
11230
11361
  serviceName: fileNode.service,
11231
- edgeType: import_types43.EdgeType.CALLS
11362
+ edgeType: import_types44.EdgeType.CALLS
11232
11363
  };
11233
11364
  }
11234
11365
  return {
11235
- targetNodeId: (0, import_types43.infraId)("cloudflare-worker", scriptName),
11366
+ targetNodeId: (0, import_types44.infraId)("cloudflare-worker", scriptName),
11236
11367
  serviceName: scriptName,
11237
- edgeType: import_types43.EdgeType.CALLS,
11368
+ edgeType: import_types44.EdgeType.CALLS,
11238
11369
  ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
11239
11370
  };
11240
11371
  };
@@ -11448,7 +11579,7 @@ var import_node_fs32 = require("fs");
11448
11579
  var import_node_path51 = __toESM(require("path"), 1);
11449
11580
 
11450
11581
  // src/daemon.ts
11451
- var import_types46 = require("@neat.is/types");
11582
+ var import_types47 = require("@neat.is/types");
11452
11583
  function daemonJsonPath(scanPath) {
11453
11584
  return import_node_path52.default.join(scanPath, "neat-out", "daemon.json");
11454
11585
  }
@@ -15444,7 +15575,7 @@ var import_node_path59 = __toESM(require("path"), 1);
15444
15575
 
15445
15576
  // src/cli-client.ts
15446
15577
  init_cjs_shims();
15447
- var import_types47 = require("@neat.is/types");
15578
+ var import_types48 = require("@neat.is/types");
15448
15579
  var HttpError = class extends Error {
15449
15580
  constructor(status2, message, responseBody = "") {
15450
15581
  super(message);
@@ -15586,7 +15717,7 @@ async function runBlastRadius(client, input) {
15586
15717
  }
15587
15718
  }
15588
15719
  function formatBlastEntry(n) {
15589
- const tag = n.edgeProvenance === import_types47.Provenance.STALE ? " [STALE \u2014 last seen too long ago]" : "";
15720
+ const tag = n.edgeProvenance === import_types48.Provenance.STALE ? " [STALE \u2014 last seen too long ago]" : "";
15590
15721
  return ` \u2022 ${n.nodeId} (distance ${n.distance}, ${n.edgeProvenance})${tag}`;
15591
15722
  }
15592
15723
  async function runDependencies(client, input) {
@@ -15643,7 +15774,7 @@ async function runObservedDependencies(client, input) {
15643
15774
  if (result.observed) {
15644
15775
  return {
15645
15776
  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.`,
15646
- provenance: import_types47.Provenance.OBSERVED
15777
+ provenance: import_types48.Provenance.OBSERVED
15647
15778
  };
15648
15779
  }
15649
15780
  const note = result.hasExtractedOutbound ? " Static (EXTRACTED) dependencies exist but no runtime traffic has been seen \u2014 is OTel running?" : "";
@@ -15653,7 +15784,7 @@ async function runObservedDependencies(client, input) {
15653
15784
  return {
15654
15785
  summary: `${input.nodeId} has ${result.dependencies.length} runtime dependenc${result.dependencies.length === 1 ? "y" : "ies"} confirmed by OTel.`,
15655
15786
  block: blockLines.join("\n"),
15656
- provenance: import_types47.Provenance.OBSERVED
15787
+ provenance: import_types48.Provenance.OBSERVED
15657
15788
  };
15658
15789
  } catch (err) {
15659
15790
  if (err instanceof HttpError && err.status === 404) {
@@ -15707,7 +15838,7 @@ async function runIncidents(client, input) {
15707
15838
  return {
15708
15839
  summary: `${target} has ${body.total} recorded incident${body.total === 1 ? "" : "s"}; showing the ${ordered.length} most recent.`,
15709
15840
  block: blockLines.join("\n"),
15710
- provenance: import_types47.Provenance.OBSERVED
15841
+ provenance: import_types48.Provenance.OBSERVED
15711
15842
  };
15712
15843
  } catch (err) {
15713
15844
  if (err instanceof HttpError && err.status === 404) {
@@ -15816,7 +15947,7 @@ async function runStaleEdges(client, input) {
15816
15947
  return {
15817
15948
  summary: `${events.length} stale-edge transition${events.length === 1 ? "" : "s"} recorded${input.edgeType ? ` for ${input.edgeType}` : ""}.`,
15818
15949
  block: blockLines.join("\n"),
15819
- provenance: import_types47.Provenance.STALE
15950
+ provenance: import_types48.Provenance.STALE
15820
15951
  };
15821
15952
  }
15822
15953
  async function runPolicies(client, input) {
@@ -16133,7 +16264,7 @@ async function runSync(opts) {
16133
16264
  }
16134
16265
 
16135
16266
  // src/cli.ts
16136
- var import_types48 = require("@neat.is/types");
16267
+ var import_types49 = require("@neat.is/types");
16137
16268
  function isNpxInvocation() {
16138
16269
  if (process.env.npm_command === "exec") return true;
16139
16270
  const execpath = process.env.npm_execpath ?? "";
@@ -17070,10 +17201,10 @@ async function runQueryVerb(cmd, parsed) {
17070
17201
  const parts = parsed.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
17071
17202
  const out = [];
17072
17203
  for (const p of parts) {
17073
- const r = import_types48.DivergenceTypeSchema.safeParse(p);
17204
+ const r = import_types49.DivergenceTypeSchema.safeParse(p);
17074
17205
  if (!r.success) {
17075
17206
  console.error(
17076
- `neat divergences: unknown --type "${p}". allowed: ${import_types48.DivergenceTypeSchema.options.join(", ")}`
17207
+ `neat divergences: unknown --type "${p}". allowed: ${import_types49.DivergenceTypeSchema.options.join(", ")}`
17077
17208
  );
17078
17209
  return 2;
17079
17210
  }