Commit Graph

8 Commits

Author SHA1 Message Date
b3f404838b feat(harmony): P2a 收尾 —— 撤掉平级「会话」tab + 权限"强制力"上界面,判据 14→19
## 撤 tab(按 pi 的顺序:先补视图与折叠,再撤入口)

底部只剩 **收件箱 / 联系人**。「会话」不是第三个地方,而是同一批数据的两种看法:
收件箱那栏按会话折叠(组头就是会话),联系人那栏的卡片视图是会话的进度视角。
依据是"信息没丢",并且把它做成了判据:**卡片字段集与 WebUI `WorkCard` 完全相等**
(多一个少一个都红)—— 其中 `status`(active/archived) 与 `from_agent` 参考实现也不显示;
哪天 WebUI 补上,这条会红,提醒跟着补,而不是悄悄少一块。

## 权限"强制力"上界面(WebUI 有、鸿蒙原先没有)

只显示档位会让人以为 plan 档真的管住了对方。WebUI 把说明放在 `title`(悬停提示),
**手指没有悬停** —— 所以鸿蒙拆两步:标记形状当场可辨(● 平台强制 / ◉ 覆盖不完整 /
○ 仅提示),点徽标用 toast 说完整那句话。三条纪律落进判据:

1. 档位/强制力标签与 WebUI 的 `MODE_LABEL` / `ENFORCEMENT_LABEL` **逐字一致**;
2. **说明文案从 WebUI 源码抽出字符串逐字比对**(3 档 × 3 强制力全覆盖)——
   两个客户端对同一个任务不能给两种保证;
3. 认不出的强制力归一到 `advisory`(保守方向),空/未知必须说"仅提示"。

收件箱每封邮件里没有 `permission_enforcement`(会话级字段),故那里只写中文档位 ——
凭空画一个强制力标记等于编一个"平台做到了什么"。

## 判据自己不可信的两个坑(变异测试逼出来的,各修一次)

- **断言一律读剥掉注释的源码**:把 `showToast` 注释掉,正则照样匹配 ——
  注释里有某个调用证明不了它存在。
- **"在回调里"不能靠正则窗口**:`onClick` 体掏空、或把 toast 挪到相邻的 `onHover`,
  窗口式正则都会放过。改成**括号配对**取那个 `onClick` 的 `{...}` 体,只在里面找。
  两次变异现在都判红。

`harmony-logic.test.mjs` 19 条(原 14);变异验证:改文案 / 改档位标签 / 页签改回「会话」/
注释掉 toast / toast 挪出 onClick / toast 写死文案 → 各判红。

## 文档

§7.9 记本轮;§7.10 记 jianf 追加的「鸿蒙要求用系统方案」:同意该理解,并补上**可离线校验**的
做法 —— SDK 自带系统资源名表 `sdk/default/openharmony/toolchains/id_defined.json`(7826 条),
其中正好有 `ohos_id_color_list_card_bg`(每项一张卡的底色)、`_list_separator`、
`_text_primary/secondary/tertiary`、`_emphasize`、`_warning`、`_alert`、`_mask_*`、
`ohos_id_blur_style_component_*_color`。**没有设备**,`$r('sys.*')` 写错在运行前发现不了,
所以先立一条判据:源码里的每个 `sys.*` 名字都必须在该表里查得到,再逐处替换。
`cross-client-theme` 的三个取值钉改"意图相同"**先与 pi 对齐、两侧一起改**(他已明确要求)。

## 验证

`hvigorw assembleHap` BUILD SUCCESSFUL;`npm test` 9 个判据文件(background 42 /
cross-client 8 / harmony-logic 19 / nav-merge 8 / build-stamp 4 / packaging 3 …)+ vitest 258。
视觉与点击仍未验(无设备,模拟器需人在命令行启动)。
2026-09-14 13:51:35 +08:00
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
6be5a543af test(suite): 判据总入口 run-all —— 全部跑完再算退出码,并接上两条从未跑过的判据
## 为什么

`npm test` 是 `&&` 链:**前面红一条,后面全部不跑**。于是"只红一条"看起来像
"只有一个问题",实际后面那些判据连跑都没跑(`packaging` 那条能发现"界面改了没重打包"的
判据,长期因此隐身)。而且这套规矩下"全绿"可信、"红"不可信。

改成 `test/run-all.mjs`(pi 建议):每条都跑,红的收集起来最后一起报、一起退出。

