Claude Codeの「待ち時間」「放置時間」問題
基本の通知設定がまだの方へ
通知リマインダの仕組み
使用するイベント
動作の流れ
実装
notify-idle.sh(音声通知+リマインダ起動)
既存のリマインダがあればkill
即時通知(バックグラウンドで実行し、hookをブロックしない)
リマインダループ(120秒ごと)
cancel-idle.sh(リマインダ停止)
実行権限の付与
settings.jsonの設定
実装のポイント
パイプの切り離しが必須
PIDファイルによるプロセス管理
リマインド間隔の調整
セッション終了後もリマインダが鳴り続ける問題
対策1:リマインダループ内でプロセスチェック
リマインダループ(120秒ごと、Claudeプロセスが存在する間のみ)
対策2:StopフックでCancel → Notifyの順に実行
サウンドのミュート切り替え
toggle-sound.sh(ミュート切り替え)
使い方
音を消す
音をつける
トグル(引数なしで切り替え)
~/.zshrc に追加
notify-idle.shへのミュート対応
即時通知
リマインダループ
Agent Teams対応:チームメンバー名も読み上げる
チーム関連のHooksイベント
notify-idle.shの拡張
stdinからJSONを読み取り、teammate_nameを抽出
teammate_nameがあればメッセージに含める
既存のリマインダがあればkill
即時通知
リマインダループ
settings.jsonへの追加
読み上げの例
コピペで導入:Claude Code用セットアッププロンプト
stdinからJSONを読み取り、teammate_nameを抽出(agent teams対応)
まとめ
この記事が参考になったら
https://s3.ap-northeast-1.amazonaws.com/hanzochang.com/_v2/1770701250089_eaz028bl2ee.png

[並列作業] ClaudeCodeに声でリマインダさせて、待ち時間放置時間をゼロに!

Claude Codeが完了や質問待ちになったら音声で喋って教えてくれる。放置が続けば繰り返しリマインド、応答したら自動停止。セッション終了後のリマインダ残留問題の対策と、ミュート切り替え機能も解説。プロンプト付き。

公開日2026.02.10

更新日2026.02.16

AI

Claude Codeの「待ち時間」「放置時間」問題

Claude Codeを複数ターミナルで並列に動かす運用は生産性が高い反面、ある問題が起こります。

フロントの修正、APIのリファクタ、テストの追加──3つのセッションを同時に走らせていると、あるセッションが完了したことに気づかず数分〜十数分放置してしまう。通知音を設定していても、別の作業に集中していると1回の音は聞き逃しがちです。

この「待ち時間」「放置時間」の積み重ねが、並列作業の生産性を大きく下げています。

この記事では、Claude CodeのHooks機能とsayコマンドを使ってClaude Codeに喋らせて状況を教えてもらい、放置が続けば繰り返しリマインドし、応答したら自動で止まる仕組みを実装します。

⚡ 今すぐ設定したい方へ

Claude Codeにコピペするだけで設定が完了するプロンプトを用意しました。 → セットアッププロンプトへジャンプ

目次

基本の通知設定がまだの方へ

この記事はアイドルリマインダに特化した内容です。Claude Codeの基本的な通知音設定(効果音+プロジェクト名読み上げ)がまだの方は、先にこちらの記事を参考にしてください。

Claude Codeの進捗を「音+案件名」で通知する

通知リマインダの仕組み

3つのHooksイベントを組み合わせて、Claude Codeに喋らせます。

使用するイベント

イベント発火タイミング役割
Stop
タスク完了時
音声通知+リマインダ起動
Notification
質問・確認待ち時
音声通知+リマインダ起動
PreToolUse
ユーザー応答後、ツール実行前
リマインダ停止

動作の流れ

[タスク完了] → 音声通知(効果音+「my-app 完了」と喋る)
              2分経過 → リマインド(Ping音+「my-app まだ待っています」)
              2分経過 → リマインド
              ...繰り返し...
          [ユーザーが応答] → PreToolUse発火 → リマインダ停止

PreToolUseがポイントです。Claude Codeがツールを使う直前に発火するイベントなので、「ユーザーが戻ってきてClaude Codeが再び動き出した」タイミングを検知できます。

実装

2つのシェルスクリプトを作成し、settings.jsonで接続します。

notify-idle.sh(音声通知+リマインダ起動)

~/.claude/scripts/notify-idle.sh として保存します。

