package resources import ( "encoding/json" "os" "path/filepath" ) // Trust is how a project directory is treated in non-interactive runs. type Trust string const ( TrustAsk Trust = "ask" TrustAlways Trust = "always" TrustNever Trust = "never" ) // Settings is the global plus project configuration. type Settings struct { Trust Trust `json:"trust,omitempty"` Model string `json:"model,omitempty"` Thinking string `json:"thinking,omitempty"` Tools []string `json:"tools,omitempty"` Exclude []string `json:"exclude,omitempty"` Vars map[string]string `json:"vars,omitempty"` } // LoadSettings reads global (optional) then project settings. // Project keys override global keys. A missing file is an empty settings. func LoadSettings(globalPath, projectPath string) (Settings, error) { global, err := readSettings(globalPath) if err != nil { return Settings{}, err } project, err := readSettings(projectPath) if err != nil { return Settings{}, err } return mergeSettings(global, project), nil } // ProjectTrusted reports whether project resources may be loaded. // ask and never refuse in non-interactive mode. approve forces trust. func ProjectTrusted(trust Trust, approve, noApprove bool) bool { if noApprove { return false } if approve { return true } return trust == TrustAlways } func readSettings(path string) (Settings, error) { if path == "" { return Settings{}, nil } raw, err := os.ReadFile(path) if err != nil { if os.IsNotExist(err) { return Settings{}, nil } return Settings{}, err } var s Settings if err := json.Unmarshal(raw, &s); err != nil { return Settings{}, err } return s, nil } func mergeSettings(base, over Settings) Settings { if over.Trust != "" { base.Trust = over.Trust } if over.Model != "" { base.Model = over.Model } if over.Thinking != "" { base.Thinking = over.Thinking } if over.Tools != nil { base.Tools = over.Tools } if over.Exclude != nil { base.Exclude = over.Exclude } if len(over.Vars) > 0 { if base.Vars == nil { base.Vars = map[string]string{} } for k, v := range over.Vars { base.Vars[k] = v } } return base } // DefaultPaths returns the global and project settings paths for a cwd. func DefaultPaths(home, cwd string) (string, string) { return filepath.Join(home, ".agent-native", "settings.json"), filepath.Join(cwd, ".agent-native", "settings.json") }