@datasynx/agentic-ai-cartography 2.3.0 → 2.4.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 +3 -3
- package/dist/{chunk-B2AKONVW.js → chunk-B4QWX7CP.js} +201 -48
- package/dist/chunk-B4QWX7CP.js.map +1 -0
- package/dist/{chunk-7VZH5PFV.js → chunk-L4OSL7I6.js} +3 -3
- package/dist/{chunk-WCR47QA2.js → chunk-QQOQBE2A.js} +16 -5
- package/dist/chunk-QQOQBE2A.js.map +1 -0
- package/dist/{chunk-7QEBFMN4.js → chunk-X5JA2UDT.js} +14 -5
- package/dist/chunk-X5JA2UDT.js.map +1 -0
- package/dist/cli.js +5 -5
- package/dist/index.cjs +241 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +168 -9
- package/dist/index.d.ts +168 -9
- package/dist/index.js +232 -50
- package/dist/index.js.map +1 -1
- package/dist/mcp-bin.js +3 -3
- package/dist/{types-TJWXAQ2L.js → types-5L3AGZLG.js} +2 -2
- package/package.json +1 -1
- package/server.json +2 -2
- package/dist/chunk-7QEBFMN4.js.map +0 -1
- package/dist/chunk-B2AKONVW.js.map +0 -1
- package/dist/chunk-WCR47QA2.js.map +0 -1
- /package/dist/{chunk-7VZH5PFV.js.map → chunk-L4OSL7I6.js.map} +0 -0
- /package/dist/{types-TJWXAQ2L.js.map → types-5L3AGZLG.js.map} +0 -0
package/dist/api-bin.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
parseApiArgs,
|
|
4
4
|
startApi
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-L4OSL7I6.js";
|
|
6
|
+
import "./chunk-X5JA2UDT.js";
|
|
7
|
+
import "./chunk-QQOQBE2A.js";
|
|
8
8
|
import "./chunk-2SZ5QHGH.js";
|
|
9
9
|
|
|
10
10
|
// src/api-bin.ts
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
sanitizeUntrusted,
|
|
21
21
|
stableStringify,
|
|
22
22
|
stripSensitive
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-X5JA2UDT.js";
|
|
24
24
|
import {
|
|
25
25
|
EdgeSchema,
|
|
26
26
|
NODE_TYPES,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
SECURITY_METADATA_KEYS,
|
|
30
30
|
SEVERITIES,
|
|
31
31
|
defaultConfig
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-QQOQBE2A.js";
|
|
33
33
|
import {
|
|
34
34
|
IS_WIN,
|
|
35
35
|
PLATFORM,
|
|
@@ -965,6 +965,41 @@ var StdoutSink = class {
|
|
|
965
965
|
|
|
966
966
|
// src/sinks/webhook.ts
|
|
967
967
|
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
|
|
968
|
+
async function postJson(opts) {
|
|
969
|
+
const doFetch = opts.fetchImpl ?? (typeof fetch === "function" ? fetch : void 0);
|
|
970
|
+
if (!doFetch) {
|
|
971
|
+
logWarn("sink unavailable: global fetch missing", { sink: opts.sinkName });
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
if (!opts.url) {
|
|
975
|
+
logWarn("sink unavailable: no url configured", { sink: opts.sinkName });
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
if (!isSecureWebhookUrl(opts.url)) {
|
|
979
|
+
logWarn("sink refused: insecure scheme (use https:// or a loopback host)", {
|
|
980
|
+
sink: opts.sinkName,
|
|
981
|
+
host: stripSensitive(opts.url)
|
|
982
|
+
});
|
|
983
|
+
return;
|
|
984
|
+
}
|
|
985
|
+
try {
|
|
986
|
+
const res = await doFetch(opts.url, {
|
|
987
|
+
method: "POST",
|
|
988
|
+
headers: { "content-type": "application/json", ...opts.headers ?? {} },
|
|
989
|
+
body: JSON.stringify(opts.body),
|
|
990
|
+
signal: AbortSignal.timeout(opts.timeoutMs ?? 1e4)
|
|
991
|
+
});
|
|
992
|
+
if (!res.ok) {
|
|
993
|
+
logError("sink delivery failed", { sink: opts.sinkName, host: stripSensitive(opts.url), status: res.status });
|
|
994
|
+
}
|
|
995
|
+
} catch (err) {
|
|
996
|
+
logError("sink delivery failed", {
|
|
997
|
+
sink: opts.sinkName,
|
|
998
|
+
host: stripSensitive(opts.url),
|
|
999
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
968
1003
|
function isSecureWebhookUrl(url, env = process.env) {
|
|
969
1004
|
if (env.CARTOGRAPHY_ALLOW_INSECURE_SYNC === "1") return true;
|
|
970
1005
|
let parsed;
|
|
@@ -983,59 +1018,177 @@ var WebhookSink = class {
|
|
|
983
1018
|
}
|
|
984
1019
|
name = "webhook";
|
|
985
1020
|
async emit(alert) {
|
|
986
|
-
if (typeof fetch !== "function") {
|
|
987
|
-
logWarn("webhook sink unavailable: global fetch missing", { sink: this.name });
|
|
988
|
-
return;
|
|
989
|
-
}
|
|
990
1021
|
const { url, token, timeoutMs } = this.opts;
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1022
|
+
await postJson({
|
|
1023
|
+
url,
|
|
1024
|
+
body: redactValue(alert),
|
|
1025
|
+
...token ? { headers: { authorization: `Bearer ${token}` } } : {},
|
|
1026
|
+
...timeoutMs !== void 0 ? { timeoutMs } : {},
|
|
1027
|
+
sinkName: this.name
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
};
|
|
1031
|
+
|
|
1032
|
+
// src/sinks/providers.ts
|
|
1033
|
+
var MAX_ITEMS = 20;
|
|
1034
|
+
var SEVERITY_EMOJI = { info: "\u{1F7E2}", warning: "\u{1F7E1}", critical: "\u{1F534}" };
|
|
1035
|
+
function headline(alert) {
|
|
1036
|
+
const s = alert.summary;
|
|
1037
|
+
return `${s.nodesAdded}+ / ${s.nodesRemoved}- / ${s.nodesChanged}~ nodes, ${s.edgesAdded}+ / ${s.edgesRemoved}- edges`;
|
|
1038
|
+
}
|
|
1039
|
+
function itemLine(it) {
|
|
1040
|
+
const sec = it.securityFields?.length ? ` [security: ${it.securityFields.join(", ")}]` : "";
|
|
1041
|
+
const fields = it.changedFields?.length ? ` (${it.changedFields.join(", ")})` : "";
|
|
1042
|
+
return `${it.severity.toUpperCase()} \xB7 ${it.kind} \xB7 ${it.label}${fields}${sec}`;
|
|
1043
|
+
}
|
|
1044
|
+
function bodyText(alert) {
|
|
1045
|
+
const lines = alert.items.slice(0, MAX_ITEMS).map(itemLine);
|
|
1046
|
+
const more = alert.items.length > MAX_ITEMS ? [`\u2026and ${alert.items.length - MAX_ITEMS} more`] : [];
|
|
1047
|
+
return [headline(alert), "", ...lines, ...more].join("\n");
|
|
1048
|
+
}
|
|
1049
|
+
function formatSlack(alert) {
|
|
1050
|
+
const title = `${SEVERITY_EMOJI[alert.severity]} Topology drift \u2014 ${alert.severity}`;
|
|
1051
|
+
return {
|
|
1052
|
+
text: `${title}: ${headline(alert)}`,
|
|
1053
|
+
blocks: [
|
|
1054
|
+
{ type: "header", text: { type: "plain_text", text: title, emoji: true } },
|
|
1055
|
+
{ type: "section", text: { type: "mrkdwn", text: "```" + bodyText(alert) + "```" } },
|
|
1056
|
+
{ type: "context", elements: [{ type: "mrkdwn", text: `base ${alert.base.sessionId} \u2192 current ${alert.current.sessionId} \xB7 ${alert.generatedAt}` }] }
|
|
1057
|
+
]
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
var PD_SEVERITY = {
|
|
1061
|
+
info: "info",
|
|
1062
|
+
warning: "warning",
|
|
1063
|
+
critical: "critical"
|
|
1064
|
+
};
|
|
1065
|
+
function formatPagerDuty(alert, routingKey) {
|
|
1066
|
+
return {
|
|
1067
|
+
routing_key: routingKey,
|
|
1068
|
+
event_action: "trigger",
|
|
1069
|
+
// Stable per base→current pair so repeated alerts for the same delta de-duplicate.
|
|
1070
|
+
dedup_key: `cartograph-drift:${alert.base.sessionId}:${alert.current.sessionId}`,
|
|
1071
|
+
payload: {
|
|
1072
|
+
summary: `Cartograph topology drift (${alert.severity}): ${headline(alert)}`,
|
|
1073
|
+
source: "cartograph",
|
|
1074
|
+
severity: PD_SEVERITY[alert.severity],
|
|
1075
|
+
timestamp: alert.generatedAt,
|
|
1076
|
+
custom_details: {
|
|
1077
|
+
summary: alert.summary,
|
|
1078
|
+
items: alert.items.slice(0, MAX_ITEMS).map((it) => ({
|
|
1079
|
+
kind: it.kind,
|
|
1080
|
+
ref: it.ref,
|
|
1081
|
+
severity: it.severity,
|
|
1082
|
+
...it.changedFields ? { changedFields: it.changedFields } : {},
|
|
1083
|
+
...it.securityFields ? { securityFields: it.securityFields } : {}
|
|
1084
|
+
}))
|
|
1014
1085
|
}
|
|
1015
|
-
} catch (err) {
|
|
1016
|
-
logError("webhook sink failed", {
|
|
1017
|
-
sink: this.name,
|
|
1018
|
-
host: stripSensitive(url),
|
|
1019
|
-
reason: err instanceof Error ? err.message : String(err)
|
|
1020
|
-
});
|
|
1021
1086
|
}
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1089
|
+
function formatJira(alert, opts) {
|
|
1090
|
+
return {
|
|
1091
|
+
fields: {
|
|
1092
|
+
project: { key: opts.project },
|
|
1093
|
+
issuetype: { name: opts.issueType ?? "Task" },
|
|
1094
|
+
summary: `Cartograph topology drift (${alert.severity}): ${headline(alert)}`,
|
|
1095
|
+
description: bodyText(alert) + `
|
|
1096
|
+
|
|
1097
|
+
base ${alert.base.sessionId} \u2192 current ${alert.current.sessionId}
|
|
1098
|
+
generated ${alert.generatedAt}`
|
|
1099
|
+
}
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
// src/sinks/provider-sink.ts
|
|
1104
|
+
var PAGERDUTY_ENQUEUE_URL = "https://events.pagerduty.com/v2/enqueue";
|
|
1105
|
+
function deliver(name, url, body, opts, headers) {
|
|
1106
|
+
return postJson({
|
|
1107
|
+
url,
|
|
1108
|
+
body,
|
|
1109
|
+
sinkName: name,
|
|
1110
|
+
...headers ? { headers } : {},
|
|
1111
|
+
...opts.timeoutMs !== void 0 ? { timeoutMs: opts.timeoutMs } : {},
|
|
1112
|
+
...opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1115
|
+
var SlackSink = class {
|
|
1116
|
+
constructor(opts) {
|
|
1117
|
+
this.opts = opts;
|
|
1118
|
+
}
|
|
1119
|
+
name = "slack";
|
|
1120
|
+
async emit(alert) {
|
|
1121
|
+
await deliver(this.name, this.opts.url, formatSlack(redactValue(alert)), this.opts);
|
|
1122
|
+
}
|
|
1123
|
+
};
|
|
1124
|
+
var PagerDutySink = class {
|
|
1125
|
+
constructor(opts) {
|
|
1126
|
+
this.opts = opts;
|
|
1127
|
+
}
|
|
1128
|
+
name = "pagerduty";
|
|
1129
|
+
async emit(alert) {
|
|
1130
|
+
const body = formatPagerDuty(redactValue(alert), this.opts.routingKey);
|
|
1131
|
+
await deliver(this.name, this.opts.url || PAGERDUTY_ENQUEUE_URL, body, this.opts);
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1134
|
+
var JiraSink = class {
|
|
1135
|
+
constructor(opts) {
|
|
1136
|
+
this.opts = opts;
|
|
1137
|
+
}
|
|
1138
|
+
name = "jira";
|
|
1139
|
+
async emit(alert) {
|
|
1140
|
+
const body = formatJira(redactValue(alert), {
|
|
1141
|
+
project: this.opts.project,
|
|
1142
|
+
...this.opts.issueType ? { issueType: this.opts.issueType } : {}
|
|
1143
|
+
});
|
|
1144
|
+
const auth = Buffer.from(`${this.opts.email}:${this.opts.token}`).toString("base64");
|
|
1145
|
+
const base = this.opts.url.replace(/\/+$/, "");
|
|
1146
|
+
await deliver(this.name, `${base}/rest/api/2/issue`, body, this.opts, { authorization: `Basic ${auth}` });
|
|
1022
1147
|
}
|
|
1023
1148
|
};
|
|
1024
1149
|
|
|
1025
1150
|
// src/sinks/index.ts
|
|
1026
1151
|
function buildSinks(drift) {
|
|
1027
1152
|
const configs = drift?.sinks && drift.sinks.length > 0 ? drift.sinks : [{ type: "stdout" }];
|
|
1153
|
+
const envSecret = process.env.CARTOGRAPHY_DRIFT_TOKEN;
|
|
1028
1154
|
const sinks = [];
|
|
1029
1155
|
for (const s of configs) {
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1156
|
+
const timeoutMs = s.timeoutMs;
|
|
1157
|
+
switch (s.type) {
|
|
1158
|
+
case "webhook":
|
|
1159
|
+
if (!s.url) {
|
|
1160
|
+
logWarn("drift sink skipped: webhook requires a url", { sink: s.type });
|
|
1161
|
+
break;
|
|
1162
|
+
}
|
|
1163
|
+
sinks.push(new WebhookSink({ url: s.url, token: s.token ?? envSecret, timeoutMs }));
|
|
1164
|
+
break;
|
|
1165
|
+
case "slack":
|
|
1166
|
+
if (!s.url) {
|
|
1167
|
+
logWarn("drift sink skipped: slack requires a webhook url", { sink: s.type });
|
|
1168
|
+
break;
|
|
1169
|
+
}
|
|
1170
|
+
sinks.push(new SlackSink({ url: s.url, timeoutMs }));
|
|
1171
|
+
break;
|
|
1172
|
+
case "pagerduty": {
|
|
1173
|
+
const routingKey = s.routingKey ?? s.token ?? envSecret;
|
|
1174
|
+
if (!routingKey) {
|
|
1175
|
+
logWarn("drift sink skipped: pagerduty requires a routingKey (or CARTOGRAPHY_DRIFT_TOKEN)", { sink: s.type });
|
|
1176
|
+
break;
|
|
1177
|
+
}
|
|
1178
|
+
sinks.push(new PagerDutySink({ url: s.url ?? PAGERDUTY_ENQUEUE_URL, routingKey, timeoutMs }));
|
|
1179
|
+
break;
|
|
1180
|
+
}
|
|
1181
|
+
case "jira": {
|
|
1182
|
+
const token = s.token ?? envSecret;
|
|
1183
|
+
if (!s.url || !s.email || !s.project || !token) {
|
|
1184
|
+
logWarn("drift sink skipped: jira requires url, email, project and a token", { sink: s.type });
|
|
1185
|
+
break;
|
|
1186
|
+
}
|
|
1187
|
+
sinks.push(new JiraSink({ url: s.url, email: s.email, token, project: s.project, issueType: s.issueType, timeoutMs }));
|
|
1188
|
+
break;
|
|
1189
|
+
}
|
|
1190
|
+
default:
|
|
1191
|
+
sinks.push(new StdoutSink());
|
|
1039
1192
|
}
|
|
1040
1193
|
}
|
|
1041
1194
|
return sinks.length > 0 ? sinks : [new StdoutSink()];
|
|
@@ -1381,7 +1534,7 @@ async function executeNlQuery(db, sessionId, search, intent, opts = {}) {
|
|
|
1381
1534
|
|
|
1382
1535
|
// src/mcp/server.ts
|
|
1383
1536
|
var SERVER_NAME = "cartography";
|
|
1384
|
-
var SERVER_VERSION = "2.
|
|
1537
|
+
var SERVER_VERSION = "2.4.0";
|
|
1385
1538
|
var SERVICE_TYPES = NODE_TYPE_GROUPS.web;
|
|
1386
1539
|
var DATA_TYPES = NODE_TYPE_GROUPS.data;
|
|
1387
1540
|
var lexicalSearch = async (db, sessionId, query, opts) => db.searchNodes(sessionId, query, { types: opts.types, limit: opts.limit }).map((node) => ({ node }));
|
|
@@ -2271,7 +2424,7 @@ function revalidateAnonymized(node, level, mode) {
|
|
|
2271
2424
|
|
|
2272
2425
|
// src/central/ingest.ts
|
|
2273
2426
|
var INGEST_SCHEMA_VERSION = 1;
|
|
2274
|
-
var
|
|
2427
|
+
var MAX_ITEMS2 = 5e4;
|
|
2275
2428
|
var ContributorSchema = z3.object({
|
|
2276
2429
|
machineId: z3.string().min(1),
|
|
2277
2430
|
hostname: z3.string().default("unknown"),
|
|
@@ -2285,7 +2438,7 @@ var IngestEnvelopeSchema = z3.object({
|
|
|
2285
2438
|
contentHash: z3.string(),
|
|
2286
2439
|
kind: z3.enum(["node", "edge"]),
|
|
2287
2440
|
payload: z3.unknown()
|
|
2288
|
-
})).max(
|
|
2441
|
+
})).max(MAX_ITEMS2),
|
|
2289
2442
|
// Extensions (forward-compatible; 2.11 does not yet send these).
|
|
2290
2443
|
contributor: ContributorSchema.optional(),
|
|
2291
2444
|
anonymizationLevel: z3.enum(["none", "anonymized", "full"]).optional()
|
|
@@ -2462,4 +2615,4 @@ export {
|
|
|
2462
2615
|
parseMcpArgs,
|
|
2463
2616
|
startMcp
|
|
2464
2617
|
};
|
|
2465
|
-
//# sourceMappingURL=chunk-
|
|
2618
|
+
//# sourceMappingURL=chunk-B4QWX7CP.js.map
|