refactor(tui): consolidate settings in cli config

This commit is contained in:
Dax Raad
2026-07-13 12:55:54 -04:00
parent 4e74f77e44
commit 775fce0177
24 changed files with 297 additions and 430 deletions
+14 -19
View File
@@ -2,7 +2,6 @@
import { testRender } from "@opentui/solid"
import { onMount } from "solid-js"
import { ArgsProvider } from "../../../../src/context/args"
import { KVProvider, useKV } from "../../../../src/context/kv"
import { ProjectProvider, useProject } from "../../../../src/context/project"
import { SDKProvider } from "../../../../src/context/sdk"
import { SyncProvider, useSync } from "../../../../src/context/sync"
@@ -20,25 +19,23 @@ export async function wait(fn: () => boolean, timeout = 2000) {
}
}
type Ctx = { kv: ReturnType<typeof useKV>; project: ReturnType<typeof useProject>; sync: ReturnType<typeof useSync> }
type Ctx = { project: ReturnType<typeof useProject>; sync: ReturnType<typeof useSync> }
export async function mount(override?: FetchHandler, state?: string) {
const events = createEventStream()
const calls = createFetch(override, events)
let sync!: ReturnType<typeof useSync>
let project!: ReturnType<typeof useProject>
let kv!: ReturnType<typeof useKV>
let done!: () => void
const ready = new Promise<void>((resolve) => {
done = resolve
})
function Probe() {
const ctx: Ctx = { kv: useKV(), project: useProject(), sync: useSync() }
const ctx: Ctx = { project: useProject(), sync: useSync() }
onMount(() => {
sync = ctx.sync
project = ctx.project
kv = ctx.kv
done()
})
return <box />
@@ -47,24 +44,22 @@ export async function mount(override?: FetchHandler, state?: string) {
const app = await testRender(() => (
<TestTuiContexts paths={state ? { state } : undefined}>
<ArgsProvider>
<KVProvider>
<SDKProvider client={createClient(calls.fetch)} api={createApi(calls.fetch)}>
<PermissionProvider>
<ProjectProvider>
<ExitProvider exit={() => {}}>
<SyncProvider>
<Probe />
</SyncProvider>
</ExitProvider>
</ProjectProvider>
</PermissionProvider>
</SDKProvider>
</KVProvider>
<SDKProvider client={createClient(calls.fetch)} api={createApi(calls.fetch)}>
<PermissionProvider>
<ProjectProvider>
<ExitProvider exit={() => {}}>
<SyncProvider>
<Probe />
</SyncProvider>
</ExitProvider>
</ProjectProvider>
</PermissionProvider>
</SDKProvider>
</ArgsProvider>
</TestTuiContexts>
))
await ready
await wait(() => sync.status === "complete")
return { app, emit: events.emit, kv, project, sync, session: calls.session }
return { app, emit: events.emit, project, sync, session: calls.session }
}
@@ -26,12 +26,10 @@ async function mountPrompt(input: {
}) {
const state = path.join(input.root, "state")
await mkdir(state, { recursive: true })
await Bun.write(path.join(state, "kv.json"), "{}")
const [
{ DialogProvider },
{ DialogPrompt },
{ KVProvider },
{ ThemeProvider },
{ ConfigProvider },
{ ToastProvider },
@@ -39,7 +37,6 @@ async function mountPrompt(input: {
] = await Promise.all([
import("../../../src/ui/dialog"),
import("../../../src/ui/dialog-prompt"),
import("../../../src/context/kv"),
import("../../../src/context/theme"),
import("../../../src/config"),
import("../../../src/ui/toast"),
@@ -67,15 +64,13 @@ async function mountPrompt(input: {
>
<OpencodeKeymapProvider keymap={keymap}>
<ConfigProvider config={resolvedConfig}>
<KVProvider>
<ThemeProvider mode="dark">
<ToastProvider>
<DialogProvider>
<DialogPrompt title="Rename Session" value="draft" onConfirm={input.onConfirm} />
</DialogProvider>
</ToastProvider>
</ThemeProvider>
</KVProvider>
<ThemeProvider mode="dark">
<ToastProvider>
<DialogProvider>
<DialogPrompt title="Rename Session" value="draft" onConfirm={input.onConfirm} />
</DialogProvider>
</ToastProvider>
</ThemeProvider>
</ConfigProvider>
</OpencodeKeymapProvider>
</TestTuiContexts>
@@ -4,7 +4,6 @@ import { RGBA } from "@opentui/core"
import { testRender } from "@opentui/solid"
import type { JSX } from "solid-js"
import { createTuiResolvedConfig } from "../../fixture/tui-runtime"
import { KVProvider } from "../../../src/context/kv"
import { ThemeProvider } from "../../../src/context/theme"
import { ConfigProvider } from "../../../src/config"
import { DiffViewerFileTree } from "../../../src/feature-plugins/system/diff-viewer-file-tree"
@@ -182,9 +181,7 @@ function withTheme(component: () => JSX.Element) {
return (
<TestTuiContexts>
<ConfigProvider config={createTuiResolvedConfig()}>
<KVProvider>
<ThemeProvider mode="dark">{component()}</ThemeProvider>
</KVProvider>
<ThemeProvider mode="dark">{component()}</ThemeProvider>
</ConfigProvider>
</TestTuiContexts>
)
@@ -5,7 +5,6 @@ import { DiffRenderable, type Renderable, ScrollBoxRenderable } from "@opentui/c
import { testRender, useRenderer } from "@opentui/solid"
import type { TuiPluginApi, TuiPluginMeta, TuiRouteCurrent, TuiRouteDefinition } from "@opencode-ai/plugin/tui"
import type { Session } from "@opencode-ai/sdk/v2"
import { KVProvider } from "../../../src/context/kv"
import { ThemeProvider } from "../../../src/context/theme"
import { ConfigProvider } from "../../../src/config"
import { SDKProvider } from "../../../src/context/sdk"
@@ -174,11 +173,9 @@ async function renderDiffViewer(vcsDiff: unknown[], height = 20, initialRoute?:
<SDKProvider client={createClient(transport.fetch)} api={createApi(transport.fetch)}>
<OpencodeKeymapProvider keymap={keymap}>
<ConfigProvider config={config}>
<KVProvider>
<ThemeProvider mode="dark">
{renderDiff?.({ params: "params" in current ? current.params : undefined })}
</ThemeProvider>
</KVProvider>
<ThemeProvider mode="dark">
{renderDiff?.({ params: "params" in current ? current.params : undefined })}
</ThemeProvider>
</ConfigProvider>
</OpencodeKeymapProvider>
</SDKProvider>
+5 -9
View File
@@ -7,7 +7,6 @@ import path from "node:path"
import { onCleanup } from "solid-js"
import { ClipboardProvider } from "../../../src/context/clipboard"
import type { FormWithLocation } from "../../../src/context/data"
import { KVProvider } from "../../../src/context/kv"
import { SDKProvider } from "../../../src/context/sdk"
import { ThemeProvider } from "../../../src/context/theme"
import { ConfigProvider } from "../../../src/config"
@@ -21,7 +20,6 @@ import { createApi, createClient, createEventStream, createFetch } from "../../f
async function mountForm(root: string, width = 80) {
const state = path.join(root, "state")
await mkdir(state, { recursive: true })
await Bun.write(path.join(state, "kv.json"), "{}")
const replies: unknown[] = []
const copied: string[] = []
@@ -78,13 +76,11 @@ async function mountForm(root: string, width = 80) {
<OpencodeKeymapProvider keymap={keymap}>
<ConfigProvider config={config}>
<SDKProvider client={createClient(transport.fetch)} api={createApi(transport.fetch)}>
<KVProvider>
<ThemeProvider mode="dark" source={{ discover: () => Promise.resolve({}) }}>
<ToastProvider>
<FormPrompt form={form} />
</ToastProvider>
</ThemeProvider>
</KVProvider>
<ThemeProvider mode="dark" source={{ discover: () => Promise.resolve({}) }}>
<ToastProvider>
<FormPrompt form={form} />
</ToastProvider>
</ThemeProvider>
</SDKProvider>
</ConfigProvider>
</OpencodeKeymapProvider>
-10
View File
@@ -11,7 +11,6 @@ type Opts = {
}
export function createTuiPluginApi(opts: Opts = {}) {
const values = new Map<string, unknown>()
const color = RGBA.fromInts(200, 200, 200)
const dialog = { clear() {}, replace() {}, setSize() {}, size: "medium" as const, depth: 0, open: false }
return {
@@ -19,15 +18,6 @@ export function createTuiPluginApi(opts: Opts = {}) {
client: opts.client,
event: opts.event,
keymap: opts.keymap,
kv: {
get(name: string, fallback?: unknown) {
return values.has(name) ? values.get(name) : fallback
},
set(name: string, value: unknown) {
values.set(name, value)
},
ready: true,
},
state: { session: { get: () => undefined, ...opts.state?.session } },
theme: { current: new Proxy({}, { get: () => color }) },
tuiConfig: createTuiResolvedConfig(),