@@ -2278,9 +2278,14 @@ function SandboxTester() {
22782278 > ( "disconnected" ) ;
22792279 const [ sessionId , setSessionId ] = useState < string | null > ( null ) ;
22802280 const [ commandInput , setCommandInput ] = useState ( "" ) ;
2281+ const [ commandOptions , setCommandOptions ] = useState ( {
2282+ cwd : "" ,
2283+ env : "" ,
2284+ } ) ;
22812285 const [ results , setResults ] = useState < CommandResult [ ] > ( [ ] ) ;
22822286 const [ isExecuting , setIsExecuting ] = useState ( false ) ;
22832287 const resultsEndRef = useRef < HTMLDivElement > ( null ) ;
2288+ const commandInputRef = useRef < HTMLInputElement > ( null ) ;
22842289
22852290 // Auto-scroll to bottom when new results are added
22862291 useEffect ( ( ) => {
@@ -2416,11 +2421,27 @@ function SandboxTester() {
24162421 } ;
24172422 setResults ( ( prev ) => [ ...prev , newResult ] ) ;
24182423
2419- // Execute the command
2420- console . log ( "Executing command:" , trimmedCommand ) ;
2421- const result = await client . execute ( trimmedCommand , [ ] , {
2424+ // Parse command options
2425+ const options : { sessionId ?: string ; cwd ?: string ; env ?: Record < string , string > } = {
24222426 sessionId : sessionId || undefined ,
2423- } ) ;
2427+ } ;
2428+
2429+ if ( commandOptions . cwd . trim ( ) ) {
2430+ options . cwd = commandOptions . cwd . trim ( ) ;
2431+ }
2432+
2433+ if ( commandOptions . env . trim ( ) ) {
2434+ const env : Record < string , string > = { } ;
2435+ commandOptions . env . split ( "," ) . forEach ( ( pair ) => {
2436+ const [ key , value ] = pair . split ( "=" ) ;
2437+ if ( key && value ) env [ key . trim ( ) ] = value . trim ( ) ;
2438+ } ) ;
2439+ options . env = env ;
2440+ }
2441+
2442+ // Execute the command
2443+ console . log ( "Executing command:" , trimmedCommand , "with options:" , options ) ;
2444+ const result = await client . execute ( trimmedCommand , [ ] , options ) ;
24242445 console . log ( "Result:" , result ) ;
24252446
24262447 // Update the result with the response
@@ -2437,6 +2458,11 @@ function SandboxTester() {
24372458 } ) ;
24382459
24392460 setCommandInput ( "" ) ;
2461+
2462+ // Refocus the input for better UX
2463+ setTimeout ( ( ) => {
2464+ commandInputRef . current ?. focus ( ) ;
2465+ } , 0 ) ;
24402466 } catch ( error : any ) {
24412467 console . error ( "Failed to execute command:" , error ) ;
24422468 setResults ( ( prev ) => {
@@ -2448,6 +2474,11 @@ function SandboxTester() {
24482474 }
24492475 return updated ;
24502476 } ) ;
2477+
2478+ // Refocus the input even on error
2479+ setTimeout ( ( ) => {
2480+ commandInputRef . current ?. focus ( ) ;
2481+ } , 100 ) ;
24512482 } finally {
24522483 setIsExecuting ( false ) ;
24532484 }
@@ -2479,18 +2510,32 @@ function SandboxTester() {
24792510 } ;
24802511 setResults ( ( prev ) => [ ...prev , newResult ] ) ;
24812512
2482- // Execute the command with streaming
2483- console . log ( "Executing streaming command:" , trimmedCommand ) ;
2484- await client . executeStream ( trimmedCommand , [ ] , {
2513+ // Parse command options (same as regular execute)
2514+ const options : { sessionId ?: string ; cwd ?: string ; env ?: Record < string , string > } = {
24852515 sessionId : sessionId || undefined ,
2486- } ) ;
2516+ } ;
2517+
2518+ if ( commandOptions . cwd . trim ( ) ) {
2519+ options . cwd = commandOptions . cwd . trim ( ) ;
2520+ }
2521+
2522+ if ( commandOptions . env . trim ( ) ) {
2523+ const env : Record < string , string > = { } ;
2524+ commandOptions . env . split ( "," ) . forEach ( ( pair ) => {
2525+ const [ key , value ] = pair . split ( "=" ) ;
2526+ if ( key && value ) env [ key . trim ( ) ] = value . trim ( ) ;
2527+ } ) ;
2528+ options . env = env ;
2529+ }
2530+
2531+ // Execute the command with streaming
2532+ console . log ( "Executing streaming command:" , trimmedCommand , "with options:" , options ) ;
2533+ await client . executeStream ( trimmedCommand , [ ] , options ) ;
24872534 const commandParts = trimmedCommand . split ( " " ) ;
24882535 const cmd = commandParts [ 0 ] ;
24892536 const args = commandParts . slice ( 1 ) ;
24902537 // Get the async generator
2491- const streamGenerator = client . execStream ( cmd , args , {
2492- sessionId : sessionId || undefined ,
2493- } ) ;
2538+ const streamGenerator = client . execStream ( cmd , args , options ) ;
24942539 // Iterate through the stream events
24952540 for await ( const event of streamGenerator ) {
24962541 console . log ( "Stream event:" , event ) ;
@@ -2517,6 +2562,11 @@ function SandboxTester() {
25172562 console . log ( "Streaming command completed" ) ;
25182563
25192564 setCommandInput ( "" ) ;
2565+
2566+ // Refocus the input for better UX
2567+ setTimeout ( ( ) => {
2568+ commandInputRef . current ?. focus ( ) ;
2569+ } , 0 ) ;
25202570 } catch ( error : any ) {
25212571 console . error ( "Failed to execute streaming command:" , error ) ;
25222572 setResults ( ( prev ) => {
@@ -2528,6 +2578,11 @@ function SandboxTester() {
25282578 }
25292579 return updated ;
25302580 } ) ;
2581+
2582+ // Refocus the input even on error
2583+ setTimeout ( ( ) => {
2584+ commandInputRef . current ?. focus ( ) ;
2585+ } , 100 ) ;
25312586 } finally {
25322587 setIsExecuting ( false ) ;
25332588 }
@@ -2622,6 +2677,7 @@ function SandboxTester() {
26222677 < div className = "command-bar" >
26232678 < span className = "command-prompt" > $</ span >
26242679 < input
2680+ ref = { commandInputRef }
26252681 type = "text"
26262682 className = "command-input"
26272683 value = { commandInput }
@@ -2658,6 +2714,32 @@ function SandboxTester() {
26582714 </ div >
26592715 </ div >
26602716
2717+ { /* Command Options */ }
2718+ < div className = "command-options" >
2719+ < div className = "option-group" >
2720+ < input
2721+ type = "text"
2722+ placeholder = "Working Directory (optional)"
2723+ value = { commandOptions . cwd }
2724+ onChange = { ( e ) =>
2725+ setCommandOptions ( ( prev ) => ( { ...prev , cwd : e . target . value } ) )
2726+ }
2727+ className = "option-input"
2728+ disabled = { isExecuting }
2729+ />
2730+ < input
2731+ type = "text"
2732+ placeholder = "Environment (KEY1=val1,KEY2=val2)"
2733+ value = { commandOptions . env }
2734+ onChange = { ( e ) =>
2735+ setCommandOptions ( ( prev ) => ( { ...prev , env : e . target . value } ) )
2736+ }
2737+ className = "option-input"
2738+ disabled = { isExecuting }
2739+ />
2740+ </ div >
2741+ </ div >
2742+
26612743 < div className = "results-container" ref = { resultsEndRef } >
26622744 { results . length === 0 ? (
26632745 < div
0 commit comments