diff --git a/packages/opencode/src/cli/cmd/tui/context/kv.tsx b/packages/opencode/src/cli/cmd/tui/context/kv.tsx index 91838f4377..43266315bf 100644 --- a/packages/opencode/src/cli/cmd/tui/context/kv.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/kv.tsx @@ -14,8 +14,10 @@ export const { use: useKV, provider: KVProvider } = createSimpleContext({ const [store, setStore] = createStore>() const filePath = path.join(Global.Path.state, "kv.json") const lock = `tui-kv:${filePath}` + // Queue same-process writes so rapid updates persist in order. let write = Promise.resolve() + // Write to a temp file first so kv.json is only replaced once the JSON is complete, avoiding partial writes if shutdown interrupts persistence. function writeSnapshot(snapshot: Record) { const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp` return Filesystem.writeJson(tempPath, snapshot) @@ -26,6 +28,7 @@ export const { use: useKV, provider: KVProvider } = createSimpleContext({ }) } + // Read under the same lock used for writes because kv.json is shared across processes. Flock.withLock(lock, () => Filesystem.readJson>(filePath)) .then((x) => { setStore(x)