• #Claude Code
  • #フック
  • #タイムスタンプ
  • #1Mコンテキスト
  • #開発環境
開発claude-code-toolsメモ

Claude Codeフックでタイムスタンプ注入

Claude Codeの1Mコンテキストで長時間セッションを走らせていると、会話のどのあたりが何時頃の話だったか見失う。「PreToolUseフックにdateコマンドを仕込めば、あらゆるツール実行時にタイムスタンプが残る」というTipsを見かけて試したが、思った通りには動かなかった。フックの仕様を理解してUserPromptSubmitに切り替えるまでの記録。


きっかけ

1Mコンテキストのセッションは数時間に及ぶことがある。途中で「さっきのエラー、何時頃だっけ」と遡りたくなっても、会話ログに時刻情報がない。claude-code-syncのDiscordで「PreToolUseフックにdateを入れると便利」というTipsが流れてきて、settings.local.jsonを開いた。

試行1: PreToolUseフックにdateコマンドを追加

PreToolUseフックでBashツール実行前にdateコマンドを走らせれば、コンテキストにタイムスタンプが入るはず。そのまま書いた。

.claude/settings.local.json のhooksセクションに追加:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "date"
          }
        ]
      }
    ]
  }
}

結果: 何も起きない。タイムスタンプがコンテキストに現れない。

試行2: Windows環境のdateコマンド問題

Git Bash環境なのでLinuxのdateが使えるはず――と思ったが、フックの実行環境ではWindows版のdateが呼ばれている可能性を疑った。bash -c "date"でラップしてみた。

{
  "type": "command",
  "command": "bash -c \"date\""
}

結果: これも動かない。タイムスタンプは表示されなかった。

仕様の壁: PreToolUseのstdoutはコンテキストに入らない

ここで手を止めて仕様を調べた。判明した事実:

  • PreToolUseフックのstdoutは、Claudeのコンテキストに注入されない
  • フックの出力は Ctrl+O で開く詳細モードのUIにのみ表示される
  • つまりデバッグ用の表示であって、Claudeが「読める」情報にはならない

PreToolUseフックは「ツール実行を許可/拒否する」ためのゲートキーパーであって、コンテキストに情報を追加する仕組みではなかった。

試行3: UserPromptSubmitフックに変更

フックの種類を見直した。UserPromptSubmitフックは、ユーザーがメッセージを送信したタイミングで実行され、そのstdoutがsystem-reminderとしてコンテキストに注入される。

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash -c \"date '+%Y-%m-%d %H:%M:%S'\""
          }
        ]
      }
    ]
  }
}

結果: 成功。メッセージを送信するたびに、system-reminderとしてタイムスタンプがコンテキストに入るようになった。

最終的な設定

UserPromptSubmitフックには、既存のVOICEVOX音声再生フックと並べてdate hookを配置した。

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -WindowStyle Hidden -File C:/scripts/play-sound.ps1"
          },
          {
            "type": "command",
            "command": "bash -c \"date '+%Y-%m-%d %H:%M:%S'\""
          }
        ]
      }
    ]
  }
}

メッセージ送信のたびに:

  1. 音声が再生される(応答開始の通知)
  2. タイムスタンプがsystem-reminderとしてコンテキストに入る

確認方法

動作しているかは、Claudeに「現在のsystem-reminderの内容を教えて」と聞くか、会話ログの中にタイムスタンプ付きのsystem-reminderが挟まっているかで確認できる。

学び

  • PreToolUseフック: ツール実行の許可/拒否が目的。stdoutはUI表示のみでコンテキストには入らない
  • UserPromptSubmitフック: ユーザー入力時に実行され、stdoutがsystem-reminderとしてコンテキストに注入される
  • フックの種類によってstdoutの扱いが違う。「出力がどこに流れるか」を把握してからフックを選ぶ必要がある
  • 1Mコンテキストの長時間セッションで、タイムスタンプが入った途端に「あのエラーは14時頃だった」とスクロールして探し当てられるようになった