feat(app): add composer add menu with draft-preserving commands (#35711)

This commit is contained in:
usrnk1 2026-07-09 07:39:55 +02:00 committed by GitHub
commit 3cd9ee5a73
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 228 additions and 20 deletions

View file

@ -520,7 +520,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
const setMode = (mode: "normal" | "shell") => { const setMode = (mode: "normal" | "shell") => {
setStore("mode", mode) setStore("mode", mode)
setStore("popover", null) setStore({ popover: null, slashMenu: false, slashMenuQuery: "" })
requestAnimationFrame(() => editorRef?.focus()) requestAnimationFrame(() => editorRef?.focus())
} }
@ -554,7 +554,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
}, },
]) ])
const closePopover = () => setStore("popover", null) const closePopover = () => setStore({ popover: null, slashMenu: false, slashMenuQuery: "" })
const resetHistoryNavigation = (force = false) => { const resetHistoryNavigation = (force = false) => {
if (!force && (store.historyIndex < 0 || store.applyingHistory)) return if (!force && (store.historyIndex < 0 || store.applyingHistory)) return
@ -800,17 +800,30 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
const handleSlashSelect = (cmd: SlashCommand | undefined) => { const handleSlashSelect = (cmd: SlashCommand | undefined) => {
if (!cmd) return if (!cmd) return
const menu = store.slashMenu
closePopover() closePopover()
const images = imageAttachments() const images = imageAttachments()
if (cmd.type === "custom") { if (cmd.type === "custom") {
const text = `/${cmd.trigger} ` 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) setEditorText(text)
prompt.set([{ type: "text", content: text, start: 0, end: text.length }, ...images], text.length) prompt.set([{ type: "text", content: text, start: 0, end: text.length }, ...images], text.length)
focusEditorEnd() focusEditorEnd()
return return
} }
if (menu) {
command.trigger(cmd.id, "slash")
return
}
clearEditor() clearEditor()
prompt.set([...DEFAULT_PROMPT, ...images], 0) prompt.set([...DEFAULT_PROMPT, ...images], 0)
command.trigger(cmd.id, "slash") command.trigger(cmd.id, "slash")
@ -1072,10 +1085,10 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
if (atMatch) { if (atMatch) {
atOnInput(atMatch[1]) atOnInput(atMatch[1])
setStore("popover", "at") setStore({ popover: "at", slashMenu: false, slashMenuQuery: "" })
} else if (slashMatch) { } else if (slashMatch) {
slashOnInput(slashMatch[1]) slashOnInput(slashMatch[1])
setStore("popover", "slash") setStore({ popover: "slash", slashMenu: false, slashMenuQuery: "" })
} else { } else {
closePopover() closePopover()
} }
@ -1171,6 +1184,28 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
return true 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") => { const addToHistory = (prompt: Prompt, mode: "normal" | "shell") => {
history.add(prompt, mode, mode === "shell" ? [] : historyComments()) history.add(prompt, mode, mode === "shell" ? [] : historyComments())
} }
@ -1199,7 +1234,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
} }
setStore("mode", "normal") setStore("mode", "normal")
setStore("popover", null) closePopover()
setStore("historyIndex", -1) setStore("historyIndex", -1)
setStore("savedPrompt", null) setStore("savedPrompt", null)
prompt.set(edit.prompt, promptLength(edit.prompt)) prompt.set(edit.prompt, promptLength(edit.prompt))
@ -1286,7 +1321,10 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
resetHistoryNavigation(true) resetHistoryNavigation(true)
}, },
setMode: (mode) => setStore("mode", mode), setMode: (mode) => setStore("mode", mode),
setPopover: (popover) => setStore("popover", popover), setPopover: (popover) => {
if (!popover) return closePopover()
setStore({ popover, slashMenu: false, slashMenuQuery: "" })
},
newSessionWorktree: () => props.newSessionWorktree, newSessionWorktree: () => props.newSessionWorktree,
onNewSessionWorktreeReset: props.onNewSessionWorktreeReset, onNewSessionWorktreeReset: props.onNewSessionWorktreeReset,
shouldQueue: props.shouldQueue, shouldQueue: props.shouldQueue,
@ -1325,7 +1363,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
const cursorPosition = getCursorPosition(editorRef) const cursorPosition = getCursorPosition(editorRef)
if (cursorPosition === 0) { if (cursorPosition === 0) {
setStore("mode", "shell") setStore("mode", "shell")
setStore("popover", null) closePopover()
event.preventDefault() event.preventDefault()
return return
} }
@ -1460,6 +1498,29 @@ export const PromptInput: Component<PromptInputProps> = (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 agentsLoading = () => props.controls.agents.loading
const agentsShouldFadeIn = createMemo<boolean>((prev) => prev ?? agentsLoading()) const agentsShouldFadeIn = createMemo<boolean>((prev) => prev ?? agentsLoading())
const providersLoading = () => props.controls.model.loading const providersLoading = () => props.controls.model.loading
@ -1527,6 +1588,13 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
slashActive={slashActive() ?? undefined} slashActive={slashActive() ?? undefined}
setSlashActive={setSlashActive} setSlashActive={setSlashActive}
onSlashSelect={handleSlashSelect} onSlashSelect={handleSlashSelect}
slashMenu={store.slashMenu}
slashMenuQuery={store.slashMenuQuery}
onSlashMenuInput={(value) => {
setStore("slashMenuQuery", value)
slashOnInput(value)
}}
onSlashMenuKeyDown={handleSlashMenuKeyDown}
commandKeybind={command.keybind} commandKeybind={command.keybind}
commandKeybindParts={command.keybindParts} commandKeybindParts={command.keybindParts}
newLayoutDesigns={props.controls.newLayoutDesigns} newLayoutDesigns={props.controls.newLayoutDesigns}
@ -1625,23 +1693,45 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
placement="top" placement="top"
value={ value={
<> <>
{language.t("prompt.action.attachFile")} {language.t("prompt.menu.addImagesAndFiles")}
<KeybindV2 keys={command.keybindParts("file.attach")} variant="neutral" /> <KeybindV2 keys={command.keybindParts("file.attach")} variant="neutral" />
</> </>
} }
> >
<IconButton <MenuV2 gutter={6} modal={false} placement="top-start">
data-action="prompt-attach" <MenuV2.Trigger
type="button" as={IconButton}
icon="plus" data-action="prompt-attach"
variant="ghost" type="button"
class="size-7 rounded-md p-[6px] text-v2-icon-icon-muted" icon="plus"
style={buttons()} variant="ghost"
onClick={pick} class="size-7 rounded-md p-[6px] text-v2-icon-icon-muted"
disabled={store.mode !== "normal"} style={buttons()}
tabIndex={store.mode === "normal" ? undefined : -1} disabled={store.mode !== "normal"}
aria-label={language.t("prompt.action.attachFile")} tabIndex={store.mode === "normal" ? undefined : -1}
/> aria-label={language.t("prompt.menu.addImagesAndFiles")}
/>
<MenuV2.Portal>
<MenuV2.Content
class="[&_[data-slot=menu-v2-item-shortcut]]:w-5 [&_[data-slot=menu-v2-item-shortcut]]:justify-center"
style={{ "min-width": "180px" }}
>
<MenuV2.Item onSelect={pick} shortcut={command.keybind("file.attach")}>
{language.t("prompt.menu.imagesAndFiles")}
</MenuV2.Item>
<MenuV2.Separator />
<MenuV2.Item onSelect={openCommands} shortcut="/">
{language.t("prompt.menu.commands")}
</MenuV2.Item>
<MenuV2.Item onSelect={openContext} shortcut="@">
{language.t("prompt.menu.context")}
</MenuV2.Item>
<MenuV2.Item onSelect={() => setMode("shell")} shortcut="!">
{language.t("prompt.menu.shellCommand")}
</MenuV2.Item>
</MenuV2.Content>
</MenuV2.Portal>
</MenuV2>
</TooltipV2> </TooltipV2>
<Show when={showAgentControl()}> <Show when={showAgentControl()}>
<ComposerAgentControl state={agentControlState()} /> <ComposerAgentControl state={agentControlState()} />

View file

@ -41,6 +41,10 @@ type PromptPopoverProps = {
slashActive?: string slashActive?: string
setSlashActive: (id: string) => void setSlashActive: (id: string) => void
onSlashSelect: (item: SlashCommand) => void onSlashSelect: (item: SlashCommand) => void
slashMenu: boolean
slashMenuQuery: string
onSlashMenuInput: (value: string) => void
onSlashMenuKeyDown: (event: KeyboardEvent) => void
commandKeybind: (id: string) => string | undefined commandKeybind: (id: string) => string | undefined
commandKeybindParts: (id: string) => string[] commandKeybindParts: (id: string) => string[]
newLayoutDesigns: boolean newLayoutDesigns: boolean
@ -254,6 +258,20 @@ export const PromptPopover: Component<PromptPopoverProps> = (props) => {
</Show> </Show>
</Match> </Match>
<Match when={props.popover === "slash"}> <Match when={props.popover === "slash"}>
<Show when={props.slashMenu}>
<div class="px-2 py-1">
<input
ref={(el) => 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"
/>
</div>
</Show>
<Show <Show
when={props.slashFlat.length > 0} when={props.slashFlat.length > 0}
fallback={ fallback={

View file

@ -4,6 +4,8 @@ import type { PromptHistoryEntry } from "./history"
export type PromptInputTransientState = { export type PromptInputTransientState = {
popover: "at" | "slash" | null popover: "at" | "slash" | null
slashMenu: boolean
slashMenuQuery: string
historyIndex: number historyIndex: number
savedPrompt: PromptHistoryEntry | null savedPrompt: PromptHistoryEntry | null
placeholder: number placeholder: number
@ -16,6 +18,8 @@ export type PromptInputTransientState = {
function resetPromptInputTransientState(setStore: SetStoreFunction<PromptInputTransientState>) { function resetPromptInputTransientState(setStore: SetStoreFunction<PromptInputTransientState>) {
setStore({ setStore({
popover: null, popover: null,
slashMenu: false,
slashMenuQuery: "",
historyIndex: -1, historyIndex: -1,
savedPrompt: null, savedPrompt: null,
draggingType: null, draggingType: null,
@ -28,6 +32,8 @@ function resetPromptInputTransientState(setStore: SetStoreFunction<PromptInputTr
export function createPromptInputTransientState(identity: Accessor<unknown>, placeholder: number) { export function createPromptInputTransientState(identity: Accessor<unknown>, placeholder: number) {
const [store, setStore] = createStore<PromptInputTransientState>({ const [store, setStore] = createStore<PromptInputTransientState>({
popover: null, popover: null,
slashMenu: false,
slashMenuQuery: "",
historyIndex: -1, historyIndex: -1,
savedPrompt: null, savedPrompt: null,
placeholder, placeholder,

View file

@ -267,6 +267,11 @@ export const dict = {
"prompt.context.removeActiveFile": "إزالة الملف النشط من السياق", "prompt.context.removeActiveFile": "إزالة الملف النشط من السياق",
"prompt.context.removeFile": "إزالة الملف من السياق", "prompt.context.removeFile": "إزالة الملف من السياق",
"prompt.action.attachFile": "إرفاق ملف", "prompt.action.attachFile": "إرفاق ملف",
"prompt.menu.addImagesAndFiles": "إضافة ملفات والمزيد",
"prompt.menu.imagesAndFiles": "الصور والملفات",
"prompt.menu.commands": "الأوامر",
"prompt.menu.context": "السياق",
"prompt.menu.shellCommand": "أمر shell",
"prompt.attachment.remove": "إزالة المرفق", "prompt.attachment.remove": "إزالة المرفق",
"prompt.action.send": "إرسال", "prompt.action.send": "إرسال",
"prompt.action.stop": "توقف", "prompt.action.stop": "توقف",

View file

@ -267,6 +267,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Remover arquivo ativo do contexto", "prompt.context.removeActiveFile": "Remover arquivo ativo do contexto",
"prompt.context.removeFile": "Remover arquivo do contexto", "prompt.context.removeFile": "Remover arquivo do contexto",
"prompt.action.attachFile": "Anexar arquivo", "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.attachment.remove": "Remover anexo",
"prompt.action.send": "Enviar", "prompt.action.send": "Enviar",
"prompt.action.stop": "Parar", "prompt.action.stop": "Parar",

View file

@ -287,6 +287,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Ukloni aktivnu datoteku iz konteksta", "prompt.context.removeActiveFile": "Ukloni aktivnu datoteku iz konteksta",
"prompt.context.removeFile": "Ukloni datoteku iz konteksta", "prompt.context.removeFile": "Ukloni datoteku iz konteksta",
"prompt.action.attachFile": "Priloži datoteku", "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.attachment.remove": "Ukloni prilog",
"prompt.action.send": "Pošalji", "prompt.action.send": "Pošalji",
"prompt.action.stop": "Zaustavi", "prompt.action.stop": "Zaustavi",

View file

@ -285,6 +285,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Fjern aktiv fil fra kontekst", "prompt.context.removeActiveFile": "Fjern aktiv fil fra kontekst",
"prompt.context.removeFile": "Fjern fil fra kontekst", "prompt.context.removeFile": "Fjern fil fra kontekst",
"prompt.action.attachFile": "Vedhæft fil", "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.attachment.remove": "Fjern vedhæftning",
"prompt.action.send": "Send", "prompt.action.send": "Send",
"prompt.action.stop": "Stop", "prompt.action.stop": "Stop",

View file

@ -272,6 +272,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Aktive Datei aus dem Kontext entfernen", "prompt.context.removeActiveFile": "Aktive Datei aus dem Kontext entfernen",
"prompt.context.removeFile": "Datei aus dem Kontext entfernen", "prompt.context.removeFile": "Datei aus dem Kontext entfernen",
"prompt.action.attachFile": "Datei anhängen", "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.attachment.remove": "Anhang entfernen",
"prompt.action.send": "Senden", "prompt.action.send": "Senden",
"prompt.action.stop": "Stopp", "prompt.action.stop": "Stopp",

View file

@ -287,6 +287,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Remove active file from context", "prompt.context.removeActiveFile": "Remove active file from context",
"prompt.context.removeFile": "Remove file from context", "prompt.context.removeFile": "Remove file from context",
"prompt.action.attachFile": "Add files", "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.attachment.remove": "Remove attachment",
"prompt.action.send": "Send", "prompt.action.send": "Send",
"prompt.action.stop": "Stop", "prompt.action.stop": "Stop",

View file

@ -286,6 +286,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Eliminar archivo activo del contexto", "prompt.context.removeActiveFile": "Eliminar archivo activo del contexto",
"prompt.context.removeFile": "Eliminar archivo del contexto", "prompt.context.removeFile": "Eliminar archivo del contexto",
"prompt.action.attachFile": "Adjuntar archivo", "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.attachment.remove": "Eliminar adjunto",
"prompt.action.send": "Enviar", "prompt.action.send": "Enviar",
"prompt.action.stop": "Detener", "prompt.action.stop": "Detener",

View file

@ -267,6 +267,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Retirer le fichier actif du contexte", "prompt.context.removeActiveFile": "Retirer le fichier actif du contexte",
"prompt.context.removeFile": "Retirer le fichier du contexte", "prompt.context.removeFile": "Retirer le fichier du contexte",
"prompt.action.attachFile": "Joindre un fichier", "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.attachment.remove": "Supprimer la pièce jointe",
"prompt.action.send": "Envoyer", "prompt.action.send": "Envoyer",
"prompt.action.stop": "Arrêter", "prompt.action.stop": "Arrêter",

View file

@ -266,6 +266,11 @@ export const dict = {
"prompt.context.removeActiveFile": "コンテキストからアクティブなファイルを削除", "prompt.context.removeActiveFile": "コンテキストからアクティブなファイルを削除",
"prompt.context.removeFile": "コンテキストからファイルを削除", "prompt.context.removeFile": "コンテキストからファイルを削除",
"prompt.action.attachFile": "ファイルを添付", "prompt.action.attachFile": "ファイルを添付",
"prompt.menu.addImagesAndFiles": "ファイルなどを追加",
"prompt.menu.imagesAndFiles": "画像とファイル",
"prompt.menu.commands": "コマンド",
"prompt.menu.context": "コンテキスト",
"prompt.menu.shellCommand": "シェルコマンド",
"prompt.attachment.remove": "添付ファイルを削除", "prompt.attachment.remove": "添付ファイルを削除",
"prompt.action.send": "送信", "prompt.action.send": "送信",
"prompt.action.stop": "停止", "prompt.action.stop": "停止",

View file

@ -254,6 +254,11 @@ export const dict = {
"prompt.context.removeActiveFile": "컨텍스트에서 활성 파일 제거", "prompt.context.removeActiveFile": "컨텍스트에서 활성 파일 제거",
"prompt.context.removeFile": "컨텍스트에서 파일 제거", "prompt.context.removeFile": "컨텍스트에서 파일 제거",
"prompt.action.attachFile": "파일 첨부", "prompt.action.attachFile": "파일 첨부",
"prompt.menu.addImagesAndFiles": "파일 및 기타 항목 추가",
"prompt.menu.imagesAndFiles": "이미지 및 파일",
"prompt.menu.commands": "명령어",
"prompt.menu.context": "컨텍스트",
"prompt.menu.shellCommand": "셸 명령",
"prompt.attachment.remove": "첨부 파일 제거", "prompt.attachment.remove": "첨부 파일 제거",
"prompt.action.send": "전송", "prompt.action.send": "전송",
"prompt.action.stop": "중지", "prompt.action.stop": "중지",

View file

@ -277,6 +277,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Fjern aktiv fil fra kontekst", "prompt.context.removeActiveFile": "Fjern aktiv fil fra kontekst",
"prompt.context.removeFile": "Fjern fil fra kontekst", "prompt.context.removeFile": "Fjern fil fra kontekst",
"prompt.action.attachFile": "Legg ved fil", "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.attachment.remove": "Fjern vedlegg",
"prompt.action.send": "Send", "prompt.action.send": "Send",
"prompt.action.stop": "Stopp", "prompt.action.stop": "Stopp",

View file

@ -268,6 +268,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Usuń aktywny plik z kontekstu", "prompt.context.removeActiveFile": "Usuń aktywny plik z kontekstu",
"prompt.context.removeFile": "Usuń plik z kontekstu", "prompt.context.removeFile": "Usuń plik z kontekstu",
"prompt.action.attachFile": "Załącz plik", "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.attachment.remove": "Usuń załącznik",
"prompt.action.send": "Wyślij", "prompt.action.send": "Wyślij",
"prompt.action.stop": "Zatrzymaj", "prompt.action.stop": "Zatrzymaj",

View file

@ -286,6 +286,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Удалить активный файл из контекста", "prompt.context.removeActiveFile": "Удалить активный файл из контекста",
"prompt.context.removeFile": "Удалить файл из контекста", "prompt.context.removeFile": "Удалить файл из контекста",
"prompt.action.attachFile": "Прикрепить файл", "prompt.action.attachFile": "Прикрепить файл",
"prompt.menu.addImagesAndFiles": "Добавить файлы и другое",
"prompt.menu.imagesAndFiles": "Изображения и файлы",
"prompt.menu.commands": "Команды",
"prompt.menu.context": "Контекст",
"prompt.menu.shellCommand": "Команда оболочки",
"prompt.attachment.remove": "Удалить вложение", "prompt.attachment.remove": "Удалить вложение",
"prompt.action.send": "Отправить", "prompt.action.send": "Отправить",
"prompt.action.stop": "Остановить", "prompt.action.stop": "Остановить",

View file

@ -286,6 +286,11 @@ export const dict = {
"prompt.context.removeActiveFile": "เอาไฟล์ที่ใช้งานอยู่ออกจากบริบท", "prompt.context.removeActiveFile": "เอาไฟล์ที่ใช้งานอยู่ออกจากบริบท",
"prompt.context.removeFile": "เอาไฟล์ออกจากบริบท", "prompt.context.removeFile": "เอาไฟล์ออกจากบริบท",
"prompt.action.attachFile": "แนบไฟล์", "prompt.action.attachFile": "แนบไฟล์",
"prompt.menu.addImagesAndFiles": "เพิ่มไฟล์และอื่น ๆ",
"prompt.menu.imagesAndFiles": "รูปภาพและไฟล์",
"prompt.menu.commands": "คำสั่ง",
"prompt.menu.context": "บริบท",
"prompt.menu.shellCommand": "คำสั่งเชลล์",
"prompt.attachment.remove": "เอาไฟล์แนบออก", "prompt.attachment.remove": "เอาไฟล์แนบออก",
"prompt.action.send": "ส่ง", "prompt.action.send": "ส่ง",
"prompt.action.stop": "หยุด", "prompt.action.stop": "หยุด",

View file

@ -291,6 +291,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Aktif dosyayı bağlamdan çıkar", "prompt.context.removeActiveFile": "Aktif dosyayı bağlamdan çıkar",
"prompt.context.removeFile": "Dosyayı bağlamdan çıkar", "prompt.context.removeFile": "Dosyayı bağlamdan çıkar",
"prompt.action.attachFile": "Dosya ekle", "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.attachment.remove": "Eki kaldır",
"prompt.action.send": "Gönder", "prompt.action.send": "Gönder",
"prompt.action.stop": "Durdur", "prompt.action.stop": "Durdur",

View file

@ -288,6 +288,11 @@ export const dict = {
"prompt.context.removeActiveFile": "Видалити активний файл з контексту", "prompt.context.removeActiveFile": "Видалити активний файл з контексту",
"prompt.context.removeFile": "Видалити файл з контексту", "prompt.context.removeFile": "Видалити файл з контексту",
"prompt.action.attachFile": "Додати файли", "prompt.action.attachFile": "Додати файли",
"prompt.menu.addImagesAndFiles": "Додати файли та інше",
"prompt.menu.imagesAndFiles": "Зображення та файли",
"prompt.menu.commands": "Команди",
"prompt.menu.context": "Контекст",
"prompt.menu.shellCommand": "Команда оболонки",
"prompt.attachment.remove": "Видалити вкладення", "prompt.attachment.remove": "Видалити вкладення",
"prompt.action.send": "Надіслати", "prompt.action.send": "Надіслати",
"prompt.action.stop": "Зупинити", "prompt.action.stop": "Зупинити",

View file

@ -306,6 +306,11 @@ export const dict = {
"prompt.context.removeActiveFile": "从上下文移除活动文件", "prompt.context.removeActiveFile": "从上下文移除活动文件",
"prompt.context.removeFile": "从上下文移除文件", "prompt.context.removeFile": "从上下文移除文件",
"prompt.action.attachFile": "附加文件", "prompt.action.attachFile": "附加文件",
"prompt.menu.addImagesAndFiles": "添加文件及更多内容",
"prompt.menu.imagesAndFiles": "图片和文件",
"prompt.menu.commands": "命令",
"prompt.menu.context": "上下文",
"prompt.menu.shellCommand": "shell 命令",
"prompt.attachment.remove": "移除附件", "prompt.attachment.remove": "移除附件",
"prompt.action.send": "发送", "prompt.action.send": "发送",
"prompt.action.stop": "停止", "prompt.action.stop": "停止",

View file

@ -286,6 +286,11 @@ export const dict = {
"prompt.context.removeActiveFile": "從上下文移除目前檔案", "prompt.context.removeActiveFile": "從上下文移除目前檔案",
"prompt.context.removeFile": "從上下文移除檔案", "prompt.context.removeFile": "從上下文移除檔案",
"prompt.action.attachFile": "附加檔案", "prompt.action.attachFile": "附加檔案",
"prompt.menu.addImagesAndFiles": "新增檔案及更多內容",
"prompt.menu.imagesAndFiles": "圖片和檔案",
"prompt.menu.commands": "命令",
"prompt.menu.context": "上下文",
"prompt.menu.shellCommand": "shell 命令",
"prompt.attachment.remove": "移除附件", "prompt.attachment.remove": "移除附件",
"prompt.action.send": "傳送", "prompt.action.send": "傳送",
"prompt.action.stop": "停止", "prompt.action.stop": "停止",

View file

@ -8,6 +8,8 @@ test("resets transient prompt input state when the prompt session changes", () =
const [state, setState] = createPromptInputTransientState(identity, 3) const [state, setState] = createPromptInputTransientState(identity, 3)
setState({ setState({
popover: "slash", popover: "slash",
slashMenu: true,
slashMenuQuery: "compact",
historyIndex: 2, historyIndex: 2,
savedPrompt: { savedPrompt: {
prompt: [{ type: "text", content: "draft-A", start: 0, end: 7 }], 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({ expect(state).toMatchObject({
popover: null, popover: null,
slashMenu: false,
slashMenuQuery: "",
historyIndex: -1, historyIndex: -1,
savedPrompt: null, savedPrompt: null,
placeholder: 3, placeholder: 3,