mergegate/scripts/hook-check-lock.sh
林 駿甫 (Shunsuke Hayashi) 263adf87cd feat(protocol): expand Obsidian wikilinks in attach_context
When attaching Obsidian notes, extract [[wikilinks]] from the note
content and resolve them to actual vault files. Linked notes are
attached as "obsidian_wikilink" type, bounded by remaining_tokens.

Supports both [[Note]] and [[Note|Display]] syntax.

Closes #102

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 10:21:01 +09:00

88 lines
2.8 KiB
Bash
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Claude Code PreToolUse Hook: ファイル編集前にロック確認
#
# Edit/Write ツールが呼ばれる前に実行される。
# ロックされていないファイルへの書き込みをブロックする。
TOOL_INPUT="$1"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# 上書き可: 別ビルドパスやインストール済み miyabi を指す
MIYABI_BIN="${MIYABI_BIN:-$REPO_ROOT/target/release/miyabi}"
STORE="${POLARIS_TASK_STORE:-$REPO_ROOT/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
# リポルートからの相対パスに変換
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