cc-haha/docs/desktop/09-electron-migration-validation-checklist.md
程序员阿江(Relakkes) 386a41e606 feat(desktop): enable Electron migration path
Introduce the Electron desktop shell alongside the existing React renderer and local Bun server boundary. The migration keeps the DesktopHost contract explicit across Tauri, Electron, and browser runtimes while adding Electron main/preload services for dialogs, shell, notifications, updates, tray/window lifecycle, terminal, preview WebContentsView, app mode, and release/package validation.

The commit also carries the latest local main desktop command updates, including agent slash entries and hidden-by-default markdown thinking details, so the packaged Electron build matches the current main UX surface.

Constraint: React renderer, local Bun server, REST/WebSocket, and sidecar boundaries must remain reusable during the migration
Constraint: macOS dev packages are ad-hoc signed and cannot prove Developer ID notarization or Gatekeeper release launch
Rejected: Browser-only smoke validation | it cannot exercise native dialogs, keychain prompts, notification behavior, or packaged app startup
Confidence: medium
Scope-risk: broad
Directive: Do not remove Tauri host support until signed Electron release artifacts pass native OS smoke on macOS, Windows, and Linux
Tested: bun run check:desktop
Tested: cd desktop && bun run check:electron
Tested: CSC_IDENTITY_AUTO_DISCOVERY=false bun run electron📦dir
Tested: bun run test:package-smoke --platform macos --package-kind dir --artifacts-dir desktop/build-artifacts/electron
Tested: Computer Use read packaged Electron app window at desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.app
Not-tested: Developer ID signed/notarized Gatekeeper launch
Not-tested: Real OS notification click-to-session action
Not-tested: Windows and Linux packaged app smoke on real hosts
2026-06-01 22:43:16 +08:00

41 KiB
Raw Blame History

Electron 迁移验证清单

用于迁移收口,不替代 docs/desktop/08-electron-migration-tasks.mdpackage-smoke 只验证包结构和关键资源,不声明 GUI 启动或交互成功。

交互式执行版见 electron-migration-qa-checklist.html,可在本地浏览器直接打开并用 localStorage 保存勾选进度与问题记录。

已有自动化证据

  • bun run check:nativesidecar build、Electron TypeScript、83 个 Electron IPC/service 测试、main/preload/preview-preload bundle、Electron --dir 打包和当前平台 package-smoke 均通过。
  • bun run check:desktopdesktop lint、151 个 Vitest 文件、1199 个测试、renderer production build 均通过。
  • bun test scripts/quality-gate/package-smoke/index.test.ts scripts/pr/release-workflow.test.tspackage-smoke harness 与 release workflow 静态回归通过。
  • bun test scripts/quality-gate/package-smoke/index.test.ts scripts/pr/release-workflow.test.ts scripts/quality-gate/runner.test.ts25 tests passed覆盖 release lane、显式 GitHub publish 配置和 latest-mac.yml 引用真实 artifact 的 package-smoke 回归。
  • bun test scripts/quality-gate/package-smoke/index.test.ts scripts/pr/release-workflow.test.ts scripts/release-update-metadata.test.ts26 tests passed覆盖 Windows canonical output、Linux x64/arm64 latest-linux*.yml update metadata、release workflow Gatekeeper/signing preflight 和 post-matrix metadata republish。
  • cd desktop && CSC_IDENTITY_AUTO_DISCOVERY=false bun run electron:package:dirmacOS unpacked .app 可打包。
  • bun run test:package-smoke --platform macosmacOS .app 结构、app.asar、unpacked sidecar、unpacked node-pty native module 和 spawn-helper 通过静态检查。
  • macOS .zip/latest-mac.yml 发布产物复验:MAC_TARGETS=zip SKIP_INSTALL=1 SIGN_BUILD=0 desktop/scripts/build-macos-arm64.sh 通过canonical 输出包含 .app.zip.zip.blockmaplatest-mac.yml,脚本末尾自动运行 canonical package-smoke 并 PASS。
  • macOS directory-only native/package 当前态:bun run check:native 通过,覆盖 sidecar 构建/ad-hoc signing、Electron 83 tests、production build、electron-builder --dirpackage-smoke --package-kind dir --artifacts-dir desktop/build-artifacts/electron。该项只证明 unpacked bundle 结构和关键资源,不证明 .dmg、Gatekeeper 或 signed release launch。
  • macOS .dmg/.zip/latest-mac.yml 当前态复验:SKIP_INSTALL=1 SIGN_BUILD=0 desktop/scripts/build-macos-arm64.sh 已通过默认 dmg zip targetcanonical desktop/build-artifacts/macos-arm64 包含 .app.dmg.dmg.blockmap.zip.zip.blockmaplatest-mac.yml,脚本末尾 release package-smoke PASS。
  • macOS canonical packaged launch smoke使用隔离 CLAUDE_CONFIG_DIR、隔离 --user-data-dirCC_HAHA_ELECTRON_DISABLE_SINGLE_INSTANCE_LOCK=1 启动 desktop/build-artifacts/macos-arm64/Claude Code Haha.appserver sidecar 启动于临时端口Computer Use get_app_state 成功读取 Claude Code Companion 主窗口和 packaged file://.../app.asar/dist/index.html renderer。
  • macOS canonical packaged system interaction smoke同一 canonical .app 隔离实例中Computer Use 确认项目选择器显示系统目录选择结果 /private/tmp/cc-haha-electron-real-fixed-sRFUeO/project;打开终端后执行 printf 'canonical-terminal-ok\n'; pwd,画面可见 canonical-terminal-ok 与实际工作目录输出,且未出现 Safe Storage 钥匙串弹窗。
  • 本地 main 同步后 targeted checks 通过:cd desktop && bun run test -- src/components/workspace/WorkspaceFileOpenWith.test.tsx src/lib/previewEvents.test.ts electron/services/updater.test.tscd desktop && bun run check:electronbun test src/server/middleware/cors.test.ts src/server/__tests__/h5-access-policy.test.ts

