Skip to main content

Context compression for Claude Code — reduces tokens via PreToolUse hooks

Project description

claude-compress

Fewer tokens, lower cost, longer context — automatically.

claude-compress sits between Claude Code and every Bash command it runs. Before the output reaches Claude, it is compressed: ANSI codes stripped, repeated lines collapsed, JSON minified, noisy build output folded, and duplicate content replaced with a short reference token. The result is the same information in fewer tokens.


Installation

Requires Python 3.9+

pip install claude-compress

Then install the hooks into Claude Code:

# This project only
claude-compress init

# Every project on this machine (recommended)
claude-compress init --global

That's it. Open Claude Code and every Bash command is now compressed automatically.


How it works

Claude Code                  claude-compress              Your shell
    │                              │                          │
    │  PreToolUse hook fires       │                          │
    │ ─────────────────────────>   │                          │
    │                              │  rewrites command        │
    │  git status                  │  ──────────────────────> │
    │  becomes:                    │                          │ runs
    │  git status 2>&1 |           │                          │ git status
    │  python -m claude_compress   │   <────────────────────  │
    │         compress             │  compresses output       │
    │   <─────────────────────────  │                         │
    │  sees compressed output      │                          │
  1. claude-compress init writes a PreToolUse hook into Claude Code's settings
  2. The hook fires before every Bash call and rewrites the command to pipe its output through the compression engine
  3. Compression runs locally — no network calls, zero telemetry
  4. Claude sees the compressed output; a dedup cache means repeated file reads return a 13-character reference instead of the full content

Token savings — real examples

Repeated log lines · 90% reduction

# Raw output (21 lines)
WARNING: deprecated API call
WARNING: deprecated API call
... × 18 more identical lines ...
Build completed: 1 error

# Compressed (3 lines)
WARNING: deprecated API call (×20)
Build completed: 1 error

Cargo build noise · 88% reduction

# Raw (21 lines — 16 Compiling + error)
   Compiling serde v1.0.0 ...
   Compiling serde v1.0.1 ...
   ... 14 more Compiling lines ...
   Compiling myapp v0.1.0 ...
error[E0308]: mismatched types
  --> src/main.rs:42:5
42 |     do_thing(42u32);
   |              ^^^^^ expected &str, found u32

# Compressed (5 lines — error preserved in full)
   Compiling ... (16 crates)
error[E0308]: mismatched types
  --> src/main.rs:42:5
42 |     do_thing(42u32);
   |              ^^^^^ expected &str, found u32

JSON API response · 69% reduction

// Raw (318 bytes)
{
  "status": "ok",
  "user": { "id": 42, "name": "prabhay", "avatar": null,
            "bio": null, "location": null,
            "preferences": { "theme": "dark", "notifications": null,
                             "language": "en", "timezone": null } },
  "metadata": null, "errors": null, "warnings": null
}

// Compressed (95 bytes — nulls stripped, compact)
{"status":"ok","user":{"id":42,"name":"prabhay","preferences":{"theme":"dark","language":"en"}}}

Dedup — same file read twice · 100% reduction

# First read: compressed normally
...file contents...

# Second read: 13-character reference
§ref:e31ccbf816f6c042§

Claude Code resolves §ref:…§ tokens back to the original content — information is not lost, just deduplicated.


Viewing your savings

Per-command (in tool output)

After every compressed command you see a summary line at the bottom of the tool output, visible directly in Claude Code:

git status output here...

[claude-compress: 72% reduction · 354→99 tokens · saved 255] [git]

Session total

claude-compress stats
claude-compress  —  last 24h
  [████████████░░░░░░░░]  62% reduction
  Tokens saved : 11,130  (18,340 → 7,210)
  Compressions : 42
claude-compress gain          # one-liner for scripts / status bars
claude-compress stats --hours 1     # last hour
claude-compress stats --hours 168   # last week

Configuration

Scope: project vs global

Command Where hooks are written When it applies
claude-compress init .claude/settings.local.json This repo only
claude-compress init --global ~/.claude/settings.json Every project on this machine

Use --global if you want compression in all your Claude Code sessions without per-project setup. Both scopes can coexist — project hooks take precedence.

Cache directory

By default the dedup cache and stats live in ~/.claude-compress/. Override with an environment variable:

export CLAUDE_COMPRESS_DIR=/tmp/my-cache   # use a custom location

Add it to your shell profile (~/.bashrc, ~/.zshrc, etc.) to make it permanent.

Windows / Git Bash

The hooks are installed using your Python interpreter's full path (e.g. C:\Users\...\python.exe) so they work in Git Bash without permission issues. Run claude-compress init --global from a normal terminal and Claude Code will pick it up automatically.

If you install manually, use the full path to claude-compress.exe in your ~/.claude/settings.json hooks — just like the example below:

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash", "hooks": [
        { "type": "command",
          "command": "C:\\Users\\you\\AppData\\Roaming\\Python\\Python312\\Scripts\\claude-compress.exe hook" }
      ]}
    ],
    "PreCompact": [
      { "hooks": [
        { "type": "command",
          "command": "C:\\Users\\you\\AppData\\Roaming\\Python\\Python312\\Scripts\\claude-compress.exe hook --precompact" }
      ]}
    ],
    "SessionStart": [
      { "matcher": "compact", "hooks": [
        { "type": "command",
          "command": "C:\\Users\\you\\AppData\\Roaming\\Python\\Python312\\Scripts\\claude-compress.exe resume" }
      ]}
    ]
  }
}

