Reference Layer
Appendices
Cross-cutting data structures, contracts, and reference notes that the larger chapters rely on.
Command Data Structures And Result Types
Reference the command objects and result shapes used throughout the commands subtree.
Why this matters
This appendix explains the recurring command pieces in plain English before later chapters rely on them.
The command kinds and helper types
The chapter on command contracts names the moving parts. This appendix gives those names a short meaning so the later pages do not have to stop and define them again.
The result and helper types
The pieces that local commands and prompt commands pass around.
export type LocalCommandResult =
| { type: 'text'; value: string }
| {
type: 'compact'
compactionResult: CompactionResult
displayText?: string
}
| { type: 'skip' } // Skip messages
export type PromptCommand = {
type: 'prompt'
progressMessage: string
contentLength: number // Length of command content in characters (used for token estimation)
argNames?: string[]
allowedTools?: string[]
model?: string
source: SettingSource | 'builtin' | 'mcp' | 'plugin' | 'bundled'
pluginInfo?: {
pluginManifest: PluginManifest
repository: string
}
disableNonInteractive?: boolean
// Hooks to register when this skill is invoked
hooks?: HooksSettings
// Base directory for skill resources (used to set CLAUDE_PLUGIN_ROOT environment variable for skill hooks)
skillRoot?: string
// Execution context: 'inline' (default) or 'fork' (run as sub-agent)
// 'inline' = skill content expands into the current conversation
// 'fork' = skill runs in a sub-agent with separate context and token budget
context?: 'inline' | 'fork'
// Agent type to use when forked (e.g., 'Bash', 'general-purpose')
// Only applicable when context is 'fork'
agent?: string
effort?: EffortValue
// Glob patterns for file paths this skill applies to
// When set, the skill is only visible after the model touches matching files
paths?: string[]
getPromptForCommand(
args: string,
context: ToolUseContext,
): Promise<ContentBlockParam[]>
}
/**
* The call signature for a local command implementation.
*/
export type LocalCommandCall = (
args: string,
context: LocalJSXCommandContext,
) => Promise<LocalCommandResult>
/**
* Module shape returned by load() for lazy-loaded local commands.
*/
export type LocalCommandModule = {
call: LocalCommandCall
}
type LocalCommand = {
type: 'local'
supportsNonInteractive: boolean
load: () => Promise<LocalCommandModule>
}
export type LocalJSXCommandContext = ToolUseContext & {
canUseTool?: CanUseToolFn
setMessages: (updater: (prev: Message[]) => Message[]) => void
options: {
dynamicMcpConfig?: Record<string, ScopedMcpServerConfig>
ideInstallationStatus: IDEExtensionInstallationStatus | null
theme: ThemeName
}
onChangeAPIKey: () => void
onChangeDynamicMcpConfig?: (
config: Record<string, ScopedMcpServerConfig>,
) => void
onInstallIDEExtension?: (ide: IdeType) => void
resume?: (
sessionId: UUID,
log: LogOption,
entrypoint: ResumeEntrypoint,
) => Promise<void>
}
export type ResumeEntrypoint =
| 'cli_flag'
| 'slash_command_picker'
| 'slash_command_session_id'
| 'slash_command_title'
| 'fork'
export type CommandResultDisplay = 'skip' | 'system' | 'user'
/**
* Callback when a command completes.
* @param result - Optional user-visible message to display
* @param options - Optional configuration for command completion
* @param options.display - How to display the result: 'skip' | 'system' | 'user' (default)
* @param options.shouldQuery - If true, send messages to the model after command completes
* @param options.metaMessages - Additional messages to insert as isMeta (model-visible but hidden)
*/
export type LocalJSXCommandOnDone = (
result?: string,
options?: {
display?: CommandResultDisplay
shouldQuery?: boolean
metaMessages?: string[]
nextInput?: string
submitNextInput?: boolean
},
) => void
/**
* The call signature for a local JSX command implementation.
*/
export type LocalJSXCommandCall = (
onDone: LocalJSXCommandOnDone,
context: ToolUseContext & LocalJSXCommandContext,
args: string,
) => Promise<React.ReactNode>
/**
* Module shape returned by load() for lazy-loaded commands.
*/
export type LocalJSXCommandModule = {
call: LocalJSXCommandCall
}
type LocalJSXCommand = {
type: 'local-jsx'
/**
* Lazy-load the command implementation.
* Returns a module with a call() function.
* This defers loading heavy dependencies until the command is invoked.
*/
load: () => Promise<LocalJSXCommandModule>
} LocalCommandResult is the small union that tells the runtime whether a local command produced text, a compaction result, or a skip. PromptCommand is the shape that carries a prompt-writing command. LocalJSXCommandContext is the extra context passed to JSX-backed commands. LocalJSXCommandOnDone is the callback they use to finish and hand control back.
CommandBase
CommandBase is the shared metadata shell around all three command kinds. The fields are the same ones the registry and autocomplete code keep checking.
CommandBase
The shared metadata shell wrapped around every command kind.
export type CommandBase = {
availability?: CommandAvailability[]
description: string
hasUserSpecifiedDescription?: boolean
/** Defaults to true. Only set when the command has conditional enablement (feature flags, env checks, etc). */
isEnabled?: () => boolean
/** Defaults to false. Only set when the command should be hidden from typeahead/help. */
isHidden?: boolean
name: string
aliases?: string[]
isMcp?: boolean
argumentHint?: string // Hint text for command arguments (displayed in gray after command)
whenToUse?: string // From the "Skill" spec. Detailed usage scenarios for when to use this command
version?: string // Version of the command/skill
disableModelInvocation?: boolean // Whether to disable this command from being invoked by models
userInvocable?: boolean // Whether users can invoke this skill by typing /skill-name
loadedFrom?:
| 'commands_DEPRECATED'
| 'skills'
| 'plugin'
| 'managed'
| 'bundled'
| 'mcp' // Where the command was loaded from
kind?: 'workflow' // Distinguishes workflow-backed commands (badged in autocomplete)
immediate?: boolean // If true, command executes immediately without waiting for a stop point (bypasses queue)
isSensitive?: boolean // If true, args are redacted from the conversation history
/** Defaults to `name`. Only override when the displayed name differs (e.g. plugin prefix stripping). */
userFacingName?: () => string
} The shared fields mostly answer simple questions:
- Is this command visible here?
- Should the UI show it?
- What label and hint should people see?
- Does it need to run immediately?
| Field | Meaning | First Pass |
|---|---|---|
availability | Limits the command to specific auth or provider environments. | Very important |
isEnabled | Lets the code turn a command on or off right now without changing the command definition. | Very important |
isHidden | Hides a command from typeahead and help when it should not be discoverable. | Very important |
argumentHint | Shows a short gray hint next to the command name so people know what arguments to type. | Very important |
immediate | Marks commands that should run right away instead of waiting in the normal queue. | Important on first read |
The appendix keeps these names together because later chapters refer to them in different combinations. Once the field list feels familiar, the command registry and execution chapters read much faster.
Kind-specific fields
These fields belong to specific command kinds, not to CommandBase.
| Field | Meaning | First Pass |
|---|---|---|
supportsNonInteractive | Tells the runtime whether a local command can still work when there is no live interactive UI. | Important on first read |
allowedTools | Lists which tools a prompt command is allowed to use while it runs. | Important on first read |
source | Shows where a prompt command came from, such as built-in code, a plugin, or a bundled skill. | Important on first read |
Prompt And Memory Data Structures
Reference the main prompt and memory shapes before diving into the deeper context chapters.
Why this matters
This appendix collects the small but important types that appear across the context subtree. If a later chapter names one of these objects, come back here to see the shape in one place before you read the longer explanation.
SystemPrompt
SystemPrompt
The branded array of prompt strings that the runtime passes along as the final system prompt.
export type SystemPrompt = readonly string[] & {
readonly __brand: 'SystemPrompt'
} MemoryType and MemoryFileInfo
MemoryType
The memory layer tag attached to each discovered memory file.
export const MEMORY_TYPE_VALUES = [
'User',
'Project',
'Local',
'Managed',
'AutoMem',
...(feature('TEAMMEM') ? (['TeamMem'] as const) : []),
] as const
export type MemoryType = (typeof MEMORY_TYPE_VALUES)[number] MemoryFileInfo
The file record Claude Code carries through discovery, filtering, and prompt assembly.
export type MemoryFileInfo = {
path: string
type: MemoryType
content: string
parent?: string // Path of the file that included this one
globs?: string[] // Glob patterns for file paths this rule applies to
contentDiffersFromDisk?: boolean
rawContent?: string
} Context object keys
The recurring context keys
These are the plain-object fields students keep seeing as the context subtree moves from snapshots to prompt assembly.
| Field | Meaning | First Pass |
|---|---|---|
gitStatus | A frozen snapshot of the repo state, branch, and recent commits. | Read this as the repo snapshot for the conversation. |
cacheBreaker | A debug-only field used to force a cached context rebuild. | Usually safe to ignore unless you are studying cache invalidation. |
claudeMd | The combined instruction text loaded from memory files, including managed, user, project, local, additional-dir, and feature-gated AutoMem or TeamMem entries when present. | This is the memory text that becomes user-visible prompt content. |
currentDate | The current date rendered as a short natural-language sentence. | This is the simplest example of a user-context field. |
Takeaways
- SystemPrompt is a branded readonly string array, not a loose string.
- MemoryType and MemoryFileInfo explain how memory files are labeled before they are rendered into prompt text.
- The same four context keys keep reappearing because they are the shared inputs to later prompt assembly steps.
Tool And Permission Data Structures
Reference the shared tool and permission types that later tools chapters reuse.
Why this matters
The next chapters reuse the same shapes again and again. This appendix puts those shapes in one place first, so later pages can talk about behavior without re-explaining the data model every time.
The rule maps behind permission decisions
ToolPermissionRulesBySource
The grouped rule maps that later become `alwaysAllowRules`, `alwaysDenyRules`, and `alwaysAskRules`.
export type ToolPermissionRulesBySource = {
[T in PermissionRuleSource]?: string[]
}export type AdditionalWorkingDirectory = {
path: string
source: WorkingDirectorySource
} Claude Code stores rules by source instead of flattening them immediately. That makes it possible to remember whether a rule came from user settings, project settings, a CLI flag, or the current session.
ToolPermissionContext
ToolPermissionContext
The session-wide permission state consulted before and during tool calls.
export type ToolPermissionContext = {
readonly mode: PermissionMode
readonly additionalWorkingDirectories: ReadonlyMap<
string,
AdditionalWorkingDirectory
>
readonly alwaysAllowRules: ToolPermissionRulesBySource
readonly alwaysDenyRules: ToolPermissionRulesBySource
readonly alwaysAskRules: ToolPermissionRulesBySource
readonly isBypassPermissionsModeAvailable: boolean
readonly strippedDangerousRules?: ToolPermissionRulesBySource
readonly shouldAvoidPermissionPrompts?: boolean
readonly awaitAutomatedChecksBeforeDialog?: boolean
readonly prePlanMode?: PermissionMode
} types/permissions.ts exports the lean, types-only version shown above.
Tool.ts defines the runtime-facing variant as DeepImmutable<{ ... }> so the
permission context is treated as immutable while tools are running. The two
types mostly line up, but they are not identical: Tool.ts adds
isAutoModeAvailable?: boolean on top of the types-only version, and its
runtime shape uses Map<string, AdditionalWorkingDirectory> inside that
DeepImmutable wrapper instead of spelling the field as a ReadonlyMap.
| Field | Meaning | First Pass |
|---|---|---|
mode | The active permission mode, such as `default`, `dontAsk`, or `plan`. | Very important |
additionalWorkingDirectories | Extra directories that are treated as in-bounds for filesystem permissions. | Very important |
alwaysAllowRules | Rule groups that silently allow matching tool calls. | Very important |
alwaysDenyRules | Rule groups that block matching tool calls before execution. | Very important |
alwaysAskRules | Rule groups that force a prompt even when a call might otherwise proceed automatically. | Very important |
shouldAvoidPermissionPrompts | A flag used for contexts that cannot show interactive approval UI. | Helpful after the basics |
prePlanMode | The permission mode captured before model-initiated plan mode so it can be restored later. | Safe to skim at first |
PermissionResult
PermissionResult
The union returned by permission code when it decides what should happen next.
export type PermissionAllowDecision<
Input extends { [key: string]: unknown } = { [key: string]: unknown },
> = {
behavior: 'allow'
updatedInput?: Input
userModified?: boolean
decisionReason?: PermissionDecisionReason
toolUseID?: string
acceptFeedback?: string
contentBlocks?: ContentBlockParam[]
}export type PermissionAskDecision<
Input extends { [key: string]: unknown } = { [key: string]: unknown },
> = {
behavior: 'ask'
message: string
updatedInput?: Input
decisionReason?: PermissionDecisionReason
suggestions?: PermissionUpdate[]
blockedPath?: string
metadata?: PermissionMetadata
isBashSecurityCheckForMisparsing?: boolean
pendingClassifierCheck?: PendingClassifierCheck
contentBlocks?: ContentBlockParam[]
}export type PermissionDenyDecision = {
behavior: 'deny'
message: string
decisionReason: PermissionDecisionReason
toolUseID?: string
}
export type PermissionResult<
Input extends { [key: string]: unknown } = { [key: string]: unknown },
> =
| PermissionDecision<Input>
| {
behavior: 'passthrough'
message: string
decisionReason?: PermissionDecision<Input>['decisionReason']
suggestions?: PermissionUpdate[]
blockedPath?: string
pendingClassifierCheck?: PendingClassifierCheck
} The beginner version is a three-way branch:
behavior: 'allow'means the tool may continuebehavior: 'ask'means Claude Code needs a human decisionbehavior: 'deny'means the tool is blocked immediately
The fourth case, behavior: 'passthrough', means “this layer is not making the
final decision yet; keep checking.”
| Field | Meaning | First Pass |
|---|---|---|
updatedInput | A rewritten input payload that later code should use instead of the original tool arguments. | Very important |
message | The human-readable reason shown when Claude Code needs to explain an ask, deny, or passthrough outcome. | Very important |
decisionReason | Structured metadata describing why the decision happened. | Helpful after the basics |
suggestions | Possible permission updates that UI code can offer to the user. | Helpful after the basics |
pendingClassifierCheck | A deferred classifier task that may auto-approve an ask before the user answers. | Safe to skim at first |
ToolUseContext.options
ToolUseContext.options
The nested runtime bundle that tells one tool call what environment it is running inside.
options: {
commands: Command[]
debug: boolean
mainLoopModel: string
tools: Tools
verbose: boolean
thinkingConfig: ThinkingConfig
mcpClients: MCPServerConnection[]
mcpResources: Record<string, ServerResource[]>
isNonInteractiveSession: boolean
agentDefinitions: AgentDefinitionsResult
maxBudgetUsd?: number
customSystemPrompt?: string
appendSystemPrompt?: string
querySource?: QuerySource
refreshTools?: () => Tools
} This object answers practical questions a tool may need right away: which tools exist, which model is running, whether UI is interactive, and whether the tool pool can be refreshed after MCP state changes.
| Field | Meaning | First Pass |
|---|---|---|
tools | The assembled tool pool available for this turn. | Very important |
commands | The command set available to the session alongside tools. | Helpful after the basics |
mainLoopModel | The model name driving the current main loop. | Helpful after the basics |
mcpClients | Connected MCP clients that can add tools and resources. | Helpful after the basics |
isNonInteractiveSession | Whether this run can show interactive permission UI. | Very important |
refreshTools | Optional callback that rebuilds the tool list when the environment changes mid-query. | Helpful after the basics |
Remote And Bridge Data Structures
Reference the connection and bridge shapes shared by the remote-control chapters.
What lives here
This appendix keeps the shared remote and bridge shapes in one place. The next bridge chapters reuse these names constantly, so the goal here is simple: explain the fields once, in plain English, before the behavior pages start depending on them.
Remote session shapes
RemoteSessionConfig tells the manager which remote session to join.
RemoteSessionCallbacks tells it which local hooks to call when remote events
arrive.
RemoteSessionConfig
The connection settings the manager needs before it can join a remote session.
export type RemoteSessionConfig = {
sessionId: string
getAccessToken: () => string
orgUuid: string
/** True if session was created with an initial prompt that's being processed */
hasInitialPrompt?: boolean
/**
* When true, this client is a pure viewer. Ctrl+C/Escape do NOT send
* interrupt to the remote agent; 60s reconnect timeout is disabled;
* session title is never updated. Used by `claude assistant`.
*/
viewerOnly?: boolean
}| Field | Meaning | First Pass |
|---|---|---|
sessionId | The remote CCR session to subscribe to over the network. | This is the remote session key the manager is built around. |
orgUuid | The organization that owns the remote session. | This is the org boundary the connection must stay inside. |
viewerOnly | Marks a pure viewer client that should not send interrupt behavior or update the session title. | This is the watch-only switch. |
hasInitialPrompt | Signals that the session started from an initial prompt and is still processing it. | Useful when the session is booting from a prompt. |
getAccessToken | Supplies a fresh access token each time the websocket connects. | This is the token hook the manager calls before it opens the socket. |
RemoteSessionCallbacks
The hooks the manager uses to hand remote events back to the local UI.
export type RemoteSessionCallbacks = {
/** Called when an SDKMessage is received from the session */
onMessage: (message: SDKMessage) => void
/** Called when a permission request is received from CCR */
onPermissionRequest: (
request: SDKControlPermissionRequest,
requestId: string,
) => void
/** Called when the server cancels a pending permission request */
onPermissionCancelled?: (
requestId: string,
toolUseId: string | undefined,
) => void
/** Called when connection is established */
onConnected?: () => void
/** Called when connection is lost and cannot be restored */
onDisconnected?: () => void
/** Called on transient WS drop while reconnect backoff is in progress */
onReconnecting?: () => void
/** Called on error */
onError?: (error: Error) => void
}
| Field | Meaning | First Pass |
|---|---|---|
onMessage | Receives ordinary SDK messages from the remote session. | This is the main message stream hook. |
onPermissionRequest | Receives the permission prompt that CCR wants the local UI to answer. | This is the callback that starts the permission roundtrip. |
onPermissionCancelled | Runs when CCR cancels a permission request before the local side answers. | Use this to clear any pending prompt state. |
onConnected | Runs when the websocket comes up cleanly. | Helpful for status updates. |
onDisconnected | Runs when the connection is definitively lost. | This is the shutdown path callback. |
onReconnecting | Runs when the client is trying to recover from a transient drop. | This is the temporary-loss callback. |
onError | Receives connection or transport errors. | Use this for logging and user-visible errors. |
Bridge-side shapes
BridgeConfig is the registration bundle that creates or reconnects a bridge
environment. WorkSecret is the server-issued payload that carries the ingress
token and the selector used for CCR v2 work.
BridgeConfig
The bridge-registration shape used when the local bridge starts or reconnects.
export type BridgeConfig = {
dir: string
machineName: string
branch: string
gitRepoUrl: string | null
maxSessions: number
spawnMode: SpawnMode
verbose: boolean
sandbox: boolean
/** Client-generated UUID identifying this bridge instance. */
bridgeId: string
/**
* Sent as metadata.worker_type so web clients can filter by origin.
* Backend treats this as opaque — any string, not just BridgeWorkerType.
*/
workerType: string
/** Client-generated UUID for idempotent environment registration. */
environmentId: string
/**
* Backend-issued environment_id to reuse on re-register. When set, the
* backend treats registration as a reconnect to the existing environment
* instead of creating a new one. Used by `claude remote-control
* --session-id` resume. Must be a backend-format ID — client UUIDs are
* rejected with 400.
*/
reuseEnvironmentId?: string
/** API base URL the bridge is connected to (used for polling). */
apiBaseUrl: string
/** Session ingress base URL for WebSocket connections (may differ from apiBaseUrl locally). */
sessionIngressUrl: string
/** Debug file path passed via --debug-file. */
debugFile?: string
/** Per-session timeout in milliseconds. Sessions exceeding this are killed. */
sessionTimeoutMs?: number
}| Field | Meaning | First Pass |
|---|---|---|
bridgeId | The client-generated ID for this bridge instance. | This is the bridge identity the server sees during registration. |
environmentId | The client-generated environment ID used for idempotent registration and reconnects. | This is the environment identity the rest of the bridge reuses. |
workerType | The metadata.worker_type value sent during registration. | This is the worker label the server can use for filtering. |
reuseEnvironmentId | A backend-issued environment ID the bridge can reuse instead of creating a new environment. | Use this when resuming an existing remote-control session. |
apiBaseUrl | The API base URL used for bridge polling. | This is the polling endpoint base. |
sessionIngressUrl | The session ingress base URL used for websocket connections. | This is the network path the bridge uses to reach sessions. |
WorkSecret
The server-issued secret payload that carries session ingress credentials and the CCR v2 toggle.
export type WorkSecret = {
version: number
session_ingress_token: string
api_base_url: string
sources: Array<{
type: string
git_info?: { type: string; repo: string; ref?: string; token?: string }
}>
auth: Array<{ type: string; token: string }>
claude_code_args?: Record<string, string> | null
mcp_config?: unknown | null
environment_variables?: Record<string, string> | null
/**
* Server-driven CCR v2 selector. Set by prepare_work_secret() when the
* session was created via the v2 compat layer (ccr_v2_compat_enabled).
* Same field the BYOC runner reads at environment-runner/sessionExecutor.ts.
*/
use_code_sessions?: boolean
}| Field | Meaning | First Pass |
|---|---|---|
session_ingress_token | The ingress token the bridge uses for session and API calls. | This is the secret token the bridge must send back to the server. |
use_code_sessions | The selector that tells the bridge whether to use CCR v2 code sessions. | This is the server-driven switch for the newer transport path. |
api_base_url | The API base URL embedded in the secret. | This keeps the bridge pointed at the right server. |
sources | The source list the server attaches to the work secret. | Useful when the bridge needs to inspect where work came from. |
auth | The auth token list carried with the secret. | This is the server-side auth bundle for the work item. |
The bridge status labels are the small set ready, connected,
reconnecting, and failed. Keep those in mind when later bridge chapters talk
about whether the environment is waiting, live, recovering, or broken.
Startup State And Session Identifiers
Reference the startup state fields and stable session identifiers used during boot.
What lives here
This appendix keeps the boot-time state in one place. The startup chapters use these names repeatedly, so it helps to see the shape once before following the rest of the flow.
The startup state bundle
State is the in-memory object that carries startup identity and workspace
identity through the boot sequence.
State
The boot-time bundle that holds the original cwd, the current cwd, the stable project root, and the session lineage.
type State = {
originalCwd: string
// Stable project root - set once at startup (including by --worktree flag),
// never updated by mid-session EnterWorktreeTool.
// Use for project identity (history, skills, sessions) not file operations.
projectRoot: string
cwd: string
sessionId: SessionId
// Parent session ID for tracking session lineage (e.g., plan mode -> implementation)
parentSessionId: SessionId | undefined
}| Field | Meaning | First Pass |
|---|---|---|
originalCwd | The boot-time home path the session uses for storage and lookup. It begins as the launch directory, but worktree setup can rewrite it. | Read this as the path boot started from, unless setup deliberately resets it for a worktree session. |
projectRoot | The stable project identity root used for history, skills, and sessions. | This is the project anchor the rest of startup keeps returning to. |
cwd | The current working directory the session is using right now. | This can move if setup switches into a worktree. |
sessionId | The unique ID for the current session. | Use this when you want to trace one run end to end. |
parentSessionId | The session that spawned this one, if there is one. | This is the lineage link for flows like plan mode to implementation. |
How to read it
originalCwd and cwd usually start as the same path, but worktree setup can
rewrite originalCwd so the session treats the new worktree as home. projectRoot
is the one to remember for project-scoped behavior such as history, skills, and
session lookup, because it stays stable even when later startup steps move the
working directory around.
sessionId identifies this exact session. parentSessionId is only filled in
when this session belongs to another one, which is how the app tracks lineage
across modes.
Takeaways
- The startup state object is small, but it carries the identity the rest of boot depends on.
- projectRoot is the stable project anchor, not a temporary path.
- sessionId and parentSessionId let the app trace session lineage in plain terms.
Extensions And MCP Data Structures
Reference the extension and MCP shapes that later chapters keep reusing.
Why this matters
This appendix collects the recurring extension and MCP objects in one place. Come back here when the chapter text starts naming loaded-from sources, plugin bundles, or connection records before it explains them in detail.
LoadedFrom is the breadcrumb that tells you where a command came from.
That matters because the runtime handles skills, plugins, bundled definitions,
and MCP-backed items a little differently. The caller still supplies source,
loadedFrom, baseDir, and paths separately.
Parsed skill fields
parseSkillFrontmatterFields() returns these values after it reads the skill
frontmatter and fills in the defaults. They are the parsed skill fields, not
the caller-supplied load context.
| Field | Meaning | First Pass |
|---|---|---|
displayName | The friendly name taken from skill frontmatter when the author wants something more readable than the folder or file name. | Very important |
description | The main explanation of what the skill does, usually taken from frontmatter or the first line of the markdown body. | Very important |
hasUserSpecifiedDescription | Whether the loader found an explicit author-written description instead of falling back to markdown text. | Important on first read |
allowedTools | The list of tools this skill is allowed to use while it runs. | Very important |
argumentHint | A short gray hint that tells the user what to type after the command name. | Very important |
argumentNames | The list of argument names the loader will use when it substitutes placeholders in the skill text. | Important on first read |
whenToUse | The plain-English guidance that explains when this skill is a good fit. | Very important |
version | The version string carried forward from the skill frontmatter, if the author set one. | Important on first read |
model | The model hint the skill should carry forward, or the inherited default when the author asked for that. | Important on first read |
disableModelInvocation | Whether the skill should be hidden from model-initiated use. | Important on first read |
userInvocable | Whether a person can invoke the skill directly instead of leaving it to the model. | Very important |
hooks | The hook settings that should be registered when the skill is loaded. | Important on first read |
executionContext | Whether the skill stays inline or runs in a forked sub-agent. | Very important |
agent | The sub-agent type to use when the skill is running in forked mode. | Important on first read |
effort | The thinking effort level that should travel with the skill when the loader parses it. | Important on first read |
shell | The shell choice for `!` blocks inside the skill markdown. | Important on first read |
The quick mental model is simple: these fields describe what the skill says, how much context it should carry, and how it should run once the loader has turned the markdown into a runtime command.
Load context and runtime fields
The loader still needs a few extra values from the caller or the plugin
runtime. These are separate from parseSkillFrontmatterFields() and should not
be mixed into the parsed skill contract.
| Field | Meaning | First Pass |
|---|---|---|
source | The runtime source tag used when the command is listed, logged, and executed. | Very important |
loadedFrom | The loader-side source label that says whether the command came from skills, plugins, bundled code, managed settings, or MCP. | Very important |
enabled | Whether the plugin is turned on right now and should contribute its skills or other capabilities. | Very important |
isBuiltin | Whether the plugin ships with Claude Code instead of coming from a marketplace or custom install. | Very important |
mcpServers | The map of MCP server definitions that the plugin contributes to the runtime. | Very important |
loadedFrom and source describe where the command came from. enabled,
isBuiltin, and mcpServers belong to the plugin or MCP load context, so the
loader can keep track of whether the capability is active and what external
servers it exposes.
Interaction State Data Structures
Reference the store contract and the main AppState slices used by the interactive shell.
What lives here
This appendix is the quick reference for the interactive shell subtree. It gives readers the small state vocabulary they need before they move into the heavier REPL and provider chapters.
Store<T> contract
The store is intentionally tiny. It does three things and nothing more:
type Listener = () => void
type OnChange<T> = (args: { newState: T; oldState: T }) => void
export type Store<T> = {
getState: () => T
setState: (updater: (prev: T) => T) => void
subscribe: (listener: Listener) => () => void
}
getState() reads the current snapshot.
setState() takes an updater, gives it the previous snapshot, and replaces the
current value with whatever the updater returns.
subscribe() lets a caller listen for changes and gives back an unsubscribe
function so the listener can be removed later.
Core AppState slices
The full AppState object is large, but the subtree mostly talks about a few
core AppState slices:
settings holds the user and session configuration that comes from the startup
and settings pipeline.
tasks tracks the active task records the shell needs to show and update.
toolPermissionContext remembers the current permission state for tools so the
shell can decide whether to ask again or reuse the previous answer.
agentDefinitions keeps the active agents and the full known agent list so the
UI can show what is available without reloading agents from disk each time.
notifications stores the current visible notification plus anything queued
behind it.
promptSuggestion stores the next suggested prompt and the small amount of
state needed to know whether that suggestion has been shown or accepted.
That is enough to read the next chapters without treating the state object like one mysterious blob.
Service Layer Config And State Shapes
Meet the recurring service-layer interfaces and state objects before later chapters rely on them.
Why this matters
The services subtree reuses a handful of interfaces and state objects across very different modules. This appendix names them in one place so the deeper chapters can stay readable instead of re-explaining the same field names.
ThinkingConfig
ThinkingConfig is the small reasoning-mode shape that later API services
carry around inside RetryContext.
Fields:
type: 'adaptive'means the model can decide how much reasoning to use.type: 'enabled'means reasoning is on with an explicitbudgetTokensnumber.type: 'disabled'means the request should not use the thinking path.
RetryContext
RetryContext is the small bundle of information the API retry layer carries
from attempt to attempt.
Fields:
modelis the target model name.thinkingConfigholds the reasoning settings for that model.maxTokensOverrideis an optional temporary cap when the caller needs one.fastModetells the retry layer whether it should preserve the fast-mode path.
CompactionResult
CompactionResult is the shape the compaction service returns after it rewrites
the conversation into a smaller transcript.
Fields:
boundaryMarkermarks where the compacted transcript begins.summaryMessagesholds the short summary that replaces the long history.attachmentskeeps important side data that still needs to travel with the compacted transcript.hookResultskeeps hook-generated messages that should survive compaction.
ManualExtractionResult
ManualExtractionResult is the return shape for a manual memory extraction.
Fields:
successsays whether the write worked.memoryPathtells the caller where the memory file ended up.errorexplains what went wrong when the extraction failed.
RateLimitMessage
RateLimitMessage is the small user-facing message the rate-limit service can
return when Claude Code needs to warn about quota state.
Fields:
messageis the text people actually read.severitysays whether the message is anerroror awarning.
AnalyticsSink
AnalyticsSink is the bridge between the analytics service and whichever
backend receives events later.
Fields:
logEventhandles normal synchronous event logging.logEventAsynchandles events that can wait for an async send.
Appendices
Cross-cutting references such as prompts, recurring data structures, and glossary pages.
What lives here
This section will hold recurring prompts, shared type explanations, glossary entries, and reading notes for large files.
Query Engine Data Structures
Reference definitions for the types that appear repeatedly across the query subtree.
What lives here
This appendix gathers the recurring types that appear across the query subtree.
QueryParams
Input bundle passed into the single-turn query generator.
export type QueryParams = {
messages: Message[]
systemPrompt: SystemPrompt
userContext: { [k: string]: string }
systemContext: { [k: string]: string }
canUseTool: CanUseToolFn
toolUseContext: ToolUseContext
fallbackModel?: string
querySource: QuerySource
maxOutputTokensOverride?: number
maxTurns?: number
skipCacheWrite?: boolean
taskBudget?: { total: number }
deps?: QueryDeps
}| Field | Meaning | First Pass |
|---|---|---|
messages | Conversation history entering this turn. | Very important |
systemPrompt | The model-facing system instructions for the turn. | Very important |
toolUseContext | The execution context shared with tools. | Very important |
deps | Injected dependencies for testing or alternate runtimes. | Safe to skim at first |
QueryConfig
Immutable configuration snapshot created once at query() entry.
export type QueryConfig = {
sessionId: SessionId
gates: {
streamingToolExecution: boolean
emitToolUseSummaries: boolean
isAnt: boolean
fastModeEnabled: boolean
}
}| Field | Meaning | First Pass |
|---|---|---|
sessionId | The stable session identifier captured once for this query call. | Very important |
gates | A nested snapshot of runtime gate decisions captured once at query() entry. | Very important |
gates.streamingToolExecution | Turns on the path that streams tool execution updates instead of waiting for a whole batch. | Helpful after the basics |
gates.emitToolUseSummaries | Controls whether the query loop emits compact summaries of tool work. | Helpful after the basics |
gates.isAnt | Records whether the current user type is the internal ant variant. | Safe to skim at first |
gates.fastModeEnabled | Records whether fast-mode behavior is available for this query. | Safe to skim at first |
Task And Agent Data Structures
Reference the recurring task and agent state shapes used across the subtree.
What lives here
This appendix is the quick reference for the task subtree. It gives readers the small vocabulary they need before they move into the deeper task chapters.
This page explains each shared field in plain English so the more detailed task chapters can stay focused on behavior instead of re-explaining the same shapes.
Shared task state
TaskStateBase
The fields every task record starts with.
// Base fields shared by all task states
export type TaskStateBase = {
id: string
type: TaskType
status: TaskStatus
description: string
toolUseId?: string
startTime: number
endTime?: number
totalPausedMs?: number
outputFile: string
outputOffset: number
notified: boolean
}| Field | Meaning | First Pass |
|---|---|---|
id | The stable task ID used to find this record again. | Important on first read |
type | The task kind, such as local shell or remote agent. | Important on first read |
status | Where the task is in its lifecycle right now. | Important on first read |
description | The short human-readable summary of the task. | Important on first read |
toolUseId | The tool call that started this task, when one exists. | Important on first read |
startTime | When the task first started. | Important on first read |
endTime | When the task finished, if it has finished. | Important on first read |
totalPausedMs | How long the task spent paused in total. | Important on first read |
outputFile | The on-disk file where the task writes its output. | Important on first read |
outputOffset | How far into the output file the reader has already consumed. | Important on first read |
notified | Whether the user has already been notified about completion. | Important on first read |
TaskContext
The runtime hooks a task implementation can use while it runs.
export type TaskContext = {
abortController: AbortController
getAppState: () => AppState
setAppState: SetAppState
}abortController is the stop signal for the running task.
getAppState() reads the current application snapshot.
setAppState() updates the application snapshot in the safe React-style way.
Concrete task unions
TaskState
The full union of task state objects used across the app.
// Union of all concrete task state types
// Use this for components that need to work with any task type
import type { DreamTaskState } from './DreamTask/DreamTask.js'
import type { InProcessTeammateTaskState } from './InProcessTeammateTask/types.js'
import type { LocalAgentTaskState } from './LocalAgentTask/LocalAgentTask.js'
import type { LocalShellTaskState } from './LocalShellTask/guards.js'
import type { LocalWorkflowTaskState } from './LocalWorkflowTask/LocalWorkflowTask.js'
import type { MonitorMcpTaskState } from './MonitorMcpTask/MonitorMcpTask.js'
import type { RemoteAgentTaskState } from './RemoteAgentTask/RemoteAgentTask.js'
export type TaskState =
| LocalShellTaskState
| LocalAgentTaskState
| RemoteAgentTaskState
| InProcessTeammateTaskState
| LocalWorkflowTaskState
| MonitorMcpTaskState
| DreamTaskState BackgroundTaskState
The task states that can appear in the background tasks indicator.
// Task types that can appear in the background tasks indicator
export type BackgroundTaskState =
| LocalShellTaskState
| LocalAgentTaskState
| RemoteAgentTaskState
| InProcessTeammateTaskState
| LocalWorkflowTaskState
| MonitorMcpTaskState
| DreamTaskState Background visibility
isBackgrounded is the extra flag that keeps a task from counting as background
work just because it exists. A task only enters the background indicator when it
is running or pending and it has not been marked as foreground-only.
/**
* Check if a task should be shown in the background tasks indicator.
* A task is considered a background task if:
* 1. It is running or pending
* 2. It has been explicitly backgrounded (not a foreground task)
*/
export function isBackgroundTask(task: TaskState): task is BackgroundTaskState {
if (task.status !== 'running' && task.status !== 'pending') {
return false
}
// Foreground tasks (isBackgrounded === false) are not yet "background tasks"
if ('isBackgrounded' in task && task.isBackgrounded === false) {
return false
}
return true
}