工程与管理工具调试

iTerm2 选中文本突然失效?一次 AI Coding 工具鼠标劫持回归的排查

症状:iTerm2 里打开某 AI Coding 工具,想复制一段输出——选中第一行,按住 Shift,点最后一行,以前能整段选中,现在不行了。

不是你的操作变了,是工具更新抢了你的鼠标。


排查过程

第一步排除 iTerm2 设置。Preferences → Pointer 里 “Emulate third button” 选项、General → Selection 里的 “Copy to pasteboard on selection” 都正常。切回普通 shell,shift+点击选区完全正常。

第二步排除鼠标驱动。同一个终端窗口,切到普通 zsh 面板选区正常,一进该工具的 REPL 就失效。问题边界明确了:仅在该工具运行状态内失效。

第三步搜 GitHub issues。找到了一个完全对上的 bug 报告:该工具在 v2.1.195 版本开始,在终端内部劫持了鼠标事件(点击、拖拽、悬停),用来实现”点击展开”、hover 高亮、滚动加速这些交互功能。副作用就是——你没法再用鼠标正常选文本了。


根因:鼠标事件被接管

该工具新版本的鼠标劫持做了什么:

旧版本:鼠标事件 → iTerm2 原生处理 → 正常选区/复制
新版本:鼠标事件 → 工具拦截 → 用于内部交互(点击展开/hover高亮/滚动加速)

                                        Shift 可绕过,但有 bug

你记得的”之前能 shift+首行、shift+点末行整体复制”——那是旧版本根本没有抢鼠标,iTerm2 原生选区正常工作。

新版本抢了鼠标之后,Shift 成了”强制交回给终端”的绕过键,但这个绕过路径有 bug,导致你按 Shift 点最后一行时,选区没有被正确扩展。

这跟广告系统上新策略一模一样:新逻辑上线 → 覆盖了旧行为 → 用户发现指标异常 → 排查到是抢占了不该抢的东西。


修复

当前版本没有 settings.json 字段也没有 CLI 参数可以关,只能用环境变量绕过:

export CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1

写入 .zshrc 持久化:

echo 'export CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1' >> ~/.zshrc
source ~/.zshrc

然后重新打开该工具会话,鼠标事件不再被劫持,iTerm2 原生选区恢复。

滚轮加速不受影响——这个环境变量只关点击/拖拽/悬停劫持,滚轮还是被该工具接管以保持加速体验。


元结构映射:广告系统里的回归事故

排查这个问题的过程和排查线上广告事故一模一样:

步骤广告系统事故本次排查
1. 确认异常CTR 暴跌 / 营收下降选中文本失效
2. 缩小范围哪个模块上线了?只在某工具内失效,zsh 正常
3. 定位变更diff 最近发布的代码对 bug report,确认 v2.1.195 引入
4. 止损回滚 / kill switchCLAUDE_CODE_DISABLE_MOUSE_CLICKS=1
5. 修复修 bug 上线等上游修复,当前绕过去

本质是一样的:新功能上线 → 覆盖了不该覆盖的旧行为 → 用户发现异常 → 开关兜底。


教训

三条:

1. 工具频繁更新时,先怀疑工具。 尤其是 AI Coding 工具迭代极快,每周都有新版本。出了问题先别急着改自己的配置,搜一下是不是新版本的回归。

2. 终端应用不该劫持终端本身的行为。 鼠标选择是终端的基础能力,就像广告系统里你不能为了加个新 feature 把曝光日志停了。新功能应该在不破坏旧功能的前提下实现。

3. 任何时候都要有 kill switch。 该工具提供了一个环境变量关掉鼠标劫持——这就是 kill switch。好设计师会在新功能旁边放一个关闭它的方式,因为任何新功能都可能出 bug。

一句话:不是你操作变了,是工具更新默认接管了鼠标交互——加一个环境变量关掉这个接管就行。