# OpenClaw 客户端自动更新方案

  ## Summary

  为当前 Electron 客户端增加“版本更新自动推送”能力：客户端启动后自动检查版本，云端可按版本、渠道、员工/组织做灰度或强
  制更新；用户收到提示后点击下载并安装，体验接近 WorkBuddy。

  默认采用“自有云接口 + electron-updater + NSIS 安装包”的方案，优先适配当前 Windows-first 打包链路。

  ## Key Changes

  ### 更新发布链路

  - 在 apps/desktop 引入 electron-updater。
  - 在 apps/desktop/electron-builder.yml 增加 publish/update feed 配置。
  - 打包后产物需要包含：
      - 千匠问天-Setup-x.y.z.exe
      - latest.yml
      - 安装包 sha512 校验信息
  - 发布流程调整为：
      1. 更新根 package.json 和 apps/desktop/package.json 版本号。
      2. 执行 corepack pnpm package。
      3. 上传 installer 与 latest.yml 到云端文件存储/CDN。
      4. 后端登记该版本的元数据。

  ### 云端版本接口

  新增一个产品更新接口，建议路径：

  POST /v1/desktop/update/check

  请求包含：

  {
    "appId": "com.qianjiangclaw.desktop",
    "currentVersion": "0.1.0",
    "platform": "win32",
    "arch": "x64",
    "employeeId": "xxx",
    "channel": "stable"
  }

  响应包含：

  {
    "available": true,
    "version": "0.2.0",
    "channel": "stable",
    "mandatory": false,
    "releaseNotes": "修复启动问题，优化专家加载。",
    "feedUrl": "https://cdn.example.com/qjclaw/stable/latest.yml",
    "downloadUrl": "https://cdn.example.com/qjclaw/stable/千匠问天-Setup-0.2.0.exe",
    "sha512": "..."
  }

  云端需要支持：

  - stable/beta/dev 渠道。
  - 按员工、组织、版本范围灰度。
  - 强制更新标记。
  - 最低可用版本，用于阻止过旧客户端继续使用。
  - 回滚到上一版本。

  ### 桌面主进程

  新增 AppUpdateService，放在 apps/desktop/src/main/services/app-update.ts。

  职责：

  - 读取当前 app.getVersion()。
  - 调用云端更新检查接口。
  - 配置 autoUpdater.setFeedURL(...)。
  - 管理状态机：
      - idle
      - checking
      - available
      - not-available
      - downloading
      - downloaded
      - installing
      - error
  - 处理 electron-updater 事件：
      - checking-for-update
      - update-available
      - update-not-available
      - download-progress
      - update-downloaded
      - error
  - 提供“立即安装”能力：调用 autoUpdater.quitAndInstall()。
  - 开发环境不自动安装，只返回 mock/disabled 状态。

  ### IPC 与共享类型

  在 packages/shared-types/src/index.ts 增加：

  - UpdateStatus
  - UpdateCheckResult
  - UpdateProgress
  - UpdateState
  - IPC channels：
      - app-update:get-status
      - app-update:check
      - app-update:download
      - app-update:install
      - app-update:event

  在 apps/desktop/src/preload/index.ts 暴露：

  qjcDesktop.appUpdate.getStatus()
  qjcDesktop.appUpdate.check()
  qjcDesktop.appUpdate.download()
  qjcDesktop.appUpdate.install()
  qjcDesktop.appUpdate.onEvent(listener)

  ### Renderer UI

  在 apps/ui/src/App.tsx 增加更新提示入口，保持现有主布局稳定。

  建议 UI 行为：

  - 普通更新：
      - 顶部 toast/notice 显示“发现新版本 x.y.z”。
      - 按钮：“立即更新”“稍后”。
      - 下载中显示进度。
      - 下载完成显示“重启并安装”。
  - 强制更新：
      - 显示不可关闭的更新弹窗。
      - 允许查看更新说明。
  - smoke/mock API 中补 mock update 状态，避免开发模式 UI 崩溃。

  - Windows 发布前建议接入代码签名证书。
  - 下载包必须校验 sha512。
  - 更新失败不得破坏现有安装。
  - 下载中断后允许重新下载。
  - 强制更新只阻止业务入口，不直接杀进程。
  - dev 模式默认禁用真实安装，避免误触发本地更新。

  ## Test Plan

  - corepack pnpm typecheck
  - corepack pnpm build
  - corepack pnpm package
  - 新增 smoke：
      - mock 云端返回无更新。
      - mock 云端返回普通更新。
      - mock 云端返回强制更新。
      - mock 下载失败时 UI 显示错误。
      - 已下载后触发安装 IPC。
  - 手工验证：
      - 旧版本安装后能检测到新版本。
      - 点击更新能下载安装包。
      - 点击“重启并安装”后版本变为新版本。
      - 强制更新弹窗不可被普通关闭绕过。
      - 设置页显示当前版本正确。

  ## Assumptions

  - 首期只支持 Windows NSIS 更新。
  - 更新源使用自有云接口控制版本策略，安装包文件放 CDN/对象存储。
  - 首期采用轮询检查，不做真正 WebSocket 实时推送：
      - 启动后检查一次。
      - 登录/绑定成功后检查一次。
      - 每 6 小时后台检查一次。
  - 真实“服务端主动推送”可作为二期，在现有状态机上增加 WebSocket/SSE 触发检查即可。
  - 未签名也能开发测试，但生产发布建议签名后再开放自动更新。