diff --git a/src/integrations/terminal/Terminal.ts b/src/integrations/terminal/Terminal.ts index 8bf2072f3d..d32578d916 100644 --- a/src/integrations/terminal/Terminal.ts +++ b/src/integrations/terminal/Terminal.ts @@ -9,6 +9,8 @@ import { mergePromise } from "./mergePromise" export class Terminal extends BaseTerminal { public terminal: vscode.Terminal + private isNewlyCreated: boolean = false + private firstCommandExecuted: boolean = false public cmdCounter: number = 0 @@ -19,6 +21,9 @@ export class Terminal extends BaseTerminal { const iconPath = new vscode.ThemeIcon("rocket") this.terminal = terminal ?? vscode.window.createTerminal({ cwd, name: "Roo Code", iconPath, env }) + // Mark if this is a newly created terminal + this.isNewlyCreated = terminal === undefined + if (Terminal.getTerminalZdotdir()) { ShellIntegrationManager.terminalTmpDirs.set(id, env.ZDOTDIR) } @@ -71,10 +76,18 @@ export class Terminal extends BaseTerminal { pWaitFor(() => this.terminal.shellIntegration !== undefined, { timeout: Terminal.getShellIntegrationTimeout(), }) - .then(() => { + .then(async () => { // Clean up temporary directory if shell integration is available, zsh did its job: ShellIntegrationManager.zshCleanupTmpDir(this.id) + // For newly created terminals on the first command, add a small delay + // to ensure the shell integration stream is fully ready + if (this.isNewlyCreated && !this.firstCommandExecuted) { + console.log(`[Terminal ${this.id}] Adding delay for first command in new terminal`) + await new Promise((resolve) => setTimeout(resolve, 200)) + this.firstCommandExecuted = true + } + // Run the command in the terminal process.run(command) }) diff --git a/src/integrations/terminal/TerminalProcess.ts b/src/integrations/terminal/TerminalProcess.ts index eb0424fe8d..be3aac2605 100644 --- a/src/integrations/terminal/TerminalProcess.ts +++ b/src/integrations/terminal/TerminalProcess.ts @@ -158,6 +158,7 @@ export class TerminalProcess extends BaseTerminalProcess { let preOutput = "" let commandOutputStarted = false + let streamDataReceived = false /* * Extract clean output from raw accumulated output. FYI: @@ -171,6 +172,8 @@ export class TerminalProcess extends BaseTerminalProcess { // Process stream data for await (let data of stream) { + streamDataReceived = true + // Check for command output start marker if (!commandOutputStarted) { preOutput += data @@ -182,7 +185,24 @@ export class TerminalProcess extends BaseTerminalProcess { this.fullOutput = "" // Reset fullOutput when command actually starts this.emit("line", "") // Trigger UI to proceed } else { - continue + // For the first chunk of data, if we don't see markers yet, + // wait a bit more to see if they arrive in the next chunk + if (!streamDataReceived && preOutput.length < 100) { + continue + } + // If we have accumulated enough preOutput without finding markers, + // treat it as command output to avoid losing data + if (preOutput.length > 500) { + console.warn( + `[Terminal Process] No start markers found after ${preOutput.length} chars, treating as output`, + ) + commandOutputStarted = true + data = preOutput + this.fullOutput = "" + this.emit("line", "") + } else { + continue + } } }