diff --git a/docs/STATE.md b/docs/STATE.md new file mode 100644 index 0000000..28063fa --- /dev/null +++ b/docs/STATE.md @@ -0,0 +1,62 @@ +# OpenTerminal 状态快照(上下文压缩续接文档) + +> 用途:新会话/子代理从此文件恢复全部工作状态,无需对话历史。每次里程碑后更新。 + +## 当前版本与仓库 + +- v0.5(提交 90058eb+),远程 `git.codingplan.site/admin/OpenTerminal.git`(令牌已存于 .git/config) +- 技术栈:Electron + electron-vite + React 19 + TS strict + antd 6(全局深色)+ zustand + dockview-react 8 + @xterm/xterm 6 + @lydell/node-pty + ssh2 + font-list +- 契约先行约定:所有跨进程接口定义在 `src/shared/`,主/预载/渲染各自实现;新功能先改 shared 再派两端 + +## 里程碑状态(详见 ROADMAP.md) + +| 阶段 | 状态 | +|---|---| +| M1 本地终端+分屏+主题/字体 | ✅ | +| M2 SSH+连接管理器+凭据加密+指纹校验 | ✅(真实服务器验收通过) | +| M2.5 关键词高亮+系统设置(自启/阻止休眠)+UI 深色化 | ✅ | +| M3 Terminal/SSH 分离+服务器监控(Wave 风格) | ✅(真实服务器验收通过) | +| M4 SFTP 文件管理+传输+权限/chmod/chown+监控图表化 | ✅(真实服务器验收通过) | +| M5 命令历史/命令库/补全+会话日志 | ✅ | +| M6 广播输入+ZMODEM+快捷输入面板+快捷键系统 | 📋 下一步 | +| M7 打包分发(electron-builder+自动更新) | | + +M6 实施要点(已定):广播输入=多会话同步键入(选中会话集合,输入写全部);ZMODEM=渲染层检测 ZRQINIT/ZRINIT 触发文件对话框+rz/sz 命令注入;快捷输入面板=右下浮层(命令输入+快捷命令+最近命令);快捷键=globalShortcut+窗口内(Ctrl+加减字号、Ctrl+PgUp/PgDn 切换终端)。 + +M7 实施要点:electron-builder nsis;node-pty 用 @lydell 预编译免 rebuild;自动更新 electron-updater。 + +## 测试(全部通过,改动后必跑) + +```bash +npx tsc --noEmit -p tsconfig.node.json && npx tsc --noEmit -p tsconfig.web.json +npm run build +node tests/ssh-loopback.mjs +npx esbuild src/main/pty.ts --bundle --platform=node --format=cjs --outfile=tests/.session-e2e.cjs --external:@lydell/node-pty --external:ssh2 --alias:electron=./tests/electron-stub.cjs && node tests/ssh-session-e2e.mjs +node tests/sysinfo-e2e.mjs +npx esbuild tests/hl-split-smoke.mjs --bundle --platform=node --format=cjs --outfile=tests/.hl-split-smoke.cjs && node tests/.hl-split-smoke.cjs +node tests/commands-store.mjs +# 真实服务器测试(需 JD 环境变量凭据): +# JD_HOST=... JD_USER=root JD_PASS=... node tests/sftp-real.mjs / tests/sftp-chmod.mjs +``` + +## 关键架构与已踩坑(勿重蹈) + +1. **主进程 = NestJS 式注入**:pty.ts 的 sessions Map(local/ssh 统一数据面);sysinfo/sftp/日志均经 provider/configure 注入,保持 ssh.ts/commands.ts 无 electron 依赖 +2. **JD 云服务器三个怪癖**:① SFTP SETSTAT 被静默忽略 → chmod/chown 走 SSH exec;② SFTP 写 ACK 惰性 → 传输用窗口化流水线 + close 兜底(见 sftp.ts 注释);③ 每连接仅允许一个 SFTP 子系统通道(第二个 open 永不响应)→ 传输复用缓存的元数据通道 +3. **esbuild CJS bundle 会让 ssh2 fastPut 完成回调不触发**(数据实际完整到达)→ 测试用 ESM bundle 或 stat 轮询完成检测;真实应用是 rollup,未复现 +4. **antd Modal 必须包在 ``+`` 内**(App.useApp 上下文),且 `.ant-app` 需显式 height:100%(高度链曾断裂) +5. **xterm 清理**:onData/onSelectionChange 返回 IDisposable 对象不可当函数调用(曾致整窗崩溃);终端卸载必须 dispose +6. **高亮引擎**:写入前 ANSI 注入;跨块用 HighlightStream carry-over(转义序列从不参与匹配);完成检测见 src/main/sftp.ts +7. **JD 服务器测试凭据**:用户临时提供过(36.151.147.123 root)——已过期勿用,凭据一律走环境变量且不落盘 + +## 编排约定(本会话确立) + +- 主代理:契约先行 → 并行派遣子代理(每个带自审清单)→ 集成验收(typecheck/build/测试/UI 截图)→ 提交推送 +- **新增:code-review 专用子代理**——后续每个里程碑在"子代理自审"与"主代理集成验收"之间插入 code-review 代理审查环节 +- 主代理额度紧张时:契约与验收保持主代理,实现全部下沉子代理 + +## 待办(按优先级) + +1. M6 里程碑(见上要点) +2. M7 打包 +3. 小项:autoWrap=false 固定列宽、OSC 标题跟随、内置 OFL 字体打包、WebGL 终端数上限降级、i18n(中英切换,需文案抽取重构)