Skip to content

Releases: Open330/context-compress

v2026.7.1 — hook/MCP spec alignment, toolchain refresh

Choose a tag to compare

@jiunbae jiunbae released this 28 Jul 23:36
v2026.7.1
5144662

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 reads permissionDecisionReason. Agents saw a bare denial with no redirect to fetch_and_index. Now uses the correct field, with a regression test asserting the legacy decision/reason pair is never emitted.
  • Duplicate PreToolUse hook registrationhooks/hooks.json (the path plugin hosts auto-discover by convention) sat alongside the explicitly declared hooks/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 return permissionDecision: "deny" with the redirect in the reason instead of rewriting the command into echo "..." — 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 to registerTool() — each now advertises a title and full ToolAnnotations (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 / discover are read-only and closed-world.
  • No outputSchema on any tool, by design — an output schema obliges the server to send structuredContent plus a serialized text duplicate, billing the same payload to the context window twice. tests/integration/tool-manifest.test.ts locks 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 the McpServer instance and shutdown alongside start(), 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/checkout and actions/setup-node bumped 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/node 20 → 24. npm audit now 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 in filterBuildOutput, and three stale biome-ignore comments for a rule that no longer exists.

Packaging

  • Hook bundle and its SHA-256 are now emitted by the same build step. npm run build regenerated hooks/pretooluse.mjs but left hooks/pretooluse.sha256 untouched, and prepublishOnly runs build — so a publish could ship a fresh bundle beside a stale checksum and make doctor report a bogus integrity failure to every user. esbuild.config.mjs now writes both, and build:hooks delegates to it via --hooks-only instead 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)

Choose a tag to compare

@jiunbae jiunbae released this 06 Jul 07:15
v2026.7.0
016b2b6

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 into template ×count via 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 the execute shell path (executor). Typical wins: JSON −41% (still valid) to −96%, logs −98%.

Intent-conditioned summaries

  • Query-ranked inliningapplyIntentFilter now 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-up search() round-trips. Error lines are surfaced as a safety net. New config field intentBudgetBytes (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, auto records 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 the stats self-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 at docs/quality-regression-report.md.

v2026.6.0

Choose a tag to compare

@jiunbae jiunbae released this 24 Jun 11:46
v2026.6.0
31c53f1

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

Choose a tag to compare

@jiunbae jiunbae released this 10 May 05:22
v2026.5.0
d3270b5

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 modesconservative (ANSI-only), balanced (default; strips noise, preserves metadata), aggressive (drops metadata for max compression). Pass --mode or set CONTEXT_COMPRESS_MODE.
  • auto mode — LLM picks the mode per command. Decisions cached at ~/.context-compress/auto-cache.json with 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.
  • --stream mode for wrap — line-by-line filtered output for tail -f, watch builds.
  • Single-binary lite CLInpm run build:bin cross-compiles via Bun for darwin-arm64/x64, linux-x64/arm64.

Setup

  • context-compress setup --auto (alias init --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-wrapCONTEXT_COMPRESS_FILTER_BASH=1 routes Bash calls through wrap automatically.
  • Mode forwarding — hook propagates CONTEXT_COMPRESS_MODE to wrapped commands.

MCP server

  • 8th tool: discover — lists indexed sources, top searchable terms, optimization suggestions.
  • isError: true on all error responses (MCP protocol compliance).
  • server.ts modularized: 845 lines → 132. Tool handlers extracted to src/tools/*.ts, utilities to src/util/*.ts.

Security & performance

  • IPv6 hex-mapped SSRF gap closed — blocks ::ffff:7f00:1, ::ffff:c0a8:101, etc.
  • getDistinctiveTerms cached per source — was scanning up to 500 chunks per call.
  • buildFetchCode IPv6 fix — properly brackets IPv6 hostnames for URL.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 scriptsbenchmark.ts (synthetic), benchmark-real.ts (this repo), benchmark-vs-rtk.ts (head-to-head with --auto and --json).

Install / upgrade

npm install -g context-compress@2026.5.0
context-compress setup --auto

Reproducing 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 --auto

Full changelog

See CHANGELOG.md.