@@ -3,6 +3,7 @@ import { useGlobalSync } from "@/context/global-sync"
33import { useLanguage } from "@/context/language"
44import { useLayout , type LocalProject , getAvatarColors } from "@/context/layout"
55import { useNotification } from "@/context/notification"
6+ import { usePermission } from "@/context/permission"
67import { base64Encode } from "@opencode-ai/util/encode"
78import { Avatar } from "@opencode-ai/ui/avatar"
89import { DiffChanges } from "@opencode-ai/ui/diff-changes"
@@ -16,16 +17,27 @@ import { getFilename } from "@opencode-ai/util/path"
1617import { type Message , type Session , type TextPart , type UserMessage } from "@opencode-ai/sdk/v2/client"
1718import { For , Match , Show , Switch , createMemo , onCleanup , type Accessor , type JSX } from "solid-js"
1819import { agentColor } from "@/utils/agent"
20+ import { hasProjectPermissions } from "./helpers"
21+ import { sessionPermissionRequest } from "../session/composer/session-request-tree"
1922
2023const OPENCODE_PROJECT_ID = "4b0ea68d7af9a6031a7ffda7ad66e0cb83315750"
2124
2225export const ProjectIcon = ( props : { project : LocalProject ; class ?: string ; notify ?: boolean } ) : JSX . Element => {
26+ const globalSync = useGlobalSync ( )
2327 const notification = useNotification ( )
28+ const permission = usePermission ( )
2429 const dirs = createMemo ( ( ) => [ props . project . worktree , ...( props . project . sandboxes ?? [ ] ) ] )
2530 const unseenCount = createMemo ( ( ) =>
2631 dirs ( ) . reduce ( ( total , directory ) => total + notification . project . unseenCount ( directory ) , 0 ) ,
2732 )
2833 const hasError = createMemo ( ( ) => dirs ( ) . some ( ( directory ) => notification . project . unseenHasError ( directory ) ) )
34+ const hasPermissions = createMemo ( ( ) =>
35+ dirs ( ) . some ( ( directory ) => {
36+ const [ store ] = globalSync . child ( directory , { bootstrap : false } )
37+ return hasProjectPermissions ( store . permission , ( item ) => ! permission . autoResponds ( item , directory ) )
38+ } ) ,
39+ )
40+ const notify = createMemo ( ( ) => props . notify && ( hasPermissions ( ) || unseenCount ( ) > 0 ) )
2941 const name = createMemo ( ( ) => props . project . name || getFilename ( props . project . worktree ) )
3042 return (
3143 < div class = { `relative size-8 shrink-0 rounded ${ props . class ?? "" } ` } >
@@ -37,15 +49,16 @@ export const ProjectIcon = (props: { project: LocalProject; class?: string; noti
3749 }
3850 { ...getAvatarColors ( props . project . icon ?. color ) }
3951 class = "size-full rounded"
40- classList = { { "badge-mask" : unseenCount ( ) > 0 && props . notify } }
52+ classList = { { "badge-mask" : notify ( ) } }
4153 />
4254 </ div >
43- < Show when = { unseenCount ( ) > 0 && props . notify } >
55+ < Show when = { notify ( ) } >
4456 < div
4557 classList = { {
4658 "absolute top-px right-px size-1.5 rounded-full z-10" : true ,
47- "bg-icon-critical-base" : hasError ( ) ,
48- "bg-text-interactive-base" : ! hasError ( ) ,
59+ "bg-surface-warning-strong" : hasPermissions ( ) ,
60+ "bg-icon-critical-base" : ! hasPermissions ( ) && hasError ( ) ,
61+ "bg-text-interactive-base" : ! hasPermissions ( ) && ! hasError ( ) ,
4962 } }
5063 />
5164 </ Show >
@@ -186,19 +199,15 @@ export const SessionItem = (props: SessionItemProps): JSX.Element => {
186199 const layout = useLayout ( )
187200 const language = useLanguage ( )
188201 const notification = useNotification ( )
202+ const permission = usePermission ( )
189203 const globalSync = useGlobalSync ( )
190204 const unseenCount = createMemo ( ( ) => notification . session . unseenCount ( props . session . id ) )
191205 const hasError = createMemo ( ( ) => notification . session . unseenHasError ( props . session . id ) )
192206 const [ sessionStore ] = globalSync . child ( props . session . directory )
193207 const hasPermissions = createMemo ( ( ) => {
194- const permissions = sessionStore . permission ?. [ props . session . id ] ?? [ ]
195- if ( permissions . length > 0 ) return true
196-
197- for ( const id of props . children . get ( props . session . id ) ?? [ ] ) {
198- const childPermissions = sessionStore . permission ?. [ id ] ?? [ ]
199- if ( childPermissions . length > 0 ) return true
200- }
201- return false
208+ return ! ! sessionPermissionRequest ( sessionStore . session , sessionStore . permission , props . session . id , ( item ) => {
209+ return ! permission . autoResponds ( item , props . session . directory )
210+ } )
202211 } )
203212 const isWorking = createMemo ( ( ) => {
204213 if ( hasPermissions ( ) ) return false
0 commit comments