feat: 新增技能编排引擎和工作流构建器组件
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

refactor: 统一Hands系统常量到单个源文件
refactor: 更新Hands中文名称和描述

fix: 修复技能市场在连接状态变化时重新加载
fix: 修复身份变更提案的错误处理逻辑

docs: 更新多个功能文档的验证状态和实现位置
docs: 更新Hands系统文档

test: 添加测试文件验证工作区路径
This commit is contained in:
iven
2026-03-25 08:27:25 +08:00
parent 9c781f5f2a
commit aa6a9cbd84
110 changed files with 12384 additions and 1337 deletions

View File

@@ -6,7 +6,7 @@
* - Recommend skills based on recent conversation patterns
* - Manage skill installation lifecycle (with user approval)
*
* Scans the local `skills/` directory for SKILL.md manifests and indexes them.
* Dynamically loads skills from the backend Kernel's SkillRegistry.
*
* Reference: ZCLAW_AGENT_INTELLIGENCE_EVOLUTION.md §6.5.2
*/
@@ -26,6 +26,20 @@ export interface SkillInfo {
installed: boolean;
category?: string;
path?: string;
version?: string;
mode?: string;
}
/** Backend skill response format */
interface BackendSkillInfo {
id: string;
name: string;
description: string;
version: string;
capabilities: string[];
tags: string[];
mode: string;
enabled: boolean;
}
export interface SkillSuggestion {
@@ -51,151 +65,89 @@ export interface ConversationContext {
const SKILL_INDEX_KEY = 'zclaw-skill-index';
const SKILL_SUGGESTIONS_KEY = 'zclaw-skill-suggestions';
// === Built-in Skill Registry ===
/**
* Pre-indexed skills from the skills/ directory.
* In production, this would be dynamically scanned from SKILL.md files.
* For Phase 4, we maintain a static registry that can be refreshed.
*/
const BUILT_IN_SKILLS: SkillInfo[] = [
{
id: 'code-review',
name: 'Code Review',
description: '审查代码、分析代码质量、提供改进建议',
triggers: ['审查代码', '代码审查', 'code review', 'PR review', '检查代码'],
capabilities: ['代码质量分析', '架构评估', '安全审计', '最佳实践检查'],
toolDeps: ['read', 'grep', 'glob'],
installed: true,
category: 'development',
},
{
id: 'frontend-developer',
name: 'Frontend Developer',
description: '前端开发专家,擅长 React/Vue/CSS/TypeScript',
triggers: ['前端开发', '页面开发', 'UI开发', 'React', 'Vue', 'CSS'],
capabilities: ['组件开发', '样式调整', '性能优化', '响应式设计'],
toolDeps: ['read', 'write', 'shell'],
installed: true,
category: 'development',
},
{
id: 'backend-architect',
name: 'Backend Architect',
description: '后端架构设计、API设计、数据库建模',
triggers: ['后端架构', 'API设计', '数据库设计', '系统架构', '微服务'],
capabilities: ['架构设计', 'API规范', '数据库建模', '性能优化'],
toolDeps: ['read', 'write', 'shell'],
installed: true,
category: 'development',
},
{
id: 'security-engineer',
name: 'Security Engineer',
description: '安全工程师,负责安全审计、漏洞检测、合规检查',
triggers: ['安全审计', '漏洞检测', '安全检查', 'security', '渗透测试'],
capabilities: ['漏洞扫描', '合规检查', '安全加固', '威胁建模'],
toolDeps: ['read', 'grep', 'shell'],
installed: true,
category: 'security',
},
{
id: 'data-analysis',
name: 'Data Analysis',
description: '数据分析、可视化、报告生成',
triggers: ['数据分析', '数据可视化', '报表', '统计', 'analytics'],
capabilities: ['数据清洗', '统计分析', '可视化图表', '报告生成'],
toolDeps: ['read', 'write', 'shell'],
installed: true,
category: 'analytics',
},
{
id: 'chinese-writing',
name: 'Chinese Writing',
description: '中文写作、文案创作、内容优化',
triggers: ['写文章', '文案', '写作', '中文创作', '内容优化'],
capabilities: ['文案创作', '文章润色', '标题优化', 'SEO写作'],
toolDeps: ['read', 'write'],
installed: true,
category: 'content',
},
{
id: 'devops-automator',
name: 'DevOps Automator',
description: 'CI/CD、Docker、K8s、自动化部署',
triggers: ['DevOps', 'CI/CD', 'Docker', '部署', '自动化', 'K8s'],
capabilities: ['CI/CD配置', '容器化', '自动化部署', '监控告警'],
toolDeps: ['shell', 'read', 'write'],
installed: true,
category: 'ops',
},
{
id: 'senior-pm',
name: 'Senior PM',
description: '项目管理、需求分析、迭代规划',
triggers: ['项目管理', '需求分析', '迭代规划', '产品设计', 'PRD'],
capabilities: ['需求拆解', '迭代排期', '风险评估', '文档撰写'],
toolDeps: ['read', 'write'],
installed: true,
category: 'management',
},
{
id: 'git',
name: 'Git Operations',
description: 'Git 版本控制操作、分支管理、冲突解决',
triggers: ['git', '版本控制', '分支', '合并', 'commit', 'merge'],
capabilities: ['分支管理', '冲突解决', 'rebase', 'cherry-pick'],
toolDeps: ['shell'],
installed: true,
category: 'development',
},
{
id: 'api-tester',
name: 'API Tester',
description: 'API 测试、接口调试、自动化测试脚本',
triggers: ['API测试', '接口测试', '接口调试', 'Postman', 'curl'],
capabilities: ['接口调试', '自动化测试', '性能测试', '断言验证'],
toolDeps: ['shell', 'read', 'write'],
installed: true,
category: 'testing',
},
{
id: 'finance-tracker',
name: 'Finance Tracker',
description: '财务追踪、预算管理、报表分析',
triggers: ['财务', '预算', '记账', '报销', '财务报表'],
capabilities: ['收支分析', '预算规划', '报表生成', '趋势预测'],
toolDeps: ['read', 'write'],
installed: true,
category: 'business',
},
{
id: 'social-media-strategist',
name: 'Social Media Strategist',
description: '社交媒体运营策略、内容规划、数据分析',
triggers: ['社交媒体', '运营', '小红书', '抖音', '微博', '内容运营'],
capabilities: ['内容策划', '发布排期', '数据分析', '竞品监控'],
toolDeps: ['read', 'write'],
installed: true,
category: 'marketing',
},
];
// === Skill Discovery Engine ===
export class SkillDiscoveryEngine {
private skills: SkillInfo[] = [];
private suggestionHistory: SkillSuggestion[] = [];
private loadedFromBackend: boolean = false;
constructor() {
this.loadIndex();
this.loadSuggestions();
if (this.skills.length === 0) {
this.skills = [...BUILT_IN_SKILLS];
// Try to load from backend, fallback to cache
this.loadFromBackend();
}
/**
* Load skills from backend Tauri command.
* Falls back to cached skills if backend is unavailable.
*/
private async loadFromBackend(): Promise<void> {
try {
// Dynamic import to avoid bundling issues in non-Tauri environments
const { invoke } = await import('@tauri-apps/api/core');
const backendSkills = await invoke<BackendSkillInfo[]>('skill_list');
// Convert backend format to frontend format
this.skills = backendSkills.map(this.convertFromBackend);
this.loadedFromBackend = true;
this.saveIndex();
console.log(`[SkillDiscovery] Loaded ${this.skills.length} skills from backend`);
} catch (error) {
console.warn('[SkillDiscovery] Failed to load skills from backend:', error);
// Keep using cached skills (loaded in loadIndex)
this.loadedFromBackend = false;
}
}
/**
* Convert backend skill format to frontend format.
*/
private convertFromBackend(backend: BackendSkillInfo): SkillInfo {
return {
id: backend.id,
name: backend.name,
description: backend.description,
version: backend.version,
triggers: backend.tags, // Use tags as triggers
capabilities: backend.capabilities,
mode: backend.mode,
toolDeps: [], // Backend doesn't have this field
installed: backend.enabled,
category: backend.tags[0] || 'general',
};
}
/**
* Refresh skills from backend.
* Optionally specify a custom directory to scan.
*/
async refresh(skillDir?: string): Promise<number> {
try {
const { invoke } = await import('@tauri-apps/api/core');
const backendSkills = await invoke<BackendSkillInfo[]>('skill_refresh', {
skillDir
});
this.skills = backendSkills.map(this.convertFromBackend);
this.loadedFromBackend = true;
this.saveIndex();
console.log(`[SkillDiscovery] Refreshed ${this.skills.length} skills`);
return this.skills.length;
} catch (error) {
console.error('[SkillDiscovery] Failed to refresh skills:', error);
throw error;
}
}
/**
* Check if skills were loaded from backend.
*/
isLoadedFromBackend(): boolean {
return this.loadedFromBackend;
}
// === Search ===
/**