@neat.is/core 0.7.1 → 0.7.3

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/neatd.cjs CHANGED
@@ -61,8 +61,8 @@ function mountBearerAuth(app, opts) {
61
61
  ]);
62
62
  const publicRead = opts.publicRead === true;
63
63
  app.addHook("preHandler", (req2, reply, done) => {
64
- const path61 = (req2.url.split("?")[0] ?? "").replace(/\/+$/, "");
65
- if (exactUnauthPaths.has(path61) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path61)) {
64
+ const path62 = (req2.url.split("?")[0] ?? "").replace(/\/+$/, "");
65
+ if (exactUnauthPaths.has(path62) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path62)) {
66
66
  done();
67
67
  return;
68
68
  }
@@ -194,8 +194,8 @@ function reshapeGrpcRequest(req2) {
194
194
  };
195
195
  }
196
196
  function resolveProtoRoot() {
197
- const here = import_node_path38.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
198
- return import_node_path38.default.resolve(here, "..", "proto");
197
+ const here = import_node_path39.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
198
+ return import_node_path39.default.resolve(here, "..", "proto");
199
199
  }
200
200
  function loadTraceService() {
201
201
  const protoRoot = resolveProtoRoot();
@@ -263,13 +263,13 @@ async function startOtelGrpcReceiver(opts) {
263
263
  })
264
264
  };
265
265
  }
