@kaitranntt/ccs 7.36.0 → 7.37.0-dev.2

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 (172) hide show
  1. package/dist/auth/commands/show-command.d.ts.map +1 -1
  2. package/dist/auth/commands/show-command.js +7 -2
  3. package/dist/auth/commands/show-command.js.map +1 -1
  4. package/dist/cliproxy/account-manager.d.ts +5 -207
  5. package/dist/cliproxy/account-manager.d.ts.map +1 -1
  6. package/dist/cliproxy/account-manager.js +35 -795
  7. package/dist/cliproxy/account-manager.js.map +1 -1
  8. package/dist/cliproxy/accounts/bulk-ops.d.ts +22 -0
  9. package/dist/cliproxy/accounts/bulk-ops.d.ts.map +1 -0
  10. package/dist/cliproxy/accounts/bulk-ops.js +88 -0
  11. package/dist/cliproxy/accounts/bulk-ops.js.map +1 -0
  12. package/dist/cliproxy/accounts/index.d.ts +19 -0
  13. package/dist/cliproxy/accounts/index.d.ts.map +1 -0
  14. package/dist/cliproxy/accounts/index.js +54 -0
  15. package/dist/cliproxy/accounts/index.js.map +1 -0
  16. package/dist/cliproxy/accounts/query.d.ts +36 -0
  17. package/dist/cliproxy/accounts/query.d.ts.map +1 -0
  18. package/dist/cliproxy/accounts/query.js +94 -0
  19. package/dist/cliproxy/accounts/query.js.map +1 -0
  20. package/dist/cliproxy/accounts/registry.d.ts +74 -0
  21. package/dist/cliproxy/accounts/registry.d.ts.map +1 -0
  22. package/dist/cliproxy/accounts/registry.js +510 -0
  23. package/dist/cliproxy/accounts/registry.js.map +1 -0
  24. package/dist/cliproxy/accounts/token-file-ops.d.ts +64 -0
  25. package/dist/cliproxy/accounts/token-file-ops.d.ts.map +1 -0
  26. package/dist/cliproxy/accounts/token-file-ops.js +206 -0
  27. package/dist/cliproxy/accounts/token-file-ops.js.map +1 -0
  28. package/dist/cliproxy/accounts/types.d.ts +66 -0
  29. package/dist/cliproxy/accounts/types.d.ts.map +1 -0
  30. package/dist/cliproxy/accounts/types.js +12 -0
  31. package/dist/cliproxy/accounts/types.js.map +1 -0
  32. package/dist/cliproxy/auth/auth-types.d.ts +2 -0
  33. package/dist/cliproxy/auth/auth-types.d.ts.map +1 -1
  34. package/dist/cliproxy/auth/oauth-handler.d.ts.map +1 -1
  35. package/dist/cliproxy/auth/oauth-handler.js +60 -0
  36. package/dist/cliproxy/auth/oauth-handler.js.map +1 -1
  37. package/dist/cliproxy/auth/token-expiry-checker.d.ts.map +1 -1
  38. package/dist/cliproxy/auth/token-expiry-checker.js +5 -1
  39. package/dist/cliproxy/auth/token-expiry-checker.js.map +1 -1
  40. package/dist/cliproxy/binary/downloader.d.ts +39 -0
  41. package/dist/cliproxy/binary/downloader.d.ts.map +1 -1
  42. package/dist/cliproxy/binary/downloader.js +97 -5
  43. package/dist/cliproxy/binary/downloader.js.map +1 -1
  44. package/dist/cliproxy/cliproxy-executor.d.ts +11 -28
  45. package/dist/cliproxy/cliproxy-executor.d.ts.map +1 -1
  46. package/dist/cliproxy/cliproxy-executor.js +20 -1018
  47. package/dist/cliproxy/cliproxy-executor.js.map +1 -1
  48. package/dist/cliproxy/config/env-builder.d.ts +60 -0
  49. package/dist/cliproxy/config/env-builder.d.ts.map +1 -0
  50. package/dist/cliproxy/config/env-builder.js +311 -0
  51. package/dist/cliproxy/config/env-builder.js.map +1 -0
  52. package/dist/cliproxy/config/generator.d.ts +63 -0
  53. package/dist/cliproxy/config/generator.d.ts.map +1 -0
  54. package/dist/cliproxy/config/generator.js +336 -0
  55. package/dist/cliproxy/config/generator.js.map +1 -0
  56. package/dist/cliproxy/config/index.d.ts +10 -0
  57. package/dist/cliproxy/config/index.d.ts.map +1 -0
  58. package/dist/cliproxy/config/index.js +26 -0
  59. package/dist/cliproxy/config/index.js.map +1 -0
  60. package/dist/cliproxy/config/path-resolver.d.ts +47 -0
  61. package/dist/cliproxy/config/path-resolver.d.ts.map +1 -0
  62. package/dist/cliproxy/config/path-resolver.js +104 -0
  63. package/dist/cliproxy/config/path-resolver.js.map +1 -0
  64. package/dist/cliproxy/config/port-manager.d.ts +33 -0
  65. package/dist/cliproxy/config/port-manager.d.ts.map +1 -0
  66. package/dist/cliproxy/config/port-manager.js +68 -0
  67. package/dist/cliproxy/config/port-manager.js.map +1 -0
  68. package/dist/cliproxy/config/thinking-config.d.ts +39 -0
  69. package/dist/cliproxy/config/thinking-config.d.ts.map +1 -0
  70. package/dist/cliproxy/config/thinking-config.js +143 -0
  71. package/dist/cliproxy/config/thinking-config.js.map +1 -0
  72. package/dist/cliproxy/config-generator.d.ts +9 -221
  73. package/dist/cliproxy/config-generator.d.ts.map +1 -1
  74. package/dist/cliproxy/config-generator.js +12 -856
  75. package/dist/cliproxy/config-generator.js.map +1 -1
  76. package/dist/cliproxy/executor/env-resolver.d.ts +45 -0
  77. package/dist/cliproxy/executor/env-resolver.d.ts.map +1 -0
  78. package/dist/cliproxy/executor/env-resolver.js +106 -0
  79. package/dist/cliproxy/executor/env-resolver.js.map +1 -0
  80. package/dist/cliproxy/executor/index.d.ts +24 -0
  81. package/dist/cliproxy/executor/index.d.ts.map +1 -0
  82. package/dist/cliproxy/executor/index.js +669 -0
  83. package/dist/cliproxy/executor/index.js.map +1 -0
  84. package/dist/cliproxy/executor/lifecycle-manager.d.ts +33 -0
  85. package/dist/cliproxy/executor/lifecycle-manager.d.ts.map +1 -0
  86. package/dist/cliproxy/executor/lifecycle-manager.js +161 -0
  87. package/dist/cliproxy/executor/lifecycle-manager.js.map +1 -0
  88. package/dist/cliproxy/executor/retry-handler.d.ts +27 -0
  89. package/dist/cliproxy/executor/retry-handler.d.ts.map +1 -0
  90. package/dist/cliproxy/executor/retry-handler.js +109 -0
  91. package/dist/cliproxy/executor/retry-handler.js.map +1 -0
  92. package/dist/cliproxy/executor/session-bridge.d.ts +30 -0
  93. package/dist/cliproxy/executor/session-bridge.d.ts.map +1 -0
  94. package/dist/cliproxy/executor/session-bridge.js +232 -0
  95. package/dist/cliproxy/executor/session-bridge.js.map +1 -0
  96. package/dist/cliproxy/index.d.ts +2 -0
  97. package/dist/cliproxy/index.d.ts.map +1 -1
  98. package/dist/cliproxy/index.js +4 -1
  99. package/dist/cliproxy/index.js.map +1 -1
  100. package/dist/cliproxy/schema-sanitizer.d.ts +45 -0
  101. package/dist/cliproxy/schema-sanitizer.d.ts.map +1 -0
  102. package/dist/cliproxy/schema-sanitizer.js +283 -0
  103. package/dist/cliproxy/schema-sanitizer.js.map +1 -0
  104. package/dist/cliproxy/tool-sanitization-proxy.d.ts +3 -2
  105. package/dist/cliproxy/tool-sanitization-proxy.d.ts.map +1 -1
  106. package/dist/cliproxy/tool-sanitization-proxy.js +14 -3
  107. package/dist/cliproxy/tool-sanitization-proxy.js.map +1 -1
  108. package/dist/commands/cliproxy/auth-subcommand.d.ts +10 -0
  109. package/dist/commands/cliproxy/auth-subcommand.d.ts.map +1 -0
  110. package/dist/commands/cliproxy/auth-subcommand.js +55 -0
  111. package/dist/commands/cliproxy/auth-subcommand.js.map +1 -0
  112. package/dist/commands/cliproxy/help-subcommand.d.ts +8 -0
  113. package/dist/commands/cliproxy/help-subcommand.d.ts.map +1 -0
  114. package/dist/commands/cliproxy/help-subcommand.js +87 -0
  115. package/dist/commands/cliproxy/help-subcommand.js.map +1 -0
  116. package/dist/commands/cliproxy/index.d.ts +11 -0
  117. package/dist/commands/cliproxy/index.d.ts.map +1 -0
  118. package/dist/commands/cliproxy/index.js +196 -0
  119. package/dist/commands/cliproxy/index.js.map +1 -0
  120. package/dist/commands/cliproxy/install-subcommand.d.ts +14 -0
  121. package/dist/commands/cliproxy/install-subcommand.d.ts.map +1 -0
  122. package/dist/commands/cliproxy/install-subcommand.js +112 -0
  123. package/dist/commands/cliproxy/install-subcommand.js.map +1 -0
  124. package/dist/commands/cliproxy/proxy-lifecycle-subcommand.d.ts +10 -0
  125. package/dist/commands/cliproxy/proxy-lifecycle-subcommand.d.ts.map +1 -0
  126. package/dist/commands/cliproxy/proxy-lifecycle-subcommand.js +54 -0
  127. package/dist/commands/cliproxy/proxy-lifecycle-subcommand.js.map +1 -0
  128. package/dist/commands/cliproxy/quota-subcommand.d.ts +16 -0
  129. package/dist/commands/cliproxy/quota-subcommand.d.ts.map +1 -0
  130. package/dist/commands/cliproxy/quota-subcommand.js +383 -0
  131. package/dist/commands/cliproxy/quota-subcommand.js.map +1 -0
  132. package/dist/commands/cliproxy/variant-subcommand.d.ts +11 -0
  133. package/dist/commands/cliproxy/variant-subcommand.d.ts.map +1 -0
  134. package/dist/commands/cliproxy/variant-subcommand.js +292 -0
  135. package/dist/commands/cliproxy/variant-subcommand.js.map +1 -0
  136. package/dist/commands/cliproxy-command.d.ts +4 -15
  137. package/dist/commands/cliproxy-command.d.ts.map +1 -1
  138. package/dist/commands/cliproxy-command.js +5 -1090
  139. package/dist/commands/cliproxy-command.js.map +1 -1
  140. package/dist/commands/help-command.d.ts.map +1 -1
  141. package/dist/commands/help-command.js +1 -0
  142. package/dist/commands/help-command.js.map +1 -1
  143. package/dist/ui/assets/{accounts-BBpXWvSH.js → accounts-D0KU1a-4.js} +1 -1
  144. package/dist/ui/assets/{alert-dialog-vAfEWTTx.js → alert-dialog-BNRDV_Kh.js} +1 -1
  145. package/dist/ui/assets/{api-DZ5UMkSM.js → api-ClkFu9LY.js} +1 -1
  146. package/dist/ui/assets/{auth-section-CaMKkkvu.js → auth-section-CNhNN1Jp.js} +1 -1
  147. package/dist/ui/assets/{backups-section-WHuXhsOd.js → backups-section-CZ721HIu.js} +1 -1
  148. package/dist/ui/assets/cliproxy-DeGucfVg.js +3 -0
  149. package/dist/ui/assets/{cliproxy-control-panel-RfbZRHh8.js → cliproxy-control-panel-T9i_Ldh0.js} +1 -1
  150. package/dist/ui/assets/{confirm-dialog-DflEMDZr.js → confirm-dialog-Cy1__gRc.js} +1 -1
  151. package/dist/ui/assets/{copilot-qDXWR1GO.js → copilot-Cdqs2Jbh.js} +3 -3
  152. package/dist/ui/assets/{globalenv-section-f_BGs9T6.js → globalenv-section-BEKtYN6I.js} +1 -1
  153. package/dist/ui/assets/{health-C8g76Gw9.js → health-BaHazGgS.js} +1 -1
  154. package/dist/ui/assets/{index-DFnuP2Pl.js → index-BTBpI5th.js} +1 -1
  155. package/dist/ui/assets/index-BZn6kF0u.js +1 -0
  156. package/dist/ui/assets/{index-lueAmZoj.js → index-C2MS84sf.js} +1 -1
  157. package/dist/ui/assets/{index-BgcyV-uV.js → index-CiULLjNI.js} +8 -8
  158. package/dist/ui/assets/{index-mYPtkHHX.js → index-PjscK1jS.js} +1 -1
  159. package/dist/ui/assets/{proxy-status-widget-B4pFTeam.js → proxy-status-widget-BY6Lnr80.js} +1 -1
  160. package/dist/ui/assets/{shared-DBOiFFnj.js → shared-dZGNvBe9.js} +1 -1
  161. package/dist/ui/assets/{switch-DtGK4jP3.js → switch-BCFbehJz.js} +1 -1
  162. package/dist/ui/index.html +1 -1
  163. package/dist/utils/shell-executor.d.ts +5 -2
  164. package/dist/utils/shell-executor.d.ts.map +1 -1
  165. package/dist/utils/shell-executor.js +17 -19
  166. package/dist/utils/shell-executor.js.map +1 -1
  167. package/dist/web-server/routes/account-routes.d.ts.map +1 -1
  168. package/dist/web-server/routes/account-routes.js +14 -2
  169. package/dist/web-server/routes/account-routes.js.map +1 -1
  170. package/package.json +3 -1
  171. package/dist/ui/assets/cliproxy-BJ4pL9JG.js +0 -3
  172. package/dist/ui/assets/index-DZpRED6o.js +0 -1
