# CLI commands


# CLI commands

banish is one binary. The bare form, `banish <cmd>`, is the proxy: it runs a
command and returns the compact output. Everything else is a subcommand for
setup, authoring, and inspection.

## Global flags

These persistent flags apply to the bare proxy form and to every subcommand.

| Flag | Default | Effect |
| --- | --- | --- |
| `--human` | off | Human-readable output instead of compact JSON. |
| `--verbose` | off | Verbose error output. |
| `--timeout <dur>` | `30s` | Default timeout for a command, for example `60s`. |
| `--stats` | off | Print token stats to stderr after execution. |

## Everyday

The commands you run in a normal session.

### `banish <cmd>` (the proxy)

Run a shell command through banish and return compact output. This is the bare
form with no subcommand: banish executes the exact command, pipes stdout through
the first matching filter, and returns the compact text. If no filter matches or
a filter errors, you get the raw output.

```sh
banish "kubectl get pods -n prod"
banish git status
echo "ls /tmp" | banish
```

> Wrap a command in quotes when it has flags or arguments banish should pass
> through verbatim, as in the `kubectl` example above. You can also pipe source
> in on stdin.

Input that is not a known subcommand is treated as inline banish or shell code,
so `banish ls /var/log ext:log | count` runs the `.bsh` pipeline directly.

### `banish run [file.bsh]`

Execute a `.bsh` file, or inline code with `-e`.

| Flag | Effect |
| --- | --- |
| `-e, --exec <code>` | Execute the given inline banish code instead of a file. |

```sh
banish run deploy.bsh
banish run -e "ls /var/log ext:log | count"
```

### `banish gain`

Show cumulative token savings from output compaction. Data is read from
`~/.banish/freq.json` and persists across sessions. Prints total commands, input
and output tokens, tokens saved with percentage, an estimated cost saved, and a
per-command breakdown.

| Flag | Default | Effect |
| --- | --- | --- |
| `--json` | off | Emit the stats as JSON. |
| `--reset` | off | Clear all tracking data. |
| `--price <usd>` | `5.0` | USD per million input tokens, used for the cost estimate. |

```sh
banish gain
banish gain --json
banish gain --price 3
```

### `banish gain reset`

Clear all token-savings tracking data. Equivalent to `banish gain --reset`; both
rewrite `~/.banish/freq.json` to an empty set.

```sh
banish gain reset
```

### `banish raw <hash>`

Print the original, uncompacted stdout and stderr of a recent command, byte for
byte. Compacted large outputs end with [an audit
footer](/docs/concepts/audit-footer) naming the hash:

```text
recover: banish raw a1b2c3d4 (costs ~7009 tokens, only if needed)
```

Raw outputs are cached in `~/.banish/cache/raw/` (user-only permissions, 1 hour
TTL, 50 MB cap - configurable via the `cache` section of
`~/.banish/config.json`; `{"cache": {"raw": false}}` disables caching). An
unknown or expired hash exits non-zero. Available since v0.6.0.

| Flag | Default | Effect |
| --- | --- | --- |
| `--clear` | off | Delete all cached raw outputs. |

```sh
banish raw a1b2c3d4
banish raw --clear
```

## Setup

Wiring banish into an agent and turning interception on or off.

### `banish init [claude-code|cursor|mcp]`

Set banish up for a project or agent. With no argument it scaffolds a starter
`BANISH` file in the current directory. With a target it wires the named agent.

| Target | What it writes |
| --- | --- |
| (none) | A starter `BANISH` file in the current directory. |
| `claude-code` | Extensions in `~/.banish/ext`, MCP config in `~/.claude/.mcp.json`, the bash hook in `~/.claude/hooks`, hook registration in `~/.claude/settings.json`, and context in `~/.claude/CLAUDE.md`. |
| `cursor` | `.cursor/mcp.json` and `.cursorrules`. |
| `mcp` | `.mcp.json` only, for any other MCP-capable agent. |

```sh
banish init
banish init claude-code
banish init cursor
banish init mcp
```

### `banish start [claude-code]`

Re-enable banish interception for an agent that was turned off with
`banish stop`. The agent argument is optional and defaults to `claude-code`.

```sh
banish start
```

### `banish stop [claude-code]`

Disable banish interception without uninstalling. Only the hook that routes
commands through banish is removed; extensions, MCP config, the hook script, and
CLAUDE.md stay in place so `banish start` re-enables instantly. The agent
argument defaults to `claude-code`.

```sh
banish stop
```

### `banish status`

Report whether banish is active for each agent, as JSON.

```sh
banish status
```

### `banish serve`

Start banish as an MCP server over stdio, exposing every extension verb as an
MCP tool. This is the command agents launch when banish is registered as an MCP
server; see [MCP server](/docs/concepts/mcp-server).

```sh
banish serve
```

### `banish completion <bash|zsh|fish|powershell>`

Print a shell completion script for banish's subcommands and flags to stdout.
Source it directly for the current session, or write it to your shell's
completion directory to make it permanent.

