SpyBara
Go Premium

Documentation 2026-05-20 06:35 UTC to 2026-05-21 06:36 UTC

17 files changed +1,882 −34. View all changes and history on the product overview
2026
Sun 31 06:39 Sat 30 06:23 Fri 29 06:38 Thu 28 06:37 Wed 27 06:42 Tue 26 06:33 Sun 24 06:25 Sat 23 06:18 Fri 22 06:33 Thu 21 06:36 Wed 20 06:35 Tue 19 06:34 Mon 18 23:59 Sun 17 01:01 Fri 15 22:58 Thu 14 17:02 Wed 13 23:01 Tue 12 22:57 Mon 11 23:00 Sun 10 23:03 Sat 9 04:57 Fri 8 22:00 Thu 7 22:59 Tue 5 23:00 Mon 4 22:58 Sat 2 18:14 Fri 1 18:19
Details

68Managed settings can lock down tools, sandbox execution, restrict MCP servers and plugin sources, and control which hooks run. Each row is a control surface with the setting keys that drive it.68Managed settings can lock down tools, sandbox execution, restrict MCP servers and plugin sources, and control which hooks run. Each row is a control surface with the setting keys that drive it.

69 69 

70| Control | What it does | Key settings |70| Control | What it does | Key settings |

71| :------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------- | :---------------------------------------------------------------------------- |71| :------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------- |

72| [Permission rules](/en/permissions) | Allow, ask, or deny specific tools and commands | `permissions.allow`, `permissions.deny` |72| [Permission rules](/en/permissions) | Allow, ask, or deny specific tools and commands | `permissions.allow`, `permissions.deny` |

