Files
zclaw_openfang/plans/sequential-churning-wreath.md
iven 07079293f4 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>
2026-03-14 23:16:32 +08:00

344 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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%