Remove resurrected /collab slash command (#22535)

## Summary
`/collab` was intentionally removed in
[#12012](https://github.com/openai/codex/pull/12012), but the
TUI/app-server migration accidentally brought that slash-command path
back. This restores the earlier product decision so the TUI no longer
advertises or dispatches `/collab`. This command was redundant because
it did the same thing as `/plan` but in a less-intuitive way.

## What Changed
- Remove `SlashCommand::Collab` from the TUI slash-command surface.
- Delete the picker and app-event plumbing that only existed to service
`/collab`.
- Remove obsolete TUI test coverage for the deleted picker flow.
This commit is contained in:
Eric Traut authored and GitHub committed 2026-05-13 15:40:37 -07:00
1 parent e6939e3969
commit efdcbba053
9 files changed
+2 -163

No files matched your search

@@ -213,51 +213,6 @@ impl ChatWidget {
});
}
pub(crate) fn open_collaboration_modes_popup(&mut self) {
let presets = collaboration_modes::presets_for_tui(self.model_catalog.as_ref());
if presets.is_empty() {
self.add_info_message(
"No collaboration modes are available right now.".to_string(),
/*hint*/ None,
);
return;
}
let current_kind = self
.active_collaboration_mask
.as_ref()
.and_then(|mask| mask.mode)
.or_else(|| {
collaboration_modes::default_mask(self.model_catalog.as_ref())
.and_then(|mask| mask.mode)
});
let items: Vec<SelectionItem> = presets
.into_iter()
.map(|mask| {
let name = mask.name.clone();
let is_current = current_kind == mask.mode;
let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
tx.send(AppEvent::UpdateCollaborationMode(mask.clone()));
})];
SelectionItem {
name,
is_current,
actions,
dismiss_on_select: true,
..Default::default()
}
})
.collect();
self.bottom_pane.show_selection_view(SelectionViewParams {
title: Some("Select Collaboration Mode".to_string()),
subtitle: Some("Pick a collaboration preset.".to_string()),
footer_hint: Some(standard_popup_hint_line()),
items,
..Default::default()
});
}
fn model_selection_actions(
model_for_action: String,
effort_for_action: Option<ReasoningEffortConfig>,
@@ -238,16 +238,6 @@ impl ChatWidget {
);
}
}
SlashCommand::Collab => {
if !self.collaboration_modes_enabled() {
self.add_info_message(
"Collaboration modes are disabled.".to_string(),
Some("Enable collaboration modes to use /collab.".to_string()),
);
return;
}
self.open_collaboration_modes_popup();
}
SlashCommand::Side => {
self.request_empty_side_conversation();
}
@@ -965,7 +955,6 @@ impl ChatWidget {
| SlashCommand::Personality
| SlashCommand::Plan
| SlashCommand::Goal
| SlashCommand::Collab
| SlashCommand::Side
| SlashCommand::Keymap
| SlashCommand::Agent
@@ -1367,63 +1367,6 @@ async fn mode_switch_surfaces_reasoning_change_notification_when_model_stays_sam
);
}
#[tokio::test]
async fn collab_slash_command_opens_picker_and_updates_mode() {
let (mut chat, mut rx, mut op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
chat.thread_id = Some(ThreadId::new());
chat.set_feature_enabled(Feature::CollaborationModes, /*enabled*/ true);
chat.dispatch_command(SlashCommand::Collab);
let popup = render_bottom_popup(&chat, /*width*/ 80);
assert!(
popup.contains("Select Collaboration Mode"),
"expected collaboration picker: {popup}"
);
chat.handle_key_event(KeyEvent::from(KeyCode::Enter));
let selected_mask = match rx.try_recv() {
Ok(AppEvent::UpdateCollaborationMode(mask)) => mask,
other => panic!("expected UpdateCollaborationMode event, got {other:?}"),
};
chat.set_collaboration_mask(selected_mask);
chat.bottom_pane
.set_composer_text("hello".to_string(), Vec::new(), Vec::new());
chat.handle_key_event(KeyEvent::from(KeyCode::Enter));
match next_submit_op(&mut op_rx) {
Op::UserTurn {
collaboration_mode:
Some(CollaborationMode {
mode: ModeKind::Default,
..
}),
personality: Some(Personality::Pragmatic),
..
} => {}
other => {
panic!("expected Op::UserTurn with code collab mode, got {other:?}")
}
}
chat.bottom_pane
.set_composer_text("follow up".to_string(), Vec::new(), Vec::new());
chat.handle_key_event(KeyEvent::from(KeyCode::Enter));
match next_submit_op(&mut op_rx) {
Op::UserTurn {
collaboration_mode:
Some(CollaborationMode {
mode: ModeKind::Default,
..
}),
personality: Some(Personality::Pragmatic),
..
} => {}
other => {
panic!("expected Op::UserTurn with code collab mode, got {other:?}")
}
}
}
#[tokio::test]
async fn plan_slash_command_switches_to_plan_mode() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;