@plumpslabs/kuma 2.3.19 → 2.3.22

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.
Files changed (39) hide show
  1. package/README.md +18 -0
  2. package/dist/index.js +10221 -332
  3. package/package.json +2 -2
  4. package/packages/ide/studio/dist/index.js +37 -5
  5. package/packages/ide/studio/public/index.html +284 -63
  6. package/dist/agentDetector-YOWQVJFR.js +0 -186
  7. package/dist/chunk-3BRBJZ7P.js +0 -1055
  8. package/dist/chunk-3OHYYXYN.js +0 -71
  9. package/dist/chunk-ABKE45T4.js +0 -1264
  10. package/dist/chunk-E2KFPEBT.js +0 -183
  11. package/dist/chunk-FKRSI5U5.js +0 -282
  12. package/dist/chunk-GFLSAXAH.js +0 -155
  13. package/dist/chunk-L7F67KUP.js +0 -172
  14. package/dist/chunk-LVKOGXLC.js +0 -658
  15. package/dist/chunk-PRUTTZBS.js +0 -1113
  16. package/dist/contextDigest-QB5XHPXE.js +0 -177
  17. package/dist/domainRules-QLPAQASB.js +0 -20
  18. package/dist/init-PL4XL662.js +0 -15
  19. package/dist/kumaAstValidator-CNM7FHYA.js +0 -150
  20. package/dist/kumaCheckpoint-J2LDQMEO.js +0 -207
  21. package/dist/kumaCodeScanner-J6B2EHGI.js +0 -563
  22. package/dist/kumaContractEngine-KX27T4N7.js +0 -305
  23. package/dist/kumaDb-4XZ5S2LH.js +0 -65
  24. package/dist/kumaDriftDetector-TOORILSZ.js +0 -237
  25. package/dist/kumaGotchas-XRGFFBTA.js +0 -151
  26. package/dist/kumaGraph-UMXZNGYF.js +0 -44
  27. package/dist/kumaMemory-FBJMV77G.js +0 -16
  28. package/dist/kumaMiner-XJETL7TL.js +0 -176
  29. package/dist/kumaPolicyEngine-2QDJDLM7.js +0 -311
  30. package/dist/kumaProgressiveContext-MWEDRXOH.js +0 -231
  31. package/dist/kumaSearch-PV4QTKE7.js +0 -321
  32. package/dist/kumaTrajectory-7NOAVNG2.js +0 -460
  33. package/dist/kumaVerifier-6YEGC77M.js +0 -265
  34. package/dist/kumaVisualize-264OEBGJ.js +0 -264
  35. package/dist/pathValidator-V4DC6U6Z.js +0 -22
  36. package/dist/safetyAudit-O45SPNTS.js +0 -12
  37. package/dist/safetyScore-TMMRD2MV.js +0 -333
  38. package/dist/sessionMemory-YPKVIOMV.js +0 -6
  39. package/dist/skillGenerator-PWEJKZNX.js +0 -304
