Skip to content

Latest commit

 

History

History
103 lines (71 loc) · 6.96 KB

File metadata and controls

103 lines (71 loc) · 6.96 KB

WSL → Cursor 自动续跑:焦点问题深度调研

1. 问题现象

  • 在 WSL 里从 Cursor 内置终端 运行 ./test-wsl-cursor-sendkeys.sh 时:
    • 「bash」被识别:聊天里出现终端相关的上下文(pill/引用)。
    • /ralph-loop 未正确触发:要么没出现开头的 /,要么整段被输入到终端里而不是聊天输入框。
  • 加上 Ctrl+` 后:焦点能成功从终端移到编辑器,但后续仍无法稳定把内容输入到聊天输入框并触发斜杠命令。

2. 当前脚本流程(焦点在谁身上)

步骤 发送的键/操作 预期焦点所在 可能出问题的地方
1 AppActivate('Cursor') Cursor 窗口激活 窗口内焦点仍是「当前活动」面板(若上次是终端,则仍是终端)
2 Ctrl+` 终端 → 编辑器 已确认有效,焦点到编辑器
3 Ctrl+L 打开聊天并聚焦聊天 不确定:焦点落在聊天面板的「哪一块」(见下)
4 Ctrl+A 全选当前焦点所在控件内容 若焦点不在输入框,会选到 pill/按钮/别处
5 SendChar('/') 在输入框输入 / 若焦点不在输入框,/ 会进别处或无效
6 Ctrl+V 粘贴到输入框 若焦点不在输入框,粘贴会进别处(或仍进输入框,取决于 Cursor 的粘贴目标逻辑)
7 Enter 提交 若焦点不在输入框,可能提交的是别处

结论:关键不确定点 = Ctrl+L 之后,键盘焦点到底在聊天面板里的哪一个控件上。

3. Ctrl+L 之后焦点可能落在哪里(推断)

Cursor 基于 VS Code/Electron,聊天面板通常包含:

  1. 顶部/侧边:模型选择、New Chat、历史等(按钮、列表)。
  2. 中间:对话历史(可滚动区域,可能可聚焦)。
  3. 上下文区context pills(@ 引用、当前文件、当前终端等),常显示为「bash」或 terminals/7.txt
  4. 底部真正的聊天输入框(textarea/input)。

文档和论坛里没有明确写「Ctrl+L 后焦点一定在输入框」。常见情况是:

  • 打开面板时焦点落在「面板内第一个可聚焦元素」;
  • 若 Cursor 会「自动附带当前终端为上下文」,第一个获得焦点的有可能是终端对应的 pill 或附近的控件;
  • 因此焦点很可能不在输入框,而在 pill / 按钮 / 列表上。

这就解释:

  • 「bash」被识别:当前焦点在「终端上下文」pill 上,Ctrl+A / 输入会作用在它或它的标签上。
  • 内容进终端:若之前没发 Ctrl+,焦点一直在终端,所有按键都进终端;发 Ctrl+ 后若 Ctrl+L 把焦点放到 pill 而不是输入框,后续按键仍可能被错误控件或默认行为处理(例如某些键被转发到终端)。

4. 技术层面:按键去了哪里

  • wscript.shell.SendKeysSendInput(KEYEVENTF_UNICODE) 都是发给当前拥有键盘焦点的控件
  • 焦点在终端 → 按键进终端;焦点在 pill/按钮 → 按键进该控件或触发其快捷键。
  • 没有「把按键强制发给聊天输入框」的 API,只能通过「先把焦点移到输入框」再发键。

因此:不解决「Ctrl+L 后焦点在输入框」这个问题,再改按键顺序或延迟都难以稳定生效。

5. 已排除 / 已确认

  • 终端抢焦点:已用 Ctrl+` 移出终端,焦点到编辑器 ✅
  • Ctrl+L 在终端被吃掉:在终端时 Ctrl+L = bash 清屏;先 Ctrl+` 再 Ctrl+L 可避免 ✅
  • Tab 切走焦点:用户反馈 Tab 会切到别处(例如侧边栏/终端),故不能用 Tab 在面板内步进 ❌

