275 lines
10 KiB
TypeScript
275 lines
10 KiB
TypeScript
import { SkillItem } from '@/pages/SkillManager/data';
|
|
|
|
// 类型映射函数
|
|
function getSkillType(skillName: string): SkillItem['type'] {
|
|
const typeMap: Record<string, string[]> = {
|
|
agent: ['agent-development', 'skill-creator', 'skill-creation-guide'],
|
|
design: [
|
|
'frontend-design',
|
|
'ui-design-system',
|
|
'ui-ux-pro-max',
|
|
'canvas-design',
|
|
'brand-guidelines',
|
|
],
|
|
document: ['docx', 'pdf', 'pptx', 'xlsx', 'doc-coauthoring'],
|
|
testing: [
|
|
'test',
|
|
'playwright',
|
|
'webapp-testing',
|
|
'test-driven-development',
|
|
],
|
|
integration: [
|
|
'mcp-builder',
|
|
'command-creator',
|
|
'command-development',
|
|
'figma',
|
|
],
|
|
workflow: [
|
|
'brainstorming',
|
|
'planning-with-files',
|
|
'subagent-driven-development',
|
|
'executing-plans',
|
|
'dispatching-parallel-agents',
|
|
'finishing-a-development-branch',
|
|
],
|
|
utility: [
|
|
'flags',
|
|
'fix',
|
|
'verify',
|
|
'extract-errors',
|
|
'flow',
|
|
'systematic-debugging',
|
|
'find-skills',
|
|
'feature-flags',
|
|
],
|
|
};
|
|
|
|
for (const [type, names] of Object.entries(typeMap)) {
|
|
if (names.includes(skillName)) {
|
|
return type as SkillItem['type'];
|
|
}
|
|
}
|
|
return 'development';
|
|
}
|
|
|
|
// 解析 frontmatter 的辅助函数
|
|
function parseFrontmatter(content: string): {
|
|
name: string;
|
|
description: string;
|
|
} {
|
|
const nameMatch = content.match(/^name:\s*(.+)$/m);
|
|
const descMatch = content.match(/^description:\s*(.+)$/m);
|
|
return {
|
|
name: nameMatch ? nameMatch[1].trim() : '',
|
|
description: descMatch ? descMatch[1].trim() : '',
|
|
};
|
|
}
|
|
|
|
// 模拟从文件系统读取 skills 数据
|
|
function getMockSkills(): SkillItem[] {
|
|
const skillsData = [
|
|
{ name: 'agent-development', source: 'agents' as const },
|
|
{ name: 'algorithmic-art', source: 'agents' as const },
|
|
{ name: 'brainstorming', source: 'agents' as const },
|
|
{ name: 'brand-guidelines', source: 'agents' as const },
|
|
{ name: 'canvas-design', source: 'agents' as const },
|
|
{ name: 'command-creator', source: 'agents' as const },
|
|
{ name: 'command-development', source: 'agents' as const },
|
|
{ name: 'context7', source: 'agents' as const },
|
|
{ name: 'context7-auto-research', source: 'agents' as const },
|
|
{ name: 'dispatching-parallel-agents', source: 'agents' as const },
|
|
{ name: 'doc-coauthoring', source: 'agents' as const },
|
|
{ name: 'docx', source: 'agents' as const },
|
|
{ name: 'executing-plans', source: 'agents' as const },
|
|
{ name: 'extract-errors', source: 'agents' as const },
|
|
{ name: 'feature-flags', source: 'agents' as const },
|
|
{ name: 'figma', source: 'agents' as const },
|
|
{ name: 'figma-implement-design', source: 'agents' as const },
|
|
{ name: 'find-skills', source: 'agents' as const },
|
|
{ name: 'finishing-a-development-branch', source: 'agents' as const },
|
|
{ name: 'fix', source: 'agents' as const },
|
|
{ name: 'flags', source: 'agents' as const },
|
|
{ name: 'flow', source: 'agents' as const },
|
|
{ name: 'frontend-design', source: 'agents' as const },
|
|
{ name: 'internal-comms', source: 'agents' as const },
|
|
{ name: 'mcp-builder', source: 'agents' as const },
|
|
{ name: 'pdf', source: 'agents' as const },
|
|
{ name: 'playwright', source: 'agents' as const },
|
|
{ name: 'pptx', source: 'agents' as const },
|
|
{ name: 'product-requirements', source: 'agents' as const },
|
|
{ name: 'prototype-prompt-generator', source: 'agents' as const },
|
|
{ name: 'receiving-code-review', source: 'agents' as const },
|
|
{ name: 'requesting-code-review', source: 'agents' as const },
|
|
{ name: 'skill-creation-guide', source: 'agents' as const },
|
|
{ name: 'skill-creator', source: 'agents' as const },
|
|
{ name: 'slack-gif-creator', source: 'agents' as const },
|
|
{ name: 'subagent-driven-development', source: 'agents' as const },
|
|
{ name: 'systematic-debugging', source: 'agents' as const },
|
|
{ name: 'template-skill', source: 'agents' as const },
|
|
{ name: 'test', source: 'agents' as const },
|
|
{ name: 'test-driven-development', source: 'agents' as const },
|
|
{ name: 'theme-factory', source: 'agents' as const },
|
|
{ name: 'ui-design-system', source: 'agents' as const },
|
|
{ name: 'ui-ux-pro-max', source: 'agents' as const },
|
|
{ name: 'using-git-worktrees', source: 'agents' as const },
|
|
{ name: 'using-superpowers', source: 'agents' as const },
|
|
{ name: 'ux-researcher-designer', source: 'agents' as const },
|
|
{ name: 'verification-before-completion', source: 'agents' as const },
|
|
{ name: 'verify', source: 'agents' as const },
|
|
{ name: 'web-artifacts-builder', source: 'agents' as const },
|
|
{ name: 'web-design-guidelines', source: 'agents' as const },
|
|
{ name: 'webapp-testing', source: 'agents' as const },
|
|
{ name: 'writing-plans', source: 'agents' as const },
|
|
{ name: 'writing-skills', source: 'agents' as const },
|
|
{ name: 'xlsx', source: 'agents' as const },
|
|
{ name: 'nodejs-backend-patterns', source: 'opencode' as const },
|
|
{ name: 'planning-with-files', source: 'opencode' as const },
|
|
];
|
|
|
|
const descriptions: Record<string, string> = {
|
|
'agent-development':
|
|
'Agent 开发技能,用于创建和管理 Claude Code 插件 agent',
|
|
'algorithmic-art': '使用 p5.js 创建算法艺术,支持生成艺术、流场和粒子系统',
|
|
brainstorming: '头脑风暴技能,在进行创造性工作前探索用户意图和需求',
|
|
'brand-guidelines': '应用 Anthropic 官方品牌颜色和字体设计规范',
|
|
'canvas-design': '使用设计哲学创建漂亮的视觉艺术作品',
|
|
'command-creator': '创建 Claude Code 斜杠命令的技能',
|
|
'command-development': '开发斜杠命令的完整指南',
|
|
context7: '通过 Context7 API 获取最新的库/框架文档',
|
|
'context7-auto-research': '自动获取 Claude Code 最新文档',
|
|
'dispatching-parallel-agents': '并行代理调度技能,处理独立任务',
|
|
'doc-coauthoring': '协作撰写文档的工作流程指南',
|
|
docx: 'Word 文档创建、编辑和分析工具包',
|
|
'executing-plans': '执行实现计划的技能',
|
|
'extract-errors': '提取和处理 React 错误消息',
|
|
'feature-flags': '功能开关管理技能',
|
|
figma: 'Figma MCP 服务器集成',
|
|
'figma-implement-design': '将 Figma 设计转换为生产代码',
|
|
'find-skills': '发现和安装 agent skills',
|
|
'finishing-a-development-branch': '完成开发分支的集成指导',
|
|
fix: '修复 lint 错误和格式化问题',
|
|
flags: '检查功能开关状态',
|
|
flow: 'Flow 类型检查技能',
|
|
'frontend-design': '创建生产级前端界面',
|
|
'internal-comms': '内部通信文档撰写',
|
|
'mcp-builder': 'MCP 服务器创建指南',
|
|
pdf: 'PDF 文档处理工具包',
|
|
playwright: '浏览器自动化测试工具',
|
|
pptx: '演示文稿创建和编辑工具',
|
|
'product-requirements': '产品需求文档生成',
|
|
'prototype-prompt-generator': 'UI/UX 原型提示生成器',
|
|
'receiving-code-review': '接收代码审查反馈',
|
|
'requesting-code-review': '请求代码审查',
|
|
'skill-creation-guide': '创建 skills 的完整指南',
|
|
'skill-creator': 'Skill 创建技能',
|
|
'slack-gif-creator': '创建 Slack 优化 GIF',
|
|
'subagent-driven-development': '子代理驱动开发',
|
|
'systematic-debugging': '系统化调试方法',
|
|
'template-skill': 'Skill 模板',
|
|
test: 'React 测试运行工具',
|
|
'test-driven-development': '测试驱动开发',
|
|
'theme-factory': '主题样式工具包',
|
|
'ui-design-system': 'UI 设计系统工具包',
|
|
'ui-ux-pro-max': 'UI/UX 设计智能工具',
|
|
'using-git-worktrees': 'Git worktree 隔离开发',
|
|
'using-superpowers': '使用技能系统',
|
|
'ux-researcher-designer': 'UX 研究和设计工具包',
|
|
'verification-before-completion': '完成前验证',
|
|
verify: '提交前验证检查',
|
|
'web-artifacts-builder': 'Web HTML artifacts 构建套件',
|
|
'web-design-guidelines': 'Web 界面指南合规性审查',
|
|
'webapp-testing': 'Web 应用测试工具包',
|
|
'writing-plans': '编写计划文档',
|
|
'writing-skills': '技能编写和验证',
|
|
xlsx: '电子表格创建和分析工具包',
|
|
'nodejs-backend-patterns': 'Node.js 后端服务开发模式',
|
|
'planning-with-files': '基于文件的复杂任务规划',
|
|
};
|
|
|
|
return skillsData.map((item, index) => ({
|
|
id: `skill_${index + 1}`,
|
|
name: item.name,
|
|
description: descriptions[item.name] || `${item.name} skill`,
|
|
path:
|
|
item.source === 'agents'
|
|
? `~/.agents/skills/${item.name}`
|
|
: `~/.config/opencode/skills/${item.name}`,
|
|
source: item.source,
|
|
type: getSkillType(item.name),
|
|
isEnabled: true,
|
|
fileCount: Math.floor(Math.random() * 10) + 1,
|
|
lastModified:
|
|
Date.now() - Math.floor(Math.random() * 30 * 24 * 60 * 60 * 1000),
|
|
}));
|
|
}
|
|
|
|
const mockSkills = getMockSkills();
|
|
|
|
export default {
|
|
'GET /api/skills': (req: any) => {
|
|
const { type, keyword, current = 1, pageSize = 10 } = req.query;
|
|
|
|
let filteredSkills = [...mockSkills];
|
|
|
|
// 按类型筛选
|
|
if (type && type !== 'all') {
|
|
filteredSkills = filteredSkills.filter((skill) => skill.type === type);
|
|
}
|
|
|
|
// 按关键词搜索
|
|
if (keyword) {
|
|
const kw = keyword.toLowerCase();
|
|
filteredSkills = filteredSkills.filter(
|
|
(skill) =>
|
|
skill.name.toLowerCase().includes(kw) ||
|
|
skill.description.toLowerCase().includes(kw),
|
|
);
|
|
}
|
|
|
|
const total = filteredSkills.length;
|
|
const start = (current - 1) * pageSize;
|
|
const data = filteredSkills.slice(start, start + pageSize);
|
|
|
|
return {
|
|
data,
|
|
total,
|
|
success: true,
|
|
};
|
|
},
|
|
|
|
'GET /api/skills/:id': (req: any) => {
|
|
const { id } = req.params;
|
|
const skill = mockSkills.find((s) => s.id === id);
|
|
|
|
if (!skill) {
|
|
return {
|
|
success: false,
|
|
errorMessage: 'Skill not found',
|
|
};
|
|
}
|
|
|
|
return {
|
|
data: {
|
|
...skill,
|
|
tags: [skill.type, skill.source],
|
|
content: `# ${skill.name}\n\n${skill.description}`,
|
|
},
|
|
success: true,
|
|
};
|
|
},
|
|
|
|
'POST /api/skills/:id/status': (req: any) => {
|
|
const { id } = req.params;
|
|
const { isEnabled } = req.body;
|
|
|
|
const skill = mockSkills.find((s) => s.id === id);
|
|
if (skill) {
|
|
skill.isEnabled = isEnabled;
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
};
|
|
},
|
|
};
|