# Claude Code core components inventory (everything except tools and slash commands)

> Source: `claude-code/src`. For each item: what it is (a beginner metaphor) → source implementation (`file:line`) → a concrete example.

---

## 1. Plugins

### What it is
A plugin is a "capability pack" — like a VS Code extension. One directory can hold slash commands, skills (`SKILL.md`), subagent definitions, hooks (hook scripts), and MCP server config, all installed in one shot. The problem it solves: a single `.claude/commands/xxx.md` file is too scattered; you cannot conveniently share and version a whole workflow.

### Source implementation
- **Plugin directory convention**: `plugin.json` manifest + `commands/` + `agents/` + `hooks/hooks.json`, see `utils/plugins/pluginLoader.ts:16-28` (file-header comments) and `createPluginFromPath()` (`pluginLoader.ts:1357`); `pluginLoader.ts:1392-1398` probes in parallel whether the four optional directories `commands/`, `agents/`, `skills/`, `output-styles/` exist.
- **Built-in plugins**: shipped with the CLI, toggleable in the `/plugin` UI, registered in `plugins/builtinPlugins.ts:21-32` (`registerBuiltinPlugin`), IDs of the form `{name}@builtin` (`builtinPlugins.ts:23,38`). Difference from marketplace plugins: no filesystem path (`path: 'builtin'` sentinel, `builtinPlugins.ts:85`); the user's on/off state is persisted to settings `enabledPlugins` (`builtinPlugins.ts:71-76`).
- **Marketplace mechanism**: a marketplace is essentially a git repo (or URL/NPM) containing a `marketplace.json` catalog. The official marketplace is the GitHub repo `anthropics/claude-plugins-official` (`utils/plugins/officialMarketplace.ts:13-27`). Adding a marketplace goes through `addMarketplaceSource()` (`utils/plugins/marketplaceManager.ts:1782`); cloning uses a partial clone + sparse checkout to save bandwidth (`marketplaceManager.ts:803 gitClone`, `1034 reconcileSparseCheckout`). Installed plugins are landed by `installPluginFromMarketplace()` (`utils/plugins/pluginInstallationHelpers.ts:506`); the load entry point is `loadAllPlugins()` (`pluginLoader.ts:3096`).
- **Priority vs built-in features**: commands from all sources are merged in `commands.ts:447-470 loadAllCommands`, in order bundledSkills → builtinPluginSkills → directory skills → workflow → pluginCommands → pluginSkills → hard-coded built-in commands (`COMMANDS()`). Lookup uses `findCommand()` (`commands.ts:688`); the first match in array order wins, so a same-named user/plugin skill ranks ahead of a hard-coded built-in command.
- **UI**: the `/plugin` command's UI lives in `commands/plugin/` (`ManagePlugins.tsx`, `BrowseMarketplace.tsx`, `AddMarketplace.tsx`, etc.).

### Example
After `/plugin marketplace add anthropics/claude-plugins-official`, `gitClone` sparse-clones the repo into `~/.claude/plugins/marketplaces/`, then `/plugin install feature-dev@claude-plugins-official`; on next startup `createPluginFromPath` finds its `commands/`, `agents/`, `hooks/hooks.json`, and those commands appear in the `/` list, source-tagged as plugin.

---

## 2. Skills

### What it is
A skill is a "spec sheet you pull on demand." Metaphor: stuffing every tool's full manual into the drawer (the system prompt) is too heavy, so Claude Code only pastes a one-page "table of contents" on the drawer (skill name + one-sentence description); when the model decides it needs a particular manual, it pulls the whole book out via the Skill tool.