Review 已收口

  • Packaged app 不再信任 ELECTRON_RENDERER_URL;只有 dev 模式允许 local HTTP renderer。
  • Preview external page bridge 增加消息大小上限、事件类型 allowlist、字段 schema 和 data URL 校验。
  • Packaged macOS node-pty runtime cache 会从 bundle manifest 校验,发现 tamper 后重建cache 权限收紧。
  • macOS 通知设置入口改走 native command + allowlisted system settings URL。
  • Electron preview.message() 不再 silent no-op会转发到 injected preview bridge。
  • Dev/release desktop workflows 在 Electron builder 后运行 test:package-smoke,阻止缺失关键 runtime 资源的产物上传/发布。
  • Packaged Electron file:// renderer origin 已纳入 server CORS/H5 token local-origin policy避免真实打包 app 的 chat WebSocket 在 H5 token mode 下被拒绝。
  • Electron Builder publish 配置不再依赖 git remote autodetectionartifactName 改为无空格稳定文件名package-smoke 会检查 latest*.yml 引用的本地 artifact 是否存在。

必跑本地门禁

  • bun run check:native
  • bun run check:desktop
  • bun run check:docs
  • bun run verify:最新为 artifacts/quality-runs/2026-05-31T21-42-57-279Z/report.mdpassed=9 failed=0 skipped=1
  • bun run check:coverage:最新为 artifacts/coverage/2026-05-31T21-46-15-873Z/coverage-report.mdpassed=5 failed=0
  • 同步本地 mainfile:// CORS/H5 修复和 Electron 迁移当前态后复跑 bun run check:server88 files / 969 tests passed。
  • 同步本地 main 与 updater no-op 修复后复跑 cd desktop && bun run check:electron16 files / 76 tests passed。
  • bun run test:package-smoke --platform macos
  • cd desktop && bun run test -- --run scripts/dev-launcher.test.ts && bun run check:electron:新增 Electron dev launcher 代理绕过回归,最新 Electron checks 为 17 files / 79 tests passed。
  • bun run test:package-smoke --platform macos:结构检查仍通过,并明确提示该命令不做 Gatekeeper launch approval。
  • cd desktop && bun run test -- src/lib/desktopRuntime.test.ts src/components/shared/UpdateChecker.test.tsx src/lib/composerAttachments.test.ts src/components/chat/ChatInput.test.tsx src/pages/EmptySession.test.tsx src/components/layout/AppShell.test.tsx src/components/controls/PermissionModeSelector.test.tsx src/components/shared/RepositoryLaunchControls.test.tsx8 files / 75 tests passed覆盖 Electron/Tauri 通用 desktop runtime 判断、更新提示、native attachment picker 和移动布局分支。
  • cd desktop && bun run check:electron16 files / 77 tests passed覆盖 Electron updater proxy contract、IPC payload validation、main/preload/preview-preload bundle。
  • bun test scripts/quality-gate/package-smoke/index.test.ts7 tests passed发布型 macOS 包缺失 resources/app-update.yml 会失败,纯 --dir 开发包不强制该文件。
  • bun test scripts/quality-gate/package-smoke/index.test.ts scripts/pr/quality-contract.test.ts12 tests passed覆盖 host platform 到 package-smoke platform 的映射,并锁定 check:native 必须包含 electron:package:dirtest:package-smoke:current
  • bun run check:native:最新复跑完成 sidecar build、Electron 77 tests、Electron --dir package并执行 bun run test:package-smoke:current -> macOS .app 结构检查 PASSnotes 明确当前纯 --dir artifact set 不强制 app-update.yml,也不做 GUI/Gatekeeper launch approval。
  • Linux electron-builder --dir package-smoke 回归Linux 纯 linux-unpacked 开发目录包会检查 app.asar、unpacked sidecar 和 node-pty 后通过,不要求 AppImage/deb发布型 AppImage/deb artifact set 仍要求 update metadata 和 app-update.yml
  • PR native workflow Electron 化:desktop-native-checks 不再安装 WebKitGTK/Rust/Rust cachebuild-sidecars 不再用 rustc -vV 推导 host triplecheck:native 只依赖 Bun/Electron sidecar/package-smoke 链路。
  • package-smoke 显式包类型:check:native 通过 --package-kind dir --artifacts-dir desktop/build-artifacts/electron 验开发目录包dev/release workflows 和平台构建脚本通过 --package-kind release --artifacts-dir <精确输出目录> 验发布包,避免旧 artifact 混入。
  • release gate 验包收窄:quality:gate --mode release 现在包含 PR checks并使用当前平台 canonical release dir 运行 test:package-smoke --package-kind release --artifacts-dir desktop/build-artifacts/<platform-arch>,不再把 desktop/build-artifacts/electron 的开发目录包当 release 证据macOS release lane 还会追加 --require-macos-gatekeeper,与 release workflow 上传前 Gatekeeper 检查保持一致。
  • 当前平台 canonical release package-smoke 复验:bun run test:package-smoke --platform macos --package-kind release --artifacts-dir desktop/build-artifacts/macos-arm64 通过,确认 canonical zip/update metadata/app-update.yml/sidecar/node-pty 结构仍完整;该命令仍不声明 GUI/Gatekeeper launch success。
  • release workflow preflightGitHub tag/workflow_dispatch 打包矩阵前先运行 bun run verify,避免 tag release 绕过 PR-quality 基线。
  • signing/notarization secrets preflight独立非 matrix signing-preflight job 在打包矩阵前检查 Developer ID、notarization 和 Windows signing secrets缺失时 GitHub Actions 直接报错并阻止所有平台 artifact 上传,不再等到 Electron Builder/Gatekeeper 阶段或发布 partial release 后才失败。
  • 多架构 update metadata 上传冲突规避release workflow 上传前将 latest*.yml 重命名为带 matrix label 的唯一 asset避免 GitHub Release 中 latest-mac.yml/latest-linux.yml 同名覆盖或上传失败。
  • 多架构标准 updater metadata 合并:scripts/release-update-metadata.ts 会在 matrix build 全部通过后重新发布标准 channel metadatamacOS 合并 x64/arm64 entries 到 latest-mac.ymlLinux 恢复 latest-linux.yml / latest-linux-arm64.ymlWindows 恢复 latest.yml。完整自动更新 release 仍需在 signed/notarized artifact 上复验。
  • MAC_TARGETS=zip SKIP_INSTALL=1 SIGN_BUILD=0 desktop/scripts/build-macos-arm64.shcanonical macOS zip/update artifact set 通过;脚本自动执行 bun run test:package-smoke --platform macos --package-kind release --artifacts-dir desktop/build-artifacts/macos-arm64,确认 latest-mac.yml 引用真实 zip安装后 resources 包含 app-update.yml
  • bun run quality:gate --mode baseline --allow-live --only 'provider-smoke:*' --provider-model sub2api-chatgpt:main:sub2api-chatgpt-mainartifacts/quality-runs/2026-05-31T21-28-07-154Z/report.mdpassed=1 failed=0 skipped=0,直接复用本机 cc-haha provider selector。
  • 当前 release provider smoke 复验:bun run quality:gate --mode release --allow-live --only 'provider-smoke:*' --provider-model sub2api-chatgpt:main:sub2api-chatgpt-main 通过,报告为 artifacts/quality-runs/2026-06-01T12-18-47-144Z/report.mdpassed=1 failed=0 skipped=0
  • cd desktop && bun test electron/services/updater.test.ts10 tests passed覆盖 unpacked app-update.yml 缺失、packaged update config 缺失时不调用 updater、GitHub release 缺少 latest-mac.yml 时降级为无更新、关闭 electron-updater 内置 logger以及非 metadata updater 错误继续抛出。
  • cd desktop && bun run check:electron:最新 97 tests passed覆盖通知 smoke close/failed lifecycle JSONL、synthetic action + renderer ack JSONL、updater missing channel metadata 修复、Keychain guard、single-instance validation bypass、update smoke stub、window smoke 诊断和 Electron main/preload/preview-preload bundle。
  • bun run test:package-smoke --platform macos --package-kind release --artifacts-dir desktop/build-artifacts/macos-arm64 --require-macos-gatekeeper:当前失败;非 Gatekeeper 结构检查 PASS包含 latest-mac.yml 引用 zip、安装后 app-update.yml、sidecar 和 node-pty。追加 Gatekeeper 后 codesign verify/details 通过,但 spctl 返回 bundle format unrecognized, invalid, or unsuitablestapler 返回 does not have a ticket stapled to it。package-smoke 现已在 spctlToo many open files 时用 raised file descriptor limit 自动重试,避免该临时诊断掩盖真实 Gatekeeper 结果。release-ready 需要 Developer ID signing/notarization 或在真实签名产物上复验。
  • Gatekeeper 失败诊断:--require-macos-gatekeeper 现在在 spctl 失败时记录 codesign --verify --deep --strict --verbose=2codesign -dv --verbose=4xcrun stapler validate 摘要,便于 signed/notarized artifact 在 CI/release runner 上定位签名链、bundle 格式或 notarization ticket 问题。
  • Gatekeeper 诊断复验:bun run test:package-smoke --platform macos --package-kind release --artifacts-dir desktop/build-artifacts/macos-arm64 --require-macos-gatekeeper 预期失败;输出中包含 spctl Gatekeeper assessment exited with status 1codesign verification exited with status 0、bundle identifier/signature detail 摘要,以及 notarization ticket validation exited with status 65 / does not have a ticket stapled to it
  • release workflow macOS 上传前强制运行 bun run test:package-smoke --platform macos --package-kind release --artifacts-dir desktop/build-artifacts/electron --require-macos-gatekeeper;开发构建仍只跑结构验包,因为 dev workflow 明确禁用签名自动发现。
  • Security/Runtime Review 修复Electron renderer 不再有 previewEval 任意 JS 注入 IPC预览截图/元素选择走结构化 preview.messageshell.openPath 拒绝 app bundle、脚本/安装器/Windows 可执行扩展和 POSIX executable 文件Electron windowControls=falseWindows 暂不显示自定义 window chrome。
  • 历史 bun run quality:gate --mode release --allow-live --provider-model sub2api-chatgpt:main:sub2api-chatgpt-mainartifacts/quality-runs/2026-05-31T20-29-45-758Z/report.mdpassed=15 failed=0 skipped=0。SubAgent Review 后 release gate 已收窄为 canonical release artifact 验包;该历史报告不能再作为当前 release-ready 证据。
  • 重新运行当前 bun run quality:gate --mode release --allow-live --provider-model sub2api-chatgpt:main:sub2api-chatgpt-main:需要 signed/notarized artifact、canonical release metadata 和可用 Computer Use 桌面会话。
  • bun run quality:gate --mode release --dry-run --only 'desktop-package-smoke:*':报告 artifacts/quality-runs/2026-06-01T12-15-48-692Z/report.md,确认 macOS release package-smoke 命令包含 --require-macos-gatekeeper
  • bun run quality:gate --mode release --only 'desktop-package-smoke:*':报告 artifacts/quality-runs/2026-06-01T12-16-06-442Z/report.md,按预期失败于 Gatekeeper结构检查均通过spctl 返回 bundle format unrecognized, invalid, or unsuitablestapler 返回 does not have a ticket stapled to it
  • bun run check:policy77 tests passed并执行 check:quarantine;覆盖 release workflow、quality gate runner、provider/desktop smoke、change policy、quality contract 和 quarantine governance。
  • 本地 main 同步后 focused regression已应用 main 最近 10 个提交的非重叠改动,并手动合并 ChatInput.tsx / previewEvents.ts / previewEvents.test.ts 冲突面。验证desktop ChatInput/previewEvents 24 tests passedserver/CLI/image/powershell/provider 124 tests passedFeishu streaming card 36 tests passedcd desktop && bun run check:electron 94 tests passed。
  • 本地 main 同步后重新打包:CSC_IDENTITY_AUTO_DISCOVERY=false bun run electron:package:dir 完成当前源码 packaged dirbun run test:package-smoke --platform macos --package-kind dir --artifacts-dir desktop/build-artifacts/electron PASS。
  • release update blockmap 验证补强:bun test scripts/quality-gate/package-smoke/index.test.ts 通过 17 testsbun run test:package-smoke --platform macos --package-kind release --artifacts-dir desktop/build-artifacts/macos-arm64 PASS并确认当前 macOS release artifact set 包含 .dmg.blockmap.zip.blockmap。Windows .exe.blockmap 与 Linux .AppImage.blockmap 已由 fixture 回归覆盖,仍需实机 release artifact smoke。
  • 通知点击 renderer ack 证据补强Electron renderer 处理通知 action 并打开目标 session 后,会通过 desktop:notification:action-ack 回写 renderer_ackCC_HAHA_ELECTRON_NOTIFICATION_SMOKE_LOG,用于后续可点击 OS 通知环境证明 main action 已进入 UI 导航链路。验证focused notification/desktopHost tests 42 passedcd desktop && bun run check:electron 97 tests passed。
  • git diff --check

