## ADDED Requirements ### Requirement: Command execution (blocking) The system SHALL provide `sandbox.runCommand(cmd, args?, opts?)` that executes a command inside the sandbox and waits for completion. Parameters: - `cmd: string` — command to execute - `args?: string[]` — command arguments - `cwd?: string` — working directory - `env?: Record` — per-command environment variables - `sudo?: boolean` — execute with root privileges - `timeoutMs?: number` — max execution time (SIGKILL on expiry) - `signal?: AbortSignal` — cancellation #### Scenario: Blocking runCommand returns finished result with exit code - **WHEN** `sandbox.runCommand("echo", ["hello"])` is called - **THEN** it SHALL return a `CommandFinished` instance with `exitCode: 0` #### Scenario: Command timeout kills process - **WHEN** `sandbox.runCommand("sleep", ["100"], { timeoutMs: 100 })` is executed - **THEN** it SHALL return a non-zero exit code after ~100ms #### Scenario: Stderr is captured separately - **WHEN** a command writes to both stdout and stderr - **THEN** `result.stdout()` and `result.stderr()` SHALL return their respective streams ### Requirement: Detached command execution The system SHALL support `{ detached: true }` mode where `runCommand()` returns immediately with a live `Command` handle. #### Scenario: Detached command returns before completion - **WHEN** `sandbox.runCommand({ cmd: "sleep", args: ["5"], detached: true })` is called - **THEN** it SHALL return a `Command` instance immediately (before the process exits) #### Scenario: Detached command can be waited on - **WHEN** `command.wait()` is called on a detached command - **THEN** it SHALL return a `CommandFinished` when the process exits ### Requirement: Command log streaming The system SHALL provide `command.logs()` as an async iterable of stdout/stderr log lines. #### Scenario: Logs stream output lines - **WHEN** `for await (const log of command.logs())` is iterated - **THEN** each `log` SHALL have `stream: "stdout" | "stderr"` and `data: string` ### Requirement: Command kill The system SHALL provide `command.kill(signal?)` to send a POSIX signal to a running command. #### Scenario: Default kill sends SIGTERM - **WHEN** `command.kill()` is called without a signal - **THEN** SIGTERM SHALL be sent to the process