### Source implementation
- **Directory format**: under `/skills/` only the `skill-name/SKILL.md` directory layout is recognized; a lone `.md` file is not treated as a skill (`skills/loadSkillsDir.ts:424-428`). Load locations have four layers: enterprise-managed, user-level `~/.claude/skills`, project-level `.claude/skills` (including `--add-dir`), and the legacy `/commands/` directory (`loadSkillsDir.ts:638-714`).
- **Full set of `SKILL.md` frontmatter fields** (parse entry `parseSkillFrontmatterFields`, `loadSkillsDir.ts:185-265`):
  - `name` (display name, `:238`), `description` (`:208-214`, default extracted from the body), `when_to_use` (`:252`, tells the model which scenes to invoke)
  - `allowed-tools` (`:242`, whitelist of tools available while the skill runs)
  - `argument-hint`, `arguments` (`:245-251`, argument hint and named arguments)
  - `version` (`:253`), `model` (`:221-226`, may be `inherit` or a specific model)
  - `effort` (`:228-235`, can specify thinking effort)
  - `disable-model-invocation` (`:255`, humans only), `user-invocable` (`:216-219`, `false` hides it from the `/` menu)
  - `hooks` (`:259`, skill-level hooks; Zod validation in `parseHooksFromFrontmatter` `:136-153`)
  - `context: fork` (`:260`, run in a forked sub-context), `agent` (`:261`)
  - `shell` (`:263`, which interpreter embedded shell commands use)
  - `paths` (`parseSkillPaths` `:159-178`, gitignore-style path filter — **conditional skills**, activated only when a matching-path file is read/written; activation logic starts at `activateConditionalSkillsForPaths` `:997`)
- **Progressive disclosure**:
  - Stage one — inject only the listing: `utils/attachments.ts:2661 getSkillListingAttachments` packs every skill's name/description/whenToUse into one `skill_listing` attachment (`attachments.ts:2744-2749`), trimmed to a token budget (`formatCommandsWithinBudget` `:2744`), and sent once per agent with incremental top-ups (`:2698-2732`).
  - Stage two — load the full text only on invoke: the model calls the Skill tool (`tools/SkillTool/SkillTool.ts:580 call`) → runs that Command's `getPromptForCommand` (`loadSkillsDir.ts:344-399`), and only then concatenates `Base directory for this skill: ...` + the full body, does argument substitution (`substituteArguments` `:349`), replaces `${CLAUDE_SKILL_DIR}`/`${CLAUDE_SESSION_ID}` (`:356-369`), and even executes markdown-embedded `` !`...` `` shell commands (`:375`). **Safety detail**: skills from MCP are "remote untrusted content" and never execute embedded shell (`:372-374`).
- **Dynamic discovery**: while a session reads/writes files, nested `.claude/skills` are discovered by walking up from the file path (`discoverSkillDirsForPaths` `:861-915`), skipping gitignored directories (`:892-897`); a skill in a deeper directory overrides a same-named shallower one (`:944-951`).
- **Built-in bundled skills**: compiled into the binary, registered in code (`skills/bundledSkills.ts:53 registerBundledSkill`), directory `skills/bundled/`: `batch`, `claudeApi`, `claudeInChrome`, `debug`, `keybindings`, `loop`, `loremIpsum`, `remember`, `scheduleRemoteAgents`, `simplify`, `skillify`, `stuck`, `updateConfig`, `verify`. Skills with attachments (`files` field, `bundledSkills.ts:29-36`) unpack reference files to disk only on first invoke (`extractBundledSkillFiles` `:131-145`), with `O_NOFOLLOW|O_EXCL` against symlink attacks (`:176-193`).
- **MCP skills**: MCP servers can also provide skills; they reuse the same parse logic via the registry in `skills/mcpSkillBuilders.ts` (to avoid a cyclic dependency).

### Example
`~/.claude/skills/pdf/SKILL.md` says `description: PDF 表格提取` + `allowed-tools: Read, Bash`. At startup the model only sees one line "pdf — PDF 表格提取"; when the user says "pull the table on page 3 of report.pdf," the model calls the Skill tool, and only then does Claude read the full `SKILL.md` and learn that `scripts/extract.py` exists, then runs the script with Bash.

---

## 3. MCP (Model Context Protocol)

### What it is
MCP is "USB-C for AI": any external service (a database, Figma, an internal company system) that implements a server per the MCP protocol can be plugged into Claude Code, and its tools, resources, and prompt templates become immediately usable.

### Source implementation
- **Client**: `services/mcp/client.ts` (3348 lines), based on the official `@modelcontextprotocol/sdk` `Client` (`client.ts:7`). Supported transports (schema in `services/mcp/types.ts:28-131`):
  - `stdio` — local subprocess (`client.ts:950 new StdioClientTransport`)
  - `sse` — HTTP long-poll push (`client.ts:673,702 SSEClientTransport`)
  - `http` — Streamable HTTP (`client.ts:861,900 StreamableHTTPClientTransport`)
  - `ws`/`ws-ide` — WebSocket (`client.ts:734,783`)
  - `sdk` — in-process SDK transport (`client.ts:3278 SdkControlClientTransport`), plus special types `sse-ide`, `claudeai-proxy`, etc.
