SpyBara
Go Premium

Documentation 2026-04-18 18:09 UTC to 2026-04-20 21:14 UTC

7 files changed +157 −93. View all changes and history on the product overview
2026
Wed 29 21:21 Tue 28 21:21 Mon 27 21:20 Sun 26 04:08 Sat 25 21:10 Fri 24 18:11 Thu 23 18:19 Wed 22 21:15 Tue 21 21:14 Mon 20 21:14 Sat 18 18:09 Fri 17 21:13 Thu 16 21:13 Wed 15 18:20 Tue 14 21:14 Mon 13 21:14 Sat 11 00:11 Fri 10 21:09 Thu 9 21:14 Wed 8 21:13 Tue 7 21:14 Sat 4 18:05 Fri 3 21:07 Thu 2 21:08 Wed 1 21:12

commands.md +2 −2

Details

91| `/tasks` | List and manage background tasks. Also available as `/bashes` |91| `/tasks` | List and manage background tasks. Also available as `/bashes` |

92| `/team-onboarding` | Generate a team onboarding guide from your Claude Code usage history. Claude analyzes your sessions, commands, and MCP server usage from the past 30 days and produces a markdown guide a teammate can paste as a first message to get set up quickly |92| `/team-onboarding` | Generate a team onboarding guide from your Claude Code usage history. Claude analyzes your sessions, commands, and MCP server usage from the past 30 days and produces a markdown guide a teammate can paste as a first message to get set up quickly |

