ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

如何为 OpenHuman 编写 Hooks 脚本:用 beforeShellExecution 拦截危险命令并用 afterFileEdit 自动格式化

如何为 OpenHuman 编写 Hooks 脚本:用 beforeShellExecution 拦截危险命令并用 afterFileEdit 自动格式化 如何为 OpenHuman 编写 Hooks 脚本用 beforeShellExecution 拦截危险命令并用 afterFileEdit 自动格式化【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman当 OpenHuman 的 agent 在你的仓库里执行工具时你可能需要让它在动 shell 之前过一道自己的规则比如拒绝rm、dd、mkfs这类破坏性命令并在每次改完文件后自动跑一遍格式化。OpenHuman 的文件式 Hooks 就是为这个任务设计的由你拥有、放在仓库里的脚本在工具执行前后由 OpenHuman 运行agent 会服从脚本给出的裁决。脚本契约与 Cursor 的 hooks 保持一致同文件名、同事件名、同 stdin 信封、同 stdout 裁决、同退出码为其中一方编写的脚本可以不加修改地用在另一方。完整协议见 Hooks 文档。本文只做两件事用beforeShellExecution拦截危险 shell 命令用afterFileEdit在文件编辑后自动格式化。把 hooks.json 放在哪一层hooks.json是 schema version 1 的 JSON 文件。OpenHuman 会读取四个位置并且是拼接而不是覆盖——更具体的文件无法移除更宽泛文件里已配置的规则层路径System/etc/openhuman/hooks.json·/Library/Application Support/OpenHuman/hooks.json·%ProgramData%\OpenHuman\hooks.jsonUser~/.openhuman/hooks.jsonWorkspaceworkspace_dir/hooks.jsonProjectaction_dir/.openhuman/hooks.json拼接是安全的因为最严格的裁决获胜所有跑过的 hook 中 deny 优先于 askask 优先于 allow。给仓库自带一份.openhuman/hooks.json不会削弱运维已经在系统层锁定的策略这正是仓库级规则可以放心随仓库分发的原因。本文的两个 hook 都放在项目层.openhuman/hooks.json随仓库提交{ version: 1, hooks: { beforeShellExecution: [ { command: ./.openhuman/deny-destructive.sh, matcher: ^\\s*(rm|dd|mkfs)\\b, timeout: 5, failClosed: true } ], afterFileEdit: [ { command: ./.openhuman/fmt.sh, matcher: \\.rs$ } ] } }各字段含义以 hooks 文档 为准字段含义command要运行的程序进程以所在hooks.json目录为 cwd 运行typecommand默认或promptmatcher哪些事件会命中该 hook缺省表示全部命中timeout秒数未写时回落到[hooks] default_timeout_secs30failClosed脚本崩溃、缺失或超时时按拒绝处理。默认falseenabled置false可以保留但不启用某个 hook两个关键取舍要说明beforeShellExecution是门控事件turn 会等它跑完拒绝会短路后续 hook。所以拦截类 hook 应设置短的timeout和failClosed: true——文档明确说“只在脚本跑成功时才拒绝的 hook 不是安全控制”failClosed覆盖脚本所有答不上来的路径超时、解释器缺失、stdout 无法解析。afterFileEdit是观察类事件被分发到后台任务执行turn 不等它一个卡死的格式化 hook 不会拖住 agent。脚本与 OpenHuman 之间的协议事件以单个 JSON 对象从stdin传入裁决写到stdout退出码决定 stdout 怎么被解读退出码含义0stdout 即裁决stdout 为空表示无操作2无论 stdout 写什么都拒绝stderr 成为告知 agent 的原因其他失败默认放行fail open除非配置了failClosedstdout 解析是宽松的——最后一个独立 JSON 对象生效——所以脚本先打日志再输出裁决也能正常工作。beforeShellExecution事件中脚本可使用的裁决对象各字段均可选{ permission: allow | deny | ask, user_message: shown to the human, agent_message: shown to the model }其中ask在有审批通道的地方会升级到审批门在没有审批通道的工具中间件里ask直接按拒绝处理而不是悄悄放行。matcher 的匹配对象由事件决定shell 事件匹配命令行文件事件匹配路径。写法规则缺省或*匹配全部无标点的字符串按字面名不区分大小写含标点的按正则解释如^rm\b、\.rs$。非法正则不匹配任何东西并记录日志。beforeShellExecution拦截破坏性命令.openhuman/deny-destructive.sh只需要输出一个 deny 裁决。OpenHuman 文档给出了同类 hook 的完整范式no-secrets.sh拒绝类脚本沿用同样的 stdout 裁决格式即可#!/bin/sh cat /dev/null # 排空 stdin本 hook 不解析事件体 echo {permission:deny,agent_message:Destructive command blocked by project policy. Ask the user before running it.}不想写 JSON 时也可以用退出码路径脚本直接exit 2stderr 里的内容会成为告知 agent 的原因。注意两点command以 hook 所在hooks.json的目录为 cwd 运行所以./.openhuman/deny-destructive.sh这样的相对路径是相对项目根.openhuman/解析的。两个脚本都需要chmod x否则脚本“缺失/无法运行”会走失败路径——配合failClosed: true拦截类 hook 的失败会按拒绝处理。hook 进程继承 core 的环境变量另加OPENHUMAN_PROJECT_DIR同时导出为CLAUDE_PROJECT_DIR、CURSOR_PROJECT_DIR、OPENHUMAN_VERSION、OPENHUMAN_HOOK_EVENT、OPENHUMAN_SESSION_ID、OPENHUMAN_AGENT_ID脚本需要项目路径时直接取用即可。afterFileEdit编辑后自动格式化afterFileEdit在file_write/edit/apply_patch之后触发matcher 匹配文件路径\\.rs$表示只对 Rust 文件生效。文档给出的格式化脚本#!/bin/sh cat /dev/null # drain stdin; this hook does not read the event cargo fmt /dev/null 21 echo {}脚本先排空 stdin不解析事件体跑cargo fmt再输出{}。stdout 为空对象即“无操作”裁决——格式化结果本身写在文件系统里不通过 stdout 传回。观察类事件只认additional_context之类的字段子集这里不需要它。如果你的仓库不只格式化 Rust按同样的 matcher 语法追加条目即可如\\.ts$对应前端项目但每个格式化器都走后台任务不阻塞 turn。主机开关config.tomlHooks 总开关在config.toml[hooks] enabled true # off means no hooks.json is read and no bridge installed default_timeout_secs 30 # for hooks that name no timeout of their ownenabled false时不读取任何hooks.json也不安装 bridge。未配置任何 hook 时harness bridge 根本不安装未配置的主机每次工具调用零开销。验证 hook 是否生效用hooks命名空间下的三个 RPC 方法核对不要靠让 agent 真的做危险操作来试探openhuman hooks list # 已配置了什么、来自哪个文件、是否已接线wired openhuman hooks reload # 重新读取所有层 openhuman hooks test --event beforeShellExecution \ --payload {command:rm -rf /,sandbox:false}hooks test在前台触发一个合成事件报告每个命中 hook 的裁决——包括观察类事件在真实分发中会后台跑的那些 hook。文档明确建议调试 hook 用hooks test而不是“让 agent 试一下看规则触发没”。JSON-RPC 上对应openhuman.hooks_list、openhuman.hooks_reload、openhuman.hooks_test。验证路径openhuman hooks list应列出.openhuman/hooks.json中的两个 hook且beforeShellExecution为已接线状态hooks test --event beforeShellExecution的载荷{command:rm -rf /,...}会命中^\\s*(rm|dd|mkfs)\\b应看到 deny 裁决改过任何一层hooks.json后跑openhuman hooks reload再复测。限制与已知边界beforeShellExecution覆盖shell/node_exec等命令执行shell、文件、MCP 事件都是从普通工具调用派生的通用preToolUse会先于专门事件触发。sessionStart、sessionEnd、preCompact、afterAgentThought已定义、可被hooks test演练但 core 尚不触发它们配置了会得到加载警告hooks list报告wired: false。这是刻意设计——文档的原话是“一个从不运行且静默的 hook 是这套系统能对你做的最坏的事”。事件名匹配宽松preToolUse、PreToolUse、pre_tool_use是同一个事件。实现入口在 src/openhuman/hooks/types线上契约、config文件与分层合并、matcher、execstdin/超时/退出码、engine选择、排序、聚合、bridge挂到 harness 的工具/turn 接缝上。要改行为而不是加脚本时从这份模块表找对应文件。文档中还有一类同名但无关的 “hook”src/openhuman/agent/hooks.rs里的进程内 Rust trait是嵌入方编译时安装、用于在 OpenHuman 之上构建产品的本文只讲文件式的、用于使用 OpenHuman 的这一类。【免费下载链接】openhumanOpenHuman is an open source personal AI for Mac, Windows and Linux — local-first memory, agent orchestration, and deep research.项目地址: https://gitcode.com/GitHub_Trending/op/openhuman创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表