7.3 KiB
7.3 KiB
OpsXShell 开发指南
轻量运维桌面终端(Tauri 2 + Rust + React + TS)。强调短路径好用;不做审计、审批、堡垒机。
请使用中文沟通。改功能后优先 npm run test:patrol。
产品形态(硬边界)
浏览器 → 官网/docs 为独立静态站(homepage/dist,可部署自有域名;本地 :8789 亦可预览)
操作 → 只走桌面 Tauri(./run.sh gui)
Vite :5175 → 仅桌面 WebView 源,不是浏览器产品
| 职责 | 放哪 |
|---|---|
| 桌面操作(SSH/SFTP/转发/RDP/VNC/串口/本地终端/AI) | 本仓 src/ + src-tauri/ |
| 产品官网 + 用户文档 | 本仓 homepage/(静态站源 → tools/homepage-build 出 dist) |
| 结账 / 在线授权 | 独立服务 opsx-licence;桌面只验 LIC- / LICOFF- |
同族对照:opsxdb / opsxapi 同形态(浏览器=官网/docs,操作=桌面)。Shell 的 Gin 只有 health/download + 本地静态托管 homepage/dist 预览,没有操作 API——原生能力全在 Rust。
src/ 里的 React 是 Tauri WebView UI,不是浏览器 SaaS 客户端。
目录对齐说明
- 已对齐:根级
src/+src-tauri/+server/+homepage/+tools/homepage-build,./run.sh web|gui,Vite :5175。 - 不要重建已废弃的
apps/、packages/、仓库根release/、.ui-review/(db/api 旧 monorepo 空壳)。语义已统一,勿再把src//src-tauri/迁回apps/web/apps/desktop。 - 安装包走 Tauri 2 标准目录
src-tauri/target/{debug,release}/bundle/(指定 triple 时为src-tauri/target/<triple>/release/bundle/)。不要再造仓库根release/发版暂存;框架给了标准路径就用标准路径。./run.sh gui是tauri dev裸二进制,macOS Dock 可能显示默认图标——这是 Tauri 开发态通病,不是缺根目录release/,正式.app/ DMG 图标以bundle.icon为准。
架构(怎么改代码)
UI / Zustand → src/platform/* → Tauri command → src-tauri/src/services/*
server → Gin:/health · /download + 静态托管 homepage/dist(无操作面)
src/features/:逐步提取功能域模型、Hook 和控件;目前从 settings 开始,页面仍在components/,不要求整仓搬目录。src/platform/:唯一invoke/ 事件入口;组件与 store 不直接invoke,复用platform/invoke.ts,不另建lib/tauri.ts。src-tauri/src/commands/:参数边界 + 统一响应;业务在services/。shared/types/:前后端契约;新能力先契约再 command,再补desktop.d.ts/platform/test/setup.ts。- 文案:
src/i18n七语种同步;test/i18n/localeKeys.test.ts校验 key。 - 官网落地页 + 用户文档:
homepage/(改完跑tools/homepage-build重新生成 dist)。Gin 只静态托管homepage/dist,不要把文档源塞回server/。
扩展顺序:契约 → services → command → platform → UI → 测试。
IPC
- 业务失败(SSH/SFTP/转发/会话/本地文件):信封
{ success, error, errorCode? }。 - RDP/VNC 运行态:throw,视图里 catch。
invokeNative将拒绝转换为NativeCommandError,保留错误码与原始原因;业务失败信封仍由调用方检查success。 - Rust 错误复用
domain/error.rs的AppError/codes;目前仅部分文件操作接入,不代表全量迁移完成。 - 文件对话框 command 须在主线程;磁盘 I/O 用
spawn_blocking。
硬边界(少而硬)
- 界面不展示 Rust 未实现的能力。
- 密码 / 私钥口令 / 代理密码:Rust 加密落盘;主密钥
~/.opsxshell/master.key(Unix0700/0600)。 - 不保存终端命令历史;批量结果仅当前窗口。
- known_hosts 校验;
ssh://禁止带密码或静默直连(走快速连接确认队列)。 - 转发:规则可持久化,运行态不落盘;停止必须关掉真实 Listener;改运行中规则先停 Listener。
- 会话运行态(SSH/转发/RDP/VNC worker)只在原生内存;断开即清理桌面 worker。
- 不把结账/签发、CLI/MCP/插件宿主、堡垒机审批做成默认能力。
- 不恢复旧 Electron 桌面壳、旧构建链。
- 不要把桌面操作做成浏览器工作台;
:5175不是对外入口。
领域要点(细节跟现有代码,勿另起炉灶)
- 隧道:
TunnelManager统一持有/取消;同窗重连可 orphan-adopt /forwardIntent;关标签不自动再启。SOCKS5 默认127.0.0.1,每主机一条动态规则。 - SSH/SFTP:协议心跳保链路(勿向 Shell 灌回车空格);意外断开有限次重连;SFTP 分清 upload/download 与路径方向。
- RDP/VNC:仅桌面端;有限次重连;压缩/帧路径跟
services/desktop/,勿新开解压栈。 - AI:新配置先临时凭据实测再落盘;远程执行只复用当前 SSH;critical 硬拒绝。
- 设置与主题:设置经
settingsStore串行保存,失败撤回对应修改并保留后续待保存项;不要绕过 store 并发写app-settings。主题复用themes/app-theme.ts与useTheme。 - 授权:只对接 opsx-licence;本地验
LIC-/LICOFF-。
实现时优先对照邻近模块与单测,而不是在本文件追加细则。当前分层与未完成项见 架构说明 和 重构进度。
命令
./run.sh # = web:官网 + docs → :8789
./run.sh web # 同上
./run.sh gui # 桌面操作入口(默认顺带起 Gin)
./run.sh stop | status
npm run test:patrol # 改功能优先
npm run acceptance:quick # 或 acceptance:full
./scripts/build.sh # 当前平台安装包 → src-tauri/target/<triple>/release/bundle/
./scripts/macos-notarize.sh # 新 DMG 公证(有凭据时)
无签名凭据时不要宣称已签名/公证/自动更新。打包须在目标 OS 实机验收。
给 AI 的协作原则
- 先做再问:需求清楚就直接改;不确定时用最小假设推进,并在回复里写明假设。
- 跟仓内模式:新功能对齐现有
platform/services分包,禁止平行架构。 - 少造文档:非用户要求不要新增长篇 markdown;改行为同步必要注释即可。
- 测试够用:功能改动跑 patrol + 相关单测;不必为每个微规则再加一篇规范。
本地数据路径规则(三族统一)
- 用户数据(连接配置/集合/AI key/驱动 jar):纯 Rust 项目走 Tauri
app_data_dir()(平台规范);有 Go sidecar 的走~/.<程序名>/dotfile(程序名叫什么目录就叫什么,如本项目~/.opsxshell/;Go 拿不到 Tauri 路径 API,dotfile 是最干净方案)。同一项目用户数据只允许一处,跟着能力层走。 - 壳状态(窗口位置等可丢弃项):
app_data_dir(),由 tauri 插件自管。 - 禁止相对路径存数据(桌面 cwd 不定,数据会散落)。