#!/bin/bash # Stop hook: 文脈が閾値を超えたら、ターンを終える前に /checkpoint と引き継ぎメモの書き出しを実行させる # 目的は compact ではなく「保存 → ユーザーが /clear → handoff-inject.sh がメモを注入して再開」を回すこと。 # herdr の外では /clear はユーザーにしか打てないので、モデルにはメモを用意させて /clear の一言案内で終わらせる。 # herdr 上では stop-auto-resume.sh が /clear と再開の指示を自動で送る。 # Stop hook の exit 2 = Claude の停止を阻止して続行を強制(stderr がモデルに渡る) # # UserPromptSubmit の通知(context-bye-reminder.sh)はモデルが先送りできるため、 # ここでターン末に一度だけ止めて指示する。保存が済んだかどうかまでは確かめない。 # 判定は % ではなく実トークン数で行う(statusline の used_percentage は 1M のコンテキストウィンドウ基準)。 THRESHOLD_TOKENS=${CLAUDE_CHECKPOINT_TOKENS:-200000} COMPACT_WINDOW=${CLAUDE_CODE_AUTO_COMPACT_WINDOW:-1000000} COMPACT_AT=$((COMPACT_WINDOW - 33000)) input=$(cat) # 無限ループ防止: stop_hook_active=true のときはスキップ if [ "$(echo "$input" | jq -r '.stop_hook_active // false')" = "true" ]; then exit 0 fi session_id=$(echo "$input" | jq -r '.session_id // empty' 2>/dev/null) [ -z "$session_id" ] && exit 0 cwd=$(echo "$input" | jq -r '.cwd // empty' 2>/dev/null) # stop-auto-resume.sh と同じく、Bash の cd でずれない起動ディレクトリをメモ名に使う key=${CLAUDE_PROJECT_DIR:-$cwd} handoff="$HOME/.claude/handoff/${key//\//-}.md" tokens=$(cat "/tmp/claude-context-tokens-${session_id}" 2>/dev/null) [ -z "$tokens" ] && exit 0 # 文脈 1 周(閾値超え → compact・/clear で閾値割れ)につき 1 回だけ発火する FLAG_FILE="/tmp/claude-stop-bye-${session_id}" if [ "$tokens" -lt "$THRESHOLD_TOKENS" ]; then rm -f "$FLAG_FILE" exit 0 fi [ -f "$FLAG_FILE" ] && exit 0 touch "$FLAG_FILE" remaining=$(( (COMPACT_AT - tokens) / 1000 )) [ "$remaining" -lt 0 ] && remaining=0 # herdr 上では stop-auto-resume.sh が /clear と再開の指示を自動で送る if [ "${HERDR_ENV:-}" = 1 ] && [ "${CLAUDE_AUTO_RESUME:-1}" != 0 ]; then closing="(3) この pane は herdr 上なので、ターンが終わると自動で /clear して引き継ぎメモから再開する。ユーザーの返事待ちなど区切りが悪い時だけ ${handoff%.md}.noauto を touch して止める。最後の応答は「自動で /clear して、引き継ぎメモから続きを再開する」と一言だけ添えて終える。" else closing="(3) 最後の応答は「区切りがよければ /clear と打てば、引き継ぎメモから続きを再開する」と一言だけ添えて終える。" fi printf '⚠️ 文脈が %dk トークンに達した(自動 compact まで残り約 %dk)。ターンを終える前に次を行うこと。ツール呼び出しは最小にする(理想は 1〜2 回の Bash)。(1) /checkpoint を実行してメモリを保存する(既に実行済みなら、その後の分だけ)。(2) 引き継ぎメモ(目的・作業中のファイル・未コミットの変更・決まったこと・次の一手)を %s に書き出す。メモリ本体の書き込み・MEMORY.md 索引への追記・引き継ぎメモは、可能なら 1 回の Bash(heredoc)でまとめる。/clear 後にこのメモが自動で読み込まれ、続きから再開できる。%s\n' \ "$((tokens / 1000))" "$remaining" "$handoff" "$closing" >&2 exit 2