Files
opsxshell/AGENTS.md
T
Logan.LiandCursor 08696896f9 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>
2026-08-16 16:08:11 +08:00

71 lines
5.7 KiB
Markdown
Raw 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.
# OpsXShell 开发指南
OpsXShell 是基于 Tauri 2、Rust、React 和 TypeScript 的轻量运维终端。产品强调便捷、人性化、操作简单实用,不加入审计、审批或堡垒机功能。
## 架构
- `src/`:React 界面、Zustand 状态和 XTerm.js 终端。
- `src/i18n/`:界面文案(zh-CN / zh-TW / en / ja / ko / vi / ru);新增可见字符串必须同步全部语种,并用 `test/i18n/localeKeys.test.ts` 校验 key 对齐。
- `src/platform/`:唯一的 Tauri 命令与事件适配入口。
- `src/platform/sftp.ts`:固定 `localPath`/`remotePath` 方向,区分远程文本读写与文件传输。
- `src/platform/rdp.ts` / `src/platform/vnc.ts`:远程桌面会话适配;运行态只在原生侧内存中。
- `src/utils/terminalPipeline.ts`:终端输入、UTF-8 输出、背压和错误边界。
- `src-tauri/src/commands/`:精简命令边界和统一响应。
- `src-tauri/src/services/`:SSH、SFTP、隧道、PTY、串口、桌面、存储和凭据服务。转发 Listener 必须由 `TunnelManager` 统一持有和取消。
- `src-tauri/src/services/ssh/`:认证、known_hosts、代理/跳板、路径和 SFTP,禁止重新堆回 `ssh.rs`。
- `src-tauri/src/services/tunnel/`:运行模型、SOCKS5 协议和 Relay;运行态只能由 `TunnelManager` 持有。
- `src-tauri/src/services/desktop/`:RDP(IronRDP)与 VNC(vnc-rs);帧、输入、剪贴板经 Tauri 事件交给 Canvas,断开即取消 worker。RDP 批量压缩优先 RDP5(MPPC/K64),避免 XCRUSH 在分辨率切换后解压失败。
- `shared/types/`:渲染层共享 TypeScript 契约。
- `test/`:Vitest 单元/组件测试与基础巡检(`test/patrol/`:SSH / SFTP / RDP / VNC);改功能后优先 `npm run test:patrol`。
- `scripts/`:本地启动、验收、版本同步与原生安装包构建/发布脚本(入口 `./run.sh`、`./scripts/build.sh`)。
- `docs/`:使用、架构、验收与发布文档;路线图与任务见根目录 `ROADMAP.md` / `TASKS.md` / `TDD_PLAN.md`。
- `license-server/`:授权与结账服务(独立 Node 包)。
React 不直接访问 SSH、文件系统或加密实现。数据流:UI → Zustand → `src/platform/*` → Tauri command → `src-tauri` 服务。新增原生能力时先定义 Rust command,再更新 `src/desktop.d.ts`、对应 `src/platform/*.ts` 和 `test/setup.ts`。
## 怎么扩展
1. 领域契约:先改 `shared/types/` 或 Rust domain,再改 command。
2. 原生实现:能力放 `src-tauri/src/services/`,command 只做参数边界和统一响应。
3. 渲染适配:只经 `src/platform/`;组件和 store 不直接 `invoke`。
4. 界面:Zustand 持有资源 ID 与 UI 状态;可见文案同步七语种。
5. 测试:功能改动优先 `npm run test:patrol`,再补对应单测。
## 规则
- 未由 Rust 后端实现的能力不能在界面中显示为可用。
- 会话密码、私钥口令和代理密码必须由 Rust 加密后落盘。
- 不保存终端命令历史;批量命令结果仅保留在当前窗口。
- 主机密钥使用 `~/.ssh/known_hosts` 校验。
- 主密钥位于 `~/.opsxshell/master.key`,Unix 目录权限 `0700`、文件权限 `0600`。
- 保持常用流程简短,高级配置默认收起。
- 端口转发规则可持久化,运行中状态不得持久化;界面的停止操作必须关闭真实原生 Listener。
- 复制转发规则不得复制运行态;运行中的规则修改前必须先停止 Listener。
- SSH 断开 / keepalive 失败 / 空闲挂起 / 同窗重连:未点「停止」的转发 Listener 应保留;按 `user@host:port` 指纹 orphan-adopt;同窗用进程内 `forwardIntent` 自动恢复;关标签不得自动再启。空闲挂起应先断开原生会话并 `retainForwards`,避免僵尸 TCP。
- 动态转发(SOCKS5)默认仅本机 `127.0.0.1:1080`;流量经当前 SSH 服务器出口 IP 访问外网。每台 SSH 主机仅保留一条动态规则。状态栏「转发」打开抽屉管理,右键复制 `socks5://127.0.0.1:1080`。
- 本地转发监听默认本机端口;远程转发监听默认远端 `127.0.0.1`。远程 `0.0.0.0` 需 sshd `GatewayPorts`,未开启时常静默只绑 loopback。
- SFTP read/write 不得作为 upload/download 的别名,本地路径与远程路径不得使用位置含糊的调用。
- RDP / VNC 仅在 Tauri 原生应用中可用;会话运行态不落盘,断开即清理。批量命令排除桌面会话。
- 大模型新配置必须先用临时凭据完成真实测试,测试期间不得写 settings 或 secrets;连接字段变化后保存必须重新锁定。
- AI 远程执行只能复用当前活跃 SSH connection;按 strict/relaxed(严格/宽松)模式决定确认阈值,critical 始终硬拒绝;不建立独立 podexec/Kubernetes 凭据边界,也不保存命令或工具输出。
- `ssh://` 禁止携带密码或静默直连;冷启动与运行中唤起都必须通过原生有界队列交付给快速连接确认。
## 命令
```bash
./run.sh # 开发启动(scripts/run.sh)
npm run test:patrol
npm run acceptance:quick
npm run acceptance:full
./scripts/build.sh # 当前平台安装包(macOS → .app + .dmg)
```
平台安装包必须在目标系统实机验收。没有签名凭据时不得宣称完成签名、公证或自动更新发布。
## 评审边界
- `src/platform/` 与 Tauri command 是本应用内部边界,不是给第三方调用的公共 API。
- `license-server/` 独立于客户端;不要把结账/授权服务逻辑堆回桌面进程。
- 不把 CLI、MCP、插件宿主或堡垒机审批做成默认能力。
- 转发 Listener、SSH 会话、RDP/VNC worker 的运行态只在原生侧内存;评审时以「停止是否关掉真实资源」为准。