@plumpslabs/kuma 2.3.8 → 2.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/{agentDetector-G4RBMZ6X.js → agentDetector-3OTNKKBS.js} +4 -4
  2. package/dist/{chunk-NAM7SCBT.js → chunk-3TX6Q37T.js} +26 -1
  3. package/dist/{chunk-L5WU2HTN.js → chunk-J2CBDLXB.js} +46 -5
  4. package/dist/{chunk-RTGLQDMI.js → chunk-OJALFQ4H.js} +2 -2
  5. package/dist/{chunk-53J56QCQ.js → chunk-Q2444HWO.js} +1 -1
  6. package/dist/{chunk-SLRRDKQ2.js → chunk-R6B3VUSB.js} +2 -2
  7. package/dist/{chunk-PTEPJK6M.js → chunk-RI3DKY62.js} +1 -1
  8. package/dist/{chunk-FL2TLLMX.js → chunk-SPHI2BOO.js} +1 -1
  9. package/dist/{chunk-4OB3XMHT.js → chunk-ZKDYTYMS.js} +108 -2
  10. package/dist/{contextDigest-4PCK3DSM.js → contextDigest-5JXLH56Z.js} +3 -3
  11. package/dist/{domainRules-LDZPOIGZ.js → domainRules-ED6EOFVY.js} +2 -2
  12. package/dist/index.js +259 -71
  13. package/dist/{init-AJAESUZZ.js → init-LLP6JDFR.js} +1 -1
  14. package/dist/kumaCheckpoint-XIQWRMGV.js +207 -0
  15. package/dist/kumaCodeScanner-LFJGPJNH.js +566 -0
  16. package/dist/kumaContractEngine-KX27T4N7.js +305 -0
  17. package/dist/{kumaDb-6D53ERFP.js → kumaDb-IC7UX7PU.js} +3 -1
  18. package/dist/{kumaDriftDetector-OESI5GTC.js → kumaDriftDetector-QBY6OJOO.js} +1 -1
  19. package/dist/{kumaGotchas-DU5H6N7X.js → kumaGotchas-5HODT5RI.js} +3 -3
  20. package/dist/{kumaGraph-AWP743TJ.js → kumaGraph-GUQM75WL.js} +8 -2
  21. package/dist/{kumaMemory-7TCUDVZX.js → kumaMemory-FMOWIODH.js} +2 -2
  22. package/dist/{kumaMiner-FFXSRHAO.js → kumaMiner-3RXEOCBP.js} +3 -3
  23. package/dist/{kumaPolicyEngine-S2PXN3C7.js → kumaPolicyEngine-ORBWL5PT.js} +2 -2
  24. package/dist/kumaProgressiveContext-CVSNPY3W.js +231 -0
  25. package/dist/{kumaSearch-QGB4QVXS.js → kumaSearch-B5WVYHHD.js} +1 -1
  26. package/dist/kumaTrajectory-T6DXGOG4.js +460 -0
  27. package/dist/{kumaVerifier-ARSGPZAM.js → kumaVerifier-KAYJHR5K.js} +2 -2
  28. package/dist/{kumaVisualize-TECABHUY.js → kumaVisualize-AFL7STLL.js} +1 -1
  29. package/dist/{safetyAudit-55IVCG5B.js → safetyAudit-32WSA4Z5.js} +2 -2
  30. package/dist/{safetyScore-GR5N55CU.js → safetyScore-WU27EOG4.js} +5 -5
  31. package/dist/{sessionMemory-CA34TCPF.js → sessionMemory-4UWA3E5J.js} +1 -1
  32. package/dist/{skillGenerator-F6YO4H5D.js → skillGenerator-ILZFWO5O.js} +6 -8
  33. package/package.json +18 -13
  34. package/packages/ide/studio/dist/index.js +140 -0
  35. package/packages/ide/studio/public/index.html +500 -0
@@ -36,10 +36,10 @@ var AGENT_DETECTORS = [
36
36
  },
37
37
  {
38
38
  type: "windsurf",
39
- checkFiles: [".windsurfrules"],
40
- checkDirs: [],
39
+ checkFiles: [],
40
+ checkDirs: [".windsurf"],
41
41
  priority: 70,
42
- label: "Windsurf (.windsurfrules)"
42
+ label: "Windsurf (.windsurf/)"
43
43
  },
