219 lines
14 KiB
Markdown
219 lines
14 KiB
Markdown
# 复刻项目技术选型推荐(0.6.29 基线)
|
||
|
||
> 前置结论:我们的目标不是从零重写,而是**以当前 0.6.29 代码为底子魔改**。
|
||
> 因此选型分两个维度:
|
||
> 1. **沿用** —— 原项目已经验证过、且替换成本高的部分,直接用;
|
||
> 2. **重做/新增** —— 原项目写得烂、或我们不需要的部分,才考虑换。
|
||
>
|
||
> 对接 Hermes 的方案单独在第 4 节说明(这是核心,也是你让我把关的部分)。
|
||
|
||
---
|
||
|
||
## 1. 分层总览
|
||
|
||
| 层 | 推荐方案 | 决策 | 理由 |
|
||
|---|---|---|---|
|
||
| 前端框架 | Vue 3 + `<script setup>` TS | **沿用** | 原项目 27 个视图全是 Vue 3,换框架 = 全部重写,没有收益 |
|
||
| 构建工具 | Vite 8 | **沿用** | 快、零配置争议,原项目已调好(含代理、多配置文件) |
|
||
| 前端状态 | Pinia | **沿用** | Vue 官方标配,13 个 store 结构清晰 |
|
||
| UI 组件库 | **换库(已确认)** | ❌ 弃用 Naive UI | 见第 2 节,具体库待拍板 |
|
||
| 路由 | Vue Router(hash 模式) | **沿用** | hash 路由对桌面端 / file:// 场景友好 |
|
||
| 后端运行时 | Node.js ≥ 23 + TypeScript | **沿用** | 与前端同语言,agent-bridge 的 Node 客户端、Socket.IO 编排全在 TS 里 |
|
||
| Web 框架 | Koa 2 | **沿用** | 见第 3 节;换 Fastify 收益低、迁移 46 个路由文件成本高 |
|
||
| 实时通信 | Socket.IO | **必须沿用** | `/chat-run` 命名空间是聊天核心协议,见第 4 节 |
|
||
| 数据库 | SQLite(better-sqlite3) | **沿用** | local-first 单机场景,零运维;原项目有完整 schema 与迁移 |
|
||
| 桌面端 | Electron | **❌ 已确认砍掉** | 砍 packages/desktop 整包,见第 2.1 节影响面 |
|
||
| 测试 | Vitest + Playwright | **沿用** | 原项目已有大量测试基建可复用 |
|
||
| Python 桥 | CPython 子进程 + JSON over socket | **必须沿用** | Hermes 对接的唯一正道,见第 4 节 |
|
||
|
||
---
|
||
|
||
## 2. 已确认的结构性决策
|
||
|
||
### 2.1 砍掉桌面端(已确认)
|
||
|
||
- 删除 `packages/desktop` 整包,以及根 workspace 引用、desktop 相关 scripts、CI 打包 workflow;
|
||
- 连带死亡的代码(无需保留):系统托盘、自动更新、开机自启、捆绑运行时打包脚本、自定义标题栏、桌面通知、登录态注入、**`/desktop-pet` 独立桌宠窗口**(透明置顶窗口是 Electron 专用);
|
||
- 连带必须处理的依赖缺口:
|
||
- **Hermes CLI 不再捆绑**:运行环境改为「用户自装 Python + hermes-agent」,通过 `HERMES_BIN` 环境变量或启动参数指定 hermes 可执行文件路径;缺失时 UI 给出引导提示(原 `hermes-path` 逻辑保留,去掉 bundled 路径推断);
|
||
- **Node 运行方式**:从 Electron 内嵌服务改为纯 `node` / `npm start` 启动(可选再加个 `pkg`/`bun` 单文件打包,不引入新框架);
|
||
- 桌宠系统随 P 组砍除(`/desktop-pet` 路由、Petdex、pet-state socket 一并删除)。
|
||
- Docker 部署路径不受影响(本就有 server 镜像)。
|
||
|
||
### 2.2 IM 频道保留(已确认)
|
||
|
||
- K 组 10 平台频道配置 + gateway 守护进程管理(autostart/锁文件/per-profile)全部沿用;
|
||
- 注意:gateway 自启原逻辑有一半长在 Electron 生命周期里,需迁到 Koa 启动钩子。
|
||
|
||
### 2.3 i18n 只保留中英双语(已确认)
|
||
|
||
- locale 目录只留 `zh` 与 `en`,删除其余 8 个语种文件与语言切换项;
|
||
- **硬规则**(继承原项目):新增/改动的用户可见字符串必须同时写入 zh 与 en 两个 locale 文件,施工蓝图里会加检查项。
|
||
|
||
### 2.4 品牌去标识(已确认)
|
||
|
||
新版本中不得出现 `ekko` 与 `hermes-web-ui` 字样:
|
||
|
||
- `package.json` name:`hermes-web-ui` → 新包名(**待定,见文末**);
|
||
- 窗口标题、侧边栏 Logo/产品名、登录页、更新弹窗、Docker 镜像名、GitHub workflow 名、README/文档统一替换;
|
||
- 代码内标识符:`EkkoAgent` 类/包名、`ekko-agent` 目录、路径常量、i18n key(如 `ekko.*`)→ **J 组已确认整组砍除,`ekko` 字样随之全部消失**;
|
||
- `Hermes` 字样**不在禁用列表**:它指被对接的 Agent 本体(`hermes CLI`、`HERMES_HOME` 等),技术上无法回避,全部保留。
|
||
|
||
## 2b. UI 组件库:换库(已确认,具体库待拍板)
|
||
|
||
原 Naive UI 弃用。换库的**真实成本不在装包,在于 27 个视图全部要动**——Naive 的 `NXxx` 组件、`NConfigProvider` 主题体系会渗透进每个页面。因此策略是:
|
||
|
||
1. **一次性换库 + 逐视图迁移**,不搞双库共存(双库样式割裂,比换库本身更丑);
|
||
2. 迁移顺序:先换 3 个样板页(登录、设置、历史)定风格基线 → 再核心聊天页 → 其余页面批量;
|
||
3. 原项目的**样式定制层**(主题变量、明暗切换、`themeOverrides` 思路)用新库的等价主题体系重建,这是"改掉官方丑风格"的主战场;
|
||
4. 聊天页的**自绘部分**(虚拟滚动消息列表、markdown 渲染、代码高亮、轨迹时间线)本来就没用组件库,换库对它们零影响——这是我们的运气。
|
||
|
||
候选库对比见文末问题,待你拍板后写入施工蓝图。
|
||
|
||
## 3. 后端:Koa 沿用,不要上 NestJS
|
||
|
||
- 原项目结构已经是分层的:`routes → controllers → services → db`,规则写在 ARCHITECTURE.md 里,问题只在个别文件膨胀,不在框架。
|
||
- 换 Fastify/NestJS 的收益(性能、DI、装饰器)在**单机自托管工具**场景里几乎为零;成本是 46 个路由文件 + 全部中间件重写。
|
||
- 真正值得在魔改中做的后端改进(属于"顺手修",不属于换框架):
|
||
- 路由保持薄,新逻辑进 services;
|
||
- 继续用 `execFile` + 参数数组调 hermes CLI(禁止 shell 拼字符串,原项目硬规则);
|
||
- Socket.IO 事件命名保持 `/chat-run` 协议不变,避免前端联动改动。
|
||
|
||
## 4. Hermes 对接方案(核心,把关结论)
|
||
|
||
原项目有**三条通道**,复刻时的取舍如下:
|
||
|
||
### 4.1 Agent Bridge(Python 子进程 + Socket)— ✅ 必须完整保留
|
||
|
||
```
|
||
浏览器 ──Socket.IO──> Koa/Node server ──JSON over Unix socket──> Python 子进程
|
||
└─ hermes-agent 的 run_agent.AIAgent
|
||
```
|
||
|
||
**为什么这是唯一正确的主通道:**
|
||
|
||
1. **零拷贝接入 Hermes 全部能力**:模型配置、工具、技能、审批、会话 DB、上下文压缩,全部由 `AIAgent` 在 Python 侧自己解析 hermes 的 `config.yaml`,Node 侧只传 `session_id + message`。任何绕开它的方案(比如自己在 Node 里重新实现一遍工具调用/会话管理)都是在重写 hermes-agent,不可行。
|
||
2. **进程内实例化 = 快且可流式**:不用每次聊天冷启动 CLI,delta 流式回传,支持中断(interrupt)、审批(approval)、澄清(clarify)、断线重挂(reattach)。
|
||
3. **原项目已替我们踩完了坑**:桥池(profile worker 池)、IPC/TCP 双传输、Windows 兼容、错误脱敏(redact)、就绪探测与自动恢复,这些都在 `agent-bridge/` 下有实现和测试。
|
||
|
||
**魔改时的把关红线:**
|
||
- ❌ 不要改成"每条消息 fork 一个 `hermes chat` CLI 进程"——冷启动慢、无法流式、无法审批交互;
|
||
- ❌ 不要试图用 hermes 的 HTTP gateway 替代桥做聊天——gateway 面向 IM 频道(telegram 等),聊天语义(队列/审批/压缩事件)对不上;
|
||
- ✅ 只允许在桥的 **JSON 协议上加字段**(例如 reasoning effort 覆盖,原项目就是这么做的 local patch);
|
||
- ✅ `agent-bridge/python/` 整个目录视为**只读 vendored 代码**,除非你确实看懂了 `bridge_pool.py` 的会话池逻辑再动。
|
||
|
||
### 4.2 Hermes CLI(execFile)— ✅ 保留,用于管理面
|
||
|
||
`sessions export/delete/rename`、`profile` CRUD、`logs`、`gateway start/stop`、`curator pin`、`setup --reset`。这些是低频管理操作,走 CLI 子进程最合适(hermes 自己保证了这些命令的稳定性)。
|
||
**把关点**:所有调用必须走 `hermes-process.ts` 的 `execHermesWithBin`(参数数组 + `HERMES_BIN` 解析),禁止散落的 `exec('hermes ...')`。
|
||
|
||
### 4.3 Gateway 守护进程管理 — ⚠️ 按需保留
|
||
|
||
只有当你需要 telegram/discord 等 IM 频道接入时才需要管 gateway 生命周期(锁文件、pid、per-profile 启停)。**如果你只要 Web 界面,这块可以整块砍掉**——聊天不依赖它。
|
||
|
||
### 4.4 数据归属原则 — ✅ 必须继承
|
||
|
||
- Hermes `state.db` = **只读**,只用于历史 API;
|
||
- Web UI 自己的 SQLite = 会话/消息/用量的**唯一可写存储**;
|
||
- 两边不搞启动时导入同步(原项目明确禁用并写了注释,理由成立)。
|
||
- Profile 隔离靠给子进程注入 `HERMES_HOME`,不要改。
|
||
|
||
---
|
||
|
||
## 5. 明确不推荐的选项
|
||
|
||
| 方案 | 为什么不要 |
|
||
|---|---|
|
||
| Node 直连 hermes 的 Python 内部(pybind/嵌入) | hermes 依赖 Python 生态,嵌入即噩梦;子进程隔离才能独立重启/崩溃恢复 |
|
||
| 把桥改成 gRPC/protobuf | JSON over socket 够用,换协议 = Node/Python 两端重写,零收益 |
|
||
| PostgreSQL 替代 SQLite | 单机自托管,多一个运维依赖,违背 local-first |
|
||
| Next.js / SSR 前端 | 纯客户端仪表盘 + Socket.IO,SSR 无意义 |
|
||
| 微服务拆分 | 单人魔改项目,拆分只会增加部署成本 |
|
||
|
||
---
|
||
|
||
## 6. 依赖版本策略
|
||
|
||
- 锁定当前 `package-lock.json`,`npm ci --ignore-scripts` 安装,**不升级任何依赖**(你特意要旧版底座);
|
||
- 新增依赖遵循:能不加就不加,必须加时选与现有栈同生态的(Vue 系 / Node 内置优先);
|
||
- Node 版本要求 `>=23`(package.json engines),与原项目一致。
|
||
|
||
---
|
||
|
||
## 7. 决策记录与遗留问题
|
||
|
||
### 已拍板
|
||
|
||
| 决策点 | 结论 |
|
||
|---|---|
|
||
| 桌面端 Electron | ❌ 砍掉(含托盘/自动更新/捆绑运行时/桌宠窗口) |
|
||
| IM 频道 + gateway 管理 | ✅ 保留 |
|
||
| I 编程代理(Claude Code / Codex 代理 + stream-tee 网关) | ❌ 砍掉(各有官方 UI,run-chat 只留 hermes 桥) |
|
||
| J ekko-agent(内置自有 Agent) | ❌ 砍掉(品牌 `ekko` 冲突随之解决) |
|
||
| P 桌宠系统 | ❌ 砍掉(浪费资源) |
|
||
| 其余功能组(B~H、K~O、Q) | ✅ 全部沿用 |
|
||
| UI 组件库 | ❌ 弃用 Naive UI,换库(库种待定) |
|
||
| ArkScope | ✅ 确认采用:vendor 源码,作颜值特效层(个人用、不分发、私人仓库) |
|
||
| i18n | 仅中文 + 英文 |
|
||
| 品牌 | 禁用 `ekko`、`hermes-web-ui` 字样;`Hermes` 保留 |
|
||
| 依赖 | 锁定 lockfile 不升级 |
|
||
|
||
### 遗留待定(下一步聊完定)
|
||
|
||
1. **新包名/产品名**(不能叫 ekko 或 hermes-web-ui);
|
||
2. **基础组件库选哪个**(ArkScope 的评估见第 8 节:它不能当基础库,需要另配一个)。
|
||
|
||
---
|
||
|
||
## 8. ArkScope 可行性评估(针对 `github.com/triplepiers/ArkScope`)
|
||
|
||
**结论:不能作为本项目的基础组件库;可以作为「风格特效层」并入,且必须搭配一个真正的基础组件库。**
|
||
|
||
### 8.1 它是什么
|
||
|
||
鹰角(明日方舟/终末地)游戏官网风格的**装饰性 Vue 3 组件集**,全部组件清单:
|
||
|
||
| 组件 | 作用 |
|
||
|---|---|
|
||
| `EndfieldSidebar` | 终末地风格导航栏(悬停展开、移动端适配) |
|
||
| `ScrambleTitle` | 塞壬唱片风文字解码标题动画 |
|
||
| `IsometricWave` | 类亚克力质感 Hover 交互 |
|
||
| `GameplayAlbum` / `NoticeCarousel` / `OperatorCarousel` / `ArknightsOperatorCarousel` | 四种风格轮播图 |
|
||
| `FullScreenNavigator` | 全屏滚动 Section 切换 |
|
||
| `Particle2D` / `Particle3D` | 2D/3D 粒子点云(3D 依赖 three.js) |
|
||
| `NewsList` / `OperatorList` | 公告/列表排版组件 |
|
||
|
||
### 8.2 为什么不能当基础库
|
||
|
||
1. **没有基础 UI 控件**:按钮、输入框、下拉、弹窗、表格、表单、Tabs、Toast、日期选择——一个都没有。而我们 27 个视图里到处是这类控件,Naive UI 换掉后必须有东西接住;
|
||
2. **不是可安装的库**:`package.json` 里 `private: true`、version `0.0.0`、构建脚本是应用构建而非 library build,**未发布到 npm** —— 只能 vendor(把 `src/components` 源码拷进来维护),拿不到版本升级支持;
|
||
3. **面向展示型官网,不是管理后台**:组件全是官网 landing 页的视觉件,与"仪表盘/表单/数据表"场景错配;
|
||
4. **素材版权**:仓库明确声明第三方素材(© 鹰角网络)不在开源许可内 —— 个人魔改无所谓,但要知道这些素材不能用于公开分发;
|
||
5. 依赖 three.js(仅 Particle3D 用),引入时注意按需,别让聊天页背这个包。
|
||
|
||
### 8.3 定位与用法(✅ 已确认,2026-10-15)
|
||
|
||
**双层策略:基础组件库(管功能)+ ArkScope(管颜值)。已确认采纳。**
|
||
|
||
使用前提已明确:**纯个人使用、不分发、只进私人仓库** —— 鹰角素材版权与 `private: true` 不可安装的问题都不构成障碍(vendor 源码进仓库即可)。
|
||
|
||
- **基础组件库**(待拍板,候选见 8.4):承担全部表单/表格/弹窗/导航等交互控件,全量替换 Naive UI;
|
||
- **ArkScope**:vendor 源码进仓库,只用于**装饰性位面**——
|
||
- 登录页 / 首页的品牌标题(`ScrambleTitle`);
|
||
- 侧边栏若做风格化改造可参考 `EndfieldSidebar`(但我们的侧边栏信息密度高,直接套大概率要重写);
|
||
- Petdex / Journey 图谱页的展示性视觉(`Particle2D`、轮播)——Petdex 已随 P 组砍除,实际只剩 Journey 图谱页可用;
|
||
- ~~桌宠相关的展示动效~~(P 组已砍,不适用)。
|
||
- **明确不用**的场景:聊天页、管理表单页、数据表格页——这些地方特效组件只会碍事;
|
||
- 接入方式:源码 vendor 至 `packages/client/src/components/arkscope/`,不加 npm 依赖(它也装不了)。
|
||
|
||
### 8.4 基础组件库候选(仍待拍板)
|
||
|
||
| 候选 | 优点 | 缺点 |
|
||
|---|---|---|
|
||
| **Element Plus** | 生态最大、控件最全、中文文档、长得普通(但可深度定制主题) | 观感"公司后台",需要我们自己下功夫做主题 |
|
||
| **Arco Design Vue** | 字节系、设计感较好、控件全、支持主题定制 | 生态比 EP 略小 |
|
||
| **PrimeVue** | 主题系统强(Aura/Material 等多套)、tailwind 友好 | 中文资料少 |
|
||
| **shadcn-vue + Tailwind** | 完全可控、改样式零阻力、最能实现"自己的风格" | 无现成组件包,27 个视图的控件要逐个搬,成本最高 |
|
||
|
||
> 与 ArkScope 风格最搭的是 Element Plus / Arco(底子干净,套鹰角风主题变量即可);shadcn-vue 路线自由度最高但工时最长。
|