Files
OpenTerminal/docs/PLAN-2026-10-21-backlog.md
T
Bill c0f1cdcecb docs(plan): ROADMAP 勾选已完成里程碑并新增 2026-10-21 backlog
- ROADMAP 修正过期限制说明,M3-A/M3-B/M4/M5 按实际完成勾选
- 新增 docs/PLAN-2026-10-21-backlog.md(W0–W5 波次计划,含核实记录)
2026-10-21 23:02:22 +08:00

17 KiB
Raw Blame History

OpenTerminal 下一轮迭代计划(v1.0.32+ 待办整理)

本计划整理自 2026-10-21 的三路代码审查(路线图梳理 / 代码缺口扫描 / 竞品对标), 所有条目均经源码逐一核实(文件:行号见各项「现状」)。本文件只是计划,不代表任何代码改动已开始。 执行时按波次进行,每个波次一个版本号;条目内的勾选框在执行阶段回填。

核实记录(2026-10-21 二轮):文档初稿写完后又逐条回源码验证,修正了 6 处凭印象写错的细节—— ① pendingOpens 在 pty.ts 而非 ssh.ts;② ssh2 无官方类型、项目用手写 shim ssh2.d.ts 且未声明 forwardOut;③ 本地 PTY 路径没有 ZMODEM sentry(W2-4 需新写检测而非复用);④ 剪贴板图片落临时文件 不经过 localPathGrants(它只授权对话框选中的路径);⑤ 官网 SFTP 区并无「双栏」宣传;⑥ zh-TW 「密碼」32 处 vs「口令」5 处(统一方向确认)。所有测试基建文件名(updater-fallback / settings-store / link-rules / zmodem-e2e / ssh-loopback)已确认存在。

总览

波次 主题 内容 预估工作量
W0 文档债清理 计划 checkbox 回填、ROADMAP 过期条目 0.5h
W1 修复:更新器 + 发布脚本 + 预设升级 4 项小修,其中 2 项影响存量用户 1 天
W2 捡漏功能(半成品补全) 链接规则导入导出、命令库参数、i18n 统一、ZMODEM 提示 1–2 天
W3 剪贴板与命令感知 OSC 52、图片粘贴、OSC 133 marks、完成通知 2–3 天
W4 Shell 与 SSH 迁移链 本地 shell 配置档、ssh_config 导入、ProxyJump + 端口转发 3–5 天
W5 差异化(择期) 远程文件编辑、应用命令面板、终端内 AI 助理 各 2–4 天
— 需决策的取舍项 代码签名、多窗口、双栏 SFTP、传输暂停续传 见 §6

波次间的依赖:W3 的「完成通知」依赖同波次的 OSC 133 marks;W4 的 ProxyJump 与端口转发共用 ssh2 通道基建必须同一波次;W5 各项独立。


W0:文档债清理(无代码改动)

W0-1 回填两份 superpowers 计划的 checkbox

  • 现状:docs/superpowers/plans/2026-10-20-mode-button-double-click-sidebar.md 12 个、 docs/superpowers/plans/2026-10-16-theme-overhaul.md 40 个 - [ ] 全部未勾,但对应代码、测试、 CHANGELOG 均已落地(v1.0.29 / v1.0.31)。
  • 动作:逐项核对后勾上。

W0-2 修正 ROADMAP 过期陈述

  • 现状:docs/ROADMAP.md:33「SSH 面板暂不支持作为分屏参照」已过时—— src/renderer/src/workspace/Workspace.tsx:880 起的 handleSplit 已实现 SSH dockview 内分屏。
  • 动作:删掉该条已知限制;顺带勾掉 M3-A / M5 已完成项的 checkbox,把 M4 真正未做的三项 (双栏 / 压缩解压 / 远程编辑)单列。

W1:修复(目标版本 v1.0.32)

W1-1 更新器周期定时器不再被高频设置写入重置

  • 现状(已核实调用链):每次设置保存走 mutateSettings(settingsStore.ts:732)→ applySystemSettings(:736)→ updateScheduleApplier?.(system)(:575)→ applyUpdateSchedule,而后者(updater.ts:533-537)无条件 clearInterval + 重建。拖 ColorPicker / 打字会把 4h 倒计时无限推迟。
  • 改动:applyUpdateSchedule 记忆当前 interval 值,仅当 updateCheckIntervalHours 实际变化时重建定时器。
  • 测试:tests/updater-fallback.mjs 已有 schedule 测试段(第 10 节,:586 起),在其内补「连续调用不改变倒计时起点」用例。

