@datasynx/agentic-ai-cartography 2.11.0 → 2.12.1
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/README.md +142 -2
- package/dist/{chunk-FFUUNSWP.js → chunk-OIDAXUW5.js} +212 -200
- package/dist/chunk-OIDAXUW5.js.map +1 -0
- package/dist/cli.js +95 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +87 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +94 -3
- package/dist/index.d.ts +94 -3
- package/dist/index.js +80 -5
- package/dist/index.js.map +1 -1
- package/dist/mcp-bin.js +1 -1
- package/llms-full.txt +305 -25
- package/package.json +1 -1
- package/server.json +2 -2
- package/dist/chunk-FFUUNSWP.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -31,9 +31,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
ACTIONS: () => ACTIONS,
|
|
34
|
+
ANON_TOKEN: () => ANON_TOKEN,
|
|
34
35
|
ActionSchema: () => ActionSchema,
|
|
35
36
|
AuthConfigSchema: () => AuthConfigSchema,
|
|
36
37
|
AuthorizationError: () => AuthorizationError,
|
|
38
|
+
BARE_INTERNAL_HOST: () => BARE_INTERNAL_HOST,
|
|
37
39
|
CLIENTS: () => CLIENTS,
|
|
38
40
|
CONFIDENCE: () => CONFIDENCE,
|
|
39
41
|
CORRELATION_CONFIDENCE: () => CORRELATION_CONFIDENCE,
|
|
@@ -197,11 +199,13 @@ __export(src_exports, {
|
|
|
197
199
|
hostname: () => hostname,
|
|
198
200
|
ingestEnvelope: () => ingestEnvelope,
|
|
199
201
|
installedAppsScanner: () => installedAppsScanner,
|
|
202
|
+
isInCluster: () => isInCluster,
|
|
200
203
|
isLoopbackHost: () => isLoopbackHost,
|
|
201
204
|
isPersonalHost: () => isPersonalHost,
|
|
202
205
|
isReadOnlyCommand: () => isReadOnlyCommand,
|
|
203
206
|
isRemembered: () => isRemembered,
|
|
204
207
|
isSecureWebhookUrl: () => isSecureWebhookUrl,
|
|
208
|
+
k8sRegistry: () => k8sRegistry,
|
|
205
209
|
k8sScanner: () => k8sScanner,
|
|
206
210
|
keyMetaOf: () => keyMetaOf,
|
|
207
211
|
layoutClusters: () => layoutClusters,
|
|
@@ -246,6 +250,7 @@ __export(src_exports, {
|
|
|
246
250
|
previewShare: () => previewShare,
|
|
247
251
|
pseudonymize: () => pseudonymize,
|
|
248
252
|
pseudonymizeFragment: () => pseudonymizeFragment,
|
|
253
|
+
pseudonymizeId: () => pseudonymizeId,
|
|
249
254
|
pseudonymizeString: () => pseudonymizeString,
|
|
250
255
|
pushDeltas: () => pushDeltas,
|
|
251
256
|
readConfigFile: () => readConfigFile,
|
|
@@ -268,6 +273,8 @@ __export(src_exports, {
|
|
|
268
273
|
runHttp: () => runHttp,
|
|
269
274
|
runLocalDiscovery: () => runLocalDiscovery,
|
|
270
275
|
runOnce: () => runOnce,
|
|
276
|
+
runOperator: () => runOperator,
|
|
277
|
+
runOperatorCycle: () => runOperatorCycle,
|
|
271
278
|
runStdio: () => runStdio,
|
|
272
279
|
runSyncClassify: () => runSyncClassify,
|
|
273
280
|
safeEnv: () => safeEnv,
|
|
@@ -4952,6 +4959,8 @@ function reversalKey(orgKey) {
|
|
|
4952
4959
|
// src/anonymize.ts
|
|
4953
4960
|
var PRIVATE_IP = /\b(?:10(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2})\b/g;
|
|
4954
4961
|
var HOSTNAME = /\b(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}\b/gi;
|
|
4962
|
+
var BARE_INTERNAL_HOST = /^[a-z0-9]+(?:-[a-z0-9]+)+$|^[a-z]+\d+$|^\d+[a-z]+$/i;
|
|
4963
|
+
var ANON_TOKEN = /^anon:(?:host|user|path|ip):[a-z2-7]+$/;
|
|
4955
4964
|
var POSIX_PATH = /(?:^|(?<=\s|=|:|"|'|\())(\/[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)+)/g;
|
|
4956
4965
|
var WIN_PATH = /\b[A-Za-z]:\\[A-Za-z0-9._\\-]+/g;
|
|
4957
4966
|
var B32_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567";
|
|
@@ -5006,8 +5015,18 @@ function pseudonymizeString(s, orgKey, db) {
|
|
|
5006
5015
|
(_m, user, host2) => `${pseudonymizeFragment(user, "user", orgKey, db)}@${pseudonymizeFragment(host2, "host", orgKey, db)}`
|
|
5007
5016
|
);
|
|
5008
5017
|
out = out.replace(HOSTNAME, (m) => pseudonymizeFragment(m, "host", orgKey, db));
|
|
5018
|
+
const trimmed = out.trim();
|
|
5019
|
+
if (out === s && !ANON_TOKEN.test(trimmed) && BARE_INTERNAL_HOST.test(trimmed)) {
|
|
5020
|
+
out = pseudonymizeFragment(trimmed, "host", orgKey, db);
|
|
5021
|
+
}
|
|
5009
5022
|
return out;
|
|
5010
5023
|
}
|
|
5024
|
+
function pseudonymizeId(id, orgKey, db) {
|
|
5025
|
+
const segments = id.split(":");
|
|
5026
|
+
if (segments.length <= 1) return pseudonymizeString(id, orgKey, db);
|
|
5027
|
+
const [type, ...rest] = segments;
|
|
5028
|
+
return [type, ...rest.map((seg) => pseudonymizeString(seg, orgKey, db))].join(":");
|
|
5029
|
+
}
|
|
5011
5030
|
function pseudonymize(value, orgKey, db) {
|
|
5012
5031
|
if (typeof value === "string") return pseudonymizeString(value, orgKey, db);
|
|
5013
5032
|
if (Array.isArray(value)) return value.map((v) => pseudonymize(v, orgKey, db));
|
|
@@ -5034,8 +5053,6 @@ var FQDN = /\b(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}\b/gi;
|
|
|
5034
5053
|
var POSIX_PATH2 = /(?:^|(?<=\s|=|:|"|'|\())(\/[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)+)/g;
|
|
5035
5054
|
var WIN_PATH2 = /\b[A-Za-z]:\\[A-Za-z0-9._\\-]+/g;
|
|
5036
5055
|
var HOME_USER = /(?:\/home\/|\/Users\/|[A-Za-z]:\\Users\\)([A-Za-z0-9._-]+)/g;
|
|
5037
|
-
var BARE_INTERNAL_HOST = /^[a-z0-9]+(?:-[a-z0-9]+)+$|^[a-z]+\d+$|^\d+[a-z]+$/i;
|
|
5038
|
-
var ANON_TOKEN = /^anon:(?:host|user|path|ip):[a-z2-7]+$/;
|
|
5039
5056
|
function violationsInString(s, path) {
|
|
5040
5057
|
const out = [];
|
|
5041
5058
|
const trimmed = s.trim();
|
|
@@ -5425,9 +5442,10 @@ function resolveEffectiveLevel(node, policy) {
|
|
|
5425
5442
|
function applySharingLevel(node, level, orgKey, db) {
|
|
5426
5443
|
if (level === "none") return null;
|
|
5427
5444
|
if (level === "full") return { ...node, metadata: { ...node.metadata ?? {} }, tags: [...node.tags ?? []] };
|
|
5445
|
+
const { globalId: _g, contentHash: _h, ...rest } = node;
|
|
5428
5446
|
return {
|
|
5429
|
-
...
|
|
5430
|
-
id:
|
|
5447
|
+
...rest,
|
|
5448
|
+
id: pseudonymizeId(node.id, orgKey, db),
|
|
5431
5449
|
name: pseudonymizeString(node.name, orgKey, db),
|
|
5432
5450
|
metadata: pseudonymize(node.metadata ?? {}, orgKey, db),
|
|
5433
5451
|
tags: (node.tags ?? []).map((t) => pseudonymizeString(t, orgKey, db))
|
|
@@ -6279,7 +6297,7 @@ function correlateTopology(nodes, _edges = []) {
|
|
|
6279
6297
|
|
|
6280
6298
|
// src/mcp/server.ts
|
|
6281
6299
|
var SERVER_NAME = "cartography";
|
|
6282
|
-
var SERVER_VERSION = "2.
|
|
6300
|
+
var SERVER_VERSION = "2.12.1";
|
|
6283
6301
|
var SERVICE_TYPES = NODE_TYPE_GROUPS.web;
|
|
6284
6302
|
var DATA_TYPES = NODE_TYPE_GROUPS.data;
|
|
6285
6303
|
var lexicalSearch = async (db, sessionId, query, opts) => db.searchNodes(sessionId, query, { types: opts.types, limit: opts.limit }).map((node) => ({ node }));
|
|
@@ -10202,6 +10220,63 @@ Use ask_user when you need context from the user.`;
|
|
|
10202
10220
|
}
|
|
10203
10221
|
}
|
|
10204
10222
|
|
|
10223
|
+
// src/k8s/operator.ts
|
|
10224
|
+
function k8sRegistry() {
|
|
10225
|
+
return new ScannerRegistry().register(k8sScanner);
|
|
10226
|
+
}
|
|
10227
|
+
function isInCluster(env = process.env) {
|
|
10228
|
+
return typeof env["KUBERNETES_SERVICE_HOST"] === "string" && env["KUBERNETES_SERVICE_HOST"].length > 0;
|
|
10229
|
+
}
|
|
10230
|
+
function pruneToRetention(db, keep, tenant) {
|
|
10231
|
+
const stale = db.getSessions(tenant).slice(Math.max(1, keep));
|
|
10232
|
+
for (const s of stale) db.deleteSession(s.id);
|
|
10233
|
+
return stale.length;
|
|
10234
|
+
}
|
|
10235
|
+
async function runOperatorCycle(db, config, opts = {}) {
|
|
10236
|
+
const sessionId = db.createSession("discover", config);
|
|
10237
|
+
const discover = opts.discover ?? ((d, s) => runLocalDiscovery(d, s, { registry: k8sRegistry() }));
|
|
10238
|
+
const res = await discover(db, sessionId);
|
|
10239
|
+
const sess = db.getSession(sessionId);
|
|
10240
|
+
if (sess && !sess.name) db.setSessionName(sessionId, deriveSessionName(db.getGraphSummary(sessionId), sess.startedAt));
|
|
10241
|
+
const driftFn = opts.drift ?? ((d, c) => runDrift(d, c));
|
|
10242
|
+
const drift = await driftFn(db, config);
|
|
10243
|
+
pruneToRetention(db, opts.retain ?? 10, normalizeTenant(config.organization));
|
|
10244
|
+
return { sessionId, nodes: res.nodes, edges: res.edges, drift };
|
|
10245
|
+
}
|
|
10246
|
+
async function runOperator(db, config, opts = {}) {
|
|
10247
|
+
const log2 = opts.log ?? ((m) => process.stderr.write(m + "\n"));
|
|
10248
|
+
const intervalMs = opts.intervalMs ?? 5 * 6e4;
|
|
10249
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((resolve3) => {
|
|
10250
|
+
if (opts.signal?.aborted) {
|
|
10251
|
+
resolve3();
|
|
10252
|
+
return;
|
|
10253
|
+
}
|
|
10254
|
+
const t = setTimeout(() => {
|
|
10255
|
+
opts.signal?.removeEventListener?.("abort", onAbort);
|
|
10256
|
+
resolve3();
|
|
10257
|
+
}, ms);
|
|
10258
|
+
const onAbort = () => {
|
|
10259
|
+
clearTimeout(t);
|
|
10260
|
+
resolve3();
|
|
10261
|
+
};
|
|
10262
|
+
opts.signal?.addEventListener?.("abort", onAbort, { once: true });
|
|
10263
|
+
}));
|
|
10264
|
+
log2(`Cartograph Kubernetes operator (in-cluster: ${isInCluster()}, interval: ${Math.round(intervalMs / 1e3)}s${opts.once ? ", single pass" : ""})`);
|
|
10265
|
+
for (; ; ) {
|
|
10266
|
+
try {
|
|
10267
|
+
const c = await runOperatorCycle(db, config, opts);
|
|
10268
|
+
log2(
|
|
10269
|
+
`reconcile: session ${c.sessionId} \u2014 ${c.nodes} nodes, ${c.edges} edges` + (c.drift ? `, drift ${c.drift.severity} (${c.drift.items.length} change${c.drift.items.length === 1 ? "" : "s"})` : ", no drift")
|
|
10270
|
+
);
|
|
10271
|
+
} catch (err) {
|
|
10272
|
+
log2(`reconcile failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
10273
|
+
}
|
|
10274
|
+
if (opts.once || opts.signal?.aborted) return;
|
|
10275
|
+
await sleep(intervalMs);
|
|
10276
|
+
if (opts.signal?.aborted) return;
|
|
10277
|
+
}
|
|
10278
|
+
}
|
|
10279
|
+
|
|
10205
10280
|
// src/cost.ts
|
|
10206
10281
|
var import_node_fs8 = require("fs");
|
|
10207
10282
|
var import_node_path8 = require("path");
|
|
@@ -12490,9 +12565,11 @@ function checkClaudePrerequisites() {
|
|
|
12490
12565
|
// Annotate the CommonJS export names for ESM import in node:
|
|
12491
12566
|
0 && (module.exports = {
|
|
12492
12567
|
ACTIONS,
|
|
12568
|
+
ANON_TOKEN,
|
|
12493
12569
|
ActionSchema,
|
|
12494
12570
|
AuthConfigSchema,
|
|
12495
12571
|
AuthorizationError,
|
|
12572
|
+
BARE_INTERNAL_HOST,
|
|
12496
12573
|
CLIENTS,
|
|
12497
12574
|
CONFIDENCE,
|
|
12498
12575
|
CORRELATION_CONFIDENCE,
|
|
@@ -12656,11 +12733,13 @@ function checkClaudePrerequisites() {
|
|
|
12656
12733
|
hostname,
|
|
12657
12734
|
ingestEnvelope,
|
|
12658
12735
|
installedAppsScanner,
|
|
12736
|
+
isInCluster,
|
|
12659
12737
|
isLoopbackHost,
|
|
12660
12738
|
isPersonalHost,
|
|
12661
12739
|
isReadOnlyCommand,
|
|
12662
12740
|
isRemembered,
|
|
12663
12741
|
isSecureWebhookUrl,
|
|
12742
|
+
k8sRegistry,
|
|
12664
12743
|
k8sScanner,
|
|
12665
12744
|
keyMetaOf,
|
|
12666
12745
|
layoutClusters,
|
|
@@ -12705,6 +12784,7 @@ function checkClaudePrerequisites() {
|
|
|
12705
12784
|
previewShare,
|
|
12706
12785
|
pseudonymize,
|
|
12707
12786
|
pseudonymizeFragment,
|
|
12787
|
+
pseudonymizeId,
|
|
12708
12788
|
pseudonymizeString,
|
|
12709
12789
|
pushDeltas,
|
|
12710
12790
|
readConfigFile,
|
|
@@ -12727,6 +12807,8 @@ function checkClaudePrerequisites() {
|
|
|
12727
12807
|
runHttp,
|
|
12728
12808
|
runLocalDiscovery,
|
|
12729
12809
|
runOnce,
|
|
12810
|
+
runOperator,
|
|
12811
|
+
runOperatorCycle,
|
|
12730
12812
|
runStdio,
|
|
12731
12813
|
runSyncClassify,
|
|
12732
12814
|
safeEnv,
|