fix(cli): prevent Thinking... Thinking... duplication in footer

This commit is contained in:
Keith Guerin
2026-02-23 22:43:56 -08:00
parent 37fa797c9d
commit 4443e1028a
4 changed files with 31 additions and 6 deletions

View File

@@ -385,7 +385,7 @@ describe('Composer', () => {
const { lastFrame } = await renderComposer(uiState, settings);
const output = lastFrame();
expect(output).toContain('LoadingIndicator: Thinking about code');
expect(output).toContain('LoadingIndicator: Thinking...');
});
it('hides shortcuts hint while loading', async () => {

View File

@@ -238,7 +238,9 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
? undefined
: uiState.currentLoadingPhrase
}
thoughtLabel={undefined}
thoughtLabel={
inlineThinkingMode === 'full' ? 'Thinking...' : undefined
}
elapsedTime={uiState.elapsedTime}
/>
)}
@@ -280,7 +282,7 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
: uiState.currentLoadingPhrase
}
thoughtLabel={
inlineThinkingMode === 'full' ? 'Thinking ...' : undefined
inlineThinkingMode === 'full' ? 'Thinking...' : undefined
}
elapsedTime={uiState.elapsedTime}
/>
@@ -388,7 +390,7 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
marginTop={
(showApprovalIndicator ||
uiState.shellModeActive) &&
isNarrow
!isNarrow
? 1
: 0
}

View File

@@ -258,13 +258,32 @@ describe('<LoadingIndicator />', () => {
const output = lastFrame();
expect(output).toBeDefined();
if (output) {
expect(output).toContain('Thinking... ');
// Should NOT contain "Thinking... " prefix because the subject already starts with "Thinking"
expect(output).not.toContain('Thinking... Thinking');
expect(output).toContain('Thinking about something...');
expect(output).not.toContain('and other stuff.');
}
unmount();
});
it('should prepend "Thinking... " if the subject does not start with "Thinking"', async () => {
const props = {
thought: {
subject: 'Planning the response...',
description: 'details',
},
elapsedTime: 5,
};
const { lastFrame, unmount, waitUntilReady } = renderWithContext(
<LoadingIndicator {...props} />,
StreamingState.Responding,
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('Thinking... Planning the response...');
unmount();
});
it('should prioritize thought.subject over currentLoadingPhrase', async () => {
const props = {
thought: {

View File

@@ -58,7 +58,11 @@ export const LoadingIndicator: React.FC<LoadingIndicatorProps> = ({
const hasThoughtIndicator =
currentLoadingPhrase !== INTERACTIVE_SHELL_WAITING_PHRASE &&
Boolean(thought?.subject?.trim());
const thinkingIndicator = hasThoughtIndicator ? 'Thinking... ' : '';
// Avoid "Thinking... Thinking..." duplication if primaryText already starts with "Thinking"
const thinkingIndicator =
hasThoughtIndicator && !primaryText?.startsWith('Thinking')
? 'Thinking... '
: '';
const cancelAndTimerContent =
showCancelAndTimer &&