@numa-tech/numa 1.11.10

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.
Files changed (99) hide show
  1. package/README.md +602 -0
  2. package/THIRD_PARTY_NOTICES.md +13 -0
  3. package/assets/codex-shortcut-icon.icns +0 -0
  4. package/assets/codex-shortcut-icon.ico +0 -0
  5. package/dist/app-config.d.ts +26 -0
  6. package/dist/app-config.js +135 -0
  7. package/dist/app-config.js.map +1 -0
  8. package/dist/backend.d.ts +16 -0
  9. package/dist/backend.js +106 -0
  10. package/dist/backend.js.map +1 -0
  11. package/dist/branding.d.ts +7 -0
  12. package/dist/branding.js +13 -0
  13. package/dist/branding.js.map +1 -0
  14. package/dist/chatgpt-console.d.ts +53 -0
  15. package/dist/chatgpt-console.js +105 -0
  16. package/dist/chatgpt-console.js.map +1 -0
  17. package/dist/cli.d.ts +2 -0
  18. package/dist/cli.js +451 -0
  19. package/dist/cli.js.map +1 -0
  20. package/dist/codex-auth-agent.d.ts +60 -0
  21. package/dist/codex-auth-agent.js +331 -0
  22. package/dist/codex-auth-agent.js.map +1 -0
  23. package/dist/codex-commands.d.ts +2 -0
  24. package/dist/codex-commands.js +528 -0
  25. package/dist/codex-commands.js.map +1 -0
  26. package/dist/codex-legacy-cleanup.d.ts +5 -0
  27. package/dist/codex-legacy-cleanup.js +77 -0
  28. package/dist/codex-legacy-cleanup.js.map +1 -0
  29. package/dist/codex-process.d.ts +13 -0
  30. package/dist/codex-process.js +193 -0
  31. package/dist/codex-process.js.map +1 -0
  32. package/dist/codex-protocol.d.ts +352 -0
  33. package/dist/codex-protocol.js +116 -0
  34. package/dist/codex-protocol.js.map +1 -0
  35. package/dist/codex-quota-cache.d.ts +20 -0
  36. package/dist/codex-quota-cache.js +82 -0
  37. package/dist/codex-quota-cache.js.map +1 -0
  38. package/dist/codex-selection.d.ts +18 -0
  39. package/dist/codex-selection.js +47 -0
  40. package/dist/codex-selection.js.map +1 -0
  41. package/dist/codex-service-client.d.ts +11 -0
  42. package/dist/codex-service-client.js +91 -0
  43. package/dist/codex-service-client.js.map +1 -0
  44. package/dist/codex-shortcuts.d.ts +43 -0
  45. package/dist/codex-shortcuts.js +429 -0
  46. package/dist/codex-shortcuts.js.map +1 -0
  47. package/dist/codex-tui.d.ts +15 -0
  48. package/dist/codex-tui.js +235 -0
  49. package/dist/codex-tui.js.map +1 -0
  50. package/dist/command-catalog.d.ts +9 -0
  51. package/dist/command-catalog.js +206 -0
  52. package/dist/command-catalog.js.map +1 -0
  53. package/dist/config-page.d.ts +2 -0
  54. package/dist/config-page.js +51 -0
  55. package/dist/config-page.js.map +1 -0
  56. package/dist/config.d.ts +22 -0
  57. package/dist/config.js +99 -0
  58. package/dist/config.js.map +1 -0
  59. package/dist/identity.d.ts +23 -0
  60. package/dist/identity.js +78 -0
  61. package/dist/identity.js.map +1 -0
  62. package/dist/media/client.d.ts +79 -0
  63. package/dist/media/client.js +175 -0
  64. package/dist/media/client.js.map +1 -0
  65. package/dist/media/commands.d.ts +2 -0
  66. package/dist/media/commands.js +193 -0
  67. package/dist/media/commands.js.map +1 -0
  68. package/dist/media/errors.d.ts +8 -0
  69. package/dist/media/errors.js +37 -0
  70. package/dist/media/errors.js.map +1 -0
  71. package/dist/media/schemas.d.ts +62 -0
  72. package/dist/media/schemas.js +71 -0
  73. package/dist/media/schemas.js.map +1 -0
  74. package/dist/media/transfers.d.ts +38 -0
  75. package/dist/media/transfers.js +169 -0
  76. package/dist/media/transfers.js.map +1 -0
  77. package/dist/oauth.d.ts +30 -0
  78. package/dist/oauth.js +295 -0
  79. package/dist/oauth.js.map +1 -0
  80. package/dist/private-file.d.ts +3 -0
  81. package/dist/private-file.js +51 -0
  82. package/dist/private-file.js.map +1 -0
  83. package/dist/server.d.ts +2 -0
  84. package/dist/server.js +197 -0
  85. package/dist/server.js.map +1 -0
  86. package/dist/types.d.ts +40 -0
  87. package/dist/types.js +2 -0
  88. package/dist/types.js.map +1 -0
  89. package/dist/web-console-page.d.ts +3 -0
  90. package/dist/web-console-page.js +59 -0
  91. package/dist/web-console-page.js.map +1 -0
  92. package/dist/web-console.d.ts +22 -0
  93. package/dist/web-console.js +335 -0
  94. package/dist/web-console.js.map +1 -0
  95. package/examples/claude-desktop-installed-binary.json +11 -0
  96. package/examples/claude-desktop-npx.json +12 -0
  97. package/examples/codex-installed-binary.json +11 -0
  98. package/examples/codex-npx.json +12 -0
  99. package/package.json +67 -0
