From e4e03fa0ddaafe7ae8f7ac59a6729adcc9bbba28 Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Wed, 28 May 2025 21:04:48 -0700 Subject: [PATCH] reverting timeout if no first chunk (#3899) * reverting timeout if no first chunk * Create fresh-days-end.md --------- Co-authored-by: Cline Evaluation Co-authored-by: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> --- .changeset/fresh-days-end.md | 5 +++ src/integrations/terminal/TerminalProcess.ts | 34 -------------------- 2 files changed, 5 insertions(+), 34 deletions(-) create mode 100644 .changeset/fresh-days-end.md diff --git a/.changeset/fresh-days-end.md b/.changeset/fresh-days-end.md new file mode 100644 index 0000000000..0aca1a1c47 --- /dev/null +++ b/.changeset/fresh-days-end.md @@ -0,0 +1,5 @@ +--- +"claude-dev": patch +--- + +Fix bug where terminal would get stuck and output "capture failure" diff --git a/src/integrations/terminal/TerminalProcess.ts b/src/integrations/terminal/TerminalProcess.ts index dfbaeb0e35..3ad076018d 100644 --- a/src/integrations/terminal/TerminalProcess.ts +++ b/src/integrations/terminal/TerminalProcess.ts @@ -35,42 +35,8 @@ export class TerminalProcess extends EventEmitter { let isFirstChunk = true let didOutputNonCommand = false let didEmitEmptyLine = false - let firstChunkTimeout: NodeJS.Timeout - - const isWindows = process.platform === "win32" - const timeoutMs = isWindows ? 5000 : 500 - - const onTimeout = () => { - // In rare cases (e.g. running the same command twice like `npm run build`), - // the shell integration stream enters a broken state where no data is ever emitted. - // We never even get the first chunk, which bricks the UI and locks the user out. - // Interestingly, the stream still gets created, and future commands (like `ls`) will work, - // suggesting the stream itself isn't one-shot—but certain shell states break its behavior. - // To recover, we add a timeout waiting for the first chunk. - // If it doesn’t arrive in time, we assume the terminal is broken, dispose it, - // and emit an error so the user can safely retry in a clean terminal. - - Logger.debug( - `[TerminalProcess.run] First chunk timeout hit — terminal likely in bad state. Terminating terminal.`, - ) - try { - terminal.dispose() - } catch (err) { - Logger.debug(`[TerminalProcess.run] Failed to dispose terminal: ${String(err)}`) - } - this.emit( - "error", - new Error("The command ran successfully, but we couldn't capture its output. Please proceed accordingly."), - ) - this.emit("completed") - this.emit("continue") - } - - firstChunkTimeout = setTimeout(onTimeout, timeoutMs) for await (let data of stream) { - clearTimeout(firstChunkTimeout) - // 1. Process chunk and remove artifacts if (isFirstChunk) { /*