Files
OpenTerminal/docs/STATE.md
T

4.5 KiB
Raw Blame History

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。

测试(全部通过,改动后必跑)

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>+<ConfigProvider darkAlgorithm> 内(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(中英切换,需文案抽取重构)