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.
- package/LICENSE +21 -0
- package/README.md +275 -0
- package/dist/cli/doctor.d.ts +2 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +131 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +31 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/setup.d.ts +2 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +43 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli/uninstall.d.ts +2 -0
- package/dist/cli/uninstall.d.ts.map +1 -0
- package/dist/cli/uninstall.js +102 -0
- package/dist/cli/uninstall.js.map +1 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +79 -0
- package/dist/config.js.map +1 -0
- package/dist/executor.d.ts +21 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +301 -0
- package/dist/executor.js.map +1 -0
- package/dist/hooks/pretooluse.d.ts +10 -0
- package/dist/hooks/pretooluse.d.ts.map +1 -0
- package/dist/hooks/pretooluse.js +117 -0
- package/dist/hooks/pretooluse.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +13 -0
- package/dist/logger.js.map +1 -0
- package/dist/runtime/index.d.ts +22 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +81 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/languages/elixir.d.ts +3 -0
- package/dist/runtime/languages/elixir.d.ts.map +1 -0
- package/dist/runtime/languages/elixir.js +15 -0
- package/dist/runtime/languages/elixir.js.map +1 -0
- package/dist/runtime/languages/go.d.ts +3 -0
- package/dist/runtime/languages/go.d.ts.map +1 -0
- package/dist/runtime/languages/go.js +29 -0
- package/dist/runtime/languages/go.js.map +1 -0
- package/dist/runtime/languages/javascript.d.ts +3 -0
- package/dist/runtime/languages/javascript.d.ts.map +1 -0
- package/dist/runtime/languages/javascript.js +13 -0
- package/dist/runtime/languages/javascript.js.map +1 -0
- package/dist/runtime/languages/perl.d.ts +3 -0
- package/dist/runtime/languages/perl.d.ts.map +1 -0
- package/dist/runtime/languages/perl.js +13 -0
- package/dist/runtime/languages/perl.js.map +1 -0
- package/dist/runtime/languages/php.d.ts +3 -0
- package/dist/runtime/languages/php.d.ts.map +1 -0
- package/dist/runtime/languages/php.js +24 -0
- package/dist/runtime/languages/php.js.map +1 -0
- package/dist/runtime/languages/python.d.ts +3 -0
- package/dist/runtime/languages/python.d.ts.map +1 -0
- package/dist/runtime/languages/python.js +13 -0
- package/dist/runtime/languages/python.js.map +1 -0
- package/dist/runtime/languages/r.d.ts +3 -0
- package/dist/runtime/languages/r.d.ts.map +1 -0
- package/dist/runtime/languages/r.js +13 -0
- package/dist/runtime/languages/r.js.map +1 -0
- package/dist/runtime/languages/ruby.d.ts +3 -0
- package/dist/runtime/languages/ruby.d.ts.map +1 -0
- package/dist/runtime/languages/ruby.js +13 -0
- package/dist/runtime/languages/ruby.js.map +1 -0
- package/dist/runtime/languages/rust.d.ts +3 -0
- package/dist/runtime/languages/rust.d.ts.map +1 -0
- package/dist/runtime/languages/rust.js +28 -0
- package/dist/runtime/languages/rust.js.map +1 -0
- package/dist/runtime/languages/shell.d.ts +3 -0
- package/dist/runtime/languages/shell.d.ts.map +1 -0
- package/dist/runtime/languages/shell.js +14 -0
- package/dist/runtime/languages/shell.js.map +1 -0
- package/dist/runtime/languages/typescript.d.ts +3 -0
- package/dist/runtime/languages/typescript.d.ts.map +1 -0
- package/dist/runtime/languages/typescript.js +15 -0
- package/dist/runtime/languages/typescript.js.map +1 -0
- package/dist/runtime/plugin.d.ts +38 -0
- package/dist/runtime/plugin.d.ts.map +1 -0
- package/dist/runtime/plugin.js +2 -0
- package/dist/runtime/plugin.js.map +1 -0
- package/dist/server.bundle.mjs +22769 -0
- package/dist/server.bundle.mjs.map +7 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +405 -0
- package/dist/server.js.map +1 -0
- package/dist/snippet.d.ts +15 -0
- package/dist/snippet.d.ts.map +1 -0
- package/dist/snippet.js +92 -0
- package/dist/snippet.js.map +1 -0
- package/dist/stats.d.ts +10 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +65 -0
- package/dist/stats.js.map +1 -0
- package/dist/store.d.ts +44 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +590 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +75 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/hooks/hooks.json +52 -0
- package/hooks/pretooluse.mjs +94 -0
- package/package.json +55 -0
- package/skills/context-compress/SKILL.md +118 -0
- package/skills/doctor/SKILL.md +15 -0
- 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
|
+
[](https://github.com/Open330/context-compress/actions)
|
|
8
|
+
[](https://nodejs.org)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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
|