diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 833c8dc8c3..3644cafa6a 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -117,11 +117,15 @@ export function tui(input: { headers?: RequestInit["headers"] events?: EventSource }) { - // promise to prevent immediate exit - // oxlint-disable-next-line no-async-promise-executor -- intentional: async executor used for sequential setup before resolve - return new Promise(async (resolve) => { + return new Promise((resolve, reject) => { const unguard = win32InstallCtrlCGuard() - win32DisableProcessedInput() + let renderer: Awaited> | undefined + const fail = (error: unknown) => { + renderer?.destroy() + renderer = undefined + unguard?.() + reject(error) + } const onExit = async () => { unguard?.() @@ -132,73 +136,77 @@ export function tui(input: { await TuiPluginRuntime.dispose() } - const renderer = await createCliRenderer(rendererConfig(input.config)) - const mode = (await renderer.waitForThemeMode(1000)) ?? "dark" + void (async () => { + win32DisableProcessedInput() - await render(() => { - return ( - ( - - )} - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ) - }, renderer) + renderer = await createCliRenderer(rendererConfig(input.config)) + const mode = (await renderer.waitForThemeMode(1000)) ?? "dark" + + await render(() => { + return ( + ( + + )} + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + }, renderer) + })().catch(fail) }) }