feat(cli): implement compact tool output (#20974)

This commit is contained in:
Jarrod Whelan
2026-03-30 16:43:29 -07:00
committed by GitHub
parent 3e95b8ec59
commit 1df5c98b33
45 changed files with 2670 additions and 386 deletions

View File

@@ -168,6 +168,7 @@ import { useSuspend } from './hooks/useSuspend.js';
import { useRunEventNotifications } from './hooks/useRunEventNotifications.js';
import { isNotificationsEnabled } from '../utils/terminalNotifications.js';
import {
getLastTurnToolCallIds,
isToolExecuting,
isToolAwaitingConfirmation,
getAllToolCalls,
@@ -238,6 +239,39 @@ export const AppContainer = (props: AppContainerProps) => {
const [adminSettingsChanged, setAdminSettingsChanged] = useState(false);
const [expandedTools, setExpandedTools] = useState<Set<string>>(new Set());
const toggleExpansion = useCallback((callId: string) => {
setExpandedTools((prev) => {
const next = new Set(prev);
if (next.has(callId)) {
next.delete(callId);
} else {
next.add(callId);
}
return next;
});
}, []);
const toggleAllExpansion = useCallback((callIds: string[]) => {
setExpandedTools((prev) => {
const next = new Set(prev);
const anyCollapsed = callIds.some((id) => !next.has(id));
if (anyCollapsed) {
callIds.forEach((id) => next.add(id));
} else {
callIds.forEach((id) => next.delete(id));
}
return next;
});
}, []);
const isExpanded = useCallback(
(callId: string) => expandedTools.has(callId),
[expandedTools],
);
const [shellModeActive, setShellModeActive] = useState(false);
const [modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError] =
useState<boolean>(false);
@@ -1137,11 +1171,6 @@ Logging in with Google... Restarting Gemini CLI to continue.
[pendingSlashCommandHistoryItems, pendingGeminiHistoryItems],
);
const hasPendingToolConfirmation = useMemo(
() => isToolAwaitingConfirmation(pendingHistoryItems),
[pendingHistoryItems],
);
toggleBackgroundTasksRef.current = toggleBackgroundTasks;
isBackgroundTaskVisibleRef.current = isBackgroundTaskVisible;
backgroundTasksRef.current = backgroundTasks;
@@ -1727,13 +1756,25 @@ Logging in with Google... Restarting Gemini CLI to continue.
return true;
}
const toggleLastTurnTools = () => {
triggerExpandHint(true);
const targetToolCallIds = getLastTurnToolCallIds(
historyManager.history,
pendingHistoryItems,
);
if (targetToolCallIds.length > 0) {
toggleAllExpansion(targetToolCallIds);
}
};
let enteringConstrainHeightMode = false;
if (!constrainHeight) {
enteringConstrainHeightMode = true;
setConstrainHeight(true);
if (keyMatchers[Command.SHOW_MORE_LINES](key)) {
// If the user manually collapses the view, show the hint and reset the x-second timer.
triggerExpandHint(true);
toggleLastTurnTools();
}
if (!isAlternateBuffer) {
refreshStatic();
@@ -1781,11 +1822,8 @@ Logging in with Google... Restarting Gemini CLI to continue.
!enteringConstrainHeightMode
) {
setConstrainHeight(false);
// If the user manually expands the view, show the hint and reset the x-second timer.
triggerExpandHint(true);
if (!isAlternateBuffer) {
refreshStatic();
}
toggleLastTurnTools();
refreshStatic();
return true;
} else if (
(keyMatchers[Command.FOCUS_SHELL_INPUT](key) ||
@@ -1890,6 +1928,9 @@ Logging in with Google... Restarting Gemini CLI to continue.
triggerExpandHint,
keyMatchers,
isHelpDismissKey,
historyManager.history,
pendingHistoryItems,
toggleAllExpansion,
],
);
@@ -2033,6 +2074,11 @@ Logging in with Google... Restarting Gemini CLI to continue.
authState === AuthState.AwaitingApiKeyInput ||
!!newAgents;
const hasPendingToolConfirmation = useMemo(
() => isToolAwaitingConfirmation(pendingHistoryItems),
[pendingHistoryItems],
);
const hasConfirmUpdateExtensionRequests =
confirmUpdateExtensionRequests.length > 0;
const hasLoopDetectionConfirmationRequest =
@@ -2639,7 +2685,13 @@ Logging in with Google... Restarting Gemini CLI to continue.
startupWarnings: props.startupWarnings || [],
}}
>
<ToolActionsProvider config={config} toolCalls={allToolCalls}>
<ToolActionsProvider
config={config}
toolCalls={allToolCalls}
isExpanded={isExpanded}
toggleExpansion={toggleExpansion}
toggleAllExpansion={toggleAllExpansion}
>
<ShellFocusContext.Provider value={isFocused}>
<App key={`app-${forceRerenderKey}`} />
</ShellFocusContext.Provider>