import type { WizardPrompter } from '../prompter/interface.js'; import type { WizardState } from '../types.js'; import { loadSkillsCatalog } from '../skills/catalog.js'; import { SKILL_CATEGORIES, categorizeSkill } from '../skills/categories.js'; function truncate(str: string, max: number): string { if (str.length <= max) return str; return str.slice(0, max - 1) + '\u2026'; } export async function skillsSelectStage( p: WizardPrompter, state: WizardState, ): Promise { p.separator(); const spin = p.spinner(); spin.update('Loading skills catalog...'); const catalog = loadSkillsCatalog(state.mosaicHome); spin.stop(`Found ${catalog.length} available skills`); if (catalog.length === 0) { p.warn( "No skills found. Run 'mosaic sync' after installation to fetch skills.", ); state.selectedSkills = []; return; } if (state.mode === 'quick') { const defaults = catalog .filter((s) => s.recommended) .map((s) => s.name); state.selectedSkills = defaults; p.note( `Selected ${defaults.length} recommended skills.\n` + `Run 'mosaic sync' later to browse the full catalog.`, 'Skills', ); return; } // Advanced mode: categorized browsing p.note( 'Skills give agents domain expertise for specific tasks.\n' + 'Browse by category and select the ones you want.\n' + "You can always change this later with 'mosaic sync'.", 'Skills Selection', ); // Build grouped options const grouped: Record< string, { value: string; label: string; hint?: string; selected?: boolean }[] > = {}; // Initialize all categories for (const categoryName of Object.keys(SKILL_CATEGORIES)) { grouped[categoryName] = []; } for (const skill of catalog) { const category = categorizeSkill(skill.name, skill.description); if (!grouped[category]) grouped[category] = []; grouped[category].push({ value: skill.name, label: skill.name, hint: truncate(skill.description, 60), selected: skill.recommended, }); } // Remove empty categories for (const key of Object.keys(grouped)) { if (grouped[key].length === 0) delete grouped[key]; } state.selectedSkills = await p.groupMultiselect({ message: 'Select skills (space to toggle)', options: grouped, required: false, }); }