mcpField
H
hookshot

hookshot

github.com/fellowship-devAgent 工作流3185 次安装2 周前更新
代码仓库

关于 hookshot

hookshot 是用于 Claude Code 和 Codex 的技能,可从仓库文档生成 Agent 提醒和检查钩子。它默认只发出指导信息;交付门禁可先记录模拟结果,再由仓库选择是否启用阻止模式。

主要功能

  1. 01根据文档生成编辑提醒钩子
  2. 02警告已追踪技能的本地修改
  3. 03对 Markdown 文件运行 lint
  4. 04提供会话预检与交付门禁
  5. 05合并现有钩子且避免重复

适用场景

  1. 01修改关键代码前提示 Agent 阅读相关文档
  2. 02发现同步技能被编辑时提醒回馈上游
  3. 03编辑 Markdown 后显示 lint 警告
  4. 04根据结果决定是否阻止未满足交付约定的会话结束

安装

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

$npx skills add https://github.com/fellowship-dev/dogfooded-skills --skill hookshot

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

包含的文件

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

references/
contract-format.md
shadow-log.md
scripts/
gate.py
preflight.py
test_gate.py

详细介绍

Hookshot

从文档到强制执行钩子。读取你编写的文档,并生成让 Agent 阅读文档的钩子。

理念: Hookshot 默认发出警告,只有仓库主动选择启用的门禁才会阻止操作。它绝不会修改文件,也不会执行检查并自动修复。它生成的每个钩子都会提供指导并以状态码 0 退出;唯一的例外是交付门禁,仓库可以在查看自己的影子日志后,将其从影子模式(仅记录)切换为强制模式(拒绝停止)。

模式

Hookshot 可组合使用——可通过一个或多个标志调用。默认模式(不带标志)运行文档覆盖率生成器。

标志添加的功能
(无标志)文档覆盖率 — PreToolUse Edit/Write 钩子,在编辑受覆盖的文件前,提醒 Agent 阅读相关的 docs/ 部分。(默认行为,详见下文。)
--drift-warn技能漂移警告 — PreToolUse Edit/Write 钩子,当 Agent 编辑 .claude/skills/<name>/ 中属于 skills-lock.json 所追踪技能的文件时发出警告。应在上游进行编辑。
--md-lintMarkdown 检查 — PostToolUse Edit/Write 钩子,对任何有改动的 *.md 文件运行 npx markdownlint-cli2,并显示警告。绝不自动修复。
--preflight会话预检 — SessionStart 钩子(启动、恢复、清除、压缩),告知 Agent 其会话 ID、为任务运行预检的要求,以及记录其结果契约指针的位置。附带 scripts/preflight.py。
--gate交付门禁 — Stop 钩子,将现有内容与会话的结果契约进行比对。影子模式会记录可能拒绝停止的情况;强制模式会拒绝停止。附带 scripts/gate.py、references/contract-format.md、references/shadow-log.md。

标志可以组合使用:/hookshot --drift-warn --md-lint 会在默认的文档覆盖率钩子之外,同时安装这两个新钩子。只有 --preflight 和 --gate 模式会附带自己的脚本,也只有这两种模式会同时安装到 Codex 和 Claude Code。再次运行 Hookshot 会以幂等方式合并现有钩子。

通过 npx 安装:

npx skills add fellowship-dev/dogfooded-skills/ops/hookshot

适用场景

  • 创建知识层(ARCHITECTURE.md、docs/)后——Hookshot 会将其接入 Agent 运行时
  • 更新 docs/code-structure.md 或 docs/code-guidelines.md 后——重新生成钩子以保持内容最新
  • 出现 #1585-class bug 时:Agent 未阅读文档便修改了关键路径——添加钩子以防止问题再次发生
  • 添加新的 FlowChad 流程后——为该关键路径生成钩子

与 Pylot 集成

  • 安装: boot-skills.sh 会通过 npx skills add 安装 Hookshot 技能。但安装技能 ≠ 生成钩子。你必须至少运行一次 /hookshot,以生成相关产物(doc-coverage.json、check-docs.sh、settings.json 钩子、docs/hooks.md)。
  • 过时检查: entropy-check 会在 PR 合并时以及每周定时任务中监控 Hookshot 覆盖率是否为最新内容。发现内容过时后,重新运行 /hookshot。
  • 按仓库配置: 每个仓库都有自己的钩子。跨仓库任务使用目标仓库的钩子。

关键见解