W1-2 「启动检查」中途拨开语义修正

  • 现状(已核实文案):设置页开关标签为「启动时自动检查」(src/shared/i18n/dicts/zh-CN/settings.ts:357), 但 updater.ts:543-547 startupArmed 只在首次武装时置位——启动时关闭过该开关的用户在会话中途打开, 会在 5s 后立刻跑一次 runCheck('startup'),与「启动时」的文案语义矛盾。
  • 改动:启动时无论开关状态都消费 startupArmed(记录「启动检查已过」), 中途打开只影响周期定时器。

W1-3 修复 --channel-only --skip-gitea 静默上传

  • 现状:scripts/release.cjs:437-441 CHANNEL_ONLY 分支在 SKIP_GITEA 警告(:442-446)之前 return—— 两个参数同用时警告永不打印,且 channel 照样上传,与操作者预期相反。
  • 改动:参数解析处直接拒绝该组合(--channel-only 的定义就是国内通道,叠加 --skip-gitea 无意义), 或把警告移到分支之前并显式确认。
  • 测试:release.cjs 无测试基建,人工跑一次参数组合验证输出即可。

W1-4 高亮预设升级机制补全(影响存量用户,本波次重点)

  • 现状(已核实判定链,settingsStore.ts:243-267):refreshBuiltinRules 只在 LEGACY_BUILTIN_PATTERNS[rule.id].includes(存储pattern) 成立时把规则升级到新 preset; 该表(:208-213)目前只有 perm/okstate/badstate 三条旧 pattern。追加新预设另有闸门 LEGACY_BUILTIN_IDS(:215 起)的「存储集合恰好等于旧预设集」判定。结论:今后改任何预设的 pattern, 若不在改动同时把旧 pattern 登记进 LEGACY_BUILTIN_PATTERNS,老用户将永远停在旧 pattern。
  • 改动:把历次发布过的预设 pattern 全量补进 LEGACY_BUILTIN_PATTERNS(从 git 历史逐版本提取), 并在文档里写明「改预设 pattern 时必须同步登记旧 pattern」的规则(AGENTS.md 高亮一节)。
  • 测试:tests/settings-store.mjs 表驱动补「旧版 pattern 规则 → 升级到新 pattern、保留用户颜色/启停」用例。

W2:捡漏功能(目标版本 v1.0.33)

W2-1 可点击链接规则的导入 / 导出 + profile 联动

  • 现状:src/renderer/src/settings/HighlightImportExport.tsx:44,52,155 只处理 highlightRules; AGENTS.md「可点击链接规则」章末明确「尚未做,属后续可加」。
  • 改动:src/shared/highlightIO.ts 的信封机制扩展 kind(或新建 linkRulesIO.ts 同构模块), UI 侧在 ClickableLinkRules 区块复用剪贴板 + FileReader + Blob 方案,不新增 IPC; profile 联动参考 excludedByProfile 的现有做法。
  • 测试:tests/link-rules.mjs 补信封/合并用例。

