https://github.com/claudioemmanuel/squeez
Hook-based token compressor for 5 AI CLI hosts (Claude Code, Copilot CLI, OpenCode, Gemini CLI, Codex CLI). Up to 95% bash compression, signature-mode for code reads, cross-call dedup, MCP server, self-teaching protocol. Zero runtime deps.
https://github.com/claudioemmanuel/squeez
ai-cli bash-hook claude-code codex-cli context-engineering context-window copilot-cli gemini-cli llm llm-tools mcp-server opencode rust session-memory signature-extraction token-compression token-optimizer zero-dependency
Last synced: 3 days ago
JSON representation
Hook-based token compressor for 5 AI CLI hosts (Claude Code, Copilot CLI, OpenCode, Gemini CLI, Codex CLI). Up to 95% bash compression, signature-mode for code reads, cross-call dedup, MCP server, self-teaching protocol. Zero runtime deps.
- Host: GitHub
- URL: https://github.com/claudioemmanuel/squeez
- Owner: claudioemmanuel
- License: apache-2.0
- Created: 2026-03-23T11:21:53.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-14T23:33:11.000Z (6 days ago)
- Last Synced: 2026-05-15T01:32:29.811Z (6 days ago)
- Topics: ai-cli, bash-hook, claude-code, codex-cli, context-engineering, context-window, copilot-cli, gemini-cli, llm, llm-tools, mcp-server, opencode, rust, session-memory, signature-extraction, token-compression, token-optimizer, zero-dependency
- Language: Rust
- Homepage:
- Size: 1.96 MB
- Stars: 116
- Watchers: 1
- Forks: 12
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Notice: NOTICE
Awesome Lists containing this project
README
# squeez
[](https://github.com/claudioemmanuel/squeez/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/squeez)
[](https://crates.io/crates/squeez)
[](LICENSE)
[](CONTRIBUTING.md#license--contributor-sign-off)
[](CHANGELOG.md)
End-to-end token optimizer for Claude Code, GitHub Copilot CLI, OpenCode, Gemini CLI, and OpenAI Codex CLI. Compresses bash output up to **95%**, collapses redundant calls, and injects a terse prompt persona β automatically, with zero new runtime dependencies.
---
## Install
Three methods β all produce the same result (binary at `~/.claude/squeez/bin/squeez`, hooks registered).
### curl (recommended)
```bash
curl -fsSL https://raw.githubusercontent.com/claudioemmanuel/squeez/main/install.sh | sh
```
> **Windows:** requires [Git Bash](https://git-scm.com/downloads). Run the command above inside Git Bash β PowerShell/CMD are not supported.
### npm / npx
```bash
# Install globally
npm install -g squeez
# Or run once without installing
npx squeez
```
Downloads the correct pre-built binary for your platform (macOS universal, Linux x86_64/aarch64, Windows x86_64). Requires Node β₯ 16.
### cargo (build from source)
```bash
cargo install squeez
```
Builds from [crates.io](https://crates.io/crates/squeez). Requires Rust stable. On Windows you also need [MSVC C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/).
---
### Supported hosts
`squeez setup` auto-detects every CLI present on disk and registers the hooks. `squeez uninstall` removes them. Session data and `config.ini` are preserved so reinstall is lossless.
| Host | Memory file | Bash wrap | Session memory | Budget inject (Read/Grep) | Notes |
|---|---|---|---|---|---|
| **Claude Code** | `~/.claude/CLAUDE.md` | β
native | β
native | β
native | Restart Claude Code to pick up hooks |
| **Copilot CLI** | `~/.copilot/copilot-instructions.md` | β
native | β
native | β
native | Restart Copilot CLI after setup |
| **OpenCode** | `~/.config/opencode/AGENTS.md` | β
native | β
native | β
native | Plugin at `~/.config/opencode/plugins/squeez.js`; MCP tool calls skip hooks (upstream sst/opencode#2319) |
| **Gemini CLI** | `~/.gemini/GEMINI.md` | β
native | β
native | π‘ soft via `GEMINI.md` | `BeforeTool` rewrite schema pending upstream docs ([google-gemini/gemini-cli#25629](https://github.com/google-gemini/gemini-cli/issues/25629)) |
| **Codex CLI** | `~/.codex/AGENTS.md` | β
native | β
native | π‘ soft via `AGENTS.md` | `apply_patch` hooks landed in 0.123.0 ([#18391](https://github.com/openai/codex/pull/18391)); `updatedInput` + `read_file`/`grep` hook surface still pending ([openai/codex#18491](https://github.com/openai/codex/issues/18491)) |
| **Pi** | `~/.pi/agent/skills/squeez/SKILL.md` | β
native | β
via skill | β
native | TypeScript extension at `~/.pi/agent/extensions/squeez/index.ts`; restart Pi after setup |
### Manage
```bash
squeez setup # register into every detected host
squeez setup --host= # register into one host
squeez uninstall # remove squeez entries from every detected host
squeez uninstall --host=
```
Slugs: `claude-code` / `copilot` / `opencode` / `gemini` / `codex` / `pi`.
After install, restart the CLI you use to pick up the new hooks.
### Uninstall
```bash
squeez uninstall # preserves session data + config.ini
bash ~/.claude/squeez/uninstall.sh # (legacy) full wipe, if the script exists
```
### Self-update
```bash
squeez update # download latest binary + verify SHA256
squeez update --check # check for update without installing
squeez update --insecure # skip checksum (not recommended)
```
---
## What it does
| Feature | Description |
|---------|-------------|
| **Bash compression** | Intercepts every command via `PreToolUse` hook, applies smart filter β dedup β grouping β truncation. Up to 95% reduction. |
| **Context engine** | Cross-call redundancy with two paths: exact-hash match (FNV-1a, fast) **and** fuzzy trigram-shingle Jaccard β₯0.85 (whitespace, timestamps, single-line edits no longer defeat dedup). |
| **Summarize fallback** | Outputs exceeding 500 lines are replaced with a β€40-line dense summary (top errors, files, test result, tail). **Benign outputs get 2Γ the threshold** so successful builds stay verbatim. |
| **Adaptive intensity** | Truly adaptive: **Full** (Γ0.6 limits) below 80% of token budget, **Ultra** (Γ0.3) above. Used to be always-Ultra; now actually responds to session pressure. |
| **MCP server** | `squeez mcp` runs a JSON-RPC 2.0 server over stdio exposing 13 read-only tools so any MCP-compatible LLM can query session memory directly. Hand-rolled, no `mcp.server` dependency. |
| **Auto-teach payload** | `squeez protocol` (or the `squeez_protocol` MCP tool) prints a 2.4 KB self-describing payload β the LLM learns squeez's markers and protocol on first call. |
| **Caveman persona** | Injects an ultra-terse prompt at session start so the model responds with fewer tokens. |
| **Memory-file compression** | `squeez compress-md` compresses CLAUDE.md / AGENTS.md / copilot-instructions.md in-place β pure Rust, zero LLM. i18n-aware: set `lang = pt` (or `--lang pt`) for pt-BR article/filler/phrase dropping and Unicode-correct matching. |
| **Session memory** | On `SessionStart`, injects a structured summary of the previous session: files investigated, learned facts (errors + git events), completed work (builds, test passes), and next steps (unresolved errors, failing tests). Summaries carry temporal validity (`valid_from`/`valid_to`). |
| **Token tracking** | Every `PostToolUse` result (Bash, Read, Grep, Glob, Monitor, SubagentStop) feeds a `SessionContext` so squeez knows what the agent has already seen. Read/Grep/Glob/Monitor outputs are also rewritten via `updatedToolOutput` (Claude Code v2.1.119+) when content is redundant or oversized. |
| **Token economy** | Sub-agent cost tracking (~200K tokens/spawn), burn rate prediction (`[budget: ~N calls left]`), session efficiency scoring, tool result size budgets. |
| **Auto-calibration** | `squeez calibrate` runs benchmarks on install and generates an optimized `config.ini` (aggressive / balanced / conservative profiles). |
---
## Scope & Limits
squeez optimizes what it can reach β the surfaces exposed by each host's hook API. It cannot fix token leaks outside those surfaces.
### Coverage table
| Surface | How | When | Supported hosts |
|---|---|---|---|
| **Bash stdout/stderr** | `PreToolUse` wraps command w/ 4-stage pipeline (smart-filter β dedup β grouping β truncation) | Every Bash invocation | all 5 |
| **Read / Grep / Glob limits** | `PreToolUse` injects `limit` / `head_limit` per `read_max_lines` / `grep_max_results` | Every Read/Grep/Glob call | Claude Code, Copilot, OpenCode (hard); Gemini + Codex soft via GEMINI.md / AGENTS.md |
| **Read / Grep / Glob / Monitor output rewrite** | `PostToolUse` runs `squeez compress-output` and returns `updatedToolOutput` when content is redundant or oversized | Claude Code v2.1.119+ | Claude Code |
| **Agent / Task prompt** | `PreToolUse` compresses `tool_input.prompt` (markdown-aware, via `compress-prompt`) | When prompt > `agent_prompt_max_tokens` | Claude Code (postβv1.8.0) |
| **Sub-agent output** | `SubagentStop` hook feeds `last_assistant_message` into SessionContext for cross-call dedup | On every sub-agent completion | Claude Code |
| **Compaction lifecycle** | `PreCompact` logs the event; `PostCompact` emits a re-arm reminder so the model knows compression is still active | On context compaction | Claude Code |
| **Session memory** | `SessionStart` injects prior session summary + file-access cache | Once per session start | all 5 |
| **Markdown viewing** | Bash handler routes `.md` reads through `compress-md` when `auto_compress_md=true` | Viewer commands on .md paths | all 5 |
### What squeez CANNOT compress
**Agent/Task returned output.** No hook API surface exists to rewrite an Agent's return value. `PostToolUse updatedToolOutput` (Claude Code v2.1.119+) covers built-in tools (Read, Grep, Glob, Monitor) but not the Agent/Task result. Workaround: keep agent prompts compact (squeez compresses at dispatch time via PreToolUse), and use `squeez_agent_costs` MCP tool to monitor spawn overhead.
**Skills & slash-command files.** Claude Code loads these into the system prompt before any hook fires. squeez has no visibility into session-start system prompt construction.
**User's top-level prompt.** squeez runs per tool call, not on user turns.
**Tools whose host doesn't expose PreToolUse / BeforeTool.** E.g. Codex `apply_patch` hooks landed in 0.123.0, but `updatedInput` is explicitly unsupported and `read_file`/`grep` still have no hook surface ([openai/codex#18491](https://github.com/openai/codex/issues/18491)) β so Read/Grep caps for Codex are soft hints in AGENTS.md, not hard injections.
### Secondary wins (not compression, but token-saving)
- **Cross-call redundancy dedup** β exact-hash and fuzzy-trigram collapsing across 16 recent calls (see [Context engine](#what-it-does))
- **File-access cache** β subsequent Bash commands trimmed when re-reading a file squeez has already fingerprinted
- **Burn-rate warnings** β `[budget: ~N calls left]` nudges so the user changes behavior before context pressure spikes
### Reducing overall session cost
squeez cannot automate these, but you can:
- Fewer Agent/Task dispatches per session β use `squeez_agent_costs` to track, then refactor tasks to batch work
- Smaller prompts injected into agents β squeez compresses them at dispatch, but smaller is better
- Shorter CLAUDE.md / AGENTS.md files β run `squeez compress-md --ultra` to drop abbreviations and filler
---
## Benchmarks
Measured on macOS (Apple Silicon). Token count = `chars / 4` (matches Claude's ~4 chars/token). Run `squeez benchmark` to reproduce.
### Per-scenario results β 28 scenarios Γ 5 iterations
| Scenario | Before | After | Reduction | Latency |
|----------|--------|-------|-----------|---------|
| `summarize_huge` | 82,257 tk | 420 tk | **-99%** | 55.9 ms |
| `repetitive_output` | 4,692 tk | 37 tk | **-99%** | 221 Β΅s |
| `xcode_build` | 1,881 tk | 17 tk | **-99%** | 83 Β΅s |
| `high_context_adaptive` | 4,418 tk | 52 tk | **-99%** | 866 Β΅s |
| `agent_directory_output` | 3,348 tk | 167 tk | **-95%** | 371 Β΅s |
| `ps_aux` | 40,373 tk | 2,352 tk | **-94%** | 4.6 ms |
| `git_log_200` | 2,692 tk | 289 tk | **-89%** | 229 Β΅s |
| `tsc_errors` | 731 tk | 101 tk | **-86%** | 22 Β΅s |
| `cargo_build_noisy` | 2,106 tk | 452 tk | **-79%** | 289 Β΅s |
| `docker_logs` | 665 tk | 186 tk | **-72%** | 50 Β΅s |
| `curl_html_response` | 2,181 tk | 626 tk | **-71%** | 50 Β΅s |
| `find_deep` | 424 tk | 134 tk | **-68%** | 132 Β΅s |
| `git_status` | 50 tk | 16 tk | **-68%** | 15 Β΅s |
| `pytest_failures` | 3,402 tk | 1,189 tk | **-65%** | 358 Β΅s |
| `verbose_app_log` | 4,957 tk | 1,991 tk | **-60%** | 330 Β΅s |
| `npm_install` | 524 tk | 232 tk | **-56%** | 49 Β΅s |
| `crosscall_redundancy_3x` | 486 tk | 241 tk | **-50%** | 51.7 ms |
| `ls_la` | 1,782 tk | 886 tk | **-50%** | 237 Β΅s |
| `env_dump` | 441 tk | 287 tk | **-35%** | 28 Β΅s |
| `git_copilot` | 640 tk | 421 tk | **-34%** | 131 Β΅s |
| `agent_heavy` | 2,306 tk | 1,564 tk | **-32%** | 368 Β΅s |
| `md_prose` | 187 tk | 138 tk | **-26%** | 880 Β΅s |
| `md_claude_md` | 316 tk | 247 tk | **-22%** | 1.4 ms |
| `claude_md_overhead` | 717 tk | 649 tk | **-9%** | 22 Β΅s |
| `git_diff` | 502 tk | 497 tk | **-1%** | 44 Β΅s |
| `jest_failures` | 451 tk | 448 tk | **-1%** | 54 Β΅s |
| `state_first_simulation` | 182 tk | 181 tk | **-1%** | 5 Β΅s |
| `kubectl_pods` | 1,513 tk | 1,513 tk | **-0%** | 36 Β΅s |
### Aggregate
| Metric | Value |
|--------|-------|
| **Total token reduction** | **90.7%** β 164,224 tk β 15,333 tk |
| Bash output | **-83.9%** |
| Markdown / context files | **-23.5%** |
| Wrap / cross-call engine | **-99.2%** |
| Quality (signal terms preserved) | **28 / 28 pass** |
| Latency p50 (filter mode) | **4.2 ms** |
| Latency p95 (incl. wrap/summarize) | **52 ms** |
### Estimated cost savings β Claude Sonnet 4.6 Β· $3.00 / MTok input
| Usage | Baseline / month | Saved / month |
|-------|-----------------|---------------|
| 100 calls / day | $18.00 | **$16.32 (91%)** |
| 1,000 calls / day | $180.00 | **$163.19 (91%)** |
| 10,000 calls / day | $1800.00 | **$1631.88 (91%)** |
---
## Commands
```bash
squeez wrap # compress a command's output end-to-end
squeez filter # compress stdin (piped usage)
squeez compress-md [--ultra] [--dry-run] [--all] ... # compress markdown files
squeez benchmark [--json] [--output ] [--scenario ] [--iterations ]
squeez mcp # JSON-RPC 2.0 MCP server over stdin/stdout
squeez protocol # print the auto-teach payload (markers + protocol)
squeez update [--check] [--insecure] # self-update
squeez init [--copilot] # session-start hook (called by hook, not manually)
squeez calibrate # auto-tune config from benchmarks
squeez budget-params # output JSON budget patch for tool
squeez --version
```
### Escape hatch β bypass compression for one command
```bash
--no-squeez git log --all --graph
```
Prefix any command with `--no-squeez` to run it raw without squeez touching it.
### `squeez wrap`
Runs a command, compresses its output, and prints a savings header:
```
# squeez [git log] 2692β289 tokens (-89%) 0.2ms [adaptive: Ultra]
```
### `squeez filter`
Reads from stdin. Use for manual pipelines:
```bash
git log --oneline | squeez filter git
docker logs mycontainer 2>&1 | squeez filter docker
```
### `squeez compress-md`
Pure-Rust, zero-LLM compressor for markdown files. Preserves code blocks, inline code, URLs, headings, file paths, and tables. Compresses prose only. Always writes a backup at `.original.md`.
```bash
squeez compress-md CLAUDE.md # Full mode (English default)
squeez compress-md --ultra CLAUDE.md # + abbreviations (withβw/, fn, cfg, etc.)
squeez compress-md --lang pt CLAUDE.md # pt-BR locale (articles, fillers, phrases)
squeez compress-md --dry-run CLAUDE.md # preview, no write
squeez compress-md --all # compress all known locations automatically
```
When `auto_compress_md = true` (default), `squeez init` runs `--all` silently on every session start.
### `squeez benchmark`
Reproducible measurement of token reduction, cost, latency, and quality across 19 scenarios:
```bash
squeez benchmark # human-readable report
squeez benchmark --json # JSON to stdout
squeez benchmark --output report.json # save JSON report
squeez benchmark --scenario git # run only git scenarios
squeez benchmark --iterations 5 # more iterations per scenario
squeez benchmark --list # list all scenarios
```
Quality is scored by checking that **signal terms** (words from error/warning/failed lines in the baseline) survive compression. 19/19 pass at β₯ 50% threshold.
### `squeez mcp`
Runs a Model Context Protocol JSON-RPC 2.0 server over stdin/stdout. Hand-rolled, no `mcp.server` / `fastmcp` dependency β keeps the `libc`-only constraint intact. Wire it into Claude Code:
```bash
claude mcp add squeez -- /path/to/squeez mcp
```
Thirteen read-only tools become available to the LLM:
| Tool | Returns |
|------|---------|
| `squeez_recent_calls` | Last N bash invocations with hash + length + cmd snippet β check before re-running |
| `squeez_seen_files` | Files this session has touched, with access type (Read/Write/Created/Deleted), sorted by recency |
| `squeez_seen_errors` | Distinct error fingerprints observed this session (FNV-1a hashes of normalized errors) |
| `squeez_seen_error_details` | Error fingerprints with the first 128 chars of message text β find *what* the error was |
| `squeez_session_summary` | Token accounting + call counts (tokens_bash / tokens_read / tokens_other / seen_files / seen_errors / seen_git_refs) |
| `squeez_session_stats` | Dedup hit counts (exact + fuzzy), summarize triggers, Ultra-mode calls, tokens saved per category |
| `squeez_agent_costs` | Sub-agent usage: spawn count, cumulative estimated tokens, per-call breakdown |
| `squeez_session_efficiency` | Session efficiency scores: compression ratio, tool choice, context reuse, budget conservation (basis points) |
| `squeez_prior_summaries` | Last N finalized prior-session summaries with structured fields: investigated / learned / completed / next_steps |
| `squeez_search_history` | Full-text search across all session summaries β find when you last saw an error or touched a file |
| `squeez_file_history` | Sessions where a given file path was touched, with token-savings and commit status |
| `squeez_session_detail` | Full structured view of a past session by date: calls, files, errors, git events, test summary |
| `squeez_protocol` | Auto-teach payload β read once per session to learn squeez's markers + memory protocol |
All read-only. Backed by `SessionContext::load()`, `memory::read_last_n()`, and `memory::search_history()`. No side effects.
### `squeez protocol`
Prints the auto-teach payload β a 2.4 KB self-describing block covering:
- The 5-rule **memory protocol** (what to do with `[squeez: ...]` markers, when to call the MCP tools)
- The **output marker spec** (`# squeez [...]`, `[squeez: identical to ...]`, `[squeez: ~95% similar to ...]`, `squeez:summary`, `# squeez hint:`)
Same content the MCP `squeez_protocol` tool returns. Pipe it into a `system` prompt or paste it into a one-shot session that doesn't have the MCP server connected.
---
## Configuration
Optional config file β all fields have defaults, none are required.
| Platform | Config path |
|----------|------------|
| Claude Code / default | `~/.claude/squeez/config.ini` |
| Copilot CLI | `~/.copilot/squeez/config.ini` |
```ini
# ββ Compression ββββββββββββββββββββββββββββββββββββββββββββββββ
max_lines = 200 # generic truncation limit
dedup_min = 3 # collapse lines appearing β₯N times
git_log_max_commits = 20
git_diff_max_lines = 150
docker_logs_max_lines = 100
find_max_results = 50
bypass = docker exec, psql, mysql, ssh # never compress these
# ββ Context engine βββββββββββββββββββββββββββββββββββββββββββββ
adaptive_intensity = true # truly adaptive: Full <80% budget, Ultra β₯80%
context_cache_enabled = true # track seen files/errors across calls
redundancy_cache_enabled = true # collapse identical OR fuzzy-similar recent outputs
summarize_threshold_lines = 500 # outputs above this trigger summarize fallback (Γ2 if benign)
compact_threshold_tokens = 120000 # session token budget β drives adaptive intensity
# ββ Session memory βββββββββββββββββββββββββββββββββββββββββββββ
memory_retention_days = 30
# ββ Output / persona βββββββββββββββββββββββββββββββββββββββββββ
persona = ultra # off | lite | full | ultra
auto_compress_md = true # run compress-md on every session start
lang = en # compress-md locale: en | pt (pt-BR) β more languages extensible
# ββ Advanced tuning (rarely needed) βββββββββββββββββββββββββββ
max_call_log = 32 # rolling call log depth (also caps redundancy window)
recent_window = 16 # how many recent calls are eligible for redundancy lookup
similarity_threshold = 0.85 # Jaccard threshold for fuzzy dedup (0.0β1.0)
ultra_trigger_pct = 0.80 # fraction of context budget at which Full β Ultra
mcp_prior_summaries_default = 5 # default n for squeez_prior_summaries
mcp_recent_calls_default = 10 # default n for squeez_recent_calls
# ββ Token economy βββββββββββββββββββββββββββββββββββββββββββββ
agent_warn_threshold_pct = 0.50 # warn when agent cost > 50% of budget
burn_rate_warn_calls = 20 # warn when < 20 calls remaining
agent_spawn_cost = 200000 # estimated tokens per Agent/Task spawn
read_max_lines = 0 # max lines injected into Read tool_input (0 = off)
grep_max_results = 0 # max results injected into Grep tool_input (0 = off)
# ββ Auto-curation nudges ββββββββββββββββββββββββββββββββββββββ
nudge_enabled = true # emit [squeez: hint ...] markers on recurring patterns
nudge_error_threshold = 3 # fingerprint repeats before a nudge fires
nudge_file_mod_threshold = 5 # writes/creates to same path before nudge fires
nudge_cmd_repeat_threshold = 4 # expensive-command repeats before nudge fires
# ββ Continuous handler calibration ββββββββββββββββββββββββββββ
handler_stats_enabled = true # accumulate per-handler savings across sessions
```
### Adaptive intensity β Full / Ultra split
When `adaptive_intensity = true` (default), squeez **actually adapts** to session pressure rather than always running Ultra:
| Used / budget | Tier | Scaling |
|---|---|---|
| `< 80%` | **Full** | Γ0.6 limits, dedup_min Γ0.66 (floor 2) |
| `β₯ 80%` | **Ultra** | Γ0.3 limits, dedup_min Γ0.5 (floor 2) |
| `adaptive_intensity = false` | **Lite** | passthrough β no scaling |
Floors are enforced so we never reduce to zero: `max_lines β₯ 20`, `git_diff_max_lines β₯ 20`, `dedup_min β₯ 2`, `summarize_threshold_lines β₯ 50`.
The active level is shown in every bash header: `[adaptive: Full]` or `[adaptive: Ultra]`.
Pre-0.3 squeez was effectively always-Ultra. The new behavior preserves more verbatim text in the common case (empty / mid-session) and only graduates to aggressive compression when the context budget is genuinely under pressure.
### Caveman persona
Three intensity levels (`lite`, `full`, `ultra`) and `off`. Default is `ultra`. The persona prompt is injected into:
- The Claude Code session banner (printed at `SessionStart`)
- The `β¦` block in `~/.copilot/copilot-instructions.md` for Copilot CLI
---
## How it works
### Compression pipeline
Each bash command passes through four strategies in order:
1. **smart_filter** β strips ANSI codes, progress bars, spinner chars, timestamps, and tool-specific noise (npm download lines, stack frame noise, etc.)
2. **dedup** β lines appearing β₯ `dedup_min` times are collapsed to one entry annotated `[ΓN]`
3. **grouping** β files in the same directory (β₯5 siblings) are collapsed to `dir/ N modified [squeez grouped]`
4. **truncation** β `Head` (keep first N) or `Tail` (keep last N) depending on handler; truncated portion noted
### Supported handlers
| Category | Commands |
|----------|----------|
| Git | `git` |
| Docker / containers | `docker`, `docker-compose`, `podman` |
| Package managers | `npm`, `pnpm`, `bun`, `yarn` |
| Build systems | `make`, `cmake`, `gradle`, `mvn`, `xcodebuild`, `cargo` (build), `next build/dev/start` |
| Test runners | `cargo test`, `jest`, `vitest`, `pytest`, `nextest`, `playwright`, `bun test` |
| TypeScript / linters | `tsc`, `eslint`, `biome` |
| Cloud CLIs | `kubectl`, `gh`, `aws`, `gcloud`, `az`, `wrangler` |
| Databases | `psql`, `prisma`, `mysql`, `drizzle-kit` |
| Filesystem | `find`, `ls`, `du`, `ps`, `env`, `lsof`, `netstat` |
| JSON / YAML / IaC | `jq`, `yq`, `terraform`, `tofu`, `helm`, `pulumi` |
| Text processing | `grep`, `rg`, `awk`, `sed` |
| Network | `curl`, `wget` |
| Runtimes | `node`, `python`, `ruby` |
| Generic fallback | everything else |
### Hooks (Claude Code & Copilot CLI)
Six hooks work together automatically after install on Claude Code (three on Copilot CLI):
- **`PreToolUse`** β rewrites every Bash call: `git status` β `squeez wrap git status`; injects Read/Grep/Glob limits; compresses Agent/Task prompts
- **`SessionStart`** β runs `squeez init`: finalizes previous session into a memory summary, injects the persona prompt
- **`PostToolUse`** β tracks every tool result; rewrites Read/Grep/Glob/Monitor output via `updatedToolOutput` when content is redundant or oversized (Claude Code v2.1.119+)
- **`SubagentStop`** *(Claude Code only)* β feeds `last_assistant_message` into SessionContext so the parent agent can dedup against what the sub-agent saw
- **`PreCompact`** *(Claude Code only)* β logs compaction events for session efficiency metrics; allows compaction to proceed
- **`PostCompact`** *(Claude Code only)* β emits a re-arm reminder after compaction so the model knows compression is still active
### Cross-call redundancy
Two-path dedup across the last 16 calls:
**Exact match** β FNV-1a hash of the compressed output. When a subsequent call produces the same bytes, it collapses to:
```
[squeez: identical to 515ba5b2 at bash#35 β re-run with --no-squeez]
```
**Fuzzy match** β bottom-k MinHash over whitespace-token trigrams (k=96, Jaccard β₯ 0.85, length-ratio guard β₯ 0.80). Survives timestamp changes, added/removed blank lines, and single-line edits. Collapses to:
```
[squeez: ~92% similar to 515ba5b2 at bash#35 β re-run with --no-squeez]
```
Minimum 6 lines to attempt fuzzy match (below that, exact-only).
### Summarize fallback
When raw output exceeds `summarize_threshold_lines` (default 500), the full pipeline is bypassed and replaced with a β€40-line dense summary:
```
squeez:summary cmd=docker logs app
total_lines=5003
top_errors:
- error: connection refused on tcp://10.0.0.1:5432
top_files:
- /var/log/app/error.log
test_summary=FAILED: 3 of 248
tail_preserved=20
[last 20 lines verbatim...]
```
**Benign-aware threshold:** before summarizing, squeez scans for error markers (`error:`, `panic`, `traceback`, `FAILED`, `EXCEPTION`, `Fatal`). If none are found, the threshold is doubled (1,000 lines default) so successful builds, clean test runs, and uneventful logs stay verbatim unless they are genuinely huge.
---
## Platform notes
### OpenCode
Plugin installed at `~/.config/opencode/plugins/squeez.js`. OpenCode auto-loads plugins on startup. All Bash commands are automatically compressed via `squeez wrap`.
### GitHub Copilot CLI
Hooks registered in `~/.copilot/settings.json`. Session memory written to `~/.copilot/copilot-instructions.md` (Copilot CLI reads this automatically). State stored separately at `~/.copilot/squeez/`.
Refresh memory manually:
```bash
SQUEEZ_DIR=~/.copilot/squeez ~/.claude/squeez/bin/squeez init --copilot
```
### Pi
TypeScript extension installed at `~/.pi/agent/extensions/squeez/index.ts`. Pi auto-discovers extensions from that directory β no settings patching needed. Session memory is injected via a skill at `~/.pi/agent/skills/squeez/SKILL.md`; Pi includes the skill description in every system prompt and loads full instructions on demand. Unlike other hosts, Pi achieves `BUDGET_HARD` output compression via the `tool_result` event (return-patch API), not just soft hints.
---
## Local development
Requires Rust stable. Windows requires Git Bash.
```bash
git clone https://github.com/claudioemmanuel/squeez.git
cd squeez
cargo test # run all tests (356 tests, 37 suites)
cargo build --release # build release binary
bash bench/run.sh # filter-mode benchmark (14 fixtures)
bash bench/run_context.sh # context-engine benchmark (3 wrap scenarios)
./target/release/squeez benchmark # full 19-scenario benchmark suite
bash build.sh # build + install to ~/.claude/squeez/bin/
```
---
## Contributing
```bash
git checkout -b feature/your-change
cargo test
cargo build --release
bash bench/run.sh
git push -u origin feature/your-change
gh pr create --base main --title "Short title" --body "Description"
```
CI runs `cargo test`, `bench/run.sh`, `bench/run_context.sh`, and `squeez benchmark` on every push and pull request.
See [CONTRIBUTING.md](CONTRIBUTING.md) for coding standards.
---
## Similar projects
There is an unrelated project with the same name at [KRLabsOrg/squeez](https://github.com/KRLabsOrg/squeez). This project (claudioemmanuel/squeez) is a hook-based token compressor for AI coding CLIs.
---
## License
Licensed under the **Apache License 2.0** β see [LICENSE](LICENSE) + [NOTICE](NOTICE).
Contributions require a DCO sign-off (`git commit -s β¦`) rather than a CLA. You keep copyright on what you contribute; sign-off is a lightweight affirmation that you have the right to submit it under Apache 2.0. See [CONTRIBUTING.md](CONTRIBUTING.md#license--contributor-sign-off) for details.