feat(desktop): arrow up/down history navigation in composer#39088
Closed
naqerl wants to merge 1 commit into
Closed
feat(desktop): arrow up/down history navigation in composer#39088naqerl wants to merge 1 commit into
naqerl wants to merge 1 commit into
Conversation
This was referenced Jun 6, 2026
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds ArrowUp/ArrowDown history navigation to the desktop composer's input. Pressing ArrowUp on an empty composer (or while already browsing) cycles backward through previously sent messages in the current session. ArrowDown cycles forward, restoring the original draft when reaching the "present". Stops at the oldest entry.
The user-text ring is derived from the live session messages on every press — no mirror, no seeding, no dedup. Single source of truth:
$messages. The store only persists the per-session cursor and the saved draft.Why derive instead of mirror: the previous mirror-based approach (push on submit, push on queue drain, push on voice submit) repeatedly fell out of sync with
$messages— different paths used different session-id keys, the seed-on-first-press logic could push duplicates in the wrong order, and switching sessions required explicit cleanup. Deriving from$messageson every press eliminates the entire class of bugs by construction.Related Issue
Fixes #38916
Type of Change
Changes Made
apps/desktop/src/store/composer-input-history.ts(new, 158 lines) —deriveUserHistory,browseBackward,browseForward,resetBrowseState,isBrowsingHistory. Per-sessioncursor+draftSnapshotonly; ring is computed lazily by the caller.apps/desktop/src/store/composer-input-history.test.ts(new, 187 lines, 11 tests) — covers derivation, both browse directions, per-session isolation, mid-browse history changes (proves no mirror), session-switch reset.apps/desktop/src/app/chat/composer/index.tsx(+81 lines) — imports the new store, subscribes to$messagesassessionMessages, adds a session-switch effect that resets the cursor, adds ArrowUp handler (with reordered guard:draft.trim() && !isBrowsingHistory(sessionId)returns early) and ArrowDown handler, callsresetBrowseState(sessionId)at the three submit sites (queue drain, regular submit, voice submit) so a new submit starts Arrow Up fresh.How to Test
$messages).Run unit tests:
Checklist
Code
feat(desktop): arrow up/down to navigate previous user messages)Documentation & Housekeeping
Screenshots / Logs