opencode-gemini-cli-oauth 1.0.0
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/LICENSE +21 -0
- package/README.md +256 -0
- package/dist/auth/account-manager.d.ts +50 -0
- package/dist/auth/account-manager.d.ts.map +1 -0
- package/dist/auth/account-manager.js +142 -0
- package/dist/auth/account-manager.js.map +1 -0
- package/dist/auth/oauth.d.ts +40 -0
- package/dist/auth/oauth.d.ts.map +1 -0
- package/dist/auth/oauth.js +126 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/request-interceptor.d.ts +18 -0
- package/dist/auth/request-interceptor.d.ts.map +1 -0
- package/dist/auth/request-interceptor.js +94 -0
- package/dist/auth/request-interceptor.js.map +1 -0
- package/dist/constants.d.ts +55 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +61 -0
- package/dist/constants.js.map +1 -0
- package/dist/index-minimal.d.ts +2 -0
- package/dist/index-minimal.d.ts.map +1 -0
- package/dist/index-minimal.js +2 -0
- package/dist/index-minimal.js.map +1 -0
- package/dist/index-simple.d.ts +5 -0
- package/dist/index-simple.d.ts.map +1 -0
- package/dist/index-simple.js +5 -0
- package/dist/index-simple.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin-minimal.d.ts +21 -0
- package/dist/plugin-minimal.d.ts.map +1 -0
- package/dist/plugin-minimal.js +27 -0
- package/dist/plugin-minimal.js.map +1 -0
- package/dist/plugin-simple.d.ts +28 -0
- package/dist/plugin-simple.d.ts.map +1 -0
- package/dist/plugin-simple.js +117 -0
- package/dist/plugin-simple.js.map +1 -0
- package/dist/plugin.d.ts +46 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +66 -0
- package/dist/plugin.js.map +1 -0
- package/dist/storage/storage.d.ts +56 -0
- package/dist/storage/storage.d.ts.map +1 -0
- package/dist/storage/storage.js +138 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/types.d.ts +73 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yusuf
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# OpenCode Gemini CLI OAuth Plugin
|
|
2
|
+
|
|
3
|
+
Use Gemini models in OpenCode with your **Google account quota** - no API keys needed!
|
|
4
|
+
|
|
5
|
+
This plugin integrates Gemini CLI's OAuth authentication with OpenCode, allowing you to use Google's free Gemini quota without generating API keys.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- 🔐 **OAuth Authentication** - Reuses Gemini CLI credentials from `~/.gemini/oauth_creds.json`
|
|
10
|
+
- 👥 **Multi-Account Support** - Automatic rotation across multiple Google accounts
|
|
11
|
+
- 🔄 **Auto Token Refresh** - Handles expired tokens seamlessly
|
|
12
|
+
- 🚦 **Rate Limit Handling** - Auto-switches to next account when rate limited
|
|
13
|
+
- 🤝 **Antigravity Compatible** - Works alongside `opencode-antigravity-auth` plugin
|
|
14
|
+
- 🆓 **Free Quota** - Use Google's free tier quota (1,500 requests/day per account)
|
|
15
|
+
|
|
16
|
+
## 📦 Installation
|
|
17
|
+
|
|
18
|
+
### Prerequisites
|
|
19
|
+
|
|
20
|
+
1. **Gemini CLI** must be installed and authenticated:
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g @google/gemini-cli
|
|
23
|
+
gemini auth login # Authenticate with your Google account
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
2. **OpenCode** v1.0.0 or higher
|
|
27
|
+
|
|
28
|
+
### Install Plugin
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Clone repository
|
|
32
|
+
git clone https://github.com/yourusername/opencode-gemini-cli-oauth.git
|
|
33
|
+
cd opencode-gemini-cli-oauth
|
|
34
|
+
|
|
35
|
+
# Install dependencies
|
|
36
|
+
npm install
|
|
37
|
+
|
|
38
|
+
# Build
|
|
39
|
+
npm run build
|
|
40
|
+
|
|
41
|
+
# Install globally
|
|
42
|
+
npm link
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Configure OpenCode
|
|
46
|
+
|
|
47
|
+
Add to `~/.config/opencode/opencode.json`:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"plugin": [
|
|
52
|
+
"opencode-antigravity-auth@beta",
|
|
53
|
+
"opencode-gemini-cli-oauth"
|
|
54
|
+
],
|
|
55
|
+
"provider": {
|
|
56
|
+
"gemini-cli-oauth": {
|
|
57
|
+
"npm": "@ai-sdk/google",
|
|
58
|
+
"models": {
|
|
59
|
+
"gemini-2.5-flash-exp": {
|
|
60
|
+
"name": "Gemini 2.5 Flash (Google Account)",
|
|
61
|
+
"limit": { "context": 1048576, "output": 65536 },
|
|
62
|
+
"modalities": { "input": ["text", "image", "pdf"], "output": ["text"] }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 🚀 Usage
|
|
71
|
+
|
|
72
|
+
### 1. Authenticate with Gemini CLI
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Login with your Google account
|
|
76
|
+
gemini auth login
|
|
77
|
+
|
|
78
|
+
# Verify authentication
|
|
79
|
+
gemini "hello"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 2. Launch OpenCode
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
opencode
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Select Model
|
|
89
|
+
|
|
90
|
+
In OpenCode:
|
|
91
|
+
- Press `Ctrl+P` → "Switch Model"
|
|
92
|
+
- Choose "Gemini 2.5 Flash (Google Account)" or any model with "(Google Account)"
|
|
93
|
+
- Start chatting!
|
|
94
|
+
|
|
95
|
+
## 🔀 3-Way Authentication Options
|
|
96
|
+
|
|
97
|
+
After installing this plugin, you have **3 authentication methods** for Google models:
|
|
98
|
+
|
|
99
|
+
| Method | Provider | Models | Source | Quota |
|
|
100
|
+
|--------|----------|--------|--------|-------|
|
|
101
|
+
| **1. Google Account (OAuth)** | `gemini-cli-oauth` | Gemini 2.5 Flash/Pro, Gemini 2.0 Flash | This plugin | Google account free tier |
|
|
102
|
+
| **2. API Key** | `google-api-key` | Gemini 1.5/2.5 models | Generated from [AI Studio](https://aistudio.google.com/apikey) | API key quota |
|
|
103
|
+
| **3. Antigravity** | `google` | Gemini 3 Pro/Flash, Claude Sonnet/Opus | [opencode-antigravity-auth](https://github.com/NoeFabris/opencode-antigravity-auth) | Antigravity quota |
|
|
104
|
+
|
|
105
|
+
All three can coexist without conflicts!
|
|
106
|
+
|
|
107
|
+
## 👥 Multi-Account Setup
|
|
108
|
+
|
|
109
|
+
To rotate across multiple Google accounts:
|
|
110
|
+
|
|
111
|
+
1. **Authenticate each account** with Gemini CLI:
|
|
112
|
+
```bash
|
|
113
|
+
gemini auth login # Login with account 1
|
|
114
|
+
# Complete OAuth flow
|
|
115
|
+
|
|
116
|
+
# Repeat for more accounts (Gemini CLI will store them)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
2. **Plugin automatically rotates** between accounts when:
|
|
120
|
+
- An account hits rate limit (429 error)
|
|
121
|
+
- Distributing requests evenly
|
|
122
|
+
|
|
123
|
+
3. **Check account pool**:
|
|
124
|
+
```bash
|
|
125
|
+
cat ~/.gemini/opencode-plugin/account_pool.json
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 🔧 How It Works
|
|
129
|
+
|
|
130
|
+
1. **OAuth Token Injection**
|
|
131
|
+
- Plugin reads credentials from `~/.gemini/oauth_creds.json` (created by Gemini CLI)
|
|
132
|
+
- Injects `Authorization: Bearer <access_token>` header to Gemini API requests
|
|
133
|
+
- Removes `?key=` parameter from URLs (OAuth doesn't need it)
|
|
134
|
+
|
|
135
|
+
2. **Request Interception**
|
|
136
|
+
- Only intercepts requests to `generativelanguage.googleapis.com`
|
|
137
|
+
- Other providers (Antigravity, standard Google) are unaffected
|
|
138
|
+
|
|
139
|
+
3. **Token Refresh**
|
|
140
|
+
- Monitors token expiry (`expiry_date` field)
|
|
141
|
+
- Auto-refreshes 5 minutes before expiration
|
|
142
|
+
- Uses `refresh_token` to get new `access_token`
|
|
143
|
+
|
|
144
|
+
4. **Rate Limit Handling**
|
|
145
|
+
- Detects 429 responses
|
|
146
|
+
- Marks account as rate-limited with `retry-after` timestamp
|
|
147
|
+
- Switches to next available account
|
|
148
|
+
- Retries request automatically
|
|
149
|
+
|
|
150
|
+
## 📊 Quota Management
|
|
151
|
+
|
|
152
|
+
**Free Tier Limits (per Google account):**
|
|
153
|
+
- **Requests:** 1,500 requests/day
|
|
154
|
+
- **Tokens:** 1,000,000 tokens/day
|
|
155
|
+
- **RPM:** 15 requests/minute (Gemini 2.5 Flash)
|
|
156
|
+
|
|
157
|
+
**With 5 accounts, you get:**
|
|
158
|
+
- 7,500 requests/day
|
|
159
|
+
- 5,000,000 tokens/day
|
|
160
|
+
- Automatic rotation on rate limits
|
|
161
|
+
|
|
162
|
+
## 🐛 Troubleshooting
|
|
163
|
+
|
|
164
|
+
### "No OAuth credentials found"
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Re-authenticate with Gemini CLI
|
|
168
|
+
gemini auth login
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### "Failed to refresh access token"
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Clear cached credentials and re-auth
|
|
175
|
+
rm ~/.gemini/oauth_creds.json
|
|
176
|
+
gemini auth login
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Plugin not loading
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Check plugin is installed
|
|
183
|
+
npm list -g opencode-gemini-cli-oauth
|
|
184
|
+
|
|
185
|
+
# Re-link if needed
|
|
186
|
+
cd ~/projects/opencode-gemini-cli-oauth
|
|
187
|
+
npm link
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Rate limited on all accounts
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Check account pool status
|
|
194
|
+
cat ~/.gemini/opencode-plugin/account_pool.json
|
|
195
|
+
|
|
196
|
+
# Clear rate limit timestamps
|
|
197
|
+
echo '{"accounts":[],"currentIndex":0}' > ~/.gemini/opencode-plugin/account_pool.json
|
|
198
|
+
|
|
199
|
+
# Or wait for retry-after period to expire
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 🔒 Security Notes
|
|
203
|
+
|
|
204
|
+
1. **OAuth credentials are stored locally** in `~/.gemini/oauth_creds.json`
|
|
205
|
+
2. **Client ID/Secret are public** (safe for "installed applications" per Google OAuth guidelines)
|
|
206
|
+
3. **Tokens auto-refresh** - no manual intervention needed
|
|
207
|
+
4. **No credentials sent to third parties** - direct Google API communication only
|
|
208
|
+
|
|
209
|
+
## 📚 API Reference
|
|
210
|
+
|
|
211
|
+
### Exported Classes
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
import {
|
|
215
|
+
OAuthManager, // OAuth token management
|
|
216
|
+
AccountManager, // Multi-account rotation
|
|
217
|
+
StorageManager, // Credentials storage
|
|
218
|
+
} from 'opencode-gemini-cli-oauth';
|
|
219
|
+
|
|
220
|
+
// Example: Get current access token
|
|
221
|
+
const oauthManager = new OAuthManager();
|
|
222
|
+
const token = await oauthManager.getAccessToken();
|
|
223
|
+
|
|
224
|
+
// Example: Check account pool stats
|
|
225
|
+
const accountManager = new AccountManager();
|
|
226
|
+
const stats = await accountManager.getPoolStats();
|
|
227
|
+
console.log(stats); // { totalAccounts: 5, availableAccounts: 4, rateLimitedAccounts: 1 }
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## 🤝 Contributing
|
|
231
|
+
|
|
232
|
+
Contributions welcome! Please:
|
|
233
|
+
|
|
234
|
+
1. Fork the repository
|
|
235
|
+
2. Create a feature branch
|
|
236
|
+
3. Submit a pull request
|
|
237
|
+
|
|
238
|
+
## 📄 License
|
|
239
|
+
|
|
240
|
+
MIT License - see LICENSE file for details
|
|
241
|
+
|
|
242
|
+
## 🙏 Credits
|
|
243
|
+
|
|
244
|
+
- Built by [@yusuf](https://github.com/yourusername)
|
|
245
|
+
- Inspired by [opencode-antigravity-auth](https://github.com/NoeFabris/opencode-antigravity-auth)
|
|
246
|
+
- Uses [Google Auth Library](https://github.com/googleapis/google-auth-library-nodejs)
|
|
247
|
+
|
|
248
|
+
## 🔗 Related Projects
|
|
249
|
+
|
|
250
|
+
- [Gemini CLI](https://github.com/google/generative-ai-cli) - Official Google Gemini CLI
|
|
251
|
+
- [OpenCode](https://opencode.ai) - AI-powered code editor
|
|
252
|
+
- [OpenCode Antigravity Auth](https://github.com/NoeFabris/opencode-antigravity-auth) - Antigravity integration
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
**Made with ❤️ for the OpenCode community**
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Yusuf
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import type { AccountPoolEntry } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Account manager for multi-account rotation and quota management
|
|
9
|
+
*/
|
|
10
|
+
export declare class AccountManager {
|
|
11
|
+
private oauthManager;
|
|
12
|
+
constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Initialize account pool from Gemini CLI credentials
|
|
15
|
+
*/
|
|
16
|
+
initialize(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Get current account from pool
|
|
19
|
+
*/
|
|
20
|
+
getCurrentAccount(): Promise<AccountPoolEntry | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Get access token for current account
|
|
23
|
+
*/
|
|
24
|
+
getCurrentAccessToken(): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Rotate to next account in pool
|
|
27
|
+
*/
|
|
28
|
+
rotateAccount(): Promise<AccountPoolEntry | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Mark account as rate limited
|
|
31
|
+
*/
|
|
32
|
+
markAccountRateLimited(email: string, retryAfterSeconds: number): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Get next available account (skips rate-limited accounts)
|
|
35
|
+
*/
|
|
36
|
+
getNextAvailableAccount(): Promise<AccountPoolEntry | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Increment request count for current account
|
|
39
|
+
*/
|
|
40
|
+
incrementRequestCount(): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Get account pool statistics
|
|
43
|
+
*/
|
|
44
|
+
getPoolStats(): Promise<{
|
|
45
|
+
totalAccounts: number;
|
|
46
|
+
availableAccounts: number;
|
|
47
|
+
rateLimitedAccounts: number;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=account-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-manager.d.ts","sourceRoot":"","sources":["../../src/auth/account-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAoB,MAAM,aAAa,CAAC;AAEtE;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAe;;IAMnC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiCjC;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAI3D;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC;IAqC9C;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAIvD;;OAEG;IACG,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrF;;OAEG;IACG,uBAAuB,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAoBjE;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5C;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC;QAC5B,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;CAcH"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Yusuf
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import { StorageManager } from '../storage/storage.js';
|
|
7
|
+
import { OAuthManager } from './oauth.js';
|
|
8
|
+
/**
|
|
9
|
+
* Account manager for multi-account rotation and quota management
|
|
10
|
+
*/
|
|
11
|
+
export class AccountManager {
|
|
12
|
+
oauthManager;
|
|
13
|
+
constructor() {
|
|
14
|
+
this.oauthManager = new OAuthManager();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Initialize account pool from Gemini CLI credentials
|
|
18
|
+
*/
|
|
19
|
+
async initialize() {
|
|
20
|
+
const credentials = await StorageManager.readOAuthCredentials();
|
|
21
|
+
if (!credentials) {
|
|
22
|
+
console.warn('⚠️ No OAuth credentials found. Run: gemini auth login');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Get user info
|
|
26
|
+
const userInfo = await this.oauthManager.getUserInfo();
|
|
27
|
+
// Check if account already exists in pool
|
|
28
|
+
const pool = await StorageManager.readAccountPool();
|
|
29
|
+
const existingAccount = pool.accounts.find((acc) => acc.email === userInfo.email);
|
|
30
|
+
if (existingAccount) {
|
|
31
|
+
// Update existing account
|
|
32
|
+
await StorageManager.updateAccountInPool(userInfo.email, {
|
|
33
|
+
credentials,
|
|
34
|
+
lastUsed: Date.now(),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// Add new account
|
|
39
|
+
const newEntry = {
|
|
40
|
+
email: userInfo.email,
|
|
41
|
+
credentials,
|
|
42
|
+
lastUsed: Date.now(),
|
|
43
|
+
requestCount: 0,
|
|
44
|
+
};
|
|
45
|
+
await StorageManager.upsertAccountInPool(newEntry);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get current account from pool
|
|
50
|
+
*/
|
|
51
|
+
async getCurrentAccount() {
|
|
52
|
+
return await StorageManager.getCurrentAccount();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get access token for current account
|
|
56
|
+
*/
|
|
57
|
+
async getCurrentAccessToken() {
|
|
58
|
+
const account = await this.getCurrentAccount();
|
|
59
|
+
if (!account) {
|
|
60
|
+
// Fallback to default OAuth credentials
|
|
61
|
+
return await this.oauthManager.getAccessToken();
|
|
62
|
+
}
|
|
63
|
+
// Check if token needs refresh
|
|
64
|
+
const now = Date.now();
|
|
65
|
+
const expiryTime = account.credentials.expiry_date || 0;
|
|
66
|
+
const needsRefresh = expiryTime - now < 5 * 60 * 1000; // 5 minutes buffer
|
|
67
|
+
if (needsRefresh) {
|
|
68
|
+
const refreshResult = await this.oauthManager.refreshAccessToken(account.credentials.refresh_token);
|
|
69
|
+
if (refreshResult.success && refreshResult.accessToken) {
|
|
70
|
+
// Update account credentials in pool
|
|
71
|
+
const updatedCredentials = {
|
|
72
|
+
...account.credentials,
|
|
73
|
+
access_token: refreshResult.accessToken,
|
|
74
|
+
expiry_date: refreshResult.expiryDate || Date.now() + 3600 * 1000,
|
|
75
|
+
};
|
|
76
|
+
await StorageManager.updateAccountInPool(account.email, {
|
|
77
|
+
credentials: updatedCredentials,
|
|
78
|
+
});
|
|
79
|
+
return refreshResult.accessToken;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return account.credentials.access_token;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Rotate to next account in pool
|
|
86
|
+
*/
|
|
87
|
+
async rotateAccount() {
|
|
88
|
+
return await StorageManager.rotateToNextAccount();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Mark account as rate limited
|
|
92
|
+
*/
|
|
93
|
+
async markAccountRateLimited(email, retryAfterSeconds) {
|
|
94
|
+
const rateLimitUntil = Date.now() + retryAfterSeconds * 1000;
|
|
95
|
+
await StorageManager.updateAccountInPool(email, { rateLimitUntil });
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get next available account (skips rate-limited accounts)
|
|
99
|
+
*/
|
|
100
|
+
async getNextAvailableAccount() {
|
|
101
|
+
const pool = await StorageManager.readAccountPool();
|
|
102
|
+
const now = Date.now();
|
|
103
|
+
// Find first account that is not rate limited
|
|
104
|
+
for (let i = 0; i < pool.accounts.length; i++) {
|
|
105
|
+
const account = pool.accounts[(pool.currentIndex + i) % pool.accounts.length];
|
|
106
|
+
if (!account.rateLimitUntil || account.rateLimitUntil < now) {
|
|
107
|
+
// Update current index
|
|
108
|
+
pool.currentIndex = (pool.currentIndex + i) % pool.accounts.length;
|
|
109
|
+
await StorageManager.writeAccountPool(pool);
|
|
110
|
+
return account;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// All accounts are rate limited
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Increment request count for current account
|
|
118
|
+
*/
|
|
119
|
+
async incrementRequestCount() {
|
|
120
|
+
const account = await this.getCurrentAccount();
|
|
121
|
+
if (account) {
|
|
122
|
+
await StorageManager.updateAccountInPool(account.email, {
|
|
123
|
+
requestCount: account.requestCount + 1,
|
|
124
|
+
lastUsed: Date.now(),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get account pool statistics
|
|
130
|
+
*/
|
|
131
|
+
async getPoolStats() {
|
|
132
|
+
const pool = await StorageManager.readAccountPool();
|
|
133
|
+
const now = Date.now();
|
|
134
|
+
const rateLimitedCount = pool.accounts.filter((acc) => acc.rateLimitUntil && acc.rateLimitUntil > now).length;
|
|
135
|
+
return {
|
|
136
|
+
totalAccounts: pool.accounts.length,
|
|
137
|
+
availableAccounts: pool.accounts.length - rateLimitedCount,
|
|
138
|
+
rateLimitedAccounts: rateLimitedCount,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=account-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-manager.js","sourceRoot":"","sources":["../../src/auth/account-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C;;GAEG;AACH,MAAM,OAAO,cAAc;IACjB,YAAY,CAAe;IAEnC;QACE,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,oBAAoB,EAAE,CAAC;QAEhE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;YACvE,OAAO;QACT,CAAC;QAED,gBAAgB;QAChB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;QAEvD,0CAA0C;QAC1C,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,eAAe,EAAE,CAAC;QACpD,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC;QAElF,IAAI,eAAe,EAAE,CAAC;YACpB,0BAA0B;YAC1B,MAAM,cAAc,CAAC,mBAAmB,CAAC,QAAQ,CAAC,KAAK,EAAE;gBACvD,WAAW;gBACX,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;aACrB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,kBAAkB;YAClB,MAAM,QAAQ,GAAqB;gBACjC,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,WAAW;gBACX,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;gBACpB,YAAY,EAAE,CAAC;aAChB,CAAC;YACF,MAAM,cAAc,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB;QACrB,OAAO,MAAM,cAAc,CAAC,iBAAiB,EAAE,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB;QACzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAE/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,wCAAwC;YACxC,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;QAClD,CAAC;QAED,+BAA+B;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,IAAI,CAAC,CAAC;QACxD,MAAM,YAAY,GAAG,UAAU,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,mBAAmB;QAE1E,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAC9D,OAAO,CAAC,WAAW,CAAC,aAAa,CAClC,CAAC;YAEF,IAAI,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,WAAW,EAAE,CAAC;gBACvD,qCAAqC;gBACrC,MAAM,kBAAkB,GAAqB;oBAC3C,GAAG,OAAO,CAAC,WAAW;oBACtB,YAAY,EAAE,aAAa,CAAC,WAAW;oBACvC,WAAW,EAAE,aAAa,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;iBAClE,CAAC;gBAEF,MAAM,cAAc,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,EAAE;oBACtD,WAAW,EAAE,kBAAkB;iBAChC,CAAC,CAAC;gBAEH,OAAO,aAAa,CAAC,WAAW,CAAC;YACnC,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,OAAO,MAAM,cAAc,CAAC,mBAAmB,EAAE,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,sBAAsB,CAAC,KAAa,EAAE,iBAAyB;QACnE,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,GAAG,IAAI,CAAC;QAC7D,MAAM,cAAc,CAAC,mBAAmB,CAAC,KAAK,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC;IACtE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,uBAAuB;QAC3B,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,eAAe,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,8CAA8C;QAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAE9E,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,cAAc,GAAG,GAAG,EAAE,CAAC;gBAC5D,uBAAuB;gBACvB,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACnE,MAAM,cAAc,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;gBAC5C,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QAED,gCAAgC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB;QACzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/C,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,cAAc,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,EAAE;gBACtD,YAAY,EAAE,OAAO,CAAC,YAAY,GAAG,CAAC;gBACtC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAKhB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,eAAe,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAC3C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,cAAc,GAAG,GAAG,CACxD,CAAC,MAAM,CAAC;QAET,OAAO;YACL,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YACnC,iBAAiB,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,gBAAgB;YAC1D,mBAAmB,EAAE,gBAAgB;SACtC,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Yusuf
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import { OAuth2Client } from 'google-auth-library';
|
|
7
|
+
import type { TokenRefreshResult } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* OAuth authentication manager
|
|
10
|
+
*/
|
|
11
|
+
export declare class OAuthManager {
|
|
12
|
+
private client;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Get access token from stored credentials
|
|
16
|
+
* Automatically refreshes if expired or near expiry
|
|
17
|
+
*/
|
|
18
|
+
getAccessToken(): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Refresh access token using refresh token
|
|
21
|
+
*/
|
|
22
|
+
refreshAccessToken(refreshToken: string, retryCount?: number): Promise<TokenRefreshResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Verify if credentials are valid
|
|
25
|
+
*/
|
|
26
|
+
verifyCredentials(): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Get user info from token
|
|
29
|
+
*/
|
|
30
|
+
getUserInfo(): Promise<{
|
|
31
|
+
email: string;
|
|
32
|
+
name?: string;
|
|
33
|
+
picture?: string;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Create OAuth2Client with credentials
|
|
37
|
+
*/
|
|
38
|
+
createAuthenticatedClient(): Promise<OAuth2Client>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AASnD,OAAO,KAAK,EAAoB,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAExE;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAe;;IAS7B;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IA6BvC;;OAEG;IACG,kBAAkB,CACtB,YAAY,EAAE,MAAM,EACpB,UAAU,SAAI,GACb,OAAO,CAAC,kBAAkB,CAAC;IA0C9B;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAU3C;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAWhF;;OAEG;IACG,yBAAyB,IAAI,OAAO,CAAC,YAAY,CAAC;CAqBzD"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Yusuf
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import { OAuth2Client } from 'google-auth-library';
|
|
7
|
+
import { OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, TOKEN_EXPIRY_BUFFER_MS, MAX_REFRESH_RETRIES, } from '../constants.js';
|
|
8
|
+
import { StorageManager } from '../storage/storage.js';
|
|
9
|
+
/**
|
|
10
|
+
* OAuth authentication manager
|
|
11
|
+
*/
|
|
12
|
+
export class OAuthManager {
|
|
13
|
+
client;
|
|
14
|
+
constructor() {
|
|
15
|
+
this.client = new OAuth2Client({
|
|
16
|
+
clientId: OAUTH_CLIENT_ID,
|
|
17
|
+
clientSecret: OAUTH_CLIENT_SECRET,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get access token from stored credentials
|
|
22
|
+
* Automatically refreshes if expired or near expiry
|
|
23
|
+
*/
|
|
24
|
+
async getAccessToken() {
|
|
25
|
+
const credentials = await StorageManager.readOAuthCredentials();
|
|
26
|
+
if (!credentials) {
|
|
27
|
+
throw new Error('No OAuth credentials found. Please authenticate using Gemini CLI: gemini auth login');
|
|
28
|
+
}
|
|
29
|
+
// Check if token needs refresh
|
|
30
|
+
const now = Date.now();
|
|
31
|
+
const expiryTime = credentials.expiry_date || 0;
|
|
32
|
+
const needsRefresh = expiryTime - now < TOKEN_EXPIRY_BUFFER_MS;
|
|
33
|
+
if (needsRefresh) {
|
|
34
|
+
const refreshResult = await this.refreshAccessToken(credentials.refresh_token);
|
|
35
|
+
if (!refreshResult.success) {
|
|
36
|
+
throw new Error(`Failed to refresh access token: ${refreshResult.error}. Please re-authenticate using: gemini auth login`);
|
|
37
|
+
}
|
|
38
|
+
return refreshResult.accessToken;
|
|
39
|
+
}
|
|
40
|
+
return credentials.access_token;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Refresh access token using refresh token
|
|
44
|
+
*/
|
|
45
|
+
async refreshAccessToken(refreshToken, retryCount = 0) {
|
|
46
|
+
try {
|
|
47
|
+
this.client.setCredentials({ refresh_token: refreshToken });
|
|
48
|
+
const { credentials } = await this.client.refreshAccessToken();
|
|
49
|
+
if (!credentials.access_token) {
|
|
50
|
+
throw new Error('No access token returned from refresh');
|
|
51
|
+
}
|
|
52
|
+
// Update stored credentials
|
|
53
|
+
const existingCreds = await StorageManager.readOAuthCredentials();
|
|
54
|
+
const updatedCreds = {
|
|
55
|
+
...existingCreds,
|
|
56
|
+
access_token: credentials.access_token,
|
|
57
|
+
expiry_date: credentials.expiry_date || Date.now() + 3600 * 1000,
|
|
58
|
+
token_type: credentials.token_type || 'Bearer',
|
|
59
|
+
};
|
|
60
|
+
await StorageManager.writeOAuthCredentials(updatedCreds);
|
|
61
|
+
return {
|
|
62
|
+
success: true,
|
|
63
|
+
accessToken: credentials.access_token,
|
|
64
|
+
expiryDate: credentials.expiry_date || undefined,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
69
|
+
// Retry on transient errors
|
|
70
|
+
if (retryCount < MAX_REFRESH_RETRIES) {
|
|
71
|
+
await new Promise((resolve) => setTimeout(resolve, 1000 * (retryCount + 1)));
|
|
72
|
+
return this.refreshAccessToken(refreshToken, retryCount + 1);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
error: errorMessage,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Verify if credentials are valid
|
|
82
|
+
*/
|
|
83
|
+
async verifyCredentials() {
|
|
84
|
+
try {
|
|
85
|
+
const token = await this.getAccessToken();
|
|
86
|
+
const tokenInfo = await this.client.getTokenInfo(token);
|
|
87
|
+
return !!tokenInfo.email;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get user info from token
|
|
95
|
+
*/
|
|
96
|
+
async getUserInfo() {
|
|
97
|
+
const token = await this.getAccessToken();
|
|
98
|
+
const tokenInfo = await this.client.getTokenInfo(token);
|
|
99
|
+
return {
|
|
100
|
+
email: tokenInfo.email || 'unknown',
|
|
101
|
+
name: undefined,
|
|
102
|
+
picture: undefined,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create OAuth2Client with credentials
|
|
107
|
+
*/
|
|
108
|
+
async createAuthenticatedClient() {
|
|
109
|
+
const credentials = await StorageManager.readOAuthCredentials();
|
|
110
|
+
if (!credentials) {
|
|
111
|
+
throw new Error('No OAuth credentials found');
|
|
112
|
+
}
|
|
113
|
+
const client = new OAuth2Client({
|
|
114
|
+
clientId: OAUTH_CLIENT_ID,
|
|
115
|
+
clientSecret: OAUTH_CLIENT_SECRET,
|
|
116
|
+
});
|
|
117
|
+
client.setCredentials({
|
|
118
|
+
access_token: credentials.access_token,
|
|
119
|
+
refresh_token: credentials.refresh_token,
|
|
120
|
+
expiry_date: credentials.expiry_date,
|
|
121
|
+
token_type: credentials.token_type,
|
|
122
|
+
});
|
|
123
|
+
return client;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Yusuf
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import { AccountManager } from '../auth/account-manager.js';
|
|
7
|
+
/**
|
|
8
|
+
* Create authenticated fetch function with OAuth token injection
|
|
9
|
+
*/
|
|
10
|
+
export declare function createAuthenticatedFetch(accountManager: AccountManager): typeof fetch;
|
|
11
|
+
/**
|
|
12
|
+
* Create request interceptor for OpenCode plugin
|
|
13
|
+
*/
|
|
14
|
+
export declare function createRequestInterceptor(): Promise<{
|
|
15
|
+
fetch: typeof fetch;
|
|
16
|
+
accountManager: AccountManager;
|
|
17
|
+
}>;
|
|
18
|
+
//# sourceMappingURL=request-interceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-interceptor.d.ts","sourceRoot":"","sources":["../../src/auth/request-interceptor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AA0B5D;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,KAAK,CA6DrF;AAED;;GAEG;AACH,wBAAsB,wBAAwB;;;GAkB7C"}
|