73| [Permission lockdown](/en/permissions#managed-only-settings) | Only managed permission rules apply; disable `--dangerously-skip-permissions` | `allowManagedPermissionRulesOnly`, `permissions.disableBypassPermissionsMode` |73| [Permission lockdown](/en/permissions#managed-only-settings) | Only managed permission rules apply; disable `--dangerously-skip-permissions` | `allowManagedPermissionRulesOnly`, `permissions.disableBypassPermissionsMode` |

74| [Sandboxing](/en/sandboxing) | OS-level filesystem and network isolation with domain allowlists | `sandbox.enabled`, `sandbox.network.allowedDomains` |74| [Sandboxing](/en/sandboxing) | OS-level filesystem and network isolation with domain allowlists | `sandbox.enabled`, `sandbox.network.allowedDomains` |

75| [Managed policy CLAUDE.md](/en/memory#deploy-organization-wide-claude-md) | Org-wide instructions loaded in every session, cannot be excluded | File at the managed policy path |75| [Managed policy CLAUDE.md](/en/memory#deploy-organization-wide-claude-md) | Org-wide instructions loaded in every session, cannot be excluded | File at the managed policy path |

76| [MCP server control](/en/mcp#managed-mcp-configuration) | Restrict which MCP servers users can add or connect to | `allowedMcpServers`, `deniedMcpServers`, `allowManagedMcpServersOnly` |76| [MCP server control](/en/mcp#managed-mcp-configuration) | Restrict which MCP servers users can add or connect to | `allowedMcpServers`, `deniedMcpServers`, `allowManagedMcpServersOnly` |

77| [Plugin marketplace control](/en/plugin-marketplaces#managed-marketplace-restrictions) | Restrict which marketplace sources users can add and install from | `strictKnownMarketplaces`, `blockedMarketplaces` |77| [Plugin marketplace control](/en/plugin-marketplaces#managed-marketplace-restrictions) | Restrict which marketplace sources users can add and install from | `strictKnownMarketplaces`, `blockedMarketplaces` |

78| [Customization lockdown](/en/settings#strictpluginonlycustomization) | Block skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings | `strictPluginOnlyCustomization` |

78| [Hook restrictions](/en/settings#hook-configuration) | Only managed hooks load; restrict HTTP hook URLs | `allowManagedHooksOnly`, `allowedHttpHookUrls` |79| [Hook restrictions](/en/settings#hook-configuration) | Only managed hooks load; restrict HTTP hook URLs | `allowManagedHooksOnly`, `allowedHttpHookUrls` |

79| [Disable agent view](/en/agent-view#how-background-sessions-are-hosted) | Turn off `claude agents`, `--bg`, `/background`, and the on-demand supervisor | `disableAgentView` |80| [Disable agent view](/en/agent-view#how-background-sessions-are-hosted) | Turn off `claude agents`, `--bg`, `/background`, and the on-demand supervisor | `disableAgentView` |

80| [Version floor](/en/settings) | Prevent auto-update from installing below an org-wide minimum | `minimumVersion` |81| [Version floor](/en/settings) | Prevent auto-update from installing below an org-wide minimum | `minimumVersion` |

Details

1> ## Documentation Index

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

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

4 

5# Persist sessions to external storage

6 

7> Mirror session transcripts to S3, Redis, or your own backend so any host can resume them.

8 

9By default, the SDK writes session transcripts to JSONL files under `~/.claude/projects/` on the local filesystem. A `SessionStore` adapter lets you mirror those transcripts to your own backend, such as S3, Redis, or a database, so a session created on one host can be resumed on another.

10 

11Common reasons to use a session store:

12 

13* **Multi-host deployments.** Serverless functions, autoscaled workers, and CI runners don't share a filesystem. A shared store lets any replica resume any session.

14* **Durability.** Local containers are ephemeral. A store backed by S3 or a database survives restarts and redeploys.

15* **Compliance and audit.** Keep transcripts in storage you already govern, with your own retention rules, encryption, and access controls.

16 

17## The `SessionStore` interface

18 

19A `SessionStore` is an object with two required methods, `append` and `load`, and three optional methods. The SDK calls `append` to write transcript entries during a query and `load` to read them back for resume.

20 

21<CodeGroup>

22 ```typescript TypeScript theme={null}

23 // Exported from @anthropic-ai/claude-agent-sdk as

24 // SessionStore, SessionKey, SessionStoreEntry.

25 

26 type SessionKey = {

27 projectKey: string;

28 sessionId: string;

29 subpath?: string;

30 };

31 

32 type SessionStore = {

33 // Required

34 append(key: SessionKey, entries: SessionStoreEntry[]): Promise<void>;

35 load(key: SessionKey): Promise<SessionStoreEntry[] | null>;

36 

37 // Optional

38 listSessions?(

39 projectKey: string,

40 ): Promise<Array<{ sessionId: string; mtime: number }>>;

41 delete?(key: SessionKey): Promise<void>;

42 listSubkeys?(key: {

43 projectKey: string;

44 sessionId: string;

45 }): Promise<string[]>;

46 };

47 ```

48 

49 ```python Python theme={null}

50 # Exported from claude_agent_sdk as

51 # SessionStore, SessionKey, SessionStoreEntry.

52 

53 class SessionKey(TypedDict):

54 project_key: str

55 session_id: str

56 subpath: NotRequired[str]

57 

58 class SessionStore(Protocol):

59 # Required

60 async def append(

61 self, key: SessionKey, entries: list[SessionStoreEntry]

62 ) -> None: ...

63 async def load(self, key: SessionKey) -> list[SessionStoreEntry] | None: ...

64 

65 # Optional — omit or raise NotImplementedError

66 async def list_sessions(

67 self, project_key: str

68 ) -> list[SessionStoreListEntry]: ...

69 async def delete(self, key: SessionKey) -> None: ...

70 async def list_subkeys(self, key: SessionListSubkeysKey) -> list[str]: ...

71 ```

72</CodeGroup>

73 

74`SessionKey` addresses one transcript. `projectKey` is a stable, filesystem-safe encoding of the working directory, `sessionId` is the session UUID, and `subpath` is set when the entry belongs to a subagent transcript or sidecar file rather than the main conversation. Treat `subpath` as an opaque key suffix; it follows the on-disk layout, for example `subagents/agent-<id>`. When `subpath` is undefined the key refers to the main transcript.

75 

76| Method | Required | Called when |

77| :------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

78| `append` | Yes | After each batch of transcript entries is written locally. Entries are JSON-safe objects, one per line in the local JSONL. |

79| `load` | Yes | Once before the subprocess spawns, when `resume` is set. Return `null` if the session is unknown. |

80| `listSessions` | No | By `listSessions({ sessionStore })` and by `query()`/`startup()` with `continue: true`. If undefined, those calls throw. |

81| `delete` | No | By `deleteSession({ sessionStore })`. Deleting the main key (no `subpath`) must cascade to all subkeys for that session. If undefined, deletion is a no-op, which suits append-only backends. |

82| `listSubkeys` | No | During resume, to discover subagent transcripts. If undefined, only the main transcript is restored. |

83 

84## Quick start

85 

86The SDK ships an `InMemorySessionStore` for development and testing. The example below runs a query with the store attached, captures the session ID from the result message, then resumes from the store in a second `query()` call. The second call passes the same store instance plus `resume`, so the SDK loads the transcript from the store instead of the local filesystem:

87 

88<CodeGroup>

89 ```typescript TypeScript theme={null}

90 import { query, InMemorySessionStore } from "@anthropic-ai/claude-agent-sdk";

91 

92 const store = new InMemorySessionStore();

93 

94 let sessionId: string | undefined;

95 for await (const message of query({

96 prompt: "List the TypeScript files under src/",

97 options: { sessionStore: store },

98 })) {

99 if (message.type === "result") {

100 sessionId = message.session_id;

101 }

102 }

103 

104 // Resume from the store. The agent has full context from the first call.

105 for await (const message of query({

106 prompt: "Summarize what those files do",

107 options: { sessionStore: store, resume: sessionId },

108 })) {

109 if (message.type === "result" && message.subtype === "success") {

110 console.log(message.result);

111 }

112 }

113 ```

114 

115 ```python Python theme={null}

116 import asyncio

117 from claude_agent_sdk import (

118 ClaudeAgentOptions,

119 InMemorySessionStore,

120 ResultMessage,

121 query,

122 )

123 

124 store = InMemorySessionStore()

125 

126 

127 async def main():

128 session_id = None

129 async for message in query(

130 prompt="List the Python files under src/",

131 options=ClaudeAgentOptions(session_store=store),

132 ):

133 if isinstance(message, ResultMessage):

134 session_id = message.session_id

135 

136 # Resume from the store. The agent has full context from the first call.

137 async for message in query(

138 prompt="Summarize what those files do",

139 options=ClaudeAgentOptions(session_store=store, resume=session_id),

140 ):

141 if isinstance(message, ResultMessage) and message.subtype == "success":

142 print(message.result)

143 

144 

145 asyncio.run(main())

146 ```

147</CodeGroup>

148 

149## Write your own adapter

150 

151Implement `append` and `load` against your backend. Add `listSessions`, `delete`, and `listSubkeys` if you want `listSessions()`, `deleteSession()`, and subagent resume to work against the store.

152 

153Entries passed to `append` are typed as `SessionStoreEntry` (a `{ type: string; ... }` object). Treat them as opaque JSON-safe values: persist them in order and return them from `load` in the same order. `load` must return entries that are deep-equal to what was appended; byte-equal serialization is not required, so backends like Postgres `jsonb` that reorder object keys are fine.

154 

155## Reference implementations

156 

157The TypeScript SDK repository includes runnable reference adapters for S3, Redis, and Postgres under [`examples/session-stores/`](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores). They are not published to npm; copy the `src/` file you need into your project and install the corresponding backend client.

158 

159| Adapter | Backend client | Storage model |

160| :----------------------------------------------------------------------------------------------------------------------------- | :------------------- | :--------------------------------------------------------------------------- |

161| [`S3SessionStore`](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores/s3) | `@aws-sdk/client-s3` | One JSONL part file per `append()`; `load()` lists, sorts, and concatenates. |

162| [`RedisSessionStore`](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores/redis) | `ioredis` | `RPUSH`/`LRANGE` list per transcript, plus a sorted-set session index. |

163| [`PostgresSessionStore`](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores/postgres) | `pg` | One row per entry in a `jsonb` table, ordered by `BIGSERIAL`. |

164 

165Each adapter takes a pre-configured client instance, so you control credentials, TLS, region, and pooling. For example, with S3:

166 

167```typescript TypeScript theme={null}

168import { query } from "@anthropic-ai/claude-agent-sdk";

169import { S3Client } from "@aws-sdk/client-s3";

170import { S3SessionStore } from "./S3SessionStore"; // copied from examples/session-stores/s3

171 

172const store = new S3SessionStore({

173 bucket: "my-claude-sessions",

174 prefix: "transcripts",

175 client: new S3Client({ region: "us-east-1" }),

176});

177 

178for await (const message of query({

179 prompt: "Hello!",

180 options: { sessionStore: store },

181})) {

182 if (message.type === "result" && message.subtype === "success") {

183 console.log(message.result);

184 }

185}

186 

187// Later, possibly on a different host:

188for await (const message of query({

189 prompt: "Continue where we left off",

190 options: { sessionStore: store, resume: "previous-session-id" },

191})) {

192 // ...

193}

194```

195 

196### Validate your adapter

197 

198Both SDKs ship a conformance suite that asserts the behavioral contract `append`, `load`, and the optional methods must satisfy. Tests for optional methods skip automatically when those methods are not implemented.

199 

200In TypeScript, copy [`shared/conformance.ts`](https://github.com/anthropics/claude-agent-sdk-typescript/blob/main/examples/session-stores/shared/conformance.ts) from the example directory into your test suite. In Python, the suite ships in the package:

201 

202```python Python theme={null}

203import pytest

204from claude_agent_sdk.testing import run_session_store_conformance

205 

206 

207@pytest.mark.asyncio

208async def test_my_store_conformance():

209 await run_session_store_conformance(MyRedisStore)

210```

211 

212## Behavior notes

213 

214### Dual-write architecture

215 

216The store is a mirror, not a replacement. The Claude Code subprocess always writes to local disk first; the SDK then forwards each batch to `append()`. If you want the local copy to be ephemeral, point `CLAUDE_CONFIG_DIR` at a temp directory in `options.env`. Because the mirror depends on local writes, `sessionStore` cannot be combined with `persistSession: false`; the SDK throws if you set both. It also throws if combined with `enableFileCheckpointing`, since file-history backup blobs are written directly to local disk and are not mirrored to the store.

217 

218### Mirror writes are best-effort

219 

220If `append()` rejects or times out, the error is logged, a `{ type: "system", subtype: "mirror_error" }` message is emitted into the iterator, and the query continues. The local transcript is already durable on disk, so a store outage does not interrupt the agent or lose data locally. Batches that fail are not retried, so monitor for `mirror_error` if you need to detect store data loss.

221 

222### `getSessionMessages` returns the post-compaction chain

223 

224`getSessionMessages({ sessionStore })` returns the linked message chain the agent would see on resume. After auto-compaction, earlier turns are replaced by a summary, so a session whose store holds 503 raw entries may return 18 messages from `getSessionMessages`. For the full raw history, including pre-compaction turns and metadata entries, call `store.load(key)` directly.

225 

226### `forkSession` is not a byte copy

227 

228`forkSession({ sessionStore })` reads the source entries, rewrites every `sessionId` field and remaps message UUIDs, then appends the transformed entries under a new key. An adapter-level copy or `CopyObject` shortcut would produce a transcript that still references the old session ID, so the SDK does not use one.

229 

230### Subagent transcripts

231 

232Subagent transcripts are mirrored under `subpath: "subagents/agent-<id>"`. `listSubagents({ sessionStore })` requires the adapter to implement `listSubkeys`; `getSubagentMessages({ sessionStore })` uses it when available but falls back to the direct subpath when it is undefined. Resume also calls `listSubkeys` to restore subagent files; without it, only the main transcript is materialized.

233 

234### Retention

235 

236The SDK never deletes from your store on its own. Retention is the adapter's responsibility: implement TTLs, S3 lifecycle policies, or scheduled cleanup according to your compliance requirements. Local transcripts under `CLAUDE_CONFIG_DIR` are swept independently by the `cleanupPeriodDays` setting.

237 

238## Supported on

239 

240The following SDK functions accept a `sessionStore` option and operate against the store instead of the local filesystem when it is provided:

241 

242* [`query()`](/en/agent-sdk/typescript#query)

243* [`startup()`](/en/agent-sdk/typescript#startup)

244* [`listSessions()`](/en/agent-sdk/typescript#listsessions)

245* [`getSessionInfo()`](/en/agent-sdk/typescript#getsessioninfo)

246* [`getSessionMessages()`](/en/agent-sdk/typescript#getsessionmessages)

247* [`renameSession()`](/en/agent-sdk/typescript#renamesession)

248* [`tagSession()`](/en/agent-sdk/typescript#tagsession)

249* [`deleteSession()`](/en/agent-sdk/typescript)

250* [`forkSession()`](/en/agent-sdk/typescript)

251* [`listSubagents()`](/en/agent-sdk/typescript)

252* [`getSubagentMessages()`](/en/agent-sdk/typescript)

253 

254## Related resources

255 

256* [Work with sessions](/en/agent-sdk/sessions): Continue, resume, and fork without a custom store

257* [Host the SDK](/en/agent-sdk/hosting): Deployment patterns for multi-host environments

258* [TypeScript `Options`](/en/agent-sdk/typescript#options): Full option reference

259* [`examples/session-stores/`](https://github.com/anthropics/claude-agent-sdk-typescript/tree/main/examples/session-stores): Runnable S3, Redis, and Postgres reference adapters

Details

22 22 

23### Rewind and summarize23### Rewind and summarize

24 24 

25Press `Esc` twice (`Esc` + `Esc`) or use the `/rewind` command to open the rewind menu. A scrollable list shows each of your prompts from the session. Select the point you want to act on, then choose an action:25Run `/rewind`, or press `Esc` twice when the prompt input is empty, to open the rewind menu.

26 

27<Note>

28 If the prompt input contains text, double `Esc` clears it instead of opening the menu. The cleared text is saved to your input history, so press `Up` to recall it after you finish in the rewind menu.

29</Note>

30 

31The rewind menu lists each prompt you sent during the session. Select the point you want to act on, then choose an action:

26 32 

27* **Restore code and conversation**: revert both code and conversation to that point33* **Restore code and conversation**: revert both code and conversation to that point

28* **Restore conversation**: rewind to that message while keeping current code34* **Restore conversation**: rewind to that message while keeping current code

en/commands.md +3 −3

Details

35In the table below, `<arg>` indicates a required argument and `[arg]` indicates an optional one.35In the table below, `<arg>` indicates a required argument and `[arg]` indicates an optional one.

36 36 

37<Note>37<Note>

38 Not every command appears for every user. Availability depends on your platform, plan, and environment. For example, `/desktop` only shows on macOS and Windows, and `/upgrade` only shows on Pro and Max plans.38 Not every command appears for every user. Availability depends on your platform, plan, and environment. For example, `/desktop` only shows on macOS and Windows when signed in with a Claude subscription, and `/upgrade` only shows on Pro and Max plans.

39</Note>39</Note>

40 40 

41| Command | Purpose |41| Command | Purpose |


57| `/copy [N]` | Copy the last assistant response to clipboard. Pass a number `N` to copy the Nth-latest response: `/copy 2` copies the second-to-last. When code blocks are present, shows an interactive picker to select individual blocks or the full response. Press `w` in the picker to write the selection to a file instead of the clipboard, which is useful over SSH |57| `/copy [N]` | Copy the last assistant response to clipboard. Pass a number `N` to copy the Nth-latest response: `/copy 2` copies the second-to-last. When code blocks are present, shows an interactive picker to select individual blocks or the full response. Press `w` in the picker to write the selection to a file instead of the clipboard, which is useful over SSH |

58| `/cost` | Alias for `/usage` |58| `/cost` | Alias for `/usage` |

59| `/debug [description]` | **[Skill](/en/skills#bundled-skills).** Enable debug logging for the current session and troubleshoot issues by reading the session debug log. Debug logging is off by default unless you started with `claude --debug`, so running `/debug` mid-session starts capturing logs from that point forward. Optionally describe the issue to focus the analysis |59| `/debug [description]` | **[Skill](/en/skills#bundled-skills).** Enable debug logging for the current session and troubleshoot issues by reading the session debug log. Debug logging is off by default unless you started with `claude --debug`, so running `/debug` mid-session starts capturing logs from that point forward. Optionally describe the issue to focus the analysis |

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

61| `/diff` | Open an interactive diff viewer showing uncommitted changes and per-turn diffs. Use left/right arrows to switch between the current git diff and individual Claude turns, and up/down to browse files |61| `/diff` | Open an interactive diff viewer showing uncommitted changes and per-turn diffs. Use left/right arrows to switch between the current git diff and individual Claude turns, and up/down to browse files |

62| `/doctor` | Diagnose and verify your Claude Code installation and settings. Results show with status icons. Press `f` to have Claude fix any reported issues |62| `/doctor` | Diagnose and verify your Claude Code installation and settings. Results show with status icons. Press `f` to have Claude fix any reported issues |

63| `/effort [level\|auto]` | Set the model [effort level](/en/model-config#adjust-effort-level). Accepts `low`, `medium`, `high`, `xhigh`, or `max`; available levels depend on the model and `max` is session-only. `auto` resets to the model default. Without an argument, opens an interactive slider; use left and right arrows to pick a level and `Enter` to apply. Takes effect immediately without waiting for the current response to finish |63| `/effort [level\|auto]` | Set the model [effort level](/en/model-config#adjust-effort-level). Accepts `low`, `medium`, `high`, `xhigh`, or `max`; available levels depend on the model and `max` is session-only. `auto` resets to the model default. Without an argument, opens an interactive slider; use left and right arrows to pick a level and `Enter` to apply. Takes effect immediately without waiting for the current response to finish |


79| `/keybindings` | Open or create your keybindings configuration file |79| `/keybindings` | Open or create your keybindings configuration file |

80| `/login` | Sign in to your Anthropic account |80| `/login` | Sign in to your Anthropic account |

81| `/logout` | Sign out from your Anthropic account |81| `/logout` | Sign out from your Anthropic account |

82| `/loop [interval] [prompt]` | **[Skill](/en/skills#bundled-skills).** Run a prompt repeatedly while the session stays open. Omit the interval and Claude self-paces between iterations. Omit the prompt and Claude runs an autonomous maintenance check, or the prompt in `.claude/loop.md` if present. Example: `/loop 5m check if the deploy finished`. See [Run prompts on a schedule](/en/scheduled-tasks). Alias: `/proactive` |82| `/loop [interval] [prompt]` | **[Skill](/en/skills#bundled-skills).** Run a prompt repeatedly while the session stays open. Omit the interval and Claude self-paces between iterations. Omit the prompt and, [where available](/en/scheduled-tasks#run-the-built-in-maintenance-prompt), Claude runs an autonomous maintenance check or the prompt in `.claude/loop.md`. Example: `/loop 5m check if the deploy finished`. See [Run prompts on a schedule](/en/scheduled-tasks). Alias: `/proactive` |

83| `/mcp` | Manage MCP server connections and OAuth authentication |83| `/mcp` | Manage MCP server connections and OAuth authentication |

84| `/memory` | Edit `CLAUDE.md` memory files, enable or disable [auto-memory](/en/memory#auto-memory), and view auto-memory entries |84| `/memory` | Edit `CLAUDE.md` memory files, enable or disable [auto-memory](/en/memory#auto-memory), and view auto-memory entries |

85| `/mobile` | Show QR code to download the Claude mobile app. Aliases: `/ios`, `/android` |85| `/mobile` | Show QR code to download the Claude mobile app. Aliases: `/ios`, `/android` |

en/desktop.md +2 −2

Details

51 51 

52### Use the prompt box52### Use the prompt box

53 53 

54Type what you want Claude to do and press **Enter** to send. Claude reads your project files, makes changes, and runs commands based on your [permission mode](#choose-a-permission-mode). You can interrupt Claude at any point: click the stop button or type your correction and press **Enter**. Claude stops what it's doing and adjusts based on your input.54Type what you want Claude to do and press **Enter** to send. Claude reads your project files, makes changes, and runs commands based on your [permission mode](#choose-a-permission-mode). You can redirect Claude at any point: click the stop button to interrupt immediately, or type a correction and press **Enter** to send it without stopping the running action. Claude reads the correction as soon as the current action completes and adjusts before its next step.

55 55 

56The **+** button next to the prompt box gives you access to file attachments, [skills](#use-skills), [connectors](#connect-external-tools), and [plugins](#install-plugins).56The **+** button next to the prompt box gives you access to file attachments, [skills](#use-skills), [connectors](#connect-external-tools), and [plugins](#install-plugins).

57 57 


642 642 

643If you already use the Claude Code CLI, Desktop runs the same underlying engine with a graphical interface. You can run both simultaneously on the same machine, even on the same project. Each maintains separate session history, but they share configuration and project memory via CLAUDE.md files.643If you already use the Claude Code CLI, Desktop runs the same underlying engine with a graphical interface. You can run both simultaneously on the same machine, even on the same project. Each maintains separate session history, but they share configuration and project memory via CLAUDE.md files.

644 644 

645To move a CLI session into Desktop, run `/desktop` in the terminal. Claude saves your session and opens it in the desktop app, then exits the CLI. This command is available on macOS and Windows only.645To move a CLI session into Desktop, run `/desktop` in the terminal. Claude saves your session and opens it in the desktop app, then exits the CLI. This command is available on macOS and Windows when you are signed in with a Claude subscription. It is not available with API key authentication or on Bedrock, Vertex, or Foundry.

646 646 

647<Tip>647<Tip>

648 When to use Desktop vs CLI: use Desktop when you want to manage parallel sessions in one window, arrange panes side by side, or review changes visually. Use the CLI when you need scripting, automation, or prefer a terminal workflow.648 When to use Desktop vs CLI: use Desktop when you want to manage parallel sessions in one window, arrange panes side by side, or review changes visually. Use the CLI when you need scripting, automation, or prefer a terminal workflow.

Details

95 95 

96You've made your first edit. For the full reference on everything Desktop can do, see [Use Claude Code Desktop](/en/desktop). Here are some things to try next.96You've made your first edit. For the full reference on everything Desktop can do, see [Use Claude Code Desktop](/en/desktop). Here are some things to try next.

97 97 

98**Interrupt and steer.** You can interrupt Claude at any point. If it's going down the wrong path, click the stop button or type your correction and press **Enter**. Claude stops what it's doing and adjusts based on your input. You don't have to wait for it to finish or start over.98**Interrupt and steer.** You can redirect Claude at any point. Click the stop button to interrupt immediately, or type a correction and press **Enter** to send it without stopping the running action. Either way, you don't have to wait for it to finish or start over.

99 99 

100**Give Claude more context.** Type `@filename` in the prompt box to pull a specific file into the conversation, attach images and PDFs using the attachment button, or drag and drop files directly into the prompt. The more context Claude has, the better the results. See [Add files and context](/en/desktop#add-files-and-context-to-prompts).100**Give Claude more context.** Type `@filename` in the prompt box to pull a specific file into the conversation, attach images and PDFs using the attachment button, or drag and drop files directly into the prompt. The more context Claude has, the better the results. See [Add files and context](/en/desktop#add-files-and-context-to-prompts).

101 101 

en/hooks.md +18 −12

Details

96 }96 }

97 }'97 }'

98else98else

99 exit 0 # allow the command99 exit 0 # no decision; normal permission flow applies

100fi100fi

101```101```

102 102 


136 }136 }

137 ```137 ```

138 138 

139 If the command had been a safer `rm` variant like `rm file.txt`, the script would hit `exit 0` instead, which tells Claude Code to allow the tool call with no further action.139 If the command had been a safer `rm` variant like `rm file.txt`, the script would hit `exit 0` instead. Exit code 0 with no output means the hook has no decision to report, so the tool call continues through the normal [permission flow](/en/permissions). The hook can deny the call, but staying silent doesn't approve it.

140 </Step>140 </Step>

141 141 

142 <Step title="Claude Code acts on the result">142 <Step title="Claude Code acts on the result">


622 exit 2 # Blocking error: tool call is prevented622 exit 2 # Blocking error: tool call is prevented

623fi623fi

624 624 

625exit 0 # Success: tool call proceeds625exit 0 # No decision: the normal permission flow applies

626```626```

627 627 

628<Warning>628<Warning>


679 679 

680### JSON output680### JSON output

681 681 

682Exit codes let you allow or block, but JSON output gives you finer-grained control. Instead of exiting with code 2 to block, exit 0 and print a JSON object to stdout. Claude Code reads specific fields from that JSON to control behavior, including [decision control](#decision-control) for blocking, allowing, or escalating to the user.682Exit codes only let you block or stay silent, but JSON output gives you finer-grained control. Instead of exiting with code 2 to block, exit 0 and print a JSON object to stdout. Claude Code reads specific fields from that JSON to control behavior, including [decision control](#decision-control) for blocking, allowing, or escalating to the user.

683 683 

684<Note>684<Note>

685 You must choose one approach per hook, not both: either use exit codes alone for signaling, or exit 0 and print JSON for structured control. Claude Code only processes JSON on exit 0. If you exit 2, any JSON is ignored.685 You must choose one approach per hook, not both: either use exit codes alone for signaling, or exit 0 and print JSON for structured control. Claude Code only processes JSON on exit 0. If you exit 2, any JSON is ignored.


699| :----------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |699| :----------------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

700| `continue` | `true` | If `false`, Claude stops processing entirely after the hook runs. Takes precedence over any event-specific decision fields |700| `continue` | `true` | If `false`, Claude stops processing entirely after the hook runs. Takes precedence over any event-specific decision fields |

701| `stopReason` | none | Message shown to the user when `continue` is `false`. Not shown to Claude |701| `stopReason` | none | Message shown to the user when `continue` is `false`. Not shown to Claude |

702| `suppressOutput` | `false` | If `true`, omits stdout from the debug log |702| `suppressOutput` | `false` | If `true`, hides the hook's stdout from the transcript. Stdout still appears in the debug log |

703| `systemMessage` | none | Warning message shown to the user |703| `systemMessage` | none | Warning message shown to the user |

704| `terminalSequence` | none | A terminal escape sequence for Claude Code to emit on your behalf, such as a desktop notification, window title, or bell. Restricted to OSC `0`/`1`/`2`/`9`/`99`/`777` and BEL. If the value contains anything outside the allowlist, the field is ignored. Use this instead of writing to `/dev/tty`, which is unavailable to hooks |704| `terminalSequence` | none | A terminal escape sequence for Claude Code to emit on your behalf, such as a desktop notification, window title, or bell. Restricted to OSC `0`/`1`/`2`/`9`/`99`/`777` and BEL. If the value contains anything outside the allowlist, the field is ignored. Use this instead of writing to `/dev/tty`, which is unavailable to hooks |

705 705 


783Not every event supports blocking or controlling behavior through JSON. The events that do each use a different set of fields to express that decision. Use this table as a quick reference before writing a hook:783Not every event supports blocking or controlling behavior through JSON. The events that do each use a different set of fields to express that decision. Use this table as a quick reference before writing a hook:

784 784 

785| Events | Decision pattern | Key fields |785| Events | Decision pattern | Key fields |

786| :---------------------------------------------------------------------------------------------------------------------------------- | :----------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |786| :---------------------------------------------------------------------------------------------------------------------------------- | :----------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

787| UserPromptSubmit, UserPromptExpansion, PostToolUse, PostToolUseFailure, PostToolBatch, Stop, SubagentStop, ConfigChange, PreCompact | Top-level `decision` | `decision: "block"`, `reason` |787| UserPromptSubmit, UserPromptExpansion, PostToolUse, PostToolUseFailure, PostToolBatch, Stop, SubagentStop, ConfigChange, PreCompact | Top-level `decision` | `decision: "block"`, `reason` |

788| TeammateIdle, TaskCreated, TaskCompleted | Exit code or `continue: false` | Exit code 2 blocks the action with stderr feedback. JSON `{"continue": false, "stopReason": "..."}` also stops the teammate entirely, matching `Stop` hook behavior |788| TeammateIdle, TaskCreated, TaskCompleted | Exit code or `continue: false` | Exit code 2 blocks the action with stderr feedback. JSON `{"continue": false, "stopReason": "..."}` also stops the teammate entirely, matching `Stop` hook behavior |

789| PreToolUse | `hookSpecificOutput` | `permissionDecision` (allow/deny/ask/defer), `permissionDecisionReason` |789| PreToolUse | `hookSpecificOutput` | `permissionDecision` (allow/deny/ask/defer), `permissionDecisionReason` |


792| WorktreeCreate | path return | Command hook prints path on stdout; HTTP hook returns `hookSpecificOutput.worktreePath`. Hook failure or missing path fails creation |792| WorktreeCreate | path return | Command hook prints path on stdout; HTTP hook returns `hookSpecificOutput.worktreePath`. Hook failure or missing path fails creation |

793| Elicitation | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (form field values for accept) |793| Elicitation | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (form field values for accept) |

794| ElicitationResult | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (form field values override) |794| ElicitationResult | `hookSpecificOutput` | `action` (accept/decline/cancel), `content` (form field values override) |

795| SessionStart, Setup, SubagentStart | Context only | `hookSpecificOutput.additionalContext` adds context for Claude. SessionStart also accepts [`initialUserMessage` and `watchPaths`](#sessionstart-decision-control). No blocking or decision control |

795| WorktreeRemove, Notification, SessionEnd, PostCompact, InstructionsLoaded, StopFailure, CwdChanged, FileChanged | None | No decision control. Used for side effects like logging or cleanup |796| WorktreeRemove, Notification, SessionEnd, PostCompact, InstructionsLoaded, StopFailure, CwdChanged, FileChanged | None | No decision control. Used for side effects like logging or cleanup |

796 797 

797Here are examples of each pattern in action:798Here are examples of each pattern in action:


882Any text your hook script prints to stdout is added as context for Claude. In addition to the [JSON output fields](#json-output) available to all hooks, you can return these event-specific fields:883Any text your hook script prints to stdout is added as context for Claude. In addition to the [JSON output fields](#json-output) available to all hooks, you can return these event-specific fields:

883 884 

884| Field | Description |885| Field | Description |

885| :------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |886| :------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

886| `additionalContext` | String added to Claude's context at the start of the conversation, before the first prompt. See [Add context for Claude](#add-context-for-claude) for how the text is delivered and what to put in it |887| `additionalContext` | String added to Claude's context at the start of the conversation, before the first prompt. See [Add context for Claude](#add-context-for-claude) for how the text is delivered and what to put in it |

888| `initialUserMessage` | String used as the first user message of the session. Applies in [non-interactive mode](/en/headless) (`-p`), where it becomes the first turn even if no prompt is provided. If a prompt is provided, it follows as the next turn. Unlike `additionalContext`, which attaches to an existing turn, this creates the turn |

889| `watchPaths` | Array of absolute paths to watch for [FileChanged](#filechanged) events during this session |

887 890 

888```json theme={null}891```json theme={null}

889{892{


1059To block a prompt, return a JSON object with `decision` set to `"block"`:1062To block a prompt, return a JSON object with `decision` set to `"block"`:

1060 1063 

1061| Field | Description |1064| Field | Description |

1062| :------------------ | :--------------------------------------------------------------------------------------------------------------------- |1065| :----------------------- | :--------------------------------------------------------------------------------------------------------------------- |

1063| `decision` | `"block"` prevents the prompt from being processed and erases it from context. Omit to allow the prompt to proceed |1066| `decision` | `"block"` prevents the prompt from being processed and erases it from context. Omit to allow the prompt to proceed |

1064| `reason` | Shown to the user when `decision` is `"block"`. Not added to context |1067| `reason` | Shown to the user when `decision` is `"block"`. Not added to context |

1065| `additionalContext` | String added to Claude's context alongside the submitted prompt. See [Add context for Claude](#add-context-for-claude) |1068| `additionalContext` | String added to Claude's context alongside the submitted prompt. See [Add context for Claude](#add-context-for-claude) |

1066| `sessionTitle` | Sets the session title. Use to name sessions automatically based on the prompt content |1069| `sessionTitle` | Sets the session title. Use to name sessions automatically based on the prompt content |

1070| `suppressOriginalPrompt` | If `true` when `decision` is `"block"`, omits the original prompt text from the block message shown to the user |

1067 1071 

1068```json theme={null}1072```json theme={null}

1069{1073{


1414| `addRules` | `rules`, `behavior`, `destination` | Adds permission rules. `rules` is an array of `{toolName, ruleContent?}` objects. Omit `ruleContent` to match the whole tool. `behavior` is `"allow"`, `"deny"`, or `"ask"` |1418| `addRules` | `rules`, `behavior`, `destination` | Adds permission rules. `rules` is an array of `{toolName, ruleContent?}` objects. Omit `ruleContent` to match the whole tool. `behavior` is `"allow"`, `"deny"`, or `"ask"` |

1415| `replaceRules` | `rules`, `behavior`, `destination` | Replaces all rules of the given `behavior` at the `destination` with the provided `rules` |1419| `replaceRules` | `rules`, `behavior`, `destination` | Replaces all rules of the given `behavior` at the `destination` with the provided `rules` |

1416| `removeRules` | `rules`, `behavior`, `destination` | Removes matching rules of the given `behavior` |1420| `removeRules` | `rules`, `behavior`, `destination` | Removes matching rules of the given `behavior` |

1417| `setMode` | `mode`, `destination` | Changes the permission mode. Valid modes are `default`, `acceptEdits`, `dontAsk`, `bypassPermissions`, and `plan` |1421| `setMode` | `mode`, `destination` | Changes the permission mode. Valid modes are `default`, `auto`, `acceptEdits`, `dontAsk`, `bypassPermissions`, and `plan` |

1418| `addDirectories` | `directories`, `destination` | Adds working directories. `directories` is an array of path strings |1422| `addDirectories` | `directories`, `destination` | Adds working directories. `directories` is an array of path strings |

1419| `removeDirectories` | `directories`, `destination` | Removes working directories |1423| `removeDirectories` | `directories`, `destination` | Removes working directories |

1420 1424 


1915| `tool` | MCP tool name. Present only for `monitor` and `MCP task` tasks |1919| `tool` | MCP tool name. Present only for `monitor` and `MCP task` tasks |

1916| `name` | Workflow name. Present only for `workflow` tasks |1920| `name` | Workflow name. Present only for `workflow` tasks |

1917 1921 

1918Each entry in `session_crons` describes one session-scoped scheduled wakeup, sourced from `CronCreate` and `/loop`:1922Each entry in `session_crons` describes one session-scoped scheduled wakeup, sourced from `CronCreate`, `ScheduleWakeup`, and `/loop`:

1919 1923 

1920| Field | Description |1924| Field | Description |

1921| :---------- | :------------------------------------------------------------------------------------------------------------------- |1925| :---------- | :------------------------------------------------------------------------------------------------------------------- |


2498 2502 

2499Events that support all five hook types (`command`, `http`, `mcp_tool`, `prompt`, and `agent`):2503Events that support all five hook types (`command`, `http`, `mcp_tool`, `prompt`, and `agent`):

2500 2504 

2505* `PermissionDenied`

2501* `PermissionRequest`2506* `PermissionRequest`

2502* `PostToolBatch`2507* `PostToolBatch`

2503* `PostToolUse`2508* `PostToolUse`


2507* `SubagentStop`2512* `SubagentStop`

2508* `TaskCompleted`2513* `TaskCompleted`

2509* `TaskCreated`2514* `TaskCreated`

2515* `TeammateIdle`

2510* `UserPromptExpansion`2516* `UserPromptExpansion`

2511* `UserPromptSubmit`2517* `UserPromptSubmit`

2512 2518 


2519* `FileChanged`2525* `FileChanged`

2520* `InstructionsLoaded`2526* `InstructionsLoaded`

2521* `Notification`2527* `Notification`

2522* `PermissionDenied`

2523* `PostCompact`2528* `PostCompact`

2524* `PreCompact`2529* `PreCompact`

2525* `SessionEnd`2530* `SessionEnd`

2526* `StopFailure`2531* `StopFailure`

2527* `SubagentStart`2532* `SubagentStart`

2528* `TeammateIdle`

2529* `WorktreeCreate`2533* `WorktreeCreate`

2530* `WorktreeRemove`2534* `WorktreeRemove`

2531 2535 


2593* `PostToolUse`: by default the turn ends and the reason appears in the chat as a warning line. Set `continueOnBlock: true` to feed the reason back to Claude and continue the turn instead2597* `PostToolUse`: by default the turn ends and the reason appears in the chat as a warning line. Set `continueOnBlock: true` to feed the reason back to Claude and continue the turn instead

2594* `PostToolBatch`, `UserPromptSubmit`, and `UserPromptExpansion`: the turn ends and the reason appears as a warning line. These events end the turn on `decision: "block"` regardless of `continue`2598* `PostToolBatch`, `UserPromptSubmit`, and `UserPromptExpansion`: the turn ends and the reason appears as a warning line. These events end the turn on `decision: "block"` regardless of `continue`

2595* `PostToolUseFailure`, `TaskCreated`, and `TaskCompleted`: the reason is returned to Claude as a tool error, similar to `PreToolUse`2599* `PostToolUseFailure`, `TaskCreated`, and `TaskCompleted`: the reason is returned to Claude as a tool error, similar to `PreToolUse`

2600* `TeammateIdle`: by default the teammate stops and the reason appears as a warning line. Set `continueOnBlock: true` to feed the reason back to the teammate and keep it working instead

2596* `PermissionRequest`: `ok: false` has no effect. To deny an approval from a hook, use a [command hook](#command-hook-fields) returning `hookSpecificOutput.decision.behavior: "deny"`2601* `PermissionRequest`: `ok: false` has no effect. To deny an approval from a hook, use a [command hook](#command-hook-fields) returning `hookSpecificOutput.decision.behavior: "deny"`

2602* `PermissionDenied`: `ok: false` has no effect because the denial already happened. The only output this event reads is `hookSpecificOutput.retry`, which prompt and agent hooks cannot set — they run on this event, but their output is discarded. Use a [command hook](#command-hook-fields) to return `retry`

2597 2603 

2598If you need finer control on any event, use a [command hook](#command-hook-fields) with the per-event fields described in [Decision control](#decision-control).2604If you need finer control on any event, use a [command hook](#command-hook-fields) with the per-event fields described in [Decision control](#decision-control).

2599 2605 

Details

545 exit 2 # exit 2 = block the action545 exit 2 # exit 2 = block the action

546fi546fi

547 547 

548exit 0 # exit 0 = let it proceed548exit 0 # exit 0 = no decision; the normal permission flow applies

549```549```

550 550 

551The exit code determines what happens next:551The exit code determines what happens next:

552 552 

553* **Exit 0**: the action proceeds. For `UserPromptSubmit`, `UserPromptExpansion`, and `SessionStart` hooks, anything you write to stdout is added to Claude's context.553* **Exit 0**: the hook reports no objection and the action proceeds normally. For a `PreToolUse` hook this doesn't approve the tool call: the normal [permission flow](/en/permissions) still applies. For `UserPromptSubmit`, `UserPromptExpansion`, and `SessionStart` hooks, anything you write to stdout is added to Claude's context.

554* **Exit 2**: the action is blocked. Write a reason to stderr, and Claude receives it as feedback so it can adjust. Some events cannot be blocked: for `SessionStart`, `Setup`, `Notification`, and others, exit 2 shows stderr to the user and execution continues. See [exit code 2 behavior per event](/en/hooks#exit-code-2-behavior-per-event) for the full list.554* **Exit 2**: the action is blocked. Write a reason to stderr, and Claude receives it as feedback so it can adjust. Some events cannot be blocked: for `SessionStart`, `Setup`, `Notification`, and others, exit 2 shows stderr to the user and execution continues. See [exit code 2 behavior per event](/en/hooks#exit-code-2-behavior-per-event) for the full list.

555* **Any other exit code**: the action proceeds. The transcript shows a `<hook name> hook error` notice followed by the first line of stderr; the full stderr goes to the [debug log](/en/hooks#debug-hooks).555* **Any other exit code**: the action proceeds. The transcript shows a `<hook name> hook error` notice followed by the first line of stderr; the full stderr goes to the [debug log](/en/hooks#debug-hooks).

556 556 

557#### Structured JSON output557#### Structured JSON output

558 558 

559Exit codes give you two options: allow or block. For more control, exit 0 and print a JSON object to stdout instead.559Exit codes only let you block or stay silent. For more control, exit 0 and print a JSON object to stdout instead.

560 560 

561<Note>561<Note>

562 Use exit 2 to block with a stderr message, or exit 0 with JSON for structured control. Don't mix them: Claude Code ignores JSON when you exit 2.562 Use exit 2 to block with a stderr message, or exit 0 with JSON for structured control. Don't mix them: Claude Code ignores JSON when you exit 2.

Details

197 197 

198#### Interrupt and steer198#### Interrupt and steer

199 199 

200You can interrupt Claude at any point. If it's going down the wrong path, just type your correction and press Enter. Claude will stop what it's doing and adjust its approach based on your input. You don't have to wait for it to finish or start over.200You can redirect Claude at any point without waiting for the turn to finish or starting over:

201 

202* **Press `Esc`** to stop Claude immediately. The running tool call is canceled and Claude waits for your next instruction.

203* **Type a correction and press `Enter`** to send it without stopping the running tool. Claude reads it as soon as the current action completes and adjusts before deciding its next step.

201 204 

202### Be specific upfront205### Be specific upfront

203 206 

Details

24 24 

25| Shortcut | Description | Context |25| Shortcut | Description | Context |

26| :------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |26| :------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

27| `Ctrl+C` | Cancel current input or generation | Standard interrupt |27| `Ctrl+C` | Interrupt, or clear input | Interrupts a running operation. If nothing is running, the first press clears the prompt input and a second press exits Claude Code |

28| `Ctrl+X Ctrl+K` | Kill all running [background subagents](/en/sub-agents#run-subagents-in-foreground-or-background) in this session. Press twice within 3 seconds to confirm | Subagent control |28| `Ctrl+X Ctrl+K` | Kill all running [background subagents](/en/sub-agents#run-subagents-in-foreground-or-background) in this session. Press twice within 3 seconds to confirm | Subagent control |

29| `Ctrl+D` | Exit Claude Code session | EOF signal |29| `Ctrl+D` | Exit Claude Code session | EOF signal |

30| `Ctrl+G` or `Ctrl+X Ctrl+E` | Open in default text editor | Edit your prompt or custom response in your default text editor. `Ctrl+X Ctrl+E` is the readline-native binding. Turn on Show last response in external editor in `/config` to prepend Claude's previous reply as `#`-commented context above your prompt; the comment block is stripped when you save |30| `Ctrl+G` or `Ctrl+X Ctrl+E` | Open in default text editor | Edit your prompt or custom response in your default text editor. `Ctrl+X Ctrl+E` is the readline-native binding. Turn on Show last response in external editor in `/config` to prepend Claude's previous reply as `#`-commented context above your prompt; the comment block is stripped when you save |


37| `Left/Right arrows` | Cycle through dialog tabs | Navigate between tabs in permission dialogs and menus |37| `Left/Right arrows` | Cycle through dialog tabs | Navigate between tabs in permission dialogs and menus |

38| `Up/Down arrows` or `Ctrl+P`/`Ctrl+N` | Move cursor or navigate command history | In multiline input, first moves the cursor within the prompt. Once the cursor is already on the top or bottom edge, pressing again navigates command history |38| `Up/Down arrows` or `Ctrl+P`/`Ctrl+N` | Move cursor or navigate command history | In multiline input, first moves the cursor within the prompt. Once the cursor is already on the top or bottom edge, pressing again navigates command history |

39| `Esc` | Interrupt Claude | Stop the current response or tool call mid-turn so you can redirect. Claude keeps the work done so far |39| `Esc` | Interrupt Claude | Stop the current response or tool call mid-turn so you can redirect. Claude keeps the work done so far |

40| `Esc` + `Esc` | Rewind or summarize | Restore code and/or conversation to a previous point, or summarize from a selected message |40| `Esc` + `Esc` | Clear input draft, or rewind | When the prompt input contains text, double `Esc` clears it and saves the draft to history so `Up` recalls it. When the input is empty, double `Esc` opens the [rewind menu](/en/checkpointing) to restore or summarize code and conversation from a previous point |

41| `Shift+Tab` or `Alt+M` (some configurations) | Cycle permission modes | Cycle through `default`, `acceptEdits`, `plan`, and any modes you have enabled, such as `auto` or `bypassPermissions`. See [permission modes](/en/permission-modes). |41| `Shift+Tab` or `Alt+M` (some configurations) | Cycle permission modes | Cycle through `default`, `acceptEdits`, `plan`, and any modes you have enabled, such as `auto` or `bypassPermissions`. See [permission modes](/en/permission-modes). |

42| `Option+P` (macOS) or `Alt+P` (Windows/Linux) | Switch model | Switch models without clearing your prompt |42| `Option+P` (macOS) or `Alt+P` (Windows/Linux) | Switch model | Switch models without clearing your prompt |

43| `Option+T` (macOS) or `Alt+T` (Windows/Linux) | Toggle extended thinking | Enable or disable extended thinking mode. {/* min-version: 2.1.132 */}As of v2.1.132 this shortcut works on macOS without configuring Option as Meta |43| `Option+T` (macOS) or `Alt+T` (Windows/Linux) | Toggle extended thinking | Enable or disable extended thinking mode. {/* min-version: 2.1.132 */}As of v2.1.132 this shortcut works on macOS without configuring Option as Meta |

Details

323The following settings are only read from managed settings. Placing them in user or project settings files has no effect.323The following settings are only read from managed settings. Placing them in user or project settings files has no effect.

324 324 

325| Setting | Description |325| Setting | Description |

326| :--------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |326| :--------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

327| `allowedChannelPlugins` | Allowlist of channel plugins that may push messages. Replaces the default Anthropic allowlist when set. Requires `channelsEnabled: true`. See [Restrict which channel plugins can run](/en/channels#restrict-which-channel-plugins-can-run) |327| `allowedChannelPlugins` | Allowlist of channel plugins that may push messages. Replaces the default Anthropic allowlist when set. Requires `channelsEnabled: true`. See [Restrict which channel plugins can run](/en/channels#restrict-which-channel-plugins-can-run) |

328| `allowManagedHooksOnly` | When `true`, only managed hooks, SDK hooks, and hooks from plugins force-enabled in managed settings `enabledPlugins` are loaded. User, project, and all other plugin hooks are blocked |328| `allowManagedHooksOnly` | When `true`, only managed hooks, SDK hooks, and hooks from plugins force-enabled in managed settings `enabledPlugins` are loaded. User, project, and all other plugin hooks are blocked |

329| `allowManagedMcpServersOnly` | When `true`, only `allowedMcpServers` from managed settings are respected. `deniedMcpServers` still merges from all sources. See [Managed MCP configuration](/en/mcp#managed-mcp-configuration) |329| `allowManagedMcpServersOnly` | When `true`, only `allowedMcpServers` from managed settings are respected. `deniedMcpServers` still merges from all sources. See [Managed MCP configuration](/en/mcp#managed-mcp-configuration) |


335| `sandbox.filesystem.allowManagedReadPathsOnly` | When `true`, only `filesystem.allowRead` paths from managed settings are respected. `denyRead` still merges from all sources |335| `sandbox.filesystem.allowManagedReadPathsOnly` | When `true`, only `filesystem.allowRead` paths from managed settings are respected. `denyRead` still merges from all sources |

336| `sandbox.network.allowManagedDomainsOnly` | When `true`, only `allowedDomains` and `WebFetch(domain:...)` allow rules from managed settings are respected. Non-allowed domains are blocked automatically without prompting the user. Denied domains still merge from all sources |336| `sandbox.network.allowManagedDomainsOnly` | When `true`, only `allowedDomains` and `WebFetch(domain:...)` allow rules from managed settings are respected. Non-allowed domains are blocked automatically without prompting the user. Denied domains still merge from all sources |

337| `strictKnownMarketplaces` | Controls which plugin marketplace sources users can add and install plugins from. See [managed marketplace restrictions](/en/plugin-marketplaces#managed-marketplace-restrictions) |337| `strictKnownMarketplaces` | Controls which plugin marketplace sources users can add and install plugins from. See [managed marketplace restrictions](/en/plugin-marketplaces#managed-marketplace-restrictions) |

338| `strictPluginOnlyCustomization` | Block skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings. `true` locks all four surfaces; an array such as `["skills", "hooks"]` locks only the named ones. See [`strictPluginOnlyCustomization`](/en/settings#strictpluginonlycustomization) |

338| `wslInheritsWindowsSettings` | When `true` in the Windows HKLM registry key or `C:\Program Files\ClaudeCode\managed-settings.json`, WSL reads managed settings from the Windows policy chain in addition to `/etc/claude-code`. See [Settings files](/en/settings#settings-files) |339| `wslInheritsWindowsSettings` | When `true` in the Windows HKLM registry key or `C:\Program Files\ClaudeCode\managed-settings.json`, WSL reads managed settings from the Windows policy chain in addition to `/etc/claude-code`. See [Settings files](/en/settings#settings-files) |

339 340 

340`disableBypassPermissionsMode` is typically placed in managed settings to enforce organizational policy, but it works from any scope. A user can set it in their own settings to lock themselves out of bypass mode.341`disableBypassPermissionsMode` is typically placed in managed settings to enforce organizational policy, but it works from any scope. A user can set it in their own settings to lock themselves out of bypass mode.

en/plugin-hints.md +148 −0 created

Details

1> ## Documentation Index

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

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

4 

5# Recommend your plugin from your CLI

6 

7> Emit a one-line marker from your CLI so Claude Code prompts users to install your official plugin.

8 

9If you maintain a CLI or SDK and have a plugin in the official Anthropic marketplace, your tool can prompt Claude Code users to install that plugin. Your CLI writes a one-line marker to stderr when it detects it is running inside Claude Code. Claude Code reads the marker, strips it from the output, and shows the user a one-time install prompt.

10 

11Claude Code strips the hint line from the command output before sending it to the model, so the marker never appears in the conversation and is not counted toward token usage. The protocol requires no extra commands and does not change what your CLI prints for users outside Claude Code.

12 

13This page is for CLI and SDK maintainers. If you are looking to install plugins, see [Discover and install plugins](/en/discover-plugins).

14 

15## How it works

16 

17Claude Code sets the [`CLAUDECODE`](/en/env-vars) environment variable to `1` for every command it runs through the Bash and PowerShell tools, and for [hook](/en/hooks) commands. When your CLI sees that variable, it writes a self-closing `<claude-code-hint />` tag to stderr. In hook commands the hint tag is stripped and ignored. Only Bash and PowerShell tool output triggers the install prompt.

18 

19When Claude Code receives the command output, it:

20 

211. Scans for hint lines and removes them before the output reaches the model

222. Checks that the hint targets a plugin in an official Anthropic marketplace

233. Checks that the plugin is not already installed and has not been prompted before

244. Shows the user an install prompt that names the command that emitted the hint

25 

26Claude Code never installs a plugin automatically. The user always confirms.

27 

28## Emit the hint

29 

30Gate emission on the `CLAUDECODE` environment variable so the marker never appears in a human user's terminal. Then write the tag to stderr on its own line.

31 

32The following examples emit a hint for a plugin named `example-cli` in the official marketplace:

33 

34<CodeGroup>

35 ```javascript Node.js theme={null}

36 if (process.env.CLAUDECODE) {

37 process.stderr.write(

38 '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />\n',

39 )

40 }

41 ```

42 

43 ```python Python theme={null}

44 import os, sys

45 

46 if os.environ.get("CLAUDECODE"):

47 print(

48 '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />',

49 file=sys.stderr,

50 )

51 ```

52 

53 ```go Go theme={null}

54 if os.Getenv("CLAUDECODE") != "" {

55 fmt.Fprintln(os.Stderr,

56 `<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />`)

57 }

58 ```

59 

60 ```shell Shell theme={null}

61 [ -n "$CLAUDECODE" ] &&

62 printf '%s\n' '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />' >&2

63 ```

64</CodeGroup>

65 

66Replace `example-cli` with your plugin's name in the official marketplace.

67 

68## Choose where to emit

69 

70You control which code paths emit the hint. Claude Code deduplicates by plugin, so emitting on every invocation has no downside. Touchpoints that work well include:

71 

72| Placement | Why it works |

73| :------------------------ | :--------------------------------------------------------- |

74| `--help` output | Claude often runs help when exploring an unfamiliar CLI |

75| Unknown-subcommand errors | Reaches the moment Claude is confused about your interface |

76| Login or auth success | The user is already in a setup mindset |

77| First-run welcome message | A natural onboarding moment |

78 

79## What the user sees

80 

81When the hint passes all checks, Claude Code shows a prompt like the following:

82 

83```text theme={null}

84─────────────────────────────────────────────────────────────

85 Plugin Recommendation

86 

87 The example-cli command suggests installing a plugin.

88 

89 Plugin: example-cli

90 Marketplace: claude-plugins-official

91 Official integration for example-cli deployments

92 

93 Would you like to install it?

94 ❯ 1. Yes, install example-cli

95 2. No

96 3. No, and don't show plugin installation hints again

97 

98─────────────────────────────────────────────────────────────

99```

100 

101The prompt names the command that produced the hint so users can spot a mismatch between the tool and the plugin it recommends. If the user does not respond within 30 seconds, the prompt dismisses as **No**.

102 

103Prompt frequency is bounded:

104 

105* **Once per plugin**: after the prompt is shown, Claude Code records the plugin and never prompts for it again, regardless of the user's answer.

106* **Once per session**: across all CLIs on the machine, at most one hint prompt appears per Claude Code session.

107 

108Selecting **Yes** installs the plugin to user scope. Selecting **No, and don't show plugin installation hints again** disables all future hint prompts for the user.

109 

110## Hint format

111 

112The hint is a self-closing tag with three required attributes.

113 

114```text theme={null}

115<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />

116```

117 

118| Attribute | Required | Description |

119| :-------- | :------- | :------------------------------------------------ |

120| `v` | Yes | Protocol version. `1` is the only supported value |

121| `type` | Yes | Hint kind. `plugin` is the only supported value |

122| `value` | Yes | Plugin identifier in `name@marketplace` form |

123 

124Attribute values may be quoted with double quotes or left unquoted. Unquoted values cannot contain whitespace. Escape sequences are not supported.

125 

126## Requirements

127 

128Claude Code enforces two conditions before acting on a hint. Hints that fail either check are dropped:

129 

130* **Own line**: the tag must occupy its own line. A tag embedded mid-line, for example inside a log statement, is ignored. Leading and trailing whitespace on the line is allowed.

131* **Official marketplace**: the `value` must reference a plugin in an Anthropic-controlled marketplace such as `claude-plugins-official`. Hints that point to other marketplaces are silently dropped.

132 

133The hint line is always removed from the output before it reaches the model, even when the version or type is unrecognized, so the marker is never counted toward token usage.

134 

135The remaining guidance is recommended but not enforced. Claude Code cannot observe whether your CLI follows it:

136 

137* **Write to stderr**: stderr keeps the tag out of shell pipelines such as `example-cli deploy | jq`. Claude Code scans both streams, so stdout also works.

138* **Gate on `CLAUDECODE`**: only emit when the `CLAUDECODE` environment variable is set. This prevents the marker from appearing to users running your CLI directly.

139 

140## Get your plugin into the official marketplace

141 

142The hint protocol only takes effect for plugins listed in the official Anthropic marketplace, `claude-plugins-official`. Anthropic curates that marketplace at its discretion, and the in-app submission forms add plugins to the [community marketplace](/en/plugins#submit-your-plugin-to-the-community-marketplace) instead, which the hint protocol does not check. If you are working with an Anthropic partner contact, reach out to them to coordinate an official-marketplace listing.

143 

144## See also

145 

146* [Create plugins](/en/plugins): build the plugin your CLI recommends

147* [Create and distribute a plugin marketplace](/en/plugin-marketplaces): host plugins outside the official marketplace

148* [Environment variables](/en/env-vars): full reference for `CLAUDECODE` and related variables

Details

945 945 

946* Verify the marketplace URL is accessible946* Verify the marketplace URL is accessible

947* Check that `.claude-plugin/marketplace.json` exists at the specified path947* Check that `.claude-plugin/marketplace.json` exists at the specified path

948* Ensure JSON syntax is valid and frontmatter is well-formed using `claude plugin validate` or `/plugin validate`948* Ensure JSON syntax is valid using `claude plugin validate` or `/plugin validate`. To check skill, agent, and command frontmatter, run the command against each plugin directory

949* For private repositories, confirm you have access permissions949* For private repositories, confirm you have access permissions

950 950 

951### Marketplace validation errors951### Marketplace validation errors

952 952 

953Run `claude plugin validate .` or `/plugin validate .` from your marketplace directory to check for issues. The validator checks `plugin.json`, skill/agent/command frontmatter, and `hooks/hooks.json` for syntax and schema errors. Common errors:953Run `claude plugin validate .` or `/plugin validate .` from your marketplace directory to check for issues. When pointed at a marketplace directory, the validator checks `marketplace.json` only: schema, duplicate plugin names, source path traversal, and version mismatches against each referenced `plugin.json`.

954 

955To validate an individual plugin's `plugin.json` and its skill, agent, command, and hook files, run the command against the plugin directory itself, for example `claude plugin validate ./plugins/my-plugin`. Common errors:

954 956 

955| Error | Cause | Solution |957| Error | Cause | Solution |

956| :------------------------------------------------ | :---------------------------------------------- | :--------------------------------------------------------------------------------------------- |958| :------------------------------------------------ | :---------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------ |

957| `File not found: .claude-plugin/marketplace.json` | Missing manifest | Create `.claude-plugin/marketplace.json` with required fields |959| `File not found: .claude-plugin/marketplace.json` | Missing manifest | Create `.claude-plugin/marketplace.json` with required fields |

958| `Invalid JSON syntax: Unexpected token...` | JSON syntax error in marketplace.json | Check for missing commas, extra commas, or unquoted strings |960| `Invalid JSON syntax: Unexpected token...` | JSON syntax error in marketplace.json | Check for missing commas, extra commas, or unquoted strings |

959| `Duplicate plugin name "x" found in marketplace` | Two plugins share the same name | Give each plugin a unique `name` value |961| `Duplicate plugin name "x" found in marketplace` | Two plugins share the same name | Give each plugin a unique `name` value |

960| `plugins[0].source: Path contains ".."` | Source path contains `..` | Use paths relative to the marketplace root without `..`. See [Relative paths](#relative-paths) |962| `plugins[0].source: Path contains ".."` | Source path contains `..` | Use paths relative to the marketplace root without `..`. See [Relative paths](#relative-paths) |

961| `YAML frontmatter failed to parse: ...` | Invalid YAML in a skill, agent, or command file | Fix the YAML syntax in the frontmatter block. At runtime this file loads with no metadata. |963| `YAML frontmatter failed to parse: ...` | Invalid YAML in a skill, agent, or command file | Fix the YAML syntax in the frontmatter block. At runtime this file loads with no metadata. Reported only when validating a plugin directory |

962| `Invalid JSON syntax: ...` (hooks.json) | Malformed `hooks/hooks.json` | Fix JSON syntax. A malformed `hooks/hooks.json` prevents the entire plugin from loading. |964| `Invalid JSON syntax: ...` (hooks.json) | Malformed `hooks/hooks.json` | Fix JSON syntax. A malformed `hooks/hooks.json` prevents the entire plugin from loading. Reported only when validating a plugin directory |

963 965 

964**Warnings** (non-blocking):966**Warnings** (non-blocking):

965 967 

en/prompt-library.md +1389 −0 created

Details

1> ## Documentation Index

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

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

4 

5# Prompt library

6 

7> Copy-paste prompts for Claude Code, tagged by task and role.

8 

9export const PromptLibrary = ({text = {}, labels = {}, tagLabels = {}, phaseLabels = {}, sourceLabels = {}, catLabels = {}}) => {

10 const RAW = useMemo(() => [{

11 id: 'get-oriented-in-a',

12 sdlc: 'discover',

13 cat: 'Onboard',

14 startN: 1,

15 roles: [],

16 prompt: 'give me an overview of this codebase: architecture, key directories, and how the pieces connect',

17 nextHref: '/en/memory',

18 src: 'workflows'

19 }, {

20 id: 'explain-unfamiliar-code',

21 sdlc: 'discover',

22 cat: 'Understand',

23 roles: [],

24 prompt: 'explain what {path} does and how data flows through it. write it up as {format}',

25 slots: {

26 path: 'src/scheduler/queue.ts',

27 format: 'an HTML page with a diagram, then open it in my browser'

28 },

29 nextHref: '/en/output-styles',

30 src: 'workflows'

31 }, {

32 id: 'find-where-something-happens',

33 sdlc: 'discover',

34 cat: 'Understand',

35 startN: 2,

36 roles: [],

37 prompt: 'where do we {behavior}?',

38 slots: {

39 behavior: 'validate uploaded file types'

40 },

41 src: 'workflows'

42 }, {

43 id: 'see-what-depends-on',

44 sdlc: 'discover',

45 cat: 'Understand',

46 roles: [],

47 prompt: 'what would break if I deleted {target}?',

48 slots: {

49 target: 'the retryWithBackoff helper'

50 },

51 src: 'workflows'

52 }, {

53 id: 'trace-how-code-evolved',

54 sdlc: 'discover',

55 cat: 'Understand',

56 roles: [],

57 prompt: 'look through the commit history of {path} and summarize how it evolved and why',

58 slots: {

59 path: 'internal/auth/session.go'

60 },

61 src: 'best-practices'

62 }, {

63 id: 'scope-a-change-before',

64 sdlc: 'discover',

65 cat: 'Understand',

66 roles: ['pm', 'design'],

67 prompt: 'which files would I need to touch to {change}?',

68 slots: {

69 change: 'add a dark mode toggle to settings'

70 },

71 src: 'teams'

72 }, {

73 id: 'ask-the-codebase-a',

74 sdlc: 'discover',

75 cat: 'Understand',

76 roles: ['pm'],

77 prompt: 'I am a {role}. walk me through what happens when a user {action}, from the UI down to the result',

78 slots: {

79 role: 'PM',

80 action: 'clicks Export to PDF'

81 },

82 nextHref: '/en/output-styles',

83 src: 'teams'

84 }, {

85 id: 'plan-a-multi-file',

86 sdlc: 'design',

87 cat: 'Plan',

88 roles: ['pm', 'design'],

89 prompt: 'plan how to refactor the {target} to {goal}. list the files you would change, but don\'t edit anything yet',

90 slots: {

91 target: 'payment module',

92 goal: 'support multiple currencies'

93 },

94 src: 'workflows'

95 }, {

96 id: 'draft-a-spec-by',

97 sdlc: 'design',

98 cat: 'Plan',

99 roles: ['pm'],

100 prompt: 'I want to build {feature}. interview me about implementation, UX, edge cases, and tradeoffs until we have covered everything, then write the spec to SPEC.md',

101 slots: {

102 feature: 'per-workspace rate limits'

103 },

104 nextHref: '/en/skills',

105 src: 'best-practices'

106 }, {

107 id: 'turn-a-meeting-into',

108 sdlc: 'design',

109 cat: 'Plan',

110 roles: ['pm'],

111 prompt: 'read {input} and write up the action items, then create a {tracker} ticket for each with acceptance criteria',

112 slots: {

113 input: '@meeting-notes.md',

114 tracker: 'Linear'

115 },

116 needs: 'tracker',

117 nextHref: '/en/skills',

118 src: 'teams'

119 }, {

120 id: 'map-edge-cases-before',

121 sdlc: 'design',

122 cat: 'Plan',

123 roles: ['design', 'pm'],

124 prompt: 'list the error states, empty states, and edge cases for {feature} that the design needs to cover',

125 slots: {

126 feature: 'the file upload flow'

127 },

128 src: 'teams'

129 }, {

130 id: 'turn-a-mockup-into',

131 sdlc: 'design',

132 cat: 'Prototype',

133 roles: ['design', 'pm', 'marketing'],

134 paste: 'mockup',

135 prompt: 'here is a mockup. build a working prototype I can click through, matching the layout and states shown',

136 src: 'teams'

137 }, {

138 id: 'implement-from-a-screenshot',

139 sdlc: 'design',

140 cat: 'Prototype',

141 roles: ['design'],

142 paste: 'design',

143 needs: 'browser',

144 prompt: 'implement this design, then take a screenshot of the result, compare it to the original, and fix any differences',

145 nextHref: '/en/goal',

146 src: 'best-practices'

147 }, {

148 id: 'follow-an-existing-pattern',

149 sdlc: 'build',

150 cat: 'Implement',

151 roles: [],

152 prompt: 'look at how {example} is implemented to understand the pattern, then build {new} the same way',

153 slots: {

154 example: 'the GitHub webhook handler',

155 new: 'a Stripe webhook handler'

156 },

157 nextHref: '/en/memory',

158 src: 'best-practices'

159 }, {

160 id: 'generate-docs-for-code',

161 sdlc: 'build',

162 cat: 'Implement',

163 roles: ['docs'],

164 prompt: 'find {scope} without {format} comments and add them, matching the style already used in the file',

165 slots: {

166 scope: 'the public functions in src/auth/',

167 format: 'JSDoc'

168 },

169 src: 'workflows'

170 }, {

171 id: 'add-a-small-well',

172 sdlc: 'build',

173 cat: 'Implement',

174 roles: [],

175 prompt: 'add a {endpoint} endpoint that returns {payload}',

176 slots: {

177 endpoint: '/health',

178 payload: 'the app version and uptime'

179 },

180 src: 'workflows'

181 }, {

182 id: 'build-a-small-internal',

183 sdlc: 'build',

184 cat: 'Implement',

185 roles: ['pm', 'design', 'marketing', 'docs'],

186 prompt: 'create a {tool} using HTML, CSS, and vanilla JavaScript, then open it in my browser',

187 slots: {

188 tool: 'drag-and-drop Kanban board with three columns'

189 },

190 src: 'teams'

191 }, {

192 id: 'work-an-issue-end',

193 sdlc: 'build',

194 cat: 'Implement',

195 roles: [],

196 prompt: 'read issue #{issue}, implement the fix, and run the tests',

197 slots: {

198 issue: '312'

199 },

200 needs: 'gh',

201 src: 'workflows'

202 }, {

203 id: 'find-and-update-copy',

204 sdlc: 'build',

205 cat: 'Implement',

206 roles: ['design', 'docs', 'marketing'],

207 prompt: 'find every place we say "{copy}" or a close variant, show me each one in context, then update them all to "{new}". leave tests and the changelog alone',

208 slots: {

209 copy: 'Sign up free',

210 new: 'Start free trial'

211 },

212 src: 'teams'

213 }, {

214 id: 'draft-from-past-examples',

215 sdlc: 'build',

216 cat: 'Implement',

217 roles: ['docs', 'marketing', 'pm'],

218 prompt: 'read the {examples} in {folder} to learn the structure and voice, then draft a new one for {topic}',

219 slots: {

220 examples: 'privacy impact assessments',

221 folder: 'legal/pia/',

222 topic: 'the new analytics integration'

223 },

224 nextHref: '/en/skills',

225 src: 'legal'

226 }, {

227 id: 'write-tests-run-them',

228 sdlc: 'build',

229 cat: 'Test',

230 startN: 4,

231 roles: [],

232 prompt: 'write tests for {path}, run them, and fix any failures',

233 slots: {

234 path: 'app/parsers/feed.py'

235 },

236 nextHref: '/en/memory',

237 src: 'workflows'

238 }, {

239 id: 'drive-implementation-from-tests',

240 sdlc: 'build',

241 cat: 'Test',

242 roles: [],

243 prompt: 'write tests for {feature} first, then implement it until they pass',

244 slots: {

245 feature: 'the password reset flow'

246 },

247 src: 'ebook'

248 }, {

249 id: 'fill-gaps-from-a',

250 sdlc: 'build',

251 cat: 'Test',

252 roles: [],

253 prompt: 'read {report} and add tests for the lowest-covered files until each is above {target}%',

254 slots: {

255 report: 'coverage/coverage-summary.json',

256 target: '80'

257 },

258 nextHref: '/en/goal',

259 src: 'workflows'

260 }, {

261 id: 'migrate-a-pattern-across',

262 sdlc: 'build',

263 cat: 'Refactor',

264 roles: [],

265 prompt: 'migrate everything from {from} to {to}: identify every place that needs to change, then make the changes',

266 slots: {

267 from: 'the old logging API',

268 to: 'the structured logger'

269 },

270 src: 'workflows'

271 }, {

272 id: 'port-code-between-languages',

273 sdlc: 'build',

274 cat: 'Refactor',

275 roles: [],

276 prompt: 'port {source} to {target}, keeping the same {keep}',

277 slots: {

278 source: 'this Python module',

279 target: 'Rust',

280 keep: 'public API and test behavior'

281 },

282 src: 'teams'

283 }, {

284 id: 'optimize-against-a-measurable',

285 sdlc: 'build',

286 cat: 'Refactor',

287 roles: ['data'],

288 prompt: 'optimize {target} to bring {metric} from {current} down to under {goal}',

289 slots: {

290 target: 'the search query',

291 metric: 'p95 latency',

292 current: '2s',

293 goal: '500ms'

294 },

295 nextHref: '/en/goal',

296 src: 'ebook'

297 }, {

298 id: 'fix-a-precise-visual',

299 sdlc: 'build',

300 cat: 'Refactor',

301 roles: ['design'],

302 prompt: 'the {element} extends {amount} beyond the {container} on {viewport}. fix it.',

303 slots: {

304 element: 'login button',

305 amount: '20px',

306 container: 'card border',

307 viewport: 'mobile'

308 },

309 nextHref: '/en/desktop#preview-your-app',

310 src: 'ebook'

311 }, {

312 id: 'review-your-changes-before',

313 sdlc: 'build',

314 cat: 'Review',

315 startN: 5,

316 roles: [],

317 prompt: 'review my uncommitted changes and flag anything that looks risky before I commit',

318 nextHref: '/en/commands',

319 src: 'workflows'

320 }, {

321 id: 'review-a-pull-request',

322 sdlc: 'build',

323 cat: 'Review',

324 roles: [],

325 prompt: 'review PR #{pr} and summarize what changed, then list any concerns',

326 slots: {

327 pr: '247'

328 },

329 needs: 'gh',

330 nextHref: '/en/code-review',

331 src: 'workflows'

332 }, {

333 id: 'review-infrastructure-changes-before',

334 sdlc: 'build',

335 cat: 'Review',

336 roles: ['security', 'ops'],

337 paste: 'plan',

338 prompt: 'here is my Terraform plan output. what is this going to do, and is anything here going to cause problems?',

339 src: 'teams'

340 }, {

341 id: 'run-a-security-review',

342 sdlc: 'build',

343 cat: 'Review',

344 roles: ['security'],

345 prompt: 'use a subagent to review {path} for security issues and report what it finds',

346 slots: {

347 path: 'src/api/'

348 },

349 nextHref: '/en/sub-agents',

350 src: 'best-practices'

351 }, {

352 id: 'review-content-before-sending',

353 sdlc: 'build',

354 cat: 'Review',

355 roles: ['marketing', 'docs'],

356 prompt: 'review {file} for {concerns} and list anything I should fix before it goes to {reviewer}',

357 slots: {

358 file: 'launch-post.md',

359 concerns: 'unsupported claims, missing attributions, and brand-guideline issues',

360 reviewer: 'legal'

361 },

362 nextHref: '/en/skills',

363 src: 'legal'

364 }, {

365 id: 'course-correct-a-wrong',

366 sdlc: 'build',

367 cat: 'Steer',

368 roles: [],

369 prompt: 'that is not right: {feedback}. try a different approach',

370 slots: {

371 feedback: 'the function signature needs to stay backward-compatible'

372 },

373 nextHref: '/en/checkpointing',

374 src: 'best-practices'

375 }, {

376 id: 'narrow-the-scope-of',

377 sdlc: 'build',

378 cat: 'Steer',

379 roles: [],

380 prompt: 'that is too much. keep only the changes to {scope} and undo your other edits',

381 slots: {

382 scope: 'the validation logic in src/forms/'

383 },

384 src: 'best-practices'

385 }, {

386 id: 'turn-a-correction-into',

387 sdlc: 'build',

388 cat: 'Steer',

389 roles: [],

390 prompt: 'you keep {mistake}. add a rule to CLAUDE.md so this stops happening',

391 slots: {

392 mistake: 'using default exports when this project uses named exports'

393 },

394 nextHref: '/en/memory',

395 src: 'best-practices'

396 }, {

397 id: 'resolve-merge-conflicts',

398 sdlc: 'ship',

399 cat: 'Git',

400 roles: [],

401 prompt: 'resolve the merge conflicts in this branch and explain what you kept from each side',

402 src: 'workflows'

403 }, {

404 id: 'commit-with-a-generated',

405 sdlc: 'ship',

406 cat: 'Git',

407 roles: [],

408 prompt: 'commit these changes with a message that summarizes what I did',

409 src: 'workflows'

410 }, {

411 id: 'open-a-pull-request',

412 sdlc: 'ship',

413 cat: 'Git',

414 roles: [],

415 prompt: 'find the {tracker} ticket about {topic} and open a PR that implements it',

416 slots: {

417 tracker: 'Linear',

418 topic: 'the login timeout'

419 },

420 needs: 'tracker',

421 src: 'workflows'

422 }, {

423 id: 'draft-release-notes-from',

424 sdlc: 'ship',

425 cat: 'Release',

426 roles: ['pm', 'docs', 'marketing'],

427 prompt: 'compare {from} to {to} and draft release notes grouped by feature, fix, and breaking change',

428 slots: {

429 from: 'v2.3.0',

430 to: 'v2.4.0'

431 },

432 nextHref: '/en/skills',

433 src: 'workflows'

434 }, {

435 id: 'write-a-ci-workflow',

436 sdlc: 'ship',

437 cat: 'Release',

438 roles: ['ops'],

439 prompt: 'write a GitHub Actions workflow that {steps} on every push to {branch}',

440 slots: {

441 steps: 'runs the tests and deploys to staging',

442 branch: 'main'

443 },

444 src: 'workflows'

445 }, {

446 id: 'find-and-fix-a',

447 sdlc: 'operate',

448 cat: 'Debug',

449 startN: 3,

450 roles: [],

451 prompt: 'the {test} test is failing, find out why and fix it',

452 slots: {

453 test: 'UserAuth'

454 },

455 src: 'workflows'

456 }, {

457 id: 'investigate-a-reported-error',

458 sdlc: 'operate',

459 cat: 'Debug',

460 roles: ['ops'],

461 prompt: 'users are seeing {symptom} on {where}. investigate and tell me what is going on',

462 slots: {

463 symptom: '500 errors',

464 where: '/api/settings'

465 },

466 nextHref: '/en/web-quickstart#pre-fill-sessions',

467 src: 'workflows'

468 }, {

469 id: 'fix-a-build-error',

470 sdlc: 'operate',

471 cat: 'Debug',

472 roles: ['ops'],

473 paste: 'error',

474 prompt: 'here is a build error. fix the root cause and verify the build succeeds',

475 src: 'best-practices'

476 }, {

477 id: 'investigate-a-production-incident',

478 sdlc: 'operate',

479 cat: 'Incident',

480 roles: ['ops', 'security'],

481 prompt: '{symptom}. check the logs, recent deploys, and config changes, then tell me the most likely cause',

482 slots: {

483 symptom: 'the checkout endpoint started returning 500s an hour ago'

484 },

485 nextHref: '/en/mcp',

486 src: 'workflows'

487 }, {

488 id: 'diagnose-from-a-console',

489 sdlc: 'operate',

490 cat: 'Incident',

491 roles: ['ops', 'data'],

492 paste: 'screenshot',

493 prompt: 'here is a screenshot of {console}. walk me through why {resource} is failing and give me the exact commands to fix it',

494 slots: {

495 console: 'the GCP Kubernetes dashboard',

496 resource: 'this pod'

497 },

498 src: 'teams'

499 }, {

500 id: 'query-logs-in-plain',

501 sdlc: 'operate',

502 cat: 'Incident',

503 roles: ['security', 'ops', 'data'],

504 prompt: 'show me all {events} for {scope} over {timeframe}. write the query, run it, and tell me what stands out',

505 slots: {

506 events: 'failed logins',

507 scope: 'the auth service',

508 timeframe: 'the past 24 hours'

509 },

510 needs: 'db',

511 src: 'cybersecurity'

512 }, {

513 id: 'analyze-a-data-file',

514 sdlc: 'operate',

515 cat: 'Data',

516 roles: ['data', 'pm', 'marketing'],

517 paste: 'csv',

518 prompt: 'read {file}, summarize the key patterns, and write the results to {output}',

519 slots: {

520 file: '@reports/q1-signups.csv',

521 output: 'an HTML page with charts, then open it in my browser'

522 },

523 nextHref: '/en/mcp',

524 src: 'teams'

525 }, {

526 id: 'generate-variations-from-performance',

527 sdlc: 'operate',

528 cat: 'Data',

529 roles: ['marketing', 'data'],

530 paste: 'csv',

531 prompt: 'read {file}, find the underperforming {items}, and generate {n} new variations that stay under {limit} characters',

532 slots: {

533 file: '@ads-performance.csv',

534 items: 'headlines',

535 n: '20',

536 limit: '90'

537 },

538 nextHref: '/en/mcp',

539 src: 'teams'

540 }, {

541 id: 'turn-a-recurring-task',

542 sdlc: 'operate',

543 cat: 'Automate',

544 roles: [],

545 prompt: 'create a /{name} skill for this project that {steps}',

546 slots: {

547 name: 'ship',

548 steps: 'runs the linter and tests, then drafts a commit message'

549 },

550 src: 'workflows'

551 }, {

552 id: 'add-a-hook-for',

553 sdlc: 'operate',

554 cat: 'Automate',

555 roles: [],

556 prompt: 'write a hook that {action} after every {event}',

557 slots: {

558 action: 'runs prettier',

559 event: 'edit to a .ts or .tsx file'

560 },

561 src: 'best-practices'

562 }, {

563 id: 'connect-a-tool-with',

564 sdlc: 'operate',

565 cat: 'Automate',

566 roles: [],

567 prompt: 'set up the {server} MCP server so you can read my {data} directly',

568 slots: {

569 server: 'Sentry',

570 data: 'error reports'

571 },

572 src: 'workflows'

573 }, {

574 id: 'capture-what-to-remember',

575 sdlc: 'operate',

576 cat: 'Automate',

577 roles: ['pm', 'docs'],

578 prompt: 'summarize what we did this session and suggest what to add to CLAUDE.md',

579 src: 'teams'

580 }], []);

581 const PROMPTS = useMemo(() => {

582 if (typeof window !== 'undefined') {

583 const rawIds = new Set(RAW.map(p => p.id));

584 RAW.forEach(p => {

585 if (!text[p.id]) console.warn('[prompt-library] no text[] entry for id:', p.id);

586 });

587 Object.keys(text).forEach(k => {

588 if (!rawIds.has(k)) console.warn('[prompt-library] orphaned text[] key:', k);

589 });

590 }

591 return RAW.map(p => ({

592 ...p,

593 title: p.id,

594 teaches: '',

595 ...text[p.id] || ({})

596 }));

597 }, [RAW, text]);

598 const L = labels;

599 const TL = k => tagLabels[k] || k;

600 const CAT_TAG = useMemo(() => ({

601 Onboard: 'understand',

602 Understand: 'understand',

603 Plan: 'plan',

604 Prototype: 'prototype',

605 Implement: 'build',

606 Test: 'test',

607 Refactor: 'refactor',

608 Review: 'review',

609 Steer: 'steer',

610 Git: 'git',

611 Release: 'release',

612 Debug: 'debug',

613 Incident: 'debug',

614 Data: 'data',

615 Automate: 'automate'

616 }), []);

617 const TAGS = useMemo(() => ['understand', 'plan', 'prototype', 'build', 'test', 'refactor', 'review', 'steer', 'debug', 'git', 'release', 'data', 'automate', 'pm', 'design', 'docs', 'marketing', 'security', 'ops'], []);

618 const tagsOf = p => [CAT_TAG[p.cat], ...p.roles || []];

619 const doc = useMemo(() => {

620 const p = typeof window !== 'undefined' ? window.location.pathname : '';

621 const base = p.startsWith('/docs/') ? '/docs' : '';

622 const m = p.slice(base.length).match(/^\/([a-z]{2}(?:-[A-Z]{2})?)\//);

623 const locale = m ? m[1] : 'en';

624 return href => {

625 if (!href || href[0] !== '/' || href[1] === '/') return href;

626 return base + (href.startsWith('/en/') ? '/' + locale + href.slice(3) : href);

627 };

628 }, []);

629 const linkify = s => {

630 const out = [];

631 let last = 0;

632 const re = /\[([^\]]+)\]\(([^)]+)\)/g;

633 for (let m; m = re.exec(s); ) {

634 if (m.index > last) out.push(s.slice(last, m.index));

635 out.push(<a key={m.index} href={doc(m[2])}>{m[1]}</a>);

636 last = re.lastIndex;

637 }

638 if (last < s.length) out.push(s.slice(last));

639 return out;

640 };

641 const codeify = s => s.split(/(`[^`]+`)/g).map((part, i) => part[0] === '`' ? <code key={i}>{part.slice(1, -1)}</code> : part);

642 const SOURCES = useMemo(() => ({

643 'workflows': '/en/common-workflows',

644 'teams': 'https://claude.com/blog/how-anthropic-teams-use-claude-code',

645 'legal': 'https://claude.com/blog/how-anthropic-uses-claude-legal',

646 'cybersecurity': 'https://claude.com/blog/how-anthropic-uses-claude-cybersecurity',

647 'best-practices': '/en/best-practices',

648 'ebook': 'https://resources.anthropic.com/hubfs/Scaling%20agentic%20coding%20across%20your%20organization.pdf'

649 }), []);

650 const [mounted, setMounted] = useState(false);

651 const [q, setQ] = useState('');

652 const [start, setStart] = useState(true);

653 const [sel, setSel] = useState(null);

654 const [openId, setOpenId] = useState(null);

655 const [copied, setCopied] = useState(null);

656 const [fills, setFills] = useState({});

657 const copyTimer = useRef(null);

658 useEffect(() => {

659 setMounted(true);

660 return () => clearTimeout(copyTimer.current);

661 }, []);

662 const setFill = (id, key, val) => setFills(f => ({

663 ...f,

664 [id + '.' + key]: val

665 }));

666 const fillOf = (p, key) => {

667 const v = fills[p.id + '.' + key];

668 return v !== undefined ? v : p.slots && p.slots[key] !== undefined ? p.slots[key] : '';

669 };

670 const assemble = p => p.prompt.replace(/\{(\w+)\}/g, (_, k) => fillOf(p, k) || p.slots && p.slots[k] || k);

671 const preview = p => p.prompt.replace(/\{(\w+)\}/g, (_, k) => p.slots && p.slots[k] || k);

672 const bodyText = p => preview(p) + ' ' + p.teaches.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') + ' ' + (p.next || '');

673 const widthFor = s => (s || '').length + 3 + 'ch';

674 const ql = q.trim().toLowerCase();

675 const toggleTag = k => {

676 setStart(false);

677 setSel(s => !ql && s === k ? null : k);

678 };

679 const clear = () => {

680 setStart(false);

681 setSel(null);

682 setQ('');

683 };

684 const results = useMemo(() => {

685 const list = PROMPTS.filter(p => {

686 if (ql) return p.title.toLowerCase().includes(ql) || bodyText(p).toLowerCase().includes(ql);

687 if (start) return !!p.startN;

688 if (sel) return tagsOf(p).includes(sel);

689 return true;

690 });

691 if (ql) return list;

692 if (start) return list.sort((a, b) => a.startN - b.startN);

693 if (sel) return list.sort((a, b) => (a.roles || []).length - (b.roles || []).length || (b.sdlc === 'operate') - (a.sdlc === 'operate'));

694 return list;

695 }, [PROMPTS, ql, start, sel]);

696 const matchSnippet = p => {

697 if (!ql || p.title.toLowerCase().includes(ql)) return null;

698 const txt = bodyText(p);

699 const at = txt.toLowerCase().indexOf(ql);

700 if (at < 0) return null;

701 const lo = Math.max(0, at - 30), hi = Math.min(txt.length, at + ql.length + 50);

702 return [lo > 0 ? '…' : '', txt.slice(lo, at), <mark key="m">{txt.slice(at, at + ql.length)}</mark>, txt.slice(at + ql.length, hi), hi < txt.length ? '…' : ''];

703 };

704 const grouped = useMemo(() => {

705 if (start && !q.trim()) return [];

706 const g = {};

707 for (const p of results) {

708 const key = p.sdlc + '|' + p.cat;

709 (g[key] = g[key] || ({

710 sdlc: p.sdlc,

711 cat: p.cat,

712 items: []

713 })).items.push(p);

714 }

715 return Object.values(g);

716 }, [results, start, q]);

717 const copy = async (str, id) => {

718 try {

719 await navigator.clipboard.writeText(str);

720 } catch {

721 const ta = document.createElement('textarea');

722 ta.value = str;

723 ta.setAttribute('readonly', '');

724 ta.style.position = 'fixed';

725 ta.style.opacity = '0';

726 document.body.appendChild(ta);

727 ta.select();

728 document.execCommand('copy');

729 document.body.removeChild(ta);

730 }

731 clearTimeout(copyTimer.current);

732 setCopied(id);

733 copyTimer.current = setTimeout(() => setCopied(null), 1600);

734 };

735 const promptBody = p => {

736 if (!p.slots) return <code>{p.prompt}</code>;

737 const parts = p.prompt.split(/(\{\w+\})/g);

738 return <code>

739 {parts.map((part, idx) => {

740 const m = part.match(/^\{(\w+)\}$/);

741 if (!m) return <span key={idx}>{part}</span>;

742 const k = m[1];

743 const val = fillOf(p, k);

744 return <input key={idx} type="text" className="pl-slot" value={val} placeholder={p.slots[k] || k} aria-label={k} style={{

745 width: widthFor(val || p.slots[k])

746 }} onChange={e => setFill(p.id, k, e.target.value)} onFocus={e => e.target.select()} onClick={e => e.stopPropagation()} />;

747 })}

748 </code>;

749 };

750 const card = p => {

751 const open = openId === p.id;

752 const srcHref = SOURCES[p.src];

753 const srcLabel = sourceLabels[p.src];

754 const snip = matchSnippet(p);

755 return <div key={p.id} className={'pl-card' + (open ? ' pl-open' : '')}>

756 <button type="button" className="pl-head" onClick={() => setOpenId(open ? null : p.id)} aria-expanded={open}>

757 <span className="pl-title">{p.title}</span>

758 {!!p.startN && <span className="pl-chip">{L.startHere} · {p.startN}</span>}

759 </button>

760 {snip ? <div className="pl-match">{snip}</div> : <code className="pl-prompt-preview">{preview(p)}</code>}

761 {open && <div className="pl-body">

762 <div className="pl-label">{p.slots ? L.fillAndCopy : L.copyThis}</div>

763 {p.needs && L.needs && L.needs[p.needs] && <div className="pl-hint pl-needs">

764 <span className="pl-needs-label">{L.needsLabel}</span> {linkify(L.needs[p.needs])}

765 </div>}

766 {p.paste && L.paste && L.paste[p.paste] && <div className="pl-hint pl-paste">{L.paste[p.paste]}</div>}

767 {p.slots && <div className="pl-hint">

768 {L.hintBefore} <span className="pl-hint-chip">{L.hintChip}</span> {L.hintAfter}

769 </div>}

770 <div className="pl-prompt-box">

771 <span className="pl-caret">{'❯'}</span>

772 {promptBody(p)}

773 <button type="button" className="pl-copy" onClick={() => copy(assemble(p), p.id)}>

774 {copied === p.id ? L.copied : L.copy}

775 </button>

776 </div>

777 <div className="pl-label">{L.whyWorks}</div>

778 <div className="pl-teaches">{linkify(p.teaches)}</div>

779 {p.nextHref && p.next && <div className="pl-next">

780 <span className="pl-next-label">{L.makeItStick}</span>

781 <a href={doc(p.nextHref)}>{codeify(p.next)} →</a>

782 </div>}

783 {srcLabel && <div className="pl-src">{L.from} {srcHref ? <a href={doc(srcHref)}>{srcLabel}</a> : srcLabel}</div>}

784 </div>}

785 </div>;

786 };

787 const STYLES = useMemo(() => `

788.pl {

789 --pl-accent: #D97757;

790 --pl-accent-bg: rgba(217,119,87,0.07);

791 --pl-bg: #fff;

792 --pl-surface: #FAFAF7;

793 --pl-border: #E8E6DC;

794 --pl-border-subtle: rgba(31,30,29,0.08);

795 --pl-text: #141413;

796 --pl-text-2: #5E5D59;

797 --pl-text-3: #73726C;

798 --pl-text-4: #9C9A92;

799 --pl-mono: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);

800 font-family: 'Anthropic Sans', -apple-system, BlinkMacSystemFont, sans-serif;

801 font-size: 16px; color: var(--pl-text); margin: 8px 0 32px;

802}

803.dark .pl {

804 --pl-bg: #1f1e1d;

805 --pl-surface: #262624;

806 --pl-border: #3d3d3a;

807 --pl-border-subtle: rgba(240,238,230,0.08);

808 --pl-text: #f0eee6;

809 --pl-text-2: #bfbdb4;

810 --pl-text-3: #91908a;

811 --pl-text-4: #73726c;

812}

813.pl *, .pl *::before, .pl *::after { box-sizing: border-box; }

814.pl button { font-family: inherit; cursor: pointer; }

815.pl a { color: var(--pl-accent); text-decoration: none; }

816.pl a:hover { text-decoration: underline; }

817 

818.pl-search {

819 display: flex; align-items: center; gap: 10px;

820 padding: 14px 18px; background: var(--pl-surface);

821 border: 1px solid var(--pl-border); border-radius: 12px;

822 margin-bottom: 14px;

823}

824.pl-search input {

825 flex: 1; border: none; outline: none; background: transparent;

826 font-size: 16px; color: var(--pl-text);

827}

828.pl-search input::placeholder { color: var(--pl-text-4); }

829 

830.pl-tags { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 18px; }

831.pl-tag {

832 padding: 7px 14px; border: 1px solid var(--pl-border); background: var(--pl-bg);

833 font-size: 14px; color: var(--pl-text-2); border-radius: 999px;

834}

835.pl-tag:hover { background: var(--pl-surface); }

836.pl-tag.pl-on { background: var(--pl-text); border-color: var(--pl-text); color: var(--pl-bg); }

837.pl-tag.pl-start { color: var(--pl-accent); font-weight: 500; }

838.pl-tag.pl-start.pl-on { background: var(--pl-accent); border-color: var(--pl-accent); color: #fff; }

839.pl-tags.pl-dim .pl-tag { opacity: 0.5; }

840.pl-tags.pl-dim .pl-tag:hover { opacity: 1; }

841.pl-sep { width: 1px; height: 22px; background: var(--pl-border); margin: 0 4px; }

842.pl-clear { border: none; background: none; font-size: 13px; color: var(--pl-text-4); padding: 4px 6px; }

843.pl-clear:hover { color: var(--pl-text-2); }

844.pl-count { margin-left: auto; font-size: 14px; color: var(--pl-text-4); }

845 

846.pl-group-h {

847 font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;

848 color: var(--pl-text-4); margin: 24px 0 12px;

849}

850.pl-group-h .pl-phase { color: var(--pl-text-3); }

851.pl-card {

852 border: 1px solid var(--pl-border-subtle); border-radius: 10px;

853 margin-bottom: 12px; background: var(--pl-bg); overflow: hidden;

854 padding: 14px 18px;

855}

856.pl-card.pl-open { border-color: var(--pl-border); background: var(--pl-surface); }

857.pl-head {

858 width: 100%; display: flex; align-items: baseline; gap: 12px;

859 border: none; background: transparent; text-align: left; padding: 0;

860}

861.pl-head:focus-visible { outline: 2px solid var(--pl-accent); outline-offset: 2px; border-radius: 6px; }

862.pl-title {

863 flex: 1; font-size: 17px; font-weight: 500; color: var(--pl-text);

864 white-space: nowrap; overflow: hidden; text-overflow: ellipsis;

865}

866.pl-prompt-preview {

867 display: block; font-family: var(--pl-mono); font-size: 13.5px; color: var(--pl-text-3);

868 margin-top: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;

869}

870.pl-chip {

871 font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase;

872 padding: 3px 9px; border-radius: 999px; flex-shrink: 0;

873 background: var(--pl-accent-bg); color: var(--pl-accent);

874}

875 

876.pl-body { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--pl-border-subtle); }

877.pl-label {

878 font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase;

879 color: var(--pl-text-4); margin: 12px 0 8px;

880}

881.pl-prompt-box {

882 display: flex; align-items: center; gap: 10px;

883 padding: 14px 16px; background: #141413; color: #f0eee6;

884 border-radius: 8px; font-family: var(--pl-mono); font-size: 15px;

885}

886.pl-caret { color: var(--pl-accent); flex-shrink: 0; }

887.pl-prompt-box code { flex: 1; background: none; padding: 0; color: inherit; white-space: pre-wrap; line-height: 1.9; }

888.pl-slot {

889 font-family: var(--pl-mono); font-size: inherit;

890 background: rgba(217,119,87,0.15); color: #f0eee6;

891 border: none; border-bottom: 1.5px dashed var(--pl-accent);

892 border-radius: 4px 4px 0 0; padding: 2px 6px; margin: 0 1px;

893 outline: none; min-width: 6ch; max-width: 100%;

894 box-sizing: content-box; cursor: text;

895}

896.pl-slot:hover { background: rgba(217,119,87,0.22); }

897.pl-slot:focus { background: rgba(217,119,87,0.28); border-bottom-style: solid; }

898.pl-slot::placeholder { color: rgba(240,238,230,0.4); font-style: italic; }

899.pl-hint { font-size: 14px; color: var(--pl-text-3); margin: 0 0 10px; }

900.pl-paste { color: var(--pl-text-2); }

901.pl-needs { color: var(--pl-text-2); }

902.pl-needs-label {

903 display: inline-block; font-size: 10.5px; letter-spacing: 0.06em;

904 text-transform: uppercase; padding: 2px 7px; margin-right: 6px;

905 border-radius: 4px; background: var(--pl-accent-bg); color: var(--pl-accent);

906}

907.pl-hint-chip {

908 font-family: var(--pl-mono); font-size: 0.92em;

909 background: var(--pl-accent-bg); color: var(--pl-accent);

910 border-bottom: 1.5px dashed var(--pl-accent);

911 border-radius: 3px 3px 0 0; padding: 1px 5px;

912}

913.pl-copy {

914 font-size: 12.5px; padding: 6px 12px; border-radius: 6px;

915 background: var(--pl-accent); color: #fff; border: none; flex-shrink: 0;

916}

917.pl-teaches { display: block; font-size: 15.5px; color: var(--pl-text-2); margin: 4px 0 0; line-height: 1.6; }

918.pl-match {

919 display: block; font-size: 13.5px; color: var(--pl-text-3);

920 margin-top: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;

921}

922.pl-match mark { background: var(--pl-accent-bg); color: var(--pl-text); padding: 1px 2px; border-radius: 3px; }

923.pl-next {

924 display: flex; align-items: baseline; gap: 10px;

925 margin: 14px 0 0; padding: 10px 12px;

926 background: var(--pl-accent-bg); border-radius: 8px; font-size: 14.5px;

927}

928.pl-next-label {

929 font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;

930 color: var(--pl-accent); font-weight: 600; flex-shrink: 0;

931}

932.pl-src { display: block; font-size: 14px; color: var(--pl-text-4); margin: 14px 0 0; }

933 

934.pl-show-all {

935 display: block; width: 100%; padding: 14px; margin-top: 4px;

936 border: 1px dashed var(--pl-border); border-radius: 10px;

937 background: transparent; font-size: 15px; color: var(--pl-accent);

938 text-align: center;

939}

940.pl-show-all:hover { background: var(--pl-accent-bg); border-style: solid; }

941 

942.pl-empty {

943 padding: 32px; text-align: center; color: var(--pl-text-4);

944 border: 1px dashed var(--pl-border); border-radius: 10px;

945}

946`, []);

947 if (!mounted) return <div className="pl" style={{

948 minHeight: 480

949 }} />;

950 return <div className="pl">

951 <style>{STYLES}</style>

952 

953 <div className="pl-search">

954 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" style={{

955 color: 'var(--pl-text-4)'

956 }}>

957 <circle cx="11" cy="11" r="7" /><line x1="21" y1="21" x2="16.65" y2="16.65" />

958 </svg>

959 <input type="text" placeholder={L.search} value={q} onChange={e => {

960 setQ(e.target.value);

961 if (e.target.value) setStart(false);

962 }} aria-label={L.search} />

963 </div>

964 

965 <div className={'pl-tags' + (ql ? ' pl-dim' : '')}>

966 <button type="button" className={'pl-tag pl-start' + (!ql && start ? ' pl-on' : '')} onClick={() => {

967 setQ('');

968 setStart(!start);

969 if (!start) setSel(null);

970 }}>

971 ★ {L.startHere}

972 </button>

973 <span className="pl-sep" />

974 {TAGS.map(k => <button key={k} type="button" aria-pressed={!ql && sel === k} className={'pl-tag' + (!ql && sel === k ? ' pl-on' : '')} onClick={() => {

975 setQ('');

976 toggleTag(k);

977 }}>

978 {TL(k)}

979 </button>)}

980 {(start || sel || q) && <button type="button" className="pl-clear" onClick={clear}>{L.clear}</button>}

981 <span className="pl-count">{results.length} {results.length === 1 ? L.prompt : L.prompts}</span>

982 </div>

983 

984 {results.length === 0 ? <div className="pl-empty">

985 {L.noMatch} {ql ? <code>{q}</code> : null} <button type="button" className="pl-clear" onClick={clear}>{L.clear}</button>

986 </div> : !ql && start ? <div>

987 <div className="pl-group-h">{L.startHereHeader}</div>

988 {results.map(card)}

989 <button type="button" className="pl-show-all" onClick={clear}>

990 {L.showAll && L.showAll.replace('{n}', PROMPTS.length)} →

991 </button>

992 </div> : grouped.map(g => <div key={g.sdlc + '|' + g.cat}>

993 <div className="pl-group-h"><span className="pl-phase">{phaseLabels[g.sdlc] || g.sdlc}</span> · {catLabels[g.cat] || g.cat}</div>

994 {g.items.map(card)}

995 </div>)}

996 </div>;

997};

998 

999This is a library of prompts to copy into Claude Code. Use it to explore ways of working you haven't tried, or when you're not sure where to start.

1000 

1001The prompts are collected from various Anthropic guides, including [Common workflows](/en/common-workflows), [Best practices](/en/best-practices), and [How Anthropic teams use Claude Code](https://claude.com/blog/how-anthropic-teams-use-claude-code). They're starting points rather than scripts. Open **Why this works** under any prompt to see the pattern behind it so you can write your own.

1002 

1003export const labels = {

1004 startHere: "Start here",

1005 startHereHeader: "Five prompts to try first",

1006 showAll: "Show all {n} prompts",

1007 search: "Search prompts…",

1008 clear: "Clear",

1009 prompt: "prompt",

1010 prompts: "prompts",

1011 noMatch: "No prompts match",

1012 fillAndCopy: "Fill in and copy",

1013 copyThis: "Copy this prompt",

1014 hintBefore: "Type in the",

1015 hintChip: "highlighted",

1016 hintAfter: "fields to customize, then copy.",

1017 copy: "Copy",

1018 copied: "Copied",

1019 whyWorks: "Why this works",

1020 makeItStick: "Make it stick",

1021 from: "From",

1022 paste: {

1023 mockup: "Paste, drag, or @-mention your mockup image, then send this:",

1024 design: "Paste, drag, or @-mention your design image, then send this:",

1025 screenshot: "Paste, drag, or @-mention your screenshot, then send this:",

1026 plan: "Paste your plan output into the prompt first, then send this:",

1027 error: "Paste the error output into the prompt first, then send this:",

1028 csv: "Drag your file into the prompt, or replace the path below with an @-mention of your own:"

1029 },

1030 needsLabel: "Needs",

1031 needs: {

1032 tracker: "your issue tracker added as a [claude.ai connector](/en/mcp#use-mcp-servers-from-claude-ai) or [MCP server](/en/mcp).",

1033 gh: "the [gh CLI](https://cli.github.com) authenticated, or GitHub added as a [claude.ai connector](/en/mcp#use-mcp-servers-from-claude-ai).",

1034 browser: "a way for Claude to render and screenshot the result. The [Desktop app](/en/desktop#preview-your-app) has this built in. In the terminal, install the [Chrome extension](/en/chrome) or a Playwright [MCP](/en/mcp) server.",

1035 db: "your data warehouse or log store added as a [claude.ai connector](/en/mcp#use-mcp-servers-from-claude-ai) or [MCP server](/en/mcp)."

1036 }

1037};

1038 

1039export const tagLabels = {

1040 understand: "Understand",

1041 plan: "Plan",

1042 prototype: "Prototype",

1043 build: "Build",

1044 test: "Test",

1045 refactor: "Refactor",

1046 review: "Review",

1047 steer: "Steer",

1048 debug: "Debug",

1049 git: "Git",

1050 release: "Release",

1051 data: "Data",

1052 automate: "Automate",

1053 pm: "Product",

1054 design: "Design",

1055 docs: "Docs",

1056 marketing: "Marketing",

1057 security: "Security",

1058 ops: "On-call"

1059};

1060 

1061export const phaseLabels = {

1062 discover: "Discover",

1063 design: "Design",

1064 build: "Build",

1065 ship: "Ship",

1066 operate: "Operate"

1067};

1068 

1069export const sourceLabels = {

1070 workflows: "Common workflows",

1071 teams: "How Anthropic teams use Claude Code",

1072 legal: "How Anthropic uses Claude in Legal",

1073 cybersecurity: "How Anthropic uses Claude in Cybersecurity",

1074 "best-practices": "Best practices",

1075 ebook: "Scaling agentic coding guide"

1076};

1077 

1078export const catLabels = {

1079 Onboard: "Onboard",

1080 Understand: "Understand",

1081 Plan: "Plan",

1082 Prototype: "Prototype",

1083 Implement: "Implement",

1084 Test: "Test",

1085 Refactor: "Refactor",

1086 Review: "Review",

1087 Steer: "Steer",

1088 Git: "Git",

1089 Release: "Release",

1090 Debug: "Debug",

1091 Incident: "Incident",

1092 Data: "Data",

1093 Automate: "Automate"

1094};

1095 

1096export const text = {

1097 "get-oriented-in-a": {

1098 title: "Get oriented in a new repository",

1099 teaches: "Describe what you want to know, not which files to read. Claude explores the project on its own and returns a summary of how it fits together.",

1100 next: "Run `/init` to set up `CLAUDE.md` so Claude remembers this every session"

1101 },

1102 "explain-unfamiliar-code": {

1103 title: "Explain unfamiliar code",

1104 teaches: "Name the file and say what format you want the answer in. Swap the HTML page for a diagram, bullet points, or whatever fits how you learn.",

1105 next: "Set an output style so Claude always explains in your preferred format"

1106 },

1107 "find-where-something-happens": {

1108 title: "Find where something happens",

1109 teaches: "Search by behavior instead of by filename. The search works even when you don't know what the file is called or which directory it lives in."

1110 },

1111 "see-what-depends-on": {

1112 title: "Check what breaks before you delete",

1113 teaches: "Ask before you remove anything. The list of callers and downstream effects tells you whether you're looking at a one-line cleanup or a change you need to coordinate."

1114 },

1115 "trace-how-code-evolved": {

1116 title: "Trace how code evolved",

1117 teaches: "Point at commit history when the question is why, not what. Claude reads the log and blame for whatever version control you use and explains the decisions behind the current implementation."

1118 },

1119 "scope-a-change-before": {

1120 title: "Scope a change before you start",

1121 teaches: "Size the work before you commit it to a roadmap. The file list tells you whether you're looking at one component or a cross-cutting change."

1122 },

1123 "ask-the-codebase-a": {

1124 title: "Ask the codebase a product question",

1125 teaches: "State your role so the answer is pitched at the right level. Claude explains what the product actually does from the source code, without you needing to read it.",

1126 next: "Set an output style so Claude always pitches answers at this level"

1127 },

1128 "plan-a-multi-file": {

1129 title: "Plan a multi-file change before touching code",

1130 teaches: "Adding \"don't edit yet\" separates exploration from changes, so you see the approach before any code moves. To make plan-first the default on every prompt, press Shift+Tab for [plan mode](/en/permission-modes#analyze-before-you-edit-with-plan-mode)."

1131 },

1132 "draft-a-spec-by": {

1133 title: "Draft a spec by interview",

1134 teaches: "Ask to be interviewed instead of writing the spec yourself. Claude asks you structured questions until the requirements are complete, then writes the result to a file.",

1135 next: "Save your interview questions as a `/spec` skill so every spec starts the same way"

1136 },

1137 "turn-a-meeting-into": {

1138 title: "Turn a meeting into tickets",

1139 teaches: "Skip the transcription step. Claude pulls action items from the unstructured input and writes them straight into your tracker via [MCP](/en/mcp), so you review the tickets, not the transcript.",

1140 next: "Save this as a `/tickets` skill"

1141 },

1142 "map-edge-cases-before": {

1143 title: "Map edge cases before building",

1144 teaches: "Ask for what's missing, not what's there. Claude lists the error states, empty states, and edge cases a happy-path design tends to skip."

1145 },

1146 "turn-a-mockup-into": {

1147 title: "Turn a mockup into a working prototype",

1148 teaches: "A clickable prototype answers questions a static mockup can't. Hand the working code to engineering instead of explaining the interactions in a doc."

1149 },

1150 "implement-from-a-screenshot": {

1151 title: "Implement from a screenshot and self-check",

1152 teaches: "This gives Claude a verification loop: it renders, compares against the source image, and iterates without you pointing out each gap.",

1153 next: "Use `/goal` to keep Claude iterating until the screenshots match"

1154 },

1155 "follow-an-existing-pattern": {

1156 title: "Follow an existing pattern",

1157 teaches: "Point at code you already like. Without a reference, Claude defaults to general best practices. With one, it matches the conventions your codebase actually uses.",

1158 next: "Ask Claude to write the pattern it followed into `CLAUDE.md` so future sessions match it without the reference"

1159 },

1160 "add-a-small-well": {

1161 title: "Add a small, well-defined feature",

1162 teaches: "State the inputs and outputs, not how to build it. Claude finds where similar code lives and adds yours alongside it."

1163 },

1164 "build-a-small-internal": {

1165 title: "Build a small internal tool from scratch",

1166 teaches: "You don't need a project, a framework, or a build step. Describe the tool and ask Claude to open it so you see it working immediately."

1167 },

1168 "work-an-issue-end": {

1169 title: "Work an issue end to end",

1170 teaches: "Give the issue number, not a summary. Claude reads the full ticket itself, so requirements you'd forget to mention come through, and it validates the change before reporting back."

1171 },

1172 "find-and-update-copy": {

1173 title: "Find and update copy across the codebase",

1174 teaches: "Ask for variants and say what to skip. Claude finds phrasings a literal search would miss and leaves test fixtures and history untouched, so you review only the copy users actually see."

1175 },

1176 "draft-from-past-examples": {

1177 title: "Draft a document from past examples",

1178 teaches: "Point at a folder of finished work instead of describing your style. Claude learns the structure and voice from what you've already shipped, so the first draft reads like one of yours.",

1179 next: "Save the voice as a skill so every draft starts there"

1180 },

1181 "write-tests-run-them": {

1182 title: "Write tests, run them, fix failures",

1183 teaches: "Ask for write, run, and fix together so Claude iterates without stopping for instructions.",

1184 next: "Run `/init` so Claude learns your test command automatically"

1185 },

1186 "drive-implementation-from-tests": {

1187 title: "Drive implementation from tests",

1188 teaches: "Test-driven development: the tests define when the work is complete, and Claude iterates on the implementation until they pass."

1189 },

1190 "fill-gaps-from-a": {

1191 title: "Fill gaps from a coverage report",

1192 teaches: "Point at the coverage report instead of guessing what's untested. Claude reads the actual numbers and writes tests for the files that need them most.",

1193 next: "Set this as a `/goal` so Claude keeps writing tests until coverage hits the target"

1194 },

1195 "port-code-between-languages": {

1196 title: "Port code to another language",

1197 teaches: "Say what to preserve, not just the target language. Naming the API or behavior that must stay the same gives Claude a contract to check the port against."

1198 },

1199 "generate-docs-for-code": {

1200 title: "Generate docs for undocumented code",

1201 teaches: "Name the scope and the format. Claude finds what's missing and matches the comment style already in the file, so the new docs read like the rest."

1202 },

1203 "migrate-a-pattern-across": {

1204 title: "Migrate a pattern across the codebase",

1205 teaches: "Describe the old pattern and the new one. Asking Claude to identify every place first means the call sites are listed in the response, so you can check none were missed."

1206 },

1207 "optimize-against-a-measurable": {

1208 title: "Optimize against a measurable target",

1209 teaches: "Stating the metric and target gives Claude a clear definition of done.",

1210 next: "Set this as a `/goal` so Claude keeps measuring and iterating until it hits the number"

1211 },

1212 "fix-a-precise-visual": {

1213 title: "Fix a precise visual bug",

1214 teaches: "Precise visual feedback gets a precise fix. State the exact element, measurement, and viewport.",

1215 next: "Add a preview tool so Claude screenshots and verifies the fix itself"

1216 },

1217 "review-your-changes-before": {

1218 title: "Review your changes before you commit",

1219 teaches: "Catch problems while they're still cheap to fix. Claude reads the changed files in full, not just the diff lines, so it spots issues a quick self-review misses.",

1220 next: "Run `/review` for the same check in one command"

1221 },

1222 "review-a-pull-request": {

1223 title: "Review a pull request",

1224 teaches: "Claude reviews with the whole codebase in context, not just the diff. It reads the changed code and what it calls, so it catches problems a diff-only review would miss.",

1225 next: "Turn this on for every PR with Code Review"

1226 },

1227 "review-infrastructure-changes-before": {

1228 title: "Review infrastructure changes before applying",

1229 teaches: "Plan output is dense and hard to scan. Pasting it gets you a plain-language summary of what's actually going to change before you apply it."

1230 },

1231 "run-a-security-review": {

1232 title: "Run a security review with a subagent",

1233 teaches: "A [subagent](/en/sub-agents) runs the audit in its own context window and reports back a summary, so a long security review doesn't fill up your main session. The built-in general-purpose subagent handles this without extra setup.",

1234 next: "Set up a dedicated security-review subagent your whole team can use"

1235 },

1236 "review-content-before-sending": {

1237 title: "Catch issues before formal review",

1238 teaches: "Get a first pass before a human spends time on it. Name the concerns you want checked so the review is focused, then fix what it finds and send a cleaner draft.",

1239 next: "Capture your review checklist as a skill your whole team can run"

1240 },

1241 "course-correct-a-wrong": {

1242 title: "Course-correct a wrong approach",

1243 teaches: "Name the constraint Claude missed, not just that it's wrong. A specific reason gives Claude a concrete constraint to satisfy on the retry, instead of guessing again.",

1244 next: "Press `Esc` twice to open the rewind menu and restore code and conversation so the retry starts clean"

1245 },

1246 "narrow-the-scope-of": {

1247 title: "Narrow the scope of a change",

1248 teaches: "When the direction is right but the change went too broad, ask Claude to keep part of it rather than rewinding everything. A stated boundary keeps a small fix from becoming a refactor."

1249 },

1250 "turn-a-correction-into": {

1251 title: "Turn a correction into a rule",

1252 teaches: "A correction in chat isn't shared with your team. A rule in the project's [CLAUDE.md](/en/memory) is shared once you commit it, and Claude reads it at the start of every session.",

1253 next: "Open `/memory` to review what Claude wrote"

1254 },

1255 "resolve-merge-conflicts": {

1256 title: "Resolve merge conflicts",

1257 teaches: "Say what state you want, not which markers to keep. Asking for the reasoning makes the merge reviewable instead of a black box."

1258 },

1259 "commit-with-a-generated": {

1260 title: "Commit with a generated message",

1261 teaches: "Let Claude derive the message from the diff. It matches your repository's existing commit style."

1262 },

1263 "open-a-pull-request": {

1264 title: "Open a pull request from a ticket",

1265 teaches: "Skip the context switch between tracker, editor, and GitHub. One prompt reads the spec, makes the change, and opens the PR."

1266 },

1267 "draft-release-notes-from": {

1268 title: "Draft release notes from git history",

1269 teaches: "Give two reference points and the structure you want. Claude reads the commit log between them and drafts a changelog you can edit.",

1270 next: "Save this as a `/changelog` skill"

1271 },

1272 "write-a-ci-workflow": {

1273 title: "Write a CI workflow",

1274 teaches: "Describe when it should run and what it should do; the YAML is generated for you, matched to your project's build and test commands."

1275 },

1276 "find-and-fix-a": {

1277 title: "Find and fix a failing test",

1278 teaches: "Describe the symptom; you don't need to know which file is broken. Claude runs the test to see the failure, traces it into source, and fixes it."

1279 },

1280 "investigate-a-reported-error": {

1281 title: "Investigate a reported error",

1282 teaches: "Describe the symptom and location; Claude reads the relevant code path and traces likely causes. Paste stack traces or logs if you have them.",

1283 next: "Put a deeplink in your runbook that opens Claude with this prompt pre-filled"

1284 },

1285 "fix-a-build-error": {

1286 title: "Fix a build error at the root",

1287 teaches: "Asking for root cause and verification prevents surface-level patches that suppress the error without fixing it."

1288 },

1289 "investigate-a-production-incident": {

1290 title: "Investigate a production incident",

1291 teaches: "List the evidence sources to correlate, not the steps to take. Claude reads logs, git history, and config together to narrow the cause.",

1292 next: "Connect Sentry or your log store via MCP"

1293 },

1294 "query-logs-in-plain": {

1295 title: "Query logs in plain English",

1296 teaches: "Ask the question instead of writing the SQL. Claude builds the query, runs it against your connected logs, and shows both the query and the result so you can check what ran."

1297 },

1298 "diagnose-from-a-console": {

1299 title: "Diagnose from a console screenshot",

1300 teaches: "Cloud consoles show you the problem but not the commands to fix it. Claude reads the screenshot and translates the dashboard into the kubectl, gcloud, or aws commands to run."

1301 },

1302 "analyze-a-data-file": {

1303 title: "Analyze a data file",

1304 teaches: "A one-off question doesn't need a one-off script. Point at a file in your project folder and Claude reads it directly, finds the patterns, and writes the output where you ask.",

1305 next: "Connect the data source via MCP instead of exporting files"

1306 },

1307 "generate-variations-from-performance": {

1308 title: "Generate variations from performance data",

1309 teaches: "State the constraint at the start so generation stays within the limit. Claude reads the metrics, picks what to replace, and produces alternatives that fit.",

1310 next: "Connect the ad platform via MCP instead of exporting a file"

1311 },

1312 "turn-a-recurring-task": {

1313 title: "Turn a recurring task into a skill",

1314 teaches: "Name the steps once; reuse them as a command. Claude writes a [skill](/en/skills) anyone on your team can run."

1315 },

1316 "add-a-hook-for": {

1317 title: "Add a hook for repeat behavior",

1318 teaches: "Hooks make a behavior automatic instead of something you have to remember to ask for. Describe the trigger and action and Claude writes the [hook](/en/hooks) configuration."

1319 },

1320 "connect-a-tool-with": {

1321 title: "Connect a tool with MCP",

1322 teaches: "Connect the source once instead of pasting data every session. After [MCP](/en/mcp) setup, Claude reads from the tool directly when you ask about it."

1323 },

1324 "capture-what-to-remember": {

1325 title: "Capture what to remember for next time",

1326 teaches: "Ask before you forget. Claude knows what it had to figure out this session and proposes [CLAUDE.md](/en/memory) entries so the next session starts with that context."

1327 }

1328};

1329 

1330<PromptLibrary text={text} labels={labels} tagLabels={tagLabels} phaseLabels={phaseLabels} sourceLabels={sourceLabels} catLabels={catLabels} />

1331 

1332## What makes these prompts work

1333 

1334The prompts above share a few patterns. Recognizing them helps you adapt any prompt here to your own task.

1335 

1336**Describe the outcome, not the steps.** Say what you want and let Claude find the files. The prompt below works without naming a single file path.

1337 

1338```text theme={null}

1339add rate limiting to the public API and make sure existing tests still pass

1340```

1341 

1342**Give it a way to check its own work.** Ask for run, test, compare, or verify in the same prompt so Claude iterates instead of stopping after one attempt.

1343 

1344```text theme={null}

1345write the migration, run it against the dev database, and confirm the schema matches

1346```

1347 

1348**Point at a reference.** Name an existing file, test, or pattern to match so the new code is consistent with what you already have.

1349 

1350```text theme={null}

1351add a settings page that follows the same layout as the profile page

1352```

1353 

1354**State the measurable target.** When the goal is performance or coverage, give the metric and threshold so completion is unambiguous.

1355 

1356```text theme={null}

1357get the bundle size under 200KB and show me what you removed

1358```

1359 

1360**Give it the artifact.** Paste errors, logs, screenshots, and plan output directly in the prompt, or type `@` to reference a file. Claude reads the source instead of your description of it.

1361 

1362```text theme={null}

1363why is the build failing? @build.log

1364```

1365 

1366**Say how you want the answer.** Name the format, length, or audience so the explanation fits how you'll use it. To make a format the default for every response, set an [output style](/en/output-styles).

1367 

1368```text theme={null}

1369explain how the payment retry logic works as an HTML page with a diagram, then open it in my browser

1370```

1371 

1372For more on each pattern, see [best practices](/en/best-practices).

1373 

1374## Where these come from

1375 

1376These prompts are based on patterns from published Anthropic resources. Each card links to its source:

1377 

1378* [Common workflows](/en/common-workflows): step-by-step guides for the core tasks

1379* [Best practices](/en/best-practices): prompting patterns and project setup

1380* [How Anthropic teams use Claude Code](https://claude.com/blog/how-anthropic-teams-use-claude-code): real workflows from engineering, product, design, and data teams, with deep dives on [legal](https://claude.com/blog/how-anthropic-uses-claude-legal), [marketing](https://claude.com/blog/how-anthropic-uses-claude-marketing), and [cybersecurity](https://claude.com/blog/how-anthropic-uses-claude-cybersecurity)

1381* [Scaling agentic coding guide](https://resources.anthropic.com/hubfs/Scaling%20agentic%20coding%20across%20your%20organization.pdf): the enterprise adoption guide

1382 

1383For video walkthroughs of these patterns, see the free [Claude Code in Action](https://anthropic.skilljar.com/claude-code-in-action) course on Anthropic Academy.

1384 

1385## Related resources

1386 

1387The prompts on this page are starting points. Once one works for your project, the next step is making it repeatable: save it as a [skill](/en/skills) so anyone on your team can run it as a `/command`, and record the conventions Claude learned in [CLAUDE.md](/en/memory) so every session starts with that context instead of Claude relearning it. For larger or riskier changes, [plan mode](/en/permission-modes#analyze-before-you-edit-with-plan-mode) shows you the file list before any edits happen.

1388 

1389If you're introducing Claude Code across a team, see [administration](/en/admin-setup) for managed settings and policy, and [costs and usage](/en/costs) for how this work is billed on your plan.

Details

93A bare `/loop` runs this prompt at a [dynamically chosen interval](#let-claude-choose-the-interval). Add an interval, for example `/loop 15m`, to run it on a fixed schedule instead. To replace the built-in prompt with your own default, see [Customize the default prompt with loop.md](#customize-the-default-prompt-with-loop-md).93A bare `/loop` runs this prompt at a [dynamically chosen interval](#let-claude-choose-the-interval). Add an interval, for example `/loop 15m`, to run it on a fixed schedule instead. To replace the built-in prompt with your own default, see [Customize the default prompt with loop.md](#customize-the-default-prompt-with-loop-md).

94 94 

95<Note>95<Note>

96 On Bedrock, Vertex AI, and Microsoft Foundry, `/loop` with no prompt prints the usage message instead of starting the maintenance loop.96 The built-in maintenance prompt isn't available to everyone yet, and isn't supported on Bedrock, Vertex AI, or Microsoft Foundry. Where it isn't active, `/loop` with no prompt prints the usage message instead.

97</Note>97</Note>

98 98 

99### Customize the default prompt with loop.md99### Customize the default prompt with loop.md


118 118 

119Edits to `loop.md` take effect on the next iteration, so you can refine the instructions while a loop is running. When no `loop.md` exists in either location, the loop falls back to the built-in maintenance prompt. Keep the file concise: content beyond 25,000 bytes is truncated.119Edits to `loop.md` take effect on the next iteration, so you can refine the instructions while a loop is running. When no `loop.md` exists in either location, the loop falls back to the built-in maintenance prompt. Keep the file concise: content beyond 25,000 bytes is truncated.

120 120 

121<Note>

122 `loop.md` follows the same availability as the [built-in maintenance prompt](#run-the-built-in-maintenance-prompt). Where the maintenance prompt isn't active, `/loop` with no prompt prints the usage message and the file isn't read.

123</Note>

124 

121### Stop a loop125### Stop a loop

122 126 

123To stop a `/loop` while it is waiting for the next iteration, press `Esc`. This clears the pending wakeup so the loop does not fire again. Tasks you scheduled by [asking Claude directly](#manage-scheduled-tasks) are not affected by `Esc` and stay in place until you delete them.127To stop a `/loop` while it is waiting for the next iteration, press `Esc`. This clears the pending wakeup so the loop does not fire again. Tasks you scheduled by [asking Claude directly](#manage-scheduled-tasks) are not affected by `Esc` and stay in place until you delete them.

en/settings.md +28 −0

Details

247| `sshConfigs` | SSH connections to show in the [Desktop](/en/desktop#pre-configure-ssh-connections-for-your-team) environment dropdown. Each entry requires `id`, `name`, and `sshHost`; `sshPort`, `sshIdentityFile`, and `startDirectory` are optional. When set in managed settings, connections are read-only for users. Read from managed and user settings only | `[{"id": "dev-vm", "name": "Dev VM", "sshHost": "user@dev.example.com"}]` |247| `sshConfigs` | SSH connections to show in the [Desktop](/en/desktop#pre-configure-ssh-connections-for-your-team) environment dropdown. Each entry requires `id`, `name`, and `sshHost`; `sshPort`, `sshIdentityFile`, and `startDirectory` are optional. When set in managed settings, connections are read-only for users. Read from managed and user settings only | `[{"id": "dev-vm", "name": "Dev VM", "sshHost": "user@dev.example.com"}]` |

248| `statusLine` | Configure a custom status line to display context. See [`statusLine` documentation](/en/statusline) | `{"type": "command", "command": "~/.claude/statusline.sh"}` |248| `statusLine` | Configure a custom status line to display context. See [`statusLine` documentation](/en/statusline) | `{"type": "command", "command": "~/.claude/statusline.sh"}` |

249| `strictKnownMarketplaces` | (Managed settings only) Allowlist of plugin marketplace sources. Undefined = no restrictions, empty array = lockdown. Enforced on marketplace add and on plugin install, update, refresh, and auto-update, so a marketplace added before the policy was set cannot be used to fetch plugins. See [Managed marketplace restrictions](/en/plugin-marketplaces#managed-marketplace-restrictions) | `[{ "source": "github", "repo": "acme-corp/plugins" }]` |249| `strictKnownMarketplaces` | (Managed settings only) Allowlist of plugin marketplace sources. Undefined = no restrictions, empty array = lockdown. Enforced on marketplace add and on plugin install, update, refresh, and auto-update, so a marketplace added before the policy was set cannot be used to fetch plugins. See [Managed marketplace restrictions](/en/plugin-marketplaces#managed-marketplace-restrictions) | `[{ "source": "github", "repo": "acme-corp/plugins" }]` |

250| `strictPluginOnlyCustomization` | (Managed settings only) Block skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings. `true` locks all four surfaces; an array locks only the named ones. See [`strictPluginOnlyCustomization`](#strictpluginonlycustomization) | `["skills", "hooks"]` |

250| `syntaxHighlightingDisabled` | Disable syntax highlighting in diffs, code blocks, and file previews | `true` |251| `syntaxHighlightingDisabled` | Disable syntax highlighting in diffs, code blocks, and file previews | `true` |

251| `teammateMode` | How [agent team](/en/agent-teams) teammates display: `auto` (picks split panes in tmux or iTerm2, in-process otherwise), `in-process`, or `tmux`. `--teammate-mode` overrides this for one session. See [choose a display mode](/en/agent-teams#choose-a-display-mode) | `"in-process"` |252| `teammateMode` | How [agent team](/en/agent-teams) teammates display: `auto` (picks split panes in tmux or iTerm2, in-process otherwise), `in-process`, or `tmux`. `--teammate-mode` overrides this for one session. See [choose a display mode](/en/agent-teams#choose-a-display-mode) | `"in-process"` |

252| `terminalProgressBarEnabled` | Show the terminal progress bar in supported terminals: ConEmu, Ghostty 1.2.0+, and iTerm2 3.6.6+. Default: `true`. Appears in `/config` as **Terminal progress bar** | `false` |253| `terminalProgressBarEnabled` | Show the terminal progress bar in supported terminals: ConEmu, Ghostty 1.2.0+, and iTerm2 3.6.6+. Default: `true`. Appears in `/config` as **Terminal progress bar** | `false` |


963 964 

964See [Managed marketplace restrictions](/en/plugin-marketplaces#managed-marketplace-restrictions) for user-facing documentation.965See [Managed marketplace restrictions](/en/plugin-marketplaces#managed-marketplace-restrictions) for user-facing documentation.

965 966 

967#### `strictPluginOnlyCustomization`

968 

969**Managed settings only**: blocks skills, agents, hooks, and MCP servers from user and project sources, so they can only come from plugins or managed settings. Combine it with `strictKnownMarketplaces` to control the full customization supply chain: the marketplace allowlist controls which plugins users can install, and this setting blocks everything that doesn't come from a plugin or from managed settings.

970 

971<Note>

972 `strictPluginOnlyCustomization` requires Claude Code v2.1.82 or later. Earlier versions ignore the key and keep loading user and project customizations, so the lockdown isn't enforced until clients update.

973</Note>

974 

975The value is either `true` to lock all four surfaces, or an array naming the surfaces to lock:

976 

977```json theme={null}

978{

979 "strictPluginOnlyCustomization": ["skills", "hooks"]

980}

981```

982 

983For each locked surface, Claude Code skips user-level and project-level sources and loads only plugin-provided and managed sources:

984 

985| Surface | Blocked when locked | Still loads |

986| :------- | :------------------------------------------------ | :---------------------------------------------------------------------------------- |

987| `skills` | `~/.claude/skills/`, `.claude/skills/` | Plugin skills, bundled skills, skills in the managed policy directory |

988| `agents` | `~/.claude/agents/`, `.claude/agents/` | Plugin agents, built-in agents, agents in the managed policy directory |

989| `hooks` | Hooks in user, project, and local `settings.json` | Plugin hooks, hooks in managed settings |

990| `mcp` | Servers in `~/.claude.json` and `.mcp.json` | Plugin MCP servers, [`managed-mcp.json`](/en/mcp#managed-mcp-configuration) servers |

991 

992Surface names that a Claude Code version doesn't recognize are ignored rather than failing the settings file, so you can add new surface names before all clients have updated.

993 

966### Managing plugins994### Managing plugins

967 995 

968Use the `/plugin` command to manage plugins interactively:996Use the `/plugin` command to manage plugins interactively:

Details

11To add custom tools, connect an [MCP server](/en/mcp). To extend Claude with reusable prompt-based workflows, write a [skill](/en/skills), which runs through the existing `Skill` tool rather than adding a new tool entry.11To add custom tools, connect an [MCP server](/en/mcp). To extend Claude with reusable prompt-based workflows, write a [skill](/en/skills), which runs through the existing `Skill` tool rather than adding a new tool entry.

12 12 

13| Tool | Description | Permission Required |13| Tool | Description | Permission Required |

14| :--------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------ |14| :--------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------ |

15| `Agent` | Spawns a [subagent](/en/sub-agents) with its own context window to handle a task. See [Agent tool behavior](#agent-tool-behavior) | No |15| `Agent` | Spawns a [subagent](/en/sub-agents) with its own context window to handle a task. See [Agent tool behavior](#agent-tool-behavior) | No |

16| `AskUserQuestion` | Asks multiple-choice questions to gather requirements or clarify ambiguity | No |16| `AskUserQuestion` | Asks multiple-choice questions to gather requirements or clarify ambiguity | No |

17| `Bash` | Executes shell commands in your environment. See [Bash tool behavior](#bash-tool-behavior) | Yes |17| `Bash` | Executes shell commands in your environment. See [Bash tool behavior](#bash-tool-behavior) | Yes |


34| `Read` | Reads the contents of files. See [Read tool behavior](#read-tool-behavior) | No |34| `Read` | Reads the contents of files. See [Read tool behavior](#read-tool-behavior) | No |

35| `ReadMcpResourceTool` | Reads a specific MCP resource by URI | No |35| `ReadMcpResourceTool` | Reads a specific MCP resource by URI | No |

36| `RemoteTrigger` | Creates, updates, runs, and lists [Routines](/en/routines) on claude.ai. Backs the `/schedule` command. {/* plan-availability: feature=routines plans=pro,max,team,enterprise providers=anthropic */}Routines live on claude.ai and require a Pro, Max, Team, or Enterprise plan, so this tool is not accessible from Amazon Bedrock, Google Vertex AI, or Microsoft Foundry | No |36| `RemoteTrigger` | Creates, updates, runs, and lists [Routines](/en/routines) on claude.ai. Backs the `/schedule` command. {/* plan-availability: feature=routines plans=pro,max,team,enterprise providers=anthropic */}Routines live on claude.ai and require a Pro, Max, Team, or Enterprise plan, so this tool is not accessible from Amazon Bedrock, Google Vertex AI, or Microsoft Foundry | No |

37| `ScheduleWakeup` | Reschedules the next iteration of a [self-paced `/loop`](/en/scheduled-tasks#let-claude-choose-the-interval). Claude calls this at the end of each iteration to pick when the next one runs, between one minute and one hour out; you don't call it directly. The pending wakeup appears in `session_crons` in [Stop hook input](/en/hooks#stop-input). {/* plan-availability: feature=loop-dynamic providers=anthropic */}Not available on Amazon Bedrock, Google Vertex AI, or Microsoft Foundry, where a `/loop` prompt with no interval runs on a fixed schedule instead | No |

37| `SendMessage` | Sends a message to an [agent team](/en/agent-teams) teammate, or [resumes a subagent](/en/sub-agents#resume-subagents) by its agent ID. Stopped subagents auto-resume in the background. Only available when `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set | No |38| `SendMessage` | Sends a message to an [agent team](/en/agent-teams) teammate, or [resumes a subagent](/en/sub-agents#resume-subagents) by its agent ID. Stopped subagents auto-resume in the background. Only available when `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set | No |

38| `ShareOnboardingGuide` | {/* plan-availability: feature=onboarding-guide-share plans=pro,max,team,enterprise providers=anthropic */}Uploads `ONBOARDING.md` and returns a share link teammates can open in Claude Code. Called from `/team-onboarding` after the guide is written. Available to claude.ai subscribers on Pro, Max, Team, and Enterprise plans | Yes |39| `ShareOnboardingGuide` | {/* plan-availability: feature=onboarding-guide-share plans=pro,max,team,enterprise providers=anthropic */}Uploads `ONBOARDING.md` and returns a share link teammates can open in Claude Code. Called from `/team-onboarding` after the guide is written. Available to claude.ai subscribers on Pro, Max, Team, and Enterprise plans | Yes |

39| `Skill` | Executes a [skill](/en/skills#control-who-invokes-a-skill) within the main conversation | Yes |40| `Skill` | Executes a [skill](/en/skills#control-who-invokes-a-skill) within the main conversation | Yes |