@@ -7,6 +7,7 @@ import type { CancellationToken } from '../../../../../../base/common/cancellati
77import { CancellationError } from '../../../../../../base/common/errors.js' ;
88import { Event } from '../../../../../../base/common/event.js' ;
99import { DisposableStore } from '../../../../../../base/common/lifecycle.js' ;
10+ import { isNumber } from '../../../../../../base/common/types.js' ;
1011import type { ICommandDetectionCapability } from '../../../../../../platform/terminal/common/capabilities/capabilities.js' ;
1112import { ITerminalLogService } from '../../../../../../platform/terminal/common/terminal.js' ;
1213import type { ITerminalInstance } from '../../../../terminal/browser/terminal.js' ;
@@ -80,14 +81,22 @@ export class BasicExecuteStrategy implements ITerminalExecuteStrategy {
8081 this . _logService . debug ( 'RunInTerminalTool#Basic: Waiting for idle' ) ;
8182 await waitForIdle ( this . _instance . onData , 1000 ) ;
8283
84+ // Record where the command started. If the marker gets disposed, re-created it where
85+ // the cursor is. This can happen in prompts where they clear the line and rerender it
86+ // like powerlevel10k's transient prompt
87+ let startMarker = store . add ( xterm . raw . registerMarker ( ) ) ;
88+ store . add ( startMarker . onDispose ( ( ) => {
89+ this . _logService . debug ( `RunInTerminalTool#Basic: Start marker was disposed, recreating` ) ;
90+ startMarker = xterm . raw . registerMarker ( ) ;
91+ } ) ) ;
92+
8393 // Execute the command
84- const startMarker = store . add ( xterm . raw . registerMarker ( ) ) ;
8594 this . _logService . debug ( `RunInTerminalTool#Basic: Executing command line \`${ commandLine } \`` ) ;
8695 this . _instance . runCommand ( commandLine , true ) ;
8796
8897 // Wait for the next end execution event - note that this may not correspond to the actual
8998 // execution requested
90- const doneData = await onDone ;
99+ const finishedCommand = await onDone ;
91100
92101 // Wait for the terminal to idle
93102 this . _logService . debug ( 'RunInTerminalTool#Basic: Waiting for idle' ) ;
@@ -98,13 +107,36 @@ export class BasicExecuteStrategy implements ITerminalExecuteStrategy {
98107 const endMarker = store . add ( xterm . raw . registerMarker ( ) ) ;
99108
100109 // Assemble final result
101- let result = xterm . getContentsAsText ( startMarker , endMarker ) ;
102- if ( doneData && typeof doneData . exitCode === 'number' && doneData . exitCode > 0 ) {
103- result += `\n\nCommand exited with code ${ doneData . exitCode } ` ;
110+ let result : string | undefined ;
111+ if ( finishedCommand ) {
112+ const commandOutput = finishedCommand ?. getOutput ( ) ;
113+ if ( commandOutput !== undefined ) {
114+ this . _logService . debug ( 'RunInTerminalTool#Basic: Fetched output via finished command' ) ;
115+ result = commandOutput ;
116+ }
117+ }
118+ if ( result === undefined ) {
119+ try {
120+ result = xterm . getContentsAsText ( startMarker , endMarker ) ;
121+ this . _logService . debug ( 'RunInTerminalTool#Basic: Fetched output via markers' ) ;
122+ } catch {
123+ this . _logService . debug ( 'RunInTerminalTool#Basic: Failed to fetch output via markers' ) ;
124+ result = 'Failed to retrieve command output' ;
125+ }
126+ }
127+
128+ if ( result . trim ( ) . length === 0 ) {
129+ result = 'Command produced no output' ;
104130 }
131+
132+ const exitCode = finishedCommand ?. exitCode ;
133+ if ( isNumber ( exitCode ) && exitCode > 0 ) {
134+ result += `\n\nCommand exited with code ${ exitCode } ` ;
135+ }
136+
105137 return {
106138 result,
107- exitCode : doneData ?. exitCode ,
139+ exitCode,
108140 } ;
109141 } finally {
110142 store . dispose ( ) ;
0 commit comments