/ src / entrypoints / sdk / coreSchemas.ts
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  )