Build This Now
Build This Now
キーボードショートカットステータスラインガイド
フックガイドClaude Code クロスプラットフォームフックClaude Code セットアップフックストップフック自己検証する Claude Code エージェントClaude Code セッションフックClaude Code コンテキストバックアップフックスキルアクティベーションフックClaude Code パーミッションフックClaude CodeのMCPツールフックCommands to Skills
Skills, Subagents, HooksSubagent Sweet SpotCLAUDE.md Best PracticesFix Context Limit
speedy_devvkoen_salo
Blog/Toolkit/Hooks/Session Hooks

Claude Code セッションフック

4 つの Claude Code セッションライフサイクルフック: オンデマンドで init を実行し、SessionStart でプロジェクトコンテキストを注入し、トランスクリプトをバックアップし、SessionEnd 終了時にログクリーンアップを行う。

設定をやめて、構築を始めよう。

AIオーケストレーション付きSaaSビルダーテンプレート。

企業向けに構築している実績を見る →
speedy_devvWritten by speedy_devvPublished Feb 12, 2026Toolkit hubHooks index

問題点: 新しいセッションはいつも白紙から始まる。作業中のブランチ、タスクキュー、スクリプトが必要な環境変数を毎回説明し直す。セッションが終わっても、やるべきだったクリーンアップは行われない。

すぐに使えるコード: これを settings.json に貼り付ける。毎回の起動時に Git コンテキストがチャットに届く:

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo '## Git' && git branch --show-current && git status --short | head -10"
          }
        ]
      }
    ]
  }
}

すべてのセッションがコンテキスト付きで始まる。手動セットアップは不要。

4 つのセッションライフサイクルフック

セッションの動作は 4 種類のフックタイプで制御される:

フック発火タイミングブロック可否用途
Setup--init または --maintenance でNO初回セットアップ、マイグレーション
SessionStartセッション開始/再開のたびにNOコンテキスト読み込み、環境変数の設定
PreCompactコンテキストコンパクション前NOトランスクリプトのバックアップ
SessionEndセッション終了時NOクリーンアップ、ログ

SessionStart: 毎回コンテキストを読み込む

SessionStart はセッションが開始または再開されるたびに実行される。Claude の頭の中に常に入れておくべきものがあるときに使う。

基本的なコンテキスト注入

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo '## Project State' && cat .claude/tasks/session-current.md 2>/dev/null || echo 'No active session'"
          }
        ]
      }
    ]
  }
}

JSON 出力を使う場合

構造化されたコンテキスト注入のために:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
def get_project_context():
    try:
        branch = subprocess.check_output(
            ['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
            text=True, stderr=subprocess.DEVNULL
        ).strip()
        status = subprocess.check_output(
            ['git', 'status', '--porcelain'],
            text=True, stderr=subprocess.DEVNULL
        ).strip()
        changes = len(status.split('\n')) if status else 0
    except:
        branch, changes = "unknown", 0
 
    return f"""=== SESSION CONTEXT ===
Git Branch: {branch}
Uncommitted Changes: {changes}
=== END ===""".strip()
 
output = {
    "hookSpecificOutput": {
        "hookEventName": "SessionStart",
        "additionalContext": get_project_context()
    }
}
print(json.dumps(output))
sys.exit(0)

SessionStart のマッチャー

特定のセッションイベントをターゲットにする:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup",
        "hooks": [{ "type": "command", "command": "echo 'Fresh session'" }]
      },
      {
        "matcher": "resume",
        "hooks": [{ "type": "command", "command": "echo 'Resumed session'" }]
      },
      {
        "matcher": "compact",
        "hooks": [{ "type": "command", "command": "echo 'Post-compaction'" }]
      }
    ]
  }
}
  • startup - 新しいセッション
  • resume - --resume、--continue、または /resume から
  • clear - /clear 後
  • compact - コンパクション後

環境変数の永続化

SessionStart は CLAUDE_ENV_FILE にアクセスしてセッション全体で有効な環境変数を設定できる:

#!/bin/bash
 
# Persist environment changes from nvm, pyenv, etc.
ENV_BEFORE=$(export -p | sort)
 
# Setup commands that modify environment
source ~/.nvm/nvm.sh
nvm use 20
 
if [ -n "$CLAUDE_ENV_FILE" ]; then
  ENV_AFTER=$(export -p | sort)
  comm -13 <(echo "$ENV_BEFORE") <(echo "$ENV_AFTER") >> "$CLAUDE_ENV_FILE"
fi
 
exit 0

CLAUDE_ENV_FILE に書き込んだものはすべて、その後 Claude が実行するすべての Bash コマンドに反映される。

Setup: 初回限りの操作

Setup フックは --init、--init-only、または --maintenance を明示的に指定したときのみ実行される。毎回の新しいセッションで発火させたくない処理に使う。

Setup と SessionStart の使い分け

操作Setup を使うSessionStart を使う
依存パッケージのインストールYesNo
データベースマイグレーションの実行YesNo
Git ステータスの読み込みNoYes
環境変数の設定YesYes
プロジェクトコンテキストの注入NoYes
一時ファイルのクリーンアップYes (maintenance)No

