From 48a7685db64ee9c19b8bacf4bedbf0f62f71ab0a Mon Sep 17 00:00:00 2001 From: James Long Date: Wed, 1 Jul 2026 14:34:23 -0400 Subject: [PATCH] feat(tui): wire simulation control server --- packages/opencode/specs/simulation-phases.md | 4 ++-- packages/tui/src/app.tsx | 11 +++++++++++ .../src/testing => tui/src}/simulation/actions.ts | 0 .../src/testing => tui/src}/simulation/server.ts | 0 .../src/testing => tui/src}/simulation/trace.ts | 0 5 files changed, 13 insertions(+), 2 deletions(-) rename packages/{opencode/src/testing => tui/src}/simulation/actions.ts (100%) rename packages/{opencode/src/testing => tui/src}/simulation/server.ts (100%) rename packages/{opencode/src/testing => tui/src}/simulation/trace.ts (100%) diff --git a/packages/opencode/specs/simulation-phases.md b/packages/opencode/specs/simulation-phases.md index 2d715e0a56..e564282939 100644 --- a/packages/opencode/specs/simulation-phases.md +++ b/packages/opencode/specs/simulation-phases.md @@ -12,14 +12,14 @@ This phase proves the core shape without swapping every foundational layer yet. Implementation checklist: -- [ ] Add `OPENCODE_SIMULATION=1` activation in V1/full-TUI startup. +- [x] Add `OPENCODE_SIMULATION=1` activation in V1/full-TUI startup. - [x] Add simulation trace service with in-memory append-only records. - [x] Add OpenTUI UI state extraction for screen, focus, elements, and generated actions. - [x] Add OpenTUI UI action execution for typing, keys, enter, arrows, focus, and click. - [x] Add reusable JSON-RPC WebSocket server on `127.0.0.1:40900+`. - [x] Expose `ui.state`, `ui.action`, `ui.render`. - [x] Expose `trace.list`, `trace.clear`, `trace.export`. -- [ ] Wire fake and visible V1/full-TUI renderer paths through the same action protocol. +- [x] Wire visible V1/full-TUI renderer path through the same action protocol. - [ ] Verify a local driver can inspect state and execute a real TUI input. Scope: diff --git a/packages/tui/src/app.tsx b/packages/tui/src/app.tsx index 32c7d4a880..c274eb73fa 100644 --- a/packages/tui/src/app.tsx +++ b/packages/tui/src/app.tsx @@ -230,6 +230,17 @@ export const run = Effect.fn("Tui.run")(function* (input: TuiInput) { renderer.once("destroy", () => Deferred.doneUnsafe(shutdown, Effect.void)) const pluginRuntime = createPluginRuntime() + const simulation = yield* Effect.promise(async () => { + if (process.env.OPENCODE_SIMULATION !== "1" && process.env.OPENCODE_SIMULATION !== "true") return + const { SimulationActions } = await import("./simulation/actions") + const { SimulationServer } = await import("./simulation/server") + return SimulationServer.start(SimulationActions.createHarness(renderer)) + }) + if (simulation) { + process.stderr.write(`opencode simulation websocket: ${simulation.url}\n`) + yield* Effect.addFinalizer(() => Effect.sync(() => simulation.stop())) + } + yield* Effect.tryPromise(async () => { // Prewarm palette before ThemeProvider mounts so `system` theme avoids a first-paint fallback flash. void renderer.getPalette({ size: 16 }).catch(() => undefined) diff --git a/packages/opencode/src/testing/simulation/actions.ts b/packages/tui/src/simulation/actions.ts similarity index 100% rename from packages/opencode/src/testing/simulation/actions.ts rename to packages/tui/src/simulation/actions.ts diff --git a/packages/opencode/src/testing/simulation/server.ts b/packages/tui/src/simulation/server.ts similarity index 100% rename from packages/opencode/src/testing/simulation/server.ts rename to packages/tui/src/simulation/server.ts diff --git a/packages/opencode/src/testing/simulation/trace.ts b/packages/tui/src/simulation/trace.ts similarity index 100% rename from packages/opencode/src/testing/simulation/trace.ts rename to packages/tui/src/simulation/trace.ts