feat(tui): expose slash commands as hotbar actions#3269
Conversation
Register built-in slash commands under slash.<name> hotbar action IDs. Arg-less and optional-arg commands dispatch through the existing slash command path, while commands with required args prefill the composer for completion. Refs Hmbown#2067 Part of Hmbown#2061
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
There was a problem hiding this comment.
Code Review
This pull request introduces the ability to bind slash commands to hotbar slots (e.g., slash.<name>). It adds a helper method to determine if a command requires arguments, registers slash commands as hotbar actions, and implements the dispatch logic. If a slash command requires arguments, it pre-fills the composer; otherwise, it executes the command immediately. Documentation and unit tests are also added to support this feature. I have no feedback to provide as there are no review comments.
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.
Hmbown
left a comment
There was a problem hiding this comment.
The action surface is sane — approving.
What I verified:
- ** bracket-depth parser** is the right call and improves on the existing naive
requires_argument()(which just checkscontains('<')). It correctly handles the nested usage strings:/queue [list|send <n>|...]→false(the<n>is inside[], so the whole arg is optional),/agent [N] <task>→true(<task>at depth 0),/mode [agent|plan|...]→false. This is the genuinely clever piece and it's correct. - API surface matches the branch:
commands::command_infos()returnsVec<&'static CommandInfo>so the&'static CommandInfofield is sound;commands::execute,clear_input_recoverable,CommandResult { action: Option<AppAction> }all exist as used. - No id-namespace collision — the
slash.prefix is unused in the existing hotbar registry. is_active() = falseis correct for slash actions: they have no toggle/highlight state (unlikemode.agent), so the button correctly never highlights as active.- Required-arg prefill path (
/rename) clears the draft recoverably and seeds/renamein the composer — the test covers the undo buffer and status message. Argless/optional-arg commands dispatch through the samecommands::executepath as typing them manually.
Full CI matrix green (ubuntu/macos/windows + lint + mobile smoke). reidliu41 is in AUTHOR_MAP. The unchecked --workspace box in the PR body is moot — the CI matrix already runs the workspace suite. Merging.
Hmbown
left a comment
There was a problem hiding this comment.
The action surface is sane — approving.
What I verified:
requires_required_argument()bracket-depth parser is the right call and improves on the existing naiverequires_argument()(which just checkscontains('<')). It correctly handles the nested usage strings:/queue [list|send <n>|...]→false(the<n>is inside[], so the whole arg is optional),/agent [N] <task>→true(<task>at depth 0),/mode [agent|plan|...]→false. This is the genuinely clever piece and it's correct.- API surface matches the branch:
commands::command_infos()returnsVec<&'static CommandInfo>so the&'static CommandInfofield is sound;commands::execute,clear_input_recoverable,CommandResult { action: Option<AppAction> }all exist as used. - No id-namespace collision — the
slash.prefix is unused in the existing hotbar registry. is_active() = falseis correct for slash actions: they have no toggle/highlight state (unlikemode.agent), so the button correctly never highlights as active.- Required-arg prefill path (
/rename) clears the draft recoverably and seeds/renamein the composer — the test covers the undo buffer and status message. Argless/optional-arg commands dispatch through the samecommands::executepath as typing them manually.
Full CI matrix green (ubuntu/macos/windows + lint + mobile smoke). reidliu41 is in AUTHOR_MAP. The unchecked --workspace box in the PR body is moot — the CI matrix already runs the workspace suite. Merging.
Summary
Refs #2067
Part of #2061
This adds the slash-command source adapter for the Hotbar.
The Hotbar can now bind existing slash commands as
slash.<name>actions, for example:slash.modeslash.taskslash.renameArg-less and optional-arg commands run through the same slash-command dispatch path as typing the command manually.
Commands with required arguments do not run incomplete; they prefill the composer with the command and a trailing space so
the user can finish the input.
Also updates
config.example.tomlwith aslash.modebinding example.Testing
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-featurescargo test --workspace --all-featuresChecklist