Compare commits

...

1 Commits

Author SHA1 Message Date
Will Wang
ce9811fd5b Remove sandbox policy from command exec 2026-04-22 13:44:56 -07:00
11 changed files with 68 additions and 344 deletions

View File

@@ -171,7 +171,7 @@
"type": "object"
},
"CommandExecParams": {
"description": "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe 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.",
"description": "Run a standalone command (argv vector) without creating a thread or turn.\n\nThe 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.",
"properties": {
"command": {
"description": "Command argv vector. Empty arrays are rejected.",
@@ -224,17 +224,6 @@
"null"
]
},
"sandboxPolicy": {
"anyOf": [
{
"$ref": "#/definitions/SandboxPolicy"
},
{
"type": "null"
}
],
"description": "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted."
},
"size": {
"anyOf": [
{

View File

@@ -6358,7 +6358,7 @@
},
"CommandExecParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe 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.",
"description": "Run a standalone command (argv vector) without creating a thread or turn.\n\nThe 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.",
"properties": {
"command": {
"description": "Command argv vector. Empty arrays are rejected.",
@@ -6411,17 +6411,6 @@
"null"
]
},
"sandboxPolicy": {
"anyOf": [
{
"$ref": "#/definitions/v2/SandboxPolicy"
},
{
"type": "null"
}
],
"description": "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted."
},
"size": {
"anyOf": [
{

View File

@@ -2965,7 +2965,7 @@
},
"CommandExecParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe 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.",
"description": "Run a standalone command (argv vector) without creating a thread or turn.\n\nThe 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.",
"properties": {
"command": {
"description": "Command argv vector. Empty arrays are rejected.",
@@ -3018,17 +3018,6 @@
"null"
]
},
"sandboxPolicy": {
"anyOf": [
{
"$ref": "#/definitions/SandboxPolicy"
},
{
"type": "null"
}
],
"description": "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted."
},
"size": {
"anyOf": [
{

View File

@@ -1,10 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AbsolutePathBuf": {
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
"type": "string"
},
"CommandExecTerminalSize": {
"description": "PTY size in character cells for `command/exec` PTY sessions.",
"properties": {
@@ -26,182 +22,9 @@
"rows"
],
"type": "object"
},
"NetworkAccess": {
"enum": [
"restricted",
"enabled"
],
"type": "string"
},
"ReadOnlyAccess": {
"oneOf": [
{
"properties": {
"includePlatformDefaults": {
"default": true,
"type": "boolean"
},
"readableRoots": {
"default": [],
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": "array"
},
"type": {
"enum": [
"restricted"
],
"title": "RestrictedReadOnlyAccessType",
"type": "string"
}
},
"required": [
"type"
],
"title": "RestrictedReadOnlyAccess",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"fullAccess"
],
"title": "FullAccessReadOnlyAccessType",
"type": "string"
}
},
"required": [
"type"
],
"title": "FullAccessReadOnlyAccess",
"type": "object"
}
]
},
"SandboxPolicy": {
"oneOf": [
{
"properties": {
"type": {
"enum": [
"dangerFullAccess"
],
"title": "DangerFullAccessSandboxPolicyType",
"type": "string"
}
},
"required": [
"type"
],
"title": "DangerFullAccessSandboxPolicy",
"type": "object"
},
{
"properties": {
"access": {
"allOf": [
{
"$ref": "#/definitions/ReadOnlyAccess"
}
],
"default": {
"type": "fullAccess"
}
},
"networkAccess": {
"default": false,
"type": "boolean"
},
"type": {
"enum": [
"readOnly"
],
"title": "ReadOnlySandboxPolicyType",
"type": "string"
}
},
"required": [
"type"
],
"title": "ReadOnlySandboxPolicy",
"type": "object"
},
{
"properties": {
"networkAccess": {
"allOf": [
{
"$ref": "#/definitions/NetworkAccess"
}
],
"default": "restricted"
},
"type": {
"enum": [
"externalSandbox"
],
"title": "ExternalSandboxSandboxPolicyType",
"type": "string"
}
},
"required": [
"type"
],
"title": "ExternalSandboxSandboxPolicy",
"type": "object"
},
{
"properties": {
"excludeSlashTmp": {
"default": false,
"type": "boolean"
},
"excludeTmpdirEnvVar": {
"default": false,
"type": "boolean"
},
"networkAccess": {
"default": false,
"type": "boolean"
},
"readOnlyAccess": {
"allOf": [
{
"$ref": "#/definitions/ReadOnlyAccess"
}
],
"default": {
"type": "fullAccess"
}
},
"type": {
"enum": [
"workspaceWrite"
],
"title": "WorkspaceWriteSandboxPolicyType",
"type": "string"
},
"writableRoots": {
"default": [],
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": "array"
}
},
"required": [
"type"
],
"title": "WorkspaceWriteSandboxPolicy",
"type": "object"
}
]
}
},
"description": "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe 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.",
"description": "Run a standalone command (argv vector) without creating a thread or turn.\n\nThe 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.",
"properties": {
"command": {
"description": "Command argv vector. Empty arrays are rejected.",
@@ -254,17 +77,6 @@
"null"
]
},
"sandboxPolicy": {
"anyOf": [
{
"$ref": "#/definitions/SandboxPolicy"
},
{
"type": "null"
}
],
"description": "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted."
},
"size": {
"anyOf": [
{

View File

@@ -2,11 +2,9 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { CommandExecTerminalSize } from "./CommandExecTerminalSize";
import type { SandboxPolicy } from "./SandboxPolicy";
/**
* Run a standalone command (argv vector) in the server sandbox without
* creating a thread or turn.
* Run a standalone command (argv vector) 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
@@ -87,11 +85,4 @@ env?: { [key in string]?: string | null } | null,
* Optional initial PTY size in character cells. Only valid when `tty` is
* true.
*/
size?: CommandExecTerminalSize | null,
/**
* 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.
*/
sandboxPolicy?: SandboxPolicy | null, };
size?: CommandExecTerminalSize | null, };

View File

@@ -17,7 +17,6 @@ impl From<v1::ExecOneOffCommandParams> for v2::CommandExecParams {
cwd: value.cwd,
env: None,
size: None,
sandbox_policy: value.sandbox_policy.map(std::convert::Into::into),
}
}
}

View File

@@ -12,7 +12,6 @@ use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::FileChange;
pub use codex_protocol::protocol::GitSha;
use codex_protocol::protocol::ReviewDecision;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::protocol::SessionSource;
use codex_protocol::protocol::TurnAbortReason;
use codex_utils_absolute_path::AbsolutePathBuf;
@@ -181,7 +180,6 @@ pub struct ExecOneOffCommandParams {
pub command: Vec<String>,
pub timeout_ms: Option<u64>,
pub cwd: Option<PathBuf>,
pub sandbox_policy: Option<SandboxPolicy>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]

View File

@@ -2949,8 +2949,7 @@ pub struct CommandExecTerminalSize {
pub cols: u16,
}
/// Run a standalone command (argv vector) in the server sandbox without
/// creating a thread or turn.
/// Run a standalone command (argv vector) 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
@@ -3023,12 +3022,6 @@ pub struct CommandExecParams {
/// true.
#[ts(optional = nullable)]
pub size: Option<CommandExecTerminalSize>,
/// 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.
#[ts(optional = nullable)]
pub sandbox_policy: Option<SandboxPolicy>,
}
/// Final buffered result for `command/exec`.
@@ -8103,7 +8096,6 @@ mod tests {
cwd: Some(PathBuf::from("/tmp")),
env: None,
size: None,
sandbox_policy: None,
}
);
}
@@ -8123,7 +8115,6 @@ mod tests {
cwd: None,
env: None,
size: None,
sandbox_policy: None,
};
let value = serde_json::to_value(&params).expect("serialize command/exec params");
@@ -8137,7 +8128,6 @@ mod tests {
"cwd": null,
"env": null,
"size": null,
"sandboxPolicy": null,
"outputBytesCap": null,
})
);
@@ -8162,7 +8152,6 @@ mod tests {
cwd: None,
env: None,
size: None,
sandbox_policy: None,
};
let value = serde_json::to_value(&params).expect("serialize command/exec params");
@@ -8178,7 +8167,6 @@ mod tests {
"cwd": null,
"env": null,
"size": null,
"sandboxPolicy": null,
})
);
@@ -8206,7 +8194,6 @@ mod tests {
("BAZ".to_string(), None),
])),
size: None,
sandbox_policy: None,
};
let value = serde_json::to_value(&params).expect("serialize command/exec params");
@@ -8224,7 +8211,6 @@ mod tests {
"BAZ": null,
},
"size": null,
"sandboxPolicy": null,
})
);
@@ -8293,7 +8279,6 @@ mod tests {
rows: 40,
cols: 120,
}),
sandbox_policy: None,
};
let value = serde_json::to_value(&params).expect("serialize command/exec params");
@@ -8311,7 +8296,6 @@ mod tests {
"rows": 40,
"cols": 120,
},
"sandboxPolicy": null,
})
);