macOS Computer Use Smoke

  • 2026-06-01 复测阻塞:早期 Computer Use 工具层对 list_appsget_app_state(Finder) 返回 NSOSStatusErrorDomain Code=-600 procNotFound;后续 list_apps 恢复,但 get_app_state(Electron) 仍超时,get_app_state(Finder)cgWindowNotFound,同时系统 screencapture 返回 could not create image from display。当前阻塞已定位为本机会话显示/截图能力不可用,不能把它解释为 Electron app 单点故障。
  • 2026-06-01 continuation 复测Computer Use list_apps 可列出运行中应用,但 get_app_state(Finder) 仍为 cgWindowNotFound;系统 screencapture 仍返回 could not create image from display。当前仍无法进行点击、输入、选择文件等 Computer Use GUI 操作。
  • 2026-06-01 Electron dev smoke本机代理环境会让 electron:dev 的 renderer 等待请求命中 502已把默认 renderer URL 改为 http://localhost:1420并对当前进程、Vite 子进程和 Electron 子进程补齐 NO_PROXY/no_proxy=localhost,127.0.0.1,::1。重启后 Electron dev 壳可启动 sidecar 和 renderer。
  • 2026-06-01 窗口可见性修正Electron main 在创建主窗口后立即 show/focusrenderer load 完成后再补一次,避免隐藏窗口等待 renderer load 时被 Computer Use/系统自动化看成无窗口。
  • 2026-06-01 packaged launch policyopen -n desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.app 被 macOS AppleSystemPolicy 直接终止ad-hoc 和本机 Apple Development 重新签名的临时副本均未通过 spctl。因此当前 unpacked .app 只能证明结构完整,不能声明 release launchable。
  • 2026-06-01 DMG builder policy清理所有旧 Claude Code Haha disk image 挂载后zip-only Electron Builder 可成功产出 update metadataDMG target 仍在本机 hdiutil create 超时,且失败后的临时读写 disk image 无法正常 detach。该项保持 macOS runner/DiskImages blocker。
  • 2026-06-01 final-definition 复测Computer Use list_apps 仍可列出运行中应用,get_app_state(Finder) 仍返回 cgWindowNotFound;系统 screencapture -x 仍返回 could not create image from display。当前机器仍不能作为 Computer Use GUI 验收环境。
  • 2026-06-01 cross-platform-script 复测Computer Use list_apps 可列出应用且包含 /Applications/Claude Code Haha.app,但 get_app_state(Finder) 仍返回 cgWindowNotFoundget_app_state(Claude Code Haha) 返回 remoteConnection,系统 screencapture -x /tmp/cc-haha-computer-use-check.png 仍失败为 could not create image from display。当前机器继续不能完成真实 GUI 操作验收。
  • 2026-06-01 package-kind 复测Computer Use list_apps 可列出运行中的 /Applications/Claude Code Haha.app,但 get_app_state(Claude Code Haha)get_app_state(Finder) 均返回 cgWindowNotFound;系统 screencapture -x /tmp/cc-haha-computer-use-check-2.png 仍失败为 could not create image from display。当前机器继续不能完成点击、输入、系统文件选择器、托盘/通知等 GUI 验收。
  • 2026-06-01 Gatekeeper 诊断后复测Computer Use list_apps 可列出运行中的 /Applications/Claude Code Haha.app,但 get_app_state(Claude Code Haha)get_app_state(Finder) 均返回 cgWindowNotFound;系统 screencapture -x /tmp/cc-haha-computer-use-check-3.png 仍失败为 could not create image from display。当前机器仍不是可用的 Computer Use GUI 验收环境。
  • 2026-06-01 release metadata 合并后复测Computer Use list_apps 仍可列出运行中的 /Applications/Claude Code Haha.app,但 get_app_state(Claude Code Haha)get_app_state(Finder) 仍返回 cgWindowNotFound;系统 screencapture -x /tmp/cc-haha-computer-use-check-4.png 仍失败为 could not create image from display。当前机器仍不能执行真实 GUI 操作验收。
  • 2026-06-01 mock update feed UI 补强后复测Computer Use list_apps 仍可列出运行中的 /Applications/Claude Code Haha.app,但 get_app_state(Claude Code Haha)get_app_state(Finder) 仍返回 cgWindowNotFound;系统 screencapture -x /tmp/cc-haha-computer-use-check-5.png 仍失败为 could not create image from display。当前机器仍不能执行真实 GUI 操作验收。
  • 2026-06-01 Keychain prompt mitigationElectron main 在 macOS 启动早期启用 Chromium use-mock-keychain,避免 claude-code-desktop Safe Storage 反复弹登录钥匙串授权;ModelSelector 不再挂载即请求 Claude/OpenAI 官方 OAuth status而是 runtime 下拉打开时按需请求一次。验证focused ModelSelector/keychain tests 12 passedcheck:electron 80 passed。
  • 2026-06-01 Keychain prompt Computer Use 复测:当前 Electron dev 壳启动后 get_app_state(Electron) 成功返回 localhost:1420/ 主界面Computer Use 截图和 AX 树没有出现 Safe Storage 钥匙串授权弹窗。
  • 2026-06-01 Keychain prompt 当前态复验focused ModelSelector/keychain tests 12 passedcheck:electron 83 passedComputer Use get_app_state(Electron) 返回 Claude Code Companion 主窗口和 localhost:1420/ renderer未出现 Safe Storage 钥匙串授权弹窗。
  • 2026-06-01 附件选择 Computer Use 复测:当前 Electron dev 壳中点击 composer 添加文件或图片macOS 原生 打开 面板可用;选择 /Users/nanmi/cc-haha-cua-attachment-smoke.txt 后回到 composer并显示 cc-haha-cua-attachment-smoke.txt 附件 chip未出现 Safe Storage 钥匙串弹窗。
  • 2026-06-01 Python 路径选择 Computer Use 复测:当前 Electron dev 壳中点击 Computer Use 设置里的 选择macOS 原生 选择 Python 解释器 面板可用;选择 /Users/nanmi/cc-haha-cua-python3-smoke 后设置页保存并解析到 /opt/homebrew/Cellar/python@3.14/3.14.5/Frameworks/Python.framework/Versions/3.14/bin/python3.14;随后恢复自动检测,/api/computer-use/authorized-apps 返回 pythonPath: null
  • 2026-06-01 外链 Computer Use 复测:当前 Electron dev 壳中点击关于页 GitHub 项目卡片后,系统浏览器 Google Chrome 被拉到前台,地址栏为 github.com/NanmiCoder/cc-hahaElectron renderer 仍停留在 localhost:1420/,未在应用内导航外链。
  • 2026-06-01 窗口关闭/恢复 Computer Use 复测:当前 Electron dev 壳中点击 macOS 关闭按钮后Electron 进程仍在 Computer Use list_apps 中保持 running 且主窗口消失;通过 macOS app activation 路径重新激活同一 Electron app 后Computer Use 再次看到 Claude Code Companion 主窗口和 localhost:1420/ renderer。Computer Use 当前不能稳定枚举 Dock因此本轮验证的是与 Dock 点击等价的 app activation/show 主窗口路径。
  • 2026-06-01 通知点击 smoke hook新增显式环境变量 CC_HAHA_ELECTRON_NOTIFICATION_SMOKE_SESSION_ID=<session-id>,用于让 Electron main process 发送带 session target 的真实 Electron 通知focused tests 覆盖默认不发送、target payload 透传和窗口恢复链路。真实 OS 点击复测时Computer Use 对 Notification Center/SystemUIServer 均超时,且 get_app_state(Electron) 本身会激活 app因此不能作为点击通知证据该项仍保持未勾选。
  • 2026-06-01 通知点击二次复测:用 CC_HAHA_ELECTRON_NOTIFICATION_SMOKE_DELAY_MS=30000 启动 Electron dev 壳Computer Use 先确认 localhost:1420/ 主窗口可见,再点击 macOS close buttonElectron 随后无主窗口符合隐藏到后台预期。等待通知触发后Computer Use 对 SystemUIServer/System/Library/CoreServices/NotificationCenter.app 仍返回 timeoutReached,前台 Chrome 截图/AX 树也未出现可点击通知横幅,因此仍不能证明真实 OS 通知点击回跳。
  • 2026-06-01 packaged 通知 JSONL smoke新增 CC_HAHA_ELECTRON_NOTIFICATION_SMOKE_LOG=<path> 后重新打包 packaged app隔离配置启动后 Computer Use 确认 packaged file://.../app.asar/dist/index.html 主窗口可见JSONL 记录 scheduledsent:true。Computer Use 对 SystemUIServer 和 Notification Center 仍 timeoutReachedJSONL 未出现 action,因此仍不能勾选“点击通知后回到目标 session”。
  • 2026-06-01 packaged 通知点击当前态复测canonical packaged app 使用 CC_HAHA_ELECTRON_NOTIFICATION_SMOKE_SESSION_ID=notification-click-smoke-sessionCC_HAHA_ELECTRON_NOTIFICATION_SMOKE_DELAY_MS=8000 和 JSONL log 启动Computer Use 关闭主窗口后 app 留在后台JSONL 记录 scheduledsent:true。Computer Use 对 UserNotificationCenter.app 返回安全策略拒绝,对 NotificationCenter.apptimeoutReached,因此真实 OS 点击仍未完成。通知 smoke 现已记录 lifecycle: close|failed,后续可在可操作通知横幅的 macOS/Windows runner 上区分 close、failed 和 action。
  • 2026-06-01 packaged 通知点击 launchctl 复测:直接执行 app binary 时 smoke env 没有进入最终 Electron app 进程;改用 launchctl setenv + open -n 启动隔离 packaged app 后JSONL 正常记录 scheduledsent:true。Computer Use 对 Notification Center 与 SystemUIServer 仍 timeoutReachedFinder 状态读取返回 ScreenCaptureKit stream errorJSONL 未出现 action,所以真实点击回跳仍不能勾选。
  • 2026-06-01 通知点击再次复测worktree packaged app 通过 launchctl setenv 启动后,通知 JSONL 正常记录 scheduledsent:trueComputer Use 对 worktree app 连续返回 ScreenCaptureKit stream errorlist_apps 仍能看到该 app running。复制当前 packaged app 为唯一 bundle id smoke app 并 ad-hoc 重签名后LaunchServices 能注册 Claude Code Haha Smoke,但 app 立即退出,系统日志显示 appDeath本轮仍没有真实 OS 点击 action 证据。
  • 2026-06-01 renderer ack 补强后 packaged 复测:重新打包 desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.app 并通过 package-smoke dir PASS首次以 notification smoke env 启动时 Computer Use 读取 worktree packaged app 返回 timeoutReached,直接执行也曾退出 137。随后用隔离 CLAUDE_CONFIG_DIR / --user-data-dir 重新直接运行同一 .app 后保持运行Computer Use 成功读取 Claude Code Companion 主窗口renderer URL 为 file:///Users/nanmi/.codex/worktrees/2392/claude-code-haha/desktop/build-artifacts/electron/mac-arm64/Claude%20Code%20Haha.app/Contents/Resources/app.asar/dist/index.html;点击设置入口后进入 packaged 设置页。spctl 仍返回 bundle format unrecognized, invalid, or unsuitablecodesign --verify --deep --strict 通过,因此 signed/notarized Gatekeeper 与真实 OS 通知点击仍未完成。
  • 2026-06-01 packaged synthetic notification action 复测:新增 CC_HAHA_ELECTRON_NOTIFICATION_SMOKE_TRIGGER_ACTION=1,仅在显式 smoke 环境中由 main process 触发同一条 notification action -> renderer navigation -> desktop:notification:action-ack 诊断链路。用 launchctl setenv + open -n desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.app --args --user-data-dir=<tmp> 启动当前 worktree packaged app 后Computer Use 成功读取 packaged file://.../app.asar/dist/index.html 主窗口JSONL 记录 scheduledsent:truesynthetic_actionrenderer_ack。该 synthetic action 不代表真实 OS 通知点击,真实点击回跳仍未勾选。
  • 2026-06-01 DiskImages 复核:hdiutil info 仍显示 Electron Builder 失败遗留的 .temp...Claude-Code-Haha-0.3.2-arm64.dmg 挂载在 /dev/disk4,但无 hdiutil / diskutil / electron-builder 残留进程;此前 hdiutil detachdiskutil 对该设备会阻塞,继续强制处理会污染当前验证。
  • 2026-06-01 macOS build script hardening默认 SKIP_INSTALL=1 SIGN_BUILD=0 desktop/scripts/build-macos-arm64.sh 现在在 stale .temp...Claude-Code-Haha-0.3.2-arm64.dmg 挂载存在时 fail fast并提示改用 MAC_TARGETS=zip 验证 update zipMAC_TARGETS=zip 路径通过且自动 package-smoke PASS。
  • 2026-06-01 macOS canonical release 复测:默认 SKIP_INSTALL=1 SIGN_BUILD=0 desktop/scripts/build-macos-arm64.sh 已完成 .dmg + .zip + latest-mac.ymlpackage-smoke release PASS。启动 canonical .app 后 Computer Use 成功读取 Claude Code Companion 主窗口electron-updater 内置 logger 已关闭,缺失 GitHub latest-mac.yml 不再向启动日志输出 404 stack。
  • 2026-06-01 canonical packaged system interaction 复测:启动 desktop/build-artifacts/macos-arm64/Claude Code Haha.app 的隔离实例后Computer Use 读取到 packaged file://.../app.asar/dist/index.html 主界面,项目选择器显示 /private/tmp/cc-haha-electron-real-fixed-sRFUeO/project;点击 打开终端 后终端面板运行 /bin/zsh,输入 printf 'canonical-terminal-ok\n'; pwd 后显示 canonical-terminal-ok/tmp/cc-haha-canonical-cua-flow.xTxSmt/claude-config。该轮未出现 claude-code-desktop Safe Storage 钥匙串授权弹窗。
  • 2026-06-01 canonical packaged Computer Use 设置流程复测:启动 desktop/build-artifacts/macos-arm64/Claude Code Haha.app 的隔离实例后,用 Computer Use 进入 设置 > Computer Use。首次状态请求曾 30s timeout点击 重试 后状态页正常;通过 安装环境 按钮完成 venv 创建与依赖安装。UI 显示 Python 3.14.5、虚拟环境已就绪、依赖包已安装、辅助功能权限已授权、屏幕录制权限未授权;GET /api/computer-use/status 返回 venv.created=truedependencies.installed=truepermissions.accessibility=truepermissions.screenRecording=false。点击 打开屏幕录制设置Computer Use 读取到 macOS 系统设置窗口 录屏与系统录音,列表中包含 Claude Code Haha 权限项。
  • 2026-06-01 canonical packaged Computer Use 授权应用复测:同一 packaged app 隔离实例中Computer Use 在 已授权应用 搜索框输入 Terminal,列表返回 Terminal / com.apple.Terminal;点击后 UI 显示 check 状态,隔离 cc-haha/computer-use-config.jsonGET /api/computer-use/authorized-apps 均返回 authorizedApps[0].bundleId=com.apple.Terminalgrant flags 为 clipboardRead=trueclipboardWrite=truesystemKeyCombos=true。该项覆盖真实 UI 输入、点击、滚动、应用枚举和授权配置持久化。
  • 2026-06-01 packaged menu/window lifecycle 复测:在隔离 desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.appComputer Use 点击 macOS app menu Settings... 后打开设置页;点击窗口关闭按钮后主窗口消失且同一 PID 继续运行System Events 显示 count=0;随后 app activation 恢复窗口Computer Use 再次读取到 packaged file://.../app.asar/dist/index.html 设置页。继续通过 app menu Quit 退出后,隔离配置写入 window-state.json;用同一 CLAUDE_CONFIG_DIR--user-data-dir 重启Computer Use 成功读取新 PID 的 packaged 主窗口System Events 显示 count=1 names=Claude Code Companion。该项覆盖菜单打开设置、关闭隐藏、恢复窗口和重启后窗口仍可见;真实 tray 图标点击仍未单独完成。
  • 2026-06-01 Gatekeeper 诊断补强后 packaged launch 复测:用隔离 CLAUDE_CONFIG_DIR--user-data-dir 启动 desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.appComputer Use 成功读取 Claude Code Companion 主窗口和 packaged file://.../app.asar/dist/index.html renderer未出现 Safe Storage 钥匙串弹窗。
  • 2026-06-01 release provider smoke 后 packaged launch 复测:真实 provider smoke 通过后,再次用隔离 CLAUDE_CONFIG_DIR--user-data-dir 启动 desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.appComputer Use 成功读取 packaged file://.../app.asar/dist/index.html 主窗口。
  • 2026-06-01 policy gate 后 packaged launch 复测:check:policy 通过后,再次用隔离 CLAUDE_CONFIG_DIR--user-data-dir 启动 packaged appComputer Use 首次读取遇到 ScreenCaptureKit stream errorSystem Events 同时显示同一 PID 有 Claude Code Companion 窗口,重试后 Computer Use 成功读取 packaged renderer。
  • 2026-06-01 本地 main 同步后 packaged launch 复测:重新打包 desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.app,使用隔离 CLAUDE_CONFIG_DIR=/tmp/cc-haha-main-sync-cua-1780317323/config 和隔离 --user-data-dir 启动Computer Use 成功读取 Claude Code Companion 主窗口和当前 packaged renderer未出现 Safe Storage 钥匙串弹窗。
  • 启动真实 packaged appdesktop/build-artifacts/electron-smoke/mac-arm64/Claude Code Haha Smoke.app。该 smoke bundle 使用同一构建产物重新打包,仅更换临时 appId/productName 以避开本机已运行的正式 app 单实例锁。
  • 本地 main 同步后启动真实 packaged appdesktop/build-artifacts/electron/mac-arm64/Claude Code Haha.app,使用隔离 --user-data-dir=/tmp/cc-haha-electron-real-fixed-sRFUeO/user-data 和隔离 CLAUDE_CONFIG_DIR
  • 确认主界面从 packaged renderer 加载local server sidecar 自动启动,无需手动 SERVER_PORT
  • 打开终端,执行 printf electron-terminal-ok,确认输出可见。
  • 关闭终端后通过进程列表确认没有残留 /tmp/cc-haha-electron-smoke-config PTY shell。
  • 选择工作目录,确认系统目录对话框可打开。
  • 复制本机 cc-haha provider/model 配置到隔离临时配置目录,真实模型选择器显示 gpt-5.5 Sub2API-ChatGPT
  • 真实模型 chat smoke会话 e0d7abc2-27db-4ff1-9954-7923f6c3385e 通过 WebSocket 启动 CLI subprocess读取 package.jsonsrc/greeting.ts,经 UI 权限审批执行 bun testJSONL 记录 1 pass / 0 failComputer Use 看到最终回复“测试通过。”。
  • 选择附件文件,确认文件可加入 composer。
  • 打开 Python 路径选择,确认系统文件选择器可用。
  • 点击外链或 OAuth 帮助链接,确认走系统浏览器。
  • 关闭主窗口,确认 Dock/app activation 可恢复窗口;真实 tray 图标点击仍需可枚举 tray 环境复验。
  • 触发通知,点击通知后回到目标 session。
  • 触发通知发送 smokepackaged app 通过 CC_HAHA_ELECTRON_NOTIFICATION_SMOKE_LOG 记录 scheduledsent:true;真实 OS 点击仍因 Computer Use 无法操作 Notification Center/SystemUIServer 而未完成。
  • 打开 preview/workbench browser panel导航 https://example.com/,确认 WebContentsView 加载成功。
  • 点击 preview 截图,确认 screenshot-full.png 回填到 composer。
  • packaged Computer Use 设置流程:隔离配置下完成环境安装,确认 venv/依赖状态、辅助功能/屏幕录制权限状态,并从应用打开 macOS 录屏与系统录音 设置页。
  • packaged Computer Use 授权应用流程:搜索并授权 Terminal / com.apple.Terminal,确认剪贴板和系统快捷键 grant flags 持久化。
  • unpacked dir package 缺少 app-update.yml 时 update check 视为无更新,不阻塞 UI非 metadata updater 错误仍会抛出。
  • 更新代理 contractElectron updater 会接收 renderer 传入的 manual proxy并在切回 system proxy 时清理手动代理IPC validator 只允许 { proxy: string } 形状,拒绝空 proxy 或额外字段。
  • 关闭 electron-updater 内置 logger避免缺失远端 latest-mac.yml 时把 404 stack 打到 packaged app 启动日志;业务层仍把 metadata 缺失分类为“无更新”。
  • 发布型包 updater metadata如果 artifact set 中存在 release archive/update metadatapackage-smoke 会强制检查安装后 resources/app-update.yml防止“有 latest*.yml 但安装后永远无法检查更新”的包进入 releasemacOS zip-only canonical artifact set 已通过该检查。
  • packaged app updater 缺失 channel metadata smoke重新打包 desktop/build-artifacts/electron/mac-arm64/Claude Code Haha.app 后,用隔离配置目录直接运行 app executableComputer Use 确认 packaged renderer 从 file://.../app.asar/dist/index.html 加载local server sidecar 自动启动,未出现 Safe Storage 钥匙串弹窗,日志未再出现 ERR_UPDATER_CHANNEL_FILE_NOT_FOUND IPC handler 崩错。纯 --dir 包缺少 app-update.yml 的提示仍按无更新处理。
  • 触发 mock feed确认 check/download/install/relaunch 状态流不阻塞 UIUpdateChecker 集成测试通过 Electron desktopHost mock update feed 驱动真实 updateStore,覆盖下载完成弹窗、点击 install、prepare/install/relaunch 调用和 prompt 退出。signed/release update feed 仍需在真实 signed/notarized artifact 上复验。
  • packaged main/preload update smokeCC_HAHA_ELECTRON_UPDATE_SMOKE_VERSION=9.9.9-smoke 启动唯一 bundle id 的 packaged dir apppackaged renderer 通过 preload 调用 desktopHost.updates.check/download/prepareInstall/install/relaunchJSONL 记录 checkdownload-startdownload-finishquit-and-install。Computer Use list_apps 可见该 smoke appget_app_state 超时,真实桌面点击安装仍按未完成处理。
  • packaged window smoke 诊断:CC_HAHA_ELECTRON_WINDOW_SMOKE_LOG 记录 packaged app 在 after-initial-showafter-final-show 均为 visible:truebounds 为 1280x820renderer URL 为 packaged file://.../app.asar/dist/index.html;早前 System Events 曾返回 windows count=0 且 Computer Use get_app_state 超时。随后用完整 .app 路径复测Computer Use 成功读取 Claude Code Companion 主窗口和 packaged rendererSystem Events 返回 front=true count=1 names=Claude Code Companion。因此之前卡点是 macOS AX/窗口捕获状态波动,不是 renderer、server sidecar 或 update preload smoke 失败。

