mcpField
G
goal-supervisor

goal-supervisor

github.com/joelfranciscoエージェントワークフロー096 回インストール11 週間前に更新
リポジトリ

goal-supervisor について

Goal Supervisorは、Claudeのプロセス終了後も長時間の目標やワークフローを進めるためのスキルです。会話記録やチェックポイントから再開し、完了・ブロック・再起動上限到達をセンチネルファイルで示します。

主な機能

  1. 01バックオフ付きで失敗したプロセスを再起動
  2. 02会話記録とチェックポイントから再開
  3. 03センチネルファイルで完了やブロックを通知
  4. 04監視下でのワークフロー実行

活用シーン

  1. 01Claudeプロセス終了後の目標タスクの再開
  2. 02独立したセッションでの長時間ワークフロー実行
  3. 03ログアウトや再起動後も目標の監視を継続

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/joelfrancisco/skills --skill goal-supervisor

インストール後、Claude Code で/goal-supervisorを入力して読み込まれたか確認します。

同梱ファイルsupervise.sh

詳細

ゴールスーパーバイザー

/goal をオーケストレーションする claude プロセスが終了すると、サブエージェントは動作を続けますが、ループを進めるものがなくなります。しかし、状態はセッショントランスクリプトに残っているため、claude -p --resume <session-id> を実行すれば、コンテキストをすべて保ったまま再開できます。このスキルは、supervise.sh(この SKILL.md と同じディレクトリにあります。ここから絶対パスを解決してください)を起動し、one_for_one の監督ツリーを実現します。

launchd/systemd/tmux (optional) ← keeps the supervisor alive
  └── supervise.sh              ← restart policy + backoff + stall detection
        └── claude -p /goal     ← worker, session pinned via --session-id
              └── subagents     ← survive on their own; the worker re-adopts state

再開の仕組み: スーパーバイザー自身がセッション UUID を選びます(uuidgen と --session-id を使用)。ワーカーが .supervisor/DONE を作成せずに終了した場合、スーパーバイザーは claude -p --resume <uuid> で再起動し、コンテキストをすべて維持します。ワーカーには、各ステップの後に .supervisor/checkpoint.md(claude-handoff 形式の短い要約)を更新するよう指示されています。セッションを再開できなくなった場合(トランスクリプトが見つからない、または再開を繰り返しすぐに失敗する場合)、スーパーバイザーはそのセッションを破棄し、チェックポイントを参照するプロンプトで新しいセッションを開始するため、進捗は引き継がれます。

終了結果: スーパーバイザーは、意図的な停止では常に 0 で終了し、停止理由を示すセンチネルを残します。.supervisor/DONE(ゴール完了)、.supervisor/BLOCKED(人間の対応が必要。ブロッカーは checkpoint.md に記載)、.supervisor/GAVE_UP(再起動上限に到達)です。ゼロ以外の終了コードはスーパーバイザー自体のクラッシュを意味します。ルートスーパーバイザーが再起動するのは、まさにこの場合です。BLOCKED または GAVE_UP が存在する間は、スーパーバイザーを再起動してもすぐに 0 で終了します。ブロッカーを解決してセンチネルを削除するか、--fresh を指定すると再試行できます。

起動方法

デーモンを優先してください。 agent-supervisord(このスクリプトのプロトタイプとなった Rust 製デーモン)は、同じセンチネルプロトコルを、より優れたセマンティクスで監督します。モデル/クォータの制限に達した場合、再起動回数を消費してしまう(bash スクリプトでは制限に達するまで再試行します)のではなく、すぐに BLOCKED になります。また、再起動タイプ、グループ、メールボックスの call/cast、セルフウォッチドッグも備えています。デーモンが起動している場合は常にデーモン経由で起動し、起動していない場合は supervise.sh にフォールバックしてください。

  1. ユーザーの意図を考慮して、ヘッドレス実行時の権限モードを決めます。-p では対話型プロンプトが表示されないため、--permission-mode acceptEdits(またはユーザーが希望する場合は bypassPermissions)を指定しないゴールは、最初の編集拒否で停止します。デーモンの種類ごとのデフォルトは、goal→acceptEdits、workflow→bypassPermissions です。上書きするには --claude-arg のペアを渡します。
  2. agentctl ping が応答する場合は、ジョブを追加して起動します。--workdir にはゴール専用のディレクトリを指定する必要があります(ここに .supervisor/ が作成されるため、ゴール間で共有してはいけません。ワーカーは引き続き、親ディレクトリをたどってリポジトリの CLAUDE.md を見つけます)。
agentctl add --name goal-<slug> --kind goal \
  --target "<abs path>/goals/<slug>/goal.md" \
  --workdir "<abs path>/goals/<slug>" \
  --claude-arg=--permission-mode --claude-arg=bypassPermissions \
  --start

