context-mode 0.9.21 → 1.0.0

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.
Files changed (102) hide show
  1. package/.claude-plugin/hooks/hooks.json +46 -4
  2. package/.claude-plugin/marketplace.json +2 -2
  3. package/.claude-plugin/plugin.json +4 -4
  4. package/README.md +377 -191
  5. package/build/adapters/claude-code/config.d.ts +8 -0
  6. package/build/adapters/claude-code/config.js +8 -0
  7. package/build/adapters/claude-code/hooks.d.ts +53 -0
  8. package/build/adapters/claude-code/hooks.js +88 -0
  9. package/build/adapters/claude-code/index.d.ts +50 -0
  10. package/build/adapters/claude-code/index.js +523 -0
  11. package/build/adapters/codex/config.d.ts +8 -0
  12. package/build/adapters/codex/config.js +8 -0
  13. package/build/adapters/codex/hooks.d.ts +21 -0
  14. package/build/adapters/codex/hooks.js +27 -0
  15. package/build/adapters/codex/index.d.ts +44 -0
  16. package/build/adapters/codex/index.js +223 -0
  17. package/build/adapters/detect.d.ts +26 -0
  18. package/build/adapters/detect.js +131 -0
  19. package/build/adapters/gemini-cli/config.d.ts +8 -0
  20. package/build/adapters/gemini-cli/config.js +8 -0
  21. package/build/adapters/gemini-cli/hooks.d.ts +44 -0
  22. package/build/adapters/gemini-cli/hooks.js +64 -0
  23. package/build/adapters/gemini-cli/index.d.ts +57 -0
  24. package/build/adapters/gemini-cli/index.js +468 -0
  25. package/build/adapters/opencode/config.d.ts +8 -0
  26. package/build/adapters/opencode/config.js +8 -0
  27. package/build/adapters/opencode/hooks.d.ts +38 -0
  28. package/build/adapters/opencode/hooks.js +50 -0
  29. package/build/adapters/opencode/index.d.ts +52 -0
  30. package/build/adapters/opencode/index.js +386 -0
  31. package/build/adapters/types.d.ts +218 -0
  32. package/build/adapters/types.js +13 -0
  33. package/build/adapters/vscode-copilot/config.d.ts +8 -0
  34. package/build/adapters/vscode-copilot/config.js +8 -0
  35. package/build/adapters/vscode-copilot/hooks.d.ts +49 -0
  36. package/build/adapters/vscode-copilot/hooks.js +76 -0
  37. package/build/adapters/vscode-copilot/index.d.ts +58 -0
  38. package/build/adapters/vscode-copilot/index.js +512 -0
  39. package/build/cli.d.ts +9 -6
  40. package/build/cli.js +133 -423
  41. package/build/db-base.d.ts +84 -0
  42. package/build/db-base.js +128 -0
  43. package/build/executor.d.ts +6 -7
  44. package/build/executor.js +111 -51
  45. package/build/opencode-plugin.d.ts +37 -0
  46. package/build/opencode-plugin.js +118 -0
  47. package/build/runtime.js +1 -1
  48. package/build/server.js +436 -117
  49. package/build/session/db.d.ts +110 -0
  50. package/build/session/db.js +285 -0
  51. package/build/session/extract.d.ts +51 -0
  52. package/build/session/extract.js +407 -0
  53. package/build/session/snapshot.d.ts +70 -0
  54. package/build/session/snapshot.js +309 -0
  55. package/build/store.d.ts +4 -22
  56. package/build/store.js +67 -55
  57. package/build/truncate.d.ts +59 -0
  58. package/build/truncate.js +157 -0
  59. package/build/types.d.ts +101 -0
  60. package/build/types.js +20 -0
  61. package/configs/claude-code/CLAUDE.md +62 -0
  62. package/configs/codex/AGENTS.md +58 -0
  63. package/configs/codex/config.toml +5 -0
  64. package/configs/gemini-cli/GEMINI.md +58 -0
  65. package/configs/gemini-cli/mcp.json +7 -0
  66. package/configs/gemini-cli/settings.json +49 -0
  67. package/configs/opencode/AGENTS.md +58 -0
  68. package/configs/opencode/opencode.json +10 -0
  69. package/configs/vscode-copilot/copilot-instructions.md +58 -0
  70. package/configs/vscode-copilot/hooks.json +16 -0
  71. package/configs/vscode-copilot/mcp.json +8 -0
  72. package/hooks/core/formatters.mjs +86 -0
  73. package/hooks/core/routing.mjs +262 -0
  74. package/hooks/core/stdin.mjs +19 -0
  75. package/hooks/formatters/claude-code.mjs +57 -0
  76. package/hooks/formatters/gemini-cli.mjs +55 -0
  77. package/hooks/formatters/vscode-copilot.mjs +55 -0
  78. package/hooks/gemini-cli/aftertool.mjs +58 -0
  79. package/hooks/gemini-cli/beforetool.mjs +25 -0
  80. package/hooks/gemini-cli/precompress.mjs +51 -0
  81. package/hooks/gemini-cli/sessionstart.mjs +117 -0
  82. package/hooks/hooks.json +46 -4
  83. package/hooks/posttooluse.mjs +53 -0
  84. package/hooks/precompact.mjs +55 -0
  85. package/hooks/pretooluse.mjs +23 -266
  86. package/hooks/routing-block.mjs +19 -6
  87. package/hooks/session-directive.mjs +353 -0
  88. package/hooks/session-helpers.mjs +112 -0
  89. package/hooks/sessionstart.mjs +123 -16
  90. package/hooks/userpromptsubmit.mjs +58 -0
  91. package/hooks/vscode-copilot/posttooluse.mjs +58 -0
  92. package/hooks/vscode-copilot/precompact.mjs +51 -0
  93. package/hooks/vscode-copilot/pretooluse.mjs +25 -0
  94. package/hooks/vscode-copilot/sessionstart.mjs +115 -0
  95. package/package.json +20 -17
  96. package/skills/context-mode/SKILL.md +49 -49
  97. package/skills/{doctor → ctx-doctor}/SKILL.md +3 -3
  98. package/skills/{stats → ctx-stats}/SKILL.md +3 -3
  99. package/skills/{upgrade → ctx-upgrade}/SKILL.md +3 -3
  100. package/start.mjs +47 -0
  101. package/hooks/pretooluse.sh +0 -147
  102. package/server.bundle.mjs +0 -341