266
- var import_node_url, import_node_path38, import_node_crypto2, grpc, protoLoader;
266
+ var import_node_url, import_node_path39, import_node_crypto2, grpc, protoLoader;
267
267
  var init_otel_grpc = __esm({
268
268
  "src/otel-grpc.ts"() {
269
269
  "use strict";
270
270
  init_cjs_shims();
271
271
  import_node_url = require("url");
272
- import_node_path38 = __toESM(require("path"), 1);
272
+ import_node_path39 = __toESM(require("path"), 1);
273
273
  import_node_crypto2 = require("crypto");
274
274
  grpc = __toESM(require("@grpc/grpc-js"), 1);
275
275
  protoLoader = __toESM(require("@grpc/proto-loader"), 1);
@@ -415,8 +415,8 @@ function websocketChannelPathOf(attrs) {
415
415
  const v = attrs[key];
416
416
  if (typeof v === "string" && v.length > 0) {
417
417
  const q = v.indexOf("?");
418
- const path61 = q === -1 ? v : v.slice(0, q);
419
- if (path61.length > 0) return path61;
418
+ const path62 = q === -1 ? v : v.slice(0, q);
419
+ if (path62.length > 0) return path62;
420
420
  }
421
421
  }
422
422
  return void 0;
@@ -475,10 +475,10 @@ function parseOtlpRequest(body) {
475
475
  return out;
476
476
  }
477
477
  function loadProtoRoot() {
478
- const here = import_node_path39.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
479
- const protoRoot = import_node_path39.default.resolve(here, "..", "proto");
478
+ const here = import_node_path40.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
479
+ const protoRoot = import_node_path40.default.resolve(here, "..", "proto");
480
480
  const root = new import_protobufjs.default.Root();
481
- root.resolvePath = (_origin, target) => import_node_path39.default.resolve(protoRoot, target);
481
+ root.resolvePath = (_origin, target) => import_node_path40.default.resolve(protoRoot, target);
482
482
  root.loadSync(
483
483
  "opentelemetry/proto/collector/trace/v1/trace_service.proto",
484
484
  { keepCase: true }
@@ -709,12 +709,12 @@ async function listenSteppingOtlp(app, requestedPort, host) {
709
709
  }
710
710
  }
711
711
  }
712
- var import_node_path39, import_node_url2, import_fastify, import_protobufjs, ENV_ATTR_CANONICAL, ENV_ATTR_COMPAT, ENV_FALLBACK, exportTraceServiceRequestType, exportTraceServiceResponseType, cachedProtobufResponseBody, OTLP_STEP_ATTEMPTS, OTLP_STEP_STRIDE;
712
+ var import_node_path40, import_node_url2, import_fastify, import_protobufjs, ENV_ATTR_CANONICAL, ENV_ATTR_COMPAT, ENV_FALLBACK, exportTraceServiceRequestType, exportTraceServiceResponseType, cachedProtobufResponseBody, OTLP_STEP_ATTEMPTS, OTLP_STEP_STRIDE;
713
713
  var init_otel = __esm({
714
714
  "src/otel.ts"() {
715
715
  "use strict";
716
716
  init_cjs_shims();
717
- import_node_path39 = __toESM(require("path"), 1);
717
+ import_node_path40 = __toESM(require("path"), 1);
718
718
  import_node_url2 = require("url");
719
719
  import_fastify = __toESM(require("fastify"), 1);
720
720
  import_protobufjs = __toESM(require("protobufjs"), 1);
@@ -738,13 +738,13 @@ __export(neatd_exports, {
738
738
  module.exports = __toCommonJS(neatd_exports);
739
739
  init_cjs_shims();
740
740
  var import_node_fs34 = require("fs");
741
- var import_node_path60 = __toESM(require("path"), 1);
741
+ var import_node_path61 = __toESM(require("path"), 1);
742
742
  var import_node_module2 = require("module");
743
743
 
744
744
  // src/daemon.ts
745
745
  init_cjs_shims();
746
746
  var import_node_fs32 = require("fs");
747
- var import_node_path58 = __toESM(require("path"), 1);
747
+ var import_node_path59 = __toESM(require("path"), 1);
748
748
  var import_node_module = require("module");
749
749
 
750
750
  // src/graph.ts
@@ -1277,19 +1277,19 @@ function confidenceFromMix(edges, now = Date.now()) {
1277
1277
  function longestIncomingWalk(graph, start, maxDepth) {
1278
1278
  let best = { path: [start], edges: [] };
1279
1279
  const visited = /* @__PURE__ */ new Set([start]);
1280
- function step(node, path61, edges) {
1281
- if (path61.length > best.path.length) {
1282
- best = { path: [...path61], edges: [...edges] };
1280
+ function step(node, path62, edges) {
1281
+ if (path62.length > best.path.length) {
1282
+ best = { path: [...path62], edges: [...edges] };
1283
1283
  }
1284
- if (path61.length - 1 >= maxDepth) return;
1284
+ if (path62.length - 1 >= maxDepth) return;
1285
1285
  const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
1286
1286
  for (const [srcId, edge] of incoming) {
1287
1287
  if (visited.has(srcId)) continue;
1288
1288
  visited.add(srcId);
1289
- path61.push(srcId);
1289
+ path62.push(srcId);
1290
1290
  edges.push(edge);
1291
- step(srcId, path61, edges);
1292
- path61.pop();
1291
+ step(srcId, path62, edges);
1292
+ path62.pop();
1293
1293
  edges.pop();
1294
1294
  visited.delete(srcId);
1295
1295
  }
@@ -1496,26 +1496,26 @@ function dominantFailingCall(graph, serviceId7, visited) {
1496
1496
  return best;
1497
1497
  }
1498
1498
  function followFailingCallChain(graph, originServiceId, maxDepth) {
1499
- const path61 = [originServiceId];
1499
+ const path62 = [originServiceId];
1500
1500
  const edges = [];
1501
1501
  const visited = /* @__PURE__ */ new Set([originServiceId]);
1502
1502
  let current = originServiceId;
1503
1503
  for (let depth = 0; depth < maxDepth; depth++) {
1504
1504
  const hop = dominantFailingCall(graph, current, visited);
1505
1505
  if (!hop) break;
1506
- path61.push(hop.nextService);
1506
+ path62.push(hop.nextService);
1507
1507
  edges.push(hop.edge);
1508
1508
  visited.add(hop.nextService);
1509
1509
  current = hop.nextService;
1510
1510
  }
1511
1511
  if (edges.length === 0) return null;
1512
- return { path: path61, edges, culprit: current };
1512
+ return { path: path62, edges, culprit: current };
1513
1513
  }
1514
1514
  function crossServiceRootCause(graph, originId, incidents, errorEvent) {
1515
1515
  const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
1516
1516
  if (!chain) return null;
1517
1517
  const culprit = chain.culprit;
1518
- const path61 = [...chain.path];
1518
+ const path62 = [...chain.path];
1519
1519
  const edgeProvenances = chain.edges.map((e) => e.provenance);
1520
1520
  const baseConfidence = confidenceFromMix(chain.edges);
1521
1521
  const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
@@ -1523,14 +1523,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
1523
1523
  if (loc) {
1524
1524
  let rootCauseNode = culprit;
1525
1525
  if (loc.fileNode) {
1526
- path61.push(loc.fileNode);
1526
+ path62.push(loc.fileNode);
1527
1527
  edgeProvenances.push(import_types.Provenance.OBSERVED);
1528
1528
  rootCauseNode = loc.fileNode;
1529
1529
  }
1530
1530
  return import_types.RootCauseResultSchema.parse({
1531
1531
  rootCauseNode,
1532
1532
  rootCauseReason: loc.rootCauseReason,
1533
- traversalPath: path61,
1533
+ traversalPath: path62,
1534
1534
  edgeProvenances,
1535
1535
  confidence,
1536
1536
  ...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
@@ -1542,7 +1542,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
1542
1542
  return import_types.RootCauseResultSchema.parse({
1543
1543
  rootCauseNode: culprit,
1544
1544
  rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
1545
- traversalPath: path61,
1545
+ traversalPath: path62,
1546
1546
  edgeProvenances,
1547
1547
  confidence,
1548
1548
  fixRecommendation: `Inspect ${culpritName}'s failing handler`
@@ -6909,7 +6909,7 @@ async function addGrpcMethods(graph, services) {
6909
6909
 
6910
6910
  // src/extract/calls/index.ts
6911
6911
  init_cjs_shims();
6912
- var import_types29 = require("@neat.is/types");
6912
+ var import_types30 = require("@neat.is/types");
6913
6913
 
6914
6914
  // src/extract/calls/http.ts
6915
6915
  init_cjs_shims();
@@ -8365,12 +8365,140 @@ function drizzleEndpointsFromFile(file, serviceDir) {
8365
8365
  return out;
8366
8366
  }
8367
8367
 
8368
+ // src/extract/calls/prisma.ts
8369
+ init_cjs_shims();
8370
+ var import_node_path38 = __toESM(require("path"), 1);
8371
+ var import_types28 = require("@neat.is/types");
8372
+ var SCALAR_TYPES = /* @__PURE__ */ new Set([
8373
+ "Int",
8374
+ "String",
8375
+ "Boolean",
8376
+ "DateTime",
8377
+ "Float",
8378
+ "Decimal",
8379
+ "BigInt",
8380
+ "Bytes",
8381
+ "Json"
8382
+ ]);
8383
+ function stripLineComment(line) {
8384
+ let inStr = false;
8385
+ for (let i = 0; i < line.length; i++) {
8386
+ const ch = line[i];
8387
+ if (ch === '"' && line[i - 1] !== "\\") inStr = !inStr;
8388
+ else if (!inStr && ch === "/" && line[i + 1] === "/") return line.slice(0, i);
8389
+ }
8390
+ return line;
8391
+ }
8392
+ function netBraces(line) {
8393
+ const s = stripLineComment(line).replace(/"(\\.|[^"\\])*"/g, "");
8394
+ let n = 0;
8395
+ for (const ch of s) {
8396
+ if (ch === "{") n++;
8397
+ else if (ch === "}") n--;
8398
+ }
8399
+ return n;
8400
+ }
8401
+ function prismaColumnsFromSchema(file, serviceDir) {
8402
+ const content = file.content;
8403
+ if (!/\bmodel\s+[A-Za-z_]\w*\s*\{/.test(content)) return [];
8404
+ const lines = content.split("\n");
8405
+ const modelNames = /* @__PURE__ */ new Set();
8406
+ const enumNames = /* @__PURE__ */ new Set();
8407
+ for (const line of lines) {
8408
+ const m = line.match(/^\s*model\s+([A-Za-z_]\w*)\s*\{/);
8409
+ if (m) modelNames.add(m[1]);
8410
+ const e = line.match(/^\s*enum\s+([A-Za-z_]\w*)\s*\{/);
8411
+ if (e) enumNames.add(e[1]);
8412
+ }
8413
+ const out = [];
8414
+ const seenTable = /* @__PURE__ */ new Set();
8415
+ const finalize = (b) => {
8416
+ if (seenTable.has(b.tableName)) return;
8417
+ seenTable.add(b.tableName);
8418
+ out.push({
8419
+ infraId: (0, import_types28.infraId)("sql-table", b.tableName),
8420
+ name: b.tableName,
8421
+ kind: "sql-table",
8422
+ edgeType: "CALLS",
8423
+ confidenceKind: "structural",
8424
+ columns: b.columns,
8425
+ evidence: {
8426
+ file: import_node_path38.default.relative(serviceDir, file.path),
8427
+ line: b.startLine,
8428
+ snippet: snippet(content, b.startLine)
8429
+ }
8430
+ });
8431
+ };
8432
+ let current = null;
8433
+ let depth = 0;
8434
+ for (let i = 0; i < lines.length; i++) {
8435
+ const raw = lines[i];
8436
+ const lineNo = i + 1;
8437
+ if (current === null) {
8438
+ const header = raw.match(/^\s*(model|enum|datasource|generator|type)\s+([A-Za-z_]\w*)\b/);
8439
+ if (header && raw.includes("{")) {
8440
+ current = {
8441
+ kind: header[1],
8442
+ tableName: header[2],
8443
+ startLine: lineNo,
8444
+ columns: [],
8445
+ seenCol: /* @__PURE__ */ new Set()
8446
+ };
8447
+ depth = netBraces(raw);
8448
+ if (depth <= 0) {
8449
+ if (current.kind === "model") finalize(current);
8450
+ current = null;
8451
+ }
8452
+ }
8453
+ continue;
8454
+ }
8455
+ depth += netBraces(raw);
8456
+ if (depth <= 0) {
8457
+ if (current.kind === "model") finalize(current);
8458
+ current = null;
8459
+ continue;
8460
+ }
8461
+ if (current.kind !== "model") continue;
8462
+ const trimmed = stripLineComment(raw).trim();
8463
+ if (!trimmed) continue;
8464
+ if (trimmed.startsWith("@@")) {
8465
+ const map = trimmed.match(/@@map\(\s*"([^"]+)"\s*\)/);
8466
+ if (map) current.tableName = map[1];
8467
+ continue;
8468
+ }
8469
+ const fm = trimmed.match(/^([A-Za-z_]\w*)\s+([A-Za-z_]\w*)/);
8470
+ if (!fm) continue;
8471
+ const fieldName = fm[1];
8472
+ const baseType = fm[2];
8473
+ if (/@relation\b/.test(trimmed) || modelNames.has(baseType)) continue;
8474
+ if (!enumNames.has(baseType) && !SCALAR_TYPES.has(baseType)) continue;
8475
+ const mapM = trimmed.match(/(?<!@)@map\(\s*"([^"]+)"\s*\)/);
8476
+ const columnName = mapM ? mapM[1] : fieldName;
8477
+ if (!current.seenCol.has(columnName)) {
8478
+ current.seenCol.add(columnName);
8479
+ current.columns.push(columnName);
8480
+ }
8481
+ }
8482
+ if (current && current.kind === "model") finalize(current);
8483
+ return out;
8484
+ }
8485
+ async function prismaColumnEndpoints(serviceDir) {
8486
+ const schemaPath = await findFirst(serviceDir, [
8487
+ import_node_path38.default.join("prisma", "schema.prisma"),
8488
+ "schema.prisma"
8489
+ ]);
8490
+ if (!schemaPath) return [];
8491
+ const content = await readIfExists(schemaPath);
8492
+ if (!content) return [];
8493
+ return prismaColumnsFromSchema({ path: schemaPath, content }, serviceDir);
8494
+ }
8495
+
8368
8496
  // src/extract/calls/go.ts
8369
8497
  init_cjs_shims();
8370
- var import_node_path40 = __toESM(require("path"), 1);
8498
+ var import_node_path41 = __toESM(require("path"), 1);
8371
8499
  var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
8372
8500
  var import_tree_sitter_go3 = __toESM(require("tree-sitter-go"), 1);
8373
- var import_types28 = require("@neat.is/types");
8501
+ var import_types29 = require("@neat.is/types");
8374
8502
  init_otel();
8375
8503
  var SQL_METHODS = /* @__PURE__ */ new Set(["Exec", "ExecContext", "Query", "QueryContext", "QueryRow", "QueryRowContext"]);
8376
8504
  var PARSE_CHUNK8 = 16384;
@@ -8382,7 +8510,7 @@ function walk5(node, visit) {
8382
8510
  }
8383
8511
  }
8384
8512
  function goSqlEndpointsFromFile(file, serviceDir) {
8385
- if (import_node_path40.default.extname(file.path) !== ".go") return [];
8513
+ if (import_node_path41.default.extname(file.path) !== ".go") return [];
8386
8514
  const parser = new import_tree_sitter10.default();
8387
8515
  parser.setLanguage(import_tree_sitter_go3.default);
8388
8516
  const tree = parser.parse(
@@ -8402,12 +8530,12 @@ function goSqlEndpointsFromFile(file, serviceDir) {
8402
8530
  if (!table) return;
8403
8531
  const line = node.startPosition.row + 1;
8404
8532
  out.push({
8405
- infraId: (0, import_types28.infraId)("sql-table", table),
8533
+ infraId: (0, import_types29.infraId)("sql-table", table),
8406
8534
  name: table,
8407
8535
  kind: "sql-table",
8408
8536
  edgeType: "CALLS",
8409
8537
  confidenceKind: "verified-call-site",
8410
- evidence: { file: toPosix(import_node_path40.default.relative(serviceDir, file.path)), line, snippet: snippet(file.content, line) }
8538
+ evidence: { file: toPosix(import_node_path41.default.relative(serviceDir, file.path)), line, snippet: snippet(file.content, line) }
8411
8539
  });
8412
8540
  });
8413
8541
  return out;
@@ -8417,11 +8545,11 @@ function goSqlEndpointsFromFile(file, serviceDir) {
8417
8545
  function edgeTypeFromEndpoint(ep) {
8418
8546
  switch (ep.edgeType) {
8419
8547
  case "PUBLISHES_TO":
8420
- return import_types29.EdgeType.PUBLISHES_TO;
8548
+ return import_types30.EdgeType.PUBLISHES_TO;
8421
8549
  case "CONSUMES_FROM":
8422
- return import_types29.EdgeType.CONSUMES_FROM;
8550
+ return import_types30.EdgeType.CONSUMES_FROM;
8423
8551
  default:
8424
- return import_types29.EdgeType.CALLS;
8552
+ return import_types30.EdgeType.CALLS;
8425
8553
  }
8426
8554
  }
8427
8555
  function isAwsKind(kind) {
@@ -8456,13 +8584,14 @@ async function addExternalEndpointEdges(graph, services) {
8456
8584
  }
8457
8585
  endpoints.push(...await mongooseCrossFileEndpoints(maskedFiles, service.dir));
8458
8586
  endpoints.push(...pythonOrmCrossFileEndpoints(maskedFiles, service.dir));
8587
+ endpoints.push(...await prismaColumnEndpoints(service.dir));
8459
8588
  if (endpoints.length === 0) continue;
8460
8589
  const seenEdges = /* @__PURE__ */ new Set();
8461
8590
  for (const ep of endpoints) {
8462
8591
  if (!graph.hasNode(ep.infraId)) {
8463
8592
  const node = {
8464
8593
  id: ep.infraId,
8465
- type: import_types29.NodeType.InfraNode,
8594
+ type: import_types30.NodeType.InfraNode,
8466
8595
  name: ep.name,
8467
8596
  // #238 — `aws-*` covers AWS-SDK client kinds (aws-s3, aws-dynamodb,
8468
8597
  // aws-cognito-identity-provider, …); `s3-` / `dynamodb-` cover the
@@ -8475,20 +8604,20 @@ async function addExternalEndpointEdges(graph, services) {
8475
8604
  }
8476
8605
  if (ep.columns && ep.columns.length > 0) {
8477
8606
  const node = graph.getNodeAttributes(ep.infraId);
8478
- if (node.type === import_types29.NodeType.InfraNode) {
8607
+ if (node.type === import_types30.NodeType.InfraNode) {
8479
8608
  graph.replaceNodeAttributes(ep.infraId, {
8480
8609
  ...node,
8481
8610
  columns: foldColumns(
8482
8611
  node.columns,
8483
8612
  ep.columns,
8484
- import_types29.Provenance.EXTRACTED,
8485
- (0, import_types29.confidenceForExtracted)(ep.confidenceKind)
8613
+ import_types30.Provenance.EXTRACTED,
8614
+ (0, import_types30.confidenceForExtracted)(ep.confidenceKind)
8486
8615
  )
8487
8616
  });
8488
8617
  }
8489
8618
  }
8490
8619
  const edgeType = edgeTypeFromEndpoint(ep);
8491
- const confidence = (0, import_types29.confidenceForExtracted)(ep.confidenceKind);
8620
+ const confidence = (0, import_types30.confidenceForExtracted)(ep.confidenceKind);
8492
8621
  const relFile = toPosix(ep.evidence.file);
8493
8622
  const { fileNodeId, nodesAdded: n, edgesAdded: e } = ensureFileNode(
8494
8623
  graph,
@@ -8498,7 +8627,7 @@ async function addExternalEndpointEdges(graph, services) {
8498
8627
  );
8499
8628
  nodesAdded += n;
8500
8629
  edgesAdded += e;
8501
- if (!(0, import_types29.passesExtractedFloor)(confidence)) {
8630
+ if (!(0, import_types30.passesExtractedFloor)(confidence)) {
8502
8631
  noteExtractedDropped({
8503
8632
  source: fileNodeId,
8504
8633
  target: ep.infraId,
@@ -8518,7 +8647,7 @@ async function addExternalEndpointEdges(graph, services) {
8518
8647
  source: fileNodeId,
8519
8648
  target: ep.infraId,
8520
8649
  type: edgeType,
8521
- provenance: import_types29.Provenance.EXTRACTED,
8650
+ provenance: import_types30.Provenance.EXTRACTED,
8522
8651
  confidence,
8523
8652
  evidence: ep.evidence
8524
8653
  };
@@ -8544,16 +8673,16 @@ init_cjs_shims();
8544
8673
 
8545
8674
  // src/extract/infra/docker-compose.ts
8546
8675
  init_cjs_shims();
8547
- var import_node_path41 = __toESM(require("path"), 1);
8548
- var import_types31 = require("@neat.is/types");
8676
+ var import_node_path42 = __toESM(require("path"), 1);
8677
+ var import_types32 = require("@neat.is/types");
8549
8678
 
8550
8679
  // src/extract/infra/shared.ts
8551
8680
  init_cjs_shims();
8552
- var import_types30 = require("@neat.is/types");
8681
+ var import_types31 = require("@neat.is/types");
8553
8682
  function makeInfraNode(kind, name, provider = "self", extras) {
8554
8683
  return {
8555
- id: (0, import_types30.infraId)(kind, name),
8556
- type: import_types30.NodeType.InfraNode,
8684
+ id: (0, import_types31.infraId)(kind, name),
8685
+ type: import_types31.NodeType.InfraNode,
8557
8686
  name,
8558
8687
  provider,
8559
8688
  kind,
@@ -8597,8 +8726,8 @@ function emitPlatformResourceEdge(graph, anchorId, edgeType, kind, name, provide
8597
8726
  source: anchorId,
8598
8727
  target: node.id,
8599
8728
  type: edgeType,
8600
- provenance: import_types30.Provenance.EXTRACTED,
8601
- confidence: (0, import_types30.confidenceForExtracted)("structural"),
8729
+ provenance: import_types31.Provenance.EXTRACTED,
8730
+ confidence: (0, import_types31.confidenceForExtracted)("structural"),
8602
8731
  evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
8603
8732
  };
8604
8733
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -8615,7 +8744,7 @@ function dependsOnList(value) {
8615
8744
  }
8616
8745
  function serviceNameToServiceNode(name, services) {
8617
8746
  for (const s of services) {
8618
- if (s.node.name === name || import_node_path41.default.basename(s.dir) === name) return s.node.id;
8747
+ if (s.node.name === name || import_node_path42.default.basename(s.dir) === name) return s.node.id;
8619
8748
  }
8620
8749
  return null;
8621
8750
  }
@@ -8624,7 +8753,7 @@ async function addComposeInfra(graph, scanPath, services) {
8624
8753
  let edgesAdded = 0;
8625
8754
  let composePath = null;
8626
8755
  for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
8627
- const abs = import_node_path41.default.join(scanPath, name);
8756
+ const abs = import_node_path42.default.join(scanPath, name);
8628
8757
  if (await exists(abs)) {
8629
8758
  composePath = abs;
8630
8759
  break;
@@ -8637,13 +8766,13 @@ async function addComposeInfra(graph, scanPath, services) {
8637
8766
  } catch (err) {
8638
8767
  recordExtractionError(
8639
8768
  "infra docker-compose",
8640
- import_node_path41.default.relative(scanPath, composePath),
8769
+ import_node_path42.default.relative(scanPath, composePath),
8641
8770
  err
8642
8771
  );
8643
8772
  return { nodesAdded, edgesAdded };
8644
8773
  }
8645
8774
  if (!compose?.services) return { nodesAdded, edgesAdded };
8646
- const evidenceFile = import_node_path41.default.relative(scanPath, composePath).split(import_node_path41.default.sep).join("/");
8775
+ const evidenceFile = import_node_path42.default.relative(scanPath, composePath).split(import_node_path42.default.sep).join("/");
8647
8776
  const composeNameToNodeId = /* @__PURE__ */ new Map();
8648
8777
  for (const [composeName, svc] of Object.entries(compose.services)) {
8649
8778
  const matchedServiceId = serviceNameToServiceNode(composeName, services);
@@ -8665,15 +8794,15 @@ async function addComposeInfra(graph, scanPath, services) {
8665
8794
  for (const dep of dependsOnList(svc.depends_on)) {
8666
8795
  const targetId = composeNameToNodeId.get(dep);
8667
8796
  if (!targetId) continue;
8668
- const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId, import_types31.EdgeType.DEPENDS_ON);
8797
+ const edgeId = (0, import_types3.extractedEdgeId)(sourceId, targetId, import_types32.EdgeType.DEPENDS_ON);
8669
8798
  if (graph.hasEdge(edgeId)) continue;
8670
8799
  const edge = {
8671
8800
  id: edgeId,
8672
8801
  source: sourceId,
8673
8802
  target: targetId,
8674
- type: import_types31.EdgeType.DEPENDS_ON,
8675
- provenance: import_types31.Provenance.EXTRACTED,
8676
- confidence: (0, import_types31.confidenceForExtracted)("structural"),
8803
+ type: import_types32.EdgeType.DEPENDS_ON,
8804
+ provenance: import_types32.Provenance.EXTRACTED,
8805
+ confidence: (0, import_types32.confidenceForExtracted)("structural"),
8677
8806
  evidence: { file: evidenceFile }
8678
8807
  };
8679
8808
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -8685,9 +8814,9 @@ async function addComposeInfra(graph, scanPath, services) {
8685
8814
 
8686
8815
  // src/extract/infra/dockerfile.ts
8687
8816
  init_cjs_shims();
8688
- var import_node_path42 = __toESM(require("path"), 1);
8817
+ var import_node_path43 = __toESM(require("path"), 1);
8689
8818
  var import_node_fs17 = require("fs");
8690
- var import_types32 = require("@neat.is/types");
8819
+ var import_types33 = require("@neat.is/types");
8691
8820
  function readDockerfile(content) {
8692
8821
  let image = null;
8693
8822
  const ports = [];
@@ -8716,7 +8845,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8716
8845
  let nodesAdded = 0;
8717
8846
  let edgesAdded = 0;
8718
8847
  for (const service of services) {
8719
- const dockerfilePath = import_node_path42.default.join(service.dir, "Dockerfile");
8848
+ const dockerfilePath = import_node_path43.default.join(service.dir, "Dockerfile");
8720
8849
  if (!await exists(dockerfilePath)) continue;
8721
8850
  let content;
8722
8851
  try {
@@ -8724,7 +8853,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8724
8853
  } catch (err) {
8725
8854
  recordExtractionError(
8726
8855
  "infra dockerfile",
8727
- import_node_path42.default.relative(scanPath, dockerfilePath),
8856
+ import_node_path43.default.relative(scanPath, dockerfilePath),
8728
8857
  err
8729
8858
  );
8730
8859
  continue;
@@ -8736,8 +8865,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8736
8865
  graph.addNode(node.id, node);
8737
8866
  nodesAdded++;
8738
8867
  }
8739
- const relDockerfile = toPosix(import_node_path42.default.relative(service.dir, dockerfilePath));
8740
- const evidenceFile = toPosix(import_node_path42.default.relative(scanPath, dockerfilePath));
8868
+ const relDockerfile = toPosix(import_node_path43.default.relative(service.dir, dockerfilePath));
8869
+ const evidenceFile = toPosix(import_node_path43.default.relative(scanPath, dockerfilePath));
8741
8870
  const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
8742
8871
  graph,
8743
8872
  service.pkg.name,
@@ -8746,15 +8875,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8746
8875
  );
8747
8876
  nodesAdded += fn;
8748
8877
  edgesAdded += fe;
8749
- const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types32.EdgeType.RUNS_ON);
8878
+ const edgeId = (0, import_types3.extractedEdgeId)(fileNodeId, node.id, import_types33.EdgeType.RUNS_ON);
8750
8879
  if (!graph.hasEdge(edgeId)) {
8751
8880
  const edge = {
8752
8881
  id: edgeId,
8753
8882
  source: fileNodeId,
8754
8883
  target: node.id,
8755
- type: import_types32.EdgeType.RUNS_ON,
8756
- provenance: import_types32.Provenance.EXTRACTED,
8757
- confidence: (0, import_types32.confidenceForExtracted)("structural"),
8884
+ type: import_types33.EdgeType.RUNS_ON,
8885
+ provenance: import_types33.Provenance.EXTRACTED,
8886
+ confidence: (0, import_types33.confidenceForExtracted)("structural"),
8758
8887
  evidence: {
8759
8888
  file: evidenceFile,
8760
8889
  ...facts.entrypoint ? { snippet: facts.entrypoint.slice(0, 120) } : {}
@@ -8769,15 +8898,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8769
8898
  graph.addNode(portNode.id, portNode);
8770
8899
  nodesAdded++;
8771
8900
  }
8772
- const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id, import_types32.EdgeType.CONNECTS_TO);
8901
+ const portEdgeId = (0, import_types3.extractedEdgeId)(fileNodeId, portNode.id, import_types33.EdgeType.CONNECTS_TO);
8773
8902
  if (graph.hasEdge(portEdgeId)) continue;
8774
8903
  const portEdge = {
8775
8904
  id: portEdgeId,
8776
8905
  source: fileNodeId,
8777
8906
  target: portNode.id,
8778
- type: import_types32.EdgeType.CONNECTS_TO,
8779
- provenance: import_types32.Provenance.EXTRACTED,
8780
- confidence: (0, import_types32.confidenceForExtracted)("structural"),
8907
+ type: import_types33.EdgeType.CONNECTS_TO,
8908
+ provenance: import_types33.Provenance.EXTRACTED,
8909
+ confidence: (0, import_types33.confidenceForExtracted)("structural"),
8781
8910
  evidence: { file: evidenceFile, snippet: `EXPOSE ${port}` }
8782
8911
  };
8783
8912
  graph.addEdgeWithKey(portEdgeId, portEdge.source, portEdge.target, portEdge);
@@ -8790,8 +8919,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8790
8919
  // src/extract/infra/terraform.ts
8791
8920
  init_cjs_shims();
8792
8921
  var import_node_fs18 = require("fs");
8793
- var import_node_path43 = __toESM(require("path"), 1);
8794
- var import_types33 = require("@neat.is/types");
8922
+ var import_node_path44 = __toESM(require("path"), 1);
8923
+ var import_types34 = require("@neat.is/types");
8795
8924
  var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
8796
8925
  var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
8797
8926
  async function walkTfFiles(start, depth = 0, max = 5) {
@@ -8801,11 +8930,11 @@ async function walkTfFiles(start, depth = 0, max = 5) {
8801
8930
  for (const entry2 of entries) {
8802
8931
  if (entry2.isDirectory()) {
8803
8932
  if (IGNORED_DIRS.has(entry2.name) || entry2.name === ".terraform") continue;
8804
- const child = import_node_path43.default.join(start, entry2.name);
8933
+ const child = import_node_path44.default.join(start, entry2.name);
8805
8934
  if (await isPythonVenvDir(child)) continue;
8806
8935
  out.push(...await walkTfFiles(child, depth + 1, max));
8807
8936
  } else if (entry2.isFile() && entry2.name.endsWith(".tf")) {
8808
- out.push(import_node_path43.default.join(start, entry2.name));
8937
+ out.push(import_node_path44.default.join(start, entry2.name));
8809
8938
  }
8810
8939
  }
8811
8940
  return out;
@@ -8837,7 +8966,7 @@ async function addTerraformResources(graph, scanPath) {
8837
8966
  const files = await walkTfFiles(scanPath);
8838
8967
  for (const file of files) {
8839
8968
  const content = await import_node_fs18.promises.readFile(file, "utf8");
8840
- const evidenceFile = toPosix(import_node_path43.default.relative(scanPath, file));
8969
+ const evidenceFile = toPosix(import_node_path44.default.relative(scanPath, file));
8841
8970
  const resources = [];
8842
8971
  const byKey = /* @__PURE__ */ new Map();
8843
8972
  RESOURCE_RE.lastIndex = 0;
@@ -8872,16 +9001,16 @@ async function addTerraformResources(graph, scanPath) {
8872
9001
  if (!target) continue;
8873
9002
  if (seen.has(target.nodeId)) continue;
8874
9003
  seen.add(target.nodeId);
8875
- const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId, import_types33.EdgeType.DEPENDS_ON);
9004
+ const edgeId = (0, import_types3.extractedEdgeId)(resource.nodeId, target.nodeId, import_types34.EdgeType.DEPENDS_ON);
8876
9005
  if (graph.hasEdge(edgeId)) continue;
8877
9006
  const line = lineAt2(content, resource.bodyOffset + ref.index);
8878
9007
  const edge = {
8879
9008
  id: edgeId,
8880
9009
  source: resource.nodeId,
8881
9010
  target: target.nodeId,
8882
- type: import_types33.EdgeType.DEPENDS_ON,
8883
- provenance: import_types33.Provenance.EXTRACTED,
8884
- confidence: (0, import_types33.confidenceForExtracted)("structural"),
9011
+ type: import_types34.EdgeType.DEPENDS_ON,
9012
+ provenance: import_types34.Provenance.EXTRACTED,
9013
+ confidence: (0, import_types34.confidenceForExtracted)("structural"),
8885
9014
  evidence: { file: evidenceFile, line, snippet: key }
8886
9015
  };
8887
9016
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -8895,7 +9024,7 @@ async function addTerraformResources(graph, scanPath) {
8895
9024
  // src/extract/infra/k8s.ts
8896
9025
  init_cjs_shims();
8897
9026
  var import_node_fs19 = require("fs");
8898
- var import_node_path44 = __toESM(require("path"), 1);
9027
+ var import_node_path45 = __toESM(require("path"), 1);
8899
9028
  var import_yaml3 = require("yaml");
8900
9029
  var K8S_KIND_TO_INFRA_KIND = {
8901
9030
  Service: "k8s-service",
@@ -8913,11 +9042,11 @@ async function walkYamlFiles2(start, depth = 0, max = 5) {
8913
9042
  for (const entry2 of entries) {
8914
9043
  if (entry2.isDirectory()) {
8915
9044
  if (IGNORED_DIRS.has(entry2.name)) continue;
8916
- const child = import_node_path44.default.join(start, entry2.name);
9045
+ const child = import_node_path45.default.join(start, entry2.name);
8917
9046
  if (await isPythonVenvDir(child)) continue;
8918
9047
  out.push(...await walkYamlFiles2(child, depth + 1, max));
8919
- } else if (entry2.isFile() && CONFIG_FILE_EXTENSIONS.has(import_node_path44.default.extname(entry2.name))) {
8920
- out.push(import_node_path44.default.join(start, entry2.name));
9048
+ } else if (entry2.isFile() && CONFIG_FILE_EXTENSIONS.has(import_node_path45.default.extname(entry2.name))) {
9049
+ out.push(import_node_path45.default.join(start, entry2.name));
8921
9050
  }
8922
9051
  }
8923
9052
  return out;
@@ -8951,13 +9080,13 @@ async function addK8sResources(graph, scanPath) {
8951
9080
  // src/extract/infra/cloudflare.ts
8952
9081
  init_cjs_shims();
8953
9082
  var import_node_fs20 = require("fs");
8954
- var import_node_path45 = __toESM(require("path"), 1);
9083
+ var import_node_path46 = __toESM(require("path"), 1);
8955
9084
  var import_smol_toml2 = require("smol-toml");
8956
- var import_types34 = require("@neat.is/types");
9085
+ var import_types35 = require("@neat.is/types");
8957
9086
  var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
8958
9087
  async function readWranglerConfig(dir) {
8959
9088
  for (const filename of WRANGLER_FILENAMES) {
8960
- const abs = import_node_path45.default.join(dir, filename);
9089
+ const abs = import_node_path46.default.join(dir, filename);
8961
9090
  if (!await exists(abs)) continue;
8962
9091
  const raw = await import_node_fs20.promises.readFile(abs, "utf8");
8963
9092
  const config = filename === "wrangler.toml" ? (0, import_smol_toml2.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
@@ -9001,8 +9130,8 @@ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, li
9001
9130
  source: anchorId,
9002
9131
  target: node.id,
9003
9132
  type: edgeType,
9004
- provenance: import_types34.Provenance.EXTRACTED,
9005
- confidence: (0, import_types34.confidenceForExtracted)("structural"),
9133
+ provenance: import_types35.Provenance.EXTRACTED,
9134
+ confidence: (0, import_types35.confidenceForExtracted)("structural"),
9006
9135
  evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
9007
9136
  };
9008
9137
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -9020,11 +9149,11 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9020
9149
  try {
9021
9150
  read = await readWranglerConfig(service.dir);
9022
9151
  } catch (err) {
9023
- recordExtractionError("infra cloudflare", import_node_path45.default.relative(scanPath, service.dir), err);
9152
+ recordExtractionError("infra cloudflare", import_node_path46.default.relative(scanPath, service.dir), err);
9024
9153
  continue;
9025
9154
  }
9026
9155
  if (!read || !read.config.name) continue;
9027
- const evidenceFile = toPosix(import_node_path45.default.relative(scanPath, import_node_path45.default.join(service.dir, read.relFile)));
9156
+ const evidenceFile = toPosix(import_node_path46.default.relative(scanPath, import_node_path46.default.join(service.dir, read.relFile)));
9028
9157
  discovered.push({ service, config: read.config, relFile: read.relFile, raw: read.raw, evidenceFile });
9029
9158
  }
9030
9159
  for (const worker of discovered) {
@@ -9036,7 +9165,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9036
9165
  }
9037
9166
  let anchorId = service.node.id;
9038
9167
  if (config.main) {
9039
- const entryRelPath = toPosix(import_node_path45.default.normalize(config.main));
9168
+ const entryRelPath = toPosix(import_node_path46.default.normalize(config.main));
9040
9169
  const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
9041
9170
  graph,
9042
9171
  service.pkg.name,
@@ -9063,15 +9192,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9063
9192
  nodesAdded++;
9064
9193
  }
9065
9194
  if (runtimeNode.id !== anchorId) {
9066
- const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id, import_types34.EdgeType.RUNS_ON);
9195
+ const runsOnId = (0, import_types3.extractedEdgeId)(anchorId, runtimeNode.id, import_types35.EdgeType.RUNS_ON);
9067
9196
  if (!graph.hasEdge(runsOnId)) {
9068
9197
  const edge = {
9069
9198
  id: runsOnId,
9070
9199
  source: anchorId,
9071
9200
  target: runtimeNode.id,
9072
- type: import_types34.EdgeType.RUNS_ON,
9073
- provenance: import_types34.Provenance.EXTRACTED,
9074
- confidence: (0, import_types34.confidenceForExtracted)("structural"),
9201
+ type: import_types35.EdgeType.RUNS_ON,
9202
+ provenance: import_types35.Provenance.EXTRACTED,
9203
+ confidence: (0, import_types35.confidenceForExtracted)("structural"),
9075
9204
  evidence: {
9076
9205
  file: evidenceFile,
9077
9206
  ...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
@@ -9085,7 +9214,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9085
9214
  const result = addResourceEdge(
9086
9215
  graph,
9087
9216
  anchorId,
9088
- import_types34.EdgeType.CONNECTS_TO,
9217
+ import_types35.EdgeType.CONNECTS_TO,
9089
9218
  "cloudflare-route",
9090
9219
  route,
9091
9220
  evidenceFile,
@@ -9109,7 +9238,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9109
9238
  const result = addResourceEdge(
9110
9239
  graph,
9111
9240
  anchorId,
9112
- import_types34.EdgeType.DEPENDS_ON,
9241
+ import_types35.EdgeType.DEPENDS_ON,
9113
9242
  group.kind,
9114
9243
  name,
9115
9244
  evidenceFile,
@@ -9123,7 +9252,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9123
9252
  const result = addResourceEdge(
9124
9253
  graph,
9125
9254
  anchorId,
9126
- import_types34.EdgeType.DEPENDS_ON,
9255
+ import_types35.EdgeType.DEPENDS_ON,
9127
9256
  "cloudflare-cron",
9128
9257
  cron,
9129
9258
  evidenceFile,
@@ -9136,7 +9265,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9136
9265
  const result = addResourceEdge(
9137
9266
  graph,
9138
9267
  anchorId,
9139
- import_types34.EdgeType.DEPENDS_ON,
9268
+ import_types35.EdgeType.DEPENDS_ON,
9140
9269
  "cloudflare-env-var",
9141
9270
  varName,
9142
9271
  evidenceFile,
@@ -9149,15 +9278,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9149
9278
  if (!svc.service) continue;
9150
9279
  const target = workerIndex.get(svc.service);
9151
9280
  if (target && target.anchorId !== anchorId) {
9152
- const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId, import_types34.EdgeType.CALLS);
9281
+ const edgeId = (0, import_types3.extractedEdgeId)(anchorId, target.anchorId, import_types35.EdgeType.CALLS);
9153
9282
  if (!graph.hasEdge(edgeId)) {
9154
9283
  const edge = {
9155
9284
  id: edgeId,
9156
9285
  source: anchorId,
9157
9286
  target: target.anchorId,
9158
- type: import_types34.EdgeType.CALLS,
9159
- provenance: import_types34.Provenance.EXTRACTED,
9160
- confidence: (0, import_types34.confidenceForExtracted)("structural"),
9287
+ type: import_types35.EdgeType.CALLS,
9288
+ provenance: import_types35.Provenance.EXTRACTED,
9289
+ confidence: (0, import_types35.confidenceForExtracted)("structural"),
9161
9290
  evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
9162
9291
  };
9163
9292
  graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
@@ -9168,7 +9297,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9168
9297
  const result = addResourceEdge(
9169
9298
  graph,
9170
9299
  anchorId,
9171
- import_types34.EdgeType.DEPENDS_ON,
9300
+ import_types35.EdgeType.DEPENDS_ON,
9172
9301
  "cloudflare-service-binding",
9173
9302
  svc.service,
9174
9303
  evidenceFile,
@@ -9184,12 +9313,12 @@ async function addCloudflareWorkers(graph, services, scanPath) {
9184
9313
  // src/extract/infra/vercel.ts
9185
9314
  init_cjs_shims();
9186
9315
  var import_node_fs21 = require("fs");
9187
- var import_node_path46 = __toESM(require("path"), 1);
9188
- var import_types35 = require("@neat.is/types");
9316
+ var import_node_path47 = __toESM(require("path"), 1);
9317
+ var import_types36 = require("@neat.is/types");
9189
9318
  var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
9190
9319
  async function readVercelConfig(dir) {
9191
9320
  for (const filename of VERCEL_CONFIG_FILENAMES) {
9192
- const abs = import_node_path46.default.join(dir, filename);
9321
+ const abs = import_node_path47.default.join(dir, filename);
9193
9322
  if (!await exists(abs)) continue;
9194
9323
  const raw = await import_node_fs21.promises.readFile(abs, "utf8");
9195
9324
  const config = JSON.parse(maskCommentsInSource(raw));
@@ -9198,7 +9327,7 @@ async function readVercelConfig(dir) {
9198
9327
  return null;
9199
9328
  }
9200
9329
  async function readLinkedProjectName(dir) {
9201
- const abs = import_node_path46.default.join(dir, ".vercel", "project.json");
9330
+ const abs = import_node_path47.default.join(dir, ".vercel", "project.json");
9202
9331
  if (!await exists(abs)) return void 0;
9203
9332
  const parsed = JSON.parse(await import_node_fs21.promises.readFile(abs, "utf8"));
9204
9333
  return typeof parsed.projectName === "string" ? parsed.projectName : void 0;
@@ -9216,7 +9345,7 @@ async function addVercelServices(graph, services, scanPath) {
9216
9345
  read = await readVercelConfig(service.dir);
9217
9346
  projectName = await readLinkedProjectName(service.dir);
9218
9347
  } catch (err) {
9219
- recordExtractionError("infra vercel", import_node_path46.default.relative(scanPath, service.dir), err);
9348
+ recordExtractionError("infra vercel", import_node_path47.default.relative(scanPath, service.dir), err);
9220
9349
  continue;
9221
9350
  }
9222
9351
  if (!read && !projectName) continue;
@@ -9232,7 +9361,7 @@ async function addVercelServices(graph, services, scanPath) {
9232
9361
  const anchorId = service.node.id;
9233
9362
  if (!read) continue;
9234
9363
  const { config, relFile, raw } = read;
9235
- const evidenceFile = toPosix(import_node_path46.default.relative(scanPath, import_node_path46.default.join(service.dir, relFile)));
9364
+ const evidenceFile = toPosix(import_node_path47.default.relative(scanPath, import_node_path47.default.join(service.dir, relFile)));
9236
9365
  const add = (edgeType, kind, name) => {
9237
9366
  if (!name) return;
9238
9367
  const result = emitPlatformResourceEdge(
@@ -9248,12 +9377,12 @@ async function addVercelServices(graph, services, scanPath) {
9248
9377
  nodesAdded += result.nodesAdded;
9249
9378
  edgesAdded += result.edgesAdded;
9250
9379
  };
9251
- add(import_types35.EdgeType.RUNS_ON, "vercel", "vercel");
9252
- for (const cron of config.crons ?? []) add(import_types35.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
9253
- for (const varName of Object.keys(config.env ?? {})) add(import_types35.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
9254
- for (const varName of Object.keys(config.build?.env ?? {})) add(import_types35.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
9380
+ add(import_types36.EdgeType.RUNS_ON, "vercel", "vercel");
9381
+ for (const cron of config.crons ?? []) add(import_types36.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
9382
+ for (const varName of Object.keys(config.env ?? {})) add(import_types36.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
9383
+ for (const varName of Object.keys(config.build?.env ?? {})) add(import_types36.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
9255
9384
  for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
9256
- add(import_types35.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
9385
+ add(import_types36.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
9257
9386
  }
9258
9387
  }
9259
9388
  return { nodesAdded, edgesAdded };
@@ -9262,13 +9391,13 @@ async function addVercelServices(graph, services, scanPath) {
9262
9391
  // src/extract/infra/railway.ts
9263
9392
  init_cjs_shims();
9264
9393
  var import_node_fs22 = require("fs");
9265
- var import_node_path47 = __toESM(require("path"), 1);
9394
+ var import_node_path48 = __toESM(require("path"), 1);
9266
9395
  var import_smol_toml3 = require("smol-toml");
9267
- var import_types36 = require("@neat.is/types");
9396
+ var import_types37 = require("@neat.is/types");
9268
9397
  var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
9269
9398
  async function readRailwayConfig(dir) {
9270
9399
  for (const filename of RAILWAY_FILENAMES) {
9271
- const abs = import_node_path47.default.join(dir, filename);
9400
+ const abs = import_node_path48.default.join(dir, filename);
9272
9401
  if (!await exists(abs)) continue;
9273
9402
  const raw = await import_node_fs22.promises.readFile(abs, "utf8");
9274
9403
  const config = filename === "railway.toml" ? (0, import_smol_toml3.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
@@ -9284,7 +9413,7 @@ async function addRailwayServices(graph, services, scanPath) {
9284
9413
  try {
9285
9414
  read = await readRailwayConfig(service.dir);
9286
9415
  } catch (err) {
9287
- recordExtractionError("infra railway", import_node_path47.default.relative(scanPath, service.dir), err);
9416
+ recordExtractionError("infra railway", import_node_path48.default.relative(scanPath, service.dir), err);
9288
9417
  continue;
9289
9418
  }
9290
9419
  if (!read) continue;
@@ -9294,7 +9423,7 @@ async function addRailwayServices(graph, services, scanPath) {
9294
9423
  }
9295
9424
  const anchorId = service.node.id;
9296
9425
  const { config, relFile, raw } = read;
9297
- const evidenceFile = toPosix(import_node_path47.default.relative(scanPath, import_node_path47.default.join(service.dir, relFile)));
9426
+ const evidenceFile = toPosix(import_node_path48.default.relative(scanPath, import_node_path48.default.join(service.dir, relFile)));
9298
9427
  const add = (edgeType, kind, name) => {
9299
9428
  if (!name) return;
9300
9429
  const result = emitPlatformResourceEdge(
@@ -9310,9 +9439,9 @@ async function addRailwayServices(graph, services, scanPath) {
9310
9439
  nodesAdded += result.nodesAdded;
9311
9440
  edgesAdded += result.edgesAdded;
9312
9441
  };
9313
- add(import_types36.EdgeType.RUNS_ON, "railway", "railway");
9314
- add(import_types36.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
9315
- add(import_types36.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
9442
+ add(import_types37.EdgeType.RUNS_ON, "railway", "railway");
9443
+ add(import_types37.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
9444
+ add(import_types37.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
9316
9445
  }
9317
9446
  return { nodesAdded, edgesAdded };
9318
9447
  }
@@ -9320,12 +9449,12 @@ async function addRailwayServices(graph, services, scanPath) {
9320
9449
  // src/extract/infra/supabase.ts
9321
9450
  init_cjs_shims();
9322
9451
  var import_node_fs23 = require("fs");
9323
- var import_node_path48 = __toESM(require("path"), 1);
9452
+ var import_node_path49 = __toESM(require("path"), 1);
9324
9453
  var import_smol_toml4 = require("smol-toml");
9325
- var import_types37 = require("@neat.is/types");
9454
+ var import_types38 = require("@neat.is/types");
9326
9455
  async function readSupabaseConfig(dir) {
9327
- const relFile = import_node_path48.default.join("supabase", "config.toml");
9328
- const abs = import_node_path48.default.join(dir, relFile);
9456
+ const relFile = import_node_path49.default.join("supabase", "config.toml");
9457
+ const abs = import_node_path49.default.join(dir, relFile);
9329
9458
  if (!await exists(abs)) return null;
9330
9459
  const raw = await import_node_fs23.promises.readFile(abs, "utf8");
9331
9460
  const config = (0, import_smol_toml4.parse)(raw);
@@ -9339,7 +9468,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
9339
9468
  try {
9340
9469
  read = await readSupabaseConfig(service.dir);
9341
9470
  } catch (err) {
9342
- recordExtractionError("infra supabase", import_node_path48.default.relative(scanPath, service.dir), err);
9471
+ recordExtractionError("infra supabase", import_node_path49.default.relative(scanPath, service.dir), err);
9343
9472
  continue;
9344
9473
  }
9345
9474
  if (!read) continue;
@@ -9354,7 +9483,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
9354
9483
  });
9355
9484
  }
9356
9485
  const anchorId = service.node.id;
9357
- const evidenceFile = toPosix(import_node_path48.default.relative(scanPath, import_node_path48.default.join(service.dir, relFile)));
9486
+ const evidenceFile = toPosix(import_node_path49.default.relative(scanPath, import_node_path49.default.join(service.dir, relFile)));
9358
9487
  const add = (edgeType, kind, name) => {
9359
9488
  if (!name) return;
9360
9489
  const result = emitPlatformResourceEdge(
@@ -9370,10 +9499,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
9370
9499
  nodesAdded += result.nodesAdded;
9371
9500
  edgesAdded += result.edgesAdded;
9372
9501
  };
9373
- add(import_types37.EdgeType.RUNS_ON, "supabase", "supabase");
9374
- for (const fn of Object.keys(config.functions ?? {})) add(import_types37.EdgeType.DEPENDS_ON, "supabase-function", fn);
9375
- if (config.storage) add(import_types37.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
9376
- if (config.auth) add(import_types37.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
9502
+ add(import_types38.EdgeType.RUNS_ON, "supabase", "supabase");
9503
+ for (const fn of Object.keys(config.functions ?? {})) add(import_types38.EdgeType.DEPENDS_ON, "supabase-function", fn);
9504
+ if (config.storage) add(import_types38.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
9505
+ if (config.auth) add(import_types38.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
9377
9506
  }
9378
9507
  return { nodesAdded, edgesAdded };
9379
9508
  }
@@ -9395,17 +9524,17 @@ async function addInfra(graph, scanPath, services) {
9395
9524
  }
9396
9525
 
9397
9526
  // src/extract/index.ts
9398
- var import_node_path50 = __toESM(require("path"), 1);
9527
+ var import_node_path51 = __toESM(require("path"), 1);
9399
9528
 
9400
9529
  // src/extract/retire.ts
9401
9530
  init_cjs_shims();
9402
9531
  var import_node_fs24 = require("fs");
9403
- var import_node_path49 = __toESM(require("path"), 1);
9404
- var import_types38 = require("@neat.is/types");
9532
+ var import_node_path50 = __toESM(require("path"), 1);
9533
+ var import_types39 = require("@neat.is/types");
9405
9534
  function dropOrphanedFileNodes(graph) {
9406
9535
  const orphans = [];
9407
9536
  graph.forEachNode((id, attrs) => {
9408
- if (attrs.type !== import_types38.NodeType.FileNode) return;
9537
+ if (attrs.type !== import_types39.NodeType.FileNode) return;
9409
9538
  if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
9410
9539
  orphans.push(id);
9411
9540
  }
@@ -9418,14 +9547,14 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
9418
9547
  const bases = [scanPath, ...serviceDirs];
9419
9548
  graph.forEachEdge((id, attrs) => {
9420
9549
  const edge = attrs;
9421
- if (edge.provenance !== import_types38.Provenance.EXTRACTED) return;
9550
+ if (edge.provenance !== import_types39.Provenance.EXTRACTED) return;
9422
9551
  const evidenceFile = edge.evidence?.file;
9423
9552
  if (!evidenceFile) return;
9424
- if (import_node_path49.default.isAbsolute(evidenceFile)) {
9553
+ if (import_node_path50.default.isAbsolute(evidenceFile)) {
9425
9554
  if (!(0, import_node_fs24.existsSync)(evidenceFile)) toDrop.push(id);
9426
9555
  return;
9427
9556
  }
9428
- const found = bases.some((base) => (0, import_node_fs24.existsSync)(import_node_path49.default.join(base, evidenceFile)));
9557
+ const found = bases.some((base) => (0, import_node_fs24.existsSync)(import_node_path50.default.join(base, evidenceFile)));
9429
9558
  if (!found) toDrop.push(id);
9430
9559
  });
9431
9560
  for (const id of toDrop) graph.dropEdge(id);
@@ -9478,7 +9607,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
9478
9607
  }
9479
9608
  const droppedEntries = drainDroppedExtracted();
9480
9609
  if (isRejectedLogEnabled() && opts.errorsPath && droppedEntries.length > 0) {
9481
- const rejectedPath = import_node_path50.default.join(import_node_path50.default.dirname(opts.errorsPath), "rejected.ndjson");
9610
+ const rejectedPath = import_node_path51.default.join(import_node_path51.default.dirname(opts.errorsPath), "rejected.ndjson");
9482
9611
  try {
9483
9612
  await writeRejectedExtracted(droppedEntries, rejectedPath);
9484
9613
  } catch (err) {
@@ -9513,8 +9642,8 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
9513
9642
  // src/persist.ts
9514
9643
  init_cjs_shims();
9515
9644
  var import_node_fs25 = require("fs");
9516
- var import_node_path51 = __toESM(require("path"), 1);
9517
- var import_types39 = require("@neat.is/types");
9645
+ var import_node_path52 = __toESM(require("path"), 1);
9646
+ var import_types40 = require("@neat.is/types");
9518
9647
  var SCHEMA_VERSION = 6;
9519
9648
  function migrateV1ToV2(payload) {
9520
9649
  const nodes = payload.graph.nodes;
@@ -9538,7 +9667,7 @@ function migrateV5ToV6(payload) {
9538
9667
  if (Array.isArray(nodes)) {
9539
9668
  for (const node of nodes) {
9540
9669
  const attrs = node.attributes;
9541
- if (!attrs || attrs.type !== import_types39.NodeType.InfraNode) continue;
9670
+ if (!attrs || attrs.type !== import_types40.NodeType.InfraNode) continue;
9542
9671
  if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
9543
9672
  if (!Array.isArray(attrs.columns)) attrs.columns = [];
9544
9673
  }
@@ -9551,12 +9680,12 @@ function migrateV2ToV3(payload) {
9551
9680
  for (const edge of edges) {
9552
9681
  const attrs = edge.attributes;
9553
9682
  if (!attrs || attrs.provenance !== "FRONTIER") continue;
9554
- attrs.provenance = import_types39.Provenance.OBSERVED;
9683
+ attrs.provenance = import_types40.Provenance.OBSERVED;
9555
9684
  const type = typeof attrs.type === "string" ? attrs.type : void 0;
9556
9685
  const source = typeof attrs.source === "string" ? attrs.source : void 0;
9557
9686
  const target = typeof attrs.target === "string" ? attrs.target : void 0;
9558
9687
  if (type && source && target) {
9559
- const newId = (0, import_types39.observedEdgeId)(source, target, type);
9688
+ const newId = (0, import_types40.observedEdgeId)(source, target, type);
9560
9689
  attrs.id = newId;
9561
9690
  if (edge.key) edge.key = newId;
9562
9691
  }
@@ -9565,7 +9694,7 @@ function migrateV2ToV3(payload) {
9565
9694
  return { ...payload, schemaVersion: 3 };
9566
9695
  }
9567
9696
  async function ensureDir(filePath) {
9568
- await import_node_fs25.promises.mkdir(import_node_path51.default.dirname(filePath), { recursive: true });
9697
+ await import_node_fs25.promises.mkdir(import_node_path52.default.dirname(filePath), { recursive: true });
9569
9698
  }
9570
9699
  async function saveGraphToDisk(graph, outPath) {
9571
9700
  await ensureDir(outPath);
@@ -9652,23 +9781,23 @@ function startPersistLoop(graph, outPath, opts = {}) {
9652
9781
 
9653
9782
  // src/projects.ts
9654
9783
  init_cjs_shims();
9655
- var import_node_path52 = __toESM(require("path"), 1);
9784
+ var import_node_path53 = __toESM(require("path"), 1);
9656
9785
  function pathsForProject(project, baseDir) {
9657
9786
  if (project === DEFAULT_PROJECT) {
9658
9787
  return {
9659
- snapshotPath: import_node_path52.default.join(baseDir, "graph.json"),
9660
- errorsPath: import_node_path52.default.join(baseDir, "errors.ndjson"),
9661
- staleEventsPath: import_node_path52.default.join(baseDir, "stale-events.ndjson"),
9662
- embeddingsCachePath: import_node_path52.default.join(baseDir, "embeddings.json"),
9663
- policyViolationsPath: import_node_path52.default.join(baseDir, "policy-violations.ndjson")
9788
+ snapshotPath: import_node_path53.default.join(baseDir, "graph.json"),
9789
+ errorsPath: import_node_path53.default.join(baseDir, "errors.ndjson"),
9790
+ staleEventsPath: import_node_path53.default.join(baseDir, "stale-events.ndjson"),
9791
+ embeddingsCachePath: import_node_path53.default.join(baseDir, "embeddings.json"),
9792
+ policyViolationsPath: import_node_path53.default.join(baseDir, "policy-violations.ndjson")
9664
9793
  };
9665
9794
  }
9666
9795
  return {
9667
- snapshotPath: import_node_path52.default.join(baseDir, `${project}.json`),
9668
- errorsPath: import_node_path52.default.join(baseDir, `errors.${project}.ndjson`),
9669
- staleEventsPath: import_node_path52.default.join(baseDir, `stale-events.${project}.ndjson`),
9670
- embeddingsCachePath: import_node_path52.default.join(baseDir, `embeddings.${project}.json`),
9671
- policyViolationsPath: import_node_path52.default.join(baseDir, `policy-violations.${project}.ndjson`)
9796
+ snapshotPath: import_node_path53.default.join(baseDir, `${project}.json`),
9797
+ errorsPath: import_node_path53.default.join(baseDir, `errors.${project}.ndjson`),
9798
+ staleEventsPath: import_node_path53.default.join(baseDir, `stale-events.${project}.ndjson`),
9799
+ embeddingsCachePath: import_node_path53.default.join(baseDir, `embeddings.${project}.json`),
9800
+ policyViolationsPath: import_node_path53.default.join(baseDir, `policy-violations.${project}.ndjson`)
9672
9801
  };
9673
9802
  }
9674
9803
  var Projects = class {
@@ -9706,19 +9835,19 @@ var Projects = class {
9706
9835
  init_cjs_shims();
9707
9836
  var import_fastify2 = __toESM(require("fastify"), 1);
9708
9837
  var import_cors = __toESM(require("@fastify/cors"), 1);
9709
- var import_types58 = require("@neat.is/types");
9838
+ var import_types59 = require("@neat.is/types");
9710
9839
 
9711
9840
  // src/extend/index.ts
9712
9841
  init_cjs_shims();
9713
9842
  var import_node_fs27 = require("fs");
9714
- var import_node_path54 = __toESM(require("path"), 1);
9843
+ var import_node_path55 = __toESM(require("path"), 1);
9715
9844
  var import_node_os2 = __toESM(require("os"), 1);
9716
9845
  var import_instrumentation_registry = require("@neat.is/instrumentation-registry");
9717
9846
 
9718
9847
  // src/installers/package-manager.ts
9719
9848
  init_cjs_shims();
9720
9849
  var import_node_fs26 = require("fs");
9721
- var import_node_path53 = __toESM(require("path"), 1);
9850
+ var import_node_path54 = __toESM(require("path"), 1);
9722
9851
  var import_node_child_process = require("child_process");
9723
9852
  var LOCKFILE_PRIORITY = [
9724
9853
  { lockfile: "bun.lockb", pm: "bun", args: ["install", "--no-summary"] },
@@ -9740,22 +9869,22 @@ async function exists2(p) {
9740
9869
  }
9741
9870
  }
9742
9871
  async function detectPackageManager(serviceDir) {
9743
- let dir = import_node_path53.default.resolve(serviceDir);
9872
+ let dir = import_node_path54.default.resolve(serviceDir);
9744
9873
  const stops = /* @__PURE__ */ new Set();
9745
9874
  for (let i = 0; i < 64; i++) {
9746
9875
  if (stops.has(dir)) break;
9747
9876
  stops.add(dir);
9748
9877
  for (const candidate of LOCKFILE_PRIORITY) {
9749
- const lockPath = import_node_path53.default.join(dir, candidate.lockfile);
9878
+ const lockPath = import_node_path54.default.join(dir, candidate.lockfile);
9750
9879
  if (await exists2(lockPath)) {
9751
9880
  return { pm: candidate.pm, cwd: dir, args: [...candidate.args] };
9752
9881
  }
9753
9882
  }
9754
- const parent = import_node_path53.default.dirname(dir);
9883
+ const parent = import_node_path54.default.dirname(dir);
9755
9884
  if (parent === dir) break;
9756
9885
  dir = parent;
9757
9886
  }
9758
- return { pm: "npm", cwd: import_node_path53.default.resolve(serviceDir), args: [...NPM_FALLBACK_ARGS] };
9887
+ return { pm: "npm", cwd: import_node_path54.default.resolve(serviceDir), args: [...NPM_FALLBACK_ARGS] };
9759
9888
  }
9760
9889
  async function runPackageManagerInstall(cmd) {
9761
9890
  return new Promise((resolve) => {
@@ -9804,7 +9933,7 @@ async function fileExists2(p) {
9804
9933
  }
9805
9934
  }
9806
9935
  async function readPackageJson(scanPath) {
9807
- const pkgPath = import_node_path54.default.join(scanPath, "package.json");
9936
+ const pkgPath = import_node_path55.default.join(scanPath, "package.json");
9808
9937
  const raw = await import_node_fs27.promises.readFile(pkgPath, "utf8");
9809
9938
  return JSON.parse(raw);
9810
9939
  }
@@ -9823,11 +9952,11 @@ async function findHookFiles(scanPath) {
9823
9952
  for (const entry2 of entries) {
9824
9953
  if (entry2.isDirectory()) {
9825
9954
  if (entry2.name.startsWith(".") || HOOK_WALK_SKIP_DIRS.has(entry2.name)) continue;
9826
- await walk6(import_node_path54.default.join(dir, entry2.name));
9955
+ await walk6(import_node_path55.default.join(dir, entry2.name));
9827
9956
  } else if (entry2.isFile()) {
9828
9957
  if ((entry2.name.startsWith("instrumentation") || entry2.name.startsWith("otel-init")) && /\.(ts|js|cjs|mjs)$/.test(entry2.name)) {
9829
- const rel = import_node_path54.default.relative(scanPath, import_node_path54.default.join(dir, entry2.name));
9830
- found.push(rel.split(import_node_path54.default.sep).join("/"));
9958
+ const rel = import_node_path55.default.relative(scanPath, import_node_path55.default.join(dir, entry2.name));
9959
+ found.push(rel.split(import_node_path55.default.sep).join("/"));
9831
9960
  }
9832
9961
  }
9833
9962
  }
@@ -9838,7 +9967,7 @@ async function findHookFiles(scanPath) {
9838
9967
  async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
9839
9968
  let fallback = null;
9840
9969
  for (const file of hookFiles) {
9841
- const content = await import_node_fs27.promises.readFile(import_node_path54.default.join(scanPath, file), "utf8");
9970
+ const content = await import_node_fs27.promises.readFile(import_node_path55.default.join(scanPath, file), "utf8");
9842
9971
  const patched = splicedContent(content, snippet2);
9843
9972
  if (patched !== null) return { file, content, patched };
9844
9973
  if (fallback === null) fallback = { file, content };
@@ -9846,11 +9975,11 @@ async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
9846
9975
  return { file: fallback.file, content: fallback.content, patched: null };
9847
9976
  }
9848
9977
  function extendLogPath() {
9849
- return process.env.NEAT_EXTEND_LOG ?? import_node_path54.default.join(import_node_os2.default.homedir(), ".neat", "extend-log.ndjson");
9978
+ return process.env.NEAT_EXTEND_LOG ?? import_node_path55.default.join(import_node_os2.default.homedir(), ".neat", "extend-log.ndjson");
9850
9979
  }
9851
9980
  async function appendExtendLog(entry2) {
9852
9981
  const logPath = extendLogPath();
9853
- await import_node_fs27.promises.mkdir(import_node_path54.default.dirname(logPath), { recursive: true });
9982
+ await import_node_fs27.promises.mkdir(import_node_path55.default.dirname(logPath), { recursive: true });
9854
9983
  await import_node_fs27.promises.appendFile(logPath, JSON.stringify(entry2) + "\n", "utf8");
9855
9984
  }
9856
9985
  function splicedContent(fileContent, snippet2) {
@@ -9909,7 +10038,7 @@ function lookupInstrumentation(library, installedVersion) {
9909
10038
  }
9910
10039
  async function describeProjectInstrumentation(ctx) {
9911
10040
  const hookFiles = await findHookFiles(ctx.scanPath);
9912
- const envNeat = await fileExists2(import_node_path54.default.join(ctx.scanPath, ".env.neat"));
10041
+ const envNeat = await fileExists2(import_node_path55.default.join(ctx.scanPath, ".env.neat"));
9913
10042
  const registryInstrPackages = new Set(
9914
10043
  (0, import_instrumentation_registry.list)().map((e) => e.instrumentation_package).filter((p) => !!p)
9915
10044
  );
@@ -9931,7 +10060,7 @@ async function applyExtension(ctx, args, options) {
9931
10060
  );
9932
10061
  }
9933
10062
  for (const file of hookFiles) {
9934
- const content = await import_node_fs27.promises.readFile(import_node_path54.default.join(ctx.scanPath, file), "utf8");
10063
+ const content = await import_node_fs27.promises.readFile(import_node_path55.default.join(ctx.scanPath, file), "utf8");
9935
10064
  if (content.includes(args.registration_snippet)) {
9936
10065
  return { library: args.library, filesTouched: [], depsAdded: [], installOutput: "", alreadyApplied: true };
9937
10066
  }
@@ -9943,10 +10072,10 @@ async function applyExtension(ctx, args, options) {
9943
10072
  );
9944
10073
  }
9945
10074
  const primaryFile = primary.file;
9946
- const primaryPath = import_node_path54.default.join(ctx.scanPath, primaryFile);
10075
+ const primaryPath = import_node_path55.default.join(ctx.scanPath, primaryFile);
9947
10076
  const filesTouched = [];
9948
10077
  const depsAdded = [];
9949
- const pkgPath = import_node_path54.default.join(ctx.scanPath, "package.json");
10078
+ const pkgPath = import_node_path55.default.join(ctx.scanPath, "package.json");
9950
10079
  const pkg = await readPackageJson(ctx.scanPath);
9951
10080
  if (!(pkg.dependencies ?? {})[args.instrumentation_package]) {
9952
10081
  pkg.dependencies = { ...pkg.dependencies ?? {}, [args.instrumentation_package]: args.version };
@@ -9985,7 +10114,7 @@ async function dryRunExtension(ctx, args) {
9985
10114
  };
9986
10115
  }
9987
10116
  for (const file of hookFiles) {
9988
- const content = await import_node_fs27.promises.readFile(import_node_path54.default.join(ctx.scanPath, file), "utf8");
10117
+ const content = await import_node_fs27.promises.readFile(import_node_path55.default.join(ctx.scanPath, file), "utf8");
9989
10118
  if (content.includes(args.registration_snippet)) {
9990
10119
  return {
9991
10120
  library: args.library,
@@ -10026,7 +10155,7 @@ async function rollbackExtension(ctx, args) {
10026
10155
  if (!match) {
10027
10156
  return { undone: false, message: "no apply found for library" };
10028
10157
  }
10029
- const pkgPath = import_node_path54.default.join(ctx.scanPath, "package.json");
10158
+ const pkgPath = import_node_path55.default.join(ctx.scanPath, "package.json");
10030
10159
  if (await fileExists2(pkgPath)) {
10031
10160
  const pkg = await readPackageJson(ctx.scanPath);
10032
10161
  if (pkg.dependencies?.[match.instrumentation_package]) {
@@ -10037,7 +10166,7 @@ async function rollbackExtension(ctx, args) {
10037
10166
  }
10038
10167
  const hookFiles = await findHookFiles(ctx.scanPath);
10039
10168
  for (const file of hookFiles) {
10040
- const filePath = import_node_path54.default.join(ctx.scanPath, file);
10169
+ const filePath = import_node_path55.default.join(ctx.scanPath, file);
10041
10170
  const content = await import_node_fs27.promises.readFile(filePath, "utf8");
10042
10171
  if (content.includes(match.registration_snippet)) {
10043
10172
  const filtered = content.split("\n").filter((line) => !line.includes(match.registration_snippet)).join("\n");
@@ -10053,39 +10182,39 @@ async function rollbackExtension(ctx, args) {
10053
10182
 
10054
10183
  // src/divergences.ts
10055
10184
  init_cjs_shims();
10056
- var import_types40 = require("@neat.is/types");
10185
+ var import_types41 = require("@neat.is/types");
10057
10186
  function bucketKey(source, target, type) {
10058
10187
  return `${type}|${source}|${target}`;
10059
10188
  }
10060
10189
  function bucketSourceFor(graph, edge) {
10061
- if (edge.type !== import_types40.EdgeType.CONNECTS_TO) return edge.source;
10062
- const parsed = (0, import_types40.parseFileId)(edge.source);
10190
+ if (edge.type !== import_types41.EdgeType.CONNECTS_TO) return edge.source;
10191
+ const parsed = (0, import_types41.parseFileId)(edge.source);
10063
10192
  if (!parsed || !graph.hasNode(edge.target)) return edge.source;
10064
10193
  const target = graph.getNodeAttributes(edge.target);
10065
- if (target.type !== import_types40.NodeType.DatabaseNode) return edge.source;
10066
- return (0, import_types40.serviceId)(parsed.service);
10194
+ if (target.type !== import_types41.NodeType.DatabaseNode) return edge.source;
10195
+ return (0, import_types41.serviceId)(parsed.service);
10067
10196
  }
10068
10197
  function bucketEdges(graph) {
10069
10198
  const buckets2 = /* @__PURE__ */ new Map();
10070
10199
  graph.forEachEdge((id, attrs) => {
10071
10200
  const e = attrs;
10072
- const parsed = (0, import_types40.parseEdgeId)(id);
10201
+ const parsed = (0, import_types41.parseEdgeId)(id);
10073
10202
  const provenance = parsed?.provenance ?? e.provenance;
10074
10203
  const source = bucketSourceFor(graph, e);
10075
10204
  const key = bucketKey(source, e.target, e.type);
10076
10205
  const cur = buckets2.get(key) ?? { source, target: e.target, type: e.type };
10077
10206
  switch (provenance) {
10078
- case import_types40.Provenance.EXTRACTED:
10207
+ case import_types41.Provenance.EXTRACTED:
10079
10208
  cur.extracted = e;
10080
10209
  break;
10081
- case import_types40.Provenance.OBSERVED:
10210
+ case import_types41.Provenance.OBSERVED:
10082
10211
  cur.observed = e;
10083
10212
  break;
10084
- case import_types40.Provenance.INFERRED:
10213
+ case import_types41.Provenance.INFERRED:
10085
10214
  cur.inferred = e;
10086
10215
  break;
10087
10216
  default:
10088
- if (e.provenance === import_types40.Provenance.STALE) cur.stale = e;
10217
+ if (e.provenance === import_types41.Provenance.STALE) cur.stale = e;
10089
10218
  }
10090
10219
  buckets2.set(key, cur);
10091
10220
  });
@@ -10094,17 +10223,17 @@ function bucketEdges(graph) {
10094
10223
  function nodeIsFrontier(graph, nodeId) {
10095
10224
  if (!graph.hasNode(nodeId)) return false;
10096
10225
  const attrs = graph.getNodeAttributes(nodeId);
10097
- return attrs.type === import_types40.NodeType.FrontierNode;
10226
+ return attrs.type === import_types41.NodeType.FrontierNode;
10098
10227
  }
10099
10228
  function nodeIsWebsocketChannel(graph, nodeId) {
10100
10229
  if (!graph.hasNode(nodeId)) return false;
10101
10230
  const attrs = graph.getNodeAttributes(nodeId);
10102
- return attrs.type === import_types40.NodeType.WebSocketChannelNode;
10231
+ return attrs.type === import_types41.NodeType.WebSocketChannelNode;
10103
10232
  }
10104
10233
  function nodeIsSymbol(graph, nodeId) {
10105
10234
  if (!graph.hasNode(nodeId)) return false;
10106
10235
  const attrs = graph.getNodeAttributes(nodeId);
10107
- return attrs.type === import_types40.NodeType.SymbolNode;
10236
+ return attrs.type === import_types41.NodeType.SymbolNode;
10108
10237
  }
10109
10238
  function clampConfidence(n) {
10110
10239
  if (!Number.isFinite(n)) return 0;
@@ -10124,14 +10253,14 @@ function gradedConfidence(edge) {
10124
10253
  return clampConfidence(confidenceForEdge(edge));
10125
10254
  }
10126
10255
  var OBSERVABLE_EDGE_TYPES = /* @__PURE__ */ new Set([
10127
- import_types40.EdgeType.CALLS,
10128
- import_types40.EdgeType.CONNECTS_TO,
10129
- import_types40.EdgeType.PUBLISHES_TO,
10130
- import_types40.EdgeType.CONSUMES_FROM
10256
+ import_types41.EdgeType.CALLS,
10257
+ import_types41.EdgeType.CONNECTS_TO,
10258
+ import_types41.EdgeType.PUBLISHES_TO,
10259
+ import_types41.EdgeType.CONSUMES_FROM
10131
10260
  ]);
10132
10261
  function detectMissingDivergences(graph, bucket) {
10133
10262
  const out = [];
10134
- if (bucket.type === import_types40.EdgeType.CONTAINS) return out;
10263
+ if (bucket.type === import_types41.EdgeType.CONTAINS) return out;
10135
10264
  if (nodeIsSymbol(graph, bucket.source) || nodeIsSymbol(graph, bucket.target)) return out;
10136
10265
  if (bucket.extracted && !bucket.observed && OBSERVABLE_EDGE_TYPES.has(bucket.type)) {
10137
10266
  if (!nodeIsFrontier(graph, bucket.target)) {
@@ -10173,7 +10302,7 @@ function declaredHostFor(svc) {
10173
10302
  function hasExtractedConfiguredBy(graph, svcId) {
10174
10303
  for (const edgeId of graph.outboundEdges(svcId)) {
10175
10304
  const e = graph.getEdgeAttributes(edgeId);
10176
- if (e.type === import_types40.EdgeType.CONFIGURED_BY && e.provenance === import_types40.Provenance.EXTRACTED) {
10305
+ if (e.type === import_types41.EdgeType.CONFIGURED_BY && e.provenance === import_types41.Provenance.EXTRACTED) {
10177
10306
  return true;
10178
10307
  }
10179
10308
  }
@@ -10186,10 +10315,10 @@ function detectHostMismatch(graph, svcId, svc) {
10186
10315
  const out = [];
10187
10316
  for (const edgeId of graph.outboundEdges(svcId)) {
10188
10317
  const edge = graph.getEdgeAttributes(edgeId);
10189
- if (edge.type !== import_types40.EdgeType.CONNECTS_TO) continue;
10190
- if (edge.provenance !== import_types40.Provenance.OBSERVED) continue;
10318
+ if (edge.type !== import_types41.EdgeType.CONNECTS_TO) continue;
10319
+ if (edge.provenance !== import_types41.Provenance.OBSERVED) continue;
10191
10320
  const target = graph.getNodeAttributes(edge.target);
10192
- if (target.type !== import_types40.NodeType.DatabaseNode) continue;
10321
+ if (target.type !== import_types41.NodeType.DatabaseNode) continue;
10193
10322
  const observedHost = target.host?.trim();
10194
10323
  if (!observedHost) continue;
10195
10324
  if (observedHost === declaredHost) continue;
@@ -10211,10 +10340,10 @@ function detectCompatDivergences(graph, svcId, svc) {
10211
10340
  const deps = svc.dependencies ?? {};
10212
10341
  for (const edgeId of graph.outboundEdges(svcId)) {
10213
10342
  const edge = graph.getEdgeAttributes(edgeId);
10214
- if (edge.type !== import_types40.EdgeType.CONNECTS_TO) continue;
10215
- if (edge.provenance !== import_types40.Provenance.OBSERVED) continue;
10343
+ if (edge.type !== import_types41.EdgeType.CONNECTS_TO) continue;
10344
+ if (edge.provenance !== import_types41.Provenance.OBSERVED) continue;
10216
10345
  const target = graph.getNodeAttributes(edge.target);
10217
- if (target.type !== import_types40.NodeType.DatabaseNode) continue;
10346
+ if (target.type !== import_types41.NodeType.DatabaseNode) continue;
10218
10347
  for (const pair of compatPairs()) {
10219
10348
  if (pair.engine !== target.engine) continue;
10220
10349
  const declared = deps[pair.driver];
@@ -10311,7 +10440,7 @@ function suppressHostMismatchHalves(all) {
10311
10440
  for (const d of all) {
10312
10441
  if (d.type !== "host-mismatch") continue;
10313
10442
  observedHalf.add(`${d.source}->${d.target}`);
10314
- declaredHalf.add((0, import_types40.databaseId)(d.extractedHost));
10443
+ declaredHalf.add((0, import_types41.databaseId)(d.extractedHost));
10315
10444
  }
10316
10445
  if (observedHalf.size === 0) return all;
10317
10446
  return all.filter((d) => {
@@ -10330,13 +10459,13 @@ function computeDivergences(graph, opts = {}) {
10330
10459
  }
10331
10460
  graph.forEachNode((nodeId, attrs) => {
10332
10461
  const n = attrs;
10333
- if (n.type === import_types40.NodeType.ServiceNode) {
10462
+ if (n.type === import_types41.NodeType.ServiceNode) {
10334
10463
  const svc = n;
10335
10464
  for (const d of detectHostMismatch(graph, nodeId, svc)) all.push(d);
10336
10465
  for (const d of detectCompatDivergences(graph, nodeId, svc)) all.push(d);
10337
10466
  return;
10338
10467
  }
10339
- if (n.type === import_types40.NodeType.InfraNode && n.kind === "sql-table") {
10468
+ if (n.type === import_types41.NodeType.InfraNode && n.kind === "sql-table") {
10340
10469
  for (const d of detectColumnDrift(n)) all.push(d);
10341
10470
  }
10342
10471
  });
@@ -10372,7 +10501,7 @@ function computeDivergences(graph, opts = {}) {
10372
10501
  const bc = "column" in b && b.column ? b.column : "";
10373
10502
  return ac.localeCompare(bc);
10374
10503
  });
10375
- return import_types40.DivergenceResultSchema.parse({
10504
+ return import_types41.DivergenceResultSchema.parse({
10376
10505
  divergences: filtered,
10377
10506
  totalAffected: filtered.length,
10378
10507
  computedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -10505,26 +10634,26 @@ function canonicalJson(value) {
10505
10634
  init_cjs_shims();
10506
10635
  var import_node_fs29 = require("fs");
10507
10636
  var import_node_os3 = __toESM(require("os"), 1);
10508
- var import_node_path55 = __toESM(require("path"), 1);
10509
- var import_types41 = require("@neat.is/types");
10637
+ var import_node_path56 = __toESM(require("path"), 1);
10638
+ var import_types42 = require("@neat.is/types");
10510
10639
  var LOCK_TIMEOUT_MS = 5e3;
10511
10640
  var LOCK_RETRY_MS = 50;
10512
10641
  function neatHome() {
10513
10642
  const override = process.env.NEAT_HOME;
10514
- if (override && override.length > 0) return import_node_path55.default.resolve(override);
10515
- return import_node_path55.default.join(import_node_os3.default.homedir(), ".neat");
10643
+ if (override && override.length > 0) return import_node_path56.default.resolve(override);
10644
+ return import_node_path56.default.join(import_node_os3.default.homedir(), ".neat");
10516
10645
  }
10517
10646
  function registryPath() {
10518
- return import_node_path55.default.join(neatHome(), "projects.json");
10647
+ return import_node_path56.default.join(neatHome(), "projects.json");
10519
10648
  }
10520
10649
  function registryLockPath() {
10521
- return import_node_path55.default.join(neatHome(), "projects.json.lock");
10650
+ return import_node_path56.default.join(neatHome(), "projects.json.lock");
10522
10651
  }
10523
10652
  function daemonPidPath() {
10524
- return import_node_path55.default.join(neatHome(), "neatd.pid");
10653
+ return import_node_path56.default.join(neatHome(), "neatd.pid");
10525
10654
  }
10526
10655
  function daemonsDir() {
10527
- return import_node_path55.default.join(neatHome(), "daemons");
10656
+ return import_node_path56.default.join(neatHome(), "daemons");
10528
10657
  }
10529
10658
  function isFiniteInt(v) {
10530
10659
  return typeof v === "number" && Number.isFinite(v);
@@ -10565,7 +10694,7 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
10565
10694
  const out = [];
10566
10695
  for (const name of names) {
10567
10696
  if (!name.endsWith(".json")) continue;
10568
- const file = import_node_path55.default.join(dir, name);
10697
+ const file = import_node_path56.default.join(dir, name);
10569
10698
  let raw;
10570
10699
  try {
10571
10700
  raw = await import_node_fs29.promises.readFile(file, "utf8");
@@ -10642,7 +10771,7 @@ function lockHolderMessage(holder, lockPath, timeoutMs) {
10642
10771
  }
10643
10772
  }
10644
10773
  async function writeAtomically(target, contents) {
10645
- await import_node_fs29.promises.mkdir(import_node_path55.default.dirname(target), { recursive: true });
10774
+ await import_node_fs29.promises.mkdir(import_node_path56.default.dirname(target), { recursive: true });
10646
10775
  const tmp = `${target}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
10647
10776
  const fd = await import_node_fs29.promises.open(tmp, "w");
10648
10777
  try {
@@ -10655,7 +10784,7 @@ async function writeAtomically(target, contents) {
10655
10784
  }
10656
10785
  async function acquireLock(lockPath, timeoutMs = LOCK_TIMEOUT_MS, probe = defaultLockHolderProbe) {
10657
10786
  const deadline = Date.now() + timeoutMs;
10658
- await import_node_fs29.promises.mkdir(import_node_path55.default.dirname(lockPath), { recursive: true });
10787
+ await import_node_fs29.promises.mkdir(import_node_path56.default.dirname(lockPath), { recursive: true });
10659
10788
  let probedHolder = false;
10660
10789
  while (true) {
10661
10790
  try {
@@ -10708,10 +10837,10 @@ async function readRegistry() {
10708
10837
  throw err;
10709
10838
  }
10710
10839
  const parsed = JSON.parse(raw);
10711
- return import_types41.RegistryFileSchema.parse(parsed);
10840
+ return import_types42.RegistryFileSchema.parse(parsed);
10712
10841
  }
10713
10842
  async function writeRegistry(reg) {
10714
- const validated = import_types41.RegistryFileSchema.parse(reg);
10843
+ const validated = import_types42.RegistryFileSchema.parse(reg);
10715
10844
  await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
10716
10845
  }
10717
10846
  async function getProject(name) {
@@ -10856,7 +10985,7 @@ init_auth();
10856
10985
  // src/connectors-config.ts
10857
10986
  init_cjs_shims();
10858
10987
  var import_node_os4 = __toESM(require("os"), 1);
10859
- var import_node_path56 = __toESM(require("path"), 1);
10988
+ var import_node_path57 = __toESM(require("path"), 1);
10860
10989
  var import_node_fs30 = require("fs");
10861
10990
  var CONNECTORS_CONFIG_VERSION = 1;
10862
10991
  var EnvRefUnsetError = class extends Error {
@@ -10871,11 +11000,11 @@ var EnvRefUnsetError = class extends Error {
10871
11000
  };
10872
11001
  function neatHome2() {
10873
11002
  const override = process.env.NEAT_HOME;
10874
- if (override && override.length > 0) return import_node_path56.default.resolve(override);
10875
- return import_node_path56.default.join(import_node_os4.default.homedir(), ".neat");
11003
+ if (override && override.length > 0) return import_node_path57.default.resolve(override);
11004
+ return import_node_path57.default.join(import_node_os4.default.homedir(), ".neat");
10876
11005
  }
10877
11006
  function connectorsConfigPath(home = neatHome2()) {
10878
- return import_node_path56.default.join(home, "connectors.json");
11007
+ return import_node_path57.default.join(home, "connectors.json");
10879
11008
  }
10880
11009
  var MODE_MASK_LOOSER_THAN_0600 = 63;
10881
11010
  async function warnIfModeLooserThan0600(file) {
@@ -11062,15 +11191,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
11062
11191
 
11063
11192
  // src/connectors/index.ts
11064
11193
  init_cjs_shims();
11065
- var import_types42 = require("@neat.is/types");
11194
+ var import_types43 = require("@neat.is/types");
11066
11195
  var NO_ENV = "unknown";
11067
11196
  function staticCallSiteFor(graph, serviceName, targetNodeId) {
11068
11197
  if (!graph.hasNode(targetNodeId)) return void 0;
11069
11198
  const sites = [];
11070
11199
  for (const edgeId of graph.inboundEdges(targetNodeId)) {
11071
11200
  const edge = graph.getEdgeAttributes(edgeId);
11072
- if (edge.provenance !== import_types42.Provenance.EXTRACTED) continue;
11073
- const parsed = (0, import_types42.parseFileId)(edge.source);
11201
+ if (edge.provenance !== import_types43.Provenance.EXTRACTED) continue;
11202
+ const parsed = (0, import_types43.parseFileId)(edge.source);
11074
11203
  if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
11075
11204
  const site = { relPath: edge.evidence.file };
11076
11205
  if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
@@ -11081,7 +11210,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
11081
11210
  function routeCallSiteFor(graph, targetNodeId) {
11082
11211
  if (!graph.hasNode(targetNodeId)) return void 0;
11083
11212
  const attrs = graph.getNodeAttributes(targetNodeId);
11084
- if (attrs.type !== import_types42.NodeType.RouteNode || !attrs.path) return void 0;
11213
+ if (attrs.type !== import_types43.NodeType.RouteNode || !attrs.path) return void 0;
11085
11214
  const site = { relPath: attrs.path };
11086
11215
  if (attrs.line !== void 0) site.line = attrs.line;
11087
11216
  return site;
@@ -11558,10 +11687,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
11558
11687
  // src/connectors/supabase/map.ts
11559
11688
  var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
11560
11689
  var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
11561
- function targetFromRestPath(path61) {
11562
- const rpcMatch = REST_RPC_PATH_RE.exec(path61);
11690
+ function targetFromRestPath(path62) {
11691
+ const rpcMatch = REST_RPC_PATH_RE.exec(path62);
11563
11692
  if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
11564
- const tableMatch = REST_TABLE_PATH_RE.exec(path61);
11693
+ const tableMatch = REST_TABLE_PATH_RE.exec(path62);
11565
11694
  if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
11566
11695
  return null;
11567
11696
  }
@@ -11672,23 +11801,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
11672
11801
 
11673
11802
  // src/connectors/supabase/resolve.ts
11674
11803
  init_cjs_shims();
11675
- var import_types44 = require("@neat.is/types");
11804
+ var import_types45 = require("@neat.is/types");
11676
11805
  function createSupabaseResolveTarget(graph, config) {
11677
11806
  return (signal, _ctx) => {
11678
11807
  if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
11679
11808
  return null;
11680
11809
  }
11681
- const subResourceId = (0, import_types44.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
11810
+ const subResourceId = (0, import_types45.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
11682
11811
  if (graph.hasNode(subResourceId)) {
11683
- return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types44.EdgeType.CALLS };
11812
+ return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types45.EdgeType.CALLS };
11684
11813
  }
11685
- const bareResourceId = (0, import_types44.infraId)(signal.targetKind, signal.targetName);
11814
+ const bareResourceId = (0, import_types45.infraId)(signal.targetKind, signal.targetName);
11686
11815
  if (graph.hasNode(bareResourceId)) {
11687
- return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types44.EdgeType.CALLS };
11816
+ return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types45.EdgeType.CALLS };
11688
11817
  }
11689
- const projectLevelId = (0, import_types44.infraId)("supabase", config.nodeRef);
11818
+ const projectLevelId = (0, import_types45.infraId)("supabase", config.nodeRef);
11690
11819
  if (graph.hasNode(projectLevelId)) {
11691
- return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types44.EdgeType.CALLS };
11820
+ return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types45.EdgeType.CALLS };
11692
11821
  }
11693
11822
  return null;
11694
11823
  };
@@ -11781,7 +11910,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
11781
11910
 
11782
11911
  // src/connectors/railway/index.ts
11783
11912
  init_cjs_shims();
11784
- var import_types48 = require("@neat.is/types");
11913
+ var import_types49 = require("@neat.is/types");
11785
11914
 
11786
11915
  // src/connectors/railway/client.ts
11787
11916
  init_cjs_shims();
@@ -11932,7 +12061,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
11932
12061
  const out = [];
11933
12062
  graph.forEachNode((_id, attrs) => {
11934
12063
  const node = attrs;
11935
- if (node.type !== import_types48.NodeType.RouteNode) return;
12064
+ if (node.type !== import_types49.NodeType.RouteNode) return;
11936
12065
  const route = attrs;
11937
12066
  if (route.service !== serviceName) return;
11938
12067
  out.push({
@@ -12036,12 +12165,12 @@ function createRailwayResolveTarget(config) {
12036
12165
  const serviceName = config.serviceNameById[config.serviceId];
12037
12166
  if (!serviceName) return null;
12038
12167
  if (signal.targetKind === ROUTE_TARGET_KIND) {
12039
- return { targetNodeId: signal.targetName, serviceName, edgeType: import_types48.EdgeType.CALLS };
12168
+ return { targetNodeId: signal.targetName, serviceName, edgeType: import_types49.EdgeType.CALLS };
12040
12169
  }
12041
12170
  if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
12042
12171
  const peerName = config.serviceNameById[signal.targetName];
12043
12172
  if (!peerName) return null;
12044
- return { targetNodeId: (0, import_types48.serviceId)(peerName), serviceName, edgeType: import_types48.EdgeType.CONNECTS_TO };
12173
+ return { targetNodeId: (0, import_types49.serviceId)(peerName), serviceName, edgeType: import_types49.EdgeType.CONNECTS_TO };
12045
12174
  }
12046
12175
  return null;
12047
12176
  };
@@ -12165,9 +12294,9 @@ function parseFirebaseTargetName(targetName) {
12165
12294
  const secondSep = rest.indexOf(FIELD_SEP);
12166
12295
  if (secondSep === -1) return null;
12167
12296
  const method = rest.slice(0, secondSep);
12168
- const path61 = rest.slice(secondSep + 1);
12169
- if (!resourceName || !method || !path61) return null;
12170
- return { resourceName, method, path: path61 };
12297
+ const path62 = rest.slice(secondSep + 1);
12298
+ if (!resourceName || !method || !path62) return null;
12299
+ return { resourceName, method, path: path62 };
12171
12300
  }
12172
12301
  function resourceNameFor(type, labels) {
12173
12302
  if (!labels) return null;
@@ -12205,14 +12334,14 @@ function mapLogEntryToSignal(entry2) {
12205
12334
  if (!req2) return null;
12206
12335
  if (typeof req2.requestMethod !== "string" || req2.requestMethod.length === 0) return null;
12207
12336
  const method = req2.requestMethod.toUpperCase();
12208
- const path61 = pathFromRequestUrl(req2.requestUrl);
12209
- if (path61 === null) return null;
12337
+ const path62 = pathFromRequestUrl(req2.requestUrl);
12338
+ if (path62 === null) return null;
12210
12339
  const timestamp = entry2.timestamp;
12211
12340
  if (typeof timestamp !== "string" || timestamp.length === 0) return null;
12212
12341
  const isError = typeof req2.status === "number" && req2.status >= ERROR_STATUS_THRESHOLD2;
12213
12342
  return {
12214
12343
  targetKind: resourceType,
12215
- targetName: packFirebaseTargetName({ resourceName, method, path: path61 }),
12344
+ targetName: packFirebaseTargetName({ resourceName, method, path: path62 }),
12216
12345
  callCount: 1,
12217
12346
  errorCount: isError ? 1 : 0,
12218
12347
  lastObservedIso: timestamp
@@ -12229,7 +12358,7 @@ function mapLogEntriesToSignals(entries) {
12229
12358
 
12230
12359
  // src/connectors/firebase/resolve.ts
12231
12360
  init_cjs_shims();
12232
- var import_types49 = require("@neat.is/types");
12361
+ var import_types50 = require("@neat.is/types");
12233
12362
  function neatServiceNameFor(resourceType, resourceName, serviceMap) {
12234
12363
  switch (resourceType) {
12235
12364
  case "cloud_function":
@@ -12244,7 +12373,7 @@ function routeEntriesFor(graph, serviceName) {
12244
12373
  const entries = [];
12245
12374
  graph.forEachNode((_id, attrs) => {
12246
12375
  const node = attrs;
12247
- if (node.type !== import_types49.NodeType.RouteNode) return;
12376
+ if (node.type !== import_types50.NodeType.RouteNode) return;
12248
12377
  const route = attrs;
12249
12378
  if (route.service !== serviceName) return;
12250
12379
  entries.push({
@@ -12276,7 +12405,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
12276
12405
  return {
12277
12406
  targetNodeId: match.routeNodeId,
12278
12407
  serviceName,
12279
- edgeType: import_types49.EdgeType.CALLS
12408
+ edgeType: import_types50.EdgeType.CALLS
12280
12409
  };
12281
12410
  };
12282
12411
  }
@@ -12303,7 +12432,7 @@ init_cjs_shims();
12303
12432
 
12304
12433
  // src/connectors/cloudflare/connector.ts
12305
12434
  init_cjs_shims();
12306
- var import_types51 = require("@neat.is/types");
12435
+ var import_types52 = require("@neat.is/types");
12307
12436
 
12308
12437
  // src/connectors/cloudflare/client.ts
12309
12438
  init_cjs_shims();
@@ -12419,7 +12548,7 @@ function mapEventToSignal(event) {
12419
12548
  if (Number.isNaN(observedAt.getTime())) return null;
12420
12549
  const statusCode = metadata?.statusCode;
12421
12550
  const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
12422
- const path61 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
12551
+ const path62 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
12423
12552
  return {
12424
12553
  targetKind: CLOUDFLARE_TARGET_KIND,
12425
12554
  targetName: scriptName,
@@ -12427,7 +12556,7 @@ function mapEventToSignal(event) {
12427
12556
  errorCount: isError ? 1 : 0,
12428
12557
  lastObservedIso: observedAt.toISOString(),
12429
12558
  method,
12430
- ...path61 ? { path: path61 } : {},
12559
+ ...path62 ? { path: path62 } : {},
12431
12560
  ...typeof statusCode === "number" ? { statusCode } : {},
12432
12561
  ...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
12433
12562
  };
@@ -12467,19 +12596,19 @@ function findTaggedWorkerFileNode(graph, workerName) {
12467
12596
  graph.forEachNode((id, attrs) => {
12468
12597
  if (found) return;
12469
12598
  const a = attrs;
12470
- if (a.type === import_types51.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
12599
+ if (a.type === import_types52.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
12471
12600
  found = id;
12472
12601
  }
12473
12602
  });
12474
12603
  return found;
12475
12604
  }
12476
- function findMatchingRouteNode(graph, serviceName, method, path61) {
12477
- const normalizedPath = normalizePathTemplate(path61);
12605
+ function findMatchingRouteNode(graph, serviceName, method, path62) {
12606
+ const normalizedPath = normalizePathTemplate(path62);
12478
12607
  let found = null;
12479
12608
  graph.forEachNode((id, attrs) => {
12480
12609
  if (found) return;
12481
12610
  const a = attrs;
12482
- if (a.type !== import_types51.NodeType.RouteNode || a.service !== serviceName) return;
12611
+ if (a.type !== import_types52.NodeType.RouteNode || a.service !== serviceName) return;
12483
12612
  if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
12484
12613
  const routeMethod = (a.method ?? "").toUpperCase();
12485
12614
  if (routeMethod !== "ALL" && routeMethod !== method) return;
@@ -12491,18 +12620,18 @@ function createCloudflareResolveTarget(config, graph) {
12491
12620
  return (signal) => {
12492
12621
  if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
12493
12622
  const scriptName = signal.targetName;
12494
- const { method, path: path61 } = signal;
12623
+ const { method, path: path62 } = signal;
12495
12624
  const resolveRouteGrain = (serviceName, wholeFileId) => {
12496
- if (!method || !path61) return wholeFileId;
12497
- return findMatchingRouteNode(graph, serviceName, method, path61) ?? wholeFileId;
12625
+ if (!method || !path62) return wholeFileId;
12626
+ return findMatchingRouteNode(graph, serviceName, method, path62) ?? wholeFileId;
12498
12627
  };
12499
12628
  const mapping = config.workers?.[scriptName];
12500
12629
  if (mapping) {
12501
- const wholeFileId = (0, import_types51.fileId)(mapping.service, mapping.entryFile);
12630
+ const wholeFileId = (0, import_types52.fileId)(mapping.service, mapping.entryFile);
12502
12631
  return {
12503
12632
  targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
12504
12633
  serviceName: mapping.service,
12505
- edgeType: import_types51.EdgeType.CALLS
12634
+ edgeType: import_types52.EdgeType.CALLS
12506
12635
  };
12507
12636
  }
12508
12637
  const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
@@ -12511,13 +12640,13 @@ function createCloudflareResolveTarget(config, graph) {
12511
12640
  return {
12512
12641
  targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
12513
12642
  serviceName: fileNode.service,
12514
- edgeType: import_types51.EdgeType.CALLS
12643
+ edgeType: import_types52.EdgeType.CALLS
12515
12644
  };
12516
12645
  }
12517
12646
  return {
12518
- targetNodeId: (0, import_types51.infraId)("cloudflare-worker", scriptName),
12647
+ targetNodeId: (0, import_types52.infraId)("cloudflare-worker", scriptName),
12519
12648
  serviceName: scriptName,
12520
- edgeType: import_types51.EdgeType.CALLS,
12649
+ edgeType: import_types52.EdgeType.CALLS,
12521
12650
  ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
12522
12651
  };
12523
12652
  };
@@ -12713,14 +12842,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
12713
12842
 
12714
12843
  // src/connectors/neon/resolve.ts
12715
12844
  init_cjs_shims();
12716
- var import_types55 = require("@neat.is/types");
12845
+ var import_types56 = require("@neat.is/types");
12717
12846
  function createNeonResolveTarget(config) {
12718
12847
  return (signal) => {
12719
12848
  if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
12720
12849
  return {
12721
- targetNodeId: (0, import_types55.infraId)("sql-table", signal.targetName),
12850
+ targetNodeId: (0, import_types56.infraId)("sql-table", signal.targetName),
12722
12851
  serviceName: config.serviceName,
12723
- edgeType: import_types55.EdgeType.CALLS,
12852
+ edgeType: import_types56.EdgeType.CALLS,
12724
12853
  ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
12725
12854
  };
12726
12855
  };
@@ -13284,11 +13413,11 @@ function registerRoutes(scope, ctx) {
13284
13413
  const candidates = req2.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
13285
13414
  const parsed = [];
13286
13415
  for (const c of candidates) {
13287
- const r = import_types58.DivergenceTypeSchema.safeParse(c);
13416
+ const r = import_types59.DivergenceTypeSchema.safeParse(c);
13288
13417
  if (!r.success) {
13289
13418
  return reply.code(400).send({
13290
13419
  error: `unknown divergence type "${c}"`,
13291
- allowed: import_types58.DivergenceTypeSchema.options
13420
+ allowed: import_types59.DivergenceTypeSchema.options
13292
13421
  });
13293
13422
  }
13294
13423
  parsed.push(r.data);
@@ -13597,7 +13726,7 @@ function registerRoutes(scope, ctx) {
13597
13726
  const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
13598
13727
  let violations = await log.readAll();
13599
13728
  if (req2.query.severity) {
13600
- const sev = import_types58.PolicySeveritySchema.safeParse(req2.query.severity);
13729
+ const sev = import_types59.PolicySeveritySchema.safeParse(req2.query.severity);
13601
13730
  if (!sev.success) {
13602
13731
  return reply.code(400).send({
13603
13732
  error: "invalid severity",
@@ -13636,7 +13765,7 @@ function registerRoutes(scope, ctx) {
13636
13765
  scope.post("/policies/check", async (req2, reply) => {
13637
13766
  const proj = resolveProject(registry, req2, reply, ctx.bootstrap, ctx.singleProject);
13638
13767
  if (!proj) return;
13639
- const parsed = import_types58.PoliciesCheckBodySchema.safeParse(req2.body ?? {});
13768
+ const parsed = import_types59.PoliciesCheckBodySchema.safeParse(req2.body ?? {});
13640
13769
  if (!parsed.success) {
13641
13770
  return reply.code(400).send({
13642
13771
  error: "invalid /policies/check body",
@@ -13958,7 +14087,7 @@ init_auth();
13958
14087
  // src/unrouted.ts
13959
14088
  init_cjs_shims();
13960
14089
  var import_node_fs31 = require("fs");
13961
- var import_node_path57 = __toESM(require("path"), 1);
14090
+ var import_node_path58 = __toESM(require("path"), 1);
13962
14091
  function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new Date()) {
13963
14092
  return {
13964
14093
  timestamp: now.toISOString(),
@@ -13968,34 +14097,34 @@ function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new
13968
14097
  };
13969
14098
  }
13970
14099
  async function appendUnroutedSpan(neatHome4, record) {
13971
- const target = import_node_path57.default.join(neatHome4, "errors.ndjson");
14100
+ const target = import_node_path58.default.join(neatHome4, "errors.ndjson");
13972
14101
  await import_node_fs31.promises.mkdir(neatHome4, { recursive: true });
13973
14102
  await import_node_fs31.promises.appendFile(target, JSON.stringify(record) + "\n", "utf8");
13974
14103
  }
13975
14104
  function unroutedErrorsPath(neatHome4) {
13976
- return import_node_path57.default.join(neatHome4, "errors.ndjson");
14105
+ return import_node_path58.default.join(neatHome4, "errors.ndjson");
13977
14106
  }
13978
14107
 
13979
14108
  // src/daemon.ts
13980
- var import_types59 = require("@neat.is/types");
14109
+ var import_types60 = require("@neat.is/types");
13981
14110
  function daemonJsonPath(scanPath) {
13982
- return import_node_path58.default.join(scanPath, "neat-out", "daemon.json");
14111
+ return import_node_path59.default.join(scanPath, "neat-out", "daemon.json");
13983
14112
  }
13984
14113
  function daemonsDiscoveryDir(home) {
13985
14114
  const base = home && home.length > 0 ? home : neatHomeFromEnv();
13986
- return import_node_path58.default.join(base, "daemons");
14115
+ return import_node_path59.default.join(base, "daemons");
13987
14116
  }
13988
14117
  function daemonDiscoveryPath(project, home) {
13989
- return import_node_path58.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
14118
+ return import_node_path59.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
13990
14119
  }
13991
14120
  function sanitizeDiscoveryName(project) {
13992
14121
  return project.replace(/[^A-Za-z0-9._-]/g, "_");
13993
14122
  }
13994
14123
  function neatHomeFromEnv() {
13995
14124
  const env = process.env.NEAT_HOME;
13996
- if (env && env.length > 0) return import_node_path58.default.resolve(env);
14125
+ if (env && env.length > 0) return import_node_path59.default.resolve(env);
13997
14126
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
13998
- return import_node_path58.default.join(home, ".neat");
14127
+ return import_node_path59.default.join(home, ".neat");
13999
14128
  }
14000
14129
  function resolveNeatVersion() {
14001
14130
  if (process.env.NEAT_LOCAL_VERSION && process.env.NEAT_LOCAL_VERSION.length > 0) {
@@ -14064,11 +14193,11 @@ function teardownSlot(slot) {
14064
14193
  }
14065
14194
  }
14066
14195
  function neatHomeFor(opts) {
14067
- if (opts.neatHome && opts.neatHome.length > 0) return import_node_path58.default.resolve(opts.neatHome);
14196
+ if (opts.neatHome && opts.neatHome.length > 0) return import_node_path59.default.resolve(opts.neatHome);
14068
14197
  const env = process.env.NEAT_HOME;
14069
- if (env && env.length > 0) return import_node_path58.default.resolve(env);
14198
+ if (env && env.length > 0) return import_node_path59.default.resolve(env);
14070
14199
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
14071
- return import_node_path58.default.join(home, ".neat");
14200
+ return import_node_path59.default.join(home, ".neat");
14072
14201
  }
14073
14202
  function routeSpanToProject(serviceName, projects) {
14074
14203
  if (!serviceName) return DEFAULT_PROJECT;
@@ -14116,11 +14245,11 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
14116
14245
  if (!serviceName) return true;
14117
14246
  if (serviceNameMatchesProject(serviceName, project)) return true;
14118
14247
  return graph.someNode(
14119
- (_id, attrs) => attrs.type === import_types59.NodeType.ServiceNode && attrs.name === serviceName
14248
+ (_id, attrs) => attrs.type === import_types60.NodeType.ServiceNode && attrs.name === serviceName
14120
14249
  );
14121
14250
  }
14122
14251
  async function bootstrapProject(entry2, connectors = [], neatHome4) {
14123
- const paths = pathsForProject(entry2.name, import_node_path58.default.join(entry2.path, "neat-out"));
14252
+ const paths = pathsForProject(entry2.name, import_node_path59.default.join(entry2.path, "neat-out"));
14124
14253
  try {
14125
14254
  const stat = await import_node_fs32.promises.stat(entry2.path);
14126
14255
  if (!stat.isDirectory()) {
@@ -14236,7 +14365,7 @@ async function startDaemon(opts = {}) {
14236
14365
  const projectArg = typeof opts.project === "string" && opts.project.length > 0 ? opts.project : process.env.NEAT_PROJECT && process.env.NEAT_PROJECT.length > 0 ? process.env.NEAT_PROJECT : null;
14237
14366
  const projectPathArg = opts.projectPath && opts.projectPath.length > 0 ? opts.projectPath : process.env.NEAT_PROJECT_PATH && process.env.NEAT_PROJECT_PATH.length > 0 ? process.env.NEAT_PROJECT_PATH : null;
14238
14367
  const singleProject = projectArg;
14239
- const singleProjectPath = singleProject && projectPathArg ? import_node_path58.default.resolve(projectPathArg) : null;
14368
+ const singleProjectPath = singleProject && projectPathArg ? import_node_path59.default.resolve(projectPathArg) : null;
14240
14369
  if (singleProject && !singleProjectPath) {
14241
14370
  throw new Error(
14242
14371
  `neatd: project "${singleProject}" given without a projectPath; pass NEAT_PROJECT_PATH alongside NEAT_PROJECT.`
@@ -14251,7 +14380,7 @@ async function startDaemon(opts = {}) {
14251
14380
  );
14252
14381
  }
14253
14382
  }
14254
- const pidPath = import_node_path58.default.join(home, "neatd.pid");
14383
+ const pidPath = import_node_path59.default.join(home, "neatd.pid");
14255
14384
  await writeAtomically(pidPath, `${process.pid}
14256
14385
  `);
14257
14386
  const slots = /* @__PURE__ */ new Map();
@@ -14663,8 +14792,8 @@ async function startDaemon(opts = {}) {
14663
14792
  let registryWatcher = null;
14664
14793
  let reloadTimer = null;
14665
14794
  if (!singleProject) try {
14666
- const regDir = import_node_path58.default.dirname(regPath);
14667
- const regBase = import_node_path58.default.basename(regPath);
14795
+ const regDir = import_node_path59.default.dirname(regPath);
14796
+ const regBase = import_node_path59.default.basename(regPath);
14668
14797
  registryWatcher = (0, import_node_fs32.watch)(regDir, (_eventType, filename) => {
14669
14798
  if (filename !== null && filename !== regBase) return;
14670
14799
  if (reloadTimer) clearTimeout(reloadTimer);
@@ -14739,7 +14868,7 @@ init_cjs_shims();
14739
14868
  var import_node_child_process2 = require("child_process");
14740
14869
  var import_node_fs33 = require("fs");
14741
14870
  var import_node_net = __toESM(require("net"), 1);
14742
- var import_node_path59 = __toESM(require("path"), 1);
14871
+ var import_node_path60 = __toESM(require("path"), 1);
14743
14872
  var DEFAULT_WEB_PORT = 6328;
14744
14873
  var DEFAULT_REST_PORT = 8080;
14745
14874
  function asValidPort(value) {
@@ -14748,11 +14877,11 @@ function asValidPort(value) {
14748
14877
  }
14749
14878
  function projectRoot() {
14750
14879
  const fromEnv = process.env.NEAT_SCAN_PATH;
14751
- return import_node_path59.default.resolve(fromEnv && fromEnv.length > 0 ? fromEnv : process.cwd());
14880
+ return import_node_path60.default.resolve(fromEnv && fromEnv.length > 0 ? fromEnv : process.cwd());
14752
14881
  }
14753
14882
  async function readDaemonPorts(root) {
14754
14883
  try {
14755
- const raw = await import_node_fs33.promises.readFile(import_node_path59.default.join(root, "neat-out", "daemon.json"), "utf8");
14884
+ const raw = await import_node_fs33.promises.readFile(import_node_path60.default.join(root, "neat-out", "daemon.json"), "utf8");
14756
14885
  const parsed = JSON.parse(raw);
14757
14886
  const ports = parsed?.ports ?? {};
14758
14887
  return { web: asValidPort(ports.web), rest: asValidPort(ports.rest) };
@@ -14797,10 +14926,10 @@ function resolveWebPackageDir() {
14797
14926
  eval("require")
14798
14927
  );
14799
14928
  const pkgJsonPath = req.resolve("@neat.is/web/package.json");
14800
- return import_node_path59.default.dirname(pkgJsonPath);
14929
+ return import_node_path60.default.dirname(pkgJsonPath);
14801
14930
  }
14802
14931
  function resolveStandaloneServerEntry(webDir) {
14803
- return import_node_path59.default.join(webDir, ".next/standalone/packages/web/server.js");
14932
+ return import_node_path60.default.join(webDir, ".next/standalone/packages/web/server.js");
14804
14933
  }
14805
14934
  async function pickInternalPort() {
14806
14935
  return new Promise((resolve, reject) => {
@@ -14853,7 +14982,7 @@ async function spawnWebUI(restPort, opts = {}) {
14853
14982
  NEAT_API_URL: apiUrl
14854
14983
  };
14855
14984
  child = (0, import_node_child_process2.spawn)(process.execPath, [serverEntry], {
14856
- cwd: import_node_path59.default.dirname(serverEntry),
14985
+ cwd: import_node_path60.default.dirname(serverEntry),
14857
14986
  env,
14858
14987
  stdio: ["ignore", "inherit", "inherit"],
14859
14988
  detached: false
@@ -15029,14 +15158,14 @@ function localVersion() {
15029
15158
  }
15030
15159
  function neatHome3() {
15031
15160
  if (process.env.NEAT_HOME && process.env.NEAT_HOME.length > 0) {
15032
- return import_node_path60.default.resolve(process.env.NEAT_HOME);
15161
+ return import_node_path61.default.resolve(process.env.NEAT_HOME);
15033
15162
  }
15034
15163
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
15035
- return import_node_path60.default.join(home, ".neat");
15164
+ return import_node_path61.default.join(home, ".neat");
15036
15165
  }
15037
15166
  async function readPid() {
15038
15167
  try {
15039
- const raw = await import_node_fs34.promises.readFile(import_node_path60.default.join(neatHome3(), "neatd.pid"), "utf8");
15168
+ const raw = await import_node_fs34.promises.readFile(import_node_path61.default.join(neatHome3(), "neatd.pid"), "utf8");
15040
15169
  const n = Number.parseInt(raw.trim(), 10);
15041
15170
  return Number.isFinite(n) ? n : null;
15042
15171
  } catch {