@neat.is/core 0.7.2 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3503,19 +3503,19 @@ function confidenceFromMix(edges, now = Date.now()) {
3503
3503
  function longestIncomingWalk(graph, start, maxDepth) {
3504
3504
  let best = { path: [start], edges: [] };
3505
3505
  const visited = /* @__PURE__ */ new Set([start]);
3506
- function step(node, path55, edges) {
3507
- if (path55.length > best.path.length) {
3508
- best = { path: [...path55], edges: [...edges] };
3506
+ function step(node, path56, edges) {
3507
+ if (path56.length > best.path.length) {
3508
+ best = { path: [...path56], edges: [...edges] };
3509
3509
  }
3510
- if (path55.length - 1 >= maxDepth) return;
3510
+ if (path56.length - 1 >= maxDepth) return;
3511
3511
  const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
3512
3512
  for (const [srcId, edge] of incoming) {
3513
3513
  if (visited.has(srcId)) continue;
3514
3514
  visited.add(srcId);
3515
- path55.push(srcId);
3515
+ path56.push(srcId);
3516
3516
  edges.push(edge);
3517
- step(srcId, path55, edges);
3518
- path55.pop();
3517
+ step(srcId, path56, edges);
3518
+ path56.pop();
3519
3519
  edges.pop();
3520
3520
  visited.delete(srcId);
3521
3521
  }
@@ -3722,26 +3722,26 @@ function dominantFailingCall(graph, serviceId7, visited) {
3722
3722
  return best;
3723
3723
  }
3724
3724
  function followFailingCallChain(graph, originServiceId, maxDepth) {
3725
- const path55 = [originServiceId];
3725
+ const path56 = [originServiceId];
3726
3726
  const edges = [];
3727
3727
  const visited = /* @__PURE__ */ new Set([originServiceId]);
3728
3728
  let current = originServiceId;
3729
3729
  for (let depth = 0; depth < maxDepth; depth++) {
3730
3730
  const hop = dominantFailingCall(graph, current, visited);
3731
3731
  if (!hop) break;
3732
- path55.push(hop.nextService);
3732
+ path56.push(hop.nextService);
3733
3733
  edges.push(hop.edge);
3734
3734
  visited.add(hop.nextService);
3735
3735
  current = hop.nextService;
3736
3736
  }
3737
3737
  if (edges.length === 0) return null;
3738
- return { path: path55, edges, culprit: current };
3738
+ return { path: path56, edges, culprit: current };
3739
3739
  }
3740
3740
  function crossServiceRootCause(graph, originId, incidents, errorEvent) {
3741
3741
  const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
3742
3742
  if (!chain) return null;
3743
3743
  const culprit = chain.culprit;
3744
- const path55 = [...chain.path];
3744
+ const path56 = [...chain.path];
3745
3745
  const edgeProvenances = chain.edges.map((e) => e.provenance);
3746
3746
  const baseConfidence = confidenceFromMix(chain.edges);
3747
3747
  const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
@@ -3749,14 +3749,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
3749
3749
  if (loc) {
3750
3750
  let rootCauseNode = culprit;
3751
3751
  if (loc.fileNode) {
3752
- path55.push(loc.fileNode);
3752
+ path56.push(loc.fileNode);
3753
3753
  edgeProvenances.push(Provenance5.OBSERVED);
3754
3754
  rootCauseNode = loc.fileNode;
3755
3755
  }
3756
3756
  return RootCauseResultSchema.parse({
3757
3757
  rootCauseNode,
3758
3758
  rootCauseReason: loc.rootCauseReason,
3759
- traversalPath: path55,
3759
+ traversalPath: path56,
3760
3760
  edgeProvenances,
3761
3761
  confidence,
3762
3762
  ...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
@@ -3768,7 +3768,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
3768
3768
  return RootCauseResultSchema.parse({
3769
3769
  rootCauseNode: culprit,
3770
3770
  rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
3771
- traversalPath: path55,
3771
+ traversalPath: path56,
3772
3772
  edgeProvenances,
3773
3773
  confidence,
3774
3774
  fixRecommendation: `Inspect ${culpritName}'s failing handler`
@@ -7692,11 +7692,138 @@ function drizzleEndpointsFromFile(file, serviceDir) {
7692
7692
  return out;
7693
7693
  }
7694
7694
 
7695
- // src/extract/calls/go.ts
7695
+ // src/extract/calls/prisma.ts
7696
7696
  import path38 from "path";
7697
+ import { infraId as infraId11 } from "@neat.is/types";
7698
+ var SCALAR_TYPES = /* @__PURE__ */ new Set([
7699
+ "Int",
7700
+ "String",
7701
+ "Boolean",
7702
+ "DateTime",
7703
+ "Float",
7704
+ "Decimal",
7705
+ "BigInt",
7706
+ "Bytes",
7707
+ "Json"
7708
+ ]);
7709
+ function stripLineComment(line) {
7710
+ let inStr = false;
7711
+ for (let i = 0; i < line.length; i++) {
7712
+ const ch = line[i];
7713
+ if (ch === '"' && line[i - 1] !== "\\") inStr = !inStr;
7714
+ else if (!inStr && ch === "/" && line[i + 1] === "/") return line.slice(0, i);
7715
+ }
7716
+ return line;
7717
+ }
7718
+ function netBraces(line) {
7719
+ const s = stripLineComment(line).replace(/"(\\.|[^"\\])*"/g, "");
7720
+ let n = 0;
7721
+ for (const ch of s) {
7722
+ if (ch === "{") n++;
7723
+ else if (ch === "}") n--;
7724
+ }
7725
+ return n;
7726
+ }
7727
+ function prismaColumnsFromSchema(file, serviceDir) {
7728
+ const content = file.content;
7729
+ if (!/\bmodel\s+[A-Za-z_]\w*\s*\{/.test(content)) return [];
7730
+ const lines = content.split("\n");
7731
+ const modelNames = /* @__PURE__ */ new Set();
7732
+ const enumNames = /* @__PURE__ */ new Set();
7733
+ for (const line of lines) {
7734
+ const m = line.match(/^\s*model\s+([A-Za-z_]\w*)\s*\{/);
7735
+ if (m) modelNames.add(m[1]);
7736
+ const e = line.match(/^\s*enum\s+([A-Za-z_]\w*)\s*\{/);
7737
+ if (e) enumNames.add(e[1]);
7738
+ }
7739
+ const out = [];
7740
+ const seenTable = /* @__PURE__ */ new Set();
7741
+ const finalize = (b) => {
7742
+ if (seenTable.has(b.tableName)) return;
7743
+ seenTable.add(b.tableName);
7744
+ out.push({
7745
+ infraId: infraId11("sql-table", b.tableName),
7746
+ name: b.tableName,
7747
+ kind: "sql-table",
7748
+ edgeType: "CALLS",
7749
+ confidenceKind: "structural",
7750
+ columns: b.columns,
7751
+ evidence: {
7752
+ file: path38.relative(serviceDir, file.path),
7753
+ line: b.startLine,
7754
+ snippet: snippet(content, b.startLine)
7755
+ }
7756
+ });
7757
+ };
7758
+ let current = null;
7759
+ let depth = 0;
7760
+ for (let i = 0; i < lines.length; i++) {
7761
+ const raw = lines[i];
7762
+ const lineNo = i + 1;
7763
+ if (current === null) {
7764
+ const header = raw.match(/^\s*(model|enum|datasource|generator|type)\s+([A-Za-z_]\w*)\b/);
7765
+ if (header && raw.includes("{")) {
7766
+ current = {
7767
+ kind: header[1],
7768
+ tableName: header[2],
7769
+ startLine: lineNo,
7770
+ columns: [],
7771
+ seenCol: /* @__PURE__ */ new Set()
7772
+ };
7773
+ depth = netBraces(raw);
7774
+ if (depth <= 0) {
7775
+ if (current.kind === "model") finalize(current);
7776
+ current = null;
7777
+ }
7778
+ }
7779
+ continue;
7780
+ }
7781
+ depth += netBraces(raw);
7782
+ if (depth <= 0) {
7783
+ if (current.kind === "model") finalize(current);
7784
+ current = null;
7785
+ continue;
7786
+ }
7787
+ if (current.kind !== "model") continue;
7788
+ const trimmed = stripLineComment(raw).trim();
7789
+ if (!trimmed) continue;
7790
+ if (trimmed.startsWith("@@")) {
7791
+ const map = trimmed.match(/@@map\(\s*"([^"]+)"\s*\)/);
7792
+ if (map) current.tableName = map[1];
7793
+ continue;
7794
+ }
7795
+ const fm = trimmed.match(/^([A-Za-z_]\w*)\s+([A-Za-z_]\w*)/);
7796
+ if (!fm) continue;
7797
+ const fieldName = fm[1];
7798
+ const baseType = fm[2];
7799
+ if (/@relation\b/.test(trimmed) || modelNames.has(baseType)) continue;
7800
+ if (!enumNames.has(baseType) && !SCALAR_TYPES.has(baseType)) continue;
7801
+ const mapM = trimmed.match(/(?<!@)@map\(\s*"([^"]+)"\s*\)/);
7802
+ const columnName = mapM ? mapM[1] : fieldName;
7803
+ if (!current.seenCol.has(columnName)) {
7804
+ current.seenCol.add(columnName);
7805
+ current.columns.push(columnName);
7806
+ }
7807
+ }
7808
+ if (current && current.kind === "model") finalize(current);
7809
+ return out;
7810
+ }
7811
+ async function prismaColumnEndpoints(serviceDir) {
7812
+ const schemaPath = await findFirst(serviceDir, [
7813
+ path38.join("prisma", "schema.prisma"),
7814
+ "schema.prisma"
7815
+ ]);
7816
+ if (!schemaPath) return [];
7817
+ const content = await readIfExists(schemaPath);
7818
+ if (!content) return [];
7819
+ return prismaColumnsFromSchema({ path: schemaPath, content }, serviceDir);
7820
+ }
7821
+
7822
+ // src/extract/calls/go.ts
7823
+ import path39 from "path";
7697
7824
  import Parser10 from "tree-sitter";
7698
7825
  import Go3 from "tree-sitter-go";
7699
- import { infraId as infraId11 } from "@neat.is/types";
7826
+ import { infraId as infraId12 } from "@neat.is/types";
7700
7827
  var SQL_METHODS = /* @__PURE__ */ new Set(["Exec", "ExecContext", "Query", "QueryContext", "QueryRow", "QueryRowContext"]);
7701
7828
  var PARSE_CHUNK8 = 16384;
7702
7829
  function walk5(node, visit) {
@@ -7707,7 +7834,7 @@ function walk5(node, visit) {
7707
7834
  }
7708
7835
  }
7709
7836
  function goSqlEndpointsFromFile(file, serviceDir) {
7710
- if (path38.extname(file.path) !== ".go") return [];
7837
+ if (path39.extname(file.path) !== ".go") return [];
7711
7838
  const parser = new Parser10();
7712
7839
  parser.setLanguage(Go3);
7713
7840
  const tree = parser.parse(
@@ -7727,12 +7854,12 @@ function goSqlEndpointsFromFile(file, serviceDir) {
7727
7854
  if (!table) return;
7728
7855
  const line = node.startPosition.row + 1;
7729
7856
  out.push({
7730
- infraId: infraId11("sql-table", table),
7857
+ infraId: infraId12("sql-table", table),
7731
7858
  name: table,
7732
7859
  kind: "sql-table",
7733
7860
  edgeType: "CALLS",
7734
7861
  confidenceKind: "verified-call-site",
7735
- evidence: { file: toPosix(path38.relative(serviceDir, file.path)), line, snippet: snippet(file.content, line) }
7862
+ evidence: { file: toPosix(path39.relative(serviceDir, file.path)), line, snippet: snippet(file.content, line) }
7736
7863
  });
7737
7864
  });
7738
7865
  return out;
@@ -7781,6 +7908,7 @@ async function addExternalEndpointEdges(graph, services) {
7781
7908
  }
7782
7909
  endpoints.push(...await mongooseCrossFileEndpoints(maskedFiles, service.dir));
7783
7910
  endpoints.push(...pythonOrmCrossFileEndpoints(maskedFiles, service.dir));
7911
+ endpoints.push(...await prismaColumnEndpoints(service.dir));
7784
7912
  if (endpoints.length === 0) continue;
7785
7913
  const seenEdges = /* @__PURE__ */ new Set();
7786
7914
  for (const ep of endpoints) {
@@ -7865,14 +7993,14 @@ async function addCallEdges(graph, services) {
7865
7993
  }
7866
7994
 
7867
7995
  // src/extract/infra/docker-compose.ts
7868
- import path39 from "path";
7996
+ import path40 from "path";
7869
7997
  import { EdgeType as EdgeType15, Provenance as Provenance16, confidenceForExtracted as confidenceForExtracted13 } from "@neat.is/types";
7870
7998
 
7871
7999
  // src/extract/infra/shared.ts
7872
- import { NodeType as NodeType16, Provenance as Provenance15, confidenceForExtracted as confidenceForExtracted12, infraId as infraId12 } from "@neat.is/types";
8000
+ import { NodeType as NodeType16, Provenance as Provenance15, confidenceForExtracted as confidenceForExtracted12, infraId as infraId13 } from "@neat.is/types";
7873
8001
  function makeInfraNode(kind, name, provider = "self", extras) {
7874
8002
  return {
7875
- id: infraId12(kind, name),
8003
+ id: infraId13(kind, name),
7876
8004
  type: NodeType16.InfraNode,
7877
8005
  name,
7878
8006
  provider,
@@ -7935,7 +8063,7 @@ function dependsOnList(value) {
7935
8063
  }
7936
8064
  function serviceNameToServiceNode(name, services) {
7937
8065
  for (const s of services) {
7938
- if (s.node.name === name || path39.basename(s.dir) === name) return s.node.id;
8066
+ if (s.node.name === name || path40.basename(s.dir) === name) return s.node.id;
7939
8067
  }
7940
8068
  return null;
7941
8069
  }
@@ -7944,7 +8072,7 @@ async function addComposeInfra(graph, scanPath, services) {
7944
8072
  let edgesAdded = 0;
7945
8073
  let composePath = null;
7946
8074
  for (const name of ["docker-compose.yml", "docker-compose.yaml"]) {
7947
- const abs = path39.join(scanPath, name);
8075
+ const abs = path40.join(scanPath, name);
7948
8076
  if (await exists(abs)) {
7949
8077
  composePath = abs;
7950
8078
  break;
@@ -7957,13 +8085,13 @@ async function addComposeInfra(graph, scanPath, services) {
7957
8085
  } catch (err) {
7958
8086
  recordExtractionError(
7959
8087
  "infra docker-compose",
7960
- path39.relative(scanPath, composePath),
8088
+ path40.relative(scanPath, composePath),
7961
8089
  err
7962
8090
  );
7963
8091
  return { nodesAdded, edgesAdded };
7964
8092
  }
7965
8093
  if (!compose?.services) return { nodesAdded, edgesAdded };
7966
- const evidenceFile = path39.relative(scanPath, composePath).split(path39.sep).join("/");
8094
+ const evidenceFile = path40.relative(scanPath, composePath).split(path40.sep).join("/");
7967
8095
  const composeNameToNodeId = /* @__PURE__ */ new Map();
7968
8096
  for (const [composeName, svc] of Object.entries(compose.services)) {
7969
8097
  const matchedServiceId = serviceNameToServiceNode(composeName, services);
@@ -8004,7 +8132,7 @@ async function addComposeInfra(graph, scanPath, services) {
8004
8132
  }
8005
8133
 
8006
8134
  // src/extract/infra/dockerfile.ts
8007
- import path40 from "path";
8135
+ import path41 from "path";
8008
8136
  import { promises as fs17 } from "fs";
8009
8137
  import { EdgeType as EdgeType16, Provenance as Provenance17, confidenceForExtracted as confidenceForExtracted14 } from "@neat.is/types";
8010
8138
  function readDockerfile(content) {
@@ -8035,7 +8163,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8035
8163
  let nodesAdded = 0;
8036
8164
  let edgesAdded = 0;
8037
8165
  for (const service of services) {
8038
- const dockerfilePath = path40.join(service.dir, "Dockerfile");
8166
+ const dockerfilePath = path41.join(service.dir, "Dockerfile");
8039
8167
  if (!await exists(dockerfilePath)) continue;
8040
8168
  let content;
8041
8169
  try {
@@ -8043,7 +8171,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8043
8171
  } catch (err) {
8044
8172
  recordExtractionError(
8045
8173
  "infra dockerfile",
8046
- path40.relative(scanPath, dockerfilePath),
8174
+ path41.relative(scanPath, dockerfilePath),
8047
8175
  err
8048
8176
  );
8049
8177
  continue;
@@ -8055,8 +8183,8 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8055
8183
  graph.addNode(node.id, node);
8056
8184
  nodesAdded++;
8057
8185
  }
8058
- const relDockerfile = toPosix(path40.relative(service.dir, dockerfilePath));
8059
- const evidenceFile = toPosix(path40.relative(scanPath, dockerfilePath));
8186
+ const relDockerfile = toPosix(path41.relative(service.dir, dockerfilePath));
8187
+ const evidenceFile = toPosix(path41.relative(scanPath, dockerfilePath));
8060
8188
  const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
8061
8189
  graph,
8062
8190
  service.pkg.name,
@@ -8108,7 +8236,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
8108
8236
 
8109
8237
  // src/extract/infra/terraform.ts
8110
8238
  import { promises as fs18 } from "fs";
8111
- import path41 from "path";
8239
+ import path42 from "path";
8112
8240
  import { EdgeType as EdgeType17, Provenance as Provenance18, confidenceForExtracted as confidenceForExtracted15 } from "@neat.is/types";
8113
8241
  var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
8114
8242
  var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
@@ -8119,11 +8247,11 @@ async function walkTfFiles(start, depth = 0, max = 5) {
8119
8247
  for (const entry of entries) {
8120
8248
  if (entry.isDirectory()) {
8121
8249
  if (IGNORED_DIRS.has(entry.name) || entry.name === ".terraform") continue;
8122
- const child = path41.join(start, entry.name);
8250
+ const child = path42.join(start, entry.name);
8123
8251
  if (await isPythonVenvDir(child)) continue;
8124
8252
  out.push(...await walkTfFiles(child, depth + 1, max));
8125
8253
  } else if (entry.isFile() && entry.name.endsWith(".tf")) {
8126
- out.push(path41.join(start, entry.name));
8254
+ out.push(path42.join(start, entry.name));
8127
8255
  }
8128
8256
  }
8129
8257
  return out;
@@ -8155,7 +8283,7 @@ async function addTerraformResources(graph, scanPath) {
8155
8283
  const files = await walkTfFiles(scanPath);
8156
8284
  for (const file of files) {
8157
8285
  const content = await fs18.readFile(file, "utf8");
8158
- const evidenceFile = toPosix(path41.relative(scanPath, file));
8286
+ const evidenceFile = toPosix(path42.relative(scanPath, file));
8159
8287
  const resources = [];
8160
8288
  const byKey = /* @__PURE__ */ new Map();
8161
8289
  RESOURCE_RE.lastIndex = 0;
@@ -8212,7 +8340,7 @@ async function addTerraformResources(graph, scanPath) {
8212
8340
 
8213
8341
  // src/extract/infra/k8s.ts
8214
8342
  import { promises as fs19 } from "fs";
8215
- import path42 from "path";
8343
+ import path43 from "path";
8216
8344
  import { parseAllDocuments as parseAllDocuments2 } from "yaml";
8217
8345
  var K8S_KIND_TO_INFRA_KIND = {
8218
8346
  Service: "k8s-service",
@@ -8230,11 +8358,11 @@ async function walkYamlFiles2(start, depth = 0, max = 5) {
8230
8358
  for (const entry of entries) {
8231
8359
  if (entry.isDirectory()) {
8232
8360
  if (IGNORED_DIRS.has(entry.name)) continue;
8233
- const child = path42.join(start, entry.name);
8361
+ const child = path43.join(start, entry.name);
8234
8362
  if (await isPythonVenvDir(child)) continue;
8235
8363
  out.push(...await walkYamlFiles2(child, depth + 1, max));
8236
- } else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(path42.extname(entry.name))) {
8237
- out.push(path42.join(start, entry.name));
8364
+ } else if (entry.isFile() && CONFIG_FILE_EXTENSIONS.has(path43.extname(entry.name))) {
8365
+ out.push(path43.join(start, entry.name));
8238
8366
  }
8239
8367
  }
8240
8368
  return out;
@@ -8267,13 +8395,13 @@ async function addK8sResources(graph, scanPath) {
8267
8395
 
8268
8396
  // src/extract/infra/cloudflare.ts
8269
8397
  import { promises as fs20 } from "fs";
8270
- import path43 from "path";
8398
+ import path44 from "path";
8271
8399
  import { parse as parseToml2 } from "smol-toml";
8272
8400
  import { EdgeType as EdgeType18, Provenance as Provenance19, confidenceForExtracted as confidenceForExtracted16 } from "@neat.is/types";
8273
8401
  var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
8274
8402
  async function readWranglerConfig(dir) {
8275
8403
  for (const filename of WRANGLER_FILENAMES) {
8276
- const abs = path43.join(dir, filename);
8404
+ const abs = path44.join(dir, filename);
8277
8405
  if (!await exists(abs)) continue;
8278
8406
  const raw = await fs20.readFile(abs, "utf8");
8279
8407
  const config = filename === "wrangler.toml" ? parseToml2(raw) : JSON.parse(maskCommentsInSource(raw));
@@ -8336,11 +8464,11 @@ async function addCloudflareWorkers(graph, services, scanPath) {
8336
8464
  try {
8337
8465
  read = await readWranglerConfig(service.dir);
8338
8466
  } catch (err) {
8339
- recordExtractionError("infra cloudflare", path43.relative(scanPath, service.dir), err);
8467
+ recordExtractionError("infra cloudflare", path44.relative(scanPath, service.dir), err);
8340
8468
  continue;
8341
8469
  }
8342
8470
  if (!read || !read.config.name) continue;
8343
- const evidenceFile = toPosix(path43.relative(scanPath, path43.join(service.dir, read.relFile)));
8471
+ const evidenceFile = toPosix(path44.relative(scanPath, path44.join(service.dir, read.relFile)));
8344
8472
  discovered.push({ service, config: read.config, relFile: read.relFile, raw: read.raw, evidenceFile });
8345
8473
  }
8346
8474
  for (const worker of discovered) {
@@ -8352,7 +8480,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
8352
8480
  }
8353
8481
  let anchorId = service.node.id;
8354
8482
  if (config.main) {
8355
- const entryRelPath = toPosix(path43.normalize(config.main));
8483
+ const entryRelPath = toPosix(path44.normalize(config.main));
8356
8484
  const { fileNodeId, nodesAdded: fn, edgesAdded: fe } = ensureFileNode(
8357
8485
  graph,
8358
8486
  service.pkg.name,
@@ -8499,12 +8627,12 @@ async function addCloudflareWorkers(graph, services, scanPath) {
8499
8627
 
8500
8628
  // src/extract/infra/vercel.ts
8501
8629
  import { promises as fs21 } from "fs";
8502
- import path44 from "path";
8630
+ import path45 from "path";
8503
8631
  import { EdgeType as EdgeType19 } from "@neat.is/types";
8504
8632
  var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
8505
8633
  async function readVercelConfig(dir) {
8506
8634
  for (const filename of VERCEL_CONFIG_FILENAMES) {
8507
- const abs = path44.join(dir, filename);
8635
+ const abs = path45.join(dir, filename);
8508
8636
  if (!await exists(abs)) continue;
8509
8637
  const raw = await fs21.readFile(abs, "utf8");
8510
8638
  const config = JSON.parse(maskCommentsInSource(raw));
@@ -8513,7 +8641,7 @@ async function readVercelConfig(dir) {
8513
8641
  return null;
8514
8642
  }
8515
8643
  async function readLinkedProjectName(dir) {
8516
- const abs = path44.join(dir, ".vercel", "project.json");
8644
+ const abs = path45.join(dir, ".vercel", "project.json");
8517
8645
  if (!await exists(abs)) return void 0;
8518
8646
  const parsed = JSON.parse(await fs21.readFile(abs, "utf8"));
8519
8647
  return typeof parsed.projectName === "string" ? parsed.projectName : void 0;
@@ -8531,7 +8659,7 @@ async function addVercelServices(graph, services, scanPath) {
8531
8659
  read = await readVercelConfig(service.dir);
8532
8660
  projectName = await readLinkedProjectName(service.dir);
8533
8661
  } catch (err) {
8534
- recordExtractionError("infra vercel", path44.relative(scanPath, service.dir), err);
8662
+ recordExtractionError("infra vercel", path45.relative(scanPath, service.dir), err);
8535
8663
  continue;
8536
8664
  }
8537
8665
  if (!read && !projectName) continue;
@@ -8547,7 +8675,7 @@ async function addVercelServices(graph, services, scanPath) {
8547
8675
  const anchorId = service.node.id;
8548
8676
  if (!read) continue;
8549
8677
  const { config, relFile, raw } = read;
8550
- const evidenceFile = toPosix(path44.relative(scanPath, path44.join(service.dir, relFile)));
8678
+ const evidenceFile = toPosix(path45.relative(scanPath, path45.join(service.dir, relFile)));
8551
8679
  const add = (edgeType, kind, name) => {
8552
8680
  if (!name) return;
8553
8681
  const result = emitPlatformResourceEdge(
@@ -8576,13 +8704,13 @@ async function addVercelServices(graph, services, scanPath) {
8576
8704
 
8577
8705
  // src/extract/infra/railway.ts
8578
8706
  import { promises as fs22 } from "fs";
8579
- import path45 from "path";
8707
+ import path46 from "path";
8580
8708
  import { parse as parseToml3 } from "smol-toml";
8581
8709
  import { EdgeType as EdgeType20 } from "@neat.is/types";
8582
8710
  var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
8583
8711
  async function readRailwayConfig(dir) {
8584
8712
  for (const filename of RAILWAY_FILENAMES) {
8585
- const abs = path45.join(dir, filename);
8713
+ const abs = path46.join(dir, filename);
8586
8714
  if (!await exists(abs)) continue;
8587
8715
  const raw = await fs22.readFile(abs, "utf8");
8588
8716
  const config = filename === "railway.toml" ? parseToml3(raw) : JSON.parse(maskCommentsInSource(raw));
@@ -8598,7 +8726,7 @@ async function addRailwayServices(graph, services, scanPath) {
8598
8726
  try {
8599
8727
  read = await readRailwayConfig(service.dir);
8600
8728
  } catch (err) {
8601
- recordExtractionError("infra railway", path45.relative(scanPath, service.dir), err);
8729
+ recordExtractionError("infra railway", path46.relative(scanPath, service.dir), err);
8602
8730
  continue;
8603
8731
  }
8604
8732
  if (!read) continue;
@@ -8608,7 +8736,7 @@ async function addRailwayServices(graph, services, scanPath) {
8608
8736
  }
8609
8737
  const anchorId = service.node.id;
8610
8738
  const { config, relFile, raw } = read;
8611
- const evidenceFile = toPosix(path45.relative(scanPath, path45.join(service.dir, relFile)));
8739
+ const evidenceFile = toPosix(path46.relative(scanPath, path46.join(service.dir, relFile)));
8612
8740
  const add = (edgeType, kind, name) => {
8613
8741
  if (!name) return;
8614
8742
  const result = emitPlatformResourceEdge(
@@ -8633,12 +8761,12 @@ async function addRailwayServices(graph, services, scanPath) {
8633
8761
 
8634
8762
  // src/extract/infra/supabase.ts
8635
8763
  import { promises as fs23 } from "fs";
8636
- import path46 from "path";
8764
+ import path47 from "path";
8637
8765
  import { parse as parseToml4 } from "smol-toml";
8638
8766
  import { EdgeType as EdgeType21 } from "@neat.is/types";
8639
8767
  async function readSupabaseConfig(dir) {
8640
- const relFile = path46.join("supabase", "config.toml");
8641
- const abs = path46.join(dir, relFile);
8768
+ const relFile = path47.join("supabase", "config.toml");
8769
+ const abs = path47.join(dir, relFile);
8642
8770
  if (!await exists(abs)) return null;
8643
8771
  const raw = await fs23.readFile(abs, "utf8");
8644
8772
  const config = parseToml4(raw);
@@ -8652,7 +8780,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
8652
8780
  try {
8653
8781
  read = await readSupabaseConfig(service.dir);
8654
8782
  } catch (err) {
8655
- recordExtractionError("infra supabase", path46.relative(scanPath, service.dir), err);
8783
+ recordExtractionError("infra supabase", path47.relative(scanPath, service.dir), err);
8656
8784
  continue;
8657
8785
  }
8658
8786
  if (!read) continue;
@@ -8667,7 +8795,7 @@ async function addSupabaseProjects(graph, services, scanPath) {
8667
8795
  });
8668
8796
  }
8669
8797
  const anchorId = service.node.id;
8670
- const evidenceFile = toPosix(path46.relative(scanPath, path46.join(service.dir, relFile)));
8798
+ const evidenceFile = toPosix(path47.relative(scanPath, path47.join(service.dir, relFile)));
8671
8799
  const add = (edgeType, kind, name) => {
8672
8800
  if (!name) return;
8673
8801
  const result = emitPlatformResourceEdge(
@@ -8708,11 +8836,11 @@ async function addInfra(graph, scanPath, services) {
8708
8836
  }
8709
8837
 
8710
8838
  // src/extract/index.ts
8711
- import path48 from "path";
8839
+ import path49 from "path";
8712
8840
 
8713
8841
  // src/extract/retire.ts
8714
8842
  import { existsSync as existsSync2 } from "fs";
8715
- import path47 from "path";
8843
+ import path48 from "path";
8716
8844
  import { NodeType as NodeType17, Provenance as Provenance20 } from "@neat.is/types";
8717
8845
  function dropOrphanedFileNodes(graph) {
8718
8846
  const orphans = [];
@@ -8746,11 +8874,11 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
8746
8874
  if (edge.provenance !== Provenance20.EXTRACTED) return;
8747
8875
  const evidenceFile = edge.evidence?.file;
8748
8876
  if (!evidenceFile) return;
8749
- if (path47.isAbsolute(evidenceFile)) {
8877
+ if (path48.isAbsolute(evidenceFile)) {
8750
8878
  if (!existsSync2(evidenceFile)) toDrop.push(id);
8751
8879
  return;
8752
8880
  }
8753
- const found = bases.some((base) => existsSync2(path47.join(base, evidenceFile)));
8881
+ const found = bases.some((base) => existsSync2(path48.join(base, evidenceFile)));
8754
8882
  if (!found) toDrop.push(id);
8755
8883
  });
8756
8884
  for (const id of toDrop) graph.dropEdge(id);
@@ -8803,7 +8931,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
8803
8931
  }
8804
8932
  const droppedEntries = drainDroppedExtracted();
8805
8933
  if (isRejectedLogEnabled() && opts.errorsPath && droppedEntries.length > 0) {
8806
- const rejectedPath = path48.join(path48.dirname(opts.errorsPath), "rejected.ndjson");
8934
+ const rejectedPath = path49.join(path49.dirname(opts.errorsPath), "rejected.ndjson");
8807
8935
  try {
8808
8936
  await writeRejectedExtracted(droppedEntries, rejectedPath);
8809
8937
  } catch (err) {
@@ -9173,7 +9301,7 @@ function computeDivergences(graph, opts = {}) {
9173
9301
 
9174
9302
  // src/persist.ts
9175
9303
  import { promises as fs24 } from "fs";
9176
- import path49 from "path";
9304
+ import path50 from "path";
9177
9305
  import { NodeType as NodeType19, Provenance as Provenance22, observedEdgeId as observedEdgeId2 } from "@neat.is/types";
9178
9306
  var SCHEMA_VERSION = 6;
9179
9307
  function migrateV1ToV2(payload) {
@@ -9225,7 +9353,7 @@ function migrateV2ToV3(payload) {
9225
9353
  return { ...payload, schemaVersion: 3 };
9226
9354
  }
9227
9355
  async function ensureDir(filePath) {
9228
- await fs24.mkdir(path49.dirname(filePath), { recursive: true });
9356
+ await fs24.mkdir(path50.dirname(filePath), { recursive: true });
9229
9357
  }
9230
9358
  async function saveGraphToDisk(graph, outPath) {
9231
9359
  await ensureDir(outPath);
@@ -9387,23 +9515,23 @@ function canonicalJson(value) {
9387
9515
  }
9388
9516
 
9389
9517
  // src/projects.ts
9390
- import path50 from "path";
9518
+ import path51 from "path";
9391
9519
  function pathsForProject(project, baseDir) {
9392
9520
  if (project === DEFAULT_PROJECT) {
9393
9521
  return {
9394
- snapshotPath: path50.join(baseDir, "graph.json"),
9395
- errorsPath: path50.join(baseDir, "errors.ndjson"),
9396
- staleEventsPath: path50.join(baseDir, "stale-events.ndjson"),
9397
- embeddingsCachePath: path50.join(baseDir, "embeddings.json"),
9398
- policyViolationsPath: path50.join(baseDir, "policy-violations.ndjson")
9522
+ snapshotPath: path51.join(baseDir, "graph.json"),
9523
+ errorsPath: path51.join(baseDir, "errors.ndjson"),
9524
+ staleEventsPath: path51.join(baseDir, "stale-events.ndjson"),
9525
+ embeddingsCachePath: path51.join(baseDir, "embeddings.json"),
9526
+ policyViolationsPath: path51.join(baseDir, "policy-violations.ndjson")
9399
9527
  };
9400
9528
  }
9401
9529
  return {
9402
- snapshotPath: path50.join(baseDir, `${project}.json`),
9403
- errorsPath: path50.join(baseDir, `errors.${project}.ndjson`),
9404
- staleEventsPath: path50.join(baseDir, `stale-events.${project}.ndjson`),
9405
- embeddingsCachePath: path50.join(baseDir, `embeddings.${project}.json`),
9406
- policyViolationsPath: path50.join(baseDir, `policy-violations.${project}.ndjson`)
9530
+ snapshotPath: path51.join(baseDir, `${project}.json`),
9531
+ errorsPath: path51.join(baseDir, `errors.${project}.ndjson`),
9532
+ staleEventsPath: path51.join(baseDir, `stale-events.${project}.ndjson`),
9533
+ embeddingsCachePath: path51.join(baseDir, `embeddings.${project}.json`),
9534
+ policyViolationsPath: path51.join(baseDir, `policy-violations.${project}.ndjson`)
9407
9535
  };
9408
9536
  }
9409
9537
  var Projects = class {
@@ -9444,7 +9572,7 @@ function parseExtraProjects(raw) {
9444
9572
  // src/registry.ts
9445
9573
  import { promises as fs26 } from "fs";
9446
9574
  import os2 from "os";
9447
- import path51 from "path";
9575
+ import path52 from "path";
9448
9576
  import {
9449
9577
  RegistryFileSchema
9450
9578
  } from "@neat.is/types";
@@ -9452,20 +9580,20 @@ var LOCK_TIMEOUT_MS = 5e3;
9452
9580
  var LOCK_RETRY_MS = 50;
9453
9581
  function neatHome() {
9454
9582
  const override = process.env.NEAT_HOME;
9455
- if (override && override.length > 0) return path51.resolve(override);
9456
- return path51.join(os2.homedir(), ".neat");
9583
+ if (override && override.length > 0) return path52.resolve(override);
9584
+ return path52.join(os2.homedir(), ".neat");
9457
9585
  }
9458
9586
  function registryPath() {
9459
- return path51.join(neatHome(), "projects.json");
9587
+ return path52.join(neatHome(), "projects.json");
9460
9588
  }
9461
9589
  function registryLockPath() {
9462
- return path51.join(neatHome(), "projects.json.lock");
9590
+ return path52.join(neatHome(), "projects.json.lock");
9463
9591
  }
9464
9592
  function daemonPidPath() {
9465
- return path51.join(neatHome(), "neatd.pid");
9593
+ return path52.join(neatHome(), "neatd.pid");
9466
9594
  }
9467
9595
  function daemonsDir() {
9468
- return path51.join(neatHome(), "daemons");
9596
+ return path52.join(neatHome(), "daemons");
9469
9597
  }
9470
9598
  function isFiniteInt(v) {
9471
9599
  return typeof v === "number" && Number.isFinite(v);
@@ -9506,7 +9634,7 @@ async function discoverDaemons(probe = defaultDiscoveryProbe) {
9506
9634
  const out = [];
9507
9635
  for (const name of names) {
9508
9636
  if (!name.endsWith(".json")) continue;
9509
- const file = path51.join(dir, name);
9637
+ const file = path52.join(dir, name);
9510
9638
  let raw;
9511
9639
  try {
9512
9640
  raw = await fs26.readFile(file, "utf8");
@@ -9627,7 +9755,7 @@ function lockHolderMessage(holder, lockPath, timeoutMs) {
9627
9755
  }
9628
9756
  }
9629
9757
  async function normalizeProjectPath(input) {
9630
- const resolved = path51.resolve(input);
9758
+ const resolved = path52.resolve(input);
9631
9759
  try {
9632
9760
  return await fs26.realpath(resolved);
9633
9761
  } catch {
@@ -9635,7 +9763,7 @@ async function normalizeProjectPath(input) {
9635
9763
  }
9636
9764
  }
9637
9765
  async function writeAtomically(target, contents) {
9638
- await fs26.mkdir(path51.dirname(target), { recursive: true });
9766
+ await fs26.mkdir(path52.dirname(target), { recursive: true });
9639
9767
  const tmp = `${target}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
9640
9768
  const fd = await fs26.open(tmp, "w");
9641
9769
  try {
@@ -9648,7 +9776,7 @@ async function writeAtomically(target, contents) {
9648
9776
  }
9649
9777
  async function acquireLock(lockPath, timeoutMs = LOCK_TIMEOUT_MS, probe = defaultLockHolderProbe) {
9650
9778
  const deadline = Date.now() + timeoutMs;
9651
- await fs26.mkdir(path51.dirname(lockPath), { recursive: true });
9779
+ await fs26.mkdir(path52.dirname(lockPath), { recursive: true });
9652
9780
  let probedHolder = false;
9653
9781
  while (true) {
9654
9782
  try {
@@ -9844,13 +9972,13 @@ import { DivergenceTypeSchema, PoliciesCheckBodySchema, PolicySeveritySchema } f
9844
9972
 
9845
9973
  // src/extend/index.ts
9846
9974
  import { promises as fs28 } from "fs";
9847
- import path53 from "path";
9975
+ import path54 from "path";
9848
9976
  import os3 from "os";
9849
9977
  import { resolve as registryResolve, list as registryList } from "@neat.is/instrumentation-registry";
9850
9978
 
9851
9979
  // src/installers/package-manager.ts
9852
9980
  import { promises as fs27 } from "fs";
9853
- import path52 from "path";
9981
+ import path53 from "path";
9854
9982
  import { spawn } from "child_process";
9855
9983
  var LOCKFILE_PRIORITY = [
9856
9984
  { lockfile: "bun.lockb", pm: "bun", args: ["install", "--no-summary"] },
@@ -9872,22 +10000,22 @@ async function exists2(p) {
9872
10000
  }
9873
10001
  }
9874
10002
  async function detectPackageManager(serviceDir) {
9875
- let dir = path52.resolve(serviceDir);
10003
+ let dir = path53.resolve(serviceDir);
9876
10004
  const stops = /* @__PURE__ */ new Set();
9877
10005
  for (let i = 0; i < 64; i++) {
9878
10006
  if (stops.has(dir)) break;
9879
10007
  stops.add(dir);
9880
10008
  for (const candidate of LOCKFILE_PRIORITY) {
9881
- const lockPath = path52.join(dir, candidate.lockfile);
10009
+ const lockPath = path53.join(dir, candidate.lockfile);
9882
10010
  if (await exists2(lockPath)) {
9883
10011
  return { pm: candidate.pm, cwd: dir, args: [...candidate.args] };
9884
10012
  }
9885
10013
  }
9886
- const parent = path52.dirname(dir);
10014
+ const parent = path53.dirname(dir);
9887
10015
  if (parent === dir) break;
9888
10016
  dir = parent;
9889
10017
  }
9890
- return { pm: "npm", cwd: path52.resolve(serviceDir), args: [...NPM_FALLBACK_ARGS] };
10018
+ return { pm: "npm", cwd: path53.resolve(serviceDir), args: [...NPM_FALLBACK_ARGS] };
9891
10019
  }
9892
10020
  async function runPackageManagerInstall(cmd) {
9893
10021
  return new Promise((resolve) => {
@@ -9936,7 +10064,7 @@ async function fileExists2(p) {
9936
10064
  }
9937
10065
  }
9938
10066
  async function readPackageJson(scanPath) {
9939
- const pkgPath = path53.join(scanPath, "package.json");
10067
+ const pkgPath = path54.join(scanPath, "package.json");
9940
10068
  const raw = await fs28.readFile(pkgPath, "utf8");
9941
10069
  return JSON.parse(raw);
9942
10070
  }
@@ -9955,11 +10083,11 @@ async function findHookFiles(scanPath) {
9955
10083
  for (const entry of entries) {
9956
10084
  if (entry.isDirectory()) {
9957
10085
  if (entry.name.startsWith(".") || HOOK_WALK_SKIP_DIRS.has(entry.name)) continue;
9958
- await walk6(path53.join(dir, entry.name));
10086
+ await walk6(path54.join(dir, entry.name));
9959
10087
  } else if (entry.isFile()) {
9960
10088
  if ((entry.name.startsWith("instrumentation") || entry.name.startsWith("otel-init")) && /\.(ts|js|cjs|mjs)$/.test(entry.name)) {
9961
- const rel = path53.relative(scanPath, path53.join(dir, entry.name));
9962
- found.push(rel.split(path53.sep).join("/"));
10089
+ const rel = path54.relative(scanPath, path54.join(dir, entry.name));
10090
+ found.push(rel.split(path54.sep).join("/"));
9963
10091
  }
9964
10092
  }
9965
10093
  }
@@ -9970,7 +10098,7 @@ async function findHookFiles(scanPath) {
9970
10098
  async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
9971
10099
  let fallback = null;
9972
10100
  for (const file of hookFiles) {
9973
- const content = await fs28.readFile(path53.join(scanPath, file), "utf8");
10101
+ const content = await fs28.readFile(path54.join(scanPath, file), "utf8");
9974
10102
  const patched = splicedContent(content, snippet2);
9975
10103
  if (patched !== null) return { file, content, patched };
9976
10104
  if (fallback === null) fallback = { file, content };
@@ -9978,11 +10106,11 @@ async function pickPrimaryHookFile(scanPath, hookFiles, snippet2) {
9978
10106
  return { file: fallback.file, content: fallback.content, patched: null };
9979
10107
  }
9980
10108
  function extendLogPath() {
9981
- return process.env.NEAT_EXTEND_LOG ?? path53.join(os3.homedir(), ".neat", "extend-log.ndjson");
10109
+ return process.env.NEAT_EXTEND_LOG ?? path54.join(os3.homedir(), ".neat", "extend-log.ndjson");
9982
10110
  }
9983
10111
  async function appendExtendLog(entry) {
9984
10112
  const logPath = extendLogPath();
9985
- await fs28.mkdir(path53.dirname(logPath), { recursive: true });
10113
+ await fs28.mkdir(path54.dirname(logPath), { recursive: true });
9986
10114
  await fs28.appendFile(logPath, JSON.stringify(entry) + "\n", "utf8");
9987
10115
  }
9988
10116
  function splicedContent(fileContent, snippet2) {
@@ -10041,7 +10169,7 @@ function lookupInstrumentation(library, installedVersion) {
10041
10169
  }
10042
10170
  async function describeProjectInstrumentation(ctx) {
10043
10171
  const hookFiles = await findHookFiles(ctx.scanPath);
10044
- const envNeat = await fileExists2(path53.join(ctx.scanPath, ".env.neat"));
10172
+ const envNeat = await fileExists2(path54.join(ctx.scanPath, ".env.neat"));
10045
10173
  const registryInstrPackages = new Set(
10046
10174
  registryList().map((e) => e.instrumentation_package).filter((p) => !!p)
10047
10175
  );
@@ -10063,7 +10191,7 @@ async function applyExtension(ctx, args, options) {
10063
10191
  );
10064
10192
  }
10065
10193
  for (const file of hookFiles) {
10066
- const content = await fs28.readFile(path53.join(ctx.scanPath, file), "utf8");
10194
+ const content = await fs28.readFile(path54.join(ctx.scanPath, file), "utf8");
10067
10195
  if (content.includes(args.registration_snippet)) {
10068
10196
  return { library: args.library, filesTouched: [], depsAdded: [], installOutput: "", alreadyApplied: true };
10069
10197
  }
@@ -10075,10 +10203,10 @@ async function applyExtension(ctx, args, options) {
10075
10203
  );
10076
10204
  }
10077
10205
  const primaryFile = primary.file;
10078
- const primaryPath = path53.join(ctx.scanPath, primaryFile);
10206
+ const primaryPath = path54.join(ctx.scanPath, primaryFile);
10079
10207
  const filesTouched = [];
10080
10208
  const depsAdded = [];
10081
- const pkgPath = path53.join(ctx.scanPath, "package.json");
10209
+ const pkgPath = path54.join(ctx.scanPath, "package.json");
10082
10210
  const pkg = await readPackageJson(ctx.scanPath);
10083
10211
  if (!(pkg.dependencies ?? {})[args.instrumentation_package]) {
10084
10212
  pkg.dependencies = { ...pkg.dependencies ?? {}, [args.instrumentation_package]: args.version };
@@ -10117,7 +10245,7 @@ async function dryRunExtension(ctx, args) {
10117
10245
  };
10118
10246
  }
10119
10247
  for (const file of hookFiles) {
10120
- const content = await fs28.readFile(path53.join(ctx.scanPath, file), "utf8");
10248
+ const content = await fs28.readFile(path54.join(ctx.scanPath, file), "utf8");
10121
10249
  if (content.includes(args.registration_snippet)) {
10122
10250
  return {
10123
10251
  library: args.library,
@@ -10158,7 +10286,7 @@ async function rollbackExtension(ctx, args) {
10158
10286
  if (!match) {
10159
10287
  return { undone: false, message: "no apply found for library" };
10160
10288
  }
10161
- const pkgPath = path53.join(ctx.scanPath, "package.json");
10289
+ const pkgPath = path54.join(ctx.scanPath, "package.json");
10162
10290
  if (await fileExists2(pkgPath)) {
10163
10291
  const pkg = await readPackageJson(ctx.scanPath);
10164
10292
  if (pkg.dependencies?.[match.instrumentation_package]) {
@@ -10169,7 +10297,7 @@ async function rollbackExtension(ctx, args) {
10169
10297
  }
10170
10298
  const hookFiles = await findHookFiles(ctx.scanPath);
10171
10299
  for (const file of hookFiles) {
10172
- const filePath = path53.join(ctx.scanPath, file);
10300
+ const filePath = path54.join(ctx.scanPath, file);
10173
10301
  const content = await fs28.readFile(filePath, "utf8");
10174
10302
  if (content.includes(match.registration_snippet)) {
10175
10303
  const filtered = content.split("\n").filter((line) => !line.includes(match.registration_snippet)).join("\n");
@@ -10284,7 +10412,7 @@ data: ${JSON.stringify(envelope.payload)}
10284
10412
 
10285
10413
  // src/connectors-config.ts
10286
10414
  import os4 from "os";
10287
- import path54 from "path";
10415
+ import path55 from "path";
10288
10416
  import { promises as fs29 } from "fs";
10289
10417
  var CONNECTORS_CONFIG_VERSION = 1;
10290
10418
  var EnvRefUnsetError = class extends Error {
@@ -10299,11 +10427,11 @@ var EnvRefUnsetError = class extends Error {
10299
10427
  };
10300
10428
  function neatHome2() {
10301
10429
  const override = process.env.NEAT_HOME;
10302
- if (override && override.length > 0) return path54.resolve(override);
10303
- return path54.join(os4.homedir(), ".neat");
10430
+ if (override && override.length > 0) return path55.resolve(override);
10431
+ return path55.join(os4.homedir(), ".neat");
10304
10432
  }
10305
10433
  function connectorsConfigPath(home = neatHome2()) {
10306
- return path54.join(home, "connectors.json");
10434
+ return path55.join(home, "connectors.json");
10307
10435
  }
10308
10436
  var MODE_MASK_LOOSER_THAN_0600 = 63;
10309
10437
  async function warnIfModeLooserThan0600(file) {
@@ -10434,7 +10562,7 @@ function connectorMatchesProject(entry, project) {
10434
10562
  var CONNECTORS_LOCK_TIMEOUT_MS = 5e3;
10435
10563
  var CONNECTORS_LOCK_RETRY_MS = 50;
10436
10564
  function connectorsConfigLockPath(home = neatHome2()) {
10437
- return path54.join(home, "connectors.json.lock");
10565
+ return path55.join(home, "connectors.json.lock");
10438
10566
  }
10439
10567
  function isEnvRef(value) {
10440
10568
  return value.length > 1 && value.startsWith("$");
@@ -10447,7 +10575,7 @@ function redactCredentialRef(ref) {
10447
10575
  return out;
10448
10576
  }
10449
10577
  async function writeConfigAtomically0600(file, contents) {
10450
- await fs29.mkdir(path54.dirname(file), { recursive: true });
10578
+ await fs29.mkdir(path55.dirname(file), { recursive: true });
10451
10579
  const tmp = `${file}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}.tmp`;
10452
10580
  const fd = await fs29.open(tmp, "w", 384);
10453
10581
  try {
@@ -10461,7 +10589,7 @@ async function writeConfigAtomically0600(file, contents) {
10461
10589
  }
10462
10590
  async function acquireConnectorsLock(lockPath, timeoutMs = CONNECTORS_LOCK_TIMEOUT_MS) {
10463
10591
  const deadline = Date.now() + timeoutMs;
10464
- await fs29.mkdir(path54.dirname(lockPath), { recursive: true });
10592
+ await fs29.mkdir(path55.dirname(lockPath), { recursive: true });
10465
10593
  for (; ; ) {
10466
10594
  try {
10467
10595
  const fd = await fs29.open(lockPath, "wx");
@@ -11092,10 +11220,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
11092
11220
  // src/connectors/supabase/map.ts
11093
11221
  var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
11094
11222
  var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
11095
- function targetFromRestPath(path55) {
11096
- const rpcMatch = REST_RPC_PATH_RE.exec(path55);
11223
+ function targetFromRestPath(path56) {
11224
+ const rpcMatch = REST_RPC_PATH_RE.exec(path56);
11097
11225
  if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
11098
- const tableMatch = REST_TABLE_PATH_RE.exec(path55);
11226
+ const tableMatch = REST_TABLE_PATH_RE.exec(path56);
11099
11227
  if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
11100
11228
  return null;
11101
11229
  }
@@ -11204,21 +11332,21 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
11204
11332
  }
11205
11333
 
11206
11334
  // src/connectors/supabase/resolve.ts
11207
- import { EdgeType as EdgeType23, infraId as infraId13 } from "@neat.is/types";
11335
+ import { EdgeType as EdgeType23, infraId as infraId14 } from "@neat.is/types";
11208
11336
  function createSupabaseResolveTarget(graph, config) {
11209
11337
  return (signal, _ctx) => {
11210
11338
  if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
11211
11339
  return null;
11212
11340
  }
11213
- const subResourceId = infraId13(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
11341
+ const subResourceId = infraId14(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
11214
11342
  if (graph.hasNode(subResourceId)) {
11215
11343
  return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: EdgeType23.CALLS };
11216
11344
  }
11217
- const bareResourceId = infraId13(signal.targetKind, signal.targetName);
11345
+ const bareResourceId = infraId14(signal.targetKind, signal.targetName);
11218
11346
  if (graph.hasNode(bareResourceId)) {
11219
11347
  return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: EdgeType23.CALLS };
11220
11348
  }
11221
- const projectLevelId = infraId13("supabase", config.nodeRef);
11349
+ const projectLevelId = infraId14("supabase", config.nodeRef);
11222
11350
  if (graph.hasNode(projectLevelId)) {
11223
11351
  return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: EdgeType23.CALLS };
11224
11352
  }
@@ -11690,9 +11818,9 @@ function parseFirebaseTargetName(targetName) {
11690
11818
  const secondSep = rest.indexOf(FIELD_SEP);
11691
11819
  if (secondSep === -1) return null;
11692
11820
  const method = rest.slice(0, secondSep);
11693
- const path55 = rest.slice(secondSep + 1);
11694
- if (!resourceName || !method || !path55) return null;
11695
- return { resourceName, method, path: path55 };
11821
+ const path56 = rest.slice(secondSep + 1);
11822
+ if (!resourceName || !method || !path56) return null;
11823
+ return { resourceName, method, path: path56 };
11696
11824
  }
11697
11825
  function resourceNameFor(type, labels) {
11698
11826
  if (!labels) return null;
@@ -11730,14 +11858,14 @@ function mapLogEntryToSignal(entry) {
11730
11858
  if (!req) return null;
11731
11859
  if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
11732
11860
  const method = req.requestMethod.toUpperCase();
11733
- const path55 = pathFromRequestUrl(req.requestUrl);
11734
- if (path55 === null) return null;
11861
+ const path56 = pathFromRequestUrl(req.requestUrl);
11862
+ if (path56 === null) return null;
11735
11863
  const timestamp = entry.timestamp;
11736
11864
  if (typeof timestamp !== "string" || timestamp.length === 0) return null;
11737
11865
  const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
11738
11866
  return {
11739
11867
  targetKind: resourceType,
11740
- targetName: packFirebaseTargetName({ resourceName, method, path: path55 }),
11868
+ targetName: packFirebaseTargetName({ resourceName, method, path: path56 }),
11741
11869
  callCount: 1,
11742
11870
  errorCount: isError ? 1 : 0,
11743
11871
  lastObservedIso: timestamp
@@ -11823,7 +11951,7 @@ function createFirebaseConnector(graph, serviceMap) {
11823
11951
  }
11824
11952
 
11825
11953
  // src/connectors/cloudflare/connector.ts
11826
- import { EdgeType as EdgeType26, NodeType as NodeType23, fileId as fileId4, infraId as infraId14 } from "@neat.is/types";
11954
+ import { EdgeType as EdgeType26, NodeType as NodeType23, fileId as fileId4, infraId as infraId15 } from "@neat.is/types";
11827
11955
 
11828
11956
  // src/connectors/cloudflare/client.ts
11829
11957
  import { randomUUID } from "crypto";
@@ -11934,7 +12062,7 @@ function mapEventToSignal(event) {
11934
12062
  if (Number.isNaN(observedAt.getTime())) return null;
11935
12063
  const statusCode = metadata?.statusCode;
11936
12064
  const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
11937
- const path55 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
12065
+ const path56 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
11938
12066
  return {
11939
12067
  targetKind: CLOUDFLARE_TARGET_KIND,
11940
12068
  targetName: scriptName,
@@ -11942,7 +12070,7 @@ function mapEventToSignal(event) {
11942
12070
  errorCount: isError ? 1 : 0,
11943
12071
  lastObservedIso: observedAt.toISOString(),
11944
12072
  method,
11945
- ...path55 ? { path: path55 } : {},
12073
+ ...path56 ? { path: path56 } : {},
11946
12074
  ...typeof statusCode === "number" ? { statusCode } : {},
11947
12075
  ...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
11948
12076
  };
@@ -11988,8 +12116,8 @@ function findTaggedWorkerFileNode(graph, workerName) {
11988
12116
  });
11989
12117
  return found;
11990
12118
  }
11991
- function findMatchingRouteNode(graph, serviceName, method, path55) {
11992
- const normalizedPath = normalizePathTemplate(path55);
12119
+ function findMatchingRouteNode(graph, serviceName, method, path56) {
12120
+ const normalizedPath = normalizePathTemplate(path56);
11993
12121
  let found = null;
11994
12122
  graph.forEachNode((id, attrs) => {
11995
12123
  if (found) return;
@@ -12006,10 +12134,10 @@ function createCloudflareResolveTarget(config, graph) {
12006
12134
  return (signal) => {
12007
12135
  if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
12008
12136
  const scriptName = signal.targetName;
12009
- const { method, path: path55 } = signal;
12137
+ const { method, path: path56 } = signal;
12010
12138
  const resolveRouteGrain = (serviceName, wholeFileId) => {
12011
- if (!method || !path55) return wholeFileId;
12012
- return findMatchingRouteNode(graph, serviceName, method, path55) ?? wholeFileId;
12139
+ if (!method || !path56) return wholeFileId;
12140
+ return findMatchingRouteNode(graph, serviceName, method, path56) ?? wholeFileId;
12013
12141
  };
12014
12142
  const mapping = config.workers?.[scriptName];
12015
12143
  if (mapping) {
@@ -12030,7 +12158,7 @@ function createCloudflareResolveTarget(config, graph) {
12030
12158
  };
12031
12159
  }
12032
12160
  return {
12033
- targetNodeId: infraId14("cloudflare-worker", scriptName),
12161
+ targetNodeId: infraId15("cloudflare-worker", scriptName),
12034
12162
  serviceName: scriptName,
12035
12163
  edgeType: EdgeType26.CALLS,
12036
12164
  ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
@@ -12214,12 +12342,12 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
12214
12342
  }
12215
12343
 
12216
12344
  // src/connectors/neon/resolve.ts
12217
- import { EdgeType as EdgeType27, infraId as infraId15 } from "@neat.is/types";
12345
+ import { EdgeType as EdgeType27, infraId as infraId16 } from "@neat.is/types";
12218
12346
  function createNeonResolveTarget(config) {
12219
12347
  return (signal) => {
12220
12348
  if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
12221
12349
  return {
12222
- targetNodeId: infraId15("sql-table", signal.targetName),
12350
+ targetNodeId: infraId16("sql-table", signal.targetName),
12223
12351
  serviceName: config.serviceName,
12224
12352
  edgeType: EdgeType27.CALLS,
12225
12353
  ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
@@ -13614,4 +13742,4 @@ export {
13614
13742
  deprovisionConnector,
13615
13743
  buildApi
13616
13744
  };
13617
- //# sourceMappingURL=chunk-RR4LWQQB.js.map
13745
+ //# sourceMappingURL=chunk-BY6ZP5WA.js.map