Files
MailUI4Agents/docs/HARMONY-ALIGN-PLAN.md
JianFeeeee dfaeab0e4d docs(harmony): 记入"必须用系统方案"的要求与 WebUI→鸿蒙的做法对应表
用户:「鸿蒙也同步,但是鸿蒙要求用系统方案」。

已转给 dsh(线索 harmony-ui-alignment),并写进计划文档:

- **含义**:能交给系统的就交给系统 —— 用 ArkUI 的组件/材质/语义资源,
  而不是把 WebUI 那套"手写 rgba + 自定义模糊 + 自制卡片"照搬。
  系统材质会跟随深色模式、动效曲线与无障碍设置,手写的不会。
- **对应表**:`backgroundBlurStyle(BlurStyle.*)` 取代手写模糊;系统 `Tabs`/`TabBar`
  取代自制导航条;`List`/`ListItem` 取代 `Scroll`+`Column`;组件自身的
  `borderRadius`/`shadow` 取代 `.glass-card`;`$r('sys.color.*')` 语义色取代自切变量
  (**顺带解决 WebUI 那个"半深不浅"的病根**);`animateTo`/`transition` 取代自定义动画。
- **对既有判据的影响(重要)**:`cross-client-theme.test.mjs` 钉的是三个**取值**。
  改用系统资源后它应当变红 —— 那是预期的,届时要把它从"取值相同"改成"意图相同"
  (品牌蓝仍须一致,材质与圆角允许各自跟随系统)。**必须两侧一起改**,
  避免一边改了一半。

同时提醒 dsh 两条已同步的语义:列表项与顶部都是"每项一张卡/气泡"(不是通栏);
玻璃只出现在一层。
2026-09-14 13:45:34 +08:00

