a/ analytics note .jp

TECH · field log

Claude Code から Codex CLI を安定呼び出しする: companion.mjs から codex exec への移行ガイド

内部ディスパッチャに依存した不安定な Codex 連携を、公開 CLI の codex exec に移行して安定化する方法を実装コードと共に解説します。

· 5 min read · #Claude Code / #Codex / #CLI / #インフラ / #自動化 / #安定性 · AI-assisted · reviewed Share on X はてブ Zennにクロスポスト

Claude Code と Codex の連携で安定性が重要な理由

データアナリスト・データエンジニアがAIを業務に組み込む際、Claude Code から外部の Codex CLI を呼び出して複雑な実装タスクを自動化するパターンが増えています。しかし従来の companion.mjs(内部ディスパッチャ)直叩きは、プラグインのバージョンアップで容易に壊れる脆弱な設計でした。

この記事では、内部ディスパッチャ依存から公開 CLI への移行によって Claude→Codex 連携を安定化する手法を実装例と共に解説します。読者の皆様が同様のAI連携基盤を構築する際の参考になれば幸いです。

companion.mjs 直叩きの構造的問題

なぜ内部ディスパッチャは不安定なのか

従来の実装では、Claude Code の /implement スキルが codex-plugin-cc の内部ディスパッチャ companion.mjs を直接呼び出していました:

# 問題のあるパターン
node ~/.config/codex/plugins/codex-plugin-cc/companion.mjs task --prompt-file prompt.txt --json

この設計の問題点:

  1. パス解決の脆さ: find ~/.config/codex -name companion.mjs でプラグイン内部パスを逆算
  2. API の不安定性: Invalid request エラー(@openai/codex 0.45.0 の thread/start API 未対応)
  3. 実装の複雑性: storedJob.payload 展開、status --wait ポーリング等の内部仕様への依存
  4. 保守性の悪さ: プラグインのマイナーバージョンアップで容易に壊れる

症状と対症療法の限界

2026年4月8日に @openai/codex@0.118.0 への強制アップデートで Invalid request は解消しましたが、これは対症療法に過ぎません。根本原因は「抽象レベルの誤り」にあります。

解決策: codex exec への移行

公開 CLI が提供する安定性

codex exec は Codex の公式 CLI であり、非対話モード用に設計された安定したインターフェースです:

# 推奨パターン
cat prompt.txt | codex exec - --sandbox read-only

この設計の利点:

  1. パス解決: command -v codex で簡潔に解決
  2. API 安定性: 公開 CLI として後方互換性が保証される
  3. 実装の簡潔性: stdin パイプ + フォアグラウンド実行
  4. 保守性: プラグイン内部実装に依存しない

Before/After の比較

観点Before (companion.mjs)After (codex exec)
パス解決`find ~/.config/codex -name companion.mjs \grep -v node_modules`
Planner 呼び出しnode companion.mjs task --prompt-file X --json`cat X \
待機方式--backgroundstatus --wait --timeout-msフォアグラウンド実行
結果取得result --jsonstoredJob.payload 展開stdout に最終メッセージのみ
ファイル変更検知payload の touchedFilesgit diff --name-only HEAD

実装手順

1. パス解決の簡素化

# Before: 内部パス逆算
COMPANION_PATH=$(find ~/.config/codex -name "companion.mjs" | grep -v node_modules | head -1)
if [[ ! -f "$COMPANION_PATH" ]]; then
    echo "Error: companion.mjs not found"
    exit 1
fi

# After: 公開 CLI 確認
if ! command -v codex &> /dev/null; then
    echo "Error: codex CLI not found"
    exit 1
fi

2. Planner 呼び出しの変更

# Before: companion.mjs 直叩き
node "$COMPANION_PATH" task \\
    --prompt-file "$PROMPT_FILE" \\
    --json \\
    --background

# After: codex exec パイプ
cat "$PROMPT_FILE" | codex exec - --sandbox read-only

3. 結果処理の簡素化

# Before: payload 展開 + ポーリング
JOB_ID=$(node "$COMPANION_PATH" task --prompt-file "$PROMPT_FILE" --json --background | jq -r '.jobId')
node "$COMPANION_PATH" status --job-id "$JOB_ID" --wait --timeout-ms 600000
RESULT=$(node "$COMPANION_PATH" result --job-id "$JOB_ID" --json)
TOUCHED_FILES=$(echo "$RESULT" | jq -r '.storedJob.payload.touchedFiles[]?' 2>/dev/null || echo "")

# After: 直接実行 + git diff
cat "$PROMPT_FILE" | codex exec - --sandbox workspace-write
TOUCHED_FILES=$(git diff --name-only HEAD)

移行時の注意点

1. サンドボックス指定

codex exec では明示的にサンドボックスを指定する必要があります:

  • --sandbox read-only: 読み取り専用(分析・調査用)
  • --sandbox workspace-write: ワークスペース書き込み可(実装用)

2. Codex CLI のパス

一部の環境では /opt/homebrew/bin/codex を直接指定する必要があります:

# ~/.superset/bin/codex には --enable codex_hooks が自動付与される場合
CODEX_PATH="/opt/homebrew/bin/codex"
if [[ -x "$CODEX_PATH" ]]; then
    cat "$PROMPT_FILE" | "$CODEX_PATH" exec - --sandbox read-only
else
    cat "$PROMPT_FILE" | codex exec - --sandbox read-only
fi

3. 認証エラーのハンドリング

# codex exec は認証エラー時に自動的にエラーステータスを返す
if ! cat "$PROMPT_FILE" | codex exec - --sandbox read-only; then
    echo "Error: Codex execution failed (possibly authentication issue)"
    exit 1
fi

実装結果と効果

コード削減効果

この移行により、実装は約1/3に削減されました:

  • 変更規模: -224行 / +64行
  • 複雑度: 内部 API 依存の除去により大幅に簡素化

実際の適用事例

以下のリポジトリで移行が完了しています:

  1. analytics-note/signal-loop#32 — 2026-04-14 マージ完了
  2. analytics-note/external-signal#56 — 2026-04-14 マージ完了

両リポジトリで /implement スキルが codex exec 経由で正常動作することを確認済みです。

まとめ: AI 連携基盤の設計原則

今回の移行から得られる汎用的な教訓:

  1. 公開 API を優先する: 内部ディスパッチャより公開 CLI を使う
  2. 抽象レベルを正しく設定する: プラグイン内部実装に依存しない
  3. 症状ではなく原因を解決する: アップグレードで直っても構造的問題は残る
  4. git を活用する: プラグイン固有の payload より git diff を使う

これらの原則に従うことで、AI 連携基盤の長期安定性を確保できます。読者の皆様の環境でも、類似の内部 API 依存がないか見直してみることをお勧めします。

関連記事

F/ この記事の設計を反映しているプロダクト: FlowAgent

see →
an

analytics note — editor

AI とデータ分析の実装ログを毎週編集。設計判断と運用のつまずきを、再現できる形で残すことを大切にしています。