@plumpslabs/kuma 2.3.20 → 2.3.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +18 -0
  2. package/dist/index.js +10316 -380
  3. package/package.json +2 -2
  4. package/packages/ide/studio/dist/index.js +90 -9
  5. package/packages/ide/studio/public/index.html +528 -233
  6. package/dist/agentDetector-YOWQVJFR.js +0 -186
  7. package/dist/chunk-3BRBJZ7P.js +0 -1055
  8. package/dist/chunk-3OHYYXYN.js +0 -71
  9. package/dist/chunk-ABKE45T4.js +0 -1264
  10. package/dist/chunk-E2KFPEBT.js +0 -183
  11. package/dist/chunk-FKRSI5U5.js +0 -282
  12. package/dist/chunk-GFLSAXAH.js +0 -155
  13. package/dist/chunk-L7F67KUP.js +0 -172
  14. package/dist/chunk-LVKOGXLC.js +0 -658
  15. package/dist/chunk-PRUTTZBS.js +0 -1113
  16. package/dist/contextDigest-QB5XHPXE.js +0 -177
  17. package/dist/domainRules-QLPAQASB.js +0 -20
  18. package/dist/init-PL4XL662.js +0 -15
  19. package/dist/kumaAstValidator-CNM7FHYA.js +0 -150
  20. package/dist/kumaCheckpoint-J2LDQMEO.js +0 -207
  21. package/dist/kumaCodeScanner-J6B2EHGI.js +0 -563
  22. package/dist/kumaContractEngine-KX27T4N7.js +0 -305
  23. package/dist/kumaDb-4XZ5S2LH.js +0 -65
  24. package/dist/kumaDriftDetector-TOORILSZ.js +0 -237
  25. package/dist/kumaGotchas-XRGFFBTA.js +0 -151
  26. package/dist/kumaGraph-UMXZNGYF.js +0 -44
  27. package/dist/kumaMemory-FBJMV77G.js +0 -16
  28. package/dist/kumaMiner-XJETL7TL.js +0 -176
  29. package/dist/kumaPolicyEngine-2QDJDLM7.js +0 -311
  30. package/dist/kumaProgressiveContext-MWEDRXOH.js +0 -231
  31. package/dist/kumaSearch-PV4QTKE7.js +0 -321
  32. package/dist/kumaTrajectory-7NOAVNG2.js +0 -460
  33. package/dist/kumaVerifier-6YEGC77M.js +0 -265
  34. package/dist/kumaVisualize-264OEBGJ.js +0 -264
  35. package/dist/pathValidator-V4DC6U6Z.js +0 -22
  36. package/dist/safetyAudit-O45SPNTS.js +0 -12
  37. package/dist/safetyScore-TMMRD2MV.js +0 -333
  38. package/dist/sessionMemory-YPKVIOMV.js +0 -6
  39. package/dist/skillGenerator-PWEJKZNX.js +0 -304
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumpslabs/kuma",
3
- "version": "2.3.20",
3
+ "version": "2.3.23",
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",
@@ -63,7 +63,7 @@
63
63
  "homepage": "https://github.com/plumpslabs/kuma#readme",
64
64
  "license": "MIT",
