Recall previously-sent prompts in the composer with the Up / Down arrows#53
Open
DragonnZhang wants to merge 1 commit into
Open
Recall previously-sent prompts in the composer with the Up / Down arrows#53DragonnZhang wants to merge 1 commit into
DragonnZhang wants to merge 1 commit into
Conversation
Recall previously-sent prompts in the chat composer, shell-style: - Up in an empty (or already-recalling) composer walks history newest->oldest - Down walks newer again and restores the original draft past the newest entry - edit / submit / session-switch exit recall mode; drafts keep normal caret nav Sent prompts are persisted globally in localStorage (craft-prompt-history), trimmed, immediate-duplicate-collapsed, capped at 100. The navigation model is a pure, unit-tested module (prompt-history.ts). No new i18n keys. Adds a data-testid on the composer input and a CDP assertion driving Up/Down in the draft state. Closes #52
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.
Closes #52
What & why
Terminal shells, the Claude Code CLI, and the Codex desktop composer all
let you recall a prompt you already sent by pressing Up in the composer.
OpenWork's composer (
FreeFormInput) had no prompt history: once a messagewas sent it was gone from the input, so re-running or tweaking a previous prompt
meant retyping it or copying it back out of the transcript. Outside the inline
mention / slash / label menus,
ArrowUp/ArrowDownin the composer only movedthe caret.
This adds shell-style prompt history recall:
persisted in
localStorage(craft-prompt-history), trimmed, with immediateduplicate collapse, capped at 100 entries.
(newest → oldest), clamping at the oldest.
restores the draft you started from and exits recall.
Up/Downkeep normalcaret-movement — recall never hijacks editing.
Frontend-only. No backend / qwen-code change. Recall drives the existing
controlled
valueprop (the same path@mentionselection already uses), andpersistence reuses the existing
lib/local-storage.tshelper. No new i18n keys.Changes
components/app-shell/input/prompt-history.ts(new) — pure, DOM-free historymodel:
pushPromptHistory(trim / immediate-repeat collapse / cap),prevPromptIndex/nextPromptIndex/promptAt(index-based Up/Downnavigation), and
getPromptHistory/recordPrompt(localStorage round-trip).components/app-shell/input/FreeFormInput.tsx— history refs, anapplyRecalledPrompthelper (drivessetInput+ caret), theArrowUp/ArrowDownbranch in
handleKeyDown, recall capture insubmitMessage, reset on real edit(
handleInputChange) and on session switch, anddata-testid="composer-input"on the composer for e2e.
lib/local-storage.ts— newpromptHistorykey (craft-prompt-history).components/app-shell/input/__tests__/prompt-history.test.ts(new) — 20 unittests for the module.
e2e/assertions/prompt-history.assert.ts(new) — CDP assertion (below).Verification (DoD)
bun run typecheck:all— zero new errors.packages/{core,shared,server-core,server,session-tools-core}pass clean;
packages/uipasses clean (checked independently); the only errorsare the 11 pre-existing ones in
apps/electron(auto-update.tsowner/repo,a
settings-default-thinkingtest tuple, two test files importingvitest) —none in the files this PR touches.
bun test— the set of failing tests is byte-for-byte identical tomain,verified by diffing the sorted, timing-stripped failure lists from a clean-
mainrun and this branch in the same environment: 56 pre-existing failures on
both (
BrowserCDP, RPC handler profiles,RoutedClient,startWebuiHttpServer,the i18n sorted checks,
resource-bundle, …). This change adds zero newfailures, and adds 20 new passing unit tests (
prompt-history.test.ts). (Theraw
N failtotal is order-dependent when the whole suite runs unisolated; thedeterministic signal is the failing-test set, which is unchanged.)
bun run build:renderer, where this change lives) — ✅ buildscleanly.
bun build e2e/assertions/prompt-history.assert.ts) — ✅.CDP e2e assertion (
prompt-history.assert.ts)Drives the real built app over CDP entirely in the draft (no-session) state — no
seeded conversation and no backend. The composer reads its history fresh from
localStorage, so the assertion seeds three prior prompts there and walks them:localStorage['craft-prompt-history'] = ['alpha one','beta two','gamma three'].ArrowUprecalls the newest (gamma three); further Ups recallbeta two,alpha one, and clamp at the oldest.ArrowDownwalks newer again (beta two,gamma three) and, once past thenewest, restores the original empty draft.
Reading the composer's actual text after each keypress proves the arrows really
change the composer contents, not merely toggle state.
Part of the autonomous desktop-feature loop (
loop-bot).Generated by Claude Code