@neat.is/core 0.4.28-dev.20260708 → 0.4.28-dev.20260709

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -61,8 +61,8 @@ function mountBearerAuth(app, opts) {
61
61
  ]);
62
62
  const publicRead = opts.publicRead === true;
63
63
  app.addHook("preHandler", (req, reply, done) => {
64
- const path57 = (req.url.split("?")[0] ?? "").replace(/\/+$/, "");
65
- if (exactUnauthPaths.has(path57) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path57)) {
64
+ const path58 = (req.url.split("?")[0] ?? "").replace(/\/+$/, "");
65
+ if (exactUnauthPaths.has(path58) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path58)) {
66
66
  done();
67
67
  return;
68
68
  }
@@ -194,8 +194,8 @@ function reshapeGrpcRequest(req) {
194
194
  };
195
195
  }
196
196
  function resolveProtoRoot() {
197
- const here = import_node_path44.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
198
- return import_node_path44.default.resolve(here, "..", "proto");
197
+ const here = import_node_path45.default.dirname((0, import_node_url2.fileURLToPath)(importMetaUrl));
198
+ return import_node_path45.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_url2, import_node_path44, import_node_crypto2, grpc, protoLoader;
266
+ var import_node_url2, import_node_path45, 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_url2 = require("url");
272
- import_node_path44 = __toESM(require("path"), 1);
272
+ import_node_path45 = __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);
@@ -362,8 +362,8 @@ function websocketChannelPathOf(attrs) {
362
362
  const v = attrs[key];
363
363
  if (typeof v === "string" && v.length > 0) {
364
364
  const q = v.indexOf("?");
365
- const path57 = q === -1 ? v : v.slice(0, q);
366
- if (path57.length > 0) return path57;
365
+ const path58 = q === -1 ? v : v.slice(0, q);
366
+ if (path58.length > 0) return path58;
367
367
  }
368
368
  }
369
369
  return void 0;
@@ -417,10 +417,10 @@ function parseOtlpRequest(body) {
417
417
  return out;
418
418
  }
419
419
  function loadProtoRoot() {
420
- const here = import_node_path45.default.dirname((0, import_node_url3.fileURLToPath)(importMetaUrl));
421
- const protoRoot = import_node_path45.default.resolve(here, "..", "proto");
420
+ const here = import_node_path46.default.dirname((0, import_node_url3.fileURLToPath)(importMetaUrl));
421
+ const protoRoot = import_node_path46.default.resolve(here, "..", "proto");
422
422
  const root = new import_protobufjs.default.Root();
423
- root.resolvePath = (_origin, target) => import_node_path45.default.resolve(protoRoot, target);
423
+ root.resolvePath = (_origin, target) => import_node_path46.default.resolve(protoRoot, target);
424
424
  root.loadSync(
425
425
  "opentelemetry/proto/collector/trace/v1/trace_service.proto",
426
426
  { keepCase: true }
@@ -648,12 +648,12 @@ async function listenSteppingOtlp(app, requestedPort, host) {
648
648
  }
649
649
  }
650
650
  }
