34 KiB
WorkBuddy 界面实测数据(YCode 视觉对齐依据)
历史实测参照,尚需通过 REA 复核。现行目标是视觉、交互与功能 1:1;本文旧版分级中的“不做/不可能”不能用于缩减范围。后续所有原版采集使用 REA,禁止直接运行
wb-*CDP 脚本绕过。接手记录见接手状态-2026-10-15.md。
采集方式:CDP(WORKBUDDY_REMOTE_DEBUGGING_PORT=9223)+ scripts/wb-capture.mjs / scripts/wb-tree.mjs
采集环境:WorkBuddy 37.10.3-42,Windows,视口 1334 × 901,DPR 1,zoom 1.000,浅色主题
采集时间:2026-10-15
原始产物:%USERPROFILE%\.ycode\captures\(含真实对话,不入库)
说明:以下均为运行时 computed style 实测值,不是静态 CSS 推断。 换窗口尺寸或字号档位需重新采集。
0. 参照文档与对齐分级
同项目源头文档已复制到 docs/reference/,不必再跳到别的仓库:
| 文档 | 用途 |
|---|---|
workbuddy-cdp.md |
采集 SOP(开启调试端口、采集流程、边界与常见问题) |
workbuddy-chat-layout.md |
对话区布局实测(字号 token、宽度约束、滚动策略) |
workbuddy-composer-reference.md |
输入区专项参考 |
ygent-ui-pixel-parity-feasibility-2026-10-14.md |
像素级对齐可行性结论与分级目标 |
ygent-font-parity.md |
字体与六档字号对齐 |
ygent-sidebar-parity.md / ygent-settings-parity.md / ygent-model-composer-parity.md |
分区对齐记录 |
ygent-workbuddy-render-audit-2026-10-08.md |
40 项逐项差异审计(含坐标/字库/间距) |
ygent-workbuddy-ai-gap-2026-10-14.md |
能力差距盘点 |
ygent-chat-parity.md |
对话区对标路线图 |
ygent-chat-interaction-parity.md |
L3 动态交互对标与验收(必测序列、事件与渲染状态) |
ygent-chat-stage-summary-2026-10-08.md |
分阶段汇总 |
ygent-streaming-activity.md |
流式活动播报 |
ygent-chat-edit.md / ygent-chat-approval-questions.md |
消息编辑 / 审批提问 |
ygent-rich-content.md / ygent-attachments.md |
富内容与附件 |
ygent-session-titles.md / ygent-shell-settings.md |
会话标题 / 壳层设置 |
ygent-debug.md |
ygent 侧 CDP 调试 |
workbuddy-independent-conversations-2026-10-08.md / workbuddy-reference-import.md |
独立会话与参照导入 |
ygent-岗位与项目团队方案.md |
岗位/团队方案(后续扩展参考) |
对齐分级(直接采用其结论,避免重复踩坑)
| 级别 | 目标 | 可行性 |
|---|---|---|
| L1 几何对齐 | 同视口/同字号下关键锚点与尺寸 ≤1px 取整误差 | ✅ 可达 |
| L2 静态像素对齐 | L1 + 图标路径/颜色/阴影/滚动条 | ⚠️ 90%+,宿主原生控件除外 |
| L3 动态交互一致 | 事件序列、折叠时机、滚动、取消/恢复 | ⏳ 真正的目标,未完成 |
| L4 全局 100% 像素一致 | 含宿主 chrome、平台入口、跨机器字形 | ❌ 不可能,不做 |
明确不做(沿用其约定)
- 不伪造消耗 / 模型元数据 / 产物计数以凑齐视觉
- 不复制平台商业入口(邀请卡、账号区)与无效操作按钮
- 不为对齐硬补高度
- 不把静态像素通过宣称为动态交互通过
- 不把任一端的绝对 y 差直接当作要修的 margin
已知的跨宿主差异(不可消除)
- 渲染引擎版本不同 → 默认 UA 样式、原生滚动条伪元素、字体回退顺序可能不同
- 系统字库为各机本地安装,不随项目分发 → 跨机器像素一致不成立
- 顶栏 chrome 与侧栏数据层级属宿主结构差,不应为复制而破坏已对齐的内部坐标
1. 顶层布局
| 区域 | 实测 |
|---|---|
| 菜单栏 | 高 30px(.codebuddy-menubar) |
| 左栏 | .conversation-sidebar x=0 y=30 280 × 871 |
| 主内容区 | 宽 1054px(1334 − 280) |
| 右栏(详情面板) | .detail-panel-container 宽 1px —— 默认收起 |
2. 左栏(侧栏)
| 元素 | 实测值 |
|---|---|
容器 .conversation-list |
280 × 871,背景 rgb(247,247,247) = #f7f7f7 |
头部 .conversation-list-header |
279 × 288,padding: 0 12px 20px,gap: 2px,flex column |
品牌行 .conversation-list-logo-row |
255 × 64(min-height 40),gap: 4px,align center |
品牌标题 .logo-*-title |
14px / 700,行高 22px,色 rgba(0,0,0,.9),左边距 12px |
| 版本行 | 高 18,padding-left: 12px,margin-top: -4px,gap: 6px |
| 版本徽标 | 10px,行高 18,letter-spacing: .2px,色 rgba(0,0,0,.5) |
次级按钮 .wb-button--secondary |
98 × 28,padding: 4px 6px 4px 8px,gap: 2px,背景 #f2f2f2,色 rgba(0,0,0,.7),边框 1px #ebebeb,圆角 100px,字号 12px / 500 |
导航按钮 .conversation-list-tab-button |
255 × 32,padding: 5px 12px,gap: 8px,圆角 8px,图标 16 × 16,标签 14px / 行高 22 |
| Beta 徽标 | 10px,大写,padding: 0 5px,边框 1px #dedede,圆角 100px,色 rgba(0,0,0,.45),行高 16 |
分组标签 .conversation-section-label |
255 × 30,padding: 5px 12px,圆角 8,背景 #f7f7f7,gap: 4px |
| 分组文字 | 12px / 600,行高 20,色 rgba(0,0,0,.5);形如「任务 (1)」 |
| 分组折叠箭头 | 14 × 14,色 rgba(0,0,0,.3) |
| 分组小按钮 | 20 × 20,圆角 4,色 rgba(0,0,0,.5) |
会话项 .conversation-item |
255 × 31;内层 .cb-agent-card padding: 5px 12px、圆角 8px |
| 会话项标题 | 14px / 行高 21,字重 400,色 rgba(0,0,0,.9),左 24 |
| 会话项时间 | 11px / 行高 20,色 rgba(0,0,0,.5),右对齐(同一行,非第二行) |
3. 对话区
| 元素 | 实测值 |
|---|---|
.cr-message-list |
x=280 y=94 1054 × 639,基础字号 13px |
.cr-message-list__content |
宽 832(max-width 832),padding: 0 40px → 正文列 752 |
.cr-agent |
752 宽,flex column,色 rgba(0,0,0,.9),13px / 行高 19 |
.cr-agent__header |
752 × 24.5,margin-bottom: 12px,gap: 10px,align center |
.cr-markdown |
17.143px / 行高 30.0002px |
.cr-markdown p |
15.0001px / 26.2502px,margin-bottom: 12px |
.cr-self-message |
flex row,justify-content: flex-end,align-items flex-start,gap: 8px |
.cr-self-bubble |
min-width: 40px,max-height: 310px,padding: 8px 12px,gap: 4px,背景 rgb(242,242,242),border-radius: 16px 16px 0,13px / 19px |
.cr-collapse__header |
高 26.25,gap: 8px,max-width: 100%,色 rgba(0,0,0,.5),15px / 26.25px |
主文字色是 rgba(0,0,0,.9),不是 #000。
4. 输入区(最容易做错的地方)
| 元素 | 实测值 |
|---|---|
.cr-input-box |
x=415 y=733 784 × 134,z-index: 16 |
.cr-input-box__main |
border-radius: 24px,gap: 4px,flex column |
.cr-input-container |
背景 rgb(255,255,255)(白底,不是渐变);边框 1px rgb(230,230,230);圆角 24px;min-height: 96px;padding-top: 12px |
| 阴影 | 双层:rgba(0,0,0,0.03) 0 16px 32px -8px, rgba(0,0,0,0.06) 0 2px 4px -4px |
| 聚焦态 | 边框色变 rgba(0,0,0,.15) |
.cr-input-editor-host |
782 × 64(min-height 64),padding: 0 16px |
| 输入文字 | 14px / 行高 21 |
.cr-input-toolbar |
782 × 56,padding: 12px,gap: 8px,justify-content: space-between,min-height 32 |
.cr-input-toolbar__right |
286 × 32,gap: 4px,背景 #fff |
.cr-send-button |
32 × 32,border-radius: 50% |
几何关系:12 (padding-top) + 64 (编辑区) + 56 (工具栏) ≈ 134 ✓;输入框 784 = 832 − 48。
⚠️ 注意区分两个 composer:
--wb-bg-input-slot-gradient(linear-gradient(180deg,#ebebeb,#f5f5f5))属于.wb-home-composer__input-slot(首页新建对话); 会话内输入框.conversation-input__box明确定义background: 0 0(透明)+ 白底容器 + 描边。两者不可混用。
5. 右栏:详情面板(展开态实测)
采集时视口变为 1638 × 901(用户展开面板后窗口更宽)。CSS 中
.detail-panel-container为width: 100%, 实际宽度由外层布局决定,面板可拖拽调宽;本次实测宽 647px。
| 元素 | 实测值 |
|---|---|
.detail-panel-container |
647 × 871,border-left: 1px solid #ebebeb |
.sidebar-next |
646 × 871,背景 #fff,border-radius: 12px 12px 0 0 |
.detail-layout |
flex column,白底 |
.detail-layout__top |
646 × 64(min-height 64) |
.sidebar-next-main-header |
646 × 64,padding: 0 16px,justify-content: space-between,gap: 4px,白底 |
.artifact-tabs |
高 32,gap: 4px |
.artifact-tab(当前项) |
240 × 32(min-width 80 / max-width 240),padding: 0 8px,gap: 4px,背景 #f2f2f2,圆角 8px,14px / 600,行高 22 |
.artifact-tab__icon |
16 × 16,色 rgba(0,0,0,.7) |
.artifact-tab__close |
14 × 14,色 rgb(119,119,119),border-radius: 999px |
.artifact-tabs__add |
32 × 32,圆角 8,图标 16 × 16 |
| 顶栏右侧操作 | 两个 32 × 32 按钮(gap: 4px),圆角 6px,图标 16 × 16,色 rgba(0,0,0,.7) |
.detail-layout__content |
646 × 807 |
.detail-main__body |
背景 #fff |
6. 图标采集与替换
真实界面的图标都是内联 SVG(<svg><path fill="currentColor">),不是字体图标(codicon 类名只在少量 VS Code 继承处出现)。
采集链路:scripts/wb-icons.mjs(CDP 取指定节点的 SVG outerHTML → icons.json)→ scripts/gen-icons.mjs(生成 src/renderer/src/components/icons.tsx)。
| YCode 组件 | 来源 | 尺寸 |
|---|---|---|
IconNewTask |
侧栏「新建任务」 | 16 |
IconChevronDown |
「发现应用」下拉箭头 | 14 |
IconFilter |
侧栏顶栏筛选 | 16 |
IconCompact / IconSectionAdd |
分组操作 | 16 |
IconPlus |
输入区「+」 | 16 |
IconShield |
「允许完全访问」盾牌 | 16 |
IconChevronSmall |
模型选择器箭头 | 12 |
IconMic |
语音输入 | 16 |
IconStop |
停止(圆底 + 圆角方块) | 32 |
IconTab |
详情面板页签 | 13 |
IconClose |
页签关闭 | 14 |
IconChevronRight |
「查看所有产物」 | 8 |
IconPanelCollapse / IconPanelRight |
面板收起 / 右侧栏 | 16 |
⚠️ 来源与替换要求:
icons.tsx中的矢量路径取自 WorkBuddy 运行时界面, 属于第三方产品界面资产,仅作为当前阶段 1:1 还原的临时占位(用户明确要求"先用 workbuddy 的,先 1:1 还原,然后再改造")。 正式发布前必须整体替换为自有图标或开源图标集。 对比:VS Code codicon 为 MIT 许可,可长期使用;本项目的icons-extra.tsx是自有矢量,可保留。
7. 标题栏与菜单栏(实测)
| 元素 | 实测值 |
|---|---|
| 顶部条带 | 高 30px,通栏 |
| 左侧操作区 | x=0 宽 92px(侧栏顶部操作) |
.codebuddy-menubar |
x=92 宽 227,padding-left: 4px,flex row,align center |
菜单按钮 .menubar-menu-button |
高 30px |
菜单标题 .menubar-menu-title |
高 24,padding: 2px 8px,圆角 4px,12px / 行高 20,色 rgb(139,148,158) = #8b949e |
| 菜单项 | 编辑(E) / 窗口(W) / 帮助(H) / 关于(A) |
| 右侧窗口控制区 | x=2422 宽 138px(约 46px × 3:最小化 / 最大化 / 关闭) |
这是自绘菜单(VS Code 风格),不是系统原生菜单。YCode 已改为
frame: false无边框窗口 + 渲染进程自绘标题栏(components/TitleBar.tsx), 菜单项均接真实行为(编辑用原生 role、窗口用 IPC、帮助/关于打开对应对话框)。
无边框窗口注意:条带设 -webkit-app-region: drag 负责拖动窗口,
按钮与菜单设 no-drag;主进程需 Menu.setApplicationMenu(null) 去掉原生菜单。
8. 空态与免责声明(实测自 CSS)
说明:采集时 WorkBuddy 处于会话中,页面无空态元素,以下取自安装包 CSS 规则(非冒烟实测), 待用户切到新建对话页后可做一次
wb-tree复核。
空态 .claw-agent-chat-pane .colleague-chat-empty--profile
| 元素 | 实测值 |
|---|---|
| 容器 | flex column,居中,gap: 24px(spacing-7),padding: 0 16px(spacing-5),text-align center |
| 头像 | 64px(spacing-12),border: 1px solid 边框色 --wb-color-border-secondary = #ebebeb,border-radius: 18px(radius-lg 8 + md 6 + sm 4),margin-bottom: 16px |
| 标题 | 24px / 34 / 500,色 text-primary |
| 说明 | max-width: 324px,12px / 18,色 text-tertiary |
| 快捷提问容器 | flex column,align-items: flex-start,gap: 16px(spacing-5) |
快捷提问胶囊 .conversation-embed-empty__quick-prompt
min-height: var(--wb-size-control-md)、padding: 10px 16px、border-radius: 9999px、
背景 --wb-color-bg-primary-default = gray-3 #f2f2f2、文字 color-mix(text-primary 90%, transparent)、
14px、行高 21、white-space: nowrap、border: 0。
免责声明 .claw-local-empty__disclaimer / .conversation-embed-empty__disclaimer
padding: 8px 0、text-align center、色 --wb-color-text-disabled = rgba(0,0,0,.3)、
12px、line-height: 20px、user-select: none、pointer-events: none。
文案:「内容由 AI 生成,请核实重要信息」。
输入区(空态变体)
.claw-local-empty__input-area:width: 100%、max-width: 832px、padding: 0 16px、margin: 0 auto。
.conversation-embed-empty__input-area:--cb-input-content-radius: 22px、--cb-input-main-area-radius: 22px、
--cb-content-background: transparent。
9. 间距阶(编号已与对标对齐)
| 编号 | 值 | 编号 | 值 |
|---|---|---|---|
| spacing-1 | 2px | spacing-7 | 24px |
| spacing-2 | 4px | spacing-8 | 32px |
| spacing-3 | 8px | spacing-9 | 40px |
| spacing-4 | 12px | spacing-10 | 48px |
| spacing-5 | 16px | spacing-12 | 64px |
| spacing-6 | 20px |
YCode 的
--yc-space-N编号与之一一对应,翻译对方 CSS 时无需换算。
10. 与 YCode 的差距(本轮已修 / 待修)
已修正
- 空态:改为「64px 圆角头像(18px 圆角 + 1px
#ebebeb边框) + 标题 24px/500 + 说明 12px/18 max-width 324px + 胶囊快捷提问(padding: 10px 16px、圆角 9999、底色#f2f2f2)」 - 输入区下方免责声明:新增「内容由 AI 生成,请核实重要信息」(12px、居中、色
rgba(0,0,0,.3)、padding: 8px 0) - 间距阶:
--yc-space-N编号对齐对标 spacing 阶(原实现整体错位一档) - 标题栏 + 菜单栏:Electron 原生菜单 → 无边框窗口(
frame: false)+ 自绘 30px 条带;菜单编辑(E)/窗口(W)/帮助(H)/关于(A),12px /#8b949e/ 标题padding: 2px 8px/ 圆角 4;右侧 46px×3 窗口控制 - 主文字
#000→rgba(0,0,0,.9) - 侧栏背景
#f2f2f2→#f7f7f7 - 输入框:错误地改成渐变 → 改回白底 + 1px
#e6e6e6+ 圆角 24 + 双层阴影,宽度 832 → 784,min-height96 - 侧栏列表项:
padding 8px 20px+ 13px + 两行堆叠 → 31px 单行,padding 5px 12px,圆角 8,标题 14px 左 + 时间 11px 右 - 侧栏结构:改为「品牌行(64px) + 版本行 + 导航项 + 分组标签(30px) + 列表项」
- 右侧详情面板:默认显示 → 默认收起(对齐真实默认态);展开态已按实测改为「顶栏 64px + 页签 32px/圆角8/底色 #f2f2f2/14px600 + 右侧 32×32 操作按钮(圆角6)」,面板白底 + 上圆角 12 +
border-left 1px #ebebeb - 详情面板拖拽调宽:新增
.app-shell__resizer手柄(0 宽网格列 + 6px 命中区伪元素,hover/拖拽显示品牌色指示线);宽度状态在App.tsx,以--yc-layout-right注入网格;范围 320–900px,默认 647px(对齐实测值)。面板收起时手柄一并卸载。已实测:左拖 150px → 797px、右拖收窄、越界夹在 320 / 900
待补(需要真实界面数据)
- 侧栏顶部完整导航项(助理 Beta / 专家·技能·连接器 / 定时任务 / 资料库 / 更多)—— YCode 目前只实现「新建对话」与「任务」分组,不伪造未实现入口
- 权限选择器、麦克风等输入区工具项
- 图标集:真实界面用 SVG 图标(16×16),YCode 已接入采集图标(见第 6 节,正式发布前需替换)
10.1 对话区顶栏(补充实测)
| 元素 | 实测值 |
|---|---|
.workbuddy-topbar |
高 64px,padding: 0 16px,align-items center,justify-content: space-between |
.workbuddy-topbar-options |
高 32px,位于顶栏内部左右两端 |
| 顶栏下方首行 | .cr-collapse--summary(「已完成 3m2s」行),字号 13px |
据此 YCode 的
.chat-head由自拟的padding: 12px 20px 10px改为 高 64px /padding: 0 16px/ 两端对齐,与实测一致。
11. 完整 design token 表(对标体系镜像)
来源:安装包 tokens-Df-i-zsO.css / contexts-BkjwYSZT.css。
YCode 的 --yc-* 编号与对标 --wb-* 一一对应,翻译对方 CSS 时是机械映射。
11.1 间距阶 --wb-spacing-N
| N | 值 | N | 值 |
|---|---|---|---|
| 1 | 2px | 7 | 24px |
| 2 | 4px | 8 | 32px |
| 3 | 8px | 9 | 40px |
| 4 | 12px | 10 | 48px |
| 5 | 16px | 12 | 64px |
| 6 | 20px |
11.2 字号阶 --wb-font-size-N
| N | 值 | N | 值 |
|---|---|---|---|
| 1 | 8px | 7 | 18px |
| 2 | 10px | 8 | 20px |
| 3 | 12px | 9 | 24px |
| 4 | 13px | 10 | 28px |
| 5 | 14px | 11 | 32px |
| 6 | 16px |
行高:4:16 4-2:18 5:20 5-2:22 6:24 7:28 8:32 10:40
字重:400 500 600 700
11.3 控件尺寸阶 --wb-size-N
| N | 值 | N | 值 |
|---|---|---|---|
| 3 | 12px | 9 | 36px |
| 3-2 | 14px | 10 | 40px |
| 4 | 16px | 11 | 44px |
| 5 | 20px | 12 | 48px |
| 6 | 24px | 13 | 52px |
| 7 | 28px | 14 | 56px |
| 8 | 32px | 17 | 68px |
语义别名:control-sm 24 control-ms 28 control-md 32 control-lg 40 control-xl 48 control-2xl 56
11.4 圆角阶 --wb-radius-*
none 0 xs 2 sm 4 md 6 lg 8 xl 12 2xl 16 3xl 20 4xl 24 full 9999
11.5 语义字号(体例)
| 角色 | 字号 | 行高 | 字重 |
|---|---|---|---|
| body | 14 | 22 | 400 |
| body-strong | 14 | 22 | 600 |
| caption | 12 | 18 | 400 |
| code | 13 | 20 | 400 |
| h1 | 24 | 32 | 600 |
| h2 | 20 | 28 | 600 |
| h3 | 16 | 24 | 600 |
| display | 32 | 40 | 700 |
11.6 语义字号(对话流 chatflow,对标独立一套)
| 角色 | 字号 | 行高 |
|---|---|---|
| h1 | 21 | 37 |
| h2 | 19 | 33 |
| h3 | 17 | 30 |
| h4 | 15 | 26 |
| p1 | 15 | 26 |
| p2 | 13 | 23 |
| p3 | 11 | 19 |
11.7 全局字号档位(六档)
机制:级别存 localStorage,同时更新「Markdown 根字号」与「全局字号偏移」;
偏移经 clamp(-1, global, 2) 夹取后作用于各语义 token。
| 档位 | --cb-md-root |
全局偏移 |
|---|---|---|
| 1 | 16px | −1 |
| 2(默认) | 17.143px | 0 |
| 3 | 18.286px | +1 |
| 4 | 20.571px | +2 |
| 5 | 22.857px | +2 |
| 6 | 26.286px | +2 |
快捷键:Ctrl+- 降档、Ctrl++ 升档、Ctrl+0 恢复默认。
YCode 的实现差异:因组件样式已全部 token 化,不需要像对标那样扫描样式表注入覆盖规则; 只改
--yc-font-offset-global与--yc-md-root两个根变量即可全局生效。 未实现对标的.cb-font-size-fixed例外类——目前没有固定字号的控件需要豁免。
11.8 字体族
- 正文:
'PingFang SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif - 等宽:
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace
11.9 实测常量(不在标准阶内,对标自身也硬写)
scrollbar 6px、菜单最小宽 200px、窗口控制图标 10px、侧栏项高 31px、侧栏项纵向 padding 5px、
行高 19 / 21 / 24.5 / 26.25、列表缩进 21.45px、气泡 max-height 310px、工具卡正文 max-height 320px、
空态头像圆角 18px、空态说明 max-width 324px、输入 min-height 96px、选项卡 80–240px、
对话框 560 / 420px
12. REA 拆解证据与工具边界
12.1 归档级拆解(已执行)
open_binary app.asar → format=asar, kind=archive
sha256 035254bc…729de918
inspect_artifact (record-and-continue) → 12253 节点 / 17356 occurrence / 14476 文件 / 2880 目录
45 处完整性矛盾(观察值标记为 untrusted)
完整性矛盾:首条为 cli/bin/native/win32-x64/job-object.node——声明的 sha256 与伴随文件不符。
REA 指出这是常见现象(打包工具会在写入归档后对未打包的原生二进制签名或裁剪),
但该模块正是绑定子进程树的 Windows Job Object 原生实现,与 GPU 沙箱受限环境的观察一致,
值得单独留意。
12.2 工具边界(重要)
REA 的 CDP 浏览器 provider 只枚举 HTTP(S) 页面目标。
WorkBuddy 的渲染器是 file:// URL,因此:
list_browser_targets http://127.0.0.1:9223
→ targets: [] excluded: { unsupported_url: 1 }
→ limitations: "All page targets with supported HTTP(S) URLs are listed."
结论:REA 的浏览器类工具(inspect_web_page / capture_web_screenshot /
compare_web_captures)目前无法观察 WorkBuddy 主窗口。
对 file:// 渲染器的 Electron 应用,实测采集需要直接用 CDP(本项目的
scripts/wb-capture.mjs / wb-tree.mjs / wb-icons.mjs)。
YCode 开发态走 http://localhost,REA 浏览器工具对其可用。
同理,REA 的二进制 provider(Ghidra / IDA / Hopper)在本机均未配置, 且不接归档目标("Ghidra v1 imports executable targets, not archive targets"), 因此无字符串检索能力;token 表据以从归档内 CSS 文件直接提取。
13. 外围壳层完整结构(第二轮实测)
采集脚本:scripts/wb-shell.mjs(输出侧栏完整子树 + 外围元素清单)
重要发现:侧栏宽度不是常量。两次采集分别为 280px(@1334 窗口) 与 240px(@1276 窗口),说明该宽度本身可变(可拖拽或随窗口变化)。 YCode 取 280px 作为展开默认值,并支持收起为 44px 窄轨。
13.1 品牌区
| 元素 | 实测值 |
|---|---|
.conversation-list-logo-row |
215×64(min-height 40),gap: 4px,align center |
.conversation-list-brand-block |
flex column,align flex-start,padding-top: 4px |
.conversation-list-brand-line |
90×22,padding-left: 12px,gap: 8px |
| 品牌标题 | 14px / 700 / 行高 22,色 rgba(0,0,0,.9) |
.conversation-list-version-row |
40×18,padding-left: 12px,margin-top: -4px,gap: 6px |
| 版本徽标 | 10px / 行高 18,letter-spacing: .2px,色 rgba(0,0,0,.5) |
| 「发现应用」按钮 | 98×28,padding: 4px 6px 4px 8px,gap: 2px,背景 #f2f2f2,色 rgba(0,0,0,.7),边框 1px #ebebeb,圆角 100px,12px / 500 / 行高 20 |
| └ 左侧图标 / 右侧箭头 | 各 14×14;箭头色 rgba(0,0,0,.3);文字 12px/400 |
13.2 导航项(实测 .conversation-list-tab-button)
| 项 | 备注 |
|---|---|
| 新建任务 | 主入口 |
| 助理 | 带 Beta 徽标 |
| 专家·技能·连接器 | |
| 定时任务 | |
| 资料库 | |
| 更多 | 右侧附 「灵感」 副文案 |
尺寸:215×32,padding: 5px 12px,gap: 8px,圆角 8px,图标 16×16,标签 14px / 行高 22。
- Beta 徽标:10px / 500 / 行高 16,
padding: 0 5px,边框 1px#dedede,圆角 100px,色rgba(0,0,0,.45) - 「灵感」副文案:11px / 行高 20,色
rgba(0,0,0,.5)
13.3 分组
| 元素 | 实测值 |
|---|---|
分组标签 .conversation-section-label |
215×30,padding: 5px 12px,gap: 4px,背景 #f7f7f7,圆角 8px,position: sticky |
| 分组文字 | 12px / 600 / 行高 20,色 rgba(0,0,0,.5),形如「任务 (1)」「空间 (2)」 |
| 折叠箭头 | 14×14,色 rgba(0,0,0,.3),默认 opacity 0(hover 显现) |
| 分组操作按钮 | 20×20,圆角 4px,色 rgba(0,0,0,.5),默认 opacity 0 |
空间分组头 .collapsible-section header |
215×34,padding: 5px 12px,gap: 4px,背景 #f7f7f7,圆角 8px |
| └ 图标 / 名称 | 16×16 / 14px 行高 22 |
13.4 底部账号区(实测)
| 元素 | 实测值 |
|---|---|
.conversation-list-footer |
239×57,padding: 8px 12px 8px 8px,border-top: 1px solid #e6e6e6 |
.user-menu |
219×40,gap: 4px |
.user-menu-trigger |
147×40(min-height 40),padding: 6px 8px,圆角 8px;内部 gap: 10px |
| 头像 | 28×28,border-radius: 50%,背景 #ebebeb,12px / 500 |
| 用户名 | 12px / 600(.user-menu-trigger-name 高 12) |
| 通知按钮 | 32×32,圆角 6px,色 rgba(0,0,0,.7),图标 16×16 |
未读角标 .msg-center-badge |
14×14,背景 #f64041,白字,border-radius: 7px,9px / 500 / 行高 14,padding: 0 3px |
| 小程序按钮 | 32×32,圆角 6px,图标 16×16 |
13.5 输入区补充
.cr-permission-setting(「允许完全访问」):132×32 —— 权限选择器实为 32px 高控件。
14. Mock 数据约定
用户明确要求「登录账号先用 mock 写死数据」。约定:
| 文件 | 内容 | 替换时机 |
|---|---|---|
src/renderer/src/mock.ts |
账号、通知、空间、导航项清单 | 接入真实数据源时整体替换 |
约束(已落实):
- 所有导出一律
MOCK_前缀,便于全局检索替换 - 使用处必须在 UI 上显式标注为示例数据:
- 通知面板底部:「示例数据 · 尚未接入消息中心」
- 设置 → 账号:「账号信息为 mock 写死数据,尚未接入登录」
- 账号按钮
title:「账号为 mock 数据」
- 未实现的入口不做假交互:点击给出 2 秒临时提示(如「『专家·技能·连接器』尚未实现」), 不伪造可用状态。这是对外围壳层「配齐」与「不虚构能力」两条要求的折中。
15. 首页 / 新建任务页(空态)—— 冒烟实测
采集方式:用户批准「方案 B」后,由 CDP 直接点击侧栏「新建任务」切换页面后采集。 脚本:
scripts/wb-probe.mjs(按文案定位,应对 CSS Module 哈希类名)、scripts/wb-home.mjs、scripts/click-shot.mjs参考截图:docs/screenshots/wb-home-reference.png
15.1 页面构成(自上而下)
- 大标题:「WorkBuddy, 我帮你」
- 分段控件
.wb-segmented:[办公][开发][设计]…(场景切换) - 分类胶囊行
.quick-actions__list - 输入框(比会话内更高)
- 工作目录 + 权限行(📁 YCode ⌄ / 🔒 允许完全访问 ⌄)
- 建议条目列表(整行胶囊 + 右上箭头)
- 底部免责声明:内容由 AI 生成,请核实重要信息
15.2 实测尺寸
| 元素 | 实测值 |
|---|---|
分类行 .quick-actions__list |
宽 680,flex row,gap: 8px,align center |
分类胶囊 .quick-actions__item |
高 32,padding: 0 12px,gap: 4px,背景 #f7f7f7,色 rgba(0,0,0,.9),边框 1px #dedede,border-radius: 100px,14px / 400 |
分段控件 .wb-segmented |
高 32,border-radius: 9999px,gap: 2px |
分段项 .wb-segmented__item |
72×32,padding: 5px 12px,gap: 4px,圆角 9999px,14px / 600,阴影 rgba(0,0,0,.05) 0 1px 4px 0 |
首页输入编辑区 .cr-input-editor-host |
798 × 74,min-height: 74px,padding: 0 16px |
| 输入占位符 | 15px / 26.25px,色 rgba(0,0,0,.9);文案「今天帮你做些什么?@ 添加上下文,/调用技能与指令」 |
注意:首页编辑区 74px,会话内是 64px —— 两者不同,不能共用。
15.3 分类清单(实测)
办公 开发 设计 创作文档 金融服务 分析数据 制作PPT 深度研究 策划方案 定时任务
YCode 已按此实现分类行(
--yc-*token 化),点击分类把对应提示词填入输入框(真实可用, 提示词为自拟,非对标文案)。
15.4 与旧实现的差异(已修正)
旧空态是「56px 头像 + 大标题 + 竖排胶囊」——那是从 CSS 规则推断的 .colleague-chat-empty--profile,
与真实首页不符。真实首页没有头像,改为「大标题 + 横排分类 + 建议列表」。已按实测重写。
15.5 垂直结构精测(第三轮,scripts/wb-home-layout.mjs + wb-home-parts.mjs)
本轮发现第一轮实现整体结构错误:我把输入框放页面底部、10 个分类挤一行。 真实首页是居中内容列,输入框在页面中部、建议列表在其下方。
| 区块 | 实测 rect(视口 1276×901) |
|---|---|
标题 h1.wb-home-header__title |
[614, 159, 278, 42] —— 30px / 600 / 行高 42,色 rgb(0,0,0),gap: 10px |
分段控件 .wb-segmented |
[643, 219, 220, 32] —— 居中于内容列(中心 753) |
分类行 .quick-actions |
[353, 317, 680, 32] —— 左对齐于内容列 |
输入框外层 .wb-home-route__input-box |
[353, 365, 800, 184],flex column gap: 12px |
└ 白框 .cr-input-container |
[353, 365, 800, 144],圆角 24,padding-top: 12,白底 + 双层阴影 |
└ 编辑区 .cr-input-editor-host |
[354, 378, 798, 74],padding: 0 16px |
└ 工具栏 .cr-input-toolbar |
[354, 452, 798, 56],padding: 12px,space-between |
权限项 .cr-permission-setting |
[461, 513, 132, 32],圆角 999px,13.33px,色 rgb(180,44,63) |
建议项 .wb-home-prompt-list__row |
[353, 601, 238, 38] 起 —— 高 38 / 圆角 9999 / 白底 / 边框 1px #e6e6e6 / 14px,行距 50(38 + 12),左对齐 |
垂直间距:标题底 201 → 分段 219 = 18;分段底 251 → 分类 317 = 66; 分类底 349 → 输入 365 = 16;输入底 549 → 建议 601 = 52。
结构结论:
- 内容列 x=353、宽 800,整体居中(中心 753 ≈ 内容区中心 758)
- 输入框不是底部停靠,在页面中部;建议列表在其下方
- 分类分两处:分段控件 3 个(办公/开发/设计) + 胶囊行 7 个,不是 10 个一行
- 输入框下方有「工作目录 + 权限」行,在输入框外层容器内部(184 = 144 + 40)
- 白框 144 = 12 + 74 + 56 + 2,纵向无 gap(YCode 早期实现误加 4px gap → 148,已修)
- 会话内输入框 134 = 12 + 64 + 56 + 2,同为无 gap
已实现:ChatPane 拆为 composer(两种变体共用,data-variant 区分编辑区高度)+
composerFooter(工作目录/权限行);首页走 .home 布局,会话走原底部停靠布局。
分段控件用前 3 个分类,胶囊行用后 7 个,与对标结构一致。
16. OMP 内核接入(底层循环替换)
架构决策(用户拍板):YCode 从「自建网关 + 自写 agent 循环」转为 OMP 前端壳。
16.1 事实
| 项 | 值 |
|---|---|
| OMP 可执行文件 | C:\Users\Administrator\AppData\Local\Ygent\omp.exe(随 Ygent 安装) |
| 版本 | omp/18.6.3 |
| 协议 | --mode rpc:stdio 上的 newline-delimited JSONL,启动先发 ready 帧,单帧上限 1 MiB |
| Profile | ~/.omp/profiles/ycode/agent/models.yml(独立 profile,不动用户 ygent 配置) |
| 上游 | https://api.iiiii.run/v1,api: openai-responses,模型 gpt-6-luna/astra/6.1-sol |
16.2 实现
| 文件 | 职责 |
|---|---|
src/main/omp.ts |
sidecar 管理:spawn + JSONL 解析 + 命令关联(id)+ ready 等待 + 退出清理;detectOmpPath() 探测可执行文件 |
src/main/agent/omp-turn.ts |
OMP 事件 → YCode ChatEvent 映射(渲染进程零改动) |
src/main/ipc.ts |
会话 → 内核进程 池;会话删除时释放进程;OMP 不可用时回退自建循环 |
事件映射:
| OMP 事件 | YCode ChatEvent |
|---|---|
message_update.assistantMessageEvent.type = "text_delta" |
text |
tool_execution_start / _update / _end |
tool_call / tool_result |
agent_end(yielded !== false) |
done |
prompt_result.status = "error" / notice(level=error) |
error |
| abort | cancelled |
踩过的坑:
spawn报ENOENT但可执行文件明明存在 —— 是 cwd 不存在(工作目录为空字符串)。 spawn 的cwd与可执行路径无关,必须单独兜底(现回退到用户主目录)。- OMP 工具事件载荷文档未给全 →
readToolInfo()做多形状兼容解析 (toolCall/call/tool/data逐层找id/name/arguments)。
16.3 端到端验证
发送「只回复两个字:收到」 → 回复「收到」(omp.exe 被拉起)
发送「用 list_dir 列出工作目录文件」 → 3 张工具卡:glob / read / bash(OMP 原生工具)
全部 ok;回复「工作目录根目录下有 12 个文件。」
注意工具名是 OMP 自己的工具集(glob/read/bash),不再是 YCode 的
list_dir/read_file—— 内核真正接管。YCode 自带的agent/tools.ts在 OMP 可用时不再使用(保留代码作回退)。
16.4 遗留
- 取消链路已接(
abort),但未做端到端验证 - 工具事件载荷的解析是容错的,若 OMP 未来改字段名可能拿不到 name/args(UI 会显示
tool) - OMP 进程按会话存活:长会话会常驻一个 omp.exe;会话删除时释放
~/.omp/profiles/ycode里的 key 有额度限制,过期后回合会失败(届时换 key 即可)