# The bash proxy


# The bash proxy

The first of banish's three parts is a proxy for your shell. Your agent thinks it
is running `git status`; banish runs the real command, pipes its output through a
matching filter, and hands back a compact version.

## The flow

```text
agent  ->  banish git status  ->  git status (real)  ->  filter: git  ->  12 tokens
```

A PreToolUse hook rewrites `git status` to `banish git status`. From there:

- banish runs the exact command you asked for, unchanged.
- It matches the command against your filters and pipes stdout through the first
  one that matches.
- It counts tokens on both the raw and compact output and returns the compact
  text to your agent.

## It never swallows data

If no filter matches, you get the raw output. If a filter errors, you get the raw
output. banish is a compaction layer, not a gate: a missing or broken filter
costs you tokens, never correctness.

And when a filter does drop lines from a large output, the compact result ends
with [an audit footer](/docs/concepts/audit-footer) that accounts for every one
of them and names the recover command - `banish raw <hash>` returns the original
output byte for byte. Every dropped line is accounted for and recoverable.

> banish only auto-approves commands your agent's permission rules already allow.
> `git commit`, `git push`, and `rm` still prompt you, exactly as they would
> without banish in the loop.

## Why a proxy and not a wrapper

A proxy keeps the command surface identical. You do not learn new commands, your
scripts do not change, and turning banish off is one command away:

```sh
banish stop
```

Everything keeps working; you just stop saving tokens until you run `banish start`.

For a command-level walkthrough, see how banish
[compacts git output](/docs/guides/compact-git-output).
