Files

562 lines
27 KiB
Markdown
Raw Permalink 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.
# 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 |
| 本机能力 | **RustTauri 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 + NSISWin+ deb + AppImageUbuntu** | 覆盖目标平台 | 二期可加 flatpak |
| 自动更新 | **Tauri updater(签名校验)**;更新源仅官方 CDN | 离线核心功能不依赖更新 | 可关自动检查 |
| 测试 | **Rustcargo 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/LinuxPATH、权限提升探测、发行版识别
│ ├── 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<Finding>
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 | npmNode 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+)或 npmUbuntu: 脚本/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/scoopUbuntu: 官方脚本/npm | brew、Releases | JSON/jsonc `~/.config/opencode/opencode.json` | api_key + browser + device_code | 授权面最全之一 |
| `crush` | `crush` | Win: winget `charmbracelet.crush`Ubuntu: 官方 aptGPG | npm、scoop、Releases | **crushrc**Bash 语法) | api_key(环境变量) | `--version` 未确认;FSL 许可展示说明 |
| `goose` | `goose` | Win: 官方 `download_cli.ps1`Ubuntu: 官方脚本 | brew、deb | YAMLWin 注意 `%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.ps1Ubuntu: curl 脚本 | brew caskLinux | 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 Managervia `keyring` | `secrets::set(service, account, secret)` |
| Linux | Secret Service / libsecret | 同上;无 daemon 时降级:**拒绝写入明文**,UI 提示安装 `gnome-keyring` |
- `service` 固定前缀 `agentdock.<cli_id>``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 # 发行版名,如 ubuntuWindows 为 None
distro_version?: string # 发行版版本,如 22.04Wave 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.<timestamp>`(及 SQLite 备份索引)。
2. 写入临时文件 `F.tmp.<pid>`
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`
QwenUI 文案明确「免费 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 可用 GPGAppImage 附 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 | 可执行文件不在 PATHWindows Store alias 劫持;`~/.local/bin` 未入 PATH |
| 依赖缺失 | Node 版本不满足(Gemini≥20、Claude/Qwen/Cline/Copilot npm≥22);无 Git;无 uvKimi |
| 版本冲突 | 多路径同名命令;npm global 与独立脚本双装(CodeBuddy 双通道) |
| 配置损坏 | JSON/TOML/YAML 解析失败;crushrc 无法识别关键赋值;权限不可读 |
网络类:仅 `HEAD/GET` 适配器 `allowed_hosts`
输出:级别 + 证据 + 中文解释 + 推荐修复(修复前 dry-run + 备份)。
---
## 11. 测试策略
| 层级 | 内容 |
|---|---|
| 适配器单元测试 | 每个 YAMLschema 校验;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 个
**B1npm/脚本同类)**Qwen、CodeBuddy、Cline、Copilot
**B2(包管理器/特殊)**Crushwinget/apt + crushrc)、GoosePS 脚本 + YAML 路径差异)、AiderPython 安装器)
**B3(闭源脚本)**Cursor`agent`)、Warp`warp`
每合入一个:单元测试 + 双平台 detect 记录。
### Wave 4 — 备份迁移 + 安装包 + 更新通道
备份不含密钥;Win NSIS + Ubuntu deb/AppImage;签名/SHA256;赛博视觉按美术规范挂满并做降级开关。
### Wave 5 — 打磨
批量更新、文档页中文、诊断规则扩容、第二批 watch 列表 UI。
---
## 13. 施工员开工检查清单(拿到本方案应无需再问架构)
- [ ] 按目录建 monorepo;适配器只加 YAML,不改 core 流程
- [ ] 一切安装命令来自上表与调研底稿,禁止凭记忆改包名
- [ ] Kimi 绝不走 npmCursor 绝不走 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 + 调研底稿三件套开工;视觉以美术师规范为准。