Skip to content

fix(shell): 补齐候选事件分派,并让 candidate-tui 在缺少 Vim 时快速失败 - #269

Merged
JavaZeroo merged 2 commits into
mainfrom
fix/candidate-event-routing
Oct 31, 2026
Merged

JavaZeroo merged 2 commits into
mainfrom
fix/candidate-event-routing

Conversation

@JavaZeroo

@JavaZeroo JavaZeroo commented Oct 31, 2026 •

Copy link
Copy Markdown
Owner

问题与最终行为

alacritty-headless (windows-2025) 反复在 candidate_shell_tui 失败。用 GitHub 的 job API 取每步结论(无需日志)定位到「Build and test candidate shell on Windows」,再用该 run 的 artifact 读到现场:

stage=50 bytes=1678 …
screen 第 23 行: "candidate-tui.txt" [New]
candidate-startup-log.txt: b'READY\n'
… unsupported terminal event kind

Vim 正常启动、[New] 与 READY 都已就位,场景却因为一个未处理的事件类型中止。

根因:事件分派不完整

unsupported terminal event kind 只在 experiments/shell/shell.cpp:826 抛出。对照 experiments/candidates/alacritty/src/ffi.rs:326-342,适配器会发出全部 13 种事件,而 shell 只处理 7 种:

kind 事件 修改前 修改后
1 PtyWrite 处理 处理
2 / 3 Title / ResetTitle 处理 处理
4 Bell 处理 处理
5 / 7 / 12 Wakeup / MouseCursorDirty / CursorBlinkingChange 处理 处理
6 Exit 处理 处理
8 / 9 ClipboardStore / ClipboardLoad throw 忽略
10 / 11 ColorRequest / TextAreaSizeRequest throw 忽略
13 ChildExit throw 忽略

default: throw 保留——将来适配器新增 kind 仍会明确失败,而不是被静默吞掉。

忽略 8/9/10/11/13 的依据:该 harness 比较文字、模式与生命周期;它不拥有剪贴板,退出码从 session 读取,这些通知对它没有语义。

附带:缺少 Vim 时快速失败

candidate-tui 会在真实 shell 里键入 Vim 命令。缺少 Vim 时原先要跑满 33 秒场景超时才失败,唯一痕迹是 shell 回显的 not recognized。本 PR 在 run.py 的 execute() 入口加一次前置检查,缺失立即抛 RuntimeError 并指向 docs/research/joint-conpty-baseline.md。按 more-capture-ech.md「skip 不代替运行证据」,这里是失败而不是 skip。(原 #267 的 workflow PATH 步骤已被证伪并移除:本 PR 不含它时两个 Windows 作业仍以 5m50s / 6m05s 通过。)

验证

  • CI:本 PR 的 alacritty-headless (windows-2025) 两个作业均通过(5m50s / 6m05s),这是修复前后的直接对照
  • 覆盖完整性:修改后 case 分支覆盖 kind 1–13 全部取值,与 ffi.rs 映射一一对应
  • 本地:装上与 CI 同源 Vim 9.1 后,合并树(11 个 PR)的候选配置下 candidate_core 1.66s、candidate_shell_tui 9.30s 通过;默认配置 67/67 通过
  • 守卫:本机无 Vim 时在 0.17 秒抛出带文档指引的 RuntimeError;非 candidate-tui 模式不受影响

性能影响(如适用)

不适用。仅增加事件分支与一次 PATH 查找。

来源与限制

  • 现场证据:CI artifact 的 sample.json(stderr 与 screen)与该轮 candidate-startup-log.txt
  • 限制:本地无法复现 "unsupported terminal event kind" 的具体触发(同版本 Vim 在本机通过),因此事件部分是按「该串唯一抛出点 + 映射穷尽」定位的;CI 对照是主要验证
  • 本 PR 不改变 candidate-tui 的任何断言

#267 在 CI 上补上固定 Vim 后,candidate-tui 改用真实 Vim 运行,随即撞到下一条:

  stage=50 … screen 中 [New] 与 READY 都已就位
  unsupported terminal event kind

该串只在 shell.cpp:826 抛出。对照 ffi.rs:326-342 的完整映射,候选适配器会发出
1-13 全部 13 种事件,而本处只处理 1,2,3,4,5,6,7,12,于是 8(ClipboardStore)、
9(ClipboardLoad)、10(ColorRequest)、11(TextAreaSizeRequest)、13(ChildExit)
任何一种都会让整个场景中止。

本修改补齐 8/9/13,并把 10/11 一并列为忽略:该 harness 比较的是文字、模式与
生命周期,不拥有剪贴板,退出码从 session 读取,这些通知对它没有语义。default
分支保留,未来新增 kind 仍会明确失败而不是被静默吞掉。

验证:本机装上与 CI 同源的 Vim 9.1(Git for Windows usr/bin)后,
candidate_shell_tui 与 candidate_core 均通过;1-13 现已全部有分支覆盖。
JavaZeroo added a commit that referenced this pull request Oct 31, 2026
#269 的 CI 结果是决定性的:该 PR 不含本步骤,两个 alacritty Windows 作业仍然
5m50s / 6m05s 通过。也就是说 hosted runner 上 Vim 本来就在 PATH,真正的失败
一直是 route_terminal_events 对 kind 8/9/10/11/13 抛异常,而不是缺 Vim。

本步骤因此没有依据,还引入一个新失败面(Git 安装位置变化时 exit 1)。
保留 run.py 的前置检查:它只在本地没有 Vim 时把 33 秒场景超时换成一条带文档
指引的即时失败,对 CI 无副作用。
并入 #267 的可用部分:candidate-tui 会在真实 shell 里键入 Vim 命令,缺少 Vim 时
不应跑满 33 秒场景超时,而应立即给出带文档指引的失败。

按 more-capture-ech.md「可选依赖缺失导致的 skip 不代替运行证据」,这里是失败
而不是 skip。与事件分派修复同属 candidate-tui 场景的健壮性,故并入本 PR;#267
的 workflow 部分已被证伪并移除。
@JavaZeroo JavaZeroo changed the title fix(shell): 候选适配器的剪贴板/颜色/尺寸/子退出事件不再使场景失败 fix(shell): 补齐候选事件分派,并让 candidate-tui 在缺少 Vim 时快速失败 Oct 31, 2026
@JavaZeroo
JavaZeroo merged commit 7d58bb3 into main Oct 31, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant