diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx
index 06c4d1c9..0399a1c8 100644
--- a/packages/opencode/src/cli/cmd/tui/app.tsx
+++ b/packages/opencode/src/cli/cmd/tui/app.tsx
@@ -249,7 +249,7 @@ function App() {
createEffect(() => {
const providerID = local.model.current().providerID
- if (providerID === "openrouter" && !kv.data.openrouter_warning) {
+ if (providerID === "openrouter" && !kv.get("openrouter_warning", false)) {
untrack(() => {
DialogAlert.show(
dialog,
diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx
index 33a5d816..41f33878 100644
--- a/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/dialog-session-list.tsx
@@ -76,7 +76,7 @@ export function DialogSessionList() {
},
},
{
- keybind: Keybind.parse("r")[0],
+ keybind: Keybind.parse("ctrl+r")[0],
title: "rename",
onTrigger: async (option) => {
dialog.replace(() => )
diff --git a/packages/opencode/src/cli/cmd/tui/context/kv.tsx b/packages/opencode/src/cli/cmd/tui/context/kv.tsx
index bb9ae847..24a9a554 100644
--- a/packages/opencode/src/cli/cmd/tui/context/kv.tsx
+++ b/packages/opencode/src/cli/cmd/tui/context/kv.tsx
@@ -1,5 +1,5 @@
import { Global } from "@/global"
-import { createSignal } from "solid-js"
+import { createSignal, type Setter } from "solid-js"
import { createStore } from "solid-js/store"
import { createSimpleContext } from "./helper"
import path from "path"
@@ -8,10 +8,7 @@ export const { use: useKV, provider: KVProvider } = createSimpleContext({
name: "KV",
init: () => {
const [ready, setReady] = createSignal(false)
- const [kvStore, setKvStore] = createStore({
- openrouter_warning: false,
- theme: "opencode",
- })
+ const [kvStore, setKvStore] = createStore>()
const file = Bun.file(path.join(Global.Path.state, "kv.json"))
file
@@ -24,22 +21,29 @@ export const { use: useKV, provider: KVProvider } = createSimpleContext({
setReady(true)
})
- return {
- get data() {
- return kvStore
- },
+ const result = {
get ready() {
return ready()
},
+ signal(name: string, defaultValue: T) {
+ if (!kvStore[name]) setKvStore(name, defaultValue)
+ return [
+ function () {
+ return result.get(name)
+ },
+ function setter(next: Setter) {
+ result.set(name, next)
+ },
+ ] as const
+ },
+ get(key: string, defaultValue?: any) {
+ return kvStore[key] ?? defaultValue
+ },
set(key: string, value: any) {
- setKvStore(key as any, value)
- Bun.write(
- file,
- JSON.stringify({
- [key]: value,
- }),
- )
+ setKvStore(key, value)
+ Bun.write(file, JSON.stringify(kvStore, null, 2))
},
}
+ return result
},
})
diff --git a/packages/opencode/src/cli/cmd/tui/context/theme.tsx b/packages/opencode/src/cli/cmd/tui/context/theme.tsx
index b5c8f21f..0add8d95 100644
--- a/packages/opencode/src/cli/cmd/tui/context/theme.tsx
+++ b/packages/opencode/src/cli/cmd/tui/context/theme.tsx
@@ -629,7 +629,7 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
const sync = useSync()
const kv = useKV()
- const [theme, setTheme] = createSignal(sync.data.config.theme ?? kv.data.theme)
+ const [theme, setTheme] = createSignal(sync.data.config.theme ?? kv.get("theme", "opencode"))
const values = createMemo(() => {
return THEMES[theme()] ?? THEMES.opencode
@@ -643,7 +643,7 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
},
}),
get selected() {
- return kv.data.theme
+ return theme()
},
set(theme: string) {
if (!THEMES[theme]) return
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 d089826d..7eb05cd4 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -65,6 +65,7 @@ import parsers from "../../../../../../parsers-config.ts"
import { Clipboard } from "../../util/clipboard"
import { Toast, useToast } from "../../ui/toast"
import { DialogSessionRename } from "../../component/dialog-session-rename"
+import { useKV } from "../../context/kv.tsx"
addDefaultParsers(parsers.parsers)
@@ -82,6 +83,7 @@ function use() {
export function Session() {
const route = useRouteData("session")
const sync = useSync()
+ const kv = useKV()
const { theme } = useTheme()
const session = createMemo(() => sync.session.get(route.sessionID)!)
const messages = createMemo(() => sync.data.message[route.sessionID] ?? [])
@@ -92,7 +94,7 @@ export function Session() {
})
const dimensions = useTerminalDimensions()
- const [sidebar, setSidebar] = createSignal<"show" | "hide" | "auto">("auto")
+ const [sidebar, setSidebar] = createSignal<"show" | "hide" | "auto">(kv.get("sidebar", "auto"))
const [conceal, setConceal] = createSignal(true)
const wide = createMemo(() => dimensions().width > 120)
@@ -200,19 +202,18 @@ export function Session() {
disabled: !!session()?.share?.url,
category: "Session",
onSelect: async (dialog) => {
- await sdk.client.session.share({
- path: {
- id: route.sessionID,
- },
- })
+ await sdk.client.session
+ .share({
+ path: {
+ id: route.sessionID,
+ },
+ })
.then((res) =>
Clipboard.copy(res.data!.share!.url).catch(() =>
- toast.show({ message: "Failed to copy URL to clipboard", variant: "error" })
- )
- )
- .then(() =>
- toast.show({ message: "Share URL copied to clipboard!", variant: "success" })
+ toast.show({ message: "Failed to copy URL to clipboard", variant: "error" }),
+ ),
)
+ .then(() => toast.show({ message: "Share URL copied to clipboard!", variant: "success" }))
.catch(() => toast.show({ message: "Failed to share session", variant: "error" }))
dialog.clear()
},
@@ -306,6 +307,8 @@ export function Session() {
if (prev === "show") return "hide"
return "show"
})
+ if (sidebar() === "show") kv.set("sidebar", "auto")
+ if (sidebar() === "hide") kv.set("sidebar", "hide")
dialog.clear()
},
},
diff --git a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
index 515c7c3d..18b53498 100644
--- a/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
+++ b/packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx
@@ -242,7 +242,7 @@ export function DialogSelect(props: DialogSelectProps) {
)}
-
+
{(item) => (