diff --git a/.gitignore b/.gitignore index 3eabc40..472608c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,9 @@ lerna-debug.log* .trae .workbuddy +.npm-cache +.bun-tmp +.uploads temp/ release_stage/ musicdl_outputs/ diff --git a/TERMINAL_MODULE_PLAN.md b/TERMINAL_MODULE_PLAN.md new file mode 100644 index 0000000..7266d15 --- /dev/null +++ b/TERMINAL_MODULE_PLAN.md @@ -0,0 +1,841 @@ +# 终端模块规划(Terminal Module Plan) + +> 状态:**P0 骨架已落地;P1 进行中**(Rust 侧:cwd 跟踪 / 状态事件 / GBK 编码 / SFTP 后端已完成并编译通过) +> 定位:Thing 工具集的第 11 个模块,`id = terminal`,`category = 'tool'` +> 作者:砚 | 日期:2026-09-17 +> 关联文档:`AI_DEV_GUIDE.md`(模块注册机制 / IPC / 进程管理范式) +> +> **实施进度与踩坑记录见文末 §9(P0)与 §10(P1)**(含与本规划不一致之处,以 §9 / §10 为准) + +--- + +## 0. 结论先行 + +三个关键判断,先摆在这里,后文展开论证: + +1. **终端模块不应复用 `ProcessManager`**。它是为「单例常驻守护进程(mihomo)」设计的:一个模块 ID 对应一个进程,崩溃即重启。而终端要的是「N 个会话、每个会话生命周期独立、能挂起能重连、能写 stdin」——语义不同,硬套会把这套抽象撑坏。正确做法是**新建独立的 `TerminalManager`**,与 `ClipboardManager` / `MusicManager` / `TranslateManager` 平级,`manage()` 进 Tauri State。 + +2. **会话进程必须跑在 Rust 侧,不能是前端 shell**。这是 Windows 上的硬约束,且与已有基建同构:`ProcessManager`、`download_engine` 都在 Rust 侧管进程。理由有三——(a) WebView2 无 PTY 访问;(b) 前端持有的子进程会在页面重载时变孤儿;(c) 多标签、后台保活、断线重连都需要一个独立于 UI 生命周期的宿主。 + +3. **SSH 走「自研客户端 + 真实 PTY」,而不是「拼接 ssh.exe + ConPTY」**。后者实现快但天花板低:无法做 SFTP 复用连接、无法读主机密钥指纹、无法做跳板机链、无法统一错误模型、`ssh.exe` 的输出会与 ConPTY 的 ANSI 处理打架。代价是 Ruffles/ssh2 的移植与 ConPTY 绑定要自己写,收益是整个能力面没有上限。 + +**总工作量估算**:P0 骨架(本地 Shell + 多会话 + 密钥管理)约 8~12 个工作日;P1(SSH/SFTP 完整能力)约 15~20 个工作日;P2(高级能力)按需。**建议按 P0 先行落地可用版本,再迭代。** + +> **收官状态(2026-09-18)**:P0–P2 全部落地(ZMODEM 经评估放弃,见实施记录), +> 并完成一轮全链路审查(修复键盘输入失效、切标签丢缓冲、连接期关闭竞态等 7 项)。 +> 单测 91/91、`cargo check` 与 `vue-tsc` 零错误。实施记录见 §9-11(精编版)。 + +--- + +## 1. 需求解构 + +用户提出的四条主干,拆成可执行的规格: + +| 用户原话 | 解构为 | 落点 | +|---|---|---| +| 「主要是 ssh」 | SSH2 客户端、主机密钥校验、认证(密钥/密码/Agent/键盘交互/2FA)、跳板机、端口转发、连接复用 | §4.2 / §5.1 | +| 「多会话」 | 多标签 + 分屏、会话持久化(切页不断连)、状态栏、会话恢复、会话模板 | §4.3 | +| 「密钥管理」 | SSH 密钥生成/导入/列举、passphrase 托管、known_hosts 管理、ssh-agent 集成、私钥不进明文 | §4.4 | +| 「文件快捷管理」 | SFTP 双栏文件管理器、拖拽上传下载、跟随终端 cwd、内联 `rz/sz`、文件编辑器 | §4.5 | +| 「方便的快捷键」 | 终端键盘映射(复制粘贴/搜索/新建标签/分屏/跳转)、可配置、与全局面板联动 | §4.6 | +| (我补充) | **本地 Shell**(PowerShell/cmd/WSL/Git-Bash)、**命令补全与历史**、**命令片段库**、**AI 命令助手**、**日志与审计**、**快速面板联动** | §4.1 / §4.7 / §4.8 | + +--- + +## 2. 现状勘察(论证依据) + +以下为 2026-09-17 从仓库实际读取的结果,作为设计约束的来源。 + +### 2.1 已具备的基建 + +| 能力 | 现有实现 | 终端模块可复用的部分 | +|---|---|---| +| 模块注册 | `src/modules/registry.ts` + `src/modules/index.ts` 静态导入 | 直接沿用,新增一行导入 + 图标映射 | +| 类型绑定 | `tauri-specta` 自动生成 `src/lib/bindings.ts`,debug 构建时导出 | **必须复用**,终端命令量较大,手写 `invoke` 类型不可接受 | +| 凭据存储 | `src-tauri/src/secrets.rs`:`keyring` + Windows 凭据管理器(DPAPI),服务名固定 `"Thing"` | **直接复用**,见 §4.4 | +| 全局快捷键 | `src-tauri/src/shortcut.rs`:原子化注册 + 应用内冲突检测 + 占用表 | **直接复用**,见 §4.6 | +| 托盘 | `src-tauri/src/tray_menu.rs` | 可挂「新建会话」入口(P2) | +| 日志 | `src-tauri/src/logger.rs`(`log_info` / `log_warn` / `log_error`) | 继承统一日志,日志页可过滤 | +| 窗口常量 | `src-tauri/src/constants.rs`(`windows` / `events`) | 需新增窗口与事件常量 | +| 弹窗范式 | `translate-popup` 的 NOACTIVATE 预创建窗口 + `capabilities/translate-popup.json` | 终端「快速会话/命令补全」浮层可参照 | + +### 2.2 关键缺口(需要新增依赖) + +| 缺口 | 现状 | 方案 | +|---|---|---| +| ConPTY 绑定 | 无。`windows-sys` 未开启 `Win32_System_Console` | 开启该 feature;或引入 `portable-pty`(见 §3.1 取舍) | +| SSH 客户端 | 无 | 引入 `russh`(纯 Rust)或 `ssh2`(libssh2 绑定) | +| SFTP | 无 | 随 SSH 库一并引入 | +| 终端渲染 | 无。`node_modules` 中**不存在** `@xterm/*` | 引入 `@xterm/xterm` + `@xterm/addon-fit` + `@xterm/addon-webgl` + `@xterm/addon-search` + `@xterm/addon-web-links` | +| 前端代码编辑器 | 无 | 按需引入 `codemirror` 或复用纯 `