14 KiB
复刻项目技术选型推荐(0.6.29 基线)
前置结论:我们的目标不是从零重写,而是以当前 0.6.29 代码为底子魔改。 因此选型分两个维度:
- 沿用 —— 原项目已经验证过、且替换成本高的部分,直接用;
- 重做/新增 —— 原项目写得烂、或我们不需要的部分,才考虑换。
对接 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 一并删除)。
- Hermes CLI 不再捆绑:运行环境改为「用户自装 Python + hermes-agent」,通过
- 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.jsonname: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 主题体系会渗透进每个页面。因此策略是:
- 一次性换库 + 逐视图迁移,不搞双库共存(双库样式割裂,比换库本身更丑);
- 迁移顺序:先换 3 个样板页(登录、设置、历史)定风格基线 → 再核心聊天页 → 其余页面批量;
- 原项目的样式定制层(主题变量、明暗切换、
themeOverrides思路)用新库的等价主题体系重建,这是"改掉官方丑风格"的主战场; - 聊天页的自绘部分(虚拟滚动消息列表、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
为什么这是唯一正确的主通道:
- 零拷贝接入 Hermes 全部能力:模型配置、工具、技能、审批、会话 DB、上下文压缩,全部由
AIAgent在 Python 侧自己解析 hermes 的config.yaml,Node 侧只传session_id + message。任何绕开它的方案(比如自己在 Node 里重新实现一遍工具调用/会话管理)都是在重写 hermes-agent,不可行。 - 进程内实例化 = 快且可流式:不用每次聊天冷启动 CLI,delta 流式回传,支持中断(interrupt)、审批(approval)、澄清(clarify)、断线重挂(reattach)。
- 原项目已替我们踩完了坑:桥池(profile worker 池)、IPC/TCP 双传输、Windows 兼容、错误脱敏(redact)、就绪探测与自动恢复,这些都在
agent-bridge/下有实现和测试。
魔改时的把关红线:
- ❌ 不要改成"每条消息 fork 一个
hermes chatCLI 进程"——冷启动慢、无法流式、无法审批交互; - ❌ 不要试图用 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 |
✅ 全部沿用 |
| UI 组件库 | ❌ 弃用 Naive UI,换库(库种待定) |
| ArkScope | ✅ 确认采用:vendor 源码,作颜值特效层(个人用、不分发、私人仓库) |
| i18n | 仅中文 + 英文 |
| 品牌 | 禁用 ekko、hermes-web-ui 字样;Hermes 保留 |
| 依赖 | 锁定 lockfile 不升级 |
遗留待定(下一步聊完定)
- 新包名/产品名(不能叫 ekko 或 hermes-web-ui);
- 基础组件库选哪个(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 为什么不能当基础库
- 没有基础 UI 控件:按钮、输入框、下拉、弹窗、表格、表单、Tabs、Toast、日期选择——一个都没有。而我们 27 个视图里到处是这类控件,Naive UI 换掉后必须有东西接住;
- 不是可安装的库:
package.json里private: true、version0.0.0、构建脚本是应用构建而非 library build,未发布到 npm —— 只能 vendor(把src/components源码拷进来维护),拿不到版本升级支持; - 面向展示型官网,不是管理后台:组件全是官网 landing 页的视觉件,与"仪表盘/表单/数据表"场景错配;
- 素材版权:仓库明确声明第三方素材(© 鹰角网络)不在开源许可内 —— 个人魔改无所谓,但要知道这些素材不能用于公开分发;
- 依赖 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 路线自由度最高但工时最长。