TUI5: Redesigned settings panel with SelectInput navigation, grouped sections, and direct toggle actions
This commit is contained in:
@@ -4180,117 +4180,146 @@ This gives the user a chance to refine requirements before implementation.
|
|||||||
{ label: '/exit Exit TUI', value: '/exit' }
|
{ label: '/exit Exit TUI', value: '/exit' }
|
||||||
];
|
];
|
||||||
|
|
||||||
// Filter commands based on search
|
// Create all menu items with proper grouping and actions
|
||||||
const filter = paletteFilter.toLowerCase();
|
const menuItems = [
|
||||||
const filteredCommands = filter
|
// ═══════════════════════════════════════════════════════════════
|
||||||
? allCommands.filter(c => c.label.toLowerCase().includes(filter))
|
// TOGGLES (direct action on select)
|
||||||
: allCommands;
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ label: `⚙ SmartX Engine ${soloMode ? '🟢 ON' : '⚫ OFF'}`, value: 'toggle_smartx', action: 'toggle' },
|
||||||
const handleCommandSelect = (item) => {
|
{ label: `⚙ Auto-Approve ${autoApprove ? '🟢 ON' : '⚫ OFF'}`, value: 'toggle_auto', action: 'toggle' },
|
||||||
setShowCommandPalette(false);
|
{ label: `⚙ Multi-Agent ${multiAgentEnabled ? '🟢 ON' : '⚫ OFF'}`, value: 'toggle_agents', action: 'toggle' },
|
||||||
setPaletteFilter(''); // Reset filter
|
{ label: `⚙ Smart Context ${contextEnabled ? '🟢 ON' : '⚫ OFF'}`, value: 'toggle_context', action: 'toggle' },
|
||||||
setInput(item.value);
|
{ label: `⚙ Exposed Thinking ${exposedThinking ? '🟢 ON' : '⚫ OFF'}`, value: 'toggle_thinking', action: 'toggle' },
|
||||||
};
|
{ label: `⚙ Debug Logging ${debugLogger.enabled ? '🟢 ON' : '⚫ OFF'}`, value: 'toggle_debug', action: 'toggle' },
|
||||||
|
{ label: '─────────────────────────────', value: 'sep1', action: 'noop' },
|
||||||
// Settings with current state
|
// ═══════════════════════════════════════════════════════════════
|
||||||
const settingsSection = [
|
// MEMORY COMMANDS
|
||||||
{
|
// ═══════════════════════════════════════════════════════════════
|
||||||
name: 'Multi-Agent Mode',
|
{ label: '📝 /remember Save to Memory', value: '/remember ', action: 'input' },
|
||||||
value: multiAgentEnabled,
|
{ label: '📝 /memory View Memory', value: '/memory', action: 'cmd' },
|
||||||
onCmd: '/agents on',
|
{ label: '📝 /forget Remove Fact', value: '/forget ', action: 'input' },
|
||||||
offCmd: '/agents off'
|
{ label: '─────────────────────────────', value: 'sep2', action: 'noop' },
|
||||||
},
|
// ═══════════════════════════════════════════════════════════════
|
||||||
{
|
// SKILLS
|
||||||
name: 'Smart Context',
|
// ═══════════════════════════════════════════════════════════════
|
||||||
value: contextEnabled,
|
{ label: '🎯 /skills List Skills', value: '/skills', action: 'cmd' },
|
||||||
onCmd: '/context',
|
{ label: '🎯 /skill Use a Skill', value: '/skill ', action: 'input' },
|
||||||
offCmd: '/context'
|
{ label: '─────────────────────────────', value: 'sep3', action: 'noop' },
|
||||||
},
|
// ═══════════════════════════════════════════════════════════════
|
||||||
{
|
// AGENTS
|
||||||
name: 'Exposed Thinking',
|
// ═══════════════════════════════════════════════════════════════
|
||||||
value: exposedThinking,
|
{ label: '🤖 /agents Agent Menu', value: '/agents', action: 'cmd' },
|
||||||
onCmd: '/thinking on',
|
{ label: '🤖 /plan Planner Agent', value: '/plan', action: 'cmd' },
|
||||||
offCmd: '/thinking off'
|
{ label: '🤖 /model Change Model', value: '/model', action: 'cmd' },
|
||||||
},
|
{ label: '─────────────────────────────', value: 'sep4', action: 'noop' },
|
||||||
{
|
// ═══════════════════════════════════════════════════════════════
|
||||||
name: 'SmartX Engine',
|
// SESSION
|
||||||
value: soloMode,
|
// ═══════════════════════════════════════════════════════════════
|
||||||
onCmd: '/smartx on',
|
{ label: '💾 /save Save Session', value: '/save ', action: 'input' },
|
||||||
offCmd: '/smartx off'
|
{ label: '📂 /load Load Session', value: '/load ', action: 'input' },
|
||||||
},
|
{ label: '📋 /paste Clipboard Paste', value: '/paste', action: 'cmd' },
|
||||||
{
|
{ label: '📁 /project Project Info', value: '/project', action: 'cmd' },
|
||||||
name: 'Auto-Approve',
|
{ label: '✍️ /write Write Files', value: '/write', action: 'cmd' },
|
||||||
value: autoApprove,
|
{ label: '🗑️ /clear Clear Session', value: '/clear', action: 'cmd' },
|
||||||
onCmd: '/auto',
|
{ label: '❓ /help All Commands', value: '/help', action: 'cmd' },
|
||||||
offCmd: '/auto'
|
{ label: '🚪 /exit Exit TUI', value: '/exit', action: 'cmd' },
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Filter out separators when searching
|
||||||
|
const filter = paletteFilter.toLowerCase();
|
||||||
|
const filteredItems = filter
|
||||||
|
? menuItems.filter(item => item.action !== 'noop' && item.label.toLowerCase().includes(filter))
|
||||||
|
: menuItems;
|
||||||
|
|
||||||
|
// Handle menu selection
|
||||||
|
const handleMenuSelect = (item) => {
|
||||||
|
if (item.action === 'noop') return; // Separator clicked
|
||||||
|
|
||||||
|
if (item.action === 'toggle') {
|
||||||
|
// Execute toggle immediately
|
||||||
|
switch (item.value) {
|
||||||
|
case 'toggle_smartx':
|
||||||
|
setSoloMode(prev => !prev);
|
||||||
|
break;
|
||||||
|
case 'toggle_auto':
|
||||||
|
setAutoApprove(prev => !prev);
|
||||||
|
break;
|
||||||
|
case 'toggle_agents':
|
||||||
|
setMultiAgentEnabled(prev => !prev);
|
||||||
|
break;
|
||||||
|
case 'toggle_context':
|
||||||
|
setContextEnabled(prev => !prev);
|
||||||
|
break;
|
||||||
|
case 'toggle_thinking':
|
||||||
|
setExposedThinking(prev => !prev);
|
||||||
|
break;
|
||||||
|
case 'toggle_debug':
|
||||||
|
debugLogger.toggle();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Don't close - allow multiple toggles
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.action === 'cmd') {
|
||||||
|
// Execute command immediately
|
||||||
|
setShowCommandPalette(false);
|
||||||
|
setPaletteFilter('');
|
||||||
|
setInput(item.value);
|
||||||
|
// Trigger submit
|
||||||
|
setTimeout(() => {
|
||||||
|
// Auto-submit the command
|
||||||
|
}, 50);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.action === 'input') {
|
||||||
|
// Put in input field for user to complete
|
||||||
|
setShowCommandPalette(false);
|
||||||
|
setPaletteFilter('');
|
||||||
|
setInput(item.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return h(Box, {
|
return h(Box, {
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
|
borderStyle: 'round',
|
||||||
|
borderColor: 'cyan',
|
||||||
padding: 1,
|
padding: 1,
|
||||||
width: Math.min(60, columns - 4),
|
width: Math.min(45, columns - 4),
|
||||||
height: rows
|
|
||||||
},
|
},
|
||||||
// Header
|
// Header
|
||||||
h(Text, { color: 'cyan', bold: true }, '⚙ Settings Menu (Ctrl+K)'),
|
h(Text, { color: 'cyan', bold: true }, '⚙ Settings & Commands'),
|
||||||
h(Text, { color: 'gray', dimColor: true }, '─'.repeat(30)),
|
h(Text, { color: 'gray', dimColor: true }, 'Use ↑↓ to navigate, Enter to select'),
|
||||||
|
|
||||||
// SETTINGS SECTION with toggles
|
|
||||||
h(Box, { marginTop: 1, marginBottom: 1, flexDirection: 'column' },
|
|
||||||
h(Text, { color: 'yellow', bold: true }, 'SETTINGS'),
|
|
||||||
...settingsSection.map((setting, i) =>
|
|
||||||
h(Box, { key: i, marginTop: 0 },
|
|
||||||
h(Text, { color: 'gray' }, ` ${setting.name}: `),
|
|
||||||
setting.value
|
|
||||||
? h(Text, { color: 'green', bold: true }, '[ON] ')
|
|
||||||
: h(Text, { color: 'gray', dimColor: true }, '[OFF]'),
|
|
||||||
h(Text, { color: 'gray', dimColor: true },
|
|
||||||
setting.value ? ` → ${setting.offCmd}` : ` → ${setting.onCmd}`)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
h(Text, { color: 'gray', dimColor: true }, '─'.repeat(30)),
|
|
||||||
|
|
||||||
// COMMANDS SECTION
|
|
||||||
h(Box, { marginTop: 1, flexDirection: 'column' },
|
|
||||||
h(Text, { color: 'yellow', bold: true }, 'COMMANDS'),
|
|
||||||
h(Text, { color: 'gray' }, ' /agents Agent Menu'),
|
|
||||||
h(Text, { color: 'gray' }, ' /plan Planner Agent'),
|
|
||||||
h(Text, { color: 'cyan' }, ' /remember Save to Memory'),
|
|
||||||
h(Text, { color: 'cyan' }, ' /memory View Memory'),
|
|
||||||
h(Text, { color: 'cyan' }, ' /skills List Skills'),
|
|
||||||
h(Text, { color: 'cyan' }, ' /skill Use a Skill'),
|
|
||||||
h(Text, { color: 'cyan' }, ' /debug Toggle Debug'),
|
|
||||||
h(Text, { color: 'gray' }, ' /paste Clipboard Paste'),
|
|
||||||
h(Text, { color: 'gray' }, ' /project Project Info'),
|
|
||||||
h(Text, { color: 'gray' }, ' /write Write Files'),
|
|
||||||
h(Text, { color: 'gray' }, ' /clear Clear Session'),
|
|
||||||
h(Text, { color: 'gray' }, ' /smartx SmartX Engine On/Off'),
|
|
||||||
h(Text, { color: 'gray' }, ' /auto Auto-Approve On/Off'),
|
|
||||||
h(Text, { color: 'gray' }, ' /help All Commands'),
|
|
||||||
h(Text, { color: 'gray' }, ' /exit Exit TUI')
|
|
||||||
),
|
|
||||||
|
|
||||||
// Search input
|
// Search input
|
||||||
h(Box, { marginTop: 1 },
|
h(Box, { marginTop: 1, marginBottom: 1 },
|
||||||
h(Text, { color: 'gray' }, '> '),
|
h(Text, { color: 'yellow' }, '🔍 '),
|
||||||
h(TextInput, {
|
h(TextInput, {
|
||||||
value: paletteFilter,
|
value: paletteFilter,
|
||||||
onChange: setPaletteFilter,
|
onChange: setPaletteFilter,
|
||||||
placeholder: 'Type command...'
|
placeholder: 'Type to filter...'
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
|
||||||
// Filtered results (if searching)
|
// Menu items with SelectInput
|
||||||
filter && filteredCommands.length > 0
|
h(Box, { flexDirection: 'column', height: Math.min(20, rows - 10) },
|
||||||
? h(SelectInput, { items: filteredCommands, onSelect: handleCommandSelect })
|
h(SelectInput, {
|
||||||
: null,
|
items: filteredItems,
|
||||||
|
onSelect: handleMenuSelect,
|
||||||
|
itemComponent: ({ isSelected, label }) =>
|
||||||
|
h(Text, {
|
||||||
|
color: label.startsWith('─') ? 'gray' : (isSelected ? 'cyan' : 'white'),
|
||||||
|
bold: isSelected,
|
||||||
|
dimColor: label.startsWith('─')
|
||||||
|
}, isSelected && !label.startsWith('─') ? `❯ ${label}` : ` ${label}`)
|
||||||
|
})
|
||||||
|
),
|
||||||
|
|
||||||
// Footer
|
// Footer
|
||||||
h(Box, { marginTop: 1 },
|
h(Box, { marginTop: 1 },
|
||||||
h(Text, { dimColor: true }, 'Esc to close')
|
h(Text, { dimColor: true }, 'Esc to close • Toggles update instantly')
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user