Skip to content

Git Hooks

このプロジェクトでは 2 系統の hook が動いている:

  1. Husky フック — 全開発者・全 git クライアントに共通。pre-commit / pre-push でリントとテストをガードする
  2. Claude Code hook — Claude Code (CLI) を使って作業しているときに追加で動く保険チェック + 作業内容の音声読み上げ

両者は独立に動き、片方が無効でももう片方は機能する。

1. Husky フック(共通)

pre-commit

コミット前に自動実行:

チェック内容所要
型チェック (tsc --noEmit)TypeScript の型エラー検出約 10 秒
Lint (lint-staged)変更ファイルのみ ESLint。自動修正可能なものは修正数秒

pre-push

プッシュ前に自動実行:

チェック内容所要
ユニットテスト (yarn test:unit)全 vitest スイート約 30 秒

テストが失敗すると push がブロックされる。

手動実行

bash
yarn typecheck     # tsc --noEmit
yarn lint:fix      # ESLint 自動修正
yarn test:unit     # vitest run
yarn validate      # 上記 3 種を一括

フックをスキップする(非推奨)

緊急時のみ:

bash
git commit --no-verify -m "message"
git push --no-verify

スキップするとバグ混入のリスクが高まる。CI で同じチェックが走るので、最終的に PR で fail する可能性が高い。

フックが失敗したとき

エラー種別対処
型エラーyarn typecheck で詳細確認 → 修正
Lint エラーyarn lint:fix で自動修正、残りは手動
テスト失敗yarn test:unit で失敗テストを特定 → 修正

関連設定ファイル

  • .husky/pre-commit — pre-commit フックスクリプト
  • .husky/pre-push — pre-push フックスクリプト
  • .lintstagedrc.json — lint-staged 設定(変更ファイルのみ lint)

2. Claude Code Hook(Claude Code 利用時のみ)

Claude Code を使って開発しているときに、.claude/hooks/ 配下のスクリプトが追加で動く。Husky フックの上書きではなく重ねがけで、より早い段階で異常を捕まえる役割。

2.1 PreToolUse: precommit-check.ps1(実装済み)

目的

Claude が git commit / git push を呼ぶ前に lint / typecheck / unit test を強制実行し、壊れたコミットを履歴に残さない。Husky フックがハーネスから無効化されている環境でも、ここで一段ガードがかかる。

構成

ファイル役割
.claude/hooks/precommit-check.ps1PreToolUse hook 本体。stdin payload を読み、git commit / git push のときだけ yarn lintyarn typecheckyarn test:unit を実行。失敗で exit 2 → tool 呼び出しをブロック。--dry-run / --help は対象外
.claude/settings.jsonhooks.PreToolUse に上記スクリプトを登録(matcher: Bash|PowerShell、shell: powershell、timeout 600s)
memory: feedback_precommit_checks.mdハーネス側でフックが無効化された場合でも、Claude 自身が同等チェックを走らせるよう memory にもルールを保存

反映タイミング

settings.json はセッション開始時に読み込まれる。新規設定を効かせるには /hooks を一度開くか、Claude Code を再起動する。

トレードオフ

yarn test:unit がフルスイートを実行するため、commit / push のたびに数十秒〜分のオーバーヘッド。重い場合は precommit-check.ps1 の test 行を変更ファイル対応のスイートだけに絞る改修が必要。

2.2 Stop Hook: stop-voicevox.ps1(VOICEVOX 読み上げ、任意)

概要

Claude の応答終了時 (Stop event) に直近の assistant メッセージを VOICEVOX TTS で音声合成して再生する。

応答中に [tts]...[/tts] ブロックがあればそれを優先して読み上げ、無ければ全文から機械抽出する。

構成

ファイル役割
.claude/hooks/stop-voicevox.ps1Stop hook 本体。transcript JSONL から直近 assistant テキストを抽出 → 整形 → VOICEVOX API → SoundPlayer.PlaySync()
.claude/settings.jsonhooks.Stop に登録
.claude/settings.local.json個人設定 (VOICEVOX_ENABLED / VOICEVOX_SPEAKER / VOICEVOX_URL 等)。gitignore 済み

個人設定例

json
{
  "env": {
    "VOICEVOX_URL": "http://127.0.0.1:50021",
    "VOICEVOX_SPEAKER": "3",
    "VOICEVOX_ENABLED": "1",
    "VOICEVOX_MAXLEN": "200"
  }
}
変数既定値意味
VOICEVOX_ENABLED(未設定 = 無効)1 で有効化
VOICEVOX_URLhttp://127.0.0.1:50021エンジン URL
VOICEVOX_SPEAKER3 (ずんだもん)話者 ID
VOICEVOX_MAXLEN200読み上げ最大文字数

エンジンに到達できない場合は静かに exit 0 するため、ローカル設定なしでも全体の動作には影響しない。

VOICEVOX 環境

採用構成は WSL2 + Docker Engine + mirrored networking。Docker Desktop 不要で WSL を既に使っていれば追加インストールは最小。

候補評価
Native Windows インストーラ△ GUI 同梱で常駐に不向き
Docker Desktop (WSL2)◎ 簡単だがライセンス注意
WSL2 内 Docker Engine◎(採用)
voicevox_engine 単体バイナリ○ Docker 未導入時の代替

WSL2 セットアップの肝:

  • ~/.wslconfignetworkingMode=mirrored で Windows と WSL の loopback を共有
  • /etc/wsl.conf[boot] systemd=true で auto-start
  • docker-compose.ymlnetwork_mode: host(userland proxy 経由だと Windows → WSL 間で接続 timeout する事象が確認済み)
  • Hyper-V Firewall の inbound 許可ルール (New-NetFirewallHyperVRule -VMCreatorId '{40E0AC32-...}') を 50021 に対して 1 回だけ作成
  • タスクスケジューラに WSL-AutoStart-OnLogin (wsl.exe -e true) を登録してログイン時に WSL を起こす

詳細手順 (検証済み) は archive のセッション記録 2026-05-04_claude-hooks-setup.md を参照。

3. 目的のまとめ

Husky / Claude Code のいずれの hook も以下を保証することがゴール:

  1. 型安全性tsc --noEmit でエラーなし
  2. コード品質 — ESLint ルール準拠(--max-warnings 0
  3. テスト健全性 — vitest スイート全 pass
  4. 作業の透明性 — 何をしたかを Stop hook で読み上げ、レビュアー以外も流れを追える

両系統が二重で動くことで、ハーネスの一時的な不調や --no-verify 利用時にも保険が効く。

4. 関連リンク