- **Config and approval**: servers can be registered in `.mcp.json` at the project root (enterprises also have `managed-mcp.json`, `services/mcp/config.ts:64-66`). Because project-level config may come from an untrusted repo, startup pops an approval dialog for every pending server: `handleMcpjsonServerApprovals()` (`services/mcpServerApproval.tsx:13-40`; a single server uses `MCPServerApprovalDialog`, several use `MCPServerMultiselectDialog`). The state machine is `getProjectMcpServerStatus()` (`services/mcp/utils.ts:351`): settings `enabledMcpjsonServers`/`disabledMcpjsonServers` record the user's choice; `enableAllProjectMcpServers` can approve all (`utils.ts:371`); `--dangerously-skip-permissions` and non-interactive mode auto-approve, with a strict anti-RCE comment (`utils.ts:383-400`). Load time only admits approved servers (`config.ts:1164-1168`).
- **Tools into the conversation**: `fetchToolsForClient()` (`client.ts:1742`) calls `tools/list`, then wraps them as `MCPTool` (`tools/MCPTool/MCPTool.ts`), names them `mcp__serverName__toolName` (`buildMcpToolName`, `client.ts:1767`). Permission rules support server-level wildcards: `mcp__server1` or `mcp__server1__*` (`utils/permissions/permissions.ts:236-259`).
- **Resources and prompts**: `ListMcpResourcesTool`, `ReadMcpResourceTool`, `McpAuthTool` (imported at `client.ts:53-56`) let the model browse/read MCP resources; MCP prompts are turned into Commands (`client.ts:2038-2077`, names likewise `mcp__server__prompt` format `:2058`).
- **Connection management**: React context `MCPConnectionManager` (`services/mcp/MCPConnectionManager.tsx`) + `useManageMCPConnections` handle reconnect and on/off; the `/mcp` command provides a management UI. Server states are `connected/failed/needs-auth/pending/disabled` (`types.ts:183-248`); `needs-auth` goes through MCP OAuth login.

### Example
Project `.mcp.json` says `{"mcpServers": {"github": {"type": "stdio", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"]}}}`. A colleague who just cloned the repo, first opening Claude Code, gets a "do you trust the github server?" approval dialog; after approval the tool list gains `mcp__github__create_issue`, and the permissions page can allow the whole server with one rule `mcp__github`.

---

## 4. API and authentication

### What it is
Claude Code supports four "ways to pay": a Claude subscription account (OAuth login), an API key billed by usage, and enterprise cloud-vendor channels (AWS Bedrock / Google Vertex / Azure Foundry). Like one SIM that can ride a contract plan, a prepaid card, or a company leased line.

### Source implementation
- **Provider detection**: `utils/model/providers.ts:6-13 getAPIProvider` — looks at env `CLAUDE_CODE_USE_BEDROCK`/`CLAUDE_CODE_USE_VERTEX`/`CLAUDE_CODE_USE_FOUNDRY`; if none are set, it is `firstParty`.
- **OAuth login flow** (standard authorization code + PKCE): `services/oauth/index.ts:14-120 OAuthService` — generate `code_verifier`/`challenge` (`:29,57-58`), start a local localhost listener `AuthCodeListener` (`:49-50`, `auth-code-listener.ts`), construct two URLs: the automatic flow (open a browser that jumps back to localhost) and the manual flow (copy-paste the code, `:71-72`); once the code is in hand, `exchangeCodeForTokens` swaps it for a token (`:103-109`). Persistence after login is in `cli/handlers/auth.ts:44 installOAuthTokens`. The scope system is in `constants/oauth.ts` (`user:inference`, `user:profile`, `org:create_api_key`).
- **Credential storage**: on macOS the OAuth token lives in the Keychain (`utils/secureStorage/index.ts:9-17`: `macOsKeychainStorage`, falling back to `plainTextStorage` on failure; other platforms currently use a plaintext file). API-key source priority is in `utils/auth.ts`: `apiKeyHelper` (an executable configured in settings, `auth.ts:123`), `ANTHROPIC_API_KEY`/`ANTHROPIC_AUTH_TOKEN` env (`:126,134`), `--settings` injection, keychain.
- **Token refresh**: `checkAndRefreshOAuthTokenIfNeeded()` (`utils/auth.ts:1427-1560`) — on finding an expired `accessToken`, first clear the cache and re-read (another process may already have refreshed), then take a file lock (`lockfile.lock` `:1500`) to keep multiple processes from refreshing at once, retry up to 5 times (`:1453`); a subscriber refresh omits scopes so the server can expand them (`:1544-1550`). On 401/"token revoked", the retry layer forces a refresh (`services/api/withRetry.ts:246-252`).
- **Billing / attribution header**: the first block of every request's system prompt is `x-anthropic-billing-header: cc_version=...; cc_entrypoint=...; cch=...; cc_workload=...` (generated in `constants/system.ts:86-95`). `splitSysPromptPrefix()` (`utils/api.ts:321-376`) lifts it out of the system prompt and marks `cacheScope: null` (does not participate in the prompt cache); remaining static blocks use `global`/`org` cache scopes — so changing entrypoint does not break the cache.

