Documentation
¶
Index ¶
- Constants
- func ClearProviderKeyStored(path, provider string) (bool, error)
- func DefaultMCPServers() map[string]MCPServerConfig
- func DefaultUserConfigPath() (string, error)
- func ForgetProviderKey(provider string) (bool, error)
- func HasProviderProfile(profile ProviderProfile) bool
- func IsDefaultMCPServer(name string) bool
- func MigratePlaintextProviderKeys(path string, store APIKeySetter) (int, error)
- func ProviderKeyStore() (*credstore.Store, error)
- func ProviderKeyStoreAt(dir string) (*credstore.Store, error)
- func SetActiveProviderEnv(name string)
- func SetMaxTurnsEnv(n int)
- func ValidateBytes(data []byte) (FileConfig, []Issue)
- func ValidateFile(path string) (FileConfig, []Issue)
- type APIKeyGetter
- type APIKeySetter
- type FileConfig
- func LoadProviderCommand(command string) (FileConfig, error)
- func SetActiveProvider(path string, name string) (FileConfig, error)
- func SetFavoriteModels(path string, models []string) (FileConfig, error)
- func SetProviderModel(path string, name string, model string) (FileConfig, error)
- func SetRecapsEnabled(path string, enabled bool) (FileConfig, error)
- func SetTheme(path string, theme string) (FileConfig, error)
- func UpsertProvider(path string, profile ProviderProfile, setActive bool) (FileConfig, error)
- type Issue
- type LocalControlConfig
- func (cfg LocalControlConfig) BrowserEnabled() bool
- func (cfg LocalControlConfig) DesktopEnabled() bool
- func (cfg LocalControlConfig) Disabled() bool
- func (cfg LocalControlConfig) Empty() bool
- func (cfg LocalControlConfig) MarshalJSON() ([]byte, error)
- func (cfg LocalControlConfig) TerminalEnabled() bool
- func (cfg *LocalControlConfig) UnmarshalJSON(data []byte) error
- type LocalControlDriverConfig
- type MCPConfig
- type MCPOAuthConfig
- type MCPServerConfig
- type NotifyConfig
- type Overrides
- type PreferencesConfig
- type ProviderKind
- type ProviderProfile
- type ResolveOptions
- type ResolvedConfig
- type SandboxConfig
- type SwarmConfig
- type ToolsConfig
Constants ¶
const ActiveProviderEnv = "ZERO_PROVIDER"
ActiveProviderEnv selects the active provider profile by name (read in applyEnv).
const AnthropicBaseURL = "https://api.anthropic.com"
const GoogleBaseURL = "https://generativelanguage.googleapis.com"
const MaxTurnsCeiling = 500
MaxTurnsCeiling caps the per-run tool-turn budget so a stray env value or typo can't set an absurd ceiling. Shared between applyEnv (read site) and the /turns command (write site) so the bound holds even if the env is set by a raw shell.
const MaxTurnsEnv = "ZERO_MAX_TURNS"
MaxTurnsEnv overrides the per-run tool-turn budget by name (read in applyEnv).
const OpenAIBaseURL = "https://api.openai.com/v1"
Variables ¶
This section is empty.
Functions ¶
func ClearProviderKeyStored ¶
ClearProviderKeyStored unsets the APIKeyStored marker for a provider in the config at path, so credential checks no longer claim a stored key after one is removed. No-op when path/provider is empty, the config is absent, or the marker is already unset.
func DefaultMCPServers ¶
func DefaultMCPServers() map[string]MCPServerConfig
DefaultMCPServers returns the MCP servers Zero ships ENABLED by default so web search and scraping work out of the box with no setup and no API key. They are seeded before user/project config is merged (see ResolveMCP), so a user can override any field — for example point firecrawl at a self-hosted instance, or add an API-key header to lift the free-tier limit — or disable it entirely with `zero mcp disable <name>` (which writes `"disabled": true`).
Keyless Firecrawl routes requests through firecrawl.dev (1,000 free credits per month, no account). Self-host Firecrawl (AGPL-3.0) for unlimited and private use. Zero only calls it over the network, so Firecrawl's license never reaches into Zero's own code.
func DefaultUserConfigPath ¶
func ForgetProviderKey ¶
ForgetProviderKey removes a provider's stored API key from the credential store, reporting whether one existed. Used by the lifecycle "remove key" / auth logout.
func HasProviderProfile ¶
func HasProviderProfile(profile ProviderProfile) bool
func IsDefaultMCPServer ¶
IsDefaultMCPServer reports whether name is one of Zero's built-in default MCP servers. The config commands use it so a default can be disabled/enabled even though it is not written to the user's config file until overridden.
func MigratePlaintextProviderKeys ¶
func MigratePlaintextProviderKeys(path string, store APIKeySetter) (int, error)
MigratePlaintextProviderKeys moves any inline plaintext API key in the config at path into the credential store, marking the profile APIKeyStored and stripping the inline secret — but ONLY after the store write succeeds, so a failed Set leaves the plaintext key in place and never strands a credential. Returns how many keys were migrated; a no-op (0, nil) when path is empty/absent or nothing needs migrating. Safe to run on every startup (idempotent).
func ProviderKeyStore ¶
ProviderKeyStore opens the credential store beside the default user config.
func ProviderKeyStoreAt ¶
ProviderKeyStoreAt opens the encrypted credential store whose file backend lives in dir. The backend resolves keyring-first, then encrypted-file, with a plaintext opt-out via ZERO_CRED_STORAGE. The dir parameter exists so tests can point the file backend at a temp directory; production always uses the user config directory (ProviderKeyStore) because provider API keys are user-scoped by design — they are only ever captured under the user config, never project config (a cloned repo must not carry keys), so runtime lookups deliberately use the user store regardless of where a provider profile was resolved from.
func SetActiveProviderEnv ¶
func SetActiveProviderEnv(name string)
SetActiveProviderEnv exports the active provider name to the process environment so a spawned child process (which inherits the environment) resolves the SAME provider profile — and therefore the same credentials (env key / stored key / OAuth) — as its parent. Without this a sub-agent re-resolves config.json's default provider and can land on one whose credentials don't match the parent's live selection, failing auth the instant it spawns. A blank name CLEARS the variable: switching back to an unnamed/default profile must not keep exporting a stale provider to children.
func SetMaxTurnsEnv ¶
func SetMaxTurnsEnv(n int)
SetMaxTurnsEnv exports the per-run tool-turn budget to the process environment so a spawned child (sub-agent / swarm member, which inherits the environment) runs with the SAME budget the user set via /turns. Without it a child re-resolves config.json's default and a large delegated task can exhaust its turns mid-run (exit 4 / max-turns). No-op for n <= 0.
func ValidateBytes ¶
func ValidateBytes(data []byte) (FileConfig, []Issue)
ValidateBytes parses data as a Zero FileConfig and runs the same semantic provider/model rules as ValidateFile. It returns the parsed config (zero value on parse failure) plus any structured issues. A parse failure yields a single issue whose Message wraps the underlying JSON error (path-less form: "invalid config JSON: <err>") so callers can extract *json.SyntaxError / *json.UnmarshalTypeError offsets via errors.As.
func ValidateFile ¶
func ValidateFile(path string) (FileConfig, []Issue)
ValidateFile reads and parses path as a Zero FileConfig and runs the same semantic provider/model rules used during resolution. It returns the parsed config (zero value on parse failure) plus any structured issues. A parse failure yields a single issue whose Message wraps the underlying JSON error so callers can extract *json.SyntaxError / *json.UnmarshalTypeError offsets via errors.As.
Types ¶
type APIKeyGetter ¶
APIKeyGetter is the read surface of the credential store; *credstore.Store satisfies it. Kept here so callers can inject a fake in tests.
type APIKeySetter ¶
APIKeySetter is the write surface of the credential store.
type FileConfig ¶
type FileConfig struct {
ActiveProvider string `json:"activeProvider,omitempty"`
Providers []ProviderProfile `json:"providers,omitempty"`
MaxTurns int `json:"maxTurns,omitempty"`
MCP MCPConfig `json:"mcp,omitempty"`
Sandbox SandboxConfig `json:"sandbox,omitempty"`
Notify NotifyConfig `json:"notify,omitempty"`
Tools ToolsConfig `json:"tools,omitempty"`
Swarm SwarmConfig `json:"swarm,omitempty"`
Preferences PreferencesConfig `json:"preferences,omitempty"`
LocalControl LocalControlConfig `json:"localControl,omitempty"`
}
func LoadProviderCommand ¶
func LoadProviderCommand(command string) (FileConfig, error)
func SetActiveProvider ¶
func SetActiveProvider(path string, name string) (FileConfig, error)
func SetFavoriteModels ¶
func SetFavoriteModels(path string, models []string) (FileConfig, error)
func SetProviderModel ¶
func SetProviderModel(path string, name string, model string) (FileConfig, error)
func SetRecapsEnabled ¶
func SetRecapsEnabled(path string, enabled bool) (FileConfig, error)
SetRecapsEnabled persists the post-turn recap preference, mirroring SetFavoriteModels (read-modify-atomic-write).
func SetTheme ¶
func SetTheme(path string, theme string) (FileConfig, error)
SetTheme persists the TUI theme preference, mirroring SetFavoriteModels (read-modify-atomic-write). A blank theme clears the stored preference.
func UpsertProvider ¶
func UpsertProvider(path string, profile ProviderProfile, setActive bool) (FileConfig, error)
func (FileConfig) MarshalJSON ¶
func (cfg FileConfig) MarshalJSON() ([]byte, error)
func (*FileConfig) UnmarshalJSON ¶
func (cfg *FileConfig) UnmarshalJSON(data []byte) error
type Issue ¶
Issue is a single structured problem found while validating a config file. Message is already routed through the package secret redaction.
type LocalControlConfig ¶
type LocalControlConfig struct {
Enabled bool `json:"enabled,omitempty"`
Browser LocalControlDriverConfig `json:"browser,omitempty"`
Desktop LocalControlDriverConfig `json:"desktop,omitempty"`
Terminal LocalControlDriverConfig `json:"terminal,omitempty"`
ArtifactsDir string `json:"artifactsDir,omitempty"`
// contains filtered or unexported fields
}
LocalControlConfig controls local browser/desktop/terminal automation helpers. Helpers are discovered lazily by the tool that needs them; no setup command or background probe is required during startup.
func (LocalControlConfig) BrowserEnabled ¶
func (cfg LocalControlConfig) BrowserEnabled() bool
func (LocalControlConfig) DesktopEnabled ¶
func (cfg LocalControlConfig) DesktopEnabled() bool
func (LocalControlConfig) Disabled ¶
func (cfg LocalControlConfig) Disabled() bool
func (LocalControlConfig) Empty ¶
func (cfg LocalControlConfig) Empty() bool
func (LocalControlConfig) MarshalJSON ¶
func (cfg LocalControlConfig) MarshalJSON() ([]byte, error)
func (LocalControlConfig) TerminalEnabled ¶
func (cfg LocalControlConfig) TerminalEnabled() bool
func (*LocalControlConfig) UnmarshalJSON ¶
func (cfg *LocalControlConfig) UnmarshalJSON(data []byte) error
type LocalControlDriverConfig ¶
type LocalControlDriverConfig struct {
Enabled bool `json:"enabled,omitempty"`
HelperPath string `json:"helperPath,omitempty"`
Driver string `json:"driver,omitempty"`
// contains filtered or unexported fields
}
func (LocalControlDriverConfig) Empty ¶
func (cfg LocalControlDriverConfig) Empty() bool
func (LocalControlDriverConfig) MarshalJSON ¶
func (cfg LocalControlDriverConfig) MarshalJSON() ([]byte, error)
func (*LocalControlDriverConfig) UnmarshalJSON ¶
func (cfg *LocalControlDriverConfig) UnmarshalJSON(data []byte) error
type MCPConfig ¶
type MCPConfig struct {
Servers map[string]MCPServerConfig `json:"servers,omitempty"`
}
func ResolveMCP ¶
func ResolveMCP(options ResolveOptions) (MCPConfig, error)
type MCPOAuthConfig ¶
type MCPOAuthConfig struct {
ClientID string `json:"clientID,omitempty"`
ClientSecret string `json:"clientSecret,omitempty"`
Scopes []string `json:"scopes,omitempty"`
AuthorizationEndpoint string `json:"authorizationEndpoint,omitempty"`
TokenEndpoint string `json:"tokenEndpoint,omitempty"`
RegistrationEndpoint string `json:"registrationEndpoint,omitempty"`
IssuerURL string `json:"issuerURL,omitempty"`
}
MCPOAuthConfig describes how to authenticate to a remote MCP server using an OAuth 2.0 + PKCE authorization-code flow. Endpoints may be discovered from the authorization server's metadata document; explicit values here override or fill in anything discovery cannot provide. Client credentials are optional when the server supports dynamic client registration.
type MCPServerConfig ¶
type MCPServerConfig struct {
Type string `json:"type,omitempty"`
Command string `json:"command,omitempty"`
Args []string `json:"args,omitempty"`
Env map[string]string `json:"env,omitempty"`
URL string `json:"url,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
Auth string `json:"auth,omitempty"`
OAuth *MCPOAuthConfig `json:"oauth,omitempty"`
Disabled bool `json:"disabled,omitempty"`
// contains filtered or unexported fields
}
func (*MCPServerConfig) UnmarshalJSON ¶
func (server *MCPServerConfig) UnmarshalJSON(data []byte) error
type NotifyConfig ¶
type Overrides ¶
type Overrides struct {
ActiveProvider string
Providers []ProviderProfile
Provider ProviderProfile
MaxTurns int
MCP MCPConfig
Sandbox SandboxConfig
Notify NotifyConfig
Tools ToolsConfig
LocalControl LocalControlConfig
}
type PreferencesConfig ¶
type PreferencesConfig struct {
FavoriteModels []string `json:"favoriteModels,omitempty"`
// Theme is the persisted TUI palette preference — "auto" or a registered theme
// name (e.g. "dracula"). Applied at startup below the --theme flag and
// ZERO_THEME, so a /theme choice survives restart. Empty = unset (defaults auto).
Theme string `json:"theme,omitempty"`
// Recaps is a tri-state: nil (unset) defaults to ON; an explicit false means
// the user turned post-turn recaps off. A *bool is its own tri-state, so no
// custom unmarshal is needed (unlike ToolsConfig.DeferThreshold's int).
Recaps *bool `json:"recaps,omitempty"`
}
func (PreferencesConfig) RecapsEnabled ¶
func (p PreferencesConfig) RecapsEnabled() bool
RecapsEnabled reports whether post-turn recaps are on. Unset defaults to ON.
type ProviderKind ¶
type ProviderKind string
const ( ProviderKindOpenAI ProviderKind = "openai" ProviderKindAnthropic ProviderKind = "anthropic" ProviderKindAnthropicCompat ProviderKind = "anthropic-compatible" ProviderKindGoogle ProviderKind = "google" ProviderKindOpenAICompatible ProviderKind = "openai-compatible" )
type ProviderProfile ¶
type ProviderProfile struct {
Name string `json:"name"`
Provider string `json:"provider,omitempty"`
ProviderKind ProviderKind `json:"provider_kind,omitempty"`
CatalogID string `json:"catalogID,omitempty"`
BaseURL string `json:"baseURL,omitempty"`
APIKey string `json:"apiKey,omitempty"`
APIKeyEnv string `json:"apiKeyEnv,omitempty"`
// APIKeyStored marks that this provider's API key lives in the encrypted
// credential store (internal/credstore), not inline in APIKey. The effective
// key is loaded from the store at provider-build time; config.json holds only
// this marker, never the secret.
APIKeyStored bool `json:"apiKeyStored,omitempty"`
APIFormat string `json:"apiFormat,omitempty"`
AuthHeader string `json:"authHeader,omitempty"`
AuthScheme string `json:"authScheme,omitempty"`
AuthHeaderValue string `json:"authHeaderValue,omitempty"`
CustomHeaders map[string]string `json:"customHeaders,omitempty"`
Model string `json:"model,omitempty"`
ParseThinkTags *bool `json:"parseThinkTags,omitempty"`
Description string `json:"description,omitempty"`
}
func ApplyStoredAPIKey ¶
func ApplyStoredAPIKey(profile ProviderProfile, store APIKeyGetter) ProviderProfile
ApplyStoredAPIKey fills profile.APIKey from the credential store when it is not already resolved — an inline config key or a resolved APIKeyEnv always wins, so this only supplies a key for providers whose secret lives in the store. A nil store, a miss, or a store error leaves the profile unchanged.
func SecureProviderProfile ¶
func SecureProviderProfile(profile ProviderProfile, configPath string) ProviderProfile
SecureProviderProfile moves an inline APIKey on the profile into the credential store co-located with configPath, returning a profile with APIKeyStored set and APIKey cleared so the secret is never written to config.json. On any store error (e.g. no keyring) it returns the profile unchanged — the inline key persists and the startup migration retries later — so capturing a provider never fails on a flaky credential backend.
func (ProviderProfile) HasConfiguredCredential ¶
func (profile ProviderProfile) HasConfiguredCredential() bool
HasConfiguredCredential reports whether the profile is set up to authenticate with its own API key (inline, stored, or a raw auth header). It is the single definition of "this profile is key-authed", shared by OAuthLoginCandidates and the cli/tui setup surfaces so they never disagree about whether a profile is keyed. APIKeyEnv is deliberately NOT included: an env var may be unset at runtime while the profile actually relies on an OAuth login, so an env-configured-but-empty profile must still be allowed to resolve a token.
func (ProviderProfile) OAuthLoginCandidates ¶
func (profile ProviderProfile) OAuthLoginCandidates() []string
OAuthLoginCandidates returns the login names to try, in order, when resolving this profile's OAuth token — used by the runtime bearer resolver, the Codex account-header resolver, and the onboarding presence check so all three agree.
It returns NO candidates for a profile that carries its own configured credential: attaching an OAuth resolver to such a profile makes withBearer erase the key the instant a token resolves, silently routing/billing the call through the OAuth account instead of the intended key (the cross-profile override the review caught — and, via the profile name, a same-name login overriding an explicit key). A stored-key profile that reaches this keyless (e.g. a transiently unreadable keyring) is likewise treated as key-auth, so it fails with a clear missing-credential error rather than silently borrowing an unrelated OAuth login. APIKeyEnv is intentionally not part of that gate (an env var may be unset while the profile relies on OAuth).
For a keyless profile the profile name comes first (a login under your own profile name is unambiguously yours), then the catalog ID as a FALLBACK (so a profile renamed away from its catalog ID — e.g. {name:"codex", catalogID:"chatgpt"} — still finds a `zero auth login chatgpt` token). Candidates are trimmed, blank-skipped, and de-duplicated CASE-SENSITIVELY — the OAuth token store is a case-sensitive map, so "ChatGPT" and "chatgpt" are distinct keys and both must survive.
func (*ProviderProfile) UnmarshalJSON ¶
func (profile *ProviderProfile) UnmarshalJSON(data []byte) error
type ResolveOptions ¶
type ResolveOptions struct {
UserConfigPath string
ProjectConfigPath string
ProviderCommand string
Env map[string]string
Overrides Overrides
}
func DefaultResolveOptions ¶
func DefaultResolveOptions(workspaceRoot string) (ResolveOptions, error)
DefaultResolveOptions builds config resolution inputs from the local process environment and workspace.
type ResolvedConfig ¶
type ResolvedConfig struct {
ActiveProvider string
Providers []ProviderProfile
Provider ProviderProfile
MaxTurns int
MCP MCPConfig
Sandbox SandboxConfig
Notify NotifyConfig
Tools ToolsConfig
Swarm SwarmConfig
Preferences PreferencesConfig
LocalControl LocalControlConfig
}
func Resolve ¶
func Resolve(options ResolveOptions) (ResolvedConfig, error)
type SandboxConfig ¶
type SandboxConfig struct {
// Network controls whether shell commands classified as network-touching
// (curl, git push, package installs, …) are allowed: "allow" or "deny".
// Empty keeps the built-in default (deny). Without this knob the engine's
// hard-coded NetworkDeny was unreachable from any config surface.
Network string `json:"network,omitempty"`
// AdditionalWriteRoots lists directories outside the workspace the sandbox
// allows writes in. Each entry must be an existing directory; entries are
// normalized (~-expanded, absolutized, symlink-resolved) at startup and an
// invalid entry fails the run. Honored from the GLOBAL user config and CLI
// flags only — deliberately not project config, so a cloned repo cannot
// grant itself write access. Session-only grants use /add-dir instead.
AdditionalWriteRoots []string `json:"additionalWriteRoots,omitempty"`
// BlockUnixSockets, when true, asks the Linux sandbox helper to install a
// best-effort seccomp filter that denies AF_UNIX socket creation inside the
// sandboxed command. Off by default; ignored on non-Linux backends.
BlockUnixSockets bool `json:"blockUnixSockets,omitempty"`
// MonitorDenials, when true on macOS, tails the unified log for this run's
// sandbox denials and appends them to a command's stderr so blocked operations
// are visible to the agent. Off by default. No-op on platforms/OS versions that
// do not deliver seatbelt denials to the queryable log.
MonitorDenials bool `json:"monitorDenials,omitempty"`
}
type SwarmConfig ¶
type SwarmConfig struct {
MaxTeamSize int `json:"maxTeamSize,omitempty"`
}
SwarmConfig tunes the multi-agent swarm. MaxTeamSize caps how many members run concurrently per team; 0 uses the built-in default (8). Spawns past the cap queue and launch as slots free, so lowering it bounds parallelism (and provider load / rate-limit pressure) without dropping work.
type ToolsConfig ¶
type ToolsConfig struct {
DeferThreshold int `json:"deferThreshold,omitempty"`
// contains filtered or unexported fields
}
func ToolsOverride ¶
func ToolsOverride(deferThreshold int) ToolsConfig
ToolsOverride builds a ToolsConfig that explicitly overrides the deferred-tool threshold (including to 0, which disables deferral). Use this for programmatic Overrides — a bare ToolsConfig{DeferThreshold: 0} is indistinguishable from "unset" and will not override.
func (*ToolsConfig) UnmarshalJSON ¶
func (cfg *ToolsConfig) UnmarshalJSON(data []byte) error