HOMEBREW-PANDAFILTER(1)

NAME

homebrew-pandafilterThe context intelligence layer for AI coding agents. Compressing noise, routing content to the right strategy,…

SYNOPSIS

$brew install pandafilter

INFO

85 stars
9 forks
0 views

DESCRIPTION

The context intelligence layer for AI coding agents. Compressing noise, routing content to the right strategy, preserving session state across compactions, and surfacing the files that actually matter.

README

PandaFilter

PandaFilter

The context intelligence layer for AI coding agents.

The layer between your tools and your AI. PandaFilter understands what's noise and what matters — compressing, routing, and preserving the right context so your agent thinks faster, costs less, and never loses its place.

Star PandaFilter on GitHub

Discord   License: MIT   Latest Release

Claude Code   Cursor   Windsurf   Gemini CLI   Codex   Cline   VS Code Copilot   OpenClaw


Install

brew tap AssafWoo/pandafilter
brew install pandafilter

Linux / any platform:

curl -fsSL https://raw.githubusercontent.com/AssafWoo/homebrew-pandafilter/main/install.sh | bash

First run: PandaFilter downloads the BERT model (90 MB, all-MiniLM-L6-v2) from HuggingFace and caches it at `/.cache/huggingface/`. Subsequent runs are instant.

Then wire it in — one command installs for every AI agent you have:

panda init --agent all

Auto-detects Claude Code, Cursor, Gemini CLI, Codex, Windsurf, Cline, OpenClaw, and VS Code Copilot. Skips anything that isn't installed. Or target one specifically:

panda init                          # Claude Code (default)
panda init --agent cursor           # Cursor
panda init --agent gemini           # Gemini CLI
panda init --agent codex            # Codex (CLI + VS Code extension)
panda init --agent windsurf         # Windsurf
panda init --agent cline            # Cline
panda init --agent openclaw         # OpenClaw
panda init --agent copilot          # VS Code Copilot

What PandaFilter Does

1. Intelligent Compression

Raw command output is filtered, deduplicated, and semantically compressed by a BERT-powered pipeline that understands what matters for your task — not just what matches a regex. When your AI agent runs pip install, cargo build, or npm install, PandaFilter intercepts the output and strips download progress, module graphs, and passing test lines. The agent sees a clean summary with errors, warnings, and results. Nothing useful is dropped.

2. Adaptive Routing (new in v1.3.0)

A content-aware router analyzes each output and activates only the strategies relevant to it: error-focus for test failures, dedup for log streams, structural digest for unchanged file re-reads, semantic summarization for prose. No more one-size-fits-all.

Enable with use_router = true in panda.toml.

3. Session Intelligence

PandaFilter learns your codebase's noise patterns across sessions. It tracks what you've read, what you've changed, and where the context pressure is building — adapting its compression strategy in real time.

New in v1.3.0: File re-reads now send diffs instead of full file content. Unchanged re-reads return structural digests (function/class signatures). Both happen automatically — no config needed.

4. Compaction Survival (new in v1.3.0)

When your agent's context fills up and auto-compacts, PandaFilter preserves what matters: edited files, error signatures, key decisions. The next session starts oriented, not blank.

Requires Claude Code and is installed automatically with panda init.


How it works

When your AI agent runs a command — pip install, cargo build, npm install — PandaFilter intercepts the output and removes everything the model doesn't need: download progress, module graphs, passing test lines, spinners. The agent sees a clean summary with errors, warnings, and results. Nothing useful is dropped.

No config changes. No workflow changes. Runs 100% locally.


See it in action

Run panda gain after a session to see your cumulative savings:

panda gain output


Token savings

Numbers from ccr/tests/handler_benchmarks.rs. Run panda gain to see your own live data.