#!/bin/bash
SOUND="${1:-Hero}"
MESSAGE="${2:-完了}"
PROJECT="$(basename "$PWD")"
PIDFILE="/tmp/claude-idle-$(echo "$PWD" | md5).pid"

# 既存のリマインダがあればkill
if [ -f "$PIDFILE" ]; then
  kill "$(cat "$PIDFILE")" 2>/dev/null
  rm -f "$PIDFILE"
fi

# 即時通知(バックグラウンドで実行し、hookをブロックしない)
(
  afplay "/System/Library/Sounds/${SOUND}.aiff"
  say "${PROJECT} ${MESSAGE}"
) > /dev/null 2>&1 &

# リマインダループ(120秒ごと)
(
  while true; do
    sleep 120
    afplay /System/Library/Sounds/Ping.aiff
    say "${PROJECT} まだ待っています"
  done
) > /dev/null 2>&1 &

echo $! > "$PIDFILE"

cancel-idle.sh(リマインダ停止)

~/.claude/scripts/cancel-idle.sh として保存します。

#!/bin/bash
PIDFILE="/tmp/claude-idle-$(echo "$PWD" | md5).pid"

if [ -f "$PIDFILE" ]; then
  kill "$(cat "$PIDFILE")" 2>/dev/null
  rm -f "$PIDFILE"
fi

実行権限の付与

chmod +x ~/.claude/scripts/notify-idle.sh ~/.claude/scripts/cancel-idle.sh

settings.jsonの設定

~/.claude/settings.jsonhooksに以下を追加します。

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/scripts/notify-idle.sh Hero 完了"
          }
        ]
      }
    ],
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/scripts/notify-idle.sh Glass 質問があります"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/scripts/cancel-idle.sh"
          }
        ]
      }
    ]
  }
}

実装のポイント

パイプの切り離しが必須

> /dev/null 2>&1 & でバックグラウンドプロセスのstdout/stderrを切り離しています。これを省略すると、バックグラウンドプロセスが親のパイプを握り続け、Claude Codeのhookシステムが完了を待ち続けてフリーズします。

PIDファイルによるプロセス管理

PIDファイル名に$(echo "$PWD" | md5)を使うことで、プロジェクトごとに独立したリマインダを管理できます。プロジェクトAの完了通知がプロジェクトBのリマインダを停止してしまう、といった問題が起きません。

リマインド間隔の調整

sleep 120(120秒=2分)がデフォルトのリマインド間隔です。頻繁すぎると感じたら値を大きく、もっと早く気づきたい場合は小さくしてください。

セッション終了後もリマインダが鳴り続ける問題

この仕組みには落とし穴があります。リマインダのループはバックグラウンドの独立プロセスとして動作するため、Claude Codeのセッションを閉じてもリマインダは鳴り続けます。

cancel-idle.shPreToolUseフックでしか呼ばれないため、Claude Codeを終了した後は誰もリマインダを止めてくれません。ターミナルを閉じた後も2分おきに「まだ待っています」と喋り続ける、という状態になります。

対策1:リマインダループ内でプロセスチェック

ループの中でClaudeプロセスの存在を確認し、なければ自動終了します。

# リマインダループ(120秒ごと、Claudeプロセスが存在する間のみ)
(
  while true; do
    sleep 120
    # Claudeプロセスが存在しなければ自動終了
    if ! pgrep -f "claude" > /dev/null 2>&1; then
      rm -f "$PIDFILE"
      exit 0
    fi
    afplay /System/Library/Sounds/Ping.aiff
    say "${REMIND_MESSAGE}"
  done
) > /dev/null 2>&1 &

pgrep -f "claude" でClaudeのプロセスが存在するかチェックし、見つからなければPIDファイルを削除してループを終了します。最大120秒の遅延はありますが、放置され続けることはなくなります。

対策2:StopフックでCancel → Notifyの順に実行

Stopイベントのcommandを変更し、前回のリマインダをキャンセルしてから新しい通知を起動するようにします。

"Stop": [
  {
    "hooks": [
      {
        "type": "command",
        "command": "~/.claude/scripts/cancel-idle.sh && ~/.claude/scripts/notify-idle.sh Hero 完了"
      }
    ]
  }
]

notify-idle.shの中でも既存リマインダのkill処理はありますが、cancel-idle.shを明示的に先に呼ぶことで、確実に前回のリマインダが止まった状態から開始されます。

両方の対策を併用すれば、正常終了時はStopフックで、異常終了時はプロセスチェックで、それぞれリマインダが自動停止します。

サウンドのミュート切り替え

