Create a sandbox that runs a command to completion (no `--keep`). Captures the full CLI output and parses the sandbox name from it. The sandbox is created synchronously (the CLI blocks until the command finishes). # Arguments `args` — Extra arguments to `openshell sandbox create`, including `-- ` if needed. # Errors Returns an error if the CLI exits with a non-zero status or the sand
(args: &[&str])
| 67 | /// Returns an error if the CLI exits with a non-zero status or the sandbox |
| 68 | /// name cannot be parsed from the output. |
| 69 | pub async fn create(args: &[&str]) -> Result<Self, String> { |
| 70 | let mut cmd = openshell_cmd(); |
| 71 | cmd.arg("sandbox").arg("create"); |
| 72 | for arg in args { |
| 73 | cmd.arg(arg); |
| 74 | } |
| 75 | cmd.stdout(Stdio::piped()).stderr(Stdio::piped()); |
| 76 | |
| 77 | let output = timeout(SANDBOX_READY_TIMEOUT, cmd.output()) |
| 78 | .await |
| 79 | .map_err(|_| { |
| 80 | format!("sandbox create timed out after {SANDBOX_READY_TIMEOUT:?}") |
| 81 | })? |
| 82 | .map_err(|e| format!("failed to spawn openshell: {e}"))?; |
| 83 | |
| 84 | let stdout = String::from_utf8_lossy(&output.stdout).to_string(); |
| 85 | let stderr = String::from_utf8_lossy(&output.stderr).to_string(); |
| 86 | let combined = format!("{stdout}{stderr}"); |
| 87 | |
| 88 | if !output.status.success() { |
| 89 | return Err(format!( |
| 90 | "sandbox create failed (exit {:?}):\n{combined}", |
| 91 | output.status.code() |
| 92 | )); |
| 93 | } |
| 94 | |
| 95 | let name = extract_sandbox_name(&combined).ok_or_else(|| { |
| 96 | format!("could not parse sandbox name from create output:\n{combined}") |
| 97 | })?; |
| 98 | |
| 99 | Ok(Self { |
| 100 | name, |
| 101 | create_output: combined, |
| 102 | child: None, |
| 103 | cleaned_up: false, |
| 104 | }) |
| 105 | } |
| 106 | |
| 107 | /// Create a sandbox with `--keep` that runs a long-lived background |
| 108 | /// command. |