/** * * skillMarketStore.ts - 技能市场状态管理 * * * 猛攻状态管理技能浏览、搜索、安装/卸载等功能 */ import { create } from 'zustand'; import { persist } from 'zustand/middleware'; import type { Skill, SkillReview, SkillMarketState } from '../types/skill-market'; // === 存储键 === const STORAGE_KEY = 'zclaw-skill-market'; const INSTALLED_KEY = 'zclaw-installed-skills'; // === 默认状态 === const initialState: SkillMarketState = { skills: [], installedSkills: [], searchResults: [], selectedSkill: null, searchQuery: '', categoryFilter: 'all', isLoading: false, error: null, }; // === Store 定义 === interface SkillMarketActions { // 技能加载 loadSkills: () => Promise; // 技能搜索 searchSkills: (query: string) => void; // 分类过滤 filterByCategory: (category: string) => void; // 选择技能 selectSkill: (skill: Skill | null) => void; // 安装技能 installSkill: (skillId: string) => Promise; // 卸载技能 uninstallSkill: (skillId: string) => Promise; // 获取技能详情 getSkillDetails: (skillId: string) => Promise; // 加载评论 loadReviews: (skillId: string) => Promise; // 添加评论 addReview: (skillId: string, review: Omit) => Promise; // 刷新技能列表 refreshSkills: () => Promise; // 清除错误 clearError: () => void; // 重置状态 reset: () => void; } // === Store 创建 === export const useSkillMarketStore = create()( persist({ key: STORAGE_KEY, storage: localStorage, partialize: (state) => ({ installedSkills: state.installedSkills, categoryFilter: state.categoryFilter, }), }), initialState, { // === 技能加载 === loadSkills: async () => { set({ isLoading: true, error: null }); try { // 扫描 skills 目录获取可用技能 const skills = await scanSkillsDirectory(); // 从 localStorage 恢复安装状态 const stored = localStorage.getItem(INSTALLED_KEY); const installedSkills: string[] = stored ? JSON.parse(stored) : []; // 更新技能的安装状态 const updatedSkills = skills.map(skill => ({ ...skill, installed: installedSkills.includes(skill.id), }))); set({ skills: updatedSkills, installedSkills, isLoading: false, }); } catch (err) { set({ isLoading: false, error: err instanceof Error ? err.message : '加载技能失败', }); } }, // === 技能搜索 === searchSkills: (query: string) => { const { skills } = get(); set({ searchQuery: query }); if (!query.trim()) { set({ searchResults: [] }); return; } const queryLower = query.toLowerCase(); const results = skills.filter(skill => { return ( skill.name.toLowerCase().includes(queryLower) || skill.description.toLowerCase().includes(queryLower) || skill.triggers.some(t => t.toLowerCase().includes(queryLower)) || skill.capabilities.some(c => c.toLowerCase().includes(queryLower)) || skill.tags?.some(t => t.toLowerCase().includes(queryLower)) ); }); set({ searchResults: results }); }, // === 分类过滤 === filterByCategory: (category: string) => { set({ categoryFilter: category }); }, // === 选择技能 === selectSkill: (skill: Skill | null) => { set({ selectedSkill: skill }); }, // === 安装技能 === installSkill: async (skillId: string) => { const { skills, installedSkills } = get(); const skill = skills.find(s => s.id === skillId); if (!skill) return false; try { // 更新安装状态 const newInstalledSkills = [...installedSkills, skillId]; const updatedSkills = skills.map(s => ({ ...s, installed: s.id === skillId ? true : s.installed, installedAt: s.id === skillId ? new Date().toISOString() : s.installedAt, })); // 持久化安装列表 localStorage.setItem(INSTALLED_KEY, JSON.stringify(newInstalledSkills)); set({ skills: updatedSkills, installedSkills: newInstalledSkills, }); return true; } catch (err) { set({ error: err instanceof Error ? err.message : '安装技能失败', }); return false; } }, // === 卸载技能 === uninstallSkill: async (skillId: string) => { const { skills, installedSkills } = get(); try { // 更新安装状态 const newInstalledSkills = installedSkills.filter(id => id !== skillId); const updatedSkills = skills.map(s => ({ ...s, installed: s.id === skillId ? false : s.installed, installedAt: s.id === skillId ? undefined : s.installedAt, })); // 持久化安装列表 localStorage.setItem(INSTALLED_KEY, JSON.stringify(newInstalledSkills)); set({ skills: updatedSkills, installedSkills: newInstalledSkills, }); return true; } catch (err) { set({ error: err instanceof Error ? err.message : '卸载技能失败', }); return false; } }, // === 获取技能详情 === getSkillDetails: async (skillId: string) => { const { skills } = get(); return skills.find(s => s.id === skillId) || null; }, // === 加载评论 === loadReviews: async (skillId: string) => { // MVP: 从 localStorage 模拟加载评论 const reviewsKey = `zclaw-skill-reviews-${skillId}`; const stored = localStorage.getItem(reviewsKey); const reviews: SkillReview[] = stored ? JSON.parse(stored) : []; return reviews; }, // === 添加评论 === addReview: async (skillId: string, review: Omit) => { const reviews = await get().loadReviews(skillId); const newReview: SkillReview = { ...review, id: `review-${Date.now()}`, skillId, createdAt: new Date().toISOString(), }; const updatedReviews = [...reviews, newReview]; // 更新技能的评分和评论数 const { skills } = get(); const updatedSkills = skills.map(s => { if (s.id === skillId) { const totalRating = updatedReviews.reduce((sum, r) => sum + r.rating, 0); const avgRating = totalRating / updatedReviews.length; return { ...s, rating: Math.round(avgRating * 10) / 10, reviewCount: updatedReviews.length, }; } return s; }); // 持久化评论 const reviewsKey = `zclaw-skill-reviews-${skillId}`; localStorage.setItem(reviewsKey, JSON.stringify(updatedReviews)); set({ skills: updatedSkills }); }, // === 刷新技能列表 === refreshSkills: async () => { // 清除缓存并重新加载 localStorage.removeItem(STORAGE_KEY); await get().loadSkills(); }, // === 清除错误 === clearError: () => { set({ error: null }); }, // === 重置状态 === reset: () => { localStorage.removeItem(STORAGE_KEY); localStorage.removeItem(INSTALLED_KEY); set(initialState); }, } ); // === 辅助函数 === /** * 扫描 skills 目录获取可用技能 */ async function scanSkillsDirectory(): Promise { // 这里我们模拟扫描,实际实现需要通过 Tauri API 访问文件系统 // 或者从预定义的技能列表中加载 const skills: Skill[] = [ // 开发类 { id: 'code-review', name: '代码审查', description: '审查代码、分析代码质量、提供改进建议', triggers: ['审查代码', '代码审查', 'code review', 'PR Review', '检查代码', '分析代码'], capabilities: ['代码质量分析', '架构评估', '最佳实践检查', '安全审计'], toolDeps: ['read', 'grep', 'glob'], category: 'development', installed: false, tags: ['代码', '审查', '质量'], }, { id: 'translation', name: '翻译助手', description: '翻译文本、多语言转换、保持语言风格一致性', triggers: ['翻译', 'translate', '中译英', '英译中', '翻译成', '转换成'], capabilities: ['多语言翻译', '技术文档翻译', '代码注释翻译', 'UI 文本翻译', '风格保持'], toolDeps: ['read', 'write'], category: 'content', installed: false, tags: ['翻译', '语言', '国际化'], }, { id: 'chinese-writing', name: '中文写作', description: '中文写作助手 - 帮助撰写各类中文文档、文章、报告', triggers: ['写一篇', '帮我写', '撰写', '起草', '润色', '中文写作'], capabilities: ['撰写文档', '润色修改', '调整语气', '中英文翻译'], toolDeps: ['read', 'write'], category: 'content', installed: false, tags: ['写作', '文档', '中文'], }, { id: 'web-search', name: '网络搜索', description: '搜索互联网信息、整合多方来源', triggers: ['搜索', 'search', '查找信息', '查询', '搜索网络'], capabilities: ['搜索引擎集成', '信息提取', '来源验证', '结果整合'], toolDeps: ['web_search'], category: 'research', installed: false, tags: ['搜索', '互联网', '信息'], }, { id: 'data-analysis', name: '数据分析', description: '数据清洗、统计分析、可视化图表', triggers: ['数据分析', '统计', '可视化', '图表', 'analytics'], capabilities: ['数据清洗', '统计分析', '可视化图表', '报告生成'], toolDeps: ['read', 'write', 'shell'], category: 'analytics', installed: false, tags: ['数据', '分析', '可视化'], }, { id: 'git', name: 'Git 操作', description: 'Git 版本控制操作、分支管理、冲突解决', triggers: ['git', '版本控制', '分支', '合并', 'commit', 'merge'], capabilities: ['分支管理', '冲突解决', 'rebase', 'cherry-pick'], toolDeps: ['shell'], category: 'development', installed: false, tags: ['git', '版本控制', '分支'], }, { id: 'shell-command', name: 'Shell 命令', description: '执行 Shell 命令、系统操作', triggers: ['shell', '命令行', '终端', 'terminal', 'bash'], capabilities: ['命令执行', '管道操作', '脚本运行', '环境管理'], toolDeps: ['shell'], category: 'ops', installed: false, tags: ['shell', '命令', '系统'], }, { id: 'file-operations', name: '文件操作', description: '文件读写、目录管理、文件搜索', triggers: ['文件', 'file', '读取', '写入', '目录', '文件夹'], capabilities: ['文件读写', '目录管理', '文件搜索', '批量操作'], toolDeps: ['read', 'write', 'glob'], category: 'ops', installed: false, tags: ['文件', '目录', '读写'], }, { id: 'security-engineer', name: '安全工程师', description: '安全工程师 - 负责安全审计、漏洞检测、合规检查', triggers: ['安全审计', '漏洞检测', '安全检查', 'security', '渗透测试'], capabilities: ['漏洞扫描', '合规检查', '安全加固', '威胁建模'], toolDeps: ['read', 'grep', 'shell'], category: 'security', installed: false, tags: ['安全', '审计', '漏洞'], }, { id: 'ai-engineer', name: 'AI 工程师', description: 'AI/ML 工程师 - 专注机器学习模型开发、LLM 集成和生产系统部署', triggers: ['AI工程师', '机器学习', 'ML模型', 'LLM集成', '深度学习', '模型训练'], capabilities: ['ML 框架', 'LLM 集成', 'RAG 系统', '向量数据库'], toolDeps: ['bash', 'read', 'write', 'grep', 'glob'], category: 'development', installed: false, tags: ['AI', 'ML', 'LLM'], }, { id: 'senior-developer', name: '高级开发', description: '高级开发工程师 - 端到端功能实现、复杂问题解决', triggers: ['高级开发', 'senior developer', '端到端', '复杂功能', '架构实现'], capabilities: ['端到端实现', '架构设计', '性能优化', '代码重构'], toolDeps: ['bash', 'read', 'write', 'grep', 'glob'], category: 'development', installed: false, tags: ['开发', '架构', '实现'], }, { id: 'frontend-developer', name: '前端开发', description: '前端开发专家 - 擅长 React/Vue/CSS/TypeScript', triggers: ['前端开发', '页面开发', 'UI开发', 'React', 'Vue', 'CSS'], capabilities: ['组件开发', '样式调整', '性能优化', '响应式设计'], toolDeps: ['read', 'write', 'shell'], category: 'development', installed: false, types: ['前端', 'UI', '组件'], }, { id: 'backend-architect', name: '后端架构', description: '后端架构设计、API设计、数据库建模', triggers: ['后端架构', 'API设计', '数据库设计', '系统架构', '微服务'], capabilities: ['架构设计', 'API规范', '数据库建模', '性能优化'], toolDeps: ['read', 'write', 'shell'], category: 'development', installed: false, tags: ['后端', '架构', 'API'], }, { id: 'devops-automator', name: 'DevOps 自动化', description: 'CI/CD、Docker、K8s、自动化部署', triggers: ['DevOps', 'CI/CD', 'Docker', '部署', '自动化', 'K8s'], capabilities: ['CI/CD配置', '容器化', '自动化部署', '监控告警'], toolDeps: ['shell', 'read', 'write'], category: 'ops', installed: false, tags: ['DevOps', 'Docker', 'CI/CD'], }, { id: 'senior-pm', name: '高级PM', description: '项目管理、需求分析、迭代规划', triggers: ['项目管理', '需求分析', '迭代规划', '产品设计', 'PRD'], capabilities: ['需求拆解', '迭代排期', '风险评估', '文档撰写'], toolDeps: ['read', 'write'], category: 'management', installed: false, tags: ['PM', '需求', '迭代'], }, ]; return skills; }