feat: bundle desktop skills

This commit is contained in:
boos
2026-06-26 14:28:13 +08:00
parent 424aaa9b1f
commit cd08ac931d
18 changed files with 719 additions and 17 deletions
+66 -5
View File
@@ -33,6 +33,57 @@ function generateBrowserResponse(userContent: string): string {
return `收到你的消息:「${userContent.length > 50 ? userContent.slice(0, 50) + '...' : userContent}」\n\n当前为浏览器预览模式,无法调用真实 AI 接口。此模式用于 UI 开发和体验测试。\n\n如需 AI 回复,请使用 \`cargo tauri dev\` 启动完整应用。`;
}
const BUILT_IN_SKILLS = [
{
name: 'jianying-editor',
description: '剪映 AI 自动化剪辑 Skill,支持草稿生成、素材导入、字幕、配音、特效和导出。',
repo: 'luoluoluo22/jianying-editor-skill',
},
{
name: 'seedance',
description: '中文 Seedance 2.0 / 即梦视频与图片提示词工程,支持 @素材引用、分镜、运镜和长视频流水线。',
repo: 'MapleShaw/seedance2.0-prompt-skill',
},
{
name: 'seedance-prompt-en',
description: 'English Seedance 2.0 multimodal AI video prompt writing guide.',
repo: 'dexhunter/seedance2-skill',
},
{
name: 'dwg-mcp-server',
description: 'DWG MCP Server 包装技能:指导 Agent 安装并使用 dwg-mcp 检查 AutoCAD DWG 文件。',
repo: 'dimitrovakulenko/dwg-mcp-server',
},
{
name: 'cad-ai-agent',
description: 'CAD/DXF Agent 包装技能:用于图纸摘要、合规检查、工程量统计、RFI 和安全编辑流程。',
repo: 'jeremylongshore/cad-ai-agent',
},
{
name: 'gorden-ppt-skill',
description: '中文 PPT 生成与编辑 Skill,支持模板套用、版式保持、出框检测和 PowerPoint 成品导出。',
repo: 'GordenSun/GordenPPTSkill',
},
];
function builtInSkillRows() {
return BUILT_IN_SKILLS.map(skill => ({
name: skill.name,
description: skill.description,
source: 'boosapi',
sourcePath: `/mock/skills/${skill.name}/SKILL.md`,
enabled: true,
hasUpdate: false,
userInvocable: true,
}));
}
function mergeBuiltInSkills(skills: any[]) {
const existingNames = new Set(skills.map((skill: any) => skill.name));
const missing = builtInSkillRows().filter(skill => !existingNames.has(skill.name));
return [...missing, ...skills];
}
// ── Built-in Providers ──────────────────────────────────────────────────
const OPENAI_REASONING_OVERRIDES = {
@@ -1584,7 +1635,7 @@ export async function handleCommand<T>(cmd: string, args?: Record<string, unknow
// ── Skills ────────────────────────────────────────────────────────
case 'list_skills':
return getStore<any[]>('skills', []) as T;
return mergeBuiltInSkills(getStore<any[]>('skills', [])) as T;
case 'get_skill':
return {
@@ -1613,13 +1664,16 @@ export async function handleCommand<T>(cmd: string, args?: Record<string, unknow
case 'install_skill': {
const source = (args as any)?.source || 'installed-skill';
const name = source.includes('jianying-editor-skill') ? 'jianying-editor' : String(source).split('/').pop();
const known = BUILT_IN_SKILLS.find(skill => (
skill.repo.toLowerCase() === String(source).replace(/^https:\/\/github\.com\//, '').replace(/\.git$/, '').toLowerCase()
));
const name = known?.name || (source.includes('jianying-editor-skill') ? 'jianying-editor' : String(source).split('/').pop());
const skills = getStore<any[]>('skills', []);
const nextSkill = {
name,
description: name === 'jianying-editor'
description: known?.description || (name === 'jianying-editor'
? '剪映 AI 自动化剪辑 Skill,支持草稿生成、素材导入、字幕、配音、特效和导出。'
: 'Installed skill',
: 'Installed skill'),
source: 'boosapi',
sourcePath: `/mock/skills/${name}`,
enabled: true,
@@ -1646,7 +1700,14 @@ export async function handleCommand<T>(cmd: string, args?: Record<string, unknow
return undefined as T;
case 'search_marketplace':
return [] as T;
return BUILT_IN_SKILLS.map(skill => ({
name: skill.name,
description: skill.description,
repo: skill.repo,
stars: 0,
installs: 0,
installed: mergeBuiltInSkills(getStore<any[]>('skills', [])).some((row: any) => row.name === skill.name),
})) as T;
case 'check_skill_updates':
return [] as T;
+51 -2
View File
@@ -28,7 +28,56 @@ const openExternalUrl = (url: string) => {
const { Text, Paragraph } = Typography;
const BUILTIN_MARKETPLACE_DETAILS: Record<string, string> = {
'dimitrovakulenko/dwg-mcp-server': `# DWG MCP Server Skill
Use this skill when a user wants to inspect AutoCAD DWG drawings with an AI agent.
Upstream project: https://github.com/dimitrovakulenko/dwg-mcp-server
## Setup
\`\`\`bash
npx -y @dmytro-prototypes/dwg-mcp-server
\`\`\`
For clients without MCP roots:
\`\`\`bash
DWG_MCP_ALLOWED_ROOTS="$HOME" npx -y @dmytro-prototypes/dwg-mcp-server
\`\`\`
## Workflow
1. Ask for the DWG file path and confirm it is under an allowed root.
2. Use \`dwg.list_roots\`, \`dwg.open_file\`, \`dwg.list_file_types\`, \`dwg.describe_type\`, \`dwg.get_objects\`, and \`dwg.query_objects\`.
3. Summarize entities, layers, blocks, layouts, references, and notable properties.
4. Close the document with \`dwg.close_file\`.
`,
'jeremylongshore/cad-ai-agent': `# CAD AI Agent Skill
Use this skill for CAD/DXF drawing summaries, compliance checks, quantity takeoffs, RFIs, health reports, revision comparison, and safe edit planning.
Upstream project: https://github.com/jeremylongshore/cad-ai-agent
## Setup
\`\`\`bash
git clone https://github.com/jeremylongshore/cad-ai-agent.git
cd cad-ai-agent
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
\`\`\`
## Workflow
1. Identify drawing format and user intent.
2. Preserve originals and prefer save-as outputs.
3. For edits, produce structured operation plans rather than touching raw CAD data directly.
4. For analysis, return layer/entity summaries, issues, measurements, and concrete next actions.
`,
};
const SOURCE_ICONS: Record<string, React.ReactNode> = {
boosapi: <img src={appLogo} alt="" style={{ width: 14, height: 14, verticalAlign: 'middle' }} />,
@@ -299,10 +348,10 @@ export function SkillsPage() {
setMarketplaceDetailContent({ name: skill.name, repo: skill.repo, content: '' });
try {
const res = await fetch(`https://raw.githubusercontent.com/${repo}/main/SKILL.md`);
const content = res.ok ? await res.text() : '(SKILL.md not found)';
const content = res.ok ? await res.text() : (BUILTIN_MARKETPLACE_DETAILS[repo] || '(SKILL.md not found)');
setMarketplaceDetailContent({ name: skill.name, repo: skill.repo, content });
} catch {
setMarketplaceDetailContent({ name: skill.name, repo: skill.repo, content: '(Failed to fetch SKILL.md)' });
setMarketplaceDetailContent({ name: skill.name, repo: skill.repo, content: BUILTIN_MARKETPLACE_DETAILS[repo] || '(Failed to fetch SKILL.md)' });
} finally {
setMarketplaceDetailLoading(false);
}