W2-2 命令库 {{param}} 参数变量落地

  • 现状(已核实执行链):src/shared/commands.ts:11 定义了 params?: string[],全仓无消费代码。 命令的实际执行路径是 Workspace.tsx:1215 的 runCommand → writeBroadcast(sid, \${cmd}\r`)(:1227) → 激活面板。参数替换应发生在 runCommand入口处,替换产物继续走writeBroadcast`, 各 pane 的 line buffer 语义自然保持。
  • 改动:执行命令时若含 {{name}} 占位,弹参数输入(antd Modal 表单),替换后写入终端。
  • 测试:替换逻辑抽纯函数 + 表驱动测试(占位符转义、未填参数、含 $ 字符等)。

W2-3 i18n 两个统一专项

  • 现状(已核实计数):zh-TW 词典「密碼」32 处(settings.ts 26 + ssh.ts 4 + workspace.ts 2)为压倒性多数, 「口令」仅 dicts/zh-TW/ssh.ts 5 处,统一为「密碼」并通读 指令/命令、伺服器/服务器、預設/默认; ja dicts/ja/ssh.ts 用「フォルダ」而 settings.ts/terminal.ts 用「フォルダー」。
  • 改动:纯文案批量替换 + 通读;不动键名。
  • 测试:无测试基建,四语言界面各过一遍设置页与 SSH 面板目检。

W2-4 本地终端运行 rz/sz 的用户提示

  • 现状(已核实数据路径):ZMODEM sentry 只挂在 SSH 流上(pty.ts:433-438 handle.stream.on('data') → feedZmodem);本地 node-pty 会话的数据路径没有任何 chunk 检测。本地终端跑 rz/sz 只会静默卡住。
  • 改动:在本地 PTY 数据路径加轻量 ZMODEM 头检测(只在看到 rz/sz 启动帧时生效,常态零开销), 命中时在终端里输出一行醒目的不支持说明(走终端数据面,i18n 四语);不要接入完整 sentry。
  • 测试:tests/zmodem-e2e.mjs 补「本地会话触发 → 提示且不进入传输态」。

W3:剪贴板与命令感知(目标版本 v1.0.34,对位「AI Agent 工作台」核心场景)

W3-1 OSC 52 远程写剪贴板

  • 现状:只装了 fit/search/unicode11/webgl 四个 addon;远程 tmux/vim 复制无法直达本机剪贴板。
  • 改动:term.parser.registerOscHandler(52, ...) 自实现(比引 @xterm/addon-clipboard 可控): base64 → UTF-8 安全解码(atob 裸解中文会乱码,用 TextDecoder)→ navigator.clipboard.writeText; 新增设置开关「允许远程程序写入剪贴板」(默认开,设上限如 1MB)。
  • 测试:解码函数抽纯模块,表驱动测中文/emoji/base64 边界。
  • 注意:新依赖规则——自实现则零依赖;若引 addon,渲染层依赖进 devDependencies。

W3-2 剪贴板图片粘贴进终端

  • 场景:截图直接喂给 Claude Code / Kimi Code 这类支持贴图的 AI CLI。
  • 改动:渲染层拦截粘贴(现有粘贴逻辑在 TerminalView.tsx:99-124 确认弹窗与 :943-946 的 xterm paste 通道), 剪贴板为图片时经 IPC 让主进程 clipboard.readImage() → 落临时 PNG(os.tmpdir(),定期清理)→ 把路径文本写入终端。不涉及 localPathGrants:该注册表只授权「系统对话框选中的路径」 (grantPickedFiles/grantPickedDirectory,localPathGrants.ts:110,119),临时文件由主进程自己写入、 应用自身不读它,无需授权。
  • 测试:临时文件命名/清理逻辑的单测;实际粘贴行为列入发版手测清单。

W3-3 OSC 133 命令块感知(marks)

  • 现状:src/main/shellIntegration.ts:8,39,60 已注入 OSC 7(bash/zsh/PowerShell 三个适配器)—— 扩到 133 是同一处注入脚本 + xterm 侧 mark 注册。
  • 改动:注入脚本补 OSC 133;A/B/C/D(prompt start / command start / output start / finished+exitcode); 渲染层监听 mark 事件建「命令块索引」,提供:
    • 滚动条刻度(marks gutter)
    • 快捷键跳上/下一条命令
    • 「复制本次命令输出」(整块选中复制——整段取 AI agent 输出是核心诉求)
  • 测试:注入脚本的字面量生成有现有测试模式可仿;mark 索引纯函数表驱动。
  • 风险:OSC 133 在不同 shell/嵌套 tmux 下行为差异大,首版只承诺 bash/zsh/pwsh,tmux 内标注「依赖外层终端透传」。

W3-4 长任务完成通知(依赖 W3-3)

  • 场景:多路分屏跑 AI agent,跑完切走被叫回来——本产品核心场景。
  • 改动:OSC 133 D(命令结束)到达且该 pane 不可见且命令耗时 > 阈值(设置项,默认 10s)时: 托盘气泡(复用 tray.ts notifyUpdate 的通道)+ 标签强调态。退出码非零时气泡文案区分成功/失败。
  • 测试:判定逻辑抽纯函数(耗时阈值、可见性、退出码),表驱动。

W4:Shell 与 SSH 迁移链(目标版本 v1.0.35,获客向)

W4-1 本地 Shell 配置档

  • 现状:src/main/pty.ts:220-228 win32 硬编码 powershell.exe;createPty 的 opts.shell/ opts.shellArgs 已存在但无任何调用方传参——只差最后一公里。
  • 改动:设置新增「默认 Shell」下拉(自动探测:wsl.exe -l -q 枚举发行版、git-bash.exe 常见路径、 cmd/pwsh/powershell),Workspace.tsx 的 createPty() 调用点传入;工作区「+ 新建终端」沿用默认, 侧栏可提供「以其它 shell 新建」次级菜单。
  • 测试:探测函数接受注入的枚举源(测试缝),表驱动覆盖各解析分支;真实 WSL/Git Bash 列入手测清单。

W4-2 ~/.ssh/config 导入

  • 现状:无任何 ssh_config 解析代码;国内用户从 Xshell/PuTTY 迁移时「几十台机器重录」是弃用理由之首。
  • 改动:解析器抽纯模块(Host/HostName/User/Port/IdentityFile/ProxyJump,多 Host 与通配 Host *), 映射到 SshConnection 并批量追加进 connections.json(新增字段时同步三处: PUBLIC_KEYS / toPublic() / saveConnection() 新记录字面量——AGENTS.md 明确要求)。 ProxyJump 字段在 W4-3 之前先存起来不生效。
  • 测试:解析器表驱动(注释、大小写、引号、通配、Include 提示不支持)。

W4-3 SSH ProxyJump + 端口转发(同一波次,共用通道基建)

  • 现状(已核实):forwardOut|ProxyJump|jumpHost 全仓零命中;企业内网 bastion 是刚需。 两个核实到的前置事实:① 飞行中连接登记表 pendingOpens 在 src/main/pty.ts:155,329,360 (不在 ssh.ts);② ssh2 不带类型定义,项目用手写 shim src/main/ssh2.d.ts, 其中只声明了 connect(),没有 forwardOut(:85-86)——必须扩 shim。
  • 改动:
    • 连接模型:SshConnection 增加 jumpHostId(引用另一条连接)与 forwards[](本地/远程/SOCKS)。
    • 主进程:ssh2 先连跳板 → forwardOut 建通道 → 在通道上再握手目标机;复用 pendingOpens 的中止与超时体系(每跳独立超时);主机指纹逐跳走现有 host key 队列。
    • 类型:扩展 src/main/ssh2.d.ts 补 forwardOut 等声明。
    • 端口转发:连接建立后按 forwards[] 起本地监听,断开/失败时面板给出醒目状态。
  • 测试:ssh-loopback 测试基建可起两级跳板做端到端;真实服务器场景列入手测清单。
  • 风险:这是本计划里架构风险最高的一项,建议单独立项评审后再动。

W5:差异化(择期,各独立立项)

W5-1 远程文件内置编辑器

  • 双击 SFTP 文件 → 面板内打开编辑(轻量 textarea 起步,Monaco 体积与零依赖取向冲突需另行评估); 保存自动回写;处理编码(UTF-8 优先)、CRLF、无写权限提示。改动点:FilePanel.tsx + sftp.ts 新增 read/write 文件 IPC(走 per-op 超时 bounded())。

W5-2 应用级命令面板 + 可自定义快捷键

  • Ctrl+Shift+P(已核实全仓无占用)动作注册表 + antd 模糊搜索 Modal;快捷键录制器复用 src/shared/reservedAccelerators.ts 保留键表(acceleratorParts/isReservedAccelerator,防抢 Ctrl+L/Ctrl+F)。 价值:功能密度已高,这是「后续功能不再堆 UI」的前置投资。

W5-3 终端内 AI 助理

  • OpenAI 兼容端点(DeepSeek/Kimi/智谱均可接入),「# 开头自然语言 → 建议命令」, 默认只生成、回车前必须人工确认;报错解释走显式按钮。红线:任何终端内容不外发, 与现有「诊断日志不含内容」的隐私原则保持一致。
  • 注意:引入网络请求路径,需过安全评审;不绑账号、无云同步(相对 Warp 的国内优势)。

§6 需决策的取舍项(不排期,等拍板)

项 取舍点 建议
代码签名证书 外部成本(~数百美元/年);无签名则 SmartScreen 拦截 + 通道完整性缺口 用户量到一定规模再做
多窗口 / 标签拖出 与单实例设计冲突,sessionState/owner 归属需重构 等真实多显示器用户反馈
SFTP 本地↔远程双栏 大工程(本地文件树模型 + 传输层重做);官网 SFTP 区从未宣传「双栏」(i18n fs.* 文案只讲远程面板 + 上传下载),无宣传口径包袱 观望;拖拽上传先满足大半诉求
传输暂停/续传 TransferState 无 paused 态,需断点续传协议层 观望
性能优化第二阶段(B3/B4) 项目自定规则:没拿到真实 PERF 日志前不许凭感觉动 维持观测,等数据
xterm 解 pin 回 ^ 锁 6.1.0-beta.304 因 IME 修复;解 pin 需同步 addon-unicode11 peer 并重测中文输入法 等上游 6.1.0 stable
autoWrap=false 固定列宽 xterm 无原生支持,等于自写列裁剪层 不做

执行约束(所有波次通用,摘自 AGENTS.md 铁律)

  1. 新增纯逻辑一律抽零 import 纯模块 + Node 原生类型剥离表驱动测试,测试数随 AGENTS.md 清单同步更新
  2. 依赖分类:src/main|preload 实际 import 的才进 dependencies;渲染层一律 devDependencies
  3. i18n 四语言键必须同步(zh-CN/zh-TW/en/ja),缺键回落简中但属必须修
  4. 新增「渲染层构造本地路径传主进程」的调用点必须过 localPathGrants
  5. CSS 一律 var(--ot-*),新代码禁止裸颜色字面量(tests/css-theme-vars.mjs 守门)
  6. 每个发版 commit 必须带 package-lock.json;发布流程照 AGENTS.md「发布新版本」六步
  7. 改 AGENTS.md 已文档化的行为时,同步更新 AGENTS.md