summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax <[email protected]>2026-02-02 00:13:47 -0500
committerGitHub <[email protected]>2026-02-02 00:13:47 -0500
commit7a9290dc9b24f8fd905d68143a17528e708a9fe4 (patch)
tree93779e5fff285ec97253d6b9cb0938a2f11a8ae7
parentcfbe9d329f50126fa6d7cca3c25e43c48f96adc3 (diff)
downloadopencode-7a9290dc9b24f8fd905d68143a17528e708a9fe4.tar.gz
opencode-7a9290dc9b24f8fd905d68143a17528e708a9fe4.zip
tui: show exit message banner (#11733)
-rw-r--r--packages/opencode/src/cli/cmd/tui/context/exit.tsx51
-rw-r--r--packages/opencode/src/cli/cmd/tui/routes/session/index.tsx13
2 files changed, 53 insertions, 11 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/context/exit.tsx b/packages/opencode/src/cli/cmd/tui/context/exit.tsx
index 414cb1a41..2aac15220 100644
--- a/packages/opencode/src/cli/cmd/tui/context/exit.tsx
+++ b/packages/opencode/src/cli/cmd/tui/context/exit.tsx
@@ -1,23 +1,52 @@
import { useRenderer } from "@opentui/solid"
import { createSimpleContext } from "./helper"
import { FormatError, FormatUnknownError } from "@/cli/error"
+type Exit = ((reason?: unknown) => Promise<void>) & {
+ message: {
+ set: (value?: string) => () => void
+ clear: () => void
+ get: () => string | undefined
+ }
+}
export const { use: useExit, provider: ExitProvider } = createSimpleContext({
name: "Exit",
init: (input: { onExit?: () => Promise<void> }) => {
const renderer = useRenderer()
- return async (reason?: any) => {
- // Reset window title before destroying renderer
- renderer.setTerminalTitle("")
- renderer.destroy()
- await input.onExit?.()
- if (reason) {
- const formatted = FormatError(reason) ?? FormatUnknownError(reason)
- if (formatted) {
- process.stderr.write(formatted + "\n")
+ let message: string | undefined
+ const store = {
+ set: (value?: string) => {
+ const prev = message
+ message = value
+ return () => {
+ message = prev
}
- }
- process.exit(0)
+ },
+ clear: () => {
+ message = undefined
+ },
+ get: () => message,
}
+ const exit: Exit = Object.assign(
+ async (reason?: unknown) => {
+ // Reset window title before destroying renderer
+ renderer.setTerminalTitle("")
+ renderer.destroy()
+ await input.onExit?.()
+ if (reason) {
+ const formatted = FormatError(reason) ?? FormatUnknownError(reason)
+ if (formatted) {
+ process.stderr.write(formatted + "\n")
+ }
+ }
+ const text = store.get()
+ if (text) process.stdout.write(text + "\n")
+ process.exit(0)
+ },
+ {
+ message: store,
+ },
+ )
+ return exit
},
})
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
index 8316d112c..f7d83b055 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -77,6 +77,7 @@ import { PermissionPrompt } from "./permission"
import { QuestionPrompt } from "./question"
import { DialogExportOptions } from "../../ui/dialog-export-options"
import { formatTranscript } from "../../util/transcript"
+import { UI } from "@/cli/ui.ts"
addDefaultParsers(parsers.parsers)
@@ -222,6 +223,18 @@ export function Session() {
// Allow exit when in child session (prompt is hidden)
const exit = useExit()
+
+ createEffect(() => {
+ return exit.message.set(
+ [
+ ``,
+ ` █▀▀█ ${UI.Style.TEXT_DIM}${session()?.title}${UI.Style.TEXT_NORMAL}`,
+ ` █ █ ${UI.Style.TEXT_DIM}opencode -s ${session()?.id}${UI.Style.TEXT_NORMAL}`,
+ ` ▀▀▀▀ `,
+ ].join("\n"),
+ )
+ })
+
useKeyboard((evt) => {
if (!session()?.parentID) return
if (keybind.match("app_exit", evt)) {