import { defineStore } from 'pinia'; import type { Skill, MarketplaceSkill } from '@src/lib/skills-types'; import { apiFetchSkills, apiSearchSkills, apiInstallSkill, apiUninstallSkill, apiUpdateSkillConfig, } from '@src/lib/skills-api'; const INSTALL_ERROR_CODES = new Set(['installTimeoutError', 'installRateLimitError']); const FETCH_ERROR_CODES = new Set(['fetchTimeoutError', 'fetchRateLimitError', 'timeoutError', 'rateLimitError']); const SEARCH_ERROR_CODES = new Set(['searchTimeoutError', 'searchRateLimitError', 'timeoutError', 'rateLimitError']); export const useSkillsStore = defineStore('skills', { state: () => ({ skills: [] as Skill[], searchResults: [] as MarketplaceSkill[], loading: false, searching: false, searchError: null as string | null, installing: {} as Record, error: null as string | null, }), getters: { sourceStats: (state) => { const safeSkills = Array.isArray(state.skills) ? state.skills : []; return { all: safeSkills.length, builtIn: safeSkills.filter(s => s.isBundled).length, marketplace: safeSkills.filter(s => !s.isBundled).length, }; }, }, actions: { async fetchSkills() { if (this.skills.length === 0) { this.loading = true; } this.error = null; try { this.skills = await apiFetchSkills(); } catch (error) { console.error('Failed to fetch skills:', error); const msg = error instanceof Error ? error.message : String(error); this.error = FETCH_ERROR_CODES.has(msg) ? msg : msg; } finally { this.loading = false; } }, async searchSkills(query: string) { this.searching = true; this.searchError = null; try { this.searchResults = await apiSearchSkills(query); } catch (error) { const msg = error instanceof Error ? error.message : String(error); this.searchError = SEARCH_ERROR_CODES.has(msg) ? msg : msg; } finally { this.searching = false; } }, async installSkill(slug: string, version?: string) { this.installing[slug] = true; try { await apiInstallSkill(slug, version); await this.fetchSkills(); } finally { delete this.installing[slug]; } }, async uninstallSkill(slug: string) { this.installing[slug] = true; try { await apiUninstallSkill(slug); await this.fetchSkills(); } finally { delete this.installing[slug]; } }, async enableSkill(skillId: string) { const skill = this.skills.find(s => s.id === skillId); if (!skill) return; try { await apiUpdateSkillConfig(skillId, { enabled: true }); skill.enabled = true; } catch (error) { console.error('Failed to enable skill:', error); throw error; } }, async disableSkill(skillId: string) { const skill = this.skills.find(s => s.id === skillId); if (!skill) return; if (skill.isCore) { throw new Error('Cannot disable core skill'); } try { await apiUpdateSkillConfig(skillId, { enabled: false }); skill.enabled = false; } catch (error) { console.error('Failed to disable skill:', error); throw error; } }, updateSkill(skillId: string, updates: Partial) { const skill = this.skills.find(s => s.id === skillId); if (skill) { Object.assign(skill, updates); } }, }, }); export { INSTALL_ERROR_CODES, FETCH_ERROR_CODES, SEARCH_ERROR_CODES };