@vybestack/llxprt-code 0.1.23 → 0.2.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 (161) hide show
  1. package/README.md +21 -17
  2. package/dist/package.json +4 -3
  3. package/dist/src/auth/anthropic-oauth-provider.d.ts +50 -3
  4. package/dist/src/auth/anthropic-oauth-provider.js +287 -63
  5. package/dist/src/auth/anthropic-oauth-provider.js.map +1 -1
  6. package/dist/src/auth/gemini-oauth-provider.d.ts +34 -3
  7. package/dist/src/auth/gemini-oauth-provider.js +308 -14
  8. package/dist/src/auth/gemini-oauth-provider.js.map +1 -1
  9. package/dist/src/auth/migration.d.ts +26 -0
  10. package/dist/src/auth/migration.js +54 -0
  11. package/dist/src/auth/migration.js.map +1 -0
  12. package/dist/src/auth/oauth-manager.d.ts +24 -0
  13. package/dist/src/auth/oauth-manager.js +179 -14
  14. package/dist/src/auth/oauth-manager.js.map +1 -1
  15. package/dist/src/auth/oauth-manager.spec.js +10 -8
  16. package/dist/src/auth/oauth-manager.spec.js.map +1 -1
  17. package/dist/src/auth/qwen-oauth-provider.d.ts +59 -3
  18. package/dist/src/auth/qwen-oauth-provider.js +263 -41
  19. package/dist/src/auth/qwen-oauth-provider.js.map +1 -1
  20. package/dist/src/config/config.js +11 -10
  21. package/dist/src/config/config.js.map +1 -1
  22. package/dist/src/config/extension.d.ts +1 -1
  23. package/dist/src/config/extension.js +1 -1
  24. package/dist/src/gemini.js +33 -11
  25. package/dist/src/gemini.js.map +1 -1
  26. package/dist/src/generated/git-commit.d.ts +1 -1
  27. package/dist/src/generated/git-commit.js +1 -1
  28. package/dist/src/integration-tests/base-url-behavior.integration.test.js +4 -1
  29. package/dist/src/integration-tests/base-url-behavior.integration.test.js.map +1 -1
  30. package/dist/src/integration-tests/compression-settings-apply.integration.test.js +85 -332
  31. package/dist/src/integration-tests/compression-settings-apply.integration.test.js.map +1 -1
  32. package/dist/src/integration-tests/ephemeral-settings.integration.test.js +5 -16
  33. package/dist/src/integration-tests/ephemeral-settings.integration.test.js.map +1 -1
  34. package/dist/src/integration-tests/model-params-isolation.integration.test.js +8 -2
  35. package/dist/src/integration-tests/model-params-isolation.integration.test.js.map +1 -1
  36. package/dist/src/integration-tests/modelParams.integration.test.js +4 -1
  37. package/dist/src/integration-tests/modelParams.integration.test.js.map +1 -1
  38. package/dist/src/integration-tests/provider-switching.integration.test.js +4 -1
  39. package/dist/src/integration-tests/provider-switching.integration.test.js.map +1 -1
  40. package/dist/src/providers/index.d.ts +1 -1
  41. package/dist/src/providers/logging/LoggingProviderWrapper.test.js +58 -47
  42. package/dist/src/providers/logging/LoggingProviderWrapper.test.js.map +1 -1
  43. package/dist/src/providers/logging/multi-provider-logging.integration.test.js +130 -68
  44. package/dist/src/providers/logging/multi-provider-logging.integration.test.js.map +1 -1
  45. package/dist/src/providers/logging/performance.test.js +39 -16
  46. package/dist/src/providers/logging/performance.test.js.map +1 -1
  47. package/dist/src/providers/provider-gemini-switching.test.js +4 -1
  48. package/dist/src/providers/provider-gemini-switching.test.js.map +1 -1
  49. package/dist/src/providers/provider-switching.integration.test.js +12 -3
  50. package/dist/src/providers/provider-switching.integration.test.js.map +1 -1
  51. package/dist/src/providers/providerConfigUtils.js +2 -4
  52. package/dist/src/providers/providerConfigUtils.js.map +1 -1
  53. package/dist/src/providers/providerManagerInstance.js +24 -49
  54. package/dist/src/providers/providerManagerInstance.js.map +1 -1
  55. package/dist/src/services/BuiltinCommandLoader.js +4 -0
  56. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  57. package/dist/src/storage/ConversationStorage.test.js +10 -7
  58. package/dist/src/storage/ConversationStorage.test.js.map +1 -1
  59. package/dist/src/test-utils/mockCommandContext.js +2 -0
  60. package/dist/src/test-utils/mockCommandContext.js.map +1 -1
  61. package/dist/src/ui/App.e2e.test.d.ts +6 -0
  62. package/dist/src/ui/App.e2e.test.js +37 -0
  63. package/dist/src/ui/App.e2e.test.js.map +1 -0
  64. package/dist/src/ui/App.js +51 -4
  65. package/dist/src/ui/App.js.map +1 -1
  66. package/dist/src/ui/commands/authCommand.d.ts +9 -1
  67. package/dist/src/ui/commands/authCommand.js +109 -31
  68. package/dist/src/ui/commands/authCommand.js.map +1 -1
  69. package/dist/src/ui/commands/clearCommand.js +2 -0
  70. package/dist/src/ui/commands/clearCommand.js.map +1 -1
  71. package/dist/src/ui/commands/ideCommand.js +26 -0
  72. package/dist/src/ui/commands/ideCommand.js.map +1 -1
  73. package/dist/src/ui/commands/keyCommand.js +16 -54
  74. package/dist/src/ui/commands/keyCommand.js.map +1 -1
  75. package/dist/src/ui/commands/keyCommand.test.js +3 -3
  76. package/dist/src/ui/commands/keyCommand.test.js.map +1 -1
  77. package/dist/src/ui/commands/keyfileCommand.js +42 -32
  78. package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
  79. package/dist/src/ui/commands/logoutCommand.d.ts +7 -0
  80. package/dist/src/ui/commands/logoutCommand.js +70 -0
  81. package/dist/src/ui/commands/logoutCommand.js.map +1 -0
  82. package/dist/src/ui/commands/modelCommand.js +16 -0
  83. package/dist/src/ui/commands/modelCommand.js.map +1 -1
  84. package/dist/src/ui/commands/profileCommand.js +26 -24
  85. package/dist/src/ui/commands/profileCommand.js.map +1 -1
  86. package/dist/src/ui/commands/profileCommand.test.js +15 -16
  87. package/dist/src/ui/commands/profileCommand.test.js.map +1 -1
  88. package/dist/src/ui/commands/providerCommand.js +10 -7
  89. package/dist/src/ui/commands/providerCommand.js.map +1 -1
  90. package/dist/src/ui/commands/setCommand.js +40 -19
  91. package/dist/src/ui/commands/setCommand.js.map +1 -1
  92. package/dist/src/ui/commands/setCommand.test.js +5 -7
  93. package/dist/src/ui/commands/setCommand.test.js.map +1 -1
  94. package/dist/src/ui/commands/setupGithubCommand.d.ts +2 -0
  95. package/dist/src/ui/commands/setupGithubCommand.js +123 -23
  96. package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
  97. package/dist/src/ui/commands/setupGithubCommand.test.js +94 -1
  98. package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -1
  99. package/dist/src/ui/commands/statusCommand.d.ts +7 -0
  100. package/dist/src/ui/commands/statusCommand.js +71 -0
  101. package/dist/src/ui/commands/statusCommand.js.map +1 -0
  102. package/dist/src/ui/commands/types.d.ts +1 -0
  103. package/dist/src/ui/commands/types.js.map +1 -1
  104. package/dist/src/ui/components/ContextIndicator.ui.test.js +19 -46
  105. package/dist/src/ui/components/ContextIndicator.ui.test.js.map +1 -1
  106. package/dist/src/ui/components/Footer.d.ts +1 -1
  107. package/dist/src/ui/components/Footer.js +7 -7
  108. package/dist/src/ui/components/Footer.js.map +1 -1
  109. package/dist/src/ui/components/Footer.responsive.test.js +28 -25
  110. package/dist/src/ui/components/Footer.responsive.test.js.map +1 -1
  111. package/dist/src/ui/components/OAuthCodeDialog.d.ts +5 -0
  112. package/dist/src/ui/components/OAuthCodeDialog.js +31 -1
  113. package/dist/src/ui/components/OAuthCodeDialog.js.map +1 -1
  114. package/dist/src/ui/components/OAuthCodeDialog.test.d.ts +6 -0
  115. package/dist/src/ui/components/OAuthCodeDialog.test.js +60 -0
  116. package/dist/src/ui/components/OAuthCodeDialog.test.js.map +1 -0
  117. package/dist/src/ui/contexts/KeypressContext.js +23 -1
  118. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  119. package/dist/src/ui/contexts/KeypressContext.test.js +58 -2
  120. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  121. package/dist/src/ui/contexts/SessionContext.d.ts +2 -0
  122. package/dist/src/ui/contexts/SessionContext.js +9 -1
  123. package/dist/src/ui/contexts/SessionContext.js.map +1 -1
  124. package/dist/src/ui/contexts/TodoContext.js +2 -2
  125. package/dist/src/ui/contexts/TodoContext.js.map +1 -1
  126. package/dist/src/ui/hooks/atCommandProcessor.js +0 -2
  127. package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
  128. package/dist/src/ui/hooks/atCommandProcessor.test.js +21 -6
  129. package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
  130. package/dist/src/ui/hooks/slashCommandProcessor.js +2 -0
  131. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  132. package/dist/src/ui/hooks/useAuthCommand.js +6 -5
  133. package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
  134. package/dist/src/ui/hooks/useGeminiStream.js +47 -63
  135. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  136. package/dist/src/ui/hooks/useProviderDialog.js +2 -5
  137. package/dist/src/ui/hooks/useProviderDialog.js.map +1 -1
  138. package/dist/src/ui/hooks/useToolScheduler.test.js +60 -24
  139. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  140. package/dist/src/ui/utils/platformConstants.d.ts +2 -0
  141. package/dist/src/ui/utils/platformConstants.js +2 -0
  142. package/dist/src/ui/utils/platformConstants.js.map +1 -1
  143. package/dist/src/ui/utils/secureInputHandler.js +18 -7
  144. package/dist/src/ui/utils/secureInputHandler.js.map +1 -1
  145. package/dist/src/ui/utils/secureInputHandler.test.js +20 -0
  146. package/dist/src/ui/utils/secureInputHandler.test.js.map +1 -1
  147. package/dist/src/utils/privacy/ConversationDataRedactor.d.ts +3 -3
  148. package/dist/src/utils/privacy/ConversationDataRedactor.js +16 -12
  149. package/dist/src/utils/privacy/ConversationDataRedactor.js.map +1 -1
  150. package/dist/src/utils/privacy/ConversationDataRedactor.test.js +115 -72
  151. package/dist/src/utils/privacy/ConversationDataRedactor.test.js.map +1 -1
  152. package/dist/src/validateNonInterActiveAuth.js +8 -17
  153. package/dist/src/validateNonInterActiveAuth.js.map +1 -1
  154. package/dist/src/zed-integration/schema.d.ts +194 -91
  155. package/dist/src/zed-integration/schema.js +7 -1
  156. package/dist/src/zed-integration/schema.js.map +1 -1
  157. package/dist/src/zed-integration/zedIntegration.d.ts +1 -3
  158. package/dist/src/zed-integration/zedIntegration.js +454 -198
  159. package/dist/src/zed-integration/zedIntegration.js.map +1 -1
  160. package/dist/tsconfig.tsbuildinfo +1 -1
  161. package/package.json +4 -3