@@ -0,0 +1,528 @@
1
+ import { createHash } from "node:crypto";
2
+ import { hostname } from "node:os";
3
+ import process from "node:process";
4
+ import { getStoragePath, loadAccounts, setStoragePath, setStoragePathDirect } from "codex-multi-auth/storage";
5
+ import { loadAppConfig } from "./app-config.js";
6
+ import { CODEX_APP_NAME, CODEX_SHORTCUT_NAME, PACKAGE_NAME } from "./branding.js";
7
+ import { backupCodexFileCredentials, codexFileCredentialsMatchAccount, inspectLocalCodexCredentialStatus, resetManagedCodexFileCredentials, restoreCodexFileCredentials, runForegroundCodexAuthAgent } from "./codex-auth-agent.js";
8
+ import { cleanupLegacyCodexProvider } from "./codex-legacy-cleanup.js";
9
+ import { ensureCodexRuntime, runOfficialCodex } from "./codex-process.js";
10
+ import { codexShortcutInstallHintNeeded, installCodexShortcuts, removeCodexShortcuts } from "./codex-shortcuts.js";
11
+ import { loadCodexQuotaUploads } from "./codex-quota-cache.js";
12
+ import { codexAccountStatusText, isCodexAccountAvailable, promptCodexAccount, renderCodexAccountDashboard } from "./codex-tui.js";
13
+ import { listRemoteCodexAccounts, normalizeCodexServiceUrl, uploadRemoteCodexAccounts } from "./codex-service-client.js";
14
+ import { clearCodexSelection, loadCodexSelection, saveCodexSelection } from "./codex-selection.js";
15
+ import { loadConfig } from "./config.js";
16
+ import { blockingBrowserLogin, ensureAccessToken, LoginRequiredError } from "./oauth.js";
17
+ function useJson(command) {
18
+ return Boolean(command.optsWithGlobals().json);
19
+ }
20
+ function printJson(value) {
21
+ process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
22
+ }
23
+ function positiveSeconds(value, option, fallback) {
24
+ if (value === undefined)
25
+ return fallback;
26
+ const parsed = Number(value);
27
+ if (!Number.isFinite(parsed) || parsed <= 0) {
28
+ throw new Error(`${option} 必须是大于 0 的秒数。`);
29
+ }
30
+ return Math.round(parsed * 1000);
31
+ }
32
+ function credentialStore(value) {
33
+ const normalized = value ?? "file";
34
+ if (normalized === "file" || normalized === "keyring" || normalized === "auto") {
35
+ return normalized;
36
+ }
37
+ throw new Error("--credential-store 仅支持 file、keyring 或 auto。");
38
+ }
39
+ function printAuthAgentLog(entry, json) {
40
+ if (json) {
41
+ printJson(entry);
42
+ return;
43
+ }
44
+ process.stdout.write(`${entry.at} ${entry.level.padEnd(5)} ${entry.event} ${entry.message}\n`);
45
+ }
46
+ function derivedServiceUrl() {
47
+ const backend = loadConfig().backendBaseUrl?.replace(/\/+$/, "");
48
+ if (!backend)
49
+ return undefined;
50
+ return /\/api$/u.test(backend) ? backend : `${backend}/api`;
51
+ }
52
+ async function resolveServiceOptions(options) {
53
+ const saved = await loadCodexSelection();
54
+ const environmentUrl = process.env.NUMA_CODEX_SERVICE_URL?.trim();
55
+ const rawUrl = options.server ?? environmentUrl ?? derivedServiceUrl() ?? saved?.serviceUrl;
56
+ if (!rawUrl) {
57
+ throw new Error("未配置 Codex 账号服务。请使用 --server,设置 NUMA_CODEX_SERVICE_URL,或配置平台 apiBaseUrl。");
58
+ }
59
+ const usesSavedService = options.server == null && !environmentUrl && rawUrl === saved?.serviceUrl;
60
+ const allowInsecurePoc = Boolean(options.insecurePoc || (usesSavedService && saved?.allowInsecurePoc));
61
+ return {
62
+ serviceUrl: normalizeCodexServiceUrl(rawUrl, allowInsecurePoc),
63
+ allowInsecurePoc
64
+ };
65
+ }
66
+ async function selectAccount(accounts, requested, selectedAccountId) {
67
+ const availableAccounts = accounts.filter(isCodexAccountAvailable);
68
+ if (accounts.length === 0)
69
+ throw new Error("Codex 账号服务没有分配给当前用户的账号。");
70
+ if (availableAccounts.length === 0) {
71
+ throw new Error("分配给当前用户的 ChatGPT 账号当前均不可用,请检查凭据状态或联系管理员。");
72
+ }
73
+ if (!requested) {
74
+ if (availableAccounts.length === 1)
75
+ return availableAccounts[0];
76
+ if (!process.stdin.isTTY) {
77
+ throw new Error("服务端有多个账号;非交互环境请运行 numa codex use <account-id> 显式选择。");
78
+ }
79
+ process.stderr.write(renderCodexAccountDashboard(accounts, selectedAccountId));
80
+ return promptCodexAccount(accounts, selectedAccountId);
81
+ }
82
+ const exact = accounts.find((account) => account.id === requested);
83
+ if (exact) {
84
+ if (!isCodexAccountAvailable(exact)) {
85
+ throw new Error(`ChatGPT 账号 ${exact.label} ${codexAccountStatusText(exact)},无法使用。`);
86
+ }
87
+ return exact;
88
+ }
89
+ const aliases = accounts.filter((account) => account.accountId === requested || account.label === requested);
90
+ if (aliases.length === 1) {
91
+ const account = aliases[0];
92
+ if (!isCodexAccountAvailable(account)) {
93
+ throw new Error(`ChatGPT 账号 ${account.label} ${codexAccountStatusText(account)},无法使用。`);
94
+ }
95
+ return account;
96
+ }
97
+ if (aliases.length > 1)
98
+ throw new Error(`账号选择 ${requested} 不唯一,请使用列表中的 account id。`);
99
+ throw new Error(`未找到 Codex 账号: ${requested}`);
100
+ }
101
+ function uploadSourceKey(account) {
102
+ return createHash("sha256")
103
+ .update(`${account.accountId ?? ""}\0${account.email ?? ""}\0${account.addedAt}`)
104
+ .digest("hex");
105
+ }
106
+ async function chooseAccount(options) {
107
+ const service = await resolveServiceOptions(options);
108
+ const response = await listRemoteCodexAccounts(loadConfig(), service.serviceUrl, service.allowInsecurePoc);
109
+ const previousSelection = await loadCodexSelection();
110
+ const account = await selectAccount(response.accounts, options.account, previousSelection?.account.id ?? response.defaultAccountId ?? undefined);
111
+ const selection = await saveCodexSelection({
112
+ serviceUrl: service.serviceUrl,
113
+ allowInsecurePoc: service.allowInsecurePoc,
114
+ account: {
115
+ id: account.id,
116
+ accountId: account.accountId,
117
+ label: account.label
118
+ }
119
+ });
120
+ return { account, ...service, selection };
121
+ }
122
+ async function installOfficialAuthOnce(selection) {
123
+ await cleanupLegacyCodexProvider();
124
+ await backupCodexFileCredentials();
125
+ await runForegroundCodexAuthAgent({
126
+ authConfig: loadConfig(),
127
+ selection,
128
+ credentialStore: "file",
129
+ once: true
130
+ });
131
+ }
132
+ async function ensureSelectedOfficialAuth(options) {
133
+ const saved = await loadCodexSelection();
134
+ const mustChoose = !saved ||
135
+ Boolean(options.selectAccount) ||
136
+ Boolean(options.server) ||
137
+ Boolean(options.account && options.account !== saved.account.id);
138
+ const selected = mustChoose
139
+ ? await chooseAccount(options)
140
+ : {
141
+ account: {
142
+ ...saved.account,
143
+ isDefault: false
144
+ },
145
+ serviceUrl: saved.serviceUrl,
146
+ selection: saved
147
+ };
148
+ if (mustChoose ||
149
+ !(await codexFileCredentialsMatchAccount(selected.selection.account.accountId))) {
150
+ await installOfficialAuthOnce(selected.selection);
151
+ }
152
+ else {
153
+ await cleanupLegacyCodexProvider();
154
+ }
155
+ return selected;
156
+ }
157
+ async function ensureRunLogin() {
158
+ const authConfig = loadConfig();
159
+ try {
160
+ await ensureAccessToken(authConfig);
161
+ }
162
+ catch (error) {
163
+ if (!(error instanceof LoginRequiredError))
164
+ throw error;
165
+ if (!process.stdin.isTTY) {
166
+ throw new LoginRequiredError("非交互环境没有可用的 Keycloak 登录。请先运行 numa login,或预置 NUMA_TOKEN_CACHE_PATH。");
167
+ }
168
+ process.stderr.write("尚未登录 Numa,正在启动 Keycloak 登录流程。\n");
169
+ await blockingBrowserLogin(authConfig);
170
+ }
171
+ }
172
+ function addExamples(command, examples) {
173
+ return command.addHelpText("after", `\nExamples:\n${examples.map((item) => ` ${item}`).join("\n")}\n`);
174
+ }
175
+ export function registerCodexCommands(program) {
176
+ const codex = program
177
+ .command("codex")
178
+ .description("安全选择服务端 Codex 账号,并用官方 Codex CLI 直接运行模型请求");
179
+ addExamples(codex
180
+ .command("list")
181
+ .description("列出服务端可用 Codex 账号元数据,不下载任何 refresh token")
182
+ .option("--server <url>", "Codex 账号服务 URL")
183
+ .option("--insecure-poc", "允许连接隔离网络中的非回环 HTTP 联调服务")
184
+ .action(async (options, command) => {
185
+ const service = await resolveServiceOptions(options);
186
+ const result = await listRemoteCodexAccounts(loadConfig(), service.serviceUrl, service.allowInsecurePoc);
187
+ if (useJson(command) || (await loadAppConfig()).output === "json") {
188
+ printJson({ ok: true, ...result });
189
+ return;
190
+ }
191
+ if (result.accounts.length === 0) {
192
+ process.stdout.write("没有可用的 Codex 账号。\n");
193
+ return;
194
+ }
195
+ const localSelection = await loadCodexSelection();
196
+ process.stdout.write(renderCodexAccountDashboard(result.accounts, localSelection?.account.id ?? result.defaultAccountId ?? undefined));
197
+ }), [
198
+ "numa codex list --server https://platform.example/api",
199
+ "numa codex list --server http://10.0.0.8:9876 --insecure-poc --json"
200
+ ]);
201
+ addExamples(codex
202
+ .command("upload")
203
+ .description("把当前 codex-multi-auth 账号池完整上传到平台服务器")
204
+ .option("--server <url>", "Codex 账号服务 URL")
205
+ .option("--insecure-poc", "允许连接隔离网络中的非回环 HTTP 联调服务")
206
+ .option("--storage <path>", "显式指定 codex-multi-auth 账号存储文件")
207
+ .option("--source <name>", "上传源标识;默认使用当前主机名")
208
+ .action(async (options, command) => {
209
+ await ensureRunLogin();
210
+ if (options.storage)
211
+ setStoragePathDirect(options.storage);
212
+ else
213
+ setStoragePath(null);
214
+ const storage = await loadAccounts();
215
+ if (!storage || storage.accounts.length === 0) {
216
+ throw new Error(`codex-multi-auth 账号池为空: ${getStoragePath()}`);
217
+ }
218
+ const quota = await loadCodexQuotaUploads(getStoragePath(), storage.accounts);
219
+ const accounts = storage.accounts.map((account, index) => {
220
+ if (!account.refreshToken?.trim()) {
221
+ throw new Error(`第 ${index + 1} 个 codex-multi-auth 账号缺少 refresh token,已取消整批上传。`);
222
+ }
223
+ return {
224
+ sourceKey: uploadSourceKey(account),
225
+ ...(account.accountId ? { accountId: account.accountId } : {}),
226
+ label: account.email?.trim() ||
227
+ account.accountLabel?.trim() ||
228
+ `Codex account ${index + 1}`,
229
+ ...(account.email ? { email: account.email } : {}),
230
+ refreshToken: account.refreshToken,
231
+ ...(account.accessToken ? { accessToken: account.accessToken } : {}),
232
+ ...(account.expiresAt ? { expiresAt: account.expiresAt } : {}),
233
+ ...(quota[index] ? { quota: quota[index] } : {}),
234
+ enabled: account.enabled !== false
235
+ };
236
+ });
237
+ const service = await resolveServiceOptions(options);
238
+ const result = await uploadRemoteCodexAccounts(loadConfig(), service.serviceUrl, {
239
+ source: options.source?.trim() || hostname(),
240
+ accounts
241
+ }, service.allowInsecurePoc);
242
+ if (useJson(command) || (await loadAppConfig()).output === "json") {
243
+ printJson({
244
+ ok: true,
245
+ storage_path: getStoragePath(),
246
+ uploaded: accounts.length,
247
+ ...result
248
+ });
249
+ return;
250
+ }
251
+ process.stdout.write(`已上传 ${accounts.length} 个账号:新建 ${result.created},更新 ${result.updated}。\n`);
252
+ process.stdout.write("refresh token 已通过认证连接发送,客户端输出和日志均不包含令牌。\n");
253
+ }), [
254
+ "numa codex upload --server https://platform.example/api",
255
+ "numa codex upload --storage ~/.codex/multi-auth/openai-codex-accounts.json"
256
+ ]);
257
+ addExamples(codex
258
+ .command("use [account]")
259
+ .description("选择账号并写入官方 ChatGPT auth.json")
260
+ .option("--server <url>", "Codex 账号服务 URL")
261
+ .option("--insecure-poc", "允许连接隔离网络中的非回环 HTTP 联调服务")
262
+ .action(async (account, options, command) => {
263
+ await ensureRunLogin();
264
+ const result = await chooseAccount({ ...options, account });
265
+ await installOfficialAuthOnce(result.selection);
266
+ if (useJson(command) || (await loadAppConfig()).output === "json") {
267
+ printJson({
268
+ ok: true,
269
+ account: result.account,
270
+ auth_mode: "chatgpt"
271
+ });
272
+ return;
273
+ }
274
+ process.stdout.write(`已选择: ${result.account.label} (${result.account.id})\n`);
275
+ process.stdout.write("官方 Codex ChatGPT 登录凭据已更新。\n");
276
+ }), [
277
+ "numa codex use --server https://platform.example/api",
278
+ "numa codex use acct_xxx --server http://10.0.0.8:9876 --insecure-poc"
279
+ ]);
280
+ addExamples(codex
281
+ .command("run [codexArgs...]")
282
+ .description("使用官方 ChatGPT auth.json 启动官方 Codex CLI")
283
+ .option("--account <id>", "本次使用的服务端账号 ID")
284
+ .option("--select-account", "启动前列出可用账号并交互选择")
285
+ .option("--server <url>", "Codex 账号服务 URL")
286
+ .option("--insecure-poc", "允许连接隔离网络中的非回环 HTTP 联调服务")
287
+ .allowUnknownOption(true)
288
+ .action(async (codexArgs, options) => {
289
+ await ensureCodexRuntime();
290
+ if (process.stderr.isTTY && await codexShortcutInstallHintNeeded()) {
291
+ process.stderr.write("提示:可运行 npx -y --prefer-online @numa-tech/numa@latest codex shortcut install 安装自动更新的 Codex 快捷命令和桌面入口。\n");
292
+ }
293
+ await ensureRunLogin();
294
+ const selected = await ensureSelectedOfficialAuth(options);
295
+ process.stderr.write(`即将使用 ChatGPT 账号: ${selected.account.label} (${selected.account.id})\n`);
296
+ process.exitCode = await runOfficialCodex(codexArgs);
297
+ }), [
298
+ "numa codex run --server https://platform.example/api",
299
+ "numa codex run --select-account",
300
+ "numa codex run --account acct_xxx",
301
+ "numa codex run --server http://10.0.0.8:9876 --insecure-poc -- exec \"完成长任务\"",
302
+ "numa codex run -- resume --last"
303
+ ]);
304
+ addExamples(codex
305
+ .command("app [workspace]")
306
+ .description("使用官方 ChatGPT auth.json 启动官方 Codex 桌面 App(macOS/Windows)")
307
+ .option("--account <id>", "使用的服务端账号 ID")
308
+ .option("--select-account", "启动前列出可用账号并交互选择")
309
+ .option("--server <url>", "Codex 账号服务 URL")
310
+ .option("--insecure-poc", "允许连接隔离网络中的非回环 HTTP 联调服务")
311
+ .action(async (workspace, options) => {
312
+ if (process.platform !== "darwin" && process.platform !== "win32") {
313
+ throw new Error("官方 Codex 桌面 App 仅支持 macOS 和 Windows。");
314
+ }
315
+ await ensureCodexRuntime();
316
+ await ensureRunLogin();
317
+ const selected = await ensureSelectedOfficialAuth(options);
318
+ process.stderr.write(`即将使用 ChatGPT 账号: ${selected.account.label} (${selected.account.id})\n`);
319
+ process.stderr.write("桌面 App 将读取官方 ChatGPT auth.json;若 App 已在运行,请完全退出后重新打开。\n");
320
+ process.exitCode = await runOfficialCodex(["app", workspace ?? "."]);
321
+ }), [
322
+ "numa codex app . --server https://platform.example/api",
323
+ "numa codex app . --select-account",
324
+ "numa codex app . --account acct_xxx",
325
+ "numa codex app . --server http://10.0.0.8:9876 --insecure-poc"
326
+ ]);
327
+ addExamples(codex
328
+ .command("shortcut [action]")
329
+ .description("安装或删除 codex run/app 的 macOS/Windows 快捷命令与桌面入口")
330
+ .option("--target <target>", "安装目标:run|app|both", "both")
331
+ .option("--command-name <name>", "快捷命令基础名称", CODEX_SHORTCUT_NAME)
332
+ .option("--app-name <name>", "桌面 App/开始菜单名称", CODEX_APP_NAME)
333
+ .option("--scope <scope>", "安装范围:auto|system|user;macOS 默认自动降级", "auto")
334
+ .option("--registry-url <url>", `快捷入口获取 ${PACKAGE_NAME} 的 npm registry`)
335
+ .option("--workspace <path>", "桌面 App 默认打开的工作区;默认当前目录")
336
+ .option("--account <id>", "快捷方式固定使用的服务端账号 ID")
337
+ .option("--select-account", "每次启动前交互选择账号")
338
+ .option("--server <url>", "快捷方式固定使用的 Codex 账号服务 URL")
339
+ .option("--insecure-poc", "快捷方式允许隔离网络中的非回环 HTTP 服务")
340
+ .option("--force", "确认覆盖同名但非 numa 管理的目标")
341
+ .action(async (action, options, command) => {
342
+ const selectedAction = action ?? "install";
343
+ if (selectedAction !== "install" && selectedAction !== "remove") {
344
+ throw new Error("shortcut action 仅支持 install 或 remove。");
345
+ }
346
+ const result = selectedAction === "install"
347
+ ? await installCodexShortcuts({
348
+ ...options,
349
+ registryUrl: options.registryUrl ?? (await loadAppConfig()).registryUrl
350
+ })
351
+ : await removeCodexShortcuts(options);
352
+ if (useJson(command) || (await loadAppConfig()).output === "json") {
353
+ printJson({
354
+ ok: true,
355
+ action: result.action,
356
+ platform: result.platform,
357
+ command_directory: result.commandDirectory,
358
+ scope: result.scope,
359
+ path_ready: result.pathReady,
360
+ path_hint: result.pathHint ?? null,
361
+ artifacts: result.artifacts
362
+ });
363
+ return;
364
+ }
365
+ const verb = result.action === "installed" ? "已安装" : "已删除";
366
+ process.stdout.write(`${verb} ${result.artifacts.length} 个 Codex 快捷入口(${result.scope === "system" ? "系统级" : "用户级"}):\n`);
367
+ for (const artifact of result.artifacts) {
368
+ process.stdout.write(` ${artifact.kind}: ${artifact.path}\n`);
369
+ }
370
+ if (result.pathHint)
371
+ process.stdout.write(`${result.pathHint}\n`);
372
+ }), [
373
+ "numa codex shortcut install",
374
+ "numa codex shortcut install --target run --select-account",
375
+ "numa codex shortcut install --target app --workspace ~/source/project",
376
+ "numa codex shortcut remove"
377
+ ]);
378
+ addExamples(codex
379
+ .command("auth-agent [account]")
380
+ .description("前台同步短效 token 到官方 Codex 登录,并持续输出状态日志")
381
+ .option("--server <url>", "Codex 账号服务 URL")
382
+ .option("--insecure-poc", "允许连接隔离网络中的非回环 HTTP 联调服务")
383
+ .option("--interval <seconds>", "状态检查间隔(秒)", "60")
384
+ .option("--refresh-before <seconds>", "到期前多少秒领取并安装新 token", "3600")
385
+ .option("--credential-store <mode>", "官方 Codex 凭据存储:file|keyring|auto", "file")
386
+ .option("--once", "只领取、安装并验证一次,然后退出")
387
+ .option("--replace-login", "确认替换当前官方 Codex 登录(必需)")
388
+ .option("--restore", "从 auth.json.numa-backup 恢复此前的文件登录")
389
+ .action(async (account, options, command) => {
390
+ const selectedStore = credentialStore(options.credentialStore);
391
+ if (selectedStore !== "file") {
392
+ throw new Error("ChatGPT auth.json 同步目前仅支持 --credential-store file。");
393
+ }
394
+ if (options.restore) {
395
+ const result = await restoreCodexFileCredentials();
396
+ printAuthAgentLog({
397
+ level: "INFO",
398
+ event: "auth.restore",
399
+ message: `已恢复此前的 Codex 文件登录: ${result.authPath};请完全退出并重新打开 App`,
400
+ at: new Date().toISOString()
401
+ }, useJson(command));
402
+ return;
403
+ }
404
+ if (!options.replaceLogin) {
405
+ throw new Error("auth-agent 会替换当前官方 Codex 登录;确认后请重新运行并添加 --replace-login。");
406
+ }
407
+ await ensureRunLogin();
408
+ const saved = await loadCodexSelection();
409
+ const mustChoose = !saved ||
410
+ Boolean(options.server) ||
411
+ Boolean(account && account !== saved.account.id);
412
+ const selection = mustChoose
413
+ ? (await chooseAccount({ ...options, account })).selection
414
+ : saved;
415
+ if (!selection)
416
+ throw new Error("无法读取已选择的 Codex 账号。");
417
+ const providerCleanup = await cleanupLegacyCodexProvider();
418
+ printAuthAgentLog({
419
+ level: "INFO",
420
+ event: "legacy.cleanup",
421
+ message: providerCleanup.changed
422
+ ? `已清理更名前废弃的 mcex-codex provider 配置: ${providerCleanup.configPath}`
423
+ : "未发现更名前废弃的 mcex-codex provider 配置",
424
+ at: new Date().toISOString()
425
+ }, useJson(command));
426
+ if (selectedStore === "file") {
427
+ const backup = await backupCodexFileCredentials();
428
+ const message = backup.action === "created"
429
+ ? `已备份当前 Codex 文件登录: ${backup.backupPath}`
430
+ : backup.action === "preserved"
431
+ ? `保留已有 Codex 登录备份: ${backup.backupPath}`
432
+ : `当前没有 auth.json,无需备份;目标路径=${backup.authPath}`;
433
+ printAuthAgentLog({
434
+ level: "INFO",
435
+ event: "auth.backup",
436
+ message,
437
+ at: new Date().toISOString()
438
+ }, useJson(command));
439
+ }
440
+ const controller = new AbortController();
441
+ const stop = () => controller.abort();
442
+ process.once("SIGINT", stop);
443
+ process.once("SIGTERM", stop);
444
+ try {
445
+ await runForegroundCodexAuthAgent({
446
+ authConfig: loadConfig(),
447
+ selection,
448
+ credentialStore: selectedStore,
449
+ intervalMs: positiveSeconds(options.interval, "--interval", 60_000),
450
+ refreshBeforeMs: positiveSeconds(options.refreshBefore, "--refresh-before", 60 * 60_000),
451
+ once: options.once,
452
+ signal: controller.signal,
453
+ log: (entry) => printAuthAgentLog(entry, useJson(command))
454
+ });
455
+ }
456
+ finally {
457
+ process.removeListener("SIGINT", stop);
458
+ process.removeListener("SIGTERM", stop);
459
+ }
460
+ }), [
461
+ "numa codex auth-agent acct_xxx --replace-login",
462
+ "numa codex auth-agent --replace-login --once",
463
+ "numa codex auth-agent --restore",
464
+ "numa codex auth-agent --replace-login --interval 30 --refresh-before 3600 --json"
465
+ ]);
466
+ addExamples(codex
467
+ .command("status")
468
+ .description("显示当前账号选择和官方 auth.json 状态,不输出令牌")
469
+ .action(async (_options, command) => {
470
+ const selection = await loadCodexSelection();
471
+ const localStatus = await inspectLocalCodexCredentialStatus(selection?.account.accountId);
472
+ const result = {
473
+ configured: Boolean(selection),
474
+ official_auth_matches_selection: selection != null &&
475
+ localStatus.usable &&
476
+ localStatus.matchesExpectedAccount === true,
477
+ official_auth: {
478
+ state: localStatus.state,
479
+ account_id: localStatus.accountId ?? null,
480
+ expires_at: localStatus.expiresAt
481
+ ? new Date(localStatus.expiresAt).toISOString()
482
+ : null,
483
+ usable: localStatus.usable
484
+ },
485
+ selection: selection
486
+ ? {
487
+ account: selection.account,
488
+ insecure_poc: selection.allowInsecurePoc,
489
+ updated_at: selection.updatedAt
490
+ }
491
+ : null
492
+ };
493
+ if (useJson(command) || (await loadAppConfig()).output === "json") {
494
+ printJson({ ok: true, ...result });
495
+ }
496
+ else {
497
+ process.stdout.write(`账号选择: ${selection ? selection.account.label : "未配置"}\n`);
498
+ process.stdout.write(`官方 ChatGPT 登录: ${result.official_auth_matches_selection ? "已匹配" : "未匹配"}\n`);
499
+ process.stdout.write(`本地凭据状态: ${localStatus.state}${localStatus.expiresAt ? `(到期 ${new Date(localStatus.expiresAt).toISOString()})` : ""}\n`);
500
+ }
501
+ }), ["numa codex status", "numa codex status --json"]);
502
+ addExamples(codex
503
+ .command("reset")
504
+ .description("重置账号选择和登录,并清理废弃的 provider 残留")
505
+ .action(async (_options, command) => {
506
+ const selection = await loadCodexSelection();
507
+ const cleanup = await cleanupLegacyCodexProvider();
508
+ const authReset = await resetManagedCodexFileCredentials(selection?.account.accountId);
509
+ await clearCodexSelection();
510
+ if (useJson(command) || (await loadAppConfig()).output === "json") {
511
+ printJson({
512
+ ok: true,
513
+ reset: true,
514
+ legacy_provider_removed: cleanup.changed,
515
+ auth_action: authReset.action
516
+ });
517
+ }
518
+ else {
519
+ const authMessage = authReset.action === "restored"
520
+ ? "已恢复原 Codex 登录"
521
+ : authReset.action === "removed"
522
+ ? "已移除 numa 写入的 Codex 登录"
523
+ : "未改动当前 Codex 登录";
524
+ process.stdout.write(`已重置 numa Codex 配置;${authMessage}(不会删除源主机账号)。\n`);
525
+ }
526
+ }), ["numa codex reset"]);
527
+ }
528
+ //# sourceMappingURL=codex-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-commands.js","sourceRoot":"","sources":["../src/codex-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface LegacyCodexProviderCleanup {
2
+ changed: boolean;
3
+ configPath: string;
4
+ }
5
+ export declare function cleanupLegacyCodexProvider(configPath?: string): Promise<LegacyCodexProviderCleanup>;
@@ -0,0 +1,77 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { getCodexCliConfigPath } from "codex-multi-auth/cli";
3
+ import { writePrivateText } from "./private-file.js";
4
+ // These identifiers intentionally retain the former product name so Numa can
5
+ // remove configuration written by releases that predate the rename.
6
+ const LEGACY_PROVIDER_ID = "mcex-codex";
7
+ const PROVIDER_START = "# >>> mcex codex provider (managed; do not edit)";
8
+ const PROVIDER_END = "# <<< mcex codex provider";
9
+ const APP_BIND_START = "# >>> mcex codex app provider (managed; do not edit)";
10
+ const APP_BIND_END = "# <<< mcex codex app provider";
11
+ const TOML_TABLE_HEADER = /^\s*\[{1,2}\s*[^\]]+?\s*\]{1,2}\s*(?:#.*)?$/;
12
+ async function readConfig(path) {
13
+ try {
14
+ return await readFile(path, "utf8");
15
+ }
16
+ catch (error) {
17
+ if (error.code === "ENOENT")
18
+ return "";
19
+ throw error;
20
+ }
21
+ }
22
+ function blockPattern(start, end) {
23
+ const escape = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24
+ return new RegExp(`${escape(start)}[\\s\\S]*?${escape(end)}\\r?\\n?`, "g");
25
+ }
26
+ function splitToml(raw) {
27
+ const lineEnding = raw.includes("\r\n") ? "\r\n" : "\n";
28
+ const lines = raw.length > 0 ? raw.split(/\r?\n/) : [];
29
+ if (lines.at(-1) === "")
30
+ lines.pop();
31
+ return { lines, lineEnding };
32
+ }
33
+ function topLevelEnd(lines) {
34
+ const firstTable = lines.findIndex((line) => TOML_TABLE_HEADER.test(line));
35
+ return firstTable < 0 ? lines.length : firstTable;
36
+ }
37
+ function previousProviderFromAppBlock(block) {
38
+ if (!/# previous_model_provider_present = true/.test(block))
39
+ return undefined;
40
+ const encoded = /# previous_model_provider_base64 = ([A-Za-z0-9+/=]*)/.exec(block)?.[1] ?? "";
41
+ const decoded = Buffer.from(encoded, "base64").toString("utf8");
42
+ return decoded && !decoded.includes(LEGACY_PROVIDER_ID) ? decoded : undefined;
43
+ }
44
+ export async function cleanupLegacyCodexProvider(configPath = getCodexCliConfigPath()) {
45
+ const current = await readConfig(configPath);
46
+ if (!current)
47
+ return { changed: false, configPath };
48
+ const appPattern = blockPattern(APP_BIND_START, APP_BIND_END);
49
+ const appMatch = appPattern.exec(current);
50
+ const previousProvider = appMatch
51
+ ? previousProviderFromAppBlock(appMatch[0])
52
+ : undefined;
53
+ let next = current
54
+ .replace(blockPattern(APP_BIND_START, APP_BIND_END), "")
55
+ .replace(blockPattern(PROVIDER_START, PROVIDER_END), "");
56
+ const parsed = splitToml(next);
57
+ const topEnd = topLevelEnd(parsed.lines);
58
+ const staleIndexes = [];
59
+ for (let index = 0; index < topEnd; index += 1) {
60
+ if (/^\s*model_provider\s*=\s*["']mcex-codex["']\s*(?:#.*)?$/.test(parsed.lines[index] ?? "")) {
61
+ staleIndexes.push(index);
62
+ }
63
+ }
64
+ for (const index of staleIndexes.reverse())
65
+ parsed.lines.splice(index, 1);
66
+ if (previousProvider &&
67
+ !parsed.lines.slice(0, topLevelEnd(parsed.lines)).some((line) => /^\s*model_provider\s*=/.test(line))) {
68
+ parsed.lines.splice(topLevelEnd(parsed.lines), 0, previousProvider);
69
+ }
70
+ next = parsed.lines.join(parsed.lineEnding).trimEnd();
71
+ next = next ? `${next}${parsed.lineEnding}` : "";
72
+ const changed = next !== current;
73
+ if (changed)
74
+ await writePrivateText(configPath, next);
75
+ return { changed, configPath };
76
+ }
77
+ //# sourceMappingURL=codex-legacy-cleanup.js.map