On this page
Auth-shadow repair and running-state detection: clears session credentials that shadow a stored token, drops orphan token entries, and spots live sessions.
#claudewheel.profile_ops
#claudewheel.profile_ops
Profile auth-shadow repair and running-state detection.
Profile create/delete/rename live in :mod:claudewheel.profile_store now; this module retains only the fix-auth flow and the session running-state check that callers apply as policy before delegating deletions to the store. That check is a delegate: :mod:claudewheel.session_registry owns every read of Claude Code's per-session registry.
#RemoveOrphanTokenResult
Outcome of remove_orphan_token_entry(): success or a reason for no-op.
ok: True when the orphan token entry was removed, False otherwise. reason: None on success; "profile-exists" (a real profile dir exists, so the entry is not an orphan -- use fix_auth_shadow) or "no-token-entry" (nothing in tokens.json under that name) on failure.
#remove_orphan_token_entry
def remove_orphan_token_entry(ws: 'Workspace', name: str) -> RemoveOrphanTokenResultRemove a tokens.json entry whose profile directory no longer exists.
An "orphan token entry" is a key in tokens.json with no profile dir behind it (audit kind "orphan-token-entry"). This removes exactly that key and nothing else. Zero printing, zero sys.exit -- returns a structured result.
A corrupt tokens.json raises :class:TokenStoreError via audit() (the hard-error contract). If name has a real profile dir the entry is NOT an orphan (reason="profile-exists"); if there is no entry at all, reason="no-token-entry".
#FixAuthResult
Outcome of fix_auth_shadow(): success or a reason for no-op/failure.
ok: True when the shadow was removed, False otherwise. reason: None on success; "no-token" / "no-shadow" / "unreadable-creds" on failure. tier_saved: rateLimitTier value preserved into tokens.json, or None. subscription_saved: subscriptionType value preserved into tokens.json, or None.
#fix_auth_shadow
def fix_auth_shadow(ws: 'Workspace', name: str) -> FixAuthResultRemove session credentials (claudeAiOauth) that shadow a long-lived token.
Reads the profile's .credentials.json, strips the claudeAiOauth key, and preserves any tier/subscription metadata into tokens.json. Zero printing, zero sys.exit -- returns a FixAuthResult describing what happened.
A corrupt tokens.json raises :class:TokenStoreError (the hard-error contract) -- token resolution cannot proceed and the operator must fix it.
#_is_profile_running
def _is_profile_running(ws: 'Workspace', name: str) -> boolTrue when a human's Claude Code session is live in this profile.
A delegate to :func:claudewheel.session_registry.has_live_interactive -- the single reader of Claude Code's per-session registry, which parses the sessions/<pid>.json files, filters out phantoms (a stale file, or a PID the kernel has since handed to something else) and classifies each record by kind. Background jobs, daemons and daemon workers are live processes but do not answer True here: they are not a person at a terminal, and the delete flow offers the user a choice about them rather than a veto.