refactor(multi-account): registry isDefault -> isAnchor (naming collision fix)

Merged
GR
4mo ago
+153-63

Summary

PR-A of the Batch 3 plan: rename the registry's per-account isDefault field to isAnchor — a pure naming refactor with backward-compatible reads, no behavior change.

Why

The multi-account system has three separate concepts, and two of them shared a name:

ConceptWhat it isRegistry representation
Anchorthe ~/.claude account (identity at HOME .claude.json, launched with no CLAUDE_CONFIG_DIR, can't be removed)per-account flag — was isDefault, now isAnchor
Defaultwhat bare claude opens (the dispatcher target, default badge, codev account default)top-level defaultAccount
Namemutable labellabel

With codev account default work, the anchor's entry literally read isDefault: true while not being the default — actively misleading for anyone reading the registry or the code.

What changed

  • Schema: entries now write isAnchor. No compatibility shim: the registry format never shipped in a release — the only registry in existence (the author's local one) was migrated by hand, so a legacy-read path would have been dead weight. normalizeRegistry() (new, pure, exported, tested) still provides shape defaults + dir-based anchor inference for partial hand-written entries (~/.claude is the anchor by definition).
  • Reader (src/accounts.ts): CodevAccount.isAnchor; a missing flag is inferred from the dir — never from defaultAccount, which is the dispatcher target and a different concept (the old inference would misroute once the default is a non-anchor account); makeDefaultAccount → makeAnchorAccount.
  • Session tag: accountIsDefault → accountIsAnchor (utility + Sessions-tab badge condition).
  • UI/CLI/types: popup Remove-gating, CLI list anchor tag + fresh-add note, CodevAccountInfo, isDefaultDir → isAnchorDir, docs §4/§11 schema examples.
  • isCurrentDefault (the dispatcher concept in listAccounts) is intentionally unchanged — that name is correct.

Verification

  • tsc --noEmit 0 errors; yarn test 20/20 (+2: pure shape normalization with input-untouched assertion; dir-based anchor inference).
  • Live sanity: yarn account list against the real (migrated) registry reads correctly (anchor + extra account, * on the right default).

Notes

  • No UI/UX change; single-account users unaffected (no registry → nothing to touch).
  • Review round already folded in: normalizeRegistry made truly pure (returns a copy), and both readers unified on dir-based inference so they can't disagree on anchor identity.
  • Sets up Batch 3 (share engine), whose logic is anchor-centric — building it on the misleading name would have cemented the confusion.

🤖 Generated with Claude Code


Summary by cubic

Renamed the per-account registry flag from isDefault to isAnchor to distinguish the anchor account (~/.claude) from the dispatcher default. Backward compatible via a pure normalizer that also infers the anchor from the dir when missing; no behavior change.

  • Refactors

    • Registry schema now writes isAnchor; normalizeRegistry accepts legacy isDefault, drops it on next write, and returns a normalized copy.
    • Readers updated: CodevAccount.isAnchor, makeAnchorAccount; missing flag inferred from the dir (~/.claude), not from defaultAccount.
    • Session/UI/CLI: accountIsDefault → accountIsAnchor, Remove gating uses the anchor flag, CLI list tag updated, CodevAccountInfo uses isAnchor, isDefaultDir → isAnchorDir.
    • Docs, tests, and CHANGELOG updated; version bumped to 1.0.81.
  • Migration

    • No manual steps. Legacy registries with isDefault are read and rewritten as isAnchor on next write.

Summary by CodeRabbit

  • New Features
    • Improved account handling by clearly distinguishing the anchor account from the selected default account.
    • Account listings, session details, and account switching now consistently identify the anchor account.
  • Bug Fixes
    • Existing registries using the legacy account flag are automatically migrated when saved.
    • Added safer fallback behavior when account configuration is missing, empty, or invalid.
  • Documentation
    • Updated account configuration guidance and examples to reflect the new terminology.
  • Release
    • Version 1.0.81 is now available.