6. 可选方案(按推荐顺序)

A. 在 Cursor 里查「聚焦聊天输入框」的快捷键(推荐先做)

  1. 打开 Cursor → File / Preferences → Keyboard Shortcuts(或 Ctrl+K Ctrl+S)。
  2. 搜索与 chat / composer / input 相关的命令,例如:
    • focus chat
    • chat input
    • composer
    • aichat
  3. 看是否有类似 「Focus Chat Input」 / 「Focus Composer Input」 的 command,并记下其快捷键(若有,例如 Ctrl+Shift+L)。
  4. 若存在且不与现有脚本冲突,在脚本里用「该快捷键」替代或补充 Ctrl+L:先 Ctrl+L 打开面板,再发该快捷键把焦点明确移到输入框,然后再 Ctrl+A / SendChar('/') / 粘贴 / Enter。

B. 用 Escape 尝试「退出当前控件、回到输入框」

  • 在不少 UI 里,Escape 会取消下拉/选择,并把焦点回到主输入框。
  • 在脚本中 Ctrl+L 之后 增加一次或两次 Escape,再适当延迟,然后执行 Ctrl+A → SendChar('/') → 粘贴 → Enter。
  • 若 Cursor 的 chat 面板里 Escape 会关掉面板,则此方案无效,需跳过。

C. 用「点击聊天输入框」保证焦点(可行但偏 hack)

  • 用 PowerShell + .NET 调用 user32(如 GetCursorPos / SetCursorPos + mouse_eventSendInput 的鼠标事件),或 C# 里 GetForegroundWindow → 取窗口矩形 → 在窗口底部中央偏下(聊天输入框常见位置)模拟点击。
  • 然后再发 Ctrl+A、SendChar('/')、粘贴、Enter。
  • 缺点:依赖窗口布局,分辨率/布局一变就可能点偏;且需要额外 C# 或 Win32 调用。

D. 改变「谁在跑脚本」、减少终端上下文干扰(辅助)

  • 若脚本由 Windows 上的计划任务非 Cursor 终端的 PowerShell 窗口 触发(且不激活 Cursor 前焦点不在 Cursor 的终端),则打开 Cursor 并 Ctrl+L 时,「当前上下文」可能不是当前终端,pill 可能不是「bash」。
  • 这不能保证焦点一定在输入框,但可能减少「bash」被选中的情况。可与 A/B 组合使用。

E. 接受 WSL 下不完全自动,文档化手动续跑

  • 在 README 中明确写:WSL 下若自动续跑失败(例如命令进终端、或只识别到 bash),在第 5 轮后手动在聊天里输入 /ralph-loop --continue <conversation_id>
  • 脚本仍可保留当前逻辑作为「尽量自动」,但不保证 100% 成功。

7. 建议的下一步

  1. 在 Cursor 里查一次键位(见 6.A),若有「Focus Chat Input」类命令,改脚本用该键。
  2. 若没有明确命令,试一次 6.B:Ctrl+L → 等约 800ms → 发 1~2 次 Escape → 再等约 300ms → 再执行现有 Ctrl+A / SendChar('/') / 粘贴 / Enter。
  3. 若仍不行,再考虑 6.C(点击输入框)或 6.E(文档化手动续跑)。

8. 参考资料(简要)

  • Cursor 论坛:Toggle focus between terminal and chat input(Ctrl+` 切终端,Cmd+1 切编辑器)。
  • Cursor/VS Code:Ctrl+L 一般用于「打开/聚焦聊天」,但未明确说明焦点是否一定在输入框。
  • VS Code when 子句:inChatInputtextInputFocus 等存在,说明「聊天输入框焦点」在内部是有区分的,但默认键位表里不一定暴露「仅聚焦输入框」的快捷键。