From 22a34d7958da382e3e11fcf51bd1400e76a230e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Haris=20Gu=C5=A1i=C4=87?= Date: Sat, 1 Nov 2025 17:13:10 +0100 Subject: [PATCH] feat: tui: Port /exit command and all command aliases (#3665) --- packages/opencode/src/cli/cmd/tui/app.tsx | 9 ++++++++- .../cli/cmd/tui/component/prompt/autocomplete.tsx | 12 +++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 0399a1c8..fee65414 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -23,7 +23,7 @@ import { Session } from "@tui/routes/session" import { PromptHistoryProvider } from "./component/prompt/history" import { DialogAlert } from "./ui/dialog-alert" import { ToastProvider, useToast } from "./ui/toast" -import { ExitProvider } from "./context/exit" +import { ExitProvider, useExit } from "./context/exit" import type { SessionRoute } from "./context/route" import { Session as SessionApi } from "@/session" import { TuiEvent } from "./event" @@ -110,6 +110,7 @@ function App() { const toast = useToast() const [sessionExists, setSessionExists] = createSignal(false) const { theme } = useTheme() + const exit = useExit() useKeyboard(async (evt) => { if (evt.meta && evt.name === "t") { @@ -245,6 +246,12 @@ function App() { }, category: "System", }, + { + title: "Exit the app", + value: "app.exit", + onSelect: exit, + category: "System", + } ]) createEffect(() => { diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx index ed46042b..2750efbe 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx @@ -18,6 +18,7 @@ export type AutocompleteRef = { export type AutocompleteOption = { display: string + aliases?: string[] disabled?: boolean description?: string onSelect?: () => void @@ -207,6 +208,7 @@ export function Autocomplete(props: { }, { display: "/compact", + aliases: ["/summarize"], description: "compact the session", onSelect: () => command.trigger("session.compact"), }, @@ -232,6 +234,7 @@ export function Autocomplete(props: { results.push( { display: "/new", + aliases: ["/clear"], description: "create a new session", onSelect: () => command.trigger("session.new"), }, @@ -247,6 +250,7 @@ export function Autocomplete(props: { }, { display: "/session", + aliases: ["/resume", "/continue"], description: "list sessions", onSelect: () => command.trigger("session.list"), }, @@ -275,6 +279,12 @@ export function Autocomplete(props: { description: "show all commands", onSelect: () => command.show(), }, + { + display: "/exit", + aliases: ["/quit", "/q"], + description: "exit the app", + onSelect: () => command.trigger("app.exit"), + }, ) const max = firstBy(results, [(x) => x.display.length, "desc"])?.display.length if (!max) return results @@ -293,7 +303,7 @@ export function Autocomplete(props: { const currentFilter = filter() if (!currentFilter) return mixed.slice(0, 10) const result = fuzzysort.go(currentFilter, mixed, { - keys: ["display", "description"], + keys: ["display", "description", (obj) => obj.aliases?.join(" ") ?? ""], limit: 10, }) return result.map((arr) => arr.obj)