funolio-agent 1.0.4 → 1.0.6

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 (50) hide show
  1. package/dist/auth/anthropic-subscription.d.ts +29 -9
  2. package/dist/auth/anthropic-subscription.d.ts.map +1 -1
  3. package/dist/auth/anthropic-subscription.js +133 -12
  4. package/dist/auth/anthropic-subscription.js.map +1 -1
  5. package/dist/auth/auto-detect.d.ts +6 -28
  6. package/dist/auth/auto-detect.d.ts.map +1 -1
  7. package/dist/auth/auto-detect.js +200 -57
  8. package/dist/auth/auto-detect.js.map +1 -1
  9. package/dist/auth/credential-reader.d.ts +4 -24
  10. package/dist/auth/credential-reader.d.ts.map +1 -1
  11. package/dist/auth/credential-reader.js +256 -31
  12. package/dist/auth/credential-reader.js.map +1 -1
  13. package/dist/auth/credential-status.d.ts +27 -7
  14. package/dist/auth/credential-status.d.ts.map +1 -1
  15. package/dist/auth/credential-status.js +95 -7
  16. package/dist/auth/credential-status.js.map +1 -1
  17. package/dist/auth/index.d.ts +2 -9
  18. package/dist/auth/index.d.ts.map +1 -1
  19. package/dist/auth/index.js +10 -10
  20. package/dist/auth/index.js.map +1 -1
  21. package/dist/auth/subscription-runtime.d.ts +23 -19
  22. package/dist/auth/subscription-runtime.d.ts.map +1 -1
  23. package/dist/auth/subscription-runtime.js +292 -24
  24. package/dist/auth/subscription-runtime.js.map +1 -1
  25. package/dist/auth/token-refresh.d.ts +28 -19
  26. package/dist/auth/token-refresh.d.ts.map +1 -1
  27. package/dist/auth/token-refresh.js +464 -26
  28. package/dist/auth/token-refresh.js.map +1 -1
  29. package/dist/bot-manager.d.ts +6 -6
  30. package/dist/bot-manager.d.ts.map +1 -1
  31. package/dist/bot-manager.js +61 -26
  32. package/dist/bot-manager.js.map +1 -1
  33. package/dist/commands/start.d.ts.map +1 -1
  34. package/dist/commands/start.js +223 -49
  35. package/dist/commands/start.js.map +1 -1
  36. package/dist/message-loop.d.ts +10 -2
  37. package/dist/message-loop.d.ts.map +1 -1
  38. package/dist/message-loop.js +249 -184
  39. package/dist/message-loop.js.map +1 -1
  40. package/dist/providers/anthropic.d.ts +5 -0
  41. package/dist/providers/anthropic.d.ts.map +1 -1
  42. package/dist/providers/anthropic.js +48 -13
  43. package/dist/providers/anthropic.js.map +1 -1
  44. package/dist/providers/index.d.ts +2 -2
  45. package/dist/providers/index.d.ts.map +1 -1
  46. package/dist/wizard-support.d.ts +2 -2
  47. package/dist/wizard-support.d.ts.map +1 -1
  48. package/dist/wizard-support.js +93 -80
  49. package/dist/wizard-support.js.map +1 -1
  50. package/package.json +1 -1
@@ -1,28 +1,80 @@
1
1
  "use strict";
2
2
  /**
3
- * REMOVED: OAuth token refresh has been removed.
3
+ * Token Refresh Module Funolio Agent OAuth System
4
4
  *
5
- * Connection to LLM providers is now exclusively via:
6
- * 1. CLI providers (claude-cli, codex-cli) handle their own auth/refresh
7
- * 2. API key (BYOK) API keys don't expire
5
+ * For Anthropic tokens: delegates refresh to the Funolio server (cloud mode)
6
+ * to prevent race conditions with single-use refresh tokens.
7
+ * The server is the sole authority for refreshing with Anthropic.
8
8
  *
9
- * The token-refresh module previously handled:
10
- * - Anthropic OAuth token refresh (single-use rotation)
11
- * - OpenAI OAuth token refresh
12
- * - Google/Gemini OAuth token refresh
13
- * - Server-delegated token refresh (cloud mode)
9
+ * For OpenAI/Gemini: refreshes directly (their tokens aren't single-use).
14
10
  *
15
- * CLI providers now handle all token lifecycle internally.
11
+ * Config: `tokenRefreshAuthority` in ~/.funolio/config.json
12
+ * - "cloud" (default): Server refreshes Anthropic tokens
13
+ * - "local": Legacy direct refresh (for self-hosted without a server)
16
14
  */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
