diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index ad05f12ff2..c7c2cacfe3 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -49,7 +49,7 @@ import { writeHeapSnapshot } from "v8" import { PromptRefProvider, usePromptRef } from "./context/prompt" import { TuiConfigProvider } from "./context/tui-config" import { TuiConfig } from "@/config/tui" -import type { TuiSlotContext, TuiSlotMap, TuiSlots } from "@opencode-ai/plugin" +import type { TuiSlotContext, TuiSlotMap, TuiSlots } from "@opencode-ai/plugin/tui" type TuiSlot = (props: { name: K } & TuiSlotMap[K]) => unknown diff --git a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx index 13051494cf..4ed7b632a4 100644 --- a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx @@ -1,6 +1,6 @@ import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2" import type { CliRenderer } from "@opentui/core" -import type { TuiSlots } from "@opencode-ai/plugin" +import type { TuiSlots } from "@opencode-ai/plugin/tui" import { createSimpleContext } from "./helper" import { createGlobalEmitter } from "@solid-primitives/event-bus" import { batch, onCleanup, onMount } from "solid-js" diff --git a/packages/opencode/src/cli/cmd/tui/plugin.ts b/packages/opencode/src/cli/cmd/tui/plugin.ts index 5084cc4969..0c17d5277c 100644 --- a/packages/opencode/src/cli/cmd/tui/plugin.ts +++ b/packages/opencode/src/cli/cmd/tui/plugin.ts @@ -1,9 +1,9 @@ import { - type PluginModule, type TuiPlugin as TuiPluginFn, type TuiPluginInput, + type TuiPluginModule, type TuiSlotPlugin, -} from "@opencode-ai/plugin" +} from "@opencode-ai/plugin/tui" import type { JSX } from "solid-js" import "@opentui/solid/preload" @@ -79,7 +79,7 @@ export namespace TuiPlugin { if (!mod) continue const seen = new Set() - for (const entry of Object.values(mod)) { + for (const entry of Object.values(mod)) { if (seen.has(entry)) continue seen.add(entry) diff --git a/packages/opencode/src/cli/cmd/tui/routes/home.tsx b/packages/opencode/src/cli/cmd/tui/routes/home.tsx index f74826b24c..7daccda371 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/home.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/home.tsx @@ -15,7 +15,7 @@ import { Installation } from "@/installation" import { useKV } from "../context/kv" import { useCommandDialog } from "../component/dialog-command" import { useLocal } from "../context/local" -import type { TuiSlotMap } from "@opencode-ai/plugin" +import type { TuiSlotMap } from "@opencode-ai/plugin/tui" type Slot = (props: { name: K } & TuiSlotMap[K]) => unknown diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 242ffcffd3..a461e53894 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -80,7 +80,7 @@ import { DialogExportOptions } from "../../ui/dialog-export-options" import { formatTranscript } from "../../util/transcript" import { UI } from "@/cli/ui.ts" import { useTuiConfig } from "../../context/tui-config" -import type { TuiSlotMap } from "@opencode-ai/plugin" +import type { TuiSlotMap } from "@opencode-ai/plugin/tui" addDefaultParsers(parsers.parsers) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 63a08496a1..e06ce331dd 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -10,7 +10,8 @@ }, "exports": { ".": "./src/index.ts", - "./tool": "./src/tool.ts" + "./tool": "./src/tool.ts", + "./tui": "./src/tui.ts" }, "files": [ "dist" diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index 16ce465aef..d2a75dbbbb 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -11,14 +11,10 @@ import type { Auth, Config as SDKConfig, } from "@opencode-ai/sdk" -import type { createOpencodeClient as createOpencodeClientV2, Event as TuiEvent } from "@opencode-ai/sdk/v2" -import type { CliRenderer } from "@opentui/core" - import type { BunShell } from "./shell" import { type ToolDefinition } from "./tool" export * from "./tool" -export type { CliRenderer } from "@opentui/core" export type ProviderContext = { source: "env" | "config" | "custom" | "api" @@ -41,89 +37,8 @@ export type Config = Omit & { plugin?: Array } -type HexColor = `#${string}` -type RefName = string -type Variant = { - dark: HexColor | RefName | number - light: HexColor | RefName | number -} -type ThemeColorValue = HexColor | RefName | number | Variant - -export type ThemeJson = { - $schema?: string - defs?: Record - theme: Record & { - selectedListItemText?: ThemeColorValue - backgroundMenu?: ThemeColorValue - thinkingOpacity?: number - } -} - -export type SlotMode = "append" | "replace" | "single_winner" - -type SlotRenderer = (ctx: Readonly, props: Props) => Node - -type SlotPlugin = { - id: string - order?: number - setup?: (ctx: Readonly, renderer: CliRenderer) => void - dispose?: () => void - slots: { - [K in keyof Slots]?: SlotRenderer - } -} - -export type TuiSlotMap = { - home_hint: {} - home_footer: {} - session_footer: { - session_id: string - } -} - -export type TuiSlotContext = { - url: string - directory?: string -} - -export type TuiSlotPlugin = SlotPlugin - -export type TuiSlots = { - register: (plugin: TuiSlotPlugin) => () => void -} - export type Plugin = (input: PluginInput, options?: PluginOptions) => Promise -export type TuiEventBus = { - on: ( - type: Type, - handler: (event: Extract) => void, - ) => () => void -} - -export type TuiPluginInput = { - client: ReturnType - event: TuiEventBus - url: string - directory?: string - renderer: Renderer - slots: TuiSlots -} - -export type TuiPlugin = ( - input: TuiPluginInput, - options?: PluginOptions, -) => Promise - -export type PluginModule = - | Plugin - | { - server?: Plugin - tui?: TuiPlugin - slots?: TuiSlotPlugin - themes?: Record - } - export type AuthHook = { provider: string loader?: (auth: () => Promise, provider: Provider) => Promise> diff --git a/packages/plugin/src/tui.ts b/packages/plugin/src/tui.ts new file mode 100644 index 0000000000..bbcbce2961 --- /dev/null +++ b/packages/plugin/src/tui.ts @@ -0,0 +1,86 @@ +import type { createOpencodeClient as createOpencodeClientV2, Event as TuiEvent } from "@opencode-ai/sdk/v2" +import type { CliRenderer } from "@opentui/core" +import type { Plugin, PluginOptions } from "./index" + +export type { CliRenderer } from "@opentui/core" + +type HexColor = `#${string}` +type RefName = string +type Variant = { + dark: HexColor | RefName | number + light: HexColor | RefName | number +} +type ThemeColorValue = HexColor | RefName | number | Variant + +export type ThemeJson = { + $schema?: string + defs?: Record + theme: Record & { + selectedListItemText?: ThemeColorValue + backgroundMenu?: ThemeColorValue + thinkingOpacity?: number + } +} + +export type SlotMode = "append" | "replace" | "single_winner" + +type SlotRenderer = (ctx: Readonly, props: Props) => Node + +type SlotPlugin = { + id: string + order?: number + setup?: (ctx: Readonly, renderer: CliRenderer) => void + dispose?: () => void + slots: { + [K in keyof Slots]?: SlotRenderer + } +} + +export type TuiSlotMap = { + home_hint: {} + home_footer: {} + session_footer: { + session_id: string + } +} + +export type TuiSlotContext = { + url: string + directory?: string +} + +export type TuiSlotPlugin = SlotPlugin + +export type TuiSlots = { + register: (plugin: TuiSlotPlugin) => () => void +} + +export type TuiEventBus = { + on: ( + type: Type, + handler: (event: Extract) => void, + ) => () => void +} + +export type TuiPluginInput = { + client: ReturnType + event: TuiEventBus + url: string + directory?: string + renderer: Renderer + slots: TuiSlots +} + +export type TuiPlugin = ( + input: TuiPluginInput, + options?: PluginOptions, +) => Promise + +export type TuiPluginModule = + | TuiPlugin + | { + server?: Plugin + tui?: TuiPlugin + slots?: TuiSlotPlugin + themes?: Record + }