codex-multi-auth 2.8.6 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -0
- package/dist/lib/account-policy.d.ts +3 -1
- package/dist/lib/account-policy.d.ts.map +1 -1
- package/dist/lib/account-policy.js +14 -1
- package/dist/lib/codex-manager/login-flow.js +7 -0
- package/dist/lib/codex-manager/login-menu-actions.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-menu-actions.js +7 -1
- package/dist/lib/policy/runtime-policy.d.ts +7 -0
- package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
- package/dist/lib/policy/runtime-policy.js +1 -0
- package/dist/lib/request/fetch-helpers.d.ts +7 -0
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
- package/dist/lib/request/fetch-helpers.js +1 -1
- package/dist/lib/request/rate-limit-decision.d.ts +27 -0
- package/dist/lib/request/rate-limit-decision.d.ts.map +1 -1
- package/dist/lib/request/rate-limit-decision.js +117 -2
- package/dist/lib/request/response-handler.d.ts +3 -1
- package/dist/lib/request/response-handler.d.ts.map +1 -1
- package/dist/lib/request/response-handler.js +26 -5
- package/dist/lib/request/stream-failover-runtime.d.ts +8 -1
- package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
- package/dist/lib/request/stream-failover-runtime.js +9 -1
- package/dist/lib/request/stream-failover.d.ts.map +1 -1
- package/dist/lib/request/stream-failover.js +41 -0
- package/dist/lib/runtime/account-check.d.ts.map +1 -1
- package/dist/lib/runtime/account-check.js +8 -1
- package/dist/lib/runtime/account-status.d.ts +39 -10
- package/dist/lib/runtime/account-status.d.ts.map +1 -1
- package/dist/lib/runtime/account-status.js +47 -42
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +73 -8
- package/dist/lib/storage.d.ts +19 -0
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +32 -0
- package/dist/lib/usage/index.d.ts +2 -0
- package/dist/lib/usage/index.d.ts.map +1 -1
- package/dist/lib/usage/index.js +2 -0
- package/dist/lib/usage/stream-usage-deferral.d.ts +39 -0
- package/dist/lib/usage/stream-usage-deferral.d.ts.map +1 -0
- package/dist/lib/usage/stream-usage-deferral.js +54 -0
- package/dist/lib/usage/usage-extraction.d.ts +42 -0
- package/dist/lib/usage/usage-extraction.d.ts.map +1 -0
- package/dist/lib/usage/usage-extraction.js +178 -0
- package/package.json +1 -1
- package/scripts/codex.js +300 -82
package/scripts/codex.js
CHANGED
|
@@ -421,6 +421,14 @@ function extractForcedAccountFlag(args) {
|
|
|
421
421
|
let sawFlag = false;
|
|
422
422
|
for (let index = 0; index < args.length; index += 1) {
|
|
423
423
|
const arg = args[index];
|
|
424
|
+
// `--` ends option parsing: everything after it is Codex's root
|
|
425
|
+
// `[PROMPT]` text. A `--account` spelled in there is the user's prompt,
|
|
426
|
+
// not a launcher flag — stripping it would both mangle the prompt and
|
|
427
|
+
// silently pin the run to an account nobody selected.
|
|
428
|
+
if (arg === "--") {
|
|
429
|
+
strippedArgs.push(...args.slice(index));
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
424
432
|
if (arg === "--account") {
|
|
425
433
|
sawFlag = true;
|
|
426
434
|
const next = args[index + 1];
|
|
@@ -1365,6 +1373,9 @@ function replaceRequestedModel(args, nextModel) {
|
|
|
1365
1373
|
const nextArgs = [...args];
|
|
1366
1374
|
for (let i = 0; i < nextArgs.length; i += 1) {
|
|
1367
1375
|
const arg = nextArgs[i];
|
|
1376
|
+
// Past `--` the tokens are the user's prompt. Rewriting one in place
|
|
1377
|
+
// would edit the prompt text itself before re-forwarding it.
|
|
1378
|
+
if (arg === "--") break;
|
|
1368
1379
|
if ((arg === "--model" || arg === "-m") && typeof nextArgs[i + 1] === "string") {
|
|
1369
1380
|
nextArgs[i + 1] = nextModel;
|
|
1370
1381
|
return nextArgs;
|
|
@@ -1859,6 +1870,11 @@ async function forwardToRealCodex(codexBin, rawArgs, baseEnv = process.env) {
|
|
|
1859
1870
|
function hasCliAuthCredentialsStoreOverride(args) {
|
|
1860
1871
|
for (let i = 0; i < args.length; i += 1) {
|
|
1861
1872
|
const arg = args[i];
|
|
1873
|
+
// Everything after `--` is the root `[PROMPT]` positional, not options:
|
|
1874
|
+
// a prompt whose text spells `--config=cli_auth_credentials_store=...` is
|
|
1875
|
+
// not a caller override, and treating it as one would silently drop the
|
|
1876
|
+
// file auth store this wrapper depends on.
|
|
1877
|
+
if (arg === "--") break;
|
|
1862
1878
|
if (arg === "-c" || arg === "--config") {
|
|
1863
1879
|
const next = args[i + 1];
|
|
1864
1880
|
if (!next || !next.includes("=")) continue;
|
|
@@ -2357,6 +2373,10 @@ function coerceReasoningEffortForModel(model, effort) {
|
|
|
2357
2373
|
function extractRequestedModel(args) {
|
|
2358
2374
|
for (let i = 0; i < args.length; i += 1) {
|
|
2359
2375
|
const arg = args[i];
|
|
2376
|
+
// Past `--` every token is root `[PROMPT]` text; a `-m` in there names
|
|
2377
|
+
// no model, and reading one would coerce reasoning config for a model
|
|
2378
|
+
// the user never requested.
|
|
2379
|
+
if (arg === "--") break;
|
|
2360
2380
|
if (arg === "--model" || arg === "-m") {
|
|
2361
2381
|
const next = args[i + 1];
|
|
2362
2382
|
if (typeof next === "string" && next.trim().length > 0) {
|
|
@@ -2427,6 +2447,8 @@ function rewriteReasoningConfigArgs(rawArgs) {
|
|
|
2427
2447
|
const nextArgs = [...rawArgs];
|
|
2428
2448
|
for (let i = 0; i < nextArgs.length; i += 1) {
|
|
2429
2449
|
const arg = nextArgs[i];
|
|
2450
|
+
// Past `--` a `-c key=value` pair is prompt text, not a config override.
|
|
2451
|
+
if (arg === "--") break;
|
|
2430
2452
|
if ((arg === "-c" || arg === "--config") && typeof nextArgs[i + 1] === "string") {
|
|
2431
2453
|
nextArgs[i + 1] = rewriteReasoningConfigAssignment(
|
|
2432
2454
|
nextArgs[i + 1],
|
|
@@ -4903,13 +4925,20 @@ async function createRuntimeRotationAppHelperContext(
|
|
|
4903
4925
|
}
|
|
4904
4926
|
};
|
|
4905
4927
|
|
|
4928
|
+
const injectedArgs = [
|
|
4929
|
+
...helperArgs,
|
|
4930
|
+
"-c",
|
|
4931
|
+
`model_provider=${configTomlModule.tomlStringLiteral(RUNTIME_ROTATION_PROXY_PROVIDER_ID)}`,
|
|
4932
|
+
];
|
|
4906
4933
|
return {
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4934
|
+
// Root TUI argv can end in the optional `[PROMPT]` positional, and `--`
|
|
4935
|
+
// binds everything after it to that positional — overrides appended
|
|
4936
|
+
// there would become prompt text, so the interactive branch asks for
|
|
4937
|
+
// them to be injected ahead of the prompt instead.
|
|
4938
|
+
args:
|
|
4939
|
+
options.injectArgsBeforeRootPrompt === true
|
|
4940
|
+
? insertArgsBeforeRootPrompt(baseContext.args, injectedArgs)
|
|
4941
|
+
: insertArgsBeforeForwardedSeparator(baseContext.args, injectedArgs),
|
|
4913
4942
|
env: {
|
|
4914
4943
|
...baseContext.env,
|
|
4915
4944
|
...helperEnv,
|
|
@@ -4991,13 +5020,19 @@ async function createRuntimeRotationProxyContextIfEnabled(
|
|
|
4991
5020
|
if (isCodexAppCommand(rawArgs)) {
|
|
4992
5021
|
return startAppHelperContext();
|
|
4993
5022
|
}
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
) {
|
|
5023
|
+
// Classify once: each predicate re-walks the whole argv, and the root-TUI
|
|
5024
|
+
// answer is needed twice below.
|
|
5025
|
+
const isRootTuiLaunch = isCodexInteractiveTuiCommand(rawArgs);
|
|
5026
|
+
if (isRootTuiLaunch || isCodexInteractiveResumeCommand(rawArgs)) {
|
|
4998
5027
|
return startAppHelperContext({
|
|
4999
5028
|
detachOnExit: true,
|
|
5000
5029
|
useCanonicalHome: true,
|
|
5030
|
+
// Root TUI launches may carry the optional `[PROMPT]` positional
|
|
5031
|
+
// (possibly forced by `--`); the provider overrides must stay on the
|
|
5032
|
+
// option side of it. `resume`/`fork` keep the appended ordering their
|
|
5033
|
+
// argv has always forwarded with — their tokens are subcommand args,
|
|
5034
|
+
// not the root prompt.
|
|
5035
|
+
injectArgsBeforeRootPrompt: isRootTuiLaunch,
|
|
5001
5036
|
});
|
|
5002
5037
|
}
|
|
5003
5038
|
|
|
@@ -5088,90 +5123,257 @@ function isPureHelpOrVersionArgs(rawArgs) {
|
|
|
5088
5123
|
);
|
|
5089
5124
|
}
|
|
5090
5125
|
|
|
5126
|
+
// Hoisted: every argv walk calls consumesNextArg once per token, and a Set
|
|
5127
|
+
// rebuilt per call allocated this list on every one of them.
|
|
5128
|
+
const OPTIONS_CONSUMING_NEXT_ARG = new Set([
|
|
5129
|
+
"-c",
|
|
5130
|
+
"--config",
|
|
5131
|
+
"--enable",
|
|
5132
|
+
"--disable",
|
|
5133
|
+
"--listen",
|
|
5134
|
+
"--remote",
|
|
5135
|
+
"--remote-auth-token-env",
|
|
5136
|
+
"--ws-auth",
|
|
5137
|
+
"--ws-token-file",
|
|
5138
|
+
"--ws-token-sha256",
|
|
5139
|
+
"--ws-shared-secret-file",
|
|
5140
|
+
"--ws-issuer",
|
|
5141
|
+
"--ws-audience",
|
|
5142
|
+
"--ws-max-clock-skew-seconds",
|
|
5143
|
+
"--download-url",
|
|
5144
|
+
"-i",
|
|
5145
|
+
"--image",
|
|
5146
|
+
"-m",
|
|
5147
|
+
"--model",
|
|
5148
|
+
"--local-provider",
|
|
5149
|
+
"-p",
|
|
5150
|
+
"--profile",
|
|
5151
|
+
"-s",
|
|
5152
|
+
"--sandbox",
|
|
5153
|
+
"-a",
|
|
5154
|
+
"--ask-for-approval",
|
|
5155
|
+
"-C",
|
|
5156
|
+
"--cd",
|
|
5157
|
+
"--add-dir",
|
|
5158
|
+
"--output-schema",
|
|
5159
|
+
"--color",
|
|
5160
|
+
"-o",
|
|
5161
|
+
"--output-last-message",
|
|
5162
|
+
]);
|
|
5163
|
+
|
|
5091
5164
|
function consumesNextArg(arg) {
|
|
5092
|
-
return
|
|
5093
|
-
"-c",
|
|
5094
|
-
"--config",
|
|
5095
|
-
"--enable",
|
|
5096
|
-
"--disable",
|
|
5097
|
-
"--listen",
|
|
5098
|
-
"--remote",
|
|
5099
|
-
"--remote-auth-token-env",
|
|
5100
|
-
"--ws-auth",
|
|
5101
|
-
"--ws-token-file",
|
|
5102
|
-
"--ws-token-sha256",
|
|
5103
|
-
"--ws-shared-secret-file",
|
|
5104
|
-
"--ws-issuer",
|
|
5105
|
-
"--ws-audience",
|
|
5106
|
-
"--ws-max-clock-skew-seconds",
|
|
5107
|
-
"--download-url",
|
|
5108
|
-
"-i",
|
|
5109
|
-
"--image",
|
|
5110
|
-
"-m",
|
|
5111
|
-
"--model",
|
|
5112
|
-
"--local-provider",
|
|
5113
|
-
"-p",
|
|
5114
|
-
"--profile",
|
|
5115
|
-
"-s",
|
|
5116
|
-
"--sandbox",
|
|
5117
|
-
"-a",
|
|
5118
|
-
"--ask-for-approval",
|
|
5119
|
-
"-C",
|
|
5120
|
-
"--cd",
|
|
5121
|
-
"--add-dir",
|
|
5122
|
-
"--output-schema",
|
|
5123
|
-
"--color",
|
|
5124
|
-
"-o",
|
|
5125
|
-
"--output-last-message",
|
|
5126
|
-
]).has(arg);
|
|
5165
|
+
return OPTIONS_CONSUMING_NEXT_ARG.has(arg);
|
|
5127
5166
|
}
|
|
5128
5167
|
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5168
|
+
// Codex's root grammar is `codex [OPTIONS] [PROMPT]` / `codex [OPTIONS]
|
|
5169
|
+
// <COMMAND> [ARGS]`, so the first positional is only a command when it names a
|
|
5170
|
+
// real root subcommand — otherwise it is the optional initial prompt of an
|
|
5171
|
+
// interactive TUI launch. The allowlist mirrors `codex --help`; treating an
|
|
5172
|
+
// unknown positional as a prompt matches native Codex, where an unrecognized
|
|
5173
|
+
// token also falls through to the prompt positional rather than erroring as a
|
|
5174
|
+
// bad subcommand. Routing predicates all resolve through this map so aliases
|
|
5175
|
+
// classify like their canonical command.
|
|
5176
|
+
//
|
|
5177
|
+
// A real root subcommand missing from this set is misrouted, not merely
|
|
5178
|
+
// misnamed: it classifies as an interactive prompt and takes the app-helper
|
|
5179
|
+
// branch with `detachOnExit: true`, so a short-lived command leaves a detached
|
|
5180
|
+
// helper and its loopback proxy idling until the rotation idle timeout. Keep
|
|
5181
|
+
// the set in sync with the upstream grammar — clap publishes the authoritative
|
|
5182
|
+
// root list in its own completions, so
|
|
5183
|
+
// codex completion bash | grep -oE 'opts="[^"]*"' | grep ' exec '
|
|
5184
|
+
// prints every root command (and alias) for the installed codex-cli.
|
|
5185
|
+
|
|
5186
|
+
const CODEX_ROOT_COMMAND_ALIASES = new Map([
|
|
5187
|
+
["e", "exec"],
|
|
5188
|
+
["a", "apply"],
|
|
5189
|
+
]);
|
|
5190
|
+
const CODEX_ROOT_COMMANDS = new Set([
|
|
5191
|
+
"exec",
|
|
5192
|
+
"review",
|
|
5193
|
+
"login",
|
|
5194
|
+
"logout",
|
|
5195
|
+
"mcp",
|
|
5196
|
+
"plugin",
|
|
5197
|
+
"mcp-server",
|
|
5198
|
+
"app-server",
|
|
5199
|
+
"remote-control",
|
|
5200
|
+
"app",
|
|
5201
|
+
"completion",
|
|
5202
|
+
"update",
|
|
5203
|
+
"doctor",
|
|
5204
|
+
"sandbox",
|
|
5205
|
+
"debug",
|
|
5206
|
+
"apply",
|
|
5207
|
+
"resume",
|
|
5208
|
+
"archive",
|
|
5209
|
+
"delete",
|
|
5210
|
+
"migrate-rollouts",
|
|
5211
|
+
"unarchive",
|
|
5212
|
+
"fork",
|
|
5213
|
+
"cloud",
|
|
5214
|
+
"exec-server",
|
|
5215
|
+
"features",
|
|
5216
|
+
"help",
|
|
5217
|
+
"auth",
|
|
5218
|
+
// Hidden root subcommands: absent from `codex --help`, but real — each is
|
|
5219
|
+
// documented by `codex help <name>`.
|
|
5220
|
+
"responses-api-proxy",
|
|
5221
|
+
"cloud-tasks",
|
|
5222
|
+
"execpolicy",
|
|
5223
|
+
// Internal stdio/UDS relay. Hidden like the three above, and short-lived:
|
|
5224
|
+
// omitting it classified `codex stdio-to-uds <socket>` as a root prompt,
|
|
5225
|
+
// which took the detached app-helper branch and leaked a helper per call.
|
|
5226
|
+
"stdio-to-uds",
|
|
5227
|
+
]);
|
|
5228
|
+
|
|
5229
|
+
function resolveCodexRootCommand(token) {
|
|
5230
|
+
const command = CODEX_ROOT_COMMAND_ALIASES.get(token) ?? token;
|
|
5231
|
+
return CODEX_ROOT_COMMANDS.has(command) ? command : null;
|
|
5232
|
+
}
|
|
5233
|
+
|
|
5234
|
+
// `-i/--image` is greedy (`<FILE>...`): native Codex consumes every following
|
|
5235
|
+
// free token up to the next option-like token, so a prompt can only follow the
|
|
5236
|
+
// image list after another option or a `--`. Every argv walker below skips the
|
|
5237
|
+
// same span, or the wrapper would disagree with native Codex about where the
|
|
5238
|
+
// positional side starts.
|
|
5239
|
+
function consumesRemainingFreeArgs(arg) {
|
|
5240
|
+
return arg === "-i" || arg === "--image";
|
|
5241
|
+
}
|
|
5242
|
+
|
|
5243
|
+
function skipOptionValueSpan(args, i) {
|
|
5244
|
+
const arg = args[i];
|
|
5245
|
+
if (consumesRemainingFreeArgs(arg)) {
|
|
5246
|
+
let end = i;
|
|
5247
|
+
while (
|
|
5248
|
+
end + 1 < args.length &&
|
|
5249
|
+
typeof args[end + 1] === "string" &&
|
|
5250
|
+
args[end + 1].length > 0 &&
|
|
5251
|
+
(args[end + 1] === "-" || !args[end + 1].startsWith("-"))
|
|
5252
|
+
) {
|
|
5253
|
+
end += 1;
|
|
5254
|
+
}
|
|
5255
|
+
return end;
|
|
5132
5256
|
}
|
|
5133
|
-
|
|
5134
|
-
|
|
5257
|
+
return consumesNextArg(arg) ? i + 1 : i;
|
|
5258
|
+
}
|
|
5259
|
+
|
|
5260
|
+
/**
|
|
5261
|
+
* The single definition of where an argv's option side ends. Walking from
|
|
5262
|
+
* `startIndex`, skips option flags and the values they consume — including a
|
|
5263
|
+
* greedy `-i a.png b.png` span — and reports what stopped the walk:
|
|
5264
|
+
*
|
|
5265
|
+
* - `index`: the first free (positional) token, or null when there is none.
|
|
5266
|
+
* - `terminatorIndex`: the bare `--` that ended option parsing, or null.
|
|
5267
|
+
* - `boundary`: where option-side content ends, i.e. the positional, the
|
|
5268
|
+
* `--`, or `args.length`. This is where injected overrides belong.
|
|
5269
|
+
*
|
|
5270
|
+
* Callers keep their own policy for `--` (the root grammar binds everything
|
|
5271
|
+
* after it to `[PROMPT]`; a subcommand's does not), but they must not keep
|
|
5272
|
+
* their own copy of the walk: a classifier and an injector that disagree by
|
|
5273
|
+
* one token put a `-c` override into prompt text or read prompt text as a
|
|
5274
|
+
* subcommand.
|
|
5275
|
+
*/
|
|
5276
|
+
function findRootPositional(args, startIndex = 0) {
|
|
5277
|
+
if (!Array.isArray(args)) {
|
|
5278
|
+
return { index: null, terminatorIndex: null, boundary: 0 };
|
|
5279
|
+
}
|
|
5280
|
+
for (let i = startIndex; i < args.length; i += 1) {
|
|
5281
|
+
const arg = args[i];
|
|
5135
5282
|
if (typeof arg !== "string" || arg.length === 0) continue;
|
|
5136
5283
|
if (arg === "--") {
|
|
5137
|
-
return i
|
|
5138
|
-
? { command: rawArgs[i + 1], index: i + 1 }
|
|
5139
|
-
: null;
|
|
5284
|
+
return { index: null, terminatorIndex: i, boundary: i };
|
|
5140
5285
|
}
|
|
5141
5286
|
if (arg.startsWith("--config=")) {
|
|
5142
5287
|
continue;
|
|
5143
5288
|
}
|
|
5144
5289
|
if (arg.startsWith("--") || (arg.startsWith("-") && arg !== "-")) {
|
|
5145
|
-
|
|
5146
|
-
i += 1;
|
|
5147
|
-
}
|
|
5290
|
+
i = skipOptionValueSpan(args, i);
|
|
5148
5291
|
continue;
|
|
5149
5292
|
}
|
|
5150
|
-
return {
|
|
5293
|
+
return { index: i, terminatorIndex: null, boundary: i };
|
|
5294
|
+
}
|
|
5295
|
+
return { index: null, terminatorIndex: null, boundary: args.length };
|
|
5296
|
+
}
|
|
5297
|
+
|
|
5298
|
+
function findForwardedCommand(rawArgs) {
|
|
5299
|
+
if (!Array.isArray(rawArgs) || rawArgs.length === 0) {
|
|
5300
|
+
return null;
|
|
5301
|
+
}
|
|
5302
|
+
// `--` ends option parsing: everything after it binds to the root
|
|
5303
|
+
// `[PROMPT]` positional, never to a subcommand, even when the text happens
|
|
5304
|
+
// to spell a command name. `findRootPositional` reports it as a terminator
|
|
5305
|
+
// and yields no positional, which settles the launch as interactive.
|
|
5306
|
+
//
|
|
5307
|
+
// Native Codex fills the root `[PROMPT]` slot with the first free token and
|
|
5308
|
+
// still tries a later one as a subcommand (`codex hello exec …` runs exec),
|
|
5309
|
+
// so an unknown positional keeps the scan going.
|
|
5310
|
+
for (
|
|
5311
|
+
let cursor = findRootPositional(rawArgs, 0);
|
|
5312
|
+
cursor.index !== null;
|
|
5313
|
+
cursor = findRootPositional(rawArgs, cursor.index + 1)
|
|
5314
|
+
) {
|
|
5315
|
+
const command = resolveCodexRootCommand(rawArgs[cursor.index]);
|
|
5316
|
+
if (command !== null) {
|
|
5317
|
+
return { command, index: cursor.index };
|
|
5318
|
+
}
|
|
5151
5319
|
}
|
|
5152
5320
|
|
|
5153
5321
|
return null;
|
|
5154
5322
|
}
|
|
5155
5323
|
|
|
5324
|
+
// Inserts option-side args ahead of the root `[PROMPT]` positional (or the
|
|
5325
|
+
// `--` that forces one), so injected overrides cannot be read as prompt text.
|
|
5326
|
+
// With no positional at all this is a plain append, which keeps bare-TUI argv
|
|
5327
|
+
// byte-identical to the pre-insertion shape.
|
|
5328
|
+
function insertArgsBeforeRootPrompt(baseArgs, injectedArgs) {
|
|
5329
|
+
const { boundary } = findRootPositional(baseArgs);
|
|
5330
|
+
return [
|
|
5331
|
+
...baseArgs.slice(0, boundary),
|
|
5332
|
+
...injectedArgs,
|
|
5333
|
+
...baseArgs.slice(boundary),
|
|
5334
|
+
];
|
|
5335
|
+
}
|
|
5336
|
+
|
|
5337
|
+
// Inserts args before a `--` separator when one is present, else appends.
|
|
5338
|
+
// Subcommand argv keeps its leading subcommand token — `resume`/`fork` argv is
|
|
5339
|
+
// pinned to it — but anything appended past a `--` lands in the subcommand's
|
|
5340
|
+
// own positional list: Codex rejects that outright for `exec`/`review`
|
|
5341
|
+
// ("unexpected argument '-c' found"), and worse, silently forwards it as
|
|
5342
|
+
// arguments for `sandbox` and into the stored config for `mcp add`. The
|
|
5343
|
+
// separator bounds the append.
|
|
5344
|
+
function insertArgsBeforeForwardedSeparator(baseArgs, injectedArgs) {
|
|
5345
|
+
// Deliberately not `findRootPositional`: that reports where the option side
|
|
5346
|
+
// ends, stopping at the first positional, and a subcommand's own arguments
|
|
5347
|
+
// are positionals — it would answer `exec` for `exec -- hi`. The question
|
|
5348
|
+
// here is only where the separator sits, and a bare `indexOf` answers it
|
|
5349
|
+
// exactly: clap never consumes `--` as an option value (`codex --cd -- hi`
|
|
5350
|
+
// is "a value is required for '--cd'"), so the first `--` is always the
|
|
5351
|
+
// separator, and it always follows the subcommand token because
|
|
5352
|
+
// `findForwardedCommand` returns null the moment it sees one.
|
|
5353
|
+
const separatorIndex = baseArgs.indexOf("--");
|
|
5354
|
+
if (separatorIndex === -1) {
|
|
5355
|
+
return [...baseArgs, ...injectedArgs];
|
|
5356
|
+
}
|
|
5357
|
+
return [
|
|
5358
|
+
...baseArgs.slice(0, separatorIndex),
|
|
5359
|
+
...injectedArgs,
|
|
5360
|
+
...baseArgs.slice(separatorIndex),
|
|
5361
|
+
];
|
|
5362
|
+
}
|
|
5363
|
+
|
|
5156
5364
|
function findForwardedSubcommand(rawArgs, commandIndex) {
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
if (consumesNextArg(arg)) {
|
|
5168
|
-
i += 1;
|
|
5169
|
-
}
|
|
5170
|
-
continue;
|
|
5171
|
-
}
|
|
5172
|
-
return arg;
|
|
5365
|
+
const { index, terminatorIndex } = findRootPositional(
|
|
5366
|
+
rawArgs,
|
|
5367
|
+
commandIndex + 1,
|
|
5368
|
+
);
|
|
5369
|
+
// Unlike the root grammar, a subcommand's `--` still precedes its own
|
|
5370
|
+
// positional args, so the token after it is the nested subcommand.
|
|
5371
|
+
if (terminatorIndex !== null) {
|
|
5372
|
+
return terminatorIndex + 1 < rawArgs.length
|
|
5373
|
+
? rawArgs[terminatorIndex + 1]
|
|
5374
|
+
: null;
|
|
5173
5375
|
}
|
|
5174
|
-
return null;
|
|
5376
|
+
return index === null ? null : rawArgs[index];
|
|
5175
5377
|
}
|
|
5176
5378
|
|
|
5177
5379
|
function hasHelpFlagAfterCommand(rawArgs, commandIndex) {
|
|
@@ -5179,8 +5381,8 @@ function hasHelpFlagAfterCommand(rawArgs, commandIndex) {
|
|
|
5179
5381
|
const arg = rawArgs[i];
|
|
5180
5382
|
if (arg === "--") return false;
|
|
5181
5383
|
if (arg === "--help" || arg === "-h" || arg === "help") return true;
|
|
5182
|
-
if (typeof arg === "string"
|
|
5183
|
-
i
|
|
5384
|
+
if (typeof arg === "string") {
|
|
5385
|
+
i = skipOptionValueSpan(rawArgs, i);
|
|
5184
5386
|
}
|
|
5185
5387
|
}
|
|
5186
5388
|
return false;
|
|
@@ -5194,6 +5396,11 @@ function isCodexAppServerCommand(rawArgs) {
|
|
|
5194
5396
|
return findForwardedCommand(rawArgs)?.command === "app-server";
|
|
5195
5397
|
}
|
|
5196
5398
|
|
|
5399
|
+
// True for every root TUI launch: bare `codex [OPTIONS]`, and `codex
|
|
5400
|
+
// [OPTIONS] [PROMPT]` with the optional initial prompt — including a prompt
|
|
5401
|
+
// forced by `--`. Both shapes start the same interactive session and need the
|
|
5402
|
+
// canonical home, or Codex stalls rebuilding the omitted thread index inside
|
|
5403
|
+
// the shadow mirror before it can submit the already-delivered prompt.
|
|
5197
5404
|
function isCodexInteractiveTuiCommand(rawArgs) {
|
|
5198
5405
|
return findForwardedCommand(rawArgs) === null;
|
|
5199
5406
|
}
|
|
@@ -5219,7 +5426,14 @@ function shouldUseRuntimeRoutingForForwardedArgs(rawArgs) {
|
|
|
5219
5426
|
|
|
5220
5427
|
const command = findForwardedCommand(rawArgs);
|
|
5221
5428
|
if (!command) {
|
|
5222
|
-
|
|
5429
|
+
// A help flag alongside a root prompt (`codex "prompt" --help`) prints
|
|
5430
|
+
// help and exits clean, so it must skip the transport for the same
|
|
5431
|
+
// reason as the request-command help forms below: the interactive
|
|
5432
|
+
// branch detaches its helper on a clean exit, and a helper started
|
|
5433
|
+
// just to print help would idle until its detached timeout. The scan
|
|
5434
|
+
// stops at `--`, so help-looking text inside a forced prompt still
|
|
5435
|
+
// routes normally.
|
|
5436
|
+
return !hasHelpFlagAfterCommand(rawArgs, -1);
|
|
5223
5437
|
}
|
|
5224
5438
|
|
|
5225
5439
|
const requestCommands = new Set(["exec", "review", "resume", "fork", "app"]);
|
|
@@ -5450,12 +5664,16 @@ function buildForwardArgs(rawArgs) {
|
|
|
5450
5664
|
return { args: compatibilityArgs, requestedModel };
|
|
5451
5665
|
}
|
|
5452
5666
|
|
|
5667
|
+
const authStoreArgs = ["-c", 'cli_auth_credentials_store="file"'];
|
|
5453
5668
|
return {
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5669
|
+
// A root launch may end in the `[PROMPT]` positional — possibly forced
|
|
5670
|
+
// by `--`, where an appended `-c` pair would be read as prompt text —
|
|
5671
|
+
// so the override is inserted on the option side of the prompt there.
|
|
5672
|
+
// Subcommand argv keeps the appended ordering it has always forwarded.
|
|
5673
|
+
args:
|
|
5674
|
+
findForwardedCommand(compatibilityArgs) === null
|
|
5675
|
+
? insertArgsBeforeRootPrompt(compatibilityArgs, authStoreArgs)
|
|
5676
|
+
: insertArgsBeforeForwardedSeparator(compatibilityArgs, authStoreArgs),
|
|
5459
5677
|
requestedModel,
|
|
5460
5678
|
};
|
|
5461
5679
|
}
|