44
44
  {
45
45
  type: "opencode",
@@ -156,7 +156,7 @@ function getSkillPath(type) {
156
156
  case "aider":
157
157
  return "CONVENTIONS.md";
158
158
  case "windsurf":
159
- return ".windsurfrules";
159
+ return ".windsurf/rules/kuma.md";
160
160
  case "copilot":
161
161
  return ".github/skills/kuma/SKILL.md";
162
162
  case "qwen":
@@ -9,6 +9,10 @@ import path from "path";
9
9
  var DB_FILENAME = "kuma.db";
10
10
  var dbInstance = null;
11
11
  var initPromise = null;
12
+ function resetDbInstance() {
13
+ dbInstance = null;
14
+ initPromise = null;
15
+ }
12
16
  async function getDb() {
13
17
  if (dbInstance) return dbInstance;
14
18
  if (initPromise) return initPromise;
@@ -74,12 +78,32 @@ function createSchema(db) {
74
78
  id INTEGER PRIMARY KEY AUTOINCREMENT,
75
79
  source_id TEXT NOT NULL REFERENCES nodes(id),
76
80
  target_id TEXT NOT NULL REFERENCES nodes(id),
77
- type TEXT NOT NULL CHECK(type IN ('calls','imports','defines','tests','routes','implements','extends','depends_on','owns','modified_by')),
81
+ type TEXT NOT NULL CHECK(type IN ('calls','imports','defines','tests','routes','implements','extends','depends_on','owns','modified_by','contains','composes')),
78
82
  weight REAL DEFAULT 1.0,
79
83
  metadata TEXT DEFAULT '{}',
80
84
  created_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),
81
85
  UNIQUE(source_id, target_id, type)
82
86
  )`);
87
+ try {
88
+ const schema = db.exec(`SELECT sql FROM sqlite_master WHERE type='table' AND name='edges'`);
89
+ const edgeSql = schema[0]?.values?.[0]?.[0] || "";
90
+ if (edgeSql.includes("contains") === false || edgeSql.includes("composes") === false) {
91
+ db.run(`ALTER TABLE edges RENAME TO edges_old`);
92
+ db.run(`CREATE TABLE IF NOT EXISTS edges (
93
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
94
+ source_id TEXT NOT NULL REFERENCES nodes(id),
95
+ target_id TEXT NOT NULL REFERENCES nodes(id),
96
+ type TEXT NOT NULL CHECK(type IN ('calls','imports','defines','tests','routes','implements','extends','depends_on','owns','modified_by','contains','composes')),
97
+ weight REAL DEFAULT 1.0,
98
+ metadata TEXT DEFAULT '{}',
99
+ created_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),
100
+ UNIQUE(source_id, target_id, type)
101
+ )`);
102
+ db.run(`INSERT OR IGNORE INTO edges SELECT * FROM edges_old`);
103
+ db.run(`DROP TABLE edges_old`);
104
+ }
105
+ } catch {
106
+ }
83
107
  db.run(`CREATE TABLE IF NOT EXISTS sessions (
84
108
  id INTEGER PRIMARY KEY AUTOINCREMENT,
85
109
  started_at INTEGER NOT NULL,
@@ -998,6 +1022,7 @@ async function getLatestVerifications(limit = 10) {
998
1022
  }
999
1023
 
1000
1024
  export {
1025
+ resetDbInstance,
1001
1026
  getDb,
1002
1027
  saveDb,
1003
1028
  getResearchCache,
@@ -23,12 +23,12 @@ var ALL_CONFIG_TYPES = [
23
23
  var CONFIG_LABELS = {
24
24
  claude: "Claude Code (CLAUDE.md / plugin)",
25
25
  cursor: "Cursor (.cursor/rules/*.mdc)",
26
- windsurf: "Windsurf (.windsurfrules)",
26
+ windsurf: "Windsurf (.windsurf/rules/)",
27
27
  copilot: "GitHub Copilot Editor (AGENTS.md + Skill)",
28
28
  cline: "Cline (.clinerules/*.md)",
29
29
  aider: "Aider (CONVENTIONS.md via .aider.conf.yml)",
30
30
  antigravity: "Antigravity CLI (.agents/skills/)",
31
- opencode: "OpenCode (opencode.json)",
31
+ opencode: "OpenCode (opencode.json + skills)",
32
32
  codex: "Codex CLI (AGENTS.md + .codex/config.toml)",
33
33
  qwen: "Qwen Code (AGENTS.md + settings.json)",
34
34
  kiro: "Kiro (.kiro/steering/*.md)",
@@ -42,7 +42,7 @@ function configFilePath(type) {
42
42
  case "cursor":
43
43
  return ".cursor/rules/kuma.mdc";
44
44
  case "windsurf":
45
- return ".windsurfrules";
45
+ return ".windsurf/rules/kuma.md";
46
46
  case "copilot":
47
47
  return "AGENTS.md";
48
48
  case "cline":
@@ -97,7 +97,12 @@ function windsurfRulesTemplate() {
97
97
  return [
98
98
  "# Kuma MCP \u2014 Windsurf",
99
99
  "",
100
- KUMA_CORE_INSTRUCTIONS
100
+ "Windsurf Cascade agent: Kuma MCP tools are installed.",
101
+ "All behavioral rules are in `.kuma/init.md`.",
102
+ "**Before coding, load project context via `kuma_init()`.**",
103
+ "Project knowledge persists in `.kuma/memories/*.md` across sessions.",
104
+ "",
105
+ "Also auto-detected as SKILL.md in `.windsurf/skills/` and `.agents/skills/`."
101
106
  ].join("\n");
102
107
  }
103
108
  function copilotTemplate() {
@@ -337,7 +342,43 @@ var TEMPLATES = {
337
342
  codewhale: codewhaleTemplate
338
343
  };
339
344
  var APPEND_SEPARATOR = "\n\n---\n_Generated by Kuma MCP - https://github.com/plumpslabs/kuma_\n\n";
340
- function handleOpencodeSecondary(_root, _results) {
345
+ function handleOpencodeSecondary(root, results) {
346
+ const skillPath = path.resolve(root, ".agents", "skills", "kuma", "SKILL.md");
347
+ if (results.some((r) => r.filePath === ".agents/skills/kuma/SKILL.md")) return;
348
+ try {
349
+ const dir = path.dirname(skillPath);
350
+ const content = [
351
+ "---",
352
+ "name: kuma-mcp",
353
+ "description: Kuma MCP \u2014 safety toolkit for AI coding agents. Research, memory, and safety guard.",
354
+ "---",
355
+ "",
356
+ "Kuma MCP tools are installed. All behavioral rules are in `.kuma/init.md`.",
357
+ "**Before coding, call `kuma_init()` to load project context and session memory.**",
358
+ "Project knowledge persists in `.kuma/memories/*.md` across sessions.",
359
+ "",
360
+ "MCP server configured in `opencode.json`."
361
+ ].join("\n");
362
+ if (fs.existsSync(skillPath)) {
363
+ const existing = fs.readFileSync(skillPath, "utf-8");
364
+ if (existing.includes("kuma-mcp")) {
365
+ results.push({ type: "opencode", filePath: ".agents/skills/kuma/SKILL.md", action: "skipped" });
366
+ return;
367
+ }
368
+ results.push({ type: "opencode", filePath: ".agents/skills/kuma/SKILL.md", action: "skipped" });
369
+ } else {
370
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
371
+ fs.writeFileSync(skillPath, content, "utf-8");
372
+ results.push({ type: "opencode", filePath: ".agents/skills/kuma/SKILL.md", action: "created" });
373
+ }
374
+ } catch (err) {
375
+ results.push({
376
+ type: "opencode",
377
+ filePath: ".agents/skills/kuma/SKILL.md",
378
+ action: "error",
379
+ error: err instanceof Error ? err.message : String(err)
380
+ });
381
+ }
341
382
  }
342
383
  function handleCodexSecondary(root, results) {
343
384
  const tomlPath = path.resolve(root, ".codex/config.toml");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionMemory
3
- } from "./chunk-SLRRDKQ2.js";
3
+ } from "./chunk-R6B3VUSB.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-AWP743TJ.js");
85
+ const { upsertNode, addEdge } = await import("./kumaGraph-GUQM75WL.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,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionMemory
3
- } from "./chunk-SLRRDKQ2.js";
3
+ } from "./chunk-R6B3VUSB.js";
4
4
  import {
5
5
  getProjectRoot
6
6
  } from "./chunk-E2KFPEBT.js";
@@ -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-6D53ERFP.js");
323
+ const { getDb, saveDb } = await import("./kumaDb-IC7UX7PU.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, ?)`,
@@ -605,7 +605,7 @@ No unresolved issues.`;
605
605
  this.addModifiedFile(filePath);
606
606
  }
607
607
  try {
608
- const { recordChange } = await import("./kumaDb-6D53ERFP.js");
608
+ const { recordChange } = await import("./kumaDb-IC7UX7PU.js");
609
609
  const gitHash = this.getGitHead();
610
610
  await recordChange({ filePath, changeType, symbol, gitCommitHash: gitHash || void 0 });
611
611
  } catch {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getDb,
3
3
  saveDb
4
- } from "./chunk-NAM7SCBT.js";
4
+ } from "./chunk-3TX6Q37T.js";
5
5
 
6
6
  // src/engine/safetyAudit.ts
7
7
  var SCHEMA_SQL = `
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionMemory
3
- } from "./chunk-SLRRDKQ2.js";
3
+ } from "./chunk-R6B3VUSB.js";
4
4
  import {
5
5
  getProjectRoot
6
6
  } from "./chunk-E2KFPEBT.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getDb,
3
3
  saveDb
4
- } from "./chunk-NAM7SCBT.js";
4
+ } from "./chunk-3TX6Q37T.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-CA34TCPF.js");
461
+ const { sessionMemory } = await import("./sessionMemory-4UWA3E5J.js");
462
462
  const toolCalls = sessionMemory.getToolCallHistory(50);
463
463
  let edgeCount = 0;
464
464
  for (const call of toolCalls) {
@@ -630,6 +630,109 @@ async function codebaseSearchFallback(query, limit = 20) {
630
630
  }
631
631
  }
632
632
  }
