@neat.is/core 0.5.0 → 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
@@ -2657,6 +2657,7 @@ function ensureFrontierNode(graph, host, ts) {
2657
2657
  }
2658
2658
  function upsertObservedEdge(graph, type, source, target, ts, isError = false, evidence) {
2659
2659
  if (!graph.hasNode(source) || !graph.hasNode(target)) return null;
2660
+ const grain = source.startsWith("file:") ? "file" : "service";
2660
2661
  const id = makeObservedEdgeId(type, source, target);
2661
2662
  if (graph.hasEdge(id)) {
2662
2663
  const existing = graph.getEdgeAttributes(id);
@@ -2673,7 +2674,9 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
2673
2674
  lastObserved: ts,
2674
2675
  callCount: newSpanCount,
2675
2676
  signal: newSignal,
2676
- confidence: (0, import_types3.confidenceForObservedSignal)(newSignal)
2677
+ confidence: (0, import_types3.confidenceForObservedSignal)(newSignal),
2678
+ grain
2679
+ // backfills legacy edges that predate ADR-142
2677
2680
  };
2678
2681
  graph.replaceEdgeAttributes(id, updated);
2679
2682
  return { edge: updated, created: false };
@@ -2693,6 +2696,7 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
2693
2696
  lastObserved: ts,
2694
2697
  callCount: 1,
2695
2698
  signal,
2699
+ grain,
2696
2700
  // Call-site evidence from span code.* semconv (file-awareness.md §4 + §6).
2697
2701
  // Only set when code.filepath was present on the span — never fabricated.
2698
2702
  ...evidence ? { evidence } : {}
@@ -4791,6 +4795,15 @@ async function parse4(serviceDir) {
4791
4795
  const config = parseConnectionString(urlMatch[1]);
4792
4796
  if (config) return [{ ...config, sourceFile: filePath }];
4793
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
+ }
4794
4807
  const hostMatch = content.match(/host\s*:\s*['"`]([^'"`]+)['"`]/);
4795
4808
  if (hostMatch) {
4796
4809
  const portMatch = content.match(/port\s*:\s*(\d+)/);
@@ -4844,6 +4857,15 @@ async function parse5(serviceDir) {
4844
4857
  const config = parseConnectionString(urlMatch[1]);
4845
4858
  if (config) return [{ ...config, sourceFile: filePath }];
4846
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
+ }
4847
4869
  const host = content.match(/host\s*:\s*['"`]([^'"`]+)['"`]/)?.[1];
4848
4870
  if (host) {
4849
4871
  const port = content.match(/port\s*:\s*(\d+)/)?.[1];
@@ -6392,6 +6414,16 @@ function constructorMatchesImport(name, ctx) {
6392
6414
  if (name === "createClient") return ctx.hasSupabaseJs;
6393
6415
  return ctx.hasSupabaseSsr;
6394
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
+ }
6395
6427
  function supabaseEndpointsFromFile(file, serviceDir) {
6396
6428
  const ctx = readImports2(file.content);
6397
6429
  if (!ctx.hasSupabaseJs && !ctx.hasSupabaseSsr) return [];
@@ -6424,6 +6456,34 @@ function supabaseEndpointsFromFile(file, serviceDir) {
6424
6456
  }
6425
6457
  });
6426
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
+ }
6427
6487
  return out;
6428
6488
  }
6429
6489
 
@@ -10021,6 +10081,7 @@ init_otel();
10021
10081
 
10022
10082
  // src/connectors/index.ts
10023
10083
  init_cjs_shims();
10084
+ var import_types35 = require("@neat.is/types");
10024
10085
 
10025
10086
  // src/connectors/registry.ts
10026
10087
  init_cjs_shims();
@@ -10496,19 +10557,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
10496
10557
 
10497
10558
  // src/connectors/supabase/resolve.ts
10498
10559
  init_cjs_shims();
10499
- var import_types36 = require("@neat.is/types");
10560
+ var import_types37 = require("@neat.is/types");
10500
10561
  function createSupabaseResolveTarget(graph, config) {
10501
10562
  return (signal, _ctx) => {
10502
10563
  if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
10503
10564
  return null;
10504
10565
  }
10505
- 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}`);
10506
10567
  if (graph.hasNode(subResourceId)) {
10507
- return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types36.EdgeType.CALLS };
10568
+ return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types37.EdgeType.CALLS };
10569
+ }
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 };
10508
10573
  }
10509
- const projectLevelId = (0, import_types36.infraId)("supabase", config.nodeRef);
10574
+ const projectLevelId = (0, import_types37.infraId)("supabase", config.nodeRef);
10510
10575
  if (graph.hasNode(projectLevelId)) {
10511
- return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types36.EdgeType.CALLS };
10576
+ return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types37.EdgeType.CALLS };
10512
10577
  }
10513
10578
  return null;
10514
10579
  };
@@ -10601,7 +10666,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
10601
10666
 
10602
10667
  // src/connectors/railway/index.ts
10603
10668
  init_cjs_shims();
10604
- var import_types40 = require("@neat.is/types");
10669
+ var import_types41 = require("@neat.is/types");
10605
10670
 
10606
10671
  // src/connectors/railway/client.ts
10607
10672
  init_cjs_shims();
@@ -10727,7 +10792,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
10727
10792
  const out = [];
10728
10793
  graph.forEachNode((_id, attrs) => {
10729
10794
  const node = attrs;
10730
- if (node.type !== import_types40.NodeType.RouteNode) return;
10795
+ if (node.type !== import_types41.NodeType.RouteNode) return;
10731
10796
  const route = attrs;
10732
10797
  if (route.service !== serviceName) return;
10733
10798
  out.push({
@@ -10823,12 +10888,12 @@ function createRailwayResolveTarget(config) {
10823
10888
  const serviceName = config.serviceNameById[config.serviceId];
10824
10889
  if (!serviceName) return null;
10825
10890
  if (signal.targetKind === ROUTE_TARGET_KIND) {
10826
- return { targetNodeId: signal.targetName, serviceName, edgeType: import_types40.EdgeType.CALLS };
10891
+ return { targetNodeId: signal.targetName, serviceName, edgeType: import_types41.EdgeType.CALLS };
10827
10892
  }
10828
10893
  if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
10829
10894
  const peerName = config.serviceNameById[signal.targetName];
10830
10895
  if (!peerName) return null;
10831
- 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 };
10832
10897
  }
10833
10898
  return null;
10834
10899
  };
@@ -11015,7 +11080,7 @@ function mapLogEntriesToSignals(entries) {
11015
11080
 
11016
11081
  // src/connectors/firebase/resolve.ts
11017
11082
  init_cjs_shims();
11018
- var import_types41 = require("@neat.is/types");
11083
+ var import_types42 = require("@neat.is/types");
11019
11084
  function neatServiceNameFor(resourceType, resourceName, serviceMap) {
11020
11085
  switch (resourceType) {
11021
11086
  case "cloud_function":
@@ -11030,7 +11095,7 @@ function routeEntriesFor(graph, serviceName) {
11030
11095
  const entries = [];
11031
11096
  graph.forEachNode((_id, attrs) => {
11032
11097
  const node = attrs;
11033
- if (node.type !== import_types41.NodeType.RouteNode) return;
11098
+ if (node.type !== import_types42.NodeType.RouteNode) return;
11034
11099
  const route = attrs;
11035
11100
  if (route.service !== serviceName) return;
11036
11101
  entries.push({
@@ -11062,7 +11127,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
11062
11127
  return {
11063
11128
  targetNodeId: match.routeNodeId,
11064
11129
  serviceName,
11065
- edgeType: import_types41.EdgeType.CALLS
11130
+ edgeType: import_types42.EdgeType.CALLS
11066
11131
  };
11067
11132
  };
11068
11133
  }
@@ -11089,7 +11154,7 @@ init_cjs_shims();
11089
11154
 
11090
11155
  // src/connectors/cloudflare/connector.ts
11091
11156
  init_cjs_shims();
11092
- var import_types43 = require("@neat.is/types");
11157
+ var import_types44 = require("@neat.is/types");
11093
11158
 
11094
11159
  // src/connectors/cloudflare/client.ts
11095
11160
  init_cjs_shims();
@@ -11250,7 +11315,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
11250
11315
  graph.forEachNode((id, attrs) => {
11251
11316
  if (found) return;
11252
11317
  const a = attrs;
11253
- 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) {
11254
11319
  found = id;
11255
11320
  }
11256
11321
  });
@@ -11262,7 +11327,7 @@ function findMatchingRouteNode(graph, serviceName, method, path61) {
11262
11327
  graph.forEachNode((id, attrs) => {
11263
11328
  if (found) return;
11264
11329
  const a = attrs;
11265
- if (a.type !== import_types43.NodeType.RouteNode || a.service !== serviceName) return;
11330
+ if (a.type !== import_types44.NodeType.RouteNode || a.service !== serviceName) return;
11266
11331
  if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
11267
11332
  const routeMethod = (a.method ?? "").toUpperCase();
11268
11333
  if (routeMethod !== "ALL" && routeMethod !== method) return;
@@ -11281,11 +11346,11 @@ function createCloudflareResolveTarget(config, graph) {
11281
11346
  };
11282
11347
  const mapping = config.workers?.[scriptName];
11283
11348
  if (mapping) {
11284
- const wholeFileId = (0, import_types43.fileId)(mapping.service, mapping.entryFile);
11349
+ const wholeFileId = (0, import_types44.fileId)(mapping.service, mapping.entryFile);
11285
11350
  return {
11286
11351
  targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
11287
11352
  serviceName: mapping.service,
11288
- edgeType: import_types43.EdgeType.CALLS
11353
+ edgeType: import_types44.EdgeType.CALLS
11289
11354
  };
11290
11355
  }
11291
11356
  const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
@@ -11294,13 +11359,13 @@ function createCloudflareResolveTarget(config, graph) {
11294
11359
  return {
11295
11360
  targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
11296
11361
  serviceName: fileNode.service,
11297
- edgeType: import_types43.EdgeType.CALLS
11362
+ edgeType: import_types44.EdgeType.CALLS
11298
11363
  };
11299
11364
  }
11300
11365
  return {
11301
- targetNodeId: (0, import_types43.infraId)("cloudflare-worker", scriptName),
11366
+ targetNodeId: (0, import_types44.infraId)("cloudflare-worker", scriptName),
11302
11367
  serviceName: scriptName,
11303
- edgeType: import_types43.EdgeType.CALLS,
11368
+ edgeType: import_types44.EdgeType.CALLS,
11304
11369
  ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
11305
11370
  };
11306
11371
  };
@@ -11514,7 +11579,7 @@ var import_node_fs32 = require("fs");
11514
11579
  var import_node_path51 = __toESM(require("path"), 1);
11515
11580
 
11516
11581
  // src/daemon.ts
11517
- var import_types46 = require("@neat.is/types");
11582
+ var import_types47 = require("@neat.is/types");
11518
11583
  function daemonJsonPath(scanPath) {
11519
11584
  return import_node_path52.default.join(scanPath, "neat-out", "daemon.json");
11520
11585
  }
@@ -15510,7 +15575,7 @@ var import_node_path59 = __toESM(require("path"), 1);
15510
15575
 
15511
15576
  // src/cli-client.ts
15512
15577
  init_cjs_shims();
15513
- var import_types47 = require("@neat.is/types");
15578
+ var import_types48 = require("@neat.is/types");
15514
15579
  var HttpError = class extends Error {
15515
15580
  constructor(status2, message, responseBody = "") {
15516
15581
  super(message);
@@ -15652,7 +15717,7 @@ async function runBlastRadius(client, input) {
15652
15717
  }
15653
15718
  }
15654
15719
  function formatBlastEntry(n) {
15655
- 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]" : "";
15656
15721
  return ` \u2022 ${n.nodeId} (distance ${n.distance}, ${n.edgeProvenance})${tag}`;
15657
15722
  }
15658
15723
  async function runDependencies(client, input) {
@@ -15709,7 +15774,7 @@ async function runObservedDependencies(client, input) {
15709
15774
  if (result.observed) {
15710
15775
  return {
15711
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.`,
15712
- provenance: import_types47.Provenance.OBSERVED
15777
+ provenance: import_types48.Provenance.OBSERVED
15713
15778
  };
15714
15779
  }