@@ -1,33 +1,327 @@
1
1
  /**
2
2
  * Gemini OAuth Provider Implementation
3
3
  *
4
- * Note: This is a placeholder that signals to use the existing Gemini OAuth flow.
5
- * The actual OAuth is handled by the GeminiProvider itself using LOGIN_WITH_GOOGLE.
4
+ * Bridges to the existing Google OAuth infrastructure in oauth2.ts
5
+ * while maintaining compatibility with the LOGIN_WITH_GOOGLE flow.
6
6
  */
7
+ import { clearOauthClientCache, OAuthError, OAuthErrorFactory, GracefulErrorHandler, RetryHandler, shouldLaunchBrowser, DebugLogger, } from '@vybestack/llxprt-code-core';
8
+ import { promises as fs } from 'node:fs';
9
+ import path from 'node:path';
10
+ import os from 'node:os';
11
+ var InitializationState;
12
+ (function (InitializationState) {
13
+ InitializationState["NotStarted"] = "not-started";
14
+ InitializationState["InProgress"] = "in-progress";
15
+ InitializationState["Completed"] = "completed";
16
+ InitializationState["Failed"] = "failed";
17
+ })(InitializationState || (InitializationState = {}));
7
18
  export class GeminiOAuthProvider {
8
19
  name = 'gemini';
9
20
  currentToken = null;
21
+ tokenStore;
22
+ initializationState = InitializationState.NotStarted;
23
+ initializationPromise;
24
+ initializationError;
25
+ errorHandler;
26
+ retryHandler;
27
+ logger;
28
+ constructor(tokenStore) {
29
+ this.tokenStore = tokenStore;
30
+ this.retryHandler = new RetryHandler();
31
+ this.errorHandler = new GracefulErrorHandler(this.retryHandler);
32
+ this.logger = new DebugLogger('llxprt:auth:gemini');
33
+ if (!tokenStore) {
34
+ console.warn(`DEPRECATION: ${this.name} OAuth provider created without TokenStore. ` +
35
+ `Token persistence will not work. Please update your code.`);
36
+ }
37
+ // DO NOT call initializeToken() - lazy initialization pattern
38
+ }
39
+ /**
40
+ * Lazy initialization with proper state management
41
+ * Ensures initialization only happens once and handles concurrent calls
42
+ */
43
+ async ensureInitialized() {
44
+ // If already completed, return immediately
45
+ if (this.initializationState === InitializationState.Completed) {
46
+ return;
47
+ }
48
+ // If failed, allow retry by resetting to NotStarted
49
+ if (this.initializationState === InitializationState.Failed) {
50
+ this.initializationState = InitializationState.NotStarted;
51
+ this.initializationPromise = undefined;
52
+ this.initializationError = undefined;
53
+ }
54
+ // If not started, start initialization
55
+ if (this.initializationState === InitializationState.NotStarted) {
56
+ this.initializationState = InitializationState.InProgress;
57
+ this.initializationPromise = this.initializeToken();
58
+ }
59
+ // Wait for initialization to complete (handles concurrent calls)
60
+ if (this.initializationPromise) {
61
+ try {
62
+ await this.initializationPromise;
63
+ this.initializationState = InitializationState.Completed;
64
+ }
65
+ catch (error) {
66
+ this.initializationState = InitializationState.Failed;
67
+ this.initializationError =
68
+ error instanceof OAuthError
69
+ ? error
70
+ : OAuthErrorFactory.fromUnknown(this.name, error, 'ensureInitialized');
71
+ throw this.initializationError;
72
+ }
73
+ }
74
+ }
75
+ async initializeToken() {
76
+ if (!this.tokenStore) {
77
+ return;
78
+ }
79
+ return this.errorHandler.handleGracefully(async () => {
80
+ // Try to load from new location first
81
+ let savedToken = await this.tokenStore.getToken('gemini');
82
+ if (!savedToken) {
83
+ // Try to migrate from legacy locations
84
+ savedToken = await this.migrateFromLegacyTokens();
85
+ }
86
+ if (savedToken) {
87
+ this.currentToken = savedToken;
88
+ }
89
+ }, undefined, // No fallback needed - graceful failure is acceptable
90
+ this.name, 'initializeToken');
91
+ }
10
92
  async initiateAuth() {
11
- // Signal that the existing LOGIN_WITH_GOOGLE flow should be used
12
- // The GeminiProvider will handle this through its own OAuth mechanism
13
- throw new Error('USE_EXISTING_GEMINI_OAUTH');
93
+ await this.ensureInitialized();
94
+ return this.errorHandler.wrapMethod(async () => {
95
+ // Import the existing Google OAuth infrastructure
96
+ const coreModule = await import('@vybestack/llxprt-code-core');
97
+ const { getOauthClient, AuthType } = coreModule;
98
+ // Create a minimal config for OAuth - use type assertion for test environment
99
+ // Type assertion is needed since we're creating a partial Config for test mode
100
+ const config = {
101
+ getProxy: () => undefined,
102
+ isBrowserLaunchSuppressed: () => !shouldLaunchBrowser(),
103
+ };
104
+ // Use the existing Google OAuth infrastructure to get a client
105
+ let client;
106
+ try {
107
+ client = await getOauthClient(AuthType.LOGIN_WITH_GOOGLE, config);
108
+ }
109
+ catch (error) {
110
+ // Handle browser auth cancellation or other auth failures
111
+ if (error instanceof Error) {
112
+ // Check for specific cancellation messages
113
+ if (error.message.includes('cancelled') ||
114
+ error.message.includes('denied') ||
115
+ error.message.includes('access_denied') ||
116
+ error.message.includes('user_cancelled')) {
117
+ // CRITICAL FIX: Trigger fallback flow instead of failing
118
+ this.logger.debug(() => `Browser auth cancelled, triggering fallback: ${error.message}`);
119
+ // Show fallback instructions to user
120
+ console.log('\n' + '─'.repeat(60));
121
+ console.log('Browser authentication was cancelled.');
122
+ console.log('Fallback options:');
123
+ console.log('1. Use API key: /keyfile <path-to-your-gemini-key>');
124
+ console.log('2. Set environment: export GEMINI_API_KEY=<your-key>');
125
+ console.log('3. Try OAuth again: /auth gemini enable');
126
+ console.log('─'.repeat(60));
127
+ // Throw a user-friendly error that doesn't hang the system
128
+ throw OAuthErrorFactory.authenticationRequired(this.name, {
129
+ reason: 'Browser authentication was cancelled. Please use one of the fallback options shown above.',
130
+ });
131
+ }
132
+ }
133
+ // Re-throw other authentication errors
134
+ throw error;
135
+ }
136
+ // The client should now have valid credentials
137
+ // Extract and cache the token
138
+ const credentials = client.credentials;
139
+ if (credentials && credentials.access_token) {
140
+ const token = this.credentialsToOAuthToken(credentials);
141
+ if (token && this.tokenStore) {
142
+ try {
143
+ await this.tokenStore.saveToken('gemini', token);
144
+ this.currentToken = token;
145
+ }
146
+ catch (saveError) {
147
+ throw OAuthErrorFactory.storageError(this.name, saveError instanceof Error ? saveError : undefined, {
148
+ operation: 'saveToken',
149
+ });
150
+ }
151
+ }
152
+ }
153
+ else {
154
+ throw OAuthErrorFactory.authenticationRequired(this.name, {
155
+ reason: 'No valid credentials received from Google OAuth',
156
+ });
157
+ }
158
+ }, this.name, 'initiateAuth')();
14
159
  }
15
160
  async getToken() {
16
- return this.currentToken;
161
+ await this.ensureInitialized();
162
+ return this.errorHandler.handleGracefully(async () => {
163
+ // Try to get from memory first
164
+ let token = await this.refreshIfNeeded();
165
+ if (!token) {
166
+ // Try to get from existing Google OAuth infrastructure
167
+ token = await this.getTokenFromGoogleOAuth();
168
+ // Cache it if found
169
+ if (token && this.tokenStore) {
170
+ try {
171
+ await this.tokenStore.saveToken('gemini', token);
172
+ this.currentToken = token;
173
+ }
174
+ catch (error) {
175
+ // Non-critical - we can still return the token
176
+ this.logger.debug(() => `Failed to cache token from Google OAuth: ${error}`);
177
+ }
178
+ }
179
+ }
180
+ return token;
181
+ }, null, // Return null on error
182
+ this.name, 'getToken');
17
183
  }
18
184
  async refreshIfNeeded() {
185
+ await this.ensureInitialized();
19
186
  if (!this.currentToken) {
20
187
  return null;
21
188
  }
22
- // Check if token needs refresh (30 second buffer)
23
- const now = Date.now() / 1000;
24
- const expiresAt = this.currentToken.expiry;
25
- if (expiresAt && expiresAt - now < 30) {
26
- // Token expires soon, refresh it
27
- // TODO: Implement Gemini token refresh
28
- console.log('Gemini token refresh needed');
189
+ return this.errorHandler.handleGracefully(async () => {
190
+ // Check if token needs refresh (30 second buffer)
191
+ const now = Date.now() / 1000;
192
+ const expiresAt = this.currentToken.expiry;
193
+ if (expiresAt && expiresAt <= now + 30) {
194
+ // Token is expired or expires soon
195
+ // Since actual Gemini OAuth refresh is handled by the GeminiProvider itself,
196
+ // we clear the expired token and return null to signal re-authentication is needed
197
+ this.currentToken = null;
198
+ if (this.tokenStore) {
199
+ try {
200
+ await this.tokenStore.removeToken('gemini');
201
+ }
202
+ catch (error) {
203
+ throw OAuthErrorFactory.storageError(this.name, error instanceof Error ? error : undefined, {
204
+ operation: 'removeExpiredToken',
205
+ });
206
+ }
207
+ }
208
+ return null;
209
+ }
210
+ return this.currentToken;
211
+ }, null, // Return null on error
212
+ this.name, 'refreshIfNeeded');
213
+ }
214
+ async logout() {
215
+ await this.ensureInitialized();
216
+ // NO ERROR SUPPRESSION - let it fail loudly
217
+ // Clear current token
218
+ this.currentToken = null;
219
+ // Remove from new token storage location - THIS MUST SUCCEED
220
+ if (this.tokenStore) {
221
+ await this.tokenStore.removeToken('gemini');
222
+ }
223
+ // Remove from legacy token locations
224
+ await this.clearLegacyTokens();
225
+ // CRITICAL SECURITY FIX: Clear OAuth client cache to prevent session leakage
226
+ // This ensures that subsequent authentication attempts require re-authentication
227
+ try {
228
+ clearOauthClientCache();
229
+ }
230
+ catch (error) {
231
+ // Log warning but don't fail logout if cache clearing fails
232
+ this.logger.debug(() => `Failed to clear OAuth client cache during Gemini logout: ${error}`);
233
+ }
234
+ }
235
+ /**
236
+ * Converts Google OAuth Credentials to our OAuthToken format
237
+ */
238
+ credentialsToOAuthToken(creds) {
239
+ if (!creds.access_token) {
240
+ return null;
241
+ }
242
+ const token = {
243
+ access_token: creds.access_token,
244
+ refresh_token: creds.refresh_token || undefined,
245
+ // Google OAuth uses expiry_date (milliseconds), we need expiry (seconds)
246
+ expiry: creds.expiry_date
247
+ ? Math.floor(creds.expiry_date / 1000)
248
+ : Math.floor(Date.now() / 1000) + 3600,
249
+ token_type: 'Bearer',
250
+ scope: creds.scope || undefined,
251
+ };
252
+ // Add id_token if available (some tests expect this)
253
+ if (creds.id_token && typeof creds === 'object' && creds.id_token) {
254
+ token.id_token = creds.id_token;
29
255
  }
30
- return this.currentToken;
256
+ return token;
257
+ }
258
+ /**
259
+ * Gets token from the existing Google OAuth infrastructure
260
+ */
261
+ async getTokenFromGoogleOAuth() {
262
+ return this.errorHandler.handleGracefully(async () => {
263
+ // Try to read from the existing OAuth credentials file
264
+ const credPath = path.join(os.homedir(), '.llxprt', 'oauth_creds.json');
265
+ const credsJson = await fs.readFile(credPath, 'utf8');
266
+ const creds = JSON.parse(credsJson);
267
+ if (creds.refresh_token || creds.access_token) {
268
+ return this.credentialsToOAuthToken(creds);
269
+ }
270
+ return null;
271
+ }, null, // Return null if we can't read the file
272
+ this.name, 'getTokenFromGoogleOAuth');
273
+ }
274
+ /**
275
+ * Migrates tokens from legacy locations to new format
276
+ */
277
+ async migrateFromLegacyTokens() {
278
+ return this.errorHandler.handleGracefully(async () => {
279
+ // Try to get token from existing Google OAuth
280
+ const token = await this.getTokenFromGoogleOAuth();
281
+ if (token && this.tokenStore) {
282
+ try {
283
+ // Save to new location
284
+ await this.tokenStore.saveToken('gemini', token);
285
+ this.logger.debug(() => 'Successfully migrated Gemini token from legacy location');
286
+ return token;
287
+ }
288
+ catch (error) {
289
+ throw OAuthErrorFactory.storageError(this.name, error instanceof Error ? error : undefined, {
290
+ operation: 'migrateToken',
291
+ });
292
+ }
293
+ }
294
+ return token;
295
+ }, null, // Return null if migration fails
296
+ this.name, 'migrateFromLegacyTokens');
297
+ }
298
+ /**
299
+ * Clears tokens from all legacy locations
300
+ */
301
+ async clearLegacyTokens() {
302
+ const legacyPaths = [
303
+ // Legacy OAuth credentials file
304
+ path.join(os.homedir(), '.llxprt', 'oauth_creds.json'),
305
+ // Legacy Google accounts file
306
+ path.join(os.homedir(), '.llxprt', 'google_accounts.json'),
307
+ ];
308
+ // Use Promise.allSettled to continue even if some paths fail
309
+ const results = await Promise.allSettled(legacyPaths.map(async (legacyPath) => {
310
+ try {
311
+ await fs.unlink(legacyPath);
312
+ this.logger.debug(() => `Cleared legacy token file: ${legacyPath}`);
313
+ }
314
+ catch (error) {
315
+ // File doesn't exist or can't be removed - that's fine for legacy cleanup
316
+ this.logger.debug(() => `Could not remove legacy token file ${legacyPath}: ${error}`);
317
+ }
318
+ }));
319
+ // Log any unexpected failures for debugging
320
+ results.forEach((result, index) => {
321
+ if (result.status === 'rejected') {
322
+ this.logger.debug(() => `Legacy cleanup failed for ${legacyPaths[index]}: ${result.reason}`);
323
+ }
324
+ });
31
325
  }
32
326
  }
33
327
  //# sourceMappingURL=gemini-oauth-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gemini-oauth-provider.js","sourceRoot":"","sources":["../../../src/auth/gemini-oauth-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,OAAO,mBAAmB;IAC9B,IAAI,GAAG,QAAQ,CAAC;IACR,YAAY,GAAsB,IAAI,CAAC;IAE/C,KAAK,CAAC,YAAY;QAChB,iEAAiE;QACjE,sEAAsE;QACtE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kDAAkD;QAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;QAE3C,IAAI,SAAS,IAAI,SAAS,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC;YACtC,iCAAiC;YACjC,uCAAuC;YACvC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;CACF"}
1
+ {"version":3,"file":"gemini-oauth-provider.js","sourceRoot":"","sources":["../../../src/auth/gemini-oauth-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * @plan PLAN-20250823-AUTHFIXES.P16
8
+ * @requirement REQ-004.2
9
+ * Migration utilities for OAuth token storage modernization
10
+ *
11
+ * This module handles migration of tokens from legacy storage formats
12
+ * to the new standardized TokenStore persistence system.
13
+ */
14
+ import { OAuthProvider } from './oauth-manager.js';
15
+ import { TokenStore } from '@vybestack/llxprt-code-core';
16
+ /**
17
+ * Migrate any in-memory tokens to persistent storage
18
+ *
19
+ * @param providers - Map of OAuth provider instances
20
+ * @param tokenStore - Token persistence store
21
+ */
22
+ export declare function migrateInMemoryTokens(providers: Map<string, OAuthProvider>, tokenStore: TokenStore): Promise<void>;
23
+ /**
24
+ * Display migration notice to users about OAuth token storage changes
25
+ */
26
+ export declare function showMigrationNotice(): void;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Migrate any in-memory tokens to persistent storage
8
+ *
9
+ * @param providers - Map of OAuth provider instances
10
+ * @param tokenStore - Token persistence store
11
+ */
12
+ export async function migrateInMemoryTokens(providers, tokenStore) {
13
+ for (const [name, provider] of providers) {
14
+ try {
15
+ // Check for in-memory token
16
+ const token = await provider.getToken();
17
+ if (token) {
18
+ const stored = await tokenStore.getToken(name);
19
+ if (!stored) {
20
+ // Migrate to storage
21
+ await tokenStore.saveToken(name, token);
22
+ console.log(`Migrated ${name} token to persistent storage`);
23
+ }
24
+ }
25
+ }
26
+ catch (_error) {
27
+ // Skip providers that don't have valid tokens
28
+ // This is expected during normal operation
29
+ continue;
30
+ }
31
+ }
32
+ }
33
+ /**
34
+ * Display migration notice to users about OAuth token storage changes
35
+ */
36
+ export function showMigrationNotice() {
37
+ console.log(`
38
+ LLXPRT OAuth Token Storage Migration
39
+ ====================================
40
+
41
+ Your OAuth tokens are now stored in standardized locations:
42
+ - Anthropic: ~/.llxprt/oauth/anthropic.json
43
+ - Gemini: ~/.llxprt/oauth/gemini.json
44
+ - Qwen: ~/.llxprt/oauth/qwen.json
45
+
46
+ If you experience authentication issues, please re-login:
47
+ - llxprt auth login anthropic
48
+ - llxprt auth login gemini
49
+ - llxprt auth login qwen
50
+
51
+ Legacy Gemini tokens in ~/.llxprt/oauth_creds.json are no longer used.
52
+ `);
53
+ }
54
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.js","sourceRoot":"","sources":["../../../src/auth/migration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,SAAqC,EACrC,UAAsB;IAEtB,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;QACzC,IAAI,CAAC;YACH,4BAA4B;YAC5B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACxC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,qBAAqB;oBACrB,MAAM,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;oBACxC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,8BAA8B,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,8CAA8C;YAC9C,2CAA2C;YAC3C,SAAS;QACX,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;CAeb,CAAC,CAAC;AACH,CAAC"}
@@ -60,11 +60,29 @@ export declare class OAuthManager {
60
60
  */
61
61
  getAuthStatus(): Promise<AuthStatus[]>;
62
62
  /**
63
+ * @plan PLAN-20250823-AUTHFIXES.P14
64
+ * @requirement REQ-002
65
+ * @pseudocode lines 51-68
63
66
  * Check if authenticated with a specific provider (required by precedence resolver)
64
67
  * @param providerName - Name of the provider
65
68
  * @returns True if authenticated, false otherwise
66
69
  */
67
70
  isAuthenticated(providerName: string): Promise<boolean>;
71
+ /**
72
+ * @plan PLAN-20250823-AUTHFIXES.P14
73
+ * @requirement REQ-002.1
74
+ * @pseudocode lines 4-37
75
+ * Logout from a specific provider by clearing stored tokens
76
+ * @param providerName - Name of the provider to logout from
77
+ */
78
+ logout(providerName: string): Promise<void>;
79
+ /**
80
+ * @plan PLAN-20250823-AUTHFIXES.P14
81
+ * @requirement REQ-002
82
+ * @pseudocode lines 39-49
83
+ * Logout from all providers by clearing all stored tokens
84
+ */
85
+ logoutAll(): Promise<void>;
68
86
  /**
69
87
  * Get OAuth token for a specific provider
70
88
  * Compatible with precedence resolver - returns access token string
@@ -107,4 +125,10 @@ export declare class OAuthManager {
107
125
  * @returns True if compatible, false otherwise
108
126
  */
109
127
  private isQwenCompatibleUrl;
128
+ /**
129
+ * CRITICAL FIX: Clear all auth caches for a provider after logout
130
+ * This method finds and clears auth caches from both BaseProvider and provider-specific implementations
131
+ * @param providerName - Name of the provider to clear caches for
132
+ */
133
+ private clearProviderAuthCaches;
110
134
  }