Files
NetMesh/ET_INTEGRATION_CHECKLIST.md
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

220 lines
15 KiB
Markdown
Raw Permalink 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.
# EternalTerminal (ET) 集成清单 — 按 Mosh 方式重做
> 目标:在上游最新架构(分支 `feat/et-history-reapply`,基于 `031bf0ee`)上,
> **完全照搬 Mosh 的方式**重新集成 EternalTerminal
> 1. **打包客户端** —— 像 `mosh-client` 那样,把 `et` 客户端二进制构建 + 下载 +
> 捆绑进安装包,运行时只用捆绑的二进制(不依赖系统安装的 et
> 2. **接入协议** —— 把旧分支 `feat/eternal-terminal`tip `67e81616`)里的 ET
> 后端 + UI 重新落到上游重构后的目录结构上,并让它启动**捆绑的** `et`。
>
> 旧实现参考:`git show 67e81616`(共 7 个 ET 提交,见 `feat/eternal-terminal`)。
> Mosh 模板参考(**仅 MoshCatty 纯二进制路径**`resources/mosh/README.md`、
> `scripts/fetch-mosh-binaries.cjs`、`scripts/resolve-mosh-bin-release.cjs`、
> `scripts/mosh-extra-resources.cjs`、`electron/bridges/terminalBridge/moshSession.cjs`。
> 客户端本体在独立仓库 [binaricat/MoshCatty](https://github.com/binaricat/MoshCatty)
> `moshcatty-*` releasesNetcatty 内已无 Cygwin 构建流水线 / FluentTerminal 回退。
## 关键设计差异ET vs Mosh
- **协议**Mosh 需要 Node 做 SSH bootstrap + 抓 `MOSH CONNECT` + 换 PTY
`moshHandshake` + `moshSession`)。**ET 不需要** —— `et` 客户端自己完成 SSH
引导 + 协议握手,我们只要把 `et` 当作普通 PTY 进程 `pty.spawn` 即可。所以**没有**
`etHandshake.cjs`
- **凭证注入**Mosh 自己驱动 ssh、直接往 PTY 里敲密码ET 内部驱动 ssh需用
**SSH_ASKPASS + 临时 ~/.ssh 环境**把保存的密码/密钥/跳板/算法喂给 et 内部的 ssh
(旧实现 `prepareEtSshEnvironment` 已完整实现,直接搬运)。
- **纯二进制**MoshCatty 与理想 ET 打包都是「每平台一个客户端文件」。Mosh 侧已
无 terminfo / Cygwin DLL 袋;`et` 同样本地不渲染终端。Windows 若动态链 CRT
才考虑可选 DLL 目录,否则只放 `et[.exe]`
- **构建系统**Mosh 客户端在 **MoshCatty** 仓库用 Rust 构建并发布Netcatty 只
`fetch`。**ET** 用 CMake + Ninja + vcpkg
`cmake -DDISABLE_TELEMETRY=ON -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo`
产物是单个 `et`Windows `et.exe`),由 `scripts/build-et/` + `build-et-binaries.yml` 发布。
## 命名约定(镜像 Mosh / MoshCatty
| Mosh (MoshCatty) | ET |
|------|----|
| `resources/mosh/<plat-arch>/mosh-client[.exe]` | `resources/et/<plat-arch>/et[.exe]` |
| 打包后 `<Resources>/mosh/mosh-client` | 打包后 `<Resources>/et/et` |
| 上游构建:`binaricat/MoshCatty` CI releases | `scripts/build-et/` + `build-et-binaries.yml` |
| `scripts/fetch-mosh-binaries.cjs` | `scripts/fetch-et-binaries.cjs` |
| `scripts/resolve-mosh-bin-release.cjs` | `scripts/resolve-et-bin-release.cjs` |
| `scripts/mosh-extra-resources.cjs` | `scripts/et-extra-resources.cjs` |
| env `MOSH_BIN_RELEASE` / 仓库 `MoshCatty` / tag `moshcatty-*` | env `ET_BIN_RELEASE` / 仓库 `Netcatty-et-bin` / tag `et-bin-*` |
| `npm run fetch:mosh[:dev]` | `npm run fetch:et[:dev]` |
| `bundledMoshClient()` / `resolveBareMoshClient()` | `bundledEtClient()` / `resolveBareEtClient()` |
---
## Phase 1 — 打包基础设施(构建/下载/捆绑)
- [x] **1.1** `resources/et/README.md` —— 镜像 `resources/mosh/README.md`:说明
二进制来源、`Netcatty-et-bin` 发布仓库、`et-bin-*` tag、许可证ET 为
Apache-2.0,与 GPL-3.0 兼容)、可复现构建命令。
- [x] **1.2** `.gitignore` —— 追加 ET 段(镜像 mosh 段):
`/resources/et/*/et``/resources/et/*/et.exe``/resources/et/*/*.dll`
`/resources/et/*/et-win32-*-dlls/`。保留 `resources/et/README.md`
- [x] **1.3** `scripts/build-et/build-linux.sh` —— manylinux2014 + vcpkg 静态三元组
构建 `et`x64/arm64产物 `et-linux-<arch>.tar.gz`(+.sha256),内含单个 `et`
校验非系统动态库ldd 白名单)。
- [x] **1.4** `scripts/build-et/build-macos.sh` —— arm64 + x86_64 分别构建后 `lipo`
成 universal`MACOSX_DEPLOYMENT_TARGET=11.0`,产物 `et-darwin-universal.tar.gz`
- [x] **1.5** `scripts/build-et/build-windows.ps1`(或 `.sh`)—— MSVC + vcpkg
`x64-windows-static`,产物 `et-win32-x64.tar.gz`(含 `et.exe`;若动态链接 CRT
则随附 DLL 目录 `et-win32-x64-dlls/`,否则纯静态无 DLL
- [x] **1.6** `scripts/et-extra-resources.cjs` —— 镜像 `mosh-extra-resources.cjs`
按平台/arch 仅当 `resources/et/<plat-arch>/et[.exe]` 存在时才产出 extraResources
指令(`to: "et/"`Windows 额外处理可选 DLL 目录。纯客户端文件为主。
- [x] **1.7** `scripts/resolve-et-bin-release.cjs` —— 镜像 `resolve-mosh-bin-release.cjs`
`TAG_RE=/^et-bin-.../`,默认仓库 `Netcatty-et-bin`env `ET_BIN_RELEASE` 优先。
- [x] **1.8** `scripts/fetch-et-binaries.cjs` —— 镜像 `fetch-mosh-binaries.cjs`
`TARGETS` 四项linux-x64/arm64、darwin-universal、win32-x64全部 tar.gz
SHA256SUMS 校验;解包到 `resources/et/<plat-arch>/`。**Windows 用自建产物**。
- [x] **1.9** 单元测试:`scripts/fetch-et-binaries.test.cjs`
`scripts/resolve-et-bin-release.test.cjs``scripts/et-extra-resources.test.cjs`
(镜像对应 mosh 测试,改名/改路径)。
- [x] **1.10** `package.json` scripts新增
`"fetch:et": "node scripts/fetch-et-binaries.cjs"`
`"fetch:et:dev": "node scripts/fetch-et-binaries.cjs --host --resolve-release"`
`dev` 脚本改成先 `fetch:mosh:dev && fetch:et:dev``test` glob 已覆盖
`scripts/*.test.cjs`(确认即可)。
- [x] **1.11** `electron-builder.config.cjs`:引入 `etExtraResources`,在 darwin/win32/
linux 三处把 `etExtraResources(plat)` 合并进 `extraResources`(与 mosh 数组拼接)。
- [x] **1.12** `.github/workflows/build-et-binaries.yml` —— 四个构建 job + 一个
`release` jobdispatch 且 `release_tag` 非空时发布到 `Netcatty-et-bin`,附
`SHA256SUMS`)。`paths` 过滤指向 `scripts/build-et/**``scripts/fetch-et-binaries.cjs`
`scripts/et-extra-resources.cjs`。env 用 `ET_REF`(默认 ET release tag`et-v6.2.x`)。
> 注:实际二进制由用户手动 `workflow_dispatch` 触发产出;本地/CI 未设
> `ET_BIN_RELEASE` 时 fetch 步骤安静跳过(同 mosh 的 `MOSH_BIN_RELEASE`)。
## Phase 2 — 运行时定位捆绑客户端
- [x] **2.1** `electron/bridges/terminalBridge.cjs` 新增 `bundledEtClient(opts)`
—— 镜像 `bundledMoshClient`:打包路径 `<Resources>/et/et[.exe]`dev 回退
`<projectRoot>/resources/et/<plat-arch>/et[.exe]`;导出到 module.exports。
## Phase 3 — ET 协议后端(搬运旧实现到新架构)
- [x] **3.1** 新建 `electron/bridges/terminalBridge/etSession.cjs` —— 用上游
`moshSession.cjs``createXxxSessionApi(ctx)` + `with(ctx)` 工厂模式,封装:
`ET_ASKPASS_SCRIPT``writeSecureFile``prepareEtSshEnvironment`
`createEtAskpassArtifacts``cleanupStaleEtTempDirs`
`cleanupSessionExternalAuthArtifacts``execOnEtSession``startEtSession`
**改动点**`etCmd``findExecutable('et')` 改为 `resolveBareEtClient()`
(取捆绑二进制);找不到时抛错(同 mosh提示跑 `npm run fetch:et:dev`)。
Windows 若有动态链接 DLL 目录,可把该目录加进 PATHMoshCatty 路径已无此需求)。
- [x] **3.2** `terminalBridge.cjs` 接线 `createEtSessionApi(ctx)`(镜像 moshSessionApi
的 ctx传入 `bundledEtClient``tempDirBridge``execFile/execFileSync` 等;
解构出 `startEtSession``execOnEtSession``cleanupStaleEtTempDirs`
`cleanupSessionExternalAuthArtifacts``resolveBareEtClient`
- [x] **3.3** `init()``cleanupStaleEtTempDirs()``registerHandlers`
`ipcMain.handle("netcatty:et:start", startEtSession)``closeSession`
`cleanupAllSessions``cleanupSessionExternalAuthArtifacts(session)`
`module.exports` 导出 `startEtSession``execOnEtSession``bundledEtClient`
- [x] **3.4** 测试:`terminalBridge.bundledEt.test.cjs`(路径解析)+
`terminalBridge/etSession.test.cjs`prepareEtSshEnvironment 的端口/密钥/
askpass/跳板/legacy 算法分支)。可参考旧分支是否已有 ET 测试并搬运。
## Phase 4 — domain / 类型 / preload 接口面
- [x] **4.1** `domain/models.ts``HostProtocol``'et'``ProtocolConfig.etPort?`
`Host`/`GroupConfig``etEnabled?`/`etPort?`/`etTerminalPath?`
`TerminalSession.etEnabled?``ConnectionLog.protocol``'et'`
(照搬 `git show 794eecdf -- domain/models.ts`
- [x] **4.2** `domain/groupConfig.ts`:加 `etEnabled` 默认项(照搬旧 diff
- [x] **4.3** `global.d.ts``NetcattyBridge``startEtSession?(options): Promise<...>`
及相关 options 类型(照搬 `git show 794eecdf -- global.d.ts`,并补齐后续 ET 提交
新增的 etPort/terminalPath/jumpHosts/legacyAlgorithms 字段)。
- [x] **4.4** `electron/preload/api.cjs`:加 `startEtSession`(镜像第 26 行的
`startMoshSession`)→ `ipcRenderer.invoke("netcatty:et:start", options)`
**注意**:上游已把 preload 重构成 `createPreloadApi`,落点在 `preload/api.cjs`
不是旧的 `preload.cjs` 内联对象。
## Phase 5 — 渲染层 + UI + i18n
- [x] **5.1** `application/state/useTerminalBackend.ts`:加 `etAvailable`(查
`bridge?.startEtSession`+ `startEtSession`,并在返回对象/依赖数组里登记
(镜像 mosh 的第 10/42/198/205 行处)。
- [x] **5.2** `application/state/useSessionState.ts`:路由 ET 会话(照搬旧 diff+6 行)。
- [x] **5.3** `components/terminal/runtime/createTerminalSessionStarters.ts`:加
`startEt(term)`(镜像 `startMosh`,组装 optionsetPort/terminalPath/
jumpHosts/legacyAlgorithms/凭证/identityFilePaths
**注意**:上游把它从旧的 `infrastructure/runtime/` 移到了
`components/terminal/runtime/` —— 落点以上游为准。
- [x] **5.4** UI 组件(照搬 `git show b1a306f8 6c0d5bf3 55caa268` 的相应文件,
映射到上游同名组件):
- [ ] `components/ProtocolSelectDialog.tsx` —— 新增 ET 选项
- [ ] `components/QuickConnectWizard.tsx`
- [ ] `components/HostDetailsPanel.tsx` —— ET 设置启用、ET 端口、etterminal 路径)
- [ ] `components/GroupDetailsPanel.tsx`
- [ ] `components/VaultView.tsx`
- [ ] `components/Terminal.tsx` / `components/TerminalLayer.tsx`
- [ ] `components/terminal/TerminalConnectionDialog.tsx` / `TerminalToolbar.tsx`
- [ ] `App.tsx`
- [x] **5.5** i18n`application/i18n/locales/en.ts``zh-CN.ts` 加 ET 文案
(照搬旧 diff键名对齐上游现有 mosh 文案结构)。
## Phase 6 — 校验
- [x] **6.1** `npm run lint`(确保新 .cjs 在 scripts/ 下不受 ESLint 限制,
或按需加 eslint-disable与 mosh 脚本一致)。
- [x] **6.2** `npm test`(新增的 fetch/resolve/extra-resources/etSession 测试全绿)。
- [x] **6.3** `npm run build`(渲染层 TS 编译通过,无类型错误)。
- [ ] **6.4** 手动冒烟(需先有发布的二进制):
`ET_BIN_RELEASE=et-bin-... npm run fetch:et``npm run start`
新建 ET 会话连一台装了 etserver 的主机,验证连接/输入/退出/凭证注入。
---
## 进度记录
- 状态:**Phase 15 已完成并通过校验**(仅余 1 个可选项 + CI 产二进制)
- 验证结果:
- `npx eslint <所有改动文件>` → 干净0 错 0 警)
- `npx tsc --noEmit` → 我的改动 **0 个新增类型错误**
`TerminalConnectionDialog``case 'mosh'` 的 TS2678 是既有问题,行号因我插入 ET 早返回从 60→64非新增
- `node --test`ET 相关)→ etSession/bundledEt/3 个脚本测试 **全绿**
- `npm test` → 1383 通过 / 16 失败,**16 个全是既有的 Windows 环境失败**
mosh 打包测试的 GNU-tar `C:` 问题、`isExecutableFile` 无 x 位、ACP execPath、SKILL.md 权限、Comware DH 等;均在我未改动的文件里)
- `npm run build`Vite**构建成功**8.55s),渲染层打包通过
### 已完成
- **Phase 1**`scripts/et-extra-resources.cjs` / `resolve-et-bin-release.cjs` /
`fetch-et-binaries.cjs`+3 测试27 通过)、`scripts/build-et/{build-linux.sh,
build-macos.sh,build-windows.ps1}``.github/workflows/build-et-binaries.yml`
`resources/et/README.md``.gitignore``package.json``electron-builder.config.cjs`
- **Phase 2**`terminalBridge.cjs` 新增并导出 `bundledEtClient`
- **Phase 3**`terminalBridge/etSession.cjs`startEtSession + prepareEtSshEnvironment +
SSH_ASKPASS 机制 + execOnEtSession + 清理),接线进 terminalBridge.cjsctx/IPC
`netcatty:et:start`/init 清理/close/quit 清理/导出),+2 测试13 通过)。
**et 指向捆绑二进制**resolveBareEtClient→bundledEtClient找不到则报错。
- **Phase 4**domain `connection.ts`/`history.ts`/`terminal.ts``groupConfig.ts`
`types/global/netcatty-bridge-session.d.ts`startEtSession + NetcattyJumpHost[])、
`electron/preload/api.cjs``domain/vaultImport.ts`(排除 'et' 导入协议)。
- **Phase 5**
- 启动派发:`useTerminalEffects.ts``Terminal.tsx`(×3) → `startEt`
- 运行时 starter`createTerminalSessionStarters.ts` 新增 `startEt`(含单跳板/凭证/
legacy 算法/askpass 路径),`.types.ts``etAvailable`/`startEtSession`
- 后端 hook`useTerminalBackend.ts`etAvailable + startEtSession
- 会话透传 etEnabled`sessionFactories.ts``useSessionState.ts`(×6)、
`TerminalLayer.tsx`(×3)、`TerminalLayerSupport.tsx``AppHandlers.ts`(协议解析/日志/选择)
- UI`HostDetailsAdvancedSections.tsx`ET 开关+端口+etterminal 路径,与 Mosh 互斥)、
`HostDetailsPanel.tsx``ProtocolSelectDialog.tsx`ET 选项)、
`TerminalConnectionDialog.tsx`ET 标签)、`TerminalToolbar.tsx`(编码菜单门控)、
`GroupSshSettingsSection.tsx` + `GroupDetailsPanel.tsx`(组级 ET`VaultView.tsx`
- i18nen/zh-CN 的 `hostDetails.section.et``hostDetails.et.*`
`terminal.connection.protocol.et``terminal.et.*`
### 剩余(可选 / 非阻塞)
- [ ] **QuickConnectWizard.tsx**:把 ET 加为“快速连接”协议按钮type/端口/建主机映射 +
UI 按钮)。当前快速连接未列 ET保存主机后开启 ET 再连即可,故仅为便利项。
- [ ] **产出二进制**:手动 `workflow_dispatch``build-et-binaries.yml`(带
`release_tag=et-bin-<ver>-1`)发布到 `Netcatty-et-bin`,并配 `ET_BIN_RELEASE_TOKEN`
secret。之后 `ET_BIN_RELEASE=... npm run fetch:et` 即可本地/打包捆绑 `et`
build-et 脚本本机无法编译 C++,需在 CI 验证。
- [ ] **端到端冒烟**:有二进制后 `npm run dev`,对装有 etserver 的主机建 ET 会话验证。
- 当前分支:`feat/et-history-reapply`(基于上游 `031bf0ee`
- 旧 ET 实现参考分支:`feat/eternal-terminal`tip `67e81616`7 个 ET 提交)