Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160package config
import ( "encoding/json" "errors" "fmt" "os" "path/filepath")
// CapabilityPrefs holds per-item defaults and per-session overrides. An absent// value is enabled. Keys are skill names, instruction IDs, or MCP server names.type CapabilityPrefs struct { Global map[string]map[string]bool `json:"global,omitempty"` Sessions map[string]map[string]map[string]bool `json:"sessions,omitempty"`}
func ReadCapabilityPrefs(home string) (CapabilityPrefs, error) { var prefs CapabilityPrefs data, err := os.ReadFile(filepath.Join(home, "capabilities.json")) if errors.Is(err, os.ErrNotExist) { return prefs, nil } if err != nil { return prefs, err } if len(data) > 1<<20 { return prefs, errors.New("capabilities.json exceeds 1 MiB") } if err = json.Unmarshal(data, &prefs); err != nil { return CapabilityPrefs{}, errors.New("invalid capabilities.json") } return prefs, nil}
func (p CapabilityPrefs) Enabled(session, kind, name string) bool { if groups := p.Sessions[session]; groups != nil { if state, ok := groups[kind][name]; ok { return state } } if state, ok := p.Global[kind][name]; ok { return state } return true}
// SetCapability persists a single selection, preserving unrelated categories.// Session changes affect only one session; global changes become the default.func SetCapability(home, session, kind, name string, global, enabled bool) error { if session == "" || name == "" || (kind != "skills" && kind != "instructions" && kind != "mcp") { return errors.New("invalid capability selection") } return lockedUpdate(home, "capabilities.lock", 50, func() error { p, err := ReadCapabilityPrefs(home) if err != nil { return err } if global { if p.Global == nil { p.Global = make(map[string]map[string]bool) } if p.Global[kind] == nil { p.Global[kind] = make(map[string]bool) } p.Global[kind][name] = enabled } else { if p.Sessions == nil { p.Sessions = make(map[string]map[string]map[string]bool) } if p.Sessions[session] == nil { p.Sessions[session] = make(map[string]map[string]bool) } if p.Sessions[session][kind] == nil { p.Sessions[session][kind] = make(map[string]bool) } p.Sessions[session][kind][name] = enabled } if err = writeJSONAtomic(home, "capabilities.json", p); err != nil { return fmt.Errorf("save capability: %w", err) } return nil })}
// ClearCapability removes an override, restoring inheritance from the global// setting (or the built-in enabled default). Used for rollback after reload.func ClearCapability(home, session, kind, name string, global bool) error { return lockedUpdate(home, "capabilities.lock", 50, func() error { p, err := ReadCapabilityPrefs(home) if err != nil { return err } if global { delete(p.Global[kind], name) } else { delete(p.Sessions[session][kind], name) } return writeJSONAtomic(home, "capabilities.json", p) })}
// MCPCredentials are deliberately separate from extension settings, which can// be shared. No API should return the secret contents to a view or transcript.type MCPCredentials struct { Servers map[string]MCPServerSecrets `json:"servers"`}type MCPServerSecrets struct { BearerToken string `json:"bearerToken,omitempty"` Headers map[string]string `json:"headers,omitempty"` Env map[string]string `json:"env,omitempty"`}
func ReadMCPCredentials(home string) (MCPCredentials, error) { var c MCPCredentials path := filepath.Join(home, "mcp-credentials.json") stat, err := os.Lstat(path) if errors.Is(err, os.ErrNotExist) { return c, nil } if err != nil { return c, err } if !stat.Mode().IsRegular() || stat.Mode().Perm()&0077 != 0 { return c, errors.New("mcp-credentials.json must be a regular 0600 file") } if stat.Size() > 1<<20 { return c, errors.New("mcp-credentials.json exceeds 1 MiB") } data, err := os.ReadFile(path) if err != nil { return c, err } if err = json.Unmarshal(data, &c); err != nil { return MCPCredentials{}, errors.New("invalid mcp-credentials.json") } return c, nil}
func SetMCPServerSecrets(home, name string, secret MCPServerSecrets) error { if name == "" { return errors.New("missing MCP server name") } return lockedUpdate(home, "mcp-credentials.lock", 50, func() error { c, err := ReadMCPCredentials(home) if err != nil { return err } if c.Servers == nil { c.Servers = make(map[string]MCPServerSecrets) } if secret.BearerToken == "" && len(secret.Headers) == 0 && len(secret.Env) == 0 { delete(c.Servers, name) } else { c.Servers[name] = secret } return writeJSONAtomic(home, "mcp-credentials.json", c) })}