mcpField
T
tool-hooks-doctor

tool-hooks-doctor

github.com/heyvhuangAgent 工作流33849 次安装30 周前更新
代码仓库

关于 tool-hooks-doctor

用于只读检查 Claude Code 中 `skill-evolution` 钩子是否已安装、启用并生成运行产物的诊断技能,可供依赖进化循环的工作流提前检测状态。

主要功能

  1. 01检查必需的钩子脚本
  2. 02检查项目和全局设置
  3. 03报告 OK、PARTIAL 或 MISSING
  4. 04可选验证运行产物

适用场景

  1. 01诊断进化工作流未运行的原因
  2. 02在运行依赖工作流前检查钩子配置

安装

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

$npx skills add https://github.com/heyvhuang/ship-faster --skill tool-hooks-doctor

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

详细介绍

Hooks Doctor(Claude Code)

目标:快速验证 skill-evolution 的 Claude Code hooks 是否已安装并启用。

这是一个原子诊断工具,供其他工作流使用,以便在演进循环未激活时尽早发出警告。

范围

  • 适用于:Claude Code hooks 的安装/配置
  • 不适用于:不支持 Claude 风格 hooks 的 Cursor/OpenCode 等

健康状态的判定标准

  1. Hook 脚本位于:
  • ~/.claude/skills/skill-evolution/hooks/
  1. 以下任一设置中已启用 hooks:
  • 项目设置:<repo_root>/.claude/settings.json
  • 或全局设置:~/.claude/settings.json
  1. 会话会在以下目录生成产物:
  • <project_root>/runs/evolution/<run_id>/...

检查(只读)

运行以下检查,并报告状态:OK / PARTIAL / MISSING。

1) Hook 脚本是否已安装?
ls -la ~/.claude/skills/skill-evolution/hooks/ 2>/dev/null || true

必需文件:

  • pre-tool.sh
  • post-bash.sh
  • post-tool.sh
  • session-end.sh

如果缺少:用户必须先安装/更新 skill-evolution 技能。

2) 设置中是否已启用 hooks?

检查以下两个位置:

test -f .claude/settings.json && echo "project settings: .claude/settings.json" || true
test -f ~/.claude/settings.json && echo "global settings: ~/.claude/settings.json" || true

grep -n "skill-evolution/hooks/pre-tool.sh" .claude/settings.json ~/.claude/settings.json 2>/dev/null || true
grep -n "skill-evolution/hooks/post-bash.sh" .claude/settings.json ~/.claude/settings.json 2>/dev/null || true
grep -n "skill-evolution/hooks/post-tool.sh" .claude/settings.json ~/.claude/settings.json 2>/dev/null || true
grep -n "skill-evolution/hooks/session-end.sh" .claude/settings.json ~/.claude/settings.json 2>/dev/null || true

判定:

  • 如果 grep 检查均未匹配:hooks 未启用。
  • 如果仅部分匹配:配置为 PARTIAL,应予修复。
3) 快速运行时冒烟测试(可选)

如果用户确认,在项目中运行一条无害的 bash 命令,然后检查:

ls -la runs/evolution 2>/dev/null || true

修复(写入;需确认)

如果 hooks 未启用,建议安装项目级 hooks(比全局设置更安全)。

应用前,明确告知用户将写入的文件:

  • 项目级:<repo_root>/.claude/settings.json(推荐)
  • 全局:~/.claude/settings.json

然后等待用户明确确认。

安装项目级 hooks(推荐)
python3 - <<'PY'
import json
from pathlib import Path

settings = Path('.claude') / 'settings.json'
settings.parent.mkdir(parents=True, exist_ok=True)

data = {}
if settings.exists():
    data = json.loads(settings.read_text() or '{}')
if not isinstance(data, dict):
    data = {}

hooks = data.get('hooks')
if not isinstance(hooks, dict):
    hooks = {}

desired = {
  'PreToolUse': [{
    'matcher': 'Bash|Write|Edit',
    'hooks': [{'type':'command','command':'bash ~/.claude/skills/skill-evolution/hooks/pre-tool.sh'}]
  }],
  'PostToolUse': [
    {
      'matcher': 'Bash',
      'hooks': [{'type':'command','command':'bash ~/.claude/skills/skill-evolution/hooks/post-bash.sh "$TOOL_OUTPUT" "$EXIT_CODE"'}]
    },
    {
      'matcher': 'Write|Edit',
      'hooks': [{'type':'command','command':'bash ~/.claude/skills/skill-evolution/hooks/post-tool.sh "$TOOL_OUTPUT" "$EXIT_CODE"'}]
    }
  ],
  'Stop': [{
    'matcher': '',
    'hooks': [{'type':'command','command':'bash ~/.claude/skills/skill-evolution/hooks/session-end.sh'}]
  }]
}

def has_command(arr, matcher, command):
    for item in arr:
        if not isinstance(item, dict):
            continue
        if item.get('matcher') != matcher:
            continue
        hs = item.get('hooks')
        if not isinstance(hs, list):
            continue
        for h in hs:
            if isinstance(h, dict) and h.get('command') == command:
                return True
    return False

for event, items in desired.items():
    arr = hooks.get(event)
    if not isinstance(arr, list):
        arr = []
    for it in items:
        cmd = it['hooks'][0]['command']
        if not has_command(arr, it['matcher'], cmd):
            arr.append(it)
    hooks[event] = arr

data['hooks'] = hooks

if settings.exists():
    backup = settings.with_suffix(settings.suffix + '.bak')
    backup.write_text(settings.read_text())

settings.write_text(json.dumps(data, indent=2, ensure_ascii=True) + '\n')
print('Installed hooks into:', settings)
PY
安装全局 hooks(可选)

同上,但写入 ~/.claude/settings.json。

评论

支持 Markdown