@neat.is/core 0.10.4 → 0.10.5-dev.20261001

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.d.cts CHANGED
@@ -45,6 +45,7 @@ interface ExtractOptions {
45
45
  onPolicyTrigger?: (graph: NeatGraph) => Promise<void> | void;
46
46
  project?: string;
47
47
  errorsPath?: string;
48
+ source?: string;
48
49
  }
49
50
  declare function extractFromDirectory(graph: NeatGraph, scanPath: string, opts?: ExtractOptions): Promise<ExtractResult>;
50
51
 
package/dist/index.d.ts CHANGED
@@ -45,6 +45,7 @@ interface ExtractOptions {
45
45
  onPolicyTrigger?: (graph: NeatGraph) => Promise<void> | void;
46
46
  project?: string;
47
47
  errorsPath?: string;
48
+ source?: string;
48
49
  }
49
50
  declare function extractFromDirectory(graph: NeatGraph, scanPath: string, opts?: ExtractOptions): Promise<ExtractResult>;
50
51
 
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  routeSpanToProject,
3
3
  startDaemon
4
- } from "./chunk-2OQVIBZZ.js";
4
+ } from "./chunk-TONL5O2E.js";
5
5
  import {
6
6
  ProjectNameCollisionError,
7
7
  addProject,
@@ -37,7 +37,7 @@ import {
37
37
  thresholdForEdgeType,
38
38
  touchLastSeen,
39
39
  writeAtomically
40
- } from "./chunk-TUGYIRUT.js";
40
+ } from "./chunk-HHAPD6JD.js";
41
41
  import {
42
42
  startOtelGrpcReceiver
43
43
  } from "./chunk-LXQCL4MP.js";
package/dist/neatd.cjs CHANGED
@@ -3362,6 +3362,10 @@ function languageForPath(relPath) {
3362
3362
  return void 0;
3363
3363
  }
3364
3364
  }
3365
+ var currentSource;
3366
+ function setExtractionSource(source) {
3367
+ currentSource = source;
3368
+ }
3365
3369
  function ensureFileNode(graph, serviceName, serviceNodeId, relPath) {
3366
3370
  let nodesAdded = 0;
3367
3371
  let edgesAdded = 0;
@@ -3374,10 +3378,16 @@ function ensureFileNode(graph, serviceName, serviceNodeId, relPath) {
3374
3378
  service: serviceName,
3375
3379
  path: relPath,
3376
3380
  ...language ? { language } : {},
3381
+ ...currentSource ? { source: currentSource } : {},
3377
3382
  discoveredVia: "static"
3378
3383
  };
3379
3384
  graph.addNode(fileNodeId, node);
3380
3385
  nodesAdded++;
3386
+ } else if (currentSource) {
3387
+ const existing = graph.getNodeAttributes(fileNodeId);
3388
+ if (existing.source !== currentSource) {
3389
+ graph.replaceNodeAttributes(fileNodeId, { ...existing, source: currentSource });
3390
+ }
3381
3391
  }
3382
3392
  const containsId = (0, import_types4.extractedEdgeId)(serviceNodeId, fileNodeId, import_types4.EdgeType.CONTAINS);
