@@ -1294,38 +1294,90 @@ def _execute_block_commands_sequential(
12941294) -> ExecutionResult :
12951295 """Execute block commands sequentially, printing output after each command.
12961296
1297+ For local blocks, commands are executed one at a time for verbose output.
1298+ For remote blocks, all commands are executed in a single SSH connection
1299+ to preserve execution state (e.g., working directory) between commands.
1300+
12971301 Returns:
12981302 ExecutionResult combining all command outputs.
12991303 """
1300- # ANSI color codes
1301- RED = "\033 [91m"
1302- DIM = "\033 [90m"
1304+ if verbose :
1305+ _print_block_header (block , block_index , total_blocks )
1306+
1307+ commands_to_execute = _iter_display_commands (block .commands )
1308+
1309+ if block .is_remote :
1310+ return _execute_remote_block_sequential (block , context , no_input , verbose , commands_to_execute )
1311+
1312+ return _execute_local_block_sequential (block , context , no_input , verbose , commands_to_execute )
1313+
1314+
1315+ def _print_block_header (block : Block , block_index : int , total_blocks : int ) -> None :
1316+ """Print block header for verbose output."""
13031317 BLUE = "\033 [94m"
13041318 YELLOW = "\033 [93m"
13051319 RESET = "\033 [0m"
13061320
1307- # Print block header if verbose
1321+ if block .is_local :
1322+ print (f"{ BLUE } [{ block_index } /{ total_blocks } ] LOCAL{ RESET } " )
1323+ else :
1324+ host = block .host or "unknown"
1325+ print (f"{ YELLOW } [{ block_index } /{ total_blocks } ] REMOTE: { host } { RESET } " )
1326+
1327+
1328+ def _execute_remote_block_sequential (
1329+ block : Block ,
1330+ context : ExecutionContext ,
1331+ no_input : bool ,
1332+ verbose : bool ,
1333+ commands_to_execute : list [str ],
1334+ ) -> ExecutionResult :
1335+ """Execute remote block commands in a single SSH connection."""
1336+ RED = "\033 [91m"
1337+ DIM = "\033 [90m"
1338+ RESET = "\033 [0m"
1339+
13081340 if verbose :
1309- if block .is_local :
1310- print (f"{ BLUE } [{ block_index } /{ total_blocks } ] LOCAL{ RESET } " )
1311- else :
1312- host = block .host or "unknown"
1313- print (f"{ YELLOW } [{ block_index } /{ total_blocks } ] REMOTE: { host } { RESET } " )
1341+ for cmd in commands_to_execute :
1342+ print (f"{ DIM } $ { cmd } { RESET } " )
1343+
1344+ result = _execute_block_once (block , context , no_input = no_input )
1345+
1346+ if verbose and result .output :
1347+ truncated = _truncate_output_lines (result .output , MAX_OUTPUT_LINES )
1348+ print (truncated )
1349+
1350+ context .last_output = result .output
1351+ context .success = result .success
1352+
1353+ if not result .success and verbose :
1354+ print (f"{ RED } ✗ Command failed with exit code { result .exit_code } { RESET } \n " )
1355+
1356+ return result
1357+
1358+
1359+ def _execute_local_block_sequential (
1360+ block : Block ,
1361+ context : ExecutionContext ,
1362+ no_input : bool ,
1363+ verbose : bool ,
1364+ commands_to_execute : list [str ],
1365+ ) -> ExecutionResult :
1366+ """Execute local block commands one at a time for verbose output."""
1367+ RED = "\033 [91m"
1368+ DIM = "\033 [90m"
1369+ RESET = "\033 [0m"
13141370
13151371 all_outputs : list [str ] = []
13161372 all_stdout : list [str ] = []
13171373 all_stderr : list [str ] = []
13181374 final_exit_code = 0
13191375 success = True
13201376
1321- commands_to_execute = _iter_display_commands (block .commands )
1322-
13231377 for cmd in commands_to_execute :
1324- # Print the command being executed
13251378 if verbose :
13261379 print (f"{ DIM } $ { cmd } { RESET } " )
13271380
1328- # Execute single command using a single-command block
13291381 single_block = Block (
13301382 target = block .target ,
13311383 commands = [cmd ],
@@ -1334,19 +1386,16 @@ def _execute_block_commands_sequential(
13341386 )
13351387 result = _execute_block_once (single_block , context , no_input = no_input )
13361388
1337- # Store outputs
13381389 all_outputs .append (result .output )
13391390 if result .stdout :
13401391 all_stdout .append (result .stdout )
13411392 if result .stderr :
13421393 all_stderr .append (result .stderr )
13431394
1344- # Print output immediately with truncation
13451395 if verbose and result .output :
13461396 truncated = _truncate_output_lines (result .output , MAX_OUTPUT_LINES )
13471397 print (truncated )
13481398
1349- # Check for failure
13501399 if not result .success :
13511400 final_exit_code = result .exit_code
13521401 success = False
@@ -1358,7 +1407,6 @@ def _execute_block_commands_sequential(
13581407 combined_stdout = "\n " .join (filter (None , all_stdout ))
13591408 combined_stderr = "\n " .join (filter (None , all_stderr ))
13601409
1361- # Update context
13621410 context .last_output = combined_output
13631411 context .success = success
13641412
0 commit comments