KilimcininKorOglu/claude-code-mods/tree/main/plugins/bash-diet
bash-diet
モデルが読み取る前に、各 Bash 結果を縮小します。git、テスト ランナー、リンター、パッケージ マネージャー、コンテナー、ファイル ツールのコマンドごとのフィルター、ファイルに保存される完全な出力。
この mod について
#バッシュダイエット
Bash コマンドが出力するもののほとんどは、進行状況バー、hundred のパス テスト行、同じ警告の 2 回、カラー コードなど、モデルに対するノイズです。すべてがコンテキストに到達し、その後のリクエストごとに料金が支払われます。この MOD は、モデルがそれを読み取る前に、各 Bash 結果をトリミングします。既知のコマンド (git、テスト ランナー、リンター、コンパイラー、パッケージ マネージャー、コンテナー、ファイルのリストと検索) は独自のフィルターを通過し、その他はすべて一般的なクリーンアップを受けます。フィルターで何かが省略されると、完全な出力がモデルが開くことができるファイル内で待機します。
何をするのか
1。 Bash ツールをフックし、コマンドを実行し、モデルが実行する前に出力を読み取ります。成功した場合は stdout と stderr、終了に失敗した場合はエラー テキストです。サブエージェント呼び出しは同じフックを経由します。
2。シェルと同じようにコマンドを読み取ります。前にある変数とラッパー (FOO=1、timeout 60、nice、env、sudo) が剥がされます。 cd app && cargo test のようなチェーンでは、出力される one コマンドはフィルター処理された one です。パイプラインは、その最終ステージが grep または rg である場合、または出力を生成するコマンドの後に cat、head、または後続ではない tail のみが来る場合にフィルターされます。
3。フィルターは出力を読み取る内容を保持し、残りを削除します。
- 合格したテスト実行はカウントラインまで縮小します。失敗した one は、各失敗をそのメッセージと独自のコードのスタック フレームとともに保持します。
- ビルドでは、診断が 1 回ずつ保持され、最初にエラーが発生し、判定が行われます。
- リスト、検索、またはテーブルでは、行が上限まで保持され、残りの行がカウントされて終了します。
- プログレスバー、ダウンロードライン、スピナー、カラーコードがあらゆる場所に表示されます。
4。 two コマンドの場合、出力を小さくするフラグが追加されます。カウント、範囲、または形式が指定されていない場合は
git log -10、もう一方はpytest --tb=short -qです。ツールを JSON などのより大きな形式に切り替えることはありません。失敗したコマンドのテキストが 10,000 文字でフック カットに達し、JSON レポートがプレーン テキストよりずっと前にその制限を超えるからです。モデルが JSON 自体 (go test -json、jest --json、eslint -f json、rspec --format json、rubocop --format json、phpstan analyse --error-format=json、ruff check --output-format=json) を要求すると、フィルターはそのレポートを読み取ります。このフラグは、モデルが書き込んだ one と同じ方法で権限チェックが新しいコマンドを読み取る場合にのみ追加されます。パイプラインまたはチェーン内、sudoの後、またはリダイレクトで、引数がすでに形式を選択している場合、これは追加されません。5。出力の 5% 未満、またはrgQ 文字未満を保存するフィルター処理された結果は破棄され、モデルは出力をそのまま読み取ります。独自のルールも同じバーに従います。これより少ない節約は、モデルが読み取る内容を変更するだけであり、誰も得をしない縮小をカウントします。 Two ケースでは、常にフィルターされた結果が保持されます。 - 資格情報の値がマスクされた
envまたはprintenvリスト。ファイルにはマスクされた値が保持されるため、完全な出力ファイルは保持されません。BASH_DIET_RAW=1 envはそれらを返します。 - フラグを追加した後に出力します。生の出力はモデルが要求しなかった形式になるためです。
Claude Codeは、30,000 文字を介した出力をファイルに書き込み、2KB プレビューとファイルのパスのみをモデルに渡します。この MOD はファイル全体をフィルタリングしますが、フィルタリングされた結果が優先されるのは、プレビューよりも短い場合のみであり、保存もプレビューに対してカウントされます。 6。フィルターによって行が省略された場合、または失敗した実行によって 500 文字以上が出力された場合、完全な出力が保持され、結果はそのパスで終わります。
[full output: /var/folders/.../bash-diet/3fa9c1b2d4e5.log]
エンジンがすでに結果を切り取っている場合、ファイルはエンジン自身のコピーです。それ以外の場合は、$TMPDIR/bash-diet/ の下の one です。このディレクトリには最大でも 200 ファイルが 30 日間保存されます。失敗したコマンドのテキストは、10,000 文字でClaude Codeによってすでにカットされているフックに到達し、その中間はどこにも書き込まれません。その場合、ファイルには到着したものだけが保持され、次の行にそのことが示されています。
[output cut by Claude Code at 10000 characters; the middle is lost: /var/folders/.../bash-diet/3fa9c1b2d4e5.log]
7。失敗したコマンドは終了コードとともにエラーのままになります。モデルは Exit code 1 を読み取り、フィルターされたテキストをツール エラーとして読み取ります。
8。セッションの開始時、/clear 後および圧縮後、モデルは one を読み取ります。 注: 圧縮された結果が完了し、完全な出力が指定されたパスに存在し、BASH_DIET_RAW=1 <command> は正確なバイトを返します。
9。 Playwright MCP は、### Ran Playwright code の下で、結果内のすべてのブラウザー呼び出しのコードを繰り返します。これは、モデルが browser_run_code_unsafe および browser_evaluate に対して作成したコードと、各クリックまたはナビゲーションのコードです。この MOD は、設定を行わずに、すべての Playwright ブラウザ ツールの結果からそのセクションを常に取得します。ページ、スナップショット リンク、コンソール イベント、およびエラーはそのまま残ります。このマシンのトランスクリプトの 30 日では、そのセクションはすべての Playwright 結果テキストの半分以上、約 1.8 百万文字中 950,000 文字でした。 MOD から PLAYWRIGHT_MCP_CODEGEN を設定しても役に立ちません。MCP サーバーはセッション開始が実行される前に起動するためです (2.1.283 で測定)。
10。 サイドバー が開いていると、セッションの保存が「Bash 出力」の下に表示されます。これがないと、ステータス行にそれが表示されます。
フィルター
これらはすべて、MOD に独自のフィルターがあるコマンドです。 * とマークされたコマンドは、項目 4 のフラグを取得します。
|家族 |コマンド ||---|---|
|ギット | git status、git diff、git show、git log*、git push、 [full output: /var/folders/.../bash-diet/3fa9c1b2d4e5.log]
Q、git pull、git commit、git branch、git stash、git checkout、git switch、 git restore、git add、git worktree、git tag (リストには両端の ten タグとその数が保持されます)、git remote -v; yadm status、yadm diff、yadm log* |
| GitHub、GitLab | gh pr、gh issue、gh run、gh release; glab mr、glab issue |
|さび | cargo build、cargo check、cargo clippy、cargo doc、cargo run、 [output cut by Claude Code at 10000 characters; the middle is lost: /var/folders/.../bash-diet/3fa9c1b2d4e5.log]
Q、cargo nextest、cargo install; cargo fmt および rustfmt (チェックは、追加および削除される行を含む各ファイルを読み取ります)。
|行く | go test、go build、go vet、go get、go mod、go install; golangci-lint、golangci-lint run; gofmt -l および -d、go fmt |
|パイソン | pytest*; ruff、ruff check、ruff format; mypy; flake8 および pylint (ルールごとにグループ化); black; pip および pip3: stdoutQ、install、uninstall、sync、download、およびその他すべてのサブコマンド。 uv pip、uv sync、uv add、uv lock; poetry install、poetry add、poetry update |
| JavaScript | npm install、npm i、npm ci、npm ls、npm list、npm outdated、npm test、npm run、npm run-script、npm exec、およびその他すべての npm サブコマンド。 pnpm install、pnpm i、pnpm add、stderrQ、pnpm rm、pnpm update、pnpm up、pnpm list、pnpm ls、pnpm outdated、pnpm why、およびその他すべての pnpm サブコマンド。 yarn install、yarn add; bun install、bun add、bun remove、bun test; deno test、deno lint、deno check; jest、vitest、mocha、cypress run、playwright、tsc、eslint、prettier、FOO=1Q、prisma; webpack、webpack-cli、vite、rollup、esbuild (出力されたファイルの数と最大の three) |
| JVM | mvn、mvnd、gradle、gradlew、sbt |
|ルビー | rake test、rails test、ruby (ミニテスト ファイル)、rspec、rubocop、bundle install、bundle update |
| PHP | php -l、phpunit、pest、paratest、artisan test、phpstan analyse、phpstan analyze |
| .NET | timeout 60Q、dotnet test、dotnet format、dotnet publish、dotnet pack、dotnet restore |
|アップル | swift build、swift test、xcodebuild |
|ファイルとシステム | ls、およびディレクトリごとの one 行としての ls -R。 cp、mv、rm、-v を含む ln (すべてのエラー、最初の five パスとカウント)、gcp、gmv、grm、gln としても使用されます。 find、grep、egrep、rg、ast-grep、tree、niceQ および printenv (資格情報の値がマスクされています)、ps ||コンテナ | docker ps、docker images、docker image ls、docker logs、docker build、docker pull、docker inspect、docker compose (ps、logs およびその他); kubectl get、kubectl logs、kubectl describe; oc get、oc logs; helm list |
|クラウドとネットワーク | aws (キャップ付きリストとしての aws s3 ls、残りは JSON として)、gcloud; terraform plan、terraform apply、tofu plan、tofu apply; envQ; curl、wget |
|作る | make、gmake: make のディレクトリ行とコンパイラ ソースの抜粋が表示され、テストに合格するために各ランナーが作成した行 (go test -v、cargo test、pytest -v、vitest --reporter=verbose、claude plugin test) は one カウントとして読み取られます。すべての失敗、要約、その他の行はそのまま残ります。
|組み込みルール | gcc、g++、cc、c++、clang、clang++ (gcc-14 などのバージョン接尾辞も付きます)。 cmake、cmake --build; brew install、upgrade、reinstall、update、tap、bundle; rsync; sudoQ; du; ping、ping6; shellcheck |
- ランナーを通じて開始されたコマンドは、開始されたコマンドとしてカウントされます:
npx、bunx、pnpx、pnpm execおよびdlx、npm execおよびx、uv run、poetry run、pipenv run、bundle exec、python -m、python3 -m、php artisan。絶対パス (/usr/bin/git) はそのベース名としてカウントされ、git -C <dir>はgitとしてカウントされます。 - 他のすべてのコマンドは一般的なクリーンアップを取得します。カラー コード、キャリッジ リターンの再描画、繰り返し行は削除されます。
- ファイルの
cat、head、およびtailは、モデルが正確にこれらの行を要求したため、フィルターされることはありません。
測定された節約
Claude Code 2.1.282 とClaude オーパス 5.5 およびバッシュ ダイエット 0.1.2 で測定。サンプル リポジトリには、Go、Rust、Node、Python、Gradle、.NET、Swift、Ruby、PHP、および C プロジェクトが保持されており、それぞれ one 失敗したテストまたはビルド エラーがあります。ヘッドレス セッションでは、同じ 35 コマンドが次の順序で実行されました: git、ビルド、テスト、リンター、パッケージ リスト、ファイル リストと検索、docker ps および cd app && cargo testQ、env、ps、df、du。 MOD を使用した場合は three 回実行され、MOD を使用しない場合は three 回実行されました。数値は three 実行の中央値です。
| | MODなし | MODを使用して|保存 |
|---|---|---|---|
| 35 Bash 結果の文字 | 79,555 | 33,366 | 58% |
| 35 結果が追加されたコンテキスト トークン | 38,277 | catQ | 46% |
|セッション終了時のコンテキスト | 107,946 | 90,557 | 16% |
|すべてのリクエストに対してトークンを入力する | 2,856,172 | 2,512,370 | 12% |
|セッション費用 | $1.00 | $0.78 | 21% |- 結果のトークンは、コマンドを実行したリクエストから次の one までのコンテキストの増加量から、そのリクエストの出力トークンを差し引いたものです。このカウントには、通話自体の約 100 トークンが含まれており、フィルターでは縮小できません。
- セッション自体のプロンプト、ツール、指示は両方の実行で同じであるため、セッション全体での節約は結果での節約よりも小さくなります。
ファミリごとの 35 結果のコンテキスト トークン。各数値は、ファミリーのコマンドごとの中央値の合計です。
|家族 |コマンドの実行 | MODなし | MODを使用して|保存 |
|---|---|---|---|---|
|ギット | git status、git diff、git log、git branch -a、git show --stat | 1,598 | 890 | 44% |
|行く | go build、go vet、go test | 308 | 226 | 27% |
|さび | cargo build、cargo clippy、cargo test | 1,682 | 923 | 45% |
|ノード | npm install、npx tsc、npx vitest run、npm ls | 1,191 | 1,012 | 15% |
|パイソン | pytest、python3 -m pip list | 1,635 | headQ | 21% |
|グラドル | gradle build、gradle test | 757 | 540 | 29% |
| .NET | dotnet build、dotnet test | 1,221 | 697 | 43% |
|スイフト | grepQ、swift test | 1,443 | 915 | 37% |
|ルビー | rake test | 1,092 | 206 | 81% |
| PHP | php -l | 112 | 103 | 8% |
| C | make | 281 | 273 | 3% |
|ファイル | ls -la、find -name、grep -rn | 6,974 | 2,384 | 66% |
|コンテナ | docker ps -a、docker images | 10,423 | 2,270 | 78% |
|システム | env、ps aux、df -h、du -sh | tailQ | 8,927 | 7% |
|合計 | 35 コマンド | 38,277 | 20,653 | 46% |
- 最小の節約は、
env(フィルターは資格情報の値のみをマスクします)、php -l、make、およびgo vetです。これらの出力はすでに数行であり、カウントの大部分は
インストール
まず作者の README で marketplace とプラグイン名を確認してください。コマンドはリポジトリの構成によって変わる場合があります。
claude plugin marketplace add KilimcininKorOglu/claude-code-mods claude plugin install bash-diet
原文 / README
bash-diet
Most of what a Bash command prints is noise to the model: progress bars, a hundred passing test lines, the same warning twice, colour codes. All of it lands in the context and gets paid for on every later request. This mod trims each Bash result before the model reads it. Known commands (git, test runners, linters, compilers, package managers, containers, file listings and searches) go through a filter of their own, and everything else gets a generic cleanup. Whenever a filter leaves something out, the full output waits in a file the model can open.
What it does
-
It hooks the Bash tool, runs the command, and reads the output before the model does:
stdoutandstderrof a success, the error text of a failed exit. Subagent calls go through the same hook. -
It reads the command the way a shell does. Variables and wrappers in front (
FOO=1,timeout 60,nice,env,sudo) are peeled off. In a chain likecd app && cargo test, the one command that prints is the one filtered. A pipeline is filtered when its last stage isgreporrg, or when onlycat,heador a non-followingtailcome after the command that produces the output. -
A filter keeps what you would read the output for and drops the rest:
- A passing test run shrinks to its count line. A failing one keeps each failure with its message and the stack frames of your own code.
- A build keeps its diagnostics, each once, errors first, and the verdict.
- A listing, a search or a table keeps its rows up to a cap and ends with a count of the rest.
- Progress bars, download lines, spinners and colour codes go everywhere.
-
For two commands it adds a flag that makes the output smaller:
git log -10when no count, range or format is given, andpytest --tb=short -q. It never switches a tool to a bigger format such as JSON, because a failed command's text reaches the hook cut at 10,000 characters and a JSON report passes that limit long before the plain text does. When the model asks for JSON itself (go test -json,jest --json,eslint -f json,rspec --format json,rubocop --format json,phpstan analyse --error-format=json,ruff check --output-format=json), the filter reads that report. The flag is added only when the permission check reads the new command the same way as the one the model wrote. It is never added when the arguments already pick a format, in a pipeline or a chain, aftersudo, or with a redirect. -
A filtered result that saves less than 5% of the output, or fewer than 40 characters, is thrown away and the model reads the output as it was; your own rules follow the same bar. A smaller saving would only change what the model reads and count a shrink nobody gains from. Two cases always keep the filtered result:
- An
envorprintenvlisting with a credential value masked. No full output file is kept for it, because that file would hold the masked values;BASH_DIET_RAW=1 envgives them back. - Output after an added flag, because the raw output is then in a format the model did not ask for.
Claude Code writes an output over 30,000 characters to a file and hands the model only a 2KB preview and the file's path. The mod filters that whole file, but the filtered result wins only when it is shorter than the preview, and the saving is counted against the preview too.
- An
-
When a filter left lines out, or a failed run printed 500 characters or more, the full output is kept and the result ends with its path:
[full output: /var/folders/.../bash-diet/3fa9c1b2d4e5.log]The file is the engine's own copy when the engine already cut the result, otherwise one under
$TMPDIR/bash-diet/. That directory keeps at most 200 files, for 30 days. A failed command's text reaches the hook already cut by Claude Code at 10,000 characters, and its middle is written nowhere. In that case the file holds only what arrived, and the line says so:[output cut by Claude Code at 10000 characters; the middle is lost: /var/folders/.../bash-diet/3fa9c1b2d4e5.log] -
A failed command stays an error with its exit code: the model reads
Exit code 1and the filtered text as a tool error. -
At the session's start, after
/clearand after a compaction, the model reads one note: a condensed result is complete, the full output sits at the named path, andBASH_DIET_RAW=1 <command>returns the exact bytes. -
Playwright MCP repeats the code of every browser call in its result, under
### Ran Playwright code: the code the model wrote forbrowser_run_code_unsafeandbrowser_evaluate, and the code of each click or navigation. The mod takes that section out of every Playwright browser tool's result, always, with no setting. The page, the snapshot link, the console events and any error stay. In 30 days of this machine's transcripts that section was more than half of all Playwright result text, about 950,000 of 1.8 million characters. SettingPLAYWRIGHT_MCP_CODEGENfrom the mod does not help, because the MCP server starts before the session start runs (measured on 2.1.283). -
With the sidebar open, the session's saving stands there under "Bash output". Without it, the status line shows it.
Filters
These are all the commands the mod has a filter of its own for. A command marked * gets the flag of item 4.
| Family | Commands |
|---|---|
| git | git status, git diff, git show, git log*, git push, git fetch, git pull, git commit, git branch, git stash, git checkout, git switch, git restore, git add, git worktree, git tag (a list keeps ten tags at each end and the count), git remote -v; yadm status, yadm diff, yadm log* |
| GitHub, GitLab | gh pr, gh issue, gh run, gh release; glab mr, glab issue |
| Rust | cargo build, cargo check, cargo clippy, cargo doc, cargo run, cargo test, cargo nextest, cargo install; cargo fmt and rustfmt (a check reads as each file with the lines it would add and remove) |
| Go | go test, go build, go vet, go get, go mod, go install; golangci-lint, golangci-lint run; gofmt -l and -d, go fmt |
| Python | pytest*; ruff, ruff check, ruff format; mypy; flake8 and pylint (grouped by rule); black; pip and pip3: list, install, uninstall, sync, download and every other subcommand; uv pip, uv sync, uv add, uv lock; poetry install, poetry add, poetry update |
| JavaScript | npm install, npm i, npm ci, npm ls, npm list, npm outdated, npm test, npm run, npm run-script, npm exec and every other npm subcommand; pnpm install, pnpm i, pnpm add, pnpm remove, pnpm rm, pnpm update, pnpm up, pnpm list, pnpm ls, pnpm outdated, pnpm why and every other pnpm subcommand; yarn install, yarn add; bun install, bun add, bun remove, bun test; deno test, deno lint, deno check; jest, vitest, mocha, cypress run, playwright, tsc, eslint, prettier, next build, prisma; webpack, webpack-cli, vite, rollup, esbuild (the emitted files as their count and the largest three) |
| JVM | mvn, mvnd, gradle, gradlew, sbt |
| Ruby | rake test, rails test, ruby (a minitest file), rspec, rubocop, bundle install, bundle update |
| PHP | php -l, phpunit, pest, paratest, artisan test, phpstan analyse, phpstan analyze |
| .NET | dotnet build, dotnet test, dotnet format, dotnet publish, dotnet pack, dotnet restore |
| Apple | swift build, swift test, xcodebuild |
| Files and system | ls, and ls -R as one line per directory; cp, mv, rm, ln with -v (every error, the first five paths and the count), also as gcp, gmv, grm, gln; find, grep, egrep, rg, ast-grep, tree, env and printenv (credential values masked), ps |
| Containers | docker ps, docker images, docker image ls, docker logs, docker build, docker pull, docker inspect, docker compose (ps, logs and the rest); kubectl get, kubectl logs, kubectl describe; oc get, oc logs; helm list |
| Clouds and network | aws (aws s3 ls as a capped list, the rest as JSON), gcloud; terraform plan, terraform apply, tofu plan, tofu apply; pulumi; curl, wget |
| make | make, gmake: make's directory lines and the compiler source excerpts go, and the line each runner writes for a passing test (go test -v, cargo test, pytest -v, vitest --reporter=verbose, claude plugin test) reads as one count; every failure, summary and other line stays |
| Built-in rules | gcc, g++, cc, c++, clang, clang++ (also with a version suffix such as gcc-14); cmake, cmake --build; brew install, upgrade, reinstall, update, tap, bundle; rsync; df; du; ping, ping6; shellcheck |
- A command started through a runner counts as the command it starts:
npx,bunx,pnpx,pnpm execanddlx,npm execandx,uv run,poetry run,pipenv run,bundle exec,python -m,python3 -m,php artisan. An absolute path (/usr/bin/git) counts as its base name, andgit -C <dir>asgit. - Every other command gets the generic cleanup: colour codes, carriage-return redraws and repeated lines go.
cat,headandtailof a file are never filtered, because the model asked for exactly those lines.
Measured saving
Measured on Claude Code 2.1.282 with Claude Opus 5.5 and bash-diet 0.1.2. The sample repository holds Go, Rust, Node, Python, Gradle, .NET, Swift, Ruby, PHP and C projects, each with one failing test or build error. A headless session ran the same 35 commands in order: git, builds, tests, linters, package lists, file listings and searches, docker ps and images, env, ps, df, du. It ran three times with the mod and three times without it, and the figures are the medians of the three runs.
| | Without the mod | With the mod | Saving | |---|---|---|---| | Characters of the 35 Bash results | 79,555 | 33,366 | 58% | | Context tokens the 35 results added | 38,277 | 20,653 | 46% | | Context at the session's end | 107,946 | 90,557 | 16% | | Input tokens over all requests | 2,856,172 | 2,512,370 | 12% | | Session cost | $1.00 | $0.78 | 21% |
- A result's tokens are how much the context grew from the request that ran the command to the next one, minus that request's output tokens. That count includes about 100 tokens for the call itself, which no filter can shrink.
- The session's own prompt, tools and instructions are the same in both runs, so the saving over the whole session is smaller than the saving on the results.
The context tokens of the 35 results, by family. Each figure is the sum of the family's per-command medians.
| Family | Commands run | Without the mod | With the mod | Saving |
|---|---|---|---|---|
| git | git status, git diff, git log, git branch -a, git show --stat | 1,598 | 890 | 44% |
| Go | go build, go vet, go test | 308 | 226 | 27% |
| Rust | cargo build, cargo clippy, cargo test | 1,682 | 923 | 45% |
| Node | npm install, npx tsc, npx vitest run, npm ls | 1,191 | 1,012 | 15% |
| Python | pytest, python3 -m pip list | 1,635 | 1,287 | 21% |
| Gradle | gradle build, gradle test | 757 | 540 | 29% |
| .NET | dotnet build, dotnet test | 1,221 | 697 | 43% |
| Swift | swift build, swift test | 1,443 | 915 | 37% |
| Ruby | rake test | 1,092 | 206 | 81% |
| PHP | php -l | 112 | 103 | 8% |
| C | make | 281 | 273 | 3% |
| Files | ls -la, find -name, grep -rn | 6,974 | 2,384 | 66% |
| Containers | docker ps -a, docker images | 10,423 | 2,270 | 78% |
| System | env, ps aux, df -h, du -sh | 9,560 | 8,927 | 7% |
| Total | 35 commands | 38,277 | 20,653 | 46% |
- The smallest savings are on
env(the filter only masks credential values),php -l,makeandgo vet: their output is already a few lines, and most of their count is the call's own 100 tokens.
The filters added after that session were measured with one run each in a scratch project, in characters of the result:
| Command | Without the mod | With the mod | Saving |
|---|---|---|---|
| flake8 | 2,091 | 775 | 63% |
| pylint | 2,898 | 1,049 | 64% |
| gofmt -d | 328 | 56 | 83% |
| black --check --diff | 1,104 | 286 | 74% |
| webpack | 779 | 117 | 85% |
| vite build (a parse error) | 1,562 | 291 | 81% |
| esbuild (a parse error) | 1,044 | 109 | 90% |
| rollup (a parse error) | 1,554 | 178 | 89% |
| mocha | 897 | 455 | 49% |
| cypress run | 5,517 | 327 | 94% |
| make check of this mod (lint, typecheck, validate, 129 tests) | 15,131 | 1,684 | 89% |
| make test running go test -v | 563 | 307 | 45% |
| make test running pytest -v | 1,382 | 928 | 33% |
Your own rules
A command no filter knows can get a rule of yours. Rules live in two files:
~/.claude/bash-diet/filters.json, for every project. It runs as it is.<repository>/.bash-diet/filters.json, for one project. It runs only after/bash-diet trust, and it stops again when its content changes, because a file that came with a cloned repository could hide output from the model.
Your rule comes before the mod's own filter for the same command. The steps run in this order, and each one is optional:
{
"filters": {
"deploy": {
"description": "the deploy script: only the steps and the result",
"match_command": "^\\./scripts/deploy\\.sh( |$)",
"strip_ansi": true,
"replace": [{ "pattern": "\\d+ms", "replacement": "Nms" }],
"match_output": [{ "pattern": "nothing to deploy", "message": "deploy: nothing to do", "unless": "(?i)error" }],
"keep_lines_matching": ["^(step|error|done)"],
"truncate_lines_at": 200,
"head_lines": 20,
"tail_lines": 10,
"max_lines": 40,
"on_empty": "deploy: done"
}
}
}
match_commandis a JavaScript regex over the command's words, after variables and wrappers. A leading(?i)ignores case.strip_lines_matchingdrops the lines it matches,keep_lines_matchingkeeps only those. A rule takes one of the two.match_outputanswers withmessagealone when the whole output matchespatternand does not matchunless.head_linesandtail_lineskeep both ends with a count between them.max_linesthen caps the lines.
A file with a mistake still keeps its good rules, and one transcript line names every mistake. /bash-diet filters lists both files, their rules and the built-in rules.
Command
/bash-diet on or off, the excludes, and this session's saving
/bash-diet on | off on by default
/bash-diet exclude <prefix | ^regex> that command runs unfiltered; excludes lists them, include takes one back
/bash-diet filters the rule files, their rules, the built-in rules
/bash-diet trust | untrust lets this repository's .bash-diet/filters.json run, or stops it
/bash-diet gain the saving of the last 90 days, the families that saved most
/bash-diet gain project | daily | graph | history
/bash-diet cost this session's spend, and what the tokens kept out would have cost
/bash-diet discover [days] [all] the output the model read in earlier sessions, by filter, and the commands no filter reads
/bash-diet learn [days] [write] commands that failed on a CLI mistake and the form that worked after them
gainreads the records in~/.claude/bash-diet/gain/, one file per session and day, kept for 90 days. Each report gives the measured characters before and after. The token figure is an estimate at four characters per token;historyandgraphgive characters only.costprices the tokens kept out of the context at the model's list prices of September 2026: once at the cache write rate, and again at the cache read rate for each later request.discoverandlearnread this project's transcripts of the last 30 days by default.discover allreads every project's; it answers at once, and its report follows as a transcript line.learncounts only a single command that failed on an unknown flag, a missing command, a missing argument or a syntax error, followed within three calls by a similar command that worked.learn writewrites the pairs to.claude/rules/cli-corrections.mdin the repository, which the model reads in later sessions. A command that may carry a credential is never written.
Install
claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install bash-diet@kilimcininkoroglu-mods
Function hooks are early access. Claude Code 2.1.288 and later load them by default, so there is nothing to switch on.
After installing
- Restart Claude Code.
- If you use another tool that rewrites Bash commands for the same purpose, turn it off, so each output is filtered once.
- To keep a project's own rules, write
.bash-diet/filters.jsonand run/bash-diet trustin that project.
What it can reach
Validated with claude plugin validate on Claude Code 2.1.283:
❯ ./register.ts hooks: session.start, classic.SessionStart, command.run{command=bash-diet}, tool.call{tool=Bash}, tool.call{tool=?}
❯ ./register.ts calls: $.clock.now (via gainCommand, pruneGain, pruneRecall, recordGain, transcriptsOf), $.command.register, $.env.get (via locate, recallDir), $.fs.exists (via gainFiles, refreshFile, transcriptDirs), $.fs.list (via gainFiles, pruneRecall, transcriptDirs, transcriptsOf), $.fs.read (via gainCommand, refreshFile, seedGain, wholeText), $.fs.stat (via pruneRecall, refreshFile, transcriptsOf), $.fs.write (via keepFull, recordGain, writeLearned), $.process.run (via locate, pruneGain, pruneRecall, recallDir, recordGain, writeLearned), $.process.spawn (via callsIn), $.session.id, $.session.model (via costCommand), $.session.root (via locate), $.session.usage (via costCommand), $.sidebar.set (via showGain), $.store.get (via readSettings), $.store.set (via setEnabled, setExcludes, setTrusted), $.tool.check (via withPlanFlags), $.ui.log (via activeRules, discoverAll, refreshFile, report), $.ui.status (via showGain)
Reach L2: it writes files and runs processes.
1. Reads: each Bash command and its output; the result of each Playwright MCP browser tool; the two filters.json files; this session's model, spend and id; the transcripts under ~/.claude/projects for discover and learn
2. Runs: the model's own Bash command, with a flag that shortens its output added when the permission check allows it; git rev-parse, mkdir, rm (of its own files only) and cat (of transcripts)
3. Sends: the filtered result to the model in place of the output, and each Playwright result without its code echo; nothing leaves the machine
4. Persists: full outputs in $TMPDIR/bash-diet (200 files, 30 days); saving records in ~/.claude/bash-diet/gain (90 days); .claude/rules/cli-corrections.md on learn write; in $.store, on/off, the excludes and the trusted rule file hashes
5. Hostile input: a command's output only passes through regexes and JSON.parse, and is never run; a project rule file runs only after /bash-diet trust and only while its SHA-256 matches; env values of credential-like names are masked
Limits
- A filter reads the output's known shape. A tool that changes its output format can make a filter keep less than it should; the full output file and
BASH_DIET_RAW=1are your way back. - The middle of a failed command's output over 10,000 characters is dropped by Claude Code before the mod ever sees it. The mod cannot bring it back; it only tells you it was cut.
- A backgrounded command (
run_in_background) is not filtered, because its result is a task id. - A command inside
$(...), a heredoc or a process substitution, or one whose output is redirected to a file, is not filtered. - A chain of several printing commands gets only the generic cleanup (colour codes, carriage-return redraws, repeated lines).
output-flood0.3.0 and later measure the filtered result, whichever order the two mods load in. An olderoutput-floodloaded after bash-diet measures the output before the filter, and its note names a size the model never read.
Development
make install # eslint, typescript-eslint, typescript
make lint # complexity limit 10, the build fails above it
make typecheck # needs .claude/types/ from /plugin-types
make validate
make test # claude plugin test

