Files
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

413 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 007 — Arco 迁移:其余 20 视图批量
| 项 | 值 |
|---|---|
| 目标 | 全仓无 naive-ui;无第二 UI 库 |
| 前置 | Phase 006 通过 |
| 产出 | `grep -r "naive-ui" packages/client/src` 零命中 |
| 参考 | `docs/03-施工蓝图.md` §8.2 |
---
## 0. 批次划分原则
按**耦合度**分批,不按页面重要性。每批独立提交、独立验收,**任何一批都能停下来过夜**。
Phase 006 已经把最难的(流式 / 虚拟滚动 / 审批)趟平了,所以下面每批都是体力活。
---
## 1. 批次一览
| 批次 | 范围 | 特征 | 风险 |
|---|---|---|---|
| 7a | Settings / Profiles / Models / Logs | 纯表单 + 表格 | 低 |
| 7b | Skills / Plugins / McpManager / Memory | 卡片列表 + 抽屉 | 低 |
| 7c | Files / Terminal | 大量 DOM + xterm | **中** |
| 7d | Usage / Performance / SkillsUsage / Journey | 图表 / 图谱 + 数据表格 | 中 |
| 7e | Kanban / Jobs / Workflow / Devices | 拖拽 + 复杂交互 | 中高 |
| 7f | Channels / GroupChat / GlobalAgent | IM 频道 + 群聊 | 中高 |
| 7g | History / VersionPreview | 历史会话 | 低 |
**7f 排在 7e 之后**:群聊也是流式页,虽然比主聊天简单,但仍有 SSE + 增量渲染,靠近 006 的经验更划算。
---
## 2. 每批的标准动作(**7a 走一遍,之后照抄**)
### 2.1 开工前
```bash
cd /Users/jack/source/MyProject/js/hermes-ui
# 看这批有多少 naive 引用
grep -rc "naive-ui" <本批文件列表>
```
### 2.2 改法顺序
1. **先建/补 `docs/arco-mapping.md`** —— 本批遇到的 Naive 组件若表里没有,先补进去
2. **Provider 层先换**(`NMessageProvider` → `useMessage()` composable)
3. **容器 → 布局**(`NLayout` → `a-layout`)
4. **表单 → 控件**(`NForm` → `a-form`,逐个 `NFormItem`)
5. **表格 / 列表**(`NDataTable` → `a-table`,差异最大)
6. **交互层**(`NModal` `NDrawer` `NPopconfirm`)
7. **删除所有未用的 naive import**(这一步最容易漏,编译器会兜底)
### 2.3 收尾
```bash
grep -rn "naive-ui" <本批文件> # 期望零命中
npm run build
npm run test
npm run test:e2e
git commit -m "feat(ui): migrate <batch> views to Arco Design Vue"
```
### 2.4 每批完成定义(四条全满足)
- [ ] 本批文件 `grep -c naive-ui` 归零
- [ ] `npm run test` 通过
- [ ] e2e 对应用例通过
- [ ] 明暗双主题人工过一遍
---
## 3. 批次内容
### 3.1 批次 7a — 纯表单与表格(**先做这批打样**)
```
views/hermes/SettingsView.vue
views/hermes/ProfilesView.vue
views/hermes/ModelsView.vue
views/hermes/LogsView.vue
components/hermes/settings/** # 约 20 个组件,含 voice/ 子目录
components/hermes/profiles/** # 6 个
components/hermes/models/** # 约 12 个,含各种 OAuth 登录弹窗
components/hermes/settings/SettingRow.vue
components/layout/ModelSelector.vue
components/layout/ProfileSelector.vue
components/layout/LanguageSwitch.vue
components/layout/ThemeSwitch.vue
```
**本批特有难点**:
- `NForm` 的校验规则 API 与 `a-form` 不同,需写适配
```
naive: [{ required: true, message: '...' }]
arco: [{ required: true, message: '...' }] # 规则对象基本一致
但 field 绑定方式与 error 展示位置不同
```
- 各 OAuth 登录弹窗(`AnthropicLoginModal` `CodexLoginModal` `CopilotLoginModal` `GeminiLoginModal` `NousLoginModal` `XaiOAuthLoginModal`)—— 每个都是独立 Modal,改完逐个点
- `SettingRow.vue` 是所有设置项的骨架容器,先改它
**完成后必须过**:
```bash
tests/client/default-credential-prompt.test.ts
tests/client/copilot-login-modal.test.ts
tests/client/platform-card.test.ts
tests/client/profile-card-config-edit.test.ts
tests/client/provider-card-built-in-action.test.ts
tests/client/provider-base-url.test.ts
tests/client/display-settings.test.ts
tests/client/gateway-auto-start-settings.test.ts
tests/client/compression-settings 相关
```
---
### 3.2 批次 7b — 卡片列表与抽屉
```
views/hermes/SkillsView.vue
views/hermes/PluginsView.vue
views/hermes/McpManagerView.vue
views/hermes/MemoryView.vue
components/hermes/skills/** # 7 个
components/hermes/mcp/McpServerCard.vue
components/hermes/common/RouteLinkItem.vue
components/hermes/settings/MemorySettings.vue
components/hermes/settings/CompressionSettings.vue
```
**本批特有难点**:
- `SkillList` / `SkillDetail` / `SkillImportModal` / `SkillExternalDirsModal` 有复杂表单与文件树
- `PendingWriteApprovals.vue` 有审批交互(与 Phase 006 的审批同源)
**完成后必须过**:
```bash
tests/client/skills-view.test.ts
tests/client/skill-list.test.ts
tests/client/skill-detail-edit.test.ts
tests/client/plugins-view.test.ts
tests/client/pending-write-approvals.test.ts
tests/client/route-link-item.test.ts
```
---
### 3.3 批次 7c — 文件与终端(**别把 Arco 塞进来**)
```
views/hermes/FilesView.vue
views/hermes/TerminalView.vue
components/hermes/files/** # 9 个
components/hermes/chat/TerminalPanel.vue # 若 7a/7b 未改
composables/useDefaultWorkspace.ts
utils/file-path.ts
utils/hermes/kanban-assignees.ts
```
**本批特有难点(**本批最特殊**):
- **文件树** `FileTree.vue` / `FileList.vue` / `FileBreadcrumb.vue` 是**手写 DOM 结构 + CSS**,不要换成 Arco 的 `a-tree`——会丢掉自定义的文件类型图标、右键菜单、拖拽。
- **xterm.js** 终端是独立 DOM 树,**外面套任何 Arco 布局都可能引入尺寸问题**。终端容器用固定 flex + 原生 CSS。
- `FileContextMenu.vue` / `FilePreview.vue` / `FileEditor.vue` / `FileToolbar.vue` 涉及上传、预览、编辑
- 右键菜单:`a-trigger` 的 `trigger="contextmenu"`
**完成后必须过**:
```bash
tests/e2e/terminal.spec.ts
tests/client/file-tree-profile-scope.test.ts
tests/client/file-list-layout.test.ts
tests/client/file-context-menu.test.ts
tests/client/folder-picker-windows-drives.test.ts
tests/client/files-view-profile-config-route.test.ts
tests/client/file-path.test.ts
```
---
### 3.4 批次 7d — 图表与数据密度
```
views/hermes/UsageView.vue
views/hermes/PerformanceView.vue
views/hermes/SkillsUsageView.vue
views/hermes/JourneyView.vue
components/hermes/usage/** # StatCards DailyTrend ModelBreakdown AgentBreakdown
api/hermes/journey.ts
stores/hermes/usage.ts
```
**本批特有难点**:
- **这是 ArkScope 装饰层的第二个合法落点**:Journey 图谱的背景层可以用装饰位面。但**数据线、节点、文字仍必须原生渲染**,装饰只能垫在最底。
- 图表组件(若有 echarts / 自绘 SVG)**不要动**,只换外围容器
- `NDataTable` → `a-table` 在这里是重灾区(数据密度高、列多、有合计行)
- 表格横向滚动 + 固定列
**完成后必须过**:
```bash
tests/client/usage-components-cache-visuals.test.ts
tests/client/usage-view-period.test.ts
tests/client/usage-store.test.ts
tests/client/skills-usage-view.test.ts
```
---
### 3.5 批次 7e — 拖拽与复杂交互
```
views/hermes/KanbanView.vue
views/hermes/JobsView.vue
views/hermes/WorkflowView.vue
views/hermes/DevicesView.vue
components/hermes/kanban/** # 4 个
components/hermes/jobs/** # 4 个
components/hermes/workflow/** # 3 个
stores/hermes/kanban.ts
stores/hermes/jobs.ts
utils/hermes/workflow-skills.ts
```
**本批特有难点**:
- **拖拽**(Kanban 列间拖卡片)是**手写 drag 事件**,换成 Arco 布局后要重新验证 drop zone 的坐标计算。**这是本批最大风险。**
- `WorkflowAgentNode.vue` 画的是节点图,坐标计算与容器尺寸耦合
- `JobRunHistory` 有时间线
**完成后必须过**:
```bash
tests/client/kanban-view.test.ts
tests/client/kanban-task-card.test.ts
tests/client/kanban-task-drawer.test.ts
tests/client/kanban-create-form.test.ts
tests/client/kanban-store.test.ts
tests/client/kanban-api.test.ts
tests/client/jobs.test.ts
tests/client/job-form-modal.test.ts
tests/client/workflow-skills.test.ts
tests/client/workflow-socket.test.ts
```
---
### 3.6 批次 7f — IM 频道与群聊
```
views/hermes/ChannelsView.vue
views/hermes/GroupChatView.vue
views/hermes/GlobalAgentView.vue
components/hermes/group-chat/** # GroupChatPanel GroupMessageList GroupMessageItem GroupChatInput CreateRoomForm
stores/hermes/group-chat.ts
api/hermes/group-chat.ts
api/hermes/global-agent.ts
```
**本批特有难点**:
- `GroupMessageList` / `GroupMessageItem` 也是**流式增量渲染**,Phase 006 的规则同样适用:气泡内禁用 Arco 组件
- 多 agent 路由的可视化(谁在响应)
- 会话设置抽屉
**完成后必须过**:
```bash
tests/client/group-chat-store-baseline.test.ts
tests/client/group-chat-store-streaming.test.ts
tests/client/group-chat-store-workspace.test.ts
tests/client/group-chat-view-settings.test.ts
tests/client/group-chat-workspace-diff.test.ts
tests/client/group-chat-input-mentions.test.ts
tests/client/group-chat-mention-options.test.ts
tests/client/group-chat-panel-workspace-source.test.ts
tests/client/group-message-list-scroll.test.ts
tests/client/group-message-item-highlight.test.ts
tests/e2e/group-chat-room-deeplink.spec.ts
```
---
### 3.7 批次 7g — 历史与版本预览(**收尾**)
```
views/hermes/HistoryView.vue
views/hermes/VersionPreviewView.vue
stores/hermes/app.ts
data/changelog.ts # Phase 002 已清空
```
**本批特有难点**:
- `VersionPreviewView` 若 `changelog` 已清空,要么给空态,要么隐藏入口
**完成后必须过**:
```bash
tests/e2e/history-session-deeplink.spec.ts
tests/client/chat-view-tab-title.test.ts
```
---
## 4. 收尾(全批次完成后)
### 4.1 删依赖
`package.json` 删:
```jsonc
"naive-ui": "...",
"@css-render/vue3-ssr": "...", // naive 的 peer,若直接依赖
"vdirs": "..." // 若直接依赖
```
先用 `grep -rn "vdirs\|@css-render" packages/client/src` 确认是否真用到。
### 4.2 改构建配置
`vite.config.ts`:
```ts
// manualChunks
if (id.includes('naive-ui') || id.includes('vueuc')) return 'ui-vendor'
// 改为
if (id.includes('@arco-design')) return 'ui-vendor'
// optimizeDeps.include
// 删掉 'naive-ui', 'vueuc', '@css-render/vue3-ssr'
// 加上 '@arco-design/web-vue'
```
### 4.3 恢复 `prepare` script
Phase 001 摘掉的 `"prepare": "[ -d dist ] || npm run build"` 恢复。
### 4.4 重写 `style-system.test.ts`
旧版断言的是 Naive 的 theme key。改为断言 Arco token:
```ts
// packages/client/src/styles/arco-theme.ts 导出的令牌完整性
// colorPrimary / colorBgLayout / colorBgContainer / borderRadius / fontFamily / fontFamilyMono 存在
// 浅色与深色两套值都定义了
```
### 4.5 新增 `no-naive-ui.test.ts`(**防回流,最强保障**)
```ts
// 递归扫 packages/client/src
// 任何文件出现 "from 'naive-ui'" 或 "from \"naive-ui\"" 即 fail
// 同时断言 package.json 的 dependencies 里无 naive-ui
```
### 4.6 更新 `AGENTS.md` 前端规则
```
- 使用 Arco Design Vue。新增控件优先从 @arco-design/web-vue/es/icon 取图标。
- 禁止引入第二个 UI 库。
- 消息气泡内部不用 Arco 组件(流式性能)。
- 装饰层一律 pointer-events: none。
```
### 4.7 更新 `DEVELOPMENT.md` 的依赖说明
删掉任何 naive 相关表述。
---
## 5. 验收
```bash
cd /Users/jack/source/MyProject/js/hermes-ui
# 全仓零命中
grep -rn "naive-ui\|vueuc\|@css-render" packages/client/src/
grep -n "naive-ui" package.json package-lock.json
# 期望:零命中
# 只 Arco 一个 UI 库
grep -nE "\"(naive-ui|element-plus|ant-design-vue|primevue|@arco-design/web-vue)\"" package.json
npm ci --ignore-scripts
npm run build
npm run test:coverage
npm run test:e2e
```
### 手工
- [ ] 全部 24 个视图(20 个 + 登录 + 缺依赖引导)逐个点过
- [ ] 明暗双主题各过一遍
- [ ] Kanban 拖拽正常
- [ ] 文件树正常
- [ ] 终端正常
- [ ] 图表正常
- [ ] 窄屏 / 移动端布局正常
---
## 6. 风险
| # | 风险 | 缓解 |
|---|---|---|
| P7-1 | 工作量超预期,7a-7g 拖太久 | 每批独立可停;先做 7a 定模式,再批量 |
| P7-2 | 批量改中顺手重构业务逻辑,污染 diff | 硬规则:**只换渲染层**。发现逻辑 bug 单独记 issue,不在本次改 |
| P7-3 | Kanban 拖拽坐标在 Arco 布局下算错 | 7e 单独安排时间手测,不与其他批混做 |
| P7-4 | 忘记某文件的 naive import | `no-naive-ui.test.ts` 卡住(§4.5) |
| P7-5 | `a-table` 替换后大数据量卡顿 | 7d 加虚拟滚动(`a-table-virtual`),先测 1000 行 |
| P7-6 | 依赖删了但 lock 没同步,`npm ci` 失败 | 删依赖后 `rm package-lock.json && npm install --package-lock-only` |
| P7-7 | 7f 群聊流式性能退化 | 复用 Phase 006 的气泡禁 Arco 规则 |
---
## 7. 完成标志
项目功能完整 + 界面全量 Arco + 无第二 UI 库。进入 Phase 008。