@kaitranntt/ccs 5.9.0-dev.7 → 5.10.0-dev.1

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.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 5.9.0-dev.7
1
+ 5.10.0-dev.1
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Account Manager for CLIProxyAPI Multi-Account Support
3
+ *
4
+ * Manages multiple OAuth accounts per provider (Gemini, Codex, etc.).
5
+ * Each provider can have multiple accounts, with one designated as default.
6
+ *
7
+ * Account storage: ~/.ccs/cliproxy/accounts.json
8
+ * Token storage: ~/.ccs/cliproxy/auth/ (flat structure, CLIProxyAPI discovers by type field)
9
+ */
10
+ import { CLIProxyProvider } from './types';
11
+ /** Account information */
12
+ export interface AccountInfo {
13
+ /** Account identifier (email or custom name) */
14
+ id: string;
15
+ /** Email address from OAuth (if available) */
16
+ email?: string;
17
+ /** Provider this account belongs to */
18
+ provider: CLIProxyProvider;
19
+ /** Whether this is the default account for the provider */
20
+ isDefault: boolean;
21
+ /** Token file name in auth directory */
22
+ tokenFile: string;
23
+ /** When account was added */
24
+ createdAt: string;
25
+ /** Last usage time */
26
+ lastUsedAt?: string;
27
+ }
28
+ /** Provider accounts configuration */
29
+ interface ProviderAccounts {
30
+ /** Default account ID for this provider */
31
+ default: string;
32
+ /** Map of account ID to account metadata */
33
+ accounts: Record<string, Omit<AccountInfo, 'id' | 'provider' | 'isDefault'>>;
34
+ }
35
+ /** Accounts registry structure */
36
+ interface AccountsRegistry {
37
+ /** Version for future migrations */
38
+ version: number;
39
+ /** Accounts organized by provider */
40
+ providers: Partial<Record<CLIProxyProvider, ProviderAccounts>>;
41
+ }
42
+ /**
43
+ * Get path to accounts registry file
44
+ */
45
+ export declare function getAccountsRegistryPath(): string;
46
+ /**
47
+ * Load accounts registry
48
+ */
49
+ export declare function loadAccountsRegistry(): AccountsRegistry;
50
+ /**
51
+ * Save accounts registry
52
+ */
53
+ export declare function saveAccountsRegistry(registry: AccountsRegistry): void;
54
+ /**
55
+ * Get all accounts for a provider
56
+ */
57
+ export declare function getProviderAccounts(provider: CLIProxyProvider): AccountInfo[];
58
+ /**
59
+ * Get default account for a provider
60
+ */
61
+ export declare function getDefaultAccount(provider: CLIProxyProvider): AccountInfo | null;
62
+ /**
63
+ * Get specific account by ID
64
+ */
65
+ export declare function getAccount(provider: CLIProxyProvider, accountId: string): AccountInfo | null;
66
+ /**
67
+ * Register a new account
68
+ * Called after successful OAuth to record the account
69
+ */
70
+ export declare function registerAccount(provider: CLIProxyProvider, tokenFile: string, email?: string): AccountInfo;
71
+ /**
72
+ * Set default account for a provider
73
+ */
74
+ export declare function setDefaultAccount(provider: CLIProxyProvider, accountId: string): boolean;
75
+ /**
76
+ * Remove an account
77
+ */
78
+ export declare function removeAccount(provider: CLIProxyProvider, accountId: string): boolean;
79
+ /**
80
+ * Update last used timestamp for an account
81
+ */
82
+ export declare function touchAccount(provider: CLIProxyProvider, accountId: string): void;
83
+ /**
84
+ * Get token file path for an account
85
+ */
86
+ export declare function getAccountTokenPath(provider: CLIProxyProvider, accountId?: string): string | null;
87
+ /**
88
+ * Auto-discover accounts from existing token files
89
+ * Called during migration or first run to populate accounts registry
90
+ */
91
+ export declare function discoverExistingAccounts(): void;
92
+ /**
93
+ * Get summary of all accounts across providers
94
+ */
95
+ export declare function getAllAccountsSummary(): Record<CLIProxyProvider, AccountInfo[]>;
96
+ export {};
97
+ //# sourceMappingURL=account-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-manager.d.ts","sourceRoot":"","sources":["../../src/cliproxy/account-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C,0BAA0B;AAC1B,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,2DAA2D;IAC3D,SAAS,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,sCAAsC;AACtC,UAAU,gBAAgB;IACxB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC;CAC9E;AAED,kCAAkC;AAClC,UAAU,gBAAgB;IACxB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC,CAAC;CAChE;AAQD;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,gBAAgB,CAiBvD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAWrE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,WAAW,EAAE,CAc7E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,WAAW,GAAG,IAAI,CAGhF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAG5F;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,WAAW,CA4Cb;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAWxF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAgCpF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAQhF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQjG;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CA6E/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAY/E"}
@@ -0,0 +1,314 @@
1
+ "use strict";
2
+ /**
3
+ * Account Manager for CLIProxyAPI Multi-Account Support
4
+ *
5
+ * Manages multiple OAuth accounts per provider (Gemini, Codex, etc.).
6
+ * Each provider can have multiple accounts, with one designated as default.
7
+ *
8
+ * Account storage: ~/.ccs/cliproxy/accounts.json
9
+ * Token storage: ~/.ccs/cliproxy/auth/ (flat structure, CLIProxyAPI discovers by type field)
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.getAllAccountsSummary = exports.discoverExistingAccounts = exports.getAccountTokenPath = exports.touchAccount = exports.removeAccount = exports.setDefaultAccount = exports.registerAccount = exports.getAccount = exports.getDefaultAccount = exports.getProviderAccounts = exports.saveAccountsRegistry = exports.loadAccountsRegistry = exports.getAccountsRegistryPath = void 0;
36
+ const fs = __importStar(require("fs"));
37
+ const path = __importStar(require("path"));
38
+ const config_generator_1 = require("./config-generator");
39
+ /** Default registry structure */
40
+ const DEFAULT_REGISTRY = {
41
+ version: 1,
42
+ providers: {},
43
+ };
44
+ /**
45
+ * Get path to accounts registry file
46
+ */
47
+ function getAccountsRegistryPath() {
48
+ return path.join((0, config_generator_1.getCliproxyDir)(), 'accounts.json');
49
+ }
50
+ exports.getAccountsRegistryPath = getAccountsRegistryPath;
51
+ /**
52
+ * Load accounts registry
53
+ */
54
+ function loadAccountsRegistry() {
55
+ const registryPath = getAccountsRegistryPath();
56
+ if (!fs.existsSync(registryPath)) {
57
+ return { ...DEFAULT_REGISTRY };
58
+ }
59
+ try {
60
+ const content = fs.readFileSync(registryPath, 'utf-8');
61
+ const data = JSON.parse(content);
62
+ return {
63
+ version: data.version || 1,
64
+ providers: data.providers || {},
65
+ };
66
+ }
67
+ catch {
68
+ return { ...DEFAULT_REGISTRY };
69
+ }
70
+ }
71
+ exports.loadAccountsRegistry = loadAccountsRegistry;
72
+ /**
73
+ * Save accounts registry
74
+ */
75
+ function saveAccountsRegistry(registry) {
76
+ const registryPath = getAccountsRegistryPath();
77
+ const dir = path.dirname(registryPath);
78
+ if (!fs.existsSync(dir)) {
79
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
80
+ }
81
+ fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2) + '\n', {
82
+ mode: 0o600,
83
+ });
84
+ }
85
+ exports.saveAccountsRegistry = saveAccountsRegistry;
86
+ /**
87
+ * Get all accounts for a provider
88
+ */
89
+ function getProviderAccounts(provider) {
90
+ const registry = loadAccountsRegistry();
91
+ const providerAccounts = registry.providers[provider];
92
+ if (!providerAccounts) {
93
+ return [];
94
+ }
95
+ return Object.entries(providerAccounts.accounts).map(([id, meta]) => ({
96
+ id,
97
+ provider,
98
+ isDefault: id === providerAccounts.default,
99
+ ...meta,
100
+ }));
101
+ }
102
+ exports.getProviderAccounts = getProviderAccounts;
103
+ /**
104
+ * Get default account for a provider
105
+ */
106
+ function getDefaultAccount(provider) {
107
+ const accounts = getProviderAccounts(provider);
108
+ return accounts.find((a) => a.isDefault) || accounts[0] || null;
109
+ }
110
+ exports.getDefaultAccount = getDefaultAccount;
111
+ /**
112
+ * Get specific account by ID
113
+ */
114
+ function getAccount(provider, accountId) {
115
+ const accounts = getProviderAccounts(provider);
116
+ return accounts.find((a) => a.id === accountId) || null;
117
+ }
118
+ exports.getAccount = getAccount;
119
+ /**
120
+ * Register a new account
121
+ * Called after successful OAuth to record the account
122
+ */
123
+ function registerAccount(provider, tokenFile, email) {
124
+ const registry = loadAccountsRegistry();
125
+ // Initialize provider section if needed
126
+ if (!registry.providers[provider]) {
127
+ registry.providers[provider] = {
128
+ default: 'default',
129
+ accounts: {},
130
+ };
131
+ }
132
+ const providerAccounts = registry.providers[provider];
133
+ if (!providerAccounts) {
134
+ throw new Error('Failed to initialize provider accounts');
135
+ }
136
+ // Determine account ID
137
+ const accountId = email || 'default';
138
+ const isFirstAccount = Object.keys(providerAccounts.accounts).length === 0;
139
+ // Create or update account
140
+ providerAccounts.accounts[accountId] = {
141
+ email,
142
+ tokenFile,
143
+ createdAt: new Date().toISOString(),
144
+ lastUsedAt: new Date().toISOString(),
145
+ };
146
+ // Set as default if first account
147
+ if (isFirstAccount) {
148
+ providerAccounts.default = accountId;
149
+ }
150
+ saveAccountsRegistry(registry);
151
+ return {
152
+ id: accountId,
153
+ provider,
154
+ isDefault: accountId === providerAccounts.default,
155
+ email,
156
+ tokenFile,
157
+ createdAt: providerAccounts.accounts[accountId].createdAt,
158
+ lastUsedAt: providerAccounts.accounts[accountId].lastUsedAt,
159
+ };
160
+ }
161
+ exports.registerAccount = registerAccount;
162
+ /**
163
+ * Set default account for a provider
164
+ */
165
+ function setDefaultAccount(provider, accountId) {
166
+ const registry = loadAccountsRegistry();
167
+ const providerAccounts = registry.providers[provider];
168
+ if (!providerAccounts || !providerAccounts.accounts[accountId]) {
169
+ return false;
170
+ }
171
+ providerAccounts.default = accountId;
172
+ saveAccountsRegistry(registry);
173
+ return true;
174
+ }
175
+ exports.setDefaultAccount = setDefaultAccount;
176
+ /**
177
+ * Remove an account
178
+ */
179
+ function removeAccount(provider, accountId) {
180
+ const registry = loadAccountsRegistry();
181
+ const providerAccounts = registry.providers[provider];
182
+ if (!providerAccounts || !providerAccounts.accounts[accountId]) {
183
+ return false;
184
+ }
185
+ // Get token file to delete
186
+ const tokenFile = providerAccounts.accounts[accountId].tokenFile;
187
+ const tokenPath = path.join((0, config_generator_1.getAuthDir)(), tokenFile);
188
+ // Delete token file
189
+ if (fs.existsSync(tokenPath)) {
190
+ try {
191
+ fs.unlinkSync(tokenPath);
192
+ }
193
+ catch {
194
+ // Ignore deletion errors
195
+ }
196
+ }
197
+ // Remove from registry
198
+ delete providerAccounts.accounts[accountId];
199
+ // Update default if needed
200
+ const remainingAccounts = Object.keys(providerAccounts.accounts);
201
+ if (providerAccounts.default === accountId && remainingAccounts.length > 0) {
202
+ providerAccounts.default = remainingAccounts[0];
203
+ }
204
+ saveAccountsRegistry(registry);
205
+ return true;
206
+ }
207
+ exports.removeAccount = removeAccount;
208
+ /**
209
+ * Update last used timestamp for an account
210
+ */
211
+ function touchAccount(provider, accountId) {
212
+ const registry = loadAccountsRegistry();
213
+ const providerAccounts = registry.providers[provider];
214
+ if (providerAccounts?.accounts[accountId]) {
215
+ providerAccounts.accounts[accountId].lastUsedAt = new Date().toISOString();
216
+ saveAccountsRegistry(registry);
217
+ }
218
+ }
219
+ exports.touchAccount = touchAccount;
220
+ /**
221
+ * Get token file path for an account
222
+ */
223
+ function getAccountTokenPath(provider, accountId) {
224
+ const account = accountId ? getAccount(provider, accountId) : getDefaultAccount(provider);
225
+ if (!account) {
226
+ return null;
227
+ }
228
+ return path.join((0, config_generator_1.getAuthDir)(), account.tokenFile);
229
+ }
230
+ exports.getAccountTokenPath = getAccountTokenPath;
231
+ /**
232
+ * Auto-discover accounts from existing token files
233
+ * Called during migration or first run to populate accounts registry
234
+ */
235
+ function discoverExistingAccounts() {
236
+ const authDir = (0, config_generator_1.getAuthDir)();
237
+ if (!fs.existsSync(authDir)) {
238
+ return;
239
+ }
240
+ const registry = loadAccountsRegistry();
241
+ const files = fs.readdirSync(authDir);
242
+ for (const file of files) {
243
+ if (!file.endsWith('.json'))
244
+ continue;
245
+ const filePath = path.join(authDir, file);
246
+ try {
247
+ const content = fs.readFileSync(filePath, 'utf-8');
248
+ const data = JSON.parse(content);
249
+ // Skip if no type field
250
+ if (!data.type)
251
+ continue;
252
+ // Map token type values to internal provider names
253
+ // CLIProxyAPI uses different type values in tokens (e.g., "antigravity" vs "agy")
254
+ const typeToProvider = {
255
+ gemini: 'gemini',
256
+ antigravity: 'agy',
257
+ codex: 'codex',
258
+ qwen: 'qwen',
259
+ iflow: 'iflow',
260
+ };
261
+ const typeValue = data.type.toLowerCase();
262
+ const provider = typeToProvider[typeValue];
263
+ // Skip if unknown provider type
264
+ if (!provider) {
265
+ continue;
266
+ }
267
+ // Extract email if available
268
+ const email = data.email || undefined;
269
+ const accountId = email || 'default';
270
+ // Initialize provider section if needed
271
+ if (!registry.providers[provider]) {
272
+ registry.providers[provider] = {
273
+ default: accountId,
274
+ accounts: {},
275
+ };
276
+ }
277
+ const providerAccounts = registry.providers[provider];
278
+ if (!providerAccounts)
279
+ continue;
280
+ // Skip if account already registered
281
+ if (providerAccounts.accounts[accountId]) {
282
+ continue;
283
+ }
284
+ // Get file stats for creation time
285
+ const stats = fs.statSync(filePath);
286
+ // Register account
287
+ providerAccounts.accounts[accountId] = {
288
+ email,
289
+ tokenFile: file,
290
+ createdAt: stats.birthtime?.toISOString() || new Date().toISOString(),
291
+ lastUsedAt: stats.mtime?.toISOString(),
292
+ };
293
+ }
294
+ catch {
295
+ // Skip invalid files
296
+ continue;
297
+ }
298
+ }
299
+ saveAccountsRegistry(registry);
300
+ }
301
+ exports.discoverExistingAccounts = discoverExistingAccounts;
302
+ /**
303
+ * Get summary of all accounts across providers
304
+ */
305
+ function getAllAccountsSummary() {
306
+ const providers = ['gemini', 'codex', 'agy', 'qwen', 'iflow'];
307
+ const summary = {};
308
+ for (const provider of providers) {
309
+ summary[provider] = getProviderAccounts(provider);
310
+ }
311
+ return summary;
312
+ }
313
+ exports.getAllAccountsSummary = getAllAccountsSummary;
314
+ //# sourceMappingURL=account-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-manager.js","sourceRoot":"","sources":["../../src/cliproxy/account-manager.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@
12
12
  * Each provider has its own directory to avoid conflicts.