Windows 待实机

  • 构建 NSIS 安装器并安装。
  • Windows build script 已补 canonical package-smokedesktop/scripts/build-windows-x64.ps1 会复制 installer/update metadata/blockmap/win-unpackeddesktop/build-artifacts/windows-x64,并默认运行 bun run test:package-smoke --platform windows --package-kind release --artifacts-dir desktop/build-artifacts/windows-x64
  • 在 Windows runner/实机运行 bun run test:package-smoke --platform windows 或 build script 内置 canonical package-smoke。
  • 启动安装后的 app验证 sidecar 自动启动。
  • 验证 sidecar 文件锁、更新前 stop process、通知、托盘、窗口隐藏/恢复、系统对话框。
  • 完成一次 Computer Use 设置和操作 smoke。

Linux 待实机

  • 构建 AppImage/deb。
  • Linux build script 已补 canonical package-smokedesktop/scripts/build-linux.sh 支持 LINUX_ARCH=x64|arm64,会复制 AppImage/deb/update metadata/blockmap/linux-unpackeddesktop/build-artifacts/linux-<arch>,并默认运行 bun run test:package-smoke --platform linux --package-kind release --artifacts-dir desktop/build-artifacts/linux-<arch>
  • Linux arm64 update metadata preflight 已补:desktop/scripts/build-linux.sh 复制 latest-linux*.ymlpackage-smoke 识别 latest-linux.ymllatest-linux-arm64.yml 并校验 metadata 引用的 AppImage/deb artifact回归测试覆盖 canonical linux-arm64 输出。
  • 在 Linux runner/实机运行 bun run test:package-smoke --platform linux 或 build script 内置 canonical package-smoke。
  • 启动 AppImage/deb 安装后的 app验证 sidecar 自动启动。
  • 验证 tray、通知、系统对话框、外链、更新策略如平台能力降级写入 release note。

完成判定

  • macOS packaged app 完成 Computer Use smoke。历史上已完成启动、server、终端、目录选择、preview、真实模型 chat 与 unpacked updater no-opdev 壳另已补附件选择、Python 路径选择、外链打开和窗口关闭后 app activation 恢复证据。最终完成仍需要可启动的 signed/notarized artifact、可截图/可点击桌面会话、通知点击回跳和完整 update feed 复验。
  • Windows packaged app 完成实机 smoke或明确记录 release blocker。
  • Linux packaged app 完成实机 smoke或明确记录 release blocker。
  • verify 通过,并记录 quality report 与 coverage report 路径。最新 quality reportartifacts/quality-runs/2026-05-31T21-42-57-279Z/report.mdcoverage reportartifacts/coverage/2026-05-31T21-46-15-873Z/coverage-report.md
  • live release gate 通过,或明确记录 provider/live access blocker。最新 release --allow-live 已通过:artifacts/quality-runs/2026-05-31T20-29-45-758Z/report.mdpassed=15 failed=0 skipped=0