🗂

Codex CLI 完全ガイド:スラッシュコマンド徹底解説

に公開

はじめに

Codex TUI では、スラッシュ(/)で始まる入力によって設定変更や状況確認を即座に行うことができます。本記事では、現在実装されているスラッシュコマンドとカスタムプロンプト機能をソースコードの参照箇所とともに詳しく解説します。

コマンド一覧は codex-rs/tui/src/slash_command.rsSlashCommand 列挙体に定義されています。ポップアップの表示順もこの列挙体の順番に従います(コメントに “DO NOT ALPHA-SORT!” とある通り)。


1. スラッシュコマンド一覧

コマンド 概要 (description() 参照) 主な処理/実装箇所 タスク実行中の可否 (available_during_task) 備考
/model モデルと Reasoning Effort を選択 chatwidget.rs:1097-1120open_model_popup()。選択結果は Op::OverrideTurnContextUpdateModelPersistModelSelection を送信。 モデル候補は codex-rs/tui/src/model_presets.rs。認証モードに応じて選択肢が変化。
/approvals 承認ポリシーとサンドボックス権限を切替 chatwidget.rs:1113-1115open_approvals_popup() AskForApprovalSandboxPolicy を UI から変更し、次のターンで適用。
/review 現在の変更をレビュー chatwidget.rs:1107-1110open_review_popup() codex-rs/tui/src/review_popup.rs でレビュー対象を選択し、Codex にチェックを依頼。
/new 会話中に新しいチャットを開始 chatwidget.rs:1087-1089AppEvent::NewSession を発火。 現在の会話を終えて新しいセッションを開始。履歴は ~/.codex/sessions/ に保存。
/init AGENTS.md を生成 chatwidget.rs:1091-1094prompt_for_init_command.md のテンプレートを送信。 カスタム手順を Codex に伝える起点。初回プロジェクトの導入に最適。
/compact 会話履歴を要約してコンテキストを節約 chatwidget.rs:1096-1100Op::Compact 長時間のセッションでトークン消費を抑える。
/undo 直近のスナップショットを復元 chatwidget.rs:1127-1130undo_last_snapshot()restore_ghost_commit() BETA_FEATURE 環境変数が必要。Git リポジトリでのみ有効。
/diff Git diff(未追跡含む)を表示 chatwidget.rs:1131-1139 の非同期タスクで get_git_diff() を実行。 出力は履歴に挿入され、長い diff は pager 表示。
/mention @ を挿入してファイル参照補助 chatwidget.rs:1143-1145insert_str("@") ファイル検索 (@) と組み合わせて特定ファイルを提示。
/status セッション設定・トークン使用量を表示 chatwidget.rs:1147-1152status::new_status_output() サンドボックス範囲、承認ポリシー、トークン数、レートリミット情報をまとめて確認。
/mcp 登録済み MCP ツールの一覧 chatwidget.rs:1151-1170add_mcp_output()。MCP 未設定時は history_cell::empty_mcp_output() MCP 連携の確認やデバッグに活用。
/logout Codex からログアウト chatwidget.rs:1119-1123codex_core::auth::logout() 成功後に AppEvent::ExitRequest で終了。 ログアウト後は再起動・再ログインが必要。
/quit Codex を終了 chatwidget.rs:1117-1119AppEvent::ExitRequest Ctrl+C よりクリーンな終了手段。
/test-approval (デバッグ用)承認ダイアログのテスト chatwidget.rs:1153-1176debug_assertions ビルドのみ)。 通常ビルドでは無効。承認 UI の開発検証に使用。

2. 実装の流れと具体例

  1. 列挙体で定義codex-rs/tui/src/slash_command.rsSlashCommand にコマンド名・説明・タスク実行中の可否を定義。
  2. ポップアップに登録CommandPopup::new()codex-rs/tui/src/bottom_pane/command_popup.rs)が built_in_slash_commands() を呼び出し、コマンド一覧とカスタムプロンプトを並べて候補リストを構築。
  3. 入力補完:入力欄が / で始まると CommandPopup::on_composer_text_change() がファジーマッチで候補を絞り込みます。
  4. 実行ChatWidget::handle_slash_command()codex-rs/tui/src/chatwidget.rs:1080 付近)で SlashCommand の各変種に対応した処理を発動。

実装例:/model

// chatwidget.rs(抜粋)
SlashCommand::Model => {
    self.open_model_popup();
}

fn open_model_popup(&mut self) {
    let presets: Vec<ModelPreset> = builtin_model_presets(auth_mode);
    let mut items: Vec<SelectionItem> = Vec::new();
    for preset in presets {
        // …中略… モデル切替の AppEvent を送信
        let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
            tx.send(AppEvent::CodexOp(Op::OverrideTurnContext {
                model: Some(model_slug.clone()),
                effort: Some(effort),
                // …
            }));
            tx.send(AppEvent::UpdateModel(model_slug.clone()));
            tx.send(AppEvent::PersistModelSelection { model: model_slug.clone(), effort });
        })];
        items.push(SelectionItem { name, description, is_current, actions });
    }
    self.bottom_pane.show_selection_popup(items);
}

