@neat.is/core 0.10.6-dev.20261010 → 0.10.7-dev.20261011
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/{chunk-H2BAPN33.js → chunk-6K22WGO7.js} +432 -181
- package/dist/chunk-6K22WGO7.js.map +1 -0
- package/dist/chunk-AEMLUMHC.js +42 -0
- package/dist/chunk-AEMLUMHC.js.map +1 -0
- package/dist/{chunk-52SCEPEW.js → chunk-S5S2FYCQ.js} +36 -7
- package/dist/chunk-S5S2FYCQ.js.map +1 -0
- package/dist/cli.cjs +836 -550
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +3 -2
- package/dist/cli.d.ts +3 -2
- package/dist/cli.js +53 -12
- package/dist/cli.js.map +1 -1
- package/dist/incidents-render.cjs +66 -0
- package/dist/incidents-render.cjs.map +1 -0
- package/dist/incidents-render.d.cts +5 -0
- package/dist/incidents-render.d.ts +5 -0
- package/dist/incidents-render.js +8 -0
- package/dist/incidents-render.js.map +1 -0
- package/dist/index.cjs +804 -523
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +810 -526
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +8 -5
- package/dist/neatd.js.map +1 -1
- package/dist/server.cjs +769 -570
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +7 -2
- package/dist/chunk-52SCEPEW.js.map +0 -1
- package/dist/chunk-H2BAPN33.js.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -801,6 +801,7 @@ __export(cli_exports, {
|
|
|
801
801
|
cwdProjectApplies: () => cwdProjectApplies,
|
|
802
802
|
isLoopbackEndpoint: () => isLoopbackEndpoint,
|
|
803
803
|
isNpxInvocation: () => isNpxInvocation,
|
|
804
|
+
loopbackResolutionHint: () => loopbackResolutionHint,
|
|
804
805
|
main: () => main,
|
|
805
806
|
parseArgs: () => parseArgs,
|
|
806
807
|
printBanner: () => printBanner,
|
|
@@ -3039,7 +3040,7 @@ var PolicyViolationsLog = class {
|
|
|
3039
3040
|
};
|
|
3040
3041
|
|
|
3041
3042
|
// src/ingest.ts
|
|
3042
|
-
var
|
|
3043
|
+
var import_types10 = require("@neat.is/types");
|
|
3043
3044
|
|
|
3044
3045
|
// src/extract/routes.ts
|
|
3045
3046
|
init_cjs_shims();
|
|
@@ -5816,9 +5817,95 @@ async function addRoutes(graph, services) {
|
|
|
5816
5817
|
return { nodesAdded, edgesAdded };
|
|
5817
5818
|
}
|
|
5818
5819
|
|
|
5819
|
-
// src/
|
|
5820
|
+
// src/extract/source-baseline.ts
|
|
5820
5821
|
init_cjs_shims();
|
|
5821
5822
|
var import_types8 = require("@neat.is/types");
|
|
5823
|
+
var states = /* @__PURE__ */ new WeakMap();
|
|
5824
|
+
var REPOSITORY = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
5825
|
+
function validCommit(commit, repository) {
|
|
5826
|
+
return !!commit && commit.repository === repository && /^[0-9a-f]{40}$/.test(commit.sha);
|
|
5827
|
+
}
|
|
5828
|
+
function stateOf(graph) {
|
|
5829
|
+
let state = states.get(graph);
|
|
5830
|
+
if (!state) {
|
|
5831
|
+
state = { repos: /* @__PURE__ */ new Map(), active: /* @__PURE__ */ new Set(), conflicted: /* @__PURE__ */ new Set() };
|
|
5832
|
+
states.set(graph, state);
|
|
5833
|
+
}
|
|
5834
|
+
return state;
|
|
5835
|
+
}
|
|
5836
|
+
function setEntry(state, repository, baseline, generation = /* @__PURE__ */ Symbol()) {
|
|
5837
|
+
state.repos.set(repository, {
|
|
5838
|
+
baseline,
|
|
5839
|
+
generation,
|
|
5840
|
+
services: state.repos.get(repository)?.services ?? /* @__PURE__ */ new Set()
|
|
5841
|
+
});
|
|
5842
|
+
}
|
|
5843
|
+
function readSourceBaselines(graph) {
|
|
5844
|
+
const state = states.get(graph);
|
|
5845
|
+
if (!state) return [];
|
|
5846
|
+
return [...state.repos.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([, entry2]) => ({ ...entry2.baseline }));
|
|
5847
|
+
}
|
|
5848
|
+
function invalidateSourceBaseline(graph, repository, status2 = "unavailable") {
|
|
5849
|
+
if (repository !== void 0) {
|
|
5850
|
+
if (REPOSITORY.test(repository)) setEntry(stateOf(graph), repository, { status: status2, repository });
|
|
5851
|
+
return;
|
|
5852
|
+
}
|
|
5853
|
+
const state = states.get(graph);
|
|
5854
|
+
if (!state) return;
|
|
5855
|
+
for (const generation of state.active) state.conflicted.add(generation);
|
|
5856
|
+
for (const name of state.repos.keys()) {
|
|
5857
|
+
setEntry(state, name, { status: "unavailable", repository: name });
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
5860
|
+
function beginSourceExtraction(graph, source, commit) {
|
|
5861
|
+
const generation = /* @__PURE__ */ Symbol();
|
|
5862
|
+
const state = stateOf(graph);
|
|
5863
|
+
if (source === void 0) {
|
|
5864
|
+
invalidateSourceBaseline(graph);
|
|
5865
|
+
state.active.add(generation);
|
|
5866
|
+
return generation;
|
|
5867
|
+
}
|
|
5868
|
+
state.active.add(generation);
|
|
5869
|
+
if (!REPOSITORY.test(source)) return generation;
|
|
5870
|
+
setEntry(
|
|
5871
|
+
state,
|
|
5872
|
+
source,
|
|
5873
|
+
validCommit(commit, source) ? { status: "syncing", repository: source } : { status: "unavailable", repository: source },
|
|
5874
|
+
generation
|
|
5875
|
+
);
|
|
5876
|
+
return generation;
|
|
5877
|
+
}
|
|
5878
|
+
function servicesOf(graph, repository) {
|
|
5879
|
+
const services = /* @__PURE__ */ new Set();
|
|
5880
|
+
graph.forEachNode((_id, attrs) => {
|
|
5881
|
+
const node = attrs;
|
|
5882
|
+
if (node.type === import_types8.NodeType.FileNode && node.source === repository && node.service) {
|
|
5883
|
+
services.add(node.service);
|
|
5884
|
+
}
|
|
5885
|
+
});
|
|
5886
|
+
return services;
|
|
5887
|
+
}
|
|
5888
|
+
function finishSourceExtraction(graph, generation, source, commit, result) {
|
|
5889
|
+
const state = states.get(graph);
|
|
5890
|
+
if (!state) return;
|
|
5891
|
+
state.active.delete(generation);
|
|
5892
|
+
const conflicted = state.conflicted.delete(generation);
|
|
5893
|
+
if (source === void 0 || !REPOSITORY.test(source)) return;
|
|
5894
|
+
const entry2 = state.repos.get(source);
|
|
5895
|
+
if (!entry2 || entry2.generation !== generation) return;
|
|
5896
|
+
entry2.services = servicesOf(graph, source);
|
|
5897
|
+
let shared = false;
|
|
5898
|
+
for (const [name, other] of state.repos) {
|
|
5899
|
+
if (name === source || ![...entry2.services].some((s) => other.services.has(s))) continue;
|
|
5900
|
+
shared = true;
|
|
5901
|
+
setEntry(state, name, { status: "unavailable", repository: name }, other.generation);
|
|
5902
|
+
}
|
|
5903
|
+
entry2.baseline = !conflicted && !shared && validCommit(commit, source) && result.extractionErrors === 0 && result.skippedFiles === 0 ? { status: "ready", repository: source, sha: commit.sha } : { status: "unavailable", repository: source };
|
|
5904
|
+
}
|
|
5905
|
+
|
|
5906
|
+
// src/columns.ts
|
|
5907
|
+
init_cjs_shims();
|
|
5908
|
+
var import_types9 = require("@neat.is/types");
|
|
5822
5909
|
var OBSERVED_COLUMN_CONFIDENCE = 0.9;
|
|
5823
5910
|
function normalizeProvenances(provenances) {
|
|
5824
5911
|
return [...new Set(provenances)].sort();
|
|
@@ -5861,10 +5948,10 @@ function foldSdkWrites(existing, writes) {
|
|
|
5861
5948
|
return out;
|
|
5862
5949
|
}
|
|
5863
5950
|
function columnIsDeclared(col) {
|
|
5864
|
-
return col.provenances.includes(
|
|
5951
|
+
return col.provenances.includes(import_types9.Provenance.EXTRACTED);
|
|
5865
5952
|
}
|
|
5866
5953
|
function columnIsObserved(col) {
|
|
5867
|
-
return col.provenances.includes(
|
|
5954
|
+
return col.provenances.includes(import_types9.Provenance.OBSERVED);
|
|
5868
5955
|
}
|
|
5869
5956
|
|
|
5870
5957
|
// src/latency-digest.ts
|
|
@@ -6328,11 +6415,11 @@ function callSiteFromSpan(span, serviceNode, scanPath) {
|
|
|
6328
6415
|
};
|
|
6329
6416
|
}
|
|
6330
6417
|
function reconcileObservedRelPath(graph, serviceName, relPath) {
|
|
6331
|
-
if (graph.hasNode((0,
|
|
6418
|
+
if (graph.hasNode((0, import_types10.fileId)(serviceName, relPath))) return relPath;
|
|
6332
6419
|
let best = null;
|
|
6333
6420
|
graph.forEachNode((_id, attrs) => {
|
|
6334
6421
|
const a = attrs;
|
|
6335
|
-
if (a.type !==
|
|
6422
|
+
if (a.type !== import_types10.NodeType.FileNode || a.service !== serviceName) return;
|
|
6336
6423
|
if (a.discoveredVia === "otel") return;
|
|
6337
6424
|
const p = a.path;
|
|
6338
6425
|
if (!p) return;
|
|
@@ -6344,14 +6431,14 @@ function reconcileObservedRelPath(graph, serviceName, relPath) {
|
|
|
6344
6431
|
}
|
|
6345
6432
|
function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
6346
6433
|
const svcAttrs = graph.hasNode(serviceNodeId) ? graph.getNodeAttributes(serviceNodeId) : void 0;
|
|
6347
|
-
const canonicalService = svcAttrs && svcAttrs.type ===
|
|
6434
|
+
const canonicalService = svcAttrs && svcAttrs.type === import_types10.NodeType.ServiceNode && typeof svcAttrs.name === "string" ? svcAttrs.name : serviceName;
|
|
6348
6435
|
const relPath = reconcileObservedRelPath(graph, canonicalService, callSite.relPath);
|
|
6349
|
-
const fileNodeId = (0,
|
|
6436
|
+
const fileNodeId = (0, import_types10.fileId)(canonicalService, relPath);
|
|
6350
6437
|
if (!graph.hasNode(fileNodeId)) {
|
|
6351
6438
|
const language = languageForExt(relPath);
|
|
6352
6439
|
const node = {
|
|
6353
6440
|
id: fileNodeId,
|
|
6354
|
-
type:
|
|
6441
|
+
type: import_types10.NodeType.FileNode,
|
|
6355
6442
|
service: canonicalService,
|
|
6356
6443
|
path: relPath,
|
|
6357
6444
|
...language ? { language } : {},
|
|
@@ -6360,14 +6447,14 @@ function ensureObservedFileNode(graph, serviceName, serviceNodeId, callSite) {
|
|
|
6360
6447
|
};
|
|
6361
6448
|
graph.addNode(fileNodeId, node);
|
|
6362
6449
|
}
|
|
6363
|
-
const containsId = makeObservedEdgeId(
|
|
6450
|
+
const containsId = makeObservedEdgeId(import_types10.EdgeType.CONTAINS, serviceNodeId, fileNodeId);
|
|
6364
6451
|
if (!graph.hasEdge(containsId)) {
|
|
6365
6452
|
const edge = {
|
|
6366
6453
|
id: containsId,
|
|
6367
6454
|
source: serviceNodeId,
|
|
6368
6455
|
target: fileNodeId,
|
|
6369
|
-
type:
|
|
6370
|
-
provenance:
|
|
6456
|
+
type: import_types10.EdgeType.CONTAINS,
|
|
6457
|
+
provenance: import_types10.Provenance.OBSERVED
|
|
6371
6458
|
};
|
|
6372
6459
|
graph.addEdgeWithKey(containsId, serviceNodeId, fileNodeId, edge);
|
|
6373
6460
|
}
|
|
@@ -6391,11 +6478,11 @@ function pickContainingSymbol(candidates, fn) {
|
|
|
6391
6478
|
return [...candidates].sort(bySpan)[0].id;
|
|
6392
6479
|
}
|
|
6393
6480
|
function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line) {
|
|
6394
|
-
const sid = (0,
|
|
6481
|
+
const sid = (0, import_types10.symbolId)(service, relPath, fn);
|
|
6395
6482
|
if (!graph.hasNode(sid)) {
|
|
6396
6483
|
const node = {
|
|
6397
6484
|
id: sid,
|
|
6398
|
-
type:
|
|
6485
|
+
type: import_types10.NodeType.SymbolNode,
|
|
6399
6486
|
kind: "function",
|
|
6400
6487
|
qualname: fn,
|
|
6401
6488
|
span: { startLine: line, endLine: line },
|
|
@@ -6405,14 +6492,14 @@ function ensureObservedSymbolNode(graph, fileNodeId, service, relPath, fn, line)
|
|
|
6405
6492
|
};
|
|
6406
6493
|
graph.addNode(sid, node);
|
|
6407
6494
|
}
|
|
6408
|
-
const containsId = makeObservedEdgeId(
|
|
6495
|
+
const containsId = makeObservedEdgeId(import_types10.EdgeType.CONTAINS, fileNodeId, sid);
|
|
6409
6496
|
if (!graph.hasEdge(containsId)) {
|
|
6410
6497
|
const edge = {
|
|
6411
6498
|
id: containsId,
|
|
6412
6499
|
source: fileNodeId,
|
|
6413
6500
|
target: sid,
|
|
6414
|
-
type:
|
|
6415
|
-
provenance:
|
|
6501
|
+
type: import_types10.EdgeType.CONTAINS,
|
|
6502
|
+
provenance: import_types10.Provenance.OBSERVED
|
|
6416
6503
|
};
|
|
6417
6504
|
graph.addEdgeWithKey(containsId, fileNodeId, sid, edge);
|
|
6418
6505
|
}
|
|
@@ -6424,9 +6511,9 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
|
|
|
6424
6511
|
let sawSymbol = false;
|
|
6425
6512
|
const candidates = [];
|
|
6426
6513
|
graph.forEachOutboundEdge(fileNodeId, (_edge, edgeAttrs, _source, target) => {
|
|
6427
|
-
if (edgeAttrs.type !==
|
|
6514
|
+
if (edgeAttrs.type !== import_types10.EdgeType.CONTAINS) return;
|
|
6428
6515
|
const t = graph.getNodeAttributes(target);
|
|
6429
|
-
if (t.type !==
|
|
6516
|
+
if (t.type !== import_types10.NodeType.SymbolNode) return;
|
|
6430
6517
|
sawSymbol = true;
|
|
6431
6518
|
if (line >= t.span.startLine && line <= t.span.endLine) {
|
|
6432
6519
|
candidates.push({ id: target, symbol: t });
|
|
@@ -6439,17 +6526,17 @@ function landObservedSymbol(graph, fileNodeId, service, relPath, callSite, mint
|
|
|
6439
6526
|
return fileNodeId;
|
|
6440
6527
|
}
|
|
6441
6528
|
function makeObservedEdgeId(type, source, target) {
|
|
6442
|
-
return (0,
|
|
6529
|
+
return (0, import_types10.observedEdgeId)(source, target, type);
|
|
6443
6530
|
}
|
|
6444
6531
|
function makeInferredEdgeId(type, source, target) {
|
|
6445
|
-
return (0,
|
|
6532
|
+
return (0, import_types10.inferredEdgeId)(source, target, type);
|
|
6446
6533
|
}
|
|
6447
6534
|
var INFERRED_CONFIDENCE = 0.6;
|
|
6448
6535
|
var STITCH_MAX_DEPTH = 2;
|
|
6449
6536
|
var STITCH_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6537
|
+
import_types10.EdgeType.CALLS,
|
|
6538
|
+
import_types10.EdgeType.CONNECTS_TO,
|
|
6539
|
+
import_types10.EdgeType.DEPENDS_ON
|
|
6453
6540
|
]);
|
|
6454
6541
|
var WIRE_SPAN_KIND_CLIENT = 3;
|
|
6455
6542
|
var WIRE_SPAN_KIND_PRODUCER = 4;
|
|
@@ -6465,11 +6552,11 @@ function spanServesGraphqlOperation(kind) {
|
|
|
6465
6552
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6466
6553
|
}
|
|
6467
6554
|
function ensureGraphqlOperationNode(graph, serviceName, operationType, operationName) {
|
|
6468
|
-
const id = (0,
|
|
6555
|
+
const id = (0, import_types10.graphqlOperationId)(serviceName, operationType, operationName);
|
|
6469
6556
|
if (graph.hasNode(id)) return id;
|
|
6470
6557
|
const node = {
|
|
6471
6558
|
id,
|
|
6472
|
-
type:
|
|
6559
|
+
type: import_types10.NodeType.GraphQLOperationNode,
|
|
6473
6560
|
name: operationName,
|
|
6474
6561
|
service: serviceName,
|
|
6475
6562
|
operationType: operationType.toLowerCase(),
|
|
@@ -6483,11 +6570,11 @@ function spanServesGrpcMethod(kind) {
|
|
|
6483
6570
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6484
6571
|
}
|
|
6485
6572
|
function ensureGrpcMethodNode(graph, rpcService, rpcMethod) {
|
|
6486
|
-
const id = (0,
|
|
6573
|
+
const id = (0, import_types10.grpcMethodId)(rpcService, rpcMethod);
|
|
6487
6574
|
if (graph.hasNode(id)) return id;
|
|
6488
6575
|
const node = {
|
|
6489
6576
|
id,
|
|
6490
|
-
type:
|
|
6577
|
+
type: import_types10.NodeType.GrpcMethodNode,
|
|
6491
6578
|
name: `${rpcService}/${rpcMethod}`,
|
|
6492
6579
|
rpcService,
|
|
6493
6580
|
rpcMethod,
|
|
@@ -6500,11 +6587,11 @@ function spanServesWebsocketChannel(kind) {
|
|
|
6500
6587
|
return kind !== WIRE_SPAN_KIND_CLIENT && kind !== WIRE_SPAN_KIND_PRODUCER && kind !== WIRE_SPAN_KIND_CONSUMER;
|
|
6501
6588
|
}
|
|
6502
6589
|
function ensureWebsocketChannelNode(graph, serviceName, channel) {
|
|
6503
|
-
const id = (0,
|
|
6590
|
+
const id = (0, import_types10.websocketChannelId)(serviceName, channel);
|
|
6504
6591
|
if (graph.hasNode(id)) return id;
|
|
6505
6592
|
const node = {
|
|
6506
6593
|
id,
|
|
6507
|
-
type:
|
|
6594
|
+
type: import_types10.NodeType.WebSocketChannelNode,
|
|
6508
6595
|
name: channel,
|
|
6509
6596
|
service: serviceName,
|
|
6510
6597
|
channel,
|
|
@@ -6517,11 +6604,11 @@ function messagingDestinationKind(system) {
|
|
|
6517
6604
|
return `${system}-topic`;
|
|
6518
6605
|
}
|
|
6519
6606
|
function ensureMessagingDestinationNode(graph, system, destination) {
|
|
6520
|
-
const id = (0,
|
|
6607
|
+
const id = (0, import_types10.infraId)(messagingDestinationKind(system), destination);
|
|
6521
6608
|
if (graph.hasNode(id)) return id;
|
|
6522
6609
|
const node = {
|
|
6523
6610
|
id,
|
|
6524
|
-
type:
|
|
6611
|
+
type: import_types10.NodeType.InfraNode,
|
|
6525
6612
|
name: destination,
|
|
6526
6613
|
provider: "self",
|
|
6527
6614
|
kind: messagingDestinationKind(system)
|
|
@@ -6565,9 +6652,9 @@ function lookupParentSpan(traceId, parentSpanId, now) {
|
|
|
6565
6652
|
};
|
|
6566
6653
|
}
|
|
6567
6654
|
function resolveServiceId(graph, host, env) {
|
|
6568
|
-
const envTagged = (0,
|
|
6655
|
+
const envTagged = (0, import_types10.serviceId)(host, env);
|
|
6569
6656
|
if (graph.hasNode(envTagged)) return envTagged;
|
|
6570
|
-
const envLess = (0,
|
|
6657
|
+
const envLess = (0, import_types10.serviceId)(host);
|
|
6571
6658
|
if (envLess !== envTagged && graph.hasNode(envLess)) return envLess;
|
|
6572
6659
|
let sameEnv = null;
|
|
6573
6660
|
let envLessMatch = null;
|
|
@@ -6575,7 +6662,7 @@ function resolveServiceId(graph, host, env) {
|
|
|
6575
6662
|
graph.forEachNode((id, attrs) => {
|
|
6576
6663
|
if (sameEnv) return;
|
|
6577
6664
|
const a = attrs;
|
|
6578
|
-
if (a.type !==
|
|
6665
|
+
if (a.type !== import_types10.NodeType.ServiceNode) return;
|
|
6579
6666
|
const matchesByName = a.name === host;
|
|
6580
6667
|
const matchesByAlias = a.aliases ? a.aliases.includes(host) : false;
|
|
6581
6668
|
if (!matchesByName && !matchesByAlias) return;
|
|
@@ -6590,14 +6677,14 @@ function resolveServiceId(graph, host, env) {
|
|
|
6590
6677
|
return sameEnv ?? envLessMatch ?? anyMatch;
|
|
6591
6678
|
}
|
|
6592
6679
|
function frontierIdFor(host) {
|
|
6593
|
-
return (0,
|
|
6680
|
+
return (0, import_types10.frontierId)(host);
|
|
6594
6681
|
}
|
|
6595
6682
|
function resolveFusedServiceId(graph, serviceName, env) {
|
|
6596
|
-
const id = (0,
|
|
6683
|
+
const id = (0, import_types10.serviceId)(serviceName, env);
|
|
6597
6684
|
if (graph.hasNode(id)) return id;
|
|
6598
6685
|
const wanted = serviceName.toLowerCase();
|
|
6599
6686
|
const extractedId = graph.findNode((_nid, attrs) => {
|
|
6600
|
-
if (attrs.type !==
|
|
6687
|
+
if (attrs.type !== import_types10.NodeType.ServiceNode) return false;
|
|
6601
6688
|
const svc = attrs;
|
|
6602
6689
|
if (svc.discoveredVia === "otel") return false;
|
|
6603
6690
|
return typeof svc.name === "string" && svc.name.toLowerCase() === wanted;
|
|
@@ -6609,7 +6696,7 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
6609
6696
|
if (graph.hasNode(resolved)) return resolved;
|
|
6610
6697
|
const node = {
|
|
6611
6698
|
id: resolved,
|
|
6612
|
-
type:
|
|
6699
|
+
type: import_types10.NodeType.ServiceNode,
|
|
6613
6700
|
name: serviceName,
|
|
6614
6701
|
language: "unknown",
|
|
6615
6702
|
discoveredVia: "otel",
|
|
@@ -6619,11 +6706,11 @@ function ensureServiceNode(graph, serviceName, env) {
|
|
|
6619
6706
|
return resolved;
|
|
6620
6707
|
}
|
|
6621
6708
|
function ensureInfraNode(graph, kind, name, provider) {
|
|
6622
|
-
const id = (0,
|
|
6709
|
+
const id = (0, import_types10.infraId)(kind, name);
|
|
6623
6710
|
if (graph.hasNode(id)) return id;
|
|
6624
6711
|
const node = {
|
|
6625
6712
|
id,
|
|
6626
|
-
type:
|
|
6713
|
+
type: import_types10.NodeType.InfraNode,
|
|
6627
6714
|
name,
|
|
6628
6715
|
provider,
|
|
6629
6716
|
kind
|
|
@@ -6635,7 +6722,7 @@ var COLUMN_BEARING_INFRA_KINDS = /* @__PURE__ */ new Set(["sql-table", "supabase
|
|
|
6635
6722
|
function mergeColumnsAt(graph, tableNodeId, columns, provenance2, confidence) {
|
|
6636
6723
|
if (!columns || columns.length === 0 || !graph.hasNode(tableNodeId)) return;
|
|
6637
6724
|
const node = graph.getNodeAttributes(tableNodeId);
|
|
6638
|
-
if (node.type !==
|
|
6725
|
+
if (node.type !== import_types10.NodeType.InfraNode || !node.kind || !COLUMN_BEARING_INFRA_KINDS.has(node.kind)) {
|
|
6639
6726
|
return;
|
|
6640
6727
|
}
|
|
6641
6728
|
graph.replaceNodeAttributes(tableNodeId, {
|
|
@@ -6644,7 +6731,7 @@ function mergeColumnsAt(graph, tableNodeId, columns, provenance2, confidence) {
|
|
|
6644
6731
|
});
|
|
6645
6732
|
}
|
|
6646
6733
|
function mergeObservedColumns(graph, tableNodeId, columns) {
|
|
6647
|
-
mergeColumnsAt(graph, tableNodeId, columns,
|
|
6734
|
+
mergeColumnsAt(graph, tableNodeId, columns, import_types10.Provenance.OBSERVED, OBSERVED_COLUMN_CONFIDENCE);
|
|
6648
6735
|
}
|
|
6649
6736
|
function mergeObservedDeployState(graph, serviceNodeId, state) {
|
|
6650
6737
|
if (!graph.hasNode(serviceNodeId)) return;
|
|
@@ -6655,11 +6742,11 @@ function mergeObservedDeployState(graph, serviceNodeId, state) {
|
|
|
6655
6742
|
graph.mergeNodeAttributes(serviceNodeId, attrs);
|
|
6656
6743
|
}
|
|
6657
6744
|
function ensureDatabaseNode(graph, host, engine) {
|
|
6658
|
-
const id = (0,
|
|
6745
|
+
const id = (0, import_types10.databaseId)(host);
|
|
6659
6746
|
if (graph.hasNode(id)) return id;
|
|
6660
6747
|
const node = {
|
|
6661
6748
|
id,
|
|
6662
|
-
type:
|
|
6749
|
+
type: import_types10.NodeType.DatabaseNode,
|
|
6663
6750
|
name: host,
|
|
6664
6751
|
engine,
|
|
6665
6752
|
engineVersion: "unknown",
|
|
@@ -6671,11 +6758,11 @@ function ensureDatabaseNode(graph, host, engine) {
|
|
|
6671
6758
|
return id;
|
|
6672
6759
|
}
|
|
6673
6760
|
function ensureLocalDatabaseNode(graph, serviceName, name, engine) {
|
|
6674
|
-
const id = (0,
|
|
6761
|
+
const id = (0, import_types10.localDatabaseId)(serviceName, name);
|
|
6675
6762
|
if (graph.hasNode(id)) return id;
|
|
6676
6763
|
const node = {
|
|
6677
6764
|
id,
|
|
6678
|
-
type:
|
|
6765
|
+
type: import_types10.NodeType.DatabaseNode,
|
|
6679
6766
|
name,
|
|
6680
6767
|
engine,
|
|
6681
6768
|
engineVersion: "unknown",
|
|
@@ -6690,17 +6777,17 @@ function findDeclaredDatabaseForService(graph, serviceNodeId, engine) {
|
|
|
6690
6777
|
const sources = [serviceNodeId];
|
|
6691
6778
|
for (const edgeId of graph.outboundEdges(serviceNodeId)) {
|
|
6692
6779
|
const e = graph.getEdgeAttributes(edgeId);
|
|
6693
|
-
if (e.type ===
|
|
6780
|
+
if (e.type === import_types10.EdgeType.CONTAINS) sources.push(e.target);
|
|
6694
6781
|
}
|
|
6695
6782
|
const matches = /* @__PURE__ */ new Set();
|
|
6696
6783
|
for (const src of sources) {
|
|
6697
6784
|
if (!graph.hasNode(src)) continue;
|
|
6698
6785
|
for (const edgeId of graph.outboundEdges(src)) {
|
|
6699
6786
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6700
|
-
if (edge.type !==
|
|
6787
|
+
if (edge.type !== import_types10.EdgeType.CONNECTS_TO || edge.provenance !== import_types10.Provenance.EXTRACTED) continue;
|
|
6701
6788
|
if (!graph.hasNode(edge.target)) continue;
|
|
6702
6789
|
const target = graph.getNodeAttributes(edge.target);
|
|
6703
|
-
if (target.type !==
|
|
6790
|
+
if (target.type !== import_types10.NodeType.DatabaseNode || target.engine !== engine) continue;
|
|
6704
6791
|
matches.add(edge.target);
|
|
6705
6792
|
}
|
|
6706
6793
|
}
|
|
@@ -6715,7 +6802,7 @@ function ensureFrontierNode(graph, host, ts) {
|
|
|
6715
6802
|
}
|
|
6716
6803
|
const node = {
|
|
6717
6804
|
id,
|
|
6718
|
-
type:
|
|
6805
|
+
type: import_types10.NodeType.FrontierNode,
|
|
6719
6806
|
name: host,
|
|
6720
6807
|
host,
|
|
6721
6808
|
firstObserved: ts,
|
|
@@ -6768,11 +6855,11 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
|
|
|
6768
6855
|
};
|
|
6769
6856
|
const updated = {
|
|
6770
6857
|
...existing,
|
|
6771
|
-
provenance:
|
|
6858
|
+
provenance: import_types10.Provenance.OBSERVED,
|
|
6772
6859
|
lastObserved: ts,
|
|
6773
6860
|
callCount: newSpanCount,
|
|
6774
6861
|
signal: newSignal,
|
|
6775
|
-
confidence: (0,
|
|
6862
|
+
confidence: (0, import_types10.confidenceForObservedSignal)(newSignal),
|
|
6776
6863
|
grain
|
|
6777
6864
|
// backfills legacy edges that predate ADR-142
|
|
6778
6865
|
};
|
|
@@ -6795,8 +6882,8 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
|
|
|
6795
6882
|
source,
|
|
6796
6883
|
target,
|
|
6797
6884
|
type,
|
|
6798
|
-
provenance:
|
|
6799
|
-
confidence: (0,
|
|
6885
|
+
provenance: import_types10.Provenance.OBSERVED,
|
|
6886
|
+
confidence: (0, import_types10.confidenceForObservedSignal)(signal),
|
|
6800
6887
|
lastObserved: ts,
|
|
6801
6888
|
callCount: 1,
|
|
6802
6889
|
signal,
|
|
@@ -6818,9 +6905,9 @@ function stitchTrace(graph, sourceServiceId, ts) {
|
|
|
6818
6905
|
const outbound = graph.outboundEdges(nodeId);
|
|
6819
6906
|
for (const edgeId of outbound) {
|
|
6820
6907
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
6821
|
-
if (edge.provenance !==
|
|
6908
|
+
if (edge.provenance !== import_types10.Provenance.EXTRACTED) continue;
|
|
6822
6909
|
if (!STITCH_EDGE_TYPES.has(edge.type)) continue;
|
|
6823
|
-
if (graph.hasEdge((0,
|
|
6910
|
+
if (graph.hasEdge((0, import_types10.observedEdgeId)(edge.source, edge.target, edge.type))) continue;
|
|
6824
6911
|
upsertInferredEdge(graph, edge.type, edge.source, edge.target, ts);
|
|
6825
6912
|
if (!visited.has(edge.target)) {
|
|
6826
6913
|
visited.add(edge.target);
|
|
@@ -6842,7 +6929,7 @@ function upsertInferredEdge(graph, type, source, target, ts) {
|
|
|
6842
6929
|
source,
|
|
6843
6930
|
target,
|
|
6844
6931
|
type,
|
|
6845
|
-
provenance:
|
|
6932
|
+
provenance: import_types10.Provenance.INFERRED,
|
|
6846
6933
|
confidence: INFERRED_CONFIDENCE,
|
|
6847
6934
|
lastObserved: ts
|
|
6848
6935
|
};
|
|
@@ -6856,7 +6943,7 @@ function emitIncidentEvent(project, ev) {
|
|
|
6856
6943
|
incidentId: ev.id,
|
|
6857
6944
|
affectedNode: ev.affectedNode,
|
|
6858
6945
|
service: ev.service,
|
|
6859
|
-
incidentKind: (0,
|
|
6946
|
+
incidentKind: (0, import_types10.incidentKindOf)(ev),
|
|
6860
6947
|
at: ev.timestamp
|
|
6861
6948
|
}
|
|
6862
6949
|
});
|
|
@@ -6885,7 +6972,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
|
6885
6972
|
const canonicalService = serviceNodeName(graph, span) ?? span.service;
|
|
6886
6973
|
const recovered = !trusted;
|
|
6887
6974
|
if (graph) {
|
|
6888
|
-
const fusedFileId = (0,
|
|
6975
|
+
const fusedFileId = (0, import_types10.fileId)(canonicalService, relPath);
|
|
6889
6976
|
if (graph.hasNode(fusedFileId)) {
|
|
6890
6977
|
const node = landObservedSymbol(
|
|
6891
6978
|
graph,
|
|
@@ -6905,7 +6992,7 @@ function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
|
6905
6992
|
}
|
|
6906
6993
|
if (recovered) return null;
|
|
6907
6994
|
}
|
|
6908
|
-
return { affectedNode: (0,
|
|
6995
|
+
return { affectedNode: (0, import_types10.fileId)(span.service, relPath) };
|
|
6909
6996
|
}
|
|
6910
6997
|
function serviceNodeName(graph, span) {
|
|
6911
6998
|
if (!graph) return void 0;
|
|
@@ -6922,7 +7009,7 @@ function stacktraceCallSite(span, serviceNode, scanPath) {
|
|
|
6922
7009
|
return { relPath, line: frame.line, ...frame.fn ? { fn: frame.fn } : {} };
|
|
6923
7010
|
}
|
|
6924
7011
|
function incidentLocus(span, graph, scanPath) {
|
|
6925
|
-
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0,
|
|
7012
|
+
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0, import_types10.serviceId)(span.service, span.env);
|
|
6926
7013
|
const serviceNode = graph && graph.hasNode(sid) ? graph.getNodeAttributes(sid) : void 0;
|
|
6927
7014
|
const callSite = callSiteFromSpan(span, serviceNode, scanPath);
|
|
6928
7015
|
if (callSite) {
|
|
@@ -7113,7 +7200,7 @@ function findRouteNodeByHttpRoute(graph, serviceName, method, httpRoute) {
|
|
|
7113
7200
|
graph.forEachNode((id, attrs) => {
|
|
7114
7201
|
if (found) return;
|
|
7115
7202
|
const a = attrs;
|
|
7116
|
-
if (a.type !==
|
|
7203
|
+
if (a.type !== import_types10.NodeType.RouteNode || a.service !== serviceName) return;
|
|
7117
7204
|
if (m && a.method !== "ALL" && a.method !== m) return;
|
|
7118
7205
|
if (normalizePathTemplate(a.pathTemplate) === target) found = id;
|
|
7119
7206
|
});
|
|
@@ -7146,7 +7233,7 @@ async function handleSpan(ctx, span) {
|
|
|
7146
7233
|
let targetId;
|
|
7147
7234
|
if (host) {
|
|
7148
7235
|
ensureDatabaseNode(ctx.graph, host, span.dbSystem);
|
|
7149
|
-
targetId = (0,
|
|
7236
|
+
targetId = (0, import_types10.databaseId)(host);
|
|
7150
7237
|
} else {
|
|
7151
7238
|
const declared = findDeclaredDatabaseForService(ctx.graph, sourceId, span.dbSystem);
|
|
7152
7239
|
if (declared) {
|
|
@@ -7163,7 +7250,7 @@ async function handleSpan(ctx, span) {
|
|
|
7163
7250
|
}
|
|
7164
7251
|
const result = upsertObservedEdge(
|
|
7165
7252
|
ctx.graph,
|
|
7166
|
-
|
|
7253
|
+
import_types10.EdgeType.CONNECTS_TO,
|
|
7167
7254
|
observedSource(),
|
|
7168
7255
|
targetId,
|
|
7169
7256
|
ts,
|
|
@@ -7177,7 +7264,7 @@ async function handleSpan(ctx, span) {
|
|
|
7177
7264
|
const collectionId = ensureInfraNode(ctx.graph, "mongodb-collection", span.dbCollection, "self");
|
|
7178
7265
|
upsertObservedEdge(
|
|
7179
7266
|
ctx.graph,
|
|
7180
|
-
|
|
7267
|
+
import_types10.EdgeType.CALLS,
|
|
7181
7268
|
observedSource(),
|
|
7182
7269
|
collectionId,
|
|
7183
7270
|
ts,
|
|
@@ -7191,7 +7278,7 @@ async function handleSpan(ctx, span) {
|
|
|
7191
7278
|
const tableId = ensureInfraNode(ctx.graph, "sql-table", span.dbTable, "self");
|
|
7192
7279
|
upsertObservedEdge(
|
|
7193
7280
|
ctx.graph,
|
|
7194
|
-
|
|
7281
|
+
import_types10.EdgeType.CALLS,
|
|
7195
7282
|
observedSource(),
|
|
7196
7283
|
tableId,
|
|
7197
7284
|
ts,
|
|
@@ -7209,7 +7296,7 @@ async function handleSpan(ctx, span) {
|
|
|
7209
7296
|
span.messagingSystem,
|
|
7210
7297
|
span.messagingDestination
|
|
7211
7298
|
);
|
|
7212
|
-
const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ?
|
|
7299
|
+
const edgeType = span.kind === WIRE_SPAN_KIND_CONSUMER ? import_types10.EdgeType.CONSUMES_FROM : import_types10.EdgeType.PUBLISHES_TO;
|
|
7213
7300
|
const result = upsertObservedEdge(
|
|
7214
7301
|
ctx.graph,
|
|
7215
7302
|
edgeType,
|
|
@@ -7231,7 +7318,7 @@ async function handleSpan(ctx, span) {
|
|
|
7231
7318
|
);
|
|
7232
7319
|
const result = upsertObservedEdge(
|
|
7233
7320
|
ctx.graph,
|
|
7234
|
-
|
|
7321
|
+
import_types10.EdgeType.CONTAINS,
|
|
7235
7322
|
observedSource(),
|
|
7236
7323
|
targetId,
|
|
7237
7324
|
ts,
|
|
@@ -7245,7 +7332,7 @@ async function handleSpan(ctx, span) {
|
|
|
7245
7332
|
const targetId = ensureGrpcMethodNode(ctx.graph, span.rpcService, span.rpcMethod);
|
|
7246
7333
|
const result = upsertObservedEdge(
|
|
7247
7334
|
ctx.graph,
|
|
7248
|
-
|
|
7335
|
+
import_types10.EdgeType.CONTAINS,
|
|
7249
7336
|
observedSource(),
|
|
7250
7337
|
targetId,
|
|
7251
7338
|
ts,
|
|
@@ -7263,7 +7350,7 @@ async function handleSpan(ctx, span) {
|
|
|
7263
7350
|
);
|
|
7264
7351
|
const result = upsertObservedEdge(
|
|
7265
7352
|
ctx.graph,
|
|
7266
|
-
|
|
7353
|
+
import_types10.EdgeType.CONNECTS_TO,
|
|
7267
7354
|
observedSource(),
|
|
7268
7355
|
targetId,
|
|
7269
7356
|
ts,
|
|
@@ -7281,7 +7368,7 @@ async function handleSpan(ctx, span) {
|
|
|
7281
7368
|
if (targetId && targetId !== sourceId) {
|
|
7282
7369
|
upsertObservedEdge(
|
|
7283
7370
|
ctx.graph,
|
|
7284
|
-
|
|
7371
|
+
import_types10.EdgeType.CALLS,
|
|
7285
7372
|
observedSource(),
|
|
7286
7373
|
targetId,
|
|
7287
7374
|
ts,
|
|
@@ -7296,7 +7383,7 @@ async function handleSpan(ctx, span) {
|
|
|
7296
7383
|
const frontierNodeId = ensureFrontierNode(ctx.graph, host, ts);
|
|
7297
7384
|
upsertObservedEdge(
|
|
7298
7385
|
ctx.graph,
|
|
7299
|
-
|
|
7386
|
+
import_types10.EdgeType.CALLS,
|
|
7300
7387
|
observedSource(),
|
|
7301
7388
|
frontierNodeId,
|
|
7302
7389
|
ts,
|
|
@@ -7324,7 +7411,7 @@ async function handleSpan(ctx, span) {
|
|
|
7324
7411
|
} : void 0;
|
|
7325
7412
|
upsertObservedEdge(
|
|
7326
7413
|
ctx.graph,
|
|
7327
|
-
|
|
7414
|
+
import_types10.EdgeType.CALLS,
|
|
7328
7415
|
fallbackSource,
|
|
7329
7416
|
sourceId,
|
|
7330
7417
|
ts,
|
|
@@ -7346,7 +7433,7 @@ async function handleSpan(ctx, span) {
|
|
|
7346
7433
|
);
|
|
7347
7434
|
if (routeNodeId) {
|
|
7348
7435
|
const routeSvc = ctx.graph.getNodeAttributes(routeNodeId).service;
|
|
7349
|
-
upsertObservedEdge(ctx.graph,
|
|
7436
|
+
upsertObservedEdge(ctx.graph, import_types10.EdgeType.CONTAINS, (0, import_types10.serviceId)(routeSvc), routeNodeId, ts, isError, void 0, durationMs, errorDetail);
|
|
7350
7437
|
}
|
|
7351
7438
|
}
|
|
7352
7439
|
if (span.statusCode === 2) {
|
|
@@ -7376,7 +7463,7 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7376
7463
|
const aliasIndex = /* @__PURE__ */ new Map();
|
|
7377
7464
|
graph.forEachNode((id, attrs) => {
|
|
7378
7465
|
const a = attrs;
|
|
7379
|
-
if (a.type !==
|
|
7466
|
+
if (a.type !== import_types10.NodeType.ServiceNode) return;
|
|
7380
7467
|
aliasIndex.set(a.name, id);
|
|
7381
7468
|
if (a.aliases) {
|
|
7382
7469
|
for (const alias of a.aliases) aliasIndex.set(alias, id);
|
|
@@ -7385,7 +7472,7 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7385
7472
|
const toPromote = [];
|
|
7386
7473
|
graph.forEachNode((id, attrs) => {
|
|
7387
7474
|
const a = attrs;
|
|
7388
|
-
if (a.type !==
|
|
7475
|
+
if (a.type !== import_types10.NodeType.FrontierNode) return;
|
|
7389
7476
|
const target = aliasIndex.get(a.host);
|
|
7390
7477
|
if (!target) return;
|
|
7391
7478
|
if (target === id) return;
|
|
@@ -7407,15 +7494,15 @@ function promoteFrontierNodes(graph, opts = {}) {
|
|
|
7407
7494
|
}
|
|
7408
7495
|
function stageFrontierEdge(graph, source, target, type) {
|
|
7409
7496
|
if (!graph.hasNode(source) || !graph.hasNode(target)) return false;
|
|
7410
|
-
if (graph.hasEdge((0,
|
|
7411
|
-
const key = (0,
|
|
7497
|
+
if (graph.hasEdge((0, import_types10.observedEdgeId)(source, target, type))) return false;
|
|
7498
|
+
const key = (0, import_types10.frontierEdgeId)(source, target, type);
|
|
7412
7499
|
if (graph.hasEdge(key)) return false;
|
|
7413
7500
|
graph.addEdgeWithKey(key, source, target, {
|
|
7414
7501
|
id: key,
|
|
7415
7502
|
source,
|
|
7416
7503
|
target,
|
|
7417
7504
|
type,
|
|
7418
|
-
provenance:
|
|
7505
|
+
provenance: import_types10.Provenance.FRONTIER
|
|
7419
7506
|
});
|
|
7420
7507
|
return true;
|
|
7421
7508
|
}
|
|
@@ -7423,8 +7510,8 @@ function promoteFrontierEdges(graph) {
|
|
|
7423
7510
|
const graduated = [];
|
|
7424
7511
|
graph.forEachEdge((edgeId, attrs) => {
|
|
7425
7512
|
const e = attrs;
|
|
7426
|
-
if (e.provenance !==
|
|
7427
|
-
if (graph.hasEdge((0,
|
|
7513
|
+
if (e.provenance !== import_types10.Provenance.FRONTIER) return;
|
|
7514
|
+
if (graph.hasEdge((0, import_types10.observedEdgeId)(e.source, e.target, e.type))) {
|
|
7428
7515
|
graduated.push(edgeId);
|
|
7429
7516
|
}
|
|
7430
7517
|
});
|
|
@@ -7445,7 +7532,7 @@ function rewireFrontierEdges(graph, frontierId2, serviceId17) {
|
|
|
7445
7532
|
}
|
|
7446
7533
|
function rebuildEdge(graph, edge, newSource, newTarget, oldEdgeId) {
|
|
7447
7534
|
graph.dropEdge(oldEdgeId);
|
|
7448
|
-
const newId = edge.provenance ===
|
|
7535
|
+
const newId = edge.provenance === import_types10.Provenance.OBSERVED ? (0, import_types10.observedEdgeId)(newSource, newTarget, edge.type) : edge.provenance === import_types10.Provenance.INFERRED ? (0, import_types10.inferredEdgeId)(newSource, newTarget, edge.type) : (0, import_types10.extractedEdgeId)(newSource, newTarget, edge.type);
|
|
7449
7536
|
if (graph.hasEdge(newId)) {
|
|
7450
7537
|
const existing = graph.getEdgeAttributes(newId);
|
|
7451
7538
|
const merged = {
|
|
@@ -7479,12 +7566,12 @@ async function markStaleEdges(graph, options = {}) {
|
|
|
7479
7566
|
const project = options.project ?? DEFAULT_PROJECT;
|
|
7480
7567
|
graph.forEachEdge((id, attrs) => {
|
|
7481
7568
|
const e = attrs;
|
|
7482
|
-
if (e.provenance !==
|
|
7569
|
+
if (e.provenance !== import_types10.Provenance.OBSERVED) return;
|
|
7483
7570
|
if (!e.lastObserved) return;
|
|
7484
7571
|
const threshold = thresholdForEdgeType(e.type, thresholds);
|
|
7485
7572
|
const age = now - new Date(e.lastObserved).getTime();
|
|
7486
7573
|
if (age > threshold) {
|
|
7487
|
-
const updated = { ...e, provenance:
|
|
7574
|
+
const updated = { ...e, provenance: import_types10.Provenance.STALE, confidence: 0.3 };
|
|
7488
7575
|
graph.replaceEdgeAttributes(id, updated);
|
|
7489
7576
|
events.push({
|
|
7490
7577
|
edgeId: id,
|
|
@@ -7501,8 +7588,8 @@ async function markStaleEdges(graph, options = {}) {
|
|
|
7501
7588
|
project,
|
|
7502
7589
|
payload: {
|
|
7503
7590
|
edgeId: id,
|
|
7504
|
-
from:
|
|
7505
|
-
to:
|
|
7591
|
+
from: import_types10.Provenance.OBSERVED,
|
|
7592
|
+
to: import_types10.Provenance.STALE
|
|
7506
7593
|
}
|
|
7507
7594
|
});
|
|
7508
7595
|
}
|
|
@@ -7650,6 +7737,7 @@ function describeZodIssues(error2) {
|
|
|
7650
7737
|
return error2.issues.map((issue) => issue.path.length > 0 ? `${issue.path.join(".")}: ${issue.message}` : issue.message).join("; ");
|
|
7651
7738
|
}
|
|
7652
7739
|
function mergeSnapshot(graph, snapshot) {
|
|
7740
|
+
invalidateSourceBaseline(graph);
|
|
7653
7741
|
const exported = snapshot.graph;
|
|
7654
7742
|
const incomingNodes = Array.isArray(exported.nodes) ? exported.nodes : [];
|
|
7655
7743
|
const incomingEdges = Array.isArray(exported.edges) ? exported.edges : [];
|
|
@@ -7658,7 +7746,7 @@ function mergeSnapshot(graph, snapshot) {
|
|
|
7658
7746
|
const validEdges = [];
|
|
7659
7747
|
for (const node of incomingNodes) {
|
|
7660
7748
|
if (node.attributes === void 0) continue;
|
|
7661
|
-
const parsed =
|
|
7749
|
+
const parsed = import_types10.GraphNodeSchema.safeParse(node.attributes);
|
|
7662
7750
|
if (!parsed.success) {
|
|
7663
7751
|
issues.push(`node "${node.key}": ${describeZodIssues(parsed.error)}`);
|
|
7664
7752
|
continue;
|
|
@@ -7667,7 +7755,7 @@ function mergeSnapshot(graph, snapshot) {
|
|
|
7667
7755
|
}
|
|
7668
7756
|
for (const edge of incomingEdges) {
|
|
7669
7757
|
if (edge.attributes === void 0) continue;
|
|
7670
|
-
const parsed =
|
|
7758
|
+
const parsed = import_types10.GraphEdgeSchema.safeParse(edge.attributes);
|
|
7671
7759
|
if (!parsed.success) {
|
|
7672
7760
|
const label = edge.key ?? `${edge.source}->${edge.target}`;
|
|
7673
7761
|
issues.push(`edge "${label}": ${describeZodIssues(parsed.error)}`);
|
|
@@ -7701,7 +7789,7 @@ var import_node_fs21 = require("fs");
|
|
|
7701
7789
|
var import_node_path23 = __toESM(require("path"), 1);
|
|
7702
7790
|
var import_ignore2 = __toESM(require("ignore"), 1);
|
|
7703
7791
|
var import_minimatch2 = require("minimatch");
|
|
7704
|
-
var
|
|
7792
|
+
var import_types20 = require("@neat.is/types");
|
|
7705
7793
|
|
|
7706
7794
|
// src/extract/python.ts
|
|
7707
7795
|
init_cjs_shims();
|
|
@@ -7774,7 +7862,7 @@ function pythonToPackage(service) {
|
|
|
7774
7862
|
init_cjs_shims();
|
|
7775
7863
|
var import_node_fs12 = require("fs");
|
|
7776
7864
|
var import_node_path13 = __toESM(require("path"), 1);
|
|
7777
|
-
var
|
|
7865
|
+
var import_types11 = require("@neat.is/types");
|
|
7778
7866
|
function parseGoMod(source) {
|
|
7779
7867
|
const module2 = source.match(/^\s*module\s+(\S+)\s*$/m)?.[1];
|
|
7780
7868
|
if (!module2) return null;
|
|
@@ -7810,8 +7898,8 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7810
7898
|
const pkg = { name, dependencies: mod.dependencies };
|
|
7811
7899
|
const framework = goFramework(mod.dependencies);
|
|
7812
7900
|
const node = {
|
|
7813
|
-
id: (0,
|
|
7814
|
-
type:
|
|
7901
|
+
id: (0, import_types11.serviceId)(name),
|
|
7902
|
+
type: import_types11.NodeType.ServiceNode,
|
|
7815
7903
|
name,
|
|
7816
7904
|
language: "go",
|
|
7817
7905
|
dependencies: mod.dependencies,
|
|
@@ -7825,7 +7913,7 @@ async function discoverGoService(scanPath, dir) {
|
|
|
7825
7913
|
init_cjs_shims();
|
|
7826
7914
|
var import_node_fs13 = require("fs");
|
|
7827
7915
|
var import_node_path14 = __toESM(require("path"), 1);
|
|
7828
|
-
var
|
|
7916
|
+
var import_types12 = require("@neat.is/types");
|
|
7829
7917
|
function parseGemfile(source) {
|
|
7830
7918
|
const dependencies = {};
|
|
7831
7919
|
for (const raw of source.split(/\r?\n/)) {
|
|
@@ -7849,8 +7937,8 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7849
7937
|
const name = import_node_path14.default.basename(dir);
|
|
7850
7938
|
const pkg = { name, dependencies: gemfile.dependencies };
|
|
7851
7939
|
const node = {
|
|
7852
|
-
id: (0,
|
|
7853
|
-
type:
|
|
7940
|
+
id: (0, import_types12.serviceId)(name),
|
|
7941
|
+
type: import_types12.NodeType.ServiceNode,
|
|
7854
7942
|
name,
|
|
7855
7943
|
language: "ruby",
|
|
7856
7944
|
dependencies: gemfile.dependencies,
|
|
@@ -7863,7 +7951,7 @@ async function discoverRubyService(scanPath, dir) {
|
|
|
7863
7951
|
// src/extract/php.ts
|
|
7864
7952
|
init_cjs_shims();
|
|
7865
7953
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
7866
|
-
var
|
|
7954
|
+
var import_types13 = require("@neat.is/types");
|
|
7867
7955
|
function parseComposerJson(composer) {
|
|
7868
7956
|
return {
|
|
7869
7957
|
dependencies: {
|
|
@@ -7883,8 +7971,8 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7883
7971
|
const name = import_node_path15.default.basename(dir);
|
|
7884
7972
|
const pkg = { name, dependencies };
|
|
7885
7973
|
const node = {
|
|
7886
|
-
id: (0,
|
|
7887
|
-
type:
|
|
7974
|
+
id: (0, import_types13.serviceId)(name),
|
|
7975
|
+
type: import_types13.NodeType.ServiceNode,
|
|
7888
7976
|
name,
|
|
7889
7977
|
language: "php",
|
|
7890
7978
|
dependencies,
|
|
@@ -7898,7 +7986,7 @@ async function discoverPhpService(scanPath, dir) {
|
|
|
7898
7986
|
init_cjs_shims();
|
|
7899
7987
|
var import_node_fs14 = require("fs");
|
|
7900
7988
|
var import_node_path16 = __toESM(require("path"), 1);
|
|
7901
|
-
var
|
|
7989
|
+
var import_types14 = require("@neat.is/types");
|
|
7902
7990
|
var CSHARP_PROJECT_EXTS = /* @__PURE__ */ new Set([".csproj", ".sln"]);
|
|
7903
7991
|
async function projectFiles(dir) {
|
|
7904
7992
|
const entries = await import_node_fs14.promises.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
@@ -7945,8 +8033,8 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7945
8033
|
}
|
|
7946
8034
|
const pkg = { name, dependencies };
|
|
7947
8035
|
const node = {
|
|
7948
|
-
id: (0,
|
|
7949
|
-
type:
|
|
8036
|
+
id: (0, import_types14.serviceId)(name),
|
|
8037
|
+
type: import_types14.NodeType.ServiceNode,
|
|
7950
8038
|
name,
|
|
7951
8039
|
language: "csharp",
|
|
7952
8040
|
dependencies,
|
|
@@ -7961,7 +8049,7 @@ async function discoverCsharpService(scanPath, dir) {
|
|
|
7961
8049
|
init_cjs_shims();
|
|
7962
8050
|
var import_node_fs15 = require("fs");
|
|
7963
8051
|
var import_node_path17 = __toESM(require("path"), 1);
|
|
7964
|
-
var
|
|
8052
|
+
var import_types15 = require("@neat.is/types");
|
|
7965
8053
|
var JAVA_MANIFESTS = ["pom.xml", "build.gradle", "build.gradle.kts"];
|
|
7966
8054
|
async function hasJavaManifest(dir) {
|
|
7967
8055
|
for (const manifest of JAVA_MANIFESTS) {
|
|
@@ -8016,8 +8104,8 @@ async function discoverJavaService(scanPath, dir) {
|
|
|
8016
8104
|
const dependencies = manifest.dependencies;
|
|
8017
8105
|
const pkg = { name, dependencies };
|
|
8018
8106
|
const node = {
|
|
8019
|
-
id: (0,
|
|
8020
|
-
type:
|
|
8107
|
+
id: (0, import_types15.serviceId)(name),
|
|
8108
|
+
type: import_types15.NodeType.ServiceNode,
|
|
8021
8109
|
name,
|
|
8022
8110
|
language: "java",
|
|
8023
8111
|
dependencies,
|
|
@@ -8030,7 +8118,7 @@ async function discoverJavaService(scanPath, dir) {
|
|
|
8030
8118
|
init_cjs_shims();
|
|
8031
8119
|
var import_node_fs16 = require("fs");
|
|
8032
8120
|
var import_node_path18 = __toESM(require("path"), 1);
|
|
8033
|
-
var
|
|
8121
|
+
var import_types16 = require("@neat.is/types");
|
|
8034
8122
|
var KOTLIN_SOURCE_EXT = ".kt";
|
|
8035
8123
|
var JAVA_SOURCE_EXT = ".java";
|
|
8036
8124
|
var SOURCE_PROBE_MAX_DEPTH = 8;
|
|
@@ -8081,8 +8169,8 @@ async function discoverKotlinService(scanPath, dir) {
|
|
|
8081
8169
|
const dependencies = manifest.dependencies;
|
|
8082
8170
|
const pkg = { name, dependencies };
|
|
8083
8171
|
const node = {
|
|
8084
|
-
id: (0,
|
|
8085
|
-
type:
|
|
8172
|
+
id: (0, import_types16.serviceId)(name),
|
|
8173
|
+
type: import_types16.NodeType.ServiceNode,
|
|
8086
8174
|
name,
|
|
8087
8175
|
language: "kotlin",
|
|
8088
8176
|
dependencies,
|
|
@@ -8096,7 +8184,7 @@ init_cjs_shims();
|
|
|
8096
8184
|
var import_node_fs17 = require("fs");
|
|
8097
8185
|
var import_node_path19 = __toESM(require("path"), 1);
|
|
8098
8186
|
var import_smol_toml2 = require("smol-toml");
|
|
8099
|
-
var
|
|
8187
|
+
var import_types17 = require("@neat.is/types");
|
|
8100
8188
|
var CARGO_MANIFEST = "Cargo.toml";
|
|
8101
8189
|
async function hasRustManifest(dir) {
|
|
8102
8190
|
return exists(import_node_path19.default.join(dir, CARGO_MANIFEST));
|
|
@@ -8131,8 +8219,8 @@ async function discoverRustService(scanPath, dir) {
|
|
|
8131
8219
|
const dependencies = manifest.dependencies;
|
|
8132
8220
|
const pkg = { name, dependencies };
|
|
8133
8221
|
const node = {
|
|
8134
|
-
id: (0,
|
|
8135
|
-
type:
|
|
8222
|
+
id: (0, import_types17.serviceId)(name),
|
|
8223
|
+
type: import_types17.NodeType.ServiceNode,
|
|
8136
8224
|
name,
|
|
8137
8225
|
language: "rust",
|
|
8138
8226
|
dependencies,
|
|
@@ -8145,7 +8233,7 @@ async function discoverRustService(scanPath, dir) {
|
|
|
8145
8233
|
init_cjs_shims();
|
|
8146
8234
|
var import_node_fs18 = require("fs");
|
|
8147
8235
|
var import_node_path20 = __toESM(require("path"), 1);
|
|
8148
|
-
var
|
|
8236
|
+
var import_types18 = require("@neat.is/types");
|
|
8149
8237
|
var CMAKE_MANIFEST = "CMakeLists.txt";
|
|
8150
8238
|
async function hasCppManifest(dir) {
|
|
8151
8239
|
return exists(import_node_path20.default.join(dir, CMAKE_MANIFEST));
|
|
@@ -8163,8 +8251,8 @@ async function discoverCppService(scanPath, dir) {
|
|
|
8163
8251
|
const dependencies = {};
|
|
8164
8252
|
const pkg = { name, dependencies };
|
|
8165
8253
|
const node = {
|
|
8166
|
-
id: (0,
|
|
8167
|
-
type:
|
|
8254
|
+
id: (0, import_types18.serviceId)(name),
|
|
8255
|
+
type: import_types18.NodeType.ServiceNode,
|
|
8168
8256
|
name,
|
|
8169
8257
|
language: "cpp",
|
|
8170
8258
|
dependencies,
|
|
@@ -8177,7 +8265,7 @@ async function discoverCppService(scanPath, dir) {
|
|
|
8177
8265
|
init_cjs_shims();
|
|
8178
8266
|
var import_node_fs19 = require("fs");
|
|
8179
8267
|
var import_node_path21 = __toESM(require("path"), 1);
|
|
8180
|
-
var
|
|
8268
|
+
var import_types19 = require("@neat.is/types");
|
|
8181
8269
|
function languageForSourceExt(ext) {
|
|
8182
8270
|
switch (ext) {
|
|
8183
8271
|
case ".py":
|
|
@@ -8263,8 +8351,8 @@ async function discoverDockerfileService(scanPath, dir) {
|
|
|
8263
8351
|
const name = import_node_path21.default.basename(dir);
|
|
8264
8352
|
const pkg = { name, dependencies: {} };
|
|
8265
8353
|
const node = {
|
|
8266
|
-
id: (0,
|
|
8267
|
-
type:
|
|
8354
|
+
id: (0, import_types19.serviceId)(name),
|
|
8355
|
+
type: import_types19.NodeType.ServiceNode,
|
|
8268
8356
|
name,
|
|
8269
8357
|
language,
|
|
8270
8358
|
dependencies: {},
|
|
@@ -8458,8 +8546,8 @@ async function discoverNodeService(scanPath, dir) {
|
|
|
8458
8546
|
const framework = detectJsFramework(pkg);
|
|
8459
8547
|
const language = await detectJsServiceLanguage(dir, pkg);
|
|
8460
8548
|
const node = {
|
|
8461
|
-
id: (0,
|
|
8462
|
-
type:
|
|
8549
|
+
id: (0, import_types20.serviceId)(pkg.name),
|
|
8550
|
+
type: import_types20.NodeType.ServiceNode,
|
|
8463
8551
|
name: pkg.name,
|
|
8464
8552
|
language,
|
|
8465
8553
|
version: pkg.version,
|
|
@@ -8475,8 +8563,8 @@ async function discoverPyService(scanPath, dir) {
|
|
|
8475
8563
|
if (!py) return null;
|
|
8476
8564
|
const pkg = pythonToPackage(py);
|
|
8477
8565
|
const node = {
|
|
8478
|
-
id: (0,
|
|
8479
|
-
type:
|
|
8566
|
+
id: (0, import_types20.serviceId)(py.name),
|
|
8567
|
+
type: import_types20.NodeType.ServiceNode,
|
|
8480
8568
|
name: py.name,
|
|
8481
8569
|
language: "python",
|
|
8482
8570
|
version: py.version,
|
|
@@ -8595,7 +8683,7 @@ init_cjs_shims();
|
|
|
8595
8683
|
var import_node_path24 = __toESM(require("path"), 1);
|
|
8596
8684
|
var import_node_fs22 = require("fs");
|
|
8597
8685
|
var import_yaml2 = require("yaml");
|
|
8598
|
-
var
|
|
8686
|
+
var import_types21 = require("@neat.is/types");
|
|
8599
8687
|
var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
8600
8688
|
"Service",
|
|
8601
8689
|
"Deployment",
|
|
@@ -8605,7 +8693,7 @@ var K8S_KINDS_WITH_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
|
8605
8693
|
function addAliases(graph, serviceId17, candidates) {
|
|
8606
8694
|
if (!graph.hasNode(serviceId17)) return;
|
|
8607
8695
|
const node = graph.getNodeAttributes(serviceId17);
|
|
8608
|
-
if (node.type !==
|
|
8696
|
+
if (node.type !== import_types21.NodeType.ServiceNode) return;
|
|
8609
8697
|
const set = new Set(node.aliases ?? []);
|
|
8610
8698
|
for (const c of candidates) {
|
|
8611
8699
|
if (!c) continue;
|
|
@@ -8795,7 +8883,7 @@ var import_tree_sitter_java = __toESM(require("tree-sitter-java"), 1);
|
|
|
8795
8883
|
var import_tree_sitter_kotlin = __toESM(require("tree-sitter-kotlin"), 1);
|
|
8796
8884
|
var import_tree_sitter_rust2 = __toESM(require("tree-sitter-rust"), 1);
|
|
8797
8885
|
var import_tree_sitter_cpp = __toESM(require("tree-sitter-cpp"), 1);
|
|
8798
|
-
var
|
|
8886
|
+
var import_types22 = require("@neat.is/types");
|
|
8799
8887
|
var PARSE_CHUNK3 = 16384;
|
|
8800
8888
|
var GRAMMAR_BY_EXT = {
|
|
8801
8889
|
".ts": import_tree_sitter_typescript.default.typescript,
|
|
@@ -8848,7 +8936,9 @@ function collectSymbolDefs(root) {
|
|
|
8848
8936
|
kind,
|
|
8849
8937
|
qualname,
|
|
8850
8938
|
startLine: node.startPosition.row + 1,
|
|
8851
|
-
endLine: node.endPosition.row + 1
|
|
8939
|
+
endLine: node.endPosition.row + 1,
|
|
8940
|
+
startIndex: node.startIndex,
|
|
8941
|
+
endIndex: node.endIndex
|
|
8852
8942
|
});
|
|
8853
8943
|
};
|
|
8854
8944
|
const visit = (node, classCtx) => {
|
|
@@ -8907,7 +8997,9 @@ function collectPythonSymbolDefs(root) {
|
|
|
8907
8997
|
kind,
|
|
8908
8998
|
qualname,
|
|
8909
8999
|
startLine: node.startPosition.row + 1,
|
|
8910
|
-
endLine: node.endPosition.row + 1
|
|
9000
|
+
endLine: node.endPosition.row + 1,
|
|
9001
|
+
startIndex: node.startIndex,
|
|
9002
|
+
endIndex: node.endIndex
|
|
8911
9003
|
});
|
|
8912
9004
|
};
|
|
8913
9005
|
const visit = (node, classCtx) => {
|
|
@@ -8980,7 +9072,9 @@ function collectGoSymbolDefs(root) {
|
|
|
8980
9072
|
kind,
|
|
8981
9073
|
qualname,
|
|
8982
9074
|
startLine: node.startPosition.row + 1,
|
|
8983
|
-
endLine: node.endPosition.row + 1
|
|
9075
|
+
endLine: node.endPosition.row + 1,
|
|
9076
|
+
startIndex: node.startIndex,
|
|
9077
|
+
endIndex: node.endIndex
|
|
8984
9078
|
});
|
|
8985
9079
|
};
|
|
8986
9080
|
const visit = (node) => {
|
|
@@ -9014,7 +9108,9 @@ function collectRubySymbolDefs(root) {
|
|
|
9014
9108
|
kind,
|
|
9015
9109
|
qualname,
|
|
9016
9110
|
startLine: node.startPosition.row + 1,
|
|
9017
|
-
endLine: node.endPosition.row + 1
|
|
9111
|
+
endLine: node.endPosition.row + 1,
|
|
9112
|
+
startIndex: node.startIndex,
|
|
9113
|
+
endIndex: node.endIndex
|
|
9018
9114
|
});
|
|
9019
9115
|
};
|
|
9020
9116
|
const nameText = (node) => node.childForFieldName("name")?.text.replace(/::/g, ".");
|
|
@@ -9065,7 +9161,9 @@ function collectPhpSymbolDefs(root) {
|
|
|
9065
9161
|
kind,
|
|
9066
9162
|
qualname,
|
|
9067
9163
|
startLine: node.startPosition.row + 1,
|
|
9068
|
-
endLine: node.endPosition.row + 1
|
|
9164
|
+
endLine: node.endPosition.row + 1,
|
|
9165
|
+
startIndex: node.startIndex,
|
|
9166
|
+
endIndex: node.endIndex
|
|
9069
9167
|
});
|
|
9070
9168
|
};
|
|
9071
9169
|
const dot = (s) => s.replace(/\\/g, ".").replace(/::/g, ".").replace(/^\.+/, "");
|
|
@@ -9131,7 +9229,9 @@ function collectCsharpSymbolDefs(root) {
|
|
|
9131
9229
|
kind,
|
|
9132
9230
|
qualname,
|
|
9133
9231
|
startLine: node.startPosition.row + 1,
|
|
9134
|
-
endLine: node.endPosition.row + 1
|
|
9232
|
+
endLine: node.endPosition.row + 1,
|
|
9233
|
+
startIndex: node.startIndex,
|
|
9234
|
+
endIndex: node.endIndex
|
|
9135
9235
|
});
|
|
9136
9236
|
};
|
|
9137
9237
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9193,7 +9293,9 @@ function collectJavaSymbolDefs(root) {
|
|
|
9193
9293
|
kind,
|
|
9194
9294
|
qualname,
|
|
9195
9295
|
startLine: node.startPosition.row + 1,
|
|
9196
|
-
endLine: node.endPosition.row + 1
|
|
9296
|
+
endLine: node.endPosition.row + 1,
|
|
9297
|
+
startIndex: node.startIndex,
|
|
9298
|
+
endIndex: node.endIndex
|
|
9197
9299
|
});
|
|
9198
9300
|
};
|
|
9199
9301
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9250,7 +9352,9 @@ function collectKotlinSymbolDefs(root) {
|
|
|
9250
9352
|
kind,
|
|
9251
9353
|
qualname,
|
|
9252
9354
|
startLine: node.startPosition.row + 1,
|
|
9253
|
-
endLine: node.endPosition.row + 1
|
|
9355
|
+
endLine: node.endPosition.row + 1,
|
|
9356
|
+
startIndex: node.startIndex,
|
|
9357
|
+
endIndex: node.endIndex
|
|
9254
9358
|
});
|
|
9255
9359
|
};
|
|
9256
9360
|
const join2 = (prefix, name) => prefix ? `${prefix}.${name}` : name;
|
|
@@ -9320,7 +9424,9 @@ function collectRustSymbolDefs(root) {
|
|
|
9320
9424
|
kind,
|
|
9321
9425
|
qualname,
|
|
9322
9426
|
startLine: node.startPosition.row + 1,
|
|
9323
|
-
endLine: node.endPosition.row + 1
|
|
9427
|
+
endLine: node.endPosition.row + 1,
|
|
9428
|
+
startIndex: node.startIndex,
|
|
9429
|
+
endIndex: node.endIndex
|
|
9324
9430
|
});
|
|
9325
9431
|
};
|
|
9326
9432
|
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
@@ -9388,7 +9494,9 @@ function collectCppSymbolDefs(root) {
|
|
|
9388
9494
|
kind,
|
|
9389
9495
|
qualname,
|
|
9390
9496
|
startLine: node.startPosition.row + 1,
|
|
9391
|
-
endLine: node.endPosition.row + 1
|
|
9497
|
+
endLine: node.endPosition.row + 1,
|
|
9498
|
+
startIndex: node.startIndex,
|
|
9499
|
+
endIndex: node.endIndex
|
|
9392
9500
|
});
|
|
9393
9501
|
};
|
|
9394
9502
|
const join2 = (prefix, name) => prefix ? `${prefix}::${name}` : name;
|
|
@@ -9516,6 +9624,22 @@ function disambiguate(defs) {
|
|
|
9516
9624
|
return { def, disambiguator: ordinal };
|
|
9517
9625
|
});
|
|
9518
9626
|
}
|
|
9627
|
+
function utf8Offsets(content, defs) {
|
|
9628
|
+
if (content.includes("\uFFFD")) return /* @__PURE__ */ new Map();
|
|
9629
|
+
const indices = [...new Set(defs.flatMap(({ startIndex, endIndex }) => [startIndex, endIndex]))].sort(
|
|
9630
|
+
(a, b) => a - b
|
|
9631
|
+
);
|
|
9632
|
+
const offsets = /* @__PURE__ */ new Map();
|
|
9633
|
+
let cursor = 0;
|
|
9634
|
+
let bytes = 0;
|
|
9635
|
+
for (const index of indices) {
|
|
9636
|
+
if (index < cursor || index > content.length) return /* @__PURE__ */ new Map();
|
|
9637
|
+
bytes += Buffer.byteLength(content.slice(cursor, index), "utf8");
|
|
9638
|
+
offsets.set(index, bytes);
|
|
9639
|
+
cursor = index;
|
|
9640
|
+
}
|
|
9641
|
+
return offsets;
|
|
9642
|
+
}
|
|
9519
9643
|
async function addSymbols(graph, services) {
|
|
9520
9644
|
const parsers = /* @__PURE__ */ new Map();
|
|
9521
9645
|
const parserForExt5 = (ext) => {
|
|
@@ -9539,47 +9663,59 @@ async function addSymbols(graph, services) {
|
|
|
9539
9663
|
if (!parser) continue;
|
|
9540
9664
|
const relPath = toPosix(import_node_path26.default.relative(service.dir, file.path));
|
|
9541
9665
|
let defs;
|
|
9666
|
+
let completeParse;
|
|
9542
9667
|
try {
|
|
9543
9668
|
const tree = parseSource3(parser, file.content);
|
|
9544
9669
|
defs = collectSymbolDefsForExt(ext, tree.rootNode);
|
|
9670
|
+
completeParse = !tree.rootNode.hasError;
|
|
9545
9671
|
} catch (err) {
|
|
9546
9672
|
recordExtractionError("symbol extraction", file.path, err);
|
|
9547
9673
|
continue;
|
|
9548
9674
|
}
|
|
9549
9675
|
if (defs.length === 0) continue;
|
|
9550
|
-
const
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
);
|
|
9676
|
+
const offsets = completeParse ? utf8Offsets(file.content, defs) : /* @__PURE__ */ new Map();
|
|
9677
|
+
const {
|
|
9678
|
+
fileNodeId,
|
|
9679
|
+
nodesAdded: fn,
|
|
9680
|
+
edgesAdded: fe
|
|
9681
|
+
} = ensureFileNode(graph, service.pkg.name, service.node.id, relPath);
|
|
9556
9682
|
nodesAdded += fn;
|
|
9557
9683
|
edgesAdded += fe;
|
|
9558
9684
|
for (const { def, disambiguator } of disambiguate(defs)) {
|
|
9559
|
-
const sid = (0,
|
|
9685
|
+
const sid = (0, import_types22.symbolId)(service.pkg.name, relPath, def.qualname, disambiguator);
|
|
9686
|
+
const startByte = offsets.get(def.startIndex);
|
|
9687
|
+
const endByte = offsets.get(def.endIndex);
|
|
9688
|
+
const precise = startByte !== void 0 && endByte !== void 0 && endByte > startByte ? { startByte, endByte } : {};
|
|
9689
|
+
const node = {
|
|
9690
|
+
id: sid,
|
|
9691
|
+
type: import_types22.NodeType.SymbolNode,
|
|
9692
|
+
kind: def.kind,
|
|
9693
|
+
qualname: def.qualname,
|
|
9694
|
+
span: { startLine: def.startLine, endLine: def.endLine, ...precise },
|
|
9695
|
+
service: service.pkg.name,
|
|
9696
|
+
relPath,
|
|
9697
|
+
discoveredVia: "static"
|
|
9698
|
+
};
|
|
9560
9699
|
if (!graph.hasNode(sid)) {
|
|
9561
|
-
const node = {
|
|
9562
|
-
id: sid,
|
|
9563
|
-
type: import_types21.NodeType.SymbolNode,
|
|
9564
|
-
kind: def.kind,
|
|
9565
|
-
qualname: def.qualname,
|
|
9566
|
-
span: { startLine: def.startLine, endLine: def.endLine },
|
|
9567
|
-
service: service.pkg.name,
|
|
9568
|
-
relPath,
|
|
9569
|
-
discoveredVia: "static"
|
|
9570
|
-
};
|
|
9571
9700
|
graph.addNode(sid, node);
|
|
9572
9701
|
nodesAdded++;
|
|
9702
|
+
} else {
|
|
9703
|
+
const previous = graph.getNodeAttributes(sid);
|
|
9704
|
+
const discoveredVia = previous.discoveredVia === "otel" || previous.discoveredVia === "merged" ? "merged" : "static";
|
|
9705
|
+
const moved = previous.span.startLine !== node.span.startLine || previous.span.endLine !== node.span.endLine || previous.span.startByte !== node.span.startByte || previous.span.endByte !== node.span.endByte;
|
|
9706
|
+
if (moved || previous.kind !== node.kind || previous.qualname !== node.qualname || previous.discoveredVia !== discoveredVia || previous.service !== node.service || previous.relPath !== node.relPath) {
|
|
9707
|
+
graph.replaceNodeAttributes(sid, { ...previous, ...node, discoveredVia });
|
|
9708
|
+
}
|
|
9573
9709
|
}
|
|
9574
|
-
const containsId = (0,
|
|
9710
|
+
const containsId = (0, import_types22.extractedEdgeId)(fileNodeId, sid, import_types22.EdgeType.CONTAINS);
|
|
9575
9711
|
if (!graph.hasEdge(containsId)) {
|
|
9576
9712
|
const edge = {
|
|
9577
9713
|
id: containsId,
|
|
9578
9714
|
source: fileNodeId,
|
|
9579
9715
|
target: sid,
|
|
9580
|
-
type:
|
|
9581
|
-
provenance:
|
|
9582
|
-
confidence: (0,
|
|
9716
|
+
type: import_types22.EdgeType.CONTAINS,
|
|
9717
|
+
provenance: import_types22.Provenance.EXTRACTED,
|
|
9718
|
+
confidence: (0, import_types22.confidenceForExtracted)("structural"),
|
|
9583
9719
|
evidence: {
|
|
9584
9720
|
file: relPath,
|
|
9585
9721
|
line: def.startLine,
|
|
@@ -9599,7 +9735,7 @@ async function addSymbols(graph, services) {
|
|
|
9599
9735
|
init_cjs_shims();
|
|
9600
9736
|
var import_node_path27 = __toESM(require("path"), 1);
|
|
9601
9737
|
var import_tree_sitter4 = __toESM(require("tree-sitter"), 1);
|
|
9602
|
-
var
|
|
9738
|
+
var import_types23 = require("@neat.is/types");
|
|
9603
9739
|
function extendsInfo(classHeritage) {
|
|
9604
9740
|
for (let i = 0; i < classHeritage.namedChildCount; i++) {
|
|
9605
9741
|
const child = classHeritage.namedChild(i);
|
|
@@ -9717,7 +9853,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9717
9853
|
}
|
|
9718
9854
|
const disambiguated = disambiguate(collectSymbolDefs(root));
|
|
9719
9855
|
const locals = disambiguated.map(({ def, disambiguator }) => ({
|
|
9720
|
-
sid: (0,
|
|
9856
|
+
sid: (0, import_types23.symbolId)(serviceName, relPath, def.qualname, disambiguator),
|
|
9721
9857
|
qualname: def.qualname,
|
|
9722
9858
|
kind: def.kind,
|
|
9723
9859
|
startLine: def.startLine,
|
|
@@ -9746,10 +9882,10 @@ async function addSymbolEdges(graph, services) {
|
|
|
9746
9882
|
if (local) return local.kind === wantKind ? local.sid : null;
|
|
9747
9883
|
const imp = resolvedImports.get(name);
|
|
9748
9884
|
if (imp) {
|
|
9749
|
-
const candidate = (0,
|
|
9885
|
+
const candidate = (0, import_types23.symbolId)(serviceName, imp.targetRelPath, imp.importedName);
|
|
9750
9886
|
if (graph.hasNode(candidate)) {
|
|
9751
9887
|
const node = graph.getNodeAttributes(candidate);
|
|
9752
|
-
if (node.type ===
|
|
9888
|
+
if (node.type === import_types23.NodeType.SymbolNode && node.kind === wantKind) return candidate;
|
|
9753
9889
|
}
|
|
9754
9890
|
}
|
|
9755
9891
|
return null;
|
|
@@ -9776,7 +9912,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9776
9912
|
sourceSid: self.sid,
|
|
9777
9913
|
targetName: ext.name,
|
|
9778
9914
|
wantKind: "class",
|
|
9779
|
-
edgeType:
|
|
9915
|
+
edgeType: import_types23.EdgeType.INHERITS,
|
|
9780
9916
|
line: ext.line
|
|
9781
9917
|
});
|
|
9782
9918
|
}
|
|
@@ -9785,7 +9921,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9785
9921
|
sourceSid: self.sid,
|
|
9786
9922
|
targetName: impl.name,
|
|
9787
9923
|
wantKind: "class",
|
|
9788
|
-
edgeType:
|
|
9924
|
+
edgeType: import_types23.EdgeType.IMPLEMENTS,
|
|
9789
9925
|
line: impl.line
|
|
9790
9926
|
});
|
|
9791
9927
|
}
|
|
@@ -9801,7 +9937,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9801
9937
|
sourceSid: caller.sid,
|
|
9802
9938
|
targetName: fn.text,
|
|
9803
9939
|
wantKind: "function",
|
|
9804
|
-
edgeType:
|
|
9940
|
+
edgeType: import_types23.EdgeType.CALLS,
|
|
9805
9941
|
line
|
|
9806
9942
|
});
|
|
9807
9943
|
}
|
|
@@ -9817,15 +9953,15 @@ async function addSymbolEdges(graph, services) {
|
|
|
9817
9953
|
const targetSid = resolveTarget(req.targetName, req.wantKind);
|
|
9818
9954
|
if (!targetSid) continue;
|
|
9819
9955
|
if (targetSid === req.sourceSid) continue;
|
|
9820
|
-
const edgeId = (0,
|
|
9956
|
+
const edgeId = (0, import_types23.extractedEdgeId)(req.sourceSid, targetSid, req.edgeType);
|
|
9821
9957
|
if (graph.hasEdge(edgeId)) continue;
|
|
9822
9958
|
const edge = {
|
|
9823
9959
|
id: edgeId,
|
|
9824
9960
|
source: req.sourceSid,
|
|
9825
9961
|
target: targetSid,
|
|
9826
9962
|
type: req.edgeType,
|
|
9827
|
-
provenance:
|
|
9828
|
-
confidence: (0,
|
|
9963
|
+
provenance: import_types23.Provenance.EXTRACTED,
|
|
9964
|
+
confidence: (0, import_types23.confidenceForExtracted)("structural"),
|
|
9829
9965
|
evidence: {
|
|
9830
9966
|
file: relPath,
|
|
9831
9967
|
line: req.line,
|
|
@@ -9844,7 +9980,7 @@ async function addSymbolEdges(graph, services) {
|
|
|
9844
9980
|
init_cjs_shims();
|
|
9845
9981
|
var import_node_path28 = __toESM(require("path"), 1);
|
|
9846
9982
|
var import_tree_sitter5 = __toESM(require("tree-sitter"), 1);
|
|
9847
|
-
var
|
|
9983
|
+
var import_types24 = require("@neat.is/types");
|
|
9848
9984
|
function stringLiteralText2(node) {
|
|
9849
9985
|
for (let i = 0; i < node.childCount; i++) {
|
|
9850
9986
|
const child = node.child(i);
|
|
@@ -10014,11 +10150,11 @@ async function addServerActions(graph, services) {
|
|
|
10014
10150
|
nodesAdded += fn;
|
|
10015
10151
|
edgesAdded += fe;
|
|
10016
10152
|
for (const action of actions) {
|
|
10017
|
-
const aid = (0,
|
|
10153
|
+
const aid = (0, import_types24.serverActionId)(service.pkg.name, relPath, action.exportName);
|
|
10018
10154
|
if (!graph.hasNode(aid)) {
|
|
10019
10155
|
const node = {
|
|
10020
10156
|
id: aid,
|
|
10021
|
-
type:
|
|
10157
|
+
type: import_types24.NodeType.ServerActionNode,
|
|
10022
10158
|
name: action.exportName,
|
|
10023
10159
|
service: service.pkg.name,
|
|
10024
10160
|
module: relPath,
|
|
@@ -10030,15 +10166,15 @@ async function addServerActions(graph, services) {
|
|
|
10030
10166
|
graph.addNode(aid, node);
|
|
10031
10167
|
nodesAdded++;
|
|
10032
10168
|
}
|
|
10033
|
-
const containsId = (0,
|
|
10169
|
+
const containsId = (0, import_types24.extractedEdgeId)(fileNodeId, aid, import_types24.EdgeType.CONTAINS);
|
|
10034
10170
|
if (!graph.hasEdge(containsId)) {
|
|
10035
10171
|
const edge = {
|
|
10036
10172
|
id: containsId,
|
|
10037
10173
|
source: fileNodeId,
|
|
10038
10174
|
target: aid,
|
|
10039
|
-
type:
|
|
10040
|
-
provenance:
|
|
10041
|
-
confidence: (0,
|
|
10175
|
+
type: import_types24.EdgeType.CONTAINS,
|
|
10176
|
+
provenance: import_types24.Provenance.EXTRACTED,
|
|
10177
|
+
confidence: (0, import_types24.confidenceForExtracted)("structural"),
|
|
10042
10178
|
evidence: {
|
|
10043
10179
|
file: relPath,
|
|
10044
10180
|
line: action.line,
|
|
@@ -10068,7 +10204,7 @@ async function addServerActions(graph, services) {
|
|
|
10068
10204
|
for (const [local, binding] of bindings) {
|
|
10069
10205
|
const target = await resolveJsImport(binding.specifier, fileDir, service.dir, tsPaths);
|
|
10070
10206
|
if (!target) continue;
|
|
10071
|
-
const aid = (0,
|
|
10207
|
+
const aid = (0, import_types24.serverActionId)(service.pkg.name, target, binding.importedName);
|
|
10072
10208
|
if (graph.hasNode(aid)) actionBindings.set(local, aid);
|
|
10073
10209
|
}
|
|
10074
10210
|
if (actionBindings.size === 0) continue;
|
|
@@ -10083,15 +10219,15 @@ async function addServerActions(graph, services) {
|
|
|
10083
10219
|
nodesAdded += ensured.nodesAdded;
|
|
10084
10220
|
edgesAdded += ensured.edgesAdded;
|
|
10085
10221
|
}
|
|
10086
|
-
const callsId = (0,
|
|
10222
|
+
const callsId = (0, import_types24.extractedEdgeId)(clientFileId, aid, import_types24.EdgeType.CALLS);
|
|
10087
10223
|
if (graph.hasEdge(callsId)) continue;
|
|
10088
10224
|
const edge = {
|
|
10089
10225
|
id: callsId,
|
|
10090
10226
|
source: clientFileId,
|
|
10091
10227
|
target: aid,
|
|
10092
|
-
type:
|
|
10093
|
-
provenance:
|
|
10094
|
-
confidence: (0,
|
|
10228
|
+
type: import_types24.EdgeType.CALLS,
|
|
10229
|
+
provenance: import_types24.Provenance.EXTRACTED,
|
|
10230
|
+
confidence: (0, import_types24.confidenceForExtracted)("structural"),
|
|
10095
10231
|
evidence: {
|
|
10096
10232
|
file: relPath,
|
|
10097
10233
|
line,
|
|
@@ -10109,7 +10245,7 @@ async function addServerActions(graph, services) {
|
|
|
10109
10245
|
// src/extract/databases/index.ts
|
|
10110
10246
|
init_cjs_shims();
|
|
10111
10247
|
var import_node_path37 = __toESM(require("path"), 1);
|
|
10112
|
-
var
|
|
10248
|
+
var import_types25 = require("@neat.is/types");
|
|
10113
10249
|
|
|
10114
10250
|
// src/extract/databases/db-config-yaml.ts
|
|
10115
10251
|
init_cjs_shims();
|
|
@@ -10768,8 +10904,8 @@ function compatibleDriversFor(engine) {
|
|
|
10768
10904
|
}
|
|
10769
10905
|
function toDatabaseNode(config) {
|
|
10770
10906
|
return {
|
|
10771
|
-
id: (0,
|
|
10772
|
-
type:
|
|
10907
|
+
id: (0, import_types25.databaseId)(config.host),
|
|
10908
|
+
type: import_types25.NodeType.DatabaseNode,
|
|
10773
10909
|
name: config.database || config.host,
|
|
10774
10910
|
engine: config.engine,
|
|
10775
10911
|
engineVersion: config.engineVersion,
|
|
@@ -10910,12 +11046,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10910
11046
|
edgesAdded += fe;
|
|
10911
11047
|
const evidenceFile = toPosix(import_node_path37.default.relative(scanPath, config.sourceFile));
|
|
10912
11048
|
const edge = {
|
|
10913
|
-
id: (0, import_types4.extractedEdgeId)(fileNodeId, dbNode.id,
|
|
11049
|
+
id: (0, import_types4.extractedEdgeId)(fileNodeId, dbNode.id, import_types25.EdgeType.CONNECTS_TO),
|
|
10914
11050
|
source: fileNodeId,
|
|
10915
11051
|
target: dbNode.id,
|
|
10916
|
-
type:
|
|
10917
|
-
provenance:
|
|
10918
|
-
confidence: (0,
|
|
11052
|
+
type: import_types25.EdgeType.CONNECTS_TO,
|
|
11053
|
+
provenance: import_types25.Provenance.EXTRACTED,
|
|
11054
|
+
confidence: (0, import_types25.confidenceForExtracted)("structural"),
|
|
10919
11055
|
// Carry how the host was recovered (ADR-213) so the divergence ranker
|
|
10920
11056
|
// can tell a real declared store from a hardcoded fault-injection /
|
|
10921
11057
|
// flag-gated probe. Only set when the parser distinguished the two.
|
|
@@ -10930,11 +11066,11 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10930
11066
|
const primary = allConfigs[0];
|
|
10931
11067
|
service.node.dbConnectionTarget = primary.port ? `${primary.host}:${primary.port}` : primary.host;
|
|
10932
11068
|
const relPath = import_node_path37.default.relative(scanPath, primary.sourceFile);
|
|
10933
|
-
const cfgId = (0,
|
|
11069
|
+
const cfgId = (0, import_types25.configId)(relPath);
|
|
10934
11070
|
if (!graph.hasNode(cfgId)) {
|
|
10935
11071
|
const cfgNode = {
|
|
10936
11072
|
id: cfgId,
|
|
10937
|
-
type:
|
|
11073
|
+
type: import_types25.NodeType.ConfigNode,
|
|
10938
11074
|
name: import_node_path37.default.basename(primary.sourceFile),
|
|
10939
11075
|
path: relPath,
|
|
10940
11076
|
fileType: isConfigFile(import_node_path37.default.basename(primary.sourceFile)).fileType || "config"
|
|
@@ -10943,12 +11079,12 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10943
11079
|
nodesAdded++;
|
|
10944
11080
|
}
|
|
10945
11081
|
const cfgEdge = {
|
|
10946
|
-
id: (0, import_types4.extractedEdgeId)(service.node.id, cfgId,
|
|
11082
|
+
id: (0, import_types4.extractedEdgeId)(service.node.id, cfgId, import_types25.EdgeType.CONFIGURED_BY),
|
|
10947
11083
|
source: service.node.id,
|
|
10948
11084
|
target: cfgId,
|
|
10949
|
-
type:
|
|
10950
|
-
provenance:
|
|
10951
|
-
confidence: (0,
|
|
11085
|
+
type: import_types25.EdgeType.CONFIGURED_BY,
|
|
11086
|
+
provenance: import_types25.Provenance.EXTRACTED,
|
|
11087
|
+
confidence: (0, import_types25.confidenceForExtracted)("structural"),
|
|
10952
11088
|
evidence: { file: toPosix(relPath) }
|
|
10953
11089
|
};
|
|
10954
11090
|
if (!graph.hasEdge(cfgEdge.id)) {
|
|
@@ -10980,7 +11116,7 @@ async function addDatabasesAndCompat(graph, services, scanPath) {
|
|
|
10980
11116
|
init_cjs_shims();
|
|
10981
11117
|
var import_node_fs26 = require("fs");
|
|
10982
11118
|
var import_node_path38 = __toESM(require("path"), 1);
|
|
10983
|
-
var
|
|
11119
|
+
var import_types26 = require("@neat.is/types");
|
|
10984
11120
|
async function walkConfigFiles(dir, excludeDirs = []) {
|
|
10985
11121
|
const excluded = new Set(excludeDirs.map((d) => import_node_path38.default.resolve(d)));
|
|
10986
11122
|
const out = [];
|
|
@@ -11009,8 +11145,8 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
11009
11145
|
for (const file of configFiles) {
|
|
11010
11146
|
const relPath = import_node_path38.default.relative(scanPath, file);
|
|
11011
11147
|
const node = {
|
|
11012
|
-
id: (0,
|
|
11013
|
-
type:
|
|
11148
|
+
id: (0, import_types26.configId)(relPath),
|
|
11149
|
+
type: import_types26.NodeType.ConfigNode,
|
|
11014
11150
|
name: import_node_path38.default.basename(file),
|
|
11015
11151
|
path: relPath,
|
|
11016
11152
|
fileType: isConfigFile(import_node_path38.default.basename(file)).fileType
|
|
@@ -11029,12 +11165,12 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
11029
11165
|
nodesAdded += fn;
|
|
11030
11166
|
edgesAdded += fe;
|
|
11031
11167
|
const edge = {
|
|
11032
|
-
id: (0, import_types4.extractedEdgeId)(fileNodeId, node.id,
|
|
11168
|
+
id: (0, import_types4.extractedEdgeId)(fileNodeId, node.id, import_types26.EdgeType.CONFIGURED_BY),
|
|
11033
11169
|
source: fileNodeId,
|
|
11034
11170
|
target: node.id,
|
|
11035
|
-
type:
|
|
11036
|
-
provenance:
|
|
11037
|
-
confidence: (0,
|
|
11171
|
+
type: import_types26.EdgeType.CONFIGURED_BY,
|
|
11172
|
+
provenance: import_types26.Provenance.EXTRACTED,
|
|
11173
|
+
confidence: (0, import_types26.confidenceForExtracted)("structural"),
|
|
11038
11174
|
evidence: { file: relPath.split(import_node_path38.default.sep).join("/") }
|
|
11039
11175
|
};
|
|
11040
11176
|
if (!graph.hasEdge(edge.id)) {
|
|
@@ -11050,7 +11186,7 @@ async function addConfigNodes(graph, services, scanPath) {
|
|
|
11050
11186
|
init_cjs_shims();
|
|
11051
11187
|
var import_node_fs27 = require("fs");
|
|
11052
11188
|
var import_node_path39 = __toESM(require("path"), 1);
|
|
11053
|
-
var
|
|
11189
|
+
var import_types27 = require("@neat.is/types");
|
|
11054
11190
|
var PROTO_EXTENSION = ".proto";
|
|
11055
11191
|
function packageOf(content) {
|
|
11056
11192
|
const m = content.match(/^\s*package\s+([A-Za-z_][A-Za-z0-9_.]*)\s*;/m);
|
|
@@ -11130,11 +11266,11 @@ async function addGrpcMethods(graph, services) {
|
|
|
11130
11266
|
}
|
|
11131
11267
|
if (methods.length === 0) continue;
|
|
11132
11268
|
for (const method of methods) {
|
|
11133
|
-
const mid = (0,
|
|
11269
|
+
const mid = (0, import_types27.grpcMethodId)(method.rpcService, method.rpcMethod);
|
|
11134
11270
|
if (!graph.hasNode(mid)) {
|
|
11135
11271
|
const node = {
|
|
11136
11272
|
id: mid,
|
|
11137
|
-
type:
|
|
11273
|
+
type: import_types27.NodeType.GrpcMethodNode,
|
|
11138
11274
|
name: `${method.rpcService}/${method.rpcMethod}`,
|
|
11139
11275
|
rpcService: method.rpcService,
|
|
11140
11276
|
rpcMethod: method.rpcMethod,
|
|
@@ -11145,15 +11281,15 @@ async function addGrpcMethods(graph, services) {
|
|
|
11145
11281
|
graph.addNode(mid, node);
|
|
11146
11282
|
nodesAdded++;
|
|
11147
11283
|
}
|
|
11148
|
-
const containsId = (0,
|
|
11284
|
+
const containsId = (0, import_types27.extractedEdgeId)(service.node.id, mid, import_types27.EdgeType.CONTAINS);
|
|
11149
11285
|
if (!graph.hasEdge(containsId)) {
|
|
11150
11286
|
const edge = {
|
|
11151
11287
|
id: containsId,
|
|
11152
11288
|
source: service.node.id,
|
|
11153
11289
|
target: mid,
|
|
11154
|
-
type:
|
|
11155
|
-
provenance:
|
|
11156
|
-
confidence: (0,
|
|
11290
|
+
type: import_types27.EdgeType.CONTAINS,
|
|
11291
|
+
provenance: import_types27.Provenance.EXTRACTED,
|
|
11292
|
+
confidence: (0, import_types27.confidenceForExtracted)("structural"),
|
|
11157
11293
|
evidence: {
|
|
11158
11294
|
file: relFile,
|
|
11159
11295
|
line: method.line,
|
|
@@ -11171,7 +11307,7 @@ async function addGrpcMethods(graph, services) {
|
|
|
11171
11307
|
|
|
11172
11308
|
// src/extract/calls/index.ts
|
|
11173
11309
|
init_cjs_shims();
|
|
11174
|
-
var
|
|
11310
|
+
var import_types47 = require("@neat.is/types");
|
|
11175
11311
|
|
|
11176
11312
|
// src/extract/calls/http.ts
|
|
11177
11313
|
init_cjs_shims();
|
|
@@ -11180,7 +11316,7 @@ var import_tree_sitter6 = __toESM(require("tree-sitter"), 1);
|
|
|
11180
11316
|
var import_tree_sitter_javascript4 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11181
11317
|
var import_tree_sitter_typescript2 = __toESM(require("tree-sitter-typescript"), 1);
|
|
11182
11318
|
var import_tree_sitter_python4 = __toESM(require("tree-sitter-python"), 1);
|
|
11183
|
-
var
|
|
11319
|
+
var import_types28 = require("@neat.is/types");
|
|
11184
11320
|
var STRING_LITERAL_NODE_TYPES = /* @__PURE__ */ new Set(["string_fragment", "string_content"]);
|
|
11185
11321
|
var JSX_EXTERNAL_LINK_TAGS = /* @__PURE__ */ new Set(["a", "Link", "NavLink", "ExternalLink", "Anchor"]);
|
|
11186
11322
|
function isInsideJsxExternalLink(node) {
|
|
@@ -11274,7 +11410,7 @@ async function addHttpCallEdges(graph, services) {
|
|
|
11274
11410
|
const dedupKey = `${relFile}|${targetId}`;
|
|
11275
11411
|
if (seen.has(dedupKey)) continue;
|
|
11276
11412
|
seen.add(dedupKey);
|
|
11277
|
-
const confidence = (0,
|
|
11413
|
+
const confidence = (0, import_types28.confidenceForExtracted)("url-literal-service-target");
|
|
11278
11414
|
const ev = {
|
|
11279
11415
|
file: relFile,
|
|
11280
11416
|
line: site.line,
|
|
@@ -11288,25 +11424,25 @@ async function addHttpCallEdges(graph, services) {
|
|
|
11288
11424
|
);
|
|
11289
11425
|
nodesAdded += n;
|
|
11290
11426
|
edgesAdded += e;
|
|
11291
|
-
if (!(0,
|
|
11427
|
+
if (!(0, import_types28.passesExtractedFloor)(confidence)) {
|
|
11292
11428
|
noteExtractedDropped({
|
|
11293
11429
|
source: fileNodeId,
|
|
11294
11430
|
target: targetId,
|
|
11295
|
-
type:
|
|
11431
|
+
type: import_types28.EdgeType.CALLS,
|
|
11296
11432
|
confidence,
|
|
11297
11433
|
confidenceKind: "url-literal-service-target",
|
|
11298
11434
|
evidence: ev
|
|
11299
11435
|
});
|
|
11300
11436
|
continue;
|
|
11301
11437
|
}
|
|
11302
|
-
const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, targetId,
|
|
11438
|
+
const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, targetId, import_types28.EdgeType.CALLS);
|
|
11303
11439
|
if (!graph.hasEdge(edgeId)) {
|
|
11304
11440
|
const edge = {
|
|
11305
11441
|
id: edgeId,
|
|
11306
11442
|
source: fileNodeId,
|
|
11307
11443
|
target: targetId,
|
|
11308
|
-
type:
|
|
11309
|
-
provenance:
|
|
11444
|
+
type: import_types28.EdgeType.CALLS,
|
|
11445
|
+
provenance: import_types28.Provenance.EXTRACTED,
|
|
11310
11446
|
confidence,
|
|
11311
11447
|
evidence: ev
|
|
11312
11448
|
};
|
|
@@ -11324,7 +11460,7 @@ init_cjs_shims();
|
|
|
11324
11460
|
var import_node_path41 = __toESM(require("path"), 1);
|
|
11325
11461
|
var import_tree_sitter7 = __toESM(require("tree-sitter"), 1);
|
|
11326
11462
|
var import_tree_sitter_javascript5 = __toESM(require("tree-sitter-javascript"), 1);
|
|
11327
|
-
var
|
|
11463
|
+
var import_types29 = require("@neat.is/types");
|
|
11328
11464
|
var PARSE_CHUNK5 = 16384;
|
|
11329
11465
|
function parseSource5(parser, source) {
|
|
11330
11466
|
return parser.parse(
|
|
@@ -11568,9 +11704,9 @@ function buildRouteIndex(graph) {
|
|
|
11568
11704
|
const index = /* @__PURE__ */ new Map();
|
|
11569
11705
|
graph.forEachNode((_id, attrs) => {
|
|
11570
11706
|
const node = attrs;
|
|
11571
|
-
if (node.type !==
|
|
11707
|
+
if (node.type !== import_types29.NodeType.RouteNode) return;
|
|
11572
11708
|
const route = attrs;
|
|
11573
|
-
const owner = (0,
|
|
11709
|
+
const owner = (0, import_types29.serviceId)(route.service);
|
|
11574
11710
|
const entry2 = {
|
|
11575
11711
|
method: route.method.toUpperCase(),
|
|
11576
11712
|
normalizedPath: normalizePathTemplate(route.pathTemplate),
|
|
@@ -11625,8 +11761,8 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11625
11761
|
noteExtractedDropped({
|
|
11626
11762
|
source: fileNodeId2,
|
|
11627
11763
|
target: "route:unresolved",
|
|
11628
|
-
type:
|
|
11629
|
-
confidence: (0,
|
|
11764
|
+
type: import_types29.EdgeType.CALLS,
|
|
11765
|
+
confidence: (0, import_types29.confidenceForExtracted)("reconstructed-approximate"),
|
|
11630
11766
|
confidenceKind: "reconstructed-approximate",
|
|
11631
11767
|
evidence: {
|
|
11632
11768
|
file: relFile,
|
|
@@ -11659,7 +11795,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11659
11795
|
edgesAdded += e;
|
|
11660
11796
|
const anchored = pathHasLiteralAnchor(site.pathTemplate);
|
|
11661
11797
|
const confidenceKind = site.approximate && !anchored ? "reconstructed-approximate" : "verified-call-site";
|
|
11662
|
-
const confidence = (0,
|
|
11798
|
+
const confidence = (0, import_types29.confidenceForExtracted)(confidenceKind);
|
|
11663
11799
|
const ev = {
|
|
11664
11800
|
file: relFile,
|
|
11665
11801
|
line: site.line,
|
|
@@ -11668,25 +11804,25 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11668
11804
|
pathTemplate: site.pathTemplate,
|
|
11669
11805
|
...confidenceKind === "reconstructed-approximate" ? { approximate: true, reason: site.reason } : {}
|
|
11670
11806
|
};
|
|
11671
|
-
if (!(0,
|
|
11807
|
+
if (!(0, import_types29.passesExtractedFloor)(confidence)) {
|
|
11672
11808
|
noteExtractedDropped({
|
|
11673
11809
|
source: fileNodeId,
|
|
11674
11810
|
target: match.routeNodeId,
|
|
11675
|
-
type:
|
|
11811
|
+
type: import_types29.EdgeType.CALLS,
|
|
11676
11812
|
confidence,
|
|
11677
11813
|
confidenceKind,
|
|
11678
11814
|
evidence: ev
|
|
11679
11815
|
});
|
|
11680
11816
|
continue;
|
|
11681
11817
|
}
|
|
11682
|
-
const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, match.routeNodeId,
|
|
11818
|
+
const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, match.routeNodeId, import_types29.EdgeType.CALLS);
|
|
11683
11819
|
if (!graph.hasEdge(edgeId)) {
|
|
11684
11820
|
const edge = {
|
|
11685
11821
|
id: edgeId,
|
|
11686
11822
|
source: fileNodeId,
|
|
11687
11823
|
target: match.routeNodeId,
|
|
11688
|
-
type:
|
|
11689
|
-
provenance:
|
|
11824
|
+
type: import_types29.EdgeType.CALLS,
|
|
11825
|
+
provenance: import_types29.Provenance.EXTRACTED,
|
|
11690
11826
|
confidence,
|
|
11691
11827
|
evidence: ev
|
|
11692
11828
|
};
|
|
@@ -11702,7 +11838,7 @@ async function addRouteCallEdges(graph, services) {
|
|
|
11702
11838
|
// src/extract/calls/kafka.ts
|
|
11703
11839
|
init_cjs_shims();
|
|
11704
11840
|
var import_node_path42 = __toESM(require("path"), 1);
|
|
11705
|
-
var
|
|
11841
|
+
var import_types30 = require("@neat.is/types");
|
|
11706
11842
|
var PRODUCER_TOPIC_RE = /(?:producer|kafkaProducer)[\s\S]{0,40}?\.send\s*\(\s*\{[\s\S]{0,200}?topic\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11707
11843
|
var CONSUMER_TOPIC_RE = /(?:consumer|kafkaConsumer)[\s\S]{0,40}?\.(?:subscribe|run)\s*\(\s*\{[\s\S]{0,200}?topic[s]?\s*:\s*(?:\[\s*)?['"`]([^'"`]+)['"`]/g;
|
|
11708
11844
|
var SARAMA_IMPORT_RE = /"[^"]*\/sarama"/;
|
|
@@ -11779,7 +11915,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11779
11915
|
seen.add(key);
|
|
11780
11916
|
const line = anchor !== void 0 ? file.content.slice(0, anchor).split("\n").length : lineOf(file.content, topic);
|
|
11781
11917
|
out.push({
|
|
11782
|
-
infraId: (0,
|
|
11918
|
+
infraId: (0, import_types30.infraId)("kafka-topic", topic),
|
|
11783
11919
|
name: topic,
|
|
11784
11920
|
kind: "kafka-topic",
|
|
11785
11921
|
edgeType,
|
|
@@ -11807,7 +11943,7 @@ function kafkaEndpointsFromFile(file, serviceDir) {
|
|
|
11807
11943
|
// src/extract/calls/redis.ts
|
|
11808
11944
|
init_cjs_shims();
|
|
11809
11945
|
var import_node_path43 = __toESM(require("path"), 1);
|
|
11810
|
-
var
|
|
11946
|
+
var import_types31 = require("@neat.is/types");
|
|
11811
11947
|
var REDIS_URL_RE = /redis(?:s)?:\/\/(?:[^@'"`\s]+@)?([^:/'"`\s]+)(?::(\d+))?/g;
|
|
11812
11948
|
function redisEndpointsFromFile(file, serviceDir) {
|
|
11813
11949
|
const out = [];
|
|
@@ -11820,7 +11956,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11820
11956
|
seen.add(host);
|
|
11821
11957
|
const line = lineOf(file.content, host);
|
|
11822
11958
|
out.push({
|
|
11823
|
-
infraId: (0,
|
|
11959
|
+
infraId: (0, import_types31.infraId)("redis", host),
|
|
11824
11960
|
name: host,
|
|
11825
11961
|
kind: "redis",
|
|
11826
11962
|
edgeType: "CALLS",
|
|
@@ -11841,7 +11977,7 @@ function redisEndpointsFromFile(file, serviceDir) {
|
|
|
11841
11977
|
// src/extract/calls/aws.ts
|
|
11842
11978
|
init_cjs_shims();
|
|
11843
11979
|
var import_node_path44 = __toESM(require("path"), 1);
|
|
11844
|
-
var
|
|
11980
|
+
var import_types32 = require("@neat.is/types");
|
|
11845
11981
|
var S3_BUCKET_RE = /Bucket\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11846
11982
|
var DYNAMO_TABLE_RE = /TableName\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
11847
11983
|
function hasMarker(text, markers) {
|
|
@@ -11865,7 +12001,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11865
12001
|
seen.add(key);
|
|
11866
12002
|
const line = lineOf(file.content, name);
|
|
11867
12003
|
out.push({
|
|
11868
|
-
infraId: (0,
|
|
12004
|
+
infraId: (0, import_types32.infraId)(kind, name),
|
|
11869
12005
|
name,
|
|
11870
12006
|
kind,
|
|
11871
12007
|
edgeType: "CALLS",
|
|
@@ -11900,7 +12036,7 @@ function awsEndpointsFromFile(file, serviceDir) {
|
|
|
11900
12036
|
// src/extract/calls/grpc.ts
|
|
11901
12037
|
init_cjs_shims();
|
|
11902
12038
|
var import_node_path45 = __toESM(require("path"), 1);
|
|
11903
|
-
var
|
|
12039
|
+
var import_types33 = require("@neat.is/types");
|
|
11904
12040
|
var GRPC_CLIENT_RE = /new\s+([A-Z][A-Za-z0-9_]*)Client\s*\(\s*['"`]?([^,'"`)]+)?/g;
|
|
11905
12041
|
var AWS_SDK_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@aws-sdk\/client-([a-z0-9-]+)['"`]/g;
|
|
11906
12042
|
var GRPC_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@grpc\/grpc-js['"`]|_grpc_pb['"`]/;
|
|
@@ -11949,7 +12085,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11949
12085
|
const { kind } = classified;
|
|
11950
12086
|
const line = lineOf(file.content, m[0]);
|
|
11951
12087
|
out.push({
|
|
11952
|
-
infraId: (0,
|
|
12088
|
+
infraId: (0, import_types33.infraId)(kind, name),
|
|
11953
12089
|
name,
|
|
11954
12090
|
kind,
|
|
11955
12091
|
edgeType: "CALLS",
|
|
@@ -11970,7 +12106,7 @@ function grpcEndpointsFromFile(file, serviceDir) {
|
|
|
11970
12106
|
// src/extract/calls/supabase.ts
|
|
11971
12107
|
init_cjs_shims();
|
|
11972
12108
|
var import_node_path46 = __toESM(require("path"), 1);
|
|
11973
|
-
var
|
|
12109
|
+
var import_types34 = require("@neat.is/types");
|
|
11974
12110
|
var SUPABASE_JS_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/supabase-js['"`]/;
|
|
11975
12111
|
var SUPABASE_SSR_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])@supabase\/ssr['"`]/;
|
|
11976
12112
|
var SUPABASE_CLIENT_RE = /\b(createClient|createServerClient|createBrowserClient)\s*\(\s*(?:['"`]([^'"`]*)['"`])?/g;
|
|
@@ -12018,7 +12154,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
12018
12154
|
seen.add(name);
|
|
12019
12155
|
const line = lineOf(file.content, m[0]);
|
|
12020
12156
|
out.push({
|
|
12021
|
-
infraId: (0,
|
|
12157
|
+
infraId: (0, import_types34.infraId)("supabase", name),
|
|
12022
12158
|
name,
|
|
12023
12159
|
kind: "supabase",
|
|
12024
12160
|
edgeType: "CALLS",
|
|
@@ -12049,7 +12185,7 @@ function supabaseEndpointsFromFile(file, serviceDir) {
|
|
|
12049
12185
|
seen.add(key);
|
|
12050
12186
|
const line = lineOf(file.content, am[0]);
|
|
12051
12187
|
out.push({
|
|
12052
|
-
infraId: (0,
|
|
12188
|
+
infraId: (0, import_types34.infraId)(kind, resource),
|
|
12053
12189
|
name: resource,
|
|
12054
12190
|
kind,
|
|
12055
12191
|
edgeType: "CALLS",
|
|
@@ -12070,7 +12206,7 @@ init_cjs_shims();
|
|
|
12070
12206
|
var import_node_path47 = __toESM(require("path"), 1);
|
|
12071
12207
|
var import_tree_sitter8 = __toESM(require("tree-sitter"), 1);
|
|
12072
12208
|
var import_tree_sitter_javascript6 = __toESM(require("tree-sitter-javascript"), 1);
|
|
12073
|
-
var
|
|
12209
|
+
var import_types35 = require("@neat.is/types");
|
|
12074
12210
|
var FIRESTORE_CLIENT_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase\/firestore['"`]/;
|
|
12075
12211
|
var FIRESTORE_ADMIN_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])firebase-admin(?:\/firestore)?['"`]/;
|
|
12076
12212
|
function parserForExt2(ext) {
|
|
@@ -12334,7 +12470,7 @@ function firestoreEndpointsFromFile(file, serviceDir, imported) {
|
|
|
12334
12470
|
}
|
|
12335
12471
|
}
|
|
12336
12472
|
out.push({
|
|
12337
|
-
infraId: (0,
|
|
12473
|
+
infraId: (0, import_types35.infraId)("firestore-collection", collPath),
|
|
12338
12474
|
name: collPath,
|
|
12339
12475
|
kind: "firestore-collection",
|
|
12340
12476
|
edgeType: "CALLS",
|
|
@@ -12450,7 +12586,7 @@ async function firestoreCrossFileEndpoints(files, serviceDir) {
|
|
|
12450
12586
|
// src/extract/calls/mongoose.ts
|
|
12451
12587
|
init_cjs_shims();
|
|
12452
12588
|
var import_node_path48 = __toESM(require("path"), 1);
|
|
12453
|
-
var
|
|
12589
|
+
var import_types36 = require("@neat.is/types");
|
|
12454
12590
|
var MONGOOSE_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongoose['"`]/;
|
|
12455
12591
|
var MONGODB_IMPORT_RE = /(?:from\s+['"`]|require\(\s*['"`])mongodb['"`]/;
|
|
12456
12592
|
var PLURALIZE_DISABLED_RE = /\bpluralize\s*\(\s*(?:null|false)\s*\)/;
|
|
@@ -12595,7 +12731,7 @@ function collectModelDefs(content, pluralizeOn) {
|
|
|
12595
12731
|
function endpoint(r, file, serviceDir, matchText) {
|
|
12596
12732
|
const line = lineOf(file.content, matchText);
|
|
12597
12733
|
return {
|
|
12598
|
-
infraId: (0,
|
|
12734
|
+
infraId: (0, import_types36.infraId)(r.kind, r.name),
|
|
12599
12735
|
name: r.name,
|
|
12600
12736
|
kind: r.kind,
|
|
12601
12737
|
edgeType: "CALLS",
|
|
@@ -12748,7 +12884,7 @@ init_cjs_shims();
|
|
|
12748
12884
|
var import_node_path49 = __toESM(require("path"), 1);
|
|
12749
12885
|
var import_tree_sitter9 = __toESM(require("tree-sitter"), 1);
|
|
12750
12886
|
var import_tree_sitter_python5 = __toESM(require("tree-sitter-python"), 1);
|
|
12751
|
-
var
|
|
12887
|
+
var import_types37 = require("@neat.is/types");
|
|
12752
12888
|
var SQLALCHEMY_IMPORT_RE = /(?:from|import)\s+(?:flask_sqlalchemy|sqlalchemy)\b/;
|
|
12753
12889
|
var PARSE_CHUNK6 = 16384;
|
|
12754
12890
|
function makePyParser3() {
|
|
@@ -12902,7 +13038,7 @@ function sqlalchemyEndpointsFromFile(file, serviceDir) {
|
|
|
12902
13038
|
if (seen.has(name)) return;
|
|
12903
13039
|
seen.add(name);
|
|
12904
13040
|
out.push({
|
|
12905
|
-
infraId: (0,
|
|
13041
|
+
infraId: (0, import_types37.infraId)("sql-table", name),
|
|
12906
13042
|
name,
|
|
12907
13043
|
kind: "sql-table",
|
|
12908
13044
|
edgeType: "CALLS",
|
|
@@ -13010,7 +13146,7 @@ function pythonOrmCrossFileEndpoints(files, serviceDir) {
|
|
|
13010
13146
|
if (seen.has(key)) continue;
|
|
13011
13147
|
seen.add(key);
|
|
13012
13148
|
out.push({
|
|
13013
|
-
infraId: (0,
|
|
13149
|
+
infraId: (0, import_types37.infraId)("sql-table", t),
|
|
13014
13150
|
name: t,
|
|
13015
13151
|
kind: "sql-table",
|
|
13016
13152
|
edgeType: "CALLS",
|
|
@@ -13031,7 +13167,7 @@ init_cjs_shims();
|
|
|
13031
13167
|
var import_node_path50 = __toESM(require("path"), 1);
|
|
13032
13168
|
var import_tree_sitter10 = __toESM(require("tree-sitter"), 1);
|
|
13033
13169
|
var import_tree_sitter_python6 = __toESM(require("tree-sitter-python"), 1);
|
|
13034
|
-
var
|
|
13170
|
+
var import_types38 = require("@neat.is/types");
|
|
13035
13171
|
var SOCKET_IMPORT_RE = /(?:^|\n)\s*(?:import\s+socket\b|from\s+socket\s+import\b)/;
|
|
13036
13172
|
var PARSE_CHUNK7 = 16384;
|
|
13037
13173
|
function makePyParser4() {
|
|
@@ -13097,7 +13233,7 @@ function socketEndpointsFromFile(file, serviceDir) {
|
|
|
13097
13233
|
seen.add(name);
|
|
13098
13234
|
const line = node.startPosition.row + 1;
|
|
13099
13235
|
out.push({
|
|
13100
|
-
infraId: (0,
|
|
13236
|
+
infraId: (0, import_types38.infraId)("socket", name),
|
|
13101
13237
|
name,
|
|
13102
13238
|
kind: "socket",
|
|
13103
13239
|
edgeType: "CALLS",
|
|
@@ -13118,7 +13254,7 @@ init_cjs_shims();
|
|
|
13118
13254
|
var import_node_path51 = __toESM(require("path"), 1);
|
|
13119
13255
|
var import_tree_sitter11 = __toESM(require("tree-sitter"), 1);
|
|
13120
13256
|
var import_tree_sitter_python7 = __toESM(require("tree-sitter-python"), 1);
|
|
13121
|
-
var
|
|
13257
|
+
var import_types39 = require("@neat.is/types");
|
|
13122
13258
|
var DJANGO_IMPORT_RE = /(?:from|import)\s+django\b/;
|
|
13123
13259
|
var PARSE_CHUNK8 = 16384;
|
|
13124
13260
|
function makePyParser5() {
|
|
@@ -13198,7 +13334,7 @@ function djangoOrmEndpointsFromFile(file, serviceDir) {
|
|
|
13198
13334
|
seen.add(table2);
|
|
13199
13335
|
const line = node.startPosition.row + 1;
|
|
13200
13336
|
out.push({
|
|
13201
|
-
infraId: (0,
|
|
13337
|
+
infraId: (0, import_types39.infraId)("sql-table", table2),
|
|
13202
13338
|
name: table2,
|
|
13203
13339
|
kind: "sql-table",
|
|
13204
13340
|
edgeType: "CALLS",
|
|
@@ -13214,7 +13350,7 @@ init_cjs_shims();
|
|
|
13214
13350
|
var import_node_path52 = __toESM(require("path"), 1);
|
|
13215
13351
|
var import_tree_sitter12 = __toESM(require("tree-sitter"), 1);
|
|
13216
13352
|
var import_tree_sitter_javascript7 = __toESM(require("tree-sitter-javascript"), 1);
|
|
13217
|
-
var
|
|
13353
|
+
var import_types40 = require("@neat.is/types");
|
|
13218
13354
|
var DRIZZLE_IMPORT_RE = /drizzle-orm/;
|
|
13219
13355
|
var TABLE_BUILDERS = /* @__PURE__ */ new Set(["pgTable", "mysqlTable", "sqliteTable"]);
|
|
13220
13356
|
function parserForExt3(ext) {
|
|
@@ -13305,7 +13441,7 @@ function drizzleEndpointsFromFile(file, serviceDir) {
|
|
|
13305
13441
|
const columns = columnsFromObject(obj);
|
|
13306
13442
|
const line = node.startPosition.row + 1;
|
|
13307
13443
|
out.push({
|
|
13308
|
-
infraId: (0,
|
|
13444
|
+
infraId: (0, import_types40.infraId)("sql-table", tableName2),
|
|
13309
13445
|
name: tableName2,
|
|
13310
13446
|
kind: "sql-table",
|
|
13311
13447
|
edgeType: "CALLS",
|
|
@@ -13415,7 +13551,7 @@ function drizzleForeignKeys(file, serviceDir) {
|
|
|
13415
13551
|
// src/extract/calls/prisma.ts
|
|
13416
13552
|
init_cjs_shims();
|
|
13417
13553
|
var import_node_path53 = __toESM(require("path"), 1);
|
|
13418
|
-
var
|
|
13554
|
+
var import_types41 = require("@neat.is/types");
|
|
13419
13555
|
var SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
13420
13556
|
"Int",
|
|
13421
13557
|
"String",
|
|
@@ -13463,7 +13599,7 @@ function prismaColumnsFromSchema(file, serviceDir) {
|
|
|
13463
13599
|
if (seenTable.has(b.tableName)) return;
|
|
13464
13600
|
seenTable.add(b.tableName);
|
|
13465
13601
|
out.push({
|
|
13466
|
-
infraId: (0,
|
|
13602
|
+
infraId: (0, import_types41.infraId)("sql-table", b.tableName),
|
|
13467
13603
|
name: b.tableName,
|
|
13468
13604
|
kind: "sql-table",
|
|
13469
13605
|
edgeType: "CALLS",
|
|
@@ -13635,7 +13771,7 @@ init_cjs_shims();
|
|
|
13635
13771
|
var import_node_path54 = __toESM(require("path"), 1);
|
|
13636
13772
|
var import_tree_sitter13 = __toESM(require("tree-sitter"), 1);
|
|
13637
13773
|
var import_tree_sitter_ruby3 = __toESM(require("tree-sitter-ruby"), 1);
|
|
13638
|
-
var
|
|
13774
|
+
var import_types42 = require("@neat.is/types");
|
|
13639
13775
|
var AR_SCHEMA_RE = /ActiveRecord::Schema/;
|
|
13640
13776
|
var PARSE_CHUNK9 = 16384;
|
|
13641
13777
|
function makeRubyParser2() {
|
|
@@ -13833,7 +13969,7 @@ function railsSchemaEndpointsFromFile(file, serviceDir) {
|
|
|
13833
13969
|
if (!table2 || seen.has(table2.name)) return;
|
|
13834
13970
|
seen.add(table2.name);
|
|
13835
13971
|
out.push({
|
|
13836
|
-
infraId: (0,
|
|
13972
|
+
infraId: (0, import_types42.infraId)("sql-table", table2.name),
|
|
13837
13973
|
name: table2.name,
|
|
13838
13974
|
kind: "sql-table",
|
|
13839
13975
|
edgeType: "CALLS",
|
|
@@ -13939,7 +14075,7 @@ function railsModelEndpointsFromFile(file, serviceDir) {
|
|
|
13939
14075
|
seen.add(table2);
|
|
13940
14076
|
const line = node.startPosition.row + 1;
|
|
13941
14077
|
out.push({
|
|
13942
|
-
infraId: (0,
|
|
14078
|
+
infraId: (0, import_types42.infraId)("sql-table", table2),
|
|
13943
14079
|
name: table2,
|
|
13944
14080
|
kind: "sql-table",
|
|
13945
14081
|
edgeType: "CALLS",
|
|
@@ -13997,7 +14133,7 @@ init_cjs_shims();
|
|
|
13997
14133
|
var import_node_path55 = __toESM(require("path"), 1);
|
|
13998
14134
|
var import_tree_sitter14 = __toESM(require("tree-sitter"), 1);
|
|
13999
14135
|
var import_tree_sitter_php3 = __toESM(require("tree-sitter-php"), 1);
|
|
14000
|
-
var
|
|
14136
|
+
var import_types43 = require("@neat.is/types");
|
|
14001
14137
|
var LARAVEL_SCHEMA_RE = /\bSchema::(create|createIfNotExists|table)\b/;
|
|
14002
14138
|
var PARSE_CHUNK10 = 16384;
|
|
14003
14139
|
function makePhpParser2() {
|
|
@@ -14244,7 +14380,7 @@ function laravelMigrationEndpointsFromFile(file, serviceDir) {
|
|
|
14244
14380
|
}
|
|
14245
14381
|
}
|
|
14246
14382
|
out.push({
|
|
14247
|
-
infraId: (0,
|
|
14383
|
+
infraId: (0, import_types43.infraId)("sql-table", bp.table),
|
|
14248
14384
|
name: bp.table,
|
|
14249
14385
|
kind: "sql-table",
|
|
14250
14386
|
edgeType: "CALLS",
|
|
@@ -14387,7 +14523,7 @@ function laravelModelEndpointsFromFile(file, serviceDir) {
|
|
|
14387
14523
|
seen.add(table2);
|
|
14388
14524
|
const line = node.startPosition.row + 1;
|
|
14389
14525
|
out.push({
|
|
14390
|
-
infraId: (0,
|
|
14526
|
+
infraId: (0, import_types43.infraId)("sql-table", table2),
|
|
14391
14527
|
name: table2,
|
|
14392
14528
|
kind: "sql-table",
|
|
14393
14529
|
edgeType: "CALLS",
|
|
@@ -14444,7 +14580,7 @@ init_cjs_shims();
|
|
|
14444
14580
|
var import_node_path58 = __toESM(require("path"), 1);
|
|
14445
14581
|
var import_tree_sitter15 = __toESM(require("tree-sitter"), 1);
|
|
14446
14582
|
var import_tree_sitter_go4 = __toESM(require("tree-sitter-go"), 1);
|
|
14447
|
-
var
|
|
14583
|
+
var import_types44 = require("@neat.is/types");
|
|
14448
14584
|
init_otel();
|
|
14449
14585
|
var PARSE_CHUNK11 = 16384;
|
|
14450
14586
|
var DATABASE_SQL_METHODS = /* @__PURE__ */ new Set([
|
|
@@ -14538,7 +14674,7 @@ function goSqlEndpointsFromFile(file, serviceDir) {
|
|
|
14538
14674
|
const columns = columnsFromSqlStatement(sql);
|
|
14539
14675
|
const line = node.startPosition.row + 1;
|
|
14540
14676
|
out.push({
|
|
14541
|
-
infraId: (0,
|
|
14677
|
+
infraId: (0, import_types44.infraId)("sql-table", table2),
|
|
14542
14678
|
name: table2,
|
|
14543
14679
|
kind: "sql-table",
|
|
14544
14680
|
edgeType: "CALLS",
|
|
@@ -14559,7 +14695,7 @@ init_cjs_shims();
|
|
|
14559
14695
|
var import_node_path59 = __toESM(require("path"), 1);
|
|
14560
14696
|
var import_tree_sitter16 = __toESM(require("tree-sitter"), 1);
|
|
14561
14697
|
var import_tree_sitter_go5 = __toESM(require("tree-sitter-go"), 1);
|
|
14562
|
-
var
|
|
14698
|
+
var import_types45 = require("@neat.is/types");
|
|
14563
14699
|
var GORM_IMPORT_RE = /gorm\.io\/gorm/;
|
|
14564
14700
|
var PARSE_CHUNK12 = 16384;
|
|
14565
14701
|
function makeGoParser4() {
|
|
@@ -15004,7 +15140,7 @@ function gormEndpointsFromFile(file, serviceDir) {
|
|
|
15004
15140
|
const columns = [];
|
|
15005
15141
|
collectColumns(struct, structs, /* @__PURE__ */ new Set(), "", columns, /* @__PURE__ */ new Set());
|
|
15006
15142
|
out.push({
|
|
15007
|
-
infraId: (0,
|
|
15143
|
+
infraId: (0, import_types45.infraId)("sql-table", table2),
|
|
15008
15144
|
name: table2,
|
|
15009
15145
|
kind: "sql-table",
|
|
15010
15146
|
edgeType: "CALLS",
|
|
@@ -15075,7 +15211,7 @@ init_cjs_shims();
|
|
|
15075
15211
|
var import_node_path60 = __toESM(require("path"), 1);
|
|
15076
15212
|
var import_tree_sitter17 = __toESM(require("tree-sitter"), 1);
|
|
15077
15213
|
var import_tree_sitter_c_sharp2 = __toESM(require("tree-sitter-c-sharp"), 1);
|
|
15078
|
-
var
|
|
15214
|
+
var import_types46 = require("@neat.is/types");
|
|
15079
15215
|
var EFCORE_GATE = /Microsoft\.EntityFrameworkCore|DataAnnotations\.Schema|\bDbContext\b|\bDbSet\s*</;
|
|
15080
15216
|
var PARSE_CHUNK13 = 16384;
|
|
15081
15217
|
function makeCsParser() {
|
|
@@ -15160,7 +15296,7 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
15160
15296
|
if (!name || seen.has(name)) return;
|
|
15161
15297
|
seen.add(name);
|
|
15162
15298
|
out.push({
|
|
15163
|
-
infraId: (0,
|
|
15299
|
+
infraId: (0, import_types46.infraId)("sql-table", name),
|
|
15164
15300
|
name,
|
|
15165
15301
|
kind: "sql-table",
|
|
15166
15302
|
edgeType: "CALLS",
|
|
@@ -15190,11 +15326,11 @@ function efcoreEndpointsFromFile(file, serviceDir) {
|
|
|
15190
15326
|
function edgeTypeFromEndpoint(ep) {
|
|
15191
15327
|
switch (ep.edgeType) {
|
|
15192
15328
|
case "PUBLISHES_TO":
|
|
15193
|
-
return
|
|
15329
|
+
return import_types47.EdgeType.PUBLISHES_TO;
|
|
15194
15330
|
case "CONSUMES_FROM":
|
|
15195
|
-
return
|
|
15331
|
+
return import_types47.EdgeType.CONSUMES_FROM;
|
|
15196
15332
|
default:
|
|
15197
|
-
return
|
|
15333
|
+
return import_types47.EdgeType.CALLS;
|
|
15198
15334
|
}
|
|
15199
15335
|
}
|
|
15200
15336
|
function isAwsKind(kind) {
|
|
@@ -15265,7 +15401,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15265
15401
|
if (!graph.hasNode(ep.infraId)) {
|
|
15266
15402
|
const node = {
|
|
15267
15403
|
id: ep.infraId,
|
|
15268
|
-
type:
|
|
15404
|
+
type: import_types47.NodeType.InfraNode,
|
|
15269
15405
|
name: ep.name,
|
|
15270
15406
|
// #238 — `aws-*` covers AWS-SDK client kinds (aws-s3, aws-dynamodb,
|
|
15271
15407
|
// aws-cognito-identity-provider, …); `s3-` / `dynamodb-` cover the
|
|
@@ -15278,21 +15414,21 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15278
15414
|
}
|
|
15279
15415
|
if (ep.columns && ep.columns.length > 0) {
|
|
15280
15416
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15281
|
-
if (node.type ===
|
|
15417
|
+
if (node.type === import_types47.NodeType.InfraNode) {
|
|
15282
15418
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15283
15419
|
...node,
|
|
15284
15420
|
columns: foldColumns(
|
|
15285
15421
|
node.columns,
|
|
15286
15422
|
ep.columns,
|
|
15287
|
-
|
|
15288
|
-
(0,
|
|
15423
|
+
import_types47.Provenance.EXTRACTED,
|
|
15424
|
+
(0, import_types47.confidenceForExtracted)(ep.confidenceKind)
|
|
15289
15425
|
)
|
|
15290
15426
|
});
|
|
15291
15427
|
}
|
|
15292
15428
|
}
|
|
15293
15429
|
if (ep.sdkWrites && Object.keys(ep.sdkWrites).length > 0) {
|
|
15294
15430
|
const node = graph.getNodeAttributes(ep.infraId);
|
|
15295
|
-
if (node.type ===
|
|
15431
|
+
if (node.type === import_types47.NodeType.InfraNode) {
|
|
15296
15432
|
graph.replaceNodeAttributes(ep.infraId, {
|
|
15297
15433
|
...node,
|
|
15298
15434
|
columns: foldSdkWrites(node.columns, ep.sdkWrites)
|
|
@@ -15300,7 +15436,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15300
15436
|
}
|
|
15301
15437
|
}
|
|
15302
15438
|
const edgeType = edgeTypeFromEndpoint(ep);
|
|
15303
|
-
const confidence = (0,
|
|
15439
|
+
const confidence = (0, import_types47.confidenceForExtracted)(ep.confidenceKind);
|
|
15304
15440
|
const relFile = toPosix(ep.evidence.file);
|
|
15305
15441
|
const { fileNodeId, nodesAdded: n, edgesAdded: e } = ensureFileNode(
|
|
15306
15442
|
graph,
|
|
@@ -15310,7 +15446,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15310
15446
|
);
|
|
15311
15447
|
nodesAdded += n;
|
|
15312
15448
|
edgesAdded += e;
|
|
15313
|
-
if (!(0,
|
|
15449
|
+
if (!(0, import_types47.passesExtractedFloor)(confidence)) {
|
|
15314
15450
|
noteExtractedDropped({
|
|
15315
15451
|
source: fileNodeId,
|
|
15316
15452
|
target: ep.infraId,
|
|
@@ -15330,7 +15466,7 @@ async function addExternalEndpointEdges(graph, services) {
|
|
|
15330
15466
|
source: fileNodeId,
|
|
15331
15467
|
target: ep.infraId,
|
|
15332
15468
|
type: edgeType,
|
|
15333
|
-
provenance:
|
|
15469
|
+
provenance: import_types47.Provenance.EXTRACTED,
|
|
15334
15470
|
confidence,
|
|
15335
15471
|
evidence: ep.evidence
|
|
15336
15472
|
};
|
|
@@ -15353,7 +15489,7 @@ async function addCallEdges(graph, services) {
|
|
|
15353
15489
|
|
|
15354
15490
|
// src/extract/table-edges.ts
|
|
15355
15491
|
init_cjs_shims();
|
|
15356
|
-
var
|
|
15492
|
+
var import_types48 = require("@neat.is/types");
|
|
15357
15493
|
async function addTableEdges(graph, services) {
|
|
15358
15494
|
let nodesAdded = 0;
|
|
15359
15495
|
let edgesAdded = 0;
|
|
@@ -15381,20 +15517,20 @@ async function addTableEdges(graph, services) {
|
|
|
15381
15517
|
}
|
|
15382
15518
|
refs.push(...modelRefs);
|
|
15383
15519
|
for (const ref of refs) {
|
|
15384
|
-
const childId = (0,
|
|
15385
|
-
const parentId = (0,
|
|
15520
|
+
const childId = (0, import_types48.infraId)("sql-table", ref.childTable);
|
|
15521
|
+
const parentId = (0, import_types48.infraId)("sql-table", ref.parentTable);
|
|
15386
15522
|
if (childId === parentId) continue;
|
|
15387
15523
|
nodesAdded += ensureTableNode(graph, childId, ref.childTable);
|
|
15388
15524
|
nodesAdded += ensureTableNode(graph, parentId, ref.parentTable);
|
|
15389
|
-
const edgeId = (0,
|
|
15525
|
+
const edgeId = (0, import_types48.extractedEdgeId)(childId, parentId, import_types48.EdgeType.REFERENCES);
|
|
15390
15526
|
if (graph.hasEdge(edgeId)) continue;
|
|
15391
15527
|
const edge = {
|
|
15392
15528
|
id: edgeId,
|
|
15393
15529
|
source: childId,
|
|
15394
15530
|
target: parentId,
|
|
15395
|
-
type:
|
|
15396
|
-
provenance:
|
|
15397
|
-
confidence: (0,
|
|
15531
|
+
type: import_types48.EdgeType.REFERENCES,
|
|
15532
|
+
provenance: import_types48.Provenance.EXTRACTED,
|
|
15533
|
+
confidence: (0, import_types48.confidenceForExtracted)("structural"),
|
|
15398
15534
|
evidence: ref.evidence
|
|
15399
15535
|
};
|
|
15400
15536
|
graph.addEdgeWithKey(edgeId, childId, parentId, edge);
|
|
@@ -15407,7 +15543,7 @@ function ensureTableNode(graph, id, name) {
|
|
|
15407
15543
|
if (graph.hasNode(id)) return 0;
|
|
15408
15544
|
const node = {
|
|
15409
15545
|
id,
|
|
15410
|
-
type:
|
|
15546
|
+
type: import_types48.NodeType.InfraNode,
|
|
15411
15547
|
name,
|
|
15412
15548
|
provider: "self",
|
|
15413
15549
|
kind: "sql-table"
|
|
@@ -15422,15 +15558,15 @@ init_cjs_shims();
|
|
|
15422
15558
|
// src/extract/infra/docker-compose.ts
|
|
15423
15559
|
init_cjs_shims();
|
|
15424
15560
|
var import_node_path61 = __toESM(require("path"), 1);
|
|
15425
|
-
var
|
|
15561
|
+
var import_types50 = require("@neat.is/types");
|
|
15426
15562
|
|
|
15427
15563
|
// src/extract/infra/shared.ts
|
|
15428
15564
|
init_cjs_shims();
|
|
15429
|
-
var
|
|
15565
|
+
var import_types49 = require("@neat.is/types");
|
|
15430
15566
|
function makeInfraNode(kind, name, provider = "self", extras) {
|
|
15431
15567
|
return {
|
|
15432
|
-
id: (0,
|
|
15433
|
-
type:
|
|
15568
|
+
id: (0, import_types49.infraId)(kind, name),
|
|
15569
|
+
type: import_types49.NodeType.InfraNode,
|
|
15434
15570
|
name,
|
|
15435
15571
|
provider,
|
|
15436
15572
|
kind,
|
|
@@ -15474,8 +15610,8 @@ function emitPlatformResourceEdge(graph, anchorId, edgeType, kind, name, provide
|
|
|
15474
15610
|
source: anchorId,
|
|
15475
15611
|
target: node.id,
|
|
15476
15612
|
type: edgeType,
|
|
15477
|
-
provenance:
|
|
15478
|
-
confidence: (0,
|
|
15613
|
+
provenance: import_types49.Provenance.EXTRACTED,
|
|
15614
|
+
confidence: (0, import_types49.confidenceForExtracted)("structural"),
|
|
15479
15615
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
15480
15616
|
};
|
|
15481
15617
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15542,15 +15678,15 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15542
15678
|
for (const dep of dependsOnList(svc.depends_on)) {
|
|
15543
15679
|
const targetId = composeNameToNodeId.get(dep);
|
|
15544
15680
|
if (!targetId) continue;
|
|
15545
|
-
const edgeId = (0, import_types4.extractedEdgeId)(sourceId, targetId,
|
|
15681
|
+
const edgeId = (0, import_types4.extractedEdgeId)(sourceId, targetId, import_types50.EdgeType.DEPENDS_ON);
|
|
15546
15682
|
if (graph.hasEdge(edgeId)) continue;
|
|
15547
15683
|
const edge = {
|
|
15548
15684
|
id: edgeId,
|
|
15549
15685
|
source: sourceId,
|
|
15550
15686
|
target: targetId,
|
|
15551
|
-
type:
|
|
15552
|
-
provenance:
|
|
15553
|
-
confidence: (0,
|
|
15687
|
+
type: import_types50.EdgeType.DEPENDS_ON,
|
|
15688
|
+
provenance: import_types50.Provenance.EXTRACTED,
|
|
15689
|
+
confidence: (0, import_types50.confidenceForExtracted)("structural"),
|
|
15554
15690
|
evidence: { file: evidenceFile }
|
|
15555
15691
|
};
|
|
15556
15692
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15564,7 +15700,7 @@ async function addComposeInfra(graph, scanPath, services) {
|
|
|
15564
15700
|
init_cjs_shims();
|
|
15565
15701
|
var import_node_path62 = __toESM(require("path"), 1);
|
|
15566
15702
|
var import_node_fs28 = require("fs");
|
|
15567
|
-
var
|
|
15703
|
+
var import_types51 = require("@neat.is/types");
|
|
15568
15704
|
function readDockerfile(content) {
|
|
15569
15705
|
let image = null;
|
|
15570
15706
|
const ports = [];
|
|
@@ -15623,15 +15759,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15623
15759
|
);
|
|
15624
15760
|
nodesAdded += fn;
|
|
15625
15761
|
edgesAdded += fe;
|
|
15626
|
-
const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, node.id,
|
|
15762
|
+
const edgeId = (0, import_types4.extractedEdgeId)(fileNodeId, node.id, import_types51.EdgeType.RUNS_ON);
|
|
15627
15763
|
if (!graph.hasEdge(edgeId)) {
|
|
15628
15764
|
const edge = {
|
|
15629
15765
|
id: edgeId,
|
|
15630
15766
|
source: fileNodeId,
|
|
15631
15767
|
target: node.id,
|
|
15632
|
-
type:
|
|
15633
|
-
provenance:
|
|
15634
|
-
confidence: (0,
|
|
15768
|
+
type: import_types51.EdgeType.RUNS_ON,
|
|
15769
|
+
provenance: import_types51.Provenance.EXTRACTED,
|
|
15770
|
+
confidence: (0, import_types51.confidenceForExtracted)("structural"),
|
|
15635
15771
|
evidence: {
|
|
15636
15772
|
file: evidenceFile,
|
|
15637
15773
|
...facts.entrypoint ? { snippet: facts.entrypoint.slice(0, 120) } : {}
|
|
@@ -15646,15 +15782,15 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15646
15782
|
graph.addNode(portNode.id, portNode);
|
|
15647
15783
|
nodesAdded++;
|
|
15648
15784
|
}
|
|
15649
|
-
const portEdgeId = (0, import_types4.extractedEdgeId)(fileNodeId, portNode.id,
|
|
15785
|
+
const portEdgeId = (0, import_types4.extractedEdgeId)(fileNodeId, portNode.id, import_types51.EdgeType.CONNECTS_TO);
|
|
15650
15786
|
if (graph.hasEdge(portEdgeId)) continue;
|
|
15651
15787
|
const portEdge = {
|
|
15652
15788
|
id: portEdgeId,
|
|
15653
15789
|
source: fileNodeId,
|
|
15654
15790
|
target: portNode.id,
|
|
15655
|
-
type:
|
|
15656
|
-
provenance:
|
|
15657
|
-
confidence: (0,
|
|
15791
|
+
type: import_types51.EdgeType.CONNECTS_TO,
|
|
15792
|
+
provenance: import_types51.Provenance.EXTRACTED,
|
|
15793
|
+
confidence: (0, import_types51.confidenceForExtracted)("structural"),
|
|
15658
15794
|
evidence: { file: evidenceFile, snippet: `EXPOSE ${port}` }
|
|
15659
15795
|
};
|
|
15660
15796
|
graph.addEdgeWithKey(portEdgeId, portEdge.source, portEdge.target, portEdge);
|
|
@@ -15668,7 +15804,7 @@ async function addDockerfileRuntimes(graph, services, scanPath) {
|
|
|
15668
15804
|
init_cjs_shims();
|
|
15669
15805
|
var import_node_fs29 = require("fs");
|
|
15670
15806
|
var import_node_path63 = __toESM(require("path"), 1);
|
|
15671
|
-
var
|
|
15807
|
+
var import_types52 = require("@neat.is/types");
|
|
15672
15808
|
var RESOURCE_RE = /resource\s+"(aws_[A-Za-z0-9_]+)"\s+"([A-Za-z0-9_-]+)"/g;
|
|
15673
15809
|
var REFERENCE_RE = /(?<![\w.])(aws_[A-Za-z0-9_]+)\.([A-Za-z0-9_-]+)/g;
|
|
15674
15810
|
async function walkTfFiles(start, depth = 0, max = 5) {
|
|
@@ -15749,16 +15885,16 @@ async function addTerraformResources(graph, scanPath) {
|
|
|
15749
15885
|
if (!target) continue;
|
|
15750
15886
|
if (seen.has(target.nodeId)) continue;
|
|
15751
15887
|
seen.add(target.nodeId);
|
|
15752
|
-
const edgeId = (0, import_types4.extractedEdgeId)(resource.nodeId, target.nodeId,
|
|
15888
|
+
const edgeId = (0, import_types4.extractedEdgeId)(resource.nodeId, target.nodeId, import_types52.EdgeType.DEPENDS_ON);
|
|
15753
15889
|
if (graph.hasEdge(edgeId)) continue;
|
|
15754
15890
|
const line = lineAt2(content, resource.bodyOffset + ref.index);
|
|
15755
15891
|
const edge = {
|
|
15756
15892
|
id: edgeId,
|
|
15757
15893
|
source: resource.nodeId,
|
|
15758
15894
|
target: target.nodeId,
|
|
15759
|
-
type:
|
|
15760
|
-
provenance:
|
|
15761
|
-
confidence: (0,
|
|
15895
|
+
type: import_types52.EdgeType.DEPENDS_ON,
|
|
15896
|
+
provenance: import_types52.Provenance.EXTRACTED,
|
|
15897
|
+
confidence: (0, import_types52.confidenceForExtracted)("structural"),
|
|
15762
15898
|
evidence: { file: evidenceFile, line, snippet: key }
|
|
15763
15899
|
};
|
|
15764
15900
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15774,7 +15910,7 @@ init_cjs_shims();
|
|
|
15774
15910
|
var import_node_fs30 = require("fs");
|
|
15775
15911
|
var import_node_path64 = __toESM(require("path"), 1);
|
|
15776
15912
|
var import_yaml3 = require("yaml");
|
|
15777
|
-
var
|
|
15913
|
+
var import_types53 = require("@neat.is/types");
|
|
15778
15914
|
var K8S_KIND_TO_INFRA_KIND = {
|
|
15779
15915
|
Service: "k8s-service",
|
|
15780
15916
|
Deployment: "k8s-deployment",
|
|
@@ -15834,7 +15970,7 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15834
15970
|
nodesAdded++;
|
|
15835
15971
|
}
|
|
15836
15972
|
if (isWorkload) {
|
|
15837
|
-
const svcId = (0,
|
|
15973
|
+
const svcId = (0, import_types53.serviceId)(name);
|
|
15838
15974
|
if (graph.hasNode(svcId)) {
|
|
15839
15975
|
const svc = graph.getNodeAttributes(svcId);
|
|
15840
15976
|
graph.replaceNodeAttributes(svcId, {
|
|
@@ -15846,7 +15982,7 @@ async function addK8sResources(graph, scanPath) {
|
|
|
15846
15982
|
edgesAdded += emitPlatformResourceEdge(
|
|
15847
15983
|
graph,
|
|
15848
15984
|
svcId,
|
|
15849
|
-
|
|
15985
|
+
import_types53.EdgeType.RUNS_ON,
|
|
15850
15986
|
infraKind,
|
|
15851
15987
|
name,
|
|
15852
15988
|
"kubernetes",
|
|
@@ -15865,7 +16001,7 @@ init_cjs_shims();
|
|
|
15865
16001
|
var import_node_fs31 = require("fs");
|
|
15866
16002
|
var import_node_path65 = __toESM(require("path"), 1);
|
|
15867
16003
|
var import_smol_toml3 = require("smol-toml");
|
|
15868
|
-
var
|
|
16004
|
+
var import_types54 = require("@neat.is/types");
|
|
15869
16005
|
var WRANGLER_FILENAMES = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
15870
16006
|
async function readWranglerConfig(dir) {
|
|
15871
16007
|
for (const filename of WRANGLER_FILENAMES) {
|
|
@@ -15913,8 +16049,8 @@ function addResourceEdge(graph, anchorId, edgeType, kind, name, evidenceFile, li
|
|
|
15913
16049
|
source: anchorId,
|
|
15914
16050
|
target: node.id,
|
|
15915
16051
|
type: edgeType,
|
|
15916
|
-
provenance:
|
|
15917
|
-
confidence: (0,
|
|
16052
|
+
provenance: import_types54.Provenance.EXTRACTED,
|
|
16053
|
+
confidence: (0, import_types54.confidenceForExtracted)("structural"),
|
|
15918
16054
|
evidence: { file: evidenceFile, ...line !== void 0 ? { line } : {} }
|
|
15919
16055
|
};
|
|
15920
16056
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -15975,15 +16111,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15975
16111
|
nodesAdded++;
|
|
15976
16112
|
}
|
|
15977
16113
|
if (runtimeNode.id !== anchorId) {
|
|
15978
|
-
const runsOnId = (0, import_types4.extractedEdgeId)(anchorId, runtimeNode.id,
|
|
16114
|
+
const runsOnId = (0, import_types4.extractedEdgeId)(anchorId, runtimeNode.id, import_types54.EdgeType.RUNS_ON);
|
|
15979
16115
|
if (!graph.hasEdge(runsOnId)) {
|
|
15980
16116
|
const edge = {
|
|
15981
16117
|
id: runsOnId,
|
|
15982
16118
|
source: anchorId,
|
|
15983
16119
|
target: runtimeNode.id,
|
|
15984
|
-
type:
|
|
15985
|
-
provenance:
|
|
15986
|
-
confidence: (0,
|
|
16120
|
+
type: import_types54.EdgeType.RUNS_ON,
|
|
16121
|
+
provenance: import_types54.Provenance.EXTRACTED,
|
|
16122
|
+
confidence: (0, import_types54.confidenceForExtracted)("structural"),
|
|
15987
16123
|
evidence: {
|
|
15988
16124
|
file: evidenceFile,
|
|
15989
16125
|
...config.compatibility_date ? { snippet: `compatibility_date = ${config.compatibility_date}`.slice(0, 120) } : {}
|
|
@@ -15997,7 +16133,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
15997
16133
|
const result = addResourceEdge(
|
|
15998
16134
|
graph,
|
|
15999
16135
|
anchorId,
|
|
16000
|
-
|
|
16136
|
+
import_types54.EdgeType.CONNECTS_TO,
|
|
16001
16137
|
"cloudflare-route",
|
|
16002
16138
|
route,
|
|
16003
16139
|
evidenceFile,
|
|
@@ -16021,7 +16157,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16021
16157
|
const result = addResourceEdge(
|
|
16022
16158
|
graph,
|
|
16023
16159
|
anchorId,
|
|
16024
|
-
|
|
16160
|
+
import_types54.EdgeType.DEPENDS_ON,
|
|
16025
16161
|
group.kind,
|
|
16026
16162
|
name,
|
|
16027
16163
|
evidenceFile,
|
|
@@ -16035,7 +16171,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16035
16171
|
const result = addResourceEdge(
|
|
16036
16172
|
graph,
|
|
16037
16173
|
anchorId,
|
|
16038
|
-
|
|
16174
|
+
import_types54.EdgeType.DEPENDS_ON,
|
|
16039
16175
|
"cloudflare-cron",
|
|
16040
16176
|
cron,
|
|
16041
16177
|
evidenceFile,
|
|
@@ -16048,7 +16184,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16048
16184
|
const result = addResourceEdge(
|
|
16049
16185
|
graph,
|
|
16050
16186
|
anchorId,
|
|
16051
|
-
|
|
16187
|
+
import_types54.EdgeType.DEPENDS_ON,
|
|
16052
16188
|
"cloudflare-env-var",
|
|
16053
16189
|
varName,
|
|
16054
16190
|
evidenceFile,
|
|
@@ -16061,15 +16197,15 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16061
16197
|
if (!svc.service) continue;
|
|
16062
16198
|
const target = workerIndex.get(svc.service);
|
|
16063
16199
|
if (target && target.anchorId !== anchorId) {
|
|
16064
|
-
const edgeId = (0, import_types4.extractedEdgeId)(anchorId, target.anchorId,
|
|
16200
|
+
const edgeId = (0, import_types4.extractedEdgeId)(anchorId, target.anchorId, import_types54.EdgeType.CALLS);
|
|
16065
16201
|
if (!graph.hasEdge(edgeId)) {
|
|
16066
16202
|
const edge = {
|
|
16067
16203
|
id: edgeId,
|
|
16068
16204
|
source: anchorId,
|
|
16069
16205
|
target: target.anchorId,
|
|
16070
|
-
type:
|
|
16071
|
-
provenance:
|
|
16072
|
-
confidence: (0,
|
|
16206
|
+
type: import_types54.EdgeType.CALLS,
|
|
16207
|
+
provenance: import_types54.Provenance.EXTRACTED,
|
|
16208
|
+
confidence: (0, import_types54.confidenceForExtracted)("structural"),
|
|
16073
16209
|
evidence: { file: evidenceFile, line: lineContaining2(raw, svc.service) }
|
|
16074
16210
|
};
|
|
16075
16211
|
graph.addEdgeWithKey(edgeId, edge.source, edge.target, edge);
|
|
@@ -16080,7 +16216,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16080
16216
|
const result = addResourceEdge(
|
|
16081
16217
|
graph,
|
|
16082
16218
|
anchorId,
|
|
16083
|
-
|
|
16219
|
+
import_types54.EdgeType.DEPENDS_ON,
|
|
16084
16220
|
"cloudflare-service-binding",
|
|
16085
16221
|
svc.service,
|
|
16086
16222
|
evidenceFile,
|
|
@@ -16097,7 +16233,7 @@ async function addCloudflareWorkers(graph, services, scanPath) {
|
|
|
16097
16233
|
init_cjs_shims();
|
|
16098
16234
|
var import_node_fs32 = require("fs");
|
|
16099
16235
|
var import_node_path66 = __toESM(require("path"), 1);
|
|
16100
|
-
var
|
|
16236
|
+
var import_types55 = require("@neat.is/types");
|
|
16101
16237
|
var VERCEL_CONFIG_FILENAMES = ["vercel.json", "vercel.jsonc"];
|
|
16102
16238
|
async function readVercelConfig(dir) {
|
|
16103
16239
|
for (const filename of VERCEL_CONFIG_FILENAMES) {
|
|
@@ -16160,12 +16296,12 @@ async function addVercelServices(graph, services, scanPath) {
|
|
|
16160
16296
|
nodesAdded += result.nodesAdded;
|
|
16161
16297
|
edgesAdded += result.edgesAdded;
|
|
16162
16298
|
};
|
|
16163
|
-
add(
|
|
16164
|
-
for (const cron of config.crons ?? []) add(
|
|
16165
|
-
for (const varName of Object.keys(config.env ?? {})) add(
|
|
16166
|
-
for (const varName of Object.keys(config.build?.env ?? {})) add(
|
|
16299
|
+
add(import_types55.EdgeType.RUNS_ON, "vercel", "vercel");
|
|
16300
|
+
for (const cron of config.crons ?? []) add(import_types55.EdgeType.DEPENDS_ON, "vercel-cron", cron.path ?? cron.schedule);
|
|
16301
|
+
for (const varName of Object.keys(config.env ?? {})) add(import_types55.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
16302
|
+
for (const varName of Object.keys(config.build?.env ?? {})) add(import_types55.EdgeType.DEPENDS_ON, "vercel-env-var", varName);
|
|
16167
16303
|
for (const route of [...config.rewrites ?? [], ...config.redirects ?? [], ...config.routes ?? []]) {
|
|
16168
|
-
add(
|
|
16304
|
+
add(import_types55.EdgeType.CONNECTS_TO, "vercel-route", routeSource(route));
|
|
16169
16305
|
}
|
|
16170
16306
|
}
|
|
16171
16307
|
return { nodesAdded, edgesAdded };
|
|
@@ -16176,7 +16312,7 @@ init_cjs_shims();
|
|
|
16176
16312
|
var import_node_fs33 = require("fs");
|
|
16177
16313
|
var import_node_path67 = __toESM(require("path"), 1);
|
|
16178
16314
|
var import_smol_toml4 = require("smol-toml");
|
|
16179
|
-
var
|
|
16315
|
+
var import_types56 = require("@neat.is/types");
|
|
16180
16316
|
var RAILWAY_FILENAMES = ["railway.toml", "railway.json", "railway.jsonc"];
|
|
16181
16317
|
async function readRailwayConfig(dir) {
|
|
16182
16318
|
for (const filename of RAILWAY_FILENAMES) {
|
|
@@ -16222,9 +16358,9 @@ async function addRailwayServices(graph, services, scanPath) {
|
|
|
16222
16358
|
nodesAdded += result.nodesAdded;
|
|
16223
16359
|
edgesAdded += result.edgesAdded;
|
|
16224
16360
|
};
|
|
16225
|
-
add(
|
|
16226
|
-
add(
|
|
16227
|
-
add(
|
|
16361
|
+
add(import_types56.EdgeType.RUNS_ON, "railway", "railway");
|
|
16362
|
+
add(import_types56.EdgeType.CONNECTS_TO, "railway-route", config.deploy?.healthcheckPath);
|
|
16363
|
+
add(import_types56.EdgeType.DEPENDS_ON, "railway-cron", config.deploy?.cronSchedule);
|
|
16228
16364
|
}
|
|
16229
16365
|
return { nodesAdded, edgesAdded };
|
|
16230
16366
|
}
|
|
@@ -16234,7 +16370,7 @@ init_cjs_shims();
|
|
|
16234
16370
|
var import_node_fs34 = require("fs");
|
|
16235
16371
|
var import_node_path68 = __toESM(require("path"), 1);
|
|
16236
16372
|
var import_smol_toml5 = require("smol-toml");
|
|
16237
|
-
var
|
|
16373
|
+
var import_types57 = require("@neat.is/types");
|
|
16238
16374
|
async function readSupabaseConfig(dir) {
|
|
16239
16375
|
const relFile = import_node_path68.default.join("supabase", "config.toml");
|
|
16240
16376
|
const abs = import_node_path68.default.join(dir, relFile);
|
|
@@ -16282,10 +16418,10 @@ async function addSupabaseProjects(graph, services, scanPath) {
|
|
|
16282
16418
|
nodesAdded += result.nodesAdded;
|
|
16283
16419
|
edgesAdded += result.edgesAdded;
|
|
16284
16420
|
};
|
|
16285
|
-
add(
|
|
16286
|
-
for (const fn of Object.keys(config.functions ?? {})) add(
|
|
16287
|
-
if (config.storage) add(
|
|
16288
|
-
if (config.auth) add(
|
|
16421
|
+
add(import_types57.EdgeType.RUNS_ON, "supabase", "supabase");
|
|
16422
|
+
for (const fn of Object.keys(config.functions ?? {})) add(import_types57.EdgeType.DEPENDS_ON, "supabase-function", fn);
|
|
16423
|
+
if (config.storage) add(import_types57.EdgeType.DEPENDS_ON, "supabase-storage", "storage");
|
|
16424
|
+
if (config.auth) add(import_types57.EdgeType.DEPENDS_ON, "supabase-auth", "auth");
|
|
16289
16425
|
}
|
|
16290
16426
|
return { nodesAdded, edgesAdded };
|
|
16291
16427
|
}
|
|
@@ -16311,7 +16447,7 @@ init_cjs_shims();
|
|
|
16311
16447
|
var import_node_path69 = __toESM(require("path"), 1);
|
|
16312
16448
|
var import_tree_sitter18 = __toESM(require("tree-sitter"), 1);
|
|
16313
16449
|
var import_tree_sitter_javascript8 = __toESM(require("tree-sitter-javascript"), 1);
|
|
16314
|
-
var
|
|
16450
|
+
var import_types58 = require("@neat.is/types");
|
|
16315
16451
|
var ZOD_IMPORT_RE = /\bzod\b/;
|
|
16316
16452
|
var ZOD_OBJECTS = /* @__PURE__ */ new Set(["z", "zod"]);
|
|
16317
16453
|
function parserForExt4(ext) {
|
|
@@ -16417,7 +16553,7 @@ function zodShapesFromFile(file, serviceDir) {
|
|
|
16417
16553
|
seen.add(name);
|
|
16418
16554
|
const line = call.startPosition.row + 1;
|
|
16419
16555
|
out.push({
|
|
16420
|
-
infraId: (0,
|
|
16556
|
+
infraId: (0, import_types58.infraId)("zod-schema", name),
|
|
16421
16557
|
name,
|
|
16422
16558
|
fields,
|
|
16423
16559
|
evidence: {
|
|
@@ -16452,7 +16588,7 @@ async function addZodShapes(graph, services) {
|
|
|
16452
16588
|
if (!graph.hasNode(shape.infraId)) {
|
|
16453
16589
|
const node = {
|
|
16454
16590
|
id: shape.infraId,
|
|
16455
|
-
type:
|
|
16591
|
+
type: import_types58.NodeType.InfraNode,
|
|
16456
16592
|
name: shape.name,
|
|
16457
16593
|
provider: "self",
|
|
16458
16594
|
kind: "zod-schema"
|
|
@@ -16462,14 +16598,14 @@ async function addZodShapes(graph, services) {
|
|
|
16462
16598
|
}
|
|
16463
16599
|
if (shape.fields.length > 0) {
|
|
16464
16600
|
const node = graph.getNodeAttributes(shape.infraId);
|
|
16465
|
-
if (node.type ===
|
|
16601
|
+
if (node.type === import_types58.NodeType.InfraNode) {
|
|
16466
16602
|
graph.replaceNodeAttributes(shape.infraId, {
|
|
16467
16603
|
...node,
|
|
16468
16604
|
columns: foldColumns(
|
|
16469
16605
|
node.columns,
|
|
16470
16606
|
shape.fields,
|
|
16471
|
-
|
|
16472
|
-
(0,
|
|
16607
|
+
import_types58.Provenance.EXTRACTED,
|
|
16608
|
+
(0, import_types58.confidenceForExtracted)("structural")
|
|
16473
16609
|
)
|
|
16474
16610
|
});
|
|
16475
16611
|
}
|
|
@@ -16483,15 +16619,15 @@ async function addZodShapes(graph, services) {
|
|
|
16483
16619
|
);
|
|
16484
16620
|
nodesAdded += n;
|
|
16485
16621
|
edgesAdded += e;
|
|
16486
|
-
const edgeId = (0,
|
|
16622
|
+
const edgeId = (0, import_types58.extractedEdgeId)(fileNodeId, shape.infraId, import_types58.EdgeType.CONTAINS);
|
|
16487
16623
|
if (!graph.hasEdge(edgeId)) {
|
|
16488
16624
|
const edge = {
|
|
16489
16625
|
id: edgeId,
|
|
16490
16626
|
source: fileNodeId,
|
|
16491
16627
|
target: shape.infraId,
|
|
16492
|
-
type:
|
|
16493
|
-
provenance:
|
|
16494
|
-
confidence: (0,
|
|
16628
|
+
type: import_types58.EdgeType.CONTAINS,
|
|
16629
|
+
provenance: import_types58.Provenance.EXTRACTED,
|
|
16630
|
+
confidence: (0, import_types58.confidenceForExtracted)("structural"),
|
|
16495
16631
|
evidence: shape.evidence
|
|
16496
16632
|
};
|
|
16497
16633
|
graph.addEdgeWithKey(edgeId, fileNodeId, shape.infraId, edge);
|
|
@@ -16505,7 +16641,7 @@ async function addZodShapes(graph, services) {
|
|
|
16505
16641
|
|
|
16506
16642
|
// src/extract/firestore-rules.ts
|
|
16507
16643
|
init_cjs_shims();
|
|
16508
|
-
var
|
|
16644
|
+
var import_types59 = require("@neat.is/types");
|
|
16509
16645
|
var FIRESTORE_COLLECTION_KIND = "firestore-collection";
|
|
16510
16646
|
var WRITE_METHODS = /* @__PURE__ */ new Set(["write", "create", "update"]);
|
|
16511
16647
|
function stripComments(src) {
|
|
@@ -16676,7 +16812,7 @@ async function addFirestoreRules(graph, services) {
|
|
|
16676
16812
|
if (guards.size === 0) return { nodesAdded: 0, edgesAdded: 0 };
|
|
16677
16813
|
graph.forEachNode((id, attrs) => {
|
|
16678
16814
|
const node = attrs;
|
|
16679
|
-
if (node.type !==
|
|
16815
|
+
if (node.type !== import_types59.NodeType.InfraNode) return;
|
|
16680
16816
|
if (node.kind !== FIRESTORE_COLLECTION_KIND) return;
|
|
16681
16817
|
const fields = guards.get(collectionKeyFromName(node.name));
|
|
16682
16818
|
if (!fields || fields.size === 0) return;
|
|
@@ -16695,12 +16831,12 @@ var import_node_path71 = __toESM(require("path"), 1);
|
|
|
16695
16831
|
init_cjs_shims();
|
|
16696
16832
|
var import_node_fs35 = require("fs");
|
|
16697
16833
|
var import_node_path70 = __toESM(require("path"), 1);
|
|
16698
|
-
var
|
|
16834
|
+
var import_types60 = require("@neat.is/types");
|
|
16699
16835
|
function dropOrphanedFileNodes(graph, source) {
|
|
16700
16836
|
const orphans = [];
|
|
16701
16837
|
graph.forEachNode((id, attrs) => {
|
|
16702
16838
|
const node = attrs;
|
|
16703
|
-
if (node.type !==
|
|
16839
|
+
if (node.type !== import_types60.NodeType.FileNode) return;
|
|
16704
16840
|
if (source && node.source !== source) return;
|
|
16705
16841
|
if (graph.inboundEdges(id).length === 0 && graph.outboundEdges(id).length === 0) {
|
|
16706
16842
|
orphans.push(id);
|
|
@@ -16714,7 +16850,7 @@ function retireEdgesByFile(graph, file) {
|
|
|
16714
16850
|
const toDrop = [];
|
|
16715
16851
|
graph.forEachEdge((id, attrs) => {
|
|
16716
16852
|
const edge = attrs;
|
|
16717
|
-
if (edge.provenance !==
|
|
16853
|
+
if (edge.provenance !== import_types60.Provenance.EXTRACTED) return;
|
|
16718
16854
|
if (!edge.evidence?.file) return;
|
|
16719
16855
|
if (edge.evidence.file === normalized) toDrop.push(id);
|
|
16720
16856
|
});
|
|
@@ -16727,7 +16863,7 @@ function outOfScope(graph, edge, source) {
|
|
|
16727
16863
|
for (const endpoint2 of [edge.source, edge.target]) {
|
|
16728
16864
|
if (!graph.hasNode(endpoint2)) continue;
|
|
16729
16865
|
const node = graph.getNodeAttributes(endpoint2);
|
|
16730
|
-
if (node.type !==
|
|
16866
|
+
if (node.type !== import_types60.NodeType.FileNode) continue;
|
|
16731
16867
|
return node.source !== source;
|
|
16732
16868
|
}
|
|
16733
16869
|
return false;
|
|
@@ -16737,7 +16873,7 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
|
|
|
16737
16873
|
const bases = [scanPath, ...serviceDirs];
|
|
16738
16874
|
graph.forEachEdge((id, attrs) => {
|
|
16739
16875
|
const edge = attrs;
|
|
16740
|
-
if (edge.provenance !==
|
|
16876
|
+
if (edge.provenance !== import_types60.Provenance.EXTRACTED) return;
|
|
16741
16877
|
if (outOfScope(graph, edge, source)) return;
|
|
16742
16878
|
const evidenceFile = edge.evidence?.file;
|
|
16743
16879
|
if (!evidenceFile) return;
|
|
@@ -16756,7 +16892,23 @@ function retireExtractedEdgesByMissingFile(graph, scanPath, serviceDirs = [], so
|
|
|
16756
16892
|
// src/extract/index.ts
|
|
16757
16893
|
var passQueue = Promise.resolve();
|
|
16758
16894
|
function extractFromDirectory(graph, scanPath, opts = {}) {
|
|
16759
|
-
|
|
16895
|
+
invalidateSourceBaseline(graph, opts.source, "syncing");
|
|
16896
|
+
const pass = passQueue.then(async () => {
|
|
16897
|
+
const sourceGeneration = beginSourceExtraction(graph, opts.source, opts.sourceCommit);
|
|
16898
|
+
let result;
|
|
16899
|
+
try {
|
|
16900
|
+
result = await runExtractionPass(graph, scanPath, opts);
|
|
16901
|
+
return result;
|
|
16902
|
+
} finally {
|
|
16903
|
+
finishSourceExtraction(
|
|
16904
|
+
graph,
|
|
16905
|
+
sourceGeneration,
|
|
16906
|
+
opts.source,
|
|
16907
|
+
opts.sourceCommit,
|
|
16908
|
+
result ?? { extractionErrors: 1, skippedFiles: 0 }
|
|
16909
|
+
);
|
|
16910
|
+
}
|
|
16911
|
+
});
|
|
16760
16912
|
passQueue = pass.catch(() => {
|
|
16761
16913
|
});
|
|
16762
16914
|
return pass;
|
|
@@ -16850,39 +17002,39 @@ async function runExtractionPass(graph, scanPath, opts) {
|
|
|
16850
17002
|
|
|
16851
17003
|
// src/divergences.ts
|
|
16852
17004
|
init_cjs_shims();
|
|
16853
|
-
var
|
|
17005
|
+
var import_types61 = require("@neat.is/types");
|
|
16854
17006
|
function bucketKey(source, target, type) {
|
|
16855
17007
|
return `${type}|${source}|${target}`;
|
|
16856
17008
|
}
|
|
16857
17009
|
function bucketSourceFor(graph, edge) {
|
|
16858
|
-
if (edge.type !==
|
|
16859
|
-
const parsed = (0,
|
|
17010
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) return edge.source;
|
|
17011
|
+
const parsed = (0, import_types61.parseFileId)(edge.source);
|
|
16860
17012
|
if (!parsed || !graph.hasNode(edge.target)) return edge.source;
|
|
16861
17013
|
const target = graph.getNodeAttributes(edge.target);
|
|
16862
|
-
if (target.type !==
|
|
16863
|
-
return (0,
|
|
17014
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) return edge.source;
|
|
17015
|
+
return (0, import_types61.serviceId)(parsed.service);
|
|
16864
17016
|
}
|
|
16865
17017
|
function bucketEdges(graph) {
|
|
16866
17018
|
const buckets2 = /* @__PURE__ */ new Map();
|
|
16867
17019
|
graph.forEachEdge((id, attrs) => {
|
|
16868
17020
|
const e = attrs;
|
|
16869
|
-
const parsed = (0,
|
|
17021
|
+
const parsed = (0, import_types61.parseEdgeId)(id);
|
|
16870
17022
|
const provenance2 = parsed?.provenance ?? e.provenance;
|
|
16871
17023
|
const source = bucketSourceFor(graph, e);
|
|
16872
17024
|
const key = bucketKey(source, e.target, e.type);
|
|
16873
17025
|
const cur = buckets2.get(key) ?? { source, target: e.target, type: e.type };
|
|
16874
17026
|
switch (provenance2) {
|
|
16875
|
-
case
|
|
17027
|
+
case import_types61.Provenance.EXTRACTED:
|
|
16876
17028
|
cur.extracted = e;
|
|
16877
17029
|
break;
|
|
16878
|
-
case
|
|
17030
|
+
case import_types61.Provenance.OBSERVED:
|
|
16879
17031
|
cur.observed = e;
|
|
16880
17032
|
break;
|
|
16881
|
-
case
|
|
17033
|
+
case import_types61.Provenance.INFERRED:
|
|
16882
17034
|
cur.inferred = e;
|
|
16883
17035
|
break;
|
|
16884
17036
|
default:
|
|
16885
|
-
if (e.provenance ===
|
|
17037
|
+
if (e.provenance === import_types61.Provenance.STALE) cur.stale = e;
|
|
16886
17038
|
}
|
|
16887
17039
|
buckets2.set(key, cur);
|
|
16888
17040
|
});
|
|
@@ -16891,22 +17043,22 @@ function bucketEdges(graph) {
|
|
|
16891
17043
|
function nodeIsFrontier(graph, nodeId) {
|
|
16892
17044
|
if (!graph.hasNode(nodeId)) return false;
|
|
16893
17045
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
16894
|
-
return attrs.type ===
|
|
17046
|
+
return attrs.type === import_types61.NodeType.FrontierNode;
|
|
16895
17047
|
}
|
|
16896
17048
|
function nodeIsWebsocketChannel(graph, nodeId) {
|
|
16897
17049
|
if (!graph.hasNode(nodeId)) return false;
|
|
16898
17050
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
16899
|
-
return attrs.type ===
|
|
17051
|
+
return attrs.type === import_types61.NodeType.WebSocketChannelNode;
|
|
16900
17052
|
}
|
|
16901
17053
|
function nodeIsServerAction(graph, nodeId) {
|
|
16902
17054
|
if (!graph.hasNode(nodeId)) return false;
|
|
16903
17055
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
16904
|
-
return attrs.type ===
|
|
17056
|
+
return attrs.type === import_types61.NodeType.ServerActionNode;
|
|
16905
17057
|
}
|
|
16906
17058
|
function nodeIsSymbol(graph, nodeId) {
|
|
16907
17059
|
if (!graph.hasNode(nodeId)) return false;
|
|
16908
17060
|
const attrs = graph.getNodeAttributes(nodeId);
|
|
16909
|
-
return attrs.type ===
|
|
17061
|
+
return attrs.type === import_types61.NodeType.SymbolNode;
|
|
16910
17062
|
}
|
|
16911
17063
|
function clampConfidence(n) {
|
|
16912
17064
|
if (!Number.isFinite(n)) return 0;
|
|
@@ -16926,14 +17078,14 @@ function gradedConfidence(edge) {
|
|
|
16926
17078
|
return clampConfidence(confidenceForEdge(edge));
|
|
16927
17079
|
}
|
|
16928
17080
|
var OBSERVABLE_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
16929
|
-
|
|
16930
|
-
|
|
16931
|
-
|
|
16932
|
-
|
|
17081
|
+
import_types61.EdgeType.CALLS,
|
|
17082
|
+
import_types61.EdgeType.CONNECTS_TO,
|
|
17083
|
+
import_types61.EdgeType.PUBLISHES_TO,
|
|
17084
|
+
import_types61.EdgeType.CONSUMES_FROM
|
|
16933
17085
|
]);
|
|
16934
17086
|
function detectMissingDivergences(graph, bucket) {
|
|
16935
17087
|
const out = [];
|
|
16936
|
-
if (bucket.type ===
|
|
17088
|
+
if (bucket.type === import_types61.EdgeType.CONTAINS) return out;
|
|
16937
17089
|
if (nodeIsSymbol(graph, bucket.source) || nodeIsSymbol(graph, bucket.target)) return out;
|
|
16938
17090
|
if (bucket.extracted && !bucket.observed && OBSERVABLE_EDGE_TYPES.has(bucket.type)) {
|
|
16939
17091
|
if (!nodeIsFrontier(graph, bucket.target) && !nodeIsServerAction(graph, bucket.target)) {
|
|
@@ -16975,7 +17127,7 @@ function declaredHostFor(svc) {
|
|
|
16975
17127
|
function hasExtractedConfiguredBy(graph, svcId) {
|
|
16976
17128
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
16977
17129
|
const e = graph.getEdgeAttributes(edgeId);
|
|
16978
|
-
if (e.type ===
|
|
17130
|
+
if (e.type === import_types61.EdgeType.CONFIGURED_BY && e.provenance === import_types61.Provenance.EXTRACTED) {
|
|
16979
17131
|
return true;
|
|
16980
17132
|
}
|
|
16981
17133
|
}
|
|
@@ -16988,10 +17140,10 @@ function detectHostMismatch(graph, svcId, svc) {
|
|
|
16988
17140
|
const out = [];
|
|
16989
17141
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
16990
17142
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
16991
|
-
if (edge.type !==
|
|
16992
|
-
if (edge.provenance !==
|
|
17143
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17144
|
+
if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
|
|
16993
17145
|
const target = graph.getNodeAttributes(edge.target);
|
|
16994
|
-
if (target.type !==
|
|
17146
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
16995
17147
|
const observedHost = target.host?.trim();
|
|
16996
17148
|
if (!observedHost) continue;
|
|
16997
17149
|
if (observedHost === declaredHost) continue;
|
|
@@ -17013,10 +17165,10 @@ function detectCompatDivergences(graph, svcId, svc) {
|
|
|
17013
17165
|
const deps = svc.dependencies ?? {};
|
|
17014
17166
|
for (const edgeId of graph.outboundEdges(svcId)) {
|
|
17015
17167
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
17016
|
-
if (edge.type !==
|
|
17017
|
-
if (edge.provenance !==
|
|
17168
|
+
if (edge.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17169
|
+
if (edge.provenance !== import_types61.Provenance.OBSERVED) continue;
|
|
17018
17170
|
const target = graph.getNodeAttributes(edge.target);
|
|
17019
|
-
if (target.type !==
|
|
17171
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17020
17172
|
for (const pair of compatPairs()) {
|
|
17021
17173
|
if (pair.engine !== target.engine) continue;
|
|
17022
17174
|
const declared = deps[pair.driver];
|
|
@@ -17179,11 +17331,11 @@ function symbolLocus(graph, ev) {
|
|
|
17179
17331
|
const location = filepath ? `${filepath}${lineno !== void 0 ? `:${lineno}` : ""}` : void 0;
|
|
17180
17332
|
const affected = ev.affectedNode;
|
|
17181
17333
|
const affectedInGraph = affected.length > 0 && graph.hasNode(affected);
|
|
17182
|
-
const affectedIsCode = affectedInGraph && ((0,
|
|
17334
|
+
const affectedIsCode = affectedInGraph && ((0, import_types61.parseSymbolId)(affected) !== null || (0, import_types61.parseFileId)(affected) !== null);
|
|
17183
17335
|
if (affectedIsCode) return { node: affected, ...location ? { location } : {} };
|
|
17184
17336
|
if (!location) return null;
|
|
17185
17337
|
if (affectedInGraph) return { node: affected, location };
|
|
17186
|
-
const svc = (0,
|
|
17338
|
+
const svc = (0, import_types61.serviceId)(ev.service);
|
|
17187
17339
|
if (graph.hasNode(svc)) return { node: svc, location };
|
|
17188
17340
|
return null;
|
|
17189
17341
|
}
|
|
@@ -17226,7 +17378,7 @@ function detectSymbolMismatches(graph, incidents) {
|
|
|
17226
17378
|
mismatchKind: g.kind,
|
|
17227
17379
|
...g.symbol ? { symbol: g.symbol } : {},
|
|
17228
17380
|
...g.location ? { location: g.location } : {},
|
|
17229
|
-
provenance:
|
|
17381
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17230
17382
|
incidentId: g.latest.id,
|
|
17231
17383
|
errorMessage: g.latest.errorMessage,
|
|
17232
17384
|
incidentCount: g.count,
|
|
@@ -17243,7 +17395,7 @@ var OBSERVED_FAILING_CONFIDENCE = 0.6;
|
|
|
17243
17395
|
function detectObservedFailingEdge(graph, bucket) {
|
|
17244
17396
|
if (!bucket.extracted || !bucket.observed) return [];
|
|
17245
17397
|
if (!OBSERVABLE_EDGE_TYPES.has(bucket.type)) return [];
|
|
17246
|
-
if (bucket.observed.provenance !==
|
|
17398
|
+
if (bucket.observed.provenance !== import_types61.Provenance.OBSERVED) return [];
|
|
17247
17399
|
const signal = bucket.observed.signal;
|
|
17248
17400
|
if (!signal) return [];
|
|
17249
17401
|
const { spanCount, errorCount } = signal;
|
|
@@ -17257,7 +17409,7 @@ function detectObservedFailingEdge(graph, bucket) {
|
|
|
17257
17409
|
source: bucket.source,
|
|
17258
17410
|
target: bucket.target,
|
|
17259
17411
|
failureKind: "error-rate",
|
|
17260
|
-
provenance:
|
|
17412
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17261
17413
|
edgeType: bucket.type,
|
|
17262
17414
|
observed: bucket.observed,
|
|
17263
17415
|
spanCount,
|
|
@@ -17362,7 +17514,7 @@ function detectObservedFailingIncidents(graph, incidents) {
|
|
|
17362
17514
|
source: g.node,
|
|
17363
17515
|
target: g.node,
|
|
17364
17516
|
failureKind: g.kind,
|
|
17365
|
-
provenance:
|
|
17517
|
+
provenance: import_types61.Provenance.INFERRED,
|
|
17366
17518
|
...g.location ? { location: g.location } : {},
|
|
17367
17519
|
incidentId: g.latest.id,
|
|
17368
17520
|
errorMessage: g.latest.errorMessage,
|
|
@@ -17381,24 +17533,24 @@ function involvesNode(d, nodeId) {
|
|
|
17381
17533
|
function datastoreEverObserved(graph, nodeId) {
|
|
17382
17534
|
if (!graph.hasNode(nodeId)) return false;
|
|
17383
17535
|
const n = graph.getNodeAttributes(nodeId);
|
|
17384
|
-
if (n.type ===
|
|
17536
|
+
if (n.type === import_types61.NodeType.DatabaseNode) {
|
|
17385
17537
|
const via = n.discoveredVia;
|
|
17386
17538
|
if (via === "otel" || via === "merged") return true;
|
|
17387
17539
|
}
|
|
17388
17540
|
for (const edgeId of graph.inboundEdges(nodeId)) {
|
|
17389
17541
|
const e = graph.getEdgeAttributes(edgeId);
|
|
17390
|
-
if (e.provenance ===
|
|
17542
|
+
if (e.provenance === import_types61.Provenance.OBSERVED || e.provenance === import_types61.Provenance.STALE) return true;
|
|
17391
17543
|
}
|
|
17392
17544
|
return false;
|
|
17393
17545
|
}
|
|
17394
17546
|
function serviceHasObservedSameEngineStore(graph, buckets2, serviceId17, engine, excludeTarget) {
|
|
17395
17547
|
for (const bucket of buckets2.values()) {
|
|
17396
|
-
if (bucket.type !==
|
|
17548
|
+
if (bucket.type !== import_types61.EdgeType.CONNECTS_TO) continue;
|
|
17397
17549
|
if (bucket.source !== serviceId17) continue;
|
|
17398
17550
|
if (bucket.target === excludeTarget) continue;
|
|
17399
17551
|
if (!graph.hasNode(bucket.target)) continue;
|
|
17400
17552
|
const target = graph.getNodeAttributes(bucket.target);
|
|
17401
|
-
if (target.type !==
|
|
17553
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) continue;
|
|
17402
17554
|
if (target.engine !== engine) continue;
|
|
17403
17555
|
if (bucket.observed || datastoreEverObserved(graph, bucket.target)) return true;
|
|
17404
17556
|
}
|
|
@@ -17408,10 +17560,10 @@ var DEAD_CODE_PROBE_CONFIDENCE = 0.1;
|
|
|
17408
17560
|
function dampenDeadCodeProbes(graph, buckets2, all) {
|
|
17409
17561
|
return all.map((d) => {
|
|
17410
17562
|
if (d.type !== "missing-observed") return d;
|
|
17411
|
-
if (!d.extracted || d.edgeType !==
|
|
17563
|
+
if (!d.extracted || d.edgeType !== import_types61.EdgeType.CONNECTS_TO) return d;
|
|
17412
17564
|
if (!graph.hasNode(d.target)) return d;
|
|
17413
17565
|
const target = graph.getNodeAttributes(d.target);
|
|
17414
|
-
if (target.type !==
|
|
17566
|
+
if (target.type !== import_types61.NodeType.DatabaseNode) return d;
|
|
17415
17567
|
if (d.extracted.evidence?.hostSource !== "literal") return d;
|
|
17416
17568
|
if (datastoreEverObserved(graph, d.target)) return d;
|
|
17417
17569
|
const engine = target.engine;
|
|
@@ -17431,7 +17583,7 @@ function suppressHostMismatchHalves(all) {
|
|
|
17431
17583
|
for (const d of all) {
|
|
17432
17584
|
if (d.type !== "host-mismatch") continue;
|
|
17433
17585
|
observedHalf.add(`${d.source}->${d.target}`);
|
|
17434
|
-
declaredHalf.add((0,
|
|
17586
|
+
declaredHalf.add((0, import_types61.databaseId)(d.extractedHost));
|
|
17435
17587
|
}
|
|
17436
17588
|
if (observedHalf.size === 0) return all;
|
|
17437
17589
|
return all.filter((d) => {
|
|
@@ -17451,14 +17603,14 @@ function computeDivergences(graph, opts = {}) {
|
|
|
17451
17603
|
}
|
|
17452
17604
|
graph.forEachNode((nodeId, attrs) => {
|
|
17453
17605
|
const n = attrs;
|
|
17454
|
-
if (n.type ===
|
|
17606
|
+
if (n.type === import_types61.NodeType.ServiceNode) {
|
|
17455
17607
|
const svc = n;
|
|
17456
17608
|
for (const d of detectHostMismatch(graph, nodeId, svc)) all.push(d);
|
|
17457
17609
|
for (const d of detectCompatDivergences(graph, nodeId, svc)) all.push(d);
|
|
17458
17610
|
for (const d of detectDeployDivergence(svc)) all.push(d);
|
|
17459
17611
|
return;
|
|
17460
17612
|
}
|
|
17461
|
-
if (n.type ===
|
|
17613
|
+
if (n.type === import_types61.NodeType.InfraNode && n.kind === "sql-table") {
|
|
17462
17614
|
for (const d of detectColumnDrift(n)) all.push(d);
|
|
17463
17615
|
}
|
|
17464
17616
|
});
|
|
@@ -17523,7 +17675,7 @@ function computeDivergences(graph, opts = {}) {
|
|
|
17523
17675
|
const bloc = "location" in b && b.location ? b.location : "";
|
|
17524
17676
|
return aloc.localeCompare(bloc);
|
|
17525
17677
|
});
|
|
17526
|
-
return
|
|
17678
|
+
return import_types61.DivergenceResultSchema.parse({
|
|
17527
17679
|
divergences: filtered,
|
|
17528
17680
|
totalAffected: filtered.length,
|
|
17529
17681
|
computedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -17534,7 +17686,7 @@ function computeDivergences(graph, opts = {}) {
|
|
|
17534
17686
|
init_cjs_shims();
|
|
17535
17687
|
var import_node_fs36 = require("fs");
|
|
17536
17688
|
var import_node_path72 = __toESM(require("path"), 1);
|
|
17537
|
-
var
|
|
17689
|
+
var import_types62 = require("@neat.is/types");
|
|
17538
17690
|
var SCHEMA_VERSION = 7;
|
|
17539
17691
|
function migrateV1ToV2(payload) {
|
|
17540
17692
|
const nodes = payload.graph.nodes;
|
|
@@ -17558,7 +17710,7 @@ function migrateV5ToV6(payload) {
|
|
|
17558
17710
|
if (Array.isArray(nodes)) {
|
|
17559
17711
|
for (const node of nodes) {
|
|
17560
17712
|
const attrs = node.attributes;
|
|
17561
|
-
if (!attrs || attrs.type !==
|
|
17713
|
+
if (!attrs || attrs.type !== import_types62.NodeType.InfraNode) continue;
|
|
17562
17714
|
if (attrs.kind !== "sql-table" && attrs.kind !== "supabase-table") continue;
|
|
17563
17715
|
if (!Array.isArray(attrs.columns)) attrs.columns = [];
|
|
17564
17716
|
}
|
|
@@ -17574,12 +17726,12 @@ function migrateV2ToV3(payload) {
|
|
|
17574
17726
|
for (const edge of edges) {
|
|
17575
17727
|
const attrs = edge.attributes;
|
|
17576
17728
|
if (!attrs || attrs.provenance !== "FRONTIER") continue;
|
|
17577
|
-
attrs.provenance =
|
|
17729
|
+
attrs.provenance = import_types62.Provenance.OBSERVED;
|
|
17578
17730
|
const type = typeof attrs.type === "string" ? attrs.type : void 0;
|
|
17579
17731
|
const source = typeof attrs.source === "string" ? attrs.source : void 0;
|
|
17580
17732
|
const target = typeof attrs.target === "string" ? attrs.target : void 0;
|
|
17581
17733
|
if (type && source && target) {
|
|
17582
|
-
const newId = (0,
|
|
17734
|
+
const newId = (0, import_types62.observedEdgeId)(source, target, type);
|
|
17583
17735
|
attrs.id = newId;
|
|
17584
17736
|
if (edge.key) edge.key = newId;
|
|
17585
17737
|
}
|
|
@@ -17767,7 +17919,7 @@ ${NEAT_OUT_LINE}
|
|
|
17767
17919
|
|
|
17768
17920
|
// src/summary.ts
|
|
17769
17921
|
init_cjs_shims();
|
|
17770
|
-
var
|
|
17922
|
+
var import_types63 = require("@neat.is/types");
|
|
17771
17923
|
|
|
17772
17924
|
// src/otlp-headers.ts
|
|
17773
17925
|
init_cjs_shims();
|
|
@@ -17786,19 +17938,19 @@ function renderOtelEnvBlock() {
|
|
|
17786
17938
|
}
|
|
17787
17939
|
function findIncompatServices(nodes) {
|
|
17788
17940
|
return nodes.filter(
|
|
17789
|
-
(n) => n.type ===
|
|
17941
|
+
(n) => n.type === import_types63.NodeType.ServiceNode && Array.isArray(n.incompatibilities) && (n.incompatibilities ?? []).length > 0
|
|
17790
17942
|
);
|
|
17791
17943
|
}
|
|
17792
17944
|
function servicesWithoutObserved(nodes, edges) {
|
|
17793
17945
|
const seen = /* @__PURE__ */ new Set();
|
|
17794
17946
|
for (const e of edges) {
|
|
17795
|
-
if (e.provenance ===
|
|
17947
|
+
if (e.provenance === import_types63.Provenance.OBSERVED) {
|
|
17796
17948
|
seen.add(e.source);
|
|
17797
17949
|
seen.add(e.target);
|
|
17798
17950
|
}
|
|
17799
17951
|
}
|
|
17800
17952
|
return nodes.filter(
|
|
17801
|
-
(n) => n.type ===
|
|
17953
|
+
(n) => n.type === import_types63.NodeType.ServiceNode && !seen.has(n.id)
|
|
17802
17954
|
);
|
|
17803
17955
|
}
|
|
17804
17956
|
function formatDivergence(d) {
|
|
@@ -17821,8 +17973,8 @@ function computeLanguageCoverage(nodes, edges) {
|
|
|
17821
17973
|
const nodeById = /* @__PURE__ */ new Map();
|
|
17822
17974
|
for (const n of nodes) {
|
|
17823
17975
|
nodeById.set(n.id, n);
|
|
17824
|
-
if (n.type ===
|
|
17825
|
-
else if (n.type ===
|
|
17976
|
+
if (n.type === import_types63.NodeType.ServiceNode) serviceLang.set(n.name, n.language);
|
|
17977
|
+
else if (n.type === import_types63.NodeType.FileNode) fileService.set(n.id, n.service);
|
|
17826
17978
|
}
|
|
17827
17979
|
const cov = /* @__PURE__ */ new Map();
|
|
17828
17980
|
const ensure = (lang) => {
|
|
@@ -17835,25 +17987,25 @@ function computeLanguageCoverage(nodes, edges) {
|
|
|
17835
17987
|
};
|
|
17836
17988
|
for (const lang of serviceLang.values()) ensure(lang);
|
|
17837
17989
|
for (const n of nodes) {
|
|
17838
|
-
if (n.type ===
|
|
17990
|
+
if (n.type === import_types63.NodeType.SymbolNode) {
|
|
17839
17991
|
if (n.discoveredVia === "otel") continue;
|
|
17840
17992
|
const lang = serviceLang.get(n.service);
|
|
17841
17993
|
if (lang) ensure(lang).symbols = true;
|
|
17842
|
-
} else if (n.type ===
|
|
17994
|
+
} else if (n.type === import_types63.NodeType.RouteNode) {
|
|
17843
17995
|
if (n.discoveredVia === "otel") continue;
|
|
17844
17996
|
const lang = serviceLang.get(n.service);
|
|
17845
17997
|
if (lang) ensure(lang).routes = true;
|
|
17846
17998
|
}
|
|
17847
17999
|
}
|
|
17848
18000
|
for (const e of edges) {
|
|
17849
|
-
if (e.type !==
|
|
18001
|
+
if (e.type !== import_types63.EdgeType.CALLS || e.provenance !== import_types63.Provenance.EXTRACTED) continue;
|
|
17850
18002
|
const svc = fileService.get(e.source);
|
|
17851
18003
|
const lang = svc ? serviceLang.get(svc) : void 0;
|
|
17852
18004
|
if (!lang) continue;
|
|
17853
18005
|
const target = nodeById.get(e.target);
|
|
17854
18006
|
if (!target) continue;
|
|
17855
|
-
if (target.type ===
|
|
17856
|
-
else if (target.type ===
|
|
18007
|
+
if (target.type === import_types63.NodeType.RouteNode) ensure(lang).crossServiceCalls = true;
|
|
18008
|
+
else if (target.type === import_types63.NodeType.InfraNode && isTableInfra(target.kind)) ensure(lang).data = true;
|
|
17857
18009
|
}
|
|
17858
18010
|
return cov;
|
|
17859
18011
|
}
|
|
@@ -17953,7 +18105,7 @@ init_cjs_shims();
|
|
|
17953
18105
|
var import_fastify2 = __toESM(require("fastify"), 1);
|
|
17954
18106
|
var import_node_crypto6 = require("crypto");
|
|
17955
18107
|
var import_cors = __toESM(require("@fastify/cors"), 1);
|
|
17956
|
-
var
|
|
18108
|
+
var import_types106 = require("@neat.is/types");
|
|
17957
18109
|
|
|
17958
18110
|
// src/extend/index.ts
|
|
17959
18111
|
init_cjs_shims();
|
|
@@ -18345,10 +18497,40 @@ function queryLogEntries(opts) {
|
|
|
18345
18497
|
|
|
18346
18498
|
// src/goodybag.ts
|
|
18347
18499
|
init_cjs_shims();
|
|
18348
|
-
var
|
|
18500
|
+
var import_types64 = require("@neat.is/types");
|
|
18349
18501
|
var CODE_FILEPATH_ATTR2 = "code.filepath";
|
|
18350
18502
|
var CODE_LINENO_ATTR2 = "code.lineno";
|
|
18351
18503
|
var BLAST_NEAREST_LIMIT = 5;
|
|
18504
|
+
function deployContextOf(ev) {
|
|
18505
|
+
const a = ev.attributes;
|
|
18506
|
+
if (!a) return void 0;
|
|
18507
|
+
const str = (k) => typeof a[k] === "string" ? a[k] : void 0;
|
|
18508
|
+
const int = (k) => typeof a[k] === "number" && Number.isFinite(a[k]) ? Math.trunc(a[k]) : void 0;
|
|
18509
|
+
const strs = (k) => {
|
|
18510
|
+
const v = a[k];
|
|
18511
|
+
return Array.isArray(v) && v.every((x) => typeof x === "string") && v.length > 0 ? v : void 0;
|
|
18512
|
+
};
|
|
18513
|
+
const ctx = {};
|
|
18514
|
+
const fault = str("k8s.fault");
|
|
18515
|
+
if (fault) ctx.fault = fault;
|
|
18516
|
+
const waiting = str("k8s.waitingReason");
|
|
18517
|
+
if (waiting) ctx.waitingReason = waiting;
|
|
18518
|
+
const image = str("k8s.image");
|
|
18519
|
+
if (image) ctx.image = image;
|
|
18520
|
+
const restarts = int("k8s.restartCount");
|
|
18521
|
+
if (restarts !== void 0) ctx.restartCount = restarts;
|
|
18522
|
+
const termReason = str("k8s.terminatedReason");
|
|
18523
|
+
if (termReason) ctx.terminatedReason = termReason;
|
|
18524
|
+
const exitCode = int("k8s.exitCode");
|
|
18525
|
+
if (exitCode !== void 0) ctx.exitCode = exitCode;
|
|
18526
|
+
const env = strs("k8s.containerEnv");
|
|
18527
|
+
if (env) ctx.containerEnv = env;
|
|
18528
|
+
const args = strs("k8s.containerArgs");
|
|
18529
|
+
if (args) ctx.containerArgs = args;
|
|
18530
|
+
const log = str("k8s.processLog");
|
|
18531
|
+
if (log) ctx.processLog = log;
|
|
18532
|
+
return Object.keys(ctx).length > 0 ? ctx : void 0;
|
|
18533
|
+
}
|
|
18352
18534
|
function grainOf2(graph, nodeId) {
|
|
18353
18535
|
if (graph.hasNode(nodeId)) {
|
|
18354
18536
|
const t = graph.getNodeAttributes(nodeId).type;
|
|
@@ -18371,7 +18553,7 @@ function locusOf(graph, ev) {
|
|
|
18371
18553
|
...Number.isFinite(line) ? { lineStart: line, lineEnd: line } : {},
|
|
18372
18554
|
...symbol ? { symbol } : {},
|
|
18373
18555
|
service: node?.service ?? ev.service,
|
|
18374
|
-
provenance:
|
|
18556
|
+
provenance: import_types64.Provenance.OBSERVED
|
|
18375
18557
|
};
|
|
18376
18558
|
}
|
|
18377
18559
|
function locusFromNode(graph, nodeId) {
|
|
@@ -18387,7 +18569,7 @@ function locusFromNode(graph, nodeId) {
|
|
|
18387
18569
|
...typeof end === "number" ? { lineEnd: end } : {},
|
|
18388
18570
|
...n.qualname ? { symbol: shortLabel(graph, nodeId) } : {},
|
|
18389
18571
|
...n.service ? { service: n.service } : {},
|
|
18390
|
-
provenance:
|
|
18572
|
+
provenance: import_types64.Provenance.INFERRED
|
|
18391
18573
|
};
|
|
18392
18574
|
}
|
|
18393
18575
|
function promoteCauseLocus(graph, causeNode, incidents) {
|
|
@@ -18396,11 +18578,16 @@ function promoteCauseLocus(graph, causeNode, incidents) {
|
|
|
18396
18578
|
);
|
|
18397
18579
|
if (native) {
|
|
18398
18580
|
const l = locusOf(graph, native);
|
|
18399
|
-
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance:
|
|
18581
|
+
if (l) return { ...l, symbol: shortLabel(graph, causeNode), provenance: import_types64.Provenance.INFERRED };
|
|
18400
18582
|
}
|
|
18401
18583
|
return locusFromNode(graph, causeNode);
|
|
18402
18584
|
}
|
|
18403
18585
|
function divergenceSummary(d) {
|
|
18586
|
+
if (d.type === "observed-symbol-mismatch" || d.source === d.target) {
|
|
18587
|
+
const symbol = "symbol" in d && d.symbol ? d.symbol : d.source;
|
|
18588
|
+
const at = "location" in d && d.location ? ` at ${d.location}` : "";
|
|
18589
|
+
return `${symbol}${at}`;
|
|
18590
|
+
}
|
|
18404
18591
|
const column = "column" in d && d.column ? `.${d.column}` : "";
|
|
18405
18592
|
const label = "table" in d && d.table ? `${d.table}${column}` : `${d.source} \u2192 ${d.target}`;
|
|
18406
18593
|
return label;
|
|
@@ -18445,7 +18632,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18445
18632
|
const chain = (rc.traversalPath ?? []).map((node, i) => ({
|
|
18446
18633
|
node,
|
|
18447
18634
|
grain: grainOf2(graph, node),
|
|
18448
|
-
provenance: provs[i] ?? provs[provs.length - 1] ??
|
|
18635
|
+
provenance: provs[i] ?? provs[provs.length - 1] ?? import_types64.Provenance.INFERRED
|
|
18449
18636
|
}));
|
|
18450
18637
|
rootCause = {
|
|
18451
18638
|
node: rc.rootCauseNode,
|
|
@@ -18476,7 +18663,7 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18476
18663
|
kind: "incident",
|
|
18477
18664
|
id: errorEvent.id,
|
|
18478
18665
|
at: errorEvent.timestamp,
|
|
18479
|
-
incidentKind: (0,
|
|
18666
|
+
incidentKind: (0, import_types64.incidentKindOf)(errorEvent),
|
|
18480
18667
|
service: errorEvent.service,
|
|
18481
18668
|
affectedNode: affected,
|
|
18482
18669
|
message: errorEvent.errorMessage,
|
|
@@ -18491,10 +18678,14 @@ function buildIncidentCard(graph, errorEvent, incidents, policies) {
|
|
|
18491
18678
|
...nearest.length > 0 ? { blastRadius: { totalAffected: blast.totalAffected, nearest } } : {},
|
|
18492
18679
|
...policyCards.length > 0 ? { policies: policyCards } : {},
|
|
18493
18680
|
...divergences.length > 0 ? { divergence: divergences } : {},
|
|
18681
|
+
...(() => {
|
|
18682
|
+
const dc = deployContextOf(errorEvent);
|
|
18683
|
+
return dc ? { deployContext: dc } : {};
|
|
18684
|
+
})(),
|
|
18494
18685
|
headline: renderHeadline(graph, errorEvent, locus, rootCause?.node ?? null)
|
|
18495
18686
|
};
|
|
18496
18687
|
card.grade = gradeIncidentCard(card);
|
|
18497
|
-
return
|
|
18688
|
+
return import_types64.IncidentCardSchema.parse(card);
|
|
18498
18689
|
}
|
|
18499
18690
|
var GRADE_PRIORS_VERSION = "sniper-architecture-priors-2026-10-08";
|
|
18500
18691
|
var GRADE_WEIGHTS = {
|
|
@@ -18601,7 +18792,7 @@ function gradeIncidentCard(card) {
|
|
|
18601
18792
|
|
|
18602
18793
|
// src/ask.ts
|
|
18603
18794
|
init_cjs_shims();
|
|
18604
|
-
var
|
|
18795
|
+
var import_types65 = require("@neat.is/types");
|
|
18605
18796
|
var DEFAULT_MAX_NODES = 3;
|
|
18606
18797
|
var MAX_FACTS_PER_SECTION = 6;
|
|
18607
18798
|
var INTENT_RULES = [
|
|
@@ -18837,14 +19028,23 @@ function idBody(id) {
|
|
|
18837
19028
|
return colon >= 0 ? id.slice(colon + 1) : id;
|
|
18838
19029
|
}
|
|
18839
19030
|
var TYPE_NOUNS = [
|
|
18840
|
-
{ nouns: ["database", "db", "table"], type:
|
|
18841
|
-
{ nouns: ["service", "api", "backend"], type:
|
|
18842
|
-
{ nouns: ["route", "endpoint"], type:
|
|
18843
|
-
{ nouns: ["file"], type:
|
|
18844
|
-
{ nouns: ["config"], type:
|
|
19031
|
+
{ nouns: ["database", "db", "table"], type: import_types65.NodeType.DatabaseNode },
|
|
19032
|
+
{ nouns: ["service", "api", "backend"], type: import_types65.NodeType.ServiceNode },
|
|
19033
|
+
{ nouns: ["route", "endpoint"], type: import_types65.NodeType.RouteNode },
|
|
19034
|
+
{ nouns: ["file"], type: import_types65.NodeType.FileNode },
|
|
19035
|
+
{ nouns: ["config"], type: import_types65.NodeType.ConfigNode }
|
|
18845
19036
|
];
|
|
18846
19037
|
var EMBED_MIN_SCORE = 0.35;
|
|
18847
19038
|
async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
19039
|
+
const verbatim = [];
|
|
19040
|
+
for (const word of question.split(/\s+/)) {
|
|
19041
|
+
const id = word.replace(/^["'`(<]+|["'`)>?!.,;]+$/g, "");
|
|
19042
|
+
if (!id || !graph.hasNode(id) || verbatim.some((m) => m.nodeId === id)) continue;
|
|
19043
|
+
const node = graph.getNodeAttributes(id);
|
|
19044
|
+
if (node.type === import_types65.NodeType.FrontierNode) continue;
|
|
19045
|
+
verbatim.push({ nodeId: id, label: nodeName(node), via: "id", score: 1 });
|
|
19046
|
+
}
|
|
19047
|
+
if (verbatim.length > 0) return { matched: verbatim.slice(0, maxNodes) };
|
|
18848
19048
|
const qTokens = queryTokens(question);
|
|
18849
19049
|
const normalized = question.toLowerCase();
|
|
18850
19050
|
const best = /* @__PURE__ */ new Map();
|
|
@@ -18855,7 +19055,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18855
19055
|
};
|
|
18856
19056
|
graph.forEachNode((id, attrs) => {
|
|
18857
19057
|
const node = attrs;
|
|
18858
|
-
if (node.type ===
|
|
19058
|
+
if (node.type === import_types65.NodeType.FrontierNode) return;
|
|
18859
19059
|
const name = nodeName(node);
|
|
18860
19060
|
const body = idBody(id);
|
|
18861
19061
|
const labelTokens = /* @__PURE__ */ new Set([...tokens(body), ...tokens(name)]);
|
|
@@ -18874,7 +19074,7 @@ async function resolveEntities(graph, question, searchIndex, maxNodes) {
|
|
|
18874
19074
|
const res = await searchIndex.search(question, 10);
|
|
18875
19075
|
if (res.provider !== "substring") {
|
|
18876
19076
|
for (const m of res.matches) {
|
|
18877
|
-
if (m.node.type ===
|
|
19077
|
+
if (m.node.type === import_types65.NodeType.FrontierNode) continue;
|
|
18878
19078
|
if (!graph.hasNode(m.node.id)) continue;
|
|
18879
19079
|
const already = best.get(m.node.id);
|
|
18880
19080
|
if (!already && m.score < EMBED_MIN_SCORE) continue;
|
|
@@ -18934,7 +19134,7 @@ function edgeSignalNote(e) {
|
|
|
18934
19134
|
function buildRootCauseSection(graph, node, incidents, now) {
|
|
18935
19135
|
const result = getRootCause(graph, node, void 0, incidents, { now });
|
|
18936
19136
|
if (!result) return null;
|
|
18937
|
-
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ??
|
|
19137
|
+
const lastProv = result.edgeProvenances[result.edgeProvenances.length - 1] ?? import_types65.Provenance.OBSERVED;
|
|
18938
19138
|
const facts = [
|
|
18939
19139
|
{
|
|
18940
19140
|
text: `Root cause: ${result.rootCauseNode} \u2014 ${result.rootCauseReason}`,
|
|
@@ -18984,7 +19184,7 @@ function buildObservedSection(graph, node) {
|
|
|
18984
19184
|
if (result.observed && result.inboundObservedCount > 0) {
|
|
18985
19185
|
facts.push({
|
|
18986
19186
|
text: `no outbound runtime calls, but OTel observed ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 a pure receiver`,
|
|
18987
|
-
provenance:
|
|
19187
|
+
provenance: import_types65.Provenance.OBSERVED
|
|
18988
19188
|
});
|
|
18989
19189
|
} else {
|
|
18990
19190
|
return null;
|
|
@@ -19007,10 +19207,10 @@ function buildBlastSection(graph, node) {
|
|
|
19007
19207
|
}
|
|
19008
19208
|
function buildDatabaseCallersSection(graph, node) {
|
|
19009
19209
|
const callers = getBlastRadius(graph, node).affectedNodes.filter((item) => {
|
|
19010
|
-
if (graph.getNodeAttributes(item.nodeId).type !==
|
|
19210
|
+
if (graph.getNodeAttributes(item.nodeId).type !== import_types65.NodeType.ServiceNode) return false;
|
|
19011
19211
|
return item.path.slice(1, -1).every((id) => {
|
|
19012
19212
|
const type = graph.getNodeAttributes(id).type;
|
|
19013
|
-
return type ===
|
|
19213
|
+
return type === import_types65.NodeType.FileNode || type === import_types65.NodeType.SymbolNode;
|
|
19014
19214
|
});
|
|
19015
19215
|
});
|
|
19016
19216
|
return {
|
|
@@ -19029,7 +19229,7 @@ function buildIncidentsSection(node, incidents) {
|
|
|
19029
19229
|
const facts = ordered.map((ev) => ({
|
|
19030
19230
|
text: `${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`,
|
|
19031
19231
|
// ErrorEvents are observation records — OBSERVED by definition.
|
|
19032
|
-
provenance:
|
|
19232
|
+
provenance: import_types65.Provenance.OBSERVED
|
|
19033
19233
|
}));
|
|
19034
19234
|
return { heading: `Recent incidents (OBSERVED) \u2014 ${relevant.length} recorded`, facts };
|
|
19035
19235
|
}
|
|
@@ -19052,8 +19252,8 @@ function runtimeEdgeState(graph) {
|
|
|
19052
19252
|
let observed = false;
|
|
19053
19253
|
let stale = false;
|
|
19054
19254
|
graph.forEachEdge((_id, attrs) => {
|
|
19055
|
-
if (attrs.provenance ===
|
|
19056
|
-
if (attrs.provenance ===
|
|
19255
|
+
if (attrs.provenance === import_types65.Provenance.OBSERVED) observed = true;
|
|
19256
|
+
if (attrs.provenance === import_types65.Provenance.STALE) stale = true;
|
|
19057
19257
|
});
|
|
19058
19258
|
return { observed, stale };
|
|
19059
19259
|
}
|
|
@@ -19121,7 +19321,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
19121
19321
|
}
|
|
19122
19322
|
const byKey = /* @__PURE__ */ new Map();
|
|
19123
19323
|
for (const ev of incidents) {
|
|
19124
|
-
const key = ev.affectedNode || (0,
|
|
19324
|
+
const key = ev.affectedNode || (0, import_types65.serviceId)(ev.service);
|
|
19125
19325
|
const cur = byKey.get(key);
|
|
19126
19326
|
if (!cur) {
|
|
19127
19327
|
byKey.set(key, { key, count: 1, latest: ev.timestamp, sampleMsg: ev.errorMessage });
|
|
@@ -19136,7 +19336,7 @@ function buildGlobalIncidentsSection(incidents) {
|
|
|
19136
19336
|
const rows = [...byKey.values()].sort((a, b) => b.count - a.count || b.latest.localeCompare(a.latest) || a.key.localeCompare(b.key)).slice(0, MAX_FACTS_PER_SECTION);
|
|
19137
19337
|
const facts = rows.map((r) => ({
|
|
19138
19338
|
text: `${r.key} \u2014 ${r.count} incident${r.count === 1 ? "" : "s"}, latest ${r.latest}: ${r.sampleMsg}`,
|
|
19139
|
-
provenance:
|
|
19339
|
+
provenance: import_types65.Provenance.OBSERVED
|
|
19140
19340
|
}));
|
|
19141
19341
|
return {
|
|
19142
19342
|
heading: `Incidents across the system \u2014 ${incidents.length} recorded`,
|
|
@@ -19149,7 +19349,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
19149
19349
|
graph.forEachNode((_id, attrs) => {
|
|
19150
19350
|
const node = attrs;
|
|
19151
19351
|
nodeByType.set(node.type, (nodeByType.get(node.type) ?? 0) + 1);
|
|
19152
|
-
if (node.type ===
|
|
19352
|
+
if (node.type === import_types65.NodeType.ServiceNode) services.push(node.id);
|
|
19153
19353
|
});
|
|
19154
19354
|
const edgeByProv = /* @__PURE__ */ new Map();
|
|
19155
19355
|
graph.forEachEdge((_id, attrs) => {
|
|
@@ -19161,10 +19361,10 @@ function buildOverviewSections(graph, incidents) {
|
|
|
19161
19361
|
const shapeFacts = [
|
|
19162
19362
|
{ text: `${graph.order} nodes, ${graph.size} edges` },
|
|
19163
19363
|
{
|
|
19164
|
-
text: `${count(
|
|
19364
|
+
text: `${count(import_types65.NodeType.ServiceNode)} services, ${count(import_types65.NodeType.FileNode)} files, ${count(import_types65.NodeType.SymbolNode)} symbols, ${count(import_types65.NodeType.DatabaseNode)} databases`
|
|
19165
19365
|
}
|
|
19166
19366
|
];
|
|
19167
|
-
for (const p of [
|
|
19367
|
+
for (const p of [import_types65.Provenance.EXTRACTED, import_types65.Provenance.OBSERVED, import_types65.Provenance.INFERRED, import_types65.Provenance.STALE]) {
|
|
19168
19368
|
const n = edgeByProv.get(p) ?? 0;
|
|
19169
19369
|
if (n > 0) shapeFacts.push({ text: `${n} ${p} edge${n === 1 ? "" : "s"}`, provenance: p });
|
|
19170
19370
|
}
|
|
@@ -19181,7 +19381,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
19181
19381
|
if (incidents && incidents.length > 0) {
|
|
19182
19382
|
const incCount = /* @__PURE__ */ new Map();
|
|
19183
19383
|
for (const ev of incidents) {
|
|
19184
|
-
const key = ev.affectedNode || (0,
|
|
19384
|
+
const key = ev.affectedNode || (0, import_types65.serviceId)(ev.service);
|
|
19185
19385
|
incCount.set(key, (incCount.get(key) ?? 0) + 1);
|
|
19186
19386
|
}
|
|
19187
19387
|
const top = [...incCount.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_FACTS_PER_SECTION);
|
|
@@ -19189,7 +19389,7 @@ function buildOverviewSections(graph, incidents) {
|
|
|
19189
19389
|
heading: `Nodes with incidents \u2014 ${incidents.length} recorded`,
|
|
19190
19390
|
facts: top.map(([k, n]) => ({
|
|
19191
19391
|
text: `${k} \u2014 ${n} incident${n === 1 ? "" : "s"}`,
|
|
19192
|
-
provenance:
|
|
19392
|
+
provenance: import_types65.Provenance.OBSERVED
|
|
19193
19393
|
}))
|
|
19194
19394
|
});
|
|
19195
19395
|
}
|
|
@@ -19320,7 +19520,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
19320
19520
|
let scope;
|
|
19321
19521
|
if (primary) {
|
|
19322
19522
|
scope = "node";
|
|
19323
|
-
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type ===
|
|
19523
|
+
const callersQuestion = intent === "dependencies" && graph.getNodeAttributes(primary).type === import_types65.NodeType.DatabaseNode && /\b(?:which|what)\s+services?\s+(?:talks?\s+to|connects?\s+to|uses?|hits?|calls?|reads?\s+from|writes?\s+to)\b/i.test(question);
|
|
19324
19524
|
if (callersQuestion) sections.push(buildDatabaseCallersSection(graph, primary));
|
|
19325
19525
|
for (const kind of SECTION_ORDER[intent]) {
|
|
19326
19526
|
if (callersQuestion && kind === "blast") continue;
|
|
@@ -19338,7 +19538,7 @@ async function askGraph(graph, question, opts = {}) {
|
|
|
19338
19538
|
const provSet = /* @__PURE__ */ new Set();
|
|
19339
19539
|
for (const s of sections) for (const f of s.facts) if (f.provenance) provSet.add(f.provenance);
|
|
19340
19540
|
const confidence = sections[0]?.facts[0]?.confidence;
|
|
19341
|
-
return
|
|
19541
|
+
return import_types65.AskResultSchema.parse({
|
|
19342
19542
|
question,
|
|
19343
19543
|
intent,
|
|
19344
19544
|
matched,
|
|
@@ -19485,7 +19685,7 @@ init_cjs_shims();
|
|
|
19485
19685
|
var import_node_fs41 = require("fs");
|
|
19486
19686
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
19487
19687
|
var import_node_path77 = __toESM(require("path"), 1);
|
|
19488
|
-
var
|
|
19688
|
+
var import_types66 = require("@neat.is/types");
|
|
19489
19689
|
var LOCK_TIMEOUT_MS = 5e3;
|
|
19490
19690
|
var LOCK_RETRY_MS = 50;
|
|
19491
19691
|
function neatHome() {
|
|
@@ -19755,10 +19955,10 @@ async function readRegistry() {
|
|
|
19755
19955
|
throw err;
|
|
19756
19956
|
}
|
|
19757
19957
|
const parsed = JSON.parse(raw);
|
|
19758
|
-
return
|
|
19958
|
+
return import_types66.RegistryFileSchema.parse(parsed);
|
|
19759
19959
|
}
|
|
19760
19960
|
async function writeRegistry(reg) {
|
|
19761
|
-
const validated =
|
|
19961
|
+
const validated = import_types66.RegistryFileSchema.parse(reg);
|
|
19762
19962
|
await writeAtomically(registryPath(), JSON.stringify(validated, null, 2) + "\n");
|
|
19763
19963
|
}
|
|
19764
19964
|
var RegistryError = class extends Error {
|
|
@@ -19908,11 +20108,11 @@ async function pruneRegistry(opts = {}) {
|
|
|
19908
20108
|
init_cjs_shims();
|
|
19909
20109
|
var import_node_fs42 = require("fs");
|
|
19910
20110
|
var import_zod = require("zod");
|
|
19911
|
-
var
|
|
20111
|
+
var import_types67 = require("@neat.is/types");
|
|
19912
20112
|
var SSE_HEARTBEAT_MS = 3e4;
|
|
19913
20113
|
var SSE_BACKPRESSURE_CAP = 1e3;
|
|
19914
20114
|
var INCIDENT_TRIGGER_STREAM_SCOPE = "incident-only-v1";
|
|
19915
|
-
var IncidentTriggerSchema =
|
|
20115
|
+
var IncidentTriggerSchema = import_types67.IncidentEventPayloadSchema.extend({
|
|
19916
20116
|
incidentId: import_zod.z.string().regex(/^[A-Za-z0-9:_-]{1,100}$/),
|
|
19917
20117
|
affectedNode: import_zod.z.string().min(1).max(512),
|
|
19918
20118
|
service: import_zod.z.string().min(1).max(256),
|
|
@@ -19940,12 +20140,12 @@ function loadIncidentReplay(errorsPath, cursor) {
|
|
|
19940
20140
|
if (!isExtractionFailure(row)) throw new Error("incident replay unavailable");
|
|
19941
20141
|
continue;
|
|
19942
20142
|
}
|
|
19943
|
-
const event =
|
|
20143
|
+
const event = import_types67.ErrorEventSchema.parse(row);
|
|
19944
20144
|
const trigger = IncidentTriggerSchema.parse({
|
|
19945
20145
|
incidentId: event.id,
|
|
19946
20146
|
affectedNode: event.affectedNode,
|
|
19947
20147
|
service: event.service,
|
|
19948
|
-
incidentKind: (0,
|
|
20148
|
+
incidentKind: (0, import_types67.incidentKindOf)(event),
|
|
19949
20149
|
at: event.timestamp
|
|
19950
20150
|
});
|
|
19951
20151
|
const prior = seen.get(trigger.incidentId), encoded = JSON.stringify(trigger);
|
|
@@ -20320,7 +20520,7 @@ function renderVerdict({
|
|
|
20320
20520
|
}
|
|
20321
20521
|
|
|
20322
20522
|
// src/pr-verdict.ts
|
|
20323
|
-
var
|
|
20523
|
+
var import_types68 = require("@neat.is/types");
|
|
20324
20524
|
|
|
20325
20525
|
// src/connectors/hosted-repos.ts
|
|
20326
20526
|
init_cjs_shims();
|
|
@@ -20393,7 +20593,7 @@ var PrVerdictError = class extends Error {
|
|
|
20393
20593
|
details;
|
|
20394
20594
|
};
|
|
20395
20595
|
function parsePrVerdictRequest(body) {
|
|
20396
|
-
const parsed =
|
|
20596
|
+
const parsed = import_types68.PrVerdictBodySchema.safeParse(body);
|
|
20397
20597
|
if (!parsed.success) {
|
|
20398
20598
|
throw new PrVerdictError("invalid pr-verdict body", 400, void 0, parsed.error.issues);
|
|
20399
20599
|
}
|
|
@@ -20863,15 +21063,15 @@ function getConnectorStatus(id, now = Date.now(), thresholdMs = CONNECTOR_STALE_
|
|
|
20863
21063
|
|
|
20864
21064
|
// src/connectors/index.ts
|
|
20865
21065
|
init_cjs_shims();
|
|
20866
|
-
var
|
|
21066
|
+
var import_types69 = require("@neat.is/types");
|
|
20867
21067
|
var NO_ENV = "unknown";
|
|
20868
21068
|
function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
20869
21069
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20870
21070
|
const sites = [];
|
|
20871
21071
|
for (const edgeId of graph.inboundEdges(targetNodeId)) {
|
|
20872
21072
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
20873
|
-
if (edge.provenance !==
|
|
20874
|
-
const parsed = (0,
|
|
21073
|
+
if (edge.provenance !== import_types69.Provenance.EXTRACTED) continue;
|
|
21074
|
+
const parsed = (0, import_types69.parseFileId)(edge.source);
|
|
20875
21075
|
if (!parsed || parsed.service !== serviceName || !edge.evidence) continue;
|
|
20876
21076
|
const site = { relPath: edge.evidence.file };
|
|
20877
21077
|
if (edge.evidence.line !== void 0) site.line = edge.evidence.line;
|
|
@@ -20882,7 +21082,7 @@ function staticCallSiteFor(graph, serviceName, targetNodeId) {
|
|
|
20882
21082
|
function routeCallSiteFor(graph, targetNodeId) {
|
|
20883
21083
|
if (!graph.hasNode(targetNodeId)) return void 0;
|
|
20884
21084
|
const attrs = graph.getNodeAttributes(targetNodeId);
|
|
20885
|
-
if (attrs.type !==
|
|
21085
|
+
if (attrs.type !== import_types69.NodeType.RouteNode || !attrs.path) return void 0;
|
|
20886
21086
|
const site = { relPath: attrs.path };
|
|
20887
21087
|
if (attrs.line !== void 0) site.line = attrs.line;
|
|
20888
21088
|
return site;
|
|
@@ -21606,23 +21806,23 @@ async function fetchPgStatStatements(connectionString, limit = DEFAULT_STATEMENT
|
|
|
21606
21806
|
|
|
21607
21807
|
// src/connectors/supabase/resolve.ts
|
|
21608
21808
|
init_cjs_shims();
|
|
21609
|
-
var
|
|
21809
|
+
var import_types71 = require("@neat.is/types");
|
|
21610
21810
|
function createSupabaseResolveTarget(graph, config) {
|
|
21611
21811
|
return (signal, _ctx) => {
|
|
21612
21812
|
if (signal.targetKind !== SUPABASE_TABLE_TARGET_KIND && signal.targetKind !== SUPABASE_RPC_TARGET_KIND) {
|
|
21613
21813
|
return null;
|
|
21614
21814
|
}
|
|
21615
|
-
const subResourceId = (0,
|
|
21815
|
+
const subResourceId = (0, import_types71.infraId)(signal.targetKind, `${config.nodeRef}/${signal.targetName}`);
|
|
21616
21816
|
if (graph.hasNode(subResourceId)) {
|
|
21617
|
-
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType:
|
|
21817
|
+
return { targetNodeId: subResourceId, serviceName: config.serviceName, edgeType: import_types71.EdgeType.CALLS };
|
|
21618
21818
|
}
|
|
21619
|
-
const bareResourceId = (0,
|
|
21819
|
+
const bareResourceId = (0, import_types71.infraId)(signal.targetKind, signal.targetName);
|
|
21620
21820
|
if (graph.hasNode(bareResourceId)) {
|
|
21621
|
-
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType:
|
|
21821
|
+
return { targetNodeId: bareResourceId, serviceName: config.serviceName, edgeType: import_types71.EdgeType.CALLS };
|
|
21622
21822
|
}
|
|
21623
|
-
const projectLevelId = (0,
|
|
21823
|
+
const projectLevelId = (0, import_types71.infraId)("supabase", config.nodeRef);
|
|
21624
21824
|
if (graph.hasNode(projectLevelId)) {
|
|
21625
|
-
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType:
|
|
21825
|
+
return { targetNodeId: projectLevelId, serviceName: config.serviceName, edgeType: import_types71.EdgeType.CALLS };
|
|
21626
21826
|
}
|
|
21627
21827
|
return null;
|
|
21628
21828
|
};
|
|
@@ -21715,7 +21915,7 @@ function createSupabaseConnector(graph, config, deps = {}) {
|
|
|
21715
21915
|
|
|
21716
21916
|
// src/connectors/railway/index.ts
|
|
21717
21917
|
init_cjs_shims();
|
|
21718
|
-
var
|
|
21918
|
+
var import_types75 = require("@neat.is/types");
|
|
21719
21919
|
|
|
21720
21920
|
// src/connectors/railway/client.ts
|
|
21721
21921
|
init_cjs_shims();
|
|
@@ -21866,7 +22066,7 @@ function buildRailwayRouteIndex(graph, serviceName) {
|
|
|
21866
22066
|
const out = [];
|
|
21867
22067
|
graph.forEachNode((_id, attrs) => {
|
|
21868
22068
|
const node = attrs;
|
|
21869
|
-
if (node.type !==
|
|
22069
|
+
if (node.type !== import_types75.NodeType.RouteNode) return;
|
|
21870
22070
|
const route = attrs;
|
|
21871
22071
|
if (route.service !== serviceName) return;
|
|
21872
22072
|
out.push({
|
|
@@ -21970,12 +22170,12 @@ function createRailwayResolveTarget(config) {
|
|
|
21970
22170
|
const serviceName = config.serviceNameById[config.serviceId];
|
|
21971
22171
|
if (!serviceName) return null;
|
|
21972
22172
|
if (signal.targetKind === ROUTE_TARGET_KIND) {
|
|
21973
|
-
return { targetNodeId: signal.targetName, serviceName, edgeType:
|
|
22173
|
+
return { targetNodeId: signal.targetName, serviceName, edgeType: import_types75.EdgeType.CALLS };
|
|
21974
22174
|
}
|
|
21975
22175
|
if (signal.targetKind === PEER_SERVICE_TARGET_KIND) {
|
|
21976
22176
|
const peerName = config.serviceNameById[signal.targetName];
|
|
21977
22177
|
if (!peerName) return null;
|
|
21978
|
-
return { targetNodeId: (0,
|
|
22178
|
+
return { targetNodeId: (0, import_types75.serviceId)(peerName), serviceName, edgeType: import_types75.EdgeType.CONNECTS_TO };
|
|
21979
22179
|
}
|
|
21980
22180
|
return null;
|
|
21981
22181
|
};
|
|
@@ -22163,11 +22363,11 @@ function mapLogEntriesToSignals(entries) {
|
|
|
22163
22363
|
|
|
22164
22364
|
// src/connectors/firebase/resolve.ts
|
|
22165
22365
|
init_cjs_shims();
|
|
22166
|
-
var
|
|
22366
|
+
var import_types77 = require("@neat.is/types");
|
|
22167
22367
|
|
|
22168
22368
|
// src/connectors/infer-service.ts
|
|
22169
22369
|
init_cjs_shims();
|
|
22170
|
-
var
|
|
22370
|
+
var import_types76 = require("@neat.is/types");
|
|
22171
22371
|
function normalizeName(name) {
|
|
22172
22372
|
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
22173
22373
|
}
|
|
@@ -22178,11 +22378,11 @@ function inferServiceName(graph, resourceName, method, path104) {
|
|
|
22178
22378
|
const owners = /* @__PURE__ */ new Set();
|
|
22179
22379
|
graph.forEachNode((_id, attrs) => {
|
|
22180
22380
|
const node = attrs;
|
|
22181
|
-
if (node.type ===
|
|
22381
|
+
if (node.type === import_types76.NodeType.ServiceNode && typeof node.name === "string") {
|
|
22182
22382
|
services.push(node.name);
|
|
22183
22383
|
return;
|
|
22184
22384
|
}
|
|
22185
|
-
if (node.type !==
|
|
22385
|
+
if (node.type !== import_types76.NodeType.RouteNode) return;
|
|
22186
22386
|
const route = attrs;
|
|
22187
22387
|
if (!route.pathTemplate || normalizePathTemplate(route.pathTemplate) !== wantedPath) return;
|
|
22188
22388
|
const routeMethod = route.method.toUpperCase();
|
|
@@ -22209,7 +22409,7 @@ function routeEntriesFor(graph, serviceName) {
|
|
|
22209
22409
|
const entries = [];
|
|
22210
22410
|
graph.forEachNode((_id, attrs) => {
|
|
22211
22411
|
const node = attrs;
|
|
22212
|
-
if (node.type !==
|
|
22412
|
+
if (node.type !== import_types77.NodeType.RouteNode) return;
|
|
22213
22413
|
const route = attrs;
|
|
22214
22414
|
if (route.service !== serviceName) return;
|
|
22215
22415
|
entries.push({
|
|
@@ -22241,7 +22441,7 @@ function createFirebaseResolveTarget(graph, serviceMap) {
|
|
|
22241
22441
|
return {
|
|
22242
22442
|
targetNodeId: match.routeNodeId,
|
|
22243
22443
|
serviceName,
|
|
22244
|
-
edgeType:
|
|
22444
|
+
edgeType: import_types77.EdgeType.CALLS
|
|
22245
22445
|
};
|
|
22246
22446
|
};
|
|
22247
22447
|
}
|
|
@@ -22274,7 +22474,7 @@ init_cjs_shims();
|
|
|
22274
22474
|
|
|
22275
22475
|
// src/connectors/cloudflare/connector.ts
|
|
22276
22476
|
init_cjs_shims();
|
|
22277
|
-
var
|
|
22477
|
+
var import_types79 = require("@neat.is/types");
|
|
22278
22478
|
|
|
22279
22479
|
// src/connectors/cloudflare/client.ts
|
|
22280
22480
|
init_cjs_shims();
|
|
@@ -22438,7 +22638,7 @@ function findTaggedWorkerFileNode(graph, workerName) {
|
|
|
22438
22638
|
graph.forEachNode((id, attrs) => {
|
|
22439
22639
|
if (found) return;
|
|
22440
22640
|
const a = attrs;
|
|
22441
|
-
if (a.type ===
|
|
22641
|
+
if (a.type === import_types79.NodeType.FileNode && a.platform === "cloudflare" && a.platformName === workerName) {
|
|
22442
22642
|
found = id;
|
|
22443
22643
|
}
|
|
22444
22644
|
});
|
|
@@ -22450,7 +22650,7 @@ function findMatchingRouteNode(graph, serviceName, method, path104) {
|
|
|
22450
22650
|
graph.forEachNode((id, attrs) => {
|
|
22451
22651
|
if (found) return;
|
|
22452
22652
|
const a = attrs;
|
|
22453
|
-
if (a.type !==
|
|
22653
|
+
if (a.type !== import_types79.NodeType.RouteNode || a.service !== serviceName) return;
|
|
22454
22654
|
if (!a.pathTemplate || normalizePathTemplate(a.pathTemplate) !== normalizedPath) return;
|
|
22455
22655
|
const routeMethod = (a.method ?? "").toUpperCase();
|
|
22456
22656
|
if (routeMethod !== "ALL" && routeMethod !== method) return;
|
|
@@ -22469,11 +22669,11 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22469
22669
|
};
|
|
22470
22670
|
const mapping = config.workers?.[scriptName];
|
|
22471
22671
|
if (mapping) {
|
|
22472
|
-
const wholeFileId = (0,
|
|
22672
|
+
const wholeFileId = (0, import_types79.fileId)(mapping.service, mapping.entryFile);
|
|
22473
22673
|
return {
|
|
22474
22674
|
targetNodeId: resolveRouteGrain(mapping.service, wholeFileId),
|
|
22475
22675
|
serviceName: mapping.service,
|
|
22476
|
-
edgeType:
|
|
22676
|
+
edgeType: import_types79.EdgeType.CALLS
|
|
22477
22677
|
};
|
|
22478
22678
|
}
|
|
22479
22679
|
const taggedFileId = findTaggedWorkerFileNode(graph, scriptName);
|
|
@@ -22482,13 +22682,13 @@ function createCloudflareResolveTarget(config, graph) {
|
|
|
22482
22682
|
return {
|
|
22483
22683
|
targetNodeId: resolveRouteGrain(fileNode.service, taggedFileId),
|
|
22484
22684
|
serviceName: fileNode.service,
|
|
22485
|
-
edgeType:
|
|
22685
|
+
edgeType: import_types79.EdgeType.CALLS
|
|
22486
22686
|
};
|
|
22487
22687
|
}
|
|
22488
22688
|
return {
|
|
22489
|
-
targetNodeId: (0,
|
|
22689
|
+
targetNodeId: (0, import_types79.infraId)("cloudflare-worker", scriptName),
|
|
22490
22690
|
serviceName: scriptName,
|
|
22491
|
-
edgeType:
|
|
22691
|
+
edgeType: import_types79.EdgeType.CALLS,
|
|
22492
22692
|
ensureInfraNode: { kind: "cloudflare-worker", name: scriptName, provider: "cloudflare" }
|
|
22493
22693
|
};
|
|
22494
22694
|
};
|
|
@@ -22684,14 +22884,14 @@ function diffNeonStatementsToSignals(rows, previous, observedAtIso) {
|
|
|
22684
22884
|
|
|
22685
22885
|
// src/connectors/neon/resolve.ts
|
|
22686
22886
|
init_cjs_shims();
|
|
22687
|
-
var
|
|
22887
|
+
var import_types83 = require("@neat.is/types");
|
|
22688
22888
|
function createNeonResolveTarget(config) {
|
|
22689
22889
|
return (signal) => {
|
|
22690
22890
|
if (signal.targetKind !== NEON_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
22691
22891
|
return {
|
|
22692
|
-
targetNodeId: (0,
|
|
22892
|
+
targetNodeId: (0, import_types83.infraId)("sql-table", signal.targetName),
|
|
22693
22893
|
serviceName: config.serviceName,
|
|
22694
|
-
edgeType:
|
|
22894
|
+
edgeType: import_types83.EdgeType.CALLS,
|
|
22695
22895
|
ensureInfraNode: { kind: "sql-table", name: signal.targetName, provider: "neon" }
|
|
22696
22896
|
};
|
|
22697
22897
|
};
|
|
@@ -22872,14 +23072,14 @@ function mapLogEntriesToSignals2(entries) {
|
|
|
22872
23072
|
|
|
22873
23073
|
// src/connectors/cloud-run/resolve.ts
|
|
22874
23074
|
init_cjs_shims();
|
|
22875
|
-
var
|
|
23075
|
+
var import_types87 = require("@neat.is/types");
|
|
22876
23076
|
var CLOUD_RUN_SERVICE_INFRA_KIND = "cloud-run-service";
|
|
22877
23077
|
function findMatchingRouteNode2(graph, serviceName, method, normalizedPath) {
|
|
22878
23078
|
let found = null;
|
|
22879
23079
|
graph.forEachNode((_id, attrs) => {
|
|
22880
23080
|
if (found) return;
|
|
22881
23081
|
const node = attrs;
|
|
22882
|
-
if (node.type !==
|
|
23082
|
+
if (node.type !== import_types87.NodeType.RouteNode) return;
|
|
22883
23083
|
const route = attrs;
|
|
22884
23084
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
22885
23085
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -22904,13 +23104,13 @@ function createCloudRunResolveTarget(graph, config) {
|
|
|
22904
23104
|
normalizePathTemplate(path104)
|
|
22905
23105
|
);
|
|
22906
23106
|
if (routeNodeId) {
|
|
22907
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
23107
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types87.EdgeType.CALLS };
|
|
22908
23108
|
}
|
|
22909
23109
|
}
|
|
22910
23110
|
return {
|
|
22911
|
-
targetNodeId: (0,
|
|
23111
|
+
targetNodeId: (0, import_types87.infraId)(CLOUD_RUN_SERVICE_INFRA_KIND, gcpServiceName),
|
|
22912
23112
|
serviceName: mappedService ?? gcpServiceName,
|
|
22913
|
-
edgeType:
|
|
23113
|
+
edgeType: import_types87.EdgeType.CALLS,
|
|
22914
23114
|
ensureInfraNode: {
|
|
22915
23115
|
kind: CLOUD_RUN_SERVICE_INFRA_KIND,
|
|
22916
23116
|
name: gcpServiceName,
|
|
@@ -23092,14 +23292,14 @@ function mapLogEntriesToSignals3(entries) {
|
|
|
23092
23292
|
|
|
23093
23293
|
// src/connectors/gcp-lb/resolve.ts
|
|
23094
23294
|
init_cjs_shims();
|
|
23095
|
-
var
|
|
23295
|
+
var import_types91 = require("@neat.is/types");
|
|
23096
23296
|
var GCP_LB_BACKEND_INFRA_KIND = "gcp-lb-backend";
|
|
23097
23297
|
function findMatchingRouteNode3(graph, serviceName, method, normalizedPath) {
|
|
23098
23298
|
let found = null;
|
|
23099
23299
|
graph.forEachNode((_id, attrs) => {
|
|
23100
23300
|
if (found) return;
|
|
23101
23301
|
const node = attrs;
|
|
23102
|
-
if (node.type !==
|
|
23302
|
+
if (node.type !== import_types91.NodeType.RouteNode) return;
|
|
23103
23303
|
const route = attrs;
|
|
23104
23304
|
if (route.service !== serviceName || !route.pathTemplate) return;
|
|
23105
23305
|
if (normalizePathTemplate(route.pathTemplate) !== normalizedPath) return;
|
|
@@ -23124,13 +23324,13 @@ function createGcpLbResolveTarget(graph, config) {
|
|
|
23124
23324
|
normalizePathTemplate(path104)
|
|
23125
23325
|
);
|
|
23126
23326
|
if (routeNodeId) {
|
|
23127
|
-
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType:
|
|
23327
|
+
return { targetNodeId: routeNodeId, serviceName: mappedService, edgeType: import_types91.EdgeType.CALLS };
|
|
23128
23328
|
}
|
|
23129
23329
|
}
|
|
23130
23330
|
return {
|
|
23131
|
-
targetNodeId: (0,
|
|
23331
|
+
targetNodeId: (0, import_types91.infraId)(GCP_LB_BACKEND_INFRA_KIND, backendServiceName),
|
|
23132
23332
|
serviceName: mappedService ?? backendServiceName,
|
|
23133
|
-
edgeType:
|
|
23333
|
+
edgeType: import_types91.EdgeType.CALLS,
|
|
23134
23334
|
ensureInfraNode: {
|
|
23135
23335
|
kind: GCP_LB_BACKEND_INFRA_KIND,
|
|
23136
23336
|
name: backendServiceName,
|
|
@@ -23171,7 +23371,7 @@ function createGcpLbConnector(graph, config = {}) {
|
|
|
23171
23371
|
|
|
23172
23372
|
// src/connectors/render/index.ts
|
|
23173
23373
|
init_cjs_shims();
|
|
23174
|
-
var
|
|
23374
|
+
var import_types94 = require("@neat.is/types");
|
|
23175
23375
|
|
|
23176
23376
|
// src/connectors/render/types.ts
|
|
23177
23377
|
init_cjs_shims();
|
|
@@ -23249,7 +23449,7 @@ function buildRenderRouteIndex(graph, serviceName) {
|
|
|
23249
23449
|
const out = [];
|
|
23250
23450
|
graph.forEachNode((_id, attrs) => {
|
|
23251
23451
|
const node = attrs;
|
|
23252
|
-
if (node.type !==
|
|
23452
|
+
if (node.type !== import_types94.NodeType.RouteNode) return;
|
|
23253
23453
|
const route = attrs;
|
|
23254
23454
|
if (route.service !== serviceName) return;
|
|
23255
23455
|
out.push({
|
|
@@ -23334,7 +23534,7 @@ function mapRenderRequestLogsToSignals(entries, routeIndex) {
|
|
|
23334
23534
|
function createRenderResolveTarget(config) {
|
|
23335
23535
|
return (signal) => {
|
|
23336
23536
|
if (signal.targetKind === ROUTE_TARGET_KIND2) {
|
|
23337
|
-
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType:
|
|
23537
|
+
return { targetNodeId: signal.targetName, serviceName: config.serviceName, edgeType: import_types94.EdgeType.CALLS };
|
|
23338
23538
|
}
|
|
23339
23539
|
return null;
|
|
23340
23540
|
};
|
|
@@ -23472,21 +23672,21 @@ function mapInsightsToSignals(rows, observedAtIso) {
|
|
|
23472
23672
|
|
|
23473
23673
|
// src/connectors/planetscale/resolve.ts
|
|
23474
23674
|
init_cjs_shims();
|
|
23475
|
-
var
|
|
23675
|
+
var import_types98 = require("@neat.is/types");
|
|
23476
23676
|
var PLANETSCALE_DATABASE_KIND = "planetscale-database";
|
|
23477
23677
|
function createPlanetscaleResolveTarget(graph, config) {
|
|
23478
23678
|
const databaseName = `${config.organization}/${config.database}`;
|
|
23479
23679
|
return (signal, _ctx) => {
|
|
23480
23680
|
if (signal.targetKind !== PLANETSCALE_SQL_TABLE_TARGET_KIND || !signal.targetName) return null;
|
|
23481
|
-
const tableId = (0,
|
|
23681
|
+
const tableId = (0, import_types98.infraId)("sql-table", signal.targetName);
|
|
23482
23682
|
if (graph.hasNode(tableId)) {
|
|
23483
|
-
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType:
|
|
23683
|
+
return { targetNodeId: tableId, serviceName: config.serviceName, edgeType: import_types98.EdgeType.CALLS };
|
|
23484
23684
|
}
|
|
23485
|
-
const providerId = (0,
|
|
23685
|
+
const providerId = (0, import_types98.infraId)(PLANETSCALE_DATABASE_KIND, databaseName);
|
|
23486
23686
|
return {
|
|
23487
23687
|
targetNodeId: providerId,
|
|
23488
23688
|
serviceName: config.serviceName,
|
|
23489
|
-
edgeType:
|
|
23689
|
+
edgeType: import_types98.EdgeType.CALLS,
|
|
23490
23690
|
ensureInfraNode: { kind: PLANETSCALE_DATABASE_KIND, name: databaseName, provider: "planetscale" }
|
|
23491
23691
|
};
|
|
23492
23692
|
};
|
|
@@ -23751,7 +23951,7 @@ function mapBuildsToSignals(builds, serviceName) {
|
|
|
23751
23951
|
|
|
23752
23952
|
// src/connectors/eas/resolve.ts
|
|
23753
23953
|
init_cjs_shims();
|
|
23754
|
-
var
|
|
23954
|
+
var import_types103 = require("@neat.is/types");
|
|
23755
23955
|
var NO_ENV2 = "unknown";
|
|
23756
23956
|
var EAS_JSON_PHASES = /* @__PURE__ */ new Set(["READ_EAS_JSON"]);
|
|
23757
23957
|
var APP_CONFIG_PHASES = /* @__PURE__ */ new Set([
|
|
@@ -23767,8 +23967,8 @@ function configBasenamesForPhase(phase) {
|
|
|
23767
23967
|
function configNodeService(graph, configNodeId) {
|
|
23768
23968
|
for (const edgeId of graph.inboundEdges(configNodeId)) {
|
|
23769
23969
|
const edge = graph.getEdgeAttributes(edgeId);
|
|
23770
|
-
if (edge.type !==
|
|
23771
|
-
const parsed = (0,
|
|
23970
|
+
if (edge.type !== import_types103.EdgeType.CONFIGURED_BY) continue;
|
|
23971
|
+
const parsed = (0, import_types103.parseFileId)(edge.source);
|
|
23772
23972
|
if (parsed) return parsed.service;
|
|
23773
23973
|
}
|
|
23774
23974
|
return null;
|
|
@@ -23779,7 +23979,7 @@ function findConfigNode(graph, basenames, serviceName) {
|
|
|
23779
23979
|
graph.forEachNode((id, attrs) => {
|
|
23780
23980
|
if (scoped) return;
|
|
23781
23981
|
const node = attrs;
|
|
23782
|
-
if (node.type !==
|
|
23982
|
+
if (node.type !== import_types103.NodeType.ConfigNode) return;
|
|
23783
23983
|
if (typeof node.name !== "string" || !basenames.includes(node.name)) return;
|
|
23784
23984
|
if (anyMatch === null) anyMatch = id;
|
|
23785
23985
|
if (configNodeService(graph, id) === serviceName) scoped = id;
|
|
@@ -23796,13 +23996,13 @@ function createEasResolveTarget(graph) {
|
|
|
23796
23996
|
if (basenames.length > 0) {
|
|
23797
23997
|
const configNodeId = findConfigNode(graph, basenames, serviceName);
|
|
23798
23998
|
if (configNodeId) {
|
|
23799
|
-
return { targetNodeId: configNodeId, serviceName, edgeType:
|
|
23999
|
+
return { targetNodeId: configNodeId, serviceName, edgeType: import_types103.EdgeType.CALLS };
|
|
23800
24000
|
}
|
|
23801
24001
|
}
|
|
23802
24002
|
return {
|
|
23803
24003
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV2),
|
|
23804
24004
|
serviceName,
|
|
23805
|
-
edgeType:
|
|
24005
|
+
edgeType: import_types103.EdgeType.CALLS
|
|
23806
24006
|
};
|
|
23807
24007
|
};
|
|
23808
24008
|
}
|
|
@@ -24521,7 +24721,7 @@ function serializeGraph(graph) {
|
|
|
24521
24721
|
graph.forEachEdge((_id, attrs) => {
|
|
24522
24722
|
edges.push(attrs);
|
|
24523
24723
|
});
|
|
24524
|
-
return { nodes, edges };
|
|
24724
|
+
return { nodes, edges, sourceBaselines: readSourceBaselines(graph) };
|
|
24525
24725
|
}
|
|
24526
24726
|
function projectFromReq(req, singleProject, registry) {
|
|
24527
24727
|
const params = req.params;
|
|
@@ -24704,11 +24904,11 @@ function registerRoutes(scope, ctx) {
|
|
|
24704
24904
|
const candidates = req.query.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
24705
24905
|
const parsed = [];
|
|
24706
24906
|
for (const c of candidates) {
|
|
24707
|
-
const r =
|
|
24907
|
+
const r = import_types106.DivergenceTypeSchema.safeParse(c);
|
|
24708
24908
|
if (!r.success) {
|
|
24709
24909
|
return reply.code(400).send({
|
|
24710
24910
|
error: `unknown divergence type "${c}"`,
|
|
24711
|
-
allowed:
|
|
24911
|
+
allowed: import_types106.DivergenceTypeSchema.options
|
|
24712
24912
|
});
|
|
24713
24913
|
}
|
|
24714
24914
|
parsed.push(r.data);
|
|
@@ -25145,7 +25345,7 @@ function registerRoutes(scope, ctx) {
|
|
|
25145
25345
|
const log = new PolicyViolationsLog(proj.paths.policyViolationsPath);
|
|
25146
25346
|
let violations = await log.readAll();
|
|
25147
25347
|
if (req.query.severity) {
|
|
25148
|
-
const sev =
|
|
25348
|
+
const sev = import_types106.PolicySeveritySchema.safeParse(req.query.severity);
|
|
25149
25349
|
if (!sev.success) {
|
|
25150
25350
|
return reply.code(400).send({
|
|
25151
25351
|
error: "invalid severity",
|
|
@@ -25184,7 +25384,7 @@ function registerRoutes(scope, ctx) {
|
|
|
25184
25384
|
scope.post("/policies/check", async (req, reply) => {
|
|
25185
25385
|
const proj = resolveProject(registry, req, reply, ctx.bootstrap, ctx.singleProject);
|
|
25186
25386
|
if (!proj) return;
|
|
25187
|
-
const parsed =
|
|
25387
|
+
const parsed = import_types106.PoliciesCheckBodySchema.safeParse(req.body ?? {});
|
|
25188
25388
|
if (!parsed.success) {
|
|
25189
25389
|
return reply.code(400).send({
|
|
25190
25390
|
error: "invalid /policies/check body",
|
|
@@ -25545,7 +25745,7 @@ init_auth();
|
|
|
25545
25745
|
|
|
25546
25746
|
// src/hang-sensor.ts
|
|
25547
25747
|
init_cjs_shims();
|
|
25548
|
-
var
|
|
25748
|
+
var import_types107 = require("@neat.is/types");
|
|
25549
25749
|
var RECONCILE_INCIDENT_LIMIT = 500;
|
|
25550
25750
|
function stageHangSurfaces(graph, incidents) {
|
|
25551
25751
|
const boundaries = /* @__PURE__ */ new Set();
|
|
@@ -25558,7 +25758,7 @@ function stageHangSurfaces(graph, incidents) {
|
|
|
25558
25758
|
if (!isBoundaryTimeoutSymptom(ctx)) continue;
|
|
25559
25759
|
const hop = resolveHangHop(graph, boundary, incidents);
|
|
25560
25760
|
if (!hop) continue;
|
|
25561
|
-
if (stageFrontierEdge(graph, hop.source, hop.target,
|
|
25761
|
+
if (stageFrontierEdge(graph, hop.source, hop.target, import_types107.EdgeType.CALLS)) staged++;
|
|
25562
25762
|
}
|
|
25563
25763
|
return staged;
|
|
25564
25764
|
}
|
|
@@ -25691,6 +25891,15 @@ async function fetchPodLog(transport, namespace, podName, opts = {}) {
|
|
|
25691
25891
|
return void 0;
|
|
25692
25892
|
}
|
|
25693
25893
|
}
|
|
25894
|
+
function hasLogContent(text) {
|
|
25895
|
+
return typeof text === "string" && text.trim().length > 0;
|
|
25896
|
+
}
|
|
25897
|
+
async function fetchPodProcessLog(transport, namespace, podName, opts = {}) {
|
|
25898
|
+
const previous = await fetchPodLog(transport, namespace, podName, { ...opts, previous: true });
|
|
25899
|
+
if (hasLogContent(previous)) return previous;
|
|
25900
|
+
const current = await fetchPodLog(transport, namespace, podName, { ...opts, previous: false });
|
|
25901
|
+
return hasLogContent(current) ? current : void 0;
|
|
25902
|
+
}
|
|
25694
25903
|
|
|
25695
25904
|
// src/connectors/kubernetes/kubeconfig.ts
|
|
25696
25905
|
init_cjs_shims();
|
|
@@ -26116,7 +26325,7 @@ function mapWorkloadsToSignals(deployments, pods, config, logs) {
|
|
|
26116
26325
|
|
|
26117
26326
|
// src/connectors/kubernetes/resolve.ts
|
|
26118
26327
|
init_cjs_shims();
|
|
26119
|
-
var
|
|
26328
|
+
var import_types109 = require("@neat.is/types");
|
|
26120
26329
|
var NO_ENV3 = "unknown";
|
|
26121
26330
|
function createK8sResolveTarget(graph) {
|
|
26122
26331
|
return (signal) => {
|
|
@@ -26127,7 +26336,7 @@ function createK8sResolveTarget(graph) {
|
|
|
26127
26336
|
return {
|
|
26128
26337
|
targetNodeId: resolveFusedServiceId(graph, serviceName, NO_ENV3),
|
|
26129
26338
|
serviceName,
|
|
26130
|
-
edgeType:
|
|
26339
|
+
edgeType: import_types109.EdgeType.CALLS
|
|
26131
26340
|
};
|
|
26132
26341
|
};
|
|
26133
26342
|
}
|
|
@@ -26237,11 +26446,10 @@ var KubernetesConnector = class {
|
|
|
26237
26446
|
const targets = faultedPods(deployments, pods, this.config);
|
|
26238
26447
|
await Promise.all(
|
|
26239
26448
|
targets.map(async (t) => {
|
|
26240
|
-
const text = await
|
|
26449
|
+
const text = await fetchPodProcessLog(transport, namespace, t.podName, {
|
|
26241
26450
|
...t.container ? { container: t.container } : {},
|
|
26242
26451
|
tailLines: PROCESS_LOG_TAIL_LINES,
|
|
26243
26452
|
limitBytes: PROCESS_LOG_LIMIT_BYTES,
|
|
26244
|
-
previous: true,
|
|
26245
26453
|
...opts
|
|
26246
26454
|
});
|
|
26247
26455
|
if (typeof text === "string" && text.length > 0) logs.set(podLogKey(t.podName, t.container), text);
|
|
@@ -26281,7 +26489,7 @@ var import_node_fs47 = require("fs");
|
|
|
26281
26489
|
var import_node_path83 = __toESM(require("path"), 1);
|
|
26282
26490
|
|
|
26283
26491
|
// src/daemon.ts
|
|
26284
|
-
var
|
|
26492
|
+
var import_types112 = require("@neat.is/types");
|
|
26285
26493
|
function daemonJsonPath(scanPath) {
|
|
26286
26494
|
return import_node_path84.default.join(scanPath, "neat-out", "daemon.json");
|
|
26287
26495
|
}
|
|
@@ -31344,7 +31552,7 @@ async function connectorAdd(args, deps) {
|
|
|
31344
31552
|
}
|
|
31345
31553
|
const { replaced } = await upsertConnectorEntry(entry2, deps.home);
|
|
31346
31554
|
const verb = replaced ? "updated" : "added";
|
|
31347
|
-
const where = project ? `project "${project}"` : "
|
|
31555
|
+
const where = project ? `project "${project}"` : "every project (no --project set)";
|
|
31348
31556
|
deps.out(`${verb} connector "${id}" (${provider}) for ${where}.`);
|
|
31349
31557
|
if (push) {
|
|
31350
31558
|
deps.out("The drain is live \u2014 traces arrive at the daemon's OTLP receiver. No poll or restart needed.");
|
|
@@ -31407,7 +31615,7 @@ async function connectorList(deps, filterProject, json = false) {
|
|
|
31407
31615
|
}
|
|
31408
31616
|
deps.out("id provider project credential");
|
|
31409
31617
|
for (const e of entries) {
|
|
31410
|
-
const project = e.project ?? "(
|
|
31618
|
+
const project = e.project ?? "(every project)";
|
|
31411
31619
|
const credential = describeCredential(e.credential, deps.env).map((c) => {
|
|
31412
31620
|
const status2 = c.status ? ` (${c.status})` : c.kind === "plaintext" ? " (plaintext)" : "";
|
|
31413
31621
|
return c.field ? `${c.field}=${c.display}${status2}` : `${c.display}${status2}`;
|
|
@@ -32420,7 +32628,48 @@ var import_node_path96 = __toESM(require("path"), 1);
|
|
|
32420
32628
|
|
|
32421
32629
|
// src/cli-client.ts
|
|
32422
32630
|
init_cjs_shims();
|
|
32423
|
-
var
|
|
32631
|
+
var import_types113 = require("@neat.is/types");
|
|
32632
|
+
|
|
32633
|
+
// src/incidents-render.ts
|
|
32634
|
+
init_cjs_shims();
|
|
32635
|
+
function deployHintLines(ev) {
|
|
32636
|
+
const a = ev.attributes;
|
|
32637
|
+
if (!a) return [];
|
|
32638
|
+
const s = (k) => typeof a[k] === "string" ? a[k] : void 0;
|
|
32639
|
+
const n = (k) => typeof a[k] === "number" ? a[k] : void 0;
|
|
32640
|
+
const arr = (k) => Array.isArray(a[k]) ? a[k].filter((x) => typeof x === "string") : [];
|
|
32641
|
+
const fault = s("k8s.fault");
|
|
32642
|
+
const env = arr("k8s.containerEnv");
|
|
32643
|
+
const args = arr("k8s.containerArgs");
|
|
32644
|
+
const log = s("k8s.processLog");
|
|
32645
|
+
if (!fault && env.length === 0 && args.length === 0 && !log) return [];
|
|
32646
|
+
const out = [];
|
|
32647
|
+
if (fault) {
|
|
32648
|
+
const bits = [fault];
|
|
32649
|
+
const wr = s("k8s.waitingReason");
|
|
32650
|
+
if (wr) bits.push(wr);
|
|
32651
|
+
const rc = n("k8s.restartCount");
|
|
32652
|
+
if (rc !== void 0) bits.push(`restarts=${rc}`);
|
|
32653
|
+
const ec = n("k8s.exitCode");
|
|
32654
|
+
if (ec !== void 0) bits.push(`exit=${ec}`);
|
|
32655
|
+
const tr = s("k8s.terminatedReason");
|
|
32656
|
+
if (tr) bits.push(tr);
|
|
32657
|
+
out.push(`deploy: ${bits.join(" ")}`);
|
|
32658
|
+
}
|
|
32659
|
+
const cap = (xs, max) => {
|
|
32660
|
+
const joined = xs.join(" ");
|
|
32661
|
+
return joined.length > max ? `${joined.slice(0, max)}\u2026(+${xs.length} entries)` : joined;
|
|
32662
|
+
};
|
|
32663
|
+
if (env.length > 0) out.push(`env: ${cap(env, 700)}`);
|
|
32664
|
+
if (args.length > 0) out.push(`args: ${cap(args, 300)}`);
|
|
32665
|
+
if (log) {
|
|
32666
|
+
const tail = log.split("\n").filter((l) => l.trim().length > 0).slice(-4);
|
|
32667
|
+
if (tail.length > 0) out.push(`log: ${tail.join(" \u23CE ")}`);
|
|
32668
|
+
}
|
|
32669
|
+
return out;
|
|
32670
|
+
}
|
|
32671
|
+
|
|
32672
|
+
// src/cli-client.ts
|
|
32424
32673
|
var HttpError = class extends Error {
|
|
32425
32674
|
constructor(status2, message, responseBody = "") {
|
|
32426
32675
|
super(message);
|
|
@@ -32562,7 +32811,7 @@ async function runBlastRadius(client, input) {
|
|
|
32562
32811
|
}
|
|
32563
32812
|
}
|
|
32564
32813
|
function formatBlastEntry(n) {
|
|
32565
|
-
const tag = n.edgeProvenance ===
|
|
32814
|
+
const tag = n.edgeProvenance === import_types113.Provenance.STALE ? " [STALE \u2014 last seen too long ago]" : "";
|
|
32566
32815
|
return ` \u2022 ${n.nodeId} (distance ${n.distance}, ${n.edgeProvenance})${tag}`;
|
|
32567
32816
|
}
|
|
32568
32817
|
async function runDependencies(client, input) {
|
|
@@ -32619,7 +32868,7 @@ async function runObservedDependencies(client, input) {
|
|
|
32619
32868
|
if (result.observed) {
|
|
32620
32869
|
return {
|
|
32621
32870
|
summary: `${input.nodeId} makes no outbound runtime calls, but OTel has observed it receiving traffic on ${result.inboundObservedCount} inbound call path${result.inboundObservedCount === 1 ? "" : "s"} \u2014 it's a pure receiver.`,
|
|
32622
|
-
provenance:
|
|
32871
|
+
provenance: import_types113.Provenance.OBSERVED
|
|
32623
32872
|
};
|
|
32624
32873
|
}
|
|
32625
32874
|
const note = result.hasExtractedOutbound ? " Static (EXTRACTED) dependencies exist but no runtime traffic has been seen \u2014 is OTel running?" : "";
|
|
@@ -32629,7 +32878,7 @@ async function runObservedDependencies(client, input) {
|
|
|
32629
32878
|
return {
|
|
32630
32879
|
summary: `${input.nodeId} has ${result.dependencies.length} runtime dependenc${result.dependencies.length === 1 ? "y" : "ies"} confirmed by OTel.`,
|
|
32631
32880
|
block: blockLines.join("\n"),
|
|
32632
|
-
provenance:
|
|
32881
|
+
provenance: import_types113.Provenance.OBSERVED
|
|
32633
32882
|
};
|
|
32634
32883
|
} catch (err) {
|
|
32635
32884
|
if (err instanceof HttpError && err.status === 404) {
|
|
@@ -32677,13 +32926,15 @@ async function runIncidents(client, input) {
|
|
|
32677
32926
|
const blockLines = [];
|
|
32678
32927
|
for (const ev of ordered) {
|
|
32679
32928
|
blockLines.push(` ${ev.timestamp} \u2014 ${ev.service}: ${ev.errorMessage}`);
|
|
32929
|
+
if (ev.exceptionType) blockLines.push(` exception: ${ev.exceptionType}`);
|
|
32930
|
+
for (const l of deployHintLines(ev)) blockLines.push(` ${l}`);
|
|
32680
32931
|
blockLines.push(` trace=${ev.traceId} span=${ev.spanId}`);
|
|
32681
32932
|
}
|
|
32682
32933
|
const target = input.nodeId ?? "the project";
|
|
32683
32934
|
return {
|
|
32684
32935
|
summary: `${target} has ${body.total} recorded incident${body.total === 1 ? "" : "s"}; showing the ${ordered.length} most recent.`,
|
|
32685
32936
|
block: blockLines.join("\n"),
|
|
32686
|
-
provenance:
|
|
32937
|
+
provenance: import_types113.Provenance.OBSERVED
|
|
32687
32938
|
};
|
|
32688
32939
|
} catch (err) {
|
|
32689
32940
|
if (err instanceof HttpError && err.status === 404) {
|
|
@@ -32792,7 +33043,7 @@ async function runStaleEdges(client, input) {
|
|
|
32792
33043
|
return {
|
|
32793
33044
|
summary: `${events.length} stale-edge transition${events.length === 1 ? "" : "s"} recorded${input.edgeType ? ` for ${input.edgeType}` : ""}.`,
|
|
32794
33045
|
block: blockLines.join("\n"),
|
|
32795
|
-
provenance:
|
|
33046
|
+
provenance: import_types113.Provenance.STALE
|
|
32796
33047
|
};
|
|
32797
33048
|
}
|
|
32798
33049
|
async function runPolicies(client, input) {
|
|
@@ -33532,7 +33783,7 @@ var import_promises5 = __toESM(require("readline/promises"), 1);
|
|
|
33532
33783
|
|
|
33533
33784
|
// src/agent-directive.generated.ts
|
|
33534
33785
|
init_cjs_shims();
|
|
33535
|
-
var AGENT_DIRECTIVE = '##
|
|
33786
|
+
var AGENT_DIRECTIVE = '## Let NEAT investigate before you search files\n\nThis project has NEAT. It does the investigation for this system so you can\nspend your effort on the code: what exists, what actually ran, where a failure\nbegan, and what a change will reach. It answers from a live graph that fuses\ncode, data and infrastructure declarations with runtime traffic, incidents and\nsupported provider telemetry. The graph is deterministic: you supply the\nreasoning about the fix; NEAT resolves named nodes and traverses recorded\nevidence rather than asking an LLM to infer architecture from file names.\n\nEvery claim carries provenance and confidence. `EXTRACTED` comes from recognized\nsource or configuration, `OBSERVED` from spans or supported provider signals,\n`INFERRED` from a bridged relationship, and `STALE` marks an observed edge that\nwent quiet. Missing runtime evidence does not prove a path never runs.\n\n**For questions about this system\'s behavior, structure, data dependencies,\nfailures, or change impact, call the MCP `ask` tool (`mcp__neat__ask`) before\nRead/Grep/Glob/Bash.** You do not need an exact node id. `ask` resolves names\nand routes to the relevant graph traversal, returning provenance-tagged facts.\nWhen MCP is unavailable, use the same door through the CLI:\n\n```\nnpx neat.is ask "why is checkout failing?"\nnpx neat.is ask "what breaks if I change the orders table?"\nnpx neat.is ask "what does the payments service depend on at runtime?"\n```\n\nFor a failure, call `get_incident_card` on the failing service, file or symbol\n(if you don\'t know which, `ask` what is failing first). The card is the\ninvestigation already done: the incident, its likely cause chain, blast radius,\nthe governing policies and divergence, in one work order. Use `expand` one hop\nat a time and `relate` to test whether the suspected cause and symptom share a\nsignal. Check provenance and confidence before acting.\n\nBefore a change, use `get_blast_radius` and `check_policies` to see dependents\nand advisory architectural rules. Use `get_divergences` to compare declared\nintent with observed behavior, `get_graph_diff` to compare a saved snapshot\nwith the live graph, and `get_recent_stale_edges` when traffic goes quiet.\n`get_dependencies` maps a node\'s outgoing graph; `get_observed_dependencies`\nshows only seen runtime/provider calls. `semantic_search` finds node labels,\nnot arbitrary source text.\n\nRead source when the graph does not model what you need: comments, arbitrary\nstring literals, config details, unsupported syntax, or a repository that has\nnot been extracted or connected. If a graph answer is empty, check the daemon\nwith `npx neat.is list` or restart it with `npx neat.is up`; wire MCP with\n`npx neat.is skill --apply`.\n';
|
|
33536
33787
|
|
|
33537
33788
|
// src/welcome.ts
|
|
33538
33789
|
var WORDMARK = [
|
|
@@ -33547,10 +33798,13 @@ function renderAgentSetupPrompt(project, restPort) {
|
|
|
33547
33798
|
const endpoint2 = restPort === void 0 ? "The daemon endpoint is unavailable; run `npx neat.is up` to start it." : `The local daemon is serving it at http://127.0.0.1:${restPort}.`;
|
|
33548
33799
|
return `NEAT is set up for project "${project}". ${endpoint2}
|
|
33549
33800
|
|
|
33550
|
-
NEAT
|
|
33551
|
-
|
|
33552
|
-
|
|
33553
|
-
what a
|
|
33801
|
+
NEAT does the investigation for this system, so you can spend your effort on the
|
|
33802
|
+
code. When something fails, call get_incident_card on the failing service, file
|
|
33803
|
+
or symbol: one work order with where the failure is, the cause chain (provenance
|
|
33804
|
+
on every hop), what a fix reaches, the policies that govern the code, and where
|
|
33805
|
+
code and runtime disagree. For anything else about how the system works, ask.
|
|
33806
|
+
NEAT answers from a live graph that fuses the code with what actually ran; a
|
|
33807
|
+
path it hasn't seen run is not proof the path never runs.
|
|
33554
33808
|
|
|
33555
33809
|
1. Wire NEAT's MCP server into this agent session:
|
|
33556
33810
|
npx neat.is skill --apply
|
|
@@ -33561,8 +33815,10 @@ what a change could affect. Missing observations do not prove a path never runs.
|
|
|
33561
33815
|
If the daemon is unreachable, run \`npx neat.is up\`.
|
|
33562
33816
|
|
|
33563
33817
|
${AGENT_DIRECTIVE}
|
|
33564
|
-
|
|
33565
|
-
neat-
|
|
33818
|
+
Runtime evidence arrives once the app runs with NEAT attached: for Node, load
|
|
33819
|
+
.env.neat first (\`set -a; . ./.env.neat; set +a\`); for Python, start under
|
|
33820
|
+
\`opentelemetry-instrument\`. Daemon log: neat-out/daemon.log. Reopen this
|
|
33821
|
+
door with \`npx neat.is welcome\`.`;
|
|
33566
33822
|
}
|
|
33567
33823
|
function printHeader(out) {
|
|
33568
33824
|
for (const line of WORDMARK) out(line);
|
|
@@ -34802,12 +35058,12 @@ async function runEditorCommand(clientId, args, projectDir = process.cwd()) {
|
|
|
34802
35058
|
|
|
34803
35059
|
// src/monitor.ts
|
|
34804
35060
|
init_cjs_shims();
|
|
34805
|
-
var
|
|
35061
|
+
var import_types114 = require("@neat.is/types");
|
|
34806
35062
|
var OBSERVED_DEP_EDGE_TYPES = /* @__PURE__ */ new Set([
|
|
34807
|
-
|
|
34808
|
-
|
|
34809
|
-
|
|
34810
|
-
|
|
35063
|
+
import_types114.EdgeType.CALLS,
|
|
35064
|
+
import_types114.EdgeType.CONNECTS_TO,
|
|
35065
|
+
import_types114.EdgeType.PUBLISHES_TO,
|
|
35066
|
+
import_types114.EdgeType.CONSUMES_FROM
|
|
34811
35067
|
]);
|
|
34812
35068
|
function divergenceKey(d) {
|
|
34813
35069
|
const column = "column" in d && d.column ? d.column : "";
|
|
@@ -34877,7 +35133,7 @@ function formatDivergenceLine2(d) {
|
|
|
34877
35133
|
}
|
|
34878
35134
|
}
|
|
34879
35135
|
function formatStaleLine(edgeId) {
|
|
34880
|
-
const parsed = (0,
|
|
35136
|
+
const parsed = (0, import_types114.parseEdgeId)(edgeId);
|
|
34881
35137
|
if (parsed) {
|
|
34882
35138
|
return `\u22EF stale ${parsed.source} \u2192 ${parsed.target} (observed edge went quiet)`;
|
|
34883
35139
|
}
|
|
@@ -34890,7 +35146,7 @@ function divergenceJson(d) {
|
|
|
34890
35146
|
return JSON.stringify({ kind: "divergence", ...d });
|
|
34891
35147
|
}
|
|
34892
35148
|
function staleJson(edgeId) {
|
|
34893
|
-
const parsed = (0,
|
|
35149
|
+
const parsed = (0, import_types114.parseEdgeId)(edgeId);
|
|
34894
35150
|
return JSON.stringify({
|
|
34895
35151
|
kind: "stale",
|
|
34896
35152
|
edgeId,
|
|
@@ -34974,7 +35230,7 @@ var MonitorEmitter = class {
|
|
|
34974
35230
|
// ignores non-OBSERVED edges and non-dependency edge types (structural
|
|
34975
35231
|
// ownership), so only real runtime dependencies reach stdout.
|
|
34976
35232
|
emitObservedEdge(edge) {
|
|
34977
|
-
if (edge.provenance !==
|
|
35233
|
+
if (edge.provenance !== import_types114.Provenance.OBSERVED) return false;
|
|
34978
35234
|
if (!OBSERVED_DEP_EDGE_TYPES.has(edge.type)) return false;
|
|
34979
35235
|
const key = `edge|${edge.id}`;
|
|
34980
35236
|
if (this.seen.has(key)) return false;
|
|
@@ -35155,7 +35411,7 @@ async function runMonitor(opts) {
|
|
|
35155
35411
|
case "edge-added": {
|
|
35156
35412
|
const payload = safeParse(frame.data);
|
|
35157
35413
|
const edge = payload?.edge;
|
|
35158
|
-
if (edge && edge.provenance ===
|
|
35414
|
+
if (edge && edge.provenance === import_types114.Provenance.OBSERVED) {
|
|
35159
35415
|
emitter.emitObservedEdge(edge);
|
|
35160
35416
|
divergences.schedule();
|
|
35161
35417
|
}
|
|
@@ -35426,7 +35682,7 @@ async function runSync(opts) {
|
|
|
35426
35682
|
}
|
|
35427
35683
|
|
|
35428
35684
|
// src/cli.ts
|
|
35429
|
-
var
|
|
35685
|
+
var import_types115 = require("@neat.is/types");
|
|
35430
35686
|
init_auth();
|
|
35431
35687
|
function usage5() {
|
|
35432
35688
|
const neat = commandPrefix();
|
|
@@ -36338,10 +36594,15 @@ async function main() {
|
|
|
36338
36594
|
return;
|
|
36339
36595
|
}
|
|
36340
36596
|
if (cmd === "sync") {
|
|
36597
|
+
const syncTarget = await resolveClientTarget({
|
|
36598
|
+
...parsed.project ? { project: parsed.project } : {},
|
|
36599
|
+
...parsed.profile ? { profile: parsed.profile } : {}
|
|
36600
|
+
});
|
|
36341
36601
|
const result = await runSync({
|
|
36342
36602
|
...parsed.project ? { project: parsed.project } : {},
|
|
36343
36603
|
...parsed.to ? { to: parsed.to } : {},
|
|
36344
36604
|
...parsed.token ? { token: parsed.token } : {},
|
|
36605
|
+
daemonUrl: syncTarget.endpoint,
|
|
36345
36606
|
dryRun: parsed.dryRun,
|
|
36346
36607
|
noInstrument: parsed.noInstrument,
|
|
36347
36608
|
sourceEdit: parsed.sourceEdit,
|
|
@@ -36500,9 +36761,28 @@ async function resolveClientTarget(opts = {}) {
|
|
|
36500
36761
|
if (daemon) {
|
|
36501
36762
|
return { endpoint: `http://localhost:${daemon.record.ports.rest}`, source: "daemon-record" };
|
|
36502
36763
|
}
|
|
36764
|
+
} else {
|
|
36765
|
+
const live = (await discoverDaemons()).filter((d) => d.live);
|
|
36766
|
+
if (live.length === 1) {
|
|
36767
|
+
return {
|
|
36768
|
+
endpoint: `http://localhost:${live[0].record.ports.rest}`,
|
|
36769
|
+
source: "sole-daemon"
|
|
36770
|
+
};
|
|
36771
|
+
}
|
|
36503
36772
|
}
|
|
36504
36773
|
return { endpoint: "http://localhost:8080", source: "default" };
|
|
36505
36774
|
}
|
|
36775
|
+
async function loopbackResolutionHint() {
|
|
36776
|
+
const live = (await discoverDaemons()).filter((d) => d.live);
|
|
36777
|
+
if (live.length === 0) {
|
|
36778
|
+
return "No NEAT daemon is running. Start one with `npx neat.is` in your project (or `neat up`), then re-run \u2014 or set NEAT_API_URL to a daemon.";
|
|
36779
|
+
}
|
|
36780
|
+
if (live.length > 1) {
|
|
36781
|
+
const list = live.map((d) => ` ${d.record.project} \u2192 http://localhost:${d.record.ports.rest}`).join("\n");
|
|
36782
|
+
return "This directory is not a registered NEAT project and several daemons are running, so NEAT cannot pick one. Run from the project directory, pass --project <name>, or set NEAT_API_URL:\n" + list;
|
|
36783
|
+
}
|
|
36784
|
+
return void 0;
|
|
36785
|
+
}
|
|
36506
36786
|
async function projectForCwd(cwd = process.cwd()) {
|
|
36507
36787
|
try {
|
|
36508
36788
|
return (await findProjectByPath(cwd))?.name;
|
|
@@ -36511,7 +36791,7 @@ async function projectForCwd(cwd = process.cwd()) {
|
|
|
36511
36791
|
}
|
|
36512
36792
|
}
|
|
36513
36793
|
function cwdProjectApplies(source) {
|
|
36514
|
-
return source === "daemon-record" || source === "default";
|
|
36794
|
+
return source === "daemon-record" || source === "sole-daemon" || source === "default";
|
|
36515
36795
|
}
|
|
36516
36796
|
async function resolveDaemonUrl(project, profile) {
|
|
36517
36797
|
return (await resolveClientTarget({ project, profile })).endpoint;
|
|
@@ -36533,6 +36813,11 @@ async function runQueryVerb(cmd, parsed) {
|
|
|
36533
36813
|
}
|
|
36534
36814
|
throw err;
|
|
36535
36815
|
}
|
|
36816
|
+
if (target.source === "default" && !requestedProject && !cwdProject) {
|
|
36817
|
+
const hint = await loopbackResolutionHint();
|
|
36818
|
+
if (hint) process.stderr.write(`${hint}
|
|
36819
|
+
`);
|
|
36820
|
+
}
|
|
36536
36821
|
const client = createHttpClient(target.endpoint, target.authToken);
|
|
36537
36822
|
const positional = parsed.positional;
|
|
36538
36823
|
let makeWork;
|
|
@@ -36659,10 +36944,10 @@ async function runQueryVerb(cmd, parsed) {
|
|
|
36659
36944
|
const parts = parsed.type.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
36660
36945
|
const out = [];
|
|
36661
36946
|
for (const p of parts) {
|
|
36662
|
-
const r =
|
|
36947
|
+
const r = import_types115.DivergenceTypeSchema.safeParse(p);
|
|
36663
36948
|
if (!r.success) {
|
|
36664
36949
|
console.error(
|
|
36665
|
-
`neat divergences: unknown --type "${p}". allowed: ${
|
|
36950
|
+
`neat divergences: unknown --type "${p}". allowed: ${import_types115.DivergenceTypeSchema.options.join(", ")}`
|
|
36666
36951
|
);
|
|
36667
36952
|
return 2;
|
|
36668
36953
|
}
|
|
@@ -36780,6 +37065,7 @@ if (/[\\/](?:cli\.(?:cjs|js)|cli|neat|neat\.is)$/.test(entry)) {
|
|
|
36780
37065
|
cwdProjectApplies,
|
|
36781
37066
|
isLoopbackEndpoint,
|
|
36782
37067
|
isNpxInvocation,
|
|
37068
|
+
loopbackResolutionHint,
|
|
36783
37069
|
main,
|
|
36784
37070
|
parseArgs,
|
|
36785
37071
|
printBanner,
|