From 29f7dc073bc23fddcb517569d8a61ca8bb5e2c1c Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 2 Apr 2026 22:11:17 +0200 Subject: Adds TUI prompt traits, refs, and plugin slots (#20741) --- packages/plugin/package.json | 8 ++--- packages/plugin/src/tui.ts | 77 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 76 insertions(+), 9 deletions(-) (limited to 'packages/plugin') diff --git a/packages/plugin/package.json b/packages/plugin/package.json index e81385688..e1cde0fd7 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -21,8 +21,8 @@ "zod": "catalog:" }, "peerDependencies": { - "@opentui/core": ">=0.1.95", - "@opentui/solid": ">=0.1.95" + "@opentui/core": ">=0.1.96", + "@opentui/solid": ">=0.1.96" }, "peerDependenciesMeta": { "@opentui/core": { @@ -33,8 +33,8 @@ } }, "devDependencies": { - "@opentui/core": "0.1.95", - "@opentui/solid": "0.1.95", + "@opentui/core": "0.1.96", + "@opentui/solid": "0.1.96", "@tsconfig/node22": "catalog:", "@types/node": "catalog:", "typescript": "catalog:", diff --git a/packages/plugin/src/tui.ts b/packages/plugin/src/tui.ts index b082f6abe..27b59b8d5 100644 --- a/packages/plugin/src/tui.ts +++ b/packages/plugin/src/tui.ts @@ -1,6 +1,8 @@ import type { + AgentPart, OpencodeClient, Event, + FilePart, LspStatus, McpStatus, Todo, @@ -10,10 +12,11 @@ import type { PermissionRequest, QuestionRequest, SessionStatus, + TextPart, Workspace, Config as SdkConfig, } from "@opencode-ai/sdk/v2" -import type { CliRenderer, ParsedKey, RGBA } from "@opentui/core" +import type { CliRenderer, ParsedKey, RGBA, SlotMode } from "@opentui/core" import type { JSX, SolidPlugin } from "@opentui/solid" import type { Config as PluginConfig, PluginOptions } from "./index.js" @@ -135,12 +138,43 @@ export type TuiDialogSelectProps = { current?: Value } +export type TuiPromptInfo = { + input: string + mode?: "normal" | "shell" + parts: ( + | Omit + | Omit + | (Omit & { + source?: { + text: { + start: number + end: number + value: string + } + } + }) + )[] +} + +export type TuiPromptRef = { + focused: boolean + current: TuiPromptInfo + set(prompt: TuiPromptInfo): void + reset(): void + blur(): void + focus(): void + submit(): void +} + export type TuiPromptProps = { + sessionID?: string workspaceID?: string visible?: boolean disabled?: boolean onSubmit?: () => void + ref?: (ref: TuiPromptRef | undefined) => void hint?: JSX.Element + right?: JSX.Element showPlaceholder?: boolean placeholders?: { normal?: string[] @@ -289,11 +323,25 @@ export type TuiSidebarFileItem = { deletions: number } -export type TuiSlotMap = { +export type TuiHostSlotMap = { app: {} home_logo: {} home_prompt: { workspace_id?: string + ref?: (ref: TuiPromptRef | undefined) => void + } + home_prompt_right: { + workspace_id?: string + } + session_prompt: { + session_id: string + visible?: boolean + disabled?: boolean + on_submit?: () => void + ref?: (ref: TuiPromptRef | undefined) => void + } + session_prompt_right: { + session_id: string } home_bottom: {} home_footer: {} @@ -310,18 +358,35 @@ export type TuiSlotMap = { } } +export type TuiSlotMap = {}> = TuiHostSlotMap & Slots + +type TuiSlotShape> = Name extends keyof TuiHostSlotMap + ? TuiHostSlotMap[Name] + : Name extends keyof Slots + ? Slots[Name] + : Record + +export type TuiSlotProps = {}> = { + name: Name + mode?: SlotMode + children?: JSX.Element +} & TuiSlotShape + export type TuiSlotContext = { theme: TuiTheme } -type SlotCore = SolidPlugin +type SlotCore = {}> = SolidPlugin, TuiSlotContext> -export type TuiSlotPlugin = Omit & { +export type TuiSlotPlugin = {}> = Omit, "id"> & { id?: never } export type TuiSlots = { - register: (plugin: TuiSlotPlugin) => string + register: { + (plugin: TuiSlotPlugin): string + >(plugin: TuiSlotPlugin): string + } } export type TuiEventBus = { @@ -391,6 +456,7 @@ export type TuiPluginApi = { command: { register: (cb: () => TuiCommand[]) => () => void trigger: (value: string) => void + show: () => void } route: { register: (routes: TuiRouteDefinition[]) => () => void @@ -403,6 +469,7 @@ export type TuiPluginApi = { DialogConfirm: (props: TuiDialogConfirmProps) => JSX.Element DialogPrompt: (props: TuiDialogPromptProps) => JSX.Element DialogSelect: (props: TuiDialogSelectProps) => JSX.Element + Slot: (props: TuiSlotProps) => JSX.Element | null Prompt: (props: TuiPromptProps) => JSX.Element toast: (input: TuiToast) => void dialog: TuiDialogStack -- cgit v1.2.3