562 lines
27 KiB
Markdown
562 lines
27 KiB
Markdown
# 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<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 | 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.<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 # 发行版名,如 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.<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`
|
||
|
||
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 + 调研底稿三件套开工;视觉以美术师规范为准。
|