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,467 @@
# ZCLAW 交付执行计划2026-03-12
## 1. 计划目标
本计划的目标不是继续做“功能堆叠”,而是把当前仓库推进到**可安装、可启动、可连接、可对话、可配置、可验证**的可交付状态。
当前对“完整可用 ZCLAW”的定义如下
- 用户能够在本机启动 ZCLAW 桌面应用
- 用户安装 ZCLAW 时OpenClaw 运行时已经随包提供,而不是要求用户另行安装
- 桌面应用能够引导并管理随 ZCLAW 一起分发的本地 OpenClaw Gateway
- 前端能够稳定连接 Gateway并完成基础握手与鉴权
- 用户能够创建、编辑、切换 AgentClone
- 用户能够发起真实对话并收到流式回复
- 关键设置页不再只是静态占位,而是尽量接到真实后端能力
- 有一套清晰的验收与收尾流程,支持阶段性提交与后续发布
---
## 2. 当前基线
### 2.1 已完成的关键能力
- Gateway 握手参数已修正,能够兼容 OpenClaw 2026.3.11
- Token 鉴权已接入前端连接流程
- `zclaw-ui` 插件可被 Gateway 正常加载
- Agent 的创建、编辑、保存链路已打通
- `scripts/setup.ts` 已可在已有 `~/.openclaw/openclaw.json` 时非破坏性合并插件与 skills 路径
- 自定义插件 manifest/package id 对齐问题已修复
### 2.2 当前仍阻塞交付的核心问题
按交付优先级排序,当前最关键的缺口为:
1. **桌面端尚未真正接管 Gateway 生命周期**
- `src/gateway/manager.ts` 已存在,但未被 Tauri 壳使用
- `desktop/src-tauri/src/lib.rs` 仍是默认模板
- 当前产品更像“前端连接外部 Gateway”还不是“完整桌面应用”
2. **当前仍默认依赖用户独立安装 OpenClaw**
- 这与最终产品目标不一致
- 最终必须做到:安装 ZCLAW 后即可直接使用 OpenClaw 能力
- 因此现阶段的 CLI/PATH 依赖只能作为开发期和过渡期方案
3. **真实桌面链路缺少本地运行闭环验证**
- 需要验证 Tauri 内从启动 Gateway 到连接、到拉数据、到发消息的完整过程
4. **设置体系中仍有若干页面/按钮处于占位状态**
- 部分页面已有 UI 但尚未连接真实能力
- 会影响“可用”判断,尤其是用户首次体验
5. **交付收尾缺少固定验收流程**
- 需要统一 smoke test、安装前检查、文档更新、阶段提交点
---
## 3. 总体推进策略
### 3.1 核心原则
- **先打通闭环,再做扩展**:优先修复阻塞真实使用的能力缺口,而不是继续加功能
- **优先最短交付路径**:优先复用 OpenClaw 现有 CLI/service 能力,而不是一开始就做完整 sidecar 架构
- **最终必须内置 OpenClaw**:开发阶段允许复用系统已安装的 OpenClaw但交付阶段必须改为随 ZCLAW 一起分发和托管
- **浏览器模式不回退**:新增 Tauri 能力必须有运行时保护,不影响现有浏览器预览/开发体验
- **阶段可提交**:每个阶段都有独立验收标准,达到后可形成 clean checkpoint
### 3.2 本轮优先级
- **P0**Tauri 桌面壳接入本地 Gateway 生命周期管理
- **P0**:完成真实桌面端基础闭环验证
- **P0**确定并落地“ZCLAW 安装即内置 OpenClaw”的分发方案
- **P1**:补齐最影响可用性的设置页占位项
- **P1**:形成交付前 smoke checklist 和文档更新
- **P2**:补测试、清理遗留代码、准备打包发布
---
## 4. 分阶段执行计划
## Phase A桌面端本地 Gateway 生命周期管理(当前最高优先级)
### A.1 目标
让 ZCLAW 桌面应用在 Tauri 环境下具备对本地 OpenClaw Gateway 的基础管理能力:
- 查询本地 Gateway 状态
- 启动本地 Gateway
- 停止本地 Gateway
- 重启本地 Gateway
- 在前端展示本地状态,并与现有 WebSocket 连接状态区分开
### A.2 实现策略
优先采用**Tauri Rust 命令封装 OpenClaw CLI** 的方式,而不是直接引入完整 sidecar
- Rust 侧封装以下命令:
- `openclaw gateway status --json`
- `openclaw gateway start --json`
- `openclaw gateway stop --json`
- `openclaw gateway restart --json`
- 前端通过 `invoke` 调用 Rust 命令
- 通过运行时判断,仅在 Tauri 环境中启用这组能力
- 浏览器模式继续保留“手工连接外部 Gateway”的现有逻辑
说明:
- 这一阶段是**开发期过渡方案**
- 它的价值是先把桌面端产品闭环跑通
- 但它**不是最终交付形态**
- 最终交付必须把 OpenClaw 运行时随 ZCLAW 一起打包,而不是要求用户本机已有 `openclaw`
### A.3 代码范围
- `desktop/src-tauri/src/lib.rs`
- `desktop/src/lib/tauri-gateway.ts`(新增)
- `desktop/src/store/gatewayStore.ts`
- `desktop/src/components/Settings/General.tsx`
- 如有必要:`desktop/src/components/RightPanel.tsx`
### A.4 验收标准
- Tauri 环境可正常调用本地 Gateway 管理命令
- 设置页能看到“本地 Gateway”状态卡片
- 用户可点击启动/停止/重启
- 启动成功后,前端可继续连接并拉取基础数据
- 浏览器模式不因该改动而报错或白屏
- 开发环境下,即使仍依赖系统 `openclaw`,也已经明确与最终 bundling 方案解耦
### A.5 风险与应对
- **风险**:不同机器上 `openclaw` 不在 PATH
- **应对**:前端明确提示“未安装 OpenClaw CLI”或“命令不可用”
- **风险**`status --json` / `start --json` 输出结构不稳定
- **应对**Rust 侧优先使用 `serde_json::Value` 宽松解析,再映射到前端稳定结构
- **风险**:服务模式与前台 `gateway run` 并存导致认知混乱
- **应对**UI 文案明确说明“本地服务状态”和“当前 WebSocket 连接状态”是两层状态
---
## Phase B真实桌面端基础闭环验证
### B.1 目标
确认 ZCLAW 在 Tauri 壳内已经不是“能打开 UI”而是“能完成一次真实任务闭环”
- 本地 Gateway 启动/可达
- 前端连接成功
- Clone 列表加载成功
- Agent 创建/编辑成功
- 首条消息发送成功
- 收到真实流式回复
### B.2 任务清单
- 启动桌面应用并检查本地 Gateway 状态
- 验证连接状态、版本、插件状态、workspace 信息是否能拉取
- 验证创建 Agent
- 验证编辑 Agent 并刷新右侧面板数据
- 验证 bootstrap 文件生成状态
- 验证聊天发送与回复流
- 记录关键报错与回退路径
### B.3 验收标准
- 至少完成一次完整桌面端对话闭环
- Agent 的创建与编辑在真实环境可用
- 连接失败、Gateway 未安装、未启动等错误能明确提示
- 关键路径没有阻塞性的控制台报错
---
## Phase COpenClaw 随包分发与运行时托管
### C.1 目标
把当前“依赖用户本机单独安装 OpenClaw”的开发态方案推进到真正可交付的产品方案
- 用户安装 ZCLAW 时OpenClaw 运行时已经包含在安装包内
- ZCLAW 启动后,能够直接找到并启动内置 OpenClaw
- 用户不需要再单独安装一套 OpenClaw CLI / 环境
### C.2 目标形态
最终交付建议采用以下形态:
- 安装包内包含 OpenClaw 可执行运行时或受控分发产物
- Tauri Rust 侧通过固定相对路径或 sidecar 机制调用该运行时
- ZCLAW 负责:
- 初始化 OpenClaw home / workspace
- 写入或合并默认配置
- 启动 / 停止 / 重启 Gateway
- 读取日志与状态
### C.3 方案比较
#### 方案 1继续依赖系统安装的 `openclaw`
优点:
- 当前开发改造最少
缺点:
- 不符合最终产品目标
- 用户安装体验差
- 环境差异和 PATH 问题会显著增加支持成本
结论:
- **仅适合开发期,不可作为最终交付方案**
#### 方案 2把 OpenClaw 作为 sidecar / bundled runtime 随 ZCLAW 分发
优点:
- 符合 QClaw / AutoClaw 式的一体化交付体验
- 可控性高
- 便于做安装后自启动、版本锁定、升级兼容
缺点:
- 需要处理体积、签名、跨平台打包、路径定位
结论:
- **这是最终推荐方案**
### C.4 实施任务
- 确认 OpenClaw 可分发形态
- npm 包直接落地
- 预构建二进制
- 内置 Node + OpenClaw 组合运行时
- 确认 Tauri 2 下 sidecar / bundled binary 的最佳实现方式
- 为 Windows 优先落地一版 bundling 方案
- 调整 Rust 侧命令执行逻辑
- 优先调用内置运行时
- 开发模式可回退到系统 `openclaw`
- 验证安装后首次启动流程
- 不依赖用户额外安装
- 可直接启动 Gateway
- 可连接、可聊天、可配置
### C.5 验收标准
- 全新机器上,未单独安装 OpenClaw 的情况下,可直接安装并启动 ZCLAW
- ZCLAW 可成功拉起内置 OpenClaw Gateway
- Agent / 聊天 / 设置等核心功能可正常工作
- 用户文档不再要求“先安装 OpenClaw 再使用 ZCLAW”
---
## Phase D设置页可用性补齐
### D.1 目标
梳理 Settings 体系中“看起来像功能、实际上还是占位”的部分,优先补齐最影响交付感知的项。
### D.2 优先补齐范围
优先级从高到低建议如下:
1. **General / ModelsAPI**
- Gateway 管理与连接语义统一
- 去掉误导性按钮或接到真实逻辑
2. **Workspace / Skills / MCPServices**
- 至少展示真实读取结果
- 对未支持能力明确标注“暂未接入”而不是伪交互
3. **IMChannels**
- 飞书状态尽量走真实探测
- 对未完成渠道使用明确状态说明
4. **Privacy / UsageStats / About**
- 以展示真实数据和静态说明为主,收尾体验
### D.3 判定标准
- 对用户可点击的动作,尽量有真实效果
- 对暂未接入的能力,明确说明而不是假按钮
- 页面不出现明显“假功能”感
---
## Phase E交付前 smoke test 与文档收尾
### E.1 目标
形成一套最小但明确的交付前检查流程,避免“本地看起来能用、别人拿到跑不起来”。
### E.2 交付前 smoke checklist
#### 环境检查
- `pnpm -v`
- `pnpm --dir desktop tauri --version`
说明:
- 最终交付 smoke test 不应再把系统级 `openclaw --version` 作为前置要求
- 应改为验证 ZCLAW 内置运行时是否可用
#### 桌面启动检查
- `pnpm --dir desktop tauri dev`
- UI 能正常打开
- 设置页不白屏
#### Gateway 闭环检查
- 本地 Gateway 状态可读
- 能启动/停止/重启
- 前端连接成功
#### 核心功能检查
- Clone 列表加载
- 新建 Clone
- 编辑 Clone
- 发送首条消息
- 收到流式回复
#### 配置检查
- quick config 可读写
- workspace 信息可读取
- 插件状态可显示
#### 安装闭环检查
- 全新环境中无需单独安装 OpenClaw
- 安装 ZCLAW 后首次启动即可使用
- 若内置运行时损坏或缺失,错误提示明确
### E.3 文档更新项
- 更新 README区分浏览器模式与 Tauri 桌面模式
- 补充本地 Gateway 启动/连接说明
- 补充已知限制与后续路线
-`PROGRESS.md` 中登记本轮交付成果
---
## Phase F交付后加强项不是当前阻塞项
以下事项重要,但不应阻塞本轮“完整可用”目标:
- 更完整的 Tauri sidecar / 进程托管架构
- 安装包/自动更新
- 更高覆盖率测试
- v1 归档代码清理
- 微信 / QQ Channel 扩展
- 新 Session Prompt 等增强功能
这些能力应在当前闭环稳定后进入下一轮计划。
---
## 5. 实施顺序与里程碑
## Milestone 1桌面端本地 Gateway 管理打通
输出物:
- Tauri 命令桥
- 前端本地 Gateway 状态卡片
- 启停/重启操作
完成标志:
- 能在桌面应用中看到并操作本地 Gateway 服务状态
## Milestone 2真实桌面闭环通过
输出物:
- 真实运行验证记录
- 阻塞 bug 列表(若有)
- 修复后的可用路径
完成标志:
- 从桌面打开到完成一次对话全链路可用
## Milestone 3OpenClaw 随包分发打通
输出物:
- Windows 优先的一体化 bundling 方案
- ZCLAW 优先调用内置 OpenClaw 运行时
- 安装后无需用户额外安装 OpenClaw 的可运行链路
完成标志:
- 在未安装 OpenClaw 的机器/环境中,安装 ZCLAW 后即可直接使用
## Milestone 4设置页与交付收尾
输出物:
- 最小可交付设置体验
- smoke checklist
- README / PROGRESS 更新
完成标志:
- 仓库进入“可给他人试用”的状态
---
## 6. 本轮立即执行项
按当前优先级,接下来立刻执行:
1. 在 Tauri Rust 侧实现 Gateway 管理命令
2. 在前端新增 Tauri Gateway bridge
3.`gatewayStore` 中接入本地 Gateway 状态与动作
4. 在 Settings > General 中增加本地 Gateway 管理卡片
5. 明确 OpenClaw 随包分发方案,避免把系统安装依赖固化为最终设计
6. 进行编译/运行级验证
7. 若验证通过,记录到 `PROGRESS.md`
---
## 7. 阶段提交策略
本轮按以下 checkpoint 推进:
### Checkpoint A
- 完成计划文档
- 完成 Tauri 命令桥与前端接线
### Checkpoint B
- 完成本地 Gateway 管理 UI
- 完成基础验证
### Checkpoint C
- 完成 OpenClaw bundling / sidecar 方案设计
- 明确 Windows 优先的交付路径
### Checkpoint D
- 完成设置页收尾 / 文档更新 / smoke checklist
说明:
- 代码会按干净阶段组织
- 如需执行远端 `push`,仍单独确认
---
## 8. 结论
当前最短、最正确的交付路径,不是继续扩展更多功能,而是先把 ZCLAW 从“能连 Gateway 的前端”推进成“能在桌面端真正管理并使用内置 OpenClaw 的产品”。
因此,本轮执行的核心结论是:
- **先做 Tauri 本地 Gateway 生命周期管理**
- **再完成 OpenClaw 随包分发方案**
- **然后做真实桌面端闭环验证**
- **最后收尾设置页与交付文档**
这条路线最符合当前仓库状态,也最接近“完整可用 ZCLAW”的真实交付目标。

