init-hooks
- Version: 1.0.0
- License: MIT
- Author: Evan Song · github.com/Songhonglei
- Repository: https://github.com/Songhonglei/better-agent-skills (skills/init-hooks)
管理 OpenClaw 容器/主机启动时自动执行的脚本钩子。gateway 重启、容器重启、容器重建均不丢失(数据持久化在
workspace/.init-hooks/)。支持 inline 命令 / 本地脚本(shell·python)/ CDN URL(zip·tar.gz 自动下载解压)三种钩子类型。
路径约定
~/.openclaw/workspace/.init-hooks/
├── hooks.json # 注册表(truth)
├── dispatcher.sh # 自动生成,post-init.sh 调用这个
├── last-run.log # 每次启动执行日志
└── downloads/ # CDN URL 钩子下载缓存
└── hook_<id>.*
脚本路径:
~/.openclaw/workspace/skills/init-hooks/scripts/
├── manage.py # 主入口(所有 CRUD + run + install)
└── sync_openclaw_config.py # openclaw.json 多路径同步工具
操作命令速查
所有操作通过 exec 运行,工作目录任意:
SCRIPT="$HOME/.openclaw/workspace/skills/init-hooks/scripts/manage.py"
python3 $SCRIPT install # 首次安装
python3 $SCRIPT list # 列出所有钩子
python3 $SCRIPT show <id> # 查看钩子详情
python3 $SCRIPT add ... # 新增(见下方)
python3 $SCRIPT edit <id> ... # 修改
python3 $SCRIPT enable <id> # 启用
python3 $SCRIPT disable <id> # 禁用
python3 $SCRIPT delete <id> # 删除(需二次确认)
python3 $SCRIPT delete <id> --force # 强制删除不确认
python3 $SCRIPT run # 立即运行所有启用的钩子
python3 $SCRIPT run <id> # 立即运行指定钩子
python3 $SCRIPT status # 查看安装状态
新增钩子:三种类型
inline(内嵌 shell 命令)
python3 $SCRIPT add \
--name "初始化日志目录" \
--type inline \
--content "mkdir -p ~/logs && echo 'started' >> ~/logs/boot.log"
多行命令用 \n 分隔:
python3 $SCRIPT add \
--name "环境变量初始化" \
--type inline \
--content $'export MY_VAR=hello\nmkdir -p ~/tmp'
script(本地 shell 脚本)
python3 $SCRIPT add \
--name "凭证/账号启动恢复" \
--type script \
--path "~/.openclaw/workspace/scripts/restore-credentials.sh"
python(本地 Python 脚本)
python3 $SCRIPT add \
--name "Agent workspace 配置" \
--type python \
--path "~/.openclaw/workspace/scripts/set-agents.py"
CDN URL(zip/tar.gz 自动下载解压)
python3 $SCRIPT add \
--name "远程初始化包" \
--type script \
--url "https://cdn.example.com/my-init.zip" \
--entry "run.sh" # 压缩包内入口文件名(不指定则自动找第一个 .sh/.py)
首次执行(启动或 run 命令)时自动下载解压到 downloads/hook_<id>/,缓存存在则直接使用,pod 重建后缓存丢失会自动重新下载。
追加 --order 控制执行顺序(默认步进 10)
python3 $SCRIPT add --name "..." --type inline --content "..." --order 5
修改钩子
# 改名称
python3 $SCRIPT edit 2 --name "新名称"
# 改内容
python3 $SCRIPT edit 2 --content "new command"
# 改路径
python3 $SCRIPT edit 1 --path ~/scripts/new.sh
# 改顺序
python3 $SCRIPT edit 1 --order 15
# 改为 URL 模式
python3 $SCRIPT edit 1 --url https://... --entry run.sh
openclaw.json 变更必须同步持久化路径
触发场景: 用户说「修改 openclaw.json」「改 gateway 配置」「给我改配置」,或者用户直接提供了修改 openclaw.json 的脚本/内容。
必须在改完后立即执行:
SYNC="$HOME/.openclaw/workspace/skills/init-hooks/scripts/sync_openclaw_config.py"
# 场景1:Agent 直接 patch(最常用)
python3 $SYNC --patch '{"acp": {"enabled": true}}'
# 场景2:用户提供了修改脚本,执行完后自动同步
python3 $SYNC --run ~/scripts/patch_config.py
# 场景3:inline 命令修改后同步
python3 $SYNC --run-inline "sed -i 's/old/new/' ~/.openclaw/openclaw.json"
# 场景4:只同步(已手动改了 runtime)
python3 $SYNC
# 检查各处是否一致
python3 $SYNC --check
同步路径(跨部署环境可配置):
~/.openclaw/openclaw.json(runtime,source of truth,始终维护)- 额外持久化目标:由环境变量
INIT_HOOKS_SYNC_PATHS(冒号分隔)配置,不存在的路径自动跳过
# 纯本地/单机:通常无需额外同步,留空即可(只维护 runtime 一份)
# 容器/K8s:把 runtime 之外的持久化挂载点填进来(按你自己的挂载布局替换示例)
export INIT_HOOKS_SYNC_PATHS="/app/clawconfig/openclaw.json:/app/k8s-config/clawconfig/openclaw.json"
未配置 INIT_HOOKS_SYNC_PATHS 时只维护 runtime 一份(本地环境属正常)。
安装流程(install)
install 是幂等的,可重复执行:
- 创建
~/.openclaw/workspace/.init-hooks/目录 - 初始化
hooks.json(若已存在则跳过) - 生成
dispatcher.sh - 检查
~/.openclaw/workspace/scripts/post-init.sh:- 存在 → 在末尾追加 dispatcher 调用(有标记防重复注入)
- 不存在 → 创建,内容只有 dispatcher 调用
- 检查容器启动脚本(
/app/start.sh,可用INIT_HOOKS_START_SH覆盖;本地无此文件时跳过):- 已有
# post-init hook→ 间接调用,跳过 - 否则在末尾追加 dispatcher 直接调用
- 已有
执行行为
- 宽松模式:单个钩子失败不中断后续
- 顺序执行:按
order字段从小到大 - 日志:每次执行追加到
last-run.log,同时 tee 到 stdout - 执行摘要:每次执行结束后打印成功/失败列表
关于 start.sh 注入
install 会尝试向容器启动脚本(默认 /app/start.sh,可用 INIT_HOOKS_START_SH 覆盖)注入 dispatcher 调用。大多数用户没有写权限、或本地环境根本没有这个文件,都属正常情况,不影响使用:
post-init.sh已注入 → dispatcher 经由 post-init.sh 间接调用- 启动脚本注入失败/不存在提示
ℹ️而非⚠️或❌,无需担心
用户意图识别
| 用户说 | Agent 动作 |
|---|---|
| 帮我安装 / 初始化 / 设置 init-hooks | install |
| 添加一个启动钩子 / 加一个开机执行 | add |
| 列出 / 查看所有钩子 | list |
| 查看钩子 #2 / 第2个钩子内容 | show 2 |
| 修改钩子 #1 | edit 1 ... |
| 禁用 / 停用 / 关闭 钩子 #3 | disable 3 |
| 删除钩子 #2 | delete 2(展示详情后二次确认) |
| 立即运行 / 测试一下 / 跑一遍 | run |
| 只运行钩子 #1 | run 1 |
| 查看状态 / 安装了吗 | status |
| 修改 openclaw.json / 改 gateway 配置 | 改完后 sync_openclaw_config.py |
| 查看上次执行日志 | read ~/.openclaw/workspace/.init-hooks/last-run.log |
钩子编写规范
详见 references/best-practices.md,包含三种类型的完整示例、路径规范、执行顺序建议。
核心规则: 钩子内容禁止硬编码 /home/node/,必须用 $HOME(shell)或 Path.home()(Python)。
注意事项
- 每次
add/edit/enable/disable/delete后,dispatcher.sh自动重新生成 - CDN URL 钩子:首次
run时下载,缓存在downloads/;re-install 不清除缓存(需手动删downloads/hook_<id>/) delete --force跳过确认,Agent 不应使用(除非用户明确说"直接删")- hooks.json 是 truth,dispatcher.sh 是生成物,手动改 dispatcher.sh 会在下次操作时被覆盖