interface BuiltinToolInputs {
    Bash: {
      /** The command to execute */
      command: string
      /** Optional timeout in milliseconds (max 600000 for a foreground command) */
      timeout?: number
      /** Clear, concise description of what this command does in active voice. Never use words like "complex" or "risk" in the description - just describe what it does. Say what the command does in plain words: do not echo the command's text, its flags, or file paths - the user reads this description, often without seeing the command. For simple commands (git, npm, standard CLI tools), keep it brief (5-10 words): - ls → "List files in current directory" - git status → "Show working tree status" - npm install → "Install package dependencies" For commands that are harder to parse at a glance (piped commands, obscure flags, etc.), add enough context to clarify what it does: - find . -name "*.tmp" -exec rm {} \; → "Find and delete all .tmp files recursively" - git reset --hard origin/main → "Discard all local changes and match remote main" - curl -s url | jq '.data[]' → "Fetch JSON from URL and extract data array elements" */
      description?: string
      /** Set to true to run this command in the background. With it, `timeout` limits how long the command may run in the background before it is stopped (default 600000 ms, max 7200000 ms). */
      run_in_background?: boolean
      /** Set this to true to dangerously override sandbox mode and run commands without sandboxing. */
      dangerouslyDisableSandbox?: boolean
    }
    Read: {
      /** The absolute path to the file to read */
      file_path: string
      /** The line number to start reading from. Only provide if the file is too large to read at once */
      offset?: number
      /** The number of lines to read. Only provide if the file is too large to read at once. */
      limit?: number
      /** Page range for PDF files (e.g., "1-5", "3", "10-20"). Only applicable to PDF files. Maximum 20 pages per request. */
      pages?: string
      /** Set to true to read a text file, or a line range of one, that is over the usual size limits, up to what still fits in your context. Only use this when you genuinely need all of it or the user asked for the whole file; otherwise read it in parts with offset and limit, or search it. */
      allow_large?: boolean
    }
}

