codexuse-cli 5.1.1 → 5.1.6
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/dist/index.js +301 -502
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4327,9 +4327,19 @@ async function requestGumroadVerify(licenseKey, mode) {
|
|
|
4327
4327
|
clearTimeout(timeout);
|
|
4328
4328
|
}
|
|
4329
4329
|
}
|
|
4330
|
-
function
|
|
4330
|
+
function isExplicitRevocationMessage(message) {
|
|
4331
|
+
if (!message) {
|
|
4332
|
+
return false;
|
|
4333
|
+
}
|
|
4334
|
+
const normalized = message.toLowerCase();
|
|
4335
|
+
return normalized.includes("revoked") || normalized.includes("refunded") || normalized.includes("chargeback") || normalized.includes("disabled") || normalized.includes("subscription") || normalized.includes("no longer active");
|
|
4336
|
+
}
|
|
4337
|
+
function normalizeVerificationResult(response, mode) {
|
|
4331
4338
|
if (!response.success) {
|
|
4332
4339
|
const message = response.message ?? "License key is invalid.";
|
|
4340
|
+
if (mode === "refresh" && !isExplicitRevocationMessage(message)) {
|
|
4341
|
+
throw new LicenseError(message, "network");
|
|
4342
|
+
}
|
|
4333
4343
|
throw new LicenseError(message, "invalid");
|
|
4334
4344
|
}
|
|
4335
4345
|
if (!response.purchase) {
|
|
@@ -4502,7 +4512,7 @@ var LicenseService = class {
|
|
|
4502
4512
|
try {
|
|
4503
4513
|
const result = await requestGumroadVerify(workingStored.licenseKey, "refresh");
|
|
4504
4514
|
ensureWithinUseLimit(result);
|
|
4505
|
-
const normalized = normalizeVerificationResult(result);
|
|
4515
|
+
const normalized = normalizeVerificationResult(result, "refresh");
|
|
4506
4516
|
const updated = {
|
|
4507
4517
|
licenseKey: workingStored.licenseKey,
|
|
4508
4518
|
purchaseEmail: normalized.email,
|
|
@@ -4561,7 +4571,7 @@ var LicenseService = class {
|
|
|
4561
4571
|
const digest = import_node_crypto5.default.createHash("sha256").update(trimmed).digest("hex");
|
|
4562
4572
|
const result = await requestGumroadVerify(trimmed, "activation");
|
|
4563
4573
|
ensureWithinUseLimit(result);
|
|
4564
|
-
const normalized = normalizeVerificationResult(result);
|
|
4574
|
+
const normalized = normalizeVerificationResult(result, "activation");
|
|
4565
4575
|
const stored = {
|
|
4566
4576
|
licenseKey: trimmed,
|
|
4567
4577
|
purchaseEmail: normalized.email,
|
|
@@ -4625,7 +4635,7 @@ var import_node_crypto6 = require("crypto");
|
|
|
4625
4635
|
var import_fs = require("fs");
|
|
4626
4636
|
var import_path = __toESM(require("path"), 1);
|
|
4627
4637
|
var import_path2 = require("path");
|
|
4628
|
-
var
|
|
4638
|
+
var import_toml = __toESM(require_toml(), 1);
|
|
4629
4639
|
|
|
4630
4640
|
// ../../packages/contracts/src/profiles/identity.ts
|
|
4631
4641
|
function normalizeValue(value) {
|
|
@@ -4670,6 +4680,10 @@ function resolveProfileIdentityKey(profile) {
|
|
|
4670
4680
|
return profileName ? `profile:${profileName}` : null;
|
|
4671
4681
|
}
|
|
4672
4682
|
function resolveProfileIdentityKeyFromProfile(profile) {
|
|
4683
|
+
const rateLimitKey = normalizeValue(profile.rateLimitKey);
|
|
4684
|
+
if (rateLimitKey) {
|
|
4685
|
+
return rateLimitKey;
|
|
4686
|
+
}
|
|
4673
4687
|
return resolveProfileIdentityKey(profile) ?? `profile:${profile.name}`;
|
|
4674
4688
|
}
|
|
4675
4689
|
|
|
@@ -4679,7 +4693,6 @@ var import_node_readline = __toESM(require("readline"), 1);
|
|
|
4679
4693
|
var import_node_fs3 = require("fs");
|
|
4680
4694
|
var import_node_os2 = __toESM(require("os"), 1);
|
|
4681
4695
|
var import_node_path5 = __toESM(require("path"), 1);
|
|
4682
|
-
var import_toml = __toESM(require_toml(), 1);
|
|
4683
4696
|
|
|
4684
4697
|
// ../../packages/runtime-codex/src/codex/cli.ts
|
|
4685
4698
|
var import_node_fs2 = require("fs");
|
|
@@ -4873,6 +4886,17 @@ function buildCodexCommand(binaryPath, args, env) {
|
|
|
4873
4886
|
};
|
|
4874
4887
|
}
|
|
4875
4888
|
|
|
4889
|
+
// ../../packages/runtime-codex/src/cli/env.ts
|
|
4890
|
+
function buildCodexChildEnv(overrides = {}) {
|
|
4891
|
+
const env = { ...process.env };
|
|
4892
|
+
for (const key of Object.keys(env)) {
|
|
4893
|
+
if (key.startsWith("OPENAI_")) {
|
|
4894
|
+
delete env[key];
|
|
4895
|
+
}
|
|
4896
|
+
}
|
|
4897
|
+
return { ...env, ...overrides };
|
|
4898
|
+
}
|
|
4899
|
+
|
|
4876
4900
|
// ../../packages/shared/src/core/logger.ts
|
|
4877
4901
|
var isTestEnv = process.env.NODE_ENV === "test" || process.env.VITEST === "true" || process.env.VITEST === "1";
|
|
4878
4902
|
function isMocked(fn) {
|
|
@@ -4905,12 +4929,6 @@ var ACTIVATION_MODEL = "gpt-5.1-codex-mini";
|
|
|
4905
4929
|
var MAX_STDERR_CAPTURE_CHARS = 32768;
|
|
4906
4930
|
var REFRESH_TOKEN_REDEEMED_SNIPPET = "refresh token was already used";
|
|
4907
4931
|
var authFileCache = /* @__PURE__ */ new Map();
|
|
4908
|
-
var CODEX_OAUTH_REFRESH_URL = "https://auth.openai.com/oauth/token";
|
|
4909
|
-
var CODEX_OAUTH_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
4910
|
-
var CODEX_OAUTH_REFRESH_MAX_AGE_MS = 8 * 24 * 60 * 60 * 1e3;
|
|
4911
|
-
var CODEX_OAUTH_ACCESS_TOKEN_REFRESH_SKEW_MS = 2 * 60 * 1e3;
|
|
4912
|
-
var CODEX_USAGE_DEFAULT_BASE_URL = "https://chatgpt.com/backend-api";
|
|
4913
|
-
var CODEX_USAGE_TIMEOUT_MS = 3e4;
|
|
4914
4932
|
function isRecord4(value) {
|
|
4915
4933
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
4916
4934
|
}
|
|
@@ -5134,17 +5152,6 @@ function extractJwtIssuedAtMs(token) {
|
|
|
5134
5152
|
}
|
|
5135
5153
|
return issuedAt * 1e3;
|
|
5136
5154
|
}
|
|
5137
|
-
function extractJwtExpiresAtMs(token) {
|
|
5138
|
-
const payload = decodeJwtPayload(token);
|
|
5139
|
-
if (!payload) {
|
|
5140
|
-
return null;
|
|
5141
|
-
}
|
|
5142
|
-
const expiresAt = payload["exp"];
|
|
5143
|
-
if (typeof expiresAt !== "number" || !Number.isFinite(expiresAt)) {
|
|
5144
|
-
return null;
|
|
5145
|
-
}
|
|
5146
|
-
return expiresAt * 1e3;
|
|
5147
|
-
}
|
|
5148
5155
|
function parseAuthRecord(content) {
|
|
5149
5156
|
try {
|
|
5150
5157
|
const parsed = JSON.parse(content);
|
|
@@ -5233,353 +5240,6 @@ async function writeAuthFileCached(filePath, content) {
|
|
|
5233
5240
|
authFileCache.delete(filePath);
|
|
5234
5241
|
}
|
|
5235
5242
|
}
|
|
5236
|
-
function nonEmptyString(value) {
|
|
5237
|
-
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
5238
|
-
}
|
|
5239
|
-
function resolveCodexAuthPathForEnv(envOverride) {
|
|
5240
|
-
return envOverride?.CODEX_HOME ? import_node_path5.default.join(envOverride.CODEX_HOME, "auth.json") : import_node_path5.default.join(
|
|
5241
|
-
envOverride?.HOME ?? process.env.HOME ?? import_node_os2.default.homedir(),
|
|
5242
|
-
".codex",
|
|
5243
|
-
"auth.json"
|
|
5244
|
-
);
|
|
5245
|
-
}
|
|
5246
|
-
function parseCodexOAuthCredentials(content) {
|
|
5247
|
-
const parsed = parseAuthRecord(content);
|
|
5248
|
-
if (!parsed) {
|
|
5249
|
-
return null;
|
|
5250
|
-
}
|
|
5251
|
-
const tokens = isRecord4(parsed.tokens) ? parsed.tokens : {};
|
|
5252
|
-
const accessToken = nonEmptyString(tokens.access_token) ?? nonEmptyString(parsed.access_token);
|
|
5253
|
-
const refreshToken = nonEmptyString(tokens.refresh_token) ?? nonEmptyString(parsed.refresh_token);
|
|
5254
|
-
if (!accessToken && !refreshToken) {
|
|
5255
|
-
return null;
|
|
5256
|
-
}
|
|
5257
|
-
return {
|
|
5258
|
-
accessToken: accessToken ?? "",
|
|
5259
|
-
refreshToken: refreshToken ?? "",
|
|
5260
|
-
idToken: nonEmptyString(tokens.id_token) ?? nonEmptyString(parsed.id_token),
|
|
5261
|
-
accountId: nonEmptyString(tokens.account_id) ?? nonEmptyString(parsed.account_id),
|
|
5262
|
-
lastRefreshMs: parseTimestamp2(tokens.last_refresh) ?? parseTimestamp2(parsed.last_refresh)
|
|
5263
|
-
};
|
|
5264
|
-
}
|
|
5265
|
-
function shouldRefreshCodexOAuthToken(credentials) {
|
|
5266
|
-
if (!credentials.refreshToken) {
|
|
5267
|
-
return false;
|
|
5268
|
-
}
|
|
5269
|
-
const accessExpiresAt = extractJwtExpiresAtMs(credentials.accessToken);
|
|
5270
|
-
if (accessExpiresAt !== null && accessExpiresAt - Date.now() <= CODEX_OAUTH_ACCESS_TOKEN_REFRESH_SKEW_MS) {
|
|
5271
|
-
return true;
|
|
5272
|
-
}
|
|
5273
|
-
if (credentials.lastRefreshMs === null) {
|
|
5274
|
-
return true;
|
|
5275
|
-
}
|
|
5276
|
-
return Date.now() - credentials.lastRefreshMs > CODEX_OAUTH_REFRESH_MAX_AGE_MS;
|
|
5277
|
-
}
|
|
5278
|
-
async function writeCodexOAuthCredentials(authPath, content, credentials) {
|
|
5279
|
-
let json = {};
|
|
5280
|
-
try {
|
|
5281
|
-
const parsed = JSON.parse(content);
|
|
5282
|
-
if (isRecord4(parsed)) {
|
|
5283
|
-
json = { ...parsed };
|
|
5284
|
-
}
|
|
5285
|
-
} catch {
|
|
5286
|
-
json = {};
|
|
5287
|
-
}
|
|
5288
|
-
const existingTokens = isRecord4(json.tokens) ? json.tokens : {};
|
|
5289
|
-
json.tokens = {
|
|
5290
|
-
...existingTokens,
|
|
5291
|
-
access_token: credentials.accessToken,
|
|
5292
|
-
refresh_token: credentials.refreshToken,
|
|
5293
|
-
...credentials.idToken ? { id_token: credentials.idToken } : {},
|
|
5294
|
-
...credentials.accountId ? { account_id: credentials.accountId } : {},
|
|
5295
|
-
last_refresh: (/* @__PURE__ */ new Date()).toISOString()
|
|
5296
|
-
};
|
|
5297
|
-
json.last_refresh = (/* @__PURE__ */ new Date()).toISOString();
|
|
5298
|
-
await writeAuthFileCached(authPath, `${JSON.stringify(json, null, 2)}
|
|
5299
|
-
`);
|
|
5300
|
-
}
|
|
5301
|
-
async function refreshCodexOAuthCredentials(credentials) {
|
|
5302
|
-
if (!credentials.refreshToken) {
|
|
5303
|
-
return credentials;
|
|
5304
|
-
}
|
|
5305
|
-
const response = await fetch(CODEX_OAUTH_REFRESH_URL, {
|
|
5306
|
-
method: "POST",
|
|
5307
|
-
headers: { "Content-Type": "application/json" },
|
|
5308
|
-
signal: AbortSignal.timeout(CODEX_USAGE_TIMEOUT_MS),
|
|
5309
|
-
body: JSON.stringify({
|
|
5310
|
-
client_id: CODEX_OAUTH_CLIENT_ID,
|
|
5311
|
-
grant_type: "refresh_token",
|
|
5312
|
-
refresh_token: credentials.refreshToken,
|
|
5313
|
-
scope: "openid profile email"
|
|
5314
|
-
})
|
|
5315
|
-
});
|
|
5316
|
-
const body = await response.text();
|
|
5317
|
-
if (!response.ok) {
|
|
5318
|
-
let code = "";
|
|
5319
|
-
try {
|
|
5320
|
-
const parsed2 = JSON.parse(body);
|
|
5321
|
-
if (isRecord4(parsed2)) {
|
|
5322
|
-
const error = isRecord4(parsed2.error) ? parsed2.error : {};
|
|
5323
|
-
code = nonEmptyString(error.code) ?? nonEmptyString(parsed2.error) ?? nonEmptyString(parsed2.code) ?? "";
|
|
5324
|
-
}
|
|
5325
|
-
} catch {
|
|
5326
|
-
code = "";
|
|
5327
|
-
}
|
|
5328
|
-
if (code === "refresh_token_reused") {
|
|
5329
|
-
throw new Error("refresh token was already used");
|
|
5330
|
-
}
|
|
5331
|
-
if (code === "refresh_token_expired") {
|
|
5332
|
-
throw new Error("refresh token expired");
|
|
5333
|
-
}
|
|
5334
|
-
if (code === "invalid_grant" || code === "refresh_token_invalidated") {
|
|
5335
|
-
throw new Error("refresh token was revoked");
|
|
5336
|
-
}
|
|
5337
|
-
throw new Error(`Codex OAuth refresh failed HTTP ${response.status}`);
|
|
5338
|
-
}
|
|
5339
|
-
let parsed;
|
|
5340
|
-
try {
|
|
5341
|
-
parsed = JSON.parse(body);
|
|
5342
|
-
} catch {
|
|
5343
|
-
throw new Error("Codex OAuth refresh returned invalid JSON");
|
|
5344
|
-
}
|
|
5345
|
-
if (!isRecord4(parsed)) {
|
|
5346
|
-
throw new Error("Codex OAuth refresh returned invalid data");
|
|
5347
|
-
}
|
|
5348
|
-
return {
|
|
5349
|
-
accessToken: nonEmptyString(parsed.access_token) ?? credentials.accessToken,
|
|
5350
|
-
refreshToken: nonEmptyString(parsed.refresh_token) ?? credentials.refreshToken,
|
|
5351
|
-
idToken: nonEmptyString(parsed.id_token) ?? credentials.idToken,
|
|
5352
|
-
accountId: credentials.accountId,
|
|
5353
|
-
lastRefreshMs: Date.now()
|
|
5354
|
-
};
|
|
5355
|
-
}
|
|
5356
|
-
async function loadCodexConfigContents(envOverride) {
|
|
5357
|
-
const codexHome = envOverride?.CODEX_HOME?.trim();
|
|
5358
|
-
const root = codexHome || import_node_path5.default.join(envOverride?.HOME ?? process.env.HOME ?? import_node_os2.default.homedir(), ".codex");
|
|
5359
|
-
try {
|
|
5360
|
-
return await import_node_fs3.promises.readFile(import_node_path5.default.join(root, "config.toml"), "utf8");
|
|
5361
|
-
} catch {
|
|
5362
|
-
return null;
|
|
5363
|
-
}
|
|
5364
|
-
}
|
|
5365
|
-
function parseChatGPTBaseUrl(contents) {
|
|
5366
|
-
if (!contents) {
|
|
5367
|
-
return CODEX_USAGE_DEFAULT_BASE_URL;
|
|
5368
|
-
}
|
|
5369
|
-
try {
|
|
5370
|
-
const parsed = (0, import_toml.parse)(contents);
|
|
5371
|
-
if (isRecord4(parsed)) {
|
|
5372
|
-
return nonEmptyString(parsed.chatgpt_base_url) ?? CODEX_USAGE_DEFAULT_BASE_URL;
|
|
5373
|
-
}
|
|
5374
|
-
} catch {
|
|
5375
|
-
return CODEX_USAGE_DEFAULT_BASE_URL;
|
|
5376
|
-
}
|
|
5377
|
-
return CODEX_USAGE_DEFAULT_BASE_URL;
|
|
5378
|
-
}
|
|
5379
|
-
async function resolveCodexUsageUrl(envOverride) {
|
|
5380
|
-
let base = parseChatGPTBaseUrl(await loadCodexConfigContents(envOverride));
|
|
5381
|
-
while (base.endsWith("/")) {
|
|
5382
|
-
base = base.slice(0, -1);
|
|
5383
|
-
}
|
|
5384
|
-
if ((base.startsWith("https://chatgpt.com") || base.startsWith("https://chat.openai.com")) && !base.includes("/backend-api")) {
|
|
5385
|
-
base += "/backend-api";
|
|
5386
|
-
}
|
|
5387
|
-
return `${base}${base.includes("/backend-api") ? "/wham/usage" : "/api/codex/usage"}`;
|
|
5388
|
-
}
|
|
5389
|
-
function numberFromUnknown(value) {
|
|
5390
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
5391
|
-
return value;
|
|
5392
|
-
}
|
|
5393
|
-
if (typeof value === "string" && value.trim()) {
|
|
5394
|
-
const parsed = Number(value.trim());
|
|
5395
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
5396
|
-
}
|
|
5397
|
-
return null;
|
|
5398
|
-
}
|
|
5399
|
-
function toOAuthWindow(window) {
|
|
5400
|
-
if (!window) {
|
|
5401
|
-
return void 0;
|
|
5402
|
-
}
|
|
5403
|
-
const usedPercent = numberFromUnknown(window.used_percent);
|
|
5404
|
-
const resetAt = numberFromUnknown(window.reset_at);
|
|
5405
|
-
const limitWindowSeconds = numberFromUnknown(window.limit_window_seconds);
|
|
5406
|
-
if (usedPercent === null && resetAt === null && limitWindowSeconds === null) {
|
|
5407
|
-
return void 0;
|
|
5408
|
-
}
|
|
5409
|
-
const result = {};
|
|
5410
|
-
if (usedPercent !== null) {
|
|
5411
|
-
result.usedPercent = Math.max(0, Math.min(100, usedPercent));
|
|
5412
|
-
}
|
|
5413
|
-
if (limitWindowSeconds !== null) {
|
|
5414
|
-
result.windowMinutes = Math.round(limitWindowSeconds / 60);
|
|
5415
|
-
}
|
|
5416
|
-
if (resetAt !== null) {
|
|
5417
|
-
const resetMs = resetAt > 1e10 ? resetAt : resetAt * 1e3;
|
|
5418
|
-
result.resetsAt = new Date(resetMs).toISOString();
|
|
5419
|
-
result.resetsInSeconds = Math.max(0, Math.round((resetMs - Date.now()) / 1e3));
|
|
5420
|
-
}
|
|
5421
|
-
return result;
|
|
5422
|
-
}
|
|
5423
|
-
function firstNonEmptyString(...values) {
|
|
5424
|
-
for (const value of values) {
|
|
5425
|
-
const text = nonEmptyString(value);
|
|
5426
|
-
if (text) {
|
|
5427
|
-
return text;
|
|
5428
|
-
}
|
|
5429
|
-
}
|
|
5430
|
-
return null;
|
|
5431
|
-
}
|
|
5432
|
-
function slugForRateLimitId(value) {
|
|
5433
|
-
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
5434
|
-
}
|
|
5435
|
-
function isSparkRateLimit(limitName, meteredFeature) {
|
|
5436
|
-
return [limitName, meteredFeature].filter((value) => Boolean(value)).some((value) => value.toLowerCase().includes("spark"));
|
|
5437
|
-
}
|
|
5438
|
-
function sparkWindowIdentity(window, fallback) {
|
|
5439
|
-
const limitWindowSeconds = numberFromUnknown(window.limit_window_seconds);
|
|
5440
|
-
const windowMinutes = limitWindowSeconds !== null ? Math.round(limitWindowSeconds / 60) : null;
|
|
5441
|
-
const kind = windowMinutes !== null && windowMinutes > 0 && windowMinutes <= 6 * 60 ? "five-hour" : windowMinutes !== null && windowMinutes >= 6 * 24 * 60 ? "weekly" : fallback;
|
|
5442
|
-
return kind === "weekly" ? { id: "codex-spark-weekly", label: "Codex Spark Weekly" } : { id: "codex-spark", label: "Codex Spark 5-hour" };
|
|
5443
|
-
}
|
|
5444
|
-
function toExtraRateLimitWindow(args) {
|
|
5445
|
-
const window = toOAuthWindow(args.window);
|
|
5446
|
-
if (!window) {
|
|
5447
|
-
return null;
|
|
5448
|
-
}
|
|
5449
|
-
return {
|
|
5450
|
-
id: args.id,
|
|
5451
|
-
label: args.label,
|
|
5452
|
-
...args.meteredFeature ? { meteredFeature: args.meteredFeature } : {},
|
|
5453
|
-
...window
|
|
5454
|
-
};
|
|
5455
|
-
}
|
|
5456
|
-
function parseExtraRateLimitWindows(additionalRateLimits) {
|
|
5457
|
-
if (!Array.isArray(additionalRateLimits)) {
|
|
5458
|
-
return [];
|
|
5459
|
-
}
|
|
5460
|
-
const usedIds = /* @__PURE__ */ new Set();
|
|
5461
|
-
const extraWindows = [];
|
|
5462
|
-
for (const entry of additionalRateLimits) {
|
|
5463
|
-
if (!isRecord4(entry)) {
|
|
5464
|
-
continue;
|
|
5465
|
-
}
|
|
5466
|
-
const limitName = firstNonEmptyString(entry.limit_name);
|
|
5467
|
-
const meteredFeature = firstNonEmptyString(entry.metered_feature);
|
|
5468
|
-
const rateLimit = isRecord4(entry.rate_limit) ? entry.rate_limit : null;
|
|
5469
|
-
if (!rateLimit) {
|
|
5470
|
-
continue;
|
|
5471
|
-
}
|
|
5472
|
-
const primary = isRecord4(rateLimit.primary_window) ? rateLimit.primary_window : null;
|
|
5473
|
-
const secondary = isRecord4(rateLimit.secondary_window) ? rateLimit.secondary_window : null;
|
|
5474
|
-
if (isSparkRateLimit(limitName, meteredFeature)) {
|
|
5475
|
-
const candidates = [
|
|
5476
|
-
{ window: primary, fallback: "five-hour" },
|
|
5477
|
-
{ window: secondary, fallback: "weekly" }
|
|
5478
|
-
];
|
|
5479
|
-
for (const candidate of candidates) {
|
|
5480
|
-
if (!candidate.window) {
|
|
5481
|
-
continue;
|
|
5482
|
-
}
|
|
5483
|
-
const identity = sparkWindowIdentity(candidate.window, candidate.fallback);
|
|
5484
|
-
if (usedIds.has(identity.id)) {
|
|
5485
|
-
continue;
|
|
5486
|
-
}
|
|
5487
|
-
const extraWindow2 = toExtraRateLimitWindow({
|
|
5488
|
-
...identity,
|
|
5489
|
-
meteredFeature,
|
|
5490
|
-
window: candidate.window
|
|
5491
|
-
});
|
|
5492
|
-
if (extraWindow2) {
|
|
5493
|
-
usedIds.add(identity.id);
|
|
5494
|
-
extraWindows.push(extraWindow2);
|
|
5495
|
-
}
|
|
5496
|
-
}
|
|
5497
|
-
continue;
|
|
5498
|
-
}
|
|
5499
|
-
const idSource = firstNonEmptyString(meteredFeature, limitName);
|
|
5500
|
-
const slug = idSource ? slugForRateLimitId(idSource) : "";
|
|
5501
|
-
if (!slug) {
|
|
5502
|
-
continue;
|
|
5503
|
-
}
|
|
5504
|
-
const id = `codex-${slug}`;
|
|
5505
|
-
if (usedIds.has(id)) {
|
|
5506
|
-
continue;
|
|
5507
|
-
}
|
|
5508
|
-
const extraWindow = toExtraRateLimitWindow({
|
|
5509
|
-
id,
|
|
5510
|
-
label: firstNonEmptyString(limitName, meteredFeature) ?? "Codex extra limit",
|
|
5511
|
-
meteredFeature,
|
|
5512
|
-
window: primary ?? secondary
|
|
5513
|
-
});
|
|
5514
|
-
if (extraWindow) {
|
|
5515
|
-
usedIds.add(id);
|
|
5516
|
-
extraWindows.push(extraWindow);
|
|
5517
|
-
}
|
|
5518
|
-
}
|
|
5519
|
-
return extraWindows;
|
|
5520
|
-
}
|
|
5521
|
-
function parseRateLimitSnapshotFromOAuthUsage(value) {
|
|
5522
|
-
if (!isRecord4(value)) {
|
|
5523
|
-
throw new Error("Codex usage API returned invalid data");
|
|
5524
|
-
}
|
|
5525
|
-
const usage = value;
|
|
5526
|
-
const primary = toOAuthWindow(usage.rate_limit?.primary_window ?? null);
|
|
5527
|
-
const secondary = toOAuthWindow(usage.rate_limit?.secondary_window ?? null);
|
|
5528
|
-
const extraWindows = parseExtraRateLimitWindows(usage.additional_rate_limits);
|
|
5529
|
-
if (!primary && !secondary && extraWindows.length === 0) {
|
|
5530
|
-
return null;
|
|
5531
|
-
}
|
|
5532
|
-
return {
|
|
5533
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5534
|
-
source: "codex-oauth-estimate",
|
|
5535
|
-
...primary ? { primary } : {},
|
|
5536
|
-
...secondary ? { secondary } : {},
|
|
5537
|
-
...extraWindows.length > 0 ? { extraWindows } : {}
|
|
5538
|
-
};
|
|
5539
|
-
}
|
|
5540
|
-
async function fetchRateLimitsViaOAuth(envOverride) {
|
|
5541
|
-
const authPath = resolveCodexAuthPathForEnv(envOverride);
|
|
5542
|
-
const authContent = await readAuthFileCached(authPath);
|
|
5543
|
-
if (!authContent) {
|
|
5544
|
-
return null;
|
|
5545
|
-
}
|
|
5546
|
-
let credentials = parseCodexOAuthCredentials(authContent);
|
|
5547
|
-
if (!credentials) {
|
|
5548
|
-
return null;
|
|
5549
|
-
}
|
|
5550
|
-
if (shouldRefreshCodexOAuthToken(credentials)) {
|
|
5551
|
-
credentials = await refreshCodexOAuthCredentials(credentials);
|
|
5552
|
-
await writeCodexOAuthCredentials(authPath, authContent, credentials);
|
|
5553
|
-
}
|
|
5554
|
-
if (!credentials.accessToken) {
|
|
5555
|
-
return null;
|
|
5556
|
-
}
|
|
5557
|
-
const usageUrl = await resolveCodexUsageUrl(envOverride);
|
|
5558
|
-
const response = await fetch(usageUrl, {
|
|
5559
|
-
method: "GET",
|
|
5560
|
-
headers: {
|
|
5561
|
-
Authorization: `Bearer ${credentials.accessToken}`,
|
|
5562
|
-
Accept: "application/json",
|
|
5563
|
-
"User-Agent": "CodexUse",
|
|
5564
|
-
...credentials.accountId ? { "ChatGPT-Account-Id": credentials.accountId } : {}
|
|
5565
|
-
},
|
|
5566
|
-
signal: AbortSignal.timeout(CODEX_USAGE_TIMEOUT_MS)
|
|
5567
|
-
});
|
|
5568
|
-
const body = await response.text();
|
|
5569
|
-
if (response.status === 401 || response.status === 403) {
|
|
5570
|
-
throw new Error(`Codex OAuth usage failed HTTP ${response.status} (${usageUrl})`);
|
|
5571
|
-
}
|
|
5572
|
-
if (!response.ok) {
|
|
5573
|
-
throw new Error(`Codex usage API failed HTTP ${response.status} (${usageUrl}): ${body.slice(0, 500)}`);
|
|
5574
|
-
}
|
|
5575
|
-
let parsed;
|
|
5576
|
-
try {
|
|
5577
|
-
parsed = JSON.parse(body);
|
|
5578
|
-
} catch {
|
|
5579
|
-
throw new Error("Codex usage API returned invalid JSON");
|
|
5580
|
-
}
|
|
5581
|
-
return parseRateLimitSnapshotFromOAuthUsage(parsed);
|
|
5582
|
-
}
|
|
5583
5243
|
function inferRefreshFailureHint(stderrOutput) {
|
|
5584
5244
|
if (!stderrOutput) {
|
|
5585
5245
|
return null;
|
|
@@ -5715,14 +5375,13 @@ async function fetchRateLimitsViaRpc(envOverride, options = {}) {
|
|
|
5715
5375
|
});
|
|
5716
5376
|
return null;
|
|
5717
5377
|
}
|
|
5718
|
-
const childEnv = {
|
|
5719
|
-
...process.env,
|
|
5378
|
+
const childEnv = buildCodexChildEnv({
|
|
5720
5379
|
...envOverride ?? {},
|
|
5721
5380
|
HOME: tempHome,
|
|
5722
5381
|
CODEX_HOME: tempHome,
|
|
5723
5382
|
CODEX_TELEMETRY_LABEL: "codex-rpc",
|
|
5724
5383
|
ELECTRON_RUN_AS_NODE: "1"
|
|
5725
|
-
};
|
|
5384
|
+
});
|
|
5726
5385
|
const command = buildCodexCommand(
|
|
5727
5386
|
binaryPath,
|
|
5728
5387
|
["-s", "read-only", "-a", "untrusted", "app-server"],
|
|
@@ -5825,14 +5484,13 @@ async function activateResetWindowViaRpc(envOverride, options = {}) {
|
|
|
5825
5484
|
});
|
|
5826
5485
|
return { status: "skipped", reason: "auth-missing" };
|
|
5827
5486
|
}
|
|
5828
|
-
const childEnv = {
|
|
5829
|
-
...process.env,
|
|
5487
|
+
const childEnv = buildCodexChildEnv({
|
|
5830
5488
|
...envOverride ?? {},
|
|
5831
5489
|
HOME: tempHome,
|
|
5832
5490
|
CODEX_HOME: tempHome,
|
|
5833
5491
|
CODEX_TELEMETRY_LABEL: "codex-reset-activation",
|
|
5834
5492
|
ELECTRON_RUN_AS_NODE: "1"
|
|
5835
|
-
};
|
|
5493
|
+
});
|
|
5836
5494
|
const command = buildCodexCommand(
|
|
5837
5495
|
binaryPath,
|
|
5838
5496
|
["-s", "read-only", "-a", "untrusted", "app-server"],
|
|
@@ -6155,6 +5813,7 @@ var ProfileManager = class {
|
|
|
6155
5813
|
displayName: record.displayName ?? null,
|
|
6156
5814
|
data: record.data,
|
|
6157
5815
|
metadata: record.metadata,
|
|
5816
|
+
rateLimitKey: record.rateLimitKey ?? null,
|
|
6158
5817
|
accountId: record.accountId ?? null,
|
|
6159
5818
|
workspaceId: record.workspaceId ?? null,
|
|
6160
5819
|
workspaceName: record.workspaceName ?? null,
|
|
@@ -6172,11 +5831,14 @@ var ProfileManager = class {
|
|
|
6172
5831
|
if (!dataRaw || typeof dataRaw !== "object") {
|
|
6173
5832
|
return null;
|
|
6174
5833
|
}
|
|
6175
|
-
|
|
5834
|
+
const data = cloneJson(dataRaw);
|
|
5835
|
+
const metadata = raw.metadata ? cloneJson(raw.metadata) : void 0;
|
|
5836
|
+
const fallbackRecord = {
|
|
6176
5837
|
name: profileName,
|
|
6177
5838
|
displayName: typeof raw.displayName === "string" ? raw.displayName : null,
|
|
6178
|
-
data
|
|
6179
|
-
metadata
|
|
5839
|
+
data,
|
|
5840
|
+
metadata,
|
|
5841
|
+
rateLimitKey: typeof raw.rateLimitKey === "string" ? raw.rateLimitKey : null,
|
|
6180
5842
|
accountId: typeof raw.accountId === "string" ? raw.accountId : null,
|
|
6181
5843
|
workspaceId: typeof raw.workspaceId === "string" ? raw.workspaceId : null,
|
|
6182
5844
|
workspaceName: typeof raw.workspaceName === "string" ? raw.workspaceName : null,
|
|
@@ -6185,6 +5847,10 @@ var ProfileManager = class {
|
|
|
6185
5847
|
createdAt: typeof raw.createdAt === "string" ? raw.createdAt : null,
|
|
6186
5848
|
updatedAt: typeof raw.updatedAt === "string" ? raw.updatedAt : null
|
|
6187
5849
|
};
|
|
5850
|
+
return {
|
|
5851
|
+
...fallbackRecord,
|
|
5852
|
+
rateLimitKey: fallbackRecord.rateLimitKey ?? this.resolveProfileIdentityFromRecord(fallbackRecord)
|
|
5853
|
+
};
|
|
6188
5854
|
}
|
|
6189
5855
|
async readProfilesStateSource() {
|
|
6190
5856
|
const state = await getAppState();
|
|
@@ -6234,10 +5900,11 @@ var ProfileManager = class {
|
|
|
6234
5900
|
}
|
|
6235
5901
|
rateLimitSnapshotKeysForRecord(record) {
|
|
6236
5902
|
return Array.from(
|
|
6237
|
-
|
|
5903
|
+
new Set([
|
|
6238
5904
|
this.resolveProfileIdentityFromRecord(record),
|
|
5905
|
+
record.rateLimitKey,
|
|
6239
5906
|
resolveFallbackAccountKey(record.name)
|
|
6240
|
-
])
|
|
5907
|
+
].filter((key) => Boolean(key)))
|
|
6241
5908
|
);
|
|
6242
5909
|
}
|
|
6243
5910
|
rateLimitSnapshotKeysForStateMap(map) {
|
|
@@ -6950,6 +6617,7 @@ var ProfileManager = class {
|
|
|
6950
6617
|
displayName,
|
|
6951
6618
|
data,
|
|
6952
6619
|
metadata: resolvedMetadata,
|
|
6620
|
+
rateLimitKey: existingRecord?.rateLimitKey ?? this.resolveProfileIdentityFromData(resolvedName, data, resolvedMetadata),
|
|
6953
6621
|
accountId,
|
|
6954
6622
|
workspaceId: data.workspace_id ?? workspaceId,
|
|
6955
6623
|
workspaceName: data.workspace_name ?? workspaceName,
|
|
@@ -6968,6 +6636,7 @@ var ProfileManager = class {
|
|
|
6968
6636
|
createdAt: row.createdAt ?? void 0,
|
|
6969
6637
|
authMethod: row.authMethod ?? void 0,
|
|
6970
6638
|
accountId: row.accountId ?? void 0,
|
|
6639
|
+
rateLimitKey: row.rateLimitKey ?? void 0,
|
|
6971
6640
|
workspaceId: row.workspaceId ?? void 0,
|
|
6972
6641
|
workspaceName: row.workspaceName ?? void 0,
|
|
6973
6642
|
metadata: row.metadata
|
|
@@ -7004,6 +6673,7 @@ var ProfileManager = class {
|
|
|
7004
6673
|
name,
|
|
7005
6674
|
displayName: fallback?.displayName ?? name,
|
|
7006
6675
|
isValid: Boolean(data && Object.keys(data).length > 0),
|
|
6676
|
+
rateLimitKey: fallback?.rateLimitKey,
|
|
7007
6677
|
accountId,
|
|
7008
6678
|
workspaceId,
|
|
7009
6679
|
workspaceName,
|
|
@@ -7322,7 +6992,7 @@ var ProfileManager = class {
|
|
|
7322
6992
|
}
|
|
7323
6993
|
let parsed;
|
|
7324
6994
|
try {
|
|
7325
|
-
parsed = (0,
|
|
6995
|
+
parsed = (0, import_toml.parse)(raw);
|
|
7326
6996
|
} catch (error) {
|
|
7327
6997
|
logWarn(`Failed to parse config.toml for profile home '${profileHome}':`, error);
|
|
7328
6998
|
return;
|
|
@@ -7332,7 +7002,7 @@ var ProfileManager = class {
|
|
|
7332
7002
|
}
|
|
7333
7003
|
delete parsed["model_reasoning_effort"];
|
|
7334
7004
|
const sanitized = this.ensureTrailingNewline(
|
|
7335
|
-
(0,
|
|
7005
|
+
(0, import_toml.stringify)(parsed)
|
|
7336
7006
|
);
|
|
7337
7007
|
try {
|
|
7338
7008
|
await import_fs.promises.writeFile(configPath, sanitized, "utf8");
|
|
@@ -7395,11 +7065,10 @@ var ProfileManager = class {
|
|
|
7395
7065
|
const codexFormat = this.convertToCodexFormat(profileData);
|
|
7396
7066
|
const profileHome = await this.prepareProfileHome(profileName, codexFormat);
|
|
7397
7067
|
const authPath = import_path.default.join(profileHome, "auth.json");
|
|
7398
|
-
const envOverrides = {
|
|
7399
|
-
...process.env,
|
|
7068
|
+
const envOverrides = buildCodexChildEnv({
|
|
7400
7069
|
HOME: profileHome,
|
|
7401
7070
|
CODEX_HOME: profileHome
|
|
7402
|
-
};
|
|
7071
|
+
});
|
|
7403
7072
|
try {
|
|
7404
7073
|
return await action(envOverrides);
|
|
7405
7074
|
} finally {
|
|
@@ -7449,11 +7118,10 @@ var ProfileManager = class {
|
|
|
7449
7118
|
const profileHome = await this.prepareProfileHome(profileName, codexFormat);
|
|
7450
7119
|
return {
|
|
7451
7120
|
profileHome,
|
|
7452
|
-
env: {
|
|
7453
|
-
...process.env,
|
|
7121
|
+
env: buildCodexChildEnv({
|
|
7454
7122
|
HOME: profileHome,
|
|
7455
7123
|
CODEX_HOME: profileHome
|
|
7456
|
-
}
|
|
7124
|
+
})
|
|
7457
7125
|
};
|
|
7458
7126
|
})
|
|
7459
7127
|
);
|
|
@@ -7696,16 +7364,7 @@ var ProfileManager = class {
|
|
|
7696
7364
|
profileName,
|
|
7697
7365
|
() => this.runWithPreparedProfileHome(
|
|
7698
7366
|
profileName,
|
|
7699
|
-
|
|
7700
|
-
try {
|
|
7701
|
-
const oauthSnapshot = await fetchRateLimitsViaOAuth(env);
|
|
7702
|
-
if (oauthSnapshot) {
|
|
7703
|
-
return oauthSnapshot;
|
|
7704
|
-
}
|
|
7705
|
-
} catch {
|
|
7706
|
-
}
|
|
7707
|
-
return fetchRateLimitsViaRpc(env, { codexPath: options.codexPath });
|
|
7708
|
-
},
|
|
7367
|
+
(env) => fetchRateLimitsViaRpc(env, { codexPath: options.codexPath }),
|
|
7709
7368
|
{ syncFromActiveAuthBeforeAction: false }
|
|
7710
7369
|
)
|
|
7711
7370
|
);
|
|
@@ -8049,6 +7708,7 @@ var ProfileManager = class {
|
|
|
8049
7708
|
displayName: typeof candidate.displayName === "string" ? candidate.displayName : null,
|
|
8050
7709
|
data,
|
|
8051
7710
|
metadata,
|
|
7711
|
+
rateLimitKey: this.resolveProfileIdentityFromData(name, data, metadata),
|
|
8052
7712
|
accountId: typeof candidate.accountId === "string" ? candidate.accountId : null,
|
|
8053
7713
|
workspaceId: typeof candidate.workspaceId === "string" ? candidate.workspaceId : null,
|
|
8054
7714
|
workspaceName: typeof candidate.workspaceName === "string" ? candidate.workspaceName : null,
|
|
@@ -9335,10 +8995,6 @@ function snapshotResetSeconds(snapshot) {
|
|
|
9335
8995
|
].filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
9336
8996
|
return values.length > 0 ? Math.min(...values) : null;
|
|
9337
8997
|
}
|
|
9338
|
-
function fallbackUsedPercent(profile) {
|
|
9339
|
-
const cached = maxUsedPercent(profile.rateLimit ?? null);
|
|
9340
|
-
return typeof cached === "number" && Number.isFinite(cached) ? cached : null;
|
|
9341
|
-
}
|
|
9342
8998
|
function compareCandidates(left, right) {
|
|
9343
8999
|
const leftUsage = left.usedPercent ?? Number.POSITIVE_INFINITY;
|
|
9344
9000
|
const rightUsage = right.usedPercent ?? Number.POSITIVE_INFINITY;
|
|
@@ -9396,16 +9052,17 @@ async function selectBestProfile(manager, profiles, codexPath) {
|
|
|
9396
9052
|
}
|
|
9397
9053
|
try {
|
|
9398
9054
|
const snapshot = await manager.readLiveRateLimits(profile.name, { codexPath });
|
|
9055
|
+
const usedPercent = maxUsedPercent(snapshot);
|
|
9399
9056
|
candidates.push({
|
|
9400
9057
|
profile,
|
|
9401
|
-
usedPercent: typeof
|
|
9058
|
+
usedPercent: typeof usedPercent === "number" ? usedPercent : null,
|
|
9402
9059
|
resetSeconds: snapshotResetSeconds(snapshot)
|
|
9403
9060
|
});
|
|
9404
9061
|
} catch {
|
|
9405
9062
|
candidates.push({
|
|
9406
9063
|
profile,
|
|
9407
|
-
usedPercent:
|
|
9408
|
-
resetSeconds:
|
|
9064
|
+
usedPercent: null,
|
|
9065
|
+
resetSeconds: null
|
|
9409
9066
|
});
|
|
9410
9067
|
}
|
|
9411
9068
|
}
|
|
@@ -9540,6 +9197,9 @@ Picks the healthiest saved profile, then runs Codex. Auto-run requires Pro or an
|
|
|
9540
9197
|
if (!best) {
|
|
9541
9198
|
throw new Error("No valid saved profiles found. Add one with `codexuse profile add <name>`.");
|
|
9542
9199
|
}
|
|
9200
|
+
if (best.usedPercent === null) {
|
|
9201
|
+
throw new Error("No live rate-limit usage found. Skipping best profile run.");
|
|
9202
|
+
}
|
|
9543
9203
|
const dryRun = hasFlag(flags, "--dry-run");
|
|
9544
9204
|
const summary = `${best.profile.name} (${formatUsagePercent(best.usedPercent)} used)`;
|
|
9545
9205
|
if (dryRun) {
|
|
@@ -9611,6 +9271,7 @@ var import_node_path10 = __toESM(require("path"), 1);
|
|
|
9611
9271
|
var import_node_fs6 = require("fs");
|
|
9612
9272
|
var import_node_path9 = __toESM(require("path"), 1);
|
|
9613
9273
|
var ROLLOUT_DIRS = ["sessions", "archived_sessions"];
|
|
9274
|
+
var SQLITE_EXTENSIONS = /* @__PURE__ */ new Set([".db", ".sqlite", ".sqlite3"]);
|
|
9614
9275
|
function isRecord5(value) {
|
|
9615
9276
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9616
9277
|
}
|
|
@@ -9729,8 +9390,91 @@ function resolveRolloutPath(profileHome, rolloutPath) {
|
|
|
9729
9390
|
}
|
|
9730
9391
|
return import_node_path9.default.isAbsolute(rolloutPath) ? rolloutPath : import_node_path9.default.join(profileHome, rolloutPath);
|
|
9731
9392
|
}
|
|
9732
|
-
async function
|
|
9733
|
-
const
|
|
9393
|
+
async function collectSessionDatabasePaths(profileHome) {
|
|
9394
|
+
const paths = [];
|
|
9395
|
+
const sqliteDir = import_node_path9.default.join(profileHome, "sqlite");
|
|
9396
|
+
try {
|
|
9397
|
+
const entries = await import_node_fs6.promises.readdir(sqliteDir, {
|
|
9398
|
+
withFileTypes: true,
|
|
9399
|
+
encoding: "utf8"
|
|
9400
|
+
});
|
|
9401
|
+
for (const entry of entries) {
|
|
9402
|
+
if (!entry.isFile()) {
|
|
9403
|
+
continue;
|
|
9404
|
+
}
|
|
9405
|
+
const entryName = String(entry.name);
|
|
9406
|
+
if (SQLITE_EXTENSIONS.has(import_node_path9.default.extname(entryName))) {
|
|
9407
|
+
paths.push(import_node_path9.default.join(sqliteDir, entryName));
|
|
9408
|
+
}
|
|
9409
|
+
}
|
|
9410
|
+
} catch {
|
|
9411
|
+
}
|
|
9412
|
+
paths.sort((left, right) => {
|
|
9413
|
+
const leftName = import_node_path9.default.basename(left);
|
|
9414
|
+
const rightName = import_node_path9.default.basename(right);
|
|
9415
|
+
if (leftName === "codex-dev.db" && rightName !== "codex-dev.db") return -1;
|
|
9416
|
+
if (rightName === "codex-dev.db" && leftName !== "codex-dev.db") return 1;
|
|
9417
|
+
return leftName.localeCompare(rightName);
|
|
9418
|
+
});
|
|
9419
|
+
const legacy = import_node_path9.default.join(profileHome, "state_5.sqlite");
|
|
9420
|
+
if (!paths.includes(legacy)) {
|
|
9421
|
+
paths.push(legacy);
|
|
9422
|
+
}
|
|
9423
|
+
return paths;
|
|
9424
|
+
}
|
|
9425
|
+
function tableColumns(db, table) {
|
|
9426
|
+
try {
|
|
9427
|
+
return new Set(
|
|
9428
|
+
db.prepare(`PRAGMA table_info(${table})`).all().map((row) => isRecord5(row) ? recordString(row.name) : null).filter((name) => Boolean(name))
|
|
9429
|
+
);
|
|
9430
|
+
} catch {
|
|
9431
|
+
return /* @__PURE__ */ new Set();
|
|
9432
|
+
}
|
|
9433
|
+
}
|
|
9434
|
+
function firstColumn(columns, names) {
|
|
9435
|
+
return names.find((name) => columns.has(name)) ?? null;
|
|
9436
|
+
}
|
|
9437
|
+
function sqlColumnOrNull(column, alias) {
|
|
9438
|
+
return column ? `${column} AS ${alias}` : `NULL AS ${alias}`;
|
|
9439
|
+
}
|
|
9440
|
+
function queryThreadRecordFromTable(db, profileHome, threadId, config) {
|
|
9441
|
+
const columns = tableColumns(db, config.table);
|
|
9442
|
+
const idColumn = firstColumn(columns, config.id);
|
|
9443
|
+
if (!idColumn) {
|
|
9444
|
+
return null;
|
|
9445
|
+
}
|
|
9446
|
+
const variants = threadIdVariants(threadId);
|
|
9447
|
+
const placeholders = variants.map(() => "?").join(", ");
|
|
9448
|
+
const orderByColumn = firstColumn(columns, [
|
|
9449
|
+
"updated_at_ms",
|
|
9450
|
+
"updated_at",
|
|
9451
|
+
"created_at_ms",
|
|
9452
|
+
"created_at"
|
|
9453
|
+
]);
|
|
9454
|
+
const select = [
|
|
9455
|
+
sqlColumnOrNull(firstColumn(columns, config.rolloutPath), "rollout_path"),
|
|
9456
|
+
sqlColumnOrNull(firstColumn(columns, config.title), "title"),
|
|
9457
|
+
sqlColumnOrNull(firstColumn(columns, config.cwd), "cwd"),
|
|
9458
|
+
sqlColumnOrNull(firstColumn(columns, ["updated_at"]), "updated_at"),
|
|
9459
|
+
sqlColumnOrNull(firstColumn(columns, ["updated_at_ms"]), "updated_at_ms"),
|
|
9460
|
+
sqlColumnOrNull(firstColumn(columns, ["created_at_ms", "created_at"]), "created_at_ms")
|
|
9461
|
+
].join(", ");
|
|
9462
|
+
const orderBy = orderByColumn ? ` ORDER BY ${orderByColumn} DESC, ${idColumn} DESC` : ` ORDER BY ${idColumn} DESC`;
|
|
9463
|
+
const row = db.prepare(
|
|
9464
|
+
`SELECT ${select} FROM ${config.table} WHERE ${idColumn} IN (${placeholders})${orderBy} LIMIT 1`
|
|
9465
|
+
).all(...variants).find(isRecord5);
|
|
9466
|
+
if (!row) {
|
|
9467
|
+
return null;
|
|
9468
|
+
}
|
|
9469
|
+
return {
|
|
9470
|
+
rolloutPath: resolveRolloutPath(profileHome, recordString(row.rollout_path)),
|
|
9471
|
+
title: recordString(row.title),
|
|
9472
|
+
cwd: recordString(row.cwd),
|
|
9473
|
+
updatedAt: recordString(row.updated_at),
|
|
9474
|
+
updatedAtMs: normalizeTimestampMs(row.updated_at_ms) ?? normalizeTimestampMs(row.updated_at) ?? normalizeTimestampMs(row.created_at_ms)
|
|
9475
|
+
};
|
|
9476
|
+
}
|
|
9477
|
+
async function readThreadRecordFromDb(profileHome, dbPath, threadId) {
|
|
9734
9478
|
try {
|
|
9735
9479
|
await import_node_fs6.promises.access(dbPath);
|
|
9736
9480
|
} catch {
|
|
@@ -9739,42 +9483,28 @@ async function readThreadRecordFromStateDb(profileHome, threadId) {
|
|
|
9739
9483
|
let db = null;
|
|
9740
9484
|
try {
|
|
9741
9485
|
db = await openReadonlyDatabase(dbPath);
|
|
9742
|
-
const
|
|
9743
|
-
|
|
9744
|
-
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
9748
|
-
|
|
9749
|
-
|
|
9750
|
-
|
|
9751
|
-
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
`SELECT ${select} FROM threads WHERE ${idColumn} IN (${placeholders})${orderBy} LIMIT 1`
|
|
9763
|
-
).all(...variants);
|
|
9764
|
-
const row = rows.find(isRecord5);
|
|
9765
|
-
if (!row) {
|
|
9766
|
-
return null;
|
|
9486
|
+
for (const config of [
|
|
9487
|
+
{
|
|
9488
|
+
table: "threads",
|
|
9489
|
+
id: ["id", "thread_id"],
|
|
9490
|
+
title: ["title", "thread_title"],
|
|
9491
|
+
cwd: ["cwd", "source_cwd"],
|
|
9492
|
+
rolloutPath: ["rollout_path"]
|
|
9493
|
+
},
|
|
9494
|
+
{
|
|
9495
|
+
table: "automation_runs",
|
|
9496
|
+
id: ["thread_id", "id"],
|
|
9497
|
+
title: ["thread_title", "title", "inbox_title"],
|
|
9498
|
+
cwd: ["source_cwd", "cwd"],
|
|
9499
|
+
rolloutPath: []
|
|
9500
|
+
}
|
|
9501
|
+
]) {
|
|
9502
|
+
const record = queryThreadRecordFromTable(db, profileHome, threadId, config);
|
|
9503
|
+
if (record) {
|
|
9504
|
+
return record;
|
|
9505
|
+
}
|
|
9767
9506
|
}
|
|
9768
|
-
return
|
|
9769
|
-
rolloutPath: resolveRolloutPath(
|
|
9770
|
-
profileHome,
|
|
9771
|
-
recordString(row.rollout_path)
|
|
9772
|
-
),
|
|
9773
|
-
title: recordString(row.title),
|
|
9774
|
-
cwd: recordString(row.cwd),
|
|
9775
|
-
updatedAt: recordString(row.updated_at),
|
|
9776
|
-
updatedAtMs: normalizeTimestampMs(row.updated_at_ms) ?? normalizeTimestampMs(row.updated_at) ?? normalizeTimestampMs(row.created_at_ms)
|
|
9777
|
-
};
|
|
9507
|
+
return null;
|
|
9778
9508
|
} catch {
|
|
9779
9509
|
return null;
|
|
9780
9510
|
} finally {
|
|
@@ -9782,9 +9512,16 @@ async function readThreadRecordFromStateDb(profileHome, threadId) {
|
|
|
9782
9512
|
}
|
|
9783
9513
|
}
|
|
9784
9514
|
async function findOfficialCodexThreadRecord(profileHome, threadId) {
|
|
9785
|
-
const
|
|
9786
|
-
|
|
9787
|
-
|
|
9515
|
+
const records = [];
|
|
9516
|
+
for (const dbPath of await collectSessionDatabasePaths(profileHome)) {
|
|
9517
|
+
const stateRecord = await readThreadRecordFromDb(profileHome, dbPath, threadId);
|
|
9518
|
+
if (stateRecord) {
|
|
9519
|
+
records.push(stateRecord);
|
|
9520
|
+
}
|
|
9521
|
+
}
|
|
9522
|
+
if (records.length > 0) {
|
|
9523
|
+
records.sort((left, right) => (right.updatedAtMs ?? 0) - (left.updatedAtMs ?? 0));
|
|
9524
|
+
return records[0] ?? null;
|
|
9788
9525
|
}
|
|
9789
9526
|
const rolloutMatch = await findRolloutFileByScan(profileHome, threadId);
|
|
9790
9527
|
if (!rolloutMatch) {
|
|
@@ -10150,13 +9887,14 @@ async function readCdpTargets(port) {
|
|
|
10150
9887
|
}
|
|
10151
9888
|
throw lastError instanceof Error ? lastError : new Error("cdp-list-failed");
|
|
10152
9889
|
}
|
|
10153
|
-
function pickCodexCdpTarget(targets) {
|
|
9890
|
+
function pickCodexCdpTarget(targets, options = {}) {
|
|
10154
9891
|
const pages = targets.filter(
|
|
10155
9892
|
(target) => target.webSocketDebuggerUrl && (target.type === "page" || target.type === "webview" || !target.type)
|
|
10156
9893
|
);
|
|
10157
|
-
|
|
9894
|
+
const codexPage = pages.find(
|
|
10158
9895
|
(target) => `${target.title ?? ""} ${target.url ?? ""}`.toLowerCase().includes("codex")
|
|
10159
|
-
) ??
|
|
9896
|
+
) ?? null;
|
|
9897
|
+
return codexPage ?? (options.allowAnyPage === true ? pages[0] ?? null : null);
|
|
10160
9898
|
}
|
|
10161
9899
|
function buildCdpDevToolsUrl(port, target) {
|
|
10162
9900
|
const frontendUrl = target.devtoolsFrontendUrl?.trim();
|
|
@@ -10500,6 +10238,8 @@ function buildInCodexStatusOverlayCssRules() {
|
|
|
10500
10238
|
`${chip} .codexuse-handoff-hide{display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;margin-right:3px;border-radius:50%;color:var(--cu-muted);cursor:pointer;font-size:12px;line-height:1;}`,
|
|
10501
10239
|
`${chip} .codexuse-handoff-hide:hover{background:var(--cu-border);color:var(--cu-fg,#ececf1);}`,
|
|
10502
10240
|
`body>[data-radix-popper-content-wrapper],body>[data-floating-ui-portal]{z-index:2147483004!important;}`,
|
|
10241
|
+
// Official Codex marks its titlebar draggable; injected controls must opt out.
|
|
10242
|
+
`${id},${id} *,${chip},${chip} *,${picker},${picker} *{-webkit-app-region:no-drag;}`,
|
|
10503
10243
|
// Hand-off account picker is a standalone body child (not inside the pill),
|
|
10504
10244
|
// so the pill-scoped popover rules don't reach it — give it its own palette
|
|
10505
10245
|
// + popover styling, mirroring the chip.
|
|
@@ -10881,6 +10621,7 @@ function createBridgeApplyQolExpression(settings) {
|
|
|
10881
10621
|
const overlayPosKey = "codexuse:overlay:pos";
|
|
10882
10622
|
const handoffHiddenKey = "codexuse:handoff:hidden";
|
|
10883
10623
|
const handoffPosKey = "codexuse:handoff:pos:v2";
|
|
10624
|
+
const defaultPosKey = "codexuse:overlay:top-default:v1";
|
|
10884
10625
|
const readOverlayStore = (key) => {
|
|
10885
10626
|
try {
|
|
10886
10627
|
return window.localStorage.getItem(key);
|
|
@@ -10975,8 +10716,8 @@ function createBridgeApplyQolExpression(settings) {
|
|
|
10975
10716
|
};
|
|
10976
10717
|
const placeInitialOverlayPosition = (pill) => {
|
|
10977
10718
|
const rect = pill.getBoundingClientRect();
|
|
10978
|
-
const x = Math.
|
|
10979
|
-
const y = Math.max(
|
|
10719
|
+
const x = Math.max(8, window.innerWidth - rect.width - 32);
|
|
10720
|
+
const y = Math.max(96, Math.min(132, Math.round(window.innerHeight * 0.12)));
|
|
10980
10721
|
placeOverlay(pill, x, y);
|
|
10981
10722
|
};
|
|
10982
10723
|
const rectsOverlap = (a, b, gap = 0) =>
|
|
@@ -10990,30 +10731,17 @@ function createBridgeApplyQolExpression(settings) {
|
|
|
10990
10731
|
right: pos.x + rect.width,
|
|
10991
10732
|
bottom: pos.y + rect.height
|
|
10992
10733
|
});
|
|
10993
|
-
const placeInitialHandoffPosition = (chip
|
|
10734
|
+
const placeInitialHandoffPosition = (chip) => {
|
|
10994
10735
|
const rect = chip.getBoundingClientRect();
|
|
10995
|
-
|
|
10996
|
-
|
|
10997
|
-
const middleY = Math.round(anchorRect.top + (anchorRect.height - rect.height) / 2);
|
|
10998
|
-
const candidates = [
|
|
10999
|
-
{ x: anchorRect.right + gap, y: middleY },
|
|
11000
|
-
{ x: anchorRect.left - rect.width - gap, y: middleY },
|
|
11001
|
-
{ x: anchorRect.right - rect.width, y: anchorRect.top - rect.height - gap },
|
|
11002
|
-
{ x: anchorRect.left, y: anchorRect.top - rect.height - gap },
|
|
11003
|
-
{ x: anchorRect.right - rect.width, y: anchorRect.bottom + gap }
|
|
11004
|
-
];
|
|
11005
|
-
for (const candidate of candidates) {
|
|
11006
|
-
const next = clampOverlayXY(chip, candidate.x, candidate.y);
|
|
11007
|
-
if (!rectsOverlap(positionedRect(rect, next), anchorRect, 6)) {
|
|
11008
|
-
placeOverlay(chip, next.x, next.y);
|
|
11009
|
-
return;
|
|
11010
|
-
}
|
|
11011
|
-
}
|
|
11012
|
-
}
|
|
11013
|
-
const x = Math.max(8, window.innerWidth - rect.width - 16);
|
|
11014
|
-
const y = Math.max(64, Math.min(128, Math.round(window.innerHeight * 0.14)));
|
|
10736
|
+
const x = Math.round((window.innerWidth - rect.width) / 2);
|
|
10737
|
+
const y = 14;
|
|
11015
10738
|
placeOverlay(chip, x, y);
|
|
11016
10739
|
};
|
|
10740
|
+
if (readOverlayStore(defaultPosKey) !== "1") {
|
|
10741
|
+
writeOverlayStore(overlayPosKey, null);
|
|
10742
|
+
writeOverlayStore(handoffPosKey, null);
|
|
10743
|
+
writeOverlayStore(defaultPosKey, "1");
|
|
10744
|
+
}
|
|
11017
10745
|
const setOverlayMessage = (value) => {
|
|
11018
10746
|
const node = document.querySelector("#" + statusId + " [data-codexuse-action-status]");
|
|
11019
10747
|
if (node) node.textContent = value || "";
|
|
@@ -11143,7 +10871,8 @@ function createBridgeApplyQolExpression(settings) {
|
|
|
11143
10871
|
renderHandoff();
|
|
11144
10872
|
}, true);
|
|
11145
10873
|
document.body.appendChild(pill);
|
|
11146
|
-
applyStoredOverlayPosition(pill);
|
|
10874
|
+
if (hasStoredPosition) applyStoredOverlayPosition(pill);
|
|
10875
|
+
else placeInitialOverlayPosition(pill);
|
|
11147
10876
|
return true;
|
|
11148
10877
|
}
|
|
11149
10878
|
pill.dataset.open = currentAutoRollDecision || wasOpen || shouldShowIntro ? "true" : "false";
|
|
@@ -11448,6 +11177,8 @@ function createBridgeApplyQolExpression(settings) {
|
|
|
11448
11177
|
if (shouldShowIntro) {
|
|
11449
11178
|
placeInitialOverlayPosition(pill);
|
|
11450
11179
|
writeOverlayStore(overlayIntroKey, "1");
|
|
11180
|
+
} else if (!hasStoredPosition) {
|
|
11181
|
+
placeInitialOverlayPosition(pill);
|
|
11451
11182
|
} else {
|
|
11452
11183
|
applyStoredOverlayPosition(pill);
|
|
11453
11184
|
}
|
|
@@ -11692,18 +11423,18 @@ function createBridgeApplyQolExpression(settings) {
|
|
|
11692
11423
|
const next = clampOverlayXY(chip, pos.x, pos.y);
|
|
11693
11424
|
const chipRect = chip.getBoundingClientRect();
|
|
11694
11425
|
if (rectsOverlap(positionedRect(chipRect, next), rect, 6)) {
|
|
11695
|
-
placeInitialHandoffPosition(chip
|
|
11426
|
+
placeInitialHandoffPosition(chip);
|
|
11696
11427
|
} else {
|
|
11697
11428
|
placeOverlay(chip, next.x, next.y);
|
|
11698
11429
|
}
|
|
11699
11430
|
} else {
|
|
11700
|
-
placeInitialHandoffPosition(chip
|
|
11431
|
+
placeInitialHandoffPosition(chip);
|
|
11701
11432
|
}
|
|
11702
11433
|
} catch {
|
|
11703
|
-
placeInitialHandoffPosition(chip
|
|
11434
|
+
placeInitialHandoffPosition(chip);
|
|
11704
11435
|
}
|
|
11705
11436
|
} else {
|
|
11706
|
-
placeInitialHandoffPosition(chip
|
|
11437
|
+
placeInitialHandoffPosition(chip);
|
|
11707
11438
|
}
|
|
11708
11439
|
if (wasOpen) openPicker();
|
|
11709
11440
|
reportHandoff("rendered");
|
|
@@ -12055,11 +11786,23 @@ function createBridgeApplyPowerExpression(settings, settingsExpression) {
|
|
|
12055
11786
|
|| typeof item.name === "string"
|
|
12056
11787
|
)
|
|
12057
11788
|
);
|
|
12058
|
-
const
|
|
11789
|
+
const modelLabelLooksKnown = (value) =>
|
|
11790
|
+
typeof value === "string" && /(?:gpt|codex|chatgpt|claude|gemini|llama|mistral|qwen|deepseek|grok|davinci|\\bo[1-9]\\b)/i.test(value);
|
|
11791
|
+
const objectArrayLooksModelLike = (items) =>
|
|
11792
|
+
objectArrayLooksPatchable(items)
|
|
11793
|
+
&& items.some((item) =>
|
|
11794
|
+
modelLabelLooksKnown(item.model)
|
|
11795
|
+
|| modelLabelLooksKnown(item.id)
|
|
11796
|
+
|| modelLabelLooksKnown(item.slug)
|
|
11797
|
+
|| modelLabelLooksKnown(item.name)
|
|
11798
|
+
|| modelLabelLooksKnown(item.displayName)
|
|
11799
|
+
|| modelLabelLooksKnown(item.title)
|
|
11800
|
+
);
|
|
11801
|
+
const patchModelArray = (items, allowEmpty = false, requireModelLike = false) => {
|
|
12059
11802
|
if (!Array.isArray(items)) return false;
|
|
12060
11803
|
let localChanged = false;
|
|
12061
|
-
unhideArray(items);
|
|
12062
11804
|
if (stringArrayLooksPatchable(items)) {
|
|
11805
|
+
if (requireModelLike && !items.some(modelLabelLooksKnown)) return false;
|
|
12063
11806
|
for (const model of modelWhitelistModels) {
|
|
12064
11807
|
if (!items.includes(model)) {
|
|
12065
11808
|
items.push(model);
|
|
@@ -12068,7 +11811,8 @@ function createBridgeApplyPowerExpression(settings, settingsExpression) {
|
|
|
12068
11811
|
}
|
|
12069
11812
|
return localChanged;
|
|
12070
11813
|
}
|
|
12071
|
-
if (objectArrayLooksPatchable(items, allowEmpty)) {
|
|
11814
|
+
if (objectArrayLooksPatchable(items, allowEmpty) && (!requireModelLike || allowEmpty || objectArrayLooksModelLike(items))) {
|
|
11815
|
+
unhideArray(items);
|
|
12072
11816
|
const existing = new Set();
|
|
12073
11817
|
for (const item of items) {
|
|
12074
11818
|
existing.add(String(item.model || item.id || item.slug || item.name || ""));
|
|
@@ -12083,8 +11827,8 @@ function createBridgeApplyPowerExpression(settings, settingsExpression) {
|
|
|
12083
11827
|
return localChanged;
|
|
12084
11828
|
};
|
|
12085
11829
|
if (patchModelArray(value.models, "defaultModel" in value || "availableModels" in value)) changed = true;
|
|
12086
|
-
if (patchModelArray(value.data)) changed = true;
|
|
12087
|
-
if (patchModelArray(value.result)) changed = true;
|
|
11830
|
+
if (patchModelArray(value.data, false, true)) changed = true;
|
|
11831
|
+
if (patchModelArray(value.result, false, true)) changed = true;
|
|
12088
11832
|
if (patchModelArray(value.availableModels, true)) changed = true;
|
|
12089
11833
|
if (patchModelArray(value.available_models, true)) changed = true;
|
|
12090
11834
|
if (value.available_models instanceof Set) {
|
|
@@ -12201,11 +11945,23 @@ function createBridgeApplyPowerExpression(settings, settingsExpression) {
|
|
|
12201
11945
|
return changed;
|
|
12202
11946
|
};
|
|
12203
11947
|
const reactFiberKeys = (element) => Object.keys(element || {}).filter((key) => key.startsWith("__reactFiber") || key.startsWith("__reactInternalInstance") || key.startsWith("__reactProps"));
|
|
11948
|
+
const reactModelStatePatchSelector = "[role='menu'],[role='dialog'],[role='listbox'],[data-radix-popper-content-wrapper],[data-floating-ui-portal]";
|
|
11949
|
+
const isWorkspaceChromeNode = (node) => {
|
|
11950
|
+
if (!node || node.nodeType !== 1) return false;
|
|
11951
|
+
if (node.closest?.("[data-app-action-sidebar-section-heading='Chats'],[data-app-action-sidebar-section-heading='Projects'],[data-app-action-sidebar-thread-id],[data-app-action-sidebar-project-row],[data-app-action-sidebar-project-id]")) {
|
|
11952
|
+
return true;
|
|
11953
|
+
}
|
|
11954
|
+
return Boolean(node.closest?.("main aside"));
|
|
11955
|
+
};
|
|
11956
|
+
const reactModelStatePatchNodes = () => {
|
|
11957
|
+
return Array.from(document.querySelectorAll(reactModelStatePatchSelector))
|
|
11958
|
+
.filter((node) => node && !isWorkspaceChromeNode(node));
|
|
11959
|
+
};
|
|
12204
11960
|
const patchReactModelState = () => {
|
|
12205
11961
|
if (!enabled.modelWhitelistUnlock) return false;
|
|
12206
11962
|
try {
|
|
12207
11963
|
const visited = new WeakSet();
|
|
12208
|
-
const nodes =
|
|
11964
|
+
const nodes = reactModelStatePatchNodes();
|
|
12209
11965
|
let changed = false;
|
|
12210
11966
|
for (const node of nodes.slice(0, 220)) {
|
|
12211
11967
|
for (const key of reactFiberKeys(node)) {
|
|
@@ -12220,6 +11976,39 @@ function createBridgeApplyPowerExpression(settings, settingsExpression) {
|
|
|
12220
11976
|
return false;
|
|
12221
11977
|
}
|
|
12222
11978
|
};
|
|
11979
|
+
const installModelReactStateObserver = () => {
|
|
11980
|
+
if (typeof state.cleanupModelReactStateObserver === "function") {
|
|
11981
|
+
state.cleanupModelReactStateObserver();
|
|
11982
|
+
state.cleanupModelReactStateObserver = null;
|
|
11983
|
+
}
|
|
11984
|
+
if (!enabled.modelWhitelistUnlock) return false;
|
|
11985
|
+
let frame = 0;
|
|
11986
|
+
const schedulePatch = () => {
|
|
11987
|
+
if (frame) return;
|
|
11988
|
+
frame = requestAnimationFrame(() => {
|
|
11989
|
+
frame = 0;
|
|
11990
|
+
patchReactModelState();
|
|
11991
|
+
});
|
|
11992
|
+
};
|
|
11993
|
+
const isPatchableMutationNode = (node) => {
|
|
11994
|
+
const element = node?.nodeType === 1 ? node : node?.parentElement;
|
|
11995
|
+
return Boolean(
|
|
11996
|
+
element?.matches?.(reactModelStatePatchSelector)
|
|
11997
|
+
|| element?.querySelector?.(reactModelStatePatchSelector)
|
|
11998
|
+
);
|
|
11999
|
+
};
|
|
12000
|
+
const observer = new MutationObserver((mutations) => {
|
|
12001
|
+
if (mutations.some((mutation) => Array.from(mutation.addedNodes).some(isPatchableMutationNode))) {
|
|
12002
|
+
schedulePatch();
|
|
12003
|
+
}
|
|
12004
|
+
});
|
|
12005
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
12006
|
+
state.cleanupModelReactStateObserver = () => {
|
|
12007
|
+
observer.disconnect();
|
|
12008
|
+
if (frame) cancelAnimationFrame(frame);
|
|
12009
|
+
};
|
|
12010
|
+
return true;
|
|
12011
|
+
};
|
|
12223
12012
|
const patchPluginContainer = (value, visited = new WeakSet(), depth = 0, inheritedMarketplaceName = null) => {
|
|
12224
12013
|
if (!enabled.pluginMarketplaceUnlock || !value || typeof value !== "object" || visited.has(value) || depth > 4) return false;
|
|
12225
12014
|
visited.add(value);
|
|
@@ -12763,6 +12552,7 @@ function createBridgeApplyPowerExpression(settings, settingsExpression) {
|
|
|
12763
12552
|
const modelStatsigPatchApplied = enabled.modelWhitelistUnlock
|
|
12764
12553
|
? patchStatsigModelWhitelist()
|
|
12765
12554
|
: false;
|
|
12555
|
+
installModelReactStateObserver();
|
|
12766
12556
|
const modelReactStatePatched = enabled.modelWhitelistUnlock
|
|
12767
12557
|
? patchReactModelState()
|
|
12768
12558
|
: false;
|
|
@@ -13939,14 +13729,16 @@ async function reloadOfficialCodexBridgePage(debuggerUrl) {
|
|
|
13939
13729
|
return false;
|
|
13940
13730
|
}
|
|
13941
13731
|
}
|
|
13942
|
-
async function probeOfficialCodexBridge(instance, forceInstall = false) {
|
|
13732
|
+
async function probeOfficialCodexBridge(instance, forceInstall = false, allowAnyPageTarget = false) {
|
|
13943
13733
|
const checkedAt = Date.now();
|
|
13944
13734
|
if (!instance.cdpPort) {
|
|
13945
13735
|
return bridgeStateUnavailable();
|
|
13946
13736
|
}
|
|
13947
13737
|
try {
|
|
13948
13738
|
const targets = await readCdpTargets(instance.cdpPort);
|
|
13949
|
-
const target = pickCodexCdpTarget(targets
|
|
13739
|
+
const target = pickCodexCdpTarget(targets, {
|
|
13740
|
+
allowAnyPage: allowAnyPageTarget
|
|
13741
|
+
});
|
|
13950
13742
|
if (!target?.webSocketDebuggerUrl) {
|
|
13951
13743
|
return bridgeStateUnhealthy(
|
|
13952
13744
|
instance.cdpPort,
|
|
@@ -14016,14 +13808,16 @@ async function probeOfficialCodexBridge(instance, forceInstall = false) {
|
|
|
14016
13808
|
);
|
|
14017
13809
|
}
|
|
14018
13810
|
}
|
|
14019
|
-
async function reapplyDesiredBridgeSettings(instance, bridge) {
|
|
13811
|
+
async function reapplyDesiredBridgeSettings(instance, bridge, allowAnyPageTarget = false) {
|
|
14020
13812
|
const shouldClearPowerRuntime = !instance.desiredPowerSettings && hasEnabledBridgePowerRuntime(bridge.bridgePower);
|
|
14021
13813
|
if (bridge.bridgeStatus !== "healthy" || !instance.cdpPort || !instance.desiredQolSettings && !instance.desiredPowerSettings && !shouldClearPowerRuntime) {
|
|
14022
13814
|
return bridge;
|
|
14023
13815
|
}
|
|
14024
13816
|
try {
|
|
14025
13817
|
const targets = await readCdpTargets(instance.cdpPort);
|
|
14026
|
-
const target = pickCodexCdpTarget(targets
|
|
13818
|
+
const target = pickCodexCdpTarget(targets, {
|
|
13819
|
+
allowAnyPage: allowAnyPageTarget
|
|
13820
|
+
});
|
|
14027
13821
|
if (!target?.webSocketDebuggerUrl) {
|
|
14028
13822
|
return bridge;
|
|
14029
13823
|
}
|
|
@@ -14109,7 +13903,7 @@ async function reapplyDesiredBridgeSettings(instance, bridge) {
|
|
|
14109
13903
|
};
|
|
14110
13904
|
}
|
|
14111
13905
|
}
|
|
14112
|
-
async function refreshBridgeStateIfNeeded(instance, running, force = false, reapplyDesired = false) {
|
|
13906
|
+
async function refreshBridgeStateIfNeeded(instance, running, force = false, reapplyDesired = false, allowAnyPageTarget = false) {
|
|
14113
13907
|
if (!running || !instance.cdpPort) {
|
|
14114
13908
|
return bridgeStateUnavailable();
|
|
14115
13909
|
}
|
|
@@ -14117,12 +13911,16 @@ async function refreshBridgeStateIfNeeded(instance, running, force = false, reap
|
|
|
14117
13911
|
if (!force && checkedAt && Date.now() - checkedAt < CODEX_BRIDGE_PROBE_TTL_MS) {
|
|
14118
13912
|
return bridgeStateForStoredInstance(instance, true);
|
|
14119
13913
|
}
|
|
14120
|
-
const bridge = await probeOfficialCodexBridge(
|
|
14121
|
-
|
|
13914
|
+
const bridge = await probeOfficialCodexBridge(
|
|
13915
|
+
instance,
|
|
13916
|
+
force,
|
|
13917
|
+
allowAnyPageTarget
|
|
13918
|
+
);
|
|
13919
|
+
return reapplyDesired ? await reapplyDesiredBridgeSettings(instance, bridge, allowAnyPageTarget) : bridge;
|
|
14122
13920
|
}
|
|
14123
13921
|
async function waitForBridgeStateAfterLaunch(instance) {
|
|
14124
13922
|
const deadline = Date.now() + CODEX_BRIDGE_LAUNCH_WAIT_MS;
|
|
14125
|
-
let latest = await refreshBridgeStateIfNeeded(instance, true, true, true);
|
|
13923
|
+
let latest = await refreshBridgeStateIfNeeded(instance, true, true, true, true);
|
|
14126
13924
|
while (latest.bridgeStatus !== "healthy" && Date.now() < deadline) {
|
|
14127
13925
|
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
14128
13926
|
latest = await refreshBridgeStateIfNeeded(
|
|
@@ -14132,6 +13930,7 @@ async function waitForBridgeStateAfterLaunch(instance) {
|
|
|
14132
13930
|
},
|
|
14133
13931
|
true,
|
|
14134
13932
|
true,
|
|
13933
|
+
true,
|
|
14135
13934
|
true
|
|
14136
13935
|
);
|
|
14137
13936
|
}
|
|
@@ -14140,7 +13939,7 @@ async function waitForBridgeStateAfterLaunch(instance) {
|
|
|
14140
13939
|
async function waitForBridgeStateAfterReload(instance) {
|
|
14141
13940
|
const deadline = Date.now() + CODEX_BRIDGE_LAUNCH_WAIT_MS;
|
|
14142
13941
|
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
14143
|
-
let latest = await refreshBridgeStateIfNeeded(instance, true, true, true);
|
|
13942
|
+
let latest = await refreshBridgeStateIfNeeded(instance, true, true, true, true);
|
|
14144
13943
|
while (latest.bridgeStatus !== "healthy" && Date.now() < deadline) {
|
|
14145
13944
|
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
14146
13945
|
latest = await refreshBridgeStateIfNeeded(
|
|
@@ -14150,6 +13949,7 @@ async function waitForBridgeStateAfterReload(instance) {
|
|
|
14150
13949
|
},
|
|
14151
13950
|
true,
|
|
14152
13951
|
true,
|
|
13952
|
+
true,
|
|
14153
13953
|
true
|
|
14154
13954
|
);
|
|
14155
13955
|
}
|
|
@@ -14519,7 +14319,7 @@ async function openCodexWithProfileHome(candidate, profileHome, profileName, cdp
|
|
|
14519
14319
|
],
|
|
14520
14320
|
{
|
|
14521
14321
|
detached: true,
|
|
14522
|
-
env:
|
|
14322
|
+
env: buildCodexChildEnv(),
|
|
14523
14323
|
stdio: "ignore"
|
|
14524
14324
|
}
|
|
14525
14325
|
);
|
|
@@ -15487,7 +15287,7 @@ function summarizeRateLimitSnapshot(snapshot) {
|
|
|
15487
15287
|
return summary;
|
|
15488
15288
|
}
|
|
15489
15289
|
function fallbackUsage(profile) {
|
|
15490
|
-
const usageSummary = summarizeRateLimitSnapshot(
|
|
15290
|
+
const usageSummary = summarizeRateLimitSnapshot(null);
|
|
15491
15291
|
if (!profile.isValid) {
|
|
15492
15292
|
return { summary: "invalid", rows: null, usageSummary };
|
|
15493
15293
|
}
|
|
@@ -15503,8 +15303,7 @@ async function resolveProfileUsage(manager, profile, codexPath) {
|
|
|
15503
15303
|
try {
|
|
15504
15304
|
const snapshot = await manager.readLiveRateLimits(profile.name, { codexPath });
|
|
15505
15305
|
if (!snapshot) {
|
|
15506
|
-
|
|
15507
|
-
return { summary: "n/a", rows: null, usageSummary };
|
|
15306
|
+
return fallbackUsage(profile);
|
|
15508
15307
|
}
|
|
15509
15308
|
const rows = [];
|
|
15510
15309
|
if (snapshot.primary) {
|
|
@@ -15556,7 +15355,7 @@ function computeAutoRollCandidate(profiles, usageMap, currentProfileName, curren
|
|
|
15556
15355
|
(profile) => profile.name !== currentProfileName && !blockedProfileNames.has(profile.name) && profile.isValid && !profile.tokenStatus?.requiresUserAction
|
|
15557
15356
|
).map((profile) => ({
|
|
15558
15357
|
profile,
|
|
15559
|
-
usageSummary: usageMap.get(profile.name)?.usageSummary ?? summarizeRateLimitSnapshot(
|
|
15358
|
+
usageSummary: usageMap.get(profile.name)?.usageSummary ?? summarizeRateLimitSnapshot(null)
|
|
15560
15359
|
}));
|
|
15561
15360
|
if (candidates.length === 0) {
|
|
15562
15361
|
return null;
|
|
@@ -15971,7 +15770,7 @@ async function runAutoRollPass(manager, options) {
|
|
|
15971
15770
|
target: null
|
|
15972
15771
|
};
|
|
15973
15772
|
}
|
|
15974
|
-
const currentUsage = usageMap.get(current.name)?.usageSummary ?? summarizeRateLimitSnapshot(
|
|
15773
|
+
const currentUsage = usageMap.get(current.name)?.usageSummary ?? summarizeRateLimitSnapshot(null);
|
|
15975
15774
|
if (!currentUsage.hasUsage) {
|
|
15976
15775
|
return {
|
|
15977
15776
|
switched: false,
|
|
@@ -16089,7 +15888,7 @@ async function handleProfileCommand(args, version) {
|
|
|
16089
15888
|
usageMap.set(profile.name, {
|
|
16090
15889
|
summary: "codex cli missing",
|
|
16091
15890
|
rows: null,
|
|
16092
|
-
usageSummary: summarizeRateLimitSnapshot(
|
|
15891
|
+
usageSummary: summarizeRateLimitSnapshot(null)
|
|
16093
15892
|
});
|
|
16094
15893
|
}
|
|
16095
15894
|
} else {
|
|
@@ -16460,7 +16259,7 @@ async function pushRemoteSnapshot(access, snapshot, options) {
|
|
|
16460
16259
|
}
|
|
16461
16260
|
|
|
16462
16261
|
// ../../packages/runtime-codex/src/codex/config.ts
|
|
16463
|
-
var
|
|
16262
|
+
var import_toml2 = __toESM(require_toml(), 1);
|
|
16464
16263
|
|
|
16465
16264
|
// ../../packages/runtime-codex/src/codex/config-metadata.ts
|
|
16466
16265
|
var import_node_child_process8 = require("child_process");
|
|
@@ -16577,7 +16376,7 @@ async function runCommand3(command, args, timeoutMs = 3e3) {
|
|
|
16577
16376
|
return new Promise((resolve, reject) => {
|
|
16578
16377
|
const child = (0, import_node_child_process8.spawn)(command, args, {
|
|
16579
16378
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16580
|
-
env:
|
|
16379
|
+
env: buildCodexChildEnv()
|
|
16581
16380
|
});
|
|
16582
16381
|
let stdout = "";
|
|
16583
16382
|
let stderr = "";
|
|
@@ -17099,7 +16898,7 @@ function formatUserFacingError(error, options = {}) {
|
|
|
17099
16898
|
// ../../packages/runtime-codex/src/codex/config.ts
|
|
17100
16899
|
function tryParseToml(content) {
|
|
17101
16900
|
try {
|
|
17102
|
-
const parsed = (0,
|
|
16901
|
+
const parsed = (0, import_toml2.parse)(content);
|
|
17103
16902
|
return { data: parsed ?? {}, error: null };
|
|
17104
16903
|
} catch (error) {
|
|
17105
16904
|
const maybe = error;
|
|
@@ -18138,7 +17937,7 @@ async function ensureCliStorageReady() {
|
|
|
18138
17937
|
}
|
|
18139
17938
|
|
|
18140
17939
|
// src/app/main.ts
|
|
18141
|
-
var VERSION = true ? "5.1.
|
|
17940
|
+
var VERSION = true ? "5.1.6" : "0.0.0";
|
|
18142
17941
|
async function runCli() {
|
|
18143
17942
|
const args = process.argv.slice(2);
|
|
18144
17943
|
if (args.length === 0) {
|