13
13
  */
14
14
  import { CLIProxyProvider } from './types';
15
+ import { AccountInfo } from './account-manager';
15
16
  /**
16
17
  * Auth status for a provider
17
18
  */
@@ -26,6 +27,10 @@ export interface AuthStatus {
26
27
  tokenFiles: string[];
27
28
  /** When last authenticated (if known) */
28
29
  lastAuth?: Date;
30
+ /** Accounts registered for this provider (multi-account support) */
31
+ accounts: AccountInfo[];
32
+ /** Default account ID */
33
+ defaultAccount?: string;
29
34
  }
30
35
  /**
31
36
  * OAuth config for each provider
@@ -76,19 +81,32 @@ export declare function clearAuth(provider: CLIProxyProvider): boolean;
76
81
  /**
77
82
  * Trigger OAuth flow for provider
78
83
  * Auto-detects headless environment and uses --no-browser flag accordingly
84
+ * @param provider - The CLIProxy provider to authenticate
85
+ * @param options - OAuth options
86
+ * @returns Account info if successful, null otherwise
79
87
  */
80
88
  export declare function triggerOAuth(provider: CLIProxyProvider, options?: {
81
89
  verbose?: boolean;
82
90
  headless?: boolean;
83
- }): Promise<boolean>;
91
+ account?: string;
92
+ }): Promise<AccountInfo | null>;
84
93
  /**
85
94
  * Ensure provider is authenticated
86
95
  * Triggers OAuth flow if not authenticated
96
+ * @param provider - The CLIProxy provider
97
+ * @param options - Auth options including optional account
98
+ * @returns true if authenticated, false otherwise
87
99
  */
