Skip to content

feat(claude): restore multi-account support with account-owned runtimes - #1140

Closed
robinebers wants to merge 1 commit into
mainfrom
codex/multi-account-rebuild
Closed

feat(claude): restore multi-account support with account-owned runtimes#1140
robinebers wants to merge 1 commit into
mainfrom
codex/multi-account-rebuild

Conversation

@robinebers

@robinebers robinebers commented Aug 24, 2026

Copy link
Copy Markdown
Owner

TL;DR

Restore Claude multi-account support by giving every verified account and organization its own permanent identity, credentials, history, layout, and display name. CLI and Desktop accounts can now coexist without borrowing each other's usage, while iCloud matches the same account safely across Macs.

What was happening

  • The reverted implementation bound the original Claude card to whichever account currently occupied the default CLI login, so switching accounts could duplicate cards, hide the original account, or show one account's data under another account's name.
  • Claude Desktop/Cowork organizations and separate Claude configuration directories had no reliable shared identity, so same-email Team and Personal accounts could collapse together or inherit the wrong credentials and local usage logs.
  • Logout, unreadable login state, older app versions, and stale account-graph services could revive unsafe fallbacks, overwrite account state, or briefly publish outdated iCloud history.
  • Saved layouts, names, API output, analytics, and cross-Mac spend did not consistently distinguish an account from its provider family.

What this changes

  • Build every Claude card from its permanent account-and-organization record and a verified default CLI, separate configuration-directory, or organization-specific Desktop credential; the original card keeps claude even after another account becomes the default login.
  • Discover additional verified CLI/Desktop organizations automatically, enable them independently, isolate their credentials and usage logs, and reject ambiguous or unattributed Cowork sessions.
  • Preserve the same permanent account record when Claude starts or stops reporting an organization ID, while quarantining ambiguous shared-organization credentials and incomplete Cowork logs; verified single-account Desktop usage remains available when a session scan times out.
  • Rebuild the live account graph when accounts change, hide unavailable accounts without deleting their saved identity/names/layout, and prevent unverified fallback accounts after logout.
  • Perform periodic CLI/Desktop discovery off the main thread, wait for the previous local API listener to fully stop before account-graph replacement, and remove the previous graph's keyboard shortcut handler before installing its replacement.
  • Store account records in a downgrade-safe v2 registry while maintaining a backwards-readable v1 mirror, so downgrading and upgrading again does not erase account identities or custom names.
  • Upgrade iCloud history to account-aware v2 documents that match the same account across different local card IDs, keep verified remote-only accounts separate in Total Spend, and quarantine unknown or ambiguous histories.
  • Recover verified Codex account identity from the credential already used by a successful refresh, preserving Keychain-backed Codex iCloud sync without another Keychain read or permission prompt; retain history across normal token rotation or briefly missing identity metadata, but quarantine an unidentifiable account change.
  • Retire the previous iCloud sync worker before an account graph changes, prevent delayed or in-flight stale writes, and preserve pending opt-out cleanup even when sync is immediately re-enabled.
  • Name accounts usefully by default, such as Claude — SUNSTORY and Claude — Personal, resolve duplicate labels deterministically, and apply custom names consistently to the dashboard, Customize, share cards, notifications, CLI, and HTTP API; the single Codex card always uses the current verified account's own saved name.
  • Give additional accounts stable, provider-related chart colors while preserving each provider's original brand color and largest-first Total Spend ordering.
  • Keep analytics at the provider-family level, so account identifiers, account-derived card IDs, and account counts do not enter telemetry.
  • Preserve existing single-account behavior, local Codex usage, current main-branch Fable positioning, Antigravity spend/history and iCloud contributions, metric defaults, and dependency footprint.

