From 86017b9f15d6c8e001ed9abbddb42fc2f47e781c Mon Sep 17 00:00:00 2001 From: Jack Wotherspoon Date: Mon, 16 Feb 2026 18:07:54 -0500 Subject: [PATCH] chore: update --- packages/cli/src/config/footerItems.test.ts | 6 +- packages/cli/src/config/footerItems.ts | 20 ++--- packages/cli/src/ui/components/Footer.tsx | 2 +- .../ui/components/FooterConfigDialog.test.tsx | 18 ---- .../src/ui/components/FooterConfigDialog.tsx | 90 +++++++------------ .../FooterConfigDialog.test.tsx.snap | 26 +++--- 6 files changed, 56 insertions(+), 106 deletions(-) diff --git a/packages/cli/src/config/footerItems.test.ts b/packages/cli/src/config/footerItems.test.ts index c43ea7be0e..0f784c5517 100644 --- a/packages/cli/src/config/footerItems.test.ts +++ b/packages/cli/src/config/footerItems.test.ts @@ -19,7 +19,7 @@ describe('deriveItemsFromLegacySettings', () => { 'git-branch', 'sandbox-status', 'model-name', - 'quota', + 'usage-limit', ]); }); @@ -39,14 +39,14 @@ describe('deriveItemsFromLegacySettings', () => { expect(items).not.toContain('sandbox-status'); }); - it('removes model-name, context-remaining, and quota when hideModelInfo is true', () => { + it('removes model-name, context-remaining, and usage-limit when hideModelInfo is true', () => { const settings = createMockSettings({ ui: { footer: { hideModelInfo: true, hideContextPercentage: true } }, }).merged; const items = deriveItemsFromLegacySettings(settings); expect(items).not.toContain('model-name'); expect(items).not.toContain('context-remaining'); - expect(items).not.toContain('quota'); + expect(items).not.toContain('usage-limit'); }); it('includes context-remaining when hideContextPercentage is false', () => { diff --git a/packages/cli/src/config/footerItems.ts b/packages/cli/src/config/footerItems.ts index a9132dc30f..49c851f5ae 100644 --- a/packages/cli/src/config/footerItems.ts +++ b/packages/cli/src/config/footerItems.ts @@ -10,12 +10,12 @@ export const ALL_ITEMS = [ { id: 'cwd', header: 'Path', - description: 'Current directory path', + description: 'Current working directory', }, { id: 'git-branch', header: 'Branch', - description: 'Current git branch name', + description: 'Current git branch name (not shown when unavailable)', }, { id: 'sandbox-status', @@ -33,14 +33,14 @@ export const ALL_ITEMS = [ description: 'Percentage of context window remaining', }, { - id: 'quota', + id: 'usage-limit', header: '/stats', - description: 'Remaining usage on daily limit', + description: 'Remaining usage on daily limit (not shown when unavailable)', }, { id: 'memory-usage', header: 'Memory', - description: 'Node.js heap memory usage', + description: 'Memory used by the application', }, { id: 'session-id', @@ -50,12 +50,12 @@ export const ALL_ITEMS = [ { id: 'code-changes', header: 'Diff', - description: 'Lines added/removed in the session', + description: 'Lines added/removed in the session (not shown when zero)', }, { id: 'token-count', header: 'Tokens', - description: 'Total tokens used in the session', + description: 'Total tokens used in the session (not shown when zero)', }, ] as const; @@ -67,7 +67,7 @@ export const DEFAULT_ORDER = [ 'sandbox-status', 'model-name', 'context-remaining', - 'quota', + 'usage-limit', 'memory-usage', 'session-id', 'code-changes', @@ -82,7 +82,7 @@ export function deriveItemsFromLegacySettings( 'git-branch', 'sandbox-status', 'model-name', - 'quota', + 'usage-limit', ]; const items = [...defaults]; @@ -96,7 +96,7 @@ export function deriveItemsFromLegacySettings( if (settings.ui.footer.hideModelInfo) { remove(items, 'model-name'); remove(items, 'context-remaining'); - remove(items, 'quota'); + remove(items, 'usage-limit'); } if ( !settings.ui.footer.hideContextPercentage && diff --git a/packages/cli/src/ui/components/Footer.tsx b/packages/cli/src/ui/components/Footer.tsx index c51c2e279a..d3b3bb5c31 100644 --- a/packages/cli/src/ui/components/Footer.tsx +++ b/packages/cli/src/ui/components/Footer.tsx @@ -312,7 +312,7 @@ export const Footer: React.FC = () => { ); break; } - case 'quota': { + case 'usage-limit': { if (quotaStats?.remaining !== undefined && quotaStats.limit) { const percentage = (quotaStats.remaining / quotaStats.limit) * 100; let color = itemColor; diff --git a/packages/cli/src/ui/components/FooterConfigDialog.test.tsx b/packages/cli/src/ui/components/FooterConfigDialog.test.tsx index ec04ae272e..c97b62d4b4 100644 --- a/packages/cli/src/ui/components/FooterConfigDialog.test.tsx +++ b/packages/cli/src/ui/components/FooterConfigDialog.test.tsx @@ -56,24 +56,6 @@ describe('', () => { }); }); - it('filters items when typing in search', async () => { - const settings = createMockSettings(); - const { lastFrame, stdin } = renderWithProviders( - , - { settings }, - ); - - act(() => { - stdin.write('session'); - }); - - await waitFor(() => { - const output = lastFrame(); - expect(output).toContain('session-id'); - expect(output).not.toContain('model-name'); - }); - }); - it('reorders items with arrow keys', async () => { const settings = createMockSettings(); const { lastFrame, stdin } = renderWithProviders( diff --git a/packages/cli/src/ui/components/FooterConfigDialog.tsx b/packages/cli/src/ui/components/FooterConfigDialog.tsx index fed4a1fc3f..3763f98e3a 100644 --- a/packages/cli/src/ui/components/FooterConfigDialog.tsx +++ b/packages/cli/src/ui/components/FooterConfigDialog.tsx @@ -11,8 +11,6 @@ import { theme } from '../semantic-colors.js'; import { useSettingsStore } from '../contexts/SettingsContext.js'; import { useKeypress, type Key } from '../hooks/useKeypress.js'; import { keyMatchers, Command } from '../keyMatchers.js'; -import { TextInput } from './shared/TextInput.js'; -import { useFuzzyList } from '../hooks/useFuzzyList.js'; import { FooterRow, type FooterRowItem } from './Footer.js'; import { ALL_ITEMS, resolveFooterState } from '../../config/footerItems.js'; import { SettingScope } from '../../config/settings.js'; @@ -29,19 +27,17 @@ interface FooterConfigState { } type FooterConfigAction = - | { type: 'MOVE_UP'; filteredCount: number; maxToShow: number } - | { type: 'MOVE_DOWN'; filteredCount: number; maxToShow: number } + | { type: 'MOVE_UP'; itemCount: number; maxToShow: number } + | { type: 'MOVE_DOWN'; itemCount: number; maxToShow: number } | { type: 'MOVE_LEFT'; - searchQuery: string; - filteredItems: Array<{ key: string }>; + items: Array<{ key: string }>; } | { type: 'MOVE_RIGHT'; - searchQuery: string; - filteredItems: Array<{ key: string }>; + items: Array<{ key: string }>; } - | { type: 'TOGGLE_ITEM'; filteredItems: Array<{ key: string }> } + | { type: 'TOGGLE_ITEM'; items: Array<{ key: string }> } | { type: 'SET_STATE'; payload: Partial } | { type: 'RESET_INDEX' }; @@ -51,15 +47,15 @@ function footerConfigReducer( ): FooterConfigState { switch (action.type) { case 'MOVE_UP': { - const { filteredCount, maxToShow } = action; - const totalSlots = filteredCount + 2; // +1 for showLabels, +1 for reset + const { itemCount, maxToShow } = action; + const totalSlots = itemCount + 2; // +1 for showLabels, +1 for reset const newIndex = state.activeIndex > 0 ? state.activeIndex - 1 : totalSlots - 1; let newOffset = state.scrollOffset; - if (newIndex < filteredCount) { - if (newIndex === filteredCount - 1) { - newOffset = Math.max(0, filteredCount - maxToShow); + if (newIndex < itemCount) { + if (newIndex === itemCount - 1) { + newOffset = Math.max(0, itemCount - maxToShow); } else if (newIndex < state.scrollOffset) { newOffset = newIndex; } @@ -67,8 +63,8 @@ function footerConfigReducer( return { ...state, activeIndex: newIndex, scrollOffset: newOffset }; } case 'MOVE_DOWN': { - const { filteredCount, maxToShow } = action; - const totalSlots = filteredCount + 2; + const { itemCount, maxToShow } = action; + const totalSlots = itemCount + 2; const newIndex = state.activeIndex < totalSlots - 1 ? state.activeIndex + 1 : 0; let newOffset = state.scrollOffset; @@ -76,7 +72,7 @@ function footerConfigReducer( if (newIndex === 0) { newOffset = 0; } else if ( - newIndex < filteredCount && + newIndex < itemCount && newIndex >= state.scrollOffset + maxToShow ) { newOffset = newIndex - maxToShow + 1; @@ -85,9 +81,8 @@ function footerConfigReducer( } case 'MOVE_LEFT': case 'MOVE_RIGHT': { - if (action.searchQuery) return state; const direction = action.type === 'MOVE_LEFT' ? -1 : 1; - const currentItem = action.filteredItems[state.activeIndex]; + const currentItem = action.items[state.activeIndex]; if (!currentItem) return state; const currentId = currentItem.key; @@ -105,10 +100,10 @@ function footerConfigReducer( return { ...state, orderedIds: newOrderedIds, activeIndex: newIndex }; } case 'TOGGLE_ITEM': { - const isSystemFocused = state.activeIndex >= action.filteredItems.length; + const isSystemFocused = state.activeIndex >= action.items.length; if (isSystemFocused) return state; - const item = action.filteredItems[state.activeIndex]; + const item = action.items[state.activeIndex]; if (!item) return state; const nextSelected = new Set(state.selectedIds); @@ -142,7 +137,7 @@ export const FooterConfigDialog: React.FC = ({ const { orderedIds, selectedIds, activeIndex, scrollOffset } = state; - // Prepare items for fuzzy list + // Prepare items const listItems = useMemo( () => orderedIds @@ -159,10 +154,7 @@ export const FooterConfigDialog: React.FC = ({ [orderedIds], ); - const { filteredItems, searchBuffer, searchQuery, maxLabelWidth } = - useFuzzyList({ - items: listItems, - }); + const maxLabelWidth = useMemo(() => listItems.reduce((max, item) => Math.max(max, item.label.length), 0), [listItems]); // Save settings when orderedIds or selectedIds change useEffect(() => { @@ -174,13 +166,8 @@ export const FooterConfigDialog: React.FC = ({ } }, [orderedIds, selectedIds, setSetting, settings.merged.ui?.footer?.items]); - // Reset index when search changes - useEffect(() => { - dispatch({ type: 'RESET_INDEX' }); - }, [searchQuery]); - - const isResetFocused = activeIndex === filteredItems.length + 1; - const isShowLabelsFocused = activeIndex === filteredItems.length; + const isResetFocused = activeIndex === listItems.length + 1; + const isShowLabelsFocused = activeIndex === listItems.length; const handleResetToDefaults = useCallback(() => { setSetting(SettingScope.User, 'ui.footer.items', undefined); @@ -209,7 +196,7 @@ export const FooterConfigDialog: React.FC = ({ if (keyMatchers[Command.DIALOG_NAVIGATION_UP](key)) { dispatch({ type: 'MOVE_UP', - filteredCount: filteredItems.length, + itemCount: listItems.length, maxToShow: maxItemsToShow, }); return true; @@ -218,19 +205,19 @@ export const FooterConfigDialog: React.FC = ({ if (keyMatchers[Command.DIALOG_NAVIGATION_DOWN](key)) { dispatch({ type: 'MOVE_DOWN', - filteredCount: filteredItems.length, + itemCount: listItems.length, maxToShow: maxItemsToShow, }); return true; } if (keyMatchers[Command.MOVE_LEFT](key)) { - dispatch({ type: 'MOVE_LEFT', searchQuery, filteredItems }); + dispatch({ type: 'MOVE_LEFT', items: listItems }); return true; } if (keyMatchers[Command.MOVE_RIGHT](key)) { - dispatch({ type: 'MOVE_RIGHT', searchQuery, filteredItems }); + dispatch({ type: 'MOVE_RIGHT', items: listItems }); return true; } @@ -240,7 +227,7 @@ export const FooterConfigDialog: React.FC = ({ } else if (isShowLabelsFocused) { handleToggleLabels(); } else { - dispatch({ type: 'TOGGLE_ITEM', filteredItems }); + dispatch({ type: 'TOGGLE_ITEM', items: listItems }); } return true; } @@ -250,12 +237,12 @@ export const FooterConfigDialog: React.FC = ({ { isActive: true, priority: true }, ); - const visibleItems = filteredItems.slice( + const visibleItems = listItems.slice( scrollOffset, scrollOffset + maxItemsToShow, ); - const activeId = filteredItems[activeIndex]?.key; + const activeId = listItems[activeIndex]?.key; const showLabels = settings.merged.ui.footer.showLabels !== false; // Preview logic @@ -290,7 +277,9 @@ export const FooterConfigDialog: React.FC = ({ 'context-remaining': ( 85% left ), - quota: daily 97%, + 'usage-limit': ( + daily 97% + ), 'memory-usage': ( 260 MB ), @@ -331,23 +320,11 @@ export const FooterConfigDialog: React.FC = ({ paddingY={1} width="100%" > - Configure Footer + Configure Footer{'\n'} Select which items to display in the footer. - - Type to search - - {searchBuffer && } - - - {visibleItems.length === 0 ? ( No items found. @@ -400,11 +377,6 @@ export const FooterConfigDialog: React.FC = ({ ↑/↓ navigate · ←/→ reorder · enter select · esc close - {searchQuery && ( - - Reordering is disabled when searching. - - )} > renders correctly with default settings 1`] = "╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ │ │ Configure Footer │ +│ │ │ Select which items to display in the footer. │ │ │ -│ Type to search │ -│ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ -│ │ │ │ -│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │ -│ │ -│ > [✓] cwd Current directory path │ -│ [✓] git-branch Current git branch name │ -│ [✓] sandbox-status Sandbox type and trust indicator │ -│ [✓] model-name Current model identifier │ -│ [✓] quota Remaining usage on daily limit │ -│ [ ] context-remaining Percentage of context window remaining │ -│ [ ] memory-usage Node.js heap memory usage │ -│ [ ] session-id Unique identifier for the current session │ -│ [ ] code-changes Lines added/removed in the session │ -│ [ ] token-count Total tokens used in the session │ +│ > [✓] cwd Current working directory │ +│ [✓] git-branch Current git branch name (not shown when unavailable) │ +│ [✓] sandbox-status Sandbox type and trust indicator │ +│ [✓] model-name Current model identifier │ +│ [✓] usage-limit Remaining usage on daily limit (not shown when unavailable) │ +│ [ ] context-remaining Percentage of context window remaining │ +│ [ ] memory-usage Memory used by the application │ +│ [ ] session-id Unique identifier for the current session │ +│ [ ] code-changes Lines added/removed in the session (not shown when zero) │ +│ [ ] token-count Total tokens used in the session (not shown when zero) │ │ │ │ [✓] Show footer labels │ │ Reset to default footer │