OperationWithout PandaFilterWith PandaFilterSavings
pip install1,7879−99%
uv sync1,57415−99%
playwright test1,36719−99%
docker build1,80124−99%
swift build1,2189−99%
dotnet build4383−99%
cmake8505−99%
gradle build80317−98%
go test4,507148−97%
git merge1645−97%
pytest3,818162−96%
terraform plan3,926163−96%
npm install64825−96%
ember build3,377139−96%
cargo build1,92393−95%
cargo test2,782174−94%
git clone1398−94%
bazel build15012−92%
next build54953−90%
cargo clippy78693−88%
make54572−87%
git diff6,370861−86%
git push17324−86%
ls691102−85%
webpack882143−84%
vitest625103−84%
nx run-many1,541273−82%
turbo run build597115−81%
ruff check2,035435−79%
eslint4,393974−78%
grep2,925691−76%
helm install22454−76%
docker ps1,057266−75%
golangci-lint3,678960−74%
git log1,573431−73%
git status650184−72%
kubectl get pods2,306689−70%
vite build526182−65%
jest330114−65%
env1,155399−65%
mvn install4,5851,613−65%
brew install368148−60%
gh pr list774321−59%
biome lint1,503753−50%
tsc2,5981,320−49%
mypy2,0531,088−47%
stylelint1,100845−23%
Total81,88214,347−82%

What's new in v1.3.0

FeatureBeforeAfter (PandaFilter v1.3.0)
Bash outputFull outputCompressed by type (error-focus, dedup, stats, etc.)
File re-readsFull file every timeDelta diff or structural digest
Context compaction60–70% conversation lostSession digest preserved and restored
Filtering strategyFixed pipeline alwaysAdaptive router — right expert per content type
Quality visibilityToken savings onlyMulti-signal quality score in panda gain
Agent support7 agents8 agents — OpenClaw added

Commands

panda gain — see your token savings:

panda gain                    # overall summary
panda gain --breakdown        # per-command table
panda gain --history          # last 14 days
panda gain --insight          # categorized savings + top saves

panda doctor — diagnose the full installation in one command.

panda init --uninstall — remove hooks:

panda init --uninstall                  # Claude Code
panda init --agent cursor --uninstall   # Cursor

panda focus — opt-in: tells the agent which files matter for the current prompt, preventing unnecessary reads:

panda focus --enable             # enable for this repo
panda focus --disable            # disable (keeps index data)
panda focus --status             # show status + index age
panda focus --dry-run            # preview guidance without enabling

panda index — manually rebuild the file-relationship index:

panda index                      # full/incremental build for current repo

Other commands:

panda verify                            # check hook integrity
panda discover                          # scan history for unfiltered commands
panda run git status                    # run a command through PandaFilter manually
panda proxy git status                  # run raw (no filtering), record baseline
panda read-file src/main.rs --level auto  # preview read filtering
panda expand ZI_3                       # restore a collapsed block
panda noise                             # show learned noise patterns; --reset to clear
panda compress --scan-session           # compress current conversation context

Handlers (59 handlers)

59 handlers (70+ command aliases) in ccr/src/handlers/. Lookup cascade:

  1. User filters.panda/filters.toml or ~/.config/panda/filters.toml
  2. Exact match — direct command name
  3. Static alias table — versioned binaries, wrappers, common aliases
  4. BERT routing — unknown commands matched by embedding similarity
