@omnicross/daemon 0.3.1 → 0.4.1

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/cli.cjs CHANGED
@@ -1170,22 +1170,22 @@ var import_node_fs36 = require("fs");
1170
1170
  var import_node_path36 = require("path");
1171
1171
  var import_audit_types = require("@omnicross/contracts/audit-types");
1172
1172
  var import_billing_types = require("@omnicross/contracts/billing-types");
1173
- var import_core4 = require("@omnicross/core");
1174
- var import_GeminiCodeAssistProjectResolver = require("@omnicross/core/auth/GeminiCodeAssistProjectResolver");
1173
+ var import_core7 = require("@omnicross/core");
1174
+ var import_GeminiCodeAssistProjectResolver2 = require("@omnicross/core/auth/GeminiCodeAssistProjectResolver");
1175
1175
  var import_ApiKeyPoolService = require("@omnicross/core/completion/ApiKeyPoolService");
1176
1176
  var import_outbound_api10 = require("@omnicross/core/outbound-api");
1177
1177
  var import_subscriptionRegistryPort = require("@omnicross/core/outbound-api/subscriptionRegistryPort");
1178
1178
  var import_SubscriptionAccountHealth4 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
1179
- var import_AccountAllowanceStore7 = require("@omnicross/core/pipeline/AccountAllowanceStore");
1179
+ var import_AccountAllowanceStore10 = require("@omnicross/core/pipeline/AccountAllowanceStore");
1180
1180
  var import_AccountAllowanceScheduling5 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
1181
- var import_upstreamFetch13 = require("@omnicross/core/pipeline/upstreamFetch");
1181
+ var import_upstreamFetch16 = require("@omnicross/core/pipeline/upstreamFetch");
1182
1182
  var import_SubscriptionIdentityStore3 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
1183
1183
  var import_gemini_code_assist_resolver = require("@omnicross/core/ports/gemini-code-assist-resolver");
1184
1184
  var import_provider_proxy4 = require("@omnicross/core/provider-proxy");
1185
1185
  var import_cli_launcher2 = require("@omnicross/cli-launcher");
1186
1186
  var import_outbound_api11 = require("@omnicross/core/outbound-api");
1187
1187
  var import_usage2 = require("@omnicross/core/usage");
1188
- var import_subscriptions9 = require("@omnicross/subscriptions");
1188
+ var import_subscriptions12 = require("@omnicross/subscriptions");
1189
1189
 
1190
1190
  // src/admin/accountsCodexOAuth.ts
1191
1191
  var import_node_crypto3 = __toESM(require("crypto"), 1);
@@ -1367,8 +1367,187 @@ function handleKimiOAuthStatus(sessionId, deps) {
1367
1367
  return { status: 200, body: { state: s.status, ...s.error ? { message: s.error } : {} } };
1368
1368
  }
1369
1369
 
1370
+ // src/admin/accountsGrokOAuth.ts
1371
+ var import_subscriptions3 = require("@omnicross/subscriptions");
1372
+ function err3(status, message) {
1373
+ return { status, body: { error: { type: "admin_api_error", message } } };
1374
+ }
1375
+ var DEFAULT_GROK_OAUTH_TTL_MS = 15 * 6e4;
1376
+ async function handleGrokOAuthStart(deps) {
1377
+ if (deps.grokSessions.isBusy()) {
1378
+ return err3(409, "a grok sign-in is already in progress \u2014 finish it in the browser or cancel it");
1379
+ }
1380
+ const fetchImpl = deps.oauthExchangeFetch("grok");
1381
+ let tokenEndpoint;
1382
+ try {
1383
+ tokenEndpoint = await import_subscriptions3.grokOAuth.resolveGrokTokenEndpoint(fetchImpl);
1384
+ } catch (e) {
1385
+ const reason = e instanceof Error ? e.message : "OIDC discovery failed";
1386
+ return err3(502, `grok token-endpoint discovery failed: ${reason}`);
1387
+ }
1388
+ let authorization;
1389
+ try {
1390
+ authorization = await import_subscriptions3.grokOAuth.requestGrokDeviceAuthorization(fetchImpl);
1391
+ } catch (e) {
1392
+ const reason = e instanceof Error ? e.message : "device authorization failed";
1393
+ return err3(502, `grok device authorization failed: ${reason}`);
1394
+ }
1395
+ const { sessionId, signal } = deps.grokSessions.begin();
1396
+ void runGrokDevicePoll(sessionId, tokenEndpoint, authorization.deviceCode, signal, deps).catch((e) => {
1397
+ const reason = e instanceof Error ? e.message : "grok sign-in failed";
1398
+ deps.grokSessions.settle(sessionId, "error", reason);
1399
+ });
1400
+ return {
1401
+ status: 200,
1402
+ body: {
1403
+ authUrl: authorization.verificationUriComplete ?? authorization.verificationUri,
1404
+ userCode: authorization.userCode,
1405
+ sessionId
1406
+ }
1407
+ };
1408
+ }
1409
+ async function runGrokDevicePoll(sessionId, tokenEndpoint, deviceCode, signal, deps) {
1410
+ const fetchImpl = deps.oauthExchangeFetch("grok");
1411
+ const result = await import_subscriptions3.grokOAuth.awaitGrokDeviceToken(
1412
+ { userCode: "", deviceCode, verificationUri: "" },
1413
+ tokenEndpoint,
1414
+ fetchImpl,
1415
+ {
1416
+ deadlineMs: DEFAULT_GROK_OAUTH_TTL_MS,
1417
+ sleep: (ms) => new Promise((resolve11, reject) => {
1418
+ const onAbort = () => {
1419
+ clearTimeout(timer);
1420
+ reject(new Error("login: cancelled"));
1421
+ };
1422
+ const timer = setTimeout(() => {
1423
+ signal.removeEventListener("abort", onAbort);
1424
+ resolve11();
1425
+ }, ms);
1426
+ signal.addEventListener("abort", onAbort, { once: true });
1427
+ })
1428
+ }
1429
+ );
1430
+ const block = {
1431
+ authMethod: "oauth",
1432
+ status: "authorized",
1433
+ accessToken: result.accessToken,
1434
+ refreshToken: result.refreshToken,
1435
+ expiresAt: new Date(Date.now() + result.expiresIn * 1e3).toISOString(),
1436
+ accountId: import_subscriptions3.grokOAuth.grokAccountIdFromAccessToken(result.accessToken),
1437
+ lastRefreshedAt: (/* @__PURE__ */ new Date()).toISOString()
1438
+ };
1439
+ await deps.subscriptionAccountAppender.appendProviderAccount("grok", block);
1440
+ deps.grokSessions.settle(sessionId, "done");
1441
+ }
1442
+ function handleGrokOAuthCancel(sessionId, deps) {
1443
+ if (!deps.grokSessions.cancel(sessionId)) return err3(404, "unknown or expired grok sign-in session");
1444
+ return { status: 200, body: { ok: true } };
1445
+ }
1446
+ function handleGrokOAuthStatus(sessionId, deps) {
1447
+ const s = deps.grokSessions.get(sessionId);
1448
+ if (!s) return err3(404, "unknown or expired grok sign-in session");
1449
+ return { status: 200, body: { state: s.status, ...s.error ? { message: s.error } : {} } };
1450
+ }
1451
+
1452
+ // src/admin/accountsCopilotOAuth.ts
1453
+ var import_subscriptions4 = require("@omnicross/subscriptions");
1454
+ function err4(status, message) {
1455
+ return { status, body: { error: { type: "admin_api_error", message } } };
1456
+ }
1457
+ var DEFAULT_COPILOT_OAUTH_TTL_MS = 15 * 6e4;
1458
+ async function handleCopilotOAuthStart(deps, enterpriseUrlInput) {
1459
+ if (deps.copilotSessions.isBusy()) {
1460
+ return err4(409, "a copilot sign-in is already in progress \u2014 finish it in the browser or cancel it");
1461
+ }
1462
+ let enterpriseUrl;
1463
+ if (typeof enterpriseUrlInput === "string" && enterpriseUrlInput.trim()) {
1464
+ try {
1465
+ enterpriseUrl = import_subscriptions4.copilotOAuth.normalizeCopilotEnterpriseDomain(enterpriseUrlInput);
1466
+ } catch (e) {
1467
+ const reason = e instanceof Error ? e.message : "invalid GitHub Enterprise domain";
1468
+ return err4(400, `copilot ${reason}`);
1469
+ }
1470
+ }
1471
+ const fetchImpl = deps.oauthExchangeFetch("copilot");
1472
+ let authorization;
1473
+ try {
1474
+ authorization = await import_subscriptions4.copilotOAuth.requestCopilotDeviceAuthorization(fetchImpl, enterpriseUrl);
1475
+ } catch (e) {
1476
+ const reason = e instanceof Error ? e.message : "device authorization failed";
1477
+ return err4(502, `copilot device authorization failed: ${reason}`);
1478
+ }
1479
+ const { sessionId, signal } = deps.copilotSessions.begin();
1480
+ void runCopilotDevicePoll(sessionId, authorization.deviceCode, signal, deps, enterpriseUrl).catch((e) => {
1481
+ const reason = e instanceof Error ? e.message : "copilot sign-in failed";
1482
+ deps.copilotSessions.settle(sessionId, "error", reason);
1483
+ });
1484
+ return {
1485
+ status: 200,
1486
+ body: {
1487
+ authUrl: authorization.verificationUri,
1488
+ userCode: authorization.userCode,
1489
+ sessionId,
1490
+ ...enterpriseUrl ? { enterpriseUrl } : {}
1491
+ }
1492
+ };
1493
+ }
1494
+ async function runCopilotDevicePoll(sessionId, deviceCode, signal, deps, enterpriseUrl) {
1495
+ const fetchImpl = deps.oauthExchangeFetch("copilot");
1496
+ const result = await import_subscriptions4.copilotOAuth.awaitCopilotDeviceToken(
1497
+ { userCode: "", deviceCode, verificationUri: "", interval: 5, expiresIn: 900 },
1498
+ fetchImpl,
1499
+ {
1500
+ deadlineMs: DEFAULT_COPILOT_OAUTH_TTL_MS,
1501
+ ...enterpriseUrl ? { enterpriseUrl } : {},
1502
+ sleep: (ms) => new Promise((resolve11, reject) => {
1503
+ const onAbort = () => {
1504
+ clearTimeout(timer);
1505
+ reject(new Error("login: cancelled"));
1506
+ };
1507
+ const timer = setTimeout(() => {
1508
+ signal.removeEventListener("abort", onAbort);
1509
+ resolve11();
1510
+ }, ms);
1511
+ signal.addEventListener("abort", onAbort, { once: true });
1512
+ })
1513
+ }
1514
+ );
1515
+ const identity = await import_subscriptions4.copilotOAuth.fetchCopilotIdentity(result.accessToken, fetchImpl, enterpriseUrl);
1516
+ const apiEndpoint = await import_subscriptions4.copilotOAuth.discoverCopilotApiEndpoint(result.accessToken, fetchImpl, enterpriseUrl);
1517
+ await import_subscriptions4.copilotOAuth.enableAllCopilotModels(
1518
+ result.accessToken,
1519
+ { apiEndpoint, ...enterpriseUrl ? { enterpriseUrl } : {} },
1520
+ fetchImpl
1521
+ );
1522
+ const block = {
1523
+ authMethod: "oauth",
1524
+ status: "authorized",
1525
+ accessToken: result.accessToken,
1526
+ refreshToken: result.accessToken,
1527
+ expiresAt: new Date(Date.now() + import_subscriptions4.copilotOAuth.COPILOT_FAR_FUTURE_MS).toISOString(),
1528
+ ...identity.accountId ? { accountId: identity.accountId } : {},
1529
+ ...identity.email ? { email: identity.email } : {},
1530
+ ...apiEndpoint ? { apiEndpoint } : {},
1531
+ ...enterpriseUrl ? { enterpriseUrl } : {},
1532
+ lastRefreshedAt: (/* @__PURE__ */ new Date()).toISOString()
1533
+ };
1534
+ await deps.subscriptionAccountAppender.appendProviderAccount("copilot", block);
1535
+ deps.copilotSessions.settle(sessionId, "done");
1536
+ }
1537
+ function handleCopilotOAuthCancel(sessionId, deps) {
1538
+ if (!deps.copilotSessions.cancel(sessionId)) {
1539
+ return err4(404, "unknown or expired copilot sign-in session");
1540
+ }
1541
+ return { status: 200, body: { ok: true } };
1542
+ }
1543
+ function handleCopilotOAuthStatus(sessionId, deps) {
1544
+ const s = deps.copilotSessions.get(sessionId);
1545
+ if (!s) return err4(404, "unknown or expired copilot sign-in session");
1546
+ return { status: 200, body: { state: s.status, ...s.error ? { message: s.error } : {} } };
1547
+ }
1548
+
1370
1549
  // src/allowance/AccountAllowanceService.ts
1371
- var import_AccountAllowanceStore5 = require("@omnicross/core/pipeline/AccountAllowanceStore");
1550
+ var import_AccountAllowanceStore8 = require("@omnicross/core/pipeline/AccountAllowanceStore");
1372
1551
  var import_AccountAllowanceScheduling = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
1373
1552
 
1374
1553
  // src/allowance/ClaudeAllowanceCollector.ts