会議中やカフェで作業しているとき、一時的に音を止めたい場面があります。フラグファイルの有無で音声のON/OFFを切り替える仕組みを追加できます。

toggle-sound.sh(ミュート切り替え)

~/.claude/scripts/toggle-sound.sh として保存します。

#!/bin/bash
MUTEFILE="/tmp/claude-sound-muted"

if [ "$1" = "on" ]; then
  rm -f "$MUTEFILE"
  echo "サウンド ON"
elif [ "$1" = "off" ]; then
  touch "$MUTEFILE"
  echo "サウンド OFF"
elif [ -f "$MUTEFILE" ]; then
  rm -f "$MUTEFILE"
  echo "サウンド ON"
else
  touch "$MUTEFILE"
  echo "サウンド OFF"
fi
chmod +x ~/.claude/scripts/toggle-sound.sh

使い方

# 音を消す
~/.claude/scripts/toggle-sound.sh off

# 音をつける
~/.claude/scripts/toggle-sound.sh on

# トグル(引数なしで切り替え)
~/.claude/scripts/toggle-sound.sh

シェルのエイリアスを設定しておくと便利です。

# ~/.zshrc に追加
alias csound="~/.claude/scripts/toggle-sound.sh"

notify-idle.shへのミュート対応

notify-idle.shにフラグファイルのチェックを追加します。

MUTEFILE="/tmp/claude-sound-muted"

# 即時通知
(
  if [ ! -f "$MUTEFILE" ]; then
    afplay "/System/Library/Sounds/${SOUND}.aiff"
    say "${SAY_MESSAGE}"
  fi
) > /dev/null 2>&1 &

# リマインダループ
(
  while true; do
    sleep 120
    if ! pgrep -f "claude" > /dev/null 2>&1; then
      rm -f "$PIDFILE"
      exit 0
    fi
    if [ ! -f "$MUTEFILE" ]; then
      afplay /System/Library/Sounds/Ping.aiff
      say "${REMIND_MESSAGE}"
    fi
  done
) > /dev/null 2>&1 &

ミュート中もリマインダループ自体は動き続けます。/tmp/claude-sound-mutedが消えた瞬間から音が復活するので、フック設定の変更やClaude Codeの再起動は不要です。

Agent Teams対応:チームメンバー名も読み上げる

Claude Codeのagent teams機能で複数のteammateを協調させている場合、「どのメンバーが完了したか」も知りたくなります。

Hooksはstdinにイベント情報のJSONを受け取ります。チーム関連のイベントにはteammate_nameが含まれるため、これを読み取ってメッセージに含めることができます。

チーム関連のHooksイベント

イベント発火タイミング含まれる情報
TeammateIdle
teammateがアイドル状態になった時
teammate_name, team_name
TaskCompleted
teammateがタスクを完了した時
teammate_name, team_name, task_subject

notify-idle.shの拡張

stdinのJSONからteammate_nameを抽出する処理を追加します。

#!/bin/bash
SOUND="${1:-Hero}"
MESSAGE="${2:-完了}"
PROJECT="$(basename "$PWD")"
PIDFILE="/tmp/claude-idle-$(echo "$PWD" | md5).pid"

# stdinからJSONを読み取り、teammate_nameを抽出
INPUT=$(cat 2>/dev/null || echo "{}")
TEAMMATE=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('teammate_name',''))" 2>/dev/null)

# teammate_nameがあればメッセージに含める
if [ -n "$TEAMMATE" ]; then
  SAY_MESSAGE="${PROJECT} ${TEAMMATE} ${MESSAGE}"
  REMIND_MESSAGE="${PROJECT} ${TEAMMATE} まだ待っています"
else
  SAY_MESSAGE="${PROJECT} ${MESSAGE}"
  REMIND_MESSAGE="${PROJECT} まだ待っています"
fi

# 既存のリマインダがあればkill
if [ -f "$PIDFILE" ]; then
  kill "$(cat "$PIDFILE")" 2>/dev/null
  rm -f "$PIDFILE"
fi

# 即時通知
(
  afplay "/System/Library/Sounds/${SOUND}.aiff"
  say "${SAY_MESSAGE}"
) > /dev/null 2>&1 &

# リマインダループ
(
  while true; do
    sleep 120
    afplay /System/Library/Sounds/Ping.aiff
    say "${REMIND_MESSAGE}"
  done
) > /dev/null 2>&1 &

echo $! > "$PIDFILE"

settings.jsonへの追加

