opencode/packages/simulation/src/frontend/simulation.ts

27 lines
1.3 KiB
TypeScript

import { createCliRenderer, type CliRendererConfig } from "@opentui/core"
import { Config, Effect } from "effect"
import { DriveManifest } from "../manifest"
import { SimulationActions } from "./actions"
import { SimulationRenderer } from "./renderer"
import { SimulationServer } from "./server"
/** Drive-mode renderer and control-server acquisition. */
export const create = Effect.fn("Drive.create")(function* (options: CliRendererConfig, version: string) {
const headless = (yield* Config.string("OPENCODE_DRIVE_RENDERER").pipe(Config.withDefault("visible"))) === "headless"
const manifest = yield* DriveManifest.resolve()
const renderer = headless
? yield* SimulationRenderer.create(options, manifest.recording?.timeline, manifest.viewport)
: yield* Effect.acquireRelease(
Effect.tryPromise(() => createCliRenderer(options)),
(renderer) =>
Effect.sync(() => {
if (!renderer.isDestroyed) renderer.destroy()
}),
)
if (!headless && manifest.viewport) renderer.resize(manifest.viewport.cols, manifest.viewport.rows)
const server = yield* SimulationServer.start(SimulationActions.createHarness(renderer), manifest.endpoints.ui, version)
yield* Effect.sync(() => process.stderr.write(`opencode drive ui websocket: ${server.url}\n`))
return renderer
})
export * as Drive from "./simulation"