/** * Stopping two profiles from holding the same account. * * This is worth preventing rather than detecting, because the damage is not just * cosmetic. Renewing a login ROTATES it: the old token stops working the moment * the new one is issued. So when two profiles share a login, renewing either one * destroys the other, and the account cannot be recovered without signing in * again. That is how two accounts here ended up dead. * * The state is also useless even before it breaks: switching between two * profiles that are the same account gains no extra room at all. */ export interface ProfileLike { name: string; dir: string; /** * The account this profile is registered FOR. Two profiles holding one token * are only siblings when this agrees; see `sameRegisteredAccount`. */ email?: string; } /** * Profiles that share a login with another profile, grouped together. * * Sharing a REFRESH token is the dangerous one: renewing any member of the group * invalidates the rest. Sharing only an access token is the same account reached * by two different logins, which is wasteful but not destructive. */ export declare function sharedLoginGroups(profiles: ProfileLike[]): Array<{ fingerprint: string; names: string[]; }>; /** * Would renewing this profile's login also invalidate another profile's? * * TOKEN equality and nothing else, deliberately. Renewal rotates the refresh * token at the server, so every profile holding that token loses it PHYSICALLY, * whoever it is registered to. A contaminated sibling (same token, different * registered account) is still killed by the rotation, so filtering it out of * this answer would let a renewal sign a live session out. Protection follows * the token; only the CARRY follows the account (see carryTargets). */ export declare function renewalWouldBreakOthers(profile: ProfileLike, profiles: ProfileLike[]): string[]; /** * Which profiles a renewal should be CARRIED across to. * * Same token AND the same registered account. Carrying a renewal to a profile * registered for a DIFFERENT account is what turned a one-off mix-up into a * permanent one: from the moment two profiles held one token, every renewal * copied the new token over the other, so they could never come apart, and * signing in again was undone by the next renewal minutes later. Three accounts * here spent a day as one, reporting one account's usage under three names and * refusing to rotate between them. * * Same token plus different registered accounts is contamination. The fix for * that is `ccx login `, which `ccx doctor` already prints, not a copy. * The contaminated holder still counts for renewal SAFETY, which is why this * is a separate question from renewalWouldBreakOthers. */ export declare function carryTargets(profile: ProfileLike, profiles: ProfileLike[]): string[]; /** * Does another profile already hold `email`? Compared case-insensitively, * because an address that differs only in case is the same account. */ export declare function profileAlreadyHolding(email: string, profiles: Array, exclude: string): string | null;