# WorkBuddy 对话区 / 右侧栏 UI 能否 1:1 复刻 **评估对象**:WorkBuddy 桌面版渲染进程 UI(`app.asar.unpacked/renderer`)+ 侧栏类扩展(`resources/extensions/*/ui`) **评估方法**:REA MCP(`analyze_javascript_application` 实测)+ 资源清单/混淆度/CSS 类名/库指纹取证 **评估日期**:2026-10-14 **结论前置**:**UI 层是整个 WorkBuddy 里最接近可复刻的部分——视觉与结构可做到高度 1:1,交互行为需重写,数据流为 0(在云端)。** --- ## 0. 一句话结论 引擎层「不可 1:1」的核心障碍是**原生二进制 + 压缩 bundle**;而 UI 层**两个障碍都不存在**—— - 渲染进程代码**基本没有混淆**(920 个具名 React 组件、10,347 个可读函数名保留在 7.5MB 主 chunk 中,函数体逐行可读) - CSS、设计 token、i18n、图标资源**全部明文可提取** - UI 技术栈**几乎全是开源库** **所以:对话区与右侧栏,可以做到「视觉 + 结构 + 交互行为」层面的 1:1 复刻;但「源码/二进制 1:1」仍然不行(版权),且排除云之后它是一套没有数据的空界面。** --- ## 1. 决定性证据:渲染进程代码未混淆 ### 1.1 实测:函数体逐行可读 抽取 `contexts-BMeWSUHk.js`(7,549,089 B)中的真实代码: ```js function ConversationInputArea({viewConversationId:e, renderRootId:t, scenarioId:n, maxContentWidth:r, inputTopSlot:i, customFloatingSlot:a, cloudServiceQuotaBar:o, fullscreenDropContainerRef:s, onPromptQueueInsetChange:c}){ let l = useConversationError(), u = useConversationSessionSelector(selectConversationInputAreaSession, shallow$1), {pending:d, planAdjustment:f} = useConversationInteraction(), p = useConversationPromptQueue(), m = useCreditInputBannerProvider(), h = useConversationBackgroundTasks(), g = useConversationApi(), ... ``` ```js function ConversationStreamingFooterImpl({options:e}){ let t = useConversationSessionSelector(selectConversationStreamingFooterSession, shallow$1), n = useConversationI18n(), ... let {reasoningOnly:s, credit:c, hasMessage:l} = useConversationMessagesSelector(createStreamingFooterMessageSelector(e.messageId,o), shallow$1), ... ``` **解读**:只有空白被压掉(平均行长 9,764 字符)和**局部变量重命名为单字母**(`e/t/n/r`),而—— - **组件名、props 名、自定义 Hook 名、selector 名、状态机枚举值全部保留** - 依赖注入关系(哪个组件用哪个 Hook)一目了然 对照:`main/server.js` 是真正压缩过的(平均行长 3,037、全单字母标识符)——**腾讯压了主进程,却没压渲染进程**。这是 UI 可复刻率远高于引擎的直接原因。 ### 1.2 量化指标 | 文件 | 大小 | 行数 | 平均行长 | 保留的可读函数名 | | --- | --- | --- | --- | --- | | `contexts-BMeWSUHk.js` | 7.55 MB | 772 | 9,764 | **10,347** | | `src-0FGg1seX.js` | 2.68 MB | 1,347 | 1,986 | 1,136 | | `colleague-chat-page-DUBLIFUp.js` | 225 KB | 3 | 56,379 | 258 | | `agent-chat-pane-CUPwHdfj.js` | 7.4 KB | — | — | **整文件可直读** | 全量普查:**920 个具名 React 组件**(`AccountPanel`、`ConversationPromptQueuePanel`、`DetailPanelSurfaceProvider`、`ClawSecondarySidebar`…)。 ### 1.3 REA 实测运行记录 | 目标 | 结果 | | --- | --- | | `renderer`(限定 2 个 JS 源文件) | parsed=2、AST 节点=2,495、findings=67、**parse_failures=0**;data-flow 关系 1,561、closure 237 | | coverage | `partial`(1,165 个文件未在本次选入范围) | | 限制 | REA 自身声明:静态语法观察,不代表运行时;未执行 bundle bootstrap | > 注意:CSS 文件**不能**作为 `analyze_javascript_application` 的 `source_paths`(实测被拒:`invalid_value`)——CSS 需用普通文本/样式工具处理,不归 REA。 --- ## 2. 视觉层:CSS + 设计 token 可完整提取 ### 2.1 CSS 明文且类名语义化 CSS 是压缩的(注释已被剥离,`/* */` 计数为 0),但**是 100% 有效 CSS,可直接提取**,且**类名一个都没被 hash**: ```css .claw-agent-chat-pane{--claw-agent-chat-content-max-width:832px; background:var(--wb-home-bg-secondary);flex-direction:column;width:100%;height:100%;...} .colleague-chat-cb-chat [class*=input-area-container]{max-width:var(--cb-chat-max-content-width);...} ``` 对话区相关类名(抽样): ``` .cb-chat-message--user .cb-chat-message--assistant .cb-chat-message-bubble .cb-chat-tool-renderer .cb-chat-search-hit--current .cb-message-time-tip .cb-input-banner--error .cb-message-queue-item .cb-message-queue-item-dragging .cb-message-queue-item-drag-over-before .assistant-message-tool-container .cb-chat-toast .cb-message-queue-item-single .cb-task-list-input ``` 右侧栏相关类名(抽样): ``` .detail-sidebar .detail-sidebar--collapsed .detail-sidebar--file-version .detail-sidebar-sash .claw-secondary-sidebar .claw-secondary-sidebar--pinned .claw-secondary-sidebar--floating .claw-sidebar-drawer--floating .conversation-sidebar .colleague-detail-panel .colleague-detail-sidebar-module .cb-sidebar-nav--compact .cb-sidebar-category--file-tree .codicon-layout-sidebar-right-dock ``` **类名本身就是 DOM 结构说明书**(BEM 风格:块-元素-修饰符)。CSS 总量:`wb-` 前缀变量/类 1,425 个 + `cb-` 前缀组件类 437 个。 ### 2.2 设计 token 完整(1,563 KB 的 `contexts-BkjwYSZT.css`) ```css :root,body[data-vscode-theme-name=IDE\ Light]{ --wb-palette-brand-8:#00c29a; --wb-palette-brand-9:#009273; --wb-palette-blue-7:#3370ff; --wb-palette-purple-6:#7c5cfc; --wb-color-text-primary; --wb-color-border-secondary; --wb-radius-lg; --wb-spacing-4; --wb-font-h1-size; --wb-alert-border-radius; ... } ``` 主题系统(light/dark/皮肤)**完全基于 CSS 变量**,且 `index.html` 内联脚本展示了主题注入协议(`windowTheme`/`colorScheme` → `root.dataset.theme`)。这意味着**换肤体系可以原样重建**。 顺带:`codicon-layout-sidebar-*` 证明图标用了 **VS Code codicon**(MIT 开源)。 --- ## 3. 资源与国际化:全部本地明文 | 资源 | 状态 | | --- | --- | | i18n 语言包 | ✅ 全量本地:`zh-cn`(1.14MB)、`zh-tw`(1.07MB)、`en`(0.87MB),含全部 `chat.*` key(`chat.input.placeholder`、`chat.search.*`、`chat.input.sendShortcutTooltip`…) | | 图标 | ✅ `icons-DmAL6CTu.js`(3.7MB)、大量 `.svg`(`file-pdf-color-link`、`wechat-color-link`…) | | 插图/位图 | ✅ `claw-welcome-light.svg`(1.6MB)、`inspiration-fallback-{1,2,3}.png`、`empty-no-files.png`、`drop-files-icon-{light,dark}.png` | | 字体 | ✅ 本地字体文件(`PingFang SC` 等走系统回退) | > i18n key 用模板字符串存 Unicode 转义,可无损还原中文原文。**UI 文案零云依赖**。 --- ## 4. UI 技术栈几乎全开源 → 直接复用,无需"复刻" 库指纹扫描(在 renderer bundle 中命中): | 能力 | 采用的开源库 | 命中文件数 | | --- | --- | --- | | 框架 | **React 18** + rolldown 构建 | — | | 无障碍/弹层原语 | Radix UI | 17 | | 定位/浮层 | Floating UI | 54 | | 状态管理 | Zustand | 39 | | 图表 | **mermaid** | 101 | | 公式 | **KaTeX** | 49 | | 白板 | **Excalidraw** | 63 | | PDF | **PDF.js** | 1 | | 终端 | xterm | 9 | | 代码编辑器 | **Monaco** | 15 | | Markdown | marked / markdown-it | 17 / 1 | | 代码高亮 | shiki / prism | 4 / 7 | | 净化 | DOMPurify | 3 | | 国际化 | i18next | 16 | | 时间 | dayjs | 50 | | 动画 | framer-motion | 3 | **除 `cb-` 前缀的内部设计系统组件库外,UI 没有任何自研底层**。这意味着"复刻 UI"实际是"用同一批开源库重搭一遍"。 --- ## 5. 侧栏的形态:壳 + 扩展 右侧栏不是单一组件,而是**主壳 + 独立扩展 UI**: ``` resources/extensions/ library/ ← 资料库 {assets/ ui/assets/ extension.json distribution.json} global-search/ ← 全局搜索 im-channels/ ← 消息通道(23MB) 含 server/ + ui/ community/ ← 社区 (12MB) cloud-assistant/ ← 云助手 workbuddy-baas-v2/ (15MB) edge-sync/ remote-desktop/ ``` 主壳侧栏由 `DetailPanelSurfaceProvider / DetailPanelSurfaceHost / DetailPanelSurfacePortal`、`ClawSecondarySidebar`、`ConversationArtifactPanelHost` 等组件驱动(均为可读组件名),扩展以独立 `ui/assets` 形式挂载。 --- ## 6. 那么,到底能复刻到什么程度? | 层面 | 可复刻度 | 说明 | | --- | --- | --- | | **视觉外观**(布局/配色/圆角/间距/阴影/动效) | **~95%** | CSS 明文 + token 完整 + 资源可复制;剩余差异来自字体渲染与平台差异 | | **DOM 结构 / 组件树** | **~90%** | 类名语义化 + 920 个具名组件 + props 可读;可完整重建组件边界 | | **交互行为**(输入、发送、流式渲染、折叠、拖拽排序、滚动、快捷键) | **~70%** | 状态机与 Hook 语义可读但要**重写**(局部变量被混淆、跨文件依赖多);跨进程/原生部分受限 | | **数据/内容流**(模型列表、专家、会话历史、配额) | **0%** | 全在云端,属被排除的「云部分」 | | **源码二进制 1:1** | **0%** | 复制 CSS/资源/代码仍构成侵权 | ### 具体受限点(诚实清单) 1. **函数内部逻辑被混淆**——`let l=..., u=...` 只能靠 Hook 名与调用顺序推断;行为需重写而非复制。 2. **跨进程交互**:窗口控件、原生菜单、文件对话框、拖到 Dock、剪贴板、截图 → 走主进程 + 原生模块(`@ban-dal/os-bridge`、`wwapi-electron` 等)。 3. **富文档预览**:office 预览经 `editor_sdk.exe`(199.5MB,见引擎报告)→ **不可复刻**;但 PDF.js / Excalidraw / 图片 预览路径是开源的,可复用。 4. **内部组件库**:`cb-` 前缀 437 个类对应的组件需自行重写。 5. **数据源**:排除云后,对话区与侧栏**没有内容可渲染**——必须自建模型网关与服务端(这是真正的护城河,也是上篇报告已指出的核心)。 --- ## 7. 最终判断 > **对话区 / 右侧栏:UI 层可以做到 1:1 的「样子和手感」,做不到 1:1 的「源码」,且做出来是空壳。** - 与引擎层的本质差别:**引擎层卡在原生二进制与压缩 bundle;UI 层这两者都不存在。** 渲染进程代码几乎未混淆、CSS/token/i18n/资源全明文、技术栈全开源。 - 工作量重心从"逆向还原"变成"用开源栈重搭 + 按可读组件名重组交互",这比复刻引擎现实得多。 - 但两个天花板不变:**版权**(不能复制产出物)与**云依赖**(没有数据源,界面无内容)。 - 结论落到可执行建议:**把 UI 分析产出当作「设计规范 + 组件清单 + 交互说明」来用**——这是安全且高价值的用法;要落地产品,用同一批开源库 + 自建后端重写。 --- ### 附:本次取证命令与命中数据(可复核) - `agent-chat-pane-CUPwHdfj.js` 与 `-F5lfde1Z.css` 全文可读(`AgentChatPane`、`computeAgentChatMaxContentWidth`、`shouldHideAssistantDuration`) - `contexts-BMeWSUHk.js`:10,347 个具名函数;`ConversationInputArea`、`ConversationStreamingFooterImpl` 函数体可读 - CSS 类名抽样:`.cb-chat-message--user`、`.detail-sidebar--collapsed`、`.claw-secondary-sidebar--pinned`、`.codicon-layout-sidebar-right-dock` - token 抽样:`--wb-palette-brand-8:#00c29a`、`--wb-color-text-primary` - i18n:`zh-cn-Dfzn8myY.js` 含 `chat.input.placeholder`、`chat.search.placeholder`、`chat.input.sendShortcutTooltip` - 库指纹:radix=17、floating-ui=54、zustand=39、mermaid=101、katex=49、excalidraw=63、pdfjs=1、monaco=15、marked=17、i18next=16、dayjs=50 - REA:`renderer` 目录分析 → 2 文件 / 2,495 AST 节点 / 67 findings / 0 parse failures / coverage=partial