“由于这些检查是自定义的,我们会编写错误消息,将修复指导注入 Agent 上下文。” ——OpenAI harness engineering

Hookshot 会自动完成这件事。它本可以告知 Agent“修改此区域前,先了解 check_redirect 的工作方式”——此技能会根据你的文档生成这条消息。

生成内容

  1. check-docs.sh — 给定正在编辑的文件,如果该文件受 docs/ 中的文档覆盖,则向 stderr 输出文档提醒
  2. .claude/settings.json 钩子 — 在每次 Edit/Write 时调用 check-docs.sh 的 PreToolUse 钩子
  3. 领域覆盖映射 — $REPO_ROOT/.claude/doc-coverage.json — 将文件 glob 映射到文档部分
  4. 自定义检查消息 — 包含特定文档部分链接的修复指导

说明

0. 确定仓库
REPO_ROOT=$(git rev-parse --show-toplevel)
REPO_NAME=$(basename $(git remote get-url origin) .git)
mkdir -p $REPO_ROOT/.claude
1. 解析知识层

读取所有文档文件并提取覆盖映射:

# Read all key docs
cat $REPO_ROOT/docs/code-structure.md 2>/dev/null
cat $REPO_ROOT/docs/code-guidelines.md 2>/dev/null
cat $REPO_ROOT/ARCHITECTURE.md 2>/dev/null
ls $REPO_ROOT/.flowchad/flows/ 2>/dev/null

针对 docs/code-structure.md 中的每个领域部分,提取:

  • 领域名称(章节标题)
  • 目录路径(“Directory:” 行)
  • 关键文件(来自 Entry Points 表格)
  • 关键模式(“Don't Repeat”部分——优先级最高)

针对 .flowchad/flows/ 中的每个 FlowChad 流程:

  • 流程名称
  • 领域
  • 入口点文件(来自流程定义)
  • 涉及的文件(流程中所有 file: 条目)
2. 构建覆盖映射

创建 $REPO_ROOT/.claude/doc-coverage.json:

{
  "version": "1",
  "generated": "{DATE}",
  "repo": "{REPO_NAME}",
  "entries": [
    {
      "glob": "app/controllers/**/*.rb",
      "domain": "Controllers",
      "doc_section": "docs/code-structure.md#controllers",
      "reminder": "Before modifying a controller, read how the controller pattern works: docs/code-structure.md#controllers. Key rule: controllers do not query the DB directly — use service objects.",
      "criticality": "high"
    },
    {
      "glob": "app/services/**/*.rb",
      "domain": "Services",
      "doc_section": "docs/code-structure.md#services",
      "reminder": "Service objects in app/services/ follow the Command pattern. Read docs/code-structure.md#services for the interface contract.",
      "criticality": "medium"
    }
  ]
}

为每个领域目录映射创建一个条目。对于关键路径(在 FlowChad 流程中发现的路径),将 criticality 设为 "high"。

提醒文本规则:

  • 以要阅读的具体文档章节开头
  • 包含该领域最重要的“Don't Repeat”规则
  • 不超过 200 个字符——这会显示在 Agent 上下文中,而不是一大段文字
  • 具有可操作性:“阅读 X”,而不是“可以考虑阅读 X”
3. 生成 check-docs.sh

写入 $REPO_ROOT/.claude/check-docs.sh:

#!/usr/bin/env bash
# check-docs.sh — Generated by hookshot on {DATE}
# Usage: check-docs.sh <file_path_being_edited>
# Outputs doc reminders to stderr if the file is covered by docs/

set -euo pipefail

FILE_PATH="${1:-}"
if [ -z "$FILE_PATH" ]; then
  exit 0
fi

# Normalize path relative to repo root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
COVERAGE_MAP="$SCRIPT_DIR/doc-coverage.json"

if [ ! -f "$COVERAGE_MAP" ]; then
  exit 0
fi

# Check file against each glob in the coverage map
# Uses jq to parse coverage map and bash glob matching
REMINDERS=$(jq -r '.entries[] | "\(.glob)\t\(.reminder)\t\(.criticality)"' "$COVERAGE_MAP" 2>/dev/null)

FOUND_REMINDER=""
FOUND_CRITICALITY=""

while IFS=$'\t' read -r GLOB REMINDER CRITICALITY; do
  # Normalize the file path
  REL_PATH="${FILE_PATH#$REPO_ROOT/}"
  
  # Normalize for bash [[ ]] pattern matching:
  # 1. **/ → * (** has no special meaning; * already matches any char incl /)
  # 2. Escape [ ] so Next.js routes like [locale] are literal, not char classes
  GLOB="${GLOB//\*\*\//*}"
  GLOB="${GLOB//\[/\\[}"
  GLOB="${GLOB//\]/\\]}"
  
  if [[ "$REL_PATH" == $GLOB ]]; then
    FOUND_REMINDER="$REMINDER"
    FOUND_CRITICALITY="$CRITICALITY"
    break
  fi
done <<< "$REMINDERS"

if [ -n "$FOUND_REMINDER" ]; then
  if [ "$FOUND_CRITICALITY" = "high" ]; then
    echo "⚠️  DOCUMENTATION REMINDER (high criticality)" >&2
    echo "$FOUND_REMINDER" >&2
    echo "" >&2
    echo "This file is in a critical path. Read the doc section before proceeding." >&2
  else
    echo "📖 Doc reminder: $FOUND_REMINDER" >&2
  fi
fi

exit 0

赋予其可执行权限:

chmod +x $REPO_ROOT/.claude/check-docs.sh
4. 将钩子写入 settings.json

如果 .claude/settings.json 已存在,先读取。 合并钩子配置——不要覆盖现有钩子。

要添加的钩子:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash {REPO_ROOT}/scripts/check-docs.sh \"$(jq -r '.tool_input.file_path // empty')\""
          }
        ]
      }
    ]
  }
}