HandlerKeysKey behavior
cargocargobuild/clippy: errors (capped at 15) + warning count. test: failures + summary. nextest run: FAIL lines + Summary.
gitgitstatus: counts. log: --oneline, cap 50 with total. diff: 2 context lines, 200-line cap. clone/merge/checkout/rebase: compressed success or full conflict output.
gogotest: NDJSON streaming, FAIL blocks + summary. build: errors only.
emberemberbuild: errors + summary; drops fingerprint/asset spam. test: failures + summary. serve: serving URL only.
tsctscErrors grouped by file; deduplicates repeated TS codes. Build OK on clean. Injects --noEmit.
vitestvitestFAIL blocks + summary; drops lines.
jestjest, bun, deno failure blocks + summary; drops PASS lines.
pytestpytestFAILED node IDs + AssertionError + short summary. Injects --tb=short.
rspecrspecInjects --format json; example-level failures with message + location.
rubocoprubocopInjects --format json; offenses grouped by severity, capped.
rakerake, bundleFailure/error blocks + summary; drops passing test lines.
mypymypyErrors grouped by file, capped at 10 per file. Injects --no-color.
ruffruffViolations grouped by error code. format: summary line only.
uvuv, uvxStrips Downloading/Fetching/Preparing noise; keeps errors + summary.
pippip, poetry, pdm, condainstall: [complete — N packages] or already-satisfied short-circuit.
pythonpythonTraceback: keep block + final error. Detects and compresses tabular/CSV, pandas DataFrames, Word (.docx), Excel (.xlsx), and PowerPoint (.pptx) output. Long output: BERT.
eslinteslintErrors grouped by file, caps at 20 + [+N more].
nextnextbuild: route table collapsed. dev: errors + ready line.
playwrightplaywrightFailing test names + error messages; passing tests dropped. Injects --reporter=list.
prettierprettier--check: files needing formatting + count.
viteviteAsset chunk table collapsed, HMR deduplication.
webpackwebpackModule resolution graph dropped; keeps assets, errors, build result.
turboturboInner task output stripped; cache hit/miss per package + final summary.
nxnx, npx nxPassing tasks collapsed to [N tasks passed]; failing task output kept.
stylelintstylelintIssues grouped by file, caps at 40 + [+N more].
biomebiomeCode context snippets stripped; keeps file:line, rule, message.
kubectlkubectl, kget pods: aggregates to [N pods, all running] or problem-pods table with counts. Smart column selection, log anomaly scoring, describe key sections. events: warning-only, capped at 20.
terraformterraform, tofuplan: +/-/~ + summary. validate: short-circuits on success. output: compact key=value. state list: capped at 50.
awsaws, gcloud, azResource extraction; --output json injected for read-only actions.
ghghCompact tables for list commands; strips HTML from pr view.
helmhelmlist: compact table. status/diff/template: structured.
dockerdockerlogs: ANSI strip + BERT. ps/images: formatted tables + total size. build: errors + final image ID.
makemake, ninja"Nothing to be done" short-circuit; keeps errors. Injects --no-print-directory.
golangci-lintgolangci-lintDiagnostics grouped by file; runner noise dropped. Detects v1 text and v2 JSON formats.
prismaprismagenerate/migrate/db push structured summaries.
mvnmvnDrops [INFO] noise; keeps errors + reactor summary.
gradlegradleUP-TO-DATE tasks collapsed; FAILED tasks and errors kept.
npm/yarnnpm, yarninstall: package count; strips boilerplate.
pnpmpnpminstall: summary; drops progress bars.
brewbrewinstall/update: status lines + Caveats.
curlcurlJSON → type schema. Non-JSON: cap 30 lines.
grep / rggrep, rgCompact paths, per-file 100-match cap, line numbers preserved, [N matches in M files] summary. Injects --no-heading --with-filename. Match-centered line truncation.
findfindGroups by directory, caps at 50. Injects -maxdepth 8 if unset.
journalctljournalctlInjects --no-pager -n 200. BERT anomaly scoring.
psqlpsqlStrips borders, caps at 20 rows.
treetreeAuto-injects -I "node_modules|.git|target|...".
diffdiff+/-/@@ + 2 context lines, max 5 hunks.
jqjqArray: schema of first element + [N items].
envenvCategorized sections; sensitive values redacted.
lslsDrops noise dirs; top-3 extension summary.
loglogTimestamp/UUID normalization, dedup [×N], error summary block.
rsyncrsyncDrops per-file transfer progress lines (to-chk=, MB/s); keeps file list and final summary.
ffmpegffmpeg, ffprobeDrops frame= and size= real-time progress lines; keeps input/output codec info and final size line.
wgetwgetInjects --quiet if no verbosity flag set.
swiftswift, swift-build, swift-testbuild: errors/warnings + Build complete. test: failures + summary. package resolve: strips progress.
dotnetdotnet, dotnet-clibuild: errors grouped by CS code + summary. Short-circuits on clean build. test: failures + summary. restore: package count.
cmakecmake, cmake3configure: errors + final written-to line. --build: errors + [N targets built]. Auto-detects mode from args/output.
bazelbazel, bazelisk, bzlbuild: errors + completion summary [N actions, build OK (Xs)]. test: failures + [N passed, N failed]. query: cap at 30 targets.
Pipeline architecture
0. Hard input ceiling (200k chars — truncates before any stage)
1. Strip ANSI codes
2. Normalize whitespace
3. Global regex pre-filter (progress bars, spinners, download lines, decorators)
4. NDJSON streaming compaction (go test -json, jest JSON reporter)
5. Command-specific pattern filter
6. If over summarize_threshold_lines:
   6a. BERT noise pre-filter
   6b. Entropy-adaptive BERT summarization (up to 7 passes)
