agentgui 1.0.758 → 1.0.759
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/lib/claude-runner.js +1266 -189
- package/lib/routes-oauth.js +105 -0
- package/package.json +1 -1
- package/server.js +4 -124
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { startGeminiOAuth, exchangeGeminiOAuthCode, getGeminiOAuthState } from './oauth-gemini.js';
|
|
2
|
+
import { startCodexOAuth, exchangeCodexOAuthCode, getCodexOAuthState } from './oauth-codex.js';
|
|
3
|
+
|
|
4
|
+
export function register(deps) {
|
|
5
|
+
const { sendJSON, parseBody, PORT, BASE_URL, rootDir } = deps;
|
|
6
|
+
const routes = {};
|
|
7
|
+
|
|
8
|
+
routes['POST /api/gemini-oauth/start'] = async (req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
const result = await startGeminiOAuth(req, { PORT, BASE_URL, rootDir });
|
|
11
|
+
sendJSON(req, res, 200, { authUrl: result.authUrl, mode: result.mode });
|
|
12
|
+
} catch (e) {
|
|
13
|
+
console.error('[gemini-oauth] /api/gemini-oauth/start failed:', e);
|
|
14
|
+
sendJSON(req, res, 500, { error: e.message });
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
routes['GET /api/gemini-oauth/status'] = async (req, res) => {
|
|
19
|
+
sendJSON(req, res, 200, getGeminiOAuthState());
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
routes['POST /api/gemini-oauth/relay'] = async (req, res) => {
|
|
23
|
+
try {
|
|
24
|
+
const body = await parseBody(req);
|
|
25
|
+
const { code, state: stateParam } = body;
|
|
26
|
+
if (!code || !stateParam) { sendJSON(req, res, 400, { error: 'Missing code or state' }); return; }
|
|
27
|
+
const email = await exchangeGeminiOAuthCode(code, stateParam);
|
|
28
|
+
sendJSON(req, res, 200, { success: true, email });
|
|
29
|
+
} catch (e) {
|
|
30
|
+
sendJSON(req, res, 400, { error: e.message });
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
routes['POST /api/gemini-oauth/complete'] = async (req, res) => {
|
|
35
|
+
try {
|
|
36
|
+
const body = await parseBody(req);
|
|
37
|
+
const pastedUrl = (body.url || '').trim();
|
|
38
|
+
if (!pastedUrl) { sendJSON(req, res, 400, { error: 'No URL provided' }); return; }
|
|
39
|
+
let parsed;
|
|
40
|
+
try { parsed = new URL(pastedUrl); } catch (_) {
|
|
41
|
+
sendJSON(req, res, 400, { error: 'Invalid URL. Paste the full URL from the browser address bar.' }); return;
|
|
42
|
+
}
|
|
43
|
+
const error = parsed.searchParams.get('error');
|
|
44
|
+
if (error) { sendJSON(req, res, 200, { error: parsed.searchParams.get('error_description') || error }); return; }
|
|
45
|
+
const code = parsed.searchParams.get('code');
|
|
46
|
+
const state = parsed.searchParams.get('state');
|
|
47
|
+
const email = await exchangeGeminiOAuthCode(code, state);
|
|
48
|
+
sendJSON(req, res, 200, { success: true, email });
|
|
49
|
+
} catch (e) {
|
|
50
|
+
sendJSON(req, res, 400, { error: e.message });
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
routes['POST /api/codex-oauth/start'] = async (req, res) => {
|
|
55
|
+
try {
|
|
56
|
+
const result = await startCodexOAuth(req, { PORT, BASE_URL });
|
|
57
|
+
sendJSON(req, res, 200, { authUrl: result.authUrl, mode: result.mode });
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.error('[codex-oauth] /api/codex-oauth/start failed:', e);
|
|
60
|
+
sendJSON(req, res, 500, { error: e.message });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
routes['GET /api/codex-oauth/status'] = async (req, res) => {
|
|
65
|
+
sendJSON(req, res, 200, getCodexOAuthState());
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
routes['POST /api/codex-oauth/relay'] = async (req, res) => {
|
|
69
|
+
try {
|
|
70
|
+
const body = await parseBody(req);
|
|
71
|
+
const { code, state: stateParam } = body;
|
|
72
|
+
if (!code || !stateParam) { sendJSON(req, res, 400, { error: 'Missing code or state' }); return; }
|
|
73
|
+
const email = await exchangeCodexOAuthCode(code, stateParam);
|
|
74
|
+
sendJSON(req, res, 200, { success: true, email });
|
|
75
|
+
} catch (e) {
|
|
76
|
+
sendJSON(req, res, 400, { error: e.message });
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
routes['POST /api/codex-oauth/complete'] = async (req, res) => {
|
|
81
|
+
try {
|
|
82
|
+
const body = await parseBody(req);
|
|
83
|
+
const pastedUrl = (body.url || '').trim();
|
|
84
|
+
if (!pastedUrl) { sendJSON(req, res, 400, { error: 'No URL provided' }); return; }
|
|
85
|
+
let parsed;
|
|
86
|
+
try { parsed = new URL(pastedUrl); } catch (_) {
|
|
87
|
+
sendJSON(req, res, 400, { error: 'Invalid URL. Paste the full URL from the browser address bar.' }); return;
|
|
88
|
+
}
|
|
89
|
+
const error = parsed.searchParams.get('error');
|
|
90
|
+
if (error) { sendJSON(req, res, 200, { error: parsed.searchParams.get('error_description') || error }); return; }
|
|
91
|
+
const code = parsed.searchParams.get('code');
|
|
92
|
+
const state = parsed.searchParams.get('state');
|
|
93
|
+
const email = await exchangeCodexOAuthCode(code, state);
|
|
94
|
+
sendJSON(req, res, 200, { success: true, email });
|
|
95
|
+
} catch (e) {
|
|
96
|
+
sendJSON(req, res, 400, { error: e.message });
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
routes['_match'] = (method, pathOnly) => {
|
|
101
|
+
return routes[`${method} ${pathOnly}`] || null;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
return routes;
|
|
105
|
+
}
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -20,6 +20,7 @@ import { findCommand, queryACPServerAgents, discoverAgents, discoverExternalACPS
|
|
|
20
20
|
import { getGeminiOAuthCreds, startGeminiOAuth, exchangeGeminiOAuthCode, handleGeminiOAuthCallback, getGeminiOAuthStatus, getGeminiOAuthState } from './lib/oauth-gemini.js';
|
|
21
21
|
import { initSpeechManager, getSpeech, ensurePocketTtsSetup, voiceCacheManager, modelDownloadState, broadcastModelProgress, ensureModelsDownloaded, eagerTTS } from './lib/speech-manager.js';
|
|
22
22
|
import { register as registerSpeechRoutes } from './lib/routes-speech.js';
|
|
23
|
+
import { register as registerOAuthRoutes } from './lib/routes-oauth.js';
|
|
23
24
|
import { startCodexOAuth, exchangeCodexOAuthCode, handleCodexOAuthCallback, getCodexOAuthStatus, getCodexOAuthState, CODEX_HOME, CODEX_AUTH_FILE } from './lib/oauth-codex.js';
|
|
24
25
|
import { WSOptimizer } from './lib/ws-optimizer.js';
|
|
25
26
|
import { WsRouter } from './lib/ws-protocol.js';
|
|
@@ -1999,130 +2000,8 @@ const server = http.createServer(async (req, res) => {
|
|
|
1999
2000
|
return;
|
|
2000
2001
|
}
|
|
2001
2002
|
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
const result = await startGeminiOAuth(req, { PORT, BASE_URL, rootDir });
|
|
2005
|
-
sendJSON(req, res, 200, { authUrl: result.authUrl, mode: result.mode });
|
|
2006
|
-
} catch (e) {
|
|
2007
|
-
console.error('[gemini-oauth] /api/gemini-oauth/start failed:', e);
|
|
2008
|
-
sendJSON(req, res, 500, { error: e.message });
|
|
2009
|
-
}
|
|
2010
|
-
return;
|
|
2011
|
-
}
|
|
2012
|
-
|
|
2013
|
-
if (pathOnly === '/api/gemini-oauth/status' && req.method === 'GET') {
|
|
2014
|
-
sendJSON(req, res, 200, getGeminiOAuthState());
|
|
2015
|
-
return;
|
|
2016
|
-
}
|
|
2017
|
-
|
|
2018
|
-
if (pathOnly === '/api/gemini-oauth/relay' && req.method === 'POST') {
|
|
2019
|
-
try {
|
|
2020
|
-
const body = await parseBody(req);
|
|
2021
|
-
const { code, state: stateParam } = body;
|
|
2022
|
-
if (!code || !stateParam) {
|
|
2023
|
-
sendJSON(req, res, 400, { error: 'Missing code or state' });
|
|
2024
|
-
return;
|
|
2025
|
-
}
|
|
2026
|
-
const email = await exchangeGeminiOAuthCode(code, stateParam);
|
|
2027
|
-
sendJSON(req, res, 200, { success: true, email });
|
|
2028
|
-
} catch (e) {
|
|
2029
|
-
sendJSON(req, res, 400, { error: e.message });
|
|
2030
|
-
}
|
|
2031
|
-
return;
|
|
2032
|
-
}
|
|
2033
|
-
|
|
2034
|
-
if (pathOnly === '/api/gemini-oauth/complete' && req.method === 'POST') {
|
|
2035
|
-
try {
|
|
2036
|
-
const body = await parseBody(req);
|
|
2037
|
-
const pastedUrl = (body.url || '').trim();
|
|
2038
|
-
if (!pastedUrl) {
|
|
2039
|
-
sendJSON(req, res, 400, { error: 'No URL provided' });
|
|
2040
|
-
return;
|
|
2041
|
-
}
|
|
2042
|
-
|
|
2043
|
-
let parsed;
|
|
2044
|
-
try { parsed = new URL(pastedUrl); } catch (_) {
|
|
2045
|
-
sendJSON(req, res, 400, { error: 'Invalid URL. Paste the full URL from the browser address bar.' });
|
|
2046
|
-
return;
|
|
2047
|
-
}
|
|
2048
|
-
|
|
2049
|
-
const error = parsed.searchParams.get('error');
|
|
2050
|
-
if (error) {
|
|
2051
|
-
const desc = parsed.searchParams.get('error_description') || error;
|
|
2052
|
-
sendJSON(req, res, 200, { error: desc });
|
|
2053
|
-
return;
|
|
2054
|
-
}
|
|
2055
|
-
|
|
2056
|
-
const code = parsed.searchParams.get('code');
|
|
2057
|
-
const state = parsed.searchParams.get('state');
|
|
2058
|
-
const email = await exchangeGeminiOAuthCode(code, state);
|
|
2059
|
-
sendJSON(req, res, 200, { success: true, email });
|
|
2060
|
-
} catch (e) {
|
|
2061
|
-
sendJSON(req, res, 400, { error: e.message });
|
|
2062
|
-
}
|
|
2063
|
-
return;
|
|
2064
|
-
}
|
|
2065
|
-
|
|
2066
|
-
if (pathOnly === '/api/codex-oauth/start' && req.method === 'POST') {
|
|
2067
|
-
try {
|
|
2068
|
-
const result = await startCodexOAuth(req, { PORT, BASE_URL });
|
|
2069
|
-
sendJSON(req, res, 200, { authUrl: result.authUrl, mode: result.mode });
|
|
2070
|
-
} catch (e) {
|
|
2071
|
-
console.error('[codex-oauth] /api/codex-oauth/start failed:', e);
|
|
2072
|
-
sendJSON(req, res, 500, { error: e.message });
|
|
2073
|
-
}
|
|
2074
|
-
return;
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
if (pathOnly === '/api/codex-oauth/status' && req.method === 'GET') {
|
|
2078
|
-
sendJSON(req, res, 200, getCodexOAuthState());
|
|
2079
|
-
return;
|
|
2080
|
-
}
|
|
2081
|
-
|
|
2082
|
-
if (pathOnly === '/api/codex-oauth/relay' && req.method === 'POST') {
|
|
2083
|
-
try {
|
|
2084
|
-
const body = await parseBody(req);
|
|
2085
|
-
const { code, state: stateParam } = body;
|
|
2086
|
-
if (!code || !stateParam) {
|
|
2087
|
-
sendJSON(req, res, 400, { error: 'Missing code or state' });
|
|
2088
|
-
return;
|
|
2089
|
-
}
|
|
2090
|
-
const email = await exchangeCodexOAuthCode(code, stateParam);
|
|
2091
|
-
sendJSON(req, res, 200, { success: true, email });
|
|
2092
|
-
} catch (e) {
|
|
2093
|
-
sendJSON(req, res, 400, { error: e.message });
|
|
2094
|
-
}
|
|
2095
|
-
return;
|
|
2096
|
-
}
|
|
2097
|
-
|
|
2098
|
-
if (pathOnly === '/api/codex-oauth/complete' && req.method === 'POST') {
|
|
2099
|
-
try {
|
|
2100
|
-
const body = await parseBody(req);
|
|
2101
|
-
const pastedUrl = (body.url || '').trim();
|
|
2102
|
-
if (!pastedUrl) {
|
|
2103
|
-
sendJSON(req, res, 400, { error: 'No URL provided' });
|
|
2104
|
-
return;
|
|
2105
|
-
}
|
|
2106
|
-
let parsed;
|
|
2107
|
-
try { parsed = new URL(pastedUrl); } catch (_) {
|
|
2108
|
-
sendJSON(req, res, 400, { error: 'Invalid URL. Paste the full URL from the browser address bar.' });
|
|
2109
|
-
return;
|
|
2110
|
-
}
|
|
2111
|
-
const error = parsed.searchParams.get('error');
|
|
2112
|
-
if (error) {
|
|
2113
|
-
const desc = parsed.searchParams.get('error_description') || error;
|
|
2114
|
-
sendJSON(req, res, 200, { error: desc });
|
|
2115
|
-
return;
|
|
2116
|
-
}
|
|
2117
|
-
const code = parsed.searchParams.get('code');
|
|
2118
|
-
const state = parsed.searchParams.get('state');
|
|
2119
|
-
const email = await exchangeCodexOAuthCode(code, state);
|
|
2120
|
-
sendJSON(req, res, 200, { success: true, email });
|
|
2121
|
-
} catch (e) {
|
|
2122
|
-
sendJSON(req, res, 400, { error: e.message });
|
|
2123
|
-
}
|
|
2124
|
-
return;
|
|
2125
|
-
}
|
|
2003
|
+
const oauthHandler = _oauthRoutes._match(req.method, pathOnly);
|
|
2004
|
+
if (oauthHandler) { await oauthHandler(req, res); return; }
|
|
2126
2005
|
|
|
2127
2006
|
const agentAuthMatch = pathOnly.match(/^\/api\/agents\/([^/]+)\/auth$/);
|
|
2128
2007
|
if (agentAuthMatch && req.method === 'POST') {
|
|
@@ -3545,6 +3424,7 @@ const wsRouter = new WsRouter();
|
|
|
3545
3424
|
|
|
3546
3425
|
initSpeechManager({ broadcastSync, syncClients, queries });
|
|
3547
3426
|
const _speechRoutes = registerSpeechRoutes({ sendJSON, parseBody, broadcastSync, debugLog });
|
|
3427
|
+
const _oauthRoutes = registerOAuthRoutes({ sendJSON, parseBody, PORT, BASE_URL, rootDir });
|
|
3548
3428
|
|
|
3549
3429
|
registerConvHandlers(wsRouter, {
|
|
3550
3430
|
queries, activeExecutions, rateLimitState,
|