@@ -214,57 +214,65 @@ impl Terminal {
214214 . take_receiver ( )
215215 . ok_or ( "Cancellation receiver already taken" ) ?;
216216
217- // Accumulator for terminal output (shared between reader tasks)
218217 let output_accumulator: Arc < RwLock < Vec < u8 > > > = Arc :: new ( RwLock :: new ( Vec :: new ( ) ) ) ;
219218
220- // Setup fs_var for local terminal or remote path for SSH
219+ let templated_code = if !self . code . is_empty ( ) {
220+ context. context_resolver . resolve_template ( & self . code ) ?
221+ } else {
222+ String :: new ( )
223+ } ;
224+
225+ let uses_output_vars = templated_code. contains ( "ATUIN_OUTPUT_VARS" ) ;
226+
227+ let ssh_host = context. context_resolver . ssh_host ( ) . cloned ( ) ;
221228 let fs_var_handle: Option < crate :: context:: fs_var:: FsVarHandle > ;
222- let remote_var_path: Option < ( String , Option < String > , String ) > ; // (hostname, username, path)
229+ let remote_var_path: Option < String > ;
223230
224- if let Some ( ssh_host ) = context . context_resolver . ssh_host ( ) {
231+ if let Some ( ref host ) = ssh_host {
225232 fs_var_handle = None ;
226233
227- // For SSH, create remote temp file
228- let ( username, hostname) = Self :: parse_ssh_host ( ssh_host ) ;
229- let ssh_pool = context
230- . ssh_pool
231- . clone ( )
232- . ok_or ( "SSH pool not available in execution context" ) ?;
234+ if uses_output_vars {
235+ let ( username, hostname) = Self :: parse_ssh_host ( host ) ;
236+ let ssh_pool = context
237+ . ssh_pool
238+ . clone ( )
239+ . ok_or ( "SSH pool not available in execution context" ) ?;
233240
234- let remote_path = ssh_pool
235- . create_temp_file ( & hostname, username. as_deref ( ) , "atuin-desktop-vars" )
236- . await
237- . map_err ( |e| format ! ( "Failed to create remote temp file: {}" , e) ) ?;
241+ let remote_path = ssh_pool
242+ . create_temp_file ( & hostname, username. as_deref ( ) , "atuin-desktop-vars" )
243+ . await
244+ . map_err ( |e| format ! ( "Failed to create remote temp file: {}" , e) ) ?;
238245
239- remote_var_path = Some ( ( hostname, username, remote_path) ) ;
246+ remote_var_path = Some ( remote_path) ;
247+ } else {
248+ remote_var_path = None ;
249+ }
240250 } else {
241- fs_var_handle =
242- Some ( crate :: context:: fs_var:: setup ( ) . map_err ( |e| {
243- format ! ( "Failed to setup temp file for output variables: {}" , e)
244- } ) ?) ;
251+ if uses_output_vars {
252+ fs_var_handle =
253+ Some ( crate :: context:: fs_var:: setup ( ) . map_err ( |e| {
254+ format ! ( "Failed to setup temp file for output variables: {}" , e)
255+ } ) ?) ;
256+ } else {
257+ fs_var_handle = None ;
258+ }
245259 remote_var_path = None ;
246260 }
247261
248- // Open PTY based on context (local or SSH)
249262 let cancellation_token_clone = cancellation_token. clone ( ) ;
250- let pty: Box < dyn PtyLike + Send > = if let Some ( (
251- ref hostname,
252- ref username,
253- ref remote_path,
254- ) ) = remote_var_path
255- {
256- // Get SSH pool from context
263+ let pty: Box < dyn PtyLike + Send > = if let Some ( ref host) = ssh_host {
264+ let ( username, hostname) = Self :: parse_ssh_host ( host) ;
257265 let ssh_pool = context
258266 . ssh_pool
259267 . clone ( )
260268 . ok_or ( "SSH pool not available in execution context" ) ?;
261269
262- // Create SSH PTY with cancellation support
263270 let ( output_sender, mut output_receiver) = tokio:: sync:: mpsc:: channel ( 100 ) ;
264271 let hostname_clone = hostname. clone ( ) ;
265272 let username_clone = username. clone ( ) ;
266273 let pty_id_str = self . id . to_string ( ) ;
267274 let ssh_pool_clone = ssh_pool. clone ( ) ;
275+ let remote_path_clone = remote_var_path. clone ( ) ;
268276
269277 let initial_cols = self . cols ;
270278 let initial_rows = self . rows ;
@@ -282,8 +290,9 @@ impl Terminal {
282290 _ = & mut cancel_rx => {
283291 let _ = ssh_pool_clone. close_pty( & pty_id_str) . await ;
284292 let _ = context. block_cancelled( ) . await ;
285- // Cleanup remote temp file if it was created
286- let _ = ssh_pool_clone. delete_file( & hostname_clone, username_clone. as_deref( ) , remote_path) . await ;
293+ if let Some ( ref path) = remote_path_clone {
294+ let _ = ssh_pool_clone. delete_file( & hostname_clone, username_clone. as_deref( ) , path) . await ;
295+ }
287296 return Err ( "SSH PTY connection cancelled" . into( ) ) ;
288297 }
289298 } ;
@@ -431,25 +440,21 @@ impl Terminal {
431440 . emit_gc_event ( GCEvent :: PtyOpened ( metadata. clone ( ) ) )
432441 . await ;
433442
434- // For SSH terminals, export ATUIN_OUTPUT_VARS first
435- if let Some ( ( _, _, ref remote_path) ) = remote_var_path {
443+ if let Some ( ref remote_path) = remote_var_path {
436444 let export_cmd = format ! ( "export ATUIN_OUTPUT_VARS='{}'\n " , remote_path) ;
437445 if let Err ( e) = pty_store. write_pty ( self . id , export_cmd. into ( ) ) . await {
438446 tracing:: warn!( "Failed to write export command to SSH PTY: {}" , e) ;
439447 }
440448 }
441449
442- // Write the command to the PTY after started event
443- if !self . code . is_empty ( ) {
444- let command = context. context_resolver . resolve_template ( & self . code ) ?;
445- let command = if command. ends_with ( '\n' ) {
446- command
450+ if !templated_code. is_empty ( ) {
451+ let command = if templated_code. ends_with ( '\n' ) {
452+ templated_code. clone ( )
447453 } else {
448- format ! ( "{}\n " , command )
454+ format ! ( "{}\n " , templated_code )
449455 } ;
450456
451457 if let Err ( e) = pty_store. write_pty ( self . id , command. into ( ) ) . await {
452- // Send error event if command writing fails
453458 let _ = context
454459 . block_failed ( format ! ( "Failed to write command to PTY: {}" , e) )
455460 . await ;
@@ -490,12 +495,12 @@ impl Terminal {
490495 tracing:: warn!( "Failed to read terminal output variables: {}" , e) ;
491496 }
492497 }
493- } else if let Some ( ( hostname , username , remote_path) ) = remote_var_path {
494- // SSH terminal
498+ } else if let ( Some ( ref host ) , Some ( ref remote_path) ) = ( & ssh_host , & remote_var_path) {
499+ let ( username , hostname ) = Self :: parse_ssh_host ( host ) ;
495500 let ssh_pool = context. ssh_pool . clone ( ) . unwrap ( ) ;
496501
497502 match ssh_pool
498- . read_file ( & hostname, username. as_deref ( ) , & remote_path)
503+ . read_file ( & hostname, username. as_deref ( ) , remote_path)
499504 . await
500505 {
501506 Ok ( contents) => {
@@ -520,9 +525,8 @@ impl Terminal {
520525 }
521526 }
522527
523- // Cleanup remote temp file
524528 let _ = ssh_pool
525- . delete_file ( & hostname, username. as_deref ( ) , & remote_path)
529+ . delete_file ( & hostname, username. as_deref ( ) , remote_path)
526530 . await ;
527531 }
528532
0 commit comments