15715
15780
  const note = result.hasExtractedOutbound ? " Static (EXTRACTED) dependencies exist but no runtime traffic has been seen \u2014 is OTel running?" : "";
@@ -15719,7 +15784,7 @@ async function runObservedDependencies(client, input) {
15719
15784
  return {
15720
15785
  summary: `${input.nodeId} has ${result.dependencies.length} runtime dependenc${result.dependencies.length === 1 ? "y" : "ies"} confirmed by OTel.`,
15721
15786
  block: blockLines.join("\n"),
15722
- provenance: import_types47.Provenance.OBSERVED
15787
+ provenance: import_types48.Provenance.OBSERVED
15723
15788
  };
15724
15789
  } catch (err) {
15725
15790
  if (err instanceof HttpError && err.status === 404) {
@@ -15773,7 +15838,7 @@ async function runIncidents(client, input) {
15773
15838
  return {
15774
15839
  summary: `${target} has ${body.total} recorded incident${body.total === 1 ? "" : "s"}; showing the ${ordered.length} most recent.`,
15775
15840
  block: blockLines.join("\n"),
15776
- provenance: import_types47.Provenance.OBSERVED
15841
+ provenance: import_types48.Provenance.OBSERVED
15777
15842
  };
15778
15843
  } catch (err) {
15779
15844
  if (err instanceof HttpError && err.status === 404) {
@@ -15882,7 +15947,7 @@ async function runStaleEdges(client, input) {
15882
15947
  return {
15883
15948
  summary: `${events.length} stale-edge transition${events.length === 1 ? "" : "s"} recorded${input.edgeType ? ` for ${input.edgeType}` : ""}.`,
15884
15949
  block: blockLines.join("\n"),
15885
- provenance: import_types47.Provenance.STALE
15950
+ provenance: import_types48.Provenance.STALE
15886
15951
  };
15887
15952
  }
15888
15953
  async function runPolicies(client, input) {
@@ -16199,7 +16264,7 @@ async function runSync(opts) {
16199
16264
  }
16200
16265
 
16201
16266
  // src/cli.ts
16202
- var import_types48 = require("@neat.is/types");
16267
+ var import_types49 = require("@neat.is/types");
16203
16268
  function isNpxInvocation() {
16204
16269
  if (process.env.npm_command === "exec") return true;
16205
16270
  const execpath = process.env.npm_execpath ?? "";
@@ -17136,10 +17201,10 @@ async function runQueryVerb(cmd, parsed) {
17136
17201
  const parts = parsed.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
17137
17202
  const out = [];
17138
17203
  for (const p of parts) {
17139
- const r = import_types48.DivergenceTypeSchema.safeParse(p);
17204
+ const r = import_types49.DivergenceTypeSchema.safeParse(p);
17140
17205
  if (!r.success) {
17141
17206
  console.error(
17142
- `neat divergences: unknown --type "${p}". allowed: ${import_types48.DivergenceTypeSchema.options.join(", ")}`
17207
+ `neat divergences: unknown --type "${p}". allowed: ${import_types49.DivergenceTypeSchema.options.join(", ")}`
17143
17208
  );
17144
17209
  return 2;
17145
17210
  }