chore: initialize qiming workspace repository

This commit is contained in:
Codex
2026-05-29 14:22:48 +08:00
commit bfd67a0f2c
10750 changed files with 1885711 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
# 客户端依赖(服务)安装、升级与启动流程
> 本文档梳理 Electron 客户端应用**依赖安装**(初始化 / 手动)、**升级**、**启动时同步**以及**安装或升级后的服务停止与重启**全流程,便于维护与排查。
---
## 1. 概述
- **必需依赖**:由 `SETUP_REQUIRED_DEPENDENCIES` 定义,不随应用打包,需在「初始化」或「依赖 Tab」中安装到 `~/.qimingclaw/`(或项目配置的数据目录)下的 `node_modules`
- **版本判定**:以**当前已真实安装的版本**为准;用户可在依赖 Tab 下手动升级,已安装版本 ≥ 配置的 `installVersion` 即视为就绪,**不降级**。
- **安装/升级后**:在主界面下(含重装流程和依赖 Tab依赖安装或升级成功后会调用 `services.restartAll()` 重启所有服务,使新二进制生效。初始化向导中的依赖安装不触发重启(此时服务尚未启动,向导完成后由自动重连流程启动服务)。
---
## 2. 必需依赖列表SETUP_REQUIRED_DEPENDENCIES
| 名称 | 显示名 | 类型 | 说明 | 固定版本(installVersion) |
|------|--------|------|------|--------------------------|
| uv | uv | bundled | Python 包管理器(已集成) | minVersion: 0.5.0 |
| pnpm | pnpm 包管理器 | npm-local | Node 包管理器 | 10.30.3 |
| qiming-file-server | 文件服务 | npm-local | 工作目录文件远程管理 | 1.2.2 |
| qimingcode | Agent 引擎 | bundled | 应用内集成 Agent 执行引擎 | 1.1.68 |
| qiming-mcp-stdio-proxy | MCP 服务 | npm-local | MCP 协议聚合代理 | 1.4.6 |
| claude-code-acp-ts | ACP 协议 | npm-local | 引擎统一适配 | 0.16.1 |
- **配置位置**`src/main/services/system/dependencies.ts` 中的 `SETUP_REQUIRED_DEPENDENCIES`
- **检测**`checkAllDependencies()` 仅检查上述列表,返回每项状态:`installed` | `bundled` | `missing` | `outdated` | `error`
---
## 3. 依赖状态与版本判定
- **installed / bundled**:已就绪,无需操作。
- **missing**:未安装,需要安装。
- **outdated**:已安装但当前版本 < 配置的 `installVersion`,可升级;**不强制**进入全屏依赖安装(用户可在依赖 Tab 自行升级)。
- **error**:检测或安装过程出错。
**版本比较约定**
- 以**当前已安装版本**与配置的 `installVersion` 比较。
- 仅当「未安装」或「已装版本 < installVersion」时标记为需安装/升级;已装 ≥ 目标则视为已就绪,不降级。
- 实现见 `dependencies.ts``checkAllDependencies``compareVersions(installed, target)` 逻辑。
---
## 4. 初始化安装(首次 / 向导内)
### 4.1 入口与流程
- **入口**:应用启动后若 `setupService.isSetupCompleted()` 为 false渲染**初始化向导**`SetupWizard`)。
- **向导阶段 1**:依赖检测与安装(`SetupDependencies`)。
- 调用 `dependencies.checkAll()`,若有任一项非 `installed`/`bundled`(包括 `outdated`),则进入依赖安装 UI。
- **注意**:向导内 `outdated` 也会触发安装阶段(确保首次设置时所有依赖都是最新),而主界面下 `outdated` 不触发全屏重装(见 section 5.1)。
- 先检查系统依赖(如 uv若缺失则提示并阻塞。
- 对 npm-local 等可安装项自动或手动安装,全部就绪后进入下一步。
- **完成回调**`SetupDependencies``onComplete``SetupWizard.handleDepsComplete` 处理:置 `dependenciesReady = true`然后进入「基础设置」步骤或快捷初始化Quick Init
### 4.2 与 Quick Init 的关系
- 若依赖已全部就绪且存在快捷初始化配置,会优先走 Quick Init不再重复安装依赖。
- 依赖步骤**不可跳过**:必须先完成依赖检测/安装,再进入基础设置与登录。
---
## 5. 主界面下「必需依赖缺失」触发的重装流程
### 5.1 触发条件
- 用户已进入主界面(`isSetupComplete === true`)。
- 应用在进入主界面后执行一次 `dependencies.checkAll()`
- **仅当**存在状态为 `missing``error` 的必需依赖时,置 `needsRequiredDepsReinstall = true`
- **outdated 不触发**:已安装但版本低于配置时,不强制全屏依赖安装,用户可在依赖 Tab 自行升级。
### 5.2 流程
1. 渲染层:`needsRequiredDepsReinstall === true` 时,全屏展示 `SetupDependencies`(与向导内为同一组件)。
2. 用户完成依赖安装后,`onComplete` 被调用:
-`setNeedsRequiredDepsReinstall(false)`,回到主界面。
- 再调用 `restartAllServices()`(内部先停后启),使新依赖生效。
3. 不改变 `isSetupComplete`,不重新走向导的账号登录等步骤。
### 5.3 涉及代码
- `App.tsx``needsRequiredDepsReinstall` 状态、`checkRequiredDeps``useEffect`、全屏 `SetupDependencies``onComplete``restartAllServices()`
---
## 6. 依赖 Tab 下手动安装 / 升级
### 6.1 入口
- 主界面 → 依赖 Tab`DependenciesPage`)。
- 可对单项点击「安装」/「升级」,或使用「全部安装」/「全部升级」/「安装并升级」。
### 6.2 行为
- **单项**:调用 `dependencies.installPackage(name, options?)`,可选 `options.version`(如 `installVersion`);成功后调用 `restartServicesAfterDepChange()`
- **批量**:遍历需安装/升级的依赖依次安装;若有任意一项成功,则调用 `restartServicesAfterDepChange()`
- **restartServicesAfterDepChange**:内部调用 `services.restartAll()`(主进程内先停后启),并提示「正在重启服务…」「服务已重启」或失败提示。
### 6.3 版本与文案
- 以当前已安装版本为准;`outdated` 时按钮为「升级」,否则为「安装」。
- 批量时按缺失/过期组合显示「全部安装」「全部升级」或「安装并升级」;完成提示区分「依赖安装完成」「依赖升级完成」「依赖安装并升级完成」。
---
## 7. 应用启动时的依赖同步syncInitDependencies
- **目的**:应用升级后,若配置中的 `installVersion` 或应用版本发生变化,将依赖同步到新版本。
- **触发**:主进程启动任务(`bootstrap/startup.ts`)中,通过 `getInitDepsState()` 读取上次同步状态,与当前 `app.getVersion()` 及各包 `installVersion` 逐一比较。满足以下任一条件即触发 `syncInitDependencies()`
- 应用版本(`appVersion`)与上次记录不同(含首次无记录);
- 任一包的 `installVersion` 与上次记录的对应值不同(含上次无该包记录)。
- **行为**:对 `SETUP_REQUIRED_DEPENDENCIES` 中带 `installVersion` 的 npm-local 包,若未安装或已装版本低于配置,则安装到指定版本,并写回 `~/.qimingclaw/.init-deps-state.json`(或当前数据目录下的同名文件)。
- **不降级**:已安装版本 ≥ `installVersion` 的包不会被执行安装,避免覆盖用户手动升级的更高版本。
---
## 8. 安装或升级后的服务停止与重启
以下任一场景在「依赖安装或升级成功」后,都会执行**先停止再重启**所有相关服务,使新二进制生效:
| 场景 | 位置 | 行为 |
|------|------|------|
| 主界面重装依赖完成 | `App.tsx` 全屏 `SetupDependencies``onComplete` | `setNeedsRequiredDepsReinstall(false)` 后调用 `restartAllServices()`(即 `services.restartAll()` |
| 依赖 Tab 单项安装/升级成功 | `DependenciesPage.handleInstallSingleDep` | 调用 `restartServicesAfterDepChange()``services.restartAll()` |
| 依赖 Tab 批量安装/升级且至少成功一项 | `DependenciesPage.handleInstallAllDeps` | 同上 `restartServicesAfterDepChange()` |
- **restartAll**:主进程 `processHandlers.ts``services:restartAll` IPC handler 的实现会先停止 Agent、ComputerServer、FileServer、Lanproxy**不停 MCP**),再按顺序启动 MCP → Agent → ComputerServer → FileServer → Lanproxy。MCP 在 restartAll 中只做 start/verify不先停。
- **stopAll**:主进程 `processHandlers.ts``services:stopAll` IPC handler 会停止所有服务**包括 MCP**。
- **用户登出**:渲染进程 `ClientPage.handleLogout` 在停止 agent/fileServer/lanproxy/mcp 后,会单独调用 `computerServer.stop()`,避免登出后进程残留导致端口冲突;详见 [认证机制与 SavedKey 生命周期](./auth-savedkey-lifecycle.md#退出登录)。
- **serviceManager.ts**`serviceManager.restartAllServices()` 是另一套实现(供 `main.ts` 内部和 Tray 菜单使用),行为与 IPC `restartAll` 略有不同:会先停 MCP 再启动,且不包含 ComputerServer。渲染进程通过 `window.electronAPI.services.restartAll()` 调用的是 `processHandlers.ts` 中的 IPC handler 版本。
- **无需单独 stopAll**`restartAll` 内部已包含停止逻辑Agent / ComputerServer / FileServer / Lanproxy若需停止所有服务含 MCP且不重启可调用 `services.stopAll()`
---
## 9. 涉及文件与入口汇总
| 类型 | 路径 / 说明 |
|------|------------------|
| 依赖配置与检测 | `src/main/services/system/dependencies.ts``SETUP_REQUIRED_DEPENDENCIES``checkAllDependencies``installNpmPackage``installMissingDependencies``syncInitDependencies``compareVersions` |
| 启动同步 | `src/main/bootstrap/startup.ts`:启动后根据 `getInitDepsState` 与版本比较调用 `syncInitDependencies` |
| IPC | `src/main/ipc/dependencyHandlers.ts``dependencies:checkAll``dependencies:installPackage` 等;`processHandlers.ts``services:stopAll``services:restartAll` |
| 服务管理器 | `src/main/window/serviceManager.ts``restartAllServices``stopAllServices`(供 main.ts / Tray 使用,行为与 IPC handler 略有不同,见 section 8 |
| 初始化向导 | `src/renderer/components/setup/SetupWizard.tsx``SetupDependencies.tsx`:向导内依赖步骤与完成回调 |
| 主界面重装 | `src/renderer/App.tsx``needsRequiredDepsReinstall`、全屏 `SetupDependencies``checkRequiredDeps``restartAllServices` |
| 依赖 Tab | `src/renderer/components/pages/DependenciesPage.tsx`:单项/批量安装与 `restartServicesAfterDepChange` |
| 持久化 | `~/.qimingclaw/.init-deps-state.json`(或当前数据目录):应用版本与各包上次同步版本,读写在 `dependencies.ts``getInitDepsState` / `setInitDepsState` |
---
## 10. 相关文档
- [依赖版本固定与安装/升级行为](./dependency-version-pinning.md) — installVersion、同步、文案与不降级约定。
- [Quick Init](./QUICK-INIT.md) — 快捷初始化与依赖步骤不可跳过的约定。