既存のhooksにTeammateIdleTaskCompletedを追加します。

{
  "hooks": {
    "TeammateIdle": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/scripts/notify-idle.sh Ping アイドル状態です"
          }
        ]
      }
    ],
    "TaskCompleted": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/scripts/notify-idle.sh Hero タスク完了"
          }
        ]
      }
    ]
  }
}

読み上げの例

イベント通常agent teams利用時
Stop
「my-app 完了」
「my-app 完了」
TeammateIdle
-
「my-app researcher アイドル状態です」
TaskCompleted
-
「my-app implementer タスク完了」
リマインド
「my-app まだ待っています」
「my-app researcher まだ待っています」

agent teamsを使っていない場合はteammate_nameが空になるため、今まで通りプロジェクト名だけが読み上げられます。既存の設定と完全に互換です。

コピペで導入:Claude Code用セットアッププロンプト

以下のプロンプトをClaude Codeにそのまま貼り付ければ、スクリプトの作成からsettings.jsonの設定まで自動で行ってくれます。

Claude Codeの通知リマインダをセットアップして。以下の通りに実装してほしい。

■ 1. ~/.claude/scripts/notify-idle.sh を作成(実行権限付き)

#!/bin/bash
SOUND="${1:-Hero}"
MESSAGE="${2:-完了}"
PROJECT="$(basename "$PWD")"
PIDFILE="/tmp/claude-idle-$(echo "$PWD" | md5).pid"
MUTEFILE="/tmp/claude-sound-muted"

# stdinからJSONを読み取り、teammate_nameを抽出(agent teams対応)
INPUT=$(cat 2>/dev/null || echo "{}")
TEAMMATE=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('teammate_name',''))" 2>/dev/null)

if [ -n "$TEAMMATE" ]; then
  SAY_MESSAGE="${PROJECT} ${TEAMMATE} ${MESSAGE}"
  REMIND_MESSAGE="${PROJECT} ${TEAMMATE} まだ待っています"
else
  SAY_MESSAGE="${PROJECT} ${MESSAGE}"
  REMIND_MESSAGE="${PROJECT} まだ待っています"
fi

if [ -f "$PIDFILE" ]; then
  kill "$(cat "$PIDFILE")" 2>/dev/null
  rm -f "$PIDFILE"
fi

(
  if [ ! -f "$MUTEFILE" ]; then
    afplay "/System/Library/Sounds/${SOUND}.aiff"
    say "${SAY_MESSAGE}"
  fi
) > /dev/null 2>&1 &

(
  while true; do
    sleep 120
    if ! pgrep -f "claude" > /dev/null 2>&1; then
      rm -f "$PIDFILE"
      exit 0
    fi
    if [ ! -f "$MUTEFILE" ]; then
      afplay /System/Library/Sounds/Ping.aiff
      say "${REMIND_MESSAGE}"
    fi
  done
) > /dev/null 2>&1 &

echo $! > "$PIDFILE"

■ 2. ~/.claude/scripts/cancel-idle.sh を作成(実行権限付き)

#!/bin/bash
PIDFILE="/tmp/claude-idle-$(echo "$PWD" | md5).pid"

if [ -f "$PIDFILE" ]; then
  kill "$(cat "$PIDFILE")" 2>/dev/null
  rm -f "$PIDFILE"
fi

■ 3. ~/.claude/scripts/toggle-sound.sh を作成(実行権限付き)

#!/bin/bash
MUTEFILE="/tmp/claude-sound-muted"

if [ "$1" = "on" ]; then
  rm -f "$MUTEFILE"
  echo "サウンド ON"
elif [ "$1" = "off" ]; then
  touch "$MUTEFILE"
  echo "サウンド OFF"
elif [ -f "$MUTEFILE" ]; then
  rm -f "$MUTEFILE"
  echo "サウンド ON"
else
  touch "$MUTEFILE"
  echo "サウンド OFF"
fi

■ 4. ~/.claude/settings.json のhooksに以下を設定

- Stop: ~/.claude/scripts/cancel-idle.sh && ~/.claude/scripts/notify-idle.sh Hero 完了
- Notification(matcher空文字): ~/.claude/scripts/notify-idle.sh Glass 質問があります
- PreToolUse(matcher空文字): ~/.claude/scripts/cancel-idle.sh
- TeammateIdle: ~/.claude/scripts/notify-idle.sh Ping アイドル状態です
- TaskCompleted: ~/.claude/scripts/notify-idle.sh Hero タスク完了

