@codeworksh/aikit 0.5.0 → 0.6.0-dev.20260613095948
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 +1 -1
- package/cli.mjs +95 -5
- package/cli.mjs.map +1 -1
- package/{codex-DfYk740t.mjs → codex-C36oU6yH.mjs} +30 -23
- package/codex-C36oU6yH.mjs.map +1 -0
- package/index.d.mts +142 -75
- package/index.mjs +8 -3
- package/index.mjs.map +1 -1
- package/oauth/openai/codex.d.mts +27 -18
- package/oauth/openai/codex.mjs +2 -2
- package/openai-codex-CZrBnLAJ.mjs +753 -0
- package/openai-codex-CZrBnLAJ.mjs.map +1 -0
- package/openai-codex-bzfev3us.mjs +2 -0
- package/package.json +3 -2
- package/{registry-Cfdk78qk.mjs → registry-DUKrGxt4.mjs} +12 -7
- package/{registry-Cfdk78qk.mjs.map → registry-DUKrGxt4.mjs.map} +1 -1
- package/codex-DfYk740t.mjs.map +0 -1
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026 Sanchit Kudari
|
|
3
|
+
Copyright (c) 2026 Sanchit Kudari <0xsanchit@gmail.com> & Contributors
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/cli.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as protocolForPackage, c as ModelCatalog, l as lazy, n as isAISDKPackage, s as Model, u as Filesystem } from "./registry-
|
|
3
|
-
import { c as openAICodexHeaders,
|
|
2
|
+
import { a as protocolForPackage, c as ModelCatalog, l as lazy, n as isAISDKPackage, s as Model, u as Filesystem } from "./registry-DUKrGxt4.mjs";
|
|
3
|
+
import { c as openAICodexHeaders, r as OpenAICodexOAuthClient, t as JsonOpenAICodexAuthStorage } from "./codex-C36oU6yH.mjs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import yargs from "yargs";
|
|
6
6
|
import { hideBin } from "yargs/helpers";
|
|
7
7
|
import { mapValues, pickBy, pipe } from "remeda";
|
|
8
8
|
//#region package.json
|
|
9
|
-
var version = "0.
|
|
9
|
+
var version = "0.6.0";
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/cli/modelgen.ts
|
|
12
12
|
const DEFAULT_PROVIDER_BASE_URLS = {
|
|
@@ -82,10 +82,100 @@ function applyThinkingLevelMetadata(model) {
|
|
|
82
82
|
if (model.id.includes("opus-4-6") || model.id.includes("opus-4.6")) mergeThinkingLevelMap(model, { xhigh: "max" });
|
|
83
83
|
if (model.id.includes("opus-4-7") || model.id.includes("opus-4.7")) mergeThinkingLevelMap(model, { xhigh: "xhigh" });
|
|
84
84
|
}
|
|
85
|
+
const OPENAI_CODEX_PROVIDER_ID = "openai-codex";
|
|
86
|
+
const OPENAI_CODEX_NPM = "@codeworksh/ai-sdk-openai-codex";
|
|
87
|
+
const OPENAI_CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
88
|
+
const OPENAI_CODEX_CONTEXT = 272e3;
|
|
89
|
+
const OPENAI_CODEX_SPARK_CONTEXT = 128e3;
|
|
90
|
+
const OPENAI_CODEX_MAX_TOKENS = 128e3;
|
|
91
|
+
const OPENAI_CODEX_MODELS = [
|
|
92
|
+
{
|
|
93
|
+
id: "gpt-5.3-codex-spark",
|
|
94
|
+
name: "GPT-5.3 Codex Spark",
|
|
95
|
+
input: ["text"],
|
|
96
|
+
cost: {
|
|
97
|
+
input: 1.75,
|
|
98
|
+
output: 14,
|
|
99
|
+
cacheRead: .175,
|
|
100
|
+
cacheWrite: 0
|
|
101
|
+
},
|
|
102
|
+
contextWindow: OPENAI_CODEX_SPARK_CONTEXT
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "gpt-5.4",
|
|
106
|
+
name: "GPT-5.4",
|
|
107
|
+
input: ["text", "image"],
|
|
108
|
+
cost: {
|
|
109
|
+
input: 2.5,
|
|
110
|
+
output: 15,
|
|
111
|
+
cacheRead: .25,
|
|
112
|
+
cacheWrite: 0
|
|
113
|
+
},
|
|
114
|
+
contextWindow: OPENAI_CODEX_CONTEXT
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: "gpt-5.4-mini",
|
|
118
|
+
name: "GPT-5.4 mini",
|
|
119
|
+
input: ["text", "image"],
|
|
120
|
+
cost: {
|
|
121
|
+
input: .75,
|
|
122
|
+
output: 4.5,
|
|
123
|
+
cacheRead: .075,
|
|
124
|
+
cacheWrite: 0
|
|
125
|
+
},
|
|
126
|
+
contextWindow: OPENAI_CODEX_CONTEXT
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: "gpt-5.5",
|
|
130
|
+
name: "GPT-5.5",
|
|
131
|
+
input: ["text", "image"],
|
|
132
|
+
cost: {
|
|
133
|
+
input: 5,
|
|
134
|
+
output: 30,
|
|
135
|
+
cacheRead: .5,
|
|
136
|
+
cacheWrite: 0
|
|
137
|
+
},
|
|
138
|
+
contextWindow: OPENAI_CODEX_CONTEXT
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
function openAICodexBuiltInModels() {
|
|
142
|
+
const models = {};
|
|
143
|
+
for (const seed of OPENAI_CODEX_MODELS) {
|
|
144
|
+
const info = {
|
|
145
|
+
...seed,
|
|
146
|
+
provider: {
|
|
147
|
+
id: OPENAI_CODEX_PROVIDER_ID,
|
|
148
|
+
name: "OpenAI Codex (ChatGPT)",
|
|
149
|
+
source: "custom",
|
|
150
|
+
env: ["OPENAI_CODEX_API_KEY"]
|
|
151
|
+
},
|
|
152
|
+
baseUrl: OPENAI_CODEX_BASE_URL,
|
|
153
|
+
reasoning: true,
|
|
154
|
+
thinkingLevelMap: { off: null },
|
|
155
|
+
maxTokens: OPENAI_CODEX_MAX_TOKENS,
|
|
156
|
+
npm: OPENAI_CODEX_NPM,
|
|
157
|
+
api: {
|
|
158
|
+
id: seed.id,
|
|
159
|
+
url: OPENAI_CODEX_BASE_URL,
|
|
160
|
+
method: Model.APIMethodEnum.responses
|
|
161
|
+
},
|
|
162
|
+
providerOptionsKey: OPENAI_CODEX_PROVIDER_ID,
|
|
163
|
+
protocol: Model.KnownProviderEnum.openaiCodex
|
|
164
|
+
};
|
|
165
|
+
applyThinkingLevelMetadata(info);
|
|
166
|
+
models[seed.id] = info;
|
|
167
|
+
}
|
|
168
|
+
return models;
|
|
169
|
+
}
|
|
85
170
|
async function generateModels(args = {}) {
|
|
86
171
|
const path = resolve(args.path ?? ModelCatalog.path());
|
|
87
|
-
const
|
|
88
|
-
|
|
172
|
+
const modelsDev = await loadBuiltInFromModelsDev();
|
|
173
|
+
const customCodexModels = openAICodexBuiltInModels();
|
|
174
|
+
const allModels = {
|
|
175
|
+
...modelsDev,
|
|
176
|
+
[OPENAI_CODEX_PROVIDER_ID]: customCodexModels
|
|
177
|
+
};
|
|
178
|
+
await Filesystem.writeJson(path, allModels);
|
|
89
179
|
return path;
|
|
90
180
|
}
|
|
91
181
|
const ModelgenCommand = {
|
package/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["pkg.version"],"sources":["../../package.json","../../src/cli/modelgen.ts","../../src/cli/oauth.ts","../../src/cli.ts"],"sourcesContent":["","import { Filesystem, lazy } from \"@codeworksh/utils\";\nimport { resolve } from \"node:path\";\nimport { mapValues, pickBy, pipe } from \"remeda\";\nimport type { CommandModule } from \"yargs\";\nimport { DEFAULT_AI_SDK_PACKAGE, isAISDKPackage, protocolForPackage } from \"../llm/registry\";\nimport { ModelCatalog } from \"../model/catalog\";\nimport { Model } from \"../model/model\";\n\nconst DEFAULT_PROVIDER_BASE_URLS: Partial<Record<Model.KnownProviderEnum, string>> = {\n\t[Model.KnownProviderEnum.anthropic]: \"https://api.anthropic.com/v1\",\n\t[Model.KnownProviderEnum.openai]: \"https://api.openai.com/v1\",\n\t[Model.KnownProviderEnum.openrouter]: \"https://openrouter.ai/api/v1\",\n\t[Model.KnownProviderEnum.xai]: \"https://api.x.ai/v1\",\n};\n\ninterface ModelsDevModel {\n\tid: string;\n\tname: string;\n\tfamily: string;\n\tattachment: boolean;\n\treasoning?: boolean;\n\ttool_call?: boolean;\n\ttemperature?: boolean;\n\tknowledge?: string | boolean;\n\trelease_date: string;\n\tlast_updated: string;\n\tmodalities: {\n\t\tinput?: string[];\n\t\toutput: string[];\n\t};\n\topen_weights: boolean;\n\tbaseUrl?: string;\n\theaders?: Record<string, string>;\n\tcost?: {\n\t\tinput?: number;\n\t\toutput?: number;\n\t\tcache_read?: number;\n\t\tcache_write?: number;\n\t};\n\tlimit?: {\n\t\tcontext?: number;\n\t\toutput?: number;\n\t};\n\tstructured_output?: boolean;\n\tprovider?: {\n\t\tnpm?: string;\n\t\tapi?: string;\n\t\theaders?: Record<string, string>;\n\t};\n}\n\ninterface ModelsDevProvider {\n\tid: string;\n\tenv: string[];\n\tnpm?: string;\n\tapi?: string;\n\tname: string;\n\tdoc?: string; // reference documentation link\n\tkey?: string; // runtime placeholder for api/oauth key\n\theaders?: Record<string, string>; // custom overrides at provider level\n\tmodels: Record<string, ModelsDevModel>;\n}\n\nexport type BuiltInModels = Partial<Record<string, Record<string, Model.Info>>>;\n\n// Doesn't represent the full spec from models.dev.\n// Represents the provider entries on a best-effort basis.\ntype ModelsDevCatalog = Record<string, ModelsDevProvider>;\ntype LazyModelsDevCatalog = ReturnType<typeof lazy<Promise<ModelsDevCatalog>>>;\n\nfunction modelsDevURL(): string {\n\treturn process.env.OPENCODE_MODELS_URL || \"https://models.dev\";\n}\n\nfunction modelsDevPath(): string | undefined {\n\treturn process.env.OPENCODE_MODELS_DEV_FILE;\n}\n\nconst modelsDevData: LazyModelsDevCatalog = lazy(async () => {\n\tconst path = modelsDevPath();\n\tif (path) {\n\t\tconst result = await Filesystem.readJson<ModelsDevCatalog>(path).catch(() => undefined);\n\t\tif (result) return result;\n\t}\n\n\tconst json = await fetch(`${modelsDevURL()}/api.json`).then((x) => x.text());\n\treturn JSON.parse(json) as ModelsDevCatalog;\n});\n\nasync function pullModelsDevData(): Promise<ModelsDevCatalog> {\n\treturn modelsDevData();\n}\n\nfunction toModelValue(providerId: string, provider: ModelsDevProvider, model: ModelsDevModel): Model.Info | undefined {\n\treturn applyModification(providerId, provider, model);\n}\n\nasync function loadBuiltInFromModelsDev() {\n\tconst catalog = await pullModelsDevData();\n\treturn pipe(\n\t\tcatalog,\n\t\tpickBy((provider) =>\n\t\t\tObject.values(provider.models).some(\n\t\t\t\t(model) => Boolean(model.tool_call) && isAISDKPackage(resolveModelNpm(provider, model)),\n\t\t\t),\n\t\t),\n\t\tmapValues((provider, providerId) =>\n\t\t\tpipe(\n\t\t\t\tprovider.models,\n\t\t\t\tpickBy((model) => Boolean(model.tool_call) && isAISDKPackage(resolveModelNpm(provider, model))),\n\t\t\t\tmapValues((model) => toModelValue(providerId, provider, model)),\n\t\t\t\tpickBy((model): model is Model.Info => model !== undefined),\n\t\t\t),\n\t\t),\n\t) as BuiltInModels;\n}\n\ntype ThinkingLevelMap = NonNullable<Model.Info[\"thinkingLevelMap\"]>;\n\nfunction resolveModelNpm(provider: ModelsDevProvider, model: ModelsDevModel): string {\n\treturn model.provider?.npm ?? provider.npm ?? DEFAULT_AI_SDK_PACKAGE;\n}\n\nfunction resolveModelBaseUrl(provider: ModelsDevProvider, model: ModelsDevModel): string {\n\tconst npm = resolveModelNpm(provider, model);\n\tconst protocol = protocolForPackage(npm);\n\treturn model.baseUrl ?? model.provider?.api ?? provider.api ?? DEFAULT_PROVIDER_BASE_URLS[protocol] ?? \"\";\n}\n\nfunction resolveModelAPIMethod(npm: string): Model.APIMethodEnum {\n\tconst protocol = protocolForPackage(npm);\n\t// `By default, xai(modelId) uses the Chat API.\n\t// To use the Responses API with server-side agentic tools, explicitly use xai.responses(modelId).`\n\t// References: https://ai-sdk.dev/providers/ai-sdk-providers/xai\n\tif (protocol === Model.KnownProviderEnum.openai || protocol === Model.KnownProviderEnum.xai) {\n\t\treturn Model.APIMethodEnum.responses;\n\t}\n\treturn Model.APIMethodEnum.languageModel;\n}\n\nfunction resolveProviderOptionsKey(protocol: Model.KnownProviderEnum): string {\n\tif (protocol === Model.KnownProviderEnum.openaiCompatible) return \"openai-compatible\";\n\tif (protocol === Model.KnownProviderEnum.googleVertex) return \"google-vertex\";\n\tif (protocol === Model.KnownProviderEnum.googleVertexAnthropic) return \"google-vertex-anthropic\";\n\treturn protocol;\n}\n\n//\n// adhoc helpers variations\nconst OPENAI_RESPONSES_NONE_REASONING_MODELS = new Set([\n\t\"gpt-5.1\",\n\t\"gpt-5.2\",\n\t\"gpt-5.3-codex\",\n\t\"gpt-5.4\",\n\t\"gpt-5.4-mini\",\n\t\"gpt-5.4-nano\",\n\t\"gpt-5.5\",\n]);\n\nfunction supportsOpenAiXhigh(modelId: string): boolean {\n\treturn (\n\t\tmodelId.includes(\"gpt-5.2\") ||\n\t\tmodelId.includes(\"gpt-5.3\") ||\n\t\tmodelId.includes(\"gpt-5.4\") ||\n\t\tmodelId.includes(\"gpt-5.5\")\n\t);\n}\n\nfunction mergeThinkingLevelMap(model: Model.Info, map: ThinkingLevelMap): void {\n\tmodel.thinkingLevelMap = { ...model.thinkingLevelMap, ...map };\n}\n\nfunction applyThinkingLevelMetadata(model: Model.Info): void {\n\tif (model.protocol === Model.KnownProviderEnum.openai && model.id.startsWith(\"gpt-5\")) {\n\t\tmergeThinkingLevelMap(model, { off: null });\n\t}\n\tif (\n\t\tmodel.protocol === Model.KnownProviderEnum.openai &&\n\t\tmodel.provider.id === \"openai\" &&\n\t\tOPENAI_RESPONSES_NONE_REASONING_MODELS.has(model.id)\n\t) {\n\t\tmergeThinkingLevelMap(model, { off: \"none\" });\n\t}\n\tif (supportsOpenAiXhigh(model.id)) {\n\t\tmergeThinkingLevelMap(model, { xhigh: \"xhigh\" });\n\t}\n\tif (model.id.includes(\"opus-4-6\") || model.id.includes(\"opus-4.6\")) {\n\t\tmergeThinkingLevelMap(model, { xhigh: \"max\" });\n\t}\n\tif (model.id.includes(\"opus-4-7\") || model.id.includes(\"opus-4.7\")) {\n\t\tmergeThinkingLevelMap(model, { xhigh: \"xhigh\" });\n\t}\n}\n\nexport async function generateModels(args: { path?: string } = {}): Promise<string> {\n\tconst path = resolve(args.path ?? ModelCatalog.path());\n\tconst models = await loadBuiltInFromModelsDev();\n\tawait Filesystem.writeJson(path, models);\n\treturn path;\n}\n\n//\n// CLI entry\nexport const ModelgenCommand: CommandModule<object, { path?: string }> = {\n\tcommand: \"modelgen [path]\",\n\tdescribe: \"generate models.gen.json\",\n\tbuilder: (yargs) =>\n\t\tyargs.positional(\"path\", {\n\t\t\ttype: \"string\",\n\t\t\tdescribe: \"output path (defaults to CODEWORK_MODELS_FILE or ./models.gen.json)\",\n\t\t}),\n\thandler: async (args) => {\n\t\tconst path = await generateModels(args);\n\t\tconsole.log(`Generated model catalog at ${path}`);\n\t},\n};\n\nexport function applyModification(\n\tproviderId: string,\n\tprovider: ModelsDevProvider,\n\tmodel: ModelsDevModel,\n): Model.Info | undefined {\n\tconst npm = resolveModelNpm(provider, model);\n\tif (!isAISDKPackage(npm)) return;\n\n\tconst protocol = protocolForPackage(npm);\n\tconst baseUrl = resolveModelBaseUrl(provider, model);\n\tconst providerInfo: Model.ProviderInfo = {\n\t\tid: providerId,\n\t\tname: provider.name,\n\t\tsource: \"api\",\n\t\tenv: provider.env,\n\t};\n\tif (provider.key) providerInfo.key = provider.key;\n\tconst api: Model.APIMetadata = {\n\t\tid: model.id,\n\t\tmethod: resolveModelAPIMethod(npm),\n\t};\n\tif (baseUrl) api.url = baseUrl;\n\n\tconst info: Model.Info = {\n\t\tid: model.id,\n\t\tname: model.name,\n\t\tprovider: providerInfo,\n\t\tbaseUrl,\n\t\treasoning: Boolean(model.reasoning),\n\t\tinput: Model.normalizeInput(model.modalities.input),\n\t\tcost: {\n\t\t\tinput: model.cost?.input ?? 0,\n\t\t\toutput: model.cost?.output ?? 0,\n\t\t\tcacheRead: model.cost?.cache_read ?? 0,\n\t\t\tcacheWrite: model.cost?.cache_write ?? 0,\n\t\t},\n\t\tcontextWindow: model.limit?.context ?? 4096,\n\t\tmaxTokens: model.limit?.output ?? 4096,\n\t\theaders: {\n\t\t\t...provider.headers,\n\t\t\t...model.provider?.headers,\n\t\t\t...model.headers,\n\t\t},\n\t\tnpm,\n\t\tapi,\n\t\tproviderOptionsKey: resolveProviderOptionsKey(protocol),\n\t\tprotocol,\n\t};\n\tif (Object.keys(info.headers ?? {}).length === 0) delete info.headers;\n\tapplyThinkingLevelMetadata(info);\n\treturn info;\n}\n","import type { CommandModule } from \"yargs\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexOAuthCredentials,\n\topenAICodexHeaders,\n} from \"../oauth/openai/codex\";\n\ntype AuthArgs = {\n\topenaiCodex?: boolean;\n\tauthFile?: string;\n\tbrowser?: boolean;\n\tmanual?: boolean;\n\tstatus?: boolean;\n\trefresh?: boolean;\n\tlogout?: boolean;\n\tjson?: boolean;\n\tprintHeaders?: boolean;\n\toriginator?: string;\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; printHeaders?: boolean },\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({ path: args.authFile });\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\toriginator: args.originator,\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\tonManualCodeInput: args.manual\n\t\t\t? async () => promptLine(\"Paste the redirect URL or authorization code, or wait for browser callback:\")\n\t\t\t: undefined,\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\";\nimport { OAuthCommand } from \"./cli/oauth\";\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/modelgen.ts","../../src/cli/oauth.ts","../../src/cli.ts"],"sourcesContent":["","import { Filesystem, lazy } from \"@codeworksh/utils\";\nimport { resolve } from \"node:path\";\nimport { mapValues, pickBy, pipe } from \"remeda\";\nimport type { CommandModule } from \"yargs\";\nimport { DEFAULT_AI_SDK_FALLBACK, isAISDKPackage, protocolForPackage } from \"../llm/registry\";\nimport { ModelCatalog } from \"../model/catalog\";\nimport { Model } from \"../model/model\";\n\nconst DEFAULT_PROVIDER_BASE_URLS: Partial<Record<Model.KnownProviderEnum, string>> = {\n\t[Model.KnownProviderEnum.anthropic]: \"https://api.anthropic.com/v1\",\n\t[Model.KnownProviderEnum.openai]: \"https://api.openai.com/v1\",\n\t[Model.KnownProviderEnum.openrouter]: \"https://openrouter.ai/api/v1\",\n\t[Model.KnownProviderEnum.xai]: \"https://api.x.ai/v1\",\n};\n\ninterface ModelsDevModel {\n\tid: string;\n\tname: string;\n\tfamily: string;\n\tattachment: boolean;\n\treasoning?: boolean;\n\ttool_call?: boolean;\n\ttemperature?: boolean;\n\tknowledge?: string | boolean;\n\trelease_date: string;\n\tlast_updated: string;\n\tmodalities: {\n\t\tinput?: string[];\n\t\toutput: string[];\n\t};\n\topen_weights: boolean;\n\tbaseUrl?: string;\n\theaders?: Record<string, string>;\n\tcost?: {\n\t\tinput?: number;\n\t\toutput?: number;\n\t\tcache_read?: number;\n\t\tcache_write?: number;\n\t};\n\tlimit?: {\n\t\tcontext?: number;\n\t\toutput?: number;\n\t};\n\tstructured_output?: boolean;\n\tprovider?: {\n\t\tnpm?: string;\n\t\tapi?: string;\n\t\theaders?: Record<string, string>;\n\t};\n}\n\ninterface ModelsDevProvider {\n\tid: string;\n\tenv: string[];\n\tnpm?: string;\n\tapi?: string;\n\tname: string;\n\tdoc?: string; // reference documentation link\n\tkey?: string; // runtime placeholder for api/oauth key\n\theaders?: Record<string, string>; // custom overrides at provider level\n\tmodels: Record<string, ModelsDevModel>;\n}\n\nexport type BuiltInModels = Partial<Record<string, Record<string, Model.Info>>>;\n\n// Doesn't represent the full spec from models.dev.\n// Represents the provider entries on a best-effort basis.\ntype ModelsDevCatalog = Record<string, ModelsDevProvider>;\ntype LazyModelsDevCatalog = ReturnType<typeof lazy<Promise<ModelsDevCatalog>>>;\n\nfunction modelsDevURL(): string {\n\treturn process.env.OPENCODE_MODELS_URL || \"https://models.dev\";\n}\n\nfunction modelsDevPath(): string | undefined {\n\treturn process.env.OPENCODE_MODELS_DEV_FILE;\n}\n\nconst modelsDevData: LazyModelsDevCatalog = lazy(async () => {\n\tconst path = modelsDevPath();\n\tif (path) {\n\t\tconst result = await Filesystem.readJson<ModelsDevCatalog>(path).catch(() => undefined);\n\t\tif (result) return result;\n\t}\n\n\tconst json = await fetch(`${modelsDevURL()}/api.json`).then((x) => x.text());\n\treturn JSON.parse(json) as ModelsDevCatalog;\n});\n\nasync function pullModelsDevData(): Promise<ModelsDevCatalog> {\n\treturn modelsDevData();\n}\n\nfunction toModelValue(providerId: string, provider: ModelsDevProvider, model: ModelsDevModel): Model.Info | undefined {\n\treturn applyModification(providerId, provider, model);\n}\n\nasync function loadBuiltInFromModelsDev() {\n\tconst catalog = await pullModelsDevData();\n\treturn pipe(\n\t\tcatalog,\n\t\tpickBy((provider) =>\n\t\t\tObject.values(provider.models).some(\n\t\t\t\t// If `resolveModelNpm` fallbacks to `@ai-sdk/openai-compatible`\n\t\t\t\t// isAISDKPakage will be truthy, modify resolveModelNpm for custom logic if needed.\n\t\t\t\t// Keep `isAISDKPackage` as readonly for supported implemenatations key check\n\t\t\t\t(model) => Boolean(model.tool_call) && isAISDKPackage(resolveModelNpm(provider, model)),\n\t\t\t),\n\t\t),\n\t\tmapValues((provider, providerId) =>\n\t\t\tpipe(\n\t\t\t\tprovider.models,\n\t\t\t\tpickBy((model) => Boolean(model.tool_call) && isAISDKPackage(resolveModelNpm(provider, model))),\n\t\t\t\tmapValues((model) => toModelValue(providerId, provider, model)),\n\t\t\t\tpickBy((model): model is Model.Info => model !== undefined),\n\t\t\t),\n\t\t),\n\t) as BuiltInModels;\n}\n\ntype ThinkingLevelMap = NonNullable<Model.Info[\"thinkingLevelMap\"]>;\n\nfunction resolveModelNpm(provider: ModelsDevProvider, model: ModelsDevModel): string {\n\treturn model.provider?.npm ?? provider.npm ?? DEFAULT_AI_SDK_FALLBACK;\n}\n\nfunction resolveModelBaseUrl(provider: ModelsDevProvider, model: ModelsDevModel): string {\n\tconst npm = resolveModelNpm(provider, model);\n\tconst protocol = protocolForPackage(npm);\n\treturn model.baseUrl ?? model.provider?.api ?? provider.api ?? DEFAULT_PROVIDER_BASE_URLS[protocol] ?? \"\";\n}\n\nfunction resolveModelAPIMethod(npm: string): Model.APIMethodEnum {\n\tconst protocol = protocolForPackage(npm);\n\t// `By default, xai(modelId) uses the Chat API.\n\t// To use the Responses API with server-side agentic tools, explicitly use xai.responses(modelId).`\n\t// References: https://ai-sdk.dev/providers/ai-sdk-providers/xai\n\tif (protocol === Model.KnownProviderEnum.openai || protocol === Model.KnownProviderEnum.xai) {\n\t\treturn Model.APIMethodEnum.responses;\n\t}\n\treturn Model.APIMethodEnum.languageModel;\n}\n\nfunction resolveProviderOptionsKey(protocol: Model.KnownProviderEnum): string {\n\tif (protocol === Model.KnownProviderEnum.openaiCompatible) return \"openai-compatible\";\n\tif (protocol === Model.KnownProviderEnum.googleVertex) return \"google-vertex\";\n\tif (protocol === Model.KnownProviderEnum.googleVertexAnthropic) return \"google-vertex-anthropic\";\n\treturn protocol;\n}\n\n//\n// adhoc helpers variations\nconst OPENAI_RESPONSES_NONE_REASONING_MODELS = new Set([\n\t\"gpt-5.1\",\n\t\"gpt-5.2\",\n\t\"gpt-5.3-codex\",\n\t\"gpt-5.4\",\n\t\"gpt-5.4-mini\",\n\t\"gpt-5.4-nano\",\n\t\"gpt-5.5\",\n]);\n\nfunction supportsOpenAiXhigh(modelId: string): boolean {\n\treturn (\n\t\tmodelId.includes(\"gpt-5.2\") ||\n\t\tmodelId.includes(\"gpt-5.3\") ||\n\t\tmodelId.includes(\"gpt-5.4\") ||\n\t\tmodelId.includes(\"gpt-5.5\")\n\t);\n}\n\nfunction mergeThinkingLevelMap(model: Model.Info, map: ThinkingLevelMap): void {\n\tmodel.thinkingLevelMap = { ...model.thinkingLevelMap, ...map };\n}\n\nfunction applyThinkingLevelMetadata(model: Model.Info): void {\n\tif (model.protocol === Model.KnownProviderEnum.openai && model.id.startsWith(\"gpt-5\")) {\n\t\tmergeThinkingLevelMap(model, { off: null });\n\t}\n\tif (\n\t\tmodel.protocol === Model.KnownProviderEnum.openai &&\n\t\tmodel.provider.id === \"openai\" &&\n\t\tOPENAI_RESPONSES_NONE_REASONING_MODELS.has(model.id)\n\t) {\n\t\tmergeThinkingLevelMap(model, { off: \"none\" });\n\t}\n\tif (supportsOpenAiXhigh(model.id)) {\n\t\tmergeThinkingLevelMap(model, { xhigh: \"xhigh\" });\n\t}\n\tif (model.id.includes(\"opus-4-6\") || model.id.includes(\"opus-4.6\")) {\n\t\tmergeThinkingLevelMap(model, { xhigh: \"max\" });\n\t}\n\tif (model.id.includes(\"opus-4-7\") || model.id.includes(\"opus-4.7\")) {\n\t\tmergeThinkingLevelMap(model, { xhigh: \"xhigh\" });\n\t}\n}\n\n//\n// OpenAI Codex (ChatGPT OAuth) models.\n// NOTE: These are not fetched from models.dev; we keep a small, explicit list to avoid aliases.\n// Context window is based on observed server limits (400s above ~272k), not marketing numbers.\nconst OPENAI_CODEX_PROVIDER_ID = \"openai-codex\";\nconst OPENAI_CODEX_NPM = \"@codeworksh/ai-sdk-openai-codex\";\nconst OPENAI_CODEX_BASE_URL = \"https://chatgpt.com/backend-api\";\nconst OPENAI_CODEX_CONTEXT = 272_000;\nconst OPENAI_CODEX_SPARK_CONTEXT = 128_000;\nconst OPENAI_CODEX_MAX_TOKENS = 128_000;\n\ntype OpenAICodexModelSeed = Pick<Model.Info, \"id\" | \"name\" | \"input\" | \"cost\" | \"contextWindow\">;\n\nconst OPENAI_CODEX_MODELS: OpenAICodexModelSeed[] = [\n\t{\n\t\tid: \"gpt-5.3-codex-spark\",\n\t\tname: \"GPT-5.3 Codex Spark\",\n\t\tinput: [\"text\"],\n\t\tcost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 },\n\t\tcontextWindow: OPENAI_CODEX_SPARK_CONTEXT,\n\t},\n\t{\n\t\tid: \"gpt-5.4\",\n\t\tname: \"GPT-5.4\",\n\t\tinput: [\"text\", \"image\"],\n\t\tcost: { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 },\n\t\tcontextWindow: OPENAI_CODEX_CONTEXT,\n\t},\n\t{\n\t\tid: \"gpt-5.4-mini\",\n\t\tname: \"GPT-5.4 mini\",\n\t\tinput: [\"text\", \"image\"],\n\t\tcost: { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 },\n\t\tcontextWindow: OPENAI_CODEX_CONTEXT,\n\t},\n\t{\n\t\tid: \"gpt-5.5\",\n\t\tname: \"GPT-5.5\",\n\t\tinput: [\"text\", \"image\"],\n\t\tcost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 },\n\t\tcontextWindow: OPENAI_CODEX_CONTEXT,\n\t},\n];\n\nexport function openAICodexBuiltInModels(): Record<string, Model.Info> {\n\tconst models: Record<string, Model.Info> = {};\n\tfor (const seed of OPENAI_CODEX_MODELS) {\n\t\tconst info: Model.Info = {\n\t\t\t...seed,\n\t\t\tprovider: {\n\t\t\t\tid: OPENAI_CODEX_PROVIDER_ID,\n\t\t\t\tname: \"OpenAI Codex (ChatGPT)\",\n\t\t\t\tsource: \"custom\",\n\t\t\t\tenv: [\"OPENAI_CODEX_API_KEY\"],\n\t\t\t},\n\t\t\tbaseUrl: OPENAI_CODEX_BASE_URL,\n\t\t\treasoning: true,\n\t\t\t// Codex models always reason; the off level cannot be requested.\n\t\t\tthinkingLevelMap: { off: null },\n\t\t\tmaxTokens: OPENAI_CODEX_MAX_TOKENS,\n\t\t\tnpm: OPENAI_CODEX_NPM,\n\t\t\tapi: {\n\t\t\t\tid: seed.id,\n\t\t\t\turl: OPENAI_CODEX_BASE_URL,\n\t\t\t\tmethod: Model.APIMethodEnum.responses,\n\t\t\t},\n\t\t\tproviderOptionsKey: OPENAI_CODEX_PROVIDER_ID,\n\t\t\tprotocol: Model.KnownProviderEnum.openaiCodex,\n\t\t};\n\t\tapplyThinkingLevelMetadata(info);\n\t\tmodels[seed.id] = info;\n\t}\n\treturn models;\n}\n\nexport async function generateModels(args: { path?: string } = {}): Promise<string> {\n\tconst path = resolve(args.path ?? ModelCatalog.path());\n\tconst modelsDev = await loadBuiltInFromModelsDev();\n\tconst customCodexModels = openAICodexBuiltInModels();\n\n\tconst allModels = { ...modelsDev, [OPENAI_CODEX_PROVIDER_ID]: customCodexModels };\n\tawait Filesystem.writeJson(path, allModels);\n\treturn path;\n}\n\n//\n// CLI entry\nexport const ModelgenCommand: CommandModule<object, { path?: string }> = {\n\tcommand: \"modelgen [path]\",\n\tdescribe: \"generate models.gen.json\",\n\tbuilder: (yargs) =>\n\t\tyargs.positional(\"path\", {\n\t\t\ttype: \"string\",\n\t\t\tdescribe: \"output path (defaults to CODEWORK_MODELS_FILE or ./models.gen.json)\",\n\t\t}),\n\thandler: async (args) => {\n\t\tconst path = await generateModels(args);\n\t\tconsole.log(`Generated model catalog at ${path}`);\n\t},\n};\n\nexport function applyModification(\n\tproviderId: string,\n\tprovider: ModelsDevProvider,\n\tmodel: ModelsDevModel,\n): Model.Info | undefined {\n\tconst npm = resolveModelNpm(provider, model);\n\tif (!isAISDKPackage(npm)) return;\n\n\tconst protocol = protocolForPackage(npm);\n\tconst baseUrl = resolveModelBaseUrl(provider, model);\n\tconst providerInfo: Model.ProviderInfo = {\n\t\tid: providerId,\n\t\tname: provider.name,\n\t\tsource: \"api\",\n\t\tenv: provider.env,\n\t};\n\tif (provider.key) providerInfo.key = provider.key;\n\tconst api: Model.APIMetadata = {\n\t\tid: model.id,\n\t\tmethod: resolveModelAPIMethod(npm),\n\t};\n\tif (baseUrl) api.url = baseUrl;\n\n\tconst info: Model.Info = {\n\t\tid: model.id,\n\t\tname: model.name,\n\t\tprovider: providerInfo,\n\t\tbaseUrl,\n\t\treasoning: Boolean(model.reasoning),\n\t\tinput: Model.normalizeInput(model.modalities.input),\n\t\tcost: {\n\t\t\tinput: model.cost?.input ?? 0,\n\t\t\toutput: model.cost?.output ?? 0,\n\t\t\tcacheRead: model.cost?.cache_read ?? 0,\n\t\t\tcacheWrite: model.cost?.cache_write ?? 0,\n\t\t},\n\t\tcontextWindow: model.limit?.context ?? 4096,\n\t\tmaxTokens: model.limit?.output ?? 4096,\n\t\theaders: {\n\t\t\t...provider.headers,\n\t\t\t...model.provider?.headers,\n\t\t\t...model.headers,\n\t\t},\n\t\tnpm,\n\t\tapi,\n\t\tproviderOptionsKey: resolveProviderOptionsKey(protocol),\n\t\tprotocol,\n\t};\n\tif (Object.keys(info.headers ?? {}).length === 0) delete info.headers;\n\tapplyThinkingLevelMetadata(info);\n\treturn info;\n}\n","import type { CommandModule } from \"yargs\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexOAuthCredentials,\n\topenAICodexHeaders,\n} from \"../oauth/openai/codex\";\n\ntype AuthArgs = {\n\topenaiCodex?: boolean;\n\tauthFile?: string;\n\tbrowser?: boolean;\n\tmanual?: boolean;\n\tstatus?: boolean;\n\trefresh?: boolean;\n\tlogout?: boolean;\n\tjson?: boolean;\n\tprintHeaders?: boolean;\n\toriginator?: string;\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; printHeaders?: boolean },\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({ path: args.authFile });\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\toriginator: args.originator,\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\tonManualCodeInput: args.manual\n\t\t\t? async () => promptLine(\"Paste the redirect URL or authorization code, or wait for browser callback:\")\n\t\t\t: undefined,\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\";\nimport { OAuthCommand } from \"./cli/oauth\";\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,11 +1,21 @@
|
|
|
1
1
|
import dedent from "dedent";
|
|
2
2
|
//#region src/oauth/openai/codex.ts
|
|
3
3
|
/**
|
|
4
|
-
* OpenAI Codex OAuth
|
|
4
|
+
* OpenAI Codex OAuth.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Public interface, by use case:
|
|
7
|
+
*
|
|
8
|
+
* 1. Server OAuth integration (storage-free, bring your own routes):
|
|
9
|
+
* `createOpenAICodexAuthorizationFlow`, `exchangeOpenAICodexAuthorizationCode`,
|
|
10
|
+
* `parseOpenAICodexAuthorizationInput`, `refreshOpenAICodexToken`, `getOpenAICodexAccountId`.
|
|
11
|
+
* 2. CLI / interactive login (localhost callback server, persisted credentials):
|
|
12
|
+
* `OpenAICodexOAuthClient`, `JsonOpenAICodexAuthStorage`, `OpenAICodexAuthStorage`.
|
|
13
|
+
* 3. Application credential access (get key, auto-refresh, request headers):
|
|
14
|
+
* `getOpenAICodexApiKey`, `OpenAICodexOAuthClient.getCredentials/getApiKey/getHeaders`,
|
|
15
|
+
* `openAICodexHeaders`, `OPENAI_CODEX_API_KEY_ENV`.
|
|
16
|
+
*
|
|
17
|
+
* Everything else in this module is an implementation detail and intentionally
|
|
18
|
+
* not exported.
|
|
9
19
|
*/
|
|
10
20
|
const CODEWORK_OAUTH_CALLBACK_HOST = "CODEWORK_OAUTH_CALLBACK_HOST";
|
|
11
21
|
const CODEWORK_CREDENTIALS = "CODEWORK_CREDENTIALS";
|
|
@@ -498,24 +508,21 @@ var OpenAICodexOAuthClient = class {
|
|
|
498
508
|
await this.storage.clear();
|
|
499
509
|
}
|
|
500
510
|
};
|
|
501
|
-
const
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
return openAICodexHeaders(credentials);
|
|
516
|
-
}
|
|
517
|
-
};
|
|
511
|
+
const OPENAI_CODEX_API_KEY_ENV = "OPENAI_CODEX_API_KEY";
|
|
512
|
+
/**
|
|
513
|
+
* Resolve the OpenAI Codex API key the same way other provider API keys are
|
|
514
|
+
* resolved: prefer the OPENAI_CODEX_API_KEY environment variable, then fall
|
|
515
|
+
* back to stored OAuth credentials (refreshing them when close to expiry).
|
|
516
|
+
*
|
|
517
|
+
* The result can be passed directly as `apiKey` to the runtime options or to
|
|
518
|
+
* `createOpenAICodex`. Returns undefined when no key is available.
|
|
519
|
+
*/
|
|
520
|
+
async function getOpenAICodexApiKey(options = {}) {
|
|
521
|
+
const envKey = readEnv(OPENAI_CODEX_API_KEY_ENV);
|
|
522
|
+
if (envKey) return envKey;
|
|
523
|
+
return new OpenAICodexOAuthClient(options).getApiKey();
|
|
524
|
+
}
|
|
518
525
|
//#endregion
|
|
519
|
-
export { exchangeOpenAICodexAuthorizationCode as a, openAICodexHeaders as c,
|
|
526
|
+
export { exchangeOpenAICodexAuthorizationCode as a, openAICodexHeaders as c, createOpenAICodexAuthorizationFlow as i, parseOpenAICodexAuthorizationInput as l, OPENAI_CODEX_API_KEY_ENV as n, getOpenAICodexAccountId as o, OpenAICodexOAuthClient as r, getOpenAICodexApiKey as s, JsonOpenAICodexAuthStorage as t, refreshOpenAICodexToken as u };
|
|
520
527
|
|
|
521
|
-
//# sourceMappingURL=codex-
|
|
528
|
+
//# sourceMappingURL=codex-C36oU6yH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-C36oU6yH.mjs","names":[],"sources":["../../src/oauth/openai/codex.ts"],"sourcesContent":["/**\n * OpenAI Codex OAuth.\n *\n * Public interface, by use case:\n *\n * 1. Server OAuth integration (storage-free, bring your own routes):\n * `createOpenAICodexAuthorizationFlow`, `exchangeOpenAICodexAuthorizationCode`,\n * `parseOpenAICodexAuthorizationInput`, `refreshOpenAICodexToken`, `getOpenAICodexAccountId`.\n * 2. CLI / interactive login (localhost callback server, persisted credentials):\n * `OpenAICodexOAuthClient`, `JsonOpenAICodexAuthStorage`, `OpenAICodexAuthStorage`.\n * 3. Application credential access (get key, auto-refresh, request headers):\n * `getOpenAICodexApiKey`, `OpenAICodexOAuthClient.getCredentials/getApiKey/getHeaders`,\n * `openAICodexHeaders`, `OPENAI_CODEX_API_KEY_ENV`.\n *\n * Everything else in this module is an implementation detail and intentionally\n * not exported.\n */\n\nimport dedent from \"dedent\";\n\nconst CODEWORK_OAUTH_CALLBACK_HOST = \"CODEWORK_OAUTH_CALLBACK_HOST\";\nconst CODEWORK_CREDENTIALS = \"CODEWORK_CREDENTIALS\";\nconst CODEWORK_HOME_DIR = \"CODEWORK_HOME_DIR\";\n\nconst CLIENT_ID = \"app_EMoamEEZ73f0CkXaXp7hrann\";\nconst AUTHORIZE_URL = \"https://auth.openai.com/oauth/authorize\";\nconst TOKEN_URL = \"https://auth.openai.com/oauth/token\";\nconst DEFAULT_REDIRECT_URI = \"http://localhost:1455/auth/callback\";\nconst DEFAULT_SCOPE = \"openid profile email offline_access\";\nconst DEFAULT_ORIGINATOR = \"codework\";\nconst DEFAULT_PROVIDER_ID = \"openai-codex\";\nconst JWT_CLAIM_PATH = \"https://api.openai.com/auth\";\nconst REFRESH_SKEW_MS = 60 * 1000;\n\nexport type OpenAICodexOAuthCredentials = {\n\taccess: string;\n\trefresh: string;\n\texpires: number;\n\taccountId: string;\n};\n\nexport type OpenAICodexTokenSuccess = {\n\ttype: \"success\";\n\taccess: string;\n\trefresh: string;\n\texpires: number;\n};\n\nexport type OpenAICodexTokenFailure = {\n\ttype: \"failed\";\n\tmessage: string;\n\tstatus?: number;\n};\n\nexport type OpenAICodexTokenResult = OpenAICodexTokenSuccess | OpenAICodexTokenFailure;\n\nexport type OpenAICodexAuthorizationFlow = {\n\turl: string;\n\tverifier: string;\n\tstate: string;\n\tredirectUri: string;\n};\n\nexport type OpenAICodexAuthorizationOptions = {\n\toriginator?: string;\n\tredirectUri?: string;\n\tscope?: string;\n};\n\nexport type OpenAICodexLoginPrompt = {\n\tmessage: string;\n\tplaceholder?: string;\n\tallowEmpty?: boolean;\n};\n\nexport type OpenAICodexLoginOptions = OpenAICodexAuthorizationOptions & {\n\tonAuth: (info: { url: string; instructions?: string }) => void;\n\tonPrompt: (prompt: OpenAICodexLoginPrompt) => Promise<string>;\n\tonProgress?: (message: string) => void;\n\tonManualCodeInput?: () => Promise<string>;\n};\n\nexport interface OpenAICodexAuthStorage {\n\tget(): Promise<OpenAICodexOAuthCredentials | undefined>;\n\tset(credentials: OpenAICodexOAuthCredentials): Promise<void>;\n\tclear(): Promise<void>;\n}\n\nexport type JsonOpenAICodexAuthStorageOptions = {\n\tpath?: string;\n\tproviderId?: string;\n};\n\ntype JwtPayload = {\n\t[JWT_CLAIM_PATH]?: {\n\t\tchatgpt_account_id?: string;\n\t};\n\t[key: string]: unknown;\n};\n\ntype OAuthServerInfo = {\n\tclose: () => void;\n\tcancelWait: () => void;\n\twaitForCode: () => Promise<{ code: string } | null>;\n};\n\ntype AuthFile = Record<string, unknown>;\n\nfunction readEnv(name: string): string | undefined {\n\tif (typeof process === \"undefined\") return undefined;\n\treturn process.env[name];\n}\n\nfunction joinPath(...parts: string[]): string {\n\treturn parts.filter(Boolean).join(\"/\").replaceAll(/\\/+/g, \"/\");\n}\n\nfunction expandHome(path: string): string {\n\tif (path === \"~\") return homeDirectory();\n\tif (path.startsWith(\"~/\")) return joinPath(homeDirectory(), path.slice(2));\n\treturn path;\n}\n\nfunction homeDirectory(): string {\n\tconst home = readEnv(\"HOME\") ?? readEnv(\"USERPROFILE\");\n\tif (!home) {\n\t\tthrow new Error(\"Unable to resolve home directory for OpenAI Codex auth storage\");\n\t}\n\treturn home;\n}\n\nfunction codeworkHomeDirectory(): string {\n\tconst override = readEnv(CODEWORK_HOME_DIR);\n\tif (override) return expandHome(override);\n\treturn joinPath(homeDirectory(), \".codework\");\n}\n\n// Internal: the resolved location is exposed as `JsonOpenAICodexAuthStorage#path`.\nfunction defaultOpenAICodexAuthFilePath(): string {\n\tconst authFile = readEnv(CODEWORK_CREDENTIALS);\n\tif (authFile) return expandHome(authFile);\n\n\treturn joinPath(codeworkHomeDirectory(), \"aikit\", \"auth.json\");\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isOpenAICodexCredentials(value: unknown): value is OpenAICodexOAuthCredentials {\n\tif (!isObject(value)) return false;\n\treturn (\n\t\ttypeof value.access === \"string\" &&\n\t\ttypeof value.refresh === \"string\" &&\n\t\ttypeof value.expires === \"number\" &&\n\t\ttypeof value.accountId === \"string\"\n\t);\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n\tlet binary = \"\";\n\tfor (const byte of bytes) {\n\t\tbinary += String.fromCharCode(byte);\n\t}\n\treturn btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replaceAll(\"=\", \"\");\n}\n\nfunction base64UrlDecode(value: string): string {\n\tconst base64 = value.replaceAll(\"-\", \"+\").replaceAll(\"_\", \"/\");\n\tconst padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, \"=\");\n\treturn atob(padded);\n}\n\ntype WebCrypto = typeof globalThis.crypto;\n\nfunction getCrypto(): WebCrypto {\n\tif (!globalThis.crypto?.getRandomValues || !globalThis.crypto.subtle) {\n\t\tthrow new Error(\"OpenAI Codex OAuth requires Web Crypto support\");\n\t}\n\treturn globalThis.crypto;\n}\n\nfunction createState(): string {\n\tconst bytes = new Uint8Array(16);\n\tgetCrypto().getRandomValues(bytes);\n\treturn Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nasync function generatePKCE(): Promise<{\n\tverifier: string;\n\tchallenge: string;\n}> {\n\tconst bytes = new Uint8Array(32);\n\tgetCrypto().getRandomValues(bytes);\n\tconst verifier = base64UrlEncode(bytes);\n\n\tconst data = new TextEncoder().encode(verifier);\n\tconst hash = await getCrypto().subtle.digest(\"SHA-256\", data);\n\tconst challenge = base64UrlEncode(new Uint8Array(hash));\n\n\treturn { verifier, challenge };\n}\n\nexport function parseOpenAICodexAuthorizationInput(input: string): {\n\tcode?: string;\n\tstate?: string;\n} {\n\tconst value = input.trim();\n\tif (!value) return {};\n\n\ttry {\n\t\tconst url = new URL(value);\n\t\treturn {\n\t\t\tcode: url.searchParams.get(\"code\") ?? undefined,\n\t\t\tstate: url.searchParams.get(\"state\") ?? undefined,\n\t\t};\n\t} catch {\n\t\t// Not a URL.\n\t}\n\n\tif (value.includes(\"#\")) {\n\t\tconst [code, state] = value.split(\"#\", 2);\n\t\treturn { code, state };\n\t}\n\n\tif (value.includes(\"code=\")) {\n\t\tconst params = new URLSearchParams(value);\n\t\treturn {\n\t\t\tcode: params.get(\"code\") ?? undefined,\n\t\t\tstate: params.get(\"state\") ?? undefined,\n\t\t};\n\t}\n\n\treturn { code: value };\n}\n\nfunction decodeJwt(token: string): JwtPayload | null {\n\ttry {\n\t\tconst parts = token.split(\".\");\n\t\tif (parts.length !== 3) return null;\n\t\treturn JSON.parse(base64UrlDecode(parts[1] ?? \"\")) as JwtPayload;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function getOpenAICodexAccountId(accessToken: string): string | null {\n\tconst payload = decodeJwt(accessToken);\n\tconst auth = payload?.[JWT_CLAIM_PATH];\n\tconst accountId = auth?.chatgpt_account_id;\n\treturn typeof accountId === \"string\" && accountId.length > 0 ? accountId : null;\n}\n\nexport async function createOpenAICodexAuthorizationFlow(\n\toptions: OpenAICodexAuthorizationOptions = {},\n): Promise<OpenAICodexAuthorizationFlow> {\n\tconst redirectUri = options.redirectUri ?? DEFAULT_REDIRECT_URI;\n\tconst { verifier, challenge } = await generatePKCE();\n\tconst state = createState();\n\n\tconst url = new URL(AUTHORIZE_URL);\n\turl.searchParams.set(\"response_type\", \"code\");\n\turl.searchParams.set(\"client_id\", CLIENT_ID);\n\turl.searchParams.set(\"redirect_uri\", redirectUri);\n\turl.searchParams.set(\"scope\", options.scope ?? DEFAULT_SCOPE);\n\turl.searchParams.set(\"code_challenge\", challenge);\n\turl.searchParams.set(\"code_challenge_method\", \"S256\");\n\turl.searchParams.set(\"state\", state);\n\turl.searchParams.set(\"id_token_add_organizations\", \"true\");\n\turl.searchParams.set(\"codex_cli_simplified_flow\", \"true\");\n\turl.searchParams.set(\"originator\", options.originator ?? DEFAULT_ORIGINATOR);\n\n\treturn { verifier, state, redirectUri, url: url.toString() };\n}\n\nexport async function exchangeOpenAICodexAuthorizationCode(\n\tcode: string,\n\tverifier: string,\n\tredirectUri: string = DEFAULT_REDIRECT_URI,\n): Promise<OpenAICodexTokenResult> {\n\tconst response = await fetch(TOKEN_URL, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\tbody: new URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tcode,\n\t\t\tcode_verifier: verifier,\n\t\t\tredirect_uri: redirectUri,\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst text = await response.text().catch(() => \"\");\n\t\treturn {\n\t\t\ttype: \"failed\",\n\t\t\tstatus: response.status,\n\t\t\tmessage: `OpenAI Codex token exchange failed (${response.status}): ${text || response.statusText}`,\n\t\t};\n\t}\n\n\tconst json = (await response.json()) as {\n\t\taccess_token?: string;\n\t\trefresh_token?: string;\n\t\texpires_in?: number;\n\t};\n\n\tif (!json.access_token || !json.refresh_token || typeof json.expires_in !== \"number\") {\n\t\treturn {\n\t\t\ttype: \"failed\",\n\t\t\tmessage: `OpenAI Codex token exchange response missing fields: ${JSON.stringify(json)}`,\n\t\t};\n\t}\n\n\treturn {\n\t\ttype: \"success\",\n\t\taccess: json.access_token,\n\t\trefresh: json.refresh_token,\n\t\texpires: Date.now() + json.expires_in * 1000,\n\t};\n}\n\nasync function refreshAccessToken(refreshToken: string): Promise<OpenAICodexTokenResult> {\n\ttry {\n\t\tconst response = await fetch(TOKEN_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\tbody: new URLSearchParams({\n\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\trefresh_token: refreshToken,\n\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text().catch(() => \"\");\n\t\t\treturn {\n\t\t\t\ttype: \"failed\",\n\t\t\t\tstatus: response.status,\n\t\t\t\tmessage: `OpenAI Codex token refresh failed (${response.status}): ${text || response.statusText}`,\n\t\t\t};\n\t\t}\n\n\t\tconst json = (await response.json()) as {\n\t\t\taccess_token?: string;\n\t\t\trefresh_token?: string;\n\t\t\texpires_in?: number;\n\t\t};\n\n\t\tif (!json.access_token || !json.refresh_token || typeof json.expires_in !== \"number\") {\n\t\t\treturn {\n\t\t\t\ttype: \"failed\",\n\t\t\t\tmessage: `OpenAI Codex token refresh response missing fields: ${JSON.stringify(json)}`,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\ttype: \"success\",\n\t\t\taccess: json.access_token,\n\t\t\trefresh: json.refresh_token,\n\t\t\texpires: Date.now() + json.expires_in * 1000,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\ttype: \"failed\",\n\t\t\tmessage: `OpenAI Codex token refresh error: ${error instanceof Error ? error.message : String(error)}`,\n\t\t};\n\t}\n}\n\nfunction oauthPage(options: { title: string; heading: string; message: string; details?: string }): string {\n\tconst escapeHtml = (value: string) =>\n\t\tvalue\n\t\t\t.replaceAll(\"&\", \"&\")\n\t\t\t.replaceAll(\"<\", \"<\")\n\t\t\t.replaceAll(\">\", \">\")\n\t\t\t.replaceAll('\"', \""\")\n\t\t\t.replaceAll(\"'\", \"'\");\n\tconst details = options.details ? escapeHtml(options.details) : undefined;\n\n\treturn dedent`\n\t<!doctype html>\n\t<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\t\t<title>${escapeHtml(options.title)}</title>\n\t\t<style>\n\t\t\thtml { color-scheme: dark; }\n\t\t\tbody {\n\t\t\tmargin: 0;\n\t\t\tmin-height: 100vh;\n\t\t\tdisplay: grid;\n\t\t\tplace-items: center;\n\t\t\tpadding: 24px;\n\t\t\tbackground: #09090b;\n\t\t\tcolor: #fafafa;\n\t\t\tfont-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n\t\t\ttext-align: center;\n\t\t\t}\n\t\t\tmain { width: 100%; max-width: 560px; }\n\t\t\th1 { margin: 0 0 10px; font-size: 28px; line-height: 1.15; font-weight: 650; }\n\t\t\tp { margin: 0; line-height: 1.7; color: #a1a1aa; font-size: 15px; }\n\t\t\t.details { margin-top: 16px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; color: #a1a1aa; white-space: pre-wrap; word-break: break-word; }\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<main>\n\t\t\t<h1>${escapeHtml(options.heading)}</h1>\n\t\t\t<p>${escapeHtml(options.message)}</p>\n\t\t\t${details ? `<div class=\"details\">${details}</div>` : \"\"}\n\t\t</main>\n\t</body>\n\t</html>\n\t`;\n}\n\nfunction oauthSuccessHtml(message: string): string {\n\treturn oauthPage({\n\t\ttitle: \"Authentication successful\",\n\t\theading: \"Authentication successful\",\n\t\tmessage,\n\t});\n}\n\nfunction oauthErrorHtml(message: string, details?: string): string {\n\treturn oauthPage({\n\t\ttitle: \"Authentication failed\",\n\t\theading: \"Authentication failed\",\n\t\tmessage,\n\t\tdetails,\n\t});\n}\n\nasync function startLocalOAuthServer(state: string): Promise<OAuthServerInfo> {\n\tconst http = await import(\"node:http\").catch(() => undefined);\n\tif (!http) {\n\t\tthrow new Error(\"OpenAI Codex OAuth callback server is only available in Node.js environments\");\n\t}\n\n\tlet settleWait: ((value: { code: string } | null) => void) | undefined;\n\tconst waitForCodePromise = new Promise<{ code: string } | null>((resolve) => {\n\t\tlet settled = false;\n\t\tsettleWait = (value) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tresolve(value);\n\t\t};\n\t});\n\n\tconst server = http.createServer((req, res) => {\n\t\ttry {\n\t\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\t\tif (url.pathname !== \"/auth/callback\") {\n\t\t\t\tres.statusCode = 404;\n\t\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\t\tres.end(oauthErrorHtml(\"Callback route not found.\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.searchParams.get(\"state\") !== state) {\n\t\t\t\tres.statusCode = 400;\n\t\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\t\tres.end(oauthErrorHtml(\"State mismatch.\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\tif (!code) {\n\t\t\t\tres.statusCode = 400;\n\t\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\t\tres.end(oauthErrorHtml(\"Missing authorization code.\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tres.statusCode = 200;\n\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\tres.end(oauthSuccessHtml(\"OpenAI authentication completed. You can close this window.\"));\n\t\t\tsettleWait?.({ code });\n\t\t} catch (error) {\n\t\t\tres.statusCode = 500;\n\t\t\tres.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n\t\t\tres.end(\n\t\t\t\toauthErrorHtml(\n\t\t\t\t\t\"Internal error while processing OAuth callback.\",\n\t\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t});\n\n\treturn new Promise((resolve) => {\n\t\tserver\n\t\t\t.listen(1455, readEnv(CODEWORK_OAUTH_CALLBACK_HOST) || \"127.0.0.1\", () => {\n\t\t\t\tresolve({\n\t\t\t\t\tclose: () => server.close(),\n\t\t\t\t\tcancelWait: () => {\n\t\t\t\t\t\tsettleWait?.(null);\n\t\t\t\t\t},\n\t\t\t\t\twaitForCode: () => waitForCodePromise,\n\t\t\t\t});\n\t\t\t})\n\t\t\t.on(\"error\", () => {\n\t\t\t\tsettleWait?.(null);\n\t\t\t\tresolve({\n\t\t\t\t\tclose: () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tserver.close();\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Ignore close errors after a listen failure.\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tcancelWait: () => {},\n\t\t\t\t\twaitForCode: async () => null,\n\t\t\t\t});\n\t\t\t});\n\t});\n}\n\n// Internal: the public login entry point is `OpenAICodexOAuthClient#login`,\n// which persists the credentials. Server integrations should use the\n// storage-free authorization helpers instead of this localhost-callback flow.\nasync function loginOpenAICodex(options: OpenAICodexLoginOptions): Promise<OpenAICodexOAuthCredentials> {\n\tconst flow = await createOpenAICodexAuthorizationFlow(options);\n\tconst server = await startLocalOAuthServer(flow.state);\n\n\toptions.onAuth({\n\t\turl: flow.url,\n\t\tinstructions: \"Complete the browser login to finish OpenAI Codex authentication.\",\n\t});\n\n\tlet code: string | undefined;\n\ttry {\n\t\tif (options.onManualCodeInput) {\n\t\t\tlet manualCode: string | undefined;\n\t\t\tlet manualError: Error | undefined;\n\t\t\tconst manualPromise = options\n\t\t\t\t.onManualCodeInput()\n\t\t\t\t.then((input) => {\n\t\t\t\t\tmanualCode = input;\n\t\t\t\t\tif (input.trim()) server.cancelWait();\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tmanualError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\tserver.cancelWait();\n\t\t\t\t});\n\n\t\t\tconst result = await server.waitForCode();\n\t\t\tif (manualError) throw manualError;\n\n\t\t\tif (result?.code) {\n\t\t\t\tcode = result.code;\n\t\t\t} else if (manualCode) {\n\t\t\t\tconst parsed = parseOpenAICodexAuthorizationInput(manualCode);\n\t\t\t\tif (parsed.state && parsed.state !== flow.state) throw new Error(\"State mismatch\");\n\t\t\t\tcode = parsed.code;\n\t\t\t}\n\n\t\t\tif (!code) {\n\t\t\t\tawait manualPromise;\n\t\t\t\tif (manualError) throw manualError;\n\t\t\t\tif (manualCode) {\n\t\t\t\t\tconst parsed = parseOpenAICodexAuthorizationInput(manualCode);\n\t\t\t\t\tif (parsed.state && parsed.state !== flow.state) throw new Error(\"State mismatch\");\n\t\t\t\t\tcode = parsed.code;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst result = await server.waitForCode();\n\t\t\tif (result?.code) code = result.code;\n\t\t}\n\n\t\tif (!code) {\n\t\t\tconst input = await options.onPrompt({\n\t\t\t\tmessage: \"Paste the authorization code or full redirect URL:\",\n\t\t\t});\n\t\t\tconst parsed = parseOpenAICodexAuthorizationInput(input);\n\t\t\tif (parsed.state && parsed.state !== flow.state) throw new Error(\"State mismatch\");\n\t\t\tcode = parsed.code;\n\t\t}\n\n\t\tif (!code) throw new Error(\"Missing authorization code\");\n\n\t\tconst tokenResult = await exchangeOpenAICodexAuthorizationCode(code, flow.verifier, flow.redirectUri);\n\t\tif (tokenResult.type !== \"success\") throw new Error(tokenResult.message);\n\n\t\tconst accountId = getOpenAICodexAccountId(tokenResult.access);\n\t\tif (!accountId) throw new Error(\"Failed to extract accountId from token\");\n\n\t\treturn {\n\t\t\taccess: tokenResult.access,\n\t\t\trefresh: tokenResult.refresh,\n\t\t\texpires: tokenResult.expires,\n\t\t\taccountId,\n\t\t};\n\t} finally {\n\t\tserver.close();\n\t}\n}\n\nexport async function refreshOpenAICodexToken(refreshToken: string): Promise<OpenAICodexOAuthCredentials> {\n\tconst result = await refreshAccessToken(refreshToken);\n\tif (result.type !== \"success\") {\n\t\tthrow new Error(result.message);\n\t}\n\n\tconst accountId = getOpenAICodexAccountId(result.access);\n\tif (!accountId) {\n\t\tthrow new Error(\"Failed to extract accountId from token\");\n\t}\n\n\treturn {\n\t\taccess: result.access,\n\t\trefresh: result.refresh,\n\t\texpires: result.expires,\n\t\taccountId,\n\t};\n}\n\nexport function openAICodexHeaders(credentials: OpenAICodexOAuthCredentials): Record<string, string> {\n\treturn {\n\t\tAuthorization: `Bearer ${credentials.access}`,\n\t\t\"chatgpt-account-id\": credentials.accountId,\n\t\t\"OpenAI-Beta\": \"responses=experimental\",\n\t};\n}\n\nexport class JsonOpenAICodexAuthStorage implements OpenAICodexAuthStorage {\n\treadonly path: string;\n\treadonly providerId: string;\n\n\tconstructor(options: JsonOpenAICodexAuthStorageOptions = {}) {\n\t\tthis.path = options.path ? expandHome(options.path) : defaultOpenAICodexAuthFilePath();\n\t\tthis.providerId = options.providerId ?? DEFAULT_PROVIDER_ID;\n\t}\n\n\tasync get(): Promise<OpenAICodexOAuthCredentials | undefined> {\n\t\tconst file = await this.readFile();\n\t\tif (!file) return undefined;\n\n\t\tif (isOpenAICodexCredentials(file)) return file;\n\n\t\tconst direct = file[this.providerId];\n\t\tif (isOpenAICodexCredentials(direct)) return direct;\n\n\t\tconst providers = file.providers;\n\t\tif (isObject(providers) && isOpenAICodexCredentials(providers[this.providerId])) {\n\t\t\treturn providers[this.providerId] as OpenAICodexOAuthCredentials;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tasync set(credentials: OpenAICodexOAuthCredentials): Promise<void> {\n\t\tconst current = await this.readFile();\n\t\tconst next = isObject(current) && !isOpenAICodexCredentials(current) ? current : {};\n\t\tnext[this.providerId] = credentials;\n\t\tawait this.writeFile(next);\n\t}\n\n\tasync clear(): Promise<void> {\n\t\tconst current = await this.readFile();\n\t\tif (!current) return;\n\n\t\tif (isOpenAICodexCredentials(current)) {\n\t\t\tawait this.writeFile({});\n\t\t\treturn;\n\t\t}\n\n\t\tdelete current[this.providerId];\n\t\tconst providers = current.providers;\n\t\tif (isObject(providers)) delete providers[this.providerId];\n\t\tawait this.writeFile(current);\n\t}\n\n\tprivate async readFile(): Promise<AuthFile | undefined> {\n\t\tconst fs = await import(\"node:fs/promises\");\n\t\ttry {\n\t\t\tconst text = await fs.readFile(this.path, \"utf8\");\n\t\t\tconst parsed = JSON.parse(text) as unknown;\n\t\t\treturn isObject(parsed) ? parsed : undefined;\n\t\t} catch (error) {\n\t\t\tif (isObject(error) && error.code === \"ENOENT\") return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async writeFile(value: AuthFile): Promise<void> {\n\t\tconst fs = await import(\"node:fs/promises\");\n\t\tconst path = await import(\"node:path\");\n\t\tawait fs.mkdir(path.dirname(this.path), { recursive: true });\n\t\tconst tempPath = `${this.path}.${process.pid}.${Date.now()}.tmp`;\n\t\tawait fs.writeFile(tempPath, `${JSON.stringify(value, null, \"\\t\")}\\n`, \"utf8\");\n\t\tawait fs.rename(tempPath, this.path);\n\t}\n}\n\nexport type OpenAICodexOAuthClientOptions = {\n\tstorage?: OpenAICodexAuthStorage;\n\trefreshSkewMs?: number;\n};\n\nexport class OpenAICodexOAuthClient {\n\treadonly storage: OpenAICodexAuthStorage;\n\treadonly refreshSkewMs: number;\n\n\tconstructor(options: OpenAICodexOAuthClientOptions = {}) {\n\t\tthis.storage = options.storage ?? new JsonOpenAICodexAuthStorage();\n\t\tthis.refreshSkewMs = options.refreshSkewMs ?? REFRESH_SKEW_MS;\n\t}\n\n\tasync login(options: OpenAICodexLoginOptions): Promise<OpenAICodexOAuthCredentials> {\n\t\tconst credentials = await loginOpenAICodex(options);\n\t\tawait this.storage.set(credentials);\n\t\treturn credentials;\n\t}\n\n\tasync getCredentials(): Promise<OpenAICodexOAuthCredentials | undefined> {\n\t\tconst credentials = await this.storage.get();\n\t\tif (!credentials) return undefined;\n\n\t\tif (credentials.expires > Date.now() + this.refreshSkewMs) {\n\t\t\treturn credentials;\n\t\t}\n\n\t\tconst refreshed = await refreshOpenAICodexToken(credentials.refresh);\n\t\tawait this.storage.set(refreshed);\n\t\treturn refreshed;\n\t}\n\n\tasync getApiKey(): Promise<string | undefined> {\n\t\treturn (await this.getCredentials())?.access;\n\t}\n\n\tasync getHeaders(): Promise<Record<string, string> | undefined> {\n\t\tconst credentials = await this.getCredentials();\n\t\treturn credentials ? openAICodexHeaders(credentials) : undefined;\n\t}\n\n\tasync logout(): Promise<void> {\n\t\tawait this.storage.clear();\n\t}\n}\n\nexport const OPENAI_CODEX_API_KEY_ENV = \"OPENAI_CODEX_API_KEY\";\n\n/**\n * Resolve the OpenAI Codex API key the same way other provider API keys are\n * resolved: prefer the OPENAI_CODEX_API_KEY environment variable, then fall\n * back to stored OAuth credentials (refreshing them when close to expiry).\n *\n * The result can be passed directly as `apiKey` to the runtime options or to\n * `createOpenAICodex`. Returns undefined when no key is available.\n */\nexport async function getOpenAICodexApiKey(options: OpenAICodexOAuthClientOptions = {}): Promise<string | undefined> {\n\tconst envKey = readEnv(OPENAI_CODEX_API_KEY_ENV);\n\tif (envKey) return envKey;\n\n\treturn new OpenAICodexOAuthClient(options).getApiKey();\n}\n"],"mappings":"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"}
|