View File

@@ -0,0 +1,663 @@
# OpenFang Hands & Workflow 集成开发方案
## 上下文
**目标**: 将 OpenFang 的 Hands 和 Workflow 功能深度集成到 ZClaw 桌面客户端,提供与 OpenFang Web 界面对等的用户体验。
**当前状态**:
- ZClaw 已有基础的 `HandsPanel.tsx``WorkflowList.tsx` 组件
- 这些组件功能有限,缺少 OpenFang 的核心 UI 特性
- OpenFang v0.4.0 提供了 8 个 Hands 和完整的 Workflow/Scheduler 系统
**参考界面**: http://127.0.0.1:50051 (OpenFang Dashboard)
---
## 一、OpenFang 界面分析总结
### 1.1 Hands 页面设计
```
┌─────────────────────────────────────────────────────────────────┐
│ Hands — Curated Autonomous Capability Packages │
│ Available 8 Active │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 🌐 Browser Hand [READY] │ │
│ │ Autonomous web browser — navigates sites... │ │
│ │ │ │
│ │ REQUIREMENTS │ │
│ │ ✓ Python 3 must be installed │ │
│ │ ✓ Chromium or Google Chrome must be installed │ │
│ │ │ │
│ │ 18 tool(s) · 3 metric(s) [productivity] │ │
│ │ [Details] [Activate] │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
**详情弹窗内容**:
- AGENT CONFIG: Provider, Model
- REQUIREMENTS: 检查项和状态 (✓/✗)
- TOOLS: 工具名称列表
- DASHBOARD METRICS: 指标名称列表
- Activate 按钮
### 1.2 Workflows 页面设计
```
┌─────────────────────────────────────────────────────────────────┐
│ Workflows │
│ What are Workflows? Workflows chain multiple agents... │
│ [List] [Visual Builder] [+ New Workflow] │
├─────────────────────────────────────────────────────────────────┤
│ NAME │ STEPS │ CREATED │ ACTIONS │
│ ──────────────────┼───────┼──────────────┼────────────────────│
│ 测试工作流 │ 1 │ 2026/3/14 │ [Run][Edit][Del] │
└─────────────────────────────────────────────────────────────────┘
```
### 1.3 Scheduler 页面设计
```
┌─────────────────────────────────────────────────────────────────┐
│ Scheduler [+ New Job] │
│ [Scheduled Jobs] [Event Triggers] [Run History] │
├─────────────────────────────────────────────────────────────────┤
│ Scheduled Jobs │
│ Create cron-based scheduled jobs... │
│ │
│ [No scheduled jobs] │
│ Create a cron job to run agents on a recurring schedule. │
│ [+ Create Scheduled Job] │
└─────────────────────────────────────────────────────────────────┘
```
### 1.4 Approvals 页面设计
```
┌─────────────────────────────────────────────────────────────────┐
│ Execution Approvals [Refresh] │
│ [All] [Pending] [Approved] [Rejected] │
├─────────────────────────────────────────────────────────────────┤
│ [No approvals] │
│ When agents request permission for sensitive actions, │
│ they'll appear here. │
└─────────────────────────────────────────────────────────────────┘
```
---
## 二、ZClaw 现有实现分析
### 2.1 已有组件
| 文件 | 功能 | 完成度 |
|------|------|--------|
| `HandsPanel.tsx` | Hand 列表、触发、审批、取消 | 40% |
| `WorkflowList.tsx` | Workflow 列表、执行 | 30% |
| `TriggersPanel.tsx` | Trigger 列表 | 20% |
| `gatewayStore.ts` | 状态管理 (Hands/Workflow API) | 60% |
### 2.2 缺失功能
1. **Hands**:
- ❌ 详情弹窗 (Details Modal)
- ❌ Requirements 状态检查可视化
- ❌ 工具和指标列表展示
- ❌ Agent Config 显示 (Provider/Model)
- ❌ 激活动画和状态反馈
- ❌ 分类标签 (productivity/data/content/communication)
2. **Workflows**:
- ❌ 创建/编辑 Workflow
- ❌ Visual Builder
- ❌ 执行历史查看
- ❌ 步骤详情展示
3. **Scheduler**:
- ❌ Scheduled Jobs 管理
- ❌ Event Triggers 管理
- ❌ Cron 表达式编辑器
- ❌ Run History
4. **Approvals**:
- ❌ 独立 Approvals 页面
- ❌ 筛选功能 (All/Pending/Approved/Rejected)
- ❌ 审批详情展示
---
## 三、开发方案
### 3.1 Phase 1: 增强 HandsPanel (优先级: 高)
**目标**: 提供与 OpenFang 对等的 Hands 管理体验
**文件修改**:
- `desktop/src/components/HandsPanel.tsx` (重写)
- `desktop/src/components/HandDetailsModal.tsx` (新建)
- `desktop/src/store/gatewayStore.ts` (扩展)
**UI 设计**:
```tsx
// HandCard 组件结构
<div className="hand-card">
<div className="hand-header">
<span className="hand-icon">{hand.icon}</span>
<h3>{hand.name}</h3>
<StatusBadge status={hand.status} /> {/* READY/SETUP NEEDED/RUNNING */}
</div>
<p className="hand-description">{hand.description}</p>
{/* Requirements 检查 */}
{hand.requirements && (
<div className="hand-requirements">
<span className="label">REQUIREMENTS</span>
{hand.requirements.map(req => (
<div className={req.met ? 'met' : 'unmet'}>
<span>{req.met ? '✓' : '✗'}</span>
<span>{req.description}</span>
</div>
))}
</div>
)}
{/* 元信息 */}
<div className="hand-meta">
<span>{hand.toolCount} tool(s)</span>
<span>{hand.metricCount} metric(s)</span>
<span className="category-tag">{hand.category}</span>
</div>
{/* 操作按钮 */}
<div className="hand-actions">
<Button variant="outline" onClick={onDetails}>Details</Button>
<Button variant="primary" onClick={onActivate} disabled={!hand.requirementsMet}>
{hand.status === 'running' ? 'Running...' : 'Activate'}
</Button>
</div>
</div>
```
**HandDetailsModal 组件**:
```tsx
// 详情弹窗
<Modal>
<ModalHeader>
<span className="icon">{hand.icon}</span>
<h2>{hand.name}</h2>
<StatusBadge status={hand.status} />
</ModalHeader>
<ModalBody>
{/* Agent Config */}
<Section title="AGENT CONFIG">
<Row label="Provider" value={hand.provider} />
<Row label="Model" value={hand.model} />
</Section>
{/* Requirements */}
<Section title="REQUIREMENTS">
{hand.requirements.map(req => (
<RequirementItem {...req} />
))}
</Section>
{/* Tools */}
<Section title="TOOLS">
<ToolGrid tools={hand.tools} />
</Section>
{/* Dashboard Metrics */}
<Section title="DASHBOARD METRICS">
<MetricList metrics={hand.metrics} />
</Section>
</ModalBody>
<ModalFooter>
<Button variant="outline" onClick={onClose}>Close</Button>
<Button variant="primary" onClick={onActivate}>Activate</Button>
</ModalFooter>
</Modal>
```
**API 扩展**:
```typescript
// gatewayStore.ts 扩展
interface Hand {
id: string;
name: string;
description: string;
status: 'idle' | 'running' | 'needs_approval' | 'error' | 'unavailable';
icon?: string;
category?: string; // productivity, data, content, communication
provider?: string;
model?: string;
requirements?: Array<{
description: string;
met: boolean;
details?: string;
}>;
tools?: string[];
metrics?: string[];
toolCount?: number;
metricCount?: number;
currentRunId?: string;
}
// 新增 API 调用
getHandDetails: (name: string) => Promise<HandDetails>;
activateHand: (name: string, params?: Record<string, unknown>) => Promise<HandRun>;
deactivateHand: (name: string) => Promise<void>;
```
### 3.2 Phase 2: 增强 WorkflowList (优先级: 高)
**目标**: 提供完整的 Workflow 管理能力
**文件修改**:
- `desktop/src/components/WorkflowList.tsx` (重写)
- `desktop/src/components/WorkflowEditor.tsx` (新建)
- `desktop/src/components/WorkflowHistory.tsx` (新建)
- `desktop/src/store/gatewayStore.ts` (扩展)
**UI 设计**:
```tsx
// WorkflowList 组件结构
<div className="workflow-list">
<div className="workflow-header">
<h2>Workflows</h2>
<div className="view-toggle">
<Button active={view === 'list'}>List</Button>
<Button active={view === 'visual'}>Visual Builder</Button>
</div>
<Button variant="primary" onClick={onCreate}>+ New Workflow</Button>
</div>
<p className="workflow-description">
Workflows chain multiple agents into automated pipelines...
</p>
<table className="workflow-table">
<thead>
<tr>
<th>NAME</th>
<th>STEPS</th>
<th>CREATED</th>
<th>ACTIONS</th>
</tr>
</thead>
<tbody>
{workflows.map(wf => (
<tr key={wf.id}>
<td>{wf.name}</td>
<td>{wf.steps}</td>
<td>{formatDate(wf.createdAt)}</td>
<td>
<Button size="sm" onClick={() => onRun(wf.id)}>Run</Button>
<Button size="sm" onClick={() => onEdit(wf.id)}>Edit</Button>
<Button size="sm" onClick={() => onHistory(wf.id)}>History</Button>
<Button size="sm" variant="danger" onClick={() => onDelete(wf.id)}>Delete</Button>
</td>
</tr>
))}
</tbody>
</table>
</div>
```
**WorkflowEditor 组件** (简化版):
```tsx
<WorkflowEditor workflow={workflow}>
<div className="workflow-editor">
<div className="workflow-info">
<Input label="Name" value={workflow.name} onChange={...} />
<Textarea label="Description" value={workflow.description} onChange={...} />
</div>
<div className="workflow-steps">
<h3>Steps</h3>
{workflow.steps.map((step, index) => (
<WorkflowStep
key={index}
step={step}
onEdit={() => editStep(index)}
onDelete={() => deleteStep(index)}
/>
))}
<Button onClick={addStep}>+ Add Step</Button>
</div>
<div className="workflow-actions">
<Button variant="outline" onClick={onCancel}>Cancel</Button>
<Button variant="primary" onClick={onSave}>Save Workflow</Button>
</div>
</div>
</WorkflowEditor>
```
**API 扩展**:
```typescript
// gatewayStore.ts 扩展
interface Workflow {
id: string;
name: string;
description?: string;
steps: WorkflowStep[];
createdAt: string;
updatedAt?: string;
}
interface WorkflowStep {
id: string;
agentId: string;
promptTemplate: string;
inputMapping?: Record<string, string>;
outputMapping?: Record<string, string>;
condition?: string;
timeout?: number;
}
// 新增 API 调用
createWorkflow: (workflow: CreateWorkflowInput) => Promise<Workflow>;
updateWorkflow: (id: string, updates: Partial<Workflow>) => Promise<Workflow>;
getWorkflowHistory: (id: string) => Promise<WorkflowRun[]>;
getWorkflowDetails: (id: string) => Promise<Workflow>;
```
### 3.3 Phase 3: 新建 SchedulerPanel (优先级: 中)
**目标**: 提供定时任务和事件触发器管理
**文件新建**:
- `desktop/src/components/SchedulerPanel.tsx`
- `desktop/src/components/ScheduledJobEditor.tsx`
- `desktop/src/components/EventTriggerEditor.tsx`
**UI 设计**:
```tsx
<SchedulerPanel>
<Tabs defaultValue="scheduled">
<TabsList>
<TabsTrigger value="scheduled">Scheduled Jobs</TabsTrigger>
<TabsTrigger value="triggers">Event Triggers</TabsTrigger>
</TabsList>
<TabsContent value="scheduled">
<div className="scheduled-jobs">
<Button onClick={onCreateJob}>+ Create Scheduled Job</Button>
{jobs.length === 0 ? (
<EmptyState
title="No scheduled jobs"
description="Create a cron job to run agents on a recurring schedule."
action="+ Create Scheduled Job"
onAction={onCreateJob}
/>
) : (
<JobList jobs={jobs} onEdit={onEditJob} onDelete={onDeleteJob} />
)}
</div>
</TabsContent>
<TabsContent value="triggers">
<div className="event-triggers">
<p>Event triggers fire agents in response to system events...</p>
{triggers.length === 0 ? (
<EmptyState title="No event triggers" />
) : (
<TriggerList triggers={triggers} />
)}
</div>
</TabsContent>
</Tabs>
</SchedulerPanel>
```
### 3.4 Phase 4: 新建 ApprovalsPanel (优先级: 中)
**目标**: 提供审批管理界面
**文件新建**:
- `desktop/src/components/ApprovalsPanel.tsx`
**UI 设计**:
```tsx
<ApprovalsPanel>
<div className="approvals-header">
<h2>Execution Approvals</h2>
<Button onClick={onRefresh}>Refresh</Button>
</div>
<div className="approvals-filters">
<Button active={filter === 'all'}>All</Button>
<Button active={filter === 'pending'}>Pending</Button>
<Button active={filter === 'approved'}>Approved</Button>
<Button active={filter === 'rejected'}>Rejected</Button>
</div>
<div className="approvals-list">
{filteredApprovals.length === 0 ? (
<EmptyState
title="No approvals"
description="When agents request permission for sensitive actions, they'll appear here."
/>
) : (
filteredApprovals.map(approval => (
<ApprovalCard
key={approval.id}
approval={approval}
onApprove={() => onApprove(approval.id)}
onReject={() => onReject(approval.id)}
/>
))
)}
</div>
</ApprovalsPanel>
```
### 3.5 Phase 5: 导航重构 (优先级: 中)
**目标**: 重构导航结构,匹配 OpenFang 布局
**文件修改**:
- `desktop/src/components/Sidebar.tsx`
- `desktop/src/components/RightPanel.tsx`
- `desktop/src/App.tsx`
**新导航结构**:
```
┌────────────────────┐
│ ZCLAW │
├────────────────────┤
│ CHAT │
│ └─ Chat │
│ MONITOR │
│ └─ Overview │
│ └─ Analytics │
│ └─ Logs │
│ AGENTS │
│ └─ Sessions │
│ └─ Approvals │
│ └─ Comms │
│ AUTOMATION │
│ └─ Workflows │
│ └─ Scheduler │
│ EXTENSIONS │
│ └─ Channels │
│ └─ Skills │
│ └─ Hands │
│ SYSTEM │
│ └─ Runtime │
│ └─ Settings │
└────────────────────┘
```
---
## 四、关键文件清单
### 4.1 需要修改的文件
| 文件路径 | 修改内容 |
|----------|----------|
| `desktop/src/components/HandsPanel.tsx` | 重写 HandCard添加详情弹窗 |
| `desktop/src/components/WorkflowList.tsx` | 添加创建/编辑功能 |
| `desktop/src/store/gatewayStore.ts` | 扩展 Hand/Workflow 类型定义 |
| `desktop/src/components/Sidebar.tsx` | 重构导航结构 |
| `desktop/src/components/RightPanel.tsx` | 集成新组件 |
| `desktop/src/lib/gateway-client.ts` | 添加新 API 调用 |
### 4.2 需要新建的文件
| 文件路径 | 功能 |
|----------|------|
| `desktop/src/components/HandDetailsModal.tsx` | Hand 详情弹窗 |
| `desktop/src/components/WorkflowEditor.tsx` | Workflow 编辑器 |
| `desktop/src/components/WorkflowHistory.tsx` | Workflow 执行历史 |
| `desktop/src/components/SchedulerPanel.tsx` | Scheduler 管理面板 |
| `desktop/src/components/ScheduledJobEditor.tsx` | 定时任务编辑器 |
| `desktop/src/components/EventTriggerEditor.tsx` | 事件触发器编辑器 |
| `desktop/src/components/ApprovalsPanel.tsx` | 审批管理面板 |
---
## 五、验证方案
### 5.1 手动测试
1. **Hands 测试**:
- 启动 ZClaw连接 OpenFang (端口 50051)
- 打开 Hands 标签
- 验证 8 个 Hands 正确显示
- 点击 Details 查看详情弹窗
- 点击 Activate 激活一个 Hand
- 验证状态变化和反馈
2. **Workflow 测试**:
- 打开 Workflow 标签
- 创建新 Workflow
- 编辑 Workflow 步骤
- 执行 Workflow
- 查看执行历史
3. **Scheduler 测试**:
- 创建定时任务
- 编辑 Cron 表达式
- 验证任务触发
4. **Approvals 测试**:
- 触发需要审批的 Hand
- 验证 Approvals 页面显示
- 批准/拒绝审批
### 5.2 自动化测试
```bash
# 运行相关测试
pnpm vitest run tests/desktop/handsPanel.test.tsx
pnpm vitest run tests/desktop/workflowList.test.tsx
pnpm vitest run tests/desktop/gatewayStore.test.ts
# 类型检查
pnpm tsc --noEmit
```
---
## 六、开发顺序 (根据用户确认)
**用户选择**:
- ✅ 优先实现 Hands 增强
- ✅ 需要完整实现 Scheduler 和 Approvals
**推荐开发顺序**:
| 顺序 | Phase | 工作量 | 说明 |
|------|-------|--------|------|
| 1 | Phase 1: HandsPanel 增强 | 2-3 天 | 最高优先级,核心功能 |
| 2 | Phase 4: ApprovalsPanel | 1 天 | Hand 执行需要审批流程 |
| 3 | Phase 2: WorkflowList 增强 | 2-3 天 | 完整工作流管理 |
| 4 | Phase 3: SchedulerPanel | 2 天 | 定时任务和事件触发器 |
| 5 | Phase 5: 导航重构 | 1-2 天 | 统一导航结构 |
| **总计** | - | **8-11 天** | - |
---
## 六-A、第一步实施细节: HandsPanel 增强
### 文件修改清单
1. **`desktop/src/components/HandsPanel.tsx`** (重写)
- 添加 HandCard 组件重构
- 添加状态徽章 (READY/SETUP NEEDED/RUNNING)
- 添加 Requirements 可视化
- 添加分类标签
- 添加工具/指标计数
2. **`desktop/src/components/HandDetailsModal.tsx`** (新建)
- Agent Config 显示 (Provider/Model)
- Requirements 列表
- Tools 列表
- Dashboard Metrics 列表
- Activate 按钮
3. **`desktop/src/store/gatewayStore.ts`** (扩展)
- 扩展 Hand 类型定义
- 添加 getHandDetails API
4. **`desktop/src/lib/gateway-client.ts`** (扩展)
- 添加 getHandDetails 方法
### UI 组件设计
```tsx
// HandStatusBadge 组件
type HandStatus = 'idle' | 'running' | 'needs_approval' | 'error' | 'unavailable' | 'setup_needed';
const STATUS_CONFIG: Record<HandStatus, { label: string; className: string }> = {
idle: { label: 'READY', className: 'bg-green-100 text-green-700' },
running: { label: 'RUNNING', className: 'bg-blue-100 text-blue-700 animate-pulse' },
needs_approval: { label: 'NEEDS APPROVAL', className: 'bg-yellow-100 text-yellow-700' },
error: { label: 'ERROR', className: 'bg-red-100 text-red-700' },
unavailable: { label: 'UNAVAILABLE', className: 'bg-gray-100 text-gray-500' },
setup_needed: { label: 'SETUP NEEDED', className: 'bg-orange-100 text-orange-700' },
};
// RequirementItem 组件
function RequirementItem({ description, met, details }: Requirement) {
return (
<div className={`flex items-start gap-2 text-sm ${met ? 'text-green-700' : 'text-red-600'}`}>
<span className="flex-shrink-0">{met ? '✓' : '✗'}</span>
<span>{description}</span>
{details && <span className="text-gray-400 text-xs">({details})</span>}
</div>
);
}
```
---
## 七、风险与缓解
| 风险 | 影响 | 缓解措施 |
|------|------|----------|
| OpenFang API 变更 | 高 | 使用实际 API 测试验证,保持与 OpenFang v0.4.0 兼容 |
| UI 复杂度 | 中 | 分阶段实现,先核心功能后高级功能 |
| 性能问题 | 低 | 使用虚拟列表处理大量数据 |
---
*计划创建时间: 2026-03-14*
*参考版本: OpenFang v0.4.0*

View File

@@ -0,0 +1,386 @@
# ZClaw: 从 OpenClaw 迁移到 OpenFang 可行性方案
> **规划日期**: 2026-03-13
> **目标**: 制定从 OpenClaw 到 OpenFang 的渐进式迁移策略,实现平稳过渡
---
## 一、背景与动机
### 1.1 当前架构 (OpenClaw)
```
┌─────────────────────────────────────────────────────────────────┐
│ ZClaw Desktop (当前) │
├─────────────────────────────────────────────────────────────────┤
│ React 19 UI → Zustand Store → GatewayClient → OpenClaw │
│ 技术栈: Tauri 2.0 + TypeScript + Node.js Gateway │
│ 内存: >1GB | 启动: 2-5s | 安装: 500MB │
└─────────────────────────────────────────────────────────────────┘
```
### 1.2 目标架构 (OpenFang)
```
┌─────────────────────────────────────────────────────────────────┐
│ ZClaw Desktop (OpenFang) │
├─────────────────────────────────────────────────────────────────┤
│ React 19 UI → Zustand Store → OpenFangClient → OpenFang │
│ 技术栈: Tauri 2.0 + TypeScript + Rust Gateway │
│ 内存: ~40MB | 启动: 180ms | 安装: 32MB │
└─────────────────────────────────────────────────────────────────┘
```
### 1.3 迁移动机
| 维度 | OpenClaw | OpenFang | 提升 |
|------|----------|----------|------|
| **启动速度** | 5.98s | 180ms | **33x 更快** |
| **内存占用** | 394MB | 40MB | **90% 更少** |
| **安装大小** | 500MB | 32MB | **94% 更小** |
| **安全防护** | 3 层 | 16 层 | **企业级安全** |
| **通道支持** | 20+ | 40+ | **覆盖更广** |
| **自主能力** | 无 | 7 Hands | **从被动到主动** |
---
## 二、核心差异分析
### 2.1 协议差异
| 方面 | OpenClaw | OpenFang |
|------|----------|----------|
| **WebSocket URL** | `ws://127.0.0.1:18789` | `ws://127.0.0.1:4200/ws` |
| **协议格式** | 自定义 JSON 帧 | 标准 JSON + gRPC |
| **认证方式** | Ed25519 设备签名 | Ed25519 + JWT |
### 2.2 配置差异
| 方面 | OpenClaw | OpenFang |
|------|----------|----------|
| **配置目录** | `~/.openclaw/` | `~/.openfang/` |
| **配置格式** | YAML/JSON | TOML |
| **插件系统** | TypeScript (`index.ts`) | SKILL.md + WASM |
### 2.3 API 差异
| 功能 | OpenClaw RPC | OpenFang API |
|------|-------------|--------------|
| 发送消息 | `agent` | `chat` / `/api/chat` |
| 列出 Agent | `zclaw.clones.list` | `GET /api/agents` |
| 获取配置 | `config.get` | `GET /api/config` |
| 触发技能 | 插件系统 | `skill_trigger` |
| Hand 自动化 | ❌ 无 | `hand_trigger` |
| Workflow | ❌ 基础 | `workflow_execute` |
---
## 三、迁移策略:渐进式双轨
### 3.1 策略原则
1. **双版本并行**: 保持 OpenClaw 可用,同时开发 OpenFang
2. **适配层抽象**: 通过接口隔离后端差异
3. **功能对等优先**: 先保证核心功能,再添加新特性
4. **灰度发布**: Beta 测试验证后全面切换
### 3.2 迁移阶段
```
Phase 1 (2周): 基础设施 ──────────────────────────────────────────►
Phase 2 (2周): 客户端实现 ────────────────────────────────────────►
Phase 3 (2周): 状态迁移 ──────────────────────────────────────────►
Phase 4 (3周): 插件迁移 ──────────────────────────────────────────►
Phase 5 (2周): Tauri 后端 ────────────────────────────────────────►
Phase 6 (3周): UI 增强 ───────────────────────────────────────────►
Phase 7 (2周): 测试验证 ──────────────────────────────────────────►
────────────────────────────────────────────────────────────────────
总工期: 16 周 (约 4 个月)
```
---
## 四、详细实施计划
### Phase 1: 基础设施 (Week 1-2)
**目标**: 建立迁移基础架构
**关键任务**:
1. 创建 `GatewayBackend` 接口抽象
2. 创建 `OpenFangClient` 骨架
3. 配置双后端切换机制
4. 设置 OpenFang 开发环境
**交付物**:
- `desktop/src/lib/types/gateway-backend.ts` - 接口定义
- `desktop/src/lib/openfang-client.ts` - 客户端骨架
- `desktop/src/lib/backend-factory.ts` - 后端工厂
### Phase 2: 客户端实现 (Week 3-4)
**目标**: 完整实现 OpenFang 客户端
**关键文件**: [gateway-client.ts](desktop/src/lib/gateway-client.ts)
**修改内容**:
```typescript
// 1. 抽取接口
interface GatewayBackend {
connect(): Promise<void>;
disconnect(): void;
chat(message: string, opts?: ChatOptions): Promise<{runId: string}>;
onStream(callback: StreamCallback): () => void;
// ... 其他方法
}
// 2. OpenClaw 实现 (现有代码重构)
class OpenClawBackend implements GatewayBackend { ... }
// 3. OpenFang 实现 (新建)
class OpenFangBackend implements GatewayBackend {
private ws: WebSocket;
private url = 'ws://127.0.0.1:4200/ws';
async connect(): Promise<void> {
// OpenFang 认证协议
}
async chat(message: string, opts?: ChatOptions): Promise<{runId: string}> {
// OpenFang chat 格式
}
}
```
### Phase 3: 状态迁移 (Week 5-6)
**目标**: 更新状态管理层支持双后端
**关键文件**: [gatewayStore.ts](desktop/src/store/gatewayStore.ts)
**修改内容**:
```typescript
interface GatewayStore {
// 新增
backendType: 'openclaw' | 'openfang';
switchBackend(type: 'openclaw' | 'openfang'): void;
// 修改 connect 方法
connect: async (url?, token?) => {
const backend = getBackendFactory().create(get().backendType);
await backend.connect(url, token);
}
}
```
### Phase 4: 插件迁移 (Week 7-9)
**目标**: 迁移现有插件到 OpenFang 格式
| 插件 | 当前格式 | 目标格式 | 复杂度 |
|------|----------|----------|--------|
| `zclaw-chinese-models` | TypeScript | TOML 配置 | 中 |
| `zclaw-feishu` | TypeScript | Rust/WASM | 高 |
| `zclaw-ui` | TypeScript RPC | REST API | 高 |
**迁移方案**:
```
plugins/
├── zclaw-chinese-models/
│ ├── openclaw.plugin.json → 删除
│ └── index.ts → 转换为 providers.toml
├── zclaw-feishu/
│ └── index.ts → 迁移到 OpenFang channels
└── zclaw-ui/
└── index.ts → 拆分为 REST 端点
```
### Phase 5: Tauri 后端 (Week 10-11)
**目标**: 更新 Rust 后端支持 OpenFang
**关键文件**: [lib.rs](desktop/src-tauri/src/lib.rs)
**修改内容**:
```rust
// 新增 OpenFang 命令
#[tauri::command]
async fn openfang_status() -> Result<OpenFangStatus, String> { ... }
#[tauri::command]
async fn openfang_start() -> Result<(), String> { ... }
#[tauri::command]
async fn openfang_stop() -> Result<(), String> { ... }
// 新增配置迁移命令
#[tauri::command]
async fn migrate_to_openfang() -> Result<MigrationResult, String> { ... }
```
### Phase 6: UI 增强 (Week 12-14)
**目标**: 添加 OpenFang 特有的 UI 功能
**新增组件**:
1. `HandsPanel.tsx` - Hands 管理界面
2. `WorkflowEditor.tsx` - 工作流编辑器
3. `TriggerManager.tsx` - 触发器管理
4. `AuditLogs.tsx` - 审计日志查看
**修改组件**:
1. `SettingsLayout.tsx` - 添加后端切换选项
2. `General.tsx` - 添加 OpenFang 配置项
### Phase 7: 测试验证 (Week 15-16)
**目标**: 全面测试和验证
**测试范围**:
- 单元测试: 新客户端、适配层
- 集成测试: 端到端消息流
- 性能测试: 启动时间、内存占用
- 迁移测试: 配置迁移正确性
---
## 五、风险评估与缓解
### 5.1 技术风险
| 风险 | 级别 | 缓解措施 |
|------|------|----------|
| 协议不兼容 | 高 | 创建适配层,保持双后端 |
| 插件迁移复杂 | 高 | 分阶段迁移,保持 TypeScript 桥接 |
| OpenFang 不成熟 | 中 | 持续关注上游,建立社区联系 |
| 配置格式差异 | 中 | 构建自动迁移工具 |
### 5.2 运营风险
| 风险 | 级别 | 缓解措施 |
|------|------|----------|
| 用户困惑 | 中 | 清晰文档,渐进发布 |
| 数据丢失 | 高 | 自动备份,非破坏性迁移 |
| 支持负担 | 中 | FAQ故障排除指南 |
### 5.3 回滚策略
```typescript
// 环境变量切换
const USE_OPENFANG = process.env.ZCLAW_USE_OPENFANG === 'true';
// localStorage 切换
const backendType = localStorage.getItem('zclaw-backend') || 'openclaw';
// 一键回滚
function rollbackToOpenClaw() {
localStorage.setItem('zclaw-backend', 'openclaw');
window.location.reload();
}
```
---
## 六、验证方案
### 6.1 功能验证清单
**核心功能**:
- [ ] WebSocket 连接和认证
- [ ] 消息发送和流式接收
- [ ] Agent/Clone CRUD 操作
- [ ] 频道管理 (飞书)
- [ ] 技能加载和执行
- [ ] 使用统计
- [ ] 配置管理
**OpenFang 新特性**:
- [ ] Hand 触发 (Clip, Lead, Researcher 等)
- [ ] Workflow 执行
- [ ] 16 层安全验证
- [ ] 审计日志访问
### 6.2 性能基准
| 指标 | OpenClaw 基线 | OpenFang 目标 |
|------|---------------|---------------|
| 冷启动 | 5.98s | < 500ms |
| 空闲内存 | 394MB | < 100MB |
| 聊天延迟 | 100ms | < 50ms |
| 安装大小 | 500MB | < 100MB |
---
## 七、关键文件清单
| 文件 | 修改类型 | 说明 |
|------|----------|------|
| [gateway-client.ts](desktop/src/lib/gateway-client.ts) | 重构 | 抽取接口创建 OpenFang 实现 |
| [gatewayStore.ts](desktop/src/store/gatewayStore.ts) | 修改 | 添加后端切换逻辑 |
| [chatStore.ts](desktop/src/store/chatStore.ts) | 修改 | 适配新事件格式 |
| [lib.rs](desktop/src-tauri/src/lib.rs) | 扩展 | 添加 OpenFang 管理命令 |
| [zclaw-ui/index.ts](plugins/zclaw-ui/index.ts) | 迁移 | 转换为 REST API |
| [zclaw-chinese-models/index.ts](plugins/zclaw-chinese-models/index.ts) | 迁移 | 转换为 TOML 配置 |
| [zclaw-feishu/index.ts](plugins/zclaw-feishu/index.ts) | 迁移 | 使用 OpenFang channel |
---
## 八、时间线总结
| 阶段 | 周期 | 开始 | 结束 | 关键交付物 |
|------|------|------|------|------------|
| Phase 1 | 2周 | Week 1 | Week 2 | OpenFangClient 骨架 |
| Phase 2 | 2周 | Week 3 | Week 4 | 完整客户端 + 流式处理 |
| Phase 3 | 2周 | Week 5 | Week 6 | 更新后的 stores |
| Phase 4 | 3周 | Week 7 | Week 9 | 迁移后的插件 |
| Phase 5 | 2周 | Week 10 | Week 11 | Rust OpenFang 支持 |
| Phase 6 | 3周 | Week 12 | Week 14 | Hands/Workflow UI |
| Phase 7 | 2周 | Week 15 | Week 16 | 测试套件验证报告 |
**总工期**: 16 ( 4 个月)
---
## 九、结论与建议
### 9.1 核心价值
```
┌─────────────────────────────────────────────────────────────────┐
│ │
│ 🚀 性能33x 启动速度 + 90% 内存节省 │
│ │
│ 🔒 安全16 层纵深防御 + 金融级合规 │
│ │
│ 🤖 智能Hands 自主系统 + Workflow 引擎 │
│ │
│ 📈 商业:企业市场拓展 + 定价提升空间 │
│ │
│ ⚠️ 成本16 周 (4个月) 迁移周期 │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### 9.2 决策建议
| 目标 | 建议 |
|------|------|
| 追求企业市场 | **强烈建议迁移** |
| 追求差异化竞争 | **建议迁移** |
| 目标是内容创作者/销售 | **强烈建议迁移** |
| 资源有限 | 渐进评估 |
| 追求快速迭代 | 保持 OpenClaw关注 OpenFang |
### 9.3 下一步行动
1. **立即**: 确认迁移决策分配资源
2. **Week 1**: 创建 `GatewayBackend` 接口
3. **Week 2**: 搭建 OpenFang 开发环境
4. **Week 3-4**: 实现 `OpenFangClient`
---
*规划日期: 2026-03-13*
*版本: v1.0*

View File

@@ -0,0 +1,420 @@
# ZCLAW 新会话提示词后续工作计划
## 一、目标
围绕 ZCLAW 的“新会话提示词”能力,完成一条从 **真实 Agent 配置****真实会话初始化行为** 的可交付链路。
这项能力的目标不是增加一个前端文本框,而是让用户可以:
- 为当前 Agent 设置默认的新会话提示词
- 在开启某个新会话时临时覆盖这段提示词
- 让提示词真实影响本次会话第一轮 Agent 行为
- 让该能力在快速配置、右侧 Agent 面板、聊天区之间语义一致
---
## 二、当前已确认基础
以下基础能力已经打通,可作为本轮工作的前提:
- Gateway 连接稳定可用
- token 注入、自动连接、Control UI 握手已修好
- `zclaw-ui` 插件已加载
- `zclaw.clones.list``zclaw.plugins.status` 可用
- Agent 创建、右侧 Agent 面板编辑、保存回刷已验证通过
- 快速配置应视为创建/更新 OpenClaw Agent
- 右侧 Agent 面板已经是当前 Agent 配置的真实编辑入口
这意味着“新会话提示词”应该优先挂在 **Agent Profile 真实配置链路** 上,而不是再创建一套独立的本地状态。
---
## 三、问题定义
当前“新对话”链路还存在几个明显缺口:
### 3.1 会话初始化仍是本地 UI 行为
现状:
- `chatStore.newConversation()` 只清空本地消息与 `sessionKey`
- 首次发送时才临时生成 `sessionKey`
- 当前没有“会话初始化参数”的明确模型
影响:
- 新会话无法承载独立初始化上下文
- 会话开场行为不可控、不可审计
### 3.2 Agent 配置与新会话行为未打通
现状:
- Agent 已有真实配置入口
- 但聊天区不会消费“新会话默认提示词”这一能力
影响:
- Agent 身份和会话起始行为割裂
- 用户改了 Agent不一定影响新会话
### 3.3 当前没有原生会话初始化协议
现状:
- 当前 Gateway `agent` 请求只传 `message / sessionKey / model`
- 尚未形成 `sessionInit``agentId``conversationContext` 等结构化初始化协议
影响:
- 若不做桥接,“新会话提示词”很难真实生效
---
## 四、设计原则
### 4.1 必须改变真实运行行为
验收标准不是“页面上能输入”,而是:
- 第一条发给 Gateway 的真实消息已经体现新会话提示词
- 不同会话可以有不同初始化上下文
- 会话恢复后能够看出本会话使用过什么提示词
### 4.2 必须依附真实 Agent 配置链路
能力入口必须统一在以下两处:
- 快速配置创建 Agent
- 右侧 Agent 面板编辑当前 Agent
不新增与 Agent 平行、脱节的新设置体系。
### 4.3 先做最小真实闭环,再继续原生化
本轮优先实现:
- Agent 级默认 `newSessionPrompt`
- 会话级 `sessionPromptDraft`
- 首轮消息注入
后续再根据 Gateway / OpenClaw 演进升级为结构化原生协议。
---
## 五、目标能力定义
### 5.1 Agent 级默认提示词
语义:
- 某个 Agent 在每次开始新会话时默认携带的启动上下文
- 属于 Agent Profile 的一部分
- 可以由快速配置或右侧 Agent 面板编辑
建议字段:
- `newSessionPrompt?: string`
### 5.2 会话级临时覆盖
语义:
- 仅对本次新会话生效
- 发出第一条用户消息前可编辑
- 发出后固化到会话元数据中,不应在后续回合反复注入
建议字段:
- `sessionPromptDraft: string`
- `conversation.sessionPrompt?: string | null`
### 5.3 首轮运行时注入
语义:
- 前端保留原始用户输入展示
- 发送给 Gateway 的第一条消息在内部包装为“新会话提示词 + 原始用户问题”
- 从而让提示词立即影响真实模型行为
---
## 六、实施阶段拆分
## Phase 1数据模型与 RPC 链路补齐
### 目标
让“新会话提示词”成为真实 Agent 数据结构的一部分。
### 涉及位置
- `plugins/zclaw-ui/index.ts`
- `desktop/src/store/gatewayStore.ts`
- `desktop/src/store/chatStore.ts`
- `desktop/src/components/CloneManager.tsx`
- `desktop/src/components/RightPanel.tsx`
### 具体任务
- 插件层 `CloneConfig` 增加 `newSessionPrompt`
- `zclaw.clones.create/update/list` 全链路透传该字段
- 前端 `Clone`、快速配置草稿、右侧面板草稿模型补齐字段
- 保证创建后、编辑后、刷新后都能回刷正确数据
### 交付物
- Agent Profile 可持久化 `newSessionPrompt`
- UI 能读取并展示该字段
### 验收标准
- 创建 Agent 时可设置默认新会话提示词
- 右侧 Agent 面板可编辑并保存该字段
- 重新连接或刷新后字段仍存在
---
## Phase 2聊天会话模型扩展
### 目标
为“新会话提示词”建立真正的会话级承载结构。
### 具体任务
- `chatStore` 增加 `sessionPromptDraft`
- `Conversation` 增加 `sessionPrompt``agentId`
- `newConversation()` 时重置当前会话的提示词草稿
- 当切换 Agent 且当前尚未开始聊天时,提示词草稿应回填为当前 Agent 默认值
- 切换到历史会话时,恢复该会话使用过的 `sessionPrompt`
### 交付物
- 会话层面拥有独立的提示词状态
- 会话与 Agent 的关系更清晰
### 验收标准
- 新会话默认读取当前 Agent 的默认提示词
- 修改草稿只影响当前新会话,不污染其他历史会话
- 切回历史会话时能恢复对应提示词信息
---
## Phase 3首轮消息注入打通真实运行行为
### 目标
让“新会话提示词”真正影响 Gateway 收到的第一条消息。
### 具体任务
-`chatStore.sendMessage()` 判断当前是否为该会话首轮用户消息
- 若有有效 `sessionPromptDraft`,则构造包装后的发送内容
- UI 中仍展示用户原始输入,不暴露包装结构
- 首轮发出后,将实际使用过的提示词固化到当前 `Conversation`
- 后续同一会话继续发送消息时不重复注入
### 建议包装格式
```text
[ZCLAW_NEW_SESSION_PROMPT]
<session prompt>
[/ZCLAW_NEW_SESSION_PROMPT]
[USER_MESSAGE]
<original user message>
[/USER_MESSAGE]
```
### 交付物
- 新会话提示词真正进入第一轮 Gateway 请求
- 该能力不再是展示层占位
### 验收标准
- 第一轮消息有提示词时,模型行为明显受影响
- 第二轮起不再重复注入
- 无提示词时发送链路与当前一致
---
## Phase 4交互与可见性优化
### 目标
让用户知道“当前会话将以什么上下文启动”,同时避免界面复杂度失控。
### 具体任务
- 在聊天区空态增加“新会话提示词”输入区
- 提供简洁说明文案,明确这是“仅本次会话”的覆盖入口
- 在右侧 Agent 面板非编辑态显示默认新会话提示词摘要
- 在历史会话列表或会话详情中,保留轻量提示,帮助用户理解该会话的启动上下文
### 交付物
- 新会话前可见、可改、可理解
- Agent 默认值与会话覆盖值关系明确
### 验收标准
- 用户能区分“Agent 默认值”和“当前会话覆盖值”
- 用户不会误以为这是长期人格或全局系统提示词
---
## Phase 5质量保障与回归验证
### 目标
确保能力上线后不会破坏现有已打通链路。
### 测试范围
- Agent 创建后默认提示词可保存
- 右侧 Agent 面板编辑提示词可回刷
- 新会话读取默认值
- 新会话覆盖值只作用于当前会话
- 首轮消息注入只发生一次
- 切换历史会话后元数据恢复正确
- 无提示词情况下原有发送链路不回归
### 建议验证方式
- Store 层单元测试
- 关键组件交互测试
- 手工联调验证 Gateway 请求行为
### 交付物
- 至少覆盖核心 store 行为的测试
- 一份人工回归清单
### 验收标准
- 核心交互不回归
- 会话状态与 Agent 状态一致性可验证
---
## 七、推荐执行顺序
建议按以下顺序推进,避免前后反复返工:
### 第一步
先做 **Phase 1**
原因:
- 没有真实字段,就谈不上后续真实会话能力
- 这一步风险最低,收益明确
### 第二步
**Phase 2**
原因:
- 会话级草稿与历史恢复能力是首轮注入的前提
### 第三步
**Phase 3**
原因:
- 这是从“有配置”到“真生效”的关键跃迁
- 也是这轮工作的核心里程碑
### 第四步
**Phase 4 + Phase 5**
原因:
- 在核心链路稳定后,再做可见性和质量封口最合适
---
## 八、本轮建议的最小可交付版本
如果本轮只做一个最小但高价值版本,建议交付以下内容:
- 插件与前端数据模型支持 `newSessionPrompt`
- 快速配置与右侧 Agent 面板都可编辑该字段
- 聊天区空态可查看/修改当前新会话提示词
- 首轮消息自动注入该提示词
- 会话中记录本次实际使用的提示词
这版已经满足:
- 有真实配置入口
- 有真实运行时行为
- 有会话级语义
- 能被用户实际使用
---
## 九、主要风险与处理策略
### 风险 1当前 selected Agent 还未完全映射到 OpenClaw runtime agent
影响:
- 即使 Agent Profile 已切换,底层仍可能没有原生 agent routing
处理:
- 本轮先用“首轮消息注入”保证真实行为变化
- 后续把 `agentId` 传输与 runtime routing 作为独立里程碑推进
### 风险 2提示词注入格式可能影响回答质量
影响:
- 包装格式不佳时,可能让模型输出不稳定
处理:
- 采用清晰、边界明确的包裹格式
- 在真实模型上做几组样例测试
### 风险 3会话切换与持久化逻辑容易变脆
影响:
- 草稿、历史会话、当前会话三者状态可能串扰
处理:
- 优先把 store 状态边界设计清楚
- 先覆盖核心状态迁移测试,再做 UI 微调
---
## 十、完成定义
当以下条件同时满足时,可视为“新会话提示词”能力第一阶段完成:
- Agent 默认新会话提示词可创建、编辑、保存、回刷
- 新会话开始前用户可临时覆盖该提示词
- 首轮真实发送到 Gateway 的消息中包含该提示词上下文
- 同一会话后续消息不重复注入
- 历史会话可以恢复其实际使用过的提示词信息
- 快速配置、右侧 Agent 面板、聊天区三处语义一致
---
## 十一、下一步建议
在本计划落地后,建议立即开始:
- **P1先补数据模型与插件透传**
- **P2再补 chatStore 的会话级状态模型**
- **P3最后接入首轮消息注入并做联调验证**
这会以最小改动建立一条真正可用的闭环,也是当前最符合 ZCLAW 产品化推进方向的高杠杆路径。

View File

@@ -0,0 +1,231 @@
# ZClaw 改进方案:从"前端 UI 演示"升级为"真正的 OpenClaw Runtime 控制界面"
**日期**: 2026-03-12
**状态**: 规划中
---
## 背景分析
### 当前状态
经过对代码库的深入分析,发现以下关键差距:
#### 1. 分身与 Agent 断层
- **现状**: 分身存储在 `zclaw-data.json` (ZCLAW 自定义格式)
- **问题**: 不映射到 OpenClaw 原生 `agents.list` 配置
- **影响**: 聊天时不所有分身共用 `main` Agent
- **表现**: Bootstrap 文件生成了但可能未被 Agent 运行时使用
**关键代码位置**:
- `desktop/src/components/CloneManager.tsx`: 分身 CRUD 界面
- `desktop/src/store/chatStore.ts`: `currentAgent` 只存前端状态
- `plugins/zclaw-ui/index.ts`: 分身存储在 `zclaw-data.json`
#### 2. 设置页是"假状态"
- **现状**: 大部分设置只存 localStorage
- **问题**: 没有调用 OpenClaw 的 `config.get/config.patch/config.apply`
- **影响**: 用户改了设置而 OpenClaw 运行时行为不变
**关键代码位置**:
- `desktop/src/components/Settings/*.tsx`: 所有设置页面
- `desktop/src/store/chatStore.ts`: `currentModel` 只存前端状态
- `desktop/src/lib/gateway-client.ts`: 缺少 `config.*` RPC 方法
#### 3. 右侧面板数据不真实
- **现状**: 部分数据是硬编码默认值
- **问题**: 没有显示真实 Agent 的运行时状态
- **影响**: 用户看到的是演示数据,- **表现**: Bootstrap 文件生成了但可能未被 Agent 运行时使用
---
## P0: 最小可行改进 - 让分身真正工作
### 目标
让分身系统真正映射到 OpenClaw Agent 实例,实现分身隔离(独立 Agent 会话)。
### 关键任务
#### 1. 实现 Agent 同步机制
-`plugins/zclaw-ui/index.ts` 中:
- 添加 `zclaw.agents.sync` RPC 方法
- 同步 `zclaw-data.json` 的分身到 `agents.list`
- 为每个分身创建独立 `agentDir`
-`desktop/src/lib/gateway-client.ts` 中:
- 添加 `agents.list` RPC 方法封装
- 添加 `agent.set` RPC 方法封装
#### 2. 修改聊天逻辑
-`desktop/src/store/chatStore.ts` 中:
- 添加 `currentAgentId` 字段
- 修改 `sendMessage` 传递 `agentId`
-`desktop/src/components/ChatArea.tsx` 中:
- 聊天时显示当前分身信息
#### 3. Agent 启动流程
- 创建分身时:
1. 生成 Bootstrap 文件
2. 同步到 `agents.list`
3. 重启 Agent 进程(如果需要)
- 切换分身时:
1. 加载对应 Agent 的上下文
2. 切换 `agentId`
### 技术挑战
- **OpenClaw Agent 进程管理**: 隐式依赖 Gateway 的 Agent 启动机制
- **会话隔离**: 需要验证 OpenClaw 是否支持 `agentId` 参数
- **配置同步时机**: 何时同步分身配置到 OpenClaw
- **错误处理**: Agent 启动失败时的回退策略
### 验收标准
- [ ] 创建分身后能在 OpenClaw 的 `agents.list` 中看到
- [ ] 切换分身后聊天时传递正确的 `agentId`
- [ ] 不同分身的会话完全隔离
- [ ] Bootstrap 文件被 Agent 正确加载
- [ ] 分身配置修改后 Agent 行为相应变化
---
## P1: 设置页 Runtime 化
### 目标
让设置页真正修改 OpenClaw Runtime 配置。
### 关键任务
#### 1. GatewayClient 扩展
`desktop/src/lib/gateway-client.ts` 中添加:
```typescript
async getConfig(path?: string): Promise<any>
async patchConfig(path: string, value: any): Promise<void>
async applyConfig(): Promise<void>
```
#### 2. 设置页改造
**模型与 API**:
- 模型选择调用 `patchConfig('agents.defaults.model', model)`
- 显示当前模型从 `getConfig('agents.defaults.model')` 获取
**MCP 服务**:
- 读取: `getConfig('mcp')`
- 修改: `patchConfig('mcp.servers.*')`
**技能**:
- 读取: `getConfig('skills')`
- 修改: `patchConfig('skills.load.extraDirs')`
**IM 频道**:
- 读取: `getConfig('channels')`
- 修改: `patchConfig('channels.*')`
**工作区**:
- 读取: `getConfig('agents.defaults.workspace')`
- 修改: `patchConfig('agents.defaults.workspace')`
### 技术挑战
- **配置路径**: OpenClaw 配置是嵌套结构,需要正确处理路径
- **配置验证**: 修改前验证配置有效性
- **错误恢复**: 配置修改失败时的回滚
- **UI 反馈**: 配置修改时的加载状态
- **配置缓存**: 避免频繁读取配置
### 验收标准
- [ ] 模型选择后聊天时使用新模型
- [ ] MCP 开关后工具可用性变化
- [ ] 技能添加后 Agent 可调用
- [ ] IM 频道配置后能收发消息
- [ ] 工作区修改后文件访问范围变化
- [ ] 配置修改后重启 Gateway 生效
---
## P2: 完整的 Agent 管理系统
### 目标
实现完整的 Agent 生命周期管理。
### 关键任务
#### 1. Agent 状态管理
`desktop/src/store/chatStore.ts` 中添加
```typescript
interface AgentState {
id: string;
status: 'idle' | 'running' | 'error';
lastActive: Date;
sessionCount: number;
currentModel: string;
}
```
#### 2. Agent 监控
`plugins/zclaw-ui/index.ts` 中添加
```typescript
api.registerGatewayMethod('zclaw.agents.status', ({ respond }) => {
// 返回所有 Agent 的运行时状态
});
```
#### 3. 右侧面板增强
`desktop/src/components/RightPanel.tsx`
- 显示真实 Agent 状态
- 显示运行时信息(当前任务、 使用的工具等)
- 显示会话历史
### 技术挑战
- **状态同步**: 客户端状态与 Gateway 状态同步
- **性能**: 大量 Agent 时的性能
- **错误处理**: Agent 状态异常时的 UI 反馈
- **实时更新**: 状态变化时的实时推送
### 验收标准
- [ ] Agent 状态实时显示
- [ ] 运行时信息准确
- [ ] 会话历史可查
- [ ] 错误状态有明确提示
- [ ] 性能满足要求(100 个 Agent)
---
## P3: 产品化封装
### 目标
提供完整的桌面应用体验。
### 关键任务
#### 1. Tauri Sidecar 管理
`desktop/src-tauri/src/gateway.rs` 中:
- 管理 Gateway 子进程生命周期
- 自动重启和错误恢复
- 配置管理和持久化
#### 2. 首次启动体验
- 欢迎向导
- Gateway 连接配置
- 默认 Agent 创建
- 工作目录选择
#### 3. 错误诊断
- 连接问题诊断
- 配置错误修复建议
- 日志查看工具
### 技术挑战
- **进程管理**: 跨平台进程管理
- **权限**: 文件系统访问权限
- **更新**: 应用更新时的状态保持
- **用户体验**: 错误时的用户引导
- **文档**: 用户文档和帮助
### 验收标准
- [ ] Gateway 自动启动
- [ ] 首次启动流程完整
- [ ] 错误有明确指引
- [ ] 配置持久化
- [ ] 应用更新无状态丢失
- [ ] 用户文档完整

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%