@datasynx/agentic-ai-cartography 2.5.0 → 2.6.0
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/api-bin.js +1 -1
- package/dist/{chunk-NQXZUWOI.js → chunk-PQ7Q6MI5.js} +90 -2
- package/dist/chunk-PQ7Q6MI5.js.map +1 -0
- package/dist/{chunk-RYQ4KQCK.js → chunk-X3UWUX3G.js} +2 -2
- package/dist/{chunk-RYQ4KQCK.js.map → chunk-X3UWUX3G.js.map} +1 -1
- package/dist/cli.js +6 -27
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +102 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +100 -35
- package/dist/index.js.map +1 -1
- package/dist/mcp-bin.js +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/dist/chunk-NQXZUWOI.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -149,6 +149,7 @@ __export(src_exports, {
|
|
|
149
149
|
diffTopology: () => diffTopology,
|
|
150
150
|
edgesToConnections: () => edgesToConnections,
|
|
151
151
|
enrichCosts: () => enrichCosts,
|
|
152
|
+
entitiesToYaml: () => entitiesToYaml,
|
|
152
153
|
evaluateCheck: () => evaluateCheck,
|
|
153
154
|
evaluateRule: () => evaluateRule,
|
|
154
155
|
evidenceLine: () => evidenceLine,
|
|
@@ -278,6 +279,7 @@ __export(src_exports, {
|
|
|
278
279
|
startApi: () => startApi,
|
|
279
280
|
stripSensitive: () => stripSensitive,
|
|
280
281
|
timingSafeEqual: () => timingSafeEqual,
|
|
282
|
+
toBackstageEntities: () => toBackstageEntities,
|
|
281
283
|
validateScanner: () => validateScanner,
|
|
282
284
|
vscodeDeeplink: () => vscodeDeeplink,
|
|
283
285
|
zodToJsonSchema: () => zodToJsonSchema
|
|
@@ -4690,6 +4692,9 @@ var SqliteQueryBackend = class {
|
|
|
4690
4692
|
node(ctx, id, sessionId) {
|
|
4691
4693
|
return this.db.getNode(this.resolveSession(ctx, sessionId), id);
|
|
4692
4694
|
}
|
|
4695
|
+
edges(ctx, sessionId) {
|
|
4696
|
+
return this.db.getEdges(this.resolveSession(ctx, sessionId));
|
|
4697
|
+
}
|
|
4693
4698
|
dependencies(ctx, id, q, sessionId) {
|
|
4694
4699
|
const sid = this.resolveSession(ctx, sessionId);
|
|
4695
4700
|
return this.db.getDependencies(sid, id, {
|
|
@@ -5932,7 +5937,7 @@ async function resolveNlQuery(db, sessionId, search, raw, opts) {
|
|
|
5932
5937
|
|
|
5933
5938
|
// src/mcp/server.ts
|
|
5934
5939
|
var SERVER_NAME = "cartography";
|
|
5935
|
-
var SERVER_VERSION = "2.
|
|
5940
|
+
var SERVER_VERSION = "2.6.0";
|
|
5936
5941
|
var SERVICE_TYPES = NODE_TYPE_GROUPS.web;
|
|
5937
5942
|
var DATA_TYPES = NODE_TYPE_GROUPS.data;
|
|
5938
5943
|
var lexicalSearch = async (db, sessionId, query, opts) => db.searchNodes(sessionId, query, { types: opts.types, limit: opts.limit }).map((node) => ({ node }));
|
|
@@ -7465,6 +7470,54 @@ function headerValue(req, name) {
|
|
|
7465
7470
|
return v;
|
|
7466
7471
|
}
|
|
7467
7472
|
|
|
7473
|
+
// src/backstage.ts
|
|
7474
|
+
var COMPONENT_TYPES = ["web_service", "container", "pod"];
|
|
7475
|
+
function sanitize(id) {
|
|
7476
|
+
return id.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
7477
|
+
}
|
|
7478
|
+
function toBackstageEntities(nodes, edges, opts = {}) {
|
|
7479
|
+
const owner = opts.org ?? "unknown";
|
|
7480
|
+
return nodes.map((node) => {
|
|
7481
|
+
const kind = COMPONENT_TYPES.includes(node.type) ? "Component" : node.type === "api_endpoint" ? "API" : "Resource";
|
|
7482
|
+
const dependsOn = edges.filter((e) => e.sourceId === node.id).map((e) => `resource:default/${sanitize(e.targetId)}`);
|
|
7483
|
+
return {
|
|
7484
|
+
apiVersion: "backstage.io/v1alpha1",
|
|
7485
|
+
kind,
|
|
7486
|
+
metadata: {
|
|
7487
|
+
name: sanitize(node.id),
|
|
7488
|
+
annotations: {
|
|
7489
|
+
"cartography/discovered-at": node.discoveredAt,
|
|
7490
|
+
"cartography/confidence": String(node.confidence)
|
|
7491
|
+
}
|
|
7492
|
+
},
|
|
7493
|
+
spec: {
|
|
7494
|
+
type: node.type,
|
|
7495
|
+
lifecycle: "production",
|
|
7496
|
+
owner: node.owner ?? owner,
|
|
7497
|
+
...dependsOn.length > 0 ? { dependsOn } : {}
|
|
7498
|
+
}
|
|
7499
|
+
};
|
|
7500
|
+
});
|
|
7501
|
+
}
|
|
7502
|
+
function entitiesToYaml(entities) {
|
|
7503
|
+
return entities.map((e) => {
|
|
7504
|
+
const lines = [
|
|
7505
|
+
`apiVersion: ${e.apiVersion}`,
|
|
7506
|
+
`kind: ${e.kind}`,
|
|
7507
|
+
`metadata:`,
|
|
7508
|
+
` name: ${e.metadata.name}`,
|
|
7509
|
+
` annotations:`,
|
|
7510
|
+
...Object.entries(e.metadata.annotations).map(([k, v]) => ` ${k}: "${v}"`),
|
|
7511
|
+
`spec:`,
|
|
7512
|
+
` type: ${e.spec.type}`,
|
|
7513
|
+
` lifecycle: ${e.spec.lifecycle}`,
|
|
7514
|
+
` owner: ${e.spec.owner}`,
|
|
7515
|
+
...e.spec.dependsOn && e.spec.dependsOn.length > 0 ? [" dependsOn:", ...e.spec.dependsOn.map((d) => ` - ${d}`)] : []
|
|
7516
|
+
];
|
|
7517
|
+
return lines.join("\n");
|
|
7518
|
+
}).join("\n---\n");
|
|
7519
|
+
}
|
|
7520
|
+
|
|
7468
7521
|
// src/api/schemas.ts
|
|
7469
7522
|
var import_zod8 = require("zod");
|
|
7470
7523
|
var DIRECTIONS = ["downstream", "upstream", "both"];
|
|
@@ -7600,6 +7653,21 @@ var ErrorResponse = import_zod8.z.object({
|
|
|
7600
7653
|
error: import_zod8.z.string(),
|
|
7601
7654
|
code: import_zod8.z.string().optional()
|
|
7602
7655
|
});
|
|
7656
|
+
var BackstageEntitySchema = import_zod8.z.object({
|
|
7657
|
+
apiVersion: import_zod8.z.literal("backstage.io/v1alpha1"),
|
|
7658
|
+
kind: import_zod8.z.enum(["Component", "API", "Resource"]),
|
|
7659
|
+
metadata: import_zod8.z.object({
|
|
7660
|
+
name: import_zod8.z.string(),
|
|
7661
|
+
annotations: import_zod8.z.record(import_zod8.z.string(), import_zod8.z.string())
|
|
7662
|
+
}),
|
|
7663
|
+
spec: import_zod8.z.object({
|
|
7664
|
+
type: import_zod8.z.string(),
|
|
7665
|
+
lifecycle: import_zod8.z.string(),
|
|
7666
|
+
owner: import_zod8.z.string(),
|
|
7667
|
+
dependsOn: import_zod8.z.array(import_zod8.z.string()).optional()
|
|
7668
|
+
})
|
|
7669
|
+
});
|
|
7670
|
+
var BackstageCatalogResponse = import_zod8.z.object({ entities: import_zod8.z.array(BackstageEntitySchema) });
|
|
7603
7671
|
var API_SCHEMAS = {
|
|
7604
7672
|
Node: NodeSchema2,
|
|
7605
7673
|
Edge: EdgeSchema2,
|
|
@@ -7611,10 +7679,13 @@ var API_SCHEMAS = {
|
|
|
7611
7679
|
Session: SessionSchema,
|
|
7612
7680
|
Sessions: SessionsResponse,
|
|
7613
7681
|
Health: HealthResponse,
|
|
7614
|
-
Error: ErrorResponse
|
|
7682
|
+
Error: ErrorResponse,
|
|
7683
|
+
BackstageEntity: BackstageEntitySchema,
|
|
7684
|
+
BackstageCatalog: BackstageCatalogResponse
|
|
7615
7685
|
};
|
|
7616
7686
|
|
|
7617
7687
|
// src/api/rest.ts
|
|
7688
|
+
var BACKSTAGE_NODE_CAP = 1e3;
|
|
7618
7689
|
function toApiNode(n) {
|
|
7619
7690
|
const out = { id: n.id, type: n.type, name: n.name, confidence: n.confidence, tags: n.tags };
|
|
7620
7691
|
if (n.domain !== void 0) out["domain"] = n.domain;
|
|
@@ -7749,6 +7820,14 @@ function handleHealth(ctx, d) {
|
|
|
7749
7820
|
const h = d.backend.health(ctx);
|
|
7750
7821
|
return ok(validateOut(HealthResponse, { status: "ok", version: d.version, store: h.store, sessions: h.sessions }));
|
|
7751
7822
|
}
|
|
7823
|
+
function handleBackstageCatalog(ctx, d) {
|
|
7824
|
+
return guard(() => {
|
|
7825
|
+
const page = d.backend.nodes(ctx, { limit: BACKSTAGE_NODE_CAP });
|
|
7826
|
+
const edges = d.backend.edges(ctx);
|
|
7827
|
+
const entities = toBackstageEntities(page.nodes, edges, { org: ctx.tenant });
|
|
7828
|
+
return ok(validateOut(BackstageCatalogResponse, { entities }));
|
|
7829
|
+
});
|
|
7830
|
+
}
|
|
7752
7831
|
|
|
7753
7832
|
// src/api/openapi.ts
|
|
7754
7833
|
function defOf(schema) {
|
|
@@ -7905,6 +7984,13 @@ function buildOpenApiDocument(opts) {
|
|
|
7905
7984
|
parameters: [TENANT_PARAM],
|
|
7906
7985
|
responses: { "200": ok2("Sessions", "Sessions"), ...errorResponses() }
|
|
7907
7986
|
}
|
|
7987
|
+
},
|
|
7988
|
+
"/v1/backstage/catalog": {
|
|
7989
|
+
get: {
|
|
7990
|
+
summary: "The tenant topology as Backstage catalog entities (live data source, 4.6)",
|
|
7991
|
+
parameters: [SESSION_PARAM, TENANT_PARAM],
|
|
7992
|
+
responses: { "200": ok2("BackstageCatalog", "Backstage catalog entities"), ...errorResponses() }
|
|
7993
|
+
}
|
|
7908
7994
|
}
|
|
7909
7995
|
}
|
|
7910
7996
|
};
|
|
@@ -8419,6 +8505,8 @@ function dispatchRest(ctx, path, url, deps) {
|
|
|
8419
8505
|
return handleDiff(ctx, url, deps);
|
|
8420
8506
|
case "/v1/sessions":
|
|
8421
8507
|
return handleSessions(ctx, deps);
|
|
8508
|
+
case "/v1/backstage/catalog":
|
|
8509
|
+
return handleBackstageCatalog(ctx, deps);
|
|
8422
8510
|
default: {
|
|
8423
8511
|
const m = DEPENDENCIES_RE.exec(path);
|
|
8424
8512
|
if (m) return handleDependencies(ctx, decodeURIComponent(m[1]), url, deps);
|
|
@@ -9925,7 +10013,7 @@ var MERMAID_CLASSES = {
|
|
|
9925
10013
|
saas_tool: "fill:#2a1a2a,stroke:#9a3a9a,color:#daf",
|
|
9926
10014
|
unknown: "fill:#2a2a2a,stroke:#5a5a5a,color:#aaa"
|
|
9927
10015
|
};
|
|
9928
|
-
function
|
|
10016
|
+
function sanitize2(id) {
|
|
9929
10017
|
return id.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
9930
10018
|
}
|
|
9931
10019
|
function nodeLabel(node) {
|
|
@@ -9967,14 +10055,14 @@ function generateTopologyMermaid(nodes, edges) {
|
|
|
9967
10055
|
const label = LAYER_LABELS[layerKey] ?? layerKey;
|
|
9968
10056
|
lines.push(` subgraph ${layerKey}["${label}"]`);
|
|
9969
10057
|
for (const node of layerNodes) {
|
|
9970
|
-
lines.push(` ${
|
|
10058
|
+
lines.push(` ${sanitize2(node.id)}${nodeLabel(node)}:::${node.type.replace(/_/g, "")}`);
|
|
9971
10059
|
}
|
|
9972
10060
|
lines.push(" end");
|
|
9973
10061
|
lines.push("");
|
|
9974
10062
|
}
|
|
9975
10063
|
for (const edge of edges) {
|
|
9976
|
-
const src =
|
|
9977
|
-
const tgt =
|
|
10064
|
+
const src = sanitize2(edge.sourceId);
|
|
10065
|
+
const tgt = sanitize2(edge.targetId);
|
|
9978
10066
|
const label = EDGE_LABELS[edge.relationship] ?? edge.relationship;
|
|
9979
10067
|
const arrow = edge.confidence < 0.6 ? `-. "${label}" .->` : `-->|"${label}"|`;
|
|
9980
10068
|
lines.push(` ${src} ${arrow} ${tgt}`);
|
|
@@ -10000,12 +10088,12 @@ function generateDependencyMermaid(nodes, edges) {
|
|
|
10000
10088
|
}
|
|
10001
10089
|
lines.push("");
|
|
10002
10090
|
for (const node of usedNodes) {
|
|
10003
|
-
lines.push(` ${
|
|
10091
|
+
lines.push(` ${sanitize2(node.id)}${nodeLabel(node)}:::${node.type.replace(/_/g, "")}`);
|
|
10004
10092
|
}
|
|
10005
10093
|
lines.push("");
|
|
10006
10094
|
for (const edge of depEdges) {
|
|
10007
10095
|
const label = EDGE_LABELS[edge.relationship] ?? edge.relationship;
|
|
10008
|
-
lines.push(` ${
|
|
10096
|
+
lines.push(` ${sanitize2(edge.sourceId)} -->|"${label}"| ${sanitize2(edge.targetId)}`);
|
|
10009
10097
|
}
|
|
10010
10098
|
return lines.join("\n");
|
|
10011
10099
|
}
|
|
@@ -10056,44 +10144,21 @@ function generateDiffMermaid(diff) {
|
|
|
10056
10144
|
ensureEndpoint(e.targetId);
|
|
10057
10145
|
}
|
|
10058
10146
|
for (const { node, cls, suffix } of entries.values()) {
|
|
10059
|
-
lines.push(` ${
|
|
10147
|
+
lines.push(` ${sanitize2(node.id)}${diffNodeLabel(node, suffix)}:::${cls}`);
|
|
10060
10148
|
}
|
|
10061
10149
|
lines.push("");
|
|
10062
10150
|
for (const e of diff.edges.added) {
|
|
10063
10151
|
const label = EDGE_LABELS[e.relationship] ?? e.relationship;
|
|
10064
|
-
lines.push(` ${
|
|
10152
|
+
lines.push(` ${sanitize2(e.sourceId)} ==>|"+ ${label}"| ${sanitize2(e.targetId)}`);
|
|
10065
10153
|
}
|
|
10066
10154
|
for (const e of diff.edges.removed) {
|
|
10067
10155
|
const label = EDGE_LABELS[e.relationship] ?? e.relationship;
|
|
10068
|
-
lines.push(` ${
|
|
10156
|
+
lines.push(` ${sanitize2(e.sourceId)} -.->|"- ${label}"| ${sanitize2(e.targetId)}`);
|
|
10069
10157
|
}
|
|
10070
10158
|
return lines.join("\n");
|
|
10071
10159
|
}
|
|
10072
10160
|
function exportBackstageYAML(nodes, edges, org) {
|
|
10073
|
-
|
|
10074
|
-
const docs = [];
|
|
10075
|
-
for (const node of nodes) {
|
|
10076
|
-
const isComponent = ["web_service", "container", "pod"].includes(node.type);
|
|
10077
|
-
const isAPI = node.type === "api_endpoint";
|
|
10078
|
-
const kind = isComponent ? "Component" : isAPI ? "API" : "Resource";
|
|
10079
|
-
const deps = edges.filter((e) => e.sourceId === node.id).map((e) => ` - resource:default/${sanitize(e.targetId)}`);
|
|
10080
|
-
const doc = [
|
|
10081
|
-
`apiVersion: backstage.io/v1alpha1`,
|
|
10082
|
-
`kind: ${kind}`,
|
|
10083
|
-
`metadata:`,
|
|
10084
|
-
` name: ${sanitize(node.id)}`,
|
|
10085
|
-
` annotations:`,
|
|
10086
|
-
` cartography/discovered-at: "${node.discoveredAt}"`,
|
|
10087
|
-
` cartography/confidence: "${node.confidence}"`,
|
|
10088
|
-
`spec:`,
|
|
10089
|
-
` type: ${node.type}`,
|
|
10090
|
-
` lifecycle: production`,
|
|
10091
|
-
` owner: ${node.owner ?? owner}`,
|
|
10092
|
-
...deps.length > 0 ? [" dependsOn:", ...deps] : []
|
|
10093
|
-
].join("\n");
|
|
10094
|
-
docs.push(doc);
|
|
10095
|
-
}
|
|
10096
|
-
return docs.join("\n---\n");
|
|
10161
|
+
return entitiesToYaml(toBackstageEntities(nodes, edges, org !== void 0 ? { org } : {}));
|
|
10097
10162
|
}
|
|
10098
10163
|
function exportJSON(db, sessionId) {
|
|
10099
10164
|
const nodes = db.getNodes(sessionId);
|
|
@@ -11898,6 +11963,7 @@ function checkClaudePrerequisites() {
|
|
|
11898
11963
|
diffTopology,
|
|
11899
11964
|
edgesToConnections,
|
|
11900
11965
|
enrichCosts,
|
|
11966
|
+
entitiesToYaml,
|
|
11901
11967
|
evaluateCheck,
|
|
11902
11968
|
evaluateRule,
|
|
11903
11969
|
evidenceLine,
|
|
@@ -12027,6 +12093,7 @@ function checkClaudePrerequisites() {
|
|
|
12027
12093
|
startApi,
|
|
12028
12094
|
stripSensitive,
|
|
12029
12095
|
timingSafeEqual,
|
|
12096
|
+
toBackstageEntities,
|
|
12030
12097
|
validateScanner,
|
|
12031
12098
|
vscodeDeeplink,
|
|
12032
12099
|
zodToJsonSchema
|