View File

@@ -164,7 +164,7 @@ Example with notification opt-out:
- `thread/realtime/appendText` — append text input to the active realtime session (experimental); returns `{}`.
- `thread/realtime/stop` — stop the active realtime session for the thread (experimental); returns `{}`.
- `review/start` — kick off Codexs automated reviewer for a thread; responds like `turn/start` and emits `item/started`/`item/completed` notifications with `enteredReviewMode` and `exitedReviewMode` items, plus a final assistant `agentMessage` containing the review.
- `command/exec` — run a single command under the server sandbox without starting a thread/turn (handy for utilities and validation).
- `command/exec` — run a single command without starting a thread/turn or enforcing a Codex sandbox (handy for utilities and validation).
- `command/exec/write` — write base64-decoded stdin bytes to a running `command/exec` session or close stdin; returns `{}`.
- `command/exec/resize` — resize a running PTY-backed `command/exec` session by `processId`; returns `{}`.
- `command/exec/terminate` — terminate a running `command/exec` session by `processId`; returns `{}`.
@@ -806,7 +806,7 @@ The `review` string is plain text that already bundles the overall explanation p
### Example: One-off command execution
Run a standalone command (argv vector) in the servers sandbox without creating a thread or turn:
Run a standalone command (argv vector) without creating a thread or turn. This RPC does not accept a sandbox policy and does not enforce a Codex sandbox.
```json
{ "method": "command/exec", "id": 32, "params": {
@@ -815,7 +815,6 @@ Run a standalone command (argv vector) in the servers sandbox without creatin
"cwd": "/Users/me/project", // optional; defaults to server cwd
"env": { "FOO": "override" }, // optional; merges into the server env and overrides matching names
"size": { "rows": 40, "cols": 120 }, // optional; PTY size in character cells, only valid with tty=true
"sandboxPolicy": { "type": "workspaceWrite" }, // optional; defaults to user config
"outputBytesCap": 1048576, // optional; per-stream capture cap
"disableOutputCap": false, // optional; cannot be combined with outputBytesCap
"timeoutMs": 10000, // optional; ms timeout; defaults to server timeout
@@ -828,12 +827,9 @@ Run a standalone command (argv vector) in the servers sandbox without creatin
} }
```
- For clients that are already sandboxed externally, set `sandboxPolicy` to `{"type":"externalSandbox","networkAccess":"enabled"}` (or omit `networkAccess` to keep it restricted). Codex will not enforce its own sandbox in this mode; it tells the model it has full file-system access and passes the `networkAccess` state through `environment_context`.
Notes:
- Empty `command` arrays are rejected.
- `sandboxPolicy` accepts the same shape used by `turn/start` (e.g., `dangerFullAccess`, `readOnly`, `workspaceWrite` with flags, `externalSandbox` with `networkAccess` `restricted|enabled`).
- `env` merges into the environment produced by the server's shell environment policy. Matching names are overridden; unspecified variables are left intact.
- When omitted, `timeoutMs` falls back to the server default.
- When omitted, `outputBytesCap` falls back to the server default of 1 MiB per stream.
@@ -841,8 +837,6 @@ Notes:
- `disableTimeout: true` disables the timeout entirely for that `command/exec` request. It cannot be combined with `timeoutMs`.
- `processId` is optional for buffered execution. When omitted, Codex generates an internal id for lifecycle tracking, but `tty`, `streamStdin`, and `streamStdoutStderr` must stay disabled and follow-up `command/exec/write` / `command/exec/terminate` calls are not available for that command.
- `size` is only valid when `tty: true`. It sets the initial PTY size in character cells.
- Buffered Windows sandbox execution accepts `processId` for correlation, but `command/exec/write` and `command/exec/terminate` are still unsupported for those requests.
- Buffered Windows sandbox execution also requires the default output cap; custom `outputBytesCap` and `disableOutputCap` are unsupported there.
- `tty`, `streamStdin`, and `streamStdoutStderr` are optional booleans. Legacy requests that omit them continue to use buffered execution.
- `tty: true` implies PTY mode plus `streamStdin: true` and `streamStdoutStderr: true`.
- `tty` and `streamStdin` do not disable the timeout on their own; omit `timeoutMs` to use the server default timeout, or set `disableTimeout: true` to keep the process alive until exit or explicit termination.

