sidekick-shared 0.26.4 → 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 (69) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +59 -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 +31 -12
  37. package/dist/index.js +68 -13
  38. package/dist/keepAlive.d.ts +44 -0
  39. package/dist/keepAlive.js +106 -0
  40. package/dist/node.d.ts +4 -1
  41. package/dist/node.js +4 -1
  42. package/dist/observedSessionCollector.d.ts +117 -5
  43. package/dist/observedSessionCollector.js +483 -76
  44. package/dist/processDetection.d.ts +32 -0
  45. package/dist/processDetection.js +210 -0
  46. package/dist/providers/claudeCode.d.ts +23 -2
  47. package/dist/providers/claudeCode.js +143 -51
  48. package/dist/providers/codex.d.ts +10 -2
  49. package/dist/providers/codex.js +95 -12
  50. package/dist/providers/directoryListingCache.d.ts +85 -0
  51. package/dist/providers/directoryListingCache.js +244 -0
  52. package/dist/providers/rolloutWalker.d.ts +28 -5
  53. package/dist/providers/rolloutWalker.js +100 -16
  54. package/dist/providers/types.d.ts +48 -1
  55. package/dist/schemas/accountManager.d.ts +283 -1
  56. package/dist/schemas/accountManager.js +122 -1
  57. package/dist/schemas/assistantTurn.d.ts +2 -2
  58. package/dist/schemas/index.d.ts +6 -1
  59. package/dist/schemas/index.js +14 -1
  60. package/dist/schemas/observedSessionV1.d.ts +21 -21
  61. package/dist/schemas/quota.d.ts +18 -18
  62. package/dist/schemas/quotaHistory.d.ts +1 -1
  63. package/dist/schemas/stateFile.d.ts +5 -5
  64. package/dist/sessionMonitor.js +24 -2
  65. package/dist/terminalSync.d.ts +5 -5
  66. package/dist/terminalSync.js +7 -112
  67. package/dist/writers/atomic.d.ts +2 -0
  68. package/dist/writers/atomic.js +49 -2
  69. package/package.json +1 -1
@@ -9,11 +9,16 @@
9
9
  * `limit` can stop early, stats each file exactly once, and returns results
10
10
  * newest first with the size and session id already attached.
11
11
  *
12
- * With `limit`, the early exit is by directory date: a rollout that was
13
- * created days ago but is still being written lands in its creation day's
14
- * directory, so a very small limit can miss it in favour of newer-dated,
15
- * older-modified files. Callers that need exact mtime order over the whole
16
- * history omit `limit` (the `maxFiles` cap still applies).
12
+ * With `limit` or `since`, the early exit is by directory date: a rollout
13
+ * that was created days ago but is still being written lands in its creation
14
+ * day's directory, so a very small limit (or a recent `since`) can miss it in
15
+ * favour of newer-dated, older-modified files. Callers that need exact mtime
16
+ * order over the whole history omit both (the `maxFiles` cap still applies);
17
+ * a live session missed this way is picked up by its next watch event.
18
+ *
19
+ * The async walker accepts a {@link DirectoryListingCache}: unchanged
20
+ * directories are then one stat each instead of a readdir plus a stat per
21
+ * file, which is what makes repeated discovery over a large history cheap.
17
22
  *
18
23
  * @module providers/rolloutWalker
19
24
  */
@@ -54,6 +59,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
54
59
  exports.DEFAULT_ROLLOUT_WALK_MAX_FILES = exports.DEFAULT_ROLLOUT_WALK_MAX_DEPTH = void 0;
55
60
  exports.isRolloutFile = isRolloutFile;
56
61
  exports.extractRolloutSessionId = extractRolloutSessionId;
62
+ exports.isDatedDirectoryBefore = isDatedDirectoryBefore;
57
63
  exports.walkRolloutFiles = walkRolloutFiles;
