🏗️ arch(browser): 四端移除旧浏览器实现,按 ZCode 蓝图重写(阶段:清理+删除已落地) - #860
Open
CavinHuang wants to merge 43 commits into
Open
Conversation
盘点确认 Lume 已是 ZCode 同型架构(webview + 主进程权威 + CDP + 挂载授权), 对齐是补差而非重写。计划列出 9 项前置清理(测试白名单/死代码/光标路径/ 截图 fallback/挂起收拢/桥版本握手/webmcp 隔离/一次性 webview/方法面盘点) 与对齐主线的依赖顺序,并冻结两条桥的契约规则。 Constraint: 对齐期间不改 browser:request 帧、browser:event 事件名、挂载协议 Constraint: 清理不改行为;行为变更一律进对齐主线 PR Rejected: 直接重写 BrowserRuntime | 现有实现与目标同型,重写无收益 Not-tested: 纯文档提交
原 test 脚本为 30+ 文件显式白名单,漂移导致 12 个浏览器测试文件 (action-effect/action-queue/agent-script/download-sweep/input-ledger/ locator/semantic-snapshot/guest-preload×2/webmcp-consumer/annotation-security) 与 scripts 侧 5 个测试从未在 CI 运行——重构防护形同虚设。 - test 脚本改为 bun test ./src ./scripts 目录级发现 - node-repl-worker.test.mjs 更名 .suite.mjs(bun 发现会误跑 node:test 套件, 它必须用 node --experimental-vm-modules 运行) - electronMockStub 补 nativeTheme(browser-runtime 依赖,缺失导致 browser-webmcp-consumer.test.ts 单独运行即挂,系预存在损坏) 结果:633 pass/0 fail(原白名单仅 590),typecheck 通过,ci-workflow 契约 6/6。 Constraint: test:smoke 白名单保持原样(CI 只跑 smoke,最小改动) Tested: bun test ./src ./scripts 全绿;node 套件独立验证;根 ci-workflow 契约测试
- enforceBackgroundLimit 的内联保护过滤提取为 isSuspendProtected 谓词, 并补齐 agentDispatching/dialogOpen 两个缺口(对齐 ZCode isBrowserTabResidencyProtected 的 operationActive 语义): 此前用户在 agent 动作在途/对话框待处理时切换 tab 可触发冻结 - screenshot() 标注为截图唯一入口并写明表面协议替换边界: 视口三层策略链(含父窗口裁剪分支)是对齐 ZCode prepare/ready/release 协议时的整体替换对象 Constraint: 行为零变更(agentDispatching/dialogOpen 保护是行为收紧,见下) Tested: typecheck 通过;bun test 633 pass/0 fail
消费方驱动的死面审计(45 方法 × 19 事件 × sidecar/web/main 全语料): - 方法面无死项(45/45 均有消费方,含仅单引号调用的 print/devtools/emulate/ share/unshare/bounds/focus) - 5 个自始零消费方的事件删除 emit:agent-cursor(光标每次移动的热路径死发)、 cursor-error、debugger-detached、lease-revoked、tab-share-changed - webmcp 推送通知链整体移除:lume:browser-page-event 通道 + handlePageEvent/ handleBrowserPageEvent + guest-preload onToolsChanged 转发 + 死测试断言; 拉取链(webmcp:list/invoke + shim + enable 门)完整保留——推送事件自始 无消费方,消费侧本就按需 list - main-webmcp-ipc.wiring 守卫改为反向断言防回潮;weread webview(159 处 web 引用)确认是活功能,不在清理范围 Constraint: 只删零引用面;不改任何有消费方的命令/事件/payload Tested: typecheck 通过;bun test 628 pass/0 fail
desktop/sidecar 独立发版后,握手描述符的协议范围此前仅在 extension 后端 被校验(sanitizeExtensionRuntimeDescriptor),IAB 后端从未验证——版本错配时 命令会静默命中未知方法/载荷,表现为难以诊断的桥接错误。 - dispatch 队列内新增 assertIabProtocolCompatible:握手描述符声明范围与 sidecar 构建期常量(BROWSER_PROTOCOL_MIN/MAX_SUPPORTED)不相容时 fail closed 抛 incompatible_protocol - 握手不可达时放行:真实命令以真实传输错误失败,闸只对正向不相容证据行动, 不吞更有诊断价值的原始错误;未声明范围的端点交由 MAC+sequence 桥兜底 - incompatible_protocol 纳入 sidecar 稳定错误码集(原排除理由'仅 legacy 插件客户端抛出'随本闸引入失效) - broker 测试:main fake 补握手协议字段、调用序断言过滤 handshake、 新增不相容/未声明两分支专项用例 Constraint: 闸置于队列内部,不改变 per-tab 串行语义与队列槽位回收(#615) Tested: broker 26 pass/0 fail;services/browser 40 pass;tools/browser 31 pass; typecheck 除预存在的 obsidian vault-facade 错误外通过(HEAD 上即存在)
记录四个提交的落地情况、死面审计结论(方法面零死项/5 死事件/webmcp 推送链)、与原计划的六处偏差(C2 上游已做/C4 缩水/C7 C8 结论反转/ C3 C9 缓行)及对齐主线就绪状态。
原挂起仅 CDP 冻结(guest 常驻占内存),唤醒为 fire-and-forget 解冻, 命令与解冻存在竞态。对齐 ZCode BrowserTabResidencyCoordinator 语义, 按 Lume 骨架化简(主进程驱动,无需 renderer ack——挂载机制本就 代际守卫,池经 guestState:unmounted 自动丢弃、guest-mount-required 自动重建): - 挂起:suspend-pending(CDP 冻结)→ 卸载 guest(复用 release 关闭 路径,释放渲染进程内存)→ suspended;冻结 await 期间被唤醒则取消 - 唤醒:wakeTab——卸载态经 recoverGuest 触发重挂(guest-mount-required → 池 recover → attachGuest 落 live),仍挂载的旧冻结解冻;dispatch 的 navigate 分支先等待重挂完成再导航,消除空 guest 竞态 - 保护谓词迁至 browser-residency-policy 纯模块并补 isLoading (加载中卸载会打断导航),五处唤醒点统一走 wakeTab - lifecycle 枚举扩展 suspend-pending/restoring(过渡态不透出模型上下文, context-assembler 白名单天然过滤);协议版本 8→9 Constraint: renderer 零改动(池已有 discard/recover 语义) Constraint: 卸载式挂起丢失页内未持久状态(表单/SPA 状态),与 ZCode 同语义取舍 Tested: desktop typecheck + 634 pass;sidecar browser 面 71 pass; ci-workflow 契约 6/6
决策:四端全删现有实现,以 ZCode IAB 还原源码为施工蓝图重建; 批注子系统随核心删除;新核心采用 ZCode 命令协议(46 命令/domSnapshot 优先/ cua/recording),sidecar 工具层同步重写,传输层沿用 MAC 桥。 文档定义目标模块映射表、协议设计(命令/事件/安全)、六阶段实施与回退策略。 Constraint: 首版不含批注/WebMCP/extension/Chrome导入/advancedCdp/凭据填充 Rejected: 增量对齐旧实现 | 用户决策改为全删重写,蓝图与还原源码齐备 Not-tested: 纯文档
删除 types/browser-runtime、browser-api-registry 及 agent.ts 的浏览器 附件/认证类型群、runtime-event 的 browserAttachments 字段、rpc-error 的 BROWSER_UNAVAILABLE、tool-names 的 mcp__browser__ 前缀;allowlist 及其 契约测试同步剥离。plugin-market 的 browser-auth/chrome-extension 枚举 属插件市场通用元数据,保留。
按删除清单(manifest 提交)全量移除: - desktop:runtime/执行引擎/批注+overlay/凭据/下载/审计/网络守卫/导入/ workspace 存储/guest+auth preload/webmcp/main.ts 全部浏览器接线 (3870→3445 行,零 browser 引用);weread 窗口、office/file-protocol、 connection-vault 等邻近功能验证无浏览器依赖,保留 - web:BrowserShell/池/右面板浏览器 tab/设置页/agent 浏览器提及与附件/ 工具结果渲染器(约 6.5k 行);settings 缓存更名 clearRendererCaches - sidecar:broker/工具层/external-chrome 传输/RPC 序列/bundled 插件/ in-app-browser skill/agent 链路浏览器附件与 auth 管道/node-repl browserRequest 桥/kernel.rs 浏览器哈希管道(-4.1k 行) - 传输断点两侧同步:desktop 不再发 browser:* 通知,sidecar 不再受理 保留:文件浏览器(file-browser)、插件市场 browser-auth 枚举(通用元数据)、 命名巧合(McpSettings 图标启发式/browser_download_url)。 Constraint: 原子移除,重写前 browser 面板在本分支不可用(不合入 main) Tested: desktop typecheck 0 错+262 pass;web typecheck 0 错+287 pass (1 个失败为 HEAD 预存在);sidecar typecheck 仅剩预存在 obsidian 错误, rpc 204 pass/0 fail
装配与接线(按 docs/plans/2026-08-30-browser-rewrite-design.md):
- desktop assemble.ts:createLumeBrowserRuntime 全链工厂——A2 驻留协调器
(onEvict→closeTabForLimit)、A8 截图表面(nativeImage CSS 重采样)、
A4+A5+A6 执行链(dispatcher+playwright-bridge→locator/dom-snapshot 会话)、
A7 输入原语+对话框控制器、A9 录像器,全部注入 BrowserGuestManager(A3)
- main.ts:runtime/ipc whenReady 创建(加固先于任何 webview)、恢复协议注册、
事件转发、dispatchCommand 路由 lume:browser-view-*、will-quit 销毁
- sidecar:IAB 后端(ZCode 形状描述符+30s 超时先 cancel)+协议版本闸+
19 工具族+control-browser SKILL;lume:browser-execute 桥(HMAC+sequence,
响应携带 protocolVersion 完成握手)
- 修复:dispatcher clipboardItems 缺 {entries} 包装(运行时 type 必抛)、
publicResult 吞 error 载荷(模型看不到稳定错误码协议)、fill→type 路由
- renderer 白名单 9 invoke + 10 event;vite 插件发出 guest-preload CJS
已声明缝(后续 PR):suspend 发起方(当前仅淘汰路径)、recoveryStore、
playwright-core 打包、设置页门控字段
Tested: desktop typecheck 0错+339 pass;web typecheck 0错+287 pass(1 预存在);
sidecar typecheck 仅预存在 obsidian;shared 0错+28 pass;
注入脚本与 ZCode 运行时产物字节相等(9 项断言)
…交互面) 四路并行逆向汇总:15 种 tab 类型全表、三层壳架构(reducer/Hook/壳组件)、 布局性能三闸、终端真 PTY+ChannelServer 协议栈、Git 只读四作用域与 diff 降级管线、Shiki+diffs-worker 渲染、WikiReference 引用装配器、 交互面(快捷键/会话联动/多窗口/per-window 状态结论)。 五份分报告与 40+ 字节偏移切片同步归档。
Q1 subagent 面板族(三入口共用 L$,readOnly+rewind/可写双形态,V4 订阅, 剪枝闭环);Q2 白板(内存canvas)/轨迹(请求级timeline)/开发者工具(半成品); Q3 RepoWiki 生成面板(host agentLane 两段式 tool-use,增量智能); Q4 计划详情(ExitPlanMode 双通道,流式容错解析);Q5 git 执行层闭环 (host 裸 spawn CLI,环境加固,三级杀灭,partial commit 临时索引); Q6 代码视图 Xt(catalogTree chunk,diffs-container Shadow DOM,Worker 池)
Q7 V4会话数据层(帧归约/CAS/恢复状态机/配额表);Q8 MessagePort协议栈 +fileWatcher(fs.watch+150ms防抖);Q9 轨迹JSONL数据源+三层快照缓存 (ETag/LRU);Q10 远程工作区语义(三态门/降级矩阵/移动overlay); Q11 App壳状态机盲区补漏(33KB重切片+修正);Q12 composer事件管道 (10种CustomEvent/三档契约/三条插入路径)。逆向覆盖度终版宣告: 右侧面板无已知盲区。
Owner
Author
浏览器重写代码审查报告(逆向比对结论)本 PR 的浏览器重写以 ZCode 桌面端 3.10.1 的逆向还原为蓝图。以下是对已落地代码的审查结论,按模块列出验证结果、发现的问题及修复状态。 一、总体结论重写的 10 个模块全部与 ZCode 逆向蓝图语义等价,注入脚本实现字节级精确还原,全仓 typecheck/test 绿。发现并已修复 3 个运行时 bug;遗留 6 条已声明缝(均为功能增量而非正确性问题)。 二、逐模块审查1. shared 协议包(
|
| 语义项 | ZCode | 本 PR | 一致 |
|---|---|---|---|
| 挂起 = 冻结 + 卸载 guest | ✅ | ✅(suspend-pending → close → suspended) | ✓ |
| 恢复 = recoverGuest → 池重建 → attach 落 live | ✅ | ✅ | ✓ |
| 激活 suspended 先 ensureResident | ✅ | ✅ | ✓ |
| 挂起期间唤醒 → 取消(代数++) | ✅ | ✅(lifecycle 离开 suspend-pending 即取消) | ✓ |
| 弹窗自动化代答 | ✅ beginAutomation | ✅ 同款 | ✓ |
| 下载跟踪(will-download + 等待者) | ✅ | ✅ | ✓ |
| 弹窗 setWindowOpenHandler deny→外开/新tab | ✅ | ✅ | ✓ |
| URL 白名单(仅 about:blank + http/https) | ✅ | ✅ | ✓ |
| 文件上传不支持(稳定错误) | ✅ | ✅ | ✓ |
| 32KB 输出头尾截断(CDP) | ✅ | ✅(toolOutput 截断引用) | ✓ |
| 光标 overlay(录像) | ✅ 18px #ff4d4f | ✅ 同款 | ✓ |
| 录像 HTML CSP + 定频 canvas + VP8 | ✅ | ✅(字节校验) | ✓ |
三、发现并已修复的 Bug(3)
| # | 严重性 | 描述 | 修复 |
|---|---|---|---|
| 1 | 🔴 高 | dispatcher clipboardItems 缺 {entries} 包装 → 每次 type 命令运行时 TypeError |
集成时替换为 core/injected/text-input.ts 规范版 |
| 2 | 🔴 高 | sidecar publicResult 吞掉 error 载荷 → 模型只看到 {"ok":false},错误码/sideEffect 协议不可见 |
改为只剥 meta/elapsedMs |
| 3 | 🟡 中 | sidecar fill 命令映射到无路由的 fill(必返 capability_unsupported) |
改映射到可达的同形 type 路由(click-ref + replace-paste) |
四、遗留缝(后续 PR)
| # | 描述 | 影响 |
|---|---|---|
| 1 | 挂起发起方:当前仅 enforceBackgroundLimit 淘汰路径触发挂起,无独立的"冻结后卸载"挂起 | 后台 tab 不会自动释放内存(对齐目标行为) |
| 2 | recoveryStore 未实现:restoreTabs 返回 [],跨重启 tab 恢复不可用 |
可选增强 |
| 3 | playwright-core 需打包进 app(node_modules 打包或 snapshot) | 缺失时快照/定位降级 capability_unsupported |
| 4 | 设置页浏览器门控字段(generalSettings.browser.agentToolsEnabled)未类型化 |
功能可用但设置项未暴露 |
| 5 | 打包期 bundled-plugins 复制到 resources | dev 模式已正常 |
| 6 | 端到端(live Electron)未验证——单侧 typecheck/test 全绿但需真机冒烟 | 合入前建议跑 test:browser-e2e 重写版 |
五、逆向证据链
全部结论可复核:
- 逆向报告 16 份:
docs/analysis/(SidePane 壳层/Git/Wiki/终端/交互面/subagent/白板/RepoWiki/计划/远程/composer/V4/git闭环/录像/传输/Xt) - ZCode 还原源码:
.zcode/analysis/extracted/(15.5k 行 + 字节精确注入脚本) - 架构汇总:
.zcode/analysis/sidepane/README-consolidated.md
Review by: 逆向分析(16 报告 + 字节精确注入脚本 14 件)→ 10 模块并行移植 → 2 轮集成 → 全仓验证
…起发起/recoveryStore/打包 差距审计驱动的收尾批次: - 🔴 BrowserSidePane 挂载进右面板(browser 功能 tab,workspaceKey 与 sidecar 同源派生);open-browser-url 队列+揭示流;后退/前进按钮态 - 标签栏完整功能:dnd-kit 拖拽重排/溢出渐隐/最近关闭重开栈(8)/ 总览弹层/操作横幅/resize 警告(aEt 移植)/缩放补偿/三类错误卡 - 工作区分桶持久化(Map≤50 LRU,browserUrls 映射,suspended 壳保活, 后台 tab 事件路由) - 挂起发起方:suspendTabForIdle 完整飞行(beginSuspend→快照先行→ 通知→5s ack→代际复检→卸载→commitSuspend)+ 空闲调度器(5min/60s) - recoveryStore:JSON 原子写/7天修剪/50壳上限/损坏兜底 - fill 命令三层打通;IAB 描述符收敛 shared 单源;打包守卫 (playwright-core 钉 1.59.1);设置门控类型化;E2E 冒烟(真机两遍) Tested: desktop typecheck 0错+370 pass;web typecheck 0错+146 browser/ right-panel pass;sidecar typecheck 仅预存在;shared 28 pass
Owner
Author
遗留缝修复状态更新(全面对齐批次已推送)审查报告中列出的 6 条遗留缝全部已修复,随
同时完成的全面对齐批次(差距审计驱动)
最终验证desktop typecheck 0 错 + 370 pass;web typecheck 0 错 + browser/right-panel 146 pass;sidecar 仅剩预存在 obsidian;shared 28 pass;E2E 真机两遍全过。 |
- 视口信息条补数值宽×高输入(ZCode $Tt 语义:Enter/blur 提交、 Escape 回退、越界 destructive+tooltip、sr-only alert) - tab favicon 槽在 agent 操作期显示呼吸指示点(带 prefers-reduced-motion 守卫),空闲恢复 favicon - 顶层 waitFor 命令路由实现(复用定位会话 waitForState,纯复用零新机器, 5 项测试);全量协议↔执行器一致性扫尾:49 成员=23 执行器+24 管理器 +capabilities 有意不路由(经描述符通道) Tested: web typecheck 0错+browser 26 pass;desktop typecheck 0错 +browser 112 pass
R1 Git 面板: - git-panel-service.ts: spawn git CLI(porcelain v2 + numstat 解析) - GitPanel.tsx: 作用域选择/文件列表/展开 diff/刷新/空态 - IPC 白名单接线(lume:browser-git-status/diff) R2 多 tab 壳层: - right-panel-workspace-store.ts: Map≤50 LRU 按工作区分桶, browserUrls 恢复映射, suspended 壳保活, 关闭后邻居回落 - SidePane 面板挂载到工作区 tab 模型, 标题/favicon/url 同步 类型修复: - RightPanelTabBar.tsx FUNCTION_META 括号索引 JSX 语法修复 - RightPanelWorkspace.tsx onCloseFile tabId 显式类型标注 Tested: desktop 399 pass/0 fail; web browser 26 pass/0 fail; sidecar browser 12 pass; shared 28 pass; 全仓 typecheck 0 错误
验证 TS 代码片段 HTML 输出含 span/line 包装/color token, 未知语言回退 text,bash 别名映射,热缓存同步路径。
electron-security.test.mjs 的 filter 条件被此前的脚本编辑损坏 (字符串拼接错误),修正并正确排除 TERMINAL_IPC_CHANNELS。 同时同步 electron-security.ts 的通道排除。 Tested: electron-security 52 pass/0 fail;desktop 全量 405 pass/0 fail
recording/orchestrator.ts 的 recordBrowserVideo/executeRecordingActions 逻辑已内联于 guest-manager.ts 的 runRecording 方法(guest-manager 内联版 经 E2E 真机验证),orchestrator 模块无生产消费方,属冗余副本。 保留 recording/recorder.ts(createElectronBrowserWebmRecorder, 被 assemble.ts 正常引用)。 Tested: typecheck 0 错误;browser 134 pass/0 fail
ZCode 通过 host 进程 fileWatcherService 监听工作区目录,60s 防抖后 刷新 Git 面板。Lume MVP 用定时轮询等效实现(无需文件 watch 基础 设施),间隔与 ZCode 防抖值一致。workspacePath 存在时启动, 切换工作区或卸载时清理。
对齐 ZCode 终端体验的核心转义子集: - SGR 全属性:前景/背景(基础+亮色+256色+真彩)、加粗/暗淡/斜体/ 下划线/删除线/反色 - CR 行覆写(与真实终端一致,后段覆盖前段同等宽度) - OSC 剥离(BEL/ST 终止) - 渲染端 AnsiStyle→React 内联样式(支持 256 色/真彩 CSS 值) - 测试全量重写(14 项,含 256 色/真彩/CR 覆写/背景色等边界) Constraint: pipe 模式固有限制——无 CUP/滚动区/交替屏幕(需 node-pty) Tested: web typecheck 0错;terminal-ansi 14/14;desktop 405 pass
- git-watcher.ts: fs.watch 递归监听工作区+.git, 60s 防抖后发 lume:browser-git-dirty 通知 renderer 刷新(替代 60s 轮询) - git-panel-service.ts: 新增 branchComparison(与 tracking branch 比较) - GitPanel.tsx: source 下拉加 branch scope; 订阅 git-dirty 事件自动刷新 - renderer-ipc-contract: 加 lume:browser-git-dirty 事件白名单 - electron-security: TERMINAL_IPC_CHANNELS 加入 sidecar 派生排除 Tested: desktop 408 pass/0 fail; web 165 pass/0 fail; typecheck 全绿
bun spawnSync 冷启动/AV 扫描使真实 git 端到端用例停顿 4-8s, 超出 bun 默认 5s 单测超时;fs watch 事件送达随机器负载浮动。 - git-panel-service e2e 用例放宽至 30s 超时 - git-watcher 事件断言改为轮询等待 + 静置期复核计数 - bun-test.d.ts 补 test() 第三参 timeout 类型 Tested: bun test git-watcher git-panel-service 34/34 通过
…host 终端)
替换 MVP 管道 spawn,结构对齐 ZCode createTerminalService(R11-host-pty):
lazy import("node-pty") + 会话表 + win32 ConPTY 双段降级
(useConptyDll:true → conpty.dll 失败特征正则 → false) + onExit 自动清理
+ 终端环境(TERM/COLORTERM/locale 回补/CI=dumb 摘除) + cwd 存在性兜底链。
协议新增 terminal:exit 通知(lume:terminal-exit 事件),renderer 会话标记
exited 并提供重新打开;resize 直传 pty.resize,TUI 程序尺寸即时生效。
打包:node-pty 系 mxc-sdk 传递依赖,bundle 脚本既有 RUNTIME_EXTERNAL
清单已将其复制到 resources/sidecar/node_modules(零新增依赖);
已验证 bundle 产物处真实 ConPTY spawn 回环。
Constraint: sidecar 经 utilityProcess(Electron ABI)运行,node-pty 走 NAPI 预编译
Rejected: 保留管道 fallback | node-pty 打包已闭环,双路径徒增维护面
Rejected: create 返回字体/主题字段 | renderer 非 xterm,无消费方(留 xterm 升级路径)
Tested: sidecar 20 用例(ConPTY 降级/环境/flush/exit 语义) + desktop 中继 7 用例
Tested: 真实 ConPTY spawn 冒烟(bundle 产物处 echo 回环)
Not-tested: darwin spawn-helper chmod(有意不做,依赖预编译产物执行位)
替换自定义 ANSI <pre> 渲染 + 单行输入,对齐 ZCode 终端 tab 的 xterm.js 形状: - 键级输入(terminal.onData,含控制字符,交互式程序可用) - FitAddon 尺寸协商(ResizeObserver → fit → onResize → pty.resize) - 键盘级 ANSI/全屏 TUI 由 xterm 原生处理(前置 node-pty 已就位) - 主题以面板 CSS 变量取色适配应用主题(偏差:不接 settingService 字体 profile) - 退出事件在终端内写暗色提示;重挂载回放模块级缓冲(跨 tab 保活语义不变) 删除被替代的自定义 ANSI 解析链(terminal-ansi/-types/test,唯一消费方 即旧 TerminalPanel);数据泵为 xterm 实例增加直写通道。 Constraint: 模块级会话仓持久面=缓冲,xterm 实例随挂载建毁(与 ZCode stash 等效) Tested: web typecheck 0 错;终端相关测试全绿;组件套件失败集合与 main 基线一致
对照 P1-shell-architecture 逐条行为规范校准两处偏差: 1. 最近关闭环排除 agent 持有的 browser-use tab(ZCode Xde 规范 "browser-use 主进程持有不入环"):任务级视图不应以用户身份重开。 2. 激活挂起 tab 时自动发 browserViewEnsureResident(ZCode handleActivateSidePaneTab 语义:先复活再激活,失败仅 warn); 原先需手动点「恢复页面」,唤醒逻辑抽为 ensureResidentFor 共用。 Tested: web typecheck 0 错;browser 组件测试 26/26
补齐 P2-git-codeviewer §1.3 的两块交互规格: 1. 查找(KEt):大小写/空白归一化子串匹配已加载 diff 文本;有查询词时 自动批量预加载全部 diff;Enter/Shift+Enter/上下按钮在命中文件间循环, 展开并 scrollToIndex(center);计数 i/n 为命中文件粒度(虚拟列表以 文件行为滚动单位);Escape 关闭。 2. 行级菜单( reveal/copy 同型):在文件管理器中显示(桌面 revealPathInSystem)/ 复制绝对路径/复制相对路径(writeClipboardText)。 偏差记录:last-turn 来源(ZCode 该构建恒空占位)不移植;「在文件树中显示」 移交待文件树 reveal 总线桥接(thread 作用域)。 Tested: web typecheck 0 错;right-panel/browser 组件测试 165/165
… 挂载/揭示) P4 §1d:ZCode 的 ready 事件订阅在常驻 shell 控制器(Qde),面板关闭时 agent 建 tab 仍按 scope 决定「展开并激活/后台挂载」;Lume 原先订阅在 面板内部,面板未挂载时 ready 丢失,agent tab 永不可见。 修复:useOpenBrowserUrlReveal 增补 ready 兜底订阅—— - 后台挂载:tab 壳(字段与面板 createTab 默认同形)记入模块级工作区仓, 面板挂载时 applyWorkspaceSnapshot 对账装表; - shouldReveal:workspaceKey === 当前 threadId(RightPanelWorkspace 推导 同式)时点亮右面板「浏览器」tab(展开并激活)。 Tested: web typecheck 0 错;失败集合与 main 基线一致(均为既有无关套件)
Q11 §3.1:ZCode 任务切换时 git 面板来源选择按 workspaceKey 键控迁移 (离开写回/进入恢复);Lume 原先是组件内 state,切走再回来重置为 unstaged。 修复:模块级 Map<workspacePath, source>(ZCode Dd 持久层同为 renderer 内存,reload 即失)+ 双向 effect(进入恢复初始化 / 变更写回); branch 失效回落 unstaged 的既有校验覆盖恢复路径。 Tested: web typecheck 0 错;right-panel 139/139
补齐 P2 §1.3 行级菜单的最后一块:RightPanelWorkspace 构造 project FileRef (scopeId=workspaceSlug)经 createFileTreeRevealRequest + reveal-directory atom 动作移交文件树(展开祖先目录+选中+滚动定位);无 slug 时宿主返回 false,GitPanel 隐藏该项。 Tested: web typecheck 0 错;right-panel 139/139
ZCode 侧栏终端是唯一可多开的 tab 类型:每次开启追加新 tab,标题按 cwd.basename 查重加序号。Lume 原先每工作区仅一个固定终端面。 - 模型:RightPanelTab 增可选 title(消毒保留/截断 40 字);终端实例 tab id 唯一(type 仍 terminal),openRightPanelTerminalInstance 非单例追加 + nextTerminalInstanceTitle 查重(「repo」「repo 2」…); 关闭/入环/重排复用既有 reducer。 - 接线:tab 条「+」菜单常驻「新终端」项(固定功能已开也能再加开); 实例渲染以 tab id 为会话隔离键(缺省固定 tab 沿用 workspacePath 单例键,既有会话无损)。 Constraint: 固定功能单例不变式不破坏,多开仅终端一种类型(ZCode 同) Tested: right-panel-state 模型用例 17/17(含实例/查重/消毒/关闭);web typecheck 0 错
Q2 §1 全规格落地:
- store:按 workspaceKey 分桶,board={id:'whiteboard:'+uuid,1280×800,
strokes/undoneStrokes};动作 create/rename/addStroke/undo/redo/clear
全量;默认名「白板 N」查重;纯内存无持久化(ZCode 同)。
- canvas:pointer 涂鸦(DPR 缩放/setPointerCapture/draft 预渲/松手提交);
橡皮=画白线(ZCode bn 同款);笔宽 2..18,橡皮 max(14,width*3);6 色盘。
- 工具条:行内改名/pen/eraser/色盘/宽度/撤销重做清空/导出 PNG。
偏差:ZCode「加入聊天」走 composer 附件通道,Lume 先落地为 PNG 下载。
- tab 接线:实例 tab 模型泛化(terminal/whiteboard 共用 open-instance-tab
+ set-tab-title);「+」菜单白板项;改名同步 tab 标题;boardId 即 tabId
(ZCode 同形)。
Constraint: 无删除 board 动作(ZCode On 亦无);关 tab 不删 board
Tested: whiteboard store 5 用例 + right-panel-state 17/17;web typecheck 0 错
vault-facade.test.ts 在 expect(result.ok) 后直接访问联合分支字段 relativePath,TS 无法收窄 → sidecar tsc 构建整体失败。补显式守卫。 该回归源自 main 的 cff63a3,阻塞本分支打包验证顺手修复。 Tested: sidecar typecheck 0 错;vault-facade 13/13
整合本次逆向+对齐全过程的单源文档:进程架构、10 项设计决策(附证据)、 9 条实现流程、ZCode 混淆产物代码位置总表(渲染器/main/host + 提取源映射 + 通道面)、Lume 对齐实现文件映射、三层验证体系、有意偏差清单。
179 个 ZCode 命名函数机械化比对筛出 20 候选,落地两个实质缺口: 1. 网络策略(V6/qSe/JSe/VSe/XSe/YSe/QSe/G6):default-session 与 embedded-browser 分区并发应用 setProxy(fixed_servers/兜底 direct|system)+ closeAllConnections + setCertificateVerifyProc (不安全证书放行 / 自定义 CA 文件指纹匹配,链深 16,OK/不匹配回 默认 -3)。配置来源偏差:ZCode 读桌面设置面;Lume 环境变量驱动 (HTTPS_PROXY|HTTP_PROXY/NO_PROXY/LUME_BROWSER_CA_CERT_PATH/ LUME_BROWSER_ALLOW_INSECURE_CERTIFICATES)。 2. webview 文本右键菜单(Pve):选中态 → 系统复制项(canCopy 门控), attach 幂等安装,弹层经 deps 注入(electron 免依赖)。 Constraint: 其余 18 候选为注册入口组织形态/打包辅助/本地预览协议,与 Lume 既有装配等价 Tested: desktop typecheck 0 错;browser 套件 158/0(含新 12 用例:代理构造/proc 三分支/链匹配环守卫/双 session 应用/env 映射/菜单模板)
Owner
Author
ZCode 浏览器/侧栏对齐状态总览(对齐工作收官)本 PR 完成对 ZCode Desktop v3.10.1 内嵌浏览器及其侧栏面板的完整对齐。当前覆盖与验证状态: 对齐范围(38+ 提交)
验证体系(三层全绿)
已判定不再跟进项(附理由)
测试desktop 409+12/0、web 浏览器+右面板+白板+终端全绿、shared 290/0、sidecar 改动面 54/0;三端 typecheck 0 错。 |
main 新增 lume:browser-view-clear-data:invoke(mode 'cache'|'all'):
- cache:clearCache + clearStorageData({storages:[shadercache,
serviceworkers,cachestorage]})(ZCode Vpe);
- all:clearCache + clearStorageData()(含登录态);
- 非法 mode 拒收 invalid_clear_mode;失败归一 embedded_browser_clear_failed。
SidePane「+」菜单新增清除缓存/清除全部数据(confirm 门控)。
偏差:ZCode F1 Chrome 数据导入依赖提权解密 helper/App-Bound/钥匙串
基础设施,不移植(已记入实现图谱偏差清单)。
Tested: desktop typecheck 0 错;browser 套件 162/0(含数据清除 4 用例);web typecheck 0 错 + 167/0
工具栏新增选取开关(MTt 同款代数守卫 + isPicking 态):注入页面脚本
(window.__zcodeWebElementPicker)hover 高亮遮罩 + 点击捕获,Esc 取消;
选取结果 {selector,outerHTML(截断),text,rect} 格式化写剪贴板。
偏差:ZCode 选取结果进 selection-side-chat 元素上下文,Lume 暂以
剪贴板承载(composer 无该通道)。
Tested: web typecheck 0 错;browser 组件套件全绿(含选取器 3 用例)
184 个 ZCode i18n 键(terminal.contextMenu.copy/paste 等)全数甄别: 落地终端右键菜单(选中复制→剪贴板/粘贴→xterm.paste→PTY), 白板画布补 whiteboard.canvasLabel 同款 aria-label。 actionMenu/branchSwitcher 系键属主窗口 worktree 面(需 commit/push 后端与 AI 提交信息生成),维持原判定。 Tested: web typecheck 0 错;browser/terminal/whiteboard 套件全绿
复用既有附件暂存链(createPendingAttachmentsFromFiles → stageAttachmentFile 分块上传):白板工具条新增「加入聊天」,导出 PNG 构造 File 后派发 lume:add-whiteboard-to-chat CustomEvent;AgentView 监听并暂存进待发附件 (toast 确认)。聊天未挂载时回退为 PNG 文件下载。 Tested: web typecheck 0 错;whiteboard/browser/terminal 套件全绿
…branches(对齐 Q5 §2) git-panel-service 从 4 方法扩展 ZCode gitService 18 方法面的写路径 (Q5 CLI 规格逐条): - stagePaths:git add -- <paths> - unstagePaths:git restore --staged -- <paths> - discardPaths:git restore --worktree -- <paths>(仅已跟踪) - commit:commit -m <msg> [-- <paths>] + rev-parse HEAD → 哈希 - push:普通 push / --set-upstream(解析 branch.<b>.remote 兜底 origin), 10 分钟/8MB 上限(ZCode 同) - getLocalBranches:for-each-ref 四字段,提交时间降序 纯服务层能力(UI 面后续接线);reject 契约含空信息/空路径。 偏差:generateCommitMessage 需模型运行时;switch 系需预检对话框,后续跟进。 Tested: 真实 git e2e 31/31(stage→unstage→commit→branches→push 全链 + discard 还原/契约拒绝);desktop typecheck 0 错
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
目标
以 ZCode 桌面端内嵌浏览器(IAB)的逆向还原为蓝图,重建 Lume 右侧面板浏览器。本 PR 承载两个阶段:
已完成
阶段一:对齐尝试(后随重写决策部分被删除,历史保留)
incompatible_protocolfail closed)阶段二:推倒重写(当前)
docs/plans/2026-08-30-browser-removal-manifest.md):四端 ~90 整文件 + ~30 共享文件剥离点逐一执行,总计 −33,256 行 / 247 文件docs/plans/2026-08-30-browser-rewrite-design.md):目标模块映射表、46 命令 zod 协议、事件面、安全模型(保留 mountToken 增强)、六阶段实施验证
git show验证)预存在问题(与本 PR 无关,HEAD 即有):sidecar obsidian
vault-facade.test.ts类型错误、web SettingsView 副本断言、sidecar 全量test:unit挂起、layering-boundary 两条例外边。后续(同一 PR 内继续提交)
Constraint: 重写完成前不合入 main;浏览器面板在本分支中间态不可用
Rejected: 增量对齐旧实现 | 旧核心与 ZCode 语义差异缠绕,蓝图与还原源码齐备后重写净收益更高