marifold 0.60.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 +674 -0
- package/dist/auth/ChatGptAuth.d.ts +17 -0
- package/dist/auth/ChatGptAuth.d.ts.map +1 -0
- package/dist/auth/ChatGptAuth.js +215 -0
- package/dist/auth/ChatGptAuth.js.map +1 -0
- package/dist/auth/GitHubCopilotAuth.d.ts +10 -0
- package/dist/auth/GitHubCopilotAuth.d.ts.map +1 -0
- package/dist/auth/GitHubCopilotAuth.js +118 -0
- package/dist/auth/GitHubCopilotAuth.js.map +1 -0
- package/dist/auth/XaiAuth.d.ts +27 -0
- package/dist/auth/XaiAuth.d.ts.map +1 -0
- package/dist/auth/XaiAuth.js +280 -0
- package/dist/auth/XaiAuth.js.map +1 -0
- package/dist/commands/RuntimeFactory.d.ts +8 -0
- package/dist/commands/RuntimeFactory.d.ts.map +1 -0
- package/dist/commands/RuntimeFactory.js +13 -0
- package/dist/commands/RuntimeFactory.js.map +1 -0
- package/dist/commands/agent.d.ts +4 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +130 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/ask.d.ts +4 -0
- package/dist/commands/ask.d.ts.map +1 -0
- package/dist/commands/ask.js +57 -0
- package/dist/commands/ask.js.map +1 -0
- package/dist/commands/channel.d.ts +8 -0
- package/dist/commands/channel.d.ts.map +1 -0
- package/dist/commands/channel.js +114 -0
- package/dist/commands/channel.js.map +1 -0
- package/dist/commands/chat.d.ts +4 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +352 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/config.d.ts +18 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +228 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/doctor.d.ts +11 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +86 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +135 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/model.d.ts +4 -0
- package/dist/commands/model.d.ts.map +1 -0
- package/dist/commands/model.js +384 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/profile.d.ts +4 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +231 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/provider.d.ts +4 -0
- package/dist/commands/provider.d.ts.map +1 -0
- package/dist/commands/provider.js +254 -0
- package/dist/commands/provider.js.map +1 -0
- package/dist/commands/schedule.d.ts +4 -0
- package/dist/commands/schedule.d.ts.map +1 -0
- package/dist/commands/schedule.js +141 -0
- package/dist/commands/schedule.js.map +1 -0
- package/dist/commands/service.d.ts +15 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +421 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/session.d.ts +4 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +171 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/status.d.ts +4 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +59 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/input/InteractivePrompt.d.ts +9 -0
- package/dist/input/InteractivePrompt.d.ts.map +1 -0
- package/dist/input/InteractivePrompt.js +101 -0
- package/dist/input/InteractivePrompt.js.map +1 -0
- package/dist/input/ModelPicker.d.ts +34 -0
- package/dist/input/ModelPicker.d.ts.map +1 -0
- package/dist/input/ModelPicker.js +327 -0
- package/dist/input/ModelPicker.js.map +1 -0
- package/dist/input/PromptAbort.d.ts +11 -0
- package/dist/input/PromptAbort.d.ts.map +1 -0
- package/dist/input/PromptAbort.js +28 -0
- package/dist/input/PromptAbort.js.map +1 -0
- package/dist/input/SecretPrompt.d.ts +3 -0
- package/dist/input/SecretPrompt.d.ts.map +1 -0
- package/dist/input/SecretPrompt.js +61 -0
- package/dist/input/SecretPrompt.js.map +1 -0
- package/dist/input/TerminalSelect.d.ts +17 -0
- package/dist/input/TerminalSelect.d.ts.map +1 -0
- package/dist/input/TerminalSelect.js +153 -0
- package/dist/input/TerminalSelect.js.map +1 -0
- package/dist/output/ConsolePrinter.d.ts +12 -0
- package/dist/output/ConsolePrinter.d.ts.map +1 -0
- package/dist/output/ConsolePrinter.js +69 -0
- package/dist/output/ConsolePrinter.js.map +1 -0
- package/dist/output/TerminalStyle.d.ts +11 -0
- package/dist/output/TerminalStyle.d.ts.map +1 -0
- package/dist/output/TerminalStyle.js +41 -0
- package/dist/output/TerminalStyle.js.map +1 -0
- package/dist/service/ServiceProcess.d.ts +45 -0
- package/dist/service/ServiceProcess.d.ts.map +1 -0
- package/dist/service/ServiceProcess.js +288 -0
- package/dist/service/ServiceProcess.js.map +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ChatGptAuthTokens {
|
|
2
|
+
accessToken: string;
|
|
3
|
+
refreshToken: string;
|
|
4
|
+
/** ChatGPT account id from the id_token, sent as the `chatgpt-account-id`
|
|
5
|
+
* header on Codex-backend requests. */
|
|
6
|
+
accountId?: string;
|
|
7
|
+
idToken?: string;
|
|
8
|
+
expiresAt?: number;
|
|
9
|
+
}
|
|
10
|
+
interface PkceCodes {
|
|
11
|
+
codeVerifier: string;
|
|
12
|
+
codeChallenge: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function authorizeChatGptWithBrowser(write?: (text: string) => void): Promise<ChatGptAuthTokens>;
|
|
15
|
+
export declare function buildChatGptAuthorizeUrl(redirectUri: string, pkce: PkceCodes, state: string): string;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=ChatGptAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatGptAuth.d.ts","sourceRoot":"","sources":["../../src/auth/ChatGptAuth.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB;2CACuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,SAAS;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAQD,wBAAsB,2BAA2B,CAC/C,KAAK,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAyC,GACjE,OAAO,CAAC,iBAAiB,CAAC,CAiB5B;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAcpG"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.authorizeChatGptWithBrowser = authorizeChatGptWithBrowser;
|
|
4
|
+
exports.buildChatGptAuthorizeUrl = buildChatGptAuthorizeUrl;
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const http_1 = require("http");
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const core_1 = require("@marifold/core");
|
|
9
|
+
const CHATGPT_AUTH_ISSUER = 'https://auth.openai.com';
|
|
10
|
+
const CHATGPT_OAUTH_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann';
|
|
11
|
+
const CHATGPT_OAUTH_SCOPE = 'openid profile email offline_access api.connectors.read api.connectors.invoke';
|
|
12
|
+
const CHATGPT_OAUTH_PORTS = [1455, 1457];
|
|
13
|
+
const CHATGPT_CALLBACK_PATH = '/auth/callback';
|
|
14
|
+
async function authorizeChatGptWithBrowser(write = text => process.stdout.write(text)) {
|
|
15
|
+
const pkce = generatePkce();
|
|
16
|
+
const state = base64Url((0, crypto_1.randomBytes)(32));
|
|
17
|
+
const callback = await startCallbackServer(state);
|
|
18
|
+
const authUrl = buildChatGptAuthorizeUrl(callback.redirectUri, pkce, state);
|
|
19
|
+
try {
|
|
20
|
+
openBrowser(authUrl);
|
|
21
|
+
write('Open this URL in your browser to sign in with ChatGPT:\n');
|
|
22
|
+
write(`${authUrl}\n`);
|
|
23
|
+
write('Waiting for the browser redirect...\n');
|
|
24
|
+
const code = await callback.waitForCode();
|
|
25
|
+
write('Received the authorization code — exchanging tokens with OpenAI...\n');
|
|
26
|
+
return await exchangeChatGptCodeForTokens(code, callback.redirectUri, pkce);
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
await callback.close();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function buildChatGptAuthorizeUrl(redirectUri, pkce, state) {
|
|
33
|
+
const params = new URLSearchParams({
|
|
34
|
+
response_type: 'code',
|
|
35
|
+
client_id: CHATGPT_OAUTH_CLIENT_ID,
|
|
36
|
+
redirect_uri: redirectUri,
|
|
37
|
+
scope: CHATGPT_OAUTH_SCOPE,
|
|
38
|
+
code_challenge: pkce.codeChallenge,
|
|
39
|
+
code_challenge_method: 'S256',
|
|
40
|
+
id_token_add_organizations: 'true',
|
|
41
|
+
codex_cli_simplified_flow: 'true',
|
|
42
|
+
state,
|
|
43
|
+
originator: 'marifold_cli',
|
|
44
|
+
});
|
|
45
|
+
return `${CHATGPT_AUTH_ISSUER}/oauth/authorize?${params.toString()}`;
|
|
46
|
+
}
|
|
47
|
+
async function exchangeChatGptCodeForTokens(code, redirectUri, pkce) {
|
|
48
|
+
const data = await postForm(`${CHATGPT_AUTH_ISSUER}/oauth/token`, {
|
|
49
|
+
grant_type: 'authorization_code',
|
|
50
|
+
code,
|
|
51
|
+
redirect_uri: redirectUri,
|
|
52
|
+
client_id: CHATGPT_OAUTH_CLIENT_ID,
|
|
53
|
+
code_verifier: pkce.codeVerifier,
|
|
54
|
+
}, 'ChatGPT token exchange failed');
|
|
55
|
+
const accessToken = stringField(data.access_token);
|
|
56
|
+
const refreshToken = stringField(data.refresh_token);
|
|
57
|
+
if (!accessToken || !refreshToken) {
|
|
58
|
+
throw new Error('ChatGPT token exchange response did not include access and refresh tokens.');
|
|
59
|
+
}
|
|
60
|
+
const idToken = stringField(data.id_token);
|
|
61
|
+
const expiresIn = numberField(data.expires_in);
|
|
62
|
+
return {
|
|
63
|
+
accessToken,
|
|
64
|
+
refreshToken,
|
|
65
|
+
// Subscription (ChatGPT plan) accounts have no platform organization, so we
|
|
66
|
+
// use the access token directly against the Codex backend rather than
|
|
67
|
+
// exchanging the id_token for a platform API key. The account id from the
|
|
68
|
+
// id_token is required as the `chatgpt-account-id` request header.
|
|
69
|
+
accountId: idToken ? (0, core_1.accountIdFromIdToken)(idToken) : undefined,
|
|
70
|
+
idToken,
|
|
71
|
+
expiresAt: expiresIn !== undefined ? Math.floor(Date.now() / 1000) + expiresIn : undefined,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function postForm(url, data, label) {
|
|
75
|
+
// Node's fetch ignores HTTPS_PROXY by default; honor it for this external call
|
|
76
|
+
// (OpenAI's token endpoint) so the exchange works behind a proxy like the browser.
|
|
77
|
+
const init = {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: {
|
|
80
|
+
Accept: 'application/json',
|
|
81
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
82
|
+
},
|
|
83
|
+
body: new URLSearchParams(data),
|
|
84
|
+
// Generous ceiling: the OAuth token endpoint can be slow through a proxy.
|
|
85
|
+
signal: AbortSignal.timeout(60000),
|
|
86
|
+
};
|
|
87
|
+
const dispatcher = (0, core_1.proxyDispatcher)();
|
|
88
|
+
if (dispatcher)
|
|
89
|
+
init.dispatcher = dispatcher;
|
|
90
|
+
const response = await fetch(url, init).catch(error => {
|
|
91
|
+
throw new Error(`${label}: ${stringifyError(error)}`);
|
|
92
|
+
});
|
|
93
|
+
if (!response.ok)
|
|
94
|
+
throw new Error(`${label}: HTTP ${response.status}: ${await response.text()}`);
|
|
95
|
+
return await response.json();
|
|
96
|
+
}
|
|
97
|
+
async function startCallbackServer(expectedState) {
|
|
98
|
+
let lastError;
|
|
99
|
+
for (const port of CHATGPT_OAUTH_PORTS) {
|
|
100
|
+
try {
|
|
101
|
+
return await listenOnPort(port, expectedState);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
throw new Error(`Could not start local OAuth callback server on ports 1455 or 1457${lastError ? `: ${lastError.message}` : ''}`);
|
|
108
|
+
}
|
|
109
|
+
function listenOnPort(port, expectedState) {
|
|
110
|
+
return new Promise((resolve, reject) => {
|
|
111
|
+
let resolveCode;
|
|
112
|
+
let rejectCode;
|
|
113
|
+
const codePromise = new Promise((codeResolve, codeReject) => {
|
|
114
|
+
resolveCode = codeResolve;
|
|
115
|
+
rejectCode = codeReject;
|
|
116
|
+
});
|
|
117
|
+
const server = (0, http_1.createServer)((request, response) => {
|
|
118
|
+
const requestUrl = new URL(request.url ?? '/', `http://localhost:${port}`);
|
|
119
|
+
if (requestUrl.pathname !== CHATGPT_CALLBACK_PATH) {
|
|
120
|
+
response.writeHead(404);
|
|
121
|
+
response.end('Not Found');
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const state = requestUrl.searchParams.get('state') ?? '';
|
|
125
|
+
if (state !== expectedState) {
|
|
126
|
+
respond(response, 'Sign-in failed: state mismatch.', 400);
|
|
127
|
+
rejectCode?.(new Error('OAuth callback state mismatch.'));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const error = requestUrl.searchParams.get('error');
|
|
131
|
+
if (error) {
|
|
132
|
+
const description = requestUrl.searchParams.get('error_description') ?? error;
|
|
133
|
+
respond(response, `Sign-in failed: ${description}`, 400);
|
|
134
|
+
rejectCode?.(new Error(description));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const code = requestUrl.searchParams.get('code');
|
|
138
|
+
if (!code) {
|
|
139
|
+
respond(response, 'Sign-in failed: missing authorization code.', 400);
|
|
140
|
+
rejectCode?.(new Error('OAuth callback did not include an authorization code.'));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
respond(response, 'Sign-in complete. You can close this window and return to Marifold.');
|
|
144
|
+
resolveCode?.(code);
|
|
145
|
+
});
|
|
146
|
+
server.once('error', error => reject(error));
|
|
147
|
+
server.listen(port, '127.0.0.1', () => {
|
|
148
|
+
resolve({
|
|
149
|
+
redirectUri: `http://localhost:${port}${CHATGPT_CALLBACK_PATH}`,
|
|
150
|
+
waitForCode: () => withTimeout(codePromise, 300000, 'ChatGPT sign-in timed out before the callback was received.'),
|
|
151
|
+
close: () => closeServer(server),
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
function respond(response, message, status = 200) {
|
|
157
|
+
const escaped = message.replace(/[&<>"']/g, char => ({
|
|
158
|
+
'&': '&',
|
|
159
|
+
'<': '<',
|
|
160
|
+
'>': '>',
|
|
161
|
+
'"': '"',
|
|
162
|
+
"'": ''',
|
|
163
|
+
}[char] ?? char));
|
|
164
|
+
const body = `<!doctype html><html><head><title>marifold auth</title></head><body><p>${escaped}</p></body></html>`;
|
|
165
|
+
response.writeHead(status, {
|
|
166
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
167
|
+
'Content-Length': String(Buffer.byteLength(body)),
|
|
168
|
+
});
|
|
169
|
+
response.end(body);
|
|
170
|
+
}
|
|
171
|
+
function closeServer(server) {
|
|
172
|
+
return new Promise(resolve => {
|
|
173
|
+
server.close(() => resolve());
|
|
174
|
+
// The browser keeps the success-page connection alive, which blocks
|
|
175
|
+
// server.close() from ever completing; force lingering sockets closed so
|
|
176
|
+
// the sign-in returns promptly instead of hanging after the token exchange.
|
|
177
|
+
server.closeAllConnections();
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function withTimeout(promise, ms, message) {
|
|
181
|
+
return new Promise((resolve, reject) => {
|
|
182
|
+
const timer = setTimeout(() => reject(new Error(message)), ms);
|
|
183
|
+
promise.then(value => {
|
|
184
|
+
clearTimeout(timer);
|
|
185
|
+
resolve(value);
|
|
186
|
+
}, error => {
|
|
187
|
+
clearTimeout(timer);
|
|
188
|
+
reject(error);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function generatePkce() {
|
|
193
|
+
const codeVerifier = base64Url((0, crypto_1.randomBytes)(32));
|
|
194
|
+
const codeChallenge = base64Url((0, crypto_1.createHash)('sha256').update(codeVerifier).digest());
|
|
195
|
+
return { codeVerifier, codeChallenge };
|
|
196
|
+
}
|
|
197
|
+
function base64Url(bytes) {
|
|
198
|
+
return bytes.toString('base64url');
|
|
199
|
+
}
|
|
200
|
+
function openBrowser(url) {
|
|
201
|
+
const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'cmd' : 'xdg-open';
|
|
202
|
+
const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];
|
|
203
|
+
const child = (0, child_process_1.spawn)(command, args, { stdio: 'ignore', detached: true });
|
|
204
|
+
child.unref();
|
|
205
|
+
}
|
|
206
|
+
function stringField(value) {
|
|
207
|
+
return typeof value === 'string' ? value : undefined;
|
|
208
|
+
}
|
|
209
|
+
function numberField(value) {
|
|
210
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
211
|
+
}
|
|
212
|
+
function stringifyError(error) {
|
|
213
|
+
return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=ChatGptAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatGptAuth.js","sourceRoot":"","sources":["../../src/auth/ChatGptAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { exchangeGitHubTokenForCopilotToken } from '@marifold/core';
|
|
2
|
+
export { exchangeGitHubTokenForCopilotToken };
|
|
3
|
+
export declare function looksLikeCopilotIdeToken(token: string): boolean;
|
|
4
|
+
export declare function authorizeGitHubCopilotWithDevice(write?: (text: string) => void): Promise<{
|
|
5
|
+
apiKey: string;
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
oauthToken: string;
|
|
8
|
+
apiKeyExpiresAt?: number;
|
|
9
|
+
}>;
|
|
10
|
+
//# sourceMappingURL=GitHubCopilotAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitHubCopilotAuth.d.ts","sourceRoot":"","sources":["../../src/auth/GitHubCopilotAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAAE,kCAAkC,EAAE,CAAC;AAK9C,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAsB,gCAAgC,CACpD,KAAK,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAyC,GACjE,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAe5F"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.exchangeGitHubTokenForCopilotToken = void 0;
|
|
4
|
+
exports.looksLikeCopilotIdeToken = looksLikeCopilotIdeToken;
|
|
5
|
+
exports.authorizeGitHubCopilotWithDevice = authorizeGitHubCopilotWithDevice;
|
|
6
|
+
const core_1 = require("@marifold/core");
|
|
7
|
+
Object.defineProperty(exports, "exchangeGitHubTokenForCopilotToken", { enumerable: true, get: function () { return core_1.exchangeGitHubTokenForCopilotToken; } });
|
|
8
|
+
const GITHUB_COPILOT_CLIENT_ID = 'Iv1.b507a08c87ecfe98';
|
|
9
|
+
const GITHUB_COPILOT_SCOPE = 'read:user';
|
|
10
|
+
function looksLikeCopilotIdeToken(token) {
|
|
11
|
+
return token.startsWith('tid=');
|
|
12
|
+
}
|
|
13
|
+
async function authorizeGitHubCopilotWithDevice(write = text => process.stdout.write(text)) {
|
|
14
|
+
const device = await startGitHubCopilotDeviceFlow();
|
|
15
|
+
write('GitHub Copilot OAuth\n');
|
|
16
|
+
write(`Open: ${device.verificationUri}\n`);
|
|
17
|
+
write(`Enter code: ${device.userCode}\n`);
|
|
18
|
+
write('Waiting for authorization...\n');
|
|
19
|
+
const githubToken = await pollGitHubCopilotDeviceFlow(device.deviceCode, device.interval, device.expiresIn);
|
|
20
|
+
const copilot = await (0, core_1.exchangeGitHubTokenForCopilotToken)(githubToken);
|
|
21
|
+
return {
|
|
22
|
+
apiKey: copilot.token,
|
|
23
|
+
baseUrl: copilot.baseUrl,
|
|
24
|
+
oauthToken: githubToken,
|
|
25
|
+
apiKeyExpiresAt: copilot.expiresAt,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
async function startGitHubCopilotDeviceFlow() {
|
|
29
|
+
const response = await fetch('https://github.com/login/device/code', {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: {
|
|
32
|
+
Accept: 'application/json',
|
|
33
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
34
|
+
'User-Agent': 'marifold',
|
|
35
|
+
},
|
|
36
|
+
body: new URLSearchParams({
|
|
37
|
+
client_id: GITHUB_COPILOT_CLIENT_ID,
|
|
38
|
+
scope: GITHUB_COPILOT_SCOPE,
|
|
39
|
+
}),
|
|
40
|
+
signal: AbortSignal.timeout(10000),
|
|
41
|
+
}).catch(error => {
|
|
42
|
+
throw new Error(`Could not start GitHub device flow: ${stringifyError(error)}`);
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok)
|
|
45
|
+
throw new Error(`GitHub device flow failed: HTTP ${response.status}: ${await response.text()}`);
|
|
46
|
+
const data = await response.json();
|
|
47
|
+
const deviceCode = requiredString(data.device_code, 'device_code');
|
|
48
|
+
const userCode = requiredString(data.user_code, 'user_code');
|
|
49
|
+
const verificationUri = requiredString(data.verification_uri, 'verification_uri');
|
|
50
|
+
return {
|
|
51
|
+
deviceCode,
|
|
52
|
+
userCode,
|
|
53
|
+
verificationUri,
|
|
54
|
+
expiresIn: numberField(data.expires_in) ?? 900,
|
|
55
|
+
interval: numberField(data.interval) ?? 5,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async function pollGitHubCopilotDeviceFlow(deviceCode, interval, expiresIn) {
|
|
59
|
+
const deadline = Date.now() + expiresIn * 1000;
|
|
60
|
+
let pollInterval = Math.max(interval, 1);
|
|
61
|
+
while (Date.now() < deadline) {
|
|
62
|
+
await delay(pollInterval * 1000);
|
|
63
|
+
const response = await fetch('https://github.com/login/oauth/access_token', {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: {
|
|
66
|
+
Accept: 'application/json',
|
|
67
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
68
|
+
'User-Agent': 'marifold',
|
|
69
|
+
},
|
|
70
|
+
body: new URLSearchParams({
|
|
71
|
+
client_id: GITHUB_COPILOT_CLIENT_ID,
|
|
72
|
+
device_code: deviceCode,
|
|
73
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
74
|
+
}),
|
|
75
|
+
signal: AbortSignal.timeout(10000),
|
|
76
|
+
}).catch(error => {
|
|
77
|
+
throw new Error(`Could not poll GitHub device flow: ${stringifyError(error)}`);
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok)
|
|
80
|
+
throw new Error(`GitHub device polling failed: HTTP ${response.status}: ${await response.text()}`);
|
|
81
|
+
const data = await response.json();
|
|
82
|
+
const token = stringField(data.access_token);
|
|
83
|
+
if (token)
|
|
84
|
+
return token;
|
|
85
|
+
const error = stringField(data.error);
|
|
86
|
+
if (error === 'authorization_pending')
|
|
87
|
+
continue;
|
|
88
|
+
if (error === 'slow_down') {
|
|
89
|
+
pollInterval += 5;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (error === 'expired_token')
|
|
93
|
+
throw new Error('The device code expired. Start again.');
|
|
94
|
+
if (error === 'access_denied')
|
|
95
|
+
throw new Error('Authorization was denied.');
|
|
96
|
+
throw new Error(stringField(data.error_description) ?? error ?? 'Authorization failed.');
|
|
97
|
+
}
|
|
98
|
+
throw new Error('The device code expired. Start again.');
|
|
99
|
+
}
|
|
100
|
+
function requiredString(value, label) {
|
|
101
|
+
const parsed = stringField(value);
|
|
102
|
+
if (!parsed)
|
|
103
|
+
throw new Error(`GitHub device flow response missing '${label}'.`);
|
|
104
|
+
return parsed;
|
|
105
|
+
}
|
|
106
|
+
function stringField(value) {
|
|
107
|
+
return typeof value === 'string' ? value : undefined;
|
|
108
|
+
}
|
|
109
|
+
function numberField(value) {
|
|
110
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
111
|
+
}
|
|
112
|
+
function delay(ms) {
|
|
113
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
114
|
+
}
|
|
115
|
+
function stringifyError(error) {
|
|
116
|
+
return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=GitHubCopilotAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitHubCopilotAuth.js","sourceRoot":"","sources":["../../src/auth/GitHubCopilotAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface XaiAuthTokens {
|
|
2
|
+
/** OAuth access token — used directly as the api.x.ai Bearer credential. */
|
|
3
|
+
accessToken: string;
|
|
4
|
+
refreshToken: string;
|
|
5
|
+
expiresAt?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface XaiAuthOptions {
|
|
8
|
+
/** Explicit provider proxy. Falls back to HTTP(S)_PROXY when omitted. */
|
|
9
|
+
proxy?: string;
|
|
10
|
+
}
|
|
11
|
+
interface PkceCodes {
|
|
12
|
+
codeVerifier: string;
|
|
13
|
+
codeChallenge: string;
|
|
14
|
+
}
|
|
15
|
+
/** Reads a line the user pastes back (the code xAI displays, or the full
|
|
16
|
+
* redirect URL). Returns undefined/empty to fall back to the loopback redirect. */
|
|
17
|
+
export type ReadPastedCode = (prompt: string) => Promise<string | undefined>;
|
|
18
|
+
export declare function authorizeXaiWithBrowser(write?: (text: string) => void, readPastedCode?: ReadPastedCode, options?: XaiAuthOptions): Promise<XaiAuthTokens>;
|
|
19
|
+
/**
|
|
20
|
+
* Extract the authorization code from whatever the user pastes: the full
|
|
21
|
+
* `http://127.0.0.1:56121/callback?code=…&state=…` redirect, a bare
|
|
22
|
+
* `code=…&state=…` querystring, or just the code shown on xAI's page.
|
|
23
|
+
*/
|
|
24
|
+
export declare function extractPastedCode(input: string, expectedState: string): string;
|
|
25
|
+
export declare function buildXaiAuthorizeUrl(redirectUri: string, pkce: PkceCodes, state: string, nonce: string): string;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=XaiAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"XaiAuth.d.ts","sourceRoot":"","sources":["../../src/auth/XaiAuth.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,SAAS;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAcD;mFACmF;AACnF,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAE7E,wBAAsB,uBAAuB,CAC3C,KAAK,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAyC,EAClE,cAAc,CAAC,EAAE,cAAc,EAC/B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAqCxB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAoB9E;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAc/G"}
|