@plumpslabs/kuma 2.3.7 → 2.3.9
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 +25 -3
- package/dist/{chunk-GDNAWLHF.js → chunk-3TX6Q37T.js} +89 -2
- package/dist/{chunk-X5TPBDKO.js → chunk-OJALFQ4H.js} +2 -2
- package/dist/chunk-Q2444HWO.js +282 -0
- package/dist/{chunk-BI7KD3SG.js → chunk-R6B3VUSB.js} +2 -2
- package/dist/chunk-RI3DKY62.js +155 -0
- package/dist/{chunk-FOQQ2CSL.js → chunk-SPHI2BOO.js} +1 -1
- package/dist/{chunk-K64NSHBR.js → chunk-ZKDYTYMS.js} +108 -2
- package/dist/contextDigest-5JXLH56Z.js +177 -0
- package/dist/domainRules-ED6EOFVY.js +20 -0
- package/dist/index.js +393 -198
- package/dist/kumaAstValidator-CNM7FHYA.js +150 -0
- package/dist/kumaCheckpoint-XIQWRMGV.js +207 -0
- package/dist/kumaCodeScanner-LFJGPJNH.js +566 -0
- package/dist/kumaContractEngine-KX27T4N7.js +305 -0
- package/dist/{kumaDb-DJUDLYBJ.js → kumaDb-IC7UX7PU.js} +3 -1
- package/dist/kumaDriftDetector-QBY6OJOO.js +237 -0
- package/dist/kumaGotchas-5HODT5RI.js +151 -0
- package/dist/{kumaGraph-35TAIBWD.js → kumaGraph-GUQM75WL.js} +8 -2
- package/dist/{kumaMemory-5SR3TGRL.js → kumaMemory-FMOWIODH.js} +2 -2
- package/dist/{kumaMiner-P5KCUSF7.js → kumaMiner-3RXEOCBP.js} +3 -3
- package/dist/kumaPolicyEngine-ORBWL5PT.js +311 -0
- package/dist/kumaProgressiveContext-CVSNPY3W.js +231 -0
- package/dist/{kumaSearch-LG2OYEJY.js → kumaSearch-B5WVYHHD.js} +1 -1
- package/dist/kumaTrajectory-T6DXGOG4.js +460 -0
- package/dist/{kumaVerifier-LFRNIGSL.js → kumaVerifier-KAYJHR5K.js} +25 -2
- package/dist/{kumaVisualize-ODCWFSUY.js → kumaVisualize-AFL7STLL.js} +1 -1
- package/dist/safetyAudit-32WSA4Z5.js +12 -0
- package/dist/{safetyScore-PJGRRBWP.js → safetyScore-WU27EOG4.js} +5 -5
- package/dist/{sessionMemory-HBBXUSIP.js → sessionMemory-4UWA3E5J.js} +1 -1
- package/package.json +18 -13
- package/packages/ide/studio/dist/index.js +140 -0
- package/packages/ide/studio/public/index.html +500 -0
package/dist/index.js
CHANGED
|
@@ -1,35 +1,40 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
auditStats,
|
|
4
|
+
queryAudit,
|
|
5
|
+
recordAudit
|
|
6
|
+
} from "./chunk-RI3DKY62.js";
|
|
2
7
|
import {
|
|
3
8
|
ALL_CONFIG_TYPES,
|
|
4
9
|
formatInitResults,
|
|
5
10
|
runInit
|
|
6
11
|
} from "./chunk-L5WU2HTN.js";
|
|
7
|
-
import {
|
|
8
|
-
analyzeImpact,
|
|
9
|
-
autoHeal,
|
|
10
|
-
detectStaleNodes,
|
|
11
|
-
formatFlow,
|
|
12
|
-
formatHealReport,
|
|
13
|
-
formatImpact,
|
|
14
|
-
getGraphStats,
|
|
15
|
-
searchGraph,
|
|
16
|
-
traceFlow
|
|
17
|
-
} from "./chunk-K64NSHBR.js";
|
|
18
12
|
import {
|
|
19
13
|
formatDecisionTemplate,
|
|
20
14
|
getProactiveMemories,
|
|
21
15
|
recordDecision,
|
|
22
16
|
scoreMemoryRelevance
|
|
23
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-OJALFQ4H.js";
|
|
24
18
|
import {
|
|
25
19
|
buildDriftMessages,
|
|
26
20
|
getGitDiffStat,
|
|
27
21
|
getSessionStats,
|
|
28
22
|
getUnresolvedCount
|
|
29
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-SPHI2BOO.js";
|
|
30
24
|
import {
|
|
31
25
|
sessionMemory
|
|
32
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-R6B3VUSB.js";
|
|
27
|
+
import {
|
|
28
|
+
analyzeImpact,
|
|
29
|
+
autoHeal,
|
|
30
|
+
detectStaleNodes,
|
|
31
|
+
formatFlow,
|
|
32
|
+
formatHealReport,
|
|
33
|
+
formatImpact,
|
|
34
|
+
getGraphStats,
|
|
35
|
+
searchGraph,
|
|
36
|
+
traceFlow
|
|
37
|
+
} from "./chunk-ZKDYTYMS.js";
|
|
33
38
|
import {
|
|
34
39
|
addContextNote,
|
|
35
40
|
addSecurityFinding,
|
|
@@ -50,12 +55,11 @@ import {
|
|
|
50
55
|
runDoctor,
|
|
51
56
|
runGarbageCollection,
|
|
52
57
|
saveBenchmark,
|
|
53
|
-
saveDb,
|
|
54
58
|
saveHealthSnapshot,
|
|
55
59
|
saveResearchCache,
|
|
56
60
|
updateDecisionStatus,
|
|
57
61
|
updateTodoStatus
|
|
58
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-3TX6Q37T.js";
|
|
59
63
|
import {
|
|
60
64
|
getProjectRoot,
|
|
61
65
|
validateFilePath
|
|
@@ -124,7 +128,24 @@ var CONTEXT_ALIASES = {
|
|
|
124
128
|
"diagram": "visualize",
|
|
125
129
|
"flow": "visualize",
|
|
126
130
|
"viz": "visualize",
|
|
127
|
-
"kuma_visualize": "visualize"
|
|
131
|
+
"kuma_visualize": "visualize",
|
|
132
|
+
// Digest synonyms (Issue #18)
|
|
133
|
+
"digest": "digest",
|
|
134
|
+
"bootstrap": "digest",
|
|
135
|
+
"kuma_digest": "digest",
|
|
136
|
+
"kuma_bootstrap": "digest",
|
|
137
|
+
"briefing": "digest",
|
|
138
|
+
"overview": "digest",
|
|
139
|
+
// Drift detection synonyms (Issue #20)
|
|
140
|
+
"drift": "drift",
|
|
141
|
+
"staleness": "drift",
|
|
142
|
+
"code-drift": "drift",
|
|
143
|
+
"freshness": "drift",
|
|
144
|
+
// Progressive context synonyms (Issue #25)
|
|
145
|
+
"progressive": "progressive",
|
|
146
|
+
"prog": "progressive",
|
|
147
|
+
"section": "progressive",
|
|
148
|
+
"sectional": "progressive"
|
|
128
149
|
};
|
|
129
150
|
async function handleContext(params) {
|
|
130
151
|
const rawAction = params.action || "init";
|
|
@@ -151,8 +172,14 @@ async function handleContext(params) {
|
|
|
151
172
|
return handleSync(params);
|
|
152
173
|
case "visualize":
|
|
153
174
|
return handleVisualize(params);
|
|
175
|
+
case "digest":
|
|
176
|
+
return handleDigest(params);
|
|
177
|
+
case "drift":
|
|
178
|
+
return handleDrift(params);
|
|
179
|
+
case "progressive":
|
|
180
|
+
return handleProgressive(params);
|
|
154
181
|
default:
|
|
155
|
-
return `Unknown action "${action}". Use: init, research, impact, navigate, changes, rollback, researches, health, sync, visualize`;
|
|
182
|
+
return `Unknown action "${action}". Use: init, research, impact, navigate, changes, rollback, researches, health, sync, visualize, digest, drift, progressive`;
|
|
156
183
|
}
|
|
157
184
|
}
|
|
158
185
|
async function handleInit(_params) {
|
|
@@ -213,8 +240,8 @@ async function handleInit(_params) {
|
|
|
213
240
|
lines.push(` \u{1F4DD} Modified: ${summary.modifiedFiles?.length || 0} file(s)`);
|
|
214
241
|
lines.push(` \u{1F6E0}\uFE0F Tool calls: ${summary.toolCallCount}`);
|
|
215
242
|
try {
|
|
216
|
-
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-
|
|
217
|
-
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-
|
|
243
|
+
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-WU27EOG4.js");
|
|
244
|
+
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-IC7UX7PU.js");
|
|
218
245
|
const score = await computeSafetyScore(_params.goal);
|
|
219
246
|
const checksStr = JSON.stringify(score.checks);
|
|
220
247
|
await saveHealthSnapshot2(score.score, score.risk, checksStr, score.summary);
|
|
@@ -276,7 +303,7 @@ async function handleResearch(params) {
|
|
|
276
303
|
lines.push(" \u23F3 No content hash available \u2014 will research fresh");
|
|
277
304
|
}
|
|
278
305
|
lines.push("");
|
|
279
|
-
lines.push("**Step 3/5: Graph Query**");
|
|
306
|
+
lines.push("**Step 3/5: Graph Query + Code Scan**");
|
|
280
307
|
try {
|
|
281
308
|
const graphResult = await searchGraph(scope, 15);
|
|
282
309
|
const graphLines = graphResult.split("\n");
|
|
@@ -308,6 +335,14 @@ async function handleResearch(params) {
|
|
|
308
335
|
} catch {
|
|
309
336
|
lines.push(" \u26A0\uFE0F Graph query failed");
|
|
310
337
|
}
|
|
338
|
+
try {
|
|
339
|
+
const { scanCodebase } = await import("./kumaCodeScanner-LFJGPJNH.js");
|
|
340
|
+
const scanResult = await scanCodebase({ scope, maxFiles: 100 });
|
|
341
|
+
if (scanResult.nodeCount > 0 || scanResult.edgeCount > 0) {
|
|
342
|
+
lines.push(` \u{1F52C} Auto-scanned ${scanResult.filesScanned} files \u2192 ${scanResult.nodeCount} nodes, ${scanResult.edgeCount} edges`);
|
|
343
|
+
}
|
|
344
|
+
} catch {
|
|
345
|
+
}
|
|
311
346
|
lines.push("");
|
|
312
347
|
lines.push("**Step 4/5: Impact Analysis**");
|
|
313
348
|
try {
|
|
@@ -387,8 +422,8 @@ async function handleResearches(_params) {
|
|
|
387
422
|
async function handleHealth(_params) {
|
|
388
423
|
sessionMemory.recordToolCall("kuma_context_health", {});
|
|
389
424
|
try {
|
|
390
|
-
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-
|
|
391
|
-
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-
|
|
425
|
+
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-WU27EOG4.js");
|
|
426
|
+
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-IC7UX7PU.js");
|
|
392
427
|
const score = await computeSafetyScore();
|
|
393
428
|
const checksStr = JSON.stringify(score.checks);
|
|
394
429
|
await saveHealthSnapshot2(score.score, score.risk, checksStr, score.summary);
|
|
@@ -415,8 +450,8 @@ async function handleSync(params) {
|
|
|
415
450
|
lines.push(` \u{1F6E0}\uFE0F Tool calls: ${summary.toolCallCount}`);
|
|
416
451
|
lines.push("");
|
|
417
452
|
try {
|
|
418
|
-
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-
|
|
419
|
-
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-
|
|
453
|
+
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-WU27EOG4.js");
|
|
454
|
+
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-IC7UX7PU.js");
|
|
420
455
|
const score = await computeSafetyScore(params.goal);
|
|
421
456
|
const checksStr = JSON.stringify(score.checks);
|
|
422
457
|
await saveHealthSnapshot2(score.score, score.risk, checksStr, score.summary);
|
|
@@ -427,14 +462,14 @@ async function handleSync(params) {
|
|
|
427
462
|
}
|
|
428
463
|
lines.push("");
|
|
429
464
|
try {
|
|
430
|
-
const { getGraphStats: getGraphStats2 } = await import("./kumaGraph-
|
|
465
|
+
const { getGraphStats: getGraphStats2 } = await import("./kumaGraph-GUQM75WL.js");
|
|
431
466
|
lines.push("**Knowledge Graph**");
|
|
432
467
|
lines.push(await getGraphStats2());
|
|
433
468
|
} catch {
|
|
434
469
|
}
|
|
435
470
|
lines.push("");
|
|
436
471
|
try {
|
|
437
|
-
const { getProactiveMemories: getProactiveMemories2 } = await import("./kumaMemory-
|
|
472
|
+
const { getProactiveMemories: getProactiveMemories2 } = await import("./kumaMemory-FMOWIODH.js");
|
|
438
473
|
const memories = getProactiveMemories2();
|
|
439
474
|
if (memories) {
|
|
440
475
|
lines.push("**Relevant Memories**");
|
|
@@ -448,13 +483,74 @@ async function handleSync(params) {
|
|
|
448
483
|
}
|
|
449
484
|
async function handleVisualize(params) {
|
|
450
485
|
const scope = params.scope;
|
|
451
|
-
const { generateVisualizeReport } = await import("./kumaVisualize-
|
|
486
|
+
const { generateVisualizeReport } = await import("./kumaVisualize-AFL7STLL.js");
|
|
452
487
|
return await generateVisualizeReport({
|
|
453
488
|
scope,
|
|
454
489
|
type: "flowchart",
|
|
455
490
|
maxNodes: 40
|
|
456
491
|
});
|
|
457
492
|
}
|
|
493
|
+
async function handleDigest(_params) {
|
|
494
|
+
sessionMemory.recordToolCall("kuma_context_digest", {});
|
|
495
|
+
try {
|
|
496
|
+
const { generateContextDigest } = await import("./contextDigest-5JXLH56Z.js");
|
|
497
|
+
return await generateContextDigest();
|
|
498
|
+
} catch (err) {
|
|
499
|
+
try {
|
|
500
|
+
const { generateDigest } = await import("./domainRules-ED6EOFVY.js");
|
|
501
|
+
return generateDigest();
|
|
502
|
+
} catch {
|
|
503
|
+
return `Error generating digest: ${err}`;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
async function handleDrift(_params) {
|
|
508
|
+
sessionMemory.recordToolCall("kuma_context_drift", {});
|
|
509
|
+
try {
|
|
510
|
+
const { detectDrift, formatDriftReport, flagStaleRecords } = await import("./kumaDriftDetector-QBY6OJOO.js");
|
|
511
|
+
await flagStaleRecords();
|
|
512
|
+
const records = await detectDrift();
|
|
513
|
+
return formatDriftReport(records);
|
|
514
|
+
} catch (err) {
|
|
515
|
+
return `Error detecting drift: ${err}`;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
async function handleProgressive(params) {
|
|
519
|
+
sessionMemory.recordToolCall("kuma_context_progressive", { scope: params.scope, section: params.section });
|
|
520
|
+
try {
|
|
521
|
+
const { getProgressiveContext, loadSection } = await import("./kumaProgressiveContext-CVSNPY3W.js");
|
|
522
|
+
if (params.section) {
|
|
523
|
+
const validSections = ["domain_rules", "architecture", "gotchas", "decisions", "graph", "changes", "health"];
|
|
524
|
+
if (!validSections.includes(params.section)) {
|
|
525
|
+
return `\u26A0\uFE0F Invalid section "${params.section}". Valid sections: ${validSections.join(", ")}`;
|
|
526
|
+
}
|
|
527
|
+
const content = await loadSection(params.section, params.scope);
|
|
528
|
+
return [
|
|
529
|
+
`\u{1F9E9} **Progressive Context** \u2014 Section: ${params.section}`,
|
|
530
|
+
`\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`,
|
|
531
|
+
"",
|
|
532
|
+
content
|
|
533
|
+
].join("\n");
|
|
534
|
+
}
|
|
535
|
+
const result = await getProgressiveContext(params.scope);
|
|
536
|
+
const lines = [
|
|
537
|
+
"\u{1F9E9} **Progressive Context**",
|
|
538
|
+
`\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`,
|
|
539
|
+
"",
|
|
540
|
+
`\u{1F4CB} **Meta**: ${result.meta}`,
|
|
541
|
+
`\u{1F517} **Skill Boundary**: ${result.boundary.name} \u2014 ${result.boundary.description}`,
|
|
542
|
+
""
|
|
543
|
+
];
|
|
544
|
+
for (const section of result.sections) {
|
|
545
|
+
lines.push(section.content);
|
|
546
|
+
lines.push("");
|
|
547
|
+
}
|
|
548
|
+
lines.push("\u{1F4A1} Use kuma_context({ action: 'progressive', section: 'gotchas', scope: 'auth' }) to load specific context on demand.");
|
|
549
|
+
return lines.join("\n");
|
|
550
|
+
} catch (err) {
|
|
551
|
+
return `Error generating progressive context: ${err}`;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
458
554
|
function computeProjectHash(scope) {
|
|
459
555
|
try {
|
|
460
556
|
const root = getProjectRoot();
|
|
@@ -536,7 +632,45 @@ var MEMORY_ALIASES = {
|
|
|
536
632
|
// Changes synonyms
|
|
537
633
|
"changes": "changes",
|
|
538
634
|
"change-log": "changes",
|
|
539
|
-
"history": "changes"
|
|
635
|
+
"history": "changes",
|
|
636
|
+
// Layer 1: Domain Rules (Issue #17)
|
|
637
|
+
"domain_rules": "domain_rules",
|
|
638
|
+
"domain-rules": "domain_rules",
|
|
639
|
+
"domain": "domain_rules",
|
|
640
|
+
"business-rules": "domain_rules",
|
|
641
|
+
// Layer 2: Architecture Flow (Issue #17)
|
|
642
|
+
"arch_flow": "arch_flow",
|
|
643
|
+
"arch-flow": "arch_flow",
|
|
644
|
+
"architecture": "arch_flow",
|
|
645
|
+
"flow-map": "arch_flow",
|
|
646
|
+
// Layer 3: Gotchas (Issue #17 / #21)
|
|
647
|
+
"gotcha": "gotcha",
|
|
648
|
+
"gotchas": "gotcha",
|
|
649
|
+
"known-gotchas": "gotcha",
|
|
650
|
+
"legacy": "gotcha",
|
|
651
|
+
"quirk": "gotcha",
|
|
652
|
+
// Layers summary
|
|
653
|
+
"layers": "layers",
|
|
654
|
+
"3-layer": "layers",
|
|
655
|
+
"memory-layers": "layers",
|
|
656
|
+
// Federated synonyms (Issue #27)
|
|
657
|
+
"federated": "federated",
|
|
658
|
+
"federated-graph": "federated",
|
|
659
|
+
"kuma-uri": "federated",
|
|
660
|
+
"remote-graph": "federated",
|
|
661
|
+
// Test generation synonyms (Issue #28)
|
|
662
|
+
"gen_test": "gen_test",
|
|
663
|
+
"gen-test": "gen_test",
|
|
664
|
+
"generate-test": "gen_test",
|
|
665
|
+
"gentest": "gen_test",
|
|
666
|
+
// Trajectory synonyms
|
|
667
|
+
"trajectory": "trajectory",
|
|
668
|
+
"trajectories": "trajectory",
|
|
669
|
+
"traj": "trajectory",
|
|
670
|
+
// Skills synonyms
|
|
671
|
+
"skills": "skills",
|
|
672
|
+
"distilled-skills": "skills",
|
|
673
|
+
"skill-list": "skills"
|
|
540
674
|
};
|
|
541
675
|
async function handleMemory(params) {
|
|
542
676
|
const rawAction = params.action || "session";
|
|
@@ -566,6 +700,22 @@ async function handleMemory(params) {
|
|
|
566
700
|
return handleBenchmark(params);
|
|
567
701
|
case "decision_log":
|
|
568
702
|
return handleDecisionLog(params);
|
|
703
|
+
case "domain_rules":
|
|
704
|
+
return handleLayerAction("domain_rules", params);
|
|
705
|
+
case "arch_flow":
|
|
706
|
+
return handleLayerAction("arch_flow", params);
|
|
707
|
+
case "gotcha":
|
|
708
|
+
return handleGotchaAction(params);
|
|
709
|
+
case "layers":
|
|
710
|
+
return handleLayersSummary(params);
|
|
711
|
+
case "federated":
|
|
712
|
+
return handleFederated(params);
|
|
713
|
+
case "gen_test":
|
|
714
|
+
return handleGenTest(params);
|
|
715
|
+
case "trajectory":
|
|
716
|
+
return handleTrajectoryList(params);
|
|
717
|
+
case "skills":
|
|
718
|
+
return handleSkillsList(params);
|
|
569
719
|
default:
|
|
570
720
|
return `Unknown action "${action}".`;
|
|
571
721
|
}
|
|
@@ -576,7 +726,7 @@ async function handleDecision(params) {
|
|
|
576
726
|
case "template":
|
|
577
727
|
return formatDecisionTemplate();
|
|
578
728
|
case "suggest": {
|
|
579
|
-
const { shouldRecordDecision } = await import("./kumaMemory-
|
|
729
|
+
const { shouldRecordDecision } = await import("./kumaMemory-FMOWIODH.js");
|
|
580
730
|
const check = shouldRecordDecision();
|
|
581
731
|
return check.worth ? `\u{1F4A1} Decision suggested: "${check.title}"
|
|
582
732
|
Use kuma_memory({ action: 'decision', title: '...', context: '...', rationale: '...', outcome: '...' }) to record.` : "\u2705 No decision needed at this time.";
|
|
@@ -654,11 +804,11 @@ async function handleSearch(params) {
|
|
|
654
804
|
if (!query) return "\u26A0\uFE0F query or scope parameter required.";
|
|
655
805
|
const limit = params.limit || 20;
|
|
656
806
|
const memResults = sessionMemory.searchMemory(query, limit);
|
|
657
|
-
const { searchGraph: searchGraph2 } = await import("./kumaGraph-
|
|
807
|
+
const { searchGraph: searchGraph2 } = await import("./kumaGraph-GUQM75WL.js");
|
|
658
808
|
const graphResults = await searchGraph2(query, Math.min(limit, 10));
|
|
659
809
|
let hybridResults = "";
|
|
660
810
|
try {
|
|
661
|
-
const { hybridSearch, formatHybridResults } = await import("./kumaSearch-
|
|
811
|
+
const { hybridSearch, formatHybridResults } = await import("./kumaSearch-B5WVYHHD.js");
|
|
662
812
|
const semanticResults = await hybridSearch(query, 8);
|
|
663
813
|
if (semanticResults.length > 0) {
|
|
664
814
|
hybridResults = "\n" + formatHybridResults(query, semanticResults);
|
|
@@ -742,7 +892,7 @@ async function handleDecisionLog(params) {
|
|
|
742
892
|
}
|
|
743
893
|
async function handleMine(params) {
|
|
744
894
|
sessionMemory.recordToolCall("kuma_memory_mine", { scope: params.scope });
|
|
745
|
-
const { mineHistoricalDecisions } = await import("./kumaMiner-
|
|
895
|
+
const { mineHistoricalDecisions } = await import("./kumaMiner-3RXEOCBP.js");
|
|
746
896
|
return await mineHistoricalDecisions({
|
|
747
897
|
scope: params.scope,
|
|
748
898
|
since: typeof params.since === "string" ? params.since : void 0,
|
|
@@ -750,6 +900,65 @@ async function handleMine(params) {
|
|
|
750
900
|
limit: params.limit
|
|
751
901
|
});
|
|
752
902
|
}
|
|
903
|
+
async function handleLayerAction(layer, params) {
|
|
904
|
+
const { readLayer, writeLayer } = await import("./domainRules-ED6EOFVY.js");
|
|
905
|
+
if (params.content) {
|
|
906
|
+
return writeLayer(layer, params.content);
|
|
907
|
+
}
|
|
908
|
+
return readLayer(layer);
|
|
909
|
+
}
|
|
910
|
+
async function handleGotchaAction(params) {
|
|
911
|
+
if (params.content && params.scope) {
|
|
912
|
+
const { addGotcha } = await import("./kumaGotchas-5HODT5RI.js");
|
|
913
|
+
return await addGotcha({
|
|
914
|
+
filePath: params.scope,
|
|
915
|
+
description: params.content,
|
|
916
|
+
severity: params.status || "medium",
|
|
917
|
+
workaround: params.description
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
const { listGotchas, syncGotchasToDb } = await import("./kumaGotchas-5HODT5RI.js");
|
|
921
|
+
await syncGotchasToDb();
|
|
922
|
+
return await listGotchas({
|
|
923
|
+
filePath: params.scope,
|
|
924
|
+
severity: params.status
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
async function handleFederated(params) {
|
|
928
|
+
sessionMemory.recordToolCall("kuma_memory_federated", { scope: params.scope, uri: params.uri });
|
|
929
|
+
if (params.uri) {
|
|
930
|
+
const { resolveFederatedNode } = await import("./kumaGraph-GUQM75WL.js");
|
|
931
|
+
return await resolveFederatedNode(params.uri);
|
|
932
|
+
}
|
|
933
|
+
const { listFederatedReferences } = await import("./kumaGraph-GUQM75WL.js");
|
|
934
|
+
return await listFederatedReferences();
|
|
935
|
+
}
|
|
936
|
+
async function handleGenTest(params) {
|
|
937
|
+
sessionMemory.recordToolCall("kuma_memory_gen_test", { target: params.target });
|
|
938
|
+
if (params.target) {
|
|
939
|
+
const id = parseInt(params.target, 10);
|
|
940
|
+
if (!isNaN(id)) {
|
|
941
|
+
const { generateTestFromTrajectoryId } = await import("./kumaTrajectory-T6DXGOG4.js");
|
|
942
|
+
return await generateTestFromTrajectoryId(id);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
const { listGeneratedTests } = await import("./kumaTrajectory-T6DXGOG4.js");
|
|
946
|
+
return await listGeneratedTests();
|
|
947
|
+
}
|
|
948
|
+
async function handleTrajectoryList(params) {
|
|
949
|
+
sessionMemory.recordToolCall("kuma_memory_trajectory", {});
|
|
950
|
+
const { listTrajectories } = await import("./kumaTrajectory-T6DXGOG4.js");
|
|
951
|
+
return await listTrajectories(params.limit || 10);
|
|
952
|
+
}
|
|
953
|
+
async function handleSkillsList(_params) {
|
|
954
|
+
sessionMemory.recordToolCall("kuma_memory_skills", {});
|
|
955
|
+
const { listDistilledSkills } = await import("./kumaTrajectory-T6DXGOG4.js");
|
|
956
|
+
return await listDistilledSkills();
|
|
957
|
+
}
|
|
958
|
+
async function handleLayersSummary(_params) {
|
|
959
|
+
const { getLayersSummary } = await import("./domainRules-ED6EOFVY.js");
|
|
960
|
+
return getLayersSummary();
|
|
961
|
+
}
|
|
753
962
|
|
|
754
963
|
// src/engine/kumaLock.ts
|
|
755
964
|
import fs3 from "fs";
|
|
@@ -858,151 +1067,6 @@ function cleanStaleLocks() {
|
|
|
858
1067
|
return count > 0 ? `\u{1F9F9} Cleaned ${count} stale lock(s).` : "\u2705 No stale locks found.";
|
|
859
1068
|
}
|
|
860
1069
|
|
|
861
|
-
// src/engine/safetyAudit.ts
|
|
862
|
-
var SCHEMA_SQL = `
|
|
863
|
-
CREATE TABLE IF NOT EXISTS safety_audit (
|
|
864
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
865
|
-
timestamp INTEGER NOT NULL,
|
|
866
|
-
tool_name TEXT NOT NULL,
|
|
867
|
-
action TEXT NOT NULL,
|
|
868
|
-
file_path TEXT,
|
|
869
|
-
risk_level TEXT NOT NULL DEFAULT 'low',
|
|
870
|
-
policy_violations INTEGER DEFAULT 0,
|
|
871
|
-
allowed INTEGER NOT NULL DEFAULT 1,
|
|
872
|
-
duration_ms INTEGER DEFAULT 0,
|
|
873
|
-
metadata TEXT DEFAULT '{}'
|
|
874
|
-
);
|
|
875
|
-
CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON safety_audit(timestamp);
|
|
876
|
-
CREATE INDEX IF NOT EXISTS idx_audit_tool ON safety_audit(tool_name);
|
|
877
|
-
CREATE INDEX IF NOT EXISTS idx_audit_risk ON safety_audit(risk_level);
|
|
878
|
-
CREATE INDEX IF NOT EXISTS idx_audit_allowed ON safety_audit(allowed);
|
|
879
|
-
`;
|
|
880
|
-
var schemaEnsured = false;
|
|
881
|
-
async function ensureSchema() {
|
|
882
|
-
if (schemaEnsured) return;
|
|
883
|
-
try {
|
|
884
|
-
const db = await getDb();
|
|
885
|
-
db.exec(SCHEMA_SQL);
|
|
886
|
-
saveDb();
|
|
887
|
-
schemaEnsured = true;
|
|
888
|
-
} catch (err) {
|
|
889
|
-
console.error(`[SafetyAudit] Failed to ensure schema: ${err}`);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
async function recordAudit(entry) {
|
|
893
|
-
try {
|
|
894
|
-
await ensureSchema();
|
|
895
|
-
const db = await getDb();
|
|
896
|
-
db.run(`
|
|
897
|
-
INSERT INTO safety_audit (timestamp, tool_name, action, file_path, risk_level, policy_violations, allowed, duration_ms, metadata)
|
|
898
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
899
|
-
`, [
|
|
900
|
-
entry.timestamp,
|
|
901
|
-
entry.toolName,
|
|
902
|
-
entry.action,
|
|
903
|
-
entry.filePath || null,
|
|
904
|
-
entry.riskLevel,
|
|
905
|
-
entry.policyViolations,
|
|
906
|
-
entry.allowed ? 1 : 0,
|
|
907
|
-
entry.durationMs,
|
|
908
|
-
JSON.stringify(entry.metadata || {})
|
|
909
|
-
]);
|
|
910
|
-
saveDb();
|
|
911
|
-
} catch (err) {
|
|
912
|
-
console.error(`[SafetyAudit] Failed to record audit: ${err}`);
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
async function queryAudit(params) {
|
|
916
|
-
try {
|
|
917
|
-
await ensureSchema();
|
|
918
|
-
const db = await getDb();
|
|
919
|
-
const { toolName, riskLevel, allowed, limit = 20, since } = params;
|
|
920
|
-
let sql = "SELECT * FROM safety_audit WHERE 1=1";
|
|
921
|
-
const bindParams = [];
|
|
922
|
-
if (toolName) {
|
|
923
|
-
sql += " AND tool_name = ?";
|
|
924
|
-
bindParams.push(toolName);
|
|
925
|
-
}
|
|
926
|
-
if (riskLevel) {
|
|
927
|
-
sql += " AND risk_level = ?";
|
|
928
|
-
bindParams.push(riskLevel);
|
|
929
|
-
}
|
|
930
|
-
if (allowed !== void 0) {
|
|
931
|
-
sql += " AND allowed = ?";
|
|
932
|
-
bindParams.push(allowed ? 1 : 0);
|
|
933
|
-
}
|
|
934
|
-
if (since) {
|
|
935
|
-
sql += " AND timestamp >= ?";
|
|
936
|
-
bindParams.push(since);
|
|
937
|
-
}
|
|
938
|
-
sql += " ORDER BY timestamp DESC LIMIT ?";
|
|
939
|
-
bindParams.push(limit);
|
|
940
|
-
const stmt = db.prepare(sql);
|
|
941
|
-
stmt.bind(bindParams);
|
|
942
|
-
const results = [];
|
|
943
|
-
while (stmt.step()) {
|
|
944
|
-
results.push(stmt.getAsObject());
|
|
945
|
-
}
|
|
946
|
-
stmt.free();
|
|
947
|
-
if (results.length === 0) {
|
|
948
|
-
return "\u{1F4CB} **Safety Audit** \u2014 No records found for the given filters.";
|
|
949
|
-
}
|
|
950
|
-
const lines = [
|
|
951
|
-
`\u{1F4CB} **Safety Audit** \u2014 ${results.length} record(s)`,
|
|
952
|
-
`\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`,
|
|
953
|
-
""
|
|
954
|
-
];
|
|
955
|
-
for (const r of results) {
|
|
956
|
-
const riskIcon = r.risk_level === "critical" ? "\u{1F534}" : r.risk_level === "high" ? "\u{1F7E0}" : r.risk_level === "medium" ? "\u{1F7E1}" : "\u{1F7E2}";
|
|
957
|
-
const allowIcon = r.allowed ? "\u2705" : "\u26D4";
|
|
958
|
-
const time = new Date(r.timestamp * 1e3).toLocaleTimeString();
|
|
959
|
-
lines.push(`${allowIcon} ${riskIcon} **${r.tool_name}** \u2014 ${r.action}`);
|
|
960
|
-
if (r.file_path) lines.push(` \u{1F4CD} ${r.file_path}`);
|
|
961
|
-
lines.push(` \u{1F550} ${time} | ${r.duration_ms}ms | ${r.policy_violations} policy violation(s)`);
|
|
962
|
-
lines.push("");
|
|
963
|
-
}
|
|
964
|
-
return lines.join("\n");
|
|
965
|
-
} catch (err) {
|
|
966
|
-
return `Error querying audit: ${err}`;
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
async function auditStats() {
|
|
970
|
-
try {
|
|
971
|
-
await ensureSchema();
|
|
972
|
-
const db = await getDb();
|
|
973
|
-
const total = db.exec("SELECT COUNT(*) as c FROM safety_audit")[0]?.values[0][0] ?? 0;
|
|
974
|
-
const blocked = db.exec("SELECT COUNT(*) as c FROM safety_audit WHERE allowed = 0")[0]?.values[0][0] ?? 0;
|
|
975
|
-
const critical = db.exec("SELECT COUNT(*) as c FROM safety_audit WHERE risk_level IN ('high','critical')")[0]?.values[0][0] ?? 0;
|
|
976
|
-
let topBlocked = [];
|
|
977
|
-
try {
|
|
978
|
-
const stmt = db.prepare("SELECT tool_name, COUNT(*) as cnt FROM safety_audit WHERE allowed = 0 GROUP BY tool_name ORDER BY cnt DESC LIMIT 5");
|
|
979
|
-
while (stmt.step()) {
|
|
980
|
-
topBlocked.push(stmt.getAsObject());
|
|
981
|
-
}
|
|
982
|
-
stmt.free();
|
|
983
|
-
} catch {
|
|
984
|
-
}
|
|
985
|
-
const lines = [
|
|
986
|
-
`\u{1F4CA} **Safety Audit Stats**`,
|
|
987
|
-
`\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`,
|
|
988
|
-
"",
|
|
989
|
-
`\u{1F4DD} Total operations: ${total}`,
|
|
990
|
-
`\u26D4 Blocked: ${blocked} (${total > 0 ? (blocked / total * 100).toFixed(1) : 0}%)`,
|
|
991
|
-
`\u{1F534} High/Critical risk: ${critical}`,
|
|
992
|
-
""
|
|
993
|
-
];
|
|
994
|
-
if (topBlocked.length > 0) {
|
|
995
|
-
lines.push("**Most blocked tools:**");
|
|
996
|
-
for (const t of topBlocked) {
|
|
997
|
-
lines.push(` \u2022 ${t.tool_name}: ${t.cnt}x blocked`);
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
return lines.join("\n");
|
|
1001
|
-
} catch (err) {
|
|
1002
|
-
return `Error getting audit stats: ${err}`;
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
1070
|
// src/tools/kumaPolicy.ts
|
|
1007
1071
|
import fs4 from "fs";
|
|
1008
1072
|
import path4 from "path";
|
|
@@ -1836,6 +1900,19 @@ async function handleSafety(params) {
|
|
|
1836
1900
|
return handleGitignore(params);
|
|
1837
1901
|
case "clean":
|
|
1838
1902
|
return handleClean(params);
|
|
1903
|
+
case "policy":
|
|
1904
|
+
return handlePolicy(params);
|
|
1905
|
+
case "ast":
|
|
1906
|
+
case "validate":
|
|
1907
|
+
return handleAstValidation(params);
|
|
1908
|
+
case "checkpoint":
|
|
1909
|
+
return handleCheckpoint(params);
|
|
1910
|
+
case "rollback_label":
|
|
1911
|
+
return handleRollbackLabel(params);
|
|
1912
|
+
case "checkpoint_list":
|
|
1913
|
+
return handleCheckpointList(params);
|
|
1914
|
+
case "contract":
|
|
1915
|
+
return handleContract(params);
|
|
1839
1916
|
default:
|
|
1840
1917
|
return `Unknown action "${action}".`;
|
|
1841
1918
|
}
|
|
@@ -1879,7 +1956,7 @@ async function handleLock(params) {
|
|
|
1879
1956
|
}
|
|
1880
1957
|
async function handleHealth2(_params) {
|
|
1881
1958
|
try {
|
|
1882
|
-
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-
|
|
1959
|
+
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-WU27EOG4.js");
|
|
1883
1960
|
const score = await computeSafetyScore();
|
|
1884
1961
|
await saveHealthSnapshot(score.score, score.risk, JSON.stringify(score.checks), score.summary);
|
|
1885
1962
|
return formatSafetyScore(score);
|
|
@@ -1983,6 +2060,85 @@ async function handleClean(_params) {
|
|
|
1983
2060
|
return `${result}
|
|
1984
2061
|
\u{1F4A1} Drift warnings have been reset. Any temporary debug artifacts are now cleared.`;
|
|
1985
2062
|
}
|
|
2063
|
+
async function handlePolicy(params) {
|
|
2064
|
+
sessionMemory.recordToolCall("kuma_safety_policy", {});
|
|
2065
|
+
if (params.command) {
|
|
2066
|
+
const { evaluateCommand, evaluateFilePath } = await import("./kumaPolicyEngine-ORBWL5PT.js");
|
|
2067
|
+
const commandVerdict = evaluateCommand(params.command);
|
|
2068
|
+
const lines = [];
|
|
2069
|
+
lines.push(`\u{1F4DC} **Policy Check**: ${commandVerdict.allowed ? "\u2705 Allowed" : "\u26D4 Blocked"}`);
|
|
2070
|
+
lines.push(`\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`);
|
|
2071
|
+
lines.push("");
|
|
2072
|
+
lines.push(`\u{1F4BB} Command: \`${params.command}\``);
|
|
2073
|
+
lines.push(`\u{1F4CB} Result: ${commandVerdict.message}`);
|
|
2074
|
+
if (commandVerdict.blockedBy) {
|
|
2075
|
+
lines.push("");
|
|
2076
|
+
lines.push(`\u{1F534} **Blocked by rule**: ${commandVerdict.blockedBy.description}`);
|
|
2077
|
+
if (commandVerdict.requiresOverride) {
|
|
2078
|
+
lines.push(`\u{1F511} Use kuma_safety({ action: 'override', toolName: 'policy', reason: '...' }) to bypass.`);
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
for (const w of commandVerdict.warnings) {
|
|
2082
|
+
lines.push(`\u{1F7E1} **Warning**: ${w.description}`);
|
|
2083
|
+
}
|
|
2084
|
+
if (params.filePath) {
|
|
2085
|
+
const fileVerdict = evaluateFilePath(params.filePath);
|
|
2086
|
+
if (!fileVerdict.allowed) {
|
|
2087
|
+
lines.push("");
|
|
2088
|
+
lines.push(fileVerdict.message);
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
return lines.join("\n");
|
|
2092
|
+
}
|
|
2093
|
+
const { formatPolicyStatus } = await import("./kumaPolicyEngine-ORBWL5PT.js");
|
|
2094
|
+
return formatPolicyStatus();
|
|
2095
|
+
}
|
|
2096
|
+
async function handleAstValidation(params) {
|
|
2097
|
+
sessionMemory.recordToolCall("kuma_safety_ast", { scope: params.scope });
|
|
2098
|
+
const { validateCodeContent, validateFile, formatValidationFindings } = await import("./kumaAstValidator-CNM7FHYA.js");
|
|
2099
|
+
if (params.command) {
|
|
2100
|
+
const findings = validateCodeContent(params.command, params.scope);
|
|
2101
|
+
return formatValidationFindings(findings, params.scope);
|
|
2102
|
+
}
|
|
2103
|
+
if (params.scope) {
|
|
2104
|
+
const findings = validateFile(params.scope);
|
|
2105
|
+
return formatValidationFindings(findings, params.scope);
|
|
2106
|
+
}
|
|
2107
|
+
return "\u26A0\uFE0F Provide a scope (file path) or command (code content) to validate.";
|
|
2108
|
+
}
|
|
2109
|
+
async function handleCheckpoint(params) {
|
|
2110
|
+
sessionMemory.recordToolCall("kuma_safety_checkpoint", { label: params.label });
|
|
2111
|
+
if (!params.label) return "\u26A0\uFE0F label parameter required. Example: kuma_safety({ action: 'checkpoint', label: 'pre-feature-x' })";
|
|
2112
|
+
const { createCheckpoint } = await import("./kumaCheckpoint-XIQWRMGV.js");
|
|
2113
|
+
return await createCheckpoint(params.label, params.description);
|
|
2114
|
+
}
|
|
2115
|
+
async function handleRollbackLabel(params) {
|
|
2116
|
+
sessionMemory.recordToolCall("kuma_safety_rollback_label", { label: params.label });
|
|
2117
|
+
if (!params.label) return "\u26A0\uFE0F label parameter required. Example: kuma_safety({ action: 'rollback_label', label: 'pre-feature-x' })";
|
|
2118
|
+
const { rollbackToCheckpoint } = await import("./kumaCheckpoint-XIQWRMGV.js");
|
|
2119
|
+
return await rollbackToCheckpoint(params.label);
|
|
2120
|
+
}
|
|
2121
|
+
async function handleCheckpointList(_params) {
|
|
2122
|
+
sessionMemory.recordToolCall("kuma_safety_checkpoint_list", {});
|
|
2123
|
+
const { listCheckpoints } = await import("./kumaCheckpoint-XIQWRMGV.js");
|
|
2124
|
+
return listCheckpoints();
|
|
2125
|
+
}
|
|
2126
|
+
async function handleContract(params) {
|
|
2127
|
+
sessionMemory.recordToolCall("kuma_safety_contract", {
|
|
2128
|
+
toolName: params.toolName || "edit",
|
|
2129
|
+
filePath: params.filePath,
|
|
2130
|
+
phase: params.phase || "pre"
|
|
2131
|
+
});
|
|
2132
|
+
const { runContractChecks, listContracts } = await import("./kumaContractEngine-KX27T4N7.js");
|
|
2133
|
+
if (!params.filePath && !params.toolName) {
|
|
2134
|
+
return listContracts();
|
|
2135
|
+
}
|
|
2136
|
+
return await runContractChecks(
|
|
2137
|
+
params.toolName || "edit",
|
|
2138
|
+
params.filePath,
|
|
2139
|
+
params.phase || "pre"
|
|
2140
|
+
);
|
|
2141
|
+
}
|
|
1986
2142
|
var _lastVerifyCall = 0;
|
|
1987
2143
|
var VERIFY_COOLDOWN_MS = 3e4;
|
|
1988
2144
|
async function handleVerify(params) {
|
|
@@ -1993,7 +2149,7 @@ async function handleVerify(params) {
|
|
|
1993
2149
|
}
|
|
1994
2150
|
_lastVerifyCall = now;
|
|
1995
2151
|
sessionMemory.recordToolCall("kuma_safety_verify", { scope: params.scope || params.filePath });
|
|
1996
|
-
const { runAutoVerification } = await import("./kumaVerifier-
|
|
2152
|
+
const { runAutoVerification } = await import("./kumaVerifier-KAYJHR5K.js");
|
|
1997
2153
|
return await runAutoVerification({
|
|
1998
2154
|
scope: params.scope || params.filePath,
|
|
1999
2155
|
force: params.force,
|
|
@@ -2007,12 +2163,13 @@ function registerAllTools(server) {
|
|
|
2007
2163
|
"kuma_context",
|
|
2008
2164
|
"**Call FIRST every session.** Understand your project before making changes. Actions: init (load project brief), research (5-step pipeline: cache\u2192staleness\u2192graph\u2192impact\u2192decision), impact (analyze change effects), navigate (trace code flow), changes (view change log), health (project health score 0-100). RESEARCH IS REQUIRED before editing unfamiliar code.",
|
|
2009
2165
|
{
|
|
2010
|
-
action: z.enum(["init", "research", "impact", "navigate", "changes", "health", "rollback", "researches", "sync", "visualize"]).describe("Action: init=project brief, research=5-step research pipeline (REQUIRED before edits), impact=analyze change effects, navigate=trace code flow, changes=view change log, rollback=undo a change by ID, researches=list all cached research, sync=unified batch state, visualize=Mermaid knowledge graph diagram, health=project health score"),
|
|
2011
|
-
scope: z.string().optional().describe("Research scope for research action
|
|
2166
|
+
action: z.enum(["init", "research", "impact", "navigate", "changes", "health", "rollback", "researches", "sync", "visualize", "digest", "drift", "progressive"]).describe("Action: init=project brief, research=5-step research pipeline (REQUIRED before edits), impact=analyze change effects, navigate=trace code flow, changes=view change log, rollback=undo a change by ID, researches=list all cached research, sync=unified batch state, visualize=Mermaid knowledge graph diagram, digest=ultra-compact <500 token project briefing (Issue #18), drift=detect memory staleness & code drift (Issue #20), progressive=progressive context loading (Issue #25), health=project health score"),
|
|
2167
|
+
scope: z.string().optional().describe("Research scope for research/progressive action"),
|
|
2012
2168
|
target: z.string().optional().describe("Target symbol/file for impact/navigate/changes"),
|
|
2013
2169
|
goal: z.string().optional().describe("Current goal (for init/health)"),
|
|
2014
2170
|
since: z.number().optional().describe("Unix timestamp filter for changes"),
|
|
2015
|
-
compact: z.boolean().optional().default(false).describe("Compact output mode")
|
|
2171
|
+
compact: z.boolean().optional().default(false).describe("Compact output mode"),
|
|
2172
|
+
section: z.string().optional().describe("Context section for progressive action (domain_rules, architecture, gotchas, decisions, graph, changes, health)")
|
|
2016
2173
|
},
|
|
2017
2174
|
async (params) => {
|
|
2018
2175
|
try {
|
|
@@ -2022,7 +2179,8 @@ function registerAllTools(server) {
|
|
|
2022
2179
|
target: params.target,
|
|
2023
2180
|
goal: params.goal,
|
|
2024
2181
|
since: params.since,
|
|
2025
|
-
compact: params.compact
|
|
2182
|
+
compact: params.compact,
|
|
2183
|
+
section: params.section
|
|
2026
2184
|
});
|
|
2027
2185
|
return { content: [{ type: "text", text }] };
|
|
2028
2186
|
} catch (err) {
|
|
@@ -2034,8 +2192,8 @@ function registerAllTools(server) {
|
|
|
2034
2192
|
"kuma_memory",
|
|
2035
2193
|
"Record and retrieve project knowledge. Actions: decision (ADR-style record/template/suggest), mine (mine historical decisions from git log & code comments), research_save (save research), session (session summary), heal (graph repair), search (search all), changes (change log), todo (persistent todo CRUD), context (inject context notes), benchmark (capture/diff metrics), decision_log (living document with status tracking).",
|
|
2036
2194
|
{
|
|
2037
|
-
action: z.enum(["decision", "mine", "research_save", "session", "heal", "search", "changes", "todo", "context", "benchmark", "decision_log"]).describe("Memory action: decision=ADR, mine=mine git log & comments, research_save=save, session=summary, heal=repair, search=search, changes=log, todo=manage todos, context=inject notes, benchmark=capture/diff, decision_log=manage decisions"),
|
|
2038
|
-
scope: z.string().optional().describe("Scope for research_save/search/todo/context/mine"),
|
|
2195
|
+
action: z.enum(["decision", "mine", "research_save", "session", "heal", "search", "changes", "todo", "context", "benchmark", "decision_log", "domain_rules", "arch_flow", "gotcha", "layers", "federated", "gen_test", "trajectory", "skills"]).describe("Memory action: decision=ADR, mine=mine git log & comments, research_save=save, session=summary, heal=repair, search=search, changes=log, todo=manage todos, context=inject notes, benchmark=capture/diff, decision_log=manage decisions, domain_rules=Layer 1 business rules (Issue #17), arch_flow=Layer 2 architecture flow (Issue #17), gotcha=Layer 3 known gotchas (Issue #17/#21), layers=all 3 layers summary, federated=resolve federated kuma:// URI (Issue #27), gen_test=generate test from trajectory (Issue #28), trajectory=list trajectories, skills=list distilled skills"),
|
|
2196
|
+
scope: z.string().optional().describe("Scope for research_save/search/todo/context/mine/federated"),
|
|
2039
2197
|
query: z.string().optional().describe("Search query for search action"),
|
|
2040
2198
|
content: z.string().optional().describe("Content/notes for research_save / context"),
|
|
2041
2199
|
record: z.string().optional().describe("JSON record string for research_save"),
|
|
@@ -2051,7 +2209,7 @@ function registerAllTools(server) {
|
|
|
2051
2209
|
healAction: z.enum(["check", "heal"]).optional().describe("Heal sub-action"),
|
|
2052
2210
|
topic: z.string().optional().describe("Memory topic for session"),
|
|
2053
2211
|
limit: z.number().min(1).max(100).optional().describe("Result limit"),
|
|
2054
|
-
target: z.string().optional().describe("File path for changes / decision_log ID"),
|
|
2212
|
+
target: z.string().optional().describe("File path for changes / decision_log ID / trajectory ID"),
|
|
2055
2213
|
since: z.number().optional().describe("Timestamp filter for changes"),
|
|
2056
2214
|
compact: z.boolean().optional().default(false).describe("Compact output mode"),
|
|
2057
2215
|
// Todo params
|
|
@@ -2065,7 +2223,9 @@ function registerAllTools(server) {
|
|
|
2065
2223
|
// Benchmark params
|
|
2066
2224
|
label: z.string().optional().describe("Benchmark label"),
|
|
2067
2225
|
metrics: z.string().optional().describe("Benchmark metrics JSON"),
|
|
2068
|
-
labelB: z.string().optional().describe("Second benchmark label for diff")
|
|
2226
|
+
labelB: z.string().optional().describe("Second benchmark label for diff"),
|
|
2227
|
+
// Federated params (#27)
|
|
2228
|
+
uri: z.string().optional().describe("Federated URI (kuma://project/node-id)")
|
|
2069
2229
|
},
|
|
2070
2230
|
async (params) => {
|
|
2071
2231
|
try {
|
|
@@ -2086,7 +2246,8 @@ function registerAllTools(server) {
|
|
|
2086
2246
|
topic: params.topic,
|
|
2087
2247
|
limit: params.limit,
|
|
2088
2248
|
target: params.target,
|
|
2089
|
-
since: params.since
|
|
2249
|
+
since: params.since,
|
|
2250
|
+
uri: params.uri
|
|
2090
2251
|
});
|
|
2091
2252
|
return { content: [{ type: "text", text }] };
|
|
2092
2253
|
} catch (err) {
|
|
@@ -2098,14 +2259,14 @@ function registerAllTools(server) {
|
|
|
2098
2259
|
"kuma_safety",
|
|
2099
2260
|
"Safety checks, policy enforcement, security scanning, integrated auto-verification, and project hygiene. Actions: guard (anti-pattern detection), verify (auto-run scoped tests), check (pre-exec safety), audit (query trail), lock (multi-agent), health (score), security (scan for leaks), gc (garbage collection), doctor (health check), portability (path check), gitignore (auto-config), override (bypass).",
|
|
2100
2261
|
{
|
|
2101
|
-
action: z.enum(["guard", "verify", "check", "audit", "lock", "health", "override", "security", "gc", "doctor", "portability", "gitignore", "clean"]).describe("Safety action: guard=anti-patterns, verify=auto-run scoped tests, check=pre-exec safety, audit=query trail, lock=multi-agent, health=score, security=scan leaks, gc=garbage collect, doctor=health check, portability=paths, gitignore=config, clean=purge scratch dir & drift, override=bypass"),
|
|
2262
|
+
action: z.enum(["guard", "verify", "check", "audit", "lock", "health", "override", "security", "gc", "doctor", "portability", "gitignore", "clean", "policy", "ast", "validate", "checkpoint", "rollback_label", "checkpoint_list", "contract"]).describe("Safety action: guard=anti-patterns, verify=auto-run scoped tests, check=pre-exec safety, audit=query trail, lock=multi-agent, health=score, security=scan leaks, gc=garbage collect, doctor=health check, portability=paths, gitignore=config, clean=purge scratch dir & drift, policy=Policy-as-Code engine (Issue #24), ast/validate=AST-based code validation (Issue #22), checkpoint=create atomic snapshot (Issue #29), rollback_label=restore from checkpoint (Issue #29), checkpoint_list=list checkpoints, contract=run contract checks (Issue #26), override=bypass"),
|
|
2102
2263
|
// Verify params
|
|
2103
2264
|
scope: z.string().optional().describe("Scope for verify or context (e.g. 'auth', file path)"),
|
|
2104
2265
|
// Guard params
|
|
2105
2266
|
guardGoal: z.string().optional().describe("Goal for guard check"),
|
|
2106
2267
|
guardCheck: z.enum(["all", "anti-pattern", "loop", "drift", "context"]).optional().describe("Guard check type"),
|
|
2107
2268
|
// Check params
|
|
2108
|
-
filePath: z.string().optional().describe("File path for check/lock/security scan"),
|
|
2269
|
+
filePath: z.string().optional().describe("File path for check/lock/security scan/contract"),
|
|
2109
2270
|
command: z.string().optional().describe("Command for check"),
|
|
2110
2271
|
// Audit params
|
|
2111
2272
|
toolName: z.string().optional().describe("Filter audit by tool name"),
|
|
@@ -2119,7 +2280,12 @@ function registerAllTools(server) {
|
|
|
2119
2280
|
agentId: z.string().optional().describe("Agent ID for lock"),
|
|
2120
2281
|
// Override params
|
|
2121
2282
|
reason: z.string().optional().describe("Reason for safety override"),
|
|
2122
|
-
compact: z.boolean().optional().default(false).describe("Compact output mode")
|
|
2283
|
+
compact: z.boolean().optional().default(false).describe("Compact output mode"),
|
|
2284
|
+
// Checkpoint params (#29)
|
|
2285
|
+
label: z.string().optional().describe("Checkpoint label for checkpoint/rollback_label actions"),
|
|
2286
|
+
description: z.string().optional().describe("Description for checkpoint"),
|
|
2287
|
+
// Contract params (#26)
|
|
2288
|
+
phase: z.enum(["pre", "post"]).optional().describe("Contract check phase")
|
|
2123
2289
|
},
|
|
2124
2290
|
async (params) => {
|
|
2125
2291
|
try {
|
|
@@ -2138,7 +2304,10 @@ function registerAllTools(server) {
|
|
|
2138
2304
|
lockAction: params.lockAction,
|
|
2139
2305
|
lockFilePath: params.lockFilePath,
|
|
2140
2306
|
agentId: params.agentId,
|
|
2141
|
-
reason: params.reason
|
|
2307
|
+
reason: params.reason,
|
|
2308
|
+
label: params.label,
|
|
2309
|
+
description: params.description,
|
|
2310
|
+
phase: params.phase
|
|
2142
2311
|
});
|
|
2143
2312
|
return { content: [{ type: "text", text }] };
|
|
2144
2313
|
} catch (err) {
|
|
@@ -2165,6 +2334,7 @@ Usage:
|
|
|
2165
2334
|
npx @plumpslabs/kuma init --merge Append to existing files (default)
|
|
2166
2335
|
npx @plumpslabs/kuma init --skip-existing Skip generation if file exists
|
|
2167
2336
|
npx @plumpslabs/kuma init --claude --cursor Generate specific files
|
|
2337
|
+
npx @plumpslabs/kuma studio Start Kuma Studio web dashboard (knowledge graph visualizer)
|
|
2168
2338
|
npx @plumpslabs/kuma init --help Show this help
|
|
2169
2339
|
|
|
2170
2340
|
Available config files:
|
|
@@ -2192,7 +2362,7 @@ async function main() {
|
|
|
2192
2362
|
console.error("");
|
|
2193
2363
|
let killedCount = 0;
|
|
2194
2364
|
try {
|
|
2195
|
-
const { getRunningVerificationPid } = await import("./kumaVerifier-
|
|
2365
|
+
const { getRunningVerificationPid } = await import("./kumaVerifier-KAYJHR5K.js");
|
|
2196
2366
|
const pid = getRunningVerificationPid();
|
|
2197
2367
|
if (pid) {
|
|
2198
2368
|
try {
|
|
@@ -2284,6 +2454,31 @@ async function main() {
|
|
|
2284
2454
|
console.error("");
|
|
2285
2455
|
process.exit(0);
|
|
2286
2456
|
}
|
|
2457
|
+
if (args[0] === "studio") {
|
|
2458
|
+
const { fileURLToPath } = await import("url");
|
|
2459
|
+
const { dirname, join } = await import("path");
|
|
2460
|
+
const { spawn } = await import("child_process");
|
|
2461
|
+
const { existsSync } = await import("fs");
|
|
2462
|
+
const distDir = dirname(fileURLToPath(import.meta.url));
|
|
2463
|
+
const studioPath = join(distDir, "..", "packages", "ide", "studio", "dist", "index.js");
|
|
2464
|
+
if (!existsSync(studioPath)) {
|
|
2465
|
+
console.error(`[${SERVER_NAME}] Kuma Studio not found at ${studioPath}`);
|
|
2466
|
+
console.error(`[${SERVER_NAME}] Make sure @plumpslabs/kuma is properly installed.`);
|
|
2467
|
+
console.error(`[${SERVER_NAME}] Or run manually: cd packages/ide/studio && pnpm start`);
|
|
2468
|
+
process.exit(1);
|
|
2469
|
+
}
|
|
2470
|
+
const studioArgs = args.slice(1);
|
|
2471
|
+
const child = spawn("node", [studioPath, ...studioArgs], {
|
|
2472
|
+
stdio: "inherit",
|
|
2473
|
+
cwd: process.cwd()
|
|
2474
|
+
});
|
|
2475
|
+
child.on("exit", (code) => process.exit(code ?? 1));
|
|
2476
|
+
child.on("error", (err) => {
|
|
2477
|
+
console.error(`[${SERVER_NAME}] Failed to start Kuma Studio: ${err.message}`);
|
|
2478
|
+
process.exit(1);
|
|
2479
|
+
});
|
|
2480
|
+
return;
|
|
2481
|
+
}
|
|
2287
2482
|
if (args[0] === "--hook") {
|
|
2288
2483
|
process.exit(0);
|
|
2289
2484
|
}
|
|
@@ -2434,7 +2629,7 @@ async function main() {
|
|
|
2434
2629
|
console.error(`[${SERVER_NAME}] \u2705 Restored session (${sessionInfo.toolCallCount} previous tool calls)`);
|
|
2435
2630
|
}
|
|
2436
2631
|
try {
|
|
2437
|
-
const { buildFromSessionMemory } = await import("./kumaGraph-
|
|
2632
|
+
const { buildFromSessionMemory } = await import("./kumaGraph-GUQM75WL.js");
|
|
2438
2633
|
const edgeCount = await buildFromSessionMemory();
|
|
2439
2634
|
if (edgeCount > 0) {
|
|
2440
2635
|
console.error(`[${SERVER_NAME}] \u2705 Graph auto-populated with ${edgeCount} entries from session memory`);
|
|
@@ -2454,13 +2649,13 @@ async function main() {
|
|
|
2454
2649
|
console.error(`[${SERVER_NAME}] \u26A0\uFE0F Scratch directory setup: ${err}`);
|
|
2455
2650
|
}
|
|
2456
2651
|
try {
|
|
2457
|
-
const { getDb: getDb2, saveDb
|
|
2652
|
+
const { getDb: getDb2, saveDb } = await import("./kumaDb-IC7UX7PU.js");
|
|
2458
2653
|
const db = await getDb2();
|
|
2459
2654
|
db.run(
|
|
2460
2655
|
`INSERT INTO sessions (started_at, goal, tool_calls) VALUES (?, ?, ?)`,
|
|
2461
2656
|
[Math.floor(Date.now() / 1e3), sessionMemory.getSummary().currentGoal || "Session start", sessionInfo.toolCallCount]
|
|
2462
2657
|
);
|
|
2463
|
-
|
|
2658
|
+
saveDb(db);
|
|
2464
2659
|
} catch (err) {
|
|
2465
2660
|
console.error(`[${SERVER_NAME}] \u26A0\uFE0F Session DB record: ${err}`);
|
|
2466
2661
|
}
|
|
@@ -2494,7 +2689,7 @@ fi
|
|
|
2494
2689
|
console.error(`[${SERVER_NAME}] \u26A0\uFE0F Auto-capture hook setup: ${err}`);
|
|
2495
2690
|
}
|
|
2496
2691
|
try {
|
|
2497
|
-
const { buildSearchVectors } = await import("./kumaSearch-
|
|
2692
|
+
const { buildSearchVectors } = await import("./kumaSearch-B5WVYHHD.js");
|
|
2498
2693
|
const vectors = await buildSearchVectors();
|
|
2499
2694
|
if (vectors.length > 0) {
|
|
2500
2695
|
console.error(`[${SERVER_NAME}] \u2705 Search vector cache pre-warmed (${vectors.length} documents)`);
|