58
64
  exports.walkRolloutFilesAsync = walkRolloutFilesAsync;
59
65
  const fs = __importStar(require("fs"));
@@ -90,8 +96,12 @@ function walkState(options) {
90
96
  seen: new Set(),
91
97
  cap: Math.min(maxFiles, limit),
92
98
  maxDepth: options.maxDepth ?? exports.DEFAULT_ROLLOUT_WALK_MAX_DEPTH,
99
+ since: options.since !== undefined && Number.isFinite(options.since) ? options.since : null,
93
100
  sessionId: options.sessionId ? options.sessionId.trim().toLowerCase() : null,
94
101
  includeEmpty: options.includeEmpty ?? false,
102
+ cache: options.cache ?? null,
103
+ revalidateRecent: options.revalidateRecent ?? false,
104
+ stats: options.stats,
95
105
  };
96
106
  }
97
107
  /** Newest-dated first: directory and file names sort descending. */
@@ -106,12 +116,14 @@ function matchesFilter(state, name) {
106
116
  function record(state, fullPath, name, stat) {
107
117
  if (!state.includeEmpty && stat.size <= 0)
108
118
  return;
119
+ if (state.since !== null && stat.mtimeMs < state.since)
120
+ return;
109
121
  if (state.seen.has(fullPath))
110
122
  return;
111
123
  state.seen.add(fullPath);
112
124
  state.results.push({
113
125
  path: fullPath,
114
- mtime: stat.mtime,
126
+ mtime: new Date(stat.mtimeMs),
115
127
  sizeBytes: stat.size,
116
128
  sessionId: extractRolloutSessionId(name),
117
129
  });
@@ -119,9 +131,38 @@ function record(state, fullPath, name, stat) {
119
131
  function finish(state) {
120
132
  return state.results.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
121
133
  }
122
- function visitSync(state, dir, depth) {
134
+ /** Slack added to a dated directory's range so a timezone skew cannot prune a live day. */
135
+ const DATE_DIR_SLACK_MS = 24 * 60 * 60_000;
136
+ /**
137
+ * True when `segments` (the directory names below the root, e.g. `['2026',
138
+ * '09', '04']`) are all numeric and describe a year, month, or day that ended
139
+ * more than a day before `since`. Non-numeric names are never pruned.
140
+ */
141
+ function isDatedDirectoryBefore(segments, since) {
142
+ if (segments.length === 0 || segments.length > 3)
143
+ return false;
144
+ const numbers = segments.map((segment) => (/^\d+$/.test(segment) ? Number(segment) : NaN));
145
+ if (numbers.some((value) => !Number.isFinite(value)))
146
+ return false;
147
+ const [year, month, day] = numbers;
148
+ if (year < 1970 || year > 9999)
149
+ return false;
150
+ if (segments.length >= 2 && (month < 1 || month > 12))
151
+ return false;
152
+ if (segments.length === 3 && (day < 1 || day > 31))
153
+ return false;
154
+ const rangeEnd = segments.length === 1
155
+ ? new Date(year + 1, 0, 1).getTime()
156
+ : segments.length === 2
157
+ ? new Date(year, month, 1).getTime()
158
+ : new Date(year, month - 1, day + 1).getTime();
159
+ return rangeEnd + DATE_DIR_SLACK_MS < since;
160
+ }
161
+ function visitSync(state, dir, depth, segments) {
123
162
  if (depth > state.maxDepth || state.results.length >= state.cap)
124
163
  return;
164
+ if (state.since !== null && isDatedDirectoryBefore(segments, state.since))
165
+ return;
125
166
  let entries;
126
167
  try {
127
168
  entries = fs.readdirSync(dir, { withFileTypes: true });
@@ -146,8 +187,9 @@ function visitSync(state, dir, depth) {
146
187
  for (const entry of entries) {
147
188
  if (state.results.length >= state.cap)
148
189
  return;
149
- if (entry.isDirectory())
150
- visitSync(state, path.join(dir, entry.name), depth + 1);
190
+ if (entry.isDirectory()) {
191
+ visitSync(state, path.join(dir, entry.name), depth + 1, [...segments, entry.name]);
192
+ }
151
193
  }
152
194
  }
153
195
  /**
@@ -157,18 +199,52 @@ function visitSync(state, dir, depth) {
157
199
  function walkRolloutFiles(roots, options = {}) {
158
200
  const state = walkState(options);
159
201
  for (const root of roots)
160
- visitSync(state, root, 0);
202
+ visitSync(state, root, 0, []);
161
203
  return finish(state);
162
204
  }
163
205
  function yieldToEventLoop() {
164
206
  return new Promise((resolve) => setImmediate(resolve));
165
207
  }
166
- async function visitAsync(state, dir, depth) {
208
+ function byStringDescending(a, b) {
209
+ return b.localeCompare(a);
210
+ }
211
+ async function visitCached(state, cache, dir, depth, segments) {
167
212
  if (depth > state.maxDepth || state.results.length >= state.cap)
168
213
  return;
214
+ if (state.since !== null && isDatedDirectoryBefore(segments, state.since))
215
+ return;
216
+ const listing = await cache.listDirectory(dir, (name) => matchesFilter(state, name), {
217
+ revalidateRecent: state.revalidateRecent,
218
+ stats: state.stats,
219
+ });
220
+ if (!listing)
221
+ return;
222
+ const names = [...listing.files.keys()].sort(byStringDescending);
223
+ for (const name of names) {
224
+ if (state.results.length >= state.cap)
225
+ return;
226
+ const stat = listing.files.get(name);
227
+ if (!stat)
228
+ continue;
229
+ record(state, path.join(dir, name), name, { size: stat.sizeBytes, mtimeMs: stat.mtimeMs });
230
+ }
231
+ await yieldToEventLoop();
232
+ for (const name of [...listing.subdirectories].sort(byStringDescending)) {
233
+ if (state.results.length >= state.cap)
234
+ return;
235
+ await visitCached(state, cache, path.join(dir, name), depth + 1, [...segments, name]);
236
+ }
237
+ }
238
+ async function visitAsync(state, dir, depth, segments) {
239
+ if (depth > state.maxDepth || state.results.length >= state.cap)
240
+ return;
241
+ if (state.since !== null && isDatedDirectoryBefore(segments, state.since))
242
+ return;
169
243
  let entries;
170
244
  try {
171
245
  entries = await fs.promises.readdir(dir, { withFileTypes: true });
246
+ if (state.stats)
247
+ state.stats.directoriesListed = (state.stats.directoriesListed ?? 0) + 1;
172
248
  }
173
249
  catch {
174
250
  return;
@@ -182,7 +258,10 @@ async function visitAsync(state, dir, depth) {
182
258
  continue;
183
259
  const fullPath = path.join(dir, entry.name);
184
260
  try {
185
- record(state, fullPath, entry.name, await fs.promises.stat(fullPath));
261
+ const stat = await fs.promises.stat(fullPath);
262
+ if (state.stats)
263
+ state.stats.filesStatted = (state.stats.filesStatted ?? 0) + 1;
264
+ record(state, fullPath, entry.name, stat);
186
265
  }
187
266
  catch {
188
267
  // Skip files that vanish between readdir and stat.
@@ -196,14 +275,19 @@ async function visitAsync(state, dir, depth) {
196
275
  for (const entry of entries) {
197
276
  if (state.results.length >= state.cap)
198
277
  return;
199
- if (entry.isDirectory())
200
- await visitAsync(state, path.join(dir, entry.name), depth + 1);
278
+ if (entry.isDirectory()) {
279
+ await visitAsync(state, path.join(dir, entry.name), depth + 1, [...segments, entry.name]);
280
+ }
201
281
  }
202
282
  }
203
283
  /** Async twin of {@link walkRolloutFiles} that yields between directories. */
204
284
  async function walkRolloutFilesAsync(roots, options = {}) {
205
285
  const state = walkState(options);
206
- for (const root of roots)
207
- await visitAsync(state, root, 0);
286
+ for (const root of roots) {
287
+ if (state.cache)
288
+ await visitCached(state, state.cache, root, 0, []);
289
+ else
290
+ await visitAsync(state, root, 0, []);
291
+ }
208
292
  return finish(state);
209
293
  }
@@ -59,6 +59,46 @@ export interface SessionFileInfo {
59
59
  /** Optional provider-recorded creation timestamp. */
60
60
  createdAt?: Date;
61
61
  }
62
+ /** Payload-free counters of what an enumeration cost. */
63
+ export interface SessionEnumerationCounters {
64
+ directoriesListed?: number;
65
+ directoriesStatted?: number;
66
+ filesStatted?: number;
67
+ }
68
+ /** Options for `listSessionFilesAsync()`; every field is optional and additive. */
69
+ export interface ListSessionFilesOptions {
70
+ /** Return at most this many files, newest first (may skip an old-directory live session; see rolloutWalker). */
71
+ limit?: number;
72
+ /** Only files modified at or after this epoch-ms. */
73
+ since?: number;
74
+ /** Re-stat recently modified files even when their directory is unchanged. */
75
+ revalidateRecent?: boolean;
76
+ /** Counters the enumerator increments for real readdir/stat calls. */
77
+ stats?: SessionEnumerationCounters;
78
+ }
79
+ /**
80
+ * What a recursive-watch event under one of the provider's watch roots maps
81
+ * to, resolved with at most one stat.
82
+ *
83
+ * - `ignored`: structurally not a session of this provider (wrong depth or
84
+ * extension, another workspace); nothing to do.
85
+ * - `unknown`: a directory or something the provider cannot classify; the
86
+ * caller should fall back to a full enumeration.
87
+ * - `missing`: the path names a session that is gone or still empty.
88
+ * - `present`: the session file with its current stat.
89
+ */
90
+ export type WatchedSessionFile = {
91
+ status: 'ignored';
92
+ } | {
93
+ status: 'unknown';
94
+ } | {
95
+ status: 'missing';
96
+ path: string;
97
+ sessionId: string;
98
+ } | {
99
+ status: 'present';
100
+ file: SessionFileInfo;
101
+ };
62
102
  /** How much of a session `readSessionStats()` could read. */
63
103
  export type SessionFileStatsAvailability = 'full' | 'partial' | 'unavailable';
64
104
  /**
@@ -225,7 +265,14 @@ export interface SessionProviderBase {
225
265
  */
226
266
  listAllSessionFiles?(): SessionFileInfo[];
227
267
  /** Event-loop-safe enumeration used by async preview and subscription APIs. */
228
- listSessionFilesAsync?(workspacePath?: string): Promise<SessionFileInfo[]>;
268
+ listSessionFilesAsync?(workspacePath?: string, options?: ListSessionFilesOptions): Promise<SessionFileInfo[]>;
269
+ /**
270
+ * Resolve a recursive-watch event (`root` from `getWatchRoots()`, the
271
+ * root-relative `relativePath` the watcher reported) to a session file with
272
+ * at most one stat, applying the same workspace filter as
273
+ * `listSessionFilesAsync(workspacePath)`.
274
+ */
275
+ statWatchedSessionFile?(root: string, relativePath: string, workspacePath?: string): Promise<WatchedSessionFile>;
229
276
  /** Batch label extraction. DB-backed implementations use at most one query. */
230
277
  extractSessionLabelsAsync?(sessionPaths: readonly string[]): Promise<Map<string, string | null>>;
231
278
  /** Tests whether a provider can monitor a directory path, including synthetic DB-backed paths. */
@@ -28,16 +28,18 @@ export declare const beginAccountLoginResultSchema: z.ZodUnion<readonly [z.ZodOb
28
28
  command: z.ZodOptional<z.ZodString>;
29
29
  args: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
30
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
31
+ envUnset: z.ZodOptional<z.ZodArray<z.ZodString>>;
31
32
  configDir: z.ZodOptional<z.ZodString>;
33
+ existingAccountId: z.ZodOptional<z.ZodString>;
32
34
  }, z.core.$strip>, z.ZodObject<{
33
35
  success: z.ZodLiteral<false>;
34
36
  error: z.ZodString;
35
37
  }, z.core.$strip>]>;
36
38
  export declare const accountLoginStatusSchema: z.ZodObject<{
37
39
  state: z.ZodEnum<{
40
+ failed: "failed";
38
41
  pending: "pending";
39
42
  authenticated: "authenticated";
40
- failed: "failed";
41
43
  }>;
42
44
  email: z.ZodOptional<z.ZodString>;
43
45
  error: z.ZodOptional<z.ZodString>;
@@ -67,6 +69,12 @@ export declare const savedAccountProfileSchema: z.ZodObject<{
67
69
  chatgpt: "chatgpt";
68
70
  "api-key": "api-key";
69
71
  }>>;
72
+ origin: z.ZodOptional<z.ZodEnum<{
73
+ login: "login";
74
+ manual: "manual";
75
+ "live-sync": "live-sync";
76
+ migration: "migration";
77
+ }>>;
70
78
  }, z.core.$strip>>;
71
79
  }, z.core.$strip>;
72
80
  export declare const listAllAccountsResultSchema: z.ZodObject<{
@@ -95,6 +103,12 @@ export declare const listAllAccountsResultSchema: z.ZodObject<{
95
103
  chatgpt: "chatgpt";
96
104
  "api-key": "api-key";
97
105
  }>>;
106
+ origin: z.ZodOptional<z.ZodEnum<{
107
+ login: "login";
108
+ manual: "manual";
109
+ "live-sync": "live-sync";
110
+ migration: "migration";
111
+ }>>;
98
112
  }, z.core.$strip>>;
99
113
  }, z.core.$strip>>;
100
114
  activeByProvider: z.ZodObject<{
@@ -102,3 +116,271 @@ export declare const listAllAccountsResultSchema: z.ZodObject<{
102
116
  codex: z.ZodNullable<z.ZodString>;
103
117
  }, z.core.$strip>;
104
118
  }, z.core.$strip>;
119
+ export declare const accountHealthStateSchema: z.ZodEnum<{
120
+ unknown: "unknown";
121
+ fresh: "fresh";
122
+ expiring: "expiring";
123
+ expired: "expired";
124
+ missing: "missing";
125
+ }>;
126
+ export declare const accountHealthSourceSchema: z.ZodEnum<{
127
+ login: "login";
128
+ "live-sync": "live-sync";
129
+ migration: "migration";
130
+ switch: "switch";
131
+ keepalive: "keepalive";
132
+ }>;
133
+ export declare const accountHealthSidecarSchema: z.ZodObject<{
134
+ version: z.ZodLiteral<1>;
135
+ capturedAt: z.ZodNumber;
136
+ accessExpiresAt: z.ZodOptional<z.ZodNumber>;
137
+ refreshExpiresAt: z.ZodOptional<z.ZodNumber>;
138
+ refreshExpiryEstimated: z.ZodOptional<z.ZodBoolean>;
139
+ lastRefreshAt: z.ZodOptional<z.ZodNumber>;
140
+ hasRefreshToken: z.ZodOptional<z.ZodBoolean>;
141
+ authMode: z.ZodOptional<z.ZodEnum<{
142
+ chatgpt: "chatgpt";
143
+ "api-key": "api-key";
144
+ oauth: "oauth";
145
+ }>>;
146
+ source: z.ZodEnum<{
147
+ login: "login";
148
+ "live-sync": "live-sync";
149
+ migration: "migration";
150
+ switch: "switch";
151
+ keepalive: "keepalive";
152
+ }>;
153
+ }, z.core.$strip>;
154
+ export declare const accountHealthSchema: z.ZodObject<{
155
+ providerId: z.ZodEnum<{
156
+ "claude-code": "claude-code";
157
+ codex: "codex";
158
+ }>;
159
+ accountId: z.ZodString;
160
+ state: z.ZodEnum<{
161
+ unknown: "unknown";
162
+ fresh: "fresh";
163
+ expiring: "expiring";
164
+ expired: "expired";
165
+ missing: "missing";
166
+ }>;
167
+ accessExpiresAt: z.ZodOptional<z.ZodNumber>;
168
+ refreshExpiresAt: z.ZodOptional<z.ZodNumber>;
169
+ refreshExpiryEstimated: z.ZodOptional<z.ZodBoolean>;
170
+ lastRefreshAt: z.ZodOptional<z.ZodNumber>;
171
+ checkedAt: z.ZodNumber;
172
+ isLive: z.ZodBoolean;
173
+ reason: z.ZodOptional<z.ZodString>;
174
+ }, z.core.$strip>;
175
+ export declare const accountViewSchema: z.ZodObject<{
176
+ id: z.ZodString;
177
+ providerId: z.ZodEnum<{
178
+ "claude-code": "claude-code";
179
+ codex: "codex";
180
+ }>;
181
+ label: z.ZodOptional<z.ZodString>;
182
+ email: z.ZodOptional<z.ZodString>;
183
+ planType: z.ZodOptional<z.ZodString>;
184
+ isActive: z.ZodBoolean;
185
+ health: z.ZodObject<{
186
+ providerId: z.ZodEnum<{
187
+ "claude-code": "claude-code";
188
+ codex: "codex";
189
+ }>;
190
+ accountId: z.ZodString;
191
+ state: z.ZodEnum<{
192
+ unknown: "unknown";
193
+ fresh: "fresh";
194
+ expiring: "expiring";
195
+ expired: "expired";
196
+ missing: "missing";
197
+ }>;
198
+ accessExpiresAt: z.ZodOptional<z.ZodNumber>;
199
+ refreshExpiresAt: z.ZodOptional<z.ZodNumber>;
200
+ refreshExpiryEstimated: z.ZodOptional<z.ZodBoolean>;
201
+ lastRefreshAt: z.ZodOptional<z.ZodNumber>;
202
+ checkedAt: z.ZodNumber;
203
+ isLive: z.ZodBoolean;
204
+ reason: z.ZodOptional<z.ZodString>;
205
+ }, z.core.$strip>;
206
+ source: z.ZodEnum<{
207
+ registered: "registered";
208
+ learned: "learned";
209
+ }>;
210
+ addedAt: z.ZodString;
211
+ }, z.core.$strip>;
212
+ export declare const runningProcessSchema: z.ZodObject<{
213
+ pid: z.ZodNumber;
214
+ name: z.ZodString;
215
+ command: z.ZodString;
216
+ }, z.core.$strip>;
217
+ export declare const accountConsumerKindSchema: z.ZodEnum<{
218
+ "claude-cli": "claude-cli";
219
+ "claude-desktop": "claude-desktop";
220
+ "codex-cli": "codex-cli";
221
+ "codex-app": "codex-app";
222
+ "vscode-extension-host": "vscode-extension-host";
223
+ }>;
224
+ export declare const runningAccountConsumerSchema: z.ZodObject<{
225
+ kind: z.ZodEnum<{
226
+ "claude-cli": "claude-cli";
227
+ "claude-desktop": "claude-desktop";
228
+ "codex-cli": "codex-cli";
229
+ "codex-app": "codex-app";
230
+ "vscode-extension-host": "vscode-extension-host";
231
+ }>;
232
+ pids: z.ZodArray<z.ZodNumber>;
233
+ switched: z.ZodBoolean;
234
+ reachability: z.ZodString;
235
+ }, z.core.$strip>;
236
+ export declare const switchAccountResultSchema: z.ZodObject<{
237
+ success: z.ZodBoolean;
238
+ error: z.ZodOptional<z.ZodString>;
239
+ warning: z.ZodOptional<z.ZodString>;
240
+ needsLogin: z.ZodOptional<z.ZodBoolean>;
241
+ profileId: z.ZodOptional<z.ZodString>;
242
+ codexHome: z.ZodOptional<z.ZodString>;
243
+ provider: z.ZodEnum<{
244
+ "claude-code": "claude-code";
245
+ codex: "codex";
246
+ }>;
247
+ accountId: z.ZodString;
248
+ previousAccountId: z.ZodNullable<z.ZodString>;
249
+ verified: z.ZodBoolean;
250
+ verification: z.ZodEnum<{
251
+ none: "none";
252
+ store: "store";
253
+ cli: "cli";
254
+ failed: "failed";
255
+ }>;
256
+ health: z.ZodOptional<z.ZodObject<{
257
+ providerId: z.ZodEnum<{
258
+ "claude-code": "claude-code";
259
+ codex: "codex";
260
+ }>;
261
+ accountId: z.ZodString;
262
+ state: z.ZodEnum<{
263
+ unknown: "unknown";
264
+ fresh: "fresh";
265
+ expiring: "expiring";
266
+ expired: "expired";
267
+ missing: "missing";
268
+ }>;
269
+ accessExpiresAt: z.ZodOptional<z.ZodNumber>;
270
+ refreshExpiresAt: z.ZodOptional<z.ZodNumber>;
271
+ refreshExpiryEstimated: z.ZodOptional<z.ZodBoolean>;
272
+ lastRefreshAt: z.ZodOptional<z.ZodNumber>;
273
+ checkedAt: z.ZodNumber;
274
+ isLive: z.ZodBoolean;
275
+ reason: z.ZodOptional<z.ZodString>;
276
+ }, z.core.$strip>>;
277
+ warnings: z.ZodArray<z.ZodString>;
278
+ hints: z.ZodArray<z.ZodString>;
279
+ runningConsumers: z.ZodArray<z.ZodObject<{
280
+ kind: z.ZodEnum<{
281
+ "claude-cli": "claude-cli";
282
+ "claude-desktop": "claude-desktop";
283
+ "codex-cli": "codex-cli";
284
+ "codex-app": "codex-app";
285
+ "vscode-extension-host": "vscode-extension-host";
286
+ }>;
287
+ pids: z.ZodArray<z.ZodNumber>;
288
+ switched: z.ZodBoolean;
289
+ reachability: z.ZodString;
290
+ }, z.core.$strip>>;
291
+ undoToken: z.ZodOptional<z.ZodString>;
292
+ alreadyActive: z.ZodOptional<z.ZodBoolean>;
293
+ email: z.ZodOptional<z.ZodString>;
294
+ }, z.core.$strip>;
295
+ export declare const lastSwitchRecordSchema: z.ZodObject<{
296
+ token: z.ZodString;
297
+ provider: z.ZodEnum<{
298
+ "claude-code": "claude-code";
299
+ codex: "codex";
300
+ }>;
301
+ from: z.ZodNullable<z.ZodString>;
302
+ to: z.ZodString;
303
+ at: z.ZodString;
304
+ }, z.core.$strip>;
305
+ export declare const providerSyncReportSchema: z.ZodObject<{
306
+ registered: z.ZodOptional<z.ZodObject<{
307
+ id: z.ZodString;
308
+ email: z.ZodOptional<z.ZodString>;
309
+ }, z.core.$strip>>;
310
+ folded: z.ZodOptional<z.ZodString>;
311
+ repointed: z.ZodOptional<z.ZodString>;
312
+ merged: z.ZodOptional<z.ZodArray<z.ZodString>>;
313
+ skipped: z.ZodOptional<z.ZodString>;
314
+ warnings: z.ZodArray<z.ZodString>;
315
+ }, z.core.$strip>;
316
+ export declare const syncReportSchema: z.ZodObject<{
317
+ claude: z.ZodObject<{
318
+ registered: z.ZodOptional<z.ZodObject<{
319
+ id: z.ZodString;
320
+ email: z.ZodOptional<z.ZodString>;
321
+ }, z.core.$strip>>;
322
+ folded: z.ZodOptional<z.ZodString>;
323
+ repointed: z.ZodOptional<z.ZodString>;
324
+ merged: z.ZodOptional<z.ZodArray<z.ZodString>>;
325
+ skipped: z.ZodOptional<z.ZodString>;
326
+ warnings: z.ZodArray<z.ZodString>;
327
+ }, z.core.$strip>;
328
+ codex: z.ZodObject<{
329
+ registered: z.ZodOptional<z.ZodObject<{
330
+ id: z.ZodString;
331
+ email: z.ZodOptional<z.ZodString>;
332
+ }, z.core.$strip>>;
333
+ folded: z.ZodOptional<z.ZodString>;
334
+ repointed: z.ZodOptional<z.ZodString>;
335
+ merged: z.ZodOptional<z.ZodArray<z.ZodString>>;
336
+ skipped: z.ZodOptional<z.ZodString>;
337
+ warnings: z.ZodArray<z.ZodString>;
338
+ }, z.core.$strip>;
339
+ ranAt: z.ZodNumber;
340
+ reason: z.ZodEnum<{
341
+ poll: "poll";
342
+ manual: "manual";
343
+ startup: "startup";
344
+ watch: "watch";
345
+ "pre-switch": "pre-switch";
346
+ }>;
347
+ }, z.core.$strip>;
348
+ export declare const accountLaunchEnvSchema: z.ZodObject<{
349
+ provider: z.ZodEnum<{
350
+ "claude-code": "claude-code";
351
+ codex: "codex";
352
+ }>;
353
+ accountId: z.ZodString;
354
+ label: z.ZodOptional<z.ZodString>;
355
+ email: z.ZodOptional<z.ZodString>;
356
+ home: z.ZodString;
357
+ env: z.ZodRecord<z.ZodString, z.ZodString>;
358
+ envUnset: z.ZodArray<z.ZodString>;
359
+ command: z.ZodEnum<{
360
+ codex: "codex";
361
+ claude: "claude";
362
+ }>;
363
+ health: z.ZodObject<{
364
+ providerId: z.ZodEnum<{
365
+ "claude-code": "claude-code";
366
+ codex: "codex";
367
+ }>;
368
+ accountId: z.ZodString;
369
+ state: z.ZodEnum<{
370
+ unknown: "unknown";
371
+ fresh: "fresh";
372
+ expiring: "expiring";
373
+ expired: "expired";
374
+ missing: "missing";
375
+ }>;
376
+ accessExpiresAt: z.ZodOptional<z.ZodNumber>;
377
+ refreshExpiresAt: z.ZodOptional<z.ZodNumber>;
378
+ refreshExpiryEstimated: z.ZodOptional<z.ZodBoolean>;
379
+ lastRefreshAt: z.ZodOptional<z.ZodNumber>;
380
+ checkedAt: z.ZodNumber;
381
+ isLive: z.ZodBoolean;
382
+ reason: z.ZodOptional<z.ZodString>;
383
+ }, z.core.$strip>;
384
+ warnings: z.ZodArray<z.ZodString>;
385
+ error: z.ZodOptional<z.ZodString>;
386
+ }, z.core.$strip>;