From 9172e28315427a08367edd0de431455df12d6199 Mon Sep 17 00:00:00 2001 From: Sehoon Shon Date: Tue, 6 Jan 2026 14:06:15 -0500 Subject: [PATCH] Add description for each settings item in /settings (#15936) --- .../src/ui/components/SettingsDialog.test.tsx | 17 ++ .../cli/src/ui/components/SettingsDialog.tsx | 117 +++++++--- .../SettingsDialog.test.tsx.snap | 216 ++++++++++++------ 3 files changed, 243 insertions(+), 107 deletions(-) diff --git a/packages/cli/src/ui/components/SettingsDialog.test.tsx b/packages/cli/src/ui/components/SettingsDialog.test.tsx index 82750be0ee..2c0c10e502 100644 --- a/packages/cli/src/ui/components/SettingsDialog.test.tsx +++ b/packages/cli/src/ui/components/SettingsDialog.test.tsx @@ -308,6 +308,23 @@ describe('SettingsDialog', () => { }); }); + describe('Setting Descriptions', () => { + it('should render descriptions for settings that have them', () => { + const settings = createMockSettings(); + const onSelect = vi.fn(); + + const { lastFrame } = renderDialog(settings, onSelect); + + const output = lastFrame(); + // 'general.vimMode' has description 'Enable Vim keybindings' in settingsSchema.ts + expect(output).toContain('Vim Mode'); + expect(output).toContain('Enable Vim keybindings'); + // 'general.disableAutoUpdate' has description 'Disable automatic updates' + expect(output).toContain('Disable Auto Update'); + expect(output).toContain('Disable automatic updates'); + }); + }); + describe('Settings Navigation', () => { it.each([ { diff --git a/packages/cli/src/ui/components/SettingsDialog.tsx b/packages/cli/src/ui/components/SettingsDialog.tsx index 1b1235edde..b0c40e2d2c 100644 --- a/packages/cli/src/ui/components/SettingsDialog.tsx +++ b/packages/cli/src/ui/components/SettingsDialog.tsx @@ -37,7 +37,12 @@ import { import { useVimMode } from '../contexts/VimModeContext.js'; import { useKeypress } from '../hooks/useKeypress.js'; import chalk from 'chalk'; -import { cpSlice, cpLen, stripUnsafeCharacters } from '../utils/textUtils.js'; +import { + cpSlice, + cpLen, + stripUnsafeCharacters, + getCachedStringWidth, +} from '../utils/textUtils.js'; import { type SettingsValue, TOGGLE_TYPES, @@ -65,7 +70,7 @@ interface SettingsDialogProps { config?: Config; } -const maxItemsToShow = 8; +const MAX_ITEMS_TO_SHOW = 8; export function SettingsDialog({ settings, @@ -194,6 +199,31 @@ export function SettingsDialog({ setShowRestartPrompt(newRestartRequired.size > 0); }, [selectedScope, settings, globalPendingChanges]); + // Calculate max width for the left column (Label/Description) to keep values aligned or close + const maxLabelOrDescriptionWidth = useMemo(() => { + const allKeys = getDialogSettingKeys(); + let max = 0; + for (const key of allKeys) { + const def = getSettingDefinition(key); + if (!def) continue; + + const scopeMessage = getScopeMessageForSetting( + key, + selectedScope, + settings, + ); + const label = def.label || key; + const labelFull = label + (scopeMessage ? ` ${scopeMessage}` : ''); + const lWidth = getCachedStringWidth(labelFull); + const dWidth = def.description + ? getCachedStringWidth(def.description) + : 0; + + max = Math.max(max, lWidth, dWidth); + } + return max; + }, [selectedScope, settings]); + const generateSettingsItems = () => { const settingKeys = searchQuery ? filteredKeys : getDialogSettingKeys(); @@ -202,6 +232,7 @@ export function SettingsDialog({ return { label: definition?.label || key, + description: definition?.description, value: key, type: definition?.type, toggle: () => { @@ -478,8 +509,8 @@ export function SettingsDialog({ currentAvailableTerminalHeight - totalFixedHeight, ); - // Each setting item takes 2 lines (the setting row + spacing) - let maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 2)); + // Each setting item takes up to 3 lines (label/value row, description row, and spacing) + let maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 3)); // Decide whether to show scope selection based on remaining space let showScopeSelection = true; @@ -492,7 +523,7 @@ export function SettingsDialog({ 1, currentAvailableTerminalHeight - totalWithScope, ); - const maxItemsWithScope = Math.max(1, Math.floor(availableWithScope / 2)); + const maxItemsWithScope = Math.max(1, Math.floor(availableWithScope / 3)); // If hiding scope selection allows us to show significantly more settings, do it if (maxVisibleItems > maxItemsWithScope + 1) { @@ -504,7 +535,7 @@ export function SettingsDialog({ 1, currentAvailableTerminalHeight - totalFixedHeight, ); - maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 2)); + maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 3)); } } else { // For normal height, include scope selection @@ -513,13 +544,13 @@ export function SettingsDialog({ 1, currentAvailableTerminalHeight - totalFixedHeight, ); - maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 2)); + maxVisibleItems = Math.max(1, Math.floor(availableHeightForSettings / 3)); } // Use the calculated maxVisibleItems or fall back to the original maxItemsToShow const effectiveMaxItemsToShow = availableTerminalHeight ? Math.min(maxVisibleItems, items.length) - : maxItemsToShow; + : MAX_ITEMS_TO_SHOW; // Ensure focus stays on settings when scope selection is hidden React.useEffect(() => { @@ -979,7 +1010,7 @@ export function SettingsDialog({ return ( - + - - - {item.label} - {scopeMessage && ( - - {' '} - {scopeMessage} - - )} - - - - - {displayValue} - + + + {item.label} + {scopeMessage && ( + + {' '} + {scopeMessage} + + )} + + + {item.description ?? ''} + + + + + + {displayValue} + + + diff --git a/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap index b6f3079414..90392e72f1 100644 --- a/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap @@ -10,21 +10,29 @@ exports[`SettingsDialog > Initial Rendering > should render settings list with v │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ +│ ● Preview Features (e.g., models) false │ +│ Enable preview features (e.g., preview models). │ │ │ -│ Vim Mode false │ +│ Vim Mode false │ +│ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ +│ Disable Auto Update false │ +│ Disable automatic updates │ │ │ -│ Enable Prompt Completion false │ +│ Enable Prompt Completion false │ +│ Enable AI-powered prompt completion suggestions while typing. │ │ │ -│ Debug Keystroke Logging false │ +│ Debug Keystroke Logging false │ +│ Enable debug logging of keystrokes to the console. │ │ │ -│ Enable Session Cleanup false │ +│ Enable Session Cleanup false │ +│ Enable automatic session cleanup │ │ │ -│ Output Format Text │ +│ Output Format Text │ +│ The format of the CLI output. │ │ │ -│ Hide Window Title false │ +│ Hide Window Title false │ +│ Hide the window title bar │ │ │ │ ▼ │ │ │ @@ -48,21 +56,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ +│ ● Preview Features (e.g., models) false │ +│ Enable preview features (e.g., preview models). │ │ │ -│ Vim Mode true* │ +│ Vim Mode true* │ +│ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ +│ Disable Auto Update false │ +│ Disable automatic updates │ │ │ -│ Enable Prompt Completion false │ +│ Enable Prompt Completion false │ +│ Enable AI-powered prompt completion suggestions while typing. │ │ │ -│ Debug Keystroke Logging false │ +│ Debug Keystroke Logging false │ +│ Enable debug logging of keystrokes to the console. │ │ │ -│ Enable Session Cleanup false │ +│ Enable Session Cleanup false │ +│ Enable automatic session cleanup │ │ │ -│ Output Format Text │ +│ Output Format Text │ +│ The format of the CLI output. │ │ │ -│ Hide Window Title false │ +│ Hide Window Title false │ +│ Hide the window title bar │ │ │ │ ▼ │ │ │ @@ -86,21 +102,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings d │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ +│ ● Preview Features (e.g., models) false │ +│ Enable preview features (e.g., preview models). │ │ │ -│ Vim Mode false* │ +│ Vim Mode false* │ +│ Enable Vim keybindings │ │ │ -│ Disable Auto Update false* │ +│ Disable Auto Update false* │ +│ Disable automatic updates │ │ │ -│ Enable Prompt Completion false* │ +│ Enable Prompt Completion false* │ +│ Enable AI-powered prompt completion suggestions while typing. │ │ │ -│ Debug Keystroke Logging false* │ +│ Debug Keystroke Logging false* │ +│ Enable debug logging of keystrokes to the console. │ │ │ -│ Enable Session Cleanup false │ +│ Enable Session Cleanup false │ +│ Enable automatic session cleanup │ │ │ -│ Output Format Text │ +│ Output Format Text │ +│ The format of the CLI output. │ │ │ -│ Hide Window Title false* │ +│ Hide Window Title false* │ +│ Hide the window title bar │ │ │ │ ▼ │ │ │ @@ -124,21 +148,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'default state' correct │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ +│ ● Preview Features (e.g., models) false │ +│ Enable preview features (e.g., preview models). │ │ │ -│ Vim Mode false │ +│ Vim Mode false │ +│ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ +│ Disable Auto Update false │ +│ Disable automatic updates │ │ │ -│ Enable Prompt Completion false │ +│ Enable Prompt Completion false │ +│ Enable AI-powered prompt completion suggestions while typing. │ │ │ -│ Debug Keystroke Logging false │ +│ Debug Keystroke Logging false │ +│ Enable debug logging of keystrokes to the console. │ │ │ -│ Enable Session Cleanup false │ +│ Enable Session Cleanup false │ +│ Enable automatic session cleanup │ │ │ -│ Output Format Text │ +│ Output Format Text │ +│ The format of the CLI output. │ │ │ -│ Hide Window Title false │ +│ Hide Window Title false │ +│ Hide the window title bar │ │ │ │ ▼ │ │ │ @@ -162,21 +194,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'file filtering setting │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ +│ ● Preview Features (e.g., models) false │ +│ Enable preview features (e.g., preview models). │ │ │ -│ Vim Mode false │ +│ Vim Mode false │ +│ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ +│ Disable Auto Update false │ +│ Disable automatic updates │ │ │ -│ Enable Prompt Completion false │ +│ Enable Prompt Completion false │ +│ Enable AI-powered prompt completion suggestions while typing. │ │ │ -│ Debug Keystroke Logging false │ +│ Debug Keystroke Logging false │ +│ Enable debug logging of keystrokes to the console. │ │ │ -│ Enable Session Cleanup false │ +│ Enable Session Cleanup false │ +│ Enable automatic session cleanup │ │ │ -│ Output Format Text │ +│ Output Format Text │ +│ The format of the CLI output. │ │ │ -│ Hide Window Title false │ +│ Hide Window Title false │ +│ Hide the window title bar │ │ │ │ ▼ │ │ │ @@ -200,21 +240,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ Preview Features (e.g., models) false │ +│ Preview Features (e.g., models) false │ +│ Enable preview features (e.g., preview models). │ │ │ -│ Vim Mode false │ +│ Vim Mode false │ +│ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ +│ Disable Auto Update false │ +│ Disable automatic updates │ │ │ -│ Enable Prompt Completion false │ +│ Enable Prompt Completion false │ +│ Enable AI-powered prompt completion suggestions while typing. │ │ │ -│ Debug Keystroke Logging false │ +│ Debug Keystroke Logging false │ +│ Enable debug logging of keystrokes to the console. │ │ │ -│ Enable Session Cleanup false │ +│ Enable Session Cleanup false │ +│ Enable automatic session cleanup │ │ │ -│ Output Format Text │ +│ Output Format Text │ +│ The format of the CLI output. │ │ │ -│ Hide Window Title false │ +│ Hide Window Title false │ +│ Hide the window title bar │ │ │ │ ▼ │ │ │ @@ -238,21 +286,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and numb │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ +│ ● Preview Features (e.g., models) false │ +│ Enable preview features (e.g., preview models). │ │ │ -│ Vim Mode false* │ +│ Vim Mode false* │ +│ Enable Vim keybindings │ │ │ -│ Disable Auto Update true* │ +│ Disable Auto Update true* │ +│ Disable automatic updates │ │ │ -│ Enable Prompt Completion false │ +│ Enable Prompt Completion false │ +│ Enable AI-powered prompt completion suggestions while typing. │ │ │ -│ Debug Keystroke Logging false │ +│ Debug Keystroke Logging false │ +│ Enable debug logging of keystrokes to the console. │ │ │ -│ Enable Session Cleanup false │ +│ Enable Session Cleanup false │ +│ Enable automatic session cleanup │ │ │ -│ Output Format Text │ +│ Output Format Text │ +│ The format of the CLI output. │ │ │ -│ Hide Window Title false* │ +│ Hide Window Title false* │ +│ Hide the window title bar │ │ │ │ ▼ │ │ │ @@ -276,21 +332,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ +│ ● Preview Features (e.g., models) false │ +│ Enable preview features (e.g., preview models). │ │ │ -│ Vim Mode false │ +│ Vim Mode false │ +│ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ +│ Disable Auto Update false │ +│ Disable automatic updates │ │ │ -│ Enable Prompt Completion false │ +│ Enable Prompt Completion false │ +│ Enable AI-powered prompt completion suggestions while typing. │ │ │ -│ Debug Keystroke Logging false │ +│ Debug Keystroke Logging false │ +│ Enable debug logging of keystrokes to the console. │ │ │ -│ Enable Session Cleanup false │ +│ Enable Session Cleanup false │ +│ Enable automatic session cleanup │ │ │ -│ Output Format Text │ +│ Output Format Text │ +│ The format of the CLI output. │ │ │ -│ Hide Window Title false │ +│ Hide Window Title false │ +│ Hide the window title bar │ │ │ │ ▼ │ │ │ @@ -314,21 +378,29 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ +│ ● Preview Features (e.g., models) false │ +│ Enable preview features (e.g., preview models). │ │ │ -│ Vim Mode true* │ +│ Vim Mode true* │ +│ Enable Vim keybindings │ │ │ -│ Disable Auto Update true* │ +│ Disable Auto Update true* │ +│ Disable automatic updates │ │ │ -│ Enable Prompt Completion true* │ +│ Enable Prompt Completion true* │ +│ Enable AI-powered prompt completion suggestions while typing. │ │ │ -│ Debug Keystroke Logging true* │ +│ Debug Keystroke Logging true* │ +│ Enable debug logging of keystrokes to the console. │ │ │ -│ Enable Session Cleanup false │ +│ Enable Session Cleanup false │ +│ Enable automatic session cleanup │ │ │ -│ Output Format Text │ +│ Output Format Text │ +│ The format of the CLI output. │ │ │ -│ Hide Window Title true* │ +│ Hide Window Title true* │ +│ Hide the window title bar │ │ │ │ ▼ │ │ │