﻿---
title: "Esc 打断只跑 Interrupt，清理不要只挂在 Stop 上"
summary: "只给顶层轮。matcher 无效。默认 1 秒、上限 3 秒。输出拦不住打断。Stop 在 Esc 时不会跑。"
category: hooks
level: advanced
surfaces: [cli]
tags: ["hooks", "Interrupt", "Esc"]
canonical: /tips/interrupt-hook/
---

# Esc 打断只跑 Interrupt，清理不要只挂在 Stop 上

只给顶层轮。matcher 无效。默认 1 秒、上限 3 秒。输出拦不住打断。Stop 在 Esc 时不会跑。

按 Esc 或杀进程打断**正在跑的顶层轮**时，跑的是 `Interrupt`，不是 `Stop`。子代理、空闲线程都不会触发。官方 Learn 钩子表把这件事单独写成一行；developers.openai.com/codex/hooks 若还没列出 `Interrupt`，以 Learn 和本机 `/hooks` 为准。

```toml
[[hooks.Interrupt]]

[[hooks.Interrupt.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/on_interrupt.py"'
timeout = 2
statusMessage = "Saving interrupted turn"
```

不要写 matcher：这个事件会忽略它。钩子跑之前 transcript 已经 flush，stdin 里有 `session_id`、`turn_id`、`transcript_path`、`cwd`、`permission_mode`。

约束：

- 默认超时 **1 秒**，上限 **3 秒**。别的钩子默认 600 秒，抄过来会在你等 Esc 时被砍掉
- 输出拦不住打断，也不能把这一轮拉回来。退出码 `0` 且不要打纯文本；需要提示时 stdout 只给 JSON，例如 `{"systemMessage": "已记下被打断的轮次。"}`
- `async = true` 时超时仍是 1–3 秒
- Learn 只明确写了 `SessionEnd` 不支持 `mcp_tool`。`Interrupt` 事件页给的是 command 输出约定，清理脚本用 command 最稳妥
- 进程内的 `on_mcp_tool_result` 是 extension，不是 `hooks.json` 里的事件，不要抄进钩子配置

适合：删本轮临时目录、把扫描器从 running 改成 aborted、给 CI 发一条中止通知。不要指望它当完成门。新钩子先 `/hooks` 信任。

## 来源

- [OpenAI · Hooks](https://learn.chatgpt.com/docs/hooks)
- [openai/codex#22858](https://github.com/openai/codex/issues/22858)
