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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.openclaw-plugin/openclaw.plugin.json +1 -1
- package/.openclaw-plugin/package.json +1 -1
- package/README.md +4 -4
- package/build/adapters/claude-code/hooks.d.ts +16 -1
- package/build/adapters/claude-code/hooks.js +16 -0
- package/build/adapters/claude-code/index.js +2 -11
- package/build/adapters/client-map.js +6 -0
- package/build/adapters/codex/hooks.d.ts +19 -0
- package/build/adapters/codex/hooks.js +22 -0
- package/build/adapters/codex/index.js +8 -1
- package/build/adapters/copilot-base.d.ts +17 -1
- package/build/adapters/copilot-base.js +18 -2
- package/build/adapters/cursor/hooks.d.ts +14 -1
- package/build/adapters/cursor/hooks.js +14 -0
- package/build/adapters/detect.d.ts +12 -2
- package/build/adapters/detect.js +96 -13
- package/build/adapters/gemini-cli/hooks.d.ts +16 -0
- package/build/adapters/gemini-cli/hooks.js +19 -0
- package/build/adapters/gemini-cli/index.js +4 -2
- package/build/adapters/kiro/hooks.d.ts +16 -1
- package/build/adapters/kiro/hooks.js +19 -0
- package/build/adapters/pi/extension.d.ts +9 -0
- package/build/adapters/pi/extension.js +52 -1
- package/build/adapters/qwen-code/hooks.d.ts +26 -0
- package/build/adapters/qwen-code/hooks.js +29 -0
- package/build/adapters/qwen-code/index.js +6 -0
- package/build/cli.js +46 -5
- package/build/executor.js +18 -3
- package/build/lifecycle.d.ts +15 -0
- package/build/lifecycle.js +24 -1
- package/build/runtime.js +34 -13
- package/build/server.js +17 -2
- package/build/session/extract.js +150 -48
- package/build/session/snapshot.js +46 -0
- package/cli.bundle.mjs +151 -150
- package/configs/codex/hooks.json +1 -1
- package/configs/cursor/hooks.json +1 -1
- package/configs/kiro/agent.json +1 -1
- package/hooks/core/routing.mjs +56 -1
- package/hooks/cursor/hooks.json +1 -1
- package/hooks/ensure-deps.mjs +45 -10
- package/hooks/hooks.json +9 -0
- package/hooks/routing-block.mjs +5 -0
- package/hooks/session-extract.bundle.mjs +2 -2
- package/hooks/session-snapshot.bundle.mjs +21 -20
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -3
- package/scripts/heal-better-sqlite3.mjs +188 -10
- package/scripts/heal-installed-plugins.mjs +111 -0
- package/scripts/postinstall.mjs +35 -9
- package/server.bundle.mjs +118 -118
- package/start.mjs +14 -1
- package/.mcp.json +0 -8
package/configs/codex/hooks.json
CHANGED
|
@@ -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": [
|
package/configs/kiro/agent.json
CHANGED
|
@@ -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
|
],
|
package/hooks/core/routing.mjs
CHANGED
|
@@ -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
|
}
|
package/hooks/cursor/hooks.json
CHANGED
|
@@ -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": [
|
package/hooks/ensure-deps.mjs
CHANGED
|
@@ -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
|
-
//
|
|
116
|
-
|
|
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
|
-
//
|
|
145
|
-
//
|
|
146
|
-
|
|
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": [
|
package/hooks/routing-block.mjs
CHANGED
|
@@ -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
|
|
2
|
-
response: ${s(r)}`:"";return[{type:"mcp",category:"mcp",data:s(`${i}${p}${
|
|
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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var
|
|
1
|
+
function a(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}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: [${
|
|
4
|
+
queries: [${e}],
|
|
5
5
|
source: "session-events"
|
|
6
|
-
)`}function
|
|
7
|
-
`)}function
|
|
8
|
-
`)}function
|
|
9
|
-
`)}function
|
|
10
|
-
`)}function
|
|
11
|
-
`)}function
|
|
12
|
-
`)}function
|
|
13
|
-
`).length}">`,
|
|
14
|
-
`)}function
|
|
15
|
-
`)}function
|
|
16
|
-
`)}function
|
|
17
|
-
`)}function
|
|
18
|
-
`)}function
|
|
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
|
|
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
|
|
26
|
+
`);return D?`${O}
|
|
26
27
|
|
|
27
|
-
${
|
|
28
|
+
${D}
|
|
28
29
|
|
|
29
|
-
${
|
|
30
|
-
${
|
|
30
|
+
${R}`:`${O}
|
|
31
|
+
${R}`}export{st as buildResumeSnapshot,z as renderTaskState};
|
package/openclaw.plugin.json
CHANGED
|
@@ -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.
|
|
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.
|
|
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",
|