408 lines
27 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# 鸿蒙客户端与 WebUI 的对齐计划
> 用户2026-09-14「安排对齐」「**鸿蒙 ui 应当交给对这一块更熟悉的 dsh 负责**」。
> 这份文档把**差距**与**分期**写清楚,免得每轮都从"感觉还差什么"重新猜。
>
> **负责人dsh**2026-09-14 起由 jianf 指定)。移交信:
> 线索 `harmony-ui-alignment``dsh@/home/program/agentmail`
> 信里交代了状态、判据纪律与踩过的坑(判据要点"用户真正会点的那一层"、
> 不许新写死颜色、不要给单个面单独做深色、模糊只由壁纸层负责、
> 列表项每项一张卡、ArkTS 编译坑、视觉不可验要如实标注)。
>
> 我pi保留 WebUI/Electron 侧:需要两边一起加令牌之类的配合,回信给 pi。
## 一、现在的差距(有据可查)
| 能力 | WebUI | 鸿蒙 | 差距性质 |
|---|---|---|---|
| 收件箱 | ✅ | ✅ | — |
| 会话 | ✅(通信页签) | ✅(独立 tab | 交互不同 |
| 联系人 | ✅ | ✅ | — |
| **发件箱** | ✅(通信页签) | ❌ | 缺页面(数据现成) |
| **授权(权限决策)** | ✅(通信页签 + 详情内决策) | ❌ | 缺页面API 现成) |
| **日历** | ✅ | ❌ | 缺页面(最大一块) |
| **管理(用户管理)** | ✅(我的页底部,管理员可见) | ❌ | 缺页面 + 权限判定 |
| **写信** | ✅ 共用 Composer | ✅ 独立实现 | 组件未统一 |
| 底部/侧边导航 | ✅ 悬浮玻璃条 | ⚠️ 系统 TabBar | 观感不同 |
| 主题 / 壁纸(账号级) | ✅ 服务端同步 | ❌ | 未接 |
| 设计令牌 | ✅ `:root` | ✅ `Theme.ets` | **已对齐**(判据钉住) |
## 二、已经做完的(本轮之前)
- **设计令牌共用**`common/Theme.ets` 与 WebUI 的 `:root` 一一对应
(品牌蓝、圆角 14/8、导航玻璃 0.72、语义色、字号),并由
`client/electron/test/cross-client-theme.test.mjs` 钉住取值一致性。
- **旧调色板清除**:页面里的 `#1A73E8`Google 蓝)/`#333333`/`#F5F7FA`
与 WebUI 不同的写死色值全部换成令牌203 处)。
- **修掉只剩第一个 tab 高亮的 bug**`currentIndex === 0` 写死)。
## 二·五、做法上的一条硬要求:**用系统方案**
用户2026-09-14「鸿蒙也同步但是**鸿蒙要求用系统方案**」。
含义:能交给系统的就交给系统 —— 用 ArkUI 的组件、材质与语义资源,
而不是把 WebUI 那套"手写 rgba + 自定义模糊 + 自制卡片"照搬过来。
系统材质会跟随深色模式、动效曲线与无障碍设置,手写的那套不会。
| WebUI 做法 | 鸿蒙应该用 |
|---|---|
| 手写 `rgba(...)` + `backdrop-filter` | `backgroundBlurStyle(BlurStyle.*)`(系统材质) |
| 自制圆角导航条 | 系统 `Tabs` + `TabBar``barBackgroundBlurStyle` |
| 自制 `Scroll` + `Column` | 系统 `List` / `ListItem``divider` / `swipeAction` |
| `.glass-card` 手写边框阴影 | `.borderRadius()` + `.backgroundBlurStyle()` + `.shadow()` |
| 自己切 CSS 变量做深色 | 系统语义色 `$r('sys.color.*')` 自动跟随 |
| 自定义 transition | `animateTo` / `transition` / `geometryTransition` |
**影响既有判据**`cross-client-theme.test.mjs` 目前钉的是三个**取值**
(品牌蓝 / 圆角 14 / 导航玻璃 0.72)。改用系统资源后它应当变红 ——
那是预期的,届时要把它从"取值相同"改成"**意图相同**"(品牌蓝仍须一致;
材质与圆角允许各自跟随系统)。改判据需 WebUI 侧pi一起改。
## 三、分期(按"能独立验收"切)
**P1 设计语言pi 已完成)** —— 令牌 + 颜色替换 + 编译通过。以下 P2P6 归 dsh。
**P2 发件箱**:复用现有列表组件,接口 `/mail/sent`。验收:能看到已发邮件、
点开进详情;空态有说明。**为什么先做它**:与收件箱同构,风险最低。
**P3 授权页**导航加一项「授权」or 通信页内页签,见 5.2③),待决列表走
`GET /permission/pending`,决策走 `POST /permission/decide`
body `{mail_id, decision, note}`);详情内也支持决策。
**(接口名已于 2026-09-14 由 dsh 核对修正,原写的 `/permission/{id}/decide` 不存在。)**
验收:待决列表与 WebUI 同口径(未决 = 无 `permission_result`
点同意/拒绝后状态立刻变;拒绝时可填备注(备注必须随决策送达模型 ——
WebUI 侧踩过这个坑,见 `gateway/handler/permission.go` 的 Note 传递)。
**P4 主题/壁纸同步**:接 `GET/PUT /me/appearance` + 图片走带认证的 fetch。
验收:换账号后外观跟随;服务端"无记录"时以本地为准(不要用默认值覆盖 —— 同 WebUI
**P5 玻璃悬浮导航**:自定义底栏(圆角 + 半透明 + `backgroundBlurStyle`
取代系统 TabBar。**注意**:视觉验收需要设备或签名 HAP
本机 `hdc list targets` 为空 ⇒ 只能保证编译与结构,观感要人眼确认。
**P6 日历**:网格 + 事件读写 + 左右滑动翻页(复用 WebUI 的手势阈值:
水平 ≥40px、≥1.5× 垂直、<600ms)。这一块最大单独排
## 四、验收纪律(照 WebUI 那套)
1. 每个页面都要有**点它**的判据WebUI 侧就是因为只验结构没验点击
漏掉了"侧栏点了不翻页")。
2. 判据不许只看截图要量几何/对比度/命中区
3. 无法验证的要**如实标注**例如"编译通过视觉未验"不能写成"已完成"。
---
## 五、交接核对dsh2026-09-14 收到 pi 的移交信后)
核对方式跑构建跑判据读代码不靠转述
### 5.1 移交信里属实的两条
- `hvigorw assembleHap --no-daemon` **BUILD SUCCESSFUL**改前改后各跑一次)。
- `node --test client/electron/test/cross-client-theme.test.mjs` 6 条全绿
### 5.2 三处纠正(照原计划直接做会踩空)
** P3 的接口名写错了。** 计划里写决策走 `POST /permission/{id}/decide`」,
实际是 `POST /api/v1/permission/decide`body `{mail_id, decision, note}`
`server/internal/handler/permission.go:301`)。而且待决列表**不要**从收件箱里
`permission_*`WebUI 用的是 `GET /api/v1/permission/pending`
`client/electron/src/api/client.ts:623`鸿蒙照这个走才同口径
理由不只是"更省事"`/me/mail/inbox` 默认只取 50 而一个会话能连着产生
十几封权限邮件从收件箱筛会把别的信挤出视野WebUI `mailGroups.ts`
开头就是为这件事写的)。** pending 接口 WebUI 同源。**
**②"不许写死颜色"的判据原来只挡得住列出来的那 8 个旧色值。**
判据全绿的同时`pages/` 里还留着 **14 **另一套写死的色 —— Google/Material
调色板`#E8F0FE``#E8F5E9``#FFF3E0``#D93025``#777777`×2
`#555555``#444444``#cccccc``#aaaaaa`遮罩 `#80000000`×2
透明 `#00000000`×2枚举挡不住漂移只有""能挡已改成
- `pages/` **一个裸色值都不许有**`#RRGGBB` / `#AARRGGBB` 都算颜色只能来自
`common/Theme.ets`页面清单也改成**扫目录**旧版硬编码 7 个文件名
接下来要加的页面会自动逃出判据)。
- 变异测试确认能判红 `InboxPage.ets` 塞一个 `#E8F0FE` 判据红撤回 绿
- 顺带把权限档位徽标的配色收进令牌`Theme.permBg/permFg` WebUI
`PermissionChip.tsx` **同一映射**plan= / workspace=绿 / full=琥珀)。
原先是 `full ? 绿 : 橙`Material WebUI 反着来
- 判据从 6 条加到 7 新增"两边权限档位配色一致"直接拿 WebUI `:root`
`--c-blue-*/green-*/amber-*` 比鸿蒙令牌"看起来差不多")。
** 导航的差距不止"观感不同"是信息架构不同。** WebUI2026-09-14 用户
导航项就只剩通信日历联系人」)已是**通信收件箱/发件箱/授权内部页签
+ 未读红/待决策橙徽标/ 日历 / 联系人**底部另有"我的含管理+ 主题 + 退出"
新建是通信页内**悬浮圆形加号**鸿蒙还是 **收件箱 / 会话 / 联系人** 三个平级 tab
没有发件授权日历会话 WebUI **没有对应入口**WebUI 是按会话把
收件箱分组没有独立会话页)。
P2/P3 不是"再加两个页面"得先对齐信息架构否则加完还是两套导航
### 5.3 一条与鸿蒙无关、但该让 pi 知道的
WebUI `npm test` **HEAD 上就是红的**`test/background.test.mjs`
- `浅色与深色两套令牌都定义了(自动反色)` —— 期望 `--nav-bg` 有浅/深两套
但深色那套已在 `faacd3c`"导航栏还是黑色"里被有意去掉
现在 `index.css` 只剩 `--nav-bg: 255 255 255 / 0.72`
- `导航在壁纸模式下仍参与模糊` —— 期望 `html[data-bg='on'] .nav-rail` 里有
`backdrop-filter: blur(`而该规则现在**是空的**"模糊由壁纸层负责这里不叠"
`index.css:892`)。
两条判据编码的都是**已被有意回滚的设计**判据没跟着改红成了常态
判据也就不再是判据 —— 这条纪律问题比色值本身更值得先修
### 5.4 修订后的分期与"点它"判据
| | 内容 | 判据必须点到用户会点的那一层 |
|---|---|---|
| P1.5 | 裸色值清零 + 判据按类挡 + 权限档位配色统一 | 判据 7/7 绿 + 变异能判红 + 构建成功 |
| P2a | 信息架构:「通信一项内部页签 收件箱/发件箱/授权未读红待决策橙徽标 | **点页签 → 断言落到哪个 pane**不是断言页签个数通信回到上次的子页签 |
| P2b | 发件箱页`GET /me/mail/sent`复用列表项 | 能看到已发邮件点开进详情空态有说明 |
| P3 | 授权页`GET /permission/pending` + `POST /permission/decide` | 未决口径与 WebUI 一致 `permission_result`点同意/拒绝后状态立刻变拒绝可填备注且**备注送达模型**决策请求已过期`expired`必须当场说清"这次批准不会恢复原调用" |
| P4 | 主题/壁纸`/me/appearance` | 换账号外观跟随服务端无记录时以本地为准不用默认值覆盖 |
| P5 | 悬浮玻璃导航取代系统 TabBar | 模糊只由壁纸层负责列表项每项一张卡命中区 44vp |
| P6 | 日历`/calendar/events` ics 导入导出 | 手势阈值与 WebUI 一致水平 40px、≥1.5× 垂直、<600ms |
**视觉/交互怎么验**本机有 `harmony-emu`实例 `HarmonyPhone`hdc
`/opt/harmonyos/ohos-sdk/linux/toolchains`能起来就能截图 + 真点
"编译通过视觉未验"变成"点过有截图"。
**实测2026-09-14**当前文件沙箱workspace-write下起不来 ——
`harmony-emu start` 卡在等一个永远不来的 hdc脚本要写 `/run/harmony-emulator.pid`
直启 `Emulator -start HarmonyPhone -noWindow` 则报
`Error opening logfile /root/.Huawei/Emulator/deployed/HarmonyPhone/Log/qemu.log: Permission denied`
实例目录在 `/root` 沙箱不许写)。**要跑真机/模拟器判据得先放宽文件权限
或换有设备的机器**在那之前鸿蒙侧的判据只能到"构建通过 + 结构/令牌一致"
观感与点击必须如实标注未验 —— 不许写成已完成
### 5.5 待定(需要 pi 或用户一句话)
1. **会话这个平级入口留不留** WebUI 没有它收件箱按会话分组)。
我倾向跟 WebUI 一致 —— 收件箱按会话折叠去掉平级会话tab
但这是删入口改之前要一句话确认
**已答(见 5.6):不是删功能,是两个 tab 合成一个页面的两种视图;先补视图与折叠,再删 tab。**
2. 新增令牌 `accentStrong / warnBg / warnFg / overlay` 取的都是 WebUI **已有**
tailwind blue-700 / amber-50 / amber-700WebUI 侧不需要动代码
`overlay` 是唯一没有对应物的WebUI 弹层不压遮罩)。 pi 认为 WebUI 侧也该
立同名令牌我再改
**已答(见 5.6WebUI 侧不立同名令牌;鸿蒙侧的 `overlay` 拆成 `overlayColor` + `overlayAlpha`。**
---
## 六、pi 的回复已落地dsh2026-09-14 下午)
### 6.1 「会话」入口的结论pi 作为 WebUI 侧负责人)
不是删功能是两个 tab 合成**一个页面的两种视图****联系人页就是会话列表**
`ContactPanel.tsx` 有列表 / 卡片两个视图 —— `ContactRow` 现在的 ContactsTab
`WorkCard`工作列表」≈ 现在的 SessionsTab主题最新一封摘要权限档位徽标
往返预算 = 现在的 `used_rounds/max_rounds`**收件箱里会话是组织方式**
`mailGroups.ts` `groupMailsBySession()` `session_id` 折叠组头取最新一封
`isFlatGroup()` 让单封不成组)。
落地顺序原样采纳
1. ****联系人页补列表 / 卡片切换卡片视图承接预算条 / `status` / 对方 Agent
收件箱加**按会话折叠**组头带未读)。折叠前先看 `total` —— 别让"只取了 50 "
被折叠伪装成"只有这么多会话"。
2. **两件都到位后**再删平级会话tab在那之前删 = 丢信息:轮次预算、`status`
`from_agent` 会无处可看"预算跑满"正是需要人介入的信号
合并后导航正好是 **通信 / 日历 / 联系人** 三项P4P6 都在这个形态上做
分期顺序调整为**P2a 联系人双视图 + 收件箱按会话折叠 P2b 通信页签收件/发件/授权
P3 授权页 P4 主题壁纸 P5 悬浮玻璃导航 P6 日历 最后删会话tab**。
### 6.2 遮罩令牌
`overlay` 拆成 `overlayColor` + `overlayAlpha`WebUI `--bg-scrim` + `--bg-dim`
透明度的两段式色要能随主题换向焊死成一个 `#AARRGGBB` 等于把枚举写回代码)。
ArkUI 只认单值故用 `Theme.overlay()` 组装。**WebUI 侧不立同名令牌**立了没人用
判据只能验"它存在"那是自证)。判据第 8 条钉住这个形态
### 6.3 那两条红判据的 patch已落地且验证过能判红
`test/background.test.mjs` 18 组三条按 pi patch 重写标签改回它真正断言的东西
两条方向相反的断言取代原两条`.dark` 不许单独给导航换色 / 模糊只由壁纸层负责)。
变异验证
- 往某个 `.dark { }` 里塞一行 `--nav-bg: 15 23 42 / 0.72;` **红**
- `html[data-bg='on'] .nav-rail` 里塞 `backdrop-filter: blur(18px);` **红**
- 撤回 绿背景判据 32 **34 通过**
### 6.4 顺手发现并修掉的真 bug构建只在日志里警告的那种
`src/background-takeover.generated.css` **头注释提前闭合**生成器在注释里写了
src「/」加两颗星加「/」「.tsx」,其中那对星号 + 斜杠 CSS 注释就地结束
剩下的尾巴变成 CSS 正文并与第一条规则的选择器连在一起 非法选择器
**`.bg-amber-100` 那条接管规则被浏览器整条丢掉**壁纸模式下它不再变半透明)。
构建只给一条 `[WARNING] Unexpected "14" [css-syntax-error]`不报错不影响构建
改在生成器 `scripts/gen-background-takeover.mjs`注释里只描述不写 glob 字面量
重新生成压缩输出现在以 `html[data-bg=on] .bg-amber-100{` 起头14 条规则全在无告警
另加两条判据"头注释没提前闭合" + 自检)。
### 6.5 一条判据从来没被跑过
`cross-client-theme.test.mjs` **不在 `npm test` 链里**`npm test` 只跑
markdown-xss / narrow-layout / theme / background / packaging + vitest
vitest 只收 `test/components` `test/stores`)—— 那条"防漂移判据"从没在默认套件
里跑过已加进 `npm test`
### 6.6 `npm test` 现在全绿(退出码 0
窄屏布局全通过主题 30背景 34cross-client 8packaging 3vitest 258 用例 / 15 文件全过
其中 **packaging 第 3 条此前是红的**但它**不是判据过期是安装包真的落后于 dist**
`release/linux-unpacked/resources/app.asar` 里装的还是旧前端)。根因有点讽刺
`npm test` `&&` 链一直在 background 那条就中断**packaging 从来没跑到过**。
`npm run build` + `npx electron-builder --linux -c.electronDownload.isVerifyChecksum=false` 重打包
**deb 目标在本机打不出来**`fpm` portable ruby `Dir.chdir` 处退出
AppImage `linux-unpacked` 正常 —— 交付前要确认这个环境问题不影响目标平台
### 6.7 WebUI 侧同源残留pi 指出的第三处,已修)
`Sidebar.tsx` 底部的**主题切换 / 退出登录**按钮原为
`text-chrome-400 hover:text-white hover:bg-chrome-800`外层分隔线 `border-chrome-700`
—— 那是"框架本来就该深"的假设导航改白玻璃后 `chrome-400` 在白底上约 2.6:1
图标要 3:1hover 还会在白导航上闪出一块近黑已换成 `.nav-item` + `border-gray-200`
**未加"Sidebar 里不许有 chrome-*"的判据**`Sidebar.tsx` 另有一处
`bg-chrome-600 text-chrome-100` 是实心小色块正常用法一刀切会误红
### 6.8 仍未验的
鸿蒙侧**视觉与点击**仍未验模拟器在本机沙箱下起不来 5.4)——
本轮的鸿蒙改动只有颜色令牌判据能覆盖** P2a 一定要有人眼或设备**
否则"点页签落在哪个 pane"这条判据无法证明
---
## 七、P2a 落地dsh2026-09-14 稍晚)
pi 给的顺序**先补视图与折叠再删 tab**。本轮做完前一半tab 保留
### 7.1 做法:把"用户真正会点的那一层"的内核抽出来,让判据**执行**它
没有设备"点一下"在鸿蒙上暂时无法自动验应对不是编个能过的新判据
而是把会点的那一层的内核抽成纯逻辑文件
`client/harmony/entry/src/main/ets/model/MailGrouping.ts` UI 依赖
判据用 node `--experimental-strip-types` **直接跑同一份代码**
- `client/electron/test/harmony-logic.test.mjs`14 )—— 断言的是**行为**
折叠后组头是不是最新一封单封是不是不成组同一时刻是否用 `mail_id` 倒序兜底
时间解析失败会不会让顺序依赖入参多账号同名会话会不会被错并预算剩 1 个来回是哪档
- 页面那一层用源码判据钉"确实调了这些函数"`groupMailsBySession` / `isFlatGroup` /
`toggleExpanded` / `budgetLabel` / `nextContactView` / `lastFromIsHuman`)——
两层合起来,「逻辑对页面接上了都有判据
- **变异验证4 全部判红**去掉组内排序 2 条红预算阈值 `<=1` `<1` 1 条红
分组键去掉账号前缀 1 条红页面不再区分单封组 1 条红
这条判据已接进 `npm test``node --experimental-strip-types --no-warnings --test`)。
### 7.2 收件箱:按会话折叠
- 组头取组内**最新一封**的别名与主题 WebUI `mailGroups.ts` 同口径
带未读数徽标与N 」;点组头展开/收起
- **单封不成组平铺** WebUI `isFlatGroup` 同结论给孤立的一封信套组头
只是多一次点击而收件箱里大多数人类来信就是孤立的一封
- 多账号是鸿蒙特有分组键带账号前缀同一 `session_id` 出现在两个账号是两件事
`session_id` 缺失时按 `mail:<id>` 各自成组
### 7.3 顺带修掉一个"看起来是总数、其实是未读数"的显示
`/me/mail/inbox` 返回的 `total` **`CountUnread`未读总数**不是总封数
`server/internal/handler/me.go` `MeGetInbox`)。鸿蒙底部原来写 N 」,
于是同一屏上会出现 7 未读 7这种自相矛盾的两行字
改法未读数**改用服务端 total**权威原来数这一页会少报
N 改成已加载 N 」;并且**这一页取满=50时如实提示
已加载 50 本页上限 50可能还有更多)」** —— 客户端手上根本没有可信的总封数
那就不能把 50 封说成全部这正是 pi 提醒的"别让只取 50 封伪装成只有这么多会话")。
WebUI 侧完全不读这个字段`mailStore` 里没有 `total`所以这条只影响鸿蒙
### 7.4 联系人页:补上卡片视图(为撤 tab 做准备)
- 右上角切换列表 / 卡片标题随视图变(「联系人」/「工作列表」, WebUI 同词
切换规则在 `nextContactView()`判据直接执行它
- 卡片对应 WebUI `WorkCard`Agent + 工作目录 + 未读徽标
会话别名空则「(未命名会话)」)、**主题当主角**、最新摘要 + /Agent 标记
`lastFromIsHuman`)、「N · 时间」、权限档位徽标、**往返预算条**
档位与 WebUI `BudgetChip` 同一判据 0 / 1 / 其余中性上限 0=不限则不显示)。
- 平级会话tab **暂时保留** —— 预算`status``from_agent` 现在卡片视图里都能看了
但按 pi 的顺序 tab 排在 P2b 之后作为独立一步撤早了会丢信息)。
### 7.5 本轮验证与如实标注
- `hvigorw assembleHap` **BUILD SUCCESSFUL**`.ts` 纯逻辑模块能被 `.ets` 引用
实测可行 —— 这是"判据能执行同一份代码"的前提)。
- `npm test` **退出码 0**窄屏布局全通过主题 30背景 34cross-client 8
harmony-logic 14packaging 3vitest 258/258
- **视觉与点击仍未验**无设备 / 模拟器起不来折叠展开的手感卡片间距
组头命中区是否够大这些**没有**任何自动判据能代替人眼 —— 交付时按"结构/逻辑已验证
观感未验"下一轮P2b 通信页签收件箱/发件箱/授权 + 徽标)。
### 7.6 模拟器为什么仍然起不来:权限门是"无人可批准"
7.5 "无设备"这次查到根上了DevEco CLI 的说明`deveco-cli` skill确认本机
****一个按需启动的模拟器实例 `HarmonyPhone`KVM`harmony-emu start` 即可
起来后 `devecocli ui layout / click / screenshot` 能做**真正的点击级验证**)。
`harmony-emu start` 要把 PID/日志写到 `/run` `/root/.Huawei`工作区之外
workspace-write 沙箱下被拒按规矩用 `sandbox_permissions` 升级重试一次得到的是
无法执行 bash权限询问无法送达该任务链上没有人类用户
也就是说**鸿蒙的点击级验证在这条链上不是"还没做"而是"当前做不到"** ——
需要人类在命令行里跑一次 `harmony-emu start`之后 `devecocli ui` 就能自动点
在那之前鸿蒙侧任何界面改动的验收口径只能是
逻辑有可执行判据 + 页面接线有判据 + 观感未验」,**不能**"已完成"。
给上游的可执行请求在有人的环境里执行
`harmony-emu start && cd client/harmony && hvigorw assembleHap && hdc install entry/build/default/outputs/default/entry-default-unsigned.hap`
即可让 P2a 之后所有阶段的"点击级判据"落地。)
### 7.7 顺手把"判据套件"本身修可信(同一族问题的总账)
这轮撞出来的问题里有一类是**判据自己不会跑**比判据写错更隐蔽输出看起来一切正常
1. `cross-client-theme.test.mjs` 从来不在 `npm test` 链里pi 已认领
2. 有人新加的 4 条玻璃判据写在 `process.exit()` **之后** —— 一条都不执行不计通过也不计失败
3. `nav-merge.test.mjs``build-stamp.test.mjs` 写好了**也没接线** 8 / 4 条判据从未跑过
4. `npm test` `&&` **前面红一条后面全部不跑**`packaging` 那条因此长期隐身)。
改法`test/run-all.mjs`pi 建议的"全跑完再算退出码"
- 每条判据都跑红的收集起来最后一起报一起退出
- **自检 1**清单里的文件必须存在写错名字 = 一条判据静默消失);
- **自检 2**`test/` 下每个 `*.test.mjs` 都必须在清单里 —— **新增判据忘了接线直接红**
这条自检当场就抓出上面第 3 条那两个文件
- 变异验证 `theme.test.mjs` 强制红 后面 5 条判据照跑汇总如实报" 1/9"、退出码 1
接线后又立刻暴露出两条**陈旧判据**代码没错判据钉的是旧写法已按"钉行为不钉字面"修好
- `setViewMode(target || commTab` 代码后来等价改写成
`target ?? (isComm ? commTab : modes[0])`改成钉"isComm 时落到 commTab"这个行为
- `MailView.tsx` grep `glass-control` 授权多选胶囊抽成了共用组件 `ComposerChip`
样式其实是对的neutral 未选中态就是 `glass-control`改成钉
"MailView ComposerChip" + "ComposerChip 用控件档"。两条都做了变异验证改坏必红)。
pi 的提议还给生成产物补了一条判据 **postcss 真解析** `background-takeover.generated.css`
断言**每条规则的选择器形状**都恰好是 `html[data-bg='on'] .bg-xxx` **规则条数与清单一致** ——
"生成器写坏产物""只有浏览器能发现"变成"跑判据就红"。
注意只验"能解析"不够 —— 实测 postcss 对当年那份坏产物照样解析出 1 条规则
只是选择器前面粘上了注释的尾巴所以卡的是形状与条数。)
套件现状`npm test` = `node test/run-all.mjs && vitest run`9 个判据文件全绿
markdown-xss / narrow-layout / nav-merge / theme / background 42 / cross-client 8 /
harmony-logic 14 / build-stamp 4 / packaging 3+ vitest 258/258
### 7.8 deb 那条结论要撤回:不是 fpm是 `/tmp` 满了
pi 问的 deb 复测有结果了`TMPDIR=/var/tmp/ebtmp` 在本沙箱里**建不出来**
工作区外不可写但把 TMPDIR 指到工作区大盘后 **deb 打出来了**
`release/agentmail-web_0.1.0_amd64.deb` 100MB)。
真因不是权限也不再是 fpm日志里的关键行是 **`Errno::ENOSPC`** —— fpm 会把
`release/linux-unpacked`291MB整份复制进 `TMPDIR`而本机 `/tmp` 9.8G tmpfs
`/tmp/gocache`4.5G等占到 99%仅剩 ~100MB 可用)。
所以本机打不出 deb这个结论**撤回**它是环境症状不是工具链缺陷
deb 也不必从 targets 里摘已写进 `client/electron/BUILD.md`含排查命令)。
顺带给所有 agent 的提醒本机 `/tmp` 99% `hvigor` 之类的构建会把它进一步挤爆
大产物构建请把 `TMPDIR` 指到工作区所在盘