Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions runtime/codex-rs/app-server/src/marathon_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,9 +524,9 @@ mod tests {
fn enabled_state_is_persisted_without_auth_material() {
let directory = tempdir().expect("tempdir");
let registry = FileAccountRegistry::new(directory.path().join("accounts.json"));
assert!(!registry.enabled().expect("default state"));
registry.set_enabled(true).expect("enable");
assert!(registry.enabled().expect("persisted state"));
assert!(registry.enabled().expect("default state"));
registry.set_enabled(false).expect("disable");
assert!(!registry.enabled().expect("persisted state"));
let contents = std::fs::read_to_string(registry.path()).expect("registry");
assert!(!contents.contains("access_token"));
assert!(!contents.contains("refresh_token"));
Expand Down
23 changes: 19 additions & 4 deletions runtime/codex-rs/codexmarathon-runtime/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ fn validate_metadata_entry(key: &str, value: &str) -> DomainResult<()> {
}

/// Serializable registry state.
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct RegistryState {
/// Persisted schema version.
#[serde(default = "default_registry_version")]
Expand All @@ -235,9 +235,9 @@ pub struct RegistryState {
#[serde(default, skip_serializing_if = "String::is_empty")]
pub active_account_id: String,
/// Whether the native Marathon service may perform account transitions.
/// Defaults to disabled for existing registries so adding the service is
/// behavior preserving until an operator explicitly enables it.
#[serde(default)]
/// New registries enable account management; an explicitly persisted value
/// continues to win when an existing registry is loaded.
#[serde(default = "default_registry_enabled")]
pub enabled: bool,
/// Records keyed by stable account ID.
#[serde(default)]
Expand All @@ -248,6 +248,21 @@ fn default_registry_version() -> u32 {
REGISTRY_VERSION
}

fn default_registry_enabled() -> bool {
true
}

impl Default for RegistryState {
fn default() -> Self {
Self {
version: REGISTRY_VERSION,
active_account_id: String::new(),
enabled: default_registry_enabled(),
accounts: BTreeMap::new(),
}
}
}

/// Storage-neutral account registry surface.
pub trait AccountStore: Send + Sync {
/// Insert a new account and reject duplicate IDs.
Expand Down
2 changes: 1 addition & 1 deletion runtime/codex-rs/tui/src/chatwidget/slash_dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1228,7 +1228,7 @@ impl ChatWidget {
};
self.add_info_message(
format!(
"Native Marathon is built into Codex.\n{current}\n\nCommands:\n /marathon on | off\n /marathon status\n /marathon auto-reset on | off | status\n /marathon login <alias> (choose browser link or device code)\n /marathon import <alias>\n /marathon switch <alias>\n\nAutomatic reset uses a provider-supported reset action only after every eligible managed account reports zero weekly quota. It never guesses a reset time. For a headless server, choose device code and finish sign-in from another machine. No separate codexmarathon command is required."
"Native Marathon is built into Codex.\n{current}\n\nCommands:\n /marathon on (enable account switching)\n /marathon off (disable account switching)\n /marathon status (show accounts and active account)\n /marathon auto-reset on | off | status (configure automatic quota reset)\n /marathon login <alias> (choose browser link or device code)\n /marathon import <alias> (save the current account under an alias)\n /marathon switch <alias> (switch to a saved account)\n\nStart by importing your current account with /marathon import <alias>. For a headless server, choose device code and finish sign-in from another machine. No separate codexmarathon command is required."
),
Some("Use ↑ to recall this help".to_string()),
);
Expand Down
Loading