@plumpslabs/kuma 2.3.5 → 2.3.6
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/{chunk-PH4JKL6T.js → chunk-BI7KD3SG.js} +15 -7
- package/dist/{chunk-ZIFLGJ5R.js → chunk-FOQQ2CSL.js} +1 -1
- package/dist/{chunk-2NBESJTH.js → chunk-GDNAWLHF.js} +20 -9
- package/dist/{chunk-LLAPHR5W.js → chunk-K64NSHBR.js} +8 -7
- package/dist/{chunk-6QX4LBHV.js → chunk-X5TPBDKO.js} +2 -2
- package/dist/index.js +76 -19
- package/dist/{kumaDb-FQ3YKJ6K.js → kumaDb-DJUDLYBJ.js} +1 -1
- package/dist/{kumaGraph-ABVEVF4M.js → kumaGraph-35TAIBWD.js} +2 -2
- package/dist/{kumaMemory-DDZQXMFZ.js → kumaMemory-5SR3TGRL.js} +2 -2
- package/dist/{kumaMiner-GP6BITKV.js → kumaMiner-BIDSZE3Q.js} +40 -6
- package/dist/{kumaVerifier-7TFWLEPG.js → kumaVerifier-B4D7NOFT.js} +2 -2
- package/dist/{safetyScore-VYT6OMVG.js → safetyScore-PJGRRBWP.js} +14 -6
- package/dist/{sessionMemory-PGYVS3BK.js → sessionMemory-HBBXUSIP.js} +1 -1
- package/package.json +1 -1
|
@@ -320,7 +320,7 @@ No unresolved issues.`;
|
|
|
320
320
|
*/
|
|
321
321
|
async autoTrackToDb(toolName, params, timestamp) {
|
|
322
322
|
try {
|
|
323
|
-
const { getDb, saveDb } = await import("./kumaDb-
|
|
323
|
+
const { getDb, saveDb } = await import("./kumaDb-DJUDLYBJ.js");
|
|
324
324
|
const db = await getDb();
|
|
325
325
|
db.run(
|
|
326
326
|
`INSERT INTO tool_calls (tool_name, params, success, duration_ms, created_at) VALUES (?, ?, 1, 0, ?)`,
|
|
@@ -466,14 +466,14 @@ No unresolved issues.`;
|
|
|
466
466
|
const memoriesDir = this.memoriesDir();
|
|
467
467
|
if (fs.existsSync(memoriesDir)) {
|
|
468
468
|
try {
|
|
469
|
-
const files = fs.readdirSync(memoriesDir);
|
|
469
|
+
const files = fs.readdirSync(memoriesDir).filter((f) => f.endsWith(".md")).slice(0, 3);
|
|
470
470
|
for (const file of files) {
|
|
471
|
-
if (!file.endsWith(".md")) continue;
|
|
472
471
|
const filePath = path.join(memoriesDir, file);
|
|
473
472
|
try {
|
|
474
473
|
const content = fs.readFileSync(filePath, "utf-8");
|
|
475
474
|
const lines = content.split("\n");
|
|
476
|
-
|
|
475
|
+
const maxLinesPerFile = 500;
|
|
476
|
+
for (let i = 0; i < Math.min(lines.length, maxLinesPerFile); i++) {
|
|
477
477
|
if (lines[i].toLowerCase().includes(q)) {
|
|
478
478
|
const topicName = file.replace(/\.md$/, "");
|
|
479
479
|
results.push({
|
|
@@ -571,10 +571,18 @@ No unresolved issues.`;
|
|
|
571
571
|
if (recentCalls.length < 6) return { isLooping: false };
|
|
572
572
|
const toolCounts = /* @__PURE__ */ new Map();
|
|
573
573
|
for (const call of recentCalls) {
|
|
574
|
-
|
|
574
|
+
const existing = toolCounts.get(call.toolName);
|
|
575
|
+
const action = call.params.action || "";
|
|
576
|
+
if (existing) {
|
|
577
|
+
existing.count++;
|
|
578
|
+
existing.actions.add(action);
|
|
579
|
+
} else {
|
|
580
|
+
toolCounts.set(call.toolName, { count: 1, actions: /* @__PURE__ */ new Set([action]) });
|
|
581
|
+
}
|
|
575
582
|
}
|
|
576
|
-
for (const [toolName, count] of toolCounts) {
|
|
583
|
+
for (const [toolName, { count, actions }] of toolCounts) {
|
|
577
584
|
if (count >= 4) {
|
|
585
|
+
if (actions.size >= 3) continue;
|
|
578
586
|
return {
|
|
579
587
|
isLooping: true,
|
|
580
588
|
toolName,
|
|
@@ -597,7 +605,7 @@ No unresolved issues.`;
|
|
|
597
605
|
this.addModifiedFile(filePath);
|
|
598
606
|
}
|
|
599
607
|
try {
|
|
600
|
-
const { recordChange } = await import("./kumaDb-
|
|
608
|
+
const { recordChange } = await import("./kumaDb-DJUDLYBJ.js");
|
|
601
609
|
const gitHash = this.getGitHead();
|
|
602
610
|
await recordChange({ filePath, changeType, symbol, gitCommitHash: gitHash || void 0 });
|
|
603
611
|
} catch {
|
|
@@ -36,18 +36,29 @@ async function initDb() {
|
|
|
36
36
|
dbInstance = db;
|
|
37
37
|
return db;
|
|
38
38
|
}
|
|
39
|
+
var _saveTimeout = null;
|
|
40
|
+
var _pendingDb = null;
|
|
41
|
+
var SAVE_DEBOUNCE_MS = 100;
|
|
39
42
|
function saveDb(db) {
|
|
40
43
|
const d = db ?? dbInstance;
|
|
41
44
|
if (!d) return;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
_pendingDb = d;
|
|
46
|
+
if (_saveTimeout) return;
|
|
47
|
+
_saveTimeout = setTimeout(() => {
|
|
48
|
+
_saveTimeout = null;
|
|
49
|
+
const targetDb = _pendingDb;
|
|
50
|
+
_pendingDb = null;
|
|
51
|
+
if (!targetDb) return;
|
|
52
|
+
try {
|
|
53
|
+
const kumaDir = getKumaDir();
|
|
54
|
+
const dbPath = path.join(kumaDir, DB_FILENAME);
|
|
55
|
+
const data = targetDb.export();
|
|
56
|
+
const buffer = Buffer.from(data);
|
|
57
|
+
fs.writeFileSync(dbPath, buffer);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.error(`[KumaDB] Failed to save database: ${err}`);
|
|
60
|
+
}
|
|
61
|
+
}, SAVE_DEBOUNCE_MS);
|
|
51
62
|
}
|
|
52
63
|
function createSchema(db) {
|
|
53
64
|
db.run(`CREATE TABLE IF NOT EXISTS nodes (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getDb,
|
|
3
3
|
saveDb
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GDNAWLHF.js";
|
|
5
5
|
import {
|
|
6
6
|
getProjectRoot
|
|
7
7
|
} from "./chunk-E2KFPEBT.js";
|
|
@@ -458,7 +458,7 @@ The two nodes may not be connected in the knowledge graph yet. Use more tools to
|
|
|
458
458
|
}
|
|
459
459
|
async function buildFromSessionMemory() {
|
|
460
460
|
try {
|
|
461
|
-
const { sessionMemory } = await import("./sessionMemory-
|
|
461
|
+
const { sessionMemory } = await import("./sessionMemory-HBBXUSIP.js");
|
|
462
462
|
const toolCalls = sessionMemory.getToolCallHistory(50);
|
|
463
463
|
let edgeCount = 0;
|
|
464
464
|
for (const call of toolCalls) {
|
|
@@ -586,8 +586,8 @@ async function codebaseSearchFallback(query, limit = 20) {
|
|
|
586
586
|
return lines.join("\n");
|
|
587
587
|
} catch {
|
|
588
588
|
try {
|
|
589
|
-
let walk2 = function(dir) {
|
|
590
|
-
if (results.length >= limit) return;
|
|
589
|
+
let walk2 = function(dir, depth = 0) {
|
|
590
|
+
if (results.length >= limit || depth > MAX_WALK_DEPTH) return;
|
|
591
591
|
let entries = [];
|
|
592
592
|
try {
|
|
593
593
|
entries = fs2.readdirSync(dir);
|
|
@@ -600,7 +600,7 @@ async function codebaseSearchFallback(query, limit = 20) {
|
|
|
600
600
|
try {
|
|
601
601
|
const stat = fs2.statSync(full);
|
|
602
602
|
if (stat.isDirectory()) {
|
|
603
|
-
walk2(full);
|
|
603
|
+
walk2(full, depth + 1);
|
|
604
604
|
} else if (entry.toLowerCase().includes(query.toLowerCase())) {
|
|
605
605
|
results.push(path2.relative(root, full));
|
|
606
606
|
}
|
|
@@ -613,7 +613,8 @@ async function codebaseSearchFallback(query, limit = 20) {
|
|
|
613
613
|
const path2 = await import("path");
|
|
614
614
|
const root = process.cwd();
|
|
615
615
|
const results = [];
|
|
616
|
-
|
|
616
|
+
const MAX_WALK_DEPTH = 8;
|
|
617
|
+
walk2(root, 0);
|
|
617
618
|
if (results.length === 0) {
|
|
618
619
|
return `\u{1F50D} **Codebase Search** \u2014 No results for "${query}". Try a different search term.`;
|
|
619
620
|
}
|
|
@@ -744,7 +745,7 @@ async function codebaseImpactFallback(target) {
|
|
|
744
745
|
const root = process.cwd();
|
|
745
746
|
const grepResult = execSync2(
|
|
746
747
|
`grep -rn --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.json" -l "${target.replace(/"/g, '\\"')}" . 2>/dev/null | grep -v node_modules | grep -v .git | grep -v dist | grep -v .kuma | head -50`,
|
|
747
|
-
{ cwd: root, encoding: "utf-8", timeout: 5e3, maxBuffer:
|
|
748
|
+
{ cwd: root, encoding: "utf-8", timeout: 5e3, maxBuffer: 256 * 1024 }
|
|
748
749
|
).trim();
|
|
749
750
|
const files = grepResult ? grepResult.split("\n").filter(Boolean).filter((f) => !f.startsWith("./")) : [];
|
|
750
751
|
if (files.length === 0) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
sessionMemory
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BI7KD3SG.js";
|
|
4
4
|
import {
|
|
5
5
|
getProjectRoot
|
|
6
6
|
} from "./chunk-E2KFPEBT.js";
|
|
@@ -82,7 +82,7 @@ function recordDecision(decision) {
|
|
|
82
82
|
}
|
|
83
83
|
async function recordDecisionToGraph(decision) {
|
|
84
84
|
try {
|
|
85
|
-
const { upsertNode, addEdge } = await import("./kumaGraph-
|
|
85
|
+
const { upsertNode, addEdge } = await import("./kumaGraph-35TAIBWD.js");
|
|
86
86
|
const decisionId = `decision::${decision.title.replace(/[^a-zA-Z0-9_\-\s]/g, "").trim().replace(/\s+/g, "-")}`;
|
|
87
87
|
await upsertNode({
|
|
88
88
|
id: decisionId,
|
package/dist/index.js
CHANGED
|
@@ -14,13 +14,13 @@ import {
|
|
|
14
14
|
getGraphStats,
|
|
15
15
|
searchGraph,
|
|
16
16
|
traceFlow
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-K64NSHBR.js";
|
|
18
18
|
import {
|
|
19
19
|
buildDriftMessages,
|
|
20
20
|
getGitDiffStat,
|
|
21
21
|
getSessionStats,
|
|
22
22
|
getUnresolvedCount
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-FOQQ2CSL.js";
|
|
24
24
|
import {
|
|
25
25
|
addContextNote,
|
|
26
26
|
addSecurityFinding,
|
|
@@ -46,16 +46,16 @@ import {
|
|
|
46
46
|
saveResearchCache,
|
|
47
47
|
updateDecisionStatus,
|
|
48
48
|
updateTodoStatus
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-GDNAWLHF.js";
|
|
50
50
|
import {
|
|
51
51
|
formatDecisionTemplate,
|
|
52
52
|
getProactiveMemories,
|
|
53
53
|
recordDecision,
|
|
54
54
|
scoreMemoryRelevance
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-X5TPBDKO.js";
|
|
56
56
|
import {
|
|
57
57
|
sessionMemory
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-BI7KD3SG.js";
|
|
59
59
|
import {
|
|
60
60
|
getProjectRoot,
|
|
61
61
|
validateFilePath
|
|
@@ -111,7 +111,13 @@ var CONTEXT_ALIASES = {
|
|
|
111
111
|
// Researches synonyms
|
|
112
112
|
"researches": "researches",
|
|
113
113
|
"research-list": "researches",
|
|
114
|
-
"list-research": "researches"
|
|
114
|
+
"list-research": "researches",
|
|
115
|
+
// Sync/Batch synonyms (Issue #12)
|
|
116
|
+
"sync": "sync",
|
|
117
|
+
"batch": "sync",
|
|
118
|
+
"kuma_sync": "sync",
|
|
119
|
+
"unified": "sync",
|
|
120
|
+
"state": "sync"
|
|
115
121
|
};
|
|
116
122
|
async function handleContext(params) {
|
|
117
123
|
const rawAction = params.action || "init";
|
|
@@ -134,8 +140,10 @@ async function handleContext(params) {
|
|
|
134
140
|
return handleResearches(params);
|
|
135
141
|
case "health":
|
|
136
142
|
return handleHealth(params);
|
|
143
|
+
case "sync":
|
|
144
|
+
return handleSync(params);
|
|
137
145
|
default:
|
|
138
|
-
return `Unknown action "${action}". Use: init, research, impact, navigate, changes, rollback, researches, health`;
|
|
146
|
+
return `Unknown action "${action}". Use: init, research, impact, navigate, changes, rollback, researches, health, sync`;
|
|
139
147
|
}
|
|
140
148
|
}
|
|
141
149
|
async function handleInit(_params) {
|
|
@@ -196,8 +204,8 @@ async function handleInit(_params) {
|
|
|
196
204
|
lines.push(` \u{1F4DD} Modified: ${summary.modifiedFiles?.length || 0} file(s)`);
|
|
197
205
|
lines.push(` \u{1F6E0}\uFE0F Tool calls: ${summary.toolCallCount}`);
|
|
198
206
|
try {
|
|
199
|
-
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-
|
|
200
|
-
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-
|
|
207
|
+
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-PJGRRBWP.js");
|
|
208
|
+
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-DJUDLYBJ.js");
|
|
201
209
|
const score = await computeSafetyScore(_params.goal);
|
|
202
210
|
const checksStr = JSON.stringify(score.checks);
|
|
203
211
|
await saveHealthSnapshot2(score.score, score.risk, checksStr, score.summary);
|
|
@@ -370,8 +378,8 @@ async function handleResearches(_params) {
|
|
|
370
378
|
async function handleHealth(_params) {
|
|
371
379
|
sessionMemory.recordToolCall("kuma_context_health", {});
|
|
372
380
|
try {
|
|
373
|
-
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-
|
|
374
|
-
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-
|
|
381
|
+
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-PJGRRBWP.js");
|
|
382
|
+
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-DJUDLYBJ.js");
|
|
375
383
|
const score = await computeSafetyScore();
|
|
376
384
|
const checksStr = JSON.stringify(score.checks);
|
|
377
385
|
await saveHealthSnapshot2(score.score, score.risk, checksStr, score.summary);
|
|
@@ -380,6 +388,55 @@ async function handleHealth(_params) {
|
|
|
380
388
|
return `Error computing health: ${err}`;
|
|
381
389
|
}
|
|
382
390
|
}
|
|
391
|
+
async function handleSync(params) {
|
|
392
|
+
sessionMemory.setGoal(params.goal || "Sync session");
|
|
393
|
+
sessionMemory.recordToolCall("kuma_context_sync", { goal: params.goal });
|
|
394
|
+
const lines = [
|
|
395
|
+
"\u{1F504} **Kuma Sync \u2014 Unified State**",
|
|
396
|
+
`\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`,
|
|
397
|
+
"",
|
|
398
|
+
`\u{1F4C1} Project: ${getProjectRoot().split("/").pop() || "unknown"}`,
|
|
399
|
+
`\u{1F550} Session: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
400
|
+
""
|
|
401
|
+
];
|
|
402
|
+
const summary = sessionMemory.getSummary();
|
|
403
|
+
lines.push("**Session State**");
|
|
404
|
+
lines.push(` \u{1F3AF} Goal: ${summary.currentGoal || "not set"}`);
|
|
405
|
+
lines.push(` \u{1F4DD} Modified: ${summary.modifiedFiles?.length || 0} file(s)`);
|
|
406
|
+
lines.push(` \u{1F6E0}\uFE0F Tool calls: ${summary.toolCallCount}`);
|
|
407
|
+
lines.push("");
|
|
408
|
+
try {
|
|
409
|
+
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-PJGRRBWP.js");
|
|
410
|
+
const { saveHealthSnapshot: saveHealthSnapshot2 } = await import("./kumaDb-DJUDLYBJ.js");
|
|
411
|
+
const score = await computeSafetyScore(params.goal);
|
|
412
|
+
const checksStr = JSON.stringify(score.checks);
|
|
413
|
+
await saveHealthSnapshot2(score.score, score.risk, checksStr, score.summary);
|
|
414
|
+
lines.push("**Health Score**");
|
|
415
|
+
lines.push(formatSafetyScore(score));
|
|
416
|
+
} catch {
|
|
417
|
+
lines.push("**Health Score**: \u26A0\uFE0F Could not compute");
|
|
418
|
+
}
|
|
419
|
+
lines.push("");
|
|
420
|
+
try {
|
|
421
|
+
const { getGraphStats: getGraphStats2 } = await import("./kumaGraph-35TAIBWD.js");
|
|
422
|
+
lines.push("**Knowledge Graph**");
|
|
423
|
+
lines.push(await getGraphStats2());
|
|
424
|
+
} catch {
|
|
425
|
+
}
|
|
426
|
+
lines.push("");
|
|
427
|
+
try {
|
|
428
|
+
const { getProactiveMemories: getProactiveMemories2 } = await import("./kumaMemory-5SR3TGRL.js");
|
|
429
|
+
const memories = getProactiveMemories2();
|
|
430
|
+
if (memories) {
|
|
431
|
+
lines.push("**Relevant Memories**");
|
|
432
|
+
lines.push(memories);
|
|
433
|
+
lines.push("");
|
|
434
|
+
}
|
|
435
|
+
} catch {
|
|
436
|
+
}
|
|
437
|
+
lines.push("\u{1F4A1} Sync complete \u2014 all state captured in a single roundtrip.");
|
|
438
|
+
return lines.join("\n");
|
|
439
|
+
}
|
|
383
440
|
function computeProjectHash(scope) {
|
|
384
441
|
try {
|
|
385
442
|
const root = getProjectRoot();
|
|
@@ -501,7 +558,7 @@ async function handleDecision(params) {
|
|
|
501
558
|
case "template":
|
|
502
559
|
return formatDecisionTemplate();
|
|
503
560
|
case "suggest": {
|
|
504
|
-
const { shouldRecordDecision } = await import("./kumaMemory-
|
|
561
|
+
const { shouldRecordDecision } = await import("./kumaMemory-5SR3TGRL.js");
|
|
505
562
|
const check = shouldRecordDecision();
|
|
506
563
|
return check.worth ? `\u{1F4A1} Decision suggested: "${check.title}"
|
|
507
564
|
Use kuma_memory({ action: 'decision', title: '...', context: '...', rationale: '...', outcome: '...' }) to record.` : "\u2705 No decision needed at this time.";
|
|
@@ -579,7 +636,7 @@ async function handleSearch(params) {
|
|
|
579
636
|
if (!query) return "\u26A0\uFE0F query or scope parameter required.";
|
|
580
637
|
const limit = params.limit || 20;
|
|
581
638
|
const memResults = sessionMemory.searchMemory(query, limit);
|
|
582
|
-
const { searchGraph: searchGraph2 } = await import("./kumaGraph-
|
|
639
|
+
const { searchGraph: searchGraph2 } = await import("./kumaGraph-35TAIBWD.js");
|
|
583
640
|
const graphResults = await searchGraph2(query, Math.min(limit, 10));
|
|
584
641
|
const lines = [`\u{1F50D} **Search Results** \u2014 "${query}"
|
|
585
642
|
\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
|
|
@@ -654,7 +711,7 @@ async function handleDecisionLog(params) {
|
|
|
654
711
|
}
|
|
655
712
|
async function handleMine(params) {
|
|
656
713
|
sessionMemory.recordToolCall("kuma_memory_mine", { scope: params.scope });
|
|
657
|
-
const { mineHistoricalDecisions } = await import("./kumaMiner-
|
|
714
|
+
const { mineHistoricalDecisions } = await import("./kumaMiner-BIDSZE3Q.js");
|
|
658
715
|
return await mineHistoricalDecisions({
|
|
659
716
|
scope: params.scope,
|
|
660
717
|
since: typeof params.since === "string" ? params.since : void 0,
|
|
@@ -1791,7 +1848,7 @@ async function handleLock(params) {
|
|
|
1791
1848
|
}
|
|
1792
1849
|
async function handleHealth2(_params) {
|
|
1793
1850
|
try {
|
|
1794
|
-
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-
|
|
1851
|
+
const { computeSafetyScore, formatSafetyScore } = await import("./safetyScore-PJGRRBWP.js");
|
|
1795
1852
|
const score = await computeSafetyScore();
|
|
1796
1853
|
await saveHealthSnapshot(score.score, score.risk, JSON.stringify(score.checks), score.summary);
|
|
1797
1854
|
return formatSafetyScore(score);
|
|
@@ -1905,7 +1962,7 @@ async function handleVerify(params) {
|
|
|
1905
1962
|
}
|
|
1906
1963
|
_lastVerifyCall = now;
|
|
1907
1964
|
sessionMemory.recordToolCall("kuma_safety_verify", { scope: params.scope || params.filePath });
|
|
1908
|
-
const { runAutoVerification } = await import("./kumaVerifier-
|
|
1965
|
+
const { runAutoVerification } = await import("./kumaVerifier-B4D7NOFT.js");
|
|
1909
1966
|
return await runAutoVerification({
|
|
1910
1967
|
scope: params.scope || params.filePath,
|
|
1911
1968
|
force: params.force,
|
|
@@ -2104,7 +2161,7 @@ async function main() {
|
|
|
2104
2161
|
console.error("");
|
|
2105
2162
|
let killedCount = 0;
|
|
2106
2163
|
try {
|
|
2107
|
-
const { getRunningVerificationPid } = await import("./kumaVerifier-
|
|
2164
|
+
const { getRunningVerificationPid } = await import("./kumaVerifier-B4D7NOFT.js");
|
|
2108
2165
|
const pid = getRunningVerificationPid();
|
|
2109
2166
|
if (pid) {
|
|
2110
2167
|
try {
|
|
@@ -2343,7 +2400,7 @@ async function main() {
|
|
|
2343
2400
|
console.error(`[${SERVER_NAME}] \u2705 Restored session (${sessionInfo.toolCallCount} previous tool calls)`);
|
|
2344
2401
|
}
|
|
2345
2402
|
try {
|
|
2346
|
-
const { buildFromSessionMemory } = await import("./kumaGraph-
|
|
2403
|
+
const { buildFromSessionMemory } = await import("./kumaGraph-35TAIBWD.js");
|
|
2347
2404
|
const edgeCount = await buildFromSessionMemory();
|
|
2348
2405
|
if (edgeCount > 0) {
|
|
2349
2406
|
console.error(`[${SERVER_NAME}] \u2705 Graph auto-populated with ${edgeCount} entries from session memory`);
|
|
@@ -2363,7 +2420,7 @@ async function main() {
|
|
|
2363
2420
|
console.error(`[${SERVER_NAME}] \u26A0\uFE0F Scratch directory setup: ${err}`);
|
|
2364
2421
|
}
|
|
2365
2422
|
try {
|
|
2366
|
-
const { getDb: getDb2, saveDb: saveDb2 } = await import("./kumaDb-
|
|
2423
|
+
const { getDb: getDb2, saveDb: saveDb2 } = await import("./kumaDb-DJUDLYBJ.js");
|
|
2367
2424
|
const db = await getDb2();
|
|
2368
2425
|
db.run(
|
|
2369
2426
|
`INSERT INTO sessions (started_at, goal, tool_calls) VALUES (?, ?, ?)`,
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
recordDecision,
|
|
5
5
|
scoreMemoryRelevance,
|
|
6
6
|
shouldRecordDecision
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-X5TPBDKO.js";
|
|
8
|
+
import "./chunk-BI7KD3SG.js";
|
|
9
9
|
import "./chunk-E2KFPEBT.js";
|
|
10
10
|
export {
|
|
11
11
|
formatDecisionTemplate,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
recordDecisionLog
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GDNAWLHF.js";
|
|
4
4
|
import {
|
|
5
5
|
recordDecision
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-X5TPBDKO.js";
|
|
7
|
+
import "./chunk-BI7KD3SG.js";
|
|
8
8
|
import "./chunk-E2KFPEBT.js";
|
|
9
9
|
|
|
10
10
|
// src/engine/kumaMiner.ts
|
|
@@ -19,9 +19,10 @@ async function mineHistoricalDecisions(options = {}) {
|
|
|
19
19
|
try {
|
|
20
20
|
const sinceFlag = options.since ? `--since="${options.since}"` : `--since="1 year"`;
|
|
21
21
|
const gitCmd = `git log ${sinceFlag} -n 100 --pretty=format:"%h|%an|%ad|%s" --date=short`;
|
|
22
|
-
const gitOutput = execSync(gitCmd, { cwd: root, encoding: "utf-8" });
|
|
22
|
+
const gitOutput = execSync(gitCmd, { cwd: root, encoding: "utf-8", timeout: 15e3 });
|
|
23
23
|
const keywords = ["fix", "revert", "hack", "workaround", "urgent", "hotfix", "don't touch", "temporary", "deprecated", "workaround"];
|
|
24
24
|
const lines = gitOutput.split("\n").filter(Boolean);
|
|
25
|
+
const matchingHashes = [];
|
|
25
26
|
for (const line of lines) {
|
|
26
27
|
const parts = line.split("|");
|
|
27
28
|
if (parts.length < 4) continue;
|
|
@@ -29,9 +30,42 @@ async function mineHistoricalDecisions(options = {}) {
|
|
|
29
30
|
const lowerSubj = subject.toLowerCase();
|
|
30
31
|
const matchedKeyword = keywords.find((kw) => lowerSubj.includes(kw));
|
|
31
32
|
if (matchedKeyword) {
|
|
32
|
-
|
|
33
|
+
matchingHashes.push({ hash, author, date, subject, keyword: matchedKeyword });
|
|
34
|
+
if (matchingHashes.length >= limit) break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
let changedFilesMap = /* @__PURE__ */ new Map();
|
|
38
|
+
if (matchingHashes.length > 0) {
|
|
39
|
+
try {
|
|
40
|
+
const hashesStr = matchingHashes.map((h) => h.hash).join(" ");
|
|
41
|
+
const batchOutput = execSync(
|
|
42
|
+
`git show --name-only --oneline ${hashesStr} 2>/dev/null | head -200`,
|
|
43
|
+
{ cwd: root, encoding: "utf-8", timeout: 1e4, maxBuffer: 256 * 1024 }
|
|
44
|
+
);
|
|
45
|
+
let currentHash = "";
|
|
46
|
+
const files = [];
|
|
47
|
+
for (const line of batchOutput.split("\n")) {
|
|
48
|
+
if (matchingHashes.find((h) => line.startsWith(h.hash))) {
|
|
49
|
+
if (currentHash && files.length > 0) {
|
|
50
|
+
changedFilesMap.set(currentHash, files.slice(0, 3).join(", "));
|
|
51
|
+
}
|
|
52
|
+
currentHash = line.split(" ")[0];
|
|
53
|
+
files.length = 0;
|
|
54
|
+
} else if (line.trim() && !line.startsWith("diff")) {
|
|
55
|
+
files.push(line.trim());
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (currentHash && files.length > 0) {
|
|
59
|
+
changedFilesMap.set(currentHash, files.slice(0, 3).join(", "));
|
|
60
|
+
}
|
|
61
|
+
} catch {
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for (const { hash, author, date, subject, keyword: matchedKeyword } of matchingHashes) {
|
|
65
|
+
let changedFiles = changedFilesMap.get(hash) || "";
|
|
66
|
+
if (!changedFiles) {
|
|
33
67
|
try {
|
|
34
|
-
changedFiles = execSync(`git show --name-only --oneline ${hash}`, { cwd: root, encoding: "utf-8" }).split("\n").slice(1).filter(Boolean).slice(0, 3).join(", ");
|
|
68
|
+
changedFiles = execSync(`git show --name-only --oneline ${hash}`, { cwd: root, encoding: "utf-8", timeout: 5e3 }).split("\n").slice(1).filter(Boolean).slice(0, 3).join(", ");
|
|
35
69
|
} catch {
|
|
36
70
|
}
|
|
37
71
|
candidates.push({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getLatestVerifications,
|
|
3
3
|
saveVerification
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GDNAWLHF.js";
|
|
5
5
|
import {
|
|
6
6
|
sessionMemory
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BI7KD3SG.js";
|
|
8
8
|
import "./chunk-E2KFPEBT.js";
|
|
9
9
|
|
|
10
10
|
// src/engine/kumaVerifier.ts
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
getGitDiffStat,
|
|
3
3
|
getSessionStats,
|
|
4
4
|
getUnresolvedCount
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FOQQ2CSL.js";
|
|
6
6
|
import {
|
|
7
7
|
sessionMemory
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BI7KD3SG.js";
|
|
9
9
|
import "./chunk-E2KFPEBT.js";
|
|
10
10
|
|
|
11
11
|
// src/engine/safetyScore.ts
|
|
@@ -15,7 +15,7 @@ async function computeSafetyScore(inputGoal) {
|
|
|
15
15
|
let totalScore = 0;
|
|
16
16
|
const maxScore = 100;
|
|
17
17
|
const gitStat = getGitDiffStat();
|
|
18
|
-
if (gitStat) {
|
|
18
|
+
if (gitStat && gitStat !== "clean") {
|
|
19
19
|
const lines = gitStat.split("\n").filter(Boolean).length;
|
|
20
20
|
if (lines === 0) {
|
|
21
21
|
checks.push({
|
|
@@ -42,6 +42,14 @@ async function computeSafetyScore(inputGoal) {
|
|
|
42
42
|
});
|
|
43
43
|
totalScore += 10;
|
|
44
44
|
}
|
|
45
|
+
} else if (gitStat === "clean") {
|
|
46
|
+
checks.push({
|
|
47
|
+
label: "Git Clean",
|
|
48
|
+
status: "pass",
|
|
49
|
+
message: "Working tree is clean",
|
|
50
|
+
weight: 20
|
|
51
|
+
});
|
|
52
|
+
totalScore += 20;
|
|
45
53
|
} else {
|
|
46
54
|
checks.push({
|
|
47
55
|
label: "Git Status",
|
|
@@ -52,7 +60,7 @@ async function computeSafetyScore(inputGoal) {
|
|
|
52
60
|
totalScore += 20;
|
|
53
61
|
}
|
|
54
62
|
try {
|
|
55
|
-
const { getDb } = await import("./kumaDb-
|
|
63
|
+
const { getDb } = await import("./kumaDb-DJUDLYBJ.js");
|
|
56
64
|
const db = await getDb();
|
|
57
65
|
const nodeCount = db.exec("SELECT COUNT(*) as c FROM nodes")[0]?.values[0][0] ?? 0;
|
|
58
66
|
const edgeCount = db.exec("SELECT COUNT(*) as c FROM edges")[0]?.values[0][0] ?? 0;
|
|
@@ -83,7 +91,7 @@ async function computeSafetyScore(inputGoal) {
|
|
|
83
91
|
totalScore += 5;
|
|
84
92
|
}
|
|
85
93
|
try {
|
|
86
|
-
const { getDb } = await import("./kumaDb-
|
|
94
|
+
const { getDb } = await import("./kumaDb-DJUDLYBJ.js");
|
|
87
95
|
const db = await getDb();
|
|
88
96
|
const researchCount = db.exec("SELECT COUNT(*) as c FROM research_cache")[0]?.values[0][0] ?? 0;
|
|
89
97
|
checks.push({
|
|
@@ -108,7 +116,7 @@ async function computeSafetyScore(inputGoal) {
|
|
|
108
116
|
const hasRunTests = stats.hasRunTests;
|
|
109
117
|
let latestVerif = null;
|
|
110
118
|
try {
|
|
111
|
-
const { getLatestVerifications } = await import("./kumaDb-
|
|
119
|
+
const { getLatestVerifications } = await import("./kumaDb-DJUDLYBJ.js");
|
|
112
120
|
const verifs = await getLatestVerifications(1);
|
|
113
121
|
if (verifs.length > 0) latestVerif = verifs[0];
|
|
114
122
|
} catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumpslabs/kuma",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.6",
|
|
4
4
|
"description": "Safety-first context & orchestration engine for AI coding agents. MCP server with mandatory research pipeline, knowledge graph, impact analysis, decision memory, and safety guard — works with any MCP client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|