
Company News
Jerod Santo Joins Socket as Head of Media
Allow myself to introduce... myself.
@astudioplus/compressor
Advanced tools
Reduce token usage in AI coding agents (Claude Code, Copilot, Cursor) with instruction packs and tool-output compression hooks — savings you can measure.
Token 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.
Requires Node >= 20.
One-line install from GitHub (builds from source, puts compressor on your PATH):
# macOS / Linux / WSL
curl -fsSL https://raw.githubusercontent.com/anvanster/compressor/main/install.sh | bash
# Windows (PowerShell)
irm https://raw.githubusercontent.com/anvanster/compressor/main/install.ps1 | iex
Pin a tag/branch/commit with COMPRESSOR_REF (env var $env:COMPRESSOR_REF on Windows), e.g. COMPRESSOR_REF=v0.3.0.
Install the CLI globally (recommended — also enables relocatable hook commands):
npm install -g @astudioplus/compressor
Or install from source:
git clone https://github.com/anvanster/compressor.git
cd compressor
npm install
npm run build # compiles the CLI and bundles the hook entries
npm link # optional: puts `compressor` on your PATH
Without 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).
cd your-project
compressor init # claude-code, mode optimized, project scope
compressor status
compressor set-mode slim # switch modes
compressor set-mode full # removes everything — a true baseline
init, set-mode, and uninstall modify your agent config files, so they
first show the diff, warn you, and back up every changed file before writing
(in a terminal they also prompt to confirm). Preview without writing using
--dry-run; skip the prompt with --yes; turn off the backup with
--no-backup. Undo the last change with compressor restore (or
compressor restore --list to pick one).
What init installs at project scope:
.claude/output-styles/compressor-<mode>.md — the instruction pack as an output style (system prompt, cache-friendly).claude/settings.json — outputStyle set to compressor-<mode> (a pre-existing foreign outputStyle is stashed and restored on uninstall).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.jsonWith --global everything goes to ~/.claude/ instead, hook included in ~/.claude/settings.json. Changes take effect on the next session (/clear or a new session).
compressor init --agent copilot # project: instructions + hook
compressor init --agent copilot --global # machine-wide hook only (Copilot CLI)
Project 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.
The 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 <m>) 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.
compressor init --agent cursor
Installs .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.
compressor init --agent agents-md
Upserts 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.
compressor init --agent opencode # project: .opencode/plugins/compressor.js
compressor init --agent opencode --global # machine-wide: ~/.config/opencode/plugins/
compressor init --agent agents-md # instructions (OpenCode reads AGENTS.md natively)
Installs 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.
Multiple agents in one go: compressor init --agent claude-code copilot agents-md opencode.
| Agent | Instruction pack | Compression hook | Global scope |
|---|---|---|---|
| claude-code | yes (output style) | yes (PostToolUse) 1 | yes (style + hook) |
| copilot | yes (project only) | yes — Copilot CLI 2 | hook only 3 |
| cursor | yes (.mdc rules) | no 4 | no (per-project standard) |
| agents-md | yes (marked section) | no | no (per-project standard) |
| opencode | via agents-md (OpenCode reads AGENTS.md natively) | yes — in-process plugin 5 | yes (~/.config/opencode/plugins) |
| Mode | Instructions | Tool-output compression |
|---|---|---|
full | none — set-mode full removes every compressor artifact and the hook, giving a true baseline rather than "empty instructions present" | none (passthrough) |
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 |
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 |
Every 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.
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:
[INFO] building module graph... ok
[compressor: previous line repeated 399 more times]
FAIL: type error in engine.ts
Error: exit 1
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:
354→ max: 100,
[compressor: lines 355-916 omitted (~4749 est tokens) — Read src/telemetry.mjs with offset=355 and limit=562 to retrieve]
356→ let mask = 0;
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, never content and never a path. The one identifying field is an optional project label, and it defaults to a keyed digest whose key is kept at ~/.compressor/project-salt, outside the ledger, so a report you share cannot be tested against guessed project names:
$ compressor savings --by tool
saved 127,041 chars (exact) ≈ 36,300 tokens (estimated — cheap estimator, not billable counts) · last 30 days
events: 8 (last 30 days)
by tool:
bash ████████████████████████████████████████ ≈ 35,162 tok
read █ ≈ 1,138 tok
compressor savings --html report.html writes a self-contained report (inline SVG, no JS, no network). Kill switch: COMPRESSOR_NO_LEDGER=1.
Benchmarked 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.
| Command | What it does | Key flags (defaults) |
|---|---|---|
init | install the instruction pack + hook for the given agents | --agent <name...> (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) |
set-mode <full|optimized|slim> | switch mode; full removes all compressor artifacts (true baseline) | --agent <name...> (claude-code), --global, --dry-run, --hook-command (as init) |
status | show installation state per agent — derived from files and markers, no state file to drift | --global |
uninstall | remove all compressor-owned artifacts | --agent <name...> (claude-code), --global, --dry-run |
compress | compress stdin to stdout via the engine; stats on stderr | --mode (optimized), --kind read|bash|search|other (other), --file-path <path>, --marker-style plain|deterrent|informative |
count <file...> | token counts per file — estimated by default | --exact (Anthropic count_tokens, needs ANTHROPIC_API_KEY), --model (claude-sonnet-4-6) |
stats | aggregate actual token usage from Claude Code transcripts | --project <path> (cwd), --since (30d) |
savings | show what the compression hook saved (live ledger, estimated tokens) | --since (30d, or all), --by day|tool|mode|agent|project (day), --html <path>, --ledger-dir <dir> |
hook post-tool-use | Claude Code PostToolUse protocol entry: payload on stdin, updated output on stdout | --mode (optimized), --marker-style, --recovery-budget <n|off> (overrides COMPRESSOR_RECOVERY_BUDGET/COMPRESSOR_NO_RECOVERY_BUDGET) |
hook copilot-post-tool-use | Copilot postToolUse protocol entry: payload on stdin, modifiedResult JSON on stdout | --mode (optimized), --marker-style, --recovery-budget <n|off> |
Installed 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.
The benchmarking commands (compressor benchmark, compressor report) are a from-source feature for measuring compressor itself — documented in docs/BENCHMARKING.md.
Three views, deliberately not conflated:
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.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.Stated plainly, because the alternative is users discovering them:
COMPRESSOR_RECOVERY_BUDGET tunes, COMPRESSOR_NO_RECOVERY_BUDGET=1 disables) bounds the re-read cost; its behavioral effect is not yet benchmarked.compressor status says so until it is.MIT — see LICENSE.
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). ↩
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. ↩
~/.copilot/hooks/compressor.json, loaded by Copilot CLI only; Copilot has no user-global instructions mechanism. ↩
Cursor postToolUse can replace MCP tool output only; built-in Read/Shell output cannot be rewritten. ↩
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. ↩
FAQs
Reduce token usage in AI coding agents (Claude Code, Copilot, Cursor) with instruction packs and tool-output compression hooks — savings you can measure.
The npm package @astudioplus/compressor receives a total of 143 weekly downloads. As such, @astudioplus/compressor popularity was classified as not popular.
We found that @astudioplus/compressor demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards users’ live OAuth session tokens through proxies controlled by a Russian bot service.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.