Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/cli/src/ui/__snapshots__/App.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,21 @@ HistoryItemDisplay
│ │
│ ? ls list directory │
│ │
│ ls │
│ Allow execution of: 'ls'? │
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ ls │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ Allow execution of [ls]? │
│ │
│ ● 1. Allow once │
│ 2. Allow for this session │
│ 3. No, suggest changes (esc) │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯







Notifications

Composer
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Full Terminal Tool Confirmation Snapshot > renders tool confirmation box in the frame of the entire terminal 1`] = `
"▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
"4. Be specific for the best results
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
> Can you edit InputPrompt.tsx for me?
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Action Required │
│ │
│ ? Edit packages/.../InputPrompt.tsx: return kittyProtocolSupporte... => return kittyProto… │
│ │
│ ... first 44 lines hidden (Ctrl+O to show) ... │
│ 45 const line45 = true; │
│ 46 const line46 = true; │
│ 47 const line47 = true; │█
│ 48 const line48 = true; │█
│ 49 const line49 = true; │█
│ 50 const line50 = true; │█
│ 51 const line51 = true; │█
│ 52 const line52 = true; │█
│ 53 const line53 = true; │█
│ 54 const line54 = true; │█
│ 55 const line55 = true; │█
│ 56 const line56 = true; │█
│ 57 const line57 = true; │█
│ 58 const line58 = true; │█
│ 59 const line59 = true; │█
│ 60 const line60 = true; │█
│ 61 - return kittyProtocolSupporte...; │█
│ 61 + return kittyProtocolSupporte...; │█
│ 62 buffer: TextBuffer; │█
│ 63 onSubmit: (value: string) => void; │█
│ ? Edit │
│ ╭─────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ ... first 43 lines hidden (Ctrl+O to show) ... │ │
│ │ 44 const line44 = true; │ │
│ │ 45 const line45 = true; │ │
│ │ 46 const line46 = true; │ │█
│ │ 47 const line47 = true; │ │█
│ │ 48 const line48 = true; │ │█
│ │ 49 const line49 = true; │ │█
│ │ 50 const line50 = true; │ │█
│ │ 51 const line51 = true; │ │█
│ │ 52 const line52 = true; │ │█
│ │ 53 const line53 = true; │ │█
│ │ 54 const line54 = true; │ │█
│ │ 55 const line55 = true; │ │█
│ │ 56 const line56 = true; │ │█
│ │ 57 const line57 = true; │ │█
│ │ 58 const line58 = true; │ │█
│ │ 59 const line59 = true; │ │█
│ │ 60 const line60 = true; │ │█
│ │ 61 - return kittyProtocolSupporte...; │ │█
│ │ 61 + return kittyProtocolSupporte...; │ │█
│ │ 62 buffer: TextBuffer; │ │█
│ │ 63 onSubmit: (value: string) => void; │ │█
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ │█
│ Apply this change? │█
│ │█
│ ● 1. Allow once │█
│ 2. Allow for this session │█
│ 3. Allow for this file in all future sessions │█
│ 3. Allow for this file in all future sessions ~/.gemini/policies/auto-saved.toml │█
│ 4. Modify with external editor │█
│ 5. No, suggest changes (esc) │█
│ │█
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯█
"
`;
92 changes: 78 additions & 14 deletions packages/cli/src/ui/components/ToolConfirmationQueue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import { Box, Text } from 'ink';
import { theme } from '../semantic-colors.js';
import { useConfig } from '../contexts/ConfigContext.js';
import { ToolConfirmationMessage } from './messages/ToolConfirmationMessage.js';
import { ToolStatusIndicator, ToolInfo } from './messages/ToolShared.js';
import {
isShellTool,
ToolStatusIndicator,
ToolInfo,
} from './messages/ToolShared.js';
import { useUIState } from '../contexts/UIStateContext.js';
import type { ConfirmingToolState } from '../hooks/useConfirmingTool.js';
import { StickyHeader } from './StickyHeader.js';
Expand All @@ -31,6 +35,16 @@ function getConfirmationHeader(
return headers[details.type] ?? 'Action Required';
}

function getConfirmationLabel(
toolName: string,
details: SerializableConfirmationDetails | undefined,
): string {
if (details?.type === 'ask_user') return 'Questions';
if (details?.type === 'exit_plan_mode') return 'Implementation';
if (isShellTool(toolName)) return 'Shell';
return toolName;
}

interface ToolConfirmationQueueProps {
confirmingTool: ConfirmingToolState;
}
Expand Down Expand Up @@ -58,22 +72,78 @@ export const ToolConfirmationQueue: React.FC<ToolConfirmationQueueProps> = ({
? Math.max(uiAvailableHeight, 4)
: Math.floor(terminalHeight * 0.5);

const isShell = isShellTool(tool.name);
const isEdit = tool.confirmationDetails?.type === 'edit';

if (isShell || isEdit) {
// Use the new simplified layout for Shell and Edit tools
const borderColor = theme.border.default;
const availableContentHeight = constrainHeight
? Math.max(maxHeight - 3, 4)
: undefined;

const toolLabel = getConfirmationLabel(tool.name, tool.confirmationDetails);

return (
<Box
flexDirection="column"
width={mainAreaWidth}
flexShrink={0}
borderStyle="round"
borderColor={borderColor}
paddingX={1}
>
{/* Header Line */}
<Box justifyContent="space-between" marginBottom={0}>
<Box flexDirection="row" flexShrink={1} overflow="hidden">
<Text color={theme.status.warning} bold>
? {toolLabel}
{!isEdit && !!tool.description && ' '}
</Text>
{!isEdit && !!tool.description && (
<Box flexShrink={1} overflow="hidden">
<Text color={theme.text.primary} wrap="truncate-end">
{tool.description}
</Text>
</Box>
)}
</Box>
{total > 1 && (
<Text color={theme.text.secondary}>
{index} of {total}
</Text>
)}
</Box>

{/* Interactive Area */}
<Box flexDirection="column">
<ToolConfirmationMessage
callId={tool.callId}
confirmationDetails={tool.confirmationDetails}
config={config}
getPreferredEditor={getPreferredEditor}
terminalWidth={mainAreaWidth - 4} // Adjust for parent border/padding
availableTerminalHeight={availableContentHeight}
toolName={tool.name}
isFocused={true}
/>
</Box>
</Box>
);
}

// Restore original logic for other tools
const isRoutine =
tool.confirmationDetails?.type === 'ask_user' ||
tool.confirmationDetails?.type === 'exit_plan_mode';
const borderColor = isRoutine ? theme.status.success : theme.status.warning;
const hideToolIdentity = isRoutine;

// ToolConfirmationMessage needs to know the height available for its OWN content.
// We subtract the lines used by the Queue wrapper:
// - 2 lines for the rounded border
// - 2 lines for the Header (text + margin)
// - 2 lines for Tool Identity (text + margin)
const availableContentHeight = constrainHeight
? Math.max(maxHeight - (hideToolIdentity ? 4 : 6), 4)
: undefined;

const content = (
return (
<Box flexDirection="column" width={mainAreaWidth} flexShrink={0}>
<StickyHeader
width={mainAreaWidth}
Expand Down Expand Up @@ -122,18 +192,14 @@ export const ToolConfirmationQueue: React.FC<ToolConfirmationQueueProps> = ({
paddingX={1}
flexDirection="column"
>
{/* Interactive Area */}
{/*
Note: We force isFocused={true} because if this component is rendered,
it effectively acts as a modal over the shell/composer.
*/}
<ToolConfirmationMessage
callId={tool.callId}
confirmationDetails={tool.confirmationDetails}
config={config}
getPreferredEditor={getPreferredEditor}
terminalWidth={mainAreaWidth - 4} // Adjust for parent border/padding
availableTerminalHeight={availableContentHeight}
toolName={tool.name}
isFocused={true}
/>
</Box>
Expand All @@ -149,6 +215,4 @@ export const ToolConfirmationQueue: React.FC<ToolConfirmationQueueProps> = ({
/>
</Box>
);

return content;
};
Loading
Loading