@@ -290,10 +290,6 @@ pub(crate) fn remove_terminal_runtime_registration(
290290 . remove ( workspace_id, session_id) )
291291}
292292
293- fn build_tmux_boot_command ( command : & str ) -> String {
294- command. to_string ( )
295- }
296-
297293pub ( crate ) fn session_runtime_start (
298294 params : SessionRuntimeStartParams ,
299295 app : AppHandle ,
@@ -380,14 +376,6 @@ pub(crate) fn session_runtime_start(
380376 & workspace_target,
381377 launch. runtime_env . clone ( ) ,
382378 ) ?;
383- let tmux_runtime = crate :: services:: tmux:: create_tmux_runtime (
384- & params. workspace_id ,
385- & params. session_id ,
386- & workspace_cwd,
387- & workspace_target,
388- & shell_env,
389- ) ?;
390-
391379 let terminal = match create_terminal_runtime (
392380 & params. workspace_id ,
393381 & workspace_cwd,
@@ -396,11 +384,11 @@ pub(crate) fn session_runtime_start(
396384 params. rows ,
397385 TerminalCreateOptions {
398386 persist_workspace_terminal : true ,
399- env : BTreeMap :: new ( ) ,
387+ env : shell_env . clone ( ) ,
400388 launch_command : TerminalLaunchCommand :: DefaultShell ,
401- bridge_target : TerminalBridgeTarget :: Tmux {
402- session_name : tmux_runtime . session_name . clone ( ) ,
403- pane_id : tmux_runtime . pane_id . clone ( ) ,
389+ bridge_target : TerminalBridgeTarget :: Pty {
390+ cwd : workspace_cwd . clone ( ) ,
391+ target : workspace_target . clone ( ) ,
404392 cols : params. cols ,
405393 rows : params. rows ,
406394 } ,
@@ -409,10 +397,7 @@ pub(crate) fn session_runtime_start(
409397 state,
410398 ) {
411399 Ok ( terminal) => terminal,
412- Err ( error) => {
413- let _ = crate :: services:: tmux:: kill_tmux_session ( & tmux_runtime. session_name ) ;
414- return Err ( error) ;
415- }
400+ Err ( error) => return Err ( error) ,
416401 } ;
417402
418403 let runtime_id = format ! ( "runtime:{}:{}" , params. workspace_id, params. session_id) ;
@@ -443,18 +428,20 @@ pub(crate) fn session_runtime_start(
443428 state,
444429 ) ;
445430 remove_failed_terminal_runtime ( & params. workspace_id , terminal. id , state) ;
446- let _ = crate :: services:: tmux:: kill_tmux_session ( & tmux_runtime. session_name ) ;
447431 return Err ( error) ;
448432 }
449433 } ;
450- if let Err ( error) = crate :: services:: tmux:: send_tmux_input (
451- & tmux_runtime. session_name ,
452- & build_tmux_boot_command ( & boot_command) ,
434+
435+ if let Err ( error) = crate :: services:: terminal:: terminal_write (
436+ params. workspace_id . clone ( ) ,
437+ terminal. id ,
438+ format ! ( "{}\n " , boot_command) ,
439+ crate :: TerminalWriteOrigin :: User ,
440+ state,
453441 ) {
454442 let _ =
455443 remove_terminal_runtime_registration ( & params. workspace_id , & params. session_id , state) ;
456444 remove_failed_terminal_runtime ( & params. workspace_id , terminal. id , state) ;
457- let _ = crate :: services:: tmux:: kill_tmux_session ( & tmux_runtime. session_name ) ;
458445 return Err ( error) ;
459446 }
460447
@@ -464,7 +451,6 @@ pub(crate) fn session_runtime_start(
464451 let _ =
465452 remove_terminal_runtime_registration ( & params. workspace_id , & params. session_id , state) ;
466453 remove_failed_terminal_runtime ( & params. workspace_id , terminal. id , state) ;
467- let _ = crate :: services:: tmux:: kill_tmux_session ( & tmux_runtime. session_name ) ;
468454 return Err ( error) ;
469455 }
470456 let updated = sync_session_runtime_state (
@@ -530,11 +516,6 @@ mod tests {
530516 assert_eq ! ( command, "codex resume resume-42 --model gpt-5.4" ) ;
531517 }
532518
533- #[ test]
534- fn build_tmux_boot_command_passes_command_through ( ) {
535- assert_eq ! ( build_tmux_boot_command( "claude --print" ) , "claude --print" ) ;
536- }
537-
538519 #[ test]
539520 fn remove_terminal_runtime_registration_clears_runtime_binding ( ) {
540521 let app = test_app ( ) ;
@@ -592,7 +573,7 @@ mod tests {
592573 }
593574
594575 #[ test]
595- fn session_runtime_start_routes_bound_terminal_output_from_tmux_runtime ( ) {
576+ fn session_runtime_start_routes_bound_terminal_output_from_pty_runtime ( ) {
596577 let app = test_app ( ) ;
597578 let workspace_id = launch_test_workspace ( & app, "/tmp/runtime-backend-terminal-launch" ) ;
598579 let session = create_session (
@@ -663,7 +644,7 @@ mod tests {
663644 }
664645 assert ! (
665646 terminal_output. contains( & expected) ,
666- "bound terminal should show tmux runtime output, got: {terminal_output:?}"
647+ "bound terminal should show PTY runtime output, got: {terminal_output:?}"
667648 ) ;
668649 }
669650
@@ -773,7 +754,7 @@ mod tests {
773754
774755 assert ! (
775756 terminal_output. contains( & expected) ,
776- "backend boot should reach tmux -backed terminal without frontend boot input write, got: {terminal_output:?}"
757+ "backend boot should reach PTY -backed terminal without frontend boot input write, got: {terminal_output:?}"
777758 ) ;
778759 }
779760
@@ -896,7 +877,7 @@ mod tests {
896877 }
897878
898879 #[ test]
899- fn terminal_write_routes_bound_terminal_input_to_tmux_runtime_env ( ) {
880+ fn terminal_write_routes_bound_terminal_input_to_pty_runtime_env ( ) {
900881 let app = test_app ( ) ;
901882 let workspace_id = launch_test_workspace ( & app, "/tmp/runtime-terminal-write-bridge" ) ;
902883 let session = create_session (
@@ -908,6 +889,8 @@ mod tests {
908889 . unwrap ( ) ;
909890 * app. state ( ) . hook_endpoint . lock ( ) . unwrap ( ) = Some ( "http://127.0.0.1:1/claude-hook" . into ( ) ) ;
910891
892+ let env_file = format ! ( "/tmp/runtime-terminal-write-{}.txt" , session. id) ;
893+
911894 app_settings_update (
912895 serde_json:: json!( {
913896 "providers" : {
@@ -916,7 +899,7 @@ mod tests {
916899 "executable" : "/bin/sh" ,
917900 "startupArgs" : [
918901 "-lc" ,
919- "sleep 0.1"
902+ format! ( "echo $CODER_STUDIO_SESSION_ID > {}" , env_file )
920903 ]
921904 }
922905 }
@@ -926,7 +909,7 @@ mod tests {
926909 )
927910 . expect ( "settings update should succeed" ) ;
928911
929- let started = session_runtime_start (
912+ session_runtime_start (
930913 SessionRuntimeStartParams {
931914 workspace_id : workspace_id. clone ( ) ,
932915 session_id : session. id . clone ( ) ,
@@ -938,34 +921,25 @@ mod tests {
938921 )
939922 . expect ( "session runtime should start" ) ;
940923
941- crate :: services:: terminal:: terminal_write (
942- workspace_id. clone ( ) ,
943- started. terminal_id ,
944- "printf 'BRIDGE:%s\n ' \" $CODER_STUDIO_SESSION_ID\" \r " . to_string ( ) ,
945- TerminalWriteOrigin :: User ,
946- app. state ( ) ,
947- )
948- . expect ( "terminal write should succeed" ) ;
949-
950- let expected = format ! ( "BRIDGE:{}" , session. id) ;
951- let mut terminal_output = String :: new ( ) ;
924+ // Wait for the boot command to execute and write the env var to the file.
925+ let expected_content = session. id . clone ( ) ;
926+ let mut found = false ;
952927 for _ in 0 ..40 {
953- terminal_output = load_workspace_snapshot ( app. state ( ) , & workspace_id)
954- . expect ( "workspace snapshot should load" )
955- . terminals
956- . into_iter ( )
957- . find ( |terminal| terminal. id == started. terminal_id )
958- . map ( |terminal| terminal. output )
959- . unwrap_or_default ( ) ;
960- if terminal_output. contains ( & expected) {
961- break ;
928+ if let Ok ( content) = std:: fs:: read_to_string ( & env_file) {
929+ if content. trim ( ) == expected_content {
930+ found = true ;
931+ break ;
932+ }
962933 }
963934 std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 50 ) ) ;
964935 }
965936
966937 assert ! (
967- terminal_output. contains( & expected) ,
968- "bound terminal input should execute inside tmux runtime env, got: {terminal_output:?}"
938+ found,
939+ "boot command should write Coder_Studio_SESSION_ID to file, file contents: {:?}" ,
940+ std:: fs:: read_to_string( & env_file) . ok( )
969941 ) ;
942+
943+ std:: fs:: remove_file ( & env_file) . ok ( ) ;
970944 }
971945}
0 commit comments