Import the client, server, skills, tests, and build scripts as the starting point for the rebuild, then trim the surfaces this project does not ship: Electron desktop packaging, the marketing website, and the ESP32 firmware tree. CI keeps the web build, e2e, lockfile, release, and Docker workflows. Rename the package and CLI entry points to hermes-ui, drop the prepare hook so npm ci no longer triggers a build, and drop the removed tsconfig and nodemon references. Rewrite AGENTS.md, ARCHITECTURE.md, DEVELOPMENT.md, and the READMEs so the documented package map and hard rules match this repository. reference_code/ is ignored: it is a read-only snapshot, not an input to the build.
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 路线自由度最高但工时最长。
|