Releases: Open330/context-compress
Release list
v2026.7.1 — hook/MCP spec alignment, toolchain refresh
Modernization pass: align the hook and MCP surfaces with the current specs, and refresh the toolchain baseline.
Upgrade note: the minimum runtime is now Node 22. Node 18 (EOL April 2025) and Node 20 (EOL April 2026) are both past end-of-life, and better-sqlite3 13 declares
engines: {node: ">=22"}— on Node 20 it segfaults rather than failing cleanly. Stay on 2026.7.0 if you cannot move off Node 20.
Fixed
- PreToolUse deny reasons were silently dropped — the WebFetch block emitted
hookSpecificOutput.reason, but Claude Code readspermissionDecisionReason. Agents saw a bare denial with no redirect tofetch_and_index. Now uses the correct field, with a regression test asserting the legacydecision/reasonpair is never emitted. - Duplicate PreToolUse hook registration —
hooks/hooks.json(the path plugin hosts auto-discover by convention) sat alongside the explicitly declaredhooks/claude-codex-hooks.json, so a plugin install could spawn the hook twice per tool call and emit two conflicting decisions. The orphaned file is removed and a test keeps it gone. curl/wget/ inline-HTTP blocks now returnpermissionDecision: "deny"with the redirect in the reason instead of rewriting the command intoecho "..."— the agent gets the alternative immediately instead of paying for a shell round-trip.
Changed
- All 8 MCP tools migrated from the deprecated
server.tool()overloads toregisterTool()— each now advertises atitleand fullToolAnnotations(readOnlyHint/destructiveHint/idempotentHint/openWorldHint). Code-executing tools (execute,execute_file,batch_execute) are pessimistically annotated as non-read-only, destructive, and open-world;search/stats/discoverare read-only and closed-world. - No
outputSchemaon any tool, by design — an output schema obliges the server to sendstructuredContentplus a serialized text duplicate, billing the same payload to the context window twice.tests/integration/tool-manifest.test.tslocks in both the annotation contract and the text-only response shape by driving the real server over an in-memory MCP transport. createServer()now returns theMcpServerinstance andshutdownalongsidestart(), so the server can be exercised over a test transport.- Node baseline raised to >= 22. Node 18 and Node 20 are both end-of-life, and better-sqlite3 13 requires Node 22+; CI caught the mismatch as a SIGSEGV across every SQLite-touching test on the Node 20 leg. CI matrix is now 22/24; esbuild targets
node22;actions/checkoutandactions/setup-nodebumped to v5. - Dependencies refreshed — MCP SDK 1.27 → 1.30, better-sqlite3 12 → 13, Biome 1.9 → 2.5 (config migrated), TypeScript 5.7 → 5.9, esbuild 0.27 → 0.28,
@types/node20 → 24.npm auditnow reports 0 vulnerabilities (the fixed advisories were all in the SDK's unused HTTP-transport dependency tree). - Dead code removed that Biome 2 newly surfaced: unused imports in
executor.ts/uninstall.ts, an unused parameter infilterBuildOutput, and three stalebiome-ignorecomments for a rule that no longer exists.
Packaging
- Hook bundle and its SHA-256 are now emitted by the same build step.
npm run buildregeneratedhooks/pretooluse.mjsbut lefthooks/pretooluse.sha256untouched, andprepublishOnlyrunsbuild— so a publish could ship a fresh bundle beside a stale checksum and makedoctorreport a bogus integrity failure to every user.esbuild.config.mjsnow writes both, andbuild:hooksdelegates to it via--hooks-onlyinstead of duplicating the bundling command.
npm: npm install -g context-compress@2026.7.1
v2026.7.0 — Smarter compression (format-aware, intent-conditioned, self-tuning)
Smarter compression release — grounded in the 2026 agent-compression literature, whose core finding is that token-level extractive compression breaks agents by destroying action grammar. Every addition here operates on whole structural units, never partial tokens.
Format-aware compression
- New
src/format-filter.ts— when no command-specific filter matches, output is compressed by its shape: JSON is minified losslessly (balanced) or collapsed to a schema + sample (aggressive), NDJSON folds into per-shape summaries, and repetitive logs fold intotemplate ×countvia variable masking (Drain-style). Error/warning lines are always preserved verbatim and balanced-mode JSON stays parseable. Wired into both the Bash-hook path (compressOutput) and theexecuteshell path (executor). Typical wins: JSON −41% (still valid) to −96%, logs −98%.
Intent-conditioned summaries
- Query-ranked inlining —
applyIntentFilternow inlines the top query-ranked sections up to a byte budget (CONTEXT_COMPRESS_INTENT_BUDGET_BYTES, default 1800) instead of only listing section titles, cutting follow-upsearch()round-trips. Error lines are surfaced as a safety net. New config fieldintentBudgetBytes(per-level defaults).
Self-tuning auto mode (ACON-style)
- Compression-regret loop (
src/util/regret.ts) — when a command is compressed aggressively and then re-run fast (≤30s) repeatedly,autorecords the regret and downgrades that command one step to preserve fidelity, with hysteresis so it doesn't oscillate. Downgrades only ever reduce compression, so a false positive costs tokens, never correctness. Surfaced in thestatsself-tuning table.
Quality-regression benchmark
- New
src/bench/+npm run bench:quality— measures survival of task-critical information, not just token ratio, and a unit test fails if survival regresses below the per-case floor. Report atdocs/quality-regression-report.md.
v2026.6.0
Summary
- Add Codex and Claude plugin manifests with local MCP config and Claude hook metadata.
- Add context-compress-audit skill for raw-output waste audits.
- Add an agentic benchmark plan for isolated context-compress on/off comparisons.
- Refresh README positioning and package distribution tests.
Verification
- Published npm package: context-compress@2026.6.0
- CI passed on main for Node 20 and Node 22.
- Local prepublish gate passed: lint, 220 tests, build.
v2026.5.0 — 4 compression modes, auto mode, RTK-beating compression
Major feature release. Headline numbers on this repo, head-to-head with RTK 0.39.0:
| RTK | conservative | balanced | aggressive | auto | |
|---|---|---|---|---|---|
| Token reduction | 82.5% | 6.0% | 75.4% | 93.0% | 77.9% |
Aggressive beats RTK by 10.5pp on the same commands. auto mode lets an LLM pick contextually appropriate compression per output (Anthropic API → claude -p fallback → heuristic).
What's new
Compression
- Three explicit modes —
conservative(ANSI-only),balanced(default; strips noise, preserves metadata),aggressive(drops metadata for max compression). Pass--modeor setCONTEXT_COMPRESS_MODE. automode — LLM picks the mode per command. Decisions cached at~/.context-compress/auto-cache.jsonwith 24h TTL.- Aggressive command filters for
git log/diff/status,ls -la*,find,grep/rg,npm ls,df,du,ps aux. - Balanced now compresses meaningfully — was 0% on
git log/ls/find. Now 75% byte-weighted on this repo without dropping any metadata.
Standalone CLI (RTK-compatible)
context-compress wrap "<cmd>"— runs a shell command and pipes stdout through the pipeline.context-compress filter [--cmd '<orig>']— stdin → compressed → stdout.--streammode forwrap— line-by-line filtered output fortail -f, watch builds.- Single-binary lite CLI —
npm run build:bincross-compiles via Bun for darwin-arm64/x64, linux-x64/arm64.
Setup
context-compress setup --auto(aliasinit --auto) — one-line install: writes~/.claude/settings.json, registers MCP server, installs PreToolUse hook, enables transparent Bash compression. Idempotent. Preserves unrelated user settings.- PreToolUse hook auto-wrap —
CONTEXT_COMPRESS_FILTER_BASH=1routesBashcalls throughwrapautomatically. - Mode forwarding — hook propagates
CONTEXT_COMPRESS_MODEto wrapped commands.
MCP server
- 8th tool:
discover— lists indexed sources, top searchable terms, optimization suggestions. isError: trueon all error responses (MCP protocol compliance).server.tsmodularized: 845 lines → 132. Tool handlers extracted tosrc/tools/*.ts, utilities tosrc/util/*.ts.
Security & performance
- IPv6 hex-mapped SSRF gap closed — blocks
::ffff:7f00:1,::ffff:c0a8:101, etc. getDistinctiveTermscached per source — was scanning up to 500 chunks per call.buildFetchCodeIPv6 fix — properly brackets IPv6 hostnames forURL.hostname.- ANSI stripping order fix — was hiding
PASS/FAIL/✓/✗markers from command filters when output had color codes.
CI / DX
- CI restored — Node 20 + 22 matrix; typecheck + lint + tests + build.
- Tests: 119 → 213 (+94). 18 unit test files + 3 integration.
- README modernized — featured-numbers hero, RTK comparison table, updated project structure.
- Three benchmark scripts —
benchmark.ts(synthetic),benchmark-real.ts(this repo),benchmark-vs-rtk.ts(head-to-head with--autoand--json).
Install / upgrade
npm install -g context-compress@2026.5.0
context-compress setup --autoReproducing the benchmark
git clone https://github.com/rtk-ai/rtk /tmp/rtk
(cd /tmp/rtk && cargo build --release)
RTK_BIN=/tmp/rtk/target/release/rtk tsx scripts/benchmark-vs-rtk.ts --autoFull changelog
See CHANGELOG.md.