use super::SandboxPolicy; use codex_experimental_api_macros::ExperimentalApi; use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; use std::collections::HashMap; use std::path::PathBuf; use ts_rs::TS; /// PTY size in character cells for `command/exec` PTY sessions. #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecTerminalSize { /// Terminal height in character cells. pub rows: u16, /// Terminal width in character cells. pub cols: u16, } /// Run a standalone command (argv vector) in the server sandbox without /// creating a thread or turn. /// /// The final `command/exec` response is deferred until the process exits and is /// sent only after all `command/exec/outputDelta` notifications for that /// connection have been emitted. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS, ExperimentalApi)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecParams { /// Command argv vector. Empty arrays are rejected. pub command: Vec, /// Optional client-supplied, connection-scoped process id. /// /// Required for `tty`, `streamStdin`, `streamStdoutStderr`, and follow-up /// `command/exec/write`, `command/exec/resize`, and /// `command/exec/terminate` calls. When omitted, buffered execution gets an /// internal id that is not exposed to the client. #[ts(optional = nullable)] pub process_id: Option, /// Enable PTY mode. /// /// This implies `streamStdin` and `streamStdoutStderr`. #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub tty: bool, /// Allow follow-up `command/exec/write` requests to write stdin bytes. /// /// Requires a client-supplied `processId`. #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub stream_stdin: bool, /// Stream stdout/stderr via `command/exec/outputDelta` notifications. /// /// Streamed bytes are not duplicated into the final response and require a /// client-supplied `processId`. #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub stream_stdout_stderr: bool, /// Optional per-stream stdout/stderr capture cap in bytes. /// /// When omitted, the server default applies. Cannot be combined with /// `disableOutputCap`. #[ts(type = "number | null")] #[ts(optional = nullable)] pub output_bytes_cap: Option, /// Disable stdout/stderr capture truncation for this request. /// /// Cannot be combined with `outputBytesCap`. #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub disable_output_cap: bool, /// Disable the timeout entirely for this request. /// /// Cannot be combined with `timeoutMs`. #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub disable_timeout: bool, /// Optional timeout in milliseconds. /// /// When omitted, the server default applies. Cannot be combined with /// `disableTimeout`. #[ts(type = "number | null")] #[ts(optional = nullable)] pub timeout_ms: Option, /// Optional working directory. Defaults to the server cwd. #[ts(optional = nullable)] pub cwd: Option, /// Optional environment overrides merged into the server-computed /// environment. /// /// Matching names override inherited values. Set a key to `null` to unset /// an inherited variable. #[ts(optional = nullable)] pub env: Option>>, /// Optional initial PTY size in character cells. Only valid when `tty` is /// true. #[ts(optional = nullable)] pub size: Option, /// Optional sandbox policy for this command. /// /// Uses the same shape as thread/turn execution sandbox configuration and /// defaults to the user's configured policy when omitted. Cannot be /// combined with `permissionProfile`. #[ts(optional = nullable)] pub sandbox_policy: Option, /// Optional active permissions profile id for this command. /// /// Defaults to the user's configured permissions when omitted. Cannot be /// combined with `sandboxPolicy`. #[experimental("command/exec.permissionProfile")] #[ts(optional = nullable)] pub permission_profile: Option, } /// Final buffered result for `command/exec`. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecResponse { /// Process exit code. pub exit_code: i32, /// Buffered stdout capture. /// /// Empty when stdout was streamed via `command/exec/outputDelta`. pub stdout: String, /// Buffered stderr capture. /// /// Empty when stderr was streamed via `command/exec/outputDelta`. pub stderr: String, } /// Write stdin bytes to a running `command/exec` session, close stdin, or /// both. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecWriteParams { /// Client-supplied, connection-scoped `processId` from the original /// `command/exec` request. pub process_id: String, /// Optional base64-encoded stdin bytes to write. #[ts(optional = nullable)] pub delta_base64: Option, /// Close stdin after writing `deltaBase64`, if present. #[serde(default, skip_serializing_if = "std::ops::Not::not")] pub close_stdin: bool, } /// Empty success response for `command/exec/write`. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecWriteResponse {} /// Terminate a running `command/exec` session. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecTerminateParams { /// Client-supplied, connection-scoped `processId` from the original /// `command/exec` request. pub process_id: String, } /// Empty success response for `command/exec/terminate`. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecTerminateResponse {} /// Resize a running PTY-backed `command/exec` session. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecResizeParams { /// Client-supplied, connection-scoped `processId` from the original /// `command/exec` request. pub process_id: String, /// New PTY size in character cells. pub size: CommandExecTerminalSize, } /// Empty success response for `command/exec/resize`. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecResizeResponse {} /// Stream label for `command/exec/outputDelta` notifications. #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub enum CommandExecOutputStream { /// stdout stream. PTY mode multiplexes terminal output here. Stdout, /// stderr stream. Stderr, } /// Base64-encoded output chunk emitted for a streaming `command/exec` request. /// /// These notifications are connection-scoped. If the originating connection /// closes, the server terminates the process. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecOutputDeltaNotification { /// Client-supplied, connection-scoped `processId` from the original /// `command/exec` request. pub process_id: String, /// Output stream for this chunk. pub stream: CommandExecOutputStream, /// Base64-encoded output bytes. pub delta_base64: String, /// `true` on the final streamed chunk for a stream when `outputBytesCap` /// truncated later output on that stream. pub cap_reached: bool, }