pub struct Settings {
pub env: HashMap<String, String>,
pub profiles: HashMap<String, Profile>,
pub mcp: McpSettings,
pub gmail: GmailSettings,
pub drive: DriveSettings,
}Expand description
Settings loaded from $HOME/.omni-dev/settings.json.
Fields§
§env: HashMap<String, String>Environment variable overrides — the default bundle, consulted only when no profile is active.
profiles: HashMap<String, Profile>Named profiles. Selecting one replaces the base env in the fallback
chain (isolated / AWS-faithful); see Settings::resolve_with.
mcp: McpSettingsMCP server defaults (issue #620); an absent block yields
McpSettings::default.
gmail: GmailSettingsNamed Gmail accounts (issue #1500); an absent block yields
GmailSettings::default, which is an empty account map.
drive: DriveSettingsNamed Google Drive accounts (issue #1520); an absent block yields
DriveSettings::default, which is an empty account map.
Implementations§
Source§impl Settings
impl Settings
Sourcepub fn load_mcp() -> McpSettings
pub fn load_mcp() -> McpSettings
Loads just the mcp section, falling back to its defaults
when the settings file is absent or unreadable — so the MCP server always
boots even with a malformed settings.json (issue #620). Mirrors the
graceful unwrap_or_default of SettingsEnv::load.
Sourcepub fn load_from_path<P: AsRef<Path>>(path: P) -> Result<Self>
pub fn load_from_path<P: AsRef<Path>>(path: P) -> Result<Self>
Loads settings from a specific path.
Sourcepub fn get_settings_path() -> Result<PathBuf>
pub fn get_settings_path() -> Result<PathBuf>
Returns the default settings path.
Sourcepub fn get_env_var(&self, key: &str) -> Option<String>
pub fn get_env_var(&self, key: &str) -> Option<String>
Returns an environment variable with fallback to settings, honouring the
active profile from OMNI_DEV_PROFILE.
Sourcepub fn resolve_with<E: EnvSource>(
&self,
raw: &E,
active: Option<&str>,
key: &str,
) -> Option<String>
pub fn resolve_with<E: EnvSource>( &self, raw: &E, active: Option<&str>, key: &str, ) -> Option<String>
Isolated / AWS-faithful resolution: raw (the process environment) wins;
then the active profile’s env if active is set, else the base env.
The base map is not consulted when a profile is active, so a missing
key fails loud rather than silently reusing a default credential against
the wrong tenant.
This is the pure seam: production wrappers pass &SystemEnv; tests pass
a MapEnv and an explicit active, mutating no process-global state.
Sourcepub fn resolve_with_source<E: EnvSource>(
&self,
raw: &E,
active: Option<&str>,
key: &str,
) -> Option<(String, EnvValueSource)>
pub fn resolve_with_source<E: EnvSource>( &self, raw: &E, active: Option<&str>, key: &str, ) -> Option<(String, EnvValueSource)>
Like Settings::resolve_with, but also reports which layer supplied
the value: the raw process environment, the active profile’s env, or
the base env (issue #1143). Same precedence, same profile isolation.
A EnvValueSource::CliFlag attribution is layered on top by
get_env_var_sourced, which knows about flag exports; this resolver
only distinguishes what it can see.
Sourcepub fn upsert_env_vars(path: &Path, vars: &[(&str, &str)]) -> Result<()>
pub fn upsert_env_vars(path: &Path, vars: &[(&str, &str)]) -> Result<()>
Merges the given key/value pairs into the base env object of the
settings file at path — Settings::upsert_env_vars_in with no
profile.
Sourcepub fn upsert_env_vars_in(
path: &Path,
profile: Option<&str>,
vars: &[(&str, &str)],
) -> Result<()>
pub fn upsert_env_vars_in( path: &Path, profile: Option<&str>, vars: &[(&str, &str)], ) -> Result<()>
Merges the given key/value pairs into the env object targeted by
profile — profiles.<name>.env when Some, the base env when
None — creating the file, its parent directory, and any missing
intermediate objects as needed. Writes therefore land where
Settings::resolve_with will look for them (issue #1116).
A profile absent from the file is created rather than rejected; the
CLI validates the active profile before dispatch, so this only affects
library callers.
The file is read and written as a generic JSON value, so every other
field (other profiles, unknown keys) is preserved verbatim. Because the
env maps hold credentials, the write is hardened: parent directory
0700, file 0600 (see [write_settings]).
Sourcepub fn remove_env_vars(path: &Path, keys: &[&str]) -> Result<bool>
pub fn remove_env_vars(path: &Path, keys: &[&str]) -> Result<bool>
Removes the given keys from the base env object of the settings file
at path — Settings::remove_env_vars_in with no profile.
Sourcepub fn remove_env_vars_in(
path: &Path,
profile: Option<&str>,
keys: &[&str],
) -> Result<bool>
pub fn remove_env_vars_in( path: &Path, profile: Option<&str>, keys: &[&str], ) -> Result<bool>
Removes the given keys from the env object targeted by profile
(profiles.<name>.env when Some, the base env when None),
leaving all other settings — including the same keys in other env
maps — intact.
Returns true if any key was present in the targeted map and removed
(the file is rewritten, hardened as in
Settings::upsert_env_vars_in), false when the file did not
exist, the targeted map was absent, or it contained none of the keys
(the file is left untouched).
Sourcepub fn validate_profile(&self, name: &str) -> Result<()>
pub fn validate_profile(&self, name: &str) -> Result<()>
Validates that name is a known profile, returning a hard error that
lists the known profiles (sorted) otherwise. Called once at the CLI
boundary so a typo never silently falls back to base credentials.
Sourcepub fn upsert_gmail_account(
path: &Path,
account: &str,
vars: &[(&str, Value)],
) -> Result<()>
pub fn upsert_gmail_account( path: &Path, account: &str, vars: &[(&str, Value)], ) -> Result<()>
Merges the given key/value pairs into gmail.accounts.<account>,
creating the file, its parent directory, and any missing intermediate
objects as needed (issue #1500,
ADR-0066). Same hardening and
unknown-field preservation as Settings::upsert_env_vars_in — no
new file-handling code.
vars takes serde_json::Value rather than &str (widened in
#1523, PR #1528 review) because GmailAccountSettings has non-string
fields (chrome_profile_from_email: bool) — a hard-coded
Value::String wrap would write the JSON string "true" into a
bool field, and since Settings deserializes as one unit, the next
Settings::load() would hard-fail parsing the entire file. Callers
writing a string field pass serde_json::Value::String(...)
explicitly.
Sourcepub fn remove_gmail_account(path: &Path, account: &str) -> Result<bool>
pub fn remove_gmail_account(path: &Path, account: &str) -> Result<bool>
Removes gmail.accounts.<account> entirely — an account is coherent
as a unit, unlike the key-by-key removal
Settings::remove_env_vars_in does. Also clears
gmail.default_account if it named the removed account, so
resolution (src/gmail/account.rs::resolve_default_account) falls
back to the sole-remaining-account rule instead of hard-erroring on
a dangling pointer (issue #1529). Returns true if the account was
present and removed, false when the file, gmail,
gmail.accounts, or the named account did not exist (the file is
left untouched in that case).
Sourcepub fn set_gmail_default_account(
path: &Path,
account: Option<&str>,
) -> Result<()>
pub fn set_gmail_default_account( path: &Path, account: Option<&str>, ) -> Result<()>
Sets (Some) or clears (None) gmail.default_account. Always
writes, mirroring Settings::upsert_env_vars_in’s unconditional-write
semantics rather than Settings::remove_env_vars_in’s
changed-only one, since this is fundamentally an upsert of a single
scalar rather than a set of keys.
Sourcepub fn upsert_drive_account(
path: &Path,
account: &str,
vars: &[(&str, Value)],
) -> Result<()>
pub fn upsert_drive_account( path: &Path, account: &str, vars: &[(&str, Value)], ) -> Result<()>
Merges the given key/value pairs into drive.accounts.<account>,
creating the file, its parent directory, and any missing intermediate
objects as needed (issue #1522,
ADR-0069). Same hardening and
unknown-field preservation as Settings::upsert_env_vars_in — no
new file-handling code.
vars takes serde_json::Value, not &str — see
Settings::upsert_gmail_account’s doc comment for why (this
helper’s twin, and the write path the PR #1528 review comment
flagged the bug against).
Sourcepub fn remove_drive_account(path: &Path, account: &str) -> Result<bool>
pub fn remove_drive_account(path: &Path, account: &str) -> Result<bool>
Removes drive.accounts.<account> entirely — an account is coherent
as a unit, exactly like Settings::remove_gmail_account. Also
clears drive.default_account if it named the removed account, for
the same dangling-pointer reason (issue #1529) — Drive has no
legacy-credential fallback to soften a stale default the way
Gmail’s resolution table can (ADR-0069 §3), so the failure would be
total. Returns true if the account was present and removed,
false when the file, drive, drive.accounts, or the named
account did not exist (the file is left untouched in that case).
Sourcepub fn set_drive_default_account(
path: &Path,
account: Option<&str>,
) -> Result<()>
pub fn set_drive_default_account( path: &Path, account: Option<&str>, ) -> Result<()>
Sets (Some) or clears (None) drive.default_account. Always
writes, mirroring Settings::set_gmail_default_account’s
unconditional-write semantics — fundamentally an upsert of a single
scalar rather than a set of keys.