既存のsettings.jsonの設定はそのまま残してhooksだけ追加・更新して。

まとめ

Claude Codeの「待ち時間」「放置時間」は、Hooksとsayコマンドの組み合わせで解消できます。

  • Stop / Notification で音声通知とリマインダループを起動
  • PreToolUse でユーザー応答を検知してリマインダを自動停止
  • PIDファイルでプロジェクトごとに独立管理
  • > /dev/null 2>&1 & でhookのブロックを回避
  • pgrepによるプロセスチェックで、セッション終了後のリマインダ残留を防止
  • Stopフックでcancel-idle.shを先に呼び、前回のリマインダを確実に停止
  • フラグファイルベースのミュート切り替えで、会議中や外出先でもサッとON/OFFできる

Claude Codeに喋らせることで、セッションを3つ、4つと増やしても画面を見ずに状況を把握できます。

参考リンク

この記事が参考になったら

この記事が役に立ったと思いましたら、よろしければフォローをお願いします。

X (Twitter)Xをフォローする

Claude Codeを活用した開発効率化やAIワークフローの構築に興味がありましたら、お気軽にご連絡ください。

株式会社hanzochangお問い合わせフォーム
picture
hanzochang - 半澤勇大
慶應義塾大学卒業後、Webプランナーとして勤務。 ナショナルクライアントのキャンペーンサイトの企画・演出を担当。 その後開発会社に創業メンバーとして参加。 Fintech案件や大手企業のDXプロジェクトに関わり、その後個人事業主として独立し、 2023年にWeb3に特化した開発会社として法人化しました。 現在はWeb3アプリ開発を中心にAI開発フローの整備を行っています。
また、趣味で2017年ごろより匿名アカウントでCryptoの調査等を行い、 ブロックチェーンメディアやSNSでビットコイン論文等の図解等を発信していました。
X (Twitter)

最新の記事

x402 × Solana実装ガイド | 支払い対応MCPサーバーをTypeScriptで構築する

x402 × Solana実装ガイド | 支払い対応MCPサーバーをTypeScriptで構築する

x402 V2プロトコルのSolana実装を徹底解説。SVM exact schemeの仕組みから、@x402/mcpパッケージを使った支払い対応MCPサーバーの構築まで、実際のコードとともにステップバイステップで解説します。

x402 V2 解説 | Solana等マルチチェーン対応・OpenClawの自動売買にも利用されるHTTP決済プロトコル

x402 V2 解説 | Solana等マルチチェーン対応・OpenClawの自動売買にも利用されるHTTP決済プロトコル

累計$600M超のボリュームを記録するHTTP決済プロトコルx402がV2で大幅進化。Solana等のマルチチェーン対応、Extensions拡張機構、Discovery APIを解説。OpenClaw FoundryやClawRouterなどAIエージェントの自動売買での採用事例も紹介します。

x402とは? AIエージェント × MCP × 暗号資産が交差するHTTP自動決済プロトコル

x402とは? AIエージェント × MCP × 暗号資産が交差するHTTP自動決済プロトコル

HTTP 402を活用した決済プロトコル「x402」の入門ガイド。暗号資産(USDC)即時決済、AIエージェントによるMCP経由の自動購入、マルチチェーン対応まで、全体像を解説します。

ClaudeCode スマホでリモート接続 - OpenClawはもう不要?! RemoteControlを使おう

ClaudeCode スマホでリモート接続 - OpenClawはもう不要?! RemoteControlを使おう

Claude Code Remote Controlを使えば、PCで動作中のセッションをスマホやタブレットからそのまま操作できます。QRコード接続、セキュリティ設定、トラブルシューティングまで解説します。

OpenClaw × Solana 事例まとめ - 公式スキル・周辺プロダクト・使いどころ

OpenClaw × Solana 事例まとめ - 公式スキル・周辺プロダクト・使いどころ

OpenClawとSolanaが交わる実例(公式スキル、周辺プラグイン、取引・監視系プロジェクト、ハッカソン)を一次ソースのリンク付きで一覧にまとめます。

OpenClaw APIトークン節約 - Happy + Claude Codeで出先から開発・指示出し

OpenClaw APIトークン節約 - Happy + Claude Codeで出先から開発・指示出し

Happyのプロセス切断をOpenClawで復帰させ、出先からいつでもClaude Code / Codexにリモートアクセスする方法を解説。APIトークンの節約と、スマホ1台で完結するAI開発ワークフローを紹介します。