@@ -170,6 +170,23 @@ func parseViewport(viewport string) (width, height, refreshRate int64, err error
170170 return w , h , refreshRate , nil
171171}
172172
173+ func parseStringMapFlag (values []string , flagName string ) (map [string ]string , error ) {
174+ if len (values ) == 0 {
175+ return nil , nil
176+ }
177+
178+ parsed := make (map [string ]string , len (values ))
179+ for _ , pair := range values {
180+ parts := strings .SplitN (pair , "=" , 2 )
181+ if len (parts ) != 2 {
182+ return nil , fmt .Errorf ("invalid %s value: %s (expected KEY=value)" , flagName , pair )
183+ }
184+ parsed [parts [0 ]] = parts [1 ]
185+ }
186+
187+ return parsed , nil
188+ }
189+
173190// Inputs for each command
174191type BrowsersCreateInput struct {
175192 PersistenceID string
@@ -1257,18 +1274,23 @@ type BrowsersProcessExecInput struct {
12571274 Timeout int
12581275 AsUser string
12591276 AsRoot BoolFlag
1277+ Env []string
12601278 Output string
12611279}
12621280
12631281type BrowsersProcessSpawnInput struct {
1264- Identifier string
1265- Command string
1266- Args []string
1267- Cwd string
1268- Timeout int
1269- AsUser string
1270- AsRoot BoolFlag
1271- Output string
1282+ Identifier string
1283+ Command string
1284+ Args []string
1285+ Cwd string
1286+ Timeout int
1287+ AsUser string
1288+ AsRoot BoolFlag
1289+ AllocateTTY BoolFlag
1290+ Cols int64
1291+ Rows int64
1292+ Env []string
1293+ Output string
12721294}
12731295
12741296type BrowsersProcessKillInput struct {
@@ -1396,6 +1418,13 @@ func (b BrowsersCmd) ProcessExec(ctx context.Context, in BrowsersProcessExecInpu
13961418 if in .AsRoot .Set {
13971419 params .AsRoot = kernel .Opt (in .AsRoot .Value )
13981420 }
1421+ env , err := parseStringMapFlag (in .Env , "--env" )
1422+ if err != nil {
1423+ return err
1424+ }
1425+ if len (env ) > 0 {
1426+ params .Env = env
1427+ }
13991428 res , err := b .process .Exec (ctx , br .SessionID , params )
14001429 if err != nil {
14011430 return util.CleanedUpSdkError {Err : err }
@@ -1463,6 +1492,27 @@ func (b BrowsersCmd) ProcessSpawn(ctx context.Context, in BrowsersProcessSpawnIn
14631492 if in .AsRoot .Set {
14641493 params .AsRoot = kernel .Opt (in .AsRoot .Value )
14651494 }
1495+ if in .AllocateTTY .Set {
1496+ params .AllocateTty = kernel .Opt (in .AllocateTTY .Value )
1497+ }
1498+ if in .Cols > 0 || in .Rows > 0 {
1499+ if ! in .AllocateTTY .Set || ! in .AllocateTTY .Value {
1500+ return fmt .Errorf ("--cols and --rows require --allocate-tty" )
1501+ }
1502+ if in .Cols > 0 {
1503+ params .Cols = kernel .Opt (in .Cols )
1504+ }
1505+ if in .Rows > 0 {
1506+ params .Rows = kernel .Opt (in .Rows )
1507+ }
1508+ }
1509+ env , err := parseStringMapFlag (in .Env , "--env" )
1510+ if err != nil {
1511+ return err
1512+ }
1513+ if len (env ) > 0 {
1514+ params .Env = env
1515+ }
14661516 res , err := b .process .Spawn (ctx , br .SessionID , params )
14671517 if err != nil {
14681518 return util.CleanedUpSdkError {Err : err }
@@ -2297,6 +2347,7 @@ func init() {
22972347 procExec .Flags ().Int ("timeout" , 0 , "Timeout in seconds" )
22982348 procExec .Flags ().String ("as-user" , "" , "Run as user" )
22992349 procExec .Flags ().Bool ("as-root" , false , "Run as root" )
2350+ procExec .Flags ().StringArray ("env" , nil , "Environment variable in KEY=value format (repeatable)" )
23002351 procExec .Flags ().StringP ("output" , "o" , "" , "Output format: json for raw API response" )
23012352 procSpawn := & cobra.Command {Use : "spawn <id> [--] [command...]" , Short : "Execute a command asynchronously" , Args : cobra .MinimumNArgs (1 ), RunE : runBrowsersProcessSpawn }
23022353 procSpawn .Flags ().String ("command" , "" , "Command to execute (optional; if omitted, trailing args are executed via /bin/bash -c)" )
@@ -2305,6 +2356,10 @@ func init() {
23052356 procSpawn .Flags ().Int ("timeout" , 0 , "Timeout in seconds" )
23062357 procSpawn .Flags ().String ("as-user" , "" , "Run as user" )
23072358 procSpawn .Flags ().Bool ("as-root" , false , "Run as root" )
2359+ procSpawn .Flags ().Bool ("allocate-tty" , false , "Allocate a pseudo-terminal (PTY) for interactive shells" )
2360+ procSpawn .Flags ().Int64 ("cols" , 0 , "Initial terminal columns when --allocate-tty is enabled" )
2361+ procSpawn .Flags ().Int64 ("rows" , 0 , "Initial terminal rows when --allocate-tty is enabled" )
2362+ procSpawn .Flags ().StringArray ("env" , nil , "Environment variable in KEY=value format (repeatable)" )
23082363 procSpawn .Flags ().StringP ("output" , "o" , "" , "Output format: json for raw API response" )
23092364 procKill := & cobra.Command {Use : "kill <id> <process-id>" , Short : "Send a signal to a process" , Args : cobra .ExactArgs (2 ), RunE : runBrowsersProcessKill }
23102365 procKill .Flags ().String ("signal" , "TERM" , "Signal to send (TERM, KILL, INT, HUP)" )
@@ -2806,6 +2861,7 @@ func runBrowsersProcessExec(cmd *cobra.Command, args []string) error {
28062861 timeout , _ := cmd .Flags ().GetInt ("timeout" )
28072862 asUser , _ := cmd .Flags ().GetString ("as-user" )
28082863 asRoot , _ := cmd .Flags ().GetBool ("as-root" )
2864+ env , _ := cmd .Flags ().GetStringArray ("env" )
28092865 if command == "" && len (args ) > 1 {
28102866 // Treat trailing args after identifier as a shell command
28112867 shellCmd := strings .Join (args [1 :], " " )
@@ -2814,7 +2870,7 @@ func runBrowsersProcessExec(cmd *cobra.Command, args []string) error {
28142870 }
28152871 output , _ := cmd .Flags ().GetString ("output" )
28162872 b := BrowsersCmd {browsers : & svc , process : & svc .Process }
2817- return b .ProcessExec (cmd .Context (), BrowsersProcessExecInput {Identifier : args [0 ], Command : command , Args : argv , Cwd : cwd , Timeout : timeout , AsUser : asUser , AsRoot : BoolFlag {Set : cmd .Flags ().Changed ("as-root" ), Value : asRoot }, Output : output })
2873+ return b .ProcessExec (cmd .Context (), BrowsersProcessExecInput {Identifier : args [0 ], Command : command , Args : argv , Cwd : cwd , Timeout : timeout , AsUser : asUser , AsRoot : BoolFlag {Set : cmd .Flags ().Changed ("as-root" ), Value : asRoot }, Env : env , Output : output })
28182874}
28192875
28202876func runBrowsersProcessSpawn (cmd * cobra.Command , args []string ) error {
@@ -2826,14 +2882,31 @@ func runBrowsersProcessSpawn(cmd *cobra.Command, args []string) error {
28262882 timeout , _ := cmd .Flags ().GetInt ("timeout" )
28272883 asUser , _ := cmd .Flags ().GetString ("as-user" )
28282884 asRoot , _ := cmd .Flags ().GetBool ("as-root" )
2885+ allocateTTY , _ := cmd .Flags ().GetBool ("allocate-tty" )
2886+ cols , _ := cmd .Flags ().GetInt64 ("cols" )
2887+ rows , _ := cmd .Flags ().GetInt64 ("rows" )
2888+ env , _ := cmd .Flags ().GetStringArray ("env" )
28292889 if command == "" && len (args ) > 1 {
28302890 shellCmd := strings .Join (args [1 :], " " )
28312891 command = "/bin/bash"
28322892 argv = []string {"-c" , shellCmd }
28332893 }
28342894 output , _ := cmd .Flags ().GetString ("output" )
28352895 b := BrowsersCmd {browsers : & svc , process : & svc .Process }
2836- return b .ProcessSpawn (cmd .Context (), BrowsersProcessSpawnInput {Identifier : args [0 ], Command : command , Args : argv , Cwd : cwd , Timeout : timeout , AsUser : asUser , AsRoot : BoolFlag {Set : cmd .Flags ().Changed ("as-root" ), Value : asRoot }, Output : output })
2896+ return b .ProcessSpawn (cmd .Context (), BrowsersProcessSpawnInput {
2897+ Identifier : args [0 ],
2898+ Command : command ,
2899+ Args : argv ,
2900+ Cwd : cwd ,
2901+ Timeout : timeout ,
2902+ AsUser : asUser ,
2903+ AsRoot : BoolFlag {Set : cmd .Flags ().Changed ("as-root" ), Value : asRoot },
2904+ AllocateTTY : BoolFlag {Set : cmd .Flags ().Changed ("allocate-tty" ), Value : allocateTTY },
2905+ Cols : cols ,
2906+ Rows : rows ,
2907+ Env : env ,
2908+ Output : output ,
2909+ })
28372910}
28382911
28392912func runBrowsersProcessKill (cmd * cobra.Command , args []string ) error {
0 commit comments