mcpField
S
scaffold-hooks

scaffold-hooks

github.com/jpcaparasAgent 工作流5667 次安装1 天前更新
代码仓库

关于 scaffold-hooks

scaffold-hooks 是用于在仓库中创建或迁移生命周期钩子的 Agent 技能,支持 Claude Code、Codex、GitHub Copilot、Devin CLI 和 OpenCode。它会检测现有配置、保留自定义钩子,并提供预演与验证流程。

主要功能

  1. 01为五种运行环境搭建钩子
  2. 02检测并刷新现有配置
  3. 03迁移受管理的旧版钩子
  4. 04保留自定义钩子和脚本
  5. 05预演、审计和验证搭建结果

适用场景

  1. 01为新仓库配置钩子
  2. 02刷新检测到的运行环境钩子
  3. 03迁移旧版生成钩子目录

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jpcaparas/skills --skill scaffold-hooks

安装后在 Claude Code 中输入/scaffold-hooks确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

AGENTS.md
agents/
.gitkeep
assets/
harnesses.json
evals/
evals.json
harnesses/claude/
PLAYBOOK.md
harnesses/claude/assets/
hook-events.json
harnesses/claude/references/
gotchas.md
hook-events.md
merge-strategy.md
project-analysis.md
README.md
reusable-scripts.md
scaffold-layout.md
harnesses/claude/scripts/
audit_project.sh
check_workspace_trust.sh
merge_settings.sh
render_hooks_readme.sh
scaffold_hooks.sh
scaffold_paths.sh
test_skill.py
validate.py
harnesses/claude/templates/
event-script.sh.tmpl
hook-plan.example.json
harnesses/codex/
PLAYBOOK.md
harnesses/codex/assets/
hook-events.json
harnesses/codex/references/
feature-flag.md
gotchas.md
hook-events.md
merge-strategy.md
project-analysis.md

详细介绍

通用 Agent Hook 脚手架

为 Agent 生命周期 Hook 搭建脚手架或迁移 Hook,让每个选定的运行环境都指向仓库自有的 Hook 脚手架。这是唯一的 Hook 脚手架工具:原来的 scaffold-cc-hooks、scaffold-codex-hooks、scaffold-github-copilot-hooks、scaffold-devin-hooks 和 scaffold-opencode-hooks 技能已停用,并作为内部运行环境组件归入 harnesses/<name>/。

决策树

  1. 如果用户提到 /scaffold-hooks、hooks、生命周期 hooks、hook 迁移,或提到 Claude Code、Codex、GitHub Copilot、Devin CLI 或 OpenCode 的 hooks,请使用此技能。
  2. 如果用户指定了运行环境,请使用 --harnesses <list> 原样传入这些运行环境。仅针对一个运行环境的请求只需使用 --harnesses <name>。
  3. 如果用户未指定目标路径,请使用当前工作区或仓库根目录作为目标项目。
  4. 如果用户未指定运行环境偏好,请检查目标项目。如果存在任何受支持的 Hook 接入点或受管理的脚手架状态,请运行通用脚本但不带 --harnesses,以便仅刷新检测到的运行环境。除非用户明确要求,否则不要添加新的运行环境。
  5. 如果不存在受支持的 Hook 接入点,请询问要为哪些运行环境搭建脚手架。对于新脚手架,默认选择所有受支持的运行环境(claude、codex、copilot、devin、opencode)。
  6. 如果现有配置指向 .claude/hooks/generated、.codex/hooks/generated 或 .devin/hooks/generated,请将此工作视为迁移:移除这些受管理的命令条目,搭建 hooks/,并且仅移除包含清单的旧版受管理文件夹。
  7. 如果项目在受管理根目录之外有自定义 hooks,请予以保留,除非用户明确要求删除。

运行环境选择

选择顺序确定如下:

  1. 用户明确指定的 --harnesses。
  2. 自定义通用计划中存在的 harnesses 列表。
  3. 目标仓库中检测到的现有 Hook 接入点或受管理的脚手架状态。
  4. 仅当以上均不存在时,使用默认的所有受支持运行环境。

检测到的接入点包括当前受管理的清单、旧版生成的清单、hooks/ 下的共享适配器,以及已包含 Hook 条目的运行环境配置文件。如果检测到任何运行环境,未经用户明确指示,不要扩展到其他运行环境。

  • claude — Claude Code,.claude/settings.json
  • codex — Codex CLI,.codex/hooks.json(需要启用 hooks 功能标记;参见 harnesses/codex/references/feature-flag.md)
  • copilot — GitHub Copilot(云端 Agent + CLI),.github/hooks/copilot-hooks.json,生成的事件位于 .github/copilot/hooks/generated/
  • devin — Devin CLI,.devin/hooks.v1.json
  • opencode — OpenCode,通过 opencode-froggy 使用 opencode.json 和 .opencode/hook/hooks.md

