diff --git a/packages/opencode/src/cli/cmd/tui/feature-plugins/activity-bar/index.tsx b/packages/opencode/src/cli/cmd/tui/feature-plugins/activity-bar/index.tsx new file mode 100644 index 00000000..8ad68a8e --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/feature-plugins/activity-bar/index.tsx @@ -0,0 +1,84 @@ +import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@mimo-ai/plugin/tui" +import { For, Show, createMemo } from "solid-js" +import { PANELS, getPanelComponent } from "./panels" + +const id = "activity-bar-panels" + +function ActivityBarIcons(props: { + api: TuiPluginApi + session_id: string + active_panels: string[] + on_toggle: (panel_id: string) => void +}) { + const theme = () => props.api.theme.current + const isActive = (id: string) => props.active_panels.includes(id) + + return ( + + {(panel) => ( + props.on_toggle(panel.id)} + > + + {panel.icon} + + + )} + + ) +} + +function SidebarPanelContent(props: { + api: TuiPluginApi + session_id: string + panel_id: string +}) { + const panelDef = getPanelComponent(props.panel_id) + if (!panelDef) return null + + return ( + + {panelDef.component(props.api, props.session_id)} + + ) +} + +const tui: TuiPlugin = async (api) => { + api.slots.register({ + order: 100, + slots: { + activity_bar(_ctx, props) { + return ( + + ) + }, + sidebar_panel(_ctx, props) { + return ( + + ) + }, + }, + }) +} + +const plugin: TuiPluginModule & { id: string } = { + id, + tui, +} + +export default plugin diff --git a/packages/opencode/src/cli/cmd/tui/feature-plugins/activity-bar/panels.tsx b/packages/opencode/src/cli/cmd/tui/feature-plugins/activity-bar/panels.tsx new file mode 100644 index 00000000..512b653e --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/feature-plugins/activity-bar/panels.tsx @@ -0,0 +1,128 @@ +import type { TuiPluginApi } from "@mimo-ai/plugin/tui" +import { createMemo, For, Show } from "solid-js" + +interface PanelDef { + id: string + icon: string + label: string + component: (api: TuiPluginApi, session_id: string) => any +} + +function FileExplorerPanel(api: TuiPluginApi, session_id: string) { + const theme = () => api.theme.current + const files = createMemo(() => api.state.session.diff(session_id)) + + return ( + + File Explorer + 0}> + + {(file) => ( + + {file.file} + + +{file.additions} + + + -{file.deletions} + + + )} + + + + ) +} + +function TasksPanel(api: TuiPluginApi, session_id: string) { + const theme = () => api.theme.current + const tasks = createMemo(() => api.state.session.task(session_id)) + + return ( + + Tasks + 0}> + + {(task) => ( + + {task.summary || "Untitled"} + {task.status} {task.id} + + )} + + + + ) +} + +function TodoPanel(api: TuiPluginApi, session_id: string) { + const theme = () => api.theme.current + const todos = createMemo(() => api.state.session.todo(session_id)) + + return ( + + Todo + 0}> + + {(todo) => ( + + {todo.status === "completed" ? "✓" : "○"} {todo.content} + + )} + + + + ) +} + +function McpPanel(api: TuiPluginApi, session_id: string) { + const theme = () => api.theme.current + const mcp = createMemo(() => api.state.mcp()) + + return ( + + MCP Servers + 0}> + + {(server) => ( + + {server.status === "connected" ? "●" : "○"} {server.name} + + )} + + + + ) +} + +function LspPanel(api: TuiPluginApi, session_id: string) { + const theme = () => api.theme.current + const lsp = createMemo(() => api.state.lsp()) + + return ( + + LSP Servers + 0}> + + {(server) => ( + + {server.status === "connected" ? "●" : "○"} {server.id} + + )} + + + + ) +} + +export const PANELS: PanelDef[] = [ + { id: "files", icon: " ", label: "File Explorer", component: FileExplorerPanel }, + { id: "tasks", icon: " ", label: "Tasks", component: TasksPanel }, + { id: "todo", icon: "✓", label: "Todo", component: TodoPanel }, + { id: "mcp", icon: " ", label: "MCP Servers", component: McpPanel }, + { id: "lsp", icon: " ", label: "LSP Servers", component: LspPanel }, +] + +export function getPanelComponent(id: string): PanelDef | undefined { + return PANELS.find(p => p.id === id) +} diff --git a/packages/opencode/src/cli/cmd/tui/feature-plugins/sidebar/panels.tsx b/packages/opencode/src/cli/cmd/tui/feature-plugins/sidebar/panels.tsx new file mode 100644 index 00000000..05e7789c --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/feature-plugins/sidebar/panels.tsx @@ -0,0 +1,132 @@ +import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@mimo-ai/plugin/tui" +import { createMemo, For, Show, createSignal } from "solid-js" + +const id = "mimocode-sidebar-panels" + +interface PanelDef { + id: string + icon: string + label: string +} + +const PANELS: PanelDef[] = [ + { id: "files", icon: " ", label: "File Explorer" }, + { id: "skills", icon: "⚡", label: "Skills" }, + { id: "plugins", icon: " ", label: "Plugins" }, + { id: "sessions", icon: " ", label: "Sessions" }, + { id: "model", icon: " ", label: "Model" }, +] + +function PanelSection(props: { + api: TuiPluginApi + panel: PanelDef + session_id: string +}) { + const [open, setOpen] = createSignal(true) + const theme = () => props.api.theme.current + + const content = createMemo(() => { + switch (props.panel.id) { + case "files": + return props.api.state.session.diff(props.session_id) + case "skills": + return props.api.state.session.skill?.() ?? [] + case "plugins": + return props.api.state.session.plugin?.() ?? [] + case "sessions": + return Object.values(props.api.state.session ?? {}) + case "model": + return props.api.state.session.model?.() ?? [] + default: + return [] + } + }) + + const hasContent = createMemo(() => { + const c = content() + return Array.isArray(c) ? c.length > 0 : !!c + }) + + return ( + + + setOpen((x) => !x)} + > + {open() ? "▼" : "▶"} + + {props.panel.icon} {props.panel.label} + + + + + {props.panel.id === "files" && ( + }> + {(item) => ( + + {item.file} + + +{item.additions} + + + -{item.deletions} + + + )} + + )} + {props.panel.id === "sessions" && ( + )}> + {(session) => ( + + {session.title || "Untitled"} + {session.id.slice(0, 8)} + + )} + + )} + {props.panel.id === "model" && ( + + {(content() as { name?: string })?.name || "No model"} + + )} + + + + + ) +} + +function View(props: { api: TuiPluginApi; session_id: string }) { + const theme = () => props.api.theme.current + + return ( + + + {(panel) => ( + + )} + + + ) +} + +const tui: TuiPlugin = async (api) => { + api.slots.register({ + order: 100, + slots: { + sidebar_content(_ctx, props) { + return + }, + }, + }) +} + +const plugin: TuiPluginModule & { id: string } = { + id, + tui, +} + +export default plugin diff --git a/packages/opencode/src/cli/cmd/tui/plugin/internal.ts b/packages/opencode/src/cli/cmd/tui/plugin/internal.ts index 1b6cd996..eb485d91 100644 --- a/packages/opencode/src/cli/cmd/tui/plugin/internal.ts +++ b/packages/opencode/src/cli/cmd/tui/plugin/internal.ts @@ -10,6 +10,8 @@ import SidebarTask from "../feature-plugins/sidebar/task" import SidebarTodo from "../feature-plugins/sidebar/todo" import SidebarFiles from "../feature-plugins/sidebar/files" import SidebarFooter from "../feature-plugins/sidebar/footer" +import SidebarPanels from "../feature-plugins/sidebar/panels" +import ActivityBarPanels from "../feature-plugins/activity-bar" import PluginManager from "../feature-plugins/system/plugins" import type { TuiPlugin, TuiPluginModule } from "@mimo-ai/plugin/tui" @@ -31,5 +33,7 @@ export const INTERNAL_TUI_PLUGINS: InternalTuiPlugin[] = [ SidebarTodo, SidebarFiles, SidebarFooter, + SidebarPanels, + ActivityBarPanels, PluginManager, ] diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/activity-bar.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/activity-bar.tsx new file mode 100644 index 00000000..b890f432 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/activity-bar.tsx @@ -0,0 +1,81 @@ +import { For, Show, createMemo } from "solid-js" +import { useTheme } from "../../context/theme" +import { TuiPluginRuntime } from "../../plugin" + +export type PanelID = string + +interface PanelDef { + id: PanelID + icon: string + label: string +} + +const BUILTIN_PANELS: PanelDef[] = [ + { id: "files", icon: " ", label: "File Explorer" }, + { id: "tasks", icon: " ", label: "Tasks" }, + { id: "todo", icon: "✓", label: "Todo" }, + { id: "mcp", icon: " ", label: "MCP Servers" }, + { id: "lsp", icon: " ", label: "LSP Servers" }, +] + +export function ActivityBar(props: { + sessionID: string + activePanels: PanelID[] + onTogglePanel: (panel: PanelID) => void + visible: boolean + onToggle: () => void +}) { + const { theme } = useTheme() + + const isActive = (id: PanelID) => props.activePanels.includes(id) + + return ( + + + + + + {(panel) => ( + props.onTogglePanel(panel.id)} + > + + {panel.icon} + + + )} + + + + + + + {props.visible ? "◁" : "▷"} + + + + + ) +} + +export { BUILTIN_PANELS } +export type { PanelDef } 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 c2a6f525..ec9394d7 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -64,6 +64,7 @@ import { DialogTimeline } from "./dialog-timeline" import { DialogForkFromTimeline } from "./dialog-fork-from-timeline" import { DialogSessionRename } from "../../component/dialog-session-rename" import { Sidebar } from "./sidebar" +import { ActivityBar, type PanelID } from "./activity-bar" import { SubagentFooter } from "./subagent-footer.tsx" import { DialogSubagent } from "./dialog-subagent.tsx" import { Flag } from "@/flag/flag" @@ -181,15 +182,22 @@ export function Session() { const [showGenericToolOutput, setShowGenericToolOutput] = kv.signal("generic_tool_output_visibility", false) const wide = createMemo(() => dimensions().width > 120) + const [activePanels, setActivePanels] = createSignal([]) + const togglePanel = (panel: PanelID) => { + setActivePanels((prev) => + prev.includes(panel) ? prev.filter((p) => p !== panel) : [...prev, panel] + ) + } const sidebarVisible = createMemo(() => { if (session()?.parentID) return false if (currentAgentID() !== "main") return false if (sidebarOpen()) return true + if (activePanels().length > 0) return true if (sidebar() === "auto" && wide()) return true return false }) const showTimestamps = createMemo(() => timestamps() === "show") - const contentWidth = createMemo(() => dimensions().width - (sidebarVisible() ? 42 : 0) - 4) + const contentWidth = createMemo(() => dimensions().width - (sidebarVisible() ? 45 : 0) - 4) const providers = createMemo(() => Model.index(sync.data.provider)) const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig)) @@ -1216,9 +1224,23 @@ export function Session() { + { + batch(() => { + const isVisible = sidebarVisible() + setSidebar(() => (isVisible ? "hide" : "auto")) + setSidebarOpen(!isVisible) + if (isVisible) setActivePanels([]) + }) + }} + /> - + - + diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/file-explorer.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/panels/file-explorer.tsx new file mode 100644 index 00000000..04451b92 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/file-explorer.tsx @@ -0,0 +1,73 @@ +import { createMemo, createSignal, For, Show } from "solid-js" +import { useTheme } from "../../../context/theme" +import { useDirectory } from "@tui/context/directory" +import fs from "fs/promises" +import path from "path" + +interface FileEntry { + name: string + isDirectory: boolean + children?: FileEntry[] + expanded?: boolean +} + +export function FileExplorerPanel() { + const { theme } = useTheme() + const directory = useDirectory() + const [files, setFiles] = createSignal([]) + const [loading, setLoading] = createSignal(true) + + const loadDir = async (dirPath: string): Promise => { + try { + const entries = await fs.readdir(dirPath, { withFileTypes: true }) + const result: FileEntry[] = [] + for (const entry of entries) { + if (entry.name.startsWith(".")) continue + if (entry.name === "node_modules") continue + result.push({ + name: entry.name, + isDirectory: entry.isDirectory(), + }) + } + return result.sort((a, b) => { + if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1 + return a.name.localeCompare(b.name) + }) + } catch { + return [] + } + } + + createMemo(async () => { + const dir = directory().split(":")[0].replace("~", process.env.HOME || "") + const entries = await loadDir(dir) + setFiles(entries) + setLoading(false) + }) + + return ( + + + File Explorer + + {directory()} + + + {(entry) => ( + + + {entry.isDirectory ? " " : " "} + + + {entry.name} + + + )} + + + + Loading... + + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/index.ts b/packages/opencode/src/cli/cmd/tui/routes/session/panels/index.ts new file mode 100644 index 00000000..b311c337 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/index.ts @@ -0,0 +1,5 @@ +export { FileExplorerPanel } from "./file-explorer" +export { TasksPanel } from "./tasks" +export { TodoPanel } from "./todo" +export { McpPanel } from "./mcp" +export { LspPanel } from "./lsp" diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/lsp.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/panels/lsp.tsx new file mode 100644 index 00000000..4c376f8b --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/lsp.tsx @@ -0,0 +1,39 @@ +import { createMemo, For, Show } from "solid-js" +import { useTheme } from "../../../context/theme" +import { useSync } from "@tui/context/sync" + +interface LspServer { + id: string + root: string + status: string +} + +export function LspPanel() { + const { theme } = useTheme() + const sync = useSync() + + const servers = createMemo(() => { + return sync.data.lsp.map((item) => ({ + id: item.id, + root: item.root, + status: item.status, + })) + }) + + return ( + + + LSP Servers + + 0}> + + {(server) => ( + + {server.status === "connected" ? "●" : "○"} {server.id} + + )} + + + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/mcp.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/panels/mcp.tsx new file mode 100644 index 00000000..2b002f8b --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/mcp.tsx @@ -0,0 +1,41 @@ +import { createMemo, For, Show } from "solid-js" +import { useTheme } from "../../../context/theme" +import { useSync } from "@tui/context/sync" + +interface McpServer { + name: string + status: string + error?: string +} + +export function McpPanel() { + const { theme } = useTheme() + const sync = useSync() + + const servers = createMemo(() => { + return Object.entries(sync.data.mcp) + .sort(([a], [b]) => a.localeCompare(b)) + .map(([name, item]) => ({ + name, + status: item.status, + error: item.status === "failed" ? item.error : undefined, + })) + }) + + return ( + + + MCP Servers + + 0}> + + {(server) => ( + + {server.status === "connected" ? "●" : "○"} {server.name} + + )} + + + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/model.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/panels/model.tsx new file mode 100644 index 00000000..f9601099 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/model.tsx @@ -0,0 +1,27 @@ +import { createMemo, For, Show } from "solid-js" +import { useTheme } from "@tui/context/theme" +import { useSync } from "@tui/context/sync" + +export function ModelPanel() { + const { theme } = useTheme() + const sync = useSync() + + const model = createMemo(() => sync.data.model) + + return ( + + + Model + + + + {model()!.name || "Unknown"} + {model()!.provider || ""} + + + + No model selected + + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/plugins.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/panels/plugins.tsx new file mode 100644 index 00000000..68f990fa --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/plugins.tsx @@ -0,0 +1,42 @@ +import { createMemo, For } from "solid-js" +import { useTheme } from "@tui/context/theme" + +interface Plugin { + name: string + version: string + enabled: boolean +} + +export function PluginsPanel() { + const { theme } = useTheme() + + const plugins = createMemo(() => { + return [ + { name: "opencode-puter-auth", version: "1.0.0", enabled: true }, + { name: "@zenobius/opencode-skillful", version: "1.2.0", enabled: true }, + { name: "@opencode-manager/memory", version: "0.9.0", enabled: true }, + { name: "work-checkpoints", version: "1.0.0", enabled: false }, + ] + }) + + return ( + + + Plugins + + + {(plugin) => ( + + + {plugin.name} + + {plugin.enabled ? "●" : "○"} + + + v{plugin.version} + + )} + + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/sessions.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/panels/sessions.tsx new file mode 100644 index 00000000..65f236c8 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/sessions.tsx @@ -0,0 +1,33 @@ +import { createMemo, For, Show } from "solid-js" +import { useTheme } from "@tui/context/theme" +import { useSync } from "@tui/context/sync" + +export function SessionsPanel() { + const { theme } = useTheme() + const sync = useSync() + + const sessions = createMemo(() => { + return Object.values(sync.data.session ?? {}) + }) + + return ( + + + Sessions + + 0}> + + {(session) => ( + + {session.title || "Untitled"} + {session.id.slice(0, 8)} + + )} + + + + No sessions + + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/skills.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/panels/skills.tsx new file mode 100644 index 00000000..01cd9d89 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/skills.tsx @@ -0,0 +1,39 @@ +import { createMemo, For, Show } from "solid-js" +import { useTheme } from "@tui/context/theme" + +interface Skill { + name: string + description: string + enabled: boolean +} + +export function SkillsPanel() { + const { theme } = useTheme() + + const skills = createMemo(() => { + return [ + { name: "brainstorming", description: "Creative work planning", enabled: true }, + { name: "systematic-debugging", description: "Bug investigation", enabled: true }, + { name: "test-driven-development", description: "TDD workflow", enabled: false }, + { name: "writing-plans", description: "Implementation planning", enabled: true }, + ] + }) + + return ( + + + Skills + + + {(skill) => ( + + {skill.name} + + {skill.enabled ? "●" : "○"} + + + )} + + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/tasks.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/panels/tasks.tsx new file mode 100644 index 00000000..e4aebf29 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/tasks.tsx @@ -0,0 +1,42 @@ +import { createMemo, For, Show } from "solid-js" +import { useTheme } from "../../../context/theme" +import { useSync } from "@tui/context/sync" + +interface Task { + id: string + status: string + summary: string + owner?: string + ended_at?: string +} + +export function TasksPanel() { + const { theme } = useTheme() + const sync = useSync() + + const tasks = createMemo(() => { + const sessionData = sync.data.session + if (!sessionData) return [] + return Object.values(sessionData).flatMap((session: any) => + sync.data.task[session.id] ?? [] + ) + }) + + return ( + + + Tasks + + 0}> + + {(task) => ( + + {task.summary || "Untitled"} + {task.status} {task.id} + + )} + + + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/panels/todo.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/panels/todo.tsx new file mode 100644 index 00000000..e0aa1dc9 --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/routes/session/panels/todo.tsx @@ -0,0 +1,38 @@ +import { createMemo, For, Show } from "solid-js" +import { useTheme } from "../../../context/theme" +import { useSync } from "@tui/context/sync" + +interface TodoItem { + content: string + status: string +} + +export function TodoPanel() { + const { theme } = useTheme() + const sync = useSync() + + const todos = createMemo(() => { + const sessionData = sync.data.session + if (!sessionData) return [] + return Object.values(sessionData).flatMap((session: any) => + sync.data.todo[session.id] ?? [] + ) + }) + + return ( + + + Todo + + 0}> + + {(todo) => ( + + {todo.status === "completed" ? "✓" : "○"} {todo.content} + + )} + + + + ) +} 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 6d92752e..9525f4d5 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx @@ -1,14 +1,33 @@ import { useProject } from "@tui/context/project" import { useSync } from "@tui/context/sync" -import { createMemo, Show } from "solid-js" +import { createMemo, For, Show } from "solid-js" import { useTheme } from "../../context/theme" import { useTuiConfig } from "../../context/tui-config" import { InstallationChannel, InstallationVersion } from "@/installation/version" import { TuiPluginRuntime } from "../../plugin" - import { getScrollAcceleration } from "../../util/scroll" +import type { PanelID } from "./activity-bar" +import { + FileExplorerPanel, + TasksPanel, + TodoPanel, + McpPanel, + LspPanel, +} from "./panels" + +const PANEL_COMPONENTS: Record any> = { + files: FileExplorerPanel, + tasks: TasksPanel, + todo: TodoPanel, + mcp: McpPanel, + lsp: LspPanel, +} -export function Sidebar(props: { sessionID: string; overlay?: boolean }) { +export function Sidebar(props: { + sessionID: string + overlay?: boolean + activePanels?: PanelID[] +}) { const project = useProject() const sync = useSync() const { theme } = useTheme() @@ -27,6 +46,7 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) { return `${info.type}: ${info.name}` } const scrollAcceleration = createMemo(() => getScrollAcceleration(tuiConfig)) + const hasActivePanels = () => (props.activePanels?.length ?? 0) > 0 return ( @@ -51,37 +71,77 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) { }} > - - - - {session()!.title} - - - {props.sessionID} - - - - {" "} - {workspaceLabel()} + + + {(panelId) => { + const Component = PANEL_COMPONENTS[panelId] + if (Component) { + return ( + + + + ) + } + return ( + + ) + }} + + + + + + + + {session()!.title} - - - {session()!.share!.url} - - - - + + {props.sessionID} + + + + + ● + {" "} + {workspaceLabel()} + + + + {session()!.share!.url} + + + + + - + Open diff --git a/packages/plugin/src/tui.ts b/packages/plugin/src/tui.ts index a7c4b551..a327c1e2 100644 --- a/packages/plugin/src/tui.ts +++ b/packages/plugin/src/tui.ts @@ -376,6 +376,15 @@ export type TuiHostSlotMap = { sidebar_footer: { session_id: string } + activity_bar: { + session_id: string + active_panels: string[] + on_toggle: (panel_id: string) => void + } + sidebar_panel: { + session_id: string + panel_id: string + } } export type TuiSlotMap = {}> = TuiHostSlotMap & Slots