fix(tui): restore diff viewer route and workspace (#28676)

This commit is contained in:
James Long 2026-05-21 12:28:07 -04:00 committed by GitHub
parent 53e2ab8b1f
commit b38f4d79f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 30 additions and 6 deletions

View file

@ -25,7 +25,7 @@ import { DialogProvider, useDialog } from "@tui/ui/dialog"
import { DialogProvider as DialogProviderList } from "@tui/component/dialog-provider"
import { ErrorComponent } from "@tui/component/error-component"
import { PluginRouteMissing } from "@tui/component/plugin-route-missing"
import { ProjectProvider } from "@tui/context/project"
import { ProjectProvider, useProject } from "@tui/context/project"
import { EditorContextProvider } from "@tui/context/editor"
import { useEvent } from "@tui/context/event"
import { SDKProvider, useSDK } from "@tui/context/sdk"
@ -279,6 +279,7 @@ function App(props: { onSnapshot?: () => Promise<string[]> }) {
const themeState = useTheme()
const { theme, mode, setMode, locked, lock, unlock } = themeState
const sync = useSync()
const project = useProject()
const exit = useExit()
const promptRef = usePromptRef()
const routes: RouteMap = new Map()
@ -304,6 +305,7 @@ function App(props: { onSnapshot?: () => Promise<string[]> }) {
toast,
renderer,
attention,
project,
})
const [ready, setReady] = createSignal(false)
TuiPluginRuntime.init({

View file

@ -1,5 +1,5 @@
/** @jsxImportSource @opentui/solid */
import type { TuiPlugin, TuiPluginApi } from "@opencode-ai/plugin/tui"
import type { TuiPlugin, TuiPluginApi, TuiRouteCurrent } from "@opencode-ai/plugin/tui"
import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2"
import type { BoxRenderable, ScrollBoxRenderable } from "@opentui/core"
import { LANGUAGE_EXTENSIONS } from "@/lsp/language"
@ -61,7 +61,7 @@ function DiffViewer(props: { api: TuiPluginApi }) {
const theme = () => props.api.theme.current
const params = () =>
("params" in props.api.route.current ? props.api.route.current.params : undefined) as
| { mode?: DiffMode; sessionID?: string; messageID?: string }
| { mode?: DiffMode; sessionID?: string; messageID?: string; returnTo?: TuiRouteCurrent }
| undefined
const mode = () => params()?.mode ?? "git"
const diffInput = createMemo(() => ({
@ -80,7 +80,10 @@ function DiffViewer(props: { api: TuiPluginApi }) {
return normalizeDiffs(result.data ?? [])
}
const result = await props.api.client.vcs.diff({ mode: "git" }, { throwOnError: true })
const result = await props.api.client.vcs.diff(
{ mode: "git", workspace: props.api.workspace.current() },
{ throwOnError: true },
)
return normalizeDiffs(result.data ?? [])
})
const files = createMemo(() => diff() ?? [])
@ -250,7 +253,8 @@ function DiffViewer(props: { api: TuiPluginApi }) {
title: "Close diff viewer",
category: "VCS",
run() {
props.api.route.navigate("home")
const target = params()?.returnTo ?? ({ name: "home" } satisfies TuiRouteCurrent)
props.api.route.navigate(target.name, "params" in target ? target.params : undefined)
},
},
{
@ -446,6 +450,7 @@ function DiffViewer(props: { api: TuiPluginApi }) {
mode: option.value,
sessionID: params()?.sessionID,
messageID: params()?.messageID,
returnTo: params()?.returnTo,
})
},
}))}
@ -672,6 +677,12 @@ const tui: TuiPlugin = async (api) => {
api.route.navigate(ROUTE, {
mode: "git",
sessionID: "params" in api.route.current ? api.route.current.params?.sessionID : undefined,
returnTo: {
name: api.route.current.name,
...("params" in api.route.current && api.route.current.params
? { params: api.route.current.params }
: {}),
},
})
api.ui.dialog.clear()
},

View file

@ -8,6 +8,7 @@ import { Dialog as DialogUI, type useDialog } from "@tui/ui/dialog"
import type { TuiConfig } from "@/cli/cmd/tui/config/tui"
import type { useOpencodeKeymap } from "../keymap"
import type { useKV } from "../context/kv"
import type { useProject } from "../context/project"
import { DialogAlert } from "../ui/dialog-alert"
import { DialogConfirm } from "../ui/dialog-confirm"
import { DialogPrompt } from "../ui/dialog-prompt"
@ -41,6 +42,7 @@ type Input = {
toast: ReturnType<typeof useToast>
renderer: TuiPluginApi["renderer"]
attention: TuiPluginApi["attention"]
project: ReturnType<typeof useProject>
}
function routeRegister(routes: RouteMap, list: TuiRouteDefinition[], bump: () => void) {
@ -227,6 +229,11 @@ export function createTuiApi(input: Input): TuiPluginApi {
return Keymap.getOpencodeModeStack(input.keymap).push(mode)
},
},
workspace: {
current() {
return input.project.workspace.current()
},
},
route: {
register(list) {
return routeRegister(input.routes, list, input.bump)

View file

@ -628,6 +628,7 @@ function pluginApi(runtime: RuntimeState, plugin: PluginEntry, scope: PluginScop
keys: api.keys,
keymap,
mode: createScopedMode(api.mode, scope),
workspace: api.workspace,
route,
ui: api.ui,
tuiConfig: api.tuiConfig,

View file

@ -242,6 +242,9 @@ export function createTuiPluginApi(opts: Opts = {}): HostPluginApi {
current: () => "base",
push: () => () => {},
},
workspace: {
current: () => undefined,
},
route: {
register: () => {
if (count) count.route_add += 1

View file

@ -579,7 +579,6 @@ export type TuiPluginInstallResult =
export type TuiWorkspace = {
current: () => string | undefined
set: (workspaceID?: string) => void
}
export type TuiPluginApi = {
@ -595,6 +594,7 @@ export type TuiPluginApi = {
keys: TuiKeys
keymap: TuiKeymap
mode: TuiModeApi
workspace: TuiWorkspace
route: {
register: (routes: TuiRouteDefinition[]) => () => void
navigate: (name: string, params?: Record<string, unknown>) => void