From 3cc33e39e7523e920522f9c802a7e49c6e75f5d0 Mon Sep 17 00:00:00 2001 From: Sebastian Herrlinger Date: Wed, 4 Mar 2026 23:30:05 +0100 Subject: [PATCH] cleanup sdk --- packages/opencode/src/cli/cmd/tui/app.tsx | 9 +++-- .../opencode/src/cli/cmd/tui/context/sdk.tsx | 11 ------ packages/opencode/src/cli/cmd/tui/plugin.ts | 34 +++++++++++-------- .../test/cli/tui/plugin-loader.test.ts | 4 ++- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 676165deb4..9cfda07852 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -150,7 +150,6 @@ export function tui(input: { } const renderer = await createCliRenderer(rendererConfig(input.config)) - TuiPlugin.initializeSlots(renderer) await render(() => { return ( @@ -165,7 +164,6 @@ export function tui(input: { { + console.error("Failed to load TUI plugins", error) + }) const toast = useToast() const { theme, mode, setMode } = useTheme() const sync = useSync() diff --git a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx index 8f87321619..2403a4e938 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx @@ -1,9 +1,7 @@ import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2" -import type { CliRenderer } from "@opentui/core" import { createSimpleContext } from "./helper" import { createGlobalEmitter } from "@solid-primitives/event-bus" import { batch, onCleanup, onMount } from "solid-js" -import { TuiPlugin } from "../plugin" export type EventSource = { on: (handler: (event: Event) => void) => () => void @@ -14,7 +12,6 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({ name: "SDK", init: (props: { url: string - renderer: CliRenderer directory?: string fetch?: typeof fetch headers?: RequestInit["headers"] @@ -41,14 +38,6 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({ [key in Event["type"]]: Extract }>() - TuiPlugin.init({ - client: sdk, - event: emitter, - renderer: props.renderer, - }).catch((error) => { - console.error("Failed to load TUI plugins", error) - }) - let queue: Event[] = [] let timer: Timer | undefined let last = 0 diff --git a/packages/opencode/src/cli/cmd/tui/plugin.ts b/packages/opencode/src/cli/cmd/tui/plugin.ts index 6049ed7a46..ceae72c43c 100644 --- a/packages/opencode/src/cli/cmd/tui/plugin.ts +++ b/packages/opencode/src/cli/cmd/tui/plugin.ts @@ -54,19 +54,24 @@ function getTuiPlugin(value: unknown) { return value.tui } +function isCliRenderer(value: unknown): value is CliRenderer { + if (!isRecord(value)) return false + if (!("once" in value)) return false + return typeof value.once === "function" +} + export namespace TuiPlugin { const log = Log.create({ service: "tui.plugin" }) let loaded: Promise | undefined let view: Slot = empty - let api: TuiSlots = { - register() { - return () => {} - }, - } export const Slot: Slot = (props) => view(props) - export function initializeSlots(renderer: CliRenderer) { + function setupSlots(renderer: unknown): TuiSlots { + if (!isCliRenderer(renderer)) { + throw new TypeError("Invalid TUI renderer") + } + const reg = createSolidSlotRegistry( renderer, {}, @@ -85,7 +90,7 @@ export namespace TuiPlugin { const slot = createSlot(reg) view = (props) => slot(props) - api = { + return { register(pluginSlot) { if (!isTuiSlotPlugin(pluginSlot)) return () => {} return reg.register(pluginSlot) @@ -95,16 +100,15 @@ export namespace TuiPlugin { export async function init(input: InitInput) { if (loaded) return loaded - loaded = load(input) + loaded = load({ + ...input, + slots: setupSlots(input.renderer), + }) return loaded } - async function load(input: InitInput) { + async function load(input: TuiPluginInput) { const dir = process.cwd() - const ctx: TuiPluginInput = { - ...input, - slots: api, - } await Instance.provide({ directory: dir, @@ -142,11 +146,11 @@ export namespace TuiPlugin { if (theme) registerThemes(theme) const slotPlugin = getTuiSlotPlugin(entry) - if (slotPlugin) ctx.slots.register(slotPlugin) + if (slotPlugin) input.slots.register(slotPlugin) const tuiPlugin = getTuiPlugin(entry) if (!tuiPlugin) continue - await tuiPlugin(ctx, Config.pluginOptions(item)) + await tuiPlugin(input, Config.pluginOptions(item)) } } }, diff --git a/packages/opencode/test/cli/tui/plugin-loader.test.ts b/packages/opencode/test/cli/tui/plugin-loader.test.ts index d1c8107f8a..a57993a3c0 100644 --- a/packages/opencode/test/cli/tui/plugin-loader.test.ts +++ b/packages/opencode/test/cli/tui/plugin-loader.test.ts @@ -88,7 +88,9 @@ test("ignores function-only tui exports and loads object exports", async () => { event: { on: () => () => {}, }, - renderer: {}, + renderer: { + once: () => undefined, + }, }) expect(await fs.readFile(tmp.extra.objMarker, "utf8")).toBe("called")