{"id":51413211,"url":"https://github.com/anvanster/compressor","last_synced_at":"2026-07-04T16:30:46.645Z","repository":{"id":363984209,"uuid":"1265831883","full_name":"anvanster/compressor","owner":"anvanster","description":"Reduce token usage in AI coding agents (Claude Code, Copilot, Cursor) with mode-switchable instruction packs and tool-output compression hooks — with a benchmark harness that measures the savings. Every optimization is measured or it doesn't ship.","archived":false,"fork":false,"pushed_at":"2026-06-11T06:37:07.000Z","size":322,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T08:12:01.024Z","etag":null,"topics":["agents-md","ai-coding-agents","anthropic","claude-code","cli","context-compression","cursor","developer-tools","github-copilot","llm","prompt-compression","token-optimization"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anvanster.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-11T05:45:56.000Z","updated_at":"2026-06-11T06:37:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/anvanster/compressor","commit_stats":null,"previous_names":["anvanster/compressor"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/anvanster/compressor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anvanster%2Fcompressor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anvanster%2Fcompressor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anvanster%2Fcompressor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anvanster%2Fcompressor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anvanster","download_url":"https://codeload.github.com/anvanster/compressor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anvanster%2Fcompressor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35129187,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents-md","ai-coding-agents","anthropic","claude-code","cli","context-compression","cursor","developer-tools","github-copilot","llm","prompt-compression","token-optimization"],"created_at":"2026-07-04T16:30:46.587Z","updated_at":"2026-07-04T16:30:46.640Z","avatar_url":"https://github.com/anvanster.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# compressor\n\nToken optimization for AI coding agents. Two parts you install: **mode-switchable instruction packs** (full / optimized / slim) for Claude Code, GitHub Copilot, Cursor, OpenCode, and AGENTS.md-reading agents, and **tool-output compression hooks** that shrink file reads and command output before they enter the model's context. Every optimization is benchmarked against real agent sessions before it ships — current measured numbers, methodology, and the project's mistakes live in [docs/BENCHMARKING.md](docs/BENCHMARKING.md).\n\n## Install\n\nRequires Node **\u003e= 20**.\n\nOne-line install from GitHub (builds from source, puts `compressor` on your PATH):\n\n```sh\n# macOS / Linux / WSL\ncurl -fsSL https://raw.githubusercontent.com/anvanster/compressor/main/install.sh | bash\n```\n\n```powershell\n# Windows (PowerShell)\nirm https://raw.githubusercontent.com/anvanster/compressor/main/install.ps1 | iex\n```\n\nPin a tag/branch/commit with `COMPRESSOR_REF` (env var `$env:COMPRESSOR_REF` on Windows), e.g. `COMPRESSOR_REF=v0.3.0`.\n\nInstall the CLI globally (recommended — also enables relocatable hook commands):\n\n```sh\nnpm install -g @astudioplus/compressor\n```\n\nOr install from source:\n\n```sh\ngit clone https://github.com/anvanster/compressor.git\ncd compressor\nnpm install\nnpm run build      # compiles the CLI and bundles the hook entries\nnpm link           # optional: puts `compressor` on your PATH\n```\n\nWithout `npm link`, substitute `node /path/to/compressor/dist/cli/index.js` for `compressor` below. Note that source-checkout installs embed the absolute path of the clone in hook commands — don't move the directory after running `init` (re-run `init` if you do).\n\n## Quickstart\n\n### Claude Code\n\n```sh\ncd your-project\ncompressor init                      # claude-code, mode optimized, project scope\ncompressor status\ncompressor set-mode slim             # switch modes\ncompressor set-mode full             # removes everything — a true baseline\n```\n\n`init`, `set-mode`, and `uninstall` modify your agent config files, so they\nfirst show the diff, warn you, and back up every changed file before writing\n(in a terminal they also prompt to confirm). Preview without writing using\n`--dry-run`; skip the prompt with `--yes`; turn off the backup with\n`--no-backup`. Undo the last change with `compressor restore` (or\n`compressor restore --list` to pick one).\n\nWhat `init` installs at project scope:\n\n- `.claude/output-styles/compressor-\u003cmode\u003e.md` — the instruction pack as an output style (system prompt, cache-friendly)\n- `.claude/settings.json` — `outputStyle` set to `compressor-\u003cmode\u003e` (a pre-existing foreign `outputStyle` is stashed and restored on uninstall)\n- `.claude/settings.local.json` — the PostToolUse hook entry (matcher `Read|Bash|Grep|Glob`). It carries a machine-specific absolute path, so it goes in the conventionally gitignored local file, never the shared `settings.json`\n\nWith `--global` everything goes to `~/.claude/` instead, hook included in `~/.claude/settings.json`. Changes take effect on the next session (`/clear` or a new session).\n\n### GitHub Copilot\n\n```sh\ncompressor init --agent copilot              # project: instructions + hook\ncompressor init --agent copilot --global     # machine-wide hook only (Copilot CLI)\n```\n\nProject scope installs a marked section in `.github/copilot-instructions.md` plus a `postToolUse` hook config at `.github/hooks/compressor.json`. Global scope installs the hook to `~/.copilot/hooks/compressor.json` (`$COPILOT_HOME` honored) — instructions have no user-global mechanism in Copilot, so global is hook-only.\n\nThe honest caveat (also shown by `compressor status`): with an absolute-path install, **compression is effective in Copilot CLI on this machine only** — the cloud agent and teammates who pull a committed `.github/hooks/compressor.json` get a fail-open no-op, and the VS Code IDE surface does not execute hook files at all (instructions still apply there). With a global npm install, `init` writes relocatable commands (`compressor-copilot-hook --mode \u003cm\u003e`) that work on any machine where the package is on PATH. Copilot `postToolUse` is fail-open by platform design, so a dead command never blocks the agent.\n\n### Cursor\n\n```sh\ncompressor init --agent cursor\n```\n\nInstalls `.cursor/rules/compressor.mdc` (`alwaysApply: true`). A legacy `.cursorrules` file gets a marked section only if it already exists — it is never created. **Instructions only**: Cursor's hooks can replace MCP tool output but not built-in Read/Shell output, so the compression half of compressor does not apply.\n\n### AGENTS.md\n\n```sh\ncompressor init --agent agents-md\n```\n\nUpserts a marked section in `AGENTS.md`, read natively by Cursor, Copilot, Codex, Windsurf, OpenCode and others. Claude Code does **not** read AGENTS.md (use the claude-code adapter). Instructions only — no hook mechanism exists through this file.\n\n### OpenCode\n\n```sh\ncompressor init --agent opencode            # project: .opencode/plugins/compressor.js\ncompressor init --agent opencode --global   # machine-wide: ~/.config/opencode/plugins/\ncompressor init --agent agents-md           # instructions (OpenCode reads AGENTS.md natively)\n```\n\nInstalls an in-process compression plugin: OpenCode's `tool.execute.after` hook mutates tool output directly (no subprocess — the cheapest hot path of any integration). Plugins load at startup; restart any running opencode session. Instructions come via the agents-md adapter.\n\nMultiple agents in one go: `compressor init --agent claude-code copilot agents-md opencode`.\n\n### Support matrix\n\n| Agent | Instruction pack | Compression hook | Global scope |\n|---|---|---|---|\n| claude-code | yes (output style) | yes (PostToolUse) [^1] | yes (style + hook) |\n| copilot | yes (project only) | yes — Copilot CLI [^2] | hook only [^3] |\n| cursor | yes (`.mdc` rules) | no [^4] | no (per-project standard) |\n| agents-md | yes (marked section) | no | no (per-project standard) |\n| opencode | via agents-md (OpenCode reads `AGENTS.md` natively) | yes — in-process plugin [^5] | yes (`~/.config/opencode/plugins`) |\n\n[^1]: At project scope the hook entry lives in `.claude/settings.local.json` because it embeds a machine-specific absolute path (npm installs with the bins on PATH get relocatable `compressor-hook` commands instead).\n[^2]: Absolute-path installs work on this machine only; relocatable installs (global npm) work wherever the package is on PATH. The VS Code IDE runs no hook files.\n[^3]: `~/.copilot/hooks/compressor.json`, loaded by Copilot CLI only; Copilot has no user-global instructions mechanism.\n[^4]: Cursor `postToolUse` can replace MCP tool output only; built-in Read/Shell output cannot be rewritten.\n[^5]: OpenCode plugins run in-process (`tool.execute.after` mutates the tool output string directly) — no subprocess on the hot path. The plugin file format is doc-verified against opencode.ai and the sst/opencode source; not yet live-verified against a running OpenCode install, and `status` says so.\n\n## Modes\n\n| Mode | Instructions | Tool-output compression |\n|---|---|---|\n| `full` | none — `set-mode full` **removes** every compressor artifact and the hook, giving a true baseline rather than \"empty instructions present\" | none (passthrough) |\n| `optimized` | answer-first output discipline plus context discipline (targeted reads, no re-reads, no tool-output echo) — 11 atoms | tier 1 structural (ANSI strip, blank-run collapse, repeated-line dedupe, recoverable truncation at ~5,000 est. tokens) + comment-strip above ~2,000 est. tokens; output below ~600 est. tokens is never touched |\n| `slim` | optimized plus code-first responses under a hard ~10% explanation budget — 12 atoms | tiers 1–2 (skeleton view above ~6,000 est. tokens) plus log-aware filtering (test failures + summary, build errors) above ~800 est. tokens; touch floor ~300 |\n\nEvery omission is marked, sized, and recoverable — truncation markers state the exact `Read offset/limit` to retrieve the omitted lines, line numbers are never renumbered, and targeted reads (explicit offset/limit) pass through untouched. The hook is fail-open: any error means the original output passes through unchanged.\n\n## What the savings look like\n\n**A repetitive command output, compressed by the hook before the model sees it.** A 402-line build log becomes 4 lines; the marker tells the model what was collapsed:\n\n```text\n[INFO] building module graph... ok\n[compressor: previous line repeated 399 more times]\nFAIL: type error in engine.ts\nError: exit 1\n```\n\n**A large file read, truncated recoverably.** A 916-line file keeps its head and tail; the omitted middle is one marker line carrying the exact retrieval instruction, and original line numbers are preserved so edits and navigation still work:\n\n```text\n   354→  max: 100,\n[compressor: lines 355-916 omitted (~4749 est tokens) — Read src/telemetry.mjs with offset=355 and limit=562 to retrieve]\n   356→  let mask = 0;\n```\n\n**Your accumulated savings, from the live ledger.** Every worthwhile compression in a real session (at least 200 chars and 10% saved) appends one privacy-safe event — sizes and transform ids only, never paths or content:\n\n```text\n$ compressor savings --by tool\nsaved 127,041 chars (exact) ≈ 36,300 tokens (estimated — cheap estimator, not billable counts) · last 30 days\nevents: 8 (last 30 days)\n\nby tool:\n  bash  ████████████████████████████████████████  ≈ 35,162 tok\n  read  █                                         ≈ 1,138 tok\n```\n\n`compressor savings --html report.html` writes a self-contained report (inline SVG, no JS, no network). Kill switch: `COMPRESSOR_NO_LEDGER=1`.\n\nBenchmarked effect sizes (real agent sessions, success-checked): the hook cut context volume **−16%** on log-heavy work, and the instruction packs cut conversational output **−10% to −79%** depending on conversation type, with zero measured quality loss. Effects are domain-specific — full numbers, distributions, run ids, and caveats in [docs/BENCHMARKING.md](docs/BENCHMARKING.md).\n\n## CLI reference\n\n| Command | What it does | Key flags (defaults) |\n|---|---|---|\n| `init` | install the instruction pack + hook for the given agents | `--agent \u003cname...\u003e` (`claude-code`), `--mode optimized\\|slim` (`optimized`), `--global`, `--dry-run`, `--hook-command auto\\|absolute\\|relocatable` (`auto`: PATH-based `compressor-hook` commands when npm-installed with the bins on PATH; absolute dev-build paths in source checkouts) |\n| `set-mode \u003cfull\\|optimized\\|slim\u003e` | switch mode; `full` removes all compressor artifacts (true baseline) | `--agent \u003cname...\u003e` (`claude-code`), `--global`, `--dry-run`, `--hook-command` (as `init`) |\n| `status` | show installation state per agent — derived from files and markers, no state file to drift | `--global` |\n| `uninstall` | remove all compressor-owned artifacts | `--agent \u003cname...\u003e` (`claude-code`), `--global`, `--dry-run` |\n| `compress` | compress stdin to stdout via the engine; stats on stderr | `--mode` (`optimized`), `--kind read\\|bash\\|search\\|other` (`other`), `--file-path \u003cpath\u003e`, `--marker-style plain\\|deterrent\\|informative` |\n| `count \u003cfile...\u003e` | token counts per file — estimated by default | `--exact` (Anthropic `count_tokens`, needs `ANTHROPIC_API_KEY`), `--model` (`claude-sonnet-4-6`) |\n| `stats` | aggregate actual token usage from Claude Code transcripts | `--project \u003cpath\u003e` (cwd), `--since` (`30d`) |\n| `savings` | show what the compression hook saved (live ledger, estimated tokens) | `--since` (`30d`, or `all`), `--by day\\|tool\\|mode` (`day`), `--html \u003cpath\u003e`, `--ledger-dir \u003cdir\u003e` |\n| `hook post-tool-use` | Claude Code PostToolUse protocol entry: payload on stdin, updated output on stdout | `--mode` (`optimized`), `--marker-style`, `--recovery-budget \u003cn\\|off\u003e` (overrides `COMPRESSOR_RECOVERY_BUDGET`/`COMPRESSOR_NO_RECOVERY_BUDGET`) |\n| `hook copilot-post-tool-use` | Copilot postToolUse protocol entry: payload on stdin, `modifiedResult` JSON on stdout | `--mode` (`optimized`), `--marker-style`, `--recovery-budget \u003cn\\|off\u003e` |\n\nInstalled hooks run as the dedicated bins `compressor-hook` / `compressor-copilot-hook` (the bundled entries directly — no CLI startup on the hot path); the `compressor hook …` subcommands exist for protocol testing.\n\nThe benchmarking commands (`compressor benchmark`, `compressor report`) are a from-source feature for measuring compressor itself — documented in [docs/BENCHMARKING.md](docs/BENCHMARKING.md).\n\n## Seeing your savings\n\nThree views, deliberately not conflated:\n\n- **`compressor savings`** — the live ledger (see the example above). Token numbers here are estimates from a cheap chars/3.5 estimator and are labelled as such; chars are exact. The ledger is fail-open — a broken ledger never breaks your agent.\n- **`compressor stats`** — raw token usage aggregated from your local Claude Code transcripts (the authoritative usage fields). Currently shows usage totals, not a before/after comparison.\n- **Benchmarks** — the measured before/after numbers, from real headless agent sessions with success checks: [docs/BENCHMARKING.md](docs/BENCHMARKING.md).\n\n## Limitations\n\nStated plainly, because the alternative is users discovering them:\n\n- **Copilot compression runs in Copilot CLI (and conditionally the cloud agent), never the IDE.** Relocatable installs (global npm) work for teammates who install the package; the cloud agent additionally needs the config on the default branch and the package in its environment. The Copilot IDE surface runs no hook files at all.\n- **Cursor and AGENTS.md get instructions only.** No mechanism exists to rewrite built-in tool output there.\n- **Compression pays where output is redundant (logs, repeated lines) and can cost where it is dense (code).** The measured hook effect is −16% context on log-heavy work, ~0 on moderate output, and slightly negative on dense code files where the model re-reads truncated content — see [docs/BENCHMARKING.md](docs/BENCHMARKING.md). The recovery-read budget (first 3 targeted re-reads pass through, further ones are compressed; `COMPRESSOR_RECOVERY_BUDGET` tunes, `COMPRESSOR_NO_RECOVERY_BUDGET=1` disables) bounds the re-read cost; its behavioral effect is not yet benchmarked.\n- **The OpenCode plugin is doc-verified, not yet live-verified** against a running OpenCode install — `compressor status` says so until it is.\n\n## Further reading\n\n- **Benchmarks and measured results**: [docs/BENCHMARKING.md](docs/BENCHMARKING.md) — current numbers with run ids, how to run the harness, auth modes, and safety rails.\n- **Methodology and run record**: [docs/MEASUREMENTS.md](docs/MEASUREMENTS.md) — the full experimental record, including the retracted first corpus and what it taught.\n- **Architecture**: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — engine tiers, adapter contracts, hook protocols, and the design decisions behind them.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanvanster%2Fcompressor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanvanster%2Fcompressor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanvanster%2Fcompressor/lists"}