CLI proxy that filters shell output before it reaches your AI coding assistant's context window.
$ npx -y skills add edouard-claude/snip --agent claude-code
What's inside
CLI proxy that filters shell output before it reaches your AI coding assistant's context window. Works with Claude Code, Cursor, Copilot, Gemini CLI, Windsurf, Cline, Codex, Pi, Grok Build, Kilo Code, Antigravity, OpenCode, OpenClaw, Aider, and any tool that runs shell commands.
AI coding agents burn tokens on verbose shell output that adds zero signal. A passing go test produces hundreds of lines the LLM will never use. git log dumps full commit metadata when a one-liner per commit suffices.
snip sits between your AI tool and the shell, filtering output through declarative YAML pipelines. Write a YAML file, drop it in a folder, done. The extensible LLM token optimizer: filters are YAML data files, not compiled code.
snip — Token Savings Report
══════════════════════════════
Commands filtered 128
Tokens saved 2.3M
Avg savings 99.8%
Efficiency Elite
Total time 725.9s
███████████████████░ 100%
14-day trend ▁█▇
Top commands by tokens saved
Command Runs Saved Savings Impact
───────────────────────── ──── ────── ─────── ────────────
go test ./... 8 806.2K 99.8% ████████████
go test ./pkg/... 3 482.9K 99.8% ███████░░░░░
go test ./... -count=1 3 482.0K 99.8% ███████░░░░░
Measured on a real Claude Code session — 128 commands, 2.3M tokens saved.
# Quick install (macOS/Linux)
curl -fsSL https://raw.githubusercontent.com/edouard-claude/snip/master/install.sh | sh
# Or via Homebrew
brew install edouard-claude/tap/snip
# Or with Go
go install github.com/edouard-claude/snip/cmd/snip@latest
# Then hook into Claude Code
snip init
# That's it. Every shell command Claude runs now goes through snip.
Before — Claude Code sees this (275 tokens):
$ go test ./...
ok github.com/edouard-claude/snip 13.697s
? github.com/edouard-claude/snip/cmd/snip [no test files]
ok github.com/edouard-claude/snip/internal/cli 1.357s
ok github.com/edouard-claude/snip/internal/config 1.898s
ok github.com/edouard-claude/snip/internal/discover 4.271s
ok github.com/edouard-claude/snip/internal/display 2.516s
ok github.com/edouard-claude/snip/internal/economics 3.073s
ok github.com/edouard-claude/snip/internal/engine 5.262s
ok github.com/edouard-claude/snip/internal/filter 3.687s
ok github.com/edouard-claude/snip/internal/hook 4.555s
ok github.com/edouard-claude/snip/internal/hookaudit 4.560s
ok github.com/edouard-claude/snip/internal/initcmd 4.534s
ok github.com/edouard-claude/snip/internal/inspect 4.598s
ok github.com/edouard-claude/snip/internal/learn 4.474s
ok github.com/edouard-claude/snip/internal/tee 4.430s
ok github.com/edouard-claude/snip/internal/tracking 4.055s
ok github.com/edouard-claude/snip/internal/trust 4.544s
ok github.com/edouard-claude/snip/internal/utils 4.528s
ok github.com/edouard-claude/snip/internal/verify 4.517s
After — snip returns this (8 tokens):
1125 passed, 0 failed
That's 97% fewer tokens, measured on this very repository. The filter injects -json and counts individual test results, so the LLM gets more signal — 1125 tests passed, not just 18 packages — in a fraction of the space.
┌─────────────┐ ┌─────────────────┐ ┌──────────────┐ ┌────────────┐
│ Claude Code │────>│ snip intercept │────>│ run command │────>│ filter │
│ runs git │ │ match filter │ │ capture I/O │ │ pipeline │
└─────────────┘ └─────────────────┘ └──────────────┘ └─────┬──────┘
│
┌─────────────────┐ ┌──────────────┐ │
│ Claude Code │<────│ track savings│<──────────┘
│ sees filtered │ │ in SQLite │
└─────────────────┘ └──────────────┘
No filter match? The command passes through unchanged — zero overhead.
| Command | Before | After | Reduction |
|---|---|---|---|
cargo test | 591 tokens | 5 tokens | 99.2% |
go test ./... | 275 tokens | 8 tokens | 97.1% |
git log | 371 tokens | 53 tokens | 85.7% |
git status | 112 tokens | 16 tokens | 85.7% |
git diff | 355 tokens | 66 tokens | 81.4% |
Stop wasting tokens on noise. snip gives the LLM the same signal in a fraction of the context window.
brew install edouard-claude/tap/snip
Download the latest binary for your platform from Releases.
# macOS (Apple Silicon)
curl -Lo snip.tar.gz https://github.com/edouard-claude/snip/releases/latest/download/snip_$(curl -s https://api.github.com/repos/edouard-claude/snip/releases/latest | grep tag_name | cut -d'"' -f4 | tr -d v)_darwin_arm64.tar.gz
tar xzf snip.tar.gz && mv snip /usr/local/bin/
go install github.com/edouard-claude/snip/cmd/snip@latest
Or build locally:
git clone https://github.com/edouard-claude/snip.git
cd snip && make install
make install and make install-lite use the first available destination:
an explicit GOBIN, go env GOBIN, or the first go env GOPATH entry plus
/bin. Use make upgrade or make upgrade-lite to replace the resolved
snip on PATH instead. An explicit GOBIN overrides the upgrade destination.
Requires Go 1.25+.
snip integrates with every major AI coding assistant. One binary, universal compatibility.
| Tool | Install | Method |
|---|---|---|
| Claude Code | snip init | PreToolUse hook (native) |
| Cursor | snip init --agent cursor | beforeShellExecution hook (native) |
| GitHub Copilot | snip init --agent copilot | preToolUse hook (native) |
| Gemini CLI | snip init --agent gemini | GEMINI.md prompt injection |
| Codex (OpenAI) | snip init --agent codex | PreToolUse hook (native) |
| Pi (pi.dev) | snip init --agent pi | PreToolUse hook (via pi-hooks) |
| Grok Build (xAI) | snip init --agent grok | PreToolUse hook (deny + re-run suggestion) |
| Windsurf | snip init --agent windsurf | .windsurfrules prompt injection |
| Cline / Roo Code | snip init --agent cline | .clinerules prompt injection |
| Kilo Code | snip init --agent kilocode | .kilocode/rules/ prompt injection |
| Antigravity | snip init --agent antigravity | PreToolUse hook (native) |
| OpenCode | opencode-snip plugin | tool.execute.before hook |
| OpenClaw | openclaw plugins install openclaw-snip | plugin |
| Aider | shell aliases | prefix commands with snip |
snip init
This installs a PreToolUse hook that transparently rewrites supported commands. Claude Code never sees the substitution -- it receives compressed output as if the original command produced it.
Supported commands: 132 filters covering 100 distinct commands: git, go, cargo, npm, yarn, pnpm, docker, kubectl, terraform, aws, gh, dotnet, and many more.
snip init --uninstall # remove the hook
snip init --agent cursor
This patches ~/.cursor/hooks.json with a beforeShellExecution hook. Works the same way as Claude Code.
snip init --agent cursor --uninstall # remove the hook
snip init --agent pi
This patches ~/.pi/agent/settings.json with a PreToolUse entry matching the bash tool. The runtime hook is interpreted by the community extension @hsingjui/pi-hooks, which mirrors Claude Code's hookSpecificOutput format (including command rewriting via updatedInput). Install it once:
pi install npm:@hsingjui/pi-hooks
Then run /reload (or restart Pi). Once active, snip rewrites supported commands transparently.
snip init --agent pi --uninstall # remove the hook
snip init --agent grok
This writes ~/.grok/hooks/snip.json with a PreToolUse hook matching the shell tool. Grok Build hooks cannot rewrite commands in place (the hook contract is allow/deny only), so snip denies matched commands with a re-run suggestion ("…/snip" run -- <command>). Non-matching commands pass through untouched, and the hook is fail-open: if snip breaks, commands simply run unfiltered.
Prefer prompt injection instead? Grok Build reads AGENTS.md natively:
snip init --agent grok --mode prompt # creates AGENTS.md
snip init --agent grok --uninstall # remove the hook
AGENTS.md is shared with Codex, so --uninstall never deletes it; it prints a reminder instead.
snip init --agent codex
This patches ~/.codex/hooks.json with a native PreToolUse hook. Supported shell commands are transparently rewritten through snip with Codex's updatedInput contract, so the model runs commands normally and sees only the filtered output.
For safety, mixed commands containing unsupported segments, pipelines with uninspected tails, and command substitutions pass through unchanged so Codex keeps its native permission flow.
Use snip proxy -- <command> when full unfiltered output is required.
snip init --agent codex --uninstall
Codex CLI 0.131.0 or later is required for PreToolUse input rewriting. For older releases, use the legacy project-scoped prompt integration:
snip init --agent codex --mode prompt
snip init --agent copilot
This patches ~/.copilot/hooks/snip.json with a native preToolUse hook that rewrites supported commands transparently, like Claude Code.
Prefer prompt injection instead? Use the legacy project-scoped mode:
snip init --agent copilot --mode prompt # creates .github/copilot-instructions.md
snip init --agent copilot --uninstall # remove the hook
PreToolUse is supported. This patches ~/.gemini/config/hooks.json.
snip init --agent antigravity
snip init --agent gemini # creates GEMINI.md
snip init --agent windsurf # creates .windsurfrules
snip init --agent cline # creates .clinerules
snip init --agent kilocode # creates .kilocode/rules/snip-rules.md
These agents use prompt injection: a markdown file instructs the LLM to prefix shell commands with snip. Project-scoped (created in the current directory).
Install the opencode-snip plugin by adding it to your OpenCode config (~/.config/opencode/opencode.json):
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-snip@latest"]
}
The plugin uses the tool.execute.before hook to automatically prefix all commands with snip. Commands not supported by snip pass through unchanged.
openclaw plugins install openclaw-snip
Use shell aliases to route commands through snip:
# Add to ~/.bashrc or ~/.zshrc
alias git="snip git"
alias go="snip go"
alias cargo="snip cargo"
FAQ
snip is a Claude Code plugin with 1 hand-picked skill for development work, indexed on Flowy. Install it with the command on its page. It includes snip. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it