93| `/teleport` | Pull a [Claude Code on the web](/en/claude-code-on-the-web#from-web-to-terminal) session into this terminal: opens a picker, then fetches the branch and conversation. Also available as `/tp`. Requires a claude.ai subscription |93| `/teleport` | Pull a [Claude Code on the web](/en/claude-code-on-the-web#from-web-to-terminal) session into this terminal: opens a picker, then fetches the branch and conversation. Also available as `/tp`. Requires a claude.ai subscription |

94| `/terminal-setup` | Configure terminal keybindings for Shift+Enter and other shortcuts. Only visible in terminals that need it, like VS Code, Alacritty, or Warp |94| `/terminal-setup` | Configure terminal keybindings for Shift+Enter and other shortcuts. Only visible in terminals that need it, like VS Code, Cursor, Windsurf, Alacritty, or Zed |

95| `/theme` | Change the color theme. Includes an `auto` option that follows your terminal's dark or light mode, light and dark variants, colorblind-accessible (daltonized) themes, and ANSI themes that use your terminal's color palette |95| `/theme` | Change the color theme. Includes an `auto` option that matches your terminal's light or dark background, light and dark variants, colorblind-accessible (daltonized) themes, and ANSI themes that use your terminal's color palette |

96| `/tui [default\|fullscreen]` | Set the terminal UI renderer and relaunch into it with your conversation intact. `fullscreen` enables the [flicker-free alt-screen renderer](/en/fullscreen). With no argument, prints the active renderer |96| `/tui [default\|fullscreen]` | Set the terminal UI renderer and relaunch into it with your conversation intact. `fullscreen` enables the [flicker-free alt-screen renderer](/en/fullscreen). With no argument, prints the active renderer |

97| `/ultraplan <prompt>` | Draft a plan in an [ultraplan](/en/ultraplan) session, review it in your browser, then execute remotely or send it back to your terminal |97| `/ultraplan <prompt>` | Draft a plan in an [ultraplan](/en/ultraplan) session, review it in your browser, then execute remotely or send it back to your terminal |

98| `/ultrareview [PR]` | Run a deep, multi-agent code review in a cloud sandbox with [ultrareview](/en/ultrareview). Includes 3 free runs on Pro and Max, then requires [extra usage](https://support.claude.com/en/articles/12429409-extra-usage-for-paid-claude-plans) |98| `/ultrareview [PR]` | Run a deep, multi-agent code review in a cloud sandbox with [ultrareview](/en/ultrareview). Includes 3 free runs on Pro and Max, then requires [extra usage](https://support.claude.com/en/articles/12429409-extra-usage-for-paid-claude-plans) |

env-vars.md +1 −1

Details

150| `CLAUDE_CONFIG_DIR` | Override the configuration directory (default: `~/.claude`). All settings, credentials, session history, and plugins are stored under this path. Useful for running multiple accounts side by side: for example, `alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude'` |150| `CLAUDE_CONFIG_DIR` | Override the configuration directory (default: `~/.claude`). All settings, credentials, session history, and plugins are stored under this path. Useful for running multiple accounts side by side: for example, `alias claude-work='CLAUDE_CONFIG_DIR=~/.claude-work claude'` |

151| `CLAUDE_ENABLE_BYTE_WATCHDOG` | Set to `1` to force-enable the byte-level streaming idle watchdog, or set to `0` to force-disable it. When unset, the watchdog is enabled by default for Anthropic API connections. The byte watchdog aborts a connection when no bytes arrive on the wire for the duration set by `CLAUDE_STREAM_IDLE_TIMEOUT_MS`, with a minimum of 5 minutes, independent of the event-level watchdog |151| `CLAUDE_ENABLE_BYTE_WATCHDOG` | Set to `1` to force-enable the byte-level streaming idle watchdog, or set to `0` to force-disable it. When unset, the watchdog is enabled by default for Anthropic API connections. The byte watchdog aborts a connection when no bytes arrive on the wire for the duration set by `CLAUDE_STREAM_IDLE_TIMEOUT_MS`, with a minimum of 5 minutes, independent of the event-level watchdog |

152| `CLAUDE_ENABLE_STREAM_WATCHDOG` | Set to `1` to enable the event-level streaming idle watchdog. Off by default. For Bedrock, Vertex, and Foundry, this is the only idle watchdog available. Configure the timeout with `CLAUDE_STREAM_IDLE_TIMEOUT_MS` |152| `CLAUDE_ENABLE_STREAM_WATCHDOG` | Set to `1` to enable the event-level streaming idle watchdog. Off by default. For Bedrock, Vertex, and Foundry, this is the only idle watchdog available. Configure the timeout with `CLAUDE_STREAM_IDLE_TIMEOUT_MS` |

153| `CLAUDE_ENV_FILE` | Path to a shell script that Claude Code sources before each Bash command. Use to persist virtualenv or conda activation across commands. Also populated dynamically by [SessionStart](/en/hooks#persist-environment-variables), [CwdChanged](/en/hooks#cwdchanged), and [FileChanged](/en/hooks#filechanged) hooks |153| `CLAUDE_ENV_FILE` | Path to a shell script whose contents Claude Code runs before each Bash command in the same shell process, so exports in the file are visible to the command. Use to persist virtualenv or conda activation across commands. Also populated dynamically by [SessionStart](/en/hooks#persist-environment-variables), [CwdChanged](/en/hooks#cwdchanged), and [FileChanged](/en/hooks#filechanged) hooks |

154| `CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX` | Prefix for auto-generated [Remote Control](/en/remote-control) session names when no explicit name is provided. Defaults to your machine's hostname, producing names like `myhost-graceful-unicorn`. The `--remote-control-session-name-prefix` CLI flag sets the same value for a single invocation |154| `CLAUDE_REMOTE_CONTROL_SESSION_NAME_PREFIX` | Prefix for auto-generated [Remote Control](/en/remote-control) session names when no explicit name is provided. Defaults to your machine's hostname, producing names like `myhost-graceful-unicorn`. The `--remote-control-session-name-prefix` CLI flag sets the same value for a single invocation |

155| `CLAUDE_STREAM_IDLE_TIMEOUT_MS` | Timeout in milliseconds before the streaming idle watchdog closes a stalled connection. For the byte-level watchdog on the Anthropic API: default and minimum `300000` (5 minutes); lower values are silently clamped to absorb extended thinking pauses and proxy buffering. For the event-level watchdog: default `90000` (90 seconds), no minimum. For third-party providers, requires `CLAUDE_ENABLE_STREAM_WATCHDOG=1` |155| `CLAUDE_STREAM_IDLE_TIMEOUT_MS` | Timeout in milliseconds before the streaming idle watchdog closes a stalled connection. For the byte-level watchdog on the Anthropic API: default and minimum `300000` (5 minutes); lower values are silently clamped to absorb extended thinking pauses and proxy buffering. For the event-level watchdog: default `90000` (90 seconds), no minimum. For third-party providers, requires `CLAUDE_ENABLE_STREAM_WATCHDOG=1` |

156| `DISABLE_AUTOUPDATER` | Set to `1` to disable automatic updates |156| `DISABLE_AUTOUPDATER` | Set to `1` to disable automatic updates |

hooks.md +12 −6

Details

55 55 

56### How a hook resolves56### How a hook resolves

57 57 

58To see how these pieces fit together, consider this `PreToolUse` hook that blocks destructive shell commands. The `matcher` narrows to Bash tool calls and the `if` condition narrows further to commands starting with `rm`, so `block-rm.sh` only spawns when both filters match:58To see how these pieces fit together, consider this `PreToolUse` hook that blocks destructive shell commands. The `matcher` narrows to Bash tool calls and the `if` condition narrows further to Bash subcommands matching `rm *`, so `block-rm.sh` only spawns when both filters match:

59 59 

60```json theme={null}60```json theme={null}

61{61{


116 </Step>116 </Step>

117 117 

118 <Step title="If condition checks">118 <Step title="If condition checks">

119 The `if` condition `"Bash(rm *)"` matches because the command starts with `rm`, so this handler spawns. If the command had been `npm test`, the `if` check would fail and `block-rm.sh` would never run, avoiding the process spawn overhead. The `if` field is optional; without it, every handler in the matched group runs.119 The `if` condition `"Bash(rm *)"` matches because `rm -rf /tmp/build` is a subcommand matching `rm *`, so this handler spawns. If the command had been `npm test`, the `if` check would fail and `block-rm.sh` would never run, avoiding the process spawn overhead. The `if` field is optional; without it, every handler in the matched group runs.

120 </Step>120 </Step>

121 121 

122 <Step title="Hook handler runs">122 <Step title="Hook handler runs">


227 227 

228`UserPromptSubmit`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, and `CwdChanged` don't support matchers and always fire on every occurrence. If you add a `matcher` field to these events, it is silently ignored.228`UserPromptSubmit`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, and `CwdChanged` don't support matchers and always fire on every occurrence. If you add a `matcher` field to these events, it is silently ignored.

229 229 

230For tool events, you can filter more narrowly by setting the [`if` field](#common-fields) on individual hook handlers. `if` uses [permission rule syntax](/en/permissions) to match against the tool name and arguments together, so `"Bash(git *)"` runs only for `git` commands and `"Edit(*.ts)"` runs only for TypeScript files.230For tool events, you can filter more narrowly by setting the [`if` field](#common-fields) on individual hook handlers. `if` uses [permission rule syntax](/en/permissions) to match against the tool name and arguments together, so `"Bash(git *)"` runs when any subcommand of the Bash input matches `git *` and `"Edit(*.ts)"` runs only for TypeScript files.

231 231 

232#### Match MCP tools232#### Match MCP tools

233 233 


280* **[Command hooks](#command-hook-fields)** (`type: "command"`): run a shell command. Your script receives the event's [JSON input](#hook-input-and-output) on stdin and communicates results back through exit codes and stdout.280* **[Command hooks](#command-hook-fields)** (`type: "command"`): run a shell command. Your script receives the event's [JSON input](#hook-input-and-output) on stdin and communicates results back through exit codes and stdout.

281* **[HTTP hooks](#http-hook-fields)** (`type: "http"`): send the event's JSON input as an HTTP POST request to a URL. The endpoint communicates results back through the response body using the same [JSON output format](#json-output) as command hooks.281* **[HTTP hooks](#http-hook-fields)** (`type: "http"`): send the event's JSON input as an HTTP POST request to a URL. The endpoint communicates results back through the response body using the same [JSON output format](#json-output) as command hooks.

282* **[Prompt hooks](#prompt-and-agent-hook-fields)** (`type: "prompt"`): send a prompt to a Claude model for single-turn evaluation. The model returns a yes/no decision as JSON. See [Prompt-based hooks](#prompt-based-hooks).282* **[Prompt hooks](#prompt-and-agent-hook-fields)** (`type: "prompt"`): send a prompt to a Claude model for single-turn evaluation. The model returns a yes/no decision as JSON. See [Prompt-based hooks](#prompt-based-hooks).

283* **[Agent hooks](#prompt-and-agent-hook-fields)** (`type: "agent"`): spawn a subagent that can use tools like Read, Grep, and Glob to verify conditions before returning a decision. See [Agent-based hooks](#agent-based-hooks).283* **[Agent hooks](#prompt-and-agent-hook-fields)** (`type: "agent"`): spawn a subagent that can use tools like Read, Grep, and Glob to verify conditions before returning a decision. Agent hooks are experimental and may change. See [Agent-based hooks](#agent-based-hooks).

284 284 

285#### Common fields285#### Common fields

286 286 

287These fields apply to all hook types:287These fields apply to all hook types:

288 288 

289| Field | Required | Description |289| Field | Required | Description |

290| :-------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |290| :-------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

291| `type` | yes | `"command"`, `"http"`, `"prompt"`, or `"agent"` |291| `type` | yes | `"command"`, `"http"`, `"prompt"`, or `"agent"` |

292| `if` | no | Permission rule syntax to filter when this hook runs, such as `"Bash(git *)"` or `"Edit(*.ts)"`. The hook only spawns if the tool call matches the pattern. Only evaluated on tool events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, and `PermissionDenied`. On other events, a hook with `if` set never runs. Uses the same syntax as [permission rules](/en/permissions) |292| `if` | no | Permission rule syntax to filter when this hook runs, such as `"Bash(git *)"` or `"Edit(*.ts)"`. The hook only spawns if the tool call matches the pattern, or if a Bash command is too complex to parse. Only evaluated on tool events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, and `PermissionRequest`. On other events, a hook with `if` set never runs. Uses the same syntax as [permission rules](/en/permissions) |

293| `timeout` | no | Seconds before canceling. Defaults: 600 for command, 30 for prompt, 60 for agent |293| `timeout` | no | Seconds before canceling. Defaults: 600 for command, 30 for prompt, 60 for agent |

294| `statusMessage` | no | Custom spinner message displayed while the hook runs |294| `statusMessage` | no | Custom spinner message displayed while the hook runs |

295| `once` | no | If `true`, runs once per session then is removed. Only honored for hooks declared in [skill frontmatter](#hooks-in-skills-and-agents); ignored in settings files and agent frontmatter |295| `once` | no | If `true`, runs once per session then is removed. Only honored for hooks declared in [skill frontmatter](#hooks-in-skills-and-agents); ignored in settings files and agent frontmatter |

296 296 

297The `if` field holds exactly one permission rule. There is no `&&`, `||`, or list syntax for combining rules; to apply multiple conditions, define a separate hook handler for each. For Bash, the rule is matched against each subcommand of the tool input after leading `VAR=value` assignments are stripped, so `if: "Bash(git push *)"` matches both `FOO=bar git push` and `npm test && git push`. The hook runs if any subcommand matches, and always runs when the command is too complex to parse.

298 

297#### Command hook fields299#### Command hook fields

298 300 

299In addition to the [common fields](#common-fields), command hooks accept these fields:301In addition to the [common fields](#common-fields), command hooks accept these fields:


2186 2188 

2187## Agent-based hooks2189## Agent-based hooks

2188 2190 

2191<Warning>

2192 Agent hooks are experimental. Behavior and configuration may change in future releases. For production workflows, prefer [command hooks](#command-hook-fields).

2193</Warning>

2194 

2189Agent-based hooks (`type: "agent"`) are like prompt-based hooks but with multi-turn tool access. Instead of a single LLM call, an agent hook spawns a subagent that can read files, search code, and inspect the codebase to verify conditions. Agent hooks support the same events as prompt-based hooks.2195Agent-based hooks (`type: "agent"`) are like prompt-based hooks but with multi-turn tool access. Instead of a single LLM call, an agent hook spawns a subagent that can read files, search code, and inspect the codebase to verify conditions. Agent hooks support the same events as prompt-based hooks.

2190 2196 

2191### How agent hooks work2197### How agent hooks work

hooks-guide.md +23 −7

Details

316 316 

317Some projects set different environment variables depending on which directory you are in. Tools like [direnv](https://direnv.net/) do this automatically in your shell, but Claude's Bash tool does not pick up those changes on its own.317Some projects set different environment variables depending on which directory you are in. Tools like [direnv](https://direnv.net/) do this automatically in your shell, but Claude's Bash tool does not pick up those changes on its own.

318 318 

319A `CwdChanged` hook fixes this: it runs each time Claude changes directory, so you can reload the correct variables for the new location. The hook writes the updated values to `CLAUDE_ENV_FILE`, which Claude Code applies before each Bash command. Add this to `~/.claude/settings.json`:319Pairing a `SessionStart` hook with a `CwdChanged` hook fixes this. `SessionStart` loads the variables for the directory you launch in, and `CwdChanged` reloads them each time Claude changes directory. Both write to `CLAUDE_ENV_FILE`, which Claude Code runs as a script preamble before each Bash command. Add this to `~/.claude/settings.json`:

320 320 

321```json theme={null}321```json theme={null}

322{322{

323 "hooks": {323 "hooks": {

324 "SessionStart": [

325 {

326 "hooks": [

327 {

328 "type": "command",

329 "command": "direnv export bash > \"$CLAUDE_ENV_FILE\""

330 }

331 ]

332 }

333 ],

324 "CwdChanged": [334 "CwdChanged": [

325 {335 {

326 "hooks": [336 "hooks": [

327 {337 {

328 "type": "command",338 "type": "command",

329 "command": "direnv export bash >> \"$CLAUDE_ENV_FILE\""339 "command": "direnv export bash > \"$CLAUDE_ENV_FILE\""

330 }340 }

331 ]341 ]

332 }342 }


335}345}

336```346```

337 347 

348Run `direnv allow` once in each directory that has an `.envrc` so direnv is permitted to load it. If you use devbox or nix instead of direnv, the same pattern works with `devbox shellenv` or `devbox global shellenv` in place of `direnv export bash`.

349 

338To react to specific files instead of every directory change, use `FileChanged` with a `matcher` listing the filenames to watch, separated by `|`. To build the watch list, this value is split into literal filenames rather than evaluated as a regex. See [FileChanged](/en/hooks#filechanged) for how the same value also filters which hook groups run when a file changes. This example watches `.envrc` and `.env` in the working directory:350To react to specific files instead of every directory change, use `FileChanged` with a `matcher` listing the filenames to watch, separated by `|`. To build the watch list, this value is split into literal filenames rather than evaluated as a regex. See [FileChanged](/en/hooks#filechanged) for how the same value also filters which hook groups run when a file changes. This example watches `.envrc` and `.env` in the working directory:

339 351 

340```json theme={null}352```json theme={null}


346 "hooks": [358 "hooks": [

347 {359 {

348 "type": "command",360 "type": "command",

349 "command": "direnv export bash >> \"$CLAUDE_ENV_FILE\""361 "command": "direnv export bash > \"$CLAUDE_ENV_FILE\""

350 }362 }

351 ]363 ]

352 }364 }


448 460 

449* `"type": "http"`: POST event data to a URL. See [HTTP hooks](#http-hooks).461* `"type": "http"`: POST event data to a URL. See [HTTP hooks](#http-hooks).

450* `"type": "prompt"`: single-turn LLM evaluation. See [Prompt-based hooks](#prompt-based-hooks).462* `"type": "prompt"`: single-turn LLM evaluation. See [Prompt-based hooks](#prompt-based-hooks).

451* `"type": "agent"`: multi-turn verification with tool access. See [Agent-based hooks](#agent-based-hooks).463* `"type": "agent"`: multi-turn verification with tool access. Agent hooks are experimental and may change. See [Agent-based hooks](#agent-based-hooks).

452 464 

453### Read input and return output465### Read input and return output

454 466 


649 The `if` field requires Claude Code v2.1.85 or later. Earlier versions ignore it and run the hook on every matched call.661 The `if` field requires Claude Code v2.1.85 or later. Earlier versions ignore it and run the hook on every matched call.

650</Note>662</Note>

651 663 

652The `if` field uses [permission rule syntax](/en/permissions) to filter hooks by tool name and arguments together, so the hook process only spawns when the tool call matches. This goes beyond `matcher`, which filters at the group level by tool name only.664The `if` field uses [permission rule syntax](/en/permissions) to filter hooks by tool name and arguments together, so the hook process only spawns when the tool call matches, or when a Bash command is too complex to parse. This goes beyond `matcher`, which filters at the group level by tool name only.

653 665 

654For example, to run a hook only when Claude uses `git` commands rather than all Bash commands:666For example, to run a hook only when Claude uses `git` commands rather than all Bash commands:

655 667 


672}684}

673```685```

674 686 

675The hook process only spawns when the Bash command starts with `git`. Other Bash commands skip this handler entirely. The `if` field accepts the same patterns as permission rules: `"Bash(git *)"`, `"Edit(*.ts)"`, and so on. To match multiple tool names, use separate handlers each with its own `if` value, or match at the `matcher` level where pipe alternation is supported.687The hook process only spawns when a subcommand of the Bash command matches `git *`, or when the command is too complex to parse into subcommands. For compound commands like `npm test && git push`, Claude Code evaluates each subcommand and fires the hook because `git push` matches. The `if` field accepts the same patterns as permission rules: `"Bash(git *)"`, `"Edit(*.ts)"`, and so on. To match multiple tool names, use separate handlers each with its own `if` value, or match at the `matcher` level where pipe alternation is supported.

676 688 

677`if` only works on tool events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, and `PermissionDenied`. Adding it to any other event prevents the hook from running.689`if` only works on tool events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, and `PermissionRequest`. Adding it to any other event prevents the hook from running.

678 690 

679### Configure hook location691### Configure hook location

680 692 


725 737 

726## Agent-based hooks738## Agent-based hooks

727 739 

740<Warning>

741 Agent hooks are experimental. Behavior and configuration may change in future releases. For production workflows, prefer [command hooks](/en/hooks#command-hook-fields).

742</Warning>

743 

728When verification requires inspecting files or running commands, use `type: "agent"` hooks. Unlike prompt hooks which make a single LLM call, agent hooks spawn a subagent that can read files, search code, and use other tools to verify conditions before returning a decision.744When verification requires inspecting files or running commands, use `type: "agent"` hooks. Unlike prompt hooks which make a single LLM call, agent hooks spawn a subagent that can read files, search code, and use other tools to verify conditions before returning a decision.

729 745 

730Agent hooks use the same `"ok"` / `"reason"` response format as prompt hooks, but with a longer default timeout of 60 seconds and up to 50 tool-use turns.746Agent hooks use the same `"ok"` / `"reason"` response format as prompt hooks, but with a longer default timeout of 60 seconds and up to 50 tool-use turns.

Details

13 13 

14 **macOS users**: Option/Alt key shortcuts (`Alt+B`, `Alt+F`, `Alt+Y`, `Alt+M`, `Alt+P`, `Alt+T`) require configuring Option as Meta in your terminal:14 **macOS users**: Option/Alt key shortcuts (`Alt+B`, `Alt+F`, `Alt+Y`, `Alt+M`, `Alt+P`, `Alt+T`) require configuring Option as Meta in your terminal:

15 15 

16 * **iTerm2**: settings → Profiles → Keys → set Left/Right Option key to "Esc+"16 * **iTerm2**: Settings → Profiles → Keys → General → set Left/Right Option key to "Esc+"

17 * **Terminal.app**: settings → Profiles → Keyboard → check "Use Option as Meta Key"17 * **Apple Terminal**: Settings → Profiles → Keyboard → check "Use Option as Meta Key"

18 * **VS Code**: set `"terminal.integrated.macOptionIsMeta": true` in VS Code settings18 * **VS Code**: set `"terminal.integrated.macOptionIsMeta": true` in VS Code settings

19 19 

20 See [Terminal configuration](/en/terminal-config) for details.20 See [Terminal configuration](/en/terminal-config) for details.


65### Multiline input65### Multiline input

66 66 

67| Method | Shortcut | Context |67| Method | Shortcut | Context |

68| :--------------- | :------------- | :------------------------------------------------------ |68| :--------------- | :------------- | :------------------------------------------------------------------------------------------------- |

69| Quick escape | `\` + `Enter` | Works in all terminals |69| Quick escape | `\` + `Enter` | Works in all terminals |

70| macOS default | `Option+Enter` | Default on macOS |70| Option key | `Option+Enter` | After enabling [Option as Meta](/en/terminal-config#enable-option-key-shortcuts-on-macos) on macOS |

71| Shift+Enter | `Shift+Enter` | Works out of the box in iTerm2, WezTerm, Ghostty, Kitty |71| Shift+Enter | `Shift+Enter` | Native in iTerm2, WezTerm, Ghostty, Kitty, Warp, Apple Terminal |

72| Control sequence | `Ctrl+J` | Line feed character for multiline |72| Control sequence | `Ctrl+J` | Works in any terminal without configuration |

73| Paste mode | Paste directly | For code blocks, logs |73| Paste mode | Paste directly | For code blocks, logs |

74 74 

75<Tip>75<Tip>

76 Shift+Enter works without configuration in iTerm2, WezTerm, Ghostty, and Kitty. For other terminals (VS Code, Alacritty, Zed, Warp), run `/terminal-setup` to install the binding.76 Shift+Enter works without configuration in iTerm2, WezTerm, Ghostty, Kitty, Warp, and Apple Terminal. For VS Code, Cursor, Windsurf, Alacritty, and Zed, run `/terminal-setup` to install the binding.

77</Tip>77</Tip>

78 78 

79### Quick commands79### Quick commands


165| `>>` | Indent line |165| `>>` | Indent line |

166| `<<` | Dedent line |166| `<<` | Dedent line |

167| `J` | Join lines |167| `J` | Join lines |

168| `u` | Undo |

168| `.` | Repeat last change |169| `.` | Repeat last change |

169 170 

170### Text objects (NORMAL mode)171### Text objects (NORMAL mode)

setup.md +5 −5

Details

41 <Tab title="Native Install (Recommended)">41 <Tab title="Native Install (Recommended)">

42 **macOS, Linux, WSL:**42 **macOS, Linux, WSL:**

43 43 

44 ```bash theme={null} theme={null} theme={null} theme={null}44 ```bash theme={null}

45 curl -fsSL https://claude.ai/install.sh | bash45 curl -fsSL https://claude.ai/install.sh | bash

46 ```46 ```

47 47 

48 **Windows PowerShell:**48 **Windows PowerShell:**

49 49 

50 ```powershell theme={null} theme={null} theme={null} theme={null}50 ```powershell theme={null}

51 irm https://claude.ai/install.ps1 | iex51 irm https://claude.ai/install.ps1 | iex

52 ```52 ```

53 53 

54 **Windows CMD:**54 **Windows CMD:**

55 55 

56 ```batch theme={null} theme={null} theme={null} theme={null}56 ```batch theme={null}

57 curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd57 curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd

58 ```58 ```

59 59 


67 </Tab>67 </Tab>

68 68 

69 <Tab title="Homebrew">69 <Tab title="Homebrew">

70 ```bash theme={null} theme={null} theme={null} theme={null}70 ```bash theme={null}

71 brew install --cask claude-code71 brew install --cask claude-code

72 ```72 ```

73 73 


79 </Tab>79 </Tab>

80 80 

81 <Tab title="WinGet">81 <Tab title="WinGet">

82 ```powershell theme={null} theme={null} theme={null} theme={null}82 ```powershell theme={null}

83 winget install Anthropic.ClaudeCode83 winget install Anthropic.ClaudeCode

84 ```84 ```

85 85 

terminal-config.md +106 −65

Details

2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt

3> Use this file to discover all available pages before exploring further.3> Use this file to discover all available pages before exploring further.

4 4 

5# Optimize your terminal setup5# Configure your terminal for Claude Code

6 6 

7> Claude Code works best when your terminal is properly configured. Follow these guidelines to optimize your experience.7> Fix Shift+Enter for newlines, get a terminal bell when Claude finishes, configure tmux, match the color theme, and enable Vim mode in the Claude Code CLI.

8 8 

9### Themes and appearance9Claude Code works in any terminal without configuration. This page is for when something specific is not behaving the way you expect. Find your symptom below. If everything already feels right, you do not need this page.

10 10 

11Claude cannot control the theme of your terminal. That's handled by your terminal application. You can match Claude Code's theme to your terminal via the `/theme` command. Select `auto` in the theme picker to have Claude Code follow your terminal's dark or light mode automatically.11* [Shift+Enter submits instead of inserting a newline](#enter-multiline-prompts)

12* [Option-key shortcuts do nothing on macOS](#enable-option-key-shortcuts-on-macos)

13* [No sound or alert when Claude finishes](#get-a-terminal-bell-or-notification)

14* [You run Claude Code inside tmux](#configure-tmux)

15* [Display flickers or scrollback jumps](#switch-to-fullscreen-rendering)

16* [You want Vim keys in the prompt](#edit-prompts-with-vim-keybindings)

12 17 

13For additional customization of the Claude Code interface itself, you can configure a [custom status line](/en/statusline) to display contextual information like the current model, working directory, or git branch at the bottom of your terminal.18This page is about getting your terminal to send the right signals to Claude Code. To change which keys Claude Code itself responds to, see [keybindings](/en/keybindings) instead.

14 19 

15### Line breaks20## Enter multiline prompts

16 21 

17You have several options for entering line breaks into Claude Code:22Pressing Enter submits your message. To add a line break without submitting, press Ctrl+J, or type `\` and then press Enter. Both work in every terminal with no setup.

18 23 

19* **Quick escape**: Type `\` followed by Enter to create a newline24In most terminals you can also press Shift+Enter, but support varies by terminal emulator:

20* **Ctrl+J**: Sends a line feed character, which works as a newline in any terminal without configuration

21* **Shift+Enter**: Works out of the box in iTerm2, WezTerm, Ghostty, and Kitty

22* **Keyboard shortcut**: Set up a keybinding to insert a newline in other terminals

23 25 

24#### Set up Shift+Enter with /terminal-setup26| Terminal | Shift+Enter for newline |

27| :---------------------------------------------------------------------------------- | :------------------------------------------ |

28| Ghostty, Kitty, iTerm2, WezTerm, Warp, Apple Terminal | Works without setup |

29| VS Code, Cursor, Windsurf, Alacritty, Zed | Run `/terminal-setup` once |

30| Windows Terminal, gnome-terminal, JetBrains IDEs such as PyCharm and Android Studio | Not available; use Ctrl+J or `\` then Enter |

25 31 

26Run `/terminal-setup` within Claude Code to automatically configure Shift+Enter for VS Code, Alacritty, Zed, and Warp.32For VS Code, Cursor, Windsurf, Alacritty, and Zed, `/terminal-setup` writes Shift+Enter and other keybindings into the terminal's configuration file. If it reports a conflict such as `Found existing VSCode terminal Shift+Enter key binding`, remove that entry from the terminal's own keybindings file, for example VS Code's `keybindings.json`, and run the command again. Run `/terminal-setup` directly in the host terminal rather than inside tmux or screen, since it needs to write to the host terminal's configuration.

27 33 

28<Note>34If you are running inside tmux, Shift+Enter also requires the [tmux configuration below](#configure-tmux) even when the outer terminal supports it.

29 The `/terminal-setup` command is only visible in terminals that require manual configuration. If you're using iTerm2, WezTerm, Ghostty, or Kitty, you won't see this command because Shift+Enter already works natively.

30</Note>

31 35 

32#### Set up Shift+Enter in tmux36To bind newline to a different key, or to swap behavior so Enter inserts a newline and Shift+Enter submits, map the `chat:newline` and `chat:submit` actions in your [keybindings file](/en/keybindings).

33 37 

34Inside tmux, `Shift+Enter` submits instead of inserting a newline unless extended key reporting is enabled. Add these lines to `~/.tmux.conf`, then run `tmux source-file ~/.tmux.conf` to reload your configuration:38## Enable Option key shortcuts on macOS

35 39 

36```text theme={null}40Some Claude Code shortcuts use the Option key, such as Option+Enter for a newline or Option+P to switch models. On macOS, most terminals do not send Option as a modifier by default, so these shortcuts do nothing until you enable it. The terminal setting for this is usually labeled "Use Option as Meta Key"; Meta is the historical Unix name for the key now labeled Option or Alt.

37set -s extended-keys on

38set -as terminal-features 'xterm*:extkeys'

39```

40 

41Claude Code requests extended keys at startup, but tmux ignores the request unless `extended-keys` is set to `on`. The `terminal-features` line tells tmux that your outer terminal can send these sequences.

42 

43#### Set up Option+Enter on macOS

44 

45On macOS, you can use Option+Enter as the newline keybinding in Terminal.app, iTerm2, and the VS Code terminal after enabling the Option-as-Meta setting.

46 41 

47<Tabs>42<Tabs>

48 <Tab title="Terminal.app">43 <Tab title="Apple Terminal">

49 1. Open Settings → Profiles → Keyboard44 Open Settings → Profiles → Keyboard and check "Use Option as Meta Key".

50 2. Check "Use Option as Meta Key"45 

46 If you accepted Claude Code's first-run prompt that offered "Option+Enter for newlines and visual bell", this is already done. That prompt runs `/terminal-setup` for you, which enables Option as Meta and switches the audio bell to a visual screen flash in your Apple Terminal profile.

51 </Tab>47 </Tab>

52 48 

53 <Tab title="iTerm2">49 <Tab title="iTerm2">

54 1. Open Settings → Profiles → Keys50 Open Settings → Profiles → Keys → General and set Left Option key and Right Option key to "Esc+".

55 2. Under General, set Left/Right Option key to "Esc+"

56 </Tab>51 </Tab>

57 52 

58 <Tab title="VS Code">53 <Tab title="VS Code">

59 Set `"terminal.integrated.macOptionIsMeta": true` in VS Code settings.54 Add `"terminal.integrated.macOptionIsMeta": true` to your VS Code settings.

60 </Tab>55 </Tab>

61</Tabs>56</Tabs>

62 57 

63### Notification setup58For Ghostty, Kitty, and other terminals, look for an Option-as-Alt or Option-as-Meta setting in the terminal's configuration file.

59 

60## Get a terminal bell or notification

61 

62When Claude finishes a task or pauses for a permission prompt, it fires a notification event. Surfacing this as a terminal bell or desktop notification lets you switch to other work while a long task runs.

63 

64Claude Code sends a desktop notification only in Ghostty, Kitty, and iTerm2; every other terminal needs a [Notification hook](#play-a-sound-with-a-notification-hook) instead. The notification also reaches your local machine over SSH, so a remote session can still alert you. Ghostty and Kitty forward it to your OS notification center without further setup. iTerm2 requires you to enable forwarding:

64 65 

65When Claude finishes working and is waiting for your input, it fires a notification event. You can surface this event as a desktop notification through your terminal or run custom logic with [notification hooks](/en/hooks#notification).66<Steps>

67 <Step title="Open iTerm2 notification settings">

68 Go to Settings → Profiles → Terminal.

69 </Step>

66 70 

67#### Terminal notifications71 <Step title="Enable alerts">

72 Check "Notification Center Alerts", then click "Filter Alerts" and enable "Send escape sequence-generated alerts".

73 </Step>

74</Steps>

68 75 

69Kitty and Ghostty support desktop notifications without additional configuration. iTerm 2 requires setup:76If notifications still do not appear, confirm that your terminal application has notification permission in your OS settings, and if you are running inside tmux, [enable passthrough](#configure-tmux).

70 77 

711. Open iTerm 2 Settings Profiles Terminal78### Play a sound with a Notification hook

722. Enable "Notification Center Alerts"

733. Click "Filter Alerts" and check "Send escape sequence-generated alerts"

74 79 

75If notifications aren't appearing, verify that your terminal app has notification permissions in your OS settings.80In any terminal you can configure a [Notification hook](/en/hooks-guide#get-notified-when-claude-needs-input) to play a sound or run a custom command when Claude needs your attention. Hooks run alongside the desktop notification rather than replacing it. Terminals such as Warp or Apple Terminal rely on a hook alone since Claude Code does not send them a desktop notification.

76 81 

77When running Claude Code inside tmux, notifications and the [terminal progress bar](/en/settings#global-config-settings) only reach the outer terminal, such as iTerm2, Kitty, or Ghostty, if you enable passthrough in your tmux configuration:82The example below plays a system sound on macOS. The linked guide has desktop notification commands for macOS, Linux, and Windows.

78 83 

84```json ~/.claude/settings.json theme={null}

85{

86 "hooks": {

87 "Notification": [

88 {

89 "hooks": [{ "type": "command", "command": "afplay /System/Library/Sounds/Glass.aiff" }]

90 }

91 ]

92 }

93}

79```94```

95 

96## Configure tmux

97 

98When Claude Code runs inside tmux, two things break by default: Shift+Enter submits instead of inserting a newline, and desktop notifications and the [progress bar](/en/settings#global-config-settings) never reach the outer terminal. Add these lines to `~/.tmux.conf`, then run `tmux source-file ~/.tmux.conf` to apply them to the running server:

99 

100```bash ~/.tmux.conf theme={null}

80set -g allow-passthrough on101set -g allow-passthrough on

102set -s extended-keys on

103set -as terminal-features 'xterm*:extkeys'

81```104```

82 105 

83Without this setting, tmux intercepts the escape sequences and they do not reach the terminal application.106The `allow-passthrough` line lets notifications and progress updates reach iTerm2, Ghostty, or Kitty instead of being swallowed by tmux. The `extended-keys` lines let tmux distinguish Shift+Enter from plain Enter so the newline shortcut works.

107 

108## Match the color theme

109 

110Use the `/theme` command, or the theme picker in `/config`, to choose a Claude Code theme that matches your terminal. Selecting the auto option detects your terminal's light or dark background, so the theme follows OS appearance changes whenever your terminal does. The available themes are built in; there is no custom theme file. Claude Code does not control the terminal's own color scheme, which is set by the terminal application.

111 

112To customize what appears at the bottom of the interface, configure a [custom status line](/en/statusline) that shows the current model, working directory, git branch, or other context.

113 

114## Switch to fullscreen rendering

115 

116If the display flickers or the scroll position jumps while Claude is working, switch to [fullscreen rendering mode](/en/fullscreen). It draws to a separate screen the terminal reserves for full-screen apps instead of appending to your normal scrollback, which keeps memory usage flat and adds mouse support for scrolling and selection. In this mode you scroll with the mouse or PageUp inside Claude Code rather than with your terminal's native scrollback; see the [fullscreen page](/en/fullscreen#search-and-review-the-conversation) for how to search and copy.

84 117 

85Other terminals, including the default macOS Terminal, do not support native notifications. Use [notification hooks](/en/hooks#notification) instead.118Run `/tui fullscreen` to switch in the current session with your conversation intact. To make it the default, set the `CLAUDE_CODE_NO_FLICKER` environment variable before starting Claude Code:

86 119 

87#### Notification hooks120<CodeGroup>

121 ```bash Bash and Zsh theme={null}

122 CLAUDE_CODE_NO_FLICKER=1 claude

123 ```

88 124 

89To add custom behavior when notifications fire, such as playing a sound or sending a message, configure a [notification hook](/en/hooks#notification). Hooks run alongside terminal notifications, not as a replacement.125 ```powershell PowerShell theme={null}

126 $env:CLAUDE_CODE_NO_FLICKER = "1"; claude

127 ```

90 128 

91### Reduce flicker and memory usage129 ```json ~/.claude/settings.json theme={null}

130 {

131 "env": {

132 "CLAUDE_CODE_NO_FLICKER": "1"

133 }

134 }

135 ```

136</CodeGroup>

92 137 

93If you see flicker during long sessions, or your terminal scroll position jumps to the top while Claude is working, try [fullscreen rendering](/en/fullscreen). It uses an alternate rendering path that keeps memory flat and adds mouse support. Run `/tui fullscreen` to switch in your current conversation.138## Paste large content

94 139 

95### Handling large inputs140When you paste more than 10,000 characters into the prompt, Claude Code collapses the input to a `[Pasted text]` placeholder so the input box stays usable. The full content is still sent to Claude when you submit.

96 141 

97When working with extensive code or long instructions:142The VS Code integrated terminal can drop characters from very large pastes before they reach Claude Code, so prefer file-based workflows there. For very large inputs such as entire files or long logs, write the content to a file and ask Claude to read it instead of pasting. This keeps the conversation transcript readable and lets Claude reference the file by path in later turns.

98 143 

99* **Avoid direct pasting**: Claude Code may struggle with very long pasted content144## Edit prompts with Vim keybindings

100* **Use file-based workflows**: Write content to a file and ask Claude to read it

101* **Be aware of VS Code limitations**: The VS Code terminal is particularly prone to truncating long pastes

102 145 

103### Vim Mode146Claude Code includes a Vim-style editing mode for the prompt input. Enable it through `/config` → Editor mode, or by setting the [`editorMode`](/en/settings#global-config-settings) global config key to `"vim"` in `~/.claude.json`. Set Editor mode back to `normal` to turn it off.

104 147 

105Claude Code supports a subset of Vim keybindings that can be enabled via `/config` Editor mode. To set the mode directly in your config file, set the [`editorMode`](/en/settings#global-config-settings) global config key to `"vim"` in `~/.claude.json`.148Vim mode supports a subset of NORMAL-mode motions and operators, such as `hjkl` navigation and `d`/`c`/`y` with text objects. See the [Vim editor mode reference](/en/interactive-mode#vim-editor-mode) for the full key table. Vim motions are not remappable through the keybindings file.

106 149 

107The supported subset includes:150Pressing Enter still submits your prompt in INSERT mode, unlike standard Vim. Use `o` or `O` in NORMAL mode, or Ctrl+J, to insert a newline instead.

108 151 

109* Mode switching: `Esc` (to NORMAL), `i`/`I`, `a`/`A`, `o`/`O` (to INSERT)152## Related resources

110* Navigation: `h`/`j`/`k`/`l`, `w`/`e`/`b`, `0`/`$`/`^`, `gg`/`G`, `f`/`F`/`t`/`T` with `;`/`,` repeat

111* Editing: `x`, `dw`/`de`/`db`/`dd`/`D`, `cw`/`ce`/`cb`/`cc`/`C`, `.` (repeat)

112* Yank/paste: `yy`/`Y`, `yw`/`ye`/`yb`, `p`/`P`

113* Text objects: `iw`/`aw`, `iW`/`aW`, `i"`/`a"`, `i'`/`a'`, `i(`/`a(`, `i[`/`a[`, `i{`/`a{`

114* Indentation: `>>`/`<<`

115* Line operations: `J` (join lines)

116 153 

117See [Interactive mode](/en/interactive-mode#vim-editor-mode) for the complete reference.154* [Interactive mode](/en/interactive-mode): full keyboard shortcut reference and the Vim key table

155* [Keybindings](/en/keybindings): remap any Claude Code shortcut, including Enter and Shift+Enter

156* [Fullscreen rendering](/en/fullscreen): details on scrolling, search, and copy in fullscreen mode

157* [Hooks guide](/en/hooks-guide): more Notification hook examples for Linux and Windows

158* [Troubleshooting](/en/troubleshooting): fixes for issues outside terminal configuration