context-mode 1.0.121 → 1.0.123
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.openclaw-plugin/openclaw.plugin.json +1 -1
- package/.openclaw-plugin/package.json +1 -1
- package/README.md +4 -4
- package/build/adapters/claude-code/hooks.d.ts +16 -1
- package/build/adapters/claude-code/hooks.js +16 -0
- package/build/adapters/claude-code/index.js +2 -11
- package/build/adapters/client-map.js +6 -0
- package/build/adapters/codex/hooks.d.ts +19 -0
- package/build/adapters/codex/hooks.js +22 -0
- package/build/adapters/codex/index.js +8 -1
- package/build/adapters/copilot-base.d.ts +17 -1
- package/build/adapters/copilot-base.js +18 -2
- package/build/adapters/cursor/hooks.d.ts +14 -1
- package/build/adapters/cursor/hooks.js +14 -0
- package/build/adapters/detect.d.ts +12 -2
- package/build/adapters/detect.js +96 -13
- package/build/adapters/gemini-cli/hooks.d.ts +16 -0
- package/build/adapters/gemini-cli/hooks.js +19 -0
- package/build/adapters/gemini-cli/index.js +4 -2
- package/build/adapters/kiro/hooks.d.ts +16 -1
- package/build/adapters/kiro/hooks.js +19 -0
- package/build/adapters/pi/extension.d.ts +9 -0
- package/build/adapters/pi/extension.js +52 -1
- package/build/adapters/qwen-code/hooks.d.ts +26 -0
- package/build/adapters/qwen-code/hooks.js +29 -0
- package/build/adapters/qwen-code/index.js +6 -0
- package/build/cli.js +46 -5
- package/build/executor.js +18 -3
- package/build/lifecycle.d.ts +15 -0
- package/build/lifecycle.js +24 -1
- package/build/runtime.js +34 -13
- package/build/server.js +17 -2
- package/build/session/extract.js +150 -48
- package/build/session/snapshot.js +46 -0
- package/cli.bundle.mjs +151 -150
- package/configs/codex/hooks.json +1 -1
- package/configs/cursor/hooks.json +1 -1
- package/configs/kiro/agent.json +1 -1
- package/hooks/core/routing.mjs +56 -1
- package/hooks/cursor/hooks.json +1 -1
- package/hooks/ensure-deps.mjs +45 -10
- package/hooks/hooks.json +9 -0
- package/hooks/routing-block.mjs +5 -0
- package/hooks/session-extract.bundle.mjs +2 -2
- package/hooks/session-snapshot.bundle.mjs +21 -20
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -3
- package/scripts/heal-better-sqlite3.mjs +188 -10
- package/scripts/heal-installed-plugins.mjs +111 -0
- package/scripts/postinstall.mjs +35 -9
- package/server.bundle.mjs +118 -118
- package/start.mjs +14 -1
- package/.mcp.json +0 -8
|
@@ -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.123"
|
|
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.123",
|
|
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.123",
|
|
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.123",
|
|
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.123",
|
|
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/README.md
CHANGED
|
@@ -146,7 +146,7 @@ This gives you all 11 MCP tools without automatic routing. The model can still u
|
|
|
146
146
|
"hooks": {
|
|
147
147
|
"BeforeTool": [
|
|
148
148
|
{
|
|
149
|
-
"matcher": "run_shell_command|read_file|read_many_files|grep_search|search_file_content|web_fetch|activate_skill|mcp__plugin_context-mode",
|
|
149
|
+
"matcher": "run_shell_command|read_file|read_many_files|grep_search|search_file_content|web_fetch|activate_skill|mcp__plugin_context-mode|mcp__context-mode|mcp__(?!.*context-mode)",
|
|
150
150
|
"hooks": [{ "type": "command", "command": "context-mode hook gemini-cli beforetool" }]
|
|
151
151
|
}
|
|
152
152
|
],
|
|
@@ -570,7 +570,7 @@ Full documentation: [`docs/adapters/openclaw.md`](docs/adapters/openclaw.md)
|
|
|
570
570
|
```json
|
|
571
571
|
{
|
|
572
572
|
"hooks": {
|
|
573
|
-
"PreToolUse": [{ "matcher": "local_shell|shell|shell_command|exec_command|container.exec|functions\\.exec_command|Bash|Shell|apply_patch|functions\\.apply_patch|Edit|Write|grep_files|ctx_execute|ctx_execute_file|ctx_batch_execute|ctx_fetch_and_index|ctx_search|ctx_index|mcp__.*__ctx_execute|mcp__.*__ctx_execute_file|mcp__.*__ctx_batch_execute|mcp__.*__ctx_fetch_and_index|mcp__.*__ctx_search|mcp__.*__ctx_index", "hooks": [{ "type": "command", "command": "context-mode hook codex pretooluse" }] }],
|
|
573
|
+
"PreToolUse": [{ "matcher": "local_shell|shell|shell_command|exec_command|container.exec|functions\\.exec_command|Bash|Shell|apply_patch|functions\\.apply_patch|Edit|Write|grep_files|ctx_execute|ctx_execute_file|ctx_batch_execute|ctx_fetch_and_index|ctx_search|ctx_index|mcp__.*__ctx_execute|mcp__.*__ctx_execute_file|mcp__.*__ctx_batch_execute|mcp__.*__ctx_fetch_and_index|mcp__.*__ctx_search|mcp__.*__ctx_index|mcp__(?!.*context-mode)", "hooks": [{ "type": "command", "command": "context-mode hook codex pretooluse" }] }],
|
|
574
574
|
"PostToolUse": [{ "hooks": [{ "type": "command", "command": "context-mode hook codex posttooluse" }] }],
|
|
575
575
|
"SessionStart": [{ "hooks": [{ "type": "command", "command": "context-mode hook codex sessionstart" }] }],
|
|
576
576
|
"PreCompact": [{ "hooks": [{ "type": "command", "command": "context-mode hook codex precompact" }] }],
|
|
@@ -632,7 +632,7 @@ Full documentation: [`docs/adapters/openclaw.md`](docs/adapters/openclaw.md)
|
|
|
632
632
|
```json
|
|
633
633
|
{
|
|
634
634
|
"hooks": {
|
|
635
|
-
"PreToolUse": [{ "matcher": "run_shell_command|read_file|read_many_files|grep_search|web_fetch|agent|mcp__plugin_context-mode_context-mode__ctx_execute|mcp__plugin_context-mode_context-mode__ctx_execute_file|mcp__plugin_context-mode_context-mode__ctx_batch_execute", "hooks": [{ "type": "command", "command": "context-mode hook qwen-code pretooluse" }] }],
|
|
635
|
+
"PreToolUse": [{ "matcher": "run_shell_command|read_file|read_many_files|grep_search|web_fetch|agent|mcp__plugin_context-mode_context-mode__ctx_execute|mcp__plugin_context-mode_context-mode__ctx_execute_file|mcp__plugin_context-mode_context-mode__ctx_batch_execute|mcp__(?!.*context-mode)", "hooks": [{ "type": "command", "command": "context-mode hook qwen-code pretooluse" }] }],
|
|
636
636
|
"PostToolUse": [{ "matcher": "", "hooks": [{ "type": "command", "command": "context-mode hook qwen-code posttooluse" }] }],
|
|
637
637
|
"SessionStart": [{ "matcher": "", "hooks": [{ "type": "command", "command": "context-mode hook qwen-code sessionstart" }] }],
|
|
638
638
|
"PreCompact": [{ "matcher": "", "hooks": [{ "type": "command", "command": "context-mode hook qwen-code precompact" }] }],
|
|
@@ -731,7 +731,7 @@ Full configs: [`configs/antigravity/mcp_config.json`](configs/antigravity/mcp_co
|
|
|
731
731
|
"description": "Context-mode hooks for context window protection",
|
|
732
732
|
"hooks": {
|
|
733
733
|
"preToolUse": [
|
|
734
|
-
{ "matcher": "execute_bash|fs_read|@context-mode/ctx_execute|@context-mode/ctx_execute_file|@context-mode/ctx_batch_execute", "command": "context-mode hook kiro pretooluse" }
|
|
734
|
+
{ "matcher": "execute_bash|fs_read|@context-mode/ctx_execute|@context-mode/ctx_execute_file|@context-mode/ctx_batch_execute|@(?!context-mode/)", "command": "context-mode hook kiro pretooluse" }
|
|
735
735
|
],
|
|
736
736
|
"postToolUse": [
|
|
737
737
|
{ "matcher": "*", "command": "context-mode hook kiro posttooluse" }
|
|
@@ -24,8 +24,23 @@ export declare const HOOK_TYPES: {
|
|
|
24
24
|
readonly USER_PROMPT_SUBMIT: "UserPromptSubmit";
|
|
25
25
|
};
|
|
26
26
|
export type HookType = (typeof HOOK_TYPES)[keyof typeof HOOK_TYPES];
|
|
27
|
+
/**
|
|
28
|
+
* Negative-lookahead matcher for external MCP tool namespaces (#529).
|
|
29
|
+
*
|
|
30
|
+
* Claude Code's hook matcher engine evaluates each entry as a regex against
|
|
31
|
+
* the tool name. This pattern fires on any `mcp__<server>__<tool>` whose
|
|
32
|
+
* server segment is NOT context-mode's own (`plugin_context-mode_...`).
|
|
33
|
+
* Without it, large payloads from external MCPs (slack channel history,
|
|
34
|
+
* telegram messages, gdrive content, notion pages, …) bypass PreToolUse
|
|
35
|
+
* routing and flood the model's context window — PostToolUse runs too late
|
|
36
|
+
* to keep the raw data out.
|
|
37
|
+
*
|
|
38
|
+
* The negative lookahead prevents this entry from double-firing on
|
|
39
|
+
* context-mode's own ctx_* tools, which already have dedicated entries above.
|
|
40
|
+
*/
|
|
41
|
+
export declare const EXTERNAL_MCP_MATCHER_PATTERN = "mcp__(?!plugin_context-mode_)";
|
|
27
42
|
/** Tools that context-mode's PreToolUse hook intercepts. */
|
|
28
|
-
export declare const PRE_TOOL_USE_MATCHERS: readonly ["Bash", "WebFetch", "Read", "Grep", "Agent", "mcp__plugin_context-mode_context-mode__ctx_execute", "mcp__plugin_context-mode_context-mode__ctx_execute_file", "mcp__plugin_context-mode_context-mode__ctx_batch_execute"];
|
|
43
|
+
export declare const PRE_TOOL_USE_MATCHERS: readonly ["Bash", "WebFetch", "Read", "Grep", "Agent", "mcp__plugin_context-mode_context-mode__ctx_execute", "mcp__plugin_context-mode_context-mode__ctx_execute_file", "mcp__plugin_context-mode_context-mode__ctx_batch_execute", "mcp__(?!plugin_context-mode_)"];
|
|
29
44
|
/**
|
|
30
45
|
* Combined matcher pattern for settings.json (pipe-separated).
|
|
31
46
|
* Used by the upgrade command when writing a single consolidated entry.
|
|
@@ -30,6 +30,21 @@ export const HOOK_TYPES = {
|
|
|
30
30
|
// ─────────────────────────────────────────────────────────
|
|
31
31
|
// PreToolUse matchers
|
|
32
32
|
// ─────────────────────────────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* Negative-lookahead matcher for external MCP tool namespaces (#529).
|
|
35
|
+
*
|
|
36
|
+
* Claude Code's hook matcher engine evaluates each entry as a regex against
|
|
37
|
+
* the tool name. This pattern fires on any `mcp__<server>__<tool>` whose
|
|
38
|
+
* server segment is NOT context-mode's own (`plugin_context-mode_...`).
|
|
39
|
+
* Without it, large payloads from external MCPs (slack channel history,
|
|
40
|
+
* telegram messages, gdrive content, notion pages, …) bypass PreToolUse
|
|
41
|
+
* routing and flood the model's context window — PostToolUse runs too late
|
|
42
|
+
* to keep the raw data out.
|
|
43
|
+
*
|
|
44
|
+
* The negative lookahead prevents this entry from double-firing on
|
|
45
|
+
* context-mode's own ctx_* tools, which already have dedicated entries above.
|
|
46
|
+
*/
|
|
47
|
+
export const EXTERNAL_MCP_MATCHER_PATTERN = "mcp__(?!plugin_context-mode_)";
|
|
33
48
|
/** Tools that context-mode's PreToolUse hook intercepts. */
|
|
34
49
|
export const PRE_TOOL_USE_MATCHERS = [
|
|
35
50
|
"Bash",
|
|
@@ -40,6 +55,7 @@ export const PRE_TOOL_USE_MATCHERS = [
|
|
|
40
55
|
"mcp__plugin_context-mode_context-mode__ctx_execute",
|
|
41
56
|
"mcp__plugin_context-mode_context-mode__ctx_execute_file",
|
|
42
57
|
"mcp__plugin_context-mode_context-mode__ctx_batch_execute",
|
|
58
|
+
EXTERNAL_MCP_MATCHER_PATTERN,
|
|
43
59
|
];
|
|
44
60
|
/**
|
|
45
61
|
* Combined matcher pattern for settings.json (pipe-separated).
|
|
@@ -16,7 +16,7 @@ import { resolve, join } from "node:path";
|
|
|
16
16
|
import { homedir } from "node:os";
|
|
17
17
|
import { ClaudeCodeBaseAdapter } from "../claude-code-base.js";
|
|
18
18
|
import { resolveClaudeConfigDir } from "../../util/claude-config.js";
|
|
19
|
-
import { HOOK_TYPES, HOOK_SCRIPTS, REQUIRED_HOOKS, PRE_TOOL_USE_MATCHER_PATTERN, isContextModeHook, isAnyContextModeHook, extractHookScriptPath, buildHookCommand, } from "./hooks.js";
|
|
19
|
+
import { HOOK_TYPES, HOOK_SCRIPTS, REQUIRED_HOOKS, PRE_TOOL_USE_MATCHERS, PRE_TOOL_USE_MATCHER_PATTERN, isContextModeHook, isAnyContextModeHook, extractHookScriptPath, buildHookCommand, } from "./hooks.js";
|
|
20
20
|
// ─────────────────────────────────────────────────────────
|
|
21
21
|
// Adapter implementation
|
|
22
22
|
// ─────────────────────────────────────────────────────────
|
|
@@ -68,16 +68,7 @@ export class ClaudeCodeAdapter extends ClaudeCodeBaseAdapter {
|
|
|
68
68
|
}
|
|
69
69
|
generateHookConfig(pluginRoot) {
|
|
70
70
|
const preToolUseCommand = `node ${pluginRoot}/hooks/pretooluse.mjs`;
|
|
71
|
-
const preToolUseMatchers = [
|
|
72
|
-
"Bash",
|
|
73
|
-
"WebFetch",
|
|
74
|
-
"Read",
|
|
75
|
-
"Grep",
|
|
76
|
-
"Task",
|
|
77
|
-
"mcp__plugin_context-mode_context-mode__ctx_execute",
|
|
78
|
-
"mcp__plugin_context-mode_context-mode__ctx_execute_file",
|
|
79
|
-
"mcp__plugin_context-mode_context-mode__ctx_batch_execute",
|
|
80
|
-
];
|
|
71
|
+
const preToolUseMatchers = [...PRE_TOOL_USE_MATCHERS];
|
|
81
72
|
return {
|
|
82
73
|
PreToolUse: preToolUseMatchers.map((matcher) => ({
|
|
83
74
|
matcher,
|
|
@@ -21,6 +21,12 @@ export const CLIENT_NAME_TO_PLATFORM = {
|
|
|
21
21
|
"Kiro CLI": "kiro",
|
|
22
22
|
"Pi CLI": "pi",
|
|
23
23
|
"Pi Coding Agent": "pi",
|
|
24
|
+
// Issue #542 — Pi rebranded to OMP. Upstream
|
|
25
|
+
// refs/platforms/oh-my-pi/packages/coding-agent/src/mcp/client.ts:46-49
|
|
26
|
+
// ships clientInfo.name = "omp-coding-agent". Resolved to the OMP
|
|
27
|
+
// adapter (~/.omp/, PI_CODING_AGENT_DIR). Legacy "Pi CLI" /
|
|
28
|
+
// "Pi Coding Agent" entries above still resolve to the pi adapter.
|
|
29
|
+
"omp-coding-agent": "omp",
|
|
24
30
|
"Zed": "zed",
|
|
25
31
|
"zed": "zed",
|
|
26
32
|
"qwen-code": "qwen-code",
|
|
@@ -26,6 +26,25 @@ export declare const HOOK_TYPES: {
|
|
|
26
26
|
readonly USER_PROMPT_SUBMIT: "UserPromptSubmit";
|
|
27
27
|
readonly STOP: "Stop";
|
|
28
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Negative-lookahead matcher for external MCP tool namespaces on Codex CLI (#529).
|
|
31
|
+
*
|
|
32
|
+
* Codex CLI's hook `tool_name` payload uses `mcp__<server>__<tool>` for any
|
|
33
|
+
* MCP-namespaced tool — verified by configs/codex/hooks.json which already
|
|
34
|
+
* matches `mcp__.*__ctx_execute` style for context-mode's OWN MCP tools. This
|
|
35
|
+
* pattern fires PreToolUse for any external `mcp__<server>__<tool>` whose
|
|
36
|
+
* server segment does NOT contain `context-mode`. Without it, large payloads
|
|
37
|
+
* from slack / telegram / gdrive / notion-style MCPs bypass the routing nudge
|
|
38
|
+
* and flood the model's context — PostToolUse runs too late to keep raw data
|
|
39
|
+
* out.
|
|
40
|
+
*
|
|
41
|
+
* The negative lookahead `(?!.*context-mode)` covers both naming variants
|
|
42
|
+
* Codex sees in practice: the canonical `mcp__context-mode__ctx_*` AND the
|
|
43
|
+
* Claude Code plugin shim `mcp__plugin_context-mode_context-mode__ctx_*`.
|
|
44
|
+
* Codex own bare names (ctx_execute, local_shell, …) are not `mcp__`-prefixed
|
|
45
|
+
* and are unaffected.
|
|
46
|
+
*/
|
|
47
|
+
export declare const EXTERNAL_MCP_MATCHER_PATTERN = "mcp__(?!.*context-mode)";
|
|
29
48
|
/**
|
|
30
49
|
* Path to the routing instructions file for Codex CLI.
|
|
31
50
|
* Used as fallback routing awareness alongside hook-based enforcement.
|
|
@@ -30,6 +30,28 @@ export const HOOK_TYPES = {
|
|
|
30
30
|
STOP: "Stop",
|
|
31
31
|
};
|
|
32
32
|
// ─────────────────────────────────────────────────────────
|
|
33
|
+
// External MCP routing matcher (#529)
|
|
34
|
+
// ─────────────────────────────────────────────────────────
|
|
35
|
+
/**
|
|
36
|
+
* Negative-lookahead matcher for external MCP tool namespaces on Codex CLI (#529).
|
|
37
|
+
*
|
|
38
|
+
* Codex CLI's hook `tool_name` payload uses `mcp__<server>__<tool>` for any
|
|
39
|
+
* MCP-namespaced tool — verified by configs/codex/hooks.json which already
|
|
40
|
+
* matches `mcp__.*__ctx_execute` style for context-mode's OWN MCP tools. This
|
|
41
|
+
* pattern fires PreToolUse for any external `mcp__<server>__<tool>` whose
|
|
42
|
+
* server segment does NOT contain `context-mode`. Without it, large payloads
|
|
43
|
+
* from slack / telegram / gdrive / notion-style MCPs bypass the routing nudge
|
|
44
|
+
* and flood the model's context — PostToolUse runs too late to keep raw data
|
|
45
|
+
* out.
|
|
46
|
+
*
|
|
47
|
+
* The negative lookahead `(?!.*context-mode)` covers both naming variants
|
|
48
|
+
* Codex sees in practice: the canonical `mcp__context-mode__ctx_*` AND the
|
|
49
|
+
* Claude Code plugin shim `mcp__plugin_context-mode_context-mode__ctx_*`.
|
|
50
|
+
* Codex own bare names (ctx_execute, local_shell, …) are not `mcp__`-prefixed
|
|
51
|
+
* and are unaffected.
|
|
52
|
+
*/
|
|
53
|
+
export const EXTERNAL_MCP_MATCHER_PATTERN = "mcp__(?!.*context-mode)";
|
|
54
|
+
// ─────────────────────────────────────────────────────────
|
|
33
55
|
// Routing instructions
|
|
34
56
|
// ─────────────────────────────────────────────────────────
|
|
35
57
|
/**
|
|
@@ -18,7 +18,14 @@ import { resolve, dirname, join } from "node:path";
|
|
|
18
18
|
import { fileURLToPath } from "node:url";
|
|
19
19
|
import { BaseAdapter } from "../base.js";
|
|
20
20
|
import { resolveCodexConfigDir } from "./paths.js";
|
|
21
|
-
|
|
21
|
+
// PreToolUse matcher: canonical Codex tool names + context-mode own MCP tools
|
|
22
|
+
// (both bare and `mcp__<server>__<tool>` forms) + external MCP catch-all (#529).
|
|
23
|
+
// The final `mcp__(?!.*context-mode)` segment uses a negative lookahead that
|
|
24
|
+
// excludes any `mcp__` tool whose server segment contains `context-mode` so
|
|
25
|
+
// context-mode's own MCP tools (already wired by the explicit entries above)
|
|
26
|
+
// are not double-routed. Keep this as a single string literal — `codex.test.ts`
|
|
27
|
+
// drift-guard parses the source with a `"([^"]+)"` regex.
|
|
28
|
+
const PRE_TOOL_USE_MATCHER_PATTERN = "local_shell|shell|shell_command|exec_command|container.exec|functions\\.exec_command|Bash|Shell|apply_patch|functions\\.apply_patch|Edit|Write|grep_files|ctx_execute|ctx_execute_file|ctx_batch_execute|ctx_fetch_and_index|ctx_search|ctx_index|mcp__.*__ctx_execute|mcp__.*__ctx_execute_file|mcp__.*__ctx_batch_execute|mcp__.*__ctx_fetch_and_index|mcp__.*__ctx_search|mcp__.*__ctx_index|mcp__(?!.*context-mode)";
|
|
22
29
|
const CODEX_HOOK_COMMANDS = {
|
|
23
30
|
PreToolUse: "context-mode hook codex pretooluse",
|
|
24
31
|
PostToolUse: "context-mode hook codex posttooluse",
|
|
@@ -68,7 +68,23 @@ export declare abstract class CopilotBaseAdapter extends BaseAdapter implements
|
|
|
68
68
|
formatPostToolUseResponse(response: PostToolUseResponse): unknown;
|
|
69
69
|
formatPreCompactResponse(response: PreCompactResponse): unknown;
|
|
70
70
|
formatSessionStartResponse(response: SessionStartResponse): unknown;
|
|
71
|
-
|
|
71
|
+
/**
|
|
72
|
+
* Resolve the absolute path to the Copilot-style hook settings file.
|
|
73
|
+
*
|
|
74
|
+
* Issue #539 fix: previously this returned `resolve(".github", ...)`
|
|
75
|
+
* — a CWD-relative path. `doctor` (validateHooks) and `upgrade`
|
|
76
|
+
* (configureAllHooks) could legitimately run from different working
|
|
77
|
+
* directories (CLI invoked from a subdir, MCP server cwd=projectDir),
|
|
78
|
+
* so each saw a DIFFERENT settings path and the diagnose/repair loop
|
|
79
|
+
* never converged on the same file.
|
|
80
|
+
*
|
|
81
|
+
* Now anchors on `projectDir` when supplied (matching the sibling
|
|
82
|
+
* `getConfigDir(projectDir?: string)` signature in
|
|
83
|
+
* vscode-copilot/index.ts:93). Falls back to `process.cwd()` to keep
|
|
84
|
+
* existing callers source-compatible — the slice-5 follow-up will
|
|
85
|
+
* thread projectDir through `cli.ts doctor`/`upgrade`.
|
|
86
|
+
*/
|
|
87
|
+
getSettingsPath(projectDir?: string): string;
|
|
72
88
|
generateHookConfig(pluginRoot: string): HookRegistration;
|
|
73
89
|
readSettings(): Record<string, unknown> | null;
|
|
74
90
|
writeSettings(settings: Record<string, unknown>): void;
|
|
@@ -149,8 +149,24 @@ export class CopilotBaseAdapter extends BaseAdapter {
|
|
|
149
149
|
return response.context ?? "";
|
|
150
150
|
}
|
|
151
151
|
// ── Configuration (shared) ─────────────────────────────
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Resolve the absolute path to the Copilot-style hook settings file.
|
|
154
|
+
*
|
|
155
|
+
* Issue #539 fix: previously this returned `resolve(".github", ...)`
|
|
156
|
+
* — a CWD-relative path. `doctor` (validateHooks) and `upgrade`
|
|
157
|
+
* (configureAllHooks) could legitimately run from different working
|
|
158
|
+
* directories (CLI invoked from a subdir, MCP server cwd=projectDir),
|
|
159
|
+
* so each saw a DIFFERENT settings path and the diagnose/repair loop
|
|
160
|
+
* never converged on the same file.
|
|
161
|
+
*
|
|
162
|
+
* Now anchors on `projectDir` when supplied (matching the sibling
|
|
163
|
+
* `getConfigDir(projectDir?: string)` signature in
|
|
164
|
+
* vscode-copilot/index.ts:93). Falls back to `process.cwd()` to keep
|
|
165
|
+
* existing callers source-compatible — the slice-5 follow-up will
|
|
166
|
+
* thread projectDir through `cli.ts doctor`/`upgrade`.
|
|
167
|
+
*/
|
|
168
|
+
getSettingsPath(projectDir) {
|
|
169
|
+
return resolve(projectDir ?? process.cwd(), ".github", "hooks", "context-mode.json");
|
|
154
170
|
}
|
|
155
171
|
generateHookConfig(pluginRoot) {
|
|
156
172
|
const { HOOK_TYPES, buildHookCommand } = this.hookModule;
|
|
@@ -16,8 +16,21 @@ export declare const HOOK_TYPES: {
|
|
|
16
16
|
export type HookType = (typeof HOOK_TYPES)[keyof typeof HOOK_TYPES];
|
|
17
17
|
/** Map of hook types that have actual script files. */
|
|
18
18
|
export declare const HOOK_SCRIPTS: Partial<Record<HookType, string>>;
|
|
19
|
+
/**
|
|
20
|
+
* Negative-lookahead matcher for external MCP tool namespaces on Cursor (#529).
|
|
21
|
+
*
|
|
22
|
+
* Cursor MCP wire shape: `MCP:<tool>` (verified in
|
|
23
|
+
* tests/fixtures/cursor/pretooluse-mcp.json, hooks/cursor/posttooluse.mjs:19-25).
|
|
24
|
+
* Context-mode's own tools surface as `MCP:ctx_<...>`. The negative lookahead
|
|
25
|
+
* on the `ctx_` prefix fires for every other MCP tool whose payload would
|
|
26
|
+
* otherwise flood the model's context window before PostToolUse can act.
|
|
27
|
+
*
|
|
28
|
+
* Routing.mjs `isExternalMcpTool` is extended to recognise the `MCP:` prefix
|
|
29
|
+
* so the routing branch returns external-MCP guidance instead of passthrough.
|
|
30
|
+
*/
|
|
31
|
+
export declare const EXTERNAL_MCP_MATCHER_PATTERN = "MCP:(?!ctx_)";
|
|
19
32
|
/** Canonical Cursor-native matchers for tools context-mode routes proactively. */
|
|
20
|
-
export declare const PRE_TOOL_USE_MATCHERS: readonly ["Shell", "Read", "Grep", "WebFetch", "mcp_web_fetch", "mcp_fetch_tool", "Task", "MCP:ctx_execute", "MCP:ctx_execute_file", "MCP:ctx_batch_execute"];
|
|
33
|
+
export declare const PRE_TOOL_USE_MATCHERS: readonly ["Shell", "Read", "Grep", "WebFetch", "mcp_web_fetch", "mcp_fetch_tool", "Task", "MCP:ctx_execute", "MCP:ctx_execute_file", "MCP:ctx_batch_execute", "MCP:(?!ctx_)"];
|
|
21
34
|
export declare const PRE_TOOL_USE_MATCHER_PATTERN: string;
|
|
22
35
|
/** Required hooks for native Cursor support. */
|
|
23
36
|
export declare const REQUIRED_HOOKS: HookType[];
|
|
@@ -21,6 +21,19 @@ export const HOOK_SCRIPTS = {
|
|
|
21
21
|
[HOOK_TYPES.STOP]: "stop.mjs",
|
|
22
22
|
[HOOK_TYPES.AFTER_AGENT_RESPONSE]: "afteragentresponse.mjs",
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Negative-lookahead matcher for external MCP tool namespaces on Cursor (#529).
|
|
26
|
+
*
|
|
27
|
+
* Cursor MCP wire shape: `MCP:<tool>` (verified in
|
|
28
|
+
* tests/fixtures/cursor/pretooluse-mcp.json, hooks/cursor/posttooluse.mjs:19-25).
|
|
29
|
+
* Context-mode's own tools surface as `MCP:ctx_<...>`. The negative lookahead
|
|
30
|
+
* on the `ctx_` prefix fires for every other MCP tool whose payload would
|
|
31
|
+
* otherwise flood the model's context window before PostToolUse can act.
|
|
32
|
+
*
|
|
33
|
+
* Routing.mjs `isExternalMcpTool` is extended to recognise the `MCP:` prefix
|
|
34
|
+
* so the routing branch returns external-MCP guidance instead of passthrough.
|
|
35
|
+
*/
|
|
36
|
+
export const EXTERNAL_MCP_MATCHER_PATTERN = "MCP:(?!ctx_)";
|
|
24
37
|
/** Canonical Cursor-native matchers for tools context-mode routes proactively. */
|
|
25
38
|
// NOTE (Cursor-3, deferred): Cursor is closed-source and does not currently
|
|
26
39
|
// publish the exact tool name it uses for sub-agent dispatch (the analogue of
|
|
@@ -40,6 +53,7 @@ export const PRE_TOOL_USE_MATCHERS = [
|
|
|
40
53
|
"MCP:ctx_execute",
|
|
41
54
|
"MCP:ctx_execute_file",
|
|
42
55
|
"MCP:ctx_batch_execute",
|
|
56
|
+
EXTERNAL_MCP_MATCHER_PATTERN,
|
|
43
57
|
];
|
|
44
58
|
export const PRE_TOOL_USE_MATCHER_PATTERN = PRE_TOOL_USE_MATCHERS.join("|");
|
|
45
59
|
/** Required hooks for native Cursor support. */
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* 3. Fallback to Claude Code (low confidence — most common)
|
|
8
8
|
*
|
|
9
9
|
* Verified env vars per platform (from source code audit):
|
|
10
|
-
* - Claude Code:
|
|
10
|
+
* - Claude Code: CLAUDE_CODE_ENTRYPOINT, CLAUDE_PLUGIN_ROOT,
|
|
11
|
+
* CLAUDE_PROJECT_DIR, CLAUDE_SESSION_ID | ~/.claude/
|
|
11
12
|
* - Gemini CLI: GEMINI_PROJECT_DIR (hooks), GEMINI_CLI (MCP) | ~/.gemini/
|
|
12
13
|
* - KiloCode: KILO, KILO_PID | ~/.config/kilo/
|
|
13
14
|
* - OpenCode: OPENCODE, OPENCODE_PID | ~/.config/opencode/
|
|
@@ -18,12 +19,21 @@
|
|
|
18
19
|
* - JetBrains Copilot: IDEA_INITIAL_DIRECTORY, IDEA_HOME, JETBRAINS_CLIENT_ID | ~/.config/JetBrains/
|
|
19
20
|
*/
|
|
20
21
|
import type { PlatformId, DetectionSignal, HookAdapter } from "./types.js";
|
|
22
|
+
/** Test-only: reset the installed_plugins.json memo so each test starts cold. */
|
|
23
|
+
export declare function __resetClaudeCodePluginCacheForTests(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Test-only: pretend installed_plugins.json does not exist (or has no
|
|
26
|
+
* context-mode entry). Lets tests that exercise the genuine vscode-copilot
|
|
27
|
+
* env-var path run on a developer machine that actually has context-mode
|
|
28
|
+
* installed as a Claude Code plugin.
|
|
29
|
+
*/
|
|
30
|
+
export declare function __seedClaudeCodePluginCacheMissForTests(): void;
|
|
21
31
|
/**
|
|
22
32
|
* High-confidence env vars per platform, checked in priority order.
|
|
23
33
|
* Single source of truth — consumed by detectPlatform() below and by
|
|
24
34
|
* tests that need to clear platform-related env vars deterministically.
|
|
25
35
|
*/
|
|
26
|
-
export declare const PLATFORM_ENV_VARS: readonly [readonly ["claude-code", readonly ["CLAUDE_PROJECT_DIR", "CLAUDE_SESSION_ID"]], readonly ["antigravity", readonly ["ANTIGRAVITY_CLI_ALIAS"]], readonly ["cursor", readonly ["CURSOR_TRACE_ID", "CURSOR_CLI"]], readonly ["kilo", readonly ["KILO", "KILO_PID"]], readonly ["opencode", readonly ["OPENCODE", "OPENCODE_PID"]], readonly ["zed", readonly ["ZED_SESSION_ID", "ZED_TERM"]], readonly ["codex", readonly ["CODEX_THREAD_ID", "CODEX_CI"]], readonly ["gemini-cli", readonly ["GEMINI_PROJECT_DIR", "GEMINI_CLI"]], readonly ["vscode-copilot", readonly ["VSCODE_PID", "VSCODE_CWD"]], readonly ["jetbrains-copilot", readonly ["IDEA_INITIAL_DIRECTORY"]], readonly ["qwen-code", readonly ["QWEN_PROJECT_DIR"]], readonly ["omp", readonly ["PI_CODING_AGENT_DIR"]], readonly ["pi", readonly ["
|
|
36
|
+
export declare const PLATFORM_ENV_VARS: readonly [readonly ["claude-code", readonly ["CLAUDE_CODE_ENTRYPOINT", "CLAUDE_PLUGIN_ROOT", "CLAUDE_PROJECT_DIR", "CLAUDE_SESSION_ID"]], readonly ["antigravity", readonly ["ANTIGRAVITY_CLI_ALIAS"]], readonly ["cursor", readonly ["CURSOR_TRACE_ID", "CURSOR_CLI"]], readonly ["kilo", readonly ["KILO", "KILO_PID"]], readonly ["opencode", readonly ["OPENCODE", "OPENCODE_PID"]], readonly ["zed", readonly ["ZED_SESSION_ID", "ZED_TERM"]], readonly ["codex", readonly ["CODEX_THREAD_ID", "CODEX_CI"]], readonly ["gemini-cli", readonly ["GEMINI_PROJECT_DIR", "GEMINI_CLI"]], readonly ["vscode-copilot", readonly ["VSCODE_PID", "VSCODE_CWD"]], readonly ["jetbrains-copilot", readonly ["IDEA_INITIAL_DIRECTORY"]], readonly ["qwen-code", readonly ["QWEN_PROJECT_DIR"]], readonly ["omp", readonly ["PI_CODING_AGENT_DIR"]], readonly ["pi", readonly ["PI_CONFIG_DIR", "PI_SESSION_FILE", "PI_COMPILED"]]];
|
|
27
37
|
/**
|
|
28
38
|
* Sync map from platform identifier → home-relative path segments where that
|
|
29
39
|
* platform stores its config. Mirrors the `super([...])` argument passed by
|
package/build/adapters/detect.js
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* 3. Fallback to Claude Code (low confidence — most common)
|
|
8
8
|
*
|
|
9
9
|
* Verified env vars per platform (from source code audit):
|
|
10
|
-
* - Claude Code:
|
|
10
|
+
* - Claude Code: CLAUDE_CODE_ENTRYPOINT, CLAUDE_PLUGIN_ROOT,
|
|
11
|
+
* CLAUDE_PROJECT_DIR, CLAUDE_SESSION_ID | ~/.claude/
|
|
11
12
|
* - Gemini CLI: GEMINI_PROJECT_DIR (hooks), GEMINI_CLI (MCP) | ~/.gemini/
|
|
12
13
|
* - KiloCode: KILO, KILO_PID | ~/.config/kilo/
|
|
13
14
|
* - OpenCode: OPENCODE, OPENCODE_PID | ~/.config/opencode/
|
|
@@ -17,10 +18,45 @@
|
|
|
17
18
|
* - VS Code Copilot: VSCODE_PID, VSCODE_CWD | ~/.vscode/
|
|
18
19
|
* - JetBrains Copilot: IDEA_INITIAL_DIRECTORY, IDEA_HOME, JETBRAINS_CLIENT_ID | ~/.config/JetBrains/
|
|
19
20
|
*/
|
|
20
|
-
import { existsSync } from "node:fs";
|
|
21
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
21
22
|
import { resolve } from "node:path";
|
|
22
23
|
import { homedir } from "node:os";
|
|
23
24
|
import { CLIENT_NAME_TO_PLATFORM } from "./client-map.js";
|
|
25
|
+
let claudeCodePluginCache = null;
|
|
26
|
+
function claudeCodeHasContextModePlugin() {
|
|
27
|
+
if (claudeCodePluginCache !== null) {
|
|
28
|
+
return claudeCodePluginCache !== "miss" && claudeCodePluginCache.hasCM;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const path = resolve(homedir(), ".claude", "plugins", "installed_plugins.json");
|
|
32
|
+
const raw = readFileSync(path, "utf-8");
|
|
33
|
+
const parsed = JSON.parse(raw);
|
|
34
|
+
const keys = [
|
|
35
|
+
...Object.keys(parsed.plugins ?? {}),
|
|
36
|
+
...Object.keys(parsed.enabledPlugins ?? {}),
|
|
37
|
+
];
|
|
38
|
+
const hasCM = keys.some((k) => k.includes("context-mode"));
|
|
39
|
+
claudeCodePluginCache = { hasCM };
|
|
40
|
+
return hasCM;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
claudeCodePluginCache = "miss";
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Test-only: reset the installed_plugins.json memo so each test starts cold. */
|
|
48
|
+
export function __resetClaudeCodePluginCacheForTests() {
|
|
49
|
+
claudeCodePluginCache = null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Test-only: pretend installed_plugins.json does not exist (or has no
|
|
53
|
+
* context-mode entry). Lets tests that exercise the genuine vscode-copilot
|
|
54
|
+
* env-var path run on a developer machine that actually has context-mode
|
|
55
|
+
* installed as a Claude Code plugin.
|
|
56
|
+
*/
|
|
57
|
+
export function __seedClaudeCodePluginCacheMissForTests() {
|
|
58
|
+
claudeCodePluginCache = "miss";
|
|
59
|
+
}
|
|
24
60
|
/**
|
|
25
61
|
* High-confidence env vars per platform, checked in priority order.
|
|
26
62
|
* Single source of truth — consumed by detectPlatform() below and by
|
|
@@ -30,7 +66,22 @@ export const PLATFORM_ENV_VARS = [
|
|
|
30
66
|
// Order matters: forks listed BEFORE the fork's parent so collision
|
|
31
67
|
// detection works. Every entry verified against platform's own runtime
|
|
32
68
|
// source code (PR #376 follow-up: full audit, May 2026 — see git blame).
|
|
33
|
-
|
|
69
|
+
// Claude Code — verified against a live `env` dump (2026-05-11):
|
|
70
|
+
// CLAUDE_CODE_ENTRYPOINT=cli (set on every CC session)
|
|
71
|
+
// CLAUDE_PLUGIN_ROOT=/Users/.../<version> (set when a plugin is loaded)
|
|
72
|
+
// CLAUDE_PROJECT_DIR=/Users/.../project (set in hooks context)
|
|
73
|
+
// CLAUDE_SESSION_ID=<uuid> (legacy session marker)
|
|
74
|
+
// CLAUDE_CODE_ENTRYPOINT and CLAUDE_PLUGIN_ROOT are CC-exclusive — they
|
|
75
|
+
// are the disambiguators for issue #539 (Claude Code running inside a
|
|
76
|
+
// VS Code integrated terminal that has VSCODE_PID set). They MUST be
|
|
77
|
+
// checked here so detect resolves to claude-code BEFORE falling through
|
|
78
|
+
// to vscode-copilot at line 70 below.
|
|
79
|
+
["claude-code", [
|
|
80
|
+
"CLAUDE_CODE_ENTRYPOINT",
|
|
81
|
+
"CLAUDE_PLUGIN_ROOT",
|
|
82
|
+
"CLAUDE_PROJECT_DIR",
|
|
83
|
+
"CLAUDE_SESSION_ID",
|
|
84
|
+
]],
|
|
34
85
|
// antigravity (Electron/VSCode fork) — google-gemini/gemini-cli
|
|
35
86
|
// packages/core/src/ide/detect-ide.ts checks ANTIGRAVITY_CLI_ALIAS as the
|
|
36
87
|
// canonical Antigravity marker. Listed before vscode-copilot.
|
|
@@ -67,9 +118,15 @@ export const PLATFORM_ENV_VARS = [
|
|
|
67
118
|
// agent-dir override per `packages/utils/src/dirs.ts:193`. Listed
|
|
68
119
|
// BEFORE pi so OMP is not misclassified as Pi when both are installed.
|
|
69
120
|
["omp", ["PI_CODING_AGENT_DIR"]],
|
|
70
|
-
// pi —
|
|
71
|
-
//
|
|
72
|
-
|
|
121
|
+
// pi — Issue #542 marker correction. PI_PROJECT_DIR is a consumer-set
|
|
122
|
+
// var (read by src/adapters/pi/extension.ts) but is NOT auto-set by
|
|
123
|
+
// the Pi runtime — verified against
|
|
124
|
+
// refs/platforms/oh-my-pi/packages/coding-agent/src/mcp/transports/stdio.ts:55-63
|
|
125
|
+
// (env passthrough only, no synthesis). The Pi runtime DOES set
|
|
126
|
+
// PI_CONFIG_DIR (config dir override), PI_SESSION_FILE (active session
|
|
127
|
+
// path), and PI_COMPILED (binary build marker). PI_CODING_AGENT_DIR is
|
|
128
|
+
// owned by OMP above; keep it there.
|
|
129
|
+
["pi", ["PI_CONFIG_DIR", "PI_SESSION_FILE", "PI_COMPILED"]],
|
|
73
130
|
// openclaw — removed (runtime never sets OPENCLAW_HOME or OPENCLAW_CLI;
|
|
74
131
|
// detection falls through to ~/.openclaw/ config-dir tier below).
|
|
75
132
|
// kiro — not listed (no auto-set process env vars; ~/.kiro/ config-dir tier).
|
|
@@ -148,6 +205,22 @@ export function detectPlatform(clientInfo) {
|
|
|
148
205
|
// ── High confidence: environment variables ─────────────
|
|
149
206
|
for (const [platform, vars] of PLATFORM_ENV_VARS) {
|
|
150
207
|
if (vars.some((v) => process.env[v])) {
|
|
208
|
+
// Issue #539 belt-and-suspenders: VSCODE_PID/VSCODE_CWD are exported
|
|
209
|
+
// by VS Code into EVERY child process — including a Claude Code CLI
|
|
210
|
+
// launched from the integrated terminal. If env vars alone want to
|
|
211
|
+
// resolve to vscode-copilot, but ~/.claude/plugins/installed_plugins.json
|
|
212
|
+
// lists context-mode as a Claude Code plugin, the runtime must be
|
|
213
|
+
// Claude Code (VS Code Copilot has no plugin concept). The env-var
|
|
214
|
+
// tier above already handles the common case via CLAUDE_CODE_ENTRYPOINT
|
|
215
|
+
// / CLAUDE_PLUGIN_ROOT; this branch covers MCP-server-only boots where
|
|
216
|
+
// those vars have not propagated yet.
|
|
217
|
+
if (platform === "vscode-copilot" && claudeCodeHasContextModePlugin()) {
|
|
218
|
+
return {
|
|
219
|
+
platform: "claude-code",
|
|
220
|
+
confidence: "high",
|
|
221
|
+
reason: "VSCODE_PID set but ~/.claude/plugins/installed_plugins.json lists context-mode (issue #539 fallback)",
|
|
222
|
+
};
|
|
223
|
+
}
|
|
151
224
|
return {
|
|
152
225
|
platform,
|
|
153
226
|
confidence: "high",
|
|
@@ -178,13 +251,15 @@ export function detectPlatform(clientInfo) {
|
|
|
178
251
|
reason: "~/.codex/ directory exists",
|
|
179
252
|
};
|
|
180
253
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
254
|
+
// Issue #542 — CLI agents BEFORE host IDEs.
|
|
255
|
+
//
|
|
256
|
+
// Cursor (a VSCode fork) is the most installed editor across our user
|
|
257
|
+
// base. Checking ~/.cursor/ first means every CLI agent co-installed
|
|
258
|
+
// with Cursor (Pi, OMP, Kiro, Qwen) silently routes through
|
|
259
|
+
// CursorAdapter even though the agent owns the session — Cursor merely
|
|
260
|
+
// hosts the terminal. Reorder: agents (.kiro/.omp/.pi/.qwen/.openclaw)
|
|
261
|
+
// win the medium-confidence tier, editors (~/.cursor/, ~/.vscode/,
|
|
262
|
+
// JetBrains) lose. Verified by the detect-config-dir.test.ts matrix.
|
|
188
263
|
if (existsSync(resolve(home, ".kiro"))) {
|
|
189
264
|
return {
|
|
190
265
|
platform: "kiro",
|
|
@@ -221,6 +296,14 @@ export function detectPlatform(clientInfo) {
|
|
|
221
296
|
reason: "~/.openclaw/ directory exists",
|
|
222
297
|
};
|
|
223
298
|
}
|
|
299
|
+
// Cursor / host IDEs — checked AFTER all CLI agents (issue #542).
|
|
300
|
+
if (existsSync(resolve(home, ".cursor"))) {
|
|
301
|
+
return {
|
|
302
|
+
platform: "cursor",
|
|
303
|
+
confidence: "medium",
|
|
304
|
+
reason: "~/.cursor/ directory exists",
|
|
305
|
+
};
|
|
306
|
+
}
|
|
224
307
|
if (existsSync(resolve(home, ".config", "kilo"))) {
|
|
225
308
|
return {
|
|
226
309
|
platform: "kilo",
|
|
@@ -27,6 +27,22 @@ export declare const HOOK_TYPES: {
|
|
|
27
27
|
readonly SESSION_START: "SessionStart";
|
|
28
28
|
};
|
|
29
29
|
export type HookType = (typeof HOOK_TYPES)[keyof typeof HOOK_TYPES];
|
|
30
|
+
/**
|
|
31
|
+
* Negative-lookahead matcher for external MCP tool namespaces on Gemini CLI (#529).
|
|
32
|
+
*
|
|
33
|
+
* Gemini CLI MCP wire shape: `mcp__<server>__<tool>` (verified in
|
|
34
|
+
* hooks/core/tool-naming.mjs — context-mode's own tools surface as
|
|
35
|
+
* `mcp__context-mode__<tool>`). This pattern fires BeforeTool for any
|
|
36
|
+
* external `mcp__<server>__<tool>` whose server segment does NOT contain
|
|
37
|
+
* `context-mode`. Without it, large payloads from slack / telegram / gdrive /
|
|
38
|
+
* notion-style MCPs bypass the routing nudge and flood the model's context.
|
|
39
|
+
*
|
|
40
|
+
* The negative lookahead `(?!.*context-mode)` covers both the canonical
|
|
41
|
+
* `mcp__context-mode__*` and any Claude shim `mcp__plugin_context-mode_*`
|
|
42
|
+
* names. Gemini native bare tool names (run_shell_command, read_file, …)
|
|
43
|
+
* are not `mcp__`-prefixed and are unaffected.
|
|
44
|
+
*/
|
|
45
|
+
export declare const EXTERNAL_MCP_MATCHER_PATTERN = "mcp__(?!.*context-mode)";
|
|
30
46
|
/** Map of hook types to their script file names. */
|
|
31
47
|
export declare const HOOK_SCRIPTS: Record<HookType, string>;
|
|
32
48
|
/** Required hooks that must be configured for context-mode to function. */
|
|
@@ -31,6 +31,25 @@ export const HOOK_TYPES = {
|
|
|
31
31
|
SESSION_START: "SessionStart",
|
|
32
32
|
};
|
|
33
33
|
// ─────────────────────────────────────────────────────────
|
|
34
|
+
// External MCP routing matcher (#529)
|
|
35
|
+
// ─────────────────────────────────────────────────────────
|
|
36
|
+
/**
|
|
37
|
+
* Negative-lookahead matcher for external MCP tool namespaces on Gemini CLI (#529).
|
|
38
|
+
*
|
|
39
|
+
* Gemini CLI MCP wire shape: `mcp__<server>__<tool>` (verified in
|
|
40
|
+
* hooks/core/tool-naming.mjs — context-mode's own tools surface as
|
|
41
|
+
* `mcp__context-mode__<tool>`). This pattern fires BeforeTool for any
|
|
42
|
+
* external `mcp__<server>__<tool>` whose server segment does NOT contain
|
|
43
|
+
* `context-mode`. Without it, large payloads from slack / telegram / gdrive /
|
|
44
|
+
* notion-style MCPs bypass the routing nudge and flood the model's context.
|
|
45
|
+
*
|
|
46
|
+
* The negative lookahead `(?!.*context-mode)` covers both the canonical
|
|
47
|
+
* `mcp__context-mode__*` and any Claude shim `mcp__plugin_context-mode_*`
|
|
48
|
+
* names. Gemini native bare tool names (run_shell_command, read_file, …)
|
|
49
|
+
* are not `mcp__`-prefixed and are unaffected.
|
|
50
|
+
*/
|
|
51
|
+
export const EXTERNAL_MCP_MATCHER_PATTERN = "mcp__(?!.*context-mode)";
|
|
52
|
+
// ─────────────────────────────────────────────────────────
|
|
34
53
|
// Hook script file names
|
|
35
54
|
// ─────────────────────────────────────────────────────────
|
|
36
55
|
/** Map of hook types to their script file names. */
|