Why: The fast and slow channel UI duplicated work cards and hid intermediate output after the final reply. Evidence: SELF isolated-network make test and make build; 15 browser scenarios; independent component review; component PRs #55, #199, #85. Impact: Pin merged Backend, Frontend and UI revisions and update DESIGN.md for one detail location and durable folded history. Refs: .task/feature-work-companion-visibility.md; Agent-System-UI #55; Agent-System-Backend #199; Agent-System-Frontend #85
21 KiB
Agent-System-Dev 设计系统(DESIGN.md)
写给 Agent 与人:在本仓生成或修改任何 UI 之前,先遵循本文,再发明新的视觉规则。 违反本文视为设计系统缺陷,不是风格偏好。
四原则:美观、现代、简洁、易用。每条规则都是四原则在某一维度上的可执行化。
参照体系:ZCode(zai-org/ZCode)开源仓的 DESIGN.md、packages/ui/src/styles.css
主题真值与动效配方。本文的色板、字号标尺、圆角层级、动效参数均逐条对照其源码校准。
1. 产品性格
Agent-System-Dev 是桌面优先、Web 兼容的 AI 工作台。界面应冷静、高密度、可操作,而非装饰性的。
为长会话、高信息密度、可读的对话与工具输出、键盘驱动的工作流而设计。
避免:营销式大留白、默认渐变装饰、大面积品牌色铺底、背景/卡片/浮层层次含混。
2. 主题
- 用户可选主题:跟随系统 / 浅色 / 深色。实现为
:root[data-theme='dark' | 'light']。 - 深色基准为 Zai Dark 复刻;浅色基准为 Zai Light。令牌唯一来源:
@ui/tokens.css。 - 禁止在组件里出现裸色值(hex/rgb 字面量);一切颜色经语义令牌消费。
守护测试(
design-guard.test.ts)以基线棘轮拦截新增裸值。
2.1 表面阶梯(层次靠背景阶梯,不是描边堆叠)
| 令牌 | 深色 (Zai Dark) | 浅色 (Zai Light) | 用途 |
|---|---|---|---|
--bg-inset |
#101010 |
#ececee |
窗口间隙(面板化布局的"底座")、代码底 |
--bg |
#161616 |
#f8f8f8 |
应用底、主区背景 |
--bg-panel |
#202020 |
#ffffff |
侧栏/面板/头部 |
--bg-raised |
#2b2b2b |
#ffffff |
卡片、输入、菜单、浮层 |
--bg-hover |
rgba(255,255,255,.05) |
rgba(13,13,13,.05) |
通用悬停 |
--bg-active |
rgba(255,255,255,.10) |
rgba(13,13,13,.08) |
选中态 |
2.2 边框(发丝三档)
--border-soft: rgba(255,255,255,.06) / --border: rgba(255,255,255,.10) /
--border-strong: rgba(255,255,255,.15)(浅色对应 13,13,13 的 .08/.10/.16)。
边框只做轮廓;选中优先用 --bg-active 填充而非换边框色。
2.3 文本
--text(主读文本,深 #d4d4d4 / 浅 #262626 / 墨绿 #082d4f)。
--text-dim:深 66% / 浅 68% / 墨绿 70%。
--text-faint:深 52% / 浅与墨绿 58%。
用文本层级制造信息密度,先于增加更多边框或颜色。
门槛(contrast-guard.test.ts,WCAG 2.1):
--text与--text-dim在主区表面(--bg、--bg-panel、--bg-raised、代码底--bg-inset)不低于 4.5:1。--text-faint不低于 3:1,并且只用于装饰:占位符、chevron、kbd、关闭图标的默认色。- 承载决策或需要读完的文字从
--text-dim起步:表头、确认详情、工具清单、空态说明、设置项描述、状态词。不要把 faint 当内容色。
侧栏另用 --text-sidebar-dim(墨绿 78%)与 --text-sidebar-faint(墨绿 62%),门槛与主区相同,只跟 --bg-sidebar 对拍。
侧栏会把 --text* 重映射成侧栏色。挂在侧栏 DOM 里、但画在主区纸面上的浮层(账户菜单)改用 --text-workspace*,这是同一套文字的不被重映射的副本。
2.4 强调与语义色
-
交互强调蓝:
--accent(深#4099ff/ 浅#0b7fff)。只用于链接、选中指示、聚焦环、 进行中指示;不做大面积铺底、不做主按钮底色。 -
主按钮:单色系反色——
--primary(深#ffffff/ 浅#0d0d0d)配--primary-foreground(反向黑/白)。品牌色保持克制。 -
语义图形色:
--ok #46bf72、--warn #ff8a30、--err #ff5c5c(浅色与墨绿#1e8a3e/#d17300/#e03131)。 语义色只表语义。图形色(状态点、描边、色条)在--bg/--bg-panel/--bg-raised上不低于 3:1。 图形色不作文字。 链接、状态词、差异文字、空闲状态字用下面的文字档。 -
文字档(同一色相,专门保证 4.5:1,含铺在
*-soft上):令牌 深色 浅色 / 墨绿 用途 --accent-text#58a6ff#0858b0链接、动作字 --warn-text#ff8a30#8d4d00警告文字;也作警告徽标底 --err-text#ff7272#a92525错误文字;也作错误徽标底 --ok-text#46bf72#17682f成功状态字 --idle-text#929292#636363空闲状态字 --diff-add-text#7dcea0#17682f差异增加的文字 --diff-remove-text#ff9b9b#a92525差异删除的文字 徽标:底用对应
*-text,字用--text-on-semantic(深#101010/ 浅与墨绿#ffffff)。 -
等你确认用
--wait(深#8b93ff/ 浅#3a46c8/ 墨绿#3d5a9a)和--wait-soft。 不借用成功绿,也不用红或橙装饰等待。 -
差异视图:增加用
--diff-add/--diff-add-text,删除用--diff-remove/--diff-remove-text。 -
空闲任务的图形用
--task-idle,文字用--idle-text。定时任务用--task-scheduled。两者不要混成同一种灰。
2.5 墨绿主题(可选,data-theme='molv')
暖纸白工作区、深海军蓝左栏与顶栏、翠绿强调。只覆盖表面与语义色;字号标尺、圆角、间距沿用 §3–§5,不另起一套。左栏与顶栏消费 --bg-sidebar / --text-sidebar*(深色与浅色下别名到面板与正文,墨绿下翻成海军蓝)。
| 令牌 | 墨绿 | 用途 |
|---|---|---|
--bg-inset |
#e0e0db |
窗口间隙 |
--bg |
#f2f2f0 |
对话主区 |
--bg-panel |
#fbfbfa |
右栏等面板 |
--bg-sidebar |
#082d4f |
左栏、顶栏 |
--text |
#082d4f |
主读文本 |
--text-sidebar |
#e9f0f6 |
左栏与顶栏文字 |
--accent |
#165f49 |
主区交互强调(翠绿)。不用于侧栏 |
--accent-sidebar |
#8fd4b4 |
侧栏内的强调:active 图标、聚焦边、选中条 |
--primary / --primary-foreground |
#082d4f / #f3f8f5 |
主区主按钮 |
--primary-sidebar / --primary-sidebar-foreground |
#e9f0f6 / #082d4f |
侧栏上的主按钮(「新建任务」) |
深色与浅色下,侧栏三令牌别名到主区:--primary-sidebar 同 --primary,深色 --accent-sidebar 同 --accent。浅色侧栏是白底,--accent-sidebar 改走 --accent-text(#0b7fff 在白底上不足 4.5:1)。侧栏内的 active、聚焦和主按钮只消费这组令牌,不直接用主区 --accent / --primary。
2.6 文档纸面(主题不变量)
Office 分页预览是内容,不是界面。纸面与默认墨色固定,三套主题同值:
| 令牌 | 值 | 用途 |
|---|---|---|
--paper |
#ffffff |
docx 页、幻灯片等文档纸面 |
--paper-ink |
#000000 |
纸面上没有自带颜色的文字的默认墨色 |
规则:保留文档自己的字号、颜色、表格和图片样式。禁止用 --bg / --text 等主题令牌覆盖这些内联样式。界面只负责纸面周围的底座(--bg-inset)和按栏宽等比缩放。
3. 字号标尺(唯一字号体系)
全局唯一可调变量 --ui-font-size(默认 14px),派生:
| 令牌 | 公式 | 默认 | 角色 |
|---|---|---|---|
--fs-ui-xl |
+4px | 18 | 阅读标题 h1 |
--fs-ui-lg |
+2px | 16 | 阅读标题 h2 |
--fs-ui-base |
= | 14 | 正文、常用按钮、区块标题 |
--fs-ui-caption |
−1px | 13 | 紧凑辅助文案 |
--fs-ui-sm |
−2px | 12 | 次要信息、行内代码 |
--fs-ui-xs |
−3px | 11 | 仅徽标与图标性字符 |
--fs-ui-tooltip |
同 --fs-ui-sm |
12 | 提示气泡。不另起字号 |
--fs-code |
−2px | 12 | 代码块、终端、Diff。随 --ui-font-size 缩放 |
规则:UI 组件一律用标尺令牌;禁止行内 font-size 数值与 Tailwind 式任意字号
(守护测试棘轮拦截)。用户调字号只改 --ui-font-size,不改根字号;图标、间距、圆角不随字号缩放。
设置中心「界面字号」提供 13 / 14 / 16 / 18 四档,写入 --ui-font-size,只存在本机(localStorage),不进账号设置。
表头用 --fs-ui-sm + --text-dim,不用 xs,也不要对中文做 uppercase。
例外:文档正文保留自己的阅读字号(约 13.5px),不跟界面标尺走。
字体:--font 系统栈优先(-apple-system/PingFang SC…);路径、命令、代码、快捷键用 --mono。
4. 间距
基数 4px。节奏:4(图标与文字)→ 8(控件内边距/行内间隙)→ 12(紧凑列表行)→ 16(卡片/面板标准内边距)→ 20–24(大区块/对话框内部)。用少量重复间距,不用任意值。
5. 圆角(按嵌套层级,不按组件重要性)
| 令牌 | 值 | 用途 |
|---|---|---|
--radius-xs |
4 | 最内层(嵌在 6px 控件里的小元素) |
--radius-sm |
6 | 基础控件(嵌套时降档)、chip |
--radius |
8 | 输入、菜单壳、工具行 |
--radius-lg |
12 | 卡片、气泡、工具调用块、面板(见 §6) |
--radius-xl |
16 | 对话框、全屏视图壳 |
--radius-full |
999 | 仅用于刻意的胶囊/圆形 |
嵌套降档:12 → 8 → 6 → 4;最内层不低于 4。对话框内部重新从 12 起算。
禁止任意值。rounded-full 不因组件类型自动获得。
6. 布局:三栏工作台
桌面工作区 = 浮在 --bg-inset 底座上的独立圆角面板(左栏 / 对话主区 / 第三栏):
面板 --radius-lg 圆角 + --border-soft 发丝描边,面板之间 4px 间隙,应用四周 4px 内衬。
拖拽分隔条:透明 4px 命中区,hover/拖拽时显示 2px --border-strong 指示线(两端留出面板圆角)。
左栏(找上下文):顶部切换项目(项目身份在此集中显示一次,含阶段徽章), 中段放会话列表与搜索,底部沉底放文件、领域工作区与账户。 第三栏(右栏,双入口「工作 / 文件」):工作入口承载待处理事项、后台任务、执行记录 与当前任务卡;文件入口承载文件搜索、多标签预览、编辑与下载——文件预览不再是独立第四栏。 工作档宽度可拖(280–560);文件入口在有预览标签时切到阅读档(420–1100),不受工作档上限约束。 打开文件自动进入文件入口的预览子视图;关掉最后一张标签回到文件列表。标签按会话记住, 切回该会话时恢复。全屏展开是文件预览的放大,不是第二落位。
层次规则:左栏与第三栏用 --bg-panel,对话主区与文件预览内容用 --bg;窄屏可退化为通栏。
信息架构原则:对话优先——普通用户仅凭对话即可完成全部工作,第三栏纯辅助、可完全收起;
系统管理类视图独立成区(管理员专属入口),不混入用户设置。
中右栏按对象分工:中栏按回合顺序保留用户输入、最终回复、文件入口和该轮可折叠的完整过程记录;
右栏「工作」是当前进度、待确认事项与成果卡的详细落位,右栏「文件」是文件列表与唯一预览。
右栏工作可见时,中栏只给需要定位的短入口,不复制完整工作卡或操作按钮;右栏关闭或切到文件时,
中栏承担完整卡片与操作。桌面顶栏的「工作/文件」入口只在右栏关闭时出现,窄屏保留导航。
当前工作卡的阅读表面使用 --work-focus-surface / --work-focus-border,两者由 UI 令牌定义。
7. 海拔(Elevation)
克制深度,分层顺序:背景对比 > 发丝描边 > 浮层阴影 > 注意级阴影。
- 基础层:无阴影,靠背景阶梯;
- 卡片:无阴影或
--shadow-md极弱; - 菜单/弹层:
--shadow-md; - Toast/重要浮卡:
--shadow-lg。
禁止用大软阴影做普通布局分层。
8. 动效(MotionKit)
动效解释状态变化,不装饰屏幕。快、低调;禁止长弹簧(仅点赞/完成反馈可用一次过冲)。
全部动效经 @ui/motion.css 的 mk-* 工具类消费;组件文件禁止私有 @keyframes
(守护测试拦截)。所有动效在 prefers-reduced-motion: reduce 下禁用。
| 工具类 | 参数 | 用途 |
|---|---|---|
mk-stream-in |
opacity,900ms cubic-bezier(0.16,1,0.3,1) |
流式内容进场(可按 token 加延迟) |
mk-rise-in |
fade + translateY(4px),180ms | 列表行/卡片进入 |
mk-waterfall |
clip-path + translateY(−12px),260ms cubic-bezier(0.22,1,0.36,1) |
建议列表逐条瀑布 |
mk-col / mk-col-inner |
高度 grid-rows 300ms ease-in-out + 内层 fade | 折叠/展开(@ui Collapsible) |
mk-sweep |
文字扫光,300% 渐变 4s linear | 运行态指示(不用 spinner) |
mk-breathe |
opacity .4↔1,1.2s | 状态点呼吸 |
mk-pop |
450ms cubic-bezier(0.34,1.56,0.64,1) |
点赞/完成过冲反馈(唯一弹性) |
mk-shimmer |
背景扫光 1.8s linear | 加载占位 |
mk-overlay-in / mk-modal-in |
140ms fade / 160ms fade+translateY(6px)+scale(.99) | 弹层进入 |
mk-panel-grow |
flex-grow 过渡 200ms ease-out(用时挂、transitionend 摘) | 面板开合 |
9. 组件范式
9.1 工具调用块(ToolBlock 契约,参照 ZCode ToolLayout)
单行摘要:[图标][工具名][主文本][副文本][状态词]。
- 运行中:工具名文字扫光(
mk-sweep),状态词最弱色;不用旋转图标(长流式期省渲染); - 完成默认收起;
autoOpen(如 edit/read 类)运行时自动展开一次,用户可再收起; - 完成边沿(running→completed)自动收起一次,不阻止用户手动展开;
- 展开态按 id 记忆,切回不丢;
- 失败不强制展开:状态词虚线下划线,hover tooltip 给报错,支持一键复制;
- 内容懒渲染,收起后延迟卸载(300ms,配合高度动画)。
- 模型、卡片和文档里的 HTML 只经
@uisafeHtml写入。外部图片和音视频不直接加载,改成带来源域名的链接;同源地址、data:image和blob:照常显示。
9.2 折叠(@ui Collapsible 原语)
一切折叠区(过程输出、长回复、任务卡)用它:外壳高度动画 + 内容 fade 两层分离、
300ms 延迟卸载、展开态记忆。禁止再写 <details> 折叠。
9.3 一个动作一个入口
同一对象只允许一个主要操作路径:一个工件 = 一个预览落位(第三栏「文件」入口)+ 预览 工具栏上的一个下载。对话里的文件卡片负责打开这个预览;卡片菜单里的下载是同一下载动作 的就近入口,不另开预览器。全屏 overlay 是文件预览的放大,不是第二落位。禁止弹窗套弹窗。
9.4 按钮
Primary(--primary 反色)、Ghost(透明,hover 出表面)、Danger(语义红)。
同一面板内保持动作层级,不把每个动作都升为 primary。
9.5 菜单与浮层
菜单壳 --radius(8) + --shadow-md + 紧凑行(--radius-sm 6 的行、--fs-ui-base);
菜单是紧凑动作行,不是迷你按钮。交互浮层必须盖过被动 tooltip。
9.6 工作时间线与标签条
助手消息默认先展示结论、必要确认与文件;工作状态用一行说明,技术执行记录按需展开。
- 默认运行中过程块也收起;块头是用户可理解的工作阶段,带
mk-sweep。用户手动展开或关闭自动折叠设置时可查看执行记录。 过程解说、已有的思考文本、工具调用与输出保留在同一轮折叠记录中;以已保存消息的顺序和内容为准,事件只补齐缺失输出与协作进展,不覆盖已保存文字。思考文本只在用户主动展开后可读,不作为最终结论。 查阅和搜索合并成一行;执行、写入、委派每次一条 ToolBlock: 编写参数时显示「编写中」和脚本尾部,运行时显示计时和输出尾部,结束后可展开看完整参数与结果。 终轮检查在过程区单独一行(通过,或未通过及原因),不写进给用户的回复。 - 终轮结束后,过程段收进 Collapsible,触发行为「已工作 X 分 Y 秒 · N 次工具调用 · N 个文件」。
用户在运行中手动折过的,结束后沿用这次选择。最终回复(终轮正文、交付物、错误)留在折叠行下面;
交付物卡片等到最终回复出来、这一轮结束后才出现,工作过程中不挂预览条。
若这次没有终轮正文,把最后一段解说提到折叠行下面,不把回复藏进过程里。
折叠区展开时按会话和 run 归属分页读取已保存的事件,补齐终态消息不带回的工具输出与子任务进展/结果;
读取失败时明确说明并只展示已有摘要,不暗示完整记录可用。旧记录缺失的内容不凭前端重造。
不在每一轮
responding时来回折叠。同一轮同名工件只留最新一张,并注明更新次数。 - 文件卡片:图标、名称、「类型 · 大小」、右侧「预览」。正文里的
art_编号若对得上工件,在正文后补一张卡片; 对不上则显示「未找到该文件」,不伪装成可打开的文件。 - 标签条用
@uiTabStrip:点击激活、× 关闭、中键关闭,溢出横向滚动。只消费令牌与mk-*。
10. 信息架构与文案
- 普通用户界面只暴露任务与对话;插件/代理/治理类能力归系统管理区(管理员可见)。
- 右栏收起时功能零缺失(D31:弹层不承载唯一步骤,每个操作另有对话内路径)。
- 中文文案:动宾结构、不带句点结尾;快捷键用
⌘/kbd 标注。 - 布局按
--text-expansion(1.3)给按钮和标签留膨胀空间。不要把宽度定死成当前中文的字数。截断不是唯一生存手段。
10.1 快捷键
| 动作 | 按键 |
|---|---|
| 新建任务 | ⌘N / Ctrl+N |
| 折叠或展开左栏 | ⌘B / Ctrl+B |
| 打开第 n 个工作区 | ⌘1–9 / Ctrl+1–9 |
11. 禁止清单(守护测试覆盖项)
- 组件/样式文件里新增裸色值(hex/rgb 字面量)——走令牌;
- 组件文件里私有
@keyframes——走 MotionKit; - TSX 行内
font-size——走字号标尺; - 运行态用旋转 spinner——用
mk-sweep/mk-breathe; - 弹窗套弹窗;
- 同一对象出现第二个预览落位(预览只在预览区,全屏是它的放大);
<details>折叠——用 Collapsible。- 绕过
safeHtml直接把 HTML 字符串写进页面(dangerouslySetInnerHTML或非空的innerHTML赋值)。 - 文字与背景的对比度低于门槛(正文与文字档 4.5:1,装饰 faint 与图形语义色 3:1)——
contrast-guard.test.ts。
12. 演进规则
改风格须在同一变更集中成对修改:UI 仓 PR 调整 tokens.css(必要时 motion.css),
Dev 组合 PR 更新 DESIGN.md 并固定对应 UI 提交;两者互链,附前后值对照并验证精确组合。
不允许只改代码不改文档。新增视觉规则先问:它属于结构、表面、交互还是状态?
拿不准时,选更安静的方案、用更强的信息层级。
12.1 对比度与字号(2026-10-05)前后值
| 令牌 | 之前 | 之后 |
|---|---|---|
--text-dim |
三主题 62% | 深 66% / 浅 68% / 墨绿 70% |
--text-faint |
深 38% / 浅与墨绿 42% | 深 52% / 浅与墨绿 58% |
--text-sidebar-dim / faint(墨绿) |
72% / 46% | 78% / 62% |
--warn(浅色、墨绿) |
#e07b00(白底 2.99:1) |
#d17300 |
--fs-ui-xs |
−4px(10px) | −3px(11px),仅徽标 |
文字档 *-text、--text-on-semantic、--accent-sidebar、--primary-sidebar、--fs-code、--idle-text |
无 | 见 §2.4–§3。图形色不再当文字用 |
12.2 三栏工作台信息架构(2026-10-11)
布局与入口收敛(无令牌变更,仅消费既有令牌):预览从「对话与右栏之间的独立第四栏」
并入第三栏「文件」入口(原「打开预览收起右栏」行为随之取消);左栏改为项目切换置顶、
会话与搜索居中、文件/工作区/账户沉底;顶栏不再重复项目身份;停止操作收敛到输入区,
输入框上方保留快慢通道轻量状态提示。工件 ⌘1 弹层撤销,文件浏览并入「文件」入口
(代理成为首个内置体系工具)。依据:三栏工作台方案(2026-10-11 评审);
实现为 Frontend feature/ui-three-column-workbench 组合变更。
12.3 渐进工作台(本次批准的界面设计)
沿用三栏、现有令牌与唯一文件预览。新用户默认浅色、辅助右栏收起,已有主题和布局偏好保留。中栏先给每轮结论,过程、会话设置和消息次要操作按需展开;后台工作通过同一任务卡显示。右栏「工作」打开时,工作卡详细内容与动作只在右栏;中栏保留对话顺序以及必要的定位入口。右栏收起或切到「文件」时,中栏提供完整工作卡。状态和动作只消费服务端已有内容。窄屏单面板提供上下文、对话、工作、文件与返回入口;不丢失同一预览的状态。
这是结构与信息层级调整;UI 仓新增当前工作卡的语义表面令牌,字号、圆角和动效仍使用现有标尺与原语。UI 组件与 Dev 精确 gitlink 组合验证后交付。设计与实施依据见 Documents 的 work-companion-ui-design r0.2 / plan r1,以及本次任务卡 I1。