- **自检 1**:清单里的文件必须存在(名字写错 = 一条判据静默消失);
- **自检 2**:`test/` 下每个 `*.test.mjs` 都必须接进清单 —— **新增判据忘了接线直接红**。
  这条自检当场抓出 `nav-merge.test.mjs`、`build-stamp.test.mjs` 两个"写好了没接线"的文件
  (8 + 4 条判据此前从未跑过,与 `cross-client-theme` 是同一族问题)。
- 变异验证:强制 `theme.test.mjs` 判红 → 后面 5 条判据照跑,汇总如实报"红 1/9"、退出码 1。

`package.json`:`"test": "node test/run-all.mjs && vitest run"`。

## 接线后暴露的两条陈旧判据(代码没错、判据钉的是旧写法),按"钉行为不钉字面"修

1. `setViewMode(target || commTab` —— 代码后来等价改写成
   `target ?? (isComm ? commTab : modes[0])`。改成钉行为"isComm 时落到 commTab",
   并额外要求桌面分支带 `target`(否则日历/联系人点不动)。
2. `MailView.tsx` 里 grep `glass-control` —— 授权多选胶囊已抽成共用组件 `ComposerChip`,
   样式其实是对的(neutral 未选中态就是 `glass-control`)。改成钉
   "MailView 用 ComposerChip" + "ComposerChip 用控件档"(文件会搬、组件不会)。
   两条都做了变异验证(去掉玻璃档 / 去掉 commTab 回退 → 各判红 1 条)。

## 生成产物再补一条判据(pi 提议)

用 postcss 真解析 `background-takeover.generated.css`:断言每条规则的选择器形状恰好是
`html[data-bg='on'] .bg-xxx`,且规则条数与源码扫到的清单条数一致。
只验"能解析"不够 —— 实测 postcss 对当年那份坏产物照样解析出 1 条规则(选择器前粘了
注释尾巴),所以卡形状与条数。变异:把坏头注释塞回生成产物 → 该条判红。

## BUILD.md:deb 结论撤回(不是 fpm)

`TMPDIR=/var/tmp/ebtmp` 在本沙箱建不出来;把 TMPDIR 指到工作区大盘后 deb 正常产出
(`release/agentmail-web_0.1.0_amd64.deb`,约 100MB)。日志关键行是 **`Errno::ENOSPC`**:
fpm 要把 291MB 的 `linux-unpacked` 整份复制进 TMPDIR,而本机 `/tmp` 是 9.8G tmpfs、
被 `/tmp/gocache`(4.5G)等占到 99%。所以「本机打不出 deb」是环境症状、不是工具链缺陷,
deb 不必从 `build.linux.target` 摘掉。排查命令写进 BUILD.md。

## 验证

`npm test` 退出码 0:9 个判据文件全绿(markdown-xss、narrow-layout、nav-merge 8、
theme、background 42、cross-client 8、harmony-logic 14、build-stamp 4、packaging 3)
+ vitest 258/258。鸿蒙侧 `hvigorw assembleHap` 仍 BUILD SUCCESSFUL。
2026-09-14 13:44:00 +08:00
e0c68d8bb2 test(cross-client): 预算条三个档位的令牌也和 WebUI 对齐 + 记录模拟器权限门
## 判据

P2a 新加的 6 个预算条令牌(`chipNeutral*` / `chipSpent*` / `chipWarn*`)此前只有鸿蒙侧
自己在用,没有任何判据钉住它们与 WebUI `BudgetChip` 的 gray-100/gray-500、
red-100/red-700、orange-100/orange-700 是**同一批值** —— 于是"鸿蒙那边自己挑了个接近的红"
没人会发现。补进 `cross-client-theme.test.mjs`(8 → 8 条,第 7 条扩了 6 个断言),
并加了反向对照(差一个色阶必须判红,实测判红)。

注意 `--c-gray-100` 等在 `.dark` 段有第二处定义,`cssVar()` 取第一处(`:root` 浅色一套),
与 `Theme.ets` 的浅色令牌对应。

## 文档

`docs/HARMONY-ALIGN-PLAN.md` §7.6:把"鸿蒙视觉/点击未验"查到根上 —— DevEco CLI 说明本机
**有**可启动的模拟器(起来后 `devecocli ui layout/click/screenshot` 能做点击级验证),
但 `harmony-emu start` 要写 `/run`、`/root/.Huawei`(工作区之外),按规矩升级重试一次后
被拒:**「权限询问无法送达:该任务链上没有人类用户」**。
即:鸿蒙的点击级验证不是"还没做",是"当前做不到"——需要人在命令行跑一次
`harmony-emu start`。此前所有阶段只能按"逻辑有可执行判据 + 接线有判据 + 观感未验"验收。
2026-09-14 13:38:35 +08:00
3729afd96f feat(harmony): P2a —— 收件箱按会话折叠 + 联系人页卡片视图(判据直接跑同一份逻辑)
按 pi 的结论落地 P2a 的前一半:**先补视图与折叠,再删平级「会话」tab**(tab 本轮保留)。