Session handoff

claude-compress handoff lets you snapshot the current session state so a new Claude Code session can resume exactly where you left off — with a trust signal showing whether the repo has drifted.

# Emit a handoff at the end of a session
claude-compress handoff emit --task "auth refactor" --body "## Where this stands
Finished the JWT middleware, blocked on Redis config."

# In the new session — verify and inject into CLAUDE.md
claude-compress handoff resume          # uses latest handoff
claude-compress handoff verify latest   # check drift without injecting

# List all saved handoffs
claude-compress handoff list

# Remove the injected context once you no longer need it
claude-compress handoff clear

Handoffs are stored in ~/.claude-compress/handoffs/ as Markdown files with YAML frontmatter containing the git snapshot (branch, commit SHA, per-file hashes). On resume, the tool diffs the recorded state against the live repo and surfaces a GREEN / YELLOW / RED trust signal before the narrative.

Handoffs are also emitted automatically before every context compaction (PreCompact hook) — no manual step needed during long sessions.


What gets compressed

Content type Technique Typical reduction
Repeated / identical lines Run-length encoding (RLE) 80–99%
Cargo / Go build output Compiling-line folding 70–90%
pytest / jest output Failure-only extraction 60–85%
JSON API responses Null stripping + minification 40–70%
git diff context Unchanged-hunk folding 20–50%
ANSI color codes Regex strip 5–20%
Repeated file reads SHA-256 dedup cache 100%
Large outputs (> 500 lines) Head + tail truncation variable

What is NOT compressed

Compression is skipped (passthrough) for:

  • Interactive commandsvim, ssh, python, psql, less, watch, …
  • Shell pipelines — commands containing &&, ||, |, ;, >, <, &
  • Command substitution$(…) or backticks
  • Heredocs<< EOF
  • Background jobs — trailing &
  • Self-invocationclaude-compress … itself

Complex one-liners and interactive sessions are always passed through unchanged.


Commands

Command Description
claude-compress init Install hooks in .claude/settings.local.json (project)
claude-compress init --global Install hooks in ~/.claude/settings.json (all projects)
claude-compress hook Process PreToolUse JSON from stdin (called by Claude Code)
claude-compress hook --precompact Auto-emit handoff + mark dedup cache stale
claude-compress compress --cmd NAME Compress stdin and print to stdout (called via pipe)
claude-compress resume Re-activate dedup cache after SessionStart/compact
claude-compress stats [--hours N] Show token savings (default: last 24 h)
claude-compress gain [--hours N] One-line savings summary (good for scripts)
claude-compress handoff emit Snapshot current session state to a handoff file
claude-compress handoff verify [ID] Check a handoff for drift against the live repo
claude-compress handoff resume [ID] Inject a handoff into .claude/CLAUDE.md
claude-compress handoff list List saved handoffs (newest first)
claude-compress handoff clear Remove the injected handoff from CLAUDE.md
claude-compress uninstall Remove hooks from project settings
claude-compress uninstall --global Remove hooks from global settings

Uninstalling

claude-compress uninstall           # this project only
claude-compress uninstall --global  # all projects

Both commands surgically remove only the claude-compress entries and leave all other hooks in your settings untouched.


Running tests

pip install pytest
python -m pytest tests/ -v

96 tests covering hook passthrough cases, compression pipeline, handoff emit/verify/resume, and installer merge/uninstall logic.


Privacy

All processing is local. No data leaves your machine. The dedup cache (~/.claude-compress/cache.db) is a local SQLite database. There is no telemetry, no network calls, and no external dependencies.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claude_compress-0.1.5.tar.gz (31.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claude_compress-0.1.5-py3-none-any.whl (24.2 kB view details)

Uploaded Python 3

File details

Details for the file claude_compress-0.1.5.tar.gz.

File metadata

  • Download URL: claude_compress-0.1.5.tar.gz
  • Upload date:
  • Size: 31.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for claude_compress-0.1.5.tar.gz
Algorithm Hash digest
SHA256 5157ff676c8b987498d3ec4b52b481e73a81a06050cca181ec14395f0fcc52d7
MD5 76a5fc19f3c245650fa672aba947d8ac
BLAKE2b-256 a8db766259cb4adbee433cf59e10833d6c0f41509ef2382924ac3f7d786386d2

See more details on using hashes here.

File details

Details for the file claude_compress-0.1.5-py3-none-any.whl.

File metadata

File hashes

Hashes for claude_compress-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 2bc49fedd771bf578ca24f2524f737580252221e6b914aa4543908b49cc5fc1c
MD5 57bfd21235098ad6cf43841a3ba79671
BLAKE2b-256 e5ef4d32322862e70c7f7d68b9e36287e4af50a0b0e0b738118147dff399dda6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page