@codeworksh/aikit 0.8.0-dev.20260905193244 → 0.9.0-dev.20260922184333
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/README.md +10 -1
- package/cli.mjs +75 -83
- package/cli.mjs.map +1 -1
- package/{codex-MtP1574D.mjs → codex-CLDBTrFm.mjs} +132 -134
- package/codex-CLDBTrFm.mjs.map +1 -0
- package/copilot-CcD3g6H8.mjs +425 -0
- package/copilot-CcD3g6H8.mjs.map +1 -0
- package/copilot-headers-DceqXlpj.mjs +104 -0
- package/copilot-headers-DceqXlpj.mjs.map +1 -0
- package/github-copilot-BJIrxOzT.mjs +3 -0
- package/github-copilot-SIUCJz1G.mjs +126 -0
- package/github-copilot-SIUCJz1G.mjs.map +1 -0
- package/index.d.mts +980 -932
- package/index.mjs +63 -11
- package/index.mjs.map +1 -1
- package/interactive-eoNnscGB.mjs +57 -0
- package/interactive-eoNnscGB.mjs.map +1 -0
- package/{model-CpX11Oob.d.mts → model-CrVLp622.d.mts} +159 -130
- package/{model-CBnredXj.mjs → model-gCDbmGqT.mjs} +31 -2
- package/model-gCDbmGqT.mjs.map +1 -0
- package/{modelgen-BjSsusLQ.mjs → modelgen-DvorXOjJ.mjs} +148 -29
- package/modelgen-DvorXOjJ.mjs.map +1 -0
- package/modelgen.d.mts +2 -3
- package/modelgen.mjs +1 -1
- package/oauth/github/copilot.d.mts +169 -0
- package/oauth/github/copilot.mjs +2 -0
- package/oauth/interactive.d.mts +21 -0
- package/oauth/interactive.mjs +2 -0
- package/oauth/openai/codex.d.mts +46 -28
- package/oauth/openai/codex.mjs +2 -2
- package/oauth/summary.d.mts +67 -0
- package/oauth/summary.mjs +2 -0
- package/{openai-codex-t4B7g-gv.mjs → openai-codex-Bqzti6Mc.mjs} +3 -3
- package/{openai-codex-t4B7g-gv.mjs.map → openai-codex-Bqzti6Mc.mjs.map} +1 -1
- package/openai-codex-DA1Q7mLN.mjs +2 -0
- package/package.json +34 -22
- package/{registry-DYdYTwFt.mjs → registry-ZxwIW0gX.mjs} +5 -3
- package/registry-ZxwIW0gX.mjs.map +1 -0
- package/storage-v6qjTQ0v.mjs +178 -0
- package/storage-v6qjTQ0v.mjs.map +1 -0
- package/summary-C_QyCVWa.mjs +68 -0
- package/summary-C_QyCVWa.mjs.map +1 -0
- package/codex-MtP1574D.mjs.map +0 -1
- package/model-CBnredXj.mjs.map +0 -1
- package/modelgen-BjSsusLQ.mjs.map +0 -1
- package/openai-codex-BRH4Qa7l.mjs +0 -2
- package/registry-DYdYTwFt.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -147,20 +147,29 @@ pnpm aikit modelgen [path]
|
|
|
147
147
|
|
|
148
148
|
### OAuth Providers
|
|
149
149
|
|
|
150
|
-
Manage OAuth credentials for providers that require it, such as OpenAI Codex.
|
|
150
|
+
Manage OAuth credentials for providers that require it, such as OpenAI Codex and GitHub Copilot.
|
|
151
151
|
|
|
152
152
|
```bash
|
|
153
153
|
# Start an OAuth login flow in your browser
|
|
154
154
|
pnpm aikit auth --openai-codex
|
|
155
155
|
|
|
156
|
+
# Codex with a device code instead: no localhost callback port, so it works
|
|
157
|
+
# over SSH, in containers, and when something else holds port 1455
|
|
158
|
+
pnpm aikit auth --openai-codex --device
|
|
159
|
+
|
|
160
|
+
# GitHub Copilot uses the device flow; add --enterprise <domain> for GitHub Enterprise
|
|
161
|
+
pnpm aikit auth --github-copilot
|
|
162
|
+
|
|
156
163
|
# Check the status of your stored credentials
|
|
157
164
|
pnpm aikit auth --openai-codex --status
|
|
165
|
+
pnpm aikit auth --github-copilot --status
|
|
158
166
|
|
|
159
167
|
# Refresh your current credentials
|
|
160
168
|
pnpm aikit auth --openai-codex --refresh
|
|
161
169
|
|
|
162
170
|
# Clear stored credentials
|
|
163
171
|
pnpm aikit auth --openai-codex --logout
|
|
172
|
+
pnpm aikit auth --github-copilot --logout
|
|
164
173
|
```
|
|
165
174
|
|
|
166
175
|
## Contribute
|
package/cli.mjs
CHANGED
|
@@ -1,105 +1,81 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { t as ModelgenCommand } from "./modelgen-
|
|
2
|
+
import { r as OpenAICodexOAuthClient, t as JsonOpenAICodexAuthStorage } from "./codex-CLDBTrFm.mjs";
|
|
3
|
+
import { t as ModelgenCommand } from "./modelgen-DvorXOjJ.mjs";
|
|
4
|
+
import { i as JsonGitHubCopilotAuthStorage, r as GitHubCopilotOAuthClient } from "./copilot-CcD3g6H8.mjs";
|
|
5
|
+
import { n as promptLine, t as openBrowser } from "./interactive-eoNnscGB.mjs";
|
|
6
|
+
import { a as oauthNotice, c as summarizeGitHubCopilot, i as oauthLoginIssue, l as summarizeOpenAICodex, n as checkOAuthProvider, r as formatOAuthSummary, s as oauthRefreshIssue } from "./summary-C_QyCVWa.mjs";
|
|
4
7
|
import yargs from "yargs";
|
|
5
8
|
import { hideBin } from "yargs/helpers";
|
|
6
9
|
//#region package.json
|
|
7
|
-
var version = "0.
|
|
10
|
+
var version = "0.9.0";
|
|
8
11
|
//#endregion
|
|
9
12
|
//#region src/cli/oauth.ts
|
|
10
|
-
async function promptLine(message) {
|
|
11
|
-
const rl = (await import("node:readline/promises")).createInterface({
|
|
12
|
-
input: process.stdin,
|
|
13
|
-
output: process.stdout
|
|
14
|
-
});
|
|
15
|
-
try {
|
|
16
|
-
return await rl.question(`${message} `);
|
|
17
|
-
} finally {
|
|
18
|
-
rl.close();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
async function openBrowser(url) {
|
|
22
|
-
const { spawn } = await import("node:child_process");
|
|
23
|
-
const command = process.platform === "darwin" ? {
|
|
24
|
-
file: "open",
|
|
25
|
-
args: [url]
|
|
26
|
-
} : process.platform === "win32" ? {
|
|
27
|
-
file: "cmd",
|
|
28
|
-
args: [
|
|
29
|
-
"/c",
|
|
30
|
-
"start",
|
|
31
|
-
"",
|
|
32
|
-
url
|
|
33
|
-
]
|
|
34
|
-
} : {
|
|
35
|
-
file: "xdg-open",
|
|
36
|
-
args: [url]
|
|
37
|
-
};
|
|
38
|
-
spawn(command.file, command.args, {
|
|
39
|
-
detached: true,
|
|
40
|
-
stdio: "ignore"
|
|
41
|
-
}).unref();
|
|
42
|
-
}
|
|
43
|
-
function printCredentials(credentials, options) {
|
|
44
|
-
if (options.json) {
|
|
45
|
-
console.log(JSON.stringify({
|
|
46
|
-
accountId: credentials.accountId,
|
|
47
|
-
expires: credentials.expires,
|
|
48
|
-
expiresAt: new Date(credentials.expires).toISOString(),
|
|
49
|
-
headers: options.printHeaders ? openAICodexHeaders(credentials) : void 0
|
|
50
|
-
}, null, 2));
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
console.log(`Account: ${credentials.accountId}`);
|
|
54
|
-
console.log(`Expires: ${new Date(credentials.expires).toLocaleString()}`);
|
|
55
|
-
if (options.printHeaders) {
|
|
56
|
-
console.log("Headers:");
|
|
57
|
-
for (const [name, value] of Object.entries(openAICodexHeaders(credentials))) console.log(`${name}: ${value}`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
13
|
async function runOpenAICodexAuth(args) {
|
|
61
14
|
const storage = new JsonOpenAICodexAuthStorage({ ...args.authFile !== void 0 && { path: args.authFile } });
|
|
62
15
|
const client = new OpenAICodexOAuthClient({ storage });
|
|
16
|
+
const show = (credentials) => process.stdout.write(formatOAuthSummary(summarizeOpenAICodex(credentials), { json: args.json === true }));
|
|
63
17
|
if (args.logout) {
|
|
64
18
|
await client.logout();
|
|
65
|
-
console.
|
|
19
|
+
console.warn(oauthNotice("cleared", "openai-codex", storage.path));
|
|
66
20
|
return;
|
|
67
21
|
}
|
|
68
|
-
if (args.status) {
|
|
69
|
-
const credentials = await storage.get();
|
|
22
|
+
if (args.status || args.refresh) {
|
|
23
|
+
const credentials = args.refresh ? await client.getCredentials() : await storage.get();
|
|
70
24
|
if (!credentials) {
|
|
71
|
-
console.
|
|
25
|
+
console.error(oauthNotice("missing", "openai-codex", storage.path));
|
|
72
26
|
process.exitCode = 1;
|
|
73
27
|
return;
|
|
74
28
|
}
|
|
75
|
-
|
|
29
|
+
if (args.refresh) console.warn(oauthNotice("refreshed", "openai-codex", storage.path));
|
|
30
|
+
show(credentials);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const credentials = await client.login({
|
|
34
|
+
device: args.device === true,
|
|
35
|
+
onAuth: (info) => {
|
|
36
|
+
console.warn(info.instructions ?? "Complete OpenAI Codex authentication in your browser.");
|
|
37
|
+
if (info.userCode) console.warn(`Enter code: ${info.userCode}`);
|
|
38
|
+
console.warn(info.url);
|
|
39
|
+
if (args.browser !== false) openBrowser(info.url, (error) => console.warn(`Failed to open browser: ${error.message}`));
|
|
40
|
+
},
|
|
41
|
+
onProgress: (message) => console.warn(message),
|
|
42
|
+
onPrompt: async (prompt) => promptLine(prompt.message)
|
|
43
|
+
});
|
|
44
|
+
console.warn(oauthNotice("saved", "openai-codex", storage.path));
|
|
45
|
+
show(credentials);
|
|
46
|
+
}
|
|
47
|
+
async function runGitHubCopilotAuth(args) {
|
|
48
|
+
const storage = new JsonGitHubCopilotAuthStorage({ ...args.authFile !== void 0 && { path: args.authFile } });
|
|
49
|
+
const client = new GitHubCopilotOAuthClient({ storage });
|
|
50
|
+
const show = (credentials) => process.stdout.write(formatOAuthSummary(summarizeGitHubCopilot(credentials), { json: args.json === true }));
|
|
51
|
+
if (args.logout) {
|
|
52
|
+
await client.logout();
|
|
53
|
+
console.warn(oauthNotice("cleared", "github-copilot", storage.path));
|
|
76
54
|
return;
|
|
77
55
|
}
|
|
78
|
-
if (args.
|
|
79
|
-
const credentials = await
|
|
56
|
+
if (args.status) {
|
|
57
|
+
const credentials = await storage.get();
|
|
80
58
|
if (!credentials) {
|
|
81
|
-
console.
|
|
59
|
+
console.error(oauthNotice("missing", "github-copilot", storage.path));
|
|
82
60
|
process.exitCode = 1;
|
|
83
61
|
return;
|
|
84
62
|
}
|
|
85
|
-
|
|
86
|
-
printCredentials(credentials, args);
|
|
63
|
+
show(credentials);
|
|
87
64
|
return;
|
|
88
65
|
}
|
|
89
66
|
const credentials = await client.login({
|
|
90
|
-
...args.
|
|
91
|
-
|
|
67
|
+
...args.enterprise !== void 0 && { enterpriseUrl: args.enterprise },
|
|
68
|
+
enableModels: args.enableModels === true,
|
|
92
69
|
onAuth: (info) => {
|
|
93
|
-
console.
|
|
94
|
-
console.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
70
|
+
console.warn(info.instructions ?? "Complete GitHub Copilot authentication in your browser.");
|
|
71
|
+
console.warn(`Enter code: ${info.userCode}`);
|
|
72
|
+
console.warn(info.url);
|
|
73
|
+
if (args.browser !== false) openBrowser(info.url, (error) => console.warn(`Failed to open browser: ${error.message}`));
|
|
98
74
|
},
|
|
99
|
-
|
|
75
|
+
onProgress: (message) => console.warn(message)
|
|
100
76
|
});
|
|
101
|
-
console.
|
|
102
|
-
|
|
77
|
+
console.warn(oauthNotice("saved", "github-copilot", storage.path));
|
|
78
|
+
show(credentials);
|
|
103
79
|
}
|
|
104
80
|
//#endregion
|
|
105
81
|
//#region src/cli.ts
|
|
@@ -109,6 +85,15 @@ const cli = yargs(hideBin(process.argv)).scriptName("aikit").wrap(100).help("hel
|
|
|
109
85
|
builder: (yargs) => yargs.option("openai-codex", {
|
|
110
86
|
type: "boolean",
|
|
111
87
|
describe: "use OpenAI Codex OAuth"
|
|
88
|
+
}).option("github-copilot", {
|
|
89
|
+
type: "boolean",
|
|
90
|
+
describe: "use GitHub Copilot OAuth (device flow)"
|
|
91
|
+
}).option("enterprise", {
|
|
92
|
+
type: "string",
|
|
93
|
+
describe: "GitHub Enterprise domain for GitHub Copilot login"
|
|
94
|
+
}).option("enable-models", {
|
|
95
|
+
type: "boolean",
|
|
96
|
+
describe: "enable unconfigured Copilot catalog models after login"
|
|
112
97
|
}).option("auth-file", {
|
|
113
98
|
type: "string",
|
|
114
99
|
describe: "path to auth.json (defaults to CODEWORK_CREDENTIALS or ~/.codework/aikit/auth.json)"
|
|
@@ -116,14 +101,10 @@ const cli = yargs(hideBin(process.argv)).scriptName("aikit").wrap(100).help("hel
|
|
|
116
101
|
type: "boolean",
|
|
117
102
|
default: true,
|
|
118
103
|
describe: "open the authorization URL in the default browser"
|
|
119
|
-
}).option("
|
|
104
|
+
}).option("device", {
|
|
120
105
|
type: "boolean",
|
|
121
106
|
default: false,
|
|
122
|
-
describe: "
|
|
123
|
-
}).option("originator", {
|
|
124
|
-
type: "string",
|
|
125
|
-
default: "codework",
|
|
126
|
-
describe: "OAuth originator value"
|
|
107
|
+
describe: "use the device-code flow instead of a localhost browser callback"
|
|
127
108
|
}).option("status", {
|
|
128
109
|
type: "boolean",
|
|
129
110
|
describe: "show stored credential status without refreshing"
|
|
@@ -136,19 +117,30 @@ const cli = yargs(hideBin(process.argv)).scriptName("aikit").wrap(100).help("hel
|
|
|
136
117
|
}).option("json", {
|
|
137
118
|
type: "boolean",
|
|
138
119
|
describe: "print machine-readable output"
|
|
139
|
-
}).option("print-headers", {
|
|
140
|
-
type: "boolean",
|
|
141
|
-
describe: "print request headers for Codex API calls"
|
|
142
120
|
}).check((args) => {
|
|
143
|
-
|
|
121
|
+
const checked = checkOAuthProvider({
|
|
122
|
+
openaiCodex: args["openai-codex"],
|
|
123
|
+
githubCopilot: args["github-copilot"]
|
|
124
|
+
});
|
|
125
|
+
if (!checked.ok) throw new Error(checked.message);
|
|
144
126
|
if ([
|
|
145
127
|
args.status,
|
|
146
128
|
args.refresh,
|
|
147
129
|
args.logout
|
|
148
130
|
].filter(Boolean).length > 1) throw new Error("choose only one of --status, --refresh, or --logout");
|
|
131
|
+
const issue = oauthLoginIssue(checked.provider, {
|
|
132
|
+
device: args.device,
|
|
133
|
+
enterprise: args.enterprise,
|
|
134
|
+
enableModels: args["enable-models"]
|
|
135
|
+
}) ?? (args.refresh ? oauthRefreshIssue(checked.provider) : void 0);
|
|
136
|
+
if (issue) throw new Error(issue);
|
|
149
137
|
return true;
|
|
150
138
|
}),
|
|
151
139
|
handler: async (args) => {
|
|
140
|
+
if (args.githubCopilot) {
|
|
141
|
+
await runGitHubCopilotAuth(args);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
152
144
|
await runOpenAICodexAuth(args);
|
|
153
145
|
}
|
|
154
146
|
}).demandCommand(1, "Choose a command").strict().fail((message, error) => {
|
package/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["pkg.version"],"sources":["../../package.json","../../src/cli/oauth.ts","../../src/cli.ts"],"sourcesContent":["","import type { CommandModule } from \"yargs\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexOAuthCredentials,\n\topenAICodexHeaders,\n} from \"../oauth/openai/codex.ts\";\n\n// `?: T | undefined` rather than plain `?: T`: yargs hands these through as explicit `undefined`,\n// which a bare optional property no longer accepts under `exactOptionalPropertyTypes`.\ntype AuthArgs = {\n\topenaiCodex?: boolean | undefined;\n\tauthFile?: string | undefined;\n\tbrowser?: boolean | undefined;\n\tmanual?: boolean | undefined;\n\tstatus?: boolean | undefined;\n\trefresh?: boolean | undefined;\n\tlogout?: boolean | undefined;\n\tjson?: boolean | undefined;\n\tprintHeaders?: boolean | undefined;\n\toriginator?: string | undefined;\n};\n\nasync function promptLine(message: string): Promise<string> {\n\tconst readline = await import(\"node:readline/promises\");\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t});\n\n\ttry {\n\t\treturn await rl.question(`${message} `);\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function openBrowser(url: string): Promise<void> {\n\tconst { spawn } = await import(\"node:child_process\");\n\tconst command =\n\t\tprocess.platform === \"darwin\"\n\t\t\t? { file: \"open\", args: [url] }\n\t\t\t: process.platform === \"win32\"\n\t\t\t\t? { file: \"cmd\", args: [\"/c\", \"start\", \"\", url] }\n\t\t\t\t: { file: \"xdg-open\", args: [url] };\n\n\tconst child = spawn(command.file, command.args, {\n\t\tdetached: true,\n\t\tstdio: \"ignore\",\n\t});\n\tchild.unref();\n}\n\nfunction printCredentials(\n\tcredentials: OpenAICodexOAuthCredentials,\n\toptions: { json?: boolean | undefined; printHeaders?: boolean | undefined },\n) {\n\tif (options.json) {\n\t\tconsole.log(\n\t\t\tJSON.stringify(\n\t\t\t\t{\n\t\t\t\t\taccountId: credentials.accountId,\n\t\t\t\t\texpires: credentials.expires,\n\t\t\t\t\texpiresAt: new Date(credentials.expires).toISOString(),\n\t\t\t\t\theaders: options.printHeaders ? openAICodexHeaders(credentials) : undefined,\n\t\t\t\t},\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t),\n\t\t);\n\t\treturn;\n\t}\n\n\tconsole.log(`Account: ${credentials.accountId}`);\n\tconsole.log(`Expires: ${new Date(credentials.expires).toLocaleString()}`);\n\tif (options.printHeaders) {\n\t\tconsole.log(\"Headers:\");\n\t\tfor (const [name, value] of Object.entries(openAICodexHeaders(credentials))) {\n\t\t\tconsole.log(`${name}: ${value}`);\n\t\t}\n\t}\n}\n\nasync function runOpenAICodexAuth(args: AuthArgs): Promise<void> {\n\tconst storage = new JsonOpenAICodexAuthStorage({\n\t\t...(args.authFile !== undefined && { path: args.authFile }),\n\t});\n\tconst client = new OpenAICodexOAuthClient({ storage });\n\n\tif (args.logout) {\n\t\tawait client.logout();\n\t\tconsole.log(`Cleared OpenAI Codex credentials from ${storage.path}`);\n\t\treturn;\n\t}\n\n\tif (args.status) {\n\t\tconst credentials = await storage.get();\n\t\tif (!credentials) {\n\t\t\tconsole.log(`No OpenAI Codex credentials found at ${storage.path}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tprintCredentials(credentials, args);\n\t\treturn;\n\t}\n\n\tif (args.refresh) {\n\t\tconst credentials = await client.getCredentials();\n\t\tif (!credentials) {\n\t\t\tconsole.log(`No OpenAI Codex credentials found at ${storage.path}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tconsole.log(`Refreshed OpenAI Codex credentials in ${storage.path}`);\n\t\tprintCredentials(credentials, args);\n\t\treturn;\n\t}\n\n\tconst credentials = await client.login({\n\t\t...(args.originator !== undefined && { originator: args.originator }),\n\t\t...(args.manual && {\n\t\t\tonManualCodeInput: async () =>\n\t\t\t\tpromptLine(\"Paste the redirect URL or authorization code, or wait for browser callback:\"),\n\t\t}),\n\t\tonAuth: (info) => {\n\t\t\tconsole.log(info.instructions ?? \"Complete OpenAI Codex authentication in your browser.\");\n\t\t\tconsole.log(info.url);\n\t\t\tif (args.browser !== false) {\n\t\t\t\tvoid openBrowser(info.url).catch((error) => {\n\t\t\t\t\tconsole.warn(`Failed to open browser: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tonPrompt: async (prompt) => promptLine(prompt.message),\n\t});\n\n\tconsole.log(`Saved OpenAI Codex credentials to ${storage.path}`);\n\tprintCredentials(credentials, args);\n}\n\nexport const OAuthCommand: CommandModule<object, AuthArgs> = {\n\tcommand: \"auth\",\n\tdescribe: \"manage OAuth credentials\",\n\tbuilder: (yargs) =>\n\t\tyargs\n\t\t\t.option(\"openai-codex\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"use OpenAI Codex OAuth\",\n\t\t\t})\n\t\t\t.option(\"auth-file\", {\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescribe: \"path to auth.json (defaults to CODEWORK_CREDENTIALS or ~/.codework/aikit/auth.json)\",\n\t\t\t})\n\t\t\t.option(\"browser\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefault: true,\n\t\t\t\tdescribe: \"open the authorization URL in the default browser\",\n\t\t\t})\n\t\t\t.option(\"manual\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefault: false,\n\t\t\t\tdescribe: \"also prompt for a pasted redirect URL or authorization code\",\n\t\t\t})\n\t\t\t.option(\"originator\", {\n\t\t\t\ttype: \"string\",\n\t\t\t\tdefault: \"codework\",\n\t\t\t\tdescribe: \"OAuth originator value\",\n\t\t\t})\n\t\t\t.option(\"status\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"show stored credential status without refreshing\",\n\t\t\t})\n\t\t\t.option(\"refresh\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"refresh stored credentials if expired\",\n\t\t\t})\n\t\t\t.option(\"logout\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"clear stored credentials\",\n\t\t\t})\n\t\t\t.option(\"json\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"print machine-readable output\",\n\t\t\t})\n\t\t\t.option(\"print-headers\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"print request headers for Codex API calls\",\n\t\t\t})\n\t\t\t.check((args) => {\n\t\t\t\tif (!args.openaiCodex) throw new Error(\"choose an auth provider, for example: auth --openai-codex\");\n\t\t\t\tconst actions = [args.status, args.refresh, args.logout].filter(Boolean).length;\n\t\t\t\tif (actions > 1) throw new Error(\"choose only one of --status, --refresh, or --logout\");\n\t\t\t\treturn true;\n\t\t\t}),\n\thandler: async (args) => {\n\t\tawait runOpenAICodexAuth(args);\n\t},\n};\n","#!/usr/bin/env node\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { ModelgenCommand } from \"./cli/modelgen.ts\";\nimport { OAuthCommand } from \"./cli/oauth.ts\";\n\nconst cli = yargs(hideBin(process.argv))\n\t.scriptName(\"aikit\")\n\t.wrap(100)\n\t.help(\"help\", \"show help\")\n\t.alias(\"help\", \"h\")\n\t.version(\"version\", \"show version number\", pkg.version)\n\t.alias(\"version\", \"v\")\n\t.command(ModelgenCommand)\n\t.command(OAuthCommand)\n\t.demandCommand(1, \"Choose a command\")\n\t.strict()\n\t.fail((message, error) => {\n\t\tif (error) throw error;\n\t\tif (message) throw new Error(message);\n\t});\n\ntry {\n\tawait cli.parse();\n} catch (error) {\n\tprocess.exitCode = 1;\n\tconsole.error(error instanceof Error ? error.message : String(error));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["pkg.version"],"sources":["../../package.json","../../src/cli/oauth.ts","../../src/cli.ts"],"sourcesContent":["","import type { CommandModule } from \"yargs\";\nimport {\n\tGitHubCopilotOAuthClient,\n\ttype GitHubCopilotOAuthCredentials,\n\tJsonGitHubCopilotAuthStorage,\n} from \"../oauth/github/copilot.ts\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexOAuthCredentials,\n} from \"../oauth/openai/codex.ts\";\nimport { openBrowser, promptLine } from \"../oauth/interactive.ts\";\nimport {\n\tcheckOAuthProvider,\n\tformatOAuthSummary,\n\toauthLoginIssue,\n\toauthRefreshIssue,\n\toauthNotice,\n\tsummarizeGitHubCopilot,\n\tsummarizeOpenAICodex,\n} from \"../oauth/summary.ts\";\n\n// `?: T | undefined` rather than plain `?: T`: yargs hands these through as explicit `undefined`,\n// which a bare optional property no longer accepts under `exactOptionalPropertyTypes`.\ntype AuthArgs = {\n\topenaiCodex?: boolean | undefined;\n\tgithubCopilot?: boolean | undefined;\n\tauthFile?: string | undefined;\n\tbrowser?: boolean | undefined;\n\tdevice?: boolean | undefined;\n\tstatus?: boolean | undefined;\n\trefresh?: boolean | undefined;\n\tlogout?: boolean | undefined;\n\tjson?: boolean | undefined;\n\tenterprise?: string | undefined;\n\tenableModels?: boolean | undefined;\n};\n\nasync function runOpenAICodexAuth(args: AuthArgs): Promise<void> {\n\tconst storage = new JsonOpenAICodexAuthStorage({\n\t\t...(args.authFile !== undefined && { path: args.authFile }),\n\t});\n\tconst client = new OpenAICodexOAuthClient({ storage });\n\n\tconst show = (credentials: OpenAICodexOAuthCredentials) =>\n\t\tprocess.stdout.write(formatOAuthSummary(summarizeOpenAICodex(credentials), { json: args.json === true }));\n\n\tif (args.logout) {\n\t\tawait client.logout();\n\t\tconsole.warn(oauthNotice(\"cleared\", \"openai-codex\", storage.path));\n\t\treturn;\n\t}\n\n\tif (args.status || args.refresh) {\n\t\t// --status is a read: asking the client for headers would refresh behind it.\n\t\tconst credentials = args.refresh ? await client.getCredentials() : await storage.get();\n\t\tif (!credentials) {\n\t\t\tconsole.error(oauthNotice(\"missing\", \"openai-codex\", storage.path));\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tif (args.refresh) console.warn(oauthNotice(\"refreshed\", \"openai-codex\", storage.path));\n\t\tshow(credentials);\n\t\treturn;\n\t}\n\n\tconst credentials = await client.login({\n\t\tdevice: args.device === true,\n\t\t// stderr, so `--json` stdout stays parseable.\n\t\tonAuth: (info) => {\n\t\t\tconsole.warn(info.instructions ?? \"Complete OpenAI Codex authentication in your browser.\");\n\t\t\tif (info.userCode) console.warn(`Enter code: ${info.userCode}`);\n\t\t\tconsole.warn(info.url);\n\t\t\tif (args.browser !== false) {\n\t\t\t\tvoid openBrowser(info.url, (error) => console.warn(`Failed to open browser: ${error.message}`));\n\t\t\t}\n\t\t},\n\t\tonProgress: (message) => console.warn(message),\n\t\tonPrompt: async (prompt) => promptLine(prompt.message),\n\t});\n\n\tconsole.warn(oauthNotice(\"saved\", \"openai-codex\", storage.path));\n\tshow(credentials);\n}\n\nasync function runGitHubCopilotAuth(args: AuthArgs): Promise<void> {\n\tconst storage = new JsonGitHubCopilotAuthStorage({\n\t\t...(args.authFile !== undefined && { path: args.authFile }),\n\t});\n\tconst client = new GitHubCopilotOAuthClient({ storage });\n\n\tconst show = (credentials: GitHubCopilotOAuthCredentials) =>\n\t\tprocess.stdout.write(formatOAuthSummary(summarizeGitHubCopilot(credentials), { json: args.json === true }));\n\n\tif (args.logout) {\n\t\tawait client.logout();\n\t\tconsole.warn(oauthNotice(\"cleared\", \"github-copilot\", storage.path));\n\t\treturn;\n\t}\n\n\tif (args.status) {\n\t\tconst credentials = await storage.get();\n\t\tif (!credentials) {\n\t\t\tconsole.error(oauthNotice(\"missing\", \"github-copilot\", storage.path));\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tshow(credentials);\n\t\treturn;\n\t}\n\n\t// GitHub OAuth tokens never expire; there is no refresh path.\n\tconst credentials = await client.login({\n\t\t...(args.enterprise !== undefined && { enterpriseUrl: args.enterprise }),\n\t\tenableModels: args.enableModels === true,\n\t\t// stderr, so `--json` stdout stays parseable.\n\t\tonAuth: (info) => {\n\t\t\tconsole.warn(info.instructions ?? \"Complete GitHub Copilot authentication in your browser.\");\n\t\t\tconsole.warn(`Enter code: ${info.userCode}`);\n\t\t\tconsole.warn(info.url);\n\t\t\tif (args.browser !== false) {\n\t\t\t\tvoid openBrowser(info.url, (error) => console.warn(`Failed to open browser: ${error.message}`));\n\t\t\t}\n\t\t},\n\t\tonProgress: (message) => console.warn(message),\n\t});\n\n\tconsole.warn(oauthNotice(\"saved\", \"github-copilot\", storage.path));\n\tshow(credentials);\n}\n\nexport const OAuthCommand: CommandModule<object, AuthArgs> = {\n\tcommand: \"auth\",\n\tdescribe: \"manage OAuth credentials\",\n\tbuilder: (yargs) =>\n\t\tyargs\n\t\t\t.option(\"openai-codex\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"use OpenAI Codex OAuth\",\n\t\t\t})\n\t\t\t.option(\"github-copilot\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"use GitHub Copilot OAuth (device flow)\",\n\t\t\t})\n\t\t\t.option(\"enterprise\", {\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescribe: \"GitHub Enterprise domain for GitHub Copilot login\",\n\t\t\t})\n\t\t\t.option(\"enable-models\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"enable unconfigured Copilot catalog models after login\",\n\t\t\t})\n\t\t\t.option(\"auth-file\", {\n\t\t\t\ttype: \"string\",\n\t\t\t\tdescribe: \"path to auth.json (defaults to CODEWORK_CREDENTIALS or ~/.codework/aikit/auth.json)\",\n\t\t\t})\n\t\t\t.option(\"browser\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefault: true,\n\t\t\t\tdescribe: \"open the authorization URL in the default browser\",\n\t\t\t})\n\t\t\t.option(\"device\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefault: false,\n\t\t\t\tdescribe: \"use the device-code flow instead of a localhost browser callback\",\n\t\t\t})\n\t\t\t.option(\"status\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"show stored credential status without refreshing\",\n\t\t\t})\n\t\t\t.option(\"refresh\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"refresh stored credentials if expired\",\n\t\t\t})\n\t\t\t.option(\"logout\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"clear stored credentials\",\n\t\t\t})\n\t\t\t.option(\"json\", {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdescribe: \"print machine-readable output\",\n\t\t\t})\n\t\t\t// yargs types this callback with the kebab-case keys, so read those.\n\t\t\t.check((args) => {\n\t\t\t\tconst checked = checkOAuthProvider({\n\t\t\t\t\topenaiCodex: args[\"openai-codex\"],\n\t\t\t\t\tgithubCopilot: args[\"github-copilot\"],\n\t\t\t\t});\n\t\t\t\tif (!checked.ok) throw new Error(checked.message);\n\t\t\t\tif ([args.status, args.refresh, args.logout].filter(Boolean).length > 1) {\n\t\t\t\t\tthrow new Error(\"choose only one of --status, --refresh, or --logout\");\n\t\t\t\t}\n\t\t\t\tconst issue =\n\t\t\t\t\toauthLoginIssue(checked.provider, {\n\t\t\t\t\t\tdevice: args.device,\n\t\t\t\t\t\tenterprise: args.enterprise,\n\t\t\t\t\t\tenableModels: args[\"enable-models\"],\n\t\t\t\t\t}) ?? (args.refresh ? oauthRefreshIssue(checked.provider) : undefined);\n\t\t\t\tif (issue) throw new Error(issue);\n\t\t\t\treturn true;\n\t\t\t}),\n\thandler: async (args) => {\n\t\tif (args.githubCopilot) {\n\t\t\tawait runGitHubCopilotAuth(args);\n\t\t\treturn;\n\t\t}\n\t\tawait runOpenAICodexAuth(args);\n\t},\n};\n","#!/usr/bin/env node\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { ModelgenCommand } from \"./cli/modelgen.ts\";\nimport { OAuthCommand } from \"./cli/oauth.ts\";\n\nconst cli = yargs(hideBin(process.argv))\n\t.scriptName(\"aikit\")\n\t.wrap(100)\n\t.help(\"help\", \"show help\")\n\t.alias(\"help\", \"h\")\n\t.version(\"version\", \"show version number\", pkg.version)\n\t.alias(\"version\", \"v\")\n\t.command(ModelgenCommand)\n\t.command(OAuthCommand)\n\t.demandCommand(1, \"Choose a command\")\n\t.strict()\n\t.fail((message, error) => {\n\t\tif (error) throw error;\n\t\tif (message) throw new Error(message);\n\t});\n\ntry {\n\tawait cli.parse();\n} catch (error) {\n\tprocess.exitCode = 1;\n\tconsole.error(error instanceof Error ? error.message : String(error));\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { i as pollDeviceCode, n as isObject, r as readEnv, t as JsonAuthStorage } from "./storage-v6qjTQ0v.mjs";
|
|
1
2
|
import dedent from "dedent";
|
|
2
3
|
//#region src/oauth/openai/codex.ts
|
|
3
4
|
/**
|
|
@@ -18,47 +19,20 @@ import dedent from "dedent";
|
|
|
18
19
|
* not exported.
|
|
19
20
|
*/
|
|
20
21
|
const CODEWORK_OAUTH_CALLBACK_HOST = "CODEWORK_OAUTH_CALLBACK_HOST";
|
|
21
|
-
const CODEWORK_CREDENTIALS = "CODEWORK_CREDENTIALS";
|
|
22
|
-
const CODEWORK_HOME_DIR = "CODEWORK_HOME_DIR";
|
|
23
22
|
const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
24
23
|
const AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize";
|
|
25
24
|
const TOKEN_URL = "https://auth.openai.com/oauth/token";
|
|
26
25
|
const DEFAULT_REDIRECT_URI = "http://localhost:1455/auth/callback";
|
|
26
|
+
const DEVICE_USER_CODE_URL = "https://auth.openai.com/api/accounts/deviceauth/usercode";
|
|
27
|
+
const DEVICE_TOKEN_URL = "https://auth.openai.com/api/accounts/deviceauth/token";
|
|
28
|
+
const DEVICE_VERIFICATION_URI = "https://auth.openai.com/codex/device";
|
|
29
|
+
const DEVICE_REDIRECT_URI = "https://auth.openai.com/deviceauth/callback";
|
|
30
|
+
const DEVICE_TIMEOUT_SECONDS = 900;
|
|
27
31
|
const DEFAULT_SCOPE = "openid profile email offline_access";
|
|
28
32
|
const DEFAULT_ORIGINATOR = "codework";
|
|
29
33
|
const DEFAULT_PROVIDER_ID = "openai-codex";
|
|
30
34
|
const JWT_CLAIM_PATH = "https://api.openai.com/auth";
|
|
31
35
|
const REFRESH_SKEW_MS = 6e4;
|
|
32
|
-
function readEnv(name) {
|
|
33
|
-
if (typeof process === "undefined") return void 0;
|
|
34
|
-
return process.env[name];
|
|
35
|
-
}
|
|
36
|
-
function joinPath(...parts) {
|
|
37
|
-
return parts.filter(Boolean).join("/").replaceAll(/\/+/g, "/");
|
|
38
|
-
}
|
|
39
|
-
function expandHome(path) {
|
|
40
|
-
if (path === "~") return homeDirectory();
|
|
41
|
-
if (path.startsWith("~/")) return joinPath(homeDirectory(), path.slice(2));
|
|
42
|
-
return path;
|
|
43
|
-
}
|
|
44
|
-
function homeDirectory() {
|
|
45
|
-
const home = readEnv("HOME") ?? readEnv("USERPROFILE");
|
|
46
|
-
if (!home) throw new Error("unable to resolve home directory for OpenAI Codex auth storage");
|
|
47
|
-
return home;
|
|
48
|
-
}
|
|
49
|
-
function codeworkHomeDirectory() {
|
|
50
|
-
const override = readEnv(CODEWORK_HOME_DIR);
|
|
51
|
-
if (override) return expandHome(override);
|
|
52
|
-
return joinPath(homeDirectory(), ".codework");
|
|
53
|
-
}
|
|
54
|
-
function defaultOpenAICodexAuthFilePath() {
|
|
55
|
-
const authFile = readEnv(CODEWORK_CREDENTIALS);
|
|
56
|
-
if (authFile) return expandHome(authFile);
|
|
57
|
-
return joinPath(codeworkHomeDirectory(), "aikit", "auth.json");
|
|
58
|
-
}
|
|
59
|
-
function isObject(value) {
|
|
60
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
61
|
-
}
|
|
62
36
|
function isOpenAICodexCredentials(value) {
|
|
63
37
|
if (!isObject(value)) return false;
|
|
64
38
|
return typeof value.access === "string" && typeof value.refresh === "string" && typeof value.expires === "number" && typeof value.accountId === "string";
|
|
@@ -283,7 +257,9 @@ function oauthErrorHtml(message, details) {
|
|
|
283
257
|
...details !== void 0 && { details }
|
|
284
258
|
});
|
|
285
259
|
}
|
|
286
|
-
async function startLocalOAuthServer(state) {
|
|
260
|
+
async function startLocalOAuthServer(state, redirectUri) {
|
|
261
|
+
const callback = new URL(redirectUri);
|
|
262
|
+
const port = Number(callback.port || (callback.protocol === "https:" ? 443 : 80));
|
|
287
263
|
const http = await import("node:http").catch(() => void 0);
|
|
288
264
|
if (!http) throw new Error("openAI codex OAuth callback server is only available in Node.js environments");
|
|
289
265
|
let settleWait;
|
|
@@ -298,7 +274,7 @@ async function startLocalOAuthServer(state) {
|
|
|
298
274
|
const server = http.createServer((req, res) => {
|
|
299
275
|
try {
|
|
300
276
|
const url = new URL(req.url || "", "http://localhost");
|
|
301
|
-
if (url.pathname !==
|
|
277
|
+
if (url.pathname !== callback.pathname) {
|
|
302
278
|
res.statusCode = 404;
|
|
303
279
|
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
304
280
|
res.end(oauthErrorHtml("Callback route not found."));
|
|
@@ -335,84 +311,139 @@ async function startLocalOAuthServer(state) {
|
|
|
335
311
|
});
|
|
336
312
|
};
|
|
337
313
|
return new Promise((resolve) => {
|
|
338
|
-
server.listen(
|
|
314
|
+
server.listen(port, readEnv(CODEWORK_OAUTH_CALLBACK_HOST) || "127.0.0.1", () => {
|
|
339
315
|
resolve({
|
|
340
316
|
close,
|
|
341
|
-
cancelWait: () => {
|
|
342
|
-
settleWait?.(null);
|
|
343
|
-
},
|
|
344
317
|
waitForCode: () => waitForCodePromise
|
|
345
318
|
});
|
|
346
|
-
}).on("error", () => {
|
|
319
|
+
}).on("error", (error) => {
|
|
347
320
|
settleWait?.(null);
|
|
348
321
|
resolve({
|
|
349
322
|
close,
|
|
350
|
-
|
|
351
|
-
|
|
323
|
+
waitForCode: async () => null,
|
|
324
|
+
listenError: error
|
|
352
325
|
});
|
|
353
326
|
});
|
|
354
327
|
});
|
|
355
328
|
}
|
|
356
329
|
async function loginOpenAICodex(options) {
|
|
330
|
+
if (options.device) return loginOpenAICodexDeviceCode(options);
|
|
357
331
|
const flow = await createOpenAICodexAuthorizationFlow(options);
|
|
358
|
-
const server = await startLocalOAuthServer(flow.state);
|
|
332
|
+
const server = await startLocalOAuthServer(flow.state, flow.redirectUri);
|
|
359
333
|
options.onAuth({
|
|
360
334
|
url: flow.url,
|
|
361
335
|
instructions: "Complete the browser login to finish OpenAI Codex authentication."
|
|
362
336
|
});
|
|
337
|
+
if (server.listenError) options.onProgress?.(`Could not listen on ${flow.redirectUri}: ${server.listenError.message}. Another sign-in is probably already running on that port and would receive the callback. Finish the login in the browser, then paste the redirect URL here.`);
|
|
363
338
|
let code;
|
|
364
339
|
try {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
let manualError;
|
|
368
|
-
const manualPromise = options.onManualCodeInput().then((input) => {
|
|
369
|
-
manualCode = input;
|
|
370
|
-
if (input.trim()) server.cancelWait();
|
|
371
|
-
}).catch((error) => {
|
|
372
|
-
manualError = error instanceof Error ? error : new Error(String(error));
|
|
373
|
-
server.cancelWait();
|
|
374
|
-
});
|
|
375
|
-
const result = await server.waitForCode();
|
|
376
|
-
if (manualError) throw manualError;
|
|
377
|
-
if (result?.code) code = result.code;
|
|
378
|
-
else if (manualCode) {
|
|
379
|
-
const parsed = parseOpenAICodexAuthorizationInput(manualCode);
|
|
380
|
-
if (parsed.state && parsed.state !== flow.state) throw new Error("state mismatch");
|
|
381
|
-
code = parsed.code;
|
|
382
|
-
}
|
|
383
|
-
if (!code) {
|
|
384
|
-
await manualPromise;
|
|
385
|
-
if (manualError) throw manualError;
|
|
386
|
-
if (manualCode) {
|
|
387
|
-
const parsed = parseOpenAICodexAuthorizationInput(manualCode);
|
|
388
|
-
if (parsed.state && parsed.state !== flow.state) throw new Error("state mismatch");
|
|
389
|
-
code = parsed.code;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
} else {
|
|
393
|
-
const result = await server.waitForCode();
|
|
394
|
-
if (result?.code) code = result.code;
|
|
395
|
-
}
|
|
340
|
+
const result = await server.waitForCode();
|
|
341
|
+
if (result?.code) code = result.code;
|
|
396
342
|
if (!code) {
|
|
397
343
|
const parsed = parseOpenAICodexAuthorizationInput(await options.onPrompt({ message: "Paste the authorization code or full redirect URL:" }));
|
|
398
344
|
if (parsed.state && parsed.state !== flow.state) throw new Error("state mismatch");
|
|
399
345
|
code = parsed.code;
|
|
400
346
|
}
|
|
401
347
|
if (!code) throw new Error("missing authorization code");
|
|
402
|
-
|
|
403
|
-
if (tokenResult.type !== "success") throw new Error(tokenResult.message);
|
|
404
|
-
const accountId = getOpenAICodexAccountId(tokenResult.access);
|
|
405
|
-
if (!accountId) throw new Error("failed to extract accountId from token");
|
|
406
|
-
return {
|
|
407
|
-
access: tokenResult.access,
|
|
408
|
-
refresh: tokenResult.refresh,
|
|
409
|
-
expires: tokenResult.expires,
|
|
410
|
-
accountId
|
|
411
|
-
};
|
|
348
|
+
return await credentialsFromCode(code, flow.verifier, flow.redirectUri);
|
|
412
349
|
} finally {
|
|
413
350
|
await server.close();
|
|
414
351
|
}
|
|
415
352
|
}
|
|
353
|
+
/** The step both flows share: redeem the code, then read the account off the JWT. */
|
|
354
|
+
async function credentialsFromCode(code, verifier, redirectUri) {
|
|
355
|
+
const tokenResult = await exchangeOpenAICodexAuthorizationCode(code, verifier, redirectUri);
|
|
356
|
+
if (tokenResult.type !== "success") throw new Error(tokenResult.message);
|
|
357
|
+
const accountId = getOpenAICodexAccountId(tokenResult.access);
|
|
358
|
+
if (!accountId) throw new Error("failed to extract accountId from token");
|
|
359
|
+
return {
|
|
360
|
+
access: tokenResult.access,
|
|
361
|
+
refresh: tokenResult.refresh,
|
|
362
|
+
expires: tokenResult.expires,
|
|
363
|
+
accountId
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/** Ask for a user code to type at {@link DEVICE_VERIFICATION_URI}. */
|
|
367
|
+
async function createOpenAICodexDeviceAuth(options = {}) {
|
|
368
|
+
const response = await fetch(DEVICE_USER_CODE_URL, {
|
|
369
|
+
method: "POST",
|
|
370
|
+
headers: { "Content-Type": "application/json" },
|
|
371
|
+
body: JSON.stringify({ client_id: CLIENT_ID }),
|
|
372
|
+
signal: options.signal ?? null
|
|
373
|
+
});
|
|
374
|
+
if (!response.ok) {
|
|
375
|
+
if (response.status === 404) throw new Error("OpenAI Codex device code login is not available for this account. Use the browser login instead.");
|
|
376
|
+
const body = await response.text().catch(() => "");
|
|
377
|
+
throw new Error(`OpenAI Codex device code request failed (${response.status})${body ? `: ${redactOAuthSecrets(body)}` : ""}`);
|
|
378
|
+
}
|
|
379
|
+
const data = await response.json();
|
|
380
|
+
if (!isObject(data)) throw new Error("Invalid OpenAI Codex device code response");
|
|
381
|
+
const interval = typeof data.interval === "string" ? Number(data.interval.trim()) : data.interval;
|
|
382
|
+
if (typeof data.device_auth_id !== "string" || typeof data.user_code !== "string" || typeof interval !== "number" || !Number.isFinite(interval) || interval < 0) throw new Error("Invalid OpenAI Codex device code response fields");
|
|
383
|
+
return {
|
|
384
|
+
deviceAuthId: data.device_auth_id,
|
|
385
|
+
userCode: data.user_code,
|
|
386
|
+
verificationUri: DEVICE_VERIFICATION_URI,
|
|
387
|
+
intervalSeconds: interval
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
/** Wait for the code to be approved; the server returns the code and its verifier. */
|
|
391
|
+
async function pollOpenAICodexDeviceAuth(device, options = {}) {
|
|
392
|
+
return pollDeviceCode({
|
|
393
|
+
intervalSeconds: device.intervalSeconds,
|
|
394
|
+
expiresInSeconds: DEVICE_TIMEOUT_SECONDS,
|
|
395
|
+
...options.signal !== void 0 && { signal: options.signal },
|
|
396
|
+
poll: async () => {
|
|
397
|
+
const response = await fetch(DEVICE_TOKEN_URL, {
|
|
398
|
+
method: "POST",
|
|
399
|
+
headers: { "Content-Type": "application/json" },
|
|
400
|
+
body: JSON.stringify({
|
|
401
|
+
device_auth_id: device.deviceAuthId,
|
|
402
|
+
user_code: device.userCode
|
|
403
|
+
}),
|
|
404
|
+
signal: options.signal ?? null
|
|
405
|
+
});
|
|
406
|
+
if (response.ok) {
|
|
407
|
+
const data = await response.json();
|
|
408
|
+
if (!isObject(data) || typeof data.authorization_code !== "string" || typeof data.code_verifier !== "string") return {
|
|
409
|
+
status: "failed",
|
|
410
|
+
message: "Invalid OpenAI Codex device auth token response"
|
|
411
|
+
};
|
|
412
|
+
return {
|
|
413
|
+
status: "complete",
|
|
414
|
+
value: {
|
|
415
|
+
authorizationCode: data.authorization_code,
|
|
416
|
+
codeVerifier: data.code_verifier
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
if (response.status === 403 || response.status === 404) return { status: "pending" };
|
|
421
|
+
const body = await response.text().catch(() => "");
|
|
422
|
+
let errorCode;
|
|
423
|
+
try {
|
|
424
|
+
const parsed = JSON.parse(body);
|
|
425
|
+
const error = isObject(parsed) ? parsed.error : void 0;
|
|
426
|
+
errorCode = isObject(error) ? error.code : error;
|
|
427
|
+
} catch {}
|
|
428
|
+
if (errorCode === "deviceauth_authorization_pending") return { status: "pending" };
|
|
429
|
+
if (errorCode === "slow_down") return { status: "slow_down" };
|
|
430
|
+
return {
|
|
431
|
+
status: "failed",
|
|
432
|
+
message: `OpenAI Codex device authorization failed (${response.status})${body ? `: ${redactOAuthSecrets(body)}` : ""}`
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
async function loginOpenAICodexDeviceCode(options) {
|
|
438
|
+
const device = await createOpenAICodexDeviceAuth(options);
|
|
439
|
+
options.onAuth({
|
|
440
|
+
url: device.verificationUri,
|
|
441
|
+
userCode: device.userCode,
|
|
442
|
+
instructions: "Open the URL and enter the code to finish OpenAI Codex authentication."
|
|
443
|
+
});
|
|
444
|
+
const { authorizationCode, codeVerifier } = await pollOpenAICodexDeviceAuth(device, options);
|
|
445
|
+
return credentialsFromCode(authorizationCode, codeVerifier, DEVICE_REDIRECT_URI);
|
|
446
|
+
}
|
|
416
447
|
async function refreshOpenAICodexToken(refreshToken) {
|
|
417
448
|
const result = await refreshAccessToken(refreshToken);
|
|
418
449
|
if (result.type !== "success") throw new Error(result.message);
|
|
@@ -433,61 +464,28 @@ function openAICodexHeaders(credentials) {
|
|
|
433
464
|
};
|
|
434
465
|
}
|
|
435
466
|
var JsonOpenAICodexAuthStorage = class {
|
|
436
|
-
|
|
437
|
-
providerId;
|
|
467
|
+
storage;
|
|
438
468
|
constructor(options = {}) {
|
|
439
|
-
this.
|
|
440
|
-
|
|
469
|
+
this.storage = new JsonAuthStorage({
|
|
470
|
+
providerId: options.providerId ?? DEFAULT_PROVIDER_ID,
|
|
471
|
+
isCredentials: isOpenAICodexCredentials,
|
|
472
|
+
...options.path !== void 0 && { path: options.path }
|
|
473
|
+
});
|
|
441
474
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
if (!file) return void 0;
|
|
445
|
-
if (isOpenAICodexCredentials(file)) return file;
|
|
446
|
-
const direct = file[this.providerId];
|
|
447
|
-
if (isOpenAICodexCredentials(direct)) return direct;
|
|
448
|
-
const providers = file.providers;
|
|
449
|
-
if (isObject(providers) && isOpenAICodexCredentials(providers[this.providerId])) return providers[this.providerId];
|
|
475
|
+
get path() {
|
|
476
|
+
return this.storage.path;
|
|
450
477
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const next = isObject(current) && !isOpenAICodexCredentials(current) ? current : {};
|
|
454
|
-
next[this.providerId] = credentials;
|
|
455
|
-
await this.writeFile(next);
|
|
478
|
+
get providerId() {
|
|
479
|
+
return this.storage.providerId;
|
|
456
480
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
if (!current) return;
|
|
460
|
-
if (isOpenAICodexCredentials(current)) {
|
|
461
|
-
await this.writeFile({});
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
delete current[this.providerId];
|
|
465
|
-
const providers = current.providers;
|
|
466
|
-
if (isObject(providers)) delete providers[this.providerId];
|
|
467
|
-
await this.writeFile(current);
|
|
481
|
+
get() {
|
|
482
|
+
return this.storage.get();
|
|
468
483
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
try {
|
|
472
|
-
const text = await fs.readFile(this.path, "utf8");
|
|
473
|
-
const parsed = JSON.parse(text);
|
|
474
|
-
return isObject(parsed) ? parsed : void 0;
|
|
475
|
-
} catch (error) {
|
|
476
|
-
if (isObject(error) && error.code === "ENOENT") return void 0;
|
|
477
|
-
throw error;
|
|
478
|
-
}
|
|
484
|
+
set(credentials) {
|
|
485
|
+
return this.storage.set(credentials);
|
|
479
486
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
const path = await import("node:path");
|
|
483
|
-
await fs.mkdir(path.dirname(this.path), { recursive: true });
|
|
484
|
-
const tempPath = `${this.path}.${process.pid}.${Date.now()}.tmp`;
|
|
485
|
-
await fs.writeFile(tempPath, `${JSON.stringify(value, null, " ")}\n`, {
|
|
486
|
-
encoding: "utf8",
|
|
487
|
-
mode: 384
|
|
488
|
-
});
|
|
489
|
-
await fs.chmod(tempPath, 384);
|
|
490
|
-
await fs.rename(tempPath, this.path);
|
|
487
|
+
clear() {
|
|
488
|
+
return this.storage.clear();
|
|
491
489
|
}
|
|
492
490
|
};
|
|
493
491
|
var OpenAICodexOAuthClient = class {
|
|
@@ -536,6 +534,6 @@ async function getOpenAICodexApiKey(options = {}) {
|
|
|
536
534
|
return new OpenAICodexOAuthClient(options).getApiKey();
|
|
537
535
|
}
|
|
538
536
|
//#endregion
|
|
539
|
-
export {
|
|
537
|
+
export { createOpenAICodexDeviceAuth as a, getOpenAICodexApiKey as c, pollOpenAICodexDeviceAuth as d, refreshOpenAICodexToken as f, createOpenAICodexAuthorizationFlow as i, openAICodexHeaders as l, OPENAI_CODEX_API_KEY_ENV as n, exchangeOpenAICodexAuthorizationCode as o, OpenAICodexOAuthClient as r, getOpenAICodexAccountId as s, JsonOpenAICodexAuthStorage as t, parseOpenAICodexAuthorizationInput as u };
|
|
540
538
|
|
|
541
|
-
//# sourceMappingURL=codex-
|
|
539
|
+
//# sourceMappingURL=codex-CLDBTrFm.mjs.map
|