summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-29 08:47:27 -0600
committerAdam <[email protected]>2025-12-29 08:47:38 -0600
commitc4930eb6b219a2011cddc70a9b76f41809418114 (patch)
treece90fdd5b21622fcb8b1a3b851e0842d771ac112 /packages/app/src
parenta24549fce77b12f025f0583063df2c7f23ad3ffc (diff)
downloadopencode-c4930eb6b219a2011cddc70a9b76f41809418114.tar.gz
opencode-c4930eb6b219a2011cddc70a9b76f41809418114.zip
fix(desktop): more fine-grained state updates for permissions
Diffstat (limited to 'packages/app/src')
-rw-r--r--packages/app/src/context/global-sync.tsx65
1 files changed, 44 insertions, 21 deletions
diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx
index 0296dfad3..e1dcf15fc 100644
--- a/packages/app/src/context/global-sync.tsx
+++ b/packages/app/src/context/global-sync.tsx
@@ -23,7 +23,7 @@ import { Binary } from "@opencode-ai/util/binary"
import { retry } from "@opencode-ai/util/retry"
import { useGlobalSDK } from "./global-sdk"
import { ErrorPage, type InitError } from "../pages/error"
-import { createContext, useContext, onMount, type ParentProps, Switch, Match } from "solid-js"
+import { batch, createContext, useContext, onMount, type ParentProps, Switch, Match } from "solid-js"
import { showToast } from "@opencode-ai/ui/toast"
import { getFilename } from "@opencode-ai/util/path"
@@ -135,7 +135,7 @@ function createGlobalSync() {
async function bootstrapInstance(directory: string) {
if (!directory) return
- const [, setStore] = child(directory)
+ const [store, setStore] = child(directory)
const sdk = createOpencodeClient({
baseUrl: globalSDK.url,
directory,
@@ -167,12 +167,32 @@ function createGlobalSync() {
vcs: () => sdk.vcs.get().then((x) => setStore("vcs", x.data)),
permission: () =>
sdk.permission.list().then((x) => {
- const grouped: Record<string, typeof x.data> = {}
+ const grouped: Record<string, Permission[]> = {}
for (const perm of x.data ?? []) {
- grouped[perm.sessionID] = grouped[perm.sessionID] ?? []
- grouped[perm.sessionID]!.push(perm)
+ const existing = grouped[perm.sessionID]
+ if (existing) {
+ existing.push(perm)
+ continue
+ }
+ grouped[perm.sessionID] = [perm]
}
- setStore("permission", grouped)
+
+ batch(() => {
+ for (const sessionID of Object.keys(store.permission)) {
+ if (grouped[sessionID]) continue
+ setStore("permission", sessionID, [])
+ }
+ for (const [sessionID, permissions] of Object.entries(grouped)) {
+ setStore(
+ "permission",
+ sessionID,
+ reconcile(
+ permissions.slice().sort((a, b) => a.id.localeCompare(b.id)),
+ { key: "id" },
+ ),
+ )
+ }
+ })
}),
}
await Promise.all(Object.values(load).map((p) => retry(p).catch((e) => setGlobalStore("error", e))))
@@ -325,23 +345,26 @@ function createGlobalSync() {
break
}
case "permission.updated": {
- const permissions = store.permission[event.properties.sessionID]
+ const sessionID = event.properties.sessionID
+ const permissions = store.permission[sessionID]
if (!permissions) {
- setStore("permission", event.properties.sessionID, [event.properties])
- } else {
- const result = Binary.search(permissions, event.properties.id, (p) => p.id)
- setStore(
- "permission",
- event.properties.sessionID,
- produce((draft) => {
- if (result.found) {
- draft[result.index] = event.properties
- return
- }
- draft.push(event.properties)
- }),
- )
+ setStore("permission", sessionID, [event.properties])
+ break
}
+
+ const result = Binary.search(permissions, event.properties.id, (p) => p.id)
+ if (result.found) {
+ setStore("permission", sessionID, result.index, reconcile(event.properties))
+ break
+ }
+
+ setStore(
+ "permission",
+ sessionID,
+ produce((draft) => {
+ draft.splice(result.index, 0, event.properties)
+ }),
+ )
break
}
case "permission.replied": {