7. Hard output cap (50k chars)

Outputs under 15 tokens skip the pipeline entirely. Step 6b falls back to head+tail if BERT is unavailable.

Pre-run cache (fires before execution): git, kubectl, docker, and terraform commands are hashed against live state. A hit skips execution entirely and returns the cached output with a [PC: cached from Xm ago] marker.

Configuration

Config loaded from: ./panda.toml~/.config/panda/config.toml → embedded default.

[global]
summarize_threshold_lines = 50
head_lines = 30
tail_lines = 30
strip_ansi = true
normalize_whitespace = true
deduplicate_lines = true
input_char_ceiling = 200000
output_char_cap = 50000
# cost_per_million_tokens = 15.0

v1.3.0: Adaptive MoE router (opt-in)

use_router = true # enable adaptive expert routing

router_exploration_noise = true # prevent expert collapse in long sessions

[tee] enabled = true mode = "aggressive" # "aggressive" | "always" | "never"

[read] mode = "auto" # "passthrough" | "auto" | "strip" | "aggressive" | "structural"

v1.3.0: delta mode (re-reads send diffs) and structural mode (signature-only) are

now active automatically — no config change needed.

[focus] enabled = false # disabled by default — enable with panda focus --enable after testing min_files = 25 # skip for repos smaller than this min_lines = 2000 # skip for repos with fewer source lines

[commands.git] patterns = [ { regex = "^(Counting|Compressing|Receiving|Resolving) objects:.*", action = "Remove" }, ]

[commands.cargo] patterns = [ { regex = "^\s+Compiling \S+ v[\d.]+", action = "Collapse" }, { regex = "^\s+Downloaded \S+ v[\d.]+", action = "Remove" }, ]

Pattern actions: Remove, Collapse, ReplaceWith = "text", TruncateLinesAt = N, HeadLines = N, TailLines = N, MatchOutput = "msg", OnEmpty = "msg".

Pricing uses cost_per_million_tokens from panda.toml if set, otherwise ANTHROPIC_MODEL env var (Opus 4.6: $15, Sonnet 4.6: $3, Haiku 4.5: $0.80), otherwise $3.00.

User-defined filters

Place filters.toml at .panda/filters.toml (project-local) or ~/.config/panda/filters.toml (global). Project-local overrides global for the same key. Runs before any built-in handler.

[commands.myapp]
patterns = [
  { regex = "^DEBUG:",            action = "Remove" },
  { regex = "^\\S+\\.ts\\(",     action = "TruncateLinesAt", max_chars = 120 },
]
on_empty = "(no relevant output)"

[commands.myapp.match_output] pattern = "Server started" message = "ok — server ready" unless_pattern = "error"

Session intelligence

State tracked via PANDA_SESSION_ID=$PPID, stored at ~/.local/share/panda/sessions/<id>.json.

  • Result cache — post-pipeline bytes frozen per input hash; returned identically on repeat calls to prevent prompt cache busts.
  • Semantic delta — repeated commands emit only new/changed lines: [Δ from turn N: +M new, K repeated — ~T tokens saved].
  • Cross-turn dedup — identical outputs (cosine > 0.92) collapse to [same output as turn 4 (3m ago) — 1.2k tokens saved].
  • Elastic context — pipeline pressure scales with session size. At >80% pressure: [⚠ context near full — run panda compress --scan-session].
  • Intent-aware query — reads the agent's last message from the live session JSONL and uses it as the BERT query.
  • File delta re-reads (v1.3.0) — re-reading a changed file sends a unified diff instead of the full content. Unchanged re-reads send a structural digest (function/class signatures). Both save 60–95% of re-read tokens automatically.
  • Compaction digest (v1.3.0, Claude Code only) — before Claude auto-compacts, PandaFilter serializes edited files, error signatures, and top commands to ~/.local/share/panda/compacts/. On the next session start, the digest is injected into context so the agent resumes oriented.
