先说工具全貌:hmharness 是一个开源的 HarmonyOS/OpenHarmony 开发智能体框架,把工程创建、检查、构建、签名、安装、启动、日志读取和结果验证接成本地工具链,让 AI 不只是生成代码,还要用本机环境证明结果;自进化行为受审批、预算、canary 和回滚约束。它不是 DevEco Studio 的替代品,而是开发智能体和鸿蒙工具链之间的验证层。本文只展开其中一环:安全多行粘贴。
把下面三行一次性粘贴到终端,会发生什么?
text
修复登录页崩溃
再跑一次构建
最后安装到模拟器
答案取决于终端。很多 shell 把换行当成"按下 Enter",所以第一行可能立刻执行,第二行也跟着执行;你以为自己只是提交了一段需求,实际却把三段输入连着放行了。Windows Terminal 官方文档把这个风险说得很直接:包含换行的多行文本粘贴到 shell 时,可能会自动执行一个或多个命令,因此它提供了 multiLinePasteWarning 这类确认提示。

这不是"用户手滑"的小问题,而是终端输入协议里的老坑。解决思路也不是让用户小心,而是让程序显式区分"用户敲键盘"和"用户粘贴文本"。
1. Bracketed paste 到底解决了什么
Bracketed paste mode 的核心是两端约定:
- 程序启动时向终端输出
ESC[?2004h,表示自己支持括号粘贴。 - 终端粘贴时不再只发送裸文本,而是在内容前后分别包上
ESC[200~和ESC[201~。 - 程序看到这一对标记,就把中间内容当作"一次粘贴的正文",而不是一串带 Enter 的键盘事件。

这带来的行为差异是:粘贴进来的三行需求先进入待编辑输入框;用户检查后按 Enter,才会提交。换行不再天然等价于"立即执行"。
2. hmharness TUI 在 117c52a 的实现
hmharness 的公开提交 117c52a9ef83510317e6ed5ce8231366a562d2fe 做了四层防线。

第一层:启用和退出 bracketed paste
TUI 进入全屏界面时输出 ESC[?2004h,退出时输出 ESC[?2004l。这样终端知道:"这个程序自己处理粘贴,请把粘贴内容包上标记。"退出时恢复模式,避免影响后续 shell 输入。
第二层:分片缓冲,不把半截粘贴当输入
终端不保证一次事件就送完整段粘贴。hmharness 看到 ESC[200~ 后开始累积缓冲;只有出现 ESC[201~ 结束标记,才把正文清理后插入输入框。若原始缓冲超过 1048576 字符,则按 runaway paste 处理并丢弃,避免输入区被异常大粘贴撑爆。
第三层:清理标记、转义序列和换行
进入输入框前,sanitizePaste 会:
- 去掉
ESC[200~/ESC[201~粘贴标记; - 去掉 CSI 转义序列和残留
ESC,防止终端控制字符混进提示词; - 把
\r\n、\r、\n折叠成空格; - 清理结尾空白;
- 将清理后的正文截断在
262144字符。
所以,上面那段三行文本最终成为一条可检查的输入:修复登录页崩溃 再跑一次构建 最后安装到模拟器。
第四层:粘贴不自动提交
粘贴只改变输入框内容,不触发任务提交。用户按 Enter 后才会提交。这一点有专门测试锁定:
ts
test('bracketed paste: multi-line text becomes ONE input, never auto-submits', async () => {
h.keys('\x1b[200~line one\nline two\r\nline three\x1b[201~');
assert.equal(p.input, 'line one line two line three');
assert.equal(h.submitted.length, 0);
h.keys('\r');
assert.deepEqual(h.submitted, ['line one line two line three']);
});
同一个提交还测试了粘贴分片到达、粘贴标记清理、转义序列清理和超长截断。
3. 为什么还要收集环境差异
Bracketed paste 是终端、shell 和程序三方配合的协议,不是万能开关。终端模拟器要支持并启用,程序也要正确开启和恢复。Windows Terminal、iTerm2、GNOME Terminal、xterm 系终端常见支持路径不同;SSH、复用器、旧 shell 或自定义输入层也可能改变行为。

如果你要验证,建议记录这四项:
text
OS 和版本:
终端模拟器及版本:
粘贴设置(Bracketed Paste / 多行粘贴警告 / 自动换行处理):
粘贴三行文本后是否自动执行:
这类反馈比"好用"更有价值:它能把兼容性边界变成可修的清单。
4. 怎么复现证据
日常使用路径:
bash
npm install -g @hmharness/cli
hmh tui
要求 Node >= 22。若要复现本文钉住的实现和测试,使用公开提交 117c52a9ef83510317e6ed5ce8231366a562d2fe:
bash
git clone https://github.com/swsgbl/hmharness.git
cd hmharness
git checkout 117c52a9ef83510317e6ed5ce8231366a562d2fe
npm install
node --import tsx --test packages/cli/src/__tests__/tui.test.ts
该提交的 GitHub Actions verify 已通过:CI 记录。本机当时 TUI 测试结果为 37/37 通过。

边界也必须说清:本文的实现细节和测试结论钉在 117c52a,不外推到所有终端实现、SSH 链路和未来 main。如果你的终端不支持 bracketed paste,或者中间层剥掉了标记,hmharness 就无法仅凭输入流区分"粘贴"和"逐键输入"。
5. 结论
安全多行粘贴不是给终端加一个"确认弹窗"这么简单,而是把输入协议讲清楚:粘贴是粘贴,Enter 是 Enter。hmharness 用 bracketed paste 标记、分片缓冲、控制字符清理、长度上限和显式提交,把多行需求变成一条可审查输入。
欢迎在仓库 Discussions 反馈你的 OS、终端和粘贴行为,这类环境数据会直接决定后续兼容性修复的优先级。
参考: