diff --git a/.opencode/plugins/tui-smoke.tsx b/.opencode/plugins/tui-smoke.tsx index 220989d448..cac60db45c 100644 --- a/.opencode/plugins/tui-smoke.tsx +++ b/.opencode/plugins/tui-smoke.tsx @@ -3,14 +3,15 @@ import mytheme from "../themes/mytheme.json" with { type: "json" } const slot = (label) => ({ id: "workspace-smoke", slots: { - home_hint() { - return [plugin:{label}] + home_logo() { + return plugin logo:{label} }, - home_footer() { - return theme:workspace-plugin-smoke - }, - session_footer(_ctx, props) { - return session:{props.session_id.slice(0, 8)} + sidebar_top(_ctx, props) { + return ( + + plugin:{label} session:{props.session_id.slice(0, 8)} + + ) }, }, }) diff --git a/packages/opencode/src/cli/cmd/tui/plugin.ts b/packages/opencode/src/cli/cmd/tui/plugin.ts index 9b5d24f3a3..14bc179242 100644 --- a/packages/opencode/src/cli/cmd/tui/plugin.ts +++ b/packages/opencode/src/cli/cmd/tui/plugin.ts @@ -4,6 +4,7 @@ import { type TuiSlotContext, type TuiSlotMap, type TuiSlots, + type SlotMode, } from "@opencode-ai/plugin/tui" import { createSlot, createSolidSlotRegistry, type JSX, type SolidPlugin } from "@opentui/solid" import type { CliRenderer } from "@opentui/core" @@ -17,10 +18,29 @@ import { Instance } from "@/project/instance" import { resolvePluginTarget, uniqueModuleEntries } from "@/plugin/shared" import { registerThemes } from "./context/theme" -type Slot = (props: { name: K } & TuiSlotMap[K]) => JSX.Element | null +type SlotInput = { + name: K + mode?: SlotMode + slotMode?: SlotMode + children?: JSX.Element +} & TuiSlotMap[K] + +type SlotProps = { + name: K + mode?: SlotMode + children?: JSX.Element +} & TuiSlotMap[K] + +type Slot = (props: SlotInput) => JSX.Element | null type InitInput = Omit, "slots"> -function empty(_props: { name: K } & TuiSlotMap[K]) { +function normalize(props: SlotInput): SlotProps { + const { slotMode, ...rest } = props + if (!slotMode || rest.mode) return rest as SlotProps + return { ...rest, mode: slotMode } as SlotProps +} + +function empty(_props: SlotInput) { return null } @@ -79,7 +99,7 @@ export namespace TuiPlugin { ) const slot = createSlot(reg) - view = (props) => slot(props) + view = (props) => slot(normalize(props)) return { register(pluginSlot) { if (!isTuiSlotPlugin(pluginSlot)) return () => {} diff --git a/packages/opencode/src/cli/cmd/tui/routes/home.tsx b/packages/opencode/src/cli/cmd/tui/routes/home.tsx index 6650159535..ea3a093c1d 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/home.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/home.tsx @@ -73,7 +73,6 @@ export function Home() { - {TuiPlugin.Slot({ name: "home_hint" })} ) @@ -113,7 +112,9 @@ export function Home() { - + + + @@ -152,7 +153,6 @@ export function Home() { - {TuiPlugin.Slot({ name: "home_footer" })} {Installation.VERSION} 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 013729de03..f3b2a5c31a 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,6 @@ 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 { TuiPlugin } from "../../plugin" addDefaultParsers(parsers.parsers) @@ -1178,7 +1177,6 @@ export function Session() { }} sessionID={route.sessionID} /> - {TuiPlugin.Slot({ name: "session_footer", session_id: route.sessionID })} diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx index 42ac5fbe08..ebcc8101bc 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx @@ -11,6 +11,7 @@ import { useKeybind } from "../../context/keybind" import { useDirectory } from "../../context/directory" import { useKV } from "../../context/kv" import { TodoItem } from "../../component/todo-item" +import { TuiPlugin } from "../../plugin" export function Sidebar(props: { sessionID: string; overlay?: boolean }) { const sync = useSync() @@ -90,6 +91,7 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) { }} > + {TuiPlugin.Slot({ name: "sidebar_top", session_id: props.sessionID })} {session().title} diff --git a/packages/plugin/src/tui.ts b/packages/plugin/src/tui.ts index f8b13c10e5..13716a846b 100644 --- a/packages/plugin/src/tui.ts +++ b/packages/plugin/src/tui.ts @@ -23,9 +23,8 @@ export type ThemeJson = { } export type TuiSlotMap = { - home_hint: {} - home_footer: {} - session_footer: { + home_logo: {} + sidebar_top: { session_id: string } }