package/start.mjs CHANGED
@@ -12,6 +12,53 @@ if (!process.env.CLAUDE_PROJECT_DIR) {
12
12
  process.env.CLAUDE_PROJECT_DIR = process.cwd();
13
13
  }
14
14
 
15
+ // Auto-write routing instructions file for the detected platform
16
+ try {
17
+ const projectDir =
18
+ process.env.CLAUDE_PROJECT_DIR ||
19
+ process.env.GEMINI_PROJECT_DIR ||
20
+ process.env.VSCODE_CWD ||
21
+ process.cwd();
22
+
23
+ const configsDir = resolve(__dirname, "configs");
24
+
25
+ // Detect platform and determine instruction file
26
+ const platformConfigs = [
27
+ { env: ["CLAUDE_PROJECT_DIR", "CLAUDE_SESSION_ID"], dir: "claude-code", file: "CLAUDE.md", target: "CLAUDE.md" },
28
+ { env: ["GEMINI_PROJECT_DIR", "GEMINI_SESSION_ID"], dir: "gemini-cli", file: "GEMINI.md", target: "GEMINI.md" },
29
+ { env: ["VSCODE_PID", "VSCODE_CWD"], dir: "vscode-copilot", file: "copilot-instructions.md", target: ".github/copilot-instructions.md" },
30
+ { env: ["OPENCODE_PROJECT_DIR", "OPENCODE_SESSION_ID"], dir: "opencode", file: "AGENTS.md", target: "AGENTS.md" },
31
+ { env: ["CODEX_HOME"], dir: "codex", file: "AGENTS.md", target: "AGENTS.md" },
32
+ ];
33
+
34
+ const detected = platformConfigs.find((p) => p.env.some((e) => process.env[e]));
35
+ if (detected) {
36
+ const targetPath = resolve(projectDir, detected.target);
37
+ const sourcePath = resolve(configsDir, detected.dir, detected.file);
38
+
39
+ // Ensure parent dir exists (for .github/copilot-instructions.md)
40
+ const targetDir = resolve(targetPath, "..");
41
+ if (!existsSync(targetDir)) {
42
+ const { mkdirSync } = await import("node:fs");
43
+ mkdirSync(targetDir, { recursive: true });
44
+ }
45
+
46
+ if (existsSync(sourcePath)) {
47
+ const content = readFileSync(sourcePath, "utf-8");
48
+ if (existsSync(targetPath)) {
49
+ const existing = readFileSync(targetPath, "utf-8");
50
+ if (!existing.includes("context-mode")) {
51
+ writeFileSync(targetPath, existing.trimEnd() + "\n\n" + content, "utf-8");
52
+ }
53
+ } else {
54
+ writeFileSync(targetPath, content, "utf-8");
55
+ }
56
+ }
57
+ }
58
+ } catch {
59
+ /* best effort — don't block server startup */
60
+ }
61
+
15
62
  // Self-heal: if a newer version dir exists, update registry so next session uses it
