@neat.is/core 0.9.18-dev.20260918 → 0.9.19

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/index.cjs CHANGED
@@ -60,8 +60,8 @@ function mountBearerAuth(app, opts) {
60
60
  ]);
61
61
  const publicRead = opts.publicRead === true;
62
62
  app.addHook("preHandler", (req, reply, done) => {
63
- const path78 = (req.url.split("?")[0] ?? "").replace(/\/+$/, "");
64
- if (exactUnauthPaths.has(path78) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path78)) {
63
+ const path79 = (req.url.split("?")[0] ?? "").replace(/\/+$/, "");
64
+ if (exactUnauthPaths.has(path79) || PROJECT_SCOPED_UNAUTH_PATTERN.test(path79)) {
65
65
  done();
66
66
  return;
67
67
  }
@@ -414,8 +414,8 @@ function websocketChannelPathOf(attrs) {
414
414
  const v = attrs[key];
415
415
  if (typeof v === "string" && v.length > 0) {
416
416
  const q = v.indexOf("?");
417
- const path78 = q === -1 ? v : v.slice(0, q);
418
- if (path78.length > 0) return path78;
417
+ const path79 = q === -1 ? v : v.slice(0, q);
418
+ if (path79.length > 0) return path79;
419
419
  }
420
420
  }
421
421
  return void 0;
@@ -1374,19 +1374,19 @@ function confidenceFromMix(edges, now = Date.now()) {
1374
1374
  function longestIncomingWalk(graph, start, maxDepth) {
1375
1375
  let best = { path: [start], edges: [] };
1376
1376
  const visited = /* @__PURE__ */ new Set([start]);
1377
- function step(node, path78, edges) {
1378
- if (path78.length > best.path.length) {
1379
- best = { path: [...path78], edges: [...edges] };
1377
+ function step(node, path79, edges) {
1378
+ if (path79.length > best.path.length) {
1379
+ best = { path: [...path79], edges: [...edges] };
1380
1380
  }
1381
- if (path78.length - 1 >= maxDepth) return;
1381
+ if (path79.length - 1 >= maxDepth) return;
1382
1382
  const incoming = bestEdgeBySource(graph, graph.inboundEdges(node));
1383
1383
  for (const [srcId, edge] of incoming) {
1384
1384
  if (visited.has(srcId)) continue;
1385
1385
  visited.add(srcId);
1386
- path78.push(srcId);
1386
+ path79.push(srcId);
1387
1387
  edges.push(edge);
1388
- step(srcId, path78, edges);
1389
- path78.pop();
1388
+ step(srcId, path79, edges);
1389
+ path79.pop();
1390
1390
  edges.pop();
1391
1391
  visited.delete(srcId);
1392
1392
  }
@@ -1601,20 +1601,20 @@ function dominantFailingCall(graph, serviceId17, visited) {
1601
1601
  return best;
1602
1602
  }
1603
1603
  function followFailingCallChain(graph, originServiceId, maxDepth) {
1604
- const path78 = [originServiceId];
1604
+ const path79 = [originServiceId];
1605
1605
  const edges = [];
1606
1606
  const visited = /* @__PURE__ */ new Set([originServiceId]);
1607
1607
  let current = originServiceId;
1608
1608
  for (let depth = 0; depth < maxDepth; depth++) {
1609
1609
  const hop = dominantFailingCall(graph, current, visited);
1610
1610
  if (!hop) break;
1611
- path78.push(hop.nextService);
1611
+ path79.push(hop.nextService);
1612
1612
  edges.push(hop.edge);
1613
1613
  visited.add(hop.nextService);
1614
1614
  current = hop.nextService;
1615
1615
  }
1616
1616
  if (edges.length === 0) return null;
1617
- return { path: path78, edges, culprit: current };
1617
+ return { path: path79, edges, culprit: current };
1618
1618
  }
1619
1619
  function isStaleCallEdge(e) {
1620
1620
  return e.type === import_types.EdgeType.CALLS && e.provenance === import_types.Provenance.STALE;
@@ -1650,26 +1650,26 @@ function dominantStaleCall(graph, serviceId17, visited) {
1650
1650
  return best;
1651
1651
  }
1652
1652
  function followStaleCallChain(graph, originServiceId, maxDepth) {
1653
- const path78 = [originServiceId];
1653
+ const path79 = [originServiceId];
1654
1654
  const edges = [];
1655
1655
  const visited = /* @__PURE__ */ new Set([originServiceId]);
1656
1656
  let current = originServiceId;
1657
1657
  for (let depth = 0; depth < maxDepth; depth++) {
1658
1658
  const hop = dominantStaleCall(graph, current, visited);
1659
1659
  if (!hop) break;
1660
- path78.push(hop.nextService);
1660
+ path79.push(hop.nextService);
1661
1661
  edges.push(hop.edge);
1662
1662
  visited.add(hop.nextService);
1663
1663
  current = hop.nextService;
1664
1664
  }
1665
1665
  if (edges.length === 0) return null;
1666
- return { path: path78, edges, culprit: current };
1666
+ return { path: path79, edges, culprit: current };
1667
1667
  }
1668
1668
  function crossServiceRootCause(graph, originId, incidents, errorEvent) {
1669
1669
  const chain = followFailingCallChain(graph, originId, ROOT_CAUSE_MAX_DEPTH);
1670
1670
  if (!chain) return null;
1671
1671
  const culprit = chain.culprit;
1672
- const path78 = [...chain.path];
1672
+ const path79 = [...chain.path];
1673
1673
  const edgeProvenances = chain.edges.map((e) => e.provenance);
1674
1674
  const baseConfidence = confidenceFromMix(chain.edges);
1675
1675
  const confidence = Math.max(0, Math.min(1, baseConfidence * INCIDENT_ROOT_CAUSE_CONFIDENCE));
@@ -1677,14 +1677,14 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
1677
1677
  if (loc) {
1678
1678
  let rootCauseNode = culprit;
1679
1679
  if (loc.fileNode) {
1680
- path78.push(loc.fileNode);
1680
+ path79.push(loc.fileNode);
1681
1681
  edgeProvenances.push(import_types.Provenance.OBSERVED);
1682
1682
  rootCauseNode = loc.fileNode;
1683
1683
  }
1684
1684
  return import_types.RootCauseResultSchema.parse({
1685
1685
  rootCauseNode,
1686
1686
  rootCauseReason: loc.rootCauseReason,
1687
- traversalPath: path78,
1687
+ traversalPath: path79,
1688
1688
  edgeProvenances,
1689
1689
  confidence,
1690
1690
  ...loc.fixRecommendation ? { fixRecommendation: loc.fixRecommendation } : {}
@@ -1696,7 +1696,7 @@ function crossServiceRootCause(graph, originId, incidents, errorEvent) {
1696
1696
  return import_types.RootCauseResultSchema.parse({
1697
1697
  rootCauseNode: culprit,
1698
1698
  rootCauseReason: `${culpritName} is failing downstream calls (${errs} observed error${errs === 1 ? "" : "s"})`,
1699
- traversalPath: path78,
1699
+ traversalPath: path79,
1700
1700
  edgeProvenances,
1701
1701
  confidence,
1702
1702
  fixRecommendation: `Inspect ${culpritName}'s failing handler`
@@ -2349,10 +2349,10 @@ function enrichWithNavigation(graph, errorNodeId, tagged, incidents, now) {
2349
2349
  traversalPath = staleChain.path;
2350
2350
  edgeProvenances = staleChain.edges.map((e) => e.provenance);
2351
2351
  } else if (top.node !== seedNode) {
2352
- const path78 = findPath(graph, errorNodeId, top.node, "up", ROOT_CAUSE_MAX_DEPTH);
2353
- if (path78) {
2354
- traversalPath = path78.nodes;
2355
- edgeProvenances = path78.edges.map((e) => e.provenance);
2352
+ const path79 = findPath(graph, errorNodeId, top.node, "up", ROOT_CAUSE_MAX_DEPTH);
2353
+ if (path79) {
2354
+ traversalPath = path79.nodes;
2355
+ edgeProvenances = path79.edges.map((e) => e.provenance);
2356
2356
  } else {
2357
2357
  traversalPath = [errorNodeId, top.node];
2358
2358
  edgeProvenances = [top.provenance ?? import_types.Provenance.OBSERVED];
@@ -3791,8 +3791,8 @@ function chiRoutesFromSource(source, parser) {
3791
3791
  chiWalk(tree.rootNode, "", out);
3792
3792
  return out;
3793
3793
  }
3794
- function stripChiRegex(path78) {
3795
- return path78.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
3794
+ function stripChiRegex(path79) {
3795
+ return path79.replace(/\{([^{}:]+):[^{}]*\}/g, "{$1}");
3796
3796
  }
3797
3797
  function chiWalk(node, prefix, out) {
3798
3798
  for (let i = 0; i < node.namedChildCount; i++) {
@@ -4464,9 +4464,9 @@ function rubyRocketRoute(args) {
4464
4464
  if (!pair || pair.type !== "pair") continue;
4465
4465
  const k = pair.childForFieldName("key");
4466
4466
  if (k?.type !== "string") continue;
4467
- const path78 = rubyLiteral(k);
4468
- if (path78 === null) continue;
4469
- return { path: path78, target: rubyLiteral(pair.childForFieldName("value")) };
4467
+ const path79 = rubyLiteral(k);
4468
+ if (path79 === null) continue;
4469
+ return { path: path79, target: rubyLiteral(pair.childForFieldName("value")) };
4470
4470
  }
4471
4471
  return null;
4472
4472
  }
@@ -10688,10 +10688,10 @@ function grpcMethodsFromProto(content, fqPackage) {
10688
10688
  }
10689
10689
  const body = content.slice(bodyStart, i - 1);
10690
10690
  const rpcRe = /\brpc\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(/g;
10691
- let rm;
10692
- while ((rm = rpcRe.exec(body)) !== null) {
10693
- const rpcMethod = rm[1];
10694
- const line = lineAt(content, bodyStart + rm.index);
10691
+ let rm2;
10692
+ while ((rm2 = rpcRe.exec(body)) !== null) {
10693
+ const rpcMethod = rm2[1];
10694
+ const line = lineAt(content, bodyStart + rm2.index);
10695
10695
  out.push({ rpcService, rpcMethod, line });
10696
10696
  }
10697
10697
  serviceRe.lastIndex = i;
@@ -19573,10 +19573,10 @@ var SUPABASE_RPC_TARGET_KIND = "supabase-rpc";
19573
19573
  // src/connectors/supabase/map.ts
19574
19574
  var REST_RPC_PATH_RE = /^\/rest\/v1\/rpc\/([^/?]+)/;
19575
19575
  var REST_TABLE_PATH_RE = /^\/rest\/v1\/([^/?]+)/;
19576
- function targetFromRestPath(path78) {
19577
- const rpcMatch = REST_RPC_PATH_RE.exec(path78);
19576
+ function targetFromRestPath(path79) {
19577
+ const rpcMatch = REST_RPC_PATH_RE.exec(path79);
19578
19578
  if (rpcMatch) return { targetKind: SUPABASE_RPC_TARGET_KIND, name: rpcMatch[1] };
19579
- const tableMatch = REST_TABLE_PATH_RE.exec(path78);
19579
+ const tableMatch = REST_TABLE_PATH_RE.exec(path79);
19580
19580
  if (tableMatch) return { targetKind: SUPABASE_TABLE_TARGET_KIND, name: tableMatch[1] };
19581
19581
  return null;
19582
19582
  }
@@ -20180,9 +20180,9 @@ function parseFirebaseTargetName(targetName) {
20180
20180
  const secondSep = rest.indexOf(FIELD_SEP);
20181
20181
  if (secondSep === -1) return null;
20182
20182
  const method = rest.slice(0, secondSep);
20183
- const path78 = rest.slice(secondSep + 1);
20184
- if (!resourceName || !method || !path78) return null;
20185
- return { resourceName, method, path: path78 };
20183
+ const path79 = rest.slice(secondSep + 1);
20184
+ if (!resourceName || !method || !path79) return null;
20185
+ return { resourceName, method, path: path79 };
20186
20186
  }
20187
20187
  function resourceNameFor(type, labels) {
20188
20188
  if (!labels) return null;
@@ -20220,14 +20220,14 @@ function mapLogEntryToSignal(entry) {
20220
20220
  if (!req) return null;
20221
20221
  if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
20222
20222
  const method = req.requestMethod.toUpperCase();
20223
- const path78 = pathFromRequestUrl(req.requestUrl);
20224
- if (path78 === null) return null;
20223
+ const path79 = pathFromRequestUrl(req.requestUrl);
20224
+ if (path79 === null) return null;
20225
20225
  const timestamp = entry.timestamp;
20226
20226
  if (typeof timestamp !== "string" || timestamp.length === 0) return null;
20227
20227
  const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD2;
20228
20228
  return {
20229
20229
  targetKind: resourceType,
20230
- targetName: packFirebaseTargetName({ resourceName, method, path: path78 }),
20230
+ targetName: packFirebaseTargetName({ resourceName, method, path: path79 }),
20231
20231
  callCount: 1,
20232
20232
  errorCount: isError ? 1 : 0,
20233
20233
  lastObservedIso: timestamp
@@ -20434,7 +20434,7 @@ function mapEventToSignal(event) {
20434
20434
  if (Number.isNaN(observedAt.getTime())) return null;
20435
20435
  const statusCode = metadata?.statusCode;
20436
20436
  const isError = typeof statusCode === "number" && statusCode >= ERROR_STATUS_THRESHOLD3;
20437
- const path78 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
20437
+ const path79 = metadata?.trigger ? parsePathFromTrigger(metadata.trigger) : void 0;
20438
20438
  return {
20439
20439
  targetKind: CLOUDFLARE_TARGET_KIND,
20440
20440
  targetName: scriptName,
@@ -20442,7 +20442,7 @@ function mapEventToSignal(event) {
20442
20442
  errorCount: isError ? 1 : 0,
20443
20443
  lastObservedIso: observedAt.toISOString(),
20444
20444
  method,
20445
- ...path78 ? { path: path78 } : {},
20445
+ ...path79 ? { path: path79 } : {},
20446
20446
  ...typeof statusCode === "number" ? { statusCode } : {},
20447
20447
  ...typeof metadata?.duration === "number" ? { duration: metadata.duration } : {}
20448
20448
  };
@@ -20488,8 +20488,8 @@ function findTaggedWorkerFileNode(graph, workerName) {
20488
20488
  });
20489
20489
  return found;
20490
20490
  }
20491
- function findMatchingRouteNode(graph, serviceName, method, path78) {
20492
- const normalizedPath = normalizePathTemplate(path78);
20491
+ function findMatchingRouteNode(graph, serviceName, method, path79) {
20492
+ const normalizedPath = normalizePathTemplate(path79);
20493
20493
  let found = null;
20494
20494
  graph.forEachNode((id, attrs) => {
20495
20495
  if (found) return;
@@ -20506,10 +20506,10 @@ function createCloudflareResolveTarget(config, graph) {
20506
20506
  return (signal) => {
20507
20507
  if (signal.targetKind !== CLOUDFLARE_TARGET_KIND) return null;
20508
20508
  const scriptName = signal.targetName;
20509
- const { method, path: path78 } = signal;
20509
+ const { method, path: path79 } = signal;
20510
20510
  const resolveRouteGrain = (serviceName, wholeFileId) => {
20511
- if (!method || !path78) return wholeFileId;
20512
- return findMatchingRouteNode(graph, serviceName, method, path78) ?? wholeFileId;
20511
+ if (!method || !path79) return wholeFileId;
20512
+ return findMatchingRouteNode(graph, serviceName, method, path79) ?? wholeFileId;
20513
20513
  };
20514
20514
  const mapping = config.workers?.[scriptName];
20515
20515
  if (mapping) {
@@ -20861,9 +20861,9 @@ function parseCloudRunTargetName(targetName) {
20861
20861
  const secondSep = rest.indexOf(FIELD_SEP2);
20862
20862
  if (secondSep === -1) return null;
20863
20863
  const method = rest.slice(0, secondSep);
20864
- const path78 = rest.slice(secondSep + 1);
20865
- if (!serviceName || !method || !path78) return null;
20866
- return { serviceName, method, path: path78 };
20864
+ const path79 = rest.slice(secondSep + 1);
20865
+ if (!serviceName || !method || !path79) return null;
20866
+ return { serviceName, method, path: path79 };
20867
20867
  }
20868
20868
 
20869
20869
  // src/connectors/cloud-run/map.ts
@@ -20892,14 +20892,14 @@ function mapLogEntryToSignal2(entry) {
20892
20892
  if (!req) return null;
20893
20893
  if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
20894
20894
  const method = req.requestMethod.toUpperCase();
20895
- const path78 = pathFromRequestUrl2(req.requestUrl);
20896
- if (path78 === null) return null;
20895
+ const path79 = pathFromRequestUrl2(req.requestUrl);
20896
+ if (path79 === null) return null;
20897
20897
  const timestamp = entry.timestamp;
20898
20898
  if (typeof timestamp !== "string" || timestamp.length === 0) return null;
20899
20899
  const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD4;
20900
20900
  return {
20901
20901
  targetKind: CLOUD_RUN_TARGET_KIND,
20902
- targetName: packCloudRunTargetName({ serviceName, method, path: path78 }),
20902
+ targetName: packCloudRunTargetName({ serviceName, method, path: path79 }),
20903
20903
  callCount: 1,
20904
20904
  errorCount: isError ? 1 : 0,
20905
20905
  lastObservedIso: timestamp
@@ -20938,14 +20938,14 @@ function createCloudRunResolveTarget(graph, config) {
20938
20938
  if (signal.targetKind !== CLOUD_RUN_TARGET_KIND) return null;
20939
20939
  const identity = parseCloudRunTargetName(signal.targetName);
20940
20940
  if (!identity) return null;
20941
- const { serviceName: gcpServiceName, method, path: path78 } = identity;
20941
+ const { serviceName: gcpServiceName, method, path: path79 } = identity;
20942
20942
  const mappedService = config.serviceMap?.[gcpServiceName];
20943
20943
  if (mappedService) {
20944
20944
  const routeNodeId = findMatchingRouteNode2(
20945
20945
  graph,
20946
20946
  mappedService,
20947
20947
  method,
20948
- normalizePathTemplate(path78)
20948
+ normalizePathTemplate(path79)
20949
20949
  );
20950
20950
  if (routeNodeId) {
20951
20951
  return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types81.EdgeType.CALLS };
@@ -21081,9 +21081,9 @@ function parseGcpLbTargetName(targetName) {
21081
21081
  const secondSep = rest.indexOf(FIELD_SEP3);
21082
21082
  if (secondSep === -1) return null;
21083
21083
  const method = rest.slice(0, secondSep);
21084
- const path78 = rest.slice(secondSep + 1);
21085
- if (!backendServiceName || !method || !path78) return null;
21086
- return { backendServiceName, method, path: path78 };
21084
+ const path79 = rest.slice(secondSep + 1);
21085
+ if (!backendServiceName || !method || !path79) return null;
21086
+ return { backendServiceName, method, path: path79 };
21087
21087
  }
21088
21088
 
21089
21089
  // src/connectors/gcp-lb/map.ts
@@ -21112,14 +21112,14 @@ function mapLogEntryToSignal3(entry) {
21112
21112
  if (!req) return null;
21113
21113
  if (typeof req.requestMethod !== "string" || req.requestMethod.length === 0) return null;
21114
21114
  const method = req.requestMethod.toUpperCase();
21115
- const path78 = pathFromRequestUrl3(req.requestUrl);
21116
- if (path78 === null) return null;
21115
+ const path79 = pathFromRequestUrl3(req.requestUrl);
21116
+ if (path79 === null) return null;
21117
21117
  const timestamp = entry.timestamp;
21118
21118
  if (typeof timestamp !== "string" || timestamp.length === 0) return null;
21119
21119
  const isError = typeof req.status === "number" && req.status >= ERROR_STATUS_THRESHOLD5;
21120
21120
  return {
21121
21121
  targetKind: GCP_LB_TARGET_KIND,
21122
- targetName: packGcpLbTargetName({ backendServiceName, method, path: path78 }),
21122
+ targetName: packGcpLbTargetName({ backendServiceName, method, path: path79 }),
21123
21123
  callCount: 1,
21124
21124
  errorCount: isError ? 1 : 0,
21125
21125
  lastObservedIso: timestamp
@@ -21158,14 +21158,14 @@ function createGcpLbResolveTarget(graph, config) {
21158
21158
  if (signal.targetKind !== GCP_LB_TARGET_KIND) return null;
21159
21159
  const identity = parseGcpLbTargetName(signal.targetName);
21160
21160
  if (!identity) return null;
21161
- const { backendServiceName, method, path: path78 } = identity;
21161
+ const { backendServiceName, method, path: path79 } = identity;
21162
21162
  const mappedService = config.backendServiceMap?.[backendServiceName];
21163
21163
  if (mappedService) {
21164
21164
  const routeNodeId = findMatchingRouteNode3(
21165
21165
  graph,
21166
21166
  mappedService,
21167
21167
  method,
21168
- normalizePathTemplate(path78)
21168
+ normalizePathTemplate(path79)
21169
21169
  );
21170
21170
  if (routeNodeId) {
21171
21171
  return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types85.EdgeType.CALLS };
@@ -23369,7 +23369,7 @@ init_otel_grpc();
23369
23369
  // src/daemon.ts
23370
23370
  init_cjs_shims();
23371
23371
  var import_node_fs41 = require("fs");
23372
- var import_node_path77 = __toESM(require("path"), 1);
23372
+ var import_node_path78 = __toESM(require("path"), 1);
23373
23373
  var import_node_module = require("module");
23374
23374
  init_otel();
23375
23375
 
@@ -23407,13 +23407,13 @@ async function reconcileFrontierSurfaces(graph, errorsPath) {
23407
23407
  init_cjs_shims();
23408
23408
  var CREDENTIAL_REFRESH_SKEW_MS = 6e4;
23409
23409
  var CP_REQUEST_TIMEOUT_MS = 1e4;
23410
- async function cpGet(path78, deps) {
23410
+ async function cpGet(path79, deps) {
23411
23411
  const f = deps.fetchImpl ?? fetch;
23412
- const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${path78}`, {
23412
+ const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${path79}`, {
23413
23413
  headers: { authorization: `Bearer ${deps.daemonToken}`, accept: "application/json" },
23414
23414
  signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS)
23415
23415
  });
23416
- if (!res.ok) throw new Error(`control plane ${path78} \u2192 HTTP ${res.status}`);
23416
+ if (!res.ok) throw new Error(`control plane ${path79} \u2192 HTTP ${res.status}`);
23417
23417
  return await res.json();
23418
23418
  }
23419
23419
  function credentialRecord(provider, cred) {
@@ -23519,6 +23519,156 @@ async function maybeStartHostedConnectors(input) {
23519
23519
  });
23520
23520
  }
23521
23521
 
23522
+ // src/connectors/hosted-repos.ts
23523
+ init_cjs_shims();
23524
+ var import_node_os5 = __toESM(require("os"), 1);
23525
+ var import_node_path75 = __toESM(require("path"), 1);
23526
+ var import_promises = require("fs/promises");
23527
+ var CP_REQUEST_TIMEOUT_MS2 = 1e4;
23528
+ var DEFAULT_SYNC_INTERVAL_MS = 5 * 6e4;
23529
+ var CLONE_TIMEOUT_MS = 5 * 6e4;
23530
+ function scrubToken(s) {
23531
+ return s.replace(/x-access-token:[^@\s]+@/g, "x-access-token:***@");
23532
+ }
23533
+ async function cpGet2(pathname, deps) {
23534
+ const f = deps.fetchImpl ?? fetch;
23535
+ const res = await f(`${deps.cpUrl.replace(/\/+$/, "")}${pathname}`, {
23536
+ headers: { authorization: `Bearer ${deps.daemonToken}`, accept: "application/json" },
23537
+ signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS2)
23538
+ });
23539
+ if (!res.ok) throw new Error(`control plane ${pathname} \u2192 HTTP ${res.status}`);
23540
+ return await res.json();
23541
+ }
23542
+ async function cpPostStatus(deps, owner, name, body) {
23543
+ const f = deps.fetchImpl ?? fetch;
23544
+ const url = `${deps.cpUrl.replace(/\/+$/, "")}/internal/projects/${deps.projectId}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/status`;
23545
+ const res = await f(url, {
23546
+ method: "POST",
23547
+ headers: { authorization: `Bearer ${deps.daemonToken}`, "content-type": "application/json" },
23548
+ body: JSON.stringify(body),
23549
+ signal: AbortSignal.timeout(CP_REQUEST_TIMEOUT_MS2)
23550
+ });
23551
+ if (!res.ok && res.status !== 404) throw new Error(`control plane status POST \u2192 HTTP ${res.status}`);
23552
+ }
23553
+ var defaultCloneRepo = async (cloneUrl, ref, destDir) => {
23554
+ const [{ default: git }, httpMod, fs40] = await Promise.all([
23555
+ import("isomorphic-git"),
23556
+ import("isomorphic-git/http/node"),
23557
+ import("fs")
23558
+ ]);
23559
+ const http = httpMod.default ?? httpMod;
23560
+ const parsed = new URL(cloneUrl);
23561
+ const password = parsed.password || parsed.username;
23562
+ const username = parsed.password ? parsed.username : "x-access-token";
23563
+ const cleanUrl = `${parsed.protocol}//${parsed.host}${parsed.pathname}`;
23564
+ const clone = git.clone({
23565
+ fs: fs40,
23566
+ http,
23567
+ dir: destDir,
23568
+ url: cleanUrl,
23569
+ // Absent ref → isomorphic-git clones the remote's default branch.
23570
+ ...ref ? { ref } : {},
23571
+ singleBranch: true,
23572
+ depth: 1,
23573
+ onAuth: () => ({ username, password })
23574
+ });
23575
+ let timer;
23576
+ const timeout = new Promise((_, reject) => {
23577
+ timer = setTimeout(() => reject(new Error(`clone timed out after ${CLONE_TIMEOUT_MS}ms`)), CLONE_TIMEOUT_MS);
23578
+ });
23579
+ try {
23580
+ await Promise.race([clone, timeout]);
23581
+ } finally {
23582
+ if (timer) clearTimeout(timer);
23583
+ }
23584
+ };
23585
+ function needsSync(r) {
23586
+ return r.syncStatus === void 0 || r.syncStatus === "syncing";
23587
+ }
23588
+ async function syncOneRepo(r, input) {
23589
+ const { deps, graph } = input;
23590
+ const cloneRepo = input.cloneRepo ?? defaultCloneRepo;
23591
+ const extract = input.extract ?? extractFromDirectory;
23592
+ const label = `${r.owner}/${r.name}`;
23593
+ const tmpRoot = input.tmpRoot ?? import_node_os5.default.tmpdir();
23594
+ let dir;
23595
+ try {
23596
+ dir = await (0, import_promises.mkdtemp)(import_node_path75.default.join(tmpRoot, "neat-repo-"));
23597
+ await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
23598
+ await extract(graph, dir);
23599
+ await cpPostStatus(deps, r.owner, r.name, {
23600
+ syncStatus: "synced",
23601
+ lastSyncAt: new Date(input.now?.() ?? Date.now()).toISOString()
23602
+ });
23603
+ } catch (err) {
23604
+ input.onError?.(label, err);
23605
+ await cpPostStatus(deps, r.owner, r.name, {
23606
+ syncStatus: "failed",
23607
+ detail: scrubToken(err.message).slice(0, 300)
23608
+ }).catch(() => {
23609
+ });
23610
+ } finally {
23611
+ if (dir) await (0, import_promises.rm)(dir, { recursive: true, force: true }).catch(() => {
23612
+ });
23613
+ }
23614
+ }
23615
+ async function runRepoSyncPass(input) {
23616
+ let repos;
23617
+ try {
23618
+ repos = await cpGet2(`/internal/projects/${input.deps.projectId}/repos`, input.deps);
23619
+ } catch (err) {
23620
+ input.onSkip?.("(all)", `control plane repo list unreadable \u2014 ${err.message}`);
23621
+ return;
23622
+ }
23623
+ if (!Array.isArray(repos)) return;
23624
+ for (const r of repos) {
23625
+ if (!needsSync(r)) continue;
23626
+ await syncOneRepo(r, input);
23627
+ }
23628
+ }
23629
+ async function startRepoSync(input) {
23630
+ const intervalMs = input.intervalMs ?? DEFAULT_SYNC_INTERVAL_MS;
23631
+ let stopped = false;
23632
+ let running = false;
23633
+ const tick = async () => {
23634
+ if (stopped || running) return;
23635
+ running = true;
23636
+ try {
23637
+ await runRepoSyncPass(input);
23638
+ } finally {
23639
+ running = false;
23640
+ }
23641
+ };
23642
+ void tick();
23643
+ const timer = setInterval(() => {
23644
+ void tick();
23645
+ }, intervalMs);
23646
+ if (typeof timer.unref === "function") timer.unref();
23647
+ return () => {
23648
+ stopped = true;
23649
+ clearInterval(timer);
23650
+ };
23651
+ }
23652
+ async function maybeStartRepoSync(input) {
23653
+ const env = input.env ?? process.env;
23654
+ const cpUrl = env.NEAT_CP_URL;
23655
+ const projectId = env.NEAT_CP_PROJECT_ID;
23656
+ const daemonToken = env.NEAT_AUTH_TOKEN;
23657
+ if (!cpUrl || !projectId || !daemonToken) return () => {
23658
+ };
23659
+ return startRepoSync({
23660
+ deps: { cpUrl, projectId, daemonToken, ...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {} },
23661
+ graph: input.graph,
23662
+ project: input.project,
23663
+ ...input.cloneRepo ? { cloneRepo: input.cloneRepo } : {},
23664
+ ...input.extract ? { extract: input.extract } : {},
23665
+ ...input.intervalMs !== void 0 ? { intervalMs: input.intervalMs } : {},
23666
+ ...input.tmpRoot ? { tmpRoot: input.tmpRoot } : {},
23667
+ ...input.onSkip ? { onSkip: input.onSkip } : {},
23668
+ ...input.onError ? { onError: input.onError } : {}
23669
+ });
23670
+ }
23671
+
23522
23672
  // src/connectors/kubernetes/index.ts
23523
23673
  init_cjs_shims();
23524
23674
 
@@ -23572,9 +23722,9 @@ function makeK8sFetchImpl(transport) {
23572
23722
  req.end();
23573
23723
  }));
23574
23724
  }
23575
- async function listResource(transport, namespace, path78, opts = {}) {
23725
+ async function listResource(transport, namespace, path79, opts = {}) {
23576
23726
  const base = opts.apiUrl ?? transport.server;
23577
- const url = `${base.replace(/\/$/, "")}${path78}`;
23727
+ const url = `${base.replace(/\/$/, "")}${path79}`;
23578
23728
  const fetchImpl = opts.fetchImpl ?? makeK8sFetchImpl(transport);
23579
23729
  const res = await junctionFetch(
23580
23730
  url,
@@ -23584,7 +23734,7 @@ async function listResource(transport, namespace, path78, opts = {}) {
23584
23734
  { provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, fetchImpl }
23585
23735
  );
23586
23736
  if (!res.ok) {
23587
- throw new Error(`kubernetes ${path78} failed: ${res.status} ${res.statusText}`);
23737
+ throw new Error(`kubernetes ${path79} failed: ${res.status} ${res.statusText}`);
23588
23738
  }
23589
23739
  const json = await res.json();
23590
23740
  return Array.isArray(json.items) ? json.items : [];
@@ -23886,21 +24036,21 @@ function createK8sResolveTarget(graph) {
23886
24036
 
23887
24037
  // src/connectors/kubernetes/substrate.ts
23888
24038
  init_cjs_shims();
23889
- var import_promises = require("fs/promises");
23890
- var import_node_os5 = __toESM(require("os"), 1);
23891
- var import_node_path75 = __toESM(require("path"), 1);
24039
+ var import_promises2 = require("fs/promises");
24040
+ var import_node_os6 = __toESM(require("os"), 1);
24041
+ var import_node_path76 = __toESM(require("path"), 1);
23892
24042
  function defaultHome() {
23893
24043
  const override = process.env.NEAT_HOME;
23894
- if (override && override.length > 0) return import_node_path75.default.resolve(override);
23895
- return import_node_path75.default.join(import_node_os5.default.homedir(), ".neat");
24044
+ if (override && override.length > 0) return import_node_path76.default.resolve(override);
24045
+ return import_node_path76.default.join(import_node_os6.default.homedir(), ".neat");
23896
24046
  }
23897
24047
  function k8sSubstrateConfigPath(home = defaultHome()) {
23898
- return import_node_path75.default.join(home, "k8s.json");
24048
+ return import_node_path76.default.join(home, "k8s.json");
23899
24049
  }
23900
24050
  async function readK8sSubstrateConfig(home = defaultHome()) {
23901
24051
  let raw;
23902
24052
  try {
23903
- raw = await (0, import_promises.readFile)(k8sSubstrateConfigPath(home), "utf8");
24053
+ raw = await (0, import_promises2.readFile)(k8sSubstrateConfigPath(home), "utf8");
23904
24054
  } catch {
23905
24055
  return { version: 1, deployments: [] };
23906
24056
  }
@@ -23995,7 +24145,7 @@ init_auth();
23995
24145
  // src/unrouted.ts
23996
24146
  init_cjs_shims();
23997
24147
  var import_node_fs40 = require("fs");
23998
- var import_node_path76 = __toESM(require("path"), 1);
24148
+ var import_node_path77 = __toESM(require("path"), 1);
23999
24149
  function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new Date()) {
24000
24150
  return {
24001
24151
  timestamp: now.toISOString(),
@@ -24005,34 +24155,34 @@ function buildUnroutedSpanRecord(serviceName, traceId, now = /* @__PURE__ */ new
24005
24155
  };
24006
24156
  }
24007
24157
  async function appendUnroutedSpan(neatHome3, record) {
24008
- const target = import_node_path76.default.join(neatHome3, "errors.ndjson");
24158
+ const target = import_node_path77.default.join(neatHome3, "errors.ndjson");
24009
24159
  await import_node_fs40.promises.mkdir(neatHome3, { recursive: true });
24010
24160
  await import_node_fs40.promises.appendFile(target, JSON.stringify(record) + "\n", "utf8");
24011
24161
  }
24012
24162
  function unroutedErrorsPath(neatHome3) {
24013
- return import_node_path76.default.join(neatHome3, "errors.ndjson");
24163
+ return import_node_path77.default.join(neatHome3, "errors.ndjson");
24014
24164
  }
24015
24165
 
24016
24166
  // src/daemon.ts
24017
24167
  var import_types106 = require("@neat.is/types");
24018
24168
  function daemonJsonPath(scanPath) {
24019
- return import_node_path77.default.join(scanPath, "neat-out", "daemon.json");
24169
+ return import_node_path78.default.join(scanPath, "neat-out", "daemon.json");
24020
24170
  }
24021
24171
  function daemonsDiscoveryDir(home) {
24022
24172
  const base = home && home.length > 0 ? home : neatHomeFromEnv();
24023
- return import_node_path77.default.join(base, "daemons");
24173
+ return import_node_path78.default.join(base, "daemons");
24024
24174
  }
24025
24175
  function daemonDiscoveryPath(project, home) {
24026
- return import_node_path77.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
24176
+ return import_node_path78.default.join(daemonsDiscoveryDir(home), `${sanitizeDiscoveryName(project)}.json`);
24027
24177
  }
24028
24178
  function sanitizeDiscoveryName(project) {
24029
24179
  return project.replace(/[^A-Za-z0-9._-]/g, "_");
24030
24180
  }
24031
24181
  function neatHomeFromEnv() {
24032
24182
  const env = process.env.NEAT_HOME;
24033
- if (env && env.length > 0) return import_node_path77.default.resolve(env);
24183
+ if (env && env.length > 0) return import_node_path78.default.resolve(env);
24034
24184
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
24035
- return import_node_path77.default.join(home, ".neat");
24185
+ return import_node_path78.default.join(home, ".neat");
24036
24186
  }
24037
24187
  function resolveNeatVersion() {
24038
24188
  if (process.env.NEAT_LOCAL_VERSION && process.env.NEAT_LOCAL_VERSION.length > 0) {
@@ -24089,17 +24239,21 @@ function teardownSlot(slot) {
24089
24239
  slot.stopK8sSubstrate();
24090
24240
  } catch {
24091
24241
  }
24242
+ try {
24243
+ slot.stopRepoSync();
24244
+ } catch {
24245
+ }
24092
24246
  try {
24093
24247
  slot.detachEvents();
24094
24248
  } catch {
24095
24249
  }
24096
24250
  }
24097
24251
  function neatHomeFor(opts) {
24098
- if (opts.neatHome && opts.neatHome.length > 0) return import_node_path77.default.resolve(opts.neatHome);
24252
+ if (opts.neatHome && opts.neatHome.length > 0) return import_node_path78.default.resolve(opts.neatHome);
24099
24253
  const env = process.env.NEAT_HOME;
24100
- if (env && env.length > 0) return import_node_path77.default.resolve(env);
24254
+ if (env && env.length > 0) return import_node_path78.default.resolve(env);
24101
24255
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
24102
- return import_node_path77.default.join(home, ".neat");
24256
+ return import_node_path78.default.join(home, ".neat");
24103
24257
  }
24104
24258
  function routeSpanToProject(serviceName, projects) {
24105
24259
  if (!serviceName) return DEFAULT_PROJECT;
@@ -24151,7 +24305,7 @@ function spanBelongsToSingleProject(graph, project, serviceName) {
24151
24305
  );
24152
24306
  }
24153
24307
  async function bootstrapProject(entry, connectors = [], neatHome3) {
24154
- const paths = pathsForProject(entry.name, import_node_path77.default.join(entry.path, "neat-out"));
24308
+ const paths = pathsForProject(entry.name, import_node_path78.default.join(entry.path, "neat-out"));
24155
24309
  try {
24156
24310
  const stat = await import_node_fs41.promises.stat(entry.path);
24157
24311
  if (!stat.isDirectory()) {
@@ -24177,6 +24331,8 @@ async function bootstrapProject(entry, connectors = [], neatHome3) {
24177
24331
  },
24178
24332
  stopK8sSubstrate: () => {
24179
24333
  },
24334
+ stopRepoSync: () => {
24335
+ },
24180
24336
  detachEvents: () => {
24181
24337
  },
24182
24338
  status: "broken",
@@ -24228,6 +24384,12 @@ async function bootstrapProject(entry, connectors = [], neatHome3) {
24228
24384
  ...neatHome3 ? { home: neatHome3 } : {},
24229
24385
  onSkip: (skipped, reason) => console.warn(`neatd: k8s substrate "${skipped.id}" skipped for project "${entry.name}" \u2014 ${reason}`)
24230
24386
  });
24387
+ const stopRepoSync = await maybeStartRepoSync({
24388
+ project: entry.name,
24389
+ graph,
24390
+ onSkip: (repo, reason) => console.warn(`neatd: repo-sync "${repo}" skipped for project "${entry.name}" \u2014 ${reason}`),
24391
+ onError: (repo, err) => console.warn(`neatd: repo-sync "${repo}" failed for project "${entry.name}" \u2014 ${err.message}`)
24392
+ });
24231
24393
  await touchLastSeen(entry.name).catch(() => {
24232
24394
  });
24233
24395
  return {
@@ -24240,6 +24402,7 @@ async function bootstrapProject(entry, connectors = [], neatHome3) {
24240
24402
  stopConnectors,
24241
24403
  stopHostedConnectors,
24242
24404
  stopK8sSubstrate,
24405
+ stopRepoSync,
24243
24406
  detachEvents,
24244
24407
  status: "active"
24245
24408
  };
@@ -24296,7 +24459,7 @@ async function startDaemon(opts = {}) {
24296
24459
  const projectArg = typeof opts.project === "string" && opts.project.length > 0 ? opts.project : process.env.NEAT_PROJECT && process.env.NEAT_PROJECT.length > 0 ? process.env.NEAT_PROJECT : null;
24297
24460
  const projectPathArg = opts.projectPath && opts.projectPath.length > 0 ? opts.projectPath : process.env.NEAT_PROJECT_PATH && process.env.NEAT_PROJECT_PATH.length > 0 ? process.env.NEAT_PROJECT_PATH : null;
24298
24461
  const singleProject = projectArg;
24299
- const singleProjectPath = singleProject && projectPathArg ? import_node_path77.default.resolve(projectPathArg) : null;
24462
+ const singleProjectPath = singleProject && projectPathArg ? import_node_path78.default.resolve(projectPathArg) : null;
24300
24463
  if (singleProject && !singleProjectPath) {
24301
24464
  throw new Error(
24302
24465
  `neatd: project "${singleProject}" given without a projectPath; pass NEAT_PROJECT_PATH alongside NEAT_PROJECT.`
@@ -24311,7 +24474,7 @@ async function startDaemon(opts = {}) {
24311
24474
  );
24312
24475
  }
24313
24476
  }
24314
- const pidPath = import_node_path77.default.join(home, "neatd.pid");
24477
+ const pidPath = import_node_path78.default.join(home, "neatd.pid");
24315
24478
  await writeAtomically(pidPath, `${process.pid}
24316
24479
  `);
24317
24480
  const slots = /* @__PURE__ */ new Map();
@@ -24783,8 +24946,8 @@ async function startDaemon(opts = {}) {
24783
24946
  let registryWatcher = null;
24784
24947
  let reloadTimer = null;
24785
24948
  if (!singleProject) try {
24786
- const regDir = import_node_path77.default.dirname(regPath);
24787
- const regBase = import_node_path77.default.basename(regPath);
24949
+ const regDir = import_node_path78.default.dirname(regPath);
24950
+ const regBase = import_node_path78.default.basename(regPath);
24788
24951
  registryWatcher = (0, import_node_fs41.watch)(regDir, (_eventType, filename) => {
24789
24952
  if (filename !== null && filename !== regBase) return;
24790
24953
  if (reloadTimer) clearTimeout(reloadTimer);