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.
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.758",
3
+ "version": "1.0.759",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "electron/main.js",
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
- if (pathOnly === '/api/gemini-oauth/start' && req.method === 'POST') {
2003
- try {
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,