### Example
The user runs `/login` → `OAuthService` opens the browser for authorization → the browser jumps back to `http://localhost:PORT/callback?code=...` → the CLI swaps for a token and stores it in the macOS Keychain. An hour later the token expires; `checkAndRefreshOAuthTokenIfNeeded` takes the file lock and silently renews; the user notices nothing.

---

## 5. effort / thinking

### What it is
A "thinking budget" — before answering, the model can draft (thinking), and the draft length is tunable. `effort` is the new-generation unified knob (`low`/`medium`/`high`/`max`); thinking budget is the old-style exact token count; the Claude 4.6 family supports "adaptive" (the model decides how long to think).

### Source implementation
- **effort grades**: `utils/effort.ts:14-20` defines `low/medium/high/max` (also allows a number, used internally). Which models support it is decided by `modelSupportsEffort()` (`effort.ts:26-50`, currently an opus-4-6/sonnet-4-6 allowlist); the `max` grade is Opus 4.6 only (`effort.ts:55-69`); unsupported models auto-drop to `high` (the clamp in `resolveAppliedEffort` `:152-168`).
- **Priority chain**: `resolveAppliedEffort()` (`effort.ts:152-168`): env `CLAUDE_CODE_EFFORT_LEVEL` → session state (what the user set with `/effort` or `/model`, `appState.effortValue`) → the model's default. On persist, numeric grades and an external user's `max` are not written to settings (`toPersistableEffort` `:101-112`). The `/effort` command is implemented in `commands/effort/effort.tsx:16-20`.
- **Sent to the API**: `services/api/claude.ts:437-465 configureEffort` — a string grade goes directly into `outputConfig.effort` (`:453-455`); a numeric grade takes the internal `effort_override` (`:458-463`, ant-only). The final apply point is `claude.ts:1458 resolveAppliedEffort` → `:1483`.
- **thinking config**: type `ThinkingConfig = adaptive | enabled(budgetTokens) | disabled` (`utils/thinking.ts:10-13`). `modelSupportsThinking()` (`:90-110`) splits by provider: on firstParty and Foundry every Claude 4+ supports it; Bedrock/Vertex only recognize sonnet-4/opus-4. On by default; `MAX_THINKING_TOKENS=0` or settings `alwaysThinkingEnabled: false` can turn it off (`shouldEnableThinkingByDefault` `:146-162`).
- **Request construction**: `services/api/claude.ts:1596-1630` — models that support adaptive (the 4.6 family, `modelSupportsAdaptiveThinking` `thinking.ts:113-144`) send `{type: 'adaptive'}` with no budget; older models send `{type: 'enabled', budget_tokens: N}`, budget = `min(maxOutputTokens-1, thinkingConfig.budgetTokens ?? model default)` (`:1617-1627`).
- **interleaved thinking**: injected as a beta header (`utils/betas.ts:95 'interleaved_thinking'`), letting the model think between tool calls; Foundry supports it on all models (`betas.ts:102`).
- **Easter egg**: the keyword `ultrathink` in user input triggers a highlight and a higher thinking grade (`thinking.ts:29-31 hasUltrathinkKeyword`, rainbow render `:60-86`), double-gated by feature flag `ULTRATHINK` + GrowthBook `tengu_turtle_carbon` (`:19-24`).

### Example
The user `/effort high` (persisted to settings); the next request's API body has `output_config: {effort: 'high'}`; if it is Opus 4.6, the thinking field is `{type: 'adaptive'}`, and the model decides thinking length itself; the status bar shows the current grade in sync (`getDisplayedEffortLevel` `effort.ts:170-178`).

---

## 6. Model selection and fallback

