@@ -15,6 +15,7 @@ import {
1515 type McpStatus ,
1616 type LspStatus ,
1717 type VcsInfo ,
18+ type Permission ,
1819 createOpencodeClient ,
1920} from "@opencode-ai/sdk/v2/client"
2021import { createStore , produce , reconcile } from "solid-js/store"
@@ -44,6 +45,9 @@ type State = {
4445 todo : {
4546 [ sessionID : string ] : Todo [ ]
4647 }
48+ permission : {
49+ [ sessionID : string ] : Permission [ ]
50+ }
4751 mcp : {
4852 [ name : string ] : McpStatus
4953 }
@@ -78,6 +82,7 @@ function createGlobalSync() {
7882 } )
7983
8084 const children : Record < string , ReturnType < typeof createStore < State > > > = { }
85+ const permissionListeners : Set < ( info : { directory : string ; permission : Permission } ) => void > = new Set ( )
8186 function child ( directory : string ) {
8287 if ( ! directory ) console . error ( "No directory provided" )
8388 if ( ! children [ directory ] ) {
@@ -93,6 +98,7 @@ function createGlobalSync() {
9398 session_status : { } ,
9499 session_diff : { } ,
95100 todo : { } ,
101+ permission : { } ,
96102 mcp : { } ,
97103 lsp : [ ] ,
98104 vcs : undefined ,
@@ -163,6 +169,15 @@ function createGlobalSync() {
163169 mcp : ( ) => sdk . mcp . status ( ) . then ( ( x ) => setStore ( "mcp" , x . data ?? { } ) ) ,
164170 lsp : ( ) => sdk . lsp . status ( ) . then ( ( x ) => setStore ( "lsp" , x . data ?? [ ] ) ) ,
165171 vcs : ( ) => sdk . vcs . get ( ) . then ( ( x ) => setStore ( "vcs" , x . data ) ) ,
172+ permission : ( ) =>
173+ sdk . permission . list ( ) . then ( ( x ) => {
174+ const grouped : Record < string , typeof x . data > = { }
175+ for ( const perm of x . data ?? [ ] ) {
176+ grouped [ perm . sessionID ] = grouped [ perm . sessionID ] ?? [ ]
177+ grouped [ perm . sessionID ] ! . push ( perm )
178+ }
179+ setStore ( "permission" , grouped )
180+ } ) ,
166181 }
167182 await Promise . all ( Object . values ( load ) . map ( ( p ) => retry ( p ) . catch ( ( e ) => setGlobalStore ( "error" , e ) ) ) )
168183 . then ( ( ) => setStore ( "ready" , true ) )
@@ -313,6 +328,46 @@ function createGlobalSync() {
313328 setStore ( "vcs" , { branch : event . properties . branch } )
314329 break
315330 }
331+ case "permission.updated" : {
332+ const permissions = store . permission [ event . properties . sessionID ]
333+ const isNew = ! permissions || ! permissions . find ( ( p ) => p . id === event . properties . id )
334+ if ( ! permissions ) {
335+ setStore ( "permission" , event . properties . sessionID , [ event . properties ] )
336+ } else {
337+ const result = Binary . search ( permissions , event . properties . id , ( p ) => p . id )
338+ setStore (
339+ "permission" ,
340+ event . properties . sessionID ,
341+ produce ( ( draft ) => {
342+ if ( result . found ) {
343+ draft [ result . index ] = event . properties
344+ return
345+ }
346+ draft . push ( event . properties )
347+ } ) ,
348+ )
349+ }
350+ if ( isNew ) {
351+ for ( const listener of permissionListeners ) {
352+ listener ( { directory, permission : event . properties } )
353+ }
354+ }
355+ break
356+ }
357+ case "permission.replied" : {
358+ const permissions = store . permission [ event . properties . sessionID ]
359+ if ( ! permissions ) break
360+ const result = Binary . search ( permissions , event . properties . permissionID , ( p ) => p . id )
361+ if ( ! result . found ) break
362+ setStore (
363+ "permission" ,
364+ event . properties . sessionID ,
365+ produce ( ( draft ) => {
366+ draft . splice ( result . index , 1 )
367+ } ) ,
368+ )
369+ break
370+ }
316371 }
317372 } )
318373
@@ -384,6 +439,12 @@ function createGlobalSync() {
384439 project : {
385440 loadSessions,
386441 } ,
442+ permission : {
443+ onUpdated ( listener : ( info : { directory : string ; permission : Permission } ) => void ) {
444+ permissionListeners . add ( listener )
445+ return ( ) => permissionListeners . delete ( listener )
446+ } ,
447+ } ,
387448 }
388449}
389450
0 commit comments