651
- var import_node_path45, import_node_url3, import_fastify2, import_protobufjs, ENV_ATTR_CANONICAL, ENV_ATTR_COMPAT, ENV_FALLBACK, exportTraceServiceRequestType, exportTraceServiceResponseType, cachedProtobufResponseBody, OTLP_STEP_ATTEMPTS, OTLP_STEP_STRIDE;
651
+ var import_node_path46, import_node_url3, import_fastify2, import_protobufjs, ENV_ATTR_CANONICAL, ENV_ATTR_COMPAT, ENV_FALLBACK, exportTraceServiceRequestType, exportTraceServiceResponseType, cachedProtobufResponseBody, OTLP_STEP_ATTEMPTS, OTLP_STEP_STRIDE;
652
652
  var init_otel = __esm({
653
653
  "src/otel.ts"() {
654
654
  "use strict";
655
655
  init_cjs_shims();
656
- import_node_path45 = __toESM(require("path"), 1);
656
+ import_node_path46 = __toESM(require("path"), 1);
657
657
  import_node_url3 = require("url");
658
658
  import_fastify2 = __toESM(require("fastify"), 1);
659
659
  import_protobufjs = __toESM(require("protobufjs"), 1);
@@ -690,8 +690,8 @@ __export(cli_exports, {
690
690
  });
691
691
  module.exports = __toCommonJS(cli_exports);
692
692
  init_cjs_shims();
693
- var import_node_path56 = __toESM(require("path"), 1);
694
- var import_node_fs36 = require("fs");
693
+ var import_node_path57 = __toESM(require("path"), 1);
694
+ var import_node_fs37 = require("fs");
695
695
 
696
696
  // src/banner.ts
697
697
  init_cjs_shims();
@@ -1256,19 +1256,19 @@ function confidenceFromMix(edges, now = Date.now()) {
1256
1256
  function longestIncomingWalk(graph, start, maxDepth) {
1257
1257
  let best = { path: [start], edges: [] };
1258
1258
  const visited = /* @__PURE__ */ new Set([start]);
1259
- function step(node, path57, edges) {
1260
- if (path57.length > best.path.length) {
1261
- best = { path: [...path57], edges: [...edges] };
1259
+ function step(node, path58, edges) {
1260
+ if (path58.length > best.path.length) {
1261
+ best = { path: [...path58], edges: [...edges] };
1262
1262
  }
1263
- if (path57.length - 1 >= maxDepth) return;
1263
+ if (path58.length - 1 >= maxDepth) return;
1264
1264
  const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
1265
1265
  for (const [srcId, edge] of incoming) {
1266
1266
  if (visited.has(srcId)) continue;
1267
1267
  visited.add(srcId);
1268
- path57.push(srcId);
1268
+ path58.push(srcId);
1269
1269
  edges.push(edge);
1270
- step(srcId, path57, edges);
1271
- path57.pop();
1270
+ step(srcId, path58, edges);
1271
+ path58.pop();
1272
1272
  edges.pop();
1273
1273
  visited.delete(srcId);
1274
1274
  }
@@ -1462,26 +1462,26 @@ function dominantFailingCall(graph, serviceId5, visited) {
1462
1462
  return best;
1463
1463
  }
1464
1464
  function followFailingCallChain(graph, originServiceId, maxDepth) {
1465
- const path57 = [originServiceId];
1465
+ const path58 = [originServiceId];
1466
1466
  const edges = [];
1467
1467
  const visited = /* @__PURE__ */ new Set([originServiceId]);
1468
1468
  let current = originServiceId;
1469
1469
  for (let depth = 0; depth < maxDepth; depth++) {
1470
1470
  const hop = dominantFailingCall(graph, current, visited);
1471
1471
  if (!hop) break;
1472
- path57.push(hop.nextService);
1472
+ path58.push(hop.nextService);
1473
1473
  edges.push(hop.edge);
1474
1474
  visited.add(hop.nextService);
1475
1475
  current = hop.nextService;
1476
1476
  }
1477
1477
  if (edges.length === 0) return null;
1478
- return { path: path57, edges, culprit: current };
1478
+ return { path: path58, edges, culprit: current };
1479
1479
  }
1480
1480
  function crossServiceRootCause(graph, originId, incidents, errorEvent) {
1481
1481
  const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
1482
1482
  if (!chain) return null;
1483
1483
  const culprit = chain.culprit;
1484
- const path57 = [...chain.path];
1484
+ const path58 = [...chain.path];
1485
1485
  const edgeProvenances = chain.edges.map((e) => e.provenance);
1486
1486
  const baseConfidence = confidenceFromMix(chain.edges);
1487
1487
  const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
@@ -1489,14 +1489,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
1489
1489
  if (loc) {
1490
1490
  let rootCauseNode = culprit;
1491
1491
  if (loc.fileNode) {
1492
- path57.push(loc.fileNode);
1492
+ path58.push(loc.fileNode);
1493
1493
  edgeProvenances.push(import_types.Provenance.OBSERVED);
1494
1494
  rootCauseNode = loc.fileNode;
1495
1495
  }
1496
1496
  return import_types.RootCauseResultSchema.parse({
1497
1497
  rootCauseNode,
1498
1498
  rootCauseReason: loc.rootCauseReason,
1499
- traversalPath: path57,
1499
+ traversalPath: path58,
1500
1500
  edgeProvenances,
1501
1501
  confidence,
1502
1502
  ...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
@@ -1508,7 +1508,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
1508
1508
  return import_types.RootCauseResultSchema.parse({
1509
1509
  rootCauseNode: culprit,
1510
1510
  rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
1511
- traversalPath: path57,
1511
+ traversalPath: path58,
1512
1512
  edgeProvenances,
1513
1513
  confidence,
1514
1514
  fixRecommendation: `Inspect ${culpritName}'s failing handler`
@@ -5355,10 +5355,10 @@ function fastifyRouteMethods(objNode) {
5355
5355
  }
5356
5356
  return [];
5357
5357
  }
5358
- function serverRoutesFromSource(source, parser, hasExpress, hasFastify) {
5358
+ function serverRoutesFromSource(source, parser, hasExpress, hasFastify, hasHono = false) {
5359
5359
  const tree = parseSource2(parser, source);
5360
5360
  const out = [];
5361
- const framework = hasExpress ? "express" : "fastify";
5361
+ const framework = hasExpress ? "express" : hasFastify ? "fastify" : hasHono ? "hono" : "unknown";
5362
5362
  walk(tree.rootNode, (node) => {
5363
5363
  if (node.type !== "call_expression") return;
5364
5364
  const fn = node.childForFieldName("function");
@@ -5508,8 +5508,9 @@ async function addRoutes(graph, services) {
5508
5508
  };
5509
5509
  const hasExpress = deps["express"] !== void 0;
5510
5510
  const hasFastify = deps["fastify"] !== void 0;
5511
+ const hasHono = deps["hono"] !== void 0;
5511
5512
  const hasNext = deps["next"] !== void 0;
5512
- if (!hasExpress && !hasFastify && !hasNext) continue;
5513
+ if (!hasExpress && !hasFastify && !hasHono && !hasNext) continue;
5513
5514
  const files = await loadSourceFiles(service.dir);
5514
5515
  for (const file of files) {
5515
5516
  if (isTestPath(file.path)) continue;
@@ -5519,8 +5520,8 @@ async function addRoutes(graph, services) {
5519
5520
  try {
5520
5521
  if (hasNext && (isNextAppRouteFile(relFile) || isNextPagesApiFile(relFile))) {
5521
5522
  routes = nextRoutesFromFile(file.content, relFile, jsParser);
5522
- } else if (hasExpress || hasFastify) {
5523
- routes = serverRoutesFromSource(file.content, jsParser, hasExpress, hasFastify);
5523
+ } else if (hasExpress || hasFastify || hasHono) {
5524
+ routes = serverRoutesFromSource(file.content, jsParser, hasExpress, hasFastify, hasHono);
5524
5525
  } else {
5525
5526
  routes = [];
5526
5527
  }
@@ -6844,30 +6845,264 @@ async function addK8sResources(graph, scanPath) {
6844
6845
  return { nodesAdded, edgesAdded: 0 };
6845
6846
  }
6846
6847
 
6848
+ // src/extract/infra/cloudflare.ts
6849
+ init_cjs_shims();
6850
+ var import_node_fs20 = require("fs");
6851
+ var import_node_path36 = __toESM(require("path"), 1);
6852
+ var import_smol_toml2 = require("smol-toml");
6853
+ var import_types25 = require("@neat.is/types");
6854
+ var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
6855
+ async function readWranglerConfig(dir) {
6856
+ for (const filename of WRANGLER_FILENAMES) {
6857
+ const abs = import_node_path36.default.join(dir, filename);
6858
+ if (!await exists(abs)) continue;
6859
+ const raw = await import_node_fs20.promises.readFile(abs, "utf8");
6860
+ const config = filename === "wrangler.toml" ? (0, import_smol_toml2.parse)(raw) : JSON.parse(maskCommentsInSource(raw));
6861
+ return { config, relFile: filename, raw };
6862
+ }
6863
+ return null;
6864
+ }
6865
+ function lineContaining(raw, needle) {
6866
+ if (!needle) return void 0;
6867
+ const idx = raw.indexOf(needle);
6868
+ if (idx === -1) return void 0;
6869
+ let line = 1;
6870
+ for (let i = 0; i < idx; i++) if (raw[i] === "\n") line++;
6871
+ return line;
6872
+ }
6873
+ function normalizeRoutes(config) {
6874
+ const out = [];
6875
+ const pushOne = (r) => {
6876
+ if (typeof r === "string") out.push(r);
6877
+ else if (r && typeof r === "object" && typeof r.pattern === "string") {
6878
+ out.push(r.pattern);
6879
+ }
6880
+ };
6881
+ if (Array.isArray(config.routes)) config.routes.forEach(pushOne);
6882
+ else if (config.route) pushOne(config.route);
6883
+ return out;
6884
+ }
6885
+ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, line) {
6886
+ let nodesAdded = 0;
6887
+ let edgesAdded = 0;
6888
+ const node = makeInfraNode(kind, name, "cloudflare");
6889
+ if (!graph.hasNode(node.id)) {
6890
+ graph.addNode(node.id, node);
6891
+ nodesAdded++;
6892
+ }
6893
+ if (node.id === anchorId) return { nodesAdded, edgesAdded };
6894
+ const edgeId = (0, import_types4.extractedEdgeId)(anchorId, node.id, edgeType);
6895
+ if (!graph.hasEdge(edgeId)) {
6896
+ const edge = {
6897
+ id: edgeId,
6898
+ source: anchorId,
6899
+ target: node.id,
6900
+ type: edgeType,
6901
+ provenance: import_types25.Provenance.EXTRACTED,
6902
+ confidence: (0, import_types25.confidenceForExtracted)("structural"),
6903
+ evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
6904
+ };
6905
+ graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
6906
+ edgesAdded++;
6907
+ }
6908
+ return { nodesAdded, edgesAdded };
6909
+ }
6910
+ async function addCloudflareWorkers(graph, services, scanPath) {
6911
+ let nodesAdded = 0;
6912
+ let edgesAdded = 0;
6913
+ const discovered = [];
6914
+ const workerIndex = /* @__PURE__ */ new Map();
6915
+ for (const service of services) {
6916
+ let read;
6917
+ try {
6918
+ read = await readWranglerConfig(service.dir);
6919
+ } catch (err) {
6920
+ recordExtractionError("infra cloudflare", import_node_path36.default.relative(scanPath, service.dir), err);
6921
+ continue;
6922
+ }
6923
+ if (!read || !read.config.name) continue;
6924
+ const evidenceFile = toPosix2(import_node_path36.default.relative(scanPath, import_node_path36.default.join(service.dir, read.relFile)));
6925
+ discovered.push({ service, config: read.config, relFile: read.relFile, raw: read.raw, evidenceFile });
6926
+ }
6927
+ for (const worker of discovered) {
6928
+ const { service, config } = worker;
6929
+ const serviceNode = graph.getNodeAttributes(service.node.id);
6930
+ if (serviceNode.platform !== "cloudflare") {
6931
+ const updated = { ...serviceNode, platform: "cloudflare" };
6932
+ graph.replaceNodeAttributes(service.node.id, updated);
6933
+ }
6934
+ let anchorId = service.node.id;
6935
+ if (config.main) {
6936
+ const entryRelPath = toPosix2(import_node_path36.default.normalize(config.main));
6937
+ const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
6938
+ graph,
6939
+ service.pkg.name,
6940
+ service.node.id,
6941
+ entryRelPath
6942
+ );
6943
+ nodesAdded += fn;
6944
+ edgesAdded += fe;
6945
+ const fileNode = graph.getNodeAttributes(fileNodeId);
6946
+ if (fileNode.platform !== "cloudflare" || fileNode.platformName !== config.name) {
6947
+ const updated = { ...fileNode, platform: "cloudflare", platformName: config.name };
6948
+ graph.replaceNodeAttributes(fileNodeId, updated);
6949
+ }
6950
+ anchorId = fileNodeId;
6951
+ }
6952
+ workerIndex.set(config.name, { anchorId });
6953
+ }
6954
+ for (const worker of discovered) {
6955
+ const { config, evidenceFile, raw } = worker;
6956
+ const anchorId = workerIndex.get(config.name).anchorId;
6957
+ const runtimeNode = makeInfraNode("workerd", "cloudflare", "cloudflare");
6958
+ if (!graph.hasNode(runtimeNode.id)) {
6959
+ graph.addNode(runtimeNode.id, runtimeNode);
6960
+ nodesAdded++;
6961
+ }
6962
+ if (runtimeNode.id !== anchorId) {
6963
+ const runsOnId = (0, import_types4.extractedEdgeId)(anchorId, runtimeNode.id, import_types25.EdgeType.RUNS_ON);
6964
+ if (!graph.hasEdge(runsOnId)) {
6965
+ const edge = {
6966
+ id: runsOnId,
6967
+ source: anchorId,
6968
+ target: runtimeNode.id,
6969
+ type: import_types25.EdgeType.RUNS_ON,
6970
+ provenance: import_types25.Provenance.EXTRACTED,
6971
+ confidence: (0, import_types25.confidenceForExtracted)("structural"),
6972
+ evidence: {
6973
+ file: evidenceFile,
6974
+ ...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
6975
+ }
6976
+ };
6977
+ graph.addEdgeWithKey(runsOnId, edge.source, edge.target, edge);
6978
+ edgesAdded++;
6979
+ }
6980
+ }
6981
+ for (const route of normalizeRoutes(config)) {
6982
+ const result = addResourceEdge(
6983
+ graph,
6984
+ anchorId,
6985
+ import_types25.EdgeType.CONNECTS_TO,
6986
+ "cloudflare-route",
6987
+ route,
6988
+ evidenceFile,
6989
+ lineContaining(raw, route)
6990
+ );
6991
+ nodesAdded += result.nodesAdded;
6992
+ edgesAdded += result.edgesAdded;
6993
+ }
6994
+ const bindingGroups = [
6995
+ { kind: "cloudflare-kv", entries: config.kv_namespaces ?? [], nameOf: (b) => b.binding },
6996
+ { kind: "cloudflare-d1", entries: config.d1_databases ?? [], nameOf: (b) => b.binding },
6997
+ { kind: "cloudflare-r2", entries: config.r2_buckets ?? [], nameOf: (b) => b.binding },
6998
+ { kind: "cloudflare-durable-object", entries: config.durable_objects?.bindings ?? [], nameOf: (b) => b.name },
6999
+ { kind: "cloudflare-queue", entries: config.queues?.producers ?? [], nameOf: (b) => b.queue },
7000
+ { kind: "cloudflare-queue", entries: config.queues?.consumers ?? [], nameOf: (b) => b.queue }
7001
+ ];
7002
+ for (const group of bindingGroups) {
7003
+ for (const entry2 of group.entries) {
7004
+ const name = group.nameOf(entry2);
7005
+ if (!name) continue;
7006
+ const result = addResourceEdge(
7007
+ graph,
7008
+ anchorId,
7009
+ import_types25.EdgeType.DEPENDS_ON,
7010
+ group.kind,
7011
+ name,
7012
+ evidenceFile,
7013
+ lineContaining(raw, name)
7014
+ );
7015
+ nodesAdded += result.nodesAdded;
7016
+ edgesAdded += result.edgesAdded;
7017
+ }
7018
+ }
7019
+ for (const cron of config.triggers?.crons ?? []) {
7020
+ const result = addResourceEdge(
7021
+ graph,
7022
+ anchorId,
7023
+ import_types25.EdgeType.DEPENDS_ON,
7024
+ "cloudflare-cron",
7025
+ cron,
7026
+ evidenceFile,
7027
+ lineContaining(raw, cron)
7028
+ );
7029
+ nodesAdded += result.nodesAdded;
7030
+ edgesAdded += result.edgesAdded;
7031
+ }
7032
+ for (const varName of Object.keys(config.vars ?? {})) {
7033
+ const result = addResourceEdge(
7034
+ graph,
7035
+ anchorId,
7036
+ import_types25.EdgeType.DEPENDS_ON,
7037
+ "cloudflare-env-var",
7038
+ varName,
7039
+ evidenceFile,
7040
+ lineContaining(raw, varName)
7041
+ );
7042
+ nodesAdded += result.nodesAdded;
7043
+ edgesAdded += result.edgesAdded;
7044
+ }
7045
+ for (const svc of config.services ?? []) {
7046
+ if (!svc.service) continue;
7047
+ const target = workerIndex.get(svc.service);
7048
+ if (target && target.anchorId !== anchorId) {
7049
+ const edgeId = (0, import_types4.extractedEdgeId)(anchorId, target.anchorId, import_types25.EdgeType.CALLS);
7050
+ if (!graph.hasEdge(edgeId)) {
7051
+ const edge = {
7052
+ id: edgeId,
7053
+ source: anchorId,
7054
+ target: target.anchorId,
7055
+ type: import_types25.EdgeType.CALLS,
7056
+ provenance: import_types25.Provenance.EXTRACTED,
7057
+ confidence: (0, import_types25.confidenceForExtracted)("structural"),
7058
+ evidence: { file: evidenceFile, line: lineContaining(raw, svc.service) }
7059
+ };
7060
+ graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
7061
+ edgesAdded++;
7062
+ }
7063
+ continue;
7064
+ }
7065
+ const result = addResourceEdge(
7066
+ graph,
7067
+ anchorId,
7068
+ import_types25.EdgeType.DEPENDS_ON,
7069
+ "cloudflare-service-binding",
7070
+ svc.service,
7071
+ evidenceFile,
7072
+ lineContaining(raw, svc.service)
7073
+ );
7074
+ nodesAdded += result.nodesAdded;
7075
+ edgesAdded += result.edgesAdded;
7076
+ }
7077
+ }
7078
+ return { nodesAdded, edgesAdded };
7079
+ }
7080
+
6847
7081
  // src/extract/infra/index.ts
6848
7082
  async function addInfra(graph, scanPath, services) {
6849
7083
  const compose = await addComposeInfra(graph, scanPath, services);
6850
7084
  const dockerfile = await addDockerfileRuntimes(graph, services, scanPath);
6851
7085
  const terraform = await addTerraformResources(graph, scanPath);
6852
7086
  const k8s = await addK8sResources(graph, scanPath);
7087
+ const cloudflare = await addCloudflareWorkers(graph, services, scanPath);
6853
7088
  return {
6854
- nodesAdded: compose.nodesAdded + dockerfile.nodesAdded + terraform.nodesAdded + k8s.nodesAdded,
6855
- edgesAdded: compose.edgesAdded + dockerfile.edgesAdded + terraform.edgesAdded + k8s.edgesAdded
7089
+ nodesAdded: compose.nodesAdded + dockerfile.nodesAdded + terraform.nodesAdded + k8s.nodesAdded + cloudflare.nodesAdded,
7090
+ edgesAdded: compose.edgesAdded + dockerfile.edgesAdded + terraform.edgesAdded + k8s.edgesAdded + cloudflare.edgesAdded
6856
7091
  };
6857
7092
  }
6858
7093
 
6859
7094
  // src/extract/index.ts
6860
- var import_node_path37 = __toESM(require("path"), 1);
7095
+ var import_node_path38 = __toESM(require("path"), 1);
6861
7096
 
6862
7097
  // src/extract/retire.ts
6863
7098
  init_cjs_shims();
6864
- var import_node_fs20 = require("fs");
6865
- var import_node_path36 = __toESM(require("path"), 1);
6866
- var import_types25 = require("@neat.is/types");
7099
+ var import_node_fs21 = require("fs");
7100
+ var import_node_path37 = __toESM(require("path"), 1);
7101
+ var import_types26 = require("@neat.is/types");
6867
7102
  function dropOrphanedFileNodes(graph) {
6868
7103
  const orphans = [];
6869
7104
  graph.forEachNode((id, attrs) => {
6870
- if (attrs.type !== import_types25.NodeType.FileNode) return;
7105
+ if (attrs.type !== import_types26.NodeType.FileNode) return;
6871
7106
  if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
6872
7107
  orphans.push(id);
6873
7108
  }
@@ -6880,7 +7115,7 @@ function retireEdgesByFile(graph, file) {
6880
7115
  const toDrop = [];
6881
7116
  graph.forEachEdge((id, attrs) => {
6882
7117
  const edge = attrs;
6883
- if (edge.provenance !== import_types25.Provenance.EXTRACTED) return;
7118
+ if (edge.provenance !== import_types26.Provenance.EXTRACTED) return;
6884
7119
  if (!edge.evidence?.file) return;
6885
7120
  if (edge.evidence.file === normalized) toDrop.push(id);
6886
7121
  });
@@ -6893,14 +7128,14 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
6893
7128
  const bases = [scanPath, ...serviceDirs];
6894
7129
  graph.forEachEdge((id, attrs) => {
6895
7130
  const edge = attrs;
6896
- if (edge.provenance !== import_types25.Provenance.EXTRACTED) return;
7131
+ if (edge.provenance !== import_types26.Provenance.EXTRACTED) return;
6897
7132
  const evidenceFile = edge.evidence?.file;
6898
7133
  if (!evidenceFile) return;
6899
- if (import_node_path36.default.isAbsolute(evidenceFile)) {
6900
- if (!(0, import_node_fs20.existsSync)(evidenceFile)) toDrop.push(id);
7134
+ if (import_node_path37.default.isAbsolute(evidenceFile)) {
7135
+ if (!(0, import_node_fs21.existsSync)(evidenceFile)) toDrop.push(id);
6901
7136
  return;
6902
7137
  }
6903
- const found = bases.some((base) => (0, import_node_fs20.existsSync)(import_node_path36.default.join(base, evidenceFile)));
7138
+ const found = bases.some((base) => (0, import_node_fs21.existsSync)(import_node_path37.default.join(base, evidenceFile)));
6904
7139
  if (!found) toDrop.push(id);
6905
7140
  });
6906
7141
  for (const id of toDrop) graph.dropEdge(id);
@@ -6942,7 +7177,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
6942
7177
  }
6943
7178
  const droppedEntries = drainDroppedExtracted();
6944
7179
  if (isRejectedLogEnabled() && opts.errorsPath && droppedEntries.length > 0) {
6945
- const rejectedPath = import_node_path37.default.join(import_node_path37.default.dirname(opts.errorsPath), "rejected.ndjson");
7180
+ const rejectedPath = import_node_path38.default.join(import_node_path38.default.dirname(opts.errorsPath), "rejected.ndjson");
6946
7181
  try {
6947
7182
  await writeRejectedExtracted(droppedEntries, rejectedPath);
6948
7183
  } catch (err) {
@@ -6976,7 +7211,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
6976
7211
 
6977
7212
  // src/divergences.ts
6978
7213
  init_cjs_shims();
6979
- var import_types26 = require("@neat.is/types");
7214
+ var import_types27 = require("@neat.is/types");
6980
7215
  function bucketKey(source, target, type) {
6981
7216
  return `${type}|${source}|${target}`;
6982
7217
  }
@@ -6984,22 +7219,22 @@ function bucketEdges(graph) {
6984
7219
  const buckets2 = /* @__PURE__ */ new Map();
6985
7220
  graph.forEachEdge((id, attrs) => {
6986
7221
  const e = attrs;
6987
- const parsed = (0, import_types26.parseEdgeId)(id);
7222
+ const parsed = (0, import_types27.parseEdgeId)(id);
6988
7223
  const provenance = parsed?.provenance ?? e.provenance;
6989
7224
  const key = bucketKey(e.source, e.target, e.type);
6990
7225
  const cur = buckets2.get(key) ?? { source: e.source, target: e.target, type: e.type };
6991
7226
  switch (provenance) {
6992
- case import_types26.Provenance.EXTRACTED:
7227
+ case import_types27.Provenance.EXTRACTED:
6993
7228
  cur.extracted = e;
6994
7229
  break;
6995
- case import_types26.Provenance.OBSERVED:
7230
+ case import_types27.Provenance.OBSERVED:
6996
7231
  cur.observed = e;
6997
7232
  break;
6998
- case import_types26.Provenance.INFERRED:
7233
+ case import_types27.Provenance.INFERRED:
6999
7234
  cur.inferred = e;
7000
7235
  break;
7001
7236
  default:
7002
- if (e.provenance === import_types26.Provenance.STALE) cur.stale = e;
7237
+ if (e.provenance === import_types27.Provenance.STALE) cur.stale = e;
7003
7238
  }
7004
7239
  buckets2.set(key, cur);
7005
7240
  });
@@ -7008,12 +7243,12 @@ function bucketEdges(graph) {
7008
7243
  function nodeIsFrontier(graph, nodeId) {
7009
7244
  if (!graph.hasNode(nodeId)) return false;
7010
7245
  const attrs = graph.getNodeAttributes(nodeId);
7011
- return attrs.type === import_types26.NodeType.FrontierNode;
7246
+ return attrs.type === import_types27.NodeType.FrontierNode;
7012
7247
  }
7013
7248
  function nodeIsWebsocketChannel(graph, nodeId) {
7014
7249
  if (!graph.hasNode(nodeId)) return false;
7015
7250
  const attrs = graph.getNodeAttributes(nodeId);
7016
- return attrs.type === import_types26.NodeType.WebSocketChannelNode;
7251
+ return attrs.type === import_types27.NodeType.WebSocketChannelNode;
7017
7252
  }
7018
7253
  function clampConfidence(n) {
7019
7254
  if (!Number.isFinite(n)) return 0;
@@ -7033,14 +7268,14 @@ function gradedConfidence(edge) {
7033
7268
  return clampConfidence(confidenceForEdge(edge));
7034
7269
  }
7035
7270
  var OBSERVABLE_EDGE_TYPES = /* @__PURE__ */ new Set([
7036
- import_types26.EdgeType.CALLS,
7037
- import_types26.EdgeType.CONNECTS_TO,
7038
- import_types26.EdgeType.PUBLISHES_TO,
7039
- import_types26.EdgeType.CONSUMES_FROM
7271
+ import_types27.EdgeType.CALLS,
7272
+ import_types27.EdgeType.CONNECTS_TO,
7273
+ import_types27.EdgeType.PUBLISHES_TO,
7274
+ import_types27.EdgeType.CONSUMES_FROM
7040
7275
  ]);
7041
7276
  function detectMissingDivergences(graph, bucket) {
7042
7277
  const out = [];
7043
- if (bucket.type === import_types26.EdgeType.CONTAINS) return out;
7278
+ if (bucket.type === import_types27.EdgeType.CONTAINS) return out;
7044
7279
  if (bucket.extracted && !bucket.observed && OBSERVABLE_EDGE_TYPES.has(bucket.type)) {
7045
7280
  if (!nodeIsFrontier(graph, bucket.target)) {
7046
7281
  out.push({
@@ -7081,7 +7316,7 @@ function declaredHostFor(svc) {
7081
7316
  function hasExtractedConfiguredBy(graph, svcId) {
7082
7317
  for (const edgeId of graph.outboundEdges(svcId)) {
7083
7318
  const e = graph.getEdgeAttributes(edgeId);
7084
- if (e.type === import_types26.EdgeType.CONFIGURED_BY && e.provenance === import_types26.Provenance.EXTRACTED) {
7319
+ if (e.type === import_types27.EdgeType.CONFIGURED_BY && e.provenance === import_types27.Provenance.EXTRACTED) {
7085
7320
  return true;
7086
7321
  }
7087
7322
  }
@@ -7094,10 +7329,10 @@ function detectHostMismatch(graph, svcId, svc) {
7094
7329
  const out = [];
7095
7330
  for (const edgeId of graph.outboundEdges(svcId)) {
7096
7331
  const edge = graph.getEdgeAttributes(edgeId);
7097
- if (edge.type !== import_types26.EdgeType.CONNECTS_TO) continue;
7098
- if (edge.provenance !== import_types26.Provenance.OBSERVED) continue;
7332
+ if (edge.type !== import_types27.EdgeType.CONNECTS_TO) continue;
7333
+ if (edge.provenance !== import_types27.Provenance.OBSERVED) continue;
7099
7334
  const target = graph.getNodeAttributes(edge.target);
7100
- if (target.type !== import_types26.NodeType.DatabaseNode) continue;
7335
+ if (target.type !== import_types27.NodeType.DatabaseNode) continue;
7101
7336
  const observedHost = target.host?.trim();
7102
7337
  if (!observedHost) continue;
7103
7338
  if (observedHost === declaredHost) continue;
@@ -7119,10 +7354,10 @@ function detectCompatDivergences(graph, svcId, svc) {
7119
7354
  const deps = svc.dependencies ?? {};
7120
7355
  for (const edgeId of graph.outboundEdges(svcId)) {
7121
7356
  const edge = graph.getEdgeAttributes(edgeId);
7122
- if (edge.type !== import_types26.EdgeType.CONNECTS_TO) continue;
7123
- if (edge.provenance !== import_types26.Provenance.OBSERVED) continue;
7357
+ if (edge.type !== import_types27.EdgeType.CONNECTS_TO) continue;
7358
+ if (edge.provenance !== import_types27.Provenance.OBSERVED) continue;
7124
7359
  const target = graph.getNodeAttributes(edge.target);
7125
- if (target.type !== import_types26.NodeType.DatabaseNode) continue;
7360
+ if (target.type !== import_types27.NodeType.DatabaseNode) continue;
7126
7361
  for (const pair of compatPairs()) {
7127
7362
  if (pair.engine !== target.engine) continue;
7128
7363
  const declared = deps[pair.driver];
@@ -7181,7 +7416,7 @@ function suppressHostMismatchHalves(all) {
7181
7416
  for (const d of all) {
7182
7417
  if (d.type !== "host-mismatch") continue;
7183
7418
  observedHalf.add(`${d.source}->${d.target}`);
7184
- declaredHalf.add((0, import_types26.databaseId)(d.extractedHost));
7419
+ declaredHalf.add((0, import_types27.databaseId)(d.extractedHost));
7185
7420
  }
7186
7421
  if (observedHalf.size === 0) return all;
7187
7422
  return all.filter((d) => {
@@ -7200,7 +7435,7 @@ function computeDivergences(graph, opts = {}) {
7200
7435
  }
7201
7436
  graph.forEachNode((nodeId, attrs) => {
7202
7437
  const n = attrs;
7203
- if (n.type !== import_types26.NodeType.ServiceNode) return;
7438
+ if (n.type !== import_types27.NodeType.ServiceNode) return;
7204
7439
  const svc = n;
7205
7440
  for (const d of detectHostMismatch(graph, nodeId, svc)) all.push(d);
7206
7441
  for (const d of detectCompatDivergences(graph, nodeId, svc)) all.push(d);
@@ -7234,7 +7469,7 @@ function computeDivergences(graph, opts = {}) {
7234
7469
  if (a.source !== b.source) return a.source.localeCompare(b.source);
7235
7470
  return a.target.localeCompare(b.target);
7236
7471
  });
7237
- return import_types26.DivergenceResultSchema.parse({
7472
+ return import_types27.DivergenceResultSchema.parse({
7238
7473
  divergences: filtered,
7239
7474
  totalAffected: filtered.length,
7240
7475
  computedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -7243,9 +7478,9 @@ function computeDivergences(graph, opts = {}) {
7243
7478
 
7244
7479
  // src/persist.ts
7245
7480
  init_cjs_shims();
7246
- var import_node_fs21 = require("fs");
7247
- var import_node_path38 = __toESM(require("path"), 1);
7248
- var import_types27 = require("@neat.is/types");
7481
+ var import_node_fs22 = require("fs");
7482
+ var import_node_path39 = __toESM(require("path"), 1);
7483
+ var import_types28 = require("@neat.is/types");
7249
7484
  var SCHEMA_VERSION = 4;
7250
7485
  function migrateV1ToV2(payload) {
7251
7486
  const nodes = payload.graph.nodes;
@@ -7267,12 +7502,12 @@ function migrateV2ToV3(payload) {
7267
7502
  for (const edge of edges) {
7268
7503
  const attrs = edge.attributes;
7269
7504
  if (!attrs || attrs.provenance !== "FRONTIER") continue;
7270
- attrs.provenance = import_types27.Provenance.OBSERVED;
7505
+ attrs.provenance = import_types28.Provenance.OBSERVED;
7271
7506
  const type = typeof attrs.type === "string" ? attrs.type : void 0;
7272
7507
  const source = typeof attrs.source === "string" ? attrs.source : void 0;
7273
7508
  const target = typeof attrs.target === "string" ? attrs.target : void 0;
7274
7509
  if (type && source && target) {
7275
- const newId = (0, import_types27.observedEdgeId)(source, target, type);
7510
+ const newId = (0, import_types28.observedEdgeId)(source, target, type);
7276
7511
  attrs.id = newId;
7277
7512
  if (edge.key) edge.key = newId;
7278
7513
  }
@@ -7281,7 +7516,7 @@ function migrateV2ToV3(payload) {
7281
7516
  return { ...payload, schemaVersion: 3 };
7282
7517
  }
7283
7518
  async function ensureDir(filePath) {
7284
- await import_node_fs21.promises.mkdir(import_node_path38.default.dirname(filePath), { recursive: true });
7519
+ await import_node_fs22.promises.mkdir(import_node_path39.default.dirname(filePath), { recursive: true });
7285
7520
  }
7286
7521
  async function saveGraphToDisk(graph, outPath) {
7287
7522
  await ensureDir(outPath);
@@ -7291,13 +7526,13 @@ async function saveGraphToDisk(graph, outPath) {
7291
7526
  graph: graph.export()
7292
7527
  };
7293
7528
  const tmp = `${outPath}.tmp`;
7294
- await import_node_fs21.promises.writeFile(tmp, JSON.stringify(payload), "utf8");
7295
- await import_node_fs21.promises.rename(tmp, outPath);
7529
+ await import_node_fs22.promises.writeFile(tmp, JSON.stringify(payload), "utf8");
7530
+ await import_node_fs22.promises.rename(tmp, outPath);
7296
7531
  }
7297
7532
  async function loadGraphFromDisk(graph, outPath) {
7298
7533
  let raw;
7299
7534
  try {
7300
- raw = await import_node_fs21.promises.readFile(outPath, "utf8");
7535
+ raw = await import_node_fs22.promises.readFile(outPath, "utf8");
7301
7536
  } catch (err) {
7302
7537
  if (err.code === "ENOENT") return;
7303
7538
  throw err;
@@ -7362,8 +7597,8 @@ function startPersistLoop(graph, outPath, opts = {}) {
7362
7597
 
7363
7598
  // src/gitignore.ts
7364
7599
  init_cjs_shims();
7365
- var import_node_fs22 = require("fs");
7366
- var import_node_path39 = __toESM(require("path"), 1);
7600
+ var import_node_fs23 = require("fs");
7601
+ var import_node_path40 = __toESM(require("path"), 1);
7367
7602
  var NEAT_OUT_LINE = "neat-out/";
7368
7603
  var NEAT_HEADER = "# NEAT \u2014 machine-local snapshots and events";
7369
7604
  function isNeatOutLine(line) {
@@ -7371,15 +7606,15 @@ function isNeatOutLine(line) {
7371
7606
  return trimmed === "neat-out/" || trimmed === "neat-out";
7372
7607
  }
7373
7608
  async function ensureNeatOutIgnored(projectDir) {
7374
- const file = import_node_path39.default.join(projectDir, ".gitignore");
7609
+ const file = import_node_path40.default.join(projectDir, ".gitignore");
7375
7610
  let existing = null;
7376
7611
  try {
7377
- existing = await import_node_fs22.promises.readFile(file, "utf8");
7612
+ existing = await import_node_fs23.promises.readFile(file, "utf8");
7378
7613
  } catch (err) {
7379
7614
  if (err.code !== "ENOENT") throw err;
7380
7615
  }
7381
7616
  if (existing === null) {
7382
- await import_node_fs22.promises.writeFile(file, `${NEAT_HEADER}
7617
+ await import_node_fs23.promises.writeFile(file, `${NEAT_HEADER}
7383
7618
  ${NEAT_OUT_LINE}
7384
7619
  `, "utf8");
7385
7620
  return { action: "created", file };
@@ -7392,13 +7627,13 @@ ${NEAT_OUT_LINE}
7392
7627
  ${NEAT_HEADER}
7393
7628
  ${NEAT_OUT_LINE}
7394
7629
  `;
7395
- await import_node_fs22.promises.writeFile(file, existing + appended, "utf8");
7630
+ await import_node_fs23.promises.writeFile(file, existing + appended, "utf8");
7396
7631
  return { action: "added", file };
7397
7632
  }
7398
7633
 
7399
7634
  // src/summary.ts
7400
7635
  init_cjs_shims();
7401
- var import_types28 = require("@neat.is/types");
7636
+ var import_types29 = require("@neat.is/types");
7402
7637
  function renderOtelEnvBlock() {
7403
7638
  return [
7404
7639
  "for prod OTel routing, set these in your deploy platform's env:",
@@ -7408,19 +7643,19 @@ function renderOtelEnvBlock() {
7408
7643
  }
7409
7644
  function findIncompatServices(nodes) {
7410
7645
  return nodes.filter(
7411
- (n) => n.type === import_types28.NodeType.ServiceNode && Array.isArray(n.incompatibilities) && (n.incompatibilities ?? []).length > 0
7646
+ (n) => n.type === import_types29.NodeType.ServiceNode && Array.isArray(n.incompatibilities) && (n.incompatibilities ?? []).length > 0
7412
7647
  );
7413
7648
  }
7414
7649
  function servicesWithoutObserved(nodes, edges) {
7415
7650
  const seen = /* @__PURE__ */ new Set();
7416
7651
  for (const e of edges) {
7417
- if (e.provenance === import_types28.Provenance.OBSERVED) {
7652
+ if (e.provenance === import_types29.Provenance.OBSERVED) {
7418
7653
  seen.add(e.source);
7419
7654
  seen.add(e.target);
7420
7655
  }
7421
7656
  }
7422
7657
  return nodes.filter(
7423
- (n) => n.type === import_types28.NodeType.ServiceNode && !seen.has(n.id)
7658
+ (n) => n.type === import_types29.NodeType.ServiceNode && !seen.has(n.id)
7424
7659
  );
7425
7660
  }
7426
7661
  function formatDivergence(d) {
@@ -7494,27 +7729,27 @@ function formatIncompat(inc) {
7494
7729
 
7495
7730
  // src/watch.ts
7496
7731
  init_cjs_shims();
7497
- var import_node_fs31 = __toESM(require("fs"), 1);
7498
- var import_node_path50 = __toESM(require("path"), 1);
7732
+ var import_node_fs32 = __toESM(require("fs"), 1);
7733
+ var import_node_path51 = __toESM(require("path"), 1);
7499
7734
  var import_chokidar = __toESM(require("chokidar"), 1);
7500
7735
 
7501
7736
  // src/api.ts
7502
7737
  init_cjs_shims();
7503
7738
  var import_fastify = __toESM(require("fastify"), 1);
7504
7739
  var import_cors = __toESM(require("@fastify/cors"), 1);
7505
- var import_types30 = require("@neat.is/types");
7740
+ var import_types31 = require("@neat.is/types");
7506
7741
 
7507
7742
  // src/extend/index.ts
7508
7743
  init_cjs_shims();
7509
- var import_node_fs24 = require("fs");
7510
- var import_node_path41 = __toESM(require("path"), 1);
7744
+ var import_node_fs25 = require("fs");
7745
+ var import_node_path42 = __toESM(require("path"), 1);
7511
7746
  var import_node_os2 = __toESM(require("os"), 1);
7512
7747
  var import_instrumentation_registry = require("@neat.is/instrumentation-registry");
7513
7748
 
7514
7749
  // src/installers/package-manager.ts
7515
7750
  init_cjs_shims();
7516
- var import_node_fs23 = require("fs");
7517
- var import_node_path40 = __toESM(require("path"), 1);
7751
+ var import_node_fs24 = require("fs");
7752
+ var import_node_path41 = __toESM(require("path"), 1);
7518
7753
  var import_node_child_process = require("child_process");
7519
7754
  var LOCKFILE_PRIORITY = [
7520
7755
  { lockfile: "bun.lockb", pm: "bun", args: ["install", "--no-summary"] },
@@ -7529,29 +7764,29 @@ var LOCKFILE_PRIORITY = [
7529
7764
  var NPM_FALLBACK_ARGS = ["install", "--no-audit", "--no-fund", "--prefer-offline"];
7530
7765
  async function exists2(p) {
7531
7766
  try {
7532
- await import_node_fs23.promises.access(p);
7767
+ await import_node_fs24.promises.access(p);
7533
7768
  return true;
7534
7769
  } catch {
7535
7770
  return false;
7536
7771
  }
7537
7772
  }
7538
7773
  async function detectPackageManager(serviceDir) {
7539
- let dir = import_node_path40.default.resolve(serviceDir);
7774
+ let dir = import_node_path41.default.resolve(serviceDir);
7540
7775
  const stops = /* @__PURE__ */ new Set();
7541
7776
  for (let i = 0; i < 64; i++) {
7542
7777
  if (stops.has(dir)) break;
7543
7778
  stops.add(dir);
7544
7779
  for (const candidate of LOCKFILE_PRIORITY) {
7545
- const lockPath = import_node_path40.default.join(dir, candidate.lockfile);
7780
+ const lockPath = import_node_path41.default.join(dir, candidate.lockfile);
7546
7781
  if (await exists2(lockPath)) {
7547
7782
  return { pm: candidate.pm, cwd: dir, args: [...candidate.args] };
7548
7783
  }
7549
7784
  }
7550
- const parent = import_node_path40.default.dirname(dir);
7785
+ const parent = import_node_path41.default.dirname(dir);
7551
7786
  if (parent === dir) break;
7552
7787
  dir = parent;
7553
7788
  }
7554
- return { pm: "npm", cwd: import_node_path40.default.resolve(serviceDir), args: [...NPM_FALLBACK_ARGS] };
7789
+ return { pm: "npm", cwd: import_node_path41.default.resolve(serviceDir), args: [...NPM_FALLBACK_ARGS] };
7555
7790
  }
7556
7791
  async function runPackageManagerInstall(cmd) {
7557
7792
  return new Promise((resolve) => {
@@ -7593,30 +7828,30 @@ ${err.message}`
7593
7828
  // src/extend/index.ts
7594
7829
  async function fileExists2(p) {
7595
7830
  try {
7596
- await import_node_fs24.promises.access(p);
7831
+ await import_node_fs25.promises.access(p);
7597
7832
  return true;
7598
7833
  } catch {
7599
7834
  return false;
7600
7835
  }
7601
7836
  }
7602
7837
  async function readPackageJson(scanPath) {
7603
- const pkgPath = import_node_path41.default.join(scanPath, "package.json");
7604
- const raw = await import_node_fs24.promises.readFile(pkgPath, "utf8");
7838
+ const pkgPath = import_node_path42.default.join(scanPath, "package.json");
7839
+ const raw = await import_node_fs25.promises.readFile(pkgPath, "utf8");
7605
7840
  return JSON.parse(raw);
7606
7841
  }
7607
7842
  async function findHookFiles(scanPath) {
7608
- const entries = await import_node_fs24.promises.readdir(scanPath);
7843
+ const entries = await import_node_fs25.promises.readdir(scanPath);
7609
7844
  return entries.filter(
7610
7845
  (e) => (e.startsWith("instrumentation") || e.startsWith("otel-init")) && /\.(ts|js)$/.test(e)
7611
7846
  ).sort();
7612
7847
  }
7613
7848
  function extendLogPath() {
7614
- return process.env.NEAT_EXTEND_LOG ?? import_node_path41.default.join(import_node_os2.default.homedir(), ".neat", "extend-log.ndjson");
7849
+ return process.env.NEAT_EXTEND_LOG ?? import_node_path42.default.join(import_node_os2.default.homedir(), ".neat", "extend-log.ndjson");
7615
7850
  }
7616
7851
  async function appendExtendLog(entry2) {
7617
7852
  const logPath = extendLogPath();
7618
- await import_node_fs24.promises.mkdir(import_node_path41.default.dirname(logPath), { recursive: true });
7619
- await import_node_fs24.promises.appendFile(logPath, JSON.stringify(entry2) + "\n", "utf8");
7853
+ await import_node_fs25.promises.mkdir(import_node_path42.default.dirname(logPath), { recursive: true });
7854
+ await import_node_fs25.promises.appendFile(logPath, JSON.stringify(entry2) + "\n", "utf8");
7620
7855
  }
7621
7856
  function splicedContent(fileContent, snippet2) {
7622
7857
  if (fileContent.includes("__INSTRUMENTATION_BLOCK__")) {
@@ -7674,7 +7909,7 @@ function lookupInstrumentation(library, installedVersion) {
7674
7909
  }
7675
7910
  async function describeProjectInstrumentation(ctx) {
7676
7911
  const hookFiles = await findHookFiles(ctx.scanPath);
7677
- const envNeat = await fileExists2(import_node_path41.default.join(ctx.scanPath, ".env.neat"));
7912
+ const envNeat = await fileExists2(import_node_path42.default.join(ctx.scanPath, ".env.neat"));
7678
7913
  const registryInstrPackages = new Set(
7679
7914
  (0, import_instrumentation_registry.list)().map((e) => e.instrumentation_package).filter((p) => !!p)
7680
7915
  );
@@ -7696,31 +7931,31 @@ async function applyExtension(ctx, args, options) {
7696
7931
  );
7697
7932
  }
7698
7933
  for (const file of hookFiles) {
7699
- const content = await import_node_fs24.promises.readFile(import_node_path41.default.join(ctx.scanPath, file), "utf8");
7934
+ const content = await import_node_fs25.promises.readFile(import_node_path42.default.join(ctx.scanPath, file), "utf8");
7700
7935
  if (content.includes(args.registration_snippet)) {
7701
7936
  return { library: args.library, filesTouched: [], depsAdded: [], installOutput: "", alreadyApplied: true };
7702
7937
  }
7703
7938
  }
7704
7939
  const primaryFile = hookFiles[0];
7705
- const primaryPath = import_node_path41.default.join(ctx.scanPath, primaryFile);
7940
+ const primaryPath = import_node_path42.default.join(ctx.scanPath, primaryFile);
7706
7941
  const filesTouched = [];
7707
7942
  const depsAdded = [];
7708
- const pkgPath = import_node_path41.default.join(ctx.scanPath, "package.json");
7943
+ const pkgPath = import_node_path42.default.join(ctx.scanPath, "package.json");
7709
7944
  const pkg = await readPackageJson(ctx.scanPath);
7710
7945
  if (!(pkg.dependencies ?? {})[args.instrumentation_package]) {
7711
7946
  pkg.dependencies = { ...pkg.dependencies ?? {}, [args.instrumentation_package]: args.version };
7712
- await import_node_fs24.promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
7947
+ await import_node_fs25.promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
7713
7948
  filesTouched.push("package.json");
7714
7949
  depsAdded.push(`${args.instrumentation_package}@${args.version}`);
7715
7950
  }
7716
- const hookContent = await import_node_fs24.promises.readFile(primaryPath, "utf8");
7951
+ const hookContent = await import_node_fs25.promises.readFile(primaryPath, "utf8");
7717
7952
  const patched = splicedContent(hookContent, args.registration_snippet);
7718
7953
  if (!patched) {
7719
7954
  throw new Error(
7720
7955
  `Could not find instrumentation insertion point in ${primaryFile}. Expected __INSTRUMENTATION_BLOCK__, instrumentations.push(, or new NodeSDK(.`
7721
7956
  );
7722
7957
  }
7723
- await import_node_fs24.promises.writeFile(primaryPath, patched, "utf8");
7958
+ await import_node_fs25.promises.writeFile(primaryPath, patched, "utf8");
7724
7959
  filesTouched.push(primaryFile);
7725
7960
  const cmd = await detectPackageManager(ctx.scanPath);
7726
7961
  const installer = options?.runInstall ?? runPackageManagerInstall;
@@ -7751,7 +7986,7 @@ async function dryRunExtension(ctx, args) {
7751
7986
  };
7752
7987
  }
7753
7988
  for (const file of hookFiles) {
7754
- const content = await import_node_fs24.promises.readFile(import_node_path41.default.join(ctx.scanPath, file), "utf8");
7989
+ const content = await import_node_fs25.promises.readFile(import_node_path42.default.join(ctx.scanPath, file), "utf8");
7755
7990
  if (content.includes(args.registration_snippet)) {
7756
7991
  return {
7757
7992
  library: args.library,
@@ -7773,7 +8008,7 @@ async function dryRunExtension(ctx, args) {
7773
8008
  depsToAdd.push(`${args.instrumentation_package}@${args.version}`);
7774
8009
  filesTouched.push("package.json");
7775
8010
  }
7776
- const hookContent = await import_node_fs24.promises.readFile(import_node_path41.default.join(ctx.scanPath, primaryFile), "utf8");
8011
+ const hookContent = await import_node_fs25.promises.readFile(import_node_path42.default.join(ctx.scanPath, primaryFile), "utf8");
7777
8012
  const patched = splicedContent(hookContent, args.registration_snippet);
7778
8013
  if (patched) {
7779
8014
  filesTouched.push(primaryFile);
@@ -7788,28 +8023,28 @@ async function rollbackExtension(ctx, args) {
7788
8023
  if (!await fileExists2(logPath)) {
7789
8024
  return { undone: false, message: "no apply found for library" };
7790
8025
  }
7791
- const raw = await import_node_fs24.promises.readFile(logPath, "utf8");
8026
+ const raw = await import_node_fs25.promises.readFile(logPath, "utf8");
7792
8027
  const entries = raw.trim().split("\n").filter(Boolean).map((line) => JSON.parse(line));
7793
8028
  const match = [...entries].reverse().find((e) => e.project === ctx.project && e.library === args.library);
7794
8029
  if (!match) {
7795
8030
  return { undone: false, message: "no apply found for library" };
7796
8031
  }
7797
- const pkgPath = import_node_path41.default.join(ctx.scanPath, "package.json");
8032
+ const pkgPath = import_node_path42.default.join(ctx.scanPath, "package.json");
7798
8033
  if (await fileExists2(pkgPath)) {
7799
8034
  const pkg = await readPackageJson(ctx.scanPath);
7800
8035
  if (pkg.dependencies?.[match.instrumentation_package]) {
7801
8036
  const { [match.instrumentation_package]: _removed, ...rest } = pkg.dependencies;
7802
8037
  pkg.dependencies = rest;
7803
- await import_node_fs24.promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
8038
+ await import_node_fs25.promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
7804
8039
  }
7805
8040
  }
7806
8041
  const hookFiles = await findHookFiles(ctx.scanPath);
7807
8042
  for (const file of hookFiles) {
7808
- const filePath = import_node_path41.default.join(ctx.scanPath, file);
7809
- const content = await import_node_fs24.promises.readFile(filePath, "utf8");
8043
+ const filePath = import_node_path42.default.join(ctx.scanPath, file);
8044
+ const content = await import_node_fs25.promises.readFile(filePath, "utf8");
7810
8045
  if (content.includes(match.registration_snippet)) {
7811
8046
  const filtered = content.split("\n").filter((line) => !line.includes(match.registration_snippet)).join("\n");
7812
- await import_node_fs24.promises.writeFile(filePath, filtered, "utf8");
8047
+ await import_node_fs25.promises.writeFile(filePath, filtered, "utf8");
7813
8048
  break;
7814
8049
  }
7815
8050
  }
@@ -7866,7 +8101,7 @@ function queryLogEntries(opts) {
7866
8101
 
7867
8102
  // src/diff.ts
7868
8103
  init_cjs_shims();
7869
- var import_node_fs25 = require("fs");
8104
+ var import_node_fs26 = require("fs");
7870
8105
  async function loadSnapshotForDiff(target) {
7871
8106
  if (/^https?:\/\//i.test(target)) {
7872
8107
  const res = await fetch(target);
@@ -7875,7 +8110,7 @@ async function loadSnapshotForDiff(target) {
7875
8110
  }
7876
8111
  return await res.json();
7877
8112
  }
7878
- const raw = await import_node_fs25.promises.readFile(target, "utf8");
8113
+ const raw = await import_node_fs26.promises.readFile(target, "utf8");
7879
8114
  return JSON.parse(raw);
7880
8115
  }
7881
8116
  function indexEntries(entries) {
@@ -7943,23 +8178,23 @@ function canonicalJson(value) {
7943
8178
 
7944
8179
  // src/projects.ts
7945
8180
  init_cjs_shims();
7946
- var import_node_path42 = __toESM(require("path"), 1);
8181
+ var import_node_path43 = __toESM(require("path"), 1);
7947
8182
  function pathsForProject(project, baseDir) {
7948
8183
  if (project === DEFAULT_PROJECT) {
7949
8184
  return {
7950
- snapshotPath: import_node_path42.default.join(baseDir, "graph.json"),
7951
- errorsPath: import_node_path42.default.join(baseDir, "errors.ndjson"),
7952
- staleEventsPath: import_node_path42.default.join(baseDir, "stale-events.ndjson"),
7953
- embeddingsCachePath: import_node_path42.default.join(baseDir, "embeddings.json"),
7954
- policyViolationsPath: import_node_path42.default.join(baseDir, "policy-violations.ndjson")
8185
+ snapshotPath: import_node_path43.default.join(baseDir, "graph.json"),
8186
+ errorsPath: import_node_path43.default.join(baseDir, "errors.ndjson"),
8187
+ staleEventsPath: import_node_path43.default.join(baseDir, "stale-events.ndjson"),
8188
+ embeddingsCachePath: import_node_path43.default.join(baseDir, "embeddings.json"),
8189
+ policyViolationsPath: import_node_path43.default.join(baseDir, "policy-violations.ndjson")
7955
8190
  };
7956
8191
  }
7957
8192
  return {
7958
- snapshotPath: import_node_path42.default.join(baseDir, `${project}.json`),
7959
- errorsPath: import_node_path42.default.join(baseDir, `errors.${project}.ndjson`),
7960
- staleEventsPath: import_node_path42.default.join(baseDir, `stale-events.${project}.ndjson`),
7961
- embeddingsCachePath: import_node_path42.default.join(baseDir, `embeddings.${project}.json`),
7962
- policyViolationsPath: import_node_path42.default.join(baseDir, `policy-violations.${project}.ndjson`)
8193
+ snapshotPath: import_node_path43.default.join(baseDir, `${project}.json`),
8194
+ errorsPath: import_node_path43.default.join(baseDir, `errors.${project}.ndjson`),
8195
+ staleEventsPath: import_node_path43.default.join(baseDir, `stale-events.${project}.ndjson`),
8196
+ embeddingsCachePath: import_node_path43.default.join(baseDir, `embeddings.${project}.json`),
8197
+ policyViolationsPath: import_node_path43.default.join(baseDir, `policy-violations.${project}.ndjson`)
7963
8198
  };
7964
8199
  }
7965
8200
  var Projects = class {
@@ -7995,28 +8230,28 @@ var Projects = class {
7995
8230
 
7996
8231
  // src/registry.ts
7997
8232
  init_cjs_shims();
7998
- var import_node_fs26 = require("fs");
8233
+ var import_node_fs27 = require("fs");
7999
8234
  var import_node_os3 = __toESM(require("os"), 1);
8000
- var import_node_path43 = __toESM(require("path"), 1);
8001
- var import_types29 = require("@neat.is/types");
8235
+ var import_node_path44 = __toESM(require("path"), 1);
8236
+ var import_types30 = require("@neat.is/types");
8002
8237
  var LOCK_TIMEOUT_MS = 5e3;
8003
8238
  var LOCK_RETRY_MS = 50;
8004
8239
  function neatHome() {
8005
8240
  const override = process.env.NEAT_HOME;
8006
- if (override && override.length > 0) return import_node_path43.default.resolve(override);
8007
- return import_node_path43.default.join(import_node_os3.default.homedir(), ".neat");
8241
+ if (override && override.length > 0) return import_node_path44.default.resolve(override);
8242
+ return import_node_path44.default.join(import_node_os3.default.homedir(), ".neat");
8008
8243
  }
8009
8244
  function registryPath() {
8010
- return import_node_path43.default.join(neatHome(), "projects.json");
8245
+ return import_node_path44.default.join(neatHome(), "projects.json");
8011
8246
  }
8012
8247
  function registryLockPath() {
8013
- return import_node_path43.default.join(neatHome(), "projects.json.lock");
8248
+ return import_node_path44.default.join(neatHome(), "projects.json.lock");
8014
8249
  }
8015
8250
  function daemonPidPath() {
8016
- return import_node_path43.default.join(neatHome(), "neatd.pid");
8251
+ return import_node_path44.default.join(neatHome(), "neatd.pid");
8017
8252
  }
8018
8253
  function daemonsDir() {
8019
- return import_node_path43.default.join(neatHome(), "daemons");
8254
+ return import_node_path44.default.join(neatHome(), "daemons");
8020
8255
  }
8021
8256
  function isFiniteInt(v) {
8022
8257
  return typeof v === "number" && Number.isFinite(v);
@@ -8049,7 +8284,7 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
8049
8284
  const dir = daemonsDir();
8050
8285
  let names;
8051
8286
  try {
8052
- names = await import_node_fs26.promises.readdir(dir);
8287
+ names = await import_node_fs27.promises.readdir(dir);
8053
8288
  } catch (err) {
8054
8289
  if (err.code === "ENOENT") return [];
8055
8290
  throw err;
@@ -8057,10 +8292,10 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
8057
8292
  const out = [];
8058
8293
  for (const name of names) {
8059
8294
  if (!name.endsWith(".json")) continue;
8060
- const file = import_node_path43.default.join(dir, name);
8295
+ const file = import_node_path44.default.join(dir, name);
8061
8296
  let raw;
8062
8297
  try {
8063
- raw = await import_node_fs26.promises.readFile(file, "utf8");
8298
+ raw = await import_node_fs27.promises.readFile(file, "utf8");
8064
8299
  } catch {
8065
8300
  continue;
8066
8301
  }
@@ -8073,7 +8308,7 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
8073
8308
  return out;
8074
8309
  }
8075
8310
  async function removeDaemonRecord(source) {
8076
- await import_node_fs26.promises.unlink(source).catch(() => {
8311
+ await import_node_fs27.promises.unlink(source).catch(() => {
8077
8312
  });
8078
8313
  }
8079
8314
  async function listMachineProjects(probe = defaultDiscoveryProbe) {
@@ -8130,7 +8365,7 @@ function isPidAliveDefault(pid) {
8130
8365
  }
8131
8366
  async function readPidFile(file) {
8132
8367
  try {
8133
- const raw = await import_node_fs26.promises.readFile(file, "utf8");
8368
+ const raw = await import_node_fs27.promises.readFile(file, "utf8");
8134
8369
  const pid = Number.parseInt(raw.trim(), 10);
8135
8370
  return Number.isInteger(pid) && pid > 0 ? pid : void 0;
8136
8371
  } catch {
@@ -8178,32 +8413,32 @@ function lockHolderMessage(holder, lockPath, timeoutMs) {
8178
8413
  }
8179
8414
  }
8180
8415
  async function normalizeProjectPath(input) {
8181
- const resolved = import_node_path43.default.resolve(input);
8416
+ const resolved = import_node_path44.default.resolve(input);
8182
8417
  try {
8183
- return await import_node_fs26.promises.realpath(resolved);
8418
+ return await import_node_fs27.promises.realpath(resolved);
8184
8419
  } catch {
8185
8420
  return resolved;
8186
8421
  }
8187
8422
  }
8188
8423
  async function writeAtomically(target, contents) {
8189
- await import_node_fs26.promises.mkdir(import_node_path43.default.dirname(target), { recursive: true });
8424
+ await import_node_fs27.promises.mkdir(import_node_path44.default.dirname(target), { recursive: true });
8190
8425
  const tmp = `${target}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
8191
- const fd = await import_node_fs26.promises.open(tmp, "w");
8426
+ const fd = await import_node_fs27.promises.open(tmp, "w");
8192
8427
  try {
8193
8428
  await fd.writeFile(contents, "utf8");
8194
8429
  await fd.sync();
8195
8430
  } finally {
8196
8431
  await fd.close();
8197
8432
  }
8198
- await import_node_fs26.promises.rename(tmp, target);
8433
+ await import_node_fs27.promises.rename(tmp, target);
8199
8434
  }
8200
8435
  async function acquireLock(lockPath, timeoutMs = LOCK_TIMEOUT_MS, probe = defaultLockHolderProbe) {
8201
8436
  const deadline = Date.now() + timeoutMs;
8202
- await import_node_fs26.promises.mkdir(import_node_path43.default.dirname(lockPath), { recursive: true });
8437
+ await import_node_fs27.promises.mkdir(import_node_path44.default.dirname(lockPath), { recursive: true });
8203
8438
  let probedHolder = false;
8204
8439
  while (true) {
8205
8440
  try {
8206
- const fd = await import_node_fs26.promises.open(lockPath, "wx");
8441
+ const fd = await import_node_fs27.promises.open(lockPath, "wx");
8207
8442
  try {
8208
8443
  await fd.writeFile(`${process.pid}
8209
8444
  `, "utf8");
@@ -8228,7 +8463,7 @@ async function acquireLock(lockPath, timeoutMs = LOCK_TIMEOUT_MS, probe = defaul
8228
8463
  }
8229
8464
  }
8230
8465
  async function releaseLock(lockPath) {
8231
- await import_node_fs26.promises.unlink(lockPath).catch(() => {
8466
+ await import_node_fs27.promises.unlink(lockPath).catch(() => {
8232
8467
  });
8233
8468
  }
8234
8469
  async function withLock(fn) {
@@ -8244,7 +8479,7 @@ async function readRegistry() {
8244
8479
  const file = registryPath();
8245
8480
  let raw;
8246
8481
  try {
8247
- raw = await import_node_fs26.promises.readFile(file, "utf8");
8482
+ raw = await import_node_fs27.promises.readFile(file, "utf8");
8248
8483
  } catch (err) {
8249
8484
  if (err.code === "ENOENT") {
8250
8485
  return { version: 1, projects: [] };
@@ -8252,10 +8487,10 @@ async function readRegistry() {
8252
8487
  throw err;
8253
8488
  }
8254
8489
  const parsed = JSON.parse(raw);
8255
- return import_types29.RegistryFileSchema.parse(parsed);
8490
+ return import_types30.RegistryFileSchema.parse(parsed);
8256
8491
  }
8257
8492
  async function writeRegistry(reg) {
8258
- const validated = import_types29.RegistryFileSchema.parse(reg);
8493
+ const validated = import_types30.RegistryFileSchema.parse(reg);
8259
8494
  await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
8260
8495
  }
8261
8496
  var ProjectNameCollisionError = class extends Error {
@@ -8340,7 +8575,7 @@ function pruneTtlMs() {
8340
8575
  }
8341
8576
  async function statPathStatus(p) {
8342
8577
  try {
8343
- const stat = await import_node_fs26.promises.stat(p);
8578
+ const stat = await import_node_fs27.promises.stat(p);
8344
8579
  return stat.isDirectory() ? "present" : "unknown";
8345
8580
  } catch (err) {
8346
8581
  return err.code === "ENOENT" ? "gone" : "unknown";
@@ -8587,11 +8822,11 @@ function registerRoutes(scope, ctx) {
8587
8822
  const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
8588
8823
  const parsed = [];
8589
8824
  for (const c of candidates) {
8590
- const r = import_types30.DivergenceTypeSchema.safeParse(c);
8825
+ const r = import_types31.DivergenceTypeSchema.safeParse(c);
8591
8826
  if (!r.success) {
8592
8827
  return reply.code(400).send({
8593
8828
  error: `unknown divergence type "${c}"`,
8594
- allowed: import_types30.DivergenceTypeSchema.options
8829
+ allowed: import_types31.DivergenceTypeSchema.options
8595
8830
  });
8596
8831
  }
8597
8832
  parsed.push(r.data);
@@ -8842,7 +9077,7 @@ function registerRoutes(scope, ctx) {
8842
9077
  const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
8843
9078
  let violations = await log.readAll();
8844
9079
  if (req.query.severity) {
8845
- const sev = import_types30.PolicySeveritySchema.safeParse(req.query.severity);
9080
+ const sev = import_types31.PolicySeveritySchema.safeParse(req.query.severity);
8846
9081
  if (!sev.success) {
8847
9082
  return reply.code(400).send({
8848
9083
  error: "invalid severity",
@@ -8881,7 +9116,7 @@ function registerRoutes(scope, ctx) {
8881
9116
  scope.post("/policies/check", async (req, reply) => {
8882
9117
  const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
8883
9118
  if (!proj) return;
8884
- const parsed = import_types30.PoliciesCheckBodySchema.safeParse(req.body ?? {});
9119
+ const parsed = import_types31.PoliciesCheckBodySchema.safeParse(req.body ?? {});
8885
9120
  if (!parsed.success) {
8886
9121
  return reply.code(400).send({
8887
9122
  error: "invalid /policies/check body",
@@ -9143,8 +9378,8 @@ init_otel();
9143
9378
 
9144
9379
  // src/daemon.ts
9145
9380
  init_cjs_shims();
9146
- var import_node_fs29 = require("fs");
9147
- var import_node_path48 = __toESM(require("path"), 1);
9381
+ var import_node_fs30 = require("fs");
9382
+ var import_node_path49 = __toESM(require("path"), 1);
9148
9383
  var import_node_module = require("module");
9149
9384
  init_otel();
9150
9385
 
@@ -9489,10 +9724,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
9489
9724
  // src/connectors/supabase/map.ts
9490
9725
  var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
9491
9726
  var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
9492
- function targetFromRestPath(path57) {
9493
- const rpcMatch = REST_RPC_PATH_RE.exec(path57);
9727
+ function targetFromRestPath(path58) {
9728
+ const rpcMatch = REST_RPC_PATH_RE.exec(path58);
9494
9729
  if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
9495
- const tableMatch = REST_TABLE_PATH_RE.exec(path57);
9730
+ const tableMatch = REST_TABLE_PATH_RE.exec(path58);
9496
9731
  if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
9497
9732
  return null;
9498
9733
  }
@@ -9595,19 +9830,19 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
9595
9830
 
9596
9831
  // src/connectors/supabase/resolve.ts
9597
9832
  init_cjs_shims();
9598
- var import_types32 = require("@neat.is/types");
9833
+ var import_types33 = require("@neat.is/types");
9599
9834
  function createSupabaseResolveTarget(graph, config) {
9600
9835
  return (signal, _ctx) => {
9601
9836
  if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
9602
9837
  return null;
9603
9838
  }
9604
- const subResourceId = (0, import_types32.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
9839
+ const subResourceId = (0, import_types33.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
9605
9840
  if (graph.hasNode(subResourceId)) {
9606
- return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types32.EdgeType.CALLS };
9841
+ return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types33.EdgeType.CALLS };
9607
9842
  }
9608
- const projectLevelId = (0, import_types32.infraId)("supabase", config.nodeRef);
9843
+ const projectLevelId = (0, import_types33.infraId)("supabase", config.nodeRef);
9609
9844
  if (graph.hasNode(projectLevelId)) {
9610
- return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types32.EdgeType.CALLS };
9845
+ return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types33.EdgeType.CALLS };
9611
9846
  }
9612
9847
  return null;
9613
9848
  };
@@ -9665,7 +9900,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
9665
9900
 
9666
9901
  // src/connectors/railway/index.ts
9667
9902
  init_cjs_shims();
9668
- var import_types36 = require("@neat.is/types");
9903
+ var import_types37 = require("@neat.is/types");
9669
9904
 
9670
9905
  // src/connectors/railway/client.ts
9671
9906
  init_cjs_shims();
@@ -9810,7 +10045,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
9810
10045
  const out = [];
9811
10046
  graph.forEachNode((_id, attrs) => {
9812
10047
  const node = attrs;
9813
- if (node.type !== import_types36.NodeType.RouteNode) return;
10048
+ if (node.type !== import_types37.NodeType.RouteNode) return;
9814
10049
  const route = attrs;
9815
10050
  if (route.service !== serviceName) return;
9816
10051
  out.push({
@@ -9906,12 +10141,12 @@ function createRailwayResolveTarget(config) {
9906
10141
  const serviceName = config.serviceNameById[config.serviceId];
9907
10142
  if (!serviceName) return null;
9908
10143
  if (signal.targetKind === ROUTE_TARGET_KIND) {
9909
- return { targetNodeId: signal.targetName, serviceName, edgeType: import_types36.EdgeType.CALLS };
10144
+ return { targetNodeId: signal.targetName, serviceName, edgeType: import_types37.EdgeType.CALLS };
9910
10145
  }
9911
10146
  if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
9912
10147
  const peerName = config.serviceNameById[signal.targetName];
9913
10148
  if (!peerName) return null;
9914
- return { targetNodeId: (0, import_types36.serviceId)(peerName), serviceName, edgeType: import_types36.EdgeType.CONNECTS_TO };
10149
+ return { targetNodeId: (0, import_types37.serviceId)(peerName), serviceName, edgeType: import_types37.EdgeType.CONNECTS_TO };
9915
10150
  }
9916
10151
  return null;
9917
10152
  };
@@ -10026,9 +10261,9 @@ function parseFirebaseTargetName(targetName) {
10026
10261
  const secondSep = rest.indexOf(FIELD_SEP);
10027
10262
  if (secondSep === -1) return null;
10028
10263
  const method = rest.slice(0, secondSep);
10029
- const path57 = rest.slice(secondSep + 1);
10030
- if (!resourceName || !method || !path57) return null;
10031
- return { resourceName, method, path: path57 };
10264
+ const path58 = rest.slice(secondSep + 1);
10265
+ if (!resourceName || !method || !path58) return null;
10266
+ return { resourceName, method, path: path58 };
10032
10267
  }
10033
10268
  function resourceNameFor(type, labels) {
10034
10269
  if (!labels) return null;
@@ -10065,14 +10300,14 @@ function mapLogEntryToSignal(entry2) {
10065
10300
  if (!req) return null;
10066
10301
  if (!req.requestMethod) return null;
10067
10302
  const method = req.requestMethod.toUpperCase();
10068
- const path57 = pathFromRequestUrl(req.requestUrl);
10069
- if (path57 === null) return null;
10303
+ const path58 = pathFromRequestUrl(req.requestUrl);
10304
+ if (path58 === null) return null;
10070
10305
  const timestamp = entry2.timestamp;
10071
10306
  if (!timestamp) return null;
10072
10307
  const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
10073
10308
  return {
10074
10309
  targetKind: resourceType,
10075
- targetName: packFirebaseTargetName({ resourceName, method, path: path57 }),
10310
+ targetName: packFirebaseTargetName({ resourceName, method, path: path58 }),
10076
10311
  callCount: 1,
10077
10312
  errorCount: isError ? 1 : 0,
10078
10313
  lastObservedIso: timestamp
@@ -10089,7 +10324,7 @@ function mapLogEntriesToSignals(entries) {
10089
10324
 
10090
10325
  // src/connectors/firebase/resolve.ts
10091
10326
  init_cjs_shims();
10092
- var import_types37 = require("@neat.is/types");
10327
+ var import_types38 = require("@neat.is/types");
10093
10328
  function neatServiceNameFor(resourceType, resourceName, serviceMap) {
10094
10329
  switch (resourceType) {
10095
10330
  case "cloud_function":
@@ -10104,7 +10339,7 @@ function routeEntriesFor(graph, serviceName) {
10104
10339
  const entries = [];
10105
10340
  graph.forEachNode((_id, attrs) => {
10106
10341
  const node = attrs;
10107
- if (node.type !== import_types37.NodeType.RouteNode) return;
10342
+ if (node.type !== import_types38.NodeType.RouteNode) return;
10108
10343
  const route = attrs;
10109
10344
  if (route.service !== serviceName) return;
10110
10345
  entries.push({
@@ -10136,7 +10371,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
10136
10371
  return {
10137
10372
  targetNodeId: match.routeNodeId,
10138
10373
  serviceName,
10139
- edgeType: import_types37.EdgeType.CALLS
10374
+ edgeType: import_types38.EdgeType.CALLS
10140
10375
  };
10141
10376
  };
10142
10377
  }
@@ -10163,7 +10398,7 @@ init_cjs_shims();
10163
10398
 
10164
10399
  // src/connectors/cloudflare/connector.ts
10165
10400
  init_cjs_shims();
10166
- var import_types39 = require("@neat.is/types");
10401
+ var import_types40 = require("@neat.is/types");
10167
10402
 
10168
10403
  // src/connectors/cloudflare/client.ts
10169
10404
  init_cjs_shims();
@@ -10213,7 +10448,14 @@ async function queryWorkerInvocations(ctx, config, window, fetchImpl = fetch) {
10213
10448
  const message = payload.errors?.map((e) => e.message).join("; ") || "unknown error";
10214
10449
  throw new Error(`cloudflare connector: telemetry query returned an error (${message})`);
10215
10450
  }
10216
- return payload.result?.events?.events ?? [];
10451
+ const events = payload.result?.events?.events;
10452
+ if (events === void 0) {
10453
+ console.warn(
10454
+ "[neat connector] cloudflare: telemetry query returned success:true but no result.events.events array \u2014 the response shape may have changed; treating as zero events this tick"
10455
+ );
10456
+ return [];
10457
+ }
10458
+ return events;
10217
10459
  }
10218
10460
 
10219
10461
  // src/connectors/cloudflare/map.ts
@@ -10244,6 +10486,13 @@ function parseHttpMethodFromTrigger(trigger) {
10244
10486
  const method = token.toUpperCase();
10245
10487
  return HTTP_METHODS.has(method) ? method : null;
10246
10488
  }
10489
+ function parsePathFromTrigger(trigger) {
10490
+ const trimmed = trigger.trim();
10491
+ const spaceIdx = trimmed.indexOf(" ");
10492
+ if (spaceIdx === -1) return void 0;
10493
+ const rest = trimmed.slice(spaceIdx + 1).trim();
10494
+ return rest.length > 0 ? rest : void 0;
10495
+ }
10247
10496
  var ERROR_STATUS_THRESHOLD3 = 500;
10248
10497
  function mapEventToSignal(event) {
10249
10498
  const metadata = event.$metadata;
@@ -10256,6 +10505,7 @@ function mapEventToSignal(event) {
10256
10505
  if (typeof timestampMs !== "number" || !Number.isFinite(timestampMs)) return null;
10257
10506
  const statusCode = metadata?.statusCode;
10258
10507
  const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
10508
+ const path58 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
10259
10509
  return {
10260
10510
  targetKind: CLOUDFLARE_TARGET_KIND,
10261
10511
  targetName: scriptName,
@@ -10263,6 +10513,7 @@ function mapEventToSignal(event) {
10263
10513
  errorCount: isError ? 1 : 0,
10264
10514
  lastObservedIso: new Date(timestampMs).toISOString(),
10265
10515
  method,
10516
+ ...path58 ? { path: path58 } : {},
10266
10517
  ...typeof statusCode === "number" ? { statusCode } : {},
10267
10518
  ...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
10268
10519
  };
@@ -10297,15 +10548,63 @@ var CloudflareConnector = class {
10297
10548
  return signals;
10298
10549
  }
10299
10550
  };
10300
- function createCloudflareResolveTarget(config) {
10551
+ function findTaggedWorkerFileNode(graph, workerName) {
10552
+ let found = null;
10553
+ graph.forEachNode((id, attrs) => {
10554
+ if (found) return;
10555
+ const a = attrs;
10556
+ if (a.type === import_types40.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
10557
+ found = id;
10558
+ }
10559
+ });
10560
+ return found;
10561
+ }
10562
+ function findMatchingRouteNode(graph, serviceName, method, path58) {
10563
+ const normalizedPath = normalizePathTemplate(path58);
10564
+ let found = null;
10565
+ graph.forEachNode((id, attrs) => {
10566
+ if (found) return;
10567
+ const a = attrs;
10568
+ if (a.type !== import_types40.NodeType.RouteNode || a.service !== serviceName) return;
10569
+ if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
10570
+ const routeMethod = (a.method ?? "").toUpperCase();
10571
+ if (routeMethod !== "ALL" && routeMethod !== method) return;
10572
+ found = id;
10573
+ });
10574
+ return found;
10575
+ }
10576
+ function createCloudflareResolveTarget(config, graph) {
10301
10577
  return (signal) => {
10302
10578
  if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
10303
- const mapping = config.workers[signal.targetName];
10304
- if (!mapping) return null;
10579
+ const scriptName = signal.targetName;
10580
+ const { method, path: path58 } = signal;
10581
+ const resolveRouteGrain = (serviceName, wholeFileId) => {
10582
+ if (!method || !path58) return wholeFileId;
10583
+ return findMatchingRouteNode(graph, serviceName, method, path58) ?? wholeFileId;
10584
+ };
10585
+ const mapping = config.workers?.[scriptName];
10586
+ if (mapping) {
10587
+ const wholeFileId = (0, import_types40.fileId)(mapping.service, mapping.entryFile);
10588
+ return {
10589
+ targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
10590
+ serviceName: mapping.service,
10591
+ edgeType: import_types40.EdgeType.CALLS
10592
+ };
10593
+ }
10594
+ const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
10595
+ if (taggedFileId) {
10596
+ const fileNode = graph.getNodeAttributes(taggedFileId);
10597
+ return {
10598
+ targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
10599
+ serviceName: fileNode.service,
10600
+ edgeType: import_types40.EdgeType.CALLS
10601
+ };
10602
+ }
10305
10603
  return {
10306
- targetNodeId: (0, import_types39.fileId)(mapping.service, mapping.entryFile),
10307
- serviceName: mapping.service,
10308
- edgeType: import_types39.EdgeType.CALLS
10604
+ targetNodeId: (0, import_types40.infraId)("cloudflare-worker", scriptName),
10605
+ serviceName: scriptName,
10606
+ edgeType: import_types40.EdgeType.CALLS,
10607
+ ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
10309
10608
  };
10310
10609
  };
10311
10610
  }
@@ -10313,8 +10612,8 @@ function createCloudflareResolveTarget(config) {
10313
10612
  // src/connectors-config.ts
10314
10613
  init_cjs_shims();
10315
10614
  var import_node_os4 = __toESM(require("os"), 1);
10316
- var import_node_path46 = __toESM(require("path"), 1);
10317
- var import_node_fs27 = require("fs");
10615
+ var import_node_path47 = __toESM(require("path"), 1);
10616
+ var import_node_fs28 = require("fs");
10318
10617
  var CONNECTORS_CONFIG_VERSION = 1;
10319
10618
  var EnvRefUnsetError = class extends Error {
10320
10619
  ref;
@@ -10328,17 +10627,17 @@ var EnvRefUnsetError = class extends Error {
10328
10627
  };
10329
10628
  function neatHome2() {
10330
10629
  const override = process.env.NEAT_HOME;
10331
- if (override && override.length > 0) return import_node_path46.default.resolve(override);
10332
- return import_node_path46.default.join(import_node_os4.default.homedir(), ".neat");
10630
+ if (override && override.length > 0) return import_node_path47.default.resolve(override);
10631
+ return import_node_path47.default.join(import_node_os4.default.homedir(), ".neat");
10333
10632
  }
10334
10633
  function connectorsConfigPath(home = neatHome2()) {
10335
- return import_node_path46.default.join(home, "connectors.json");
10634
+ return import_node_path47.default.join(home, "connectors.json");
10336
10635
  }
10337
10636
  var MODE_MASK_LOOSER_THAN_0600 = 63;
10338
10637
  async function warnIfModeLooserThan0600(file) {
10339
10638
  if (process.platform === "win32") return;
10340
10639
  try {
10341
- const stat = await import_node_fs27.promises.stat(file);
10640
+ const stat = await import_node_fs28.promises.stat(file);
10342
10641
  if ((stat.mode & MODE_MASK_LOOSER_THAN_0600) !== 0) {
10343
10642
  const mode = (stat.mode & 511).toString(8).padStart(3, "0");
10344
10643
  console.warn(
@@ -10352,7 +10651,7 @@ async function readConnectorsConfig(home = neatHome2()) {
10352
10651
  const file = connectorsConfigPath(home);
10353
10652
  let raw;
10354
10653
  try {
10355
- raw = await import_node_fs27.promises.readFile(file, "utf8");
10654
+ raw = await import_node_fs28.promises.readFile(file, "utf8");
10356
10655
  } catch (err) {
10357
10656
  if (err.code === "ENOENT") {
10358
10657
  return { version: CONNECTORS_CONFIG_VERSION, connectors: [] };
@@ -10460,15 +10759,15 @@ function resolveRef(value, env) {
10460
10759
  var CONNECTORS_LOCK_TIMEOUT_MS = 5e3;
10461
10760
  var CONNECTORS_LOCK_RETRY_MS = 50;
10462
10761
  function connectorsConfigLockPath(home = neatHome2()) {
10463
- return import_node_path46.default.join(home, "connectors.json.lock");
10762
+ return import_node_path47.default.join(home, "connectors.json.lock");
10464
10763
  }
10465
10764
  function isEnvRef(value) {
10466
10765
  return value.length > 1 && value.startsWith("$");
10467
10766
  }
10468
10767
  async function writeConfigAtomically0600(file, contents) {
10469
- await import_node_fs27.promises.mkdir(import_node_path46.default.dirname(file), { recursive: true });
10768
+ await import_node_fs28.promises.mkdir(import_node_path47.default.dirname(file), { recursive: true });
10470
10769
  const tmp = `${file}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
10471
- const fd = await import_node_fs27.promises.open(tmp, "w", 384);
10770
+ const fd = await import_node_fs28.promises.open(tmp, "w", 384);
10472
10771
  try {
10473
10772
  await fd.writeFile(contents, "utf8");
10474
10773
  await fd.chmod(384);
@@ -10476,14 +10775,14 @@ async function writeConfigAtomically0600(file, contents) {
10476
10775
  } finally {
10477
10776
  await fd.close();
10478
10777
  }
10479
- await import_node_fs27.promises.rename(tmp, file);
10778
+ await import_node_fs28.promises.rename(tmp, file);
10480
10779
  }
10481
10780
  async function acquireConnectorsLock(lockPath, timeoutMs = CONNECTORS_LOCK_TIMEOUT_MS) {
10482
10781
  const deadline = Date.now() + timeoutMs;
10483
- await import_node_fs27.promises.mkdir(import_node_path46.default.dirname(lockPath), { recursive: true });
10782
+ await import_node_fs28.promises.mkdir(import_node_path47.default.dirname(lockPath), { recursive: true });
10484
10783
  for (; ; ) {
10485
10784
  try {
10486
- const fd = await import_node_fs27.promises.open(lockPath, "wx");
10785
+ const fd = await import_node_fs28.promises.open(lockPath, "wx");
10487
10786
  try {
10488
10787
  await fd.writeFile(`${process.pid}
10489
10788
  `, "utf8");
@@ -10503,7 +10802,7 @@ async function acquireConnectorsLock(lockPath, timeoutMs = CONNECTORS_LOCK_TIMEO
10503
10802
  }
10504
10803
  }
10505
10804
  async function releaseConnectorsLock(lockPath) {
10506
- await import_node_fs27.promises.unlink(lockPath).catch(() => {
10805
+ await import_node_fs28.promises.unlink(lockPath).catch(() => {
10507
10806
  });
10508
10807
  }
10509
10808
  async function withConnectorsLock(home, fn) {
@@ -10695,12 +10994,16 @@ var PROVIDER_DISPATCH = {
10695
10994
  provider: "cloudflare",
10696
10995
  primaryCredentialKey: "apiToken",
10697
10996
  requiredCredentialFields: ["apiToken"],
10698
- requiredOptionFields: ["accountId", "workers"],
10699
- build(_graph, options) {
10997
+ // `workers` dropped as a required field (ADR-133) — the mapping is now
10998
+ // derived from the extracted graph's platform tag; an `options.workers`
10999
+ // entry still works as an explicit override
11000
+ // (CloudflareConnectorConfig.workers).
11001
+ requiredOptionFields: ["accountId"],
11002
+ build(graph, options) {
10700
11003
  const config = options;
10701
11004
  return {
10702
11005
  connector: new CloudflareConnector(config),
10703
- resolveTarget: createCloudflareResolveTarget(config)
11006
+ resolveTarget: createCloudflareResolveTarget(config, graph)
10704
11007
  };
10705
11008
  },
10706
11009
  // GET /user/tokens/verify — Cloudflare's own purpose-built "is this API
@@ -10771,33 +11074,33 @@ init_auth();
10771
11074
 
10772
11075
  // src/unrouted.ts
10773
11076
  init_cjs_shims();
10774
- var import_node_fs28 = require("fs");
10775
- var import_node_path47 = __toESM(require("path"), 1);
11077
+ var import_node_fs29 = require("fs");
11078
+ var import_node_path48 = __toESM(require("path"), 1);
10776
11079
 
10777
11080
  // src/daemon.ts
10778
- var import_types42 = require("@neat.is/types");
11081
+ var import_types43 = require("@neat.is/types");
10779
11082
  function daemonJsonPath(scanPath) {
10780
- return import_node_path48.default.join(scanPath, "neat-out", "daemon.json");
11083
+ return import_node_path49.default.join(scanPath, "neat-out", "daemon.json");
10781
11084
  }
10782
11085
  function daemonsDiscoveryDir(home) {
10783
11086
  const base = home && home.length > 0 ? home : neatHomeFromEnv();
10784
- return import_node_path48.default.join(base, "daemons");
11087
+ return import_node_path49.default.join(base, "daemons");
10785
11088
  }
10786
11089
  function daemonDiscoveryPath(project, home) {
10787
- return import_node_path48.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
11090
+ return import_node_path49.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
10788
11091
  }
10789
11092
  function sanitizeDiscoveryName(project) {
10790
11093
  return project.replace(/[^A-Za-z0-9._-]/g, "_");
10791
11094
  }
10792
11095
  function neatHomeFromEnv() {
10793
11096
  const env = process.env.NEAT_HOME;
10794
- if (env && env.length > 0) return import_node_path48.default.resolve(env);
11097
+ if (env && env.length > 0) return import_node_path49.default.resolve(env);
10795
11098
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
10796
- return import_node_path48.default.join(home, ".neat");
11099
+ return import_node_path49.default.join(home, ".neat");
10797
11100
  }
10798
11101
  async function readDaemonRecord(scanPath) {
10799
11102
  try {
10800
- const raw = await import_node_fs29.promises.readFile(daemonJsonPath(scanPath), "utf8");
11103
+ const raw = await import_node_fs30.promises.readFile(daemonJsonPath(scanPath), "utf8");
10801
11104
  const parsed = JSON.parse(raw);
10802
11105
  if (typeof parsed.project === "string" && parsed.ports && typeof parsed.ports.rest === "number" && typeof parsed.ports.otlp === "number" && typeof parsed.ports.web === "number") {
10803
11106
  return parsed;
@@ -10837,7 +11140,7 @@ async function clearDaemonRecord(record, home) {
10837
11140
  } catch {
10838
11141
  }
10839
11142
  try {
10840
- await import_node_fs29.promises.unlink(daemonDiscoveryPath(record.project, home));
11143
+ await import_node_fs30.promises.unlink(daemonDiscoveryPath(record.project, home));
10841
11144
  } catch {
10842
11145
  }
10843
11146
  }
@@ -10863,8 +11166,8 @@ init_otel_grpc();
10863
11166
 
10864
11167
  // src/search.ts
10865
11168
  init_cjs_shims();
10866
- var import_node_fs30 = require("fs");
10867
- var import_node_path49 = __toESM(require("path"), 1);
11169
+ var import_node_fs31 = require("fs");
11170
+ var import_node_path50 = __toESM(require("path"), 1);
10868
11171
  var import_node_crypto4 = require("crypto");
10869
11172
  var DEFAULT_LIMIT = 10;
10870
11173
  var NOMIC_DIM = 768;
@@ -11018,7 +11321,7 @@ async function pickEmbedder() {
11018
11321
  }
11019
11322
  async function readCache(cachePath) {
11020
11323
  try {
11021
- const raw = await import_node_fs30.promises.readFile(cachePath, "utf8");
11324
+ const raw = await import_node_fs31.promises.readFile(cachePath, "utf8");
11022
11325
  const parsed = JSON.parse(raw);
11023
11326
  if (parsed.version !== 1) return null;
11024
11327
  return parsed;
@@ -11027,8 +11330,8 @@ async function readCache(cachePath) {
11027
11330
  }
11028
11331
  }
11029
11332
  async function writeCache(cachePath, cache) {
11030
- await import_node_fs30.promises.mkdir(import_node_path49.default.dirname(cachePath), { recursive: true });
11031
- await import_node_fs30.promises.writeFile(cachePath, JSON.stringify(cache));
11333
+ await import_node_fs31.promises.mkdir(import_node_path50.default.dirname(cachePath), { recursive: true });
11334
+ await import_node_fs31.promises.writeFile(cachePath, JSON.stringify(cache));
11032
11335
  }
11033
11336
  var VectorIndex = class {
11034
11337
  constructor(embedder, cachePath) {
@@ -11185,8 +11488,8 @@ var ALL_PHASES = [
11185
11488
  ];
11186
11489
  function classifyChange(relPath) {
11187
11490
  const phases = /* @__PURE__ */ new Set();
11188
- const base = import_node_path50.default.basename(relPath).toLowerCase();
11189
- const segments = relPath.split(import_node_path50.default.sep).map((s) => s.toLowerCase());
11491
+ const base = import_node_path51.default.basename(relPath).toLowerCase();
11492
+ const segments = relPath.split(import_node_path51.default.sep).map((s) => s.toLowerCase());
11190
11493
  if (base === "package.json" || base === "requirements.txt" || base === "pyproject.toml" || base === "setup.py") {
11191
11494
  phases.add("services");
11192
11495
  phases.add("aliases");
@@ -11307,16 +11610,16 @@ function countWatchableDirs(scanPath, limit) {
11307
11610
  if (count >= limit) return;
11308
11611
  let entries;
11309
11612
  try {
11310
- entries = import_node_fs31.default.readdirSync(dir, { withFileTypes: true });
11613
+ entries = import_node_fs32.default.readdirSync(dir, { withFileTypes: true });
11311
11614
  } catch {
11312
11615
  return;
11313
11616
  }
11314
11617
  for (const e of entries) {
11315
11618
  if (count >= limit) return;
11316
11619
  if (!e.isDirectory()) continue;
11317
- if (IGNORED_WATCH_PATHS.some((re) => re.test(import_node_path50.default.join(dir, e.name) + import_node_path50.default.sep))) continue;
11620
+ if (IGNORED_WATCH_PATHS.some((re) => re.test(import_node_path51.default.join(dir, e.name) + import_node_path51.default.sep))) continue;
11318
11621
  count++;
11319
- if (depth < 2) visit(import_node_path50.default.join(dir, e.name), depth + 1);
11622
+ if (depth < 2) visit(import_node_path51.default.join(dir, e.name), depth + 1);
11320
11623
  }
11321
11624
  };
11322
11625
  visit(scanPath, 0);
@@ -11334,8 +11637,8 @@ async function startWatch(graph, opts) {
11334
11637
  const projectName = opts.project ?? DEFAULT_PROJECT;
11335
11638
  await loadGraphFromDisk(graph, opts.outPath);
11336
11639
  const detachEventBus = attachGraphToEventBus(graph, { project: projectName });
11337
- const policyFilePath = import_node_path50.default.join(opts.scanPath, "policy.json");
11338
- const policyViolationsPath = import_node_path50.default.join(import_node_path50.default.dirname(opts.outPath), "policy-violations.ndjson");
11640
+ const policyFilePath = import_node_path51.default.join(opts.scanPath, "policy.json");
11641
+ const policyViolationsPath = import_node_path51.default.join(import_node_path51.default.dirname(opts.outPath), "policy-violations.ndjson");
11339
11642
  let policies = [];
11340
11643
  try {
11341
11644
  policies = await loadPolicyFile(policyFilePath);
@@ -11386,7 +11689,7 @@ async function startWatch(graph, opts) {
11386
11689
  assertBindAuthority(host, auth.authToken);
11387
11690
  const port = opts.port ?? 8080;
11388
11691
  const otelPort = opts.otelPort ?? 4318;
11389
- const cachePath = opts.embeddingsCachePath ?? import_node_path50.default.join(import_node_path50.default.dirname(opts.outPath), "embeddings.json");
11692
+ const cachePath = opts.embeddingsCachePath ?? import_node_path51.default.join(import_node_path51.default.dirname(opts.outPath), "embeddings.json");
11390
11693
  let searchIndex;
11391
11694
  try {
11392
11695
  searchIndex = await buildSearchIndex(graph, { cachePath });
@@ -11404,7 +11707,7 @@ async function startWatch(graph, opts) {
11404
11707
  // Paths are derived from the explicit options the watch caller passes
11405
11708
  // — pathsForProject is only used to fill in the embeddings/snapshot
11406
11709
  // fields so the registry shape is complete.
11407
- ...pathsForProject(projectName, import_node_path50.default.dirname(opts.outPath)),
11710
+ ...pathsForProject(projectName, import_node_path51.default.dirname(opts.outPath)),
11408
11711
  snapshotPath: opts.outPath,
11409
11712
  errorsPath: opts.errorsPath,
11410
11713
  staleEventsPath: opts.staleEventsPath
@@ -11522,9 +11825,9 @@ async function startWatch(graph, opts) {
11522
11825
  };
11523
11826
  const onPath = (absPath) => {
11524
11827
  if (shouldIgnore(absPath)) return;
11525
- const rel = import_node_path50.default.relative(opts.scanPath, absPath);
11828
+ const rel = import_node_path51.default.relative(opts.scanPath, absPath);
11526
11829
  if (!rel || rel.startsWith("..")) return;
11527
- pendingPaths.add(rel.split(import_node_path50.default.sep).join("/"));
11830
+ pendingPaths.add(rel.split(import_node_path51.default.sep).join("/"));
11528
11831
  const phases = classifyChange(rel);
11529
11832
  if (phases.size === 0) {
11530
11833
  for (const p of ALL_PHASES) pending.add(p);
@@ -11580,8 +11883,8 @@ async function startWatch(graph, opts) {
11580
11883
 
11581
11884
  // src/deploy/detect.ts
11582
11885
  init_cjs_shims();
11583
- var import_node_fs32 = require("fs");
11584
- var import_node_path51 = __toESM(require("path"), 1);
11886
+ var import_node_fs33 = require("fs");
11887
+ var import_node_path52 = __toESM(require("path"), 1);
11585
11888
  var import_node_child_process2 = require("child_process");
11586
11889
  var import_node_crypto5 = require("crypto");
11587
11890
  function generateToken() {
@@ -11681,21 +11984,21 @@ async function runDeploy(opts = {}) {
11681
11984
  const token = generateToken();
11682
11985
  switch (substrate) {
11683
11986
  case "docker-compose": {
11684
- const artifactPath = import_node_path51.default.join(cwd, "docker-compose.neat.yml");
11987
+ const artifactPath = import_node_path52.default.join(cwd, "docker-compose.neat.yml");
11685
11988
  const contents = emitDockerCompose(cwd);
11686
- await import_node_fs32.promises.writeFile(artifactPath, contents, "utf8");
11989
+ await import_node_fs33.promises.writeFile(artifactPath, contents, "utf8");
11687
11990
  return {
11688
11991
  substrate,
11689
11992
  artifactPath,
11690
11993
  token,
11691
11994
  contents,
11692
- startCommand: `NEAT_AUTH_TOKEN=${token} docker compose -f ${import_node_path51.default.basename(artifactPath)} up -d`
11995
+ startCommand: `NEAT_AUTH_TOKEN=${token} docker compose -f ${import_node_path52.default.basename(artifactPath)} up -d`
11693
11996
  };
11694
11997
  }
11695
11998
  case "systemd": {
11696
- const artifactPath = import_node_path51.default.join(cwd, "neat.service");
11999
+ const artifactPath = import_node_path52.default.join(cwd, "neat.service");
11697
12000
  const contents = emitSystemdUnit(cwd);
11698
- await import_node_fs32.promises.writeFile(artifactPath, contents, "utf8");
12001
+ await import_node_fs33.promises.writeFile(artifactPath, contents, "utf8");
11699
12002
  return {
11700
12003
  substrate,
11701
12004
  artifactPath,
@@ -11728,8 +12031,8 @@ init_cjs_shims();
11728
12031
 
11729
12032
  // src/installers/javascript.ts
11730
12033
  init_cjs_shims();
11731
- var import_node_fs33 = require("fs");
11732
- var import_node_path52 = __toESM(require("path"), 1);
12034
+ var import_node_fs34 = require("fs");
12035
+ var import_node_path53 = __toESM(require("path"), 1);
11733
12036
  var import_semver2 = __toESM(require("semver"), 1);
11734
12037
 
11735
12038
  // src/installers/templates.ts
@@ -12344,15 +12647,15 @@ var OTEL_ENV = {
12344
12647
  value: "http://localhost:4318/projects/<project>/v1/traces"
12345
12648
  };
12346
12649
  function serviceNodeName(pkg, serviceDir) {
12347
- return pkg.name ?? import_node_path52.default.basename(serviceDir);
12650
+ return pkg.name ?? import_node_path53.default.basename(serviceDir);
12348
12651
  }
12349
12652
  function projectToken(pkg, serviceDir, project) {
12350
12653
  if (project && project.length > 0) return project;
12351
- return pkg.name ?? import_node_path52.default.basename(serviceDir);
12654
+ return pkg.name ?? import_node_path53.default.basename(serviceDir);
12352
12655
  }
12353
12656
  async function readJsonFile(p) {
12354
12657
  try {
12355
- const raw = await import_node_fs33.promises.readFile(p, "utf8");
12658
+ const raw = await import_node_fs34.promises.readFile(p, "utf8");
12356
12659
  return JSON.parse(raw);
12357
12660
  } catch {
12358
12661
  return null;
@@ -12361,16 +12664,16 @@ async function readJsonFile(p) {
12361
12664
  async function detectRuntimeKind(pkgRoot, pkg) {
12362
12665
  const deps = allDeps(pkg);
12363
12666
  if ("react-native" in deps || "expo" in deps) return "react-native";
12364
- const appJson = await readJsonFile(import_node_path52.default.join(pkgRoot, "app.json"));
12667
+ const appJson = await readJsonFile(import_node_path53.default.join(pkgRoot, "app.json"));
12365
12668
  if (appJson && typeof appJson === "object" && "expo" in appJson) {
12366
12669
  return "react-native";
12367
12670
  }
12368
- if (await exists3(import_node_path52.default.join(pkgRoot, "vite.config.js")) || await exists3(import_node_path52.default.join(pkgRoot, "vite.config.ts")) || await exists3(import_node_path52.default.join(pkgRoot, "vite.config.mjs")) || "vite" in deps) {
12671
+ if (await exists3(import_node_path53.default.join(pkgRoot, "vite.config.js")) || await exists3(import_node_path53.default.join(pkgRoot, "vite.config.ts")) || await exists3(import_node_path53.default.join(pkgRoot, "vite.config.mjs")) || "vite" in deps) {
12369
12672
  return "browser-bundle";
12370
12673
  }
12371
- if (await exists3(import_node_path52.default.join(pkgRoot, "wrangler.toml"))) return "cloudflare-workers";
12372
- if (await exists3(import_node_path52.default.join(pkgRoot, "bun.lockb"))) return "bun";
12373
- if (await exists3(import_node_path52.default.join(pkgRoot, "deno.json")) || await exists3(import_node_path52.default.join(pkgRoot, "deno.lock"))) {
12674
+ if (await exists3(import_node_path53.default.join(pkgRoot, "wrangler.toml"))) return "cloudflare-workers";
12675
+ if (await exists3(import_node_path53.default.join(pkgRoot, "bun.lockb"))) return "bun";
12676
+ if (await exists3(import_node_path53.default.join(pkgRoot, "deno.json")) || await exists3(import_node_path53.default.join(pkgRoot, "deno.lock"))) {
12374
12677
  return "deno";
12375
12678
  }
12376
12679
  const engines = pkg.engines ?? {};
@@ -12379,7 +12682,7 @@ async function detectRuntimeKind(pkgRoot, pkg) {
12379
12682
  }
12380
12683
  async function readPackageJson2(serviceDir) {
12381
12684
  try {
12382
- const raw = await import_node_fs33.promises.readFile(import_node_path52.default.join(serviceDir, "package.json"), "utf8");
12685
+ const raw = await import_node_fs34.promises.readFile(import_node_path53.default.join(serviceDir, "package.json"), "utf8");
12383
12686
  return JSON.parse(raw);
12384
12687
  } catch {
12385
12688
  return null;
@@ -12387,7 +12690,7 @@ async function readPackageJson2(serviceDir) {
12387
12690
  }
12388
12691
  async function exists3(p) {
12389
12692
  try {
12390
- await import_node_fs33.promises.stat(p);
12693
+ await import_node_fs34.promises.stat(p);
12391
12694
  return true;
12392
12695
  } catch {
12393
12696
  return false;
@@ -12395,7 +12698,7 @@ async function exists3(p) {
12395
12698
  }
12396
12699
  async function readFileMaybe(p) {
12397
12700
  try {
12398
- return await import_node_fs33.promises.readFile(p, "utf8");
12701
+ return await import_node_fs34.promises.readFile(p, "utf8");
12399
12702
  } catch {
12400
12703
  return null;
12401
12704
  }
@@ -12423,7 +12726,7 @@ function needsVersionUpgrade(installed, expected) {
12423
12726
  var NEXT_CONFIG_CANDIDATES = ["next.config.js", "next.config.ts", "next.config.mjs"];
12424
12727
  async function findNextConfig(serviceDir) {
12425
12728
  for (const name of NEXT_CONFIG_CANDIDATES) {
12426
- const candidate = import_node_path52.default.join(serviceDir, name);
12729
+ const candidate = import_node_path53.default.join(serviceDir, name);
12427
12730
  if (await exists3(candidate)) return candidate;
12428
12731
  }
12429
12732
  return null;
@@ -12492,7 +12795,7 @@ function hasRemixDependency(pkg) {
12492
12795
  }
12493
12796
  async function findRemixEntry(serviceDir) {
12494
12797
  for (const rel of REMIX_ENTRY_CANDIDATES) {
12495
- const candidate = import_node_path52.default.join(serviceDir, rel);
12798
+ const candidate = import_node_path53.default.join(serviceDir, rel);
12496
12799
  if (await exists3(candidate)) return candidate;
12497
12800
  }
12498
12801
  return null;
@@ -12504,14 +12807,14 @@ function hasSvelteKitDependency(pkg) {
12504
12807
  }
12505
12808
  async function findSvelteKitHooks(serviceDir) {
12506
12809
  for (const rel of SVELTEKIT_HOOKS_CANDIDATES) {
12507
- const candidate = import_node_path52.default.join(serviceDir, rel);
12810
+ const candidate = import_node_path53.default.join(serviceDir, rel);
12508
12811
  if (await exists3(candidate)) return candidate;
12509
12812
  }
12510
12813
  return null;
12511
12814
  }
12512
12815
  async function findSvelteKitConfig(serviceDir) {
12513
12816
  for (const rel of SVELTEKIT_CONFIG_CANDIDATES) {
12514
- const candidate = import_node_path52.default.join(serviceDir, rel);
12817
+ const candidate = import_node_path53.default.join(serviceDir, rel);
12515
12818
  if (await exists3(candidate)) return candidate;
12516
12819
  }
12517
12820
  return null;
@@ -12522,7 +12825,7 @@ function hasNuxtDependency(pkg) {
12522
12825
  }
12523
12826
  async function findNuxtConfig(serviceDir) {
12524
12827
  for (const name of NUXT_CONFIG_CANDIDATES) {
12525
- const candidate = import_node_path52.default.join(serviceDir, name);
12828
+ const candidate = import_node_path53.default.join(serviceDir, name);
12526
12829
  if (await exists3(candidate)) return candidate;
12527
12830
  }
12528
12831
  return null;
@@ -12533,7 +12836,7 @@ function hasAstroDependency(pkg) {
12533
12836
  }
12534
12837
  async function findAstroConfig(serviceDir) {
12535
12838
  for (const name of ASTRO_CONFIG_CANDIDATES) {
12536
- const candidate = import_node_path52.default.join(serviceDir, name);
12839
+ const candidate = import_node_path53.default.join(serviceDir, name);
12537
12840
  if (await exists3(candidate)) return candidate;
12538
12841
  }
12539
12842
  return null;
@@ -12547,7 +12850,7 @@ function parseNextMajor(range) {
12547
12850
  return Number.isFinite(n) ? n : null;
12548
12851
  }
12549
12852
  async function isTypeScriptProject(serviceDir) {
12550
- return exists3(import_node_path52.default.join(serviceDir, "tsconfig.json"));
12853
+ return exists3(import_node_path53.default.join(serviceDir, "tsconfig.json"));
12551
12854
  }
12552
12855
  var INDEX_EXTENSIONS = [".ts", ".tsx", ".js", ".mjs", ".cjs"];
12553
12856
  var INDEX_CANDIDATES = INDEX_EXTENSIONS.map((ext) => `index${ext}`);
@@ -12596,7 +12899,7 @@ function entryFromScript(script) {
12596
12899
  }
12597
12900
  async function resolveEntry(serviceDir, pkg) {
12598
12901
  if (typeof pkg.main === "string" && pkg.main.length > 0) {
12599
- const candidate = import_node_path52.default.resolve(serviceDir, pkg.main);
12902
+ const candidate = import_node_path53.default.resolve(serviceDir, pkg.main);
12600
12903
  if (await exists3(candidate)) return candidate;
12601
12904
  }
12602
12905
  if (pkg.bin) {
@@ -12610,40 +12913,40 @@ async function resolveEntry(serviceDir, pkg) {
12610
12913
  if (typeof first === "string") binEntry = first;
12611
12914
  }
12612
12915
  if (binEntry) {
12613
- const candidate = import_node_path52.default.resolve(serviceDir, binEntry);
12916
+ const candidate = import_node_path53.default.resolve(serviceDir, binEntry);
12614
12917
  if (await exists3(candidate)) return candidate;
12615
12918
  }
12616
12919
  }
12617
12920
  const startEntry = entryFromScript(pkg.scripts?.start);
12618
12921
  if (startEntry) {
12619
- const candidate = import_node_path52.default.resolve(serviceDir, startEntry);
12922
+ const candidate = import_node_path53.default.resolve(serviceDir, startEntry);
12620
12923
  if (await exists3(candidate)) return candidate;
12621
12924
  }
12622
12925
  const devEntry = entryFromScript(pkg.scripts?.dev);
12623
12926
  if (devEntry) {
12624
- const candidate = import_node_path52.default.resolve(serviceDir, devEntry);
12927
+ const candidate = import_node_path53.default.resolve(serviceDir, devEntry);
12625
12928
  if (await exists3(candidate)) return candidate;
12626
12929
  }
12627
12930
  for (const rel of SRC_INDEX_CANDIDATES) {
12628
- const candidate = import_node_path52.default.join(serviceDir, rel);
12931
+ const candidate = import_node_path53.default.join(serviceDir, rel);
12629
12932
  if (await exists3(candidate)) return candidate;
12630
12933
  }
12631
12934
  for (const rel of SRC_NAMED_CANDIDATES) {
12632
- const candidate = import_node_path52.default.join(serviceDir, rel);
12935
+ const candidate = import_node_path53.default.join(serviceDir, rel);
12633
12936
  if (await exists3(candidate)) return candidate;
12634
12937
  }
12635
12938
  for (const rel of ROOT_NAMED_CANDIDATES) {
12636
- const candidate = import_node_path52.default.join(serviceDir, rel);
12939
+ const candidate = import_node_path53.default.join(serviceDir, rel);
12637
12940
  if (await exists3(candidate)) return candidate;
12638
12941
  }
12639
12942
  for (const name of INDEX_CANDIDATES) {
12640
- const candidate = import_node_path52.default.join(serviceDir, name);
12943
+ const candidate = import_node_path53.default.join(serviceDir, name);
12641
12944
  if (await exists3(candidate)) return candidate;
12642
12945
  }
12643
12946
  return null;
12644
12947
  }
12645
12948
  function dispatchEntry(entryFile, pkg) {
12646
- const ext = import_node_path52.default.extname(entryFile).toLowerCase();
12949
+ const ext = import_node_path53.default.extname(entryFile).toLowerCase();
12647
12950
  if (ext === ".ts" || ext === ".tsx") return "ts";
12648
12951
  if (ext === ".mjs") return "esm";
12649
12952
  if (ext === ".cjs") return "cjs";
@@ -12660,9 +12963,9 @@ function otelInitContents(flavor) {
12660
12963
  return OTEL_INIT_CJS;
12661
12964
  }
12662
12965
  function injectionLine(flavor, entryFile, otelInitFile) {
12663
- let rel = import_node_path52.default.relative(import_node_path52.default.dirname(entryFile), otelInitFile);
12966
+ let rel = import_node_path53.default.relative(import_node_path53.default.dirname(entryFile), otelInitFile);
12664
12967
  if (!rel.startsWith(".")) rel = `./${rel}`;
12665
- rel = rel.split(import_node_path52.default.sep).join("/");
12968
+ rel = rel.split(import_node_path53.default.sep).join("/");
12666
12969
  if (flavor === "cjs") return `require('${rel}')`;
12667
12970
  if (flavor === "esm") return `import '${rel}'`;
12668
12971
  const tsRel = rel.replace(/\.ts$/, "");
@@ -12675,27 +12978,27 @@ function lineIsOtelInjection(line) {
12675
12978
  }
12676
12979
  async function detectsSrcLayout(serviceDir) {
12677
12980
  const [hasSrcApp, hasSrcPages, hasRootApp, hasRootPages] = await Promise.all([
12678
- exists3(import_node_path52.default.join(serviceDir, "src", "app")),
12679
- exists3(import_node_path52.default.join(serviceDir, "src", "pages")),
12680
- exists3(import_node_path52.default.join(serviceDir, "app")),
12681
- exists3(import_node_path52.default.join(serviceDir, "pages"))
12981
+ exists3(import_node_path53.default.join(serviceDir, "src", "app")),
12982
+ exists3(import_node_path53.default.join(serviceDir, "src", "pages")),
12983
+ exists3(import_node_path53.default.join(serviceDir, "app")),
12984
+ exists3(import_node_path53.default.join(serviceDir, "pages"))
12682
12985
  ]);
12683
12986
  return (hasSrcApp || hasSrcPages) && !hasRootApp && !hasRootPages;
12684
12987
  }
12685
12988
  async function planNext(serviceDir, pkg, manifestPath, nextConfigPath, project) {
12686
12989
  const useTs = await isTypeScriptProject(serviceDir);
12687
12990
  const srcLayout = await detectsSrcLayout(serviceDir);
12688
- const baseDir = srcLayout ? import_node_path52.default.join(serviceDir, "src") : serviceDir;
12689
- const instrumentationFile = import_node_path52.default.join(baseDir, useTs ? "instrumentation.ts" : "instrumentation.js");
12690
- const instrumentationNodeFile = import_node_path52.default.join(
12991
+ const baseDir = srcLayout ? import_node_path53.default.join(serviceDir, "src") : serviceDir;
12992
+ const instrumentationFile = import_node_path53.default.join(baseDir, useTs ? "instrumentation.ts" : "instrumentation.js");
12993
+ const instrumentationNodeFile = import_node_path53.default.join(
12691
12994
  baseDir,
12692
12995
  useTs ? "instrumentation.node.ts" : "instrumentation.node.js"
12693
12996
  );
12694
- const instrumentationEdgeFile = import_node_path52.default.join(
12997
+ const instrumentationEdgeFile = import_node_path53.default.join(
12695
12998
  baseDir,
12696
12999
  useTs ? "instrumentation.edge.ts" : "instrumentation.edge.js"
12697
13000
  );
12698
- const envNeatFile = import_node_path52.default.join(baseDir, ".env.neat");
13001
+ const envNeatFile = import_node_path53.default.join(baseDir, ".env.neat");
12699
13002
  const existingDeps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
12700
13003
  const dependencyEdits = [];
12701
13004
  for (const sdk of SDK_PACKAGES) {
@@ -12772,7 +13075,7 @@ async function planNext(serviceDir, pkg, manifestPath, nextConfigPath, project)
12772
13075
  const nextMajor = parseNextMajor(nextRange);
12773
13076
  if (nextMajor !== null && nextMajor < 15) {
12774
13077
  try {
12775
- const raw = await import_node_fs33.promises.readFile(nextConfigPath, "utf8");
13078
+ const raw = await import_node_fs34.promises.readFile(nextConfigPath, "utf8");
12776
13079
  if (!raw.includes("instrumentationHook")) {
12777
13080
  nextConfigEdit = {
12778
13081
  file: nextConfigPath,
@@ -12820,7 +13123,7 @@ function buildDependencyEdits(pkg, manifestPath) {
12820
13123
  return edits;
12821
13124
  }
12822
13125
  async function queueEnvNeat(serviceDir, pkg, project, generatedFiles) {
12823
- const envNeatFile = import_node_path52.default.join(serviceDir, ".env.neat");
13126
+ const envNeatFile = import_node_path53.default.join(serviceDir, ".env.neat");
12824
13127
  if (!await exists3(envNeatFile)) {
12825
13128
  generatedFiles.push({
12826
13129
  file: envNeatFile,
@@ -12855,7 +13158,7 @@ function fileImportsOtelHook(raw, specifiers) {
12855
13158
  }
12856
13159
  async function planRemix(serviceDir, pkg, manifestPath, entryFile, project) {
12857
13160
  const useTs = await isTypeScriptProject(serviceDir);
12858
- const otelServerFile = import_node_path52.default.join(
13161
+ const otelServerFile = import_node_path53.default.join(
12859
13162
  serviceDir,
12860
13163
  useTs ? "app/otel.server.ts" : "app/otel.server.js"
12861
13164
  );
@@ -12876,7 +13179,7 @@ async function planRemix(serviceDir, pkg, manifestPath, entryFile, project) {
12876
13179
  await queueEnvNeat(serviceDir, pkg, project, generatedFiles);
12877
13180
  const entrypointEdits = [];
12878
13181
  try {
12879
- const raw = await import_node_fs33.promises.readFile(entryFile, "utf8");
13182
+ const raw = await import_node_fs34.promises.readFile(entryFile, "utf8");
12880
13183
  if (!fileImportsOtelHook(raw, ["./otel.server"])) {
12881
13184
  const lines = raw.split(/\r?\n/);
12882
13185
  const firstReal = lines[0]?.startsWith("#!") ? lines[1] ?? "" : lines[0] ?? "";
@@ -12912,11 +13215,11 @@ async function planRemix(serviceDir, pkg, manifestPath, entryFile, project) {
12912
13215
  }
12913
13216
  async function planSvelteKit(serviceDir, pkg, manifestPath, hooksFile, project) {
12914
13217
  const useTs = await isTypeScriptProject(serviceDir);
12915
- const otelInitFile = import_node_path52.default.join(
13218
+ const otelInitFile = import_node_path53.default.join(
12916
13219
  serviceDir,
12917
13220
  useTs ? "src/otel-init.ts" : "src/otel-init.js"
12918
13221
  );
12919
- const resolvedHooksFile = hooksFile ?? import_node_path52.default.join(serviceDir, useTs ? "src/hooks.server.ts" : "src/hooks.server.js");
13222
+ const resolvedHooksFile = hooksFile ?? import_node_path53.default.join(serviceDir, useTs ? "src/hooks.server.ts" : "src/hooks.server.js");
12920
13223
  const dependencyEdits = buildDependencyEdits(pkg, manifestPath);
12921
13224
  const generatedFiles = [];
12922
13225
  const entrypointEdits = [];
@@ -12941,7 +13244,7 @@ async function planSvelteKit(serviceDir, pkg, manifestPath, hooksFile, project)
12941
13244
  });
12942
13245
  } else {
12943
13246
  try {
12944
- const raw = await import_node_fs33.promises.readFile(hooksFile, "utf8");
13247
+ const raw = await import_node_fs34.promises.readFile(hooksFile, "utf8");
12945
13248
  if (!fileImportsOtelHook(raw, ["./otel-init"])) {
12946
13249
  const lines = raw.split(/\r?\n/);
12947
13250
  const firstReal = lines[0]?.startsWith("#!") ? lines[1] ?? "" : lines[0] ?? "";
@@ -12978,11 +13281,11 @@ async function planSvelteKit(serviceDir, pkg, manifestPath, hooksFile, project)
12978
13281
  }
12979
13282
  async function planNuxt(serviceDir, pkg, manifestPath, project) {
12980
13283
  const useTs = await isTypeScriptProject(serviceDir);
12981
- const otelPluginFile = import_node_path52.default.join(
13284
+ const otelPluginFile = import_node_path53.default.join(
12982
13285
  serviceDir,
12983
13286
  useTs ? "server/plugins/otel.ts" : "server/plugins/otel.js"
12984
13287
  );
12985
- const otelInitFile = import_node_path52.default.join(
13288
+ const otelInitFile = import_node_path53.default.join(
12986
13289
  serviceDir,
12987
13290
  useTs ? "server/plugins/otel-init.ts" : "server/plugins/otel-init.js"
12988
13291
  );
@@ -13033,19 +13336,19 @@ async function planNuxt(serviceDir, pkg, manifestPath, project) {
13033
13336
  var ASTRO_MIDDLEWARE_CANDIDATES = ["src/middleware.ts", "src/middleware.js"];
13034
13337
  async function findAstroMiddleware(serviceDir) {
13035
13338
  for (const rel of ASTRO_MIDDLEWARE_CANDIDATES) {
13036
- const candidate = import_node_path52.default.join(serviceDir, rel);
13339
+ const candidate = import_node_path53.default.join(serviceDir, rel);
13037
13340
  if (await exists3(candidate)) return candidate;
13038
13341
  }
13039
13342
  return null;
13040
13343
  }
13041
13344
  async function planAstro(serviceDir, pkg, manifestPath, project) {
13042
13345
  const useTs = await isTypeScriptProject(serviceDir);
13043
- const otelInitFile = import_node_path52.default.join(
13346
+ const otelInitFile = import_node_path53.default.join(
13044
13347
  serviceDir,
13045
13348
  useTs ? "src/otel-init.ts" : "src/otel-init.js"
13046
13349
  );
13047
13350
  const existingMiddleware = await findAstroMiddleware(serviceDir);
13048
- const middlewareFile = existingMiddleware ?? import_node_path52.default.join(serviceDir, useTs ? "src/middleware.ts" : "src/middleware.js");
13351
+ const middlewareFile = existingMiddleware ?? import_node_path53.default.join(serviceDir, useTs ? "src/middleware.ts" : "src/middleware.js");
13049
13352
  const dependencyEdits = buildDependencyEdits(pkg, manifestPath);
13050
13353
  const generatedFiles = [];
13051
13354
  const entrypointEdits = [];
@@ -13070,7 +13373,7 @@ async function planAstro(serviceDir, pkg, manifestPath, project) {
13070
13373
  });
13071
13374
  } else {
13072
13375
  try {
13073
- const raw = await import_node_fs33.promises.readFile(existingMiddleware, "utf8");
13376
+ const raw = await import_node_fs34.promises.readFile(existingMiddleware, "utf8");
13074
13377
  if (!fileImportsOtelHook(raw, ["./otel-init"])) {
13075
13378
  const lines = raw.split(/\r?\n/);
13076
13379
  const firstReal = lines[0]?.startsWith("#!") ? lines[1] ?? "" : lines[0] ?? "";
@@ -13141,7 +13444,7 @@ async function findFrameworkDispatch(serviceDir, pkg, manifestPath, project) {
13141
13444
  }
13142
13445
  async function plan(serviceDir, opts) {
13143
13446
  const pkg = await readPackageJson2(serviceDir);
13144
- const manifestPath = import_node_path52.default.join(serviceDir, "package.json");
13447
+ const manifestPath = import_node_path53.default.join(serviceDir, "package.json");
13145
13448
  const project = opts?.project;
13146
13449
  const empty = {
13147
13450
  language: "javascript",
@@ -13176,8 +13479,8 @@ async function plan(serviceDir, opts) {
13176
13479
  return { ...empty, libOnly: true };
13177
13480
  }
13178
13481
  const flavor = dispatchEntry(entryFile, pkg);
13179
- const otelInitFile = import_node_path52.default.join(import_node_path52.default.dirname(entryFile), otelInitFilename(flavor));
13180
- const envNeatFile = import_node_path52.default.join(serviceDir, ".env.neat");
13482
+ const otelInitFile = import_node_path53.default.join(import_node_path53.default.dirname(entryFile), otelInitFilename(flavor));
13483
+ const envNeatFile = import_node_path53.default.join(serviceDir, ".env.neat");
13181
13484
  const existingDeps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
13182
13485
  const dependencyEdits = [];
13183
13486
  for (const sdk of SDK_PACKAGES) {
@@ -13201,7 +13504,7 @@ async function plan(serviceDir, opts) {
13201
13504
  }
13202
13505
  const entrypointEdits = [];
13203
13506
  try {
13204
- const raw = await import_node_fs33.promises.readFile(entryFile, "utf8");
13507
+ const raw = await import_node_fs34.promises.readFile(entryFile, "utf8");
13205
13508
  const lines = raw.split(/\r?\n/);
13206
13509
  const firstReal = lines[0]?.startsWith("#!") ? lines[1] ?? "" : lines[0] ?? "";
13207
13510
  if (!lineIsOtelInjection(firstReal)) {
@@ -13246,13 +13549,13 @@ async function plan(serviceDir, opts) {
13246
13549
  };
13247
13550
  }
13248
13551
  function isAllowedWritePath(serviceDir, target) {
13249
- const rel = import_node_path52.default.relative(serviceDir, target);
13552
+ const rel = import_node_path53.default.relative(serviceDir, target);
13250
13553
  if (rel.startsWith("..")) return false;
13251
- const base = import_node_path52.default.basename(target);
13554
+ const base = import_node_path53.default.basename(target);
13252
13555
  if (base === "package.json") return true;
13253
13556
  if (base === ".env.neat") return true;
13254
13557
  if (/^otel-init\.(?:js|cjs|mjs|ts)$/.test(base)) return true;
13255
- const relPosix = rel.split(import_node_path52.default.sep).join("/");
13558
+ const relPosix = rel.split(import_node_path53.default.sep).join("/");
13256
13559
  if (/^instrumentation(?:\.(?:node|edge))?\.(?:js|cjs|mjs|ts)$/.test(base)) {
13257
13560
  if (relPosix === base) return true;
13258
13561
  if (relPosix === `src/${base}`) return true;
@@ -13269,10 +13572,10 @@ function isAllowedWritePath(serviceDir, target) {
13269
13572
  return false;
13270
13573
  }
13271
13574
  async function writeAtomic(file, contents) {
13272
- await import_node_fs33.promises.mkdir(import_node_path52.default.dirname(file), { recursive: true });
13575
+ await import_node_fs34.promises.mkdir(import_node_path53.default.dirname(file), { recursive: true });
13273
13576
  const tmp = `${file}.${process.pid}.${Date.now()}.tmp`;
13274
- await import_node_fs33.promises.writeFile(tmp, contents, "utf8");
13275
- await import_node_fs33.promises.rename(tmp, file);
13577
+ await import_node_fs34.promises.writeFile(tmp, contents, "utf8");
13578
+ await import_node_fs34.promises.rename(tmp, file);
13276
13579
  }
13277
13580
  async function apply(installPlan) {
13278
13581
  const { serviceDir } = installPlan;
@@ -13348,7 +13651,7 @@ async function apply(installPlan) {
13348
13651
  for (const target of allTargets) {
13349
13652
  if (await exists3(target)) {
13350
13653
  try {
13351
- originals.set(target, await import_node_fs33.promises.readFile(target, "utf8"));
13654
+ originals.set(target, await import_node_fs34.promises.readFile(target, "utf8"));
13352
13655
  } catch {
13353
13656
  }
13354
13657
  }
@@ -13431,14 +13734,14 @@ async function rollback(installPlan, originals, createdFiles) {
13431
13734
  const removed = [];
13432
13735
  for (const [file, raw] of originals.entries()) {
13433
13736
  try {
13434
- await import_node_fs33.promises.writeFile(file, raw, "utf8");
13737
+ await import_node_fs34.promises.writeFile(file, raw, "utf8");
13435
13738
  restored.push(file);
13436
13739
  } catch {
13437
13740
  }
13438
13741
  }
13439
13742
  for (const file of createdFiles) {
13440
13743
  try {
13441
- await import_node_fs33.promises.unlink(file);
13744
+ await import_node_fs34.promises.unlink(file);
13442
13745
  removed.push(file);
13443
13746
  } catch {
13444
13747
  }
@@ -13453,8 +13756,8 @@ async function rollback(installPlan, originals, createdFiles) {
13453
13756
  ...removed.map((f) => `removed: ${f}`),
13454
13757
  ""
13455
13758
  ];
13456
- const rollbackPath = import_node_path52.default.join(installPlan.serviceDir, "neat-rollback.patch");
13457
- await import_node_fs33.promises.writeFile(rollbackPath, lines.join("\n"), "utf8");
13759
+ const rollbackPath = import_node_path53.default.join(installPlan.serviceDir, "neat-rollback.patch");
13760
+ await import_node_fs34.promises.writeFile(rollbackPath, lines.join("\n"), "utf8");
13458
13761
  }
13459
13762
  function injectInstrumentationHook(raw) {
13460
13763
  if (raw.includes("instrumentationHook")) return raw;
@@ -13483,8 +13786,8 @@ var javascriptInstaller = {
13483
13786
 
13484
13787
  // src/installers/python.ts
13485
13788
  init_cjs_shims();
13486
- var import_node_fs34 = require("fs");
13487
- var import_node_path53 = __toESM(require("path"), 1);
13789
+ var import_node_fs35 = require("fs");
13790
+ var import_node_path54 = __toESM(require("path"), 1);
13488
13791
  var SDK_PACKAGES2 = [
13489
13792
  { name: "opentelemetry-distro", version: ">=0.49b0" },
13490
13793
  { name: "opentelemetry-exporter-otlp", version: ">=1.28.0" }
@@ -13496,7 +13799,7 @@ var OTEL_ENV2 = {
13496
13799
  };
13497
13800
  async function exists4(p) {
13498
13801
  try {
13499
- await import_node_fs34.promises.stat(p);
13802
+ await import_node_fs35.promises.stat(p);
13500
13803
  return true;
13501
13804
  } catch {
13502
13805
  return false;
@@ -13505,7 +13808,7 @@ async function exists4(p) {
13505
13808
  async function detect2(serviceDir) {
13506
13809
  const markers = ["requirements.txt", "pyproject.toml", "setup.py"];
13507
13810
  for (const m of markers) {
13508
- if (await exists4(import_node_path53.default.join(serviceDir, m))) return true;
13811
+ if (await exists4(import_node_path54.default.join(serviceDir, m))) return true;
13509
13812
  }
13510
13813
  return false;
13511
13814
  }
@@ -13515,9 +13818,9 @@ function reqPackageName(line) {
13515
13818
  return head.replace(/[<>=!~].*$/, "").toLowerCase();
13516
13819
  }
13517
13820
  async function planRequirementsTxtEdits(serviceDir) {
13518
- const file = import_node_path53.default.join(serviceDir, "requirements.txt");
13821
+ const file = import_node_path54.default.join(serviceDir, "requirements.txt");
13519
13822
  if (!await exists4(file)) return null;
13520
- const raw = await import_node_fs34.promises.readFile(file, "utf8");
13823
+ const raw = await import_node_fs35.promises.readFile(file, "utf8");
13521
13824
  const presentNames = new Set(
13522
13825
  raw.split(/\r?\n/).map(reqPackageName).filter((n) => n.length > 0)
13523
13826
  );
@@ -13525,9 +13828,9 @@ async function planRequirementsTxtEdits(serviceDir) {
13525
13828
  return { manifest: file, missing: [...missing] };
13526
13829
  }
13527
13830
  async function planProcfileEdits(serviceDir) {
13528
- const procfile = import_node_path53.default.join(serviceDir, "Procfile");
13831
+ const procfile = import_node_path54.default.join(serviceDir, "Procfile");
13529
13832
  if (!await exists4(procfile)) return [];
13530
- const raw = await import_node_fs34.promises.readFile(procfile, "utf8");
13833
+ const raw = await import_node_fs35.promises.readFile(procfile, "utf8");
13531
13834
  const edits = [];
13532
13835
  for (const line of raw.split(/\r?\n/)) {
13533
13836
  if (line.length === 0) continue;
@@ -13579,8 +13882,8 @@ async function applyRequirementsTxt(manifest, edits, original) {
13579
13882
  const next = `${original}${trailing}${newlines.join("\n")}
13580
13883
  `;
13581
13884
  const tmp = `${manifest}.${process.pid}.${Date.now()}.tmp`;
13582
- await import_node_fs34.promises.writeFile(tmp, next, "utf8");
13583
- await import_node_fs34.promises.rename(tmp, manifest);
13885
+ await import_node_fs35.promises.writeFile(tmp, next, "utf8");
13886
+ await import_node_fs35.promises.rename(tmp, manifest);
13584
13887
  }
13585
13888
  async function applyProcfile(procfile, edits, original) {
13586
13889
  let next = original;
@@ -13589,8 +13892,8 @@ async function applyProcfile(procfile, edits, original) {
13589
13892
  next = next.replace(e.before, e.after);
13590
13893
  }
13591
13894
  const tmp = `${procfile}.${process.pid}.${Date.now()}.tmp`;
13592
- await import_node_fs34.promises.writeFile(tmp, next, "utf8");
13593
- await import_node_fs34.promises.rename(tmp, procfile);
13895
+ await import_node_fs35.promises.writeFile(tmp, next, "utf8");
13896
+ await import_node_fs35.promises.rename(tmp, procfile);
13594
13897
  }
13595
13898
  async function apply2(installPlan) {
13596
13899
  const { serviceDir } = installPlan;
@@ -13603,7 +13906,7 @@ async function apply2(installPlan) {
13603
13906
  const originals = /* @__PURE__ */ new Map();
13604
13907
  for (const file of touched) {
13605
13908
  try {
13606
- originals.set(file, await import_node_fs34.promises.readFile(file, "utf8"));
13909
+ originals.set(file, await import_node_fs35.promises.readFile(file, "utf8"));
13607
13910
  } catch {
13608
13911
  }
13609
13912
  }
@@ -13614,7 +13917,7 @@ async function apply2(installPlan) {
13614
13917
  if (raw === void 0) {
13615
13918
  throw new Error(`python installer: cannot read ${file} during apply`);
13616
13919
  }
13617
- const base = import_node_path53.default.basename(file);
13920
+ const base = import_node_path54.default.basename(file);
13618
13921
  if (base === "requirements.txt") {
13619
13922
  const edits = installPlan.dependencyEdits.filter((e) => e.file === file);
13620
13923
  if (edits.length > 0) {
@@ -13639,7 +13942,7 @@ async function rollback2(installPlan, originals) {
13639
13942
  const restored = [];
13640
13943
  for (const [file, raw] of originals.entries()) {
13641
13944
  try {
13642
- await import_node_fs34.promises.writeFile(file, raw, "utf8");
13945
+ await import_node_fs35.promises.writeFile(file, raw, "utf8");
13643
13946
  restored.push(file);
13644
13947
  } catch {
13645
13948
  }
@@ -13653,8 +13956,8 @@ async function rollback2(installPlan, originals) {
13653
13956
  ...restored.map((f) => `restored: ${f}`),
13654
13957
  ""
13655
13958
  ];
13656
- const rollbackPath = import_node_path53.default.join(installPlan.serviceDir, "neat-rollback.patch");
13657
- await import_node_fs34.promises.writeFile(rollbackPath, lines.join("\n"), "utf8");
13959
+ const rollbackPath = import_node_path54.default.join(installPlan.serviceDir, "neat-rollback.patch");
13960
+ await import_node_fs35.promises.writeFile(rollbackPath, lines.join("\n"), "utf8");
13658
13961
  }
13659
13962
  var pythonInstaller = {
13660
13963
  name: "python",
@@ -13777,10 +14080,10 @@ function renderPatch(sections) {
13777
14080
 
13778
14081
  // src/orchestrator.ts
13779
14082
  init_cjs_shims();
13780
- var import_node_fs35 = require("fs");
14083
+ var import_node_fs36 = require("fs");
13781
14084
  var import_node_http = __toESM(require("http"), 1);
13782
14085
  var import_node_net = __toESM(require("net"), 1);
13783
- var import_node_path54 = __toESM(require("path"), 1);
14086
+ var import_node_path55 = __toESM(require("path"), 1);
13784
14087
  var import_node_child_process3 = require("child_process");
13785
14088
  var import_node_readline = __toESM(require("readline"), 1);
13786
14089
  async function extractAndPersist(opts) {
@@ -13789,7 +14092,7 @@ async function extractAndPersist(opts) {
13789
14092
  const graphKey = opts.projectExplicit ? opts.project : DEFAULT_PROJECT;
13790
14093
  resetGraph(graphKey);
13791
14094
  const graph = getGraph(graphKey);
13792
- const projectPaths = pathsForProject(graphKey, import_node_path54.default.join(opts.scanPath, "neat-out"));
14095
+ const projectPaths = pathsForProject(graphKey, import_node_path55.default.join(opts.scanPath, "neat-out"));
13793
14096
  const extraction = await extractFromDirectory(graph, opts.scanPath, {
13794
14097
  errorsPath: projectPaths.errorsPath
13795
14098
  });
@@ -13841,7 +14144,7 @@ async function applyInstallersOver(services, project, options = {}) {
13841
14144
  libOnly++;
13842
14145
  const appDeps = svc.pkg ? appFrameworkDependencies(svc.pkg) : [];
13843
14146
  if (appDeps.length > 0) {
13844
- const svcName = import_node_path54.default.basename(svc.dir);
14147
+ const svcName = import_node_path55.default.basename(svc.dir);
13845
14148
  const list = appDeps.join(", ");
13846
14149
  console.warn(
13847
14150
  `neat: runtime layer won't engage for ${svcName}: no entry point found.
@@ -13854,7 +14157,7 @@ async function applyInstallersOver(services, project, options = {}) {
13854
14157
  console.log(`skipping ${svc.dir}: browser bundle; browser-OTel support lands in a future release.`);
13855
14158
  } else if (outcome.outcome === "react-native") {
13856
14159
  reactNative++;
13857
- const svcName = import_node_path54.default.basename(svc.dir);
14160
+ const svcName = import_node_path55.default.basename(svc.dir);
13858
14161
  console.log(
13859
14162
  `neat: ${svc.dir} detected as React Native / Expo
13860
14163
  The installer doesn't cover this runtime deterministically.
@@ -13865,7 +14168,7 @@ async function applyInstallersOver(services, project, options = {}) {
13865
14168
  );
13866
14169
  } else if (outcome.outcome === "bun") {
13867
14170
  bun++;
13868
- const svcName = import_node_path54.default.basename(svc.dir);
14171
+ const svcName = import_node_path55.default.basename(svc.dir);
13869
14172
  console.log(
13870
14173
  `neat: ${svc.dir} detected as Bun
13871
14174
  The installer doesn't cover this runtime deterministically.
@@ -13876,7 +14179,7 @@ async function applyInstallersOver(services, project, options = {}) {
13876
14179
  );
13877
14180
  } else if (outcome.outcome === "deno") {
13878
14181
  deno++;
13879
- const svcName = import_node_path54.default.basename(svc.dir);
14182
+ const svcName = import_node_path55.default.basename(svc.dir);
13880
14183
  console.log(
13881
14184
  `neat: ${svc.dir} detected as Deno
13882
14185
  The installer doesn't cover this runtime deterministically.
@@ -13887,7 +14190,7 @@ async function applyInstallersOver(services, project, options = {}) {
13887
14190
  );
13888
14191
  } else if (outcome.outcome === "cloudflare-workers") {
13889
14192
  cloudflareWorkers++;
13890
- const svcName = import_node_path54.default.basename(svc.dir);
14193
+ const svcName = import_node_path55.default.basename(svc.dir);
13891
14194
  console.log(
13892
14195
  `neat: ${svc.dir} detected as Cloudflare Workers
13893
14196
  The installer doesn't cover this runtime deterministically.
@@ -13898,7 +14201,7 @@ async function applyInstallersOver(services, project, options = {}) {
13898
14201
  );
13899
14202
  } else if (outcome.outcome === "electron") {
13900
14203
  electron++;
13901
- const svcName = import_node_path54.default.basename(svc.dir);
14204
+ const svcName = import_node_path55.default.basename(svc.dir);
13902
14205
  console.log(
13903
14206
  `neat: ${svc.dir} detected as Electron
13904
14207
  The installer doesn't cover this runtime deterministically.
@@ -13911,7 +14214,7 @@ async function applyInstallersOver(services, project, options = {}) {
13911
14214
  if (svc.pkg && (outcome.outcome === "instrumented" || outcome.outcome === "already-instrumented")) {
13912
14215
  const gaps = uninstrumentedLibraries(svc.pkg);
13913
14216
  if (gaps.length > 0) {
13914
- const svcName = import_node_path54.default.basename(svc.dir);
14217
+ const svcName = import_node_path55.default.basename(svc.dir);
13915
14218
  const list = gaps.join(", ");
13916
14219
  const subject = gaps.length === 1 ? "this library" : "these libraries";
13917
14220
  const aux = gaps.length === 1 ? "isn't" : "aren't";
@@ -14117,24 +14420,24 @@ async function persistedPortsFor(scanPath) {
14117
14420
  return { rest: record.ports.rest, otlp: record.ports.otlp, web: record.ports.web };
14118
14421
  }
14119
14422
  async function acquireSpawnLock(scanPath) {
14120
- const lockPath = import_node_path54.default.join(scanPath, "neat-out", "daemon.spawn.lock");
14121
- await import_node_fs35.promises.mkdir(import_node_path54.default.dirname(lockPath), { recursive: true });
14423
+ const lockPath = import_node_path55.default.join(scanPath, "neat-out", "daemon.spawn.lock");
14424
+ await import_node_fs36.promises.mkdir(import_node_path55.default.dirname(lockPath), { recursive: true });
14122
14425
  const STALE_LOCK_MS = 6e4;
14123
14426
  try {
14124
- const fd = await import_node_fs35.promises.open(lockPath, "wx");
14427
+ const fd = await import_node_fs36.promises.open(lockPath, "wx");
14125
14428
  await fd.writeFile(`${process.pid}
14126
14429
  `, "utf8");
14127
14430
  await fd.close();
14128
14431
  return async () => {
14129
- await import_node_fs35.promises.unlink(lockPath).catch(() => {
14432
+ await import_node_fs36.promises.unlink(lockPath).catch(() => {
14130
14433
  });
14131
14434
  };
14132
14435
  } catch (err) {
14133
14436
  if (err.code !== "EEXIST") return null;
14134
14437
  try {
14135
- const stat = await import_node_fs35.promises.stat(lockPath);
14438
+ const stat = await import_node_fs36.promises.stat(lockPath);
14136
14439
  if (Date.now() - stat.mtimeMs > STALE_LOCK_MS) {
14137
- await import_node_fs35.promises.unlink(lockPath).catch(() => {
14440
+ await import_node_fs36.promises.unlink(lockPath).catch(() => {
14138
14441
  });
14139
14442
  return acquireSpawnLock(scanPath);
14140
14443
  }
@@ -14163,13 +14466,13 @@ async function healthIsForProject(restPort, project) {
14163
14466
  return false;
14164
14467
  }
14165
14468
  function daemonLogPath(projectPath2) {
14166
- return import_node_path54.default.join(projectPath2, "neat-out", "daemon.log");
14469
+ return import_node_path55.default.join(projectPath2, "neat-out", "daemon.log");
14167
14470
  }
14168
14471
  function spawnDaemonDetached(spec) {
14169
- const here = import_node_path54.default.dirname(new URL(importMetaUrl).pathname);
14472
+ const here = import_node_path55.default.dirname(new URL(importMetaUrl).pathname);
14170
14473
  const candidates = [
14171
- import_node_path54.default.join(here, "neatd.cjs"),
14172
- import_node_path54.default.join(here, "neatd.js")
14474
+ import_node_path55.default.join(here, "neatd.cjs"),
14475
+ import_node_path55.default.join(here, "neatd.js")
14173
14476
  ];
14174
14477
  let entry2 = null;
14175
14478
  const fsSync = require("fs");
@@ -14199,7 +14502,7 @@ function spawnDaemonDetached(spec) {
14199
14502
  let logFd = null;
14200
14503
  if (spec) {
14201
14504
  const logPath = daemonLogPath(spec.projectPath);
14202
- fsSync.mkdirSync(import_node_path54.default.dirname(logPath), { recursive: true });
14505
+ fsSync.mkdirSync(import_node_path55.default.dirname(logPath), { recursive: true });
14203
14506
  logFd = fsSync.openSync(logPath, "a");
14204
14507
  }
14205
14508
  const child = (0, import_node_child_process3.spawn)(process.execPath, [entry2, "start"], {
@@ -14238,7 +14541,7 @@ async function runOrchestrator(opts) {
14238
14541
  browser: "skipped"
14239
14542
  }
14240
14543
  };
14241
- const stat = await import_node_fs35.promises.stat(opts.scanPath).catch(() => null);
14544
+ const stat = await import_node_fs36.promises.stat(opts.scanPath).catch(() => null);
14242
14545
  if (!stat || !stat.isDirectory()) {
14243
14546
  console.error(`neat: ${opts.scanPath} is not a directory`);
14244
14547
  result.exitCode = 2;
@@ -14398,7 +14701,7 @@ async function runOrchestrator(opts) {
14398
14701
  result.steps.browser = openBrowser(dashboardUrl);
14399
14702
  }
14400
14703
  const daemonRunning = result.steps.daemon === "spawned" || result.steps.daemon === "already-running";
14401
- const daemonLog = daemonRunning ? import_node_path54.default.relative(opts.scanPath, daemonLogPath(opts.scanPath)) : null;
14704
+ const daemonLog = daemonRunning ? import_node_path55.default.relative(opts.scanPath, daemonLogPath(opts.scanPath)) : null;
14402
14705
  printSummary(result, graph, dashboardUrl, daemonLog);
14403
14706
  return result;
14404
14707
  }
@@ -14766,11 +15069,11 @@ async function runConnectorCommand(rawArgs, deps = {}) {
14766
15069
 
14767
15070
  // src/cli-verbs.ts
14768
15071
  init_cjs_shims();
14769
- var import_node_path55 = __toESM(require("path"), 1);
15072
+ var import_node_path56 = __toESM(require("path"), 1);
14770
15073
 
14771
15074
  // src/cli-client.ts
14772
15075
  init_cjs_shims();
14773
- var import_types43 = require("@neat.is/types");
15076
+ var import_types44 = require("@neat.is/types");
14774
15077
  var HttpError = class extends Error {
14775
15078
  constructor(status2, message, responseBody = "") {
14776
15079
  super(message);
@@ -14795,10 +15098,10 @@ function createHttpClient(baseUrl, bearerToken) {
14795
15098
  const root = baseUrl.replace(/\/$/, "");
14796
15099
  const authHeader = bearerToken && bearerToken.length > 0 ? { authorization: `Bearer ${bearerToken}` } : {};
14797
15100
  return {
14798
- async get(path57) {
15101
+ async get(path58) {
14799
15102
  let res;
14800
15103
  try {
14801
- res = await fetch(`${root}${path57}`, {
15104
+ res = await fetch(`${root}${path58}`, {
14802
15105
  headers: { ...authHeader }
14803
15106
  });
14804
15107
  } catch (err) {
@@ -14810,16 +15113,16 @@ function createHttpClient(baseUrl, bearerToken) {
14810
15113
  const body = await res.text().catch(() => "");
14811
15114
  throw new HttpError(
14812
15115
  res.status,
14813
- `${res.status} ${res.statusText} on GET ${path57}: ${body}`,
15116
+ `${res.status} ${res.statusText} on GET ${path58}: ${body}`,
14814
15117
  body
14815
15118
  );
14816
15119
  }
14817
15120
  return await res.json();
14818
15121
  },
14819
- async post(path57, body) {
15122
+ async post(path58, body) {
14820
15123
  let res;
14821
15124
  try {
14822
- res = await fetch(`${root}${path57}`, {
15125
+ res = await fetch(`${root}${path58}`, {
14823
15126
  method: "POST",
14824
15127
  headers: { "content-type": "application/json", ...authHeader },
14825
15128
  body: JSON.stringify(body)
@@ -14833,7 +15136,7 @@ function createHttpClient(baseUrl, bearerToken) {
14833
15136
  const text = await res.text().catch(() => "");
14834
15137
  throw new HttpError(
14835
15138
  res.status,
14836
- `${res.status} ${res.statusText} on POST ${path57}: ${text}`,
15139
+ `${res.status} ${res.statusText} on POST ${path58}: ${text}`,
14837
15140
  text
14838
15141
  );
14839
15142
  }
@@ -14847,12 +15150,12 @@ function projectPath(project, suffix) {
14847
15150
  }
14848
15151
  async function runRootCause(client, input) {
14849
15152
  const qs = input.errorId ? `?errorId=${encodeURIComponent(input.errorId)}` : "";
14850
- const path57 = projectPath(
15153
+ const path58 = projectPath(
14851
15154
  input.project,
14852
15155
  `/graph/root-cause/${encodeURIComponent(input.errorNode)}${qs}`
14853
15156
  );
14854
15157
  try {
14855
- const result = await client.get(path57);
15158
+ const result = await client.get(path58);
14856
15159
  const arrowPath = result.traversalPath.join(" \u2190 ");
14857
15160
  const provenances = result.edgeProvenances.length ? result.edgeProvenances.join(", ") : "(direct, no edges traversed)";
14858
15161
  const summary = `Root cause for ${input.errorNode} is ${result.rootCauseNode}. ` + result.rootCauseReason + (result.fixRecommendation ? ` Recommended fix: ${result.fixRecommendation}.` : "");
@@ -14878,12 +15181,12 @@ async function runRootCause(client, input) {
14878
15181
  }
14879
15182
  async function runBlastRadius(client, input) {
14880
15183
  const qs = input.depth !== void 0 ? `?depth=${input.depth}` : "";
14881
- const path57 = projectPath(
15184
+ const path58 = projectPath(
14882
15185
  input.project,
14883
15186
  `/graph/blast-radius/${encodeURIComponent(input.nodeId)}${qs}`
14884
15187
  );
14885
15188
  try {
14886
- const result = await client.get(path57);
15189
+ const result = await client.get(path58);
14887
15190
  if (result.totalAffected === 0) {
14888
15191
  return {
14889
15192
  summary: `${result.origin} has no dependents. Nothing else would break if it failed.`
@@ -14912,17 +15215,17 @@ async function runBlastRadius(client, input) {
14912
15215
  }
14913
15216
  }
14914
15217
  function formatBlastEntry(n) {
14915
- const tag = n.edgeProvenance === import_types43.Provenance.STALE ? " [STALE \u2014 last seen too long ago]" : "";
15218
+ const tag = n.edgeProvenance === import_types44.Provenance.STALE ? " [STALE \u2014 last seen too long ago]" : "";
14916
15219
  return ` \u2022 ${n.nodeId} (distance ${n.distance}, ${n.edgeProvenance})${tag}`;
14917
15220
  }
14918
15221
  async function runDependencies(client, input) {
14919
15222
  const depth = input.depth ?? 3;
14920
- const path57 = projectPath(
15223
+ const path58 = projectPath(
14921
15224
  input.project,
14922
15225
  `/graph/dependencies/${encodeURIComponent(input.nodeId)}?depth=${depth}`
14923
15226
  );
14924
15227
  try {
14925
- const result = await client.get(path57);
15228
+ const result = await client.get(path58);
14926
15229
  if (result.total === 0) {
14927
15230
  return {
14928
15231
  summary: depth === 1 ? `${input.nodeId} has no direct dependencies in the graph.` : `${input.nodeId} has no dependencies (BFS to depth ${depth}).`
@@ -14969,7 +15272,7 @@ async function runObservedDependencies(client, input) {
14969
15272
  if (result.observed) {
14970
15273
  return {
14971
15274
  summary: `${input.nodeId} makes no outbound runtime calls, but OTel has observed it receiving traffic on ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 it's a pure receiver.`,
14972
- provenance: import_types43.Provenance.OBSERVED
15275
+ provenance: import_types44.Provenance.OBSERVED
14973
15276
  };
14974
15277
  }
14975
15278
  const note = result.hasExtractedOutbound ? " Static (EXTRACTED) dependencies exist but no runtime traffic has been seen \u2014 is OTel running?" : "";
@@ -14979,7 +15282,7 @@ async function runObservedDependencies(client, input) {
14979
15282
  return {
14980
15283
  summary: `${input.nodeId} has ${result.dependencies.length} runtime dependenc${result.dependencies.length === 1 ? "y" : "ies"} confirmed by OTel.`,
14981
15284
  block: blockLines.join("\n"),
14982
- provenance: import_types43.Provenance.OBSERVED
15285
+ provenance: import_types44.Provenance.OBSERVED
14983
15286
  };
14984
15287
  } catch (err) {
14985
15288
  if (err instanceof HttpError && err.status === 404) {
@@ -15014,9 +15317,9 @@ function formatDuration(ms) {
15014
15317
  return `${Math.round(h / 24)}d`;
15015
15318
  }
15016
15319
  async function runIncidents(client, input) {
15017
- const path57 = input.nodeId ? projectPath(input.project, `/incidents/${encodeURIComponent(input.nodeId)}`) : projectPath(input.project, "/incidents");
15320
+ const path58 = input.nodeId ? projectPath(input.project, `/incidents/${encodeURIComponent(input.nodeId)}`) : projectPath(input.project, "/incidents");
15018
15321
  try {
15019
- const body = await client.get(path57);
15322
+ const body = await client.get(path58);
15020
15323
  const events = body.events;
15021
15324
  if (events.length === 0) {
15022
15325
  return {
@@ -15033,7 +15336,7 @@ async function runIncidents(client, input) {
15033
15336
  return {
15034
15337
  summary: `${target} has ${body.total} recorded incident${body.total === 1 ? "" : "s"}; showing the ${ordered.length} most recent.`,
15035
15338
  block: blockLines.join("\n"),
15036
- provenance: import_types43.Provenance.OBSERVED
15339
+ provenance: import_types44.Provenance.OBSERVED
15037
15340
  };
15038
15341
  } catch (err) {
15039
15342
  if (err instanceof HttpError && err.status === 404) {
@@ -15142,7 +15445,7 @@ async function runStaleEdges(client, input) {
15142
15445
  return {
15143
15446
  summary: `${events.length} stale-edge transition${events.length === 1 ? "" : "s"} recorded${input.edgeType ? ` for ${input.edgeType}` : ""}.`,
15144
15447
  block: blockLines.join("\n"),
15145
- provenance: import_types43.Provenance.STALE
15448
+ provenance: import_types44.Provenance.STALE
15146
15449
  };
15147
15450
  }
15148
15451
  async function runPolicies(client, input) {
@@ -15306,7 +15609,7 @@ async function resolveProjectEntry(opts) {
15306
15609
  const cwd = opts.cwd ?? process.cwd();
15307
15610
  const resolvedCwd = await normalizeProjectPath(cwd);
15308
15611
  for (const entry2 of entries) {
15309
- if (resolvedCwd === entry2.path || resolvedCwd.startsWith(`${entry2.path}${import_node_path55.default.sep}`)) {
15612
+ if (resolvedCwd === entry2.path || resolvedCwd.startsWith(`${entry2.path}${import_node_path56.default.sep}`)) {
15310
15613
  return entry2;
15311
15614
  }
15312
15615
  }
@@ -15459,7 +15762,7 @@ async function runSync(opts) {
15459
15762
  }
15460
15763
 
15461
15764
  // src/cli.ts
15462
- var import_types44 = require("@neat.is/types");
15765
+ var import_types45 = require("@neat.is/types");
15463
15766
  function isNpxInvocation() {
15464
15767
  if (process.env.npm_command === "exec") return true;
15465
15768
  const execpath = process.env.npm_execpath ?? "";
@@ -15752,7 +16055,7 @@ async function buildPatchSections(services, project) {
15752
16055
  }
15753
16056
  async function runInit(opts) {
15754
16057
  const written = [];
15755
- const stat = await import_node_fs36.promises.stat(opts.scanPath).catch(() => null);
16058
+ const stat = await import_node_fs37.promises.stat(opts.scanPath).catch(() => null);
15756
16059
  if (!stat || !stat.isDirectory()) {
15757
16060
  console.error(`neat init: ${opts.scanPath} is not a directory`);
15758
16061
  return { exitCode: 2, writtenFiles: written };
@@ -15761,13 +16064,13 @@ async function runInit(opts) {
15761
16064
  printDiscoveryReport(opts, services);
15762
16065
  const sections = opts.noInstall ? [] : await buildPatchSections(services, opts.project);
15763
16066
  const patch = renderPatch(sections);
15764
- const patchPath = import_node_path56.default.join(opts.scanPath, "neat.patch");
16067
+ const patchPath = import_node_path57.default.join(opts.scanPath, "neat.patch");
15765
16068
  if (opts.dryRun) {
15766
- await import_node_fs36.promises.writeFile(patchPath, patch, "utf8");
16069
+ await import_node_fs37.promises.writeFile(patchPath, patch, "utf8");
15767
16070
  written.push(patchPath);
15768
16071
  console.log(`dry-run: patch written to ${patchPath}`);
15769
- const gitignorePath = import_node_path56.default.join(opts.scanPath, ".gitignore");
15770
- const gitignoreExists = await import_node_fs36.promises.stat(gitignorePath).then(() => true).catch(() => false);
16072
+ const gitignorePath = import_node_path57.default.join(opts.scanPath, ".gitignore");
16073
+ const gitignoreExists = await import_node_fs37.promises.stat(gitignorePath).then(() => true).catch(() => false);
15771
16074
  const verb = gitignoreExists ? "append" : "create";
15772
16075
  console.log(`dry-run: would ${verb} ${gitignorePath} (add neat-out/)`);
15773
16076
  console.log("rerun without --dry-run to register and snapshot.");
@@ -15778,9 +16081,9 @@ async function runInit(opts) {
15778
16081
  const graph = getGraph(graphKey);
15779
16082
  const projectPaths = pathsForProject(
15780
16083
  graphKey,
15781
- import_node_path56.default.join(opts.scanPath, "neat-out")
16084
+ import_node_path57.default.join(opts.scanPath, "neat-out")
15782
16085
  );
15783
- const errorsPath = import_node_path56.default.join(import_node_path56.default.dirname(opts.outPath), import_node_path56.default.basename(projectPaths.errorsPath));
16086
+ const errorsPath = import_node_path57.default.join(import_node_path57.default.dirname(opts.outPath), import_node_path57.default.basename(projectPaths.errorsPath));
15784
16087
  const result = await extractFromDirectory(graph, opts.scanPath, { errorsPath });
15785
16088
  await saveGraphToDisk(graph, opts.outPath);
15786
16089
  written.push(opts.outPath);
@@ -15859,7 +16162,7 @@ async function runInit(opts) {
15859
16162
  console.log("Run `npm install` (or your language equivalent) to refresh lockfiles.");
15860
16163
  }
15861
16164
  } else {
15862
- await import_node_fs36.promises.writeFile(patchPath, patch, "utf8");
16165
+ await import_node_fs37.promises.writeFile(patchPath, patch, "utf8");
15863
16166
  written.push(patchPath);
15864
16167
  }
15865
16168
  }
@@ -15899,9 +16202,9 @@ var CLAUDE_SKILL_CONFIG = {
15899
16202
  };
15900
16203
  function claudeConfigPath() {
15901
16204
  const override = process.env.NEAT_CLAUDE_CONFIG;
15902
- if (override && override.length > 0) return import_node_path56.default.resolve(override);
16205
+ if (override && override.length > 0) return import_node_path57.default.resolve(override);
15903
16206
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
15904
- return import_node_path56.default.join(home, ".claude.json");
16207
+ return import_node_path57.default.join(home, ".claude.json");
15905
16208
  }
15906
16209
  async function runSkill(opts) {
15907
16210
  const snippet2 = JSON.stringify(CLAUDE_SKILL_CONFIG, null, 2) + "\n";
@@ -15913,7 +16216,7 @@ async function runSkill(opts) {
15913
16216
  const target = claudeConfigPath();
15914
16217
  let existing = {};
15915
16218
  try {
15916
- existing = JSON.parse(await import_node_fs36.promises.readFile(target, "utf8"));
16219
+ existing = JSON.parse(await import_node_fs37.promises.readFile(target, "utf8"));
15917
16220
  } catch (err) {
15918
16221
  if (err.code !== "ENOENT") {
15919
16222
  console.error(`neat skill: failed to read ${target} \u2014 ${err.message}`);
@@ -15925,8 +16228,8 @@ async function runSkill(opts) {
15925
16228
  ...existing,
15926
16229
  mcpServers: { ...mcp, neat: CLAUDE_SKILL_CONFIG.mcpServers.neat }
15927
16230
  };
15928
- await import_node_fs36.promises.mkdir(import_node_path56.default.dirname(target), { recursive: true });
15929
- await import_node_fs36.promises.writeFile(target, JSON.stringify(merged, null, 2) + "\n", "utf8");
16231
+ await import_node_fs37.promises.mkdir(import_node_path57.default.dirname(target), { recursive: true });
16232
+ await import_node_fs37.promises.writeFile(target, JSON.stringify(merged, null, 2) + "\n", "utf8");
15930
16233
  console.log(`neat skill: wrote mcpServers.neat to ${target}`);
15931
16234
  console.log("restart Claude Code to pick up the new MCP server.");
15932
16235
  return { exitCode: 0 };
@@ -15980,12 +16283,12 @@ async function main() {
15980
16283
  console.error("neat init: --apply and --dry-run are mutually exclusive");
15981
16284
  process.exit(2);
15982
16285
  }
15983
- const scanPath = import_node_path56.default.resolve(target);
16286
+ const scanPath = import_node_path57.default.resolve(target);
15984
16287
  const projectExplicit = parsed.project !== null;
15985
- const projectName = projectExplicit ? project : import_node_path56.default.basename(scanPath);
16288
+ const projectName = projectExplicit ? project : import_node_path57.default.basename(scanPath);
15986
16289
  const projectKey = projectExplicit ? project : DEFAULT_PROJECT;
15987
- const fallback = pathsForProject(projectKey, import_node_path56.default.join(scanPath, "neat-out")).snapshotPath;
15988
- const outPath = import_node_path56.default.resolve(process.env.NEAT_OUT_PATH ?? fallback);
16290
+ const fallback = pathsForProject(projectKey, import_node_path57.default.join(scanPath, "neat-out")).snapshotPath;
16291
+ const outPath = import_node_path57.default.resolve(process.env.NEAT_OUT_PATH ?? fallback);
15989
16292
  const result = await runInit({
15990
16293
  scanPath,
15991
16294
  outPath,
@@ -16006,21 +16309,21 @@ async function main() {
16006
16309
  usage();
16007
16310
  process.exit(2);
16008
16311
  }
16009
- const scanPath = import_node_path56.default.resolve(target);
16010
- const stat = await import_node_fs36.promises.stat(scanPath).catch(() => null);
16312
+ const scanPath = import_node_path57.default.resolve(target);
16313
+ const stat = await import_node_fs37.promises.stat(scanPath).catch(() => null);
16011
16314
  if (!stat || !stat.isDirectory()) {
16012
16315
  console.error(`neat watch: ${scanPath} is not a directory`);
16013
16316
  process.exit(2);
16014
16317
  }
16015
- const projectPaths = pathsForProject(project, import_node_path56.default.join(scanPath, "neat-out"));
16016
- const outPath = import_node_path56.default.resolve(process.env.NEAT_OUT_PATH ?? projectPaths.snapshotPath);
16017
- const errorsPath = import_node_path56.default.resolve(
16018
- process.env.NEAT_ERRORS_PATH ?? import_node_path56.default.join(import_node_path56.default.dirname(outPath), import_node_path56.default.basename(projectPaths.errorsPath))
16318
+ const projectPaths = pathsForProject(project, import_node_path57.default.join(scanPath, "neat-out"));
16319
+ const outPath = import_node_path57.default.resolve(process.env.NEAT_OUT_PATH ?? projectPaths.snapshotPath);
16320
+ const errorsPath = import_node_path57.default.resolve(
16321
+ process.env.NEAT_ERRORS_PATH ?? import_node_path57.default.join(import_node_path57.default.dirname(outPath), import_node_path57.default.basename(projectPaths.errorsPath))
16019
16322
  );
16020
- const staleEventsPath = import_node_path56.default.resolve(
16021
- process.env.NEAT_STALE_EVENTS_PATH ?? import_node_path56.default.join(import_node_path56.default.dirname(outPath), import_node_path56.default.basename(projectPaths.staleEventsPath))
16323
+ const staleEventsPath = import_node_path57.default.resolve(
16324
+ process.env.NEAT_STALE_EVENTS_PATH ?? import_node_path57.default.join(import_node_path57.default.dirname(outPath), import_node_path57.default.basename(projectPaths.staleEventsPath))
16022
16325
  );
16023
- const embeddingsCachePath = process.env.NEAT_EMBEDDINGS_CACHE_PATH ? import_node_path56.default.resolve(process.env.NEAT_EMBEDDINGS_CACHE_PATH) : void 0;
16326
+ const embeddingsCachePath = process.env.NEAT_EMBEDDINGS_CACHE_PATH ? import_node_path57.default.resolve(process.env.NEAT_EMBEDDINGS_CACHE_PATH) : void 0;
16024
16327
  const handle = await startWatch(getGraph(project), {
16025
16328
  scanPath,
16026
16329
  outPath,
@@ -16203,11 +16506,11 @@ async function main() {
16203
16506
  process.exit(1);
16204
16507
  }
16205
16508
  async function tryOrchestrator(cmd, parsed) {
16206
- const scanPath = import_node_path56.default.resolve(cmd);
16207
- const stat = await import_node_fs36.promises.stat(scanPath).catch(() => null);
16509
+ const scanPath = import_node_path57.default.resolve(cmd);
16510
+ const stat = await import_node_fs37.promises.stat(scanPath).catch(() => null);
16208
16511
  if (!stat || !stat.isDirectory()) return null;
16209
16512
  const projectExplicit = parsed.project !== null;
16210
- const projectName = projectExplicit ? parsed.project : import_node_path56.default.basename(scanPath);
16513
+ const projectName = projectExplicit ? parsed.project : import_node_path57.default.basename(scanPath);
16211
16514
  const result = await runOrchestrator({
16212
16515
  scanPath,
16213
16516
  project: projectName,
@@ -16396,10 +16699,10 @@ async function runQueryVerb(cmd, parsed) {
16396
16699
  const parts = parsed.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
16397
16700
  const out = [];
16398
16701
  for (const p of parts) {
16399
- const r = import_types44.DivergenceTypeSchema.safeParse(p);
16702
+ const r = import_types45.DivergenceTypeSchema.safeParse(p);
16400
16703
  if (!r.success) {
16401
16704
  console.error(
16402
- `neat divergences: unknown --type "${p}". allowed: ${import_types44.DivergenceTypeSchema.options.join(", ")}`
16705
+ `neat divergences: unknown --type "${p}". allowed: ${import_types45.DivergenceTypeSchema.options.join(", ")}`
16403
16706
  );
16404
16707
  return 2;
16405
16708
  }