(Workflow スクリプトを対象にする場合は --kind workflow を指定します。)デーモンが停止している場合に限り、現在のセッションのプロセスツリー外で、bash のフォールバックをバックグラウンド起動します。

nohup "<path-to-this-skill>/supervise.sh" "goals/<slug>/goal.md" \
  -- --permission-mode acceptEdits >/dev/null 2>&1 &
  1. ユーザーに進捗の確認方法と、結果を示すセンチネルファイルを伝えます(どちらのランナーでも同じパスです)。
    • agentctl status goal-<slug> / agentctl logs goal-<slug> -f — デーモンの状態
    • tail -f goals/<slug>/.supervisor/worker.log — claude の出力
    • .supervisor/DONE / BLOCKED / GAVE_UP — 結果を示すセンチネル(上記参照)
    • 実行中のジョブへの指示:agentctl cast goal-<slug> "<instruction>" (次のターンで配信されます。デーモンのみ)

supervise.sh のオプション

  • --max-restarts N / --window S — 再起動の強度(デフォルトは 3600 秒あたり 10 回の再起動。初回起動は含みません)。上限を超えると処理を断念し、GAVE_UP を書き込んで通知します。
  • --stall S — セッショントランスクリプトに S 秒間アクティビティがない場合、プロセスを終了して再起動します(デフォルトは 3600。0 で無効)。トランスクリプトファイルが見つからない間は無効になるため、パスが一致しないだけで正常なワーカーが終了することはありません。長時間にわたり出力がないフェーズ(大規模なビルド、サブエージェントの長時間実行など)があるゴールでは、値を大きくしてください。
  • --fresh — 以前のセッションと結果センチネルを破棄して最初からやり直します(メモリーとしてチェックポイントは保持します)。

ワークフロー(--kind workflow)

長時間実行されるワークフローは、ホストとなる会話がコンパクションされると停止します。解決策は分離です。会話が小さく保たれる専用の監視対象セッションでワークフローを実行すれば、コンパクションは発生しません。同じツリーを別のワーカーで実行します。

nohup "<path-to-this-skill>/supervise.sh" "path/to/workflow.js" --kind workflow \
  -- --permission-mode bypassPermissions --model sonnet >/dev/null 2>&1 &
  • ランナーセッションはスクリプトで Workflow ツールを呼び出し、実行 ID を .supervisor/workflow-run-id に保存して、完了を待ち、.supervisor/result.md と DONE を書き込みます。
  • 停止した場合、再開したセッションはそのファイルに記録された resumeFromRunId を指定して Workflow を呼び出します。完了済みの agent() 呼び出しはジャーナルキャッシュから再生され、残りの処理だけがライブで実行されます。再開後も同じ実行 ID/ジャーナルが使われます。
  • ジャーナルキャッシュはセッションに紐づいています。監視プロセスがセッションを破棄せざるを得ない場合(トランスクリプトを再開できない場合)、ワークフローは最初から再実行されます。
  • 権限: acceptEdits だけでは不十分です。ヘッドレスセッションから動的なワークフロースクリプトを実行すると、対話型の承認が求められ、その場で実行が停止します。--permission-mode bypassPermissions(検証済み)を使うか、より限定したい場合は Workflow ツールを対象とする権限許可リストを使用してください。
  • エンドツーエンドで検証済み:ステージ 3/12 の途中で SIGKILL → 再開 → 3 ステージはキャッシュから、9 ステージはライブで実行され、結果全体が返されます。

監視プロセスの監視プロセス(ツリーのルート)

ログアウトや再起動後も実行を継続するには、supervise.sh 自体をシステムの初期化プロセスのもとで実行します。意図的な停止では終了コード 0 が返るため、「失敗時のみ再起動」を設定すると、どちらのプラットフォームでも適切な動作になります。クラッシュ時は再起動し、DONE/BLOCKED/GAVE_UP の場合は停止したままになります。

macOS(launchd): ProgramArguments が supervise.sh と goal.md を指し、WorkingDirectory がリポジトリに設定され、RunAtLoad と KeepAlive: {SuccessfulExit: false} を含む ~/Library/LaunchAgents/com.user.goal-<slug>.plist を生成し、launchctl load で読み込みます。

Linux(systemd user unit): 手早く行うには、一時ユニットを使います。

systemd-run --user --unit=goal-<slug> \
  --property=Restart=on-failure --property=RestartSec=30 \
  --working-directory=<repo> \
  "<path-to-this-skill>/supervise.sh" "goals/<slug>/goal.md" -- --permission-mode acceptEdits
# follow along: journalctl --user -u goal-<slug> -f

ログアウト後も実行を継続するには、リンガーを有効にします:loginctl enable-linger $USER。 (永続化する場合は、~/.config/systemd/user/ に Restart=on-failure と WorkingDirectory を設定した .service を作成し、systemctl --user enable --now を実行します。)

両プラットフォームでの簡単な代替手段:tmux new -d -s goal-<slug> '...supervise.sh ...'。

コメント