feat(cli): improve CTRL+O experience for both standard and alternate screen buffer (ASB) modes (#19010)

Co-authored-by: jacob314 <jacob314@gmail.com>
This commit is contained in:
Jarrod Whelan
2026-02-20 16:26:11 -08:00
committed by GitHub
parent 547f5d45f5
commit 727f9b67b1
39 changed files with 1622 additions and 428 deletions
+60 -22
View File
@@ -47,32 +47,61 @@ export const MainContent = () => {
pendingHistoryItems,
mainAreaWidth,
staticAreaMaxItemHeight,
availableTerminalHeight,
cleanUiDetailsVisible,
} = uiState;
const showHeaderDetails = cleanUiDetailsVisible;
const lastUserPromptIndex = useMemo(() => {
for (let i = uiState.history.length - 1; i >= 0; i--) {
const type = uiState.history[i].type;
if (type === 'user' || type === 'user_shell') {
return i;
}
}
return -1;
}, [uiState.history]);
const historyItems = useMemo(
() =>
uiState.history.map((h) => (
<MemoizedHistoryItemDisplay
terminalWidth={mainAreaWidth}
availableTerminalHeight={staticAreaMaxItemHeight}
availableTerminalHeightGemini={MAX_GEMINI_MESSAGE_LINES}
key={h.id}
item={h}
isPending={false}
commands={uiState.slashCommands}
/>
)),
uiState.history.map((h, index) => {
const isExpandable = index > lastUserPromptIndex;
return (
<MemoizedHistoryItemDisplay
terminalWidth={mainAreaWidth}
availableTerminalHeight={
uiState.constrainHeight || !isExpandable
? staticAreaMaxItemHeight
: undefined
}
availableTerminalHeightGemini={MAX_GEMINI_MESSAGE_LINES}
key={h.id}
item={h}
isPending={false}
commands={uiState.slashCommands}
isExpandable={isExpandable}
/>
);
}),
[
uiState.history,
mainAreaWidth,
staticAreaMaxItemHeight,
uiState.slashCommands,
uiState.constrainHeight,
lastUserPromptIndex,
],
);
const staticHistoryItems = useMemo(
() => historyItems.slice(0, lastUserPromptIndex + 1),
[historyItems, lastUserPromptIndex],
);
const lastResponseHistoryItems = useMemo(
() => historyItems.slice(lastUserPromptIndex + 1),
[historyItems, lastUserPromptIndex],
);
const pendingItems = useMemo(
() => (
<Box flexDirection="column">
@@ -80,14 +109,12 @@ export const MainContent = () => {
<HistoryItemDisplay
key={i}
availableTerminalHeight={
(uiState.constrainHeight && !isAlternateBuffer) ||
isAlternateBuffer
? availableTerminalHeight
: undefined
uiState.constrainHeight ? staticAreaMaxItemHeight : undefined
}
terminalWidth={mainAreaWidth}
item={{ ...item, id: 0 }}
isPending={true}
isExpandable={true}
/>
))}
{showConfirmationQueue && confirmingTool && (
@@ -98,8 +125,7 @@ export const MainContent = () => {
[
pendingHistoryItems,
uiState.constrainHeight,
isAlternateBuffer,
availableTerminalHeight,
staticAreaMaxItemHeight,
mainAreaWidth,
showConfirmationQueue,
confirmingTool,
@@ -109,10 +135,14 @@ export const MainContent = () => {
const virtualizedData = useMemo(
() => [
{ type: 'header' as const },
...uiState.history.map((item) => ({ type: 'history' as const, item })),
...uiState.history.map((item, index) => ({
type: 'history' as const,
item,
isExpandable: index > lastUserPromptIndex,
})),
{ type: 'pending' as const },
],
[uiState.history],
[uiState.history, lastUserPromptIndex],
);
const renderItem = useCallback(
@@ -129,12 +159,17 @@ export const MainContent = () => {
return (
<MemoizedHistoryItemDisplay
terminalWidth={mainAreaWidth}
availableTerminalHeight={undefined}
availableTerminalHeight={
uiState.constrainHeight || !item.isExpandable
? staticAreaMaxItemHeight
: undefined
}
availableTerminalHeightGemini={MAX_GEMINI_MESSAGE_LINES}
key={item.item.id}
item={item.item}
isPending={false}
commands={uiState.slashCommands}
isExpandable={item.isExpandable}
/>
);
} else {
@@ -147,6 +182,8 @@ export const MainContent = () => {
mainAreaWidth,
uiState.slashCommands,
pendingItems,
uiState.constrainHeight,
staticAreaMaxItemHeight,
],
);
@@ -176,7 +213,8 @@ export const MainContent = () => {
key={uiState.historyRemountKey}
items={[
<AppHeader key="app-header" version={version} />,
...historyItems,
...staticHistoryItems,
...lastResponseHistoryItems,
]}
>
{(item) => item}