@datasynx/agentic-ai-cartography 2.9.0 → 2.11.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 +2 -2
- package/dist/{chunk-LRUWWHMQ.js → chunk-FFUUNSWP.js} +276 -6
- package/dist/chunk-FFUUNSWP.js.map +1 -0
- package/dist/{chunk-YVV6NIT2.js → chunk-LO6YFS6H.js} +2 -1
- package/dist/{chunk-W4Q3TXHR.js → chunk-PD67MOKR.js} +2 -2
- package/dist/cli.js +3 -3
- package/dist/index.cjs +307 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -1
- package/dist/index.d.ts +112 -1
- package/dist/index.js +287 -12
- package/dist/index.js.map +1 -1
- package/dist/mcp-bin.js +2 -2
- package/llms-full.txt +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
- package/dist/chunk-LRUWWHMQ.js.map +0 -1
- /package/dist/{chunk-YVV6NIT2.js.map → chunk-LO6YFS6H.js.map} +0 -0
- /package/dist/{chunk-W4Q3TXHR.js.map → chunk-PD67MOKR.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -5840,9 +5840,146 @@ async function resolveNlQuery(db, sessionId, search, raw, opts) {
|
|
|
5840
5840
|
return executeNlQuery(db, sessionId, search, parseNlQuery(raw), opts);
|
|
5841
5841
|
}
|
|
5842
5842
|
|
|
5843
|
+
// src/correlation/signals.ts
|
|
5844
|
+
var IPV4 = /\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)\b/g;
|
|
5845
|
+
var DNS = /\b(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.){1,8}[a-z]{2,24}\b/gi;
|
|
5846
|
+
var ENDPOINT = /\b((?:[a-z0-9][a-z0-9.-]{0,253})):(\d{1,5})\b/gi;
|
|
5847
|
+
function isPrivateIp(ip) {
|
|
5848
|
+
return /^(?:10\.|127\.|169\.254\.|192\.168\.|172\.(?:1[6-9]|2\d|3[01])\.)/.test(ip);
|
|
5849
|
+
}
|
|
5850
|
+
function sources(node) {
|
|
5851
|
+
const out = [node.id, node.name];
|
|
5852
|
+
const meta = node.metadata;
|
|
5853
|
+
if (meta) {
|
|
5854
|
+
for (const k of ["host", "hostname", "ip", "address", "dns", "dnsName", "endpoint", "fqdn", "publicIp", "privateIp", "url"]) {
|
|
5855
|
+
const v = meta[k];
|
|
5856
|
+
if (typeof v === "string") out.push(v);
|
|
5857
|
+
}
|
|
5858
|
+
}
|
|
5859
|
+
return out;
|
|
5860
|
+
}
|
|
5861
|
+
var KNOWN_PROVIDERS = /* @__PURE__ */ new Set(["aws", "gcp", "azure", "k8s", "kubernetes", "localhost", "docker"]);
|
|
5862
|
+
function parseProvider(id) {
|
|
5863
|
+
const seg = id.split(":");
|
|
5864
|
+
if (seg.length >= 3 && KNOWN_PROVIDERS.has(seg[1])) return seg[1];
|
|
5865
|
+
return void 0;
|
|
5866
|
+
}
|
|
5867
|
+
function extractSignals(node) {
|
|
5868
|
+
const text = sources(node).join(" \n ");
|
|
5869
|
+
const publicIps = /* @__PURE__ */ new Set();
|
|
5870
|
+
const privateIps = /* @__PURE__ */ new Set();
|
|
5871
|
+
const dnsNames = /* @__PURE__ */ new Set();
|
|
5872
|
+
const endpoints = /* @__PURE__ */ new Set();
|
|
5873
|
+
for (const m of text.matchAll(IPV4)) (isPrivateIp(m[0]) ? privateIps : publicIps).add(m[0]);
|
|
5874
|
+
for (const m of text.matchAll(DNS)) dnsNames.add(m[0].toLowerCase());
|
|
5875
|
+
for (const m of text.matchAll(ENDPOINT)) endpoints.add(`${m[1].toLowerCase()}:${m[2]}`);
|
|
5876
|
+
const provider = parseProvider(node.id);
|
|
5877
|
+
const sortUniq = (s) => [...s].sort();
|
|
5878
|
+
return {
|
|
5879
|
+
...provider ? { provider } : {},
|
|
5880
|
+
endpoints: sortUniq(endpoints),
|
|
5881
|
+
publicIps: sortUniq(publicIps),
|
|
5882
|
+
privateIps: sortUniq(privateIps),
|
|
5883
|
+
// The DNS regex requires an alphabetic TLD, so pure IPv4s never land here.
|
|
5884
|
+
dnsNames: sortUniq(dnsNames)
|
|
5885
|
+
};
|
|
5886
|
+
}
|
|
5887
|
+
|
|
5888
|
+
// src/correlation/correlate.ts
|
|
5889
|
+
var CORRELATION_CONFIDENCE = {
|
|
5890
|
+
"global-identity": 1,
|
|
5891
|
+
"dns-name": 0.95,
|
|
5892
|
+
"public-ip": 0.9,
|
|
5893
|
+
"endpoint": 0.85,
|
|
5894
|
+
"private-ip": 0.5
|
|
5895
|
+
};
|
|
5896
|
+
var MERGE_THRESHOLD = 0.85;
|
|
5897
|
+
var DSU = class {
|
|
5898
|
+
parent;
|
|
5899
|
+
constructor(n) {
|
|
5900
|
+
this.parent = Array.from({ length: n }, (_, i) => i);
|
|
5901
|
+
}
|
|
5902
|
+
find(x) {
|
|
5903
|
+
while (this.parent[x] !== x) {
|
|
5904
|
+
this.parent[x] = this.parent[this.parent[x]];
|
|
5905
|
+
x = this.parent[x];
|
|
5906
|
+
}
|
|
5907
|
+
return x;
|
|
5908
|
+
}
|
|
5909
|
+
union(a, b) {
|
|
5910
|
+
const ra = this.find(a), rb = this.find(b);
|
|
5911
|
+
if (ra !== rb) this.parent[Math.max(ra, rb)] = Math.min(ra, rb);
|
|
5912
|
+
}
|
|
5913
|
+
};
|
|
5914
|
+
function correlateTopology(nodes, _edges = []) {
|
|
5915
|
+
const n = nodes.length;
|
|
5916
|
+
const signals = nodes.map(extractSignals);
|
|
5917
|
+
const dsu = new DSU(n);
|
|
5918
|
+
const correlations = [];
|
|
5919
|
+
const merged = /* @__PURE__ */ new Set();
|
|
5920
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
5921
|
+
const add = (sig, val, i) => {
|
|
5922
|
+
const k = `${sig}|${val}`;
|
|
5923
|
+
const arr = buckets.get(k);
|
|
5924
|
+
if (arr) arr.push(i);
|
|
5925
|
+
else buckets.set(k, [i]);
|
|
5926
|
+
};
|
|
5927
|
+
nodes.forEach((node, i) => {
|
|
5928
|
+
if (node.globalId) add("global-identity", node.globalId, i);
|
|
5929
|
+
for (const d of signals[i].dnsNames) add("dns-name", d, i);
|
|
5930
|
+
for (const ip of signals[i].publicIps) add("public-ip", ip, i);
|
|
5931
|
+
for (const e of signals[i].endpoints) add("endpoint", e, i);
|
|
5932
|
+
});
|
|
5933
|
+
const order = ["global-identity", "dns-name", "public-ip", "endpoint"];
|
|
5934
|
+
for (const sig of order) {
|
|
5935
|
+
const conf = CORRELATION_CONFIDENCE[sig];
|
|
5936
|
+
const keys = [...buckets.keys()].filter((k) => k.startsWith(`${sig}|`)).sort();
|
|
5937
|
+
for (const key of keys) {
|
|
5938
|
+
const members = buckets.get(key).slice().sort((x, y) => nodes[x].id.localeCompare(nodes[y].id));
|
|
5939
|
+
const value = key.slice(sig.length + 1);
|
|
5940
|
+
for (let j = 1; j < members.length; j++) {
|
|
5941
|
+
const a = members[0], b = members[j];
|
|
5942
|
+
if (conf < MERGE_THRESHOLD) continue;
|
|
5943
|
+
dsu.union(a, b);
|
|
5944
|
+
merged.add(a);
|
|
5945
|
+
merged.add(b);
|
|
5946
|
+
const [s, t] = [nodes[a].id, nodes[b].id].sort();
|
|
5947
|
+
correlations.push({ sourceId: s, targetId: t, relationship: "same_as", signal: sig, confidence: conf, evidence: `[${sig}] shared ${value}` });
|
|
5948
|
+
}
|
|
5949
|
+
}
|
|
5950
|
+
}
|
|
5951
|
+
const clusters = /* @__PURE__ */ new Map();
|
|
5952
|
+
for (let i = 0; i < n; i++) {
|
|
5953
|
+
const r = dsu.find(i);
|
|
5954
|
+
const arr = clusters.get(r);
|
|
5955
|
+
if (arr) arr.push(i);
|
|
5956
|
+
else clusters.set(r, [i]);
|
|
5957
|
+
}
|
|
5958
|
+
const canonical = [];
|
|
5959
|
+
let crossCloud = 0;
|
|
5960
|
+
for (const idxs of clusters.values()) {
|
|
5961
|
+
const memberNodes = idxs.map((i) => nodes[i]);
|
|
5962
|
+
const members = memberNodes.map((m) => m.id).sort();
|
|
5963
|
+
const providers = [...new Set(idxs.map((i) => signals[i].provider).filter((p) => !!p))].sort();
|
|
5964
|
+
const rep = memberNodes.reduce((a, b) => a.id < b.id ? a : b);
|
|
5965
|
+
const memberIds = new Set(members);
|
|
5966
|
+
const internal = correlations.filter((c) => memberIds.has(c.sourceId) && memberIds.has(c.targetId));
|
|
5967
|
+
const confidence = internal.length ? Math.min(...internal.map((c) => c.confidence)) : 1;
|
|
5968
|
+
if (providers.length > 1) crossCloud += 1;
|
|
5969
|
+
canonical.push({ id: rep.id, type: rep.type, name: rep.name, members, providers, confidence });
|
|
5970
|
+
}
|
|
5971
|
+
canonical.sort((a, b) => a.id.localeCompare(b.id));
|
|
5972
|
+
correlations.sort((a, b) => b.confidence - a.confidence || a.sourceId.localeCompare(b.sourceId) || a.targetId.localeCompare(b.targetId));
|
|
5973
|
+
return {
|
|
5974
|
+
canonical,
|
|
5975
|
+
correlations,
|
|
5976
|
+
summary: { rawNodes: n, canonicalNodes: canonical.length, collapsed: n - canonical.length, crossCloud }
|
|
5977
|
+
};
|
|
5978
|
+
}
|
|
5979
|
+
|
|
5843
5980
|
// src/mcp/server.ts
|
|
5844
5981
|
var SERVER_NAME = "cartography";
|
|
5845
|
-
var SERVER_VERSION = "2.
|
|
5982
|
+
var SERVER_VERSION = "2.11.0";
|
|
5846
5983
|
var SERVICE_TYPES = NODE_TYPE_GROUPS.web;
|
|
5847
5984
|
var DATA_TYPES = NODE_TYPE_GROUPS.data;
|
|
5848
5985
|
var lexicalSearch = async (db, sessionId, query, opts) => db.searchNodes(sessionId, query, { types: opts.types, limit: opts.limit }).map((node) => ({ node }));
|
|
@@ -6002,6 +6139,15 @@ function createMcpServer(opts = {}) {
|
|
|
6002
6139
|
return json(db.getGraphSummary(sid));
|
|
6003
6140
|
}
|
|
6004
6141
|
);
|
|
6142
|
+
server.registerTool(
|
|
6143
|
+
"correlate_topology",
|
|
6144
|
+
{ title: "Correlate multi-cloud topology", description: "Collapse the same logical resource discovered across clouds/on-prem (by global identity or a shared DNS name / public IP / endpoint) into canonical entities with confidence-scored same_as links. Read-only, non-destructive (5.1).", inputSchema: {}, annotations: readOnly },
|
|
6145
|
+
() => {
|
|
6146
|
+
const sid = resolveSession();
|
|
6147
|
+
if (!sid) return json({ error: "No discovery session found." });
|
|
6148
|
+
return json(correlateTopology(db.getNodes(sid), db.getEdges(sid)));
|
|
6149
|
+
}
|
|
6150
|
+
);
|
|
6005
6151
|
server.registerTool(
|
|
6006
6152
|
"get_cost_summary",
|
|
6007
6153
|
{ title: "Get cost summary", description: "FinOps rollup: cost by domain and owner, currency/period-bucketed (3.3).", inputSchema: {}, annotations: readOnly },
|
|
@@ -7243,9 +7389,132 @@ var serviceConfigScanner = {
|
|
|
7243
7389
|
}
|
|
7244
7390
|
};
|
|
7245
7391
|
|
|
7392
|
+
// src/scanners/terraform.ts
|
|
7393
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
7394
|
+
var TYPE_RULES = [
|
|
7395
|
+
[/(db_instance|_rds|sql_database|sql_instance|database_instance|cosmosdb|dynamodb|spanner|bigtable|documentdb|redshift)/, "database_server"],
|
|
7396
|
+
[/(elasticache|_redis|memcached|memorystore)/, "cache_server"],
|
|
7397
|
+
[/(s3_bucket|storage_bucket|gcs_bucket|storage_account|_blob)/, "database"],
|
|
7398
|
+
[/(_sqs|_queue|servicebus_queue)/, "queue"],
|
|
7399
|
+
[/(_sns|_topic|pubsub_topic|servicebus_topic)/, "topic"],
|
|
7400
|
+
[/(kafka|_msk|event_hub|kinesis)/, "message_broker"],
|
|
7401
|
+
[/(_eks|_gke|_aks|kubernetes_cluster|container_cluster)/, "k8s_cluster"],
|
|
7402
|
+
[/(ecs_|_container|fargate)/, "container"],
|
|
7403
|
+
[/(lambda|cloud_function|cloudfunctions|function_app|cloud_run)/, "web_service"],
|
|
7404
|
+
[/(_lb$|load_balancer|_alb|_elb|application_gateway)/, "web_service"],
|
|
7405
|
+
[/(api_gateway|apigateway)/, "api_endpoint"],
|
|
7406
|
+
[/(_instance|virtual_machine|_vm$|compute_instance)/, "host"]
|
|
7407
|
+
];
|
|
7408
|
+
function terraformTypeToNode(tfType) {
|
|
7409
|
+
const t = tfType.toLowerCase();
|
|
7410
|
+
for (const [re, nt] of TYPE_RULES) if (re.test(t)) return nt;
|
|
7411
|
+
return "unknown";
|
|
7412
|
+
}
|
|
7413
|
+
var IDENTITY_ATTRS = ["id", "arn", "region", "location", "instance_type", "engine", "machine_type"];
|
|
7414
|
+
var OWNER_TAGS = ["Owner", "owner", "Team", "team"];
|
|
7415
|
+
var SAFE_TAG_KEYS = /* @__PURE__ */ new Set(["Name", "name", "Owner", "owner", "Team", "team", "Env", "env", "Environment", "environment", "Service", "service", "Component", "component", "App", "app", "Project", "project", "Tier", "tier", "Role", "role"]);
|
|
7416
|
+
var SECRET_KEY = /pass|secret|token|key|pwd|cred|private/i;
|
|
7417
|
+
function attrTags(tags) {
|
|
7418
|
+
if (!tags || typeof tags !== "object") return [];
|
|
7419
|
+
return Object.entries(tags).filter(([k]) => SAFE_TAG_KEYS.has(k) && !SECRET_KEY.test(k)).map(([k, v]) => `${k}:${redactSecrets(String(v))}`);
|
|
7420
|
+
}
|
|
7421
|
+
function parseTerraformState(json2) {
|
|
7422
|
+
let state;
|
|
7423
|
+
try {
|
|
7424
|
+
state = JSON.parse(json2);
|
|
7425
|
+
} catch {
|
|
7426
|
+
return { nodes: [], edges: [] };
|
|
7427
|
+
}
|
|
7428
|
+
const resources = Array.isArray(state?.resources) ? state.resources : [];
|
|
7429
|
+
const nodes = [];
|
|
7430
|
+
const edges = [];
|
|
7431
|
+
const addrToId = /* @__PURE__ */ new Map();
|
|
7432
|
+
for (const raw of resources) {
|
|
7433
|
+
const r = raw;
|
|
7434
|
+
if (r.mode && r.mode !== "managed") continue;
|
|
7435
|
+
if (typeof r.type !== "string" || typeof r.name !== "string") continue;
|
|
7436
|
+
const address = `${r.type}.${r.name}`;
|
|
7437
|
+
const nt = terraformTypeToNode(r.type);
|
|
7438
|
+
const id = `${nt}:terraform:${address}`;
|
|
7439
|
+
if (addrToId.has(address)) continue;
|
|
7440
|
+
addrToId.set(address, id);
|
|
7441
|
+
const inst = Array.isArray(r.instances) ? r.instances[0] : void 0;
|
|
7442
|
+
const attrs = inst?.attributes ?? {};
|
|
7443
|
+
const identity = { source: "terraform", tfType: r.type };
|
|
7444
|
+
for (const k of IDENTITY_ATTRS) if (attrs[k] !== void 0) identity[k] = attrs[k];
|
|
7445
|
+
const owner = OWNER_TAGS.map((k) => attrs.tags?.[k]).find((v) => typeof v === "string");
|
|
7446
|
+
nodes.push({
|
|
7447
|
+
id,
|
|
7448
|
+
type: nt,
|
|
7449
|
+
name: address,
|
|
7450
|
+
discoveredVia: "terraform-state",
|
|
7451
|
+
confidence: 0.9,
|
|
7452
|
+
// IaC is authoritative declared intent.
|
|
7453
|
+
metadata: redactValue(identity),
|
|
7454
|
+
tags: attrTags(attrs.tags),
|
|
7455
|
+
...owner ? { owner } : {}
|
|
7456
|
+
});
|
|
7457
|
+
}
|
|
7458
|
+
for (const raw of resources) {
|
|
7459
|
+
const r = raw;
|
|
7460
|
+
if (r.mode && r.mode !== "managed") continue;
|
|
7461
|
+
if (typeof r.type !== "string" || typeof r.name !== "string") continue;
|
|
7462
|
+
const srcId = addrToId.get(`${r.type}.${r.name}`);
|
|
7463
|
+
if (!srcId) continue;
|
|
7464
|
+
const inst = Array.isArray(r.instances) ? r.instances[0] : void 0;
|
|
7465
|
+
const deps = Array.isArray(inst?.dependencies) ? inst.dependencies : [];
|
|
7466
|
+
for (const dep of deps) {
|
|
7467
|
+
if (typeof dep !== "string") continue;
|
|
7468
|
+
const tgtId = addrToId.get(dep) ?? addrToId.get(dep.split("[")[0]);
|
|
7469
|
+
if (!tgtId || tgtId === srcId) continue;
|
|
7470
|
+
edges.push({ sourceId: srcId, targetId: tgtId, relationship: "depends_on", evidence: evidenceLine("config-declared", `terraform depends_on ${dep}`), confidence: 0.85 });
|
|
7471
|
+
}
|
|
7472
|
+
}
|
|
7473
|
+
return { nodes, edges };
|
|
7474
|
+
}
|
|
7475
|
+
function stateDirs() {
|
|
7476
|
+
return [".", "./terraform", "./infra", "./infrastructure", "./deploy", "./terraform/environments"];
|
|
7477
|
+
}
|
|
7478
|
+
function hintPath(hint) {
|
|
7479
|
+
if (!hint) return void 0;
|
|
7480
|
+
const m = /(?:^|[\s,])tfstate=([^\s,]+)/.exec(hint);
|
|
7481
|
+
return m ? m[1] : void 0;
|
|
7482
|
+
}
|
|
7483
|
+
function resolveStatePath(ctx) {
|
|
7484
|
+
const explicit = hintPath(ctx.hint);
|
|
7485
|
+
if (explicit) return explicit;
|
|
7486
|
+
const found = (ctx.findFiles ?? findFiles)(stateDirs(), ["*.tfstate"], 4, 20).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
7487
|
+
return found[0];
|
|
7488
|
+
}
|
|
7489
|
+
function readStateFile(path) {
|
|
7490
|
+
try {
|
|
7491
|
+
return readFileSync4(path, "utf8");
|
|
7492
|
+
} catch {
|
|
7493
|
+
return "";
|
|
7494
|
+
}
|
|
7495
|
+
}
|
|
7496
|
+
var terraformScanner = {
|
|
7497
|
+
id: "terraform-state",
|
|
7498
|
+
title: "Terraform state (IaC)",
|
|
7499
|
+
platforms: "all",
|
|
7500
|
+
// No shell commands — the state file is read directly via node:fs, so an
|
|
7501
|
+
// operator-supplied path can never inject a command (no `cat "${path}"` interpolation).
|
|
7502
|
+
detect(ctx) {
|
|
7503
|
+
return resolveStatePath(ctx) !== void 0;
|
|
7504
|
+
},
|
|
7505
|
+
async scan(ctx) {
|
|
7506
|
+
const path = resolveStatePath(ctx);
|
|
7507
|
+
if (!path) return { nodes: [], edges: [] };
|
|
7508
|
+
const json2 = (ctx.readFile ?? readStateFile)(path);
|
|
7509
|
+
if (!json2) return { nodes: [], edges: [] };
|
|
7510
|
+
const result = parseTerraformState(json2);
|
|
7511
|
+
return { ...result, report: `terraform-state: ${result.nodes.length} resources, ${result.edges.length} dependencies from ${path}` };
|
|
7512
|
+
}
|
|
7513
|
+
};
|
|
7514
|
+
|
|
7246
7515
|
// src/scanners/registry.ts
|
|
7247
7516
|
function defaultRegistry() {
|
|
7248
|
-
return new ScannerRegistry().register(bookmarksScanner).register(installedAppsScanner).register(portsScanner).register(cloudAwsScanner).register(cloudGcpScanner).register(cloudAzureScanner).register(k8sScanner).register(databasesScanner).register(connectionsScanner).register(serviceConfigScanner);
|
|
7517
|
+
return new ScannerRegistry().register(bookmarksScanner).register(installedAppsScanner).register(portsScanner).register(cloudAwsScanner).register(cloudGcpScanner).register(cloudAzureScanner).register(k8sScanner).register(databasesScanner).register(connectionsScanner).register(serviceConfigScanner).register(terraformScanner);
|
|
7249
7518
|
}
|
|
7250
7519
|
|
|
7251
7520
|
// src/scanners/loader.ts
|
|
@@ -8613,13 +8882,13 @@ var AuthConfigSchema = z9.object({
|
|
|
8613
8882
|
});
|
|
8614
8883
|
|
|
8615
8884
|
// src/api/start.ts
|
|
8616
|
-
import { readFileSync as
|
|
8885
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
8617
8886
|
import { dirname as dirname3, resolve } from "path";
|
|
8618
8887
|
import { fileURLToPath } from "url";
|
|
8619
8888
|
function readVersion() {
|
|
8620
8889
|
try {
|
|
8621
8890
|
const dir = import.meta.dirname ?? dirname3(fileURLToPath(import.meta.url));
|
|
8622
|
-
return JSON.parse(
|
|
8891
|
+
return JSON.parse(readFileSync5(resolve(dir, "..", "package.json"), "utf-8")).version ?? "0.0.0";
|
|
8623
8892
|
} catch {
|
|
8624
8893
|
return "0.0.0";
|
|
8625
8894
|
}
|
|
@@ -8750,7 +9019,7 @@ function defaultServerEntry(opts = {}) {
|
|
|
8750
9019
|
}
|
|
8751
9020
|
|
|
8752
9021
|
// src/installer/install.ts
|
|
8753
|
-
import { mkdirSync as mkdirSync4, readFileSync as
|
|
9022
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync4 } from "fs";
|
|
8754
9023
|
import { dirname as dirname4 } from "path";
|
|
8755
9024
|
import { homedir as homedir3 } from "os";
|
|
8756
9025
|
function currentOs() {
|
|
@@ -8767,7 +9036,7 @@ function planInstall(spec, ctx, opts) {
|
|
|
8767
9036
|
throw new Error(`${spec.label} does not support the "${ctx.scope}" scope.`);
|
|
8768
9037
|
}
|
|
8769
9038
|
const fileExists = existsSync4(path);
|
|
8770
|
-
const before = fileExists ?
|
|
9039
|
+
const before = fileExists ? readFileSync6(path, "utf8") : "";
|
|
8771
9040
|
const existing = parseConfig(before, spec.format);
|
|
8772
9041
|
const merged = spec.apply(existing, opts.serverName ?? DEFAULT_SERVER_NAME, opts.entry);
|
|
8773
9042
|
const after = serializeConfig(merged, spec.format);
|
|
@@ -9633,7 +9902,7 @@ Use ask_user when you need context from the user.`;
|
|
|
9633
9902
|
}
|
|
9634
9903
|
|
|
9635
9904
|
// src/cost.ts
|
|
9636
|
-
import { readFileSync as
|
|
9905
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
9637
9906
|
import { resolve as resolve2 } from "path";
|
|
9638
9907
|
function splitCsvLine(line) {
|
|
9639
9908
|
const out = [];
|
|
@@ -9712,7 +9981,7 @@ var CsvCostSource = class {
|
|
|
9712
9981
|
}
|
|
9713
9982
|
id;
|
|
9714
9983
|
async fetch() {
|
|
9715
|
-
const text =
|
|
9984
|
+
const text = readFileSync7(resolve2(this.opts.filePath), "utf-8");
|
|
9716
9985
|
const records = parseCostCsv(text);
|
|
9717
9986
|
const match = this.opts.match ?? "nodeId";
|
|
9718
9987
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -11477,7 +11746,7 @@ function formatComplianceText(report) {
|
|
|
11477
11746
|
}
|
|
11478
11747
|
|
|
11479
11748
|
// src/config.ts
|
|
11480
|
-
import { readFileSync as
|
|
11749
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
11481
11750
|
var ConfigError = class extends Error {
|
|
11482
11751
|
constructor(message) {
|
|
11483
11752
|
super(message);
|
|
@@ -11502,7 +11771,7 @@ function loadConfig(path) {
|
|
|
11502
11771
|
function readConfigFile(path) {
|
|
11503
11772
|
let raw;
|
|
11504
11773
|
try {
|
|
11505
|
-
raw =
|
|
11774
|
+
raw = readFileSync8(path, "utf-8");
|
|
11506
11775
|
} catch (err) {
|
|
11507
11776
|
throw new ConfigError(
|
|
11508
11777
|
`Cannot read config file ${path}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -11860,14 +12129,14 @@ function runSyncClassify(db, sessionId, config, opts = {}) {
|
|
|
11860
12129
|
|
|
11861
12130
|
// src/preflight.ts
|
|
11862
12131
|
import { execSync as execSync2 } from "child_process";
|
|
11863
|
-
import { existsSync as existsSync5, readFileSync as
|
|
12132
|
+
import { existsSync as existsSync5, readFileSync as readFileSync9 } from "fs";
|
|
11864
12133
|
import { join as join6 } from "path";
|
|
11865
12134
|
function isOAuthLoggedIn() {
|
|
11866
12135
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "/tmp";
|
|
11867
12136
|
const credFile = join6(home, ".claude", ".credentials.json");
|
|
11868
12137
|
if (!existsSync5(credFile)) return false;
|
|
11869
12138
|
try {
|
|
11870
|
-
const creds = JSON.parse(
|
|
12139
|
+
const creds = JSON.parse(readFileSync9(credFile, "utf8"));
|
|
11871
12140
|
const oauth = creds["claudeAiOauth"];
|
|
11872
12141
|
return typeof oauth?.["accessToken"] === "string" && oauth["accessToken"].length > 0;
|
|
11873
12142
|
} catch {
|
|
@@ -11924,6 +12193,7 @@ export {
|
|
|
11924
12193
|
AuthorizationError,
|
|
11925
12194
|
CLIENTS,
|
|
11926
12195
|
CONFIDENCE,
|
|
12196
|
+
CORRELATION_CONFIDENCE,
|
|
11927
12197
|
CartographyDB,
|
|
11928
12198
|
ComplianceReportSchema,
|
|
11929
12199
|
ComplianceRuleSchema,
|
|
@@ -12010,6 +12280,7 @@ export {
|
|
|
12010
12280
|
computeIdentity,
|
|
12011
12281
|
connectionsScanner,
|
|
12012
12282
|
contentHash,
|
|
12283
|
+
correlateTopology,
|
|
12013
12284
|
createBashTool,
|
|
12014
12285
|
createCartographyTools,
|
|
12015
12286
|
createClaudeProvider,
|
|
@@ -12057,6 +12328,7 @@ export {
|
|
|
12057
12328
|
exportJGF,
|
|
12058
12329
|
exportJSON,
|
|
12059
12330
|
extractListeningPorts,
|
|
12331
|
+
extractSignals,
|
|
12060
12332
|
filterBySeverity,
|
|
12061
12333
|
findAnonViolations,
|
|
12062
12334
|
formatComplianceText,
|
|
@@ -12123,6 +12395,7 @@ export {
|
|
|
12123
12395
|
parseNginxUpstreams,
|
|
12124
12396
|
parseNlQuery,
|
|
12125
12397
|
parseScanHint,
|
|
12398
|
+
parseTerraformState,
|
|
12126
12399
|
pixelToHex,
|
|
12127
12400
|
planInstall,
|
|
12128
12401
|
portsScanner,
|
|
@@ -12172,6 +12445,8 @@ export {
|
|
|
12172
12445
|
stableStringify,
|
|
12173
12446
|
startApi,
|
|
12174
12447
|
stripSensitive,
|
|
12448
|
+
terraformScanner,
|
|
12449
|
+
terraformTypeToNode,
|
|
12175
12450
|
timingSafeEqual,
|
|
12176
12451
|
toBackstageEntities,
|
|
12177
12452
|
validateScanner,
|