View File

@@ -228,7 +228,6 @@ use codex_core::ThreadManager;
use codex_core::clear_memory_roots_contents;
use codex_core::config::Config;
use codex_core::config::ConfigOverrides;
use codex_core::config::NetworkProxyAuditMetadata;
use codex_core::config::edit::ConfigEdit;
use codex_core::config::edit::ConfigEditsBuilder;
use codex_core::config_loader::CloudRequirementsLoadError;
@@ -2070,7 +2069,6 @@ impl CodexMessageProcessor {
cwd,
env: env_overrides,
size,
sandbox_policy,
} = params;
if size.is_some() && !tty {
@@ -2138,33 +2136,6 @@ impl CodexMessageProcessor {
},
None => None,
};
let managed_network_requirements_enabled =
self.config.managed_network_requirements_enabled();
let started_network_proxy = match self.config.permissions.network.as_ref() {
Some(spec) => match spec
.start_proxy(
self.config.permissions.sandbox_policy.get(),
/*policy_decider*/ None,
/*blocked_request_observer*/ None,
managed_network_requirements_enabled,
NetworkProxyAuditMetadata::default(),
)
.await
{
Ok(started) => Some(started),
Err(err) => {
let error = JSONRPCErrorError {
code: INTERNAL_ERROR_CODE,
message: format!("failed to start managed network proxy: {err}"),
data: None,
};
self.outgoing.send_error(request, error).await;
return;
}
},
None => None,
};
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
let output_bytes_cap = if disable_output_cap {
None
} else {
@@ -2190,11 +2161,9 @@ impl CodexMessageProcessor {
expiration,
capture_policy,
env,
network: started_network_proxy
.as_ref()
.map(codex_core::config::StartedNetworkProxy::proxy),
network: None,
sandbox_permissions: SandboxPermissions::UseDefault,
windows_sandbox_level,
windows_sandbox_level: WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: self
.config
.permissions
@@ -2203,41 +2172,14 @@ impl CodexMessageProcessor {
arg0: None,
};
let requested_policy = sandbox_policy.map(|policy| policy.to_core());
let (
effective_policy,
effective_file_system_sandbox_policy,
effective_network_sandbox_policy,
) = match requested_policy {
Some(policy) => match self.config.permissions.sandbox_policy.can_set(&policy) {
Ok(()) => {
let file_system_sandbox_policy =
codex_protocol::permissions::FileSystemSandboxPolicy::from_legacy_sandbox_policy(&policy, &sandbox_cwd);
let network_sandbox_policy =
codex_protocol::permissions::NetworkSandboxPolicy::from(&policy);
(policy, file_system_sandbox_policy, network_sandbox_policy)
}
Err(err) => {
let error = JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message: format!("invalid sandbox policy: {err}"),
data: None,
};
self.outgoing.send_error(request, error).await;
return;
}
},
None => (
self.config.permissions.sandbox_policy.get().clone(),
self.config.permissions.file_system_sandbox_policy.clone(),
self.config.permissions.network_sandbox_policy,
),
};
let sandbox_policy = codex_protocol::protocol::SandboxPolicy::DangerFullAccess;
let file_system_sandbox_policy =
codex_protocol::permissions::FileSystemSandboxPolicy::unrestricted();
let network_sandbox_policy = codex_protocol::permissions::NetworkSandboxPolicy::Enabled;
let codex_linux_sandbox_exe = self.arg0_paths.codex_linux_sandbox_exe.clone();
let outgoing = self.outgoing.clone();
let request_for_task = request.clone();
let started_network_proxy_for_task = started_network_proxy;
let use_legacy_landlock = self.config.features.use_legacy_landlock();
let size = match size.map(crate::command_exec::terminal_size_from_protocol) {
Some(Ok(size)) => Some(size),
@@ -2250,9 +2192,9 @@ impl CodexMessageProcessor {
match codex_core::exec::build_exec_request(
exec_params,
&effective_policy,
&effective_file_system_sandbox_policy,
effective_network_sandbox_policy,
&sandbox_policy,
&file_system_sandbox_policy,
network_sandbox_policy,
&sandbox_cwd,
&codex_linux_sandbox_exe,
use_legacy_landlock,
@@ -2265,7 +2207,7 @@ impl CodexMessageProcessor {
request_id: request_for_task,
process_id,
exec_request,
started_network_proxy: started_network_proxy_for_task,
started_network_proxy: None,
tty,
stream_stdin,
stream_stdout_stderr,

View File

@@ -56,7 +56,6 @@ async fn command_exec_without_streams_can_be_terminated() -> Result<()> {
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
let terminate_request_id = mcp
@@ -108,7 +107,6 @@ async fn command_exec_without_process_id_keeps_buffered_compatibility() -> Resul
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
@@ -128,6 +126,55 @@ async fn command_exec_without_process_id_keeps_buffered_compatibility() -> Resul
Ok(())
}
#[tokio::test]
async fn command_exec_ignores_read_only_sandbox_config() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let project = TempDir::new()?;
let output_path = project.path().join("command-exec-write.txt");
let mut mcp = McpProcess::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
.send_command_exec_request(CommandExecParams {
command: vec![
"sh".to_string(),
"-lc".to_string(),
"printf 'unsandboxed' > command-exec-write.txt; cat command-exec-write.txt"
.to_string(),
],
process_id: None,
tty: false,
stream_stdin: false,
stream_stdout_stderr: false,
output_bytes_cap: None,
disable_output_cap: false,
disable_timeout: false,
timeout_ms: None,
cwd: Some(project.path().to_path_buf()),
env: None,
size: None,
})
.await?;
let response = mcp
.read_stream_until_response_message(RequestId::Integer(command_request_id))
.await?;
let response: CommandExecResponse = to_response(response)?;
assert_eq!(
response,
CommandExecResponse {
exit_code: 0,
stdout: "unsandboxed".to_string(),
stderr: String::new(),
}
);
assert_eq!(std::fs::read_to_string(output_path)?, "unsandboxed");
Ok(())
}
#[tokio::test]
async fn command_exec_env_overrides_merge_with_server_environment_and_support_unset() -> Result<()>
{
@@ -166,7 +213,6 @@ async fn command_exec_env_overrides_merge_with_server_environment_and_support_un
("RUST_LOG".to_string(), None),
])),
size: None,
sandbox_policy: None,
})
.await?;
@@ -208,7 +254,6 @@ async fn command_exec_rejects_disable_timeout_with_timeout_ms() -> Result<()> {
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
@@ -245,7 +290,6 @@ async fn command_exec_rejects_disable_output_cap_with_output_bytes_cap() -> Resu
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
@@ -282,7 +326,6 @@ async fn command_exec_rejects_negative_timeout_ms() -> Result<()> {
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
@@ -319,7 +362,6 @@ async fn command_exec_without_process_id_rejects_streaming() -> Result<()> {
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
@@ -360,7 +402,6 @@ async fn command_exec_non_streaming_respects_output_cap() -> Result<()> {
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
@@ -407,7 +448,6 @@ async fn command_exec_streaming_does_not_buffer_output() -> Result<()> {
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
@@ -470,7 +510,6 @@ async fn command_exec_pipe_streams_output_and_accepts_write() -> Result<()> {
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
@@ -545,7 +584,6 @@ async fn command_exec_tty_implies_streaming_and_reports_pty_output() -> Result<(
cwd: None,
env: None,
size: None,
sandbox_policy: None,
})
.await?;
@@ -618,7 +656,6 @@ async fn command_exec_tty_supports_initial_size_and_resize() -> Result<()> {
rows: 31,
cols: 101,
}),
sandbox_policy: None,
})
.await?;