## 判据怎么"点用户真正会点的那一层"

鸿蒙侧没有设备(`hdc list targets` 为空、模拟器在本机沙箱下起不来),"点一下"暂时
无法自动验。应对不是编个能过的新判据,而是把会点的那一层的内核抽成纯逻辑:
`entry/src/main/ets/model/MailGrouping.ts`(无 UI 依赖),判据用 node 的
`--experimental-strip-types` **执行同一份代码**(`test/harmony-logic.test.mjs`,14 条),
断言的是行为而不是"源码里出现过某个字符串":

- 折叠后组头是不是**最新一封**、组内是否时间倒序、组间排序、同一时刻用 `mail_id` 倒序兜底;
- 时间解析失败**不能让顺序依赖入参**(WebUI 侧踩过的 NaN 比较坑);
- 多账号合并下同名 `session_id` 不能被错并成一组;`session_id` 缺失时各自成组;
- 预算档位与 WebUI `BudgetChip` 完全一致(剩 0 用尽 / ≤1 将尽 / 上限 0 不显示);
- 视图切换与卡片上"最新一封是人还是 Agent"的判据。

页面那一层另用源码判据钉"确实调了这些函数",两层合起来覆盖「逻辑对」+「页面接上了」。
**变异验证 4 处全部判红**:去掉组内排序(2 条红)、预算阈值 `<=1` 改 `<1`、
分组键去掉账号前缀、页面不再区分单封组。

## 收件箱折叠

- 组头取组内最新一封的别名与主题,带未读数徽标与「N 封」,点它展开/收起;
- **单封不成组、平铺**(与 WebUI `isFlatGroup` 同结论:给孤立一封信套组头只是多一次点击);
- 多账号是鸿蒙特有:分组键带账号前缀;`session_id` 缺失按 `mail:<id>` 各自成组。

## 顺带修掉一个"看起来是总数、其实是未读数"的显示

`/me/mail/inbox` 的 `total` 是 **`CountUnread`(未读总数)**,不是总封数
(`server/internal/handler/me.go`)。鸿蒙底部原写「共 N 封」⇒ 同一屏出现
「共 7 封」和「未读 7」两行自相矛盾的字。改成:未读数用服务端 `total`(权威,
原来数这一页会少报);「共 N 封」→「已加载 N 封」;**这一页取满时如实提示
「已加载 50 封(本页上限 50,可能还有更多)」** —— 客户端没有可信总封数,
就不能把 50 封说成全部(pi 提醒的"别让只取 50 封伪装成只有这么多会话")。
WebUI 侧不读这个字段,故只影响鸿蒙。

## 联系人页补卡片视图(撤 tab 的前置)

- 右上角切列表/卡片,标题「联系人」/「工作列表」(与 WebUI 同词),切换规则在
  `nextContactView()`;
- 卡片对应 WebUI 的 `WorkCard`:Agent 名 + 工作目录 + 未读徽标、会话别名、
  **主题当主角**、最新摘要 + 人/Agent 标记、`N 封 · 时间`、权限档位徽标、
  **往返预算条**(同一档位判据)。
- 平级「会话」tab 暂留:撤 tab 按 pi 的顺序排在后面单独一步(撤早了预算/status/from_agent 没处看)。

## 验证

- `hvigorw assembleHap` **BUILD SUCCESSFUL**(`.ts` 纯逻辑模块被 `.ets` 引用,实测可行)。
- `npm test` **退出码 0**:窄屏布局全通过、主题 30、背景 34、cross-client 8、
  harmony-logic 14、packaging 3、vitest 258/258;新判据已接进 `npm test`。
- **视觉与点击仍未验**(无设备):展开手感、卡片间距、组头命中区没有任何自动判据
  能代替人眼 —— 交付按"结构/逻辑已验证、观感未验"写,未写成已完成。
2026-09-14 13:36:05 +08:00
e07e3bf1a1 docs(harmony): 记入交接核对结果与 pi 回复的落地(P2a/P2b 顺序、判据、真 bug)
第五节:收到 pi 移交信后的核对 —— 移交信里属实的两条(构建成功、cross-client 6/6 绿)、
三处纠正(P3 接口名写错、判据只挡枚举、导航差距其实是信息架构差距),
以及一条与鸿蒙无关但该让 pi 知道的(WebUI `npm test` 在 HEAD 上恒红)。