17
48
  Object.defineProperty(exports, "__esModule", { value: true });
18
49
  exports.TokenRefreshError = void 0;
19
- exports.needsRefresh = needsRefresh;
20
- exports.refreshToken = refreshToken;
21
50
  exports.refreshOpenAIToken = refreshOpenAIToken;
22
51
  exports.refreshGeminiToken = refreshGeminiToken;
23
52
  exports.writeClaudeCredentials = writeClaudeCredentials;
24
53
  exports.writeCodexCredentials = writeCodexCredentials;
25
54
  exports.seedServerWithToken = seedServerWithToken;
55
+ exports.needsRefresh = needsRefresh;
56
+ exports.refreshToken = refreshToken;
57
+ const fs = __importStar(require("fs"));
58
+ const path = __importStar(require("path"));
59
+ const os = __importStar(require("os"));
60
+ const crypto = __importStar(require("crypto"));
61
+ const child_process_1 = require("child_process");
62
+ const credential_reader_1 = require("./credential-reader");
63
+ const config_1 = require("../config");
64
+ // ── Constants ───────────────────────────────────────────────────────────────
65
+ const REFRESH_TIMEOUT_MS = 30_000;
66
+ const EXPIRY_BUFFER_MS = 5 * 60_000; // 5 minutes
67
+ // Anthropic OAuth (used only in local/fallback mode)
68
+ const ANTHROPIC_TOKEN_URL = 'https://platform.claude.com/v1/oauth/token';
69
+ const ANTHROPIC_CLIENT_ID = atob('OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl');
70
+ // OpenAI Codex OAuth (from pi-ai/src/utils/oauth/openai-codex.ts)
71
+ const OPENAI_TOKEN_URL = 'https://auth.openai.com/oauth/token';
72
+ const OPENAI_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann';
73
+ // Google Gemini CLI OAuth (from pi-ai/src/utils/oauth/google-gemini-cli.ts)
74
+ const GEMINI_TOKEN_URL = 'https://oauth2.googleapis.com/token';
75
+ const GEMINI_CLIENT_ID = atob('NjgxMjU1ODA5Mzk1LW9vOGZ0Mm9wcmRybnA5ZTNhcWY2YXYzaG1kaWIxMzVqLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29t');
76
+ const GEMINI_CLIENT_SECRET = atob('R09DU1BYLTR1SGdNUG0tMW83U2stZ2VWNkN1NWNsWEZzeGw=');
77
+ // ── Types ───────────────────────────────────────────────────────────────────
26
78
  class TokenRefreshError extends Error {
27
79
  provider;
28
80
  httpStatus;
@@ -34,22 +86,408 @@ class TokenRefreshError extends Error {
34
86
  }
35
87
  }
36
88
  exports.TokenRefreshError = TokenRefreshError;