@@ -1,265 +0,0 @@
1
- import {
2
- sessionMemory
3
- } from "./chunk-LVKOGXLC.js";
4
- import {
5
- getLatestVerifications,
6
- saveVerification
7
- } from "./chunk-3BRBJZ7P.js";
8
- import "./chunk-E2KFPEBT.js";
9
-
10
- // src/engine/kumaVerifier.ts
11
- import fs from "fs";
12
- import path from "path";
13
- import { exec } from "child_process";
14
- var LOCK_DIR_NAME = ".kuma/verifier.lock";
15
- function getLockDir(root = process.cwd()) {
16
- return path.resolve(root, LOCK_DIR_NAME);
17
- }
18
- function getPidFile(root = process.cwd()) {
19
- return path.join(getLockDir(root), "pid");
20
- }
21
- function acquireFileLock(root) {
22
- const lockDir = getLockDir(root);
23
- try {
24
- fs.mkdirSync(lockDir, { recursive: false });
25
- fs.writeFileSync(getPidFile(root), String(process.pid), "utf-8");
26
- return true;
27
- } catch {
28
- try {
29
- if (fs.existsSync(getPidFile(root))) {
30
- const pid = parseInt(fs.readFileSync(getPidFile(root), "utf-8"), 10);
31
- try {
32
- process.kill(pid, 0);
33
- return false;
34
- } catch {
35
- fs.rmSync(lockDir, { recursive: true, force: true });
36
- return acquireFileLock(root);
37
- }
38
- }
39
- } catch {
40
- }
41
- try {
42
- fs.rmSync(lockDir, { recursive: true, force: true });
43
- return acquireFileLock(root);
44
- } catch {
45
- return false;
46
- }
47
- }
48
- }
49
- function releaseFileLock(root) {
50
- try {
51
- fs.rmSync(getLockDir(root), { recursive: true, force: true });
52
- } catch {
53
- }
54
- }
55
- var _localRunning = false;
56
- var _currentProcess = null;
57
- var STALE_RESULT_MS = 3e5;
58
- var DEFAULT_TIMEOUT_MS = 3e4;
59
- var RUNAWAY_WINDOW_MS = 3e5;
60
- var RUNAWAY_MAX_CALLS = 3;
61
- var _verifyCallTimestamps = [];
62
- function checkRunaway() {
63
- const now = Date.now();
64
- while (_verifyCallTimestamps.length > 0 && _verifyCallTimestamps[0] < now - RUNAWAY_WINDOW_MS) {
65
- _verifyCallTimestamps.shift();
66
- }
67
- if (_verifyCallTimestamps.length >= RUNAWAY_MAX_CALLS) {
68
- const oldestInWindow = _verifyCallTimestamps[0];
69
- const waitMs = RUNAWAY_WINDOW_MS - (now - oldestInWindow);
70
- const waitSec = Math.ceil(waitMs / 1e3);
71
- return `\u26D4 **Runaway protection active** \u2014 ${RUNAWAY_MAX_CALLS}+ verify calls in the last 5 minutes. Please wait ${waitSec}s before trying again.
72
- \u{1F4A1} This prevents resource exhaustion (CPU/RAM) from uncontrolled test spawning.`;
73
- }
74
- _verifyCallTimestamps.push(now);
75
- return null;
76
- }
77
- function getRunningVerificationPid() {
78
- return _currentProcess?.pid ?? null;
79
- }
80
- function detectTestRunner(root = process.cwd()) {
81
- const pkgPath = path.join(root, "package.json");
82
- if (fs.existsSync(pkgPath)) {
83
- try {
84
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
85
- if (pkg.scripts && pkg.scripts.test) {
86
- if (fs.existsSync(path.join(root, "pnpm-lock.yaml"))) return { runner: "pnpm", baseCommand: "pnpm test" };
87
- if (fs.existsSync(path.join(root, "yarn.lock"))) return { runner: "yarn", baseCommand: "yarn test" };
88
- return { runner: "npm", baseCommand: "npm test" };
89
- }
90
- } catch {
91
- }
92
- }
93
- if (fs.existsSync(path.join(root, "pytest.ini")) || fs.existsSync(path.join(root, "pyproject.toml"))) return { runner: "pytest", baseCommand: "pytest" };
94
- if (fs.existsSync(path.join(root, "Cargo.toml"))) return { runner: "cargo", baseCommand: "cargo test" };
95
- if (fs.existsSync(path.join(root, "go.mod"))) return { runner: "go", baseCommand: "go test ./..." };
96
- if (fs.existsSync(path.join(root, "Makefile"))) {
97
- try {
98
- const makefileContent = fs.readFileSync(path.join(root, "Makefile"), "utf-8");
99
- const hasTestTarget = /^test:/m.test(makefileContent) || /^\s+test:/.test(makefileContent);
100
- if (hasTestTarget) return { runner: "make", baseCommand: "make test" };
101
- } catch {
102
- }
103
- }
104
- if (fs.existsSync(path.join(root, "package.json"))) {
105
- try {
106
- const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf-8"));
107
- if (pkg.dependencies || pkg.devDependencies) {
108
- if (fs.existsSync(path.join(root, "tsconfig.json"))) return { runner: "tsc", baseCommand: "npx tsc --noEmit" };
109
- const srcDir = path.join(root, "src");
110
- if (fs.existsSync(srcDir)) return { runner: "node", baseCommand: `node -c "${srcDir}/**/*.js" 2>/dev/null || node --check $(find src -name '*.js' 2>/dev/null | head -5)` };
111
- }
112
- } catch {
113
- }
114
- }
115
- return { runner: "unknown", baseCommand: "npm test || echo 'No test runner configured'" };
116
- }
117
- function checkAllowed(root) {
118
- if (_localRunning) return "\u23F3 Verification already in progress (this instance).";
119
- if (!acquireFileLock(root)) return "\u23F3 Another Kuma instance is running verification.";
120
- return null;
121
- }
122
- async function checkStaleness(scope) {
123
- if (scope !== "session-impact" && scope !== void 0) return null;
124
- try {
125
- const recent = await getLatestVerifications(1);
126
- if (recent.length === 0) return null;
127
- const age = Date.now() - recent[0].created_at * 1e3;
128
- if (age >= STALE_RESULT_MS) return null;
129
- const ageSeconds = Math.floor(age / 1e3);
130
- return [
131
- `\u23E9 **Using cached verification** (${ageSeconds}s old, < 5 min threshold)`,
132
- `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501`,
133
- "",
134
- `\u{1F6E0}\uFE0F Runner: \`${recent[0].runner}\``,
135
- `\u{1F4BB} Command: \`${recent[0].test_command}\``,
136
- `\u{1F3AF} Scope: \`${recent[0].scope}\``,
137
- `\u23F1\uFE0F Original duration: ${recent[0].duration_ms}ms`,
138
- "",
139
- recent[0].passed ? "\u2705 **Result: PASSED** (served from cache)" : "\u{1F534} **Result: FAILED** (served from cache)",
140
- "",
141
- "\u{1F4A1} Use `force: true` to bypass cache and run tests again."
142
- ].join("\n");
143
- } catch {
144
- return null;
145
- }
146
- }
147
- async function runAutoVerification(options = {}) {
148
- const startTime = Date.now();
149
- const root = process.cwd();
150
- const scope = options.scope || "session-impact";
151
- const timeoutMs = options.timeoutMs || DEFAULT_TIMEOUT_MS;
152
- const denial = checkAllowed(root);
153
- if (denial) return denial;
154
- const runawayBlock = checkRunaway();
155
- if (runawayBlock) {
156
- releaseFileLock(root);
157
- return runawayBlock;
158
- }
159
- try {
160
- if (!options.force) {
161
- const cached = await checkStaleness(scope);
162
- if (cached) {
163
- releaseFileLock(root);
164
- return cached;
165
- }
166
- }
167
- _localRunning = true;
168
- const { runner, baseCommand } = detectTestRunner(root);
169
- let testFiles = [];
170
- const modified = sessionMemory.getModifiedFiles().map((f) => f.filePath);
171
- if (options.scope) {
172
- const term = options.scope.toLowerCase();
173
- testFiles = modified.filter((f) => f.toLowerCase().includes(term));
174
- if (testFiles.length === 0) {
175
- try {
176
- const { default: glob } = await import("fast-glob");
177
- testFiles = await glob([`**/*${term}*test*.*`, `**/*test*/*${term}*.*`], { cwd: root, ignore: ["node_modules/**", "dist/**"] });
178
- } catch {
179
- }
180
- }
181
- } else {
182
- testFiles = modified.filter((f) => f.includes(".test.") || f.includes(".spec.") || f.includes("_test."));
183
- }
184
- let fullCommand = baseCommand;
185
- if (testFiles.length > 0 && runner === "npm") {
186
- fullCommand = `${baseCommand} -- ${testFiles.map((f) => `"${f}"`).join(" ")}`;
187
- }
188
- return await new Promise((resolve) => {
189
- const killTimer = setTimeout(() => {
190
- if (_currentProcess && !_currentProcess.killed) {
191
- try {
192
- const childPid = _currentProcess.pid;
193
- if (childPid) {
194
- try {
195
- process.kill(-childPid, "SIGKILL");
196
- } catch {
197
- }
198
- try {
199
- _currentProcess.kill("SIGKILL");
200
- } catch {
201
- }
202
- }
203
- } catch {
204
- }
205
- }
206
- }, timeoutMs + 5e3);
207
- const heartbeatTimer = setInterval(() => {
208
- if (getLockDir(root)) {
209
- try {
210
- fs.writeFileSync(getPidFile(root), String(process.pid), "utf-8");
211
- } catch {
212
- }
213
- }
214
- }, 15e3);
215
- const child = exec(fullCommand, { cwd: root, timeout: timeoutMs }, async (error, stdout, stderr) => {
216
- const durationMs = Date.now() - startTime;
217
- const rawOutput = (stdout + "\n" + stderr).trim();
218
- const passed = !error;
219
- const truncatedOutput = rawOutput.length > 2e3 ? rawOutput.substring(rawOutput.length - 2e3) : rawOutput;
220
- await saveVerification(scope, runner, fullCommand, passed, truncatedOutput, durationMs);
221
- _localRunning = false;
222
- _currentProcess = null;
223
- releaseFileLock(root);
224
- clearInterval(heartbeatTimer);
225
- const statusSymbol = passed ? "\u2705" : "\u{1F534}";
226
- const lines = [
227
- `${statusSymbol} **Verification ${passed ? "PASSED" : "FAILED"}**`,
228
- `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501`,
229
- "",
230
- `\u{1F6E0}\uFE0F **Runner**: \`${runner}\``,
231
- `\u{1F4BB} **Command**: \`${fullCommand}\``,
232
- `\u{1F3AF} **Scope**: \`${scope}\`${testFiles.length > 0 ? ` (${testFiles.length} file(s) matched)` : ""}`,
233
- `\u23F1\uFE0F **Duration**: ${durationMs}ms`,
234
- ""
235
- ];
236
- if (!passed) {
237
- lines.push("\u26A0\uFE0F **Verification failed!** Please fix test failures before shipping.");
238
- if (error && error.killed) {
239
- lines.push(`\u23F0 **Process was killed after ${timeoutMs}ms timeout**`);
240
- }
241
- lines.push("```text", rawOutput.substring(0, 1500), "```");
242
- } else {
243
- lines.push("\u{1F389} All scoped tests passed!");
244
- if (rawOutput) lines.push("```text", rawOutput.substring(0, 800), "```");
245
- }
246
- resolve(lines.join("\n"));
247
- });
248
- _currentProcess = child;
249
- _localRunning = true;
250
- child.on("close", () => {
251
- clearTimeout(killTimer);
252
- });
253
- });
254
- } catch (err) {
255
- releaseFileLock(root);
256
- _localRunning = false;
257
- _currentProcess = null;
258
- return `\u274C Verification failed with error: ${err}`;
259
- }
260
- }
261
- export {
262
- detectTestRunner,
263
- getRunningVerificationPid,
264
- runAutoVerification
265
- };
@@ -1,264 +0,0 @@
1
- import {
2
- getDb
3
- } from "./chunk-3BRBJZ7P.js";
4
- import "./chunk-E2KFPEBT.js";
5
-
6
- // src/engine/kumaVisualize.ts
7
- async function visualizeGraph(options = {}) {
8
- const {
9
- type = "flowchart",
10
- scope,
11
- maxNodes = 30,
12
- // depth unused: kept for API consistency
13
- format = "mermaid"
14
- } = options;
15
- try {
16
- const db = await getDb();
17
- let nodeSql = `SELECT id, type, name, file_path FROM nodes WHERE 1=1`;
18
- const nodeBind = [];
19
- if (scope) {
20
- nodeSql += ` AND (name LIKE ? OR file_path LIKE ? OR id LIKE ?)`;
21
- nodeBind.push(`%${scope}%`, `%${scope}%`, `%${scope}%`);
22
- }
23
- nodeSql += ` ORDER BY updated_at DESC LIMIT ?`;
24
- nodeBind.push(maxNodes);
25
- const nodeStmt = db.prepare(nodeSql);
26
- nodeStmt.bind(nodeBind);
27
- const nodes = [];
28
- while (nodeStmt.step()) {
29
- nodes.push(nodeStmt.getAsObject());
30
- }
31
- nodeStmt.free();
32
- if (nodes.length === 0) {
33
- return format === "mermaid" ? "```mermaid\nflowchart TD\n Start[Empty Graph \u2014 No nodes found]\n```" : "\u{1F4ED} **Empty Graph** \u2014 No nodes found to visualize.";
34
- }
35
- const nodeIds = nodes.map((n) => n.id);
36
- const edgeSql = `
37
- SELECT e.source_id, e.target_id, e.type, e.weight,
38
- sn.name AS source_name, tn.name AS target_name
39
- FROM edges e
40
- JOIN nodes sn ON sn.id = e.source_id
41
- JOIN nodes tn ON tn.id = e.target_id
42
- WHERE (e.source_id IN (${nodeIds.map(() => "?").join(",")})
43
- OR e.target_id IN (${nodeIds.map(() => "?").join(",")}))
44
- AND e.source_id != e.target_id
45
- ORDER BY e.weight DESC
46
- LIMIT 100
47
- `;
48
- const edgeBind = [...nodeIds, ...nodeIds];
49
- const edgeStmt = db.prepare(edgeSql);
50
- edgeStmt.bind(edgeBind);
51
- const edges = [];
52
- while (edgeStmt.step()) {
53
- edges.push(edgeStmt.getAsObject());
54
- }
55
- edgeStmt.free();
56
- switch (type) {
57
- case "flowchart":
58
- return formatFlowchart(nodes, edges, format);
59
- case "dependency":
60
- return formatDependencyGraph(nodes, edges, format);
61
- case "mindmap":
62
- return formatMindMap(nodes, edges, format);
63
- default:
64
- return formatFlowchart(nodes, edges, format);
65
- }
66
- } catch (err) {
67
- return `Error generating visualization: ${err}`;
68
- }
69
- }
70
- function formatFlowchart(nodes, edges, _format) {
71
- void _format;
72
- const lines = ["```mermaid", "flowchart TD"];
73
- for (const node of nodes) {
74
- const id = sanitizeId(node.id);
75
- const name = truncate(node.name, 30);
76
- const nodeType = node.type;
77
- const shape = getNodeShape(nodeType);
78
- if (shape) {
79
- lines.push(` ${id}${shape}${name}${reverseShape(shape)}`);
80
- } else {
81
- lines.push(` ${id}[${name}]`);
82
- }
83
- }
84
- for (const edge of edges) {
85
- const sourceId = sanitizeId(edge.source_id);
86
- const targetId = sanitizeId(edge.target_id);
87
- const edgeType = edge.type;
88
- void edge.weight;
89
- const label = truncate(edgeType, 15);
90
- const edgeStyle = getEdgeStyle(edgeType);
91
- lines.push(` ${sourceId}${edgeStyle}|${label}|${targetId}`);
92
- }
93
- lines.push("```");
94
- return lines.join("\n");
95
- }
96
- function formatDependencyGraph(nodes, edges, _format) {
97
- void _format;
98
- const lines = ["```mermaid", "flowchart LR"];
99
- const grouped = /* @__PURE__ */ new Map();
100
- for (const node of nodes) {
101
- const type = node.type || "unknown";
102
- if (!grouped.has(type)) grouped.set(type, []);
103
- grouped.get(type).push(node);
104
- }
105
- let subgraphIndex = 0;
106
- for (const [type, typeNodes] of grouped) {
107
- if (typeNodes.length < 1) continue;
108
- lines.push(` subgraph ${type.toUpperCase()}[${type.toUpperCase()}]`);
109
- for (const node of typeNodes) {
110
- const id = sanitizeId(node.id);
111
- const name = truncate(node.name, 25);
112
- lines.push(` ${id}(${name})`);
113
- }
114
- lines.push(" end");
115
- subgraphIndex++;
116
- }
117
- for (const edge of edges) {
118
- const sourceId = sanitizeId(edge.source_id);
119
- const targetId = sanitizeId(edge.target_id);
120
- const edgeType = edge.type;
121
- const style = getEdgeStyle(edgeType);
122
- lines.push(` ${sourceId}${style}|${edgeType}|${targetId}`);
123
- }
124
- lines.push("```");
125
- return lines.join("\n");
126
- }
127
- function formatMindMap(nodes, edges, _format) {
128
- void _format;
129
- const lines = ["```mermaid", "mindmap"];
130
- const hasIncoming = /* @__PURE__ */ new Set();
131
- for (const edge of edges) {
132
- hasIncoming.add(edge.target_id);
133
- }
134
- const roots = nodes.filter((n) => !hasIncoming.has(n.id));
135
- if (roots.length === 0 && nodes.length > 0) {
136
- const root = nodes[0];
137
- lines.push(` root((${truncate(root.name, 25)}))`);
138
- for (const node of nodes.slice(1)) {
139
- lines.push(` ${sanitizeId(node.id)}(${truncate(node.name, 25)})`);
140
- }
141
- } else {
142
- for (const root of roots.slice(0, 3)) {
143
- lines.push(` root((${truncate(root.name, 25)}))`);
144
- }
145
- const others = nodes.filter((n) => !roots.includes(n));
146
- for (const node of others.slice(0, 10)) {
147
- const parent = edges.find((e) => e.source_id === node.id || e.target_id === node.id);
148
- const indent = parent ? " " : " ";
149
- lines.push(`${indent}${sanitizeId(node.id)}(${truncate(node.name, 25)})`);
150
- }
151
- }
152
- lines.push("```");
153
- return lines.join("\n");
154
- }
155
- function sanitizeId(id) {
156
- const safe = id.replace(/[^a-zA-Z0-9_]/g, "_").replace(/^(\d)/, "n$1").substring(0, 40);
157
- return safe || "n0";
158
- }
159
- function truncate(str, maxLen) {
160
- if (str.length <= maxLen) return str;
161
- return str.substring(0, maxLen - 3) + "...";
162
- }
163
- function getNodeShape(type) {
164
- switch (type) {
165
- case "function":
166
- return "([";
167
- case "file":
168
- return "[";
169
- case "test":
170
- return "{";
171
- case "api_route":
172
- return "[[";
173
- case "db_table":
174
- return ">";
175
- // database shape approximation
176
- case "class":
177
- return "[";
178
- case "interface":
179
- return "(";
180
- case "module":
181
- return "[";
182
- case "variable":
183
- return "(";
184
- // Domain Flow shapes (V4)
185
- case "feature_domain":
186
- return "[";
187
- // box with rounded corners
188
- case "workflow":
189
- return "([";
190
- // stadium shape
191
- case "cross_service_link":
192
- return "[";
193
- default:
194
- return "[";
195
- }
196
- }
197
- function reverseShape(shape) {
198
- const map = {
199
- "([": "])",
200
- "[": "]",
201
- "{": "}",
202
- "[[": "]]",
203
- ">": "<]",
204
- "(": ")"
205
- };
206
- return map[shape] || "]";
207
- }
208
- function getEdgeStyle(type) {
209
- switch (type) {
210
- case "calls":
211
- return " ==> ";
212
- case "imports":
213
- return " -.-> ";
214
- case "defines":
215
- return " --- ";
216
- case "tests":
217
- return " -.-> ";
218
- case "routes":
219
- return " ==> ";
220
- case "implements":
221
- return " -.-> ";
222
- case "extends":
223
- return " ==> ";
224
- case "depends_on":
225
- return " -.-> ";
226
- case "owns":
227
- return " --- ";
228
- case "modified_by":
229
- return " -.-> ";
230
- // Domain Flow edge styles (V4)
231
- case "flows_through":
232
- return " ==> ";
233
- case "triggers":
234
- return " -.-> ";
235
- case "syncs_with":
236
- return " <==> ";
237
- default:
238
- return " --- ";
239
- }
240
- }
241
- async function generateVisualizeReport(options = {}) {
242
- const diagram = await visualizeGraph(options);
243
- const lines = [
244
- "\u{1F3A8} **Knowledge Graph Visualization**",
245
- "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501",
246
- "",
247
- diagram,
248
- "",
249
- "\u{1F4CB} **Rendering Instructions:**",
250
- "- Paste the Mermaid code above into any Mermaid-compatible viewer",
251
- "- GitHub: Mermaid code blocks render automatically",
252
- "- VS Code: Install 'Markdown Preview Mermaid Support' extension",
253
- "- Online: https://mermaid.live",
254
- "",
255
- "\u{1F4A1} Use `kuma_visualize({ type: 'dependency' })` for clustered view",
256
- "\u{1F4A1} Use `kuma_visualize({ type: 'mindmap' })` for overview",
257
- "\u{1F4A1} Use `kuma_visualize({ scope: 'auth' })` to filter by topic"
258
- ];
259
- return lines.join("\n");
260
- }
261
- export {
262
- generateVisualizeReport,
263
- visualizeGraph
264
- };
@@ -1,22 +0,0 @@
1
- import {
2
- ensureBackupDir,
3
- getBackupPath,
4
- getKumaBackupsDir,
5
- getKumaDir,
6
- getProjectRoot,
7
- isReadable,
8
- isWritable,
9
- validateFileExtension,
10
- validateFilePath
11
- } from "./chunk-E2KFPEBT.js";
12
- export {
13
- ensureBackupDir,
14
- getBackupPath,
15
- getKumaBackupsDir,
16
- getKumaDir,
17
- getProjectRoot,
18
- isReadable,
19
- isWritable,
20
- validateFileExtension,
21
- validateFilePath
22
- };
@@ -1,12 +0,0 @@
1
- import {
2
- auditStats,
3
- queryAudit,
4
- recordAudit
5
- } from "./chunk-GFLSAXAH.js";
6
- import "./chunk-3BRBJZ7P.js";
7
- import "./chunk-E2KFPEBT.js";
8
- export {
9
- auditStats,
10
- queryAudit,
11
- recordAudit
12
- };