158 lines
9.8 KiB
Markdown
158 lines
9.8 KiB
Markdown
# 对话页面待开发事项
|
||
|
||
对话台(ChatView)是全项目离 CYBER 原型最远的一页。设置页那套骨架已经落地,
|
||
但对话台没有套上 —— 全仓库只有 `SettingsView.vue` 在用 `cy-*` 骨架类。
|
||
|
||
本文记录已核实的差距和推进顺序。所有条目均已对照
|
||
`prototype_reference/hermes-ui-cyber-chat.html` 与真实组件确认,不是推测。
|
||
|
||
> **进度:P0 / P1 / P2 已全部完成**(2026-10-19)。变更片段见
|
||
> `chat-chain-changes/2026-10-19-chat-cyber-skeleton-pass.md` 与
|
||
> `chat-chain-changes/2026-10-19-three-colour-semantics.md`。
|
||
> 下方各条目已标注实测结果;与真实代码不符的旧记录就地更正并说明原因。
|
||
|
||
## 为什么对话台排在最前面
|
||
|
||
对话台是结构最复杂的一页:一个页面里有会话列表、气泡流、审批卡、输入区、
|
||
右侧两个面板,六种结构各自的视觉规则都不同。骨架层没套上来,意味着这六块
|
||
各自沿用迁移前的样子,霓虹暗色的辨识度出不来。
|
||
|
||
令牌层和控件层已经达标 —— `styles/global.scss` 里的 `neon-sheen`、
|
||
`neon-pulse`、各处 `text-shadow` 都在。**缺的是页面骨架层和组件级语义配色**,
|
||
也就是原型第 3、7、9 三节。
|
||
|
||
## 现状:骨架类使用情况
|
||
|
||
> **注意**:本节记录的是 P0/P1 动工**之前**的基线。对话台最终没有套用
|
||
> `cy-view` / `cy-panel` 这类通用骨架类 —— CYBER 语义是按「每种颜色只承担
|
||
> 一种含义」逐组件落的(见下文 P1),直接套骨架类反而会把语义抹平。
|
||
> 真正补上的是 `global.scss` 里的 `.cy-led` 与 `@keyframes live-ring`。
|
||
|
||
`cy-view` / `cy-panel` / `cy-tabs` / `cy-sec-t` 的全仓库使用点:
|
||
|
||
| 文件 | 位置 |
|
||
| --- | --- |
|
||
| `views/hermes/SettingsView.vue` | `cy-tabs`、`cy-panel`、`cy-panel-b` |
|
||
| `styles/global.scss` | 定义处 |
|
||
|
||
对话台相关组件 —— `ChatPanel.vue`、`MessageList.vue`、`MessageItem.vue`、
|
||
`ChatInput.vue`、`SessionListItem.vue` —— **一个都没用**。
|
||
|
||
## 任务清单
|
||
|
||
### P0 · 修 rainbow-glow(违反三色语义规则)✅ 已完成
|
||
|
||
一次动画里四种语义色同时在闪,直接违反「同屏内每种颜色只承担一种含义」。
|
||
硬编码值,未走令牌。
|
||
|
||
三处重复定义,需要收敛成一处:
|
||
|
||
| 文件 | 行 |
|
||
| --- | --- |
|
||
| `components/hermes/chat/MessageItem.vue` | `1523`(定义)、`1451`(调用) |
|
||
| `components/hermes/chat/SessionListItem.vue` | `409`(定义)、`395`(调用) |
|
||
| `components/hermes/group-chat/GroupMessageItem.vue` | `1051`(定义)、`1114`(调用) |
|
||
|
||
原色值循环:`#ff6b6b` → `#feca57` → `#48dbfb` → `#ff9ff3` → 回环。
|
||
|
||
**处理结果**:三处本地 `@keyframes rainbow-glow` 全部删除(约 130 行重复),
|
||
改用 `global.scss` 里单一定义的 `@keyframes live-ring` —— 荧光绿
|
||
(`--success`,语义为「机器在动」)单色呼吸,不再循环。`.speech-playing`
|
||
与 `.streaming` 两类「机器正在动」的指示形态从此共用这一个动画。
|
||
|
||
### P1 · 组件级语义配色 ✅ 已完成
|
||
|
||
| 项 | 原型 | 真实实现(更新于 2026-10-19) |
|
||
| --- | --- | --- |
|
||
| 发送键扫光 | 原型 133-140:28×26,青管壁 + `sheen` 每 3.4s 扫过 | **已完成**。移除 `border: 0 !important` + `box-shadow: none !important`(原本把 `neon-tube` 整个抹平),恢复全站霓虹管 + 扫光;禁用态不再硬编码 `#9f9f9f` 灰块,走全局熄灭态;新增 `.send-button--stop` 琥珀橙中断态 |
|
||
| 气泡 role 配色 | 原型 216-227:用户=青、助手=绿,助手气泡左缘一道 `lime-line` | **此前记录有误,实为已完成**。`MessageItem.vue:1310` 用户气泡 `border-right: 2px solid rgba(var(--accent-primary-rgb), 0.45)`;助手气泡 `border-left: 2px solid var(--success-line)`;`.message-bubble.system` 琥珀橙边 + 橙底;`.agent-error` 用 `$error`。由 `2026-10-19-three-colour-semantics.md` 完成 |
|
||
| LED 指示灯 | 原型 151-156:7px 圆点 + 发光 + 呼吸动画 | **已完成**。`global.scss` 新增 `.cy-led`(7px 圆点),绑定真实 `appStore.connected`:连通=绿 + `led-breathe` 呼吸,断开=红且**静止**(死连接不该看起来还在动)。挂在 `ChatPanel.vue` 顶栏标题后 |
|
||
| 会话列表当前项 | 原型 190-192:青软底 + 左侧 2px 发光条 | **已完成**。`SessionListItem.vue` 的 `.session-item.active` 从 `box-shadow: 0 0 0 3px` 描边改为青软底 + `inset 2px 0 0` 左侧发光条(用 inset 而非 `border-left`,避免挤动整行内容宽度) |
|
||
| 顶栏青色微光 | 原型 200-201:`radial-gradient` 压顶 | **已完成**。`ChatPanel.vue` 的 `.chat-header` 压一层 `radial-gradient(120% 160% at 50% 0%, rgba(var(--accent-primary-rgb), 0.07), transparent 70%)`。用 radial 而非 linear —— linear 会让整条边均匀发亮,反而没有「压顶」的层次 |
|
||
| 审批卡橙区 | 原型 264-267:橙边 + 内发光 | **此前记录有误,实为已完成**。`MessageList.vue` 的 `.approval-float-panel` 已用 `var(--warning-line)` 边框 + `--warning-soft` 底 + `inset 0 0 22px rgba(var(--warning-rgb), 0.06)` 内发光 + `@keyframes approval-pulse`。由 `2026-10-19-three-colour-semantics.md` 完成 |
|
||
| 上下文余量条 | 原型 273-278:绿→橙→红三段 | **此前记录为「待确认」,实为已完成**。`ChatInput.vue:1061-1064` 按 `usagePercent` 分三段:默认绿、>60%~80% 转 `context-bar-warn`(橙)、>80% 转 `context-bar-danger`(红) |
|
||
|
||
### P2 · 响应式 ✅ 已完成
|
||
|
||
原型 166-177 定义了两档断点:
|
||
|
||
- `≤1180px`:Outline 从挤压主区改为浮层覆盖(`position: absolute`)
|
||
—— **已完成**。`OutlinePanel.vue` 在 ≤1180px 下改 `position: absolute` +
|
||
`z-index: 20` + 左侧投影;≤768px 进一步收窄为 `min(280px, 86vw)`。
|
||
右上角的 Outline 按钮本身就是开关,不需要额外关闭控件。
|
||
- `≤900px`:顶栏 `.ws-tag` / 工作区徽标隐藏 —— **已完成**。
|
||
`ChatPanel.vue` 在 ≤900px 下 `.workspace-badge { display: none }`。
|
||
|
||
> **与原建议的一处偏离**:原型在 ≤900px 还要求「会话侧栏整体隐藏」,**未采纳**。
|
||
> 真实实现的会话侧栏由顶栏 toggle 按钮控制显隐,隐藏整列后用户将无法再打开 ——
|
||
> 比挤一点更糟。窄屏下改为只隐藏次要信息(工作区徽标),侧栏交给 toggle。
|
||
|
||
> 核实记录:真实实现原本只有 `$breakpoint-mobile`(768px)一档断点,
|
||
> 不存在 ≤1180px 的等价实现。
|
||
|
||
## 已知原型侧问题(不是待开发项)
|
||
|
||
以下原型自身与真实实现不符,接入时以真实实现为准,不要照抄原型:
|
||
|
||
- **会话来源标签**:原型列了 8 种,真实只有 4 种
|
||
(`api_server` / `cli` / `global_agent` / `workflow`,见
|
||
`stores/hermes/chat.ts`)。原型里的 `cron` / `channel` / `group_chat` /
|
||
`terminal` / `file` / `kanban` 不存在。
|
||
- **`moa` 作为气泡 role**:原型写进「role 全集」,但真实 `Message.role` 是
|
||
5 元联合类型(`stores/hermes/chat.ts:47`)。`moa` 是 `display_role`,
|
||
渲染时被映射成 `system`(同文件 `:483`)。原型的 `.bubble-row.moa` 和
|
||
`AV.moa = '◇'` 都应删。
|
||
- **Outline 的「附件」区块**:原型 578-580 有,真实 `OutlinePanel.vue:82-111`
|
||
只产出「用户提问 + h1/h2/h3 标题」两类条目,没有附件概念。
|
||
- **会话列表 `⌕` 搜索按钮**:原型 498 有,全项目无会话搜索功能。
|
||
- **顶栏副标题 `01JQ8F2K · default profile`**:原型 618 有,真实 header 只有
|
||
单个 `headerTitle` 字符串(`ChatPanel.vue:307-311`),无第二行。
|
||
- **`m.reasoning` 作为消息字段**:原型当作字段,实际是
|
||
`utils/thinking-parser.ts:51` 从 `content` 里正则摘 `<think>` 标签得到。
|
||
折叠交互是真的,数据结构是假的。
|
||
- **`⇤` 语义错位**:原型 615 画成「返回」,真实同位置是切换会话侧栏显隐。
|
||
- **`~/work/hermes-ui` 完整路径**:真实 `workspace-badge` 只显示 basename
|
||
(`ChatPanel.vue:1599`)。
|
||
- **顶栏常驻 `streaming` tag**:真实 streaming 标记在会话列表项上
|
||
(`ChatPanel.vue:1209`),不在 header。
|
||
|
||
## 执行顺序建议(已执行)
|
||
|
||
1. **P0 rainbow-glow** ✅ —— 三处收敛成一处,删约 130 行重复。
|
||
2. **P1 组件级语义配色** ✅ —— 逐块推进,每块单独验证。
|
||
3. **P2 响应式** ✅ —— 在 P1 布局稳定后落地。
|
||
|
||
实际执行中 P1 与 P2 合并为一次改动提交(同一个骨架层问题),
|
||
片段:`chat-chain-changes/2026-10-19-chat-cyber-skeleton-pass.md`。
|
||
|
||
## 验证基线
|
||
|
||
改动前后都应跑:
|
||
|
||
```bash
|
||
npm run harness:check
|
||
npm run test # 当前 277 文件 / 2047 通过
|
||
npm run test:e2e # 当前 46 通过
|
||
npm run build
|
||
```
|
||
|
||
`chat/` 属聊天链,改动需要 `docs/chat-chain-changes/<date>-<slug>.md` 片段,
|
||
`harness:check` 会强制校验。
|
||
|
||
### 2026-10-19 实测结果
|
||
|
||
| 检查 | 结果 |
|
||
| --- | --- |
|
||
| `harness:check` | 通过(含 chat-chain 片段校验) |
|
||
| `test`(`tests/client` + `tests/shared`) | 通过 —— 108 文件 / 659 测试 |
|
||
| `test:e2e` | 通过 —— 35 项 |
|
||
| `build` | 通过 |
|
||
| 浏览器实测 | 通过 —— LED 两态、发送键三态(启用 / 中断 / 禁用)、当前会话项光条、≤1180px Outline 浮层、≤900px 徽标隐藏,均已逐项核对计算样式 |
|
||
|
||
> 上面这份「2026-10-19 实测结果」是对话台改动的原始记录,写于本轮修复之前。
|
||
> 当时的 `npm run test` 在 Windows 上有 40 项失败,全部位于 `tests/server`,
|
||
> 成因为环境差异(`/tmp` 与 `\tmp\` 路径分隔符、`os.homedir()` 在 Windows 读
|
||
> `USERPROFILE` 而非 `HOME`、测试端点写死了 POSIX IPC 形态)。
|
||
> 这些失败已在 2026-10-19 全部修掉:改成平台无关的等价断言,而不是跳过用例,
|
||
> 因此 Linux / macOS 的行为不受影响。当前 `npm run test` 在 Windows 上 0 失败。
|