@datasynx/agentic-ai-cartography 2.10.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-ASCA3UFM.js → chunk-FFUUNSWP.js} +130 -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 +155 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +138 -12
- package/dist/index.js.map +1 -1
- package/dist/mcp-bin.js +2 -2
- package/package.json +1 -1
- package/server.json +2 -2
- package/dist/chunk-ASCA3UFM.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
|
@@ -3391,6 +3391,7 @@ export {
|
|
|
3391
3391
|
k8sScanner,
|
|
3392
3392
|
databasesScanner,
|
|
3393
3393
|
stripSensitive,
|
|
3394
|
+
redactSecrets,
|
|
3394
3395
|
redactValue,
|
|
3395
3396
|
buildCartographyToolHandlers,
|
|
3396
3397
|
createCartographyTools,
|
|
@@ -3414,4 +3415,4 @@ export {
|
|
|
3414
3415
|
AuthorizationError,
|
|
3415
3416
|
authorize
|
|
3416
3417
|
};
|
|
3417
|
-
//# sourceMappingURL=chunk-
|
|
3418
|
+
//# sourceMappingURL=chunk-LO6YFS6H.js.map
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
defaultAllowedHosts,
|
|
11
11
|
normalizeTenant,
|
|
12
12
|
resolvePrincipal
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-LO6YFS6H.js";
|
|
14
14
|
import {
|
|
15
15
|
ANOMALY_KINDS,
|
|
16
16
|
ANOMALY_SEVERITIES,
|
|
@@ -1409,4 +1409,4 @@ export {
|
|
|
1409
1409
|
parseApiArgs,
|
|
1410
1410
|
startApi
|
|
1411
1411
|
};
|
|
1412
|
-
//# sourceMappingURL=chunk-
|
|
1412
|
+
//# sourceMappingURL=chunk-PD67MOKR.js.map
|
package/dist/cli.js
CHANGED
|
@@ -11,12 +11,12 @@ import {
|
|
|
11
11
|
runDrift,
|
|
12
12
|
runLocalDiscovery,
|
|
13
13
|
startMcp
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-FFUUNSWP.js";
|
|
15
15
|
import {
|
|
16
16
|
entitiesToYaml,
|
|
17
17
|
startApi,
|
|
18
18
|
toBackstageEntities
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-PD67MOKR.js";
|
|
20
20
|
import {
|
|
21
21
|
CartographyDB,
|
|
22
22
|
buildCartographyToolHandlers,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
redactValue,
|
|
29
29
|
stableStringify,
|
|
30
30
|
stripSensitive
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-LO6YFS6H.js";
|
|
32
32
|
import {
|
|
33
33
|
ConfigFileSchema,
|
|
34
34
|
CostEntrySchema,
|
package/dist/index.cjs
CHANGED
|
@@ -238,6 +238,7 @@ __export(src_exports, {
|
|
|
238
238
|
parseNginxUpstreams: () => parseNginxUpstreams,
|
|
239
239
|
parseNlQuery: () => parseNlQuery,
|
|
240
240
|
parseScanHint: () => parseScanHint,
|
|
241
|
+
parseTerraformState: () => parseTerraformState,
|
|
241
242
|
pixelToHex: () => pixelToHex,
|
|
242
243
|
planInstall: () => planInstall,
|
|
243
244
|
portsScanner: () => portsScanner,
|
|
@@ -287,6 +288,8 @@ __export(src_exports, {
|
|
|
287
288
|
stableStringify: () => stableStringify,
|
|
288
289
|
startApi: () => startApi,
|
|
289
290
|
stripSensitive: () => stripSensitive,
|
|
291
|
+
terraformScanner: () => terraformScanner,
|
|
292
|
+
terraformTypeToNode: () => terraformTypeToNode,
|
|
290
293
|
timingSafeEqual: () => timingSafeEqual,
|
|
291
294
|
toBackstageEntities: () => toBackstageEntities,
|
|
292
295
|
validateScanner: () => validateScanner,
|
|
@@ -6276,7 +6279,7 @@ function correlateTopology(nodes, _edges = []) {
|
|
|
6276
6279
|
|
|
6277
6280
|
// src/mcp/server.ts
|
|
6278
6281
|
var SERVER_NAME = "cartography";
|
|
6279
|
-
var SERVER_VERSION = "2.
|
|
6282
|
+
var SERVER_VERSION = "2.11.0";
|
|
6280
6283
|
var SERVICE_TYPES = NODE_TYPE_GROUPS.web;
|
|
6281
6284
|
var DATA_TYPES = NODE_TYPE_GROUPS.data;
|
|
6282
6285
|
var lexicalSearch = async (db, sessionId, query, opts) => db.searchNodes(sessionId, query, { types: opts.types, limit: opts.limit }).map((node) => ({ node }));
|
|
@@ -7686,9 +7689,132 @@ var serviceConfigScanner = {
|
|
|
7686
7689
|
}
|
|
7687
7690
|
};
|
|
7688
7691
|
|
|
7692
|
+
// src/scanners/terraform.ts
|
|
7693
|
+
var import_node_fs5 = require("fs");
|
|
7694
|
+
var TYPE_RULES = [
|
|
7695
|
+
[/(db_instance|_rds|sql_database|sql_instance|database_instance|cosmosdb|dynamodb|spanner|bigtable|documentdb|redshift)/, "database_server"],
|
|
7696
|
+
[/(elasticache|_redis|memcached|memorystore)/, "cache_server"],
|
|
7697
|
+
[/(s3_bucket|storage_bucket|gcs_bucket|storage_account|_blob)/, "database"],
|
|
7698
|
+
[/(_sqs|_queue|servicebus_queue)/, "queue"],
|
|
7699
|
+
[/(_sns|_topic|pubsub_topic|servicebus_topic)/, "topic"],
|
|
7700
|
+
[/(kafka|_msk|event_hub|kinesis)/, "message_broker"],
|
|
7701
|
+
[/(_eks|_gke|_aks|kubernetes_cluster|container_cluster)/, "k8s_cluster"],
|
|
7702
|
+
[/(ecs_|_container|fargate)/, "container"],
|
|
7703
|
+
[/(lambda|cloud_function|cloudfunctions|function_app|cloud_run)/, "web_service"],
|
|
7704
|
+
[/(_lb$|load_balancer|_alb|_elb|application_gateway)/, "web_service"],
|
|
7705
|
+
[/(api_gateway|apigateway)/, "api_endpoint"],
|
|
7706
|
+
[/(_instance|virtual_machine|_vm$|compute_instance)/, "host"]
|
|
7707
|
+
];
|
|
7708
|
+
function terraformTypeToNode(tfType) {
|
|
7709
|
+
const t = tfType.toLowerCase();
|
|
7710
|
+
for (const [re, nt] of TYPE_RULES) if (re.test(t)) return nt;
|
|
7711
|
+
return "unknown";
|
|
7712
|
+
}
|
|
7713
|
+
var IDENTITY_ATTRS = ["id", "arn", "region", "location", "instance_type", "engine", "machine_type"];
|
|
7714
|
+
var OWNER_TAGS = ["Owner", "owner", "Team", "team"];
|
|
7715
|
+
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"]);
|
|
7716
|
+
var SECRET_KEY = /pass|secret|token|key|pwd|cred|private/i;
|
|
7717
|
+
function attrTags(tags) {
|
|
7718
|
+
if (!tags || typeof tags !== "object") return [];
|
|
7719
|
+
return Object.entries(tags).filter(([k]) => SAFE_TAG_KEYS.has(k) && !SECRET_KEY.test(k)).map(([k, v]) => `${k}:${redactSecrets(String(v))}`);
|
|
7720
|
+
}
|
|
7721
|
+
function parseTerraformState(json2) {
|
|
7722
|
+
let state;
|
|
7723
|
+
try {
|
|
7724
|
+
state = JSON.parse(json2);
|
|
7725
|
+
} catch {
|
|
7726
|
+
return { nodes: [], edges: [] };
|
|
7727
|
+
}
|
|
7728
|
+
const resources = Array.isArray(state?.resources) ? state.resources : [];
|
|
7729
|
+
const nodes = [];
|
|
7730
|
+
const edges = [];
|
|
7731
|
+
const addrToId = /* @__PURE__ */ new Map();
|
|
7732
|
+
for (const raw of resources) {
|
|
7733
|
+
const r = raw;
|
|
7734
|
+
if (r.mode && r.mode !== "managed") continue;
|
|
7735
|
+
if (typeof r.type !== "string" || typeof r.name !== "string") continue;
|
|
7736
|
+
const address = `${r.type}.${r.name}`;
|
|
7737
|
+
const nt = terraformTypeToNode(r.type);
|
|
7738
|
+
const id = `${nt}:terraform:${address}`;
|
|
7739
|
+
if (addrToId.has(address)) continue;
|
|
7740
|
+
addrToId.set(address, id);
|
|
7741
|
+
const inst = Array.isArray(r.instances) ? r.instances[0] : void 0;
|
|
7742
|
+
const attrs = inst?.attributes ?? {};
|
|
7743
|
+
const identity = { source: "terraform", tfType: r.type };
|
|
7744
|
+
for (const k of IDENTITY_ATTRS) if (attrs[k] !== void 0) identity[k] = attrs[k];
|
|
7745
|
+
const owner = OWNER_TAGS.map((k) => attrs.tags?.[k]).find((v) => typeof v === "string");
|
|
7746
|
+
nodes.push({
|
|
7747
|
+
id,
|
|
7748
|
+
type: nt,
|
|
7749
|
+
name: address,
|
|
7750
|
+
discoveredVia: "terraform-state",
|
|
7751
|
+
confidence: 0.9,
|
|
7752
|
+
// IaC is authoritative declared intent.
|
|
7753
|
+
metadata: redactValue(identity),
|
|
7754
|
+
tags: attrTags(attrs.tags),
|
|
7755
|
+
...owner ? { owner } : {}
|
|
7756
|
+
});
|
|
7757
|
+
}
|
|
7758
|
+
for (const raw of resources) {
|
|
7759
|
+
const r = raw;
|
|
7760
|
+
if (r.mode && r.mode !== "managed") continue;
|
|
7761
|
+
if (typeof r.type !== "string" || typeof r.name !== "string") continue;
|
|
7762
|
+
const srcId = addrToId.get(`${r.type}.${r.name}`);
|
|
7763
|
+
if (!srcId) continue;
|
|
7764
|
+
const inst = Array.isArray(r.instances) ? r.instances[0] : void 0;
|
|
7765
|
+
const deps = Array.isArray(inst?.dependencies) ? inst.dependencies : [];
|
|
7766
|
+
for (const dep of deps) {
|
|
7767
|
+
if (typeof dep !== "string") continue;
|
|
7768
|
+
const tgtId = addrToId.get(dep) ?? addrToId.get(dep.split("[")[0]);
|
|
7769
|
+
if (!tgtId || tgtId === srcId) continue;
|
|
7770
|
+
edges.push({ sourceId: srcId, targetId: tgtId, relationship: "depends_on", evidence: evidenceLine("config-declared", `terraform depends_on ${dep}`), confidence: 0.85 });
|
|
7771
|
+
}
|
|
7772
|
+
}
|
|
7773
|
+
return { nodes, edges };
|
|
7774
|
+
}
|
|
7775
|
+
function stateDirs() {
|
|
7776
|
+
return [".", "./terraform", "./infra", "./infrastructure", "./deploy", "./terraform/environments"];
|
|
7777
|
+
}
|
|
7778
|
+
function hintPath(hint) {
|
|
7779
|
+
if (!hint) return void 0;
|
|
7780
|
+
const m = /(?:^|[\s,])tfstate=([^\s,]+)/.exec(hint);
|
|
7781
|
+
return m ? m[1] : void 0;
|
|
7782
|
+
}
|
|
7783
|
+
function resolveStatePath(ctx) {
|
|
7784
|
+
const explicit = hintPath(ctx.hint);
|
|
7785
|
+
if (explicit) return explicit;
|
|
7786
|
+
const found = (ctx.findFiles ?? findFiles)(stateDirs(), ["*.tfstate"], 4, 20).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
7787
|
+
return found[0];
|
|
7788
|
+
}
|
|
7789
|
+
function readStateFile(path) {
|
|
7790
|
+
try {
|
|
7791
|
+
return (0, import_node_fs5.readFileSync)(path, "utf8");
|
|
7792
|
+
} catch {
|
|
7793
|
+
return "";
|
|
7794
|
+
}
|
|
7795
|
+
}
|
|
7796
|
+
var terraformScanner = {
|
|
7797
|
+
id: "terraform-state",
|
|
7798
|
+
title: "Terraform state (IaC)",
|
|
7799
|
+
platforms: "all",
|
|
7800
|
+
// No shell commands — the state file is read directly via node:fs, so an
|
|
7801
|
+
// operator-supplied path can never inject a command (no `cat "${path}"` interpolation).
|
|
7802
|
+
detect(ctx) {
|
|
7803
|
+
return resolveStatePath(ctx) !== void 0;
|
|
7804
|
+
},
|
|
7805
|
+
async scan(ctx) {
|
|
7806
|
+
const path = resolveStatePath(ctx);
|
|
7807
|
+
if (!path) return { nodes: [], edges: [] };
|
|
7808
|
+
const json2 = (ctx.readFile ?? readStateFile)(path);
|
|
7809
|
+
if (!json2) return { nodes: [], edges: [] };
|
|
7810
|
+
const result = parseTerraformState(json2);
|
|
7811
|
+
return { ...result, report: `terraform-state: ${result.nodes.length} resources, ${result.edges.length} dependencies from ${path}` };
|
|
7812
|
+
}
|
|
7813
|
+
};
|
|
7814
|
+
|
|
7689
7815
|
// src/scanners/registry.ts
|
|
7690
7816
|
function defaultRegistry() {
|
|
7691
|
-
return new ScannerRegistry().register(bookmarksScanner).register(installedAppsScanner).register(portsScanner).register(cloudAwsScanner).register(cloudGcpScanner).register(cloudAzureScanner).register(k8sScanner).register(databasesScanner).register(connectionsScanner).register(serviceConfigScanner);
|
|
7817
|
+
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);
|
|
7692
7818
|
}
|
|
7693
7819
|
|
|
7694
7820
|
// src/scanners/loader.ts
|
|
@@ -9056,14 +9182,14 @@ var AuthConfigSchema = import_zod9.z.object({
|
|
|
9056
9182
|
});
|
|
9057
9183
|
|
|
9058
9184
|
// src/api/start.ts
|
|
9059
|
-
var
|
|
9185
|
+
var import_node_fs6 = require("fs");
|
|
9060
9186
|
var import_node_path5 = require("path");
|
|
9061
9187
|
var import_node_url = require("url");
|
|
9062
9188
|
var import_meta = {};
|
|
9063
9189
|
function readVersion() {
|
|
9064
9190
|
try {
|
|
9065
9191
|
const dir = import_meta.dirname ?? (0, import_node_path5.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
9066
|
-
return JSON.parse((0,
|
|
9192
|
+
return JSON.parse((0, import_node_fs6.readFileSync)((0, import_node_path5.resolve)(dir, "..", "package.json"), "utf-8")).version ?? "0.0.0";
|
|
9067
9193
|
} catch {
|
|
9068
9194
|
return "0.0.0";
|
|
9069
9195
|
}
|
|
@@ -9194,7 +9320,7 @@ function defaultServerEntry(opts = {}) {
|
|
|
9194
9320
|
}
|
|
9195
9321
|
|
|
9196
9322
|
// src/installer/install.ts
|
|
9197
|
-
var
|
|
9323
|
+
var import_node_fs7 = require("fs");
|
|
9198
9324
|
var import_node_path6 = require("path");
|
|
9199
9325
|
var import_node_os4 = require("os");
|
|
9200
9326
|
function currentOs() {
|
|
@@ -9210,8 +9336,8 @@ function planInstall(spec, ctx, opts) {
|
|
|
9210
9336
|
if (!path) {
|
|
9211
9337
|
throw new Error(`${spec.label} does not support the "${ctx.scope}" scope.`);
|
|
9212
9338
|
}
|
|
9213
|
-
const fileExists = (0,
|
|
9214
|
-
const before = fileExists ? (0,
|
|
9339
|
+
const fileExists = (0, import_node_fs7.existsSync)(path);
|
|
9340
|
+
const before = fileExists ? (0, import_node_fs7.readFileSync)(path, "utf8") : "";
|
|
9215
9341
|
const existing = parseConfig(before, spec.format);
|
|
9216
9342
|
const merged = spec.apply(existing, opts.serverName ?? DEFAULT_SERVER_NAME, opts.entry);
|
|
9217
9343
|
const after = serializeConfig(merged, spec.format);
|
|
@@ -9228,8 +9354,8 @@ function planInstall(spec, ctx, opts) {
|
|
|
9228
9354
|
};
|
|
9229
9355
|
}
|
|
9230
9356
|
function applyInstall(plan) {
|
|
9231
|
-
(0,
|
|
9232
|
-
(0,
|
|
9357
|
+
(0, import_node_fs7.mkdirSync)((0, import_node_path6.dirname)(plan.path), { recursive: true });
|
|
9358
|
+
(0, import_node_fs7.writeFileSync)(plan.path, plan.after, "utf8");
|
|
9233
9359
|
}
|
|
9234
9360
|
function renderDiff(before, after) {
|
|
9235
9361
|
if (before === after) return " (no changes)";
|
|
@@ -10077,7 +10203,7 @@ Use ask_user when you need context from the user.`;
|
|
|
10077
10203
|
}
|
|
10078
10204
|
|
|
10079
10205
|
// src/cost.ts
|
|
10080
|
-
var
|
|
10206
|
+
var import_node_fs8 = require("fs");
|
|
10081
10207
|
var import_node_path8 = require("path");
|
|
10082
10208
|
function splitCsvLine(line) {
|
|
10083
10209
|
const out = [];
|
|
@@ -10156,7 +10282,7 @@ var CsvCostSource = class {
|
|
|
10156
10282
|
}
|
|
10157
10283
|
id;
|
|
10158
10284
|
async fetch() {
|
|
10159
|
-
const text = (0,
|
|
10285
|
+
const text = (0, import_node_fs8.readFileSync)((0, import_node_path8.resolve)(this.opts.filePath), "utf-8");
|
|
10160
10286
|
const records = parseCostCsv(text);
|
|
10161
10287
|
const match = this.opts.match ?? "nodeId";
|
|
10162
10288
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -10198,7 +10324,7 @@ async function enrichCosts(db, sessionId, source) {
|
|
|
10198
10324
|
}
|
|
10199
10325
|
|
|
10200
10326
|
// src/exporter.ts
|
|
10201
|
-
var
|
|
10327
|
+
var import_node_fs9 = require("fs");
|
|
10202
10328
|
var import_node_path9 = require("path");
|
|
10203
10329
|
|
|
10204
10330
|
// src/hex.ts
|
|
@@ -11868,28 +11994,28 @@ function exportComplianceReport(report, format) {
|
|
|
11868
11994
|
return lines.join("\n");
|
|
11869
11995
|
}
|
|
11870
11996
|
function exportAll(db, sessionId, outputDir, formats = ["mermaid", "json", "yaml", "html", "map", "discovery"]) {
|
|
11871
|
-
(0,
|
|
11997
|
+
(0, import_node_fs9.mkdirSync)(outputDir, { recursive: true });
|
|
11872
11998
|
const nodes = db.getNodes(sessionId);
|
|
11873
11999
|
const edges = db.getEdges(sessionId);
|
|
11874
12000
|
const jgfPath = (0, import_node_path9.join)(outputDir, "cartography-graph.jgf.json");
|
|
11875
|
-
(0,
|
|
12001
|
+
(0, import_node_fs9.writeFileSync)(jgfPath, exportJGF(nodes, edges));
|
|
11876
12002
|
if (formats.includes("mermaid")) {
|
|
11877
|
-
(0,
|
|
11878
|
-
(0,
|
|
12003
|
+
(0, import_node_fs9.writeFileSync)((0, import_node_path9.join)(outputDir, "topology.mermaid"), generateTopologyMermaid(nodes, edges));
|
|
12004
|
+
(0, import_node_fs9.writeFileSync)((0, import_node_path9.join)(outputDir, "dependencies.mermaid"), generateDependencyMermaid(nodes, edges));
|
|
11879
12005
|
}
|
|
11880
12006
|
if (formats.includes("json")) {
|
|
11881
|
-
(0,
|
|
12007
|
+
(0, import_node_fs9.writeFileSync)((0, import_node_path9.join)(outputDir, "catalog.json"), exportJSON(db, sessionId));
|
|
11882
12008
|
}
|
|
11883
12009
|
if (formats.includes("yaml")) {
|
|
11884
|
-
(0,
|
|
12010
|
+
(0, import_node_fs9.writeFileSync)((0, import_node_path9.join)(outputDir, "catalog-info.yaml"), exportBackstageYAML(nodes, edges));
|
|
11885
12011
|
}
|
|
11886
12012
|
if (formats.includes("html") || formats.includes("map") || formats.includes("discovery")) {
|
|
11887
|
-
(0,
|
|
12013
|
+
(0, import_node_fs9.writeFileSync)((0, import_node_path9.join)(outputDir, "discovery.html"), exportDiscoveryApp(nodes, edges));
|
|
11888
12014
|
}
|
|
11889
12015
|
if (formats.includes("cost")) {
|
|
11890
12016
|
const summary = db.getGraphSummary(sessionId);
|
|
11891
|
-
(0,
|
|
11892
|
-
(0,
|
|
12017
|
+
(0, import_node_fs9.writeFileSync)((0, import_node_path9.join)(outputDir, "cost-by-domain.csv"), exportCostCSV(summary));
|
|
12018
|
+
(0, import_node_fs9.writeFileSync)((0, import_node_path9.join)(outputDir, "cost-summary.json"), exportCostSummary(summary));
|
|
11893
12019
|
}
|
|
11894
12020
|
}
|
|
11895
12021
|
|
|
@@ -11921,7 +12047,7 @@ function formatComplianceText(report) {
|
|
|
11921
12047
|
}
|
|
11922
12048
|
|
|
11923
12049
|
// src/config.ts
|
|
11924
|
-
var
|
|
12050
|
+
var import_node_fs10 = require("fs");
|
|
11925
12051
|
var ConfigError = class extends Error {
|
|
11926
12052
|
constructor(message) {
|
|
11927
12053
|
super(message);
|
|
@@ -11946,7 +12072,7 @@ function loadConfig(path) {
|
|
|
11946
12072
|
function readConfigFile(path) {
|
|
11947
12073
|
let raw;
|
|
11948
12074
|
try {
|
|
11949
|
-
raw = (0,
|
|
12075
|
+
raw = (0, import_node_fs10.readFileSync)(path, "utf-8");
|
|
11950
12076
|
} catch (err) {
|
|
11951
12077
|
throw new ConfigError(
|
|
11952
12078
|
`Cannot read config file ${path}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -12304,14 +12430,14 @@ function runSyncClassify(db, sessionId, config, opts = {}) {
|
|
|
12304
12430
|
|
|
12305
12431
|
// src/preflight.ts
|
|
12306
12432
|
var import_node_child_process2 = require("child_process");
|
|
12307
|
-
var
|
|
12433
|
+
var import_node_fs11 = require("fs");
|
|
12308
12434
|
var import_node_path10 = require("path");
|
|
12309
12435
|
function isOAuthLoggedIn() {
|
|
12310
12436
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "/tmp";
|
|
12311
12437
|
const credFile = (0, import_node_path10.join)(home, ".claude", ".credentials.json");
|
|
12312
|
-
if (!(0,
|
|
12438
|
+
if (!(0, import_node_fs11.existsSync)(credFile)) return false;
|
|
12313
12439
|
try {
|
|
12314
|
-
const creds = JSON.parse((0,
|
|
12440
|
+
const creds = JSON.parse((0, import_node_fs11.readFileSync)(credFile, "utf8"));
|
|
12315
12441
|
const oauth = creds["claudeAiOauth"];
|
|
12316
12442
|
return typeof oauth?.["accessToken"] === "string" && oauth["accessToken"].length > 0;
|
|
12317
12443
|
} catch {
|
|
@@ -12571,6 +12697,7 @@ function checkClaudePrerequisites() {
|
|
|
12571
12697
|
parseNginxUpstreams,
|
|
12572
12698
|
parseNlQuery,
|
|
12573
12699
|
parseScanHint,
|
|
12700
|
+
parseTerraformState,
|
|
12574
12701
|
pixelToHex,
|
|
12575
12702
|
planInstall,
|
|
12576
12703
|
portsScanner,
|
|
@@ -12620,6 +12747,8 @@ function checkClaudePrerequisites() {
|
|
|
12620
12747
|
stableStringify,
|
|
12621
12748
|
startApi,
|
|
12622
12749
|
stripSensitive,
|
|
12750
|
+
terraformScanner,
|
|
12751
|
+
terraformTypeToNode,
|
|
12623
12752
|
timingSafeEqual,
|
|
12624
12753
|
toBackstageEntities,
|
|
12625
12754
|
validateScanner,
|