From 761863ae355b3ca1e606ea5eb2106772fa763c19 Mon Sep 17 00:00:00 2001
From: Adam <2363879+adamdotdevin@users.noreply.github.com>
Date: Tue, 6 Jan 2026 21:38:08 -0600
Subject: chore(app): rework storage approach

---
 packages/app/src/context/file.tsx | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

(limited to 'packages/app/src/context/file.tsx')

diff --git a/packages/app/src/context/file.tsx b/packages/app/src/context/file.tsx
index a26f97c2a..ff36919a1 100644
--- a/packages/app/src/context/file.tsx
+++ b/packages/app/src/context/file.tsx
@@ -1,4 +1,4 @@
-import { createMemo, onCleanup } from "solid-js"
+import { createEffect, createMemo, onCleanup } from "solid-js"
 import { createStore, produce } from "solid-js/store"
 import { createSimpleContext } from "@opencode-ai/ui/context"
 import type { FileContent } from "@opencode-ai/sdk/v2"
@@ -7,7 +7,7 @@ import { useParams } from "@solidjs/router"
 import { getFilename } from "@opencode-ai/util/path"
 import { useSDK } from "./sdk"
 import { useSync } from "./sync"
-import { persisted } from "@/utils/persist"
+import { Persist, persisted } from "@/utils/persist"
 
 export type FileSelection = {
   startLine: number
@@ -134,10 +134,10 @@ export const { use: useFile, provider: FileProvider } = createSimpleContext({
       file: {},
     })
 
-    const viewKey = createMemo(() => `${params.dir}/file${params.id ? "/" + params.id : ""}.v1`)
+    const legacyViewKey = createMemo(() => `${params.dir}/file${params.id ? "/" + params.id : ""}.v1`)
 
     const [view, setView, _, ready] = persisted(
-      viewKey(),
+      Persist.scoped(params.dir, params.id, "file-view", [legacyViewKey()]),
       createStore<{
         file: Record<string, FileViewState>
       }>({
@@ -145,6 +145,32 @@ export const { use: useFile, provider: FileProvider } = createSimpleContext({
       }),
     )
 
+    const MAX_VIEW_FILES = 500
+    const viewMeta = { pruned: false }
+
+    const pruneView = (keep?: string) => {
+      const keys = Object.keys(view.file)
+      if (keys.length <= MAX_VIEW_FILES) return
+
+      const drop = keys.filter((key) => key !== keep).slice(0, keys.length - MAX_VIEW_FILES)
+      if (drop.length === 0) return
+
+      setView(
+        produce((draft) => {
+          for (const key of drop) {
+            delete draft.file[key]
+          }
+        }),
+      )
+    }
+
+    createEffect(() => {
+      if (!ready()) return
+      if (viewMeta.pruned) return
+      viewMeta.pruned = true
+      pruneView()
+    })
+
     function ensure(path: string) {
       if (!path) return
       if (store.file[path]) return
@@ -233,6 +259,7 @@ export const { use: useFile, provider: FileProvider } = createSimpleContext({
           scrollTop: top,
         }
       })
+      pruneView(path)
     }
 
     const setScrollLeft = (input: string, left: number) => {
@@ -244,6 +271,7 @@ export const { use: useFile, provider: FileProvider } = createSimpleContext({
           scrollLeft: left,
         }
       })
+      pruneView(path)
     }
 
     const setSelectedLines = (input: string, range: SelectedLineRange | null) => {
@@ -256,6 +284,7 @@ export const { use: useFile, provider: FileProvider } = createSimpleContext({
           selectedLines: next,
         }
       })
+      pruneView(path)
     }
 
     onCleanup(() => stop())
-- 
cgit v1.2.3