Heads-up

  • Default Claude CLI login changes are detected in roughly five seconds; separate config-directory and Desktop source changes are rediscovered in roughly one minute.
  • This implements Claude multi-account discovery. Codex remains single-account; Codex multi-account discovery and complete account-specific historical timeline partitioning remain follow-up work.
  • iCloud history stays in the existing private per-Mac file, but its document format moves from v1 to v2. Upgrade every syncing Mac together: older builds reject newer documents entirely, and newer builds deliberately exclude old Claude/Codex history that lacks proven account ownership.
  • Provider-issued account and organization IDs, not email addresses or credentials, are stored as supplied in the user's private iCloud document. Accounts whose identity cannot yet be proven continue working locally but do not contribute history until verification; Keychain-backed Codex accounts verify during their first successful normal refresh.
  • Downgrading rewrites that Mac's iCloud file in v1, and older builds can discard account-specific layout when saving settings; the separate v2 account registry still preserves identities and custom names for re-upgrade.
  • Full Claude Desktop logout is detected when encrypted credential material disappears. Removing one Desktop organization while other Desktop accounts remain can leave its old card showing an authentication error because organization membership is encrypted.
  • Supersedes the outdated approach in Account-first Phase 3: Claude Cowork / Desktop accounts #1032, which has now been closed.

Tests

  • swift test -Xlinker -rpath -Xlinker /Users/rebers/.codex/worktrees/700a/openusage/.build/out/Products/Debug1,294 XCTest cases, three pre-existing skips, zero failures; additional CLI and Swift Testing suites also pass.
  • Added coverage for verified CLI/config/Desktop discovery, identity-spelling migration, same-email organization isolation, three Desktop accounts, ambiguous shared organizations, incomplete Cowork scans, verified Desktop organization pins, off-main discovery, completed local API listener handoff, shortcut replacement, CLI switching/logout, downgrade-safe account records, account layouts, account-safe iCloud merge/quarantine, Keychain-backed Codex identity, OAuth token rotation, first-refresh ownership races, account-owned renames, remote-only Total Spend, chart colors, telemetry privacy, canceled iCloud writes, opt-out cleanup, and rendered account labels.
  • Rebuilt the development app and verified the real Claude Team and Personal accounts through the running local API.

Screenshots

Production account-card and Total Spend chart components rendered with synthetic usage values; no private account activity is included.

Claude Team and Personal account cards

Comment thread Sources/OpenUsage/Stores/ProviderAccountsStore.swift
Comment thread Sources/OpenUsage/App/OpenUsageApp.swift
Comment thread Sources/OpenUsage/App/AppContainer.swift
@robinebers robinebers added the gate-passed Passed the automated PR gatekeeper checks (gatekeeper skips it on later runs) label Aug 24, 2026 — with Cursor
Comment thread Sources/OpenUsage/App/StatusItemController.swift
Comment thread Sources/OpenUsage/Stores/WidgetDataStore.swift
Comment thread Sources/OpenUsage/Stores/WidgetDataStore.swift Outdated
Comment thread Sources/OpenUsage/Providers/ProviderCatalog.swift Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ab8d5da. Configure here.

Comment thread Sources/OpenUsage/Services/ProviderAccountAssembly.swift Outdated
@robinebers
robinebers marked this pull request as draft August 24, 2026 10:44
@robinebers
robinebers force-pushed the codex/multi-account-rebuild branch 2 times, most recently from 6745a19 to 17c14b4 Compare August 24, 2026 11:02
@robinebers
robinebers force-pushed the codex/multi-account-rebuild branch from 17c14b4 to 8ad1bf2 Compare August 24, 2026 11:06
@robinebers

Copy link
Copy Markdown
Owner Author

Superseded by the independently reviewable stacked PRs #1147, #1148, #1145, #1146, #1149, #1150, #1151, #1152, #1154, #1153, #1156, #1155, #1158, and #1157. Documentation asset cleanup is separate in #1159. The fully assembled replacement stack passes the complete Swift test suite.

@robinebers robinebers closed this Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs gate-passed Passed the automated PR gatekeeper checks (gatekeeper skips it on later runs) provider tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant