feat(ui): composer UX refresh

- Implement refreshed multi-row status area with flattened visibility logic.
- Stabilize Composer row heights to prevent layout jumping during debounce and typing.
- Refactor renderStatusRow to use a direct flow for Mini(ized) mode, Shell Waiting, and status states.
- Relocate ToastDisplay to top Composer row
- Migrate Composer tests to use real ToastDisplay component and content-based assertions.
- Regenerate all CLI UI snapshots to match the final architecture.
This commit is contained in:
Jarrod Whelan
2026-03-04 16:26:38 -08:00
committed by Jarrod Whelan
parent cd7dced951
commit c210b57ab9
52 changed files with 1326 additions and 1082 deletions

View File

@@ -22,16 +22,18 @@ export interface UseLoadingIndicatorProps {
retryStatus: RetryAttemptPayload | null;
loadingPhrasesMode?: LoadingPhrasesMode;
customWittyPhrases?: string[];
errorVerbosity: 'low' | 'full';
errorVerbosity?: 'low' | 'full';
maxLength?: number;
}
export const useLoadingIndicator = ({
streamingState,
shouldShowFocusHint,
retryStatus,
loadingPhrasesMode,
loadingPhrasesMode = 'tips',
customWittyPhrases,
errorVerbosity,
errorVerbosity = 'full',
maxLength,
}: UseLoadingIndicatorProps) => {
const [timerResetKey, setTimerResetKey] = useState(0);
const isTimerActive = streamingState === StreamingState.Responding;
@@ -40,12 +42,20 @@ export const useLoadingIndicator = ({
const isPhraseCyclingActive = streamingState === StreamingState.Responding;
const isWaiting = streamingState === StreamingState.WaitingForConfirmation;
const currentLoadingPhrase = usePhraseCycler(
const showTips =
loadingPhrasesMode === 'tips' || loadingPhrasesMode === 'all';
const showWit =
loadingPhrasesMode === 'witty' || loadingPhrasesMode === 'all';
const { currentTip, currentWittyPhrase } = usePhraseCycler(
isPhraseCyclingActive,
isWaiting,
shouldShowFocusHint,
loadingPhrasesMode,
showTips,
showWit,
customWittyPhrases,
maxLength,
);
const [retainedElapsedTime, setRetainedElapsedTime] = useState(0);
@@ -86,6 +96,8 @@ export const useLoadingIndicator = ({
streamingState === StreamingState.WaitingForConfirmation
? retainedElapsedTime
: elapsedTimeFromTimer,
currentLoadingPhrase: retryPhrase || currentLoadingPhrase,
currentLoadingPhrase: retryPhrase || currentTip || currentWittyPhrase,
currentTip,
currentWittyPhrase,
};
};