authorgravatar for 73941998+UtkarshUsername@users.noreply.github.comUtkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com> 2026-08-29 04:47:04+05:30
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-29 04:47:04+05:30
logac3b2adf96e755580fc09e149b7c7eb057d0b282
treed6b637426f4e34fa8cd170c89bae190739387e40
parente898008959247befda6b5e6c40079cd6dee33cad
signature Signed by PGP key B5690EEEBB952194

fix(web): show the configured stash shortcut (#8437)

Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>

3 files changed, 32 insertions(+), 3 deletions(-)

apps/web/src/components/chat/ChatComposer.tsx+8-1
......@@ -90,7 +90,7 @@ import {
9090} from "../../lib/attachmentUploadState";
9191import { isCommandPaletteOpen } from "../../commandPaletteBus";
9292import { getTerminalFocusOwner } from "../../lib/terminalFocus";
93import { resolveShortcutCommand } from "../../keybindings";
93import { resolveShortcutCommand, shortcutLabelForCommand } from "../../keybindings";
9494import {
9595 type TerminalContextDraft,
9696 type TerminalContextSelection,
......@@ -3201,6 +3201,13 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
32013201 <ComposerCommandMenuLayer anchor={composerMenuAnchor}>
32023202 <ComposerStashMenu
32033203 entries={stashQueue}
3204 stashShortcutLabel={shortcutLabelForCommand(keybindings, "composer.stash", {
3205 context: {
3206 terminalFocus: false,
3207 terminalOpen,
3208 modelPickerOpen: false,
3209 },
3210 })}
32043211 onRestore={restoreStashEntry}
32053212 onDelete={deleteStashEntry}
32063213 onClose={() => setIsStashMenuOpen(false)}
apps/web/src/components/chat/ComposerStashMenu.test.tsx+18
......@@ -8,6 +8,7 @@ describe("ComposerStashMenu", () => {
88 const markup = renderToStaticMarkup(
99 <ComposerStashMenu
1010 entries={[]}
11 stashShortcutLabel="Ctrl+S"
1112 onRestore={() => {}}
1213 onDelete={() => {}}
1314 onClose={() => {}}
......@@ -20,6 +21,22 @@ describe("ComposerStashMenu", () => {
2021 expect(markup).toContain('aria-label="Close stash"');
2122 expect(markup).not.toContain("dropdown-glass");
2223 expect(markup).not.toContain("Stashed prompts");
24 expect(markup).toContain("Press Ctrl+S with a prompt in the composer to stash it.");
25 });
26
27 it("does not advertise a shortcut when stash is unbound", () => {
28 const markup = renderToStaticMarkup(
29 <ComposerStashMenu
30 entries={[]}
31 stashShortcutLabel={null}
32 onRestore={() => {}}
33 onDelete={() => {}}
34 onClose={() => {}}
35 />,
36 );
37
38 expect(markup).toContain("Nothing stashed yet.");
39 expect(markup).not.toContain("Press");
2340 });
2441
2542 it("shows saved image thumbnails and incomplete image states", () => {
......@@ -53,6 +70,7 @@ describe("ComposerStashMenu", () => {
5370 pendingImageCount: 1,
5471 },
5572 ]}
73 stashShortcutLabel="Ctrl+S"
5674 onRestore={() => {}}
5775 onDelete={() => {}}
5876 onClose={() => {}}
apps/web/src/components/chat/ComposerStashMenu.tsx+6-2
......@@ -31,11 +31,12 @@ function stashEntrySnippet(entry: PromptStashEntry): string {
3131 */
3232export const ComposerStashMenu = memo(function ComposerStashMenu(props: {
3333 entries: ReadonlyArray<PromptStashEntry>;
34 stashShortcutLabel: string | null;
3435 onRestore: (entry: PromptStashEntry) => void;
3536 onDelete: (entry: PromptStashEntry) => void;
3637 onClose: () => void;
3738}) {
38 const { entries, onRestore, onDelete, onClose } = props;
39 const { entries, stashShortcutLabel, onRestore, onDelete, onClose } = props;
3940 const drawerRef = useRef<HTMLDivElement>(null);
4041 const [highlightedId, setHighlightedId] = useState<string | null>(entries[0]?.id ?? null);
4142
......@@ -128,7 +129,10 @@ export const ComposerStashMenu = memo(function ComposerStashMenu(props: {
128129 <CommandGroup>
129130 {entries.length === 0 ? (
130131 <p className="px-3 py-1.5 text-secondary-label text-xs">
131 Nothing stashed yet. Press ⌘S with a prompt in the composer to stash it.
132 Nothing stashed yet.
133 {stashShortcutLabel
134 ? ` Press ${stashShortcutLabel} with a prompt in the composer to stash it.`
135 : null}
132136 </p>
133137 ) : (
134138 entries.map((entry) => (