キャンセルスキル
アクティブなOMCモードを検出してキャンセルするインテリジェントなキャンセル機能。
キャンセルスキルは、任意のOMCモードを完了および終了する標準的な方法です。
停止フックが処理の完了を検出すると、LLMにこのスキルを呼び出すよう指示し、適切な状態クリーンアップを行います。キャンセルが失敗または中断された場合は、--forceフラグを付けて再試行するか、最後の手段として2時間のスティルネスタイムアウトを待ちます。
機能
アクティブなモードを自動的に検出し、キャンセルします:
- オートパイロット: ワークフローを停止し、再開用に進捗を保持します
- ラルフ: 永続化ループを停止します
- レガシーUltrawork状態: アップグレードされたインストールのためのクリーンアップ専用削除。アクティブなワークフローではありません
- ウルトラQA(廃止): ライブワークフローは残っていません。5.0.0以前の
ultraqa-state.jsonが存在する場合は削除します - ウルトラゴール: セッションスコープのウルトラゴールランタイムガード(
.omc/state/.../ultragoal-state.json)をクリアし、PreToolUse/goalの強制と停止の強化を解放します。永続的な.omc/ultragoal/計画/台帳アーティファクトは保持されます。 - スウォーム: 調整されたエージェントスウォームを停止し、要求されたタスクを解放します
- ウルトラパイロット: 並列オートパイロットワーカーを停止します
- パイプライン: シーケンシャルエージェントパイプラインを停止します
- チーム: アクティブなチーム/会話サーフェスを通じて全チームメイトにシャットダウンを要求し、応答/タイムアウトを待ち、OMCチーム状態をクリアし、リンクされたラルフが存在する場合はそれをクリアします。Claude Code 2.1.178+ にはTeamDeleteはありません。
- チーム+ラルフ(リンク): まずチームをキャンセル(グレースフルシャットダウン)し、次にラルフ状態をクリアします。リンク時にラルフをキャンセルすると、最初にチームもキャンセルされます。
使用方法
/oh-my-claudecode:cancel
または次のように言う: "cancelomc", "stopomc"
重要な注意事項:遅延ツール処理
状態管理ツール(state_clear、state_read、state_write、state_list_active、state_get_status)は、Claude Codeによって遅延ツールとして登録される場合があります。状態ツールを呼び出す前に、ToolSearchを使用してそれらをすべて最初にロードする必要があります:
ToolSearch(query="select:mcp__plugin_oh-my-claudecode_t__state_clear,mcp__plugin_oh-my-claudecode_t__state_read,mcp__plugin_oh-my-claudecode_t__state_write,mcp__plugin_oh-my-claudecode_t__state_list_active,mcp__plugin_oh-my-claudecode_t__state_get_status")
state_clearが利用できないか失敗した場合は、このbashフォールバックを停止フックループからの緊急脱出として使用してください。これはキャンセルフローの完全な代替ではありません。セッションのブロックを解除するために状態ファイルを削除するだけです。リンクされたアクティブモード(例:autopilot→ralph)は、モードごとにフォールバックを1回実行して別々にクリアする必要があります。
MODEを特定のモード(例:ralplan、ralph、ultrawork、ultragoal)に置き換えてください。
警告: autopilotまたはomc-teamsにはこのフォールバックを使用しないでください。オートパイロットでは、再開データを保持するためにstate_write(active=false)が必要です。omc-teamsでは、ファイル削除だけでは実行できないtmuxセッションのクリーンアップが必要です。
# フォールバック: state_clear MCPツールが利用できない場合の直接ファイル削除
SESSION_ID="${CLAUDE_SESSION_ID:-${CLAUDECODE_SESSION_ID:-}}"
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || { d="$PWD"; while [ "$d" != "/" ] && [ ! -d "$d/.omc" ]; do d="$(dirname "$d")"; done; echo "$d"; })"
# クロスプラットフォームSHA-256 (macOS: shasum, Linux: sha256sum)
sha256portable() { printf '%s' "$1" | (sha256sum 2>/dev/null || shasum -a 256) | cut -c1-16; }
# 状態ディレクトリを解決(OMC_STATE_DIR集中ストレージをサポート)
if [ -n "${OMC_STATE_DIR:-}" ]; then
# worktree-paths.tsのgetProjectIdentifier()をミラー
SOURCE="$(git remote get-url origin 2>/dev/null || echo "$REPO_ROOT")"
HASH="$(sha256portable "$SOURCE")"
DIR_NAME="$(basename "$REPO_ROOT" | sed 's/[^a-zA-Z0-9_-]/_/g')"
OMC_STATE="$OMC_STATE_DIR/${DIR_NAME}-${HASH}/state"
[ ! -d "$OMC_STATE" ] && { echo "ERROR: State dir not found at $OMC_STATE" >&2; exit 1; }
elif [ "$REPO_ROOT" != "/" ] && [ -d "$REPO_ROOT/.omc" ]; then
OMC_STATE="$REPO_ROOT/.omc/state"
else
echo "ERROR: Could not locate .omc state directory" >&2
exit 1
fi
MODE="ralplan" # <-- ターゲットモードに置き換え
# 特定のモードのセッションスコープ状態をクリア
if [ -n "$SESSION_ID" ] && [ -d "$OMC_STATE/sessions/$SESSION_ID" ]; then
rm -f "$OMC_STATE/sessions/$SESSION_ID/${MODE}-state.json"
rm -f "$OMC_STATE/sessions/$SESSION_ID/${MODE}-stop-breaker.json"
rm -f "$OMC_STATE/sessions/$SESSION_ID/skill-active-state.json"
# キャンセル信号を書き込み、停止フックがキャンセル進行中を検出できるようにする
NOW_ISO="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
EXPIRES_ISO="$(date -u -d "+30 seconds" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || python3 - <<'PY'\nfrom datetime import datetime, timedelta, timezone\nprint((datetime.now(timezone.utc) + timedelta(seconds=30)).strftime('%Y-%m-%dT%H:%M:%SZ'))\nPY\n)"
printf '{"active":true,"requested_at":"%s","expires_at":"%s","mode":"%s","source":"bash_fallback"}' \
"$NOW_ISO" "$EXPIRES_ISO" "$MODE" > "$OMC_STATE/sessions/$SESSION_ID/cancel-signal-state.json"
fi
# セッションIDがない場合のみレガシー状態をクリア(他のセッションの状態をクリアしないようにする)
if [ -z "$SESSION_ID" ]; then
rm -f "$OMC_STATE/${MODE}-state.json"
fi
自動検出
/oh-my-claudecode:cancel はセッション認識型の状態契約に従います:
- デフォルトでは、コマンドは
state_list_activeとstate_get_statusを使用して現在のセッションを検査し、.omc/state/sessions/{sessionId}/…を参照してアクティブなモードを特定します。 - セッションIDが提供されているか既知の場合は、そのセッションスコープのパスが信頼されます。レガシーファイル
.omc/state/*.jsonは、セッションIDが欠落または空の場合の互換性フォールバックとしてのみ参照されます。 - スウォームは共有SQLite/マーカーモード(
.omc/state/swarm.db/.omc/state/swarm-active.marker)であり、セッションスコープではありません。 - デフォルトのクリーンアップロジックは、セッションIDを使用して
state_clearを呼び出し、一致するセッションファイルのみを削除します。モードは元のセッションにバインドされたままです。
アクティブなモードは依存関係の順序でキャンセルされます:
- オートパイロット(リンクされたラルフと廃止された状態のクリーンアップを含む)
- ラルフ
- レガシーUltrawork/UltraQA状態クリーンアップ
- ウルトラゴール(スタンドアロンランタイムガード —
state_clear(mode="ultragoal"); 永続的な.omc/ultragoal/アーティファクトを保持) - スウォーム(スタンドアロン)
- ウルトラパイロット(スタンドアロン)
- パイプライン(スタンドアロン)
- チーム(Claude Codeネイティブ)
- OMC Teams(tmux CLIワーカー)
- 計画コンセンサス(スタンドアロン)
- 自己改善(スタンドアロン — 状態をクリアし、孤立したワークツリーをクリーンアップし、再開用にiteration_stateを保持し、解決された
<self-improve-root>/state/agent-settings.jsonにステータス「user_stopped」を設定。新しい実行は.omc/self-improve/topics/<topic-slug>/を使用し、フラットな.omc/self-improve/はレガシーシングルトラック再開のためにのみ保持)
すべてを強制クリア
ワークスペースを完全にリセットする場合など、すべてのセッションとレガシーアーティファクトを消去する必要がある場合は、--forceまたは--allを使用します。
/oh-my-claudecode:cancel --force
/oh-my-claudecode:cancel --all
内部の手順:
state_list_activeが.omc/state/sessions/{sessionId}/…を列挙し、既知のすべてのセッションを検出します。state_clearがセッションごとに1回実行され、そのセッションのファイルを削除します。session_idなしのグローバルなstate_clearが、.omc/state/*.json、.omc/state/swarm*.db、および互換性アーティファクト(リスト参照)の下のレガシーファイルを削除します。- チームアーティファクト(
~/.claude/teams/*/、~/.claude/tasks/*/、.omc/state/team-state.json)は、レガシーフォールバックの一部としてベストエフォートでクリアされます。- ネイティブチームのキャンセルはomc-teams状態に影響を与えず、その逆も同様です。
すべてのstate_clearコマンドはsession_id引数を尊重するため、フォースモードでもレガシーファイルを削除する前に、まずセッション認識パスを使用します。
レガシー互換性リスト(--force/--all下でのみ削除):
.omc/state/autopilot-state.json.omc/state/ralph-state.json.omc/state/ralph-plan-state.json.omc/state/ralph-verification.json.omc/state/ultrawork-state.json.omc/state/ultraqa-state.json.omc/state/swarm.db.omc/state/swarm.db-wal.omc/state/swarm.db-shm.omc/state/swarm-active.marker.omc/state/swarm-tasks.db.omc/state/ultrapilot-state.json.omc/state/ultrapilot-ownership.json.omc/state/pipeline-state.json.omc/state/omc-teams-state.json.omc/state/plan-consensus.json.omc/state/ralplan-state.json.omc/state/boulder.json.omc/state/hud-state.json.omc/state/subagent-tracking.json.omc/state/subagent-tracker.lock.omc/state/rate-limit-daemon.pid.omc/state/rate-limit-daemon.log.omc/state/checkpoints/(ディレクトリ).omc/state/sessions/(セッションクリア後の空ディレクトリクリーンアップ)
実装手順
このスキルを呼び出す場合:
1. 引数の解析
# --force または --all フラグのチェック
FORCE_MODE=false
if [[ "$*" == *"--force"* ]] || [[ "$*" == *"--all"* ]]; then
FORCE_MODE=true
fi
2. アクティブモードの検出
このスキルは、ハードコードされたファイルパスではなく、セッション認識型の状態契約に依存するようになりました:
state_list_activeを呼び出して.omc/state/sessions/{sessionId}/…を列挙し、すべてのアクティブセッションを検出します。- セッションIDごとに
state_get_statusを呼び出し、実行中のアクティブモードと依存モードが存在するかどうかを確認します。Ultraworkレコードは廃止されたクリーンアップ入力としてのみ扱います。 /oh-my-claudecode:cancelにsession_idが指定された場合、レガシーフォールバックを完全にスキップし、そのセッションパス内でのみ動作します。それ以外の場合は、状態ツールがアクティブなセッションを報告しない場合にのみ、.omc/state/*.jsonのレガシーファイルを参照します。スウォームはセッションスコープ外の共有SQLite/マーカーモードのままです。- このドキュメントのキャンセルロジックはすべて、状態ツールを介して検出された依存関係順序(autopilot → ralph → ...)を反映しています。
3A. フォースモード(--force または --all の場合)
フォースモードを使用して、state_clearを介してすべてのセッションとレガシーアーティファクトをクリアします。直接ファイル削除は、状態ツールがアクティブなセッションを報告しない場合のレガシークリーンアップのために予約されています。
3B. スマートキャンセル(デフォルト)
チームがアクティブな場合(Claude Code暗黙的チーム)
チームはOMCチーム状態を介して検出され、削除されたClaude Code ~/.claude/teams設定ディレクトリは検出されません:
# アクティブなOMCチーム状態の確認
state_read(mode="team")
2パスキャンセルプロトコル:
パス 1: グレースフルシャットダウン
アクティブなOMCチーム状態の場合:
1. OMC状態/ハンドオフ/タスク台帳からteam_nameとワーカーラベルを読み取る
2. アクティブなチームメイトごとに:
a. アクティブな会話/チームメッセージングサーフェスを通じて、名前付きのチームメイトにシャットダウンを要求または通知する
b. シャットダウン応答を最大15秒待つ
c. 応答を受信した場合: メンバーを確認済みとしてマーク
d. タイムアウトの場合: メンバーを応答なしとしてマークし、次に進む
3. ログ: "グレースフルパス: X/Y メンバーが応答しました"
パス 2: 調整
グレースフルパス後:
1. 応答のないチームメイトがまだ処理中である可能性があるため、さらに5秒待つ
2. 残りの応答のないチームメイトをキャンセルレポートに記録する
3. TeamDeleteを呼び出さない。Claude Code 2.1.178+ はチームごとのネイティブクリーンアップを削除しました
OMC状態クリーンアップ:
1. チーム状態をクリア: state_clear(mode="team")
2. リンクされたラルフを確認: state_read(mode="ralph") — linked_teamがtrueの場合:
a. ラルフ状態をクリア: state_clear(mode="ralph")
3. レガシー`omc team` / `/omc-teams`ワーカーのみOMC tmux/CLI孤立スキャンを実行(以下参照)
4. 構造化キャンセルレポートを出力
孤立検出(クリーンアップ後):
レガシーOMC tmux/CLIワーカー実行の場合、ワーカープロセスが残っていないことを確認します:
node "${CLAUDE_PLUGIN_ROOT}/scripts/cleanup-orphans.mjs" --team-name "{team_name}"
孤立スキャナー:
ps aux(Unix)またはtasklist(Windows)で、クリーンアップされたチームと一致する--team-nameを持つOMCワーカープロセスをチェック- SIGTERMを送信し、5秒待機し、まだ生きている場合はSIGKILLを送信
- クリーンアップ結果をJSONとして報告
--dry-runを使用して、強制終了せずに検査します。スキャナーは複数回実行しても安全です。
構造化キャンセルレポート:
チーム "{team_name}" がキャンセルされました:
- 通知されたメンバー: N
- 受信した応答数: M
- 応答なし: K(存在する場合は名前をリスト)
- OMC状態クリア: はい/いいえ
- 手動クリーンアップが必要: はい/いいえ
パス: OMCチーム状態 / tmuxワーカープロセス(存在する場合)
実装上の注意: キャンセルスキルはbashスクリプトとしてではなく、LLMによって実行されます。アクティブなチームを検出した場合:
state_read(mode="team")を読み取り、アクティブなOMCチームを見つけます- 状態、ハンドオフ、またはタスク台帳からアクティブな名前付きチームメイトを特定します
- チームメイトごとに、アクティブな会話/チームメッセージングサーフェスを通じて、名前付きチームメイトにシャットダウンを要求または通知します
- シャットダウン応答を短時間待機します(メンバーごとに15秒のタイムアウト)
- 調整待機後、応答のないチームメイトを記録します
- チーム状態をクリア:
state_clear(mode="team", session_id) - ユーザーに構造化された概要を報告します
オートパイロットがアクティブな場合
オートパイロットは、独自のプライマリファーストクリーンアップを処理します。名前付きワークフローは、リンクされたラルフと廃止されたウルトラQAクリーンアップの前に、自身のセッション所有のネストされたralplan強制状態のみを削除します。
state_read(mode="autopilot", session_id)を介してオートパイロット状態を読み取り、workflowRunIdが存在する場合はそれを含む正確な現在の実行を取得します。state_write(mode="autopilot", session_id, active=false, state={workflowRunId: "<正確なrun id>"})という狭い変更でその正確な実行を一時停止します。状態の読み返しを再生またはコピーしないでください。Linuxのflockでは、ツールは変更ロック下で保持された実行とワークフローの整合性を再検証してから、activeのみをfalseに変更します。ワークフロー、パイプライン追跡、タスクIDを保持します。target_state_sha256は、現在のシリアル化状態の正確なSHA-256である場合にのみ含めることができます。- この書き込みが失敗した場合は、すぐに停止します。ネストされたralplan、リンクされた状態、キャンセル信号、またはランタイムアーティファクトをクリアしないでください。
- 名前付きワークフローの場合、同じ
session_idが所有するralplan状態のみをクリアします。別のセッションのスタンドアロンralplan状態をクリアしないでください。障害を記録しますが、一時停止されたプライマリは再開可能なままにします。 - プライマリの一時停止がコミットされた後にのみ、
state_read(mode="ralph", session_id)を介してリンクされたラルフを確認します。linked_autopilotがtrueの場合のみ、ラルフ状態をクリアします。 - リンクされたラルフのクリーンアップ後、廃止されたウルトラQA状態をクリアします(
active: falseとして安全に無視されるため、これはベストエフォートでかまいません)。 - ラルフのクリーンアップが確認された場合に限り、キャンセル信号を書き込みます。
実装上の注意: 上記のフローをbashスクリプトとして実行しないでください。状態ツールを呼び出して、説明されている手順を段階的に実行してください。
スウォームがアクティブな場合
state_read(mode="swarm")
スウォームキャンセルはスタンドアロンであり、他のモードにリンクされません:
state_read(mode="swarm")を介してスウォーム状態を読み取り、タスク割り当てを取得します。- 各タスクについて、ワーカーが保持している場合は
state_writeを介してtask_idリリースを記録します。 state_clear(mode="swarm")でスウォーム状態をクリアします。- 構造化キャンセルレポートを出力します。
ラルフがアクティブな場合(リンクされていないスタンドアロン)
state_read(mode="ralph")
ラルフがスタンドアロンでアクティブな場合:
state_read(mode="ralph", session_id)を介してラルフ状態を読み取ります。- 永続化ループの完了を確認します。
state_clear(mode="ralph", session_id)でラルフ状態をクリアします。- 構造化キャンセルレポートを出力します。
その他のモードがアクティブな場合
その他すべてのアクティブモードは、スタンドアロンのクリーンアップロジックに従います:
- ウルトラゴール:
state_clear(mode="ultragoal", session_id)。.omc/ultragoal/アーティファクトは保持されます。 - ウルトラパイロット:
state_clear(mode="ultrapilot", session_id)。 - パイプライン:
state_clear(mode="pipeline", session_id)。 - 自己改善:
state_clear(mode="self-improve", session_id)。iteration_stateを保持し、ステータスを「user_stopped」に設定します。
4. キャンセルレポートの出力
キャンセル後に構造化された概要をユーザーに出力します。例:
## OMCキャンセルレポート
**アクティブモード:** オートパイロット + ラルフ
**アクション:**
- ✅ オートパイロット: 一時停止済み(再開可能)
- ✅ ラルフ: クリア済み
- ✅ レガシーUltraQA状態: 存在しません
**結果:** すべてのアクティブ状態がクリアされました
## OMCキャンセルレポート
**アクティブモード:** チーム
**アクション:**
- ✅ チーム「my-engineering-team」: グレースフルシャットダウン送信
- ✅ 応答したメンバー: 4/5
- ⚠️ 応答なし: alice(手動確認が必要)
- ✅ OMC状態クリア
**結果:** チームはキャンセルされました。1人のメンバーが応答しませんでした
実装手順(続き)
レガシーOMC tmux CLIチームサポートの詳細
チームがアクティブな場合(レガシーOMC tmux CLIチーム)
レガシーOMC tmux CLIチームは、Claude Codeのネイティブチーム機能ではなく、別のメカニズムです。代わりにomc-teams状態を検出してください:
state_read(mode="omc-teams")
レガシーOMC tmux CLIチームの場合:
実装上の注意:
omc-teamsモードは、Claude Codeネイティブのteamモードとは異なります。omc-teams検出はstate_read(mode="omc-teams")をチェックし、ネイティブチームのstate_read(mode="team")とは別に処理する必要があります。
state_read(mode="omc-teams")を介してomc-teams状態を読み取ります。- 各tmuxワーカーについて:
a. tmuxセッションIDを特定します。
b. tmuxセッションにシャットダウンコマンドを送信します。例:
tmux send-keys -t "{session_id}" C-cc. セッションが終了するまで2秒間待機します。 d. 必要に応じて、tmux kill-session -t "{session_id}"で強制終了します。 state_clear(mode="omc-teams")を呼び出します。- 構造化キャンセルレポートを出力します。
実装上の注意:
- 常に状態ツールを使用してチームが
omc-teamsモードかネイティブteamモードかを検出します - 間違ったクリーンアップロジックを適用しないでください。omc-teamsはtmuxシグナリングでクリーンアップし、ネイティブチームは会話サーフェスメッセージングを使用します
- omc-teamsの状態設定はネイティブチーム状態設定とは異なります
レガシー状態クリーンアップの詳細
--forceまたは--allが渡された場合、レガシーファイルチェックは、アクティブなセッションがない場合、または状態ツールが利用できない場合にのみ、これらのファイルを削除します:
比較的高い精度でこれらのファイルの存在を検出するには:
# レガシーファイルが存在するかどうかのチェック(これは状態検出に代わるものではありません)
ls "$OMC_STATE_DIR"/*.json 2>/dev/null | head -5
ls "$OMC_STATE_DIR"/swarm*.db* 2>/dev/null | head -5
トラブルシューティング
問題: 状態ツールが利用できません
ToolSearchを使用してすべての状態ツールをロードし、それでも失敗する場合は、上記のbashフォールバックを使用します。
問題: セッションIDが不明です
state_list_activeがセッションを報告しない場合は、環境変数を使用します:
${CLAUDE_SESSION_ID:-${CLAUDECODE_SESSION_ID:-}}
問題: オートパイロットの再開が機能しません
上記の手順に従って、state_writeが正確なワークフロー実行IDで呼び出されていることを確認します。
問題: チームメイトがシャットダウンに応答しません
応答のないチームメイトを報告し、手動確認を提案します。15秒のタイムアウト後、スキルは先に進みます。
問題: キャンセルがスタックしました
--forceを使用して再試行するか、bashフォールバックを使用して脱出します。