// opencode TUI plugin: one key toggles the whole "verbose view". // // The session view keeps four independent display toggles in the TUI's persisted KV store // (~/.local/state/opencode/kv.json). Built-in commands only flip one each. This plugin reads all // four and drives them to the same state: if every one is on, turn all off; otherwise turn all on. // Writing the KV keys directly is what the built-in toggles do too (kv.signal is a reactive // store), so the open session re-renders immediately and the choice survives restarts. // // Declared in tui.json: "plugin": [["./tui-plugins/verbose.ts", { "key": "v" }]] // (TUI plugins are never auto-discovered, and this dir is deliberately NOT ~/.config/opencode/plugins/, // which the server-side plugin loader scans and would reject a TUI-only module.) // Also available as /verbose and from the command palette. import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@opencode-ai/plugin/tui" // KV keys + values as used by packages/tui/src/routes/session/index.tsx and context/thinking.ts (v1.18.29) const KEYS = { details: "tool_details_visibility", // boolean, default true generic: "generic_tool_output_visibility", // boolean, default false timestamps: "timestamps", // "show" | "hide", default "hide" thinking: "thinking_mode", // "show" | "hide", default "hide" } as const const COMMAND = "verbose.toggle" function current(api: TuiPluginApi) { return { details: api.kv.get(KEYS.details, true) === true, generic: api.kv.get(KEYS.generic, false) === true, timestamps: api.kv.get(KEYS.timestamps, "hide") === "show", thinking: api.kv.get(KEYS.thinking, "hide") === "show", } } function apply(api: TuiPluginApi, on: boolean) { api.kv.set(KEYS.details, on) api.kv.set(KEYS.generic, on) api.kv.set(KEYS.timestamps, on ? "show" : "hide") api.kv.set(KEYS.thinking, on ? "show" : "hide") } const tui: TuiPlugin = async (api, options) => { const opts = (options ?? {}) as Record const key = typeof opts.key === "string" && opts.key.length > 0 ? opts.key : "v" api.keymap.registerLayer({ mode: "base", commands: [ { name: COMMAND, title: "Toggle verbose view (tool details, generic output, thinking, timestamps)", category: "Session", namespace: "palette", slashName: "verbose", run() { const state = current(api) const on = !Object.values(state).every(Boolean) apply(api, on) api.ui.toast({ variant: "info", message: on ? "Verbose view on" : "Verbose view off", duration: 1500, }) }, }, ], bindings: [{ key, cmd: COMMAND, desc: "Toggle verbose view" }], }) } const plugin: TuiPluginModule & { id: string } = { id: "coja.verbose", tui } export default plugin