coreSchemas.ts
1 /** 2 * SDK Core Schemas - Zod schemas for serializable SDK data types. 3 * 4 * These schemas are the single source of truth for SDK data types. 5 * TypeScript types are generated from these schemas and committed for IDE support. 6 * 7 * @see scripts/generate-sdk-types.ts for type generation 8 */ 9 10 import { z } from 'zod/v4' 11 import { lazySchema } from '../../utils/lazySchema.js' 12 13 // ============================================================================ 14 // Usage & Model Types 15 // ============================================================================ 16 17 export const ModelUsageSchema = lazySchema(() => 18 z.object({ 19 inputTokens: z.number(), 20 outputTokens: z.number(), 21 cacheReadInputTokens: z.number(), 22 cacheCreationInputTokens: z.number(), 23 webSearchRequests: z.number(), 24 costUSD: z.number(), 25 contextWindow: z.number(), 26 maxOutputTokens: z.number(), 27 }), 28 ) 29 30 // ============================================================================ 31 // Output Format Types 32 // ============================================================================ 33 34 export const OutputFormatTypeSchema = lazySchema(() => z.literal('json_schema')) 35 36 export const BaseOutputFormatSchema = lazySchema(() => 37 z.object({ 38 type: OutputFormatTypeSchema(), 39 }), 40 ) 41 42 export const JsonSchemaOutputFormatSchema = lazySchema(() => 43 z.object({ 44 type: z.literal('json_schema'), 45 schema: z.record(z.string(), z.unknown()), 46 }), 47 ) 48 49 export const OutputFormatSchema = lazySchema(() => 50 JsonSchemaOutputFormatSchema(), 51 ) 52 53 // ============================================================================ 54 // Config Types 55 // ============================================================================ 56 57 export const ApiKeySourceSchema = lazySchema(() => 58 z.enum(['user', 'project', 'org', 'temporary', 'oauth']), 59 ) 60 61 export const ConfigScopeSchema = lazySchema(() => 62 z.enum(['local', 'user', 'project']).describe('Config scope for settings.'), 63 ) 64 65 export const SdkBetaSchema = lazySchema(() => 66 z.literal('context-1m-2025-08-07'), 67 ) 68 69 export const ThinkingAdaptiveSchema = lazySchema(() => 70 z 71 .object({ 72 type: z.literal('adaptive'), 73 }) 74 .describe('Claude decides when and how much to think (Opus 4.6+).'), 75 ) 76 77 export const ThinkingEnabledSchema = lazySchema(() => 78 z 79 .object({ 80 type: z.literal('enabled'), 81 budgetTokens: z.number().optional(), 82 }) 83 .describe('Fixed thinking token budget (older models)'), 84 ) 85 86 export const ThinkingDisabledSchema = lazySchema(() => 87 z 88 .object({ 89 type: z.literal('disabled'), 90 }) 91 .describe('No extended thinking'), 92 ) 93 94 export const ThinkingConfigSchema = lazySchema(() => 95 z 96 .union([ 97 ThinkingAdaptiveSchema(), 98 ThinkingEnabledSchema(), 99 ThinkingDisabledSchema(), 100 ]) 101 .describe( 102 "Controls Claude's thinking/reasoning behavior. When set, takes precedence over the deprecated maxThinkingTokens.", 103 ), 104 ) 105 106 // ============================================================================ 107 // MCP Server Config Types (serializable only) 108 // ============================================================================ 109 110 export const McpStdioServerConfigSchema = lazySchema(() => 111 z.object({ 112 type: z.literal('stdio').optional(), // Optional for backwards compatibility 113 command: z.string(), 114 args: z.array(z.string()).optional(), 115 env: z.record(z.string(), z.string()).optional(), 116 }), 117 ) 118 119 export const McpSSEServerConfigSchema = lazySchema(() => 120 z.object({ 121 type: z.literal('sse'), 122 url: z.string(), 123 headers: z.record(z.string(), z.string()).optional(), 124 }), 125 ) 126 127 export const McpHttpServerConfigSchema = lazySchema(() => 128 z.object({ 129 type: z.literal('http'), 130 url: z.string(), 131 headers: z.record(z.string(), z.string()).optional(), 132 }), 133 ) 134 135 export const McpSdkServerConfigSchema = lazySchema(() => 136 z.object({ 137 type: z.literal('sdk'), 138 name: z.string(), 139 }), 140 ) 141 142 export const McpServerConfigForProcessTransportSchema = lazySchema(() => 143 z.union([ 144 McpStdioServerConfigSchema(), 145 McpSSEServerConfigSchema(), 146 McpHttpServerConfigSchema(), 147 McpSdkServerConfigSchema(), 148 ]), 149 ) 150 151 export const McpClaudeAIProxyServerConfigSchema = lazySchema(() => 152 z.object({ 153 type: z.literal('claudeai-proxy'), 154 url: z.string(), 155 id: z.string(), 156 }), 157 ) 158 159 // Broader config type for status responses (includes claudeai-proxy which is output-only) 160 export const McpServerStatusConfigSchema = lazySchema(() => 161 z.union([ 162 McpServerConfigForProcessTransportSchema(), 163 McpClaudeAIProxyServerConfigSchema(), 164 ]), 165 ) 166 167 export const McpServerStatusSchema = lazySchema(() => 168 z 169 .object({ 170 name: z.string().describe('Server name as configured'), 171 status: z 172 .enum(['connected', 'failed', 'needs-auth', 'pending', 'disabled']) 173 .describe('Current connection status'), 174 serverInfo: z 175 .object({ 176 name: z.string(), 177 version: z.string(), 178 }) 179 .optional() 180 .describe('Server information (available when connected)'), 181 error: z 182 .string() 183 .optional() 184 .describe("Error message (available when status is 'failed')"), 185 config: McpServerStatusConfigSchema() 186 .optional() 187 .describe('Server configuration (includes URL for HTTP/SSE servers)'), 188 scope: z 189 .string() 190 .optional() 191 .describe( 192 'Configuration scope (e.g., project, user, local, claudeai, managed)', 193 ), 194 tools: z 195 .array( 196 z.object({ 197 name: z.string(), 198 description: z.string().optional(), 199 annotations: z 200 .object({ 201 readOnly: z.boolean().optional(), 202 destructive: z.boolean().optional(), 203 openWorld: z.boolean().optional(), 204 }) 205 .optional(), 206 }), 207 ) 208 .optional() 209 .describe('Tools provided by this server (available when connected)'), 210 capabilities: z 211 .object({ 212 experimental: z.record(z.string(), z.unknown()).optional(), 213 }) 214 .optional() 215 .describe( 216 "@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.", 217 ), 218 }) 219 .describe('Status information for an MCP server connection.'), 220 ) 221 222 export const McpSetServersResultSchema = lazySchema(() => 223 z 224 .object({ 225 added: z.array(z.string()).describe('Names of servers that were added'), 226 removed: z 227 .array(z.string()) 228 .describe('Names of servers that were removed'), 229 errors: z 230 .record(z.string(), z.string()) 231 .describe( 232 'Map of server names to error messages for servers that failed to connect', 233 ), 234 }) 235 .describe('Result of a setMcpServers operation.'), 236 ) 237 238 // ============================================================================ 239 // Permission Types 240 // ============================================================================ 241 242 export const PermissionUpdateDestinationSchema = lazySchema(() => 243 z.enum([ 244 'userSettings', 245 'projectSettings', 246 'localSettings', 247 'session', 248 'cliArg', 249 ]), 250 ) 251 252 export const PermissionBehaviorSchema = lazySchema(() => 253 z.enum(['allow', 'deny', 'ask']), 254 ) 255 256 export const PermissionRuleValueSchema = lazySchema(() => 257 z.object({ 258 toolName: z.string(), 259 ruleContent: z.string().optional(), 260 }), 261 ) 262 263 export const PermissionUpdateSchema = lazySchema(() => 264 z.discriminatedUnion('type', [ 265 z.object({ 266 type: z.literal('addRules'), 267 rules: z.array(PermissionRuleValueSchema()), 268 behavior: PermissionBehaviorSchema(), 269 destination: PermissionUpdateDestinationSchema(), 270 }), 271 z.object({ 272 type: z.literal('replaceRules'), 273 rules: z.array(PermissionRuleValueSchema()), 274 behavior: PermissionBehaviorSchema(), 275 destination: PermissionUpdateDestinationSchema(), 276 }), 277 z.object({ 278 type: z.literal('removeRules'), 279 rules: z.array(PermissionRuleValueSchema()), 280 behavior: PermissionBehaviorSchema(), 281 destination: PermissionUpdateDestinationSchema(), 282 }), 283 z.object({ 284 type: z.literal('setMode'), 285 mode: z.lazy(() => PermissionModeSchema()), 286 destination: PermissionUpdateDestinationSchema(), 287 }), 288 z.object({ 289 type: z.literal('addDirectories'), 290 directories: z.array(z.string()), 291 destination: PermissionUpdateDestinationSchema(), 292 }), 293 z.object({ 294 type: z.literal('removeDirectories'), 295 directories: z.array(z.string()), 296 destination: PermissionUpdateDestinationSchema(), 297 }), 298 ]), 299 ) 300 301 export const PermissionDecisionClassificationSchema = lazySchema(() => 302 z 303 .enum(['user_temporary', 'user_permanent', 'user_reject']) 304 .describe( 305 'Classification of this permission decision for telemetry. SDK hosts ' + 306 'that prompt users (desktop apps, IDEs) should set this to reflect ' + 307 'what actually happened: user_temporary for allow-once, user_permanent ' + 308 'for always-allow (both the click and later cache hits), user_reject ' + 309 'for deny. If unset, the CLI infers conservatively (temporary for ' + 310 'allow, reject for deny). The vocabulary matches tool_decision OTel ' + 311 'events (monitoring-usage docs).', 312 ), 313 ) 314 315 export const PermissionResultSchema = lazySchema(() => 316 z.union([ 317 z.object({ 318 behavior: z.literal('allow'), 319 // Optional - may not be provided if hook sets permission without input modification 320 updatedInput: z.record(z.string(), z.unknown()).optional(), 321 updatedPermissions: z.array(PermissionUpdateSchema()).optional(), 322 toolUseID: z.string().optional(), 323 decisionClassification: 324 PermissionDecisionClassificationSchema().optional(), 325 }), 326 z.object({ 327 behavior: z.literal('deny'), 328 message: z.string(), 329 interrupt: z.boolean().optional(), 330 toolUseID: z.string().optional(), 331 decisionClassification: 332 PermissionDecisionClassificationSchema().optional(), 333 }), 334 ]), 335 ) 336 337 export const PermissionModeSchema = lazySchema(() => 338 z 339 .enum(['default', 'acceptEdits', 'bypassPermissions', 'plan', 'dontAsk']) 340 .describe( 341 'Permission mode for controlling how tool executions are handled. ' + 342 "'default' - Standard behavior, prompts for dangerous operations. " + 343 "'acceptEdits' - Auto-accept file edit operations. " + 344 "'bypassPermissions' - Bypass all permission checks (requires allowDangerouslySkipPermissions). " + 345 "'plan' - Planning mode, no actual tool execution. " + 346 "'dontAsk' - Don't prompt for permissions, deny if not pre-approved.", 347 ), 348 ) 349 350 351 // ============================================================================ 352 // Hook Types 353 // ============================================================================ 354 355 export const HOOK_EVENTS = [ 356 'PreToolUse', 357 'PostToolUse', 358 'PostToolUseFailure', 359 'Notification', 360 'UserPromptSubmit', 361 'SessionStart', 362 'SessionEnd', 363 'Stop', 364 'StopFailure', 365 'SubagentStart', 366 'SubagentStop', 367 'PreCompact', 368 'PostCompact', 369 'PermissionRequest', 370 'PermissionDenied', 371 'Setup', 372 'TeammateIdle', 373 'TaskCreated', 374 'TaskCompleted', 375 'Elicitation', 376 'ElicitationResult', 377 'ConfigChange', 378 'WorktreeCreate', 379 'WorktreeRemove', 380 'InstructionsLoaded', 381 'CwdChanged', 382 'FileChanged', 383 ] as const 384 385 export const HookEventSchema = lazySchema(() => z.enum(HOOK_EVENTS)) 386 387 export const BaseHookInputSchema = lazySchema(() => 388 z.object({ 389 session_id: z.string(), 390 transcript_path: z.string(), 391 cwd: z.string(), 392 permission_mode: z.string().optional(), 393 agent_id: z 394 .string() 395 .optional() 396 .describe( 397 'Subagent identifier. Present only when the hook fires from within a subagent ' + 398 '(e.g., a tool called by an AgentTool worker). Absent for the main thread, ' + 399 'even in --agent sessions. Use this field (not agent_type) to distinguish ' + 400 'subagent calls from main-thread calls.', 401 ), 402 agent_type: z 403 .string() 404 .optional() 405 .describe( 406 'Agent type name (e.g., "general-purpose", "code-reviewer"). Present when the ' + 407 'hook fires from within a subagent (alongside agent_id), or on the main thread ' + 408 'of a session started with --agent (without agent_id).', 409 ), 410 }), 411 ) 412 413 // Use .and() instead of .extend() to preserve BaseHookInput & {...} in generated types 414 export const PreToolUseHookInputSchema = lazySchema(() => 415 BaseHookInputSchema().and( 416 z.object({ 417 hook_event_name: z.literal('PreToolUse'), 418 tool_name: z.string(), 419 tool_input: z.unknown(), 420 tool_use_id: z.string(), 421 }), 422 ), 423 ) 424 425 export const PermissionRequestHookInputSchema = lazySchema(() => 426 BaseHookInputSchema().and( 427 z.object({ 428 hook_event_name: z.literal('PermissionRequest'), 429 tool_name: z.string(), 430 tool_input: z.unknown(), 431 permission_suggestions: z.array(PermissionUpdateSchema()).optional(), 432 }), 433 ), 434 ) 435 436 export const PostToolUseHookInputSchema = lazySchema(() => 437 BaseHookInputSchema().and( 438 z.object({ 439 hook_event_name: z.literal('PostToolUse'), 440 tool_name: z.string(), 441 tool_input: z.unknown(), 442 tool_response: z.unknown(), 443 tool_use_id: z.string(), 444 }), 445 ), 446 ) 447 448 export const PostToolUseFailureHookInputSchema = lazySchema(() => 449 BaseHookInputSchema().and( 450 z.object({ 451 hook_event_name: z.literal('PostToolUseFailure'), 452 tool_name: z.string(), 453 tool_input: z.unknown(), 454 tool_use_id: z.string(), 455 error: z.string(), 456 is_interrupt: z.boolean().optional(), 457 }), 458 ), 459 ) 460 461 export const PermissionDeniedHookInputSchema = lazySchema(() => 462 BaseHookInputSchema().and( 463 z.object({ 464 hook_event_name: z.literal('PermissionDenied'), 465 tool_name: z.string(), 466 tool_input: z.unknown(), 467 tool_use_id: z.string(), 468 reason: z.string(), 469 }), 470 ), 471 ) 472 473 export const NotificationHookInputSchema = lazySchema(() => 474 BaseHookInputSchema().and( 475 z.object({ 476 hook_event_name: z.literal('Notification'), 477 message: z.string(), 478 title: z.string().optional(), 479 notification_type: z.string(), 480 }), 481 ), 482 ) 483 484 export const UserPromptSubmitHookInputSchema = lazySchema(() => 485 BaseHookInputSchema().and( 486 z.object({ 487 hook_event_name: z.literal('UserPromptSubmit'), 488 prompt: z.string(), 489 }), 490 ), 491 ) 492 493 export const SessionStartHookInputSchema = lazySchema(() => 494 BaseHookInputSchema().and( 495 z.object({ 496 hook_event_name: z.literal('SessionStart'), 497 source: z.enum(['startup', 'resume', 'clear', 'compact']), 498 agent_type: z.string().optional(), 499 model: z.string().optional(), 500 }), 501 ), 502 ) 503 504 export const SetupHookInputSchema = lazySchema(() => 505 BaseHookInputSchema().and( 506 z.object({ 507 hook_event_name: z.literal('Setup'), 508 trigger: z.enum(['init', 'maintenance']), 509 }), 510 ), 511 ) 512 513 export const StopHookInputSchema = lazySchema(() => 514 BaseHookInputSchema().and( 515 z.object({ 516 hook_event_name: z.literal('Stop'), 517 stop_hook_active: z.boolean(), 518 last_assistant_message: z 519 .string() 520 .optional() 521 .describe( 522 'Text content of the last assistant message before stopping. ' + 523 'Avoids the need to read and parse the transcript file.', 524 ), 525 }), 526 ), 527 ) 528 529 export const StopFailureHookInputSchema = lazySchema(() => 530 BaseHookInputSchema().and( 531 z.object({ 532 hook_event_name: z.literal('StopFailure'), 533 error: SDKAssistantMessageErrorSchema(), 534 error_details: z.string().optional(), 535 last_assistant_message: z.string().optional(), 536 }), 537 ), 538 ) 539 540 export const SubagentStartHookInputSchema = lazySchema(() => 541 BaseHookInputSchema().and( 542 z.object({ 543 hook_event_name: z.literal('SubagentStart'), 544 agent_id: z.string(), 545 agent_type: z.string(), 546 }), 547 ), 548 ) 549 550 export const SubagentStopHookInputSchema = lazySchema(() => 551 BaseHookInputSchema().and( 552 z.object({ 553 hook_event_name: z.literal('SubagentStop'), 554 stop_hook_active: z.boolean(), 555 agent_id: z.string(), 556 agent_transcript_path: z.string(), 557 agent_type: z.string(), 558 last_assistant_message: z 559 .string() 560 .optional() 561 .describe( 562 'Text content of the last assistant message before stopping. ' + 563 'Avoids the need to read and parse the transcript file.', 564 ), 565 }), 566 ), 567 ) 568 569 export const PreCompactHookInputSchema = lazySchema(() => 570 BaseHookInputSchema().and( 571 z.object({ 572 hook_event_name: z.literal('PreCompact'), 573 trigger: z.enum(['manual', 'auto']), 574 custom_instructions: z.string().nullable(), 575 }), 576 ), 577 ) 578 579 export const PostCompactHookInputSchema = lazySchema(() => 580 BaseHookInputSchema().and( 581 z.object({ 582 hook_event_name: z.literal('PostCompact'), 583 trigger: z.enum(['manual', 'auto']), 584 compact_summary: z 585 .string() 586 .describe('The conversation summary produced by compaction'), 587 }), 588 ), 589 ) 590 591 export const TeammateIdleHookInputSchema = lazySchema(() => 592 BaseHookInputSchema().and( 593 z.object({ 594 hook_event_name: z.literal('TeammateIdle'), 595 teammate_name: z.string(), 596 team_name: z.string(), 597 }), 598 ), 599 ) 600 601 export const TaskCreatedHookInputSchema = lazySchema(() => 602 BaseHookInputSchema().and( 603 z.object({ 604 hook_event_name: z.literal('TaskCreated'), 605 task_id: z.string(), 606 task_subject: z.string(), 607 task_description: z.string().optional(), 608 teammate_name: z.string().optional(), 609 team_name: z.string().optional(), 610 }), 611 ), 612 ) 613 614 export const TaskCompletedHookInputSchema = lazySchema(() => 615 BaseHookInputSchema().and( 616 z.object({ 617 hook_event_name: z.literal('TaskCompleted'), 618 task_id: z.string(), 619 task_subject: z.string(), 620 task_description: z.string().optional(), 621 teammate_name: z.string().optional(), 622 team_name: z.string().optional(), 623 }), 624 ), 625 ) 626 627 export const ElicitationHookInputSchema = lazySchema(() => 628 BaseHookInputSchema() 629 .and( 630 z.object({ 631 hook_event_name: z.literal('Elicitation'), 632 mcp_server_name: z.string(), 633 message: z.string(), 634 mode: z.enum(['form', 'url']).optional(), 635 url: z.string().optional(), 636 elicitation_id: z.string().optional(), 637 requested_schema: z.record(z.string(), z.unknown()).optional(), 638 }), 639 ) 640 .describe( 641 '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.', 642 ), 643 ) 644 645 export const ElicitationResultHookInputSchema = lazySchema(() => 646 BaseHookInputSchema() 647 .and( 648 z.object({ 649 hook_event_name: z.literal('ElicitationResult'), 650 mcp_server_name: z.string(), 651 elicitation_id: z.string().optional(), 652 mode: z.enum(['form', 'url']).optional(), 653 action: z.enum(['accept', 'decline', 'cancel']), 654 content: z.record(z.string(), z.unknown()).optional(), 655 }), 656 ) 657 .describe( 658 '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.', 659 ), 660 ) 661 662 export const CONFIG_CHANGE_SOURCES = [ 663 'user_settings', 664 'project_settings', 665 'local_settings', 666 'policy_settings', 667 'skills', 668 ] as const 669 670 export const ConfigChangeHookInputSchema = lazySchema(() => 671 BaseHookInputSchema().and( 672 z.object({ 673 hook_event_name: z.literal('ConfigChange'), 674 source: z.enum(CONFIG_CHANGE_SOURCES), 675 file_path: z.string().optional(), 676 }), 677 ), 678 ) 679 680 export const INSTRUCTIONS_LOAD_REASONS = [ 681 'session_start', 682 'nested_traversal', 683 'path_glob_match', 684 'include', 685 'compact', 686 ] as const 687 688 export const INSTRUCTIONS_MEMORY_TYPES = [ 689 'User', 690 'Project', 691 'Local', 692 'Managed', 693 ] as const 694 695 export const InstructionsLoadedHookInputSchema = lazySchema(() => 696 BaseHookInputSchema().and( 697 z.object({ 698 hook_event_name: z.literal('InstructionsLoaded'), 699 file_path: z.string(), 700 memory_type: z.enum(INSTRUCTIONS_MEMORY_TYPES), 701 load_reason: z.enum(INSTRUCTIONS_LOAD_REASONS), 702 globs: z.array(z.string()).optional(), 703 trigger_file_path: z.string().optional(), 704 parent_file_path: z.string().optional(), 705 }), 706 ), 707 ) 708 709 export const WorktreeCreateHookInputSchema = lazySchema(() => 710 BaseHookInputSchema().and( 711 z.object({ 712 hook_event_name: z.literal('WorktreeCreate'), 713 name: z.string(), 714 }), 715 ), 716 ) 717 718 export const WorktreeRemoveHookInputSchema = lazySchema(() => 719 BaseHookInputSchema().and( 720 z.object({ 721 hook_event_name: z.literal('WorktreeRemove'), 722 worktree_path: z.string(), 723 }), 724 ), 725 ) 726 727 export const CwdChangedHookInputSchema = lazySchema(() => 728 BaseHookInputSchema().and( 729 z.object({ 730 hook_event_name: z.literal('CwdChanged'), 731 old_cwd: z.string(), 732 new_cwd: z.string(), 733 }), 734 ), 735 ) 736 737 export const FileChangedHookInputSchema = lazySchema(() => 738 BaseHookInputSchema().and( 739 z.object({ 740 hook_event_name: z.literal('FileChanged'), 741 file_path: z.string(), 742 event: z.enum(['change', 'add', 'unlink']), 743 }), 744 ), 745 ) 746 747 export const EXIT_REASONS = [ 748 'clear', 749 'resume', 750 'logout', 751 'prompt_input_exit', 752 'other', 753 'bypass_permissions_disabled', 754 ] as const 755 756 export const ExitReasonSchema = lazySchema(() => z.enum(EXIT_REASONS)) 757 758 export const SessionEndHookInputSchema = lazySchema(() => 759 BaseHookInputSchema().and( 760 z.object({ 761 hook_event_name: z.literal('SessionEnd'), 762 reason: ExitReasonSchema(), 763 }), 764 ), 765 ) 766 767 export const HookInputSchema = lazySchema(() => 768 z.union([ 769 PreToolUseHookInputSchema(), 770 PostToolUseHookInputSchema(), 771 PostToolUseFailureHookInputSchema(), 772 PermissionDeniedHookInputSchema(), 773 NotificationHookInputSchema(), 774 UserPromptSubmitHookInputSchema(), 775 SessionStartHookInputSchema(), 776 SessionEndHookInputSchema(), 777 StopHookInputSchema(), 778 StopFailureHookInputSchema(), 779 SubagentStartHookInputSchema(), 780 SubagentStopHookInputSchema(), 781 PreCompactHookInputSchema(), 782 PostCompactHookInputSchema(), 783 PermissionRequestHookInputSchema(), 784 SetupHookInputSchema(), 785 TeammateIdleHookInputSchema(), 786 TaskCreatedHookInputSchema(), 787 TaskCompletedHookInputSchema(), 788 ElicitationHookInputSchema(), 789 ElicitationResultHookInputSchema(), 790 ConfigChangeHookInputSchema(), 791 InstructionsLoadedHookInputSchema(), 792 WorktreeCreateHookInputSchema(), 793 WorktreeRemoveHookInputSchema(), 794 CwdChangedHookInputSchema(), 795 FileChangedHookInputSchema(), 796 ]), 797 ) 798 799 export const AsyncHookJSONOutputSchema = lazySchema(() => 800 z.object({ 801 async: z.literal(true), 802 asyncTimeout: z.number().optional(), 803 }), 804 ) 805 806 export const PreToolUseHookSpecificOutputSchema = lazySchema(() => 807 z.object({ 808 hookEventName: z.literal('PreToolUse'), 809 permissionDecision: PermissionBehaviorSchema().optional(), 810 permissionDecisionReason: z.string().optional(), 811 updatedInput: z.record(z.string(), z.unknown()).optional(), 812 additionalContext: z.string().optional(), 813 }), 814 ) 815 816 export const UserPromptSubmitHookSpecificOutputSchema = lazySchema(() => 817 z.object({ 818 hookEventName: z.literal('UserPromptSubmit'), 819 additionalContext: z.string().optional(), 820 }), 821 ) 822 823 export const SessionStartHookSpecificOutputSchema = lazySchema(() => 824 z.object({ 825 hookEventName: z.literal('SessionStart'), 826 additionalContext: z.string().optional(), 827 initialUserMessage: z.string().optional(), 828 watchPaths: z.array(z.string()).optional(), 829 }), 830 ) 831 832 export const SetupHookSpecificOutputSchema = lazySchema(() => 833 z.object({ 834 hookEventName: z.literal('Setup'), 835 additionalContext: z.string().optional(), 836 }), 837 ) 838 839 export const SubagentStartHookSpecificOutputSchema = lazySchema(() => 840 z.object({ 841 hookEventName: z.literal('SubagentStart'), 842 additionalContext: z.string().optional(), 843 }), 844 ) 845 846 export const PostToolUseHookSpecificOutputSchema = lazySchema(() => 847 z.object({ 848 hookEventName: z.literal('PostToolUse'), 849 additionalContext: z.string().optional(), 850 updatedMCPToolOutput: z.unknown().optional(), 851 }), 852 ) 853 854 export const PostToolUseFailureHookSpecificOutputSchema = lazySchema(() => 855 z.object({ 856 hookEventName: z.literal('PostToolUseFailure'), 857 additionalContext: z.string().optional(), 858 }), 859 ) 860 861 export const PermissionDeniedHookSpecificOutputSchema = lazySchema(() => 862 z.object({ 863 hookEventName: z.literal('PermissionDenied'), 864 retry: z.boolean().optional(), 865 }), 866 ) 867 868 export const NotificationHookSpecificOutputSchema = lazySchema(() => 869 z.object({ 870 hookEventName: z.literal('Notification'), 871 additionalContext: z.string().optional(), 872 }), 873 ) 874 875 export const PermissionRequestHookSpecificOutputSchema = lazySchema(() => 876 z.object({ 877 hookEventName: z.literal('PermissionRequest'), 878 decision: z.union([ 879 z.object({ 880 behavior: z.literal('allow'), 881 updatedInput: z.record(z.string(), z.unknown()).optional(), 882 updatedPermissions: z.array(PermissionUpdateSchema()).optional(), 883 }), 884 z.object({ 885 behavior: z.literal('deny'), 886 message: z.string().optional(), 887 interrupt: z.boolean().optional(), 888 }), 889 ]), 890 }), 891 ) 892 893 export const CwdChangedHookSpecificOutputSchema = lazySchema(() => 894 z.object({ 895 hookEventName: z.literal('CwdChanged'), 896 watchPaths: z.array(z.string()).optional(), 897 }), 898 ) 899 900 export const FileChangedHookSpecificOutputSchema = lazySchema(() => 901 z.object({ 902 hookEventName: z.literal('FileChanged'), 903 watchPaths: z.array(z.string()).optional(), 904 }), 905 ) 906 907 export const SyncHookJSONOutputSchema = lazySchema(() => 908 z.object({ 909 continue: z.boolean().optional(), 910 suppressOutput: z.boolean().optional(), 911 stopReason: z.string().optional(), 912 decision: z.enum(['approve', 'block']).optional(), 913 systemMessage: z.string().optional(), 914 reason: z.string().optional(), 915 hookSpecificOutput: z 916 .union([ 917 PreToolUseHookSpecificOutputSchema(), 918 UserPromptSubmitHookSpecificOutputSchema(), 919 SessionStartHookSpecificOutputSchema(), 920 SetupHookSpecificOutputSchema(), 921 SubagentStartHookSpecificOutputSchema(), 922 PostToolUseHookSpecificOutputSchema(), 923 PostToolUseFailureHookSpecificOutputSchema(), 924 PermissionDeniedHookSpecificOutputSchema(), 925 NotificationHookSpecificOutputSchema(), 926 PermissionRequestHookSpecificOutputSchema(), 927 ElicitationHookSpecificOutputSchema(), 928 ElicitationResultHookSpecificOutputSchema(), 929 CwdChangedHookSpecificOutputSchema(), 930 FileChangedHookSpecificOutputSchema(), 931 WorktreeCreateHookSpecificOutputSchema(), 932 ]) 933 .optional(), 934 }), 935 ) 936 937 export const ElicitationHookSpecificOutputSchema = lazySchema(() => 938 z 939 .object({ 940 hookEventName: z.literal('Elicitation'), 941 action: z.enum(['accept', 'decline', 'cancel']).optional(), 942 content: z.record(z.string(), z.unknown()).optional(), 943 }) 944 .describe( 945 'Hook-specific output for the Elicitation event. Return this to programmatically accept or decline an MCP elicitation request.', 946 ), 947 ) 948 949 export const ElicitationResultHookSpecificOutputSchema = lazySchema(() => 950 z 951 .object({ 952 hookEventName: z.literal('ElicitationResult'), 953 action: z.enum(['accept', 'decline', 'cancel']).optional(), 954 content: z.record(z.string(), z.unknown()).optional(), 955 }) 956 .describe( 957 'Hook-specific output for the ElicitationResult event. Return this to override the action or content before the response is sent to the MCP server.', 958 ), 959 ) 960 961 export const WorktreeCreateHookSpecificOutputSchema = lazySchema(() => 962 z 963 .object({ 964 hookEventName: z.literal('WorktreeCreate'), 965 worktreePath: z.string(), 966 }) 967 .describe( 968 'Hook-specific output for the WorktreeCreate event. Provides the absolute path to the created worktree directory. Command hooks print the path on stdout instead.', 969 ), 970 ) 971 972 export const HookJSONOutputSchema = lazySchema(() => 973 z.union([AsyncHookJSONOutputSchema(), SyncHookJSONOutputSchema()]), 974 ) 975 976 export const PromptRequestOptionSchema = lazySchema(() => 977 z.object({ 978 key: z 979 .string() 980 .describe('Unique key for this option, returned in the response'), 981 label: z.string().describe('Display text for this option'), 982 description: z 983 .string() 984 .optional() 985 .describe('Optional description shown below the label'), 986 }), 987 ) 988 989 export const PromptRequestSchema = lazySchema(() => 990 z.object({ 991 prompt: z 992 .string() 993 .describe( 994 'Request ID. Presence of this key marks the line as a prompt request.', 995 ), 996 message: z.string().describe('The prompt message to display to the user'), 997 options: z 998 .array(PromptRequestOptionSchema()) 999 .describe('Available options for the user to choose from'), 1000 }), 1001 ) 1002 1003 export const PromptResponseSchema = lazySchema(() => 1004 z.object({ 1005 prompt_response: z 1006 .string() 1007 .describe('The request ID from the corresponding prompt request'), 1008 selected: z.string().describe('The key of the selected option'), 1009 }), 1010 ) 1011 1012 // ============================================================================ 1013 // Skill/Command Types 1014 // ============================================================================ 1015 1016 export const SlashCommandSchema = lazySchema(() => 1017 z 1018 .object({ 1019 name: z.string().describe('Skill name (without the leading slash)'), 1020 description: z.string().describe('Description of what the skill does'), 1021 argumentHint: z 1022 .string() 1023 .describe('Hint for skill arguments (e.g., "<file>")'), 1024 }) 1025 .describe( 1026 'Information about an available skill (invoked via /command syntax).', 1027 ), 1028 ) 1029 1030 export const AgentInfoSchema = lazySchema(() => 1031 z 1032 .object({ 1033 name: z.string().describe('Agent type identifier (e.g., "Explore")'), 1034 description: z.string().describe('Description of when to use this agent'), 1035 model: z 1036 .string() 1037 .optional() 1038 .describe( 1039 "Model alias this agent uses. If omitted, inherits the parent's model", 1040 ), 1041 }) 1042 .describe( 1043 'Information about an available subagent that can be invoked via the Task tool.', 1044 ), 1045 ) 1046 1047 export const ModelInfoSchema = lazySchema(() => 1048 z 1049 .object({ 1050 value: z.string().describe('Model identifier to use in API calls'), 1051 displayName: z.string().describe('Human-readable display name'), 1052 description: z 1053 .string() 1054 .describe("Description of the model's capabilities"), 1055 supportsEffort: z 1056 .boolean() 1057 .optional() 1058 .describe('Whether this model supports effort levels'), 1059 supportedEffortLevels: z 1060 .array(z.enum(['low', 'medium', 'high', 'max'])) 1061 .optional() 1062 .describe('Available effort levels for this model'), 1063 supportsAdaptiveThinking: z 1064 .boolean() 1065 .optional() 1066 .describe( 1067 'Whether this model supports adaptive thinking (Claude decides when and how much to think)', 1068 ), 1069 supportsFastMode: z 1070 .boolean() 1071 .optional() 1072 .describe('Whether this model supports fast mode'), 1073 supportsAutoMode: z 1074 .boolean() 1075 .optional() 1076 .describe('Whether this model supports auto mode'), 1077 }) 1078 .describe('Information about an available model.'), 1079 ) 1080 1081 export const AccountInfoSchema = lazySchema(() => 1082 z 1083 .object({ 1084 email: z.string().optional(), 1085 organization: z.string().optional(), 1086 subscriptionType: z.string().optional(), 1087 tokenSource: z.string().optional(), 1088 apiKeySource: z.string().optional(), 1089 apiProvider: z 1090 .enum(['firstParty', 'bedrock', 'vertex', 'foundry']) 1091 .optional() 1092 .describe( 1093 '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.).', 1094 ), 1095 }) 1096 .describe("Information about the logged in user's account."), 1097 ) 1098 1099 // ============================================================================ 1100 // Agent Definition Types 1101 // ============================================================================ 1102 1103 export const AgentMcpServerSpecSchema = lazySchema(() => 1104 z.union([ 1105 z.string(), 1106 z.record(z.string(), McpServerConfigForProcessTransportSchema()), 1107 ]), 1108 ) 1109 1110 export const AgentDefinitionSchema = lazySchema(() => 1111 z 1112 .object({ 1113 description: z 1114 .string() 1115 .describe('Natural language description of when to use this agent'), 1116 tools: z 1117 .array(z.string()) 1118 .optional() 1119 .describe( 1120 'Array of allowed tool names. If omitted, inherits all tools from parent', 1121 ), 1122 disallowedTools: z 1123 .array(z.string()) 1124 .optional() 1125 .describe('Array of tool names to explicitly disallow for this agent'), 1126 prompt: z.string().describe("The agent's system prompt"), 1127 model: z 1128 .string() 1129 .optional() 1130 .describe( 1131 "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", 1132 ), 1133 mcpServers: z.array(AgentMcpServerSpecSchema()).optional(), 1134 criticalSystemReminder_EXPERIMENTAL: z 1135 .string() 1136 .optional() 1137 .describe('Experimental: Critical reminder added to system prompt'), 1138 skills: z 1139 .array(z.string()) 1140 .optional() 1141 .describe('Array of skill names to preload into the agent context'), 1142 initialPrompt: z 1143 .string() 1144 .optional() 1145 .describe( 1146 '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.', 1147 ), 1148 maxTurns: z 1149 .number() 1150 .int() 1151 .positive() 1152 .optional() 1153 .describe( 1154 'Maximum number of agentic turns (API round-trips) before stopping', 1155 ), 1156 background: z 1157 .boolean() 1158 .optional() 1159 .describe( 1160 'Run this agent as a background task (non-blocking, fire-and-forget) when invoked', 1161 ), 1162 memory: z 1163 .enum(['user', 'project', 'local']) 1164 .optional() 1165 .describe( 1166 "Scope for auto-loading agent memory files. 'user' - ~/.claude/agent-memory/<agentType>/, 'project' - .claude/agent-memory/<agentType>/, 'local' - .claude/agent-memory-local/<agentType>/", 1167 ), 1168 effort: z 1169 .union([z.enum(['low', 'medium', 'high', 'max']), z.number().int()]) 1170 .optional() 1171 .describe( 1172 'Reasoning effort level for this agent. Either a named level or an integer', 1173 ), 1174 permissionMode: PermissionModeSchema() 1175 .optional() 1176 .describe( 1177 'Permission mode controlling how tool executions are handled', 1178 ), 1179 }) 1180 .describe( 1181 'Definition for a custom subagent that can be invoked via the Agent tool.', 1182 ), 1183 ) 1184 1185 // ============================================================================ 1186 // Settings Types 1187 // ============================================================================ 1188 1189 export const SettingSourceSchema = lazySchema(() => 1190 z 1191 .enum(['user', 'project', 'local']) 1192 .describe( 1193 'Source for loading filesystem-based settings. ' + 1194 "'user' - Global user settings (~/.claude/settings.json). " + 1195 "'project' - Project settings (.claude/settings.json). " + 1196 "'local' - Local settings (.claude/settings.local.json).", 1197 ), 1198 ) 1199 1200 export const SdkPluginConfigSchema = lazySchema(() => 1201 z 1202 .object({ 1203 type: z 1204 .literal('local') 1205 .describe("Plugin type. Currently only 'local' is supported"), 1206 path: z 1207 .string() 1208 .describe('Absolute or relative path to the plugin directory'), 1209 }) 1210 .describe('Configuration for loading a plugin.'), 1211 ) 1212 1213 // ============================================================================ 1214 // Rewind Types 1215 // ============================================================================ 1216 1217 export const RewindFilesResultSchema = lazySchema(() => 1218 z 1219 .object({ 1220 canRewind: z.boolean(), 1221 error: z.string().optional(), 1222 filesChanged: z.array(z.string()).optional(), 1223 insertions: z.number().optional(), 1224 deletions: z.number().optional(), 1225 }) 1226 .describe('Result of a rewindFiles operation.'), 1227 ) 1228 1229 // ============================================================================ 1230 // External Type Placeholders 1231 // ============================================================================ 1232 // 1233 // These schemas use z.unknown() as placeholders for external types. 1234 // The generation script uses TypeOverrideMap to output the correct TS type references. 1235 // This allows us to define SDK message types in Zod while maintaining proper typing. 1236 1237 /** Placeholder for APIUserMessage from @anthropic-ai/sdk */ 1238 export const APIUserMessagePlaceholder = lazySchema(() => z.unknown()) 1239 1240 /** Placeholder for APIAssistantMessage from @anthropic-ai/sdk */ 1241 export const APIAssistantMessagePlaceholder = lazySchema(() => z.unknown()) 1242 1243 /** Placeholder for RawMessageStreamEvent from @anthropic-ai/sdk */ 1244 export const RawMessageStreamEventPlaceholder = lazySchema(() => z.unknown()) 1245 1246 /** Placeholder for UUID from crypto */ 1247 export const UUIDPlaceholder = lazySchema(() => z.string()) 1248 1249 /** Placeholder for NonNullableUsage (mapped type over Usage) */ 1250 export const NonNullableUsagePlaceholder = lazySchema(() => z.unknown()) 1251 1252 // ============================================================================ 1253 // SDK Message Types 1254 // ============================================================================ 1255 1256 export const SDKAssistantMessageErrorSchema = lazySchema(() => 1257 z.enum([ 1258 'authentication_failed', 1259 'billing_error', 1260 'rate_limit', 1261 'invalid_request', 1262 'server_error', 1263 'unknown', 1264 'max_output_tokens', 1265 ]), 1266 ) 1267 1268 export const SDKStatusSchema = lazySchema(() => 1269 z.union([z.literal('compacting'), z.null()]), 1270 ) 1271 1272 // SDKUserMessage content without uuid/session_id 1273 const SDKUserMessageContentSchema = lazySchema(() => 1274 z.object({ 1275 type: z.literal('user'), 1276 message: APIUserMessagePlaceholder(), 1277 parent_tool_use_id: z.string().nullable(), 1278 isSynthetic: z.boolean().optional(), 1279 tool_use_result: z.unknown().optional(), 1280 priority: z.enum(['now', 'next', 'later']).optional(), 1281 timestamp: z 1282 .string() 1283 .optional() 1284 .describe( 1285 'ISO timestamp when the message was created on the originating process. Older emitters omit it; consumers should fall back to receive time.', 1286 ), 1287 }), 1288 ) 1289 1290 export const SDKUserMessageSchema = lazySchema(() => 1291 SDKUserMessageContentSchema().extend({ 1292 uuid: UUIDPlaceholder().optional(), 1293 session_id: z.string().optional(), 1294 }), 1295 ) 1296 1297 export const SDKUserMessageReplaySchema = lazySchema(() => 1298 SDKUserMessageContentSchema().extend({ 1299 uuid: UUIDPlaceholder(), 1300 session_id: z.string(), 1301 isReplay: z.literal(true), 1302 }), 1303 ) 1304 1305 export const SDKRateLimitInfoSchema = lazySchema(() => 1306 z 1307 .object({ 1308 status: z.enum(['allowed', 'allowed_warning', 'rejected']), 1309 resetsAt: z.number().optional(), 1310 rateLimitType: z 1311 .enum([ 1312 'five_hour', 1313 'seven_day', 1314 'seven_day_opus', 1315 'seven_day_sonnet', 1316 'overage', 1317 ]) 1318 .optional(), 1319 utilization: z.number().optional(), 1320 overageStatus: z 1321 .enum(['allowed', 'allowed_warning', 'rejected']) 1322 .optional(), 1323 overageResetsAt: z.number().optional(), 1324 overageDisabledReason: z 1325 .enum([ 1326 'overage_not_provisioned', 1327 'org_level_disabled', 1328 'org_level_disabled_until', 1329 'out_of_credits', 1330 'seat_tier_level_disabled', 1331 'member_level_disabled', 1332 'seat_tier_zero_credit_limit', 1333 'group_zero_credit_limit', 1334 'member_zero_credit_limit', 1335 'org_service_level_disabled', 1336 'org_service_zero_credit_limit', 1337 'no_limits_configured', 1338 'unknown', 1339 ]) 1340 .optional(), 1341 isUsingOverage: z.boolean().optional(), 1342 surpassedThreshold: z.number().optional(), 1343 }) 1344 .describe('Rate limit information for claude.ai subscription users.'), 1345 ) 1346 1347 export const SDKAssistantMessageSchema = lazySchema(() => 1348 z.object({ 1349 type: z.literal('assistant'), 1350 message: APIAssistantMessagePlaceholder(), 1351 parent_tool_use_id: z.string().nullable(), 1352 error: SDKAssistantMessageErrorSchema().optional(), 1353 uuid: UUIDPlaceholder(), 1354 session_id: z.string(), 1355 }), 1356 ) 1357 1358 export const SDKRateLimitEventSchema = lazySchema(() => 1359 z 1360 .object({ 1361 type: z.literal('rate_limit_event'), 1362 rate_limit_info: SDKRateLimitInfoSchema(), 1363 uuid: UUIDPlaceholder(), 1364 session_id: z.string(), 1365 }) 1366 .describe('Rate limit event emitted when rate limit info changes.'), 1367 ) 1368 1369 export const SDKStreamlinedTextMessageSchema = lazySchema(() => 1370 z 1371 .object({ 1372 type: z.literal('streamlined_text'), 1373 text: z 1374 .string() 1375 .describe('Text content preserved from the assistant message'), 1376 session_id: z.string(), 1377 uuid: UUIDPlaceholder(), 1378 }) 1379 .describe( 1380 '@internal Streamlined text message - replaces SDKAssistantMessage in streamlined output. Text content preserved, thinking and tool_use blocks removed.', 1381 ), 1382 ) 1383 1384 export const SDKStreamlinedToolUseSummaryMessageSchema = lazySchema(() => 1385 z 1386 .object({ 1387 type: z.literal('streamlined_tool_use_summary'), 1388 tool_summary: z 1389 .string() 1390 .describe('Summary of tool calls (e.g., "Read 2 files, wrote 1 file")'), 1391 session_id: z.string(), 1392 uuid: UUIDPlaceholder(), 1393 }) 1394 .describe( 1395 '@internal Streamlined tool use summary - replaces tool_use blocks in streamlined output with a cumulative summary string.', 1396 ), 1397 ) 1398 1399 export const SDKPermissionDenialSchema = lazySchema(() => 1400 z.object({ 1401 tool_name: z.string(), 1402 tool_use_id: z.string(), 1403 tool_input: z.record(z.string(), z.unknown()), 1404 }), 1405 ) 1406 1407 export const SDKResultSuccessSchema = lazySchema(() => 1408 z.object({ 1409 type: z.literal('result'), 1410 subtype: z.literal('success'), 1411 duration_ms: z.number(), 1412 duration_api_ms: z.number(), 1413 is_error: z.boolean(), 1414 num_turns: z.number(), 1415 result: z.string(), 1416 stop_reason: z.string().nullable(), 1417 total_cost_usd: z.number(), 1418 usage: NonNullableUsagePlaceholder(), 1419 modelUsage: z.record(z.string(), ModelUsageSchema()), 1420 permission_denials: z.array(SDKPermissionDenialSchema()), 1421 structured_output: z.unknown().optional(), 1422 fast_mode_state: FastModeStateSchema().optional(), 1423 uuid: UUIDPlaceholder(), 1424 session_id: z.string(), 1425 }), 1426 ) 1427 1428 export const SDKResultErrorSchema = lazySchema(() => 1429 z.object({ 1430 type: z.literal('result'), 1431 subtype: z.enum([ 1432 'error_during_execution', 1433 'error_max_turns', 1434 'error_max_budget_usd', 1435 'error_max_structured_output_retries', 1436 ]), 1437 duration_ms: z.number(), 1438 duration_api_ms: z.number(), 1439 is_error: z.boolean(), 1440 num_turns: z.number(), 1441 stop_reason: z.string().nullable(), 1442 total_cost_usd: z.number(), 1443 usage: NonNullableUsagePlaceholder(), 1444 modelUsage: z.record(z.string(), ModelUsageSchema()), 1445 permission_denials: z.array(SDKPermissionDenialSchema()), 1446 errors: z.array(z.string()), 1447 fast_mode_state: FastModeStateSchema().optional(), 1448 uuid: UUIDPlaceholder(), 1449 session_id: z.string(), 1450 }), 1451 ) 1452 1453 export const SDKResultMessageSchema = lazySchema(() => 1454 z.union([SDKResultSuccessSchema(), SDKResultErrorSchema()]), 1455 ) 1456 1457 export const SDKSystemMessageSchema = lazySchema(() => 1458 z.object({ 1459 type: z.literal('system'), 1460 subtype: z.literal('init'), 1461 agents: z.array(z.string()).optional(), 1462 apiKeySource: ApiKeySourceSchema(), 1463 betas: z.array(z.string()).optional(), 1464 claude_code_version: z.string(), 1465 cwd: z.string(), 1466 tools: z.array(z.string()), 1467 mcp_servers: z.array( 1468 z.object({ 1469 name: z.string(), 1470 status: z.string(), 1471 }), 1472 ), 1473 model: z.string(), 1474 permissionMode: PermissionModeSchema(), 1475 slash_commands: z.array(z.string()), 1476 output_style: z.string(), 1477 skills: z.array(z.string()), 1478 plugins: z.array( 1479 z.object({ 1480 name: z.string(), 1481 path: z.string(), 1482 source: z 1483 .string() 1484 .optional() 1485 .describe( 1486 '@internal Plugin source identifier in "name\\@marketplace" format. Sentinels: "name\\@inline" for --plugin-dir, "name\\@builtin" for built-in plugins.', 1487 ), 1488 }), 1489 ), 1490 fast_mode_state: FastModeStateSchema().optional(), 1491 uuid: UUIDPlaceholder(), 1492 session_id: z.string(), 1493 }), 1494 ) 1495 1496 export const SDKPartialAssistantMessageSchema = lazySchema(() => 1497 z.object({ 1498 type: z.literal('stream_event'), 1499 event: RawMessageStreamEventPlaceholder(), 1500 parent_tool_use_id: z.string().nullable(), 1501 uuid: UUIDPlaceholder(), 1502 session_id: z.string(), 1503 }), 1504 ) 1505 1506 export const SDKCompactBoundaryMessageSchema = lazySchema(() => 1507 z.object({ 1508 type: z.literal('system'), 1509 subtype: z.literal('compact_boundary'), 1510 compact_metadata: z.object({ 1511 trigger: z.enum(['manual', 'auto']), 1512 pre_tokens: z.number(), 1513 preserved_segment: z 1514 .object({ 1515 head_uuid: UUIDPlaceholder(), 1516 anchor_uuid: UUIDPlaceholder(), 1517 tail_uuid: UUIDPlaceholder(), 1518 }) 1519 .optional() 1520 .describe( 1521 'Relink info for messagesToKeep. Loaders splice the preserved ' + 1522 'segment at anchor_uuid (summary for suffix-preserving, ' + 1523 'boundary for prefix-preserving partial compact) so resume ' + 1524 'includes preserved content. Unset when compaction summarizes ' + 1525 'everything (no messagesToKeep).', 1526 ), 1527 }), 1528 uuid: UUIDPlaceholder(), 1529 session_id: z.string(), 1530 }), 1531 ) 1532 1533 export const SDKStatusMessageSchema = lazySchema(() => 1534 z.object({ 1535 type: z.literal('system'), 1536 subtype: z.literal('status'), 1537 status: SDKStatusSchema(), 1538 permissionMode: PermissionModeSchema().optional(), 1539 uuid: UUIDPlaceholder(), 1540 session_id: z.string(), 1541 }), 1542 ) 1543 1544 export const SDKPostTurnSummaryMessageSchema = lazySchema(() => 1545 z 1546 .object({ 1547 type: z.literal('system'), 1548 subtype: z.literal('post_turn_summary'), 1549 summarizes_uuid: z.string(), 1550 status_category: z.enum([ 1551 'blocked', 1552 'waiting', 1553 'completed', 1554 'review_ready', 1555 'failed', 1556 ]), 1557 status_detail: z.string(), 1558 is_noteworthy: z.boolean(), 1559 title: z.string(), 1560 description: z.string(), 1561 recent_action: z.string(), 1562 needs_action: z.string(), 1563 artifact_urls: z.array(z.string()), 1564 uuid: UUIDPlaceholder(), 1565 session_id: z.string(), 1566 }) 1567 .describe( 1568 '@internal Background post-turn summary emitted after each assistant turn. summarizes_uuid points to the assistant message this summarizes.', 1569 ), 1570 ) 1571 1572 export const SDKAPIRetryMessageSchema = lazySchema(() => 1573 z 1574 .object({ 1575 type: z.literal('system'), 1576 subtype: z.literal('api_retry'), 1577 attempt: z.number(), 1578 max_retries: z.number(), 1579 retry_delay_ms: z.number(), 1580 error_status: z.number().nullable(), 1581 error: SDKAssistantMessageErrorSchema(), 1582 uuid: UUIDPlaceholder(), 1583 session_id: z.string(), 1584 }) 1585 .describe( 1586 '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.', 1587 ), 1588 ) 1589 1590 export const SDKLocalCommandOutputMessageSchema = lazySchema(() => 1591 z 1592 .object({ 1593 type: z.literal('system'), 1594 subtype: z.literal('local_command_output'), 1595 content: z.string(), 1596 uuid: UUIDPlaceholder(), 1597 session_id: z.string(), 1598 }) 1599 .describe( 1600 'Output from a local slash command (e.g. /voice, /cost). Displayed as assistant-style text in the transcript.', 1601 ), 1602 ) 1603 1604 export const SDKHookStartedMessageSchema = lazySchema(() => 1605 z.object({ 1606 type: z.literal('system'), 1607 subtype: z.literal('hook_started'), 1608 hook_id: z.string(), 1609 hook_name: z.string(), 1610 hook_event: z.string(), 1611 uuid: UUIDPlaceholder(), 1612 session_id: z.string(), 1613 }), 1614 ) 1615 1616 export const SDKHookProgressMessageSchema = lazySchema(() => 1617 z.object({ 1618 type: z.literal('system'), 1619 subtype: z.literal('hook_progress'), 1620 hook_id: z.string(), 1621 hook_name: z.string(), 1622 hook_event: z.string(), 1623 stdout: z.string(), 1624 stderr: z.string(), 1625 output: z.string(), 1626 uuid: UUIDPlaceholder(), 1627 session_id: z.string(), 1628 }), 1629 ) 1630 1631 export const SDKHookResponseMessageSchema = lazySchema(() => 1632 z.object({ 1633 type: z.literal('system'), 1634 subtype: z.literal('hook_response'), 1635 hook_id: z.string(), 1636 hook_name: z.string(), 1637 hook_event: z.string(), 1638 output: z.string(), 1639 stdout: z.string(), 1640 stderr: z.string(), 1641 exit_code: z.number().optional(), 1642 outcome: z.enum(['success', 'error', 'cancelled']), 1643 uuid: UUIDPlaceholder(), 1644 session_id: z.string(), 1645 }), 1646 ) 1647 1648 export const SDKToolProgressMessageSchema = lazySchema(() => 1649 z.object({ 1650 type: z.literal('tool_progress'), 1651 tool_use_id: z.string(), 1652 tool_name: z.string(), 1653 parent_tool_use_id: z.string().nullable(), 1654 elapsed_time_seconds: z.number(), 1655 task_id: z.string().optional(), 1656 uuid: UUIDPlaceholder(), 1657 session_id: z.string(), 1658 }), 1659 ) 1660 1661 export const SDKAuthStatusMessageSchema = lazySchema(() => 1662 z.object({ 1663 type: z.literal('auth_status'), 1664 isAuthenticating: z.boolean(), 1665 output: z.array(z.string()), 1666 error: z.string().optional(), 1667 uuid: UUIDPlaceholder(), 1668 session_id: z.string(), 1669 }), 1670 ) 1671 1672 export const SDKFilesPersistedEventSchema = lazySchema(() => 1673 z.object({ 1674 type: z.literal('system'), 1675 subtype: z.literal('files_persisted'), 1676 files: z.array( 1677 z.object({ 1678 filename: z.string(), 1679 file_id: z.string(), 1680 }), 1681 ), 1682 failed: z.array( 1683 z.object({ 1684 filename: z.string(), 1685 error: z.string(), 1686 }), 1687 ), 1688 processed_at: z.string(), 1689 uuid: UUIDPlaceholder(), 1690 session_id: z.string(), 1691 }), 1692 ) 1693 1694 export const SDKTaskNotificationMessageSchema = lazySchema(() => 1695 z.object({ 1696 type: z.literal('system'), 1697 subtype: z.literal('task_notification'), 1698 task_id: z.string(), 1699 tool_use_id: z.string().optional(), 1700 status: z.enum(['completed', 'failed', 'stopped']), 1701 output_file: z.string(), 1702 summary: z.string(), 1703 usage: z 1704 .object({ 1705 total_tokens: z.number(), 1706 tool_uses: z.number(), 1707 duration_ms: z.number(), 1708 }) 1709 .optional(), 1710 uuid: UUIDPlaceholder(), 1711 session_id: z.string(), 1712 }), 1713 ) 1714 1715 export const SDKTaskStartedMessageSchema = lazySchema(() => 1716 z.object({ 1717 type: z.literal('system'), 1718 subtype: z.literal('task_started'), 1719 task_id: z.string(), 1720 tool_use_id: z.string().optional(), 1721 description: z.string(), 1722 task_type: z.string().optional(), 1723 workflow_name: z 1724 .string() 1725 .optional() 1726 .describe( 1727 "meta.name from the workflow script (e.g. 'spec'). Only set when task_type is 'local_workflow'.", 1728 ), 1729 prompt: z.string().optional(), 1730 uuid: UUIDPlaceholder(), 1731 session_id: z.string(), 1732 }), 1733 ) 1734 1735 export const SDKSessionStateChangedMessageSchema = lazySchema(() => 1736 z 1737 .object({ 1738 type: z.literal('system'), 1739 subtype: z.literal('session_state_changed'), 1740 state: z.enum(['idle', 'running', 'requires_action']), 1741 uuid: UUIDPlaceholder(), 1742 session_id: z.string(), 1743 }) 1744 .describe( 1745 "Mirrors notifySessionStateChanged. 'idle' fires after heldBackResult flushes and the bg-agent do-while exits — authoritative turn-over signal.", 1746 ), 1747 ) 1748 1749 1750 export const SDKTaskProgressMessageSchema = lazySchema(() => 1751 z.object({ 1752 type: z.literal('system'), 1753 subtype: z.literal('task_progress'), 1754 task_id: z.string(), 1755 tool_use_id: z.string().optional(), 1756 description: z.string(), 1757 usage: z.object({ 1758 total_tokens: z.number(), 1759 tool_uses: z.number(), 1760 duration_ms: z.number(), 1761 }), 1762 last_tool_name: z.string().optional(), 1763 summary: z.string().optional(), 1764 uuid: UUIDPlaceholder(), 1765 session_id: z.string(), 1766 }), 1767 ) 1768 1769 export const SDKToolUseSummaryMessageSchema = lazySchema(() => 1770 z.object({ 1771 type: z.literal('tool_use_summary'), 1772 summary: z.string(), 1773 preceding_tool_use_ids: z.array(z.string()), 1774 uuid: UUIDPlaceholder(), 1775 session_id: z.string(), 1776 }), 1777 ) 1778 1779 export const SDKElicitationCompleteMessageSchema = lazySchema(() => 1780 z 1781 .object({ 1782 type: z.literal('system'), 1783 subtype: z.literal('elicitation_complete'), 1784 mcp_server_name: z.string(), 1785 elicitation_id: z.string(), 1786 uuid: UUIDPlaceholder(), 1787 session_id: z.string(), 1788 }) 1789 .describe( 1790 'Emitted when an MCP server confirms that a URL-mode elicitation is complete.', 1791 ), 1792 ) 1793 1794 /** @internal */ 1795 export const SDKPromptSuggestionMessageSchema = lazySchema(() => 1796 z 1797 .object({ 1798 type: z.literal('prompt_suggestion'), 1799 suggestion: z.string(), 1800 uuid: UUIDPlaceholder(), 1801 session_id: z.string(), 1802 }) 1803 .describe( 1804 'Predicted next user prompt, emitted after each turn when promptSuggestions is enabled.', 1805 ), 1806 ) 1807 1808 // ============================================================================ 1809 // Session Listing Types 1810 // ============================================================================ 1811 1812 export const SDKSessionInfoSchema = lazySchema(() => 1813 z 1814 .object({ 1815 sessionId: z.string().describe('Unique session identifier (UUID).'), 1816 summary: z 1817 .string() 1818 .describe( 1819 'Display title for the session: custom title, auto-generated summary, or first prompt.', 1820 ), 1821 lastModified: z 1822 .number() 1823 .describe('Last modified time in milliseconds since epoch.'), 1824 fileSize: z 1825 .number() 1826 .optional() 1827 .describe( 1828 'File size in bytes. Only populated for local JSONL storage.', 1829 ), 1830 customTitle: z 1831 .string() 1832 .optional() 1833 .describe('User-set session title via /rename.'), 1834 firstPrompt: z 1835 .string() 1836 .optional() 1837 .describe('First meaningful user prompt in the session.'), 1838 gitBranch: z 1839 .string() 1840 .optional() 1841 .describe('Git branch at the end of the session.'), 1842 cwd: z.string().optional().describe('Working directory for the session.'), 1843 tag: z.string().optional().describe('User-set session tag.'), 1844 createdAt: z 1845 .number() 1846 .optional() 1847 .describe( 1848 "Creation time in milliseconds since epoch, extracted from the first entry's timestamp.", 1849 ), 1850 }) 1851 .describe('Session metadata returned by listSessions and getSessionInfo.'), 1852 ) 1853 1854 export const SDKMessageSchema = lazySchema(() => 1855 z.union([ 1856 SDKAssistantMessageSchema(), 1857 SDKUserMessageSchema(), 1858 SDKUserMessageReplaySchema(), 1859 SDKResultMessageSchema(), 1860 SDKSystemMessageSchema(), 1861 SDKPartialAssistantMessageSchema(), 1862 SDKCompactBoundaryMessageSchema(), 1863 SDKStatusMessageSchema(), 1864 SDKAPIRetryMessageSchema(), 1865 SDKLocalCommandOutputMessageSchema(), 1866 SDKHookStartedMessageSchema(), 1867 SDKHookProgressMessageSchema(), 1868 SDKHookResponseMessageSchema(), 1869 SDKToolProgressMessageSchema(), 1870 SDKAuthStatusMessageSchema(), 1871 SDKTaskNotificationMessageSchema(), 1872 SDKTaskStartedMessageSchema(), 1873 SDKTaskProgressMessageSchema(), 1874 SDKSessionStateChangedMessageSchema(), 1875 SDKFilesPersistedEventSchema(), 1876 SDKToolUseSummaryMessageSchema(), 1877 SDKRateLimitEventSchema(), 1878 SDKElicitationCompleteMessageSchema(), 1879 SDKPromptSuggestionMessageSchema(), 1880 ]), 1881 ) 1882 1883 export const FastModeStateSchema = lazySchema(() => 1884 z 1885 .enum(['off', 'cooldown', 'on']) 1886 .describe( 1887 'Fast mode state: off, in cooldown after rate limit, or actively enabled.', 1888 ), 1889 )