diff --git a/packages/cli/src/ui/components/ShowMoreLines.tsx b/packages/cli/src/ui/components/ShowMoreLines.tsx index e19f877560..a3317d4dc6 100644 --- a/packages/cli/src/ui/components/ShowMoreLines.tsx +++ b/packages/cli/src/ui/components/ShowMoreLines.tsx @@ -31,7 +31,7 @@ export const ShowMoreLines = ({ constrainHeight }: ShowMoreLinesProps) => { } return ( - + Press ctrl-o to show more lines diff --git a/packages/cli/src/ui/components/messages/DenseToolMessage.tsx b/packages/cli/src/ui/components/messages/DenseToolMessage.tsx index 1c54f2f0fd..591e6e537e 100644 --- a/packages/cli/src/ui/components/messages/DenseToolMessage.tsx +++ b/packages/cli/src/ui/components/messages/DenseToolMessage.tsx @@ -25,6 +25,7 @@ export const DenseToolMessage: React.FC = ({ description, status, resultDisplay, + outputFile, }) => { let denseResult: string | undefined; @@ -54,22 +55,31 @@ export const DenseToolMessage: React.FC = ({ } return ( - - - - - {name} - + + + + + + {name} + + + + + {description} + + + {denseResult && ( + + + → {denseResult} + + + )} - - - {description} - - - {denseResult && ( - - - → {denseResult} + {outputFile && ( + + + (Output saved to: {outputFile}) )} diff --git a/packages/cli/src/ui/components/messages/ShellToolMessage.tsx b/packages/cli/src/ui/components/messages/ShellToolMessage.tsx index 80e5e0ff8e..fbbcda024d 100644 --- a/packages/cli/src/ui/components/messages/ShellToolMessage.tsx +++ b/packages/cli/src/ui/components/messages/ShellToolMessage.tsx @@ -167,7 +167,7 @@ export const ShellToolMessage: React.FC = ({ )} /> {isThisShellFocused && config && ( - + = ({ */ width={terminalWidth} paddingRight={TOOL_MESSAGE_HORIZONTAL_MARGIN} - marginBottom={1} + marginBottom={borderBottomOverride === false ? 0 : 1} > {visibleToolCalls.map((tool, index) => { const isConfirming = toolAwaitingApproval?.callId === tool.callId; @@ -218,106 +218,113 @@ export const ToolGroupMessage: React.FC = ({ ) : ( )} - - {tool.status === ToolCallStatus.Confirming && - isConfirming && - tool.confirmationDetails && ( - + {((tool.status === ToolCallStatus.Confirming && + isConfirming && + tool.confirmationDetails) || + tool.outputFile) && ( + + {tool.status === ToolCallStatus.Confirming && + isConfirming && + tool.confirmationDetails && ( + + )} + {tool.outputFile && ( + + + Output too long and was saved to: {tool.outputFile} + + )} - {tool.outputFile && ( - - - Output too long and was saved to: {tool.outputFile} - - - )} - + + )} ); })} - { - /* - We have to keep the bottom border separate so it doesn't get - drawn over by the sticky header directly inside it. - Only render if the last tool was displayed in full/verbose mode, - or if explicitly overridden. - */ - (() => { - if (visibleToolCalls.length === 0) { - if (borderBottomOverride !== undefined) { - return ( - - ); - } - return null; - } - - const lastTool = visibleToolCalls[visibleToolCalls.length - 1]; - const isShell = isShellTool(lastTool.name); - const isConfirming = lastTool.status === ToolCallStatus.Confirming; - - // Logic: If dense view (not verbose, not shell, not confirming), hide border by default - const isDense = !isVerboseMode && !isShell && !isConfirming; - let showBottomBorder = !isDense; + {(() => { + if (visibleToolCalls.length === 0) { + // If we are in dense mode, we generally don't want to draw a border for an empty group. + // HOWEVER, if borderBottomOverride is true, it means the scheduler explicitly + // wants to close a box. Since dense tools don't have boxes, this must be closing + // a non-dense (e.g. shell) tool box. So we must allow it. + if (!isVerboseMode && borderBottomOverride !== true) return null; if (borderBottomOverride !== undefined) { - showBottomBorder = borderBottomOverride; + return ( + + ); } + return null; + } - if (!showBottomBorder) return null; + const lastTool = visibleToolCalls[visibleToolCalls.length - 1]; + const isShell = isShellTool(lastTool.name); + const isConfirming = lastTool.status === ToolCallStatus.Confirming; - return ( - - ); - })() - } - {(borderBottomOverride ?? true) && visibleToolCalls.length > 0 && ( - - - - )} + // Logic: If dense view (not verbose, not shell, not confirming), hide border by default + const isDense = !isVerboseMode && !isShell && !isConfirming; + + if (isDense) return null; + + let showBottomBorder = true; + + if (borderBottomOverride !== undefined) { + showBottomBorder = borderBottomOverride; + } + + if (!showBottomBorder) return null; + + return ( + + ); + })()} + {!isVerboseMode + ? null + : (borderBottomOverride ?? true) && + visibleToolCalls.length > 0 && ( + + )} ); }; diff --git a/packages/cli/src/ui/components/messages/ToolMessage.tsx b/packages/cli/src/ui/components/messages/ToolMessage.tsx index 06ad6b3f7b..c6b24e11f0 100644 --- a/packages/cli/src/ui/components/messages/ToolMessage.tsx +++ b/packages/cli/src/ui/components/messages/ToolMessage.tsx @@ -116,7 +116,7 @@ export const ToolMessage: React.FC = ({ hasFocus={isThisShellFocused} /> {isThisShellFocused && config && ( - + > Ask User Filtering > does NOT filter out ask_user when status is Error 1`] = ` +"╭──────────────────────────────────────────────────────────────────────────╮ +│ x Ask User │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ +" +`; + +exports[` > Ask User Filtering > does NOT filter out ask_user when status is Success 1`] = ` +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ Ask User │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ +" +`; + +exports[` > Ask User Filtering > filters out ask_user when status is Confirming 1`] = `""`; + +exports[` > Ask User Filtering > filters out ask_user when status is Executing 1`] = `""`; + +exports[` > Ask User Filtering > filters out ask_user when status is Pending 1`] = `""`; + +exports[` > Ask User Filtering > shows other tools when ask_user is filtered out 1`] = ` +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ other-tool A tool for testing │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ +" +`; + exports[` > Border Color Logic > uses gray border when all tools are successful and no shell commands 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ test-tool A tool for testing │ -│ │ -│ Test result │ -│ │ -│ ✓ another-tool A tool for testing │ -│ │ -│ Test result │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ test-tool A tool for testing │ +│ │ +│ Test result │ +│ │ +│ ✓ another-tool A tool for testing │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Border Color Logic > uses yellow border for shell commands even when successful 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ run_shell_command A tool for testing │ -│ │ -│ Test result │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ run_shell_command A tool for testing │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Border Color Logic > uses yellow border when tools are pending 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ o test-tool A tool for testing │ -│ │ -│ Test result │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ o test-tool A tool for testing │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Confirmation Handling > renders confirmation with permanent approval disabled 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ? confirm-tool A tool for testing ← │ -│ │ -│ Test result │ -│ Do you want to proceed? │ -│ │ -│ Do you want to proceed? │ -│ │ -│ ● 1. Allow once │ -│ 2. Allow for this session │ -│ 3. No, suggest changes (esc) │ -│ │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ? confirm-tool A tool for testing ← │ +│ │ +│ Test result │ +│ Do you want to proceed? │ +│ Do you want to proceed? │ +│ │ +│ ● 1. Allow once │ +│ 2. Allow for this session │ +│ 3. No, suggest changes (esc) │ +│ │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Confirmation Handling > renders confirmation with permanent approval enabled 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ? confirm-tool A tool for testing ← │ -│ │ -│ Test result │ -│ Do you want to proceed? │ -│ │ -│ Do you want to proceed? │ -│ │ -│ ● 1. Allow once │ -│ 2. Allow for this session │ -│ 3. Allow for all future sessions │ -│ 4. No, suggest changes (esc) │ -│ │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ? confirm-tool A tool for testing ← │ +│ │ +│ Test result │ +│ Do you want to proceed? │ +│ Do you want to proceed? │ +│ │ +│ ● 1. Allow once │ +│ 2. Allow for this session │ +│ 3. Allow for all future sessions │ +│ 4. No, suggest changes (esc) │ +│ │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Confirmation Handling > shows confirmation dialog for first confirming tool only 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ? first-confirm A tool for testing ← │ -│ │ -│ Test result │ -│ Confirm first tool │ -│ │ -│ Do you want to proceed? │ -│ │ -│ ● 1. Allow once │ -│ 2. Allow for this session │ -│ 3. No, suggest changes (esc) │ -│ │ -│ │ -│ ? second-confirm A tool for testing │ -│ │ -│ Test result │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ? first-confirm A tool for testing ← │ +│ │ +│ Test result │ +│ Confirm first tool │ +│ Do you want to proceed? │ +│ │ +│ ● 1. Allow once │ +│ 2. Allow for this session │ +│ 3. No, suggest changes (esc) │ +│ │ +│ │ +│ ? second-confirm A tool for testing │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ +" +`; + +exports[` > Event-Driven Scheduler > hides confirming tools when event-driven scheduler is enabled 1`] = `""`; + +exports[` > Event-Driven Scheduler > renders nothing when only tool is in-progress AskUser with borderBottom=false 1`] = `""`; + +exports[` > Event-Driven Scheduler > shows only successful tools when mixed with confirming tools 1`] = ` +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ success-tool A tool for testing │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Golden Snapshots > renders empty tool calls array 1`] = `""`; exports[` > Golden Snapshots > renders header when scrolled 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ tool-1 Description 1. This is a long description that will need to be tr… │ -│──────────────────────────────────────────────────────────────────────────────│ -│ │ ▄ -│ ✓ tool-2 Description 2 │ █ -│ │ █ -│ line1 │ █ -│ line2 │ █ -╰──────────────────────────────────────────────────────────────────────────────╯ █ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ tool-1 Description 1. This is a long description that will need to b… │ +│──────────────────────────────────────────────────────────────────────────│ +│ │ ▄ +│ ✓ tool-2 Description 2 │ █ +│ │ █ +│ line1 │ █ +│ line2 │ █ +╰──────────────────────────────────────────────────────────────────────────╯ █ █" `; exports[` > Golden Snapshots > renders mixed tool calls including shell command 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ read_file Read a file │ -│ │ -│ Test result │ -│ │ -│ ⊷ run_shell_command Run command │ -│ │ -│ Test result │ -│ │ -│ o write_file Write to file │ -│ │ -│ Test result │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ read_file Read a file │ +│ │ +│ Test result │ +│ │ +│ ⊷ run_shell_command Run command │ +│ │ +│ Test result │ +│ │ +│ o write_file Write to file │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Golden Snapshots > renders multiple tool calls with different statuses 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ successful-tool This tool succeeded │ -│ │ -│ Test result │ -│ │ -│ o pending-tool This tool is pending │ -│ │ -│ Test result │ -│ │ -│ x error-tool This tool failed │ -│ │ -│ Test result │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ successful-tool This tool succeeded │ +│ │ +│ Test result │ +│ │ +│ o pending-tool This tool is pending │ +│ │ +│ Test result │ +│ │ +│ x error-tool This tool failed │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Golden Snapshots > renders shell command with yellow border 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ run_shell_command Execute shell command │ -│ │ -│ Test result │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ run_shell_command Execute shell command │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Golden Snapshots > renders single successful tool call 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ test-tool A tool for testing │ -│ │ -│ Test result │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ test-tool A tool for testing │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Golden Snapshots > renders tool call awaiting confirmation 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ? confirmation-tool This tool needs confirmation ← │ -│ │ -│ Test result │ -│ Are you sure you want to proceed? │ -│ │ -│ Do you want to proceed? │ -│ │ -│ ● 1. Allow once │ -│ 2. Allow for this session │ -│ 3. No, suggest changes (esc) │ -│ │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ? confirmation-tool This tool needs confirmation ← │ +│ │ +│ Test result │ +│ Are you sure you want to proceed? │ +│ Do you want to proceed? │ +│ │ +│ ● 1. Allow once │ +│ 2. Allow for this session │ +│ 3. No, suggest changes (esc) │ +│ │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Golden Snapshots > renders tool call with outputFile 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ tool-with-file Tool that saved output to file │ -│ │ -│ Test result │ -│ Output too long and was saved to: /path/to/output.txt │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ tool-with-file Tool that saved output to file │ +│ │ +│ Test result │ +│ Output too long and was saved to: /path/to/output.txt │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Golden Snapshots > renders two tool groups where only the last line of the previous group is visible 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ tool-2 Description 2 │ -│ │ -│ line1 │ ▄ -╰──────────────────────────────────────────────────────────────────────────────╯ █ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ tool-2 Description 2 │ +│ │ +│ line1 │ ▄ +╰──────────────────────────────────────────────────────────────────────────╯ █ █" `; exports[` > Golden Snapshots > renders when not focused 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ test-tool A tool for testing │ -│ │ -│ Test result │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ test-tool A tool for testing │ +│ │ +│ Test result │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Golden Snapshots > renders with limited terminal height 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ tool-with-result Tool with output │ -│ │ -│ This is a long result that might need height constraints │ -│ │ -│ ✓ another-tool Another tool │ -│ │ -│ More output here │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ tool-with-result Tool with output │ +│ │ +│ This is a long result that might need height constraints │ +│ │ +│ ✓ another-tool Another tool │ +│ │ +│ More output here │ +╰──────────────────────────────────────────────────────────────────────────╯ " `; exports[` > Golden Snapshots > renders with narrow terminal width 1`] = ` -"╭──────────────────────────────────────╮ -│ ✓ very-long-tool-name-that-might-w… │ -│ │ -│ Test result │ -╰──────────────────────────────────────╯ +"╭──────────────────────────────────╮ +│ ✓ very-long-tool-name-that-mig… │ +│ │ +│ Test result │ +╰──────────────────────────────────╯ " `; exports[` > Height Calculation > calculates available height correctly with multiple tools with results 1`] = ` -"╭──────────────────────────────────────────────────────────────────────────────╮ -│ ✓ test-tool A tool for testing │ -│ │ -│ Result 1 │ -│ │ -│ ✓ test-tool A tool for testing │ -│ │ -│ Result 2 │ -│ │ -│ ✓ test-tool A tool for testing │ -│ │ -╰──────────────────────────────────────────────────────────────────────────────╯ +"╭──────────────────────────────────────────────────────────────────────────╮ +│ ✓ test-tool A tool for testing │ +│ │ +│ Result 1 │ +│ │ +│ ✓ test-tool A tool for testing │ +│ │ +│ Result 2 │ +│ │ +│ ✓ test-tool A tool for testing │ +│ │ +╰──────────────────────────────────────────────────────────────────────────╯ " `;