Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 105 additions & 43 deletions packages/opencode/src/cli/cmd/tui/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -469,34 +477,92 @@ function App() {
category: "System",
},
{
title: "Help",
value: "help.show",
slash: {
name: "help",
},
onSelect: () => {
dialog.replace(() => <DialogHelp />)
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",
Expand Down Expand Up @@ -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(() => <DialogHelp />)
},
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))
})
}
})
Expand Down
69 changes: 6 additions & 63 deletions packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down Expand Up @@ -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",
Expand Down