@@ -77,7 +77,7 @@ pub use crate::ssh::{
7777 sandbox_ssh_proxy_by_name, sandbox_sync_down, sandbox_sync_up, sandbox_sync_up_files,
7878} ;
7979pub use openshell_core:: forward:: {
80- find_forward_by_port, list_forwards, stop_forward, stop_forwards_for_sandbox,
80+ ForwardSpec , find_forward_by_port, list_forwards, stop_forward, stop_forwards_for_sandbox,
8181} ;
8282
8383#[ derive( Debug , PartialEq , Eq ) ]
@@ -1574,10 +1574,7 @@ pub fn doctor_check() -> Result<()> {
15741574 Err ( miette:: miette!( "docker info failed: {}" , stderr. trim( ) ) )
15751575}
15761576
1577- fn sandbox_should_persist (
1578- keep : bool ,
1579- forward : Option < & openshell_core:: forward:: ForwardSpec > ,
1580- ) -> bool {
1577+ fn sandbox_should_persist ( keep : bool , forward : Option < & ForwardSpec > ) -> bool {
15811578 keep || forward. is_some ( )
15821579}
15831580
@@ -1745,31 +1742,86 @@ async fn finalize_sandbox_create_session(
17451742 session_result
17461743}
17471744
1745+ /// Configuration for creating a sandbox via the CLI.
1746+ ///
1747+ /// Infrastructure parameters (`server`, `gateway_name`, `tls`) remain positional
1748+ /// on the function signature, following the `provider_refresh_config(server, input, tls)`
1749+ /// precedent. This struct captures sandbox-specific options.
1750+ #[ derive( Debug ) ]
1751+ pub struct SandboxCreateConfig < ' a > {
1752+ pub name : Option < & ' a str > ,
1753+ pub from : Option < & ' a str > ,
1754+ pub uploads : & ' a [ ( String , Option < String > , bool ) ] ,
1755+ pub keep : bool ,
1756+ pub gpu_requirements : Option < GpuResourceRequirements > ,
1757+ pub cpu : Option < & ' a str > ,
1758+ pub memory : Option < & ' a str > ,
1759+ pub driver_config_json : Option < & ' a str > ,
1760+ pub editor : Option < Editor > ,
1761+ pub providers : & ' a [ String ] ,
1762+ pub policy : Option < & ' a str > ,
1763+ pub forward : Option < ForwardSpec > ,
1764+ pub command : & ' a [ String ] ,
1765+ pub tty_override : Option < bool > ,
1766+ pub auto_providers_override : Option < bool > ,
1767+ pub labels : HashMap < String , String > ,
1768+ pub environment : HashMap < String , String > ,
1769+ pub approval_mode : & ' a str ,
1770+ }
1771+
1772+ impl Default for SandboxCreateConfig < ' _ > {
1773+ fn default ( ) -> Self {
1774+ Self {
1775+ name : None ,
1776+ from : None ,
1777+ uploads : & [ ] ,
1778+ keep : false ,
1779+ gpu_requirements : None ,
1780+ cpu : None ,
1781+ memory : None ,
1782+ driver_config_json : None ,
1783+ editor : None ,
1784+ providers : & [ ] ,
1785+ policy : None ,
1786+ forward : None ,
1787+ command : & [ ] ,
1788+ tty_override : None ,
1789+ auto_providers_override : None ,
1790+ labels : HashMap :: new ( ) ,
1791+ environment : HashMap :: new ( ) ,
1792+ approval_mode : "manual" ,
1793+ }
1794+ }
1795+ }
1796+
17481797/// Create a sandbox with default settings.
1749- #[ allow( clippy:: too_many_arguments, clippy:: implicit_hasher) ] // user-facing CLI command; default hasher is fine
17501798pub async fn sandbox_create (
17511799 server : & str ,
1752- name : Option < & str > ,
1753- from : Option < & str > ,
17541800 gateway_name : & str ,
1755- uploads : & [ ( String , Option < String > , bool ) ] ,
1756- keep : bool ,
1757- gpu_requirements : Option < GpuResourceRequirements > ,
1758- cpu : Option < & str > ,
1759- memory : Option < & str > ,
1760- driver_config_json : Option < & str > ,
1761- editor : Option < Editor > ,
1762- providers : & [ String ] ,
1763- policy : Option < & str > ,
1764- forward : Option < openshell_core:: forward:: ForwardSpec > ,
1765- command : & [ String ] ,
1766- tty_override : Option < bool > ,
1767- auto_providers_override : Option < bool > ,
1768- labels : & HashMap < String , String > ,
1769- environment : & HashMap < String , String > ,
1770- approval_mode : & str ,
1801+ config : SandboxCreateConfig < ' _ > ,
17711802 tls : & TlsOptions ,
17721803) -> Result < ( ) > {
1804+ let SandboxCreateConfig {
1805+ name,
1806+ from,
1807+ uploads,
1808+ keep,
1809+ gpu_requirements,
1810+ cpu,
1811+ memory,
1812+ driver_config_json,
1813+ editor,
1814+ providers,
1815+ policy,
1816+ forward,
1817+ command,
1818+ tty_override,
1819+ auto_providers_override,
1820+ labels,
1821+ environment,
1822+ approval_mode,
1823+ } = config;
1824+
17731825 if editor. is_some ( ) && !command. is_empty ( ) {
17741826 return Err ( miette:: miette!(
17751827 "--editor cannot be used with a trailing command; use `openshell sandbox connect <name> --editor ...` after the sandbox is ready"
@@ -1846,14 +1898,14 @@ pub async fn sandbox_create(
18461898 let request = CreateSandboxRequest {
18471899 spec : Some ( SandboxSpec {
18481900 resource_requirements,
1849- environment : environment . clone ( ) ,
1901+ environment,
18501902 policy,
18511903 providers : configured_providers,
18521904 template,
18531905 ..SandboxSpec :: default ( )
18541906 } ) ,
18551907 name : name. unwrap_or_default ( ) . to_string ( ) ,
1856- labels : labels . clone ( ) ,
1908+ labels,
18571909 } ;
18581910
18591911 let response = match client. create_sandbox ( request) . await {
0 commit comments