# Approvals in the terminal

> Keys for tool, file-edit, plan and question approvals, and for stopping a run, in the terminal app.

Which calls ask, the safelist and interaction modes: [tool approvals](https://zidane.si/docs/approvals.md). Settings › Agent › Tool approvals is Ask by default.

## Approve a tool call

The approval block replaces the prompt. `↑` `↓` pick an answer, `Enter` confirms.

*Terminal: The agent wants to run the tests and waits for an answer.*

```text
 ┌ New session ────────────────────────────────── ▢ ─ ~/acme-api  1 user message  0 turns ┐
 │ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
 │ │ ❯ Run the limiter tests                                                            │ │
 │ └────────────────────────────────────────────────────────────────────────────────────┘ │
 │                                                                                        │
 │ I will run the test suite first.                                                       │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 │                                                                                        │
 └────────────────────────────────────────────────────────────────────────────────────────┘
 ┌─ approve tool call (ctrl+esc aborts the run) ──────────────────────────────────────────┐
 │ ↳ shell(command: "bun test src/limits.test.ts")                                        │
 │  ▶ accept once                                                                         │
 │    accept for session (auto-approve matching calls until you quit)                     │
 │    accept + remember (adds "shell:bun:*" to projects.json)                             │
 │    deny (the model sees "Blocked")                                                     │
 └────────────────────────────────────────────────────────────────────────────────────────┘
 ↑↓ navigate  ↵ select  ctrl+esc abort run  ▱▱▰▰▰ 0s                    ctx 10 / 1.00M (0%)
```

| Answer | Does |
| - | - |
| accept once | Runs this call |
| accept for session | Runs it, and every matching call until you quit |
| accept + remember | Runs it and adds a rule to the project's safelist |
| deny | Blocks it. The agent sees that you refused. |

For a chained command such as `cd src && bun test`, remember proposes one rule per command.

## Approve a file edit

`edit`, `multi_edit` and `write_file` show the diff first, side by side at 100 columns and wider. `←` `→` or `Tab` move between buttons, `Enter` confirms.

*Terminal: An edit waiting for approval: the changed line in red and green.*

```text
 ┌─ edit approval ───────────────────────────────────────────────────────────── limits.ts ┐
 │                                                                                        │
 │ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
 │ │  1   export function rateLimit(opts: { perMinute: number }) {                      │ │
 │ │  2     const hits = new Map<string, number[]>()                                    │ │
 │ │  3     return async (c, next) => {                                                 │ │
 │ │  4       const ip = c.req.header('x-forwarded-for') ?? 'local'                     │ │
 │ │  5       const now = Date.now()                                                    │ │
 │ │  6       const recent = (hits.get(ip) ?? []).filter(t => now - t < 60_000)         │ │
 │ │  7 -     if (recent.length >= opts.perMinute)                                      │ │
 │ │  7 +     if (recent.length >= opts.perMinute * 3)                                  │ │
 │ │  8         return c.text('Too many requests', 429)                                 │ │
 │ │  9       hits.set(ip, [...recent, now])                                            │ │
 │ │ 10       await next()                                                              │ │
 │ │ 11     }                                                                           │ │
 │ │ 12   }                                                                             │ │
 │ │                                                                                    │ │
 │ │                                                                                    │ │
 │ │                                                                                    │ │
 │ │                                                                                    │ │
 │ │                                                                                    │ │
 │ └────────────────────────────────────────────────────────────────────────────────────┘ │
 │                                                                                        │
 │  Allow (a)    Allow for session (s)    Always allow (p)    Deny (d)                    │
 │                                                                                        │
 └ ←→ navigate  ↵ confirm  esc deny ──────────────────────────────────────────────────────┘
 ┌─────── ↵ queue  shift+↵ newline  ↑↓ history  ctrl+esc abort  @ files  / skills  # chat ┐
 │ Ask zidane…                                                                            │
 └────────────────────────────────────────────────────────────────────────────────────────┘
 ↑↓ navigate  ↵ select  ctrl+esc abort run  ▱▱▰▰▰ 0s                    ctx 10 / 1.00M (0%)
```

| Key | Button |
| - | - |
| `A` | Allow |
| `S` | Allow for session |
| `P` | Always allow (adds a rule to the safelist) |
| `D` or `Esc` | Deny |

### Apply some hunks

An edit with several hunks lists them with checkboxes.

| Key | Does |
| - | - |
| `↑` `↓` or `K` `J` | Move between hunks |
| `Space` | Tick or untick a hunk |
| `Y` / `N` | Tick all / untick all |
| `Tab` | Switch between the list and the buttons |

Allow then reads `Apply 2/3`, or `Apply all` when every hunk is ticked. The agent learns which hunks you applied.

## Answer a plan or a question

These blocks also replace the prompt.

| The agent calls | You |
| - | - |
| `present_plan` | Approve, revise with a note, or reject. On reject the agent reads your note and the run stops. |
| `ask_user` | `↑` `↓` or `K` `J` move, `Space` ticks an option, `Enter` answers |

`Esc` leaves a question from an earlier run for later. Settings › Agent › Interaction mode decides whether the agent asks at all ([interaction modes](https://zidane.si/docs/approvals.md#interaction-modes)).

## Stop and cancel

| Key | Does |
| - | - |
| `Ctrl`+`Esc` | Abort the run and deny everything pending |
| `Ctrl`+`K` | Pick one running tool call or background task to cancel, or press `A` to cancel all. The run continues. |

If your terminal cannot send Ctrl+Esc, [rebind](https://zidane.si/docs/tui-keys.md#rebind-a-key) `abortRun`.

## Related settings

| Topic | Home |
| - | - |
| Guardrails, Sandbox and Run limits rows with defaults | [Settings](https://zidane.si/docs/tui-settings.md#guardrails) |
| The OS sandbox | [execution contexts](https://zidane.si/docs/execution-contexts.md#os-sandbox) |
| Run limits | [errors](https://zidane.si/docs/errors.md#run-level-budgets) |
| `zidane run --json`, which never asks | [headless and CI](https://zidane.si/docs/cli-headless.md#approvals) |
