π File detail
entrypoints/sdk/coreSchemas.ts
π― Use case
This file lives under βentrypoints/β, which covers public entry surfaces and SDK-facing entrypoints. On the API surface it exposes ModelUsageSchema, OutputFormatTypeSchema, BaseOutputFormatSchema, JsonSchemaOutputFormatSchema, and OutputFormatSchema (and more) β mainly types, interfaces, or factory objects. Dependencies touch schema validation. It composes internal code from utils (relative imports). What the file header says: SDK Core Schemas - Zod schemas for serializable SDK data types. These schemas are the single source of truth for SDK data types. TypeScript types are generated from these schemas and committed for IDE support. @see scripts/generate-sdk-types.ts for type generation.
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
SDK Core Schemas - Zod schemas for serializable SDK data types. These schemas are the single source of truth for SDK data types. TypeScript types are generated from these schemas and committed for IDE support. @see scripts/generate-sdk-types.ts for type generation
π€ Exports (heuristic)
ModelUsageSchemaOutputFormatTypeSchemaBaseOutputFormatSchemaJsonSchemaOutputFormatSchemaOutputFormatSchemaApiKeySourceSchemaConfigScopeSchemaSdkBetaSchemaThinkingAdaptiveSchemaThinkingEnabledSchemaThinkingDisabledSchemaThinkingConfigSchemaMcpStdioServerConfigSchemaMcpSSEServerConfigSchemaMcpHttpServerConfigSchemaMcpSdkServerConfigSchemaMcpServerConfigForProcessTransportSchemaMcpClaudeAIProxyServerConfigSchemaMcpServerStatusConfigSchemaMcpServerStatusSchemaMcpSetServersResultSchemaPermissionUpdateDestinationSchemaPermissionBehaviorSchemaPermissionRuleValueSchemaPermissionUpdateSchemaPermissionDecisionClassificationSchemaPermissionResultSchemaPermissionModeSchemaHOOK_EVENTSHookEventSchemaBaseHookInputSchemaPreToolUseHookInputSchemaPermissionRequestHookInputSchemaPostToolUseHookInputSchemaPostToolUseFailureHookInputSchemaPermissionDeniedHookInputSchemaNotificationHookInputSchemaUserPromptSubmitHookInputSchemaSessionStartHookInputSchemaSetupHookInputSchema
π External import roots
Package roots from from "β¦" (relative paths omitted).
zod
π₯οΈ Source preview
/**
* SDK Core Schemas - Zod schemas for serializable SDK data types.
*
* These schemas are the single source of truth for SDK data types.
* TypeScript types are generated from these schemas and committed for IDE support.
*
* @see scripts/generate-sdk-types.ts for type generation
*/
import { z } from 'zod/v4'
import { lazySchema } from '../../utils/lazySchema.js'
// ============================================================================
// Usage & Model Types
// ============================================================================
export const ModelUsageSchema = lazySchema(() =>
z.object({
inputTokens: z.number(),
outputTokens: z.number(),
cacheReadInputTokens: z.number(),
cacheCreationInputTokens: z.number(),
webSearchRequests: z.number(),
costUSD: z.number(),
contextWindow: z.number(),
maxOutputTokens: z.number(),
}),
)
// ============================================================================
// Output Format Types
// ============================================================================
export const OutputFormatTypeSchema = lazySchema(() => z.literal('json_schema'))
export const BaseOutputFormatSchema = lazySchema(() =>
z.object({
type: OutputFormatTypeSchema(),
}),
)
export const JsonSchemaOutputFormatSchema = lazySchema(() =>
z.object({
type: z.literal('json_schema'),
schema: z.record(z.string(), z.unknown()),
}),
)
export const OutputFormatSchema = lazySchema(() =>
JsonSchemaOutputFormatSchema(),
)
// ============================================================================
// Config Types
// ============================================================================
export const ApiKeySourceSchema = lazySchema(() =>
z.enum(['user', 'project', 'org', 'temporary', 'oauth']),
)
export const ConfigScopeSchema = lazySchema(() =>
z.enum(['local', 'user', 'project']).describe('Config scope for settings.'),
)
export const SdkBetaSchema = lazySchema(() =>
z.literal('context-1m-2025-08-07'),
)
export const ThinkingAdaptiveSchema = lazySchema(() =>
z
.object({
type: z.literal('adaptive'),
})
.describe('Claude decides when and how much to think (Opus 4.6+).'),
)
export const ThinkingEnabledSchema = lazySchema(() =>
z
.object({
type: z.literal('enabled'),
budgetTokens: z.number().optional(),
})
.describe('Fixed thinking token budget (older models)'),
)
export const ThinkingDisabledSchema = lazySchema(() =>
z
.object({
type: z.literal('disabled'),
})
.describe('No extended thinking'),
)
export const ThinkingConfigSchema = lazySchema(() =>
z
.union([
ThinkingAdaptiveSchema(),
ThinkingEnabledSchema(),
ThinkingDisabledSchema(),
])
.describe(
"Controls Claude's thinking/reasoning behavior. When set, takes precedence over the deprecated maxThinkingTokens.",
),
)
// ============================================================================
// MCP Server Config Types (serializable only)
// ============================================================================
export const McpStdioServerConfigSchema = lazySchema(() =>
z.object({
type: z.literal('stdio').optional(), // Optional for backwards compatibility
command: z.string(),
args: z.array(z.string()).optional(),
env: z.record(z.string(), z.string()).optional(),
}),
)
export const McpSSEServerConfigSchema = lazySchema(() =>
z.object({
type: z.literal('sse'),
url: z.string(),
headers: z.record(z.string(), z.string()).optional(),
}),
)
export const McpHttpServerConfigSchema = lazySchema(() =>
z.object({
type: z.literal('http'),
url: z.string(),
headers: z.record(z.string(), z.string()).optional(),
}),
)
export const McpSdkServerConfigSchema = lazySchema(() =>
z.object({
type: z.literal('sdk'),
name: z.string(),
}),
)
export const McpServerConfigForProcessTransportSchema = lazySchema(() =>
z.union([
McpStdioServerConfigSchema(),
McpSSEServerConfigSchema(),
McpHttpServerConfigSchema(),
McpSdkServerConfigSchema(),
]),
)
export const McpClaudeAIProxyServerConfigSchema = lazySchema(() =>
z.object({
type: z.literal('claudeai-proxy'),
url: z.string(),
id: z.string(),
}),
)
// Broader config type for status responses (includes claudeai-proxy which is output-only)
export const McpServerStatusConfigSchema = lazySchema(() =>
z.union([
McpServerConfigForProcessTransportSchema(),
McpClaudeAIProxyServerConfigSchema(),
]),
)
export const McpServerStatusSchema = lazySchema(() =>
z
.object({
name: z.string().describe('Server name as configured'),
status: z
.enum(['connected', 'failed', 'needs-auth', 'pending', 'disabled'])
.describe('Current connection status'),
serverInfo: z
.object({
name: z.string(),
version: z.string(),
})
.optional()
.describe('Server information (available when connected)'),
error: z
.string()
.optional()
.describe("Error message (available when status is 'failed')"),
config: McpServerStatusConfigSchema()
.optional()
.describe('Server configuration (includes URL for HTTP/SSE servers)'),
scope: z
.string()
.optional()
.describe(
'Configuration scope (e.g., project, user, local, claudeai, managed)',
),
tools: z
.array(
z.object({
name: z.string(),
description: z.string().optional(),
annotations: z
.object({
readOnly: z.boolean().optional(),
destructive: z.boolean().optional(),
openWorld: z.boolean().optional(),
})
.optional(),
}),
)
.optional()
.describe('Tools provided by this server (available when connected)'),
capabilities: z
.object({
experimental: z.record(z.string(), z.unknown()).optional(),
})
.optional()
.describe(
"@internal Server capabilities (available when connected). experimental['claude/channel'] is only present if the server's plugin is on the approved channels allowlist β use its presence to decide whether to show an Enable-channel prompt.",
),
})
.describe('Status information for an MCP server connection.'),
)
export const McpSetServersResultSchema = lazySchema(() =>
z
.object({
added: z.array(z.string()).describe('Names of servers that were added'),
removed: z
.array(z.string())
.describe('Names of servers that were removed'),
errors: z
.record(z.string(), z.string())
.describe(
'Map of server names to error messages for servers that failed to connect',
),
})
.describe('Result of a setMcpServers operation.'),
)
// ============================================================================
// Permission Types
// ============================================================================
export const PermissionUpdateDestinationSchema = lazySchema(() =>
z.enum([
'userSettings',
'projectSettings',
'localSettings',
'session',
'cliArg',
]),
)
export const PermissionBehaviorSchema = lazySchema(() =>
z.enum(['allow', 'deny', 'ask']),
)
export const PermissionRuleValueSchema = lazySchema(() =>
z.object({
toolName: z.string(),
ruleContent: z.string().optional(),
}),
)
export const PermissionUpdateSchema = lazySchema(() =>
z.discriminatedUnion('type', [
z.object({
type: z.literal('addRules'),
rules: z.array(PermissionRuleValueSchema()),
behavior: PermissionBehaviorSchema(),
destination: PermissionUpdateDestinationSchema(),
}),
z.object({
type: z.literal('replaceRules'),
rules: z.array(PermissionRuleValueSchema()),
behavior: PermissionBehaviorSchema(),
destination: PermissionUpdateDestinationSchema(),
}),
z.object({
type: z.literal('removeRules'),
rules: z.array(PermissionRuleValueSchema()),
behavior: PermissionBehaviorSchema(),
destination: PermissionUpdateDestinationSchema(),
}),
z.object({
type: z.literal('setMode'),
mode: z.lazy(() => PermissionModeSchema()),
destination: PermissionUpdateDestinationSchema(),
}),
z.object({
type: z.literal('addDirectories'),
directories: z.array(z.string()),
destination: PermissionUpdateDestinationSchema(),
}),
z.object({
type: z.literal('removeDirectories'),
directories: z.array(z.string()),
destination: PermissionUpdateDestinationSchema(),
}),
]),
)
export const PermissionDecisionClassificationSchema = lazySchema(() =>
z
.enum(['user_temporary', 'user_permanent', 'user_reject'])
.describe(
'Classification of this permission decision for telemetry. SDK hosts ' +
'that prompt users (desktop apps, IDEs) should set this to reflect ' +
'what actually happened: user_temporary for allow-once, user_permanent ' +
'for always-allow (both the click and later cache hits), user_reject ' +
'for deny. If unset, the CLI infers conservatively (temporary for ' +
'allow, reject for deny). The vocabulary matches tool_decision OTel ' +
'events (monitoring-usage docs).',
),
)
export const PermissionResultSchema = lazySchema(() =>
z.union([
z.object({
behavior: z.literal('allow'),
// Optional - may not be provided if hook sets permission without input modification
updatedInput: z.record(z.string(), z.unknown()).optional(),
updatedPermissions: z.array(PermissionUpdateSchema()).optional(),
toolUseID: z.string().optional(),
decisionClassification:
PermissionDecisionClassificationSchema().optional(),
}),
z.object({
behavior: z.literal('deny'),
message: z.string(),
interrupt: z.boolean().optional(),
toolUseID: z.string().optional(),
decisionClassification:
PermissionDecisionClassificationSchema().optional(),
}),
]),
)
export const PermissionModeSchema = lazySchema(() =>
z
.enum(['default', 'acceptEdits', 'bypassPermissions', 'plan', 'dontAsk'])
.describe(
'Permission mode for controlling how tool executions are handled. ' +
"'default' - Standard behavior, prompts for dangerous operations. " +
"'acceptEdits' - Auto-accept file edit operations. " +
"'bypassPermissions' - Bypass all permission checks (requires allowDangerouslySkipPermissions). " +
"'plan' - Planning mode, no actual tool execution. " +
"'dontAsk' - Don't prompt for permissions, deny if not pre-approved.",
),
)
// ============================================================================
// Hook Types
// ============================================================================
export const HOOK_EVENTS = [
'PreToolUse',
'PostToolUse',
'PostToolUseFailure',
'Notification',
'UserPromptSubmit',
'SessionStart',
'SessionEnd',
'Stop',
'StopFailure',
'SubagentStart',
'SubagentStop',
'PreCompact',
'PostCompact',
'PermissionRequest',
'PermissionDenied',
'Setup',
'TeammateIdle',
'TaskCreated',
'TaskCompleted',
'Elicitation',
'ElicitationResult',
'ConfigChange',
'WorktreeCreate',
'WorktreeRemove',
'InstructionsLoaded',
'CwdChanged',
'FileChanged',
] as const
export const HookEventSchema = lazySchema(() => z.enum(HOOK_EVENTS))
export const BaseHookInputSchema = lazySchema(() =>
z.object({
session_id: z.string(),
transcript_path: z.string(),
cwd: z.string(),
permission_mode: z.string().optional(),
agent_id: z
.string()
.optional()
.describe(
'Subagent identifier. Present only when the hook fires from within a subagent ' +
'(e.g., a tool called by an AgentTool worker). Absent for the main thread, ' +
'even in --agent sessions. Use this field (not agent_type) to distinguish ' +
'subagent calls from main-thread calls.',
),
agent_type: z
.string()
.optional()
.describe(
'Agent type name (e.g., "general-purpose", "code-reviewer"). Present when the ' +
'hook fires from within a subagent (alongside agent_id), or on the main thread ' +
'of a session started with --agent (without agent_id).',
),
}),
)
// Use .and() instead of .extend() to preserve BaseHookInput & {...} in generated types
export const PreToolUseHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('PreToolUse'),
tool_name: z.string(),
tool_input: z.unknown(),
tool_use_id: z.string(),
}),
),
)
export const PermissionRequestHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('PermissionRequest'),
tool_name: z.string(),
tool_input: z.unknown(),
permission_suggestions: z.array(PermissionUpdateSchema()).optional(),
}),
),
)
export const PostToolUseHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('PostToolUse'),
tool_name: z.string(),
tool_input: z.unknown(),
tool_response: z.unknown(),
tool_use_id: z.string(),
}),
),
)
export const PostToolUseFailureHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('PostToolUseFailure'),
tool_name: z.string(),
tool_input: z.unknown(),
tool_use_id: z.string(),
error: z.string(),
is_interrupt: z.boolean().optional(),
}),
),
)
export const PermissionDeniedHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('PermissionDenied'),
tool_name: z.string(),
tool_input: z.unknown(),
tool_use_id: z.string(),
reason: z.string(),
}),
),
)
export const NotificationHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('Notification'),
message: z.string(),
title: z.string().optional(),
notification_type: z.string(),
}),
),
)
export const UserPromptSubmitHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('UserPromptSubmit'),
prompt: z.string(),
}),
),
)
export const SessionStartHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('SessionStart'),
source: z.enum(['startup', 'resume', 'clear', 'compact']),
agent_type: z.string().optional(),
model: z.string().optional(),
}),
),
)
export const SetupHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('Setup'),
trigger: z.enum(['init', 'maintenance']),
}),
),
)
export const StopHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('Stop'),
stop_hook_active: z.boolean(),
last_assistant_message: z
.string()
.optional()
.describe(
'Text content of the last assistant message before stopping. ' +
'Avoids the need to read and parse the transcript file.',
),
}),
),
)
export const StopFailureHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('StopFailure'),
error: SDKAssistantMessageErrorSchema(),
error_details: z.string().optional(),
last_assistant_message: z.string().optional(),
}),
),
)
export const SubagentStartHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('SubagentStart'),
agent_id: z.string(),
agent_type: z.string(),
}),
),
)
export const SubagentStopHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('SubagentStop'),
stop_hook_active: z.boolean(),
agent_id: z.string(),
agent_transcript_path: z.string(),
agent_type: z.string(),
last_assistant_message: z
.string()
.optional()
.describe(
'Text content of the last assistant message before stopping. ' +
'Avoids the need to read and parse the transcript file.',
),
}),
),
)
export const PreCompactHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('PreCompact'),
trigger: z.enum(['manual', 'auto']),
custom_instructions: z.string().nullable(),
}),
),
)
export const PostCompactHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('PostCompact'),
trigger: z.enum(['manual', 'auto']),
compact_summary: z
.string()
.describe('The conversation summary produced by compaction'),
}),
),
)
export const TeammateIdleHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('TeammateIdle'),
teammate_name: z.string(),
team_name: z.string(),
}),
),
)
export const TaskCreatedHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('TaskCreated'),
task_id: z.string(),
task_subject: z.string(),
task_description: z.string().optional(),
teammate_name: z.string().optional(),
team_name: z.string().optional(),
}),
),
)
export const TaskCompletedHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('TaskCompleted'),
task_id: z.string(),
task_subject: z.string(),
task_description: z.string().optional(),
teammate_name: z.string().optional(),
team_name: z.string().optional(),
}),
),
)
export const ElicitationHookInputSchema = lazySchema(() =>
BaseHookInputSchema()
.and(
z.object({
hook_event_name: z.literal('Elicitation'),
mcp_server_name: z.string(),
message: z.string(),
mode: z.enum(['form', 'url']).optional(),
url: z.string().optional(),
elicitation_id: z.string().optional(),
requested_schema: z.record(z.string(), z.unknown()).optional(),
}),
)
.describe(
'Hook input for the Elicitation event. Fired when an MCP server requests user input. Hooks can auto-respond (accept/decline) instead of showing the dialog.',
),
)
export const ElicitationResultHookInputSchema = lazySchema(() =>
BaseHookInputSchema()
.and(
z.object({
hook_event_name: z.literal('ElicitationResult'),
mcp_server_name: z.string(),
elicitation_id: z.string().optional(),
mode: z.enum(['form', 'url']).optional(),
action: z.enum(['accept', 'decline', 'cancel']),
content: z.record(z.string(), z.unknown()).optional(),
}),
)
.describe(
'Hook input for the ElicitationResult event. Fired after the user responds to an MCP elicitation. Hooks can observe or override the response before it is sent to the server.',
),
)
export const CONFIG_CHANGE_SOURCES = [
'user_settings',
'project_settings',
'local_settings',
'policy_settings',
'skills',
] as const
export const ConfigChangeHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('ConfigChange'),
source: z.enum(CONFIG_CHANGE_SOURCES),
file_path: z.string().optional(),
}),
),
)
export const INSTRUCTIONS_LOAD_REASONS = [
'session_start',
'nested_traversal',
'path_glob_match',
'include',
'compact',
] as const
export const INSTRUCTIONS_MEMORY_TYPES = [
'User',
'Project',
'Local',
'Managed',
] as const
export const InstructionsLoadedHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('InstructionsLoaded'),
file_path: z.string(),
memory_type: z.enum(INSTRUCTIONS_MEMORY_TYPES),
load_reason: z.enum(INSTRUCTIONS_LOAD_REASONS),
globs: z.array(z.string()).optional(),
trigger_file_path: z.string().optional(),
parent_file_path: z.string().optional(),
}),
),
)
export const WorktreeCreateHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('WorktreeCreate'),
name: z.string(),
}),
),
)
export const WorktreeRemoveHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('WorktreeRemove'),
worktree_path: z.string(),
}),
),
)
export const CwdChangedHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('CwdChanged'),
old_cwd: z.string(),
new_cwd: z.string(),
}),
),
)
export const FileChangedHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('FileChanged'),
file_path: z.string(),
event: z.enum(['change', 'add', 'unlink']),
}),
),
)
export const EXIT_REASONS = [
'clear',
'resume',
'logout',
'prompt_input_exit',
'other',
'bypass_permissions_disabled',
] as const
export const ExitReasonSchema = lazySchema(() => z.enum(EXIT_REASONS))
export const SessionEndHookInputSchema = lazySchema(() =>
BaseHookInputSchema().and(
z.object({
hook_event_name: z.literal('SessionEnd'),
reason: ExitReasonSchema(),
}),
),
)
export const HookInputSchema = lazySchema(() =>
z.union([
PreToolUseHookInputSchema(),
PostToolUseHookInputSchema(),
PostToolUseFailureHookInputSchema(),
PermissionDeniedHookInputSchema(),
NotificationHookInputSchema(),
UserPromptSubmitHookInputSchema(),
SessionStartHookInputSchema(),
SessionEndHookInputSchema(),
StopHookInputSchema(),
StopFailureHookInputSchema(),
SubagentStartHookInputSchema(),
SubagentStopHookInputSchema(),
PreCompactHookInputSchema(),
PostCompactHookInputSchema(),
PermissionRequestHookInputSchema(),
SetupHookInputSchema(),
TeammateIdleHookInputSchema(),
TaskCreatedHookInputSchema(),
TaskCompletedHookInputSchema(),
ElicitationHookInputSchema(),
ElicitationResultHookInputSchema(),
ConfigChangeHookInputSchema(),
InstructionsLoadedHookInputSchema(),
WorktreeCreateHookInputSchema(),
WorktreeRemoveHookInputSchema(),
CwdChangedHookInputSchema(),
FileChangedHookInputSchema(),
]),
)
export const AsyncHookJSONOutputSchema = lazySchema(() =>
z.object({
async: z.literal(true),
asyncTimeout: z.number().optional(),
}),
)
export const PreToolUseHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('PreToolUse'),
permissionDecision: PermissionBehaviorSchema().optional(),
permissionDecisionReason: z.string().optional(),
updatedInput: z.record(z.string(), z.unknown()).optional(),
additionalContext: z.string().optional(),
}),
)
export const UserPromptSubmitHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('UserPromptSubmit'),
additionalContext: z.string().optional(),
}),
)
export const SessionStartHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('SessionStart'),
additionalContext: z.string().optional(),
initialUserMessage: z.string().optional(),
watchPaths: z.array(z.string()).optional(),
}),
)
export const SetupHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('Setup'),
additionalContext: z.string().optional(),
}),
)
export const SubagentStartHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('SubagentStart'),
additionalContext: z.string().optional(),
}),
)
export const PostToolUseHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('PostToolUse'),
additionalContext: z.string().optional(),
updatedMCPToolOutput: z.unknown().optional(),
}),
)
export const PostToolUseFailureHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('PostToolUseFailure'),
additionalContext: z.string().optional(),
}),
)
export const PermissionDeniedHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('PermissionDenied'),
retry: z.boolean().optional(),
}),
)
export const NotificationHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('Notification'),
additionalContext: z.string().optional(),
}),
)
export const PermissionRequestHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('PermissionRequest'),
decision: z.union([
z.object({
behavior: z.literal('allow'),
updatedInput: z.record(z.string(), z.unknown()).optional(),
updatedPermissions: z.array(PermissionUpdateSchema()).optional(),
}),
z.object({
behavior: z.literal('deny'),
message: z.string().optional(),
interrupt: z.boolean().optional(),
}),
]),
}),
)
export const CwdChangedHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('CwdChanged'),
watchPaths: z.array(z.string()).optional(),
}),
)
export const FileChangedHookSpecificOutputSchema = lazySchema(() =>
z.object({
hookEventName: z.literal('FileChanged'),
watchPaths: z.array(z.string()).optional(),
}),
)
export const SyncHookJSONOutputSchema = lazySchema(() =>
z.object({
continue: z.boolean().optional(),
suppressOutput: z.boolean().optional(),
stopReason: z.string().optional(),
decision: z.enum(['approve', 'block']).optional(),
systemMessage: z.string().optional(),
reason: z.string().optional(),
hookSpecificOutput: z
.union([
PreToolUseHookSpecificOutputSchema(),
UserPromptSubmitHookSpecificOutputSchema(),
SessionStartHookSpecificOutputSchema(),
SetupHookSpecificOutputSchema(),
SubagentStartHookSpecificOutputSchema(),
PostToolUseHookSpecificOutputSchema(),
PostToolUseFailureHookSpecificOutputSchema(),
PermissionDeniedHookSpecificOutputSchema(),
NotificationHookSpecificOutputSchema(),
PermissionRequestHookSpecificOutputSchema(),
ElicitationHookSpecificOutputSchema(),
ElicitationResultHookSpecificOutputSchema(),
CwdChangedHookSpecificOutputSchema(),
FileChangedHookSpecificOutputSchema(),
WorktreeCreateHookSpecificOutputSchema(),
])
.optional(),
}),
)
export const ElicitationHookSpecificOutputSchema = lazySchema(() =>
z
.object({
hookEventName: z.literal('Elicitation'),
action: z.enum(['accept', 'decline', 'cancel']).optional(),
content: z.record(z.string(), z.unknown()).optional(),
})
.describe(
'Hook-specific output for the Elicitation event. Return this to programmatically accept or decline an MCP elicitation request.',
),
)
export const ElicitationResultHookSpecificOutputSchema = lazySchema(() =>
z
.object({
hookEventName: z.literal('ElicitationResult'),
action: z.enum(['accept', 'decline', 'cancel']).optional(),
content: z.record(z.string(), z.unknown()).optional(),
})
.describe(
'Hook-specific output for the ElicitationResult event. Return this to override the action or content before the response is sent to the MCP server.',
),
)
export const WorktreeCreateHookSpecificOutputSchema = lazySchema(() =>
z
.object({
hookEventName: z.literal('WorktreeCreate'),
worktreePath: z.string(),
})
.describe(
'Hook-specific output for the WorktreeCreate event. Provides the absolute path to the created worktree directory. Command hooks print the path on stdout instead.',
),
)
export const HookJSONOutputSchema = lazySchema(() =>
z.union([AsyncHookJSONOutputSchema(), SyncHookJSONOutputSchema()]),
)
export const PromptRequestOptionSchema = lazySchema(() =>
z.object({
key: z
.string()
.describe('Unique key for this option, returned in the response'),
label: z.string().describe('Display text for this option'),
description: z
.string()
.optional()
.describe('Optional description shown below the label'),
}),
)
export const PromptRequestSchema = lazySchema(() =>
z.object({
prompt: z
.string()
.describe(
'Request ID. Presence of this key marks the line as a prompt request.',
),
message: z.string().describe('The prompt message to display to the user'),
options: z
.array(PromptRequestOptionSchema())
.describe('Available options for the user to choose from'),
}),
)
export const PromptResponseSchema = lazySchema(() =>
z.object({
prompt_response: z
.string()
.describe('The request ID from the corresponding prompt request'),
selected: z.string().describe('The key of the selected option'),
}),
)
// ============================================================================
// Skill/Command Types
// ============================================================================
export const SlashCommandSchema = lazySchema(() =>
z
.object({
name: z.string().describe('Skill name (without the leading slash)'),
description: z.string().describe('Description of what the skill does'),
argumentHint: z
.string()
.describe('Hint for skill arguments (e.g., "<file>")'),
})
.describe(
'Information about an available skill (invoked via /command syntax).',
),
)
export const AgentInfoSchema = lazySchema(() =>
z
.object({
name: z.string().describe('Agent type identifier (e.g., "Explore")'),
description: z.string().describe('Description of when to use this agent'),
model: z
.string()
.optional()
.describe(
"Model alias this agent uses. If omitted, inherits the parent's model",
),
})
.describe(
'Information about an available subagent that can be invoked via the Task tool.',
),
)
export const ModelInfoSchema = lazySchema(() =>
z
.object({
value: z.string().describe('Model identifier to use in API calls'),
displayName: z.string().describe('Human-readable display name'),
description: z
.string()
.describe("Description of the model's capabilities"),
supportsEffort: z
.boolean()
.optional()
.describe('Whether this model supports effort levels'),
supportedEffortLevels: z
.array(z.enum(['low', 'medium', 'high', 'max']))
.optional()
.describe('Available effort levels for this model'),
supportsAdaptiveThinking: z
.boolean()
.optional()
.describe(
'Whether this model supports adaptive thinking (Claude decides when and how much to think)',
),
supportsFastMode: z
.boolean()
.optional()
.describe('Whether this model supports fast mode'),
supportsAutoMode: z
.boolean()
.optional()
.describe('Whether this model supports auto mode'),
})
.describe('Information about an available model.'),
)
export const AccountInfoSchema = lazySchema(() =>
z
.object({
email: z.string().optional(),
organization: z.string().optional(),
subscriptionType: z.string().optional(),
tokenSource: z.string().optional(),
apiKeySource: z.string().optional(),
apiProvider: z
.enum(['firstParty', 'bedrock', 'vertex', 'foundry'])
.optional()
.describe(
'Active API backend. Anthropic OAuth login only applies when "firstParty"; for 3P providers the other fields are absent and auth is external (AWS creds, gcloud ADC, etc.).',
),
})
.describe("Information about the logged in user's account."),
)
// ============================================================================
// Agent Definition Types
// ============================================================================
export const AgentMcpServerSpecSchema = lazySchema(() =>
z.union([
z.string(),
z.record(z.string(), McpServerConfigForProcessTransportSchema()),
]),
)
export const AgentDefinitionSchema = lazySchema(() =>
z
.object({
description: z
.string()
.describe('Natural language description of when to use this agent'),
tools: z
.array(z.string())
.optional()
.describe(
'Array of allowed tool names. If omitted, inherits all tools from parent',
),
disallowedTools: z
.array(z.string())
.optional()
.describe('Array of tool names to explicitly disallow for this agent'),
prompt: z.string().describe("The agent's system prompt"),
model: z
.string()
.optional()
.describe(
"Model alias (e.g. 'sonnet', 'opus', 'haiku') or full model ID (e.g. 'claude-opus-4-5'). If omitted or 'inherit', uses the main model",
),
mcpServers: z.array(AgentMcpServerSpecSchema()).optional(),
criticalSystemReminder_EXPERIMENTAL: z
.string()
.optional()
.describe('Experimental: Critical reminder added to system prompt'),
skills: z
.array(z.string())
.optional()
.describe('Array of skill names to preload into the agent context'),
initialPrompt: z
.string()
.optional()
.describe(
'Auto-submitted as the first user turn when this agent is the main thread agent. Slash commands are processed. Prepended to any user-provided prompt.',
),
maxTurns: z
.number()
.int()
.positive()
.optional()
.describe(
'Maximum number of agentic turns (API round-trips) before stopping',
),
background: z
.boolean()
.optional()
.describe(
'Run this agent as a background task (non-blocking, fire-and-forget) when invoked',
),
memory: z
.enum(['user', 'project', 'local'])
.optional()
.describe(
"Scope for auto-loading agent memory files. 'user' - ~/.claude/agent-memory/<agentType>/, 'project' - .claude/agent-memory/<agentType>/, 'local' - .claude/agent-memory-local/<agentType>/",
),
effort: z
.union([z.enum(['low', 'medium', 'high', 'max']), z.number().int()])
.optional()
.describe(
'Reasoning effort level for this agent. Either a named level or an integer',
),
permissionMode: PermissionModeSchema()
.optional()
.describe(
'Permission mode controlling how tool executions are handled',
),
})
.describe(
'Definition for a custom subagent that can be invoked via the Agent tool.',
),
)
// ============================================================================
// Settings Types
// ============================================================================
export const SettingSourceSchema = lazySchema(() =>
z
.enum(['user', 'project', 'local'])
.describe(
'Source for loading filesystem-based settings. ' +
"'user' - Global user settings (~/.claude/settings.json). " +
"'project' - Project settings (.claude/settings.json). " +
"'local' - Local settings (.claude/settings.local.json).",
),
)
export const SdkPluginConfigSchema = lazySchema(() =>
z
.object({
type: z
.literal('local')
.describe("Plugin type. Currently only 'local' is supported"),
path: z
.string()
.describe('Absolute or relative path to the plugin directory'),
})
.describe('Configuration for loading a plugin.'),
)
// ============================================================================
// Rewind Types
// ============================================================================
export const RewindFilesResultSchema = lazySchema(() =>
z
.object({
canRewind: z.boolean(),
error: z.string().optional(),
filesChanged: z.array(z.string()).optional(),
insertions: z.number().optional(),
deletions: z.number().optional(),
})
.describe('Result of a rewindFiles operation.'),
)
// ============================================================================
// External Type Placeholders
// ============================================================================
//
// These schemas use z.unknown() as placeholders for external types.
// The generation script uses TypeOverrideMap to output the correct TS type references.
// This allows us to define SDK message types in Zod while maintaining proper typing.
/** Placeholder for APIUserMessage from @anthropic-ai/sdk */
export const APIUserMessagePlaceholder = lazySchema(() => z.unknown())
/** Placeholder for APIAssistantMessage from @anthropic-ai/sdk */
export const APIAssistantMessagePlaceholder = lazySchema(() => z.unknown())
/** Placeholder for RawMessageStreamEvent from @anthropic-ai/sdk */
export const RawMessageStreamEventPlaceholder = lazySchema(() => z.unknown())
/** Placeholder for UUID from crypto */
export const UUIDPlaceholder = lazySchema(() => z.string())
/** Placeholder for NonNullableUsage (mapped type over Usage) */
export const NonNullableUsagePlaceholder = lazySchema(() => z.unknown())
// ============================================================================
// SDK Message Types
// ============================================================================
export const SDKAssistantMessageErrorSchema = lazySchema(() =>
z.enum([
'authentication_failed',
'billing_error',
'rate_limit',
'invalid_request',
'server_error',
'unknown',
'max_output_tokens',
]),
)
export const SDKStatusSchema = lazySchema(() =>
z.union([z.literal('compacting'), z.null()]),
)
// SDKUserMessage content without uuid/session_id
const SDKUserMessageContentSchema = lazySchema(() =>
z.object({
type: z.literal('user'),
message: APIUserMessagePlaceholder(),
parent_tool_use_id: z.string().nullable(),
isSynthetic: z.boolean().optional(),
tool_use_result: z.unknown().optional(),
priority: z.enum(['now', 'next', 'later']).optional(),
timestamp: z
.string()
.optional()
.describe(
'ISO timestamp when the message was created on the originating process. Older emitters omit it; consumers should fall back to receive time.',
),
}),
)
export const SDKUserMessageSchema = lazySchema(() =>
SDKUserMessageContentSchema().extend({
uuid: UUIDPlaceholder().optional(),
session_id: z.string().optional(),
}),
)
export const SDKUserMessageReplaySchema = lazySchema(() =>
SDKUserMessageContentSchema().extend({
uuid: UUIDPlaceholder(),
session_id: z.string(),
isReplay: z.literal(true),
}),
)
export const SDKRateLimitInfoSchema = lazySchema(() =>
z
.object({
status: z.enum(['allowed', 'allowed_warning', 'rejected']),
resetsAt: z.number().optional(),
rateLimitType: z
.enum([
'five_hour',
'seven_day',
'seven_day_opus',
'seven_day_sonnet',
'overage',
])
.optional(),
utilization: z.number().optional(),
overageStatus: z
.enum(['allowed', 'allowed_warning', 'rejected'])
.optional(),
overageResetsAt: z.number().optional(),
overageDisabledReason: z
.enum([
'overage_not_provisioned',
'org_level_disabled',
'org_level_disabled_until',
'out_of_credits',
'seat_tier_level_disabled',
'member_level_disabled',
'seat_tier_zero_credit_limit',
'group_zero_credit_limit',
'member_zero_credit_limit',
'org_service_level_disabled',
'org_service_zero_credit_limit',
'no_limits_configured',
'unknown',
])
.optional(),
isUsingOverage: z.boolean().optional(),
surpassedThreshold: z.number().optional(),
})
.describe('Rate limit information for claude.ai subscription users.'),
)
export const SDKAssistantMessageSchema = lazySchema(() =>
z.object({
type: z.literal('assistant'),
message: APIAssistantMessagePlaceholder(),
parent_tool_use_id: z.string().nullable(),
error: SDKAssistantMessageErrorSchema().optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKRateLimitEventSchema = lazySchema(() =>
z
.object({
type: z.literal('rate_limit_event'),
rate_limit_info: SDKRateLimitInfoSchema(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
})
.describe('Rate limit event emitted when rate limit info changes.'),
)
export const SDKStreamlinedTextMessageSchema = lazySchema(() =>
z
.object({
type: z.literal('streamlined_text'),
text: z
.string()
.describe('Text content preserved from the assistant message'),
session_id: z.string(),
uuid: UUIDPlaceholder(),
})
.describe(
'@internal Streamlined text message - replaces SDKAssistantMessage in streamlined output. Text content preserved, thinking and tool_use blocks removed.',
),
)
export const SDKStreamlinedToolUseSummaryMessageSchema = lazySchema(() =>
z
.object({
type: z.literal('streamlined_tool_use_summary'),
tool_summary: z
.string()
.describe('Summary of tool calls (e.g., "Read 2 files, wrote 1 file")'),
session_id: z.string(),
uuid: UUIDPlaceholder(),
})
.describe(
'@internal Streamlined tool use summary - replaces tool_use blocks in streamlined output with a cumulative summary string.',
),
)
export const SDKPermissionDenialSchema = lazySchema(() =>
z.object({
tool_name: z.string(),
tool_use_id: z.string(),
tool_input: z.record(z.string(), z.unknown()),
}),
)
export const SDKResultSuccessSchema = lazySchema(() =>
z.object({
type: z.literal('result'),
subtype: z.literal('success'),
duration_ms: z.number(),
duration_api_ms: z.number(),
is_error: z.boolean(),
num_turns: z.number(),
result: z.string(),
stop_reason: z.string().nullable(),
total_cost_usd: z.number(),
usage: NonNullableUsagePlaceholder(),
modelUsage: z.record(z.string(), ModelUsageSchema()),
permission_denials: z.array(SDKPermissionDenialSchema()),
structured_output: z.unknown().optional(),
fast_mode_state: FastModeStateSchema().optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKResultErrorSchema = lazySchema(() =>
z.object({
type: z.literal('result'),
subtype: z.enum([
'error_during_execution',
'error_max_turns',
'error_max_budget_usd',
'error_max_structured_output_retries',
]),
duration_ms: z.number(),
duration_api_ms: z.number(),
is_error: z.boolean(),
num_turns: z.number(),
stop_reason: z.string().nullable(),
total_cost_usd: z.number(),
usage: NonNullableUsagePlaceholder(),
modelUsage: z.record(z.string(), ModelUsageSchema()),
permission_denials: z.array(SDKPermissionDenialSchema()),
errors: z.array(z.string()),
fast_mode_state: FastModeStateSchema().optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKResultMessageSchema = lazySchema(() =>
z.union([SDKResultSuccessSchema(), SDKResultErrorSchema()]),
)
export const SDKSystemMessageSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('init'),
agents: z.array(z.string()).optional(),
apiKeySource: ApiKeySourceSchema(),
betas: z.array(z.string()).optional(),
claude_code_version: z.string(),
cwd: z.string(),
tools: z.array(z.string()),
mcp_servers: z.array(
z.object({
name: z.string(),
status: z.string(),
}),
),
model: z.string(),
permissionMode: PermissionModeSchema(),
slash_commands: z.array(z.string()),
output_style: z.string(),
skills: z.array(z.string()),
plugins: z.array(
z.object({
name: z.string(),
path: z.string(),
source: z
.string()
.optional()
.describe(
'@internal Plugin source identifier in "name\\@marketplace" format. Sentinels: "name\\@inline" for --plugin-dir, "name\\@builtin" for built-in plugins.',
),
}),
),
fast_mode_state: FastModeStateSchema().optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKPartialAssistantMessageSchema = lazySchema(() =>
z.object({
type: z.literal('stream_event'),
event: RawMessageStreamEventPlaceholder(),
parent_tool_use_id: z.string().nullable(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKCompactBoundaryMessageSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('compact_boundary'),
compact_metadata: z.object({
trigger: z.enum(['manual', 'auto']),
pre_tokens: z.number(),
preserved_segment: z
.object({
head_uuid: UUIDPlaceholder(),
anchor_uuid: UUIDPlaceholder(),
tail_uuid: UUIDPlaceholder(),
})
.optional()
.describe(
'Relink info for messagesToKeep. Loaders splice the preserved ' +
'segment at anchor_uuid (summary for suffix-preserving, ' +
'boundary for prefix-preserving partial compact) so resume ' +
'includes preserved content. Unset when compaction summarizes ' +
'everything (no messagesToKeep).',
),
}),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKStatusMessageSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('status'),
status: SDKStatusSchema(),
permissionMode: PermissionModeSchema().optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKPostTurnSummaryMessageSchema = lazySchema(() =>
z
.object({
type: z.literal('system'),
subtype: z.literal('post_turn_summary'),
summarizes_uuid: z.string(),
status_category: z.enum([
'blocked',
'waiting',
'completed',
'review_ready',
'failed',
]),
status_detail: z.string(),
is_noteworthy: z.boolean(),
title: z.string(),
description: z.string(),
recent_action: z.string(),
needs_action: z.string(),
artifact_urls: z.array(z.string()),
uuid: UUIDPlaceholder(),
session_id: z.string(),
})
.describe(
'@internal Background post-turn summary emitted after each assistant turn. summarizes_uuid points to the assistant message this summarizes.',
),
)
export const SDKAPIRetryMessageSchema = lazySchema(() =>
z
.object({
type: z.literal('system'),
subtype: z.literal('api_retry'),
attempt: z.number(),
max_retries: z.number(),
retry_delay_ms: z.number(),
error_status: z.number().nullable(),
error: SDKAssistantMessageErrorSchema(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
})
.describe(
'Emitted when an API request fails with a retryable error and will be retried after a delay. error_status is null for connection errors (e.g. timeouts) that had no HTTP response.',
),
)
export const SDKLocalCommandOutputMessageSchema = lazySchema(() =>
z
.object({
type: z.literal('system'),
subtype: z.literal('local_command_output'),
content: z.string(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
})
.describe(
'Output from a local slash command (e.g. /voice, /cost). Displayed as assistant-style text in the transcript.',
),
)
export const SDKHookStartedMessageSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('hook_started'),
hook_id: z.string(),
hook_name: z.string(),
hook_event: z.string(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKHookProgressMessageSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('hook_progress'),
hook_id: z.string(),
hook_name: z.string(),
hook_event: z.string(),
stdout: z.string(),
stderr: z.string(),
output: z.string(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKHookResponseMessageSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('hook_response'),
hook_id: z.string(),
hook_name: z.string(),
hook_event: z.string(),
output: z.string(),
stdout: z.string(),
stderr: z.string(),
exit_code: z.number().optional(),
outcome: z.enum(['success', 'error', 'cancelled']),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKToolProgressMessageSchema = lazySchema(() =>
z.object({
type: z.literal('tool_progress'),
tool_use_id: z.string(),
tool_name: z.string(),
parent_tool_use_id: z.string().nullable(),
elapsed_time_seconds: z.number(),
task_id: z.string().optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKAuthStatusMessageSchema = lazySchema(() =>
z.object({
type: z.literal('auth_status'),
isAuthenticating: z.boolean(),
output: z.array(z.string()),
error: z.string().optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKFilesPersistedEventSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('files_persisted'),
files: z.array(
z.object({
filename: z.string(),
file_id: z.string(),
}),
),
failed: z.array(
z.object({
filename: z.string(),
error: z.string(),
}),
),
processed_at: z.string(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKTaskNotificationMessageSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('task_notification'),
task_id: z.string(),
tool_use_id: z.string().optional(),
status: z.enum(['completed', 'failed', 'stopped']),
output_file: z.string(),
summary: z.string(),
usage: z
.object({
total_tokens: z.number(),
tool_uses: z.number(),
duration_ms: z.number(),
})
.optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKTaskStartedMessageSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('task_started'),
task_id: z.string(),
tool_use_id: z.string().optional(),
description: z.string(),
task_type: z.string().optional(),
workflow_name: z
.string()
.optional()
.describe(
"meta.name from the workflow script (e.g. 'spec'). Only set when task_type is 'local_workflow'.",
),
prompt: z.string().optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKSessionStateChangedMessageSchema = lazySchema(() =>
z
.object({
type: z.literal('system'),
subtype: z.literal('session_state_changed'),
state: z.enum(['idle', 'running', 'requires_action']),
uuid: UUIDPlaceholder(),
session_id: z.string(),
})
.describe(
"Mirrors notifySessionStateChanged. 'idle' fires after heldBackResult flushes and the bg-agent do-while exits β authoritative turn-over signal.",
),
)
export const SDKTaskProgressMessageSchema = lazySchema(() =>
z.object({
type: z.literal('system'),
subtype: z.literal('task_progress'),
task_id: z.string(),
tool_use_id: z.string().optional(),
description: z.string(),
usage: z.object({
total_tokens: z.number(),
tool_uses: z.number(),
duration_ms: z.number(),
}),
last_tool_name: z.string().optional(),
summary: z.string().optional(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKToolUseSummaryMessageSchema = lazySchema(() =>
z.object({
type: z.literal('tool_use_summary'),
summary: z.string(),
preceding_tool_use_ids: z.array(z.string()),
uuid: UUIDPlaceholder(),
session_id: z.string(),
}),
)
export const SDKElicitationCompleteMessageSchema = lazySchema(() =>
z
.object({
type: z.literal('system'),
subtype: z.literal('elicitation_complete'),
mcp_server_name: z.string(),
elicitation_id: z.string(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
})
.describe(
'Emitted when an MCP server confirms that a URL-mode elicitation is complete.',
),
)
/** @internal */
export const SDKPromptSuggestionMessageSchema = lazySchema(() =>
z
.object({
type: z.literal('prompt_suggestion'),
suggestion: z.string(),
uuid: UUIDPlaceholder(),
session_id: z.string(),
})
.describe(
'Predicted next user prompt, emitted after each turn when promptSuggestions is enabled.',
),
)
// ============================================================================
// Session Listing Types
// ============================================================================
export const SDKSessionInfoSchema = lazySchema(() =>
z
.object({
sessionId: z.string().describe('Unique session identifier (UUID).'),
summary: z
.string()
.describe(
'Display title for the session: custom title, auto-generated summary, or first prompt.',
),
lastModified: z
.number()
.describe('Last modified time in milliseconds since epoch.'),
fileSize: z
.number()
.optional()
.describe(
'File size in bytes. Only populated for local JSONL storage.',
),
customTitle: z
.string()
.optional()
.describe('User-set session title via /rename.'),
firstPrompt: z
.string()
.optional()
.describe('First meaningful user prompt in the session.'),
gitBranch: z
.string()
.optional()
.describe('Git branch at the end of the session.'),
cwd: z.string().optional().describe('Working directory for the session.'),
tag: z.string().optional().describe('User-set session tag.'),
createdAt: z
.number()
.optional()
.describe(
"Creation time in milliseconds since epoch, extracted from the first entry's timestamp.",
),
})
.describe('Session metadata returned by listSessions and getSessionInfo.'),
)
export const SDKMessageSchema = lazySchema(() =>
z.union([
SDKAssistantMessageSchema(),
SDKUserMessageSchema(),
SDKUserMessageReplaySchema(),
SDKResultMessageSchema(),
SDKSystemMessageSchema(),
SDKPartialAssistantMessageSchema(),
SDKCompactBoundaryMessageSchema(),
SDKStatusMessageSchema(),
SDKAPIRetryMessageSchema(),
SDKLocalCommandOutputMessageSchema(),
SDKHookStartedMessageSchema(),
SDKHookProgressMessageSchema(),
SDKHookResponseMessageSchema(),
SDKToolProgressMessageSchema(),
SDKAuthStatusMessageSchema(),
SDKTaskNotificationMessageSchema(),
SDKTaskStartedMessageSchema(),
SDKTaskProgressMessageSchema(),
SDKSessionStateChangedMessageSchema(),
SDKFilesPersistedEventSchema(),
SDKToolUseSummaryMessageSchema(),
SDKRateLimitEventSchema(),
SDKElicitationCompleteMessageSchema(),
SDKPromptSuggestionMessageSchema(),
]),
)
export const FastModeStateSchema = lazySchema(() =>
z
.enum(['off', 'cooldown', 'on'])
.describe(
'Fast mode state: off, in cooldown after rate limit, or actively enabled.',
),
)