65
65
  "scripts": {
66
- "build": "tsup src/index.ts --format esm --clean --out-dir dist",
66
+ "build": "tsup src/index.ts --format esm --no-splitting --clean --out-dir dist",
67
67
  "build:studio": "cd packages/ide/studio && tsup src/index.ts --format esm --clean --out-dir dist",
68
68
  "build:all": "pnpm run build && pnpm run build:studio",
69
69
  "dev": "tsup src/index.ts --format esm --watch --out-dir dist",
@@ -38,7 +38,17 @@ function query(sql) {
38
38
  function queryJson(sql) {
39
39
  const raw = query(sql);
40
40
  if (!raw) return [];
41
- return JSON.parse(raw);
41
+ try {
42
+ return JSON.parse(raw);
43
+ } catch {
44
+ try {
45
+ const sanitized = raw.replace(/[\r\n]+/g, " ");
46
+ return JSON.parse(sanitized);
47
+ } catch (e) {
48
+ console.warn("[Studio DB] queryJson parse failed:", e);
49
+ return [];
50
+ }
51
+ }
42
52
  }
43
53
  function getDashboardData() {
44
54
  return {
@@ -47,37 +57,83 @@ function getDashboardData() {
47
57
  'node_count', (SELECT COUNT(*) FROM nodes),
48
58
  'edge_count', (SELECT COUNT(*) FROM edges),
49
59
  'gotcha_count', (SELECT COUNT(*) FROM known_gotchas),
50
- 'trajectory_count', (SELECT COUNT(*) FROM trajectories),
51
- 'skill_count', (SELECT COUNT(*) FROM distilled_skills),
60
+ 'feature_count', (SELECT COUNT(*) FROM nodes WHERE type = 'feature'),
52
61
  'health_score', COALESCE((SELECT score FROM health_snapshots ORDER BY created_at DESC LIMIT 1), 0)
53
62
  )
54
63
  `),
55
64
  nodes: queryJson(
56
- `SELECT json_group_array(json_object('id',id,'name',name,'type',type,'file_path',file_path)) FROM nodes ORDER BY created_at DESC`
65
+ `SELECT json_group_array(json_object('id',id,'name',name,'type',type,'file_path',file_path,'metadata',COALESCE(metadata,'{}'))) FROM nodes ORDER BY updated_at DESC`
57
66
  ),
58
67
  edges: queryJson(
59
- `SELECT json_group_array(json_object('source',source_id,'target',target_id,'relation',type)) FROM edges`
68
+ `SELECT json_group_array(json_object('source',source_id,'target',target_id,'relation',type,'weight',weight)) FROM edges`
60
69
  ),
61
70
  gotchas: queryJson(
62
- `SELECT json_group_array(json_object('id',id,'file_path',file_path,'description',description,'severity',severity,'workaround',workaround)) FROM known_gotchas ORDER BY severity DESC`
71
+ `SELECT json_group_array(json_object('id',id,'file_path',file_path,'description',REPLACE(REPLACE(description,char(10),' '),char(13),''),'severity',severity,'workaround',REPLACE(REPLACE(COALESCE(workaround,''),char(10),' '),char(13),''))) FROM known_gotchas ORDER BY severity DESC`
63
72
  ),
64
- trajectories: queryJson(
65
- `SELECT json_group_array(json_object('id',id,'goal',goal,'total_duration_ms',total_duration_ms,'success_rate',success_rate,'created_at',created_at)) FROM trajectories ORDER BY created_at DESC LIMIT 20`
73
+ features: queryJson(
74
+ `SELECT json_group_array(json_object('id',id,'name',name,'metadata',COALESCE(metadata,'{}'))) FROM nodes WHERE type = 'feature' ORDER BY name`
66
75
  ),
67
76
  health: queryJson(
68
- `SELECT json_group_array(json_object('score',score,'summary',summary,'risk_level',risk_level,'created_at',created_at)) FROM health_snapshots ORDER BY created_at DESC LIMIT 10`
77
+ `SELECT json_group_array(json_object('score',score,'summary',REPLACE(REPLACE(COALESCE(summary,''),char(10),' '),char(13),''),'risk_level',risk_level,'created_at',created_at)) FROM health_snapshots ORDER BY created_at DESC LIMIT 10`
69
78
  )
70
79
  };
71
80
  }
81
+ function getNodeDetail(nodeId) {
82
+ const escaped = nodeId.replace(/'/g, "''");
83
+ const shortName = nodeId.split("::").pop()?.replace(/'/g, "''") || "";
84
+ const node = queryJson(
85
+ `SELECT json_object('id',id,'name',name,'type',type,'file_path',file_path,'metadata',COALESCE(metadata,'{}'),'updated_at',updated_at) FROM nodes WHERE id = '${escaped}'`
86
+ );
87
+ const nodeObj = Array.isArray(node) ? node[0] : node;
88
+ if (!nodeObj) return null;
89
+ const rawOut = query(
90
+ `SELECT json_object('target',e.target_id,'relation',e.type,'weight',e.weight,'target_name',n.name,'target_type',n.type) FROM edges e LEFT JOIN nodes n ON n.id = e.target_id WHERE e.source_id = '${escaped}'`
91
+ );
92
+ const outgoing = rawOut ? rawOut.split("\n").filter(Boolean).map((r) => {
93
+ try {
94
+ return JSON.parse(r);
95
+ } catch {
96
+ return null;
97
+ }
98
+ }).filter(Boolean) : [];
99
+ const rawIn = query(
100
+ `SELECT json_object('source',e.source_id,'relation',e.type,'weight',e.weight,'source_name',n.name,'source_type',n.type) FROM edges e LEFT JOIN nodes n ON n.id = e.source_id WHERE e.target_id = '${escaped}'`
101
+ );
102
+ const incoming = rawIn ? rawIn.split("\n").filter(Boolean).map((r) => {
103
+ try {
104
+ return JSON.parse(r);
105
+ } catch {
106
+ return null;
107
+ }
108
+ }).filter(Boolean) : [];
109
+ const rawGotcha = query(
110
+ `SELECT json_object('id',id,'description',REPLACE(REPLACE(description,char(10),' '),char(13),''),'severity',severity) FROM known_gotchas WHERE file_path = '${escaped}' OR file_path LIKE '%${shortName}%'`
111
+ );
112
+ const gotchas = rawGotcha ? rawGotcha.split("\n").filter(Boolean).map((r) => {
113
+ try {
114
+ return JSON.parse(r);
115
+ } catch {
116
+ return null;
117
+ }
118
+ }).filter(Boolean) : [];
119
+ return { node: nodeObj, outgoing, incoming, gotchas };
120
+ }
72
121
 
73
122
  // src/api.ts
123
+ import fs from "fs";
74
124
  var api = new Hono();
75
125
  api.use("/*", cors());
76
126
  api.get("/status", (c) => {
77
127
  const dbPath = findKumaDb();
128
+ let dbSize = "0 KB";
129
+ if (dbPath && fs.existsSync(dbPath)) {
130
+ const bytes = fs.statSync(dbPath).size;
131
+ dbSize = bytes > 1024 * 1024 ? (bytes / (1024 * 1024)).toFixed(2) + " MB" : (bytes / 1024).toFixed(1) + " KB";
132
+ }
78
133
  return c.json({
79
134
  ok: !!dbPath,
80
135
  dbPath,
136
+ dbSize,
81
137
  project: dbPath ? dbPath.replace("/.kuma/kuma.db", "").split("/").pop() : null
82
138
  });
83
139
  });
@@ -89,6 +145,31 @@ api.get("/dashboard", (c) => {
89
145
  return c.json({ error: e.message }, 500);
90
146
  }
91
147
  });
148
+ api.get("/node/:id", (c) => {
149
+ try {
150
+ const nodeId = c.req.param("id");
151
+ const detail = getNodeDetail(nodeId);
152
+ if (!detail) return c.json({ error: "Node not found" }, 404);
153
+ return c.json(detail);
154
+ } catch (e) {
155
+ return c.json({ error: e.message }, 500);
156
+ }
157
+ });
158
+ api.post("/reset-db", (c) => {
159
+ try {
160
+ const dbPath = findKumaDb();
161
+ if (dbPath && fs.existsSync(dbPath)) {
162
+ fs.unlinkSync(dbPath);
163
+ }
164
+ return c.json({ ok: true, message: "Kuma DB reset successfully" });
165
+ } catch (e) {
166
+ return c.json({ error: e.message }, 500);
167
+ }
168
+ });
169
+ api.post("/stop-server", (c) => {
170
+ setTimeout(() => process.exit(0), 500);
171
+ return c.json({ ok: true, message: "Kuma Studio server shutting down" });
172
+ });
92
173
  var api_default = api;
93
174
 
94
175
  // src/index.ts