@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.
- package/README.md +49 -2
- package/dist/package.json +3 -3
- package/dist/src/auth/anthropic-oauth-provider.d.ts +33 -0
- package/dist/src/auth/anthropic-oauth-provider.js +129 -0
- package/dist/src/auth/anthropic-oauth-provider.js.map +1 -0
- package/dist/src/auth/gemini-oauth-provider.d.ts +15 -0
- package/dist/src/auth/gemini-oauth-provider.js +33 -0
- package/dist/src/auth/gemini-oauth-provider.js.map +1 -0
- package/dist/src/auth/oauth-manager.d.ts +110 -0
- package/dist/src/auth/oauth-manager.js +345 -0
- package/dist/src/auth/oauth-manager.js.map +1 -0
- package/dist/src/auth/oauth-manager.spec.d.ts +6 -0
- package/dist/src/auth/oauth-manager.spec.js +523 -0
- package/dist/src/auth/oauth-manager.spec.js.map +1 -0
- package/dist/src/auth/qwen-oauth-provider.d.ts +14 -0
- package/dist/src/auth/qwen-oauth-provider.js +75 -0
- package/dist/src/auth/qwen-oauth-provider.js.map +1 -0
- package/dist/src/auth/types.d.ts +7 -0
- package/dist/src/auth/types.js +7 -0
- package/dist/src/auth/types.js.map +1 -0
- package/dist/src/config/auth.js +6 -0
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/config.js +32 -15
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/keyBindings.d.ts +2 -0
- package/dist/src/config/keyBindings.js +7 -8
- package/dist/src/config/keyBindings.js.map +1 -1
- package/dist/src/config/settings.d.ts +3 -62
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +587 -0
- package/dist/src/config/settingsSchema.js +565 -0
- package/dist/src/config/settingsSchema.js.map +1 -0
- package/dist/src/gemini.js +23 -5
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/providers/providerManagerInstance.d.ts +2 -0
- package/dist/src/providers/providerManagerInstance.js +45 -5
- package/dist/src/providers/providerManagerInstance.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +2 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/ui/App.js +108 -17
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/IdeIntegrationNudge.d.ts +7 -4
- package/dist/src/ui/IdeIntegrationNudge.js +26 -6
- package/dist/src/ui/IdeIntegrationNudge.js.map +1 -1
- package/dist/src/ui/commands/authCommand.d.ts +11 -1
- package/dist/src/ui/commands/authCommand.js +153 -48
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/diagnosticsCommand.js +94 -10
- package/dist/src/ui/commands/diagnosticsCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +7 -4
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.js +32 -2
- package/dist/src/ui/commands/keyCommand.js.map +1 -1
- package/dist/src/ui/commands/keyfileCommand.js +15 -12
- package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
- package/dist/src/ui/commands/modelCommand.js +21 -3
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/providerCommand.js +52 -14
- package/dist/src/ui/commands/providerCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.js +17 -1
- package/dist/src/ui/commands/setCommand.js.map +1 -1
- package/dist/src/ui/commands/settingsCommand.d.ts +7 -0
- package/dist/src/ui/commands/settingsCommand.js +16 -0
- package/dist/src/ui/commands/settingsCommand.js.map +1 -0
- package/dist/src/ui/commands/toolformatCommand.js +79 -23
- package/dist/src/ui/commands/toolformatCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +1 -1
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.js +55 -62
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/Footer.d.ts +1 -0
- package/dist/src/ui/components/Footer.js +2 -2
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.d.ts +1 -0
- package/dist/src/ui/components/InputPrompt.js +59 -7
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/OAuthCodeDialog.d.ts +13 -0
- package/dist/src/ui/components/OAuthCodeDialog.js +52 -0
- package/dist/src/ui/components/OAuthCodeDialog.js.map +1 -0
- package/dist/src/ui/components/SettingsDialog.d.ts +14 -0
- package/dist/src/ui/components/SettingsDialog.js +247 -0
- package/dist/src/ui/components/SettingsDialog.js.map +1 -0
- package/dist/src/ui/components/ThemeDialog.js +4 -15
- package/dist/src/ui/components/ThemeDialog.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +2 -2
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.d.ts +17 -4
- package/dist/src/ui/components/shared/text-buffer.js +224 -70
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/vim-buffer-actions.js +137 -151
- package/dist/src/ui/components/shared/vim-buffer-actions.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js +5 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAuthCommand.js +14 -20
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.d.ts +2 -1
- package/dist/src/ui/hooks/useGeminiStream.js +67 -25
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useSettingsCommand.d.ts +10 -0
- package/dist/src/ui/hooks/useSettingsCommand.js +21 -0
- package/dist/src/ui/hooks/useSettingsCommand.js.map +1 -0
- package/dist/src/ui/reducers/appReducer.d.ts +3 -2
- package/dist/src/ui/reducers/appReducer.js +1 -0
- package/dist/src/ui/reducers/appReducer.js.map +1 -1
- package/dist/src/utils/dialogScopeUtils.d.ts +31 -0
- package/dist/src/utils/dialogScopeUtils.js +48 -0
- package/dist/src/utils/dialogScopeUtils.js.map +1 -0
- package/dist/src/utils/settingsUtils.d.ts +126 -0
- package/dist/src/utils/settingsUtils.js +327 -0
- package/dist/src/utils/settingsUtils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# LLxprt Code
|
2
2
|
|
3
3
|
[](https://github.com/acoliver/llxprt-code/actions/workflows/ci.yml)
|
4
|
+
|
5
|
+
[](https://github.com/Piebald-AI/awesome-gemini-cli)
|
4
6
|
|
5
7
|

|
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
|
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
|
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
|
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
|
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
|
+
}
|