import type { TuiPluginApi, TuiPluginInstallOptions, TuiPluginInstallResult, TuiPluginStatus, } from "@opencode-ai/plugin/tui" import { createContext, createSignal, useContext, type JSX, type ParentProps } from "solid-js" import { createPluginRoutes } from "./api" import { createSlots, type HostSlots } from "./slots" export function createPluginRuntime() { const [commands, setCommands] = createSignal(emptyCommands) const [status, setStatus] = createSignal>([]) const slots = createSlots() return { Slot: slots.Slot, routes: createPluginRoutes(), commands, status, update(input: { commands?: PluginRuntimeCommands; status?: ReadonlyArray }) { if (input.commands) setCommands(input.commands) if (input.status) setStatus(input.status) }, clear() { setCommands(emptyCommands) setStatus([]) slots.clear() }, setupSlots(api: TuiPluginApi): HostSlots { return slots.setup(api) }, } } export type PluginRuntimeCommands = { activate: (id: string) => Promise deactivate: (id: string) => Promise add: (spec: string) => Promise install: (spec: string, options?: TuiPluginInstallOptions) => Promise } const emptyCommands: PluginRuntimeCommands = { async activate() { return false }, async deactivate() { return false }, async add() { return false }, async install() { return { ok: false, message: "Plugin runtime is not available." } }, } export type PluginRuntime = ReturnType export type TuiPluginHost = { start(input: { api: TuiPluginApi config: any runtime: PluginRuntime dispose?: () => void }): Promise dispose(): Promise } const Context = createContext() export function PluginRuntimeProvider(props: ParentProps<{ value: PluginRuntime }>): JSX.Element { return {props.children} } export function usePluginRuntime() { const runtime = useContext(Context) if (!runtime) throw new Error("usePluginRuntime must be used within PluginRuntimeProvider") return runtime }