Git Hooks
このプロジェクトでは 2 系統の hook が動いている:
- Husky フック — 全開発者・全 git クライアントに共通。pre-commit / pre-push でリントとテストをガードする
- 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 がブロックされる。
手動実行
yarn typecheck # tsc --noEmit
yarn lint:fix # ESLint 自動修正
yarn test:unit # vitest run
yarn validate # 上記 3 種を一括フックをスキップする(非推奨)
緊急時のみ:
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.ps1 | PreToolUse hook 本体。stdin payload を読み、git commit / git push のときだけ yarn lint → yarn typecheck → yarn test:unit を実行。失敗で exit 2 → tool 呼び出しをブロック。--dry-run / --help は対象外 |
.claude/settings.json | hooks.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.ps1 | Stop hook 本体。transcript JSONL から直近 assistant テキストを抽出 → 整形 → VOICEVOX API → SoundPlayer.PlaySync() |
.claude/settings.json | hooks.Stop に登録 |
.claude/settings.local.json | 個人設定 (VOICEVOX_ENABLED / VOICEVOX_SPEAKER / VOICEVOX_URL 等)。gitignore 済み |
個人設定例
{
"env": {
"VOICEVOX_URL": "http://127.0.0.1:50021",
"VOICEVOX_SPEAKER": "3",
"VOICEVOX_ENABLED": "1",
"VOICEVOX_MAXLEN": "200"
}
}| 変数 | 既定値 | 意味 |
|---|---|---|
VOICEVOX_ENABLED | (未設定 = 無効) | 1 で有効化 |
VOICEVOX_URL | http://127.0.0.1:50021 | エンジン URL |
VOICEVOX_SPEAKER | 3 (ずんだもん) | 話者 ID |
VOICEVOX_MAXLEN | 200 | 読み上げ最大文字数 |
エンジンに到達できない場合は静かに exit 0 するため、ローカル設定なしでも全体の動作には影響しない。
VOICEVOX 環境
採用構成は WSL2 + Docker Engine + mirrored networking。Docker Desktop 不要で WSL を既に使っていれば追加インストールは最小。
| 候補 | 評価 |
|---|---|
| Native Windows インストーラ | △ GUI 同梱で常駐に不向き |
| Docker Desktop (WSL2) | ◎ 簡単だがライセンス注意 |
| WSL2 内 Docker Engine | ◎(採用) |
| voicevox_engine 単体バイナリ | ○ Docker 未導入時の代替 |
WSL2 セットアップの肝:
~/.wslconfigにnetworkingMode=mirroredで Windows と WSL の loopback を共有/etc/wsl.confに[boot] systemd=trueで auto-startdocker-compose.ymlはnetwork_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 も以下を保証することがゴール:
- 型安全性 —
tsc --noEmitでエラーなし - コード品質 — ESLint ルール準拠(
--max-warnings 0) - テスト健全性 — vitest スイート全 pass
- 作業の透明性 — 何をしたかを Stop hook で読み上げ、レビュアー以外も流れを追える
両系統が二重で動くことで、ハーネスの一時的な不調や --no-verify 利用時にも保険が効く。
4. 関連リンク
- Release Workflow — push 後のリリース手順
- GitHub Actions — CI 側の同等チェック
- E2E Testing Guide — E2E 自動化との関係