合并策略:

  • 如果 PreToolUse 已存在 → 添加到数组中,不要替换
  • 如果已存在完全相同的 check-docs.sh 钩子 → 跳过(幂等)
  • 保留所有现有钩子条目

将合并后的结果写回 .claude/settings.json。

5. 生成自定义 Lint 消息

为 docs/code-guidelines.md 中的每条准则生成一个 lint 消息文件:

创建 $REPO_ROOT/.claude/lint-messages.md:

# Custom Lint Messages — {REPO_NAME}

Generated by hookshot on {DATE}. Used by PreToolUse hooks to inject remediation context.

## {Domain}: {Rule Name}

**Pattern detected:** {what triggers this message}
**Message injected into context:**
> {The exact message the agent will see}
**Doc reference:** docs/code-guidelines.md#{anchor}

---

{Repeat per rule}

对于关键规则(例如,“绝不自行实现身份验证”、“使用 check_redirect,而不是内联条件判断”),生成明确的检查命令并添加到 check-docs.sh:

# Add to check-docs.sh after the glob check:

# Rule-based checks (pattern detection in file content)
if echo "$FILE_PATH" | grep -q "controllers/"; then
  # Check if file being written contains a raw redirect without check_redirect
  # (This is a hint — actual content checking happens post-edit)
  echo "📖 Controllers reminder: Use check_redirect in lib/redirect_service.rb for all redirects." >&2
fi

将这些基于规则的检查添加到 check-docs.sh 中,并放在清晰标注的部分。

5b. 生成 docs/hooks.md

在目标仓库中生成 docs/hooks.md 文件,说明当前启用的钩子:

# Hooks — {REPO_NAME}

