@@ -20,6 +20,13 @@ type ScopePrompt = {
2020 scope : AskPermissionScope ;
2121} ;
2222
23+ type PromptOption = {
24+ kind : "allow" | "always" | "deny" ;
25+ label : string ;
26+ scopeDescription ?: string ;
27+ scopeColor ?: string ;
28+ } ;
29+
2330const ALWAYS_ALLOWED_SCOPES = new Set < AskPermissionScope > ( [
2431 "read-in-cwd" ,
2532 "read-out-cwd" ,
@@ -138,7 +145,7 @@ export function PermissionPrompt({ requests, onSubmit, onCancel }: Props): React
138145 { options . map ( ( option , optionIndex ) => (
139146 < Text key = { option . kind } color = { optionIndex === cursor ? "cyanBright" : undefined } >
140147 { optionIndex === cursor ? "> " : " " }
141- { optionIndex + 1 } . { option . label }
148+ { optionIndex + 1 } . { renderOptionLabel ( option ) }
142149 </ Text >
143150 ) ) }
144151 </ Box >
@@ -149,6 +156,18 @@ export function PermissionPrompt({ requests, onSubmit, onCancel }: Props): React
149156 ) ;
150157}
151158
159+ function renderOptionLabel ( option : PromptOption ) : React . ReactNode {
160+ if ( option . scopeDescription && option . scopeColor ) {
161+ return (
162+ < >
163+ { option . label }
164+ < Text color = { option . scopeColor } > { option . scopeDescription } </ Text >
165+ </ >
166+ ) ;
167+ }
168+ return option . label ;
169+ }
170+
152171function buildScopePrompts ( requests : AskPermissionRequest [ ] ) : ScopePrompt [ ] {
153172 const prompts : ScopePrompt [ ] = [ ] ;
154173 for ( const request of requests ) {
@@ -159,10 +178,15 @@ function buildScopePrompts(requests: AskPermissionRequest[]): ScopePrompt[] {
159178 return prompts ;
160179}
161180
162- function buildOptions ( scope : AskPermissionScope ) : Array < { kind : "allow" | "always" | "deny" ; label : string } > {
163- const options : Array < { kind : "allow" | "always" | "deny" ; label : string } > = [ { kind : "allow" , label : "Yes" } ] ;
181+ function buildOptions ( scope : AskPermissionScope ) : PromptOption [ ] {
182+ const options : PromptOption [ ] = [ { kind : "allow" , label : "Yes" } ] ;
164183 if ( isAlwaysAllowedScope ( scope ) ) {
165- options . push ( { kind : "always" , label : `Yes, and always allow ${ describeScope ( scope ) } ` } ) ;
184+ options . push ( {
185+ kind : "always" ,
186+ label : "Yes, and always allow " ,
187+ scopeDescription : describeScope ( scope ) ,
188+ scopeColor : getScopeRiskColor ( scope ) ,
189+ } ) ;
166190 }
167191 options . push ( { kind : "deny" , label : "No" } ) ;
168192 return options ;
@@ -201,6 +225,27 @@ function isAlwaysAllowedScope(scope: AskPermissionScope): scope is PermissionSco
201225 return ALWAYS_ALLOWED_SCOPES . has ( scope ) ;
202226}
203227
228+ export function getScopeRiskColor ( scope : AskPermissionScope ) : string {
229+ switch ( scope ) {
230+ case "read-in-cwd" :
231+ case "query-git-log" :
232+ return "#22c55e" ;
233+ case "read-out-cwd" :
234+ case "write-in-cwd" :
235+ case "network" :
236+ case "mcp" :
237+ return "#f59e0b" ;
238+ case "write-out-cwd" :
239+ case "delete-in-cwd" :
240+ case "delete-out-cwd" :
241+ case "mutate-git-log" :
242+ case "unknown" :
243+ return "#ef4444" ;
244+ default :
245+ return "#ef4444" ;
246+ }
247+ }
248+
204249function describeScope ( scope : PermissionScope ) : string {
205250 switch ( scope ) {
206251 case "read-in-cwd" :
0 commit comments