context-mode 1.0.41 → 1.0.42
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 +49 -49
- package/build/openclaw-plugin.js +1 -1
- package/build/opencode-plugin.js +1 -1
- package/build/server.js +11 -7
- package/cli.bundle.mjs +77 -77
- package/hooks/core/routing.mjs +29 -11
- package/hooks/core/tool-naming.mjs +50 -0
- package/hooks/cursor/pretooluse.mjs +1 -1
- package/hooks/cursor/sessionstart.mjs +4 -1
- package/hooks/gemini-cli/beforetool.mjs +1 -1
- package/hooks/gemini-cli/sessionstart.mjs +4 -1
- package/hooks/kiro/pretooluse.mjs +1 -1
- package/hooks/pretooluse.mjs +1 -1
- package/hooks/routing-block.mjs +34 -8
- package/hooks/sessionstart.mjs +4 -1
- package/hooks/vscode-copilot/pretooluse.mjs +1 -1
- package/hooks/vscode-copilot/sessionstart.mjs +4 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/server.bundle.mjs +52 -52
- package/start.mjs +8 -65
package/hooks/core/routing.mjs
CHANGED
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
* - null (passthrough)
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
ROUTING_BLOCK, READ_GUIDANCE, GREP_GUIDANCE, BASH_GUIDANCE,
|
|
15
|
+
createRoutingBlock, createReadGuidance, createGrepGuidance, createBashGuidance,
|
|
16
|
+
} from "../routing-block.mjs";
|
|
17
|
+
import { createToolNamer } from "./tool-naming.mjs";
|
|
14
18
|
import { existsSync, mkdirSync, rmSync, openSync, closeSync, constants as fsConstants } from "node:fs";
|
|
15
19
|
import { tmpdir } from "node:os";
|
|
16
20
|
import { resolve } from "node:path";
|
|
@@ -129,8 +133,22 @@ const TOOL_ALIASES = {
|
|
|
129
133
|
|
|
130
134
|
/**
|
|
131
135
|
* Route a PreToolUse event. Returns normalized decision object or null for passthrough.
|
|
136
|
+
*
|
|
137
|
+
* @param {string} toolName - The tool name as reported by the platform
|
|
138
|
+
* @param {object} toolInput - The tool input/parameters
|
|
139
|
+
* @param {string} [projectDir] - Project directory for security policy lookup
|
|
140
|
+
* @param {string} [platform="claude-code"] - Platform ID for tool name formatting
|
|
132
141
|
*/
|
|
133
|
-
export function routePreToolUse(toolName, toolInput, projectDir) {
|
|
142
|
+
export function routePreToolUse(toolName, toolInput, projectDir, platform) {
|
|
143
|
+
// Build platform-specific tool namer (defaults to claude-code for backward compat)
|
|
144
|
+
const t = createToolNamer(platform || "claude-code");
|
|
145
|
+
|
|
146
|
+
// Build platform-specific guidance/routing content
|
|
147
|
+
const routingBlock = platform ? createRoutingBlock(t) : ROUTING_BLOCK;
|
|
148
|
+
const readGuidance = platform ? createReadGuidance(t) : READ_GUIDANCE;
|
|
149
|
+
const grepGuidance = platform ? createGrepGuidance(t) : GREP_GUIDANCE;
|
|
150
|
+
const bashGuidance = platform ? createBashGuidance(t) : BASH_GUIDANCE;
|
|
151
|
+
|
|
134
152
|
// Normalize platform-specific tool name to canonical
|
|
135
153
|
const canonical = TOOL_ALIASES[toolName] ?? toolName;
|
|
136
154
|
|
|
@@ -167,7 +185,7 @@ export function routePreToolUse(toolName, toolInput, projectDir) {
|
|
|
167
185
|
return {
|
|
168
186
|
action: "modify",
|
|
169
187
|
updatedInput: {
|
|
170
|
-
command:
|
|
188
|
+
command: `echo "context-mode: curl/wget blocked. You MUST use ${t("ctx_fetch_and_index")}(url, source) to fetch URLs, or ${t("ctx_execute")}(language, code) to run HTTP calls in sandbox. Do NOT retry with curl/wget."`,
|
|
171
189
|
},
|
|
172
190
|
};
|
|
173
191
|
}
|
|
@@ -186,7 +204,7 @@ export function routePreToolUse(toolName, toolInput, projectDir) {
|
|
|
186
204
|
return {
|
|
187
205
|
action: "modify",
|
|
188
206
|
updatedInput: {
|
|
189
|
-
command:
|
|
207
|
+
command: `echo "context-mode: Inline HTTP blocked. Use ${t("ctx_execute")}(language, code) to run HTTP calls in sandbox, or ${t("ctx_fetch_and_index")}(url, source) for web pages. Do NOT retry with Bash."`,
|
|
190
208
|
},
|
|
191
209
|
};
|
|
192
210
|
}
|
|
@@ -198,23 +216,23 @@ export function routePreToolUse(toolName, toolInput, projectDir) {
|
|
|
198
216
|
return {
|
|
199
217
|
action: "modify",
|
|
200
218
|
updatedInput: {
|
|
201
|
-
command: `echo "context-mode: Build tool redirected to sandbox. Use
|
|
219
|
+
command: `echo "context-mode: Build tool redirected to sandbox. Use ${t("ctx_execute")}(language: \\"shell\\", code: \\"${safeCmd}\\") to run this command. Do NOT retry with Bash."`,
|
|
202
220
|
},
|
|
203
221
|
};
|
|
204
222
|
}
|
|
205
223
|
|
|
206
224
|
// allow all other Bash commands, but inject routing nudge (once per session)
|
|
207
|
-
return guidanceOnce("bash",
|
|
225
|
+
return guidanceOnce("bash", bashGuidance);
|
|
208
226
|
}
|
|
209
227
|
|
|
210
228
|
// ─── Read: nudge toward execute_file (once per session) ───
|
|
211
229
|
if (canonical === "Read") {
|
|
212
|
-
return guidanceOnce("read",
|
|
230
|
+
return guidanceOnce("read", readGuidance);
|
|
213
231
|
}
|
|
214
232
|
|
|
215
233
|
// ─── Grep: nudge toward execute (once per session) ───
|
|
216
234
|
if (canonical === "Grep") {
|
|
217
|
-
return guidanceOnce("grep",
|
|
235
|
+
return guidanceOnce("grep", grepGuidance);
|
|
218
236
|
}
|
|
219
237
|
|
|
220
238
|
// ─── WebFetch: deny + redirect to sandbox ───
|
|
@@ -222,7 +240,7 @@ export function routePreToolUse(toolName, toolInput, projectDir) {
|
|
|
222
240
|
const url = toolInput.url ?? "";
|
|
223
241
|
return {
|
|
224
242
|
action: "deny",
|
|
225
|
-
reason: `context-mode: WebFetch blocked. Use
|
|
243
|
+
reason: `context-mode: WebFetch blocked. Use ${t("ctx_fetch_and_index")}(url: "${url}", source: "...") to fetch this URL in sandbox. Then use ${t("ctx_search")}(queries: [...]) to query results. Do NOT use curl, wget, mcp_web_fetch, or mcp_fetch_tool.`,
|
|
226
244
|
};
|
|
227
245
|
}
|
|
228
246
|
|
|
@@ -235,8 +253,8 @@ export function routePreToolUse(toolName, toolInput, projectDir) {
|
|
|
235
253
|
|
|
236
254
|
const updatedInput =
|
|
237
255
|
subagentType === "Bash"
|
|
238
|
-
? { ...toolInput, [fieldName]: prompt +
|
|
239
|
-
: { ...toolInput, [fieldName]: prompt +
|
|
256
|
+
? { ...toolInput, [fieldName]: prompt + routingBlock, subagent_type: "general-purpose" }
|
|
257
|
+
: { ...toolInput, [fieldName]: prompt + routingBlock };
|
|
240
258
|
|
|
241
259
|
return { action: "modify", updatedInput };
|
|
242
260
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-aware MCP tool naming.
|
|
3
|
+
* Each platform has its own convention for how MCP tool names appear to the LLM.
|
|
4
|
+
*
|
|
5
|
+
* Evidence-based naming conventions (from official docs):
|
|
6
|
+
* | Platform | Pattern |
|
|
7
|
+
* |--------------------|------------------------------------------------------------|
|
|
8
|
+
* | Claude Code | mcp__plugin_context-mode_context-mode__<tool> |
|
|
9
|
+
* | Gemini CLI | mcp__context-mode__<tool> |
|
|
10
|
+
* | Antigravity | mcp__context-mode__<tool> |
|
|
11
|
+
* | OpenCode | context-mode_<tool> |
|
|
12
|
+
* | VS Code Copilot | context-mode_<tool> |
|
|
13
|
+
* | Kiro | @context-mode/<tool> |
|
|
14
|
+
* | Zed | mcp:context-mode:<tool> |
|
|
15
|
+
* | Cursor / Codex / OpenClaw / Pi | bare <tool> |
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const TOOL_PREFIXES = {
|
|
19
|
+
"claude-code": (tool) => `mcp__plugin_context-mode_context-mode__${tool}`,
|
|
20
|
+
"gemini-cli": (tool) => `mcp__context-mode__${tool}`,
|
|
21
|
+
"antigravity": (tool) => `mcp__context-mode__${tool}`,
|
|
22
|
+
"opencode": (tool) => `context-mode_${tool}`,
|
|
23
|
+
"vscode-copilot": (tool) => `context-mode_${tool}`,
|
|
24
|
+
"kiro": (tool) => `@context-mode/${tool}`,
|
|
25
|
+
"zed": (tool) => `mcp:context-mode:${tool}`,
|
|
26
|
+
"cursor": (tool) => tool,
|
|
27
|
+
"codex": (tool) => tool,
|
|
28
|
+
"openclaw": (tool) => tool,
|
|
29
|
+
"pi": (tool) => tool,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get the platform-specific MCP tool name for a bare tool name.
|
|
34
|
+
* Falls back to claude-code convention if platform is unknown.
|
|
35
|
+
*/
|
|
36
|
+
export function getToolName(platform, bareTool) {
|
|
37
|
+
const fn = TOOL_PREFIXES[platform] || TOOL_PREFIXES["claude-code"];
|
|
38
|
+
return fn(bareTool);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Create a namer function bound to a specific platform.
|
|
43
|
+
* Returns (bareTool) => platformSpecificToolName.
|
|
44
|
+
*/
|
|
45
|
+
export function createToolNamer(platform) {
|
|
46
|
+
return (bareTool) => getToolName(platform, bareTool);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** List of all known platform IDs. */
|
|
50
|
+
export const KNOWN_PLATFORMS = Object.keys(TOOL_PREFIXES);
|
|
@@ -19,7 +19,7 @@ const tool = input.tool_name ?? "";
|
|
|
19
19
|
const toolInput = input.tool_input ?? {};
|
|
20
20
|
const projectDir = getInputProjectDir(input, CURSOR_OPTS);
|
|
21
21
|
|
|
22
|
-
const decision = routePreToolUse(tool, toolInput, projectDir);
|
|
22
|
+
const decision = routePreToolUse(tool, toolInput, projectDir, "cursor");
|
|
23
23
|
const response = formatDecision("cursor", decision);
|
|
24
24
|
// Cursor treats empty stdout as an invalid hook response,
|
|
25
25
|
// so even passthrough decisions must emit a syntactically valid no-op payload.
|
|
@@ -4,7 +4,10 @@ import "../suppress-stderr.mjs";
|
|
|
4
4
|
* Cursor sessionStart hook for context-mode.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { createRoutingBlock } from "../routing-block.mjs";
|
|
8
|
+
import { createToolNamer } from "../core/tool-naming.mjs";
|
|
9
|
+
|
|
10
|
+
const ROUTING_BLOCK = createRoutingBlock(createToolNamer("cursor"));
|
|
8
11
|
import {
|
|
9
12
|
writeSessionEventsFile,
|
|
10
13
|
buildSessionDirective,
|
|
@@ -19,7 +19,7 @@ const input = JSON.parse(raw);
|
|
|
19
19
|
const tool = input.tool_name ?? "";
|
|
20
20
|
const toolInput = input.tool_input ?? {};
|
|
21
21
|
|
|
22
|
-
const decision = routePreToolUse(tool, toolInput, process.env.GEMINI_PROJECT_DIR || process.env.CLAUDE_PROJECT_DIR);
|
|
22
|
+
const decision = routePreToolUse(tool, toolInput, process.env.GEMINI_PROJECT_DIR || process.env.CLAUDE_PROJECT_DIR, "gemini-cli");
|
|
23
23
|
const response = formatDecision("gemini-cli", decision);
|
|
24
24
|
if (response !== null) {
|
|
25
25
|
process.stdout.write(JSON.stringify(response) + "\n");
|
|
@@ -10,7 +10,10 @@ import "../suppress-stderr.mjs";
|
|
|
10
10
|
* - "clear" → No action needed
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { createRoutingBlock } from "../routing-block.mjs";
|
|
14
|
+
import { createToolNamer } from "../core/tool-naming.mjs";
|
|
15
|
+
|
|
16
|
+
const ROUTING_BLOCK = createRoutingBlock(createToolNamer("gemini-cli"));
|
|
14
17
|
import { writeSessionEventsFile, buildSessionDirective, getSessionEvents, getLatestSessionEvents } from "../session-directive.mjs";
|
|
15
18
|
import {
|
|
16
19
|
readStdin, getSessionId, getSessionDBPath, getSessionEventsPath, getCleanupFlagPath,
|
|
@@ -24,7 +24,7 @@ const tool = input.tool_name ?? "";
|
|
|
24
24
|
const toolInput = input.tool_input ?? {};
|
|
25
25
|
const projectDir = input.cwd ?? process.cwd();
|
|
26
26
|
|
|
27
|
-
const decision = routePreToolUse(tool, toolInput, projectDir);
|
|
27
|
+
const decision = routePreToolUse(tool, toolInput, projectDir, "kiro");
|
|
28
28
|
|
|
29
29
|
if (!decision) process.exit(0);
|
|
30
30
|
|
package/hooks/pretooluse.mjs
CHANGED
|
@@ -136,7 +136,7 @@ const tool = input.tool_name ?? "";
|
|
|
136
136
|
const toolInput = input.tool_input ?? {};
|
|
137
137
|
|
|
138
138
|
// ─── Route and format response ───
|
|
139
|
-
const decision = routePreToolUse(tool, toolInput, process.env.CLAUDE_PROJECT_DIR);
|
|
139
|
+
const decision = routePreToolUse(tool, toolInput, process.env.CLAUDE_PROJECT_DIR, "claude-code");
|
|
140
140
|
const response = formatDecision("claude-code", decision);
|
|
141
141
|
if (response !== null) {
|
|
142
142
|
process.stdout.write(JSON.stringify(response) + "\n");
|
package/hooks/routing-block.mjs
CHANGED
|
@@ -1,28 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared routing block for context-mode hooks.
|
|
3
3
|
* Single source of truth — imported by pretooluse.mjs and sessionstart.mjs.
|
|
4
|
+
*
|
|
5
|
+
* Factory functions accept a tool namer `t(bareTool) => platformSpecificName`
|
|
6
|
+
* so each platform gets correct tool names in guidance messages.
|
|
7
|
+
*
|
|
8
|
+
* Backward compat: static exports (ROUTING_BLOCK, READ_GUIDANCE, etc.)
|
|
9
|
+
* default to claude-code naming convention.
|
|
4
10
|
*/
|
|
5
11
|
|
|
6
|
-
|
|
12
|
+
import { createToolNamer } from "./core/tool-naming.mjs";
|
|
13
|
+
|
|
14
|
+
// ── Factory functions ─────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
export function createRoutingBlock(t) {
|
|
17
|
+
return `
|
|
7
18
|
<context_window_protection>
|
|
8
19
|
<priority_instructions>
|
|
9
20
|
Raw tool output floods your context window. You MUST use context-mode MCP tools to keep raw data in the sandbox.
|
|
10
21
|
</priority_instructions>
|
|
11
22
|
|
|
12
23
|
<tool_selection_hierarchy>
|
|
13
|
-
1. GATHER:
|
|
24
|
+
1. GATHER: ${t("ctx_batch_execute")}(commands, queries)
|
|
14
25
|
- Primary tool for research. Runs all commands, auto-indexes, and searches.
|
|
15
26
|
- ONE call replaces many individual steps.
|
|
16
|
-
2. FOLLOW-UP:
|
|
27
|
+
2. FOLLOW-UP: ${t("ctx_search")}(queries: ["q1", "q2", ...])
|
|
17
28
|
- Use for all follow-up questions. ONE call, many queries.
|
|
18
|
-
3. PROCESSING:
|
|
29
|
+
3. PROCESSING: ${t("ctx_execute")}(language, code) | ${t("ctx_execute_file")}(path, language, code)
|
|
19
30
|
- Use for API calls, log analysis, and data processing.
|
|
20
31
|
</tool_selection_hierarchy>
|
|
21
32
|
|
|
22
33
|
<forbidden_actions>
|
|
23
34
|
- DO NOT use Bash for commands producing >20 lines of output.
|
|
24
35
|
- DO NOT use Read for analysis (use execute_file). Read IS correct for files you intend to Edit.
|
|
25
|
-
- DO NOT use WebFetch (use
|
|
36
|
+
- DO NOT use WebFetch (use ${t("ctx_fetch_and_index")} instead).
|
|
26
37
|
- Bash is ONLY for git/mkdir/rm/mv/navigation.
|
|
27
38
|
</forbidden_actions>
|
|
28
39
|
|
|
@@ -52,9 +63,24 @@ export const ROUTING_BLOCK = `
|
|
|
52
63
|
→ Call the upgrade MCP tool, execute the returned shell command, display results as a checklist.
|
|
53
64
|
</ctx_commands>
|
|
54
65
|
</context_window_protection>`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function createReadGuidance(t) {
|
|
69
|
+
return '<context_guidance>\n <tip>\n If you are reading this file to Edit it, Read is the correct tool — Edit needs file content in context.\n If you are reading to analyze or explore, use ' + t("ctx_execute_file") + '(path, language, code) instead — only your printed summary will enter the context.\n </tip>\n</context_guidance>';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function createGrepGuidance(t) {
|
|
73
|
+
return '<context_guidance>\n <tip>\n This operation may flood your context window. To stay efficient:\n - Use ' + t("ctx_execute") + '(language: "shell", code: "...") to run searches in the sandbox.\n - Only your final printed summary will enter the context.\n </tip>\n</context_guidance>';
|
|
74
|
+
}
|
|
55
75
|
|
|
56
|
-
export
|
|
76
|
+
export function createBashGuidance(t) {
|
|
77
|
+
return '<context_guidance>\n <tip>\n This Bash command may produce large output. To stay efficient:\n - Use ' + t("ctx_batch_execute") + '(commands, queries) for multiple commands\n - Use ' + t("ctx_execute") + '(language: "shell", code: "...") to run in sandbox\n - Only your final printed summary will enter the context.\n - Bash is best for: git, mkdir, rm, mv, navigation, and short-output commands only.\n </tip>\n</context_guidance>';
|
|
78
|
+
}
|
|
57
79
|
|
|
58
|
-
|
|
80
|
+
// ── Backward compat: static exports defaulting to claude-code ──
|
|
59
81
|
|
|
60
|
-
|
|
82
|
+
const _t = createToolNamer("claude-code");
|
|
83
|
+
export const ROUTING_BLOCK = createRoutingBlock(_t);
|
|
84
|
+
export const READ_GUIDANCE = createReadGuidance(_t);
|
|
85
|
+
export const GREP_GUIDANCE = createGrepGuidance(_t);
|
|
86
|
+
export const BASH_GUIDANCE = createBashGuidance(_t);
|
package/hooks/sessionstart.mjs
CHANGED
|
@@ -14,7 +14,10 @@ import "./suppress-stderr.mjs";
|
|
|
14
14
|
* - "clear" → User cleared context. No resume.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { createRoutingBlock } from "./routing-block.mjs";
|
|
18
|
+
import { createToolNamer } from "./core/tool-naming.mjs";
|
|
19
|
+
|
|
20
|
+
const ROUTING_BLOCK = createRoutingBlock(createToolNamer("claude-code"));
|
|
18
21
|
import { readStdin, getSessionId, getSessionDBPath, getSessionEventsPath, getCleanupFlagPath } from "./session-helpers.mjs";
|
|
19
22
|
import { writeSessionEventsFile, buildSessionDirective, getSessionEvents, getLatestSessionEvents } from "./session-directive.mjs";
|
|
20
23
|
import { createSessionLoaders } from "./session-loaders.mjs";
|
|
@@ -19,7 +19,7 @@ const input = JSON.parse(raw);
|
|
|
19
19
|
const tool = input.tool_name ?? "";
|
|
20
20
|
const toolInput = input.tool_input ?? {};
|
|
21
21
|
|
|
22
|
-
const decision = routePreToolUse(tool, toolInput, process.env.VSCODE_CWD || process.env.CLAUDE_PROJECT_DIR);
|
|
22
|
+
const decision = routePreToolUse(tool, toolInput, process.env.VSCODE_CWD || process.env.CLAUDE_PROJECT_DIR, "vscode-copilot");
|
|
23
23
|
const response = formatDecision("vscode-copilot", decision);
|
|
24
24
|
if (response !== null) {
|
|
25
25
|
process.stdout.write(JSON.stringify(response) + "\n");
|
|
@@ -11,7 +11,10 @@ import "../suppress-stderr.mjs";
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { createSessionLoaders } from "../session-loaders.mjs";
|
|
14
|
-
import {
|
|
14
|
+
import { createRoutingBlock } from "../routing-block.mjs";
|
|
15
|
+
import { createToolNamer } from "../core/tool-naming.mjs";
|
|
16
|
+
|
|
17
|
+
const ROUTING_BLOCK = createRoutingBlock(createToolNamer("vscode-copilot"));
|
|
15
18
|
import { writeSessionEventsFile, buildSessionDirective, getSessionEvents, getLatestSessionEvents } from "../session-directive.mjs";
|
|
16
19
|
import {
|
|
17
20
|
readStdin, getSessionId, getSessionDBPath, getSessionEventsPath, getCleanupFlagPath,
|
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.42",
|
|
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.42",
|
|
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",
|