633
+ async function resolveFederatedNode(uri) {
634
+ try {
635
+ if (!uri.startsWith("kuma://")) {
636
+ return `\u26A0\uFE0F Invalid URI scheme: "${uri.substring(0, 20)}...". Use kuma://project/node-id`;
637
+ }
638
+ const pathPart = uri.replace("kuma://", "");
639
+ const firstSlash = pathPart.indexOf("/");
640
+ if (firstSlash === -1) {
641
+ return `\u26A0\uFE0F Invalid federated URI: "${uri}". Format: kuma://<project>/<node-id>`;
642
+ }
643
+ const projectName = pathPart.substring(0, firstSlash);
644
+ const nodeRef = pathPart.substring(firstSlash + 1);
645
+ const db = await getDb();
646
+ const stmt = db.prepare(`
647
+ SELECT id, type, name, file_path, metadata FROM nodes
648
+ WHERE id = ? OR name LIKE ?
649
+ LIMIT 5
650
+ `);
651
+ stmt.bind([nodeRef, `%${nodeRef}%`]);
652
+ const results = [];
653
+ while (stmt.step()) results.push(stmt.getAsObject());
654
+ stmt.free();
655
+ if (results.length > 0) {
656
+ const lines = [
657
+ `\u{1F517} **Federated Node Resolved** (local)`,
658
+ `\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`,
659
+ `\u{1F4C1} Project: ${projectName}`,
660
+ `\u{1F517} URI: ${uri}`,
661
+ ""
662
+ ];
663
+ for (const r of results) {
664
+ lines.push(` \u2022 **${r.name}** (${r.type}) \u2014 ${r.file_path || "no path"}`);
665
+ }
666
+ lines.push("", "\u{1F4A1} Federated cross-repo resolution is active. Remote resolution via HTTP coming soon.");
667
+ return lines.join("\n");
668
+ }
669
+ const federatedNodes = await registerFederatedReference(uri, projectName, nodeRef);
670
+ return [
671
+ `\u{1F517} **Federated Reference**`,
672
+ `\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`,
673
+ `\u{1F4C1} Remote project: ${projectName}`,
674
+ `\u{1F517} URI: ${uri}`,
675
+ `\u{1F4CC} Node ref: ${nodeRef}`,
676
+ "",
677
+ `\u{1F4DD} Registered as federated reference for future resolution.`,
678
+ `\u{1F4A1} Remote graph resolution will be available when the target project is reachable.`,
679
+ federatedNodes > 0 ? `\u2705 Created ${federatedNodes} federated node(s) in local graph.` : ""
680
+ ].filter(Boolean).join("\n");
681
+ } catch (err) {
682
+ return `\u274C Federated resolution failed: ${err}`;
683
+ }
684
+ }
685
+ async function registerFederatedReference(uri, projectName, nodeRef) {
686
+ try {
687
+ await upsertNode({
688
+ id: `federated::${uri}`,
689
+ type: "module",
690
+ name: `[${projectName}] ${nodeRef}`,
691
+ metadata: {
692
+ federated: true,
693
+ uri,
694
+ project: projectName,
695
+ ref: nodeRef,
696
+ resolved: false
697
+ }
698
+ });
699
+ return 1;
700
+ } catch {
701
+ return 0;
702
+ }
703
+ }
704
+ async function listFederatedReferences() {
705
+ try {
706
+ const db = await getDb();
707
+ const stmt = db.prepare(`
708
+ SELECT id, name, metadata FROM nodes
709
+ WHERE metadata LIKE '%"federated":true%'
710
+ ORDER BY updated_at DESC
711
+ LIMIT 20
712
+ `);
713
+ const results = [];
714
+ while (stmt.step()) results.push(stmt.getAsObject());
715
+ stmt.free();
716
+ if (results.length === 0) {
717
+ return "\u{1F517} **No federated references.** Use kuma_memory({ action: 'federated', uri: 'kuma://project/node-id' }) to add one.";
718
+ }
719
+ const lines = [
720
+ "\u{1F517} **Federated References**",
721
+ "\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",
722
+ ""
723
+ ];
724
+ for (const r of results) {
725
+ const meta = JSON.parse(r.metadata || "{}");
726
+ lines.push(` \u{1F517} **${r.name}**`);
727
+ lines.push(` URI: ${meta.uri || "unknown"}`);
728
+ lines.push(` Resolved: ${meta.resolved ? "\u2705" : "\u23F3"}`);
729
+ lines.push("");
730
+ }
731
+ return lines.join("\n");
732
+ } catch (err) {
733
+ return `Error: ${err}`;
734
+ }
735
+ }
633
736
  async function getGraphStats() {
634
737
  try {
635
738
  const db = await getDb();
@@ -850,6 +953,7 @@ export {
850
953
  detectStaleNodes,
851
954
  autoHeal,
852
955
  formatHealReport,
956
+ nodeId,
853
957
  upsertNode,
854
958
  addEdge,
855
959
  recordFunctionCall,
@@ -860,6 +964,8 @@ export {
860
964
  queryGraph,
861
965
  buildFromSessionMemory,
862
966
  searchGraph,
967
+ resolveFederatedNode,
968
+ listFederatedReferences,
863
969
  getGraphStats,
864
970
  analyzeImpact,
865
971
  formatImpact,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getActiveGotchas
3
- } from "./chunk-53J56QCQ.js";
3
+ } from "./chunk-Q2444HWO.js";
4
4
  import {
5
5
  sessionMemory
6
- } from "./chunk-SLRRDKQ2.js";
6
+ } from "./chunk-R6B3VUSB.js";
7
7
  import {
8
8
  getDb
9
- } from "./chunk-NAM7SCBT.js";
9
+ } from "./chunk-3TX6Q37T.js";
10
10
  import {
11
11
  getProjectRoot
12
12
  } from "./chunk-E2KFPEBT.js";
@@ -6,8 +6,8 @@ import {
6
6
  getLayersSummary,
7
7
  readLayer,
8
8
  writeLayer
9
- } from "./chunk-53J56QCQ.js";
10
- import "./chunk-SLRRDKQ2.js";
9
+ } from "./chunk-Q2444HWO.js";
10
+ import "./chunk-R6B3VUSB.js";
11
11
  import "./chunk-E2KFPEBT.js";
12
12
  export {
13
13
  appendToLayer,