summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/context
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-31 13:12:24 -0600
committerAdam <[email protected]>2025-12-31 13:12:31 -0600
commit93845db4623f157dff96a3a1ef440e21ab865769 (patch)
tree9545ed6d2139e20c53a2c3f32f2b89691b3e7da4 /packages/app/src/context
parent65bc72098b737bee12f388215913808fa1629a4d (diff)
downloadopencode-93845db4623f157dff96a3a1ef440e21ab865769.tar.gz
opencode-93845db4623f157dff96a3a1ef440e21ab865769.zip
fix(desktop): don't show notifs if auto-accepting
Diffstat (limited to 'packages/app/src/context')
-rw-r--r--packages/app/src/context/permission.tsx121
1 files changed, 51 insertions, 70 deletions
diff --git a/packages/app/src/context/permission.tsx b/packages/app/src/context/permission.tsx
index 6d7b335ad..d82a8392c 100644
--- a/packages/app/src/context/permission.tsx
+++ b/packages/app/src/context/permission.tsx
@@ -1,17 +1,15 @@
-import { createEffect, createRoot, onCleanup } from "solid-js"
+import { onCleanup } from "solid-js"
import { createStore } from "solid-js/store"
import { createSimpleContext } from "@opencode-ai/ui/context"
import type { Permission } from "@opencode-ai/sdk/v2/client"
import { persisted } from "@/utils/persist"
-
-type PermissionsBySession = {
- [sessionID: string]: Permission[]
-}
+import { useGlobalSDK } from "@/context/global-sdk"
type PermissionRespondFn = (input: {
sessionID: string
permissionID: string
response: "once" | "always" | "reject"
+ directory?: string
}) => void
const AUTO_ACCEPT_TYPES = new Set(["edit", "write"])
@@ -22,105 +20,88 @@ function shouldAutoAccept(perm: Permission) {
export const { use: usePermission, provider: PermissionProvider } = createSimpleContext({
name: "Permission",
- init: (props: { permissions: PermissionsBySession; onRespond: PermissionRespondFn }) => {
+ init: () => {
+ const globalSDK = useGlobalSDK()
const [store, setStore, _, ready] = persisted(
- "permission.v1",
+ "permission.v3",
createStore({
autoAcceptEdits: {} as Record<string, boolean>,
}),
)
const responded = new Set<string>()
- const watches = new Map<string, () => void>()
-
- function respond(perm: Permission) {
- if (responded.has(perm.id)) return
- responded.add(perm.id)
- props.onRespond({
- sessionID: perm.sessionID,
- permissionID: perm.id,
- response: "once",
+
+ const respond: PermissionRespondFn = (input) => {
+ globalSDK.client.permission.respond(input).catch(() => {
+ responded.delete(input.permissionID)
})
}
- function watch(sessionID: string) {
- if (watches.has(sessionID)) return
-
- const dispose = createRoot((dispose) => {
- createEffect(() => {
- if (!store.autoAcceptEdits[sessionID]) return
-
- const permissions = props.permissions[sessionID] ?? []
- permissions.length
-
- for (const perm of permissions) {
- if (!shouldAutoAccept(perm)) continue
- respond(perm)
- }
- })
-
- return dispose
+ function respondOnce(permission: Permission, directory?: string) {
+ if (responded.has(permission.id)) return
+ responded.add(permission.id)
+ respond({
+ sessionID: permission.sessionID,
+ permissionID: permission.id,
+ response: "once",
+ directory,
})
-
- watches.set(sessionID, dispose)
}
- function unwatch(sessionID: string) {
- const dispose = watches.get(sessionID)
- if (!dispose) return
- dispose()
- watches.delete(sessionID)
+ function isAutoAccepting(sessionID: string) {
+ return store.autoAcceptEdits[sessionID] ?? false
}
- createEffect(() => {
- if (!ready()) return
+ const unsubscribe = globalSDK.event.listen((e) => {
+ const event = e.details
+ if (event?.type !== "permission.updated") return
- for (const sessionID in store.autoAcceptEdits) {
- if (!store.autoAcceptEdits[sessionID]) continue
- watch(sessionID)
- }
- })
+ const perm = event.properties
+ if (!isAutoAccepting(perm.sessionID)) return
+ if (!shouldAutoAccept(perm)) return
- onCleanup(() => {
- for (const dispose of watches.values()) dispose()
- watches.clear()
+ respondOnce(perm, e.name)
})
+ onCleanup(unsubscribe)
- function enable(sessionID: string) {
+ function enable(sessionID: string, directory: string) {
setStore("autoAcceptEdits", sessionID, true)
- watch(sessionID)
- const permissions = props.permissions[sessionID] ?? []
- for (const perm of permissions) {
- if (!shouldAutoAccept(perm)) continue
- respond(perm)
- }
+ globalSDK.client.permission
+ .list({ directory })
+ .then((x) => {
+ for (const perm of x.data ?? []) {
+ if (!perm?.id) continue
+ if (perm.sessionID !== sessionID) continue
+ if (!shouldAutoAccept(perm)) continue
+ respondOnce(perm, directory)
+ }
+ })
+ .catch(() => undefined)
}
function disable(sessionID: string) {
setStore("autoAcceptEdits", sessionID, false)
- unwatch(sessionID)
}
return {
- get permissions() {
- return props.permissions
- },
- respond: props.onRespond,
- isAutoAccepting(sessionID: string) {
- return store.autoAcceptEdits[sessionID] ?? false
+ ready,
+ respond,
+ autoResponds(permission: Permission) {
+ return isAutoAccepting(permission.sessionID) && shouldAutoAccept(permission)
},
- toggleAutoAccept(sessionID: string) {
- if (store.autoAcceptEdits[sessionID]) {
+ isAutoAccepting,
+ toggleAutoAccept(sessionID: string, directory: string) {
+ if (isAutoAccepting(sessionID)) {
disable(sessionID)
return
}
- enable(sessionID)
+ enable(sessionID, directory)
},
- enableAutoAccept(sessionID: string) {
- if (store.autoAcceptEdits[sessionID]) return
- enable(sessionID)
+ enableAutoAccept(sessionID: string, directory: string) {
+ if (isAutoAccepting(sessionID)) return
+ enable(sessionID, directory)
},
disableAutoAccept(sessionID: string) {
disable(sessionID)