refactor(tui): dispatch editable slash commands

This commit is contained in:
Shoubhit Dash 2026-05-21 17:45:13 +05:30
parent c7a17aea4b
commit 80cbafa3c3
2 changed files with 31 additions and 12 deletions

View file

@ -59,7 +59,14 @@ import { DialogWorkspaceUnavailable } from "../dialog-workspace-unavailable"
import { useArgs } from "@tui/context/args"
import { Flag } from "@opencode-ai/core/flag/flag"
import { type WorkspaceStatus } from "../workspace-label"
import { OPENCODE_BASE_MODE, useBindings, useCommandShortcut, useLeaderActive, useOpencodeKeymap } from "../../keymap"
import {
OPENCODE_BASE_MODE,
useBindings,
useCommandShortcut,
useCommandSlashes,
useLeaderActive,
useOpencodeKeymap,
} from "../../keymap"
import { useTuiConfig } from "../../context/tui-config"
export type PromptProps = {
@ -151,6 +158,7 @@ export function Prompt(props: PromptProps) {
const history = usePromptHistory()
const stash = usePromptStash()
const keymap = useOpencodeKeymap()
const slashCommands = useCommandSlashes()
const agentShortcut = useCommandShortcut("agent.cycle")
const paletteShortcut = useCommandShortcut("command.palette.show")
const renderer = useRenderer()
@ -1145,15 +1153,8 @@ export function Prompt(props: PromptProps) {
command: inputText,
})
setStore("mode", "normal")
} else if (slash && (slash.name === "compact" || slash.name === "summarize")) {
const instructions = slash.arguments.trim()
const payload = {
sessionID,
modelID: selectedModel.modelID,
providerID: selectedModel.providerID,
...(instructions ? { $body_instructions: instructions } : {}),
} satisfies Parameters<typeof sdk.client.session.summarize>[0] & { $body_instructions?: string }
void sdk.client.session.summarize(payload)
} else if (slash && slashCommand(slash.name)?.input) {
slashCommand(slash.name)?.onSelect()
} else if (slash && sync.data.command.some((x) => x.name === slash.name)) {
void sdk.client.session.command({
sessionID,
@ -1229,6 +1230,10 @@ export function Prompt(props: PromptProps) {
arguments: firstLineArgs.join(" ") + (restOfInput ? "\n" + restOfInput : ""),
}
}
function slashCommand(name: string) {
return slashCommands().find((item) => item.name === name || item.aliases?.includes(`/${name}`))
}
const exit = useExit()
function pasteText(text: string, virtualText: string) {

View file

@ -314,6 +314,17 @@ export function Session() {
const dialog = useDialog()
const renderer = useRenderer()
function slashArguments(name: string) {
const input = prompt?.current.input
if (!input?.startsWith("/")) return
const firstLineEnd = input.indexOf("\n")
const firstLine = firstLineEnd === -1 ? input : input.slice(0, firstLineEnd)
const [command, ...firstLineArgs] = firstLine.split(" ")
if (command !== `/${name}`) return
const restOfInput = firstLineEnd === -1 ? "" : input.slice(firstLineEnd + 1)
return firstLineArgs.join(" ") + (restOfInput ? "\n" + restOfInput : "")
}
event.on("session.status", (evt) => {
if (evt.properties.sessionID !== route.sessionID) return
if (evt.properties.status.type !== "retry") return
@ -558,11 +569,14 @@ export function Session() {
})
return
}
void sdk.client.session.summarize({
const instructions = slashArguments("compact") ?? slashArguments("summarize")
const payload = {
sessionID: route.sessionID,
modelID: selectedModel.modelID,
providerID: selectedModel.providerID,
})
...(instructions?.trim() ? { $body_instructions: instructions.trim() } : {}),
} satisfies Parameters<typeof sdk.client.session.summarize>[0] & { $body_instructions?: string }
void sdk.client.session.summarize(payload)
dialog.clear()
},
},