context-mode 1.0.121 → 1.0.123

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 (55) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.openclaw-plugin/openclaw.plugin.json +1 -1
  4. package/.openclaw-plugin/package.json +1 -1
  5. package/README.md +4 -4
  6. package/build/adapters/claude-code/hooks.d.ts +16 -1
  7. package/build/adapters/claude-code/hooks.js +16 -0
  8. package/build/adapters/claude-code/index.js +2 -11
  9. package/build/adapters/client-map.js +6 -0
  10. package/build/adapters/codex/hooks.d.ts +19 -0
  11. package/build/adapters/codex/hooks.js +22 -0
  12. package/build/adapters/codex/index.js +8 -1
  13. package/build/adapters/copilot-base.d.ts +17 -1
  14. package/build/adapters/copilot-base.js +18 -2
  15. package/build/adapters/cursor/hooks.d.ts +14 -1
  16. package/build/adapters/cursor/hooks.js +14 -0
  17. package/build/adapters/detect.d.ts +12 -2
  18. package/build/adapters/detect.js +96 -13
  19. package/build/adapters/gemini-cli/hooks.d.ts +16 -0
  20. package/build/adapters/gemini-cli/hooks.js +19 -0
  21. package/build/adapters/gemini-cli/index.js +4 -2
  22. package/build/adapters/kiro/hooks.d.ts +16 -1
  23. package/build/adapters/kiro/hooks.js +19 -0
  24. package/build/adapters/pi/extension.d.ts +9 -0
  25. package/build/adapters/pi/extension.js +52 -1
  26. package/build/adapters/qwen-code/hooks.d.ts +26 -0
  27. package/build/adapters/qwen-code/hooks.js +29 -0
  28. package/build/adapters/qwen-code/index.js +6 -0
  29. package/build/cli.js +46 -5
  30. package/build/executor.js +18 -3
  31. package/build/lifecycle.d.ts +15 -0
  32. package/build/lifecycle.js +24 -1
  33. package/build/runtime.js +34 -13
  34. package/build/server.js +17 -2
  35. package/build/session/extract.js +150 -48
  36. package/build/session/snapshot.js +46 -0
  37. package/cli.bundle.mjs +151 -150
  38. package/configs/codex/hooks.json +1 -1
  39. package/configs/cursor/hooks.json +1 -1
  40. package/configs/kiro/agent.json +1 -1
  41. package/hooks/core/routing.mjs +56 -1
  42. package/hooks/cursor/hooks.json +1 -1
  43. package/hooks/ensure-deps.mjs +45 -10
  44. package/hooks/hooks.json +9 -0
  45. package/hooks/routing-block.mjs +5 -0
  46. package/hooks/session-extract.bundle.mjs +2 -2
  47. package/hooks/session-snapshot.bundle.mjs +21 -20
  48. package/openclaw.plugin.json +1 -1
  49. package/package.json +3 -3
  50. package/scripts/heal-better-sqlite3.mjs +188 -10
  51. package/scripts/heal-installed-plugins.mjs +111 -0
  52. package/scripts/postinstall.mjs +35 -9
  53. package/server.bundle.mjs +118 -118
  54. package/start.mjs +14 -1
  55. package/.mcp.json +0 -8
