docs(spec): add automation system redesign specification

Design for Hands/Workflow unified automation panel with:
- Visual scheduler without cron syntax
- Result stream integration into chat
- Batch operations (trigger, approve, configure)
- Real-time status via WebSocket
- Offline queue and error recovery

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-03-18 15:10:55 +08:00
parent e262200f1e
commit 552efb513b

View File

@@ -0,0 +1,456 @@
# ZCLAW 自动化系统重设计方案
> **状态**: 待审核
> **作者**: Claude
> **日期**: 2026-03-18
> **版本**: 1.0
---
## 一、背景与目标
### 1.1 当前问题
| 问题 | 影响 | 严重程度 |
|------|------|---------|
| HandsPanel 使用 gatewayStore 而非 handStore | 状态管理混乱,新 store 未被使用 | 高 |
| HandParamsForm 参数未传递给 triggerHand | 用户填写的参数被丢弃 | 致命 |
| 缺少 WebSocket 实时状态更新 | 无法看到执行进度 | 高 |
| 无执行结果展示 | 用户不知道 Hand 执行结果 | 高 |
| 无执行历史查看 | 无法追溯过去的执行 | 中 |
| Hands 与 Workflows 分离 | 用户体验割裂 | 中 |
### 1.2 设计目标
基于用户需求确认:
1. **专业版功能** - 完整重构 + 工作流集成 + 批量操作 + 调度管理
2. **可视化调度器** - 图形化界面选择时间/频率,无需了解 cron 语法
3. **结果流展示** - Hand 输出作为对话消息显示在聊天区域
4. **批量操作** - 支持批量触发、批量审批、批量配置
5. **统一视图** - Hands 和 Workflows 合并到一个"自动化"视图,按任务类型分类
---
## 二、架构设计
### 2.1 整体架构
```
┌─────────────────────────────────────────────────────────────┐
│ UI Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │AutomationPanel│ │ScheduleEditor│ │ExecutionResultStream│ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ State Management │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ automationStore.ts │ │
│ │ - hands: Hand[] │ │
│ │ - workflows: Workflow[] │ │
│ │ - runs: Run[] │ │
│ │ - schedules: Schedule[] │ │
│ │ - approvals: Approval[] │ │
│ │ - selectedIds: Set<string> │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Data Layer │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ gateway-client.ts │ │
│ │ - listHands() / listWorkflows() │ │
│ │ - triggerHand() / executeWorkflow() │ │
│ │ - createSchedule() / updateSchedule() │ │
│ │ - WebSocket 事件监听 │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### 2.2 数据流
```
用户操作 → AutomationPanel → automationStore → gateway-client → OpenFang API
├── 更新 UI 状态
├── WebSocket 事件 → 更新执行状态
└── 执行完成 → 注入结果到 chatStore
```
### 2.3 文件结构
```
desktop/src/
├── components/
│ ├── Automation/ # 新建目录
│ │ ├── AutomationPanel.tsx # 统一入口
│ │ ├── AutomationCard.tsx # Hand/Workflow 卡片
│ │ ├── AutomationFilters.tsx # 分类筛选
│ │ ├── ScheduleEditor.tsx # 可视化调度器
│ │ ├── ExecutionResult.tsx # 结果展示组件
│ │ ├── BatchActionBar.tsx # 批量操作栏
│ │ └── ApprovalQueue.tsx # 审批队列
│ └── HandsPanel.tsx # 重构为 AutomationPanel 入口
├── store/
│ ├── automationStore.ts # 新建:统一状态管理
│ └── handStore.ts # 保留:逐步迁移
├── types/
│ └── automation.ts # 新建:统一类型定义
└── hooks/
└── useAutomationEvents.ts # 新建WebSocket 事件 Hook
```
---
## 三、核心组件设计
### 3.1 AutomationPanel统一入口
```typescript
interface AutomationPanelProps {
initialCategory?: CategoryType;
onSelect?: (item: AutomationItem) => void;
}
interface AutomationPanelState {
items: AutomationItem[]; // Hands + Workflows 合并
categories: CategoryStats; // 各分类统计
filters: FilterState; // 当前筛选条件
selectedIds: string[]; // 批量选择
viewMode: 'grid' | 'list'; // 视图模式
}
type CategoryType = 'all' | 'research' | 'data' | 'automation' | 'communication';
```
**UI 布局**:
```
┌─────────────────────────────────────────────────────────────┐
│ 自动化 [新建] [调度] │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 全部 │ │ 研究 │ │ 数据 │ │ 自动化 │ ... │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────────────────────────┤
│ [AutomationCard] [AutomationCard] [AutomationCard] │
│ [AutomationCard] [AutomationCard] [AutomationCard] │
└─────────────────────────────────────────────────────────────┘
```
### 3.2 AutomationCard统一卡片
```typescript
interface AutomationCardProps {
item: AutomationItem;
status: ExecutionStatus;
result?: ExecutionResult;
onSelect: (selected: boolean) => void;
onExecute: (params?: Record<string, unknown>) => void;
onSchedule: () => void;
}
interface AutomationItem {
id: string;
name: string;
description: string;
type: 'hand' | 'workflow';
category: CategoryType;
status: ItemStatus;
parameters: Parameter[];
lastRun?: RunInfo;
schedule?: ScheduleInfo;
requiresApproval: boolean;
}
```
### 3.3 ScheduleEditor可视化调度器
```typescript
interface ScheduleEditorProps {
schedule?: ScheduleInfo;
onSave: (schedule: ScheduleInfo) => void;
onCancel: () => void;
}
interface ScheduleInfo {
enabled: boolean;
frequency: 'once' | 'daily' | 'weekly' | 'monthly' | 'custom';
time: { hour: number; minute: number };
daysOfWeek?: number[]; // 0-6 for weekly
dayOfMonth?: number; // 1-31 for monthly
customCron?: string; // 高级模式可选
timezone: string;
endDate?: Date;
}
```
**UI 设计**:
```
┌─────────────────────────────────────────────────────────────┐
│ 调度设置 [保存] │
├─────────────────────────────────────────────────────────────┤
│ 频率: ○ 一次 ● 每天 ○ 每周 ○ 每月 ○ 自定义 │
│ 时间: [09] : [00] 时区: [Asia/Shanghai ▼] │
│ ┌─ 每周重复 (选中"每周"时显示) ───────────────────────┐ │
│ │ [一] [二] [三] [四] [五] [六] [日] │ │
│ └───────────────────────────────────────────────────────┘ │
│ 结束日期: [无结束日期 ▼] 或 选择日期: [____-__-__] │
│ 预览: "每天 09:00 (Asia/Shanghai),无结束日期" │
└─────────────────────────────────────────────────────────────┘
```
---
## 四、结果流设计
### 4.1 消息类型扩展
```typescript
interface ChatMessage {
id: string;
role: 'user' | 'assistant' | 'system' | 'hand' | 'workflow'; // 新增
content: string;
timestamp: number;
executionInfo?: {
type: 'hand' | 'workflow';
name: string;
runId: string;
status: 'running' | 'completed' | 'failed' | 'needs_approval';
duration?: number;
output?: unknown;
error?: string;
};
}
```
### 4.2 结果消息渲染
```
┌─────────────────────────────────────────────────────────────┐
│ 🔍 Researcher │
│ ─────────────────────────────────────────────────────── │
│ 状态: ✅ 完成 耗时: 2m 34s │
│ │
│ ## 研究结果摘要 │
│ ... │
│ │
│ [查看完整报告] [下载 PDF] [重新执行] │
└─────────────────────────────────────────────────────────────┘
```
---
## 五、批量操作设计
### 5.1 批量操作接口
```typescript
interface BatchOperations {
selectedIds: Set<string>;
executeSelected: (params?: Record<string, unknown>) => Promise<void>;
approveSelected: () => Promise<void>;
rejectSelected: (reason: string) => Promise<void>;
updateConfigSelected: (config: Partial<Config>) => Promise<void>;
scheduleSelected: (schedule: ScheduleInfo) => Promise<void>;
}
```
### 5.2 批量操作栏 UI
```
┌─────────────────────────────────────────────────────────────┐
│ 已选择 3 项 [取消选择] │
├─────────────────────────────────────────────────────────────┤
│ [▶ 执行选中] [✓ 批量审批] [✗ 批量拒绝] [⏰ 批量调度] │
└─────────────────────────────────────────────────────────────┘
```
### 5.3 批量审批队列
```
┌─────────────────────────────────────────────────────────────┐
│ 审批队列 (5 待处理) [全部批准] [全部拒绝] │
├─────────────────────────────────────────────────────────────┤
│ ☐ Browser - 访问 github.com/search │
│ 请求者: Agent-1 | 请求时间: 2分钟前 │
│ ☐ Lead - 搜索 LinkedIn 销售线索 │
│ 请求者: Agent-2 | 请求时间: 5分钟前 │
└─────────────────────────────────────────────────────────────┘
```
---
## 六、实时状态与错误处理
### 6.1 状态流转
```
┌─────────┐ trigger ┌─────────┐ execute ┌───────────┐
│ idle │ ──────────► │ pending │ ──────────► │ running │
└─────────┘ └─────────┘ └───────────┘
▲ │
│ ┌──────────────┐ │
└──────────────│ completed │◄───────────────────┘
└──────────────┘
┌──────────────┐
│ failed │
└──────────────┘
┌──────────────┐
│needs_approval│ ──approve──► running
└──────────────┘
```
### 6.2 WebSocket 事件处理
```typescript
interface AutomationWebSocketHandlers {
onHandStatus: (data: { name: string; status: string; runId?: string }) => void;
onHandResult: (data: { name: string; runId: string; result: unknown }) => void;
onWorkflowStep: (data: { id: string; step: number; status: string }) => void;
onWorkflowComplete: (data: { id: string; result: unknown }) => void;
onApprovalRequest: (data: ApprovalRequest) => void;
onApprovalResolved: (data: { id: string; approved: boolean }) => void;
}
```
### 6.3 错误处理
```typescript
type ErrorCode =
| 'CONNECTION_LOST'
| 'HAND_UNAVAILABLE'
| 'PARAM_INVALID'
| 'PERMISSION_DENIED'
| 'RATE_LIMITED'
| 'TIMEOUT'
| 'APPROVAL_REQUIRED'
| 'APPROVAL_REJECTED'
| 'EXECUTION_FAILED';
interface AutomationError {
code: ErrorCode;
message: string;
recoverable: boolean;
suggestedAction?: string;
}
```
### 6.4 离线队列
```typescript
interface ConnectionState {
status: 'connected' | 'disconnected' | 'reconnecting';
pendingActions: PendingAction[];
}
// 离线时缓存操作,重连后批量执行
```
---
## 七、实现计划
### 7.1 分阶段实施
| 阶段 | 任务 | 交付物 | 预计时间 |
|------|------|--------|---------|
| **Phase 1** | 基础修复 | 可用的 Hands 系统 | 1-2 天 |
| **Phase 2** | UI 重构 | 统一自动化面板 | 2-3 天 |
| **Phase 3** | 高级功能 | 调度与批量操作 | 2-3 天 |
| **Phase 4** | 工作流集成 | 完整自动化系统 | 2-3 天 |
### 7.2 文件变更清单
**新建文件**:
- `desktop/src/components/Automation/` 目录7 个组件)
- `desktop/src/store/automationStore.ts`
- `desktop/src/types/automation.ts`
- `desktop/src/hooks/useAutomationEvents.ts`
- `tests/desktop/automation/` 测试目录
**修改文件**:
- `desktop/src/components/HandsPanel.tsx` - 重构为入口
- `desktop/src/store/handStore.ts` - 合并到 automationStore
- `desktop/src/lib/gateway-client.ts` - 增强 WebSocket 事件
- `desktop/src/store/chatStore.ts` - 支持 hand/workflow 消息类型
- `desktop/src/components/ChatArea.tsx` - 渲染结果流消息
- `desktop/src/components/Sidebar.tsx` - 导航更新
---
## 八、测试策略
### 8.1 测试覆盖
| 测试类型 | 覆盖范围 | 工具 |
|---------|---------|------|
| 单元测试 | Store 逻辑、工具函数、组件 | Vitest |
| 集成测试 | API 调用、WebSocket 事件 | Vitest + MSW |
| E2E 测试 | 完整用户流程 | Playwright |
### 8.2 关键测试用例
1. 参数从表单正确传递到 API
2. WebSocket 事件正确更新 UI 状态
3. 批量选择和操作功能
4. 调度器生成正确的 cron 表达式
5. 结果流消息正确注入聊天
6. 离线队列在重连后执行
7. 错误状态正确显示和恢复
---
## 九、验收标准
| 功能 | 验收标准 |
|------|---------|
| Hand 执行 | 填写参数 → 执行 → 看到实时进度 → 结果显示在聊天流 |
| 批量操作 | 选择 3 个 Hand → 批量执行 → 全部成功 |
| 调度 | 设置"每天 9:00" → 保存 → 在调度列表看到正确预览 |
| 审批 | Hand 需要审批 → 弹出审批请求 → 批准 → 继续执行 |
| 离线 | 断网 → 触发 Hand → 重连 → 自动执行 |
---
## 十、风险评估
| 风险 | 可能性 | 影响 | 缓解措施 |
|------|--------|------|---------|
| 后端 API 不完整 | 中 | 高 | 使用 fallback 数据,明确标注未实现 |
| WebSocket 不稳定 | 低 | 高 | 心跳机制 + 自动重连 + 离线队列 |
| 迁移影响现有功能 | 中 | 中 | 分阶段迁移,保留旧组件作为 fallback |
| 调度器复杂度 | 低 | 中 | 先实现基础频率,高级功能后续迭代 |
---
## 附录 AAPI 端点参考
| 端点 | 方法 | 用途 |
|------|------|------|
| `/api/hands` | GET | 列出所有 Hands |
| `/api/hands/{name}` | GET | 获取 Hand 详情 |
| `/api/hands/{name}/activate` | POST | 触发 Hand 执行 |
| `/api/hands/{name}/runs/{runId}` | GET | 获取执行状态 |
| `/api/hands/{name}/runs/{runId}/approve` | POST | 批准执行 |
| `/api/hands/{name}/runs/{runId}/cancel` | POST | 取消执行 |
| `/api/hands/{name}/runs` | GET | 列出执行历史 |
| `/api/workflows` | GET/POST | 工作流管理 |
| `/api/triggers` | GET/POST/PUT/DELETE | 触发器管理 |
---
## 附录 BWebSocket 事件参考
| 事件类型 | 字段 | 说明 |
|---------|------|------|
| `hand` | hand_name, hand_status, hand_result | Hand 状态变更 |
| `workflow` | workflow_id, step, status | Workflow 步骤变更 |
| `approval` | approval_id, type, status | 审批请求/响应 |