88
100
  export declare function ensureAuth(provider: CLIProxyProvider, options?: {
89
101
  verbose?: boolean;
90
102
  headless?: boolean;
103
+ account?: string;
91
104
  }): Promise<boolean>;
105
+ /**
106
+ * Initialize accounts registry from existing tokens
107
+ * Should be called on startup to populate accounts from existing token files
108
+ */
109
+ export declare function initializeAccounts(): void;
92
110
  /**
93
111
  * Display auth status for all providers
94
112
  */
@@ -1 +1 @@
1
- {"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/cliproxy/auth-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAsF3C;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,oBAAoB;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,oCAAoC;IACpC,aAAa,EAAE,OAAO,CAAC;IACvB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,UAAU,mBAAmB;IAC3B,0BAA0B;IAC1B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA4CD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,CAM9E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAEtE;AA2CD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAkCnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,gBAAgB,GAAG,UAAU,CA8CpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,EAAE,CAG/C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAkC7D;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACtD,OAAO,CAAC,OAAO,CAAC,CA6KlB;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACtD,OAAO,CAAC,OAAO,CAAC,CAclB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAkBxC"}
1
+ {"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/cliproxy/auth-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EACL,WAAW,EAMZ,MAAM,mBAAmB,CAAC;AAsF3B;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,oBAAoB;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,oCAAoC;IACpC,aAAa,EAAE,OAAO,CAAC;IACvB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,oEAAoE;IACpE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,yBAAyB;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,UAAU,mBAAmB;IAC3B,0BAA0B;IAC1B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA4CD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,CAM9E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAEtE;AA2CD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAkCnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,gBAAgB,GAAG,UAAU,CAoDpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,EAAE,CAG/C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAkC7D;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAgL7B;AA8CD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAkBxC"}
@@ -36,13 +36,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
36
36
  return result;
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.displayAuthStatus = exports.ensureAuth = exports.triggerOAuth = exports.clearAuth = exports.getAllAuthStatus = exports.getAuthStatus = exports.isAuthenticated = exports.getProviderTokenDir = exports.getOAuthConfig = void 0;
39
+ exports.displayAuthStatus = exports.initializeAccounts = exports.ensureAuth = exports.triggerOAuth = exports.clearAuth = exports.getAllAuthStatus = exports.getAuthStatus = exports.isAuthenticated = exports.getProviderTokenDir = exports.getOAuthConfig = void 0;
40
40
  const child_process_1 = require("child_process");
