SpyBara
Go Premium

Documentation 2026-10-26 22:57 UTC to 2026-10-27 22:59 UTC

68 files changed +931 −597. View all changes and history on the product overview
2026
Fri 30 23:01 Thu 29 23:57 Wed 28 23:57 Tue 27 22:59 Mon 26 22:57 Sun 25 23:58 Sat 24 22:59 Fri 23 22:59 Thu 22 22:58 Wed 21 23:02 Tue 20 23:00 Mon 19 23:58 Sat 17 23:57 Fri 16 22:59 Thu 15 23:58 Wed 14 22:58 Tue 13 23:57 Sun 11 23:57 Sat 10 23:01 Fri 9 23:02 Thu 8 22:58 Wed 7 23:59 Tue 6 23:59 Mon 5 23:58 Sun 4 23:58 Sat 3 23:57 Fri 2 22:59 Thu 1 23:59
Details

79| `Permission Required:` | A permission prompt waiting for your answer |79| `Permission Required:` | A permission prompt waiting for your answer |

80| `Cost:` | The session cost summary when Claude Code exits, if your account [shows costs](https://code.claude.com/docs/en/costs.md) |80| `Cost:` | The session cost summary when Claude Code exits, if your account [shows costs](https://code.claude.com/docs/en/costs.md) |

81 81 

82Claude Code keeps the terminal cursor on the input caret, so your screen reader's read-current-line command reads the prompt you're editing.82Claude Code keeps the terminal cursor on the input caret, so your screen reader's read-current-line command reads the prompt you're editing. As you type at the end of the input line, or press `Backspace` there, Claude Code writes only the characters that change. Your screen reader echoes only those characters.

83 

84As you type at the end of the input line, or press `Backspace` there, Claude Code writes only the characters that change. Your screen reader echoes only those characters.

85 83 

86When you delete a word or a line with one of the [text editing shortcuts](https://code.claude.com/docs/en/interactive-mode.md#text-editing), Claude Code announces the deleted text:84When you delete a word or a line with one of the [text editing shortcuts](https://code.claude.com/docs/en/interactive-mode.md#text-editing), Claude Code announces the deleted text:

87 85 

admin-setup.md +1 −0

Details

191* [Server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md): deliver managed policy from the Claude admin console191* [Server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md): deliver managed policy from the Claude admin console

192* [All settings](https://code.claude.com/docs/en/settings-reference.md): every setting key, with where it goes and an example192* [All settings](https://code.claude.com/docs/en/settings-reference.md): every setting key, with where it goes and an example

193* [Which value Claude Code uses](https://code.claude.com/docs/en/settings.md#which-value-claude-code-uses): the precedence rules across managed, project, local, and user settings193* [Which value Claude Code uses](https://code.claude.com/docs/en/settings.md#which-value-claude-code-uses): the precedence rules across managed, project, local, and user settings

194* [Manage plugins for your organization](https://code.claude.com/docs/en/plugins/org.md): install shared plugins on every machine through managed settings

194* [Monorepos and large repos](https://code.claude.com/docs/en/large-codebases.md): per-directory configuration patterns for organizations deploying into a monorepo195* [Monorepos and large repos](https://code.claude.com/docs/en/large-codebases.md): per-directory configuration patterns for organizations deploying into a monorepo

195* [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md), [Google Cloud's Agent Platform](https://code.claude.com/docs/en/google-vertex-ai.md), [Microsoft Foundry](https://code.claude.com/docs/en/microsoft-foundry.md): provider-specific deployment196* [Amazon Bedrock](https://code.claude.com/docs/en/amazon-bedrock.md), [Google Cloud's Agent Platform](https://code.claude.com/docs/en/google-vertex-ai.md), [Microsoft Foundry](https://code.claude.com/docs/en/microsoft-foundry.md): provider-specific deployment

196* [Claude Enterprise Administrator Guide](https://claude.com/resources/tutorials/claude-enterprise-administrator-guide): SSO, SCIM, seat management, and rollout playbook197* [Claude Enterprise Administrator Guide](https://claude.com/resources/tutorials/claude-enterprise-administrator-guide): SSO, SCIM, seat management, and rollout playbook

Details

41 41 

42That was four turns: three with tool calls, one final text-only response.42That was four turns: three with tool calls, one final text-only response.

43 43 

44You can cap the loop with `max_turns` / `maxTurns`, which counts tool-use turns only. For example, `max_turns=2` in the loop above would have stopped before the edit step. You can also use `max_budget_usd` / `maxBudgetUsd` to cap turns based on a spend threshold.44You can cap the loop with `max_turns` / `maxTurns`. Count each turn with tool calls, plus one for the final text-only response. Without that extra turn, the run ends with a `ResultMessage` of subtype `error_max_turns` and no final response. For example, `max_turns=2` in the loop above would have stopped before the edit step. You can also use `max_budget_usd` / `maxBudgetUsd` to cap turns based on a spend threshold.

45 45 

46Without limits, the loop runs until Claude finishes on its own, which is fine for well-scoped tasks but can run long on open-ended prompts ("improve this codebase"). Setting a budget is a good default for production agents. See [Turns and budget](#turns-and-budget) below for the option reference.46Without limits, the loop runs until Claude finishes on its own, which is fine for well-scoped tasks but can run long on open-ended prompts ("improve this codebase"). Setting a budget is a good default for production agents. See [Turns and budget](#turns-and-budget) below for the option reference.

47 47 


191 191 

192| Option | What it controls | Default |192| Option | What it controls | Default |

193| :- | :- | :- |193| :- | :- | :- |

194| Max turns (`max_turns` / `maxTurns`) | Maximum tool-use round trips | No limit |194| Max turns (`max_turns` / `maxTurns`) | Maximum number of [turns](#turns-and-messages) | No limit |

195| Max budget (`max_budget_usd` / `maxBudgetUsd`) | Estimated spend at which the loop stops | No limit |195| Max budget (`max_budget_usd` / `maxBudgetUsd`) | Estimated spend at which the loop stops | No limit |

196 196 

197When either limit is hit, the SDK returns a `ResultMessage` with a corresponding error subtype (`error_max_turns` or `error_max_budget_usd`). See [Handle the result](#handle-the-result) for how to check these subtypes and [`ClaudeAgentOptions`](https://code.claude.com/docs/en/agent-sdk/python#claudeagentoptions) / [`Options`](https://code.claude.com/docs/en/agent-sdk/typescript#options) for syntax.197When either limit is hit, the SDK returns a `ResultMessage` with a corresponding error subtype (`error_max_turns` or `error_max_budget_usd`). See [Handle the result](#handle-the-result) for how to check these subtypes and [`ClaudeAgentOptions`](https://code.claude.com/docs/en/agent-sdk/python#claudeagentoptions) / [`Options`](https://code.claude.com/docs/en/agent-sdk/typescript#options) for syntax.

Details

161 161 

162Both languages have the same setters:162Both languages have the same setters:

163 163 

164* **`setModel()` / `set_model()`**: switches the model. Call it with no model to switch to [Claude Code's default model](https://code.claude.com/docs/en/model-config.md#default-model-setting) rather than the `model` you passed in options.164* **`setModel()` / `set_model()`**: switches the model. Call it with no model to switch to [Claude Code's default model](https://code.claude.com/docs/en/model-config.md#default-model-setting) rather than the `model` you passed in options. If the session is in auto mode and you switch to a model that auto mode doesn't support, the session changes to `default` mode. To return to auto mode, see [Auto mode (`auto`)](https://code.claude.com/docs/en/agent-sdk/permissions#auto-mode-auto).

165* **`setPermissionMode()` / `set_permission_mode()`**: switches the permission mode165* **`setPermissionMode()` / `set_permission_mode()`**: switches the permission mode

166 166 

167TypeScript also has `applyFlagSettings()` and `updateSettings()`:167TypeScript also has `applyFlagSettings()` and `updateSettings()`:

Details

192 192 

193The container needs your SDK's language runtime:193The container needs your SDK's language runtime:

194 194 

195* Python 3.10+ for the Python SDK, or Node.js 18+ for the TypeScript SDK195* Python 3.10+ for the Python SDK, or Node.js 18.14+ for the TypeScript SDK

196* Both the TypeScript and Python SDKs bundle a native Claude Code binary for most installs, and the spawned CLI needs no separate Node.js install. See the [quickstart's install note](https://code.claude.com/docs/en/agent-sdk/quickstart.md) for the installs that need a separate native Claude Code install.196* Both the TypeScript and Python SDKs bundle a native Claude Code binary for most installs, and the spawned CLI needs no separate Node.js install. See the [quickstart's install note](https://code.claude.com/docs/en/agent-sdk/quickstart.md) for the installs that need a separate native Claude Code install.

197 197 

198The bundled binary is pinned to the SDK package version, so updating the SDK is how you update the CLI. The SDK follows semver: take patch releases continuously and review the [TypeScript](https://github.com/anthropics/claude-agent-sdk-typescript/blob/main/CHANGELOG.md) or [Python](https://github.com/anthropics/claude-agent-sdk-python/blob/main/CHANGELOG.md) changelog before taking a minor.198The bundled binary is pinned to the SDK package version, so updating the SDK is how you update the CLI. The SDK follows semver: take patch releases continuously and review the [TypeScript](https://github.com/anthropics/claude-agent-sdk-typescript/blob/main/CHANGELOG.md) or [Python](https://github.com/anthropics/claude-agent-sdk-python/blob/main/CHANGELOG.md) changelog before taking a minor.


335 335 

336| Limitation | What to do |336| Limitation | What to do |

337| - | - |337| - | - |

338| No top-level session timeout | A session does not time out on its own. Set `maxTurns` in TypeScript or `max_turns` in Python to bound how many tool-use round trips the agent takes before stopping. |338| No top-level session timeout | A session doesn't time out on its own. Set `maxTurns` in TypeScript or `max_turns` in Python to bound how many [turns](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#turns-and-messages) the agent takes before stopping. |

339| Memory growth over long sessions | Cap session length or recycle subprocesses periodically. See [Scaling and concurrency](#scaling-and-concurrency). |339| Memory growth over long sessions | Cap session length or recycle subprocesses periodically. See [Scaling and concurrency](#scaling-and-concurrency). |

340| Large parallel-subagent fanouts can hit rate limits | Break work into smaller batches rather than issuing one wide dispatch. |340| Large parallel-subagent fanouts can hit rate limits | Break work into smaller batches rather than issuing one wide dispatch. |

341| No per-subagent wall-clock deadline | Cap each [subagent](https://code.claude.com/docs/en/agent-sdk/subagents.md) with `maxTurns` in its `AgentDefinition`. `CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS` sets a stall watchdog that fires when a subagent stops producing output; it isn't a total-runtime deadline. |341| No per-subagent wall-clock deadline | Cap each [subagent](https://code.claude.com/docs/en/agent-sdk/subagents.md) with `maxTurns` in its `AgentDefinition`. `CLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MS` sets a stall watchdog that fires when a subagent stops producing output; it isn't a total-runtime deadline. |

Details

425 425 

426Set `includeGitInstructions` to `false` to keep out the built-in commit and pull request instructions, which are part of the Bash tool's description and reach Claude even with a custom `systemPrompt`. With the minimal default, a custom `systemPrompt`, or a custom main-thread agent that has its own prompt, though, the session starts without the git status snapshot.426Set `includeGitInstructions` to `false` to keep out the built-in commit and pull request instructions, which are part of the Bash tool's description and reach Claude even with a custom `systemPrompt`. With the minimal default, a custom `systemPrompt`, or a custom main-thread agent that has its own prompt, though, the session starts without the git status snapshot.

427 427 

428If you set `CLAUDE_CODE_DISABLE_ATTACHMENTS`, Claude Code also sends `@` file mentions as plain text instead of expanding them into file content. The list of available subagents and background task notifications still arrive. To stop only `@` file mentions from expanding, set [`CLAUDE_CODE_DISABLE_FILE_MENTIONS=1`](https://code.claude.com/docs/en/env-vars#variables) instead, on Claude Code v2.1.299 or later. Claude then gets the mentioned paths plus a note to read them with its file tools.428* If you set `CLAUDE_CODE_DISABLE_ATTACHMENTS`, Claude Code also sends `@` file mentions as plain text instead of expanding them into file content. The list of available subagents and background task notifications still arrive.

429* To stop only `@` file mentions from expanding, set [`CLAUDE_CODE_DISABLE_FILE_MENTIONS=1`](https://code.claude.com/docs/en/env-vars#variables) instead, on Claude Code v2.1.299 or later. Claude then gets the mentioned paths plus a note to read them with its file tools, and your `PreToolUse` hooks see each file read as a tool call.

429 430 

430The following example is for an agent that carries its own commit rules in `append`. It sets both `attribution` keys to empty strings to remove the trailer and footer, and turns off `includeGitInstructions` so Claude Code's own commit workflow instructions don't compete with yours:431The following example is for an agent that carries its own commit rules in `append`. It sets both `attribution` keys to empty strings to remove the trailer and footer, and turns off `includeGitInstructions` so Claude Code's own commit workflow instructions don't compete with yours:

431 432 

Details

43Apply the active [permission mode](#permission-modes):43Apply the active [permission mode](#permission-modes):

44 44 

45* In `bypassPermissions` mode, Claude Code approves everything that reaches this step except recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) and Bash commands flagged [`Dangerous rm operation not ruled out`](https://code.claude.com/docs/en/permission-modes#dangerous-rm-operation-not-ruled-out), which fall through instead.45* In `bypassPermissions` mode, Claude Code approves everything that reaches this step except recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) and Bash commands flagged [`Dangerous rm operation not ruled out`](https://code.claude.com/docs/en/permission-modes#dangerous-rm-operation-not-ruled-out), which fall through instead.

46 * To run those removals with no prompt, see [Turn off the critical-path removal prompt](https://code.claude.com/docs/en/permission-modes.md#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode).

46* In `acceptEdits` mode, Claude Code approves the file operations listed under [Accept edits mode](#accept-edits-mode-acceptedits).47* In `acceptEdits` mode, Claude Code approves the file operations listed under [Accept edits mode](#accept-edits-mode-acceptedits).

47* In `plan` mode, Claude Code sends file-edit tools to your `canUseTool` callback regardless of allow rules.48* In `plan` mode, Claude Code sends file-edit tools to your `canUseTool` callback regardless of allow rules.

48* In other modes, the request falls through.49* In other modes, the request falls through.


305> `allowed_tools` does not constrain this mode. Every tool is approved, not just the ones you listed. These controls still apply:306> `allowed_tools` does not constrain this mode. Every tool is approved, not just the ones you listed. These controls still apply:

306>307>

307> * Deny rules, explicit `ask` rules, and hooks are evaluated before the mode check and can still block a tool.308> * Deny rules, explicit `ask` rules, and hooks are evaluated before the mode check and can still block a tool.

308> * Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, and recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) still fall through to your `canUseTool` callback. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths). Outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), calls to custom tools your application [marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools) fall through to the callback too.309> * Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, and recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) still fall through to your `canUseTool` callback. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths), and you can [turn off the critical-path removal prompt](https://code.claude.com/docs/en/permission-modes.md#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode). Outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), calls to custom tools your application [marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools) fall through to the callback too.

309> * The [cross-session messaging safeguards](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) still apply.310> * The [cross-session messaging safeguards](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) still apply.

310 311 

311#### Plan mode (`plan`)312#### Plan mode (`plan`)

Details

880| `continue_conversation` | `bool` | `False` | Continue the most recent conversation |880| `continue_conversation` | `bool` | `False` | Continue the most recent conversation |

881| `resume` | `str \| None` | `None` | Session ID to resume |881| `resume` | `str \| None` | `None` | Session ID to resume |

882| `session_id` | `str \| None` | `None` | Use a specific session ID instead of an auto-generated one. Must be a valid UUID. Can't be combined with `continue_conversation` or `resume` unless `fork_session` is also set |882| `session_id` | `str \| None` | `None` | Use a specific session ID instead of an auto-generated one. Must be a valid UUID. Can't be combined with `continue_conversation` or `resume` unless `fork_session` is also set |

883| `max_turns` | `int \| None` | `None` | Maximum agentic turns (tool-use round trips) |883| `max_turns` | `int \| None` | `None` | Maximum agentic [turns](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#turns-and-messages) |

884| `max_budget_usd` | `float \| None` | `None` | Stop the query when the client-side cost estimate reaches this USD value. The estimate can pass this value, so [leave headroom](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#budget-headroom). Counts only the call's own spend; totals restored from a resumed session don't count. For accuracy caveats and reset behavior, see [Track cost and usage](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md) |884| `max_budget_usd` | `float \| None` | `None` | Stop the query when the client-side cost estimate reaches this USD value. The estimate can pass this value, so [leave headroom](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#budget-headroom). Counts only the call's own spend; totals restored from a resumed session don't count. For accuracy caveats and reset behavior, see [Track cost and usage](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md) |

885| `disallowed_tools` | `list[str]` | `[]` | Tools to deny. A bare name such as `"Bash"` removes the tool from Claude's context. A scoped rule such as `"Bash(rm *)"` leaves the tool available and denies matching calls in every permission mode, including `bypassPermissions`, for the command [as written](https://code.claude.com/docs/en/permissions.md#bash-rule-limits). See [Permissions](https://code.claude.com/docs/en/agent-sdk/permissions.md#allow-and-deny-rules) |885| `disallowed_tools` | `list[str]` | `[]` | Tools to deny. A bare name such as `"Bash"` removes the tool from Claude's context. A scoped rule such as `"Bash(rm *)"` leaves the tool available and denies matching calls in every permission mode, including `bypassPermissions`, for the command [as written](https://code.claude.com/docs/en/permissions.md#bash-rule-limits). See [Permissions](https://code.claude.com/docs/en/agent-sdk/permissions.md#allow-and-deny-rules) |

886| `enable_file_checkpointing` | `bool` | `False` | Enable file change tracking for rewinding. See [File checkpointing](https://code.claude.com/docs/en/agent-sdk/file-checkpointing.md) |886| `enable_file_checkpointing` | `bool` | `False` | Enable file change tracking for rewinding. See [File checkpointing](https://code.claude.com/docs/en/agent-sdk/file-checkpointing.md) |


2568 2568 

2569### Agent2569### Agent

2570 2570 

2571**Tool name:** `Agent`. The previous name `Task` is still accepted as an alias, and the `tools` list in the init [`SystemMessage`](#systemmessage) reports this tool as `Task` for backward compatibility.2571**Tool name:** `Agent`. The previous name `Task` is still accepted as an alias when this tool is available to the session.

2572 

2573The `tools` list in the init [`SystemMessage`](#systemmessage) reports this tool as `Task` for backward compatibility.

2572 2574 

2573**Input:**2575**Input:**

2574 2576 


3642| `deniedDomains` | `list[str]` | `[]` | Domain names that sandboxed processes cannot access. Takes precedence over `allowedDomains` |3644| `deniedDomains` | `list[str]` | `[]` | Domain names that sandboxed processes cannot access. Takes precedence over `allowedDomains` |

3643| `allowManagedDomainsOnly` | `bool` | `False` | Managed-settings only: when set in managed settings, ignore `allowedDomains` and `WebFetch(domain:...)` allow rules from non-managed settings sources. Has no effect when set via SDK options |3645| `allowManagedDomainsOnly` | `bool` | `False` | Managed-settings only: when set in managed settings, ignore `allowedDomains` and `WebFetch(domain:...)` allow rules from non-managed settings sources. Has no effect when set via SDK options |

3644| `allowUnixSockets` | `list[str]` | `[]` | macOS only: Unix socket paths that processes can access, such as the Docker socket. Ignored on Linux |3646| `allowUnixSockets` | `list[str]` | `[]` | macOS only: Unix socket paths that processes can access, such as the Docker socket. Ignored on Linux |

3645| `allowAllUnixSockets` | `bool` | `False` | Allow access to all Unix sockets |3647| `allowAllUnixSockets` | `bool` | `False` | Allow access to all Unix sockets, and on Linux to VM sockets (`AF_VSOCK`) |

3646| `allowLocalBinding` | `bool` | `False` | Allow processes to bind to local ports (for example, for dev servers) |3648| `allowLocalBinding` | `bool` | `False` | Allow processes to bind to local ports (for example, for dev servers) |

3647| `allowMachLookup` | `list[str]` | `[]` | macOS only: XPC/Mach service names to allow. Supports a trailing wildcard |3649| `allowMachLookup` | `list[str]` | `[]` | macOS only: XPC/Mach service names to allow. Supports a trailing wildcard |

3648| `httpProxyPort` | `int` | `None` | HTTP proxy port for network requests |3650| `httpProxyPort` | `int` | `None` | HTTP proxy port for network requests |

Details

16 16 

17## Prerequisites17## Prerequisites

18 18 

19* **Node.js 18+** or **Python 3.10+**19* **Node.js 18.14+** or **Python 3.10+**

20* An **Anthropic account**. If you don't have one, [sign up here](https://platform.claude.com/).20* An **Anthropic account**. If you don't have one, [sign up here](https://platform.claude.com/).

21 21 

22## Setup22## Setup

Details

118 118 

119### Handle a stream that's cut off119### Handle a stream that's cut off

120 120 

121If a stream is cut off mid-message, such as when you interrupt the turn or the connection drops, you still receive that message's `message_stop` before the turn ends. A cut text or thinking block also gets its `content_block_stop`. A cut tool call doesn't, so if `message_stop` arrives while a tool call's block is still open, treat that call's input as incomplete.121If a stream is cut off mid-message, you still receive that message's `message_stop` before the turn ends. Causes of a cut-off stream include an interrupted turn, a dropped connection, and a fallback to a non-streaming request. `content_block_stop` and `message_delta` can be missing before that `message_stop`:

122 

123* **`content_block_stop`**: arrives for the block that was open, unless that block is a tool call. If `message_stop` arrives while a tool call's block is still open, treat that call's input as incomplete.

124* **`message_delta`**: arrives when you interrupt the turn, and can be missing after a dropped connection or a fallback to non-streaming, so don't wait for one on a cut message.

122 125 

123Before Claude Code v2.1.290, a cut stream could end the turn without `message_stop`, so a reply you render from stream events could stay shown as in progress. The TypeScript Agent SDK bundles Claude Code v2.1.290 or later from v0.3.290, and the Python Agent SDK from v0.2.164. If a reply stays shown as in progress after the turn ends, update the SDK.126Before Claude Code v2.1.290, a cut stream could end the turn without `message_stop`, so a reply you render from stream events could stay shown as in progress. The TypeScript Agent SDK bundles Claude Code v2.1.290 or later from v0.3.290, and the Python Agent SDK from v0.2.164. If a reply stays shown as in progress after the turn ends, update the SDK.

124 127 

Details

105 105 

106Returns a `Promise<`[`WarmQuery`](#warmquery)`>` that resolves once the subprocess has spawned and completed its initialize handshake.106Returns a `Promise<`[`WarmQuery`](#warmquery)`>` that resolves once the subprocess has spawned and completed its initialize handshake.

107 107 

108Of the [`hook_progress`](#sdkhookprogressmessage) messages a `SessionStart` or `Setup` hook emits before the handshake completes, you get only the newest, which carries all of the hook's output so far. `startup()` holds that message, the hook's [`hook_started`](#sdkhookstartedmessage) message, and anything else the subprocess emits before the handshake completes. The held messages reach you once you call `.query()` on the `WarmQuery` and iterate the result.

109 

108#### Example110#### Example

109 111 

110Call `startup()` early, for example on application boot, then call `.query()` on the returned handle once a prompt is ready. This moves subprocess spawn and initialization out of the critical path.112Call `startup()` early, for example on application boot, then call `.query()` on the returned handle once a prompt is ready. This moves subprocess spawn and initialization out of the critical path.


524| `managedSettings` | `Settings` | `undefined` | Policy-tier settings your host process supplies to the spawned session. On machines with admin-deployed managed settings, Claude Code ignores these unless the admin's highest-priority managed source sets `parentSettingsBehavior: 'merge'`, and never merges them while a [`policyHelper`](https://code.claude.com/docs/en/settings-reference#policyhelper) supplies managed settings. Merged values pass through a restrictive-only filter; [Restrict parent settings](https://code.claude.com/docs/en/claude-apps-gateway#restrict-parent-settings) covers what the filter admits and the `allowManaged*Only` locks. A host that sets [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](https://code.claude.com/docs/en/env-vars) has three keys read straight from this payload instead: its [model configuration](https://code.claude.com/docs/en/model-config.md#restrict-model-selection) on Claude Code v2.1.222 or later, [`modelPricing`](https://code.claude.com/docs/en/settings-reference#modelpricing) when no managed source sets it on v2.1.246 or later, and its `ENABLE_TOOL_SEARCH` env entry on v2.1.247 or later |526| `managedSettings` | `Settings` | `undefined` | Policy-tier settings your host process supplies to the spawned session. On machines with admin-deployed managed settings, Claude Code ignores these unless the admin's highest-priority managed source sets `parentSettingsBehavior: 'merge'`, and never merges them while a [`policyHelper`](https://code.claude.com/docs/en/settings-reference#policyhelper) supplies managed settings. Merged values pass through a restrictive-only filter; [Restrict parent settings](https://code.claude.com/docs/en/claude-apps-gateway#restrict-parent-settings) covers what the filter admits and the `allowManaged*Only` locks. A host that sets [`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`](https://code.claude.com/docs/en/env-vars) has three keys read straight from this payload instead: its [model configuration](https://code.claude.com/docs/en/model-config.md#restrict-model-selection) on Claude Code v2.1.222 or later, [`modelPricing`](https://code.claude.com/docs/en/settings-reference#modelpricing) when no managed source sets it on v2.1.246 or later, and its `ENABLE_TOOL_SEARCH` env entry on v2.1.247 or later |

525| `maxBudgetUsd` | `number` | `undefined` | Stop the query when the client-side cost estimate reaches this USD value. The estimate can pass this value, so [leave headroom](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#budget-headroom). Counts only the call's own spend; totals restored from a resumed session don't count. For accuracy caveats and reset behavior, see [Track cost and usage](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md) |527| `maxBudgetUsd` | `number` | `undefined` | Stop the query when the client-side cost estimate reaches this USD value. The estimate can pass this value, so [leave headroom](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#budget-headroom). Counts only the call's own spend; totals restored from a resumed session don't count. For accuracy caveats and reset behavior, see [Track cost and usage](https://code.claude.com/docs/en/agent-sdk/cost-tracking.md) |

526| `maxThinkingTokens` | `number` | `undefined` | *Deprecated:* Use `thinking` instead. Maximum tokens for thinking process |528| `maxThinkingTokens` | `number` | `undefined` | *Deprecated:* Use `thinking` instead. Maximum tokens for thinking process |

527| `maxTurns` | `number` | `undefined` | Maximum agentic turns (tool-use round trips) |529| `maxTurns` | `number` | `undefined` | Maximum agentic [turns](https://code.claude.com/docs/en/agent-sdk/agent-loop.md#turns-and-messages) |

528| `mcpServers` | `Record<string, [`McpServerConfig`](#mcpserverconfig)>` | `{}` | MCP server configurations |530| `mcpServers` | `Record<string, [`McpServerConfig`](#mcpserverconfig)>` | `{}` | MCP server configurations |

529| `model` | `string` | Default from CLI | Claude model alias or full model name. See [accepted values and provider-specific IDs](https://code.claude.com/docs/en/model-config.md#available-models) |531| `model` | `string` | Default from CLI | Claude model alias or full model name. See [accepted values and provider-specific IDs](https://code.claude.com/docs/en/model-config.md#available-models) |

530| `onElicitation` | `(request: ElicitationRequest, options: { signal: AbortSignal }) => Promise<ElicitationResult>` | `undefined` | Callback for handling MCP elicitation requests. Called when an MCP server requests user input and no hook handles it first. When not provided, unhandled elicitation requests are declined automatically |532| `onElicitation` | `(request: ElicitationRequest, options: { signal: AbortSignal }) => Promise<ElicitationResult>` | `undefined` | Callback for handling MCP elicitation requests. Called when an MCP server requests user input and no hook handles it first. When not provided, unhandled elicitation requests are declined automatically |


1403 };1405 };

1404```1406```

1405 1407 

1408If you return `allow` with more than 4,096 items in `updatedPermissions`, Claude Code treats the result as invalid and denies the tool call. Each update counts as one item, and so does each entry in its `rules` or `directories` list. The denial message ends with `updatedPermissions may hold at most 4096 updates, rules and directories in all`. To have the call allowed, return 4,096 items or fewer.

1409 

1406### `ToolConfig`1410### `ToolConfig`

1407 1411 

1408Configuration for built-in tool behavior.1412Configuration for built-in tool behavior.


1464 1468 

1465#### `McpSdkServerConfigWithInstance`1469#### `McpSdkServerConfigWithInstance`

1466 1470 

1467The configuration for an in-process MCP server, one that [`createSdkMcpServer()`](#createsdkmcpserver) creates and that runs inside your application's process. It is the object `createSdkMcpServer()` returns, plus an optional `tools` list of [`McpServerToolPolicy`](#mcpservertoolpolicy) entries that you add yourself. To require approval for calls to one of the server's tools, or to deny them, add an entry that names the tool.1471Configuration for an in-process MCP server. It is what [`createSdkMcpServer()`](#createsdkmcpserver) returns, plus an optional `tools` list of [`McpServerToolPolicy`](#mcpservertoolpolicy) entries that you add.

1468 1472 

1469```typescript theme={null}1473```typescript theme={null}

1470type McpSdkServerConfigWithInstance = {1474type McpSdkServerConfigWithInstance = {


1476};1480};

1477```1481```

1478 1482 

1479To set a policy, spread the object `createSdkMcpServer()` returns into a new object in `mcpServers` and add the `tools` list to that new object. The `tools` option of `createSdkMcpServer()` itself is a different list, which holds the tool definitions and doesn't accept policy entries. The policy list requires Agent SDK v0.3.301 or later, and [`McpServerToolPolicy`](#mcpservertoolpolicy) describes what each `permission_policy` value does.1483To require approval for calls to one of the server's tools, or deny them, add a policy entry naming the tool. Spread what `createSdkMcpServer()` returns into an object under `mcpServers` and put the entry in a `tools` list on that object, because the function's `tools` option accepts tool definitions and not policy entries. The policy list requires Agent SDK v0.3.301 or later, and [`McpServerToolPolicy`](#mcpservertoolpolicy) describes what each `permission_policy` value does.

1480 1484 

1481This example pre-approves every tool on the `records` server with an `allowedTools` wildcard, then marks `delete_record` as `always_ask` so that calls to it go to `canUseTool` anyway. With the `destructiveHint: true` annotation, the call still reaches the callback if the session runs in `auto` mode, where the auto mode [classifier](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) could otherwise approve it.1485In this script, an `allowedTools` wildcard pre-approves every tool on the `records` server, but `delete_record` is marked `always_ask`, so calls to it go to `canUseTool` anyway. With the `destructiveHint: true` annotation, the call still reaches the callback if the session runs in `auto` mode, where the auto mode [classifier](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) could otherwise approve it.

1482 1486 

1483```typescript theme={null}1487```typescript theme={null}

1484import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";1488import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";


1517}1521}

1518```1522```

1519 1523 

1520When Claude calls the tool, the script prints `Approval requested for mcp__records__delete_record` before the `delete_record` tool runs, although the `allowedTools` entry would otherwise have approved the call.1524When Claude calls `delete_record`, the script prints `Approval requested for mcp__records__delete_record`.

1521 1525 

1522To change or lift a tool's policy while the session runs, pass the server's config with a new `tools` value to [`setMcpServers()`](#mcpsetserversresult). The `tools` value you pass takes effect from Claude's next call to that server's tools:1526To change or lift a tool's policy while the session runs, pass the server's config with a new `tools` value to [`setMcpServers()`](#mcpsetserversresult). The `tools` value you pass takes effect from Claude's next call to that server's tools:

1523 1527 


1556 1560 

1557##### Permission modes that can approve an `always_ask` call1561##### Permission modes that can approve an `always_ask` call

1558 1562 

1559In `auto`, `plan`, and `bypassPermissions` mode, a call to a tool marked [`always_ask`](#permission-policy-values) can be approved before it reaches your `canUseTool` callback. Find your session's mode in this list to see when that approval happens and what to set so the call reaches your callback anyway:1563In `auto`, `plan`, and `bypassPermissions` mode, a call to a tool marked [`always_ask`](#permission-policy-values) can be approved before it reaches your `canUseTool` callback.

1560 1564 

1561* **`auto`**: the auto mode [classifier](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) reviews the call and can allow it. To make every call reach your callback in `auto` mode, set `destructiveHint: true` in the tool's [annotations](#toolannotations)1565* **`auto`**: the auto mode [classifier](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) reviews the call and can allow it. To make every call reach your callback in `auto` mode, set `destructiveHint: true` in the tool's [annotations](#toolannotations)

1562* **`plan`**: while [auto mode is available](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) to the session, calls to an `always_ask` tool annotated `readOnlyHint: true` go to the auto mode classifier, which can allow them. Calls to other `always_ask` tools reach your callback. To make a read-only tool's calls reach your callback too, add `destructiveHint: true` to that tool's annotations alongside `readOnlyHint: true`. Alternatively, set [`useAutoModeDuringPlan`](https://code.claude.com/docs/en/settings-reference#useautomodeduringplan) to `false`, which turns the classifier off during planning1566* **`plan`**: while [auto mode is available](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) to the session, calls to an `always_ask` tool annotated `readOnlyHint: true` go to the auto mode classifier, which can allow them. Calls to other `always_ask` tools reach your callback. To make a read-only tool's calls reach your callback too, add `destructiveHint: true` to that tool's annotations alongside `readOnlyHint: true`. Alternatively, set [`useAutoModeDuringPlan`](https://code.claude.com/docs/en/settings-reference#useautomodeduringplan) to `false`, which turns the classifier off during planning


1692 1696 

1693`aborted` is `true` when an interrupt or abort truncated the assistant message before the stream completed: the message has no `stop_reason` and the content may end mid-word. The field is absent on normally completed messages. It requires Agent SDK v0.3.214 or later.1697`aborted` is `true` when an interrupt or abort truncated the assistant message before the stream completed: the message has no `stop_reason` and the content may end mid-word. The field is absent on normally completed messages. It requires Agent SDK v0.3.214 or later.

1694 1698 

1695`agent_id` identifies the subagent that produced the message and is absent on main-thread messages. The value equals the `task_id` on that subagent's [`task_started`](#sdktaskstartedmessage) and other task events, and is unchanged when the subagent is [resumed](https://code.claude.com/docs/en/agent-sdk/subagents.md#resume-subagents). The field requires Agent SDK v0.3.292 or later.1699`agent_id` identifies the subagent that produced the message and is absent on main-thread messages. The value equals the `task_id` on that subagent's [`task_started`](#sdktaskstartedmessage) and other task events, and is unchanged when the subagent is [resumed](https://code.claude.com/docs/en/agent-sdk/subagents.md#resume-subagents). On messages from a [nested subagent](https://code.claude.com/docs/en/sub-agents.md#let-subagents-spawn-their-own-subagents), it names the nested subagent, not the subagent that spawned it. The field requires Agent SDK v0.3.292 or later.

1696 1700 

1697Match a subagent's messages to its task events on `agent_id` rather than pairing a message's `parent_tool_use_id` with a task event's `tool_use_id`. When a tool call resumes the subagent, the task events carry that call's `tool_use_id`, while the messages keep the `parent_tool_use_id` of the tool call that first started the subagent, so the two no longer match.1701Match a subagent's messages to its task events on `agent_id` rather than pairing a message's `parent_tool_use_id` with a task event's `tool_use_id`. When a tool call resumes the subagent, the task events carry that call's `tool_use_id`, while the messages keep the `parent_tool_use_id` of the tool call that first started the subagent, so the two no longer match.

1698 1702 


3273 3277 

3274### Agent3278### Agent

3275 3279 

3276**Tool name:** `Agent`. The previous name `Task` is still accepted as an alias, and the `tools` array in the [`SDKSystemMessage`](#sdksystemmessage) init message currently lists this tool as `Task` for backward compatibility.3280**Tool name:** `Agent`. The previous name `Task` is still accepted as an alias when this tool is available to the session.

3281 

3282The `tools` array in the [`SDKSystemMessage`](#sdksystemmessage) init message lists this tool as `Task` for backward compatibility.

3277 3283 

3278> [!NOTE]3284> [!NOTE]

3279>3285>


4010 4016 

4011### Agent4017### Agent

4012 4018 

4013**Tool name:** `Agent`. The previous name `Task` is still accepted as an alias, and the `tools` array in the [`SDKSystemMessage`](#sdksystemmessage) init message currently lists this tool as `Task` for backward compatibility.4019**Tool name:** `Agent`. The previous name `Task` is still accepted as an alias when this tool is available to the session.

4014 4020 

4015```typescript theme={null}4021```typescript theme={null}

4016type AgentOutput =4022type AgentOutput =


5210 5216 

5211#### When a tool's `_meta.ui` holds only `visibility`5217#### When a tool's `_meta.ui` holds only `visibility`

5212 5218 

5213If your server declares `ui.resourceUri` for a tool but the `_meta.ui` your application receives holds only `visibility`, the `ui` object the server sent failed one of Claude Code's checks. Claude Code checks `ui` and `ui/resourceUri` separately, so one key can reach your application when the other fails. Compare the `_meta` in your server's `tools/list` response against the checks for each key:5219If your server declares `ui.resourceUri` for a tool but the `_meta.ui` your application receives holds only `visibility`, the `ui` object the server sent failed one of Claude Code's checks. Compare the `_meta` in your server's `tools/list` response against the checks for each key:

5214 5220 

5215* **`ui`**: reaches your application unchanged, including any members other than `resourceUri` and `visibility`, if all three checks pass:5221* **`ui`**: reaches your application unchanged, including any members other than `resourceUri` and `visibility`, if all three checks pass:

5216 5222 


5553 5559 

5554Claude Code delivers this message, [`SDKHookProgressMessage`](#sdkhookprogressmessage), and [`SDKHookResponseMessage`](#sdkhookresponsemessage) to the message stream immediately, including while a `SessionStart` or `Setup` hook is still running during session startup. Claude Code v2.1.169 through v2.1.203 delivered these messages in one batch after a `SessionStart` or `Setup` hook completed; v2.1.204 restored live delivery.5560Claude Code delivers this message, [`SDKHookProgressMessage`](#sdkhookprogressmessage), and [`SDKHookResponseMessage`](#sdkhookresponsemessage) to the message stream immediately, including while a `SessionStart` or `Setup` hook is still running during session startup. Claude Code v2.1.169 through v2.1.203 delivered these messages in one batch after a `SessionStart` or `Setup` hook completed; v2.1.204 restored live delivery.

5555 5561 

5562If you start the session with [`startup()`](#startup), these messages reach you once you call `.query()` and iterate the result.

5563 

5556```typescript theme={null}5564```typescript theme={null}

5557type SDKHookStartedMessage = {5565type SDKHookStartedMessage = {

5558 type: "system";5566 type: "system";


6072| `allowManagedDomainsOnly` | `boolean` | `false` | Managed-settings only. When set in [managed settings](https://code.claude.com/docs/en/managed-settings.md), only `allowedDomains` entries and `WebFetch(domain:...)` allow rules from managed settings are honored, and allow entries from user, project, or local settings are ignored. From the SDK, pass it through the [`managedSettings`](#options) option |6080| `allowManagedDomainsOnly` | `boolean` | `false` | Managed-settings only. When set in [managed settings](https://code.claude.com/docs/en/managed-settings.md), only `allowedDomains` entries and `WebFetch(domain:...)` allow rules from managed settings are honored, and allow entries from user, project, or local settings are ignored. From the SDK, pass it through the [`managedSettings`](#options) option |

6073| `allowLocalBinding` | `boolean` | `false` | Allow processes to bind to local ports (for example, for dev servers) |6081| `allowLocalBinding` | `boolean` | `false` | Allow processes to bind to local ports (for example, for dev servers) |

6074| `allowUnixSockets` | `string[]` | `[]` | Unix socket paths that processes can access (for example, Docker socket) |6082| `allowUnixSockets` | `string[]` | `[]` | Unix socket paths that processes can access (for example, Docker socket) |

6075| `allowAllUnixSockets` | `boolean` | `false` | Allow access to all Unix sockets |6083| `allowAllUnixSockets` | `boolean` | `false` | Allow access to all Unix sockets, and on Linux to VM sockets (`AF_VSOCK`) |

6076| `httpProxyPort` | `number` | `undefined` | HTTP proxy port for network requests |6084| `httpProxyPort` | `number` | `undefined` | HTTP proxy port for network requests |

6077| `socksProxyPort` | `number` | `undefined` | SOCKS proxy port for network requests |6085| `socksProxyPort` | `number` | `undefined` | SOCKS proxy port for network requests |

6078 6086 

agent-view.md +8 −2

Details

320 320 

321#### Bring back a past session321#### Bring back a past session

322 322 

323To bring a session back on Claude Code v2.1.212 or later, type `/resume` in the [dispatch input](#dispatch-an-agent-from-agent-view). A picker opens with past sessions of the repository you opened agent view from, newest first, including sessions you deleted from the list. Sessions that already have a row aren't listed. Press `Enter` to resume the selected session as a background session, so it rejoins the list as a row.323To bring a session back, type `/resume` in the [dispatch input](#dispatch-an-agent-from-agent-view). A picker opens with past sessions of the repository you opened agent view from, newest first, including sessions you deleted from the list. Sessions that already have a row aren't listed. Press `Enter` to resume the selected session as a background session, so it rejoins the list as a row.

324 324 

325`/resume` fails with `isn't available in agent view` when:325`/resume` fails with `isn't available in agent view` when:

326 326 


410* `/logout` signs you out410* `/logout` signs you out

411* `/model`, `/effort`, and `/fast` set [what the sessions you dispatch next start with](#set-the-model-effort-and-fast-mode). `/effort` and `/fast` require Claude Code v2.1.299 or later.411* `/model`, `/effort`, and `/fast` set [what the sessions you dispatch next start with](#set-the-model-effort-and-fast-mode). `/effort` and `/fast` require Claude Code v2.1.299 or later.

412* `/login` opens the sign-in dialog so you can sign in again without attaching to a session412* `/login` opens the sign-in dialog so you can sign in again without attaching to a session

413* A bare `/resume`, or its `/continue` alias, opens a picker of the repository's past sessions to [bring one back](#bring-back-a-past-session) as a background session. Requires Claude Code v2.1.212 or later413* A bare `/resume`, or its `/continue` alias, opens a picker of the repository's past sessions to [bring one back](#bring-back-a-past-session) as a background session

414 414 

415Skills, your own commands, and prompt-expanding built-ins such as `/init` are sent to a new background session as its first prompt. The hint `isn't available in agent view` means the built-in command you entered didn't run. To run it, [attach to a session](#attach-to-a-session) and enter it there. Everything you typed stays in the input next to the hint so you can edit it.415Skills, your own commands, and prompt-expanding built-ins such as `/init` are sent to a new background session as its first prompt. The hint `isn't available in agent view` means the built-in command you entered didn't run. To run it, [attach to a session](#attach-to-a-session) and enter it there. Everything you typed stays in the input next to the hint so you can edit it.

416 416 


454 454 

455When [agent view is turned off](#turn-off-agent-view), `/fork` starts a [forked subagent](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation) instead of copying the session.455When [agent view is turned off](#turn-off-agent-view), `/fork` starts a [forked subagent](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation) instead of copying the session.

456 456 

457##### Prompt the copy and open its session

458 

457Pass a prompt such as `/fork open a draft pull request with the work so far` and the copy starts working on it immediately. Without a prompt the copy waits for its first instruction: select its row in `claude agents` and press `Space` to send one, or run `claude attach <id>`. The selected row shows `space to send it a prompt` while it waits.459Pass a prompt such as `/fork open a draft pull request with the work so far` and the copy starts working on it immediately. Without a prompt the copy waits for its first instruction: select its row in `claude agents` and press `Space` to send one, or run `claude attach <id>`. The selected row shows `space to send it a prompt` while it waits.

458 460 

459The `/fork` confirmation is one line showing the copy's state, such as `session running`, the name of its agent-view row, and its session ID for `claude attach`. Click the name to switch into the copy: this session moves to the background, the same as pressing `←`, and agent view opens the copy's session.461The `/fork` confirmation is one line showing the copy's state, such as `session running`, the name of its agent-view row, and its session ID for `claude attach`. Click the name to switch into the copy: this session moves to the background, the same as pressing `←`, and agent view opens the copy's session.

460 462 

463##### Where the copy runs

464 

461Except when the copy [edits in place](#how-file-edits-are-isolated), Claude Code instructs it to create a worktree of its own before making code changes. Outside a git repository, only a copy moved out of a hook-created worktree gets the instruction; with no [`WorktreeCreate` hook](https://code.claude.com/docs/en/hooks#worktreecreate), the copy edits in place. A copy moved out of your worktree is also told never to edit, run commands in, or enter that worktree, whatever the isolation setting.465Except when the copy [edits in place](#how-file-edits-are-isolated), Claude Code instructs it to create a worktree of its own before making code changes. Outside a git repository, only a copy moved out of a hook-created worktree gets the instruction; with no [`WorktreeCreate` hook](https://code.claude.com/docs/en/hooks#worktreecreate), the copy edits in place. A copy moved out of your worktree is also told never to edit, run commands in, or enter that worktree, whatever the isolation setting.

462 466 

463Where the copy starts depends on where the current session is running:467Where the copy starts depends on where the current session is running:


467* When you launched the session inside a linked worktree of a repository that has a main working tree, the copy starts in that main working tree, with the same worktree-of-its-own rule but no branch instruction. The confirmation ends with `runs in the origin tree` here too.471* When you launched the session inside a linked worktree of a repository that has a main working tree, the copy starts in that main working tree, with the same worktree-of-its-own rule but no branch instruction. The confirmation ends with `runs in the origin tree` here too.

468* A session launched inside a worktree of a bare-repository layout has no main working tree to return to, so the copy stays where it is, and the confirmation ends with `edits this checkout`. The same note appears when worktree isolation is [turned off](#how-file-edits-are-isolated) in a session that isn't inside a linked worktree, because the copy then edits the files you have open.472* A session launched inside a worktree of a bare-repository layout has no main working tree to return to, so the copy stays where it is, and the confirmation ends with `edits this checkout`. The same note appears when worktree isolation is [turned off](#how-file-edits-are-isolated) in a session that isn't inside a linked worktree, because the copy then edits the files you have open.

469 473 

474##### Sessions that can't be forked

475 

470Sessions started with launch flags the copy wouldn't inherit, such as a replaced system prompt or a `--tools` allowlist, can't be forked; Claude Code says so instead of making a partial copy. A session dispatched from agent view forks normally: the copy is launched with the same [agent definition](https://code.claude.com/docs/en/sub-agents.md) and appended instructions as the session it came from.476Sessions started with launch flags the copy wouldn't inherit, such as a replaced system prompt or a `--tools` allowlist, can't be forked; Claude Code says so instead of making a partial copy. A session dispatched from agent view forks normally: the copy is launched with the same [agent definition](https://code.claude.com/docs/en/sub-agents.md) and appended instructions as the session it came from.

471 477 

472#### What carries over when you background478#### What carries over when you background

agents.md +1 −1

Details

32 32 

33> [!NOTE]33> [!NOTE]

34>34>

35> Running several sessions or subagents at once multiplies token usage. See [Costs](https://code.claude.com/docs/en/costs.md) for usage and rate-limit details.35> Running several sessions or subagents at once multiplies token usage. See [Costs](https://code.claude.com/docs/en/costs.md) for usage and rate limit details.

36 36 

37## Choose an approach37## Choose an approach

38 38 

Details

251| Primary model | Opus 5.5, for example `us.anthropic.claude-opus-5-5` in a `us-*` region |251| Primary model | Opus 5.5, for example `us.anthropic.claude-opus-5-5` in a `us-*` region |

252| Small/fast model | Sonnet 4.5, for example `us.anthropic.claude-sonnet-4-5-20250929-v1:0` in a `us-*` region |252| Small/fast model | Sonnet 4.5, for example `us.anthropic.claude-sonnet-4-5-20250929-v1:0` in a `us-*` region |

253 253 

254Before v2.1.280, the primary model on Amazon Bedrock defaulted to Opus 5 and the `opus` alias resolved to Opus 5 from v2.1.219.

255 

254Background tasks such as session title generation use the small/fast model, normally a Haiku-class model. On Amazon Bedrock, Claude Code uses the default Sonnet model for background tasks because Haiku may not be enabled in every account or region. Two selections change which model carries them:256Background tasks such as session title generation use the small/fast model, normally a Haiku-class model. On Amazon Bedrock, Claude Code uses the default Sonnet model for background tasks because Haiku may not be enabled in every account or region. Two selections change which model carries them:

255 257 

256* When you select a primary model with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, background tasks use that model. When Claude Code starts the session on the model you set with [`ANTHROPIC_DEFAULT_MODEL`](https://code.claude.com/docs/en/model-config#set-a-default-model-for-new-sessions), background tasks use that model too. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` also counts as a selection, because the built-in Sonnet model may not be enabled in an account that steers its own Opus.258* When you select a primary model with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, background tasks use that model. When Claude Code starts the session on the model you set with [`ANTHROPIC_DEFAULT_MODEL`](https://code.claude.com/docs/en/model-config#set-a-default-model-for-new-sessions), background tasks use that model too. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` also counts as a selection, because the built-in Sonnet model may not be enabled in an account that steers its own Opus.


260>262>

261> Opus models have a higher per-token price than Sonnet models, so if you don't pin a primary model, you're billed at the Opus rate. To use Sonnet 4.5 as the primary model, set `ANTHROPIC_MODEL` to its full model ID. A deployment that steers the default with `ANTHROPIC_DEFAULT_SONNET_MODEL` and doesn't set `ANTHROPIC_DEFAULT_OPUS_MODEL` keeps its steered Sonnet model as the default.263> Opus models have a higher per-token price than Sonnet models, so if you don't pin a primary model, you're billed at the Opus rate. To use Sonnet 4.5 as the primary model, set `ANTHROPIC_MODEL` to its full model ID. A deployment that steers the default with `ANTHROPIC_DEFAULT_SONNET_MODEL` and doesn't set `ANTHROPIC_DEFAULT_OPUS_MODEL` keeps its steered Sonnet model as the default.

262 264 

263Before v2.1.280, the primary model on Amazon Bedrock defaulted to Opus 5 and the `opus` alias resolved to Opus 5 from v2.1.219. On v2.1.207 through v2.1.218, the primary model on Amazon Bedrock defaulted to Opus 4.8 and the `opus` alias resolved to Opus 4.8.

264 

265To customize models further, use one of these methods:265To customize models further, use one of these methods:

266 266 

267```bash theme={null}267```bash theme={null}

artifacts.md +2 −2

Details

95 95 

96Select an artifact, then press one of these keys:96Select an artifact, then press one of these keys:

97 97 

98* **`Enter`**: opens it in your browser when it's already attached to the current session, and attaches it when it isn't. Before v2.1.216, `Enter` opened it in your browser98* **`Enter`**: opens it in your browser when it's already attached to the current session, and attaches it when it isn't

99* **`o`**: opens it in your browser99* **`o`**: opens it in your browser

100* **`c`**: copies its link100* **`c`**: copies its link

101* **`d`**: outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), permanently deletes an artifact you own after you confirm. Its link stops working for everyone, including you101* **`d`**: outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), permanently deletes an artifact you own after you confirm. Its link stops working for everyone, including you


225 225 

226When a connector-backed page renders but its live sections stay empty for a viewer in your organization, work through these causes:226When a connector-backed page renders but its live sections stay empty for a viewer in your organization, work through these causes:

227 227 

228* **The viewer hasn't connected the connector**: connectors are per-account, so each viewer needs their own connection to every connector the page calls. They can add one under **Settings > Connectors** on claude.ai, then reload the page.228* **The viewer hasn't connected the connector**: connectors are per-account, so each viewer needs their own connection to every connector the page calls. They can add one under [**Customize > Connectors**](https://claude.ai/customize/connectors) on claude.ai, then reload the page.

229* **The viewer declined the permission ask**: a denial lasts for the rest of that page load. Reloading the page brings the permission ask back.229* **The viewer declined the permission ask**: a denial lasts for the rest of that page load. Reloading the page brings the permission ask back.

230* **Connector calls are turned off for the organization**: an Owner controls the [**Enable artifact connectors** toggle](#control-connector-calls-from-artifacts) in admin settings.230* **Connector calls are turned off for the organization**: an Owner controls the [**Enable artifact connectors** toggle](#control-connector-calls-from-artifacts) in admin settings.

231* **The page calls tool names the connector doesn't expose**: the affected sections stay empty for everyone, including you. This can happen when a page names the individual tools behind a gateway-style connector that exposes only a few tools of its own. Ask Claude to fix the tool names the page calls and publish it again.231* **The page calls tool names the connector doesn't expose**: the affected sections stay empty for everyone, including you. This can happen when a page names the individual tools behind a gateway-style connector that exposes only a few tools of its own. Ask Claude to fix the tool names the page calls and publish it again.

best-practices.md +416 −354

Details

4 4 

5# Best practices for Claude Code5# Best practices for Claude Code

6 6 

7> Tips and patterns for getting the most out of Claude Code, from configuring your environment to scaling across parallel sessions.7> Get more out of Claude Code: tell Claude what it can't see, give it a check to run, and enforce the rules that can't have exceptions.

8 8 

9Claude Code is an agentic coding environment. Unlike a chatbot that answers questions and waits, Claude Code can read your files, run commands, make changes, and autonomously work through problems while you watch, redirect, or step away entirely.9Claude Code is built in a way that, in most cases, your first plain prompt in a fresh session already does the right thing, without any setup on your part.

10 10 

11This changes how you work. Instead of writing code yourself and asking Claude to review it, you describe what you want and Claude figures out how to build it. Claude explores, plans, and implements.11For example:

12 12 

13But this autonomy still comes with a learning curve. Claude works within certain constraints you need to understand.13* To let commands run safely without you approving each one, new terminal and VS Code sessions start in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), where a classifier reviews anything risky before it runs.

14* To keep your main conversation focused while independent work happens in parallel, Claude delegates to subagents and checks in only when it has to.

15* To keep a long session going without you managing it, your conversation is compacted automatically before the context window fills.

14 16 

15This guide covers patterns that have proven effective across Anthropic's internal teams and for engineers using Claude Code across various codebases, languages, and environments. For how the agentic loop works, see [How Claude Code works](https://code.claude.com/docs/en/how-claude-code-works.md).17This page covers what to do when the defaults aren't enough. That usually happens when your project has knowledge, rules, or constraints that Claude can't see from the code alone:

16 18 

17***19* A deploy process that lives in someone's head

20* A file that must never be read

21* A check that has to pass before anything counts as done

22* A budget you need to stay under

18 23 

19Most best practices are based on one constraint: Claude's context window fills up fast, and performance degrades as it fills.24No default can know those things about your project, so this is where a small amount of setup on your side pays off.

20 25 

21Claude's context window holds your entire conversation, including every message, every file Claude reads, and every command output. However, this can fill up fast. A single debugging session or codebase exploration might generate and consume tens of thousands of tokens.26When a session doesn't go the way you expected, it's almost always one of these:

22 27 

23This matters since LLM performance degrades as context fills. When the context window is getting full, Claude may start "forgetting" earlier instructions or making more mistakes. The context window is the most important resource to manage. To see how a session fills up in practice, [watch an interactive walkthrough](https://code.claude.com/docs/en/context-window.md) of what loads at startup and what each file read costs. Track context usage continuously with a [custom status line](https://code.claude.com/docs/en/statusline.md), and see [Reduce token usage](https://code.claude.com/docs/en/costs.md#reduce-token-usage) for strategies on reducing token usage.28* Claude built something different from what you had in mind, or it has to rediscover the same fact at the start of every session. It's missing information it can't get from reading the repo. See [Tell Claude what it can't see](#tell-claude-what-it-cant-see).

29* Claude said it was done and it wasn't quite, usually because it had no way to check its own work. See [Give Claude a check to run](#give-claude-a-check-to-run).

30* Claude did something that must never happen in this repo, or skipped a step that must always happen. A prompt alone can't guarantee either of those. See [Enforce the rules that can't have exceptions](#enforce-the-rules-that-cant-have-exceptions).

31* Claude got it right, but it took more time, tokens, or permission prompts than the task was worth. See [Change a default](#change-a-default).

24 32 

25***33[Let Claude run without you](#let-claude-run-without-you) applies the same four points to unattended runs, and [What you can stop doing](#what-you-can-stop-doing) lists the advice that current models have made unnecessary.

26 34 

27## Give Claude a way to verify its work35> [!NOTE]

28 

29> [!TIP]

30>36>

31> Give Claude a check it can run: tests, a build, a screenshot to compare. It's the difference between a session you watch and one you walk away from.37> Setup for a whole team is on a separate page: [Set up Claude Code for your organization](https://code.claude.com/docs/en/admin-setup.md).

32 38 

33Claude stops when the work looks done. Without a check it can run, "looks done" is the only signal available, and you become the verification loop: every mistake waits for you to notice it. Give Claude something that produces a pass or fail, and the loop closes on its own. Claude does the work, runs the check, reads the result, and iterates until the check passes.39## Deterministic and non-deterministic instructions

34 40 

35The check is anything that returns a signal Claude can read in the conversation: a test suite, a build exit code, a linter, a script that diffs output against a fixture, or a [browser screenshot](https://code.claude.com/docs/en/chrome.md) compared against a design. Run [`/verify`](https://code.claude.com/docs/en/skills#run-and-verify-your-app) yourself after Claude's check passes to confirm the change against the running app.41Every instruction you give Claude Code is one of these:

36 42 

37| Strategy | Before | After |431. Non-deterministic: you write the instruction, and Claude (the model) reads it. This can be your prompt, `CLAUDE.md`, or a skill. The model then decides what to do with this information. It usually follows your commands, and current models are good at understanding your intent without much context, but there's no *guarantee* that it'll follow your instructions. It can still decide not to do things, or do other things.

38| - | - | - |442. Deterministic: you configure the instruction, and Claude Code (the harness) *has* to execute this. This can be a hook, a deny rule, or a managed setting. Claude Code applies this every time, no matter what the model decided to do.

39| **Provide verification criteria** | *"implement a function that validates email addresses"* | *"write a validateEmail function. example test cases: [user@example.com](mailto:user@example.com) is true, invalid is false, [user@.com](mailto:user@.com) is false. run the tests after implementing"* |

40| **Verify UI changes visually** | *"make the dashboard look better"* | *"\[paste screenshot] implement this design. take a screenshot of the result and compare it to the original. list differences and fix them"* |

41| **Address root causes, not symptoms** | *"the build is failing"* | *"the build fails with this error: \[paste error]. fix it and verify the build succeeds. address the root cause, don't suppress the error"* |

42 45 

43Once the check exists, decide how hard it gates the stop:46Most things in Claude Code come in both forms:

44 47 

45* **In one prompt**: ask Claude to run the check and iterate in the same message, as in the table above.48| | Non-deterministic (Claude decides) | Deterministic (Claude Code enforces) |

46* **Across a session**: set the check as a [`/goal` condition](https://code.claude.com/docs/en/goal). A separate evaluator re-checks it after every turn and Claude keeps working until the goal resolves. If Claude stalls, Claude Code eventually stops the run with the goal still set — see [how /goal evaluation works](https://code.claude.com/docs/en/goal.md#how-evaluation-works).49| :- | :- | :- |

47* **As a deterministic gate**: a [Stop hook](https://code.claude.com/docs/en/hooks.md#stop) runs your check as a script and blocks the turn from ending until it passes. [Stop input](https://code.claude.com/docs/en/hooks.md#stop-input) covers the cap on consecutive blocks.50| What to do | Your prompt, `CLAUDE.md`, skills Claude picks up itself | Hooks, and which skills only you can start |

48* **By a second opinion**: a [verification subagent](https://code.claude.com/docs/en/sub-agents.md) or a [dynamic workflow](https://code.claude.com/docs/en/workflows.md) that checks its own findings has a fresh model try to refute the result, so the agent doing the work isn't the one grading it.51| What it can touch | Auto mode's classifier | Deny rules, the sandbox in [strict mode](https://code.claude.com/docs/en/sandboxing.md#turn-off-the-retry-with-strict-sandbox-mode), managed settings |

52| When it's done | A request for evidence, `/goal`, `/code-review` | Tests, typecheck, a `Stop` hook, CI |

53| How much it spends | Effort level, Claude's own pace | `--max-turns` or [`--max-budget-usd`](https://code.claude.com/docs/en/cli-reference) with `-p`, a [spend limit](https://code.claude.com/docs/en/costs.md) you've set |

54| Who has the last word | Claude's summary of what it did | Branch protection, a person who approves the merge |

49 55 

50Each step trades setup for attention. The prompt version works on any task today. The `/goal` and Stop hook versions are what let an unattended run finish correctly without you.56Most of the time, you want Claude to decide. Almost every guideline has exceptions, and current models are good at reading the code in front of them and judging whether a guideline fits the situation. With the actual code in front of it, Claude is usually better placed to make that call than a rule you wrote in advance.

51 57 

52Have Claude show evidence rather than asserting success: the test output, the command it ran and what it returned, or a screenshot of the result. Reviewing evidence is faster than re-running the verification yourself, and it works for sessions you weren't watching.58The deterministic kind is for when you want to make sure certain things *always* happen (or never happen), no matter what the model decides. This doesn't have to be anything dramatic. Auto mode already [blocks the dramatic things](https://code.claude.com/docs/en/permission-modes.md#what-the-classifier-blocks-by-default), like a production deploy or a force push over someone's work. It's usually something specific to *your* project, and it can be as niche as you want it to be:

53 59 

54***60* Never edit the generated client in `src/gen/`

61* Always run the license-header script after creating a file

55 62 

56## Explore first, then plan, then code63You could've written either of these as a line in `CLAUDE.md` or in your prompt, and Claude would follow it nearly every time. But no matter how strongly you word it, whether Claude follows that line on a given turn is still Claude's call.

57 64 

58> [!TIP]65> [!TIP]

59>66>

60> Separate research and planning from implementation to avoid solving the wrong problem.67> If you keep adding emphasis to a `CLAUDE.md` line and Claude still misses it, that's a sign the line belongs in a hook. The reverse holds too: if you have hooks for things that are only preferences, delete them and let Claude decide.

61 68 

62Letting Claude jump straight to coding can produce code that solves the wrong problem. Use [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) to separate exploration from execution.69## Tell Claude what it can't see

63 70 

64The recommended workflow has four phases:71> [!TIP]

72>

73> Only write down what Claude can't find by reading the repo, or what it would otherwise spend time rediscovering every session.

65 74 

66**1. Explore**75Claude starts every task by reading your code, and current models are *very* good at this. They'll find your file layout, your conventions, your test framework, and how existing components are built, usually faster than you could explain them. That means Claude already knows most of what you might be tempted to write down for it.

67 76 

68Enter plan mode by pressing `Shift+Tab` until the status bar shows `⏸ plan mode on`, or start the session with `claude --permission-mode plan`. Claude reads files and answers questions without making changes.77What it can't find is the information that was never in the repo:

69 78 

70```txt title="claude (plan mode)" wrap theme={null}79* A decision your team made in a meeting

71read /src/auth and understand how we handle sessions and login.80* A deploy process that lives in one person's head

72also look at how we manage environment variables for secrets.81* The environment variable your integration tests need

73```

74 82 

75**2. Plan**83There's also information that *is* in the repo but takes a few minutes of digging to find, and Claude has to redo that digging at the start of every session.

76 84 

77Ask Claude to create a detailed implementation plan.85A good test before you write anything down for Claude:

78 86 

79```txt title="claude (plan mode)" wrap theme={null}871. Could it find this by reading the code?

80I want to add Google OAuth. What files need to change?882. Would it actually go and look?

81What's the session flow? Create a plan.

82```

83 89 

84Press `Ctrl+G` to open the plan in your text editor for direct editing before Claude proceeds.90If both are yes, leave it out.

85 91 

86**3. Implement**92### Write a specific prompt

87 93 

88Switch out of plan mode by approving the plan or pressing `Shift+Tab`, then let Claude code, verifying against its plan.94A specific prompt helps for the same reason, because it gives Claude information it doesn't already have. If you name the file, describe the symptom, and say what "fixed" looks like up front, you usually save yourself a round of corrections later.

89 95 

90```txt title="claude" wrap theme={null}96The same goes for a preference between two reasonable approaches: Claude can't read that from the code, so if you care which one it picks, say so up front.

91implement the OAuth flow from your plan. write tests for the

92callback handler, run the test suite and fix any failures.

93```

94 97 

95**4. Commit**98| Instead of | Try |

99| :- | :- |

100| *"fix the login bug"* | *"users report login fails after the session times out. look at token refresh in src/auth/, write a failing test that reproduces it, then fix it"* |

101| *"add a calendar widget"* | *"follow the pattern in HotDogWidget.php and build a calendar widget that lets you pick a month and page between years. no new libraries"* |

96 102 

97Ask Claude to commit with a descriptive message and create a PR.103If you already have the thing Claude needs, hand it over instead of describing it:

98 104 

99```txt title="claude" wrap theme={null}105* A file: type `@` and the path to [include the file contents](https://code.claude.com/docs/en/common-workflows.md#reference-files-and-directories) in your message.

100commit with a descriptive message and open a PR106* An image: paste the screenshot of the design or the error into the prompt.

101```107* Command output: pipe it in from your shell with `cat error.log | claude -p "what's going on here"`.

102 108 

103Plan mode is useful, but also adds overhead.109Phrases like `think step by step` or `be thorough` are ordinary prompt text rather than keywords. The main control for how hard Claude thinks is the [effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level), which [Change the model and effort](#change-the-model-and-effort) covers. Wording like that can still nudge Claude within its effort setting, but it won't lift it past it.

104 110 

105For tasks where the scope is clear and the fix is small (like fixing a typo, adding a log line, or renaming a variable) ask Claude to do it directly.111One phrase that does still help is `be ambitious`. Claude tends to read a request conservatively and build the smallest thing that satisfies it, since it can't see how much you were hoping for. When you want the fuller version, with the edge cases handled and the natural follow-on included, say so:

106 112 

107Planning is most useful when you're uncertain about the approach, when the change modifies multiple files, or when you're unfamiliar with the code being modified. If you could describe the diff in one sentence, skip the plan.113```text theme={null}

114build the settings page from the mockup. be ambitious: empty and error states, the save flow wired up, keyboard navigation, not just the layout

115```

108 116 

109***117That's telling Claude about scope, which only you know, rather than how hard to think.

110 118 

111## Provide specific context in your prompts119And when you're exploring rather than fixing something specific, a vague prompt like `what would you improve in this file?` is completely fine. You'll correct a bit more as you go, and that's the trade-off.

112 120 

113> [!TIP]121### Brainstorm with Claude first

114>

115> The more precise your instructions, the fewer corrections you'll need.

116 122 

117Claude can infer intent, but it can't read your mind. Reference specific files, mention constraints, and point to example patterns.123When you don't know exactly what you want yet, you don't have to work it all out before you prompt. Ask Claude to interview you instead:

118 124 

119| Strategy | Before | After |125```text theme={null}

120| - | - | - |126I want to add rate limiting to the public API but haven't thought it through yet. Interview me until you could write the spec, then write it to SPEC.md.

121| **Scope the task.** Specify which file, what scenario, and testing preferences. | *"add tests for foo.py"* | *"write a test for foo.py covering the edge case where the user is logged out. avoid mocks."* |127```

122| **Point to sources.** Direct Claude to the source that can answer a question. | *"why does ExecutionFactory have such a weird api?"* | *"look through ExecutionFactory's git history and summarize how its api came to be"* |

123| **Reference existing patterns.** Point Claude to patterns in your codebase. | *"add a calendar widget"* | *"look at how existing widgets are implemented on the home page to understand the patterns. HotDogWidget.php is a good example. follow the pattern to implement a new calendar widget that lets the user select a month and paginate forwards/backwards to pick a year. build from scratch without libraries other than the ones already used in the codebase."* |

124| **Describe the symptom.** Provide the symptom, the likely location, and what "fixed" looks like. | *"fix the login bug"* | *"users report that login fails after session timeout. check the auth flow in src/auth/, especially token refresh. write a failing test that reproduces the issue, then fix it"* |

125 128 

126Vague prompts can be useful when you're exploring and can afford to course-correct. A prompt like `"what would you improve in this file?"` can surface things you wouldn't have thought to ask about.129Claude comes back with multiple-choice questions about the parts you haven't pinned down: per-user versus per-key limits, what happens to requests over the limit, what's out of scope. It keeps asking until the answers add up to a spec.

127 130 

128### Provide rich content131Once `SPEC.md` exists, start a fresh session to build from it, so the build begins with a clean context and a written definition of done. It's also the file you'll point the reviewer at later, in [Give Claude a check to run](#give-claude-a-check-to-run).

129 132 

130> [!TIP]133### Keep CLAUDE.md short

131>

132> Use `@` to reference files, paste screenshots/images, or pipe data directly.

133 134 

134You can provide rich data to Claude in several ways:135Claude Code loads [`CLAUDE.md`](https://code.claude.com/docs/en/memory) into every session, which means every line in it takes a little of Claude's attention on *every* task, whether it's relevant or not. That's why the file works best when it only holds what Claude couldn't work out from the code itself:

135 136 

136* **Reference files with `@`** instead of describing where code lives. Claude reads the file before responding.137* How to confirm work in this repo: the exact test, typecheck, and lint commands, and how to run a single test file

137* **Paste images directly**. Copy/paste or drag and drop images into the prompt.138* Places where the code is misleading: an old pattern that's everywhere but that new code must not copy, or a directory that looks unused but isn't

138* **Give URLs** for documentation and API references. Use `/permissions` to allowlist frequently used domains.139* Decisions that aren't in the repo: which error helper the team settled on, how deploys work, what needs a migration review

139* **Pipe in data** by running `cat error.log | claude -p "explain this error"` to send file contents directly.140* Anything you've had to correct twice already

140* **Let Claude fetch what it needs**. Tell Claude to pull context itself using Bash commands, MCP tools, or by reading files.

141 141 

142***142A `CLAUDE.md` that passes that test stays short:

143 143 

144## Configure your environment144```markdown CLAUDE.md theme={null}

145# Commands

146- Install: pnpm install

147- Run one test file: pnpm vitest run path/to/file.test.ts

148- Typecheck: pnpm tsc --noEmit

145 149 

146A few setup steps make Claude Code significantly more effective across all your sessions. For a full overview of extension features and when to use each one, see [Extend Claude Code](https://code.claude.com/docs/en/features-overview.md).150# Conventions

151- Use the error helpers in src/lib/errors.ts, never throw raw strings

152- src/legacy/ is still live but don't copy its patterns into new code

147 153 

148### Write an effective CLAUDE.md154# Gotchas

155- Integration tests need DATABASE_URL set, see .env.example

156```

149 157 

150> [!TIP]158In a session, run `/context` to confirm that Claude loaded the file.

151>

152> Run `/init` to generate a starter CLAUDE.md file based on your current project structure, then refine over time.

153 159 

154CLAUDE.md is a special file that Claude reads at the start of every conversation. Include Bash commands, code style, and workflow rules. This gives Claude persistent context it can't infer from code alone.160Notice that the typecheck line is only the command. Claude needs to know the command so it can check its own work as it goes. If you also want Claude Code to *enforce* a passing typecheck before Claude finishes, that's a job for a [`Stop` hook](#enforce-the-check-with-a-stop-hook). A line like `Always typecheck before you finish` in this file works most of the time, not every time.

155 161 

156There's no required format for CLAUDE.md files, but keep it short and human-readable. For example:162You don't have to write the file from scratch:

157 163 

158```markdown CLAUDE.md theme={null}164* `/init` generates a starting version from your codebase. From there the work is mostly removing lines. The [memory guide](https://code.claude.com/docs/en/memory.md#write-effective-instructions) recommends staying under 200.

159# Code style165* `/doctor` suggests cuts for anything Claude can [already work out from the code](https://code.claude.com/docs/en/memory.md#my-claude-md-is-too-large).

160- Use ES modules (import/export) syntax, not CommonJS (require)166* `/doctor prompt-audit` flags instructions that were written for older models, point at files that no longer exist, or [contradict each other](https://code.claude.com/docs/en/memory.md#audit-your-instruction-files).

161- Destructure imports when possible (eg. import { foo } from 'bar')

162 167 

163# Workflow168Your personal preferences go in `CLAUDE.local.md` instead of `CLAUDE.md`, and you add that file to `.gitignore` so it stays out of the repo.

164- Be sure to typecheck when you're done making a series of code changes

165- Prefer running single tests, and not the whole test suite, for performance

166```

167 169 

168Run `/context` to confirm Claude loaded the file. CLAUDE.md is loaded every session, so only include things that apply broadly. For domain knowledge or workflows that are only relevant sometimes, use [skills](https://code.claude.com/docs/en/skills.md) instead. Claude loads them on demand without bloating every conversation.170> [!NOTE]

171>

172> If Claude keeps ignoring a line that *is* in `CLAUDE.md`, adding IMPORTANT probably won't fix it. Either the file has grown long enough that the line gets lost, or the line is a rule that can't have exceptions, in which case it belongs in a [hook](#enforce-the-rules-that-cant-have-exceptions).

169 173 

170Keep it concise. For each line, ask: *"Would removing this cause Claude to make mistakes?"* If not, cut it. Bloated CLAUDE.md files cause Claude to ignore your actual instructions!174### Scope rules to one part of the codebase

171 175 

172| ✅ Include | ❌ Exclude |176If a rule only matters in one part of the codebase, put it in [`.claude/rules/`](https://code.claude.com/docs/en/memory#path-specific-rules) with a `paths:` filter so it only loads when Claude is actually working there. For example, this `.claude/rules/api.md` loads for TypeScript files under `src/api/`:

173| - | - |

174| Bash commands Claude can't guess | Anything Claude can figure out by reading code |

175| Code style rules that differ from defaults | Standard language conventions Claude already knows |

176| Testing instructions and preferred test runners | Detailed API documentation (link to docs instead) |

177| Repository etiquette (branch naming, PR conventions) | Information that changes frequently |

178| Architectural decisions specific to your project | Long explanations or tutorials |

179| Developer environment quirks (required env vars) | File-by-file descriptions of the codebase |

180| Common gotchas or behaviors that aren't self-evident | Self-evident practices like "write clean code" |

181 177 

182If Claude keeps doing something you don't want despite having a rule against it, the file is probably too long and the rule is getting lost. If Claude asks you questions that are answered in CLAUDE.md, the phrasing might be ambiguous. Treat CLAUDE.md like code: review it when things go wrong, prune it regularly, and test changes by observing whether Claude's behavior actually shifts. For a checked-in CLAUDE.md, run [`/doctor`](https://code.claude.com/docs/en/commands#all-commands) and Claude proposes cuts for content it can derive from the codebase.178```markdown .claude/rules/api.md theme={null}

179---

180paths:

181 - "src/api/**/*.ts"

182---

183- Validate request bodies with the zod schemas in src/api/schemas/, don't hand-roll checks

184- Every new endpoint needs an entry in openapi.yaml, CI fails without it

185```

183 186 

184If Claude keeps skipping one instruction, add emphasis such as "IMPORTANT" to that line alone. If you emphasize many lines, none of them stands out. Check CLAUDE.md into git so your team can contribute. The file compounds in value over time.187### Put team procedures in skills

185 188 

186CLAUDE.md files can import additional files using `@path/to/import` syntax. For import rules and where CLAUDE.md files can live, see [CLAUDE.md files](https://code.claude.com/docs/en/memory.md#claude-md-files).189A more capable model knows more about engineering, but not how *your* team does a release, what your incident runbook says, or how you want API docs written. That kind of knowledge goes in a [skill](https://code.claude.com/docs/en/skills.md): a procedure or a piece of team knowledge saved at `.claude/skills/<name>/SKILL.md`.

187 190 

188### Configure permissions191Skills are also lighter on context than `CLAUDE.md` for this kind of thing. For a skill Claude can start on its own, it sees the name and description in every session, but only [reads the full file](https://code.claude.com/docs/en/skills.md#skill-content-lifecycle) when the task calls for it. A long release procedure sitting in a skill doesn't weigh on your unrelated bug fix the way it would in `CLAUDE.md`.

189 192 

190> [!TIP]193> [!NOTE]

191>194>

192> To get fewer prompts without giving up control, pre-approve the tools you trust with `/permissions` and let sandboxed commands run without asking with `/sandbox`. Switch to Manual mode when you want to approve edits and commands yourself.195> The `CLAUDE.md` rule applies to skills too: only write down what Claude can't find on its own.

193 196 

194With Claude Code v2.1.283 or later, auto mode is the [built-in starting permission mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for interactive terminal and VS Code sessions: a separate classifier model reviews most actions instead of you and blocks only what looks risky, such as scope escalation, unknown infrastructure, or hostile-content-driven actions. On earlier versions, auto mode is the built-in starting permission mode only on Pro, Max, and Team plans.197For a workflow with side effects, like actually cutting that release, add `disable-model-invocation: true`. Claude then [can't start the skill on its own](https://code.claude.com/docs/en/skills.md#control-who-invokes-a-skill), and it only runs when you type `/release` yourself. Saved as `.claude/skills/release/SKILL.md`, it could look like this:

195 198 

196In Manual mode, Claude Code asks before actions that might modify your system: file writes, Bash commands, MCP tools. That's safe but tedious. After the tenth approval you're clicking through rather than reviewing. Two tools cut those interruptions in Manual mode and apply in auto mode as well:199```markdown .claude/skills/release/SKILL.md theme={null}

200---

201name: release

202description: Cut a new release. Bumps the version, writes the changelog entry, tags it and pushes the tag so CI can publish.

203disable-model-invocation: true

204---

2051. Make sure you're on main with a clean tree. If not, stop and ask.

2062. Run `pnpm changeset version` and commit the result.

2073. Summarize the PRs merged since the last tag into CHANGELOG.md, one line each, user-facing changes only.

2084. Tag `v<new version>` and push the tag. CI publishes from there, never publish from your machine.

209```

197 210 

198* **Permission allowlists**: permit specific tools you know are safe, like `npm run lint` or `git commit`211### Connect the tools Claude needs

199* **Sandboxing**: enable OS-level isolation that restricts filesystem and network access, allowing Claude to work more freely within defined boundaries

200 212 

201Read more about [permission modes](https://code.claude.com/docs/en/permission-modes.md), [permission rules](https://code.claude.com/docs/en/permissions.md), and [sandboxing](https://code.claude.com/docs/en/sandboxing.md).213Some of what Claude can't see lives in another system entirely, like your issue tracker or your error dashboard. If that system has a CLI, that's usually the easiest way in. With `gh` installed and signed in, for example, Claude will open pull requests and read review comments without any explanation from you. For a CLI it hasn't seen before, pointing it at `--help` is enough.

202 214 

203### Use CLI tools215For systems without a CLI, there's [MCP](https://code.claude.com/docs/en/mcp.md). You add a server from your shell:

204 216 

205> [!TIP]217```bash theme={null}

206>218claude mcp add --transport http notion https://mcp.notion.com/mcp

207> Tell Claude Code to use CLI tools like `gh`, `aws`, `gcloud`, and `sentry-cli` when interacting with external services.219```

220 

221The server then shows up under `/mcp` inside a session. Connected servers add their tool names and instructions to the context even when you're not using them, so it's worth [turning off the ones you don't need](https://code.claude.com/docs/en/mcp.md#disable-a-server-without-removing-it) there.

222 

223And if you work in a typed language, a [code intelligence plugin](https://code.claude.com/docs/en/plugins/code-intelligence.md) lets Claude jump straight to a definition instead of reading through many files to find it.

208 224 

209CLI tools are the most context-efficient way to interact with external services. If you use GitHub, install the `gh` CLI. Claude knows how to use it for creating issues, opening pull requests, and reading comments. Without `gh`, Claude can still use the GitHub API, but unauthenticated requests often hit rate limits.225## Give Claude a check to run

210 226 

211Claude is also effective at learning CLI tools it doesn't already know. Try prompts like `Use 'foo-cli-tool --help' to learn about foo tool, then use it to solve A, B, C.`227Claude stops when the work looks done. If it has nothing to run that tells it whether the work actually *is* done, "looks done" is all it has to go on. In practice that makes you the test suite, and every mistake sits there until you happen to notice it.

212 228 

213### Connect MCP servers229If you give it something that comes back pass or fail, Claude can close that loop itself. It makes the change, runs the check, and if something broke it reads the output and fixes it before running the check again.

214 230 

215> [!TIP]231> [!TIP]

216>232>

217> Run `claude mcp add` with a server name and URL or command to connect external tools like Notion, Figma, or your database. For example: `claude mcp add --transport http notion https://mcp.notion.com/mcp`.233> Give Claude something it can run that comes back pass or fail. Once it has that, it can keep going on its own and you don't have to watch.

218 234 

219With [MCP servers](https://code.claude.com/docs/en/mcp.md), you can ask Claude to implement features from issue trackers, query databases, analyze monitoring data, integrate designs from Figma, and automate workflows.235The check can be almost anything, as long as Claude can read the result:

220 236 

221### Set up hooks237* A test file

238* A build's exit code

239* A linter

240* A script that diffs output against a fixture

241* A [browser screenshot](https://code.claude.com/docs/en/chrome.md) next to the mockup

222 242 

223> [!TIP]243If your repo already has one of these, the single most useful line in your `CLAUDE.md` is the command that runs it.

224>

225> Use hooks for actions that must happen every time with zero exceptions.

226 244 

227[Hooks](https://code.claude.com/docs/en/hooks-guide.md) run scripts automatically at specific points in Claude's workflow. Unlike CLAUDE.md instructions which are advisory, hooks are deterministic and guarantee the action happens.245How strict you make the check is up to you. The options go from Claude deciding for itself all the way to Claude Code enforcing it:

228 246 

229Claude can write hooks for you. Try prompts like *"Write a hook that runs eslint after every file edit"* or *"Write a hook that blocks writes to the migrations folder."* Edit `.claude/settings.json` directly to configure hooks by hand, and run `/hooks` to browse what's configured.247* In the prompt: `run the auth tests after, and keep going until they pass`. Claude decides for itself when it's satisfied. This works for any task, today, with no setup.

248* As a goal: [`/goal all tests in tests/auth pass and lint is clean`](https://code.claude.com/docs/en/goal) sets a condition that a separate model checks against the conversation after every turn, and Claude keeps going until it's met. You rarely need this in the session yourself. It matters for long background runs, where Claude sometimes ends a turn with a progress summary while items are still open, and the goal sends it back.

249* As a Stop hook: a [`Stop` hook](https://code.claude.com/docs/en/hooks#stop) runs your script whenever Claude tries to end its turn, and sends Claude back to work if the script exits with code 2. This one is enforced by Claude Code (the harness), so the turn doesn't end until the typecheck passes or the [block limit](https://code.claude.com/docs/en/hooks.md#stop-input) is reached. There's an [example further down](#enforce-the-check-with-a-stop-hook).

250* By someone who didn't write the code: in the terminal, [`/code-review`](https://code.claude.com/docs/en/code-review-local) reviews the diff in a fresh subagent that never saw your conversation. It isn't swayed by the reasoning that produced the code.

230 251 

231### Create skills252Whichever option you use, ask Claude for *evidence*: the command it ran and its output, or the screenshot. "All tests pass" on its own tells you very little, and reading the output is faster than rerunning the check yourself. For a session you weren't watching, it's also the only evidence you have.

232 253 

233> [!TIP]254> [!TIP]

234>255>

235> Create `SKILL.md` files in `.claude/skills/` to give Claude domain knowledge and reusable workflows.256> Once Claude says it's done, you can also run [`/verify`](https://code.claude.com/docs/en/skills#run-and-verify-your-app) in the session, which has Claude build and run the app and look at the result. That catches the kind of problem that tests and typechecks miss.

236 257 

237[Skills](https://code.claude.com/docs/en/skills.md) extend Claude's knowledge with information specific to your project, team, or domain. Claude applies them automatically when relevant, or you can invoke them directly with `/skill-name`.258### Review against your spec

238 259 

239Create a skill by adding a directory with a `SKILL.md` to `.claude/skills/`:260If you'd rather have the review check the work against your plan than hunt for bugs in general, write the review prompt yourself:

240 261 

241```markdown .claude/skills/api-conventions/SKILL.md theme={null}262```text theme={null}

242name: api-conventions263use a subagent to review the rate limiter diff against SPEC.md, check every requirement is implemented and the listed edge cases have tests, report gaps that affect correctness and skip style

243description: REST API design conventions for our services

244# API Conventions

245- Use kebab-case for URL paths

246- Use camelCase for JSON properties

247- Always include pagination for list endpoints

248- Version APIs in the URL path (/v1/, /v2/)

249```264```

250 265 

251Skills can also define repeatable workflows you invoke directly:266> [!NOTE]

252 267>

253```markdown .claude/skills/fix-issue/SKILL.md theme={null}268> Don't drop the `skip style` part of that prompt. A reviewer that's asked to find problems will always find *something*. If you fix every finding, you end up with extra abstraction layers and tests for cases that can't happen.

254name: fix-issue269 

255description: Fix a GitHub issue270### Enforce the check with a Stop hook

256disable-model-invocation: true271 

257Analyze and fix the GitHub issue: $ARGUMENTS.272The `Stop` hook version of the typecheck rule is a few lines in `.claude/settings.json`. Exit code 2 is what blocks the stop. Whatever the command prints to stderr goes back to Claude as the reason it can't finish yet, which is why the compiler output is redirected there:

258 273 

2591. Use `gh issue view` to get the issue details274```json .claude/settings.json theme={null}

2602. Understand the problem described in the issue275{

2613. Search the codebase for relevant files276 "hooks": {

2624. Implement the necessary changes to fix the issue277 "Stop": [

2635. Write and run tests to verify the fix278 {

2646. Ensure code passes linting and type checking279 "hooks": [

2657. Create a descriptive commit message280 { "type": "command", "command": "pnpm tsc --noEmit 1>&2 || exit 2" }

2668. Push and create a PR281 ]

282 }

283 ]

284 }

285}

267```286```

268 287 

269Run `/fix-issue 1234` to invoke it. Use `disable-model-invocation: true` for workflows with side effects that you want to trigger manually.288To see it work, ask Claude for a change that breaks a type: instead of finishing, it gets the compiler errors back and keeps going until `tsc` passes. If the hook blocks [eight stops in a row](https://code.claude.com/docs/en/hooks.md#stop-input) with no tool call between them, Claude Code overrides the next block and ends the turn. To raise the cap, set [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](https://code.claude.com/docs/en/env-vars).

270 289 

271### Create custom subagents290## Enforce the rules that can't have exceptions

272 291 

273> [!TIP]292> [!TIP]

274>293>

275> Define specialized assistants in `.claude/agents/` that Claude can delegate to for isolated tasks.294> If something has to happen every time, make it a hook, a deny rule, or a managed setting. `CLAUDE.md` is for guidelines, and Claude is allowed to decide a guideline doesn't apply.

276 295 

277[Subagents](https://code.claude.com/docs/en/sub-agents.md) run in their own context with their own set of allowed tools. They're useful for tasks that read many files or need specialized focus without cluttering your main conversation.296Take three rules you might have in `CLAUDE.md` today: `Never read .env`, `Always run the formatter after editing`, `Don't touch the migrations folder`. Claude will follow these almost every time. For the few where "almost" isn't good enough, move them out of `CLAUDE.md` and into configuration that Claude Code (the harness) applies itself. From then on, the outcome doesn't depend on what the model remembers or decides.

278 297 

279```markdown .claude/agents/security-reviewer.md theme={null}298### Enforce steps with hooks

280name: security-reviewer299 

281description: Reviews code for security vulnerabilities300[Hooks](https://code.claude.com/docs/en/hooks-guide.md) run something of yours at fixed points in Claude's loop: before or after a tool call, when Claude tries to stop, when a session starts, and so on. That something can be:

282tools: Read, Grep, Glob, Bash301 

283model: opus302* A shell command (the usual case)

284You are a senior security engineer. Review code for:303* A POST to an HTTP endpoint

285- Injection vulnerabilities (SQL, XSS, command injection)304* A tool call on one of your MCP servers

286- Authentication and authorization flaws305* A [`prompt` or `agent` hook](https://code.claude.com/docs/en/hooks#hook-handler-fields), which lets a model decide

287- Secrets or credentials in code306 

288- Insecure data handling307A `prompt` or `agent` hook asks *another model* to decide, so it isn't deterministic either. For real enforcement, use a `command` or `http` hook, and add [`onFailure: "block"`](https://code.claude.com/docs/en/hooks#block-the-action-when-a-hook-fails) if the action should also be stopped when the hook itself crashes or times out. For a hook that scans commits for secrets, say, you'd rather block the commit than let it through unscanned while the scanner is down.

308 

309Here's the formatter rule as a `PostToolUse` hook. It runs after every `Edit` or `Write`, and whether Claude remembers the rule no longer matters, because Claude isn't the one running it:

289 310 

290Provide specific line references and suggested fixes.311```json .claude/settings.json theme={null}

312{

313 "hooks": {

314 "PostToolUse": [

315 {

316 "matcher": "Edit|Write",

317 "hooks": [

318 { "type": "command", "command": "npx prettier --write --ignore-unknown \"$(jq -r '.tool_input.file_path')\"" }

319 ]

320 }

321 ]

322 }

323}

291```324```

292 325 

293Tell Claude to use subagents explicitly: *"Use a subagent to review this code for security issues."*326To check the hook, ask Claude to add a badly indented line to a file Prettier formats. The saved file comes back with the indentation fixed.

294 327 

295### Install plugins328The migrations rule becomes a [`PreToolUse` hook](https://code.claude.com/docs/en/hooks-guide#block-edits-to-protected-files) that exits with code 2 for any path under `migrations/`. You don't have to write it yourself: `write a hook that blocks edits to the migrations folder` works as a prompt, and `/hooks` shows the result. Don't overdo it, though: a hook is for a rule with *zero* exceptions, and `Prefer named exports` has plenty, so that one stays in `CLAUDE.md`.

296 329 

297> [!TIP]330### Limit access with permission rules and the sandbox

298>

299> Run `/plugin` to browse the marketplace. Plugins add skills, tools, and integrations without configuration.

300 331 

301[Plugins](https://code.claude.com/docs/en/plugins/overview.md) bundle skills, hooks, subagents, and MCP servers into a single installable unit from the community and Anthropic. If you work with a typed language, install a [code intelligence plugin](https://code.claude.com/docs/en/plugins/code-intelligence.md) to give Claude precise symbol navigation and automatic error detection after edits.332[Permission rules](https://code.claude.com/docs/en/permissions.md) decide what Claude is allowed to run, read, and fetch. `deny` rules hold in every permission mode, including auto and `bypassPermissions`, which is exactly why the `.env` rule belongs there:

302 333 

303For guidance on choosing between skills, subagents, hooks, and MCP, see [Extend Claude Code](https://code.claude.com/docs/en/features-overview.md#match-features-to-your-goal).334```json .claude/settings.json theme={null}

335{

336 "permissions": {

337 "allow": ["Bash(pnpm tsc --noEmit)"],

338 "ask": ["Bash(git push *)"],

339 "deny": ["Read(./.env)", "Read(./.env.local)", "Read(./secrets/**)"]

340 }

341}

342```

304 343 

305***344With this saved, asking Claude what's in `.env` fails, through the `Read` tool and through `cat .env` alike.

306 345 

307## Communicate effectively346Rules match tool calls, not intent, so it's worth knowing where the edges are:

308 347 

309Ask Claude the questions you'd ask another engineer, and for larger features have Claude interview you and write a spec before you start implementing.348* The `Read` rule *does* catch `cat .env`, because Claude Code recognizes the [common file-reading commands](https://code.claude.com/docs/en/permissions.md#read-and-edit).

349* It won't catch a script that opens the file.

350* A `WebFetch` deny rule for a domain does nothing about `curl` to that same domain, unless the sandbox is on.

310 351 

311### Ask codebase questions352For an OS-level limit on filesystem or network access, turn on the [sandbox](https://code.claude.com/docs/en/sandboxing.md) with `/sandbox` in a session. It confines Claude's shell commands on macOS, Linux, and WSL2 and [picks up your `Read` deny rules and `WebFetch(domain:...)` rules](https://code.claude.com/docs/en/sandboxing#permission-rules) too, so for anything security-related you want both.

312 353 

313> [!TIP]354By default Claude can still ask to retry a blocked command outside the sandbox, and that request goes through the normal permission flow. [Strict sandbox mode](https://code.claude.com/docs/en/sandboxing.md#turn-off-the-retry-with-strict-sandbox-mode), in the `/sandbox` **Overrides** tab, turns that retry off.

355 

356> [!WARNING]

314>357>

315> Ask Claude questions you'd ask a senior engineer.358> Auto mode is a classifier model judging each action rather than a hard rule. It's good at that, but like any judgment call it can be wrong. You can also tune what it treats as risky, and your org can turn it off entirely, so your "never" rules belong in deny rules or hooks.

359 

360### Choose who a rule applies to

316 361 

317When onboarding to a new codebase, use Claude Code for learning and exploration. You can ask Claude the same sorts of questions you would ask another engineer:362Where a rule lives decides who it applies to:

318 363 

319* How does logging work?364* `.claude/settings.local.json` and `~/.claude/settings.json` are yours alone. When you select **Yes, and don't ask again** for a command, Claude Code saves that rule to the local file.

320* How do I make a new API endpoint?365* `.claude/settings.json` and the hooks in it belong to the repo. Once you commit them, they apply to everyone who works in the repo. Its deny rules apply right away. Its `allow` rules wait until each person accepts the [trust dialog](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder) for that folder, and [workspace trust](https://code.claude.com/docs/en/hooks.md#workspace-trust) also decides when its hooks start running on their machine.

321* What does `async move { ... }` do on line 134 of `foo.rs`?366* [Managed settings](https://code.claude.com/docs/en/managed-settings.md) belong to the organization. They come from the admin console, MDM, or a `managed-settings.json` file, and no personal settings file can override them, which makes them the only place for a security team's policy. If you are the person who sets them, see [Set up Claude Code for your organization](https://code.claude.com/docs/en/admin-setup.md).

322* What edge cases does `CustomerOnboardingFlowImpl` handle?

323* Why does this code call `foo()` instead of `bar()` on line 333?

324 367 

325Using Claude Code this way is an effective onboarding workflow, improving ramp-up time and reducing load on other engineers. No special prompting required: ask questions directly.368Whatever the scope, keep the enforced set small. Every hook and deny rule will occasionally fire when it shouldn't, and someone has to maintain each one. If you ever find yourself at forty of them, most are probably preferences that Claude could have weighed on its own.

326 369 

327### Let Claude interview you370## Change a default

328 371 

329> [!TIP]372> [!TIP]

330>373>

331> For larger features, have Claude interview you first. Start with a minimal prompt and ask Claude to interview you using the `AskUserQuestion` tool.374> The defaults are good enough to leave alone until a task costs more time, tokens, or interruptions than it should. When that happens, run `/usage` in the session to see where it went.

332 375 

333Claude asks about things you might not have considered yet, including technical implementation, UI/UX, edge cases, and tradeoffs. Replace `[brief description]` with your feature before sending the prompt.376A new session already makes a handful of decisions for you:

334 377 

335```text wrap theme={null}378* Interactive terminal and VS Code sessions start in auto mode.

336I want to build [brief description]. Interview me in detail using the AskUserQuestion tool.379* It runs [Claude Opus 5.5 at medium effort](https://code.claude.com/docs/en/model-config.md#default-model-setting) on most plans and providers.

380* It delegates work to subagents when it sees a reason to.

381* It compacts the conversation as it grows.

337 382 

338Ask about technical implementation, UI/UX, edge cases, concerns, and tradeoffs. Don't ask obvious questions, dig into the hard parts I might not have considered.383Most of the time you never think about these. When a task does cost more than it should, one of these four is usually why.

339 384 

340Keep interviewing until we've covered everything, then write a complete spec to SPEC.md.385### Change the permission mode

341```

342 386 

343Once the spec is complete, start a fresh session to execute it. The new session has clean context focused entirely on implementation, and you have a written spec to reference.387Both ends of the permission range have a cost:

344 388 

345The most useful specs are self-contained: they name the files and interfaces involved, state what is out of scope, and end with an end-to-end verification step that proves the feature works. Time spent making the spec precise pays off more than time spent watching the implementation.389* **Manual mode**: you approve every edit and every command that isn't read-only yourself. Safe, but after the tenth prompt you start approving without reading, and nothing moves while you're away from the keyboard.

390* **`bypassPermissions`**: approves everything your deny and ask rules don't cover, which only makes sense in a disposable container.

346 391 

347***392[Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) sits between the two, and it's what interactive terminal and VS Code sessions [start in](https://code.claude.com/docs/en/permission-modes.md#which-mode-a-session-starts-in). Claude works without stopping for routine approvals, and a separate classifier model checks actions in [a fixed order](https://code.claude.com/docs/en/permission-modes.md#how-the-classifier-evaluates-actions) before they run. It concentrates on [the things you'd want a person to stop](https://code.claude.com/docs/en/permission-modes.md#what-the-classifier-blocks-by-default):

348 393 

349## Manage your session394* `curl | bash`

395* Production deploys and migrations

396* Force pushes over other people's work

397* Sensitive data sent to external endpoints

398* Actions that look driven by content Claude read rather than by you

350 399 

351Conversations are persistent and reversible. Use this to your advantage!400When it does block something, you get a notification and the action shows up under **Recently denied** in `/permissions`, where you can retry it with a manual approval. After [three blocks in a row](https://code.claude.com/docs/en/permission-modes.md#when-auto-mode-falls-back) (or twenty in total), auto mode pauses and goes back to asking you.

352 401 

353### Course-correct early and often402None of this replaces your deterministic controls, because it runs *after* them. Deny and ask rules and `PreToolUse` hooks apply before the classifier sees anything, so a deny rule blocks in auto mode exactly like it does everywhere else. The sandbox still confines the [shell commands it wraps](https://code.claude.com/docs/en/sandboxing.md#what-runs-outside-the-sandbox).

354 403 

355> [!TIP]404> [!NOTE]

356>405>

357> Correct Claude as soon as you notice it going off track.406> You can also say `don't push until I've reviewed` in the conversation, and the classifier [treats that as a block signal](https://code.claude.com/docs/en/permission-modes.md#boundaries-you-state-in-conversation). It's still a model reading the transcript, and the sentence can get lost when the conversation compacts, so anything that matters belongs in a deny rule.

407 

408The opposite problem is the classifier repeatedly stopping something that's routine in your setup. Rather than approving it manually every time, add it to `autoMode.allow` or describe your trusted infrastructure in the [auto mode configuration](https://code.claude.com/docs/en/auto-mode-config.md). It's plain English rather than patterns, and [`/auto-mode-setup`](https://code.claude.com/docs/en/auto-mode-config#generate-environment-entries) can draft the `environment` part for you from your project and recent sessions:

409 

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

411{

412 "autoMode": {

413 "environment": [

414 "$defaults",

415 "Source control: github.com/example-org and every repo under it",

416 "Trusted internal domains: *.internal.example.com"

417 ],

418 "allow": [

419 "$defaults",

420 "Deploying to the staging namespace is fine, it's isolated from production and resets nightly"

421 ]

422 }

423}

424```

358 425 

359The best results come from tight feedback loops. Though Claude occasionally solves problems perfectly on the first attempt, correcting it quickly generally produces better solutions faster.426> [!WARNING]

427>

428> Keep `"$defaults"` in every list you set, because without it your entries *replace* that list's built-in rules instead of adding to them. For `environment` and `allow` you'd lose the built-in context and exceptions, and a `soft_deny` list without it drops the built-in blocks on force pushes and production deploys.

429>

430> The `autoMode` block also has to live in `~/.claude/settings.json` rather than the project, because the classifier ignores `autoMode` in project settings.

360 431 

361* **`Esc`**: stop Claude mid-action with the `Esc` key. Context is preserved, so you can redirect.432If you'd rather see every edit and command before it happens, `Shift+Tab` in the session cycles through the permission modes, Manual included, or start with `claude --permission-mode manual` from your shell. And if Manual then asks too often, `/fewer-permission-prompts` scans your recent transcripts for common read-only Bash and MCP calls and adds them to an allowlist in `.claude/settings.json`.

362* **`Esc + Esc` or `/rewind`**: press `Esc` twice or run `/rewind` to open the rewind menu and restore previous conversation and code state, or summarize from a selected message.

363* **`"Undo that"`**: have Claude revert its changes.

364* **`/clear`**: reset context between unrelated tasks. Long sessions with irrelevant context can reduce performance.

365 433 

366If you've corrected Claude more than twice on the same issue in one session, the context is cluttered with failed approaches. Run `/clear` and start fresh with a more specific prompt that incorporates what you learned. A clean session with a better prompt almost always outperforms a long session with accumulated corrections.434### Change the model and effort

367 435 

368### Manage context aggressively436[Effort](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) is the main control for how long Claude thinks, and it replaces most of what people used to do with prompt wording. Claude Opus 5.5, Sonnet 5.5, and Haiku 5.5 default to `medium`, which is plenty for everyday feature work with a clear scope. The times you'd move it, with `/effort` in the session:

369 437 

370> [!TIP]438* Raise it with `/effort high` or `/effort xhigh` when getting it right depends on cases that are quick to overlook. Think of a bug in code you didn't write, a flaky test, or a schema change where Claude has to find every reader of the old shape. Claude then checks more edge cases and verifies more of its work before answering, which is where the extra time and tokens go.

371>439* Lower it with `/effort low` when you're going back and forth quickly and reviewing each result anyway: brainstorming, a first sketch, a rename across a few files. Claude gets you a starting point sooner, and since you're steering every step, the extra deliberation wouldn't have changed much besides the wait.

372> Run `/clear` between unrelated tasks to reset context.440* Save `max` for a hard problem you want Claude to work through without you, like hunting for a security vulnerability. On ordinary tasks it tends to overthink, so you pay more for an answer that may be no better than `high` would have given you.

441* When only the next message needs it, like one tricky question in the middle of otherwise routine work, put [`ultrathink`](https://code.claude.com/docs/en/model-config#use-ultrathink-for-one-off-deep-reasoning) in that prompt instead of changing the setting.

373 442 

374Claude Code automatically compacts conversation history when you approach context limits, which preserves important code and decisions while freeing space.443For the model itself, the default Opus 5.5 handles most coding well and Sonnet costs less on routine work. [Claude Fable 5.1](https://code.claude.com/docs/en/model-config.md#work-with-fable) is there when you select it explicitly with `/model fable`, and Haiku is a good fit for subagents doing simple jobs. [Model configuration](https://code.claude.com/docs/en/model-config.md) has the full list per plan and provider.

375 444 

376During long sessions, Claude's context window can fill with irrelevant conversation, file contents, and commands. This can reduce performance and sometimes distract Claude.445### Know what subagents cost

377 446 

378* Use `/clear` frequently between tasks to reset the context window entirely447Claude delegates to [subagents](https://code.claude.com/docs/en/sub-agents.md) on its own:

379* When auto compaction triggers, Claude summarizes what matters most, including code patterns, file states, and key decisions

380* For more control, run `/compact <instructions>`, like `/compact Focus on the API changes`

381* To compact only part of the conversation, use `Esc + Esc` or `/rewind`, select a message checkpoint, and choose **Summarize from here** or **Summarize up to here**. The first condenses messages from that point forward while keeping earlier context intact; the second condenses earlier messages while keeping recent ones in full. See [the rewind menu's summarize options](https://code.claude.com/docs/en/checkpointing.md#rewind-and-summarize).

382* Customize compaction behavior in CLAUDE.md with instructions like `"When compacting, always preserve the full list of modified files and any test commands"` to ensure critical context survives summarization

383* For questions that don't need to stay in context, use [`/btw`](https://code.claude.com/docs/en/interactive-mode#side-questions-with-%2Fbtw). The answer never enters conversation history, so you can check a detail without growing context.

384 448 

385### Use subagents for investigation449* Broad codebase searches go to the built-in Explore agent.

450* Side tasks get [forked](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation) while fork mode is on (the default).

451* The subagents it starts run in the background by default, so your main conversation keeps moving.

386 452 

387> [!TIP]453You rarely need to ask for any of this, but it helps to know what you're getting and what it costs.

388>

389> Delegate research with `"use subagents to investigate X"`. They explore in a separate context, keeping your main conversation clean for implementation.

390 454 

391Since context is your fundamental constraint, use subagents to keep research out of it. When Claude researches a codebase it reads lots of files, all of which consume your context. Subagents run in separate context windows and report back summaries:455Subagents pay off in these situations:

392 456 

393```text wrap theme={null}457* Running independent pieces of work at the same time, so the whole task finishes sooner

394Use subagents to investigate how our authentication system handles token458* Keeping long output, like a full test run or a wide search, out of your main conversation, where it would otherwise ride along for the rest of the session

395refresh, and whether we have any existing OAuth utilities I should reuse.459* Getting a reviewer that hasn't seen how the code was written

396```460* Giving a task fewer tools than the main session has, like a reviewer that can read but not edit

397 461 

398You can also use subagents for verification after Claude implements something. See [Add an adversarial review step](#add-an-adversarial-review-step).462What they cost you is mostly tokens, since every subagent sends its own requests and they count against the same usage as your main conversation. Sometimes it's time as well: a fresh subagent first has to gather context your conversation already had, so it can end up *slower* than doing the task where you are.

399 463 

400### Rewind with checkpoints464And by default it's the same model (or a smaller one) on the same task. You get parallelism or a fresh pair of eyes out of it, but not a smarter answer.

401 465 

402> [!TIP]466To spend less on them:

403>

404> Every prompt you send that starts a turn creates a checkpoint. You can restore conversation, code, or both to any previous checkpoint.

405 467 

406Claude automatically snapshots files before each change so a checkpoint can restore them. Double-tap `Escape` or run `/rewind` to open the rewind menu. You can restore conversation only, restore code only, restore both, or summarize from a selected message. See [Checkpointing](https://code.claude.com/docs/en/checkpointing.md) for details.468* Set [`model: haiku`](https://code.claude.com/docs/en/sub-agents#choose-a-model) in a subagent's definition if its work is simple, like collecting the files that import a module or checking links in the docs. That kind of job doesn't need the bigger model, and Haiku costs a lot less per request.

469* Ask for short summaries back, so twenty results don't fill your context anyway.

470* Check `/usage` to see what share of your usage each subagent type takes, so you can tell which ones are earning their cost.

471* Give a custom subagent in `.claude/agents/` only `tools: Read, Grep, Glob`. Now it's a reviewer that can't edit anything, and that limit is enforced by Claude Code rather than requested in a prompt.

407 472 

408Instead of carefully planning every move, you can tell Claude to try something risky. If it doesn't work, rewind and try a different approach. Checkpoints are saved with the conversation, so you can close your terminal, resume the session later, and still rewind.473That reviewer is one short file, `.claude/agents/reviewer.md`:

409 474 

410> [!WARNING]475```markdown .claude/agents/reviewer.md theme={null}

411>476---

412> Checkpoints only track changes made through Claude's file editing tools. Changes made through Bash commands or external processes are not captured. This isn't a replacement for git.477name: reviewer

478description: Reviews changed files against the spec they were built from. Use after implementing a feature, before opening the PR.

479tools: Read, Grep, Glob

480---

481You're reviewing code you didn't write. Compare the changed files against the spec you're given,

482check that every requirement is implemented and the listed edge cases have tests,

483and report only the gaps that affect correctness. Skip style.

484```

413 485 

414### Resume conversations486Ask Claude to `have the reviewer compare the rate limiter against SPEC.md` and the gaps come back into your session, where Claude can fix them.

415 487 

416> [!TIP]488### Keep cost and context down

417>

418> Name sessions with `/rename` and treat them like branches: each workstream gets its own persistent context.

419 489 

420Claude Code saves conversations locally, so when a task spans multiple sittings you don't have to re-explain the context. Run [`claude --continue`](https://code.claude.com/docs/en/sessions#resume-a-session) to pick up where you left off, or `claude --resume` to choose from a list. Give sessions descriptive names like `oauth-migration` so you can find them later. See [Manage sessions](https://code.claude.com/docs/en/sessions.md) for the full set of resume, branch, and naming controls.490With a 1M-token window on most current models and compaction near the top of it, you'll rarely run out of context. You can still *pay* for context you don't need, though. Every request sends the whole conversation, so a session that's collected three unrelated tasks re-reads all three on every turn of the fourth. That's [discounted while the cache is warm](https://code.claude.com/docs/en/costs.md#why-usage-climbs-in-a-long-session) and full price once it expires.

421 491 

422***492[`/usage`](https://code.claude.com/docs/en/costs) is the first place to look. On Pro, Max, Team, and Enterprise it breaks your usage down by skill, subagent, plugin, and MCP server. It also flags patterns like long context or frequent cache misses once one of them passes 10% of your usage. From there, the usual fixes:

423 493 

424## Automate and scale494* `/clear` between unrelated tasks. It costs nothing, and it means the next task doesn't keep paying for the previous one's history. `/clear oauth-migration` names the session you're leaving, so you can come back to it later.

495* `/compact` with a focus, like `/compact keep the API changes and the test commands`. On a long session `/compact` is itself a big request, since it reads the whole conversation to summarize it, and even more so once the cache has expired.

496* Keep an eye on background work: a `/loop`, a goal's check after every turn, and Claude's own subagents all keep sending requests while you aren't typing.

425 497 

426Once you're effective with one Claude, multiply your output with parallel sessions, non-interactive mode, and fan-out patterns.498> [!NOTE]

499>

500> The [prompt cache](https://code.claude.com/docs/en/prompt-caching.md) lasts about an hour on a subscription and five minutes on an API key, cloud provider, or usage credits. Subagents get five minutes unless you change it.

501>

502> On the one-hour cache, a session past about 200K tokens that sits idle is compacted shortly before the cache expires, so after lunch you continue from a summary. If you don't need the history at all, a fresh session still costs less.

427 503 

428### Run non-interactive mode504## Steer the session

429 505 

430> [!TIP]506> [!TIP]

431>507>

432> Use `claude -p "prompt"` in CI, pre-commit hooks, or scripts. Add `--output-format stream-json --verbose` for streaming JSON output.508> Watch the first minute, press `Esc` the moment Claude drifts, and after two failed corrections run `/clear` and write a better prompt instead of a third.

433 509 

434With `claude -p "your prompt"`, you can run Claude non-interactively, without an interactive prompt. The run still creates a resumable session unless you pass `--no-session-persistence`. [Non-interactive mode](https://code.claude.com/docs/en/headless.md) is how you integrate Claude into CI pipelines, pre-commit hooks, or any automated workflow. The output formats let you parse results programmatically: plain text, JSON, or streaming JSON.510No amount of configuration replaces watching the first minute and stepping in when Claude heads somewhere you didn't intend. There are only a few controls for that, and they're worth knowing by heart:

435 511 

436```bash theme={null}512* `Esc` stops Claude mid-action and keeps everything up to that point, so you can redirect without losing work.

437# One-off queries513* `/rewind`, or `Esc` twice on an empty prompt, opens the [rewind menu](https://code.claude.com/docs/en/checkpointing.md#rewind-and-summarize), where you roll the code, the conversation, or both back to an earlier prompt. That makes it low-risk to try the bolder approach first and rewind if it doesn't work out. The same menu can also summarize part of the conversation when it has gone stale.

438claude -p "Explain what this project does"514* `/clear` starts over. If you've corrected the same thing twice and it's still wrong, a third correction mostly adds to a conversation that already contains two failed attempts for Claude to keep re-reading. `/clear` plus one new prompt that folds in what you learned works better almost every time.

439 

440# Structured output for scripts

441claude -p "List all API endpoints" --output-format json

442 515 

443# Streaming for real-time processing516> [!WARNING]

444claude -p "Analyze this log file" --output-format stream-json --verbose517>

445```518> Checkpoints cover the files Claude edited with its own file tools in your main conversation, so a file that only a Bash command touched [isn't restored](https://code.claude.com/docs/en/checkpointing.md#bash-command-changes-not-tracked). They work alongside git rather than replacing it.

446 519 

447The first command prints plain text. The `json` format returns a single JSON object with a `result` field. The `stream-json` format prints one JSON object per line, starting with an init event.520Two smaller ones: [`/btw`](https://code.claude.com/docs/en/interactive-mode#side-questions-with-%2Fbtw) answers a quick question without adding anything to the history. And for work that spans several days, `/rename oauth-migration` in the session names it, so that [`claude --resume oauth-migration`](https://code.claude.com/docs/en/sessions#resume-by-session-id-or-name) from your shell picks it back up later, checkpoints included. `claude --continue` resumes the most recent one.

448 521 

449### Run multiple Claude sessions522## Let Claude run without you

450 523 

451> [!TIP]524> [!TIP]

452>525>

453> Run multiple Claude sessions in parallel to speed up development, run isolated experiments, or start complex workflows.526> Before a run goes unattended, make sure it knows what done looks like, can check its own work, and can only touch what it should. Give it a cap on turns or spend, and have a person approve the result at the end.

454 

455Pick the parallel approach that fits how much coordination you want to do yourself, and add messaging when the sessions need to pass findings between them:

456 527 

457* [Worktrees](https://code.claude.com/docs/en/worktrees.md): run separate CLI sessions in isolated git checkouts so edits don't collide528Everything on this page matters a little more once you're not around to catch mistakes. While you're watching, Claude missing some piece of context isn't a big deal: you notice within a message or two and tell it. In a run you started before going to bed, nobody tells it, and you find out the next morning that it spent the whole night building on the wrong assumption.

458* [Cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md): let the sessions you run yourself pass findings to each other

459* [Desktop app](https://code.claude.com/docs/en/desktop.md#work-in-parallel-with-sessions): manage multiple local sessions visually, optionally each in its own worktree

460* [Use Claude Code in the cloud](https://code.claude.com/docs/en/claude-code-on-the-web.md): run sessions on Anthropic-managed infrastructure by default

461* [Agent view](https://code.claude.com/docs/en/agent-view.md): research preview. Run `claude agents` to dispatch sessions that keep running in the background and watch them from one screen

462* [Agent teams](https://code.claude.com/docs/en/agent-teams.md): experimental and disabled by default. Automated coordination of multiple sessions with shared tasks, messaging, and a team lead

463 529 

464Beyond parallelizing work, multiple sessions enable quality-focused workflows. A fresh context improves code review since Claude won't be biased toward code it just wrote.530Before you leave a task running on its own, it's worth going through these five questions with that specific task in mind:

465 531 

466For example, use a Writer/Reviewer pattern:5321. Does it know what done looks like? A goal condition, a spec file, or a failing test it has to turn green.

5332. Can it check its own work? The test suite, a `Stop` hook, some kind of review step.

5343. What's it allowed to touch? Permission rules, `dontAsk`, the sandbox, a worktree, the one branch it may push to.

5354. What stops it? `--max-turns`, `--max-budget-usd`, a spend limit.

5365. Where does the result go, and who signs off? A PR, a comment, or a summary, and then a person approving the merge, the deploy, or anything else you can't take back.

467 537 

468| Session A (Writer) | Session B (Reviewer) |538Once it's going, Claude will carry a long task through on its own. The parts that stay with you are starting it, deciding what "done" means this time, and approving the merge at the end.

469| - | - |

470| `Implement a rate limiter for our API endpoints` | |

471| | `Review the rate limiter implementation in @src/middleware/rateLimiter.ts. Look for edge cases, race conditions, and consistency with our existing middleware patterns.` |

472| `Here's the review feedback: [Session B output]. Address these issues.` | |

473 539 

474You can do something similar with tests: have one Claude write tests, then another write code to pass them.540### Run Claude from a script

475 541 

476### Fan out across files542[`claude -p "prompt"`](https://code.claude.com/docs/en/headless) runs once and exits, which is how Claude Code ends up in CI jobs, git hooks, and shell loops.

477 

478> [!TIP]

479>

480> Loop through tasks calling `claude -p` for each. Use `--allowedTools` to pre-approve tools for batch operations.

481 543 

482For large migrations or analyses, you can distribute work across many parallel Claude invocations. Run [`/batch <instruction>`](https://code.claude.com/docs/en/commands#all-commands) to have Claude split the change across 5 to 30 subagents. Each subagent works in its own worktree. To drive the fan-out from your own script instead, loop over `claude -p`:544In a script you'll almost always want a few more flags:

483 545 

484**1. Generate a task list**546* [`--bare`](https://code.claude.com/docs/en/headless#start-faster-with-bare-mode) skips hooks, skills, plugins, MCP servers, and `CLAUDE.md` files, the repo's as well as the machine's, so the run does the same thing wherever it runs. It also never touches your claude.ai login: auth comes from `ANTHROPIC_API_KEY`, an `apiKeyHelper` in the file you pass with `--settings`, or your cloud provider's credentials.

547* `--append-system-prompt`, `--mcp-config`, and `--settings` pass in whatever the run *does* need, explicitly.

548* `--allowedTools` pre-approves its tools, and [`--permission-mode dontAsk`](https://code.claude.com/docs/en/permission-modes#allow-only-pre-approved-tools-with-dontask-mode) refuses anything else that would have prompted.

549* `--output-format json` gives you a single result object to parse, and `stream-json` with `--verbose` streams events as they happen.

485 550 

486Have Claude write the list of files that need migrating to a file, so the loop in the next step can read it, with a prompt like `list all 2,000 Python files that need migrating and save the list to files.txt`551Put together, that looks like this:

487 

488**2. Write a script to loop through the list**

489 552 

490```bash theme={null}553```bash theme={null}

491for file in $(cat files.txt); do554for file in $(cat files.txt); do

492 claude -p "Migrate $file from Python 2 to Python 3. Return OK or FAIL." \555 claude --bare -p "Migrate $file to the new logger API and commit. Reply OK or FAIL." \

493 --allowedTools "Edit,Bash(git commit *)" \556 --allowedTools "Read,Edit,Bash(git add *),Bash(git commit *)" \

494 --permission-mode dontAsk557 --permission-mode dontAsk \

558 --max-turns 20

495done559done

496```560```

497 561 

498**3. Test on a few files, then run on all of them**562When a run finishes, Claude replies `OK` or `FAIL`, and a run that hits the turn limit exits with an error instead. Try it on three files first, see what goes wrong, fix the prompt, then run the rest.

499 

500Refine your prompt based on what goes wrong with the first 2-3 files, then run on the full set. The `--allowedTools` flag pre-approves the tools the migration needs. [`--permission-mode dontAsk`](https://code.claude.com/docs/en/permission-modes#allow-only-pre-approved-tools-with-dontask-mode) denies anything else that would need approval, which matters when you're running unattended, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve some of those calls.

501 563 

502You can also integrate Claude into existing data/processing pipelines:564Auto mode works with `-p` too if you pass `--permission-mode auto`. In a non-interactive run, a classifier block denies that one action and Claude carries on, and repeated blocks don't pause the run the way they do in a terminal. Read [how the thresholds apply there](https://code.claude.com/docs/en/permission-modes.md#repeated-block-thresholds) before you rely on it.

503 565 

504```bash theme={null}566### Start runs on a schedule or an event

505claude -p "<your prompt>" --output-format json | your_command

506```

507 567 

508### Run autonomously with auto mode568Once a run is going, Claude can handle the rest by itself. The one thing it can't do is decide to *start*, so something has to: you, a timer, or an event like a failed CI check or a new PR.

509 569 

510For uninterrupted execution with background safety checks, use [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode). A classifier model reviews commands before they run, blocking scope escalation, unknown infrastructure, and hostile-content-driven actions while letting routine work proceed without prompts.570Inside an open session that's [`/loop`](https://code.claude.com/docs/en/scheduled-tasks#run-a-prompt-repeatedly-with-%2Floop), which repeats a prompt on an interval:

511 571 

512```bash theme={null}572```text theme={null}

513claude --permission-mode auto -p "fix all lint errors"573/loop 15m check CI on this branch, and if it's red pull the failing job's log, fix it and push

514```574```

515 575 

516When the classifier repeatedly blocks actions in a non-interactive run with the `-p` flag, Claude Code doesn't stop the run. See [when auto mode falls back](https://code.claude.com/docs/en/permission-modes.md#when-auto-mode-falls-back) for what happens instead and for the thresholds.576Each run is another turn in the same session, so don't leave one going in a long conversation. For anything that should happen while your laptop is closed, [`/schedule`](https://code.claude.com/docs/en/routines#create-from-the-cli) sets up a [cloud scheduled task](https://code.claude.com/docs/en/routines.md) that runs on a timer. It needs a claude.ai login rather than an API key. You can add a GitHub-event trigger by asking Claude, or an API trigger at [claude.ai/code/routines](https://claude.ai/code/routines).

517 

518### Add an adversarial review step

519 577 

520> [!TIP]578> [!WARNING]

521>579>

522> Before treating a task as done, have a subagent review the diff in a fresh context and report gaps.580> Before you leave a cloud scheduled task running, protect `main` with a [GitHub branch rule the task can't bypass](https://code.claude.com/docs/en/routines.md#repositories-and-branch-permissions). And watch the first few runs of anything new before trusting it unattended.

523 

524The longer Claude works unattended, the more an independent check matters before you count the work as done. A reviewer running in a fresh [subagent](https://code.claude.com/docs/en/sub-agents.md) context sees only the diff and the criteria you give it, not the reasoning that produced the change, so it evaluates the result on its own terms.

525 581 

526For a correctness check, run the bundled [`/code-review` skill](https://code.claude.com/docs/en/commands), which reviews the current diff for bugs in a fresh subagent and returns findings to the session. To check the diff against your plan instead, write the review prompt yourself. Name the work to check, the plan to check it against, and what counts as a finding:582### Run sessions in parallel

527 583 

528```text wrap theme={null}584When you have separate pieces of work going at once, give each its own checkout so the edits can't collide. [`claude -w feature-auth`](https://code.claude.com/docs/en/worktrees#start-claude-in-a-worktree) starts a session in a new worktree, the [desktop app](https://code.claude.com/docs/en/desktop.md#work-in-parallel-with-sessions) runs several of these side by side, and [cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md) run them in the cloud instead of on your machine.

529Use a subagent to review the rate limiter diff against PLAN.md. Check that

530every requirement is implemented, the listed edge cases have tests, and

531nothing outside the task's scope changed. Report gaps, not style preferences.

532```

533 585 

534Because the reviewer runs as a subagent, the implementing session receives the gaps directly and can fix them and re-review without you copying findings between windows.586A worktree is a fresh checkout, which means gitignored files like `.env` aren't there and dependencies aren't installed. For the first, list the gitignored files you need in a [`.worktreeinclude`](https://code.claude.com/docs/en/worktrees#copy-gitignored-files-into-worktrees) at the repo root (same syntax as `.gitignore`) and Claude Code copies them into every worktree it creates:

535 587 

536A reviewer prompted to find gaps will usually report some, even when the work is sound, because that is what it was asked to do. Chasing every finding leads to over-engineering: extra abstraction layers, defensive code, and tests for cases that can't happen. Tell the reviewer to flag only gaps that affect correctness or the stated requirements, and treat the rest as optional.588```text .worktreeinclude theme={null}

589.env

590.env.local

591config/dev-credentials.json

592```

537 593 

538***594Keep it to small files: it copies rather than links, so `node_modules` in there would mean a full copy per worktree. For large directories there's the [`worktree.symlinkDirectories`](https://code.claude.com/docs/en/settings-reference#worktree-symlinkdirectories) setting, or keep the install command in `CLAUDE.md` so Claude runs it whenever it starts in a new checkout.

539 595 

540## Avoid common failure patterns596You rarely have to clean any of this up yourself:

541 597 

542These are common mistakes. Recognizing them early saves time:598* When you exit an unnamed worktree session, Claude Code [removes the worktree](https://code.claude.com/docs/en/worktrees.md#clean-up-worktrees) if there's nothing in it. For a named session, or one with changes, it asks what to do.

599* Subagent worktrees disappear when the subagent finishes without changes.

600* Subagent and background-session worktrees that do get left behind are swept once they're older than `cleanupPeriodDays` and hold no work.

543 601 

544* **The kitchen sink session.** You start with one task, then ask Claude something unrelated, then go back to the first task. Context is full of irrelevant information.602> [!NOTE]

545 > **Fix**: `/clear` between unrelated tasks.603>

546* **Correcting over and over.** Claude does something wrong, you correct it, it's still wrong, you correct again. Context is polluted with failed approaches.604> A `claude -p --worktree` run is one you clean up yourself, since it exits without asking. Remove those with `git worktree remove <path>`, and if git refuses because the worktree is locked, `git worktree unlock <path>` first.

547 > **Fix**: After two failed corrections, `/clear` and write a better initial prompt incorporating what you learned.

548* **The over-specified CLAUDE.md.** If your CLAUDE.md is too long, Claude ignores half of it because important rules get lost in the noise.

549 > **Fix**: Ruthlessly prune. If Claude already does something correctly without the instruction, delete it or convert it to a hook.

550* **The trust-then-verify gap.** Claude produces a plausible-looking implementation that doesn't handle edge cases.

551 > **Fix**: Always provide verification (tests, scripts, screenshots). If you can't verify it, don't ship it.

552* **The infinite exploration.** You ask Claude to "investigate" something without scoping it. Claude reads hundreds of files, filling the context.

553 > **Fix**: Scope investigations narrowly or use subagents so the exploration doesn't consume your main context.

554 605 

555***606For one big mechanical change across many files, [`/batch migrate every handler to the v2 response helpers`](https://code.claude.com/docs/en/commands) splits the work into 5 to 30 units and shows you the plan. Then it runs each unit in its own worktree and opens a PR for it. From your shell, [`claude agents`](https://code.claude.com/docs/en/agent-view) (still a research preview) gives you one screen for everything running in the background on your machine.

556 607 

557## Develop your intuition608A second session is also the easiest independent reviewer you can get. One session writes the rate limiter, another reviews `@src/middleware/rateLimiter.ts` without having watched it being written, and you paste the findings back into the first. Same idea as `/code-review`, with you carrying the messages.

558 609 

559The patterns in this guide aren't set in stone. They're starting points that work well in general, but might not be optimal for every situation.610## What you can stop doing

560 611 

561Sometimes you *should* let context accumulate because you're deep in one complex problem and the history is valuable. Sometimes you should skip planning and let Claude figure it out because the task is exploratory. Sometimes a vague prompt is exactly right because you want to see how Claude interprets the problem before constraining it.612Every one of these was good advice when it was written. Most were workarounds for something the model couldn't reliably do yet, and the models have since caught up. If a few are still habits, here's why it's safe to drop them.

562 613 

563Pay attention to what works. When Claude produces great output, notice what you did: the prompt structure, the context you provided, the mode you were in. When Claude struggles, ask why. Was the context too noisy? The prompt too vague? The task too big for one pass?614| The old advice | Why it's gone |

615| :- | :- |

616| The context window is your main constraint, manage it aggressively | Most current models have a 1M-token window and compaction happens on its own, so running out is rare. `/clear` between tasks is still worth doing, because a focused context gets you better answers and costs less. |

617| Add IMPORTANT or ALL CAPS to instructions Claude keeps missing | Older models sometimes needed the emphasis. Current ones follow a plainly worded line, and piling on emphasis mostly makes Claude over-apply the rule. If it's a rule that can't bend, turn it into a hook or a deny rule. If the line is getting lost in a long file, the file needs to be shorter. |

618| Use subagents to protect your context window | Running out of context is rarely the problem anymore. Subagents are still great for parallel work, keeping noisy output out of your way, and independent review, but each of those costs extra tokens. |

619| Delegate to a subagent for a better answer | Handing the same task to a subagent doesn't make the answer any better. A fresh reviewer does help, because it hasn't seen your reasoning, which is a different thing from delegating. |

620| `think hard`, `think harder`, `be thorough` in the prompt | Effort is the control for that. Those phrases are ordinary prompt text that nudges Claude within its effort setting rather than keywords that raise it. `ultrathink` still works: it asks for deeper reasoning on that single turn without touching your effort setting. |

621| Tell Claude to keep going, loop until done, don't be lazy | Current models usually carry on through an agreed task without being told, and lines like that are more likely to cause over-work than fix a stall. Giving Claude a check to pass is different, and still worth doing. If a run does stop short, say `continue`, and for runs nobody's watching, `/goal` or a `Stop` hook enforces it. |

622| Describe your architecture and file layout in `CLAUDE.md` | Claude reads the repo itself. Only write down what isn't in there. |

564 623 

565Over time, you'll develop intuition that no guide can capture. You'll know when to be specific and when to be open-ended, when to plan and when to explore, when to clear context and when to let it accumulate.624If any other advice on this page ever starts to feel like busywork, that's probably a sign it belongs in this table too.

566 625 

567## Related resources626## Related resources

568 627 

569* [How Claude Code works](https://code.claude.com/docs/en/how-claude-code-works.md): the agentic loop, tools, and context management628* [How Claude Code works](https://code.claude.com/docs/en/how-claude-code-works.md): the loop, the tools, and what loads at startup

570* [Extend Claude Code](https://code.claude.com/docs/en/features-overview.md): skills, hooks, MCP, subagents, and plugins629* [Explore the context window](https://code.claude.com/docs/en/context-window.md): what uses space in a session and when it loads

571* [Common workflows](https://code.claude.com/docs/en/common-workflows.md): step-by-step recipes for debugging, testing, PRs, and more630* [Extend Claude Code](https://code.claude.com/docs/en/features-overview.md): the choice between skills, hooks, MCP, subagents, and plugins

572* [CLAUDE.md](https://code.claude.com/docs/en/memory.md): store project conventions and persistent context631* [Choose a permission mode](https://code.claude.com/docs/en/permission-modes.md) and [Configure permissions](https://code.claude.com/docs/en/permissions.md)

632* [Manage costs effectively](https://code.claude.com/docs/en/costs.md)

633* [Run Claude Code programmatically](https://code.claude.com/docs/en/headless.md) and [Automate work with cloud scheduled tasks](https://code.claude.com/docs/en/routines.md)

634* For team leads and admins: [Set up Claude Code for your organization](https://code.claude.com/docs/en/admin-setup.md)

chrome.md +1 −1

Details

43 43 

44In Enterprise organizations that have HIPAA enabled, Claude in Chrome is off by default, and an [Owner](https://code.claude.com/docs/en/server-managed-settings.md#access-control) can turn it on in [**Organization settings > Claude in Chrome**](https://claude.ai/admin-settings/browser-extension). Your Business Associate Agreement (BAA) with Anthropic doesn't cover data sent to third-party sites through Claude in Chrome. See the [Implementation Guide](https://trust.anthropic.com/resources?s=l1wrssd9hsbi4gak0tp5a6\&name=%5Banthropic%5D-hipaa-ready-offering-implementation-guide) for a list of Eligible Services.44In Enterprise organizations that have HIPAA enabled, Claude in Chrome is off by default, and an [Owner](https://code.claude.com/docs/en/server-managed-settings.md#access-control) can turn it on in [**Organization settings > Claude in Chrome**](https://claude.ai/admin-settings/browser-extension). Your Business Associate Agreement (BAA) with Anthropic doesn't cover data sent to third-party sites through Claude in Chrome. See the [Implementation Guide](https://trust.anthropic.com/resources?s=l1wrssd9hsbi4gak0tp5a6\&name=%5Banthropic%5D-hipaa-ready-offering-implementation-guide) for a list of Eligible Services.

45 45 

46Chrome integration also requires signing in with `/login`. If you authenticate with an API key or a long-lived token from [`claude setup-token`](https://code.claude.com/docs/en/authentication#generate-a-long-lived-token), Claude Code keeps Chrome integration off, even when you pass `--chrome`, because the browser extension can't authenticate with those credentials. Before v2.1.216, these sessions could enable Chrome integration, but every attempt to connect to the browser extension failed with a 403 error.46Chrome integration also requires signing in with `/login`. If you authenticate with an API key or a long-lived token from [`claude setup-token`](https://code.claude.com/docs/en/authentication#generate-a-long-lived-token), Claude Code keeps Chrome integration off, even when you pass `--chrome`. The browser extension can't authenticate with those credentials.

47 47 

48> [!NOTE]48> [!NOTE]

49>49>

Details

996 996 

997[Approval memory](https://code.claude.com/docs/en/server-managed-settings.md#approval-memory) covers how long an approval lasts and when the dialog appears again.997[Approval memory](https://code.claude.com/docs/en/server-managed-settings.md#approval-memory) covers how long an approval lasts and when the dialog appears again.

998 998 

999Claude Code applies some delivered `env` variables without showing the developer the approval dialog, such as model selection settings and numeric limits. Other delivered variables can require the developer's approval before they take effect; a non-empty proxy, base-URL, or `OTEL_EXPORTER_OTLP_ENDPOINT` value always does. When a delivered variable needs approval, the dialog names it.999Claude Code applies some delivered `env` variables without showing the developer the approval dialog, such as model selection settings and numeric limits. Other delivered variables can require the developer's approval; a non-empty proxy, base-URL, or `OTEL_EXPORTER_OTLP_ENDPOINT` value always does. When a delivered variable needs approval, the dialog names it. [Environment variables and the approval dialog](https://code.claude.com/docs/en/server-managed-settings.md#environment-variables-and-the-approval-dialog) has the details, including four privacy toggles whose delivered value decides whether they need approval.

1000 

1001[Environment variables and the approval dialog](https://code.claude.com/docs/en/server-managed-settings.md#environment-variables-and-the-approval-dialog) has the details, including four privacy toggles whose delivered value decides whether they need approval. Before v2.1.218, Claude Code applied fewer variables without asking the developer, so more delivered variables triggered the dialog.

1002 1000 

1003The gateway's [telemetry](#telemetry) configuration pushes `OTEL_EXPORTER_OTLP_ENDPOINT`, so setting `telemetry.forward_to` triggers the dialog on each interactive client. The dialog protects the developer's machine from a compromised or hostile gateway, not the organization from the developer.1001The gateway's [telemetry](#telemetry) configuration pushes `OTEL_EXPORTER_OTLP_ENDPOINT`, so setting `telemetry.forward_to` triggers the dialog on each interactive client. The dialog protects the developer's machine from a compromised or hostile gateway, not the organization from the developer.

1004 1002 

Details

264* **The full walkthrough, including PR creation**: see [Review and iterate](https://code.claude.com/docs/en/web-quickstart.md#review-and-iterate)264* **The full walkthrough, including PR creation**: see [Review and iterate](https://code.claude.com/docs/en/web-quickstart.md#review-and-iterate)

265* **Having Claude monitor the PR for CI failures and review comments automatically**: see [Auto-fix pull requests](#auto-fix-pull-requests)265* **Having Claude monitor the PR for CI failures and review comments automatically**: see [Auto-fix pull requests](#auto-fix-pull-requests)

266 266 

267#### Troubleshoot a missing file in the diff view

268 

269A file you expected can be missing from the diff view's file list when it compares against the base branch, whether or not the session has pushed changes:

270 

271* **No changes pushed yet**: the list has Claude's own edits, but not changes made by commands Claude ran, such as a formatter

272* **Changes pushed**: the list has pushed commits, but not changes made after the last push

273 

274To add a missing change to the list, ask Claude to commit and push.

275 

267### Manage context276### Manage context

268 277 

269Cloud sessions support [built-in commands](https://code.claude.com/docs/en/commands.md) that produce text output. Commands that only run in the terminal interface, such as `/plugin` or `/resume`, aren't available. Commands that open a picker or panel in the terminal behave differently in cloud sessions:278Cloud sessions support [built-in commands](https://code.claude.com/docs/en/commands.md) that produce text output. Commands that only run in the terminal interface, such as `/plugin` or `/resume`, aren't available. Commands that open a picker or panel in the terminal behave differently in cloud sessions:

270 279 

271* **`/model`, `/effort`, `/color`, and `/rename`**: pass the value as an argument, for example `/model sonnet`, instead of opening the terminal picker or slider. The argument forms follow each command's [availability notes](https://code.claude.com/docs/en/commands.md#all-commands).280* **`/model`, `/effort`, `/color`, and `/rename`**: pass the value as an argument, for example `/model sonnet`, instead of opening the terminal picker or slider. The argument forms follow each command's [availability notes](https://code.claude.com/docs/en/commands.md#all-commands).

272* **`/fast`**: toggles [fast mode](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-in-cloud-sessions) for the session when fast mode is [available on your account](https://code.claude.com/docs/en/fast-mode.md#requirements). Requires Claude Code v2.1.271 or later in the session's environment.281* **`/fast`**: toggles [fast mode](https://code.claude.com/docs/en/fast-mode.md#use-fast-mode-in-cloud-sessions) for the session when fast mode is [available on your account](https://code.claude.com/docs/en/fast-mode.md#requirements). Requires Claude Code v2.1.271 or later in the session's environment.

273* **`/config`**: in your browser at claude.ai/code, opens the Claude Code section of your settings instead of setting a value. To change a setting for a cloud session, set an [environment variable](https://code.claude.com/docs/en/cloud-environments.md#set-environment-variables) on the environment. In a session with one repository outside a [project](https://code.claude.com/docs/en/claude-projects.md)'s threads, commit the key to that repository's `.claude/settings.json` instead. [Settings in cloud sessions](https://code.claude.com/docs/en/settings.md#settings-in-cloud-sessions) lists what each session reads.282* **`/config`**: in your browser at claude.ai/code, opens **Settings > Code** or **Settings > Claude Code** instead of setting a value. To change a setting for a cloud session, set an [environment variable](https://code.claude.com/docs/en/cloud-environments.md#set-environment-variables) on the environment. In a session with one repository outside a [project](https://code.claude.com/docs/en/claude-projects.md)'s threads, commit the key to that repository's `.claude/settings.json` instead. [Settings in cloud sessions](https://code.claude.com/docs/en/settings.md#settings-in-cloud-sessions) lists what each session reads.

274 283 

275For context management in a cloud session outside a [project's threads](https://code.claude.com/docs/en/claude-projects.md#choose-models-and-let-claude-manage-context):284For context management in a cloud session outside a [project's threads](https://code.claude.com/docs/en/claude-projects.md#choose-models-and-let-claude-manage-context):

276 285 


337* **Repository access**: verification isn't enabled by default346* **Repository access**: verification isn't enabled by default

338* **Sensitive content**: check your session before sharing. Sessions may contain code and credentials from private GitHub repositories347* **Sensitive content**: check your session before sharing. Sessions may contain code and credentials from private GitHub repositories

339 348 

340To require recipients to have repository access, or to hide your name from shared sessions, go to [**Settings > Claude Code > Sharing settings**](https://claude.ai/settings/claude-code).349To require recipients to have repository access, or to hide your name from shared sessions, open Settings on claude.ai, then:

350 

351* **If the Settings menu shows Code instead of Claude Code**: go to [**Privacy**](https://claude.ai/settings/data-privacy-controls), which has these settings

352* **Otherwise**: go to [**Claude Code > Sharing settings**](https://claude.ai/settings/claude-code)

341 353 

342### Archive sessions354### Archive sessions

343 355 

Details

95 95 

96Claude Platform on AWS uses the same model IDs as the direct Claude API.96Claude Platform on AWS uses the same model IDs as the direct Claude API.

97 97 

98The default aliases `fable`, `opus`, `sonnet`, and `haiku` resolve to Claude Code's built-in defaults for Claude Platform on AWS, which can lag the newest release. Without `ANTHROPIC_DEFAULT_OPUS_MODEL`, the `opus` alias resolves to Opus 5.5. Before v2.1.280, it resolved to Opus 5 from v2.1.219, and to Opus 4.8 from v2.1.207.98The default aliases `fable`, `opus`, `sonnet`, and `haiku` resolve to Claude Code's built-in defaults for Claude Platform on AWS, which can lag the newest release. Without `ANTHROPIC_DEFAULT_OPUS_MODEL`, the `opus` alias resolves to Opus 5.5. Before v2.1.280, it resolved to Opus 5 from v2.1.219.

99 99 

100If you deploy Claude Code to a team, pin the model IDs explicitly so a new release doesn't move everyone at once:100If you deploy Claude Code to a team, pin the model IDs explicitly so a new release doesn't move everyone at once:

101 101 

Details

70You create and use projects at [claude.ai/code](https://claude.ai/code), in the Code tab of the desktop app, or in the Claude mobile app for [iOS](https://apps.apple.com/us/app/claude-by-anthropic/id6473753684) and [Android](https://play.google.com/store/apps/details?id=com.anthropic.claude). In the browser and the desktop app there are two ways to start a project:70You create and use projects at [claude.ai/code](https://claude.ai/code), in the Code tab of the desktop app, or in the Claude mobile app for [iOS](https://apps.apple.com/us/app/claude-by-anthropic/id6473753684) and [Android](https://play.google.com/store/apps/details?id=com.anthropic.claude). In the browser and the desktop app there are two ways to start a project:

71 71 

72* **From scratch**, when you know the stream of work you want Claude to run: open the **New project** dialog and name it. [Start a new project from scratch](#start-a-new-project-from-scratch) walks through the dialog.72* **From scratch**, when you know the stream of work you want Claude to run: open the **New project** dialog and name it. [Start a new project from scratch](#start-a-new-project-from-scratch) walks through the dialog.

73* **From a cloud session that's already doing the work**: in that session's sidebar menu, choose **Move to project**, then **Continue as new project**. Claude proposes the project's setup from what the session was doing. See [Start from an existing cloud session](#start-from-an-existing-cloud-session).73* **From a cloud session that's already doing the work**: in that session's sidebar menu, choose **Continue in project**, then **Continue as new project**. Claude proposes the project's setup from what the session was doing. See [Start from an existing cloud session](#start-from-an-existing-cloud-session).

74 74 

75Either way, [check the prerequisites](#check-the-prerequisites) first.75Either way, [check the prerequisites](#check-the-prerequisites) first.

76 76 


113 113 

114### Start from an existing session114### Start from an existing session

115 115 

116If a cloud session you started yourself is doing work that belongs in a project, open its sidebar menu and choose **Move to project**, then pick from the submenu:116If a cloud session you started yourself is doing work that belongs in a project, open its sidebar menu and choose **Continue in project**, then pick from the submenu:

117 117 

118* Choose **Continue as new project** to create a new project from the session. The project opens, and Claude reads the session and posts **Setup recommendations** in the project conversation for you to confirm. The original session stays in your session list. If it was in the middle of a turn it keeps running, so stop it yourself if you don't want both working at once.118* Choose **Continue as new project** to create a new project from the session. The project opens, and Claude reads the session and posts **Setup recommendations** in the project conversation for you to confirm. The original session stays in your session list. If it was in the middle of a turn it keeps running, so stop it yourself if you don't want both working at once.

119* Choose one of your existing projects to bring the session's work into that project. That project opens, and a message sent on your behalf asks Claude to read the session and pick up where it left off. The original session stays in your session list, unchanged.119* Choose one of your existing projects to bring the session's work into that project. That project opens, and a message sent on your behalf asks Claude to read the session and pick up where it left off. The original session stays in your session list, unchanged.


262 262 

263On the computer that has the folder the task needs, make it available through Remote Control in one of two ways. Both need Claude Code v2.1.280 or later on that computer.263On the computer that has the folder the task needs, make it available through Remote Control in one of two ways. Both need Claude Code v2.1.280 or later on that computer.

264 264 

265* **In the Claude desktop app**: open **Settings > Claude Code**, turn on **Use this computer from your phone and claude.ai**, and add the folder to the list under that switch. Threads can run on this computer while the app is open.265* **In the Claude desktop app**: open **Settings > Code** or **Settings > Claude Code** and turn on **Use this computer from your phone and claude.ai**. Add the folder to the list under that switch. Threads can run on this computer while the app is open.

266* **In a terminal**: run `claude remote-control` in the folder and leave it running. In a git repository, add `--spawn worktree` to give each thread there its own [worktree](https://code.claude.com/docs/en/worktrees.md) instead of the folder itself.266* **In a terminal**: run `claude remote-control` in the folder and leave it running. In a git repository, add `--spawn worktree` to give each thread there its own [worktree](https://code.claude.com/docs/en/worktrees.md) instead of the folder itself.

267 267 

268**2. Ask for the task with Work locally**268**2. Ask for the task with Work locally**


275 275 

276The thread runs in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), so Claude runs commands and edits files in that folder without asking you each time. If auto mode is unavailable or turned off in that computer's Claude Code, the thread runs without it, and any permission prompt it raises waits for your answer in the thread, as [Unblock a thread waiting on approval](#unblock-a-thread-waiting-on-approval) describes.276The thread runs in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode), so Claude runs commands and edits files in that folder without asking you each time. If auto mode is unavailable or turned off in that computer's Claude Code, the thread runs without it, and any permission prompt it raises waits for your answer in the thread, as [Unblock a thread waiting on approval](#unblock-a-thread-waiting-on-approval) describes.

277 277 

278While the thread runs, a laptop icon in its header shows whether your computer is connected. Click it to see which folder the thread is using or to turn the connection off. The thread pauses while that computer is asleep, and stops if the desktop app or `claude remote-control` quits. [Lost contact with your folder](#lost-contact-with-your-folder) covers getting it going again. In the desktop app, turn on **Keep this computer awake for Remote Control** under **Settings > Claude Code** to stop the computer from sleeping on its own.278While the thread runs, a laptop icon in its header shows whether your computer is connected. Click it to see which folder the thread is using or to turn the connection off. The thread pauses while that computer is asleep, and stops if the desktop app or `claude remote-control` quits.

279 

280* **To get the thread going again**: see [Lost contact with your folder](#lost-contact-with-your-folder)

281* **To keep the computer from sleeping on its own**: in the desktop app, turn on **Keep this computer awake for Remote Control** in **Settings > Code** or **Settings > Claude Code**

279 282 

280A project can't run a thread on your computer while [**Require trusted devices**](https://code.claude.com/docs/en/remote-control.md#trusted-devices) is on for your account.283A project can't run a thread on your computer while [**Require trusted devices**](https://code.claude.com/docs/en/remote-control.md#trusted-devices) is on for your account.

281 284 


427Several Claude Code features let more than one session work at the same time, so running work in parallel is not by itself what a project is for. In a project, Claude starts and tracks the sessions instead of you, and each one starts from the same instructions. This is how each neighboring feature connects to a project:430Several Claude Code features let more than one session work at the same time, so running work in parallel is not by itself what a project is for. In a project, Claude starts and tracks the sessions instead of you, and each one starts from the same instructions. This is how each neighboring feature connects to a project:

428 431 

429* **Claude Tag**: [Claude Tag](https://claude.com/docs/claude-tag/overview) is Claude in your team's Slack channels, on Team and Enterprise plans. Anyone in a channel can give it work, everyone in the channel sees and steers it, and it uses connections an admin set up for that channel. A project is yours alone: you're the only one who sends it work or sees its threads, it uses your own GitHub access and connectors, and it's on Pro and Max. [How Claude Tag differs from Cowork and Claude Code](https://claude.com/docs/claude-tag/concepts/how-it-works#how-claude-tag-differs-from-cowork-and-claude-code) has the side-by-side.432* **Claude Tag**: [Claude Tag](https://claude.com/docs/claude-tag/overview) is Claude in your team's Slack channels, on Team and Enterprise plans. Anyone in a channel can give it work, everyone in the channel sees and steers it, and it uses connections an admin set up for that channel. A project is yours alone: you're the only one who sends it work or sees its threads, it uses your own GitHub access and connectors, and it's on Pro and Max. [How Claude Tag differs from Cowork and Claude Code](https://claude.com/docs/claude-tag/concepts/how-it-works#how-claude-tag-differs-from-cowork-and-claude-code) has the side-by-side.

430* **Cloud sessions**: every thread is a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md) unless you ask Claude to run it on your machine. Either way, Claude starts and tracks it instead of you. You can also bring the work of a cloud session you started yourself into a project: choose [**Move to project**](#start-from-an-existing-cloud-session) in that session's sidebar menu.433* **Cloud sessions**: every thread is a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md) unless you ask Claude to run it on your machine. Either way, Claude starts and tracks it instead of you. You can also bring the work of a cloud session you started yourself into a project: choose [**Continue in project**](#start-from-an-existing-cloud-session) in that session's sidebar menu.

431* **Scheduled tasks**: when you ask for scheduled work in a project, Claude creates a [cloud scheduled task](https://code.claude.com/docs/en/routines.md) that runs as threads in that project and appears on its **Scheduled tasks** tab. Scheduled tasks you create outside a project keep working on their own.434* **Scheduled tasks**: when you ask for scheduled work in a project, Claude creates a [cloud scheduled task](https://code.claude.com/docs/en/routines.md) that runs as threads in that project and appears on its **Scheduled tasks** tab. Scheduled tasks you create outside a project keep working on their own.

432* **Remote Control**: [Remote Control](https://code.claude.com/docs/en/remote-control.md) connects claude.ai to a Claude Code session running on your machine. When you ask Claude in a project to run a thread on your computer, the project [uses Remote Control to do it](#run-a-thread-on-your-own-computer).435* **Remote Control**: [Remote Control](https://code.claude.com/docs/en/remote-control.md) connects claude.ai to a Claude Code session running on your machine. When you ask Claude in a project to run a thread on your computer, the project [uses Remote Control to do it](#run-a-thread-on-your-own-computer).

433* **Local sessions and agent view**: a session you start yourself in your terminal, IDE, or the desktop app's local environment stays outside your projects, though you can [bring its work into one](#start-from-an-existing-cloud-session). [Agent view](https://code.claude.com/docs/en/agent-view.md) is a screen for tracking several local sessions side by side, and you still start each one and give it its task yourself.436* **Local sessions and agent view**: a session you start yourself in your terminal, IDE, or the desktop app's local environment stays outside your projects, though you can [bring its work into one](#start-from-an-existing-cloud-session). [Agent view](https://code.claude.com/docs/en/agent-view.md) is a screen for tracking several local sessions side by side, and you still start each one and give it its task yourself.


445* You can't add a session you started yourself on your machine to a project, though you can [bring its work into one](#start-from-an-existing-cloud-session). A project reaches your machine by [running a thread there through Remote Control](#run-a-thread-on-your-own-computer), and that section lists what it needs.448* You can't add a session you started yourself on your machine to a project, though you can [bring its work into one](#start-from-an-existing-cloud-session). A project reaches your machine by [running a thread there through Remote Control](#run-a-thread-on-your-own-computer), and that section lists what it needs.

446* A cloud thread's sandbox pauses between turns and resumes when the thread continues. If the sandbox can't be resumed, the thread continues from a fresh clone, so uncommitted changes can be lost. On long tasks, ask Claude to commit and push work in progress.449* A cloud thread's sandbox pauses between turns and resumes when the thread continues. If the sandbox can't be resumed, the thread continues from a fresh clone, so uncommitted changes can be lost. On long tasks, ask Claude to commit and push work in progress.

447* A project belongs to one user. You can't share a project or its threads with another user, and thread transcripts don't have the share option other cloud sessions have. There are no organization-level controls for projects during the beta.450* A project belongs to one user. You can't share a project or its threads with another user, and thread transcripts don't have the share option other cloud sessions have. There are no organization-level controls for projects during the beta.

448* A thread belongs to the one project that started it. You can't move or copy a thread to another project, or move it out to stand alone. [**Move to project**](#start-from-an-existing-cloud-session) goes the other way only: it brings a cloud session's work into a project. You can't merge two projects into one.451* A thread belongs to the one project that started it. You can't move or copy a thread to another project, or move it out to stand alone. [**Continue in project**](#start-from-an-existing-cloud-session) goes the other way only: it brings a cloud session's work into a project. You can't merge two projects into one.

449 452 

450## Troubleshooting453## Troubleshooting

451 454 


489 492 

490### Lost contact with your folder493### Lost contact with your folder

491 494 

492A thread running on your computer shows this when the Claude Code session there stopped responding, usually because the computer went to sleep or the desktop app or `claude remote-control` quit. Wake the computer, and if the desktop app or `claude remote-control` is no longer running there, start it again: reopen the app and confirm **Use this computer from your phone and claude.ai** is still on under **Settings > Claude Code**, or run `claude remote-control` again in the same folder.495A thread running on your computer shows this when the Claude Code session there stopped responding, usually because the computer went to sleep or the desktop app or `claude remote-control` quit. Wake the computer. If the desktop app or `claude remote-control` is no longer running there, start it again:

496 

497* **Desktop app**: reopen the app and confirm **Use this computer from your phone and claude.ai** is still on under **Settings > Code** or **Settings > Claude Code**

498* **Terminal**: run `claude remote-control` again in the same folder

493 499 

494### Other messages500### Other messages

495 501 

Details

71* In a terminal session, where `/code-review` runs the review as a [forked subagent](https://code.claude.com/docs/en/skills.md#run-skills-in-a-subagent)71* In a terminal session, where `/code-review` runs the review as a [forked subagent](https://code.claude.com/docs/en/skills.md#run-skills-in-a-subagent)

72* In a `-p` run with text or JSON output72* In a `-p` run with text or JSON output

73 73 

74In a host application that requests the findings list, such as the [desktop app](https://code.claude.com/docs/en/desktop.md#review-your-code), Claude reports the review's findings through the [`ReportFindings` tool](https://code.claude.com/docs/en/tools-reference) instead. The report appears as a findings list, and each entry shows the file location, a one-sentence summary, and a category tag such as `correctness` when the finding carries one. A host request applies at every effort level and requires Claude Code v2.1.218 or later.74In a host application that requests the findings list, such as the [desktop app](https://code.claude.com/docs/en/desktop.md#review-your-code), Claude reports the review's findings through the [`ReportFindings` tool](https://code.claude.com/docs/en/tools-reference) instead. The report appears as a findings list, and each entry shows the file location, a one-sentence summary, and a category tag such as `correctness` when the finding carries one. A host request applies at every effort level.

75 75 

76When Claude fixes reported findings later in the session, it reports them again. Claude Code then marks each finding in the updated findings list as fixed, skipped, or no change needed.76When Claude fixes reported findings later in the session, it reports them again. Claude Code then marks each finding in the updated findings list as fixed, skipped, or no change needed.

77 77 


104After the effort level and flags, Claude Code reads the rest of the line as the review target. The `ultra` argument changes that reading:104After the effort level and flags, Claude Code reads the rest of the line as the review target. The `ultra` argument changes that reading:

105 105 

106* **With `ultra`**: Claude Code reads a single word as a base branch or PR number. Longer text that doesn't name a branch or PR becomes [a note attached to the review](https://code.claude.com/docs/en/ultrareview.md#pass-a-request-in-plain-words). `/code-review ultra check my auth changes` reviews your current branch, and Claude relates the findings to your note.106* **With `ultra`**: Claude Code reads a single word as a base branch or PR number. Longer text that doesn't name a branch or PR becomes [a note attached to the review](https://code.claude.com/docs/en/ultrareview.md#pass-a-request-in-plain-words). `/code-review ultra check my auth changes` reviews your current branch, and Claude relates the findings to your note.

107* **Without `ultra`**: everything left is the review target, even when it starts with another command name. `/code-review /fix-issue 123` reviews with `/fix-issue 123` as target text instead of loading `/fix-issue` as a second [stacked skill](https://code.claude.com/docs/en/skills.md#stack-several-skills-in-one-message). Before v2.1.218, a command stacked after `/code-review` expanded as its own skill.107* **Without `ultra`**: everything left is the review target, even when it starts with another command name. `/code-review /fix-issue 123` reviews with `/fix-issue 123` as target text instead of loading `/fix-issue` as a second [stacked skill](https://code.claude.com/docs/en/skills.md#stack-several-skills-in-one-message).

108 108 

109## Run in the foreground109## Run in the foreground

110 110 


114* Set [`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS`](https://code.claude.com/docs/en/env-vars) to `1`, which also turns off other background task features114* Set [`CLAUDE_CODE_DISABLE_BACKGROUND_TASKS`](https://code.claude.com/docs/en/env-vars) to `1`, which also turns off other background task features

115* Run `/code-review` again while an earlier review is still in progress115* Run `/code-review` again while an earlier review is still in progress

116 116 

117Before v2.1.218, the review ran inside your conversation.

118 

119## Let Claude start the review117## Let Claude start the review

120 118 

121Claude can start `/code-review` on its own, without you typing the command:119Claude can start `/code-review` on its own, without you typing the command:

commands.md +3 −3

Details

37* **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills)**: a bundled skill. It works like skills you write yourself: a prompt handed to Claude.37* **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills)**: a bundled skill. It works like skills you write yourself: a prompt handed to Claude.

38 * `/verify` runs only when you invoke it. Before v2.1.215, Claude could also run `/verify` on its own.38 * `/verify` runs only when you invoke it. Before v2.1.215, Claude could also run `/verify` on its own.

39* **[Workflow](https://code.claude.com/docs/en/workflows.md#bundled-workflows)**: a bundled [dynamic workflow](https://code.claude.com/docs/en/workflows.md) that fans work out across many subagents and runs in the background.39* **[Workflow](https://code.claude.com/docs/en/workflows.md#bundled-workflows)**: a bundled [dynamic workflow](https://code.claude.com/docs/en/workflows.md) that fans work out across many subagents and runs in the background.

40 * `/deep-research` runs only when you invoke it. Before v2.1.218, Claude could also start it on its own.40 * `/deep-research` runs only when you invoke it.

41 41 

42To add your own commands, see [skills](https://code.claude.com/docs/en/skills.md).42To add your own commands, see [skills](https://code.claude.com/docs/en/skills.md).

43 43 


54| `/agents` | Print a reminder to ask Claude to create or manage [subagents](https://code.claude.com/docs/en/sub-agents.md), or to edit `.claude/agents/` or `~/.claude/agents/` directly. On v2.1.197 and earlier, opens an interactive interface for creating and managing subagent configurations |54| `/agents` | Print a reminder to ask Claude to create or manage [subagents](https://code.claude.com/docs/en/sub-agents.md), or to edit `.claude/agents/` or `~/.claude/agents/` directly. On v2.1.197 and earlier, opens an interactive interface for creating and managing subagent configurations |

55| `/artifact-capabilities` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Load the reference for the runtime capabilities a published [artifact](https://code.claude.com/docs/en/artifacts.md) can use, such as [calling your connectors](https://code.claude.com/docs/en/artifacts.md#pull-live-data-with-mcp-connectors) or [offering a file download](https://code.claude.com/docs/en/artifacts.md#offer-a-file-download), including which ones your account has. Claude normally loads it on its own before building a page that uses one. Available where [artifacts](https://code.claude.com/docs/en/artifacts.md#availability) are |55| `/artifact-capabilities` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Load the reference for the runtime capabilities a published [artifact](https://code.claude.com/docs/en/artifacts.md) can use, such as [calling your connectors](https://code.claude.com/docs/en/artifacts.md#pull-live-data-with-mcp-connectors) or [offering a file download](https://code.claude.com/docs/en/artifacts.md#offer-a-file-download), including which ones your account has. Claude normally loads it on its own before building a page that uses one. Available where [artifacts](https://code.claude.com/docs/en/artifacts.md#availability) are |

56| `/artifact-diagramming` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Load diagramming guidance for Claude to follow in [artifacts](https://code.claude.com/docs/en/artifacts.md): when a diagram helps, what to draw, and how to write inline SVG that stays legible in light and dark themes. Requires Claude Code v2.1.221 or later |56| `/artifact-diagramming` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Load diagramming guidance for Claude to follow in [artifacts](https://code.claude.com/docs/en/artifacts.md): when a diagram helps, what to draw, and how to write inline SVG that stays legible in light and dark themes. Requires Claude Code v2.1.221 or later |

57| `/artifacts` | List the [artifacts](https://code.claude.com/docs/en/artifacts.md#find-an-artifact-again) you own or that are shared with you, then attach one to the session, open it in your browser, or copy its link. Available where [artifacts](https://code.claude.com/docs/en/artifacts.md#availability) are. Requires Claude Code v2.1.208 or later; attaching with `Enter` requires v2.1.216 |57| `/artifacts` | List the [artifacts](https://code.claude.com/docs/en/artifacts.md#find-an-artifact-again) you own or that are shared with you, then attach one to the session, open it in your browser, or copy its link. Available where [artifacts](https://code.claude.com/docs/en/artifacts.md#availability) are |

58| `/auto-mode-setup` | [Draft `autoMode.environment` entries](https://code.claude.com/docs/en/auto-mode-config#generate-environment-entries) from your project and recent sessions, then review the draft and save it to your user settings. On a Pro, Max, or Team plan, requires Claude Code v2.1.228 or later, or v2.1.233 or later on native Windows. On an Enterprise plan or with a Claude Console API key, requires v2.1.283 or later. If the command is missing, see [`/auto-mode-setup` returns "Unknown command"](https://code.claude.com/docs/en/auto-mode-config#auto-mode-setup-returns-unknown-command) |58| `/auto-mode-setup` | [Draft `autoMode.environment` entries](https://code.claude.com/docs/en/auto-mode-config#generate-environment-entries) from your project and recent sessions, then review the draft and save it to your user settings. On a Pro, Max, or Team plan, requires Claude Code v2.1.228 or later, or v2.1.233 or later on native Windows. On an Enterprise plan or with a Claude Console API key, requires v2.1.283 or later. If the command is missing, see [`/auto-mode-setup` returns "Unknown command"](https://code.claude.com/docs/en/auto-mode-config#auto-mode-setup-returns-unknown-command) |

59| `/autocompact [auto\|<tokens>]` | Set the auto-compact window: how full the context window gets before Claude Code compacts automatically. Pass a size such as `500k`, or `auto` to return to the window tuned for your model. Claude Code saves the value to user settings and applies it to the current session. See [Set the auto-compact window](https://code.claude.com/docs/en/model-config.md#set-the-auto-compact-window) for accepted values and what overrides it. Without an argument, opens a dialog that shows the current window. Requires Claude Code v2.1.221 or later |59| `/autocompact [auto\|<tokens>]` | Set the auto-compact window: how full the context window gets before Claude Code compacts automatically. Pass a size such as `500k`, or `auto` to return to the window tuned for your model. Claude Code saves the value to user settings and applies it to the current session. See [Set the auto-compact window](https://code.claude.com/docs/en/model-config.md#set-the-auto-compact-window) for accepted values and what overrides it. Without an argument, opens a dialog that shows the current window. Requires Claude Code v2.1.221 or later |

60| `/autofix-pr [prompt]` | Spawn a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md#auto-fix-pull-requests) that watches the current branch's PR and pushes fixes when CI fails or reviewers leave comments. Detects the open PR from your checked-out branch with `gh pr view`; to watch a different PR, check out its branch first. By default the cloud session is told to fix every CI failure and review comment; pass a prompt to give it different instructions, for example `/autofix-pr only fix lint and type errors`. Requires the `gh` CLI and access to [cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md) |60| `/autofix-pr [prompt]` | Spawn a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md#auto-fix-pull-requests) that watches the current branch's PR and pushes fixes when CI fails or reviewers leave comments. Detects the open PR from your checked-out branch with `gh pr view`; to watch a different PR, check out its branch first. By default the cloud session is told to fix every CI failure and review comment; pass a prompt to give it different instructions, for example `/autofix-pr only fix lint and type errors`. Requires the `gh` CLI and access to [cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md) |


85| `/desktop` | Continue the current session in the Claude Code Desktop app. Requires macOS or x64 Windows and a Claude subscription. Alias: `/app` |85| `/desktop` | Continue the current session in the Claude Code Desktop app. Requires macOS or x64 Windows and a Claude subscription. Alias: `/app` |

86| `/diff` | Review the changes in your working tree, including the edits Claude has made so far. See [Review changes with /diff](https://code.claude.com/docs/en/interactive-mode.md#review-changes-with-%2Fdiff) |86| `/diff` | Review the changes in your working tree, including the edits Claude has made so far. See [Review changes with /diff](https://code.claude.com/docs/en/interactive-mode.md#review-changes-with-%2Fdiff) |

87| `/doctor [prompt-audit [path]]` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Run a setup checkup that diagnoses installation, settings, extension, and `CLAUDE.md` problems and proposes fixes that Claude applies after you confirm. For what the checkup covers, or to audit your instructions with `prompt-audit` instead, see [Check your setup with `/doctor`](https://code.claude.com/docs/en/skills#check-your-setup-with-/doctor). The `prompt-audit` subcommand requires Claude Code v2.1.283 or later. Alias: `/checkup` |87| `/doctor [prompt-audit [path]]` | **[Skill](https://code.claude.com/docs/en/skills.md#bundled-skills).** Run a setup checkup that diagnoses installation, settings, extension, and `CLAUDE.md` problems and proposes fixes that Claude applies after you confirm. For what the checkup covers, or to audit your instructions with `prompt-audit` instead, see [Check your setup with `/doctor`](https://code.claude.com/docs/en/skills#check-your-setup-with-/doctor). The `prompt-audit` subcommand requires Claude Code v2.1.283 or later. Alias: `/checkup` |

88| `/effort [level\|auto\|status\|ultracode [on\|off]]` | Set the [effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level): `low` to `xhigh`, `max`, or `auto`; `status` prints it. `ultracode` or `ultracode on` turns [ultracode](https://code.claude.com/docs/en/workflows.md#let-claude-decide-with-ultracode) on for the session at the current level, and `ultracode off` turns it off; the [`ultracode`](https://code.claude.com/docs/en/settings-reference#ultracode) key persists. `max` is session-only. The `on` and `off` arguments and keeping the current level require Claude Code v2.1.284 or later. Before v2.1.284, `/effort ultracode` set the session to `xhigh`, and `/effort ultracode off` failed with `Invalid argument`. Run it while Claude is responding and, once you confirm the [cache warning](https://code.claude.com/docs/en/prompt-caching.md#changing-effort-level), if Claude Code shows one, Claude Code applies the new level to the next request in that turn. Before v2.1.242, Claude Code decided from a feature flag it fetched from Anthropic whether to run the command mid-turn or queue it until the turn finished, and always queued it in a session that doesn't [fetch feature flags](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching), such as on a [third-party provider](https://code.claude.com/docs/en/third-party-integrations.md). Works in `-p` |88| `/effort [level\|auto\|status\|ultracode [on\|off]]` | Set the [effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level): `low` to `xhigh`, `max`, or `auto`; `status` prints it. `ultracode` or `ultracode on` turns [ultracode](https://code.claude.com/docs/en/workflows.md#let-claude-decide-with-ultracode) on for the session, and `ultracode off` turns it off; the [`ultracode`](https://code.claude.com/docs/en/settings-reference#ultracode) key persists. `max` is session-only. The `on` and `off` arguments require Claude Code v2.1.284 or later. If you run `/effort` while Claude is working, see [when the new level starts](https://code.claude.com/docs/en/model-config.md#when-a-new-effort-level-starts). Works in `-p` on v2.1.205 or later |

89| `/exit` | Exit the CLI. In an attached [background session](https://code.claude.com/docs/en/agent-view.md#attach-to-a-session), this detaches and the session keeps running. Alias: `/quit` |89| `/exit` | Exit the CLI. In an attached [background session](https://code.claude.com/docs/en/agent-view.md#attach-to-a-session), this detaches and the session keeps running. Alias: `/quit` |

90| `/export [filename]` | Export the current conversation as plain text. With a filename, writes directly to that file. Without, opens a dialog to copy to clipboard or save to a file |90| `/export [filename]` | Export the current conversation as plain text. With a filename, writes directly to that file. Without, opens a dialog to copy to clipboard or save to a file |

91| `/fast [on\|off]` | Toggle [fast mode](https://code.claude.com/docs/en/fast-mode.md) on or off. Run it while Claude is responding and Claude Code toggles fast mode without waiting for the turn to end, though the running turn finishes at its original speed. Before v2.1.242, Claude Code decided from a feature flag it fetched from Anthropic whether to run the command mid-turn or queue it until the turn finished, and always queued it in a session that doesn't [fetch feature flags](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching). Availability in non-interactive mode with `-p` is limited; see [Toggle fast mode](https://code.claude.com/docs/en/fast-mode.md#toggle-fast-mode) |91| `/fast [on\|off]` | Toggle [fast mode](https://code.claude.com/docs/en/fast-mode.md) on or off. Run it while Claude is responding and Claude Code toggles fast mode without waiting for the turn to end, though the running turn finishes at its original speed. Before v2.1.242, Claude Code decided from a feature flag it fetched from Anthropic whether to run the command mid-turn or queue it until the turn finished, and always queued it in a session that doesn't [fetch feature flags](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching). Availability in non-interactive mode with `-p` is limited; see [Toggle fast mode](https://code.claude.com/docs/en/fast-mode.md#toggle-fast-mode) |

computer-use.md +1 −1

Details

178| Feature | Desktop | CLI |178| Feature | Desktop | CLI |

179| :- | :- | :- |179| :- | :- | :- |

180| Platforms | macOS and Windows | macOS only |180| Platforms | macOS and Windows | macOS only |

181| Enable | Toggle in **Settings > This computer > System** | Enable `computer-use` in `/mcp` |181| Enable | Toggle in [Settings](https://code.claude.com/docs/en/desktop.md#enable-computer-use) | Enable `computer-use` in `/mcp` |

182| Denied apps list | Configurable in Settings | Not yet available |182| Denied apps list | Configurable in Settings | Not yet available |

183| Auto-unhide toggle | Optional | Always on |183| Auto-unhide toggle | Optional | Always on |

184| Dispatch integration | Dispatch-spawned sessions can use computer use | Not applicable |184| Dispatch integration | Dispatch-spawned sessions can use computer use | Not applicable |

Details

70* [Extend Claude Code](https://code.claude.com/docs/en/features-overview.md): when to use CLAUDE.md vs skills vs rules vs hooks vs MCP70* [Extend Claude Code](https://code.claude.com/docs/en/features-overview.md): when to use CLAUDE.md vs skills vs rules vs hooks vs MCP

71* [Store instructions and memories](https://code.claude.com/docs/en/memory.md): CLAUDE.md hierarchy and auto memory71* [Store instructions and memories](https://code.claude.com/docs/en/memory.md): CLAUDE.md hierarchy and auto memory

72* [Subagents](https://code.claude.com/docs/en/sub-agents.md): delegate research to a separate context window72* [Subagents](https://code.claude.com/docs/en/sub-agents.md): delegate research to a separate context window

73* [Best practices](https://code.claude.com/docs/en/best-practices.md): managing context as your primary constraint73* [Best practices](https://code.claude.com/docs/en/best-practices.md#keep-cost-and-context-down): keep sessions focused and costs down

74* [Prompt caching](https://code.claude.com/docs/en/prompt-caching.md): which actions invalidate the cached prefix74* [Prompt caching](https://code.claude.com/docs/en/prompt-caching.md): which actions invalidate the cached prefix

75* [Reduce token usage](https://code.claude.com/docs/en/costs.md#reduce-token-usage): strategies for keeping context usage low75* [Reduce token usage](https://code.claude.com/docs/en/costs.md#reduce-token-usage): strategies for keeping context usage low

Details

174Any of these shows you the full text:174Any of these shows you the full text:

175 175 

176* Press `Ctrl+O` to open the [transcript viewer](https://code.claude.com/docs/en/interactive-mode.md#transcript-viewer) and read the full text under the sender's session name.176* Press `Ctrl+O` to open the [transcript viewer](https://code.claude.com/docs/en/interactive-mode.md#transcript-viewer) and read the full text under the sender's session name.

177 

178 If Claude is busy and hasn't received the message yet, scroll to the end of the transcript, where the message is listed under `Waiting to be delivered`. Requires Claude Code v2.1.309 or later.

179 

177* In [fullscreen rendering](https://code.claude.com/docs/en/fullscreen.md#use-the-mouse), click a preview line that leaves part of the message out to expand it in place.180* In [fullscreen rendering](https://code.claude.com/docs/en/fullscreen.md#use-the-mouse), click a preview line that leaves part of the message out to expand it in place.

181 

178* In a session started with [`--verbose`](https://code.claude.com/docs/en/cli-reference#cli-flags), Claude Code shows the full text instead of the preview.182* In a session started with [`--verbose`](https://code.claude.com/docs/en/cli-reference#cli-flags), Claude Code shows the full text instead of the preview.

179 183 

180The preview shortens only what you see. Whether or not you expand it, Claude reads the full message.184The preview shortens only what you see. Whether or not you expand it, Claude reads the full message.

desktop.md +31 −22

Details

69* **Use the suggestion**: press **Tab** or **Right arrow** to place it in the prompt box, edit it if you want, then press **Enter** to send it. Pressing **Enter** before you accept the suggestion doesn't send it.69* **Use the suggestion**: press **Tab** or **Right arrow** to place it in the prompt box, edit it if you want, then press **Enter** to send it. Pressing **Enter** before you accept the suggestion doesn't send it.

70* **Write your own prompt**: start typing. The suggestion shows only while the prompt box is empty and has no attached files.70* **Write your own prompt**: start typing. The suggestion shows only while the prompt box is empty and has no attached files.

71 71 

72Go to **Settings > Claude Code** and turn off **Prompt suggestions** under **Sessions** to stop suggestions in each session from the next time it starts or resumes.72Turn off **Prompt suggestions** in **Settings > Code** or **Settings > Claude Code** to stop suggestions. Each session stops showing them the next time it starts or resumes.

73 73 

74### Add files and context to prompts74### Add files and context to prompts

75 75 


92| **Accept edits** | `acceptEdits` | Claude auto-accepts file edits and common filesystem commands like `mkdir`, `touch`, and `mv`, but still asks before running other terminal commands. Use this when you trust file changes and want faster iteration. |92| **Accept edits** | `acceptEdits` | Claude auto-accepts file edits and common filesystem commands like `mkdir`, `touch`, and `mv`, but still asks before running other terminal commands. Use this when you trust file changes and want faster iteration. |

93| **Plan** | `plan` | Claude reads files and runs commands to explore, then proposes a plan without editing your source code. Good for complex tasks where you want to review the approach first. |93| **Plan** | `plan` | Claude reads files and runs commands to explore, then proposes a plan without editing your source code. Good for complex tasks where you want to review the approach first. |

94| **Auto** | `auto` | Claude runs without routine prompts; before actions such as shell commands and network requests run, a background classifier checks that they align with your request. Appears when [auto mode is available](#auto-mode-availability); there is no separate Settings toggle for it. |94| **Auto** | `auto` | Claude runs without routine prompts; before actions such as shell commands and network requests run, a background classifier checks that they align with your request. Appears when [auto mode is available](#auto-mode-availability); there is no separate Settings toggle for it. |

95| **Bypass permissions** | `bypassPermissions` | Claude runs without permission prompts, except for the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves), safety classifiers when Claude [acts on external sites](#browse-external-sites), or desktop actions such as deleting a session, though not [archiving one](#work-across-sessions). Equivalent to `--dangerously-skip-permissions` in the CLI. On Pro and Max plans, enable it in your Settings → Claude Code under "Allow bypass permissions mode"; on Team and Enterprise plans there is no Settings toggle, and organization policy controls it instead. Only use this in sandboxed containers or VMs. |95| **Bypass permissions** | `bypassPermissions` | Claude runs without permission prompts, except for the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves), safety classifiers when Claude [acts on external sites](#browse-external-sites), or desktop actions such as deleting a session, though not [archiving one](#work-across-sessions). Equivalent to `--dangerously-skip-permissions` in the CLI. On Pro and Max plans, enable "Allow bypass permissions mode" in **Settings > Code** or **Settings > Claude Code**. On Team and Enterprise plans there is no Settings toggle, and organization policy controls it instead. Only use this in sandboxed containers or VMs. |

96 96 

97Earlier versions of the Code tab labeled these modes Ask permissions, Auto accept edits, and Plan mode.97Earlier versions of the Code tab labeled these modes Ask permissions, Auto accept edits, and Plan mode.

98 98 


100 100 

101> [!TIP]101> [!TIP]

102>102>

103> Start complex tasks in Plan so Claude maps out an approach before making changes. Once you approve the plan, switch to Accept edits or Manual to execute it. See [explore first, then plan, then code](https://code.claude.com/docs/en/best-practices.md#explore-first-then-plan-then-code) for more on this workflow.103> Start complex tasks in Plan so Claude maps out an approach before making changes. Once you approve the plan, switch to Accept edits or Manual to execute it. See [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) for more on this workflow.

104 104 

105Cloud sessions support Accept edits, Plan, and Auto. Accept edits corresponds to `default` mode: cloud sessions pre-approve file edits, so the selector shows Accept edits instead of Manual. Bypass permissions isn't available in cloud sessions, including sessions in a [self-hosted environment](https://code.claude.com/docs/en/self-hosted-environments).105Cloud sessions support Accept edits, Plan, and Auto. Accept edits corresponds to `default` mode: cloud sessions pre-approve file edits, so the selector shows Accept edits instead of Manual. Bypass permissions isn't available in cloud sessions, including sessions in a [self-hosted environment](https://code.claude.com/docs/en/self-hosted-environments).

106 106 


133 133 

134Claude creates the initial server configuration based on your project. If your app uses a custom dev command, edit `.claude/launch.json` to match your setup. See [Configure preview servers](#configure-preview-servers) for the full reference.134Claude creates the initial server configuration based on your project. If your app uses a custom dev command, edit `.claude/launch.json` to match your setup. See [Configure preview servers](#configure-preview-servers) for the full reference.

135 135 

136To clear the Browser's saved data, select **Clear browsing data** in the Browser pane's **⋮** menu. To turn the Browser off entirely, turn off **Browser tools** in **Settings > Claude Code**.136To clear the Browser's saved data, select **Clear browsing data** in the Browser pane's **⋮** menu. To turn the Browser off entirely, turn off **Browser tools** in **Settings > Code** or **Settings > Claude Code**.

137 137 

138### Browse external sites138### Browse external sites

139 139 


164 164 

165### Review changes with diff view165### Review changes with diff view

166 166 

167After Claude makes changes to your code, the diff view lets you review modifications file by file before creating a pull request. To open the diff view, click the line counts, such as `+12 -1`, in the **Changes** card of the [session details panel](#see-session-details). You can also click **Changes** in the session's title bar.167After Claude makes changes to your code, the diff view lets you review modifications file by file before creating a pull request. To open the diff view, click the line counts, such as `+12 -1`, in the **Changes** card of the [session details panel](#see-session-details). You can also click **Changes** in the session's title bar. A cloud session's diff against the base branch can [leave out changes that aren't pushed yet](https://code.claude.com/docs/en/claude-code-on-the-web.md#troubleshoot-a-missing-file-in-the-diff-view).

168 168 

169To comment on specific lines, click any line in the diff to open a comment box. Type your feedback and press **Enter** to add the comment. After adding comments to multiple lines, submit all comments at once:169To comment on specific lines, hover over a line and click the **+** that appears beside its line number to open a comment box. Type your feedback and press **Enter** to add the comment. After adding comments to multiple lines, submit all comments at once:

170 170 

171* **macOS**: press **Cmd+Enter**171* **macOS**: press **Cmd+Enter**

172* **Windows**: press **Ctrl+Enter**172* **Windows**: press **Ctrl+Enter**


194 * **If the repository doesn't allow auto-merge**: **Merge when ready** doesn't turn on, so enable auto-merge in your [GitHub repository settings](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-auto-merge-for-pull-requests-in-your-repository) first194 * **If the repository doesn't allow auto-merge**: **Merge when ready** doesn't turn on, so enable auto-merge in your [GitHub repository settings](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-auto-merge-for-pull-requests-in-your-repository) first

195* **[Earlier layout](#check-which-layout-you-have)**: once the session has a pull request, click **CI** on its status bar.195* **[Earlier layout](#check-which-layout-you-have)**: once the session has a pull request, click **CI** on its status bar.

196 196 

197To archive the session automatically once the PR merges or closes, turn on [auto-archive](#archive-a-session) in **Settings > Claude Code**.197To archive the session automatically once the PR merges or closes, turn on [auto-archive](#archive-a-session) in **Settings > Code** or **Settings > Claude Code**.

198 198 

199> [!NOTE]199> [!NOTE]

200>200>


275* **Cmd+Ctrl**: press **Ctrl+Alt**275* **Cmd+Ctrl**: press **Ctrl+Alt**

276* **Cmd**: press **Ctrl**276* **Cmd**: press **Ctrl**

277 277 

278Session cycling, the terminal toggle, and the view-mode toggle use **Ctrl** on every platform.278Shortcuts that start with `Ctrl` stay the same on every platform.

279 279 

280| Shortcut | Action |280| Shortcut | Action |

281| - | - |281| - | - |


284| `Cmd` `Option` `1`–`9` | On the new session screen in the [current layout](#check-which-layout-you-have), select an environment |284| `Cmd` `Option` `1`–`9` | On the new session screen in the [current layout](#check-which-layout-you-have), select an environment |

285| `Cmd` `Option` `0` | On the new session screen in the current layout, open the [**New environment** dialog](#create-a-saved-environment) |285| `Cmd` `Option` `0` | On the new session screen in the current layout, open the [**New environment** dialog](#create-a-saved-environment) |

286| `Cmd` `W` | Close session |286| `Cmd` `W` | Close session |

287| `Ctrl` `Tab` / `Ctrl` `Shift` `Tab` | Next or previous session |287| `Ctrl` `Tab` / `Ctrl` `Shift` `Tab` | Switch between sessions |

288| `Cmd` `Shift` `]` / `Cmd` `Shift` `[` | Next or previous session |288| `Cmd` `Shift` `]` / `Cmd` `Shift` `[` | Next or previous session |

289| `Esc` | Stop Claude's response |289| `Esc` | Stop Claude's response |

290| `Tab` / `Right arrow` | [Accept the suggested prompt](#accept-a-suggested-prompt) in an empty prompt box |290| `Tab` / `Right arrow` | [Accept the suggested prompt](#accept-a-suggested-prompt) in an empty prompt box |


352 352 

353**2. Turn on the toggle**353**2. Turn on the toggle**

354 354 

355In the desktop app, go to **Settings > This computer > System**. Under **Computer use**, turn on **Enable computer use**. On Windows, the toggle takes effect immediately and setup is complete. On macOS, continue to the next step.355In the desktop app, open **Settings**, then:

356 

357* **If the Settings menu lists This computer**: go to **This computer > System**

358* **Otherwise**: go to **Capabilities**

359 

360Under **Computer use**, turn on **Enable computer use**:

361 

362* **Windows**: the toggle takes effect immediately and setup is complete

363* **macOS**: continue to the next step

356 364 

357If you don't see the toggle, confirm you're on macOS or Windows with a Pro or Max plan, then update and restart the app.365If you don't see the toggle, confirm you're on macOS or Windows with a Pro or Max plan, then update and restart the app.

358 366 


379 387 

380Apps with broad reach, like terminals, Finder or File Explorer, and System Settings or Settings, show an extra warning in the prompt so you know what approving them grants.388Apps with broad reach, like terminals, Finder or File Explorer, and System Settings or Settings, show an extra warning in the prompt so you know what approving them grants.

381 389 

382The **Computer use** section in **Settings > This computer > System** includes these options:390In Settings, the **Computer use** section where you [turned computer use on](#enable-computer-use) includes these options:

383 391 

384* **Denied apps**: add apps here to reject them without prompting. Claude may still affect a denied app indirectly through actions in an allowed app, but it can't interact with the denied app directly.392* **Denied apps**: add apps here to reject them without prompting. Claude may still affect a denied app indirectly through actions in an allowed app, but it can't interact with the denied app directly.

385* **Unhide apps when Claude finishes**: when computer use isn't running in the background, Claude hides your other windows while it works so it interacts with only the approved app. When Claude finishes, hidden windows are restored unless you turn this setting off.393* **Unhide apps when Claude finishes**: when computer use isn't running in the background, Claude hides your other windows while it works so it interacts with only the approved app. When Claude finishes, hidden windows are restored unless you turn this setting off.


390 398 

391### Work in parallel with sessions399### Work in parallel with sessions

392 400 

393Click **+ New** in the sidebar, or press **Cmd+N** on macOS or **Ctrl+N** on Windows, to work on multiple tasks in parallel. Press **Ctrl+Tab** and **Ctrl+Shift+Tab** to cycle through sessions in the sidebar.401Click **+ New** in the sidebar, or press **Cmd+N** on macOS or **Ctrl+N** on Windows, to work on multiple tasks in parallel. Press **Ctrl+Tab** and **Ctrl+Shift+Tab** to switch between sessions.

394 402 

395You can also open a second session next to the current session or in a window of its own:403You can also open a second session next to the current session or in a window of its own:

396 404 


401 409 

402#### Run a session in its own worktree410#### Run a session in its own worktree

403 411 

404In a project that's a Git repository, turn on **Worktree** before you start a session to run it in its own [Git worktree](https://code.claude.com/docs/en/worktrees.md), an isolated copy of the project. By default, **Worktree** is off and Claude works in the project folder itself. Click the project folder control in the [row under the prompt box](#start-a-session) and turn on **Worktree**.412In a project that's a Git repository, turn on **Worktree** before you start a session to run it in its own [Git worktree](https://code.claude.com/docs/en/worktrees.md), an isolated copy of the project. By default, **Worktree** is off and Claude works in the project folder itself. On the [current layout](#check-which-layout-you-have), turn on the **Worktree** button in the [row under the prompt box](#start-a-session).

405 413 

406* **With a [saved environment](#create-a-saved-environment)**: set **Worktree** when you create or edit the environment414* **With a [third-party provider](https://code.claude.com/docs/en/third-party-integrations.md)**: if the row under the prompt box shows the project folder control but no **Worktree** button, click that control and turn on **Worktree**

415* **As the default for a [saved local or SSH environment](#create-a-saved-environment)**: set **Worktree** when you create or edit the environment

407* **[Earlier layout](#check-which-layout-you-have)**: select the **worktree** checkbox beside the branch name, above the prompt box416* **[Earlier layout](#check-which-layout-you-have)**: select the **worktree** checkbox beside the branch name, above the prompt box

408 417 

409Worktrees are stored in `<project-root>/.claude/worktrees/` by default. To store them in a custom directory instead:418Worktrees are stored in `<project-root>/.claude/worktrees/` by default. To store them in a custom directory instead:

410 419 

411* **Local sessions**: set **Worktree location** in **Settings > Claude Code**420* **Local sessions**: set **Worktree location** in **Settings > Code** or **Settings > Claude Code**

412* **SSH sessions**: set **Worktree folder** on the [SSH connection](#choose-where-ssh-session-worktrees-go)421* **SSH sessions**: set **Worktree folder** on the [SSH connection](#choose-where-ssh-session-worktrees-go)

413 422 

414You can also set a **Branch prefix** in **Settings > Claude Code**. Desktop prepends it to every worktree branch name, which is useful for keeping Claude-created branches organized.423You can also set a **Branch prefix** in **Settings > Code** or **Settings > Claude Code**. Desktop prepends it to every worktree branch name, which is useful for keeping Claude-created branches organized.

415 424 

416To include gitignored files like `.env` in new worktrees, create a [`.worktreeinclude` file](https://code.claude.com/docs/en/worktrees#copy-gitignored-files-into-worktrees) in your project root. See [What worktrees share with the main checkout](https://code.claude.com/docs/en/worktrees.md#what-worktrees-share-with-the-main-checkout) for where a worktree session reads project settings, hooks, and skills.425To include gitignored files like `.env` in new worktrees, create a [`.worktreeinclude` file](https://code.claude.com/docs/en/worktrees#copy-gitignored-files-into-worktrees) in your project root. See [What worktrees share with the main checkout](https://code.claude.com/docs/en/worktrees.md#what-worktrees-share-with-the-main-checkout) for where a worktree session reads project settings, hooks, and skills.

417 426 


430 439 

431Before you archive a session whose worktree has uncommitted changes, see [Keep uncommitted changes when a session is archived](#keep-uncommitted-changes-when-a-session-is-archived). To archive a session, hover over it in the sidebar, open its menu, and select **Archive**. The session moves to your [archived sessions](#organize-and-find-sessions).440Before you archive a session whose worktree has uncommitted changes, see [Keep uncommitted changes when a session is archived](#keep-uncommitted-changes-when-a-session-is-archived). To archive a session, hover over it in the sidebar, open its menu, and select **Archive**. The session moves to your [archived sessions](#organize-and-find-sessions).

432 441 

433To have sessions archive themselves when their pull request merges or closes, turn on **Auto-archive after PR merge or close** in **Settings > Claude Code**. Cloud sessions and sessions that are still running don't archive themselves.442To have sessions archive themselves when their pull request merges or closes, turn on **Auto-archive after PR merge or close** in **Settings > Code** or **Settings > Claude Code**. Cloud sessions and sessions that are still running don't archive themselves.

434 443 

435#### Keep uncommitted changes when a session is archived444#### Keep uncommitted changes when a session is archived

436 445 


527A local session connects when you turn Remote Control on for it, or when it connects automatically as it starts:536A local session connects when you turn Remote Control on for it, or when it connects automatically as it starts:

528 537 

529* **You turn it on for that session**: with the session's **Remote Control** switch, or by typing `/remote-control` in its prompt box.538* **You turn it on for that session**: with the session's **Remote Control** switch, or by typing `/remote-control` in its prompt box.

530* **It connects when it starts**: new sessions connect automatically while **Connect new sessions to Remote Control** is on in **Settings > Claude Code**. If you've never changed that setting, Desktop follows [`remoteControlAtStartup`](https://code.claude.com/docs/en/settings-reference#remotecontrolatstartup) in your user or managed settings, then your organization's default.539* **It connects when it starts**: new sessions connect automatically while **Connect new sessions to Remote Control** is on in **Settings > Code** or **Settings > Claude Code**. If you've never changed that setting, Desktop follows [`remoteControlAtStartup`](https://code.claude.com/docs/en/settings-reference#remotecontrolatstartup) in your user or managed settings, then your organization's default.

531 540 

532To see whether a session is connected, check the **Remote Control** switch in the **Environment** card of its [session details panel](#see-session-details).541To see whether a session is connected, check the **Remote Control** switch in the **Environment** card of its [session details panel](#see-session-details).

533 542 

534To keep sessions off your other devices, turn Remote Control off at the level you need:543To keep sessions off your other devices, turn Remote Control off at the level you need:

535 544 

536* **One session**: turn off its **Remote Control** switch. In a session that connected when it started, typing `/remote-control` leaves Remote Control on and shows `Remote Control is already on. This session connected automatically when it started.` Click **Turn off** on that line to disconnect.545* **One session**: turn off its **Remote Control** switch. In a session that connected when it started, typing `/remote-control` leaves Remote Control on and shows `Remote Control is already on. This session connected automatically when it started.` Click **Turn off** on that line to disconnect.

537* **New Desktop sessions on this computer**: turn off **Connect new sessions to Remote Control** in **Settings > Claude Code**. If it already shows off, turn it on and then off so Desktop saves your choice. Once saved, it takes precedence over `remoteControlAtStartup` and the defaults.546* **New Desktop sessions on this computer**: turn off **Connect new sessions to Remote Control** in **Settings > Code** or **Settings > Claude Code**. If it already shows off, turn it on and then off so Desktop saves your choice. Once saved, it takes precedence over `remoteControlAtStartup` and the defaults.

538* **Any session on this computer, including the CLI**: set [`disableRemoteControl`](https://code.claude.com/docs/en/settings-reference#disableremotecontrol) to `true` in `~/.claude/settings.json` to stop sessions from connecting. A session that was already connected when you saved the file stays connected until you turn Remote Control off for it.547* **Any session on this computer, including the CLI**: set [`disableRemoteControl`](https://code.claude.com/docs/en/settings-reference#disableremotecontrol) to `true` in `~/.claude/settings.json` to stop sessions from connecting. A session that was already connected when you saved the file stays connected until you turn Remote Control off for it.

539 548 

540To hide a session that already appears on your other devices, archive it in Desktop. Desktop archives the session's Remote Control copy too, so it leaves the default session list on those devices. To view or delete it there, see [Archive sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md#archive-sessions).549To hide a session that already appears on your other devices, archive it in Desktop. Desktop archives the session's Remote Control copy too, so it leaves the default session list on those devices. To view or delete it there, see [Archive sessions](https://code.claude.com/docs/en/claude-code-on-the-web.md#archive-sessions).


576> * **Connectors is grayed out in a WSL session**: see [If the terminal or connectors are unavailable](https://code.claude.com/docs/en/desktop-wsl.md#check-for-the-terminal-and-connectors)585> * **Connectors is grayed out in a WSL session**: see [If the terminal or connectors are unavailable](https://code.claude.com/docs/en/desktop-wsl.md#check-for-the-terminal-and-connectors)

577> * **Cloud sessions**: see [How connectors reach Claude Code](https://code.claude.com/docs/en/mcp.md#how-connectors-reach-claude-code)586> * **Cloud sessions**: see [How connectors reach Claude Code](https://code.claude.com/docs/en/mcp.md#how-connectors-reach-claude-code)

578 587 

579Once connected, Claude can read your calendar, send messages, create issues, and interact with your tools directly. You can ask Claude what connectors are configured in your session. To manage or disconnect connectors, go to **Settings > Connectors** in the desktop app.588Once connected, Claude can read your calendar, send messages, create issues, and interact with your tools directly. You can ask Claude what connectors are configured in your session. To manage or disconnect connectors, click **Customize** in the sidebar and open **Connectors**.

580 589 

581For integrations not listed in Connectors, add MCP servers manually via [settings files](https://code.claude.com/docs/en/mcp.md#installing-mcp-servers). You can also [create custom connectors](https://support.claude.com/en/articles/11175166-getting-started-with-custom-connectors-using-remote-mcp).590For integrations not listed in Connectors, add MCP servers manually via [settings files](https://code.claude.com/docs/en/mcp.md#installing-mcp-servers). You can also [create custom connectors](https://support.claude.com/en/articles/11175166-getting-started-with-custom-connectors-using-remote-mcp).

582 591 


2028| `--model sonnet` | Model picker in the row under the prompt box |2037| `--model sonnet` | Model picker in the row under the prompt box |

2029| `--resume`, `--continue` | Click a session in the sidebar, or type `/resume` in the prompt box to pick up a session you started from the CLI |2038| `--resume`, `--continue` | Click a session in the sidebar, or type `/resume` in the prompt box to pick up a session you started from the CLI |

2030| `--permission-mode` | Mode selector in the row under the prompt box |2039| `--permission-mode` | Mode selector in the row under the prompt box |

2031| `--dangerously-skip-permissions` | Bypass permissions mode. On Pro and Max plans, enable it in Settings → Claude Code → "Allow bypass permissions mode"; on Team and Enterprise plans, organization policy controls it |2040| `--dangerously-skip-permissions` | Bypass permissions mode. On Pro and Max plans, enable "Allow bypass permissions mode" in **Settings > Code** or **Settings > Claude Code**; on Team and Enterprise plans, organization policy controls it |

2032| `--add-dir` | [Add folders to a session](#add-folders-to-a-session) in local and SSH sessions, or select [several repositories](#run-long-running-tasks-in-the-cloud) in a cloud session |2041| `--add-dir` | [Add folders to a session](#add-folders-to-a-session) in local and SSH sessions, or select [several repositories](#run-long-running-tasks-in-the-cloud) in a cloud session |

2033| `--allowedTools`, `--disallowedTools` | No per-session equivalent. Permission rules in [settings files](https://code.claude.com/docs/en/settings.md) still apply. |2042| `--allowedTools`, `--disallowedTools` | No per-session equivalent. Permission rules in [settings files](https://code.claude.com/docs/en/settings.md) still apply. |

2034| `--verbose` | [Verbose view mode](#switch-view-modes) |2043| `--verbose` | [Verbose view mode](#switch-view-modes) |


2088* **Agent teams**: coordinated teams, where Claude as the team lead assigns tasks to teammates from a shared task list, are available in the [CLI](https://code.claude.com/docs/en/agent-teams.md), not in Desktop. For multi-agent work inside one session, use [dynamic workflows](https://code.claude.com/docs/en/workflows.md), which run in Desktop; Claude can also [message and manage your other sessions](#work-across-sessions) directly.2097* **Agent teams**: coordinated teams, where Claude as the team lead assigns tasks to teammates from a shared task list, are available in the [CLI](https://code.claude.com/docs/en/agent-teams.md), not in Desktop. For multi-agent work inside one session, use [dynamic workflows](https://code.claude.com/docs/en/workflows.md), which run in Desktop; Claude can also [message and manage your other sessions](#work-across-sessions) directly.

2089* **Terminal-dialog commands**: built-in commands that open an interactive panel in the terminal behave differently in the Code tab. Edit [settings files](https://code.claude.com/docs/en/settings.md) directly to manage permission rules and configuration, or run the commands from the standalone CLI.2098* **Terminal-dialog commands**: built-in commands that open an interactive panel in the terminal behave differently in the Code tab. Edit [settings files](https://code.claude.com/docs/en/settings.md) directly to manage permission rules and configuration, or run the commands from the standalone CLI.

2090 * Commands with no argument form, such as `/permissions`, reply with `isn't available in this environment`.2099 * Commands with no argument form, such as `/permissions`, reply with `isn't available in this environment`.

2091 * `/config` opens **Settings > Claude Code**.2100 * `/config` opens **Settings > Code** or **Settings > Claude Code**.

2092 2101 

2093## Troubleshooting2102## Troubleshooting

2094 2103 

Details

135 135 

136Local scheduled tasks run on your machine. Desktop checks the schedule every minute while the app is open and starts a fresh session when a task is due, independent of any manual sessions you have open. Each task gets a small delay of a few minutes after the scheduled time to stagger API traffic. The delay is deterministic: the same task always starts at the same offset.136Local scheduled tasks run on your machine. Desktop checks the schedule every minute while the app is open and starts a fresh session when a task is due, independent of any manual sessions you have open. Each task gets a small delay of a few minutes after the scheduled time to stagger API traffic. The delay is deterministic: the same task always starts at the same offset.

137 137 

138Tasks only run while the desktop app is running and your computer is awake. If your computer sleeps through a scheduled time, the run is skipped. To prevent idle-sleep, turn on **Keep computer awake** in **Settings > This computer > System**. Closing the laptop lid still puts it to sleep.138Tasks only run while the desktop app is running and your computer is awake. If your computer sleeps through a scheduled time, the run is skipped. To prevent idle-sleep, turn on **Keep computer awake** in **Settings > Desktop app** or **Settings > This computer > System**. Closing the laptop lid still puts it to sleep.

139 139 

140> [!NOTE]140> [!NOTE]

141>141>

env-vars.md +2 −0

Details

291| `CLAUDE_CODE_ENABLE_TASKS` | Selects which task-tracking tools Claude Code provides in [sessions that have them](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability). By default, Claude Code provides the Task tools `TaskCreate`, `TaskUpdate`, `TaskGet`, and `TaskList`. Set to `0` to get the legacy `TodoWrite` tool instead. See [Task list](https://code.claude.com/docs/en/interactive-mode.md#task-list) |291| `CLAUDE_CODE_ENABLE_TASKS` | Selects which task-tracking tools Claude Code provides in [sessions that have them](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability). By default, Claude Code provides the Task tools `TaskCreate`, `TaskUpdate`, `TaskGet`, and `TaskList`. Set to `0` to get the legacy `TodoWrite` tool instead. See [Task list](https://code.claude.com/docs/en/interactive-mode.md#task-list) |

292| `CLAUDE_CODE_ENABLE_TELEMETRY` | Set to `1` to enable OpenTelemetry data collection for metrics and logging. Required before configuring OTel exporters. Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](https://code.claude.com/docs/en/settings-reference.md#variables-claude-code-ignores-in-env). See [Monitoring](https://code.claude.com/docs/en/monitoring-usage.md) |292| `CLAUDE_CODE_ENABLE_TELEMETRY` | Set to `1` to enable OpenTelemetry data collection for metrics and logging. Required before configuring OTel exporters. Set it in your shell, user settings, or managed settings. Ignored in [project and local settings](https://code.claude.com/docs/en/settings-reference.md#variables-claude-code-ignores-in-env). See [Monitoring](https://code.claude.com/docs/en/monitoring-usage.md) |

293| `CLAUDE_CODE_ENABLE_TODO_TOOLS` | Set to `1` to get the task-tracking tools on every model. Without it, Claude Code provides them by default only on the models listed under [Task tool availability](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability). `CLAUDE_CODE_ENABLE_TASKS` still selects the Task tools or `TodoWrite`. Requires Claude Code v2.1.233 or later |293| `CLAUDE_CODE_ENABLE_TODO_TOOLS` | Set to `1` to get the task-tracking tools on every model. Without it, Claude Code provides them by default only on the models listed under [Task tool availability](https://code.claude.com/docs/en/tools-reference.md#task-tool-availability). `CLAUDE_CODE_ENABLE_TASKS` still selects the Task tools or `TodoWrite`. Requires Claude Code v2.1.233 or later |

294| `CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS` | Set to `1` to [run dangerous `rm` commands with no prompt](https://code.claude.com/docs/en/permission-modes#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode) in `bypassPermissions` mode, which removes a safety prompt for destructive deletes. The linked section lists where it has no effect. [Set it in the environment that launches Claude Code](#set-variables-in-your-shell), because Claude Code [ignores it in a settings `env` block](https://code.claude.com/docs/en/settings-reference#variables-claude-code-ignores-in-env). Requires Claude Code v2.1.311 or later |

294| `CLAUDE_CODE_EXIT_AFTER_STOP_DELAY` | Time in milliseconds to wait after the query loop becomes idle before automatically exiting. Useful for automated workflows and scripts using SDK mode |295| `CLAUDE_CODE_EXIT_AFTER_STOP_DELAY` | Time in milliseconds to wait after the query loop becomes idle before automatically exiting. Useful for automated workflows and scripts using SDK mode |

295| `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` | Set to `1` to enable [agent teams](https://code.claude.com/docs/en/agent-teams.md). Agent teams are experimental and disabled by default |296| `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` | Set to `1` to enable [agent teams](https://code.claude.com/docs/en/agent-teams.md). Agent teams are experimental and disabled by default |

296| `CLAUDE_CODE_EXTRA_BODY` | JSON object to merge into the top level of every API request body. Useful for passing provider-specific parameters that Claude Code doesn't expose directly. A value exported in your shell also applies to the [background sessions](https://code.claude.com/docs/en/agent-view.md) you dispatch with `claude agents` or `--bg`. Before v2.1.206, background sessions ignored a shell-exported value and used whatever copy the background supervisor process inherited |297| `CLAUDE_CODE_EXTRA_BODY` | JSON object to merge into the top level of every API request body. Useful for passing provider-specific parameters that Claude Code doesn't expose directly. A value exported in your shell also applies to the [background sessions](https://code.claude.com/docs/en/agent-view.md) you dispatch with `claude agents` or `--bg`. Before v2.1.206, background sessions ignored a shell-exported value and used whatever copy the background supervisor process inherited |


368| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` | Set to `1` to automatically resume if the previous session ended mid-turn. Used in SDK mode so the model continues without requiring the SDK to re-send the prompt. To turn this off, unset the variable or set it to `0`. For the VS Code chat panel, see [Continue conversations after a reload](https://code.claude.com/docs/en/vs-code.md#continue-conversations-after-a-reload) |369| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` | Set to `1` to automatically resume if the previous session ended mid-turn. Used in SDK mode so the model continues without requiring the SDK to re-send the prompt. To turn this off, unset the variable or set it to `0`. For the VS Code chat panel, see [Continue conversations after a reload](https://code.claude.com/docs/en/vs-code.md#continue-conversations-after-a-reload) |

369| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS` | Maximum age in milliseconds of the last transcript message for a session that ended mid-turn to continue automatically on resume. When the last message is older than this bound, Claude Code skips the `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` automatic resume and its `CLAUDE_CODE_RESUME_PROMPT` continuation message, and the session starts idle so you continue explicitly. Unset or `0` sets no bound, except that some turns resume only within six hours of their last message, such as one that ended with an API error. A positive value bounds every turn, including those; a negative or non-numeric value applies a one-hour bound. Spawn scripts for long-running agents can set this so a restart against an old transcript doesn't re-run a stale prompt. Claude Code sets a one-hour bound itself when it restarts a crashed [agent view](https://code.claude.com/docs/en/agent-view.md) session that inherited its conversation from an interactive session. Requires Claude Code v2.1.211 or later |370| `CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS` | Maximum age in milliseconds of the last transcript message for a session that ended mid-turn to continue automatically on resume. When the last message is older than this bound, Claude Code skips the `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` automatic resume and its `CLAUDE_CODE_RESUME_PROMPT` continuation message, and the session starts idle so you continue explicitly. Unset or `0` sets no bound, except that some turns resume only within six hours of their last message, such as one that ended with an API error. A positive value bounds every turn, including those; a negative or non-numeric value applies a one-hour bound. Spawn scripts for long-running agents can set this so a restart against an old transcript doesn't re-run a stale prompt. Claude Code sets a one-hour bound itself when it restarts a crashed [agent view](https://code.claude.com/docs/en/agent-view.md) session that inherited its conversation from an interactive session. Requires Claude Code v2.1.211 or later |

370| `CLAUDE_CODE_RESUME_PROMPT` | Override the continuation message Claude Code sends to Claude when `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` continues an interrupted turn instead of resending its prompt, or when you resume a [deferred tool call](https://code.claude.com/docs/en/hooks.md#defer-a-tool-call-for-later) with `-p`. Defaults to `Continue from where you left off.`. An empty string uses the default |371| `CLAUDE_CODE_RESUME_PROMPT` | Override the continuation message Claude Code sends to Claude when `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` continues an interrupted turn instead of resending its prompt, or when you resume a [deferred tool call](https://code.claude.com/docs/en/hooks.md#defer-a-tool-call-for-later) with `-p`. Defaults to `Continue from where you left off.`. An empty string uses the default |

372| `CLAUDE_CODE_RESUME_SHOWS_CUT_OFF_CALLS` | Set to `1` to keep [interrupted tool calls](https://code.claude.com/docs/en/sessions.md#what-a-resumed-session-restores), marked as cut off, in a turn that `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` continues. When unset, those calls are dropped before the turn continues. Some calls stay dropped, such as calls to subagents, skills, workflows, and tools that wait on a person. For the VS Code chat panel, see [Continue conversations after a reload](https://code.claude.com/docs/en/vs-code.md#continue-conversations-after-a-reload). Requires Claude Code v2.1.309 or later |

371| `CLAUDE_CODE_RETRY_WATCHDOG` | Set to `1` for unattended sessions such as eval harnesses, CI jobs, or remote workers. Retries `429` and `529` capacity errors indefinitely instead of failing after `CLAUDE_CODE_MAX_RETRIES` attempts. Claude Code fails at once when a standard-speed request gets a `429` that reports a spend limit or exhausted usage credits, even one from a [gateway spend cap](https://code.claude.com/docs/en/errors.md#spend-limit-reached) that resets on a schedule. Before v2.1.239, the watchdog retried these indefinitely. For fast mode requests, see [Handle rate limits](https://code.claude.com/docs/en/fast-mode.md#handle-rate-limits). The watchdog backs off up to 5 minutes between attempts, or until the limit resets when the response carries a rate-limit reset time, so a session that hits a usage limit waits out the remaining window. On v2.1.199 or later it also raises the default retry count for other transient errors, such as server errors, timeouts, and dropped connections, to 300, roughly three hours of backoff, and removes the cap of 15 on `CLAUDE_CODE_MAX_RETRIES` if you set that variable explicitly. Requires Claude Code v2.1.186 or later |373| `CLAUDE_CODE_RETRY_WATCHDOG` | Set to `1` for unattended sessions such as eval harnesses, CI jobs, or remote workers. Retries `429` and `529` capacity errors indefinitely instead of failing after `CLAUDE_CODE_MAX_RETRIES` attempts. Claude Code fails at once when a standard-speed request gets a `429` that reports a spend limit or exhausted usage credits, even one from a [gateway spend cap](https://code.claude.com/docs/en/errors.md#spend-limit-reached) that resets on a schedule. Before v2.1.239, the watchdog retried these indefinitely. For fast mode requests, see [Handle rate limits](https://code.claude.com/docs/en/fast-mode.md#handle-rate-limits). The watchdog backs off up to 5 minutes between attempts, or until the limit resets when the response carries a rate-limit reset time, so a session that hits a usage limit waits out the remaining window. On v2.1.199 or later it also raises the default retry count for other transient errors, such as server errors, timeouts, and dropped connections, to 300, roughly three hours of backoff, and removes the cap of 15 on `CLAUDE_CODE_MAX_RETRIES` if you set that variable explicitly. Requires Claude Code v2.1.186 or later |

372| `CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS` | Maximum time in milliseconds that each API request spends waiting out `429` and `529` errors when `CLAUDE_CODE_RETRY_WATCHDOG` is set. Once that time is spent, the next such error ends the request. Give a positive whole number in plain digits, such as `1800000` for 30 minutes. When unset, the wait has no limit. Requires Claude Code v2.1.295 or later |374| `CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS` | Maximum time in milliseconds that each API request spends waiting out `429` and `529` errors when `CLAUDE_CODE_RETRY_WATCHDOG` is set. Once that time is spent, the next such error ends the request. Give a positive whole number in plain digits, such as `1800000` for 30 minutes. When unset, the wait has no limit. Requires Claude Code v2.1.295 or later |

373| `CLAUDE_CODE_RETRY_WATCHDOG_USAGE_LIMIT_RECHECK_MS` | Minimum interval in milliseconds between checks of whether a [usage limit](https://code.claude.com/docs/en/errors.md#youve-hit-your-session-limit) was already lifted, while a request waits for that limit to reset with `CLAUDE_CODE_RETRY_WATCHDOG` set. When a check finds the limit lifted, the request goes out at once. Give a whole number in plain digits from `60000`, one minute, to `10800000`, three hours. Checks are made only for a claude.ai subscription's session or weekly limit while usage credits aren't in use, and not while `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` is set. When this variable is unset or its value is outside that range, no checks are made. Requires Claude Code v2.1.305 or later |375| `CLAUDE_CODE_RETRY_WATCHDOG_USAGE_LIMIT_RECHECK_MS` | Minimum interval in milliseconds between checks of whether a [usage limit](https://code.claude.com/docs/en/errors.md#youve-hit-your-session-limit) was already lifted, while a request waits for that limit to reset with `CLAUDE_CODE_RETRY_WATCHDOG` set. When a check finds the limit lifted, the request goes out at once. Give a whole number in plain digits from `60000`, one minute, to `10800000`, three hours. Checks are made only for a claude.ai subscription's session or weekly limit while usage credits aren't in use, and not while `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` is set. When this variable is unset or its value is outside that range, no checks are made. Requires Claude Code v2.1.305 or later |

errors.md +34 −7

Details

146| `N sessions ended while this machine was offline — the environment was cleaned up on the server and can't be resumed.` | [Network](#sessions-ended-while-this-machine-was-offline) |146| `N sessions ended while this machine was offline — the environment was cleaned up on the server and can't be resumed.` | [Network](#sessions-ended-while-this-machine-was-offline) |

147| `Couldn't share the transcript.` | [Network](#couldnt-share-the-transcript) |147| `Couldn't share the transcript.` | [Network](#couldnt-share-the-transcript) |

148| `Couldn't send feedback` | [Network](#couldnt-send-feedback) |148| `Couldn't send feedback` | [Network](#couldnt-send-feedback) |

149| `Feedback payload too large. Try again without the transcript, or shorten the details.` | [Network](#feedback-payload-too-large) |

149| `MCP server "<name>" connection timed out. Your computer went to sleep or its clock changed while connecting.` | [Network](#mcp-server-connection-timed-out-during-a-sleep-or-clock-change) |150| `MCP server "<name>" connection timed out. Your computer went to sleep or its clock changed while connecting.` | [Network](#mcp-server-connection-timed-out-during-a-sleep-or-clock-change) |

150| `Prompt is too long` / `Input is too long for requested model` | [Request errors](#prompt-is-too-long) |151| `Prompt is too long` / `Input is too long for requested model` | [Request errors](#prompt-is-too-long) |

151| `Prompt is too long · automatic compaction failed:` | [Request errors](#prompt-is-too-long) |152| `Prompt is too long · automatic compaction failed:` | [Request errors](#prompt-is-too-long) |


335| `Failed to write the plan approval request to the lead's inbox — plan not submitted` | [Tool errors](#failed-to-write-to-a-teammate-inbox) |336| `Failed to write the plan approval request to the lead's inbox — plan not submitted` | [Tool errors](#failed-to-write-to-a-teammate-inbox) |

336| `Its agent definition was not restored: the folder its definition file came from is not trusted` | [Tool errors](#teammate-agent-definition-not-restored) |337| `Its agent definition was not restored: the folder its definition file came from is not trusted` | [Tool errors](#teammate-agent-definition-not-restored) |

337| `Only a teammate can approve a shutdown request` | [Tool errors](#only-a-teammate-can-approve-a-shutdown-request) |338| `Only a teammate can approve a shutdown request` | [Tool errors](#only-a-teammate-can-approve-a-shutdown-request) |

339| `A command-line deny rule cannot be handed to a teammate intact` | [Tool errors](#command-line-deny-rule-cannot-be-handed-to-a-teammate) |

338| `Message too large for cross-session delivery` | [Tool errors](#message-too-large-for-cross-session-delivery) |340| `Message too large for cross-session delivery` | [Tool errors](#message-too-large-for-cross-session-delivery) |

339| `Too many messages to this session just now` | [Tool errors](#too-many-messages-to-this-session-just-now) |341| `Too many messages to this session just now` | [Tool errors](#too-many-messages-to-this-session-just-now) |

340| `Cross-session message was dropped at the recipient session's inbox` | [Tool errors](#cross-session-message-dropped-at-the-inbox) |342| `Cross-session message was dropped at the recipient session's inbox` | [Tool errors](#cross-session-message-dropped-at-the-inbox) |


375| `This conversation is already open in another running Claude session` | [Background session errors](#this-session-is-running-in-another-terminal) |377| `This conversation is already open in another running Claude session` | [Background session errors](#this-session-is-running-in-another-terminal) |

376| `This session's saved conversation is no longer on disk` | [Background session errors](#this-sessions-saved-conversation-is-no-longer-on-disk) |378| `This session's saved conversation is no longer on disk` | [Background session errors](#this-sessions-saved-conversation-is-no-longer-on-disk) |

377| `Bypass permissions was requested at launch and ignored` | [Bypass permissions ignored in a background session](https://code.claude.com/docs/en/permission-modes.md#bypass-permissions-ignored-in-a-background-session) |379| `Bypass permissions was requested at launch and ignored` | [Bypass permissions ignored in a background session](https://code.claude.com/docs/en/permission-modes.md#bypass-permissions-ignored-in-a-background-session) |

378| `kept <id> — its worktree is still at <path>` | [Background session errors](#worktree-has-commits-that-are-not-pushed-anywhere) |380| `kept <id> — its worktree is still at <path>` | [Background session errors](#worktree-has-commits-that-are-not-pushed-anywhere) if the message's next line mentions unpushed commits, otherwise [What deleting a session removes](https://code.claude.com/docs/en/agent-view.md#what-deleting-a-session-removes) |

379| `kept <id> — <n> unpushed commits on <branch>` | [Background session errors](#worktree-has-commits-that-are-not-pushed-anywhere) |381| `kept <id> — <n> unpushed commits on <branch>` | [Background session errors](#worktree-has-commits-that-are-not-pushed-anywhere) |

380| `kept <id> — worktree has commits that are not pushed anywhere` | [Background session errors](#worktree-has-commits-that-are-not-pushed-anywhere) |382| `kept <id> — worktree has commits that are not pushed anywhere` | [Background session errors](#worktree-has-commits-that-are-not-pushed-anywhere) |

381| `terminal host process died — press Enter to restart` / `This session's terminal host process died` | [Background session errors](#terminal-host-process-died) |383| `terminal host process died — press Enter to restart` / `This session's terminal host process died` | [Background session errors](#terminal-host-process-died) |


2188 2190 

2189### Couldn't send feedback2191### Couldn't send feedback

2190 2192 

2191A message starting `Couldn't send feedback` means the report you submitted from the [`/feedback`, `/bug`, or `/share` dialog](https://code.claude.com/docs/en/commands#all-commands), or a queued [feedback draft](https://code.claude.com/docs/en/tools-reference.md#sendfeedback-tool-behavior), wasn't sent. When a sentence about your organization follows the colon, your organization refuses feedback and the same report gets the same answer.2193A message starting `Couldn't send feedback` means the feedback service didn't confirm the report you submitted from the [`/feedback`, `/bug`, or `/share` dialog](https://code.claude.com/docs/en/commands#all-commands), or a queued [feedback draft](https://code.claude.com/docs/en/tools-reference.md#sendfeedback-tool-behavior). Treat it as not received. When a sentence about your organization follows the colon, your organization refuses feedback and the same report gets the same answer.

2192 2194 

2193The first of these two examples is a network failure and the second is an organization's refusal:2195The second of these two examples is an organization's refusal:

2194 2196 

2195```text wrap theme={null}2197```text wrap theme={null}

2196Couldn't send feedback (couldn't reach the service). If it keeps failing, you can file at https://github.com/anthropics/claude-code/issues instead.2198Couldn't send feedback (couldn't reach the service). If it keeps failing, you can file at https://github.com/anthropics/claude-code/issues instead.


2203* **Not signed in**: the message continues `: not signed in. Run /login, then retry.` Run `/login`, then send again2205* **Not signed in**: the message continues `: not signed in. Run /login, then retry.` Run `/login`, then send again

2204* **Your organization's refusal**: for example `: Feedback has not been enabled for your organization.` or `: Feedback collection is not available for organizations with custom data retention policies.` If the message adds `To report a bug, open an issue`, do so at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues). A queued draft stays queued, and you can [discard it](https://code.claude.com/docs/en/tools-reference.md#discard-or-keep-a-draft)2206* **Your organization's refusal**: for example `: Feedback has not been enabled for your organization.` or `: Feedback collection is not available for organizations with custom data retention policies.` If the message adds `To report a bug, open an issue`, do so at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues). A queued draft stays queued, and you can [discard it](https://code.claude.com/docs/en/tools-reference.md#discard-or-keep-a-draft)

2205* **Refused credentials**: the message continues `: the sign-in this session uses is not allowed to send feedback` or `: the server did not accept the credentials this session uses`. Run `/status` at the Claude Code prompt to see which login, token, or API key this session sends2207* **Refused credentials**: the message continues `: the sign-in this session uses is not allowed to send feedback` or `: the server did not accept the credentials this session uses`. Run `/status` at the Claude Code prompt to see which login, token, or API key this session sends

2206* **`(request timed out)` or `(couldn't reach the service)` straight after `Couldn't send feedback`**: these are network failures. Send the report or the queued draft again. The dialog keeps your text, and a queued draft's message says `The draft is still queued.` If other requests are failing too, check your network connection and see [Unable to connect to API](#unable-to-connect-to-api). If it keeps failing, file the report at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues)2208* **`(request timed out)` or `(couldn't reach the service)` straight after `Couldn't send feedback`**: send the report or the queued draft again. The dialog keeps your text, and a queued draft's message says `The draft is still queued.` If other requests are failing too, check your network connection and see [Unable to connect to API](#unable-to-connect-to-api). If it keeps failing, file the report at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues)

2207* **`(server returned <status>)`, or no reason, straight after `Couldn't send feedback`**: the status is the service's response code. The service's own message follows it when one was sent, as in `(server returned 403: Access Forbidden)`. If it keeps failing, file the report at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues)2209* **`(server returned <status>)`, or no reason, straight after `Couldn't send feedback`**: the status is the service's response code. The service's own message follows it when one was sent, as in `(server returned 403: Access Forbidden)`. If it keeps failing, file the report at [github.com/anthropics/claude-code/issues](https://github.com/anthropics/claude-code/issues)

2208 2210 

2209Issues at github.com/anthropics/claude-code are public, so leave out code, transcripts, and anything else confidential when you open one.2211Issues at github.com/anthropics/claude-code are public, so leave out code, transcripts, and anything else confidential when you open one.

2210 2212 

2211Before v2.1.281, every send failed with this message once a Remote Control **Stop** or an urgent cross-session message had arrived while the dialog was open. On those versions, close the dialog, reopen it, and send again.2213Before v2.1.281, every send failed with this message once a Remote Control **Stop** or an urgent cross-session message had arrived while the dialog was open. On those versions, close the dialog, reopen it, and send again.

2212 2214 

2215### Feedback payload too large

2216 

2217This message in the [review screen](https://code.claude.com/docs/en/tools-reference.md#review-and-edit-a-draft) for a [feedback draft](https://code.claude.com/docs/en/tools-reference.md#sendfeedback-tool-behavior) means Claude Code has no confirmation that the service accepted the draft. Treat it as not received. The draft stays in your `/feedback` queue, so you can send it again.

2218 

2219```text wrap theme={null}

2220Feedback payload too large. Try again without the transcript, or shorten the details.

2221```

2222 

2223**What to do:**

2224 

2225* In the review screen, set **Send transcript** to `no`, then send the draft again. Shortening the details removes at most 10 KB of text, which is all a draft's details can hold.

2226 

2213### MCP server connection timed out during a sleep or clock change2227### MCP server connection timed out during a sleep or clock change

2214 2228 

2215This message means a connection to an [MCP server](https://code.claude.com/docs/en/mcp.md) timed out, and Claude Code found that your system clock jumped forward during the attempt:2229This message means a connection to an [MCP server](https://code.claude.com/docs/en/mcp.md) timed out, and Claude Code found that your system clock jumped forward during the attempt:


3476 3490 

3477### MCP server rejected the elicitation capability3491### MCP server rejected the elicitation capability

3478 3492 

3479An MCP server built on Java MCP SDK 0.11.0 through 0.17.0 refused the connection. Those SDK versions can't parse the `form` and `url` [elicitation modes](https://code.claude.com/docs/en/mcp.md#elicitation-modes-claude-code-declares) that Claude Code declares in its handshake. `claude mcp list` shows the server as failed with this message in place of the server's own error:3493An MCP server built on Java MCP SDK 0.11.0 through 0.17.0 refused the connection. Those SDK versions can't parse the `form` and `url` [elicitation modes](https://code.claude.com/docs/en/mcp.md#elicitation-modes-claude-code-declares) that Claude Code declares in its handshake. The message reads:

3480 3494 

3481```text theme={null}3495```text theme={null}

3482This server (Java MCP SDK 0.17.0 or older) rejected Claude Code's elicitation capability. Set "bareElicitationCapability": true for it, or upgrade to Java MCP SDK 0.17.1+ (Spring AI 1.0.7+ or 1.1.6+).3496This server (Java MCP SDK 0.17.0 or older) rejected Claude Code's elicitation capability. Set "bareElicitationCapability": true for it, or upgrade to Java MCP SDK 0.17.1+ (Spring AI 1.0.7+ or 1.1.6+).


4678* If the teammate is still running, ask the lead at its prompt to shut the teammate down, for example `Ask the researcher teammate to shut down`. See [Shut down teammates](https://code.claude.com/docs/en/agent-teams.md#shut-down-teammates).4692* If the teammate is still running, ask the lead at its prompt to shut the teammate down, for example `Ask the researcher teammate to shut down`. See [Shut down teammates](https://code.claude.com/docs/en/agent-teams.md#shut-down-teammates).

4679* If a former teammate you resumed yourself with `claude --resume` got this refusal, nothing was sent. To end that session, run `/exit` at its prompt.4693* If a former teammate you resumed yourself with `claude --resume` got this refusal, nothing was sent. To end that session, run `/exit` at its prompt.

4680 4694 

4695### A command-line deny rule cannot be handed to a teammate intact

4696 

4697This message means Claude Code didn't start a [split-pane](https://code.claude.com/docs/en/agent-teams.md#choose-a-display-mode) teammate in your [agent team](https://code.claude.com/docs/en/agent-teams.md). Claude Code passes the lead's command-line deny rules to a split-pane teammate on the teammate's own command line, and stops when the teammate would read one of them differently:

4698 

4699```text wrap theme={null}

4700A command-line deny rule cannot be handed to a teammate intact, so the teammate would not enforce it — spawn aborted

4701```

4702 

4703**What to do:**

4704 

4705* Run `/config` in the lead session and set **Teammate mode** to `in-process`, then ask Claude to start the teammate again. You don't need to find the rule or restart the lead. An in-process teammate [runs under the lead's live deny rules](https://code.claude.com/docs/en/agent-teams.md#permissions).

4706* Later sessions that take [`teammateMode`](https://code.claude.com/docs/en/settings-reference#teammatemode) from your user settings start teammates in-process too, because `/config` saves the choice there. To go back to split panes in a later session, set **Teammate mode** to `auto`, `tmux`, or `iterm2`, whichever you used before.

4707 

4681### Message too large for cross-session delivery4708### Message too large for cross-session delivery

4682 4709 

4683Claude's [cross-session message](https://code.claude.com/docs/en/cross-session-messaging.md) to another of your sessions on this machine was too long to send. Claude Code refused it, and the receiving session got nothing. The refusal appears in the sending session's tool result, not as a banner in your terminal. It names both sizes and how to make the message fit:4710Claude's [cross-session message](https://code.claude.com/docs/en/cross-session-messaging.md) to another of your sessions on this machine was too long to send. Claude Code refused it, and the receiving session got nothing. The refusal appears in the sending session's tool result, not as a banner in your terminal. It names both sizes and how to make the message fit:


5115**What to do:**5142**What to do:**

5116 5143 

5117* To keep the commits, push the worktree's branch, or merge it into the default branch checked out in your main checkout, then delete the session again5144* To keep the commits, push the worktree's branch, or merge it into the default branch checked out in your main checkout, then delete the session again

5118* To discard the commits, run the `claude rm <id> --discard-unpushed` command the message printed, or press `Ctrl+X` twice on the session's row in agent view again. This removes the session and the worktree along with its branch, the unpushed commits, and any uncommitted changes. If the worktree has gained a commit since the refusal, Claude Code keeps it again and shows the updated state5145* To discard the commits, run the `claude rm <id> --discard-unpushed` command the message printed, or press `Ctrl+X` twice on the session's row in agent view again. This removes the session and the worktree along with its branch, the unpushed commits, and any uncommitted changes. If the delete is refused again, follow the new message.

5119* When the message says the worktree is also recorded by another finished session, deleting again doesn't discard it: push the commits, then delete the session again5146* When the message says the worktree is also recorded by another finished session, deleting again doesn't discard it: push the commits, then delete the session again

5120 5147 

5121Before v2.1.268, `claude rm` put the commit summary on the `kept` line itself. When `claude rm` couldn't summarize the commits, the `kept` line read `worktree has commits that are not pushed anywhere` in place of the summary.5148Before v2.1.268, `claude rm` put the commit summary on the `kept` line itself. When `claude rm` couldn't summarize the commits, the `kept` line read `worktree has commits that are not pushed anywhere` in place of the summary.

5122 5149 

5123Before v2.1.260, the message didn't name the branch or the commits, and deleting again was refused the same way: deleting the session without pushing meant removing the worktree yourself with `git worktree remove --force <path>`, then running `claude rm <id>` again.5150Before v2.1.260, the message didn't name the branch or commits, and there was no discard route. You can still delete the session, losing uncommitted changes but keeping the branch and commits. Run `git worktree remove --force --force <path>` with the path the refusal printed, then `claude rm <id>`. Git needs `--force` twice for a locked worktree.

5124 5151 

5125Before v2.1.248, the default branch checked out in your main checkout didn't count: a branch you had already merged there still triggered this refusal until its commits reached a remote.5152Before v2.1.248, the default branch checked out in your main checkout didn't count: a branch you had already merged there still triggered this refusal until its commits reached a remote.

5126 5153 

fast-mode.md +1 −1

Details

45* A small `↯` icon appears next to the prompt while fast mode is active45* A small `↯` icon appears next to the prompt while fast mode is active

46* Run `/fast` again at any time to check whether fast mode is on or off46* Run `/fast` again at any time to check whether fast mode is on or off

47 47 

48Opus 5.5 is the fast mode default in Claude Code v2.1.280 and later. Before v2.1.280, fast mode defaulted to Opus 5 from v2.1.219, and to Opus 4.8 on v2.1.154 through v2.1.218.48Opus 5.5 is the fast mode default in Claude Code v2.1.280 and later. Before v2.1.280, fast mode defaulted to Opus 5 from v2.1.219.

49 49 

50When you disable fast mode with `/fast` again, you remain on Opus. To switch to a different model, use `/model`.50When you disable fast mode with `/fast` again, you remain on Opus. To switch to a different model, use `/model`.

51 51 

glossary.md +1 −1

Details

373 373 

374How a session knows the work is actually done instead of accepting a result that looks plausible. You give Claude a check it can run, such as a test suite, a build, or a screenshot comparison, and Claude iterates until the check passes instead of stopping after one attempt. A verification loop is the prerequisite for [`/goal`](https://code.claude.com/docs/en/goal), unattended runs, and [dynamic workflows](https://code.claude.com/docs/en/workflows.md): without one, the only thing deciding the agent is finished is the agent itself.374How a session knows the work is actually done instead of accepting a result that looks plausible. You give Claude a check it can run, such as a test suite, a build, or a screenshot comparison, and Claude iterates until the check passes instead of stopping after one attempt. A verification loop is the prerequisite for [`/goal`](https://code.claude.com/docs/en/goal), unattended runs, and [dynamic workflows](https://code.claude.com/docs/en/workflows.md): without one, the only thing deciding the agent is finished is the agent itself.

375 375 

376Learn more: [Give Claude a way to verify its work](https://code.claude.com/docs/en/best-practices.md#give-claude-a-way-to-verify-its-work)376Learn more: [Give Claude a check to run](https://code.claude.com/docs/en/best-practices.md#give-claude-a-check-to-run)

377 377 

378## W378## W

379 379 

Details

166| Primary model | `claude-opus-5-5` |166| Primary model | `claude-opus-5-5` |

167| Small/fast model | `claude-sonnet-4-5@20250929` |167| Small/fast model | `claude-sonnet-4-5@20250929` |

168 168 

169Before v2.1.280, the primary model on Google Cloud's Agent Platform defaulted to Opus 5 and the `opus` alias resolved to Opus 5 from v2.1.219.

170 

169Background tasks such as session title generation use the small/fast model, normally a Haiku-class model. On Google Cloud's Agent Platform, Claude Code uses the default Sonnet model for background tasks because Haiku may not be enabled in every project or region. Two selections change which model carries them:171Background tasks such as session title generation use the small/fast model, normally a Haiku-class model. On Google Cloud's Agent Platform, Claude Code uses the default Sonnet model for background tasks because Haiku may not be enabled in every project or region. Two selections change which model carries them:

170 172 

171* When you select a primary model with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, background tasks use that model. When Claude Code starts the session on the model you set with [`ANTHROPIC_DEFAULT_MODEL`](https://code.claude.com/docs/en/model-config#set-a-default-model-for-new-sessions), background tasks use that model too. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` also counts as a selection, because the built-in Sonnet model may not be enabled in a project that steers its own Opus.173* When you select a primary model with `--model`, `ANTHROPIC_MODEL`, or the `model` setting, background tasks use that model. When Claude Code starts the session on the model you set with [`ANTHROPIC_DEFAULT_MODEL`](https://code.claude.com/docs/en/model-config#set-a-default-model-for-new-sessions), background tasks use that model too. Setting `ANTHROPIC_DEFAULT_OPUS_MODEL` without `ANTHROPIC_DEFAULT_SONNET_MODEL` also counts as a selection, because the built-in Sonnet model may not be enabled in a project that steers its own Opus.


175>177>

176> Opus models have a higher per-token price than Sonnet models, so if you don't pin a primary model, you're billed at the Opus rate. To use Sonnet 4.5 as the primary model, set `ANTHROPIC_MODEL` to its full model ID. A deployment that steers the default with `ANTHROPIC_DEFAULT_SONNET_MODEL` and doesn't set `ANTHROPIC_DEFAULT_OPUS_MODEL` keeps its steered Sonnet model as the default.178> Opus models have a higher per-token price than Sonnet models, so if you don't pin a primary model, you're billed at the Opus rate. To use Sonnet 4.5 as the primary model, set `ANTHROPIC_MODEL` to its full model ID. A deployment that steers the default with `ANTHROPIC_DEFAULT_SONNET_MODEL` and doesn't set `ANTHROPIC_DEFAULT_OPUS_MODEL` keeps its steered Sonnet model as the default.

177 179 

178Before v2.1.280, the primary model on Google Cloud's Agent Platform defaulted to Opus 5 and the `opus` alias resolved to Opus 5 from v2.1.219. On v2.1.207 through v2.1.218, the primary model on Google Cloud's Agent Platform defaulted to Opus 4.8 and the `opus` alias resolved to Opus 4.8.

179 

180To customize models further:180To customize models further:

181 181 

182```bash theme={null}182```bash theme={null}

headless.md +4 −3

Details

236 236 

237If some of these messages are missing from your stream, check your Claude Code version against these minimums:237If some of these messages are missing from your stream, check your Claude Code version against these minimums:

238 238 

239* **Forwarding at every nesting depth**: v2.1.219 or later

240* **A forked skill that Claude starts with the Skill tool from the main conversation**: v2.1.86 or later for its `tool_use` and `tool_result` blocks, and v2.1.265 or later for its first `user` message and its text and thinking blocks239* **A forked skill that Claude starts with the Skill tool from the main conversation**: v2.1.86 or later for its `tool_use` and `tool_result` blocks, and v2.1.265 or later for its first `user` message and its text and thinking blocks

241* **Messages of subagents that a forked skill spawns, and of forked skills started inside a subagent or another forked skill**: v2.1.275 or later240* **Messages of subagents that a forked skill spawns, and of forked skills started inside a subagent or another forked skill**: v2.1.275 or later

242* **Messages of a forked skill you start by passing `/<skill-name>` as the prompt**: v2.1.287 or later241* **Messages of a forked skill you start by passing `/<skill-name>` as the prompt**: v2.1.287 or later


285| Field | Type | Description |284| Field | Type | Description |

286| - | - | - |285| - | - | - |

287| `mcp_servers` | array | MCP servers in the session, each with `name` and `status` |286| `mcp_servers` | array | MCP servers in the session, each with `name` and `status` |

288| `mcp_server_errors` | array | `--mcp-config` entries skipped by config validation, each with `name`, `type`, and `message`. `type` is a skip category such as `unknown_type`, `url_missing_type`, `invalid_config`, or `reserved_name`; treat values you don't recognize as a generic skip. Affected servers are absent from `mcp_servers`. The key is omitted when there are no errors, so a CI gate can fail on a non-empty array. Requires Claude Code v2.1.219 or later |287| `mcp_server_errors` | array | `--mcp-config` entries skipped by config validation, each with `name`, `type`, and `message`. `type` is a skip category such as `unknown_type`, `url_missing_type`, `invalid_config`, or `reserved_name`; treat values you don't recognize as a generic skip. Affected servers are absent from `mcp_servers`. The key is omitted when there are no errors, so a CI gate can fail on a non-empty array |

289 288 

290When you run the command by hand in a terminal, Claude Code also prints a startup warning to stderr, such as `Warning: 1 MCP server skipped due to invalid config:`, followed by the reason for each skipped entry. When you redirect stderr, or when a program such as a CI runner or an SDK host captures it, Claude Code prints no warning and reports the skipped entries only in the `mcp_server_errors` field. The warning requires Claude Code v2.1.219 or later.289When you run the command yourself in a terminal, Claude Code also prints a startup warning to stderr, such as `Warning: 1 MCP server skipped due to invalid config:`, followed by the reason for each skipped entry.

290 

291When you redirect stderr, or when a program such as a CI runner or an SDK host captures it, Claude Code prints no warning. It reports the skipped entries only in the `mcp_server_errors` field.

291 292 

292#### Track plugin installs293#### Track plugin installs

293 294 

hooks.md +5 −9

Details

679 679 

680Frontmatter hooks in a project skill follow the same [workspace trust rule as hooks in settings files](#workspace-trust). Claude Code registers them when you or Claude invoke the skill, including in a `-p` run in a folder you haven't trusted.680Frontmatter hooks in a project skill follow the same [workspace trust rule as hooks in settings files](#workspace-trust). Claude Code registers them when you or Claude invoke the skill, including in a `-p` run in a folder you haven't trusted.

681 681 

682Frontmatter hooks in a project subagent run only after you accept the [workspace trust dialog](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust) for the folder the agent file came from. A `-p` session doesn't count as accepting it. [What runs before you trust a folder](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder) compares this with the settings-file rule, and the subagents page lists [which scopes are exempt](https://code.claude.com/docs/en/sub-agents.md#hooks-in-subagent-frontmatter). Before v2.1.218, these hooks could run from folders you hadn't trusted.682Frontmatter hooks in a project subagent run only after you accept the [workspace trust dialog](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust) for the folder the agent file came from. A `-p` session doesn't count as accepting it. [What runs before you trust a folder](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder) compares this with the settings-file rule, and the subagents page lists [which scopes are exempt](https://code.claude.com/docs/en/sub-agents.md#hooks-in-subagent-frontmatter).

683 683 

684#### Limits on skill hooks684#### Limits on skill hooks

685 685 


3196* **Command hooks** (`type: "command"`): print the path as the last non-empty line of stdout. Claude Code strips ANSI escape codes before reading that line, so shell startup banners printed before your `echo` are ignored. Redirect any other hook output to stderr.3196* **Command hooks** (`type: "command"`): print the path as the last non-empty line of stdout. Claude Code strips ANSI escape codes before reading that line, so shell startup banners printed before your `echo` are ignored. Redirect any other hook output to stderr.

3197* **HTTP hooks** (`type: "http"`): return `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` in the response body.3197* **HTTP hooks** (`type: "http"`): return `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` in the response body.

3198 3198 

3199If the hook fails or produces no path, worktree creation fails with an error.3199If the hook fails or produces no path, worktree creation fails with an error. Claude Code resolves a relative path against the directory the hook ran in, collapsing any `.` or `..` segments in it. If the resulting path isn't a directory Claude Code can enter, the session prints an error naming the path and exits with code 1.

3200 3200 

3201Claude Code resolves a relative path against the directory the hook ran in, collapsing any `.` or `..` segments in it. If the resulting path isn't a directory Claude Code can enter, the session prints an error naming the path and exits with code 1.3201Claude Code refuses an absolute path that contains `.` or `..` segments, and any path that passes through a symlink below the repository root. The error names the rejected component. A symlink committed to the repository could redirect the worktree outside it. Return a normalized path that doesn't pass through a symlink inside the repository.

3202 

3203Claude Code refuses an absolute path that contains `.` or `..` segments, and any path that passes through a symlink below the repository root, because a symlink committed to the repository could redirect the worktree outside it. The error names the rejected component. Return a normalized path that doesn't pass through a symlink inside the repository. Before v2.1.216, worktree creation followed the hook's path without this screening.

3204 3202 

3205### WorktreeRemove3203### WorktreeRemove

3206 3204 


3228* **Hook exits 0**: the worktree counts as removed. Claude Code reads nothing else from the hook, so make sure your hook deleted the directory.3226* **Hook exits 0**: the worktree counts as removed. Claude Code reads nothing else from the hook, so make sure your hook deleted the directory.

3229* **Hook exits non-zero**: the removal fails if the directory at `worktree_path` still exists afterward, and the worktree stays on disk with no git fallback. A hook that deleted the directory before exiting non-zero counts as removed. For how the failure is reported, see [WorktreeRemove input](#worktreeremove-input).3227* **Hook exits non-zero**: the removal fails if the directory at `worktree_path` still exists afterward, and the worktree stays on disk with no git fallback. A hook that deleted the directory before exiting non-zero counts as removed. For how the failure is reported, see [WorktreeRemove input](#worktreeremove-input).

3230 3228 

3231Claude Code never deletes a branch belonging to a hook-created worktree, because it only knows the path your WorktreeCreate hook returned. If your WorktreeCreate hook creates a branch, delete it in your WorktreeRemove hook.3229Claude Code never deletes a branch belonging to a hook-created worktree, because it only knows the path your WorktreeCreate hook returned. If your WorktreeCreate hook creates a branch, delete it in your WorktreeRemove hook. Claude Code discards a WorktreeRemove hook's [JSON output fields](#json-output), such as `systemMessage` and `continue`.

3232 

3233Claude Code discards a WorktreeRemove hook's [JSON output fields](#json-output), such as `systemMessage` and `continue`.

3234 3230 

3235For a background-session delete, Claude Code verifies the stored worktree path before running the hook and refuses a path that is a symlink or passes through one below the repository root. On that route, the hook runs for a worktree that still contains files only when you confirm the delete in [agent view](https://code.claude.com/docs/en/agent-view.md#what-deleting-a-session-removes); for such a worktree, [`claude rm`](https://code.claude.com/docs/en/agent-view#manage-sessions-from-the-shell) keeps the session and worktree instead. Before v2.1.216, the hook ran on the stored path without these checks.3231For a background-session delete, Claude Code verifies the stored worktree path before running the hook, refusing a path that is a symlink or passes through one below the repository root. On that route, the hook runs for a worktree that still contains files only when you confirm the delete in [agent view](https://code.claude.com/docs/en/agent-view.md#what-deleting-a-session-removes). For such a worktree, [`claude rm`](https://code.claude.com/docs/en/agent-view#manage-sessions-from-the-shell) keeps the session and worktree instead.

3236 3232 

3237Claude Code passes the path returned by WorktreeCreate as `worktree_path` in the hook input. This example reads that path and removes the directory:3233Claude Code passes the path returned by WorktreeCreate as `worktree_path` in the hook input. This example reads that path and removes the directory:

3238 3234 

Details

174 174 

175## Work effectively with Claude Code175## Work effectively with Claude Code

176 176 

177These tips help you get better results from Claude Code. For more on specific prompts, verification, and planning, see [Best practices](https://code.claude.com/docs/en/best-practices.md).177These tips help you get better results from Claude Code. For more on specific prompts, verification, and the rules worth enforcing rather than prompting for, see [Best practices](https://code.claude.com/docs/en/best-practices.md).

178 178 

179### Ask Claude Code for help179### Ask Claude Code for help

180 180 

Details

92| `/` at start | Command or skill | See [commands](#commands) and [skills](https://code.claude.com/docs/en/skills.md) |92| `/` at start | Command or skill | See [commands](#commands) and [skills](https://code.claude.com/docs/en/skills.md) |

93| `!` at start | Shell mode | Run a command directly, add its output to the session, and have Claude respond to it |93| `!` at start | Shell mode | Run a command directly, add its output to the session, and have Claude respond to it |

94| `@` | File path mention | Trigger file path autocomplete. In sessions with [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md#message-another-session), when you type at least one letter after the `@`, Claude Code also suggests your other live sessions on this machine, so you can tell Claude to message the one you pick. Requires Claude Code v2.1.232 or later |94| `@` | File path mention | Trigger file path autocomplete. In sessions with [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md#message-another-session), when you type at least one letter after the `@`, Claude Code also suggests your other live sessions on this machine, so you can tell Claude to message the one you pick. Requires Claude Code v2.1.232 or later |

95| `:` | Emoji shortcode | Type a full `:name:` to insert the emoji, or two or more characters for suggestions. See [Emoji shortcodes](#emoji-shortcodes). Requires Claude Code v2.1.217 or later |95| `:` | Emoji shortcode | Type a full `:name:` to insert the emoji, or two or more characters for suggestions. See [Emoji shortcodes](#emoji-shortcodes) |

96| `?` on empty input | Toggle the shortcut help panel | Typing `?` when the input already contains text inserts the character |96| `?` on empty input | Toggle the shortcut help panel | Typing `?` when the input already contains text inserts the character |

97 97 

98### Transcript viewer98### Transcript viewer


197 197 

198> [!NOTE]198> [!NOTE]

199>199>

200> In vim NORMAL mode, if the cursor is at the beginning or end of input and can't move further, `j`/`k` and `↑`/`↓` navigate command history instead. `←` on an empty prompt opens [agent view](https://code.claude.com/docs/en/agent-view.md) from NORMAL mode as well as INSERT; before v2.1.219, `←` on an empty prompt did nothing in NORMAL mode.200> In vim NORMAL mode, if the cursor is at the beginning or end of input and can't move further, `j`/`k` and `↑`/`↓` navigate command history instead. `←` on an empty prompt opens [agent view](https://code.claude.com/docs/en/agent-view.md) from NORMAL mode as well as INSERT.

201 201 

202### Editing (NORMAL mode)202### Editing (NORMAL mode)

203 203 


396Claude Code runs some commands as soon as you send them instead of queueing them, among them `/model`, `/effort`, and `/fast`. Each of the three changes a setting: the model, the effort level, or fast mode. Whether Claude Code applies the new setting to the turn Claude is already working on, or only from your next turn, differs by command:396Claude Code runs some commands as soon as you send them instead of queueing them, among them `/model`, `/effort`, and `/fast`. Each of the three changes a setting: the model, the effort level, or fast mode. Whether Claude Code applies the new setting to the turn Claude is already working on, or only from your next turn, differs by command:

397 397 

398* [`/model`](https://code.claude.com/docs/en/model-config#setting-your-model): once you confirm the [cache warning](https://code.claude.com/docs/en/prompt-caching.md#switching-models), if Claude Code shows one, Claude Code applies your change to the next request it makes in that turn398* [`/model`](https://code.claude.com/docs/en/model-config#setting-your-model): once you confirm the [cache warning](https://code.claude.com/docs/en/prompt-caching.md#switching-models), if Claude Code shows one, Claude Code applies your change to the next request it makes in that turn

399* [`/effort`](https://code.claude.com/docs/en/model-config#adjust-effort-level): once you confirm the [cache warning](https://code.claude.com/docs/en/prompt-caching.md#changing-effort-level), if Claude Code shows one, Claude Code applies your change to the next request it makes in that turn399* `/effort`: the next message you send runs at the new level. To [start it in the turn Claude is already working on](https://code.claude.com/docs/en/model-config.md#when-a-new-effort-level-starts), queue a message while Claude is running tool calls

400* [`/fast`](https://code.claude.com/docs/en/fast-mode#toggle-fast-mode): Claude Code keeps the fast mode setting that was active when the turn started, so your speed change applies from your next turn. If your current model doesn't support fast mode, turning it on also [switches your model](https://code.claude.com/docs/en/prompt-caching.md#turning-on-fast-mode), and Claude Code uses the new model from its next request in that turn400* [`/fast`](https://code.claude.com/docs/en/fast-mode#toggle-fast-mode): Claude Code keeps the fast mode setting that was active when the turn started, so your speed change applies from your next turn. If your current model doesn't support fast mode, turning it on also [switches your model](https://code.claude.com/docs/en/prompt-caching.md#turning-on-fast-mode), and Claude Code uses the new model from its next request in that turn

401 401 

402### Background a session with messages queued402### Background a session with messages queued


513 513 

514## Emoji shortcodes514## Emoji shortcodes

515 515 

516Type a `:` followed by an emoji shortcode in the prompt input to insert the emoji. Requires Claude Code v2.1.217 or later.516Type a `:` followed by an emoji shortcode in the prompt input to insert the emoji.

517 517 

518* Type a complete shortcode such as `:heart:` and Claude Code replaces it with ❤️ as soon as you type the closing `:`518* Type a complete shortcode such as `:heart:` and Claude Code replaces it with ❤️ as soon as you type the closing `:`

519* Type `:` plus at least two characters of a name, such as `:hea`, to open a suggestion popup, then press `Tab` or `Enter` to insert the highlighted emoji519* Type `:` plus at least two characters of a name, such as `:hea`, to open a suggestion popup, then press `Tab` or `Enter` to insert the highlighted emoji

Details

31 31 

32> [!TIP]32> [!TIP]

33>33>

34> For workflow techniques that keep context small in any repository, such as [running exploration in a subagent](https://code.claude.com/docs/en/best-practices.md#use-subagents-for-investigation) so file reads stay out of the main conversation, see [Best practices for Claude Code](https://code.claude.com/docs/en/best-practices.md). To roll out a baseline configuration to every developer in your organization, see [Set up Claude Code for your organization](https://code.claude.com/docs/en/admin-setup.md).34> For workflow techniques that keep context small in any repository, see [Best practices for Claude Code](https://code.claude.com/docs/en/best-practices.md). One example is [running exploration in a subagent](https://code.claude.com/docs/en/best-practices.md#know-what-subagents-cost) so file reads stay out of the main conversation. To roll out a baseline configuration to every developer in your organization, see [Set up Claude Code for your organization](https://code.claude.com/docs/en/admin-setup.md).

35 35 

36### The example monorepo36### The example monorepo

37 37 


158The deny rules can cover everyone working in the repository, only you, or every session on the machine, depending on which settings file you put them in:158The deny rules can cover everyone working in the repository, only you, or every session on the machine, depending on which settings file you put them in:

159 159 

160* **Everyone working in the repository**: commit the rules to `.claude/settings.json`, at the repository root if you start Claude there, or in each package's `.claude/` if you start from subdirectories. Like other project settings on this page, that file isn't inherited from parent directories.160* **Everyone working in the repository**: commit the rules to `.claude/settings.json`, at the repository root if you start Claude there, or in each package's `.claude/` if you start from subdirectories. Like other project settings on this page, that file isn't inherited from parent directories.

161* **Yourself only**: use `.claude/settings.local.json` at the repository root, which loads in every CLI session inside the repository regardless of starting directory, except in the cases where Claude Code [doesn't use the repository root](https://code.claude.com/docs/en/settings.md#where-claude-code-looks-for-each-file), such as on Windows. Relative patterns like the example's `Read(./**/vendor/**/*)` still [anchor at the session's current working directory](https://code.claude.com/docs/en/permissions.md#read-and-edit) rather than the repository root, so if you start sessions from subdirectories, write the rules in this file as `//`-absolute paths, such as `Read(//absolute/path/to/repo/**/vendor/**/*)`. Before v2.1.211, `.claude/settings.local.json` also loaded only from the starting directory.161* **Yourself only**: use `.claude/settings.local.json` at the repository root. It loads in every CLI session inside the repository regardless of starting directory, except in the cases where Claude Code [doesn't use the repository root](https://code.claude.com/docs/en/settings.md#where-claude-code-looks-for-each-file), such as on Windows.

162 

163 Relative patterns like the example's `Read(./**/vendor/**/*)` still [anchor at the session's current working directory](https://code.claude.com/docs/en/permissions.md#read-and-edit) rather than the repository root. If you start sessions from subdirectories, write the rules in this file as `//`-absolute paths, such as `Read(//absolute/path/to/repo/**/vendor/**/*)`.

162* **Everyone, enforced in every session**: set the rules in [managed settings](https://code.claude.com/docs/en/managed-settings.md), which user and project settings cannot override.164* **Everyone, enforced in every session**: set the rules in [managed settings](https://code.claude.com/docs/en/managed-settings.md), which user and project settings cannot override.

163 165 

164The example below blocks build artifacts and a vendored SDK. Its directory patterns end with `/**/*` rather than `/**` so that each rule covers everything inside the directory but not the directory itself. Claude can then still list those directories or change into them, for example with `ls dist` or `cd build`.166The example below blocks build artifacts and a vendored SDK. Its directory patterns end with `/**/*` rather than `/**` so that each rule covers everything inside the directory but not the directory itself. Claude can then still list those directories or change into them, for example with `ls dist` or `cd build`.


376Move conventions and reference content out of always-loaded CLAUDE.md and into mechanisms that load on demand:378Move conventions and reference content out of always-loaded CLAUDE.md and into mechanisms that load on demand:

377 379 

378* [Skills](https://code.claude.com/docs/en/skills.md): reference material Claude loads only when relevant to the task380* [Skills](https://code.claude.com/docs/en/skills.md): reference material Claude loads only when relevant to the task

379* [Plugins](https://code.claude.com/docs/en/plugins/overview.md): versioned bundles of skills, hooks, and commands that a platform team owns centrally381* [Plugins](https://code.claude.com/docs/en/plugins/overview.md): versioned bundles of skills, hooks, and commands that a platform team owns centrally and can [install for everyone through managed settings](https://code.claude.com/docs/en/plugins/org.md#pre-install-and-require-plugins)

380* [MCP servers](https://code.claude.com/docs/en/mcp.md): if your organization already runs a code search or RAG index over the repository, expose it as an MCP tool so Claude queries it instead of reading files directly382* [MCP servers](https://code.claude.com/docs/en/mcp.md): if your organization already runs a code search or RAG index over the repository, expose it as an MCP tool so Claude queries it instead of reading files directly

381 383 

382See [server-managed or endpoint-managed settings](https://code.claude.com/docs/en/server-managed-settings.md#choose-between-server-managed-and-endpoint-managed-settings) for how platform teams can enforce these centrally.384See [server-managed or endpoint-managed settings](https://code.claude.com/docs/en/server-managed-settings.md#choose-between-server-managed-and-endpoint-managed-settings) for how platform teams can enforce these centrally.


465Two techniques help keep a cross-package change consistent:467Two techniques help keep a cross-package change consistent:

466 468 

467* **Give Claude the whole change in one session**: handing over the shared edit and its call sites together keeps the decisions behind each edit consistent, rather than re-deriving them per package469* **Give Claude the whole change in one session**: handing over the shared edit and its call sites together keeps the decisions behind each edit consistent, rather than re-deriving them per package

468* **Plan before editing**: [plan first](https://code.claude.com/docs/en/best-practices.md#explore-first-then-plan-then-code) in [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode), and Claude writes the plan to a file. A long cross-package session [compacts its context](https://code.claude.com/docs/en/context-window.md#what-survives-compaction) along the way. Claude Code re-injects the plan file after each compaction, so the plan survives where conversation history may not470* **Plan before editing**: plan first in [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode), and Claude writes the plan to a file. A long cross-package session [compacts its context](https://code.claude.com/docs/en/context-window.md#what-survives-compaction) as it goes. Claude Code re-injects the plan file after each compaction, so the plan survives where conversation history may not

469 471 

470## Next steps472## Next steps

471 473 

Details

361 361 

362The gateway carries model requests, but Claude Code also sends nonessential background traffic outside the gateway path, to Anthropic and to third-party services such as GitHub: version checks, telemetry, release notes, and similar requests. On a network that only allows egress to the gateway, these requests fail and can appear as blocked connections in your egress monitoring.362The gateway carries model requests, but Claude Code also sends nonessential background traffic outside the gateway path, to Anthropic and to third-party services such as GitHub: version checks, telemetry, release notes, and similar requests. On a network that only allows egress to the gateway, these requests fail and can appear as blocked connections in your egress monitoring.

363 363 

364Claude Code attaches a credential to a telemetry or usage-metrics request only when the request goes to the host the credential belongs to. While `ANTHROPIC_BASE_URL` points at the gateway, Claude Code sends its telemetry events to Anthropic without your gateway credential. With a [credential variable](#set-the-credential-variable) or `apiKeyHelper` also active, Claude Code doesn't report usage metrics to the Console [analytics dashboard](https://code.claude.com/docs/en/analytics.md#access-analytics-for-api-customers). Before v2.1.246, Claude Code could attach the gateway credential to telemetry and usage-metrics requests bound for Anthropic hosts; model requests always went to the gateway with the credential the gateway expects.

365 

366To turn that traffic off, set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` alongside the gateway variables, in the same shell exports or settings-file `env` block:364To turn that traffic off, set `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` alongside the gateway variables, in the same shell exports or settings-file `env` block:

367 365 

368**Bash or Zsh**366**Bash or Zsh**

mcp.md +8 −2

Details

84 84 

85Only an SDK host application, such as an [Agent SDK](https://code.claude.com/docs/en/agent-sdk/mcp.md) application or the [desktop app](https://code.claude.com/docs/en/desktop.md), can register an in-process `"type": "sdk"` server. Claude Code skips a `"type": "sdk"` entry in `.mcp.json`, `~/.claude.json`, or settings and reports `Skipped — MCP server "<name>" declares type "sdk", which only an SDK host application can register`.85Only an SDK host application, such as an [Agent SDK](https://code.claude.com/docs/en/agent-sdk/mcp.md) application or the [desktop app](https://code.claude.com/docs/en/desktop.md), can register an in-process `"type": "sdk"` server. Claude Code skips a `"type": "sdk"` entry in `.mcp.json`, `~/.claude.json`, or settings and reports `Skipped — MCP server "<name>" declares type "sdk", which only an SDK host application can register`.

86 86 

87In `--output-format stream-json` runs, Claude Code also reports a skipped `--mcp-config` entry in the `system/init` event's [`mcp_server_errors` field](https://code.claude.com/docs/en/headless#stream-responses), so scripts can detect that the server never loaded. This requires Claude Code v2.1.219 or later.87> [!NOTE]

88>

89> In `--output-format stream-json` runs, Claude Code also reports a skipped `--mcp-config` entry in the `system/init` event's [`mcp_server_errors` field](https://code.claude.com/docs/en/headless#stream-responses), so scripts can detect that the server never loaded.

88 90 

89### Option 2: Add a remote SSE server91### Option 2: Add a remote SSE server

90 92 


276 278 

277When you select **Disable** or **Clear authentication** from a server's menu in `/mcp`, Claude Code also discards that server's cache entry. **Reconnect** discards it too on a connected or failed server; on a `cached` server, **Reconnect** connects the server now and keeps the entry. The next time Claude Code connects to the server after discarding the entry, it fetches the tool list from the server instead of from the cache.279When you select **Disable** or **Clear authentication** from a server's menu in `/mcp`, Claude Code also discards that server's cache entry. **Reconnect** discards it too on a connected or failed server; on a `cached` server, **Reconnect** connects the server now and keeps the entry. The next time Claude Code connects to the server after discarding the entry, it fetches the tool list from the server instead of from the cache.

278 280 

279When a server's status is `✘ Failed to connect`, `claude mcp list` appends the failure detail to that status line, and `claude mcp get <name>` shows it on an `Issue:` line: the HTTP status or error code, plus any error text the server returned. The server's detail view in `/mcp` includes the same server-reported text in its `Issue:` row. Claude Code redacts credential-like text from this detail and never includes the expanded server URL, which can carry secrets. Claude Code appends no detail to a `✘ Connection error` status, because the exception text it would print there can embed that URL. Before v2.1.219, both commands showed only the bare failure status, without the status code or the server's error text.281##### Connection failures and unconfigured servers

282 

283When a server's status is `✘ Failed to connect`, `claude mcp list` appends the failure detail to that status line, and `claude mcp get <name>` shows it on an `Issue:` line. The detail is the HTTP status or error code, plus any error text the server returned. The server's detail view in `/mcp` includes the same server-reported text in its `Issue:` row.

284 

285Claude Code redacts credential-like text from this detail and never includes the expanded server URL, which can carry secrets. Claude Code appends no detail to a `✘ Connection error` status, because the exception text it would print there can embed that URL.

280 286 

281When you complete authentication from `/mcp` and the connection still fails with an HTTP status or a transport error code, Claude Code adds that code and the origin of the server's URL to the message it prints after the attempt. The origin is the scheme and host, plus the port when the URL names one, such as `https://mcp.example.com`.287When you complete authentication from `/mcp` and the connection still fails with an HTTP status or a transport error code, Claude Code adds that code and the origin of the server's URL to the message it prints after the attempt. The origin is the scheme and host, plus the port when the URL names one, such as `https://mcp.example.com`.

282 288 

memory.md +2 −2

Details

237 237 

238Each brace group multiplies the number of expanded patterns: `src/*.{ts,tsx}` expands to two patterns, and `{a,b}/{c,d}/*.{ts,tsx}` to eight. To keep expansion bounded, a rule's whole `paths` list shares one budget of 1,000 expanded patterns and 4 MiB, and patterns without braces don't count against it.238Each brace group multiplies the number of expanded patterns: `src/*.{ts,tsx}` expands to two patterns, and `{a,b}/{c,d}/*.{ts,tsx}` to eight. To keep expansion bounded, a rule's whole `paths` list shares one budget of 1,000 expanded patterns and 4 MiB, and patterns without braces don't count against it.

239 239 

240Claude Code uses any pattern that would exceed the budget unexpanded, and its literal braces match no files. Before v2.1.217, a `paths` value with many brace groups stalled or crashed the CLI at startup.240Claude Code uses any pattern that would exceed the budget unexpanded, and its literal braces match no files.

241 241 

242Glob syntax treats `[` as the start of a bracket expression such as `[abc]`. A pattern with a `[` that can't be read as a bracket expression, such as `photos [2024/**`, is invalid: it matches nothing, and the rule's other patterns keep working. To match a literal `[` in a file name, escape it as `photos \[2024/**`.242Glob syntax treats `[` as the start of a bracket expression such as `[abc]`. A pattern with a `[` that can't be read as a bracket expression, such as `photos [2024/**`, is invalid: it matches nothing, and the rule's other patterns keep working. To match a literal `[` in a file name, escape it as `photos \[2024/**`.

243 243 


568 568 

569The `/memory` command lists your CLAUDE.md, CLAUDE.local.md, and other memory file locations across user and project scopes, including user and project CLAUDE.md entries for files that don't exist yet. It also lets you toggle auto memory on or off and provides an option to open the auto memory folder. Select any file to open it in your editor; selecting one that doesn't exist yet creates it first. To check which `CLAUDE.md` and rules files loaded at launch, run `/context`.569The `/memory` command lists your CLAUDE.md, CLAUDE.local.md, and other memory file locations across user and project scopes, including user and project CLAUDE.md entries for files that don't exist yet. It also lets you toggle auto memory on or off and provides an option to open the auto memory folder. Select any file to open it in your editor; selecting one that doesn't exist yet creates it first. To check which `CLAUDE.md` and rules files loaded at launch, run `/context`.

570 570 

571GUI editors such as VS Code open the file in a separate window, and you can keep using the session while it's open. Before v2.1.216, `/memory` waited for you to close the file before responding. Terminal editors such as Vim take over the terminal until you exit.571GUI editors such as VS Code open the file in a separate window, and you can keep using the session while it's open. Terminal editors such as Vim take over the terminal until you exit.

572 572 

573When you ask Claude to remember something, like "always use pnpm, not npm" or "remember that the API tests require a local Redis instance," Claude saves it to auto memory. To add instructions to CLAUDE.md instead, ask Claude directly, like "add this to CLAUDE.md," or edit the file yourself via `/memory`.573When you ask Claude to remember something, like "always use pnpm, not npm" or "remember that the API tests require a local Redis instance," Claude saves it to auto memory. To add instructions to CLAUDE.md instead, ask Claude directly, like "add this to CLAUDE.md," or edit the file yourself via `/memory`.

574 574 

model-config.md +21 −4

Details

542A different level applies in cases such as these:542A different level applies in cases such as these:

543 543 

544* **Your own change**: once you choose an effort level, pick a model in `/model`, or resume the session later, the flagged request's level no longer carries over.544* **Your own change**: once you choose an effort level, pick a model in `/model`, or resume the session later, the flagged request's level no longer carries over.

545* **Skill effort**: a level that a skill's `effort` frontmatter set for the flagged request applies to that turn, and later turns run at the level the [effort resolution order](#adjust-effort-level) gives the fallback model.545* **Effort set for one turn**: if you raised the flagged turn with `ultrathink`, or a skill's `effort` frontmatter set its level, that level applies to that turn. Later turns run at the level the [effort resolution order](#adjust-effort-level) gives the fallback model.

546 546 

547In the session, run `/effort status` to see the level in effect, or `/effort` to change it.547In the session, run `/effort status` to see the level in effect, or `/effort` to change it.

548 548 


674 674 

675#### Use ultrathink for one-off deep reasoning675#### Use ultrathink for one-off deep reasoning

676 676 

677Include `ultrathink` anywhere in your prompt to request deeper reasoning on that turn without changing your session effort setting. Claude Code recognizes the keyword and adds an in-context instruction. The effort level sent to the API is unchanged. Claude Code passes other phrases such as "think", "think hard", and "think more" through as ordinary prompt text and doesn't recognize them as keywords.677Include `ultrathink` anywhere in your prompt to request deeper reasoning on that turn without changing your session effort setting. Claude Code recognizes the keyword and adds an in-context instruction. Claude Code passes other phrases such as "think", "think hard", and "think more" through as ordinary prompt text and doesn't recognize them as keywords.

678 

679Typed in the terminal prompt, the word can also raise that turn to `xhigh` effort. When it can, the word shows in rainbow colors. Requires Claude Code v2.1.311 or later. If the word isn't rainbow when you start a new turn, try one of these:

680 

681* Retype it outside anything such as quotes, brackets, a path, or a command, in a prompt that doesn't start with `/`

682* Unset `CLAUDE_CODE_EFFORT_LEVEL` if it's set below `xhigh`, raise your own [`maxEffortLevel`](https://code.claude.com/docs/en/settings-reference#maxeffortlevel) to `xhigh` or above, or ask an organization admin to raise your [organization's limit](#organization-effort-limits)

683* Run `/model` in your session to switch to an Opus 5.5, Sonnet 5.5, Haiku 5.5, or Fable 5.1 model. Where the word can't raise a turn, such as on Amazon Bedrock, [set the effort level](#set-the-effort-level) instead

678 684 

679#### Set the effort level685#### Set the effort level

680 686 

681You can change effort through any of the following:687You can change effort through any of the following:

682 688 

683* **`/effort`**: run `/effort` with no arguments to open an interactive slider, `/effort` followed by a level name to set it directly, or `/effort auto` to clear your saved level for the active model. You can run it while Claude is working, and once you confirm the [cache warning](https://code.claude.com/docs/en/prompt-caching.md#changing-effort-level), if Claude Code shows one, Claude Code applies the new level to the next request in the turn689* **`/effort`**: run `/effort` with no arguments to open an interactive slider, `/effort` followed by a level name to set it directly, or `/effort auto` to clear your saved level for the active model

684* **In `/model`**: use left/right arrow keys to adjust the effort slider when selecting a model690* **In `/model`**: use left/right arrow keys to adjust the effort slider when selecting a model

685* **`--effort` flag**: pass a level name to set it for a single session when launching Claude Code691* **`--effort` flag**: pass a level name to set it for a single session when launching Claude Code

686* **Environment variable**: set `CLAUDE_CODE_EFFORT_LEVEL` to a level name or `auto`692* **Environment variable**: set `CLAUDE_CODE_EFFORT_LEVEL` to a level name or `auto`


692 698 

693If you set `effortLevel` in [managed settings](https://code.claude.com/docs/en/managed-settings.md), Claude Code applies it at the settings step of the [effort resolution order](#adjust-effort-level), and users can still change the level with `/effort` or `--effort`. To keep users at or below a level, set [`maxEffortLevel`](https://code.claude.com/docs/en/settings-reference#maxeffortlevel).699If you set `effortLevel` in [managed settings](https://code.claude.com/docs/en/managed-settings.md), Claude Code applies it at the settings step of the [effort resolution order](#adjust-effort-level), and users can still change the level with `/effort` or `--effort`. To keep users at or below a level, set [`maxEffortLevel`](https://code.claude.com/docs/en/settings-reference#maxeffortlevel).

694 700 

695The effort slider appears in `/model` when a supported model is selected. The current effort level is also shown in the session header next to the model name, for example "with low effort", so you can confirm which setting is active without opening `/model`. The footer also briefly shows the effort level at startup and when it changes.701#### Check the effort level you set

702 

703The effort slider appears in `/model` when a supported model is selected. A level in the session header, for example "with low effort", comes from your effort setting, even if Claude is [still working at the old level](#when-a-new-effort-level-starts). The footer also briefly shows the effort level at startup and when it changes.

704 

705#### When a new effort level starts

706 

707In a terminal session, once `/effort` confirms the new level, the next message you send runs at that level. You can send it after the turn in progress ends or [while Claude is still working](https://code.claude.com/docs/en/interactive-mode.md#queue-messages-while-claude-works):

708 

709* **After the turn ends**: you don't have to do anything until then, and it's expected if the turn finishes at the old level

710* **While Claude is still working**: type a message, such as `keep going`, and press `Enter` to queue it without interrupting the turn. Claude gets it when its current tool calls finish, or when the turn ends at the latest, and works at the new level from then on.

711 

712Before v2.1.242, Claude Code could queue `/effort` itself until the turn finished, and always did in a session that doesn't [fetch feature flags](https://code.claude.com/docs/en/env-vars.md#features-that-need-feature-flag-fetching), such as on a [third-party provider](https://code.claude.com/docs/en/third-party-integrations.md).

696 713 

697#### Adaptive reasoning and fixed thinking budgets714#### Adaptive reasoning and fixed thinking budgets

698 715 

Details

648| `claude_code.code_edit_tool.decision` | Count of code editing tool permission decisions | none |648| `claude_code.code_edit_tool.decision` | Count of code editing tool permission decisions | none |

649| `claude_code.active_time.total` | Total active time | s |649| `claude_code.active_time.total` | Total active time | s |

650 650 

651When `prometheus` is the only exporter listed in `OTEL_METRICS_EXPORTER`, Claude Code omits the `USD`, `tokens`, and `s` units from the exported metrics so the scrape stays valid Prometheus text format. Metric names don't change, and configurations that combine exporters, such as `otlp,prometheus`, keep the units. Before v2.1.216, the Prometheus scrape included OpenMetrics-only `# UNIT` lines that some scrapers rejected.651When `prometheus` is the only exporter listed in `OTEL_METRICS_EXPORTER`, Claude Code omits the `USD`, `tokens`, and `s` units from the exported metrics so the scrape stays valid Prometheus text format. Metric names don't change, and configurations that combine exporters, such as `otlp,prometheus`, keep the units.

652 652 

653### Metric details653### Metric details

654 654 


995 995 

996 The `source` value doesn't indicate which of these sources matched. To find which one refused a call, look for the [Safety event](#safety-event) with the same `tool_use_id` and read its `category` and `rule_source` attributes. Some refused calls [have no safety event](#calls-without-a-safety-event).996 The `source` value doesn't indicate which of these sources matched. To find which one refused a call, look for the [Safety event](#safety-event) with the same `tool_use_id` and read its `category` and `rule_source` attributes. Some refused calls [have no safety event](#calls-without-a-safety-event).

997 997 

998 Claude Code also reports `"config"` when the permission prompt request itself fails. For example, that request fails when the Agent SDK's [`canUseTool`](https://code.claude.com/docs/en/agent-sdk/typescript#canusetool) callback or the [`--permission-prompt-tool`](https://code.claude.com/docs/en/cli-reference#cli-flags) tool returns an invalid result, or when the input stream closes while the request is pending. Before v2.1.216, Claude Code reported these failures as `"user_reject"`.998 Claude Code also reports `"config"` when the permission prompt request itself fails. For example, that request fails when the Agent SDK's [`canUseTool`](https://code.claude.com/docs/en/agent-sdk/typescript#canusetool) callback or the [`--permission-prompt-tool`](https://code.claude.com/docs/en/cli-reference#cli-flags) tool returns an invalid result, or when the input stream closes while the request is pending.

999 * `"hook"`: A `PreToolUse` or `PermissionRequest` hook returned the decision.999 * `"hook"`: A `PreToolUse` or `PermissionRequest` hook returned the decision.

1000 * `"user_permanent"`: Emitted when the user chose "Yes, and don't ask again for ..." at a permission prompt, which saves an allow rule to their personal settings. In the interactive CLI this is emitted only for that choice itself; later calls that match the saved rule emit `"config"` instead. In Agent SDK or non-interactive `-p` sessions, both the initial choice and later rule matches emit `"user_permanent"`. Treated as an accept.1000 * `"user_permanent"`: Emitted when the user chose "Yes, and don't ask again for ..." at a permission prompt, which saves an allow rule to their personal settings. In the interactive CLI this is emitted only for that choice itself; later calls that match the saved rule emit `"config"` instead. In Agent SDK or non-interactive `-p` sessions, both the initial choice and later rule matches emit `"user_permanent"`. Treated as an accept.

1001 * `"user_temporary"`: Emitted when the user chose "Yes" at a permission prompt for a one-time approval, or chose an option that grants access for the rest of the session on a file edit or read prompt. In the interactive CLI this is emitted only for the choice itself; later calls allowed by that session-scoped grant emit `"config"` instead. In Agent SDK or non-interactive `-p` sessions, both the choice and later matches emit `"user_temporary"`. Treated as an accept.1001 * `"user_temporary"`: Emitted when the user chose "Yes" at a permission prompt for a one-time approval, or chose an option that grants access for the rest of the session on a file edit or read prompt. In the interactive CLI this is emitted only for the choice itself; later calls allowed by that session-scoped grant emit `"config"` instead. In Agent SDK or non-interactive `-p` sessions, both the choice and later matches emit `"user_temporary"`. Treated as an accept.

1002 * `"user_abort"`: Emitted when the user dismissed the permission prompt without answering. In Agent SDK and non-interactive `-p` sessions, this includes interrupting the turn while a `canUseTool` or `--permission-prompt-tool` permission request is pending; before v2.1.216, Claude Code reported that interrupt as `"user_reject"`. Treated as a reject.1002 * `"user_abort"`: Emitted when the user dismissed the permission prompt without answering. In Agent SDK and non-interactive `-p` sessions, this includes interrupting the turn while a `canUseTool` or `--permission-prompt-tool` permission request is pending. Treated as a reject.

1003 * `"user_reject"`: Emitted when the user chose "No" when prompted. In the interactive CLI this is emitted only for that choice itself; calls that match a deny rule in the user's personal settings emit `"config"` instead. In Agent SDK or non-interactive `-p` sessions, calls that match a deny rule in personal settings emit `"user_reject"`. Treated as a reject.1003 * `"user_reject"`: Emitted when the user chose "No" when prompted. In the interactive CLI this is emitted only for that choice itself; calls that match a deny rule in the user's personal settings emit `"config"` instead. In Agent SDK or non-interactive `-p` sessions, calls that match a deny rule in personal settings emit `"user_reject"`. Treated as a reject.

1004* `classifier_verdict`: The auto mode [classifier](https://code.claude.com/docs/en/permission-modes.md#how-the-classifier-evaluates-actions) verdict for the call, or why Claude Code denied the call when none came. Requires Claude Code v2.1.301 or later1004* `classifier_verdict`: The auto mode [classifier](https://code.claude.com/docs/en/permission-modes.md#how-the-classifier-evaluates-actions) verdict for the call, or why Claude Code denied the call when none came. Requires Claude Code v2.1.301 or later

1005 1005 

Details

97 The command also works in [non-interactive mode](https://code.claude.com/docs/en/headless.md) and Agent SDK sessions, and from the mobile app or web via [Remote Control](https://code.claude.com/docs/en/remote-control.md#limitations), where you can list and select only [built-in styles](#built-in-output-styles). Requires Claude Code v2.1.269 or later.97 The command also works in [non-interactive mode](https://code.claude.com/docs/en/headless.md) and Agent SDK sessions, and from the mobile app or web via [Remote Control](https://code.claude.com/docs/en/remote-control.md#limitations), where you can list and select only [built-in styles](#built-in-output-styles). Requires Claude Code v2.1.269 or later.

98* **Terminal menu**: run `/config` and select **Output style** to pick a style from a menu.98* **Terminal menu**: run `/config` and select **Output style** to pick a style from a menu.

99* **VS Code extension**: open the [command menu](https://code.claude.com/docs/en/vs-code.md#use-the-prompt-box) with `/` and select **Output styles** to pick a style, including your custom styles. Requires Claude Code v2.1.257 or later.99* **VS Code extension**: open the [command menu](https://code.claude.com/docs/en/vs-code.md#use-the-prompt-box) with `/` and select **Output styles** to pick a style, including your custom styles. Requires Claude Code v2.1.257 or later.

100* **Desktop app**: set the `outputStyle` field in a settings file, for example `.claude/settings.local.json`, the file the terminal menu writes. When you run `/config` there, Claude Code [opens **Settings > Claude Code**](https://code.claude.com/docs/en/desktop.md#what’s-not-available-in-desktop) rather than a menu.100* **Desktop app**: set the `outputStyle` field in a settings file, for example `.claude/settings.local.json`, the file the terminal menu writes. When you run `/config` there, Claude Code [opens **Settings > Code** or **Settings > Claude Code**](https://code.claude.com/docs/en/desktop.md#what’s-not-available-in-desktop) rather than a menu.

101 101 

102To set a style without the menu, edit the `outputStyle` field directly in a settings file:102To set a style without the menu, edit the `outputStyle` field directly in a settings file:

103 103 

Details

31 31 

32### Actions no mode auto-approves32### Actions no mode auto-approves

33 33 

34Claude Code doesn't auto-approve the following in any mode, including `bypassPermissions`. Each bullet links to the section that says what happens instead in each mode:34Claude Code doesn't auto-approve the following in any mode, including `bypassPermissions`, though you can [turn off the prompt for dangerous `rm` commands](#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode) in `bypassPermissions` mode. Each bullet links to the section that says what happens instead in each mode:

35 35 

36* Tools matched by an explicit [ask rule](https://code.claude.com/docs/en/permissions.md#manage-permissions)36* Tools matched by an explicit [ask rule](https://code.claude.com/docs/en/permissions.md#manage-permissions)

37* Connector tools your organization [set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), in sessions where that setting reaches Claude Code37* Connector tools your organization [set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), in sessions where that setting reaches Claude Code


504* Read-only HTTP requests504* Read-only HTTP requests

505* Pushing to any branch of the repository you're working in, including the default branch. A non-default branch whose name marks it as a deploy or publication target, such as `production` or `gh-pages`, isn't covered: the classifier judges a push there on its own terms.505* Pushing to any branch of the repository you're working in, including the default branch. A non-default branch whose name marks it as a deploy or publication target, such as `production` or `gh-pages`, isn't covered: the classifier judges a push there on its own terms.

506 506 

507 A push's content is still checked against the classifier's other rules, and [`permissions.deny` rules](https://code.claude.com/docs/en/permissions#manage-permissions) can still block push commands [as written](https://code.claude.com/docs/en/permissions.md#bash-rule-limits) in every mode. The remote's own branch protection still applies. From v2.1.203 until v2.1.211, only routine default-branch pushes and pushes to the branch you started on or to branches Claude created were allowed by default.507 A push's content is still checked against the classifier's other rules, and [`permissions.deny` rules](https://code.claude.com/docs/en/permissions#manage-permissions) can still block push commands [as written](https://code.claude.com/docs/en/permissions.md#bash-rule-limits) in every mode. The remote's own branch protection still applies.

508* Deleting the exact jobs Claude created earlier in the same session508* Deleting the exact jobs Claude created earlier in the same session

509* Reading, reviewing, or writing security-related code, configs, and threat models as part of your task509* Reading, reviewing, or writing security-related code, configs, and threat models as part of your task

510* Messages between agents working together in the same multi-agent session510* Messages between agents working together in the same multi-agent session


649 649 

650`bypassPermissions` mode disables permission prompts and safety checks so tool calls execute immediately, including writes to [protected paths](#protected-paths).650`bypassPermissions` mode disables permission prompts and safety checks so tool calls execute immediately, including writes to [protected paths](#protected-paths).

651 651 

652Even in `bypassPermissions` mode, each of the [actions no mode auto-approves](#actions-no-mode-auto-approves) gets a prompt or a denial instead of running on its own. Reading [another organization's public artifact](https://code.claude.com/docs/en/artifacts.md#read-an-artifact-shared-with-you) needs your approval, and this mode doesn't ask for it, so Claude can't read one. The [Remove-Item in PowerShell](#remove-item-in-powershell) denies also apply in this mode.652Even in `bypassPermissions` mode, each of the [actions no mode auto-approves](#actions-no-mode-auto-approves) gets a prompt or a denial, though you can [turn off the prompt for dangerous `rm` commands](#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode). Reading [another organization's public artifact](https://code.claude.com/docs/en/artifacts.md#read-an-artifact-shared-with-you) needs your approval, and this mode doesn't ask for it, so Claude can't read one. The [Remove-Item in PowerShell](#remove-item-in-powershell) denies also apply in this mode.

653 653 

654Two [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md) safeguards still apply in this mode, and in interactive terminal plan-mode sessions where bypass permissions are available:654Two [cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging.md) safeguards still apply in this mode, and in interactive terminal plan-mode sessions where bypass permissions are available:

655 655 


861This command could not be checked for dangerous rm operations: the shell may read it differently than it was parsed.861This command could not be checked for dangerous rm operations: the shell may read it differently than it was parsed.

862```862```

863 863 

864You get the prompt or denial a critical-path removal gets [in your permission mode](#critical-path-removals-in-each-permission-mode), `bypassPermissions` included. You can't approve the command with a `Bash` or `Bash(*)` allow rule, sandbox [auto-allow mode](https://code.claude.com/docs/en/sandboxing.md#auto-allow-mode), or a `PreToolUse` hook returning `"allow"`. Read the command, then approve the prompt or, after a denial, run it in your shell.864You get the prompt or denial a critical-path removal gets [in your permission mode](#critical-path-removals-in-each-permission-mode), `bypassPermissions` included, though you can [turn off that prompt](#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode) in `bypassPermissions` mode. You can't approve the command with a `Bash` or `Bash(*)` allow rule, sandbox [auto-allow mode](https://code.claude.com/docs/en/sandboxing.md#auto-allow-mode), or a `PreToolUse` hook returning `"allow"`. Read the command, then approve the prompt or, after a denial, run it in your shell.

865 865 

866### The mounted drive prompt866### The mounted drive prompt

867 867 


923 923 

924If an explicit [ask rule](https://code.claude.com/docs/en/permissions.md#manage-permissions) matches the command, Claude Code asks you instead, even in `auto` mode and without a time limit. In modes that ask, a [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) can answer the prompt.924If an explicit [ask rule](https://code.claude.com/docs/en/permissions.md#manage-permissions) matches the command, Claude Code asks you instead, even in `auto` mode and without a time limit. In modes that ask, a [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) can answer the prompt.

925 925 

926To run these removals with no prompt in `bypassPermissions` mode, see [Turn off the critical-path removal prompt](#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode).

927 

926### Time limits and denials in auto and bypassPermissions modes928### Time limits and denials in auto and bypassPermissions modes

927 929 

928In `auto` and `bypassPermissions` modes, the terminal prompt for a critical-path removal shows a two-minute countdown:930In `auto` and `bypassPermissions` modes, the terminal prompt for a critical-path removal shows a two-minute countdown:


939| :- | :- | :- |941| :- | :- | :- |

940| [VS Code extension](https://code.claude.com/docs/en/vs-code.md)'s chat panel | Denies it | Denies it unless a [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) allows it |942| [VS Code extension](https://code.claude.com/docs/en/vs-code.md)'s chat panel | Denies it | Denies it unless a [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) allows it |

941| [Desktop app](https://code.claude.com/docs/en/desktop.md) | Denies it | Denies it unless a `PermissionRequest` hook allows it |943| [Desktop app](https://code.claude.com/docs/en/desktop.md) | Denies it | Denies it unless a `PermissionRequest` hook allows it |

942| [`-p` run](https://code.claude.com/docs/en/headless) or [Agent SDK session](https://code.claude.com/docs/en/agent-sdk/permissions.md) | Denies it | Your [`--permission-prompt-tool`](https://code.claude.com/docs/en/cli-reference#cli-flags) or [`canUseTool` callback](https://code.claude.com/docs/en/agent-sdk/user-input#handle-tool-approval-requests) decides. With neither, or under [`--permission-prompts none`](https://code.claude.com/docs/en/headless#turn-off-permission-prompts-in-unattended-runs), denies it unless a `PermissionRequest` hook allows it |944| [`-p` run](https://code.claude.com/docs/en/headless) or [Agent SDK session](https://code.claude.com/docs/en/agent-sdk/permissions.md) | Denies it | Your [`--permission-prompt-tool`](https://code.claude.com/docs/en/cli-reference#cli-flags) or [`canUseTool` callback](https://code.claude.com/docs/en/agent-sdk/user-input#handle-tool-approval-requests) decides. With neither, or under [`--permission-prompts none`](https://code.claude.com/docs/en/headless#turn-off-permission-prompts-in-unattended-runs), denies it unless a `PermissionRequest` hook allows it. To run these removals with no prompt instead, see [Turn off the critical-path removal prompt](#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode) |

943 945 

944Wherever the removal is denied, you can read the whole command and run it in your shell.946Wherever the removal is denied, you can read the whole command and run it in your shell.

945 947 


958}960}

959```961```

960 962 

963### Turn off the critical-path removal prompt in bypassPermissions mode

964 

965To run Bash `rm` and `rmdir` commands that target [critical paths](#critical-paths) with no prompt in `bypassPermissions` mode, start Claude Code with [`CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS=1`](https://code.claude.com/docs/en/env-vars#variables) in its environment. This requires Claude Code v2.1.311 or later. Claude Code reads the variable from the launch environment only and [ignores it in a settings file's `env` block](https://code.claude.com/docs/en/settings-reference#variables-claude-code-ignores-in-env). For example, set it in [your shell](https://code.claude.com/docs/en/env-vars.md#set-variables-in-your-shell) and start `claude` from there:

966 

967**macOS, Linux, WSL**

968 

969```bash theme={null}

970export CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS=1

971claude --permission-mode bypassPermissions

972```

973 

974**Windows PowerShell**

975 

976```powershell theme={null}

977$env:CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS = "1"

978claude --permission-mode bypassPermissions

979```

980 

981**Windows CMD**

982 

983```batch theme={null}

984set CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS=1

985claude --permission-mode bypassPermissions

986```

987 

988> [!WARNING]

989>

990> With this variable set, you lose a safety prompt for destructive deletes: a command such as `rm -rf ~` can run without asking you. Set it only in an [isolated environment](#skip-all-checks-with-bypasspermissions-mode) whose contents you can afford to lose.

991 

992Removals run with no prompt only in `bypassPermissions` mode itself, not in plan mode, and only for what the critical-path check flags in the Bash and [Monitor](https://code.claude.com/docs/en/tools-reference.md#monitor-tool) tools. That includes commands Claude Code can't fully parse, which also run with no prompt.

993 

994#### Startup notices about the critical-path removal prompt

995 

996To check whether `CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS` is working, read the line Claude Code prints at startup. In a `-p` run, it's on stderr. In an Agent SDK app, pass the [`stderr` option](https://code.claude.com/docs/en/agent-sdk/typescript#options) to read it. The line says one of these:

997 

998* **`is set, so dangerous rm commands can run without a prompt`**: removals can run with no prompt once managed settings and plugin hooks have loaded. If removals keep getting a prompt or denial, see [Why the critical-path removal prompt stays on](#why-the-critical-path-removal-prompt-stays-on)

999* **`has no effect in this session`**: removals keep their usual prompt or denial for the whole session. To change that, find your case under [Why the critical-path removal prompt stays on](#why-the-critical-path-removal-prompt-stays-on)

1000* **`has no effect while the Windows registry cannot be read for managed settings`**: removals keep their usual prompt or denial, and the variable takes effect with no restart if a later read of the registry succeeds. If removals keep getting a prompt or denial, see [Why the critical-path removal prompt stays on](#why-the-critical-path-removal-prompt-stays-on)

1001 

1002A missing line doesn't mean the prompt is on: an Agent SDK app with no `stderr` option sees no line, and removals can still run with no prompt. Otherwise, check that you set the variable in the launch environment, that the session [can enter `bypassPermissions` mode](#skip-all-checks-with-bypasspermissions-mode), and that `claude` isn't inside another session. Some sessions [start without the variable](#why-the-critical-path-removal-prompt-stays-on).

1003 

1004If you see one of these lines and didn't set the variable, find where it's set, such as your shell profile, and remove it.

1005 

1006#### Why the critical-path removal prompt stays on

1007 

1008If `CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS` has no effect and removals keep their [usual prompt or denial](#critical-path-removals-in-each-permission-mode), check for causes such as these:

1009 

1010* **Something else handles permission prompts**: a [`--permission-prompt-tool`](https://code.claude.com/docs/en/cli-reference#cli-flags) or an Agent SDK [`canUseTool` callback](https://code.claude.com/docs/en/agent-sdk/user-input) without [`--permission-prompts none`](https://code.claude.com/docs/en/headless#turn-off-permission-prompts-in-unattended-runs), a [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) with any matcher, or a [mod](https://code.claude.com/docs/en/plugins/mods/events.md#hook-the-settings-hook-events) that handles that event. Remove the hook, mod, tool, or callback and restart `claude`

1011* **The [VS Code extension](https://code.claude.com/docs/en/vs-code.md)'s chat panel or the [Desktop app](https://code.claude.com/docs/en/desktop.md) runs the session**: start `claude` in a terminal instead, such as an IDE's integrated terminal

1012* **A rule covers Bash, Edit, or Read**: a [deny or ask rule](https://code.claude.com/docs/en/permissions.md#manage-permissions) that targets one of these tools, at launch or once Claude Code reads it during the session, even if you remove it later. Remove the rule and restart `claude`. To leave a tool out, use [`--tools`](https://code.claude.com/docs/en/cli-reference#cli-flags) instead of a deny rule

1013* **[`permissions.blockReadsOutsideWorkingDirectories`](https://code.claude.com/docs/en/settings-reference#permissions-blockreadsoutsideworkingdirectories) is on**: remove the setting from every settings file that sets it to `true`, then restart `claude`

1014* **`claude` runs inside another session**: a `claude` started from a session's Bash tool or a hook, even with the variable on its command line. Start `claude` from your own shell. Don't rely on this nested-session limit as a security boundary

1015* **A `PreToolUse` hook answers `ask` for a removal**: change what the hook returns

1016* **Claude Code starts the session for you**: [background sessions](https://code.claude.com/docs/en/agent-view.md), [agent team](https://code.claude.com/docs/en/agent-teams.md) teammates in split panes, and sessions a [Remote Control](https://code.claude.com/docs/en/remote-control.md) server creates start without the variable. Start `claude` from your own shell

1017* **Managed settings can't be read**: Claude Code hasn't successfully read your [managed settings](https://code.claude.com/docs/en/managed-settings.md) sources. If server-managed settings keep failing to load, see [Remote managed settings failed to load](https://code.claude.com/docs/en/errors.md#remote-managed-settings-failed-to-load). For any other failure that isn't a registry query, ask whoever manages that source to fix it

1018* **The Windows registry can't be queried**: on Windows and in WSL, the variable needs an answer from the registry, even when [WSL doesn't use it for settings](https://code.claude.com/docs/en/settings-reference.md#wslinheritswindowssettings). The query can fail all session on a non-English Windows, in WSL with interop off, or in a container on a WSL2 kernel. If interop is off, turn it on. Otherwise, run those removals yourself

1019 

961### Remove-Item in PowerShell1020### Remove-Item in PowerShell

962 1021 

963When you enable the [PowerShell tool](https://code.claude.com/docs/en/tools-reference.md#powershell-tool), Claude Code gives `Remove-Item` and the `cmd` built-ins `rd`, `rmdir`, `del`, and `erase` their own checks, separate from the `rm` critical-path list. For `Remove-Item`, the outcome depends on the target, and the first matching case applies:1022When you enable the [PowerShell tool](https://code.claude.com/docs/en/tools-reference.md#powershell-tool), Claude Code gives `Remove-Item` and the `cmd` built-ins `rd`, `rmdir`, `del`, and `erase` their own checks, separate from the `rm` critical-path list. For `Remove-Item`, the outcome depends on the target, and the first matching case applies:

permissions.md +11 −9

Details

28 28 

29When you choose "Yes, and don't ask again" and the approval saves permanently, such as for a Bash command or a WebFetch domain, Claude Code saves the rule to `.claude/settings.local.json` at the root of the git repository, resolved through [worktrees](https://code.claude.com/docs/en/worktrees.md) to the main checkout. The rule applies to future sessions anywhere in that repository, including sessions started in subdirectories and in worktrees. A file-modification approval isn't saved to the file: as the table shows, it lasts until the session ends. In some cases, such as outside a git repository or on Windows, Claude Code doesn't use the repository root; [Where Claude Code looks for each file](https://code.claude.com/docs/en/settings.md#where-claude-code-looks-for-each-file) lists those cases and where it saves the rule instead.29When you choose "Yes, and don't ask again" and the approval saves permanently, such as for a Bash command or a WebFetch domain, Claude Code saves the rule to `.claude/settings.local.json` at the root of the git repository, resolved through [worktrees](https://code.claude.com/docs/en/worktrees.md) to the main checkout. The rule applies to future sessions anywhere in that repository, including sessions started in subdirectories and in worktrees. A file-modification approval isn't saved to the file: as the table shows, it lasts until the session ends. In some cases, such as outside a git repository or on Windows, Claude Code doesn't use the repository root; [Where Claude Code looks for each file](https://code.claude.com/docs/en/settings.md#where-claude-code-looks-for-each-file) lists those cases and where it saves the rule instead.

30 30 

31Before v2.1.211, Claude Code always saved the rule in the starting directory, so an approval granted in a worktree or subdirectory didn't apply to the rest of the repository. Rules that earlier versions saved in a subdirectory or worktree still apply to sessions started there.

32 

33Sometimes a permission prompt offers only a one-time approval, with no "don't ask again" option and no option to allow the action for the rest of the session. Claude Code offers those options only when the prompt can show you everything they would allow, so a rule you save from a prompt covers only what its option named. When a prompt offers only the one-time approval, approve the action once, or add the rule yourself in [`/permissions`](#manage-permissions). To stop the prompts for a command that starts with an exec wrapper such as `watch`, or for a `find` command with an action such as `-delete`, see [Exec wrappers and `find` actions](#exec-wrappers-and-find-actions).31Sometimes a permission prompt offers only a one-time approval, with no "don't ask again" option and no option to allow the action for the rest of the session. Claude Code offers those options only when the prompt can show you everything they would allow, so a rule you save from a prompt covers only what its option named. When a prompt offers only the one-time approval, approve the action once, or add the rule yourself in [`/permissions`](#manage-permissions). To stop the prompts for a command that starts with an exec wrapper such as `watch`, or for a `find` command with an action such as `-delete`, see [Exec wrappers and `find` actions](#exec-wrappers-and-find-actions).

34 32 

35### Add a comment when you answer a permission prompt33### Add a comment when you answer a permission prompt


218 216 

219> [!TIP]217> [!TIP]

220>218>

221> Claude Code is aware of shell operators, so a rule like `Bash(safe-cmd *)` won't give it permission to run the command `safe-cmd && other-cmd`. The recognized command separators are `&&`, `||`, `;`, `|`, `|&`, `&`, and newlines. A rule must match each subcommand independently.219> Claude Code is aware of shell operators, so a rule like `Bash(safe-cmd *)` won't give it permission to run the command `safe-cmd && other-cmd`. The recognized command separators are `&&`, `||`, `;`, `|`, `|&`, `&`, and newlines. Every subcommand must be allowed for a compound command to run without a prompt, for example because the subcommand matches an allow rule or is a [read-only command](#read-only-commands).

222 220 

223Deny and ask rules apply when any subcommand matches them, including a command nested inside a subshell, a command substitution, or a control-flow body such as a `for` loop. An ask rule like `Bash(git clean *)` still prompts you for `cd /tmp && git clean -f` or `echo "$(git clean -f)"`, even in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode).221Deny and ask rules apply when any subcommand matches them, including a command nested inside a subshell, a command substitution, or a control-flow body such as a `for` loop. An ask rule like `Bash(git clean *)` still prompts you for `cd /tmp && git clean -f` or `echo "$(git clean -f)"`, even in [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode).

224 222 


314 312 

315### PowerShell313### PowerShell

316 314 

317PowerShell permission rules use the same shape as Bash rules. Wildcards with `*` match at any position, the `:*` suffix is equivalent to a trailing ` *`, and a bare `PowerShell` or `PowerShell(*)` matches every command. This configuration allows `Get-ChildItem` and `git commit` commands while blocking `Remove-Item`:315PowerShell permission rules use the same shape as [Bash rules](#wildcard-patterns), and a bare `PowerShell` or `PowerShell(*)` matches every command. This configuration allows `Get-ChildItem` and `git commit` commands while blocking `Remove-Item`:

318 316 

319```json theme={null}317```json theme={null}

320{318{


330}328}

331```329```

332 330 

333Common aliases are canonicalized before matching. A rule written for the cmdlet name also matches its aliases, so `PowerShell(Get-ChildItem *)` matches `gci`, `ls`, and `dir` as well. Matching is case-insensitive.331Common aliases are canonicalized before matching. A rule written for the cmdlet name also matches those aliases, so `PowerShell(Get-ChildItem *)` matches `gci`, `ls`, and `dir` as well. Matching is case-insensitive.

334 332 

335Claude Code parses the PowerShell AST and checks each command in a compound command independently. Pipeline operators `|`, statement separators `;`, and on PowerShell 7+ the chain operators `&&` and `||` split a compound command into subcommands. A rule must match every subcommand for the compound command to be allowed.333Claude Code parses the PowerShell AST and checks each command in a compound command independently. Pipeline operators `|`, statement separators `;`, and on PowerShell 7+ the chain operators `&&` and `||` split a compound command into subcommands. Every subcommand must be allowed for the compound command to run without a prompt, for example by matching an allow rule.

336 334 

337### Read and Edit335### Read and Edit

338 336 


390 388 

391A rule you add through `/permissions` follows the row for the settings file you save it to.389A rule you add through `/permissions` follows the row for the settings file you save it to.

392 390 

393Local settings rules anchor at the session's [primary working directory](#working-directories), not at the repository root where Claude Code [stores the file](#permission-system) in v2.1.211 and later. In a session started at the repository root, the two directories are the same; in a [worktree](https://code.claude.com/docs/en/worktrees.md) session, a shared rule such as `Edit(/src/**)` matches that worktree's own `src/` directory.391Local settings rules anchor at the session's [primary working directory](#working-directories), not at the repository root where Claude Code [stores the file](#permission-system). In a session started at the repository root, the two directories are the same; in a [worktree](https://code.claude.com/docs/en/worktrees.md) session, a shared rule such as `Edit(/src/**)` matches that worktree's own `src/` directory.

394 392 

395A deny rule such as `Read(/secrets/**)` in user settings blocks `~/.claude/secrets/**`, not a `secrets` directory in your project. To write a rule in user settings that applies inside every project, use a `//` absolute path or a `~/` home-relative path instead.393A deny rule such as `Read(/secrets/**)` in user settings blocks `~/.claude/secrets/**`, not a `secrets` directory in your project. To write a rule in user settings that applies inside every project, use a `//` absolute path or a `~/` home-relative path instead.

396 394 


524 522 

525To read files on a network share without this prompt, give the share a local path first:523To read files on a network share without this prompt, give the share a local path first:

526 524 

527* **Windows**: map the share to a drive letter and pass the drive with `--add-dir` when you launch Claude Code, as [Working directories](#working-directories) describes. Reads under a drive you add later with `/add-dir`, or list in `additionalDirectories` in a settings file, still prompt. To stop those prompts for a share mapped to `Z:`, start a new session in PowerShell with `claude --add-dir Z:\`.525* **Windows**: map the share to a drive letter and pass the drive with `--add-dir` when you launch Claude Code, as [Working directories](#working-directories) describes. For a share mapped to `Z:`, run `claude --add-dir Z:\` in PowerShell.

528* **macOS and Linux**: mount the share at a local path, such as a directory under `/mnt` or `/Volumes`, and read the files from there, as [Working directory is a network path](https://code.claude.com/docs/en/errors.md#working-directory-is-a-network-path) describes526* **macOS and Linux**: mount the share at a local path, such as a directory under `/mnt` or `/Volumes`, and read the files from there, as [Working directory is a network path](https://code.claude.com/docs/en/errors.md#working-directory-is-a-network-path) describes

529 527 

530### WebFetch528### WebFetch


711 709 

712To load the skills, commands, and subagents from a subdirectory of your [primary working directory](#working-directories) mid-session, run `/add-dir` with that subdirectory's path. Claude Code loads them for the rest of the session without prompting you or adding a working directory, because the subdirectory is already readable. This requires Claude Code v2.1.257 or later.710To load the skills, commands, and subagents from a subdirectory of your [primary working directory](#working-directories) mid-session, run `/add-dir` with that subdirectory's path. Claude Code loads them for the rest of the session without prompting you or adding a working directory, because the subdirectory is already readable. This requires Claude Code v2.1.257 or later.

713 711 

714Claude Code discovers output styles from the current working directory and its parents, your user directory at `~/.claude/`, and managed settings. Hooks and other `.claude/settings.json` keys load from the current working directory's `.claude/` folder with no parent-directory fallback, alongside your user `~/.claude/settings.json` and managed settings. `.claude/settings.local.json` loads from the git repository root instead, even when you start Claude Code in a subdirectory, except in the cases where Claude Code [doesn't use the repository root](https://code.claude.com/docs/en/settings.md#where-claude-code-looks-for-each-file), such as on Windows; before v2.1.211, it too loaded only from the current working directory. [Agent SDK](https://code.claude.com/docs/en/agent-sdk/claude-code-features.md#control-filesystem-settings-with-settingsources) sessions load it from the working directory in all versions.712#### Where output styles, hooks, and local settings load from

713 

714Claude Code discovers output styles from the current working directory and its parents, your user directory at `~/.claude/`, and managed settings. Hooks and other `.claude/settings.json` keys load from the current working directory's `.claude/` folder with no parent-directory fallback, alongside your user `~/.claude/settings.json` and managed settings.

715 

716`.claude/settings.local.json` loads from the git repository root instead, even when you start Claude Code in a subdirectory, except where Claude Code [doesn't use the repository root](https://code.claude.com/docs/en/settings.md#where-claude-code-looks-for-each-file), such as on Windows.

715 717 

716To share that configuration across projects, use one of these approaches:718To share that configuration across projects, use one of these approaches:

717 719 

Details

313 313 

314To see the tool calls that the API ran itself during the request, such as calls to the [advisor tool](https://code.claude.com/docs/en/advisor.md), read `result.serverToolUses`. Claude Code doesn't run these calls, so no `tool.call` or `tool.check` hook fires for them. The field is absent when the response has no such calls, and it requires Claude Code v2.1.290 or later.314To see the tool calls that the API ran itself during the request, such as calls to the [advisor tool](https://code.claude.com/docs/en/advisor.md), read `result.serverToolUses`. Claude Code doesn't run these calls, so no `tool.call` or `tool.check` hook fires for them. The field is absent when the response has no such calls, and it requires Claude Code v2.1.290 or later.

315 315 

316#### Send a request to a different model

317 

318If a `turn.step` request fails with a model error when `model` is an alias such as `haiku`, update to Claude Code v2.1.309 or later, or use a full model id. Before v2.1.309, an alias went out as written.

319 

320To send a request to a different model, pass `next` the event with `model` changed, as in `yield* next({ ...e, model: 'haiku' })`.

321 

316### Change or refuse a settings read322### Change or refuse a settings read

317 323 

318A `settings.read` hook runs on a mod's read and on Claude Code's own read:324Use a `settings.read` hook to change or refuse a settings read, either a mod's or Claude Code's own:

319 325 

320* **A mod's read**: a mod calls [`$.settings.read`](https://code.claude.com/docs/en/plugins/mods/api#read-one-source-or-one-key).326* **A mod's read**: a mod calls [`$.settings.read`](https://code.claude.com/docs/en/plugins/mods/api#read-one-source-or-one-key).

321* **Claude Code's own read**: Claude Code builds the session's merged settings. This read repeats when settings or the loaded plugins change.327* **Claude Code's own read**: your hook first runs when Claude Code merges the session's settings, after the session's mods have loaded. Your hook runs again when settings or loaded plugins change.

322 328 

323Before you rely on either read, check the guard and your version:329Check which mods get this event and your Claude Code version:

324 330 

325* **The built-in guard**: with managed settings, or with a Team or Enterprise [`/login`](https://code.claude.com/docs/en/authentication#authentication-precedence) as the session's credential, the [built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#know-what-happens-by-default) can skip this hook in a mod you install or load with `--plugin-dir`. To check, search the [debug log](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#read-the-debug-log) for `settings.read bypassed by cc-plugin-sec-default`. If a line with that text names your mod, ask your organization's administrator to [install the mod as one of the organization's mods](https://code.claude.com/docs/en/plugins/mods/admin.md#install-your-organizations-mods).331* **The built-in guard**: with managed settings, or with a Team or Enterprise [`/login`](https://code.claude.com/docs/en/authentication#authentication-precedence) as the session's credential, the [built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#know-what-happens-by-default) can skip this hook in a mod you install or load with `--plugin-dir`. To check, search the [debug log](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#read-the-debug-log) for `settings.read bypassed by cc-plugin-sec-default`. If a line with that text names your mod, ask your organization's administrator to [install the mod as one of the organization's mods](https://code.claude.com/docs/en/plugins/mods/admin.md#install-your-organizations-mods).

326* **The version**: the event firing on Claude Code's own read, and the `e.layers` field, require Claude Code v2.1.304 or later.332* **The version**: the event firing on Claude Code's own read, and the `e.layers` field, require Claude Code v2.1.304 or later.


336 342 

337#### Tell Claude Code's own read from a mod's read343#### Tell Claude Code's own read from a mod's read

338 344 

339On [Claude Code's own read](#settings-read-hook), [`next.origin`](https://code.claude.com/docs/en/plugins/mods/reference#the-hook-function) is `{ plugin: 'engine', tier: 'core' }`, and on a mod's read `next.origin.plugin` is the calling mod's name.345Check [`next.origin`](https://code.claude.com/docs/en/plugins/mods/reference#the-hook-function):

346 

347* **Claude Code's own read**: `{ plugin: 'engine', tier: 'core' }`

348* **A mod's read**: `plugin` is the calling mod's name

340 349 

341#### What a `settings.read` hook can return350#### What a `settings.read` hook can return

342 351 

343Your hook can return [`next(e)`](https://code.claude.com/docs/en/plugins/mods/reference#the-hook-function)'s result unchanged, a `{ value }` of its own, or `{ deny: reason }`. On [Claude Code's own read](#settings-read-hook) and a mod's read, a `{ value }` replaces what the read gives and `{ deny: reason }` refuses the read:352Return [`next(e)`](#settings-read-next)'s result unchanged to leave the read as it is, or return one of these:

344 353 

345| Return | On Claude Code's own read | On a mod's read |354| Return | On [Claude Code's own read](#settings-read-hook) | On a mod's read |

346| :- | :- | :- |355| :- | :- | :- |

347| `{ value }` | For each key you change, what you return replaces that key's whole value in the session's merged settings, if it [fits the key's schema](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#settings-read-key-refused) | That mod's call resolves to your `value`, or to the `key` it asked for taken from your `value`, so return a whole object and not an array |356| `{ value }` | For each key changed, you replace its whole value in the session's merged settings, if yours [fits the key's schema](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#settings-read-key-refused) | That mod's call resolves to your `value`, or to the `key` it asked for taken from your `value`, so return a whole object and not an array |

348| `{ deny: reason }` | The session keeps the settings as they were merged before any hook answered, and the [debug log records your `reason`](https://code.claude.com/docs/en/plugins/mods/troubleshoot#settings-read-refused) | That mod's call rejects with `<calling mod>: $.settings.read: <reason>` |357| `{ deny: reason }` | The session keeps the settings as they were merged before any hook answered, and the [debug log records your `reason`](https://code.claude.com/docs/en/plugins/mods/troubleshoot#settings-read-refused) | That mod's call rejects with `<calling mod>: $.settings.read: <reason>` |

349 358 

350On Claude Code's own read, build your `{ value }` from [`next(e)`'s `value`](#settings-read-next), since a key you leave out is unset. Where Claude Code reads a key such as `env` from each source separately, changing it in your `value` [has no effect](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#settings-read-key-no-effect).359On Claude Code's own read, build your `{ value }` from [`next(e)`'s `value`](#settings-read-next), since a key you leave out is unset. Where Claude Code reads a key such as `env` from each source separately, changing it in your `value` [has no effect](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#settings-read-key-no-effect).


373})382})

374```383```

375 384 

376On Claude Code's own read, if your hook returns a value outside the key's schema, such as a string, that key alone keeps the value merged before any hook answered. The debug log then says [`the answer for <key> is no value the key can hold`](https://code.claude.com/docs/en/plugins/mods/troubleshoot#settings-read-key-refused). If your value fits and the key still doesn't change, see [why a returned key has no effect](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#settings-read-key-no-effect).385On Claude Code's own read, if your hook returns a value outside the key's schema, such as a string, that key alone keeps the value merged before any hook answered. The debug log then says [`the answer for <key> is no value the key can hold`](https://code.claude.com/docs/en/plugins/mods/troubleshoot#settings-read-key-refused). If your value fits and the key still doesn't change, see [why a key doesn't take effect](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#settings-read-key-no-effect).

377 386 

378### Handle the settings hook events387### Handle the settings hook events

379 388 

Details

421Note: Type a note and press Enter421Note: Type a note and press Enter

422```422```

423 423 

424Add `rows` to let the field hold several lines. Enter still submits, and a backslash before Enter starts a new line, as does Shift+Enter where [the terminal supports it](https://code.claude.com/docs/en/terminal-config.md#enter-multiline-prompts). The gallery shows [a field with `rows`](https://code.claude.com/docs/en/plugins/mods/gallery#input).424Set `rows` to 2 or more for [a field that holds several lines](https://code.claude.com/docs/en/plugins/mods/gallery.md#input).

425 425 

426The [interface gallery](https://code.claude.com/docs/en/plugins/mods/gallery.md) has samples and screenshots of most elements. This table lists every element:426The [interface gallery](https://code.claude.com/docs/en/plugins/mods/gallery.md) has samples and screenshots of most elements. This table lists every element:

427 427 


546| Key | What it does |546| Key | What it does |

547| :- | :- |547| :- | :- |

548| Tab | Moves to the next control |548| Tab | Moves to the next control |

549| Up and Down | Move between controls while your drawing fits. When the pane or band has more rows than it can show, they scroll it. In an `Input`, they [move between the field's rows](https://code.claude.com/docs/en/plugins/mods/gallery.md#input) first. |549| Up and Down | Move between controls while your drawing fits. When the pane or band has more rows than it can show, they scroll it. In an `Input` in the terminal, they [move between the field's rows](https://code.claude.com/docs/en/plugins/mods/gallery.md#input), and from its first or last row they move to the control before or after it. |

550| Enter | Presses the focused `Button`, submits the focused `Input`, or picks in a `Select` |550| Enter | Presses the focused `Button`, submits the focused `Input`, or picks in a `Select` |

551| A button's hotkey | Presses that button. While an `Input` has the focus, every printable key goes to the field. |551| A button's hotkey | Presses that button. While an `Input` has the focus, every printable key goes to the field. |

552| Page Up, Page Down, Home, and End | Scroll your pane or band when it has more rows than it can show |552| Page Up, Page Down, Home, and End | Scroll your pane or band when it has more rows than it can show |

Details

110 110 

111### Commands and configuration111### Commands and configuration

112 112 

113Command and configuration events fire when a command runs or is listed, when a `/config` row is shown or changed, and on a settings read:

114 

115| Event | Fires when | A hook can return |113| Event | Fires when | A hook can return |

116| :- | :- | :- |114| :- | :- | :- |

117| [`command.run`](https://code.claude.com/docs/en/plugins/mods/api#add-a-command) | A command is about to run | `{ text }`, `{}`, or `next(e)` |115| [`command.run`](https://code.claude.com/docs/en/plugins/mods/api#add-a-command) | A command is about to run | `{ text }`, `{}`, or `next(e)` |

118| `command.describe` | Once for each command, for the command list | `{ description, argumentHint, isHidden }` |116| `command.describe` | Once for each command, for the command list | `{ description, argumentHint, isHidden }` |

119| `config.set` | A `/config` row is about to change | `next({ ...e, value })` or `{ deny: reason }` |117| `config.set` | A `/config` row is about to change | `next({ ...e, value })` or `{ deny: reason }` |

120| `config.describe` | Once for each `/config` row | `{ label, description, isHidden }` |118| `config.describe` | Once for each `/config` row | `{ label, description, isHidden }` |

121| [`settings.read`](https://code.claude.com/docs/en/plugins/mods/events#settings-read-hook) | A mod calls [`$.settings.read`](https://code.claude.com/docs/en/plugins/mods/api#reach-files-processes-and-the-network), or Claude Code builds the session's merged settings | `next(e)`, `{ value }`, or `{ deny: reason }` |119| [`settings.read`](https://code.claude.com/docs/en/plugins/mods/events#settings-read-hook) | A mod calls [`$.settings.read`](https://code.claude.com/docs/en/plugins/mods/api#reach-files-processes-and-the-network), or Claude Code builds the session's merged settings. Requires Claude Code v2.1.304 or later on Claude Code's own read and for `e.layers` | `next(e)`, `{ value }`, or `{ deny: reason }` |

122 120 

123#### `e.layers` and `e.source` on `settings.read`121#### `e.layers` and `e.source` on `settings.read`

124 122 

125* **`e.layers`**: one `{ source, settings }` object for each source in use that holds settings, lowest [precedence](https://code.claude.com/docs/en/settings.md#settings-precedence) first. See [What a `settings.read` hook receives](https://code.claude.com/docs/en/plugins/mods/events#settings-read-receives).123* **`e.layers`**: one `{ source, settings }` object for each source in use that holds settings, lowest [precedence](https://code.claude.com/docs/en/settings.md#settings-precedence) first. See [What a `settings.read` hook receives](https://code.claude.com/docs/en/plugins/mods/events#settings-read-receives).

126* **`e.source`**: the one source a mod asked for, as in `$.settings.read({ source: 'policy' })`. Absent on Claude Code's own read and on any other read of the merged settings124* **`e.source`**: the one source a mod asked for, as in `$.settings.read({ source: 'policy' })`. Absent on Claude Code's own read and on a read of the merged settings

127 

128On `settings.read`, the event firing on Claude Code's own read and the `e.layers` field require Claude Code v2.1.304 or later. For when the hook runs and what the hook can return, with an example, see [Change or refuse a settings read](https://code.claude.com/docs/en/plugins/mods/events.md#settings-read-hook).

129 125 

130### Turns126### Turns

131 127 


271| :- | :- | :-: | :-: | :-: |267| :- | :- | :-: | :-: | :-: |

272| [`Box`](https://code.claude.com/docs/en/plugins/mods/interface#build-a-tree-from-elements) | `key`, flex layout, [`gap`, `padding`, `margin`](#box-spacing-steps), `width`, `height`, `minWidth`, `minHeight`, [`borderStyle`](#box-border-styles), `borderColor`, `borderDimColor`, `backgroundColor`, `position`, `top`, `left`, `right`, `bottom`, `overflow`, `display`, `hover` | ✓ | ✓ | ✓ |268| [`Box`](https://code.claude.com/docs/en/plugins/mods/interface#build-a-tree-from-elements) | `key`, flex layout, [`gap`, `padding`, `margin`](#box-spacing-steps), `width`, `height`, `minWidth`, `minHeight`, [`borderStyle`](#box-border-styles), `borderColor`, `borderDimColor`, `backgroundColor`, `position`, `top`, `left`, `right`, `bottom`, `overflow`, `display`, `hover` | ✓ | ✓ | ✓ |

273| [`Text`](https://code.claude.com/docs/en/plugins/mods/interface#build-a-tree-from-elements) | `color`, `backgroundColor`, [`bold`](#text-bold), `italic`, `underline`, `strikethrough`, `dimColor`, `inverse`, `wrap`, [`size`, `weight`, `mono`, `tabular`](#text-typography), `hover` | ✓ | ✓ | ✓ |269| [`Text`](https://code.claude.com/docs/en/plugins/mods/interface#build-a-tree-from-elements) | `color`, `backgroundColor`, [`bold`](#text-bold), `italic`, `underline`, `strikethrough`, `dimColor`, `inverse`, `wrap`, [`size`, `weight`, `mono`, `tabular`](#text-typography), `hover` | ✓ | ✓ | ✓ |

274| [`Button`](https://code.claude.com/docs/en/plugins/mods/interface#respond-to-presses-and-typing) | `key`, `label`, `onPress`, `hotkey`, `plain`, `dimColor`, `autoFocus`, `action`, `hover` | ✓ | ✓ | ✓ |270| [`Button`](https://code.claude.com/docs/en/plugins/mods/interface#respond-to-presses-and-typing) | `key`, `label`, `children`, `onPress`, `hotkey`, `plain`, `dimColor`, `autoFocus`, `action`, `variant`, `role`, `hover` | ✓ | ✓ | ✓ |

275| [`Link`](https://code.claude.com/docs/en/plugins/mods/interface#link-in-the-desktop-app) | `href`, `label`. See [Limits](#limits). | ✓ | ✓ | ✓ |271| [`Link`](https://code.claude.com/docs/en/plugins/mods/interface#link-in-the-desktop-app) | `href`, `label`. See [Limits](#limits). | ✓ | ✓ | ✓ |

276| [`Code`](https://code.claude.com/docs/en/plugins/mods/gallery#show-code-and-changes) | `source`, `language`, `path`, `startLine`, `format`, `wrap` | ✓ | ✓ | ✓ |272| [`Code`](https://code.claude.com/docs/en/plugins/mods/gallery#show-code-and-changes) | `source`, `language`, `path`, `startLine`, `format`, `wrap` | ✓ | ✓ | ✓ |

277| `Markdown` | `text`, `key`, `dimColor`, `onLinkPress`, `pressableLinks` | ✓ | ✓ | ✓ |273| `Markdown` | `text`, `key`, `dimColor`, `onLinkPress`, `pressableLinks` | ✓ | ✓ | ✓ |


288* **Digit hotkeys on the band**: a digit `hotkey` on a button in the band also fires when the user types that digit alone into an empty prompt and pauses284* **Digit hotkeys on the band**: a digit `hotkey` on a button in the band also fires when the user types that digit alone into an empty prompt and pauses

289* **A collapsed band**: while the band is [collapsed](https://code.claude.com/docs/en/plugins/mods/interface.md#when-the-user-collapses-the-band), neither an `action` binding nor a hotkey presses a button in it285* **A collapsed band**: while the band is [collapsed](https://code.claude.com/docs/en/plugins/mods/interface.md#when-the-user-collapses-the-band), neither an `action` binding nor a hotkey presses a button in it

290* **Two buttons on one hotkey**: when two buttons in one drawing name the same `hotkey`, the later one gets it286* **Two buttons on one hotkey**: when two buttons in one drawing name the same `hotkey`, the later one gets it

287* **`variant`**: `primary` or `secondary`, and any other value throws. In the terminal, a `primary` button draws in the accent color unless it's `plain`.

288* **`role`**: `dismiss` marks a close button, and any other value throws. Do the closing in your `onPress`. In a band that holds text and a row of buttons, the Desktop app can draw the row's first `dismiss` button as its own close control. The terminal draws the button as it would without `role`.

289 

290A `Button` can hold `children` in place of a `label`:

291 

292* **What children can be**: strings and `Text` elements, such as a name followed by a dim detail or a colored chip. Claude Code refuses any other element inside a `Button`.

293* **Naming the button**: the `label` names the button and defaults to the text of its children. Give a button with children other than one string a `key` or a `label`.

294* **In the terminal**: the children draw where the label would be, and a press anywhere on them counts as one press, so you can make each row of a list a single button

295* **In the Desktop app and the VS Code extension**: the button draws its `label`

296 

297> [!NOTE]

298>

299> A `Button` with children other than a single string requires Claude Code v2.1.295 or later.

291 300 

292`autoFocus` accepts only `true` on any control, so omit the prop to leave it off.301`autoFocus` accepts only `true` on any control, so omit the prop to leave it off.

293 302 


295 304 

296* **`Box`**: `position` with its `top`, `left`, `right`, and `bottom`, `alignSelf`, `borderDimColor`, and `hover`305* **`Box`**: `position` with its `top`, `left`, `right`, and `bottom`, `alignSelf`, `borderDimColor`, and `hover`

297* **`Text`**: `size`, `mono`, `tabular`, and `hover`306* **`Text`**: `size`, `mono`, `tabular`, and `hover`

298* **`Button`**: `hotkey`, `plain`, `autoFocus`, `action`, and `hover`, so the user presses a button there with a click, or with Enter once it has focus307* **`Button`**: `hotkey`, `plain`, `autoFocus`, `action`, and `hover`, so the user presses a button there with a click, or with Enter once it has focus. The extension also ignores `variant` and `role`.

299* **`Code`**: `language`, `path`, `startLine`, `format`, and `wrap`, so code draws without colors or line numbers, and a `format: 'diff'` block shows the diff's raw text308* **`Code`**: `language`, `path`, `startLine`, `format`, and `wrap`, so code draws without colors or line numbers, and a `format: 'diff'` block shows the diff's raw text

300* **`Input` and `Select`**: `autoFocus`309* **`Input` and `Select`**: `autoFocus`, and `rows` on an `Input`

301* **`Svg`**: `isInteractive`310* **`Svg`**: `isInteractive`

302 311 

303### `Box` border styles312### `Box` border styles


364| A `.catch` handler's execution time | 1 second |373| A `.catch` handler's execution time | 1 second |

365| All `session.end` hooks together | As long as the [SessionEnd hook budget](https://code.claude.com/docs/en/hooks.md#sessionend-input), 1.5 seconds unless you change it, counted from when your settings `SessionEnd` hooks finish |374| All `session.end` hooks together | As long as the [SessionEnd hook budget](https://code.claude.com/docs/en/hooks.md#sessionend-input), 1.5 seconds unless you change it, counted from when your settings `SessionEnd` hooks finish |

366| `$.process.run` timeout | 30 seconds by default, 10 minutes at most |375| `$.process.run` timeout | 30 seconds by default, 10 minutes at most |

376| `$.process.run` `stdout` and `stderr` | 4 MiB each. `isStdoutTruncated` or `isStderrTruncated` is `true` when one was cut. |

367| `$.model.complete` `maxTokens` | 1024 by default, up to 64,000 or the model's output limit |377| `$.model.complete` `maxTokens` | 1024 by default, up to 64,000 or the model's output limit |

368| `$.fs.read` and `$.fs.write` | 4 MiB for one file |378| `$.fs.read` and `$.fs.write` | 4 MiB for one file |

369| A `$.http.fetch` request body | 4 MiB, counted in characters. A call with a larger body rejects. |379| A `$.http.fetch` request body | 4 MiB, counted in characters. A call with a larger body rejects. |


381| `$.store` | 4 MiB of JSON in total |391| `$.store` | 4 MiB of JSON in total |

382| `$.session.messages()` | The newest 4,096 entries |392| `$.session.messages()` | The newest 4,096 entries |

383| `$.ui.invalidate('ui.render')` redraws | Throttled to 10 a second, or 30 in the terminal for the visible pane, the expanded band, and the hint line under the prompt. Calls that come sooner are coalesced. |393| `$.ui.invalidate('ui.render')` redraws | Throttled to 10 a second, or 30 in the terminal for the visible pane, the expanded band, and the hint line under the prompt. Calls that come sooner are coalesced. |

384| `$.ui.toast` | Shown for 4 seconds unless you pass `{ timeoutMs }` |394| `$.ui.toast` | Shown for 4 seconds unless you pass `{ timeoutMs }`. In the [classic renderer](https://code.claude.com/docs/en/fullscreen.md#enable-fullscreen-rendering), a mod's newer toast can [take the place of its older one](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#a-toast-doesn’t-appear) that's showing or waiting to show. |

385| A pane opened without the user asking | Placed from 144 terminal columns, 110 after they've opened it once |395| A pane opened without the user asking | Placed from 144 terminal columns, 110 after they've opened it once |

396| Nesting depth of a mods API call's arguments | 28,000 levels. Past that, the call rejects with a message ending `nesting deeper than 28000 levels is not supported`. Requires Claude Code v2.1.299 or later. |

397| Nesting depth of a changed event passed to `next`, outside [async generator hooks](#events) such as one on `turn.step` | 28,000 levels. Past that, `next` rejects with a message ending `nesting deeper than 28000 levels is not supported`. Requires Claude Code v2.1.299 or later. |

398| Nesting depth of a hook's return value, outside `ui.render`, `ui.resolve`, and async generator hooks | 28,000 levels. Past that, the hook's result is refused, and [the notice that reports it](https://code.claude.com/docs/en/plugins/mods/troubleshoot.md#find-out-why-a-mod-does-nothing) includes `nesting deeper than 28000 levels is not supported`. Requires Claude Code v2.1.299 or later. |

386| Scopes, such as functions, blocks, and loops, nested inside one another in one file of a hooks module | 2,000 |399| Scopes, such as functions, blocks, and loops, nested inside one another in one file of a hooks module | 2,000 |

387| Command, tool, subagent type, and pane names | Letters, digits, `_`, and `-`, up to 64 characters |400| Command, tool, subagent type, and pane names | Letters, digits, `_`, and `-`, up to 64 characters |

388| One `claude plugin test` test | 5 seconds unless the test sets `timeoutMs` |401| One `claude plugin test` test | 5 seconds unless the test sets `timeoutMs` |

Details

341 341 

342### A key your `settings.read` hook returns doesn't take effect342### A key your `settings.read` hook returns doesn't take effect

343 343 

344Returned `env` entries don't become environment variables. Returned `allow`, `ask`, and `deny` rules aren't checked on tool calls. Set those in a [settings file](https://code.claude.com/docs/en/settings.md), or call [`$.env.set`](https://code.claude.com/docs/en/plugins/mods/api#reach-files-processes-and-the-network) for environment variables.344If you return permission rules or `env` on [Claude Code's own read](https://code.claude.com/docs/en/plugins/mods/events.md#settings-read-hook), the rules aren't checked on tool calls and the `env` entries don't become environment variables. Use a [settings file](https://code.claude.com/docs/en/settings.md) for both, or [`$.env.set`](https://code.claude.com/docs/en/plugins/mods/api#reach-files-processes-and-the-network) for `env`.

345 345 

346For another key, check [which mods get `settings.read` and from which version](https://code.claude.com/docs/en/plugins/mods/events#settings-read-hook), then search the [debug log](#read-the-debug-log) for `settings.read` and look for one of these lines:346For another key, check [which mods get `settings.read` and from which version](https://code.claude.com/docs/en/plugins/mods/events#settings-read-hook), then search the [debug log](#read-the-debug-log) for `settings.read` and look for one of these lines:

347 347 


349| :- | :- |349| :- | :- |

350| `settings.read hook skipped`, after your mod's name | Your hook failed. [Fix the error the line reports](#hook-skipped). |350| `settings.read hook skipped`, after your mod's name | Your hook failed. [Fix the error the line reports](#hook-skipped). |

351| `settings.read bypassed by cc-plugin-sec-default`, on a line that names your mod ahead of it | The [built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#know-what-happens-by-default) skipped your hook. Ask your organization's administrator to [install the mod as one of the organization's mods](https://code.claude.com/docs/en/plugins/mods/admin.md#install-your-organizations-mods). |351| `settings.read bypassed by cc-plugin-sec-default`, on a line that names your mod ahead of it | The [built-in guard](https://code.claude.com/docs/en/plugins/mods/admin.md#know-what-happens-by-default) skipped your hook. Ask your organization's administrator to [install the mod as one of the organization's mods](https://code.claude.com/docs/en/plugins/mods/admin.md#install-your-organizations-mods). |

352| `settings.read: the answer for <key> is no value the key can hold` | The returned value doesn't fit the key's schema. [Return one it allows](#settings-read-key-refused). |352| `settings.read: the answer for <key> is no value the key can hold` | Claude Code refused the value a hook returned for that key. The hook may be yours or another mod's. Follow [the step for your case](#settings-read-key-refused). |

353| `settings.read: the merge never settles for <key>` | The keys the line names keep the settings sources' values. Set them in a settings file. |353| `settings.read: the merge never settles for <key>` | The keys the line names keep the settings sources' values. Set them in a settings file. |

354| `answered settings.read without next()`, after a mod's name | Relevant only if that mod [runs before yours](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in). Then your hook didn't run on that read. [Turn that mod off](https://code.claude.com/docs/en/plugins/mods/overview.md#turn-mods-on-or-off), or if your organization deployed it, ask its administrator to. |354| `answered settings.read without next()`, after a mod's name | Your hook is affected if the named mod [runs before yours](https://code.claude.com/docs/en/plugins/mods/events.md#the-order-mods-run-in). Then your hook didn't run on that read. [Turn that mod off](https://code.claude.com/docs/en/plugins/mods/overview.md#turn-mods-on-or-off), or if your organization deployed it, ask its administrator to. |

355| `settings.read: refused to the engine` | The read was refused, so no hook's `{ value }` applied. [Find what refused it](#settings-read-refused). |355| `settings.read: refused to the engine` | Your value didn't apply because Claude Code's own read was refused. [Find what refused it](#settings-read-refused). |

356 356 

357If no line explains the key, check the mods that run before yours for a `settings.read` hook that [changes the key](https://code.claude.com/docs/en/plugins/mods/events.md#settings-read-example). Turn that mod off, or ask your organization's administrator to. If no hook does, set the key in a settings file.357If no line explains the key, check the mods that run before yours for a `settings.read` hook that [changes the key](https://code.claude.com/docs/en/plugins/mods/events.md#settings-read-example). Turn that mod off, or ask your organization's administrator to. If no hook does, set the key in a settings file.

358 358 

359### `the answer for <key> is no value the key can hold`359### `the answer for <key> is no value the key can hold`

360 360 

361This [debug log](#read-the-debug-log) line means Claude Code refused the value your [`settings.read`](https://code.claude.com/docs/en/plugins/mods/events#settings-read-hook) hook returned for the named key, and that key alone:361This [debug log](#read-the-debug-log) line means Claude Code refused the value a [`settings.read`](https://code.claude.com/docs/en/plugins/mods/events#settings-read-hook) hook returned for the named key, and that key alone:

362 362 

363```text theme={null}363```text theme={null}

364settings.read: the answer for <key> is no value the key can hold; the settings' own value stands364settings.read: the answer for <key> is no value the key can hold; the settings' own value stands

365```365```

366 366 

367The value you returned for the named key didn't fit that key's schema, for example by type or by range. Return a value that the key's [settings reference](https://code.claude.com/docs/en/settings-reference.md) entry allows. While your value doesn't fit, the key keeps the value merged from the settings sources before any hook answered. The line calls it the settings' own value.367The value returned for the named key didn't fit that key's schema, for example by type or by range.

368 

369* **Your value doesn't fit the key's schema**: return one the key's [settings reference](https://code.claude.com/docs/en/settings-reference.md) entry allows.

370* **Your value fits**: the value that doesn't fit came from another mod's `settings.read` hook. To find that mod, follow [the steps to turn off mods one at a time](#settings-read-refused). Search each new log for this line instead of `refused to the engine`.

371 

372While the value doesn't fit, the key keeps the value merged from the settings sources before any hook answered. The line calls it the settings' own value.

368 373 

369### `settings.read: refused to the engine`374### `settings.read: refused to the engine`

370 375 

371This [debug log](#read-the-debug-log) line means [Claude Code's own read](https://code.claude.com/docs/en/plugins/mods/events.md#settings-read-hook) was refused, so no hook's `{ value }` applied, yours included. When a `settings.read` hook refuses that read with [`{ deny: reason }`](https://code.claude.com/docs/en/plugins/mods/events#settings-read-returns), the line carries that hook's reason:376You see this line in the [debug log](#read-the-debug-log) when [Claude Code's own read](https://code.claude.com/docs/en/plugins/mods/events.md#settings-read-hook) is refused, and Claude Code drops every hook's value. When a `settings.read` hook refuses that read with [`{ deny: reason }`](https://code.claude.com/docs/en/plugins/mods/events#settings-read-returns), the line carries that hook's reason:

372 377 

373```text theme={null}378```text theme={null}

374settings.read: refused to the engine (engine: $.settings.read: <reason>); the settings' own values stand379settings.read: refused to the engine (engine: $.settings.read: <reason>); the settings' own values stand

375```380```

376 381 

377Search your own hook's code for the `<reason>` text:382Search your code for the reason in the parentheses:

378 383 

379* **Your code has it**: your hook refused the read. Make it return `{ value }` when [`next.origin`](https://code.claude.com/docs/en/plugins/mods/events#settings-read-origin) shows Claude Code's own read.384* **Your code has it**: your hook refused the read. Make it return `{ value }` when [`next.origin`](https://code.claude.com/docs/en/plugins/mods/events#settings-read-origin) shows Claude Code's own read.

380* **Your code doesn't have it**: [turn off](https://code.claude.com/docs/en/plugins/mods/overview.md#turn-mods-on-or-off) your other mods one at a time. After each, rerun this session's command from your shell with one `--debug-file` on a new path, and search that file for `refused to the engine`. If the line is there, turn off the next mod. If not, the last mod you turned off refused the read, so keep it off.385* **Your code doesn't have it**: [turn off](https://code.claude.com/docs/en/plugins/mods/overview.md#turn-mods-on-or-off) your other mods one at a time. If your organization deployed a mod, ask its administrator to turn it off. After each:

386 1. Start the session from your shell with `claude --debug-file ./settings-read-2.log`, followed by the flags it started with. Use a new path each time.

387 2. Search that file for `refused to the engine`. If the line is there, turn off the next mod. If not, the last mod you turned off refused the read, so keep it off.

381 388 

382With no other mod left, use a [settings file](https://code.claude.com/docs/en/settings.md) for the keys your hook returns. Its values hold while the read is refused.389If the line stays with no other mod left, set the keys your hook returns in a [settings file](https://code.claude.com/docs/en/settings.md). Its values hold while the read is refused.

383 390 

384## Read the debug log391## Read the debug log

385 392 

Details

192The VS Code extension and the Desktop app also have an auto-connect toggle:192The VS Code extension and the Desktop app also have an auto-connect toggle:

193 193 

194* **VS Code extension**: **Enable Remote Control for all sessions** in the [command menu's](https://code.claude.com/docs/en/vs-code.md#use-the-prompt-box) Settings section.194* **VS Code extension**: **Enable Remote Control for all sessions** in the [command menu's](https://code.claude.com/docs/en/vs-code.md#use-the-prompt-box) Settings section.

195* **Desktop app**: **Settings > Claude Code > Connect new sessions to Remote Control**. See [Control which sessions appear on your other devices](https://code.claude.com/docs/en/desktop.md#control-which-sessions-appear-on-your-other-devices).195* **Desktop app**: **Connect new sessions to Remote Control** in **Settings > Code** or **Settings > Claude Code**. See [Control which sessions appear on your other devices](https://code.claude.com/docs/en/desktop.md#control-which-sessions-appear-on-your-other-devices).

196 196 

197To turn auto-connect on from a settings file instead, set [`remoteControlAtStartup`](https://code.claude.com/docs/en/settings-reference#remotecontrolatstartup) to `true` in your user `~/.claude/settings.json` or in [managed settings](https://code.claude.com/docs/en/managed-settings.md). In project or local settings (`.claude/settings.json`, `.claude/settings.local.json`), Claude Code honors a `false` and turns auto-connect off for that repository, but ignores a `true`, so a checked-in file can't turn on Remote Control for everyone who opens the repository.197To turn auto-connect on from a settings file instead, set [`remoteControlAtStartup`](https://code.claude.com/docs/en/settings-reference#remotecontrolatstartup) to `true` in your user `~/.claude/settings.json` or in [managed settings](https://code.claude.com/docs/en/managed-settings.md). In project or local settings (`.claude/settings.json`, `.claude/settings.local.json`), Claude Code honors a `false` and turns auto-connect off for that repository, but ignores a `true`, so a checked-in file can't turn on Remote Control for everyone who opens the repository.

198 198 


363 * Text-output commands: `/compact`, `/clear`, `/context`, `/usage`, `/exit`, `/usage-credits`, `/recap`, and `/reload-plugins`. `/usage-credits` prints the billing URL instead of opening a browser. `/reload-plugins` works only when the session runs in an interactive terminal; a session without one declines it.363 * Text-output commands: `/compact`, `/clear`, `/context`, `/usage`, `/exit`, `/usage-credits`, `/recap`, and `/reload-plugins`. `/usage-credits` prints the billing URL instead of opening a browser. `/reload-plugins` works only when the session runs in an interactive terminal; a session without one declines it.

364 * `/model`, `/effort`, `/fast`, `/color`, and `/rename`: pass the value as an argument, for example `/model sonnet` or `/effort high`. From mobile and web, `/model` and `/effort` take the argument in place of the terminal picker or slider.364 * `/model`, `/effort`, `/fast`, `/color`, and `/rename`: pass the value as an argument, for example `/model sonnet` or `/effort high`. From mobile and web, `/model` and `/effort` take the argument in place of the terminal picker or slider.

365 * `/mcp`: from the mobile app, returns a text summary of server status instead of opening the picker. On the web, `/mcp` on its own opens a directory of [claude.ai connectors](https://code.claude.com/docs/en/mcp.md#use-mcp-servers-from-claude-ai) instead of returning the summary. The `reconnect`, `enable`, and `disable` [subcommands](https://code.claude.com/docs/en/commands.md#all-commands) work from both when the session runs in an interactive terminal. `/mcp reconnect` with no server name retries every server that has failed or needs authentication. To authorize a claude.ai connector without the picker, see [Authorize a connector again from your shell](#authorize-a-connector-again-from-your-shell).365 * `/mcp`: from the mobile app, returns a text summary of server status instead of opening the picker. On the web, `/mcp` on its own opens a directory of [claude.ai connectors](https://code.claude.com/docs/en/mcp.md#use-mcp-servers-from-claude-ai) instead of returning the summary. The `reconnect`, `enable`, and `disable` [subcommands](https://code.claude.com/docs/en/commands.md#all-commands) work from both when the session runs in an interactive terminal. `/mcp reconnect` with no server name retries every server that has failed or needs authentication. To authorize a claude.ai connector without the picker, see [Authorize a connector again from your shell](#authorize-a-connector-again-from-your-shell).

366 * `/config`: from the mobile app, pass `key=value` to set a setting, or run it with no argument to list the keys you can set. On the web, `/config` opens the Claude Code section of your settings instead.366 * `/config`: from the mobile app, pass `key=value` to set a setting, or run it with no argument to list the keys you can set. On the web, `/config` opens **Settings > Code** or **Settings > Claude Code** instead.

367 * On Team and Enterprise, `/usage-credits` from mobile or web doesn't send a [usage-credits request to your admin](https://code.claude.com/docs/en/costs.md#add-usage-credits-to-your-subscription). Sending requires a confirmation that appears only in the interactive CLI, so the command tells you to run it there instead.367 * On Team and Enterprise, `/usage-credits` from mobile or web doesn't send a [usage-credits request to your admin](https://code.claude.com/docs/en/costs.md#add-usage-credits-to-your-subscription). Sending requires a confirmation that appears only in the interactive CLI, so the command tells you to run it there instead.

368 * `/autocompact`, from v2.1.221: pass the window size as an argument, for example `/autocompact 500k`. With no argument, it prints the current window size as text instead of opening the dialog the command shows in a terminal session.368 * `/autocompact`, from v2.1.221: pass the window size as an argument, for example `/autocompact 500k`. With no argument, it prints the current window size as text instead of opening the dialog the command shows in a terminal session.

369 * `/advisor`, from v2.1.260: pass the model as an argument, for example `/advisor opus`, or pass `off` to turn the advisor off. Both forms apply to the current session only and leave your saved default unchanged. With no argument, it prints the current advisor as text instead of opening the picker.369 * `/advisor`, from v2.1.260: pass the model as an argument, for example `/advisor opus`, or pass `off` to turn the advisor off. Both forms apply to the current session only and leave your saved default unchanged. With no argument, it prints the current advisor as text instead of opening the picker.

routines.md +9 −5

Details

77 77 

78**2. Name the task and write the prompt**78**2. Name the task and write the prompt**

79 79 

80Give the scheduled task a descriptive name and write the prompt Claude runs each time. The prompt is the most important part: the task runs autonomously, so the prompt must be self-contained and explicit about what to do and what success looks like. Select a model in the prompt input's model selector. Claude uses it on every run.80Give the scheduled task a descriptive name and write the prompt Claude runs each time. The prompt is the most important part: the task runs autonomously, so the prompt must be self-contained and explicit about what to do and what success looks like.

81 81 

82When a trigger fires, the session receives the saved prompt as its assignment and carries it out, rather than treating it as untrusted content that arrived mid-conversation. The trigger attests only that the prompt was stored ahead of time by an authorized session on your account. The fired prompt is therefore not live user input and can't act as approval or consent for actions during the run. Content the session fetches during the run keeps its normal handling.82When a trigger fires, the session receives the saved prompt as its assignment and carries it out, rather than treating it as untrusted content that arrived mid-conversation. The trigger attests only that the prompt was stored ahead of time by an authorized session on your account. The fired prompt is therefore not live user input and can't act as approval or consent for actions during the run. Content the session fetches during the run keeps its normal handling.

83 83 


115 115 

116If your task needs to reach your own services directly, or a domain outside that list, edit the environment's [network access](https://code.claude.com/docs/en/cloud-environments.md#network-access) before running. To use a separate environment, [create one](https://code.claude.com/docs/en/cloud-environments.md#configure-your-environment) first.116If your task needs to reach your own services directly, or a domain outside that list, edit the environment's [network access](https://code.claude.com/docs/en/cloud-environments.md#network-access) before running. To use a separate environment, [create one](https://code.claude.com/docs/en/cloud-environments.md#configure-your-environment) first.

117 117 

118**6. Review connectors**118**6. Select a model and effort level**

119 

120Select a model in the prompt input's model selector for Claude to use on every run. For a Claude Code task, if the model offers [effort levels](https://code.claude.com/docs/en/model-config.md#adjust-effort-level), **Effort** in the same selector shows the current level. To change it, select another level. The selector's **Default** option offers no levels.

121 

122**7. Review connectors**

119 123 

120Switch to the **Connectors** tab of **Advanced settings**. All of your connected [MCP connectors](https://code.claude.com/docs/en/mcp.md) are included by default. Remove any the task doesn't need: Claude can use an included connector during a run, including writes. For when a run stops to ask you first, see [Permission prompts during a run](#permission-prompts-during-a-run).124Switch to the **Connectors** tab of **Advanced settings**. All of your connected [MCP connectors](https://code.claude.com/docs/en/mcp.md) are included by default. Remove any the task doesn't need: Claude can use an included connector during a run, including writes. For when a run stops to ask you first, see [Permission prompts during a run](#permission-prompts-during-a-run).

121 125 

122**7. Create the task**126**8. Create the task**

123 127 

124Click **Create**. The dialog closes and the new task's detail page opens. The task runs the next time one of its triggers matches. To start a run immediately, click **Run now** on the detail page.128Click **Create**. The dialog closes and the new task's detail page opens. The task runs the next time one of its triggers matches. To start a run immediately, click **Run now** on the detail page.

125 129 


136In the Desktop app, if a menu with **Local** and **Cloud** opens, select **Cloud**. A page titled **New routine** or **New scheduled task** opens. Fill in its fields:140In the Desktop app, if a menu with **Local** and **Cloud** opens, select **Cloud**. A page titled **New routine** or **New scheduled task** opens. Fill in its fields:

137 141 

138* **Name**: enter one.142* **Name**: enter one.

139* **Instructions**: enter the prompt. In the same box, select the model, the repositories, and the environment. For what each one controls, see the steps under [Create from the web](#create-from-the-web).143* **Instructions**: enter the prompt. In the same box, select the model, the effort level if the model offers one, the repositories, and the environment. For what each one controls, see the steps under [Create from the web](#create-from-the-web).

140* **Select a trigger**: select **Schedule**, **GitHub event**, or **API**. For a schedule, see [Add a schedule trigger](#add-a-schedule-trigger). For a [GitHub event](#add-a-github-trigger), select a repository. For an [API trigger](#add-an-api-trigger), copy the token from the **API token** dialog that opens after you click **Create**, because it is shown once. To combine several triggers, click **Add another trigger**.144* **Select a trigger**: select **Schedule**, **GitHub event**, or **API**. For a schedule, see [Add a schedule trigger](#add-a-schedule-trigger). For a [GitHub event](#add-a-github-trigger), select a repository. For an [API trigger](#add-an-api-trigger), copy the token from the **API token** dialog that opens after you click **Create**, because it is shown once. To combine several triggers, click **Add another trigger**.

141* **Connectors**: all of your connected connectors are included by default, so remove the ones the task doesn't need.145* **Connectors**: all of your connected connectors are included by default, so remove the ones the task doesn't need.

142 146 


153* **API trigger**: edit the task on the web at [claude.ai/code/routines](https://claude.ai/code/routines)157* **API trigger**: edit the task on the web at [claude.ai/code/routines](https://claude.ai/code/routines)

154* **[GitHub trigger](#add-a-github-trigger)**: edit the task on the web, or ask Claude in the CLI. Adding one from the CLI requires Claude Code v2.1.225 or later158* **[GitHub trigger](#add-a-github-trigger)**: edit the task on the web, or ask Claude in the CLI. Adding one from the CLI requires Claude Code v2.1.225 or later

155 159 

156A scheduled task with no schedule trigger, such as one started only by API calls or GitHub events, has no next run time. The CLI shows none when Claude saves or updates it. Before v2.1.211, the CLI reported a next run time in the year 1 for these tasks.160A scheduled task with no schedule trigger, such as one started only by API calls or GitHub events, has no next run time. The CLI shows none when Claude saves or updates it.

157 161 

158## Configure triggers162## Configure triggers

159 163 

sandboxing.md +2 −1

Details

320* **Every command in the call has to match**: `npm ci && docker compose build` stays sandboxed unless another entry covers `npm ci`320* **Every command in the call has to match**: `npm ci && docker compose build` stays sandboxed unless another entry covers `npm ci`

321* **Claude Code matches the text of the call**: a script or `make` target that calls `docker` internally doesn't match, and neither does `/usr/local/bin/docker`321* **Claude Code matches the text of the call**: a script or `make` target that calls `docker` internally doesn't match, and neither does `/usr/local/bin/docker`

322* **Some calls stay sandboxed**: a redirect to a file, a `cd`, or a command substitution such as `$(...)` keeps the whole call sandboxed. The [reference entry](https://code.claude.com/docs/en/settings-reference.md#sandbox-excludedcommands) lists more calls that stay sandboxed322* **Some calls stay sandboxed**: a redirect to a file, a `cd`, or a command substitution such as `$(...)` keeps the whole call sandboxed. The [reference entry](https://code.claude.com/docs/en/settings-reference.md#sandbox-excludedcommands) lists more calls that stay sandboxed

323* **A `git clone` needs relative paths**: your entry doesn't cover a clone that names an absolute path, a path starting with `~`, or one with a `..` segment. If the clone can go inside your working directory, ask Claude to use a relative path with no `..` segment, such as `vendor/lib`

323* **Where you save the entry can matter**: while the sandbox is [admin-required](#repository-settings-under-an-admin-required-sandbox), Claude Code ignores entries in `.claude/settings.json` and `.claude/settings.local.json`324* **Where you save the entry can matter**: while the sandbox is [admin-required](#repository-settings-under-an-admin-required-sandbox), Claude Code ignores entries in `.claude/settings.json` and `.claude/settings.local.json`

324 325 

325An excluded command goes through the regular permission flow:326An excluded command goes through the regular permission flow:


354 355 

355The sandbox has two independent layers: [filesystem isolation](#filesystem-isolation) controls which paths sandboxed commands can read and write, and [network isolation](#network-isolation) controls which domains they can reach. With the filesystem layer off, sandboxed commands get unrestricted read and write access to the host filesystem, while their network egress stays confined to your allowed domains. Turn the layer off when you sandbox to control where commands connect rather than what they write.356The sandbox has two independent layers: [filesystem isolation](#filesystem-isolation) controls which paths sandboxed commands can read and write, and [network isolation](#network-isolation) controls which domains they can reach. With the filesystem layer off, sandboxed commands get unrestricted read and write access to the host filesystem, while their network egress stays confined to your allowed domains. Turn the layer off when you sandbox to control where commands connect rather than what they write.

356 357 

357`sandbox.filesystem.disabled` defaults to `false`. Requires Claude Code v2.1.216 or later.358`sandbox.filesystem.disabled` defaults to `false`.

358 359 

359> [!WARNING]360> [!WARNING]

360>361>

Details

381 381 

382| Flag, with an example value | Pass it to | What it does |382| Flag, with an example value | Pass it to | What it does |

383| :- | :- | :- |383| :- | :- | :- |

384| `--release-idle-session-min 30` | Every runner your hook starts | The runner releases its session after that many idle minutes and then exits 0. The session resumes when its user sends their next message, but [work it hadn't pushed is gone](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#additional-limitations). |384| `--release-idle-session-min 30` | Every runner your hook starts | The runner releases its session after that many idle minutes and then exits 0. The session resumes when its user sends their next message, but [work it hadn't pushed is gone](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#additional-limitations). [Hold a session](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#keep-an-idle-session-while-its-processes-run) for processes it left running. |

385| `--kill-session-after-min 480` | Every runner your hook starts | Limits each session to that many minutes, as a backstop for [sessions that don't count as idle](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#some-sessions-don’t-count-as-idle), so set it above your longest expected session |385| `--kill-session-after-min 480` | Every runner your hook starts | Limits each session to that many minutes, as a backstop for [sessions that don't count as idle](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#some-sessions-don’t-count-as-idle), so set it above your longest expected session |

386| `--exit-if-unused-min 60` | Standby runners, which your hook starts for pre-warming requests | A standby that never takes a session exits after that many minutes. If you set [`--min-idle`](https://code.claude.com/docs/en/self-hosted-environments-reference#orchestrator-cli-flags), you get a replacement unless the standby was surplus, so use a value well above your boot time. |386| `--exit-if-unused-min 60` | Standby runners, which your hook starts for pre-warming requests | A standby that never takes a session exits after that many minutes. If you set [`--min-idle`](https://code.claude.com/docs/en/self-hosted-environments-reference#orchestrator-cli-flags), you get a replacement unless the standby was surplus, so use a value well above your boot time. |

387 387 

Details

68| `code.claude.com` and `claude.com` | 443 | Documentation lookups by the built-in claude-code-guide agent and pre-approved WebFetch requests during sessions. Blocking these hosts only affects documentation lookups. |68| `code.claude.com` and `claude.com` | 443 | Documentation lookups by the built-in claude-code-guide agent and pre-approved WebFetch requests during sessions. Blocking these hosts only affects documentation lookups. |

69| `*.frame.claudeusercontent.com` | 443 | Only when the [Artifact tool](https://code.claude.com/docs/en/artifacts.md#availability) is available for sessions in your organization; defaults vary by plan, per the availability table there. Set `CLAUDE_CODE_DISABLE_ARTIFACT=1` on the runner to keep the tool disabled regardless of the organization setting. |69| `*.frame.claudeusercontent.com` | 443 | Only when the [Artifact tool](https://code.claude.com/docs/en/artifacts.md#availability) is available for sessions in your organization; defaults vary by plan, per the availability table there. Set `CLAUDE_CODE_DISABLE_ARTIFACT=1` on the runner to keep the tool disabled regardless of the organization setting. |

70| `registry.npmjs.org` | 443 | When a session installs a plugin, both for fetching npm-source plugin packages and for installing a plugin's Node.js dependencies, or when an `npx`-launched MCP server runs |70| `registry.npmjs.org` | 443 | When a session installs a plugin, both for fetching npm-source plugin packages and for installing a plugin's Node.js dependencies, or when an `npx`-launched MCP server runs |

71| An internal mirror of the package registries your builds use, or the registries themselves | 443, or your mirror's port | When sessions install dependencies to build or test your repositories |

71| `http-intake.logs.us5.datadoghq.com` | 443 | Anthropic operational metrics. Only when `CLAUDE_CODE_BYOC_ENABLE_DATADOG=1` is set; off by default in self-hosted environments. |72| `http-intake.logs.us5.datadoghq.com` | 443 | Anthropic operational metrics. Only when `CLAUDE_CODE_BYOC_ENABLE_DATADOG=1` is set; off by default in self-hosted environments. |

72| `browser-intake-us5-datadoghq.com` | 443 | Anthropic error-report uploads, sent only when [error reporting](https://code.claude.com/docs/en/data-usage.md#telemetry-services) is enabled for the session's account. Suppressed by `DISABLE_ERROR_REPORTING=1` or `DISABLE_TELEMETRY=1`. |73| `browser-intake-us5-datadoghq.com` | 443 | Anthropic error-report uploads, sent only when [error reporting](https://code.claude.com/docs/en/data-usage.md#telemetry-services) is enabled for the session's account. Suppressed by `DISABLE_ERROR_REPORTING=1` or `DISABLE_TELEMETRY=1`. |

73| Your cloud provider's endpoints for model requests, model lookups, and renewing credentials, such as `bedrock-runtime.us-east-1.amazonaws.com` or `aiplatform.googleapis.com` | 443 | Only when the runner [sends model requests to Amazon Bedrock or Google Cloud's Agent Platform](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#send-model-requests-to-bedrock-or-agent-platform) |74| Your cloud provider's endpoints for model requests, model lookups, and renewing credentials, such as `bedrock-runtime.us-east-1.amazonaws.com` or `aiplatform.googleapis.com` | 443 | Only when the runner [sends model requests to Amazon Bedrock or Google Cloud's Agent Platform](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#send-model-requests-to-bedrock-or-agent-platform) |


631 632 

632In the first two stages that follow the signal, the runner releases sessions, and a released session resumes on a fresh runner when its user sends their next message. Counting from the first signal, the runner moves through three stages:633In the first two stages that follow the signal, the runner releases sessions, and a released session resumes on a fresh runner when its user sends their next message. Counting from the first signal, the runner moves through three stages:

633 634 

634* **For the first `n` minutes**: the runner serves its sessions normally and keeps enforcing `--startup-timeout-min` and `--kill-session-after-min`. If you also set [`--release-idle-session-min`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags), the runner releases any session whose user has been idle that long; without it, idle sessions stay on the runner.635* **For the first `n` minutes**: the runner serves its sessions normally and keeps enforcing `--startup-timeout-min` and `--kill-session-after-min`. If you also set [`--release-idle-session-min`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags), the runner releases any session whose user has been idle that long, unless you [hold that session](#keep-an-idle-session-while-its-processes-run). Without the flag, idle sessions stay on the runner.

635* **When the `n` minutes run out**: the runner releases every session it still holds, idle or not. The runner waits for a mid-turn session's turn to end, and up to 60 seconds more for a turn's background tasks, before releasing that session.636* **When the `n` minutes run out**: the runner releases every session it still holds, idle or not. The runner waits for a mid-turn session's turn to end, and up to 60 seconds more for a turn's background tasks, before releasing that session.

636* **When the post-release grace runs out**: the runner drains whatever sessions it still holds, and the control plane requeues each drained session to another runner right away. The post-release grace starts when the `n` minutes run out and is 75 seconds at defaults. If you set `--drain-wait-sec` above 60 seconds, the post-release grace is `--drain-wait-sec` plus 15 seconds instead.637* **When the post-release grace runs out**: the runner drains whatever sessions it still holds, and the control plane requeues each drained session to another runner right away. The post-release grace starts when the `n` minutes run out and is 75 seconds at defaults. If you set `--drain-wait-sec` above 60 seconds, the post-release grace is `--drain-wait-sec` plus 15 seconds instead.

637 638 


716 717 

717### Release idle sessions on a fixed fleet718### Release idle sessions on a fixed fleet

718 719 

719If sessions stay queued on a fixed fleet while every runner is online, idle sessions may be the cause. By default, a session keeps its slot after its turn finishes, and its runner stays locked to that session's [owner](https://code.claude.com/docs/en/self-hosted-environments#key-concepts). If your team's [cloud scheduled task](https://code.claude.com/docs/en/routines.md) starts a new session at each run, its idle sessions can fill every slot.720If sessions stay queued on a fixed fleet while every runner is online, idle sessions may be the cause. By default, a session keeps its slot after its turn finishes, and its runner stays locked to that session's [owner](https://code.claude.com/docs/en/self-hosted-environments#key-concepts). Other owners' sessions can't use that runner's free slots. If your team's [cloud scheduled task](https://code.claude.com/docs/en/routines.md) starts a new session at each run, its idle sessions can fill every slot.

720 721 

721To check, read `claude_code_self_hosted_runner_session_idle_seconds` in each runner's [Prometheus metrics](https://code.claude.com/docs/en/self-hosted-environments-reference.md#prometheus-metrics). Each session a runner holds has its own series: `0` while the session is busy, otherwise the seconds since it went idle. Choose the idle time you'd allow: longer than the pauses people take mid-task, and short enough that each run is released before the scheduled task's next one starts. Compare the series with it.722To check, read `claude_code_self_hosted_runner_session_idle_seconds` in each runner's [Prometheus metrics](https://code.claude.com/docs/en/self-hosted-environments-reference.md#prometheus-metrics). Each session a runner holds has its own series: `0` while the session is busy, otherwise the seconds since it went idle. Choose the idle time you'd allow: longer than the pauses people take mid-task, and short enough that each run is released before the scheduled task's next one starts. Compare the series with it.

722 723 


725* **A runner with no series**: no session holds it. See **Sessions stay queued** under [Troubleshooting](#troubleshooting).726* **A runner with no series**: no session holds it. See **Sessions stay queued** under [Troubleshooting](#troubleshooting).

726* **A runner whose metrics don't answer**: its process may have exited. See **An environment that looks healthy** under [When the runner exits](#when-the-runner-exits).727* **A runner whose metrics don't answer**: its process may have exited. See **An environment that looks healthy** under [When the runner exits](#when-the-runner-exits).

727 728 

728To release idle sessions, start every runner with [`--release-idle-session-min`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags) and that time in minutes, such as `--release-idle-session-min 30`. The runner then releases any session that stays idle that long, whether a scheduled task or a person started it.729To release idle sessions, start every runner with [`--release-idle-session-min`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags) and that time in minutes, such as `--release-idle-session-min 30`. The runner then releases any session that stays idle that long, whether a scheduled task or a person started it, unless you [hold it for processes it left running](#keep-an-idle-session-while-its-processes-run).

729 730 

730* **Unpushed work**: a released session resumes at its next message, without the work it hadn't pushed. To keep its commits, see [Resumed sessions lose unpushed work](#additional-limitations).731* **Unpushed work**: a released session resumes at its next message, without the work it hadn't pushed. To keep its commits, see [Resumed sessions lose unpushed work](#additional-limitations).

731* **Runner exits**: a runner that releases its last session starts a [normal exit](#when-the-runner-exits). Have your supervisor restart it on a fresh filesystem, as [Harden your deployment](#harden-your-deployment) describes.732* **Runner exits**: a runner that releases its last session starts a [normal exit](#when-the-runner-exits). Have your supervisor restart it on a fresh filesystem, as [Harden your deployment](#harden-your-deployment) describes.

732* **Sessions that never go idle**: also set [`--kill-session-after-min`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags), because [some sessions don't count as idle](#some-sessions-don’t-count-as-idle)733* **Sessions that never go idle**: also set [`--kill-session-after-min`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags), because [some sessions don't count as idle](#some-sessions-don’t-count-as-idle)

733 734 

735### Keep an idle session while its processes run

736 

737To keep an idle session until processes it left on your host finish, such as `nohup` jobs, start the runner with [`--hold-idle-file`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags) and keep touching that file from the host. Requires Claude Code v2.1.311 or later.

738 

739These steps assume a non-root runner on a host. If your runner runs as `root`, its sessions can touch the file themselves, so run it as a dedicated user first.

740 

741**1. Pick a path for the file**

742 

743Choose a local regular file, such as `/var/lib/claude-hold/hold-idle`, in a directory sessions can't write to, parent directories included, so a session can't write to it. The runner and its sessions share one OS user, so create that directory first, owned by another user such as `root`, with mode `755`.

744 

745**2. Start the runner**

746 

747From your shell, start the runner with `--hold-idle-file`, `--release-idle-session-min`, and [`--max-hold-min`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags), the cap on a hold, counted from when a session goes idle. Without it, the cap is one day. Set it above `--release-idle-session-min`, or nothing is held. This example releases idle sessions after 30 minutes and releases a held session at most 4 hours after it went idle:

748 

749```bash theme={null}

750claude self-hosted-runner \

751 --environment-secret-file /etc/claude/environment-secret \

752 --release-idle-session-min 30 \

753 --hold-idle-file /var/lib/claude-hold/hold-idle \

754 --max-hold-min 240

755```

756 

757**3. Touch the file while the processes run**

758 

759While the processes run, `touch` the file from the host as the directory's owner, more often than every three minutes. The first `touch` creates the file. For example, add this line to `root`'s crontab:

760 

761```text theme={null}

762* * * * * pgrep -x nightly-build > /dev/null && touch /var/lib/claude-hold/hold-idle

763```

764 

765The line runs once a minute and touches the file while any process named `nightly-build` runs, so a session that starts one stays held up to the cap. Replace the `pgrep` check with however your host finds what sessions left running.

766 

767The check must stop matching when they finish, or every idle session on that runner stays held until the cap.

768 

769**4. Confirm the hold**

770 

771While the processes run, check that the file's modification time stays under three minutes old. When a session's idle time runs out, look for `idle release held` in the runner's log. If no such line appears, read `leftover-hold=` in the `watchdog config` line the runner logs at startup, which shows the file and cap, or why nothing is held.

772 

773Three minutes after the last `touch`, the hold ends. Within about a minute more, the log shows `idle release no longer held` and the runner releases the session.

774 

775Even while the file keeps changing, a hold can end, in cases such as these:

776 

777* **Past the cap**: `--max-hold-min` runs out. To hold longer, raise it

778* **Forced releases**: you set [`--retire-at`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags), [`--defer-shutdown-max-min`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags), or [`--kill-session-after-min`](https://code.claude.com/docs/en/self-hosted-environments-reference#runner-cli-flags), and that limit arrives. To hold longer, set a later limit

779 

734## Known issues and limitations780## Known issues and limitations

735 781 

736The following are the limitations in this release, with workarounds where one exists.782The following are the limitations in this release, with workarounds where one exists.


828* **Claude Tag sometimes doesn't post its reply in Slack**: the reply reminder is a [hook the control plane supplies](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#how-each-session’s-config-is-assembled). Confirm the runner is Claude Code v2.1.229 or later with `claude --version`, since older runners ignore supplied hooks; confirm `python3 --version` succeeds inside the runner image, since the hooks run `python3`; and confirm no settings file turns hooks off, whether `disableAllHooks` in `managed-settings.json`, the runner user's `~/.claude/settings.json`, or the repository's `.claude/settings.json` or `.claude/settings.local.json`, or `allowManagedHooksOnly` or a [`strictPluginOnlyCustomization`](https://code.claude.com/docs/en/settings-reference#strictpluginonlycustomization) that covers hooks in managed settings.874* **Claude Tag sometimes doesn't post its reply in Slack**: the reply reminder is a [hook the control plane supplies](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#how-each-session’s-config-is-assembled). Confirm the runner is Claude Code v2.1.229 or later with `claude --version`, since older runners ignore supplied hooks; confirm `python3 --version` succeeds inside the runner image, since the hooks run `python3`; and confirm no settings file turns hooks off, whether `disableAllHooks` in `managed-settings.json`, the runner user's `~/.claude/settings.json`, or the repository's `.claude/settings.json` or `.claude/settings.local.json`, or `allowManagedHooksOnly` or a [`strictPluginOnlyCustomization`](https://code.claude.com/docs/en/settings-reference#strictpluginonlycustomization) that covers hooks in managed settings.

829* **A session starts without one of its repositories**: on a runner with no [`checkout` hook](https://code.claude.com/docs/en/self-hosted-environments-configuration#checkout), the git host can refuse the runner's access check for a repository the session only reads from. The runner then skips that repository, logs a `[runner:warn] could not access context source` line naming the refusal, and starts the session on the remaining ones.875* **A session starts without one of its repositories**: on a runner with no [`checkout` hook](https://code.claude.com/docs/en/self-hosted-environments-configuration#checkout), the git host can refuse the runner's access check for a repository the session only reads from. The runner then skips that repository, logs a `[runner:warn] could not access context source` line naming the refusal, and starts the session on the remaining ones.

830 876 

831 The runner skips only a clear refusal: the host answers that the repository wasn't found, git finds no credentials for the host, or authentication fails. A network failure, a timeout, or an HTTP `403` still fails the session start, as does a refusal for a repository the session pushes results to. The runner still fails a session that skipping would leave with no repository at all. With [`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy), the runner skips only a repository the git proxy itself denies.877 With its own git credentials, the runner can skip a repository when the host answers that the repository wasn't found, git finds no credentials for the host, or authentication fails.

878 

879 With [`--use-anthropic-git-proxy`](#use-the-anthropic-git-proxy), when the git proxy refuses a repository with `access denied by the git proxy`, the runner skips it. The log line then says `blocked by the git proxy`. For the causes to check, see the `remote: access denied by the git proxy` case in [When sessions fail to start on a runner with the git proxy](#when-anthropic-doesnt-serve-a-session).

880 

881 A network failure, a timeout, or any other HTTP `403` still fails the session start, as does a refusal for a repository the session pushes results to. The runner still fails a session that skipping would leave with no repository at all.

832 882 

833 The access check runs again each time the session starts on a runner, so once the runner's git identity has read access, the next start clones the repository. Before v2.1.274, each of these refusals failed the session start.883 The access check runs again each time the session starts on a runner, so once the runner's git identity has read access, the next start clones the repository. Before v2.1.274, each of these refusals failed the session start.

884* **The log shows `could not read context source`**: this line, unlike `could not access context source`, means the git host kept answering HTTP `429`, or a wrapper you installed as `git` kept exiting `75`. The runner skipped that repository. To retry, start a new session. The runner also tries the repository again each time this session starts on a runner.

885 

886 With no `checkout` hook, the runner can skip a repository the session only reads from, unless it's first among the session's repositories. Before v2.1.311, the session start failed.

834* **A session fails to start with `This runner couldn't read`**: the runner asked the git host for a repository with its [git credentials](#configure-git) and got a not-found answer. The repository doesn't exist, or those credentials can't reach the repository.887* **A session fails to start with `This runner couldn't read`**: the runner asked the git host for a repository with its [git credentials](#configure-git) and got a not-found answer. The repository doesn't exist, or those credentials can't reach the repository.

835 * **If you administer the runner**: give its git credentials read access to the repository, then start a new session.888 * **If you administer the runner**: give its git credentials read access to the repository, then start a new session.

836 * **If you started the session**: if the repository doesn't exist, start a new session with the right repository. If the runner can't reach the repository, ask the runner's administrator to grant access, then start a new session.889 * **If you started the session**: if the repository doesn't exist, start a new session with the right repository. If the runner can't reach the repository, ask the runner's administrator to grant access, then start a new session.

Details

37| `--git-host-rewrite <from>=<to>` | none | unset | Rewrite `https://<from>/...` source URLs to `https://<to>/...` before cloning, for split-horizon DNS. Repeatable; flag only. |37| `--git-host-rewrite <from>=<to>` | none | unset | Rewrite `https://<from>/...` source URLs to `https://<to>/...` before cloning, for split-horizon DNS. Repeatable; flag only. |

38| `--git-ssh-rewrite <host>` | none | unset | Rewrite `https://<host>/...` source URLs to `git@<host>:...` before cloning, for SSH-only git hosts. Repeatable; flag only. |38| `--git-ssh-rewrite <host>` | none | unset | Rewrite `https://<host>/...` source URLs to `git@<host>:...` before cloning, for SSH-only git hosts. Repeatable; flag only. |

39| `--health-port <port>` | `SELF_HOSTED_RUNNER_HEALTH_PORT` | `8080` | Port for the `/healthz` and `/metrics` listener. Set `0` to disable. |39| `--health-port <port>` | `SELF_HOSTED_RUNNER_HEALTH_PORT` | `8080` | Port for the `/healthz` and `/metrics` listener. Set `0` to disable. |

40| `--hold-idle-file <path>` | `SELF_HOSTED_RUNNER_HOLD_IDLE_FILE` | unset | File your host keeps changing to hold an idle session on the runner. See [Keep an idle session while its processes run](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#keep-an-idle-session-while-its-processes-run). Requires Claude Code v2.1.311 or later. |

40| `--hooks-dir <path>` | `SELF_HOSTED_RUNNER_HOOKS_DIR` | unset | Directory of lifecycle hook scripts. See [Lifecycle hooks](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#lifecycle-hooks). |41| `--hooks-dir <path>` | `SELF_HOSTED_RUNNER_HOOKS_DIR` | unset | Directory of lifecycle hook scripts. See [Lifecycle hooks](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#lifecycle-hooks). |

41| `--host-config-snapshot <mode>` | `SELF_HOSTED_RUNNER_HOST_CONFIG_SNAPSHOT` | `disk` | Where the runner keeps the startup snapshot of the [host config directory](#environment-variable-only-settings) that it seeds each session from. `disk` copies the snapshot into a runner-owned directory under `--base-dir` and, at each session start, verifies every file against an in-memory digest. If a file in the copy has been modified, the session fails and the runner refuses sessions until you restart it. `memory` holds the whole snapshot on the heap, capped at 64 MiB; over the cap, sessions start without host config and show a notice saying so. When the runner can't write the disk snapshot, it logs the failure and uses `memory` for that run. Requires Claude Code v2.1.271 or later. |42| `--host-config-snapshot <mode>` | `SELF_HOSTED_RUNNER_HOST_CONFIG_SNAPSHOT` | `disk` | Where the runner keeps the startup snapshot of the [host config directory](#environment-variable-only-settings) that it seeds each session from. `disk` copies the snapshot into a runner-owned directory under `--base-dir` and, at each session start, verifies every file against an in-memory digest. If a file in the copy has been modified, the session fails and the runner refuses sessions until you restart it. `memory` holds the whole snapshot on the heap, capped at 64 MiB; over the cap, sessions start without host config and show a notice saying so. When the runner can't write the disk snapshot, it logs the failure and uses `memory` for that run. Requires Claude Code v2.1.271 or later. |

42| `--kill-session-after-min <n>` | `SELF_HOSTED_RUNNER_MAX_LIFETIME_MS` | `0` | Limit a session to N minutes wall-clock, as a safety limit for stuck sessions. On v2.1.260 or later, the runner releases a session that reaches the limit so it can resume on its user's next message, and terminates it only if it's still on the runner when the [`SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS`](#environment-variable-only-settings) grace window ends. Before v2.1.260, the runner terminated the session at the limit. See [Some sessions don't count as idle](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#some-sessions-don’t-count-as-idle) for the details and how to choose a value. `0` disables. |43| `--kill-session-after-min <n>` | `SELF_HOSTED_RUNNER_MAX_LIFETIME_MS` | `0` | Limit a session to N minutes wall-clock, as a safety limit for stuck sessions. On v2.1.260 or later, the runner releases a session that reaches the limit so it can resume on its user's next message, and terminates it only if it's still on the runner when the [`SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS`](#environment-variable-only-settings) grace window ends. Before v2.1.260, the runner terminated the session at the limit. See [Some sessions don't count as idle](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#some-sessions-don’t-count-as-idle) for the details and how to choose a value. `0` disables. |

43| `--lock-to-account <id>` | `SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT` | unset | Pre-lock the runner to a specific account at startup instead of locking on first session. Accepts an email address or `user_...` ID in the environment's organization. A pre-locked runner never picks up Claude Tag channel sessions, which have no account. |44| `--lock-to-account <id>` | `SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT` | unset | Pre-lock the runner to a specific account at startup instead of locking on first session. Accepts an email address or `user_...` ID in the environment's organization. A pre-locked runner never picks up Claude Tag channel sessions, which have no account. |

44| `--log-file <path>` | `SELF_HOSTED_RUNNER_LOG_FILE` | unset | Mirror runner logs to a file in addition to stdout and stderr, created with `0600` permissions. Required for `self-hosted-runner doctor` to tail logs locally. |45| `--log-file <path>` | `SELF_HOSTED_RUNNER_LOG_FILE` | unset | Mirror runner logs to a file in addition to stdout and stderr, created with `0600` permissions. Required for `self-hosted-runner doctor` to tail logs locally. |

45| `--log-level <level>` | none | `info` | `info` or `debug` |46| `--log-level <level>` | none | `info` | `info` or `debug` |

47| `--max-hold-min <n>` | `SELF_HOSTED_RUNNER_MAX_HOLD_MS` | `1440` | With `--hold-idle-file`, release a held session anyway N minutes after it went idle. A value at or below `--release-idle-session-min` holds nothing. `0` turns the hold off. Requires Claude Code v2.1.311 or later. |

46| `--post-session-hook-timeout-sec <n>` | `SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS` | `60` | Budget for the [`post-session` hook](https://code.claude.com/docs/en/self-hosted-environments-configuration#post-session) on every session end, including runner shutdown |48| `--post-session-hook-timeout-sec <n>` | `SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS` | `60` | Budget for the [`post-session` hook](https://code.claude.com/docs/en/self-hosted-environments-configuration#post-session) on every session end, including runner shutdown |

47| `--proxy-authorization-command <command>` | `SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND` | unset | Shell command the runner runs for every connection to your egress proxy, using its trimmed stdout as the `Proxy-Authorization` header value. Requires `HTTPS_PROXY` or `HTTP_PROXY`, and can't be combined with `--proxy-authorization-file`. See [Authenticate to an egress proxy](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#authenticate-to-an-egress-proxy). Requires Claude Code v2.1.238 or later. |49| `--proxy-authorization-command <command>` | `SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND` | unset | Shell command the runner runs for every connection to your egress proxy, using its trimmed stdout as the `Proxy-Authorization` header value. Requires `HTTPS_PROXY` or `HTTP_PROXY`, and can't be combined with `--proxy-authorization-file`. See [Authenticate to an egress proxy](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#authenticate-to-an-egress-proxy). Requires Claude Code v2.1.238 or later. |

48| `--proxy-authorization-file <path>` | `SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE` | unset | File the runner reads for every connection to your egress proxy, using its trimmed contents as the `Proxy-Authorization` header value. Use this flag for a token another process rotates in place. Carries the same requirements as `--proxy-authorization-command`, and can't be combined with it. See [Authenticate to an egress proxy](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#authenticate-to-an-egress-proxy). Requires Claude Code v2.1.238 or later. |50| `--proxy-authorization-file <path>` | `SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE` | unset | File the runner reads for every connection to your egress proxy, using its trimmed contents as the `Proxy-Authorization` header value. Use this flag for a token another process rotates in place. Carries the same requirements as `--proxy-authorization-command`, and can't be combined with it. See [Authenticate to an egress proxy](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#authenticate-to-an-egress-proxy). Requires Claude Code v2.1.238 or later. |

49| `--push-outcome-on-release` | `SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE` | off | On a runner-initiated session end such as a drain or idle release, push tracked outcome branches to `origin` before deleting the workspace, so in-flight commits survive a restart. Best-effort; adds 30 seconds to the shutdown budget, and requires git 2.29 or newer to resume from the pushed branch. Restrict push access to `claude/*` refs before enabling; see [Resumed sessions lose unpushed work](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#additional-limitations). Repositories checked out via a `checkout` lifecycle hook aren't pushed; snapshot those from the [`post-session` hook](https://code.claude.com/docs/en/self-hosted-environments-configuration#post-session) instead. |51| `--push-outcome-on-release` | `SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE` | off | On a runner-initiated session end such as a drain or idle release, push tracked outcome branches to `origin` before deleting the workspace, so in-flight commits survive a restart. Best-effort; adds 30 seconds to the shutdown budget, and requires git 2.29 or newer to resume from the pushed branch. Restrict push access to `claude/*` refs before enabling; see [Resumed sessions lose unpushed work](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#additional-limitations). Repositories checked out via a `checkout` lifecycle hook aren't pushed; snapshot those from the [`post-session` hook](https://code.claude.com/docs/en/self-hosted-environments-configuration#post-session) instead. |

50| `--release-idle-session-min <n>` | `SELF_HOSTED_RUNNER_SESSION_IDLE_MS` | `0` | Release a session slot after N minutes of inactivity once a turn finishes or the session waits for the user's action. A session that's still mid-turn, including one holding a never-finishing background task or an approval requested from inside a running tool call, doesn't count as idle; pair with `--kill-session-after-min` as the hard backstop. After a session's background task finishes, the runner considers the session busy until the follow-up turn that reads the result starts, for at most the [`SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS`](#environment-variable-only-settings) window. Until the runner receives a shutdown signal or reaches its retire time, a release that leaves the runner with no active sessions starts the same exit path as a normal drain, governed by `--drain-grace-sec`. After a first signal you deferred with [`--defer-shutdown-max-min`](https://code.claude.com/docs/en/self-hosted-environments-deploy#defer-the-drain-past-the-first-signal), the runner exits as soon as a release leaves it holding no sessions. `0` disables. |52| `--release-idle-session-min <n>` | `SELF_HOSTED_RUNNER_SESSION_IDLE_MS` | `0` | Release a session slot after N minutes of inactivity once a turn finishes or the session waits for the user's action. [Some sessions don't count as idle](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#some-sessions-don’t-count-as-idle), so pair with `--kill-session-after-min`. A finished background task keeps the session busy for at most the [`SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS`](#environment-variable-only-settings) window. To delay a release, set [`--hold-idle-file`](https://code.claude.com/docs/en/self-hosted-environments-deploy#keep-an-idle-session-while-its-processes-run). `0` disables. |

51| `--remove-session-state [bool]` | `SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE` | off | Remove a session's per-session directories under `<base-dir>/_sessions/` when the session ends on this runner, whatever the outcome. [Reuse a pre-warmed checkout](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#reuse-a-pre-warmed-checkout) describes what they hold and who can read them when they stay. The removal is best-effort: the per-session directories stay in place when the runner is killed or reaches its drain deadline before cleanup runs. With the flag on, a failed or interrupted session's debug log isn't kept on disk. Requires Claude Code v2.1.268 or later. |53| `--remove-session-state [bool]` | `SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE` | off | Remove a session's per-session directories under `<base-dir>/_sessions/` when the session ends on this runner, whatever the outcome. [Reuse a pre-warmed checkout](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#reuse-a-pre-warmed-checkout) describes what they hold and who can read them when they stay. The removal is best-effort: the per-session directories stay in place when the runner is killed or reaches its drain deadline before cleanup runs. With the flag on, a failed or interrupted session's debug log isn't kept on disk. Requires Claude Code v2.1.268 or later. |

52| `--retire-at <epoch-seconds>` | `SELF_HOSTED_RUNNER_RETIRE_AT` | unset | Retire the runner at an absolute Unix timestamp in seconds, for infrastructure that kills the runner at a known time; [Runner lifecycle](https://code.claude.com/docs/en/self-hosted-environments#runner-lifecycle) describes the release sequence and how to size the margin. Values before 2001 or after the year 5138 are rejected by the flag and ignored by the environment variable. |54| `--retire-at <epoch-seconds>` | `SELF_HOSTED_RUNNER_RETIRE_AT` | unset | Retire the runner at an absolute Unix timestamp in seconds, for infrastructure that kills the runner at a known time; [Runner lifecycle](https://code.claude.com/docs/en/self-hosted-environments#runner-lifecycle) describes the release sequence and how to size the margin. Values before 2001 or after the year 5138 are rejected by the flag and ignored by the environment variable. |

53| `--server-auto-mode-lists <mode>` | `SELF_HOSTED_RUNNER_SERVER_AUTO_MODE_LISTS` | `no-allow` | Which of the [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) classifier rule lists that the control plane sends with a session may reach that session: `all`, `no-allow`, or `none`. See [Auto mode rule lists](#auto-mode-rule-lists) for what each value applies. An invalid value stops the runner at startup. Requires Claude Code v2.1.295 or later. |55| `--server-auto-mode-lists <mode>` | `SELF_HOSTED_RUNNER_SERVER_AUTO_MODE_LISTS` | `no-allow` | Which of the [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) classifier rule lists that the control plane sends with a session may reach that session: `all`, `no-allow`, or `none`. See [Auto mode rule lists](#auto-mode-rule-lists) for what each value applies. An invalid value stops the runner at startup. Requires Claude Code v2.1.295 or later. |


314 316 

315### Alert on lost runners and waiting sessions317### Alert on lost runners and waiting sessions

316 318 

317On a [fixed fleet](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#scale-the-fleet), load `ClaudeRunnersBelowFloor`. With [on-demand runners](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#on-demand-runners), load `ClaudeOrchestratorSessionsWaiting` and `ClaudeOrchestratorQueueWaitHigh` instead.319To be alerted when runners are lost, sessions wait, or the orchestrator is down, load these Prometheus alert rules beside the [sample alert rules](#sample-alert-rules):

320 

321* **[Fixed fleet](https://code.claude.com/docs/en/self-hosted-environments-deploy.md#scale-the-fleet)**: `ClaudeRunnersBelowFloor`

322* **[On-demand runners](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#on-demand-runners)**: `ClaudeOrchestratorSessionsWaiting`, `ClaudeOrchestratorQueueWaitHigh`, and `ClaudeOrchestratorAbsent`

318 323 

319#### Alert when a fixed fleet loses runners324#### Alert when a fixed fleet loses runners

320 325 


372* **Threshold**: if some session is always waiting, raise the `> 0` in `ClaudeOrchestratorSessionsWaiting` above the number you usually see377* **Threshold**: if some session is always waiting, raise the `> 0` in `ClaudeOrchestratorSessionsWaiting` above the number you usually see

373* **`ClaudeOrchestratorDisconnected`**: keep it loaded from the [sample alert rules](#sample-alert-rules), because `ClaudeOrchestratorSessionsWaiting` stops firing about 2 minutes after the last orchestrator in the namespace disconnects378* **`ClaudeOrchestratorDisconnected`**: keep it loaded from the [sample alert rules](#sample-alert-rules), because `ClaudeOrchestratorSessionsWaiting` stops firing about 2 minutes after the last orchestrator in the namespace disconnects

374 379 

380#### Alert when the orchestrator is down

381 

382To learn that the [orchestrator](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#on-demand-runners) itself is down, load `ClaudeOrchestratorAbsent`. It fires when no orchestrator in the namespace has been scraped for 5 minutes:

383 

384```yaml theme={null}

385groups:

386 # On-demand runners only. Replace claude-runners with the orchestrator's namespace.

387 - name: claude-code-self-hosted-on-demand-orchestrator

388 rules:

389 - alert: ClaudeOrchestratorAbsent

390 expr: absent(claude_code_self_hosted_orchestrator_connected{namespace="claude-runners"})

391 for: 5m

392 labels: {severity: critical}

393 annotations:

394 summary: "No orchestrator has been scraped for 5 minutes. If it's down, no on-demand runner starts, and sessions wait. Check the orchestrator workload first, then its scrape target if it's running."

395```

396 

397* **Namespace**: replace `claude-runners` with the orchestrator's namespace, and copy the alert for each further namespace that runs an orchestrator. If your targets have no `namespace` label, remove the matcher, or the alert fires after 5 minutes and stays on.

398* **Prometheus servers that don't scrape the orchestrator**: leave the alert out of their rule files, because on such a server it fires after 5 minutes and stays on

399* **Don't rely on the orchestrator's other alerts**: they read metrics that the orchestrator itself serves. `ClaudeOrchestratorSessionsWaiting`, `ClaudeOrchestratorQueueWaitHigh`, and the orchestrator's [sample alert rules](#sample-alert-rules) all stop firing within about 10 minutes of the orchestrator going down.

400 

375### Pass through session-child metrics401### Pass through session-child metrics

376 402 

377Each session runs in its own child process with its own OpenTelemetry metrics; at `--capacity` above one, the runner rewrites how those child metrics are exposed. Setting `OTEL_METRICS_EXPORTER=prometheus` on the runner host and `CLAUDE_CODE_ENABLE_TELEMETRY=1` in the session's environment, for example from your [wrapper script](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#wrapper-scripts) or the runner's own environment, which sessions inherit, re-exposes each child's counter and gauge instruments on the runner's own `/metrics` endpoint, alongside the runner's series. The runner rewrites the child's exporter to push over OTLP to a loopback-only receiver on the health port, tags each series with `session_id` and `client_platform` labels, and evicts a session's series when that session ends. Histograms don't pass through, and a child metric whose name would collide with the runner's own prefix is dropped.403Each session runs in its own child process with its own OpenTelemetry metrics; at `--capacity` above one, the runner rewrites how those child metrics are exposed. Setting `OTEL_METRICS_EXPORTER=prometheus` on the runner host and `CLAUDE_CODE_ENABLE_TELEMETRY=1` in the session's environment, for example from your [wrapper script](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#wrapper-scripts) or the runner's own environment, which sessions inherit, re-exposes each child's counter and gauge instruments on the runner's own `/metrics` endpoint, alongside the runner's series. The runner rewrites the child's exporter to push over OTLP to a loopback-only receiver on the health port, tags each series with `session_id` and `client_platform` labels, and evicts a session's series when that session ends. Histograms don't pass through, and a child metric whose name would collide with the runner's own prefix is dropped.

Details

288 288 

289 The command can't read from the keyboard when you pipe or redirect its input and, on macOS and Linux, it also can't open `/dev/tty`. If you pipe or redirect its output too, the run is non-interactive instead, and the delivered settings apply for that run only.289 The command can't read from the keyboard when you pipe or redirect its input and, on macOS and Linux, it also can't open `/dev/tty`. If you pipe or redirect its output too, the run is non-interactive instead, and the delivered settings apply for that run only.

290* **An error closes the dialog before you answer**: Claude Code doesn't apply the delivered settings and keeps the last-approved settings. It shows the dialog again in the next session that can show it.290* **An error closes the dialog before you answer**: Claude Code doesn't apply the delivered settings and keeps the last-approved settings. It shows the dialog again in the next session that can show it.

291* **A non-interactive run**, such as `claude -p`, an Agent SDK session, or a session in the VS Code extension's chat panel or the desktop app's Code tab: Claude Code can't show the dialog, so when the delivered settings would require approval, it applies them for that run only. It doesn't record them as approved or write them to the [local cache](#fetch-and-caching-behavior), and the next interactive session shows the dialog. Until a user approves in an interactive session, each non-interactive run fetches the settings again at startup. Before v2.1.207, a non-interactive run saved the settings as approved, so later interactive sessions never showed the dialog for them.291* **A non-interactive run**, such as `claude -p`, an Agent SDK session, or a session in the VS Code extension's chat panel or the desktop app's Code tab: Claude Code can't show the dialog. When the delivered settings would require approval, they apply for that run only.

292 

293 Claude Code doesn't record the settings as approved or write them to the [local cache](#fetch-and-caching-behavior), and the next interactive session shows the dialog. Until a user approves in an interactive session, each non-interactive run fetches the settings again at startup.

292 294 

293#### Environment variables and the approval dialog295#### Environment variables and the approval dialog

294 296 


306* `OTEL_EXPORTER_OTLP_ENDPOINT`308* `OTEL_EXPORTER_OTLP_ENDPOINT`

307* `CLAUDE_CODE_DISABLE_1M_CONTEXT`309* `CLAUDE_CODE_DISABLE_1M_CONTEXT`

308 310 

309When a delivered variable needs approval, the dialog names it, so the user sees exactly what the policy is asking to set. Before v2.1.218, Claude Code applied fewer variables without asking the user, so settings such as `DISABLE_AUTO_COMPACT` triggered the dialog at any non-empty value.311When a delivered variable needs approval, the dialog names it, so the user sees exactly what the policy is asking to set.

310 312 

311Claude Code decides whether four privacy toggles need approval by the delivered value rather than by the variable name: `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`, `DISABLE_ERROR_REPORTING`, `DISABLE_TELEMETRY`, and `DO_NOT_TRACK`. A truthy value such as `1` or `true` only turns tracking, reporting, or other nonessential traffic off, so Claude Code applies it without asking the user. For any other non-empty value, Claude Code shows the dialog. Before v2.1.218, all of them except `DO_NOT_TRACK` applied without approval at any value, and `DO_NOT_TRACK` triggered the dialog at any non-empty value.313Claude Code decides whether four privacy toggles need approval by the delivered value rather than by the variable name: `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`, `DISABLE_ERROR_REPORTING`, `DISABLE_TELEMETRY`, and `DO_NOT_TRACK`. A truthy value such as `1` or `true` only turns tracking, reporting, or other nonessential traffic off, so Claude Code applies it without asking the user. For any other non-empty value, Claude Code shows the dialog.

312 314 

313Claude Code also decides whether [`API_FORCE_IDLE_TIMEOUT`](https://code.claude.com/docs/en/env-vars) needs approval by the delivered value: a truthy value only turns the [body idle timeout](https://code.claude.com/docs/en/network-config.md#streaming-idle-watchdogs) on, so Claude Code applies it without asking the user. For any other non-empty value, Claude Code shows the dialog. Before v2.1.248, any non-empty value triggered the dialog.315Claude Code also decides whether [`API_FORCE_IDLE_TIMEOUT`](https://code.claude.com/docs/en/env-vars) needs approval by the delivered value: a truthy value only turns the [body idle timeout](https://code.claude.com/docs/en/network-config.md#streaming-idle-watchdogs) on, so Claude Code applies it without asking the user. For any other non-empty value, Claude Code shows the dialog. Before v2.1.248, any non-empty value triggered the dialog.

314 316 

sessions.md +2 −2

Details

46When Claude Code loads a conversation from its transcript, the resumed session restores the conversation along with the state saved in it:46When Claude Code loads a conversation from its transcript, the resumed session restores the conversation along with the state saved in it:

47 47 

48* Conversation history: the messages, tool calls, and results. If the session was [compacted](https://code.claude.com/docs/en/context-window.md#what-survives-compaction), the conversation opens at a `Conversation compacted` row. Claude continues with the last compaction's summary, the messages that compaction left unsummarized, and every message since. The messages that the last compaction summarized aren't loaded again.48* Conversation history: the messages, tool calls, and results. If the session was [compacted](https://code.claude.com/docs/en/context-window.md#what-survives-compaction), the conversation opens at a `Conversation compacted` row. Claude continues with the last compaction's summary, the messages that compaction left unsummarized, and every message since. The messages that the last compaction summarized aren't loaded again.

49* Interrupted tool calls: a tool that was still running when the previous process ended, for example in a crash, doesn't finish or get rerun when you resume. Claude sees the call marked as cut off before its result was recorded and is told to check whether it took effect before running it again, unless [`CLAUDE_CODE_RESUME_INTERRUPTED_TURN`](https://code.claude.com/docs/en/env-vars#variables) is set.49* Interrupted tool calls: a tool that was still running when the previous process ended, for example in a crash, doesn't get rerun when you resume.

50* Model: the session continues on the model it was using, except in the cases in [Setting your model](https://code.claude.com/docs/en/model-config.md#setting-your-model).50* Model: the session continues on the model it was using, except in the cases in [Setting your model](https://code.claude.com/docs/en/model-config.md#setting-your-model).

51* Agent: a session started with [`--agent`](https://code.claude.com/docs/en/sub-agents#invoke-subagents-explicitly) or the `agent` setting continues as that agent, keeping its tool restrictions and model. Pass `--agent` when resuming to pick a different one; for the system prompt in either case, see [System prompt flags in resumed conversations](https://code.claude.com/docs/en/cli-reference.md#system-prompt-flags-in-resumed-conversations). Claude Code looks for the agent in two places: the session's original directory, provided you have [trusted that workspace](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust), and then the directory you resume from, so a project-scoped agent still loads when you resume from another directory. If Claude Code doesn't find the agent in either place, the session resumes with the default tools and shows a [warning naming the agent](https://code.claude.com/docs/en/errors.md#session-agent-no-longer-available).51* Agent: a session started with [`--agent`](https://code.claude.com/docs/en/sub-agents#invoke-subagents-explicitly) or the `agent` setting continues as that agent, keeping its tool restrictions and model. Pass `--agent` when resuming to pick a different one; for the system prompt in either case, see [System prompt flags in resumed conversations](https://code.claude.com/docs/en/cli-reference.md#system-prompt-flags-in-resumed-conversations). Claude Code looks for the agent in two places: the session's original directory, provided you have [trusted that workspace](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust), and then the directory you resume from, so a project-scoped agent still loads when you resume from another directory. If Claude Code doesn't find the agent in either place, the session resumes with the default tools and shows a [warning naming the agent](https://code.claude.com/docs/en/errors.md#session-agent-no-longer-available).

52* Permission mode: if you resume from a terminal with `claude --continue`, `claude --resume <session-id>`, or `claude --resume <name>` when the name matches one session, without `-p`, Claude Code restores the permission mode the session was in, except in the cases in [permission mode on resume](#permission-mode-on-resume), which also covers the session picker, `/resume`, and resuming with `claude -p`. Pass `--permission-mode` or `--dangerously-skip-permissions` to override the restored mode.52* Permission mode: if you resume from a terminal with `claude --continue`, `claude --resume <session-id>`, or `claude --resume <name>` when the name matches one session, without `-p`, Claude Code restores the permission mode the session was in, except in the cases in [permission mode on resume](#permission-mode-on-resume), which also covers the session picker, `/resume`, and resuming with `claude -p`. Pass `--permission-mode` or `--dangerously-skip-permissions` to override the restored mode.


224* **`/compact [instructions]`**: replace history with a summary, optionally focused on what you specify224* **`/compact [instructions]`**: replace history with a summary, optionally focused on what you specify

225* **`/context`**: show what is currently consuming context225* **`/context`**: show what is currently consuming context

226 226 

227For how compaction interacts with CLAUDE.md, skills, and rules, see the [context window guide](https://code.claude.com/docs/en/context-window.md). For strategies on when to clear versus compact, see [Best practices](https://code.claude.com/docs/en/best-practices.md#manage-your-session).227For how compaction interacts with CLAUDE.md, skills, and rules, see the [context window guide](https://code.claude.com/docs/en/context-window.md). For strategies on when to clear versus compact, see [Best practices](https://code.claude.com/docs/en/best-practices.md#keep-cost-and-context-down).

228 228 

229## Export and locate session data229## Export and locate session data

230 230 

settings.md +1 −1

Details

326* **Shared project settings with several repositories**: in an Anthropic-hosted environment, a session with several repositories starts above the clones and reads only the `enabledPlugins` and `extraKnownMarketplaces` keys from each repository's `.claude/settings.json`, not permission rules, hooks, `env`, or other keys. The marketplaces and plugins those two keys declare still [don't load in a cloud session](https://code.claude.com/docs/en/cloud-environments.md#what-carries-over-from-your-setup). For a self-hosted environment, see [which repository's settings apply](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#repository-settings-in-sessions-with-several-repositories).326* **Shared project settings with several repositories**: in an Anthropic-hosted environment, a session with several repositories starts above the clones and reads only the `enabledPlugins` and `extraKnownMarketplaces` keys from each repository's `.claude/settings.json`, not permission rules, hooks, `env`, or other keys. The marketplaces and plugins those two keys declare still [don't load in a cloud session](https://code.claude.com/docs/en/cloud-environments.md#what-carries-over-from-your-setup). For a self-hosted environment, see [which repository's settings apply](https://code.claude.com/docs/en/self-hosted-environments-configuration.md#repository-settings-in-sessions-with-several-repositories).

327* **User and project local settings** (`~/.claude/settings.json` and `.claude/settings.local.json`): not read. Both stay on your machine, and the local file isn't in the clone.327* **User and project local settings** (`~/.claude/settings.json` and `.claude/settings.local.json`): not read. Both stay on your machine, and the local file isn't in the clone.

328* **Managed settings**: a `managed-settings.json` file or MDM profile on your device doesn't reach a cloud session. Your organization's [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md) do; [surface coverage](https://code.claude.com/docs/en/model-config.md#surface-coverage) lists which cloud sessions receive them. A [self-hosted environment](https://code.claude.com/docs/en/self-hosted-environments) also reads the managed settings file in its runner image. [How Claude Code combines managed sources](https://code.claude.com/docs/en/managed-settings.md#how-claude-code-combines-managed-sources) says when that file applies.328* **Managed settings**: a `managed-settings.json` file or MDM profile on your device doesn't reach a cloud session. Your organization's [server-managed settings](https://code.claude.com/docs/en/server-managed-settings.md) do; [surface coverage](https://code.claude.com/docs/en/model-config.md#surface-coverage) lists which cloud sessions receive them. A [self-hosted environment](https://code.claude.com/docs/en/self-hosted-environments) also reads the managed settings file in its runner image. [How Claude Code combines managed sources](https://code.claude.com/docs/en/managed-settings.md#how-claude-code-combines-managed-sources) says when that file applies.

329* **`/config`**: in your browser at claude.ai/code, opens the Claude Code section of your claude.ai settings instead of changing a value. To change a setting for a cloud session, set an [environment variable](https://code.claude.com/docs/en/cloud-environments.md#set-environment-variables) on the environment. In a session with one repository outside a project's threads, you can instead commit the key to that repository's `.claude/settings.json`.329* **`/config`**: in your browser at claude.ai/code, opens your claude.ai **Code** or **Claude Code** settings page instead of changing a value. To change a setting for a cloud session, set an [environment variable](https://code.claude.com/docs/en/cloud-environments.md#set-environment-variables) on the environment. In a session with one repository outside a project's threads, you can instead commit the key to that repository's `.claude/settings.json`.

330 330 

331[What carries over from your setup](https://code.claude.com/docs/en/cloud-environments.md#what-carries-over-from-your-setup) lists the rest: `CLAUDE.md`, skills, MCP servers, plugins, and credentials.331[What carries over from your setup](https://code.claude.com/docs/en/cloud-environments.md#what-carries-over-from-your-setup) lists the rest: `CLAUDE.md`, skills, MCP servers, plugins, and credentials.

332 332 

Details

1293* A command starting with `sudo`, `eval`, or `xargs`1293* A command starting with `sudo`, `eval`, or `xargs`

1294* A `cd`, `pushd`, or `popd`, wherever it appears in the call1294* A `cd`, `pushd`, or `popd`, wherever it appears in the call

1295* A command substitution, a subshell, or a control-flow block such as `if` or `for`1295* A command substitution, a subshell, or a control-flow block such as `if` or `for`

1296* A redirection, such as `docker build . > build.log`, other than one that only duplicates a file descriptor, as `2>&1` does1296* A redirection, such as `docker build . > build.log` or a `<<EOF` heredoc, other than one that only duplicates a file descriptor, as `2>&1` does

1297* A command name that comes from a variable1297* A command name that comes from a variable

1298* A `git clone`, `git init`, `git worktree add`, `git worktree move`, or `git bundle create` with a path argument that is absolute, starts with `~`, or contains a `..` segment1298* A `git clone`, `git init`, `git worktree add`, `git worktree move`, or `git bundle create` with a path argument that is absolute, starts with `~`, or contains a `..` segment

1299 1299 


1521 1521 

1522### `sandbox.filesystem.disabled`1522### `sandbox.filesystem.disabled`

1523 1523 

1524Skip filesystem isolation while keeping network isolation. Sandboxed commands get unrestricted read and write access to the host filesystem, and their network egress stays confined to [`network.allowedDomains`](#sandbox-network-alloweddomains). Use it when you sandbox to control where commands connect rather than what they write. Requires Claude Code v2.1.216 or later.1524Skip filesystem isolation while keeping network isolation. Sandboxed commands get unrestricted read and write access to the host filesystem, and their network egress stays confined to [`network.allowedDomains`](#sandbox-network-alloweddomains). Use it when you sandbox to control where commands connect rather than what they write.

1525 1525 

1526* **Scope**: [`User or managed`](#scopes). When managed settings configure `sandbox.filesystem` at all, or list a `sandbox.credentials.files` entry with `"mode": "deny"`, only managed settings can set it.1526* **Scope**: [`User or managed`](#scopes). When managed settings configure `sandbox.filesystem` at all, or list a `sandbox.credentials.files` entry with `"mode": "deny"`, only managed settings can set it.

1527* **Type**: Boolean1527* **Type**: Boolean


1545}1545}

1546```1546```

1547 1547 

1548With the layer off, Claude Code doesn't enforce `denyRead` or `credentials.files` `deny` entries, while `credentials.envVars` entries and applied `mask` entries keep working. [`autoAllowBashIfSandboxed`](#sandbox-autoallowbashifsandboxed) still defaults to `true`, so set it to `false` to keep prompting. See [Disable filesystem isolation](https://code.claude.com/docs/en/sandboxing.md#disable-filesystem-isolation) for the full list of sources that can set it and what changes when isolation is off. Requires Claude Code v2.1.216 or later.1548With the layer off, Claude Code doesn't enforce `denyRead` or `credentials.files` `deny` entries, while `credentials.envVars` entries and applied `mask` entries keep working. [`autoAllowBashIfSandboxed`](#sandbox-autoallowbashifsandboxed) still defaults to `true`, so set it to `false` to keep prompting. See [Disable filesystem isolation](https://code.claude.com/docs/en/sandboxing.md#disable-filesystem-isolation) for the full list of sources that can set it and what changes when isolation is off.

1549 1549 

1550### `sandbox.ignoreViolations`1550### `sandbox.ignoreViolations`

1551 1551 


2392* [`CLAUDE_CODE_RESTRICTED`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code reads from the launch environment only, is ignored from every file.2392* [`CLAUDE_CODE_RESTRICTED`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code reads from the launch environment only, is ignored from every file.

2393* [`CLAUDE_CODE_DISABLE_POWERSHELL_CMD_RM_DENY`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code reads from the launch environment only, is ignored from every file. The variable requires Claude Code v2.1.283 or later.2393* [`CLAUDE_CODE_DISABLE_POWERSHELL_CMD_RM_DENY`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code reads from the launch environment only, is ignored from every file. The variable requires Claude Code v2.1.283 or later.

2394* [`CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT`, `CLAUDE_CODE_DISABLE_SUBSTITUTION_RM_PROMPT`, `CLAUDE_CODE_DISABLE_INLINE_SHELL_RM_PROMPT`, and `CLAUDE_CODE_DISABLE_MOUNTED_DRIVE_RM_PROMPT`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code reads from the launch environment only, are ignored from every file.2394* [`CLAUDE_CODE_DISABLE_DANGEROUS_RM_TIMEOUT`, `CLAUDE_CODE_DISABLE_SUBSTITUTION_RM_PROMPT`, `CLAUDE_CODE_DISABLE_INLINE_SHELL_RM_PROMPT`, and `CLAUDE_CODE_DISABLE_MOUNTED_DRIVE_RM_PROMPT`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code reads from the launch environment only, are ignored from every file.

2395* [`CLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code reads from the launch environment only, is ignored from every file.

2395* [`CLAUDE_CODE_WARN_DISK_FREE_GIB` and `CLAUDE_CODE_WARN_MEMORY_FREE_GIB`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code reads from the launch environment only, are ignored from every file. The variables require Claude Code v2.1.304 or later.2396* [`CLAUDE_CODE_WARN_DISK_FREE_GIB` and `CLAUDE_CODE_WARN_MEMORY_FREE_GIB`](https://code.claude.com/docs/en/env-vars#variables), which Claude Code reads from the launch environment only, are ignored from every file. The variables require Claude Code v2.1.304 or later.

2396 2397 

2397### `fileCheckpointingEnabled`2398### `fileCheckpointingEnabled`


2716}2717}

2717```2718```

2718 2719 

2719See [Emoji shortcodes](https://code.claude.com/docs/en/interactive-mode.md#emoji-shortcodes). Requires Claude Code v2.1.217 or later.2720See [Emoji shortcodes](https://code.claude.com/docs/en/interactive-mode.md#emoji-shortcodes).

2720 2721 

2721### `fileSuggestion`2722### `fileSuggestion`

2722 2723 


3691 3692 

3692### `workflowSizeGuideline`3693### `workflowSizeGuideline`

3693 3694 

3694Set the [agent count Claude aims for](https://code.claude.com/docs/en/workflows.md#set-a-size-guideline) in the dynamic workflows it writes. Claude Code sends the value to Claude as advice, not an enforced cap: `"small"` asks for fewer than 5 agents, `"medium"` fewer than 10, and `"large"` fewer than 50. Choose `"small"` when you want to bound what a workflow spends. Requires Claude Code v2.1.219 or later.3695Set the [agent count Claude aims for](https://code.claude.com/docs/en/workflows.md#set-a-size-guideline) in the dynamic workflows it writes. Claude Code sends the value to Claude as advice, not an enforced cap: `"small"` asks for fewer than 5 agents, `"medium"` fewer than 10, and `"large"` fewer than 50. Choose `"small"` when you want to bound what a workflow spends.

3695 3696 

3696* **Scope**: [`Any file`](#scopes). A value there takes precedence over the **Dynamic workflow size** choice in `/config`, which Claude Code stores in `~/.claude.json`, and Claude Code hides that row while a settings file sets the key.3697* **Scope**: [`Any file`](#scopes). A value there takes precedence over the **Dynamic workflow size** choice in `/config`, which Claude Code stores in `~/.claude.json`, and Claude Code hides that row while a settings file sets the key.

3697* **Type**: string, one of:3698* **Type**: string, one of:


3707}3708}

3708```3709```

3709 3710 

3710Requires Claude Code v2.1.219 or later; on v2.1.202 through v2.1.218, set the guideline in `/config` instead.

3711 

3712## Plugins and skills3711## Plugins and skills

3713 3712 

3714Enable plugins, register marketplaces, restrict which plugin sources an organization allows, and control which skills load. For installing and building plugins, see [Plugins](https://code.claude.com/docs/en/plugins/overview.md).3713Enable plugins, register marketplaces, restrict which plugin sources an organization allows, and control which skills load. For installing and building plugins, see [Plugins](https://code.claude.com/docs/en/plugins/overview.md).

skills.md +5 −7

Details

83| Subcommand | What it does | Minimum version |83| Subcommand | What it does | Minimum version |

84| :- | :- | :- |84| :- | :- | :- |

85| `migrate` | Update your existing Claude API code to a newer model | Earlier than v2.1.221 |85| `migrate` | Update your existing Claude API code to a newer model | Earlier than v2.1.221 |

86| `upgrade` | Move your project's Anthropic SDK dependency across a major version, currently the Python `anthropic` package from 0.x to 1.x | v2.1.236 or later |86| `upgrade` | Upgrade your project's Anthropic SDK to a new major version and update your code for its breaking changes | v2.1.236 or later |

87| `api-version` | Update your Claude API code for a newer [API version](https://platform.claude.com/docs/en/api/versioning), then switch your requests to that version | v2.1.307 or later |87| `api-version` | Update your Claude API code for a newer [API version](https://platform.claude.com/docs/en/api/versioning), then switch your requests to that version | v2.1.307 or later |

88| `managed-agents-onboard` | Walk through creating a new Managed Agent | Earlier than v2.1.221 |88| `managed-agents-onboard` | Walk through creating a new Managed Agent | Earlier than v2.1.221 |

89| `managed-agents-onboard <url>` | Build the Managed Agent that the page at the URL describes, such as a page in the [Managed Agents docs](https://platform.claude.com/docs/en/managed-agents/overview) | v2.1.290 or later |89| `managed-agents-onboard <url>` | Build the Managed Agent that the page at the URL describes, such as a page in the [Managed Agents docs](https://platform.claude.com/docs/en/managed-agents/overview) | v2.1.290 or later |


3713. Push to the deployment target3713. Push to the deployment target

372```372```

373 373 

374Keep the body itself concise. Once a skill loads, its content [stays in context across turns](#skill-content-lifecycle), so every line is a recurring token cost. State what to do rather than narrating how or why, and apply the same conciseness test you would for [CLAUDE.md content](https://code.claude.com/docs/en/best-practices.md#write-an-effective-claude-md).374Keep the body itself concise. Once a skill loads, its content [stays in context across turns](#skill-content-lifecycle), so every line is a recurring token cost. State what to do rather than narrating how or why, and apply the same conciseness test you would for [CLAUDE.md content](https://code.claude.com/docs/en/best-practices.md#keep-claude-md-short).

375 375 

376### Frontmatter reference376### Frontmatter reference

377 377 


388Your skill instructions here...388Your skill instructions here...

389```389```

390 390 

391All fields are optional. Only `description` is recommended so Claude knows when to use the skill. A field name must match the table exactly, hyphens included: Claude Code ignores a field it doesn't recognize without reporting an error.391All fields are optional. Only `description` is recommended so Claude knows when to use the skill. A field name must match the table exactly, hyphens included: Claude Code ignores a field it doesn't recognize without reporting an error. Boolean fields accept `yes`, `no`, `on`, `off`, `1`, and `0` in any letter case, in addition to `true` and `false`.

392 392 

393Claude Code reads the frontmatter only when the opening `---` is the file's first line. Otherwise it treats the whole file, `---` markers included, as skill content. If the YAML between the markers doesn't parse, the skill still loads with no fields set; see [Skill not triggering](#skill-not-triggering) to find and fix the error.393Claude Code reads the frontmatter only when the opening `---` is the file's first line. Otherwise it treats the whole file, `---` markers included, as skill content. If the YAML between the markers doesn't parse, the skill still loads with no fields set; see [Skill not triggering](#skill-not-triggering) to find and fix the error.

394 394 

395Boolean fields accept `yes`, `no`, `on`, `off`, `1`, and `0` in any letter case, in addition to `true` and `false`. Before v2.1.218, Claude Code recognized only `true` and `false`.

396 

397| Field | Required | Description |395| Field | Required | Description |

398| :- | :- | :- |396| :- | :- | :- |

399| `name` | No | Command name shown in the `/` menu. Defaults to the directory name. See [How a skill gets its command name](#how-a-skill-gets-its-command-name) for how the field interacts with the name you type to invoke the skill. |397| `name` | No | Command name shown in the `/` menu. Defaults to the directory name. See [How a skill gets its command name](#how-a-skill-gets-its-command-name) for how the field interacts with the name you type to invoke the skill. |


409| `effort` | No | [Effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) when this skill is active. Overrides the session effort level. When you omit it, the level comes from the [effort resolution order](https://code.claude.com/docs/en/model-config.md#adjust-effort-level). Options: `low`, `medium`, `high`, `xhigh`, `max`; available levels depend on the model. |407| `effort` | No | [Effort level](https://code.claude.com/docs/en/model-config.md#adjust-effort-level) when this skill is active. Overrides the session effort level. When you omit it, the level comes from the [effort resolution order](https://code.claude.com/docs/en/model-config.md#adjust-effort-level). Options: `low`, `medium`, `high`, `xhigh`, `max`; available levels depend on the model. |

410| `context` | No | Set to `fork` to run in a forked subagent context. See [Run skills in a subagent](#run-skills-in-a-subagent). |408| `context` | No | Set to `fork` to run in a forked subagent context. See [Run skills in a subagent](#run-skills-in-a-subagent). |

411| `agent` | No | Which subagent type to use when `context: fork` is set. |409| `agent` | No | Which subagent type to use when `context: fork` is set. |

412| `background` | No | Only applies with `context: fork`. Set to `false` to wait for the forked subagent's result in the turn that invoked the skill, instead of [running it in the background](#run-skills-in-a-subagent). Default: `true`. Requires Claude Code v2.1.218 or later. |410| `background` | No | Only applies with `context: fork`. Set to `false` to wait for the forked subagent's result in the turn that invoked the skill, instead of [running it in the background](#run-skills-in-a-subagent). Default: `true`. |

413| `hooks` | No | Hooks that Claude Code registers when the skill is invoked and keeps running for the rest of the session. See [Hooks in skills and agents](https://code.claude.com/docs/en/hooks.md#hooks-in-skills-and-agents) for the configuration format, the `once` option, and the [limits on skill hooks](https://code.claude.com/docs/en/hooks.md#limits-on-skill-hooks). |411| `hooks` | No | Hooks that Claude Code registers when the skill is invoked and keeps running for the rest of the session. See [Hooks in skills and agents](https://code.claude.com/docs/en/hooks.md#hooks-in-skills-and-agents) for the configuration format, the `once` option, and the [limits on skill hooks](https://code.claude.com/docs/en/hooks.md#limits-on-skill-hooks). |

414| `paths` | No | Glob patterns that limit when this skill is activated. Accepts a comma-separated string or a YAML list. When set, Claude loads the skill automatically only when working with files matching the patterns. Patterns are relative to Claude's current working directory, and files outside that directory don't match. Uses the same glob format as [path-specific rules](https://code.claude.com/docs/en/memory.md#path-specific-rules). |412| `paths` | No | Glob patterns that limit when this skill is activated. Accepts a comma-separated string or a YAML list. When set, Claude loads the skill automatically only when working with files matching the patterns. Patterns are relative to Claude's current working directory, and files outside that directory don't match. Uses the same glob format as [path-specific rules](https://code.claude.com/docs/en/memory.md#path-specific-rules). |

415| `shell` | No | Shell to use for `` !`command` `` and ` ```! ` blocks in this skill. Accepts `bash` (default) or `powershell`. Setting `powershell` runs inline shell commands via PowerShell when the [PowerShell tool](https://code.claude.com/docs/en/tools-reference.md#powershell-tool) is enabled: it's on by default on Windows without Git Bash, on by default with Git Bash for claude.ai and Console accounts, and needs `CLAUDE_CODE_USE_POWERSHELL_TOOL=1` in Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry sessions and on macOS, Linux, and WSL. Set it to `0` to turn the tool off. |413| `shell` | No | Shell to use for `` !`command` `` and ` ```! ` blocks in this skill. Accepts `bash` (default) or `powershell`. Setting `powershell` runs inline shell commands via PowerShell when the [PowerShell tool](https://code.claude.com/docs/en/tools-reference.md#powershell-tool) is enabled: it's on by default on Windows without Git Bash, on by default with Git Bash for claude.ai and Console accounts, and needs `CLAUDE_CODE_USE_POWERSHELL_TOOL=1` in Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry sessions and on macOS, Linux, and WSL. Set it to `0` to turn the tool off. |


800>798>

801> Despite the name, a skill with `context: fork` doesn't run in a [fork of the current conversation](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation), which would hand the subagent everything you've discussed so far. When the task depends on that history, fork the conversation instead of using `context: fork`.799> Despite the name, a skill with `context: fork` doesn't run in a [fork of the current conversation](https://code.claude.com/docs/en/sub-agents.md#fork-the-current-conversation), which would hand the subagent everything you've discussed so far. When the task depends on that history, fork the conversation instead of using `context: fork`.

802 800 

803The forked subagent runs in the [background](https://code.claude.com/docs/en/sub-agents.md#run-subagents-in-foreground-or-background): you keep working while it runs, and its result arrives in your conversation when it completes. Set `background: false` in the frontmatter to instead wait for the result in the turn that invoked the skill. Before v2.1.218, forked skills always blocked the turn until they finished.801The forked subagent runs in the [background](https://code.claude.com/docs/en/sub-agents.md#run-subagents-in-foreground-or-background): you keep working while it runs, and its result arrives in your conversation when it completes. Set `background: false` in the frontmatter to instead wait for the result in the turn that invoked the skill.

804 802 

805Claude Code also waits for the result, even when the skill doesn't set `background: false`, in cases like these:803Claude Code also waits for the result, even when the skill doesn't set `background: false`, in cases like these:

806 804 

sub-agents.md +2 −9

Details

352* **Full model ID**: use a full model ID such as `claude-opus-5-5` or `claude-sonnet-5`. Accepts the same values as the `--model` flag352* **Full model ID**: use a full model ID such as `claude-opus-5-5` or `claude-sonnet-5`. Accepts the same values as the `--model` flag

353* **inherit**: use the same model as the main conversation353* **inherit**: use the same model as the main conversation

354 354 

355When Claude invokes a subagent, it can also pass a `model` parameter for that specific invocation. Claude Code resolves the subagent's model in this order:355When Claude invokes a subagent, it can also pass a `model` parameter for that specific invocation. On an Agent tool call, that parameter takes a model alias: `sonnet`, `opus`, `haiku`, or `fable`. Claude can't pass a full model ID or `inherit` on that call. Claude Code resolves the subagent's model in this order:

356 356 

3571. The per-invocation `model` parameter3571. The per-invocation `model` parameter

3582. The subagent definition's `model` frontmatter, where `inherit` selects the main conversation's model3582. The subagent definition's `model` frontmatter, where `inherit` selects the main conversation's model


762 762 

763To let a project-level subagent's frontmatter hooks run, accept the [workspace trust dialog](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust) for the folder that contains the agent file. Hooks from user-level subagents in `~/.claude/agents/` and from definitions you pass with `--agents` run without this step. If you added a folder with `--add-dir` from outside your trusted workspace's repository, trust that folder separately: its `.claude/agents/` hooks don't inherit the workspace's grant.763To let a project-level subagent's frontmatter hooks run, accept the [workspace trust dialog](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust) for the folder that contains the agent file. Hooks from user-level subagents in `~/.claude/agents/` and from definitions you pass with `--agents` run without this step. If you added a folder with `--add-dir` from outside your trusted workspace's repository, trust that folder separately: its `.claude/agents/` hooks don't inherit the workspace's grant.

764 764 

765Until you trust the folder, the subagent still runs, but Claude Code skips its frontmatter hooks and logs an error to the debug log explaining how to trust the folder. This is a stricter rule than the one for hooks in settings files: trusting a parent folder isn't enough, and a `-p` session doesn't count as trusted. [What runs before you trust a folder](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder) compares the two. Before v2.1.218, frontmatter hooks could run from folders you hadn't trusted, including in non-interactive sessions.765Until you trust the folder, the subagent still runs, but Claude Code skips its frontmatter hooks and logs an error to the debug log explaining how to trust the folder. This is a stricter rule than the one for hooks in settings files: trusting a parent folder isn't enough, and a `-p` session doesn't count as trusted. [What runs before you trust a folder](https://code.claude.com/docs/en/permissions.md#what-runs-before-you-trust-a-folder) compares the two.

766 766 

767All [hook events](https://code.claude.com/docs/en/hooks.md#hook-events) are supported. The most common events for subagents are:767All [hook events](https://code.claude.com/docs/en/hooks.md#hook-events) are supported. The most common events for subagents are:

768 768 


1075 1075 

1076In the terminal, Claude Code shows nested subagents as a tree in the subagent panel below the prompt input and marks each row that still has descendants in the panel with a `(+N)` count of them. Open a row to see that subagent's siblings and direct children with a path back to `main`.1076In the terminal, Claude Code shows nested subagents as a tree in the subagent panel below the prompt input and marks each row that still has descendants in the panel with a `(+N)` count of them. Open a row to see that subagent's siblings and direct children with a path back to `main`.

1077 1077 

1078> [!NOTE]

1079>

1080> Earlier versions used different defaults:

1081>

1082> * **v2.1.172 through v2.1.216**: subagents could nest by default, up to five layers deep, and the limit couldn't be changed.

1083> * **v2.1.217 through v2.1.218**: the limit defaulted to one, so a subagent couldn't spawn its own unless you raised it; v2.1.219 raised the default to three.

1084 

1085### Concurrent subagent limit1078### Concurrent subagent limit

1086 1079 

1087Two limits control subagent use, each with its own variable: this one stops Claude from spawning more subagents while too many are running, and the [depth limit](#let-subagents-spawn-their-own-subagents) caps how deeply subagents nest. There's no limit on the total number of subagents Claude can spawn over a session.1080Two limits control subagent use, each with its own variable: this one stops Claude from spawning more subagents while too many are running, and the [depth limit](#let-subagents-spawn-their-own-subagents) caps how deeply subagents nest. There's no limit on the total number of subagents Claude can spawn over a session.

Details

290>290>

291> Each [subagent](https://code.claude.com/docs/en/sub-agents.md) and parallel task is shown in one of eight named colors so you can tell them apart in the transcript. The token names follow the pattern `<color>_FOR_SUBAGENTS_ONLY`, where `<color>` is `red`, `blue`, `green`, `yellow`, `purple`, `orange`, `pink`, or `cyan`. Override these to change what each named color looks like. For example, a subagent with `color: blue` in its definition is drawn using the `blue_FOR_SUBAGENTS_ONLY` value.291> Each [subagent](https://code.claude.com/docs/en/sub-agents.md) and parallel task is shown in one of eight named colors so you can tell them apart in the transcript. The token names follow the pattern `<color>_FOR_SUBAGENTS_ONLY`, where `<color>` is `red`, `blue`, `green`, `yellow`, `purple`, `orange`, `pink`, or `cyan`. Override these to change what each named color looks like. For example, a subagent with `color: blue` in its definition is drawn using the `blue_FOR_SUBAGENTS_ONLY` value.

292>292>

293> Claude Code renders the [`ultrathink`](https://code.claude.com/docs/en/model-config#use-ultrathink-for-one-off-deep-reasoning) keyword in the prompt input with a seven-color rainbow gradient. The token names follow the pattern `rainbow_<color>` and `rainbow_<color>_shimmer`, where `<color>` is `red`, `orange`, `yellow`, `green`, `blue`, `indigo`, or `violet`.293> When [`ultrathink`](https://code.claude.com/docs/en/model-config#use-ultrathink-for-one-off-deep-reasoning) can raise a turn's effort, Claude Code renders the word in the prompt input with a seven-color rainbow gradient. The token names follow the pattern `rainbow_<color>` and `rainbow_<color>_shimmer`, where `<color>` is `red`, `orange`, `yellow`, `green`, `blue`, `indigo`, or `violet`.

294 294 

295## Switch to fullscreen rendering295## Switch to fullscreen rendering

296 296 

ultrareview.md +4 −2

Details

85 85 

86### Pass a request in plain words86### Pass a request in plain words

87 87 

88On Claude Code v2.1.218 or later, you can also describe what you're working on in plain words:88You can also describe what you're working on in plain words:

89 89 

90```text theme={null}90```text theme={null}

91/code-review ultra check my auth changes91/code-review ultra check my auth changes


159 159 

160You consent to the whole-repository fallback and to the billing and terms prompt when you run the subcommand, so the run doesn't stop to confirm them. Running it yourself is what counts as consent. When Claude runs the subcommand for you instead, for example through the Bash tool, Claude Code refuses the whole-repository review.160You consent to the whole-repository fallback and to the billing and terms prompt when you run the subcommand, so the run doesn't stop to confirm them. Running it yourself is what counts as consent. When Claude runs the subcommand for you instead, for example through the Bash tool, Claude Code refuses the whole-repository review.

161 161 

162`claude -p '/code-review ultra'` doesn't get you the findings, so use `claude ultrareview` in scripts. The `-p` run launches the cloud review and exits without waiting for it. When the review would bill usage credits, the `-p` run stops without launching it. Before v2.1.218, `/code-review ultra` in a non-interactive session ran a local review.162> [!NOTE]

163>

164> `claude -p '/code-review ultra'` doesn't get you the findings, so use `claude ultrareview` in scripts. The `-p` run launches the cloud review and exits without waiting for it. When the review would bill usage credits, the `-p` run stops without launching it.

163 165 

164| Flag | Description |166| Flag | Description |

165| - | - |167| - | - |

Details

182* You can also click **Changes** in the session's title bar, or in the bar's **⋮** menu.182* You can also click **Changes** in the session's title bar, or in the bar's **⋮** menu.

183* To show the panel when it's hidden, click the **Show session rail** icon in the session's title bar, or in the bar's **⋮** menu.183* To show the panel when it's hidden, click the **Show session rail** icon in the session's title bar, or in the bar's **⋮** menu.

184 184 

185The diff compares the session's changes against its base branch by default. To compare against a different branch, select **Compare against** and pick one.185The diff compares the session's changes against its base branch by default. To compare against a different branch, select **Compare against** and pick one. Against the base branch, the diff can [leave out changes that aren't pushed yet](https://code.claude.com/docs/en/claude-code-on-the-web.md#troubleshoot-a-missing-file-in-the-diff-view).

186 186 

187**2. Leave inline comments**187**2. Leave inline comments**

188 188 

189Select any line in the diff, type your feedback, and press Enter. Comments queue up until you send your next message, then they're bundled with it. Claude sees "at `src/auth.ts:47`, don't catch the error here" alongside your main instruction, so you don't have to describe where the problem is.189Hover over a line in the diff and click the **+** that appears beside its line number to open a comment box, then type your feedback and press Enter. Comments queue up until you send your next message, then they're bundled with it. Claude sees "at `src/auth.ts:47`, don't catch the error here" alongside your main instruction, so you don't have to describe where the problem is.

190 190 

191**3. Create a pull request**191**3. Create a pull request**

192 192 

workflows.md +5 −9

Details

155* The session's [concurrent subagent limit](https://code.claude.com/docs/en/sub-agents.md#concurrent-subagent-limit) isn't enforced for the subagents Claude spawns with the Agent tool155* The session's [concurrent subagent limit](https://code.claude.com/docs/en/sub-agents.md#concurrent-subagent-limit) isn't enforced for the subagents Claude spawns with the Agent tool

156* In auto permission mode, you aren't asked to [approve the first workflow launch](#approve-the-plan-before-it-runs)156* In auto permission mode, you aren't asked to [approve the first workflow launch](#approve-the-plan-before-it-runs)

157 157 

158`/effort ultracode` lasts for the current session; to have every session start with it, set the [`ultracode`](https://code.claude.com/docs/en/settings-reference#ultracode) setting. Turn it off with `/effort ultracode off` when you return to routine work. The `/effort` slider offers the toggle only [when ultracode is available](https://code.claude.com/docs/en/model-config.md#when-ultracode-is-available).158`/effort ultracode` lasts for the current session; to have every session start with it, set the [`ultracode`](https://code.claude.com/docs/en/settings-reference#ultracode) setting. Turn it off with `/effort ultracode off` when you return to routine work. The `/effort` slider offers the toggle only [when ultracode is available](https://code.claude.com/docs/en/model-config.md#when-ultracode-is-available). Before v2.1.284, `/effort ultracode` set the session to `xhigh`, and `/effort ultracode off` failed with `Invalid argument`.

159 159 

160### Approve the plan before it runs160### Approve the plan before it runs

161 161 


198* `.claude/workflows/` in your project: shared with everyone who clones the repo198* `.claude/workflows/` in your project: shared with everyone who clones the repo

199* `~/.claude/workflows/` in your home directory: available in every project, visible only to you. If you set [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars), this location is the `workflows/` directory under that path.199* `~/.claude/workflows/` in your home directory: available in every project, visible only to you. If you set [`CLAUDE_CONFIG_DIR`](https://code.claude.com/docs/en/env-vars), this location is the `workflows/` directory under that path.

200 200 

201The save dialog shows the resolved path for the personal location.201The save dialog shows the resolved path for the personal location. Press Enter to save. The workflow runs as `/<name>` in future sessions from either location.

202 202 

203Press Enter to save. The workflow runs as `/<name>` in future sessions from either location.203Claude Code checks the save location for symlinks before writing, and shows an error instead of writing through one:

204 

205Claude Code checks the save location for symlinks before writing, and shows an error instead of writing through one. What it checks depends on where you save:

206 204 

207* Project location: Claude Code refuses if `.claude`, `.claude/workflows`, or the target file is a symlink.205* Project location: Claude Code refuses if `.claude`, `.claude/workflows`, or the target file is a symlink.

208* Personal location: Claude Code refuses only if the target file itself is a symlink, so a `~/.claude` directory managed by a dotfiles tool still works.206* Personal location: Claude Code refuses only if the target file itself is a symlink, so a `~/.claude` directory managed by a dotfiles tool still works.

209 207 

210Before v2.1.216, Claude Code followed the link, which could place the file outside the location you chose.

211 

212In a monorepo with several `.claude/` directories, you can keep workflows alongside the package they apply to. Saving to the project location writes to the closest `.claude/workflows/` directory that already exists between your working directory and the repository root, or to the repository root if none exists yet. Project workflows also load from every `.claude/workflows/` along that path, and when more than one defines the same name Claude Code runs the one closest to the working directory.208In a monorepo with several `.claude/` directories, you can keep workflows alongside the package they apply to. Saving to the project location writes to the closest `.claude/workflows/` directory that already exists between your working directory and the repository root, or to the repository root if none exists yet. Project workflows also load from every `.claude/workflows/` along that path, and when more than one defines the same name Claude Code runs the one closest to the working directory.

213 209 

214If a project workflow and a personal workflow share a name, the project one runs.210If a project workflow and a personal workflow share a name, the project one runs.


469| `medium` | Fewer than 10 agents |465| `medium` | Fewer than 10 agents |

470| `large` | Fewer than 50 agents |466| `large` | Fewer than 50 agents |

471 467 

472The default is `medium`, or `small` when you're signed in on a Pro plan with Claude Code v2.1.271 or later. Until you choose a value, the `/config` row marks the value as the default, and the workflow's `Running in background` line names the size in force. Requires Claude Code v2.1.219 or later; earlier versions default to `unrestricted`.468The default is `medium`, or `small` when you're signed in on a Pro plan with Claude Code v2.1.271 or later. Until you choose a value, the `/config` row marks the value as the default, and the workflow's `Running in background` line names the size in force.

473 469 

474To change the guideline, pick a value for the Dynamic workflow size setting in `/config`, or run `/config workflowSizeGuideline=small`. On v2.1.219 and later, you can also set the [`workflowSizeGuideline` key](https://code.claude.com/docs/en/settings-reference#workflowsizeguideline) in any settings file; that value takes precedence over `/config`, and Claude Code hides the `/config` row while a settings file provides one.470To change the guideline, pick a value for the Dynamic workflow size setting in `/config`, or run `/config workflowSizeGuideline=small`. You can also set the [`workflowSizeGuideline` key](https://code.claude.com/docs/en/settings-reference#workflowsizeguideline) in any settings file; that value takes precedence over `/config`, and Claude Code hides the `/config` row while a settings file provides one.

475 471 

476Changes take effect on the next prompt. The [runtime agent caps](#behavior-and-limits) still apply regardless of the setting.472Changes take effect on the next prompt. The [runtime agent caps](#behavior-and-limits) still apply regardless of the setting.

477 473 

worktrees.md +21 −9

Details

43 43 

44You can also ask Claude to "work in a worktree" during a session, and it creates one with the [`EnterWorktree`](https://code.claude.com/docs/en/tools-reference) tool. Once in a worktree, Claude can switch directly to another one under `.claude/worktrees/` by calling `EnterWorktree` with the target path; the previous worktree stays on disk untouched.44You can also ask Claude to "work in a worktree" during a session, and it creates one with the [`EnterWorktree`](https://code.claude.com/docs/en/tools-reference) tool. Once in a worktree, Claude can switch directly to another one under `.claude/worktrees/` by calling `EnterWorktree` with the target path; the previous worktree stays on disk untouched.

45 45 

46When Claude enters a path outside the repository's `.claude/worktrees/` directory, Claude Code asks for your approval first, because the move takes the session's working directory, write access, and project configuration such as `CLAUDE.md` and settings to that location. An `EnterWorktree` [permission rule](https://code.claude.com/docs/en/permissions.md) or choosing "don't ask again" doesn't suppress this prompt; only `bypassPermissions` mode skips it. Before v2.1.206, Claude could enter any existing worktree path without asking.46When Claude enters a path outside the repository's `.claude/worktrees/` directory, Claude Code asks for your approval first. The move takes the session's working directory, write access, and project configuration such as `CLAUDE.md` and settings to that location. An `EnterWorktree` [permission rule](https://code.claude.com/docs/en/permissions.md) or choosing "don't ask again" doesn't suppress this prompt; only `bypassPermissions` mode skips it.

47 47 

48> [!NOTE]48> [!NOTE]

49>49>


63 63 

64Non-interactive runs with `-p` have no exit prompt, so Claude doesn't clean up their worktrees, and Claude Code leaves the lock it took on each one at creation in place until a later session's [stale-lock sweep](#clean-up-subagent-and-background-session-worktrees) releases it. To remove one, run `git worktree remove`; if git refuses because the worktree is locked, run `git worktree unlock` on it first.64Non-interactive runs with `-p` have no exit prompt, so Claude doesn't clean up their worktrees, and Claude Code leaves the lock it took on each one at creation in place until a later session's [stale-lock sweep](#clean-up-subagent-and-background-session-worktrees) releases it. To remove one, run `git worktree remove`; if git refuses because the worktree is locked, run `git worktree unlock` on it first.

65 65 

66On Windows, removing a worktree doesn't delete files outside it. If a folder inside the worktree is a link to somewhere else, such as an NTFS junction or a directory symlink, Claude Code deletes only the link and keeps the folder it points to. Before v2.1.205, removing a worktree with a link nested in a subdirectory could delete the folder it pointed to.66On Windows, removing a worktree doesn't delete files outside it. If a folder inside the worktree is a link to somewhere else, such as an NTFS junction or a directory symlink, Claude Code deletes only the link.

67 67 

68## Resume a worktree session68## Resume a worktree session

69 69 


81>81>

82> Before v2.1.212, a non-interactive resume stayed in the starting directory and `ExitWorktree` reported that there was no active worktree session to exit.82> Before v2.1.212, a non-interactive resume stayed in the starting directory and `ExitWorktree` reported that there was no active worktree session to exit.

83 83 

84When Claude enters or exits a worktree that Claude Code created with git, the transcript follows: Claude Code records the session under the session's new working directory, the same way [`/cd`](https://code.claude.com/docs/en/commands) does, so `/desktop` and `--resume` find it there. Exiting moves it back the same way. A worktree created by a [`WorktreeCreate` hook](#non-git-version-control) keeps its transcript at the launch directory. Requires Claude Code v2.1.198 or later.84When Claude enters or exits a worktree that Claude Code created with git, the transcript follows. Claude Code records the session under the session's new working directory, the same way [`/cd`](https://code.claude.com/docs/en/commands) does, so `/desktop` and `--resume` find it there. Exiting moves it back the same way. A worktree created by a [`WorktreeCreate` hook](#non-git-version-control) keeps its transcript at the launch directory.

85 85 

86## How Claude Code enforces isolation86## How Claude Code enforces isolation

87 87 


139 139 

140Claude Code writes a marker into the git metadata of every worktree it creates with git, and the sweep keeps any worktree without one, including a worktree a [`WorktreeCreate` hook](#non-git-version-control) created.140Claude Code writes a marker into the git metadata of every worktree it creates with git, and the sweep keeps any worktree without one, including a worktree a [`WorktreeCreate` hook](#non-git-version-control) created.

141 141 

142#### Worktree locks and manual removal

143 

142While an agent is running, Claude Code holds a `git worktree lock` on its worktree so that concurrent cleanup can't remove it, and releases the lock when the agent finishes. Claude Code holds the same lock on the worktree it created for a backgrounded session while the session runs, so the sweep leaves the worktree in place and `git worktree remove` refuses to remove it.144While an agent is running, Claude Code holds a `git worktree lock` on its worktree so that concurrent cleanup can't remove it, and releases the lock when the agent finishes. Claude Code holds the same lock on the worktree it created for a backgrounded session while the session runs, so the sweep leaves the worktree in place and `git worktree remove` refuses to remove it.

143 145 

144The sweep also releases a lock Claude Code set for a session whose process has exited, so a killed background session doesn't leave its worktree permanently locked. The sweep never releases a lock you set yourself with `git worktree lock`. Before v2.1.210, a lock left by a killed session stayed in place until you ran `git worktree unlock`.146The sweep also releases a lock Claude Code set for a session whose process has exited, so a killed background session doesn't leave its worktree permanently locked. The sweep never releases a lock you set yourself with `git worktree lock`.

145 147 

146To clean up a worktree that the sweep keeps, run `git worktree remove`, adding `--force` if the worktree has uncommitted changes or untracked files. If git refuses because the worktree is locked, run `git worktree unlock` on it first.148To clean up a worktree that the sweep keeps, run `git worktree remove`, adding `--force` if the worktree has uncommitted changes or untracked files. If git refuses because the worktree is locked, run `git worktree unlock` on it first.

147 149 


158 160 

159You can't set `worktree.baseRef` to a branch name. To start a worktree from a specific existing branch, [create it with git directly](#manage-worktrees-manually).161You can't set `worktree.baseRef` to a branch name. To start a worktree from a specific existing branch, [create it with git directly](#manage-worktrees-manually).

160 162 

161For a `"fresh"` base, Claude Code keeps `origin/HEAD` current: when the repository hasn't been fetched in the last 24 hours, it fetches the default branch, capped at five seconds, and uses the locally cached ref if the fetch fails. The fetch never waits for input in your terminal, so it also counts as failed when git or ssh would ask for a password, a key passphrase, or confirmation of a new SSH host. If no remote is configured, or `origin/HEAD` isn't cached locally and can't be fetched, the worktree falls back to your current local `HEAD`. Before v2.1.208, a fresh worktree used whatever `origin/HEAD` was already cached locally.163For a `"fresh"` base, Claude Code keeps `origin/HEAD` current:

164 

165* When the repository hasn't been fetched in the last 24 hours, it fetches the default branch, capped at five seconds, and uses the locally cached ref if the fetch fails.

166* The fetch never waits for input in your terminal. It also counts as failed when git or ssh would ask for a password, a key passphrase, or confirmation of a new SSH host.

167* If no remote is configured, or `origin/HEAD` isn't cached locally and can't be fetched, the worktree falls back to your current local `HEAD`.

162 168 

163This example makes every new worktree branch from your current work:169This example makes every new worktree branch from your current work:

164 170 


225* `worktree.baseRef` is `"head"`.231* `worktree.baseRef` is `"head"`.

226* The name is a pull request or merge request reference.232* The name is a pull request or merge request reference.

227 233 

228Before v2.1.208, when you reused a name, Claude Code always reopened the old worktree at its old tip.

229 

230### Replace worktree creation with a hook234### Replace worktree creation with a hook

231 235 

232Configure a [`WorktreeCreate` hook](https://code.claude.com/docs/en/hooks#worktreecreate) to replace the default `git worktree` logic entirely, including placing worktrees somewhere other than `.claude/worktrees/`. For a complete example, see [Non-git version control](#non-git-version-control).236Configure a [`WorktreeCreate` hook](https://code.claude.com/docs/en/hooks#worktreecreate) to replace the default `git worktree` logic entirely, including placing worktrees somewhere other than `.claude/worktrees/`. For a complete example, see [Non-git version control](#non-git-version-control).


236A worktree gets its own files and branch, but it shares the following with the main checkout:240A worktree gets its own files and branch, but it shares the following with the main checkout:

237 241 

238* **The repository's `.git` directory**: git commands in a worktree write to the main repository's shared `.git` directory, and [sandboxing](https://code.claude.com/docs/en/sandboxing.md#filesystem-isolation) allows those writes, so commands such as `git commit` work from inside a worktree with the sandbox enabled.242* **The repository's `.git` directory**: git commands in a worktree write to the main repository's shared `.git` directory, and [sandboxing](https://code.claude.com/docs/en/sandboxing.md#filesystem-isolation) allows those writes, so commands such as `git commit` work from inside a worktree with the sandbox enabled.

239* **Plugins**: plugins installed at [project scope](https://code.claude.com/docs/en/plugins/loading.md#find-where-a-plugin-is-enabled) from the main checkout also load in worktrees of the same repository, so you don't need to reinstall them per worktree. Requires Claude Code v2.1.200 or later.243* **Plugins**: plugins installed at [project scope](https://code.claude.com/docs/en/plugins/loading.md#find-where-a-plugin-is-enabled) from the main checkout also load in worktrees of the same repository, so you don't need to reinstall them per worktree.

240* **Permission approvals**: choosing "Yes, and don't ask again" for a Bash command in a worktree session saves the rule to the main checkout's `.claude/settings.local.json`, so it applies in the main checkout and in every other worktree of the repository, and it survives the worktree's removal. On Windows and in the other cases where Claude Code [doesn't use the repository root](https://code.claude.com/docs/en/settings.md#where-claude-code-looks-for-each-file), the rule stays with that worktree. Before v2.1.211, an approval granted in a worktree was saved inside that worktree, didn't apply elsewhere, and was lost when the worktree was removed. See [where approvals are saved](https://code.claude.com/docs/en/permissions.md#permission-system).244* **Permission approvals**: choosing "Yes, and don't ask again" for a Bash command in a worktree session saves the rule to the main checkout's `.claude/settings.local.json`. The rule applies in the main checkout and in every other worktree of the repository, and it survives the worktree's removal.

245 

246 On Windows and in the other cases where Claude Code [doesn't use the repository root](https://code.claude.com/docs/en/settings.md#where-claude-code-looks-for-each-file), the rule stays with that worktree. See [where approvals are saved](https://code.claude.com/docs/en/permissions.md#permission-system).

241* **Untracked skills, agents, and commands**: when the worktree checkout has no `.claude/skills` directory at its root, for example because your `.claude/skills` is gitignored, Claude Code loads the main checkout's [project skills](https://code.claude.com/docs/en/skills.md#where-skills-live) in the worktree session. In a worktree with its own `.claude/skills` directory, only that copy loads.247* **Untracked skills, agents, and commands**: when the worktree checkout has no `.claude/skills` directory at its root, for example because your `.claude/skills` is gitignored, Claude Code loads the main checkout's [project skills](https://code.claude.com/docs/en/skills.md#where-skills-live) in the worktree session. In a worktree with its own `.claude/skills` directory, only that copy loads.

242 248 

243 The same read-through covers `.claude/agents` and `.claude/commands`. For skills, the read-through requires Claude Code v2.1.277 or later.249 The same read-through covers `.claude/agents` and `.claude/commands`. For skills, the read-through requires Claude Code v2.1.277 or later.


322 328 

323Claude Code refuses to create a worktree when `.claude`, `.claude/worktrees`, or the worktree directory itself is a symlink, and the error names the symlinked path. Remove the symlink and retry. Before v2.1.212, if the repository already contained a committed symlink at one of those paths, worktree creation followed it and could create files outside the repository.329Claude Code refuses to create a worktree when `.claude`, `.claude/worktrees`, or the worktree directory itself is a symlink, and the error names the symlinked path. Remove the symlink and retry. Before v2.1.212, if the repository already contained a committed symlink at one of those paths, worktree creation followed it and could create files outside the repository.

324 330 

331### A worktree Claude Code created has the original content of replaced objects

332 

333If your repository uses [`git replace`](https://git-scm.com/docs/git-replace), the files in a worktree that Claude Code creates hold the original objects' content rather than the replacements your `refs/replace/` entries name. Claude Code runs the git commands that check out the worktree's files with `GIT_NO_REPLACE_OBJECTS=1`, ignoring any value you exported for that variable.

334 

335To get the replaced content, [create the worktree yourself](#manage-worktrees-manually) with `git worktree add` and start Claude Code inside it.

336 

325### Git LFS files are pointer files in a worktree Claude Code created337### Git LFS files are pointer files in a worktree Claude Code created

326 338 

327If you set up [Git LFS](https://git-lfs.com) with `git lfs install --local`, a worktree that Claude Code creates contains LFS pointer files instead of the real files. The `--local` flag writes the LFS filter into the repository's own `.git/config` rather than your global git config. A plain `git lfs install` writes to your global config and isn't affected. The same applies to any other [filter driver](https://git-scm.com/docs/gitattributes) defined in the repository's own config.339If you set up [Git LFS](https://git-lfs.com) with `git lfs install --local`, a worktree that Claude Code creates contains LFS pointer files instead of the real files. The `--local` flag writes the LFS filter into the repository's own `.git/config` rather than your global git config. A plain `git lfs install` writes to your global config and isn't affected. The same applies to any other [filter driver](https://git-scm.com/docs/gitattributes) defined in the repository's own config.