diff --git a/codex-rs/tui/src/bottom_pane/chat_composer.rs b/codex-rs/tui/src/bottom_pane/chat_composer.rs index c56105243..bf2eb1789 100644 --- a/codex-rs/tui/src/bottom_pane/chat_composer.rs +++ b/codex-rs/tui/src/bottom_pane/chat_composer.rs @@ -3579,8 +3579,7 @@ impl ChatComposer { insert_text: format!("${skill_name}"), search_terms, path: Some(skill.path_to_skills_md.to_string_lossy().into_owned()), - category_tag: (skill.scope == codex_protocol::protocol::SkillScope::Repo) - .then(|| "[Repo]".to_string()), + category_tag: Some("[Skill]".to_string()), }); } } @@ -3631,8 +3630,7 @@ impl ChatComposer { insert_text: format!("${plugin_name}"), search_terms, path: Some(format!("plugin://{}", plugin.config_name)), - category_tag: (!marketplace_name.is_empty()) - .then(|| format!("[{marketplace_name}]")), + category_tag: Some("[Plugin]".to_string()), }); } } @@ -3660,16 +3658,6 @@ impl ChatComposer { } } - let mut counts: HashMap = HashMap::new(); - for mention in &mentions { - *counts.entry(mention.insert_text.clone()).or_insert(0) += 1; - } - for mention in &mut mentions { - if counts.get(&mention.insert_text).copied().unwrap_or(0) <= 1 { - mention.category_tag = None; - } - } - mentions } @@ -5343,6 +5331,60 @@ mod tests { }); } + #[test] + fn mention_popup_type_prefixes_snapshot() { + snapshot_composer_state_with_width("mention_popup_type_prefixes", 72, false, |composer| { + composer.set_connectors_enabled(true); + composer.set_text_content("$goog".to_string(), Vec::new(), Vec::new()); + composer.set_skill_mentions(Some(vec![SkillMetadata { + name: "google-calendar-skill".to_string(), + description: "Find availability and plan event changes".to_string(), + short_description: None, + interface: Some(codex_core::skills::model::SkillInterface { + display_name: Some("Google Calendar".to_string()), + short_description: None, + icon_small: None, + icon_large: None, + brand_color: None, + default_prompt: None, + }), + dependencies: None, + policy: None, + permission_profile: None, + path_to_skills_md: PathBuf::from("/tmp/repo/google-calendar/SKILL.md"), + scope: codex_protocol::protocol::SkillScope::Repo, + }])); + composer.set_plugin_mentions(Some(vec![PluginCapabilitySummary { + config_name: "google-calendar@debug".to_string(), + display_name: "Google Calendar".to_string(), + description: Some( + "Connect Google Calendar for scheduling, availability, and event management." + .to_string(), + ), + has_skills: false, + mcp_server_names: vec!["google-calendar".to_string()], + app_connector_ids: Vec::new(), + }])); + composer.set_connector_mentions(Some(ConnectorsSnapshot { + connectors: vec![AppInfo { + id: "google_calendar".to_string(), + name: "Google Calendar".to_string(), + description: Some("Look up events and availability".to_string()), + logo_url: None, + logo_url_dark: None, + distribution_channel: None, + branding: None, + app_metadata: None, + labels: None, + install_url: Some("https://example.test/google-calendar".to_string()), + is_accessible: true, + is_enabled: true, + plugin_display_names: Vec::new(), + }], + })); + }); + } + #[test] fn set_connector_mentions_excludes_disabled_apps_from_mention_popup() { let (tx, _rx) = unbounded_channel::(); diff --git a/codex-rs/tui/src/bottom_pane/skill_popup.rs b/codex-rs/tui/src/bottom_pane/skill_popup.rs index c848bca9e..4e8a8ae6d 100644 --- a/codex-rs/tui/src/bottom_pane/skill_popup.rs +++ b/codex-rs/tui/src/bottom_pane/skill_popup.rs @@ -98,14 +98,26 @@ impl SkillPopup { .map(|(idx, indices, _score)| { let mention = &self.mentions[idx]; let name = truncate_text(&mention.display_name, MENTION_NAME_TRUNCATE_LEN); - let description = mention.description.clone().unwrap_or_default(); + let description = match ( + mention.category_tag.as_deref(), + mention.description.as_deref(), + ) { + (Some(tag), Some(description)) if !description.is_empty() => { + Some(format!("{tag} {description}")) + } + (Some(tag), _) => Some(tag.to_string()), + (None, Some(description)) if !description.is_empty() => { + Some(description.to_string()) + } + _ => None, + }; GenericDisplayRow { name, name_prefix_spans: Vec::new(), match_indices: indices, display_shortcut: None, - description: Some(description).filter(|desc| !desc.is_empty()), - category_tag: mention.category_tag.clone(), + description, + category_tag: None, is_disabled: false, disabled_reason: None, wrap_indent: None, diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__mention_popup_type_prefixes.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__mention_popup_type_prefixes.snap new file mode 100644 index 000000000..fec45981b --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__mention_popup_type_prefixes.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› $goog " +" " +" " +" Google Calendar [Skill] Find availability and plan event changes " +" Google Calendar [Plugin] Connect Google Calendar for scheduling, ava…" +" Google Calendar [App] Look up events and availability " +" " +" Press enter to insert or esc to close " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__plugin_mention_popup.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__plugin_mention_popup.snap index 636cf8881..e46bc96cf 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__plugin_mention_popup.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__chat_composer__tests__plugin_mention_popup.snap @@ -8,6 +8,6 @@ expression: terminal.backend() " " " " " " -" Sample Plugin Plugin that includes the Figma MCP server and Skills for common workflows " +" Sample Plugin [Plugin] Plugin that includes the Figma MCP server and Skills for common workflows " " " " Press enter to insert or esc to close "