--- version: 1.0 last-updated: 2026-03-04 status: stable --- # Quick Init — 快捷初始化 > 通过预置 `~/.qimingclaw/qimingclaw.json` 或环境变量,跳过手动向导完成客户端初始化。 --- ## 概述 客户端初始化向导需要用户手动填写配置(端口、工作区)和登录(动态认证码)。Quick Init 支持通过预置配置文件或环境变量快速完成初始化——文件中包含 `savedKey`(已完成过登录的设备密钥),直接调 reg 接口(password 传空字符串),跳过动态码流程。 **关键约束**:即使有快捷配置,依赖安装步骤不能跳过,必须先完成依赖检测/安装。qiming-file-server、qiming-mcp-stdio-proxy、qimingcode、claude-code-acp-ts 四包均不随包集成,通过 SETUP_REQUIRED_DEPENDENCIES 的 installVersion 在 ~/.qimingclaw 初始化安装,并参与升级后的 syncInitDependencies。 --- ## 配置来源与优先级 ``` qimingclaw.json (quickInit scope) → 环境变量 → 无配置(走正常向导) ``` Per-field 合并:每个字段独立按 JSON > 环境变量 > 默认值 取值。 ### qimingclaw.json 文件路径:`~/.qimingclaw/qimingclaw.json` 使用 `quickInit` scope,便于将来在同一文件中增加其他配置。 ```json { "quickInit": { "enabled": true, "serverHost": "https://agent.qiming.com", "savedKey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "username": "user@example.com", "agentPort": 60001, "fileServerPort": 60000, "workspaceDir": "/home/user/workspace" } } ``` 最简写法(只需必填字段,其余走默认值): ```json { "quickInit": { "serverHost": "https://agent.qiming.com", "savedKey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } } ``` 设为 `"enabled": false` 可禁用快捷初始化(同时阻断环境变量回退)。 ### 环境变量 | 环境变量 | 对应字段 | 必填 | |---|---|---| | `QIMING_SERVER_HOST` | serverHost | 是 | | `QIMING_SAVED_KEY` | savedKey | 是 | | `QIMING_USER_NAME` | username | 否 | | `QIMING_AGENT_PORT` | agentPort | 否 | | `QIMING_FILE_SERVER_PORT` | fileServerPort | 否 | | `QIMING_WORKSPACE_DIR` | workspaceDir | 否 | ### 字段说明 | 字段 | 类型 | 必填 | 默认值 | 说明 | |---|---|---|---|---| | `serverHost` | string | **是** | - | 服务域名 | | `savedKey` | string | **是** | - | 设备密钥(已注册) | | `username` | string | 否 | `''` | 登录用户名 | | `agentPort` | number | 否 | `60001` | Agent 端口 | | `fileServerPort` | number | 否 | `60000` | 文件服务端口 | | `workspaceDir` | string | 否 | `~/.qimingclaw/workspace` | 工作区目录 | | `enabled` | boolean | 否 | `true` | 是否启用(仅 JSON) | --- ## 架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ Main Process │ │ │ │ bootstrap/quickInit.ts │ │ ┌────────────────────────────────────────────────────┐ │ │ │ readQuickInitConfig() │ │ │ │ 1. 读取 ~/.qimingclaw/qimingclaw.json → quickInit │ │ │ │ 2. 读取 QIMING_* 环境变量 │ │ │ │ 3. Per-field 合并: JSON > env > default │ │ │ │ 4. 校验 serverHost + savedKey 必填 │ │ │ │ 5. 缓存结果(每次启动只读一次) │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ │ IPC: quickInit:getConfig │ │ │ │ ├─────────────────────────┼───────────────────────────────────┤ │ ▼ │ │ Renderer Process │ │ │ │ App.tsx (每次启动) │ │ ┌────────────────────────────────────────────────────┐ │ │ │ checkSetup: │ │ │ │ setup 已完成? │ │ │ │ ├─ 是 → quickInit.getConfig() │ │ │ │ │ ├─ 有配置 → applyQuickInitToDb() │ │ │ │ │ │ (覆盖 step1 + savedKey + 静默注册) │ │ │ │ │ └─ 无配置 → 使用 DB 已有值 │ │ │ │ │ → 进入主界面 │ │ │ │ └─ 否 → 渲染 SetupWizard │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ SetupWizard.tsx (仅首次 setup) │ │ ┌────────────────────────────────────────────────────┐ │ │ │ 启动 → 依赖检测 │ │ │ │ │ │ │ │ │ ├─ 依赖就绪 + setup 未完成 │ │ │ │ │ └─ quickInit.getConfig() │ │ │ │ │ ├─ 有配置 → performQuickInit() │ │ │ │ │ └─ 无配置 → 正常向导 │ │ │ │ │ │ │ │ │ └─ 依赖缺失 → 安装流程 │ │ │ │ └─ handleDepsComplete │ │ │ │ └─ quickInit.getConfig() │ │ │ │ ├─ 有配置 → performQuickInit() │ │ │ │ └─ 无配置 → 正常向导 │ │ │ └────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` │ │ └─ 无配置 → 正常向导 │ │ │ └────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 启动时序 ``` App 启动 │ ├─ Main: 注册 quickInit:getConfig IPC handler │ └─ Renderer: App.tsx checkSetup │ └─ setupService.isSetupCompleted() │ ├─ true (setup 已完成) │ └─ ✅ quickInit.getConfig() │ ├─ 有配置 → applyQuickInitToDb() │ │ 覆盖 step1 config + savedKey + 静默 loginAndRegister │ └─ 无配置 → 使用 DB 已有值 │ → 进入主界面 → autoReconnect → 启动服务 │ └─ false (setup 未完成) → 渲染 SetupWizard │ └─ useEffect init() │ ├─ 依赖全部就绪 │ └─ ✅ quickInit.getConfig() │ ├─ 有配置 → performQuickInit() → 自动完成 │ └─ 无配置 → 正常向导 step 1/2 │ └─ 依赖缺失 → 安装流程 └─ 安装完成 handleDepsComplete └─ ✅ quickInit.getConfig() ``` **每次启动都读取配置**:无论 setup 是否已完成,都优先读取 `qimingclaw.json` / 环境变量。有配置 → 覆盖 DB;无配置 → 使用 DB 已有值。 --- ## applyQuickInitToDb 流程(setup 已完成时) App.tsx 中 setup 已完成时静默更新 DB,确保后续 autoReconnect / 服务启动使用最新值。 ``` applyQuickInitToDb(config) │ ├─ 1. 覆盖 Step1 配置(serverHost, agentPort, fileServerPort, workspaceDir) │ ├─ 2. 覆盖 savedKey(全局 + 域名级) │ └─ 3. 静默 loginAndRegister(username, '', { domain }) └─ 失败不阻塞启动(console.warn,已有 auth 信息仍可用) ``` ## performQuickInit 流程(setup 未完成时) ``` performQuickInit(config) │ ├─ 1. 保存 Step1 配置(serverHost, agentPort, fileServerPort, workspaceDir) │ ├─ 2. 预存 savedKey 到 SQLite │ ├─ AUTH_KEYS.SAVED_KEY → 全局 savedKey │ └─ AUTH_KEYS.SAVED_KEYS_PREFIX + domain_username → 域名级 savedKey │ ├─ 3. loginAndRegister(username, '', { domain }) │ └─ password 传空字符串,函数内部从 DB 取 savedKey 附加到 reg 请求 │ ├─ 4. completeStep2() + completeSetup() │ └─ 5. onComplete() → 进入主界面 │ └─ [失败] catch → console.error → 回退到手动向导(step1 可能已保存) ``` 失败兜底:quick init 任何步骤失败 → 回退到正常向导流程。UI 显示 `` + "正在自动配置..."。 --- ## 文件清单 ### 新建 | 文件 | 说明 | |---|---| | `src/shared/types/quickInit.ts` | `QuickInitConfig` 接口 + `hasRequiredQuickInitFields()` 校验 | | `src/main/bootstrap/quickInit.ts` | Main 进程读取 JSON / 环境变量,per-field 合并,缓存 | | `src/shared/types/quickInit.test.ts` | 类型校验测试(10 cases) | | `src/main/bootstrap/quickInit.test.ts` | 读取逻辑测试(19 cases) | ### 修改 | 文件 | 改动 | |---|---| | `src/main/ipc/settingsHandlers.ts` | 添加 `quickInit:getConfig` IPC handler | | `src/preload/index.ts` | 暴露 `quickInit.getConfig()` 给 Renderer | | `src/shared/types/electron.d.ts` | 添加 `QuickInitAPI` 接口 + `ElectronAPI.quickInit` | | `src/renderer/App.tsx` | setup 已完成时读取配置 → `applyQuickInitToDb()` 覆盖 DB | | `src/renderer/components/setup/SetupWizard.tsx` | setup 未完成时检测配置 → `performQuickInit()` 自动完成流程 | --- ## 复用的现有函数 | 函数 | 文件 | 用途 | |---|---|---| | `loginAndRegister()` | `renderer/services/core/auth.ts` | 调用 reg API,savedKey 由函数内部从 DB 读取 | | `normalizeServerHost()` | `renderer/services/core/auth.ts` | 域名标准化(加 https 前缀、去尾 /) | | `setupService.saveStep1Config()` | `renderer/services/core/setup.ts` | 保存 step1 配置并更新 state | | `setupService.completeStep2()` | `renderer/services/core/setup.ts` | 标记 step2 完成 | | `setupService.completeSetup()` | `renderer/services/core/setup.ts` | 标记整体完成 | | `APP_DATA_DIR_NAME` | `shared/constants.ts` | `.qimingclaw` 目录名 | | `DEFAULT_AGENT_RUNNER_PORT` | `shared/constants.ts` | `60001` | | `DEFAULT_FILE_SERVER_PORT` | `shared/constants.ts` | `60000` | --- ## 测试 29 个测试用例,覆盖以下场景: ### hasRequiredQuickInitFields(10 cases) - 必填字段齐全 / 全字段齐全 - 缺 serverHost / 缺 savedKey / 空字符串 - null / undefined / 非 object / 字段类型错误 ### readQuickInitConfig(19 cases) | 分类 | 场景 | |---|---| | 无配置 | 无 JSON + 无 env → null | | JSON | 全字段 / 仅必填(填默认值) / enabled:false / enabled:true / 无 quickInit scope / 缺必填 / 格式错误 | | 环境变量 | 全字段 / 仅必填 / 缺一个必填 → null / 无效端口回退默认 | | 优先级 | JSON > env / env 补充 JSON 缺失字段 / 都缺省走 default | | enabled:false | 阻断环境变量回退 | | 缓存 | 二次调用同引用 / null 也缓存 | 运行: ```bash npx vitest run src/shared/types/quickInit.test.ts src/main/bootstrap/quickInit.test.ts ``` --- ## 验证清单 | # | 场景 | 预期 | |---|---|---| | 1 | 无 JSON + 无 env | 正常向导流程不受影响 | | 2 | JSON 缺必填字段 | 控制台 warn 日志,走正常向导 | | 3 | JSON `enabled: false` | 跳过 quick init,不回退 env | | 4 | 有效 JSON + 无效 savedKey | 依赖安装正常 → quick init 调 reg 失败 → 回退手动向导(step1 已预填) | | 5 | 有效 JSON + 有效 savedKey | 依赖安装 → 自动配置 spinner → 直接进入主界面 | | 6 | 仅 env QIMING_SERVER_HOST + QIMING_SAVED_KEY | 同 #5,其余走默认值 | | 7 | JSON serverHost + env QIMING_AGENT_PORT | JSON 字段优先,env 补充缺失字段 | | 8 | `npm run electron:dev` 开发模式 | 正常运行 | --- *Last updated: 2026-03-04*