### What it is
A "lead actor and understudy" mechanism: normally use the primary model (`mainLoopModel`); when Anthropic's servers are overloaded (HTTP 529), automatically swap in the backup (`fallbackModel`) so the conversation does not break.

### Source implementation
- **Primary-model resolution priority** (`utils/model/model.ts:84-101 getMainLoopModel`):
  1. what `/model` changed in-session (`getMainLoopModelOverride`, `bootstrap/state.ts:838`)
  2. startup flag `--model`
  3. env `ANTHROPIC_MODEL`
  4. `model` in settings
  5. built-in default (Opus 4.6; third-party channels default Sonnet 4.5 because listing lags, the `@[MODEL LAUNCH]` comment in `model.ts:103-133`)
- **fallback specification**: CLI flag `--fallback-model <model>` (`main.tsx:1000`, help text notes "only works with --print"), parsed at `main.tsx:2020`, passed into the query loop `main.tsx:2846 → query.ts:258`. The fallback model is not allowed to be the same as the primary (`main.tsx:1337` validation).
- **Trigger**: in the retry layer `services/api/withRetry.ts` — consecutive 529 (server overload) are counted; at `MAX_529_RETRIES = 3` (`:54`) and with a configured `fallbackModel`, a special `FallbackTriggeredError` is thrown (`:163-165`, `:337-352`). Note: by default this only fires for "non-subscribers on non-custom Opus"; env `FALLBACK_FOR_ALL_PRIMARY_MODELS` can open it up (`:330-336`). Background tasks (summaries, title generation) on 529 are dropped rather than retried with backoff (`:319-327`).
- **Switch execution**: `query.ts:894-910` — after catching `FallbackTriggeredError`, replace `currentModel` with `fallbackModel`, clear this turn's half-built assistant message (and fill in tool results of 'Model fallback triggered'), then resend the whole request.
- **Small-model division of labor**: there is also `getSmallFastModel()` (`services/api/claude.ts:339-340`); conversation-topic detection, command descriptions, and other chores use a Haiku-class small model, separated from the main-loop model.

### Example
The user runs `claude -p --model opus --fallback-model sonnet "重构这个模块"`. At peak, Opus returns 529 three times in a row; the retry layer throws `FallbackTriggeredError`; the query loop silently switches to Sonnet and continues; the user only sees a model-switch notice in the transcript.

---

## 7. Permission modes

### What it is
A permission mode is "how long a leash the AI gets": from "ask me every step" to "fully off-leash," several grades, cycled with Shift+Tab.

### Source implementation
- **Semantics and UI config of each mode** (`utils/permissions/PermissionMode.ts:42-91`):
  - `default` — ask via dialog on every dangerous operation
  - `plan` (Plan Mode) — research and propose only; must not touch files / run commands; at the end, use the ExitPlanMode tool to hand the plan to the user for approval (write operations intercepted from `utils/permissions/filesystem.ts:1446`)
  - `acceptEdits` — file edits are auto-accepted (`filesystem.ts:1366`: edits inside the working directory are let through), everything else still asks
  - `bypassPermissions` — skip all asking (dangerous; needs `--dangerously-skip-permissions` or a UI confirmation to enable)
  - `dontAsk` — not exposed in the UI cycle (`getNextPermissionMode.ts:70-72`)
  - `auto` — internal (ant-only) mode; a transcript classifier judges in real time whether each operation is safe (feature flag `TRANSCRIPT_CLASSIFIER`, `PermissionMode.ts:80-90`); entering the cycle requires the `isAutoModeAvailable` gate (`getNextPermissionMode.ts:17-29`)
- **Shift+Tab cycle**: keybinding defined in `keybindings/defaultBindings.ts:30-36` (`MODE_CYCLE_KEY`; on Windows without VT mode, falls back to `meta+m`). Cycle order is in `utils/permissions/getNextPermissionMode.ts:34-79`: `default → acceptEdits → plan → bypassPermissions (if available) → default`. On switch, `cyclePermissionMode()` (`:88-101`) calls `transitionPermissionMode` to clean context (e.g. strip dangerous permissions when entering auto).
- **Mode banner**: the status bar changes color by mode (`PermissionMode.ts:26-30` color map: plan blue, accept cyan, bypass red).

### Example
You want Claude to research a bug but fear it will thrash the code: Shift+Tab to `plan`; Claude reads code, writes a plan, and finally pops "approve the plan?" via ExitPlanMode; after approval it auto-switches to `acceptEdits` and lands the edits (`filesystem.ts:1450` mode suggestion).

