diff --git a/packages/tui/src/app.tsx b/packages/tui/src/app.tsx index 4d4959dcc1..7aff0f8d79 100644 --- a/packages/tui/src/app.tsx +++ b/packages/tui/src/app.tsx @@ -8,7 +8,7 @@ import { ClipboardProvider, useClipboard } from "./context/clipboard" import { ExitProvider, useExit } from "./context/exit" import { EpilogueProvider } from "./context/epilogue" import * as Selection from "./util/selection" -import { createCliRenderer, MouseButton } from "@opentui/core" +import { createCliRenderer, MouseButton, type CliRendererConfig } from "@opentui/core" import { RouteProvider, useRoute } from "./context/route" import { Switch, @@ -185,12 +185,7 @@ export const run = Effect.fn("Tui.run")(function* (input: TuiInput) { const renderer = yield* Effect.acquireRelease( Effect.tryPromise({ try: async () => { - if (process.env.OPENCODE_SIMULATION === "1" || process.env.OPENCODE_SIMULATION === "true") { - const { Simulation } = await import("./simulation/simulation") - return Simulation.createSimulation() - } - - return createCliRenderer({ + const options = { externalOutputMode: "passthrough", targetFps: 60, gatherStats: false, @@ -202,7 +197,14 @@ export const run = Effect.fn("Tui.run")(function* (input: TuiInput) { consoleOptions: { keyBindings: [{ name: "y", ctrl: true, action: "copy-selection" }], }, - }) + } satisfies CliRendererConfig + + if (process.env.OPENCODE_SIMULATION === "1" || process.env.OPENCODE_SIMULATION === "true") { + const { Simulation } = await import("./simulation/simulation") + return Simulation.createSimulation(options) + } + + return createCliRenderer(options) }, catch: (error) => (error instanceof Error ? error : new Error(String(error))), }), diff --git a/packages/tui/src/simulation/renderer.ts b/packages/tui/src/simulation/renderer.ts index b59f3c9826..03e182cadc 100644 --- a/packages/tui/src/simulation/renderer.ts +++ b/packages/tui/src/simulation/renderer.ts @@ -1,4 +1,4 @@ -import type { CliRenderer } from "@opentui/core" +import type { CliRenderer, CliRendererConfig } from "@opentui/core" import { createTestRenderer, type TestRendererSetup } from "@opentui/core/testing" const setups = new WeakMap() @@ -9,8 +9,9 @@ const setups = new WeakMap() * kept module-side (keyed by renderer) so the harness can use the supported * testing APIs without app code carrying it around. */ -export async function create(): Promise { +export async function create(options: CliRendererConfig): Promise { const setup = await createTestRenderer({ + ...options, width: Number(process.env.OPENCODE_SIMULATION_TUI_WIDTH) || 100, height: Number(process.env.OPENCODE_SIMULATION_TUI_HEIGHT) || 40, }) diff --git a/packages/tui/src/simulation/simulation.ts b/packages/tui/src/simulation/simulation.ts index b677b7f092..ff24e0459d 100644 --- a/packages/tui/src/simulation/simulation.ts +++ b/packages/tui/src/simulation/simulation.ts @@ -1,4 +1,4 @@ -import { createCliRenderer, type CliRenderer } from "@opentui/core" +import { createCliRenderer, type CliRenderer, type CliRendererConfig } from "@opentui/core" import { SimulationActions } from "./actions" import { SimulationRenderer } from "./renderer" import { SimulationServer } from "./server" @@ -6,24 +6,16 @@ import { SimulationServer } from "./server" /** * Simulation-mode renderer entry point. * - * Creates the renderer (fake when OPENCODE_SIMULATION_RENDERER=fake, a - * visible terminal renderer otherwise) and starts the simulation control + * Creates the renderer (fake when OPENCODE_SIMULATION_RENDERER=fake, the + * normal visible renderer otherwise) and starts the simulation control * server against it. The server stops when the renderer is destroyed, so the * caller only manages the renderer lifecycle. */ -export async function createSimulation(): Promise { +export async function createSimulation(options: CliRendererConfig): Promise { const renderer = process.env.OPENCODE_SIMULATION_RENDERER === "fake" - ? await SimulationRenderer.create() - : await createCliRenderer({ - externalOutputMode: "passthrough", - targetFps: 60, - gatherStats: false, - exitOnCtrlC: false, - useKittyKeyboard: {}, - autoFocus: false, - openConsoleOnError: false, - }) + ? await SimulationRenderer.create(options) + : await createCliRenderer(options) const server = SimulationServer.start(SimulationActions.createHarness(renderer)) if (server) { process.stderr.write(`opencode simulation websocket: ${server.url}\n`)