context-mode 1.0.150 → 1.0.152
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/.codex-plugin/mcp.json +5 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.openclaw-plugin/openclaw.plugin.json +16 -1
- package/.openclaw-plugin/package.json +1 -1
- package/README.md +89 -3
- package/build/adapters/claude-code/hooks.js +2 -2
- package/build/adapters/claude-code/index.js +14 -13
- package/build/adapters/client-map.js +3 -0
- package/build/adapters/detect.js +13 -1
- package/build/adapters/gemini-cli/hooks.d.ts +10 -0
- package/build/adapters/gemini-cli/hooks.js +12 -2
- package/build/adapters/gemini-cli/index.d.ts +21 -1
- package/build/adapters/gemini-cli/index.js +37 -1
- package/build/adapters/kimi/config.d.ts +8 -0
- package/build/adapters/kimi/config.js +8 -0
- package/build/adapters/kimi/hooks.d.ts +28 -0
- package/build/adapters/kimi/hooks.js +34 -0
- package/build/adapters/kimi/index.d.ts +66 -0
- package/build/adapters/kimi/index.js +537 -0
- package/build/adapters/kimi/paths.d.ts +1 -0
- package/build/adapters/kimi/paths.js +12 -0
- package/build/adapters/kiro/hooks.js +2 -2
- package/build/adapters/openclaw/plugin.d.ts +14 -13
- package/build/adapters/openclaw/plugin.js +140 -40
- package/build/adapters/opencode/plugin.js +4 -3
- package/build/adapters/opencode/zod3tov4.js +8 -8
- package/build/adapters/pi/extension.js +9 -24
- package/build/adapters/pi/mcp-bridge.js +37 -0
- package/build/adapters/qwen-code/index.js +7 -7
- package/build/adapters/types.d.ts +39 -2
- package/build/adapters/types.js +55 -2
- package/build/adapters/vscode-copilot/index.js +13 -1
- package/build/cli.js +433 -25
- package/build/executor.js +6 -3
- package/build/runtime.d.ts +81 -1
- package/build/runtime.js +195 -9
- package/build/search/ctx-search-schema.d.ts +90 -0
- package/build/search/ctx-search-schema.js +135 -0
- package/build/search/unified.d.ts +12 -0
- package/build/search/unified.js +17 -2
- package/build/server.d.ts +2 -1
- package/build/server.js +378 -97
- package/build/session/analytics.d.ts +36 -13
- package/build/session/analytics.js +123 -26
- package/build/session/db.d.ts +24 -0
- package/build/session/db.js +41 -0
- package/build/session/extract.js +30 -0
- package/build/session/snapshot.js +24 -0
- package/build/store.d.ts +12 -1
- package/build/store.js +72 -20
- package/build/types.d.ts +7 -0
- package/build/util/project-dir.d.ts +19 -16
- package/build/util/project-dir.js +80 -45
- package/cli.bundle.mjs +371 -320
- package/configs/kimi/hooks.json +54 -0
- package/configs/pi/AGENTS.md +3 -85
- package/hooks/cache-heal-utils.mjs +148 -0
- package/hooks/core/formatters.mjs +26 -0
- package/hooks/core/routing.mjs +9 -1
- package/hooks/core/stdin.mjs +74 -3
- package/hooks/core/tool-naming.mjs +1 -0
- package/hooks/heal-partial-install.mjs +712 -0
- package/hooks/kimi/platform.mjs +1 -0
- package/hooks/kimi/posttooluse.mjs +72 -0
- package/hooks/kimi/precompact.mjs +80 -0
- package/hooks/kimi/pretooluse.mjs +42 -0
- package/hooks/kimi/sessionend.mjs +61 -0
- package/hooks/kimi/sessionstart.mjs +113 -0
- package/hooks/kimi/stop.mjs +61 -0
- package/hooks/kimi/userpromptsubmit.mjs +90 -0
- package/hooks/normalize-hooks.mjs +66 -12
- package/hooks/routing-block.mjs +8 -2
- package/hooks/security.bundle.mjs +1 -1
- package/hooks/session-db.bundle.mjs +6 -4
- package/hooks/session-extract.bundle.mjs +2 -2
- package/hooks/session-helpers.mjs +93 -3
- package/hooks/session-snapshot.bundle.mjs +20 -19
- package/hooks/sessionstart.mjs +64 -0
- package/insight/server.mjs +15 -3
- package/openclaw.plugin.json +16 -1
- package/package.json +1 -1
- package/scripts/heal-installed-plugins.mjs +31 -10
- package/scripts/postinstall.mjs +10 -0
- package/server.bundle.mjs +206 -157
- package/skills/ctx-index/SKILL.md +46 -0
- package/skills/ctx-search/SKILL.md +35 -0
- package/start.mjs +84 -11
- package/build/cache-heal.d.ts +0 -48
- package/build/cache-heal.js +0 -150
- package/build/concurrency/runPool.d.ts +0 -36
- package/build/concurrency/runPool.js +0 -51
- package/build/openclaw/mcp-tools.d.ts +0 -54
- package/build/openclaw/mcp-tools.js +0 -198
- package/build/openclaw/workspace-router.d.ts +0 -29
- package/build/openclaw/workspace-router.js +0 -64
- package/build/openclaw-plugin.d.ts +0 -130
- package/build/openclaw-plugin.js +0 -626
- package/build/opencode-plugin.d.ts +0 -122
- package/build/opencode-plugin.js +0 -375
- package/build/pi-extension.d.ts +0 -14
- package/build/pi-extension.js +0 -451
- package/build/routing-block.d.ts +0 -8
- package/build/routing-block.js +0 -86
- package/build/tool-naming.d.ts +0 -4
- package/build/tool-naming.js +0 -24
|
@@ -1 +1 @@
|
|
|
1
|
-
var h=(n,t)=>()=>(n&&(t=n(n=0)),t);var _,I=h(()=>{"use strict";_={"claude-code":"claude-code","gemini-cli-mcp-client":"gemini-cli","antigravity-client":"antigravity","cursor-vscode":"cursor","Visual-Studio-Code":"vscode-copilot","JetBrains Client":"jetbrains-copilot","IntelliJ IDEA":"jetbrains-copilot",PyCharm:"jetbrains-copilot",Codex:"codex","codex-mcp-client":"codex","Kilo Code":"kilo","Kiro CLI":"kiro","Pi CLI":"pi","Pi Coding Agent":"pi","omp-coding-agent":"omp",Zed:"zed",zed:"zed","qwen-code":"qwen-code","qwen-cli-mcp-client":"qwen-code"}});import{existsSync as l,readFileSync as N}from"node:fs";import{resolve as a}from"node:path";import{homedir as S}from"node:os";function L(){if(f!==null)return f!=="miss"&&f.hasCM;try{let n=a(S(),".claude","plugins","installed_plugins.json"),t=N(n,"utf-8"),e=JSON.parse(t),r=[...Object.keys(e.plugins??{}),...Object.keys(e.enabledPlugins??{})].some(i=>i.includes("context-mode"));return f={hasCM:r},r}catch{return f="miss",!1}}function A(n){switch(n){case"claude-code":return[".claude"];case"gemini-cli":return[".gemini"];case"antigravity":return[".gemini"];case"openclaw":return[".openclaw"];case"codex":return[".codex"];case"cursor":return[".cursor"];case"vscode-copilot":return[".vscode"];case"kiro":return[".kiro"];case"pi":return[".pi"];case"omp":return[".omp"];case"qwen-code":return[".qwen"];case"kilo":return[".config","kilo"];case"opencode":return[".config","opencode"];case"zed":return[".config","zed"];case"jetbrains-copilot":return[".config","JetBrains"];default:return null}}function O(n){if(n?.name){let o=_[n.name];if(o)return{platform:o,confidence:"high",reason:`MCP clientInfo.name="${n.name}"`};if(n.name.startsWith("qwen-cli-mcp-client"))return{platform:"qwen-code",confidence:"high",reason:`MCP clientInfo.name="${n.name}" (qwen-cli pattern)`}}let t=process.env.CONTEXT_MODE_PLATFORM;if(t&&["claude-code","gemini-cli","kilo","opencode","codex","vscode-copilot","jetbrains-copilot","cursor","antigravity","kiro","pi","omp","zed","qwen-code"].includes(t))return{platform:t,confidence:"high",reason:`CONTEXT_MODE_PLATFORM=${t} override`};for(let[o,r]of F)if(r.some(i=>i.detect!==!1&&process.env[i.name]))return o==="vscode-copilot"&&L()?{platform:"claude-code",confidence:"high",reason:"VSCODE_PID set but ~/.claude/plugins/installed_plugins.json lists context-mode (issue #539 fallback)"}:{platform:o,confidence:"high",reason:`${r.filter(i=>i.detect!==!1).map(i=>i.name).join(" or ")} env var set`};let e=S();return l(a(e,".claude"))?{platform:"claude-code",confidence:"medium",reason:"~/.claude/ directory exists"}:l(a(e,".gemini"))?{platform:"gemini-cli",confidence:"medium",reason:"~/.gemini/ directory exists"}:l(a(e,".codex"))?{platform:"codex",confidence:"medium",reason:"~/.codex/ directory exists"}:l(a(e,".kiro"))?{platform:"kiro",confidence:"medium",reason:"~/.kiro/ directory exists"}:l(a(e,".omp"))?{platform:"omp",confidence:"medium",reason:"~/.omp/ directory exists"}:l(a(e,".pi"))?{platform:"pi",confidence:"medium",reason:"~/.pi/ directory exists"}:l(a(e,".qwen"))?{platform:"qwen-code",confidence:"medium",reason:"~/.qwen/ directory exists"}:l(a(e,".openclaw"))?{platform:"openclaw",confidence:"medium",reason:"~/.openclaw/ directory exists"}:l(a(e,".cursor"))?{platform:"cursor",confidence:"medium",reason:"~/.cursor/ directory exists"}:l(a(e,".config","kilo"))?{platform:"kilo",confidence:"medium",reason:"~/.config/kilo/ directory exists"}:l(a(e,".config","JetBrains"))?{platform:"jetbrains-copilot",confidence:"medium",reason:"~/.config/JetBrains/ directory exists"}:l(a(e,".config","opencode"))?{platform:"opencode",confidence:"medium",reason:"~/.config/opencode/ directory exists"}:l(a(e,".config","zed"))?{platform:"zed",confidence:"medium",reason:"~/.config/zed/ directory exists"}:{platform:"claude-code",confidence:"low",reason:"No platform detected, defaulting to Claude Code"}}var f,M,F,R=h(()=>{"use strict";I();f=null;M=[["claude-code",[{name:"CLAUDE_CODE_ENTRYPOINT",role:"identification"},{name:"CLAUDE_PLUGIN_ROOT",role:"identification"},{name:"CLAUDE_PROJECT_DIR",role:"workspace"},{name:"CLAUDE_SESSION_ID",role:"identification"}]],["antigravity",[{name:"ANTIGRAVITY_CLI_ALIAS",role:"identification"}]],["cursor",[{name:"CURSOR_CWD",role:"workspace"},{name:"CURSOR_TRACE_ID",role:"identification"},{name:"CURSOR_CLI",role:"identification"}]],["kilo",[{name:"KILO",role:"identification"},{name:"KILO_PID",role:"identification"}]],["opencode",[{name:"OPENCODE_PROJECT_DIR",role:"workspace"},{name:"OPENCODE_CLIENT",role:"identification"},{name:"OPENCODE_TERMINAL",role:"identification"},{name:"OPENCODE",role:"identification"},{name:"OPENCODE_PID",role:"identification"}]],["zed",[{name:"ZED_SESSION_ID",role:"identification"},{name:"ZED_TERM",role:"identification"}]],["codex",[{name:"CODEX_THREAD_ID",role:"identification"},{name:"CODEX_CI",role:"identification"}]],["gemini-cli",[{name:"GEMINI_PROJECT_DIR",role:"workspace"},{name:"GEMINI_CLI",role:"identification"}]],["vscode-copilot",[{name:"VSCODE_CWD",role:"workspace"},{name:"VSCODE_PID",role:"identification"}]],["jetbrains-copilot",[{name:"IDEA_INITIAL_DIRECTORY",role:"workspace"}]],["qwen-code",[{name:"QWEN_PROJECT_DIR",role:"workspace"}]],["omp",[{name:"PI_CODING_AGENT_DIR",role:"workspace"}]],["pi",[{name:"PI_WORKSPACE_DIR",role:"workspace",detect:!1},{name:"PI_PROJECT_DIR",role:"workspace",detect:!1},{name:"PI_CONFIG_DIR",role:"identification"},{name:"PI_SESSION_FILE",role:"identification"},{name:"PI_COMPILED",role:"identification"}]]],F=new Map(M)});import{resolve as p}from"node:path";import{homedir as P}from"node:os";function j(n=process.env){let t=n.CLAUDE_CONFIG_DIR;return t&&t.trim()!==""?t.startsWith("~")?p(P(),t.replace(/^~[/\\]?/,"")):p(t):p(P(),".claude")}function G(n=process.env){return p(j(n),"settings.json")}function w(n=process.env){let t=[],e=O();if(e.platform!=="claude-code"){let r=A(e.platform);r&&r.length>0&&t.push(p(P(),...r,"settings.json"))}let o=G(n);return t.includes(o)||t.push(o),t}var v=h(()=>{"use strict";R()});v();import{readFileSync as D,realpathSync as $}from"node:fs";import{resolve as u}from"node:path";function b(n){let t=n.match(/^Bash\((.+)\)$/);return t?t[1]:null}function J(n){let t=n.match(/^(\w+)\((.+)\)$/);return t?{tool:t[1],glob:t[2]}:null}function q(n){return n.replace(/[.*+?^${}()|[\]\\\/\-]/g,"\\$&")}function k(n){return n.replace(/[.+?^${}()|[\]\\\/\-]/g,"\\$&").replace(/\*/g,".*")}function V(n,t=!1){let e,o=n.indexOf(":");if(o!==-1){let r=n.slice(0,o),i=n.slice(o+1),s=q(r),c=k(i);e=`^${s}(\\s${c})?$`}else e=`^${k(n)}$`;return new RegExp(e,t?"i":"")}function z(n,t=!1){let e="",o=0;for(;o<n.length;)n[o]==="*"&&n[o+1]==="*"?o+2<n.length&&n[o+2]==="/"?(e+="(.*/)?",o+=3):(e+=".*",o+=2):n[o]==="*"?(e+="[^/]*",o++):n[o]==="?"?(e+="[^/]",o++):(e+=n[o].replace(/[.+^${}()|[\]\\\/\-]/g,"\\$&"),o++);return new RegExp(`^${e}$`,t?"i":"")}function g(n,t,e=!1){for(let o of t){let r=b(o);if(r&&V(r,e).test(n))return o}return null}function T(n){let t=[],e="",o=!1,r=!1,i=!1;for(let s=0;s<n.length;s++){let c=n[s],d=s>0?n[s-1]:"";c==="'"&&!r&&!i&&d!=="\\"?(o=!o,e+=c):c==='"'&&!o&&!i&&d!=="\\"?(r=!r,e+=c):c==="`"&&!o&&!r&&d!=="\\"?(i=!i,e+=c):!o&&!r&&!i?c===";"?(t.push(e.trim()),e=""):c==="|"&&n[s+1]==="|"||c==="&"&&n[s+1]==="&"?(t.push(e.trim()),e="",s++):c==="|"?(t.push(e.trim()),e=""):e+=c:e+=c}return e.trim()&&t.push(e.trim()),t.filter(s=>s.length>0)}function C(n){let t;try{t=D(n,"utf-8")}catch{return null}let e;try{e=JSON.parse(t)}catch{return null}let o=e?.permissions;if(!o||typeof o!="object")return null;let r=i=>Array.isArray(i)?i.filter(s=>typeof s=="string"&&b(s)!==null):[];return{allow:r(o.allow),deny:r(o.deny),ask:r(o.ask)}}function ce(n,t){let e=[];if(n){let r=u(n,".claude","settings.local.json"),i=C(r);i&&e.push(i);let s=u(n,".claude","settings.json"),c=C(s);c&&e.push(c)}let o=t!==void 0?[t]:w();for(let r of o){let i=C(r);i&&e.push(i)}return e}function ae(n,t,e){let o=[],r=s=>{let c;try{c=D(s,"utf-8")}catch{return null}let d;try{d=JSON.parse(c)}catch{return null}let m=d?.permissions?.deny;if(!Array.isArray(m))return[];let x=[];for(let E of m){if(typeof E!="string")continue;let y=J(E);y&&y.tool===n&&x.push(y.glob)}return x};if(t){let s=r(u(t,".claude","settings.local.json"));s!==null&&o.push(s);let c=r(u(t,".claude","settings.json"));c!==null&&o.push(c)}let i=e!==void 0?[e]:w();for(let s of i){let c=r(s);c!==null&&o.push(c)}return o}function le(n,t,e=process.platform==="win32"){let o=T(n);for(let r of o)for(let i of t){let s=g(r,i.deny,e);if(s)return{decision:"deny",matchedPattern:s}}for(let r of t){let i=g(n,r.ask,e);if(i)return{decision:"ask",matchedPattern:i};let s=g(n,r.allow,e);if(s)return{decision:"allow",matchedPattern:s}}return{decision:"ask"}}function de(n,t,e=process.platform==="win32"){let o=T(n);for(let r of o)for(let i of t){let s=g(r,i.deny,e);if(s)return{decision:"deny",matchedPattern:s}}return{decision:"allow"}}function fe(n,t,e=process.platform==="win32",o){let r=s=>s.replace(/\\/g,"/"),i=new Set;if(i.add(r(n)),o){let s=u(o,n);i.add(r(s));try{i.add(r($(s)))}catch{}}for(let s of t)for(let c of s){let d=z(r(c),e);for(let m of i)if(d.test(m))return{denied:!0,matchedPattern:c}}return{denied:!1}}var B={python:[/os\.system\(\s*(['"])(.*?)\1\s*\)/g,/subprocess\.(?:run|call|Popen|check_output|check_call)\(\s*(['"])(.*?)\1/g],javascript:[/exec(?:Sync|File|FileSync)?\(\s*(['"`])(.*?)\1/g,/spawn(?:Sync)?\(\s*(['"`])(.*?)\1/g],typescript:[/exec(?:Sync|File|FileSync)?\(\s*(['"`])(.*?)\1/g,/spawn(?:Sync)?\(\s*(['"`])(.*?)\1/g],ruby:[/system\(\s*(['"])(.*?)\1/g,/`(.*?)`/g],go:[/exec\.Command\(\s*(['"`])(.*?)\1/g],php:[/shell_exec\(\s*(['"`])(.*?)\1/g,/(?:^|[^.])exec\(\s*(['"`])(.*?)\1/g,/(?:^|[^.])system\(\s*(['"`])(.*?)\1/g,/passthru\(\s*(['"`])(.*?)\1/g,/proc_open\(\s*(['"`])(.*?)\1/g],rust:[/Command::new\(\s*(['"`])(.*?)\1/g]};function U(n){let t=[],e=/subprocess\.(?:run|call|Popen|check_output|check_call)\(\s*\[([^\]]+)\]/g,o;for(;(o=e.exec(n))!==null;){let i=[...o[1].matchAll(/(['"])(.*?)\1/g)].map(s=>s[2]);i.length>0&&t.push(i.join(" "))}return t}function pe(n,t){let e=B[t];if(!e&&t!=="python")return[];let o=[];if(e)for(let r of e){r.lastIndex=0;let i;for(;(i=r.exec(n))!==null;){let s=i[i.length-1];s&&o.push(s)}}return t==="python"&&o.push(...U(n)),o}export{le as evaluateCommand,de as evaluateCommandDenyOnly,fe as evaluateFilePath,pe as extractShellCommands,z as fileGlobToRegex,V as globToRegex,g as matchesAnyPattern,b as parseBashPattern,J as parseToolPattern,ce as readBashPolicies,ae as readToolDenyPatterns,T as splitChainedCommands};
|
|
1
|
+
var h=(n,t)=>()=>(n&&(t=n(n=0)),t);var _,I=h(()=>{"use strict";_={"claude-code":"claude-code","gemini-cli-mcp-client":"gemini-cli","antigravity-client":"antigravity","cursor-vscode":"cursor","Visual-Studio-Code":"vscode-copilot","JetBrains Client":"jetbrains-copilot","IntelliJ IDEA":"jetbrains-copilot",PyCharm:"jetbrains-copilot",Codex:"codex","codex-mcp-client":"codex","Kilo Code":"kilo","Kiro CLI":"kiro","Pi CLI":"pi","Pi Coding Agent":"pi","omp-coding-agent":"omp",Zed:"zed",zed:"zed","qwen-code":"qwen-code","qwen-cli-mcp-client":"qwen-code","kimi-code":"kimi",kimi:"kimi","Kimi Code":"kimi"}});import{existsSync as l,readFileSync as N}from"node:fs";import{resolve as a}from"node:path";import{homedir as k}from"node:os";function L(){if(f!==null)return f!=="miss"&&f.hasCM;try{let n=a(k(),".claude","plugins","installed_plugins.json"),t=N(n,"utf-8"),e=JSON.parse(t),r=[...Object.keys(e.plugins??{}),...Object.keys(e.enabledPlugins??{})].some(i=>i.includes("context-mode"));return f={hasCM:r},r}catch{return f="miss",!1}}function S(n){switch(n){case"claude-code":return[".claude"];case"gemini-cli":return[".gemini"];case"antigravity":return[".gemini"];case"openclaw":return[".openclaw"];case"codex":return[".codex"];case"cursor":return[".cursor"];case"vscode-copilot":return[".vscode"];case"kiro":return[".kiro"];case"pi":return[".pi"];case"omp":return[".omp"];case"qwen-code":return[".qwen"];case"kimi":return[".kimi-code"];case"kilo":return[".config","kilo"];case"opencode":return[".config","opencode"];case"zed":return[".config","zed"];case"jetbrains-copilot":return[".config","JetBrains"];default:return null}}function A(n){if(n?.name){let o=_[n.name];if(o)return{platform:o,confidence:"high",reason:`MCP clientInfo.name="${n.name}"`};if(n.name.startsWith("qwen-cli-mcp-client"))return{platform:"qwen-code",confidence:"high",reason:`MCP clientInfo.name="${n.name}" (qwen-cli pattern)`}}let t=process.env.CONTEXT_MODE_PLATFORM;if(t&&["claude-code","gemini-cli","kilo","opencode","codex","vscode-copilot","jetbrains-copilot","cursor","antigravity","kiro","pi","omp","zed","qwen-code","kimi"].includes(t))return{platform:t,confidence:"high",reason:`CONTEXT_MODE_PLATFORM=${t} override`};for(let[o,r]of F)if(r.some(i=>i.detect!==!1&&process.env[i.name]))return o==="vscode-copilot"&&L()?{platform:"claude-code",confidence:"high",reason:"VSCODE_PID set but ~/.claude/plugins/installed_plugins.json lists context-mode (issue #539 fallback)"}:{platform:o,confidence:"high",reason:`${r.filter(i=>i.detect!==!1).map(i=>i.name).join(" or ")} env var set`};let e=k();return l(a(e,".claude"))?{platform:"claude-code",confidence:"medium",reason:"~/.claude/ directory exists"}:l(a(e,".gemini"))?{platform:"gemini-cli",confidence:"medium",reason:"~/.gemini/ directory exists"}:l(a(e,".codex"))?{platform:"codex",confidence:"medium",reason:"~/.codex/ directory exists"}:l(a(e,".kiro"))?{platform:"kiro",confidence:"medium",reason:"~/.kiro/ directory exists"}:l(a(e,".omp"))?{platform:"omp",confidence:"medium",reason:"~/.omp/ directory exists"}:l(a(e,".pi"))?{platform:"pi",confidence:"medium",reason:"~/.pi/ directory exists"}:l(a(e,".qwen"))?{platform:"qwen-code",confidence:"medium",reason:"~/.qwen/ directory exists"}:l(a(e,".kimi-code"))?{platform:"kimi",confidence:"medium",reason:"~/.kimi-code/ directory exists"}:l(a(e,".openclaw"))?{platform:"openclaw",confidence:"medium",reason:"~/.openclaw/ directory exists"}:l(a(e,".cursor"))?{platform:"cursor",confidence:"medium",reason:"~/.cursor/ directory exists"}:l(a(e,".config","kilo"))?{platform:"kilo",confidence:"medium",reason:"~/.config/kilo/ directory exists"}:l(a(e,".config","JetBrains"))?{platform:"jetbrains-copilot",confidence:"medium",reason:"~/.config/JetBrains/ directory exists"}:l(a(e,".config","opencode"))?{platform:"opencode",confidence:"medium",reason:"~/.config/opencode/ directory exists"}:l(a(e,".config","zed"))?{platform:"zed",confidence:"medium",reason:"~/.config/zed/ directory exists"}:{platform:"claude-code",confidence:"low",reason:"No platform detected, defaulting to Claude Code"}}var f,M,F,O=h(()=>{"use strict";I();f=null;M=[["claude-code",[{name:"CLAUDE_CODE_ENTRYPOINT",role:"identification"},{name:"CLAUDE_PLUGIN_ROOT",role:"identification"},{name:"CLAUDE_PROJECT_DIR",role:"workspace"},{name:"CLAUDE_SESSION_ID",role:"identification"}]],["antigravity",[{name:"ANTIGRAVITY_CLI_ALIAS",role:"identification"}]],["cursor",[{name:"CURSOR_CWD",role:"workspace"},{name:"CURSOR_TRACE_ID",role:"identification"},{name:"CURSOR_CLI",role:"identification"}]],["kilo",[{name:"KILO",role:"identification"},{name:"KILO_PID",role:"identification"}]],["opencode",[{name:"OPENCODE_PROJECT_DIR",role:"workspace"},{name:"OPENCODE_CLIENT",role:"identification"},{name:"OPENCODE_TERMINAL",role:"identification"},{name:"OPENCODE",role:"identification"},{name:"OPENCODE_PID",role:"identification"}]],["zed",[{name:"ZED_SESSION_ID",role:"identification"},{name:"ZED_TERM",role:"identification"}]],["codex",[{name:"CODEX_THREAD_ID",role:"identification"},{name:"CODEX_CI",role:"identification"}]],["gemini-cli",[{name:"GEMINI_PROJECT_DIR",role:"workspace"},{name:"GEMINI_CLI",role:"identification"}]],["vscode-copilot",[{name:"VSCODE_CWD",role:"workspace"},{name:"VSCODE_PID",role:"identification"}]],["jetbrains-copilot",[{name:"IDEA_INITIAL_DIRECTORY",role:"workspace"}]],["qwen-code",[{name:"QWEN_PROJECT_DIR",role:"workspace"}]],["omp",[{name:"PI_CODING_AGENT_DIR",role:"workspace"}]],["pi",[{name:"PI_WORKSPACE_DIR",role:"workspace",detect:!1},{name:"PI_PROJECT_DIR",role:"workspace",detect:!1},{name:"PI_CONFIG_DIR",role:"identification"},{name:"PI_SESSION_FILE",role:"identification"},{name:"PI_COMPILED",role:"identification"}]]],F=new Map(M)});import{resolve as u}from"node:path";import{homedir as P}from"node:os";function j(n=process.env){let t=n.CLAUDE_CONFIG_DIR;return t&&t.trim()!==""?t.startsWith("~")?u(P(),t.replace(/^~[/\\]?/,"")):u(t):u(P(),".claude")}function G(n=process.env){return u(j(n),"settings.json")}function w(n=process.env){let t=[],e=A();if(e.platform!=="claude-code"){let r=S(e.platform);r&&r.length>0&&t.push(u(P(),...r,"settings.json"))}let o=G(n);return t.includes(o)||t.push(o),t}var R=h(()=>{"use strict";O()});R();import{readFileSync as D,realpathSync as $}from"node:fs";import{resolve as p}from"node:path";function b(n){let t=n.match(/^Bash\((.+)\)$/);return t?t[1]:null}function J(n){let t=n.match(/^(\w+)\((.+)\)$/);return t?{tool:t[1],glob:t[2]}:null}function q(n){return n.replace(/[.*+?^${}()|[\]\\\/\-]/g,"\\$&")}function v(n){return n.replace(/[.+?^${}()|[\]\\\/\-]/g,"\\$&").replace(/\*/g,".*")}function V(n,t=!1){let e,o=n.indexOf(":");if(o!==-1){let r=n.slice(0,o),i=n.slice(o+1),s=q(r),c=v(i);e=`^${s}(\\s${c})?$`}else e=`^${v(n)}$`;return new RegExp(e,t?"i":"")}function z(n,t=!1){let e="",o=0;for(;o<n.length;)n[o]==="*"&&n[o+1]==="*"?o+2<n.length&&n[o+2]==="/"?(e+="(.*/)?",o+=3):(e+=".*",o+=2):n[o]==="*"?(e+="[^/]*",o++):n[o]==="?"?(e+="[^/]",o++):(e+=n[o].replace(/[.+^${}()|[\]\\\/\-]/g,"\\$&"),o++);return new RegExp(`^${e}$`,t?"i":"")}function g(n,t,e=!1){for(let o of t){let r=b(o);if(r&&V(r,e).test(n))return o}return null}function T(n){let t=[],e="",o=!1,r=!1,i=!1;for(let s=0;s<n.length;s++){let c=n[s],d=s>0?n[s-1]:"";c==="'"&&!r&&!i&&d!=="\\"?(o=!o,e+=c):c==='"'&&!o&&!i&&d!=="\\"?(r=!r,e+=c):c==="`"&&!o&&!r&&d!=="\\"?(i=!i,e+=c):!o&&!r&&!i?c===";"?(t.push(e.trim()),e=""):c==="|"&&n[s+1]==="|"||c==="&"&&n[s+1]==="&"?(t.push(e.trim()),e="",s++):c==="|"?(t.push(e.trim()),e=""):e+=c:e+=c}return e.trim()&&t.push(e.trim()),t.filter(s=>s.length>0)}function C(n){let t;try{t=D(n,"utf-8")}catch{return null}let e;try{e=JSON.parse(t)}catch{return null}let o=e?.permissions;if(!o||typeof o!="object")return null;let r=i=>Array.isArray(i)?i.filter(s=>typeof s=="string"&&b(s)!==null):[];return{allow:r(o.allow),deny:r(o.deny),ask:r(o.ask)}}function ce(n,t){let e=[];if(n){let r=p(n,".claude","settings.local.json"),i=C(r);i&&e.push(i);let s=p(n,".claude","settings.json"),c=C(s);c&&e.push(c)}let o=t!==void 0?[t]:w();for(let r of o){let i=C(r);i&&e.push(i)}return e}function ae(n,t,e){let o=[],r=s=>{let c;try{c=D(s,"utf-8")}catch{return null}let d;try{d=JSON.parse(c)}catch{return null}let m=d?.permissions?.deny;if(!Array.isArray(m))return[];let x=[];for(let E of m){if(typeof E!="string")continue;let y=J(E);y&&y.tool===n&&x.push(y.glob)}return x};if(t){let s=r(p(t,".claude","settings.local.json"));s!==null&&o.push(s);let c=r(p(t,".claude","settings.json"));c!==null&&o.push(c)}let i=e!==void 0?[e]:w();for(let s of i){let c=r(s);c!==null&&o.push(c)}return o}function le(n,t,e=process.platform==="win32"){let o=T(n);for(let r of o)for(let i of t){let s=g(r,i.deny,e);if(s)return{decision:"deny",matchedPattern:s}}for(let r of t){let i=g(n,r.ask,e);if(i)return{decision:"ask",matchedPattern:i};let s=g(n,r.allow,e);if(s)return{decision:"allow",matchedPattern:s}}return{decision:"ask"}}function de(n,t,e=process.platform==="win32"){let o=T(n);for(let r of o)for(let i of t){let s=g(r,i.deny,e);if(s)return{decision:"deny",matchedPattern:s}}return{decision:"allow"}}function fe(n,t,e=process.platform==="win32",o){let r=s=>s.replace(/\\/g,"/"),i=new Set;if(i.add(r(n)),o){let s=p(o,n);i.add(r(s));try{i.add(r($(s)))}catch{}}for(let s of t)for(let c of s){let d=z(r(c),e);for(let m of i)if(d.test(m))return{denied:!0,matchedPattern:c}}return{denied:!1}}var B={python:[/os\.system\(\s*(['"])(.*?)\1\s*\)/g,/subprocess\.(?:run|call|Popen|check_output|check_call)\(\s*(['"])(.*?)\1/g],javascript:[/exec(?:Sync|File|FileSync)?\(\s*(['"`])(.*?)\1/g,/spawn(?:Sync)?\(\s*(['"`])(.*?)\1/g],typescript:[/exec(?:Sync|File|FileSync)?\(\s*(['"`])(.*?)\1/g,/spawn(?:Sync)?\(\s*(['"`])(.*?)\1/g],ruby:[/system\(\s*(['"])(.*?)\1/g,/`(.*?)`/g],go:[/exec\.Command\(\s*(['"`])(.*?)\1/g],php:[/shell_exec\(\s*(['"`])(.*?)\1/g,/(?:^|[^.])exec\(\s*(['"`])(.*?)\1/g,/(?:^|[^.])system\(\s*(['"`])(.*?)\1/g,/passthru\(\s*(['"`])(.*?)\1/g,/proc_open\(\s*(['"`])(.*?)\1/g],rust:[/Command::new\(\s*(['"`])(.*?)\1/g]};function U(n){let t=[],e=/subprocess\.(?:run|call|Popen|check_output|check_call)\(\s*\[([^\]]+)\]/g,o;for(;(o=e.exec(n))!==null;){let i=[...o[1].matchAll(/(['"])(.*?)\1/g)].map(s=>s[2]);i.length>0&&t.push(i.join(" "))}return t}function ue(n,t){let e=B[t];if(!e&&t!=="python")return[];let o=[];if(e)for(let r of e){r.lastIndex=0;let i;for(;(i=r.exec(n))!==null;){let s=i[i.length-1];s&&o.push(s)}}return t==="python"&&o.push(...U(n)),o}export{le as evaluateCommand,de as evaluateCommandDenyOnly,fe as evaluateFilePath,ue as extractShellCommands,z as fileGlobToRegex,V as globToRegex,g as matchesAnyPattern,b as parseBashPattern,J as parseToolPattern,ce as readBashPolicies,ae as readToolDenyPatterns,T as splitChainedCommands};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{createRequire as oe}from"node:module";import{existsSync as ie,unlinkSync as P,renameSync as ae}from"node:fs";import{tmpdir as ce}from"node:os";import{join as ue}from"node:path";var A=class{#e;constructor(e){this.#e=e}pragma(e){let r=this.#e.prepare(`PRAGMA ${e}`).all();if(!r||r.length===0)return;if(r.length>1)return r;let s=Object.values(r[0]);return s.length===1?s[0]:r[0]}exec(e){let t="",r=null;for(let a=0;a<e.length;a++){let i=e[a];if(r)t+=i,i===r&&(r=null);else if(i==="'"||i==='"')t+=i,r=i;else if(i===";"){let c=t.trim();c&&this.#e.prepare(c).run(),t=""}else t+=i}let s=t.trim();return s&&this.#e.prepare(s).run(),this}prepare(e){let t=this.#e.prepare(e);return{run:(...r)=>t.run(...r),get:(...r)=>{let s=t.get(...r);return s===null?void 0:s},all:(...r)=>t.all(...r),iterate:(...r)=>t.iterate(...r)}}transaction(e){return this.#e.transaction(e)}close(){this.#e.close()}},w=class{#e;constructor(e){this.#e=e}pragma(e){let r=this.#e.prepare(`PRAGMA ${e}`).all();if(!r||r.length===0)return;if(r.length>1)return r;let s=Object.values(r[0]);return s.length===1?s[0]:r[0]}exec(e){return this.#e.exec(e),this}prepare(e){let t=this.#e.prepare(e);return{run:(...r)=>t.run(...r),get:(...r)=>t.get(...r),all:(...r)=>t.all(...r),iterate:(...r)=>typeof t.iterate=="function"?t.iterate(...r):t.all(...r)[Symbol.iterator]()}}transaction(e){return(...t)=>{this.#e.exec("BEGIN");try{let r=e(...t);return this.#e.exec("COMMIT"),r}catch(r){throw this.#e.exec("ROLLBACK"),r}}}close(){this.#e.close()}},E=null;function de(n){let e=null;try{return e=new n(":memory:"),e.exec("CREATE VIRTUAL TABLE __fts5_probe USING fts5(x)"),!0}catch{return!1}finally{try{e?.close()}catch{}}}function le(n,e){let t=e!==void 0?e:globalThis.Bun;if(typeof t<"u"&&t!==null)return!0;let r=n??process.versions,[s,a]=(r.node??"0.0.0").split("."),i=Number(s),c=Number(a);return!Number.isFinite(i)||!Number.isFinite(c)?!1:i>22||i===22&&c>=5}function ge(){if(!E){let n=oe(import.meta.url);if(globalThis.Bun){let e=n(["bun","sqlite"].join(":")).Database;E=function(r,s){let a=new e(r,{readonly:s?.readonly,create:!0}),i=new A(a);return s?.timeout&&i.pragma(`busy_timeout = ${s.timeout}`),i}}else if(le()){let e=null;try{({DatabaseSync:e}=n(["node","sqlite"].join(":")))}catch{e=null}e&&de(e)?E=function(r,s){let a=new e(r,{readOnly:s?.readonly??!1}),i=new w(a);return s?.timeout&&i.pragma(`busy_timeout = ${s.timeout}`),i}:E=n("better-sqlite3")}else E=n("better-sqlite3")}return E}function
|
|
2
|
-
`))}function K(n){let e=process.env[l];if(e===void 0)return{kind:"unset"};let t=e.trim();if(!t)return{kind:"ignored-empty",ignoredEnvVar:l,ignoredReason:"empty"};if(!Y(t))throw be(n,t,`${l} must be an absolute path.`);return{kind:"override",root:p(t)}}function De(n){return n.kind==="ignored-empty"?{ignoredEnvVar:n.ignoredEnvVar,ignoredReason:n.ignoredReason}:{}}function z(n,e){let t=K(n);return t.kind!=="override"?null:{kind:n,path:g(t.root,e),envVar:l,source:"override"}}function Le(n,e,t){return{kind:n,path:p(e()),envVar:null,source:"default",...t}}function Q(n){let e=K("session");return e.kind==="override"?{kind:"session",path:g(e.root,q),envVar:l,source:"override"}:Le("session",n,De(e))}function Ye(n){let e=z("content",
|
|
3
|
-
`)}function Oe(n){return n.ignoredEnvVar&&n.ignoredReason==="empty"?`Ignored empty ${n.ignoredEnvVar}; using adapter default.`:null}function J(){return`Set ${l} to a writable absolute path.`}function Ce(n){if(!n||typeof n!="object")return null;let e=n.path;return typeof e=="string"&&e.length>0?e:null}var m;function
|
|
1
|
+
import{createRequire as oe}from"node:module";import{existsSync as ie,unlinkSync as P,renameSync as ae}from"node:fs";import{tmpdir as ce}from"node:os";import{join as ue}from"node:path";var A=class{#e;constructor(e){this.#e=e}pragma(e){let r=this.#e.prepare(`PRAGMA ${e}`).all();if(!r||r.length===0)return;if(r.length>1)return r;let s=Object.values(r[0]);return s.length===1?s[0]:r[0]}exec(e){let t="",r=null;for(let a=0;a<e.length;a++){let i=e[a];if(r)t+=i,i===r&&(r=null);else if(i==="'"||i==='"')t+=i,r=i;else if(i===";"){let c=t.trim();c&&this.#e.prepare(c).run(),t=""}else t+=i}let s=t.trim();return s&&this.#e.prepare(s).run(),this}prepare(e){let t=this.#e.prepare(e);return{run:(...r)=>t.run(...r),get:(...r)=>{let s=t.get(...r);return s===null?void 0:s},all:(...r)=>t.all(...r),iterate:(...r)=>t.iterate(...r)}}transaction(e){return this.#e.transaction(e)}close(){this.#e.close()}},w=class{#e;constructor(e){this.#e=e}pragma(e){let r=this.#e.prepare(`PRAGMA ${e}`).all();if(!r||r.length===0)return;if(r.length>1)return r;let s=Object.values(r[0]);return s.length===1?s[0]:r[0]}exec(e){return this.#e.exec(e),this}prepare(e){let t=this.#e.prepare(e);return{run:(...r)=>t.run(...r),get:(...r)=>t.get(...r),all:(...r)=>t.all(...r),iterate:(...r)=>typeof t.iterate=="function"?t.iterate(...r):t.all(...r)[Symbol.iterator]()}}transaction(e){return(...t)=>{this.#e.exec("BEGIN");try{let r=e(...t);return this.#e.exec("COMMIT"),r}catch(r){throw this.#e.exec("ROLLBACK"),r}}}close(){this.#e.close()}},E=null;function de(n){let e=null;try{return e=new n(":memory:"),e.exec("CREATE VIRTUAL TABLE __fts5_probe USING fts5(x)"),!0}catch{return!1}finally{try{e?.close()}catch{}}}function le(n,e){let t=e!==void 0?e:globalThis.Bun;if(typeof t<"u"&&t!==null)return!0;let r=n??process.versions,[s,a]=(r.node??"0.0.0").split("."),i=Number(s),c=Number(a);return!Number.isFinite(i)||!Number.isFinite(c)?!1:i>22||i===22&&c>=5}function ge(){if(!E){let n=oe(import.meta.url);if(globalThis.Bun){let e=n(["bun","sqlite"].join(":")).Database;E=function(r,s){let a=new e(r,{readonly:s?.readonly,create:!0}),i=new A(a);return s?.timeout&&i.pragma(`busy_timeout = ${s.timeout}`),i}}else if(le()){let e=null;try{({DatabaseSync:e}=n(["node","sqlite"].join(":")))}catch{e=null}e&&de(e)?E=function(r,s){let a=new e(r,{readOnly:s?.readonly??!1}),i=new w(a);return s?.timeout&&i.pragma(`busy_timeout = ${s.timeout}`),i}:E=n("better-sqlite3")}else E=n("better-sqlite3")}return E}function k(n){n.pragma("journal_mode = WAL"),n.pragma("synchronous = NORMAL");try{n.pragma("mmap_size = 268435456")}catch{}}function F(n){if(!ie(n))for(let e of["-wal","-shm"])try{P(n+e)}catch{}}function Ee(n){for(let e of["","-wal","-shm"])try{P(n+e)}catch{}}function I(n){try{n.pragma("wal_checkpoint(TRUNCATE)")}catch{}try{n.close()}catch{}}function j(n="context-mode"){return ue(ce(),`${n}-${process.pid}.db`)}function me(n,e=[100,500,2e3]){let t;for(let r=0;r<=e.length;r++)try{return n()}catch(s){let a=s instanceof Error?s.message:String(s);if(!a.includes("SQLITE_BUSY")&&!a.includes("database is locked"))throw s;if(t=s instanceof Error?s:new Error(a),r<e.length){let i=e[r],c=Date.now();for(;Date.now()-c<i;);}}throw new Error(`SQLITE_BUSY: database is locked after ${e.length} retries. Original error: ${t?.message}`)}function pe(n){return n.includes("SQLITE_CORRUPT")||n.includes("SQLITE_NOTADB")||n.includes("database disk image is malformed")||n.includes("file is not a database")}function ye(n){let e=Date.now();for(let t of["","-wal","-shm"])try{ae(n+t,`${n}${t}.corrupt-${e}`)}catch{}}var _=Symbol.for("__context_mode_live_dbs_v3__"),C=(()=>{let n=globalThis;return n[_]||(n[_]=new Set,process.on("exit",()=>{for(let e of n[_])I(e);n[_].clear()})),n[_]})(),v=class{#e;#t;constructor(e){let t=ge();this.#e=e,F(e);let r;try{r=new t(e,{timeout:3e4}),k(r)}catch(s){let a=s instanceof Error?s.message:String(s);if(pe(a)){ye(e),F(e);try{r=new t(e,{timeout:3e4}),k(r)}catch(i){throw new Error(`Failed to create fresh DB after renaming corrupt file: ${i instanceof Error?i.message:String(i)}`)}}else throw s}this.#t=r,C.add(this.#t),this.initSchema(),this.prepareStatements()}get db(){return this.#t}get dbPath(){return this.#e}close(){C.delete(this.#t),I(this.#t)}withRetry(e){return me(e)}cleanup(){C.delete(this.#t),I(this.#t),Ee(this.#e)}};import{createHash as f}from"node:crypto";import{execFileSync as _e}from"node:child_process";import{accessSync as fe,constants as he,existsSync as D,mkdirSync as Te,realpathSync as Se,renameSync as x}from"node:fs";import{homedir as G}from"node:os";import{dirname as ve,isAbsolute as Y,join as g,resolve as p}from"node:path";var l="CONTEXT_MODE_DIR",q="sessions",B="content",h=class extends Error{kind;path;overrideEnvVar;ignoredEnvVar;ignoredReason;constructor(e,t,r=l,s,a,i={}){super(a??Ne(e,t,i),{cause:s}),this.name="StorageDirectoryError",this.kind=e,this.path=t,this.overrideEnvVar=r,this.ignoredEnvVar=i.ignoredEnvVar,this.ignoredReason=i.ignoredReason}},b=new Map;function Ge(n){let e=n.env??process.env,t=n.legacySessionDirEnv,r=t?e[t]?.trim():void 0;return r&&t?(n.onLegacySessionDir?.(t,r),r):g(Re(n.configDir,n.configDirEnv,e),"context-mode","sessions")}function Re(n,e,t){let r=e?t[e]:void 0;return r&&r.trim()!==""?V(r.trim()):V(n,G())}function V(n,e){return n.startsWith("~")?p(G(),n.replace(/^~[/\\]?/,"")):Y(n)?p(n):e?p(e,n):p(n)}function be(n,e,t){return new h(n,e,l,void 0,[`Invalid ${l} for context-mode ${n} directory: ${t}`,J()].join(`
|
|
2
|
+
`))}function K(n){let e=process.env[l];if(e===void 0)return{kind:"unset"};let t=e.trim();if(!t)return{kind:"ignored-empty",ignoredEnvVar:l,ignoredReason:"empty"};if(!Y(t))throw be(n,t,`${l} must be an absolute path.`);return{kind:"override",root:p(t)}}function De(n){return n.kind==="ignored-empty"?{ignoredEnvVar:n.ignoredEnvVar,ignoredReason:n.ignoredReason}:{}}function z(n,e){let t=K(n);return t.kind!=="override"?null:{kind:n,path:g(t.root,e),envVar:l,source:"override"}}function Le(n,e,t){return{kind:n,path:p(e()),envVar:null,source:"default",...t}}function Q(n){let e=K("session");return e.kind==="override"?{kind:"session",path:g(e.root,q),envVar:l,source:"override"}:Le("session",n,De(e))}function Ye(n){let e=z("content",B);if(e)return e;let t=Q(n);return{kind:"content",path:g(ve(t.path),B),envVar:t.envVar,source:t.source,ignoredEnvVar:t.ignoredEnvVar,ignoredReason:t.ignoredReason}}function qe(n){let e=z("stats",q);if(e)return e;let t=Q(n);return{kind:"stats",path:t.path,envVar:t.envVar,source:t.source,ignoredEnvVar:t.ignoredEnvVar,ignoredReason:t.ignoredReason}}function Ke(n){return n.message}function ze(n){return n.source==="override"&&n.envVar?`via ${n.envVar}`:n.ignoredEnvVar&&n.ignoredReason==="empty"?`default; ignored empty ${n.ignoredEnvVar}`:"default"}function Qe(){b.clear()}function Je(n){let e=[n.kind,n.path,n.source,n.envVar??"",n.ignoredEnvVar??"",n.ignoredReason??""].join("\0"),t=b.get(e);if(t instanceof h)throw t;if(t===n.path)return t;try{return Te(n.path,{recursive:!0}),fe(n.path,he.W_OK),b.set(e,n.path),n.path}catch(r){let s=new h(n.kind,Ce(r)??n.path,l,r,void 0,{ignoredEnvVar:n.ignoredEnvVar,ignoredReason:n.ignoredReason});throw b.set(e,s),s}}function Ne(n,e,t={}){return[`context-mode ${n} directory is not writable: ${e}`,Oe(t),J()].filter(Boolean).join(`
|
|
3
|
+
`)}function Oe(n){return n.ignoredEnvVar&&n.ignoredReason==="empty"?`Ignored empty ${n.ignoredEnvVar}; using adapter default.`:null}function J(){return`Set ${l} to a writable absolute path.`}function Ce(n){if(!n||typeof n!="object")return null;let e=n.path;return typeof e=="string"&&e.length>0?e:null}var m;function T(n){let e=n.replace(/\\/g,"/");return/^\/+$/.test(e)?"/":/^[A-Za-z]:\/+$/.test(e)?`${e.slice(0,2)}/`:e.replace(/\/+$/,"")}function W(n){let e=n;try{e=Se.native(n)}catch{}let t=T(e);return process.platform==="win32"||process.platform==="darwin"?t.toLowerCase():t}function Z(n,e){return _e("git",["-C",n,...e],{encoding:"utf-8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim()}function Ae(n){let e=Z(n,["rev-parse","--show-toplevel"]);return e.length>0?T(e):null}function we(n){let e=Z(n,["worktree","list","--porcelain"]).split(/\r?\n/).find(t=>t.startsWith("worktree "))?.replace("worktree ","")?.trim();return e?T(e):null}function Ie(n=process.cwd()){let e=process.env.CONTEXT_MODE_SESSION_SUFFIX;if(m&&m.projectDir===n&&m.envSuffix===e)return m.suffix;let t="";if(e!==void 0)t=e?`__${e}`:"";else try{let r=Ae(n),s=we(n);if(r&&s){let a=W(r),i=W(s);a!==i&&(t=`__${f("sha256").update(a).digest("hex").slice(0,8)}`)}}catch{}return m={projectDir:n,envSuffix:e,suffix:t},t}function Ze(){m=void 0}function ee(n){return f("sha256").update(T(n)).digest("hex").slice(0,16)}function te(n){let e=T(n),t=process.platform==="darwin"||process.platform==="win32"?e.toLowerCase():e;return f("sha256").update(t).digest("hex").slice(0,16)}function et(n){let{projectDir:e,contentDir:t}=n,r=te(e),s=g(t,`${r}.db`);if(D(s))return s;let a=ee(e);if(a===r)return s;let i=g(t,`${a}.db`);if(D(i))try{x(i,s);for(let c of["-wal","-shm"])try{x(i+c,s+c)}catch{}}catch{}return s}function tt(n){return xe({...n,ext:".db"})}function xe(n){let{projectDir:e,sessionsDir:t,ext:r}=n,s=n.suffix??Ie(e),a=te(e),i=g(t,`${a}${s}${r}`);if(D(i))return i;let c=ee(e);if(c===a)return i;let d=g(t,`${c}${s}${r}`);if(D(d))try{x(d,i)}catch{}return i}var H=1e3,X=5;function R(n){let e=Number(n);return!Number.isFinite(e)||e<=0?0:Math.floor(e)}var o={insertEvent:"insertEvent",getEvents:"getEvents",getEventsByType:"getEventsByType",getEventsByPriority:"getEventsByPriority",getEventsByTypeAndPriority:"getEventsByTypeAndPriority",getEventCount:"getEventCount",getLatestAttributedProject:"getLatestAttributedProject",checkDuplicate:"checkDuplicate",evictLowestPriority:"evictLowestPriority",updateMetaLastEvent:"updateMetaLastEvent",ensureSession:"ensureSession",getSessionStats:"getSessionStats",incrementCompactCount:"incrementCompactCount",upsertResume:"upsertResume",getResume:"getResume",markResumeConsumed:"markResumeConsumed",claimLatestUnconsumedResume:"claimLatestUnconsumedResume",deleteEvents:"deleteEvents",deleteMeta:"deleteMeta",deleteResume:"deleteResume",getOldSessions:"getOldSessions",searchEvents:"searchEvents",incrementToolCall:"incrementToolCall",getToolCallTotals:"getToolCallTotals",getToolCallByTool:"getToolCallByTool",getEventBytesSummary:"getEventBytesSummary"},Ue=[["project_dir","TEXT NOT NULL DEFAULT ''"],["attribution_source","TEXT NOT NULL DEFAULT 'unknown'"],["attribution_confidence","REAL NOT NULL DEFAULT 0"],["bytes_avoided","INTEGER NOT NULL DEFAULT 0"],["bytes_returned","INTEGER NOT NULL DEFAULT 0"]];function ne(n){let e=n.pragma("table_xinfo(session_events)"),t=new Set(e.map(s=>s.name)),r=!1;for(let[s,a]of Ue)t.has(s)||(n.exec(`ALTER TABLE session_events ADD COLUMN ${s} ${a}`),r=!0);return r&&n.exec("CREATE INDEX IF NOT EXISTS idx_session_events_project ON session_events(session_id, project_dir)"),r}function nt(n,e){let t=null;try{t=new e(n),ne(t)}catch{}finally{try{t?.close()}catch{}}}var $=class extends v{constructor(e){super(e?.dbPath??j("session"))}stmt(e){return this.stmts.get(e)}initSchema(){try{let t=this.db.pragma("table_xinfo(session_events)").find(r=>r.name==="data_hash");t&&t.hidden!==0&&this.db.exec("DROP TABLE session_events")}catch{}this.db.exec(`
|
|
4
4
|
CREATE TABLE IF NOT EXISTS session_events (
|
|
5
5
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
6
6
|
session_id TEXT NOT NULL,
|
|
@@ -118,4 +118,6 @@ import{createRequire as oe}from"node:module";import{existsSync as ie,unlinkSync
|
|
|
118
118
|
FROM tool_calls WHERE session_id = ?`),e(o.getToolCallByTool,`SELECT tool, calls, bytes_returned
|
|
119
119
|
FROM tool_calls WHERE session_id = ? ORDER BY calls DESC`),e(o.getEventBytesSummary,`SELECT COALESCE(SUM(bytes_avoided), 0) AS bytes_avoided,
|
|
120
120
|
COALESCE(SUM(bytes_returned), 0) AS bytes_returned
|
|
121
|
-
FROM session_events WHERE session_id = ?`)}insertEvent(e,t,r="PostToolUse",s,a){let i=f("sha256").update(t.data).digest("hex").slice(0,16).toUpperCase(),c=String(s?.projectDir??t.project_dir??this._getSessionProjectDir(e)).trim(),d=String(s?.source??t.attribution_source??"unknown"),u=Number(s?.confidence??t.attribution_confidence??0),S=Number.isFinite(u)?Math.max(0,Math.min(1,u)):0,y=R(a?.bytesAvoided),L=R(a?.bytesReturned),N=this.db.transaction(()=>{if(this.stmt(o.checkDuplicate).get(e
|
|
121
|
+
FROM session_events WHERE session_id = ?`)}insertEvent(e,t,r="PostToolUse",s,a){let i=f("sha256").update(t.data).digest("hex").slice(0,16).toUpperCase(),c=String(s?.projectDir??t.project_dir??this._getSessionProjectDir(e)).trim(),d=String(s?.source??t.attribution_source??"unknown"),u=Number(s?.confidence??t.attribution_confidence??0),S=Number.isFinite(u)?Math.max(0,Math.min(1,u)):0,y=R(a?.bytesAvoided),L=R(a?.bytesReturned),N=this.db.transaction(()=>{if(this.stmt(o.checkDuplicate).get(e,X,t.type,i))return;this.stmt(o.getEventCount).get(e).cnt>=H&&this.stmt(o.evictLowestPriority).run(e),this.stmt(o.insertEvent).run(e,t.type,t.category,t.priority,t.data,c,d,S,y,L,r,i),this.stmt(o.updateMetaLastEvent).run(e)});this.withRetry(()=>N())}bulkInsertEvents(e,t,r="PostToolUse",s,a){if(!t||t.length===0)return;if(t.length===1){this.insertEvent(e,t[0],r,s?.[0],a?.[0]);return}let i=t.map((d,u)=>{let S=f("sha256").update(d.data).digest("hex").slice(0,16).toUpperCase(),y=s?.[u],L=String(y?.projectDir??d.project_dir??this._getSessionProjectDir(e)??"").trim(),N=String(y?.source??d.attribution_source??"unknown"),O=Number(y?.confidence??d.attribution_confidence??0),U=Number.isFinite(O)?Math.max(0,Math.min(1,O)):0,M=a?.[u],re=R(M?.bytesAvoided),se=R(M?.bytesReturned);return{event:d,dataHash:S,projectDir:L,attributionSource:N,attributionConfidence:U,bytesAvoided:re,bytesReturned:se}}),c=this.db.transaction(()=>{let d=this.stmt(o.getEventCount).get(e).cnt;for(let u of i)this.stmt(o.checkDuplicate).get(e,X,u.event.type,u.dataHash)||(d>=H?this.stmt(o.evictLowestPriority).run(e):d++,this.stmt(o.insertEvent).run(e,u.event.type,u.event.category,u.event.priority,u.event.data,u.projectDir,u.attributionSource,u.attributionConfidence,u.bytesAvoided,u.bytesReturned,r,u.dataHash));this.stmt(o.updateMetaLastEvent).run(e)});this.withRetry(()=>c())}getEvents(e,t){let r=t?.limit??1e3,s=t?.type,a=t?.minPriority;return s&&a!==void 0?this.stmt(o.getEventsByTypeAndPriority).all(e,s,a,r):s?this.stmt(o.getEventsByType).all(e,s,r):a!==void 0?this.stmt(o.getEventsByPriority).all(e,a,r):this.stmt(o.getEvents).all(e,r)}getEventCount(e){return this.stmt(o.getEventCount).get(e).cnt}getEventBytesSummary(e){let t=this.stmt(o.getEventBytesSummary).get(e);return{bytesAvoided:Number(t?.bytes_avoided??0),bytesReturned:Number(t?.bytes_returned??0)}}getLatestAttributedProjectDir(e){return this.stmt(o.getLatestAttributedProject).get(e)?.project_dir||null}_getSessionProjectDir(e){try{return this.db.prepare("SELECT project_dir FROM session_meta WHERE session_id = ?").get(e)?.project_dir||""}catch{return""}}searchEvents(e,t,r,s){try{let a=e.replace(/[%_]/g,c=>"\\"+c),i=s??null;return this.stmt(o.searchEvents).all(r,a,a,i,i,t)}catch{return[]}}getSessionIdsForProject(e){try{return this.db.prepare(`SELECT DISTINCT session_id
|
|
122
|
+
FROM session_events
|
|
123
|
+
WHERE project_dir = ?`).all(e).map(r=>r.session_id)}catch{return[]}}ensureSession(e,t){this.stmt(o.ensureSession).run(e,t)}getSessionStats(e){return this.stmt(o.getSessionStats).get(e)??null}incrementCompactCount(e){this.stmt(o.incrementCompactCount).run(e)}upsertResume(e,t,r){this.stmt(o.upsertResume).run(e,t,r??0)}getResume(e){return this.stmt(o.getResume).get(e)??null}markResumeConsumed(e){this.stmt(o.markResumeConsumed).run(e)}claimLatestUnconsumedResume(e){let t=this.stmt(o.claimLatestUnconsumedResume).get(e);return t?{sessionId:t.session_id,snapshot:t.snapshot}:null}getLatestSessionId(){try{return this.db.prepare("SELECT session_id FROM session_meta ORDER BY started_at DESC LIMIT 1").get()?.session_id??null}catch{return null}}incrementToolCall(e,t,r=0){let s=Number.isFinite(r)&&r>0?Math.round(r):0;try{this.stmt(o.incrementToolCall).run(e,t,s)}catch{}}getToolCallStats(e){try{let t=this.stmt(o.getToolCallTotals).get(e),r=this.stmt(o.getToolCallByTool).all(e),s={};for(let a of r)s[a.tool]={calls:a.calls,bytesReturned:a.bytes_returned};return{totalCalls:t?.calls??0,totalBytesReturned:t?.bytes_returned??0,byTool:s}}catch{return{totalCalls:0,totalBytesReturned:0,byTool:{}}}}deleteSession(e){this.db.transaction(()=>{this.stmt(o.deleteEvents).run(e),this.stmt(o.deleteResume).run(e),this.stmt(o.deleteMeta).run(e)})()}cleanupOldSessions(e=7){let t=`-${e}`,r=this.stmt(o.getOldSessions).all(t);for(let{session_id:s}of r)this.deleteSession(s);return r.length}pruneOrphanedEvents(){let e=this.db.prepare("DELETE FROM session_events WHERE session_id NOT IN (SELECT session_id FROM session_meta)").run();return Number(e.changes??0)}};export{$ as SessionDB,h as StorageDirectoryError,Ze as _resetWorktreeSuffixCacheForTests,ne as applyMissingSessionEventsColumns,Qe as clearStorageDirectoryCheckCacheForTests,ze as describeStorageDirectorySource,nt as ensureSessionEventsSchema,Je as ensureWritableStorageDir,Ke as formatStorageDirectoryError,Ie as getWorktreeSuffix,te as hashProjectDirCanonical,ee as hashProjectDirLegacy,T as normalizeWorktreePath,Ye as resolveContentStorageDir,et as resolveContentStorePath,Ge as resolveDefaultSessionDir,tt as resolveSessionDbPath,xe as resolveSessionPath,Q as resolveSessionStorageDir,qe as resolveStatsStorageDir};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function i(t){return t==null?"":String(t)}function E(t){return t==null?"":typeof t=="string"?t:JSON.stringify(t)}function d(t){let e=String(t.tool_response??""),n=String(t.tool_input?.command??"");if(e.startsWith("context-mode:")||n.startsWith('echo "context-mode:')||n.startsWith("echo 'context-mode:"))return!1;let r=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)||r}function k(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 S(t){return/(?:^|[/\\])\.claude[/\\]plans[/\\]/.test(t)}function A(t){let{tool_name:e,tool_input:n,tool_response:r}=t,o=[];if(e==="Read"){let s=String(n.file_path??"");return(/(?:CLAUDE|AGENTS(?:\.override)?|GEMINI|QWEN|KIRO)\.md$/i.test(s)||/\/copilot-instructions\.md$/i.test(s)||/\/context-mode\.mdc$/i.test(s)||/\.claude[\\/]/i.test(s)||/[\\/]memor(?:y|ies)[\\/][^\\/]+\.md$/i.test(s))&&(o.push({type:"rule",category:"rule",data:i(s),priority:1}),r&&r.length>0&&o.push({type:"rule_content",category:"rule",data:i(r),priority:1})),o.push({type:"file_read",category:"file",data:i(s),priority:1}),o}if(e==="Edit"){let s=String(n.file_path??"");return o.push({type:"file_edit",category:"file",data:i(s),priority:1}),o}if(e==="NotebookEdit"){let s=String(n.notebook_path??"");return o.push({type:"file_edit",category:"file",data:i(s),priority:1}),o}if(e==="Write"){let s=String(n.file_path??"");return o.push({type:"file_write",category:"file",data:i(s),priority:1}),o}if(e==="apply_patch"){if(d(t))return[];let s=k(String(n.command??n.patch??""));for(let a of s)o.push({type:a.type,category:"file",data:i(a.path),priority:1});return o}if(e==="Glob"){let s=String(n.pattern??"");return o.push({type:"file_glob",category:"file",data:i(s),priority:3}),o}if(e==="Grep"){let s=String(n.pattern??""),a=String(n.path??"");return o.push({type:"file_search",category:"file",data:i(`${s} in ${a}`),priority:3}),o}return o}function R(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:i(r),priority:2}]}function
|
|
2
|
-
response: ${i(r)}`:"";return[{type:"mcp",category:"mcp",data:i(`${s}${u}${c}`),priority:3}]}var M=2048;function B(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 W=/(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,j="[REDACTED]";function y(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=>y(r,e));else{let r={};for(let[o,s]of Object.entries(t))W.test(o)?r[o]=j:r[o]=y(s,e);n=r}return e.delete(t),n}function
|
|
1
|
+
function i(t){return t==null?"":String(t)}function E(t){return t==null?"":typeof t=="string"?t:JSON.stringify(t)}function d(t){let e=String(t.tool_response??""),n=String(t.tool_input?.command??"");if(e.startsWith("context-mode:")||n.startsWith('echo "context-mode:')||n.startsWith("echo 'context-mode:"))return!1;let r=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)||r}function k(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 S(t){return/(?:^|[/\\])\.claude[/\\]plans[/\\]/.test(t)}function A(t){let{tool_name:e,tool_input:n,tool_response:r}=t,o=[];if(e==="Read"){let s=String(n.file_path??"");return(/(?:CLAUDE|AGENTS(?:\.override)?|GEMINI|QWEN|KIRO)\.md$/i.test(s)||/\/copilot-instructions\.md$/i.test(s)||/\/context-mode\.mdc$/i.test(s)||/\.claude[\\/]/i.test(s)||/[\\/]memor(?:y|ies)[\\/][^\\/]+\.md$/i.test(s))&&(o.push({type:"rule",category:"rule",data:i(s),priority:1}),r&&r.length>0&&o.push({type:"rule_content",category:"rule",data:i(r),priority:1})),o.push({type:"file_read",category:"file",data:i(s),priority:1}),o}if(e==="Edit"){let s=String(n.file_path??"");return o.push({type:"file_edit",category:"file",data:i(s),priority:1}),o}if(e==="NotebookEdit"){let s=String(n.notebook_path??"");return o.push({type:"file_edit",category:"file",data:i(s),priority:1}),o}if(e==="Write"){let s=String(n.file_path??"");return o.push({type:"file_write",category:"file",data:i(s),priority:1}),o}if(e==="apply_patch"){if(d(t))return[];let s=k(String(n.command??n.patch??""));for(let a of s)o.push({type:a.type,category:"file",data:i(a.path),priority:1});return o}if(e==="Glob"){let s=String(n.pattern??"");return o.push({type:"file_glob",category:"file",data:i(s),priority:3}),o}if(e==="Grep"){let s=String(n.pattern??""),a=String(n.path??"");return o.push({type:"file_search",category:"file",data:i(`${s} in ${a}`),priority:3}),o}return o}function R(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:i(r),priority:2}]}function T(t){let{tool_response:e}=t,n=String(e??"");return d(t)?[{type:"error_tool",category:"error",data:i(n),priority:2}]:[]}var x=[{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 w(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??""),n=x.find(r=>r.pattern.test(e));return n?[{type:"git",category:"git",data:i(n.operation),priority:2}]:[]}function I(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:i(JSON.stringify(t.tool_input)),priority:1}]:[]}function N(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: ${E(n.map(s=>typeof s=="object"&&s!==null&&"prompt"in s?String(s.prompt):String(s)).join(", "))})`:"exited plan mode";e.push({type:"plan_exit",category:"plan",data:i(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:i(`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(S(e))return[{type:"plan_file_write",category:"plan",data:i(`plan file: ${e.split(/[/\\]/).pop()??e}`),priority:2}]}return t.tool_name==="apply_patch"?d(t)?[]:k(String(t.tool_input.command??t.tool_input.patch??"")).filter(n=>S(n.path)).map(n=>({type:"plan_file_write",category:"plan",data:i(`plan file: ${n.path.split(/[/\\]/).pop()??n.path}`),priority:2})):[]}var C=[/\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 L(t){if(t.tool_name!=="Bash")return[];let e=String(t.tool_input.command??"");if(!C.some(o=>o.test(e)))return[];let r=e.replace(/\bexport\s+(\w+)=\S*/g,"export $1=***");return[{type:"env",category:"env",data:i(r),priority:2}]}function $(t){if(t.tool_name!=="Skill")return[];let e=String(t.tool_input.skill??"");return[{type:"skill",category:"skill",data:i(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 s=e.toLowerCase().indexOf(o[0].toLowerCase()),a=e.slice(Math.max(0,s-50),Math.min(e.length,s+200)).trim();return[{type:"constraint_discovered",category:"constraint",data:i(a),priority:2}]}}return[]}function O(t){if(t.tool_name!=="Agent")return[];let e=i(String(t.tool_input.prompt??t.tool_input.description??"")),n=t.tool_response?i(String(t.tool_response)):"",r=n.length>0;return[{type:r?"subagent_completed":"subagent_launched",category:"subagent",data:i(r?`[completed] ${e} \u2192 ${n}`:`[launched] ${e}`),priority:r?2:3}]}function P(t){let{tool_name:e,tool_input:n,tool_response:r}=t;if(!e.startsWith("mcp__"))return[];let o=e.split("__"),s=o[o.length-1]||e,a=Object.values(n).find(g=>typeof g=="string"),u=a?`: ${i(String(a))}`:"",c=r&&r.length>0?`
|
|
2
|
+
response: ${i(r)}`:"";return[{type:"mcp",category:"mcp",data:i(`${s}${u}${c}`),priority:3}]}var M=2048;function B(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 W=/(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,j="[REDACTED]";function y(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=>y(r,e));else{let r={};for(let[o,s]of Object.entries(t))W.test(o)?r[o]=j:r[o]=y(s,e);n=r}return e.delete(t),n}function D(t){let{tool_name:e,tool_input:n}=t;if(!e.startsWith("mcp__"))return[];let r=y(n??{}),o;try{o=JSON.stringify(r)}catch{o="{}"}let{value:s,truncated:a}=B(o,M),u=a?`{"tool_name":${JSON.stringify(e)},"params_raw":${JSON.stringify(s)},"truncated":true}`:`{"tool_name":${JSON.stringify(e)},"params":${s}}`;return[{type:"mcp_tool_call",category:"mcp_tool_call",data:i(u),priority:4}]}function F(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=String(t.tool_response??""),o="";try{let c=JSON.parse(r)?.answers;if(c&&typeof c=="object"){let g=f=>typeof f=="string"?f:Array.isArray(f)?f.filter(h=>typeof h=="string").join(" | "):"",m=n?g(c[n]):"";m?o=m:o=Object.values(c).map(g).filter(h=>h.length>0).join(" | ")}}catch{}let s=i(o),a=n?`Q: ${i(n)} \u2192 A: ${s}`:`answer: ${s}`;return[{type:"decision_question",category:"decision",data:i(a),priority:2}]}function U(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:i(e),priority:2}]}function G(t){let e=[E(t.tool_input),i(t.tool_response)].join(" ");if(e.length===0)return[];let n=new Set,r=e.match(/https?:\/\/[^\s)]+/g);if(r)for(let c of r)c=c.replace(/["'})\],;.]+$/,""),/localhost|127\.0\.0\.1/i.test(c)||n.add(c);let o=e.match(/(?<!\w)#(\d+)/g);if(o)for(let c of o)n.add(c);if(n.size===0)return[];let s,a=i(t.tool_response).match(/Fetched and indexed[^\(]*\(([\d.]+)\s*KB\)/i);if(a){let c=Number(a[1]);Number.isFinite(c)&&c>0&&(s=Math.round(c*1024))}let u={type:"external_ref",category:"external-ref",data:i(Array.from(n).join(", ")),priority:3};return s!==void 0&&(u.bytes_avoided=s),[u]}function K(t){if(t.tool_name!=="EnterWorktree")return[];let e=String(t.tool_input.name??"unnamed");return[{type:"worktree",category:"env",data:i(`entered worktree: ${e}`),priority:2}]}var v=/[,;,;、،]/u,J=15,q=500;function z(t){if(_.test(t)||!b.test(t)||!v.test(t))return!1;let e=[...t].length;return e>=J&&e<=q}function Q(t){let e=t.trim();return z(e)?[{type:"decision",category:"decision",data:i(t),priority:2}]:[]}var V=8,X=120,Y=new RegExp("\\p{L}+\\s+\\p{L}+","u"),Z=new RegExp("\\p{L}{6,}","u");function tt(t){let e=t.split(/[.!\n。!]/u)[0].trim();if(_.test(e)||v.test(e)||!b.test(e))return!1;let n=[...e].length;return n<V||n>X?!1:Y.test(e)||Z.test(e)}function et(t){let e=t.trim();return tt(e)?[{type:"role",category:"role",data:i(t),priority:3}]:[]}var _=/[??؟¿]/u,b=new RegExp("\\p{L}","u"),nt=60;function rt(t){if(_.test(t)||!b.test(t))return!1;let e=[...t].length;return e>0&&e<nt}function ot(t){let e=t.trim();if(!e)return[];let n;return _.test(e)?n="investigate":rt(e)&&(n="implement"),n?[{type:"intent",category:"intent",data:i(n),priority:4}]:[]}var st=/^(?:\/goal\s+|(?:goal|objective)\s*:\s*)(.+)$/is;function it(t){let e=t.trim();if(!e)return[];let n=e.match(st);if(!n)return[];let r=n[1].trim();return r?[{type:"goal",category:"goal",data:i(r),priority:4}]:[]}var at=/(?:\bError\s*:|\bException\s*:|\bTraceback\b|\bat\s+\S+\s*\([^)]*:\d+:\d+\))/u,ct=/[✓✔✅☑🎉]/u,lt=/^\s*(?:fixed|resolved)\s*:/iu;function pt(t){let e=[];return ct.test(t)||lt.test(t)?(e.push({type:"blocker_resolved",category:"blocked-on",data:i(t),priority:2}),e):(at.test(t)&&e.push({type:"blocker",category:"blocked-on",data:i(t),priority:2}),e)}function ut(t){return t.length<=1024?[]:[{type:"data",category:"data",data:i(t),priority:4}]}var l=null;function ft(t){let{tool_name:e,tool_response:n}=t,r=String(n??"");if(d(t))return l={tool:e,error:r.slice(0,200),callsSince:0},[];if(!l)return[];if(l.callsSince++,l.callsSince>10)return l=null,[];if(!!d(t))return[];let s=e===l.tool,a=l.tool==="Read"&&(e==="Edit"||e==="Write"||e==="apply_patch");if(s||a){let u={type:"error_resolved",category:"error-resolution",data:i(`Error in ${l.tool}: ${l.error} \u2192 Fixed`),priority:2};return l=null,[u]}return[]}function yt(){l=null}var p=[];function dt(t){return`${t.length}:${t.slice(0,20)}`}function gt(t){let{tool_name:e,tool_input:n}=t,r=dt(JSON.stringify(n).slice(0,200));if(p.push({tool:e,inputHash:r}),p.length>50&&p.splice(0,p.length-50),p.length<3)return[];let o=0;for(let s=p.length-1;s>=0&&(p[s].tool===e&&p[s].inputHash===r);s--)o++;return o>=3?(p.splice(p.length-o),[{type:"retry_detected",category:"iteration-loop",data:i(`${e} called ${o} times with similar input`),priority:2}]):[]}function bt(){p.length=0}var _t={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 ht(t){let e=_t[t.tool_name];return!e||e===t.tool_name?t:{...t,tool_name:e}}function mt(t){try{let e=ht(t),n=[];return n.push(...A(e)),n.push(...R(e)),n.push(...T(e)),n.push(...w(e)),n.push(...L(e)),n.push(...I(e)),n.push(...N(e)),n.push(...$(e)),n.push(...O(e)),n.push(...P(e)),n.push(...D(e)),n.push(...F(e)),n.push(...H(e)),n.push(...K(e)),n.push(...U(e)),n.push(...G(e)),n.push(...ft(e)),n.push(...gt(e)),n}catch{return[]}}function St(t){try{let e=[];return e.push(...Q(t)),e.push(...et(t)),e.push(...ot(t)),e.push(...it(t)),e.push(...pt(t)),e.push(...ut(t)),e}catch{return[]}}export{mt as extractEvents,St as extractUserEvents,yt as resetErrorResolutionState,bt as resetIterationLoopState};
|
|
@@ -175,6 +175,25 @@ export const KIRO_OPTS = {
|
|
|
175
175
|
sessionIdEnv: undefined, // No session ID env var — uses ppid fallback
|
|
176
176
|
};
|
|
177
177
|
|
|
178
|
+
/** Kimi Code CLI platform options.
|
|
179
|
+
*
|
|
180
|
+
* `KIMI_CODE_HOME` is documented at
|
|
181
|
+
* refs/platforms/kimi-code/docs/zh/configuration/env-vars.md:11-21
|
|
182
|
+
* refs/platforms/kimi-code/docs/en/configuration/env-vars.md:9-21
|
|
183
|
+
* and is read by MoonshotAI's own first-party plugins
|
|
184
|
+
* refs/platforms/kimi-code/plugins/official/kimi-datasource/bin/
|
|
185
|
+
* kimi-datasource.mjs:207-210
|
|
186
|
+
* so context-mode must honour it too — otherwise relocated Kimi installs
|
|
187
|
+
* keep the user's data root at `$KIMI_CODE_HOME` while context-mode keeps
|
|
188
|
+
* its session DB stranded at `~/.kimi-code/context-mode/sessions/`.
|
|
189
|
+
*/
|
|
190
|
+
export const KIMI_OPTS = {
|
|
191
|
+
configDir: ".kimi-code",
|
|
192
|
+
configDirEnv: "KIMI_CODE_HOME",
|
|
193
|
+
projectDirEnv: undefined, // Kimi Code passes cwd in hook stdin, no env var
|
|
194
|
+
sessionIdEnv: undefined, // Uses session_id from hook stdin or ppid fallback
|
|
195
|
+
};
|
|
196
|
+
|
|
178
197
|
/** JetBrains Copilot platform options. */
|
|
179
198
|
export const JETBRAINS_OPTS = {
|
|
180
199
|
configDir: ".config/JetBrains",
|
|
@@ -212,15 +231,86 @@ export function parseStdin(raw) {
|
|
|
212
231
|
|
|
213
232
|
/**
|
|
214
233
|
* Read all of stdin as a string (event-based, cross-platform safe).
|
|
234
|
+
*
|
|
235
|
+
* Idle-timeout semantics (override via env `CONTEXT_MODE_HOOK_STDIN_IDLE_MS`,
|
|
236
|
+
* default 1500 ms):
|
|
237
|
+
* - EOF before any data \u2192 resolve("") \u2014 the original well-behaved path.
|
|
238
|
+
* - EOF after data \u2192 resolve(buffer) with BOM strip (#139 \u2014 Cursor on
|
|
239
|
+
* Windows can emit a leading U+FEFF that crashes
|
|
240
|
+
* downstream JSON.parse).
|
|
241
|
+
* - Idle with 0 bytes \u2192 resolve("") \u2014 covers hosts that hold the pipe open
|
|
242
|
+
* without ever closing it (issue #639 \u2014 Bun re-exec
|
|
243
|
+
* EOF path) so the hook still terminates.
|
|
244
|
+
* - Idle with > 0 bytes \u2192 reject(Error) \u2014 partial data after a stall MUST NOT
|
|
245
|
+
* be silently truncated, otherwise downstream
|
|
246
|
+
* JSON.parse corrupts on large `tool_response`
|
|
247
|
+
* payloads (issue #242 \u2014 Gemini AfterTool >1MB).
|
|
248
|
+
* Visible non-zero exit is correct here; the host
|
|
249
|
+
* surfaces the failure in its hook diagnostics.
|
|
215
250
|
*/
|
|
216
251
|
export function readStdin() {
|
|
217
252
|
return new Promise((resolve, reject) => {
|
|
218
253
|
let data = "";
|
|
254
|
+
const idleMs = Number(process.env.CONTEXT_MODE_HOOK_STDIN_IDLE_MS || 1500);
|
|
255
|
+
let done = false;
|
|
256
|
+
let timer;
|
|
257
|
+
|
|
258
|
+
const cleanup = () => {
|
|
259
|
+
clearTimeout(timer);
|
|
260
|
+
process.stdin.removeListener("data", onData);
|
|
261
|
+
process.stdin.removeListener("end", onEnd);
|
|
262
|
+
process.stdin.removeListener("error", onError);
|
|
263
|
+
try { process.stdin.pause(); } catch {}
|
|
264
|
+
try { process.stdin.destroy?.(); } catch {}
|
|
265
|
+
};
|
|
266
|
+
const resolveBuffer = () => {
|
|
267
|
+
if (done) return;
|
|
268
|
+
done = true;
|
|
269
|
+
cleanup();
|
|
270
|
+
// Preserves #139 BOM strip \u2014 applies on both EOF and idle-empty paths.
|
|
271
|
+
resolve(data.replace(/^\uFEFF/, ""));
|
|
272
|
+
};
|
|
273
|
+
const rejectIdle = () => {
|
|
274
|
+
if (done) return;
|
|
275
|
+
done = true;
|
|
276
|
+
cleanup();
|
|
277
|
+
reject(new Error(
|
|
278
|
+
`stdin idle for ${idleMs}ms with ${data.length} bytes buffered`,
|
|
279
|
+
));
|
|
280
|
+
};
|
|
281
|
+
const onIdle = () => {
|
|
282
|
+
// Zero-buffer idle = host never wrote anything (issue #639). Resolve
|
|
283
|
+
// empty so the hook can no-op. Non-zero buffer = partial data, which
|
|
284
|
+
// must reject to avoid silent JSON.parse corruption (issue #242).
|
|
285
|
+
if (data.length === 0) {
|
|
286
|
+
resolveBuffer();
|
|
287
|
+
} else {
|
|
288
|
+
rejectIdle();
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
const arm = () => {
|
|
292
|
+
clearTimeout(timer);
|
|
293
|
+
timer = setTimeout(onIdle, idleMs);
|
|
294
|
+
timer.unref?.();
|
|
295
|
+
};
|
|
296
|
+
const onData = (chunk) => {
|
|
297
|
+
data += chunk;
|
|
298
|
+
arm();
|
|
299
|
+
};
|
|
300
|
+
const onEnd = () => resolveBuffer();
|
|
301
|
+
const onError = (error) => {
|
|
302
|
+
if (done) return;
|
|
303
|
+
done = true;
|
|
304
|
+
cleanup();
|
|
305
|
+
reject(error);
|
|
306
|
+
};
|
|
307
|
+
|
|
219
308
|
process.stdin.setEncoding("utf-8");
|
|
220
|
-
process.stdin.on("data",
|
|
221
|
-
process.stdin.on("end",
|
|
222
|
-
process.stdin.on("error",
|
|
309
|
+
process.stdin.on("data", onData);
|
|
310
|
+
process.stdin.on("end", onEnd);
|
|
311
|
+
process.stdin.on("error", onError);
|
|
223
312
|
process.stdin.resume();
|
|
313
|
+
arm();
|
|
224
314
|
});
|
|
225
315
|
}
|
|
226
316
|
|
|
@@ -1,31 +1,32 @@
|
|
|
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 B=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
4
|
queries: [${e}],
|
|
5
5
|
source: "session-events"
|
|
6
|
-
)`}function
|
|
7
|
-
`)}function
|
|
8
|
-
`)}function
|
|
9
|
-
`)}function
|
|
10
|
-
`)}function
|
|
11
|
-
`)}function
|
|
12
|
-
`)}function
|
|
6
|
+
)`}function G(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(-B),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 J(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 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),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 z(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 P(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 H(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 K(t,r){let e=H(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
13
|
`).length}">`,e,m(r,o)," </task_state>"].join(`
|
|
14
|
-
`)}function
|
|
15
|
-
`)}function
|
|
16
|
-
`)}function
|
|
17
|
-
`)}function
|
|
18
|
-
`)}function
|
|
19
|
-
`)}function
|
|
14
|
+
`)}function Q(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 U(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 V(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 W(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 Y(t){if(t.length===0)return"";let r=t[t.length-1];return` <intent mode="${a(r.data)}"/>`}function Z(t){if(t.length===0)return"";let r=t[t.length-1];return[" <session_goal>"," The active objective for this session. Keep working toward it until it is met; do not ask the user to restate it.",` ${a(r.data)}`," </session_goal>"].join(`
|
|
19
|
+
`)}var tt=3,nt=400;function et(t,r){let e=[...t];return e.length<=r?t:e.slice(0,r).join("")}function st(t){if(t.length===0)return"";let e=t.slice(-tt).map(n=>{let o=et(n.data??"",nt);return o?` <message>${a(o)}</message>`:""}).filter(Boolean);return e.length===0?"":[` <recent_user_messages count="${e.length}">`,...e," </recent_user_messages>"].join(`
|
|
20
|
+
`)}function it(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=[],E=[];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"goal":k.push(g);break;case"skill":$.push(g);break;case"role":v.push(g);break;case"user-prompt":E.push(g);break}let l=[];l.push(` <how_to_search>
|
|
20
21
|
Each section below contains a summary of prior work.
|
|
21
22
|
For FULL DETAILS, run the exact tool call shown under each section.
|
|
22
23
|
Do NOT ask the user to re-explain prior work. Search first.
|
|
23
24
|
Do NOT invent your own queries \u2014 use the ones provided.
|
|
24
|
-
</how_to_search>`);let
|
|
25
|
+
</how_to_search>`);let _=Z(k);_&&l.push(_);let w=G(c,n);w&&l.push(w);let j=J(S,n);j&&l.push(j);let q=X(u,n);q&&l.push(q);let T=z(s,n);T&&l.push(T);let L=P(d,n);L&&l.push(L);let M=K(i,n);M&&l.push(M);let C=Q(f,p,n);C&&l.push(C);let A=U(b,n);A&&l.push(A);let I=V($,n);I&&l.push(I);let N=W(v,n);N&&l.push(N);let O=Y(y);O&&l.push(O);let R=st(E);R&&l.push(R);let x=`<session_resume events="${t.length}" compact_count="${e}" generated_at="${o}">`,D="</session_resume>",F=l.join(`
|
|
25
26
|
|
|
26
|
-
`);return
|
|
27
|
+
`);return F?`${x}
|
|
27
28
|
|
|
28
|
-
${
|
|
29
|
+
${F}
|
|
29
30
|
|
|
30
|
-
${
|
|
31
|
-
${
|
|
31
|
+
${D}`:`${x}
|
|
32
|
+
${D}`}export{it as buildResumeSnapshot,H as renderTaskState};
|
package/hooks/sessionstart.mjs
CHANGED
|
@@ -51,6 +51,70 @@ await runHook(async () => {
|
|
|
51
51
|
const HOOK_DIR = dirname(fileURLToPath(import.meta.url));
|
|
52
52
|
const { loadSessionDB } = createSessionLoaders(HOOK_DIR);
|
|
53
53
|
|
|
54
|
+
// Self-heal a partial plugin cache install before anything else
|
|
55
|
+
// touches the cache dir. The Algo-D4 boot gate and the #604
|
|
56
|
+
// normalize-hooks ratchet both fire from start.mjs, which is one of
|
|
57
|
+
// the files that may be missing in the failure mode; sessionstart.mjs
|
|
58
|
+
// fires from CC's hooks.json wiring regardless of MCP boot status, so
|
|
59
|
+
// it is the reliably-available entry point. See
|
|
60
|
+
// hooks/heal-partial-install.mjs for the full failure-mode description.
|
|
61
|
+
try {
|
|
62
|
+
const { healPartialInstallFromMarketplace } = await import("./heal-partial-install.mjs");
|
|
63
|
+
healPartialInstallFromMarketplace();
|
|
64
|
+
} catch { /* best effort, never block session start */ }
|
|
65
|
+
|
|
66
|
+
// Issue #710 — Layer 2: self-heal Claude Code's per-session shell snapshots.
|
|
67
|
+
//
|
|
68
|
+
// Claude Code `source`s ~/.claude/shell-snapshots/snapshot-*.sh before every
|
|
69
|
+
// Bash tool call (refs/platforms/claude-code/src/utils/bash/ShellSnapshot.ts:269-336,
|
|
70
|
+
// sourced at bashProvider.ts:166). The snapshot bakes an `export PATH='…'`
|
|
71
|
+
// line with the context-mode `bin/` of the version active at session boot.
|
|
72
|
+
// After /ctx-upgrade deletes the old cache dir, the snapshot still points
|
|
73
|
+
// at it — every Bash call fails with "Plugin directory does not exist"
|
|
74
|
+
// until the session restarts.
|
|
75
|
+
//
|
|
76
|
+
// Layer 1 (cli.ts /ctx-upgrade) rewrites the active session's snapshot
|
|
77
|
+
// mid-upgrade so the in-process session never sees the broken state.
|
|
78
|
+
// Layer 2 (this) catches sessions that started after /ctx-upgrade but
|
|
79
|
+
// whose snapshots somehow missed the rewrite (parallel sessions, killed
|
|
80
|
+
// /ctx-upgrade run, manual cache surgery). Resolves currentVersion from
|
|
81
|
+
// the plugin's own manifest — no env-var dependency, immune to PATH bugs.
|
|
82
|
+
// Best-effort, never blocks session start.
|
|
83
|
+
try {
|
|
84
|
+
const { selfHealShellSnapshots } = await import("./cache-heal-utils.mjs");
|
|
85
|
+
const { resolve } = await import("node:path");
|
|
86
|
+
const { resolveConfigDir } = await import("./session-helpers.mjs");
|
|
87
|
+
|
|
88
|
+
// Read the version this MCP boot is running under. PLUGIN_ROOT
|
|
89
|
+
// points at ~/.claude/plugins/cache/context-mode/context-mode/<vX>/.
|
|
90
|
+
let currentVersion = null;
|
|
91
|
+
try {
|
|
92
|
+
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT
|
|
93
|
+
?? resolve(HOOK_DIR, "..");
|
|
94
|
+
const manifestPath = resolve(pluginRoot, ".claude-plugin", "plugin.json");
|
|
95
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
96
|
+
if (typeof manifest?.version === "string" && manifest.version) {
|
|
97
|
+
currentVersion = manifest.version;
|
|
98
|
+
}
|
|
99
|
+
} catch { /* missing/malformed manifest — skip self-heal */ }
|
|
100
|
+
|
|
101
|
+
if (currentVersion) {
|
|
102
|
+
const snapshotsDir = resolve(resolveConfigDir(), "shell-snapshots");
|
|
103
|
+
const pluginCacheRoot = resolve(
|
|
104
|
+
resolveConfigDir(),
|
|
105
|
+
"plugins",
|
|
106
|
+
"cache",
|
|
107
|
+
"context-mode",
|
|
108
|
+
"context-mode",
|
|
109
|
+
);
|
|
110
|
+
selfHealShellSnapshots({
|
|
111
|
+
snapshotsDir,
|
|
112
|
+
pluginCacheRoot,
|
|
113
|
+
currentVersion,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
} catch { /* best effort, never block session start */ }
|
|
117
|
+
|
|
54
118
|
let additionalContext = ROUTING_BLOCK;
|
|
55
119
|
|
|
56
120
|
// ─── #558: surface security init failure as agent-facing context ───
|
package/insight/server.mjs
CHANGED
|
@@ -448,6 +448,10 @@ function apiAnalytics() {
|
|
|
448
448
|
safeAll(db, `SELECT data as detail, created_at, session_id FROM session_events
|
|
449
449
|
WHERE type = 'error_tool' OR type = 'error' ORDER BY created_at DESC LIMIT 20`)
|
|
450
450
|
);
|
|
451
|
+
const errorCounts = queryAllSessionDBs(db =>
|
|
452
|
+
safeAll(db, `SELECT COUNT(*) as count FROM session_events
|
|
453
|
+
WHERE type = 'error_tool' OR type = 'error'`)
|
|
454
|
+
);
|
|
451
455
|
const fileActivity = queryAllSessionDBs(db =>
|
|
452
456
|
safeAll(db, `SELECT data as file, type as op, COUNT(*) as count FROM session_events
|
|
453
457
|
WHERE type IN ('file_read', 'file_write', 'file') AND data != ''
|
|
@@ -563,17 +567,25 @@ function apiAnalytics() {
|
|
|
563
567
|
safeAll(db, `SELECT substr(data, 1, 100) as task, created_at FROM session_events
|
|
564
568
|
WHERE type = 'task' ORDER BY created_at DESC LIMIT 20`)
|
|
565
569
|
);
|
|
570
|
+
const taskCounts = queryAllSessionDBs(db =>
|
|
571
|
+
safeAll(db, `SELECT COUNT(*) as count FROM session_events WHERE type = 'task'`)
|
|
572
|
+
);
|
|
566
573
|
const prompts = queryAllSessionDBs(db =>
|
|
567
574
|
safeAll(db, `SELECT substr(data, 1, 100) as prompt, created_at, session_id FROM session_events
|
|
568
575
|
WHERE type = 'user_prompt' ORDER BY created_at DESC LIMIT 20`)
|
|
569
576
|
);
|
|
577
|
+
const promptCounts = queryAllSessionDBs(db =>
|
|
578
|
+
safeAll(db, `SELECT COUNT(*) as count FROM session_events WHERE type = 'user_prompt'`)
|
|
579
|
+
);
|
|
570
580
|
|
|
571
581
|
const rw = readWriteRatio.reduce((a, b) => ({
|
|
572
582
|
reads: (a.reads || 0) + (b.reads || 0), writes: (a.writes || 0) + (b.writes || 0),
|
|
573
583
|
total_file_ops: (a.total_file_ops || 0) + (b.total_file_ops || 0),
|
|
574
584
|
}), { reads: 0, writes: 0, total_file_ops: 0 });
|
|
575
585
|
const totalEvents = toolUsage.reduce((a, b) => a + b.count, 0);
|
|
576
|
-
const totalErrors =
|
|
586
|
+
const totalErrors = errorCounts.reduce((a, b) => a + (b.count || 0), 0);
|
|
587
|
+
const totalTasks = taskCounts.reduce((a, b) => a + (b.count || 0), 0);
|
|
588
|
+
const totalPrompts = promptCounts.reduce((a, b) => a + (b.count || 0), 0);
|
|
577
589
|
const totalCompacts = sessionDurations.reduce((a, b) => a + (b.compact_count || 0), 0);
|
|
578
590
|
const sessionsWithCompact = sessionDurations.filter(s => s.compact_count > 0).length;
|
|
579
591
|
|
|
@@ -706,9 +718,9 @@ function apiAnalytics() {
|
|
|
706
718
|
reads: rw.reads, writes: rw.writes,
|
|
707
719
|
readWriteRatio: rw.writes > 0 ? Math.round(10 * rw.reads / rw.writes) / 10 : rw.reads,
|
|
708
720
|
totalFileOps: rw.total_file_ops, totalSubagents: subagents.total,
|
|
709
|
-
totalTasks
|
|
721
|
+
totalTasks, totalPrompts,
|
|
710
722
|
promptsPerSession: sessionDurations.length > 0
|
|
711
|
-
? Math.round(10 *
|
|
723
|
+
? Math.round(10 * totalPrompts / sessionDurations.length) / 10 : 0,
|
|
712
724
|
uniqueProjects: nonUnknownProjects.length,
|
|
713
725
|
totalCommits: commitRate.reduce((a, b) => a + (b.commits || 0), 0),
|
|
714
726
|
commitsPerSession: sessionDurations.length > 0
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,12 +3,27 @@
|
|
|
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.152",
|
|
7
7
|
"sandbox": {
|
|
8
8
|
"mode": "permissive",
|
|
9
9
|
"filesystem_access": "full",
|
|
10
10
|
"system_access": "full"
|
|
11
11
|
},
|
|
12
|
+
"contracts": {
|
|
13
|
+
"tools": [
|
|
14
|
+
"ctx_execute",
|
|
15
|
+
"ctx_execute_file",
|
|
16
|
+
"ctx_index",
|
|
17
|
+
"ctx_search",
|
|
18
|
+
"ctx_fetch_and_index",
|
|
19
|
+
"ctx_batch_execute",
|
|
20
|
+
"ctx_stats",
|
|
21
|
+
"ctx_doctor",
|
|
22
|
+
"ctx_upgrade",
|
|
23
|
+
"ctx_purge",
|
|
24
|
+
"ctx_insight"
|
|
25
|
+
]
|
|
26
|
+
},
|
|
12
27
|
"configSchema": {
|
|
13
28
|
"type": "object",
|
|
14
29
|
"properties": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "context-mode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.152",
|
|
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",
|