refactor(tui): narrow mini compatibility surfaces (#38262)

This commit is contained in:
Simon Klee 2026-07-22 10:35:35 +02:00 committed by GitHub
commit 794137b33b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 67 additions and 159 deletions

View file

@ -1,19 +0,0 @@
import { resolve, type Info, type Resolved } from "../../../src/config"
import { TuiKeybind } from "../../../src/config/keybind"
type ResolvedInput = Omit<Info, "attention" | "keybinds" | "leader"> & {
attention?: Partial<Resolved["attention"]>
keybinds?: Partial<TuiKeybind.Keybinds>
leader_timeout?: number
}
export function createTuiResolvedConfig(input: ResolvedInput = {}) {
const { leader_timeout, ...current } = input
return resolve(
{
...current,
leader: leader_timeout === undefined ? undefined : { timeout: leader_timeout },
},
{ terminalSuspend: process.platform !== "win32" },
)
}

View file

@ -26,7 +26,6 @@ test("down opens subagents from an empty prompt", async () => {
label: "Explore",
description: "Inspect the keymap",
status: "running",
lastUpdatedAt: 1,
},
],
details: {},
@ -54,7 +53,6 @@ test("down opens subagents from an empty prompt", async () => {
view={view}
subagent={subagents}
theme={() => RUN_THEME_FALLBACK}
tuiConfig={config}
miniSettings={() => ({ thinking: "hide", shell_output: "hide", turn_summary: "show", footer: "show", mono: false })}
mono={false}
onSubmit={() => true}

View file

@ -35,7 +35,7 @@ import type {
} from "../../src/mini/types"
import { selectedCommand } from "../../src/mini/footer.prompt"
import { RejectField } from "../../src/mini/footer.permission"
import { createTuiResolvedConfig } from "./fixture/tui-runtime"
import { createTuiResolvedConfig } from "../fixture/tui-runtime"
const tuiConfig = createTuiResolvedConfig()
@ -87,7 +87,6 @@ function subagent(input: {
label: input.label,
description: input.description,
status: input.status ?? "running",
lastUpdatedAt: 1,
} satisfies FooterSubagentTab
}
@ -152,7 +151,6 @@ async function renderFooter(
subagent={subagents}
theme={input.theme ?? (() => RUN_THEME_FALLBACK)}
mono={input.mono ?? false}
tuiConfig={config}
miniSettings={miniSettings}
onSubmit={input.onSubmit ?? (() => true)}
onPermissionReply={() => {}}
@ -996,27 +994,17 @@ test("direct footer closes settings with ctrl-c instead of arming exit", async (
}
})
test("selectedCommand backfills the catalog source for bound drafts", () => {
const catalog = [command({ name: "opencode-ts", description: "TS skill", source: "skill" })]
// The skill picker binds `/name ` drafts; older drafts may lack source.
expect(selectedCommand("/opencode-ts fix it", { name: "opencode-ts", arguments: "" }, catalog)).toEqual({
name: "opencode-ts",
arguments: "fix it",
source: "skill",
})
// An explicit source wins without a catalog lookup.
test("selectedCommand validates the bound command and refreshes its arguments", () => {
expect(selectedCommand("/opencode-ts", { name: "opencode-ts", arguments: "", source: "skill" })).toEqual({
name: "opencode-ts",
arguments: "",
source: "skill",
})
// Plain commands stay untagged.
expect(
selectedCommand("/deploy prod", { name: "deploy", arguments: "" }, [
command({ name: "deploy", description: "Deploy" }),
]),
).toEqual({ name: "deploy", arguments: "prod" })
expect(selectedCommand("/deploy prod", { name: "deploy", arguments: "" })).toEqual({
name: "deploy",
arguments: "prod",
})
expect(selectedCommand("/other", { name: "deploy", arguments: "" })).toBeUndefined()
})
test("direct footer tags skill slash submissions with their catalog source", async () => {
@ -1162,7 +1150,6 @@ test("direct footer shows authoritative pending work while running", async () =>
},
]}
theme={() => RUN_THEME_FALLBACK}
tuiConfig={tuiConfig}
miniSettings={() => ({ thinking: "hide", shell_output: "hide", turn_summary: "show", footer: "show", mono: false })}
mono={false}
onSubmit={() => true}

View file

@ -3,7 +3,7 @@ import { OpenCode } from "@opencode-ai/client/promise"
import type { Resolved } from "../../src/config"
import { resolveMiniSettings, resolveModelInfo, resolveRunTuiConfig } from "../../src/mini/runtime.boot"
import { catalogModel, catalogProvider } from "./fixture/catalog"
import { createTuiResolvedConfig } from "./fixture/tui-runtime"
import { createTuiResolvedConfig } from "../fixture/tui-runtime"
function config(input?: {
leader?: string
@ -21,7 +21,7 @@ function config(input?: {
}): Resolved {
const bind = input?.bindings
return createTuiResolvedConfig({
leader_timeout: input?.leaderTimeout,
leader: input?.leaderTimeout === undefined ? undefined : { timeout: input.leaderTimeout },
keybinds: {
...(input?.leader && { leader: input.leader }),
...(bind?.commandList && { command_list: bind.commandList }),
@ -95,14 +95,12 @@ describe("run runtime boot", () => {
const result = await resolveRunTuiConfig(
createTuiResolvedConfig({
theme: { mode: "light" },
leader_timeout: 450,
session: { thinking: "show" },
leader: { timeout: 450 },
}),
)
expect(result.theme).toEqual({ mode: "light" })
expect(result.leader.timeout).toBe(450)
expect(result.session?.thinking).toBe("show")
expect(resolveMiniSettings(result)).toEqual({
thinking: "hide",
shell_output: "hide",

View file

@ -5,7 +5,6 @@ import type { LifecycleInput } from "../../src/mini/runtime.lifecycle"
import type { FooterEvent, MiniHost } from "../../src/mini/types"
import { catalogModel, catalogProvider, stubCatalogLists } from "./fixture/catalog"
import { createFooterApiFixture } from "./fixture/footer-api"
import { createTuiResolvedConfig } from "./fixture/tui-runtime"
function defer<T>() {
let resolve!: (value: T | PromiseLike<T>) => void

View file

@ -33,7 +33,7 @@ describe("Mini tool presentation", () => {
type: "update",
filePath: "/tmp/project/src/a.ts",
relativePath: "src/a.ts",
diff: "@@ -1 +1 @@\n-old\n+new",
patch: "@@ -1 +1 @@\n-old\n+new",
},
],
},