sidekick-shared 0.26.5 → 0.26.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +56 -51
  3. package/dist/accountChanges.js +21 -2
  4. package/dist/accountHealth.d.ts +72 -0
  5. package/dist/accountHealth.js +286 -0
  6. package/dist/accountLaunch.d.ts +30 -0
  7. package/dist/accountLaunch.js +124 -0
  8. package/dist/accountManager.d.ts +33 -8
  9. package/dist/accountManager.js +183 -50
  10. package/dist/accountRegistry.d.ts +10 -0
  11. package/dist/accountRegistry.js +42 -22
  12. package/dist/accountSwitch.d.ts +43 -0
  13. package/dist/accountSwitch.js +115 -0
  14. package/dist/accountSync.d.ts +30 -0
  15. package/dist/accountSync.js +180 -0
  16. package/dist/accountSyncTypes.d.ts +25 -0
  17. package/dist/accountSyncTypes.js +7 -0
  18. package/dist/accounts.d.ts +58 -6
  19. package/dist/accounts.js +408 -189
  20. package/dist/claudeCredentials.d.ts +38 -0
  21. package/dist/claudeCredentials.js +74 -0
  22. package/dist/claudeProfiles.d.ts +40 -0
  23. package/dist/claudeProfiles.js +102 -10
  24. package/dist/codexAuth.d.ts +32 -0
  25. package/dist/codexAuth.js +127 -0
  26. package/dist/codexPaths.d.ts +21 -0
  27. package/dist/codexPaths.js +117 -0
  28. package/dist/codexProfiles.d.ts +58 -5
  29. package/dist/codexProfiles.js +574 -289
  30. package/dist/credentialIO.d.ts +12 -5
  31. package/dist/credentialIO.js +63 -29
  32. package/dist/credentials.d.ts +8 -0
  33. package/dist/credentials.js +28 -32
  34. package/dist/ensureDefaultAccounts.d.ts +8 -0
  35. package/dist/ensureDefaultAccounts.js +42 -82
  36. package/dist/index.d.ts +27 -10
  37. package/dist/index.js +61 -9
  38. package/dist/keepAlive.d.ts +44 -0
  39. package/dist/keepAlive.js +106 -0
  40. package/dist/processDetection.d.ts +32 -0
  41. package/dist/processDetection.js +210 -0
  42. package/dist/schemas/accountManager.d.ts +283 -1
  43. package/dist/schemas/accountManager.js +122 -1
  44. package/dist/schemas/assistantTurn.d.ts +2 -2
  45. package/dist/schemas/index.d.ts +6 -1
  46. package/dist/schemas/index.js +14 -1
  47. package/dist/schemas/observedSessionV1.d.ts +21 -21
  48. package/dist/schemas/quota.d.ts +18 -18
  49. package/dist/schemas/quotaHistory.d.ts +1 -1
  50. package/dist/schemas/stateFile.d.ts +5 -5
  51. package/dist/terminalSync.d.ts +5 -5
  52. package/dist/terminalSync.js +7 -112
  53. package/dist/writers/atomic.d.ts +2 -0
  54. package/dist/writers/atomic.js +49 -2
  55. package/package.json +1 -1
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getLastSwitchPath = getLastSwitchPath;
37
+ exports.readLastSwitch = readLastSwitch;
38
+ exports.writeLastSwitch = writeLastSwitch;
39
+ exports.clearLastSwitch = clearLastSwitch;
40
+ exports.switchFailure = switchFailure;
41
+ exports.finishSwitchResult = finishSwitchResult;
42
+ /**
43
+ * Shared shape of a verified account switch plus the undo record. The
44
+ * provider-specific switch cores live in accounts.ts (Claude) and
45
+ * codexProfiles.ts (Codex); accountManager.ts exposes the provider-agnostic
46
+ * `switchAccount*` and `undoLastSwitch` entry points.
47
+ */
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const crypto_1 = require("crypto");
51
+ const accountRegistry_1 = require("./accountRegistry");
52
+ const atomic_1 = require("./writers/atomic");
53
+ function providerDirName(provider) {
54
+ return provider === 'codex' ? 'codex' : 'claude';
55
+ }
56
+ function getLastSwitchPath(provider) {
57
+ return path.join((0, accountRegistry_1.getAccountsDir)(), providerDirName(provider), 'last-switch.json');
58
+ }
59
+ function readLastSwitch(provider) {
60
+ try {
61
+ const parsed = JSON.parse(fs.readFileSync(getLastSwitchPath(provider), 'utf8'));
62
+ return parsed && typeof parsed.token === 'string' && typeof parsed.to === 'string'
63
+ ? parsed
64
+ : null;
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ }
70
+ function writeLastSwitch(provider, from, to) {
71
+ const record = {
72
+ token: (0, crypto_1.randomUUID)(),
73
+ provider,
74
+ from,
75
+ to,
76
+ at: new Date().toISOString(),
77
+ };
78
+ (0, atomic_1.atomicWriteJsonSync)(getLastSwitchPath(provider), record);
79
+ return record;
80
+ }
81
+ function clearLastSwitch(provider) {
82
+ try {
83
+ fs.rmSync(getLastSwitchPath(provider), { force: true });
84
+ }
85
+ catch {
86
+ /* best effort */
87
+ }
88
+ }
89
+ function switchFailure(provider, accountId, error, extra = {}) {
90
+ return {
91
+ success: false,
92
+ error,
93
+ provider,
94
+ accountId,
95
+ previousAccountId: null,
96
+ verified: false,
97
+ verification: 'none',
98
+ warnings: [],
99
+ hints: [],
100
+ runningConsumers: [],
101
+ ...extra,
102
+ };
103
+ }
104
+ /** Fold per-consumer warnings into a result; keeps `warning` (legacy) in sync. */
105
+ function finishSwitchResult(result) {
106
+ const warnings = [
107
+ ...result.warnings,
108
+ ...result.runningConsumers.map((consumer) => consumer.reachability),
109
+ ];
110
+ return {
111
+ ...result,
112
+ warnings,
113
+ warning: warnings.length ? warnings.join(' ') : undefined,
114
+ };
115
+ }
@@ -0,0 +1,30 @@
1
+ import type { AccountProviderId } from './accountRegistry';
2
+ import { type SyncReason, type SyncReport } from './accountSyncTypes';
3
+ export interface SyncLiveAccountStateOptions {
4
+ providers?: AccountProviderId[];
5
+ reason?: SyncReason;
6
+ /**
7
+ * Skip the sync when the live files have not changed since the last pass
8
+ * (default for `watch`/`poll`). On macOS the Keychain cannot be fingerprinted
9
+ * cheaply, so a Claude fold still runs at most every `keychainFoldIntervalMs`.
10
+ */
11
+ onlyIfChanged?: boolean;
12
+ keychainFoldIntervalMs?: number;
13
+ now?: number;
14
+ }
15
+ /**
16
+ * Reconcile the live logins with the saved profiles for both providers.
17
+ * Safe to call from watchers: re-entrant calls return an empty report, and
18
+ * `onlyIfChanged` short-circuits when the live files are unchanged.
19
+ */
20
+ export declare function syncLiveAccountStateSync(options?: SyncLiveAccountStateOptions): SyncReport;
21
+ /** Promise-returning twin of {@link syncLiveAccountStateSync} for async hosts. */
22
+ export declare function syncLiveAccountState(options?: SyncLiveAccountStateOptions): Promise<SyncReport>;
23
+ /** Forget the change fingerprints (tests, or after an external reset). */
24
+ export declare function _resetSyncFingerprints(): void;
25
+ export interface CleanupAbandonedLoginsResult {
26
+ claude: string[];
27
+ codex: string[];
28
+ }
29
+ /** Remove isolated login homes that never authenticated (both providers). */
30
+ export declare function cleanupAbandonedLogins(olderThanMs?: number, now?: number): CleanupAbandonedLoginsResult;
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.syncLiveAccountStateSync = syncLiveAccountStateSync;
37
+ exports.syncLiveAccountState = syncLiveAccountState;
38
+ exports._resetSyncFingerprints = _resetSyncFingerprints;
39
+ exports.cleanupAbandonedLogins = cleanupAbandonedLogins;
40
+ /**
41
+ * Continuous reconciliation between the live provider logins and sidekick's
42
+ * saved profiles. One engine replaces the old bootstrap/reconcile/backup
43
+ * paths: it registers logins sidekick has never seen, folds rotated tokens
44
+ * back into their profile, merges duplicate Codex seats, and re-points the
45
+ * active pointer at whatever is really logged in.
46
+ */
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ const accounts_1 = require("./accounts");
50
+ const claudeProfiles_1 = require("./claudeProfiles");
51
+ const codexProfiles_1 = require("./codexProfiles");
52
+ const codexPaths_1 = require("./codexPaths");
53
+ const accountSyncTypes_1 = require("./accountSyncTypes");
54
+ const DEFAULT_KEYCHAIN_FOLD_INTERVAL_MS = 10 * 60 * 1000;
55
+ const fingerprints = {
56
+ 'claude-code': {},
57
+ codex: {},
58
+ };
59
+ let syncInProgress = false;
60
+ function statStamp(filePath) {
61
+ try {
62
+ const stat = fs.statSync(filePath);
63
+ return `${stat.mtimeMs}:${stat.size}`;
64
+ }
65
+ catch {
66
+ return 'absent';
67
+ }
68
+ }
69
+ function claudeFingerprint() {
70
+ const home = (0, claudeProfiles_1.getLiveClaudeHome)();
71
+ const identity = (0, claudeProfiles_1.readLiveClaudeIdentity)();
72
+ // Fingerprint the identity, not the config file: Claude Code rewrites
73
+ // `~/.claude.json` on nearly every prompt, which would defeat the
74
+ // `onlyIfChanged` short-circuit and the macOS keychain fold interval.
75
+ return [
76
+ identity?.uuid ?? 'none',
77
+ identity?.email ?? '',
78
+ statStamp(path.join(home, '.credentials.json')),
79
+ ].join('|');
80
+ }
81
+ function codexFingerprint() {
82
+ const home = (0, codexPaths_1.getSystemCodexHome)();
83
+ return [
84
+ statStamp(path.join(home, 'auth.json')),
85
+ statStamp(path.join(home, '.credentials.json')),
86
+ ].join('|');
87
+ }
88
+ function sourceForReason(reason) {
89
+ return reason === 'pre-switch' ? 'switch' : 'live-sync';
90
+ }
91
+ function shouldSync(provider, fingerprint, options) {
92
+ if (!options.onlyIfChanged)
93
+ return true;
94
+ const state = fingerprints[provider];
95
+ if (state.fingerprint !== fingerprint)
96
+ return true;
97
+ if (provider === 'claude-code' && process.platform === 'darwin') {
98
+ // The Keychain item can change without touching any watched file.
99
+ return (state.lastFoldAt ?? 0) + options.keychainFoldIntervalMs <= options.now;
100
+ }
101
+ return false;
102
+ }
103
+ /** Sync one provider under its swap lock; never throws. */
104
+ function syncProvider(provider, reason, options) {
105
+ const fingerprint = provider === 'codex' ? codexFingerprint() : claudeFingerprint();
106
+ if (!shouldSync(provider, fingerprint, options)) {
107
+ return { ...(0, accountSyncTypes_1.emptyProviderSyncReport)(), skipped: 'unchanged' };
108
+ }
109
+ const source = sourceForReason(reason);
110
+ let report;
111
+ try {
112
+ report =
113
+ provider === 'codex'
114
+ ? (0, codexProfiles_1.withCodexAuthSwapLock)(() => (0, codexProfiles_1.syncCodexLiveStateUnlocked)(source))
115
+ : (0, accounts_1.withClaudeAuthSwapLock)(() => (0, accounts_1.syncClaudeLiveStateUnlocked)(source));
116
+ }
117
+ catch (err) {
118
+ return { warnings: [`Could not acquire the ${provider} account-switch lock: ${err}`] };
119
+ }
120
+ fingerprints[provider] = {
121
+ // Re-fingerprint after the sync: folding rewrites nothing in the live home,
122
+ // but registering touches accounts.json, which is also watched.
123
+ fingerprint: provider === 'codex' ? codexFingerprint() : claudeFingerprint(),
124
+ lastFoldAt: options.now,
125
+ };
126
+ return report;
127
+ }
128
+ /**
129
+ * Reconcile the live logins with the saved profiles for both providers.
130
+ * Safe to call from watchers: re-entrant calls return an empty report, and
131
+ * `onlyIfChanged` short-circuits when the live files are unchanged.
132
+ */
133
+ function syncLiveAccountStateSync(options = {}) {
134
+ const reason = options.reason ?? 'manual';
135
+ const now = options.now ?? Date.now();
136
+ const resolved = {
137
+ onlyIfChanged: options.onlyIfChanged ?? (reason === 'watch' || reason === 'poll'),
138
+ keychainFoldIntervalMs: options.keychainFoldIntervalMs ?? DEFAULT_KEYCHAIN_FOLD_INTERVAL_MS,
139
+ now,
140
+ };
141
+ const providers = options.providers ?? ['claude-code', 'codex'];
142
+ const report = {
143
+ claude: { ...(0, accountSyncTypes_1.emptyProviderSyncReport)(), skipped: 'not-requested' },
144
+ codex: { ...(0, accountSyncTypes_1.emptyProviderSyncReport)(), skipped: 'not-requested' },
145
+ ranAt: now,
146
+ reason,
147
+ };
148
+ if (syncInProgress) {
149
+ report.claude.skipped = 'in-progress';
150
+ report.codex.skipped = 'in-progress';
151
+ return report;
152
+ }
153
+ syncInProgress = true;
154
+ try {
155
+ if (providers.includes('claude-code'))
156
+ report.claude = syncProvider('claude-code', reason, resolved);
157
+ if (providers.includes('codex'))
158
+ report.codex = syncProvider('codex', reason, resolved);
159
+ }
160
+ finally {
161
+ syncInProgress = false;
162
+ }
163
+ return report;
164
+ }
165
+ /** Promise-returning twin of {@link syncLiveAccountStateSync} for async hosts. */
166
+ async function syncLiveAccountState(options = {}) {
167
+ return syncLiveAccountStateSync(options);
168
+ }
169
+ /** Forget the change fingerprints (tests, or after an external reset). */
170
+ function _resetSyncFingerprints() {
171
+ fingerprints['claude-code'] = {};
172
+ fingerprints.codex = {};
173
+ }
174
+ /** Remove isolated login homes that never authenticated (both providers). */
175
+ function cleanupAbandonedLogins(olderThanMs = 6 * 60 * 60 * 1000, now = Date.now()) {
176
+ return {
177
+ claude: (0, accounts_1.cleanupAbandonedClaudeLogins)(olderThanMs, now),
178
+ codex: (0, codexProfiles_1.cleanupAbandonedCodexLogins)(olderThanMs, now),
179
+ };
180
+ }
@@ -0,0 +1,25 @@
1
+ /** Reports produced by the live-state sync engine (see accountSync.ts). */
2
+ export interface ProviderSyncReport {
3
+ /** A live login that had no saved profile was registered under this id. */
4
+ registered?: {
5
+ id: string;
6
+ email?: string;
7
+ };
8
+ /** The live credential was folded into this profile's backup. */
9
+ folded?: string;
10
+ /** The active pointer was moved to this profile to match the live login. */
11
+ repointed?: string;
12
+ /** Duplicate profiles merged away (ids of the removed losers). */
13
+ merged?: string[];
14
+ /** Why nothing was synced (`logged-out`, `keyring`, `no-identity`, `unchanged`). */
15
+ skipped?: string;
16
+ warnings: string[];
17
+ }
18
+ export type SyncReason = 'startup' | 'watch' | 'poll' | 'pre-switch' | 'manual';
19
+ export interface SyncReport {
20
+ claude: ProviderSyncReport;
21
+ codex: ProviderSyncReport;
22
+ ranAt: number;
23
+ reason: SyncReason;
24
+ }
25
+ export declare function emptyProviderSyncReport(): ProviderSyncReport;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /** Reports produced by the live-state sync engine (see accountSync.ts). */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.emptyProviderSyncReport = emptyProviderSyncReport;
5
+ function emptyProviderSyncReport() {
6
+ return { warnings: [] };
7
+ }
@@ -1,10 +1,18 @@
1
1
  /**
2
- * Multi-account management for Claude Max subscriptions.
2
+ * Multi-account management for Claude Code logins.
3
3
  *
4
- * Handles saving, listing, switching, and removing Claude accounts.
4
+ * Handles saving, listing, switching, syncing, and removing Claude accounts.
5
5
  * Both the VS Code extension and CLI consume this module.
6
+ *
7
+ * Model: the live home (`CLAUDE_CONFIG_DIR` or `~/.claude`) is the source of
8
+ * truth for whichever account is logged in right now; every saved profile is a
9
+ * backup that the sync core keeps fresh, because Claude Code rotates the
10
+ * refresh token on every refresh and a stale snapshot is a dead login.
6
11
  */
7
12
  import { type ResolvedActiveAccount } from './accountRegistry';
13
+ import { type AccountHealthSource } from './accountHealth';
14
+ import { type SwitchAccountOptions, type SwitchAccountResult } from './accountSwitch';
15
+ import { type ProviderSyncReport } from './accountSyncTypes';
8
16
  export interface AccountEntry {
9
17
  uuid: string;
10
18
  email: string;
@@ -28,11 +36,54 @@ export interface AccountManagerResult {
28
36
  profileId?: string;
29
37
  codexHome?: string;
30
38
  }
39
+ /** Store a profile's identity (`oauthAccount`) in its home and the flat backup. */
40
+ export declare function storeClaudeProfileIdentity(uuid: string, oauthAccount: unknown): void;
41
+ /**
42
+ * The single chokepoint for storing a Claude credential in a profile: profile
43
+ * home store (suffixed Keychain item on macOS, file elsewhere), the flat
44
+ * backup, and the secret-free health sidecar.
45
+ */
46
+ export declare function storeClaudeProfileCredentials(uuid: string, credentials: unknown, source: AccountHealthSource): void;
47
+ export declare function readStoredClaudeAccount(uuid: string): {
48
+ credentials: unknown;
49
+ oauthAccount: unknown;
50
+ } | null;
31
51
  export declare function readAccountRegistry(): AccountRegistry | null;
32
52
  export declare function writeAccountRegistry(registry: AccountRegistry): void;
33
53
  export declare function readActiveClaudeAccount(): ActiveAccountInfo | null;
34
54
  export declare function addCurrentAccount(label?: string): AccountManagerResult;
35
- export declare function switchToAccount(uuid: string): AccountManagerResult;
55
+ /**
56
+ * Serializes live Claude credential swaps across processes so two concurrent
57
+ * switchers cannot interleave their backup/write/rollback sequences. It cannot
58
+ * exclude Claude Code's own writes to the live home — only our switchers. Lock
59
+ * ordering: this lock first, the registry lock (inside setActiveSavedAccount)
60
+ * inside it — never the reverse. Never spawn a child process while holding it.
61
+ */
62
+ export declare function withClaudeAuthSwapLock<T>(operation: () => T): T;
63
+ /**
64
+ * Fold the live login into the saved profiles: register an unknown login
65
+ * (label = email), refresh the matching profile's backup when the live
66
+ * credential is newer, and re-point the active pointer at it. Caller holds the
67
+ * swap lock. Never throws; problems land in `warnings`.
68
+ */
69
+ export declare function syncClaudeLiveStateUnlocked(source?: AccountHealthSource): ProviderSyncReport;
70
+ /** {@link syncClaudeLiveStateUnlocked} under the swap lock. */
71
+ export declare function syncClaudeLiveState(source?: AccountHealthSource): ProviderSyncReport;
72
+ /**
73
+ * Remove isolated login homes that never authenticated (the user closed the
74
+ * browser, the login timed out) once they are older than `olderThanMs`.
75
+ * Returns the removed login ids.
76
+ */
77
+ export declare function cleanupAbandonedClaudeLogins(olderThanMs?: number, now?: number): string[];
78
+ export declare function switchToAccount(uuid: string, options?: SwitchAccountOptions): SwitchAccountResult;
79
+ /** {@link switchToAccount} with the process probe off the event loop. */
80
+ export declare function switchToAccountAsync(uuid: string, options?: SwitchAccountOptions): Promise<SwitchAccountResult>;
81
+ /**
82
+ * Install a saved profile's credentials into the live home without changing
83
+ * which account is active: used right after a re-login of the live account,
84
+ * whose freshly minted token must replace the (possibly dead) live one.
85
+ */
86
+ export declare function applyClaudeProfileToLiveHome(uuid: string): AccountManagerResult;
36
87
  export declare function resolveActiveClaudeHome(): string;
37
88
  export declare function applyActiveClaudeToLiveHome(): AccountManagerResult;
38
89
  export declare function reconcileClaudeAuthState(): void;
@@ -41,14 +92,15 @@ export declare function listAccounts(): AccountEntry[];
41
92
  export declare function getActiveAccount(): AccountEntry | null;
42
93
  /**
43
94
  * Resolves the *currently logged-in* Claude account for display, preferring the
44
- * live `~/.claude/.claude.json` identity over the saved registry pointer (which
45
- * only sidekick's own switch flow updates and therefore goes stale after a native
95
+ * live `.claude.json` identity over the saved registry pointer (which only
96
+ * sidekick's own switch flow updates and therefore goes stale after a native
46
97
  * `claude /login`).
47
98
  *
48
99
  * Safe self-heal: when the live account matches a saved profile (by account UUID,
49
100
  * email as fallback) that isn't the current active pointer, the pointer is
50
101
  * re-pointed so registry-keyed data tracks reality too. Never creates or deletes
51
- * profiles; an unknown live account is shown as-is with no label and no write.
102
+ * profiles; an unknown live account is shown as-is with no label and no write
103
+ * (the sync engine registers it on the next startup or watch event).
52
104
  */
53
105
  export declare function resolveActiveClaudeAccount(options?: {
54
106
  selfHeal?: boolean;