feat: harden local shell, SFTP, and desktop session reliability
Finder-launched terminals now inherit a login PATH so tools like ollama resolve, destructive SFTP/editor actions require confirmation, and terminal search plus window dragging work again. SSH forwards and RDP sessions keep listeners and survive reconnect without FastPath crashes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
188f3556ed
commit
08696896f9
223 files changed
+13493
-3423
No files matched your search
+4
-2
@@ -7,8 +7,10 @@
|
||||
| [使用指南](./user-guide.md) | SSH、SFTP、代理、串口、AI 助手和数据安全 |
|
||||
| [架构说明](./architecture.md) | Tauri/Rust 分层、原生服务、AI 与安全边界 |
|
||||
| [SSH Agent CLI](./ai-agent.md) | ReAct 执行循环、工具、风险、记忆取舍与评测 |
|
||||
| [产品体验全面评估](./ux-foundation-audit.md) | 全产品评分、大众操作习惯、P0/P1/P2 与统一回归清单 |
|
||||
| [测试验收](./testing-acceptance.md) | 本地门禁、真实 SSH 探针和发版验收 |
|
||||
| [发布指南](./release.md) | macOS/Windows 构建、签名、产物和临时文件清理 |
|
||||
| [路线图](../ROADMAP.md) | 已完成基线与下一阶段(根目录权威副本) |
|
||||
| [当前任务](../TASKS.md) | Hermes / OpenClaw 可勾选任务 |
|
||||
| [测试计划](../TDD_PLAN.md) | 巡检、门禁与下一任务的测试先行 |
|
||||
|
||||
项目定位、功能概览和开发命令见仓库根目录的 [README](../README.md),未完成事项只在 [ROADMAP](../ROADMAP.md) 维护。
|
||||
项目定位、功能概览和开发命令见仓库根目录的 [README](../README.md),未完成事项只在 [ROADMAP.md](../ROADMAP.md) / [TASKS.md](../TASKS.md) 维护。
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
## 产品边界
|
||||
|
||||
OpsXShell 是轻量原生的运维终端,核心范围是连接、终端、文件传输、端口转发、代理、RDP / VNC 远程桌面、串口和多会话操作。审计、录像、审批和堡垒机能力不在客户端范围内。
|
||||
OpsXShell 是简单好用的原生运维终端:短路径完成连接、终端、传文件、转发和远程桌面。审计、录像、审批和堡垒机能力不在客户端范围内。
|
||||
|
||||
## 目录与职责
|
||||
|
||||
```text
|
||||
src/ React 界面、工作区和 Zustand 状态
|
||||
src/i18n/ 界面文案(zh-CN / en)与 locale 检测
|
||||
src/i18n/ 界面文案(zh-CN / zh-TW / en / ja / ko / vi / ru)与 locale 检测
|
||||
src/platform/ Tauri command/event 适配层
|
||||
shared/types/ 渲染层 TypeScript 契约
|
||||
src-tauri/src/commands/ 参数边界和统一响应
|
||||
@@ -65,7 +65,7 @@ services/
|
||||
| 凭据 | AES-256-GCM + `~/.opsxshell/master.key` |
|
||||
| 主机信任 | OpenSSH `~/.ssh/known_hosts` |
|
||||
| 终端 AI | Rust `reqwest` + OpenAI/Anthropic 兼容协议 |
|
||||
| 界面语言 | i18next;zh-CN / en,首启按系统语言检测 |
|
||||
| 界面语言 | i18next;zh-CN / zh-TW / en / ja / ko / vi / ru,首启按系统语言检测 |
|
||||
|
||||
## SSH Agent CLI 边界
|
||||
|
||||
@@ -106,9 +106,11 @@ XTerm 当前焦点分屏
|
||||
|
||||
- `ForwardRule` 由 React 管理并按会话 / 标签 / 连接维度写入设置,只保存类型、端口和目标。
|
||||
- `ForwardStatus` 由 Rust `TunnelManager` 管理,只在当前进程有效,包含监听端口、开始时间、连接数和流量。
|
||||
- 每个运行实例有唯一 `forwardId` 和取消标志。停止、删除正在运行的规则或断开 SSH 连接时,Rust 必须关闭真实 Listener。
|
||||
- 每个运行实例有唯一 `forwardId` 和取消标志。用户点停止 / 删除正在运行的规则、关闭标签、连接面板手动断开,或进程退出时,Rust 才关闭真实 Listener。终端 SSH 断开、空闲挂起或重连不得拆掉未停止的规则。
|
||||
- 本地 / 动态转发:本机 TCP 监听长住,每条规则共用一条专用 SSH 会话(保活;会话挂了只重建传输,不拆本地端口)。远程转发:专用会话保活,断开后在进程内自动重听。
|
||||
- SSH 重连(同一 `user@host:port`)通过 `adopt_orphans` 把仍在监听的运行实例挂到新 connectionId。运行态仍不落盘。
|
||||
- 规则支持编辑和复制。复制只产生新的规则 ID,不复制运行态;运行中的规则必须先停止真实 Listener 才能编辑。
|
||||
- 应用重启后不得根据上次 UI 状态显示“运行中”,必须以 `ssh_forward_list` 返回的原生状态为准。
|
||||
- 应用重启后不得根据上次 UI 状态显示“运行中”,必须以 `ssh_forward_list` 返回的原生状态为准。运行态只存在当前进程内存。
|
||||
- 状态栏「转发」打开右侧抽屉:动态 SOCKS5 固定 `127.0.0.1:1080`(每台 SSH 主机一条),本地 / 远程规则可列表启停;右键状态栏项复制 `socks5://127.0.0.1:1080`。
|
||||
|
||||
当前动态 SOCKS5 默认仅绑定 `127.0.0.1`,不对局域网暴露。客户端仅支持 SOCKS5 CONNECT 和无认证方式。流量经当前 SSH 服务器出口 IP 访问外网。
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
|
||||
<rect x="64" y="64" width="896" height="896" rx="224" fill="#101820"/>
|
||||
<rect x="116" y="116" width="792" height="792" rx="180" fill="#17232d"/>
|
||||
<path d="M258 326 454 512 258 698" fill="none" stroke="#f2f7f8" stroke-width="92" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M500 698h244" fill="none" stroke="#55aef2" stroke-width="92" stroke-linecap="round"/>
|
||||
<circle cx="750" cy="308" r="52" fill="#42d392"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 502 B |
+8
-8
@@ -4,19 +4,19 @@
|
||||
|
||||
```bash
|
||||
# 推荐:当前平台完整门禁、打包、验证和 SHA-256
|
||||
./build.sh
|
||||
./scripts/build.sh
|
||||
|
||||
# macOS Apple Silicon 指定版本
|
||||
./build.sh v2.1.1 mac-arm64
|
||||
./scripts/build.sh v2.1.1 mac-arm64
|
||||
|
||||
# Windows x86_64(推荐在 Windows CMD/PowerShell 中执行)
|
||||
build.bat v2.1.1 win-x64
|
||||
scripts\build.bat v2.1.1 win-x64
|
||||
|
||||
# 本地重复构建时缩短门禁;正式发布不要跳过
|
||||
./build.sh v2.1.1 mac-arm64 --quick
|
||||
./scripts/build.sh v2.1.1 mac-arm64 --quick
|
||||
```
|
||||
|
||||
`build.sh` 与 `build.bat` 面向 v2.1.x,会检查 Node、npm、Rust target 和五处版本元数据。显式传入不同于当前源码的新版本时,脚本会同步版本文件;它们只负责构建,不会自动创建 tag 或推送远程仓库。安装包和 `SHA256SUMS.txt` 输出到:
|
||||
`scripts/build.sh` 与 `scripts/build.bat` 面向 v2.1.x,会检查 Node、npm、Rust target 和五处版本元数据。显式传入不同于当前源码的新版本时,脚本会同步版本文件;它们只负责构建,不会自动创建 tag 或推送远程仓库。安装包和 `SHA256SUMS.txt` 输出到:
|
||||
|
||||
```text
|
||||
release/v2.1.1/macos-arm64/
|
||||
@@ -41,7 +41,7 @@ release/v2.1.1/windows-x64/
|
||||
rustup default stable-x86_64-pc-windows-msvc
|
||||
rustup target add x86_64-pc-windows-msvc
|
||||
npm ci
|
||||
build.bat v2.1.1 win-x64
|
||||
scripts\build.bat v2.1.1 win-x64
|
||||
```
|
||||
|
||||
默认执行完整门禁;`--quick` 适合开发期重复构建,正式发布不要使用 `--skip-checks`。输出位于 `release\v2.1.1\windows-x64\`。没有代码签名证书时可以生成开发安装包,但 Windows SmartScreen 可能提示未知发布者。
|
||||
@@ -52,10 +52,10 @@ build.bat v2.1.1 win-x64
|
||||
|
||||
```bash
|
||||
# 只检查附件,不访问 Gitee API
|
||||
./release.py v2.1.1 --dry-run
|
||||
./scripts/release.py v2.1.1 --dry-run
|
||||
|
||||
# 创建或更新 Release,上传安装包和 SHA256SUMS.txt,并核验远程附件
|
||||
./release.py v2.1.1
|
||||
./scripts/release.py v2.1.1
|
||||
```
|
||||
|
||||
发布凭据从 `GITEE_TOKEN` 或 `~/.netrc` 的 `gitee.com` 条目读取,脚本不会输出 Token。脚本只读取 `release/v<版本>/` 下的 `.dmg`、`.exe`、`.msi` 和 `SHA256SUMS.txt`,上传成功后保留本地文件。远程已有同名同大小附件时会跳过;同名但大小不同时停止,避免静默覆盖已发布二进制。
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# 路线图
|
||||
|
||||
权威副本在仓库根目录:
|
||||
|
||||
- [ROADMAP.md](../ROADMAP.md) — 产品方向与下一阶段
|
||||
- [TASKS.md](../TASKS.md) — 当前可勾选任务(Hermes / OpenClaw / Cursor)
|
||||
- [TDD_PLAN.md](../TDD_PLAN.md) — 测试先行与门禁
|
||||
|
||||
开发规则以 [AGENTS.md](../AGENTS.md) 为准。不要在本文件再维护一份进度,避免漂移。
|
||||
@@ -29,7 +29,7 @@ npm run acceptance:full
|
||||
- HTTP CONNECT、SOCKS5 和断点复制
|
||||
- 转发规则不持久化运行状态,复制产生新 ID;原生隧道可启动、查询、停止并在 SSH 断开时清理
|
||||
- 状态栏「转发」抽屉启停动态 `127.0.0.1:1080`,右键复制 SOCKS 地址;每台 SSH 主机仅一条动态规则
|
||||
- i18n:zh-CN / en 的 namespace key 对齐(`test/i18n/localeKeys.test.ts`)
|
||||
- i18n:全部 APP_LANGUAGES(zh-CN / zh-TW / en / ja / ko / vi / ru)的 namespace key 对齐(`test/i18n/localeKeys.test.ts`)
|
||||
- RDP / VNC 仅原生可用;非 Tauri 环境不得显示为可连接;桌面会话不参与批量命令
|
||||
- SFTP 本地/远程路径参数方向、原生路径上传、选中文件下载、双栏双向拖拽、目录落点、远程文本读写和错误反馈
|
||||
- 终端分屏、剪贴板、快捷键、分片 UTF-8 解码、高输出背压和异步输入错误
|
||||
|
||||
+16
-9
@@ -1,5 +1,7 @@
|
||||
# 使用指南
|
||||
|
||||
OpsXShell 主打简单好用:常用远程操作走短路径,高级选项默认收起。不做堡垒审计。
|
||||
|
||||
## 快速连接
|
||||
|
||||
按 `Cmd/Ctrl + K`,输入 `user@host` 或 `user@host:port` 后连接。默认端口为 `22`。快速连接适合临时使用,不会自动保存会话。
|
||||
@@ -35,10 +37,12 @@ socks5://127.0.0.1:1080
|
||||
|
||||
- 动态转发每台 SSH 主机仅一条,端口固定 `1080`;在抽屉中直接启停。
|
||||
- 状态栏「转发」右键可复制 `socks5://127.0.0.1:1080`。需要远程 DNS 解析的命令行工具应使用 `socks5h`,例如 `curl --proxy socks5h://127.0.0.1:1080 https://example.com`。
|
||||
- 本地转发:本机监听默认只需填端口(绑定 `127.0.0.1` / localhost,等同 `ssh -L 8080:…`);需要局域网访问时再展开高级项改为内网 IP 或 `0.0.0.0`。目标主机相对当前 SSH 服务器(常用 `127.0.0.1` 或内网 IP),不是会话页主机名,且不能填 `0.0.0.0`。
|
||||
- 本地 / 远程规则在抽屉列表中添加、启停和删除;“停止”会关闭 Rust Listener,不是只改界面图标。
|
||||
- 远程转发(`-R`):远端监听填 `127.0.0.1:端口`(仅 SSH 服务器本机可访问)或 `0.0.0.0:端口`(远端内网其它主机也可访问,需 sshd `GatewayPorts yes` 或 `clientspecified`)。目标为本机或内网 `host:port`(不能填 `0.0.0.0`)。服务器还需 `AllowTcpForwarding yes` 或 `remote`;监听端口不能已被占用;`<1024` 通常需要 root。可用 `ssh -R [bind:]port:host:port user@host` 对照。
|
||||
- “复制规则”会创建独立的新规则,便于只修改端口或目标;不会复制原规则的运行状态。
|
||||
- 运行中的规则选择“编辑”时,会先提示停止真实监听,再允许保存新配置。
|
||||
- 保存的是规则,不是“运行中”状态;应用重启后需要用户再次启动。
|
||||
- 保存的是规则,不是“运行中”状态;应用重启后需要用户再次启动。同一窗口内只要没点「停止」,SSH 断线、保活失败、空闲挂起或重连都会继续监听(本地 / SOCKS 端口不拆,远程转发会自动重听)。点停止、关闭标签、连接面板手动断开,或退出应用,才会关闭真实 Listener。关闭标签后再开同一会话不会自动拉起转发。
|
||||
- SOCKS5 默认仅监听本机,当前不提供局域网开放和客户端密码认证。
|
||||
|
||||
## 远程桌面(RDP / VNC)
|
||||
@@ -67,15 +71,18 @@ socks5://127.0.0.1:1080
|
||||
|
||||
## SFTP
|
||||
|
||||
SFTP 使用双栏文件管理器。上传和下载先写入 `.opsx-part` 临时文件,中断后再次传输同一路径会从已有字节继续。传输完成并通过大小校验后才替换正式文件,因此失败传输不会伪装成完整文件。
|
||||
SFTP 使用双栏文件管理器。中间箭头可上传/下载;上传和下载先写入 `.opsx-part` 临时文件,中断后再次传输同一路径会从已有字节继续。传输完成并通过大小校验后才替换正式文件,因此失败传输不会伪装成完整文件。
|
||||
|
||||
- 上传:在左侧本地栏选中文件后点击“上传”;未选择文件时点击“上传”会打开系统原生文件选择器。
|
||||
- 下载:在右侧远程栏选中文件后点击“下载”。下载按钮在未选择远程文件时保持禁用。
|
||||
- 文件右键菜单也提供对应的“上传”或“下载”操作。
|
||||
- 可直接把左侧本地文件拖到右侧远程栏上传,也可把右侧远程文件拖到左侧本地栏下载;拖到目录行时以该目录为目标,并显示落点高亮。
|
||||
- 上传:在左侧本地栏选中文件后点中间「上传」箭头;未选择文件时会打开系统原生文件选择器。
|
||||
- 下载:在右侧远程栏选中文件后点中间「下载」箭头;未选择远程文件时下载保持禁用。
|
||||
- 文件右键菜单也提供对应的「上传」或「下载」操作。
|
||||
- 可把左侧本地文件拖到右侧远程栏上传,也可把右侧远程文件拖到左侧本地栏下载;拖到目录行时以该目录为目标,并显示落点高亮。系统未提供拖拽路径时,请改用中间箭头或文件选择器。
|
||||
- 当前拖拽只支持单个文件,不递归传输目录;同侧拖拽不会执行移动或重命名。
|
||||
- 远程文本编辑的“打开/保存”直接读写远程文件,不会在本地创建同名文件,也不等同于上传或下载。
|
||||
- 传输失败会在传输队列和界面通知中显示 Rust/SFTP 返回的具体原因。
|
||||
- 远程文本编辑直接读写远程文件,不会在本地创建同名文件,也不等同于上传或下载。可编辑类型按扩展名排除归档/二进制等;单文件约 **2MB** 上限,超限、二进制或非 UTF-8 会提示并拒绝打开,请下载后用本地编辑器处理。
|
||||
- 上传/下载若目标已存在同名项,会询问「覆盖」或「跳过」;失败或取消的任务可在传输队列里一键重试。
|
||||
- SSH 断线后,SFTP 一键重连会优先回到断线前的远程目录;进行中的传输会标为失败,可重试。终端标签本身也支持一键重新连接(及可选自动重连)。
|
||||
- 刷新时状态栏显示「正在刷新…」,传输忙时浏览类操作会立即返回忙提示而不是卡住界面。
|
||||
- 传输失败会在传输队列和界面通知中显示经多语言映射后的原因。
|
||||
|
||||
当前目标文件采用覆盖语义。内容哈希校验和显式冲突选择仍在路线图中。
|
||||
|
||||
@@ -122,7 +129,7 @@ SFTP 使用双栏文件管理器。上传和下载先写入 `.opsx-part` 临时
|
||||
|
||||
## 界面语言
|
||||
|
||||
设置中可切换中文(zh-CN)与 English。首次启动按系统语言自动选择;验收与单元测试默认中文文案。
|
||||
设置中可切换:简体中文(zh-CN)、繁体中文(zh-TW)、English、日本語、한국어、Tiếng Việt、Русский。首次启动按系统语言自动选择;新增可见文案须同步全部语种,并由 `test/i18n/localeKeys.test.ts` 校验 key 对齐。验收与单元测试默认中文文案。
|
||||
|
||||
## 本地数据
|
||||
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
# 产品体验与基础能力全面评估
|
||||
|
||||
> 更新:2026-07-31
|
||||
> 目标:OpsXShell 做成“麻雀虽小、五脏俱全”的轻量 SSH/SFTP 工具。常用操作直接、结果明确、失败可恢复,不用花哨概念增加学习成本。
|
||||
|
||||
## 评估结论
|
||||
|
||||
当前开发分支已具备 SSH、SFTP、串口、分屏、批量命令、SOCKS5、跳板和 AI Agent 的完整产品骨架,已经不是功能演示,但距离可长期替代 Tabby、Netcatty、Xshell 或 WindTerm 仍有一段可靠性和跨平台发布差距。
|
||||
|
||||
综合评分为 **7.1/10**。评分针对当前代码和自动化基线,不等于正式安装包质量;Windows 实机、macOS 安装版、断网/休眠和真实大文件传输未统一验收前,不能按成熟商业终端评价。
|
||||
|
||||
| 维度 | 分数 | 判断 |
|
||||
| ------------------ | ---: | ---------------------------------------------------------------------------------- |
|
||||
| 产品聚焦 | 8.5 | SSH/SFTP/代理/串口边界清楚,没有堡垒机、审计和 CMDB 噪音 |
|
||||
| 首次连接与会话管理 | 7.8 | 快速连接和保存会话路径短,支持密码、私钥、代理和跳板 |
|
||||
| 终端基础体验 | 7.2 | 复制粘贴、右键、分屏、广播和 Shell 生命周期已补齐;搜索和高压稳定性仍不足 |
|
||||
| SFTP | 6.8 | 双栏、双向拖拽、上传下载、权限和远程编辑已具备;冲突、重试和任务恢复不足 |
|
||||
| 隧道与 SOCKS5 | 7.5 | 规则与运行实例分离、真实启停和状态统计方向正确;重连和复用还需压测 |
|
||||
| 批量运维 | 7.0 | 多主机选择、并发、逐机结果清楚;取消和独立超时未完成 |
|
||||
| AI Agent | 6.8 | 单入口、当前 SSH 执行、风险模式和 ReAct 基线可用;执行内核仍在 React,真正取消不足 |
|
||||
| 性能与可靠性 | 6.2 | Tauri/Rust 基础占优,但断网、休眠、大输出和频繁切换仍缺持续压测 |
|
||||
| 跨平台发布 | 5.8 | macOS/Windows 构建脚本已具备;Windows 实机、签名、公证、更新和崩溃诊断未闭环 |
|
||||
| 文档与自动化 | 7.8 | 有契约、组件、Rust 和真实探针分层;仍需把实机矩阵纳入每次候选发布 |
|
||||
|
||||
## 产品主旨
|
||||
|
||||
OpsXShell 的默认界面只围绕七件事:连接主机、管理会话、操作终端、传输文件、开隧道、批量执行、必要时让 AI 在当前主机协助处理。
|
||||
|
||||
必须坚持:
|
||||
|
||||
1. 高频动作一步可达,高级选项默认收起。
|
||||
2. 当前操作目标始终可见,尤其是广播、批量命令、SFTP 和 AI 执行。
|
||||
3. 成功、进行中、失败、断开是四种不同状态,不能只靠颜色或开发日志表达。
|
||||
4. 空闲操作不滥用确认框;删除、覆盖、关闭运行任务和高风险 AI 命令才确认。
|
||||
5. 不保存终端命令、广播输入、批量命令、AI 对话或工具输出。
|
||||
6. 不加入审计、录像、审批、CMDB、独立 podexec 或 Kubernetes 凭据。
|
||||
|
||||
## 大众操作习惯基线
|
||||
|
||||
### 鼠标与窗口
|
||||
|
||||
- 单击负责选择和聚焦,双击负责打开会话/目录或切换窗口最大化,不能让一次双击触发两次相反操作。
|
||||
- 右键必须显示与当前位置相关的菜单;普通区域不得出现 WebView 的 Reload/Inspect Element。
|
||||
- macOS 使用原生红黄绿窗口控制,Windows 使用系统最小化/最大化/关闭;标题栏空白区可拖动。
|
||||
- 拖拽必须显示源、目标和允许/禁止状态;文件落到目录行时传入该目录,落到空白区时传入当前目录。
|
||||
|
||||
### 键盘
|
||||
|
||||
| 动作 | macOS | Windows/Linux |
|
||||
| -------------------- | -------------- | ------------------------------------------------- |
|
||||
| 复制/粘贴终端 | `Cmd+C/V` | `Ctrl+Shift+C/V` |
|
||||
| 普通输入框复制/粘贴 | `Cmd+C/V` | `Ctrl+C/V` |
|
||||
| 新建会话 | `Cmd+N` | `Ctrl+N` |
|
||||
| 快速连接 | `Cmd+K` | `Ctrl+K` |
|
||||
| 折叠/展开侧栏 | `Cmd+B` | `Ctrl+B` |
|
||||
| 关闭标签 | `Cmd+W` | `Ctrl+W` |
|
||||
| 分屏 | `Cmd+D` | `Ctrl+D`,但必须避免与远端 EOF 语义冲突并允许改键 |
|
||||
| 终端搜索 | `Cmd+F` | `Ctrl+F` |
|
||||
| 开发工具(开发构建) | `Cmd+Option+I` | `F12` |
|
||||
|
||||
- 侧栏折叠采用**完全隐藏**(专心终端):折叠后不保留图标窄轨。会话树是主内容而非 IDE 工具切换条;折叠后靠 `Cmd/Ctrl+B`、标签栏左侧展开按钮恢复。快速连接继续走 `Cmd/Ctrl+K`,不依赖侧栏可见。
|
||||
- 快捷键不能抢占输入框的复制、粘贴、全选、撤销和输入法组合状态。
|
||||
- 菜单和提示必须显示当前平台实际快捷键,不能同时展示两套组合键让用户猜。
|
||||
- `Escape` 关闭当前最上层弹框/菜单;`Enter` 触发主动作,文本域需要明确换行组合键。
|
||||
|
||||
### 表单
|
||||
|
||||
- SSH 目标允许直接粘贴 `user@host:port`,端口默认 22。
|
||||
- 保存会话只展示“密码/密钥”两个常用认证入口;代理、跳板、标签和启动命令放在高级区。
|
||||
- 端口、路径和 Endpoint 在失焦或提交时给出就地错误,不能无提示恢复默认值。
|
||||
- 取消或重新打开快速连接、批量命令、AI 面板时,敏感输入必须清空。
|
||||
- 按钮文案说明结果,如“连接”“创建并保存”“执行到 3 台”,避免只显示含义不明的图标。
|
||||
|
||||
### 状态与错误
|
||||
|
||||
- 错误必须包含“什么失败、作用于谁、如何恢复”,例如“Host A 命令超时,可重试”,而不是 `unknown`。
|
||||
- 剪贴板失败、广播目标变为 0、Shell 已退出、隧道端口占用和 SFTP 冲突必须在界面提示。
|
||||
- 重试不能重复创建连接、Shell、SFTP 通道或 Listener;状态必须以 Rust 真实资源为准。
|
||||
- 加载超过 300ms 显示进行中,超过设置超时显示具体阶段;不能无限转圈。
|
||||
|
||||
## 核心用户旅程
|
||||
|
||||
| 旅程 | 目标操作长度 | 当前状态 | 验收标准 |
|
||||
| ----------- | ----------------------------: | -------------- | ------------------------------------------------------- |
|
||||
| 临时连接 | 快捷键 → 粘贴 → 回车 | 已实现 | `user@host:port` 可粘贴;取消重开后密码为空 |
|
||||
| 保存会话 | 新建 → 目标/凭据 → 保存 | 已实现 | 默认 22;常用项不超过一屏;错误就地显示 |
|
||||
| 重复连接 | 双击侧栏会话 | 已实现 | 单击只选择,双击只打开一个终端标签 |
|
||||
| 终端操作 | 右键或快捷键 | 已实现 | 复制、粘贴、全选、清屏、分屏、最大化、关闭均明确 |
|
||||
| 多终端广播 | 开广播 → 输入 | 已实现,待增强 | 覆盖所有打开 SSH Shell,显示目标数,本地 Shell 永不参与 |
|
||||
| 批量命令 | 选主机 → 命令 → 执行 | 已实现,待增强 | 最多并发 5,逐机结果和耗时;关闭后命令销毁 |
|
||||
| SFTP | 会话右键 → SFTP 文件 | 已实现,待实机 | 本地↔远程拖拽、按钮和右键都走明确 upload/download 方向 |
|
||||
| SOCKS5 | 会话 → 转发 → 启动 | 已实现,待压测 | 默认 `127.0.0.1:1080`;停止后真实端口不可连接 |
|
||||
| 串口 | 快速启动 → 串口 → 参数 → 连接 | 已实现,待实机 | 可枚举设备,默认常用参数,断开和重连状态明确 |
|
||||
| AI 处理任务 | 当前 SSH → AI → 描述 → 执行 | 实验可用 | 目标固定、安全模式明确、critical 硬拒、关闭后上下文销毁 |
|
||||
|
||||
## 当前已完成的基础修正
|
||||
|
||||
- 全局广播覆盖所有打开且已连接的 SSH 标签与分屏,排除本地 Shell;目标不足两个时自动关闭。
|
||||
- 终端右键菜单包含复制、粘贴、全选、清屏、向右/向下分屏、最大化/恢复和关闭。
|
||||
- 关闭分屏会调用 Rust `ssh_close_shell`,远端关闭失败会记录明确错误,不只移除前端格子。
|
||||
- 远端 Shell 的 EOF、`TMOUT` 和 `Ctrl+D` 不再等同整个 SSH 连接断开,可只重开当前 Shell。
|
||||
- 批量命令支持搜索、全选当前结果、调整目标、最大并发 5、逐机状态/输出/耗时和总进度。
|
||||
- 快速连接和批量命令重新打开会清空敏感输入,结果不落盘。
|
||||
- Agent 支持严格、均衡、宽松三级安全模式;默认均衡只确认 high,critical 永久硬拒绝。
|
||||
- 普通 WebView 区域禁止 Reload/Inspect Element,文本输入保留系统编辑菜单。
|
||||
- 应用版本由 `package.json` 构建时注入,不再在状态栏硬编码旧版本。
|
||||
|
||||
## P0:下一候选版本必须完成
|
||||
|
||||
| ID | 优化项 | 当前缺口 | 完成标准 |
|
||||
| ----- | --------------------- | -------------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| P0-01 | 连接生命周期压测 | 断网、睡眠唤醒、快速切标签和连接复用证据不足 | 自动覆盖连接/重连/挂起/恢复;100 次切换无重复连接和监听器泄漏 |
|
||||
| P0-02 | 终端搜索接通 | `SearchAddon` 已加载,但分屏工作区没有可用搜索 UI | `Cmd/Ctrl+F` 搜索当前焦点分屏,支持上一项/下一项/关闭 |
|
||||
| P0-03 | 终端高输出稳定性 | 仍出现过 CPU 高占用和操作卡顿 | 持续输出 10 分钟 UI 可操作;后台标签限流;CPU/内存有基准阈值 |
|
||||
| P0-04 | 用户可见 I/O 错误 | 部分剪贴板、关闭 Shell 和事件错误只写日志 | toast/覆盖层说明失败对象和恢复动作;不得产生未处理 Promise |
|
||||
| P0-05 | SFTP 基础传输实机门禁 | 自动测试有方向契约和探针,但真实安装版仍需重复验证 | 上传、下载、覆盖、目录落点、拖拽、取消后临时文件处理全部通过 |
|
||||
| P0-06 | SFTP 冲突规则 | 同名文件处理不够显式 | 每次任务可选择覆盖/跳过/重命名;目录递归不静默覆盖 |
|
||||
| P0-07 | 批量任务超时与取消 | 当前只能等待 worker 完成 | 区分连接/命令超时;停止后不再启动新主机,当前命令标为等待完成 |
|
||||
| P0-08 | 隧道重连与清理 | Listener 真实启停已做,网络恢复策略不足 | 主连接断开立即清理;重连后按用户选择恢复;端口冲突显示占用地址 |
|
||||
| P0-09 | 最小窗口适配 | 960×720 基础可用,AI 打开后终端区域偏窄 | 960×640 无遮挡;打开 AI 时可自动收起侧栏或提供一键扩展 |
|
||||
| P0-10 | 双平台安装验收 | macOS 结果不能代表 Windows | macOS arm64 与 Windows x86_64 分别完成安装、升级、卸载和核心冒烟 |
|
||||
|
||||
## P1:提升日常效率
|
||||
|
||||
| ID | 优化项 | 建议 |
|
||||
| ----- | --------------- | ----------------------------------------------------------------------------- |
|
||||
| P1-01 | 广播目标预览 | 点击目标数查看主机/分屏,允许本次临时排除;默认仍是全部打开 SSH |
|
||||
| P1-02 | 批量失败重试 | 一键仅重试失败主机,可从分组/标签建立目标集合 |
|
||||
| P1-03 | 终端标题与路径 | 安全解析 OSC 标题/当前目录,允许锁定会话名,防止远端伪装安全提示 |
|
||||
| P1-04 | 关闭保护 | 仅当前台有运行任务时提示关闭会结束远端 Shell;空闲时一步关闭 |
|
||||
| P1-05 | SFTP 任务中心 | 统一暂停/继续/取消/重试,显示速度、剩余时间和失败原因;重启后可恢复未完成任务 |
|
||||
| P1-06 | SFTP 易用性 | 多选拖拽、复制路径、在终端打开目录、远程编辑冲突提示、校验和验证 |
|
||||
| P1-07 | SSH Config 导入 | 展示将导入字段、冲突处理和不可支持项;支持 ProxyJump 链预览 |
|
||||
| P1-08 | 隧道便捷入口 | 状态栏一键查看/复制 SOCKS5 地址;复制规则永不复制运行态 |
|
||||
| P1-09 | Agent Runtime | 从 React 抽离状态机,增加单步超时、真正取消、结构化 tool calling 和 eval |
|
||||
| P1-10 | 无障碍 | 所有图标按钮有名称;焦点圈清楚;弹框焦点锁定/返回;状态不只靠颜色 |
|
||||
|
||||
## P2:专业兼容与发布闭环
|
||||
|
||||
- Agent Forwarding、OpenSSH 证书、FIDO2 和更完整的算法策略。
|
||||
- 保存常用分屏布局,但不保存 Shell ID、命令或终端输出。
|
||||
- 隧道使用明确的共享连接/Multiplexer 策略,避免每个请求重新握手。
|
||||
- macOS Developer ID 签名与公证、Windows Authenticode、自动更新清单和回滚。
|
||||
- 用户主动导出的脱敏诊断包:版本、平台、错误码、资源统计,不包含命令、密码和终端输出。
|
||||
- 可选主题和键位导入;不为了生态而引入重量级插件框架。
|
||||
|
||||
## 明确不做
|
||||
|
||||
- 不恢复命令历史,不持久化广播、批量命令或 Agent 输入输出。
|
||||
- 不增加堡垒机审计、审批流、录像、CMDB、告警大盘或独立 podexec。
|
||||
- 不使用“有选区右键复制、无选区右键直接粘贴”这类隐藏行为。
|
||||
- 不让本地 Shell 加入远程广播,不允许 `ssh://` 携带密码或静默连接。
|
||||
- 不为“专业感”堆无用途状态卡、动画、统计图和多级配置。
|
||||
|
||||
## 统一回归场景
|
||||
|
||||
1. 快速连接粘贴 `root@opsbase.cn:55555`,取消后重开,目标和密码为空;通过 `ssh://` 唤起时只预填安全目标。
|
||||
2. 新建会话默认端口 22,密码/密钥切换不会把另一种凭据落盘;编辑高级配置不影响基础字段。
|
||||
3. 打开两个 SSH 标签,其中一个分两屏;广播输入 `date`,三个远端各收到一次,本地 Shell 不收到。
|
||||
4. 关闭一个分屏,Rust Shell 释放,广播目标立即减少,兄弟分屏、SFTP 和隧道保持可用。
|
||||
5. 终端右键复制、粘贴、全选、清屏、向右/向下分屏、最大化/恢复和关闭均可用,无 Reload/Inspect Element。
|
||||
6. `Cmd/Ctrl+F` 只搜索当前焦点分屏;切换分屏后结果随焦点切换。
|
||||
7. 批量选择两台执行 `date`,逐机显示耗时和结果;停止后不启动剩余主机;关闭重开命令为空。
|
||||
8. SFTP 按钮上传、右键上传、本地拖到远程、远程拖到本地结果一致;文件逐字节校验成功。
|
||||
9. 同名文件明确选择覆盖/跳过/重命名;失败不留下被误认为完整文件的目标。
|
||||
10. 启动 `127.0.0.1:1080` SOCKS5,代理请求成功且统计变化;停止后端口不可连接,重启应用显示未运行。
|
||||
11. 远端 `TMOUT` 只关闭当前 Shell,一键重开可用,SSH connection 和其他资源不被误断。
|
||||
12. Agent 均衡模式自动执行 `df -h`,`systemctl restart nginx` 先确认;严格模式修改文件先确认;宽松仍拒绝 `rm -rf /`。
|
||||
13. 断网后状态由“已连接”进入“重连中/失败”,恢复后不重复创建标签、连接、Shell 或 Listener。
|
||||
14. macOS 窗口可拖动,双击标题栏只切换一次最大化;Windows 系统按钮、快捷键和安装卸载符合平台习惯。
|
||||
15. 960×640、125%/150% Windows 缩放以及长主机名、中文分组下,无按钮遮挡、水平溢出或不可达操作。
|
||||
|
||||
## 发版判定
|
||||
|
||||
自动化全绿只代表代码门禁通过。候选发布还必须分别在 macOS arm64 和 Windows x86_64 完成上述核心旅程,并记录版本、安装包哈希、测试平台、失败项和回归结果。任何“只能偶现”“重试一般能好”的连接、终端输入、SFTP 或隧道问题都按未通过处理。
|
||||
Reference in new issue
Block a user