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 | ansi+git+rle] [git]

The tags at the end (ansi+git+rle) show which techniques fired for that command.

Technique breakdown

To see a full per-technique breakdown of recent compressions:

claude-compress last
Last 5 compression(s):

  #1  git        [2m ago]   72% | 354->99 tokens | saved 255  (ansi+git+rle)
       ansi        : -38 tokens
       git         : -180 tokens
       rle         : -25 tokens
       blank       : -12 tokens

  #2  cargo      [5m ago]   88% | 450->54 tokens | saved 396  (ansi+cargo)
       ansi        : -12 tokens
       cargo       : -350 tokens
       rle         : -34 tokens

  #3  pytest     [12m ago]  61% | 820->320 tokens | saved 500  (pytest+rle)
       pytest      : -450 tokens
       rle         : -50 tokens
claude-compress last --n 10   # show last 10

Technique names:

Tag What it means
ansi ANSI color codes stripped
git Unchanged diff hunks folded
cargo Compiling lines collapsed
pytest Passing tests folded, failures kept
node npm install noise removed
json Null fields stripped, output minified
rle Repeated identical lines collapsed
blank Multiple blank lines collapsed
truncate Output truncated (head + tail kept)
dedup Identical content replaced with reference token

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" }
      ]}
    ],
    "Stop": [
      { "hooks": [
        { "type": "command",
          "command": "C:\\Users\\you\\AppData\\Roaming\\Python\\Python312\\Scripts\\claude-compress.exe gain" }
      ]}
    ]
  }
}

Session-end savings summary (Stop hook)

claude-compress init now also installs a Stop hook that prints a one-line savings summary at the end of every Claude Code session:

claude-compress: saved 11,130 tokens (62% reduction, 42 compressions)

No configuration needed — it's included automatically.

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
Source code files Language-aware comment/docstring stripping 15–50%
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

Source code compression

When Claude reads a source file (cat, head, tail), claude-compress detects the language and strips:

  • Standalone comment lines# …, // … lines that contain only comments
  • Block comments/* … */ blocks collapsed to a one-line summary
  • Multi-line docstrings — collapsed to the first sentence
  • Excess blank lines — 3+ consecutive blank lines → 1

Inline comments (x = 1 # important) and shebangs / encoding declarations are always kept.

Supported languages: Python, JavaScript, TypeScript, Go, Rust, Java, C, C++, C#, Swift, Kotlin, Ruby, PHP

# Before (cat src/auth.py — 800 tokens)
def verify_token(token: str) -> bool:
    """
    Verify that the provided JWT token is valid.

    This function checks the signature, expiry, and claims.
    It also validates the issuer and audience fields.
    """
    # First decode the header to find the algorithm
    # We support RS256 and HS256 only
    # See RFC 7519 for full JWT spec
    header = _decode_header(token)
    ...

# After (320 tokens — 60% reduction)
def verify_token(token: str) -> bool:
    """Verify that the provided JWT token is valid."""
    header = _decode_header(token)
    ...

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 gain [--hours N] One-line savings summary — shown at end of each session via Stop hook
claude-compress stats [--hours N] Full savings breakdown (default: last 24 h)
claude-compress last [--n N] Per-technique breakdown of the last N compressions (default: 5)
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.3.0.tar.gz (39.4 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.3.0-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: claude_compress-0.3.0.tar.gz
  • Upload date:
  • Size: 39.4 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.3.0.tar.gz
Algorithm Hash digest
SHA256 9ac205be733f796ac25a2607f7199cf18976c14ae4a3cb11298a654429436a3e
MD5 a1d25cd8f7aae1195310083917f8592b
BLAKE2b-256 0fe80cbcb85cd5d3e6e7684a7b10d9421d263896ec8de92ce98e549fdcd1ca09

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for claude_compress-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4f3b2efe1753793e0c8e9685465180d652fd4a47909530d64528b0eafe8b6292
MD5 f290a7fa2d190294e6764926445defa7
BLAKE2b-256 a05c57904c95fcf7647f752d59e519391d1da608436cce82e92c063f44c2f851

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