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 │