41
41
  const fs = __importStar(require("fs"));
42
42
  const path = __importStar(require("path"));
43
43
  const progress_indicator_1 = require("../utils/progress-indicator");
44
44
  const binary_manager_1 = require("./binary-manager");
45
45
  const config_generator_1 = require("./config-generator");
46
+ const account_manager_1 = require("./account-manager");
46
47
  /**
47
48
  * OAuth callback ports used by CLIProxyAPI (hardcoded in binary)
48
49
  * See: https://github.com/router-for-me/CLIProxyAPI/tree/main/internal/auth
@@ -297,12 +298,17 @@ function getAuthStatus(provider) {
297
298
  }
298
299
  }
299
300
  }
301
+ // Get registered accounts for multi-account support
302
+ const accounts = (0, account_manager_1.getProviderAccounts)(provider);
303
+ const defaultAccount = (0, account_manager_1.getDefaultAccount)(provider);
300
304
  return {
301
305
  provider,
302
306
  authenticated: tokenFiles.length > 0,
303
307
  tokenDir,
304
308
  tokenFiles,
305
309
  lastAuth,
310
+ accounts,
311
+ defaultAccount: defaultAccount?.id,
306
312
  };
307
313
  }
308
314
  exports.getAuthStatus = getAuthStatus;
@@ -352,6 +358,9 @@ exports.clearAuth = clearAuth;
352
358
  /**
353
359
  * Trigger OAuth flow for provider
354
360
  * Auto-detects headless environment and uses --no-browser flag accordingly
361
+ * @param provider - The CLIProxy provider to authenticate
362
+ * @param options - OAuth options
363
+ * @returns Account info if successful, null otherwise
355
364
  */