使用 --harnesses claude,codex,copilot,devin,opencode(或其中一个子集)显式传入要添加的运行环境。在已有 hooks 的仓库中直接运行只会刷新,不会扩展。

快速参考

任务命令
刷新检测到的现有运行环境,或在干净仓库中搭建所有环境scripts/scaffold_all_hooks.sh --project /path/to/project
预览而不写入文件scripts/scaffold_all_hooks.sh --project /path/to/project --dry-run
使用项目专属的通用计划scripts/scaffold_all_hooks.sh --project /path/to/project --plan /path/to/scaffold-hooks.json
仅为选定的运行环境搭建脚手架scripts/scaffold_all_hooks.sh --project /path/to/project --harnesses claude,codex
刷新运行环境适配器,同时保留共享事件脚本scripts/scaffold_all_hooks.sh --project /path/to/project --mode overhaul
审计某个目标仓库中的一个运行环境harnesses/<name>/scripts/audit_project.sh /path/to/project
验证运行环境组件python3 harnesses/<name>/scripts/validate.py harnesses/<name>
运行运行环境测试套件python3 harnesses/<name>/scripts/test_skill.py harnesses/<name>

标准工作流

  1. 先检查目标项目:
    • 现有的 .claude/settings*.json
    • .codex/hooks.json 和 .codex/config.toml
    • .devin/hooks.v1.json 和 .devin/config*.json
    • opencode.json、.opencode/hook/hooks.md、旧的 .opencode/plugins/.managed/,以及任何自定义的 .opencode/plugins/
    • .github/hooks/copilot-hooks.json 和 .github/copilot/hooks/generated/
    • 现有的 hooks/ 目录树和 scripts/ 下由仓库管理的验证脚本
  2. 仅在创建新脚手架或添加 harness 时,确认 harness 集合。若在已有 hook 配置的仓库中直接运行,只刷新检测到的集合。
  3. 使用仓库配置、已安装版本的证据,以及所选 harness 的 PLAYBOOK.md 来规划修复。如果这些证据不足、似乎已过时,或事件语义将发生变化,请查阅相关的官方实时文档;对于稳定的本地修复,不要浏览每个 harness。每个组件都在 harnesses/<name>/assets/hook-events.json 中记录其捆绑契约。只在有疑问时加载参考资料。
  4. 从 templates/hook-plan.example.json 开始,除非项目已有更清晰的计划。
  5. 先运行带有 --dry-run 的 scripts/scaffold_all_hooks.sh,然后不带 --dry-run 再运行一次。
  6. 检查 hooks/README.md、hooks/.state/scaffold-hooks/manifest.json、harness 配置文件和所选适配器。
  7. 运行项目的常规验证。

输出形式

捆绑的 Claude、Codex、Devin 和 Copilot 生成器使用 Bash 入口点,并渲染清单中的所有事件,但只接入已启用的事件。共享目录树是生成器的约定,并非每个 harness 或仓库的要求。将合适的仓库自有程序保留在 Bash 协议边界之后;这些辅助工具不提供仅包含所选事件的文件布局。保留现有的自定义架构,不要仅为匹配此模式而替换它们:

hooks/
  README.md
  lib/
    agent-hook-runtime.sh
    claude.sh
    codex.sh
    devin.sh
  .state/
    scaffold-hooks/
      manifest.json
    claude/
    codex/
    devin/
  stop/
    script.sh
    claude.sh
    claude.json
    codex.sh
    codex.json
    devin.sh
    devin.json
.opencode/
  hook/
    hooks.md
    README.md
    .managed/
      manifest.json
      plan.snapshot.json
opencode.json

Harness 配置文件应保留在其文档规定的位置:

  • Claude:.claude/settings.json
  • Codex:.codex/hooks.json
  • Devin:.devin/hooks.v1.json
  • OpenCode:opencode.json 加载 opencode-froggy;Froggy 读取 .opencode/hook/hooks.md
  • GitHub Copilot:.github/hooks/copilot-hooks.json,生成的事件位于 .github/copilot/hooks/generated/ 下(独立完整,因为 Copilot 云 Agent 会从仓库读取所有内容)

计划格式

