# snip rewrites your command, not just its output

> A Go proxy that sits between an AI coding agent and the shell, cutting context-window use with YAML filter pipelines. Two things the headline number hides: some filters inject flags so the agent reads output from a command it never ran, and four of the fourteen supported agents are wired up by writing into a rules file rather than by a real hook.

**edouard-claude/snip** — CLI proxy that reduces LLM token usage by 60-90%. Declarative YAML filters for Claude Code, Cursor, Copilot, Gemini. rtk alternative in Go. 

- Repository: https://github.com/edouard-claude/snip
- Website: https://edouard-claude.github.io/snip/
- Stars: 459 · Forks: 46
- Language: Go
- License: MIT
- Published: 2026-09-17 · Updated: 2026-09-17 · Language: en
- Canonical page: https://hysenlabs.com/projects/edouard-claude-snip

## The filter injects flags the agent never asked for

This is the part that distinguishes snip from a tail or a grep. The worked example is `go test ./...`, where 275 tokens of per-package output become 8 tokens reading 1125 passed, 0 failed. Getting from eighteen package lines to an actual test count is not a matter of deleting text: the filter injects `-json`, runs the test binary in its machine-readable mode, and counts individual results. The agent therefore receives output from a command it never typed. The documentation is upfront about the mechanism and careful in its wording, saying Claude Code never sees the substitution and receives compressed output as if the original command produced it. That last clause is carrying a lot of weight. More signal in fewer tokens is a genuine win, but the agent's model of what it ran is now approximate, and any bug that changes which flag gets injected changes the semantics of the command rather than only its presentation.

## Four of fourteen agents are wired up by prompt injection

The supported-tools table is worth reading row by row, because the method column contains two genuinely different designs. Claude Code, Cursor, GitHub Copilot, Codex, Antigravity and Pi get real hooks, named as `PreToolUse`, `beforeShellExecution` or `preToolUse`, which fire before the shell runs and can rewrite the command. Gemini CLI, Windsurf, Cline and Roo Code, and Kilo Code instead get text written into `GEMINI.md`, `.windsurfrules`, `.clinerules` and `.kilocode/rules/`. Those are prompt files. Nothing intercepts the shell; the agent is asked to prefix commands itself, so the savings depend on the model complying with a rule it wrote. Aider is weaker still, plain shell aliases you apply by hand. Two more entries, OpenCode and OpenClaw, require separate community plugin packages rather than `snip init`. So the claim of working with every major assistant is true in the sense that each has a path, and false in the sense that only about half of those paths are enforced by the tool rather than by the agent.

## 132 filters, and go test does not test them

The count is 132 filters covering 100 distinct commands, spanning git, go, cargo, npm, yarn, pnpm, docker, kubectl, terraform, aws, gh and dotnet. The gap between 132 and 100 is the interesting part: some commands carry several filters for their variants, which the savings table confirms, since `go test ./...` and `go test ./... -count=1` are separate rows. Those filters are YAML data files under `filters/`, and the Makefile carries a comment stating that filter YAML tests are not exercised by `go test`. They get their own subcommand, `go run ./cmd/snip verify`, and the aggregate target wires it in: `make ci` runs test-race, verify, lint and vulncheck. That is a reasonable design for a data-driven filter set, and it is also a gap worth naming plainly, because `make test` on its own will pass with every filter broken. A filter that fails to match simply falls through, which is the documented no-overhead path, so a typo in a filter file looks identical to a command nobody has filtered yet.

## The 60-90% headline and the 99.8% demo are different workloads

The repository description claims a 60 to 90 percent reduction. The demonstration report claims 99.8 percent average savings, and both can be honest because they measure different things. The report covers 128 commands filtering out 2.3M tokens, and its top three rows by tokens saved are all variants of the same command: `go test ./...` with 806.2K saved at 99.8 percent, `go test ./pkg/...` with 482.9K at 99.8 percent, and `go test ./... -count=1` with 482.0K at 99.8 percent. An average dominated by test output will land near 100 percent no matter how good the git filters are. The per-command table for mixed shell work is the more useful number, and it descends: `cargo test` from 591 tokens to 5, `go test ./...` from 275 to 8, then `git log` from 371 to 53, `git status` from 112 to 16, and `git diff` from 355 to 66. Read that as the realistic band for a session that is not only running tests. The two figures are not in conflict, but only one of them describes a working day.

## A static binary with embedded filters and a savings ledger

The dependency list explains what kind of program this is. The six direct requirements are a styling library, terminal size and TTY detection, a TOML parser, a YAML parser and SQLite. The SQLite driver is the pure-Go `modernc.org/sqlite`, and the Makefile builds with `CGO_ENABLED=0`, so the result is a static binary with no C toolchain required at install time. That matches the claim of one binary working across platforms. The presence of `embed.go` next to `filters/` explains how 132 YAML filters ship inside that binary rather than being read from disk at runtime, which is a design decision worth noticing against the pitch that you can just drop a YAML file in a folder: the built-ins are compiled in, and user filters are the part that lives on disk. Version strings are injected at build time from `git describe --tags`, stripped with `-s -w`, and there is a separate `lite` build behind a build tag whose contents the visible documentation never explains. Savings are tracked in SQLite, but the path to that database file is not documented in the text available here.

