306 lines
9.3 KiB
Markdown
306 lines
9.3 KiB
Markdown
# Phase 008 — 测试与 CI 收口 + harness 重写
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 目标 | `harness:check` 覆盖新结构;CI 全绿;删 `reference_code/` 后仍自洽 |
|
||
| 前置 | Phase 007 通过 |
|
||
| 产出 | `scripts/harness-check.mjs` 重写完成,CI 五个检查项全过 |
|
||
| 参考 | `docs/03-施工蓝图.md` §10 |
|
||
|
||
---
|
||
|
||
## 0. 为什么要重写而不是删几行
|
||
|
||
现有 [harness-check.mjs](file:///Users/jack/source/OtherProjectTemp/ekko-studio/scripts/harness-check.mjs) 有 **170+ 行在断言 desktop / website 的产物与文案**:
|
||
|
||
- `desktop-release.yml` 的 dmg / exe / AppImage / nsis 产物名
|
||
- `installer.nsh` 的 `Stop-Process` 片段
|
||
- updater 的 `download.ekkolearnai.com`
|
||
- `packages/desktop/build/icons/` 的 11 个图标文件名
|
||
- website 的 `docs/` 静态站路径
|
||
|
||
**Phase 001 已删掉这些包,这些断言全部失效。逐行删会漏,且失去对新结构的保护。整体重写。**
|
||
|
||
---
|
||
|
||
## 1. 功能任务 1 — 新 harness 的校验项
|
||
|
||
新建 `scripts/harness-check.mjs`,覆盖以下 9 项:
|
||
|
||
### 1.1 必需文件存在
|
||
|
||
```
|
||
AGENTS.md
|
||
ARCHITECTURE.md
|
||
DEVELOPMENT.md
|
||
README.md
|
||
package.json
|
||
vite.config.ts
|
||
vitest.config.ts
|
||
playwright.config.ts
|
||
tsconfig.json
|
||
docs/harness/README.md
|
||
docs/harness/validation.md
|
||
docs/harness/worktree-runbook.md
|
||
docs/harness/pr-review.md
|
||
```
|
||
|
||
### 1.2 必需目录存在
|
||
|
||
```
|
||
packages/client/src
|
||
packages/server/src
|
||
packages/skills
|
||
tests/client
|
||
tests/server
|
||
tests/shared
|
||
tests/e2e
|
||
.github/workflows
|
||
```
|
||
|
||
### 1.3 **禁止目录不存在**(防回流,Phase 001 已有对应配置)
|
||
|
||
```
|
||
packages/desktop
|
||
packages/website
|
||
packages/ekko-agent
|
||
packages/esp32-c3
|
||
reference_code ← 项目完成前允许存在,见 §5
|
||
```
|
||
|
||
> `reference_code` 这一条**先不加**。等 Phase 009 确认项目完全自洽后再加,避免中途误红。
|
||
|
||
### 1.4 `AGENTS.md` 约束
|
||
|
||
- 行数 ≤ 120
|
||
- 链接到 `DEVELOPMENT.md` `ARCHITECTURE.md` `docs/harness/README.md` `docs/harness/validation.md` `docs/harness/worktree-runbook.md` `docs/harness/pr-review.md`
|
||
- 6 条 Hard Rules 齐全(路由薄 / Web UI 状态隔离 / Hermes 状态隔离 / 本地路由先于代理 / 结构化 API / 双 locale)
|
||
- 提及 `packages/skills`
|
||
|
||
### 1.5 `package.json` 脚本齐全
|
||
|
||
必须含:`harness:check` `test` `test:coverage` `test:e2e` `build`
|
||
|
||
必须**不含**:`desktop:*` `build:desktop*` `dev:website` `build:website`
|
||
|
||
### 1.6 `ARCHITECTURE.md` 数据归属
|
||
|
||
必须含 `HERMES_WEB_UI_HOME`(这是有意保留的旧标识,需要在文档里写明原因)。
|
||
|
||
### 1.7 **禁止字符串扫描**(Phase 002 已建测试,harness 里做静态版)
|
||
|
||
扫 `packages/` `tests/` `scripts/` `bin/`:
|
||
|
||
```
|
||
'ekko'(大小写不敏感)
|
||
'hermes-web-ui'
|
||
'hermes-studio'
|
||
```
|
||
|
||
**白名单**(允许出现,需在代码里显式注释原因):
|
||
|
||
```
|
||
HERMES_WEB_UI_* 环境变量名
|
||
HERMES_WEBUI_STATE_DIR 环境变量名
|
||
hermes_brightness localStorage key
|
||
hermes_style localStorage key
|
||
hermes_locale localStorage key
|
||
config.ts 里的 ~/.hermes-web-ui 默认数据目录名
|
||
```
|
||
|
||
> `config.ts` 的默认数据目录名是**刻意保留**的旧标识(避免破坏已有数据目录)。白名单里写清楚。
|
||
|
||
### 1.8 **禁止第二 UI 库**(Phase 007 已有 `no-naive-ui.test.ts`,harness 做静态版)
|
||
|
||
`package.json` 的 `dependencies` / `devDependencies` 里:
|
||
|
||
```
|
||
只能有 @arco-design/web-vue
|
||
不能有 naive-ui / element-plus / ant-design-vue / primevue / vuetify / quasar
|
||
```
|
||
|
||
### 1.9 Chat 链路变更片段规则
|
||
|
||
保留旧版机制(`docs/chat-chain-changes/`),但清单去掉已砍的部分。
|
||
|
||
**变更以下文件时,必须附一个 `docs/chat-chain-changes/<date>-<slug>.md`**:
|
||
|
||
```
|
||
packages/server/src/services/hermes/run-chat/**
|
||
packages/server/src/services/hermes/agent-bridge/**(含 python/)
|
||
packages/server/src/services/hermes/group-chat/**
|
||
packages/server/src/services/hermes/context-engine/**
|
||
packages/server/src/lib/context-compressor/**
|
||
packages/client/src/stores/hermes/chat.ts
|
||
packages/client/src/stores/hermes/group-chat.ts
|
||
```
|
||
|
||
> **已砍掉**:`services/agent-runner/**`(Phase 003)、`services/coding-agents.ts`、`services/ekko-agent/**` —— 不再需要片段。
|
||
|
||
CI 里 `actions/checkout` 必须带 `fetch-depth: 0`,否则 `git diff` 检测失效。
|
||
|
||
---
|
||
|
||
## 2. 功能任务 2 — CI workflow
|
||
|
||
### 2.1 保留的 5 个
|
||
|
||
```
|
||
build.yml
|
||
playwright.yml
|
||
npm-lockfile-check.yml
|
||
docker-publish.yml
|
||
webui-release.yml
|
||
```
|
||
|
||
### 2.2 `build.yml` 步骤
|
||
|
||
```yaml
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0 # 必须,harness:check 依赖 git diff
|
||
|
||
- run: npm ci --ignore-scripts
|
||
- run: npm run harness:check
|
||
- run: npm run test:coverage
|
||
- run: npm run test:e2e
|
||
- run: npm run build
|
||
```
|
||
|
||
### 2.3 `playwright.yml`
|
||
|
||
保留,但要确认 mock 后端服务启动脚本里没有引用已删的 API。
|
||
|
||
### 2.4 `webui-release.yml`
|
||
|
||
Phase 002 已去品牌。确认打包产物名是 `hermes-ui`。
|
||
|
||
若你**不打算发布**,这个 workflow 可以删。发布与否决定 `controllers/update.ts` 的在线更新是否可用(见 Phase 002 §2.3)。
|
||
|
||
---
|
||
|
||
## 3. 功能任务 3 — 测试补强清单
|
||
|
||
已有机制(Phase 002 / 007 建立):
|
||
|
||
| 测试 | 作用 |
|
||
|---|---|
|
||
| `tests/server/no-legacy-brand.test.ts` | 旧品牌扫描 |
|
||
| `tests/client/no-naive-ui.test.ts` | UI 库防回流 |
|
||
| `tests/client/i18n-coverage.test.ts` | zh/en key 一致性 |
|
||
| `tests/client/arkscope-vendor.test.ts` | vendor 边界 |
|
||
| `tests/client/message-item-arko.test.ts` | 气泡内禁 Arco |
|
||
|
||
本 Phase 建议再加 3 个:
|
||
|
||
### 3.1 `tests/client/i18n-parity.test.ts`
|
||
|
||
`zh.ts` 与 `en.ts` 的 key 集合必须完全一致(`i18n-coverage.test.ts` 已覆盖大部分,此处补 `zh` 与 `en` 互相的完整对等检查)。
|
||
|
||
### 3.2 `tests/server/hermes-db-readonly.test.ts`
|
||
|
||
**红线机械化**:断言 server 源码中没有任何地方直接 `open()` / `new Database()` hermes 的 `state.db`。
|
||
|
||
扫描 `packages/server/src/` 下对 `state.db` 的引用,每一处都必须在白名单(如注释、文档字符串)里。
|
||
|
||
### 3.3 `tests/server/no-desktop-reference.test.ts`
|
||
|
||
断言 `packages/` 里没有 `HERMES_DESKTOP`(**除 `agent-bridge/python/bridge_runtime.py`**)。
|
||
|
||
那个文件里的判断是 Windows 隐藏控制台窗口用的(见 Phase 004 §6),必须豁免。
|
||
|
||
---
|
||
|
||
## 4. 功能任务 4 — 文档收口
|
||
|
||
| 文件 | 收口内容 |
|
||
|---|---|
|
||
| `AGENTS.md` | 补一条:**`agent-bridge/python/` 是只读 vendored 代码**;**hermes `state.db` 只读** |
|
||
| `ARCHITECTURE.md` | 补数据归属图:我们的 SQLite 唯一可写 vs hermes state.db 只读;profile 隔离靠注入 `HERMES_HOME` |
|
||
| `DEVELOPMENT.md` | 加「首次安装」章节:装 Python + `pip install hermes-agent`,或设 `HERMES_BIN`(因为已无桌面端捆绑) |
|
||
| `README.md` / `README_zh.md` | 同上,安装步骤放最前面 |
|
||
| `docs/harness/validation.md` | 更新为新结构(Phase 001 拷的是旧版,含 desktop 内容) |
|
||
| `docs/harness/pr-review.md` | 检查是否引用已砍功能 |
|
||
| `docs/harness/worktree-runbook.md` | 检查是否引用 `packages/desktop` 路径 |
|
||
|
||
**这 4 个 harness 文档是 Phase 001 从 reference 拷的,里面大概率有 desktop 内容。逐个检查。**
|
||
|
||
---
|
||
|
||
## 5. 验收
|
||
|
||
```bash
|
||
cd /Users/jack/source/MyProject/js/hermes-ui
|
||
|
||
npm run harness:check
|
||
npm run test:coverage
|
||
npm run test:e2e
|
||
npm run build
|
||
```
|
||
|
||
### 5.1 自洽性验证(**模拟最终删 reference_code**)
|
||
|
||
```bash
|
||
# 1. 确认无引用
|
||
grep -rn "reference_code" . \
|
||
--include="*.ts" --include="*.vue" --include="*.json" \
|
||
--include="*.mjs" --include="*.yml" --include="Dockerfile*" \
|
||
| grep -v "^./docs/phases/"
|
||
# 期望:零命中
|
||
|
||
# 2. 临时移走,验证完全自洽
|
||
mv reference_code /tmp/hermes-ui-reference-backup
|
||
|
||
npm ci --ignore-scripts
|
||
npm run build
|
||
npm run test
|
||
npm run harness:check
|
||
# 全部通过
|
||
|
||
mv /tmp/hermes-ui-reference-backup reference_code
|
||
```
|
||
|
||
**这一步通过,才允许删除 `reference_code/`。**
|
||
|
||
### 5.2 手工
|
||
|
||
- [ ] `npm run harness:check` 在故意破坏时能报错(删一个必需文件试试)
|
||
- [ ] 往代码里加一处 `ekko` 字样,扫描会红
|
||
- [ ] 往代码里加一处 `naive-ui` import,测试会红
|
||
|
||
---
|
||
|
||
## 6. 风险
|
||
|
||
| # | 风险 | 缓解 |
|
||
|---|---|---|
|
||
| P8-1 | harness 重写漏项,CI 变弱 | §5.2 手工验证三个场景都能报红 |
|
||
| P8-2 | harness 白名单被后续误加,扫描形同虚设 | 白名单每项必须带注释写明原因,review 时盯 |
|
||
| P8-3 | `docs/harness/*.md` 里的 desktop 内容没改,误导后续 | §4 逐个检查 |
|
||
| P8-4 | `fetch-depth: 0` 丢失,链路变更检测静默失效 | build.yml 显式写,harness 也检查这条 |
|
||
| P8-5 | `no-desktop-reference.test.ts` 误伤 python 文件 | 显式豁免路径 + 注释说明原因 |
|
||
|
||
---
|
||
|
||
## 7. 项目完成
|
||
|
||
Phase 008 通过后,项目达成:
|
||
|
||
- [x] 无 `ekko` / `hermes-web-ui` 字样(配置层白名单除外)
|
||
- [x] 无 Electron、无桌面端、无官网
|
||
- [x] 无编程代理、无自有 Agent、无桌宠
|
||
- [x] 聊天链路只走 Hermes 桥,协议未改
|
||
- [x] Arco Design Vue 单 UI 库
|
||
- [x] ArkScope 只做装饰位面
|
||
- [x] i18n 只 zh + en
|
||
- [x] CI 全绿
|
||
- [x] **删掉 `reference_code/` 后完全自洽**
|
||
|
||
**此时可以安全删除 `reference_code/`。**
|
||
|
||
### 可选后续(不在本蓝图范围)
|
||
|
||
- 发布 npm 包,接通 `update.ts` 在线更新
|
||
- ESP32 语音硬件(需从 reference 恢复 `packages/esp32-c3`)
|
||
- 更多 locale 语言
|