8.4 KiB
CLI Agent Composer Auto-Show & Auto-Dismiss — Tech Spec
Problem
The PRODUCT.md spec requires three new settings that control the visibility lifecycle of the CLI agent rich input composer. The implementation spans settings definitions, the settings UI, the session model, and the terminal view's subscription to CLI agent session status changes.
Relevant Code
app/src/settings/ai.rs (492–1144)—AISettingsgroup where new settings will be added, near the existingshould_render_cli_agent_footersetting.app/src/settings_view/ai_page.rs (4949–5067)—CLIAgentWidgetthat renders the "Coding Agents" section in Settings > AI.app/src/terminal/cli_agent_sessions/mod.rs—CLIAgentSessionsModelsingleton,CLIAgentSession,CLIAgentSessionStatus,CLIAgentInputState.app/src/terminal/view.rs:10802—handle_cli_agent_sessions_event()which reacts toCLIAgentSessionsModelEvent::StatusChanged.app/src/terminal/view/use_agent_footer/mod.rs:486–524—submit_cli_agent_rich_input()which currently always closes the composer after submission.app/src/terminal/view/use_agent_footer/mod.rs:527–574—open_cli_agent_rich_input()which opens the composer.
Current State
- The composer is opened manually via Ctrl-G or the footer button (
open_cli_agent_rich_input). - After the user submits a prompt,
submit_cli_agent_rich_inputalways callsclose_cli_agent_rich_input. handle_cli_agent_sessions_eventonly handlesStatusChangedfor desktop notifications when the user is navigated away — it does not drive any composer visibility logic.- The
CLIAgentSessionstruct has alistener: Option<ModelHandle<CLIAgentSessionListener>>field that indicates whether the plugin is connected.
Proposed Changes
1. New settings in AISettings (settings/ai.rs)
Add three new boolean settings inside the define_settings_group!(AISettings, ...) block, placed after should_render_cli_agent_footer:
auto_toggle_composer(AutoToggleComposer): defaulttrue. Auto-hides the composer onBlockedand auto-shows onInProgress/Success, gated on plugin presence and the per-sessionshould_auto_toggle_inputflag.auto_open_composer_on_cli_agent_start(AutoOpenComposerOnCLIAgentStart): defaultfalse. Auto-opens the composer when a session is created or a plugin listener is registered. Also sets the session's initialshould_auto_toggle_inputflag.auto_dismiss_composer_after_submit(AutoDismissComposerAfterSubmit): defaultfalse. Auto-closes the composer after prompt submission, only when Setting 1 is not actively managing visibility.
2. Settings UI (settings_view/ai_page.rs)
Extend CLIAgentWidget to include two new SwitchStateHandle fields and render two new toggles inside the "Coding Agents" section, gated on is_footer_enabled:
- Setting 1 toggle: Label "Auto show/hide composer based on agent status" with an
AdditionalInfoinfo tooltip saying "Requires the Warp plugin for your coding agent". - Setting 2 toggle: Label "Auto dismiss composer after prompt submission" with a description explaining the behavior.
Add corresponding AISettingsPageAction variants (ToggleAutoToggleComposer, ToggleAutoDismissComposerAfterSubmit) and wire them to the settings.
3. Per-session should_auto_toggle_input flag (cli_agent_sessions/mod.rs)
Add a should_auto_toggle_input: bool field to CLIAgentSession. This flag controls whether auto-toggle is active for a given session:
- Initialized from
*AISettings::as_ref(ctx).auto_open_composer_on_cli_agent_startwhen the session is created or a listener is registered. - Set to
truewhenever the composer is opened (viaopen_input, which always passestrue). - Set to
falsewhen the user manually dismisses the composer (close_cli_agent_rich_input_and_disable_auto_toggle→close_inputwithfalse). - Preserved as
truewhen auto-close fires on Blocked (close_cli_agent_rich_input→close_inputwithtrue).
Threaded through register_listener, open_input, and close_input as a parameter.
4. Auto-show/hide on status changes (terminal/view.rs)
Extend handle_cli_agent_sessions_event to react to StatusChanged for the current terminal view (not just notifications). When all conditions are met:
auto_toggle_composeris enabled- The session has a plugin listener and
should_auto_toggle_inputistrue - AI is enabled and the CLI agent toolbar is enabled
Then:
- On transition to
Blocked: callclose_cli_agent_rich_input(preservesshould_auto_toggle_input = true). - On transition to
InProgressorSuccess: callopen_cli_agent_rich_input(AutoShow)if the composer isn't already open.
Additionally, maybe_auto_open_cli_agent_composer is called after session creation and listener registration to handle the auto-open-on-start setting.
5. Conditional close after submission (terminal/view/use_agent_footer/mod.rs)
A shared maybe_close_composer_after_submit method encapsulates the conditional close logic, called from both the synchronous path and the DelayedEnter timer callback in write_cli_agent_text_then_submit. It checks has_plugin (plugin present AND should_auto_toggle_input) and auto_toggle_composer to decide whether status events manage visibility or auto_dismiss_composer_after_submit should close the composer.
6. Close variants (terminal/view/use_agent_footer/mod.rs)
close_cli_agent_rich_input: delegates toclose_cli_agent_rich_input_impl(true)— preservesshould_auto_toggle_inputfor auto-close on Blocked.close_cli_agent_rich_input_and_disable_auto_toggle: delegates toclose_cli_agent_rich_input_impl(false)— disables auto-toggle when the user manually dismisses.
All manual close call sites (Escape, Ctrl-G toggle, footer button toggle, footer hide, block completion) use the _and_disable_auto_toggle variant.
7. New CLIAgentInputEntrypoint::AutoShow variant
Added to cli_agent_sessions/mod.rs to distinguish auto-opens from manual opens in telemetry.
End-to-End Flow
Auto-open on session start (Setting 2 enabled):
- CLI agent command detected → session created with
should_auto_toggle_input = true. maybe_auto_open_cli_agent_composerfires → composer opens viaAutoShowentrypoint.
Auto-hide on blocked, auto-show on resume (Setting 1 enabled, plugin present):
- CLI agent runs and enters
PermissionRequest→CLIAgentSession::apply_eventsets status toBlocked. CLIAgentSessionsModelemitsStatusChanged { status: Blocked }.TerminalView::handle_cli_agent_sessions_eventchecks: setting on, plugin present,should_auto_toggle_inputtrue → callsclose_cli_agent_rich_input(preserves flag).- User interacts directly with the terminal (e.g., approves permission).
- Agent resumes → status changes to
InProgress→ handler callsopen_cli_agent_rich_input(AutoShow).
Manual dismiss breaks auto-toggle cycle:
- During auto-toggle, user presses Escape →
close_cli_agent_rich_input_and_disable_auto_togglesetsshould_auto_toggle_input = false. - Subsequent status changes no longer trigger auto-open/close for this session.
- User manually re-opens with Ctrl-G →
open_inputsetsshould_auto_toggle_input = true→ auto-toggle resumes.
Auto-dismiss on submit (Setting 3 enabled, no plugin):
- User manually opens composer with Ctrl-G.
- User submits text →
maybe_close_composer_after_submitchecks: no plugin (orshould_auto_toggle_inputfalse), setting 3 is on → closes the composer.
Risks and Mitigations
- Flicker from rapid status transitions: If a CLI agent rapidly transitions Blocked→InProgress→Blocked, the composer could flicker open/close. Mitigation: unlikely in practice since permission requests have user-gated responses. Can add a debounce later if needed.
- Race with manual open: If the user manually opens the composer just before auto-close fires, it could feel jarring. Mitigation: the auto-close only fires on status transitions, not on a timer, so it maps to genuine agent state.
Testing and Validation
- Add unit tests in
cli_agent_sessions/mod_tests.rsverifying thatStatusChangedevents propagate correctly. - Add integration test scenarios exercising auto-show on blocked and auto-dismiss on submit.
- Manual testing with and without the plugin to verify both settings behave correctly.
Follow-ups
- Add telemetry for auto-show/auto-dismiss to track adoption.
- Consider debounce/delay on auto-show if rapid transitions prove to be an issue.