feat(hands): restructure Hands UI with Chinese localization

Major changes:
- Add HandList.tsx component for left sidebar
- Add HandTaskPanel.tsx for middle content area
- Restructure Sidebar tabs: 分身/HANDS/Workflow
- Remove Hands tab from RightPanel
- Localize all UI text to Chinese
- Archive legacy OpenClaw documentation
- Add Hands integration lessons document
- Update feature checklist with new components

UI improvements:
- Left sidebar now shows Hands list with status icons
- Middle area shows selected Hand's tasks and results
- Consistent styling with Tailwind CSS
- Chinese status labels and buttons

Documentation:
- Create docs/archive/openclaw-legacy/ for old docs
- Add docs/knowledge-base/hands-integration-lessons.md
- Update docs/knowledge-base/feature-checklist.md
- Update docs/knowledge-base/README.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-03-14 23:16:32 +08:00
parent 67e1da635d
commit 07079293f4
126 changed files with 36229 additions and 1035 deletions

View File

@@ -0,0 +1,343 @@
# ZClaw 项目深度分析与改进计划
## 一、现状分析
### 1.1 核心发现
基于 `docs/openclaw-deep-dive.md` 的目标与实际代码的对比:
| 模块 | 目标状态 | 实际状态 | 差距程度 |
|------|----------|----------|----------|
| **Gateway 连接** | 设备认证 + Challenge 签名 | ✅ 完整实现 | 无差距 |
| **分身系统** | 映射到 OpenClaw `agents.list` | ⚠️ 独立存储在 `zclaw-data.json` | **严重** |
| **设置页** | OpenClaw Runtime 配置面板 | ⚠️ 大部分是前端本地状态 | **严重** |
| **右侧面板** | 真实 Agent 身份与状态 | ⚠️ 混合真实数据与硬编码值 | **中等** |
### 1.2 关键差距详解
#### 差距 1分身与 Agent 断层(最严重)
```
当前架构:
┌─────────────────────────────────────────────────────────────┐
│ ZClaw 分身系统 (zclaw-data.json) │
│ clone_1: { name: "程序员", workspaceDir: "...", ... } │
│ clone_2: { name: "设计师", workspaceDir: "...", ... } │
└────────────────────────┬────────────────────────────────────┘
│ ❌ 无同步
┌─────────────────────────────────────────────────────────────┐
│ OpenClaw agents.list (openclaw.json) │
│ 只有: [{ id: "main", groupChat: {...} }] │
└─────────────────────────────────────────────────────────────┘
```
**后果**
- 所有分身实际共用同一个 `main` Agent
- 聊天时不传递 `agentId`OpenClaw 不知道当前是哪个分身
- Bootstrap 文件IDENTITY.md, SOUL.md 等)生成了但未被运行时使用
#### 差距 2设置页是"假状态"
| 设置页 | 当前实现 | 应该实现 |
|--------|----------|----------|
| 模型选择 | 存在 `chatStore.currentModel`(前端状态) | 调用 `config.patch` 修改 OpenClaw 配置 |
| MCP 服务 | 存 `quickConfig`,部分同步到 Gateway | 管理 `plugins.load.paths` |
| 技能目录 | 存 `quickConfig` | 管理 `skills.load.extraDirs` |
| IM 频道 | 存 `quickConfig`,只显示状态 | 管理 `channels.*` 配置 |
| 工作区 | 存 `quickConfig` | 管理 `agents.defaults.workspace` |
| 隐私 | 存 `quickConfig` | 管理 telemetry/优化计划 |
**缺失的 RPC 方法**
- `config.get` - 读取 OpenClaw 配置
- `config.patch` - 修改配置
- `config.apply` - 热更新配置
#### 差距 3右侧面板数据不真实
```typescript
// 硬编码的默认值RightPanel.tsx
const credits = 2268; // 完全假数据
const defaultUserName = '用户7141'; // 假用户名
```
---
## 二、根因分析
### 2.1 架构层面的偏差
**文档期望**
> ZClaw 应该是 OpenClaw Runtime 的控制界面
**实际实现**
> ZClaw 是一个有自己数据模型的前端应用,与 OpenClaw 是松耦合
### 2.2 数据模型的分裂
```
OpenClaw 数据模型:
openclaw.json → agents.list → Agent workspace → Bootstrap files
ZClaw 数据模型:
zclaw-data.json → clones[] → (独立的) workspace 路径
```
两套数据模型没有桥接,导致:
1. 分身不能路由到正确的 Agent
2. 设置不能影响 OpenClaw 行为
3. Bootstrap 文件与运行时脱节
---
## 三、头脑风暴:改进方案
### 3.1 方案 A完全对齐 OpenClaw推荐
**核心思路**:让 ZClaw 分身直接映射到 OpenClaw Agent
```
改进后架构:
┌─────────────────────────────────────────────────────────────┐
│ ZClaw 分身 = OpenClaw Agent │
│ │
│ clone_1 ↔ agents.list[0] (id: "programmer") │
│ clone_2 ↔ agents.list[1] (id: "designer") │
│ │
│ 分身 CRUD → 同步修改 agents.list │
│ 聊天时 → 传递 agentId 到 Gateway │
└─────────────────────────────────────────────────────────────┘
```
**优点**
- 符合 `openclaw-deep-dive.md` 的设计哲学
- 分身真正有独立人格、记忆、工具权限
- 设置页可以直接操作 OpenClaw 配置
**缺点**
- 改动较大,需要修改多个模块
- 需要处理数据迁移
### 3.2 方案 B保持独立增强桥接
**核心思路**:保持 `zclaw-data.json`,但增加同步逻辑
```
改进后架构:
┌─────────────────────────────────────────────────────────────┐
│ ZClaw 分身系统 (主) │
│ zclaw-data.json → clones[] │
│ │ │
│ ▼ (单向同步) │
│ openclaw.json → agents.list (从分身生成) │
└─────────────────────────────────────────────────────────────┘
```
**优点**
- 改动较小
- 保持现有分身管理逻辑
**缺点**
- 数据冗余,需要维护同步
- 不符合 OpenClaw 的设计哲学
### 3.3 方案 C混合模式
**核心思路**
- 简单分身:共用 `main` Agent通过 Bootstrap 文件区分
- 高级分身:映射到独立 OpenClaw Agent
---
## 四、推荐实施路线(方案 A
### P0让分身真正工作最小可行
**目标**:创建分身时同步到 OpenClaw `agents.list`,聊天时传递 `agentId`
**关键修改**
1. **`plugins/zclaw-ui/index.ts`**
- `createClone` 时调用 OpenClaw API 添加到 `agents.list`
- `deleteClone` 时从 `agents.list` 移除
- 新增 `zclaw.agents.sync` 方法
2. **`desktop/src/lib/gateway-client.ts`**
- `chat()` 方法增加 `agentId` 参数
```typescript
async chat(message: string, opts?: { agentId?: string; sessionKey?: string }): Promise<...>
```
3. **`desktop/src/store/chatStore.ts`**
- `sendMessage` 时传递 `currentAgent.id` 作为 `agentId`
4. **新增 Gateway RPC**
- `zclaw.config.get` - 读取 OpenClaw 配置
- `zclaw.config.patch` - 修改配置
**验收标准**
- [ ] 创建分身后,`openclaw.json` 的 `agents.list` 包含新 Agent
- [ ] 切换分身后,聊天请求携带正确的 `agentId`
- [ ] 每个分身有独立的对话上下文
### P1设置页 Runtime 化
**目标**:设置修改直接影响 OpenClaw Runtime
**关键修改**
1. **`desktop/src/lib/gateway-client.ts`**
- 实现 `configGet()`、`configPatch()`、`configApply()` 方法
2. **各设置页改造**
- **模型与 API**:调用 `config.patch` 修改 `agents.defaults.model`
- **MCP 服务**:管理 `plugins.load.paths`
- **技能目录**:管理 `skills.load.extraDirs`
- **工作区**:管理 `agents.defaults.workspace`
- **隐私**:管理 telemetry 相关配置
3. **UI 反馈**
- 显示配置保存状态
- 配置变更后显示"需要重启"提示(如需要)
**验收标准**
- [ ] 模型选择后,`openclaw.json` 的 `agents.defaults.model` 更新
- [ ] 添加技能目录后,`skills.load.extraDirs` 更新
- [ ] Gateway 重启后配置生效
### P2完整的 Agent 管理系统
**目标**:分身管理 = Agent 全生命周期管理
**功能扩展**
1. 分身绑定渠道(飞书账号、微信群等)
2. 分身 Heartbeat 配置
3. 分身工具权限/沙箱配置
4. 分身间路由规则
**UI 改进**
- 右侧面板显示真实 Agent 状态(非硬编码)
- 分身详情页增加完整配置选项
### P3产品化封装
**目标**:开箱即用的桌面体验
**功能**
1. Tauri sidecar 管理 Gateway 进程
2. 首次安装配置向导
3. 错误诊断与自动修复
4. 一键更新
---
## 五、关键文件清单
| 文件 | 修改内容 |
|------|----------|
| `plugins/zclaw-ui/index.ts` | 分身 CRUD 同步到 agents.list |
| `desktop/src/lib/gateway-client.ts` | 增加 agentId 参数、config RPC |
| `desktop/src/store/chatStore.ts` | sendMessage 传递 agentId |
| `desktop/src/store/gatewayStore.ts` | 管理 Agent 配置状态 |
| `desktop/src/components/CloneManager.tsx` | 显示同步状态 |
| `desktop/src/components/RightPanel.tsx` | 显示真实 Agent 数据 |
| `desktop/src/components/Settings/*.tsx` | 改造为 Runtime 配置面板 |
| `config/openclaw.default.json` | 更新默认 Agent 模板 |
---
## 六、风险与缓解
| 风险 | 缓解措施 |
|------|----------|
| 数据迁移复杂 | 提供迁移脚本,保留 `zclaw-data.json` 作为备份 |
| OpenClaw 版本兼容 | 检测 OpenClaw 版本,低版本降级到兼容模式 |
| 破坏现有功能 | 灰度发布,支持回滚 |
| 性能下降 | 懒加载 Agent 配置,缓存 RPC 结果 |
---
## 七、确认的方案
**选择:方案 A - 完全对齐 OpenClaw**
理由:
1. 符合 `openclaw-deep-dive.md` 的设计哲学
2. 分身真正有独立人格、记忆、工具权限
3. 设置页可以直接操作 OpenClaw 配置
4. 长期维护成本最低
---
## 八、下一步行动P0 详细任务)
### Task 1: 修改 `zclaw-ui` 插件 - 分身同步到 agents.list
**文件**: `plugins/zclaw-ui/index.ts`
**修改点**:
1. `createClone` 方法增加:
- 调用 OpenClaw 内部 API 将分身添加到 `agents.list`
- 设置 `agentId` 字段关联分身与 Agent
2. `deleteClone` 方法增加:
- 从 `agents.list` 移除对应 Agent
3. `updateClone` 方法增加:
- 同步更新 Agent 配置
4. 新增 `zclaw.agents.sync` 方法:
- 读取当前 `agents.list`
- 与 `zclaw-data.json` 比对
- 修复不一致
### Task 2: 修改 GatewayClient - 支持 agentId
**文件**: `desktop/src/lib/gateway-client.ts`
**修改点**:
1. `chat()` 方法签名改为:
```typescript
async chat(message: string, opts?: {
agentId?: string; // 新增
sessionKey?: string;
model?: string;
}): Promise<{ runId: string; acceptedAt: string }>
```
2. `request('agent', ...)` 时传递 `agentId`
### Task 3: 修改 chatStore - 传递 agentId
**文件**: `desktop/src/store/chatStore.ts`
**修改点**:
1. `sendMessage` 方法调用 `client.chat()` 时传递 `currentAgent.id`
### Task 4: 新增配置 RPC 方法
**文件**: `desktop/src/lib/gateway-client.ts` + `plugins/zclaw-ui/index.ts`
**新增方法**:
- `zclaw.config.get` - 读取 OpenClaw 配置
- `zclaw.config.patch` - 修改配置(不重启)
- `zclaw.config.apply` - 热更新配置(如需重启)
### Task 5: 数据迁移脚本
**创建**: `scripts/migrate-clones-to-agents.ts`
**功能**:
1. 读取现有 `zclaw-data.json` 中的分身
2. 为每个分身在 `agents.list` 创建对应条目
3. 更新分身的 `agentId` 字段
4. 备份原始文件
---
## 九、验收标准
### P0 完成标准
- [ ] 创建分身后,`~/.openclaw/openclaw.json` 的 `agents.list` 包含新 Agent
- [ ] 删除分身后,对应 Agent 从 `agents.list` 移除
- [ ] 切换分身后,聊天请求携带正确的 `agentId`
- [ ] 每个分身有独立的对话上下文(不串聊)
- [ ] 现有分身数据成功迁移,无数据丢失
- [ ] 单元测试覆盖新增逻辑 ≥ 80%