| author | |
| committer | |
| log | 14bf3f6d1644a37029be58429e8f0138e1ceb743 |
| tree | d4ecd9d072c4f32e9931edeaa33afc88b7e1b7ee |
| parent | 09d13de4381925fa2a6dea74eff8185fa301e905 |
| signature | Signed by PGP key B5690EEEBB952194 |
Cmd+S opened the stash menu even when the composer was empty and only one prompt was stashed. It now restores that prompt directly, so repeated presses toggle between the draft and stash.
Multiple entries and images that are still saving open the menu. The stash badge still opens the menu.
Validation: 94 focused stash, shortcut, and attachment tests pass. Web typecheck and formatting pass. Targeted lint has no new warnings or errors. Browser checks were skipped at Theo's request.
Original implementation by Theo Browne. No code changes were needed during the takeover audit.
Audited with GPT-6 Astra (preview) in Codex.3 files changed, 16 insertions(+), 7 deletions(-)
apps/web/src/components/chat/ChatComposer.tsx+8-1| ... | ... | @@ -3336,7 +3336,13 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 3336 | 3336 | const images = [...composerImagesRef.current]; |
| 3337 | 3337 | const files = [...composerFilesRef.current]; |
| 3338 | 3338 | if (prompt.length === 0 && images.length === 0 && files.length === 0) { |
| 3339 | setIsStashMenuOpen((open) => !open); | |
| 3339 | const entries = usePromptStashStore.getState().entries; | |
| 3340 | const entry = entries.length === 1 ? entries[0] : undefined; | |
| 3341 | if (entry && !entry.pendingImageCount) { | |
| 3342 | await restoreStashEntry(entry); | |
| 3343 | } else { | |
| 3344 | setIsStashMenuOpen((open) => !open); | |
| 3345 | } | |
| 3340 | 3346 | return; |
| 3341 | 3347 | } |
| 3342 | 3348 | const stashedFiles: PersistedComposerFileAttachment[] = []; |
| ... | ... | @@ -3523,6 +3529,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) |
| 3523 | 3529 | finalizeStashEntryImages, |
| 3524 | 3530 | promptRef, |
| 3525 | 3531 | pulseStashBadge, |
| 3532 | restoreStashEntry, | |
| 3526 | 3533 | stashEntryToQueue, |
| 3527 | 3534 | ]); |
| 3528 | 3535 |
apps/web/src/components/chat/ComposerStashMenu.tsx+4-4| ... | ... | @@ -30,10 +30,10 @@ function stashEntrySnippet(entry: PromptStashEntry): string { |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | /** |
| 33 | * Attached banner listing the stashed prompts. Keyboard-first: opened by ⌘S on an | |
| 34 | * empty composer, navigated with arrows, restored with Enter, dismissed | |
| 35 | * with Escape. The listener runs capture-phase on window so it wins over | |
| 36 | * the Lexical editor's handlers while the menu is open. | |
| 33 | * Attached banner listing the stashed prompts. Opened by the stash badge or ⌘S | |
| 34 | * when the empty composer cannot restore a single entry. Navigated with arrows, | |
| 35 | * restored with Enter, dismissed with Escape. The listener runs capture-phase | |
| 36 | * on window so it wins over the Lexical editor's handlers while the menu is open. | |
| 37 | 37 | */ |
| 38 | 38 | export const ComposerStashMenu = memo(function ComposerStashMenu(props: { |
| 39 | 39 | entries: ReadonlyArray<PromptStashEntry>; |
docs/user/composer.md+4-2| ... | ... | @@ -182,8 +182,10 @@ open the stack. Interacting with the attached banner or composer does not open t |
| 182 | 182 | ## Prompt stash |
| 183 | 183 | |
| 184 | 184 | Use the default shortcut, `Cmd+S` on macOS or `Ctrl+S` on Windows and Linux, to stash the current |
| 185 | prompt and its attachments after all file uploads finish. Restore the entry later from the stash | |
| 186 | menu. Stashes that contain files must be restored in the environment where those files were | |
| 185 | prompt and its attachments after all file uploads finish. When the composer is empty and the stash | |
| 186 | has one entry, press the shortcut again to restore it. The shortcut opens the stash menu if there | |
| 187 | are multiple entries or the entry's images are still saving. You can also open the menu from the | |
| 188 | stash badge. Stashes that contain files must be restored in the environment where those files were | |
| 187 | 189 | uploaded. Stashed files stay uploaded on the server for 24 hours. If you restore an entry after |
| 188 | 190 | that, the file comes back with **Attach again** next to it. Attach the file again or remove it, then |
| 189 | 191 | send. |