> Auto-generated by [hookshot](https://github.com/fellowship-dev/dogfooded-skills). Safe to add notes — hookshot merges on update, it won't overwrite your additions.

## Active Hooks

### PreToolUse: Doc Reminders on Edit/Write

**Trigger:** Every `Edit` or `Write` tool call
**Script:** `scripts/check-docs.sh` (or `.claude/check-docs.sh`)
**Config:** `.claude/settings.json` → `hooks.PreToolUse`
**Coverage map:** `.claude/doc-coverage.json`

When an agent edits a file matching a covered glob, the hook injects a doc reminder into context before the edit proceeds. High-criticality files produce warnings; medium-criticality files produce reminders.

## Covered Domains

{For each entry in doc-coverage.json, list:}
| Domain | Glob | Criticality | Reminder |
|--------|------|-------------|----------|
| {domain} | `{glob}` | {criticality} | {reminder} |

## Maintaining Hooks

- **Quick tweaks:** Edit `.claude/doc-coverage.json` directly — add/remove entries, adjust criticality or reminder text. Changes take effect immediately.
- **Full regeneration:** Run `/hookshot` to rebuild coverage map from current `docs/code-structure.md`. This merges with your existing `doc-coverage.json` and `docs/hooks.md` — it won't overwrite manual additions.
- **Staleness detection:** `/entropy-check` monitors whether hooks are current vs docs. If it flags staleness, re-run `/hookshot`.

## Troubleshooting

### Glob doesn't match expected files
The hook uses bash `[[ ]]` pattern matching, which differs from gitignore globs:
- `**` has no special meaning — `*` already matches any character including `/`
- `[brackets]` are character classes, not literal — Next.js routes like `[locale]` need escaping
- The generated `check-docs.sh` normalizes both automatically. If you're writing manual globs, use `*` not `**/*` for recursive matching.

Test a glob: `bash scripts/check-docs.sh "/full/path/to/file.ts"`

### Hook breaks the agent or slows edits
Disable temporarily by removing the hook entry from `.claude/settings.json`. Re-run `/hookshot` to restore.

### settings.json got clobbered
Re-run `/hookshot` — it merges hooks into existing settings, never overwrites other config.

再次运行时,读取现有的 docs/hooks.md 并进行合并:保留人工添加的部分,并根据当前状态重新生成“Covered Domains”表格和“Active Hooks”部分。

6. 验证

测试生成的钩子:

# Test with a file that should trigger a reminder
bash $REPO_ROOT/.claude/check-docs.sh "$REPO_ROOT/app/controllers/sessions_controller.rb"

# Test with a file that should NOT trigger
bash $REPO_ROOT/.claude/check-docs.sh "$REPO_ROOT/README.md"

# Verify settings.json is valid JSON
cat $REPO_ROOT/.claude/settings.json | jq . > /dev/null && echo "settings.json: valid JSON"

# Verify doc-coverage.json is valid JSON
cat $REPO_ROOT/.claude/doc-coverage.json | jq . > /dev/null && echo "doc-coverage.json: valid JSON"
7. 汇总报告
## Hookshot Complete: {REPO_NAME}

### Coverage Map
- {N} domain entries in .claude/doc-coverage.json
- {N} high-criticality entries (will produce warnings)
- {N} medium-criticality entries (will produce reminders)

### Hooks Generated
- .claude/check-docs.sh — glob-based doc lookup
- .claude/settings.json — PreToolUse hook wired
- .claude/lint-messages.md — custom lint message catalog
- docs/hooks.md — human-readable hook documentation

### Coverage Gaps
{List any domains in ARCHITECTURE.md that have no glob coverage — need manual mapping}

### Manual Next Steps
- [ ] Review .claude/doc-coverage.json — adjust globs that are too broad or too narrow
- [ ] Test a real edit to a covered file and confirm the reminder appears
- [ ] Add rule-based checks for your most critical "Don't Repeat" patterns
- [ ] Run /entropy-check to verify grades reflect the new hook coverage

模式:漂移警告(--drift-warn)

当 Agent 即将编辑 .claude/skills/<name>/ 目录中的文件,且对应技能已在 skills-lock.json 中跟踪时发出警告。不会阻止实际编辑——这只是提示,Agent 有时确实需要先对同步的技能进行紧急修复,再提交上游。

生成 .claude/check-skill-drift.sh
#!/usr/bin/env bash
# check-skill-drift.sh — Generated by hookshot (--drift-warn) on {DATE}
# Usage: check-skill-drift.sh <file_path>
# Warns to stderr if the file belongs to a skill tracked in skills-lock.json.

set -uo pipefail

FILE_PATH="${1:-}"
[ -z "$FILE_PATH" ] && exit 0

# Walk up from the file to find the nearest skills-lock.json
DIR="$(dirname "$FILE_PATH")"
LOCK_FILE=""
while [ "$DIR" != "/" ] && [ "$DIR" != "." ]; do
  if [ -f "$DIR/skills-lock.json" ]; then
    LOCK_FILE="$DIR/skills-lock.json"
    break
  fi
  DIR="$(dirname "$DIR")"
done
[ -z "$LOCK_FILE" ] && exit 0

# Path must contain /.claude/skills/<name>/ or /.agents/skills/<name>/
SKILL_NAME="$(echo "$FILE_PATH" | sed -nE 's|.*/\.(claude|agents)/skills/([^/]+)/.*|\2|p')"
[ -z "$SKILL_NAME" ] && exit 0

# Look up in lockfile
SOURCE=$(python3 -c "
import json, sys
try:
    data = json.load(open('$LOCK_FILE'))
    entry = (data.get('skills') or {}).get('$SKILL_NAME')
    if entry:
        print(entry.get('source', ''))
except Exception:
    pass
" 2>/dev/null)

if [ -n "$SOURCE" ]; then
  echo "⚠️  SKILL DRIFT WARNING" >&2
  echo "'$SKILL_NAME' is a remote skill synced from: $SOURCE" >&2
  echo "Local edits will drift from upstream and may be overwritten on next 'npx skills update'." >&2
  echo "Edit upstream at https://github.com/$SOURCE instead, or be prepared to PR the change back." >&2
fi

exit 0

赋予其可执行权限,并使用匹配器 Edit|Write 将其接入 .claude/settings.json 中的 PreToolUse。采用与默认文档覆盖钩子相同的合并策略,不要覆盖现有配置。

验证
# Should warn — entropy-check is a tracked skill
bash .claude/check-skill-drift.sh "$PWD/.claude/skills/entropy-check/SKILL.md"

# Should be silent — file is outside any skills dir
bash .claude/check-skill-drift.sh "$PWD/README.md"

# Should be silent — skill isn't in lockfile (e.g. a local-only skill)
bash .claude/check-skill-drift.sh "$PWD/.claude/skills/local-thing/SKILL.md"

模式:Markdown Lint(--md-lint)

在 Edit 或 Write 后,对任何已更改的 .md 文件运行 npx markdownlint-cli2,并将警告反馈给 Agent。绝不自动修复——由 Agent 决定。

起始版 .markdownlint.json

如果仓库根目录没有 .markdownlint.json 或 .markdownlint-cli2.jsonc,则添加一个宽松的起始配置,避免一开始就被 lint 规则淹没:

{
  "default": true,
  "MD013": false,
  "MD033": false,
  "MD041": false
}
  • MD013(行长度)——默认关闭;文档和技能文件经常包含长行
  • MD033(内联 HTML)——关闭;我们在报告中使用 HTML details/summary
  • MD041(第一行必须是 h1)——关闭;许多文档以 frontmatter 开头

如果已有配置,则保持不变。绝不覆盖。

生成 .claude/check-md-lint.sh
#!/usr/bin/env bash
# check-md-lint.sh — Generated by hookshot (--md-lint) on {DATE}
# Usage: check-md-lint.sh <file_path>
# Runs markdownlint-cli2 on the file if it's *.md. Warns only — never fixes.

set -uo pipefail

FILE_PATH="${1:-}"
[ -z "$FILE_PATH" ] && exit 0

# Only lint markdown files
case "$FILE_PATH" in
  *.md|*.markdown) ;;
  *) exit 0 ;;
