Files
zn-ai/docs/Launch-At-Startup-Migration-Plan.md
DEV_DSW 416399e7a8 feat: implement menu service for context menu management
feat: add provider API service for managing provider accounts and keys
feat: create provider runtime sync service for agent runtime management
feat: introduce script execution service for running automation scripts
feat: develop script store service for managing script metadata and storage
feat: implement theme service for managing application theme settings
feat: add updater service for handling application updates
feat: create window service for managing application windows and their states
2026-04-22 09:26:39 +08:00

464 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 开机自动启动功能复制计划
## 1. 目标与结论
目标是在 `zn-ai/src/pages/Setting/components/GeneralSettingsPanel.tsx` 中复制 `ClawX` 的“开机自动启动”能力,并把视觉位置排在“语言设置”后面、“网关设置”前面。
先给结论:
- `ClawX` 的“开机自动启动”不是单纯的前端 `Switch`,而是“设置持久化 + 主进程 OS 级生效 + 启动时回放同步”的完整链路。
- `zn-ai` 已经具备可复用的设置基础设施:`settingsStore``config-service``SET_CONFIG/GET_CONFIG` IPC、`/api/settings` 本地路由。
- `zn-ai` 当前没有 `launchAtStartup` 配置键,也没有任何 OS 级自启动应用逻辑。
- 这次复制不需要新增复杂的状态 hook、也不需要新增 preload 专用桥接;最小可行方案是复用现有设置存取链路,只补 `launchAtStartup` 配置模型和主进程副作用。
## 2. ClawX 现有实现拆解
### 2.1 渲染层 UI 结构
`ClawX/src/pages/Settings/index.tsx` 中,“开机自动启动”位于通用设置区块内,紧跟在语言设置后面,位于 Gateway 区块前:
- 主题按钮组
- 语言按钮组
- `launchAtStartup` 开关
- `Separator`
- Gateway 区块
对应 UI 代码位置:
- `ClawX/src/pages/Settings/index.tsx:528`
- `ClawX/src/pages/Settings/index.tsx:545`
交互特征:
- 左侧是标题和说明文案。
- 右侧是一个 `Switch`
- 没有额外保存按钮,属于“切换即保存”。
- 没有单独 loading/error 状态,也没有回滚提示。
### 2.2 渲染层状态链路
`ClawX` 渲染层把 `launchAtStartup` 放在 `settings` store 中统一管理:
- 字段定义:`ClawX/src/stores/settings.ts:19`
- 默认值:`ClawX/src/stores/settings.ts:72`
- 初始化从 `/api/settings` 拉取:`ClawX/src/stores/settings.ts:86`
- setter 里直接调用 `/api/settings/launchAtStartup``ClawX/src/stores/settings.ts:132`
实现特征:
- 先本地 `set({ launchAtStartup })`,再异步请求主进程。
- 请求失败时静默吞掉,没有回滚。
- 这和 `gatewayAutoStart``theme``language` 是同一类“轻量即改即存”模式。
### 2.3 i18n 文案
`ClawX` 使用 `settings.appearance` 下的两个键:
- `launchAtStartup`
- `launchAtStartupDesc`
对应位置:
- 中文:`ClawX/src/i18n/locales/zh/settings.json:12`
- 英文:`ClawX/src/i18n/locales/en/settings.json:12`
- 日文:`ClawX/src/i18n/locales/ja/settings.json:12`
### 2.4 主进程与 Host API 链路
`ClawX` 的主进程实现分成 4 层:
1. 持久化配置
- `ClawX/electron/utils/store.ts:24`
- `launchAtStartup` 被定义为 `AppSettings` 字段,默认值为 `false`
2. 设置路由
- `ClawX/electron/api/routes/settings.ts:27`
- `PUT /api/settings`
- `PUT /api/settings/launchAtStartup`
- `POST /api/settings/reset`
- 只要 patch/key 触达 `launchAtStartup`,都会执行 `syncLaunchAtStartupSettingFromStore()`
3. OS 级应用逻辑
- `ClawX/electron/main/launch-at-startup.ts:1`
- Windows/macOS`app.setLoginItemSettings({ openAtLogin, openAsHidden: false })`
- Linux写入或删除 `~/.config/autostart/clawx.desktop`
- 错误只记录日志,不向上抛出
4. 启动时同步
- `ClawX/electron/main/index.ts:298`
- 应用启动后会从 store 读取 `launchAtStartup`,再回放到操作系统
### 2.5 测试覆盖
`ClawX` 已经对 OS 级逻辑做了单元测试:
- `ClawX/tests/unit/launch-at-startup.test.ts`
覆盖点:
- Windows `setLoginItemSettings`
- macOS `setLoginItemSettings`
- Linux `.desktop` 文件创建/删除
- 非支持平台不抛异常
## 3. zn-ai 当前现状
### 3.1 已有可复用能力
`zn-ai` 已经具备以下基础:
- 通用设置 UI`zn-ai/src/pages/Setting/components/GeneralSettingsPanel.tsx`
- 设置页容器:`zn-ai/src/pages/Setting/index.tsx`
- 自定义开关组件:`zn-ai/src/pages/Setting/components/ToggleSwitch.tsx`
- 全局设置 store`zn-ai/src/stores/settings.ts`
- 配置持久化:`zn-ai/electron/service/config-service.ts`
- 通用设置本地路由:`zn-ai/electron/api/routes/settings.ts`
- 主进程初始化入口:`zn-ai/electron/main.ts`
### 3.2 关键差异
`ClawX` 相比,`zn-ai` 当前的关键差异有 5 个:
1. `launchAtStartup` 不在 `ConfigValueMap`
- `zn-ai/src/types/runtime.ts`
- `zn-ai/runtime-shared/lib/constants.ts`
- `zn-ai/runtime-shared/lib/types.ts`
2. `settingsStore` 只管理 `gatewayAutoStart`,没有 `launchAtStartup`
- `zn-ai/src/stores/settings.ts`
3. `config-service` 默认配置里没有 `launchAtStartup`
- `zn-ai/electron/service/config-service.ts`
4. 主进程没有 OS 级开机自启动服务
- `zn-ai/electron` 下目前不存在 `launch-at-startup` 模块
5. `zn-ai` 的设置主写路径不是 Host API而是 `SET_CONFIG` IPC
- `zn-ai/src/stores/settings.ts`
- `zn-ai/electron/service/config-service.ts`
这意味着:
- 不能只在 `/api/settings` 路由里补副作用。
- 必须覆盖到 `SET_CONFIG` 这条实际写入通路,否则 UI 开关会“写进配置但不生效到系统”。
## 4. 复制范围与非目标
### 4.1 本次复制范围
只复制 `ClawX` 的这一项能力:
- “开机自动启动”开关
- 配套说明文案
- 配置持久化
- 主进程 OS 级应用
- 应用启动时回放同步
### 4.2 明确不做的内容
这次不要把以下内容一起带进来:
- `startMinimized`
- `minimizeToTray`
- Gateway 自动启动
- 代理设置
- 日志目录打开
- 开发者模式
- Telemetry
原因:
- 这些不是 `ClawX`“开机自动启动”功能的必要组成。
- 一起迁移会把范围从“复制单一功能”扩大成“重新设计通用设置”。
## 5. zn-ai 的最小复制方案
### 5.1 UI 方案
`zn-ai/src/pages/Setting/components/GeneralSettingsPanel.tsx` 中,把新行插在语言设置后面:
- 保持和现有设置页一致的 `border-b` 行布局
- 左侧:标题 + 描述
- 右侧:复用 `ToggleSwitch`
建议结构:
1. 主题设置
2. 语言设置
3. 开机自动启动
4. Gateway
5. 更新
说明:
- 不需要新建卡片。
- 不需要新建 section header。
- 不需要新建独立 hook。
- 这项功能足够简单,沿用 `themeMode/language` 的 props 传递模式即可。
### 5.2 状态与设置层方案
推荐在 `zn-ai/src/stores/settings.ts` 中新增:
- `launchAtStartup: boolean`
- `updateLaunchAtStartup(launchAtStartup: boolean, persist = true)`
并在 `SettingsState``createInitialState()``hydrate()` 中补齐:
- 读取 `CONFIG_KEYS.LAUNCH_AT_STARTUP`
- 默认值 `false`
`GeneralSettingsPanel` 通过 props 收到:
- `launchAtStartup`
- `onLaunchAtStartupChange`
`Setting/index.tsx` 负责从 `useSettingsStore` 取值并透传。
### 5.3 配置模型方案
需要同时修改以下位置,保证 key 一致:
- `zn-ai/runtime-shared/lib/constants.ts`
- `zn-ai/runtime-shared/lib/types.ts`
- `zn-ai/src/types/runtime.ts`
- `zn-ai/electron/service/config-service.ts`
建议新增 key
- `launchAtStartup`
默认值建议:
- `false`
原因:
-`ClawX` 保持一致。
- 对桌面应用更保守,避免首次启动时直接注册系统自启动。
### 5.4 主进程方案
建议新增模块:
- `zn-ai/electron/service/launch-at-startup.ts`
职责直接对齐 `ClawX`,但把应用标识替换为 `zn-ai` 当前产品信息:
- Windows/macOS
- `app.setLoginItemSettings({ openAtLogin: enabled, openAsHidden: false })`
- Linux
- 写入或删除 `~/.config/autostart/*.desktop`
- 不能直接照搬 `clawx.desktop`
- `Name``Comment`、桌面文件名需要改成 zn-ai 当前产品名
建议暴露两个函数:
- `applyLaunchAtStartupSetting(enabled: boolean)`
- `syncLaunchAtStartupSettingFromStore()`
### 5.5 副作用挂载位置
这是本次复制里最关键的实现点。
因为 `zn-ai` 当前 renderer 主要通过 `SET_CONFIG` IPC 写设置,所以副作用至少要覆盖两条路径:
1. `SET_CONFIG` / `UPDATE_CONFIG`
- 位置:`zn-ai/electron/service/config-service.ts`
- 当 key 或 patch 触达 `launchAtStartup` 时,调用 `applyLaunchAtStartupSetting(...)`
2. 应用启动回放
- 位置:`zn-ai/electron/main.ts`
- `await configManager.init()` 之后调用 `syncLaunchAtStartupSettingFromStore()`
一致性建议:
- `zn-ai/electron/api/routes/settings.ts` 也补齐同样的副作用。
- 虽然当前 UI 主通路不是走这个 route但本地 Host API 应该与 IPC 行为一致。
## 6. 文件级改动清单
### 6.1 渲染层
- `zn-ai/src/pages/Setting/components/GeneralSettingsPanel.tsx`
- `zn-ai/src/pages/Setting/index.tsx`
- `zn-ai/src/stores/settings.ts`
- `zn-ai/src/i18n/messages.ts`
- `zn-ai/src/types/runtime.ts`
### 6.2 共享常量与类型
- `zn-ai/runtime-shared/lib/constants.ts`
- `zn-ai/runtime-shared/lib/types.ts`
### 6.3 主进程
- `zn-ai/electron/service/config-service.ts`
- `zn-ai/electron/service/launch-at-startup.ts`(新增)
- `zn-ai/electron/api/routes/settings.ts`
- `zn-ai/electron/main.ts`
### 6.4 测试
- `zn-ai/tests/launch-at-startup.test.ts`(建议新增)
## 7. 关键风险与处理建议
### 7.1 双写路径风险
风险:
- `SET_CONFIG` IPC 和 `/api/settings` route 都能改配置。
- 如果只给其中一条路径挂副作用,会出现“配置值正确但系统登录项没同步”的假成功。
处理:
- 两条路径都挂同一个 helper。
### 7.2 Linux 桌面文件元数据风险
风险:
- 直接复制 `ClawX``clawx.desktop``Name=ClawX` 会导致 Linux 桌面环境识别错误。
处理:
- 使用 zn-ai 当前产品名、可执行路径和桌面文件名。
- 优先通过 `app.getName()` / `process.execPath` 生成,而不是写死 ClawX 文案。
### 7.3 产品名文案不一致风险
风险:
- `package.json``productName``NIANXX`,但前端文案里大量使用 `ZN-AI`
处理:
- 本次设置说明文案优先使用“应用”或“系统登录后自动启动”这种泛化表达。
- 不在这次迁移里额外引入品牌命名统一改造。
### 7.4 静默失败体验风险
风险:
- `ClawX` 的写法对失败是静默吞掉,用户可能看不出 OS 级注册失败。
处理:
- 第一版可以保持与 `ClawX` 相同的轻量体验。
- 如果后续需要提高可观测性,再补 toast 或错误文案,但这不属于这次最小复制范围。
## 8. 推荐实施顺序
### Phase 1主进程能力补齐
1. 新增 `launchAtStartup` config key
2. 新增 `launch-at-startup` 服务
3.`config-service``/api/settings` 中挂副作用
4.`electron/main.ts` 启动时回放同步
### Phase 2渲染层接入
1. `settingsStore` 增加 `launchAtStartup`
2. `Setting/index.tsx` 透传 prop
3. `GeneralSettingsPanel.tsx` 在语言设置后插入 UI
4. `messages.ts` 补三语文案
### Phase 3验证
1. `typecheck`
2. `launch-at-startup` 单元测试
3. 手动验证设置页切换
4. 手动验证 Windows/macOS/Linux 的系统登录项行为
## 9. 最小测试集合
建议至少覆盖以下 4 类验证:
1. 单元测试
- Windows/macOS 调用 `app.setLoginItemSettings`
- Linux `.desktop` 创建/删除
2. 配置链路测试
- 改写 `launchAtStartup` 后,`configManager` 中值已更新
3. 渲染层回归
- 设置页中开关显示在语言设置后面
- 开关值能和 store 状态联动
4. 启动同步验证
- 应用启动后能读取持久化值并重新应用 OS 级自启动
## 10. sub-agent 估算与分工
### 10.1 推荐数量
推荐 `3` 个 sub-agent。
理由:
- 这次复制的改动面天然分成“渲染层”“配置/状态链路”“主进程 OS 级服务”三块。
- 三块之间耦合度低,适合并行推进。
- 再往上拆会让协同成本高于收益。
### 10.2 分工建议
#### Worker 1渲染层与 i18n
负责文件:
- `zn-ai/src/pages/Setting/components/GeneralSettingsPanel.tsx`
- `zn-ai/src/pages/Setting/index.tsx`
- `zn-ai/src/i18n/messages.ts`
职责:
- 在语言设置后插入 UI
- 接入 `launchAtStartup` prop
- 补齐中英日文案
- 确保视觉风格与现有设置页一致
#### Worker 2设置模型与配置链路
负责文件:
- `zn-ai/src/stores/settings.ts`
- `zn-ai/src/types/runtime.ts`
- `zn-ai/runtime-shared/lib/constants.ts`
- `zn-ai/runtime-shared/lib/types.ts`
职责:
- 新增 `launchAtStartup` 配置键和类型
- 在 store 中完成读取、更新、对外导出
- 保证 renderer 能通过现有设置链路读写该值
#### Worker 3主进程自启动服务与测试
负责文件:
- `zn-ai/electron/service/launch-at-startup.ts`
- `zn-ai/electron/service/config-service.ts`
- `zn-ai/electron/api/routes/settings.ts`
- `zn-ai/electron/main.ts`
- `zn-ai/tests/launch-at-startup.test.ts`
职责:
- 实现跨平台 OS 级自启动逻辑
- 把副作用挂到配置写入与启动同步节点
- 补齐最小单元测试
## 11. 最终建议
这次复制应严格控制在“ClawX 的 launchAtStartup 单功能迁移”范围内推进。
建议落地原则:
- UI 只加一行,不做新的设置分组。
- 状态层只加一个布尔配置,不新建复杂 hook。
- 主进程只加一个独立服务,不顺手扩散到别的系统设置功能。
- 测试优先覆盖 OS 级副作用,而不是先写大量 UI 测试。
按这个方案推进,能以最小代价把 `ClawX` 的成熟能力复制到 `zn-ai`,同时避免出现“只做了开关外观、没有真正接到系统登录项”的伪完成状态。