@@ -25,7 +25,6 @@ import {
2525 addLineNumbers ,
2626 stripLineNumbers ,
2727 everyLineHasLineNumbers ,
28- truncateOutput ,
2928} from "../integrations/misc/extract-text"
3029import { TerminalManager , ExitCodeDetails } from "../integrations/terminal/TerminalManager"
3130import { UrlContentFetcher } from "../services/browser/UrlContentFetcher"
@@ -55,11 +54,12 @@ import { HistoryItem } from "../shared/HistoryItem"
5554import { ClineAskResponse } from "../shared/WebviewMessage"
5655import { GlobalFileNames } from "../shared/globalFileNames"
5756import { defaultModeSlug , getModeBySlug , getFullModeDetails } from "../shared/modes"
57+ import { EXPERIMENT_IDS , experiments as Experiments , ExperimentId } from "../shared/experiments"
5858import { calculateApiCost } from "../utils/cost"
5959import { fileExistsAtPath } from "../utils/fs"
6060import { arePathsEqual , getReadablePath } from "../utils/path"
6161import { parseMentions } from "./mentions"
62- import { RooIgnoreController , LOCK_TEXT_SYMBOL } from "./ignore/RooIgnoreController"
62+ import { RooIgnoreController } from "./ignore/RooIgnoreController"
6363import { AssistantMessageContent , parseAssistantMessage , ToolParamName , ToolUseName } from "./assistant-message"
6464import { formatResponse } from "./prompts/responses"
6565import { SYSTEM_PROMPT } from "./prompts/system"
@@ -70,7 +70,7 @@ import { BrowserSession } from "../services/browser/BrowserSession"
7070import { McpHub } from "../services/mcp/McpHub"
7171import crypto from "crypto"
7272import { insertGroups } from "./diff/insert-groups"
73- import { EXPERIMENT_IDS , experiments as Experiments , ExperimentId } from "../shared/experiments "
73+ import { OutputBuilder } from "../integrations/terminal/OutputBuilder "
7474
7575const cwd =
7676 vscode . workspace . workspaceFolders ?. map ( ( folder ) => folder . uri . fsPath ) . at ( 0 ) ?? path . join ( os . homedir ( ) , "Desktop" ) // may or may not exist but fs checking existence would immediately ask for permission which would be bad UX, need to come up with a better solution
@@ -912,44 +912,52 @@ export class Cline {
912912 // Tools
913913
914914 async executeCommandTool ( command : string ) : Promise < [ boolean , ToolResponse ] > {
915+ const { terminalOutputLimit } = ( await this . providerRef . deref ( ) ?. getState ( ) ) ?? { }
916+
915917 const terminalInfo = await this . terminalManager . getOrCreateTerminal ( cwd )
916- terminalInfo . terminal . show ( ) // weird visual bug when creating new terminals (even manually) where there's an empty space at the top.
917- const process = this . terminalManager . runCommand ( terminalInfo , command )
918+ // Weird visual bug when creating new terminals (even manually) where
919+ // there's an empty space at the top.
920+ terminalInfo . terminal . show ( )
921+ const process = this . terminalManager . runCommand ( terminalInfo , command , terminalOutputLimit )
918922
919923 let userFeedback : { text ?: string ; images ?: string [ ] } | undefined
920924 let didContinue = false
921- const sendCommandOutput = async ( line : string ) : Promise < void > => {
925+
926+ const sendCommandOutput = async ( line : string ) => {
922927 try {
923928 const { response, text, images } = await this . ask ( "command_output" , line )
929+
924930 if ( response === "yesButtonClicked" ) {
925- // proceed while running
931+ // Proceed while running.
926932 } else {
927933 userFeedback = { text, images }
928934 }
935+
929936 didContinue = true
930- process . continue ( ) // continue past the await
937+ process . continue ( ) // Continue past the await.
931938 } catch {
932- // This can only happen if this ask promise was ignored, so ignore this error
939+ // This can only happen if this ask promise was ignored, so ignore this error.
933940 }
934941 }
935942
936- let lines : string [ ] = [ ]
943+ let completed = false
944+ let exitDetails : ExitCodeDetails | undefined
945+
946+ let builder = new OutputBuilder ( { maxSize : terminalOutputLimit } )
947+ let output : string | undefined = undefined
948+
937949 process . on ( "line" , ( line ) => {
938- lines . push ( line )
950+ builder . append ( line )
951+
939952 if ( ! didContinue ) {
940953 sendCommandOutput ( line )
941954 } else {
942955 this . say ( "command_output" , line )
943956 }
944957 } )
945958
946- let completed = false
947- let exitDetails : ExitCodeDetails | undefined
948- process . once ( "completed" , ( output ?: string ) => {
949- // Use provided output if available, otherwise keep existing result.
950- if ( output ) {
951- lines = output . split ( "\n" )
952- }
959+ process . once ( "completed" , ( buffer ?: string ) => {
960+ output = buffer
953961 completed = true
954962 } )
955963
@@ -965,19 +973,17 @@ export class Cline {
965973
966974 await process
967975
968- // Wait for a short delay to ensure all messages are sent to the webview
976+ // Wait for a short delay to ensure all messages are sent to the webview.
969977 // This delay allows time for non-awaited promises to be created and
970978 // for their associated messages to be sent to the webview, maintaining
971979 // the correct order of messages (although the webview is smart about
972- // grouping command_output messages despite any gaps anyways)
980+ // grouping command_output messages despite any gaps anyways).
973981 await delay ( 50 )
974-
975- const { terminalOutputLineLimit } = ( await this . providerRef . deref ( ) ?. getState ( ) ) ?? { }
976- const output = truncateOutput ( lines . join ( "\n" ) , terminalOutputLineLimit )
977- const result = output . trim ( )
982+ const result = output || builder . content
978983
979984 if ( userFeedback ) {
980985 await this . say ( "user_feedback" , userFeedback . text , userFeedback . images )
986+
981987 return [
982988 true ,
983989 formatResponse . toolResult (
@@ -991,25 +997,28 @@ export class Cline {
991997
992998 if ( completed ) {
993999 let exitStatus = "No exit code available"
1000+
9941001 if ( exitDetails !== undefined ) {
9951002 if ( exitDetails . signal ) {
9961003 exitStatus = `Process terminated by signal ${ exitDetails . signal } (${ exitDetails . signalName } )`
1004+
9971005 if ( exitDetails . coreDumpPossible ) {
9981006 exitStatus += " - core dump possible"
9991007 }
10001008 } else {
10011009 exitStatus = `Exit code: ${ exitDetails . exitCode } `
10021010 }
10031011 }
1012+
10041013 return [ false , `Command executed. ${ exitStatus } ${ result . length > 0 ? `\nOutput:\n${ result } ` : "" } ` ]
1005- } else {
1006- return [
1007- false ,
1008- `Command is still running in the user's terminal.${
1009- result . length > 0 ? `\nHere's the output so far:\n${ result } ` : ""
1010- } \n\nYou will be updated on the terminal status and new output in the future.`,
1011- ]
10121014 }
1015+
1016+ return [
1017+ false ,
1018+ `Command is still running in the user's terminal.${
1019+ result . length > 0 ? `\nHere's the output so far:\n${ result } ` : ""
1020+ } \n\nYou will be updated on the terminal status and new output in the future.`,
1021+ ]
10131022 }
10141023
10151024 async * attemptApiRequest ( previousApiReqIndex : number , retryAttempt : number = 0 ) : ApiStream {
@@ -3495,7 +3504,7 @@ export class Cline {
34953504 terminalDetails += "\n\n# Actively Running Terminals"
34963505 for ( const busyTerminal of busyTerminals ) {
34973506 terminalDetails += `\n## Original command: \`${ busyTerminal . lastCommand } \``
3498- const newOutput = this . terminalManager . getUnretrievedOutput ( busyTerminal . id )
3507+ const newOutput = this . terminalManager . readLine ( busyTerminal . id )
34993508 if ( newOutput ) {
35003509 terminalDetails += `\n### New Output\n${ newOutput } `
35013510 } else {
@@ -3507,7 +3516,7 @@ export class Cline {
35073516 if ( inactiveTerminals . length > 0 ) {
35083517 const inactiveTerminalOutputs = new Map < number , string > ( )
35093518 for ( const inactiveTerminal of inactiveTerminals ) {
3510- const newOutput = this . terminalManager . getUnretrievedOutput ( inactiveTerminal . id )
3519+ const newOutput = this . terminalManager . readLine ( inactiveTerminal . id )
35113520 if ( newOutput ) {
35123521 inactiveTerminalOutputs . set ( inactiveTerminal . id , newOutput )
35133522 }
0 commit comments