chore: 官网拆分 homepage + 关于页瘦身 + 端口 5175(当前可用状态基线)

This commit is contained in:
Logan.Li committed 2026-10-14 20:31:51 +08:00
1 parent 5eb11826db
commit be151cb68f
85 files changed
+4420 -1530

No files matched your search

+9
View File
@@ -1,5 +1,14 @@
# opsxshell docs
开发规则以根目录 [AGENTS.md](../AGENTS.md) 为准,[CLAUDE.md](../CLAUDE.md) 为短入口。
- [架构说明](architecture.md):当前分层、状态与原生生命周期
- [架构重构](architecture-refactor.md):已完成部分与待实施轨道
- [测试与验收](testing-acceptance.md):巡检、针对性测试和实机验收
- [使用指南](user-guide.md) · [发布](release.md)
以下为 AI 专题:
| 文档 | 说明 |
| --------------------------------------------------------------------- | ----------------------------------------- |
| [01-AI-Agent步数预算与incomplete](01-AI-Agent步数预算与incomplete.md) | MAX_AGENT_STEPS=12 与 incomplete/续跑目标 |
+6 -4
View File
@@ -1,12 +1,14 @@
# 架构重构(单独轨道,尚未开始)
# 架构重构(渐进推进)
**当前不要做。** 改动面覆盖几乎全部 `src-tauri` 服务、`src/desktop.d.ts`、`src/platform/*` 和测试替身。本文件只记录怎么拆,避免和日常功能 PR 缠在一起。
局部职责拆分已开始;下述 EventSink、契约生成和 infrastructure 端口仍是待实施方案。不要把已完成的局部改造当成全仓迁移,也不要顺带引入平行架构。
已落地:本地文件业务下沉至无 Tauri 依赖的 `services/files.rs`;`AppError` 部分接入;前端 IPC 拒绝错误统一映射;settings 功能模型、Hook 和控件提取;设置串行保存与失败回退;系统主题同步修复。实现位置与限制见 [架构说明](architecture.md)。
当前真实分层是 **commands → services → domain DTO**。目录里虽有 `application/`、`infrastructure/`,但:
- `infrastructure/` 只有 `file_log`,services 并不走它。
- `application/state.rs` 是服务集合,不是端口组合根。
- 稳定 IPC 错误码放在 `domain/error.rs` 的 `codes`(如 `native.taskJoin`),不是空壳 `DomainError` 类型。
- `domain/error.rs` 已有稳定 IPC 错误码 `codes` 和部分接入的 `AppError`;尚未覆盖所有业务错误。
- SSH / 存储 / 桌面服务直接 `use tauri::AppHandle`;known_hosts 还用 `bind_app_handle` 全局 static。
- 前后端契约靠手写 `src/desktop.d.ts` + `shared/types/`,没有 specta / ts-rs。
@@ -66,7 +68,7 @@ pub trait EventSink: Send + Sync {
`infrastructure/mod.rs` 里现在的「SQLite / keychain / PTY 适配器」是过期注释,做 C 轨时改成与真实 trait 一致,没做的删掉,避免再写成已存在。
IPC 错误码继续用 `domain/error.rs` 的 `codes` 常量,不要再加一层空壳 `DomainError`。
IPC 错误继续扩展 `domain/error.rs` 的 `AppError` / `codes`,保留既有信封和运行态抛错契约,不另建重复错误类型。
## 明确不做(本轨道也不做)
+20 -1
View File
@@ -8,12 +8,14 @@ OpsXShell 是简单好用的原生运维终端:短路径完成连接、终端
```text
src/ React 界面、工作区和 Zustand 状态
src/features/settings/ 设置模型、快捷键录入 Hook 和设置控件(渐进拆分)
src/i18n/ 界面文案(zh-CN / zh-TW / en / ja / ko / vi / ru)与 locale 检测
src/platform/ Tauri command/event 适配层
shared/types/ 渲染层 TypeScript 契约
src-tauri/src/commands/ 参数边界和统一响应
src-tauri/src/domain/ Rust 领域模型
src-tauri/src/services/ SSH、SFTP、隧道、PTY、串口、桌面、AI、存储和安全策略
src-tauri/target/…/bundle/ Tauri 2 标准产物(debug/release 的 .app / dmg / nsis)
```
React 不直接访问 SSH、文件系统或加密实现。Rust 服务持有连接、Shell、SFTP、串口和桌面会话资源,渲染层只保存资源 ID 与界面状态。新增原生接口时必须同步更新:
@@ -22,7 +24,7 @@ React 不直接访问 SSH、文件系统或加密实现。Rust 服务持有连
2. `src/desktop.d.ts` 类型契约
3. 对应 `src/platform/*.ts` 适配实现(通用能力走 `desktop.ts`,RDP / VNC 走 `rdp.ts` / `vnc.ts`)
4. `test/setup.ts` 测试替身
5. 若有用户可见文案:同步 `src/i18n/locales/{zh-CN,en}/` 并保证 key 对齐
5. 若有用户可见文案:同步 `src/i18n/locales/` 七语种并保证 key 对齐
Rust SSH 服务保留 `ssh.rs` 作为连接与 Shell 门面,已将独立边界拆出:
@@ -49,6 +51,17 @@ services/
模块化只约束内部职责,不引入插件框架,也不把 libssh2 或桌面协议引擎资源暴露到 command 层。后续 connection/shell 拆分继续保持现有 Tauri command 契约不变。
## 已落地的职责边界
- 本地文件读写、目录列表、元数据和增删改在 `src-tauri/src/services/files.rs`,DTO 在 `domain/files.rs`;该 service 不依赖 Tauri。Command 负责调度 `spawn_blocking` 和返回失败信封;原生文件对话框仍在主线程。
- `domain/error.rs` 提供 `AppError` 和稳定错误码,目前部分文件操作接入。SSH、存储、桌面等 service 仍有 Tauri 依赖,全量错误迁移和 EventSink 尚未完成。
- `src/platform/invoke.ts` 统一调用与拒绝错误映射;`NativeCommandError` 保留 command、detail、errorCode、originalError。它不把业务失败信封自动抛出,也不统一弹 toast 或为所有原生操作添加超时。
- `features/settings/model.ts` 管默认值和归一化,`useKeyRecording.ts` 管录入生命周期,`SettingControls.tsx` 提供设置控件。`components/settings/SettingsView.tsx` 仍负责页面组合与部分交互;其他领域尚未全量迁入 features。
- `settingsStore` 串行处理加载与保存:已确认快照叠加待保存修改形成即时 UI,保存成功才更新确认快照,失败只撤回对应项并提示,不把失败修改写入后续快照。错误由 store 消化并通知,不能仅凭 `Promise<void>` 完成就判断保存成功。
- 应用主题沿用 `themes/app-theme.ts` 颜色 token;`useTheme` 同步系统偏好、返回的有效主题、DOM 和边框变量。主题偏好随设置保存;尚未完成全界面样式 token 化,也未验证冷启动异步加载设置时完全无闪烁。
剩余重构见 [架构重构](architecture-refactor.md)。
## 原生服务
| 能力 | 实现 |
@@ -173,3 +186,9 @@ SSH 传输本身受协议 MAC 保护;当前应用额外执行大小校验,
| Linux AppImage | 35 MB |
Release 使用 LTO、单 codegen unit、`panic = abort` 和符号剥离。平台功能必须在对应系统实机验收。
## 开发态 Dock 图标(已知限制)
`./run.sh gui` 走 `tauri dev`,macOS 启动的是 `src-tauri/target/debug/` 下的裸二进制。Dock 对非 `.app` 进程显示默认齿轮图标——这是 Tauri 通病,不是 `bundle.icon` 没配。正式 `tauri build` 的 `.app` / DMG 三族图标一致。
安装包与校验和只放在 `src-tauri/target/<triple>/release/bundle/`,由 `build.sh` / `release.py` 直接读写,不再拷到仓库根 `release/`。opsxapi 开发态正确 Dock 图标来自临时 `.app` 壳(`src-tauri/target/gui-app/`,刷 `icon.icns`)。要对齐开发态 Dock 图标应复用该壳,而不是另建发版目录。
+10 -10
View File
@@ -7,7 +7,7 @@
本机已打出 **Tauri 窗口布局** 的 Developer ID 签名 DMG(不是手搓 `hdiutil`,Finder 里是大图标 + 拖到 Applications):
```text
release/v2.1.1/macos-arm64/OpsXShell_2.1.1_aarch64.dmg
src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/OpsXShell_2.1.1_aarch64.dmg
```
这份包**还没公证、没 staple**。别人下载后仍可能被 Gatekeeper 拦。你这边只差公证:
@@ -49,11 +49,11 @@ scripts\build.bat v2.1.1 win-x64
./scripts/build.sh v2.1.1 mac-arm64 --quick
```
`scripts/build.sh` 与 `scripts/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` 留在 Tauri 2 标准目录:
```text
release/v2.1.1/macos-arm64/
release/v2.1.1/windows-x64/
src-tauri/target/aarch64-apple-darwin/release/bundle/ # macOS arm64:dmg/ + macos/*.app
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/ # Windows:nsis/ + msi/
```
平台安装包必须在目标系统构建和验证。macOS 不能替代 Windows x86_64 实机打包。
@@ -77,7 +77,7 @@ npm ci
scripts\build.bat v2.1.1 win-x64
```
默认执行完整门禁;`--quick` 适合开发期重复构建,正式发布不要使用 `--skip-checks`。输出位于 `release\v2.1.1\windows-x64\`。没有代码签名证书时可以生成开发安装包,但 Windows SmartScreen 可能提示未知发布者。
默认执行完整门禁;`--quick` 适合开发期重复构建,正式发布不要使用 `--skip-checks`。输出位于 `src-tauri\target\x86_64-pc-windows-msvc\release\bundle\`。没有代码签名证书时可以生成开发安装包,但 Windows SmartScreen 可能提示未知发布者。
## Gitee Release
@@ -91,15 +91,15 @@ scripts\build.bat v2.1.1 win-x64
./scripts/release.py v2.1.1
```
发布凭据从 `GITEE_TOKEN` 或 `~/.netrc` 的 `gitee.com` 条目读取,脚本不会输出 Token。脚本只读取 `release/v<版本>/` 下的 `.dmg`、`.exe`、`.msi` 和 `SHA256SUMS.txt`,上传成功后保留本地文件。远程已有同名同大小附件时会跳过;同名但大小不同时停止,避免静默覆盖已发布二进制。
发布凭据从 `GITEE_TOKEN` 或 `~/.netrc` 的 `gitee.com` 条目读取,脚本不会输出 Token。脚本只读取 `src-tauri/target/<triple>/release/bundle/` 下的 `.dmg`、`.exe`、`.msi` 和 `SHA256SUMS.txt`,上传成功后保留本地文件。远程已有同名同大小附件时会跳过;同名但大小不同时停止,避免静默覆盖已发布二进制。不要再使用仓库根 `release/`。
macOS App 位于:
```text
src-tauri/target/release/bundle/macos/OpsXShell.app
src-tauri/target/aarch64-apple-darwin/release/bundle/macos/OpsXShell.app
```
指定 `aarch64-apple-darwin` target 时,产物位于对应 target 的 `release/bundle` 下。
未指定 `--target` 时,产物在 `src-tauri/target/release/bundle/`。开发态 Dock 图标差异见 [架构说明](./architecture.md#开发态-dock-图标已知限制)。
## 临时 DMG
@@ -124,7 +124,7 @@ lsof +D /Volumes/<临时卷名>
## 签名、公证和自动更新
申请账号和 Developer ID、导入钥匙串的完整步骤见 [download/Apple开发者签名.md](../download/Apple开发者签名.md)。
申请 Developer ID 的说明见 [Apple Developer ID](https://developer.apple.com/developer-id/);本仓签名配置与公证方式如下。
**当前状态(本机可签 macOS;这份 DMG 待公证;自动更新仍未做):**
@@ -176,7 +176,7 @@ lsof +D /Volumes/<临时卷名>
# 先弹出已挂载的安装盘,再:
APPLE_ID='开发者邮箱' ./scripts/macos-notarize.sh
# 可选:指定 DMG 路径
APPLE_ID='开发者邮箱' ./scripts/macos-notarize.sh release/v2.1.1/macos-arm64/OpsXShell_2.1.1_aarch64.dmg
APPLE_ID='开发者邮箱' ./scripts/macos-notarize.sh src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/OpsXShell_2.1.1_aarch64.dmg
```
脚本会:已 staple 则退出;否则先 staple;没有票据才要 App 专用密码并 `notarytool submit --wait --timeout 15m`,超时仍 staple。开发者后台网页没有这份 DMG 的进度页,用终端或:
+38
View File
@@ -0,0 +1,38 @@
# 变更日志模板
> 每次发版:复制本模板到 `docs/CHANGELOG.md` 顶部,按类型归类填写;空分类整段删除。
> 提交信息与 PR 标题建议带同样 emoji,方便汇总时检索。
## vX.Y.Z(YYYY-MM-DD)
### ✨ 新增功能
-
### 🚀 优化改进
-
### 🐞 修复问题
-
### 🔨 破坏性变更
-
### 📖 文档
- ***
## Emoji 图例
| Emoji | 含义 | 用途 |
| ----- | ---------- | ------------------------------------ |
| ✨ | 新增功能 | 新能力、新入口、新引擎支持 |
| 🚀 | 优化改进 | 性能、交互打磨、UI 调整、重构 |
| 🐞 | 修复问题 | 缺陷修复、回归修复 |
| 🔨 | 破坏性变更 | 配置格式/接口/快捷键变更,需迁移说明 |
| 📖 | 文档 | 官网、帮助文档、架构文档更新 |
| ⚡ | 性能 | 单独标注显著性能提升(可并入 🚀) |
| 🗑️ | 移除 | 废弃功能下线 |
+14 -3
View File
@@ -2,7 +2,7 @@
## 本地门禁
日常开发执行:
改功能先跑 `npm run test:patrol` 和相关单测,再按范围执行验收:
```bash
npm run acceptance:quick
@@ -27,7 +27,7 @@ npm run acceptance:full
- Tauri 事件监听注册/销毁竞态
- SSH 连接关闭后的状态回收
- HTTP CONNECT、SOCKS5 和断点复制
- 转发规则不持久化运行状态,复制产生新 ID;原生隧道可启动、查询、停止并在 SSH 断开时清理
- 转发规则不持久化运行状态,复制产生新 ID;原生隧道可启动、查询、停止;按断开原因验证保留或清理
- 状态栏「转发」抽屉启停动态 `127.0.0.1:1080`,右键复制 SOCKS 地址;每台 SSH 主机仅一条动态规则
- i18n:全部 APP_LANGUAGES(zh-CN / zh-TW / en / ja / ko / vi / ru)的 namespace key 对齐(`test/i18n/localeKeys.test.ts`)
- RDP / VNC 仅原生可用;非 Tauri 环境不得显示为可连接;桌面会话不参与批量命令
@@ -47,6 +47,17 @@ npm run acceptance:full
测试替身必须完整实现 `DesktopApiContract`。新增或删除桌面接口后,`typecheck:test` 必须能发现未同步的契约。
## 分层与设置回归
```bash
npx vitest run test/platform/invoke.test.ts test/stores/settingsPersistence.test.ts test/stores/settingsMigration.test.ts test/hooks/useTheme.test.ts
cargo test --manifest-path src-tauri/Cargo.toml --lib files
```
覆盖 IPC 拒绝错误码与原始原因、业务失败信封保持、设置串行保存与失败回退、加载期间修改设置、无效主题归一化、系统主题切换,以及本地文件二进制往返和无效 Base64 不覆盖原文件。
文案变更另跑 `npx vitest run test/i18n/localeKeys.test.ts`。巡检通过不代表全量验收通过;既有失败应明确报告,不能以针对性测试替代全量结果。仅文档变更检查路径、链接和说明与实现一致,不必运行功能测试。
## AI 助手验收
自动验收不得使用真实个人 API Key。可以用本机 mock OpenAI Compatible 服务验证以下边界:
@@ -104,7 +115,7 @@ Rust 单元测试会用随机本地端口验证动态监听器的唯一 ID、运
3. 确认连接数和流量会变化(若界面展示统计)。
4. 停止后确认端口无法再连接,不能只检查 UI 颜色。
5. 重启应用后规则仍在,但状态必须为未运行。
6. 断开 SSH 主连接后,关联的本地、远程和 SOCKS5 监听器全部清理。
6. 分别验证意外断开/空闲挂起与用户停止/关闭标签:前者按保留策略维持转发并支持同窗重连接管,后者必须关闭真实 Listener;不能把所有 SSH 断开一概视为清理转发。
7. 复制规则后确认新规则 ID 独立且状态为未运行;编辑运行中的规则必须先停止原 Listener。
8. 同一 SSH 主机不得出现第二条动态规则。
+1 -1
View File
@@ -4,7 +4,7 @@ OpsXShell 主打简单好用:常用远程操作走短路径,高级选项默
## 安装(macOS)
从 `release/v*/macos-arm64/` 打开 `.dmg`,把 OpsXShell 拖到「应用程序」。Finder 里应是 Tauri 那套大图标布局(应用在左、Applications 在右)。**已经 staple 的正式包**一般可直接打开。
从官网下载,或打开本机构建产物 `src-tauri/target/<triple>/release/bundle/dmg/` 里的 `.dmg`,把 OpsXShell 拖到「应用程序」。Finder 里应是 Tauri 那套大图标布局(应用在左、Applications 在右)。**已经 staple 的正式包**一般可直接打开。
自己改代码后重新打包:先 `./scripts/build.sh mac-arm64 --quick`(本机有签名配置就会签 Developer ID),再 `./scripts/macos-notarize.sh`(会要 App 专用密码)。新打的 DMG 在公证完成前仍会被 Gatekeeper 拦截。你现在要做的步骤见 [发布指南](./release.md#macos-next-steps)。