interface BuiltinToolResults {
    Bash: {
      /** The standard output of the command */
      stdout: string
      /** The standard error output of the command */
      stderr: string
      /** Path to raw output file for large MCP tool outputs */
      rawOutputPath?: string
      /** Whether the command was interrupted */
      interrupted: boolean
      /** Flag to indicate if stdout contains image data */
      isImage?: boolean
      /** ID of the background task if command is running in background */
      backgroundTaskId?: string
      /** True if the user manually backgrounded the command with Ctrl+B */
      backgroundedByUser?: boolean
      /** @internal True if a plugin's turn abort moved the running command to the background */
      backgroundedByTurnAbort?: boolean
      /** @internal True if the command was moved to the background so a message queued for the model could reach it */
      backgroundedToDeliverMessage?: boolean
      /** Set when the command hit its timeout and was auto-backgrounded; the timeout value in ms */
      timedOutAfterMs?: number
      /** Model-facing note that the session cwd was not changed by a backgrounded command containing a directory-change builtin (cd/pushd/popd/chdir) */
      backgroundCwdHint?: string
      /** True when this backgrounded command is terminated at its caller's final response, so no completion notification can follow (a synchronous subagent's command, or a headless session that takes no further input and is not waiting for background commands); absent when the command survives */
      backgroundEndsWithFinalResponse?: true
      /** Flag to indicate if sandbox mode was overridden */
      dangerouslyDisableSandbox?: boolean
      /** Semantic interpretation for non-error exit codes with special meaning */
      returnCodeInterpretation?: string
      /** Whether the command is expected to produce no output on success */
      noOutputExpected?: boolean
      /** Structured content blocks */
      structuredContent?: unknown[]
      /** Path to the persisted full output in tool-results dir (set when output is too large for inline) */
      persistedOutputPath?: string
      /** Total size of the output in bytes (set when output is too large for inline) */
      persistedOutputSize?: number
      /** Model-facing note listing readFileState entries whose mtime bumped during this command (set when WRITE_COMMAND_MARKERS matches) */
      staleReadFileStateHint?: string
      /** Model-facing system-reminder appended when a gh command reports a GitHub API rate-limit error */
      ghRateLimitHint?: string
      /** Structured classification of git/gh operations detected in this command (commit/push/merge/rebase/PR). Client-facing — lets clients render git activity without re-parsing stdout; not surfaced to the model. */
      gitOperation?: {
        commit?: {
          sha: string
          kind: "committed" | "amended" | "cherry-picked"
          branch?: string
        }
        push?: {
          branch: string
        }
        branch?: {
          ref: string
          action: "merged" | "rebased"
        }
        pr?: {
          number: number
          url?: string
          action: "created" | "edited" | "merged" | "commented" | "closed" | "reopened" | "ready" | "draft" | "auto-merge-enabled" | "auto-merge-disabled"
        }
      }
      /** @internal Per-file diff of the working-tree changes this command made, for rendering and for PostToolUse Bash hooks (changedFiles: absolute paths of every changed file known, shown or not, at most 200; cut when shorter than files.length + moreFiles); not surfaced to the model. */
      bashEditDiff?: {
        files: {
          filePath: string
          hunks: {
            oldStart: number
            oldLines: number
            newStart: number
            newLines: number
            lines: string[]
          }[]
          created?: true
          deleted?: true
        }[]
        moreFiles: number
        changedFiles?: string[]
        unavailable?: true
        skipped?: true
        shared?: true
      }
    }
    Read: {
      type: "text"
      file: {
        /** The path to the file that was read */
        filePath: string
        /** The content of the file */
        content: string
        /** Number of lines in the returned content */
        numLines: number
        /** The starting line number */
        startLine: number
        /** Total number of lines in the file */
        totalLines: number
        /** True when a whole-file read was auto-paginated because it exceeded the token cap (the content is a partial first page). A programmatic signal for internal consumers; survives output reconstruction (unlike the render-time banner). */
        truncatedByTokenCap?: boolean
      }
      /** Set when this Read completed a saved Artifact source file: the Artifact and the version of it that now counts as viewed. */
      artifactRead?: {
        slug: string
        ver: string
      }
    } | {
      type: "image"
      file: {
        /** Base64-encoded image data */
        base64: string
        /** The MIME type of the image */
        type: "image/jpeg" | "image/png" | "image/gif" | "image/webp"
        /** Original file size in bytes */
        originalSize: number
        /** Image dimension info for coordinate mapping */
        dimensions?: {
          /** Original image width in pixels */
          originalWidth?: number
          /** Original image height in pixels */
          originalHeight?: number
          /** Displayed image width in pixels (after resizing) */
          displayWidth?: number
          /** Displayed image height in pixels (after resizing) */
          displayHeight?: number
        }
      }
    } | {
      type: "notebook"
      file: {
        /** The path to the notebook file */
        filePath: string
        /** Array of notebook cells */
        cells: unknown[]
      }
    } | {
      type: "pdf"
      file: {
        /** The path to the PDF file */
        filePath: string
        /** Base64-encoded PDF data */
        base64: string
        /** Original file size in bytes */
        originalSize: number
      }
    } | {
      type: "parts"
      file: {
        /** The path to the PDF file */
        filePath: string
        /** Original file size in bytes */
        originalSize: number
        /** Number of pages extracted */
        count: number
        /** Directory containing extracted page images */
        outputDir: string
      }
      /** Document page number of the first extracted page (1 when no range was requested); labels the page images in the model-facing tool_result */
      firstPage?: number
      /** Extracted page images, in page order. Present only transiently in-process: the page image bytes are delivered solely as image blocks in the model-facing tool_result content and are not retained on the tool_use_result, so this key is absent on the emitted/persisted result */
      pages?: Array<{
        /** Base64-encoded page image; empty when the page could not be processed */
        base64: string
        /** The MIME type of the image */
        mediaType: "image/jpeg" | "image/png" | "image/gif" | "image/webp"
        /** Why the page could not be processed as an image; set only when base64 is empty */
        error?: string
      }>
    } | {
      type: "file_unchanged"
      file: {
        /** The path to the file */
        filePath: string
      }
      /** Set when the dedup matched a startup-seeded entry (CLAUDE.md / nested memory) rather than a prior Read tool_result */
      source?: "seeded"
    }
}
