@plumpslabs/kuma 2.4.21 → 2.4.22

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/index.js CHANGED
@@ -11438,25 +11438,30 @@ function opencodePluginTemplate() {
11438
11438
  " }",
11439
11439
  "}",
11440
11440
  "",
11441
- "export const KumaPlugin = async ({ project, client, $, directory, worktree }) => {",
11441
+ "function enforceGotchas(tool, args) {",
11442
+ ' const name = String(tool || "").toLowerCase();',
11443
+ " const argv = args || {};",
11444
+ ' const targetPath = argv.filePath || argv.targetFile || argv.path || argv.file || "";',
11445
+ " if (!targetPath) return;",
11446
+ ' if (!(name.includes("edit") || name.includes("write") || name.includes("patch"))) return;',
11447
+ " const blocking = getBlockingGotchasForFile(String(targetPath));",
11448
+ " if (blocking.length > 0) {",
11449
+ " throw new Error(",
11450
+ " `\u{1F43B} [Kuma] ${blocking.length} critical/high gotcha(s) for ${targetPath}:\\n` +",
11451
+ ' blocking.map((g) => ` \u{1F534} ${g}`).join("\\n") +',
11452
+ ' `\\nRead .kuma/KNOWN_GOTCHAS.md for workarounds, or run kuma_memory({ action: "gotcha" }) to list.`',
11453
+ " );",
11454
+ " }",
11455
+ "}",
11456
+ "",
11457
+ "// \u2500\u2500\u2500 v1 host: factory (named export, legacy mode requires functions) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
11458
+ "export const KumaPlugin = async () => {",
11442
11459
  " return {",
11443
11460
  ' "tool.execute.before": async (input, output) => {',
11444
- ' const tool = String(input.tool || "").toLowerCase();',
11445
- " const args = output.args || {};",
11446
- ' const targetPath = args.filePath || args.targetFile || args.path || args.file || "";',
11447
- " if (!targetPath) return;",
11448
- ' if (!(tool.includes("edit") || tool.includes("write") || tool.includes("patch"))) return;',
11449
- " const blocking = getBlockingGotchasForFile(String(targetPath));",
11450
- " if (blocking.length > 0) {",
11451
- " throw new Error(",
11452
- " `\u{1F43B} [Kuma] ${blocking.length} critical/high gotcha(s) for ${targetPath}:\\n` +",
11453
- ' blocking.map((g) => ` \u{1F534} ${g}`).join("\\n") +',
11454
- ' `\\nRead .kuma/KNOWN_GOTCHAS.md for workarounds, or run kuma_memory({ action: "gotcha" }) to list.`',
11455
- " );",
11456
- " }",
11461
+ " enforceGotchas(input?.tool, output?.args);",
11457
11462
  " },",
11458
11463
  ' "file.edited": async (input) => {',
11459
- ' const fp = input.filePath || input.path || (input.file && input.file.path) || "";',
11464
+ ' const fp = input?.filePath || input?.path || (input?.file && input?.file.path) || "";',
11460
11465
  ' if (fp) console.warn(`\u{1F43B} [Kuma] ${fp} edited \u2014 consider kuma_safety({ action: "verify", scope: "${fp}" })`);',
11461
11466
  " },",
11462
11467
  ' "experimental.session.compacting": async (input, output) => {',
@@ -11470,6 +11475,48 @@ function opencodePluginTemplate() {
11470
11475
  " },",
11471
11476
  " };",
11472
11477
  "};",
11478
+ "",
11479
+ "// \u2500\u2500\u2500 v1 host: module object form (v1 >= 1.18 calls server(), ignores setup) \u2500",
11480
+ "async function server() {",
11481
+ " return {",
11482
+ ' "tool.execute.before": async (input, output) => {',
11483
+ " enforceGotchas(input?.tool, output?.args);",
11484
+ " },",
11485
+ ' "file.edited": async (input) => {',
11486
+ ' const fp = input?.filePath || input?.path || (input?.file && input?.file.path) || "";',
11487
+ ' if (fp) console.warn(`\u{1F43B} [Kuma] ${fp} edited \u2014 consider kuma_safety({ action: "verify", scope: "${fp}" })`);',
11488
+ " },",
11489
+ ' "experimental.session.compacting": async (input, output) => {',
11490
+ " try {",
11491
+ ' const { execSync } = await import("node:child_process");',
11492
+ ' const ctx = execSync("kuma hook pre-compact", { encoding: "utf-8", timeout: 8000 });',
11493
+ ' const parsed = JSON.parse(ctx || "{}");',
11494
+ ' const add = parsed?.hookSpecificOutput?.hookSpecificOutput?.additionalContext || "";',
11495
+ " if (add && output && Array.isArray(output.context)) output.context.push(add);",
11496
+ " } catch { /* compacting must never fail */ }",
11497
+ " },",
11498
+ " };",
11499
+ "}",
11500
+ "",
11501
+ "// \u2500\u2500\u2500 v2 host: setup registers hooks on ctx (mutable event draft) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
11502
+ "async function setup(ctx) {",
11503
+ ' const hook = ctx && ctx.tool && typeof ctx.tool.hook === "function"',
11504
+ " ? ctx.tool.hook.bind(ctx.tool)",
11505
+ " : null;",
11506
+ " if (!hook) return;",
11507
+ ' await hook("execute.before", async (event) => {',
11508
+ " const e = event || {};",
11509
+ ' const tool = e.tool ?? e.toolName ?? e.name ?? e.input?.tool ?? "";',
11510
+ " const args = e.input ?? e.args ?? e.output?.args ?? {};",
11511
+ " enforceGotchas(tool, args);",
11512
+ " });",
11513
+ "}",
11514
+ "",
11515
+ "export default {",
11516
+ ' id: "kuma",',
11517
+ " server,",
11518
+ " setup,",
11519
+ "};",
11473
11520
  ""
11474
11521
  ].join("\n");
11475
11522
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumpslabs/kuma",
3
- "version": "2.4.21",
3
+ "version": "2.4.22",
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",
package/plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://antigravity.google/schemas/v1/plugin.json",
3
3
  "name": "kuma",
4
- "version": "2.4.21",
4
+ "version": "2.4.22",
5
5
  "description": "Safety-first context & orchestration engine for AI coding agents. Shadow memory, gotcha lifecycle, blast radius impact analysis, and test verification.",
6
6
  "author": {
7
7
  "name": "plumpslabs",