@plumpslabs/kuma 2.2.2 → 2.2.5
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 +221 -165
- package/dist/index.js +534 -74
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -100,13 +100,14 @@ async function handleSmartGrep(params) {
|
|
|
100
100
|
const projectRoot = getProjectRoot();
|
|
101
101
|
try {
|
|
102
102
|
const searchPattern = targetFolder ? path.join(targetFolder, "**/*").replace(/\\/g, "/") : "**/*";
|
|
103
|
+
const targetDepth = targetFolder ? targetFolder.split("/").filter(Boolean).length : 0;
|
|
104
|
+
const maxDepth = targetFolder ? Math.min(targetDepth + 5, 20) : 10;
|
|
103
105
|
let entries = await fg(searchPattern, {
|
|
104
106
|
cwd: projectRoot,
|
|
105
107
|
ignore: IGNORE_PATTERNS,
|
|
106
108
|
onlyFiles: true,
|
|
107
109
|
absolute: false,
|
|
108
|
-
deep:
|
|
109
|
-
// Batasi kedalaman
|
|
110
|
+
deep: maxDepth,
|
|
110
111
|
dot: false
|
|
111
112
|
// Skip dotfiles
|
|
112
113
|
});
|
|
@@ -175,13 +176,14 @@ async function handleSmartGrep(params) {
|
|
|
175
176
|
}
|
|
176
177
|
}
|
|
177
178
|
function createRegex(query) {
|
|
179
|
+
const normalized = query.replace(/\\\|/g, "|");
|
|
178
180
|
try {
|
|
179
|
-
if (/[.\\+*?[\](){}^$|]/.test(
|
|
180
|
-
return new RegExp(
|
|
181
|
+
if (/[.\\+*?[\](){}^$|]/.test(normalized)) {
|
|
182
|
+
return new RegExp(normalized, "i");
|
|
181
183
|
}
|
|
182
184
|
} catch {
|
|
183
185
|
}
|
|
184
|
-
return new RegExp(
|
|
186
|
+
return new RegExp(normalized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "i");
|
|
185
187
|
}
|
|
186
188
|
function formatResults(results, query, filesScanned) {
|
|
187
189
|
if (results.length === 0) {
|
|
@@ -887,10 +889,10 @@ File "${filePath}" restored from backup: "${relBackupPath}".`;
|
|
|
887
889
|
}
|
|
888
890
|
async function handleCommitRollback(filePath, version) {
|
|
889
891
|
try {
|
|
890
|
-
const { execSync:
|
|
892
|
+
const { execSync: execSync10 } = await import("child_process");
|
|
891
893
|
const root = getProjectRoot();
|
|
892
894
|
if (version === "list") {
|
|
893
|
-
const log =
|
|
895
|
+
const log = execSync10("git log --oneline -20", { cwd: root, encoding: "utf-8" });
|
|
894
896
|
const lines = log.trim().split("\n").map((l) => ` ${l}`).join("\n");
|
|
895
897
|
return [
|
|
896
898
|
`\u{1F4CB} **Recent Commits:**`,
|
|
@@ -900,7 +902,7 @@ async function handleCommitRollback(filePath, version) {
|
|
|
900
902
|
`\u{1F4A1} Use { action: "rollback", scope: "commit", version: <N> } to restore a specific commit.`
|
|
901
903
|
].join("\n");
|
|
902
904
|
}
|
|
903
|
-
const status =
|
|
905
|
+
const status = execSync10("git status --porcelain", { cwd: root, encoding: "utf-8" }).trim();
|
|
904
906
|
if (status) {
|
|
905
907
|
return [
|
|
906
908
|
`\u26A0\uFE0F **Uncommitted changes detected.**`,
|
|
@@ -921,10 +923,10 @@ async function handleCommitRollback(filePath, version) {
|
|
|
921
923
|
target = "HEAD~1";
|
|
922
924
|
}
|
|
923
925
|
if (filePath) {
|
|
924
|
-
|
|
926
|
+
execSync10(`git checkout ${target} -- "${filePath}"`, { cwd: root, encoding: "utf-8" });
|
|
925
927
|
return `\u2705 **Commit Rollback** \u2014 File "${filePath}" restored from ${target}.`;
|
|
926
928
|
} else {
|
|
927
|
-
|
|
929
|
+
execSync10(`git checkout ${target}`, { cwd: root, encoding: "utf-8" });
|
|
928
930
|
return `\u2705 **Commit Rollback** \u2014 Project restored to ${target}.`;
|
|
929
931
|
}
|
|
930
932
|
} catch (err) {
|
|
@@ -1214,8 +1216,10 @@ async function detectConventions(forceRescan = false) {
|
|
|
1214
1216
|
}
|
|
1215
1217
|
const projectRoot = getProjectRoot();
|
|
1216
1218
|
const workspaces = detectWorkspaces(projectRoot);
|
|
1219
|
+
const lang = detectLanguage(projectRoot);
|
|
1220
|
+
const framework = lang !== "typescript" && lang !== "javascript" ? detectMultiLanguageFramework(projectRoot, lang) : detectFramework(projectRoot);
|
|
1217
1221
|
const conventions = {
|
|
1218
|
-
framework
|
|
1222
|
+
framework,
|
|
1219
1223
|
projectType: detectProjectType(projectRoot),
|
|
1220
1224
|
testRunner: detectTestRunner(projectRoot),
|
|
1221
1225
|
styling: detectStyling(projectRoot),
|
|
@@ -1228,6 +1232,9 @@ async function detectConventions(forceRescan = false) {
|
|
|
1228
1232
|
isMonorepo: workspaces.length > 0,
|
|
1229
1233
|
workspaces
|
|
1230
1234
|
};
|
|
1235
|
+
if (lang !== "typescript" && lang !== "javascript") {
|
|
1236
|
+
conventions.moduleSystem = "other";
|
|
1237
|
+
}
|
|
1231
1238
|
cachedConventions = conventions;
|
|
1232
1239
|
return conventions;
|
|
1233
1240
|
}
|
|
@@ -1504,13 +1511,169 @@ function detectModuleSystem(root) {
|
|
|
1504
1511
|
return "cjs";
|
|
1505
1512
|
}
|
|
1506
1513
|
function detectLanguage(root) {
|
|
1514
|
+
if (fs5.existsSync(path5.join(root, "go.mod"))) return "go";
|
|
1515
|
+
if (fs5.existsSync(path5.join(root, "Cargo.toml"))) return "rust";
|
|
1516
|
+
if (fs5.existsSync(path5.join(root, "composer.json"))) return "php";
|
|
1517
|
+
if (fs5.existsSync(path5.join(root, "pyproject.toml")) || fs5.existsSync(path5.join(root, "requirements.txt")) || fs5.existsSync(path5.join(root, "setup.py"))) return "python";
|
|
1518
|
+
if (fs5.existsSync(path5.join(root, "Gemfile"))) return "ruby";
|
|
1519
|
+
if (fs5.existsSync(path5.join(root, "pom.xml"))) return "java";
|
|
1520
|
+
if (fs5.existsSync(path5.join(root, "build.gradle")) || fs5.existsSync(path5.join(root, "build.gradle.kts"))) return "kotlin";
|
|
1521
|
+
if (fs5.existsSync(path5.join(root, "Package.swift"))) return "swift";
|
|
1522
|
+
try {
|
|
1523
|
+
const entries = fs5.readdirSync(root);
|
|
1524
|
+
if (entries.some((e) => e.endsWith(".csproj"))) return "csharp";
|
|
1525
|
+
} catch {
|
|
1526
|
+
}
|
|
1507
1527
|
if (fs5.existsSync(path5.join(root, "tsconfig.json"))) return "typescript";
|
|
1508
1528
|
const srcDir = path5.join(root, "src");
|
|
1509
1529
|
if (fs5.existsSync(srcDir)) {
|
|
1510
1530
|
const tsFiles = findFiles(srcDir, [".ts", ".tsx"]);
|
|
1511
1531
|
if (tsFiles.length > 0) return "typescript";
|
|
1532
|
+
const jsFiles = findFiles(srcDir, [".js", ".jsx"]);
|
|
1533
|
+
if (jsFiles.length > 0) return "javascript";
|
|
1534
|
+
}
|
|
1535
|
+
try {
|
|
1536
|
+
const tsFiles = findFiles(root, [".ts", ".tsx"]);
|
|
1537
|
+
if (tsFiles.length > 0) return "typescript";
|
|
1538
|
+
const jsFiles = findFiles(root, [".js", ".jsx"]);
|
|
1539
|
+
if (jsFiles.length > 0) return "javascript";
|
|
1540
|
+
} catch {
|
|
1541
|
+
}
|
|
1542
|
+
return "typescript";
|
|
1543
|
+
}
|
|
1544
|
+
function detectMultiLanguageFramework(root, language) {
|
|
1545
|
+
switch (language) {
|
|
1546
|
+
case "go": {
|
|
1547
|
+
try {
|
|
1548
|
+
const goMod = fs5.readFileSync(path5.join(root, "go.mod"), "utf-8");
|
|
1549
|
+
if (goMod.includes("github.com/gin-gonic/gin")) return "Gin";
|
|
1550
|
+
if (goMod.includes("github.com/labstack/echo")) return "Echo";
|
|
1551
|
+
if (goMod.includes("github.com/gofiber/fiber")) return "Fiber";
|
|
1552
|
+
if (goMod.includes("github.com/go-chi/chi")) return "Chi";
|
|
1553
|
+
if (goMod.includes("github.com/gorilla/mux")) return "Gorilla Mux";
|
|
1554
|
+
if (goMod.includes("github.com/urfave/cli")) return "CLI (urfave/cli)";
|
|
1555
|
+
if (goMod.includes("github.com/spf13/cobra")) return "Cobra CLI";
|
|
1556
|
+
} catch {
|
|
1557
|
+
}
|
|
1558
|
+
return "Go";
|
|
1559
|
+
}
|
|
1560
|
+
case "php": {
|
|
1561
|
+
try {
|
|
1562
|
+
const composer = JSON.parse(fs5.readFileSync(path5.join(root, "composer.json"), "utf-8"));
|
|
1563
|
+
const req = composer.require ?? {};
|
|
1564
|
+
const reqDev = composer["require-dev"] ?? {};
|
|
1565
|
+
const deps = { ...req, ...reqDev };
|
|
1566
|
+
if (deps["laravel/framework"]) return "Laravel";
|
|
1567
|
+
if (deps["symfony/symfony"] || deps["symfony/framework-bundle"]) return "Symfony";
|
|
1568
|
+
if (deps["codeigniter4/framework"]) return "CodeIgniter";
|
|
1569
|
+
if (deps["yiisoft/yii2"]) return "Yii2";
|
|
1570
|
+
if (deps["cakephp/cakephp"]) return "CakePHP";
|
|
1571
|
+
if (deps["phalcon/incubator"]) return "Phalcon";
|
|
1572
|
+
if (deps["wp-coding-standards/wpcs"]) return "WordPress";
|
|
1573
|
+
} catch {
|
|
1574
|
+
}
|
|
1575
|
+
return "PHP";
|
|
1576
|
+
}
|
|
1577
|
+
case "python": {
|
|
1578
|
+
try {
|
|
1579
|
+
if (fs5.existsSync(path5.join(root, "pyproject.toml"))) {
|
|
1580
|
+
const content = fs5.readFileSync(path5.join(root, "pyproject.toml"), "utf-8");
|
|
1581
|
+
if (content.includes("django")) return "Django";
|
|
1582
|
+
if (content.includes("flask")) return "Flask";
|
|
1583
|
+
if (content.includes("fastapi")) return "FastAPI";
|
|
1584
|
+
}
|
|
1585
|
+
if (fs5.existsSync(path5.join(root, "requirements.txt"))) {
|
|
1586
|
+
const content = fs5.readFileSync(path5.join(root, "requirements.txt"), "utf-8");
|
|
1587
|
+
if (content.includes("django")) return "Django";
|
|
1588
|
+
if (content.includes("flask")) return "Flask";
|
|
1589
|
+
if (content.includes("fastapi")) return "FastAPI";
|
|
1590
|
+
if (content.includes("tornado")) return "Tornado";
|
|
1591
|
+
if (content.includes("aiohttp")) return "aiohttp";
|
|
1592
|
+
}
|
|
1593
|
+
} catch {
|
|
1594
|
+
}
|
|
1595
|
+
return "Python";
|
|
1596
|
+
}
|
|
1597
|
+
case "rust": {
|
|
1598
|
+
try {
|
|
1599
|
+
const cargo = fs5.readFileSync(path5.join(root, "Cargo.toml"), "utf-8");
|
|
1600
|
+
if (cargo.includes("axum")) return "Axum";
|
|
1601
|
+
if (cargo.includes("actix-web")) return "Actix Web";
|
|
1602
|
+
if (cargo.includes("rocket")) return "Rocket";
|
|
1603
|
+
if (cargo.includes("warp")) return "Warp";
|
|
1604
|
+
if (cargo.includes("tide")) return "Tide";
|
|
1605
|
+
if (cargo.includes("poem")) return "Poem";
|
|
1606
|
+
if (cargo.includes("clap")) return "Clap CLI";
|
|
1607
|
+
} catch {
|
|
1608
|
+
}
|
|
1609
|
+
return "Rust";
|
|
1610
|
+
}
|
|
1611
|
+
case "java": {
|
|
1612
|
+
try {
|
|
1613
|
+
const content = fs5.readFileSync(path5.join(root, "pom.xml"), "utf-8");
|
|
1614
|
+
if (content.includes("spring-boot")) return "Spring Boot";
|
|
1615
|
+
if (content.includes("quarkus")) return "Quarkus";
|
|
1616
|
+
if (content.includes("micronaut")) return "Micronaut";
|
|
1617
|
+
if (content.includes("jakarta")) return "Jakarta EE";
|
|
1618
|
+
if (content.includes("helidon")) return "Helidon";
|
|
1619
|
+
} catch {
|
|
1620
|
+
try {
|
|
1621
|
+
const gradle = fs5.readFileSync(path5.join(root, "build.gradle"), "utf-8");
|
|
1622
|
+
if (gradle.includes("spring")) return "Spring Boot";
|
|
1623
|
+
if (gradle.includes("quarkus")) return "Quarkus";
|
|
1624
|
+
} catch {
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
return "Java";
|
|
1628
|
+
}
|
|
1629
|
+
case "kotlin": {
|
|
1630
|
+
try {
|
|
1631
|
+
const gradle = fs5.readFileSync(path5.join(root, "build.gradle.kts"), "utf-8");
|
|
1632
|
+
if (gradle.includes("spring")) return "Spring Boot (Kotlin)";
|
|
1633
|
+
if (gradle.includes("ktor")) return "Ktor";
|
|
1634
|
+
} catch {
|
|
1635
|
+
}
|
|
1636
|
+
return "Kotlin";
|
|
1637
|
+
}
|
|
1638
|
+
case "ruby": {
|
|
1639
|
+
try {
|
|
1640
|
+
const gemfile = fs5.readFileSync(path5.join(root, "Gemfile"), "utf-8");
|
|
1641
|
+
if (gemfile.includes("rails")) return "Ruby on Rails";
|
|
1642
|
+
if (gemfile.includes("sinatra")) return "Sinatra";
|
|
1643
|
+
if (gemfile.includes("hanami")) return "Hanami";
|
|
1644
|
+
if (gemfile.includes("grape")) return "Grape API";
|
|
1645
|
+
} catch {
|
|
1646
|
+
}
|
|
1647
|
+
return "Ruby";
|
|
1648
|
+
}
|
|
1649
|
+
case "csharp": {
|
|
1650
|
+
try {
|
|
1651
|
+
const entries = fs5.readdirSync(root);
|
|
1652
|
+
const csproj = entries.find((e) => e.endsWith(".csproj"));
|
|
1653
|
+
if (csproj) {
|
|
1654
|
+
const content = fs5.readFileSync(path5.join(root, csproj), "utf-8");
|
|
1655
|
+
if (content.includes("Microsoft.AspNetCore")) return "ASP.NET Core";
|
|
1656
|
+
if (content.includes("Microsoft.Maui")) return ".NET MAUI";
|
|
1657
|
+
if (content.includes("Serilog")) return "Serilog";
|
|
1658
|
+
}
|
|
1659
|
+
} catch {
|
|
1660
|
+
}
|
|
1661
|
+
return "C#";
|
|
1662
|
+
}
|
|
1663
|
+
case "swift": {
|
|
1664
|
+
try {
|
|
1665
|
+
const content = fs5.readFileSync(path5.join(root, "Package.swift"), "utf-8");
|
|
1666
|
+
if (content.includes("vapor")) return "Vapor";
|
|
1667
|
+
if (content.includes("swift-nio")) return "SwiftNIO";
|
|
1668
|
+
if (content.includes("perfect")) return "Perfect";
|
|
1669
|
+
if (content.includes("kitura")) return "Kitura";
|
|
1670
|
+
} catch {
|
|
1671
|
+
}
|
|
1672
|
+
return "Swift";
|
|
1673
|
+
}
|
|
1674
|
+
default:
|
|
1675
|
+
return detectFramework(root);
|
|
1512
1676
|
}
|
|
1513
|
-
return "javascript";
|
|
1514
1677
|
}
|
|
1515
1678
|
function detectFeatures(root) {
|
|
1516
1679
|
const features = [];
|
|
@@ -7965,57 +8128,236 @@ function formatDecisionTemplate() {
|
|
|
7965
8128
|
}
|
|
7966
8129
|
|
|
7967
8130
|
// src/engine/kumaContextEngine.ts
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
8131
|
+
import { execSync as execSync8 } from "child_process";
|
|
8132
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
8133
|
+
"the",
|
|
8134
|
+
"this",
|
|
8135
|
+
"that",
|
|
8136
|
+
"with",
|
|
8137
|
+
"from",
|
|
8138
|
+
"what",
|
|
8139
|
+
"which",
|
|
8140
|
+
"fix",
|
|
8141
|
+
"bug",
|
|
8142
|
+
"bikin",
|
|
8143
|
+
"buat",
|
|
8144
|
+
"add",
|
|
8145
|
+
"new",
|
|
8146
|
+
"need",
|
|
8147
|
+
"make",
|
|
8148
|
+
"want",
|
|
8149
|
+
"can",
|
|
8150
|
+
"get",
|
|
8151
|
+
"set",
|
|
8152
|
+
"use",
|
|
8153
|
+
"using",
|
|
8154
|
+
"would",
|
|
8155
|
+
"could",
|
|
8156
|
+
"should",
|
|
8157
|
+
"have",
|
|
8158
|
+
"has",
|
|
8159
|
+
"had",
|
|
8160
|
+
"for",
|
|
8161
|
+
"and",
|
|
8162
|
+
"not",
|
|
8163
|
+
"but",
|
|
8164
|
+
"are",
|
|
8165
|
+
"was",
|
|
8166
|
+
"were",
|
|
8167
|
+
"all",
|
|
8168
|
+
"any",
|
|
8169
|
+
"each",
|
|
8170
|
+
"every",
|
|
8171
|
+
"some",
|
|
8172
|
+
"find",
|
|
8173
|
+
"show",
|
|
8174
|
+
"list",
|
|
8175
|
+
"create",
|
|
8176
|
+
"update",
|
|
8177
|
+
"delete",
|
|
8178
|
+
"remove",
|
|
8179
|
+
"change"
|
|
8180
|
+
]);
|
|
8181
|
+
function extractTerms(goal) {
|
|
8182
|
+
const words = goal.toLowerCase().split(/[\s_\/-]+/).filter((w) => w.length > 2);
|
|
8183
|
+
const filtered = words.filter((w) => !STOP_WORDS.has(w));
|
|
8184
|
+
const unique = [...new Set(filtered)];
|
|
8185
|
+
return unique.slice(0, 10);
|
|
8186
|
+
}
|
|
8187
|
+
async function searchNodesFts(db, terms) {
|
|
8188
|
+
const results = [];
|
|
8189
|
+
if (terms.length === 0) return results;
|
|
7971
8190
|
try {
|
|
7972
|
-
const
|
|
7973
|
-
|
|
8191
|
+
const escaped = terms.map((t) => t.replace(/"/g, '""'));
|
|
8192
|
+
const ftsQuery = escaped.map((t) => '"' + t + '"').join(" OR ");
|
|
8193
|
+
const stmt = db.prepare(`
|
|
8194
|
+
SELECT n.id, n.type, n.name, n.file_path, rank
|
|
8195
|
+
FROM nodes_fts f
|
|
8196
|
+
JOIN nodes n ON n.rowid = f.rowid
|
|
8197
|
+
WHERE nodes_fts MATCH ?
|
|
8198
|
+
ORDER BY rank
|
|
8199
|
+
LIMIT 10
|
|
8200
|
+
`);
|
|
8201
|
+
stmt.bind([ftsQuery]);
|
|
8202
|
+
while (stmt.step()) {
|
|
8203
|
+
const row = stmt.getAsObject();
|
|
8204
|
+
results.push({
|
|
8205
|
+
id: row.id,
|
|
8206
|
+
type: row.type,
|
|
8207
|
+
name: row.name,
|
|
8208
|
+
file_path: row.file_path,
|
|
8209
|
+
rank: row.rank || 0
|
|
8210
|
+
});
|
|
8211
|
+
}
|
|
8212
|
+
stmt.free();
|
|
8213
|
+
return results;
|
|
8214
|
+
} catch {
|
|
8215
|
+
}
|
|
8216
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8217
|
+
for (const term of terms) {
|
|
8218
|
+
try {
|
|
7974
8219
|
const stmt = db.prepare(`
|
|
7975
8220
|
SELECT id, type, name, file_path FROM nodes
|
|
7976
|
-
WHERE
|
|
8221
|
+
WHERE name LIKE ? OR file_path LIKE ?
|
|
7977
8222
|
ORDER BY updated_at DESC LIMIT 5
|
|
7978
8223
|
`);
|
|
7979
8224
|
stmt.bind([`%${term}%`, `%${term}%`]);
|
|
7980
8225
|
while (stmt.step()) {
|
|
7981
8226
|
const row = stmt.getAsObject();
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
8227
|
+
const id = row.id;
|
|
8228
|
+
if (!seen.has(id)) {
|
|
8229
|
+
seen.add(id);
|
|
8230
|
+
results.push({
|
|
8231
|
+
id,
|
|
8232
|
+
type: row.type,
|
|
8233
|
+
name: row.name,
|
|
8234
|
+
file_path: row.file_path,
|
|
8235
|
+
rank: 0
|
|
8236
|
+
});
|
|
8237
|
+
}
|
|
7988
8238
|
}
|
|
7989
8239
|
stmt.free();
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8240
|
+
} catch {
|
|
8241
|
+
}
|
|
8242
|
+
}
|
|
8243
|
+
return results.slice(0, 10);
|
|
8244
|
+
}
|
|
8245
|
+
function getFileRecencySeconds(filePath) {
|
|
8246
|
+
try {
|
|
8247
|
+
const escapedPath = filePath.replace(/"/g, '\\"');
|
|
8248
|
+
const result = execSync8(
|
|
8249
|
+
'git log -1 --format=%ct -- "' + escapedPath + '" 2>/dev/null || echo 0',
|
|
8250
|
+
{ encoding: "utf-8", timeout: 2e3 }
|
|
8251
|
+
);
|
|
8252
|
+
const timestamp = parseInt(result.trim(), 10);
|
|
8253
|
+
if (!timestamp || timestamp === 0) return null;
|
|
8254
|
+
return Math.floor(Date.now() / 1e3) - timestamp;
|
|
8255
|
+
} catch {
|
|
8256
|
+
return null;
|
|
8257
|
+
}
|
|
8258
|
+
}
|
|
8259
|
+
function calculatePriority(type, label, terms, recencySeconds) {
|
|
8260
|
+
let score = 0;
|
|
8261
|
+
switch (type) {
|
|
8262
|
+
case "failure":
|
|
8263
|
+
score = 90;
|
|
8264
|
+
break;
|
|
8265
|
+
case "file":
|
|
8266
|
+
score = 60;
|
|
8267
|
+
break;
|
|
8268
|
+
case "graph":
|
|
8269
|
+
score = 50;
|
|
8270
|
+
break;
|
|
8271
|
+
case "memory":
|
|
8272
|
+
score = 40;
|
|
8273
|
+
break;
|
|
8274
|
+
}
|
|
8275
|
+
const lower = label.toLowerCase();
|
|
8276
|
+
for (const term of terms) {
|
|
8277
|
+
if (lower === term) {
|
|
8278
|
+
score += 30;
|
|
8279
|
+
} else if (lower.includes(term)) {
|
|
8280
|
+
score += 15;
|
|
8281
|
+
}
|
|
8282
|
+
}
|
|
8283
|
+
if (recencySeconds !== null) {
|
|
8284
|
+
if (recencySeconds < 3600) score += 20;
|
|
8285
|
+
else if (recencySeconds < 86400) score += 10;
|
|
8286
|
+
else if (recencySeconds < 604800) score += 5;
|
|
8287
|
+
}
|
|
8288
|
+
return Math.min(score, 100);
|
|
8289
|
+
}
|
|
8290
|
+
async function buildContextForGoal(goal) {
|
|
8291
|
+
const items = [];
|
|
8292
|
+
const terms = extractTerms(goal);
|
|
8293
|
+
if (terms.length === 0) {
|
|
8294
|
+
const modifiedFiles2 = sessionMemory.getModifiedFiles();
|
|
8295
|
+
for (const mf of modifiedFiles2) {
|
|
8296
|
+
items.push({
|
|
8297
|
+
type: "file",
|
|
8298
|
+
label: mf.filePath,
|
|
8299
|
+
detail: "Modified (" + mf.status + ")",
|
|
8300
|
+
priority: calculatePriority("file", mf.filePath, [], null)
|
|
8301
|
+
});
|
|
8302
|
+
}
|
|
8303
|
+
return { context: items.slice(0, 15), summary: "\u{1F4CB} No specific terms in goal. Showing " + Math.min(items.length, 15) + " modified file(s)." };
|
|
8304
|
+
}
|
|
8305
|
+
try {
|
|
8306
|
+
const db = await getDb();
|
|
8307
|
+
const nodeResults = await searchNodesFts(db, terms);
|
|
8308
|
+
const seenNodes = /* @__PURE__ */ new Set();
|
|
8309
|
+
for (const node of nodeResults) {
|
|
8310
|
+
if (seenNodes.has(node.id)) continue;
|
|
8311
|
+
seenNodes.add(node.id);
|
|
8312
|
+
const recency = node.file_path ? getFileRecencySeconds(node.file_path) : null;
|
|
8313
|
+
const priority = calculatePriority("graph", node.name, terms, recency);
|
|
8314
|
+
items.push({
|
|
8315
|
+
type: "graph",
|
|
8316
|
+
label: node.name,
|
|
8317
|
+
detail: node.type + ": " + (node.file_path || node.id),
|
|
8318
|
+
priority
|
|
8319
|
+
});
|
|
8320
|
+
if (nodeResults.indexOf(node) < 3) {
|
|
8321
|
+
try {
|
|
8322
|
+
const edgeStmt = db.prepare(`
|
|
8323
|
+
SELECT e.type, e.weight, n.name, n.file_path
|
|
8324
|
+
FROM edges e
|
|
8325
|
+
JOIN nodes n ON n.id = e.target_id
|
|
8326
|
+
WHERE e.source_id = ?
|
|
8327
|
+
ORDER BY e.weight DESC LIMIT 3
|
|
8328
|
+
`);
|
|
8329
|
+
edgeStmt.bind([node.id]);
|
|
8330
|
+
while (edgeStmt.step()) {
|
|
8331
|
+
const row = edgeStmt.getAsObject();
|
|
8332
|
+
const edgeName = row.name || "";
|
|
8333
|
+
const edgeKey = "edge:" + edgeName;
|
|
8334
|
+
if (!seenNodes.has(edgeKey)) {
|
|
8335
|
+
seenNodes.add(edgeKey);
|
|
8336
|
+
items.push({
|
|
8337
|
+
type: "graph",
|
|
8338
|
+
label: edgeName,
|
|
8339
|
+
detail: row.type + " (weight: " + row.weight + ")",
|
|
8340
|
+
priority: calculatePriority("graph", edgeName, terms, null) - 10
|
|
8341
|
+
});
|
|
8342
|
+
}
|
|
8343
|
+
}
|
|
8344
|
+
edgeStmt.free();
|
|
8345
|
+
} catch {
|
|
8346
|
+
}
|
|
8006
8347
|
}
|
|
8007
|
-
edgeStmt.free();
|
|
8008
8348
|
}
|
|
8009
8349
|
} catch {
|
|
8010
8350
|
}
|
|
8011
8351
|
const modifiedFiles = sessionMemory.getModifiedFiles();
|
|
8012
8352
|
for (const mf of modifiedFiles) {
|
|
8013
8353
|
if (terms.some((t) => mf.filePath.toLowerCase().includes(t))) {
|
|
8354
|
+
const recency = getFileRecencySeconds(mf.filePath);
|
|
8355
|
+
const priority = calculatePriority("file", mf.filePath, terms, recency);
|
|
8014
8356
|
items.push({
|
|
8015
8357
|
type: "file",
|
|
8016
8358
|
label: mf.filePath,
|
|
8017
|
-
detail:
|
|
8018
|
-
priority
|
|
8359
|
+
detail: "Modified (" + mf.status + ")",
|
|
8360
|
+
priority
|
|
8019
8361
|
});
|
|
8020
8362
|
}
|
|
8021
8363
|
}
|
|
@@ -8023,11 +8365,12 @@ async function buildContextForGoal(goal) {
|
|
|
8023
8365
|
for (const ff of failedFiles) {
|
|
8024
8366
|
for (const f of ff.failures) {
|
|
8025
8367
|
if (!f.resolved && terms.some((t) => f.error.toLowerCase().includes(t))) {
|
|
8368
|
+
const priority = calculatePriority("failure", ff.task, terms, null);
|
|
8026
8369
|
items.push({
|
|
8027
8370
|
type: "failure",
|
|
8028
8371
|
label: ff.task,
|
|
8029
8372
|
detail: f.error.substring(0, 120),
|
|
8030
|
-
priority
|
|
8373
|
+
priority
|
|
8031
8374
|
});
|
|
8032
8375
|
break;
|
|
8033
8376
|
}
|
|
@@ -8035,16 +8378,17 @@ async function buildContextForGoal(goal) {
|
|
|
8035
8378
|
}
|
|
8036
8379
|
const memories = scoreMemoryRelevance(goal, 3);
|
|
8037
8380
|
for (const m of memories) {
|
|
8381
|
+
const priority = calculatePriority("memory", m.topic, terms, null);
|
|
8038
8382
|
items.push({
|
|
8039
8383
|
type: "memory",
|
|
8040
8384
|
label: m.topic,
|
|
8041
8385
|
detail: m.content.substring(0, 100),
|
|
8042
|
-
priority
|
|
8386
|
+
priority
|
|
8043
8387
|
});
|
|
8044
8388
|
}
|
|
8045
8389
|
const seen = /* @__PURE__ */ new Set();
|
|
8046
8390
|
const unique = items.filter((i) => {
|
|
8047
|
-
const key =
|
|
8391
|
+
const key = i.type + ":" + i.label;
|
|
8048
8392
|
if (seen.has(key)) return false;
|
|
8049
8393
|
seen.add(key);
|
|
8050
8394
|
return true;
|
|
@@ -8054,18 +8398,18 @@ async function buildContextForGoal(goal) {
|
|
|
8054
8398
|
const fileCount = unique.filter((i) => i.type === "file").length;
|
|
8055
8399
|
const failureCount = unique.filter((i) => i.type === "failure").length;
|
|
8056
8400
|
const memoryCount = unique.filter((i) => i.type === "memory").length;
|
|
8057
|
-
const summary =
|
|
8401
|
+
const summary = '\u{1F4CB} Context for "' + goal.substring(0, 40) + '": ' + unique.length + " items (" + graphCount + " graph, " + fileCount + " files, " + failureCount + " failures, " + memoryCount + " memories)";
|
|
8058
8402
|
return { context: unique.slice(0, 15), summary };
|
|
8059
8403
|
}
|
|
8060
8404
|
function formatContextItems(items, summary) {
|
|
8061
8405
|
if (items.length === 0) return "";
|
|
8062
8406
|
const lines = [
|
|
8063
8407
|
summary,
|
|
8064
|
-
"\u2501
|
|
8408
|
+
"\u2501".repeat(25)
|
|
8065
8409
|
];
|
|
8066
8410
|
for (const item of items) {
|
|
8067
8411
|
const icon = item.type === "graph" ? "\u{1F517}" : item.type === "file" ? "\u{1F4C4}" : item.type === "failure" ? "\u274C" : item.type === "memory" ? "\u{1F9E0}" : "\u{1F4CC}";
|
|
8068
|
-
lines.push(
|
|
8412
|
+
lines.push(" " + icon + " **" + item.label + "** \u2014 " + item.detail);
|
|
8069
8413
|
}
|
|
8070
8414
|
return lines.join("\n");
|
|
8071
8415
|
}
|
|
@@ -8832,7 +9176,7 @@ function countFiles(dir) {
|
|
|
8832
9176
|
async function investigate(problem) {
|
|
8833
9177
|
try {
|
|
8834
9178
|
const db = await getDb();
|
|
8835
|
-
const terms =
|
|
9179
|
+
const terms = extractTerms2(problem);
|
|
8836
9180
|
const paths = [];
|
|
8837
9181
|
const seen = /* @__PURE__ */ new Set();
|
|
8838
9182
|
let step = 0;
|
|
@@ -8898,7 +9242,7 @@ async function investigate(problem) {
|
|
|
8898
9242
|
return `Error investigating: ${err}`;
|
|
8899
9243
|
}
|
|
8900
9244
|
}
|
|
8901
|
-
function
|
|
9245
|
+
function extractTerms2(problem) {
|
|
8902
9246
|
return problem.toLowerCase().replace(/[^a-z0-9\s]/g, "").split(/\s+/).filter((w) => w.length > 2 && !["the", "and", "for", "are", "but", "not", "you", "all", "can", "had", "her", "was", "one", "our", "out", "has", "have", "been", "some", "them", "then", "their", "this", "that", "with", "from", "they", "will", "would", "could", "should", "about", "into", "over", "after", "also", "does", "each", "made", "just", "more", "most", "much", "must", "only", "other", "such", "than", "very", "when", "where", "which", "while", "your", "fix", "bug", "slow", "error", "issue", "problem"].includes(w)).slice(0, 8);
|
|
8903
9247
|
}
|
|
8904
9248
|
function findBottlenecks(paths) {
|
|
@@ -10717,7 +11061,7 @@ function formatCollectivePatterns(patterns) {
|
|
|
10717
11061
|
}
|
|
10718
11062
|
|
|
10719
11063
|
// src/engine/kumaMarketplace.ts
|
|
10720
|
-
import { execSync as
|
|
11064
|
+
import { execSync as execSync9 } from "child_process";
|
|
10721
11065
|
import fs27 from "fs";
|
|
10722
11066
|
import path28 from "path";
|
|
10723
11067
|
var BUILT_IN_TEMPLATES = [
|
|
@@ -11103,7 +11447,7 @@ async function tryInstallFromNpm(templateId) {
|
|
|
11103
11447
|
try {
|
|
11104
11448
|
const npmPackage = `@kuma-templates/${name}`;
|
|
11105
11449
|
const root = getProjectRoot();
|
|
11106
|
-
|
|
11450
|
+
execSync9(`npm install --no-save ${npmPackage}`, {
|
|
11107
11451
|
cwd: root,
|
|
11108
11452
|
encoding: "utf-8",
|
|
11109
11453
|
timeout: 3e4,
|
|
@@ -11761,7 +12105,113 @@ async function handleAdvanced(action, params) {
|
|
|
11761
12105
|
}
|
|
11762
12106
|
}
|
|
11763
12107
|
|
|
12108
|
+
// src/utils/kumaOutput.ts
|
|
12109
|
+
import crypto3 from "crypto";
|
|
12110
|
+
var dedupCache = /* @__PURE__ */ new Map();
|
|
12111
|
+
var DEDUP_TTL_MS = 6e4;
|
|
12112
|
+
function getCachedOutput(key) {
|
|
12113
|
+
const entry = dedupCache.get(key);
|
|
12114
|
+
if (entry && Date.now() - entry.timestamp < DEDUP_TTL_MS) {
|
|
12115
|
+
return entry.output;
|
|
12116
|
+
}
|
|
12117
|
+
return null;
|
|
12118
|
+
}
|
|
12119
|
+
function setCachedOutput(key, output) {
|
|
12120
|
+
dedupCache.set(key, { output, timestamp: Date.now() });
|
|
12121
|
+
if (dedupCache.size > 50) {
|
|
12122
|
+
const now = Date.now();
|
|
12123
|
+
for (const [k, v] of dedupCache) {
|
|
12124
|
+
if (now - v.timestamp > DEDUP_TTL_MS) dedupCache.delete(k);
|
|
12125
|
+
}
|
|
12126
|
+
}
|
|
12127
|
+
}
|
|
12128
|
+
function buildCacheKey(toolName, params) {
|
|
12129
|
+
const stable = {};
|
|
12130
|
+
for (const key of Object.keys(params).sort()) {
|
|
12131
|
+
const val = params[key];
|
|
12132
|
+
if (typeof val === "string") stable[key] = val.trim().substring(0, 200);
|
|
12133
|
+
else if (typeof val === "number") stable[key] = val;
|
|
12134
|
+
else if (typeof val === "boolean") stable[key] = val;
|
|
12135
|
+
else if (Array.isArray(val)) stable[key] = val.length;
|
|
12136
|
+
else if (val === null || val === void 0) stable[key] = null;
|
|
12137
|
+
else stable[key] = JSON.stringify(val).substring(0, 200);
|
|
12138
|
+
}
|
|
12139
|
+
const str = JSON.stringify(stable);
|
|
12140
|
+
return toolName + ":" + crypto3.createHash("md5").update(str).digest("hex").substring(0, 12);
|
|
12141
|
+
}
|
|
12142
|
+
var EMOJI_PATTERN = /[\u{1F000}-\u{1FFFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{2300}-\u{23FF}]/gu;
|
|
12143
|
+
var BOLD_PATTERN = /\*\*/g;
|
|
12144
|
+
var DECORATIVE_LINE = /[━┉═]{5,}/g;
|
|
12145
|
+
var MULTI_NEWLINE = /\n{3,}/g;
|
|
12146
|
+
function stripFormatting(text) {
|
|
12147
|
+
return text.replace(EMOJI_PATTERN, "").replace(BOLD_PATTERN, "").replace(DECORATIVE_LINE, "").replace(MULTI_NEWLINE, "\n\n").split("\n").map((l) => l.trim()).join("\n").trim();
|
|
12148
|
+
}
|
|
12149
|
+
function adaptiveCompress(text, tokenBudget) {
|
|
12150
|
+
const lines = text.split("\n");
|
|
12151
|
+
const estimatedTokens = estimateTokens(text);
|
|
12152
|
+
if (!tokenBudget || estimatedTokens <= tokenBudget) return text;
|
|
12153
|
+
const stripped = stripFormatting(text);
|
|
12154
|
+
const strippedTokens = estimateTokens(stripped);
|
|
12155
|
+
if (strippedTokens <= tokenBudget) return stripped;
|
|
12156
|
+
if (lines.length < 50) {
|
|
12157
|
+
const maxChars = tokenBudget * 3;
|
|
12158
|
+
return stripped.slice(0, maxChars) + `
|
|
12159
|
+
|
|
12160
|
+
[...truncated: ~${estimatedTokens}tokens > ${tokenBudget}tokens]`;
|
|
12161
|
+
}
|
|
12162
|
+
if (lines.length < 200) {
|
|
12163
|
+
const head = lines.slice(0, 30).join("\n");
|
|
12164
|
+
const tail = lines.slice(-10).join("\n");
|
|
12165
|
+
return `${stripFormatting(head)}
|
|
12166
|
+
|
|
12167
|
+
[...${lines.length - 40} lines hidden - ${estimatedTokens}tokens > ${tokenBudget}tokens]
|
|
12168
|
+
|
|
12169
|
+
${stripFormatting(tail)}`;
|
|
12170
|
+
}
|
|
12171
|
+
const summaryLines = lines.filter((l) => {
|
|
12172
|
+
const t = l.trim();
|
|
12173
|
+
return t.length > 10 && !t.startsWith(" ") && !t.startsWith(".") && !/^[━┉═\s]+$/.test(t);
|
|
12174
|
+
});
|
|
12175
|
+
const compressed = stripFormatting(summaryLines.slice(0, 20).join("\n"));
|
|
12176
|
+
return `${compressed}
|
|
12177
|
+
|
|
12178
|
+
[...${lines.length} lines compressed to ${summaryLines.length} key lines - ~${estimatedTokens}tokens > ${tokenBudget}tokens]`;
|
|
12179
|
+
}
|
|
12180
|
+
function formatOutput2(text, options = {}) {
|
|
12181
|
+
const { compact, responseBudget } = options;
|
|
12182
|
+
let result = text;
|
|
12183
|
+
if (options.cacheKey) {
|
|
12184
|
+
const cached = getCachedOutput(options.cacheKey);
|
|
12185
|
+
if (cached !== null) {
|
|
12186
|
+
return cached;
|
|
12187
|
+
}
|
|
12188
|
+
}
|
|
12189
|
+
if (compact) {
|
|
12190
|
+
result = stripFormatting(result);
|
|
12191
|
+
}
|
|
12192
|
+
if (responseBudget && responseBudget > 0) {
|
|
12193
|
+
const tokens = estimateTokens(result);
|
|
12194
|
+
if (tokens > responseBudget) {
|
|
12195
|
+
result = adaptiveCompress(result, responseBudget);
|
|
12196
|
+
}
|
|
12197
|
+
}
|
|
12198
|
+
if (options.cacheKey) {
|
|
12199
|
+
setCachedOutput(options.cacheKey, result);
|
|
12200
|
+
}
|
|
12201
|
+
return result;
|
|
12202
|
+
}
|
|
12203
|
+
|
|
11764
12204
|
// src/manifest.ts
|
|
12205
|
+
function wrapOutput(text, toolName, params) {
|
|
12206
|
+
const compact = params.compact === true;
|
|
12207
|
+
const responseBudget = params.responseBudget;
|
|
12208
|
+
const cacheKey = buildCacheKey(toolName, params);
|
|
12209
|
+
return formatOutput2(text, { compact, responseBudget, cacheKey });
|
|
12210
|
+
}
|
|
12211
|
+
var compactSchema = {
|
|
12212
|
+
compact: z.boolean().optional().default(false).describe("Compact output mode (strips emojis/formatting, saves ~50% tokens)"),
|
|
12213
|
+
responseBudget: z.number().min(100).max(1e4).optional().describe("Max tokens for response (auto-compresses if exceeded)")
|
|
12214
|
+
};
|
|
11765
12215
|
function registerAllTools(server) {
|
|
11766
12216
|
server.tool(
|
|
11767
12217
|
"kuma_init",
|
|
@@ -11770,12 +12220,13 @@ function registerAllTools(server) {
|
|
|
11770
12220
|
action: z.enum(["init", "conventions", "structure"]).default("init").describe("Action: init=load all context, conventions=detect stack, structure=show tree"),
|
|
11771
12221
|
projectRoot: z.string().optional().describe("Project root path (auto-detected)"),
|
|
11772
12222
|
forceRescan: z.boolean().optional().default(false).describe("Force rescan for conventions"),
|
|
11773
|
-
depth: z.number().min(1).max(6).optional().default(3).describe("Tree depth for structure")
|
|
12223
|
+
depth: z.number().min(1).max(6).optional().default(3).describe("Tree depth for structure"),
|
|
12224
|
+
...compactSchema
|
|
11774
12225
|
},
|
|
11775
12226
|
async (params) => {
|
|
11776
12227
|
try {
|
|
11777
12228
|
const text = await handleInit(params.action || "init", params);
|
|
11778
|
-
return { content: [{ type: "text", text }] };
|
|
12229
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_init", params) }] };
|
|
11779
12230
|
} catch (err) {
|
|
11780
12231
|
return { content: [{ type: "text", text: `Error in kuma_init: ${err}` }], isError: true };
|
|
11781
12232
|
}
|
|
@@ -11820,17 +12271,18 @@ function registerAllTools(server) {
|
|
|
11820
12271
|
line: z.number().min(0).optional().describe("Line number (0-indexed) for LSP"),
|
|
11821
12272
|
character: z.number().min(0).optional().describe("Character position (0-indexed) for LSP"),
|
|
11822
12273
|
lspAction: z.enum(["def", "refs", "type", "rename"]).optional().describe("LSP sub-action"),
|
|
11823
|
-
newName: z.string().optional().describe("New name for rename action")
|
|
12274
|
+
newName: z.string().optional().describe("New name for rename action"),
|
|
12275
|
+
...compactSchema
|
|
11824
12276
|
},
|
|
11825
12277
|
async (params) => {
|
|
11826
12278
|
try {
|
|
11827
12279
|
const action = params.action || "grep";
|
|
11828
12280
|
if (action === "edit") {
|
|
11829
12281
|
const text2 = await safeEditHandler(params);
|
|
11830
|
-
return { content: [{ type: "text", text: text2 }] };
|
|
12282
|
+
return { content: [{ type: "text", text: wrapOutput(text2, "kuma_core", params) }] };
|
|
11831
12283
|
}
|
|
11832
12284
|
const text = await handleCore(action, params);
|
|
11833
|
-
return { content: [{ type: "text", text }] };
|
|
12285
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_core", params) }] };
|
|
11834
12286
|
} catch (err) {
|
|
11835
12287
|
return { content: [{ type: "text", text: `Error in kuma_core: ${err}` }], isError: true };
|
|
11836
12288
|
}
|
|
@@ -11854,12 +12306,13 @@ function registerAllTools(server) {
|
|
|
11854
12306
|
format: z.enum(["text", "json"]).optional().default("text").describe("Output format"),
|
|
11855
12307
|
// lint params
|
|
11856
12308
|
tool: z.enum(["eslint", "tsc", "prettier", "ruff", "all"]).optional().default("all").describe("Lint tool"),
|
|
11857
|
-
autoFix: z.boolean().optional().default(false).describe("Auto-fix issues")
|
|
12309
|
+
autoFix: z.boolean().optional().default(false).describe("Auto-fix issues"),
|
|
12310
|
+
...compactSchema
|
|
11858
12311
|
},
|
|
11859
12312
|
async (params) => {
|
|
11860
12313
|
try {
|
|
11861
12314
|
const text = await handleVerify(params.action || "test", params);
|
|
11862
|
-
return { content: [{ type: "text", text }] };
|
|
12315
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_verify", params) }] };
|
|
11863
12316
|
} catch (err) {
|
|
11864
12317
|
return { content: [{ type: "text", text: `Error in kuma_verify: ${err}` }], isError: true };
|
|
11865
12318
|
}
|
|
@@ -11880,7 +12333,8 @@ function registerAllTools(server) {
|
|
|
11880
12333
|
check: z.enum(["all", "anti-pattern", "loop", "drift", "context"]).optional().default("all").describe("Guard check type"),
|
|
11881
12334
|
packageName: z.string().optional().describe("Package name for dependency guard"),
|
|
11882
12335
|
packageVersion: z.string().optional().describe("Package version for dependency guard"),
|
|
11883
|
-
actionCheck: z.string().optional().describe("Check sub-action (e.g. 'edit')")
|
|
12336
|
+
actionCheck: z.string().optional().describe("Check sub-action (e.g. 'edit')"),
|
|
12337
|
+
...compactSchema
|
|
11884
12338
|
},
|
|
11885
12339
|
async (params) => {
|
|
11886
12340
|
try {
|
|
@@ -11890,7 +12344,7 @@ function registerAllTools(server) {
|
|
|
11890
12344
|
actionCheck: params.actionCheck || params.action,
|
|
11891
12345
|
contextAction: params.contextAction || (action === "context" ? "save" : void 0)
|
|
11892
12346
|
});
|
|
11893
|
-
return { content: [{ type: "text", text }] };
|
|
12347
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_safety", params) }] };
|
|
11894
12348
|
} catch (err) {
|
|
11895
12349
|
return { content: [{ type: "text", text: `Error in kuma_safety: ${err}` }], isError: true };
|
|
11896
12350
|
}
|
|
@@ -11912,12 +12366,13 @@ function registerAllTools(server) {
|
|
|
11912
12366
|
experienceAction: z.enum(["suggest", "errors", "prune"]).optional().describe("Experience sub-action"),
|
|
11913
12367
|
toolName: z.string().optional().describe("Tool name for experience errors"),
|
|
11914
12368
|
intentAction: z.enum(["suggest"]).optional().describe("Intent sub-action"),
|
|
11915
|
-
intent: z.string().optional().describe("Intent description")
|
|
12369
|
+
intent: z.string().optional().describe("Intent description"),
|
|
12370
|
+
...compactSchema
|
|
11916
12371
|
},
|
|
11917
12372
|
async (params) => {
|
|
11918
12373
|
try {
|
|
11919
12374
|
const text = await handleGraph(params.action || "query", params);
|
|
11920
|
-
return { content: [{ type: "text", text }] };
|
|
12375
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_graph", params) }] };
|
|
11921
12376
|
} catch (err) {
|
|
11922
12377
|
return { content: [{ type: "text", text: `Error in kuma_graph: ${err}` }], isError: true };
|
|
11923
12378
|
}
|
|
@@ -11938,12 +12393,13 @@ function registerAllTools(server) {
|
|
|
11938
12393
|
title: z.string().optional().describe("Decision title for record"),
|
|
11939
12394
|
rationale: z.string().optional().describe("Decision rationale for record"),
|
|
11940
12395
|
outcome: z.string().optional().describe("Decision outcome for record"),
|
|
11941
|
-
healAction: z.enum(["check", "heal"]).optional().default("heal").describe("Heal sub-action")
|
|
12396
|
+
healAction: z.enum(["check", "heal"]).optional().default("heal").describe("Heal sub-action"),
|
|
12397
|
+
...compactSchema
|
|
11942
12398
|
},
|
|
11943
12399
|
async (params) => {
|
|
11944
12400
|
try {
|
|
11945
12401
|
const text = await handleMemory(params.action || "get", params);
|
|
11946
|
-
return { content: [{ type: "text", text }] };
|
|
12402
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_memory", params) }] };
|
|
11947
12403
|
} catch (err) {
|
|
11948
12404
|
return { content: [{ type: "text", text: `Error in kuma_memory: ${err}` }], isError: true };
|
|
11949
12405
|
}
|
|
@@ -11957,12 +12413,13 @@ function registerAllTools(server) {
|
|
|
11957
12413
|
goal: z.string().optional().describe("Goal for reflect"),
|
|
11958
12414
|
context: z.string().optional().describe("Context for predict"),
|
|
11959
12415
|
target: z.string().optional().describe("Target for confidence"),
|
|
11960
|
-
sessionStats: z.boolean().optional().default(false).describe("Include session stats in heatmap")
|
|
12416
|
+
sessionStats: z.boolean().optional().default(false).describe("Include session stats in heatmap"),
|
|
12417
|
+
...compactSchema
|
|
11961
12418
|
},
|
|
11962
12419
|
async (params) => {
|
|
11963
12420
|
try {
|
|
11964
12421
|
const text = await handleAnalytics(params.action || "reflect", params);
|
|
11965
|
-
return { content: [{ type: "text", text }] };
|
|
12422
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_analytics", params) }] };
|
|
11966
12423
|
} catch (err) {
|
|
11967
12424
|
return { content: [{ type: "text", text: `Error in kuma_analytics: ${err}` }], isError: true };
|
|
11968
12425
|
}
|
|
@@ -11981,12 +12438,13 @@ function registerAllTools(server) {
|
|
|
11981
12438
|
staged: z.boolean().optional().default(false).describe("Show staged changes for diff"),
|
|
11982
12439
|
contextLines: z.number().min(1).max(20).optional().default(3).describe("Context lines for diff"),
|
|
11983
12440
|
baseRef: z.string().optional().describe("Base git ref for diff"),
|
|
11984
|
-
targetRef: z.string().optional().describe("Target git ref for diff")
|
|
12441
|
+
targetRef: z.string().optional().describe("Target git ref for diff"),
|
|
12442
|
+
...compactSchema
|
|
11985
12443
|
},
|
|
11986
12444
|
async (params) => {
|
|
11987
12445
|
try {
|
|
11988
12446
|
const text = await handleHistory(params.action || "log", params);
|
|
11989
|
-
return { content: [{ type: "text", text }] };
|
|
12447
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_history", params) }] };
|
|
11990
12448
|
} catch (err) {
|
|
11991
12449
|
return { content: [{ type: "text", text: `Error in kuma_history: ${err}` }], isError: true };
|
|
11992
12450
|
}
|
|
@@ -11998,12 +12456,13 @@ function registerAllTools(server) {
|
|
|
11998
12456
|
{
|
|
11999
12457
|
action: z.enum(["acquire", "release", "list", "clean"]).describe("Lock action"),
|
|
12000
12458
|
filePath: z.string().optional().describe("File path for acquire/release"),
|
|
12001
|
-
agentId: z.string().optional().describe("Agent identifier for lock")
|
|
12459
|
+
agentId: z.string().optional().describe("Agent identifier for lock"),
|
|
12460
|
+
...compactSchema
|
|
12002
12461
|
},
|
|
12003
12462
|
async (params) => {
|
|
12004
12463
|
try {
|
|
12005
12464
|
const text = await handleLock(params.action || "list", params);
|
|
12006
|
-
return { content: [{ type: "text", text }] };
|
|
12465
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_lock", params) }] };
|
|
12007
12466
|
} catch (err) {
|
|
12008
12467
|
return { content: [{ type: "text", text: `Error in kuma_lock: ${err}` }], isError: true };
|
|
12009
12468
|
}
|
|
@@ -12030,12 +12489,13 @@ function registerAllTools(server) {
|
|
|
12030
12489
|
marketplaceAction: z.enum(["list", "install"]).optional().describe("Marketplace sub-action"),
|
|
12031
12490
|
template: z.string().optional().describe("Template ID for marketplace install"),
|
|
12032
12491
|
// query params
|
|
12033
|
-
query: z.string().optional().describe("Query for failure query")
|
|
12492
|
+
query: z.string().optional().describe("Query for failure query"),
|
|
12493
|
+
...compactSchema
|
|
12034
12494
|
},
|
|
12035
12495
|
async (params) => {
|
|
12036
12496
|
try {
|
|
12037
12497
|
const text = await handleAdvanced(params.action || "marketplace", params);
|
|
12038
|
-
return { content: [{ type: "text", text }] };
|
|
12498
|
+
return { content: [{ type: "text", text: wrapOutput(text, "kuma_advanced", params) }] };
|
|
12039
12499
|
} catch (err) {
|
|
12040
12500
|
return { content: [{ type: "text", text: `Error in kuma_advanced: ${err}` }], isError: true };
|
|
12041
12501
|
}
|