@@ -0,0 +1,510 @@
1
+ "use strict";
2
+ /**
3
+ * Account registry CRUD operations
4
+ * Handles loading, saving, and syncing the accounts.json file
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || function (mod) {
23
+ if (mod && mod.__esModule) return mod;
24
+ var result = {};
25
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
26
+ __setModuleDefault(result, mod);
27
+ return result;
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.discoverExistingAccounts = exports.setAccountTier = exports.touchAccount = exports.renameAccount = exports.removeAccount = exports.resumeAccount = exports.pauseAccount = exports.setDefaultAccount = exports.registerAccount = exports.syncRegistryWithTokenFiles = exports.saveAccountsRegistry = exports.loadAccountsRegistry = void 0;
31
+ const fs = __importStar(require("fs"));
32
+ const path = __importStar(require("path"));
33
+ const auth_types_1 = require("../auth/auth-types");
34
+ const config_generator_1 = require("../config-generator");
35
+ const types_1 = require("./types");
36
+ const token_file_ops_1 = require("./token-file-ops");
37
+ /** Default registry structure */
38
+ const DEFAULT_REGISTRY = {
39
+ version: 1,
40
+ providers: {},
41
+ };
42
+ /**
43
+ * Load accounts registry
44
+ */
45
+ function loadAccountsRegistry() {
46
+ const registryPath = (0, token_file_ops_1.getAccountsRegistryPath)();
47
+ if (!fs.existsSync(registryPath)) {
48
+ return { ...DEFAULT_REGISTRY };
49
+ }
50
+ try {
51
+ const content = fs.readFileSync(registryPath, 'utf-8');
52
+ const data = JSON.parse(content);
53
+ return {
54
+ version: data.version || 1,
55
+ providers: data.providers || {},
56
+ };
57
+ }
58
+ catch {
59
+ return { ...DEFAULT_REGISTRY };
60
+ }
61
+ }
62
+ exports.loadAccountsRegistry = loadAccountsRegistry;
63
+ /**
64
+ * Save accounts registry
65
+ */
66
+ function saveAccountsRegistry(registry) {
67
+ const registryPath = (0, token_file_ops_1.getAccountsRegistryPath)();
68
+ const dir = path.dirname(registryPath);
69
+ if (!fs.existsSync(dir)) {
70
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
71
+ }
72
+ fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2) + '\n', {
73
+ mode: 0o600,
74
+ });
75
+ }
76
+ exports.saveAccountsRegistry = saveAccountsRegistry;
77
+ /**
78
+ * Sync registry with actual token files
79
+ * Removes stale entries where token file no longer exists
80
+ * For paused accounts, checks both auth/ and paused/ directories
81
+ * Called automatically when loading accounts
82
+ */
83
+ function syncRegistryWithTokenFiles(registry) {
84
+ const authDir = (0, config_generator_1.getAuthDir)();
85
+ const pausedDir = (0, token_file_ops_1.getPausedDir)();
86
+ let modified = false;
87
+ for (const [_providerName, providerAccounts] of Object.entries(registry.providers)) {
88
+ if (!providerAccounts)
89
+ continue;
90
+ const staleIds = [];
91
+ for (const [accountId, meta] of Object.entries(providerAccounts.accounts)) {
92
+ const tokenPath = path.join(authDir, meta.tokenFile);
93
+ const pausedPath = path.join(pausedDir, meta.tokenFile);
94
+ // For paused accounts, check paused dir; for active accounts, check auth dir
95
+ const expectedPath = meta.paused ? pausedPath : tokenPath;
96
+ // Also accept if file exists in either location (handles edge cases)
97
+ const existsAnywhere = fs.existsSync(tokenPath) || fs.existsSync(pausedPath);
98
+ if (!fs.existsSync(expectedPath) && !existsAnywhere) {
99
+ staleIds.push(accountId);
100
+ }
101
+ }
102
+ // Remove stale accounts
103
+ for (const id of staleIds) {
104
+ delete providerAccounts.accounts[id];
105
+ modified = true;
106
+ // Update default if deleted
107
+ if (providerAccounts.default === id) {
108
+ const remainingIds = Object.keys(providerAccounts.accounts);
109
+ providerAccounts.default = remainingIds[0] || 'default';
110
+ }
111
+ }
112
+ }
113
+ return modified;
114
+ }
115
+ exports.syncRegistryWithTokenFiles = syncRegistryWithTokenFiles;
116
+ /**
117
+ * Register a new account
118
+ * Called after successful OAuth to record the account
119
+ *
120
+ * For providers without email (kiro, ghcp):
121
+ * - nickname is REQUIRED and used as accountId
122
+ * - Uniqueness is enforced to prevent overwriting
123
+ *
124
+ * For providers with email:
125
+ * - email is used as accountId
126
+ * - nickname is auto-generated from email if not provided
127
+ */
128
+ function registerAccount(provider, tokenFile, email, nickname, projectId) {
129
+ const registry = loadAccountsRegistry();
130
+ // Initialize provider section if needed
131
+ if (!registry.providers[provider]) {
132
+ registry.providers[provider] = {
133
+ default: 'default',
134
+ accounts: {},
135
+ };
136
+ }
137
+ const providerAccounts = registry.providers[provider];
138
+ if (!providerAccounts) {
139
+ throw new Error('Failed to initialize provider accounts');
140
+ }
141
+ // Determine account ID based on provider type
142
+ let accountId;
143
+ let accountNickname;
144
+ if (types_1.PROVIDERS_WITHOUT_EMAIL.includes(provider)) {
145
+ // For kiro/ghcp: nickname is REQUIRED and used as accountId
146
+ if (!nickname || nickname === 'default') {
147
+ throw new Error(`Nickname is required when adding ${provider} accounts. ` +
148
+ `Use --nickname <name> or provide a nickname in the UI.`);
149
+ }
150
+ // Validate nickname format
151
+ const validationError = (0, token_file_ops_1.validateNickname)(nickname);
152
+ if (validationError) {
153
+ throw new Error(validationError);
154
+ }
155
+ // Check uniqueness
156
+ for (const [existingId, _account] of Object.entries(providerAccounts.accounts)) {
157
+ if (existingId.toLowerCase() === nickname.toLowerCase()) {
158
+ throw new Error(`An account with nickname "${nickname}" already exists for ${provider}. ` +
159
+ `Choose a different nickname.`);
160
+ }
161
+ }
162
+ accountId = nickname;
163
+ accountNickname = nickname;
164
+ }
165
+ else {
166
+ // For other providers: use email as accountId, fallback to filename extraction
167
+ accountId = (0, token_file_ops_1.extractAccountIdFromTokenFile)(tokenFile, email);
168
+ accountNickname = nickname || (0, token_file_ops_1.generateNickname)(email);
169
+ }
170
+ const isFirstAccount = Object.keys(providerAccounts.accounts).length === 0;
171
+ // Create or update account
172
+ const accountMeta = {
173
+ email,
174
+ nickname: accountNickname,
175
+ tokenFile,
176
+ createdAt: new Date().toISOString(),
177
+ lastUsedAt: new Date().toISOString(),
178
+ };
179
+ // Include projectId for Antigravity accounts
180
+ if (provider === 'agy' && projectId) {
181
+ accountMeta.projectId = projectId;
182
+ }
183
+ providerAccounts.accounts[accountId] = accountMeta;
184
+ // Set as default if first account
185
+ if (isFirstAccount) {
186
+ providerAccounts.default = accountId;
187
+ }
188
+ saveAccountsRegistry(registry);
189
+ return {
190
+ id: accountId,
191
+ provider,
192
+ isDefault: accountId === providerAccounts.default,
193
+ email,
194
+ nickname: accountNickname,
195
+ tokenFile,
196
+ createdAt: providerAccounts.accounts[accountId].createdAt,
197
+ lastUsedAt: providerAccounts.accounts[accountId].lastUsedAt,
198
+ projectId: providerAccounts.accounts[accountId].projectId,
199
+ };
200
+ }
201
+ exports.registerAccount = registerAccount;
202
+ /**
203
+ * Set default account for a provider
204
+ */
205
+ function setDefaultAccount(provider, accountId) {
206
+ const registry = loadAccountsRegistry();
207
+ const providerAccounts = registry.providers[provider];
208
+ if (!providerAccounts || !providerAccounts.accounts[accountId]) {
209
+ return false;
210
+ }
211
+ providerAccounts.default = accountId;
212
+ saveAccountsRegistry(registry);
213
+ return true;
214
+ }
215
+ exports.setDefaultAccount = setDefaultAccount;
216
+ /**
217
+ * Pause an account (skip in quota rotation)
218
+ * Moves token file to paused/ subdir so CLIProxyAPI won't discover it
219
+ */
220
+ function pauseAccount(provider, accountId) {
221
+ const registry = loadAccountsRegistry();
222
+ const providerAccounts = registry.providers[provider];
223
+ if (!providerAccounts?.accounts[accountId]) {
224
+ return false;
225
+ }
226
+ const accountMeta = providerAccounts.accounts[accountId];
227
+ // Skip if already paused (idempotent)
228
+ if (accountMeta.paused) {
229
+ return true;
230
+ }
231
+ // Move token file to paused directory (if it exists in auth dir)
232
+ (0, token_file_ops_1.moveTokenToPaused)(accountMeta.tokenFile);
233
+ providerAccounts.accounts[accountId].paused = true;
234
+ providerAccounts.accounts[accountId].pausedAt = new Date().toISOString();
235
+ saveAccountsRegistry(registry);
236
+ return true;
237
+ }
238
+ exports.pauseAccount = pauseAccount;
239
+ /**
240
+ * Resume a paused account
241
+ * Moves token file back from paused/ to auth/ so CLIProxyAPI can discover it
242
+ */
243
+ function resumeAccount(provider, accountId) {
244
+ const registry = loadAccountsRegistry();
245
+ const providerAccounts = registry.providers[provider];
246
+ if (!providerAccounts?.accounts[accountId]) {
247
+ return false;
248
+ }
249
+ const accountMeta = providerAccounts.accounts[accountId];
250
+ // Skip if already active (idempotent)
251
+ if (!accountMeta.paused) {
252
+ return true;
253
+ }
254
+ // Move token file back from paused directory (if it exists in paused dir)
255
+ (0, token_file_ops_1.moveTokenFromPaused)(accountMeta.tokenFile);
256
+ providerAccounts.accounts[accountId].paused = false;
257
+ providerAccounts.accounts[accountId].pausedAt = undefined;
258
+ saveAccountsRegistry(registry);
259
+ return true;
260
+ }
261
+ exports.resumeAccount = resumeAccount;
262
+ /**
263
+ * Remove an account
264
+ */
265
+ function removeAccount(provider, accountId) {
266
+ const registry = loadAccountsRegistry();
267
+ const providerAccounts = registry.providers[provider];
268
+ if (!providerAccounts || !providerAccounts.accounts[accountId]) {
269
+ return false;
270
+ }
271
+ // Delete token file from both auth and paused directories
272
+ const tokenFile = providerAccounts.accounts[accountId].tokenFile;
273
+ (0, token_file_ops_1.deleteTokenFile)(tokenFile);
274
+ // Remove from registry
275
+ delete providerAccounts.accounts[accountId];
276
+ // Update default if needed
277
+ const remainingAccounts = Object.keys(providerAccounts.accounts);
278
+ if (providerAccounts.default === accountId && remainingAccounts.length > 0) {
279
+ providerAccounts.default = remainingAccounts[0];
280
+ }
281
+ saveAccountsRegistry(registry);
282
+ return true;
283
+ }
284
+ exports.removeAccount = removeAccount;
285
+ /**
286
+ * Rename an account's nickname
287
+ */
288
+ function renameAccount(provider, accountId, newNickname) {
289
+ const validationError = (0, token_file_ops_1.validateNickname)(newNickname);
290
+ if (validationError) {
291
+ throw new Error(validationError);
292
+ }
293
+ const registry = loadAccountsRegistry();
294
+ const providerAccounts = registry.providers[provider];
295
+ if (!providerAccounts?.accounts[accountId]) {
296
+ return false;
297
+ }
298
+ // Check if nickname is already used by another account
299
+ for (const [id, account] of Object.entries(providerAccounts.accounts)) {
300
+ if (id !== accountId && account.nickname?.toLowerCase() === newNickname.toLowerCase()) {
301
+ throw new Error(`Nickname "${newNickname}" is already used by another account`);
302
+ }
303
+ }
304
+ providerAccounts.accounts[accountId].nickname = newNickname;
305
+ saveAccountsRegistry(registry);
306
+ return true;
307
+ }
308
+ exports.renameAccount = renameAccount;
309
+ /**
310
+ * Update last used timestamp for an account
311
+ */
312
+ function touchAccount(provider, accountId) {
313
+ const registry = loadAccountsRegistry();
314
+ const providerAccounts = registry.providers[provider];
315
+ if (providerAccounts?.accounts[accountId]) {
316
+ providerAccounts.accounts[accountId].lastUsedAt = new Date().toISOString();
317
+ saveAccountsRegistry(registry);
318
+ }
319
+ }
320
+ exports.touchAccount = touchAccount;
321
+ /**
322
+ * Update account tier
323
+ */
324
+ function setAccountTier(provider, accountId, tier) {
325
+ const registry = loadAccountsRegistry();
326
+ const providerAccounts = registry.providers[provider];
327
+ if (!providerAccounts?.accounts[accountId]) {
328
+ return false;
329
+ }
330
+ providerAccounts.accounts[accountId].tier = tier;
331
+ saveAccountsRegistry(registry);
332
+ return true;
333
+ }
334
+ exports.setAccountTier = setAccountTier;
335
+ /**
336
+ * Auto-discover accounts from existing token files
337
+ * Called during migration or first run to populate accounts registry
338
+ *
339
+ * For kiro/ghcp providers without email, generates unique accountId from:
340
+ * 1. OAuth provider + profile ID from filename (e.g., github-ABC123)
341
+ * 2. Fallback: provider + index (e.g., kiro-1, kiro-2)
342
+ */
343
+ function discoverExistingAccounts() {
344
+ const authDir = (0, config_generator_1.getAuthDir)();
345
+ if (!fs.existsSync(authDir)) {
346
+ return;
347
+ }
348
+ const registry = loadAccountsRegistry();
349
+ const files = fs.readdirSync(authDir);
350
+ // Track whether any accounts were discovered (to avoid saving empty registry)
351
+ let discoveredCount = 0;
352
+ for (const file of files) {
353
+ if (!file.endsWith('.json'))
354
+ continue;
355
+ const filePath = path.join(authDir, file);
356
+ try {
357
+ const content = fs.readFileSync(filePath, 'utf-8');
358
+ const data = JSON.parse(content);
359
+ // Skip if no type field
360
+ if (!data.type)
361
+ continue;
362
+ // Build reverse mapping from PROVIDER_TYPE_VALUES (type value -> provider)
363
+ // e.g., "antigravity" -> "agy", "kiro" -> "kiro", "codewhisperer" -> "kiro"
364
+ const typeValue = data.type.toLowerCase();
365
+ let provider;
366
+ for (const [prov, typeValues] of Object.entries(auth_types_1.PROVIDER_TYPE_VALUES)) {
367
+ if (typeValues.includes(typeValue)) {
368
+ provider = prov;
369
+ break;
370
+ }
371
+ }
372
+ // Skip if unknown provider type
373
+ if (!provider) {
374
+ continue;
375
+ }
376
+ // Extract email if available, fallback to filename-based ID
377
+ let email = data.email || undefined;
378
+ // Fallback: extract email from filename (e.g., "kiro-google-user@example.com.json")
379
+ if (!email && file.includes('@')) {
380
+ const match = file.match(/([^-]+@[^.]+\.[^.]+)(?=\.json$)/);
381
+ if (match) {
382
+ email = match[1];
383
+ }
384
+ }
385
+ // Initialize provider section if needed
386
+ if (!registry.providers[provider]) {
387
+ registry.providers[provider] = {
388
+ default: 'default',
389
+ accounts: {},
390
+ };
391
+ }
392
+ const providerAccounts = registry.providers[provider];
393
+ if (!providerAccounts)
394
+ continue;
395
+ // Skip if token file already registered (under any accountId)
396
+ const existingTokenFiles = Object.values(providerAccounts.accounts).map((a) => a.tokenFile);
397
+ if (existingTokenFiles.includes(file)) {
398
+ // Token file exists - check if we need to update projectId for agy accounts
399
+ const projectIdValue = typeof data.project_id === 'string' && data.project_id.trim()
400
+ ? data.project_id.trim()
401
+ : null;
402
+ if (provider === 'agy' && projectIdValue) {
403
+ const existingEntry = Object.entries(providerAccounts.accounts).find(([, meta]) => meta.tokenFile === file);
404
+ // Update if missing or changed
405
+ if (existingEntry && existingEntry[1].projectId !== projectIdValue) {
406
+ existingEntry[1].projectId = projectIdValue;
407
+ discoveredCount++; // Count projectId updates as changes
408
+ }
409
+ }
410
+ continue;
411
+ }
412
+ // Determine accountId based on provider type
413
+ let accountId;
414
+ if (types_1.PROVIDERS_WITHOUT_EMAIL.includes(provider) && !email) {
415
+ // For kiro/ghcp without email: extract from filename or generate unique
416
+ // Pattern: kiro-github-ABC123.json -> github-ABC123
417
+ const filenameId = (0, token_file_ops_1.extractAccountIdFromTokenFile)(file, undefined);
418
+ if (filenameId !== 'default') {
419
+ accountId = filenameId;
420
+ }
421
+ else {
422
+ // Generate unique ID: provider + incrementing index
423
+ let index = 1;
424
+ while (providerAccounts.accounts[`${provider}-${index}`]) {
425
+ index++;
426
+ }
427
+ accountId = `${provider}-${index}`;
428
+ }
429
+ }
430
+ else {
431
+ // For providers with email: use email or filename extraction
432
+ accountId = (0, token_file_ops_1.extractAccountIdFromTokenFile)(file, email);
433
+ }
434
+ // Skip if account already registered
435
+ if (providerAccounts.accounts[accountId]) {
436
+ continue;
437
+ }
438
+ // Set as default if first account
439
+ if (Object.keys(providerAccounts.accounts).length === 0) {
440
+ providerAccounts.default = accountId;
441
+ }
442
+ // Get file stats for creation time
443
+ const stats = fs.statSync(filePath);
444
+ // Register account with auto-generated nickname
445
+ // Use mtime as lastUsedAt (when token was last modified = last auth/refresh)
446
+ const lastModified = stats.mtime || stats.birthtime || new Date();
447
+ const accountMeta = {
448
+ email,
449
+ nickname: (0, token_file_ops_1.generateNickname)(email),
450
+ tokenFile: file,
451
+ createdAt: stats.birthtime?.toISOString() || new Date().toISOString(),
452
+ lastUsedAt: lastModified.toISOString(),
453
+ };
454
+ // Read project_id for Antigravity accounts (read-only field from auth token)
455
+ const discoveredProjectId = typeof data.project_id === 'string' && data.project_id.trim()
456
+ ? data.project_id.trim()
457
+ : null;
458
+ if (provider === 'agy' && discoveredProjectId) {
459
+ accountMeta.projectId = discoveredProjectId;
460
+ }
461
+ providerAccounts.accounts[accountId] = accountMeta;
462
+ discoveredCount++;
463
+ }
464
+ catch {
465
+ // Skip invalid files
466
+ continue;
467
+ }
468
+ }
469
+ // Only save if at least one account was discovered or updated
470
+ // This prevents creating accounts.json with empty provider sections
471
+ if (discoveredCount === 0) {
472
+ return;
473
+ }
474
+ // Reload-merge pattern: reduce race condition with concurrent OAuth registration
475
+ // Reload fresh registry and merge discovered accounts (fresh registry wins on conflicts)
476
+ const freshRegistry = loadAccountsRegistry();
477
+ for (const [providerName, discovered] of Object.entries(registry.providers)) {
478
+ if (!discovered)
479
+ continue;
480
+ // Skip empty provider sections (no accounts discovered)
481
+ if (Object.keys(discovered.accounts).length === 0)
482
+ continue;
483
+ const prov = providerName;
484
+ if (!freshRegistry.providers[prov]) {
485
+ freshRegistry.providers[prov] = discovered;
486
+ }
487
+ else {
488
+ // Merge accounts, preferring fresh registry's existing entries but updating projectId
489
+ const freshProviderAccounts = freshRegistry.providers[prov];
490
+ if (!freshProviderAccounts)
491
+ continue;
492
+ for (const [id, meta] of Object.entries(discovered.accounts)) {
493
+ if (!freshProviderAccounts.accounts[id]) {
494
+ freshProviderAccounts.accounts[id] = meta;
495
+ // Set default if none exists
496
+ if (!freshProviderAccounts.default || freshProviderAccounts.default === 'default') {
497
+ freshProviderAccounts.default = id;
498
+ }
499
+ }
500
+ else if (meta.projectId && !freshProviderAccounts.accounts[id].projectId) {
501
+ // Update existing account with projectId if discovered from auth file
502
+ freshProviderAccounts.accounts[id].projectId = meta.projectId;
503
+ }
504
+ }
505
+ }
506
+ }
507
+ saveAccountsRegistry(freshRegistry);
508
+ }
509
+ exports.discoverExistingAccounts = discoverExistingAccounts;
510
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/cliproxy/accounts/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Token file operations and path management
3
+ */
4
+ import { AccountInfo } from './types';
5
+ /**
6
+ * Get path to accounts registry file
7
+ */
8
+ export declare function getAccountsRegistryPath(): string;
9
+ /**
10
+ * Get path to paused tokens directory
11
+ * Paused tokens are moved here so CLIProxyAPI won't discover them
12
+ *
13
+ * Uses sibling directory (auth-paused/) instead of subdirectory (auth/paused/)
14
+ * because CLIProxyAPI's watcher uses filepath.Walk() which recursively scans
15
+ * all subdirectories of auth/. A sibling directory is completely outside
16
+ * CLIProxyAPI's scan path, preventing token refresh loops.
17
+ */
18
+ export declare function getPausedDir(): string;
19
+ /**
20
+ * Get token file path for an account
21
+ * Returns path in paused/ dir if account is paused, otherwise auth/
22
+ */
23
+ export declare function getAccountTokenPath(account: AccountInfo): string;
24
+ /**
25
+ * Move token file to paused directory
26
+ * Creates paused directory if needed, idempotent
27
+ */
28
+ export declare function moveTokenToPaused(tokenFile: string): boolean;
29
+ /**
30
+ * Move token file from paused directory back to auth
31
+ * Idempotent
32
+ */
33
+ export declare function moveTokenFromPaused(tokenFile: string): boolean;
34
+ /**
35
+ * Delete token file from both auth and paused directories
36
+ * Idempotent
37
+ */
38
+ export declare function deleteTokenFile(tokenFile: string): void;
39
+ /**
40
+ * Check if token file exists in either auth or paused directory
41
+ */
42
+ export declare function tokenFileExists(tokenFile: string): boolean;
43
+ /**
44
+ * Extract unique account ID from token filename when email is unavailable
45
+ * For Kiro/GHCP OAuth, filenames are: <provider>-<oauth>-<profile_id>.json
46
+ * Extracts: <oauth>-<profile_id> as unique identifier
47
+ * @example kiro-github-ABC123.json → github-ABC123
48
+ * @example ghcp-amazon-XYZ789.json → amazon-XYZ789
49
+ * @example kiro-nomail.json → default (no OAuth structure)
50
+ */
51
+ export declare function extractAccountIdFromTokenFile(filename: string, email?: string): string;
52
+ /**
53
+ * Generate nickname from email
54
+ * Takes prefix before @ symbol, sanitizes whitespace
55
+ * Validation: 1-50 chars, any non-whitespace (permissive per user preference)
56
+ */
57
+ export declare function generateNickname(email?: string): string;
58
+ /**
59
+ * Validate nickname
60
+ * Rules: 1-50 chars, no whitespace, URL-safe, no reserved patterns
61
+ * @returns null if valid, error message if invalid
62
+ */
63
+ export declare function validateNickname(nickname: string): string | null;
64
+ //# sourceMappingURL=token-file-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-file-ops.d.ts","sourceRoot":"","sources":["../../../src/cliproxy/accounts/token-file-ops.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAGhE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAsB5D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAkB9D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAqBvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAI1D;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAStF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBhE"}