Skip to content

Commit c3bf10c

Browse files
committed
refactor(tui): port sidebar plugin to snapshot api
1 parent eedefaf commit c3bf10c

File tree

5 files changed

+353
-93
lines changed

5 files changed

+353
-93
lines changed

tui/index.tsx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/** @jsxImportSource @opentui/solid */
2-
import type { TuiPluginInput } from "@opencode-ai/plugin/tui"
2+
import type { TuiPlugin } from "@opencode-ai/plugin/tui"
33
import { getConfigForDirectory } from "../lib/config"
44
import { Logger } from "../lib/logger"
55
import { createSidebarTopSlot } from "./slots/sidebar-top"
66
import { createSummaryRoute } from "./routes/summary"
77
import { NAMES } from "./shared/names"
88

9-
const tui = async (input: TuiPluginInput) => {
9+
const tui: TuiPlugin = async (api) => {
1010
const config = getConfigForDirectory(process.cwd(), (title, message) => {
11-
input.api.ui.toast({
11+
api.ui.toast({
1212
title,
1313
message,
1414
variant: "warning",
@@ -19,19 +19,10 @@ const tui = async (input: TuiPluginInput) => {
1919

2020
const logger = new Logger(config.tui.debug, "tui")
2121

22-
input.api.route.register([createSummaryRoute(input.api)])
22+
api.route.register([createSummaryRoute(api)])
2323

2424
if (config.tui.sidebar) {
25-
input.slots.register(
26-
createSidebarTopSlot(
27-
input.api,
28-
input.client,
29-
input.event,
30-
input.renderer,
31-
NAMES,
32-
logger,
33-
),
34-
)
25+
api.slots.register(createSidebarTopSlot(api, NAMES, logger))
3526
}
3627
}
3728

tui/routes/summary.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,19 @@ function CollapsibleSectionRow(props: { section: CollapsibleSection; palette: Dc
100100
}
101101

102102
function SummaryScreen(props: { api: TuiApi }) {
103-
const params = createMemo(() => (props.api.route.current.params ?? {}) as SummaryRouteParams)
103+
const params = createMemo(() => {
104+
const current = props.api.route.current
105+
return ("params" in current ? current.params : {}) as SummaryRouteParams
106+
})
104107
const palette = createMemo(() => getPalette(props.api.theme.current as Record<string, unknown>))
105108
const parsed = createMemo(() => parseSummary(params().summary || ""))
106109

107-
const keys = props.api.keybind?.create({ close: "escape" })
110+
const keys = props.api.keybind.create({ close: "escape" })
108111

109112
useKeyboard((evt: any) => {
110113
if (props.api.route.current.name !== NAMES.routes.summary) return
111-
if (props.api.ui?.dialog?.open) return
112-
const matched = keys ? keys.match("close", evt) : evt.name === "escape"
114+
if (props.api.ui.dialog.open) return
115+
const matched = keys.match("close", evt)
113116
if (!matched) return
114117
evt.preventDefault()
115118
evt.stopPropagation()

tui/shared/types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import type { TuiPluginInput } from "@opencode-ai/plugin/tui"
1+
import type { TuiPluginApi } from "@opencode-ai/plugin/tui"
22
import type {
33
MessageStatus as DcpMessageStatus,
44
TokenBreakdown as DcpContextBreakdown,
55
} from "../../lib/analysis/tokens"
66

7-
export type DcpTuiClient = TuiPluginInput["client"]
7+
export type DcpTuiApi = TuiPluginApi
8+
export type DcpTuiClient = DcpTuiApi["client"]
89

910
export type { DcpMessageStatus }
1011

tui/slots/sidebar-top.tsx

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/** @jsxImportSource @opentui/solid */
22
import { createEffect, createMemo, createSignal, on, onCleanup, untrack } from "solid-js"
3-
import type { TuiApi, TuiPluginInput } from "@opencode-ai/plugin/tui"
3+
import type { TuiSlotPlugin } from "@opencode-ai/plugin/tui"
44
import { Logger } from "../../lib/logger"
55
import {
66
createPlaceholderContextSnapshot,
@@ -10,7 +10,7 @@ import {
1010
} from "../data/context"
1111
import { getPalette, toneColor, type DcpColor, type DcpPalette } from "../shared/theme"
1212
import { LABEL, type DcpRouteNames } from "../shared/names"
13-
import type { DcpActiveBlockInfo, DcpMessageStatus, DcpTuiClient } from "../shared/types"
13+
import type { DcpActiveBlockInfo, DcpMessageStatus, DcpTuiApi } from "../shared/types"
1414

1515
const SINGLE_BORDER = { type: "single" } as any
1616
const DIM_TEXT = { dim: true } as any
@@ -114,10 +114,7 @@ const SidebarContextBar = (props: {
114114
}
115115

116116
const SidebarContext = (props: {
117-
api: TuiApi
118-
client: DcpTuiClient
119-
event: TuiPluginInput["event"]
120-
renderer: TuiPluginInput["renderer"]
117+
api: DcpTuiApi
121118
names: DcpRouteNames
122119
palette: DcpPalette
123120
sessionID: () => string
@@ -137,7 +134,7 @@ const SidebarContext = (props: {
137134
renderTimeout = setTimeout(() => {
138135
renderTimeout = undefined
139136
try {
140-
props.renderer.requestRender()
137+
props.api.renderer.requestRender()
141138
} catch (error) {
142139
props.logger.warn("Failed to request TUI render", {
143140
error: error instanceof Error ? error.message : String(error),
@@ -180,7 +177,7 @@ const SidebarContext = (props: {
180177
const currentRequest = ++requestVersion
181178

182179
try {
183-
const value = await loadContextSnapshotCached(props.client, props.logger, sessionID)
180+
const value = await loadContextSnapshotCached(props.api.client, props.logger, sessionID)
184181
if (currentRequest !== requestVersion || props.sessionID() !== sessionID) {
185182
return
186183
}
@@ -230,43 +227,43 @@ const SidebarContext = (props: {
230227
}
231228

232229
const unsubs = [
233-
props.event.on("message.updated", (event) => {
230+
props.api.event.on("message.updated", (event) => {
234231
if (event.properties.info.sessionID !== sessionID) return
235232
scheduleRefresh()
236233
}),
237-
props.event.on("message.removed", (event) => {
234+
props.api.event.on("message.removed", (event) => {
238235
if (event.properties.sessionID !== sessionID) return
239236
scheduleRefresh()
240237
}),
241-
props.event.on("message.part.updated", (event) => {
238+
props.api.event.on("message.part.updated", (event) => {
242239
if (event.properties.part.sessionID !== sessionID) return
243240
scheduleRefresh()
244241
}),
245-
props.event.on("message.part.delta", (event) => {
242+
props.api.event.on("message.part.delta", (event) => {
246243
if (event.properties.sessionID !== sessionID) return
247244
scheduleRefresh()
248245
}),
249-
props.event.on("message.part.removed", (event) => {
246+
props.api.event.on("message.part.removed", (event) => {
250247
if (event.properties.sessionID !== sessionID) return
251248
scheduleRefresh()
252249
}),
253-
props.event.on("session.updated", (event) => {
250+
props.api.event.on("session.updated", (event) => {
254251
if (event.properties.info.id !== sessionID) return
255252
scheduleRefresh()
256253
}),
257-
props.event.on("session.deleted", (event) => {
254+
props.api.event.on("session.deleted", (event) => {
258255
if (event.properties.info.id !== sessionID) return
259256
scheduleRefresh()
260257
}),
261-
props.event.on("session.diff", (event) => {
258+
props.api.event.on("session.diff", (event) => {
262259
if (event.properties.sessionID !== sessionID) return
263260
scheduleRefresh()
264261
}),
265-
props.event.on("session.error", (event) => {
262+
props.api.event.on("session.error", (event) => {
266263
if (event.properties.sessionID !== sessionID) return
267264
scheduleRefresh()
268265
}),
269-
props.event.on("session.status", (event) => {
266+
props.api.event.on("session.status", (event) => {
270267
if (event.properties.sessionID !== sessionID) return
271268
scheduleRefresh()
272269
}),
@@ -471,13 +468,10 @@ const SidebarContext = (props: {
471468
}
472469

473470
export const createSidebarTopSlot = (
474-
api: TuiApi,
475-
client: DcpTuiClient,
476-
event: TuiPluginInput["event"],
477-
renderer: TuiPluginInput["renderer"],
471+
api: DcpTuiApi,
478472
names: DcpRouteNames,
479473
logger: Logger,
480-
) => ({
474+
): TuiSlotPlugin => ({
481475
id: names.slot,
482476
slots: {
483477
sidebar_top(
@@ -490,9 +484,6 @@ export const createSidebarTopSlot = (
490484
return (
491485
<SidebarContext
492486
api={api}
493-
client={client}
494-
event={event}
495-
renderer={renderer}
496487
names={names}
497488
palette={palette()}
498489
sessionID={() => value.session_id}

0 commit comments

Comments
 (0)