使用 templates/hook-plan.example.json 作为通用计划架构的准确信息来源。顶层计划控制共享行为:

  • mode:additive 或 overhaul
  • hooks_root:通常为 hooks
  • cleanup_legacy:仅当旧的受管生成目录中包含清单时才将其移除
  • harnesses:claude、codex、copilot、devin、opencode 的子集;仅在有意选择或扩展 harness 集合时使用
  • plans:传递给各 harness 组件的逐 harness 计划对象

添加项目专用脚本或命令前,请阅读 references/plan-format.md。

信任与输出边界

计划和现有钩子配置属于可执行的项目策略,并非来自任意代码仓库的安全数据。启用钩子或运行会执行这些配置的测试前,请先检查其中的命令、脚本路径、工作目录和引用的代码。Shell 命令和 Froggy 操作可以使用 Agent 的文件系统、网络和凭据;输出路径检查不会对这些命令进行沙箱隔离。请在不含敏感凭据的隔离环境中测试不受信任的钩子。

项目脚手架会拒绝绝对路径、相对于主目录的路径、遍历父目录的路径以及符号链接输出路径,包括托管目录树内的链接。Universal 运行会在更改配置或移除托管输出前,预先检查所有选定的工具。对于被拒绝的目标路径,请与用户确认解决方案,不要删除链接,也不要将私有配置移入代码仓库。

OpenCode 全局作用域需要用户明确授权并指定 --allow-global-targets;输出必须位于 ~/.config/opencode/ 下。启用 Codex 用户级功能时,也必须先获得授权,才能选择用户作用域。不要为了绕过项目路径检查而更改任一作用域。这些检查旨在保护稳定的文件系统,而非防范被对手同时修改的文件系统。

冲突策略

此技能采取保守策略:

  • 追加新的 hooks/<event>/<harness>.sh 命令前,先移除旧的托管生成根目录命令。
  • 保留同一配置文件中的非托管自定义钩子。
  • 保留现有的 hooks/<event>/script.sh 文件,避免其他工具重写共享的项目行为。
  • 在 overhaul 模式下,仅删除 hooks/ 下选定工具的适配器和状态,然后对 Shell 工具以增量模式调用工具组件。
  • 对于 OpenCode,保留非托管的 .opencode/plugins/ 文件,但将脚手架拥有的插件输出迁移至 opencode-froggy 和 .opencode/hook/hooks.md。

更改合并行为前,请阅读 references/collision-policy.md。

工具组件

每个受支持的工具都是 harnesses/<name>/ 下的独立组件,包含自己的 PLAYBOOK.md、脚手架脚本、事件清单、模板、参考资料、验证器和测试套件:

  • harnesses/claude/ 负责 Claude Code 事件语义和 .claude/settings.json 合并。
  • harnesses/codex/ 负责 Codex 事件语义、功能标志处理和 .codex/hooks.json 合并。
  • harnesses/devin/ 负责 Devin 事件语义和 .devin/hooks.v1.json 合并。
  • harnesses/opencode/ 负责 OpenCode Froggy 配置、opencode.json 插件合并,以及清理先前由脚手架生成的本地插件产物。
  • harnesses/copilot/ 负责 GitHub Copilot 事件语义,以及为云端 Agent 和 Copilot CLI 合并 .github/hooks/copilot-hooks.json。

事件名称、匹配器、输出契约或功能标志发生变化时,请遵循下方的基于来源的更新流程。对于已获授权的包更新,请先更改工具组件(清单、参考资料、脚本、测试),然后再更改通用编排。更改组合顺序或添加工具时,请阅读 references/harness-composition.md。

协议输出规范

将 stdout 视为 harness 协议的一部分,而不是临时日志。对于 JSON 输出钩子,stdout 仅用于输出最终协议 JSON 载荷;成功的无操作路径应保持静默,除非事件契约明确允许向 stdout 输出内容。将诊断信息、调试文本、文件名和人类可读的失败详情发送到 stderr,除非 harness 要求将它们输出到 stdout。

谓词必须保持静默,且只返回退出状态。其他辅助程序不得将未捕获的输出泄漏到协议 stdout;生成值的辅助程序可以返回捕获的数据,指定的协议发送器可以写入事件的 JSON。使用 grep -q / grep -Eq 这类静默检查,或将 stdout 重定向到 /dev/null;除非输出已被捕获且不会泄漏到钩子 stdout,否则不要使用 grep ... | head -1 这类文件名探测。已知回归问题:hook_has_code_changes 必须保持为仅返回退出状态的谓词。

验证生成的 JSON 输出钩子:静默成功/无操作路径的 stdout 必须为空;输出上下文或决策时,只能输出一个可解析且符合事件要求的 JSON 载荷,不能带前缀或后缀;共享辅助程序不能泄漏文件名/调试/状态行。分别保留每个事件的退出码契约。