Setup の設定

{
  "hooks": {
    "Setup": [
      {
        "matcher": "init",
        "hooks": [
          {
            "type": "command",
            "command": "npm install && npm run db:migrate"
          }
        ]
      },
      {
        "matcher": "maintenance",
        "hooks": [
          {
            "type": "command",
            "command": "npm prune && npm dedupe && rm -rf .cache"
          }
        ]
      }
    ]
  }
}

実行方法:

claude --init          # Runs 'init' matcher
claude --init-only     # Runs 'init' matcher, then exits
claude --maintenance   # Runs 'maintenance' matcher

Setup フックも環境変数の永続化のために CLAUDE_ENV_FILE に書き込める。

PreCompact: コンテキスト消失前に

PreCompact はコンパクションの直前に発火する。ユーザーが /compact でトリガーした場合も、ウィンドウが埋まって自動的に発火した場合も同様だ。

トランスクリプトのバックアップ

#!/usr/bin/env python3
import json
import sys
import shutil
from pathlib import Path
from datetime import datetime
 
input_data = json.load(sys.stdin)
transcript_path = input_data.get('transcript_path', '')
trigger = input_data.get('trigger', 'unknown')
 
if transcript_path and Path(transcript_path).exists():
    backup_dir = Path('.claude/backups')
    backup_dir.mkdir(parents=True, exist_ok=True)
 
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    backup_name = f"transcript_{trigger}_{timestamp}.jsonl"
    shutil.copy2(transcript_path, backup_dir / backup_name)
 
    # Keep only last 10 backups
    backups = sorted(backup_dir.glob('transcript_*.jsonl'))
    for old_backup in backups[:-10]:
        old_backup.unlink()
 
sys.exit(0)

PreCompact のマッチャー

{
  "hooks": {
    "PreCompact": [
      {
        "matcher": "auto",
        "hooks": [{ "type": "command", "command": "echo 'Auto-compacting...'" }]
      },
      {
        "matcher": "manual",
        "hooks": [{ "type": "command", "command": "echo 'Manual /compact'" }]
      }
    ]
  }
}
  • auto - コンテキストウィンドウが埋まり、自動コンパクション
  • manual - ユーザーが /compact を実行

リカバリーマーカーの作成

コンパクションイベント後にコンテキストを再構築するために PreCompact と SessionStart をペアにする。有効なパターン: 共有の backup-core モジュール、しきい値ベースのトリガーを発火させる StatusLine モニター、そして PreCompact ハンドラーが 1 つの状態ファイルを通じて協調する。これによりセッション間で何も失われない。完全なウォークスルーは Context Recovery フックガイドを参照。

SessionEnd: クリーンアップ

SessionEnd はセッションが終了するときに実行される。シャットダウンをブロックできないが、クリーンアップは実行できる。

セッション統計のログ

#!/usr/bin/env python3
import json
import sys
from pathlib import Path
from datetime import datetime
 
input_data = json.load(sys.stdin)
session_id = input_data.get('session_id', 'unknown')
reason = input_data.get('reason', 'unknown')
 
log_dir = Path('.claude/logs')
log_dir.mkdir(parents=True, exist_ok=True)
 
log_entry = {
    "session_id": session_id,
    "ended_at": datetime.now().isoformat(),
    "reason": reason
}
 
with open(log_dir / 'session-history.jsonl', 'a') as f:
    f.write(json.dumps(log_entry) + '\n')
 
sys.exit(0)

SessionEnd の終了理由

reason フィールドはセッションが終了した理由を伝える:

  • clear - ユーザーが /clear を実行した
  • logout - ユーザーがログアウトした
  • prompt_input_exit - プロンプト表示中にユーザーが終了した
  • other - その他の終了理由

完全なライフサイクル例

端から端まで接続された完全なライフサイクル設定:

{
  "hooks": {
    "Setup": [
      {
        "matcher": "init",
        "hooks": [
          {
            "type": "command",
            "command": "npm install && echo 'Dependencies installed'"
          }
        ]
      }
    ],
 
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo '## Context' && git status --short && echo '## Tasks' && cat .claude/tasks/session-current.md 2>/dev/null | head -20"
          }
        ]
      }
    ],
 
    "PreCompact": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "cp \"$CLAUDE_TRANSCRIPT_PATH\" .claude/backups/last-transcript.jsonl 2>/dev/null || true"
          }
        ]
      }
    ],
 
    "SessionEnd": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo \"Session ended: $(date)\" >> .claude/logs/sessions.log"
          }
        ]
      }
    ]
  }
}

入力ペイロード

SessionStart の入力

{
  "session_id": "abc123",
  "hook_event_name": "SessionStart",
  "source": "startup",
  "model": "claude-sonnet-4-20250514",
  "cwd": "/path/to/project"
}

Setup の入力

{
  "session_id": "abc123",
  "hook_event_name": "Setup",
  "trigger": "init",
  "cwd": "/path/to/project"
}

PreCompact の入力

