Wave 2.2: 流式安装输出、软件内授权四模式、本机环境一键装与总览缓存

EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
leefer
2026-08-25 17:11:14 +08:00
co-authored by Cursor
parent a2fd5e369b
commit dd5a9378d2
24 changed files with 2659 additions and 263 deletions
+57
View File
@@ -0,0 +1,57 @@
# AgentDock Wave 2.2 实现说明
基线:工位 git `wave-2.1` tagd2e9de1,即 HEL-137 交付的 `agentdock-wave-2.1-source.zip`)。
本波对应老板复验 Wave 2.1 后提的 4 条「可用性」硬要求,逐条解决如下。
## 1. 安装输出实时滚动 + 失败提示人话化
**根因**:旧 `run_streaming` 先读 stdout、读完后才读 stderr,且主循环只在一行到达时才检查取消。导致 stderr 内容全部延迟到进程结束才一次性上屏(老板所见「最后才显示结果和中间过程」)。
**修复**`crates/agentdock-core/src/process.rs`):
- `run_streaming` / `run_streaming_cancellable` 改为**两条读取线程并发**消费 stdout/stderr,经 mpsc 通道按到达顺序实时回调,主循环用 `recv_timeout(200ms)` 兜底(静默期也能响应取消)。
- 新增 `resolve_exe`PATH 解析到 .exe/.cmd/.bat 实际路径)、`run_with_stdin`API Key 经 stdin 注入官方登录命令)、`run_terminal`CREATE_NEW_CONSOLE 一次性终端窗口)、`open_with_shell`explorer/xdg-open 打开文件或 URL)。
- `RunningProcess` 提供 `request_cancel` / `cancel_flag``kill` 在 Windows 用 `taskkill /T /F` 杀整棵进程树,避免 `.cmd` 包装的 node 子进程变孤儿。
**人话化错误映射**`crates/agentdock-core/src/errors_zh.rs`):
- `program not found` → 「未找到 X 命令:需要先安装 Y(可在本机环境区一键安装)」+ `missing_runtime`npm→node、python→python、git、winget、uv…)。
- 网络超时/连接拒绝/DNS、磁盘不足、权限不足等均映射为中文建议。
- 原始报错保留在 `raw`,事件 `data` 携带结构化 `ErrorHint { code, friendly_zh, raw, missing_runtime }``ActionEvent::error_hint`)。
**前端**`pages/CliDetail.tsx`):失败态默认展示人话版,原始报错折叠可展开;`missing_runtime` 时给内联「去安装 Node.js」按钮,直达本机环境区一键安装(联动第 3 条)。
## 2. 软件内授权(PRD FR-06
**引擎**`crates/agentdock-core/src/engine.rs`):
- 新增 `Engine::authorize_stream` + `cancel_authorize` + 会话注册表(可取消进程句柄)。
- 四类流程:
- `api_key`:有官方命令时(如 codex `login --with-api-key`)从密钥库读 key 经 stdin 注入;无命令(opencode)仅核对密钥库。
- `browser_oauth`:后台运行官方登录命令,流式回传、可取消、结束后刷新授权状态。
- `device_code`:运行官方命令,`parse_device_code` 解析 `user_code` + `verification_url`(ANSI 去色 + 正则),大号验证码上屏。
- `local_tui``run_terminal` 打开一次性本机终端窗口,结束只回传脱敏成败状态。
- 全程不记录令牌明文,日志/状态只存枚举;输出经 `redact` 脱敏。
**前端**`components/AuthPanel.tsx`):配置页「授权 / 登录」第一层从说明文字升级为可操作流程——每个授权方式一个「开始授权」按钮,弹「授权进行中」面板(可取消),设备码大号展示 + 一键复制 + 「打开授权网页」,结束后即时刷新授权状态灯。
## 3. 本机环境一键安装 + 修总览诊断
**运行时来源表**`crates/agentdock-core/src/runtime_install.rs`):
- 内置 node/python/git/winget/uv 官方来源(download_url + download_page + size_approx + elevate_needed + allowed_hosts)。
- `is_url_host_allowed` 白名单校验(安全红线);`download_with_curl` 用系统 curl.exe 下载。
**IPC**`src-tauri/src/commands/runtime.rs`):`previewRuntimeInstall` / `installRuntime`(下载→打开安装向导,进度经 `runtime-install-event` 回传)/ `openRuntimePage`(官网兜底)。
**前端**`components/RuntimeInstallModal.tsx` + `pages/Overview.tsx`):本机环境未安装项变「安装」按钮 → 弹确认框(官方来源/体积/权限)→ 下载并打开安装向导;失败或不可直接安装时兜底「打开官方下载页」。
**修诊断**:新增 `diagnoseAll` IPC(对全部已装工具跑诊断),总览「立即诊断」(诊断卡 + 快速操作两处)都接上,弹全量诊断汇总。
## 4. 总览加载闪烁
- `hooks/useDetectAll.ts` / `useEnv.ts`:检测结果**模块级本地缓存**——切页回来先用缓存立即渲染,后台静默刷新。
- `pages/Overview.tsx`:检测未完成(首次、无缓存)时显示**骨架屏**「正在检测本机 CLI…」,绝不显示「工具箱是空的」;该文案仅在检测完成且确实零安装时出现。
## 涉及文件
- Rust`process.rs``errors_zh.rs`(新)、`runtime_install.rs`(新)、`engine.rs``types.rs``lib.rs`core);`commands/cli.rs``commands/runtime.rs`(新)、`commands/mod.rs``lib.rs`desktop);`secrets/src/keyring.rs`(加真机往返测试)。
- 前端:`ipc/index.ts``ipc/types.ts``components/AuthPanel.tsx`(新)、`components/RuntimeInstallModal.tsx`(新)、`components/ConfigForm.tsx``pages/CliDetail.tsx``pages/Overview.tsx``hooks/useDetectAll.ts``hooks/useEnv.ts``styles/global.css`
未引入任何新依赖(下载用系统 curl.exe、打开用 explorer.exe、任务树终止用 taskkill)。