356
365
  async function triggerOAuth(provider, options = {}) {
357
366
  const oauthConfig = getOAuthConfig(provider);
@@ -465,7 +474,7 @@ async function triggerOAuth(provider, options = {}) {
465
474
  console.error(' - Make sure a browser is available');
466
475
  console.error(' - Try running with --verbose for details');
467
476
  }
468
- resolve(false);
477
+ resolve(null);
469
478
  }, timeoutMs);
470
479
  authProcess.on('exit', (code) => {
471
480
  clearTimeout(timeout);
@@ -475,7 +484,9 @@ async function triggerOAuth(provider, options = {}) {
475
484
  if (!headless)
476
485
  spinner.succeed(`Authenticated with ${oauthConfig.displayName}`);
477
486
  console.log('[OK] Authentication successful');
478
- resolve(true);
487
+ // Register the account in accounts registry
488
+ const account = registerAccountFromToken(provider, tokenDir);
489
+ resolve(account);
479
490
  }
480
491
  else {
481
492
  if (!headless)
@@ -491,7 +502,7 @@ async function triggerOAuth(provider, options = {}) {
491
502
  console.error(' The OAuth flow may have been cancelled or callback port was in use');
492
503
  console.error(` Try: pkill -f cli-proxy-api && ccs ${provider} --auth`);
493
504
  }
494
- resolve(false);
505
+ resolve(null);
495
506
  }
496
507
  }
497
508
  else {
@@ -506,7 +517,7 @@ async function triggerOAuth(provider, options = {}) {
506
517
  console.error('');
507
518
  console.error('[i] No OAuth URL was displayed. Try with --verbose for details.');
508
519
  }
509
- resolve(false);
520
+ resolve(null);
510
521
  }
511
522
  });