@@ -2,7 +2,7 @@
2
2
  "hooks": {
3
3
  "PreToolUse": [
4
4
  {
5
- "matcher": "local_shell|shell|shell_command|exec_command|container.exec|functions\\.exec_command|Bash|Shell|apply_patch|functions\\.apply_patch|Edit|Write|grep_files|ctx_execute|ctx_execute_file|ctx_batch_execute|ctx_fetch_and_index|ctx_search|ctx_index|mcp__.*__ctx_execute|mcp__.*__ctx_execute_file|mcp__.*__ctx_batch_execute|mcp__.*__ctx_fetch_and_index|mcp__.*__ctx_search|mcp__.*__ctx_index",
5
+ "matcher": "local_shell|shell|shell_command|exec_command|container.exec|functions\\.exec_command|Bash|Shell|apply_patch|functions\\.apply_patch|Edit|Write|grep_files|ctx_execute|ctx_execute_file|ctx_batch_execute|ctx_fetch_and_index|ctx_search|ctx_index|mcp__.*__ctx_execute|mcp__.*__ctx_execute_file|mcp__.*__ctx_batch_execute|mcp__.*__ctx_fetch_and_index|mcp__.*__ctx_search|mcp__.*__ctx_index|mcp__(?!.*context-mode)",
6
6
  "hooks": [
7
7
  { "type": "command", "command": "context-mode hook codex pretooluse" }
8
8
  ]
@@ -4,7 +4,7 @@
4
4
  "preToolUse": [
5
5
  {
6
6
  "command": "context-mode hook cursor pretooluse",
7
- "matcher": "Shell|Read|Grep|WebFetch|mcp_web_fetch|mcp_fetch_tool|Task|MCP:ctx_execute|MCP:ctx_execute_file|MCP:ctx_batch_execute"
7
+ "matcher": "Shell|Read|Grep|WebFetch|mcp_web_fetch|mcp_fetch_tool|Task|MCP:ctx_execute|MCP:ctx_execute_file|MCP:ctx_batch_execute|MCP:(?!ctx_)"
8
8
  }
9
9
  ],
10
10
  "postToolUse": [
@@ -4,7 +4,7 @@
4
4
  "hooks": {
5
5
  "preToolUse": [
6
6
  {
7
- "matcher": "execute_bash|fs_read|@context-mode/ctx_execute|@context-mode/ctx_execute_file|@context-mode/ctx_batch_execute",
7
+ "matcher": "execute_bash|fs_read|@context-mode/ctx_execute|@context-mode/ctx_execute_file|@context-mode/ctx_batch_execute|@(?!context-mode/)",
8
8
  "command": "context-mode hook kiro pretooluse"
9
9
  }
10
10
  ],
@@ -11,8 +11,9 @@
11
11
  */
12
12
 
13
13
  import {
14
- ROUTING_BLOCK, READ_GUIDANCE, GREP_GUIDANCE, BASH_GUIDANCE,
14
+ ROUTING_BLOCK, READ_GUIDANCE, GREP_GUIDANCE, BASH_GUIDANCE, EXTERNAL_MCP_GUIDANCE,
15
15
  createRoutingBlock, createReadGuidance, createGrepGuidance, createBashGuidance,
16
+ createExternalMcpGuidance,
16
17
  } from "../routing-block.mjs";
17
18
  import { createToolNamer } from "./tool-naming.mjs";
18
19
  import { isMCPReady } from "./mcp-ready.mjs";
@@ -358,6 +359,50 @@ function matchesContextModeTool(toolName, ctxName, legacyName) {
358
359
  return raw.includes("context-mode") && leaf === legacyName;
359
360
  }
360
361
 
362
+ // External MCP detection (#529 + 15-adapter coverage follow-up).
363
+ //
364
+ // MCP-namespaced tool names follow per-platform conventions (see
365
+ // core/tool-naming.mjs):
366
+ // - `mcp__<server>__<tool>` Claude Code / Gemini CLI / Antigravity / Qwen Code / Codex
367
+ // - `MCP:<tool>` Cursor
368
+ // - `@<server>/<tool>` Kiro
369
+ //
370
+ // Tools belonging to context-mode itself are excluded — they have dedicated
371
+ // routing branches above (ctx_execute, ctx_execute_file, ctx_batch_execute)
372
+ // and re-routing them here would double-process the call.
373
+ const MCP_PREFIX = "mcp__";
374
+ const CURSOR_MCP_PREFIX = "MCP:";
375
+ const KIRO_MCP_PREFIX = "@";
376
+ const CTX_TOOL_PREFIX = "ctx_";
377
+ const CONTEXT_MODE_SUBSTRING = "context-mode";
378
+
379
+ function isExternalMcpTool(toolName) {
380
+ const raw = String(toolName ?? "");
381
+
382
+ // Claude / Codex / Gemini / Qwen / Antigravity wire shape.
383
+ if (raw.startsWith(MCP_PREFIX)) {
384
+ const server = raw.slice(MCP_PREFIX.length).split("__")[0];
385
+ if (!server) return false;
386
+ return !server.includes(CONTEXT_MODE_SUBSTRING);
387
+ }
388
+
389
+ // Cursor wire shape: `MCP:<tool>` — own tools are `MCP:ctx_*`. There is no
390
+ // server segment, so the discriminator is the tool-leaf prefix.
391
+ if (raw.startsWith(CURSOR_MCP_PREFIX)) {
392
+ const tool = raw.slice(CURSOR_MCP_PREFIX.length);
393
+ return tool.length > 0 && !tool.startsWith(CTX_TOOL_PREFIX);
394
+ }
395
+
396
+ // Kiro wire shape: `@<server>/<tool>` — own tools are `@context-mode/ctx_*`.
397
+ if (raw.startsWith(KIRO_MCP_PREFIX) && raw.includes("/")) {
398
+ const server = raw.slice(KIRO_MCP_PREFIX.length).split("/")[0];
399
+ if (!server) return false;
400
+ return !server.includes(CONTEXT_MODE_SUBSTRING);
401
+ }
402
+
403
+ return false;
404
+ }
405
+
361
406
  /**
362
407
  * Route a PreToolUse event. Returns normalized decision object or null for passthrough.
363
408
  *
@@ -665,6 +710,16 @@ export function routePreToolUse(toolName, toolInput, projectDir, platform, sessi
665
710
  return null;
666
711
  }
667
712
 
713
+ // ─── External MCP tools: one-shot guidance about routing large payloads ─── (#529)
714
+ // hooks/hooks.json registers a `mcp__(?!plugin_context-mode_)` matcher so this
715
+ // branch fires for slack/telegram/gdrive/notion-style MCPs whose results would
716
+ // otherwise spill into context. We don't deny or modify — the agent still needs
717
+ // the tool's output; we just nudge it to pipe large results through ctx_execute.
718
+ if (isExternalMcpTool(toolName)) {
719
+ const externalMcpGuidance = platform ? createExternalMcpGuidance(t) : EXTERNAL_MCP_GUIDANCE;
720
+ return guidanceOnce("external-mcp", externalMcpGuidance, sessionId);
721
+ }
722
+
668
723
  // Unknown tool — pass through
669
724
  return null;
670
725
  }
@@ -4,7 +4,7 @@
4
4
  "preToolUse": [
5
5
  {
6
6
  "command": "npx -y context-mode hook cursor pretooluse",
7
- "matcher": "Shell|Read|Grep|WebFetch|mcp_web_fetch|mcp_fetch_tool|Task|MCP:ctx_execute|MCP:ctx_execute_file|MCP:ctx_batch_execute"
7
+ "matcher": "Shell|Read|Grep|WebFetch|mcp_web_fetch|mcp_fetch_tool|Task|MCP:ctx_execute|MCP:ctx_execute_file|MCP:ctx_batch_execute|MCP:(?!ctx_)"
8
8
  }
9
9
  ],
10
10
  "postToolUse": [
@@ -23,6 +23,7 @@ import { existsSync, copyFileSync } from "node:fs";
23
23
  import { execSync } from "node:child_process";
24
24
  import { resolve, dirname } from "node:path";
25
25
  import { fileURLToPath, pathToFileURL } from "node:url";
26
+ import { createRequire } from "node:module";
26
27
 
27
28
  const __dirname = dirname(fileURLToPath(import.meta.url));
28
29
  const root = resolve(__dirname, "..");
@@ -111,20 +112,51 @@ function probeNativeInChildProcess(pluginRoot) {
111
112
  }
112
113
  }
113
114
 
115
+ /**
116
+ * In-process probe — cheap, safe on modern Node (no child spawn, no SIGSEGV path).
117
+ * Returns true if better-sqlite3 loads against the current ABI.
118
+ */
119
+ function probeNativeInProcess(pluginRoot) {
120
+ try {
121
+ const req = createRequire(resolve(pluginRoot, "package.json"));
122
+ const Database = req("better-sqlite3");
123
+ new Database(":memory:").close();
124
+ return true;
125
+ } catch {
126
+ return false;
127
+ }
128
+ }
129
+
114
130
  export function ensureNativeCompat(pluginRoot) {
115
- // Bun ships bun:sqliteno native addon needed
116
- if (typeof globalThis.Bun !== "undefined") return;
131
+ // Pre-compute paths regardless of runtime the Bun branch below uses
132
+ // them to seed the ABI cache (#543) so the next /ctx-upgrade boot (under
133
+ // Node) finds the success marker file. Bun spoofs
134
+ // process.versions.modules to match the Node ABI level (e.g. 137 on
135
+ // Darwin matching Node 24), so a plain file-copy produces the correct
136
+ // filename for any subsequent Node boot at the same ABI.
137
+ const abi = process.versions.modules;
138
+ const nativeDir = resolve(pluginRoot, "node_modules", "better-sqlite3", "build", "Release");
139
+ const binaryPath = resolve(nativeDir, "better_sqlite3.node");
140
+ const abiCachePath = resolve(nativeDir, `better_sqlite3.abi${abi}.node`);
141
+
142
+ // Bun ships bun:sqlite — no native addon needed at RUNTIME. But
143
+ // /ctx-upgrade still verifies the ABI cache file as the success marker,
144
+ // so we seed it from the active binary if it exists. Best-effort:
145
+ // any failure here is silent because Bun never loads better-sqlite3.
146
+ if (typeof globalThis.Bun !== "undefined") {
147
+ try {
148
+ if (existsSync(nativeDir) && existsSync(binaryPath) && !existsSync(abiCachePath)) {
149
+ copyFileSync(binaryPath, abiCachePath);
150
+ }
151
+ } catch { /* best effort — Bun never dlopens this file */ }
152
+ return;
153
+ }
117
154
 
118
155
  // On Node >= 22.5, skip the child-process probe that can cause SIGSEGV (#331).
119
156
  // The binary install/rebuild still runs — only the dlopen probe is skipped.
120
157
  const skipProbe = hasModernSqlite();
121
158
 
122
159
  try {
123
- const abi = process.versions.modules;
124
- const nativeDir = resolve(pluginRoot, "node_modules", "better-sqlite3", "build", "Release");
125
- const binaryPath = resolve(nativeDir, "better_sqlite3.node");
126
- const abiCachePath = resolve(nativeDir, `better_sqlite3.abi${abi}.node`);
127
-
128
160
  if (!existsSync(nativeDir)) return;
129
161
 
130
162
  // Fast path: cached binary for this ABI already exists — swap in
@@ -141,9 +173,12 @@ export function ensureNativeCompat(pluginRoot) {
141
173
  }
142
174
 
143
175
  if (skipProbe) {
144
- // On modern Node, the current ABI cache is the compatibility marker.
145
- // Without it, rebuild even when the active binary exists: it may be stale
146
- // from a previous Node ABI and cannot be probed safely here.
176
+ // Seed the ABI cache from a working binary before falling back to rebuild;
177
+ // otherwise a missing cache forces npm rebuild on every hook invocation.
178
+ if (existsSync(binaryPath) && probeNativeInProcess(pluginRoot)) {
179
+ copyFileSync(binaryPath, abiCachePath);
180
+ return;
181
+ }
147
182
  execSync(`${process.platform === "win32" ? "npm.cmd" : "npm"} rebuild better-sqlite3 --ignore-scripts=false`, {
148
183
  cwd: pluginRoot,
149
184
  stdio: "pipe",
package/hooks/hooks.json CHANGED
@@ -95,6 +95,15 @@
95
95
  "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.mjs\""
96
96
  }
97
97
  ]
98
+ },
99
+ {
100
+ "matcher": "mcp__(?!plugin_context-mode_)",
101
+ "hooks": [
102
+ {
103
+ "type": "command",
104
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.mjs\""
105
+ }
106
+ ]
98
107
  }
99
108
  ],
100
109
  "UserPromptSubmit": [
@@ -91,6 +91,10 @@ export function createBashGuidance(t) {
91
91
  return '<context_guidance>\n <tip>\n May produce large output. Use ' + t("ctx_batch_execute") + '(commands, queries) for multiple commands, ' + t("ctx_execute") + '(language: "shell", code: "...") for single. Only printed summary enters context. Bash only for: git, mkdir, rm, mv, navigation.\n </tip>\n</context_guidance>';
92
92
  }
93
93
 
94
+ export function createExternalMcpGuidance(t) {
95
+ return '<context_guidance>\n <tip>\n External MCP tools may return large payloads (channel history, file content, search results) that flood context. After this call, if the result is large or you need to filter/aggregate it, pipe the data through ' + t("ctx_execute") + '(language, code) — only your printed summary enters context. For docs-style fetches, prefer ' + t("ctx_fetch_and_index") + '(url, source) then ' + t("ctx_search") + '(queries).\n </tip>\n</context_guidance>';
96
+ }
97
+
94
98
  // ── Backward compat: static exports defaulting to claude-code ──
95
99
 
96
100
  const _t = createToolNamer("claude-code");
@@ -98,3 +102,4 @@ export const ROUTING_BLOCK = createRoutingBlock(_t);
98
102
  export const READ_GUIDANCE = createReadGuidance(_t);
99
103
  export const GREP_GUIDANCE = createGrepGuidance(_t);
100
104
  export const BASH_GUIDANCE = createBashGuidance(_t);
105
+ export const EXTERNAL_MCP_GUIDANCE = createExternalMcpGuidance(_t);
@@ -1,2 +1,2 @@
1
- function s(t){return t==null?"":String(t)}function g(t){return t==null?"":typeof t=="string"?t:JSON.stringify(t)}function u(t){let e=String(t.tool_response??""),o=t.tool_output?.isError===!0||t.tool_output?.is_error===!0;return t.tool_name==="Bash"&&/exit code [1-9]|error:|Error:|FAIL|failed/i.test(e)||o}function h(t){if(!t)return[];let e=[];for(let r of t.split(/\r?\n/)){if(r.startsWith("*** Add File: ")){e.push({path:r.slice(14).trim(),type:"file_write"});continue}if(r.startsWith("*** Update File: ")){e.push({path:r.slice(17).trim(),type:"file_edit"});continue}if(r.startsWith("*** Delete File: ")){e.push({path:r.slice(17).trim(),type:"file_edit"});continue}r.startsWith("*** Move to: ")&&e.push({path:r.slice(13).trim(),type:"file_edit"})}let o=new Set;return e.filter(r=>{if(!r.path)return!1;let n=`${r.type}:${r.path}`;return o.has(n)?!1:(o.add(n),!0)})}function f(t){return/(?:^|[/\\])\.claude[/\\]plans[/\\]/.test(t)}function _(t){let{tool_name:e,tool_input:o,tool_response:r}=t,n=[];if(e==="Read"){let i=String(o.file_path??"");return(/(?:CLAUDE|AGENTS(?:\.override)?|GEMINI|QWEN|KIRO)\.md$/i.test(i)||/\/copilot-instructions\.md$/i.test(i)||/\/context-mode\.mdc$/i.test(i)||/\.claude[\\/]/i.test(i)||/[\\/]memor(?:y|ies)[\\/][^\\/]+\.md$/i.test(i))&&(n.push({type:"rule",category:"rule",data:s(i),priority:1}),r&&r.length>0&&n.push({type:"rule_content",category:"rule",data:s(r),priority:1})),n.push({type:"file_read",category:"file",data:s(i),priority:1}),n}if(e==="Edit"){let i=String(o.file_path??"");return n.push({type:"file_edit",category:"file",data:s(i),priority:1}),n}if(e==="NotebookEdit"){let i=String(o.notebook_path??"");return n.push({type:"file_edit",category:"file",data:s(i),priority:1}),n}if(e==="Write"){let i=String(o.file_path??"");return n.push({type:"file_write",category:"file",data:s(i),priority:1}),n}if(e==="apply_patch"){if(u(t))return[];let i=h(String(o.command??o.patch??""));for(let a of i)n.push({type:a.type,category:"file",data:s(a.path),priority:1});return n}if(e==="Glob"){let i=String(o.pattern??"");return n.push({type:"file_glob",category:"file",data:s(i),priority:3}),n}if(e==="Grep"){let i=String(o.pattern??""),a=String(o.path??"");return n.push({type:"file_search",category:"file",data:s(`${i} in ${a}`),priority:3}),n}return n}function m(t){if(t.tool_name!=="Bash")return[];let o=String(t.tool_input.command??"").match(/\bcd\s+("([^"]+)"|'([^']+)'|(\S+))/);if(!o)return[];let r=o[2]??o[3]??o[4]??"";return[{type:"cwd",category:"cwd",data:s(r),priority:2}]}function S(t){let{tool_response:e}=t,o=String(e??"");return u(t)?[{type:"error_tool",category:"error",data:s(o),priority:2}]:[]}var k=[{pattern:/\bgit\s+checkout\b/,operation:"branch"},{pattern:/\bgit\s+commit\b/,operation:"commit"},{pattern:/\bgit\s+merge\s+\S+/,operation:"merge"},{pattern:/\bgit\s+rebase\b/,operation:"rebase"},{pattern:/\bgit\s+stash\b/,operation:"stash"},{pattern:/\bgit\s+push\b/,operation:"push"},{pattern:/\bgit\s+pull\b/,operation:"pull"},{pattern:/\bgit\s+log\b/,operation:"log"},{pattern:/\bgit\s+diff\b/,operation:"diff"},{pattern:/\bgit\s+status\b/,operation:"status"},{pattern:/\bgit\s+branch\b/,operation:"branch"},{pattern:/\bgit\s+reset\b/,operation:"reset"},{pattern:/\bgit\s+add\b/,operation:"add"},{pattern:/\bgit\s+cherry-pick\b/,operation:"cherry-pick"},{pattern:/\bgit\s+tag\b/,operation:"tag"},{pattern:/\bgit\s+fetch\b/,operation:"fetch"},{pattern:/\bgit\s+clone\b/,operation:"clone"},{pattern:/\bgit\s+worktree\b/,operation:"worktree"}];function E(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??""),o=k.find(r=>r.pattern.test(e));return o?[{type:"git",category:"git",data:s(o.operation),priority:2}]:[]}function v(t){return new Set(["TodoWrite","TaskCreate","TaskUpdate"]).has(t.tool_name)?[{type:t.tool_name==="TaskUpdate"?"task_update":t.tool_name==="TaskCreate"?"task_create":"task",category:"task",data:s(JSON.stringify(t.tool_input)),priority:1}]:[]}function x(t){if(t.tool_name==="EnterPlanMode")return[{type:"plan_enter",category:"plan",data:"entered plan mode",priority:2}];if(t.tool_name==="ExitPlanMode"){let e=[],o=t.tool_input.allowedPrompts,r=Array.isArray(o)&&o.length>0?`exited plan mode (allowed: ${g(o.map(i=>typeof i=="object"&&i!==null&&"prompt"in i?String(i.prompt):String(i)).join(", "))})`:"exited plan mode";e.push({type:"plan_exit",category:"plan",data:s(r),priority:2});let n=String(t.tool_response??"").toLowerCase();return n.includes("approved")||n.includes("approve")?e.push({type:"plan_approved",category:"plan",data:"plan approved by user",priority:1}):(n.includes("rejected")||n.includes("decline")||n.includes("denied"))&&e.push({type:"plan_rejected",category:"plan",data:s(`plan rejected: ${t.tool_response??""}`),priority:2}),e}if(t.tool_name==="Write"||t.tool_name==="Edit"){let e=String(t.tool_input.file_path??"");if(f(e))return[{type:"plan_file_write",category:"plan",data:s(`plan file: ${e.split(/[/\\]/).pop()??e}`),priority:2}]}return t.tool_name==="apply_patch"?u(t)?[]:h(String(t.tool_input.command??t.tool_input.patch??"")).filter(o=>f(o.path)).map(o=>({type:"plan_file_write",category:"plan",data:s(`plan file: ${o.path.split(/[/\\]/).pop()??o.path}`),priority:2})):[]}var w=[/\bsource\s+\S*activate\b/,/\bexport\s+\w+=/,/\bnvm\s+use\b/,/\bpyenv\s+(shell|local|global)\b/,/\bconda\s+activate\b/,/\brbenv\s+(shell|local|global)\b/,/\bnpm\s+install\b/,/\bnpm\s+ci\b/,/\bpip\s+install\b/,/\bbun\s+install\b/,/\byarn\s+(add|install)\b/,/\bpnpm\s+(add|install)\b/,/\bcargo\s+(install|add)\b/,/\bgo\s+(install|get)\b/,/\brustup\b/,/\basdf\b/,/\bvolta\b/,/\bdeno\s+install\b/];function R(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??"");if(!w.some(n=>n.test(e)))return[];let r=e.replace(/\bexport\s+(\w+)=\S*/g,"export $1=***");return[{type:"env",category:"env",data:s(r),priority:2}]}function T(t){if(t.tool_name!=="Skill")return[];let e=String(t.tool_input.skill??"");return[{type:"skill",category:"skill",data:s(e),priority:2}]}function A(t){if(!t.tool_response?.includes("Error")&&!t.tool_output?.isError)return[];let e=String(t.tool_response||""),o=[/not supported/i,/cannot/i,/does not support/i,/FAIL/i,/refused/i,/permission denied/i,/incompatible/i];for(let r of o){let n=e.match(r);if(n){let i=e.toLowerCase().indexOf(n[0].toLowerCase()),a=e.slice(Math.max(0,i-50),Math.min(e.length,i+200)).trim();return[{type:"constraint_discovered",category:"constraint",data:s(a),priority:2}]}}return[]}function I(t){if(t.tool_name!=="Agent")return[];let e=s(String(t.tool_input.prompt??t.tool_input.description??"")),o=t.tool_response?s(String(t.tool_response)):"",r=o.length>0;return[{type:r?"subagent_completed":"subagent_launched",category:"subagent",data:s(r?`[completed] ${e} \u2192 ${o}`:`[launched] ${e}`),priority:r?2:3}]}function $(t){let{tool_name:e,tool_input:o,tool_response:r}=t;if(!e.startsWith("mcp__"))return[];let n=e.split("__"),i=n[n.length-1]||e,a=Object.values(o).find(b=>typeof b=="string"),p=a?`: ${s(String(a))}`:"",y=r&&r.length>0?`
2
- response: ${s(r)}`:"";return[{type:"mcp",category:"mcp",data:s(`${i}${p}${y}`),priority:3}]}var H=2048;function P(t,e){if(Buffer.byteLength(t,"utf8")<=e)return{value:t,truncated:!1};let o=Buffer.from(t,"utf8"),r=e;for(;r>0&&(o[r]&192)===128;)r--;return{value:o.subarray(0,r).toString("utf8"),truncated:!0}}var N=/(authorization|auth_token|access_token|refresh_token|bearer|token|secret|password|passwd|pwd|api[-_]?key|apikey|cookie|set-cookie|signature|private[-_]?key|client[-_]?secret|x[-_]?api[-_]?key)/i,O="[REDACTED]";function d(t,e=new WeakSet){if(t==null||typeof t!="object")return t;if(e.has(t))return"[CIRCULAR]";e.add(t);let o;if(Array.isArray(t))o=t.map(r=>d(r,e));else{let r={};for(let[n,i]of Object.entries(t))N.test(n)?r[n]=O:r[n]=d(i,e);o=r}return e.delete(t),o}function B(t){let{tool_name:e,tool_input:o}=t;if(!e.startsWith("mcp__"))return[];let r=d(o??{}),n;try{n=JSON.stringify(r)}catch{n="{}"}let{value:i,truncated:a}=P(n,H),p=a?`{"tool_name":${JSON.stringify(e)},"params_raw":${JSON.stringify(i)},"truncated":true}`:`{"tool_name":${JSON.stringify(e)},"params":${i}}`;return[{type:"mcp_tool_call",category:"mcp_tool_call",data:s(p),priority:4}]}function C(t){if(t.tool_name!=="AskUserQuestion")return[];let e=t.tool_input.questions,o=Array.isArray(e)&&e.length>0?String(e[0].question??""):"",r=s(String(t.tool_response??"")),n=o?`Q: ${s(o)} \u2192 A: ${r}`:`answer: ${r}`;return[{type:"decision_question",category:"decision",data:s(n),priority:2}]}function L(t){if(t.tool_name!=="Agent")return[];if(!t.tool_response||t.tool_response.length===0)return[];let e=t.tool_response.length>500?t.tool_response.slice(0,500):t.tool_response;return[{type:"agent_finding",category:"agent-finding",data:s(e),priority:2}]}function W(t){let e=[g(t.tool_input),s(t.tool_response)].join(" ");if(e.length===0)return[];let o=new Set,r=e.match(/https?:\/\/[^\s)]+/g);if(r)for(let i of r)i=i.replace(/["'})\],;.]+$/,""),/localhost|127\.0\.0\.1/i.test(i)||o.add(i);let n=e.match(/(?<!\w)#(\d+)/g);if(n)for(let i of n)o.add(i);return o.size===0?[]:[{type:"external_ref",category:"external-ref",data:s(Array.from(o).join(", ")),priority:3}]}function M(t){if(t.tool_name!=="EnterWorktree")return[];let e=String(t.tool_input.name??"unnamed");return[{type:"worktree",category:"env",data:s(`entered worktree: ${e}`),priority:2}]}var j=[/\b(don'?t|do not|never|always|instead|rather|prefer)\b/i,/\b(use|switch to|go with|pick|choose)\s+\w+\s+(instead|over|not)\b/i,/\b(no,?\s+(use|do|try|make))\b/i,/\b(hayır|hayir|evet|böyle|boyle|degil|değil|yerine|kullan)\b/i];function D(t){return j.some(o=>o.test(t))?[{type:"decision",category:"decision",data:s(t),priority:2}]:[]}var F=[/\b(act as|you are|behave like|pretend|role of|persona)\b/i,/\b(senior|staff|principal|lead)\s+(engineer|developer|architect)\b/i,/\b(gibi davran|rolünde|olarak çalış)\b/i];function G(t){return F.some(o=>o.test(t))?[{type:"role",category:"role",data:s(t),priority:3}]:[]}var U=[{mode:"investigate",pattern:/\b(why|how does|explain|understand|what is|analyze|debug|look into)\b/i},{mode:"implement",pattern:/\b(create|add|build|implement|write|make|develop|fix)\b/i},{mode:"discuss",pattern:/\b(think about|consider|should we|what if|pros and cons|opinion)\b/i},{mode:"review",pattern:/\b(review|check|audit|verify|test|validate)\b/i}];function J(t){let e=U.find(({pattern:o})=>o.test(t));return e?[{type:"intent",category:"intent",data:s(e.mode),priority:4}]:[]}var q=[/\bblocked on\b/i,/\bwaiting for\b/i,/\bneed\s+\S+\s+before\b/i,/\bcan'?t proceed until\b/i,/\bdepends on\b/i,/\bblocked\b/i,/\bbekliyor\b/i,/\bbekliyorum\b/i],z=[/\bunblocked\b/i,/\bresolved\b/i,/\bgot the\s+\S+/i,/\bis ready now\b/i,/\bcan proceed\b/i];function K(t){let e=[];return z.some(n=>n.test(t))?(e.push({type:"blocker_resolved",category:"blocked-on",data:s(t),priority:2}),e):(q.some(n=>n.test(t))&&e.push({type:"blocker",category:"blocked-on",data:s(t),priority:2}),e)}function Q(t){return t.length<=1024?[]:[{type:"data",category:"data",data:s(t),priority:4}]}var c=null;function V(t){let{tool_name:e,tool_response:o}=t,r=String(o??"");if(u(t))return c={tool:e,error:r.slice(0,200),callsSince:0},[];if(!c)return[];if(c.callsSince++,c.callsSince>10)return c=null,[];if(!!u(t))return[];let i=e===c.tool,a=c.tool==="Read"&&(e==="Edit"||e==="Write"||e==="apply_patch");if(i||a){let p={type:"error_resolved",category:"error-resolution",data:s(`Error in ${c.tool}: ${c.error} \u2192 Fixed`),priority:2};return c=null,[p]}return[]}function et(){c=null}var l=[];function Y(t){return`${t.length}:${t.slice(0,20)}`}function Z(t){let{tool_name:e,tool_input:o}=t,r=Y(JSON.stringify(o).slice(0,200));if(l.push({tool:e,inputHash:r}),l.length>50&&l.splice(0,l.length-50),l.length<3)return[];let n=0;for(let i=l.length-1;i>=0&&(l[i].tool===e&&l[i].inputHash===r);i--)n++;return n>=3?(l.splice(l.length-n),[{type:"retry_detected",category:"iteration-loop",data:s(`${e} called ${n} times with similar input`),priority:2}]):[]}function ot(){l.length=0}var X={run_shell_command:"Bash",read_file:"Read",read_many_files:"Read",grep_search:"Grep",search_file_content:"Grep",web_fetch:"WebFetch",write_file:"Write",edit:"Edit",glob:"Glob",todo_write:"TodoWrite",ask_user_question:"AskUserQuestion",list_directory:"LS",save_memory:"Memory",skill:"Skill",exit_plan_mode:"ExitPlanMode",agent:"Agent",bash:"Bash",view:"Read",grep:"Grep",fetch:"WebFetch",shell:"Bash",shell_command:"Bash",exec_command:"Bash","container.exec":"Bash",local_shell:"Bash",grep_files:"Grep"};function tt(t){let e=X[t.tool_name];return!e||e===t.tool_name?t:{...t,tool_name:e}}function rt(t){try{let e=tt(t),o=[];return o.push(..._(e)),o.push(...m(e)),o.push(...S(e)),o.push(...E(e)),o.push(...R(e)),o.push(...v(e)),o.push(...x(e)),o.push(...T(e)),o.push(...I(e)),o.push(...$(e)),o.push(...B(e)),o.push(...C(e)),o.push(...A(e)),o.push(...M(e)),o.push(...L(e)),o.push(...W(e)),o.push(...V(e)),o.push(...Z(e)),o}catch{return[]}}function nt(t){try{let e=[];return e.push(...D(t)),e.push(...G(t)),e.push(...J(t)),e.push(...K(t)),e.push(...Q(t)),e}catch{return[]}}export{rt as extractEvents,nt as extractUserEvents,et as resetErrorResolutionState,ot as resetIterationLoopState};
1
+ function s(t){return t==null?"":String(t)}function h(t){return t==null?"":typeof t=="string"?t:JSON.stringify(t)}function u(t){let e=String(t.tool_response??""),n=t.tool_output?.isError===!0||t.tool_output?.is_error===!0;return t.tool_name==="Bash"&&/exit code [1-9]|error:|Error:|FAIL|failed/i.test(e)||n}function y(t){if(!t)return[];let e=[];for(let r of t.split(/\r?\n/)){if(r.startsWith("*** Add File: ")){e.push({path:r.slice(14).trim(),type:"file_write"});continue}if(r.startsWith("*** Update File: ")){e.push({path:r.slice(17).trim(),type:"file_edit"});continue}if(r.startsWith("*** Delete File: ")){e.push({path:r.slice(17).trim(),type:"file_edit"});continue}r.startsWith("*** Move to: ")&&e.push({path:r.slice(13).trim(),type:"file_edit"})}let n=new Set;return e.filter(r=>{if(!r.path)return!1;let o=`${r.type}:${r.path}`;return n.has(o)?!1:(n.add(o),!0)})}function _(t){return/(?:^|[/\\])\.claude[/\\]plans[/\\]/.test(t)}function E(t){let{tool_name:e,tool_input:n,tool_response:r}=t,o=[];if(e==="Read"){let i=String(n.file_path??"");return(/(?:CLAUDE|AGENTS(?:\.override)?|GEMINI|QWEN|KIRO)\.md$/i.test(i)||/\/copilot-instructions\.md$/i.test(i)||/\/context-mode\.mdc$/i.test(i)||/\.claude[\\/]/i.test(i)||/[\\/]memor(?:y|ies)[\\/][^\\/]+\.md$/i.test(i))&&(o.push({type:"rule",category:"rule",data:s(i),priority:1}),r&&r.length>0&&o.push({type:"rule_content",category:"rule",data:s(r),priority:1})),o.push({type:"file_read",category:"file",data:s(i),priority:1}),o}if(e==="Edit"){let i=String(n.file_path??"");return o.push({type:"file_edit",category:"file",data:s(i),priority:1}),o}if(e==="NotebookEdit"){let i=String(n.notebook_path??"");return o.push({type:"file_edit",category:"file",data:s(i),priority:1}),o}if(e==="Write"){let i=String(n.file_path??"");return o.push({type:"file_write",category:"file",data:s(i),priority:1}),o}if(e==="apply_patch"){if(u(t))return[];let i=y(String(n.command??n.patch??""));for(let a of i)o.push({type:a.type,category:"file",data:s(a.path),priority:1});return o}if(e==="Glob"){let i=String(n.pattern??"");return o.push({type:"file_glob",category:"file",data:s(i),priority:3}),o}if(e==="Grep"){let i=String(n.pattern??""),a=String(n.path??"");return o.push({type:"file_search",category:"file",data:s(`${i} in ${a}`),priority:3}),o}return o}function k(t){if(t.tool_name!=="Bash")return[];let n=String(t.tool_input.command??"").match(/\bcd\s+("([^"]+)"|'([^']+)'|(\S+))/);if(!n)return[];let r=n[2]??n[3]??n[4]??"";return[{type:"cwd",category:"cwd",data:s(r),priority:2}]}function A(t){let{tool_response:e}=t,n=String(e??"");return u(t)?[{type:"error_tool",category:"error",data:s(n),priority:2}]:[]}var R=[{pattern:/\bgit\s+checkout\b/,operation:"branch"},{pattern:/\bgit\s+commit\b/,operation:"commit"},{pattern:/\bgit\s+merge\s+\S+/,operation:"merge"},{pattern:/\bgit\s+rebase\b/,operation:"rebase"},{pattern:/\bgit\s+stash\b/,operation:"stash"},{pattern:/\bgit\s+push\b/,operation:"push"},{pattern:/\bgit\s+pull\b/,operation:"pull"},{pattern:/\bgit\s+log\b/,operation:"log"},{pattern:/\bgit\s+diff\b/,operation:"diff"},{pattern:/\bgit\s+status\b/,operation:"status"},{pattern:/\bgit\s+branch\b/,operation:"branch"},{pattern:/\bgit\s+reset\b/,operation:"reset"},{pattern:/\bgit\s+add\b/,operation:"add"},{pattern:/\bgit\s+cherry-pick\b/,operation:"cherry-pick"},{pattern:/\bgit\s+tag\b/,operation:"tag"},{pattern:/\bgit\s+fetch\b/,operation:"fetch"},{pattern:/\bgit\s+clone\b/,operation:"clone"},{pattern:/\bgit\s+worktree\b/,operation:"worktree"}];function v(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??""),n=R.find(r=>r.pattern.test(e));return n?[{type:"git",category:"git",data:s(n.operation),priority:2}]:[]}function T(t){return new Set(["TodoWrite","TaskCreate","TaskUpdate"]).has(t.tool_name)?[{type:t.tool_name==="TaskUpdate"?"task_update":t.tool_name==="TaskCreate"?"task_create":"task",category:"task",data:s(JSON.stringify(t.tool_input)),priority:1}]:[]}function x(t){if(t.tool_name==="EnterPlanMode")return[{type:"plan_enter",category:"plan",data:"entered plan mode",priority:2}];if(t.tool_name==="ExitPlanMode"){let e=[],n=t.tool_input.allowedPrompts,r=Array.isArray(n)&&n.length>0?`exited plan mode (allowed: ${h(n.map(i=>typeof i=="object"&&i!==null&&"prompt"in i?String(i.prompt):String(i)).join(", "))})`:"exited plan mode";e.push({type:"plan_exit",category:"plan",data:s(r),priority:2});let o=String(t.tool_response??"").toLowerCase();return o.includes("approved")||o.includes("approve")?e.push({type:"plan_approved",category:"plan",data:"plan approved by user",priority:1}):(o.includes("rejected")||o.includes("decline")||o.includes("denied"))&&e.push({type:"plan_rejected",category:"plan",data:s(`plan rejected: ${t.tool_response??""}`),priority:2}),e}if(t.tool_name==="Write"||t.tool_name==="Edit"){let e=String(t.tool_input.file_path??"");if(_(e))return[{type:"plan_file_write",category:"plan",data:s(`plan file: ${e.split(/[/\\]/).pop()??e}`),priority:2}]}return t.tool_name==="apply_patch"?u(t)?[]:y(String(t.tool_input.command??t.tool_input.patch??"")).filter(n=>_(n.path)).map(n=>({type:"plan_file_write",category:"plan",data:s(`plan file: ${n.path.split(/[/\\]/).pop()??n.path}`),priority:2})):[]}var I=[/\bsource\s+\S*activate\b/,/\bexport\s+\w+=/,/\bnvm\s+use\b/,/\bpyenv\s+(shell|local|global)\b/,/\bconda\s+activate\b/,/\brbenv\s+(shell|local|global)\b/,/\bnpm\s+install\b/,/\bnpm\s+ci\b/,/\bpip\s+install\b/,/\bbun\s+install\b/,/\byarn\s+(add|install)\b/,/\bpnpm\s+(add|install)\b/,/\bcargo\s+(install|add)\b/,/\bgo\s+(install|get)\b/,/\brustup\b/,/\basdf\b/,/\bvolta\b/,/\bdeno\s+install\b/];function w(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??"");if(!I.some(o=>o.test(e)))return[];let r=e.replace(/\bexport\s+(\w+)=\S*/g,"export $1=***");return[{type:"env",category:"env",data:s(r),priority:2}]}function C(t){if(t.tool_name!=="Skill")return[];let e=String(t.tool_input.skill??"");return[{type:"skill",category:"skill",data:s(e),priority:2}]}function H(t){if(!t.tool_response?.includes("Error")&&!t.tool_output?.isError)return[];let e=String(t.tool_response||""),n=[/not supported/i,/cannot/i,/does not support/i,/FAIL/i,/refused/i,/permission denied/i,/incompatible/i];for(let r of n){let o=e.match(r);if(o){let i=e.toLowerCase().indexOf(o[0].toLowerCase()),a=e.slice(Math.max(0,i-50),Math.min(e.length,i+200)).trim();return[{type:"constraint_discovered",category:"constraint",data:s(a),priority:2}]}}return[]}function L(t){if(t.tool_name!=="Agent")return[];let e=s(String(t.tool_input.prompt??t.tool_input.description??"")),n=t.tool_response?s(String(t.tool_response)):"",r=n.length>0;return[{type:r?"subagent_completed":"subagent_launched",category:"subagent",data:s(r?`[completed] ${e} \u2192 ${n}`:`[launched] ${e}`),priority:r?2:3}]}function N(t){let{tool_name:e,tool_input:n,tool_response:r}=t;if(!e.startsWith("mcp__"))return[];let o=e.split("__"),i=o[o.length-1]||e,a=Object.values(n).find(m=>typeof m=="string"),p=a?`: ${s(String(a))}`:"",S=r&&r.length>0?`
2
+ response: ${s(r)}`:"";return[{type:"mcp",category:"mcp",data:s(`${i}${p}${S}`),priority:3}]}var $=2048;function P(t,e){if(Buffer.byteLength(t,"utf8")<=e)return{value:t,truncated:!1};let n=Buffer.from(t,"utf8"),r=e;for(;r>0&&(n[r]&192)===128;)r--;return{value:n.subarray(0,r).toString("utf8"),truncated:!0}}var O=/(authorization|auth_token|access_token|refresh_token|bearer|token|secret|password|passwd|pwd|api[-_]?key|apikey|cookie|set-cookie|signature|private[-_]?key|client[-_]?secret|x[-_]?api[-_]?key)/i,M="[REDACTED]";function d(t,e=new WeakSet){if(t==null||typeof t!="object")return t;if(e.has(t))return"[CIRCULAR]";e.add(t);let n;if(Array.isArray(t))n=t.map(r=>d(r,e));else{let r={};for(let[o,i]of Object.entries(t))O.test(o)?r[o]=M:r[o]=d(i,e);n=r}return e.delete(t),n}function B(t){let{tool_name:e,tool_input:n}=t;if(!e.startsWith("mcp__"))return[];let r=d(n??{}),o;try{o=JSON.stringify(r)}catch{o="{}"}let{value:i,truncated:a}=P(o,$),p=a?`{"tool_name":${JSON.stringify(e)},"params_raw":${JSON.stringify(i)},"truncated":true}`:`{"tool_name":${JSON.stringify(e)},"params":${i}}`;return[{type:"mcp_tool_call",category:"mcp_tool_call",data:s(p),priority:4}]}function W(t){if(t.tool_name!=="AskUserQuestion")return[];let e=t.tool_input.questions,n=Array.isArray(e)&&e.length>0?String(e[0].question??""):"",r=s(String(t.tool_response??"")),o=n?`Q: ${s(n)} \u2192 A: ${r}`:`answer: ${r}`;return[{type:"decision_question",category:"decision",data:s(o),priority:2}]}function j(t){if(t.tool_name!=="Agent")return[];if(!t.tool_response||t.tool_response.length===0)return[];let e=t.tool_response.length>500?t.tool_response.slice(0,500):t.tool_response;return[{type:"agent_finding",category:"agent-finding",data:s(e),priority:2}]}function D(t){let e=[h(t.tool_input),s(t.tool_response)].join(" ");if(e.length===0)return[];let n=new Set,r=e.match(/https?:\/\/[^\s)]+/g);if(r)for(let i of r)i=i.replace(/["'})\],;.]+$/,""),/localhost|127\.0\.0\.1/i.test(i)||n.add(i);let o=e.match(/(?<!\w)#(\d+)/g);if(o)for(let i of o)n.add(i);return n.size===0?[]:[{type:"external_ref",category:"external-ref",data:s(Array.from(n).join(", ")),priority:3}]}function U(t){if(t.tool_name!=="EnterWorktree")return[];let e=String(t.tool_input.name??"unnamed");return[{type:"worktree",category:"env",data:s(`entered worktree: ${e}`),priority:2}]}var b=/[,;,;、،]/u,F=15,K=500;function G(t){if(f.test(t)||!g.test(t)||!b.test(t))return!1;let e=[...t].length;return e>=F&&e<=K}function J(t){let e=t.trim();return G(e)?[{type:"decision",category:"decision",data:s(t),priority:2}]:[]}var q=8,z=120,Q=new RegExp("\\p{L}+\\s+\\p{L}+","u"),V=new RegExp("\\p{L}{6,}","u");function X(t){let e=t.split(/[.!\n。!]/u)[0].trim();if(f.test(e)||b.test(e)||!g.test(e))return!1;let n=[...e].length;return n<q||n>z?!1:Q.test(e)||V.test(e)}function Y(t){let e=t.trim();return X(e)?[{type:"role",category:"role",data:s(t),priority:3}]:[]}var f=/[??؟¿]/u,g=new RegExp("\\p{L}","u"),Z=60;function tt(t){if(f.test(t)||!g.test(t))return!1;let e=[...t].length;return e>0&&e<Z}function et(t){let e=t.trim();if(!e)return[];let n;return f.test(e)?n="investigate":tt(e)&&(n="implement"),n?[{type:"intent",category:"intent",data:s(n),priority:4}]:[]}var nt=/(?:\bError\s*:|\bException\s*:|\bTraceback\b|\bat\s+\S+\s*\([^)]*:\d+:\d+\))/u,rt=/[✓✔✅☑🎉]/u,ot=/^\s*(?:fixed|resolved)\s*:/iu;function it(t){let e=[];return rt.test(t)||ot.test(t)?(e.push({type:"blocker_resolved",category:"blocked-on",data:s(t),priority:2}),e):(nt.test(t)&&e.push({type:"blocker",category:"blocked-on",data:s(t),priority:2}),e)}function st(t){return t.length<=1024?[]:[{type:"data",category:"data",data:s(t),priority:4}]}var c=null;function at(t){let{tool_name:e,tool_response:n}=t,r=String(n??"");if(u(t))return c={tool:e,error:r.slice(0,200),callsSince:0},[];if(!c)return[];if(c.callsSince++,c.callsSince>10)return c=null,[];if(!!u(t))return[];let i=e===c.tool,a=c.tool==="Read"&&(e==="Edit"||e==="Write"||e==="apply_patch");if(i||a){let p={type:"error_resolved",category:"error-resolution",data:s(`Error in ${c.tool}: ${c.error} \u2192 Fixed`),priority:2};return c=null,[p]}return[]}function ft(){c=null}var l=[];function ct(t){return`${t.length}:${t.slice(0,20)}`}function lt(t){let{tool_name:e,tool_input:n}=t,r=ct(JSON.stringify(n).slice(0,200));if(l.push({tool:e,inputHash:r}),l.length>50&&l.splice(0,l.length-50),l.length<3)return[];let o=0;for(let i=l.length-1;i>=0&&(l[i].tool===e&&l[i].inputHash===r);i--)o++;return o>=3?(l.splice(l.length-o),[{type:"retry_detected",category:"iteration-loop",data:s(`${e} called ${o} times with similar input`),priority:2}]):[]}function dt(){l.length=0}var pt={run_shell_command:"Bash",read_file:"Read",read_many_files:"Read",grep_search:"Grep",search_file_content:"Grep",web_fetch:"WebFetch",write_file:"Write",edit:"Edit",glob:"Glob",todo_write:"TodoWrite",ask_user_question:"AskUserQuestion",list_directory:"LS",save_memory:"Memory",skill:"Skill",exit_plan_mode:"ExitPlanMode",agent:"Agent",bash:"Bash",view:"Read",grep:"Grep",fetch:"WebFetch",shell:"Bash",shell_command:"Bash",exec_command:"Bash","container.exec":"Bash",local_shell:"Bash",grep_files:"Grep"};function ut(t){let e=pt[t.tool_name];return!e||e===t.tool_name?t:{...t,tool_name:e}}function gt(t){try{let e=ut(t),n=[];return n.push(...E(e)),n.push(...k(e)),n.push(...A(e)),n.push(...v(e)),n.push(...w(e)),n.push(...T(e)),n.push(...x(e)),n.push(...C(e)),n.push(...L(e)),n.push(...N(e)),n.push(...B(e)),n.push(...W(e)),n.push(...H(e)),n.push(...U(e)),n.push(...j(e)),n.push(...D(e)),n.push(...at(e)),n.push(...lt(e)),n}catch{return[]}}function _t(t){try{let e=[];return e.push(...J(t)),e.push(...Y(t)),e.push(...et(t)),e.push(...it(t)),e.push(...st(t)),e}catch{return[]}}export{gt as extractEvents,_t as extractUserEvents,ft as resetErrorResolutionState,dt as resetIterationLoopState};
@@ -1,30 +1,31 @@
1
- function a(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}var x=10;function h(t,r=4){return[...new Set(t.filter(o=>o.length>0))].slice(0,r).map(o=>o.length>80?o.slice(0,80):o)}function m(t,r){if(r.length===0)return"";let s=r.map(n=>`"${a(n)}"`).join(", ");return`
1
+ function a(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}var F=10;function h(t,r=4){return[...new Set(t.filter(o=>o.length>0))].slice(0,r).map(o=>o.length>80?o.slice(0,80):o)}function m(t,r){if(r.length===0)return"";let e=r.map(n=>`"${a(n)}"`).join(", ");return`
2
2
  For full details:
3
3
  ${a(t)}(
4
- queries: [${s}],
4
+ queries: [${e}],
5
5
  source: "session-events"
6
- )`}function D(t,r){if(t.length===0)return"";let s=new Map;for(let l of t){let S=l.data,p=s.get(S);p||(p={ops:new Map},s.set(S,p));let d;l.type==="file_write"?d="write":l.type==="file_read"?d="read":l.type==="file_edit"?d="edit":d=l.type,p.ops.set(d,(p.ops.get(d)??0)+1)}let o=Array.from(s.entries()).slice(-x),c=[],i=[];for(let[l,{ops:S}]of o){let p=Array.from(S.entries()).map(([b,y])=>`${b}\xD7${y}`).join(", "),d=l.split("/").pop()??l;c.push(` ${a(d)} (${a(p)})`),i.push(`${d} ${Array.from(S.keys()).join(" ")}`)}let e=h(i);return[` <files count="${s.size}">`,...c,m(r,e)," </files>"].join(`
7
- `)}function R(t,r){if(t.length===0)return"";let s=[],n=[];for(let i of t)s.push(` ${a(i.data)}`),n.push(i.data);let o=h(n);return[` <errors count="${t.length}">`,...s,m(r,o)," </errors>"].join(`
8
- `)}function F(t,r){if(t.length===0)return"";let s=new Set,n=[],o=[];for(let e of t)s.has(e.data)||(s.add(e.data),n.push(` ${a(e.data)}`),o.push(e.data));if(n.length===0)return"";let c=h(o);return[` <decisions count="${n.length}">`,...n,m(r,c)," </decisions>"].join(`
9
- `)}function B(t,r){if(t.length===0)return"";let s=new Set,n=[],o=[];for(let e of t)s.has(e.data)||(s.add(e.data),e.type==="rule_content"?n.push(` ${a(e.data)}`):n.push(` ${a(e.data)}`),o.push(e.data));if(n.length===0)return"";let c=h(o);return[` <rules count="${n.length}">`,...n,m(r,c)," </rules>"].join(`
10
- `)}function J(t,r){if(t.length===0)return"";let s=[],n=[];for(let i of t)s.push(` ${a(i.data)}`),n.push(i.data);let o=h(n);return[` <git count="${t.length}">`,...s,m(r,o)," </git>"].join(`
11
- `)}function X(t){if(t.length===0)return"";let r=[],s={};for(let e of t)try{let u=JSON.parse(e.data);typeof u.subject=="string"?r.push(u.subject):typeof u.taskId=="string"&&typeof u.status=="string"&&(s[u.taskId]=u.status)}catch{}if(r.length===0)return"";let n=new Set(["completed","deleted","failed"]),o=Object.keys(s).sort((e,u)=>Number(e)-Number(u)),c=[];for(let e=0;e<r.length;e++){let u=o[e],l=u?s[u]??"pending":"pending";n.has(l)||c.push(r[e])}if(c.length===0)return"";let i=[];for(let e of c)i.push(` [pending] ${a(e)}`);return i.join(`
12
- `)}function z(t,r){let s=X(t);if(!s)return"";let n=[];for(let e of t)try{let u=JSON.parse(e.data);typeof u.subject=="string"&&n.push(u.subject)}catch{}let o=h(n);return[` <task_state count="${s.split(`
13
- `).length}">`,s,m(r,o)," </task_state>"].join(`
14
- `)}function G(t,r,s){if(t.length===0&&r.length===0)return"";let n=[],o=[];if(t.length>0){let e=t[t.length-1];n.push(` cwd: ${a(e.data)}`),o.push("working directory")}for(let e of r)n.push(` ${a(e.data)}`),o.push(e.data);let c=h(o);return[" <environment>",...n,m(s,c)," </environment>"].join(`
15
- `)}function P(t,r){if(t.length===0)return"";let s=[],n=[];for(let i of t){let e=i.type==="subagent_completed"?"completed":i.type==="subagent_launched"?"launched":"unknown";s.push(` [${e}] ${a(i.data)}`),n.push(`subagent ${i.data}`)}let o=h(n);return[` <subagents count="${t.length}">`,...s,m(r,o)," </subagents>"].join(`
16
- `)}function Q(t,r){if(t.length===0)return"";let s=new Map;for(let e of t){let u=e.data.split(":")[0].trim();s.set(u,(s.get(u)??0)+1)}let n=[],o=[];for(let[e,u]of s)n.push(` ${a(e)} (${u}\xD7)`),o.push(`skill ${e} invocation`);let c=h(o);return[` <skills count="${t.length}">`,...n,m(r,c)," </skills>"].join(`
17
- `)}function U(t,r){if(t.length===0)return"";let s=new Set,n=[],o=[];for(let e of t)s.has(e.data)||(s.add(e.data),n.push(` ${a(e.data)}`),o.push(e.data));if(n.length===0)return"";let c=h(o);return[` <roles count="${n.length}">`,...n,m(r,c)," </roles>"].join(`
18
- `)}function V(t){if(t.length===0)return"";let r=t[t.length-1];return` <intent mode="${a(r.data)}"/>`}function W(t,r){let s=r?.compactCount??1,n=r?.searchTool??"ctx_search",o=new Date().toISOString(),c=[],i=[],e=[],u=[],l=[],S=[],p=[],d=[],b=[],y=[],$=[],k=[];for(let f of t)switch(f.category){case"file":c.push(f);break;case"task":i.push(f);break;case"rule":e.push(f);break;case"decision":u.push(f);break;case"cwd":l.push(f);break;case"error":S.push(f);break;case"env":p.push(f);break;case"git":d.push(f);break;case"subagent":b.push(f);break;case"intent":y.push(f);break;case"skill":$.push(f);break;case"role":k.push(f);break}let g=[];g.push(` <how_to_search>
6
+ )`}function x(t,r){if(t.length===0)return"";let e=new Map;for(let f of t){let S=f.data,p=e.get(S);p||(p={ops:new Map},e.set(S,p));let d;f.type==="file_write"?d="write":f.type==="file_read"?d="read":f.type==="file_edit"?d="edit":d=f.type,p.ops.set(d,(p.ops.get(d)??0)+1)}let o=Array.from(e.entries()).slice(-F),c=[],i=[];for(let[f,{ops:S}]of o){let p=Array.from(S.entries()).map(([b,y])=>`${b}\xD7${y}`).join(", "),d=f.split("/").pop()??f;c.push(` ${a(d)} (${a(p)})`),i.push(`${d} ${Array.from(S.keys()).join(" ")}`)}let s=h(i);return[` <files count="${e.size}">`,...c,m(r,s)," </files>"].join(`
7
+ `)}function B(t,r){if(t.length===0)return"";let e=[],n=[];for(let i of t)e.push(` ${a(i.data)}`),n.push(i.data);let o=h(n);return[` <errors count="${t.length}">`,...e,m(r,o)," </errors>"].join(`
8
+ `)}function J(t,r){if(t.length===0)return"";let e=new Set,n=[],o=[];for(let s of t)e.has(s.data)||(e.add(s.data),n.push(` ${a(s.data)}`),o.push(s.data));if(n.length===0)return"";let c=h(o);return[` <decisions count="${n.length}">`,...n,m(r,c)," </decisions>"].join(`
9
+ `)}function X(t,r){if(t.length===0)return"";let e=new Set,n=[],o=[];for(let s of t)e.has(s.data)||(e.add(s.data),s.type==="rule_content"?n.push(` ${a(s.data)}`):n.push(` ${a(s.data)}`),o.push(s.data));if(n.length===0)return"";let c=h(o);return[` <rules count="${n.length}">`,...n,m(r,c)," </rules>"].join(`
10
+ `)}function G(t,r){if(t.length===0)return"";let e=[],n=[];for(let i of t)e.push(` ${a(i.data)}`),n.push(i.data);let o=h(n);return[` <git count="${t.length}">`,...e,m(r,o)," </git>"].join(`
11
+ `)}function z(t){if(t.length===0)return"";let r=[],e={};for(let s of t)try{let u=JSON.parse(s.data);typeof u.subject=="string"?r.push(u.subject):typeof u.taskId=="string"&&typeof u.status=="string"&&(e[u.taskId]=u.status)}catch{}if(r.length===0)return"";let n=new Set(["completed","deleted","failed"]),o=Object.keys(e).sort((s,u)=>Number(s)-Number(u)),c=[];for(let s=0;s<r.length;s++){let u=o[s],f=u?e[u]??"pending":"pending";n.has(f)||c.push(r[s])}if(c.length===0)return"";let i=[];for(let s of c)i.push(` [pending] ${a(s)}`);return i.join(`
12
+ `)}function H(t,r){let e=z(t);if(!e)return"";let n=[];for(let s of t)try{let u=JSON.parse(s.data);typeof u.subject=="string"&&n.push(u.subject)}catch{}let o=h(n);return[` <task_state count="${e.split(`
13
+ `).length}">`,e,m(r,o)," </task_state>"].join(`
14
+ `)}function P(t,r,e){if(t.length===0&&r.length===0)return"";let n=[],o=[];if(t.length>0){let s=t[t.length-1];n.push(` cwd: ${a(s.data)}`),o.push("working directory")}for(let s of r)n.push(` ${a(s.data)}`),o.push(s.data);let c=h(o);return[" <environment>",...n,m(e,c)," </environment>"].join(`
15
+ `)}function Q(t,r){if(t.length===0)return"";let e=[],n=[];for(let i of t){let s=i.type==="subagent_completed"?"completed":i.type==="subagent_launched"?"launched":"unknown";e.push(` [${s}] ${a(i.data)}`),n.push(`subagent ${i.data}`)}let o=h(n);return[` <subagents count="${t.length}">`,...e,m(r,o)," </subagents>"].join(`
16
+ `)}function U(t,r){if(t.length===0)return"";let e=new Map;for(let s of t){let u=s.data.split(":")[0].trim();e.set(u,(e.get(u)??0)+1)}let n=[],o=[];for(let[s,u]of e)n.push(` ${a(s)} (${u}\xD7)`),o.push(`skill ${s} invocation`);let c=h(o);return[` <skills count="${t.length}">`,...n,m(r,c)," </skills>"].join(`
17
+ `)}function V(t,r){if(t.length===0)return"";let e=new Set,n=[],o=[];for(let s of t)e.has(s.data)||(e.add(s.data),n.push(` ${a(s.data)}`),o.push(s.data));if(n.length===0)return"";let c=h(o);return[` <roles count="${n.length}">`,...n,m(r,c)," </roles>"].join(`
18
+ `)}function K(t){if(t.length===0)return"";let r=t[t.length-1];return` <intent mode="${a(r.data)}"/>`}var W=3,Y=400;function Z(t,r){let e=[...t];return e.length<=r?t:e.slice(0,r).join("")}function tt(t){if(t.length===0)return"";let e=t.slice(-W).map(n=>{let o=Z(n.data??"",Y);return o?` <message>${a(o)}</message>`:""}).filter(Boolean);return e.length===0?"":[` <recent_user_messages count="${e.length}">`,...e," </recent_user_messages>"].join(`
19
+ `)}function st(t,r){let e=r?.compactCount??1,n=r?.searchTool??"ctx_search",o=new Date().toISOString(),c=[],i=[],s=[],u=[],f=[],S=[],p=[],d=[],b=[],y=[],$=[],k=[],v=[];for(let g of t)switch(g.category){case"file":c.push(g);break;case"task":i.push(g);break;case"rule":s.push(g);break;case"decision":u.push(g);break;case"cwd":f.push(g);break;case"error":S.push(g);break;case"env":p.push(g);break;case"git":d.push(g);break;case"subagent":b.push(g);break;case"intent":y.push(g);break;case"skill":$.push(g);break;case"role":k.push(g);break;case"user-prompt":v.push(g);break}let l=[];l.push(` <how_to_search>
19
20
  Each section below contains a summary of prior work.
20
21
  For FULL DETAILS, run the exact tool call shown under each section.
21
22
  Do NOT ask the user to re-explain prior work. Search first.
22
23
  Do NOT invent your own queries \u2014 use the ones provided.
23
- </how_to_search>`);let v=D(c,n);v&&g.push(v);let w=R(S,n);w&&g.push(w);let E=F(u,n);E&&g.push(E);let q=B(e,n);q&&g.push(q);let L=J(d,n);L&&g.push(L);let j=z(i,n);j&&g.push(j);let _=G(l,p,n);_&&g.push(_);let T=P(b,n);T&&g.push(T);let C=Q($,n);C&&g.push(C);let O=U(k,n);O&&g.push(O);let I=V(y);I&&g.push(I);let N=`<session_resume events="${t.length}" compact_count="${s}" generated_at="${o}">`,M="</session_resume>",A=g.join(`
24
+ </how_to_search>`);let E=x(c,n);E&&l.push(E);let _=B(S,n);_&&l.push(_);let w=J(u,n);w&&l.push(w);let q=X(s,n);q&&l.push(q);let j=G(d,n);j&&l.push(j);let L=H(i,n);L&&l.push(L);let T=P(f,p,n);T&&l.push(T);let C=Q(b,n);C&&l.push(C);let M=U($,n);M&&l.push(M);let I=V(k,n);I&&l.push(I);let N=K(y);N&&l.push(N);let A=tt(v);A&&l.push(A);let O=`<session_resume events="${t.length}" compact_count="${e}" generated_at="${o}">`,R="</session_resume>",D=l.join(`
24
25
 
25
- `);return A?`${N}
26
+ `);return D?`${O}
26
27
 
27
- ${A}
28
+ ${D}
28
29
 
29
- ${M}`:`${N}
30
- ${M}`}export{W as buildResumeSnapshot,X as renderTaskState};
30
+ ${R}`:`${O}
31
+ ${R}`}export{st as buildResumeSnapshot,z as renderTaskState};
@@ -3,7 +3,7 @@
3
3
  "name": "Context Mode",
4
4
  "kind": "tool",
5
5
  "description": "OpenClaw plugin that saves 98% of your context window. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and intent-driven search.",
6
- "version": "1.0.121",
6
+ "version": "1.0.123",
7
7
  "sandbox": {
8
8
  "mode": "permissive",
9
9
  "filesystem_access": "full",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context-mode",
3
- "version": "1.0.121",
3
+ "version": "1.0.123",
4
4
  "type": "module",
5
5
  "description": "MCP plugin that saves 98% of your context window. Works with Claude Code, Gemini CLI, VS Code Copilot, OpenCode, and Codex CLI. Sandboxed code execution, FTS5 knowledge base, and intent-driven search.",
6
6
  "author": "Mert Koseoğlu",
@@ -74,7 +74,6 @@
74
74
  "skills",
75
75
  ".claude-plugin",
76
76
  ".openclaw-plugin",
77
- ".mcp.json",
78
77
  "openclaw.plugin.json",
79
78
  "start.mjs",
80
79
  "scripts/postinstall.mjs",
@@ -84,8 +83,9 @@
84
83
  "LICENSE"
85
84
  ],
86
85
  "scripts": {
87
- "build": "tsc && node -e \"if(process.platform!=='win32'){require('fs').chmodSync('build/cli.js',0o755)}\" && npm run bundle && npm run assert-bundle",
86
+ "build": "tsc && node -e \"if(process.platform!=='win32'){require('fs').chmodSync('build/cli.js',0o755)}\" && npm run bundle && npm run assert-bundle && npm run assert-asymmetric-drift",
88
87
  "assert-bundle": "node scripts/assert-bundle.mjs server.bundle.mjs cli.bundle.mjs hooks/session-extract.bundle.mjs hooks/session-snapshot.bundle.mjs hooks/session-db.bundle.mjs",
88
+ "assert-asymmetric-drift": "node scripts/assert-asymmetric-drift.mjs",
89
89
  "bundle": "esbuild src/server.ts --bundle --platform=node --target=node18 --format=esm --outfile=server.bundle.mjs --external:better-sqlite3 --external:turndown --external:turndown-plugin-gfm --external:@mixmark-io/domino --minify && esbuild src/cli.ts --bundle --platform=node --target=node18 --format=esm --outfile=cli.bundle.mjs --external:better-sqlite3 --minify && esbuild src/session/extract.ts --bundle --platform=node --target=node18 --format=esm --outfile=hooks/session-extract.bundle.mjs --minify && esbuild src/session/snapshot.ts --bundle --platform=node --target=node18 --format=esm --outfile=hooks/session-snapshot.bundle.mjs --minify && esbuild src/session/db.ts --bundle --platform=node --target=node18 --format=esm --outfile=hooks/session-db.bundle.mjs --external:better-sqlite3 --minify",
90
90
  "version-sync": "node scripts/version-sync.mjs",
91
91
  "version": "node scripts/version-sync.mjs && git add package.json .claude-plugin/plugin.json .claude-plugin/marketplace.json .cursor-plugin/plugin.json .codex-plugin/plugin.json .openclaw-plugin/openclaw.plugin.json .openclaw-plugin/package.json openclaw.plugin.json .pi/extensions/context-mode/package.json",