Files
agent/mock/skill.ts
2026-02-16 12:46:37 +08:00

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,
};
},
};