Skip to content

fix(tui): make provider key replacement discoverable#2717

Closed
xyuai wants to merge 1 commit into
Hmbown:mainfrom
xyuai:fix-2662-provider-picker-key-edit
Closed

fix(tui): make provider key replacement discoverable#2717
xyuai wants to merge 1 commit into
Hmbown:mainfrom
xyuai:fix-2662-provider-picker-key-edit

Conversation

@xyuai

@xyuai xyuai commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add an inline r shortcut in the provider picker so configured providers can reopen API-key entry without leaving /provider
  • update the picker footer to advertise the edit flow and show when Enter will apply vs set a key
  • add provider-picker regression tests for the new shortcut and footer hint

Fixes #2662.

Greptile Summary

This PR adds an r shortcut 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.

  • Extracts duplicated key-entry transition logic into enter_key_entry() and wires it to KeyCode::Char(c) matching r/R in the list stage.
  • Changes the footer's Enter label from the static "apply" to a dynamic "apply" / "set key" string, and adds a new R edit key hint.
  • Adds two regression tests covering the new shortcut and the updated footer text.

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 r shortcut and refactored enter_key_entry() helper are clean and well-tested for the common cases. The one gap is the dynamic footer label: it reads selected_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_action label logic near render_list line 162

Important Files Changed

Filename Overview
crates/tui/src/tui/provider_picker.rs Adds r-key shortcut and dynamic footer; the enter_action computation is based solely on selected_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"| OAuth
Loading

Fix All in Codex Fix All in Claude Code Fix All in Cursor

Reviews (1): Last reviewed commit: "feat(tui): let provider picker edit save..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

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 .github/APPROVED_CONTRIBUTORS will be closed automatically.

Please read CONTRIBUTING.md for the expected contribution shape. A maintainer can grant PR access by commenting /lgtm on a pull request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +377 to +380
KeyCode::Char(c) if c.eq_ignore_ascii_case(&'r') => {
self.enter_key_entry();
ViewAction::None
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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
                }

Comment on lines +162 to +166
let enter_action = if self.selected_has_key() {
"apply"
} else {
"set key"
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Suggested change
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!

Fix in Codex Fix in Claude Code Fix in Cursor

Comment on lines +559 to +579
#[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());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Fix in Codex Fix in Claude Code Fix in Cursor

Hmbown added a commit that referenced this pull request Jun 3, 2026
- 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.
@Hmbown

Hmbown commented Jun 3, 2026

Copy link
Copy Markdown
Owner

Ported to codex/v0.8.53 in be7a3e7 with review fix: r shortcut now guards against Ctrl/Alt/Meta modifiers.

@Hmbown Hmbown closed this Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

provider picker: API key replacement is not discoverable from provider management

2 participants