3383
3393
  if (!graph.hasEdge(containsId)) {
@@ -16435,10 +16445,12 @@ init_cjs_shims();
16435
16445
  var import_node_fs33 = require("fs");
16436
16446
  var import_node_path68 = __toESM(require("path"), 1);
16437
16447
  var import_types58 = require("@neat.is/types");
16438
- function dropOrphanedFileNodes(graph) {
16448
+ function dropOrphanedFileNodes(graph, source) {
16439
16449
  const orphans = [];
16440
16450
  graph.forEachNode((id, attrs) => {
16441
- if (attrs.type !== import_types58.NodeType.FileNode) return;
16451
+ const node = attrs;
16452
+ if (node.type !== import_types58.NodeType.FileNode) return;
16453
+ if (source && node.source !== source) return;
16442
16454
  if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
16443
16455
  orphans.push(id);
16444
16456
  }
@@ -16446,12 +16458,23 @@ function dropOrphanedFileNodes(graph) {
16446
16458
  for (const id of orphans) graph.dropNode(id);
16447
16459
  return orphans.length;
16448
16460
  }
16449
- function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
16461
+ function outOfScope(graph, edge, source) {
16462
+ if (!source) return false;
16463
+ for (const endpoint2 of [edge.source, edge.target]) {
16464
+ if (!graph.hasNode(endpoint2)) continue;
16465
+ const node = graph.getNodeAttributes(endpoint2);
16466
+ if (node.type !== import_types58.NodeType.FileNode) continue;
16467
+ return node.source !== source;
16468
+ }
16469
+ return false;
16470
+ }
16471
+ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], source) {
16450
16472
  const toDrop = [];
16451
16473
  const bases = [scanPath, ...serviceDirs];
16452
16474
  graph.forEachEdge((id, attrs) => {
16453
16475
  const edge = attrs;
16454
16476
  if (edge.provenance !== import_types58.Provenance.EXTRACTED) return;
16477
+ if (outOfScope(graph, edge, source)) return;
16455
16478
  const evidenceFile = edge.evidence?.file;
16456
16479
  if (!evidenceFile) return;
16457
16480
  if (import_node_path68.default.isAbsolute(evidenceFile)) {
@@ -16462,7 +16485,7 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = []) {
16462
16485
  if (!found) toDrop.push(id);
16463
16486
  });
16464
16487
  for (const id of toDrop) graph.dropEdge(id);
16465
- dropOrphanedFileNodes(graph);
16488
+ dropOrphanedFileNodes(graph, source);
16466
16489
  return toDrop.length;
16467
16490
  }
16468
16491
 
@@ -16471,6 +16494,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
16471
16494
  await ensureCompatLoaded();
16472
16495
  drainExtractionErrors();
16473
16496
  drainSkippedFiles();
16497
+ setExtractionSource(opts.source);
16474
16498
  const services = await discoverServices(scanPath);
16475
16499
  const phase1Nodes = addServiceNodes(graph, services);
16476
16500
  await addServiceAliases(graph, scanPath, services);
@@ -16491,7 +16515,8 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
16491
16515
  const ghostsRetired = retireExtractedEdgesByMissingFile(
16492
16516
  graph,
16493
16517
  scanPath,
16494
- services.map((s) => s.dir)
16518
+ services.map((s) => s.dir),
16519
+ opts.source
16495
16520
  );
16496
16521
  const frontiersPromoted = promoteFrontierNodes(graph);
16497
16522
  if (opts.onPolicyTrigger) await opts.onPolicyTrigger(graph);
@@ -16526,6 +16551,7 @@ async function extractFromDirectory(graph, scanPath, opts = {}) {
16526
16551
  );
16527
16552
  }
16528
16553
  }
16554
+ setExtractionSource(void 0);
16529
16555
  const result = {
16530
16556
  nodesAdded: phase1Nodes + fileEnum.nodesAdded + symbolEnum.nodesAdded + importGraph.nodesAdded + symbolEdges.nodesAdded + actionPhase.nodesAdded + phase2.nodesAdded + phase3.nodesAdded + routePhase.nodesAdded + grpcPhase.nodesAdded + phase4.nodesAdded + tableEdges.nodesAdded + phase5.nodesAdded + zodPhase.nodesAdded + firestoreRulesPhase.nodesAdded,
16531
16557
  edgesAdded: fileEnum.edgesAdded + symbolEnum.edgesAdded + importGraph.edgesAdded + symbolEdges.edgesAdded + actionPhase.edgesAdded + phase2.edgesAdded + phase3.edgesAdded + routePhase.edgesAdded + grpcPhase.edgesAdded + phase4.edgesAdded + tableEdges.edgesAdded + phase5.edgesAdded + zodPhase.edgesAdded + firestoreRulesPhase.edgesAdded,
@@ -24420,7 +24446,7 @@ async function syncOneRepo(r, input) {
24420
24446
  await cpPostStatus(deps, r.owner, r.name, { syncStatus: "syncing", detail: "cloning" }).catch(() => {
24421
24447
  });
24422
24448
  await cloneRepo(r.cloneUrl, r.defaultBranch, dir);
24423
- const extracted = await extract(graph, dir);
24449
+ const extracted = await extract(graph, dir, { source: label });
24424
24450
  const nodes = extracted?.nodesAdded ?? 0;
24425
24451
  const edges = extracted?.edgesAdded ?? 0;
24426
24452
  await cpPostStatus(deps, r.owner, r.name, {
@@ -25217,7 +25243,7 @@ async function bootstrapProject(entry2, connectors = [], neatHome4) {
25217
25243
  await loadGraphFromDisk(graph, outPath);
25218
25244
  const detachEvents = attachGraphToEventBus(graph, { project: entry2.name });
25219
25245
  try {
25220
- await extractFromDirectory(graph, entry2.path);
25246
+ await extractFromDirectory(graph, entry2.path, { source: entry2.name });
25221
25247
  const stopPersist = startPersistLoop(graph, outPath, { exitOnSignal: false });
25222
25248
  const stopStaleness = startStalenessLoop(graph, {
25223
25249
  staleEventsPath: paths.staleEventsPath,