fix(tui): make provider key replacement discoverable#2717
Conversation
|
Thanks @xyuai for taking the time to contribute. This repository is currently observing a maintainer-managed contribution gate in dry-run mode, so this pull request is staying open. When enforcement is enabled, pull requests from contributors who are not listed in Please read |
There was a problem hiding this comment.
Code Review
This pull request introduces the ability to edit or replace a provider's API key inline by pressing the r key in the provider picker modal. It adds helper methods, updates the footer UI to display the new shortcut, and includes corresponding unit tests. Feedback suggests ensuring that the r key handler explicitly checks for active modifier keys (like Ctrl or Alt) to prevent conflicts with global shortcuts.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| KeyCode::Char(c) if c.eq_ignore_ascii_case(&'r') => { | ||
| self.enter_key_entry(); | ||
| ViewAction::None | ||
| } |
There was a problem hiding this comment.
The key handler for Stage::List transitions to the key entry stage when the r key is pressed, but it does not check if any modifier keys are active. This can lead to accidental triggering of the inline edit flow when global shortcuts like Ctrl+R (Session Picker) or Alt+R (Search History) are pressed while the modal is open. We should ensure that no modifiers like CONTROL or ALT are active.
KeyCode::Char(c) if c.eq_ignore_ascii_case(&'r') && !key.modifiers.intersects(KeyModifiers::CONTROL | KeyModifiers::ALT) => {
self.enter_key_entry();
ViewAction::None
}| let enter_action = if self.selected_has_key() { | ||
| "apply" | ||
| } else { | ||
| "set key" | ||
| }; |
There was a problem hiding this comment.
The
enter_action label is derived from selected_has_key() alone, but the Enter handler has a third branch: when Moonshot is selected with Kimi CLI OAuth credentials present but no explicit API key, Enter emits ProviderPickerKimiOAuthEnabled — it does not go to key-entry. In that state the footer will say "Enter set key", which is incorrect and could confuse users expecting the OAuth activation path.
| let enter_action = if self.selected_has_key() { | |
| "apply" | |
| } else { | |
| "set key" | |
| }; | |
| let enter_action = if self.selected_has_key() { | |
| "apply" | |
| } else if self.selected_provider() == ApiProvider::Moonshot | |
| && kimi_cli_credentials_present() | |
| { | |
| "oauth" | |
| } else { | |
| "set key" | |
| }; |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| #[test] | ||
| fn configured_provider_can_reenter_key_entry_with_r() { | ||
| let config = Config { | ||
| providers: Some(crate::config::ProvidersConfig { | ||
| xiaomi_mimo: crate::config::ProviderConfig { | ||
| api_key: Some("mimo-key".to_string()), | ||
| ..Default::default() | ||
| }, | ||
| ..Default::default() | ||
| }), | ||
| ..Config::default() | ||
| }; | ||
| let mut picker = ProviderPickerView::new(ApiProvider::Deepseek, &config); | ||
| move_to_provider(&mut picker, ApiProvider::XiaomiMimo); | ||
|
|
||
| let action = picker.handle_key(key(KeyCode::Char('r'))); | ||
|
|
||
| assert!(matches!(action, ViewAction::None)); | ||
| assert_eq!(picker.stage, Stage::KeyEntry); | ||
| assert!(picker.api_key_input.is_empty()); | ||
| } |
There was a problem hiding this comment.
r shortcut not tested for Moonshot + Kimi OAuth path
The new test covers r on a configured provider (XiaomiMimo with an API key) and the Enter-key OAuth branch is unchanged, but there is no test for pressing r when Moonshot is selected and kimi_cli_credentials_present() is true. In that case r bypasses the OAuth flow entirely and drops the user into key-entry — a distinct behaviour from what Enter does in the same selection state. A test covering this divergence would help catch any future regression.
- add r/R shortcut to re-enter API key for any provider in picker - guard against Ctrl/Alt/Meta modifiers (only plain r triggers) - dynamic footer: 'apply' when key exists, 'set key' otherwise - add 'R edit key' hint to picker footer - add route/model to scoped auth status output - add tests for r shortcut, ctrl-r guard, footer text, and route/model Ports #2717 with review fix. Fixes #2662.
|
Ported to codex/v0.8.53 in be7a3e7 with review fix: r shortcut now guards against Ctrl/Alt/Meta modifiers. |
Summary
rshortcut in the provider picker so configured providers can reopen API-key entry without leaving/providerFixes #2662.
Greptile Summary
This PR adds an
rshortcut in the provider picker's list stage so users can re-enter the API-key input for an already-configured provider without closing the modal, complemented by a dynamic footer hint that shows "apply" or "set key" depending on whether the selection has a key.enter_key_entry()and wires it toKeyCode::Char(c)matchingr/Rin the list stage.R edit keyhint.Confidence Score: 4/5
Safe to merge; all changes are confined to the provider picker UI and its unit tests, with no persistence logic touched.
The
rshortcut and refactoredenter_key_entry()helper are clean and well-tested for the common cases. The one gap is the dynamic footer label: it readsselected_has_key()to pick between "apply" and "set key", but the Enter handler has a third branch for Moonshot + Kimi CLI OAuth that neither of those labels describes accurately. In that specific state the footer says "Enter set key" while Enter actually activates OAuth, creating a misleading hint. This is a narrow edge case (Moonshot + Kimi CLI only), limited to UI text, and does not affect any persisted state or key-submission logic.crates/tui/src/tui/provider_picker.rs — the
enter_actionlabel logic nearrender_listline 162Important Files Changed
r-key shortcut and dynamic footer; theenter_actioncomputation is based solely onselected_has_key(), which produces a misleading "set key" hint for Moonshot when Kimi CLI OAuth is present but no API key is set (Enter triggers OAuth in that state, not key-entry).Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD List["Stage::List"] -->|"Enter (has key)"| Apply["EmitAndClose: ProviderPickerApplied"] List -->|"Enter (Moonshot + Kimi OAuth, no key)"| OAuth["EmitAndClose: ProviderPickerKimiOAuthEnabled"] List -->|"Enter (no key)"| KeyEntry["Stage::KeyEntry"] List -->|"r / R"| KeyEntry List -->|Esc| Close["ViewAction::Close"] KeyEntry -->|"Enter (non-empty input)"| Submit["EmitAndClose: ProviderPickerApiKeySubmitted"] KeyEntry -->|"Enter (empty input)"| KeyEntry KeyEntry -->|Esc| List KeyEntry -->|Backspace / Ctrl+H| KeyEntry KeyEntry -->|"Char (non-whitespace)"| KeyEntry Footer["Footer hint (render_list)"] -->|"selected_has_key() = true"| FApply["'Enter apply'"] Footer -->|"selected_has_key() = false"| FSetKey["'Enter set key'"] FSetKey -.->|"misleading when Moonshot + Kimi OAuth active"| OAuthReviews (1): Last reviewed commit: "feat(tui): let provider picker edit save..." | Re-trigger Greptile