注意事项

  1. 不要在通用运行中直接向 shell harness 脚手架传入 overhaul。它们会重写共享的 script.sh 文件。通用脚本会先清理 harness,然后再以增量方式调用它们。
  2. OpenCode 现在使用 opencode-froggy 作为插件层。除非用户明确要求自定义插件代码,否则不要重新创建旧的生成版 .opencode/plugins/*.ts 生命周期适配器。
  3. 仅当旧版生成目录中包含受管理清单时才应删除。否则,其中可能是用户自己的文件,只是路径名称不太合适。
  4. 配置看起来干净,并不代表没有冲突:旧的生成命令仍可能存在。始终检查最终配置中是否包含 .claude/hooks/generated、.codex/hooks/generated 和 .devin/hooks/generated。
  5. 将项目策略保留在仓库自有脚本中,例如 ./scripts/agent-stop-checks.sh;钩子适配器应转换协议,而不是重复验证逻辑。生成的 shell Stop 适配器默认设置 run_on_code_changes: true,并使用检测到的源文件/配置文件扩展名,以避免在代码未变更的回合运行开销大的检查。
  6. Copilot 不会将适配器写入共享的 hooks/ 目录。它生成的事件保留在 .github/copilot/hooks/generated/ 下,因为 Copilot 云端 Agent 只会读取已提交到仓库的文件;将共享策略放在仓库自有的 scripts/ 中,供两层共同调用。
  7. 共享的 SessionStart 上下文脚本可以对 Claude、Codex 和 Devin 使用经过专门验证的 hookSpecificOutput.additionalContext JSON 结构。该共享结构并不意味着它兼容其他事件或字段。参见 references/harness-composition.md,了解 Devin 记录在文档中的 JSON 结构和历史纯文本失败证据。
  8. 将退出码和输出流视为彼此独立的契约。退出码控制成功、失败或阻止操作;stderr 用于诊断和说明失败原因,而不是输出成功状态消息。成功的常规跳过操作只有在 harness 协议允许时才应向 stdout 写入内容,否则应保持静默。
  9. Froggy 的 isMainSession 条件可为 OpenCode 钩子处理主会话筛选;对于应跳过子会话/子 Agent 会话的会话生命周期钩子,请使用此条件。
  10. 受管理清单会记录脚手架技能来源、计划/模板哈希、选定的 harness、检测到的 harness、选择来源以及受管理文件哈希。重新运行时应使用这些快照来刷新未被修改的受管理适配器,同时保留用户修改过的文件。
  11. 单独调用 /scaffold-hooks 时会采取保守策略。如果检测到任何受支持的钩子接口,只刷新检测到的那组;除非用户明确要求,否则不要扩展到其他 harness。

Hook 可见性矩阵

不同 Harness TUI 对 Hook 活动的可见性各不相同。在搭建脚手架时明确说明预期表现,避免用户将无响应误认为故障:

Harness是否在 TUI 中呈现 Hook 运行情况通过以下方式验证 Hook
Claude Code部分可见(错误、详细模式)/hooks、对话记录
Codex CLI是(“Running SessionStart hook”,Hook 上下文内联显示)内联可见
Devin CLI否(即使成功也不显示;截至 v2026.5.26-8,不呈现 systemMessage)/hooks、CLI 日志、对话记录 JSON、询问 Agent
OpenCode由插件定义插件日志
GitHub Copilot云端 Agent:会话日志;CLI:因情况而异会话日志、.github/copilot/hooks/generated/ 输出

渐进式维护者漂移检查

将记录的版本和日期视为验证基线,而不是永久的运行要求。对于不确定或可能变化的约定,请查阅相关官方文档;必要时,核对与已安装版本相匹配的源代码或架构证据。main 分支可能描述尚未发布的行为。除非经过验证且变更属于当前范围,否则应保留确定性版本锁定。

如果证据表明指南已过时,请记录受影响的段落、当前官方来源及适用的版本/日期、建议的修正内容和回归检查。应提出更新建议,而不是悄悄修改已安装的技能。只有在维护工作属于当前范围时,才编辑规范包;随后,在调整通用编排之前,应协调更新受影响的清单、引用、生成器、模板、验证器和测试。对于不受支持的漂移,应如实报告,不要声称随附的辅助工具已实现相关更新。对于仅涉及措辞或已知的本地修复,无需全面检查在线文档。

尽早检查信任状态和实际生效的功能状态,但在激活状态尚未确定时,仍可进行独立的只读诊断。更改信任状态、用户/全局设置或策略之前,必须获得授权;切勿绕过这些门槛来让脚手架看起来已激活。

评论

支持 Markdown