@@ -33,9 +33,18 @@ type Shortcut struct {
3333 Command string
3434 Description string
3535 Risk string // "read" | "write" | "high-risk-write" (empty defaults to "read")
36- Scopes []string // default scopes (fallback when UserScopes/BotScopes are empty)
37- UserScopes []string // optional: user-identity scopes (overrides Scopes when non-empty)
38- BotScopes []string // optional: bot-identity scopes (overrides Scopes when non-empty)
36+ Scopes []string // unconditional pre-flight scopes (fallback when UserScopes/BotScopes are empty)
37+ UserScopes []string // optional: user-identity unconditional scopes (overrides Scopes when non-empty)
38+ BotScopes []string // optional: bot-identity unconditional scopes (overrides Scopes when non-empty)
39+
40+ // ConditionalScopes are additional scopes that only some execution paths
41+ // need (for example a default mode vs. a lighter --quick mode, or a
42+ // destructive flag like --delete-remote). They are surfaced in metadata,
43+ // auth hints, and scope-diagnosis output via DeclaredScopesForIdentity, but
44+ // they are NOT enforced by the framework's unconditional pre-flight check.
45+ ConditionalScopes []string // fallback when ConditionalUserScopes/BotScopes are empty
46+ ConditionalUserScopes []string // optional: user-identity conditional scopes
47+ ConditionalBotScopes []string // optional: bot-identity conditional scopes
3948
4049 // Declarative fields (new framework).
4150 AuthTypes []string // supported identities: "user", "bot" (default: ["user"])
@@ -72,3 +81,47 @@ func (s *Shortcut) ScopesForIdentity(identity string) []string {
7281 }
7382 return s .Scopes
7483}
84+
85+ // ConditionalScopesForIdentity returns additional flag/path-dependent scopes
86+ // for the given identity. Identity-specific conditional scopes override the
87+ // default ConditionalScopes when present.
88+ func (s * Shortcut ) ConditionalScopesForIdentity (identity string ) []string {
89+ switch identity {
90+ case "user" :
91+ if len (s .ConditionalUserScopes ) > 0 {
92+ return s .ConditionalUserScopes
93+ }
94+ case "bot" :
95+ if len (s .ConditionalBotScopes ) > 0 {
96+ return s .ConditionalBotScopes
97+ }
98+ }
99+ return s .ConditionalScopes
100+ }
101+
102+ // DeclaredScopesForIdentity returns the full scope set agents/help/diagnostics
103+ // should know about for this shortcut: unconditional pre-flight scopes plus
104+ // any conditional scopes that some execution paths may require.
105+ func (s * Shortcut ) DeclaredScopesForIdentity (identity string ) []string {
106+ base := s .ScopesForIdentity (identity )
107+ extra := s .ConditionalScopesForIdentity (identity )
108+ if len (base ) == 0 && len (extra ) == 0 {
109+ return nil
110+ }
111+ out := make ([]string , 0 , len (base )+ len (extra ))
112+ seen := make (map [string ]struct {}, len (base )+ len (extra ))
113+ for _ , scope := range append (base , extra ... ) {
114+ if scope == "" {
115+ continue
116+ }
117+ if _ , ok := seen [scope ]; ok {
118+ continue
119+ }
120+ seen [scope ] = struct {}{}
121+ out = append (out , scope )
122+ }
123+ if len (out ) == 0 {
124+ return nil
125+ }
126+ return out
127+ }
0 commit comments