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:

  1. behavior: 'allow' means the tool may continue
  2. behavior: 'ask' means Claude Code needs a human decision
  3. behavior: '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 explicit budgetTokens number.
  • 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:

  • model is the target model name.
  • thinkingConfig holds the reasoning settings for that model.
  • maxTokensOverride is an optional temporary cap when the caller needs one.
  • fastMode tells 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:

  • boundaryMarker marks where the compacted transcript begins.
  • summaryMessages holds the short summary that replaces the long history.
  • attachments keeps important side data that still needs to travel with the compacted transcript.
  • hookResults keeps hook-generated messages that should survive compaction.

ManualExtractionResult

ManualExtractionResult is the return shape for a manual memory extraction.

Fields:

  • success says whether the write worked.
  • memoryPath tells the caller where the memory file ended up.
  • error explains 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:

  • message is the text people actually read.
  • severity says whether the message is an error or a warning.

AnalyticsSink

AnalyticsSink is the bridge between the analytics service and whichever backend receives events later.

Fields:

  • logEvent handles normal synchronous event logging.
  • logEventAsync handles 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
}