mirror of
https://github.com/openai/codex.git
synced 2026-11-01 08:16:54 +00:00
## Summary Adds a simple `/plan` slash command in the TUI that switches the active collaboration mode to Plan mode. The command is only available when the `collaboration_modes` feature is enabled. ## Changes - Add `plan_mask` helper in `codex-rs/tui/src/collaboration_modes.rs` - Add `SlashCommand::Plan` metadata in `codex-rs/tui/src/slash_command.rs` - Implement and hard-gate `/plan` dispatch in `codex-rs/tui/src/chatwidget.rs` - Hide `/plan` when collaboration modes are disabled in `codex-rs/tui/src/bottom_pane/slash_commands.rs` - Update command popup tests in `codex-rs/tui/src/bottom_pane/command_popup.rs` - Add a focused unit test for `/plan` in `codex-rs/tui/src/chatwidget/tests.rs` ## Behavior notes - `/plan` is now a no-op if `Feature::CollaborationModes` is disabled. - When enabled, `/plan` switches directly to Plan mode without opening the picker. ## Codex author `codex resume 019c05da-d7c3-7322-ae2c-3ca38d0ef702`
66 lines
2.0 KiB
Rust
66 lines
2.0 KiB
Rust
use codex_core::models_manager::manager::ModelsManager;
|
|
use codex_protocol::config_types::CollaborationModeMask;
|
|
use codex_protocol::config_types::ModeKind;
|
|
|
|
fn is_tui_mode(kind: ModeKind) -> bool {
|
|
matches!(kind, ModeKind::Plan | ModeKind::Code)
|
|
}
|
|
|
|
fn filtered_presets(models_manager: &ModelsManager) -> Vec<CollaborationModeMask> {
|
|
models_manager
|
|
.list_collaboration_modes()
|
|
.into_iter()
|
|
.filter(|mask| mask.mode.is_some_and(is_tui_mode))
|
|
.collect()
|
|
}
|
|
|
|
pub(crate) fn presets_for_tui(models_manager: &ModelsManager) -> Vec<CollaborationModeMask> {
|
|
filtered_presets(models_manager)
|
|
}
|
|
|
|
pub(crate) fn default_mask(models_manager: &ModelsManager) -> Option<CollaborationModeMask> {
|
|
let presets = filtered_presets(models_manager);
|
|
presets
|
|
.iter()
|
|
.find(|mask| mask.mode == Some(ModeKind::Code))
|
|
.cloned()
|
|
.or_else(|| presets.into_iter().next())
|
|
}
|
|
|
|
pub(crate) fn mask_for_kind(
|
|
models_manager: &ModelsManager,
|
|
kind: ModeKind,
|
|
) -> Option<CollaborationModeMask> {
|
|
if !is_tui_mode(kind) {
|
|
return None;
|
|
}
|
|
filtered_presets(models_manager)
|
|
.into_iter()
|
|
.find(|mask| mask.mode == Some(kind))
|
|
}
|
|
|
|
/// Cycle to the next collaboration mode preset in list order.
|
|
pub(crate) fn next_mask(
|
|
models_manager: &ModelsManager,
|
|
current: Option<&CollaborationModeMask>,
|
|
) -> Option<CollaborationModeMask> {
|
|
let presets = filtered_presets(models_manager);
|
|
if presets.is_empty() {
|
|
return None;
|
|
}
|
|
let current_kind = current.and_then(|mask| mask.mode);
|
|
let next_index = presets
|
|
.iter()
|
|
.position(|mask| mask.mode == current_kind)
|
|
.map_or(0, |idx| (idx + 1) % presets.len());
|
|
presets.get(next_index).cloned()
|
|
}
|
|
|
|
pub(crate) fn code_mask(models_manager: &ModelsManager) -> Option<CollaborationModeMask> {
|
|
mask_for_kind(models_manager, ModeKind::Code)
|
|
}
|
|
|
|
pub(crate) fn plan_mask(models_manager: &ModelsManager) -> Option<CollaborationModeMask> {
|
|
mask_for_kind(models_manager, ModeKind::Plan)
|
|
}
|