@@ -1839,7 +2018,7 @@ var CodexAllowanceCollector = class {
1839
2018
  // src/allowance/KimiAllowanceCollector.ts
1840
2019
  var import_AccountAllowanceStore3 = require("@omnicross/core/pipeline/AccountAllowanceStore");
1841
2020
  var import_upstreamFetch3 = require("@omnicross/core/pipeline/upstreamFetch");
1842
- var import_subscriptions3 = require("@omnicross/subscriptions");
2021
+ var import_subscriptions5 = require("@omnicross/subscriptions");
1843
2022
  var KIMI_ALLOWANCE_CACHE_MS = 5 * 6e4;
1844
2023
  var KIMI_USAGE_URL = "https://api.kimi.com/coding/v1/usages";
1845
2024
  function finiteNumber2(value) {
@@ -2011,80 +2190,737 @@ var KimiAllowanceCollector = class {
2011
2190
  try {
2012
2191
  payload = await response.json();
2013
2192
  } catch {
2014
- return this.failureSnapshot(accountId, "kimi_usage_invalid_response", this.now());
2193
+ return this.failureSnapshot(accountId, "kimi_usage_invalid_response", this.now());
2194
+ }
2195
+ const now = this.now();
2196
+ const windows = parseKimiUsagePayload(payload, now);
2197
+ const snapshot = {
2198
+ providerId: "kimi",
2199
+ accountId,
2200
+ source: "oauth-usage-api",
2201
+ observedAt: new Date(now).toISOString(),
2202
+ expiresAt: new Date(now + KIMI_ALLOWANCE_CACHE_MS).toISOString(),
2203
+ windows: windows.length > 0 ? windows : [
2204
+ { id: "five-hour", label: "5 hours", scope: "all", usedPercent: null, state: "unavailable" },
2205
+ { id: "seven-day", label: "7 days", scope: "all", usedPercent: null, state: "unavailable" }
2206
+ ],
2207
+ ...windows.length > 0 ? {} : { lastErrorCode: "kimi_usage_invalid_response" }
2208
+ };
2209
+ this.store.set(snapshot);
2210
+ return snapshot;
2211
+ }
2212
+ request(accountId, accessToken, tokens) {
2213
+ return this.fetchImpl(KIMI_USAGE_URL, {
2214
+ method: "GET",
2215
+ headers: {
2216
+ Authorization: `Bearer ${accessToken}`,
2217
+ Accept: "application/json",
2218
+ ...(0, import_subscriptions5.kimiFingerprintHeaders)(tokens.deviceId)
2219
+ },
2220
+ signal: AbortSignal.timeout(15e3)
2221
+ }, accountId);
2222
+ }
2223
+ failureSnapshot(accountId, code, now) {
2224
+ const existing = this.store.get("kimi", accountId, now);
2225
+ const snapshot = existing ? {
2226
+ ...existing,
2227
+ expiresAt: new Date(now + KIMI_ALLOWANCE_CACHE_MS).toISOString(),
2228
+ windows: existing.windows.map((window) => ({
2229
+ ...window,
2230
+ state: window.state === "unsupported" ? "unsupported" : window.usedPercent !== null || window.resetsAt ? "stale" : "unavailable"
2231
+ })),
2232
+ lastErrorCode: code
2233
+ } : {
2234
+ providerId: "kimi",
2235
+ accountId,
2236
+ source: "oauth-usage-api",
2237
+ observedAt: new Date(now).toISOString(),
2238
+ expiresAt: new Date(now + KIMI_ALLOWANCE_CACHE_MS).toISOString(),
2239
+ windows: [
2240
+ { id: "five-hour", label: "5 hours", scope: "all", usedPercent: null, state: "unavailable" },
2241
+ { id: "seven-day", label: "7 days", scope: "all", usedPercent: null, state: "unavailable" }
2242
+ ],
2243
+ lastErrorCode: code
2244
+ };
2245
+ this.store.set(snapshot);
2246
+ return snapshot;
2247
+ }
2248
+ unsupportedSnapshot(accountId, now, code = "kimi_usage_unsupported_auth") {
2249
+ return {
2250
+ providerId: "kimi",
2251
+ accountId,
2252
+ source: "oauth-usage-api",
2253
+ observedAt: new Date(now).toISOString(),
2254
+ windows: [
2255
+ { id: "five-hour", label: "5 hours", scope: "all", usedPercent: null, state: "unsupported" },
2256
+ { id: "seven-day", label: "7 days", scope: "all", usedPercent: null, state: "unsupported" }
2257
+ ],
2258
+ lastErrorCode: code
2259
+ };
2260
+ }
2261
+ };
2262
+
2263
+ // src/allowance/GrokAllowanceCollector.ts
2264
+ var import_AccountAllowanceStore4 = require("@omnicross/core/pipeline/AccountAllowanceStore");
2265
+ var import_upstreamFetch4 = require("@omnicross/core/pipeline/upstreamFetch");
2266
+ var GROK_ALLOWANCE_CACHE_MS = 5 * 6e4;
2267
+ var GROK_BILLING_BASE = "https://cli-chat-proxy.grok.com";
2268
+ var GROK_BILLING_CREDITS_URL = `${GROK_BILLING_BASE}/v1/billing?format=credits`;
2269
+ var GROK_BILLING_MONTHLY_URL = `${GROK_BILLING_BASE}/v1/billing`;
2270
+ function isRecord2(value) {
2271
+ return !!value && typeof value === "object" && !Array.isArray(value);
2272
+ }
2273
+ function finiteNumber3(value) {
2274
+ if (value === null || value === void 0 || value === "") return void 0;
2275
+ const parsed = typeof value === "number" ? value : Number(value);
2276
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
2277
+ }
2278
+ function percent(value) {
2279
+ const parsed = finiteNumber3(value);
2280
+ return parsed !== void 0 && parsed <= 100 ? parsed : void 0;
2281
+ }
2282
+ function onDemandAmount(value) {
2283
+ return isRecord2(value) ? finiteNumber3(value["val"]) : void 0;
2284
+ }
2285
+ function confirmsNoMonthlyQuota(raw) {
2286
+ const limit = onDemandAmount(raw["monthlyLimit"]);
2287
+ if (limit !== void 0) return limit === 0;
2288
+ return parseWeeklyConfig(raw)?.inferredPercent === true;
2289
+ }
2290
+ function parseWeeklyConfig(raw) {
2291
+ const period = isRecord2(raw["currentPeriod"]) ? raw["currentPeriod"] : void 0;
2292
+ if (!period) return null;
2293
+ const start = typeof period["start"] === "string" ? Date.parse(period["start"]) : Number.NaN;
2294
+ const end = typeof period["end"] === "string" ? Date.parse(period["end"]) : Number.NaN;
2295
+ const type = typeof period["type"] === "string" ? period["type"] : "";
2296
+ if (!Number.isFinite(start) || !Number.isFinite(end) || end <= start) return null;
2297
+ if (!type.toUpperCase().includes("WEEK")) return null;
2298
+ const inferred = raw["creditUsagePercent"] === void 0 || raw["creditUsagePercent"] === null;
2299
+ let creditUsagePercent;
2300
+ if (inferred) {
2301
+ creditUsagePercent = end > Date.now() ? 0 : void 0;
2302
+ } else {
2303
+ creditUsagePercent = percent(raw["creditUsagePercent"]);
2304
+ }
2305
+ if (creditUsagePercent === void 0) return null;
2306
+ return {
2307
+ creditUsagePercent,
2308
+ inferredPercent: inferred,
2309
+ resetsAtMs: end,
2310
+ unified: raw["isUnifiedBillingUser"] === true
2311
+ };
2312
+ }
2313
+ function parseMonthlyConfig(raw) {
2314
+ const start = typeof raw["billingPeriodStart"] === "string" ? Date.parse(raw["billingPeriodStart"]) : Number.NaN;
2315
+ const end = typeof raw["billingPeriodEnd"] === "string" ? Date.parse(raw["billingPeriodEnd"]) : Number.NaN;
2316
+ if (!Number.isFinite(start) || !Number.isFinite(end) || end <= start) return null;
2317
+ const limit = onDemandAmount(raw["monthlyLimit"]);
2318
+ const used = onDemandAmount(raw["used"]);
2319
+ if (limit === void 0 || limit <= 0 || used === void 0) return null;
2320
+ return { used, limit, periodStartMs: start, periodEndMs: end };
2321
+ }
2322
+ function secondsUntil4(instant, now) {
2323
+ if (!instant) return void 0;
2324
+ return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
2325
+ }
2326
+ var MINUTE_MS2 = 6e4;
2327
+ var DAY_MS2 = 864e5;
2328
+ var WEEK_MINUTES = 7 * 24 * 60;
2329
+ function weeklyWindow(config, now) {
2330
+ const resetsAt = new Date(config.resetsAtMs).toISOString();
2331
+ return {
2332
+ id: "seven-day",
2333
+ label: "7 days",
2334
+ scope: "all",
2335
+ usedPercent: config.creditUsagePercent,
2336
+ windowMinutes: WEEK_MINUTES,
2337
+ resetsAt,
2338
+ remainingSeconds: secondsUntil4(resetsAt, now),
2339
+ state: "fresh"
2340
+ };
2341
+ }
2342
+ function monthlyWindow(config, now) {
2343
+ const resetsAt = new Date(config.periodEndMs).toISOString();
2344
+ const days = Math.max(1, Math.round((config.periodEndMs - config.periodStartMs) / DAY_MS2));
2345
+ return {
2346
+ id: "thirty-day",
2347
+ label: days === 30 || days === 31 ? "30 days" : `${days} days`,
2348
+ scope: "all",
2349
+ usedPercent: Math.round(Math.min(100, config.used / config.limit * 100) * 10) / 10,
2350
+ windowMinutes: Math.round((config.periodEndMs - config.periodStartMs) / MINUTE_MS2),
2351
+ resetsAt,
2352
+ remainingSeconds: secondsUntil4(resetsAt, now),
2353
+ state: "fresh"
2354
+ };
2355
+ }
2356
+ function onDemandWindow(raw) {
2357
+ const cap = onDemandAmount(raw["onDemandCap"]);
2358
+ const used = onDemandAmount(raw["onDemandUsed"]);
2359
+ if (cap === void 0 || cap <= 0 || used === void 0) return null;
2360
+ return {
2361
+ id: "on-demand",
2362
+ label: "On-demand",
2363
+ scope: "all",
2364
+ usedPercent: Math.round(Math.min(100, used / cap * 100) * 10) / 10,
2365
+ state: "fresh"
2366
+ };
2367
+ }
2368
+ async function probeBilling(url, accessToken, accountId, fetchImpl) {
2369
+ try {
2370
+ const response = await fetchImpl(url, {
2371
+ method: "GET",
2372
+ headers: {
2373
+ Authorization: `Bearer ${accessToken}`,
2374
+ Accept: "application/json",
2375
+ "X-XAI-Token-Auth": "xai-grok-cli"
2376
+ },
2377
+ redirect: "error",
2378
+ signal: AbortSignal.timeout(15e3)
2379
+ }, accountId);
2380
+ if (!response.ok) return { status: response.status, payload: null };
2381
+ const payload = await response.json();
2382
+ return { status: response.status, payload: isRecord2(payload) ? payload : null };
2383
+ } catch {
2384
+ return { status: 0, payload: null };
2385
+ }
2386
+ }
2387
+ function parseGrokBillingPayloads(creditsPayload, monthlyPayload, now) {
2388
+ const creditsConfig = isRecord2(creditsPayload?.["config"]) ? creditsPayload["config"] : null;
2389
+ const monthlyConfig = isRecord2(monthlyPayload?.["config"]) ? monthlyPayload["config"] : null;
2390
+ let weekly = creditsConfig ? parseWeeklyConfig(creditsConfig) : null;
2391
+ const unifiedFlag = creditsConfig?.["isUnifiedBillingUser"] === true;
2392
+ let monthly = monthlyConfig ? parseMonthlyConfig(monthlyConfig) : null;
2393
+ if (weekly?.inferredPercent && unifiedFlag) {
2394
+ if (monthly) {
2395
+ weekly = null;
2396
+ } else if (!monthlyConfig || !confirmsNoMonthlyQuota(monthlyConfig)) {
2397
+ weekly = null;
2398
+ }
2399
+ }
2400
+ const windows = [];
2401
+ if (weekly) windows.push(weeklyWindow(weekly, now));
2402
+ if (monthly) windows.push(monthlyWindow(monthly, now));
2403
+ const onDemandSource = monthly && monthlyConfig ? monthlyConfig : creditsConfig;
2404
+ const onDemand = onDemandSource ? onDemandWindow(onDemandSource) : null;
2405
+ if (onDemand) windows.push(onDemand);
2406
+ return windows.length > 0 ? windows : null;
2407
+ }
2408
+ var GrokAllowanceCollector = class {
2409
+ constructor(credentials, store = (0, import_AccountAllowanceStore4.getSharedAccountAllowanceStore)(), fetchImpl = (url, init, accountId) => (0, import_upstreamFetch4.fetchUpstream)(url, init, { providerId: "grok", accountId, redactBodies: true }), now = Date.now) {
2410
+ this.credentials = credentials;
2411
+ this.store = store;
2412
+ this.fetchImpl = fetchImpl;
2413
+ this.now = now;
2414
+ }
2415
+ credentials;
2416
+ store;
2417
+ fetchImpl;
2418
+ now;
2419
+ inFlight = /* @__PURE__ */ new Map();
2420
+ async collectMany(accounts, options = {}) {
2421
+ const settled = await Promise.allSettled(accounts.map((account) => this.collect(account, options)));
2422
+ return settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
2423
+ }
2424
+ collect(account, options = {}) {
2425
+ const now = this.now();
2426
+ if (account.tokens.authMethod !== "oauth") {
2427
+ const existing = this.store.get("grok", account.id, now);
2428
+ if (existing?.windows.every((window) => window.state === "unsupported")) {
2429
+ return Promise.resolve(existing);
2430
+ }
2431
+ const snapshot = this.unsupportedSnapshot(account.id, now);
2432
+ this.store.set(snapshot);
2433
+ return Promise.resolve(snapshot);
2434
+ }
2435
+ const cached = this.store.get("grok", account.id, now);
2436
+ if (!options.force && cached && this.isCacheValid(cached, now, options.refreshAheadMs)) {
2437
+ return Promise.resolve(cached);
2438
+ }
2439
+ const running = this.inFlight.get(account.id);
2440
+ if (running) return running;
2441
+ const promise = this.fetchAccount(account.id).catch(() => this.failureSnapshot(account.id, "grok_usage_request_failed", this.now())).finally(() => this.inFlight.delete(account.id));
2442
+ this.inFlight.set(account.id, promise);
2443
+ return promise;
2444
+ }
2445
+ isCacheValid(snapshot, now, refreshAheadMs) {
2446
+ if (snapshot.windows.every((window) => window.state === "unsupported")) return true;
2447
+ const expiresAt = snapshot.expiresAt ? Date.parse(snapshot.expiresAt) : 0;
2448
+ const ahead = typeof refreshAheadMs === "number" && Number.isFinite(refreshAheadMs) ? Math.max(0, refreshAheadMs) : 0;
2449
+ return Number.isFinite(expiresAt) && expiresAt > now + ahead;
2450
+ }
2451
+ async fetchAccount(accountId) {
2452
+ const probe = async () => {
2453
+ const accessToken = await this.credentials.getAccessTokenForAccount("grok", accountId);
2454
+ if (!accessToken) return { unauthorized: true, windows: null };
2455
+ const credits = await probeBilling(GROK_BILLING_CREDITS_URL, accessToken, accountId, this.fetchImpl);
2456
+ if (credits.status === 401 || credits.status === 403) return { unauthorized: true, windows: null };
2457
+ const creditsConfig = isRecord2(credits.payload?.["config"]) ? credits.payload["config"] : null;
2458
+ const weekly = creditsConfig ? parseWeeklyConfig(creditsConfig) : null;
2459
+ const monthly = !weekly || creditsConfig?.["isUnifiedBillingUser"] === true ? await probeBilling(GROK_BILLING_MONTHLY_URL, accessToken, accountId, this.fetchImpl) : { status: 200, payload: null };
2460
+ if (monthly.status === 401 || monthly.status === 403) return { unauthorized: true, windows: null };
2461
+ return {
2462
+ unauthorized: false,
2463
+ windows: parseGrokBillingPayloads(credits.payload, monthly.payload, this.now())
2464
+ };
2465
+ };
2466
+ let result = await probe();
2467
+ if (result.unauthorized) {
2468
+ const refreshed = await this.credentials.refreshAccountToken("grok", accountId);
2469
+ if (!refreshed) return this.failureSnapshot(accountId, "grok_usage_unauthorized", this.now());
2470
+ result = await probe();
2471
+ if (result.unauthorized) {
2472
+ return this.failureSnapshot(accountId, "grok_usage_unauthorized", this.now());
2473
+ }
2474
+ }
2475
+ const now = this.now();
2476
+ if (result.windows && result.windows.length > 0) {
2477
+ const snapshot = {
2478
+ providerId: "grok",
2479
+ accountId,
2480
+ source: "oauth-usage-api",
2481
+ observedAt: new Date(now).toISOString(),
2482
+ expiresAt: new Date(now + GROK_ALLOWANCE_CACHE_MS).toISOString(),
2483
+ windows: result.windows
2484
+ };
2485
+ this.store.set(snapshot);
2486
+ return snapshot;
2487
+ }
2488
+ return this.failureSnapshot(accountId, "grok_usage_invalid_response", now);
2489
+ }
2490
+ failureSnapshot(accountId, code, now) {
2491
+ const existing = this.store.get("grok", accountId, now);
2492
+ const snapshot = existing ? {
2493
+ ...existing,
2494
+ expiresAt: new Date(now + GROK_ALLOWANCE_CACHE_MS).toISOString(),
2495
+ windows: existing.windows.map((window) => ({
2496
+ ...window,
2497
+ state: window.state === "unsupported" ? "unsupported" : window.usedPercent !== null || window.resetsAt ? "stale" : "unavailable"
2498
+ })),
2499
+ lastErrorCode: code
2500
+ } : {
2501
+ providerId: "grok",
2502
+ accountId,
2503
+ source: "oauth-usage-api",
2504
+ observedAt: new Date(now).toISOString(),
2505
+ expiresAt: new Date(now + GROK_ALLOWANCE_CACHE_MS).toISOString(),
2506
+ windows: [
2507
+ { id: "seven-day", label: "7 days", scope: "all", usedPercent: null, state: "unavailable" },
2508
+ { id: "thirty-day", label: "30 days", scope: "all", usedPercent: null, state: "unavailable" }
2509
+ ],
2510
+ lastErrorCode: code
2511
+ };
2512
+ this.store.set(snapshot);
2513
+ return snapshot;
2514
+ }
2515
+ unsupportedSnapshot(accountId, now) {
2516
+ return {
2517
+ providerId: "grok",
2518
+ accountId,
2519
+ source: "oauth-usage-api",
2520
+ observedAt: new Date(now).toISOString(),
2521
+ windows: [
2522
+ { id: "seven-day", label: "7 days", scope: "all", usedPercent: null, state: "unsupported" },
2523
+ { id: "thirty-day", label: "30 days", scope: "all", usedPercent: null, state: "unsupported" }
2524
+ ],
2525
+ lastErrorCode: "grok_usage_unsupported_auth"
2526
+ };
2527
+ }
2528
+ };
2529
+
2530
+ // src/allowance/CopilotAllowanceCollector.ts
2531
+ var import_AccountAllowanceStore5 = require("@omnicross/core/pipeline/AccountAllowanceStore");
2532
+ var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
2533
+ var import_subscriptions6 = require("@omnicross/subscriptions");
2534
+ var COPILOT_ALLOWANCE_CACHE_MS = 5 * 6e4;
2535
+ function isRecord3(value) {
2536
+ return !!value && typeof value === "object" && !Array.isArray(value);
2537
+ }
2538
+ function finiteNumber4(value) {
2539
+ if (value === null || value === void 0 || value === "") return void 0;
2540
+ const parsed = typeof value === "number" ? value : Number(value);
2541
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
2542
+ }
2543
+ function booleanValue(value) {
2544
+ if (typeof value === "boolean") return value;
2545
+ if (value === "true") return true;
2546
+ if (value === "false") return false;
2547
+ return void 0;
2548
+ }
2549
+ function parseQuotaDetail(value) {
2550
+ if (!isRecord3(value)) return null;
2551
+ const entitlement = finiteNumber4(value["entitlement"]);
2552
+ const remaining = finiteNumber4(value["remaining"]);
2553
+ const percentRemaining = finiteNumber4(value["percent_remaining"]);
2554
+ const unlimited = booleanValue(value["unlimited"]);
2555
+ if (entitlement === void 0 || remaining === void 0 || percentRemaining === void 0 || unlimited === void 0) {
2556
+ return null;
2557
+ }
2558
+ return { entitlement, remaining, percentRemaining, unlimited };
2559
+ }
2560
+ function secondsUntil5(instant, now) {
2561
+ if (!instant) return void 0;
2562
+ return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
2563
+ }
2564
+ function parseCopilotUserPayload(payload, now) {
2565
+ if (!isRecord3(payload)) return null;
2566
+ const snapshots = isRecord3(payload["quota_snapshots"]) ? payload["quota_snapshots"] : void 0;
2567
+ if (!snapshots) return null;
2568
+ const resetRaw = payload["quota_reset_date"];
2569
+ const resetsAt = typeof resetRaw === "string" && resetRaw.trim() && Number.isFinite(Date.parse(resetRaw)) ? new Date(Date.parse(resetRaw)).toISOString() : void 0;
2570
+ const windows = [];
2571
+ const premium = parseQuotaDetail(snapshots["premium_interactions"]);
2572
+ if (premium) {
2573
+ const usedPercent = premium.unlimited ? 0 : premium.entitlement > 0 ? Math.round(Math.min(100, (premium.entitlement - premium.remaining) / premium.entitlement * 100) * 10) / 10 : finiteNumber4(premium.percentRemaining) !== void 0 ? Math.round(Math.min(100, Math.max(0, 100 - premium.percentRemaining)) * 10) / 10 : null;
2574
+ if (usedPercent !== null) {
2575
+ windows.push({
2576
+ id: "thirty-day",
2577
+ label: "Monthly",
2578
+ scope: "all",
2579
+ usedPercent,
2580
+ windowMinutes: 30 * 24 * 60,
2581
+ ...resetsAt !== void 0 ? { resetsAt } : {},
2582
+ remainingSeconds: secondsUntil5(resetsAt, now),
2583
+ state: "fresh"
2584
+ });
2585
+ }
2586
+ }
2587
+ const chat = parseQuotaDetail(snapshots["chat"]);
2588
+ if (chat && !chat.unlimited && chat.entitlement > 0) {
2589
+ const usedPercent = Math.round(Math.min(100, (chat.entitlement - chat.remaining) / chat.entitlement * 100) * 10) / 10;
2590
+ windows.push({
2591
+ id: "chat-monthly",
2592
+ label: "Chat (monthly)",
2593
+ scope: "all",
2594
+ usedPercent,
2595
+ windowMinutes: 30 * 24 * 60,
2596
+ ...resetsAt !== void 0 ? { resetsAt } : {},
2597
+ remainingSeconds: secondsUntil5(resetsAt, now),
2598
+ state: "fresh"
2599
+ });
2600
+ }
2601
+ return windows.length > 0 ? windows : null;
2602
+ }
2603
+ function githubApiBase(tokens) {
2604
+ return (0, import_subscriptions6.copilotGitHubApiBase)(tokens.enterpriseUrl);
2605
+ }
2606
+ var CopilotAllowanceCollector = class {
2607
+ constructor(credentials, store = (0, import_AccountAllowanceStore5.getSharedAccountAllowanceStore)(), fetchImpl = (url, init, accountId) => (0, import_upstreamFetch5.fetchUpstream)(url, init, { providerId: "copilot", accountId, redactBodies: true }), now = Date.now) {
2608
+ this.credentials = credentials;
2609
+ this.store = store;
2610
+ this.fetchImpl = fetchImpl;
2611
+ this.now = now;
2612
+ }
2613
+ credentials;
2614
+ store;
2615
+ fetchImpl;
2616
+ now;
2617
+ inFlight = /* @__PURE__ */ new Map();
2618
+ async collectMany(accounts, options = {}) {
2619
+ const settled = await Promise.allSettled(
2620
+ accounts.map((account) => this.collect(account, options))
2621
+ );
2622
+ return settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
2623
+ }
2624
+ collect(account, options = {}) {
2625
+ const now = this.now();
2626
+ if (account.tokens.authMethod !== "oauth") {
2627
+ const existing = this.store.get("copilot", account.id, now);
2628
+ if (existing?.windows.every((window) => window.state === "unsupported")) {
2629
+ return Promise.resolve(existing);
2630
+ }
2631
+ const snapshot = this.unsupportedSnapshot(account.id, now);
2632
+ this.store.set(snapshot);
2633
+ return Promise.resolve(snapshot);
2634
+ }
2635
+ const cached = this.store.get("copilot", account.id, now);
2636
+ if (!options.force && cached && this.isCacheValid(cached, now, options.refreshAheadMs)) {
2637
+ return Promise.resolve(cached);
2638
+ }
2639
+ const running = this.inFlight.get(account.id);
2640
+ if (running) return running;
2641
+ const promise = this.fetchAccount(account.id, account.tokens).catch(() => this.failureSnapshot(account.id, "copilot_usage_request_failed", this.now())).finally(() => this.inFlight.delete(account.id));
2642
+ this.inFlight.set(account.id, promise);
2643
+ return promise;
2644
+ }
2645
+ isCacheValid(snapshot, now, refreshAheadMs) {
2646
+ if (snapshot.windows.every((window) => window.state === "unsupported")) return true;
2647
+ const expiresAt = snapshot.expiresAt ? Date.parse(snapshot.expiresAt) : 0;
2648
+ const ahead = typeof refreshAheadMs === "number" && Number.isFinite(refreshAheadMs) ? Math.max(0, refreshAheadMs) : 0;
2649
+ return Number.isFinite(expiresAt) && expiresAt > now + ahead;
2650
+ }
2651
+ async fetchAccount(accountId, tokens) {
2652
+ let accessToken = await this.credentials.getAccessTokenForAccount("copilot", accountId);
2653
+ if (!accessToken) return this.failureSnapshot(accountId, "copilot_usage_token_unavailable", this.now());
2654
+ let response = await this.request(accountId, accessToken, tokens);
2655
+ if (response.status === 401 || response.status === 403) {
2656
+ const refreshed = await this.credentials.refreshAccountToken("copilot", accountId);
2657
+ if (!refreshed) return this.failureSnapshot(accountId, "copilot_usage_unauthorized", this.now());
2658
+ accessToken = await this.credentials.getAccessTokenForAccount("copilot", accountId);
2659
+ if (!accessToken) return this.failureSnapshot(accountId, "copilot_usage_token_unavailable", this.now());
2660
+ response = await this.request(accountId, accessToken, tokens);
2661
+ if (response.status === 401 || response.status === 403) {
2662
+ return this.failureSnapshot(accountId, "copilot_usage_unauthorized", this.now());
2663
+ }
2664
+ }
2665
+ if (!response.ok) return this.failureSnapshot(accountId, "copilot_usage_http_error", this.now());
2666
+ let payload;
2667
+ try {
2668
+ payload = await response.json();
2669
+ } catch {
2670
+ return this.failureSnapshot(accountId, "copilot_usage_invalid_response", this.now());
2671
+ }
2672
+ const now = this.now();
2673
+ const windows = parseCopilotUserPayload(payload, now);
2674
+ const snapshot = {
2675
+ providerId: "copilot",
2676
+ accountId,
2677
+ source: "oauth-usage-api",
2678
+ observedAt: new Date(now).toISOString(),
2679
+ expiresAt: new Date(now + COPILOT_ALLOWANCE_CACHE_MS).toISOString(),
2680
+ windows: windows ?? [
2681
+ { id: "thirty-day", label: "Monthly", scope: "all", usedPercent: null, state: "unavailable" }
2682
+ ],
2683
+ ...windows ? {} : { lastErrorCode: "copilot_usage_invalid_response" }
2684
+ };
2685
+ this.store.set(snapshot);
2686
+ return snapshot;
2687
+ }
2688
+ request(accountId, accessToken, tokens) {
2689
+ return this.fetchImpl(`${githubApiBase(tokens)}/copilot_internal/user`, {
2690
+ method: "GET",
2691
+ headers: {
2692
+ Authorization: `Bearer ${accessToken}`,
2693
+ Accept: "application/json",
2694
+ "Content-Type": "application/json",
2695
+ ...import_subscriptions6.COPILOT_GITHUB_HEADERS
2696
+ },
2697
+ signal: AbortSignal.timeout(15e3)
2698
+ }, accountId);
2699
+ }
2700
+ failureSnapshot(accountId, code, now) {
2701
+ const existing = this.store.get("copilot", accountId, now);
2702
+ const snapshot = existing ? {
2703
+ ...existing,
2704
+ expiresAt: new Date(now + COPILOT_ALLOWANCE_CACHE_MS).toISOString(),
2705
+ windows: existing.windows.map((window) => ({
2706
+ ...window,
2707
+ state: window.state === "unsupported" ? "unsupported" : window.usedPercent !== null || window.resetsAt ? "stale" : "unavailable"
2708
+ })),
2709
+ lastErrorCode: code
2710
+ } : {
2711
+ providerId: "copilot",
2712
+ accountId,
2713
+ source: "oauth-usage-api",
2714
+ observedAt: new Date(now).toISOString(),
2715
+ expiresAt: new Date(now + COPILOT_ALLOWANCE_CACHE_MS).toISOString(),
2716
+ windows: [
2717
+ { id: "thirty-day", label: "Monthly", scope: "all", usedPercent: null, state: "unavailable" }
2718
+ ],
2719
+ lastErrorCode: code
2720
+ };
2721
+ this.store.set(snapshot);
2722
+ return snapshot;
2723
+ }
2724
+ unsupportedSnapshot(accountId, now) {
2725
+ return {
2726
+ providerId: "copilot",
2727
+ accountId,
2728
+ source: "oauth-usage-api",
2729
+ observedAt: new Date(now).toISOString(),
2730
+ windows: [
2731
+ { id: "thirty-day", label: "Monthly", scope: "all", usedPercent: null, state: "unsupported" }
2732
+ ],
2733
+ lastErrorCode: "copilot_usage_unsupported_auth"
2734
+ };
2735
+ }
2736
+ };
2737
+
2738
+ // src/allowance/GeminiAllowanceCollector.ts
2739
+ var import_GeminiCodeAssistProjectResolver = require("@omnicross/core/auth/GeminiCodeAssistProjectResolver");
2740
+ var import_AccountAllowanceStore6 = require("@omnicross/core/pipeline/AccountAllowanceStore");
2741
+ var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
2742
+ var import_transformers = require("@omnicross/core/transformer/transformers");
2743
+ var GEMINI_ALLOWANCE_CACHE_MS = 5 * 6e4;
2744
+ function isRecord4(value) {
2745
+ return !!value && typeof value === "object" && !Array.isArray(value);
2746
+ }
2747
+ function secondsUntil6(instant, now) {
2748
+ if (!instant) return void 0;
2749
+ return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
2750
+ }
2751
+ function parseGeminiQuotaPayload(payload, now) {
2752
+ if (!isRecord4(payload)) return null;
2753
+ const buckets = Array.isArray(payload["buckets"]) ? payload["buckets"] : [];
2754
+ const windows = [];
2755
+ const seen = /* @__PURE__ */ new Set();
2756
+ for (const raw of buckets) {
2757
+ if (!isRecord4(raw)) continue;
2758
+ const modelId = typeof raw["modelId"] === "string" && raw["modelId"].trim() ? raw["modelId"].trim() : void 0;
2759
+ const id = `gemini:${modelId ?? "all"}`;
2760
+ if (seen.has(id)) continue;
2761
+ seen.add(id);
2762
+ const fractionRaw = typeof raw["remainingFraction"] === "number" ? raw["remainingFraction"] : Number(raw["remainingFraction"]);
2763
+ const usedPercent = Number.isFinite(fractionRaw) ? Math.round(Math.min(100, Math.max(0, (1 - Math.min(1, Math.max(0, fractionRaw))) * 100)) * 10) / 10 : null;
2764
+ const resetRaw = typeof raw["resetTime"] === "string" && raw["resetTime"].trim() ? raw["resetTime"] : void 0;
2765
+ const resetsAt = resetRaw !== void 0 && Number.isFinite(Date.parse(resetRaw)) ? new Date(Date.parse(resetRaw)).toISOString() : void 0;
2766
+ windows.push({
2767
+ id,
2768
+ label: modelId ? `Gemini ${modelId}` : "Gemini quota",
2769
+ scope: modelId ? "model-family" : "all",
2770
+ ...modelId ? { modelFamily: modelId } : {},
2771
+ usedPercent,
2772
+ ...resetsAt !== void 0 ? { resetsAt } : {},
2773
+ remainingSeconds: secondsUntil6(resetsAt, now),
2774
+ state: "fresh"
2775
+ });
2776
+ }
2777
+ return windows.length > 0 ? windows : null;
2778
+ }
2779
+ var GeminiAllowanceCollector = class {
2780
+ constructor(credentials, store = (0, import_AccountAllowanceStore6.getSharedAccountAllowanceStore)(), fetchImpl = (url, init, accountId) => (0, import_upstreamFetch6.fetchUpstream)(url, init, { providerId: "gemini", accountId, redactBodies: true }), now = Date.now, projectResolver = (0, import_GeminiCodeAssistProjectResolver.getGeminiCodeAssistProjectResolver)()) {
2781
+ this.credentials = credentials;
2782
+ this.store = store;
2783
+ this.fetchImpl = fetchImpl;
2784
+ this.now = now;
2785
+ this.projectResolver = projectResolver;
2786
+ }
2787
+ credentials;
2788
+ store;
2789
+ fetchImpl;
2790
+ now;
2791
+ projectResolver;
2792
+ inFlight = /* @__PURE__ */ new Map();
2793
+ async collectMany(accounts, options = {}) {
2794
+ const settled = await Promise.allSettled(
2795
+ accounts.map((account) => this.collect(account, options))
2796
+ );
2797
+ return settled.flatMap((result) => result.status === "fulfilled" ? [result.value] : []);
2798
+ }
2799
+ collect(account, options = {}) {
2800
+ const now = this.now();
2801
+ if (account.tokens.authMethod !== "oauth") {
2802
+ const existing = this.store.get("gemini", account.id, now);
2803
+ if (existing?.windows.every((window) => window.state === "unsupported")) {
2804
+ return Promise.resolve(existing);
2805
+ }
2806
+ const snapshot = this.unsupportedSnapshot(account.id, now);
2807
+ this.store.set(snapshot);
2808
+ return Promise.resolve(snapshot);
2809
+ }
2810
+ const cached = this.store.get("gemini", account.id, now);
2811
+ if (!options.force && cached && this.isCacheValid(cached, now, options.refreshAheadMs)) {
2812
+ return Promise.resolve(cached);
2813
+ }
2814
+ const running = this.inFlight.get(account.id);
2815
+ if (running) return running;
2816
+ const promise = this.fetchAccount(account.id).catch(() => this.failureSnapshot(account.id, "gemini_usage_request_failed", this.now())).finally(() => this.inFlight.delete(account.id));
2817
+ this.inFlight.set(account.id, promise);
2818
+ return promise;
2819
+ }
2820
+ isCacheValid(snapshot, now, refreshAheadMs) {
2821
+ if (snapshot.windows.every((window) => window.state === "unsupported")) return true;
2822
+ const expiresAt = snapshot.expiresAt ? Date.parse(snapshot.expiresAt) : 0;
2823
+ const ahead = typeof refreshAheadMs === "number" && Number.isFinite(refreshAheadMs) ? Math.max(0, refreshAheadMs) : 0;
2824
+ return Number.isFinite(expiresAt) && expiresAt > now + ahead;
2825
+ }
2826
+ async fetchAccount(accountId) {
2827
+ let accessToken = await this.credentials.getAccessTokenForAccount("gemini", accountId);
2828
+ if (!accessToken) return this.failureSnapshot(accountId, "gemini_usage_token_unavailable", this.now());
2829
+ let project;
2830
+ try {
2831
+ project = await this.projectResolver.resolveProject(accessToken);
2832
+ } catch {
2833
+ project = void 0;
2834
+ }
2835
+ let response = await this.request(accountId, accessToken, project);
2836
+ if (response.status === 401 || response.status === 403) {
2837
+ const refreshed = await this.credentials.refreshAccountToken("gemini", accountId);
2838
+ if (!refreshed) return this.failureSnapshot(accountId, "gemini_usage_unauthorized", this.now());
2839
+ accessToken = await this.credentials.getAccessTokenForAccount("gemini", accountId);
2840
+ if (!accessToken) return this.failureSnapshot(accountId, "gemini_usage_token_unavailable", this.now());
2841
+ response = await this.request(accountId, accessToken, project);
2842
+ if (response.status === 401 || response.status === 403) {
2843
+ return this.failureSnapshot(accountId, "gemini_usage_unauthorized", this.now());
2844
+ }
2845
+ }
2846
+ if (!response.ok) return this.failureSnapshot(accountId, "gemini_usage_http_error", this.now());
2847
+ let payload;
2848
+ try {
2849
+ payload = await response.json();
2850
+ } catch {
2851
+ return this.failureSnapshot(accountId, "gemini_usage_invalid_response", this.now());
2015
2852
  }
2016
2853
  const now = this.now();
2017
- const windows = parseKimiUsagePayload(payload, now);
2854
+ const windows = parseGeminiQuotaPayload(payload, now);
2018
2855
  const snapshot = {
2019
- providerId: "kimi",
2856
+ providerId: "gemini",
2020
2857
  accountId,
2021
2858
  source: "oauth-usage-api",
2022
2859
  observedAt: new Date(now).toISOString(),
2023
- expiresAt: new Date(now + KIMI_ALLOWANCE_CACHE_MS).toISOString(),
2024
- windows: windows.length > 0 ? windows : [
2025
- { id: "five-hour", label: "5 hours", scope: "all", usedPercent: null, state: "unavailable" },
2026
- { id: "seven-day", label: "7 days", scope: "all", usedPercent: null, state: "unavailable" }
2860
+ expiresAt: new Date(now + GEMINI_ALLOWANCE_CACHE_MS).toISOString(),
2861
+ windows: windows ?? [
2862
+ { id: "gemini-quota", label: "Gemini quota", scope: "all", usedPercent: null, state: "unavailable" }
2027
2863
  ],
2028
- ...windows.length > 0 ? {} : { lastErrorCode: "kimi_usage_invalid_response" }
2864
+ ...windows ? {} : { lastErrorCode: "gemini_usage_invalid_response" }
2029
2865
  };
2030
2866
  this.store.set(snapshot);
2031
2867
  return snapshot;
2032
2868
  }
2033
- request(accountId, accessToken, tokens) {
2034
- return this.fetchImpl(KIMI_USAGE_URL, {
2035
- method: "GET",
2869
+ request(accountId, accessToken, project) {
2870
+ return this.fetchImpl(`${(0, import_transformers.resolveCodeAssistEndpoint)()}/v1internal:retrieveUserQuota`, {
2871
+ method: "POST",
2036
2872
  headers: {
2037
2873
  Authorization: `Bearer ${accessToken}`,
2038
2874
  Accept: "application/json",
2039
- ...(0, import_subscriptions3.kimiFingerprintHeaders)(tokens.deviceId)
2875
+ "Content-Type": "application/json",
2876
+ ...(0, import_transformers.getGeminiCliIdentityHeaders)()
2040
2877
  },
2878
+ body: JSON.stringify(project ? { project } : {}),
2041
2879
  signal: AbortSignal.timeout(15e3)
2042
2880
  }, accountId);
2043
2881
  }
2044
2882
  failureSnapshot(accountId, code, now) {
2045
- const existing = this.store.get("kimi", accountId, now);
2883
+ const existing = this.store.get("gemini", accountId, now);
2046
2884
  const snapshot = existing ? {
2047
2885
  ...existing,
2048
- expiresAt: new Date(now + KIMI_ALLOWANCE_CACHE_MS).toISOString(),
2886
+ expiresAt: new Date(now + GEMINI_ALLOWANCE_CACHE_MS).toISOString(),
2049
2887
  windows: existing.windows.map((window) => ({
2050
2888
  ...window,
2051
2889
  state: window.state === "unsupported" ? "unsupported" : window.usedPercent !== null || window.resetsAt ? "stale" : "unavailable"
2052
2890
  })),
2053
2891
  lastErrorCode: code
2054
2892
  } : {
2055
- providerId: "kimi",
2893
+ providerId: "gemini",
2056
2894
  accountId,
2057
2895
  source: "oauth-usage-api",
2058
2896
  observedAt: new Date(now).toISOString(),
2059
- expiresAt: new Date(now + KIMI_ALLOWANCE_CACHE_MS).toISOString(),
2897
+ expiresAt: new Date(now + GEMINI_ALLOWANCE_CACHE_MS).toISOString(),
2060
2898
  windows: [
2061
- { id: "five-hour", label: "5 hours", scope: "all", usedPercent: null, state: "unavailable" },
2062
- { id: "seven-day", label: "7 days", scope: "all", usedPercent: null, state: "unavailable" }
2899
+ { id: "gemini-quota", label: "Gemini quota", scope: "all", usedPercent: null, state: "unavailable" }
2063
2900
  ],
2064
2901
  lastErrorCode: code
2065
2902
  };
2066
2903
  this.store.set(snapshot);
2067
2904
  return snapshot;
2068
2905
  }
2069
- unsupportedSnapshot(accountId, now, code = "kimi_usage_unsupported_auth") {
2906
+ unsupportedSnapshot(accountId, now) {
2070
2907
  return {
2071
- providerId: "kimi",
2908
+ providerId: "gemini",
2072
2909
  accountId,
2073
2910
  source: "oauth-usage-api",
2074
2911
  observedAt: new Date(now).toISOString(),
2075
2912
  windows: [
2076
- { id: "five-hour", label: "5 hours", scope: "all", usedPercent: null, state: "unsupported" },
2077
- { id: "seven-day", label: "7 days", scope: "all", usedPercent: null, state: "unsupported" }
2913
+ { id: "gemini-quota", label: "Gemini quota", scope: "all", usedPercent: null, state: "unsupported" }
2078
2914
  ],
2079
- lastErrorCode: code
2915
+ lastErrorCode: "gemini_usage_unsupported_auth"
2080
2916
  };
2081
2917
  }
2082
2918
  };
2083
2919
 
2084
2920
  // src/allowance/OpenCodeGoAllowanceCollector.ts
2085
- var import_AccountAllowanceStore4 = require("@omnicross/core/pipeline/AccountAllowanceStore");
2086
- var import_upstreamFetch4 = require("@omnicross/core/pipeline/upstreamFetch");
2087
- var import_subscriptions4 = require("@omnicross/subscriptions");
2921
+ var import_AccountAllowanceStore7 = require("@omnicross/core/pipeline/AccountAllowanceStore");
2922
+ var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
2923
+ var import_subscriptions7 = require("@omnicross/subscriptions");
2088
2924
  var OPENCODEGO_ALLOWANCE_CACHE_MS = 5 * 6e4;
2089
2925
  var OPENCODEGO_DEFAULT_GO_BASE = "https://opencode.ai/zen/go";
2090
2926
  function finitePercent3(value) {
@@ -2097,7 +2933,7 @@ function isoInstant2(value) {
2097
2933
  const time = Date.parse(value);
2098
2934
  return Number.isFinite(time) ? new Date(time).toISOString() : void 0;
2099
2935
  }
2100
- function secondsUntil4(instant, now) {
2936
+ function secondsUntil7(instant, now) {
2101
2937
  if (!instant) return void 0;
2102
2938
  return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
2103
2939
  }
@@ -2112,12 +2948,12 @@ function windowFromPayload3(id, label, minutes, payload, now) {
2112
2948
  usedPercent,
2113
2949
  windowMinutes: minutes,
2114
2950
  ...resetsAt !== void 0 ? { resetsAt } : {},
2115
- remainingSeconds: secondsUntil4(resetsAt, now),
2951
+ remainingSeconds: secondsUntil7(resetsAt, now),
2116
2952
  state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
2117
2953
  };
2118
2954
  }
2119
2955
  var OpenCodeGoAllowanceCollector = class {
2120
- constructor(credentials, store = (0, import_AccountAllowanceStore4.getSharedAccountAllowanceStore)(), fetchImpl = (url, init, accountId) => (0, import_upstreamFetch4.fetchUpstream)(url, init, { providerId: "opencodego", accountId, redactBodies: true }), now = Date.now) {
2956
+ constructor(credentials, store = (0, import_AccountAllowanceStore7.getSharedAccountAllowanceStore)(), fetchImpl = (url, init, accountId) => (0, import_upstreamFetch7.fetchUpstream)(url, init, { providerId: "opencodego", accountId, redactBodies: true }), now = Date.now) {
2121
2957
  this.credentials = credentials;
2122
2958
  this.store = store;
2123
2959
  this.fetchImpl = fetchImpl;
@@ -2147,7 +2983,7 @@ var OpenCodeGoAllowanceCollector = class {
2147
2983
  async fetchAccount(account) {
2148
2984
  const apiKey = await this.credentials.getAccessTokenForAccount("opencodego", account.id);
2149
2985
  if (!apiKey) return this.failureSnapshot(account.id, this.now());
2150
- const base = account.tokens.baseUrl ? (0, import_subscriptions4.normalizeOpenCodeGoBaseUrl)(account.tokens.baseUrl) : OPENCODEGO_DEFAULT_GO_BASE;
2986
+ const base = account.tokens.baseUrl ? (0, import_subscriptions7.normalizeOpenCodeGoBaseUrl)(account.tokens.baseUrl) : OPENCODEGO_DEFAULT_GO_BASE;
2151
2987
  const response = await this.fetchImpl(`${base}/v1/usage`, {
2152
2988
  method: "GET",
2153
2989
  headers: { Authorization: `Bearer ${apiKey}`, Accept: "application/json" },
@@ -2222,7 +3058,7 @@ function codexUnavailable(accountId, now) {
2222
3058
  };
2223
3059
  }
2224
3060
  var AccountAllowanceService = class {
2225
- constructor(credentials, store = (0, import_AccountAllowanceStore5.getSharedAccountAllowanceStore)(), collector, codexCollector, kimiCollector, opencodegoCollector, now = Date.now) {
3061
+ constructor(credentials, store = (0, import_AccountAllowanceStore8.getSharedAccountAllowanceStore)(), collector, codexCollector, kimiCollector, opencodegoCollector, grokCollector, copilotCollector, geminiCollector, now = Date.now) {
2226
3062
  this.credentials = credentials;
2227
3063
  this.store = store;
2228
3064
  this.now = now;
@@ -2230,6 +3066,9 @@ var AccountAllowanceService = class {
2230
3066
  this.codexCollector = codexCollector ?? new CodexAllowanceCollector(credentials, store);
2231
3067
  this.kimiCollector = kimiCollector ?? new KimiAllowanceCollector(credentials, store);
2232
3068
  this.opencodegoCollector = opencodegoCollector ?? new OpenCodeGoAllowanceCollector(credentials, store);
3069
+ this.grokCollector = grokCollector ?? new GrokAllowanceCollector(credentials, store);
3070
+ this.copilotCollector = copilotCollector ?? new CopilotAllowanceCollector(credentials, store);
3071
+ this.geminiCollector = geminiCollector ?? new GeminiAllowanceCollector(credentials, store);
2233
3072
  }
2234
3073
  credentials;
2235
3074
  store;
@@ -2237,7 +3076,10 @@ var AccountAllowanceService = class {
2237
3076
  claudeCollector;
2238
3077
  codexCollector;
2239
3078
  kimiCollector;
3079
+ grokCollector;
3080
+ copilotCollector;
2240
3081
  opencodegoCollector;
3082
+ geminiCollector;
2241
3083
  /**
2242
3084
  * Read all/filtered snapshots. Claude's and Codex's five-minute caches are
2243
3085
  * refreshed lazily on read (Codex polls `/backend-api/wham/usage`; the
@@ -2271,11 +3113,29 @@ var AccountAllowanceService = class {
2271
3113
  (account) => !filter.accountId || account.id === filter.accountId
2272
3114
  );
2273
3115
  if (wantsOpenCodeGo) await this.opencodegoCollector.collectMany(opencodegoAccounts);
3116
+ const wantsGrok = !filter.providerId || filter.providerId === "grok";
3117
+ const grokAccounts = (config.grokAccounts ?? []).filter(
3118
+ (account) => !filter.accountId || account.id === filter.accountId
3119
+ );
3120
+ if (wantsGrok) await this.grokCollector.collectMany(grokAccounts);
3121
+ const wantsCopilot = !filter.providerId || filter.providerId === "copilot";
3122
+ const copilotAccounts = (config.copilotAccounts ?? []).filter(
3123
+ (account) => !filter.accountId || account.id === filter.accountId
3124
+ );
3125
+ if (wantsCopilot) await this.copilotCollector.collectMany(copilotAccounts);
3126
+ const wantsGemini = !filter.providerId || filter.providerId === "gemini";
3127
+ const geminiAccounts = (config.geminiAccounts ?? []).filter(
3128
+ (account) => !filter.accountId || account.id === filter.accountId
3129
+ );
3130
+ if (wantsGemini) await this.geminiCollector.collectMany(geminiAccounts);
2274
3131
  const known = /* @__PURE__ */ new Set();
2275
3132
  if (wantsClaude) for (const account of claudeAccounts) known.add(`claude\0${account.id}`);
2276
3133
  if (wantsCodex) for (const account of codexAccounts) known.add(`codex\0${account.id}`);
2277
3134
  if (wantsKimi) for (const account of kimiAccounts) known.add(`kimi\0${account.id}`);
2278
3135
  if (wantsOpenCodeGo) for (const account of opencodegoAccounts) known.add(`opencodego\0${account.id}`);
3136
+ if (wantsGrok) for (const account of grokAccounts) known.add(`grok\0${account.id}`);
3137
+ if (wantsCopilot) for (const account of copilotAccounts) known.add(`copilot\0${account.id}`);
3138
+ if (wantsGemini) for (const account of geminiAccounts) known.add(`gemini\0${account.id}`);
2279
3139
  return this.store.list(filter).filter((snapshot) => known.has(`${snapshot.providerId}\0${snapshot.accountId}`));
2280
3140
  }
2281
3141
  knownAccounts(config) {
@@ -2283,7 +3143,10 @@ var AccountAllowanceService = class {
2283
3143
  ...(config.claudeAccounts ?? []).map((account) => ({ providerId: "claude", accountId: account.id })),
2284
3144
  ...(config.codexAccounts ?? []).map((account) => ({ providerId: "codex", accountId: account.id })),
2285
3145
  ...(config.kimiAccounts ?? []).map((account) => ({ providerId: "kimi", accountId: account.id })),
2286
- ...(config.opencodegoAccounts ?? []).map((account) => ({ providerId: "opencodego", accountId: account.id }))
3146
+ ...(config.opencodegoAccounts ?? []).map((account) => ({ providerId: "opencodego", accountId: account.id })),
3147
+ ...(config.grokAccounts ?? []).map((account) => ({ providerId: "grok", accountId: account.id })),
3148
+ ...(config.copilotAccounts ?? []).map((account) => ({ providerId: "copilot", accountId: account.id })),
3149
+ ...(config.geminiAccounts ?? []).map((account) => ({ providerId: "gemini", accountId: account.id }))
2287
3150
  ];
2288
3151
  }
2289
3152
  /** Force-refresh Claude usage for one account or every stored Claude account. */
@@ -2326,6 +3189,33 @@ var AccountAllowanceService = class {
2326
3189
  );
2327
3190
  return this.kimiCollector.collectMany(accounts, { force: true });
2328
3191
  }
3192
+ /** Force-refresh Copilot usage (copilot_internal/user) for one/all accounts. */
3193
+ async refreshCopilot(accountId) {
3194
+ const config = await this.credentials.getFullConfig();
3195
+ this.store.pruneToKnownAccounts(this.knownAccounts(config));
3196
+ const accounts = (config.copilotAccounts ?? []).filter(
3197
+ (account) => !accountId || account.id === accountId
3198
+ );
3199
+ return this.copilotCollector.collectMany(accounts, { force: true });
3200
+ }
3201
+ /** Force-refresh Grok usage (CLI billing proxy) for one/all accounts. */
3202
+ async refreshGrok(accountId) {
3203
+ const config = await this.credentials.getFullConfig();
3204
+ this.store.pruneToKnownAccounts(this.knownAccounts(config));
3205
+ const accounts = (config.grokAccounts ?? []).filter(
3206
+ (account) => !accountId || account.id === accountId
3207
+ );
3208
+ return this.grokCollector.collectMany(accounts, { force: true });
3209
+ }
3210
+ /** Force-refresh Gemini usage (Code Assist retrieveUserQuota) for one/all accounts. */
3211
+ async refreshGemini(accountId) {
3212
+ const config = await this.credentials.getFullConfig();
3213
+ this.store.pruneToKnownAccounts(this.knownAccounts(config));
3214
+ const accounts = (config.geminiAccounts ?? []).filter(
3215
+ (account) => !accountId || account.id === accountId
3216
+ );
3217
+ return this.geminiCollector.collectMany(accounts, { force: true });
3218
+ }
2329
3219
  /**
2330
3220
  * Keep Claude + Codex + Kimi snapshots warm for allowance-aware routing. All
2331
3221
  * collectors preserve their cache + per-account in-flight coalescing; a tick
@@ -2340,6 +3230,9 @@ var AccountAllowanceService = class {
2340
3230
  await this.codexCollector.collectMany(config.codexAccounts ?? [], { refreshAheadMs });
2341
3231
  await this.kimiCollector.collectMany(config.kimiAccounts ?? [], { refreshAheadMs });
2342
3232
  await this.opencodegoCollector.collectMany(config.opencodegoAccounts ?? [], { refreshAheadMs });
3233
+ await this.grokCollector.collectMany(config.grokAccounts ?? [], { refreshAheadMs });
3234
+ await this.copilotCollector.collectMany(config.copilotAccounts ?? [], { refreshAheadMs });
3235
+ await this.geminiCollector.collectMany(config.geminiAccounts ?? [], { refreshAheadMs });
2343
3236
  }
2344
3237
  /** Remove a cache row as soon as an account is deleted by the admin path. */
2345
3238
  removeAccountSnapshot(providerId, accountId) {
@@ -2434,7 +3327,7 @@ var ClaudeAllowanceRefreshScheduler = class {
2434
3327
  var import_node_crypto4 = require("crypto");
2435
3328
  var import_node_fs6 = require("fs");
2436
3329
  var import_node_path6 = require("path");
2437
- var import_AccountAllowanceStore6 = require("@omnicross/core/pipeline/AccountAllowanceStore");
3330
+ var import_AccountAllowanceStore9 = require("@omnicross/core/pipeline/AccountAllowanceStore");
2438
3331
  var ACCOUNT_ALLOWANCE_CACHE_VERSION = 1;
2439
3332
  var MAX_PERSISTED_ALLOWANCE_SNAPSHOTS = 256;
2440
3333
  var MAX_ALLOWANCE_CACHE_BYTES = 1e6;
@@ -2463,7 +3356,7 @@ var JsonAccountAllowancePersistence = class {
2463
3356
  save(snapshots) {
2464
3357
  const rows = [];
2465
3358
  for (const snapshot of snapshots) {
2466
- const normalized2 = (0, import_AccountAllowanceStore6.normalizeAccountAllowanceSnapshot)(snapshot);
3359
+ const normalized2 = (0, import_AccountAllowanceStore9.normalizeAccountAllowanceSnapshot)(snapshot);
2467
3360
  if (!normalized2) continue;
2468
3361
  rows.push(normalized2);
2469
3362
  if (rows.length >= MAX_PERSISTED_ALLOWANCE_SNAPSHOTS) break;
@@ -2739,7 +3632,8 @@ var import_outbound_api5 = require("@omnicross/core/outbound-api");
2739
3632
  var import_image_generation_types = require("@omnicross/contracts/image-generation-types");
2740
3633
  var import_AccountAllowanceScheduling2 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
2741
3634
  var import_SubscriptionAccountHealth = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
2742
- var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
3635
+ var import_upstreamFetch10 = require("@omnicross/core/pipeline/upstreamFetch");
3636
+ var import_core3 = require("@omnicross/core");
2743
3637
 
2744
3638
  // src/image-generation/imagesConfigValidation.ts
2745
3639
  var import_outbound_api = require("@omnicross/core/outbound-api");
@@ -3035,6 +3929,7 @@ async function applyServerConfigTransaction(current, next, deps) {
3035
3929
 
3036
3930
  // src/config.ts
3037
3931
  var import_node_fs8 = require("fs");
3932
+ var import_core = require("@omnicross/core");
3038
3933
  var DEFAULT_ADMIN_PORT = 8766;
3039
3934
  function validateAdmin(raw) {
3040
3935
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
@@ -3091,6 +3986,18 @@ var FORMAT_AXIS_TRANSFORMERS = [
3091
3986
  "openai-response",
3092
3987
  "gemini-code-assist"
3093
3988
  ];
3989
+ function validateExtraHeaders(raw) {
3990
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
3991
+ const reserved = import_core.EXTRA_HEADER_RESERVED_NAMES;
3992
+ const out = {};
3993
+ for (const [name, value] of Object.entries(raw)) {
3994
+ if (!name.trim()) continue;
3995
+ if (typeof value !== "string") continue;
3996
+ if (reserved.has(name.toLowerCase())) continue;
3997
+ out[name] = value;
3998
+ }
3999
+ return Object.keys(out).length > 0 ? out : void 0;
4000
+ }
3094
4001
  function validateApiKeys(raw) {
3095
4002
  if (!Array.isArray(raw)) return void 0;
3096
4003
  const out = [];
@@ -3304,6 +4211,9 @@ function validateProvider(raw, index) {
3304
4211
  apiVersion,
3305
4212
  maxConcurrency,
3306
4213
  modelsEndpoint,
4214
+ // Static extra headers: load-guard (reserved names dropped), collapse-to-
4215
+ // undefined; enforced by the outbound header funnel + admin probes.
4216
+ extraHeaders: validateExtraHeaders(p["extraHeaders"]),
3307
4217
  // Provider transformer config (app-parity child 5): load-guard, collapse-to-
3308
4218
  // undefined; non-secret; ENFORCED via resolveTransformerChain (parity-2 child 2).
3309
4219
  // Format-axis entries are stripped by `migrateFormatAxis` — `use[]` is the
@@ -3373,7 +4283,7 @@ var import_node_crypto6 = require("crypto");
3373
4283
  var import_node_fs10 = require("fs");
3374
4284
  var import_node_os3 = require("os");
3375
4285
  var import_node_path10 = require("path");
3376
- var import_core = require("@omnicross/core");
4286
+ var import_core2 = require("@omnicross/core");
3377
4287
 
3378
4288
  // src/integrations/codexAuthHelper.ts
3379
4289
  var import_node_path8 = require("path");
@@ -3854,7 +4764,7 @@ var IntegrationManager = class {
3854
4764
  if (!secret) {
3855
4765
  throw new IntegrationConflictError("The selected access key cannot be revealed and cannot power a CLI integration.");
3856
4766
  }
3857
- const effective = [...(0, import_core.effectiveOutboundPermissions)(row.allowedEndpoints)];
4767
+ const effective = [...(0, import_core2.effectiveOutboundPermissions)(row.allowedEndpoints)];
3858
4768
  const previousPermissions = row.allowedEndpoints === void 0 ? [...effective] : [...row.allowedEndpoints];
3859
4769
  const nextPermissions = [...effective];
3860
4770
  for (const required of REQUIRED_PERMISSIONS[client]) {
@@ -3952,7 +4862,7 @@ var IntegrationManager = class {
3952
4862
  return { binding, row, secret, created: false };
3953
4863
  }
3954
4864
  async createManagedClientKey(client, state) {
3955
- const created = await (0, import_core.createIntegrationKey)(
4865
+ const created = await (0, import_core2.createIntegrationKey)(
3956
4866
  this.options.keyDb,
3957
4867
  `Omnicross ${displayClient(client)} integration`,
3958
4868
  [...REQUIRED_PERMISSIONS[client]]
@@ -4044,7 +4954,7 @@ var IntegrationManager = class {
4044
4954
  const row = rows.find((candidate) => candidate.id === keyId);
4045
4955
  if (!row) return { usable: false, message: "The bound access key no longer exists." };
4046
4956
  const secret = legacy?.secret ?? await this.options.keyDb.outboundApiKeysReveal(keyId) ?? void 0;
4047
- const allowedEndpoints = [...(0, import_core.effectiveOutboundPermissions)(row.allowedEndpoints)];
4957
+ const allowedEndpoints = [...(0, import_core2.effectiveOutboundPermissions)(row.allowedEndpoints)];
4048
4958
  const status = {
4049
4959
  id: row.id,
4050
4960
  name: row.name,
@@ -4088,7 +4998,7 @@ var IntegrationManager = class {
4088
4998
  }
4089
4999
  };
4090
5000
  function hasRequiredPermissions(row, client) {
4091
- const allowed = (0, import_core.effectiveOutboundPermissions)(row.allowedEndpoints);
5001
+ const allowed = (0, import_core2.effectiveOutboundPermissions)(row.allowedEndpoints);
4092
5002
  return REQUIRED_PERMISSIONS[client].every((permission) => allowed.includes(permission));
4093
5003
  }
4094
5004
  function samePermissions(a, b) {
@@ -4257,7 +5167,10 @@ function mapPresetToProvider(preset, opts) {
4257
5167
  apiFormat: resolved.format,
4258
5168
  baseUrl: opts.baseUrlOverride ?? preset.api_base_url,
4259
5169
  apiKey: opts.key,
4260
- models: Array.isArray(preset.models) ? preset.models : void 0
5170
+ models: Array.isArray(preset.models) ? preset.models : void 0,
5171
+ // Static identity headers (e.g. the Cline client set) survive the mapping —
5172
+ // the CLI-seeded row needs them as much as an admin-API-created one.
5173
+ extraHeaders: preset.extraHeaders
4261
5174
  };
4262
5175
  return { provider };
4263
5176
  }
@@ -4282,7 +5195,8 @@ function listMappablePresets() {
4282
5195
  description: preset.description,
4283
5196
  features: preset.features,
4284
5197
  website: preset.website,
4285
- modelsEndpoint: preset.modelsEndpoint
5198
+ modelsEndpoint: preset.modelsEndpoint,
5199
+ extraHeaders: preset.extraHeaders
4286
5200
  });
4287
5201
  }
4288
5202
  return { mappable, excluded };
@@ -4372,11 +5286,11 @@ function preserveOutboundProxySecrets(incoming, current) {
4372
5286
  }
4373
5287
 
4374
5288
  // src/proxy/upstreamProxyResolver.ts
4375
- var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
5289
+ var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
4376
5290
  var serverProxy;
4377
5291
  function setServerProxyConfig(proxy) {
4378
5292
  serverProxy = proxy;
4379
- (0, import_upstreamFetch5.bumpUpstreamProxyGeneration)();
5293
+ (0, import_upstreamFetch8.bumpUpstreamProxyGeneration)();
4380
5294
  }
4381
5295
  function getServerProxyConfig() {
4382
5296
  return serverProxy;
@@ -4444,7 +5358,7 @@ function createUpstreamProxyResolver(src = {}) {
4444
5358
  }
4445
5359
 
4446
5360
  // src/admin/accountsOAuth.ts
4447
- var import_subscriptions5 = require("@omnicross/subscriptions");
5361
+ var import_subscriptions8 = require("@omnicross/subscriptions");
4448
5362
 
4449
5363
  // src/admin/accountsWrite.ts
4450
5364
  var VALID_PROVIDER_IDS = [
@@ -4452,7 +5366,9 @@ var VALID_PROVIDER_IDS = [
4452
5366
  "codex",
4453
5367
  "gemini",
4454
5368
  "opencodego",
4455
- "kimi"
5369
+ "kimi",
5370
+ "grok",
5371
+ "copilot"
4456
5372
  ];
4457
5373
  function asSubscriptionProviderId(id) {
4458
5374
  return VALID_PROVIDER_IDS.includes(id) ? id : null;
@@ -4600,6 +5516,40 @@ function validateKimi(body) {
4600
5516
  copyOptional(out, body, ["accessToken", "refreshToken", "expiresAt", "accountId", "deviceId", "lastRefreshedAt", "errorMessage"]);
4601
5517
  return out;
4602
5518
  }
5519
+ function validateGrok(body) {
5520
+ const authMethod = str(body["authMethod"]);
5521
+ const status = str(body["status"]);
5522
+ if (!authMethod || !OAUTH_AUTH_METHODS.has(authMethod)) return null;
5523
+ if (!status || !TOKEN_STATUSES.has(status)) return null;
5524
+ const out = {
5525
+ authMethod,
5526
+ status
5527
+ };
5528
+ copyOptional(out, body, ["accessToken", "refreshToken", "expiresAt", "accountId", "lastRefreshedAt", "errorMessage"]);
5529
+ return out;
5530
+ }
5531
+ function validateCopilot(body) {
5532
+ const authMethod = str(body["authMethod"]);
5533
+ const status = str(body["status"]);
5534
+ if (!authMethod || !OAUTH_AUTH_METHODS.has(authMethod)) return null;
5535
+ if (!status || !TOKEN_STATUSES.has(status)) return null;
5536
+ const out = {
5537
+ authMethod,
5538
+ status
5539
+ };
5540
+ copyOptional(out, body, [
5541
+ "accessToken",
5542
+ "refreshToken",
5543
+ "expiresAt",
5544
+ "accountId",
5545
+ "email",
5546
+ "apiEndpoint",
5547
+ "enterpriseUrl",
5548
+ "lastRefreshedAt",
5549
+ "errorMessage"
5550
+ ]);
5551
+ return out;
5552
+ }
4603
5553
  function validateOpenCodeGo(body) {
4604
5554
  const authMethod = str(body["authMethod"]);
4605
5555
  const status = str(body["status"]);
@@ -4637,6 +5587,10 @@ function validateTokenBody(providerId, body) {
4637
5587
  return validateOpenCodeGo(body);
4638
5588
  case "kimi":
4639
5589
  return validateKimi(body);
5590
+ case "grok":
5591
+ return validateGrok(body);
5592
+ case "copilot":
5593
+ return validateCopilot(body);
4640
5594
  default:
4641
5595
  return null;
4642
5596
  }
@@ -4666,37 +5620,37 @@ async function statusEntryFor(reader, providerId) {
4666
5620
 
4667
5621
  // src/admin/accountsOAuth.ts
4668
5622
  var OAUTH_HTTP_PROVIDERS = /* @__PURE__ */ new Set(["claude", "gemini"]);
4669
- function err3(status, message) {
5623
+ function err5(status, message) {
4670
5624
  return { status, body: { error: { type: "admin_api_error", message } } };
4671
5625
  }
4672
5626
  function handleOAuthStart(providerId, deps) {
4673
5627
  if (!OAUTH_HTTP_PROVIDERS.has(providerId)) {
4674
- return err3(400, `oauth not available for provider '${providerId}'`);
5628
+ return err5(400, `oauth not available for provider '${providerId}'`);
4675
5629
  }
4676
- const flow = providerId === "claude" ? import_subscriptions5.claudeOAuth : import_subscriptions5.geminiOAuth;
5630
+ const flow = providerId === "claude" ? import_subscriptions8.claudeOAuth : import_subscriptions8.geminiOAuth;
4677
5631
  const { authUrl, codeVerifier, state } = flow.generateAuthParams();
4678
5632
  const sessionId = deps.oauthSessions.put({ providerId, codeVerifier, state });
4679
5633
  return { status: 200, body: { authUrl, sessionId } };
4680
5634
  }
4681
5635
  async function handleOAuthComplete(providerId, body, deps) {
4682
5636
  if (!OAUTH_HTTP_PROVIDERS.has(providerId)) {
4683
- return err3(400, `oauth not available for provider '${providerId}'`);
5637
+ return err5(400, `oauth not available for provider '${providerId}'`);
4684
5638
  }
4685
5639
  const sessionId = typeof body["sessionId"] === "string" ? body["sessionId"] : "";
4686
5640
  const rawCode = typeof body["code"] === "string" ? body["code"] : "";
4687
- if (!sessionId) return err3(400, "oauth complete requires { sessionId }");
4688
- if (!rawCode) return err3(400, "oauth complete requires { code }");
5641
+ if (!sessionId) return err5(400, "oauth complete requires { sessionId }");
5642
+ if (!rawCode) return err5(400, "oauth complete requires { code }");
4689
5643
  const session = deps.oauthSessions.peek(sessionId);
4690
- if (!session) return err3(410, "oauth session is unknown, expired, or already used");
5644
+ if (!session) return err5(410, "oauth session is unknown, expired, or already used");
4691
5645
  if (session.providerId !== providerId) {
4692
- return err3(400, `oauth session does not match provider '${providerId}'`);
5646
+ return err5(400, `oauth session does not match provider '${providerId}'`);
4693
5647
  }
4694
5648
  let code = rawCode.trim();
4695
5649
  if (providerId === "claude") {
4696
5650
  const [splitCode, pastedState] = code.split("#");
4697
- if (!splitCode) return err3(400, "no authorization code was provided");
5651
+ if (!splitCode) return err5(400, "no authorization code was provided");
4698
5652
  if (pastedState && pastedState !== session.state) {
4699
- return err3(400, "oauth state did not match (possible CSRF) \u2014 aborting");
5653
+ return err5(400, "oauth state did not match (possible CSRF) \u2014 aborting");
4700
5654
  }
4701
5655
  code = splitCode;
4702
5656
  }
@@ -4706,7 +5660,7 @@ async function handleOAuthComplete(providerId, body, deps) {
4706
5660
  block = providerId === "claude" ? await exchangeClaude(code, session.codeVerifier, session.state, exchangeFetch) : await exchangeGemini(code, session.codeVerifier, exchangeFetch);
4707
5661
  } catch (exchangeError) {
4708
5662
  const reason = exchangeError instanceof Error ? exchangeError.message : "token exchange failed";
4709
- return err3(502, `oauth token exchange failed for '${providerId}': ${reason}`);
5663
+ return err5(502, `oauth token exchange failed for '${providerId}': ${reason}`);
4710
5664
  }
4711
5665
  deps.oauthSessions.consume(sessionId);
4712
5666
  const label = typeof body["label"] === "string" && body["label"].trim() ? body["label"].trim() : void 0;
@@ -4715,7 +5669,7 @@ async function handleOAuthComplete(providerId, body, deps) {
4715
5669
  return { status: 200, body: status ? { account: status } : { ok: true } };
4716
5670
  }
4717
5671
  async function exchangeClaude(code, codeVerifier, state, exchangeFetch) {
4718
- const result = await import_subscriptions5.claudeOAuth.exchangeCodeForTokens(
5672
+ const result = await import_subscriptions8.claudeOAuth.exchangeCodeForTokens(
4719
5673
  { authorizationCode: code, codeVerifier, state },
4720
5674
  exchangeFetch
4721
5675
  );
@@ -4731,7 +5685,7 @@ async function exchangeClaude(code, codeVerifier, state, exchangeFetch) {
4731
5685
  };
4732
5686
  }
4733
5687
  async function exchangeGemini(code, codeVerifier, exchangeFetch) {
4734
- const result = await import_subscriptions5.geminiOAuth.exchangeCodeForTokens(code, codeVerifier, exchangeFetch);
5688
+ const result = await import_subscriptions8.geminiOAuth.exchangeCodeForTokens(code, codeVerifier, exchangeFetch);
4735
5689
  const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
4736
5690
  return {
4737
5691
  authMethod: "oauth",
@@ -5036,8 +5990,8 @@ function errBody(message) {
5036
5990
  return { error: { type: "admin_api_error", message } };
5037
5991
  }
5038
5992
  var defaultCommandRunner = (command) => new Promise((resolve11) => {
5039
- (0, import_node_child_process.exec)(command, { timeout: 18e4 }, (err6, _stdout, stderr) => {
5040
- if (err6) resolve11({ ok: false, error: stderr.trim() || err6.message });
5993
+ (0, import_node_child_process.exec)(command, { timeout: 18e4 }, (err8, _stdout, stderr) => {
5994
+ if (err8) resolve11({ ok: false, error: stderr.trim() || err8.message });
5041
5995
  else resolve11({ ok: true });
5042
5996
  });
5043
5997
  });
@@ -5083,8 +6037,8 @@ async function handleCliLaunch(cli, body, ctx) {
5083
6037
  providerId: typeof body["providerId"] === "string" ? body["providerId"] : void 0,
5084
6038
  model: typeof body["model"] === "string" ? body["model"] : void 0
5085
6039
  });
5086
- } catch (err6) {
5087
- return { status: 400, body: errBody(err6 instanceof Error ? err6.message : "no launch target") };
6040
+ } catch (err8) {
6041
+ return { status: 400, body: errBody(err8 instanceof Error ? err8.message : "no launch target") };
5088
6042
  }
5089
6043
  const id = (0, import_node_crypto7.randomUUID)();
5090
6044
  let leaseId2;
@@ -5112,9 +6066,9 @@ async function handleCliLaunch(cli, body, ctx) {
5112
6066
  } else {
5113
6067
  launch = await buildLaunchEnv(cli, ctx.llmConfig, target);
5114
6068
  }
5115
- } catch (err6) {
5116
- const status = err6 instanceof import_provider_proxy2.RouteLeaseError ? err6.status : 400;
5117
- return { status, body: errBody(err6 instanceof Error ? err6.message : "failed to build launch env") };
6069
+ } catch (err8) {
6070
+ const status = err8 instanceof import_provider_proxy2.RouteLeaseError ? err8.status : 400;
6071
+ return { status, body: errBody(err8 instanceof Error ? err8.message : "failed to build launch env") };
5118
6072
  }
5119
6073
  const cwd = typeof body["cwd"] === "string" && body["cwd"].trim() ? body["cwd"].trim() : void 0;
5120
6074
  const opener = ctx.opener ?? defaultTerminalOpener;
@@ -5142,9 +6096,9 @@ async function handleCliLaunch(cli, body, ctx) {
5142
6096
  onFailure: onSessionEnd
5143
6097
  });
5144
6098
  if (cleanup) openerCleanup = cleanup;
5145
- } catch (err6) {
6099
+ } catch (err8) {
5146
6100
  onSessionEnd();
5147
- return { status: 500, body: errBody(err6 instanceof Error ? err6.message : "failed to open terminal") };
6101
+ return { status: 500, body: errBody(err8 instanceof Error ? err8.message : "failed to open terminal") };
5148
6102
  }
5149
6103
  if (ended) {
5150
6104
  openerCleanup?.();
@@ -5399,7 +6353,7 @@ async function runSearchLiveChecks(contributions, now = () => (/* @__PURE__ */ n
5399
6353
  }
5400
6354
 
5401
6355
  // src/search/SearchAssembly.ts
5402
- var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
6356
+ var import_upstreamFetch9 = require("@omnicross/core/pipeline/upstreamFetch");
5403
6357
  var import_search = require("@omnicross/core/search");
5404
6358
  var import_api2 = require("@omnicross/core/search/api");
5405
6359
  var import_http2 = require("@omnicross/core/search/http");
@@ -5417,7 +6371,7 @@ function searchPolicyFrom(config) {
5417
6371
  };
5418
6372
  }
5419
6373
  function resolveSearchUpstreamDispatcher(url) {
5420
- return (0, import_upstreamFetch6.resolveUpstreamDispatcher)({ url });
6374
+ return (0, import_upstreamFetch9.resolveUpstreamDispatcher)({ url });
5421
6375
  }
5422
6376
  var searchUpstreamProxyConfig = createUpstreamProxyResolver();
5423
6377
  function resolveSearchUpstreamProxyConfig(url) {
@@ -5699,7 +6653,7 @@ async function handleSearchQuery(req, res, deps) {
5699
6653
  // src/admin/searchAdminView.ts
5700
6654
  var API_KEY_PROVIDERS = /* @__PURE__ */ new Set(["tavily", "jina", "zhipu", "z.ai"]);
5701
6655
  var BASIC_AUTH_PROVIDERS = /* @__PURE__ */ new Set(["searxng"]);
5702
- function isRecord2(value) {
6656
+ function isRecord5(value) {
5703
6657
  return value !== null && typeof value === "object" && !Array.isArray(value);
5704
6658
  }
5705
6659
  function redactSearchServerConfig(search) {
@@ -5749,13 +6703,13 @@ function resolveSecretField(entry, field, stored) {
5749
6703
  else delete entry[field];
5750
6704
  }
5751
6705
  function preserveSearchSecrets(incoming, current) {
5752
- if (!isRecord2(incoming)) return incoming;
6706
+ if (!isRecord5(incoming)) return incoming;
5753
6707
  const section = { ...incoming };
5754
6708
  const providersValue = section["providers"];
5755
- if (!isRecord2(providersValue)) return section;
6709
+ if (!isRecord5(providersValue)) return section;
5756
6710
  const providers = {};
5757
6711
  for (const [id, entryValue] of Object.entries(providersValue)) {
5758
- if (!isRecord2(entryValue)) {
6712
+ if (!isRecord5(entryValue)) {
5759
6713
  providers[id] = entryValue;
5760
6714
  continue;
5761
6715
  }
@@ -5833,7 +6787,7 @@ function parseKeyPolicyBody(body) {
5833
6787
  var ENDPOINTS = /* @__PURE__ */ new Set(["chat", "responses", "messages", "gemini"]);
5834
6788
  var TARGET_KINDS = /* @__PURE__ */ new Set(["account", "account-group", "account-pool", "provider"]);
5835
6789
  var FALLBACKS = /* @__PURE__ */ new Set(["next", "fail", "global"]);
5836
- function isRecord3(value) {
6790
+ function isRecord6(value) {
5837
6791
  return !!value && typeof value === "object" && !Array.isArray(value);
5838
6792
  }
5839
6793
  function nonBlank(value) {
@@ -5853,7 +6807,7 @@ function validateGatewayBindingsSegment(patch) {
5853
6807
  const ids = /* @__PURE__ */ new Set();
5854
6808
  raw.forEach((entry, index) => {
5855
6809
  const path2 = `bindings[${index}]`;
5856
- if (!isRecord3(entry)) {
6810
+ if (!isRecord6(entry)) {
5857
6811
  errors.push(`${path2} must be an object`);
5858
6812
  return;
5859
6813
  }
@@ -5882,12 +6836,12 @@ function validateGatewayBindingsSegment(patch) {
5882
6836
  } else if (entry.modelMappings.length > 100) {
5883
6837
  errors.push(`${path2}.modelMappings cannot contain more than 100 entries`);
5884
6838
  } else if (entry.modelMappings.some(
5885
- (mapping) => !isRecord3(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
6839
+ (mapping) => !isRecord6(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
5886
6840
  )) {
5887
6841
  errors.push(`${path2}.modelMappings must contain non-empty source and target strings`);
5888
6842
  }
5889
6843
  }
5890
- if (!isRecord3(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
6844
+ if (!isRecord6(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
5891
6845
  errors.push(`${path2}.target is invalid`);
5892
6846
  } else {
5893
6847
  if (!nonBlank(entry.target.providerId)) errors.push(`${path2}.target.providerId is required`);
@@ -5902,7 +6856,7 @@ function validateGatewayBindingsSegment(patch) {
5902
6856
  }
5903
6857
  }
5904
6858
  if (entry.modelMap !== void 0) {
5905
- if (!isRecord3(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
6859
+ if (!isRecord6(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
5906
6860
  errors.push(`${path2}.modelMap must contain string values`);
5907
6861
  }
5908
6862
  }
@@ -6185,7 +7139,9 @@ var PROVIDER_KEYS = {
6185
7139
  accounts: "opencodegoAccounts",
6186
7140
  active: "activeOpencodegoAccountId"
6187
7141
  },
6188
- kimi: { block: "kimi", accounts: "kimiAccounts", active: "activeKimiAccountId" }
7142
+ kimi: { block: "kimi", accounts: "kimiAccounts", active: "activeKimiAccountId" },
7143
+ grok: { block: "grok", accounts: "grokAccounts", active: "activeGrokAccountId" },
7144
+ copilot: { block: "copilot", accounts: "copilotAccounts", active: "activeCopilotAccountId" }
6189
7145
  };
6190
7146
  function clone(value) {
6191
7147
  return JSON.parse(JSON.stringify(value));
@@ -6707,7 +7663,7 @@ async function applyImport(packString, passphrase, mode, deps, parseProviderInpu
6707
7663
  }
6708
7664
 
6709
7665
  // src/admin/adminMigration.ts
6710
- function err4(status, message) {
7666
+ function err6(status, message) {
6711
7667
  return { status, body: { error: { type: "admin_api_error", message } } };
6712
7668
  }
6713
7669
  async function handleExport(body, deps) {
@@ -6717,30 +7673,30 @@ async function handleExport(body, deps) {
6717
7673
  return { status: 200, body: { pack, version: BUNDLE_VERSION } };
6718
7674
  } catch (error) {
6719
7675
  if (error instanceof WeakPassphraseError) {
6720
- return err4(400, error.message);
7676
+ return err6(400, error.message);
6721
7677
  }
6722
- return err4(500, "failed to build the migration pack");
7678
+ return err6(500, "failed to build the migration pack");
6723
7679
  }
6724
7680
  }
6725
7681
  async function handleImport(body, deps) {
6726
7682
  const blob = typeof body["blob"] === "string" ? body["blob"] : "";
6727
7683
  const passphrase = typeof body["passphrase"] === "string" ? body["passphrase"] : "";
6728
7684
  const mode = body["mode"] === "overwrite" ? "overwrite" : "merge";
6729
- if (!blob) return err4(400, "import requires { blob }");
7685
+ if (!blob) return err6(400, "import requires { blob }");
6730
7686
  try {
6731
7687
  const counts = await applyImport(blob, passphrase, mode, deps, deps.parseProviderInput);
6732
7688
  return { status: 200, body: counts };
6733
7689
  } catch (error) {
6734
7690
  if (error instanceof WeakPassphraseError) {
6735
- return err4(400, error.message);
7691
+ return err6(400, error.message);
6736
7692
  }
6737
- return err4(400, error instanceof Error ? error.message : "import failed");
7693
+ return err6(400, error instanceof Error ? error.message : "import failed");
6738
7694
  }
6739
7695
  }
6740
7696
 
6741
7697
  // src/admin/usagePricing.ts
6742
7698
  var import_usage = require("@omnicross/core/usage");
6743
- var err5 = (status, message) => ({
7699
+ var err7 = (status, message) => ({
6744
7700
  status,
6745
7701
  body: { error: { type: "admin_api_error", message } }
6746
7702
  });
@@ -6753,7 +7709,7 @@ function parseRange(query2) {
6753
7709
  const startTs = parseFiniteInt(query2.get("startTs"));
6754
7710
  const endTs = parseFiniteInt(query2.get("endTs"));
6755
7711
  if (startTs === null || endTs === null) {
6756
- return err5(400, "startTs and endTs are required finite-integer unix-millis query params");
7712
+ return err7(400, "startTs and endTs are required finite-integer unix-millis query params");
6757
7713
  }
6758
7714
  return { startTs, endTs };
6759
7715
  }
@@ -6778,14 +7734,14 @@ async function handleUsageGet(view, query2, deps) {
6778
7734
  case "timeseries": {
6779
7735
  const bucket = query2.get("bucket");
6780
7736
  if (bucket !== "hour" && bucket !== "day" && bucket !== "month") {
6781
- return err5(400, "bucket must be one of 'hour', 'day', 'month'");
7737
+ return err7(400, "bucket must be one of 'hour', 'day', 'month'");
6782
7738
  }
6783
7739
  const now = Date.now();
6784
7740
  const clamped = { startTs: range.startTs, endTs: Math.min(range.endTs, now) };
6785
7741
  if (clamped.startTs < clamped.endTs) {
6786
7742
  const projected = Math.ceil((clamped.endTs - clamped.startTs) / BUCKET_SPAN_MS[bucket]) + 1;
6787
7743
  if (projected > MAX_TIMESERIES_BUCKETS) {
6788
- return err5(
7744
+ return err7(
6789
7745
  400,
6790
7746
  `requested range projects ~${projected} '${bucket}' buckets (max ${MAX_TIMESERIES_BUCKETS}); narrow the range or use a coarser bucket`
6791
7747
  );
@@ -6808,7 +7764,7 @@ async function handleUsageGet(view, query2, deps) {
6808
7764
  };
6809
7765
  }
6810
7766
  default:
6811
- return err5(404, `unknown usage view '${view ?? ""}'`);
7767
+ return err7(404, `unknown usage view '${view ?? ""}'`);
6812
7768
  }
6813
7769
  }
6814
7770
  function poolKeyLabels(cfg) {
@@ -6857,7 +7813,7 @@ async function handlePricingList(deps) {
6857
7813
  async function handlePricingUpsert(body, deps) {
6858
7814
  const input = parsePricingEntryInput(body);
6859
7815
  if (!input) {
6860
- return err5(400, "invalid pricing entry (providerId, modelId, finite numeric inputPricePer1m/outputPricePer1m required)");
7816
+ return err7(400, "invalid pricing entry (providerId, modelId, finite numeric inputPricePer1m/outputPricePer1m required)");
6861
7817
  }
6862
7818
  const entry = await deps.pricingEngine.upsertManual(input);
6863
7819
  return { status: 200, body: { entry } };
@@ -6866,7 +7822,7 @@ async function handlePricingDelete(query2, deps) {
6866
7822
  const providerId = query2.get("providerId")?.trim() ?? "";
6867
7823
  const modelId = query2.get("modelId")?.trim() ?? "";
6868
7824
  if (!providerId || !modelId) {
6869
- return err5(400, "delete requires providerId and modelId query params");
7825
+ return err7(400, "delete requires providerId and modelId query params");
6870
7826
  }
6871
7827
  const deleted = await deps.pricingStore.delete(providerId, modelId);
6872
7828
  if (deleted) await deps.pricingEngine.invalidateCache();
@@ -6886,13 +7842,13 @@ async function handlePricingFetchLatest(deps) {
6886
7842
  }
6887
7843
  };
6888
7844
  } catch (e) {
6889
- return err5(502, `pricing-source fetch failed: ${e instanceof Error ? e.message : String(e)}`);
7845
+ return err7(502, `pricing-source fetch failed: ${e instanceof Error ? e.message : String(e)}`);
6890
7846
  }
6891
7847
  }
6892
7848
  async function handlePricingResolveConflicts(body, deps) {
6893
7849
  const raw = body["resolutions"];
6894
7850
  if (!Array.isArray(raw)) {
6895
- return err5(400, "resolve-conflicts requires { resolutions: [...] }");
7851
+ return err7(400, "resolve-conflicts requires { resolutions: [...] }");
6896
7852
  }
6897
7853
  const currentRows = await deps.pricingStore.getAll();
6898
7854
  const userEditedKeys = new Set(
@@ -6902,21 +7858,21 @@ async function handlePricingResolveConflicts(body, deps) {
6902
7858
  const pendingIncoming = /* @__PURE__ */ new Map();
6903
7859
  let staleCount = 0;
6904
7860
  for (const item of raw) {
6905
- if (!item || typeof item !== "object") return err5(400, "invalid resolution entry");
7861
+ if (!item || typeof item !== "object") return err7(400, "invalid resolution entry");
6906
7862
  const r = item;
6907
7863
  const action = r["action"];
6908
7864
  if (action !== "overwrite" && action !== "skip") {
6909
- return err5(400, "resolution action must be 'overwrite' or 'skip'");
7865
+ return err7(400, "resolution action must be 'overwrite' or 'skip'");
6910
7866
  }
6911
7867
  const providerId = typeof r["providerId"] === "string" && r["providerId"].trim() ? r["providerId"].trim() : "";
6912
7868
  const modelId = typeof r["modelId"] === "string" && r["modelId"].trim() ? r["modelId"].trim() : "";
6913
7869
  if (!providerId || !modelId) {
6914
- return err5(400, "each resolution requires top-level providerId and modelId");
7870
+ return err7(400, "each resolution requires top-level providerId and modelId");
6915
7871
  }
6916
7872
  const incoming = parsePricingEntryInput(r["incoming"]);
6917
- if (!incoming) return err5(400, "each resolution must echo a valid incoming pricing entry");
7873
+ if (!incoming) return err7(400, "each resolution must echo a valid incoming pricing entry");
6918
7874
  if (incoming.providerId !== providerId || incoming.modelId !== modelId) {
6919
- return err5(400, "resolution providerId/modelId must match the echoed incoming entry");
7875
+ return err7(400, "resolution providerId/modelId must match the echoed incoming entry");
6920
7876
  }
6921
7877
  const key = `${providerId}::${modelId}`;
6922
7878
  if (action === "overwrite" && !userEditedKeys.has(key)) {
@@ -6961,7 +7917,7 @@ function query(req) {
6961
7917
  }
6962
7918
  function allowanceProvider(value) {
6963
7919
  if (!value) return void 0;
6964
- return value === "claude" || value === "codex" || value === "kimi" || value === "opencodego" ? value : null;
7920
+ return value === "claude" || value === "codex" || value === "kimi" || value === "opencodego" || value === "grok" || value === "copilot" || value === "gemini" ? value : null;
6965
7921
  }
6966
7922
  async function handleAccountAllowanceApi(req, res, method, rest, service) {
6967
7923
  if (!service) return writeError2(res, 501, "account allowance service is not available");
@@ -6976,7 +7932,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
6976
7932
  const pathProvider = rest.length >= 2 ? rest[0] : null;
6977
7933
  const providerId = allowanceProvider(pathProvider ?? params.get("providerId") ?? params.get("provider"));
6978
7934
  if (providerId === null) {
6979
- return writeError2(res, 400, "providerId must be claude, codex, kimi, or opencodego");
7935
+ return writeError2(res, 400, "providerId must be claude, codex, kimi, opencodego, grok, copilot, or gemini");
6980
7936
  }
6981
7937
  const accountId = rest.length >= 2 ? rest[1] : params.get("accountId") ?? void 0;
6982
7938
  const allowances = await service.list({ providerId, accountId });
@@ -7018,6 +7974,36 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7018
7974
  }
7019
7975
  return writeJson3(res, 200, { allowances: allowances2 });
7020
7976
  }
7977
+ if (requestedProvider === "copilot") {
7978
+ if (!service.refreshCopilot) {
7979
+ return writeError2(res, 501, "copilot allowance refresh is not available");
7980
+ }
7981
+ const allowances2 = await service.refreshCopilot(accountId);
7982
+ if (accountId && allowances2.length === 0) {
7983
+ return writeError2(res, 404, `Copilot account '${accountId}' not found`);
7984
+ }
7985
+ return writeJson3(res, 200, { allowances: allowances2 });
7986
+ }
7987
+ if (requestedProvider === "grok") {
7988
+ if (!service.refreshGrok) {
7989
+ return writeError2(res, 501, "grok allowance refresh is not available");
7990
+ }
7991
+ const allowances2 = await service.refreshGrok(accountId);
7992
+ if (accountId && allowances2.length === 0) {
7993
+ return writeError2(res, 404, `Grok account '${accountId}' not found`);
7994
+ }
7995
+ return writeJson3(res, 200, { allowances: allowances2 });
7996
+ }
7997
+ if (requestedProvider === "gemini") {
7998
+ if (!service.refreshGemini) {
7999
+ return writeError2(res, 501, "gemini allowance refresh is not available");
8000
+ }
8001
+ const allowances2 = await service.refreshGemini(accountId);
8002
+ if (accountId && allowances2.length === 0) {
8003
+ return writeError2(res, 404, `Gemini account '${accountId}' not found`);
8004
+ }
8005
+ return writeJson3(res, 200, { allowances: allowances2 });
8006
+ }
7021
8007
  const allowances = await service.refreshClaude(accountId);
7022
8008
  if (accountId && allowances.length === 0) {
7023
8009
  return writeError2(res, 404, `Claude account '${accountId}' not found`);
@@ -7116,6 +8102,9 @@ function toProviderView(row) {
7116
8102
  apiVersion: row.apiVersion,
7117
8103
  maxConcurrency: row.maxConcurrency,
7118
8104
  modelsEndpoint: row.modelsEndpoint,
8105
+ // Static extra headers round-trip VERBATIM (non-secret identity values;
8106
+ // auth/content names were already dropped at the write/load gate).
8107
+ extraHeaders: row.extraHeaders,
7119
8108
  // app-parity child 5: transformer config round-trips VERBATIM (non-secret —
7120
8109
  // transform-rule names + options, no key material; absent stays absent).
7121
8110
  transformer: row.transformer,
@@ -7185,8 +8174,8 @@ async function handleAdminApi(req, res, path2, deps) {
7185
8174
  default:
7186
8175
  return writeJsonError(res, 404, `unknown admin resource '${resource}'`);
7187
8176
  }
7188
- } catch (err6) {
7189
- writeJsonError(res, 500, err6 instanceof Error ? err6.message : String(err6));
8177
+ } catch (err8) {
8178
+ writeJsonError(res, 500, err8 instanceof Error ? err8.message : String(err8));
7190
8179
  }
7191
8180
  }
7192
8181
  function requestQuery(req) {
@@ -7344,6 +8333,9 @@ async function handleProviderReorder(req, res, cfg, deps) {
7344
8333
  persistProviders(cfg, deps);
7345
8334
  return writeJson4(res, 200, { ok: true, providers: cfg.providers.map(toProviderView) });
7346
8335
  }
8336
+ function expandRowExtraHeaders(row) {
8337
+ return (0, import_core3.mergeExtraHeaders)({}, row.extraHeaders);
8338
+ }
7347
8339
  async function handleDiscoverModels(res, id, cfg) {
7348
8340
  if (!id) return writeJsonError(res, 400, "provider id required in path");
7349
8341
  const row = cfg.providers.find((p) => p.id === id);
@@ -7357,7 +8349,8 @@ async function handleDiscoverModels(res, id, cfg) {
7357
8349
  try {
7358
8350
  const headers = { Accept: "application/json" };
7359
8351
  if (resolvedKey) headers["Authorization"] = `Bearer ${resolvedKey}`;
7360
- const response = await (0, import_upstreamFetch7.fetchUpstream)(url, { method: "GET", headers }, { providerId: "byo" });
8352
+ Object.assign(headers, expandRowExtraHeaders(row));
8353
+ const response = await (0, import_upstreamFetch10.fetchUpstream)(url, { method: "GET", headers }, { providerId: "byo" });
7361
8354
  if (!response.ok) {
7362
8355
  const text = await response.text().catch(() => "");
7363
8356
  let message = text.slice(0, 300);
@@ -7374,8 +8367,8 @@ async function handleDiscoverModels(res, id, cfg) {
7374
8367
  const data = await response.json();
7375
8368
  const models = Array.isArray(data?.data) ? data.data.map((m) => typeof m?.id === "string" ? m.id : "").filter((m) => m.length > 0) : [];
7376
8369
  return writeJson4(res, 200, { models });
7377
- } catch (err6) {
7378
- const message = err6 instanceof Error ? err6.message : String(err6);
8370
+ } catch (err8) {
8371
+ const message = err8 instanceof Error ? err8.message : String(err8);
7379
8372
  return writeJson4(res, 200, { models: [], error: `discovery failed: ${message}` });
7380
8373
  }
7381
8374
  }
@@ -7414,9 +8407,10 @@ async function handleTestModel(req, res, id, cfg) {
7414
8407
  messages: [{ role: "user", content: prompt }]
7415
8408
  };
7416
8409
  }
8410
+ Object.assign(headers, expandRowExtraHeaders(row));
7417
8411
  const startedAt = Date.now();
7418
8412
  try {
7419
- const response = await (0, import_upstreamFetch7.fetchUpstream)(
8413
+ const response = await (0, import_upstreamFetch10.fetchUpstream)(
7420
8414
  url,
7421
8415
  { method: "POST", headers, body: JSON.stringify(payload) },
7422
8416
  { providerId: "byo" }
@@ -7438,8 +8432,8 @@ async function handleTestModel(req, res, id, cfg) {
7438
8432
  latencyMs,
7439
8433
  sample: extractSampleText(text, row.apiFormat)
7440
8434
  });
7441
- } catch (err6) {
7442
- const message = err6 instanceof Error ? err6.message : String(err6);
8435
+ } catch (err8) {
8436
+ const message = err8 instanceof Error ? err8.message : String(err8);
7443
8437
  return writeJson4(res, 200, { ok: false, latencyMs: Date.now() - startedAt, message });
7444
8438
  }
7445
8439
  }
@@ -7721,6 +8715,7 @@ function parseProviderInput(body, existing) {
7721
8715
  const apiVersion = typeof body["apiVersion"] === "string" && body["apiVersion"].length > 0 ? body["apiVersion"] : body["apiVersion"] === null ? void 0 : existing?.apiVersion;
7722
8716
  const modelsEndpoint = typeof body["modelsEndpoint"] === "string" && body["modelsEndpoint"].length > 0 ? body["modelsEndpoint"] : body["modelsEndpoint"] === null ? void 0 : existing?.modelsEndpoint;
7723
8717
  const maxConcurrency = typeof body["maxConcurrency"] === "number" && Number.isFinite(body["maxConcurrency"]) ? body["maxConcurrency"] : body["maxConcurrency"] === null ? void 0 : existing?.maxConcurrency;
8718
+ const extraHeaders = body["extraHeaders"] === null ? void 0 : body["extraHeaders"] === void 0 ? existing?.extraHeaders : validateExtraHeaders(body["extraHeaders"]);
7724
8719
  const transformer = body["transformer"] === null ? void 0 : parseTransformerInput(body["transformer"], existing?.transformer);
7725
8720
  const codingPlan = body["codingPlan"] === null ? void 0 : body["codingPlan"] === void 0 ? existing?.codingPlan : body["codingPlan"] && typeof body["codingPlan"] === "object" && !Array.isArray(body["codingPlan"]) ? parseCodingPlanInput(body["codingPlan"], existing?.codingPlan) : existing?.codingPlan;
7726
8721
  const apiModes = body["apiModes"] === null ? void 0 : parseApiModesInput(body["apiModes"], existing?.apiModes);
@@ -7746,6 +8741,7 @@ function parseProviderInput(body, existing) {
7746
8741
  apiVersion,
7747
8742
  maxConcurrency,
7748
8743
  modelsEndpoint,
8744
+ extraHeaders,
7749
8745
  transformer: migrated.transformer,
7750
8746
  codingPlan,
7751
8747
  apiModes,
@@ -7767,7 +8763,10 @@ function handlePresets(res, method) {
7767
8763
  description: p.description,
7768
8764
  features: p.features,
7769
8765
  website: p.website,
7770
- modelsEndpoint: p.modelsEndpoint
8766
+ modelsEndpoint: p.modelsEndpoint,
8767
+ // Static extra headers ride along so `addFromPreset` can seed them onto the
8768
+ // row (the write gateway re-validates via the shared allowlist).
8769
+ extraHeaders: p.extraHeaders
7771
8770
  }));
7772
8771
  return writeJson4(res, 200, { presets, excluded });
7773
8772
  }
@@ -8249,12 +9248,12 @@ async function handleAccounts(req, res, method, rest, deps) {
8249
9248
  }
8250
9249
  return writeJson4(res, 200, { ok: true, affected: result.affected });
8251
9250
  }
8252
- if (method === "GET" && (rest[0] === "codex" || rest[0] === "kimi") && rest[1] === "oauth" && rest[3] === "status") {
8253
- const result = rest[0] === "codex" ? handleCodexOAuthStatus(rest[2], deps) : handleKimiOAuthStatus(rest[2], deps);
9251
+ if (method === "GET" && (rest[0] === "codex" || rest[0] === "kimi" || rest[0] === "grok" || rest[0] === "copilot") && rest[1] === "oauth" && rest[3] === "status") {
9252
+ const result = rest[0] === "codex" ? handleCodexOAuthStatus(rest[2], deps) : rest[0] === "kimi" ? handleKimiOAuthStatus(rest[2], deps) : rest[0] === "grok" ? handleGrokOAuthStatus(rest[2], deps) : handleCopilotOAuthStatus(rest[2], deps);
8254
9253
  return writeJson4(res, result.status, result.body);
8255
9254
  }
8256
- if (method === "DELETE" && (rest[0] === "codex" || rest[0] === "kimi") && rest[1] === "oauth" && rest[2]) {
8257
- const result = rest[0] === "codex" ? handleCodexOAuthCancel(rest[2], deps) : handleKimiOAuthCancel(rest[2], deps);
9255
+ if (method === "DELETE" && (rest[0] === "codex" || rest[0] === "kimi" || rest[0] === "grok" || rest[0] === "copilot") && rest[1] === "oauth" && rest[2]) {
9256
+ const result = rest[0] === "codex" ? handleCodexOAuthCancel(rest[2], deps) : rest[0] === "kimi" ? handleKimiOAuthCancel(rest[2], deps) : rest[0] === "grok" ? handleGrokOAuthCancel(rest[2], deps) : handleCopilotOAuthCancel(rest[2], deps);
8258
9257
  return writeJson4(res, result.status, result.body);
8259
9258
  }
8260
9259
  if (method === "GET" && rest.length === 3 && rest[2] === "diagnostics") {
@@ -8315,6 +9314,15 @@ async function handleAccounts(req, res, method, rest, deps) {
8315
9314
  const result2 = await handleKimiOAuthStart(deps);
8316
9315
  return writeJson4(res, result2.status, result2.body);
8317
9316
  }
9317
+ if (providerId === "grok") {
9318
+ const result2 = await handleGrokOAuthStart(deps);
9319
+ return writeJson4(res, result2.status, result2.body);
9320
+ }
9321
+ if (providerId === "copilot") {
9322
+ const body2 = await readJsonBody4(req);
9323
+ const result2 = await handleCopilotOAuthStart(deps, body2["enterpriseUrl"]);
9324
+ return writeJson4(res, result2.status, result2.body);
9325
+ }
8318
9326
  const result = handleOAuthStart(providerId, deps);
8319
9327
  return writeJson4(res, result.status, result.body);
8320
9328
  }
@@ -8809,12 +9817,12 @@ async function handlePlayground(req, res, method, deps) {
8809
9817
  const payload = body["body"];
8810
9818
  const status = deps.outboundApiServer.getStatus();
8811
9819
  if (!status.running || !status.port) return writeJsonError(res, 503, "outbound server not running");
8812
- const path2 = resolvePlaygroundPath(endpoint, isRecord4(payload) ? payload : {});
9820
+ const path2 = resolvePlaygroundPath(endpoint, isRecord7(payload) ? payload : {});
8813
9821
  if (!path2) return writeJsonError(res, 400, `unknown endpoint '${endpoint}'`);
8814
9822
  const upstreamBody = typeof payload === "string" ? payload : JSON.stringify(payload ?? {});
8815
9823
  await proxyToOutbound(res, status.port, path2, key, upstreamBody);
8816
9824
  }
8817
- function isRecord4(v) {
9825
+ function isRecord7(v) {
8818
9826
  return !!v && typeof v === "object" && !Array.isArray(v);
8819
9827
  }
8820
9828
  function proxyToOutbound(res, outboundPort, path2, key, body) {
@@ -8843,8 +9851,8 @@ function proxyToOutbound(res, outboundPort, path2, key, body) {
8843
9851
  });
8844
9852
  }
8845
9853
  );
8846
- upstream.on("error", (err6) => {
8847
- if (!res.headersSent) writeJsonError(res, 502, `playground proxy failed: ${err6.message}`);
9854
+ upstream.on("error", (err8) => {
9855
+ if (!res.headersSent) writeJsonError(res, 502, `playground proxy failed: ${err8.message}`);
8848
9856
  else res.end();
8849
9857
  resolve11();
8850
9858
  });
@@ -8950,7 +9958,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
8950
9958
  }
8951
9959
 
8952
9960
  // src/admin/version.ts
8953
- var DAEMON_VERSION = true ? "0.3.1" : "0.0.0-dev";
9961
+ var DAEMON_VERSION = true ? "0.4.1" : "0.0.0-dev";
8954
9962
 
8955
9963
  // src/admin/AdminServer.ts
8956
9964
  var LOOPBACK_ADDR = "127.0.0.1";
@@ -8993,13 +10001,13 @@ var AdminServer = class {
8993
10001
  const server = import_node_http2.default.createServer((req, res) => {
8994
10002
  this.onRequest(req, res);
8995
10003
  });
8996
- const onError = (err6) => {
8997
- if (err6.code === "EADDRINUSE" && port !== 0) {
10004
+ const onError = (err8) => {
10005
+ if (err8.code === "EADDRINUSE" && port !== 0) {
8998
10006
  server.removeListener("error", onError);
8999
10007
  this.listen(bindAddr, 0).then(resolve11, reject);
9000
10008
  return;
9001
10009
  }
9002
- reject(err6);
10010
+ reject(err8);
9003
10011
  };
9004
10012
  server.on("error", onError);
9005
10013
  server.listen(port, bindAddr, () => {
@@ -9017,8 +10025,8 @@ var AdminServer = class {
9017
10025
  }
9018
10026
  /** Per-request handler: auth gate (when a token is set) → routing. */
9019
10027
  onRequest(req, res) {
9020
- void this.dispatch(req, res).catch((err6) => {
9021
- const message = err6 instanceof Error ? err6.message : String(err6);
10028
+ void this.dispatch(req, res).catch((err8) => {
10029
+ const message = err8 instanceof Error ? err8.message : String(err8);
9022
10030
  this.deps.logger.error("[AdminServer] unhandled error:", message);
9023
10031
  if (!res.headersSent) {
9024
10032
  res.writeHead(500, { "Content-Type": "application/json" });
@@ -9282,18 +10290,18 @@ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal
9282
10290
  return;
9283
10291
  }
9284
10292
  signal?.addEventListener("abort", abort, { once: true });
9285
- server.on("error", (err6) => {
10293
+ server.on("error", (err8) => {
9286
10294
  if (settled) return;
9287
10295
  settled = true;
9288
10296
  clearTimeout(timer);
9289
- if (err6.code === "EADDRINUSE") {
10297
+ if (err8.code === "EADDRINUSE") {
9290
10298
  reject(
9291
10299
  new Error(
9292
10300
  `login: cannot bind ${LOOPBACK_HOST}:${LOOPBACK_PORT} (address in use) \u2014 another codex login or process is holding the port`
9293
10301
  )
9294
10302
  );
9295
10303
  } else {
9296
- reject(err6);
10304
+ reject(err8);
9297
10305
  }
9298
10306
  });
9299
10307
  const timer = setTimeout(() => {
@@ -9369,21 +10377,22 @@ function createPoolKeysLoader(getProviderRow, autoDisabled) {
9369
10377
  }
9370
10378
 
9371
10379
  // src/allowance/ProviderKeyQuotaService.ts
9372
- var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
10380
+ var import_core4 = require("@omnicross/core");
10381
+ var import_upstreamFetch11 = require("@omnicross/core/pipeline/upstreamFetch");
9373
10382
 
9374
10383
  // src/allowance/ProviderKeyQuota.ts
9375
- var MINUTE_MS2 = 6e4;
9376
- var HOUR_MS2 = 60 * MINUTE_MS2;
9377
- var DAY_MS2 = 24 * HOUR_MS2;
9378
- var WEEK_MS = 7 * DAY_MS2;
9379
- var MONTH_MS = 30 * DAY_MS2;
9380
- function finiteNumber3(value) {
10384
+ var MINUTE_MS3 = 6e4;
10385
+ var HOUR_MS2 = 60 * MINUTE_MS3;
10386
+ var DAY_MS3 = 24 * HOUR_MS2;
10387
+ var WEEK_MS = 7 * DAY_MS3;
10388
+ var MONTH_MS = 30 * DAY_MS3;
10389
+ function finiteNumber5(value) {
9381
10390
  if (value === null || value === void 0 || value === "") return void 0;
9382
10391
  const parsed = typeof value === "number" ? value : Number(value);
9383
10392
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
9384
10393
  }
9385
10394
  function finitePercent4(value) {
9386
- const parsed = finiteNumber3(value);
10395
+ const parsed = finiteNumber5(value);
9387
10396
  return parsed !== void 0 && parsed <= 100 ? parsed : null;
9388
10397
  }
9389
10398
  function isoInstant3(value) {
@@ -9391,18 +10400,18 @@ function isoInstant3(value) {
9391
10400
  const time = Date.parse(value);
9392
10401
  if (Number.isFinite(time)) return new Date(time).toISOString();
9393
10402
  }
9394
- const numeric = finiteNumber3(value);
10403
+ const numeric = finiteNumber5(value);
9395
10404
  if (numeric !== void 0 && numeric > 1e9) {
9396
10405
  const ms = numeric > 1e12 ? numeric : numeric * 1e3;
9397
10406
  return new Date(ms).toISOString();
9398
10407
  }
9399
10408
  return void 0;
9400
10409
  }
9401
- function secondsUntil5(instant, now) {
10410
+ function secondsUntil8(instant, now) {
9402
10411
  if (!instant) return void 0;
9403
10412
  return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
9404
10413
  }
9405
- function isRecord5(value) {
10414
+ function isRecord8(value) {
9406
10415
  return !!value && typeof value === "object" && !Array.isArray(value);
9407
10416
  }
9408
10417
  function detectProviderKeyQuotaAdapter(baseUrl) {
@@ -9415,7 +10424,7 @@ function detectProviderKeyQuotaAdapter(baseUrl) {
9415
10424
  }
9416
10425
  const host = url.hostname.toLowerCase();
9417
10426
  const path2 = url.pathname.toLowerCase();
9418
- if ((host === "api.z.ai" || host === "open.bigmodel.cn") && path2.includes("/coding")) {
10427
+ if ((host === "api.z.ai" || host === "open.bigmodel.cn") && (path2.includes("/coding") || path2.includes("/anthropic"))) {
9419
10428
  return "zai";
9420
10429
  }
9421
10430
  if ((host === "api.minimax.io" || host === "api.minimaxi.com") && // Token Plan rides the plain openai `/v1` (chat completions) surface; the
@@ -9425,6 +10434,7 @@ function detectProviderKeyQuotaAdapter(baseUrl) {
9425
10434
  }
9426
10435
  if (host === "api.code.umans.ai") return "umans";
9427
10436
  if (host === "api.synthetic.new") return "synthetic";
10437
+ if (host === "api.cline.bot") return "cline-pass";
9428
10438
  return null;
9429
10439
  }
9430
10440
  function providerKeyQuotaUrl(adapter, baseUrl) {
@@ -9432,6 +10442,7 @@ function providerKeyQuotaUrl(adapter, baseUrl) {
9432
10442
  if (adapter === "zai") return `${origin}/api/monitor/usage/quota/limit`;
9433
10443
  if (adapter === "minimax-token-plan") return `${origin}/v1/token_plan/remains`;
9434
10444
  if (adapter === "umans") return `${origin}/v1/usage`;
10445
+ if (adapter === "cline-pass") return `${origin}/api/v1/users/me/plan/usage-limits`;
9435
10446
  return `${origin}/v2/quotas`;
9436
10447
  }
9437
10448
  function providerKeyQuotaAuthHeader(adapter, key) {
@@ -9443,7 +10454,7 @@ function zaiWindowDurationMs(item) {
9443
10454
  case 3:
9444
10455
  return count * HOUR_MS2;
9445
10456
  case 4:
9446
- return count * DAY_MS2;
10457
+ return count * DAY_MS3;
9447
10458
  case 5:
9448
10459
  return count * MONTH_MS;
9449
10460
  case 6:
@@ -9456,8 +10467,8 @@ function zaiWindowIdLabel(durationMs) {
9456
10467
  if (durationMs === WEEK_MS) return { id: "seven-day", label: "7 days" };
9457
10468
  if (durationMs === 5 * HOUR_MS2) return { id: "five-hour", label: "5 hours" };
9458
10469
  if (durationMs === MONTH_MS) return { id: "thirty-day", label: "30 days" };
9459
- if (durationMs !== void 0 && durationMs % DAY_MS2 === 0) {
9460
- const days = durationMs / DAY_MS2;
10470
+ if (durationMs !== void 0 && durationMs % DAY_MS3 === 0) {
10471
+ const days = durationMs / DAY_MS3;
9461
10472
  return { id: `${days}d`, label: `${days} day${days === 1 ? "" : "s"}` };
9462
10473
  }
9463
10474
  if (durationMs !== void 0 && durationMs % HOUR_MS2 === 0) {
@@ -9467,23 +10478,23 @@ function zaiWindowIdLabel(durationMs) {
9467
10478
  return { id: "quota", label: "Quota" };
9468
10479
  }
9469
10480
  function parseZaiQuotaPayload(payload, now) {
9470
- if (!isRecord5(payload)) return null;
9471
- const data = isRecord5(payload["data"]) ? payload["data"] : payload;
10481
+ if (!isRecord8(payload)) return null;
10482
+ const data = isRecord8(payload["data"]) ? payload["data"] : payload;
9472
10483
  if (payload["success"] === false) return null;
9473
10484
  const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
9474
10485
  const byWindow = /* @__PURE__ */ new Map();
9475
10486
  for (const raw of limits) {
9476
- if (!isRecord5(raw)) continue;
10487
+ if (!isRecord8(raw)) continue;
9477
10488
  const item = raw;
9478
10489
  if (item.type === void 0) continue;
9479
10490
  const details = raw["usageDetails"];
9480
- if (Array.isArray(details) && details.some((d) => isRecord5(d) && d["modelCode"] === "zread")) {
10491
+ if (Array.isArray(details) && details.some((d) => isRecord8(d) && d["modelCode"] === "zread")) {
9481
10492
  continue;
9482
10493
  }
9483
10494
  const durationMs = zaiWindowDurationMs(item);
9484
10495
  const { id, label } = zaiWindowIdLabel(durationMs);
9485
- const limit = finiteNumber3(item.usage);
9486
- const used = finiteNumber3(item.currentValue);
10496
+ const limit = finiteNumber5(item.usage);
10497
+ const used = finiteNumber5(item.currentValue);
9487
10498
  const fromAbsolute = limit !== void 0 && used !== void 0 && limit > 0 ? Math.min(100, used / limit * 100) : void 0;
9488
10499
  const fromPercentage = finitePercent4(item.percentage) ?? void 0;
9489
10500
  const usedPercent = fromAbsolute !== void 0 ? Math.round(fromAbsolute * 10) / 10 : fromPercentage;
@@ -9494,9 +10505,9 @@ function parseZaiQuotaPayload(payload, now) {
9494
10505
  label,
9495
10506
  scope: "all",
9496
10507
  usedPercent,
9497
- ...durationMs !== void 0 ? { windowMinutes: Math.round(durationMs / MINUTE_MS2) } : {},
10508
+ ...durationMs !== void 0 ? { windowMinutes: Math.round(durationMs / MINUTE_MS3) } : {},
9498
10509
  ...resetsAt !== void 0 ? { resetsAt } : {},
9499
- remainingSeconds: secondsUntil5(resetsAt, now),
10510
+ remainingSeconds: secondsUntil8(resetsAt, now),
9500
10511
  state: "fresh"
9501
10512
  };
9502
10513
  const existing = byWindow.get(id);
@@ -9510,21 +10521,21 @@ function parseZaiQuotaPayload(payload, now) {
9510
10521
  var MINIMAX_STATUS_EXHAUSTED = 2;
9511
10522
  var MINIMAX_SHARED_BUCKET = "general";
9512
10523
  function parseMiniMaxBucket(value) {
9513
- if (!isRecord5(value)) return null;
10524
+ if (!isRecord8(value)) return null;
9514
10525
  const modelName = typeof value["model_name"] === "string" ? value["model_name"].trim() : "";
9515
10526
  if (!modelName) return null;
9516
10527
  const instant = (v) => {
9517
- const n = finiteNumber3(v);
10528
+ const n = finiteNumber5(v);
9518
10529
  return n !== void 0 && n > 1e9 ? n > 1e12 ? n : n * 1e3 : void 0;
9519
10530
  };
9520
10531
  return {
9521
10532
  modelName,
9522
10533
  intervalEnd: instant(value["end_time"]),
9523
- intervalRemainingPercent: finiteNumber3(value["current_interval_remaining_percent"]),
9524
- intervalStatus: finiteNumber3(value["current_interval_status"]),
10534
+ intervalRemainingPercent: finiteNumber5(value["current_interval_remaining_percent"]),
10535
+ intervalStatus: finiteNumber5(value["current_interval_status"]),
9525
10536
  weeklyEnd: instant(value["weekly_end_time"]),
9526
- weeklyRemainingPercent: finiteNumber3(value["current_weekly_remaining_percent"]),
9527
- weeklyStatus: finiteNumber3(value["current_weekly_status"])
10537
+ weeklyRemainingPercent: finiteNumber5(value["current_weekly_remaining_percent"]),
10538
+ weeklyStatus: finiteNumber5(value["current_weekly_status"])
9528
10539
  };
9529
10540
  }
9530
10541
  function minimaxWindow(id, label, windowMinutes, resetsAtMs, remainingPercent, status, now) {
@@ -9537,14 +10548,14 @@ function minimaxWindow(id, label, windowMinutes, resetsAtMs, remainingPercent, s
9537
10548
  usedPercent,
9538
10549
  ...windowMinutes !== void 0 ? { windowMinutes } : {},
9539
10550
  ...resetsAt !== void 0 ? { resetsAt } : {},
9540
- remainingSeconds: secondsUntil5(resetsAt, now),
10551
+ remainingSeconds: secondsUntil8(resetsAt, now),
9541
10552
  state: usedPercent !== null ? "fresh" : "unavailable"
9542
10553
  };
9543
10554
  }
9544
10555
  function parseMiniMaxTokenPlanPayload(payload, now) {
9545
- if (!isRecord5(payload)) return null;
10556
+ if (!isRecord8(payload)) return null;
9546
10557
  const baseResp = payload["base_resp"];
9547
- if (!isRecord5(baseResp) || baseResp["status_code"] !== 0) return null;
10558
+ if (!isRecord8(baseResp) || baseResp["status_code"] !== 0) return null;
9548
10559
  const buckets = Array.isArray(payload["model_remains"]) ? payload["model_remains"] : [];
9549
10560
  let general = null;
9550
10561
  for (const raw of buckets) {
@@ -9568,7 +10579,7 @@ function parseMiniMaxTokenPlanPayload(payload, now) {
9568
10579
  minimaxWindow(
9569
10580
  "seven-day",
9570
10581
  "7 days",
9571
- Math.round(WEEK_MS / MINUTE_MS2),
10582
+ Math.round(WEEK_MS / MINUTE_MS3),
9572
10583
  general.weeklyEnd,
9573
10584
  general.weeklyRemainingPercent,
9574
10585
  general.weeklyStatus,
@@ -9577,15 +10588,15 @@ function parseMiniMaxTokenPlanPayload(payload, now) {
9577
10588
  ];
9578
10589
  }
9579
10590
  function parseUmansUsagePayload(payload, now) {
9580
- if (!isRecord5(payload)) return null;
9581
- const limits = isRecord5(payload["limits"]) ? payload["limits"] : void 0;
9582
- const requests = limits && isRecord5(limits["requests"]) ? limits["requests"] : void 0;
9583
- const usage = isRecord5(payload["usage"]) ? payload["usage"] : void 0;
9584
- const window = isRecord5(payload["window"]) ? payload["window"] : void 0;
9585
- const hardCap = finiteNumber3(requests?.["hard_cap"]);
9586
- const softLimit = finiteNumber3(requests?.["limit"]);
9587
- const requestsInWindow = finiteNumber3(usage?.["requests_in_window"]);
9588
- const weightedInWindow = finiteNumber3(usage?.["weighted_in_window"]);
10591
+ if (!isRecord8(payload)) return null;
10592
+ const limits = isRecord8(payload["limits"]) ? payload["limits"] : void 0;
10593
+ const requests = limits && isRecord8(limits["requests"]) ? limits["requests"] : void 0;
10594
+ const usage = isRecord8(payload["usage"]) ? payload["usage"] : void 0;
10595
+ const window = isRecord8(payload["window"]) ? payload["window"] : void 0;
10596
+ const hardCap = finiteNumber5(requests?.["hard_cap"]);
10597
+ const softLimit = finiteNumber5(requests?.["limit"]);
10598
+ const requestsInWindow = finiteNumber5(usage?.["requests_in_window"]);
10599
+ const weightedInWindow = finiteNumber5(usage?.["weighted_in_window"]);
9589
10600
  const resetsAt = isoInstant3(window?.["resets_at"]);
9590
10601
  let usedPercent = null;
9591
10602
  if (hardCap !== void 0 && hardCap > 0 && requestsInWindow !== void 0) {
@@ -9602,19 +10613,19 @@ function parseUmansUsagePayload(payload, now) {
9602
10613
  usedPercent,
9603
10614
  windowMinutes: 5 * 60,
9604
10615
  ...resetsAt !== void 0 ? { resetsAt } : {},
9605
- remainingSeconds: secondsUntil5(resetsAt, now),
10616
+ remainingSeconds: secondsUntil8(resetsAt, now),
9606
10617
  state: "fresh"
9607
10618
  }
9608
10619
  ];
9609
10620
  }
9610
10621
  function parseSyntheticQuotasPayload(payload, now) {
9611
- if (!isRecord5(payload)) return null;
9612
- const fiveHour = isRecord5(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
9613
- const weekly = isRecord5(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
10622
+ if (!isRecord8(payload)) return null;
10623
+ const fiveHour = isRecord8(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
10624
+ const weekly = isRecord8(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
9614
10625
  const windows = [];
9615
10626
  if (fiveHour) {
9616
- const max = finiteNumber3(fiveHour["max"]);
9617
- const remaining = finiteNumber3(fiveHour["remaining"]);
10627
+ const max = finiteNumber5(fiveHour["max"]);
10628
+ const remaining = finiteNumber5(fiveHour["remaining"]);
9618
10629
  const usedPercent = max !== void 0 && max > 0 && remaining !== void 0 ? Math.round(Math.min(100, (max - remaining) / max * 100) * 10) / 10 : null;
9619
10630
  const resetsAt = isoInstant3(fiveHour["nextTickAt"]);
9620
10631
  windows.push({
@@ -9624,12 +10635,12 @@ function parseSyntheticQuotasPayload(payload, now) {
9624
10635
  usedPercent,
9625
10636
  windowMinutes: 5 * 60,
9626
10637
  ...resetsAt !== void 0 ? { resetsAt } : {},
9627
- remainingSeconds: secondsUntil5(resetsAt, now),
10638
+ remainingSeconds: secondsUntil8(resetsAt, now),
9628
10639
  state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
9629
10640
  });
9630
10641
  }
9631
10642
  if (weekly) {
9632
- const percentRemaining = finiteNumber3(weekly["percentRemaining"]);
10643
+ const percentRemaining = finiteNumber5(weekly["percentRemaining"]);
9633
10644
  const usedPercent = percentRemaining !== void 0 ? Math.round(Math.min(100, Math.max(0, 100 - percentRemaining)) * 10) / 10 : null;
9634
10645
  const resetsAt = isoInstant3(weekly["nextRegenAt"]);
9635
10646
  windows.push({
@@ -9639,12 +10650,42 @@ function parseSyntheticQuotasPayload(payload, now) {
9639
10650
  usedPercent,
9640
10651
  windowMinutes: 7 * 24 * 60,
9641
10652
  ...resetsAt !== void 0 ? { resetsAt } : {},
9642
- remainingSeconds: secondsUntil5(resetsAt, now),
10653
+ remainingSeconds: secondsUntil8(resetsAt, now),
9643
10654
  state: usedPercent !== null || resetsAt ? "fresh" : "unavailable"
9644
10655
  });
9645
10656
  }
9646
10657
  return windows.length > 0 ? windows : null;
9647
10658
  }
10659
+ var CLINE_WINDOW_CONFIG = {
10660
+ five_hour: { id: "five-hour", label: "5 hours", minutes: 5 * 60 },
10661
+ weekly: { id: "seven-day", label: "7 days", minutes: 7 * 24 * 60 },
10662
+ monthly: { id: "thirty-day", label: "30 days", minutes: 30 * 24 * 60 }
10663
+ };
10664
+ function parseClinePassUsageLimitsPayload(payload, now) {
10665
+ if (!isRecord8(payload)) return null;
10666
+ const data = isRecord8(payload["data"]) ? payload["data"] : payload;
10667
+ const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
10668
+ const windows = [];
10669
+ for (const raw of limits) {
10670
+ if (!isRecord8(raw)) continue;
10671
+ const config = CLINE_WINDOW_CONFIG[typeof raw["type"] === "string" ? raw["type"] : ""];
10672
+ if (!config) continue;
10673
+ const usedPercent = finitePercent4(raw["percentUsed"]);
10674
+ if (usedPercent === null) continue;
10675
+ const resetsAt = isoInstant3(raw["resetsAt"]);
10676
+ windows.push({
10677
+ id: config.id,
10678
+ label: config.label,
10679
+ scope: "all",
10680
+ usedPercent,
10681
+ windowMinutes: config.minutes,
10682
+ ...resetsAt !== void 0 ? { resetsAt } : {},
10683
+ remainingSeconds: secondsUntil8(resetsAt, now),
10684
+ state: "fresh"
10685
+ });
10686
+ }
10687
+ return windows.length > 0 ? windows : null;
10688
+ }
9648
10689
 
9649
10690
  // src/allowance/ProviderKeyQuotaService.ts
9650
10691
  function parseQuotaPayload(adapter, payload, now) {
@@ -9657,6 +10698,8 @@ function parseQuotaPayload(adapter, payload, now) {
9657
10698
  return parseUmansUsagePayload(payload, now);
9658
10699
  case "synthetic":
9659
10700
  return parseSyntheticQuotasPayload(payload, now);
10701
+ case "cline-pass":
10702
+ return parseClinePassUsageLimitsPayload(payload, now);
9660
10703
  }
9661
10704
  }
9662
10705
  var PROVIDER_KEY_QUOTA_CACHE_MS = 5 * 6e4;
@@ -9676,7 +10719,7 @@ function rowKeyEntries(row) {
9676
10719
  return [];
9677
10720
  }
9678
10721
  var ProviderKeyQuotaService = class {
9679
- constructor(box, fetchImpl = (url, init) => (0, import_upstreamFetch8.fetchUpstream)(url, init, { redactBodies: true }), now = Date.now) {
10722
+ constructor(box, fetchImpl = (url, init) => (0, import_upstreamFetch11.fetchUpstream)(url, init, { redactBodies: true }), now = Date.now) {
9680
10723
  this.box = box;
9681
10724
  this.fetchImpl = fetchImpl;
9682
10725
  this.now = now;
@@ -9738,7 +10781,10 @@ var ProviderKeyQuotaService = class {
9738
10781
  headers: {
9739
10782
  Authorization: providerKeyQuotaAuthHeader(adapter, key),
9740
10783
  Accept: "application/json",
9741
- "Content-Type": "application/json"
10784
+ "Content-Type": "application/json",
10785
+ // The row's static identity headers ride along — the Cline usage
10786
+ // endpoint sits behind the SAME client-identity 403 gate as inference.
10787
+ ...(0, import_core4.mergeExtraHeaders)({}, row.extraHeaders)
9742
10788
  },
9743
10789
  signal: AbortSignal.timeout(15e3)
9744
10790
  });
@@ -9776,7 +10822,7 @@ var ProviderKeyQuotaService = class {
9776
10822
  // src/image-generation/ImageDoctorService.ts
9777
10823
  var import_image_generation = require("@omnicross/core/image-generation");
9778
10824
  var import_outbound_api7 = require("@omnicross/core/outbound-api");
9779
- var import_subscriptions6 = require("@omnicross/subscriptions");
10825
+ var import_subscriptions9 = require("@omnicross/subscriptions");
9780
10826
 
9781
10827
  // src/image-generation/FileCodexImageCapabilityEvidenceSource.ts
9782
10828
  var import_node_crypto13 = require("crypto");
@@ -10214,7 +11260,7 @@ function createImageDoctorService(options) {
10214
11260
  paths,
10215
11261
  ttlMs: config.evidenceTtlMs
10216
11262
  }));
10217
- const createLiveVerifier = options.createLiveVerifier ?? ((strategy, config) => (0, import_subscriptions6.createCodexImageLiveVerifier)({
11263
+ const createLiveVerifier = options.createLiveVerifier ?? ((strategy, config) => (0, import_subscriptions9.createCodexImageLiveVerifier)({
10218
11264
  authStrategy: strategy,
10219
11265
  generationTimeoutMs: config.queue.generationTimeoutMs
10220
11266
  }));
@@ -10576,7 +11622,7 @@ var ImageCleanupService = class {
10576
11622
  var import_node_crypto16 = require("crypto");
10577
11623
  var import_image_generation5 = require("@omnicross/core/image-generation");
10578
11624
  var import_outbound_api8 = require("@omnicross/core/outbound-api");
10579
- var import_subscriptions7 = require("@omnicross/subscriptions");
11625
+ var import_subscriptions10 = require("@omnicross/subscriptions");
10580
11626
 
10581
11627
  // src/image-generation/ImageApiRuntimeResolver.ts
10582
11628
  var import_node_crypto14 = require("crypto");
@@ -11107,7 +12153,7 @@ function createImageRuntimeGeneration(options) {
11107
12153
  now: options.now ?? Date.now,
11108
12154
  referenceStore: options.storage.referenceStore,
11109
12155
  stateStore: options.storage.stateStore
11110
- }) : (0, import_subscriptions7.createCodexSubscriptionImageProvider)({
12156
+ }) : (0, import_subscriptions10.createCodexSubscriptionImageProvider)({
11111
12157
  authStrategy,
11112
12158
  evidenceSource: generationEvidenceSource,
11113
12159
  executionScheduler: scheduler,
@@ -14251,7 +15297,7 @@ var ImageRuntimeManager = class {
14251
15297
  };
14252
15298
 
14253
15299
  // src/ports/ConfigFileProviderConfigSource.ts
14254
- var import_core2 = require("@omnicross/core");
15300
+ var import_core5 = require("@omnicross/core");
14255
15301
  var EMPTY_CHAIN = {
14256
15302
  providerTransformers: [],
14257
15303
  modelTransformers: []
@@ -14276,8 +15322,8 @@ var ConfigFileProviderConfigSource = class {
14276
15322
  reloadHook;
14277
15323
  constructor(config) {
14278
15324
  for (const p of config.providers) this.providers.set(p.id, p);
14279
- this.transformerService = new import_core2.TransformerService();
14280
- void (0, import_core2.registerBuiltinTransformers)(this.transformerService);
15325
+ this.transformerService = new import_core5.TransformerService();
15326
+ void (0, import_core5.registerBuiltinTransformers)(this.transformerService);
14281
15327
  }
14282
15328
  // ── Reload hook (key-pool design D4) ───────────────────────────────────────
14283
15329
  /**
@@ -14298,7 +15344,7 @@ var ConfigFileProviderConfigSource = class {
14298
15344
  }
14299
15345
  /** Await the built-in transformer registration (tests await this before dispatch). */
14300
15346
  async ready() {
14301
- await (0, import_core2.registerBuiltinTransformers)(this.transformerService);
15347
+ await (0, import_core5.registerBuiltinTransformers)(this.transformerService);
14302
15348
  }
14303
15349
  // ── Hot-reload seam (admin dashboard, RT3 design D6) ───────────────────────
14304
15350
  /**
@@ -14409,6 +15455,10 @@ function toLLMProvider(row) {
14409
15455
  // `parseProviderInput`), so customizations are preserved (the row value wins).
14410
15456
  apiModes: row.apiModes,
14411
15457
  selectedApiModeId: row.selectedApiModeId,
15458
+ // Static extra request headers ride along verbatim (load-guarded — no
15459
+ // auth/content names); core's `getProviderHeaders` merges them into every
15460
+ // BYO request, and the same-format relay path inherits that funnel.
15461
+ extraHeaders: row.extraHeaders,
14412
15462
  // Official-Anthropic signature handling only matters for the Anthropic
14413
15463
  // ingress (deferred → 502); leave it off for the BYO transform path.
14414
15464
  isOfficial: false
@@ -15774,7 +16824,7 @@ function bucketLabel(bucketStartTs, bucket) {
15774
16824
 
15775
16825
  // src/ports/JsonOutboundKeyDb.ts
15776
16826
  var import_node_fs23 = require("fs");
15777
- var import_core3 = require("@omnicross/core");
16827
+ var import_core6 = require("@omnicross/core");
15778
16828
 
15779
16829
  // src/ports/atomicFile.ts
15780
16830
  var import_node_crypto22 = require("crypto");
@@ -15896,7 +16946,7 @@ var JsonOutboundKeyDb = class {
15896
16946
  });
15897
16947
  }
15898
16948
  async outboundApiKeysSetPermissions(id, permissions) {
15899
- const exact = (0, import_core3.validateOutboundPermissions)(permissions);
16949
+ const exact = (0, import_core6.validateOutboundPermissions)(permissions);
15900
16950
  return this.mutateRow(id, (row) => {
15901
16951
  if (row.revokedAt !== null) return false;
15902
16952
  row.allowedEndpoints = [...exact];
@@ -16333,9 +17383,9 @@ var import_node_fs28 = require("fs");
16333
17383
  var import_node_path27 = require("path");
16334
17384
  var import_SubscriptionAccountHealth2 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
16335
17385
  var import_AccountAllowanceScheduling3 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
16336
- var import_upstreamFetch9 = require("@omnicross/core/pipeline/upstreamFetch");
17386
+ var import_upstreamFetch12 = require("@omnicross/core/pipeline/upstreamFetch");
16337
17387
  var import_SubscriptionIdentityStore2 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
16338
- var import_subscriptions8 = require("@omnicross/subscriptions");
17388
+ var import_subscriptions11 = require("@omnicross/subscriptions");
16339
17389
 
16340
17390
  // src/ports/account-sync.ts
16341
17391
  function viewOf(tokens) {
@@ -16483,7 +17533,7 @@ var JsonSubscriptionCredentialStore = class {
16483
17533
  * a plaintext token pair into `upstream-trace.jsonl`.
16484
17534
  */
16485
17535
  buildRefreshFetch(providerId, accountId) {
16486
- return this.fetchImpl ?? ((url, init) => (0, import_upstreamFetch9.fetchUpstream)(url, init, { providerId, accountId, redactBodies: true }));
17536
+ return this.fetchImpl ?? ((url, init) => (0, import_upstreamFetch12.fetchUpstream)(url, init, { providerId, accountId, redactBodies: true }));
16487
17537
  }
16488
17538
  /**
16489
17539
  * In-flight refresh coalescing. OAuth refresh tokens are
@@ -16524,7 +17574,7 @@ var JsonSubscriptionCredentialStore = class {
16524
17574
  * other hot reads. Never returns token material.
16525
17575
  */
16526
17576
  getAccountProxy(providerId, accountId) {
16527
- if (providerId !== "claude" && providerId !== "codex" && providerId !== "gemini" && providerId !== "opencodego" && providerId !== "kimi") {
17577
+ if (providerId !== "claude" && providerId !== "codex" && providerId !== "gemini" && providerId !== "opencodego" && providerId !== "kimi" && providerId !== "grok" && providerId !== "copilot") {
16528
17578
  return void 0;
16529
17579
  }
16530
17580
  return getAccountProxy(this.readConfig(), providerId, accountId);
@@ -16543,7 +17593,7 @@ var JsonSubscriptionCredentialStore = class {
16543
17593
  const fingerprintOn = identityStore.isEnabled();
16544
17594
  const now = Date.now();
16545
17595
  const out = {};
16546
- for (const provider of ["claude", "codex", "gemini", "opencodego", "kimi"]) {
17596
+ for (const provider of ["claude", "codex", "gemini", "opencodego", "kimi", "grok", "copilot"]) {
16547
17597
  const sanitized = sanitizeAccounts(config, provider);
16548
17598
  if (sanitized.length === 0) continue;
16549
17599
  for (const account of sanitized) {
@@ -16609,7 +17659,7 @@ var JsonSubscriptionCredentialStore = class {
16609
17659
  this.materializeMigration(config);
16610
17660
  const refreshFetch = this.buildRefreshFetch("claude", capturedId);
16611
17661
  try {
16612
- const result = await import_subscriptions8.claudeOAuth.refreshAccessToken(claude.refreshToken, refreshFetch);
17662
+ const result = await import_subscriptions11.claudeOAuth.refreshAccessToken(claude.refreshToken, refreshFetch);
16613
17663
  const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
16614
17664
  const next = {
16615
17665
  ...claude,
@@ -16644,7 +17694,7 @@ var JsonSubscriptionCredentialStore = class {
16644
17694
  this.materializeMigration(config);
16645
17695
  const refreshFetch = this.buildRefreshFetch("codex", capturedId);
16646
17696
  try {
16647
- const result = await import_subscriptions8.codexOAuth.refreshAccessToken(codex.refreshToken, refreshFetch);
17697
+ const result = await import_subscriptions11.codexOAuth.refreshAccessToken(codex.refreshToken, refreshFetch);
16648
17698
  const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
16649
17699
  const next = {
16650
17700
  ...codex,
@@ -16682,7 +17732,7 @@ var JsonSubscriptionCredentialStore = class {
16682
17732
  this.materializeMigration(config);
16683
17733
  const refreshFetch = this.buildRefreshFetch("gemini", capturedId);
16684
17734
  try {
16685
- const result = await import_subscriptions8.geminiOAuth.refreshAccessToken(gemini.refreshToken, refreshFetch);
17735
+ const result = await import_subscriptions11.geminiOAuth.refreshAccessToken(gemini.refreshToken, refreshFetch);
16686
17736
  const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
16687
17737
  const next = {
16688
17738
  ...gemini,
@@ -16718,10 +17768,10 @@ var JsonSubscriptionCredentialStore = class {
16718
17768
  this.materializeMigration(config);
16719
17769
  const refreshFetch = this.buildRefreshFetch("kimi", capturedId);
16720
17770
  try {
16721
- const result = await import_subscriptions8.kimiOAuth.refreshAccessToken(
17771
+ const result = await import_subscriptions11.kimiOAuth.refreshAccessToken(
16722
17772
  kimi.refreshToken,
16723
17773
  refreshFetch,
16724
- import_subscriptions8.kimiOAuth.kimiFingerprintHeaders(kimi.deviceId)
17774
+ import_subscriptions11.kimiOAuth.kimiFingerprintHeaders(kimi.deviceId)
16725
17775
  );
16726
17776
  const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
16727
17777
  const next = {
@@ -16742,6 +17792,66 @@ var JsonSubscriptionCredentialStore = class {
16742
17792
  }
16743
17793
  });
16744
17794
  }
17795
+ /**
17796
+ * Refresh the Grok (xAI SuperGrok) OAuth access token. The token endpoint is
17797
+ * resolved through OIDC discovery on every refresh (process-cached 1h by the
17798
+ * flow module) so a rotated endpoint document is picked up without a daemon
17799
+ * restart. HONEST `false` when no refresh_token.
17800
+ */
17801
+ async refreshGrokToken() {
17802
+ return this.coalesce("grok:active", async () => {
17803
+ const config = this.readConfig();
17804
+ const active = getActiveAccount(config, "grok");
17805
+ const grok = active?.tokens;
17806
+ if (!active || !grok?.refreshToken) return false;
17807
+ const capturedId = active.id;
17808
+ this.materializeMigration(config);
17809
+ const refreshFetch = this.buildRefreshFetch("grok", capturedId);
17810
+ try {
17811
+ const tokenEndpoint = await import_subscriptions11.grokOAuth.resolveGrokTokenEndpoint(refreshFetch);
17812
+ const result = await import_subscriptions11.grokOAuth.refreshGrokAccessToken(grok.refreshToken, tokenEndpoint, refreshFetch);
17813
+ const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
17814
+ const next = {
17815
+ ...grok,
17816
+ accessToken: result.accessToken,
17817
+ refreshToken: result.refreshToken,
17818
+ expiresAt,
17819
+ status: "authorized",
17820
+ lastRefreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
17821
+ errorMessage: void 0,
17822
+ syncWarning: void 0
17823
+ };
17824
+ this.writeBackById("grok", capturedId, next);
17825
+ return true;
17826
+ } catch (error) {
17827
+ this.markExpiredById("grok", capturedId, grok, error);
17828
+ return false;
17829
+ }
17830
+ });
17831
+ }
17832
+ /**
17833
+ * "Refresh" a GitHub Copilot token — there is nothing to refresh (ghu_
17834
+ * tokens are long-lived with no exchange endpoint). A call here means the
17835
+ * strategy saw a 401 (the token was revoked); mark the account `expired`
17836
+ * with a re-authenticate message and return `false` (the proxy then declines
17837
+ * the retry instead of looping on a dead token).
17838
+ */
17839
+ async refreshCopilotToken() {
17840
+ return this.coalesce("copilot:active", async () => {
17841
+ const config = this.readConfig();
17842
+ const active = getActiveAccount(config, "copilot");
17843
+ const copilot = active?.tokens;
17844
+ if (!active || !copilot?.accessToken) return false;
17845
+ this.materializeMigration(config);
17846
+ this.markExpiredById(
17847
+ "copilot",
17848
+ active.id,
17849
+ copilot,
17850
+ new Error("GitHub Copilot tokens cannot be refreshed \u2014 re-authenticate the account")
17851
+ );
17852
+ return false;
17853
+ });
17854
+ }
16745
17855
  /**
16746
17856
  * Refresh a SPECIFIC managed account by id (background scheduler sweep and
16747
17857
  * account-pool resolution). It uses only that account's stored refresh
@@ -16794,7 +17904,7 @@ var JsonSubscriptionCredentialStore = class {
16794
17904
  }
16795
17905
  const oauth = account.tokens;
16796
17906
  if (!oauth.accessToken) return null;
16797
- if (providerId === "codex" || providerId === "gemini" || providerId === "kimi") {
17907
+ if (providerId === "codex" || providerId === "gemini" || providerId === "kimi" || providerId === "grok" || providerId === "copilot") {
16798
17908
  const expiresAtMs = oauth.expiresAt ? Date.parse(oauth.expiresAt) : 0;
16799
17909
  const expiringSoon = expiresAtMs > 0 && Date.now() >= expiresAtMs - ACCOUNT_REFRESH_LEAD_MS;
16800
17910
  if (expiringSoon && oauth.refreshToken) {
@@ -16887,10 +17997,10 @@ var JsonSubscriptionCredentialStore = class {
16887
17997
  if (provider === "kimi") {
16888
17998
  const account = accountId ? getAccountById(this.readConfig(), "kimi", accountId) : void 0;
16889
17999
  const deviceId = account?.tokens?.deviceId;
16890
- const r2 = await import_subscriptions8.kimiOAuth.refreshAccessToken(
18000
+ const r2 = await import_subscriptions11.kimiOAuth.refreshAccessToken(
16891
18001
  refreshToken,
16892
18002
  refreshFetch,
16893
- import_subscriptions8.kimiOAuth.kimiFingerprintHeaders(deviceId)
18003
+ import_subscriptions11.kimiOAuth.kimiFingerprintHeaders(deviceId)
16894
18004
  );
16895
18005
  return {
16896
18006
  accessToken: r2.accessToken,
@@ -16898,7 +18008,19 @@ var JsonSubscriptionCredentialStore = class {
16898
18008
  expiresAt: new Date(Date.now() + r2.expiresIn * 1e3).toISOString()
16899
18009
  };
16900
18010
  }
16901
- const flow = provider === "claude" ? import_subscriptions8.claudeOAuth : provider === "codex" ? import_subscriptions8.codexOAuth : import_subscriptions8.geminiOAuth;
18011
+ if (provider === "grok") {
18012
+ const tokenEndpoint = await import_subscriptions11.grokOAuth.resolveGrokTokenEndpoint(refreshFetch);
18013
+ const r2 = await import_subscriptions11.grokOAuth.refreshGrokAccessToken(refreshToken, tokenEndpoint, refreshFetch);
18014
+ return {
18015
+ accessToken: r2.accessToken,
18016
+ refreshToken: r2.refreshToken,
18017
+ expiresAt: new Date(Date.now() + r2.expiresIn * 1e3).toISOString()
18018
+ };
18019
+ }
18020
+ if (provider === "copilot") {
18021
+ throw new Error("GitHub Copilot tokens cannot be refreshed \u2014 re-authenticate the account");
18022
+ }
18023
+ const flow = provider === "claude" ? import_subscriptions11.claudeOAuth : provider === "codex" ? import_subscriptions11.codexOAuth : import_subscriptions11.geminiOAuth;
16902
18024
  const r = await flow.refreshAccessToken(refreshToken, refreshFetch);
16903
18025
  return {
16904
18026
  accessToken: r.accessToken,
@@ -17141,7 +18263,7 @@ var JsonSubscriptionCredentialStore = class {
17141
18263
  };
17142
18264
 
17143
18265
  // src/AccountHealthProbeScheduler.ts
17144
- var import_upstreamFetch10 = require("@omnicross/core/pipeline/upstreamFetch");
18266
+ var import_upstreamFetch13 = require("@omnicross/core/pipeline/upstreamFetch");
17145
18267
 
17146
18268
  // src/probe/CodexGenerationProbe.ts
17147
18269
  var import_codexCliHeaders = require("@omnicross/core/provider-proxy/identity/codexCliHeaders");
@@ -17284,7 +18406,16 @@ var PROVIDER_PROBE_PLANS = {
17284
18406
  // Kimi's `GET /coding/v1/usages` is a verified FREE authed GET (the allowance
17285
18407
  // collector uses it), but the probe path also needs the fingerprint headers —
17286
18408
  // keep the probe local until the collector covers the health surface.
17287
- kimi: { kind: "local" }
18409
+ kimi: { kind: "local" },
18410
+ // Grok's billing proxy is a verified FREE authed GET (the allowance collector
18411
+ // uses it) but it REJECTS non-OAuth credentials and sits on a separate host
18412
+ // with its own product-gate header — keep the probe local, the collector
18413
+ // owns the health surface.
18414
+ grok: { kind: "local" },
18415
+ // The Copilot quota endpoint (copilot_internal/user) is a verified FREE
18416
+ // authed GET but lives on api.github.com with its own auth dialect and a
18417
+ // monthly-only window — the allowance collector owns the health surface.
18418
+ copilot: { kind: "local" }
17288
18419
  };
17289
18420
  function probePlanFor(providerId) {
17290
18421
  return PROVIDER_PROBE_PLANS[providerId] ?? { kind: "local" };
@@ -17306,7 +18437,7 @@ var AccountHealthProbeScheduler = class {
17306
18437
  this.logger = logger;
17307
18438
  this.config = config;
17308
18439
  this.now = opts.now ?? Date.now;
17309
- this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch10.fetchUpstream;
18440
+ this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch13.fetchUpstream;
17310
18441
  this.sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
17311
18442
  this.planFor = opts.planFor ?? probePlanFor;
17312
18443
  }
@@ -17856,7 +18987,7 @@ async function readAuditStats(auditDir, query2 = {}) {
17856
18987
  }
17857
18988
 
17858
18989
  // src/audit/AuditPruneSweeper.ts
17859
- var DAY_MS3 = 24 * 60 * 6e4;
18990
+ var DAY_MS4 = 24 * 60 * 6e4;
17860
18991
  var SWEEP_INTERVAL_MS2 = 60 * 6e4;
17861
18992
  var ARCHIVE_BATCH = 64;
17862
18993
  var AuditPruneSweeper = class {
@@ -17920,7 +19051,7 @@ var AuditPruneSweeper = class {
17920
19051
  this.sweeping = true;
17921
19052
  try {
17922
19053
  if (!(0, import_node_fs30.existsSync)(this.auditDir)) return 0;
17923
- const cutoff = this.todayMidnight() - (this.config.retentionDays - 1) * DAY_MS3;
19054
+ const cutoff = this.todayMidnight() - (this.config.retentionDays - 1) * DAY_MS4;
17924
19055
  let removed = 0;
17925
19056
  for (const name of (0, import_node_fs30.readdirSync)(this.auditDir)) {
17926
19057
  const dateMs = auditFileDateMs(name);
@@ -18177,7 +19308,7 @@ async function closeAll(writers) {
18177
19308
  // src/usage/UsagePruneSweeper.ts
18178
19309
  var import_promises8 = require("fs/promises");
18179
19310
  var import_node_path31 = require("path");
18180
- var DAY_MS4 = 24 * 60 * 6e4;
19311
+ var DAY_MS5 = 24 * 60 * 6e4;
18181
19312
  var SWEEP_INTERVAL_MS3 = 60 * 6e4;
18182
19313
  var DEFAULT_USAGE_RETENTION_DAYS = 90;
18183
19314
  var UsagePruneSweeper = class {
@@ -18234,7 +19365,7 @@ var UsagePruneSweeper = class {
18234
19365
  this.sweeping = true;
18235
19366
  try {
18236
19367
  const retentionDays = this.config.retentionDays ?? DEFAULT_USAGE_RETENTION_DAYS;
18237
- const cutoff = this.todayMidnight() - (retentionDays - 1) * DAY_MS4;
19368
+ const cutoff = this.todayMidnight() - (retentionDays - 1) * DAY_MS5;
18238
19369
  let removed = 0;
18239
19370
  for (const entry of await listUsageDays(this.usageDir)) {
18240
19371
  if (!entry.hasShard) continue;
@@ -18462,7 +19593,7 @@ var AuditWriter = class {
18462
19593
  var import_node_fs34 = require("fs");
18463
19594
  var import_node_crypto24 = require("crypto");
18464
19595
  var import_node_path34 = require("path");
18465
- var import_upstreamFetch11 = require("@omnicross/core/pipeline/upstreamFetch");
19596
+ var import_upstreamFetch14 = require("@omnicross/core/pipeline/upstreamFetch");
18466
19597
 
18467
19598
  // src/billing/billingFiles.ts
18468
19599
  var BILLING_FILE_RE = /^billing-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
@@ -18485,7 +19616,7 @@ var BillingPublisher = class {
18485
19616
  constructor(billingDir, logger, opts = {}) {
18486
19617
  this.billingDir = billingDir;
18487
19618
  this.logger = logger;
18488
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch11.fetchUpstream)(url, init));
19619
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch14.fetchUpstream)(url, init));
18489
19620
  this.defer = opts.defer ?? ((fn) => setTimeout(fn, 0));
18490
19621
  this.timeoutMs = opts.timeoutMs ?? BILLING_POST_TIMEOUT_MS;
18491
19622
  this.now = opts.now ?? Date.now;
@@ -18735,7 +19866,7 @@ var BillingRetrySweeper = class {
18735
19866
  // src/TokenRefreshScheduler.ts
18736
19867
  var REFRESH_LEAD_MS2 = 5 * 6e4;
18737
19868
  var SWEEP_INTERVAL_MS5 = 6e4;
18738
- var OAUTH_PROVIDERS2 = ["claude", "codex", "gemini", "kimi"];
19869
+ var OAUTH_PROVIDERS2 = ["claude", "codex", "gemini", "kimi", "grok", "copilot"];
18739
19870
  var TokenRefreshScheduler = class {
18740
19871
  constructor(store, logger, intervalMs = SWEEP_INTERVAL_MS5, leadMs = REFRESH_LEAD_MS2) {
18741
19872
  this.store = store;
@@ -18820,6 +19951,12 @@ var TokenRefreshScheduler = class {
18820
19951
  return this.store.refreshGeminiToken();
18821
19952
  case "kimi":
18822
19953
  return this.store.refreshKimiToken();
19954
+ case "grok":
19955
+ return this.store.refreshGrokToken();
19956
+ // ghu_ tokens never near-expire (far-future expiresAt), so the sweep
19957
+ // never reaches this — the branch exists for union totality.
19958
+ case "copilot":
19959
+ return this.store.refreshCopilotToken();
18823
19960
  }
18824
19961
  }
18825
19962
  };
@@ -18896,7 +20033,7 @@ function createRouteLeaseSubscriptionPreflight(credentials) {
18896
20033
 
18897
20034
  // src/webhook/WebhookDispatcher.ts
18898
20035
  var import_node_crypto25 = require("crypto");
18899
- var import_upstreamFetch12 = require("@omnicross/core/pipeline/upstreamFetch");
20036
+ var import_upstreamFetch15 = require("@omnicross/core/pipeline/upstreamFetch");
18900
20037
  var WEBHOOK_MAX_ATTEMPTS = 3;
18901
20038
  var WEBHOOK_QUEUE_MAX = 1e3;
18902
20039
  var WEBHOOK_SEND_TIMEOUT_MS = 1e4;
@@ -18916,7 +20053,7 @@ var WebhookDispatcher = class {
18916
20053
  sleep;
18917
20054
  now;
18918
20055
  constructor(opts = {}) {
18919
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch12.fetchUpstream)(url, init));
20056
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch15.fetchUpstream)(url, init));
18920
20057
  this.logger = opts.logger;
18921
20058
  this.maxAttempts = opts.maxAttempts ?? WEBHOOK_MAX_ATTEMPTS;
18922
20059
  this.queueMax = opts.queueMax ?? WEBHOOK_QUEUE_MAX;
@@ -19002,8 +20139,8 @@ var WebhookDispatcher = class {
19002
20139
  signal: AbortSignal.timeout(this.timeoutMs)
19003
20140
  });
19004
20141
  return res.ok ? { ok: true, status: res.status } : { ok: false, status: res.status };
19005
- } catch (err6) {
19006
- return { ok: false, error: err6 instanceof Error ? err6.message : String(err6) };
20142
+ } catch (err8) {
20143
+ return { ok: false, error: err8 instanceof Error ? err8.message : String(err8) };
19007
20144
  }
19008
20145
  }
19009
20146
  /**
@@ -19066,7 +20203,7 @@ function feishuText(event) {
19066
20203
  // src/bootstrap.ts
19067
20204
  var activeImageRuntimeBootstrapSession;
19068
20205
  function createImageRuntimeBootstrapSession(initialGeneration) {
19069
- const openAIOperationRegistry = new import_core4.OpenAIOperationRegistry();
20206
+ const openAIOperationRegistry = new import_core7.OpenAIOperationRegistry();
19070
20207
  const imageRuntimeManager = new ImageRuntimeManager(initialGeneration);
19071
20208
  const unregisterContributions = [];
19072
20209
  try {
@@ -19140,12 +20277,12 @@ function buildDaemon(config, paths) {
19140
20277
  setSecretBox(secretBox3);
19141
20278
  setSecretBox2(secretBox3);
19142
20279
  const decryptedConfig = decryptConfigSecrets(config, secretBox3);
19143
- const accountAllowanceStore = new import_AccountAllowanceStore7.AccountAllowanceStore(
20280
+ const accountAllowanceStore = new import_AccountAllowanceStore10.AccountAllowanceStore(
19144
20281
  Date.now,
19145
20282
  void 0,
19146
20283
  new JsonAccountAllowancePersistence(defaultAccountAllowancePath(paths.configPath))
19147
20284
  );
19148
- (0, import_AccountAllowanceStore7.setSharedAccountAllowanceStore)(accountAllowanceStore);
20285
+ (0, import_AccountAllowanceStore10.setSharedAccountAllowanceStore)(accountAllowanceStore);
19149
20286
  (0, import_AccountAllowanceScheduling5.getSharedAccountAllowanceScheduling)().configure(
19150
20287
  (0, import_outbound_api10.normalizeServerConfig)(decryptedConfig.server).allowanceScheduling
19151
20288
  );
@@ -19170,20 +20307,20 @@ function buildDaemon(config, paths) {
19170
20307
  claudeAllowanceRefreshScheduler.configure(
19171
20308
  (0, import_outbound_api10.normalizeServerConfig)(decryptedConfig.server).allowanceScheduling
19172
20309
  );
19173
- const subscriptionAccounts = new import_subscriptions9.SubscriptionAccountService(credentialStore);
19174
- (0, import_subscriptions9.setSubscriptionAccountService)(subscriptionAccounts);
19175
- const subscriptionRegistry = new import_subscriptions9.SubscriptionProviderRegistry(
20310
+ const subscriptionAccounts = new import_subscriptions12.SubscriptionAccountService(credentialStore);
20311
+ (0, import_subscriptions12.setSubscriptionAccountService)(subscriptionAccounts);
20312
+ const subscriptionRegistry = new import_subscriptions12.SubscriptionProviderRegistry(
19176
20313
  subscriptionAccounts,
19177
20314
  credentialStore
19178
20315
  );
19179
- (0, import_subscriptions9.setSubscriptionProviderRegistry)(subscriptionRegistry);
20316
+ (0, import_subscriptions12.setSubscriptionProviderRegistry)(subscriptionRegistry);
19180
20317
  setServerProxyConfig(decryptedConfig.server?.proxy);
19181
- (0, import_upstreamFetch13.setUpstreamProxyResolver)(
20318
+ (0, import_upstreamFetch16.setUpstreamProxyResolver)(
19182
20319
  createUpstreamProxyResolver({
19183
20320
  getAccountProxy: (providerId, accountId) => credentialStore.getAccountProxy(providerId, accountId)
19184
20321
  })
19185
20322
  );
19186
- (0, import_gemini_code_assist_resolver.setGeminiCodeAssistResolver)((0, import_GeminiCodeAssistProjectResolver.getGeminiCodeAssistProjectResolver)());
20323
+ (0, import_gemini_code_assist_resolver.setGeminiCodeAssistResolver)((0, import_GeminiCodeAssistProjectResolver2.getGeminiCodeAssistProjectResolver)());
19187
20324
  const autoDisableStore = new AutoDisableStore();
19188
20325
  const providerKeyQuotaService = new ProviderKeyQuotaService(secretBox3);
19189
20326
  const apiKeyPool = new import_ApiKeyPoolService.ApiKeyPoolService(
@@ -19202,7 +20339,7 @@ function buildDaemon(config, paths) {
19202
20339
  const pricingEngine = new import_usage2.PricingEngine(pricingStore, logger, {
19203
20340
  // Catalog egress follows the same global/env proxy policy as every other
19204
20341
  // daemon upstream call; no provider/account override applies here.
19205
- fetchImpl: ((input, init) => (0, import_upstreamFetch13.fetchUpstream)(String(input), init ?? {}))
20342
+ fetchImpl: ((input, init) => (0, import_upstreamFetch16.fetchUpstream)(String(input), init ?? {}))
19206
20343
  });
19207
20344
  const pricingRefreshScheduler = new PricingRefreshScheduler(
19208
20345
  pricingEngine,
@@ -19487,7 +20624,7 @@ function buildDaemon(config, paths) {
19487
20624
  // — `server.proxy.byProvider[...]` was silently skipped — and the call was
19488
20625
  // excluded from the upstream trace, so a failing login left no evidence.
19489
20626
  // `redactBodies` keeps the code/verifier + minted token out of that trace.
19490
- oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => (0, import_upstreamFetch13.fetchUpstream)(url, init, { providerId, redactBodies: true }),
20627
+ oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => (0, import_upstreamFetch16.fetchUpstream)(url, init, { providerId, redactBodies: true }),
19491
20628
  subscriptionAccountAppender: credentialStore,
19492
20629
  // Codex interactive OAuth (app-parity-2 child 5) — the async loopback flow store
19493
20630
  // + the one-shot 127.0.0.1:1455 listener. Token captured + persisted daemon-side;
@@ -19499,6 +20636,9 @@ function buildDaemon(config, paths) {
19499
20636
  // paste; the app shows the verification URL + user code and polls the
19500
20637
  // token-free status). Token captured + persisted daemon-side.
19501
20638
  kimiSessions: new CodexOAuthSessionStore(),
20639
+ // Grok interactive OAuth — the same async DEVICE-CODE shape as kimi.
20640
+ grokSessions: new CodexOAuthSessionStore(),
20641
+ copilotSessions: new CodexOAuthSessionStore(),
19502
20642
  // Migration pack (app-parity child 6, design D2/D3) — the concrete credential
19503
20643
  // store provides BOTH the full DECRYPTED read (`getFullConfig`, export) and
19504
20644
  // the multi-account append (`appendProviderAccount`, import re-encrypts at-
@@ -19557,7 +20697,7 @@ function buildDaemon(config, paths) {
19557
20697
  });
19558
20698
  const webhookDispatcher = new WebhookDispatcher({
19559
20699
  logger,
19560
- fetchImpl: (url, init) => (0, import_upstreamFetch13.fetchUpstream)(url, init)
20700
+ fetchImpl: (url, init) => (0, import_upstreamFetch16.fetchUpstream)(url, init)
19561
20701
  });
19562
20702
  setWebhookRuntime(webhookDispatcher, (0, import_SubscriptionAccountHealth4.getSharedAccountHealth)());
19563
20703
  const auditWriter = new AuditWriter(auditDir, logger);
@@ -19871,11 +21011,11 @@ async function runLiveProbe(url, key, fetchImpl = fetch) {
19871
21011
  status: res.status,
19872
21012
  estimateHeader: res.headers.get("x-omnicross-count-estimate")
19873
21013
  };
19874
- } catch (err6) {
21014
+ } catch (err8) {
19875
21015
  return {
19876
21016
  status: null,
19877
21017
  estimateHeader: null,
19878
- error: err6 instanceof Error ? err6.message : String(err6)
21018
+ error: err8 instanceof Error ? err8.message : String(err8)
19879
21019
  };
19880
21020
  }
19881
21021
  }
@@ -20282,9 +21422,9 @@ async function runLaunch(argv, deps) {
20282
21422
  await daemon.llmConfig.ready();
20283
21423
  await daemon.migrateUsageStore();
20284
21424
  await daemon.providerProxy.start();
20285
- } catch (err6) {
21425
+ } catch (err8) {
20286
21426
  await shutdownLaunchDaemon(daemon);
20287
- throw err6;
21427
+ throw err8;
20288
21428
  }
20289
21429
  let launch;
20290
21430
  try {
@@ -20292,9 +21432,9 @@ async function runLaunch(argv, deps) {
20292
21432
  providerId: values.provider,
20293
21433
  model: values.model
20294
21434
  });
20295
- } catch (err6) {
21435
+ } catch (err8) {
20296
21436
  await shutdownLaunchDaemon(daemon);
20297
- throw err6;
21437
+ throw err8;
20298
21438
  }
20299
21439
  try {
20300
21440
  const plan = buildCliSpawnPlan({
@@ -20399,9 +21539,9 @@ function spawnCliInherit(plan) {
20399
21539
  process.removeListener("SIGINT", onSignal);
20400
21540
  process.removeListener("SIGTERM", onSignal);
20401
21541
  };
20402
- child.on("error", (err6) => {
21542
+ child.on("error", (err8) => {
20403
21543
  detach();
20404
- if (err6.code === "ENOENT") {
21544
+ if (err8.code === "ENOENT") {
20405
21545
  reject(
20406
21546
  new Error(
20407
21547
  `launch: "${plan.command}" not found on PATH \u2014 install the CLI first.`
@@ -20409,7 +21549,7 @@ function spawnCliInherit(plan) {
20409
21549
  );
20410
21550
  return;
20411
21551
  }
20412
- reject(err6);
21552
+ reject(err8);
20413
21553
  });
20414
21554
  child.on("exit", (code, signal) => {
20415
21555
  detach();
@@ -20422,9 +21562,9 @@ function spawnCliInherit(plan) {
20422
21562
  var import_node_child_process3 = require("child_process");
20423
21563
  var import_node_readline2 = require("readline");
20424
21564
  var import_node_util7 = require("util");
20425
- var import_upstreamFetch14 = require("@omnicross/core/pipeline/upstreamFetch");
20426
- var import_subscriptions10 = require("@omnicross/subscriptions");
20427
- var PROVIDERS2 = ["claude", "codex", "gemini", "kimi"];
21565
+ var import_upstreamFetch17 = require("@omnicross/core/pipeline/upstreamFetch");
21566
+ var import_subscriptions13 = require("@omnicross/subscriptions");
21567
+ var PROVIDERS2 = ["claude", "codex", "gemini", "kimi", "grok", "copilot"];
20428
21568
  async function runLogin(argv, deps) {
20429
21569
  const { values, positionals } = (0, import_node_util7.parseArgs)({
20430
21570
  args: argv,
@@ -20432,7 +21572,9 @@ async function runLogin(argv, deps) {
20432
21572
  config: { type: "string", short: "c" },
20433
21573
  "master-key-file": { type: "string" },
20434
21574
  // Optional user label for the appended account (multi-account).
20435
- label: { type: "string" }
21575
+ label: { type: "string" },
21576
+ // Optional GitHub Enterprise domain for `login copilot` (GHE accounts).
21577
+ enterprise: { type: "string" }
20436
21578
  },
20437
21579
  allowPositionals: true
20438
21580
  });
@@ -20446,46 +21588,55 @@ async function runLogin(argv, deps) {
20446
21588
  if (!values.config) {
20447
21589
  throw new Error("login: --config <path> is required");
20448
21590
  }
21591
+ if (values.enterprise !== void 0 && provider !== "copilot") {
21592
+ throw new Error("login: --enterprise is only supported for the copilot provider");
21593
+ }
21594
+ const enterpriseDomain = values.enterprise !== void 0 ? import_subscriptions13.copilotOAuth.normalizeCopilotEnterpriseDomain(values.enterprise) : void 0;
20449
21595
  const resolved = {
20450
21596
  openBrowser: deps?.openBrowser ?? openBrowser,
20451
21597
  promptPaste: deps?.promptPaste ?? promptPaste,
20452
21598
  awaitLoopback: deps?.awaitLoopback ?? ((state) => awaitLoopbackCode(state)),
20453
21599
  awaitKimiDevice: deps?.awaitKimiDevice ?? ((fetchImpl) => runKimiDeviceFlow(fetchImpl, resolvedOpenBrowser)),
21600
+ awaitGrokDevice: deps?.awaitGrokDevice ?? ((fetchImpl) => runGrokDeviceFlow(fetchImpl, resolvedOpenBrowser)),
21601
+ awaitCopilotDevice: deps?.awaitCopilotDevice ?? ((fetchImpl, enterpriseUrl) => runCopilotDeviceFlow(fetchImpl, resolvedOpenBrowser, enterpriseUrl)),
20454
21602
  tokensFetch: deps?.tokensFetch
20455
21603
  };
20456
21604
  const resolvedOpenBrowser = resolved.openBrowser;
20457
21605
  const box = resolveSecretBox(values["master-key-file"]);
20458
21606
  setSecretBox(box);
20459
- (0, import_upstreamFetch14.setUpstreamProxyResolver)(createUpstreamProxyResolver());
21607
+ (0, import_upstreamFetch17.setUpstreamProxyResolver)(createUpstreamProxyResolver());
20460
21608
  try {
20461
21609
  const tokensPath = defaultTokensPath(values.config);
20462
- const exchangeFetch = resolved.tokensFetch ?? ((url, init) => (0, import_upstreamFetch14.fetchUpstream)(url, init, { providerId: provider, redactBodies: true }));
21610
+ const exchangeFetch = resolved.tokensFetch ?? ((url, init) => (0, import_upstreamFetch17.fetchUpstream)(url, init, { providerId: provider, redactBodies: true }));
20463
21611
  const store = new JsonSubscriptionCredentialStore(tokensPath, box, exchangeFetch);
20464
21612
  const expiresAt = await runProviderLogin(
20465
21613
  provider,
20466
21614
  store,
20467
21615
  resolved,
20468
21616
  exchangeFetch,
20469
- values.label
21617
+ values.label,
21618
+ enterpriseDomain
20470
21619
  );
20471
21620
  console.info(`Logged in to '${provider}' \u2192 ${tokensPath}`);
20472
21621
  console.info(` token: [stored, encrypted] expiresAt: ${expiresAt ?? "n/a"}`);
20473
21622
  } finally {
20474
21623
  setSecretBox(null);
20475
- (0, import_upstreamFetch14.setUpstreamProxyResolver)(null);
21624
+ (0, import_upstreamFetch17.setUpstreamProxyResolver)(null);
20476
21625
  }
20477
21626
  }
20478
- async function runProviderLogin(provider, store, deps, exchangeFetch, label) {
21627
+ async function runProviderLogin(provider, store, deps, exchangeFetch, label, enterpriseUrl) {
20479
21628
  if (provider === "codex") return loginCodex(store, deps, exchangeFetch, label);
20480
21629
  if (provider === "claude") return loginClaude(store, deps, exchangeFetch, label);
20481
21630
  if (provider === "kimi") return loginKimi(store, deps, exchangeFetch, label);
21631
+ if (provider === "grok") return loginGrok(store, deps, exchangeFetch, label);
21632
+ if (provider === "copilot") return loginCopilot(store, deps, exchangeFetch, label, enterpriseUrl);
20482
21633
  return loginGemini(store, deps, exchangeFetch, label);
20483
21634
  }
20484
21635
  async function loginCodex(store, deps, exchangeFetch, label) {
20485
- const { authUrl, codeVerifier, state } = import_subscriptions10.codexOAuth.generateAuthParams();
21636
+ const { authUrl, codeVerifier, state } = import_subscriptions13.codexOAuth.generateAuthParams();
20486
21637
  await presentUrl(authUrl, deps);
20487
21638
  const code = await deps.awaitLoopback(state);
20488
- const result = await import_subscriptions10.codexOAuth.exchangeCodeForTokens(
21639
+ const result = await import_subscriptions13.codexOAuth.exchangeCodeForTokens(
20489
21640
  { authorizationCode: code, codeVerifier, state },
20490
21641
  exchangeFetch
20491
21642
  );
@@ -20504,7 +21655,7 @@ async function loginCodex(store, deps, exchangeFetch, label) {
20504
21655
  return expiresAt;
20505
21656
  }
20506
21657
  async function loginClaude(store, deps, exchangeFetch, label) {
20507
- const { authUrl, codeVerifier, state } = import_subscriptions10.claudeOAuth.generateAuthParams();
21658
+ const { authUrl, codeVerifier, state } = import_subscriptions13.claudeOAuth.generateAuthParams();
20508
21659
  await presentUrl(authUrl, deps);
20509
21660
  const pasted = (await deps.promptPaste("Paste the authorization code (code#state): ")).trim();
20510
21661
  const [code, pastedState] = pasted.split("#");
@@ -20512,7 +21663,7 @@ async function loginClaude(store, deps, exchangeFetch, label) {
20512
21663
  if (pastedState && pastedState !== state) {
20513
21664
  throw new Error("login: pasted state did not match (possible CSRF) \u2014 aborting");
20514
21665
  }
20515
- const result = await import_subscriptions10.claudeOAuth.exchangeCodeForTokens(
21666
+ const result = await import_subscriptions13.claudeOAuth.exchangeCodeForTokens(
20516
21667
  { authorizationCode: code, codeVerifier, state },
20517
21668
  exchangeFetch
20518
21669
  );
@@ -20531,11 +21682,11 @@ async function loginClaude(store, deps, exchangeFetch, label) {
20531
21682
  return expiresAt;
20532
21683
  }
20533
21684
  async function loginGemini(store, deps, exchangeFetch, label) {
20534
- const { authUrl, codeVerifier } = import_subscriptions10.geminiOAuth.generateAuthParams();
21685
+ const { authUrl, codeVerifier } = import_subscriptions13.geminiOAuth.generateAuthParams();
20535
21686
  await presentUrl(authUrl, deps);
20536
21687
  const code = (await deps.promptPaste("Paste the authorization code: ")).trim();
20537
21688
  if (!code) throw new Error("login: no authorization code was pasted");
20538
- const result = await import_subscriptions10.geminiOAuth.exchangeCodeForTokens(code, codeVerifier, exchangeFetch);
21689
+ const result = await import_subscriptions13.geminiOAuth.exchangeCodeForTokens(code, codeVerifier, exchangeFetch);
20539
21690
  const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
20540
21691
  const block = {
20541
21692
  authMethod: "oauth",
@@ -20550,9 +21701,9 @@ async function loginGemini(store, deps, exchangeFetch, label) {
20550
21701
  return expiresAt;
20551
21702
  }
20552
21703
  async function runKimiDeviceFlow(exchangeFetch, openBrowserFn) {
20553
- const deviceId = import_subscriptions10.kimiOAuth.generateKimiDeviceId();
20554
- const fingerprint = import_subscriptions10.kimiOAuth.kimiFingerprintHeaders(deviceId);
20555
- const authorization = await import_subscriptions10.kimiOAuth.requestDeviceAuthorization(exchangeFetch, fingerprint);
21704
+ const deviceId = import_subscriptions13.kimiOAuth.generateKimiDeviceId();
21705
+ const fingerprint = import_subscriptions13.kimiOAuth.kimiFingerprintHeaders(deviceId);
21706
+ const authorization = await import_subscriptions13.kimiOAuth.requestDeviceAuthorization(exchangeFetch, fingerprint);
20556
21707
  const url = authorization.verificationUriComplete ?? authorization.verificationUri;
20557
21708
  console.info("Open this URL in your browser and approve the request:");
20558
21709
  console.info(` ${url}`);
@@ -20560,14 +21711,14 @@ async function runKimiDeviceFlow(exchangeFetch, openBrowserFn) {
20560
21711
  console.info(` Then enter this code: ${authorization.userCode}`);
20561
21712
  }
20562
21713
  await openBrowserFn(url).catch(() => false);
20563
- const result = await import_subscriptions10.kimiOAuth.awaitDeviceToken(authorization, exchangeFetch, {
21714
+ const result = await import_subscriptions13.kimiOAuth.awaitDeviceToken(authorization, exchangeFetch, {
20564
21715
  fingerprint,
20565
21716
  onPending: () => process.stdout.write(".")
20566
21717
  });
20567
21718
  console.info("");
20568
21719
  return {
20569
21720
  ...result,
20570
- accountId: import_subscriptions10.kimiOAuth.kimiAccountIdFromAccessToken(result.accessToken),
21721
+ accountId: import_subscriptions13.kimiOAuth.kimiAccountIdFromAccessToken(result.accessToken),
20571
21722
  deviceId
20572
21723
  };
20573
21724
  }
@@ -20588,6 +21739,90 @@ async function loginKimi(store, deps, exchangeFetch, label) {
20588
21739
  logMasked("kimi", result.accessToken);
20589
21740
  return expiresAt;
20590
21741
  }
21742
+ async function runGrokDeviceFlow(exchangeFetch, openBrowserFn) {
21743
+ const tokenEndpoint = await import_subscriptions13.grokOAuth.resolveGrokTokenEndpoint(exchangeFetch);
21744
+ const authorization = await import_subscriptions13.grokOAuth.requestGrokDeviceAuthorization(exchangeFetch);
21745
+ const url = authorization.verificationUriComplete ?? authorization.verificationUri;
21746
+ console.info("Open this URL in your browser and approve the request:");
21747
+ console.info(` ${url}`);
21748
+ if (!authorization.verificationUriComplete) {
21749
+ console.info(` Then enter this code: ${authorization.userCode}`);
21750
+ }
21751
+ await openBrowserFn(url).catch(() => false);
21752
+ const result = await import_subscriptions13.grokOAuth.awaitGrokDeviceToken(authorization, tokenEndpoint, exchangeFetch, {
21753
+ onPending: () => process.stdout.write(".")
21754
+ });
21755
+ console.info("");
21756
+ return {
21757
+ ...result,
21758
+ accountId: import_subscriptions13.grokOAuth.grokAccountIdFromAccessToken(result.accessToken)
21759
+ };
21760
+ }
21761
+ async function loginGrok(store, deps, exchangeFetch, label) {
21762
+ const result = await deps.awaitGrokDevice(exchangeFetch);
21763
+ const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
21764
+ const block = {
21765
+ authMethod: "oauth",
21766
+ status: "authorized",
21767
+ accessToken: result.accessToken,
21768
+ refreshToken: result.refreshToken,
21769
+ expiresAt,
21770
+ ...result.accountId ? { accountId: result.accountId } : {},
21771
+ lastRefreshedAt: (/* @__PURE__ */ new Date()).toISOString()
21772
+ };
21773
+ await store.appendProviderAccount("grok", block, label);
21774
+ logMasked("grok", result.accessToken);
21775
+ return expiresAt;
21776
+ }
21777
+ async function runCopilotDeviceFlow(exchangeFetch, openBrowserFn, enterpriseUrl) {
21778
+ if (enterpriseUrl) console.info(`Using GitHub Enterprise host: ${enterpriseUrl}`);
21779
+ const authorization = await import_subscriptions13.copilotOAuth.requestCopilotDeviceAuthorization(exchangeFetch, enterpriseUrl);
21780
+ const url = authorization.verificationUri;
21781
+ console.info("Open this URL in your browser and approve the request:");
21782
+ console.info(` ${url}`);
21783
+ console.info(` Then enter this code: ${authorization.userCode}`);
21784
+ await openBrowserFn(url).catch(() => false);
21785
+ const result = await import_subscriptions13.copilotOAuth.awaitCopilotDeviceToken(authorization, exchangeFetch, {
21786
+ onPending: () => process.stdout.write("."),
21787
+ ...enterpriseUrl ? { enterpriseUrl } : {}
21788
+ });
21789
+ console.info("");
21790
+ const identity = await import_subscriptions13.copilotOAuth.fetchCopilotIdentity(result.accessToken, exchangeFetch, enterpriseUrl);
21791
+ const apiEndpoint = await import_subscriptions13.copilotOAuth.discoverCopilotApiEndpoint(result.accessToken, exchangeFetch, enterpriseUrl);
21792
+ console.info("Enabling Copilot models (policy)...");
21793
+ await import_subscriptions13.copilotOAuth.enableAllCopilotModels(
21794
+ result.accessToken,
21795
+ { apiEndpoint, ...enterpriseUrl ? { enterpriseUrl } : {} },
21796
+ exchangeFetch
21797
+ );
21798
+ return {
21799
+ accessToken: result.accessToken,
21800
+ expiresIn: Math.floor(import_subscriptions13.copilotOAuth.COPILOT_FAR_FUTURE_MS / 1e3),
21801
+ ...identity,
21802
+ ...apiEndpoint ? { apiEndpoint } : {}
21803
+ };
21804
+ }
21805
+ async function loginCopilot(store, deps, exchangeFetch, label, enterpriseUrl) {
21806
+ const result = await deps.awaitCopilotDevice(exchangeFetch, enterpriseUrl);
21807
+ const expiresAt = new Date(Date.now() + result.expiresIn * 1e3).toISOString();
21808
+ const block = {
21809
+ authMethod: "oauth",
21810
+ status: "authorized",
21811
+ accessToken: result.accessToken,
21812
+ // ghu_ tokens have no refresh lifecycle — the same token doubles as the
21813
+ // stored refresh credential so generic refresh paths stay well-formed.
21814
+ refreshToken: result.accessToken,
21815
+ expiresAt,
21816
+ ...result.accountId ? { accountId: result.accountId } : {},
21817
+ ...result.email ? { email: result.email } : {},
21818
+ ...result.apiEndpoint ? { apiEndpoint: result.apiEndpoint } : {},
21819
+ ...enterpriseUrl ? { enterpriseUrl } : {},
21820
+ lastRefreshedAt: (/* @__PURE__ */ new Date()).toISOString()
21821
+ };
21822
+ await store.appendProviderAccount("copilot", block, label);
21823
+ logMasked("copilot", result.accessToken);
21824
+ return expiresAt;
21825
+ }
20591
21826
  function isLoginProvider(value) {
20592
21827
  return PROVIDERS2.includes(value);
20593
21828
  }
@@ -21293,7 +22528,7 @@ async function main() {
21293
22528
  process.exitCode = 1;
21294
22529
  }
21295
22530
  }
21296
- main().catch((err6) => {
21297
- console.error(err6 instanceof Error ? err6.message : String(err6));
22531
+ main().catch((err8) => {
22532
+ console.error(err8 instanceof Error ? err8.message : String(err8));
21298
22533
  process.exitCode = 1;
21299
22534
  });