---

## 8. Output styles

### What it is
An output style is "a personality mask for Claude" — it rewrites the opening of the system prompt so the same model answers in a different style (e.g. didactic vs. minimal).

### Source implementation
- **Built-in styles**: `constants/outputStyles.ts:42-100` — `default` (value null, no extra seasoning), `Explanatory` (explain every implementation choice, with a `★ Insight` block template), `Learning` (deliberately leave 2–10 lines as a small task for the human to write, the `TODO(human)` mechanism).
- **Custom styles**: drop a markdown file into `~/.claude/output-styles/*.md` or the project's `.claude/output-styles/*.md`; frontmatter supports `name`, `description`, `keep-coding-instructions` (`outputStyles/loadOutputStylesDir.ts:41-62`); plugins can also provide them via an `output-styles/` directory (`loadOutputStylesDir.ts:11`).
- **Injection**: the selected style is concatenated as a `# Output Style: {name}\n{prompt}` paragraph into the system prompt (`constants/prompts.ts:152-157`), and the thesis sentence becomes "according to your Output Style below" (`prompts.ts:180`). `keep-coding-instructions: true` means keep the original coding instructions and only overlay style.
- **Switching**: `/output-style` command (`commands/output-style/`); a plugin can force a style with `force-for-plugin` (`outputStyles.ts:14-21`).

### Example
A beginner user `/output-style Learning`; when Claude writes 30 lines of code it deliberately leaves the core function, sends a "Learn by Doing" card asking you to fill in the `TODO(human)` part, and waits until you are ready before continuing.

---

## 9. Memory system and quick memory

### What it is
Four "brains": long-term memory across sessions (MEMORY.md auto-memory), project covenant (the CLAUDE.md family), notes for the current session (Session Memory), and the manually managed `/memory` editor.

### Source implementation
- **Auto memory / memdir**: `memdir/memdir.ts` — one memory directory per project (default `~/.claude/projects/<project-path>/memory/`, `memdir/paths.ts`); entry file `MEMORY.md` (`memdir.ts:35`) hard-capped at 200 lines / 25KB, truncated with a warning when over (`memdir.ts:37-40, 59-95 truncateEntrypointContent`). Claude autonomously writes user preferences and project habits into markdown files under that directory; at startup they are retrieved by relevance and injected (`memdir/findRelevantMemories.ts`); injected entries carry a "freshness" prefix (`tools/FileReadTool/FileReadTool.ts:749 memoryFileFreshnessPrefix`). When the user corrects Claude, the tail of the denial message appends a hint to "consider storing this in memory" (`utils/messages.ts:177-191`).
- **Session Memory**: `services/SessionMemory/sessionMemory.ts:1-7` — a background fork of a sub-agent periodically distills the current conversation into markdown notes, without interrupting the main dialogue; used to restore context after auto-compact. Compact integration is in `services/compact/sessionMemoryCompact.ts`.
- **CLAUDE.md system**: `utils/claudemd.ts getMemoryFiles` collects project/user/nested CLAUDE.md and `.claude/rules`; a subdirectory's CLAUDE.md is injected on demand when a file in it is read (`utils/attachments.ts:1710 memoryFilesToAttachments` + `nestedMemoryAttachmentTriggers` for dedup, `FileReadTool.ts:848,870`).
- **`/memory` command**: `commands/memory/memory.tsx` — pops `MemoryFileSelector` (`components/memory/MemoryFileSelector.tsx:44`) to pick a user/project/nested memory file, then opens it with `$EDITOR`/`$VISUAL` (`memory.tsx:72`, `editFileInEditor`).
- **About the `#` quick-memory shortcut**: this source snapshot **does not** have a `#`-prefix input mode — `components/PromptInput/inputModes.ts:31-33` only recognizes `!` (bash mode), and the `PromptInputMode` type (`types/textInputTypes.ts:265-269`) only has bash/prompt etc. The early-version `#` quick-append memory has, in this snapshot, evolved into the `/memory` command + auto-memory system (note the version difference when writing primers).

### Example
You say offhand "our team writes commits in Chinese"; Claude writes that into `~/.claude/projects/xxx/memory/team-conventions.md` and updates the `MEMORY.md` index; next week's new session, that preference shows up automatically in the system prompt with the relevant memories.

---

## 10. Other mechanisms worth a primer

