context-mode 1.0.60 → 1.0.62
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/build/executor.d.ts +3 -0
- package/build/executor.js +15 -5
- package/build/server.js +14 -3
- package/cli.bundle.mjs +81 -81
- package/hooks/codex/pretooluse.mjs +4 -3
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/server.bundle.mjs +73 -73
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Claude Code plugins by Mert Koseoğlu",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.62"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "context-mode",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Claude Code MCP plugin that saves 98% of your context window. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and intent-driven search.",
|
|
16
|
-
"version": "1.0.
|
|
16
|
+
"version": "1.0.62",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "Mert Koseoğlu"
|
|
19
19
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "context-mode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.62",
|
|
4
4
|
"description": "MCP server that saves 98% of your context window with session continuity. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and automatic state restore across compactions.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Mert Koseoğlu",
|
|
@@ -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.62",
|
|
7
7
|
"sandbox": {
|
|
8
8
|
"mode": "permissive",
|
|
9
9
|
"filesystem_access": "full",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "context-mode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.62",
|
|
4
4
|
"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.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Mert Koseoğlu",
|
package/build/executor.d.ts
CHANGED
|
@@ -7,6 +7,9 @@ interface ExecuteOptions {
|
|
|
7
7
|
timeout?: number;
|
|
8
8
|
/** Keep process running after timeout instead of killing it. */
|
|
9
9
|
background?: boolean;
|
|
10
|
+
/** Env vars to inherit from the parent process (e.g. ['TMPDIR']).
|
|
11
|
+
* Security-critical variables (NODE_OPTIONS, LD_PRELOAD, etc.) are always blocked. */
|
|
12
|
+
inheritEnvKeys?: string[];
|
|
10
13
|
}
|
|
11
14
|
interface ExecuteFileOptions extends ExecuteOptions {
|
|
12
15
|
path: string;
|
package/build/executor.js
CHANGED
|
@@ -63,7 +63,7 @@ export class PolyglotExecutor {
|
|
|
63
63
|
this.#backgroundedPids.clear();
|
|
64
64
|
}
|
|
65
65
|
async execute(opts) {
|
|
66
|
-
const { language, code, timeout = 30_000, background = false } = opts;
|
|
66
|
+
const { language, code, timeout = 30_000, background = false, inheritEnvKeys } = opts;
|
|
67
67
|
const tmpDir = mkdtempSync(join(OS_TMPDIR, ".ctx-mode-"));
|
|
68
68
|
try {
|
|
69
69
|
const filePath = this.#writeScript(tmpDir, code, language);
|
|
@@ -76,7 +76,7 @@ export class PolyglotExecutor {
|
|
|
76
76
|
// and other project-aware tools work naturally. Non-shell languages
|
|
77
77
|
// run in the temp directory where their script file is written.
|
|
78
78
|
const cwd = language === "shell" ? this.#projectRoot : tmpDir;
|
|
79
|
-
const result = await this.#spawn(cmd, cwd, tmpDir, timeout, background);
|
|
79
|
+
const result = await this.#spawn(cmd, cwd, tmpDir, timeout, background, inheritEnvKeys);
|
|
80
80
|
// Skip tmpDir cleanup if process was backgrounded — it may still need files
|
|
81
81
|
if (!result.backgrounded) {
|
|
82
82
|
try {
|
|
@@ -160,7 +160,7 @@ export class PolyglotExecutor {
|
|
|
160
160
|
// Run
|
|
161
161
|
return this.#spawn([binPath], cwd, cwd, timeout);
|
|
162
162
|
}
|
|
163
|
-
async #spawn(cmd, cwd, sandboxTmpDir, timeout, background = false) {
|
|
163
|
+
async #spawn(cmd, cwd, sandboxTmpDir, timeout, background = false, inheritEnvKeys) {
|
|
164
164
|
return new Promise((res) => {
|
|
165
165
|
// Only .cmd/.bat shims need shell on Windows; real executables don't.
|
|
166
166
|
// Using shell: true globally causes process-tree kill issues with MSYS2/Git Bash.
|
|
@@ -182,7 +182,7 @@ export class PolyglotExecutor {
|
|
|
182
182
|
const proc = spawn(spawnCmd, spawnArgs, {
|
|
183
183
|
cwd,
|
|
184
184
|
stdio: ["ignore", "pipe", "pipe"],
|
|
185
|
-
env: this.#buildSafeEnv(sandboxTmpDir),
|
|
185
|
+
env: this.#buildSafeEnv(sandboxTmpDir, inheritEnvKeys),
|
|
186
186
|
shell: needsShell,
|
|
187
187
|
// On Unix, create a new process group so killTree can kill all children
|
|
188
188
|
detached: !isWin,
|
|
@@ -272,7 +272,7 @@ export class PolyglotExecutor {
|
|
|
272
272
|
});
|
|
273
273
|
});
|
|
274
274
|
}
|
|
275
|
-
#buildSafeEnv(tmpDir) {
|
|
275
|
+
#buildSafeEnv(tmpDir, inheritEnvKeys) {
|
|
276
276
|
const realHome = process.env.HOME ?? process.env.USERPROFILE ?? tmpDir;
|
|
277
277
|
// Denylist: env vars that corrupt sandbox stdout, inject code, or break
|
|
278
278
|
// language runtimes. Each entry is backed by CVE, MITRE, or live testing.
|
|
@@ -395,6 +395,16 @@ export class PolyglotExecutor {
|
|
|
395
395
|
}
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
|
+
// Apply user-requested env var inheritance (blocked by DENIED set).
|
|
399
|
+
// This runs AFTER sandbox overrides so callers can opt-in to inheriting
|
|
400
|
+
// the parent's value for vars like TMPDIR (needed for Gradle daemon, etc.).
|
|
401
|
+
if (inheritEnvKeys?.length) {
|
|
402
|
+
for (const key of inheritEnvKeys) {
|
|
403
|
+
if (!DENIED.has(key) && process.env[key] !== undefined) {
|
|
404
|
+
env[key] = process.env[key];
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
398
408
|
return env;
|
|
399
409
|
}
|
|
400
410
|
#wrapWithFileContent(absolutePath, language, code) {
|
package/build/server.js
CHANGED
|
@@ -426,8 +426,13 @@ server.registerTool("ctx_execute", {
|
|
|
426
426
|
"indexes output into knowledge base and returns section titles + previews — not full content. " +
|
|
427
427
|
"Use search(queries: [...]) to retrieve specific sections. Example: 'failing tests', 'HTTP 500 errors'." +
|
|
428
428
|
"\n\nTIP: Use specific technical terms, not just concepts. Check 'Searchable terms' in the response for available vocabulary."),
|
|
429
|
+
inheritEnvKeys: z
|
|
430
|
+
.array(z.string())
|
|
431
|
+
.optional()
|
|
432
|
+
.describe("Environment variables to inherit from the parent process (e.g. ['TMPDIR']). " +
|
|
433
|
+
"Security-critical variables (NODE_OPTIONS, LD_PRELOAD, etc.) are always blocked."),
|
|
429
434
|
}),
|
|
430
|
-
}, async ({ language, code, timeout, background, intent }) => {
|
|
435
|
+
}, async ({ language, code, timeout, background, intent, inheritEnvKeys }) => {
|
|
431
436
|
// Security: deny-only firewall
|
|
432
437
|
if (language === "shell") {
|
|
433
438
|
const denied = checkDenyPolicy(code, "execute");
|
|
@@ -494,7 +499,7 @@ ${code}
|
|
|
494
499
|
__cm_main().catch(e=>{console.error(e);process.exitCode=1});${background ? '\nsetInterval(()=>{},2147483647);' : ''}
|
|
495
500
|
})(typeof require!=='undefined'?require:null);`;
|
|
496
501
|
}
|
|
497
|
-
const result = await executor.execute({ language, code: instrumentedCode, timeout, background });
|
|
502
|
+
const result = await executor.execute({ language, code: instrumentedCode, timeout, background, inheritEnvKeys });
|
|
498
503
|
// Parse sandbox network metrics from stderr
|
|
499
504
|
const netMatch = result.stderr?.match(/__CM_NET__:(\d+)/);
|
|
500
505
|
if (netMatch) {
|
|
@@ -1291,8 +1296,13 @@ server.registerTool("ctx_batch_execute", {
|
|
|
1291
1296
|
.optional()
|
|
1292
1297
|
.default(60000)
|
|
1293
1298
|
.describe("Max execution time in ms (default: 60s)"),
|
|
1299
|
+
inheritEnvKeys: z
|
|
1300
|
+
.array(z.string())
|
|
1301
|
+
.optional()
|
|
1302
|
+
.describe("Environment variables to inherit from the parent process (e.g. ['TMPDIR']). " +
|
|
1303
|
+
"Security-critical variables (NODE_OPTIONS, LD_PRELOAD, etc.) are always blocked."),
|
|
1294
1304
|
}),
|
|
1295
|
-
}, async ({ commands, queries, timeout }) => {
|
|
1305
|
+
}, async ({ commands, queries, timeout, inheritEnvKeys }) => {
|
|
1296
1306
|
// Security: check each command against deny patterns
|
|
1297
1307
|
for (const cmd of commands) {
|
|
1298
1308
|
const denied = checkDenyPolicy(cmd.command, "batch_execute");
|
|
@@ -1318,6 +1328,7 @@ server.registerTool("ctx_batch_execute", {
|
|
|
1318
1328
|
language: "shell",
|
|
1319
1329
|
code: `${cmd.command} 2>&1`,
|
|
1320
1330
|
timeout: remaining,
|
|
1331
|
+
inheritEnvKeys,
|
|
1321
1332
|
});
|
|
1322
1333
|
const output = result.stdout || "(no output)";
|
|
1323
1334
|
perCommandOutputs.push(`# ${cmd.label}\n\n${output}\n`);
|