context-mode 0.4.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.
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "context-mode",
3
+ "version": "0.4.0",
4
+ "description": "Claude Code MCP plugin that saves 94% of your context window. Sandboxed code execution in 10 languages, FTS5 knowledge base with BM25 ranking, and smart truncation.",
5
+ "author": {
6
+ "name": "Mert Koseoğlu",
7
+ "url": "https://github.com/mksglu"
8
+ },
9
+ "homepage": "https://github.com/mksglu/claude-context-mode#readme",
10
+ "repository": "https://github.com/mksglu/claude-context-mode",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "mcp",
14
+ "context-window",
15
+ "sandbox",
16
+ "code-execution",
17
+ "fts5",
18
+ "bm25",
19
+ "playwright",
20
+ "context7"
21
+ ],
22
+ "mcpServers": {
23
+ "context-mode": {
24
+ "command": "node",
25
+ "args": ["${CLAUDE_PLUGIN_ROOT}/build/server.js"]
26
+ }
27
+ },
28
+ "skills": "./skills/"
29
+ }
package/.mcp.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "context-mode": {
4
+ "command": "node",
5
+ "args": ["${CLAUDE_PLUGIN_ROOT}/build/server.js"]
6
+ }
7
+ }
8
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mert Koseoğlu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,304 @@
1
+ # Context Mode
2
+
3
+ **Claude Code MCP plugin that saves 94% of your context window.**
4
+
5
+ Every tool call in Claude Code consumes context tokens. A single Playwright snapshot burns 10K-135K tokens. A Context7 docs lookup dumps 4K-10K tokens. GitHub's `list_commits` with 30 results costs 29K-64K tokens. With 5+ MCP servers active, you lose ~55K tokens before your first message — and after 30 minutes of real debugging, responses slow to a crawl.
6
+
7
+ Context Mode intercepts these operations, processes data in isolated subprocesses, and returns only what matters.
8
+
9
+ ## The Problem: MCP Context Bloat
10
+
11
+ Claude Code has a 200K token context window. Here's how fast popular MCP servers eat through it:
12
+
13
+ | MCP Server | Tool | Output per Call | Source |
14
+ |---|---|---|---|
15
+ | **Playwright** | `browser_snapshot` | 10K-135K tokens (50-540 KB) | [playwright-mcp#1233](https://github.com/microsoft/playwright-mcp/issues/1233) |
16
+ | **Context7** | `query-docs` | 4K-10K tokens per query | [upstash/context7](https://github.com/upstash/context7) |
17
+ | **GitHub** | `list_commits` (30) | 29K-64K tokens | [github-mcp-server#142](https://github.com/github/github-mcp-server/issues/142) |
18
+ | **Sentry** | full mode tools | 14K tokens (definitions only) | [getsentry/sentry-mcp](https://github.com/getsentry/sentry-mcp) |
19
+ | **Supabase** | database tools | 4.2K tokens (definitions only) | [supabase-community/supabase-mcp](https://github.com/supabase-community/supabase-mcp) |
20
+ | **Firecrawl** | `scrape` / `crawl` | 5K-50K+ tokens per page | [firecrawl](https://github.com/mendableai/firecrawl) |
21
+ | **Chrome DevTools** | all tools | 17K tokens (definitions only) | Community benchmark |
22
+ | **Fetch** | `fetch` | 5K-50K tokens per page | Official reference server |
23
+
24
+ **Real measurement** ([Scott Spence, 2025](https://scottspence.com/posts/optimising-mcp-server-context-usage-in-claude-code)): With 81+ MCP tools enabled across multiple servers, **143K of 200K tokens (72%) consumed** — 82K tokens just for MCP tool definitions. Only 28% left for actual work.
25
+
26
+ **Vercel's finding** ([December 2025](https://www.anthropic.com/engineering/advanced-tool-use)): Removing 80% of tools resulted in 3.5x faster execution, 37% fewer tokens, and 100% success rate (up from 80%).
27
+
28
+ ## Before / After
29
+
30
+ | What you're doing | Without Context Mode | With Context Mode | Savings |
31
+ |---|---|---|---|
32
+ | Playwright `browser_snapshot` | 12 KB into context | 50 B summary | **99%** |
33
+ | Context7 `query-docs` (React) | 60 KB raw docs | 285 B search result | **99%** |
34
+ | `gh pr list` / `gh api` | 8 KB JSON response | 40 B summary | **99%** |
35
+ | Read `access.log` (500 req) | 45 KB raw log | 71 B status breakdown | **99%** |
36
+ | `npm test` (30 suites) | 6 KB raw output | 37 B pass/fail | **99%** |
37
+ | Git log (153 commits) | 12 KB raw log | 18 B summary | **99%** |
38
+ | Supabase Edge Functions docs | 4 KB raw docs | 123 B code example | **97%** |
39
+
40
+ **Real aggregate across 13 scenarios: 194 KB raw → 12.6 KB context (94% savings)**
41
+
42
+ ## Quick Start
43
+
44
+ ### Option 1: Claude Code Plugin (Recommended)
45
+
46
+ ```bash
47
+ /plugin install context-mode@claude-plugin-directory
48
+ ```
49
+
50
+ Installs as a Claude Code plugin with skills and MCP server bundled together.
51
+
52
+ ### Option 2: MCP Server Only
53
+
54
+ ```bash
55
+ claude mcp add context-mode -- npx -y context-mode
56
+ ```
57
+
58
+ Restart Claude Code. 5 tools are now available.
59
+
60
+ ## Tools
61
+
62
+ ### `execute` — Run Code in Sandbox
63
+
64
+ Execute code in 10 languages: JavaScript, TypeScript, Python, Shell, Ruby, Go, Rust, PHP, Perl, R. Only stdout enters context — raw data stays in the subprocess.
65
+
66
+ ```
67
+ Claude calls: execute({ language: "shell", code: "gh pr list --json title,state | jq length" })
68
+ Returns: "3" ← 2 bytes instead of 8KB JSON
69
+ ```
70
+
71
+ Authenticated CLIs work out of the box — `gh`, `aws`, `gcloud`, `kubectl`, `docker` credentials are passed through securely. Bun auto-detected for 3-5x faster JS/TS.
72
+
73
+ ### `execute_file` — Process Files Without Loading
74
+
75
+ File contents never enter context. The file is read into a `FILE_CONTENT` variable inside the sandbox.
76
+
77
+ ```
78
+ Claude calls: execute_file({ path: "access.log", language: "python", code: "..." })
79
+ Returns: "200: 312 | 404: 89 | 500: 14" ← 30 bytes instead of 45KB
80
+ ```
81
+
82
+ ### `index` — Build Searchable Knowledge Base
83
+
84
+ Chunks markdown by headings, keeps code blocks intact, stores in ephemeral FTS5 database with BM25 ranking.
85
+
86
+ ```
87
+ Claude calls: index({ content: <60KB React docs>, source: "React useEffect" })
88
+ Returns: "Indexed 33 sections (15 with code)" ← 40 bytes
89
+ ```
90
+
91
+ ### `search` — Retrieve Exact Content
92
+
93
+ BM25 full-text search with Porter stemming. Returns exact code blocks — not summaries.
94
+
95
+ ```
96
+ Claude calls: search({ query: "useEffect cleanup function" })
97
+ Returns: exact code example with heading context ← 500 bytes instead of 60KB
98
+ ```
99
+
100
+ ### `fetch_and_index` — Fetch & Index URLs
101
+
102
+ Fetches URL in subprocess, converts HTML to markdown, indexes into FTS5. Raw content never enters context.
103
+
104
+ ```
105
+ Claude calls: fetch_and_index({ url: "https://react.dev/reference/react/useEffect" })
106
+ Returns: "Indexed 33 sections (15 with code)" ← 40 bytes instead of 60KB
107
+ ```
108
+
109
+ Use instead of WebFetch or Context7 when you need documentation — index once, search many times.
110
+
111
+ ## How It Works
112
+
113
+ ```
114
+ ┌──────────────────────────────────────────────────────────────────┐
115
+ │ Without Context Mode │
116
+ │ │
117
+ │ Claude Code → Playwright snapshot → 12KB into context │
118
+ │ Claude Code → Context7 docs → 60KB into context │
119
+ │ Claude Code → gh pr list → 8KB into context │
120
+ │ Claude Code → cat access.log → 45KB into context │
121
+ │ │
122
+ │ Total: 125KB consumed = ~32,000 tokens = 16% of context gone │
123
+ └──────────────────────────────────────────────────────────────────┘
124
+
125
+ ┌──────────────────────────────────────────────────────────────────┐
126
+ │ With Context Mode │
127
+ │ │
128
+ │ Claude Code → fetch_and_index(url) → "Indexed 8 sections" (50B)│
129
+ │ Claude Code → search("snapshot") → exact element (500B) │
130
+ │ Claude Code → execute("gh pr list") → "3 open PRs" (40B)│
131
+ │ Claude Code → execute_file(log) → "500:14, 404:89" (30B)│
132
+ │ │
133
+ │ Total: 620B consumed = ~160 tokens = 0.08% of context │
134
+ └──────────────────────────────────────────────────────────────────┘
135
+ ```
136
+
137
+ ## Architecture
138
+
139
+ ```
140
+ ┌─────────────┐ stdio / JSON-RPC ┌──────────────────────────────┐
141
+ │ │ ◄──────────────────────► │ Context Mode MCP Server │
142
+ │ Claude Code │ tool calls/results │ │
143
+ │ │ │ ┌────────────────────────┐ │
144
+ └─────────────┘ │ │ PolyglotExecutor │ │
145
+ │ │ • 10 language runtimes │ │
146
+ │ │ • Sandboxed subprocess │ │
147
+ │ │ • Auth passthrough │ │
148
+ │ │ • Smart truncation │ │
149
+ │ └────────────────────────┘ │
150
+ │ │
151
+ │ ┌────────────────────────┐ │
152
+ │ │ ContentStore │ │
153
+ │ │ • SQLite FTS5 │ │
154
+ │ │ • BM25 ranking │ │
155
+ │ │ • Porter stemming │ │
156
+ │ │ • Heading-aware chunks │ │
157
+ │ └────────────────────────┘ │
158
+ └──────────────────────────────┘
159
+ ```
160
+
161
+ ### Sandbox Isolation
162
+
163
+ Each `execute` call spawns an isolated subprocess with:
164
+
165
+ - **Isolated temp directory** per execution — scripts can't access each other
166
+ - **Real HOME** — so `gh`, `aws`, `gcloud` find their auth configs
167
+ - **Auth passthrough** — GH_TOKEN, AWS credentials, KUBECONFIG, Docker, npm tokens, XDG paths
168
+ - **Clean environment** — PATH, LANG, NO_COLOR, Python unbuffered mode
169
+
170
+ ### FTS5 Knowledge Base
171
+
172
+ The `index` and `search` tools use SQLite FTS5 with BM25 ranking:
173
+
174
+ ```sql
175
+ CREATE VIRTUAL TABLE chunks USING fts5(
176
+ title, -- heading hierarchy, weighted 2x
177
+ content, -- section text + code blocks
178
+ source_id UNINDEXED,
179
+ content_type UNINDEXED, -- "code" or "prose"
180
+ tokenize='porter unicode61' -- stemming + unicode support
181
+ );
182
+
183
+ SELECT title, content, bm25(chunks, 2.0, 1.0) AS rank
184
+ FROM chunks
185
+ WHERE chunks MATCH ?
186
+ ORDER BY rank LIMIT 3;
187
+ ```
188
+
189
+ **Chunking algorithm:**
190
+ - Splits on H1-H4 headings and `---` separators
191
+ - Tracks heading hierarchy: `"React > Hooks > useEffect > Cleanup"`
192
+ - Keeps code blocks intact — never splits mid-block
193
+ - Marks chunks as `code` or `prose` for content-type filtering
194
+ - Porter stemming: "connecting" matches "connect", "connection", "connected"
195
+
196
+ **Lazy singleton:** Database created only when `index` or `search` is first called — zero overhead for sessions that don't use it.
197
+
198
+ ### Smart Truncation
199
+
200
+ When subprocess output exceeds the 100KB buffer, Context Mode preserves both head and tail:
201
+
202
+ ```
203
+ Head (60%): Initial output with context
204
+ ... [47 lines / 3.2KB truncated — showing first 12 + last 8 lines] ...
205
+ Tail (40%): Final output with errors/results
206
+ ```
207
+
208
+ Line-boundary snapping — never cuts mid-line. Error messages at the bottom are always preserved.
209
+
210
+ ### HTML to Markdown Conversion
211
+
212
+ `fetch_and_index` converts HTML in a subprocess (raw HTML never enters context):
213
+
214
+ 1. Strip `<script>`, `<style>`, `<nav>`, `<header>`, `<footer>`
215
+ 2. Convert `<h1>`-`<h4>` to `#`-`####` markdown headings
216
+ 3. Convert `<pre><code>` to fenced code blocks with language detection
217
+ 4. Convert `<a>`, `<li>`, `<p>`, `<br>`, `<hr>` to markdown
218
+ 5. Decode HTML entities (`&amp;`, `&lt;`, `&nbsp;`, etc.)
219
+ 6. Collapse excessive whitespace
220
+
221
+ ## Benchmarks
222
+
223
+ ### Real MCP Ecosystem Comparison
224
+
225
+ Tested with tools from popular MCP servers and Claude Code workflows:
226
+
227
+ | Scenario | Tool | Raw | Context | Savings |
228
+ |---|---|---|---|---|
229
+ | Playwright page snapshot | `execute_file` | 50+ KB | 78 B | **99%** |
230
+ | Context7 React docs | `index + search` | 5.9 KB | 285 B | **95%** |
231
+ | Context7 Supabase docs | `index + search` | 3.9 KB | 123 B | **97%** |
232
+ | Context7 Next.js docs | `index + search` | 6.5 KB | 273 B | **96%** |
233
+ | httpbin.org API docs | `fetch_and_index` | 9.4 KB | 50 B | **99%** |
234
+ | GitHub API response | `execute` | 8+ KB | 40 B | **99%** |
235
+ | Access log (500 req) | `execute_file` | 45.1 KB | 71 B | **100%** |
236
+ | Analytics CSV (500 rows) | `execute_file` | 85.5 KB | 11.5 KB | **87%** |
237
+ | MCP tools manifest (40 tools) | `execute_file` | 17.0 KB | 78 B | **100%** |
238
+ | npm test (30 suites) | `execute_file` | 6.0 KB | 37 B | **99%** |
239
+ | Git log (153 commits) | `execute` | 11.6 KB | 18 B | **100%** |
240
+
241
+ ### Session Impact
242
+
243
+ Typical 45-minute debugging session:
244
+
245
+ | Metric | Without | With | Delta |
246
+ |---|---|---|---|
247
+ | Context consumed | 177 KB | 10 KB | **-94%** |
248
+ | Tokens used | ~45,300 | ~2,600 | **-94%** |
249
+ | Context remaining | 77% | 95% | **+18pp** |
250
+ | Time before slowdown | ~30 min | ~3 hours | **+6x** |
251
+
252
+ ## Tool Decision Matrix
253
+
254
+ | Data Type | Best Tool | Why |
255
+ |---|---|---|
256
+ | Web documentation | `fetch_and_index` → `search` | Index once, search many times |
257
+ | MCP tool output (large) | `index` → `search` | Keep raw output out of context |
258
+ | Log files | `execute_file` | Aggregate stats |
259
+ | Test output | `execute_file` | Pass/fail summary |
260
+ | CSV / JSON data | `execute_file` | Computed metrics |
261
+ | Git / GitHub operations | `execute` | `gh`, `git` commands with auth |
262
+ | Cloud CLI | `execute` | `aws`, `gcloud`, `kubectl` with auth |
263
+ | Build output | `execute` | Error counts and warnings |
264
+ | Source code to edit | Plain `Read` tool | Need full content for edits |
265
+ | Small files (<20 lines) | Plain `Read` tool | Minimal overhead |
266
+
267
+ ## Requirements
268
+
269
+ - **Node.js 18+**
270
+ - **Claude Code** with MCP support
271
+
272
+ ### Auto-Detected Runtimes
273
+
274
+ | Runtime | Used For | Speed |
275
+ |---|---|---|
276
+ | Bun (optional) | JS/TS execution | 3-5x faster than Node |
277
+ | Python 3 | Python code | Standard |
278
+ | Ruby, Go, Rust, PHP, Perl, R | Respective languages | Standard |
279
+
280
+ ## Test Suite
281
+
282
+ 113 tests across 3 suites:
283
+
284
+ | Suite | Tests | Coverage |
285
+ |---|---|---|
286
+ | Executor | 55 | 10 languages, sandbox, truncation, concurrency, timeouts |
287
+ | ContentStore | 34 | FTS5 schema, BM25 ranking, chunking, stemming, fixtures |
288
+ | MCP Integration | 24 | JSON-RPC protocol, all 5 tools, fetch_and_index, errors |
289
+
290
+ ## Development
291
+
292
+ ```bash
293
+ git clone https://github.com/mksglu/claude-context-mode.git
294
+ cd claude-context-mode
295
+ npm install
296
+ npm run build
297
+ npm test # executor (55 tests)
298
+ npm run test:store # FTS5/BM25 (34 tests)
299
+ npm run test:all # all suites (113 tests)
300
+ ```
301
+
302
+ ## License
303
+
304
+ MIT
package/build/cli.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * context-mode CLI
4
+ *
5
+ * Usage:
6
+ * context-mode → Start MCP server (stdio)
7
+ * context-mode setup → Interactive setup (detect runtimes, install Bun)
8
+ * context-mode doctor → Diagnose runtime issues
9
+ */
10
+ export {};
package/build/cli.js ADDED
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * context-mode CLI
4
+ *
5
+ * Usage:
6
+ * context-mode → Start MCP server (stdio)
7
+ * context-mode setup → Interactive setup (detect runtimes, install Bun)
8
+ * context-mode doctor → Diagnose runtime issues
9
+ */
10
+ import * as p from "@clack/prompts";
11
+ import color from "picocolors";
12
+ import { execSync } from "node:child_process";
13
+ import { detectRuntimes, getRuntimeSummary, hasBunRuntime, getAvailableLanguages, } from "./runtime.js";
14
+ const args = process.argv.slice(2);
15
+ if (args[0] === "setup") {
16
+ setup();
17
+ }
18
+ else if (args[0] === "doctor") {
19
+ doctor();
20
+ }
21
+ else {
22
+ // Default: start MCP server
23
+ import("./server.js");
24
+ }
25
+ async function setup() {
26
+ console.clear();
27
+ p.intro(color.bgCyan(color.black(" context-mode setup ")));
28
+ const s = p.spinner();
29
+ // Step 1: Detect runtimes
30
+ s.start("Detecting installed runtimes");
31
+ const runtimes = detectRuntimes();
32
+ const available = getAvailableLanguages(runtimes);
33
+ s.stop("Detected " + available.length + " languages");
34
+ // Show what's available
35
+ p.note(getRuntimeSummary(runtimes), "Detected Runtimes");
36
+ // Step 2: Check Bun
37
+ if (!hasBunRuntime()) {
38
+ p.log.warn(color.yellow("Bun is not installed.") +
39
+ " JS/TS will run with Node.js (3-5x slower).");
40
+ const installBun = await p.confirm({
41
+ message: "Would you like to install Bun for faster execution?",
42
+ initialValue: true,
43
+ });
44
+ if (p.isCancel(installBun)) {
45
+ p.cancel("Setup cancelled.");
46
+ process.exit(0);
47
+ }
48
+ if (installBun) {
49
+ s.start("Installing Bun");
50
+ try {
51
+ execSync("curl -fsSL https://bun.sh/install | bash", {
52
+ stdio: "pipe",
53
+ timeout: 60000,
54
+ });
55
+ s.stop(color.green("Bun installed successfully!"));
56
+ // Re-detect runtimes
57
+ const newRuntimes = detectRuntimes();
58
+ if (hasBunRuntime()) {
59
+ p.log.success("JavaScript and TypeScript will now use Bun " +
60
+ color.dim("(3-5x faster)"));
61
+ }
62
+ p.note(getRuntimeSummary(newRuntimes), "Updated Runtimes");
63
+ }
64
+ catch (err) {
65
+ const message = err instanceof Error ? err.message : String(err);
66
+ s.stop(color.red("Failed to install Bun"));
67
+ p.log.error("Installation failed: " +
68
+ message +
69
+ "\nYou can install manually: curl -fsSL https://bun.sh/install | bash");
70
+ p.log.info(color.dim("Continuing with Node.js — everything will still work."));
71
+ }
72
+ }
73
+ else {
74
+ p.log.info(color.dim("No problem! Using Node.js. You can install Bun later: curl -fsSL https://bun.sh/install | bash"));
75
+ }
76
+ }
77
+ else {
78
+ p.log.success(color.green("Bun detected!") +
79
+ " JS/TS will run at maximum speed.");
80
+ }
81
+ // Step 3: Check optional runtimes
82
+ const missing = [];
83
+ if (!runtimes.python)
84
+ missing.push("Python (python3)");
85
+ if (!runtimes.ruby)
86
+ missing.push("Ruby (ruby)");
87
+ if (!runtimes.go)
88
+ missing.push("Go (go)");
89
+ if (!runtimes.php)
90
+ missing.push("PHP (php)");
91
+ if (!runtimes.r)
92
+ missing.push("R (Rscript)");
93
+ if (missing.length > 0) {
94
+ p.log.info(color.dim("Optional runtimes not found: " + missing.join(", ")));
95
+ p.log.info(color.dim("Install them to enable additional language support in context-mode."));
96
+ }
97
+ // Step 4: Installation instructions
98
+ const installMethod = await p.select({
99
+ message: "How would you like to configure context-mode?",
100
+ options: [
101
+ {
102
+ value: "claude-code",
103
+ label: "Claude Code (recommended)",
104
+ hint: "claude mcp add",
105
+ },
106
+ {
107
+ value: "manual",
108
+ label: "Show manual configuration",
109
+ hint: ".mcp.json",
110
+ },
111
+ { value: "skip", label: "Skip — I'll configure later" },
112
+ ],
113
+ });
114
+ if (p.isCancel(installMethod)) {
115
+ p.cancel("Setup cancelled.");
116
+ process.exit(0);
117
+ }
118
+ const serverPath = new URL("./server.js", import.meta.url).pathname;
119
+ if (installMethod === "claude-code") {
120
+ s.start("Adding to Claude Code");
121
+ try {
122
+ execSync(`claude mcp add context-mode -- node ${serverPath}`, { stdio: "pipe", timeout: 10000 });
123
+ s.stop(color.green("Added to Claude Code!"));
124
+ }
125
+ catch {
126
+ s.stop(color.yellow("Could not add automatically"));
127
+ p.log.info("Run manually:\n" +
128
+ color.cyan(` claude mcp add context-mode -- node ${serverPath}`));
129
+ }
130
+ }
131
+ else if (installMethod === "manual") {
132
+ p.note(JSON.stringify({
133
+ mcpServers: {
134
+ "context-mode": {
135
+ command: "node",
136
+ args: [serverPath],
137
+ },
138
+ },
139
+ }, null, 2), "Add to your .mcp.json or Claude Code settings");
140
+ }
141
+ p.outro(color.green("Setup complete!") +
142
+ " " +
143
+ color.dim(available.length + " languages ready."));
144
+ }
145
+ async function doctor() {
146
+ console.clear();
147
+ p.intro(color.bgMagenta(color.white(" context-mode doctor ")));
148
+ const s = p.spinner();
149
+ s.start("Running diagnostics");
150
+ const runtimes = detectRuntimes();
151
+ const available = getAvailableLanguages(runtimes);
152
+ s.stop("Diagnostics complete");
153
+ // Runtime check
154
+ p.note(getRuntimeSummary(runtimes), "Runtimes");
155
+ // Speed tier
156
+ if (hasBunRuntime()) {
157
+ p.log.success(color.green("Performance: FAST") +
158
+ " — Bun detected for JS/TS execution");
159
+ }
160
+ else {
161
+ p.log.warn(color.yellow("Performance: NORMAL") +
162
+ " — Using Node.js (install Bun for 3-5x speed boost)");
163
+ }
164
+ // Language coverage
165
+ const total = 10;
166
+ const pct = ((available.length / total) * 100).toFixed(0);
167
+ p.log.info(`Language coverage: ${available.length}/${total} (${pct}%)` +
168
+ color.dim(` — ${available.join(", ")}`));
169
+ // Server test
170
+ p.log.step("Testing server initialization...");
171
+ try {
172
+ const { PolyglotExecutor } = await import("./executor.js");
173
+ const executor = new PolyglotExecutor({ runtimes });
174
+ const result = await executor.execute({
175
+ language: "javascript",
176
+ code: 'console.log("ok");',
177
+ timeout: 5000,
178
+ });
179
+ if (result.exitCode === 0 && result.stdout.trim() === "ok") {
180
+ p.log.success(color.green("Server test: PASS"));
181
+ }
182
+ else {
183
+ p.log.error(color.red("Server test: FAIL") + ` — exit ${result.exitCode}`);
184
+ }
185
+ }
186
+ catch (err) {
187
+ const message = err instanceof Error ? err.message : String(err);
188
+ p.log.error(color.red("Server test: FAIL") + ` — ${message}`);
189
+ }
190
+ p.outro(available.length >= 4
191
+ ? color.green("Everything looks good!")
192
+ : color.yellow("Some runtimes missing — install them for full coverage"));
193
+ }
@@ -0,0 +1,27 @@
1
+ import { type RuntimeMap, type Language } from "./runtime.js";
2
+ export interface ExecResult {
3
+ stdout: string;
4
+ stderr: string;
5
+ exitCode: number;
6
+ timedOut: boolean;
7
+ }
8
+ interface ExecuteOptions {
9
+ language: Language;
10
+ code: string;
11
+ timeout?: number;
12
+ }
13
+ interface ExecuteFileOptions extends ExecuteOptions {
14
+ path: string;
15
+ }
16
+ export declare class PolyglotExecutor {
17
+ #private;
18
+ constructor(opts?: {
19
+ maxOutputBytes?: number;
20
+ projectRoot?: string;
21
+ runtimes?: RuntimeMap;
22
+ });
23
+ get runtimes(): RuntimeMap;
24
+ execute(opts: ExecuteOptions): Promise<ExecResult>;
25
+ executeFile(opts: ExecuteFileOptions): Promise<ExecResult>;
26
+ }
27
+ export {};