{
  "session_id": "abc123",
  "hook_event_name": "PreCompact",
  "transcript_path": "~/.claude/projects/.../transcript.jsonl",
  "trigger": "auto",
  "custom_instructions": ""
}

SessionEnd の入力

{
  "session_id": "abc123",
  "hook_event_name": "SessionEnd",
  "reason": "clear",
  "cwd": "/path/to/project"
}

ベストプラクティス

  1. SessionStart は素早く - 毎回のセッションで実行される。重い処理は Setup に移す。

  2. Setup は初回限りの処理に - 依存パッケージのインストール、マイグレーション、初回プロジェクトのブートストラップ。

  3. コンパクション前にバックアップ - PreCompact はトランスクリプトを取得する最後のチャンスだ。

  4. セッション終了をログに残す - SessionEnd はアナリティクスとデバッグに便利だ。

  5. マッチャーを慎重に - startup と resume と compact で異なる動作にすることで予期せぬ挙動を防ぐ。

次のステップ

  • 全 12 フックのためにメインの Hooks ガイドをセットアップする
  • コンパクションを乗り越えるために Context Recovery を設定する
  • タスク完了の強制に Stop フックを使う
  • 自動スキル読み込みのためにスキル起動を探索する

Continue in Hooks

  • Slash Commands Are Now Skills: Migrating Commands to Skills
    Claude Code slash commands and skills now do the same thing. Here is how to migrate .claude/commands to .claude/skills and why it pays off.
  • Claude Code セットアップフック
    スクリプト、エージェント、ドキュメントをClaude Codeのセットアップフックに組み合わせる方法。1つのコマンドで決定論的スクリプトを実行し、診断エージェントに出力を渡し、自動更新されるドキュメントを記録する。
  • Claude Code コンテキストバックアップフック
    StatusLineを活用したClaude Codeのコンテキストバックアップフック。10Kトークンごとに構造化されたスナップショットを書き込み、自動圧縮によってエラー文字列・関数シグネチャ・判断内容が失われるのを防ぐ。
  • Claude Code クロスプラットフォームフック
    Claude Codeのクロスプラットフォームフック: .cmd・.sh・.ps1のラッパーを捨て、nodeを直接呼び出すことで、1つの.mjsファイルがmacOS・Linux・Windowsで動く方法。
  • フックガイド
    Claude Code フックの基礎から実践まで: 終了コード、JSON出力、非同期コマンド、HTTPエンドポイント、PreToolUseとPostToolUseのマッチャー、本番環境パターン。
  • Claude CodeのMCPツールフック
    type: mcp_toolを使ってClaude CodeのフックからMCPサーバーのツールを直接呼び出す方法。スキーマ、変数展開の構文、ユースケース、本番パターンまで解説します。

More from Toolkit

  • CLAUDE.md, Skills, Subagents, Hooks: When to Use Which
    Claude Code skills vs subagents vs hooks vs CLAUDE.md: a plain mental model for picking the right primitive, with token costs and examples.
  • Claude Code Subagents: The 3 to 5 Agent Sweet Spot
    Claude code subagents work best at 3-5 concurrent agents. Here is why that ceiling exists, how to set them up, and what to use past it.
  • CLAUDE.md Best Practices: The File That Makes Claude Code Reliable
    CLAUDE.md best practices: keep it under 200 lines, write it by hand, and use hooks when you need real enforcement, not advice.
  • How to Fix Claude Code Running Out of Context
    Claude Code running out of context is a session design problem. Fix it with /compact, lean CLAUDE.md, skills, and subagents, not a bigger window.

設定をやめて、構築を始めよう。

AIオーケストレーション付きSaaSビルダーテンプレート。

企業向けに構築している実績を見る →

自己検証する Claude Code エージェント

自己検証する Claude Code エージェント: PostToolUse リントフック、Stop フック、読み取り専用レビュアーのサブエージェントをエージェント定義に組み込み、不良な出力が出荷されないようにする。

Claude Code コンテキストバックアップフック

StatusLineを活用したClaude Codeのコンテキストバックアップフック。10Kトークンごとに構造化されたスナップショットを書き込み、自動圧縮によってエラー文字列・関数シグネチャ・判断内容が失われるのを防ぐ。

On this page

4 つのセッションライフサイクルフック
SessionStart: 毎回コンテキストを読み込む
基本的なコンテキスト注入
JSON 出力を使う場合
SessionStart のマッチャー
環境変数の永続化
Setup: 初回限りの操作
Setup と SessionStart の使い分け
Setup の設定
PreCompact: コンテキスト消失前に
トランスクリプトのバックアップ
PreCompact のマッチャー
リカバリーマーカーの作成
SessionEnd: クリーンアップ
セッション統計のログ
SessionEnd の終了理由
完全なライフサイクル例
入力ペイロード
SessionStart の入力
Setup の入力
PreCompact の入力
SessionEnd の入力
ベストプラクティス
次のステップ

設定をやめて、構築を始めよう。

AIオーケストレーション付きSaaSビルダーテンプレート。

企業向けに構築している実績を見る →