# AgentDock 技术架构方案 版本:1.0 · 日期:2026-08-24 · 角色:总工 · 状态:方案期交付 依据:`PRODUCT-REQUIREMENTS.md` v0.1 + `agent-cli-survey-2026-08-24.md` 范围:首批 14 适配器设计;第二批 4 个仅预留扩展点,不实现 --- ## 0. 一句话定位与竞品差异 **AgentDock** = 本机桌面「Agent CLI 生命周期管家」:发现 → 环境检查 → 安装/识别 → 中文配置 → 授权 → 更新/卸载 → 诊断。 | 维度 | AgentDock | 智谱 ZCode(竞品) | |---|---|---| | 形态 | 纯本地桌面管理器 | GUI 开发环境 + 管理 | | 模型绑定 | **渠道中立**,不绑任何厂商套餐 | 捆绑 GLM Coding Plan | | 管理对象 | 官方渠道安装的第三方 CLI | 自家 Harness + 切换多工具 | | 数据与密钥 | 全本地;密钥进系统钥匙串 | 订阅与账号体系偏云端 | | 核心卖点 | 中文化、离线可用、可扩展适配器 | 可视化切换 + 自家模型 | 差异化口号(给总管翻译老板用):**「不卖模型、不绑套餐——只管帮你把各家官方 CLI 装好、配好、查清楚。」** --- ## 1. 技术栈清单(以 PRD 4.2 为基线) | 层 | 选型 | 理由 | 以后怎么扩展 | |---|---|---|---| | 桌面壳 | **Tauri 2** | 体积小、Rust 本机能力天然契合;比 Electron 更适合「管本机命令/文件」 | 二期加 macOS / ARM 时复用同一壳 | | UI | **React 19 + TypeScript + Vite** | 生态熟、施工员上手快;与赛博风组件库兼容 | 可加路由/状态库,不换栈 | | 样式 | **CSS Variables 设计 Token + 少量 Tailwind(或纯 CSS Modules)** | Token 对接美术师规范;避免硬编码颜色 | 主题切换 = 换 Token 集 | | 动效 | **Framer Motion(布局/页面)+ CSS `@property`/滤镜光效;重粒子用 Canvas 可选** | 可控帧率、易降级 | 高特效档可再加 WebGL | | 本机能力 | **Rust(Tauri commands + 独立 crate)** | 进程、PATH、文件原子写、密钥库、平台差异 | 能力以 IPC 契约暴露,UI 不直调 OS | | 适配器定义 | **版本化 YAML(主)+ JSON Schema 校验** | 人可读、可热更新目录;PRD 已示意 YAML | 远程目录更新可不发版 | | 本地状态 | **SQLite(`rusqlite` / `sqlx`)** | 安装记录、诊断历史、备份索引;比散落 JSON 好查 | 导出仍可用 JSON | | 敏感信息 | **keyring crate** → Win Credential Manager / Linux Secret Service | 满足 PRD 4.2/8;禁止明文落盘 | 迁移仅钥匙串或用户重授权 | | 配置解析 | **toml / serde_json / serde_yaml**;Crush 用专用 `crushrc` 解析器 | 覆盖 14 家格式差异 | 新格式 = 新 `ConfigCodec` | | 包构建 | **tauri-cli + NSIS(Win)+ deb + AppImage(Ubuntu)** | 覆盖目标平台 | 二期可加 flatpak | | 自动更新 | **Tauri updater(签名校验)**;更新源仅官方 CDN | 离线核心功能不依赖更新 | 可关自动检查 | | 测试 | **Rust:cargo test;前端:Vitest;适配器:fixture 驱动** | 双平台 CI 矩阵 | 真机 smoke 人工/脚本 | ### 相对 PRD 的明确修正(仅 2 处) 1. **本地状态优先 SQLite,不用「纯原子 JSON」作主库**——诊断历史、备份索引、操作审计需要查询;配置文件本身仍原子写。 2. **适配器主格式定 YAML**——与 PRD 示例一致;运行时编译/校验为内部 JSON 表示,避免双源真相。 --- ## 2. 目录结构与模块边界 ```text agentdock/ ├── apps/ │ └── desktop/ # Tauri 2 应用入口 │ ├── src/ # React UI │ │ ├── pages/ # 总览 / 目录 / 我的CLI / 配置 / 备份 / 设置 │ │ ├── components/ │ │ ├── tokens/ # 对接美术师:颜色/字体/动效/光效变量 │ │ ├── hooks/ │ │ └── ipc/ # 类型化 invoke 封装(唯一前端→Rust 入口) │ ├── src-tauri/ │ │ ├── src/ │ │ │ ├── main.rs │ │ │ ├── commands/ # Tauri IPC 命令(薄层) │ │ │ └── lib.rs │ │ └── tauri.conf.json │ └── package.json ├── crates/ │ ├── agentdock-core/ # 编排:发现/安装/配置/授权/诊断流水线 │ ├── agentdock-adapter/ # schema 加载、版本校验、dry-run、执行器接口 │ ├── agentdock-platform/ # Win/Linux:PATH、权限提升探测、发行版识别 │ ├── agentdock-config/ # 原子写入、备份、多格式编解码 │ ├── agentdock-secrets/ # 系统密钥库封装 + 脱敏 │ ├── agentdock-exec/ # 参数白名单、禁止 shell 拼接的进程执行 │ ├── agentdock-diag/ # 规则引擎 │ └── agentdock-store/ # SQLite schema 与仓库 ├── adapters/ # 版本化适配器 YAML(14 + 目录元数据) │ ├── catalog.yaml # 目录索引 │ ├── schema/ │ │ └── adapter.schema.json # JSON Schema(校验 YAML) │ └── tools/ │ ├── codex.yaml │ ├── claude-code.yaml │ ├── gemini.yaml │ ├── copilot.yaml │ ├── kimi.yaml │ ├── qwen.yaml │ ├── codebuddy.yaml │ ├── opencode.yaml │ ├── crush.yaml │ ├── goose.yaml │ ├── aider.yaml │ ├── cursor.yaml │ ├── cline.yaml │ └── warp.yaml ├── docs/ │ └── architecture.md # 本方案落仓后副本 └── tests/ ├── fixtures/ # 假 PATH、假配置文件、假 --version 输出 └── e2e/ # 可选:双平台 smoke 脚本 ``` ### 四层边界(施工员铁律) | 层 | 职责 | 禁止 | |---|---|---| | **界面层** | 渲染适配器数据、表单、确认对话框、赛博视觉 | 直接拼命令、读写密钥、解析配置格式 | | **本机能力层(Rust)** | IPC、编排、平台检测、执行、密钥、SQLite | 硬编码某 CLI 的特殊路径逻辑(应进适配器) | | **适配器层** | 声明安装/检测/配置/授权/诊断;提供 dry-run | 在 YAML 里写任意 shell 字符串 | | **状态存储** | SQLite 元数据 + 用户配置文件原子写 + 钥匙串 | 把 API Key 写入 SQLite/日志/备份默认项 | ### 模块关系(简图) ```text UI --invoke--> commands --→ core orchestrator ├→ adapter registry (YAML) ├→ platform (env detect) ├→ exec (safe spawn) ├→ config codecs + atomic IO ├→ secrets (keyring) ├→ diag engine └→ store (sqlite) ``` ### 关键 IPC 契约(示意,施工员按此生成 TS 类型) ```typescript // 均返回 Result;错误带 code + message_zh + raw(原始错误永不吞) detectEnv(): PlatformEnv listCatalog(): CatalogEntry[] detectCli(id: string): DetectResult previewAction(id, action, opts): DryRunPlan // 安装/更新/卸载/写配置/授权/修复 runAction(id, action, opts): ActionStream // 事件流:step/stdout/stderr/done readConfig(id): ConfigFormState writeConfig(id, patch): WriteResult authStatus(id): AuthStatus authorize(id, mode): AuthFlowHandle diagnose(id): DiagnosticReport listBackups() / createBackup() / restoreBackup(id, preview) ``` --- ## 3. 适配器 Schema(完整定义 + 14 工具渠道矩阵) ### 3.1 Schema 核心(在 PRD §6 上扩展) ```yaml # adapter.schema 关键字段(v1) id: string # 稳定 ID,如 codex name: string # 展示名 name_zh: string vendor: string adapter_version: semver license: string # 展示用;专有许可注明「仅官方渠道安装、不重打包」 platforms: windows: architectures: [x64] notes: string? # 如 Gemini 要求 Win11 24H2+ linux: distributions: [ubuntu] architectures: [x64] min_ubuntu: "22.04"? official: homepage: url docs: url allowed_hosts: [string] # 网络白名单(诊断/下载仅可访问) runtime_deps: # 依赖探测 - id: node | python | git | powershell | ... semver_range: ">=20" required_for: [install|run] install: preferred: channel_id # 默认渠道 channels: - id: npm | official_script | winget | choco | scoop | brew | apt | pypi_uv | github_release platforms: [windows|linux] # 命令必须是 argv 数组,禁止字符串拼接 command: [string, ...] # 脚本类:下载 URL 必须在 allowed_hosts;执行走专用 runner,不经 /bin/sh -c script: url: url? kind: powershell_irm | bash_pipe | ps1_file integrity: { sha256: hex }? # 有则强制校验 package: string? # npm/pypi 包名 elevate: never | if_needed | required elevate_reason_zh: string? post_checks: [detect] # 安装后自动检测 detect: executable: string # PATH 上的命令名;Cursor 为 agent version_args: [string] version_regex: string version_unconfirmed: bool? # 调研标注「文档未能确认」时 true,UI 显示「实测兜底」 path_hints: [string]? # 非 PATH 常见位置 update: method: npm_update | self_update_cmd | channel_reinstall | winget_upgrade | ... command: [string, ...]? uninstall: method: npm_uninstall | package_manager | manual_delete command: [string, ...]? keep_config_default: true authorization: modes: # 可多选 - mode: browser_oauth | device_code | api_key | local_tui command: [string, ...]? env_keys: [string]? # 写入钥匙串后注入的环境变量名 status_command: [string, ...]? # 如 codex login status notes_zh: string configuration: files: - path: string # 支持 ~ 与平台变量 format: toml | json | jsonc | yaml | env | crushrc scope: user | project | system environment: - key: string sensitive: bool maps_to_field: string fields: # 中文配置表单 - id: string label_zh: string help_zh: string required: bool sensitive: bool type: string | url | enum | bool storage: file | env | keyring # keyring 永不进普通备份 platforms: [windows|linux]? docs_url: url? diagnostics: - rule_id: string # 引用规则库或内联 documentation: quickstart_zh: string commands: [{ cmd, desc_zh }] updated_at: date risks_zh: [string] ``` ### 3.2 统一执行器接口(Rust trait) ```text AdapterExecutor: detect() -> DetectResult install(plan) / update / uninstall read_config() / write_config(patch) authorization_status() / authorize(mode) diagnose() -> Vec dry_run(action) -> DryRunPlan # 必须:命令 argv、权限、影响文件、回滚说明 ``` 所有 `command` 经 `agentdock-exec`:`Command::new(prog).args(args)`,**禁止** `cmd /C`、`sh -c`、管道字符串。官方「curl | bash」类安装:下载到临时文件 → SHA256(若有)→ 用明确解释器执行文件(PowerShell `-File` / `bash script.sh`),并在 UI 展示完整脚本来源。 ### 3.3 首批 14 CLI 安装渠道与设计依据(均来自调研底稿) | ID | 命令 | 首选安装(Win / Ubuntu) | 备选 | 配置格式 | 授权模式 | 备注(底稿依据) | |---|---|---|---|---|---|---| | `codex` | `codex` | Win: 官方 PS 脚本或 npm `@openai/codex`;Ubuntu: 官方脚本或 npm | brew、GitHub Releases | TOML `~/.codex/config.toml` | browser + device_code + api_key | `--version` 文档未列,`version_unconfirmed` | | `claude-code` | `claude` | Win: winget `Anthropic.ClaudeCode` 或 PS 脚本;Ubuntu: 官方脚本或 apt | npm(Node 22+) | JSON `~/.claude/settings.json` | browser + api_key | 专有许可:只引导官方安装 | | `gemini` | `gemini` | 双端 npm `@google/gemini-cli`(Node 20+) | brew | JSON `~/.gemini/settings.json` | browser + api_key + vertex | Win 官方要求 11 24H2+,适配器 notes 声明 | | `copilot` | `copilot` | Win: winget `GitHub.Copilot`(需 PS v6+)或 npm;Ubuntu: 脚本/npm/brew | — | JSON + env(`COPILOT_*`) | local_tui(`/login`) + PAT env | `--version` 未确认;需 Copilot 订阅 | | `kimi` | `kimi` | 官方 `code.kimi.com` 脚本(内装 uv + **PyPI `kimi-cli`**) | `uv tool install kimi-cli` | TOML `~/.kimi/config.toml` | browser + api_key | **禁止** npm 仿名包 `kimi-code` | | `qwen` | `qwen` | npm `@qwen-code/qwen-code`(Node 22+)或阿里 OSS 独立脚本 | brew | JSON `~/.qwen/settings.json` | **仅 api_key**(OAuth 已停) | `--version` 未确认 | | `codebuddy` | `codebuddy` | npm `@tencent-ai/codebuddy-code` | `codebuddy install stable` 原生线 | 经 `codebuddy config`(路径待实测) | browser(微信登录);api_key 未确认 | 双升级路径要分 channel | | `opencode` | `opencode` | Win: choco/scoop;Ubuntu: 官方脚本/npm | brew、Releases | JSON/jsonc `~/.config/opencode/opencode.json` | api_key + browser + device_code | 授权面最全之一 | | `crush` | `crush` | Win: winget `charmbracelet.crush`;Ubuntu: 官方 apt(GPG) | npm、scoop、Releases | **crushrc**(Bash 语法) | api_key(环境变量) | `--version` 未确认;FSL 许可展示说明 | | `goose` | `goose` | Win: 官方 `download_cli.ps1`;Ubuntu: 官方脚本 | brew、deb | YAML;Win 注意 `%APPDATA%\Block\goose\...` | api_key + 订阅 ACP | 密钥默认进系统钥匙串 | | `aider` | `aider` | 官方 `aider-install` / PS 脚本 / PyPI `aider-chat` | uv/pipx;**不推荐 brew** | YAML `.aider.conf.yml` | **仅 api_key** | 独立 Python 3.12 环境 | | `cursor` | `agent` | **仅官方脚本**(Win PS / Linux curl);**无 npm** | — | Cursor 账户体系 | browser(`agent login`) | 命令名是 `agent` 不是 cursor-agent | | `cline` | `cline` | npm `cline`(Node 22+) | nightly 通道 | JSON `~/.cline/data/settings/providers.json` | browser + api_key + 本地模型 | 密钥已用系统 keychain | | `warp` | `warp` | Win: 官方 agent-cli.ps1;Ubuntu: curl 脚本 | brew cask(Linux) | Warp 账户 / `WARP_API_KEY` | device_code + browser + api_key | 管 Agent CLI,不管 Warp 终端本体 | ### 3.4 第二批(暂缓,仅 catalog 占位 `status: watch`) `grok`、`amp`、`deepseek-dsh`、`plandex` —— schema 允许加载但不出现在默认「可安装」列表,或灰显「观察中」。 --- ## 4. 安全设计 ### 4.1 密钥库封装 | 平台 | 后端 | API | |---|---|---| | Windows | Credential Manager(via `keyring`) | `secrets::set(service, account, secret)` | | Linux | Secret Service / libsecret | 同上;无 daemon 时降级:**拒绝写入明文**,UI 提示安装 `gnome-keyring` | - `service` 固定前缀 `agentdock.`;`account` 为字段 id(如 `api_key`)。 - 读配置时:表单敏感字段只显示「已保存 / 未保存」,回显用遮罩;真实值仅在写回目标 CLI 时短暂注入。 - **禁止**:SQLite、普通备份、日志、崩溃报告、剪贴板默认复制密钥。 ### 4.2 命令执行边界 1. 仅执行适配器声明的 argv;用户输入只作为**已校验参数槽位**(枚举/路径/版本号),不做字符串拼接。 2. 默认禁止:管道、重定向、`$()`、反引号、`&&` 链、隐式脚本。 3. 工作目录限制在用户主目录或用户确认的项目根。 4. 下载:HTTPS + `allowed_hosts`;可选 SHA256;展示来源 URL。 5. 权限提升:`elevate: if_needed|required` 时弹窗说明 `elevate_reason_zh`;**应用本身不以管理员启动**。 6. 禁止远程网页驱动本机执行;禁止任意 URL 代理(防 SSRF)。 ### 4.3 日志脱敏规则 | 模式 | 处理 | |---|---| | `sk-` / `xai-` / `ghp_` / `gho_` / JWT 形态 | 替换为 `***REDACTED***` | | 适配器标记 `sensitive: true` 的 env/字段值 | 一律脱敏 | | 家目录绝对路径 | 可选折叠为 `~`(诊断导出前提示) | | 原始错误 | 保留结构,但过脱敏器后再落盘 | --- ## 5. 环境检测方案(Win 10/11 x64 · Ubuntu 22.04/24.04 x64) `PlatformEnv` 结构: ```text os: windows | linux os_version: ... arch: x64 | other(reject) distro?: string # 发行版名,如 ubuntu(Windows 为 None) distro_version?: string # 发行版版本,如 22.04(Wave 1 拆分:原 distro?: ubuntu + version) shells: powershell_version?, bash_available? runtimes: { node?, npm?, python?, uv?, git?, winget?, apt? } path_entries: [...] capabilities: { keyring: ok|missing, can_elevate: bool } ``` | 检测项 | Windows | Ubuntu | |---|---|---| | OS/版本 | `RtlGetVersion` / 注册表 | `/etc/os-release` | | PATH | 用户+系统 PATH 合并,注意商店别名 | `$PATH` + `~/.local/bin` 是否在内(Goose/Cursor 常见坑) | | Node/npm | `where node` + `node -v` | `command -v` + 版本 | | Python/uv | `py -0p` / `uv --version` | 同上 | | 包管理器 | winget / choco / scoop 可用性 | apt;可选 brew-on-linux | | PowerShell | 区分 Windows PowerShell 5 vs pwsh 6+(Copilot winget 依赖) | N/A | | 密钥库 | Credential Manager 可用性 | `secret-tool` / DBus Secret Service | 检测失败分类(对齐 FR-02):`not_installed` | `not_in_path` | `permission_denied` | `exec_failed` | `version_unparseable`。 Wave 1 已把 `permission_denied` 从一般执行失败中拆分为独立状态(`std::io::ErrorKind::PermissionDenied` 单独归类),`RuntimeInfo.status` 相应支持该值。 --- ## 6. 配置读写设计 ### 6.1 原子写入 + 自动备份 对任意目标文件 `F`: 1. 若 `F` 存在 → 复制到 `F.bak.`(及 SQLite 备份索引)。 2. 写入临时文件 `F.tmp.`。 3. `fsync` 后 `rename` 覆盖(Windows 用 `MoveFileEx` 替换语义)。 4. 失败则保留原文件与临时文件,UI 展示原始错误。 ### 6.2 多格式统一策略:`ConfigCodec` trait | format | 实现要点 | 代表 CLI | |---|---|---| | `toml` | `toml_edit` 保注释 | Codex、Kimi | | `json` / `jsonc` | jsonc 用 `jsonc-parser` 或 strip comments | Claude、Gemini、Qwen、OpenCode、Cline、Copilot | | `yaml` | serde_yaml | Goose、Aider | | `env` | KEY=VALUE 行;敏感键走钥匙串引用 | 多 CLI 辅助 | | `crushrc` | **专用解析器**:识别 Crush 内建赋值语句,不做任意 bash 执行;未知行保留原样 | Crush | 表单字段 `storage`: - `file` → Codec 读写 - `env` → 用户级环境变量(Win:用户环境;Linux:`~/.config/agentdock/env.d/*.sh` 并提示加入 shell,或仅会话注入说明) - `keyring` → 只写钥匙串;可选写入 CLI 期望的「env 变量名指针」到配置(如 Codex `env_key`) Goose:尊重其「密钥默认进系统钥匙串」——AgentDock 与之对齐,不把 Key 写入 `config.yaml`。 --- ## 7. 授权状态统一模型 ```text AuthStatus = authorized | unauthorized | unknown | possibly_expired AuthMode = browser_oauth | device_code | api_key | local_tui ``` | 模式 | AgentDock 行为 | |---|---| | `browser_oauth` | 启动适配器 login 命令;监听进程结束;可选检测本机打开浏览器;结果只存状态枚举 | | `device_code` | 弹出「设备码」面板展示 stdout 中的 user_code + verification_url(解析规则在适配器);不截获 token 明文到日志 | | `api_key` | 表单写入钥匙串;按 CLI 要求设置 env 或 `login --with-api-key`(stdin 传,不进 argv) | | `local_tui` | 打开一次性伪终端面板(如 Copilot `/login`、部分 onboarding);结束后关闭,只留脱敏状态 | 状态探测优先级: 1. 适配器 `status_command`(如 `codex login status`、`opencode auth list`) 2. 钥匙串是否有对应 key 3. 配置文件非敏感标记 4. 否则 `unknown` Qwen:UI 文案明确「免费 OAuth 已停用,请配置 API Key」。 Kimi:安装源校验拦截非官方 npm。 --- ## 8. 赛博风 UI 技术支撑与性能底线 ### 8.1 与美术师对接点(施工员只消费 Token) ```text src/tokens/ color.css /* --ad-bg, --ad-neon-cyan, --ad-danger, ... */ typography.css space.css motion.css /* --ad-duration-fast/mid, --ad-ease-cyber */ effects.css /* --ad-glow-strength, --ad-scanline-opacity */ tiers.css /* data-fx-tier="high|balanced|low" */ ``` 页面结构按 PRD §7:总览 / CLI 目录 / 我的 CLI / 配置中心 / 备份 / 设置。视觉细节以美术师 HEL-101 规范为准;架构只保证:**所有颜色/光晕/动效时长走 Token,组件不写死魔法数。** ### 8.2 实现分层 | 层级 | 技术 | 用途 | |---|---|---| | L0 静态 | CSS 渐变、网格背景、边框霓虹(`box-shadow` Token) | 常驻,成本低 | | L1 过渡 | Framer Motion / CSS transition | 路由、列表、按钮 | | L2 光效 | SVG/CSS 扫光、有限 blur | 卡片 hover、焦点 | | L3 粒子/噪点 | 可选 Canvas,**默认关** | 总览背景 | ### 8.3 性能底线与降级 - 目标:集成显卡笔记本上总览页 **≥45 FPS**;交互延迟 <100ms。 - 默认档 `balanced`:关 L3、降低 blur、减少同时动画数量(`max-concurrent-motions ≤ 3`)。 - `low`:仅 L0+必要过渡;`prefers-reduced-motion` 强制 `low`。 - 长列表虚拟滚动;日志终端用虚拟化,避免万行 DOM。 - WebView 合成层:大面积滤镜仅用于静态背景层,不叠在滚动内容上。 --- ## 9. 安装包分发与自动更新 | 产物 | 工具链 | 校验 | |---|---|---| | Windows x64 安装包 | Tauri + NSIS(或 MSI 二选一,首期 NSIS) | Authenticode 签名(有证书则必须;无证书时 UI 提示校验 SHA256) | | Ubuntu | `.deb` + **AppImage**(覆盖无 root 场景) | deb 可用 GPG;AppImage 附 SHA256SUMS | | 更新 | Tauri Updater | ed25519/minisign 签名;更新端点在 `allowed_hosts` | | 回滚 | 保留上一版安装包;失败则提示卸载重装 + Git tag 对应版本 | 方案期约定:发版打 tag,坏版本从更新通道撤下 | 应用自动更新与「CLI 更新」分离:设置页两项独立开关。核心管理功能 **离线可用**(目录 YAML 内置;在线仅用于检查更新与声明过的诊断 URL)。 --- ## 10. 诊断规则引擎 ### 10.1 规则模型 ```yaml rule_id: path.missing_executable severity: path | dependency | version_conflict | config_corrupt | network | auth severity: info | warn | error when: { adapter_expr } # 可选:仅某些 CLI check: # 声明式检查器 type: which | semver | file_parse | http_head | keyring_has ... message_zh: "..." evidence: capture # 原始 which 输出等 fix: - id: add_to_path dry_run: true reversible: true impact_zh: "..." ``` ### 10.2 四类必检(可扩展) | 类 | 示例规则 | |---|---| | PATH | 可执行文件不在 PATH;Windows Store alias 劫持;`~/.local/bin` 未入 PATH | | 依赖缺失 | Node 版本不满足(Gemini≥20、Claude/Qwen/Cline/Copilot npm≥22);无 Git;无 uv(Kimi) | | 版本冲突 | 多路径同名命令;npm global 与独立脚本双装(CodeBuddy 双通道) | | 配置损坏 | JSON/TOML/YAML 解析失败;crushrc 无法识别关键赋值;权限不可读 | 网络类:仅 `HEAD/GET` 适配器 `allowed_hosts`。 输出:级别 + 证据 + 中文解释 + 推荐修复(修复前 dry-run + 备份)。 --- ## 11. 测试策略 | 层级 | 内容 | |---|---| | 适配器单元测试 | 每个 YAML:schema 校验;dry-run 快照;version_regex 对 fixture stdout;危险命令(含 shell 元字符)必须拒载 | | Codec 测试 | 各格式往返;保留未知键;原子写失败注入 | | Exec 测试 | 拒绝管道字符串;参数白名单 | | Secrets 测试 | mock keyring;断言日志无明文 | | 平台检测测试 | Win/Ubuntu CI 或容器:`PlatformEnv` 字段;对「未安装」场景断言错误码 | | UI 冒烟 | 目录渲染 14 条;安装确认框展示 argv;降级档无运行时错误 | | 手工验收(对齐 PRD §10) | 双平台干净机:装应用→检测→至少 1 个 CLI GUI 安装成功→配置往返→Key 不进日志 | Wave A 五个适配器必须先有绿灯测试,再扩 Wave B。 --- ## 12. 分波次交付节奏(14 = 5 + 9,每步可运行) 对齐 PRD §11,并按老板升级的 14 适配器拆波: ### Wave 0 — 空壳可运行(约 1 迭代) Tauri2 + React 壳、Token 占位、IPC 心跳、SQLite 空库、平台检测页、假目录。 ### Wave 1 — 适配器框架 + 环境检测 Schema、加载器、dry-run、exec 沙箱、密钥库封装、日志脱敏。 ### Wave 2 — Wave A 五件套打通全链路(安装→检测→配置→授权状态→诊断) 优先选「文档全、双平台稳、配置清晰」: 1. **Codex**(三授权 + TOML) 2. **Claude Code**(winget/脚本 + JSON) 3. **Gemini**(npm + JSON Schema) 4. **Kimi**(脚本/PyPI,验证非 npm 路径) 5. **OpenCode**(多渠道 + 多授权) 验收:五者均可 detect;至少两者 GUI 安装成功;API Key 配置往返;三类诊断可命中。 ### Wave 3 — Wave B 补齐 9 个 **B1(npm/脚本同类)**:Qwen、CodeBuddy、Cline、Copilot **B2(包管理器/特殊)**:Crush(winget/apt + crushrc)、Goose(PS 脚本 + YAML 路径差异)、Aider(Python 安装器) **B3(闭源脚本)**:Cursor(`agent`)、Warp(`warp`) 每合入一个:单元测试 + 双平台 detect 记录。 ### Wave 4 — 备份迁移 + 安装包 + 更新通道 备份不含密钥;Win NSIS + Ubuntu deb/AppImage;签名/SHA256;赛博视觉按美术规范挂满并做降级开关。 ### Wave 5 — 打磨 批量更新、文档页中文、诊断规则扩容、第二批 watch 列表 UI。 --- ## 13. 施工员开工检查清单(拿到本方案应无需再问架构) - [ ] 按目录建 monorepo;适配器只加 YAML,不改 core 流程 - [ ] 一切安装命令来自上表与调研底稿,禁止凭记忆改包名 - [ ] Kimi 绝不走 npm;Cursor 绝不走 npm;命令名 `agent` - [ ] 用户确认前只 `dry_run`;确认后流式展示 stdout/stderr - [ ] 密钥只进 keyring;日志过脱敏 - [ ] 颜色/动效只引用 `tokens/`,等美术师规范合并 - [ ] 不实现第二批 4 个,不建远程业务后端 - [ ] 每 Wave 结束保持 `cargo test` + 前端 build 通过 --- ## 14. 风险与需总管转告老板的点(非阻塞,已在方案内消化) 1. 若干 CLI 的 `--version` 官方未文档化 → 适配器 `version_unconfirmed` + 实测表。 2. CodeBuddy 配置路径、Copilot 登录是浏览器还是设备码 → Wave B 实测补字段。 3. Gemini 官方写 Win11 24H2+ → 低版本 Win10 显示「官方未支持」而非强装。 4. 无代码签名证书时 Win 智能筛选会报警 → 提供 SHA256 核对说明。 5. Crush FSL 许可 → 关于页展示,不做竞品再分发其源码。 --- **本方案只交付设计,不含实现代码、不建仓库、不部署。** 施工员以本文 + PRD + 调研底稿三件套开工;视觉以美术师规范为准。