Files
dots/common/.config/opencode/tui-plugins/verbose.ts
T
2026-09-17 20:58:21 +02:00

72 lines
2.8 KiB
TypeScript

// 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": "<leader>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<boolean>(KEYS.details, true) === true,
generic: api.kv.get<boolean>(KEYS.generic, false) === true,
timestamps: api.kv.get<string>(KEYS.timestamps, "hide") === "show",
thinking: api.kv.get<string>(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<string, unknown>
const key = typeof opts.key === "string" && opts.key.length > 0 ? opts.key : "<leader>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