37
- /** @deprecated Always returns false. API keys don't expire. */
38
- function needsRefresh(_credential) {
39
- return false;
89
+ // ── Config Reader ───────────────────────────────────────────────────────────
90
+ /**
91
+ * Read the token refresh authority from config.
92
+ * Returns "cloud" (default) or "local".
93
+ */
94
+ function getTokenRefreshAuthority() {
95
+ try {
96
+ const configPath = path.join(os.homedir(), '.funolio', 'config.json');
97
+ if (fs.existsSync(configPath)) {
98
+ const cfg = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
99
+ if (cfg.tokenRefreshAuthority === 'local')
100
+ return 'local';
101
+ }
102
+ }
103
+ catch { /* default to cloud */ }
104
+ return 'cloud';
105
+ }
106
+ /**
107
+ * Read the bot API key from config (bb_sk_ prefixed).
108
+ * Needed for authenticating with the server's token-refresh endpoint.
109
+ */
110
+ function getBotApiKey() {
111
+ try {
112
+ const configPath = path.join(os.homedir(), '.funolio', 'config.json');
113
+ if (fs.existsSync(configPath)) {
114
+ const cfg = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
115
+ // Try auth.token first (set during `funolio-agent init`)
116
+ if (cfg.auth?.token)
117
+ return cfg.auth.token;
118
+ }
119
+ }
120
+ catch { /* ignore */ }
121
+ return null;
122
+ }
123
+ // ── Retry Helper ────────────────────────────────────────────────────────────
124
+ async function withRetry(fn, provider, maxAttempts = 3) {
125
+ let lastError;
126
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
127
+ try {
128
+ return await fn();
129
+ }
130
+ catch (err) {
131
+ lastError = err;
132
+ const normalized = String(err?.message || '').toLowerCase();
133
+ const nonRetryable = normalized.includes('invalid_grant')
134
+ || normalized.includes('refresh token not found or invalid')
135
+ || /\(400\)/.test(normalized);
136
+ if (nonRetryable) {
137
+ break;
138
+ }
139
+ if (attempt < maxAttempts) {
140
+ const delayMs = Math.pow(2, attempt - 1) * 1000;
141
+ console.log(`[token-refresh] ${provider} refresh attempt ${attempt}/${maxAttempts} failed, retrying in ${delayMs}ms...`);
142
+ await new Promise(resolve => setTimeout(resolve, delayMs));
143
+ }
144
+ }
145
+ }
146
+ const statusMatch = lastError?.message?.match(/\((\d{3})\)/);
147
+ const httpStatus = statusMatch ? parseInt(statusMatch[1], 10) : undefined;
148
+ throw new TokenRefreshError(provider, `${provider} token refresh failed after ${maxAttempts} attempts: ${lastError?.message}`, httpStatus);
149
+ }
150
+ // ── Fetch with Timeout ──────────────────────────────────────────────────────
151
+ async function fetchWithTimeout(url, init, timeoutMs = REFRESH_TIMEOUT_MS) {
152
+ const controller = new AbortController();
153
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
154
+ try {
155
+ return await fetch(url, { ...init, signal: controller.signal });
156
+ }
157
+ finally {
158
+ clearTimeout(timer);
159
+ }
160
+ }
161
+ // ── Cloud Refresh (via Funolio Server) ──────────────────────────────────────
162
+ /**
163
+ * Refresh an Anthropic token via the Funolio server.
164
+ * The server holds the refresh token and is the sole authority for
165
+ * exchanging it with Anthropic. This prevents race conditions.
166
+ *
167
+ * Returns updated credential with new access token (refresh token unchanged
168
+ * on the agent side — we don't need it).
169
+ */
170
+ async function refreshViaServer(credential) {
171
+ const apiKey = getBotApiKey();
172
+ if (!apiKey) {
173
+ throw new TokenRefreshError(credential.provider, 'No bot API key found in config. Run `funolio-agent init` to set up, or set tokenRefreshAuthority to "local".');
174
+ }
175
+ const serverUrl = process.env.FUNOLIO_API_URL || config_1.FUNOLIO_API_URL;
176
+ const url = `${serverUrl}/api/v1/bot/token-refresh`;
177
+ console.log(`[token-refresh] Requesting ${credential.provider} token refresh from server...`);
178
+ const response = await fetchWithTimeout(url, {
179
+ method: 'POST',
180
+ headers: {
181
+ 'Authorization': `Bearer ${apiKey}`,
182
+ 'Content-Type': 'application/json',
183
+ 'Accept': 'application/json',
184
+ },
185
+ body: JSON.stringify({ provider: credential.provider }),
186
+ });
187
+ if (!response.ok) {
188
+ const body = await response.text().catch(() => '');
189
+ throw new TokenRefreshError(credential.provider, `Server token refresh failed (${response.status}): ${body}`, response.status);
190
+ }
191
+ const data = await response.json();
192
+ if (!data.accessToken) {
193
+ throw new TokenRefreshError(credential.provider, 'Server returned no accessToken');
194
+ }
195
+ console.log(`[token-refresh] Server refresh successful for ${credential.provider}, expires: ${new Date(data.expiresAt).toISOString()}`);
196
+ return {
197
+ ...credential,
198
+ accessToken: data.accessToken,
199
+ // Keep local refreshToken as-is — we don't use it in cloud mode,
200
+ // but preserve it for potential fallback to local mode.
201
+ expiresAt: data.expiresAt,
202
+ };
203
+ }
204
+ // ── Local Refresh Functions (legacy / fallback) ─────────────────────────────
205
+ /**
206
+ * Refresh Anthropic token directly (local mode only).
207
+ * WARNING: This consumes the single-use refresh token. Only use when
208
+ * tokenRefreshAuthority is "local" (self-hosted without a server).
209
+ */
210
+ async function refreshAnthropicTokenLocal(credential) {
211
+ const response = await fetchWithTimeout(ANTHROPIC_TOKEN_URL, {
212
+ method: 'POST',
213
+ headers: {
214
+ 'Content-Type': 'application/json',
215
+ 'Accept': 'application/json',
216
+ },
217
+ body: JSON.stringify({
218
+ grant_type: 'refresh_token',
219
+ client_id: ANTHROPIC_CLIENT_ID,
220
+ refresh_token: credential.refreshToken,
221
+ }),
222
+ });
223
+ if (!response.ok) {
224
+ const body = await response.text().catch(() => '');
225
+ throw new Error(`Anthropic token refresh failed (${response.status}): ${body}`);
226
+ }
227
+ const data = (await response.json());
228
+ const expiresAt = Date.now() + data.expires_in * 1000;
229
+ console.log(`[token-refresh] Anthropic local refresh successful, new expiry: ${new Date(expiresAt).toISOString()}`);
230
+ return {
231
+ ...credential,
232
+ accessToken: data.access_token,
233
+ refreshToken: data.refresh_token,
234
+ expiresAt,
235
+ };
236
+ }
237
+ async function refreshOpenAIToken(credential) {
238
+ const response = await fetchWithTimeout(OPENAI_TOKEN_URL, {
239
+ method: 'POST',
240
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
241
+ body: new URLSearchParams({
242
+ grant_type: 'refresh_token',
243
+ refresh_token: credential.refreshToken,
244
+ client_id: OPENAI_CLIENT_ID,
245
+ }),
246
+ });
247
+ if (!response.ok) {
248
+ const body = await response.text().catch(() => '');
249
+ throw new Error(`OpenAI token refresh failed (${response.status}): ${body}`);
250
+ }
251
+ const data = (await response.json());
252
+ const expiresAt = Date.now() + data.expires_in * 1000;
253
+ console.log(`[token-refresh] OpenAI refresh successful, new expiry: ${new Date(expiresAt).toISOString()}`);
254
+ return {
255
+ ...credential,
256
+ accessToken: data.access_token,
257
+ refreshToken: data.refresh_token,
258
+ expiresAt,
259
+ ...(credential.accountId ? { accountId: credential.accountId } : {}),
260
+ ...(data.id_token ? { idToken: data.id_token } : (credential.idToken ? { idToken: credential.idToken } : {})),
261
+ };
262
+ }
263
+ async function refreshGeminiToken(credential) {
264
+ const response = await fetchWithTimeout(GEMINI_TOKEN_URL, {
265
+ method: 'POST',
266
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
267
+ body: new URLSearchParams({
268
+ grant_type: 'refresh_token',
269
+ refresh_token: credential.refreshToken,
270
+ client_id: GEMINI_CLIENT_ID,
271
+ client_secret: GEMINI_CLIENT_SECRET,
272
+ }),
273
+ });
274
+ if (!response.ok) {
275
+ const body = await response.text().catch(() => '');
276
+ throw new Error(`Gemini token refresh failed (${response.status}): ${body}`);
277
+ }
278
+ const data = (await response.json());
279
+ const expiresAt = Date.now() + data.expires_in * 1000;
280
+ console.log(`[token-refresh] Gemini refresh successful, new expiry: ${new Date(expiresAt).toISOString()}`);
281
+ return {
282
+ ...credential,
283
+ accessToken: data.access_token,
284
+ refreshToken: data.refresh_token || credential.refreshToken,
285
+ expiresAt,
286
+ ...(credential.projectId ? { projectId: credential.projectId } : {}),
287
+ };
288
+ }
289
+ // ── Credential Writers ──────────────────────────────────────────────────────
290
+ function writeClaudeCredentials(credential) {
291
+ try {
292
+ const credPath = path.join(os.homedir(), '.claude', '.credentials.json');
293
+ const dir = path.dirname(credPath);
294
+ if (!fs.existsSync(dir))
295
+ fs.mkdirSync(dir, { recursive: true });
296
+ let existing = {};
297
+ try {
298
+ existing = JSON.parse(fs.readFileSync(credPath, 'utf-8'));
299
+ }
300
+ catch { /* new file */ }
301
+ // Merge with existing claudeAiOauth to preserve fields like scopes,
302
+ // subscriptionType, rateLimitTier that were set during initial auth.
303
+ const prev = (existing.claudeAiOauth && typeof existing.claudeAiOauth === 'object')
304
+ ? existing.claudeAiOauth
305
+ : {};
306
+ existing.claudeAiOauth = {
307
+ ...prev,
308
+ accessToken: credential.accessToken,
309
+ refreshToken: credential.refreshToken,
310
+ expiresAt: credential.expiresAt,
311
+ };
312
+ fs.writeFileSync(credPath, JSON.stringify(existing, null, 2), 'utf-8');
313
+ console.log('[token-refresh] Wrote updated Claude credentials to disk');
314
+ if (process.platform === 'darwin') {
315
+ try {
316
+ const json = JSON.stringify(existing);
317
+ (0, child_process_1.execSync)(`security add-generic-password -U -s "Claude Code-credentials" -a "Claude Code" -w ${JSON.stringify(json)}`, { timeout: 5000, stdio: 'pipe' });
318
+ console.log('[token-refresh] Updated macOS Keychain for Claude');
319
+ }
320
+ catch { /* Non-fatal */ }
321
+ }
322
+ return true;
323
+ }
324
+ catch (err) {
325
+ console.error('[token-refresh] Failed to write Claude credentials:', err instanceof Error ? err.message : err);
326
+ return false;
327
+ }
328
+ }
329
+ function writeCodexCredentials(credential) {
330
+ try {
331
+ const codexHome = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
332
+ const authPath = path.join(codexHome, 'auth.json');
333
+ if (!fs.existsSync(codexHome))
334
+ fs.mkdirSync(codexHome, { recursive: true });
335
+ let existing = {};
336
+ try {
337
+ existing = JSON.parse(fs.readFileSync(authPath, 'utf-8'));
338
+ }
339
+ catch { /* new file */ }
340
+ const existingTokens = existing.tokens || {};
341
+ existing.tokens = {
342
+ ...existingTokens,
343
+ access_token: credential.accessToken,
344
+ refresh_token: credential.refreshToken,
345
+ ...(credential.accountId
346
+ ? { account_id: credential.accountId }
347
+ : (existingTokens.account_id ? { account_id: String(existingTokens.account_id) } : {})),
348
+ ...(credential.idToken
349
+ ? { id_token: credential.idToken }
350
+ : (existingTokens.id_token ? { id_token: String(existingTokens.id_token) } : {})),
351
+ };
352
+ fs.writeFileSync(authPath, JSON.stringify(existing, null, 2), 'utf-8');
353
+ console.log('[token-refresh] Wrote updated Codex credentials to disk');
354
+ if (process.platform === 'darwin') {
355
+ try {
356
+ const account = crypto.createHash('sha256').update(codexHome).digest('hex').slice(0, 16);
357
+ const json = JSON.stringify(existing);
358
+ (0, child_process_1.execSync)(`security add-generic-password -U -s "Codex Auth" -a ${JSON.stringify(account)} -w ${JSON.stringify(json)}`, { timeout: 5000, stdio: 'pipe' });
359
+ console.log('[token-refresh] Updated macOS Keychain for Codex');
360
+ }
361
+ catch { /* Non-fatal */ }
362
+ }
363
+ return true;
364
+ }
365
+ catch (err) {
366
+ console.error('[token-refresh] Failed to write Codex credentials:', err instanceof Error ? err.message : err);
367
+ return false;
368
+ }
369
+ }
370
+ function writeGeminiCredentials(credential) {
371
+ try {
372
+ const adcPath = path.join(os.homedir(), '.config', 'gcloud', 'application_default_credentials.json');
373
+ let existing = {};
374
+ try {
375
+ existing = JSON.parse(fs.readFileSync(adcPath, 'utf-8'));
376
+ }
377
+ catch { /* skip */ }
378
+ existing.access_token = credential.accessToken;
379
+ if (credential.refreshToken) {
380
+ existing.refresh_token = credential.refreshToken;
381
+ }
382
+ fs.writeFileSync(adcPath, JSON.stringify(existing, null, 2), 'utf-8');
383
+ console.log('[token-refresh] Wrote updated Gemini ADC credentials to disk');
384
+ return true;
385
+ }
386
+ catch (err) {
387
+ console.error('[token-refresh] Failed to write Gemini credentials:', err instanceof Error ? err.message : err);
388
+ return false;
389
+ }
40
390
  }