第六节:pi 回复的落地 ——
- 「会话」入口的结论:不是删功能,是联系人页的**卡片视图** + 收件箱按会话折叠,
  两件到位后再删 tab(在那之前删 = 丢信息:轮次预算 / status / from_agent 无处可看)。
  ⇒ 分期顺序改为 P2a 联系人双视图 + 收件箱折叠 → P2b 通信页签 → P3 授权 → P4 主题壁纸
  → P5 悬浮玻璃导航 → P6 日历 → 最后删 tab。
- 遮罩拆两段式;WebUI 侧不立同名令牌(立了没人用、判据只能验"它存在",是自证)。
- 两条红判据的 patch 已落地且验证过能判红;background 判据 32 → 34 通过。
- 顺手修掉的真 bug:生成 CSS 头注释提前闭合导致 `.bg-amber-100` 那条规则被整条丢掉。
- 一条判据从来没被跑过:cross-client 判据不在 `npm test` 链里,已加进去。
- `npm test` 现在全绿(退出码 0);deb 目标在本机打不出来(fpm),要确认是否影响交付平台。
- 仍未验的:鸿蒙侧的视觉与点击(模拟器起不来),到 P2a 必须有人眼或设备。
2026-09-14 13:30:03 +08:00
fac30eb09c docs(harmony): 鸿蒙对齐移交 dsh(jianf 指定),计划文档记入负责人与纪律
用户:「鸿蒙 ui 应当交给对这一块更熟悉的 dsh 负责」。

- 给 dsh 发了移交信(新线索 `harmony-ui-alignment`),交代:
  当前状态(P1 完成)、分期(P2–P6)、**判据纪律**(结构类改动必须配"点它"的判据
  —— WebUI 侧就是因此漏掉了"点日历不翻页")、**避坑清单**(不许新写死颜色;
  这个应用没有真正的深色主题,别让单个面自己变深;玻璃只该出现一次;
  列表项每项一张卡;ArkTS 的 `arkts-no-any-unknown`/`arkts-no-standalone-this`;
  视觉不可验要如实标注)、以及两条服务端语义(已读按读者记录;
  授权被拒的备注必须送达模型)。
- `HARMONY-ALIGN-PLAN.md` 记入负责人与移交线索,并标明 P1 已完成、P2–P6 归 dsh。

分工:鸿蒙归 dsh,WebUI/Electron 与网关仍归 pi;需要两边同时改令牌之类的配合,
由 dsh 回信给我。
2026-09-14 13:13:44 +08:00
5434bc9e4e feat(harmony): 对齐第一阶段 + 对齐计划文档(差距/分期/验收纪律)
用户:「安排对齐」。

## 先量差距(不靠感觉)

鸿蒙侧的调色板与 WebUI **根本不同**:`#1A73E8`(Google 蓝)vs 品牌 `#2563EB`、
`#333333` vs slate-900 `#0F172A`、`#F5F7FA` vs `#F8FAFC`、`#FF4444` vs red-600…
共 217 处硬编码色值散在 7 个页面里。

功能面:鸿蒙是 收件箱/会话/联系人 三个 tab,**缺 发件箱 / 授权 / 日历 / 管理**,
也没有玻璃悬浮底栏、主题壁纸同步、Composer 共用组件。

## 第一阶段(已完成并可验收)

- `common/Theme.ets` 补齐文字/浅底/语义令牌,页面里的旧调色板**全量替换为令牌**
  (共 203 处),`hvigorw assembleHap` **BUILD SUCCESSFUL**。
- 判据:`cross-client-theme.test.mjs` 新增"鸿蒙页面里不得再出现旧调色板色值"
  (6 条全绿,含扰动自检)。这条防的是**新页面又随手写个"差不多"的颜色** ——
  漂移就是这么开始的,而此前没有任何判据会红。

## 计划文档:docs/HARMONY-ALIGN-PLAN.md

写清两件事,免得每轮重新猜"还差什么":

- **差距表**(逐项,标出"缺页面/交互不同/观感不同"的性质);
- **分期**:P2 发件箱(与收件箱同构,风险最低)→ P3 授权页(备注必须随决策送达模型
  —— WebUI 侧踩过这个坑)→ P4 主题/壁纸同步(服务端"无记录"时以本地为准)
  → P5 玻璃悬浮导航 → P6 日历(最大,单独排)。

## 如实说明

鸿蒙**视觉未验证**:本机 `hdc list targets` 为空、HAP 未签名 ⇒ 只能保证编译通过 +
令牌一致,观感需要设备或签名后由人眼确认。文档里也把这条写进"验收纪律"。
2026-09-14 12:49:40 +08:00