TUI5: Added scrollable Skill Selector modal - /skill and /skills now open SelectInput picker
This commit is contained in:
@@ -2289,6 +2289,10 @@ const App = () => {
|
|||||||
const [showCommandPalette, setShowCommandPalette] = useState(false);
|
const [showCommandPalette, setShowCommandPalette] = useState(false);
|
||||||
const [paletteFilter, setPaletteFilter] = useState(''); // For search
|
const [paletteFilter, setPaletteFilter] = useState(''); // For search
|
||||||
|
|
||||||
|
// SKILL SELECTOR: Overlay for selecting skills
|
||||||
|
const [showSkillSelector, setShowSkillSelector] = useState(false);
|
||||||
|
const [activeSkill, setActiveSkill] = useState(null);
|
||||||
|
|
||||||
// PRO PROTOCOL: Run state management
|
// PRO PROTOCOL: Run state management
|
||||||
const [currentRun, setCurrentRun] = useState(null);
|
const [currentRun, setCurrentRun] = useState(null);
|
||||||
|
|
||||||
@@ -2622,28 +2626,25 @@ const App = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '/skills': {
|
case '/skills':
|
||||||
const display = getSkillListDisplay();
|
|
||||||
setMessages(prev => [...prev, { role: 'system', content: `🎯 **Available Skills**\n${display}\nUsage: /skill <name> then describe your task` }]);
|
|
||||||
setInput('');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case '/skill': {
|
case '/skill': {
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
|
// Open skill selector
|
||||||
|
setShowSkillSelector(true);
|
||||||
|
setInput('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Direct skill activation with argument
|
||||||
|
const skillName = arg.split(/\s+/)[0];
|
||||||
|
const skill = getSkill(skillName);
|
||||||
|
if (!skill) {
|
||||||
const skills = getAllSkills();
|
const skills = getAllSkills();
|
||||||
const names = skills.map(s => s.id).join(', ');
|
const names = skills.map(s => s.id).join(', ');
|
||||||
setMessages(prev => [...prev, { role: 'system', content: `❌ Usage: /skill <name>\nAvailable: ${names}` }]);
|
setMessages(prev => [...prev, { role: 'system', content: `❌ Unknown skill: "${skillName}"\nAvailable: ${names}\n\nUse /skills to see the full list.` }]);
|
||||||
} else {
|
} else {
|
||||||
const skillName = arg.split(/\s+/)[0];
|
// Inject skill prompt into system for next message
|
||||||
const skill = getSkill(skillName);
|
setActiveSkill(skill);
|
||||||
if (!skill) {
|
setMessages(prev => [...prev, { role: 'system', content: `🎯 **Activated: ${skill.name}**\n${skill.description}\n\nNow describe your task and I'll apply this skill.` }]);
|
||||||
const skills = getAllSkills();
|
|
||||||
const names = skills.map(s => s.id).join(', ');
|
|
||||||
setMessages(prev => [...prev, { role: 'system', content: `❌ Unknown skill: "${skillName}"\nAvailable: ${names}` }]);
|
|
||||||
} else {
|
|
||||||
setMessages(prev => [...prev, { role: 'system', content: `🎯 **Activated: ${skill.name}**\n${skill.description}\n\nNow describe your task and I'll apply this skill.` }]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setInput('');
|
setInput('');
|
||||||
return;
|
return;
|
||||||
@@ -4140,6 +4141,80 @@ This gives the user a chance to refine requirements before implementation.
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// SKILL SELECTOR OVERLAY - Scrollable skill picker
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
if (showSkillSelector && appState === 'chat') {
|
||||||
|
const skills = getAllSkills();
|
||||||
|
const skillItems = skills.map(skill => ({
|
||||||
|
label: `${getCategoryEmoji(skill.category)} ${skill.id.padEnd(20)} ${skill.name}`,
|
||||||
|
value: skill.id,
|
||||||
|
skill: skill
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Category emoji helper
|
||||||
|
function getCategoryEmoji(cat) {
|
||||||
|
const emojis = {
|
||||||
|
design: '🎨',
|
||||||
|
documents: '📄',
|
||||||
|
development: '💻',
|
||||||
|
testing: '🧪',
|
||||||
|
writing: '✍️',
|
||||||
|
creative: '🎭',
|
||||||
|
documentation: '📚',
|
||||||
|
meta: '🔧'
|
||||||
|
};
|
||||||
|
return emojis[cat] || '📌';
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSkillSelect = (item) => {
|
||||||
|
setShowSkillSelector(false);
|
||||||
|
setActiveSkill(item.skill);
|
||||||
|
setMessages(prev => [...prev, {
|
||||||
|
role: 'system',
|
||||||
|
content: `🎯 **Activated: ${item.skill.name}**\n${item.skill.description}\n\nNow describe your task and I'll apply this skill.`
|
||||||
|
}]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle ESC to close
|
||||||
|
useInput((input, key) => {
|
||||||
|
if (key.escape) {
|
||||||
|
setShowSkillSelector(false);
|
||||||
|
}
|
||||||
|
}, { isActive: showSkillSelector });
|
||||||
|
|
||||||
|
return h(Box, {
|
||||||
|
flexDirection: 'column',
|
||||||
|
borderStyle: 'round',
|
||||||
|
borderColor: 'magenta',
|
||||||
|
padding: 1,
|
||||||
|
width: Math.min(55, columns - 4),
|
||||||
|
},
|
||||||
|
// Header
|
||||||
|
h(Text, { color: 'magenta', bold: true }, '🎯 Select a Skill'),
|
||||||
|
h(Text, { color: 'gray', dimColor: true }, 'Use ↑↓ to navigate, Enter to select'),
|
||||||
|
|
||||||
|
// Skill list with SelectInput
|
||||||
|
h(Box, { flexDirection: 'column', marginTop: 1, height: Math.min(18, rows - 8) },
|
||||||
|
h(SelectInput, {
|
||||||
|
items: skillItems,
|
||||||
|
onSelect: handleSkillSelect,
|
||||||
|
itemComponent: ({ isSelected, label }) =>
|
||||||
|
h(Text, {
|
||||||
|
color: isSelected ? 'magenta' : 'white',
|
||||||
|
bold: isSelected
|
||||||
|
}, isSelected ? `❯ ${label}` : ` ${label}`)
|
||||||
|
})
|
||||||
|
),
|
||||||
|
|
||||||
|
// Footer with categories
|
||||||
|
h(Box, { marginTop: 1, flexDirection: 'column' },
|
||||||
|
h(Text, { dimColor: true }, 'Categories: 🎨Design 📄Docs 💻Dev 🧪Test ✍️Write'),
|
||||||
|
h(Text, { dimColor: true }, 'Esc to close')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
// COMMAND PALETTE OVERLAY (Ctrl+K) - Searchable commands
|
// COMMAND PALETTE OVERLAY (Ctrl+K) - Searchable commands
|
||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
|||||||
Reference in New Issue
Block a user