Supported agents (7)

All agents share the same binary and filtering pipeline. panda init --agent all installs for everything detected on your machine in one shot.

AgentInstallConfig
Claude Codepanda init~/.claude/settings.json
Cursorpanda init --agent cursor~/.cursor/hooks.json
Gemini CLIpanda init --agent gemini~/.gemini/settings.json
Codex (CLI + VS Code)panda init --agent codex~/.codex/hooks.json
Windsurfpanda init --agent windsurf~/.codeium/windsurf/hooks.json
Clinepanda init --agent cline.clinerules (project dir)
VS Code Copilotpanda init --agent copilot.github/hooks/ (project dir)

Hook-based agents (Claude Code, Cursor, Gemini, Codex, Windsurf) intercept every command before and after execution via the agent's native hook system.

Rules-based agents (Cline, Copilot) inject panda run <cmd> directives into the agent's context file, relying on the model to follow them.

PreToolUse: known handler → rewrites to panda run <cmd>; unknown → no-op; already wrapped → no double-wrap; compound commands → each segment rewritten independently.

PostToolUse: Bash → full pipeline; Read → BERT + session dedup; Glob → grouped by directory; Grep → compact paths.

UserPromptSubmit: Context Focusing module → queries file graph → injects guidance (recommended + excluded files).

Hook integrity: panda init writes SHA-256 baselines (chmod 0o444). PandaFilter verifies at every invocation and exits 1 with a warning if tampered. panda verify checks all installed agents.

Crate overview
ccr/        CLI binary (panda) — handlers, hooks, session state, commands
ccr-core/   Core library (no I/O) — pipeline, BERT summarizer, config, analytics
ccr-sdk/    Conversation compression — tiered compressor, deduplicator, Ollama
ccr-eval/   Evaluation suite — fixtures against Claude API
config/     Embedded default filter patterns
Uninstall
panda init --uninstall                            # Claude Code
panda init --agent cursor   --uninstall           # Cursor
panda init --agent gemini   --uninstall           # Gemini CLI
panda init --agent codex    --uninstall           # Codex
panda init --agent windsurf --uninstall           # Windsurf
panda init --agent cline    --uninstall           # Cline
panda init --agent copilot  --uninstall           # VS Code Copilot

brew uninstall pandafilter && brew untap AssafWoo/pandafilter   # Homebrew
# or: cargo uninstall panda

rm -rf ~/.local/share/panda                   # analytics + sessions
rm -rf ~/.cache/huggingface/hub/models--sentence-transformers--all-MiniLM-L6-v2

FAQ

Does PandaFilter change what the agent can see? It removes noise — build progress, passing test lines, module download logs. Errors, file paths, and results are always kept.

What if I don't want a specific command filtered? Add a rule to .panda/filters.toml to customize or override any handler. See the User-defined filters section. You can also use panda proxy <cmd> to run a command raw with no filtering.

What about commands PandaFilter doesn't know? Output passes through unchanged. PandaFilter never silently drops output from unknown commands.

How do I verify it's working? Run panda gain after a session. To see exactly what the agent received from a specific command: panda run git log --oneline -20.

Does PandaFilter send any data outside my machine? No. All processing is fully local. BERT runs on-device.

What is Context Focusing? An opt-in feature that tells the agent which files are relevant for the current prompt, preventing it from reading unrelated files. Enable with panda focus --enable after running panda doctor to confirm the index is ready.


Why PandaFilter? Why Panda?

AI coding sessions are expensive — not because of what you ask, but because of what the agent reads back. Every cargo build or npm install dumps thousands of tokens of noise into the context window. I built PandaFilter to strip that out automatically.

The name comes from how a panda eats: it consumes enormous amounts of raw material and extracts only what it needs.

Assaf Petronio · github.com/AssafWoo


Contributing

Open an issue or PR on GitHub. To add a handler: implement the Handler trait and register it in ccr/src/handlers/mod.rs — see git.rs as a template.


License

MIT — see LICENSE.

SEE ALSO

clihub4/27/2026HOMEBREW-PANDAFILTER(1)