41
- /** @deprecated Always throws. Use CLI providers or API keys instead. */
42
- async function refreshToken(_credential) {
43
- throw new TokenRefreshError(_credential.provider, 'OAuth token refresh has been removed. Use CLI providers (claude-cli, codex-cli) or API keys instead.');
391
+ // ── Server Token Seeding ────────────────────────────────────────────────────
392
+ /**
393
+ * Push a fresh credential to the Funolio server so it can perform
394
+ * server-side refresh later. Fire-and-forget after local refresh.
395
+ */
396
+ async function seedServerWithToken(credential) {
397
+ const apiKey = getBotApiKey();
398
+ if (!apiKey)
399
+ return false;
400
+ const serverUrl = process.env.FUNOLIO_API_URL || config_1.FUNOLIO_API_URL;
401
+ try {
402
+ const res = await fetchWithTimeout(`${serverUrl}/api/v1/bot/token-seed`, {
403
+ method: 'POST',
404
+ headers: {
405
+ 'Authorization': `Bearer ${apiKey}`,
406
+ 'Content-Type': 'application/json',
407
+ },
408
+ body: JSON.stringify({
409
+ provider: credential.provider,
410
+ accessToken: credential.accessToken,
411
+ refreshToken: credential.refreshToken,
412
+ expiresAt: credential.expiresAt,
413
+ }),
414
+ });
415
+ if (!res.ok) {
416
+ console.warn(`[token-seed] Server seed failed (${res.status})`);
417
+ return false;
418
+ }
419
+ console.log(`[token-seed] Successfully seeded server with ${credential.provider} token`);
420
+ return true;
421
+ }
422
+ catch (err) {
423
+ console.warn(`[token-seed] Failed: ${err.message}`);
424
+ return false;
425
+ }
44
426
  }
45
- // Re-export stubs for any remaining import references
46
- async function refreshOpenAIToken(_credential) {
47
- throw new TokenRefreshError('openai', 'Token refresh removed. Use codex-cli or API key.');
427
+ // ── Main Refresh Function ───────────────────────────────────────────────────
428
+ /**
429
+ * Check if a credential needs refresh (expired or within 5-minute buffer).
430
+ */
431
+ function needsRefresh(credential) {
432
+ return Date.now() >= credential.expiresAt - EXPIRY_BUFFER_MS;
48
433
  }
49
- async function refreshGeminiToken(_credential) {
50
- throw new TokenRefreshError('google-gemini', 'Token refresh removed. Use API key.');
434
+ /**
435
+ * Refresh a single credential. For Anthropic in cloud mode, delegates to the
436
+ * Funolio server. For other providers (or local mode), refreshes directly.
437
+ *
438
+ * After refresh, writes updated tokens back to the source files.
439
+ */
440
+ async function refreshToken(credential) {
441
+ const authority = getTokenRefreshAuthority();
442
+ console.log(`[token-refresh] Refreshing ${credential.provider} token (authority: ${authority})...`);
443
+ let refreshed;
444
+ switch (credential.provider) {
445
+ case 'anthropic':
446
+ if (authority === 'cloud') {
447
+ // Cloud mode: ask the server to refresh (it holds the refresh token)
448
+ try {
449
+ refreshed = await refreshViaServer(credential);
450
+ }
451
+ catch (err) {
452
+ // If server is unreachable, log clearly but don't fall back to local
453
+ // (falling back would consume the single-use refresh token and create
454
+ // the exact race condition we're trying to prevent)
455
+ console.error(`[token-refresh] Server refresh failed: ${err.message}`);
456
+ throw new TokenRefreshError('anthropic', `Server token refresh failed. Ensure the Funolio server is reachable, or set tokenRefreshAuthority to "local" if self-hosted. Error: ${err.message}`, err.httpStatus);
457
+ }
458
+ }
459
+ else {
460
+ // Local mode: refresh directly with Anthropic (self-hosted, no server)
461
+ // No retry — refresh tokens are single-use
462
+ refreshed = await refreshAnthropicTokenLocal(credential);
463
+ // Seed server with fresh token so it can do future cloud refreshes
464
+ seedServerWithToken(refreshed).catch(() => { });
465
+ }
466
+ break;
467
+ case 'openai':
468
+ refreshed = await withRetry(() => refreshOpenAIToken(credential), 'openai');
469
+ break;
470
+ case 'google-gemini':
471
+ refreshed = await withRetry(() => refreshGeminiToken(credential), 'google-gemini');
472
+ break;
473
+ default:
474
+ throw new TokenRefreshError(credential.provider, `Unknown provider: ${credential.provider}`);
475
+ }
476
+ // Write back to credential files
477
+ let written = false;
478
+ switch (refreshed.provider) {
479
+ case 'anthropic':
480
+ written = writeClaudeCredentials(refreshed);
481
+ break;
482
+ case 'openai':
483
+ written = writeCodexCredentials(refreshed);
484
+ break;
485
+ case 'google-gemini':
486
+ written = writeGeminiCredentials(refreshed);
487
+ break;
488
+ }
489
+ // Clear credential-reader cache so next read picks up new tokens
490
+ (0, credential_reader_1.clearCache)();
491
+ return { credential: refreshed, written };
51
492
  }
52
- function writeClaudeCredentials(_credential) { return false; }
53
- function writeCodexCredentials(_credential) { return false; }
54
- async function seedServerWithToken(_credential) { return false; }
55
493
  //# sourceMappingURL=token-refresh.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-refresh.js","sourceRoot":"","sources":["../../src/auth/token-refresh.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAsBH,oCAEC;AAGD,oCAKC;AAGD,gDAEC;AAED,gDAEC;AAED,wDAA+F;AAC/F,sDAA8F;AAC9F,kDAA2G;AAzC3G,MAAa,iBAAkB,SAAQ,KAAK;IAC1B,QAAQ,CAAS;IACjB,UAAU,CAAqB;IAE/C,YAAY,QAAgB,EAAE,OAAe,EAAE,UAAmB;QAChE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAVD,8CAUC;AAOD,+DAA+D;AAC/D,SAAgB,YAAY,CAAC,WAA4B;IACvD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wEAAwE;AACjE,KAAK,UAAU,YAAY,CAAC,WAA4B;IAC7D,MAAM,IAAI,iBAAiB,CACzB,WAAW,CAAC,QAAQ,EACpB,sGAAsG,CACvG,CAAC;AACJ,CAAC;AAED,sDAAsD;AAC/C,KAAK,UAAU,kBAAkB,CAAC,WAA4B;IACnE,MAAM,IAAI,iBAAiB,CAAC,QAAQ,EAAE,kDAAkD,CAAC,CAAC;AAC5F,CAAC;AAEM,KAAK,UAAU,kBAAkB,CAAC,WAA4B;IACnE,MAAM,IAAI,iBAAiB,CAAC,eAAe,EAAE,qCAAqC,CAAC,CAAC;AACtF,CAAC;AAED,SAAgB,sBAAsB,CAAC,WAA4B,IAAa,OAAO,KAAK,CAAC,CAAC,CAAC;AAC/F,SAAgB,qBAAqB,CAAC,WAA4B,IAAa,OAAO,KAAK,CAAC,CAAC,CAAC;AACvF,KAAK,UAAU,mBAAmB,CAAC,WAA4B,IAAsB,OAAO,KAAK,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"token-refresh.js","sourceRoot":"","sources":["../../src/auth/token-refresh.ts"],"names":[],"mappings":"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"}
@@ -4,11 +4,13 @@ export interface BotManagerOptions {
4
4
  projectDir: string;
5
5
  userId: string;
6
6
  mqttClient: AgentMqttClient;
7
- /** Active agent provider/model/apiKey/oauthToken (resolved from agents[] + providers[]) */
7
+ /** Active agent provider/model/apiKey (resolved from agents[] + providers[]) */
8
8
  defaultProvider: string;
9
9
  defaultModel: string;
10
10
  defaultApiKey?: string;
11
11
  defaultOauthToken?: string;
12
+ defaultOauthRefreshToken?: string;
13
+ defaultOauthExpiresAt?: number;
12
14
  /** Active agent permission mode and tool config */
13
15
  permissionMode?: string;
14
16
  enabledTools?: string[];
@@ -19,10 +21,6 @@ export interface BotManagerOptions {
19
21
  * Manages agent MessageLoops, keyed by agent ID.
20
22
  * The active agent runs as "__default__" loop.
21
23
  * Runtime source of truth: config.agents[] + config.activeAgentId.
22
- *
23
- * Auth modes supported:
24
- * 1. CLI providers (claude-cli, codex-cli) — handle their own auth
25
- * 2. API key (BYOK) — standard x-api-key authentication
26
24
  */
27
25
  export declare class BotManager {
28
26
  private loops;
@@ -31,7 +29,7 @@ export declare class BotManager {
31
29
  private resolvedAuth;
32
30
  private recentCommandIds;
33
31
  constructor(options: BotManagerOptions);
34
- /** Start the active agent loop */
32
+ /** Start the active agent loop, auto-detecting OAuth credentials if no API key is configured */
35
33
  startActive(): Promise<void>;
36
34
  /**
37
35
  * Load all agent configs from ~/.funolio/agents/ and start a loop for each.
@@ -66,6 +64,8 @@ export declare class BotManager {
66
64
  private handleAgentRemove;
67
65
  /** Update an agent — re-fetches config from server to get credentials */
68
66
  private handleAgentUpdate;
67
+ /** Update the default OAuth token for the active loop (used by token refresh) */
68
+ updateDefaultToken(token: string): void;
69
69
  private handleUpdateCommand;
70
70
  }
71
71
  //# sourceMappingURL=bot-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bot-manager.d.ts","sourceRoot":"","sources":["../src/bot-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG9D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI3C,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,eAAe,CAAC;IAC5B,2FAA2F;IAC3F,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AASD;;;;;;;;GAQG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,gBAAgB,CAA6B;gBAEzC,OAAO,EAAE,iBAAiB;IAItC,kCAAkC;IAC5B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAsClC;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAkGnC,gDAAgD;IAChD,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,eAAe;IAQvB,kGAAkG;IAClG,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAyD1C,4CAA4C;IAC5C,gBAAgB,IAAI,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAe1G,MAAM,IAAI,OAAO;IAOjB,OAAO,CAAC,SAAS;IAsBjB,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,cAAc;IAItB;;;OAGG;YACW,kBAAkB;IAmDhC,yEAAyE;YAC3D,cAAc;IAgE5B,oDAAoD;IACpD,OAAO,CAAC,iBAAiB;IAkBzB,yEAAyE;YAC3D,iBAAiB;YAgEjB,mBAAmB;CAoClC"}
1
+ {"version":3,"file":"bot-manager.d.ts","sourceRoot":"","sources":["../src/bot-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG9D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAI3C,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,eAAe,CAAC;IAC5B,gFAAgF;IAChF,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AASD;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,gBAAgB,CAA6B;gBAEzC,OAAO,EAAE,iBAAiB;IAItC,gGAAgG;IAC1F,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAwClC;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA0GnC,gDAAgD;IAChD,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,eAAe;IAQvB,kGAAkG;IAClG,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAyD1C,4CAA4C;IAC5C,gBAAgB,IAAI,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAe1G,MAAM,IAAI,OAAO;IAOjB,OAAO,CAAC,SAAS;IAwBjB,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,cAAc;IAItB;;;OAGG;YACW,kBAAkB;IAsEhC,yEAAyE;YAC3D,cAAc;IAmE5B,oDAAoD;IACpD,OAAO,CAAC,iBAAiB;IAkBzB,yEAAyE;YAC3D,iBAAiB;IAmE/B,iFAAiF;IACjF,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;YAQzB,mBAAmB;CAoClC"}