Files
hermes-ui/docs/phases/phase_003.md
T
toor 1e9ea89d86
Build / build (push) Canceled after 0s
NPM Lockfile Check / npm ci --ignore-scripts (push) Canceled after 0s
Playwright / e2e (push) Canceled after 0s
chore: bootstrap hermes-ui skeleton from 0.6.29 snapshot
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.
2026-10-16 10:34:35 +08:00

6.5 KiB
Raw Blame History

Phase 003 — 砍 I 组(编程代理)+ J 组(ekko-agent)

项 值
目标 删除 Claude Code / Codex 编程代理与自有 Agent,聊天链路只走 Hermes 桥
前置 Phase 002 通过
产出 三条聊天链路(普通聊天 / 全局 Agent / 群聊)功能对等
参考 docs/03-施工蓝图.md §5

0. 为什么可以安全砍(已核实)

run-chat/index.ts 的 dispatch 结构:

ensureBridgeReadyForChatRun()
→ handleBridgeRun()                              ← 主路径,最先执行且 return
→ if (isEkkoAgentExecution(data)) handleEkkoAgentRun()   ← J 组
→ handleCodingAgentRun()                         ← I 组兜底
  • bridge 分支在最前且有 return,删掉后面两条不影响它
  • 全局 Agent 走 global-agent/server.ts → getChatRunServer().runAndWait(),砍 I/J 后自动只走桥
  • 群聊走 group-chat/agent-clients.ts 的 AgentBridgeClient 直连,与 I/J 无关

1. 功能任务 1 — 删文件

1.1 I 组

rm -rf packages/client/src/views/hermes/CodingAgentsView.vue
rm -f  packages/client/src/api/coding-agents.ts
rm -f  packages/server/src/routes/coding-agents.ts
rm -f  packages/server/src/routes/claude-code-proxy.ts
rm -f  packages/server/src/routes/codex-proxy.ts
rm -f  packages/server/src/controllers/coding-agents.ts
rm -f  packages/server/src/services/coding-agents.ts
rm -rf packages/server/src/services/agent-runner/     # 含 stream-tee 网关 + adapters

1.2 J 组

rm -rf packages/server/src/services/ekko-agent/
rm -f  packages/server/src/services/hermes/run-chat/handle-ekko-agent-run.ts

1.3 相关测试

rm -f tests/server/coding-agents-*.test.ts
rm -f tests/server/coding-agent-run-manager-windows.test.ts
rm -f tests/server/agent-runner-gateway.test.ts
rm -f tests/server/handle-coding-agent-run.test.ts
rm -f tests/client/coding-agent-api-modes.test.ts

先 ls tests/server/ | grep -i "coding\|agent-runner\|ekko" 拿到实际清单再删,别只按上面猜。


2. 功能任务 2 — server 路由层

packages/server/src/routes/index.ts:

  1. 删 codingAgentRoutes / claudeCodeProxyRoutes / codexProxyRoutes 的 import
  2. 删对应的 app.use(...)(在原文件 L64/65/79 附近)
  3. 保持 L78 那条注释的约束:本地 API 路由必须注册在 proxy 兜底路由之前

packages/server/src/controllers/hermes/sessions.ts:删代理相关字段。


3. 功能任务 3 — run-chat dispatch 简化(核心)

packages/server/src/services/hermes/run-chat/index.ts:

3.1 删 import

handle-coding-agent-run
handle-ekko-agent-run

3.2 删两个判定函数

isCodingAgentExecution()
isEkkoAgentExecution()

3.3 删 dispatch 分支

handleBridgeRun() 之后直接结束,删掉 isEkkoAgentExecution / handleCodingAgentRun 两条。

3.4 修 isWorking 判定(三处,最容易漏)

isCodingAgentExecution 同时被用于工作状态判定:

原行 原逻辑 改后
L289 state.isWorking = !isCodingAgentExecution(source, data) state.isWorking = true
L423 if (!isCodingAgentExecution(source, data)) { ... } 去掉条件,保留花括号内逻辑
L707 state.isWorking = !isCodingAgentExecution(source, data) state.isWorking = true

不要留空壳函数。行号以本项目 run-chat/index.ts 实际为准,用 grep -n isCodingAgentExecution 定位。

3.5 同目录其他文件

文件 改动
run-chat/types.ts 删 ChatCodingAgentId 类型及其引用
run-chat/session-command.ts 删代理分支
run-chat/load-state.ts 删代理分支
run-chat/abort.ts 删代理分支

4. 功能任务 4 — client 导航与视图

文件 改动
router/index.ts 删 name: 'hermes.codingAgents' 路由块
components/layout/AppSidebar.vue 删编程代理导航项
components/hermes/chat/SessionListItem.vue 删代理类型图标分支
components/hermes/chat/ChatInput.vue 删代理选择 UI
components/hermes/chat/ChatPanel.vue 删代理相关分支
components/hermes/chat/MessageList.vue 删代理消息渲染分支
components/hermes/chat/HistoryMessageList.vue 删代理消息渲染分支
components/hermes/usage/AgentBreakdown.vue 删 ekko / coding agent 分组
stores/hermes/chat.ts 删代理选择器 state 与 setter
shared/session-display.ts 删代理类型标签

5. 功能任务 5 — 工作流与用量

文件 改动
components/hermes/workflow/types.ts 删 coding_agent_id
components/hermes/workflow/WorkflowAgentNode.vue 删 agent 类型选择
views/hermes/WorkflowView.vue 删对应 UI
views/hermes/HistoryView.vue 删对应列
services/hermes/workflow-manager.ts 删 coding_agent_id 持久化
services/usage-recorder.ts 删 ekko / coding agent 用量归类

历史数据兼容:旧会话里可能存有 coding_agent_id。读侧改成「读到就忽略」,不做数据迁移。


6. 验收

6.1 命令

cd /Users/jack/source/MyProject/js/hermes-ui

# 残留检查
grep -rn "coding_agent\|codingAgent\|CodingAgent\|ekko-agent\|ekkoAgent\|EkkoAgent" \
  packages/ tests/ --include="*.ts" --include="*.vue" --include="*.json"
# 期望:零命中

npm run build
npm run test
npm run test:e2e

6.2 手工(三条链路必须逐条走)

  • 普通聊天:发消息 → 流式输出 → 完成
  • 全局 Agent:跑一条 → 走桥正常
  • 群聊:多 agent 房间发消息 → 路由正常
  • 会话列表不再出现代理类型图标
  • 用量页 AgentBreakdown 不再显示 ekko / coding 分组
  • 工作流页不再能选编程代理
  • 侧边栏无编程代理入口

7. 风险

# 风险 缓解
P3-1 isWorking 三处漏改 → 聊天状态卡死或一直转圈 grep -n isCodingAgentExecution 必须零命中后才算改完
P3-2 历史会话带 coding_agent_id 导致渲染报错 读侧容忍未知字段;手工造一条旧会话验证
P3-3 删 agent-runner/ 时误删共用工具 先 grep -rn "agent-runner" 确认引用方只在这两组内
P3-4 e2e 有用例依赖 coding-agents API npm run test:e2e 必跑,红了删对应用例
P3-5 AgentBreakdown 删分组后百分比除零 该组件有空态处理,确认无 NaN%

8. 完成标志

进入 Phase 004(砍桌面端 + 官网)。