### Vim mode (`src/vim/`)
The input box supports Vim keybindings (NORMAL/INSERT mode switch, motion, operator, text object). Implementation is split into pure-function modules: `vim/motions.ts`, `vim/operators.ts`, `vim/textObjects.ts`, `vim/transitions.ts`; state types live in `types/textInputTypes.ts:255-260 VimInputState`.

### Voice input (`src/voice/` + `src/services/voiceStreamSTT.ts`)
Push-to-talk: `voiceStreamSTT.ts:1-36` connects to Anthropic's `/api/ws/speech_to_text/voice_stream` WebSocket for streaming transcription. Gate: `voice/voiceModeEnabled.ts:18-24` GrowthBook kill switch + `:31-40 hasVoiceAuth` — **must have an OAuth token** (it uses the claude.ai endpoint; API key / Bedrock / Vertex are unavailable).

### Remote and Bridge (`src/remote/`, `src/bridge/`)
- `bridge/bridgeMain.ts`: make this machine the "executor" for the claude.ai web/App — poll the cloud for session tasks, run them locally, post results back (`createSessionSpawner`, `getRemoteSessionUrl`, `createBridgeApiClient`); supports worktree isolation (`:22` import).
- `remote/SessionsWebSocket.ts` + `RemoteSessionManager.ts`: bridge a local REPL session to the web for real-time control (bidirectional WebSocket; `remotePermissionBridge.ts` syncs permission dialogs to the web for confirmation).

### Cost tracking (`src/cost-tracker.ts`)
Each API response's usage is run through `calculateUSDCost()` (`utils/modelCost.js`, per the model price list) and accumulated into counters in `bootstrap/state` (`cost-tracker.ts:3-27` imports a string of `getTotalCostUSD`/`getTotalInputTokens` etc.); the `/cost` command displays them, and `lastCost` is persisted to project config (`:146`) for cross-session totals.

### Telemetry / Analytics (`src/services/analytics/`)
Event instrumentation uniformly goes through `logEvent()`, event names of the form `tengu_*` (e.g. `tengu_api_opus_fallback_triggered`, `tengu_oauth_token_refresh_starting`); backends include Statsig (feature flags), GrowthBook (experiment assignment, `growthbook.ts`), Datadog (`datadog.ts`), first-party event reporting (`firstPartyEventLogger.ts`); sensitive fields are forced through a type tag (`AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS`).

### Keybinding system (`src/keybindings/`)
A declarative keybinding system: default table `keybindings/defaultBindings.ts:37+` (chunked by context `Global`/`Chat` etc.; values are action strings like `app:interrupt`, `history:search`); users can override in `keybindings.json` (`loadUserBindings.ts`); parse and match live in `parser.ts`/`match.ts`; the React side subscribes with the `useKeybinding` hook. `ctrl+c`/`ctrl+d` are reserved and cannot be rebound.

### UDS message service (inject messages from outside)
`setup.ts:86-101`: at startup, create a Unix Domain Socket under `$TMPDIR` (`--messaging-socket-path` can specify); an external process can write messages into the socket to inject them into the conversation (on by default for ant, feature `UDS_INBOX`, implementation dynamically imported from `utils/udsMessaging.js`); the path is passed to child processes via `$CLAUDE_CODE_MESSAGING_SOCKET`, and the bind must finish before the SessionStart hook (comments `:91-94`). `--bare` mode skips it.

### `--worktree` isolation
`entrypoints/cli.tsx:247-261`: `-w/--worktree` runs the session inside a git worktree (`.claude/worktrees/<slug>`), so changes do not touch the main workspace; the slug has path-traversal protection (comment `utils/worktree.ts:52-55`); with `--tmux` there is also a fast exec path.

### SDK / Headless mode
- `cli/print.ts` (5594 lines): entry for `claude -p "..."` non-interactive mode, no React tree (comment `:517`); supports `--output-format json/stream-json`, a headless profiler (`:314-317`), headless plugin install (`:331`).
- `QueryEngine.ts`: abstracts "one query" into a reusable engine (shared by SDK and CLI): assemble tools/systemPrompt/toolUseContext (`:370`, `:518`), drive `query.ts`'s async-generator loop, produce an `SDKMessage` stream (SDK consumers) or text (print mode).
- Also supports `--bare` (slim startup: skip skill discovery, UDS, telemetry init, etc., `loadSkillsDir.ts:654-675`, `setup.ts:86-88`).