## make install resolves its destination from your Go environment

Four install routes are offered and Homebrew is the one marked recommended:

```bash
# 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
```

Building from source is the fourth, and it is where the sharp edge is:

```bash
git clone https://github.com/edouard-claude/snip.git
cd snip && make install
```

`make install` and `make install-lite` pick the first available destination in order: an explicit `GOBIN`, then `go env GOBIN`, then the first `go env GOPATH` entry plus `/bin`. Nothing is printed as a plan before the choice is made, so where the binary lands depends on state you may not have set deliberately. Upgrading uses the same resolver, and an explicit `GOBIN` overrides the upgrade destination as well. Go 1.25 or newer is required. The lint target is unusually careful by comparison: it reuses an installed golangci-lint only when its version matches the pinned `.golangci-lint-version` exactly, and otherwise runs that exact version from the Go module cache.

## Init rewrites your agent config, and uninstall reverses it

`snip init` is what actually wires the proxy in, and what it writes depends on the agent. For Cursor it patches `~/.cursor/hooks.json` to add a `beforeShellExecution` hook, which is a modification to an existing file rather than a drop-in of a new one. `snip init --uninstall` removes the hook, so the change is reversible, and that reversibility matters more than usual because the tool sits in the path of every command the agent runs. The integration behaviour is not uniform even among the hook-based agents. Claude Code gets a transparent rewrite in which the command is substituted before execution. Grok Build gets a PreToolUse hook described as a deny plus a re-run suggestion, meaning the agent is interrupted and asked to try again rather than silently handed compressed output. Two further guarantees do hold generally: when no filter matches, the command passes through unchanged at what the documentation calls zero overhead, and savings are attributed per command, which is what makes the report possible at all. The GitHub Releases path for macOS on Apple Silicon is a shell one-liner that queries the releases API for the tag name to build the download URL.

## Weekly releases on a pre-1.0 version

Three releases in the space of a fortnight: v0.25.0 on 2026-08-28, v0.25.1 on 2026-09-03 and v0.25.2 on 2026-09-12. The patch number suggests active iteration on a 0.x line, which in Go convention means the API is not held stable and you should expect churn in flags and file formats. The last push to the default branch, master, was on 2026-09-12, the same day as the newest release. Version stamping is automated from git tags rather than edited by hand, and the module path is `github.com/edouard-claude/snip` with the command living at `cmd/snip`, so a Go consumer can pin a specific version through the module system. The tree carries the usual set of governance files, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md` and `SECURITY.md`, plus `CLAUDE.md` and `SKILL.md`, and the lint configuration is committed as both `.golangci.yml` and a separate version-pinning file. Licence is MIT and the project publishes a documentation site at edouard-claude.github.io/snip.

## Conclusion

Adopt snip if your agent spends most of its context on passing test output and verbose git output, and if you are using an agent with a genuine PreToolUse hook, since that is where the transparent rewrite is reliable. Do not adopt it expecting uniform coverage, because the Gemini, Windsurf, Cline and Kilo Code paths depend on the model choosing to follow an injected rule, and OpenCode and OpenClaw need separate third-party plugins. Verify first that `go run ./cmd/snip verify` passes in your checkout, because the 132 filter files are not exercised by `go test` and a broken filter fails silently as a pass-through.

## FAQ

### How do I install snip?

Four routes are documented: piping `install.sh` to a shell on macOS or Linux, `brew install edouard-claude/tap/snip`, `go install github.com/edouard-claude/snip/cmd/snip@latest`, or cloning and running `make install`. Go 1.25 or newer is required. After any of them, `snip init` hooks it into Claude Code.

### Does snip change the commands my AI agent actually runs?

For some commands, yes. The go test filter injects `-json` so the agent receives a count of individual test results rather than per-package lines, turning 275 tokens into 8 while reporting 1125 tests passed instead of 18 packages. Claude Code never sees the substitution.

### Which AI coding tools does snip integrate with through real hooks?

Claude Code, Cursor, GitHub Copilot, Codex, Antigravity and Pi get hook-based integrations. Gemini CLI, Windsurf, Cline and Roo Code, and Kilo Code are instead handled by prompt injection into `GEMINI.md`, `.windsurfrules`, `.clinerules` and `.kilocode/rules/`, and Aider uses shell aliases.

### How are snip's filters tested?

Not by `go test`. The Makefile states that filter YAML tests are not exercised by it and routes them to `go run ./cmd/snip verify`, which is part of `make ci` alongside test-race, lint and vulncheck. Running `make test` alone passes even if every filter is broken.

### How much context does snip actually save?

The stated range is 60 to 90 percent. The demonstration session reports 99.8 percent average, but its top three commands are all go test variants at 99.8 percent each. For mixed shell work the per-command table descends from 99.2 percent for cargo test to 81.4 percent for git diff.

## Sources

- [edouard-claude/snip on GitHub](https://github.com/edouard-claude/snip)
- [License: MIT](https://github.com/edouard-claude/snip/blob/master/LICENSE)
- [Project website](https://edouard-claude.github.io/snip/)
- [README](https://github.com/edouard-claude/snip/blob/master/README.md)
- [Releases](https://github.com/edouard-claude/snip/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/edouard-claude-snip