512
523
  authProcess.on('error', (error) => {
@@ -514,14 +525,53 @@ async function triggerOAuth(provider, options = {}) {
514
525
  if (!headless)
515
526
  spinner.fail('Authentication error');
516
527
  console.error(`[X] Failed to start auth process: ${error.message}`);
517
- resolve(false);
528
+ resolve(null);
518
529
  });
519
530
  });
520
531
  }
521
532
  exports.triggerOAuth = triggerOAuth;
533
+ /**
534
+ * Register account from newly created token file
535
+ * Scans auth directory for new token and extracts email
536
+ */
537
+ function registerAccountFromToken(provider, tokenDir) {
538
+ try {
539
+ const files = fs.readdirSync(tokenDir);
540
+ const jsonFiles = files.filter((f) => f.endsWith('.json'));
541
+ // Find newest token file for this provider
542
+ let newestFile = null;
543
+ let newestMtime = 0;
544
+ for (const file of jsonFiles) {
545
+ const filePath = path.join(tokenDir, file);
546
+ if (!isTokenFileForProvider(filePath, provider))
547
+ continue;
548
+ const stats = fs.statSync(filePath);
549
+ if (stats.mtimeMs > newestMtime) {
550
+ newestMtime = stats.mtimeMs;
551
+ newestFile = file;
552
+ }
553
+ }
554
+ if (!newestFile) {
555
+ return null;
556
+ }
557
+ // Read token to extract email
558
+ const tokenPath = path.join(tokenDir, newestFile);
559
+ const content = fs.readFileSync(tokenPath, 'utf-8');
560
+ const data = JSON.parse(content);
561
+ const email = data.email || undefined;
562
+ // Register the account
563
+ return (0, account_manager_1.registerAccount)(provider, newestFile, email);
564
+ }
565
+ catch {
566
+ return null;
567
+ }
568
+ }
522
569
  /**
523
570
  * Ensure provider is authenticated
524
571
  * Triggers OAuth flow if not authenticated
572
+ * @param provider - The CLIProxy provider
573
+ * @param options - Auth options including optional account
574
+ * @returns true if authenticated, false otherwise
525
575
  */
