@@ -485,6 +485,19 @@ pub(crate) fn build_claude_resume_command(
485485 format ! ( "{command} --resume {claude_session_id}" )
486486}
487487
488+ #[ cfg_attr( not( target_os = "windows" ) , allow( dead_code) ) ]
489+ pub ( crate ) fn build_windows_native_agent_shell_invocation ( command : & str ) -> ( String , Vec < String > ) {
490+ (
491+ "cmd" . to_string ( ) ,
492+ vec ! [
493+ "/D" . to_string( ) ,
494+ "/S" . to_string( ) ,
495+ "/C" . to_string( ) ,
496+ command. to_string( ) ,
497+ ] ,
498+ )
499+ }
500+
488501pub ( crate ) fn build_agent_pty_command (
489502 target : & ExecTarget ,
490503 cwd : & str ,
@@ -505,8 +518,8 @@ pub(crate) fn build_agent_pty_command(
505518 } else {
506519 #[ cfg( target_os = "windows" ) ]
507520 {
508- let shell_cmd = build_agent_shell_command ( cwd, command , true ) ;
509- ( "cmd" . to_string ( ) , vec ! [ "/C" . to_string ( ) , shell_cmd ] )
521+ let _ = cwd;
522+ build_windows_native_agent_shell_invocation ( command )
510523 }
511524 #[ cfg( not( target_os = "windows" ) ) ]
512525 {
@@ -591,3 +604,27 @@ pub(crate) fn repo_name_from_url(url: &str) -> String {
591604 let name = trimmed. split ( '/' ) . next_back ( ) . unwrap_or ( "repo" ) ;
592605 name. trim_end_matches ( ".git" ) . to_string ( )
593606}
607+
608+ #[ cfg( test) ]
609+ mod tests {
610+ use super :: * ;
611+
612+ #[ test]
613+ fn build_windows_native_agent_shell_invocation_avoids_cd_wrapper ( ) {
614+ let command = r#"node D:\a\coder-studio\coder-studio\tests\e2e\fixtures\claude-lifecycle-agent.mjs --running-delay-ms 150"# ;
615+
616+ let ( program, args) = build_windows_native_agent_shell_invocation ( command) ;
617+
618+ assert_eq ! ( program, "cmd" ) ;
619+ assert_eq ! (
620+ args,
621+ vec![
622+ "/D" . to_string( ) ,
623+ "/S" . to_string( ) ,
624+ "/C" . to_string( ) ,
625+ command. to_string( )
626+ ]
627+ ) ;
628+ assert ! ( !args[ 3 ] . contains( "cd /d" ) ) ;
629+ }
630+ }
0 commit comments