From 89b3f786a0010263d48f96523ec49afe20fd77a0 Mon Sep 17 00:00:00 2001 From: Saatvik Arya Date: Fri, 5 Dec 2025 16:31:26 +0530 Subject: [PATCH] feat(tui): add dynamic terminal window title Update terminal window title reactively based on current route and session: - Show 'opencode' on home screen or for sessions with default titles - Show 'oc | {title}' for sessions with generated titles (max 40 chars) - Reset window title on exit to restore terminal defaults --- packages/opencode/src/cli/cmd/tui/app.tsx | 20 +++++++++++++++++++ .../opencode/src/cli/cmd/tui/context/exit.tsx | 2 ++ 2 files changed, 22 insertions(+) diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 3fb20f16797..bd2a233553d 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -169,6 +169,26 @@ function App() { console.log(JSON.stringify(route.data)) }) + // Update terminal window title based on current route and session + createEffect(() => { + if (route.data.type === "home") { + renderer.setTerminalTitle("opencode") + return + } + + if (route.data.type === "session") { + const session = sync.session.get(route.data.sessionID) + if (!session || SessionApi.isDefaultTitle(session.title)) { + renderer.setTerminalTitle("opencode") + return + } + + // Truncate title to 40 chars max + const title = session.title.length > 40 ? session.title.slice(0, 37) + "..." : session.title + renderer.setTerminalTitle(`oc | ${title}`) + } + }) + const args = useArgs() onMount(() => { batch(() => { diff --git a/packages/opencode/src/cli/cmd/tui/context/exit.tsx b/packages/opencode/src/cli/cmd/tui/context/exit.tsx index 3e23f718c13..414cb1a41d0 100644 --- a/packages/opencode/src/cli/cmd/tui/context/exit.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/exit.tsx @@ -7,6 +7,8 @@ export const { use: useExit, provider: ExitProvider } = createSimpleContext({ init: (input: { onExit?: () => Promise }) => { const renderer = useRenderer() return async (reason?: any) => { + // Reset window title before destroying renderer + renderer.setTerminalTitle("") renderer.destroy() await input.onExit?.() if (reason) {