diff --git a/packages/desktop/src/components/prompt-input.tsx b/packages/desktop/src/components/prompt-input.tsx index 1a6e233e3..02fa700bf 100644 --- a/packages/desktop/src/components/prompt-input.tsx +++ b/packages/desktop/src/components/prompt-input.tsx @@ -99,6 +99,7 @@ export const PromptInput: Component = (props) => { placeholder: number dragging: boolean imageAttachments: ImageAttachmentPart[] + mode: "normal" | "shell" }>({ popover: null, historyIndex: -1, @@ -106,6 +107,7 @@ export const PromptInput: Component = (props) => { placeholder: Math.floor(Math.random() * PLACEHOLDERS.length), dragging: false, imageAttachments: [], + mode: "normal", }) const MAX_HISTORY = 100 @@ -579,6 +581,24 @@ export const PromptInput: Component = (props) => { } const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "!" && store.mode === "normal") { + const cursorPosition = getCursorPosition(editorRef) + if (cursorPosition === 0) { + setStore("mode", "shell") + setStore("popover", null) + event.preventDefault() + return + } + } + if (store.mode === "shell") { + const cursorPosition = getCursorPosition(editorRef) + if ((event.key === "Backspace" && cursorPosition === 0) || event.key === "Escape") { + setStore("mode", "normal") + event.preventDefault() + return + } + } + if (store.popover && (event.key === "ArrowUp" || event.key === "ArrowDown" || event.key === "Enter")) { if (store.popover === "file") { onKeyDown(event) @@ -688,10 +708,28 @@ export const PromptInput: Component = (props) => { filename: attachment.filename, })) + const isShellMode = store.mode === "shell" tabs().setActive(undefined) editorRef.innerHTML = "" prompt.set([{ type: "text", content: "", start: 0, end: 0 }], 0) setStore("imageAttachments", []) + setStore("mode", "normal") + + const model = { + modelID: local.model.current()!.id, + providerID: local.model.current()!.provider.id, + } + const agent = local.agent.current()!.name + + if (isShellMode) { + sdk.client.session.shell({ + sessionID: existing.id, + agent, + model, + command: text, + }) + return + } if (text.startsWith("/")) { const [cmdName, ...args] = text.split(" ") @@ -702,19 +740,13 @@ export const PromptInput: Component = (props) => { sessionID: existing.id, command: commandName, arguments: args.join(" "), - agent: local.agent.current()!.name, - model: `${local.model.current()!.provider.id}/${local.model.current()!.id}`, + agent, + model: `${model.providerID}/${model.modelID}`, }) return } } - const model = { - modelID: local.model.current()!.id, - providerID: local.model.current()!.provider.id, - } - const agent = local.agent.current()!.name - sync.session.addOptimisticMessage({ sessionID: existing.id, text, @@ -883,30 +915,45 @@ export const PromptInput: Component = (props) => { />
- Ask anything... "{PLACEHOLDERS[store.placeholder]}" + {store.mode === "shell" + ? "Enter shell command..." + : `Ask anything... "${PLACEHOLDERS[store.placeholder]}"`}
- agent.name)} + current={local.agent.current().name} + onSelect={local.agent.set} + class="capitalize" + variant="ghost" + /> + + +