Files
ycode/docs/WorkBuddy-UI复刻可行性评估.md
T

12 KiB
Raw Blame History

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)中的真实代码:

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(), ...
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:

.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)

: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