526
576
  async function ensureAuth(provider, options = {}) {
527
577
  // Check if already authenticated
@@ -529,14 +579,28 @@ async function ensureAuth(provider, options = {}) {
529
579
  if (options.verbose) {
530
580
  console.error(`[auth] ${provider} already authenticated`);
531
581
  }
582
+ // Touch the account to update last used time
583
+ const defaultAccount = (0, account_manager_1.getDefaultAccount)(provider);
584
+ if (defaultAccount) {
585
+ (0, account_manager_1.touchAccount)(provider, options.account || defaultAccount.id);
586
+ }
532
587
  return true;
533
588
  }
534
589
  // Not authenticated - trigger OAuth
535
590
  const oauthConfig = getOAuthConfig(provider);
536
591
  console.log(`[i] ${oauthConfig.displayName} authentication required`);
537
- return triggerOAuth(provider, options);
592
+ const account = await triggerOAuth(provider, options);
593
+ return account !== null;
538
594
  }
539
595
  exports.ensureAuth = ensureAuth;
596
+ /**
597
+ * Initialize accounts registry from existing tokens
598
+ * Should be called on startup to populate accounts from existing token files
599
+ */
600
+ function initializeAccounts() {
601
+ (0, account_manager_1.discoverExistingAccounts)();
602
+ }
603
+ exports.initializeAccounts = initializeAccounts;
540
604
  /**
541
605
  * Display auth status for all providers
542
606
  */