feat: implement task management store with IPC integration

- Added a new task store in `src-react/stores/task.ts` to manage tasks and their statuses.
- Implemented functions for creating, executing, and retrying tasks, along with handling task progress and completion.
- Introduced persistence for tasks using IPC.
- Created utility functions for normalizing room types and building subtasks.
- Added a new CSS file for global styles in `src-react/styles.css`.
- Created runtime types in `src-react/types/runtime.ts` and exported them.
- Updated the main entry points for Vue and React applications to support dynamic framework loading.
- Refactored chat model interfaces and utility functions into `src/shared/chat-model.ts`.
- Updated TypeScript configuration to include paths for React components and types.
- Enhanced Vite configuration to support both Vue and React frameworks.
This commit is contained in:
duanshuwen
2026-04-17 07:09:56 +08:00
parent d233b94b2a
commit b1dea9a5c2
68 changed files with 5910 additions and 397 deletions

View File

@@ -0,0 +1,469 @@
# zn-ai 对齐 ClawX 的 Vue -> React 平替迁移计划
## 1. 目标与结论
- `zn-ai` 当前前端是完整的 `Vue 3 + Pinia + Vue Router + Element Plus + Tailwind` 体系,不是少量页面级 Vue 组件。
- `ClawX` 当前前端是完整的 `React 19 + React Router + Zustand + Radix/shadcn + Tailwind` 体系。
- 如果目标是“对齐 ClawX 使用 React”建议迁移目标不只是“把 `.vue` 改成 `.tsx`”,而是 **整体对齐前端工程组织方式**
- 路由层对齐 `React Router`
- 状态层对齐 `Zustand`
- 组件层逐步摆脱 `Element Plus`
- 页面层按业务模块分波次平替
- 最终目标是 **React-only**Vue 只允许作为短期过渡层存在,迁移完成后必须移除。
- 推荐路径是 **短期双栈过渡、按路由/页面壳分批平替、迁完即收口**,不建议一次性大爆炸重写。
## 2. 当前现状
### 2.1 zn-ai 当前 Vue 技术栈
| 维度 | 当前实现 | 关键路径 |
| --- | --- | --- |
| 应用入口 | Vue 根应用 | `zn-ai/src/main.ts` |
| 根组件 | `App.vue + router-view + keep-alive` | `zn-ai/src/App.vue` |
| 路由 | `vue-router` | `zn-ai/src/router/index.ts` |
| 状态管理 | `Pinia` | `zn-ai/src/stores/*` |
| UI 组件体系 | `Element Plus + 自定义 Vue 组件 + Tailwind` | `zn-ai/src/components/*` |
| 页面目录 | Vue 页面分散在 `src/pages/*` | `zn-ai/src/pages/*` |
| Electron 交互 | `window.api + hostapi:fetch + gateway:rpc` | `zn-ai/electron/*` `zn-ai/src/lib/*` |
| 样式 | `Tailwind v4 + 全局 CSS + Element Plus 主题` | `zn-ai/src/styles/*` |
### 2.2 ClawX 当前 React 参照栈
| 维度 | ClawX 做法 | 关键路径 |
| --- | --- | --- |
| 应用入口 | `main.tsx` + `HashRouter` | `ClawX/src/main.tsx` |
| 根组件 | `App.tsx` + `Routes/Route` | `ClawX/src/App.tsx` |
| 布局 | `MainLayout + Sidebar + TitleBar` | `ClawX/src/components/layout/*` |
| 状态管理 | `Zustand` | `ClawX/src/stores/*` |
| UI 组件体系 | `Radix + 自建 ui 组件 + Tailwind` | `ClawX/src/components/ui/*` |
| 页面目录 | 按页面模块划分 | `ClawX/src/pages/*` |
| API/Gateway | `host-api.ts` / `gateway-client.ts` / typed stores | `ClawX/src/lib/*` |
| 样式 | `globals.css + CSS variables + Tailwind utilities` | `ClawX/src/styles/globals.css` |
## 3. 迁移目标
### 3.1 技术目标
1. `zn-ai` Renderer 入口从 Vue 根应用切换为 React 根应用。
2. 路由系统从 `vue-router` 切换为 `react-router-dom`
3. 核心状态逐步从 `Pinia` 迁到 `Zustand`
4. 页面与通用组件逐步从 `.vue` 平替为 `.tsx`
5. UI 层逐步减少 `Element Plus` 依赖,最终以 Tailwind + React 组件为主。
6. Electron 主进程、preload、IPC、Host API 相关逻辑尽量保持不动,避免把“框架迁移”和“桌面能力迁移”绑死在同一波次。
### 3.2 业务目标
- 保持 `Home/Chat``Agents``Skills``Cron``Scripts``Setting``Login` 可持续可用。
- 在迁移过程中不影响 Electron 打包、启动、窗口控制、IPC 调用。
- React 平替后,后续功能开发可以直接复用 ClawX 的 React 组织方式与组件思想。
## 4. 推荐迁移策略
## 4.1 不推荐:大爆炸式重写
特点:
- 一次性删除 Vue 根应用
- 一次性切到 React
- 所有页面同步重写
问题:
- 风险最高
- 回归面最大
- 业务停滞时间最长
- 很难快速验证 Electron 集成链路是否稳定
## 4.2 推荐:短期双栈过渡、分波次平替
特点:
- 在同一仓库临时同时支持 `@vitejs/plugin-vue``@vitejs/plugin-react`
- 先把 React 根应用、路由、布局、状态基建搭起来
- 再按页面分批把 Vue 页面平替成 React 页面
- React 接管默认入口后,立即进入 Vue 清退阶段
- 最后删除 Vue 页面、Vue store、Vue Router、Element Plus 与 Vue 构建链
优点:
- 风险可控
- 可以边迁移边交付
- 页面出现问题时回滚范围小
- 更适合 `zn-ai` 这种 Electron 桌面应用
边界要求:
- 双栈只用于迁移窗口期,不作为长期架构存在
- Phase 2 之后默认 Renderer 入口必须是 React
- Phase 3 起禁止新增 Vue 页面、Vue store、Element Plus 依赖
- Phase 5 必须完成 Vue 依赖与 Vue 代码清退,否则不算迁移完成
### 4.3 推荐迁移粒度
建议按这个粒度迁移:
1. 应用壳:入口、路由、主布局、标题栏、侧边栏
2. 核心页面:`Home/Chat`
3. 平台页面:`Agents``Setting`
4. 工具页面:`Skills``Cron``Scripts`
5. 低频或独立页面:`Knowledge``Login`
6. 最后移除 Vue 运行时与旧依赖
不建议按“单个小组件岛”零散迁移,因为:
- `zn-ai` 的页面级状态和路由耦合很重
- `Layout + SideMenus + 页面容器 + store` 是一整套
- 组件岛太细会让 Vue/React 互相嵌套,维护复杂度更高
### 4.4 终态约束
最终态不是 “Vue/React 双栈长期共存”,而是:
- Renderer 只保留 React 入口
- 路由只保留 `react-router-dom`
- 状态层只保留 React 可用的 store 体系
- UI 只保留当前视觉风格对应的 React 组件实现
- `vue``vue-router``pinia``element-plus``@vitejs/plugin-vue` 从生产依赖与构建链中移除
## 5. 工程平替方案
### 5.1 目录策略
推荐迁移期间采用双目录:
```text
src/ # 保留现有 Vue 代码
src-react/ # 新增 React 代码
```
或者更偏最终态的方式:
```text
src/
react/
electron/
shared/
```
更推荐第一种,原因是:
- 对当前工程侵入更小
- 平替期间边界更清晰
- 方便按页面对照迁移
但这个目录策略只服务于迁移期。最终收口时应执行以下动作之一:
-`src-react/` 合并回最终 Renderer 目录
- 或者删除旧 `src/` 中仅服务 Vue 的前端代码,只保留共享与 Electron 代码
### 5.2 构建策略
建议分两步:
1. 先在 `vite.config.ts` 里加入 `@vitejs/plugin-react`
2. 保留 `plugin-vue` 一段时间,直到最后一个 Vue 页面被移除
迁移初期目标不是删 Vue而是
- 先让 React 页面可以在 Electron Renderer 中跑起来
- 再让 React 尽快接手默认入口
构建收口要求:
- 默认启动入口一旦切到 React就不再新增任何 Vue 侧能力开发
- 最后一阶段必须移除 `@vitejs/plugin-vue`
- 打包与开发脚本最终只保留 React 所需链路
### 5.3 状态管理策略
| 当前 | 目标 | 建议 |
| --- | --- | --- |
| `Pinia` | `Zustand` | 新 React 页面只写 Zustand不再新增 Pinia store |
| 旧 Pinia store | 过渡兼容 | 迁移期间允许 React 通过桥接层复用部分现有逻辑 |
| 领域状态 | 切分迁移 | 优先迁移 `chat/providers/theme/locale/settings` |
推荐做法:
- 对每个核心领域新增 React 版 store
- 在短期内允许 Pinia 与 React store 并存
- 页面迁走后,再删除对应 Pinia store
- 从 Phase 3 开始禁止新增 Pinia 代码
### 5.4 UI 组件策略
| 当前 | 目标 | 建议 |
| --- | --- | --- |
| `Element Plus` | `Tailwind + React 组件` | 不直接一比一平替 Element Plus 组件 API |
| `Vue 单文件组件` | `TSX 组件` | 先迁页面壳,再抽通用组件 |
| Tailwind 样式 | 保留 | 继续沿用颜色、间距、布局 token |
建议:
- 不要把 `Element Plus` 在 React 中“硬套”一层兼容壳
- 更适合借鉴 ClawX 的做法,逐步建设 `src-react/components/ui/*`
- 先做基础组件Button、Input、Dialog、Tabs、Tooltip、Dropdown、Toast
### 5.5 共享能力策略
以下模块尽量不重写,只做前端适配:
- `electron/main.ts`
- `electron/preload/*`
- `electron/gateway/*`
- `src/lib/host-api.ts` 的底层契约
- `src/lib/gateway-client.ts` 的底层契约
- 绝大部分 `electron/service/*`
换句话说:
- 框架迁移主要发生在 Renderer
- 主进程和 Electron 基础设施尽量保持稳定
## 6. 页面迁移优先级
### 6.1 P0先迁基础壳
- `App.vue`
- `src/main.ts`
- `src/router/index.ts`
- `src/components/Layout/index.vue`
- `src/components/SideMenus/index.vue`
- `src/components/Layout/TitleBar/index.vue`
原因:
- 这是 React 页面承接的运行底座
- 不先迁应用壳,后面页面只能继续挂在 Vue 下
### 6.2 P1高价值页面
- `src/pages/home/index.vue`
- `src/pages/home/ChatBox.vue`
- `src/pages/home/ChatHistory.vue`
- `src/pages/home/components/chat/*`
- `src/stores/chat.ts`
- `src/stores/providers.ts`
原因:
- 首页/对话页是使用频率最高的模块
- 同时它也是最能直接复用 ClawX React 经验的地方
### 6.3 P2管理页面
- `src/pages/agents/index.vue`
- `src/pages/setting/index.vue`
- `src/pages/skills/index.vue`
- `src/pages/cron/index.vue`
- `src/pages/scripts/index.vue`
### 6.4 P3低频与收尾页面
- `src/pages/knowledge/index.vue`
- `src/pages/login/index.vue`
- 零散公用组件
- Vue/Pinia/Element Plus 清理
## 7. 分阶段实施计划
| 阶段 | 目标 | 主要产出 | 退出标准 |
| --- | --- | --- | --- |
| Phase 0 | 冻结迁移边界 | 迁移文档、路由清单、页面资产清单、Vue 退场清单 | 团队对范围、命名、目录、状态策略与 Vue 退场标准达成一致 |
| Phase 1 | 建短期双栈基建 | React 依赖、React 入口、临时双栈 Vite 配置 | Electron 中可启动 React 根页面 |
| Phase 2 | React 接管应用壳 | React `App`、React Router、MainLayout、Sidebar、TitleBar、默认入口切换 | Vue 根壳退出默认路径React 成为默认 Renderer |
| Phase 3 | 平替核心页 | Home/Chat 与核心 store 迁到 React | 主路径用户完全走 ReactVue 不再承接核心流程 |
| Phase 4 | 平替剩余页面 | Agents/Setting/Skills/Cron/Scripts/Knowledge/Login 迁到 React | 所有用户可见主页面全部脱离 Vue |
| Phase 5 | Vue 退场与依赖清理 | 删除 `.vue` 页面、Pinia/Vue Router/Element Plus 依赖与构建链 | 项目代码库不再依赖 Vue 运行时与 Vue 构建插件 |
| Phase 6 | 回归与交付 | 回归测试、打包验证、文档更新 | Dev/Build/Package 全链路稳定React-only 终态成立 |
## 8. sub-agent 数量估算
### 8.1 标准推荐编制
- 架构收口 sub-agent`1`
- 功能迁移 sub-agent`5`
- Vue 清退 sub-agent`1`
- 集成验收 sub-agent`1`
- 标准总数:`8`
这是最适合当前 `zn-ai` 体量的推荐方案,能覆盖:
- React-only 架构冻结
- 应用壳迁移
- 状态与通信层迁移
- 视觉样式与通用组件平替
- 高复杂页面迁移
- Vue 退场
- 联调验收
### 8.2 扩展并行编制
- 架构收口 sub-agent`1`
- 功能迁移 sub-agent`6`
- Vue 清退 sub-agent`1`
- 集成验收 sub-agent`1`
- 扩展总数:`9`
适用于你希望更快并行推进、并把页面迁移与 Vue 清退准备拆得更细的情况。
### 8.3 最小可行编制
- 架构收口 sub-agent`1`
- 功能迁移 sub-agent`4`
- Vue 清退与集成验收由主协调 agent 兼任
- 最小总数:`5`
这个方案能做,但节奏会更紧,回归与清尾风险更高。
### 8.4 为什么比“只迁聊天页”需要更多 sub-agent
这次不是单一页面迁移,而是:
- 前端框架替换
- 路由替换
- 状态管理替换
- UI 体系替换
- 页面级别平替
- Electron Renderer 构建链调整
因此复杂度明显高于单一业务模块迁移。
## 9. 推荐 sub-agent 分工
### 9.1 标准 8-agent 分工
| 角色 | 数量 | 负责范围 | 建议文件所有权 |
| --- | --- | --- | --- |
| A1React-only 架构收口 | 1 | 冻结迁移边界、禁止新增 Vue 扩面、维护 Vue 退场清单 | 只读分析,不改文件 |
| M1构建与入口切换 | 1 | React 依赖、Vite、Renderer 入口切换、保留短期双栈兜底 | `package.json` `vite.config.ts` `tsconfig*` `src/main.ts` `src/framework.ts` |
| M2应用壳与路由 | 1 | React `App`、React Router、布局、标题栏、侧栏并保持当前视觉风格 | `src-react/App.tsx` `src-react/router/*` `src-react/components/layout/*` |
| M3共享基础设施 | 1 | i18n、theme、host-api、gateway-client、window api 类型桥接 | `src-react/lib/*` `src-react/stores/*` `src-react/i18n/*` `src-react/types/*` |
| M4Home/Chat 主链路 | 1 | Home、Chat、ChatHistory、聊天 store、对话组件保持当前 UI 布局与交互 | `src-react/pages/Home/*` `src-react/components/chat/*` `src-react/stores/chat/*` |
| M5非聊天页面平替 | 1 | Agents、Setting、Skills、Cron、Scripts、Knowledge、Login 等页面平替,视觉沿用当前实现 | `src-react/pages/Agents/*` `src-react/pages/Setting/*` `src-react/pages/Skills/*` `src-react/pages/Cron/*` `src-react/pages/Scripts/*` `src-react/pages/Knowledge/*` `src-react/pages/Login/*` |
| C1Vue 清退与依赖下线 | 1 | 删除 `.vue` 页面、Pinia/Vue Router/Element Plus、清理 Vue 构建链与过渡文件 | `src/*.vue` `src/router/*` `src/stores/*` `vite.config.ts` `package.json` |
| I1联调与验收 | 1 | 回归、打包验证、迁移文档回填、React-only 验收 | 测试脚本、验收记录、迁移记录 |
### 9.2 扩展 9-agent 分工
如果采用扩展并行编制,可以把标准方案里的 `M5` 再拆成两组:
- 迁移 M5平台与设置页
- 迁移 M6技能与工具页
这样页面并行度更高,更适合在 React 接管默认入口后快速清空剩余 Vue 页面。
### 9.3 当前阶段继续执行的推荐编组
如果从当前阶段继续往下推进,推荐立即投入这 `4` 个执行向 sub-agent再由主协调 agent 持续整合:
- `Gibbs`:负责 `M1`,继续把默认入口、构建配置和 Vue 兜底边界收紧,禁止双栈长期化。
- `Mendel`:负责 `M2 + M5`,优先把应用壳、侧栏、标题栏和非聊天页面按当前视觉样式迁到 React。
- `Dalton`:负责 `M3`,继续打通 React 侧 i18n、theme、host-api、gateway-client 与 settings store。
- 新增 `C1/M4` 组合 worker优先迁 `Home/Chat` 主链路,并同步维护 Vue 退场清单,避免聊天页迁完后又回头返工。
## 10. 推荐并行波次
| 波次 | 并行 sub-agent | 说明 |
| --- | --- | --- |
| Wave 1 | A1 | 先冻结 React-only 边界、Vue 退场标准与视觉复用策略 |
| Wave 2 | M1 + M2 + M3 | 一边搭建 React 运行底座,一边准备共享桥接层,并让 React 接手默认入口 |
| Wave 3 | M4 + M5 | 核心页与剩余页面并行平替,要求沿用当前视觉样式 |
| Wave 4 | C1 + I1 | 集中执行 Vue 清退、构建链收口、联调与验收 |
如果采用扩展 9-agent 方案,则 `Wave 3` 可改为:
- `M4 + M5 + M6` 并行
- `C1` 提前介入维护 Vue 删除清单
- `I1` 提前介入做持续验收
## 11. 文件级拆分建议
### 11.1 M1构建与短期双栈基建
- `zn-ai/package.json`
- `zn-ai/vite.config.ts`
- `zn-ai/tsconfig.app.json`
- `zn-ai/tsconfig.json`
### 11.2 M2应用壳与路由
- `zn-ai/src-react/main.tsx`
- `zn-ai/src-react/App.tsx`
- `zn-ai/src-react/router/*`
- `zn-ai/src-react/components/layout/*`
### 11.3 M3共享基础设施
- `zn-ai/src-react/lib/host-api.ts`
- `zn-ai/src-react/lib/gateway-client.ts`
- `zn-ai/src-react/lib/*`
- `zn-ai/src-react/i18n/*`
- `zn-ai/src-react/stores/settings.ts`
### 11.4 M4Home/Chat
- `zn-ai/src-react/pages/Home/*`
- `zn-ai/src-react/components/chat/*`
- `zn-ai/src-react/stores/chat/*`
### 11.5 M5非聊天页面平替
- `zn-ai/src-react/pages/Agents/*`
- `zn-ai/src-react/pages/Setting/*`
- `zn-ai/src-react/pages/Login/*`
- `zn-ai/src-react/pages/Skills/*`
- `zn-ai/src-react/pages/Cron/*`
- `zn-ai/src-react/pages/Scripts/*`
- `zn-ai/src-react/pages/Knowledge/*`
### 11.6 C1Vue 清退与依赖下线
- `zn-ai/src/main-vue.ts`
- `zn-ai/src/router/*`
- `zn-ai/src/stores/*`
- `zn-ai/src/components/**/*.vue`
- `zn-ai/src/pages/**/*.vue`
- `zn-ai/package.json`
- `zn-ai/vite.config.ts`
### 11.7 扩展方案 M6技能与工具页
- `zn-ai/src-react/pages/Skills/*`
- `zn-ai/src-react/pages/Cron/*`
- `zn-ai/src-react/pages/Scripts/*`
- `zn-ai/src-react/pages/Knowledge/*`
## 12. 主要风险
| 风险 | 说明 | 建议 |
| --- | --- | --- |
| Vue/React 双栈期间复杂度上升 | 两套路由、样式、状态会短期并存 | 严格限定过渡期目录与职责边界,并对双栈设置明确退出时间点 |
| Element Plus 替换成本被低估 | 不是只替换组件,还会影响交互与样式结构 | 先迁页面壳和逻辑,再逐步建设 React UI 库 |
| Pinia 逻辑复制导致状态漂移 | 同一业务状态在 Vue/React 两边各维护一套容易分叉 | 核心领域先做桥接层,明确单一真源 |
| 页面迁移顺序不当 | 先迁低价值页会拉长工期,主路径收益低 | 先壳后首页,再平台页 |
| 打包链路回归 | Electron Renderer 切换入口后容易影响 dev/build/package | M1 和 I1 都要覆盖打包验证 |
## 13. 验收标准
- React 入口可以作为默认 Renderer 启动入口。
- 主布局、路由、标题栏、侧边导航全部由 React 承接。
- `Home/Chat``Agents``Setting``Skills``Cron``Scripts` 至少完成 React 版主路径迁移。
- Electron IPC、Host API、Gateway 调用在 React 页面中保持可用。
- 迁移完成后,项目必须移除 `vue``pinia``vue-router``element-plus``@vitejs/plugin-vue`
- `pnpm dev``pnpm build`、打包主流程可正常运行。
## 14. 最终建议
- **推荐方案**:以 `React-only` 为唯一终态,短期双栈仅作为过渡。
- **标准推荐 sub-agent 数量**`8` 个。
- **扩展并行数量**`9` 个。
- **最小可行数量**`5` 个。
- **最重要的执行原则**:先让 React 接管默认入口,再迁高价值页面,随后立即清退 Vue。
从投入产出比来看,最值得优先平替的是:
1. 应用壳与路由
2. Home/Chat
3. Agents/Setting
只要这三块完成,`zn-ai` 就已经从“Vue 项目”实质性切到“React 项目”了;剩余工作不再是“是否保留 Vue”的讨论而是明确执行 Vue 清退与 React-only 收口。