context-compress 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 (118) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +275 -0
  3. package/dist/cli/doctor.d.ts +2 -0
  4. package/dist/cli/doctor.d.ts.map +1 -0
  5. package/dist/cli/doctor.js +131 -0
  6. package/dist/cli/doctor.js.map +1 -0
  7. package/dist/cli/index.d.ts +12 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +31 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/setup.d.ts +2 -0
  12. package/dist/cli/setup.d.ts.map +1 -0
  13. package/dist/cli/setup.js +43 -0
  14. package/dist/cli/setup.js.map +1 -0
  15. package/dist/cli/uninstall.d.ts +2 -0
  16. package/dist/cli/uninstall.d.ts.map +1 -0
  17. package/dist/cli/uninstall.js +102 -0
  18. package/dist/cli/uninstall.js.map +1 -0
  19. package/dist/config.d.ts +37 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +79 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/executor.d.ts +21 -0
  24. package/dist/executor.d.ts.map +1 -0
  25. package/dist/executor.js +301 -0
  26. package/dist/executor.js.map +1 -0
  27. package/dist/hooks/pretooluse.d.ts +10 -0
  28. package/dist/hooks/pretooluse.d.ts.map +1 -0
  29. package/dist/hooks/pretooluse.js +117 -0
  30. package/dist/hooks/pretooluse.js.map +1 -0
  31. package/dist/index.d.ts +2 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +9 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/logger.d.ts +4 -0
  36. package/dist/logger.d.ts.map +1 -0
  37. package/dist/logger.js +13 -0
  38. package/dist/logger.js.map +1 -0
  39. package/dist/runtime/index.d.ts +22 -0
  40. package/dist/runtime/index.d.ts.map +1 -0
  41. package/dist/runtime/index.js +81 -0
  42. package/dist/runtime/index.js.map +1 -0
  43. package/dist/runtime/languages/elixir.d.ts +3 -0
  44. package/dist/runtime/languages/elixir.d.ts.map +1 -0
  45. package/dist/runtime/languages/elixir.js +15 -0
  46. package/dist/runtime/languages/elixir.js.map +1 -0
  47. package/dist/runtime/languages/go.d.ts +3 -0
  48. package/dist/runtime/languages/go.d.ts.map +1 -0
  49. package/dist/runtime/languages/go.js +29 -0
  50. package/dist/runtime/languages/go.js.map +1 -0
  51. package/dist/runtime/languages/javascript.d.ts +3 -0
  52. package/dist/runtime/languages/javascript.d.ts.map +1 -0
  53. package/dist/runtime/languages/javascript.js +13 -0
  54. package/dist/runtime/languages/javascript.js.map +1 -0
  55. package/dist/runtime/languages/perl.d.ts +3 -0
  56. package/dist/runtime/languages/perl.d.ts.map +1 -0
  57. package/dist/runtime/languages/perl.js +13 -0
  58. package/dist/runtime/languages/perl.js.map +1 -0
  59. package/dist/runtime/languages/php.d.ts +3 -0
  60. package/dist/runtime/languages/php.d.ts.map +1 -0
  61. package/dist/runtime/languages/php.js +24 -0
  62. package/dist/runtime/languages/php.js.map +1 -0
  63. package/dist/runtime/languages/python.d.ts +3 -0
  64. package/dist/runtime/languages/python.d.ts.map +1 -0
  65. package/dist/runtime/languages/python.js +13 -0
  66. package/dist/runtime/languages/python.js.map +1 -0
  67. package/dist/runtime/languages/r.d.ts +3 -0
  68. package/dist/runtime/languages/r.d.ts.map +1 -0
  69. package/dist/runtime/languages/r.js +13 -0
  70. package/dist/runtime/languages/r.js.map +1 -0
  71. package/dist/runtime/languages/ruby.d.ts +3 -0
  72. package/dist/runtime/languages/ruby.d.ts.map +1 -0
  73. package/dist/runtime/languages/ruby.js +13 -0
  74. package/dist/runtime/languages/ruby.js.map +1 -0
  75. package/dist/runtime/languages/rust.d.ts +3 -0
  76. package/dist/runtime/languages/rust.d.ts.map +1 -0
  77. package/dist/runtime/languages/rust.js +28 -0
  78. package/dist/runtime/languages/rust.js.map +1 -0
  79. package/dist/runtime/languages/shell.d.ts +3 -0
  80. package/dist/runtime/languages/shell.d.ts.map +1 -0
  81. package/dist/runtime/languages/shell.js +14 -0
  82. package/dist/runtime/languages/shell.js.map +1 -0
  83. package/dist/runtime/languages/typescript.d.ts +3 -0
  84. package/dist/runtime/languages/typescript.d.ts.map +1 -0
  85. package/dist/runtime/languages/typescript.js +15 -0
  86. package/dist/runtime/languages/typescript.js.map +1 -0
  87. package/dist/runtime/plugin.d.ts +38 -0
  88. package/dist/runtime/plugin.d.ts.map +1 -0
  89. package/dist/runtime/plugin.js +2 -0
  90. package/dist/runtime/plugin.js.map +1 -0
  91. package/dist/server.bundle.mjs +22769 -0
  92. package/dist/server.bundle.mjs.map +7 -0
  93. package/dist/server.d.ts +5 -0
  94. package/dist/server.d.ts.map +1 -0
  95. package/dist/server.js +405 -0
  96. package/dist/server.js.map +1 -0
  97. package/dist/snippet.d.ts +15 -0
  98. package/dist/snippet.d.ts.map +1 -0
  99. package/dist/snippet.js +92 -0
  100. package/dist/snippet.js.map +1 -0
  101. package/dist/stats.d.ts +10 -0
  102. package/dist/stats.d.ts.map +1 -0
  103. package/dist/stats.js +65 -0
  104. package/dist/stats.js.map +1 -0
  105. package/dist/store.d.ts +44 -0
  106. package/dist/store.d.ts.map +1 -0
  107. package/dist/store.js +590 -0
  108. package/dist/store.js.map +1 -0
  109. package/dist/types.d.ts +75 -0
  110. package/dist/types.d.ts.map +1 -0
  111. package/dist/types.js +14 -0
  112. package/dist/types.js.map +1 -0
  113. package/hooks/hooks.json +52 -0
  114. package/hooks/pretooluse.mjs +94 -0
  115. package/package.json +55 -0
  116. package/skills/context-compress/SKILL.md +118 -0
  117. package/skills/doctor/SKILL.md +15 -0
  118. package/skills/stats/SKILL.md +11 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Open330
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,275 @@
1
+ <div align="center">
2
+
3
+ # context-compress
4
+
5
+ **Keep your context window lean. Let the sandbox do the heavy lifting.**
6
+
7
+ [![CI](https://github.com/Open330/context-compress/actions/workflows/ci.yml/badge.svg)](https://github.com/Open330/context-compress/actions)
8
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
10
+ [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=white)](tsconfig.json)
11
+
12
+ A context-aware **MCP server** for [Claude Code](https://claude.ai/claude-code) that compresses tool output by processing it in isolated subprocesses. Raw data stays in the sandbox — only concise summaries enter your context window.
13
+
14
+ [Quickstart for Agents](#quickstart-for-agents) · [Getting Started](#getting-started) · [How It Works](#how-it-works) · [Configuration](#configuration) · [CLI](#cli) · [Changelog](CHANGELOG.md)
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ ## Quickstart for Agents
21
+
22
+ ```
23
+ npm install -g context-compress && claude mcp add context-compress -- node $(which context-compress)
24
+ ```
25
+
26
+ MCP server that compresses tool output for Claude Code — raw data stays in sandboxed subprocesses, only concise summaries enter your context window.
27
+
28
+ ---
29
+
30
+ ## Why?
31
+
32
+ Every byte of tool output that enters your Claude Code context window **reduces quality and speed**.
33
+ A single `git log` or `npm test` can dump 50KB+ into context — that's ~12,000 tokens gone.
34
+
35
+ **context-compress** intercepts these tools, processes output in a sandbox, and returns only what matters:
36
+
37
+ ```
38
+ Before: git log --oneline -100 → 8.2KB into context
39
+ After: execute("git log ...") → 0.3KB summary + full data searchable in FTS5
40
+ ```
41
+
42
+ > Based on [context-mode](https://github.com/mksglu/claude-context-mode) by Mert Koseoğlu — rewritten in TypeScript with security hardening, architectural improvements, and better DX.
43
+
44
+ ---
45
+
46
+ ## Getting Started
47
+
48
+ ### Install
49
+
50
+ ```bash
51
+ npm install -g context-compress
52
+ ```
53
+
54
+ ### Add to Claude Code
55
+
56
+ ```bash
57
+ claude mcp add context-compress -- node $(which context-compress)
58
+ ```
59
+
60
+ Or add to your project's `.mcp.json`:
61
+
62
+ ```json
63
+ {
64
+ "mcpServers": {
65
+ "context-compress": {
66
+ "command": "node",
67
+ "args": ["/path/to/context-compress/dist/index.js"]
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Verify
74
+
75
+ ```bash
76
+ context-compress doctor
77
+ ```
78
+
79
+ ---
80
+
81
+ ## How It Works
82
+
83
+ ```
84
+ ┌─────────────────────────────────────────────────────────┐
85
+ │ Claude Code │
86
+ │ │
87
+ │ "Run tests" ──→ PreToolUse Hook intercepts │
88
+ │ │ │
89
+ │ ▼ │
90
+ │ ┌──────────────────┐ │
91
+ │ │ context-compress │ │
92
+ │ │ MCP Server │ │
93
+ │ └────────┬─────────┘ │
94
+ │ │ │
95
+ │ ┌───────────┼───────────┐ │
96
+ │ ▼ ▼ ▼ │
97
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
98
+ │ │ Executor │ │ Store │ │ Stats │ │
99
+ │ │ (11 lang)│ │ (FTS5) │ │ Tracker │ │
100
+ │ └──────────┘ └──────────┘ └──────────┘ │
101
+ │ │ │ │
102
+ │ ▼ ▼ │
103
+ │ Raw output Indexed & Only summary │
104
+ │ stays here searchable enters context │
105
+ └─────────────────────────────────────────────────────────┘
106
+ ```
107
+
108
+ ### 7 MCP Tools
109
+
110
+ | Tool | What it does |
111
+ |:-----|:-------------|
112
+ | **`execute`** | Run code in 11 languages. Only stdout enters context. |
113
+ | **`execute_file`** | Process a file via `FILE_CONTENT` variable — file never enters context. |
114
+ | **`index`** | Chunk markdown/text into FTS5 knowledge base for search. |
115
+ | **`search`** | BM25 search with Porter stemming → trigram → fuzzy fallback. |
116
+ | **`fetch_and_index`** | Fetch URL → HTML-to-markdown → auto-index. Preview only in context. |
117
+ | **`batch_execute`** | Run N commands + search in ONE call. Replaces 30+ tool calls. |
118
+ | **`stats`** | Real-time session statistics: bytes saved, tokens avoided, savings ratio. |
119
+
120
+ ### Supported Languages
121
+
122
+ `javascript` · `typescript` · `python` · `shell` · `ruby` · `go` · `rust` · `php` · `perl` · `r` · `elixir`
123
+
124
+ > Bun auto-detected for 3-5x faster JS/TS execution.
125
+
126
+ ---
127
+
128
+ ## What Changed from context-mode
129
+
130
+ | | context-mode | context-compress |
131
+ |:--|:------------|:-----------------|
132
+ | **Credentials** | 20+ auth env vars passed by default | Opt-in only (`passthroughEnvVars: []`) |
133
+ | **Hook writes** | Self-modifies `settings.json` | Zero filesystem writes |
134
+ | **Rust compile** | Shell string → injection risk | `execFileSync` with array args |
135
+ | **Upgrade** | `git clone` arbitrary code | Removed entirely |
136
+ | **FTS5 indexing** | Always dual-table (Porter + trigram) | Lazy trigram — 50% fewer writes |
137
+ | **Runtime detect** | Sequential `execSync` ~250ms | Parallel `Promise.all` ~40ms |
138
+ | **batch_execute** | Sequential commands | `Promise.allSettled` parallel |
139
+ | **Config** | None | ENV + file + defaults |
140
+ | **Errors** | 23 silent catch blocks | `CONTEXT_COMPRESS_DEBUG=1` logs all |
141
+ | **Uninstall** | None | `context-compress uninstall` |
142
+
143
+ ---
144
+
145
+ ## Configuration
146
+
147
+ Loaded in order: **ENV vars** → **`.context-compress.json`** → **defaults**
148
+
149
+ ### Environment Variables
150
+
151
+ ```bash
152
+ # Enable debug logging (stderr)
153
+ CONTEXT_COMPRESS_DEBUG=1
154
+
155
+ # Pass specific env vars to subprocesses (default: none)
156
+ CONTEXT_COMPRESS_PASSTHROUGH_ENV=GH_TOKEN,AWS_PROFILE
157
+
158
+ # Disable curl/wget blocking
159
+ CONTEXT_COMPRESS_BLOCK_CURL=0
160
+
161
+ # Disable WebFetch blocking
162
+ CONTEXT_COMPRESS_BLOCK_WEBFETCH=0
163
+
164
+ # Disable Read/Grep nudges
165
+ CONTEXT_COMPRESS_NUDGE_READ=0
166
+ CONTEXT_COMPRESS_NUDGE_GREP=0
167
+ ```
168
+
169
+ ### Config File
170
+
171
+ Create `.context-compress.json` in your project root or home directory:
172
+
173
+ ```json
174
+ {
175
+ "passthroughEnvVars": ["GH_TOKEN", "AWS_PROFILE", "KUBECONFIG"],
176
+ "blockCurl": true,
177
+ "blockWebFetch": true,
178
+ "debug": false
179
+ }
180
+ ```
181
+
182
+ ---
183
+
184
+ ## CLI
185
+
186
+ ```bash
187
+ context-compress # Start MCP server (stdio)
188
+ context-compress setup # Detect runtimes, show install instructions
189
+ context-compress doctor # Diagnose: runtimes, hooks, FTS5, version
190
+ context-compress uninstall # Clean removal: hooks, MCP reg, stale DBs
191
+ ```
192
+
193
+ ### Doctor Output Example
194
+
195
+ ```
196
+ context-compress doctor
197
+
198
+ [PASS] Performance: FAST — Bun detected
199
+ [PASS] Language coverage: 7/11 (64%)
200
+ [PASS] Server test: OK
201
+ [PASS] PreToolUse hook configured
202
+ [PASS] FTS5 / better-sqlite3 works
203
+
204
+ Version: v1.0.0
205
+ All checks passed.
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Project Structure
211
+
212
+ ```
213
+ context-compress/
214
+ ├── src/
215
+ │ ├── index.ts # Entry point
216
+ │ ├── server.ts # MCP server (7 tools)
217
+ │ ├── executor.ts # SubprocessExecutor
218
+ │ ├── store.ts # ContentStore (FTS5)
219
+ │ ├── config.ts # Config system
220
+ │ ├── logger.ts # Debug logger
221
+ │ ├── snippet.ts # FTS5 snippet extraction
222
+ │ ├── stats.ts # Session tracker
223
+ │ ├── types.ts # Shared types
224
+ │ ├── runtime/
225
+ │ │ ├── plugin.ts # LanguagePlugin interface
226
+ │ │ ├── index.ts # Registry + parallel detection
227
+ │ │ └── languages/ # 11 language plugins
228
+ │ ├── hooks/
229
+ │ │ └── pretooluse.ts # PreToolUse hook (no self-mod)
230
+ │ └── cli/
231
+ │ ├── index.ts # CLI entry
232
+ │ ├── setup.ts # Interactive setup
233
+ │ ├── doctor.ts # Diagnostics
234
+ │ └── uninstall.ts # Clean removal
235
+ ├── tests/
236
+ │ ├── unit/ # 7 unit test files
237
+ │ └── integration/ # 3 integration test files
238
+ ├── hooks/
239
+ │ └── hooks.json # Hook matcher config
240
+ ├── skills/ # Slash command definitions
241
+ └── dist/ # Compiled output
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Security
247
+
248
+ | Threat | Mitigation |
249
+ |:-------|:-----------|
250
+ | Credential leakage | `passthroughEnvVars` defaults to `[]` — zero env vars passed unless opted in |
251
+ | Shell injection (Rust) | `execFileSync` with array arguments — no string interpolation |
252
+ | Hook self-modification | No `fs.writeFileSync` in hooks — zero filesystem side effects |
253
+ | Arbitrary code execution | No `upgrade` command — no `git clone` or `npm install` at runtime |
254
+ | Silent failures | Debug mode surfaces all catch block errors to stderr |
255
+
256
+ ---
257
+
258
+ ## Contributing
259
+
260
+ ```bash
261
+ git clone https://github.com/Open330/context-compress
262
+ cd context-compress
263
+ npm install
264
+ npm run typecheck # Type checking
265
+ npm run lint # Biome linting
266
+ npm run test:unit # 36 unit tests
267
+ npm run test # All tests (unit + integration)
268
+ npm run build # Compile + bundle
269
+ ```
270
+
271
+ ---
272
+
273
+ ## License
274
+
275
+ [MIT](LICENSE) — Based on [context-mode](https://github.com/mksglu/claude-context-mode) by Mert Koseoğlu.
@@ -0,0 +1,2 @@
1
+ export declare function doctor(): Promise<number>;
2
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AA6BA,wBAAsB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CA4G9C"}
@@ -0,0 +1,131 @@
1
+ import { constants, accessSync, readFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { dirname, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import Database from "better-sqlite3";
6
+ import { loadConfig } from "../config.js";
7
+ import { SubprocessExecutor } from "../executor.js";
8
+ import { detectRuntimes, getRuntimeSummary, hasBun } from "../runtime/index.js";
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ function getVersion() {
11
+ try {
12
+ const pkg = JSON.parse(readFileSync(resolve(__dirname, "..", "..", "package.json"), "utf-8"));
13
+ return pkg.version ?? "unknown";
14
+ }
15
+ catch {
16
+ return "unknown";
17
+ }
18
+ }
19
+ function readSettings() {
20
+ try {
21
+ const path = resolve(homedir(), ".claude", "settings.json");
22
+ return JSON.parse(readFileSync(path, "utf-8"));
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ export async function doctor() {
29
+ console.log("\n context-compress doctor\n");
30
+ let criticalFails = 0;
31
+ // 1. Runtimes
32
+ console.log(" Detecting runtimes...");
33
+ const runtimes = await detectRuntimes();
34
+ console.log(getRuntimeSummary(runtimes));
35
+ console.log();
36
+ if (hasBun(runtimes)) {
37
+ console.log(" [PASS] Performance: FAST — Bun detected");
38
+ }
39
+ else {
40
+ console.log(" [WARN] Performance: NORMAL — Using Node.js (install Bun for 3-5x speed)");
41
+ }
42
+ const pct = ((runtimes.size / 11) * 100).toFixed(0);
43
+ if (runtimes.size < 2) {
44
+ criticalFails++;
45
+ console.log(` [FAIL] Language coverage: ${runtimes.size}/11 (${pct}%)`);
46
+ }
47
+ else {
48
+ console.log(` [PASS] Language coverage: ${runtimes.size}/11 (${pct}%)`);
49
+ }
50
+ // 2. Server test
51
+ console.log("\n Testing server...");
52
+ try {
53
+ const config = loadConfig();
54
+ const executor = new SubprocessExecutor(runtimes, config);
55
+ const result = await executor.execute({
56
+ language: "javascript",
57
+ code: 'console.log("ok");',
58
+ timeout: 5000,
59
+ });
60
+ if (result.exitCode === 0 && result.stdout.trim() === "ok") {
61
+ console.log(" [PASS] Server test: OK");
62
+ }
63
+ else {
64
+ criticalFails++;
65
+ console.log(` [FAIL] Server test: exit ${result.exitCode}`);
66
+ }
67
+ }
68
+ catch (err) {
69
+ criticalFails++;
70
+ const msg = err instanceof Error ? err.message : String(err);
71
+ console.log(` [FAIL] Server test: ${msg}`);
72
+ }
73
+ // 3. Hooks
74
+ console.log("\n Checking hooks...");
75
+ const settings = readSettings();
76
+ if (settings) {
77
+ const hooks = settings.hooks;
78
+ const preToolUse = hooks?.PreToolUse;
79
+ if (preToolUse?.some((e) => e.hooks?.some((h) => h.command?.includes("pretooluse.mjs")))) {
80
+ console.log(" [PASS] PreToolUse hook configured");
81
+ }
82
+ else {
83
+ console.log(" [WARN] PreToolUse hook not found — run setup to configure");
84
+ }
85
+ }
86
+ else {
87
+ console.log(" [WARN] Could not read ~/.claude/settings.json");
88
+ }
89
+ // 4. Hook script
90
+ const hookPath = resolve(__dirname, "..", "..", "hooks", "pretooluse.mjs");
91
+ try {
92
+ accessSync(hookPath, constants.R_OK);
93
+ console.log(" [PASS] Hook script exists");
94
+ }
95
+ catch {
96
+ console.log(` [WARN] Hook script not found at ${hookPath}`);
97
+ }
98
+ // 5. FTS5 / better-sqlite3
99
+ console.log("\n Checking FTS5...");
100
+ try {
101
+ const db = new Database(":memory:");
102
+ db.exec("CREATE VIRTUAL TABLE fts_test USING fts5(content)");
103
+ db.exec("INSERT INTO fts_test(content) VALUES ('hello world')");
104
+ const row = db.prepare("SELECT * FROM fts_test WHERE fts_test MATCH 'hello'").get();
105
+ db.close();
106
+ if (row?.content === "hello world") {
107
+ console.log(" [PASS] FTS5 / better-sqlite3 works");
108
+ }
109
+ else {
110
+ criticalFails++;
111
+ console.log(" [FAIL] FTS5 returned unexpected result");
112
+ }
113
+ }
114
+ catch (err) {
115
+ criticalFails++;
116
+ const msg = err instanceof Error ? err.message : String(err);
117
+ console.log(` [FAIL] FTS5: ${msg}`);
118
+ }
119
+ // 6. Version
120
+ const version = getVersion();
121
+ console.log(`\n Version: v${version}`);
122
+ // Summary
123
+ console.log();
124
+ if (criticalFails > 0) {
125
+ console.log(` ${criticalFails} critical issue(s) found.\n`);
126
+ return 1;
127
+ }
128
+ console.log(" All checks passed.\n");
129
+ return 0;
130
+ }
131
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * context-compress CLI
4
+ *
5
+ * Usage:
6
+ * context-compress → Start MCP server (stdio)
7
+ * context-compress setup → Interactive setup
8
+ * context-compress doctor → Diagnose issues
9
+ * context-compress uninstall → Clean removal
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG"}
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * context-compress CLI
4
+ *
5
+ * Usage:
6
+ * context-compress → Start MCP server (stdio)
7
+ * context-compress setup → Interactive setup
8
+ * context-compress doctor → Diagnose issues
9
+ * context-compress uninstall → Clean removal
10
+ */
11
+ const args = process.argv.slice(2);
12
+ const command = args[0];
13
+ if (command === "setup") {
14
+ const { setup } = await import("./setup.js");
15
+ await setup();
16
+ }
17
+ else if (command === "doctor") {
18
+ const { doctor } = await import("./doctor.js");
19
+ const code = await doctor();
20
+ process.exit(code);
21
+ }
22
+ else if (command === "uninstall") {
23
+ const { uninstall } = await import("./uninstall.js");
24
+ await uninstall();
25
+ }
26
+ else {
27
+ // Default: start MCP server
28
+ await import("../index.js");
29
+ }
30
+ export {};
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAExB,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;IACzB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IAC7C,MAAM,KAAK,EAAE,CAAC;AACf,CAAC;KAAM,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;IACjC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;KAAM,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;IACpC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACrD,MAAM,SAAS,EAAE,CAAC;AACnB,CAAC;KAAM,CAAC;IACP,4BAA4B;IAC5B,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function setup(): Promise<void>;
2
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAOA,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA+C3C"}
@@ -0,0 +1,43 @@
1
+ import { execSync } from "node:child_process";
2
+ import { dirname, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { detectRuntimes, getRuntimeSummary, hasBun } from "../runtime/index.js";
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ export async function setup() {
7
+ console.log("\n context-compress setup\n");
8
+ // Step 1: Detect runtimes
9
+ console.log(" Detecting runtimes...");
10
+ const runtimes = await detectRuntimes();
11
+ console.log(` Found ${runtimes.size} languages:\n`);
12
+ console.log(getRuntimeSummary(runtimes));
13
+ console.log();
14
+ // Step 2: Check Bun
15
+ if (hasBun(runtimes)) {
16
+ console.log(" Bun detected — JS/TS will run at maximum speed.\n");
17
+ }
18
+ else {
19
+ console.log(" Bun not found — JS/TS will use Node.js (install Bun for 3-5x speed).\n");
20
+ }
21
+ // Step 3: Missing optional runtimes
22
+ const all = ["python", "ruby", "go", "rust", "php", "perl", "r", "elixir"];
23
+ const missing = all.filter((lang) => !runtimes.has(lang));
24
+ if (missing.length > 0) {
25
+ console.log(` Optional runtimes not found: ${missing.join(", ")}`);
26
+ console.log(" Install them to enable additional language support.\n");
27
+ }
28
+ // Step 4: Show installation instructions
29
+ const serverPath = resolve(__dirname, "..", "index.js");
30
+ console.log(" To add to Claude Code, run:");
31
+ console.log(` claude mcp add context-compress -- node ${serverPath}\n`);
32
+ console.log(" Or add to .mcp.json:");
33
+ console.log(JSON.stringify({
34
+ mcpServers: {
35
+ "context-compress": {
36
+ command: "node",
37
+ args: [serverPath],
38
+ },
39
+ },
40
+ }, null, 4));
41
+ console.log("\n Setup complete!\n");
42
+ }
43
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAEhF,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,MAAM,CAAC,KAAK,UAAU,KAAK;IAC1B,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAE5C,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,WAAW,QAAQ,CAAC,IAAI,eAAe,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,oBAAoB;IACpB,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;IACzF,CAAC;IAED,oCAAoC;IACpC,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAU,CAAC;IACpF,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,kCAAkC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACxE,CAAC;IAED,yCAAyC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,+CAA+C,UAAU,IAAI,CAAC,CAAC;IAE3E,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CACV,IAAI,CAAC,SAAS,CACb;QACC,UAAU,EAAE;YACX,kBAAkB,EAAE;gBACnB,OAAO,EAAE,MAAM;gBACf,IAAI,EAAE,CAAC,UAAU,CAAC;aAClB;SACD;KACD,EACD,IAAI,EACJ,CAAC,CACD,CACD,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function uninstall(): Promise<void>;
2
+ //# sourceMappingURL=uninstall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../src/cli/uninstall.ts"],"names":[],"mappings":"AAKA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAkG/C"}
@@ -0,0 +1,102 @@
1
+ import { readFileSync, readdirSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { homedir } from "node:os";
4
+ import { join, resolve } from "node:path";
5
+ export async function uninstall() {
6
+ console.log("\n context-compress uninstall\n");
7
+ const changes = [];
8
+ // 1. Remove hooks from settings.json
9
+ console.log(" Removing hooks from settings.json...");
10
+ const settingsPath = resolve(homedir(), ".claude", "settings.json");
11
+ try {
12
+ const settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
13
+ const hooks = settings.hooks;
14
+ if (hooks?.PreToolUse && Array.isArray(hooks.PreToolUse)) {
15
+ const before = hooks.PreToolUse.length;
16
+ hooks.PreToolUse = hooks.PreToolUse.filter((entry) => {
17
+ const entryHooks = entry.hooks;
18
+ return !entryHooks?.some((h) => h.command?.includes("context-compress") || h.command?.includes("pretooluse.mjs"));
19
+ });
20
+ if (hooks.PreToolUse.length === 0) {
21
+ // biome-ignore lint/performance/noDelete: removing key from JSON object
22
+ delete hooks.PreToolUse;
23
+ }
24
+ if (hooks.PreToolUse === undefined || hooks.PreToolUse.length < before) {
25
+ settings.hooks = hooks;
26
+ writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
27
+ changes.push("Removed PreToolUse hooks from settings.json");
28
+ }
29
+ }
30
+ }
31
+ catch {
32
+ console.log(" Could not modify settings.json (may not exist)");
33
+ }
34
+ // 2. Remove MCP server registration
35
+ console.log(" Removing MCP server registration...");
36
+ try {
37
+ const mcpPath = resolve(homedir(), ".claude", "settings.json");
38
+ const settings = JSON.parse(readFileSync(mcpPath, "utf-8"));
39
+ const mcpServers = settings.mcpServers;
40
+ if (mcpServers && "context-compress" in mcpServers) {
41
+ mcpServers["context-compress"] = undefined;
42
+ writeFileSync(mcpPath, `${JSON.stringify(settings, null, 2)}\n`, "utf-8");
43
+ changes.push("Removed context-compress MCP server from settings");
44
+ }
45
+ }
46
+ catch {
47
+ // May not exist
48
+ }
49
+ // Also check project-level .mcp.json
50
+ try {
51
+ const cwd = process.cwd();
52
+ const mcpJson = resolve(cwd, ".mcp.json");
53
+ const mcp = JSON.parse(readFileSync(mcpJson, "utf-8"));
54
+ const servers = mcp.mcpServers;
55
+ if (servers && "context-compress" in servers) {
56
+ servers["context-compress"] = undefined;
57
+ writeFileSync(mcpJson, `${JSON.stringify(mcp, null, 2)}\n`, "utf-8");
58
+ changes.push("Removed context-compress from .mcp.json");
59
+ }
60
+ }
61
+ catch {
62
+ // May not exist
63
+ }
64
+ // 3. Clean stale databases
65
+ console.log(" Cleaning stale databases...");
66
+ const dir = tmpdir();
67
+ try {
68
+ const files = readdirSync(dir);
69
+ let cleaned = 0;
70
+ for (const file of files) {
71
+ if (file.startsWith("context-compress-") && file.endsWith(".db")) {
72
+ for (const suffix of ["", "-wal", "-shm"]) {
73
+ try {
74
+ unlinkSync(join(dir, file + suffix));
75
+ }
76
+ catch {
77
+ // Ignore
78
+ }
79
+ }
80
+ cleaned++;
81
+ }
82
+ }
83
+ if (cleaned > 0) {
84
+ changes.push(`Cleaned ${cleaned} database file(s)`);
85
+ }
86
+ }
87
+ catch {
88
+ // Ignore
89
+ }
90
+ // Summary
91
+ console.log();
92
+ if (changes.length > 0) {
93
+ for (const change of changes) {
94
+ console.log(` + ${change}`);
95
+ }
96
+ }
97
+ else {
98
+ console.log(" Nothing to clean up.");
99
+ }
100
+ console.log("\n Uninstall complete. Restart Claude Code to apply changes.\n");
101
+ }
102
+ //# sourceMappingURL=uninstall.js.map