@vybestack/llxprt-code 0.1.19-beta → 0.1.19

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 (115) hide show
  1. package/README.md +49 -2
  2. package/dist/package.json +3 -3
  3. package/dist/src/auth/anthropic-oauth-provider.d.ts +33 -0
  4. package/dist/src/auth/anthropic-oauth-provider.js +129 -0
  5. package/dist/src/auth/anthropic-oauth-provider.js.map +1 -0
  6. package/dist/src/auth/gemini-oauth-provider.d.ts +15 -0
  7. package/dist/src/auth/gemini-oauth-provider.js +33 -0
  8. package/dist/src/auth/gemini-oauth-provider.js.map +1 -0
  9. package/dist/src/auth/oauth-manager.d.ts +110 -0
  10. package/dist/src/auth/oauth-manager.js +345 -0
  11. package/dist/src/auth/oauth-manager.js.map +1 -0
  12. package/dist/src/auth/oauth-manager.spec.d.ts +6 -0
  13. package/dist/src/auth/oauth-manager.spec.js +523 -0
  14. package/dist/src/auth/oauth-manager.spec.js.map +1 -0
  15. package/dist/src/auth/qwen-oauth-provider.d.ts +14 -0
  16. package/dist/src/auth/qwen-oauth-provider.js +75 -0
  17. package/dist/src/auth/qwen-oauth-provider.js.map +1 -0
  18. package/dist/src/auth/types.d.ts +7 -0
  19. package/dist/src/auth/types.js +7 -0
  20. package/dist/src/auth/types.js.map +1 -0
  21. package/dist/src/config/auth.js +6 -0
  22. package/dist/src/config/auth.js.map +1 -1
  23. package/dist/src/config/config.js +32 -15
  24. package/dist/src/config/config.js.map +1 -1
  25. package/dist/src/config/keyBindings.d.ts +2 -0
  26. package/dist/src/config/keyBindings.js +7 -8
  27. package/dist/src/config/keyBindings.js.map +1 -1
  28. package/dist/src/config/settings.d.ts +3 -62
  29. package/dist/src/config/settings.js.map +1 -1
  30. package/dist/src/config/settingsSchema.d.ts +587 -0
  31. package/dist/src/config/settingsSchema.js +565 -0
  32. package/dist/src/config/settingsSchema.js.map +1 -0
  33. package/dist/src/gemini.js +23 -5
  34. package/dist/src/gemini.js.map +1 -1
  35. package/dist/src/generated/git-commit.d.ts +1 -1
  36. package/dist/src/generated/git-commit.js +1 -1
  37. package/dist/src/providers/providerManagerInstance.d.ts +2 -0
  38. package/dist/src/providers/providerManagerInstance.js +45 -5
  39. package/dist/src/providers/providerManagerInstance.js.map +1 -1
  40. package/dist/src/services/BuiltinCommandLoader.js +2 -0
  41. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  42. package/dist/src/ui/App.js +108 -17
  43. package/dist/src/ui/App.js.map +1 -1
  44. package/dist/src/ui/IdeIntegrationNudge.d.ts +7 -4
  45. package/dist/src/ui/IdeIntegrationNudge.js +26 -6
  46. package/dist/src/ui/IdeIntegrationNudge.js.map +1 -1
  47. package/dist/src/ui/commands/authCommand.d.ts +11 -1
  48. package/dist/src/ui/commands/authCommand.js +153 -48
  49. package/dist/src/ui/commands/authCommand.js.map +1 -1
  50. package/dist/src/ui/commands/diagnosticsCommand.js +94 -10
  51. package/dist/src/ui/commands/diagnosticsCommand.js.map +1 -1
  52. package/dist/src/ui/commands/ideCommand.js +7 -4
  53. package/dist/src/ui/commands/ideCommand.js.map +1 -1
  54. package/dist/src/ui/commands/keyCommand.js +32 -2
  55. package/dist/src/ui/commands/keyCommand.js.map +1 -1
  56. package/dist/src/ui/commands/keyfileCommand.js +15 -12
  57. package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
  58. package/dist/src/ui/commands/modelCommand.js +21 -3
  59. package/dist/src/ui/commands/modelCommand.js.map +1 -1
  60. package/dist/src/ui/commands/providerCommand.js +52 -14
  61. package/dist/src/ui/commands/providerCommand.js.map +1 -1
  62. package/dist/src/ui/commands/setCommand.js +17 -1
  63. package/dist/src/ui/commands/setCommand.js.map +1 -1
  64. package/dist/src/ui/commands/settingsCommand.d.ts +7 -0
  65. package/dist/src/ui/commands/settingsCommand.js +16 -0
  66. package/dist/src/ui/commands/settingsCommand.js.map +1 -0
  67. package/dist/src/ui/commands/toolformatCommand.js +79 -23
  68. package/dist/src/ui/commands/toolformatCommand.js.map +1 -1
  69. package/dist/src/ui/commands/types.d.ts +1 -1
  70. package/dist/src/ui/commands/types.js.map +1 -1
  71. package/dist/src/ui/components/AuthDialog.js +55 -62
  72. package/dist/src/ui/components/AuthDialog.js.map +1 -1
  73. package/dist/src/ui/components/Footer.d.ts +1 -0
  74. package/dist/src/ui/components/Footer.js +2 -2
  75. package/dist/src/ui/components/Footer.js.map +1 -1
  76. package/dist/src/ui/components/InputPrompt.d.ts +1 -0
  77. package/dist/src/ui/components/InputPrompt.js +59 -7
  78. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  79. package/dist/src/ui/components/OAuthCodeDialog.d.ts +13 -0
  80. package/dist/src/ui/components/OAuthCodeDialog.js +52 -0
  81. package/dist/src/ui/components/OAuthCodeDialog.js.map +1 -0
  82. package/dist/src/ui/components/SettingsDialog.d.ts +14 -0
  83. package/dist/src/ui/components/SettingsDialog.js +247 -0
  84. package/dist/src/ui/components/SettingsDialog.js.map +1 -0
  85. package/dist/src/ui/components/ThemeDialog.js +4 -15
  86. package/dist/src/ui/components/ThemeDialog.js.map +1 -1
  87. package/dist/src/ui/components/messages/ToolConfirmationMessage.js +2 -2
  88. package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
  89. package/dist/src/ui/components/shared/text-buffer.d.ts +17 -4
  90. package/dist/src/ui/components/shared/text-buffer.js +224 -70
  91. package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
  92. package/dist/src/ui/components/shared/vim-buffer-actions.js +137 -151
  93. package/dist/src/ui/components/shared/vim-buffer-actions.js.map +1 -1
  94. package/dist/src/ui/hooks/slashCommandProcessor.d.ts +1 -1
  95. package/dist/src/ui/hooks/slashCommandProcessor.js +5 -1
  96. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  97. package/dist/src/ui/hooks/useAuthCommand.js +14 -20
  98. package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
  99. package/dist/src/ui/hooks/useGeminiStream.d.ts +2 -1
  100. package/dist/src/ui/hooks/useGeminiStream.js +67 -25
  101. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  102. package/dist/src/ui/hooks/useSettingsCommand.d.ts +10 -0
  103. package/dist/src/ui/hooks/useSettingsCommand.js +21 -0
  104. package/dist/src/ui/hooks/useSettingsCommand.js.map +1 -0
  105. package/dist/src/ui/reducers/appReducer.d.ts +3 -2
  106. package/dist/src/ui/reducers/appReducer.js +1 -0
  107. package/dist/src/ui/reducers/appReducer.js.map +1 -1
  108. package/dist/src/utils/dialogScopeUtils.d.ts +31 -0
  109. package/dist/src/utils/dialogScopeUtils.js +48 -0
  110. package/dist/src/utils/dialogScopeUtils.js.map +1 -0
  111. package/dist/src/utils/settingsUtils.d.ts +126 -0
  112. package/dist/src/utils/settingsUtils.js +327 -0
  113. package/dist/src/utils/settingsUtils.js.map +1 -0
  114. package/dist/tsconfig.tsbuildinfo +1 -1
  115. package/package.json +3 -3
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # LLxprt Code
2
2
 
