From 3cd9ee5a735d709c51a92afd095c1d73dfed47bb Mon Sep 17 00:00:00 2001 From: usrnk1 <7547651+usrnk1@users.noreply.github.com> Date: Thu, 9 Jul 2026 07:39:55 +0200 Subject: [PATCH] feat(app): add composer add menu with draft-preserving commands (#35711) --- packages/app/src/components/prompt-input.tsx | 130 +++++++++++++++--- .../components/prompt-input/slash-popover.tsx | 18 +++ .../prompt-input/transient-state.ts | 6 + packages/app/src/i18n/ar.ts | 5 + packages/app/src/i18n/br.ts | 5 + packages/app/src/i18n/bs.ts | 5 + packages/app/src/i18n/da.ts | 5 + packages/app/src/i18n/de.ts | 5 + packages/app/src/i18n/en.ts | 5 + packages/app/src/i18n/es.ts | 5 + packages/app/src/i18n/fr.ts | 5 + packages/app/src/i18n/ja.ts | 5 + packages/app/src/i18n/ko.ts | 5 + packages/app/src/i18n/no.ts | 5 + packages/app/src/i18n/pl.ts | 5 + packages/app/src/i18n/ru.ts | 5 + packages/app/src/i18n/th.ts | 5 + packages/app/src/i18n/tr.ts | 5 + packages/app/src/i18n/uk.ts | 5 + packages/app/src/i18n/zh.ts | 5 + packages/app/src/i18n/zht.ts | 5 + .../prompt-transient-state.test.ts | 4 + 22 files changed, 228 insertions(+), 20 deletions(-) diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 75ec3b7be5..92aefd9717 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -520,7 +520,7 @@ export const PromptInput: Component = (props) => { const setMode = (mode: "normal" | "shell") => { setStore("mode", mode) - setStore("popover", null) + setStore({ popover: null, slashMenu: false, slashMenuQuery: "" }) requestAnimationFrame(() => editorRef?.focus()) } @@ -554,7 +554,7 @@ export const PromptInput: Component = (props) => { }, ]) - const closePopover = () => setStore("popover", null) + const closePopover = () => setStore({ popover: null, slashMenu: false, slashMenuQuery: "" }) const resetHistoryNavigation = (force = false) => { if (!force && (store.historyIndex < 0 || store.applyingHistory)) return @@ -800,17 +800,30 @@ export const PromptInput: Component = (props) => { const handleSlashSelect = (cmd: SlashCommand | undefined) => { if (!cmd) return + const menu = store.slashMenu closePopover() const images = imageAttachments() if (cmd.type === "custom") { const text = `/${cmd.trigger} ` + if (menu) { + editorRef.focus() + setCursorPosition(editorRef, 0) + addPart({ type: "text", content: text, start: 0, end: text.length }) + focusEditorEnd() + return + } setEditorText(text) prompt.set([{ type: "text", content: text, start: 0, end: text.length }, ...images], text.length) focusEditorEnd() return } + if (menu) { + command.trigger(cmd.id, "slash") + return + } + clearEditor() prompt.set([...DEFAULT_PROMPT, ...images], 0) command.trigger(cmd.id, "slash") @@ -1072,10 +1085,10 @@ export const PromptInput: Component = (props) => { if (atMatch) { atOnInput(atMatch[1]) - setStore("popover", "at") + setStore({ popover: "at", slashMenu: false, slashMenuQuery: "" }) } else if (slashMatch) { slashOnInput(slashMatch[1]) - setStore("popover", "slash") + setStore({ popover: "slash", slashMenu: false, slashMenuQuery: "" }) } else { closePopover() } @@ -1171,6 +1184,28 @@ export const PromptInput: Component = (props) => { return true } + const openCommands = () => { + const populated = prompt.dirty() || commentCount() > 0 + requestAnimationFrame(() => { + if (!populated) { + if (!addPart({ type: "text", content: "/", start: 0, end: 0 })) return + slashOnInput("") + setStore({ popover: "slash", slashMenu: false, slashMenuQuery: "" }) + return + } + slashOnInput("") + setStore({ popover: "slash", slashMenu: true, slashMenuQuery: "" }) + }) + } + + const openContext = () => { + requestAnimationFrame(() => { + if (!addPart({ type: "text", content: "@", start: 0, end: 0 })) return + atOnInput("") + setStore({ popover: "at", slashMenu: false, slashMenuQuery: "" }) + }) + } + const addToHistory = (prompt: Prompt, mode: "normal" | "shell") => { history.add(prompt, mode, mode === "shell" ? [] : historyComments()) } @@ -1199,7 +1234,7 @@ export const PromptInput: Component = (props) => { } setStore("mode", "normal") - setStore("popover", null) + closePopover() setStore("historyIndex", -1) setStore("savedPrompt", null) prompt.set(edit.prompt, promptLength(edit.prompt)) @@ -1286,7 +1321,10 @@ export const PromptInput: Component = (props) => { resetHistoryNavigation(true) }, setMode: (mode) => setStore("mode", mode), - setPopover: (popover) => setStore("popover", popover), + setPopover: (popover) => { + if (!popover) return closePopover() + setStore({ popover, slashMenu: false, slashMenuQuery: "" }) + }, newSessionWorktree: () => props.newSessionWorktree, onNewSessionWorktreeReset: props.onNewSessionWorktreeReset, shouldQueue: props.shouldQueue, @@ -1325,7 +1363,7 @@ export const PromptInput: Component = (props) => { const cursorPosition = getCursorPosition(editorRef) if (cursorPosition === 0) { setStore("mode", "shell") - setStore("popover", null) + closePopover() event.preventDefault() return } @@ -1460,6 +1498,29 @@ export const PromptInput: Component = (props) => { } } + const handleSlashMenuKeyDown = (event: KeyboardEvent) => { + if (event.key === "Escape") { + closePopover() + requestAnimationFrame(() => editorRef.focus()) + event.preventDefault() + return + } + + if (event.key === "Tab") { + selectPopoverActive() + event.preventDefault() + return + } + + const ctrl = event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey + const nav = event.key === "ArrowUp" || event.key === "ArrowDown" || event.key === "Enter" + const ctrlNav = ctrl && (event.key === "n" || event.key === "p") + if (!nav && !ctrlNav) return + slashOnKeyDown(event) + if (event.key === "ArrowUp" || event.key === "ArrowDown" || ctrlNav) scrollSlashActiveIntoView() + event.preventDefault() + } + const agentsLoading = () => props.controls.agents.loading const agentsShouldFadeIn = createMemo((prev) => prev ?? agentsLoading()) const providersLoading = () => props.controls.model.loading @@ -1527,6 +1588,13 @@ export const PromptInput: Component = (props) => { slashActive={slashActive() ?? undefined} setSlashActive={setSlashActive} onSlashSelect={handleSlashSelect} + slashMenu={store.slashMenu} + slashMenuQuery={store.slashMenuQuery} + onSlashMenuInput={(value) => { + setStore("slashMenuQuery", value) + slashOnInput(value) + }} + onSlashMenuKeyDown={handleSlashMenuKeyDown} commandKeybind={command.keybind} commandKeybindParts={command.keybindParts} newLayoutDesigns={props.controls.newLayoutDesigns} @@ -1625,23 +1693,45 @@ export const PromptInput: Component = (props) => { placement="top" value={ <> - {language.t("prompt.action.attachFile")} + {language.t("prompt.menu.addImagesAndFiles")} } > - + + + + + + {language.t("prompt.menu.imagesAndFiles")} + + + + {language.t("prompt.menu.commands")} + + + {language.t("prompt.menu.context")} + + setMode("shell")} shortcut="!"> + {language.t("prompt.menu.shellCommand")} + + + + diff --git a/packages/app/src/components/prompt-input/slash-popover.tsx b/packages/app/src/components/prompt-input/slash-popover.tsx index a84cbcca08..b9a2dc7afa 100644 --- a/packages/app/src/components/prompt-input/slash-popover.tsx +++ b/packages/app/src/components/prompt-input/slash-popover.tsx @@ -41,6 +41,10 @@ type PromptPopoverProps = { slashActive?: string setSlashActive: (id: string) => void onSlashSelect: (item: SlashCommand) => void + slashMenu: boolean + slashMenuQuery: string + onSlashMenuInput: (value: string) => void + onSlashMenuKeyDown: (event: KeyboardEvent) => void commandKeybind: (id: string) => string | undefined commandKeybindParts: (id: string) => string[] newLayoutDesigns: boolean @@ -254,6 +258,20 @@ export const PromptPopover: Component = (props) => { + +
+ requestAnimationFrame(() => el.focus())} + value={props.slashMenuQuery} + onInput={(event) => props.onSlashMenuInput(event.currentTarget.value)} + onKeyDown={props.onSlashMenuKeyDown} + onMouseDown={(event) => event.stopPropagation()} + aria-label={props.t("prompt.menu.commands")} + placeholder="/" + class="w-full bg-transparent outline-none text-[13px] leading-5 text-v2-text-text-base placeholder:text-v2-text-text-faint" + /> +
+
0} fallback={ diff --git a/packages/app/src/components/prompt-input/transient-state.ts b/packages/app/src/components/prompt-input/transient-state.ts index c8abf9a766..eaf35476d1 100644 --- a/packages/app/src/components/prompt-input/transient-state.ts +++ b/packages/app/src/components/prompt-input/transient-state.ts @@ -4,6 +4,8 @@ import type { PromptHistoryEntry } from "./history" export type PromptInputTransientState = { popover: "at" | "slash" | null + slashMenu: boolean + slashMenuQuery: string historyIndex: number savedPrompt: PromptHistoryEntry | null placeholder: number @@ -16,6 +18,8 @@ export type PromptInputTransientState = { function resetPromptInputTransientState(setStore: SetStoreFunction) { setStore({ popover: null, + slashMenu: false, + slashMenuQuery: "", historyIndex: -1, savedPrompt: null, draggingType: null, @@ -28,6 +32,8 @@ function resetPromptInputTransientState(setStore: SetStoreFunction, placeholder: number) { const [store, setStore] = createStore({ popover: null, + slashMenu: false, + slashMenuQuery: "", historyIndex: -1, savedPrompt: null, placeholder, diff --git a/packages/app/src/i18n/ar.ts b/packages/app/src/i18n/ar.ts index b343d1a929..2b639eded7 100644 --- a/packages/app/src/i18n/ar.ts +++ b/packages/app/src/i18n/ar.ts @@ -267,6 +267,11 @@ export const dict = { "prompt.context.removeActiveFile": "إزالة الملف النشط من السياق", "prompt.context.removeFile": "إزالة الملف من السياق", "prompt.action.attachFile": "إرفاق ملف", + "prompt.menu.addImagesAndFiles": "إضافة ملفات والمزيد", + "prompt.menu.imagesAndFiles": "الصور والملفات", + "prompt.menu.commands": "الأوامر", + "prompt.menu.context": "السياق", + "prompt.menu.shellCommand": "أمر shell", "prompt.attachment.remove": "إزالة المرفق", "prompt.action.send": "إرسال", "prompt.action.stop": "توقف", diff --git a/packages/app/src/i18n/br.ts b/packages/app/src/i18n/br.ts index 5227491445..688b05fee1 100644 --- a/packages/app/src/i18n/br.ts +++ b/packages/app/src/i18n/br.ts @@ -267,6 +267,11 @@ export const dict = { "prompt.context.removeActiveFile": "Remover arquivo ativo do contexto", "prompt.context.removeFile": "Remover arquivo do contexto", "prompt.action.attachFile": "Anexar arquivo", + "prompt.menu.addImagesAndFiles": "Adicionar arquivos e mais", + "prompt.menu.imagesAndFiles": "Imagens e arquivos", + "prompt.menu.commands": "Comandos", + "prompt.menu.context": "Contexto", + "prompt.menu.shellCommand": "Comando shell", "prompt.attachment.remove": "Remover anexo", "prompt.action.send": "Enviar", "prompt.action.stop": "Parar", diff --git a/packages/app/src/i18n/bs.ts b/packages/app/src/i18n/bs.ts index 8e259a1534..e0d4e2aa03 100644 --- a/packages/app/src/i18n/bs.ts +++ b/packages/app/src/i18n/bs.ts @@ -287,6 +287,11 @@ export const dict = { "prompt.context.removeActiveFile": "Ukloni aktivnu datoteku iz konteksta", "prompt.context.removeFile": "Ukloni datoteku iz konteksta", "prompt.action.attachFile": "Priloži datoteku", + "prompt.menu.addImagesAndFiles": "Dodaj datoteke i više", + "prompt.menu.imagesAndFiles": "Slike i datoteke", + "prompt.menu.commands": "Komande", + "prompt.menu.context": "Kontekst", + "prompt.menu.shellCommand": "Shell naredba", "prompt.attachment.remove": "Ukloni prilog", "prompt.action.send": "Pošalji", "prompt.action.stop": "Zaustavi", diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts index b92b2ad946..3b02b6a026 100644 --- a/packages/app/src/i18n/da.ts +++ b/packages/app/src/i18n/da.ts @@ -285,6 +285,11 @@ export const dict = { "prompt.context.removeActiveFile": "Fjern aktiv fil fra kontekst", "prompt.context.removeFile": "Fjern fil fra kontekst", "prompt.action.attachFile": "Vedhæft fil", + "prompt.menu.addImagesAndFiles": "Tilføj filer og mere", + "prompt.menu.imagesAndFiles": "Billeder og filer", + "prompt.menu.commands": "Kommandoer", + "prompt.menu.context": "Kontekst", + "prompt.menu.shellCommand": "Shell-kommando", "prompt.attachment.remove": "Fjern vedhæftning", "prompt.action.send": "Send", "prompt.action.stop": "Stop", diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts index 508f9f4c94..cf530f6488 100644 --- a/packages/app/src/i18n/de.ts +++ b/packages/app/src/i18n/de.ts @@ -272,6 +272,11 @@ export const dict = { "prompt.context.removeActiveFile": "Aktive Datei aus dem Kontext entfernen", "prompt.context.removeFile": "Datei aus dem Kontext entfernen", "prompt.action.attachFile": "Datei anhängen", + "prompt.menu.addImagesAndFiles": "Dateien und mehr hinzufügen", + "prompt.menu.imagesAndFiles": "Bilder und Dateien", + "prompt.menu.commands": "Befehle", + "prompt.menu.context": "Kontext", + "prompt.menu.shellCommand": "Shell-Befehl", "prompt.attachment.remove": "Anhang entfernen", "prompt.action.send": "Senden", "prompt.action.stop": "Stopp", diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index a281968d65..f44af82297 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -287,6 +287,11 @@ export const dict = { "prompt.context.removeActiveFile": "Remove active file from context", "prompt.context.removeFile": "Remove file from context", "prompt.action.attachFile": "Add files", + "prompt.menu.addImagesAndFiles": "Add files and more", + "prompt.menu.imagesAndFiles": "Images and files", + "prompt.menu.commands": "Commands", + "prompt.menu.context": "Context", + "prompt.menu.shellCommand": "Shell command", "prompt.attachment.remove": "Remove attachment", "prompt.action.send": "Send", "prompt.action.stop": "Stop", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index 8a42519da5..0610f2de00 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -286,6 +286,11 @@ export const dict = { "prompt.context.removeActiveFile": "Eliminar archivo activo del contexto", "prompt.context.removeFile": "Eliminar archivo del contexto", "prompt.action.attachFile": "Adjuntar archivo", + "prompt.menu.addImagesAndFiles": "Añadir archivos y más", + "prompt.menu.imagesAndFiles": "Imágenes y archivos", + "prompt.menu.commands": "Comandos", + "prompt.menu.context": "Contexto", + "prompt.menu.shellCommand": "Comando de shell", "prompt.attachment.remove": "Eliminar adjunto", "prompt.action.send": "Enviar", "prompt.action.stop": "Detener", diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts index 781fbb6305..3ed47d5dba 100644 --- a/packages/app/src/i18n/fr.ts +++ b/packages/app/src/i18n/fr.ts @@ -267,6 +267,11 @@ export const dict = { "prompt.context.removeActiveFile": "Retirer le fichier actif du contexte", "prompt.context.removeFile": "Retirer le fichier du contexte", "prompt.action.attachFile": "Joindre un fichier", + "prompt.menu.addImagesAndFiles": "Ajouter des fichiers et plus encore", + "prompt.menu.imagesAndFiles": "Images et fichiers", + "prompt.menu.commands": "Commandes", + "prompt.menu.context": "Contexte", + "prompt.menu.shellCommand": "Commande shell", "prompt.attachment.remove": "Supprimer la pièce jointe", "prompt.action.send": "Envoyer", "prompt.action.stop": "Arrêter", diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts index 87f0ebebe7..52ec83b3c4 100644 --- a/packages/app/src/i18n/ja.ts +++ b/packages/app/src/i18n/ja.ts @@ -266,6 +266,11 @@ export const dict = { "prompt.context.removeActiveFile": "コンテキストからアクティブなファイルを削除", "prompt.context.removeFile": "コンテキストからファイルを削除", "prompt.action.attachFile": "ファイルを添付", + "prompt.menu.addImagesAndFiles": "ファイルなどを追加", + "prompt.menu.imagesAndFiles": "画像とファイル", + "prompt.menu.commands": "コマンド", + "prompt.menu.context": "コンテキスト", + "prompt.menu.shellCommand": "シェルコマンド", "prompt.attachment.remove": "添付ファイルを削除", "prompt.action.send": "送信", "prompt.action.stop": "停止", diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts index de3a61a9f9..738123fe03 100644 --- a/packages/app/src/i18n/ko.ts +++ b/packages/app/src/i18n/ko.ts @@ -254,6 +254,11 @@ export const dict = { "prompt.context.removeActiveFile": "컨텍스트에서 활성 파일 제거", "prompt.context.removeFile": "컨텍스트에서 파일 제거", "prompt.action.attachFile": "파일 첨부", + "prompt.menu.addImagesAndFiles": "파일 및 기타 항목 추가", + "prompt.menu.imagesAndFiles": "이미지 및 파일", + "prompt.menu.commands": "명령어", + "prompt.menu.context": "컨텍스트", + "prompt.menu.shellCommand": "셸 명령", "prompt.attachment.remove": "첨부 파일 제거", "prompt.action.send": "전송", "prompt.action.stop": "중지", diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts index 90638a6c36..0a37f8bf32 100644 --- a/packages/app/src/i18n/no.ts +++ b/packages/app/src/i18n/no.ts @@ -277,6 +277,11 @@ export const dict = { "prompt.context.removeActiveFile": "Fjern aktiv fil fra kontekst", "prompt.context.removeFile": "Fjern fil fra kontekst", "prompt.action.attachFile": "Legg ved fil", + "prompt.menu.addImagesAndFiles": "Legg til filer og mer", + "prompt.menu.imagesAndFiles": "Bilder og filer", + "prompt.menu.commands": "Kommandoer", + "prompt.menu.context": "Kontekst", + "prompt.menu.shellCommand": "Shell-kommando", "prompt.attachment.remove": "Fjern vedlegg", "prompt.action.send": "Send", "prompt.action.stop": "Stopp", diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts index 469dbbda7a..f56e023aed 100644 --- a/packages/app/src/i18n/pl.ts +++ b/packages/app/src/i18n/pl.ts @@ -268,6 +268,11 @@ export const dict = { "prompt.context.removeActiveFile": "Usuń aktywny plik z kontekstu", "prompt.context.removeFile": "Usuń plik z kontekstu", "prompt.action.attachFile": "Załącz plik", + "prompt.menu.addImagesAndFiles": "Dodaj pliki i inne elementy", + "prompt.menu.imagesAndFiles": "Obrazy i pliki", + "prompt.menu.commands": "Polecenia", + "prompt.menu.context": "Kontekst", + "prompt.menu.shellCommand": "Polecenie powłoki", "prompt.attachment.remove": "Usuń załącznik", "prompt.action.send": "Wyślij", "prompt.action.stop": "Zatrzymaj", diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts index fbc4878165..0d68552e6d 100644 --- a/packages/app/src/i18n/ru.ts +++ b/packages/app/src/i18n/ru.ts @@ -286,6 +286,11 @@ export const dict = { "prompt.context.removeActiveFile": "Удалить активный файл из контекста", "prompt.context.removeFile": "Удалить файл из контекста", "prompt.action.attachFile": "Прикрепить файл", + "prompt.menu.addImagesAndFiles": "Добавить файлы и другое", + "prompt.menu.imagesAndFiles": "Изображения и файлы", + "prompt.menu.commands": "Команды", + "prompt.menu.context": "Контекст", + "prompt.menu.shellCommand": "Команда оболочки", "prompt.attachment.remove": "Удалить вложение", "prompt.action.send": "Отправить", "prompt.action.stop": "Остановить", diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts index 5b245d55e2..91c009be0c 100644 --- a/packages/app/src/i18n/th.ts +++ b/packages/app/src/i18n/th.ts @@ -286,6 +286,11 @@ export const dict = { "prompt.context.removeActiveFile": "เอาไฟล์ที่ใช้งานอยู่ออกจากบริบท", "prompt.context.removeFile": "เอาไฟล์ออกจากบริบท", "prompt.action.attachFile": "แนบไฟล์", + "prompt.menu.addImagesAndFiles": "เพิ่มไฟล์และอื่น ๆ", + "prompt.menu.imagesAndFiles": "รูปภาพและไฟล์", + "prompt.menu.commands": "คำสั่ง", + "prompt.menu.context": "บริบท", + "prompt.menu.shellCommand": "คำสั่งเชลล์", "prompt.attachment.remove": "เอาไฟล์แนบออก", "prompt.action.send": "ส่ง", "prompt.action.stop": "หยุด", diff --git a/packages/app/src/i18n/tr.ts b/packages/app/src/i18n/tr.ts index f0472d325e..ff17d0001c 100644 --- a/packages/app/src/i18n/tr.ts +++ b/packages/app/src/i18n/tr.ts @@ -291,6 +291,11 @@ export const dict = { "prompt.context.removeActiveFile": "Aktif dosyayı bağlamdan çıkar", "prompt.context.removeFile": "Dosyayı bağlamdan çıkar", "prompt.action.attachFile": "Dosya ekle", + "prompt.menu.addImagesAndFiles": "Dosya ve daha fazlasını ekle", + "prompt.menu.imagesAndFiles": "Görseller ve dosyalar", + "prompt.menu.commands": "Komutlar", + "prompt.menu.context": "Bağlam", + "prompt.menu.shellCommand": "Kabuk komutu", "prompt.attachment.remove": "Eki kaldır", "prompt.action.send": "Gönder", "prompt.action.stop": "Durdur", diff --git a/packages/app/src/i18n/uk.ts b/packages/app/src/i18n/uk.ts index 0da1f738fb..c6a0ae9629 100644 --- a/packages/app/src/i18n/uk.ts +++ b/packages/app/src/i18n/uk.ts @@ -288,6 +288,11 @@ export const dict = { "prompt.context.removeActiveFile": "Видалити активний файл з контексту", "prompt.context.removeFile": "Видалити файл з контексту", "prompt.action.attachFile": "Додати файли", + "prompt.menu.addImagesAndFiles": "Додати файли та інше", + "prompt.menu.imagesAndFiles": "Зображення та файли", + "prompt.menu.commands": "Команди", + "prompt.menu.context": "Контекст", + "prompt.menu.shellCommand": "Команда оболонки", "prompt.attachment.remove": "Видалити вкладення", "prompt.action.send": "Надіслати", "prompt.action.stop": "Зупинити", diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts index a1325d9067..a44bfc107f 100644 --- a/packages/app/src/i18n/zh.ts +++ b/packages/app/src/i18n/zh.ts @@ -306,6 +306,11 @@ export const dict = { "prompt.context.removeActiveFile": "从上下文移除活动文件", "prompt.context.removeFile": "从上下文移除文件", "prompt.action.attachFile": "附加文件", + "prompt.menu.addImagesAndFiles": "添加文件及更多内容", + "prompt.menu.imagesAndFiles": "图片和文件", + "prompt.menu.commands": "命令", + "prompt.menu.context": "上下文", + "prompt.menu.shellCommand": "shell 命令", "prompt.attachment.remove": "移除附件", "prompt.action.send": "发送", "prompt.action.stop": "停止", diff --git a/packages/app/src/i18n/zht.ts b/packages/app/src/i18n/zht.ts index 436e2b60d8..e9a1fea29e 100644 --- a/packages/app/src/i18n/zht.ts +++ b/packages/app/src/i18n/zht.ts @@ -286,6 +286,11 @@ export const dict = { "prompt.context.removeActiveFile": "從上下文移除目前檔案", "prompt.context.removeFile": "從上下文移除檔案", "prompt.action.attachFile": "附加檔案", + "prompt.menu.addImagesAndFiles": "新增檔案及更多內容", + "prompt.menu.imagesAndFiles": "圖片和檔案", + "prompt.menu.commands": "命令", + "prompt.menu.context": "上下文", + "prompt.menu.shellCommand": "shell 命令", "prompt.attachment.remove": "移除附件", "prompt.action.send": "傳送", "prompt.action.stop": "停止", diff --git a/packages/app/test-browser/prompt-transient-state.test.ts b/packages/app/test-browser/prompt-transient-state.test.ts index 55ef8d3922..61b5c6a14f 100644 --- a/packages/app/test-browser/prompt-transient-state.test.ts +++ b/packages/app/test-browser/prompt-transient-state.test.ts @@ -8,6 +8,8 @@ test("resets transient prompt input state when the prompt session changes", () = const [state, setState] = createPromptInputTransientState(identity, 3) setState({ popover: "slash", + slashMenu: true, + slashMenuQuery: "compact", historyIndex: 2, savedPrompt: { prompt: [{ type: "text", content: "draft-A", start: 0, end: 7 }], @@ -23,6 +25,8 @@ test("resets transient prompt input state when the prompt session changes", () = expect(state).toMatchObject({ popover: null, + slashMenu: false, + slashMenuQuery: "", historyIndex: -1, savedPrompt: null, placeholder: 3,