mirror of
https://github.com/openai/codex.git
synced 2026-04-30 09:26:44 +00:00
TUI/Core: preserve duplicate skill/app mention selection across submit + resume (#10855)
## What changed
- In `codex-rs/core/src/skills/injection.rs`, we now honor explicit
`UserInput::Skill { name, path }` first, then fall back to text mentions
only when safe.
- In `codex-rs/tui/src/bottom_pane/chat_composer.rs`, mention selection
is now token-bound (selected mention is tied to the specific inserted
`$token`), and we snapshot bindings at submit time so selection is not
lost.
- In `codex-rs/tui/src/chatwidget.rs` and
`codex-rs/tui/src/bottom_pane/mod.rs`, submit/queue paths now consume
the submit-time mention snapshot (instead of rereading cleared composer
state).
- In `codex-rs/tui/src/mention_codec.rs` and
`codex-rs/tui/src/bottom_pane/chat_composer_history.rs`, history now
round-trips mention targets so resume restores the same selected
duplicate.
- In `codex-rs/tui/src/bottom_pane/skill_popup.rs` and
`codex-rs/tui/src/bottom_pane/chat_composer.rs`, duplicate labels are
normalized to `[Repo]` / `[App]`, app rows no longer show `Connected -`,
and description space is a bit wider.
<img width="550" height="163" alt="Screenshot 2026-02-05 at 9 56 56 PM"
src="https://github.com/user-attachments/assets/346a7eb2-a342-4a49-aec8-68dfec0c7d89"
/>
<img width="550" height="163" alt="Screenshot 2026-02-05 at 9 57 09 PM"
src="https://github.com/user-attachments/assets/5e04d9af-cccf-4932-98b3-c37183e445ed"
/>
## Before vs now
- Before: selecting a duplicate could still submit the default/repo
match, and resume could lose which duplicate was originally selected.
- Now: the exact selected target (skill path or app id) is preserved
through submit, queue/restore, and resume.
## Manual test
1. Build and run this branch locally:
- `cd /Users/daniels/code/codex/codex-rs`
- `cargo build -p codex-cli --bin codex`
- `./target/debug/codex`
2. Open mention picker with `$` and pick a duplicate entry (not the
first one).
3. Confirm duplicate UI:
- repo duplicate rows show `[Repo]`
- app duplicate rows show `[App]`
- app description does **not** start with `Connected -`
4. Submit the prompt, then press Up to restore draft and submit again.
Expected: it keeps the same selected duplicate target.
5. Use `/resume` to reopen the session and send again.
Expected: restored mention still resolves to the same duplicate target.
This commit is contained in:
@@ -3,6 +3,8 @@ use std::path::PathBuf;
|
||||
|
||||
use crate::app_event::AppEvent;
|
||||
use crate::app_event_sender::AppEventSender;
|
||||
use crate::bottom_pane::MentionBinding;
|
||||
use crate::mention_codec::decode_history_mentions;
|
||||
use codex_core::protocol::Op;
|
||||
use codex_protocol::user_input::TextElement;
|
||||
|
||||
@@ -11,6 +13,7 @@ pub(crate) struct HistoryEntry {
|
||||
pub(crate) text: String,
|
||||
pub(crate) text_elements: Vec<TextElement>,
|
||||
pub(crate) local_image_paths: Vec<PathBuf>,
|
||||
pub(crate) mention_bindings: Vec<MentionBinding>,
|
||||
}
|
||||
|
||||
impl HistoryEntry {
|
||||
@@ -19,14 +22,24 @@ impl HistoryEntry {
|
||||
text: String::new(),
|
||||
text_elements: Vec::new(),
|
||||
local_image_paths: Vec::new(),
|
||||
mention_bindings: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_text(text: String) -> Self {
|
||||
let decoded = decode_history_mentions(&text);
|
||||
Self {
|
||||
text,
|
||||
text: decoded.text,
|
||||
text_elements: Vec::new(),
|
||||
local_image_paths: Vec::new(),
|
||||
mention_bindings: decoded
|
||||
.mentions
|
||||
.into_iter()
|
||||
.map(|mention| MentionBinding {
|
||||
mention: mention.mention,
|
||||
path: mention.path,
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user