lowfat is a lightweight CLI tool that reduces AI token costs by filtering unnecessary CLI output before it reaches your agent.
Wrap commands as shell functions and pipe them through composable processors like grep, cut, head, and token-budget.
- Lightweight — Small single binary, small core; but extensible.
- Local-first — No telemetry; you own your data.
- Composable — UNIX-style pipes, mix built-ins and your own filters; not magic.
- User-owned —
lowfat historyshows what you run most; allow you to customize for your usecase.
cargo install lowfat
# or
brew install zdk/tools/lowfatPre-built binaries are also available on GitHub Releases.
Choose one of the following:
Add to .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "lowfat hook"
}
]
}
]
}
}echo 'eval "$(lowfat shell-init zsh)"' >> ~/.zshrc # or ~/.bashrcActivates automatically inside agent environments (CLAUDECODE=1, CODEX_ENV) — commands run normally otherwise.
lowfat git status
lowfat docker ps
lowfat ls -laThree levels control how aggressively output is compressed:
lowfat level # show current level
lowfat level ultra # set to ultra (most aggressive)
LOWFAT_LEVEL=lite lowfat git log # per-command override| Level | Behavior |
|---|---|
lite |
Gentle — keeps most context |
full |
Default — balanced filtering |
ultra |
Maximum compression — minimal output |
| Command | Shows |
|---|---|
config |
resolved config, validates .lowfat |
filters |
enabled/disabled filters |
pipeline <cmd> |
active pipeline for a command |
gain |
lifetime token savings report |
history |
plugin candidates, ranked (see below) |
audit |
recent plugin executions |
status |
compact status badge |
Optional. Create a .lowfat file in your project root (or any parent directory — lowfat walks up to find it). All built-in filters and plugins are active by default.
# Set intensity level (default: full)
level=ultra
# Filter any command with a pipeline
pipeline.deploy = grep:^(Deploy|ERROR|FAIL) | head:10All settings:
level=ultra # lite, full (default), ultra
disable=npm,cargo # disable specific filters (default: none)
filters=git,docker # whitelist mode — only these active (default: all)
pipeline.<cmd> = ... # per-command pipeline
pipeline.<cmd>.error = ... # when exit code != 0
pipeline.<cmd>.empty = ... # when output is empty
pipeline.<cmd>.large = ... # when output > 10KBdisable and filters are mutually exclusive — use one or the other, not both.
Run lowfat config to see the resolved config and validate your .lowfat file.
All settings can also be overridden with environment variables:
| Env var | Effect |
|---|---|
LOWFAT_LEVEL |
Override level (lite, full, ultra) |
LOWFAT_DISABLE |
Comma-separated filters to disable |
LOWFAT_HOME |
Plugin/config home (default: ~/.lowfat) |
LOWFAT_DATA |
Data directory for history db (default: ~/.local/share/lowfat) |
Env vars take priority over .lowfat file. History and gain data live at $LOWFAT_DATA/history.db (default ~/.local/share/lowfat/history.db) — delete the file to reset.
| Command | Raw | Filtered | Saved |
|---|---|---|---|
git status |
115t | 5t | 96% |
git diff |
2,376t | 115t | 95% |
git log |
379t | 118t | 69% |
cargo build |
558t | 18t | 96% |
cargo clippy |
2,023t | 292t | 85% |
cargo test |
1,499t | 171t | 88% |
docker ps |
271t | 41t | 85% |
ls -la |
192t | 30t | 84% |
lowfat history ranks your real usage by runs × avg tokens × (1 − savings) so commands that run often, produce a lot of output, and aren't being trimmed yet float to the top — exactly the ones worth writing a plugin for.
# command runs avg raw savings plugin
1 git status 12x 59 91.5% yes
2 ls 8x 211 0.9% yes
3 kubectl get 6x 4.2K 0.0% no
4 terraform plan 3x 12K 0.0% no
no-plugin rows are the best candidates. Only command + first non-flag arg is stored locally (capped at 10k rows) — never full arguments, output, or secrets.
Add a one-liner to .lowfat — no plugin needed:
# Your deploy script dumps a wall of rollout text
pipeline.deploy = grep:^(Deploy|ERROR|FAIL|Migrating) | head:10
# Custom test runner with non-standard output
pipeline.run-tests = grep:✗|failed|error|^\[suite\] | head:20
# Internal CLI with wide tables — only show what's broken
pipeline.acme = grep:degraded|down|error|total | head:10
# Log viewer spitting thousands of lines
pipeline.stern = grep:ERROR|WARN|panic|fatal | head:30
# CI script that prints every step
pipeline.ci-run = grep:^(STEP|PASS|FAIL|ERROR) | head:20
# Linter with lots of "ok" files
pipeline.lint = grep-v:^✓ | head:30
# Database migration tool
pipeline.migrate = grep:^(Migrating|Applied|Error|Already) | head:15
The command name matches what you pass to lowfat: lowfat deploy args..., lowfat run-tests --suite integration, etc. Command names must not contain dots (. separates command from condition suffix).
Use .error, .empty, .large suffixes to handle different output states:
pipeline.deploy = grep:complete|updated | head:5
pipeline.deploy.error = head:50 # exit code != 0
pipeline.deploy.empty = passthrough # no output
pipeline.deploy.large = grep:ERROR|FAIL | token-budget:500 # output > 10KB
| Processor | Syntax | Description |
|---|---|---|
grep |
grep:pattern |
Keep lines matching regex |
grep-v |
grep-v:pattern |
Remove lines matching regex |
head |
head:N |
First N lines |
truncate |
truncate:N |
First N characters per line |
cut |
cut:1,3 or cut:2-5 |
Extract fields (cut:,;1,3 for comma delimiter) |
strip-ansi |
strip-ansi |
Remove ANSI escape codes |
token-budget |
token-budget:N |
Trim to ~N tokens |
dedup-blank |
dedup-blank |
Collapse consecutive blank lines |
normalize |
normalize |
Trim whitespace, collapse blanks (runs automatically) |
redact-secrets |
redact-secrets |
Mask API keys, tokens, passwords |
For command-specific filtering beyond built-in processors, plugins are shell scripts that read raw output from stdin and write filtered output to stdout.
Bundled plugins: git-compact, docker-compact, ls-compact, npm-compact, go-compact, cargo-compact
lowfat plugin list # list installed plugins
lowfat plugin new terraform # scaffold a new plugin
lowfat plugin bench terraform # benchmark against sample files
lowfat plugin doctor # check plugin healthlowfat plugin new terraform creates ~/.lowfat/plugins/terraform/terraform-compact/ with:
lowfat.toml # manifest: name, commands, runtime
filter.sh # your filter logic (stdin → stdout)
samples/ # sample outputs for benchmarking
Plugins receive context via environment variables: $LOWFAT_LEVEL, $LOWFAT_COMMAND, $LOWFAT_SUBCOMMAND, $LOWFAT_ARGS, $LOWFAT_EXIT_CODE.
$LOWFAT_ARGS contains all arguments (e.g., get pods -n kube-system) — use it when the subcommand alone isn't enough to decide how to filter. See docs/PLUGINS.md for examples.
Plugins can be mixed with built-in processors in pipelines:
pipeline.git = strip-ansi | git-compact | truncate:100
Apache-2.0
AI tools were used for this project