esac

[ -f "$FILE_PATH" ] || exit 0

# Run markdownlint-cli2 — fast start via npx
OUTPUT=$(npx --yes markdownlint-cli2 "$FILE_PATH" 2>&1) || true

if [ -n "$OUTPUT" ] && echo "$OUTPUT" | grep -qE 'MD[0-9]{3}'; then
  echo "📝 Markdown lint warnings for $(basename "$FILE_PATH"):" >&2
  echo "$OUTPUT" | grep -E 'MD[0-9]{3}' | head -20 >&2
  echo "(warnings only — no auto-fix. Run 'npx markdownlint-cli2 --fix <file>' manually if desired.)" >&2
fi

exit 0

使用匹配器 Edit|Write 将其接入 .claude/settings.json 中的 PostToolUse(而不是 PreToolUse——文件必须先存在,才能运行 lint)。

验证
# Should print MD### warnings if the file has any lint issues
bash .claude/check-md-lint.sh README.md

# Should be silent — not a markdown file
bash .claude/check-md-lint.sh package.json

模式:会话预检与交付门禁(--preflight、--gate)

两个钩子,由一个主体维护。脚本位于此技能中(scripts/preflight.py、scripts/gate.py,使用 Python 3 标准库),客户端配置只负责指向这些脚本。仓库不会保存逻辑副本,只保存接线配置。

  • 预检(启动、恢复、清除、压缩时触发 SessionStart):注入会话 ID,提醒 Agent 在首条提示词是任务时运行预检,并提供指针路径 <state>/contracts/<session_id>,供 Agent 记录其契约相对于仓库的路径。创建 <state>/contracts/。
  • 门禁(触发 Stop):通过该指针查找契约,按 references/contract-format.md 检查契约,按 references/shadow-log.md 向影子日志追加一行,并在强制模式下返回 {"decision": "block", "reason": …},列出未满足的项目。stop_hook_active 为 true 时,绝不会阻止流程;发生任何内部错误时,均以状态码 0 退出。

