mcpField
T
tool-hooks-doctor

tool-hooks-doctor

github.com/heyvhuangエージェントワークフロー33849 回インストール30 週間前に更新
リポジトリ

tool-hooks-doctor について

Claude Code の `skill-evolution` フックがインストール済みか、有効か、実行成果物を生成しているかを読み取り専用で確認する診断スキルです。進化ループに依存するワークフローの事前確認に使えます。

主な機能

  1. 01必要なフックスクリプトの確認
  2. 02プロジェクトとグローバル設定の確認
  3. 03OK・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 フックがインストールされ、有効になっているかをすばやく確認します。

これは、進化ループが有効でない場合に他のワークフローが早期に警告できるようにする、単独の診断ツールです。

対象範囲

  • 対象:Claude Code のフックのインストール/設定
  • 対象外:Claude スタイルのフックをサポートしていない Cursor/OpenCode など

「正常」な状態

  1. フックスクリプトが次の場所に存在する:
  • ~/.claude/skills/skill-evolution/hooks/
  1. 設定で、次のいずれかからフックが有効になっている:
  • プロジェクト設定:<repo_root>/.claude/settings.json
  • またはグローバル設定:~/.claude/settings.json
  1. セッションによって、次の場所に成果物が生成される:
  • <project_root>/runs/evolution/<run_id>/...

確認(読み取り専用)

次の確認を実行し、ステータスを OK/PARTIAL/MISSING として報告します。

1) フックスクリプトはインストールされていますか?
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) 設定でフックは有効になっていますか?

次の両方の場所を確認します。

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 のチェックがどれも一致しない場合:フックは有効になっていません。
  • 一部だけ一致する場合:設定は PARTIAL で、修正が必要です。
3) 実行時の簡易スモークテスト(任意)

ユーザーの確認を得たら、プロジェクト内で無害な bash コマンドを実行し、その後、次を確認します。

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

修正(書き込み;確認が必要)

フックが有効になっていない場合は、プロジェクトレベルのフック(グローバルより安全)のインストールを推奨します。

適用する前に、書き込むファイルをユーザーに正確に伝えます。

  • プロジェクトレベル:<repo_root>/.claude/settings.json(推奨)
  • グローバル:~/.claude/settings.json

その後、明示的な確認を待ちます。

プロジェクトレベルのフックをインストール(推奨)
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
グローバルフックをインストール(任意)

上記と同じですが、~/.claude/settings.json に書き込みます。

コメント