mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-20 18:14:29 -07:00
Fix bottom border color (#19266)
This commit is contained in:
@@ -1286,7 +1286,9 @@ describe('handleAtCommand', () => {
|
||||
// Assert
|
||||
// It SHOULD be called for the tool_group
|
||||
expect(mockAddItem).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ type: 'tool_group' }),
|
||||
expect.objectContaining({
|
||||
type: 'tool_group',
|
||||
}),
|
||||
999,
|
||||
);
|
||||
|
||||
@@ -1343,7 +1345,9 @@ describe('handleAtCommand', () => {
|
||||
});
|
||||
expect(containsResourceText).toBe(true);
|
||||
expect(mockAddItem).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ type: 'tool_group' }),
|
||||
expect.objectContaining({
|
||||
type: 'tool_group',
|
||||
}),
|
||||
expect.any(Number),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -23,10 +23,15 @@ import {
|
||||
*/
|
||||
export function mapToDisplay(
|
||||
toolOrTools: ToolCall[] | ToolCall,
|
||||
options: { borderTop?: boolean; borderBottom?: boolean } = {},
|
||||
options: {
|
||||
borderTop?: boolean;
|
||||
borderBottom?: boolean;
|
||||
borderColor?: string;
|
||||
borderDimColor?: boolean;
|
||||
} = {},
|
||||
): HistoryItemToolGroup {
|
||||
const toolCalls = Array.isArray(toolOrTools) ? toolOrTools : [toolOrTools];
|
||||
const { borderTop, borderBottom } = options;
|
||||
const { borderTop, borderBottom, borderColor, borderDimColor } = options;
|
||||
|
||||
const toolDisplays = toolCalls.map((call): IndividualToolCallDisplay => {
|
||||
let description: string;
|
||||
@@ -104,5 +109,7 @@ export function mapToDisplay(
|
||||
tools: toolDisplays,
|
||||
borderTop,
|
||||
borderBottom,
|
||||
borderColor,
|
||||
borderDimColor,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import type { Part, PartListUnion } from '@google/genai';
|
||||
import type { UseHistoryManagerReturn } from './useHistoryManager.js';
|
||||
import type { SlashCommandProcessorResult } from '../types.js';
|
||||
import { MessageType, StreamingState } from '../types.js';
|
||||
|
||||
import type { LoadedSettings } from '../../config/settings.js';
|
||||
|
||||
// --- MOCKS ---
|
||||
|
||||
@@ -78,6 +78,8 @@ import {
|
||||
type TrackedWaitingToolCall,
|
||||
type TrackedExecutingToolCall,
|
||||
} from './useToolScheduler.js';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
import { getToolGroupBorderAppearance } from '../utils/borderStyles.js';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { useSessionStats } from '../contexts/SessionContext.js';
|
||||
@@ -250,6 +252,8 @@ export const useGeminiStream = (
|
||||
mapTrackedToolCallsToDisplay(toolsToPush as TrackedToolCall[], {
|
||||
borderTop: isFirstToolInGroupRef.current,
|
||||
borderBottom: true,
|
||||
borderColor: theme.border.default,
|
||||
borderDimColor: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -290,6 +294,45 @@ export const useGeminiStream = (
|
||||
getPreferredEditor,
|
||||
);
|
||||
|
||||
const activeToolPtyId = useMemo(() => {
|
||||
const executingShellTool = toolCalls.find(
|
||||
(tc) =>
|
||||
tc.status === 'executing' && tc.request.name === 'run_shell_command',
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
return (executingShellTool as TrackedExecutingToolCall | undefined)?.pid;
|
||||
}, [toolCalls]);
|
||||
|
||||
const onExec = useCallback(async (done: Promise<void>) => {
|
||||
setIsResponding(true);
|
||||
await done;
|
||||
setIsResponding(false);
|
||||
}, []);
|
||||
|
||||
const {
|
||||
handleShellCommand,
|
||||
activeShellPtyId,
|
||||
lastShellOutputTime,
|
||||
backgroundShellCount,
|
||||
isBackgroundShellVisible,
|
||||
toggleBackgroundShell,
|
||||
backgroundCurrentShell,
|
||||
registerBackgroundShell,
|
||||
dismissBackgroundShell,
|
||||
backgroundShells,
|
||||
} = useShellCommandProcessor(
|
||||
addItem,
|
||||
setPendingHistoryItem,
|
||||
onExec,
|
||||
onDebugMessage,
|
||||
config,
|
||||
geminiClient,
|
||||
setShellInputFocused,
|
||||
terminalWidth,
|
||||
terminalHeight,
|
||||
activeToolPtyId,
|
||||
);
|
||||
|
||||
const streamingState = useMemo(
|
||||
() => calculateStreamingState(isResponding, toolCalls),
|
||||
[isResponding, toolCalls],
|
||||
@@ -347,6 +390,13 @@ export const useGeminiStream = (
|
||||
const historyItem = mapTrackedToolCallsToDisplay(tc, {
|
||||
borderTop: isFirst,
|
||||
borderBottom: isLastInBatch,
|
||||
...getToolGroupBorderAppearance(
|
||||
{ type: 'tool_group', tools: toolCalls },
|
||||
activeShellPtyId,
|
||||
!!isShellFocused,
|
||||
[],
|
||||
backgroundShells,
|
||||
),
|
||||
});
|
||||
addItem(historyItem);
|
||||
isFirst = false;
|
||||
@@ -362,6 +412,9 @@ export const useGeminiStream = (
|
||||
setPushedToolCallIds,
|
||||
setIsFirstToolInGroup,
|
||||
addItem,
|
||||
activeShellPtyId,
|
||||
isShellFocused,
|
||||
backgroundShells,
|
||||
]);
|
||||
|
||||
const pendingToolGroupItems = useMemo((): HistoryItemWithoutId[] => {
|
||||
@@ -371,11 +424,20 @@ export const useGeminiStream = (
|
||||
|
||||
const items: HistoryItemWithoutId[] = [];
|
||||
|
||||
const appearance = getToolGroupBorderAppearance(
|
||||
{ type: 'tool_group', tools: toolCalls },
|
||||
activeShellPtyId,
|
||||
!!isShellFocused,
|
||||
[],
|
||||
backgroundShells,
|
||||
);
|
||||
|
||||
if (remainingTools.length > 0) {
|
||||
items.push(
|
||||
mapTrackedToolCallsToDisplay(remainingTools, {
|
||||
borderTop: pushedToolCallIds.size === 0,
|
||||
borderBottom: false, // Stay open to connect with the slice below
|
||||
...appearance,
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -423,20 +485,18 @@ export const useGeminiStream = (
|
||||
tools: [] as IndividualToolCallDisplay[],
|
||||
borderTop: false,
|
||||
borderBottom: true,
|
||||
...appearance,
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}, [toolCalls, pushedToolCallIds]);
|
||||
|
||||
const activeToolPtyId = useMemo(() => {
|
||||
const executingShellTool = toolCalls.find(
|
||||
(tc) =>
|
||||
tc.status === 'executing' && tc.request.name === 'run_shell_command',
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
return (executingShellTool as TrackedExecutingToolCall | undefined)?.pid;
|
||||
}, [toolCalls]);
|
||||
}, [
|
||||
toolCalls,
|
||||
pushedToolCallIds,
|
||||
activeShellPtyId,
|
||||
isShellFocused,
|
||||
backgroundShells,
|
||||
]);
|
||||
|
||||
const lastQueryRef = useRef<PartListUnion | null>(null);
|
||||
const lastPromptIdRef = useRef<string | null>(null);
|
||||
@@ -448,36 +508,6 @@ export const useGeminiStream = (
|
||||
onComplete: (result: { userSelection: 'disable' | 'keep' }) => void;
|
||||
} | null>(null);
|
||||
|
||||
const onExec = useCallback(async (done: Promise<void>) => {
|
||||
setIsResponding(true);
|
||||
await done;
|
||||
setIsResponding(false);
|
||||
}, []);
|
||||
|
||||
const {
|
||||
handleShellCommand,
|
||||
activeShellPtyId,
|
||||
lastShellOutputTime,
|
||||
backgroundShellCount,
|
||||
isBackgroundShellVisible,
|
||||
toggleBackgroundShell,
|
||||
backgroundCurrentShell,
|
||||
registerBackgroundShell,
|
||||
dismissBackgroundShell,
|
||||
backgroundShells,
|
||||
} = useShellCommandProcessor(
|
||||
addItem,
|
||||
setPendingHistoryItem,
|
||||
onExec,
|
||||
onDebugMessage,
|
||||
config,
|
||||
geminiClient,
|
||||
setShellInputFocused,
|
||||
terminalWidth,
|
||||
terminalHeight,
|
||||
activeToolPtyId,
|
||||
);
|
||||
|
||||
const activePtyId = activeShellPtyId || activeToolPtyId;
|
||||
|
||||
const prevActiveShellPtyIdRef = useRef<number | null>(null);
|
||||
|
||||
Reference in New Issue
Block a user