diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx
index 10d7a25f88f..bf6a7b228ff 100644
--- a/packages/opencode/src/cli/cmd/tui/app.tsx
+++ b/packages/opencode/src/cli/cmd/tui/app.tsx
@@ -205,7 +205,15 @@ function App() {
.catch(toast.error)
renderer.clearSelection()
}
- const [terminalTitleEnabled, setTerminalTitleEnabled] = createSignal(kv.get("terminal_title_enabled", true))
+ const [terminalTitleEnabled, setTerminalTitleEnabled] = kv.signal("terminal_title_enabled", true)
+ const [codeConceal, setCodeConceal] = kv.signal("conceal_code", true)
+ const [timestamps, setTimestamps] = kv.signal<"hide" | "show">("timestamps", "hide")
+ const [showThinking, setShowThinking] = kv.signal("thinking_visibility", true)
+ const [showDetails, setShowDetails] = kv.signal("tool_details_visibility", true)
+ const [_, setShowScrollbar] = kv.signal("scrollbar_visible", false)
+ const [animationsEnabled, setAnimationsEnabled] = kv.signal("animations_enabled", true)
+ const [diffWrapMode, setDiffWrapMode] = kv.signal<"word" | "none">("diff_wrap_mode", "word")
+ const [openrouterWarning, setOpenrouterWarning] = kv.signal("openrouter_warning", false)
createEffect(() => {
console.log(JSON.stringify(route.data))
@@ -469,34 +477,92 @@ function App() {
category: "System",
},
{
- title: "Help",
- value: "help.show",
- slash: {
- name: "help",
- },
- onSelect: () => {
- dialog.replace(() => )
+ title: animationsEnabled() ? "Disable animations" : "Enable animations",
+ value: "app.toggle.animations",
+ category: "System",
+ onSelect: (dialog) => {
+ setAnimationsEnabled((prev) => !prev)
+ dialog.clear()
},
+ },
+ {
+ title: diffWrapMode() === "word" ? "Disable diff wrapping" : "Enable diff wrapping",
+ value: "app.toggle.diffwrap",
category: "System",
+ onSelect: (dialog) => {
+ setDiffWrapMode((prev) => (prev === "word" ? "none" : "word"))
+ dialog.clear()
+ },
},
{
- title: "Open docs",
- value: "docs.open",
- onSelect: () => {
- open("https://opencode.ai/docs").catch(() => {})
+ title: codeConceal() ? "Disable code concealment" : "Enable code concealment",
+ value: "app.toggle.conceal",
+ keybind: "messages_toggle_conceal",
+ category: "System",
+ onSelect: (dialog) => {
+ setCodeConceal((prev) => !prev)
dialog.clear()
},
+ },
+ {
+ title: timestamps() === "show" ? "Hide timestamps" : "Show timestamps",
+ value: "app.toggle.timestamps",
category: "System",
+ slash: {
+ name: "timestamps",
+ aliases: ["toggle-timestamps"],
+ },
+ onSelect: (dialog) => {
+ setTimestamps((prev) => (prev === "show" ? "hide" : "show"))
+ dialog.clear()
+ },
},
{
- title: "Exit the app",
- value: "app.exit",
+ title: showThinking() ? "Hide thinking" : "Show thinking",
+ value: "app.toggle.thinking",
+ category: "System",
slash: {
- name: "exit",
- aliases: ["quit", "q"],
+ name: "thinking",
+ aliases: ["toggle-thinking"],
},
- onSelect: () => exit(),
+ onSelect: (dialog) => {
+ setShowThinking((prev) => !prev)
+ dialog.clear()
+ },
+ },
+ {
+ title: showDetails() ? "Hide tool details" : "Show tool details",
+ value: "app.toggle.actions",
+ keybind: "tool_details",
+ category: "System",
+ onSelect: (dialog) => {
+ setShowDetails((prev) => !prev)
+ dialog.clear()
+ },
+ },
+ {
+ title: "Toggle session scrollbar",
+ value: "app.toggle.scrollbar",
+ keybind: "scrollbar_toggle",
+ category: "System",
+ onSelect: (dialog) => {
+ setShowScrollbar((prev) => !prev)
+ dialog.clear()
+ },
+ },
+ {
+ title: terminalTitleEnabled() ? "Disable terminal title" : "Enable terminal title",
+ value: "terminal.title.toggle",
+ keybind: "terminal_title_toggle",
category: "System",
+ onSelect: (dialog) => {
+ setTerminalTitleEnabled((prev) => {
+ const next = !prev
+ if (!next) renderer.setTerminalTitle("")
+ return next
+ })
+ dialog.clear()
+ },
},
{
title: "Toggle debug panel",
@@ -547,51 +613,47 @@ function App() {
},
},
{
- title: terminalTitleEnabled() ? "Disable terminal title" : "Enable terminal title",
- value: "terminal.title.toggle",
- keybind: "terminal_title_toggle",
- category: "System",
- onSelect: (dialog) => {
- setTerminalTitleEnabled((prev) => {
- const next = !prev
- kv.set("terminal_title_enabled", next)
- if (!next) renderer.setTerminalTitle("")
- return next
- })
- dialog.clear()
+ title: "Help",
+ value: "help.show",
+ slash: {
+ name: "help",
},
+ onSelect: () => {
+ dialog.replace(() => )
+ },
+ category: "System",
},
{
- title: kv.get("animations_enabled", true) ? "Disable animations" : "Enable animations",
- value: "app.toggle.animations",
- category: "System",
- onSelect: (dialog) => {
- kv.set("animations_enabled", !kv.get("animations_enabled", true))
+ title: "Open docs",
+ value: "docs.open",
+ onSelect: () => {
+ open("https://opencode.ai/docs").catch(() => {})
dialog.clear()
},
+ category: "System",
},
{
- title: kv.get("diff_wrap_mode", "word") === "word" ? "Disable diff wrapping" : "Enable diff wrapping",
- value: "app.toggle.diffwrap",
- category: "System",
- onSelect: (dialog) => {
- const current = kv.get("diff_wrap_mode", "word")
- kv.set("diff_wrap_mode", current === "word" ? "none" : "word")
- dialog.clear()
+ title: "Exit app",
+ value: "app.exit",
+ slash: {
+ name: "exit",
+ aliases: ["quit", "q"],
},
+ onSelect: () => exit(),
+ category: "System",
},
])
createEffect(() => {
const currentModel = local.model.current()
if (!currentModel) return
- if (currentModel.providerID === "openrouter" && !kv.get("openrouter_warning", false)) {
+ if (currentModel.providerID === "openrouter" && !openrouterWarning()) {
untrack(() => {
DialogAlert.show(
dialog,
"Warning",
"While openrouter is a convenient way to access LLMs your request will often be routed to subpar providers that do not work well in our testing.\n\nFor reliable access to models check out OpenCode Zen\nhttps://opencode.ai/zen",
- ).then(() => kv.set("openrouter_warning", true))
+ ).then(() => setOpenrouterWarning(() => true))
})
}
})
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
index 5f47562d2e3..df08cdc6c77 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -139,14 +139,13 @@ export function Session() {
const dimensions = useTerminalDimensions()
const [sidebar, setSidebar] = kv.signal<"auto" | "hide">("sidebar", "hide")
const [sidebarOpen, setSidebarOpen] = createSignal(false)
- const [conceal, setConceal] = createSignal(true)
- const [showThinking, setShowThinking] = kv.signal("thinking_visibility", true)
- const [timestamps, setTimestamps] = kv.signal<"hide" | "show">("timestamps", "hide")
- const [showDetails, setShowDetails] = kv.signal("tool_details_visibility", true)
- const [showAssistantMetadata, setShowAssistantMetadata] = kv.signal("assistant_metadata_visibility", true)
- const [showScrollbar, setShowScrollbar] = kv.signal("scrollbar_visible", false)
+ const [conceal] = kv.signal("conceal_code", true)
+ const [showThinking] = kv.signal("thinking_visibility", true)
+ const [timestamps] = kv.signal<"hide" | "show">("timestamps", "hide")
+ const [showDetails] = kv.signal("tool_details_visibility", true)
+ const [showAssistantMetadata] = kv.signal("assistant_metadata_visibility", true)
+ const [showScrollbar] = kv.signal("scrollbar_visible", false)
const [diffWrapMode] = kv.signal<"word" | "none">("diff_wrap_mode", "word")
- const [animationsEnabled, setAnimationsEnabled] = kv.signal("animations_enabled", true)
const wide = createMemo(() => dimensions().width > 120)
const sidebarVisible = createMemo(() => {
@@ -502,62 +501,6 @@ export function Session() {
dialog.clear()
},
},
- {
- title: conceal() ? "Disable code concealment" : "Enable code concealment",
- value: "session.toggle.conceal",
- keybind: "messages_toggle_conceal" as any,
- category: "Session",
- onSelect: (dialog) => {
- setConceal((prev) => !prev)
- dialog.clear()
- },
- },
- {
- title: showTimestamps() ? "Hide timestamps" : "Show timestamps",
- value: "session.toggle.timestamps",
- category: "Session",
- slash: {
- name: "timestamps",
- aliases: ["toggle-timestamps"],
- },
- onSelect: (dialog) => {
- setTimestamps((prev) => (prev === "show" ? "hide" : "show"))
- dialog.clear()
- },
- },
- {
- title: showThinking() ? "Hide thinking" : "Show thinking",
- value: "session.toggle.thinking",
- category: "Session",
- slash: {
- name: "thinking",
- aliases: ["toggle-thinking"],
- },
- onSelect: (dialog) => {
- setShowThinking((prev) => !prev)
- dialog.clear()
- },
- },
- {
- title: showDetails() ? "Hide tool details" : "Show tool details",
- value: "session.toggle.actions",
- keybind: "tool_details",
- category: "Session",
- onSelect: (dialog) => {
- setShowDetails((prev) => !prev)
- dialog.clear()
- },
- },
- {
- title: "Toggle session scrollbar",
- value: "session.toggle.scrollbar",
- keybind: "scrollbar_toggle",
- category: "Session",
- onSelect: (dialog) => {
- setShowScrollbar((prev) => !prev)
- dialog.clear()
- },
- },
{
title: "Page up",
value: "session.page.up",