SIGN IN SIGN UP

feat(accounts): surface Anthropic account/organization UUIDs through the full OAuth stack

Bundles three related changes that all revolve around the OAuth account
record: capturing the new identity fields returned by the token-exchange
endpoint, preventing stale CC credentials from clobbering a fresher
locally persisted token, and making CC token refresh fall back to a
still-valid cached credential when the claude binary is unavailable.

UUID surfacing
- src/oauth.ts: exchange() now picks up account.uuid and organization.uuid
  from the token response and returns them on the success variant.
- src/storage.ts: AccountMetadata gains optional accountUuid and
  organizationUuid fields; validateAccount threads them through.
- src/accounts.ts + src/accounts/matching.ts +
  src/accounts/persistence.ts: ManagedAccount and createManagedAccount
  accept and retain the UUIDs. updateManagedAccountFromStorage merges
  them in without losing previously set values.
- src/commands/oauth-flow.ts: completeSlashOAuth copies both UUIDs into
  the managed account on add, update, and replace paths.
- tests/unit/request/metadata.test.ts (new): pins the contract that
  getAccountIdentifier prefers accountUuid over the synthetic id when
  building metadata.user_id for downstream billing.

Stale-token adoption rewrite
- AccountManager.ensureOAuthAccountsFromCc now compares CC-credential
  recency against locally persisted auth recency before overwriting.
  Adopts the CC auth only when the local access token is missing,
  already expired, or the CC credential is at least as fresh.
  Refresh-token match still unconditionally adopts to avoid split-brain.
- persistence.mergeAuthFallbackIntoAccounts accepts a preferredIndex and
  applies the auth fallback to the single account (or active index when
  there is ambiguity) only when the fallback looks fresh.
- Exposes AccountManager.getManagedAccounts() so admin flows can mutate
  the live refs before persist.

Token-refresh resilience
- src/token-refresh.ts: introduces applyCCCredential and
  useCurrentAccountAccessIfStillValid helpers. refreshCCAccount now
  falls back to the cached credential when either the claude binary is
  missing, the execSync probe fails, or the post-probe read does not
  return a fresher token. refreshAccountToken downgrades the
  'CC credential refresh failed' hard-throw to a debugLog, so callers
  automatically try the OAuth HTTP refresh path.

Tests
- tests/unit/oauth.test.ts: captures both UUIDs from a successful
  exchange response.
- tests/unit/accounts.test.ts, matching.test.ts, persistence.test.ts:
  coverage for UUID plumbing and the fresher-token adoption rules.
- tests/unit/token-refresh.test.ts: reworks the 'no claude binary'
  test into an HTTP-fallback assertion and adds coverage for the
  refresh-failure-but-cache-fresh path.

Expected pre-existing bun-vs-vitest failures in these suites
(vi.setSystemTime + mockFetch harness gaps) remain at 42 in the two
largest files, unchanged by this commit.
V
Vacbo committed
1587d325ea3f97f8e8bdd5e168cc676bb537f56f
Parent: 22e9c71