実装例:/mcp

SlashCommand::Mcp => {
    self.add_mcp_output();
}

pub(crate) fn add_mcp_output(&mut self) {
    if self.config.mcp_servers.is_empty() {
        self.add_to_history(history_cell::empty_mcp_output());
    } else {
        self.submit_op(Op::ListMcpTools);
    }
}

実装例:/diff

SlashCommand::Diff => {
    self.add_diff_in_progress();
    let tx = self.app_event_tx.clone();
    tokio::spawn(async move {
        let text = match get_git_diff().await {
            Ok((is_git_repo, diff_text)) => {
                if is_git_repo { diff_text } else { "`/diff` — _not inside a git repository_".to_string() }
            }
            Err(e) => format!("Failed to compute diff: {e}"),
        };
        tx.send(AppEvent::DiffResult(text));
    });
}

3. カスタムプロンプトをスラッシュコマンドとして使う

ビルトインコマンドに加えて、prompts/<name>.md のようなファイルを配置するとカスタムプロンプトが /prompts:<name> として呼び出せます。

3.1 構成

  • Codex は ~/.codex/prompts/ と、作業ディレクトリの prompts/ サブフォルダを探索します。
  • 各ファイルは Markdown やプレーンテキストで、冒頭に簡単なメタ情報をコメントとして書くことも可能(必須ではありません)。
  • 読み込まれたファイルは codex-rs/protocol/src/custom_prompts.rsCustomPrompt 構造体で表されます。
    pub struct CustomPrompt {
        pub name: String,
        pub path: PathBuf,
        pub content: String,
        pub description: Option<String>,
        pub argument_hint: Option<String>,
    }
    
  • コマンドポップアップは built_in_slash_commands() とカスタムプロンプトをマージし、prompts:name の形式で表示します。
  • ビルトインと同名のプロンプトは無視される(command_popup.rsprompt_name_collision_with_builtin_is_ignored テスト参照)。

3.2 例:prompts/test-plan.md

# 自動テスト計画の出力テンプレート

以下の情報を箇条書きでまとめてください:
- 追加した / 修正した機能
- 単体テストでチェックすべき項目
- 手動テスト(UI/CLI)の観点

このファイルを prompts/test-plan.md に置くと、TUI で /prompts:test-plan と入力するだけでテンプレートを送信できます。複数のプロジェクトで共有したい場合は ~/.codex/prompts/ に配置しておくと便利です。

3.3 引数付きプロンプト

argument_hint を設定すると、プロンプトが引数を取ることを UI に示せます。たとえば以下の JSON メタ情報付きテンプレートを prompts/refactor.json として用意すると:

{
  "name": "refactor",
  "description": "既存コードをリファクタリングする際の指示",
  "argument_hint": "ファイルパスや関数名を入力してください"
}
---
対象コード:

Codex は argument_hint の内容をポップアップに表示し、ユーザーに入力を促します。フォーマットは content 部分に続けて Markdown を記述するだけで OK です(上記のように JSON メタ情報+--- 区切りを使うとわかりやすい)。

3.4 ベストプラクティス

  • 命名規則prompts:<name>/init などビルトインと重複しないように命名。ユニークな接頭辞を付けると検索しやすい。
  • 説明文description を書いておくとポップアップで用途が一目でわかる。JSON メタ情報を使うか、冒頭にコメントを残すなどの方法があります。
  • 引数ヒントargument_hint を設定すると、複数のカスタムプロンプトを運用する際に入力ミスが減ります。
  • 共有:チームで共通テンプレートを使う場合はリポジトリ内に prompts/ フォルダを置き、README に運用ルールを記載すると良いでしょう。

4. ユースケースと使いどころ

  • セッション管理/new/status を活用すると、複数の課題を順に処理する際に作業状況を把握しやすくなります。
  • 権限調整/approvals で権限を緩和しすぎないよう制御しつつ、必要な場面で一時的に解除。/diff/review で変更点の確認とリスク洗い出しをセットで実施。
  • MCP 連携確認/mcp を使って登録済みツールが認識されているかチェック。/status と組み合わせるとワークスペース範囲とトークン使用量も把握可能。
  • カスタムワークフロー/prompts:<name> を利用してプロジェクトごとの定型プロンプトを即座に展開。ドキュメント作成やテスト計画の定着に役立ちます。

5. まとめ

  • スラッシュコマンドは TUI 操作を効率化するショートカット。列挙体(slash_command.rs)と handle_slash_command の分岐を押さえることで挙動が把握できます。
  • /model/approvals/status/diff などは日常的に活躍。ベータ機能の /undo を試す際は BETA_FEATURE=1 を設定。
  • カスタムプロンプトを /prompts:<name> 形式で呼び出し、チーム独自のテンプレートを簡単に利用可能。description や argument_hint を活用すると UI も使いやすくなる。

今後のシリーズ記事では、コマンド実装を拡張する方法や独自のカスタムコマンドを追加する手順についても取り上げる予定です。

Discussion