11-Cursor Hooks与自动化

张开发
2026/4/16 10:11:13 15 分钟阅读

分享文章

11-Cursor Hooks与自动化
11-Cursor Hooks与自动化使用Cursor Agent Hooks在 Agent 生命周期内执行自定义命令拦截 Shell、在 Agent 改文件后运行脚本等。适用于 Cursor 3.x以 官方文档 为准。一、Hooks 概述1.1 什么是 Cursor HooksCursor Agent Hooks由 Cursor 在Agent 模式下触发用子进程运行你在hooks.json里配置的命令通过标准输入输出传递 JSON与常见「编辑器保存即触发」的插件钩子不是同一套机制。特性说明事件驱动在 Agent 执行特定步骤前后触发如执行终端命令前、Agent 写入文件后可编程每条 hook 对应一个可执行命令脚本、解释器运行脚本等可拦截beforeShellExecution/beforeReadFile等可返回 allow / deny与项目绑定支持项目级与全局级hooks.json常见误解务必区分不是VS Code 的「保存时格式化」手动按 CtrlS不会触发下文中的afterFileEdit。不是Git 自带的pre-commit你在本机终端里自己执行git commit默认不会走 Cursor 的beforeShellExecution除非 Agent 代为执行同一条命令。1.2 官方支持的 Hook 事件Agent当前协议下hooks.json里只能使用下列键名名称需完全一致事件名作用简述beforeShellExecutionAgent 执行终端命令前可拒绝并返回说明beforeMCPExecution调用 MCP 工具前可拒绝afterFileEditAgent完成一次文件编辑后通知型常用于格式化/记录beforeReadFileAgent 读取文件前可拒绝beforeSubmitPrompt用户提示发送给模型前可阻止提交stopAgent 本轮结束时通知型说明Tab / 内联补全若另有 hook 名称以官方文档更新为准本文仅保证与 Agent Hooks 文档一致。二、Hooks 配置hooks.json2.1 配置文件位置项目级: 仓库根/.cursor/hooks.json 全局级: ~/.cursor/hooks.json Windows: C:\Users\用户名\.cursor\hooks.json 企业级: 见官方文档如 ProgramData 下集中配置合并与优先级以 Cursor 实际行为为准调试时可查看输出面板中与cursor.hooks相关的日志。2.2 协议格式必读官方要求顶层包含version且hooks的每个事件值为「对象数组」数组元素目前为{ command: ... }可配合 JSON Schema 做校验。正确示例Windows PowerShell 版已验证{version:1,hooks:{afterFileEdit:[{command:powershell -NoProfile -ExecutionPolicy Bypass -File C:/Users/an845/.cursor/hooks/after_file_edit.ps1}]}}关键点说明问题解决方案中文路径乱码PowerShell 脚本中用[Console]::InputEncoding UTF8读取 stdinJSON 解析失败hook 脚本 stdout 输出合法 JSON如{status:completed,message:All done!}而非纯文本All done! 不显示将消息放在 JSON 的message字段 Cursor 会在 Output 区域显示stdin 为空避免直接用python.exe启动PowerShell 更稳定地传递 stdin配套 PowerShell 脚本示例after_file_edit.ps1# 读取 UTF-8 stdin 的 JSON payload[Console]::InputEncoding [System.Text.Encoding]::UTF8$reader[System.IO.StreamReader]::new([System.Console]::OpenStandardInput(),[System.Text.Encoding]::UTF8)$json$reader.ReadToEnd()$reader.Close()# 解析 JSON$payload$json|ConvertFrom-Json$filePath$payload.file_path# 运行 black flake8收集输出$outputs ()$blackResult python.exe-m black$filePath21$outputs$blackResult$flake8Result python.exe-m flake8$filePath21$outputs$flake8Result# 输出合法 JSONCursor 会解析并显示{status completedmessage All done!file $filePathdetails $outputs}|ConvertTo-Json-Compress|Write-Host错误示例旧版教程臆测格式会导致 Failed to parse下列写法不是Cursor 的hooks.json协议加载会失败请勿使用{hooks:{onSave:{enabled:true,actions:[]},preCommit:{enabled:true,actions:[]}}}2.3 与「保存时 format / 提交前 pytest」意图的对应关系若你希望实现「改 Python → black flake8」、「执行 git commit 前先 pytest」一类流程应在合法事件下用脚本完成教程式说法Agent Hooks 中的等价做法保存后格式化/检查在afterFileEdit的脚本里判断file_path是否为.py再调用black/flake8提交前跑测试在beforeShellExecution的脚本里解析 payload 中的command若为git … commit则在cwd/workspace_roots下先跑pytest失败则打印{permission:deny,...}具体可参考全局示例%USERPROFILE%\.cursor\hooks\下的after_file_edit.py、before_shell_execution.py需与本机 Python、依赖路径一致。三、自定义 Hooks 开发3.1 Hook 脚本位置推荐放在项目.cursor/hooks/下便于版本管理全局 hook 可放在用户~/.cursor/hooks/。3.2 标准输入载荷PayloadAgent Hooks 的字段为snake_case且会包含hook_event_name、workspace_roots等。示例节选以实际版本为准afterFileEdit输入示例{hook_event_name:afterFileEdit,conversation_id:...,generation_id:...,file_path:D:\\\\proj\\\\src\\\\main.py,edits:[{old_string:...,new_string:...}],workspace_roots:[D:/proj]}beforeShellExecution输入示例{hook_event_name:beforeShellExecution,command:git commit -m \msg\,cwd:D:\\\\proj,workspace_roots:[D:/proj]}读取方式Pythonimportjsonimportsys payloadjson.loads(sys.stdin.buffer.read().decode(utf-8))3.3 标准输出响应Response不同事件要求不同必须满足 Cursor 解析规则否则日志会出现no valid response事件典型响应beforeShellExecution/beforeMCPExecution{permission:allow}或{permission:deny,userMessage:...}等beforeReadFile{permission:allow}或{permission:deny}beforeSubmitPrompt{continue: true}或{continue: false}afterFileEdit/stop通知型无强制响应格式以官方文档为准不要再使用旧文档中的虚构格式如统一的successactionsnotifications除非官方另行支持。3.4 在 hooks.json 中注册每个事件下配置一条或多条command由 Cursor 依次拉起进程{version:1,hooks:{beforeShellExecution:[{command:python -u .cursor/hooks/guard_shell.py}]}}不支持在hooks.json里声明type: script、interpreter、timeout等嵌套字段这些需在你自己的脚本或包装命令中处理。四、实战Python 质量检查思路4.1 项目结构示例my-project/ ├── .cursor/ │ ├── hooks.json │ └── hooks/ │ ├── after_file_edit.py # black flake8afterFileEdit │ └── before_shell.py # git commit 前 pytestbeforeShellExecution ├── src/ ├── tests/ └── pyproject.toml4.2 beforeShellExecution提交前跑 pytestAgent 发起 git commit 时脚本从 stdin 读 JSON若判定为git … commit则在合适的工作目录执行python -m pytest -xvs失败则向 stdout 打印denyJSON成功打印allow。要点cwd可能为空需回退到workspace_roots[0]。Windows 上workspace_roots可能出现/d:/path形式需在脚本中规范化为d:/path再chdir。pytest退出码5未收集到测试是否视为通过由团队约定。4.3 afterFileEditAgent 改完 .py 后跑 black / flake8在脚本中判断file_path.endswith(.py)再subprocess.run([sys.executable, -m, black, file_path], ...)。注意这会在Agent 已写入之后再改磁盘文件需接受与 Agent 后续步骤的时序关系。五、高级说明5.1 「条件触发」「并行」官方hooks.json不内置condition、parallel、onError等声明式字段。需要时请在单个 hook 脚本内自行分支读 payload、判断路径/命令或拆成多条command由 Cursor 顺序执行。5.2 JSON Schema 与补全可在hooks.json顶部加入$schema指向cursor-hooks发布的 schema或在 VS Code / Cursor 的settings.json里为**/.cursor/hooks.json配置json.schemas以获得校验与补全。六、故障排除6.1 常见问题现象可能原因处理Failed to parse ... hooks configuration缺少version、事件名非法、或结构不是{command}数组对照本文 2.2 与官方 schemaJSONDecodeError/ stdin 为空Windows 下通过py -3启动导致 stdin 未传入改用python.exe绝对路径 -uno valid responsebeforeShellExecution等未向 stdout 打印合法 JSON保证每条路径都有print出响应Hook 似乎从不触发未使用 Agent、或事件类型与操作不匹配确认是 Agent 改文件 / Agent 跑 shell 等场景6.2 调试建议查看 Cursor 日志中带cursor.hooks的输出其中常包含INPUT与脚本STDERR。在脚本内临时将 payload 写入用户目录下日志文件注意不要提交密钥。在终端手动模拟echo {...} | python -u your_hook.py七、下一步掌握 Agent Hooks 后你可以为团队统一Shell / 读文件安全策略在 Agent 改代码后自动跑格式化与静态检查与Git Hooks / CI分工Cursor 管 Agent 路径仓库仍可用pre-commit管本地提交。接下来学习 12-Context与Harness工程.md。

更多文章