16
63
  const cacheMatch = __dirname.match(
17
64
  /^(.*[\/\\]plugins[\/\\]cache[\/\\][^\/\\]+[\/\\][^\/\\]+[\/\\])([^\/\\]+)$/,
@@ -1,147 +0,0 @@
1
- #!/bin/bash
2
- # Unified PreToolUse hook for context-mode
3
- # Redirects data-fetching tools to context-mode MCP tools
4
-
5
- INPUT=$(cat /dev/stdin)
6
- TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
7
-
8
- # ─── Bash: redirect data-fetching commands via updatedInput ───
9
- if [ "$TOOL" = "Bash" ]; then
10
- COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
11
-
12
- # curl/wget → replace with echo redirect
13
- if echo "$COMMAND" | grep -qiE '(^|\s|&&|\||\;)(curl|wget)\s'; then
14
- jq -n '{
15
- "hookSpecificOutput": {
16
- "hookEventName": "PreToolUse",
17
- "updatedInput": {
18
- "command": "echo \"context-mode: curl/wget blocked. You MUST use mcp__context-mode__fetch_and_index(url, source) to fetch URLs, or mcp__context-mode__execute(language, code) to run HTTP calls in sandbox. Do NOT retry with curl/wget.\""
19
- }
20
- }
21
- }'
22
- exit 0
23
- fi
24
-
25
- # inline fetch (node -e, python -c, etc.) → replace with echo redirect
26
- if echo "$COMMAND" | grep -qiE 'fetch\s*\(\s*['"'"'"](https?://|http)' || \
27
- echo "$COMMAND" | grep -qiE 'requests\.(get|post|put)\s*\(' || \
28
- echo "$COMMAND" | grep -qiE 'http\.(get|request)\s*\('; then
29
- jq -n '{
30
- "hookSpecificOutput": {
31
- "hookEventName": "PreToolUse",
32
- "updatedInput": {
33
- "command": "echo \"context-mode: Inline HTTP blocked. Use mcp__context-mode__execute(language, code) to run HTTP calls in sandbox, or mcp__context-mode__fetch_and_index(url, source) for web pages. Do NOT retry with Bash.\""
34
- }
35
- }
36
- }'
37
- exit 0
38
- fi
39
-
40
- # allow all other Bash commands
41
- exit 0
42
- fi
43
-
44
- # ─── Read: nudge toward execute_file ───
45
- if [ "$TOOL" = "Read" ]; then
46
- jq -n '{
47
- "hookSpecificOutput": {
48
- "hookEventName": "PreToolUse",
49
- "additionalContext": "CONTEXT TIP: If this file is large (>50 lines), prefer mcp__context-mode__execute_file(path, language, code) — processes in sandbox, only stdout enters context."
50
- }
51
- }'
52
- exit 0
53
- fi
54
-
55
- # ─── Grep: nudge toward execute ───
56
- if [ "$TOOL" = "Grep" ]; then
57
- jq -n '{
58
- "hookSpecificOutput": {
59
- "hookEventName": "PreToolUse",
60
- "additionalContext": "CONTEXT TIP: If results may be large, prefer mcp__context-mode__execute(language: \"shell\", code: \"grep ...\") — runs in sandbox, only stdout enters context."
61
- }
62
- }'
63
- exit 0
64
- fi
65
-
66
- # ─── Glob: passthrough ───
67
- if [ "$TOOL" = "Glob" ]; then
68
- exit 0
69
- fi
70
-
71
- # ─── WebFetch: deny + redirect to sandbox ───
72
- if [ "$TOOL" = "WebFetch" ]; then
73
- ORIGINAL_URL=$(echo "$INPUT" | jq -r '.tool_input.url // ""')
74
- jq -n --arg url "$ORIGINAL_URL" '{
75
- "hookSpecificOutput": {
76
- "hookEventName": "PreToolUse",
77
- "permissionDecision": "deny",
78
- "reason": ("context-mode: WebFetch blocked. Use mcp__context-mode__fetch_and_index(url: \"" + $url + "\", source: \"...\") to fetch this URL in sandbox. Then use mcp__context-mode__search(queries: [...]) to query results. Do NOT use curl/wget — they are also blocked.")
79
- }
80
- }'
81
- exit 0
82
- fi
83
-
84
- # ─── WebSearch: passthrough ───
85
- if [ "$TOOL" = "WebSearch" ]; then
86
- exit 0
87
- fi
88
-
89
- # ─── Task: inject context-mode routing into subagent prompts ───
90
- if [ "$TOOL" = "Task" ]; then
91
- SUBAGENT_TYPE=$(echo "$INPUT" | jq -r '.tool_input.subagent_type // ""')
92
- ROUTING_BLOCK='
93
-
94
- ---
95
- CONTEXT WINDOW PROTECTION — USE CONTEXT-MODE MCP TOOLS
96
-
97
- Raw Bash/Read/WebFetch output floods your context. You have context-mode tools that keep data in sandbox.
98
-
99
- STEP 1 — GATHER: mcp__context-mode__batch_execute(commands, queries)
100
- commands: [{label: "Name", command: "shell cmd"}, ...]
101
- queries: ["query1", "query2", ...] — put 5-8 queries covering everything you need.
102
- Runs all commands, indexes output, returns search results. ONE call, no follow-ups.
103
-
104
- STEP 2 — FOLLOW-UP: mcp__context-mode__search(queries: ["q1", "q2", "q3", ...])
105
- Pass ALL follow-up questions as queries array. ONE call, not separate calls.
106
-
107
- OTHER: execute(language, code) | execute_file(path, language, code) | fetch_and_index(url) + search
108
-
109
- FORBIDDEN: Bash for output, Read for files, WebFetch. Bash is ONLY for git/mkdir/rm/mv.
110
-
111
- OUTPUT FORMAT — KEEP YOUR FINAL RESPONSE UNDER 500 WORDS:
112
- The parent agent context window is precious. Your full response gets injected into it.
113
-
114
- 1. ARTIFACTS (PRDs, configs, code files) → Write to FILES, never return as inline text.
115
- Return only: file path + 1-line description.
116
- 2. DETAILED FINDINGS → Index into knowledge base:
117
- mcp__context-mode__index(content: "...", source: "descriptive-label")
118
- The parent agent shares the SAME knowledge base and can search() your indexed content.
119
- 3. YOUR RESPONSE must be a concise summary:
120
- - What you did (2-3 bullets)
121
- - File paths created/modified (if any)
122
- - Source labels you indexed (so parent can search)
123
- - Key findings in bullet points
124
- Do NOT return raw data, full file contents, or lengthy explanations.
125
- ---'
126
-
127
- if [ "$SUBAGENT_TYPE" = "Bash" ]; then
128
- # Bash subagents only have the Bash tool — upgrade to general-purpose for MCP access
129
- echo "$INPUT" | jq --arg routing "$ROUTING_BLOCK" '{
130
- "hookSpecificOutput": {
131
- "hookEventName": "PreToolUse",
132
- "updatedInput": (.tool_input + { "prompt": (.tool_input.prompt + $routing), "subagent_type": "general-purpose" })
133
- }
134
- }'
135
- else
136
- echo "$INPUT" | jq --arg routing "$ROUTING_BLOCK" '{
137
- "hookSpecificOutput": {
138
- "hookEventName": "PreToolUse",
139
- "updatedInput": (.tool_input + { "prompt": (.tool_input.prompt + $routing) })
140
- }
141
- }'
142
- fi
143
- exit 0
144
- fi
145
-
146
- # Unknown tool — pass through
147
- exit 0