两个客户端都会通过标准输入传入 session_id、cwd、source(SessionStart)以及 stop_hook_active、last_assistant_message(Stop),并接受相同的 additionalContext 和 decision: block 结构。Codex 会解析并跳过 prompt/agent 处理程序,因此只有 Claude Code 原生支持大模型评审;在 Codex 上,门禁会记录 judge: none。

环境
变量默认值用途
HOOKSHOT_STATE_DIR<cwd>/.state指针、影子日志、评审数据包。将其加入 Git 忽略列表。
HOOKSHOT_GATE_MODEshadowshadow 表示记录日志;enforce 表示拒绝。阅读日志后再切换。
HOOKSHOT_PREFLIGHT_DOC未设置预检提醒 Agent 阅读的仓库相对文档
HOOKSHOT_NO_NETWORK未设置跳过 URL 和 PR 检查(这些检查会记录为 unverifiable)
安装到 Claude Code(项目级 .claude/settings.json)
{
  "hooks": {
    "SessionStart": [{"hooks": [{"type": "command",
      "command": "HOOKSHOT_PREFLIGHT_DOC=docs/preflight.md python3 \"$CLAUDE_PROJECT_DIR/.agents/skills/hookshot/scripts/preflight.py\" --client claude-code"}]}],
    "Stop": [{"hooks": [{"type": "command", "timeout": 20,
      "command": "HOOKSHOT_GATE_MODE=shadow python3 \"$CLAUDE_PROJECT_DIR/.agents/skills/hookshot/scripts/gate.py\" --client claude-code"}]}]
  }
}

省略 SessionStart 匹配器,使其在每种来源下都会触发。Claude Code 桌面应用和 VS Code 扩展读取同一个文件。与其他模式一样,合并配置,不要覆盖。

安装到 Codex(项目级 .codex/hooks.json)
{
  "hooks": {
    "SessionStart": [{"hooks": [{"type": "command",
      "command": "HOOKSHOT_PREFLIGHT_DOC=docs/preflight.md python3 .agents/skills/hookshot/scripts/preflight.py --client codex"}]}],
    "Stop": [{"hooks": [{"type": "command", "timeout": 20,
      "command": "HOOKSHOT_GATE_MODE=shadow python3 .agents/skills/hookshot/scripts/gate.py --client codex"}]}]
  }
}

Codex 会从会话工作目录运行钩子。Codex 根据哈希信任每个钩子定义:安装或更改钩子后,需要有人在每台机器上的交互式 Codex 会话中运行 /hooks 并信任该钩子。不要使用 --dangerously-bypass-hook-trust 自动执行此操作。Codex Desktop 和 IDE 扩展中存在关于钩子未触发以及 Stop 阻止导致错误的未解决问题;在影子日志证明门禁正常工作之前,应将收尾步骤视为此处的门禁。

非交互式会话

对于不会触发钩子的客户端(例如忽略用户配置并启动 codex exec 的运行器),运行器会在会话结束后调用同一个脚本:

python3 .agents/skills/hookshot/scripts/gate.py --client codex-exec \
  --session-id "$RUN_ID" --last-message "$LAST_MESSAGE_FILE" --cwd "$REPO"

契约指针仍为 <state>/contracts/<RUN_ID>;如果运行器已知契约路径,请传入 --contract PATH。

验证
python3 .agents/skills/hookshot/scripts/test_gate.py
echo '{"session_id":"t","cwd":"'$PWD'","source":"startup"}' | python3 .agents/skills/hookshot/scripts/preflight.py --client claude-code
echo '{"session_id":"t","cwd":"'$PWD'","stop_hook_active":false,"last_assistant_message":"DELIVERED"}' | python3 .agents/skills/hookshot/scripts/gate.py --client codex
tail -1 .state/hookshot/gate-shadow.jsonl

覆盖范围映射参考

doc-coverage.json 格式支持以下 glob 样式:

模式匹配项
app/controllers/**/*.rbcontrollers/ 下的任意 Ruby 文件
src/pages/**/*.tsxpages/ 下的任意 TSX 文件
lib/redirect_service.rb精确文件
app/models/user.rb精确文件
**/*_mailer.rb任意位置的邮件程序文件

对高关键性文件使用具体的 glob;对领域目录使用宽泛的 glob。

评论

支持 Markdown