3
3
  [![LLxprt Code CI](https://github.com/acoliver/llxprt-code/actions/workflows/ci.yml/badge.svg)](https://github.com/acoliver/llxprt-code/actions/workflows/ci.yml)
4
+  
5
+ [![Mentioned in Awesome Gemini CLI](https://awesome.re/mentioned-badge.svg)](https://github.com/Piebald-AI/awesome-gemini-cli)
4
6
 
5
7
  ![LLxprt Code Screenshot](./docs/assets/llxprt-screenshot.png)
6
8
 
@@ -87,7 +89,26 @@ Direct access to o3, o1, GPT-4.1, and other OpenAI models:
87
89
 
88
90
  ### Using Anthropic
89
91
 
90
- Access Claude Sonnet 4, Claude Opus 4, and other Anthropic models:
92
+ Access Claude Sonnet 4, Claude Opus 4.1, and other Anthropic models:
93
+
94
+ #### Option 1: Log in with Anthropic to use your Claude Pro or Max account
95
+
96
+ Use OAuth authentication to access Claude with your existing Claude Pro or Max subscription:
97
+
98
+ 1. Select the Anthropic provider:
99
+ ```
100
+ /provider anthropic
101
+ ```
102
+ 2. Authenticate with your Claude account:
103
+ ```
104
+ /auth
105
+ ```
106
+ 3. Your browser will open to the Claude authentication page
107
+ 4. Log in and authorize LLxprt Code
108
+ 5. Copy the authorization code shown and paste it back in the terminal
109
+ 6. You're now using your Claude Pro/Max account!
110
+
111
+ #### Option 2: Use an API Key
91
112
 
92
113
  1. Get your API key from [Anthropic](https://console.anthropic.com/account/keys)
93
114
  2. Configure:
@@ -97,6 +118,32 @@ Access Claude Sonnet 4, Claude Opus 4, and other Anthropic models:
97
118
  /model claude-sonnet-4-20250115
98
119
  ```
99
120
 
121
+ ### Using Qwen
122
+
123
+ Access Qwen3-Coder-Pro and other Qwen models for free:
124
+
125
+ #### Option 1: Log in with Qwen (FREE)
126
+
127
+ Use OAuth authentication to access Qwen with your free account:
128
+
129
+ ```
130
+ /auth qwen
131
+ ```
132
+
133
+ Your browser will open to the Qwen authentication page. Log in and authorize LLxprt Code, then copy the authorization code shown and paste it back in the terminal. You're now using Qwen3-Coder-Pro for free!
134
+
135
+ #### Option 2: Use an API Key
136
+
137
+ For advanced users who need API access:
138
+
139
+ 1. Get your API key from [Qwen](https://platform.qwen.ai/)
140
+ 2. Configure:
141
+ ```
142
+ /provider qwen
143
+ /key your-qwen-api-key
144
+ /model qwen3-coder-pro
145
+ ```
146
+
100
147
  ### Using Local Models
101
148
 
102
149
  Run models locally for complete privacy and control. LLxprt Code works with any OpenAI-compatible server.
@@ -277,7 +324,7 @@ Learn more in the [Prompt Configuration Guide](./docs/prompt-configuration.md).
277
324
  - `/baseurl` - Set custom API endpoint
278
325
  - `/key` - Set API key for current session
279
326
  - `/keyfile` - Load API key from file
280
- - `/auth` - Authenticate with Google (for Gemini provider)
327
+ - `/auth` - Authenticate with Google (for Gemini), Anthropic (for Claude), or Qwen
281
328
 
282
329
  ### Troubleshooting
283
330
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vybestack/llxprt-code",
3
- "version": "0.1.19-beta",
3
+ "version": "0.1.19",
4
4
  "description": "LLxprt Code",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "dist"
34
34
  ],
35
35
  "config": {
36
- "sandboxImageUri": "ghcr.io/acoliver/llxprt-code/sandbox:0.1.19-beta"
36
+ "sandboxImageUri": "ghcr.io/acoliver/llxprt-code/sandbox:0.1.19"
37
37
  },
38
38
  "dependencies": {
39
39
  "@anthropic-ai/sdk": "^0.55.1",
@@ -42,7 +42,7 @@
42
42
  "@iarna/toml": "^2.2.5",
43
43
  "@modelcontextprotocol/sdk": "^1.15.1",
44
44
  "@types/update-notifier": "^6.0.8",
45
- "@vybestack/llxprt-code-core": "0.1.19-beta",
45
+ "@vybestack/llxprt-code-core": "0.1.19",
46
46
  "chalk": "^5.3.0",
47
47
  "command-exists": "^1.2.9",
48
48
  "diff": "^7.0.0",
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Anthropic OAuth Provider Implementation
3
+ */
4
+ import { OAuthProvider } from './oauth-manager.js';
5
+ import { OAuthToken } from '@vybestack/llxprt-code-core';
6
+ export declare class AnthropicOAuthProvider implements OAuthProvider {
7
+ name: string;
8
+ private deviceFlow;
9
+ private currentToken;
10
+ private authCodeResolver?;
11
+ private authCodeRejecter?;
12
+ private pendingAuthPromise?;
13
+ constructor();
14
+ /**
15
+ * Wait for authorization code from UI dialog
16
+ */
17
+ waitForAuthCode(): Promise<string>;
18
+ /**
19
+ * Submit authorization code from UI dialog
20
+ */
21
+ submitAuthCode(code: string): void;
22
+ /**
23
+ * Cancel OAuth flow
24
+ */
25
+ cancelAuth(): void;
26
+ initiateAuth(): Promise<void>;
27
+ /**
28
+ * Complete authentication with the authorization code
29
+ */
30
+ completeAuth(authCode: string): Promise<void>;
31
+ getToken(): Promise<OAuthToken | null>;
32
+ refreshIfNeeded(): Promise<OAuthToken | null>;
33
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Anthropic OAuth Provider Implementation
3
+ */
4
+ import { AnthropicDeviceFlow, openBrowserSecurely, shouldLaunchBrowser, } from '@vybestack/llxprt-code-core';
5
+ export class AnthropicOAuthProvider {
6
+ name = 'anthropic';
7
+ deviceFlow;
8
+ currentToken = null;
9
+ authCodeResolver;
10
+ authCodeRejecter;
11
+ pendingAuthPromise;
12
+ constructor() {
13
+ this.deviceFlow = new AnthropicDeviceFlow();
14
+ }
15
+ /**
16
+ * Wait for authorization code from UI dialog
17
+ */
18
+ waitForAuthCode() {
19
+ return new Promise((resolve, reject) => {
20
+ this.authCodeResolver = resolve;
21
+ this.authCodeRejecter = reject;
22
+ });
23
+ }
24
+ /**
25
+ * Submit authorization code from UI dialog
26
+ */
27
+ submitAuthCode(code) {
28
+ if (this.authCodeResolver) {
29
+ this.authCodeResolver(code);
30
+ this.authCodeResolver = undefined;
31
+ this.authCodeRejecter = undefined;
32
+ }
33
+ }
34
+ /**
35
+ * Cancel OAuth flow
36
+ */
37
+ cancelAuth() {
38
+ if (this.authCodeRejecter) {
39
+ this.authCodeRejecter(new Error('OAuth authentication cancelled'));
40
+ this.authCodeResolver = undefined;
41
+ this.authCodeRejecter = undefined;
42
+ }
43
+ }
44
+ async initiateAuth() {
45
+ // Start device flow
46
+ const deviceCodeResponse = await this.deviceFlow.initiateDeviceFlow();
47
+ // Construct the authorization URL
48
+ const authUrl = deviceCodeResponse.verification_uri_complete ||
49
+ `${deviceCodeResponse.verification_uri}?user_code=${deviceCodeResponse.user_code}`;
50
+ // Display user instructions
51
+ console.log('\nAnthropic Claude OAuth Authentication');
52
+ console.log('─'.repeat(40));
53
+ // Try to open browser if appropriate
54
+ if (shouldLaunchBrowser()) {
55
+ console.log('Opening browser for authentication...');
56
+ console.log('If the browser does not open, please visit:');
57
+ console.log(authUrl);
58
+ try {
59
+ await openBrowserSecurely(authUrl);
60
+ }
61
+ catch (_error) {
62
+ // If browser fails to open, just show the URL
63
+ console.log('Failed to open browser automatically.');
64
+ }
65
+ }
66
+ else {
67
+ // In non-interactive environments, just show the URL
68
+ console.log('Visit this URL to authorize:');
69
+ console.log(authUrl);
70
+ }
71
+ console.log('─'.repeat(40));
72
+ // Store the provider name globally so the dialog knows which provider
73
+ global.__oauth_provider =
74
+ 'anthropic';
75
+ // Create a promise that will resolve when the code is entered
76
+ this.pendingAuthPromise = new Promise((resolve, reject) => {
77
+ this.authCodeResolver = resolve;
78
+ this.authCodeRejecter = reject;
79
+ // Set a timeout to prevent hanging forever
80
+ setTimeout(() => {
81
+ reject(new Error('OAuth authentication timed out'));
82
+ }, 5 * 60 * 1000); // 5 minute timeout
83
+ });
84
+ // Signal that we need the OAuth code dialog
85
+ // This needs to be caught by the UI to open the dialog
86
+ global.__oauth_needs_code =
87
+ true;
88
+ // Wait for the code to be entered
89
+ const authCode = await this.pendingAuthPromise;
90
+ // Exchange the code for tokens
91
+ await this.completeAuth(authCode);
92
+ }
93
+ /**
94
+ * Complete authentication with the authorization code
95
+ */
96
+ async completeAuth(authCode) {
97
+ if (!authCode) {
98
+ throw new Error('No authorization code provided');
99
+ }
100
+ // Exchange the authorization code for tokens
101
+ this.currentToken = await this.deviceFlow.exchangeCodeForToken(authCode);
102
+ console.log('Successfully authenticated with Anthropic Claude!');
103
+ }
104
+ async getToken() {
105
+ return this.currentToken;
106
+ }
107
+ async refreshIfNeeded() {
108
+ if (!this.currentToken) {
109
+ return null;
110
+ }
111
+ // Check if token needs refresh (30 second buffer)
112
+ const now = Date.now() / 1000;
113
+ const expiresAt = this.currentToken.expiry;
114
+ if (expiresAt && expiresAt - now < 30) {
115
+ // Token expires soon, refresh it
116
+ if (this.currentToken.refresh_token) {
117
+ try {
118
+ this.currentToken = await this.deviceFlow.refreshToken(this.currentToken.refresh_token);
119
+ }
120
+ catch (error) {
121
+ console.error('Failed to refresh Anthropic token:', error);
122
+ return null;
123
+ }
124
+ }
125
+ }
126
+ return this.currentToken;
127
+ }
128
+ }
129
+ //# sourceMappingURL=anthropic-oauth-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-oauth-provider.js","sourceRoot":"","sources":["../../../src/auth/anthropic-oauth-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Gemini OAuth Provider Implementation
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.
6
+ */
7
+ import { OAuthProvider } from './oauth-manager.js';
8
+ import { OAuthToken } from '@vybestack/llxprt-code-core';
9
+ export declare class GeminiOAuthProvider implements OAuthProvider {
10
+ name: string;
11
+ private currentToken;
12
+ initiateAuth(): Promise<void>;
13
+ getToken(): Promise<OAuthToken | null>;
14
+ refreshIfNeeded(): Promise<OAuthToken | null>;
15
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Gemini OAuth Provider Implementation
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.
6
+ */
7
+ export class GeminiOAuthProvider {
8
+ name = 'gemini';
9
+ currentToken = null;
10
+ 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');
14
+ }
15
+ async getToken() {
16
+ return this.currentToken;
17
+ }
18
+ async refreshIfNeeded() {
19
+ if (!this.currentToken) {
20
+ return null;
21
+ }
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');
29
+ }
30
+ return this.currentToken;
31
+ }
32
+ }
33
+ //# sourceMappingURL=gemini-oauth-provider.js.map
@@ -0,0 +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"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { OAuthToken, AuthStatus, TokenStore } from './types.js';
7
+ import { LoadedSettings } from '../config/settings.js';
8
+ /**
9
+ * Interface for OAuth provider abstraction
10
+ * Each provider (e.g., Google, Qwen) implements this interface
11
+ */
12
+ export interface OAuthProvider {
13
+ /** Provider name (e.g., 'gemini', 'qwen') */
14
+ name: string;
15
+ /**
16
+ * Initiate OAuth authentication flow
17
+ * This starts the device flow or opens browser for auth
18
+ */
19
+ initiateAuth(): Promise<void>;
20
+ /**
21
+ * Get current OAuth token for this provider
22
+ * @returns OAuth token if available, null otherwise
23
+ */
24
+ getToken(): Promise<OAuthToken | null>;
25
+ /**
26
+ * Refresh token if it's expired or about to expire
27
+ * @returns Refreshed token or null if refresh failed
28
+ */
29
+ refreshIfNeeded(): Promise<OAuthToken | null>;
30
+ }
31
+ /**
32
+ * OAuth Manager coordinates multiple OAuth providers
33
+ * Provides unified interface for authentication across providers
34
+ */
35
+ export declare class OAuthManager {
36
+ private providers;
37
+ private tokenStore;
38
+ private settings?;
39
+ private inMemoryOAuthState;
40
+ constructor(tokenStore: TokenStore, settings?: LoadedSettings);
41
+ /**
42
+ * Register an OAuth provider with the manager
43
+ * @param provider - The OAuth provider to register
44
+ */
45
+ registerProvider(provider: OAuthProvider): void;
46
+ /**
47
+ * Get a registered OAuth provider
48
+ * @param name - Provider name
49
+ * @returns OAuth provider or undefined if not registered
50
+ */
51
+ getProvider(name: string): OAuthProvider | undefined;
52
+ /**
53
+ * Authenticate with a specific provider
54
+ * @param providerName - Name of the provider to authenticate with
55
+ */
56
+ authenticate(providerName: string): Promise<void>;
57
+ /**
58
+ * Get authentication status for all registered providers
59
+ * @returns Array of authentication status for each provider
60
+ */
61
+ getAuthStatus(): Promise<AuthStatus[]>;
62
+ /**
63
+ * Check if authenticated with a specific provider (required by precedence resolver)
64
+ * @param providerName - Name of the provider
65
+ * @returns True if authenticated, false otherwise
66
+ */
67
+ isAuthenticated(providerName: string): Promise<boolean>;
68
+ /**
69
+ * Get OAuth token for a specific provider
70
+ * Compatible with precedence resolver - returns access token string
71
+ * @param providerName - Name of the provider
72
+ * @returns Access token string if available, null otherwise
73
+ */
74
+ getToken(providerName: string): Promise<string | null>;
75
+ /**
76
+ * Get OAuth token object for a specific provider
77
+ * @param providerName - Name of the provider
78
+ * @returns OAuth token if available, null otherwise
79
+ */
80
+ getOAuthToken(providerName: string): Promise<OAuthToken | null>;
81
+ /**
82
+ * Get list of all registered provider names
83
+ * @returns Array of provider names
84
+ */
85
+ getSupportedProviders(): string[];
86
+ /**
87
+ * Toggle OAuth enablement for a provider
88
+ * @param providerName - Name of the provider
89
+ * @returns New enablement state (true if enabled, false if disabled)
90
+ */
91
+ toggleOAuthEnabled(providerName: string): Promise<boolean>;
92
+ /**
93
+ * Check if OAuth is enabled for a provider
94
+ * @param providerName - Name of the provider
95
+ * @returns True if OAuth is enabled, false otherwise
96
+ */
97
+ isOAuthEnabled(providerName: string): boolean;
98
+ /**
99
+ * Check for higher priority authentication methods
100
+ * @param providerName - Name of the provider to check
101
+ * @returns String describing higher priority auth method, null if none
102
+ */
103
+ getHigherPriorityAuth(providerName: string): Promise<string | null>;
104
+ /**
105
+ * Check if a URL is compatible with Qwen OAuth
106
+ * @param url - The base URL to check
107
+ * @returns True if compatible, false otherwise
108
+ */
109
+ private isQwenCompatibleUrl;
110
+ }