[追加] Claude Code hooks: ファイル編集前にロック自動チェック (#73 関連)

.claude/settings.json:
  PreToolUse hook: Edit/Write 前に miyabi gate locks を確認
  PostToolUse hook: git commit 後にロック状態をリマインド

scripts/hook-check-lock.sh:
  他人がロック中のファイルへの書き込みを exit 2 でブロック
  ロックなしファイルの編集は警告のみ(ブロックしない)

scripts/hook-post-bash.sh:
  git commit 後にロック残数を表示

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
林 駿甫 (Shunsuke Hayashi) 2026-04-10 08:58:58 +09:00
parent 3744382d3d
commit 3e3149f7d1
3 changed files with 126 additions and 0 deletions

86
scripts/hook-check-lock.sh Executable file
View file

@ -0,0 +1,86 @@
#!/bin/bash
# Claude Code PreToolUse Hook: ファイル編集前にロック確認
#
# Edit/Write ツールが呼ばれる前に実行される。
# ロックされていないファイルへの書き込みをブロックする。
TOOL_INPUT="$1"
MIYABI_BIN="/Users/shunsukehayashi/dev/platform/miyabi-cli-standalone/target/release/miyabi"
STORE="/Users/shunsukehayashi/dev/platform/miyabi-cli-standalone/project_memory/tasks.json"
# miyabi バイナリがなければスキップ
if [ ! -x "$MIYABI_BIN" ]; then
exit 0
fi
# tasks.json がなければスキップ(初回)
if [ ! -f "$STORE" ]; then
exit 0
fi
# 編集対象ファイルを抽出file_path パラメータ)
TARGET_FILE=$(echo "$TOOL_INPUT" | python3 -c "
import sys, json
try:
data = json.loads(sys.stdin.read())
print(data.get('file_path', ''))
except:
pass
" 2>/dev/null)
if [ -z "$TARGET_FILE" ]; then
exit 0
fi
# リポルートからの相対パスに変換
REPO_ROOT="/Users/shunsukehayashi/dev/platform/miyabi-cli-standalone"
REL_PATH="${TARGET_FILE#$REPO_ROOT/}"
# ロック一覧を取得
LOCKS=$("$MIYABI_BIN" gate --store-path "$STORE" --format json locks 2>/dev/null)
# このファイルがロックされているか確認
LOCK_INFO=$(echo "$LOCKS" | python3 -c "
import sys, json
try:
data = json.loads(sys.stdin.read())
if isinstance(data, dict):
for file, info in data.items():
if file == '$REL_PATH' or '$REL_PATH'.endswith(file):
print(f'{info.get(\"agent\",\"?\")}@{info.get(\"node\",\"?\")}')
break
except:
pass
" 2>/dev/null)
# ロックが存在し、かつ自分のロックでない場合はブロック
if [ -n "$LOCK_INFO" ]; then
POLARIS_AGENT="${POLARIS_AGENT_ID:-claude}"
if echo "$LOCK_INFO" | grep -qv "$POLARIS_AGENT"; then
echo "⚠️ POLARIS: $REL_PATH$LOCK_INFO がロック中です。"
echo "miyabi gate assign でロックを取得してください。"
# exit 2 でブロックClaude Code はこれでツール実行を中止する)
exit 2
fi
fi
# ロックがない場合も警告(ただしブロックはしない)
ACTIVE_LOCKS=$("$MIYABI_BIN" gate --store-path "$STORE" locks 2>/dev/null | grep -c "->")
if [ "$ACTIVE_LOCKS" -gt 0 ]; then
# 他のファイルにロックがある場合、このファイルにロックがないことを警告
HAS_LOCK=$(echo "$LOCKS" | python3 -c "
import sys, json
try:
data = json.loads(sys.stdin.read())
if isinstance(data, dict) and '$REL_PATH' in data:
print('yes')
except:
pass
" 2>/dev/null)
if [ -z "$HAS_LOCK" ]; then
echo " POLARIS: $REL_PATH はロックされていません。miyabi gate assign で登録を推奨します。"
fi
fi
exit 0

24
scripts/hook-post-bash.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/bash
# Claude Code PostToolUse Hook: Bash 実行後にロック状態をリマインド
#
# git commit が実行された場合、post-commit hook が発火するので
# ここでは軽い状態表示のみ。
TOOL_INPUT="$1"
MIYABI_BIN="/Users/shunsukehayashi/dev/platform/miyabi-cli-standalone/target/release/miyabi"
STORE="/Users/shunsukehayashi/dev/platform/miyabi-cli-standalone/project_memory/tasks.json"
# miyabi バイナリがなければスキップ
if [ ! -x "$MIYABI_BIN" ]; then
exit 0
fi
# git commit を検出した場合にステータス表示
if echo "$TOOL_INPUT" | grep -q "git commit"; then
ACTIVE=$("$MIYABI_BIN" gate --store-path "$STORE" locks 2>/dev/null | grep -c "->")
if [ "$ACTIVE" -gt 0 ]; then
echo " POLARIS: $ACTIVE 件のファイルがまだロック中です。作業完了したら miyabi gate merge または miyabi gate manual-complete を実行してください。"
fi
fi
exit 0