```sh
# bash (requires the bash-completion package)
banish completion bash > /usr/local/etc/bash_completion.d/banish

# zsh
banish completion zsh > "${fpath[1]}/_banish"

# fish
banish completion fish > ~/.config/fish/completions/banish.fish
```

Restart your shell after installing the script. Run
`banish completion <shell> --help` for setup notes specific to each shell.

## Authoring and inspection

Commands for writing extensions and understanding your own history.

### `banish check <file.bsh>`

Parse a `.bsh` file and report syntax errors without executing it. On success it
prints the statement count; on error it writes the parse errors to stderr and
exits with a non-zero status.

```sh
banish check deploy.bsh
```

### `banish schema`

Emit the verb catalog and pipeline syntax as compact JSON, suitable for pasting
into a system prompt so an agent knows the available verbs.

```sh
banish schema
```

### `banish discover`

Scan your Claude Code history for the commands your agent runs most and surface
the frequent ones that no installed `.bsh` filter compacts yet - the best
candidates for a new filter. Prints a ready-to-edit filter stub for the top one.

| Flag | Default | Effect |
| --- | --- | --- |
| `--limit <n>` | `10` | Show the top N uncovered commands. |

```sh
banish discover
banish discover --limit 20
```

### `banish learn`

Scan your Claude Code history for commands that failed and were then re-run
successfully with a small change - the agent's own corrections. The recurring
ones point to a flag it keeps getting wrong or a verb worth adding.

| Flag | Default | Effect |
| --- | --- | --- |
| `--limit <n>` | `15` | Show the top N corrections. |

```sh
banish learn
```

## Maintenance

Keeping banish current and removing it.

### `banish upgrade`

Download the latest release, verify its checksum against the release
`checksums.txt`, and replace the running binary in place. If banish is installed
in a directory that needs elevated permissions, the command reports that instead
of failing silently.

| Flag | Default | Effect |
| --- | --- | --- |
| `--check` | off | Report whether a newer release exists, without installing it. |
| `--channel <stable\|beta>` | see below | Release channel. `beta` also considers prereleases (release candidates). |

```sh
banish upgrade
banish upgrade --check
banish upgrade --channel beta
```

The channel resolves in this order: the `--channel` flag, then `"channel"` in
`~/.banish/config.json`, then inference from the running build - a binary
already on a prerelease (`0.6.0-beta.1`) tracks the beta channel
automatically, so testers keep receiving candidates and the stable release
that eventually supersedes them. Everyone else stays on stable and never
sees prereleases.

To opt in permanently instead of passing the flag each time:

```json
{ "channel": "beta" }
```

> banish shows a one-line notice when a newer release is available. It only
> appears on an interactive terminal, so agents, hooks, and CI never see it. Set
> `BANISH_NO_UPDATE_CHECK=1` to turn the notice off.

### `banish uninstall`

Remove the banish binary. Agent wiring written by `banish init` is left in place;
run `banish stop` first to disable the bash hook, or remove the MCP entry from
your agent's settings.

| Flag | Default | Effect |
| --- | --- | --- |
| `--purge` | off | Also remove `~/.banish` (extensions, cache, and savings data). |
| `-y, --yes` | off | Skip the confirmation prompt. |

```sh
banish uninstall
banish uninstall --purge
```

## Diagnostics

### `banish audit`

List the commands banish auto-approved through the PreToolUse hook, because your
agent's permission rules already allowed them. Only auto-approvals are recorded;
commands that prompted you or were deferred are not. Entries are read from
`~/.banish/hook-audit.jsonl`.

| Flag | Default | Effect |
| --- | --- | --- |
| `--limit <n>` | `20` | Show the most recent N entries (`0` for all). |
| `--clear` | off | Delete the audit log. |

```sh
banish audit
banish audit --limit 50
banish audit --clear
```

### `BANISH_TRACE=1` (trace mode)

Not a subcommand but the environment switch for filter debugging: with
`BANISH_TRACE=1` set, every run of lines a filter drops silently is replaced by
an inline annotation instead of removed, so you can see exactly where each
filter stage cut content.

```sh
BANISH_TRACE=1 banish "go test ./..."
# [banish: dropped 20 lines via go-test.drop]
```

See [the audit footer](/docs/concepts/audit-footer) for how drop accounting
works.

### `banish version`

Print the installed version and the build platform.

```sh
banish version
```

### `banish hook`

Internal PreToolUse entry point used by the Claude Code and Cursor integrations.
It reads the tool-input JSON on stdin, decides whether to allow, ask, deny, or
defer a command based on the host's permission rules, and writes the hook
response on stdout. You do not run this by hand; `banish init` wires it up.

| Flag | Default | Effect |
| --- | --- | --- |
| `--host <name>` | `claude-code` | Agent host whose permission rules apply: `claude-code` or `cursor`. |

For how these fit together, start with [the bash proxy](/docs/concepts/bash-proxy)
and [the MCP server](/docs/concepts/mcp-server).
