@codexhost/cli-win32-arm64 0.13.2 → 0.13.3

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.
@@ -14835,6 +14835,48 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14835
14835
  initializeOnly: external_exports.boolean().optional()
14836
14836
  });
14837
14837
 
14838
+ // ../shared-contracts/dist/harness-presentation.js
14839
+ var localeSchema = external_exports.string().max(64).regex(/^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/u);
14840
+ var displayText = (maximum) => external_exports.string().min(1).max(maximum).refine((text) => text.trim().length > 0);
14841
+ var harnessLocalizationsSchema = external_exports.record(localeSchema, external_exports.object({
14842
+ label: displayText(256).optional(),
14843
+ description: displayText(1024).optional()
14844
+ }).strict()).refine((entries) => Object.keys(entries).length <= 16, "Too many locales");
14845
+ var harnessLocalizedTextSchema = external_exports.record(localeSchema, displayText(4096)).refine((entries) => typeof entries.en === "string", "English fallback is required").refine((entries) => Object.keys(entries).length <= 16, "Too many locales");
14846
+ function translation(entries, locale) {
14847
+ if (!entries)
14848
+ return void 0;
14849
+ const language = locale.split("-")[0] ?? locale;
14850
+ for (const candidate of [locale, language]) {
14851
+ if (Object.hasOwn(entries, candidate))
14852
+ return entries[candidate];
14853
+ }
14854
+ return void 0;
14855
+ }
14856
+ function localizeHarnessPresentation(value, locale) {
14857
+ const localized = translation(value.localizations, locale);
14858
+ const language = translation(value.localizations, locale.split("-")[0] ?? locale);
14859
+ return {
14860
+ label: localized?.label ?? language?.label ?? value.label,
14861
+ description: localized?.description ?? language?.description ?? value.description
14862
+ };
14863
+ }
14864
+ function localizeHarnessText(value, locale) {
14865
+ return translation(value, locale) ?? value.en ?? "";
14866
+ }
14867
+
14868
+ // ../shared-contracts/dist/account-credits-presentation.js
14869
+ function accountCreditsWindowLabel(window2, locale, periodLabel) {
14870
+ if (window2.periodType && window2.periodType !== "unknown" && (window2.scope || !window2.label)) {
14871
+ const period = periodLabel(window2.periodType);
14872
+ return window2.scope ? `${localizeHarnessPresentation(window2.scope, locale).label} \xB7 ${period}` : period;
14873
+ }
14874
+ return localizeHarnessPresentation({
14875
+ label: window2.label ?? window2.product ?? periodLabel("unknown"),
14876
+ ...window2.localizations ? { localizations: window2.localizations } : {}
14877
+ }, locale).label;
14878
+ }
14879
+
14838
14880
  // ../shared-contracts/dist/model-price-overrides.js
14839
14881
  var MODEL_PRICE_OVERRIDES_GET_METHOD = "codexhost/usage/model-prices/get";
14840
14882
  var MODEL_PRICE_OVERRIDES_SET_METHOD = "codexhost/usage/model-prices/set";
@@ -15179,8 +15221,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15179
15221
  }
15180
15222
  });
15181
15223
  var usagePercentSchema = external_exports.number().finite().min(0).max(100);
15224
+ var accountCreditsPeriodSchema = external_exports.enum([
15225
+ "weekly",
15226
+ "monthly",
15227
+ "five_hour",
15228
+ "seven_day",
15229
+ "unknown"
15230
+ ]);
15231
+ var accountCreditsScopeSchema = external_exports.object({
15232
+ id: external_exports.string().min(1).max(256),
15233
+ label: external_exports.string().min(1).max(256),
15234
+ localizations: harnessLocalizationsSchema.optional()
15235
+ }).strict();
15182
15236
  var accountCreditsProductUsageSchema = external_exports.object({
15183
15237
  product: external_exports.string().min(1),
15238
+ /** Native period and scope, never inferred from the display name. */
15239
+ periodType: accountCreditsPeriodSchema.optional(),
15240
+ scope: accountCreditsScopeSchema.optional(),
15241
+ localizations: harnessLocalizationsSchema.optional(),
15184
15242
  used: external_exports.number().finite().nonnegative().optional(),
15185
15243
  // Zero is a real empty cap, not an absent field.
15186
15244
  limit: external_exports.number().finite().nonnegative().optional(),
@@ -15200,9 +15258,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15200
15258
  unit: external_exports.string().min(1).max(32).optional(),
15201
15259
  /** Native label when the primary limit is scoped to a model or product group. */
15202
15260
  label: external_exports.string().min(1).optional(),
15261
+ scope: accountCreditsScopeSchema.optional(),
15262
+ localizations: harnessLocalizationsSchema.optional(),
15203
15263
  usedPercent: usagePercentSchema,
15204
15264
  resetsAt: external_exports.string().min(1).optional(),
15205
- periodType: external_exports.enum(["weekly", "monthly", "five_hour", "seven_day", "unknown"]),
15265
+ periodType: accountCreditsPeriodSchema,
15206
15266
  productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional(),
15207
15267
  resetCredits: accountResetCreditsSchema.optional()
15208
15268
  }).strict();
@@ -15213,7 +15273,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15213
15273
  var threadUsageInspectionSchema = external_exports.object({
15214
15274
  threadId: hostThreadIdSchema,
15215
15275
  usage: threadUsageSnapshotSchema.nullable(),
15216
- accountCredits: accountCreditsSnapshotSchema.optional()
15276
+ accountCredits: accountCreditsSnapshotSchema.optional(),
15277
+ /** Whether this source can provide cached account quota independently of usage. */
15278
+ accountCreditsSupported: external_exports.boolean().optional()
15217
15279
  }).strict();
15218
15280
 
15219
15281
  // ../shared-contracts/dist/harness-accounts.js
@@ -15340,7 +15402,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15340
15402
  id: harnessPermissionModeIdSchema,
15341
15403
  label: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_LABEL_MAX_LENGTH),
15342
15404
  description: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_DESCRIPTION_MAX_LENGTH).optional(),
15343
- dangerous: external_exports.boolean().optional()
15405
+ dangerous: external_exports.boolean().optional(),
15406
+ localizations: harnessLocalizationsSchema.optional()
15344
15407
  }).strict();
15345
15408
  var harnessPermissionModeCatalogSchema = external_exports.object({
15346
15409
  modes: external_exports.array(harnessPermissionModeSchema).min(1).max(HARNESS_PERMISSION_MODE_CATALOG_MAX_LENGTH),
@@ -15763,6 +15826,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15763
15826
  // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15764
15827
  message: external_exports.string().max(2048).optional(),
15765
15828
  messageCode: external_exports.string().min(1).max(128).optional(),
15829
+ /** Safe plugin-owned explanation, distinct from raw diagnostic message. */
15830
+ notice: harnessLocalizedTextSchema.optional(),
15766
15831
  latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15767
15832
  }).strict();
15768
15833
 
@@ -15894,6 +15959,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15894
15959
  invocation: commandInvocationSchema,
15895
15960
  label: commandLabelSchema,
15896
15961
  description: commandDescriptionSchema.optional(),
15962
+ localizations: harnessLocalizationsSchema.optional(),
15897
15963
  argumentMode: external_exports.enum(["none", "text"]),
15898
15964
  /**
15899
15965
  * Native distinction reported by the Harness. Omitted when the Harness does
@@ -17457,37 +17523,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17457
17523
 
17458
17524
  // src/settings/harness-version-messages.ts
17459
17525
  var harnessVersionEnglish = Object.freeze({
17526
+ locale: "en",
17460
17527
  unknown: "Unknown",
17461
17528
  trackingBranch: "Tracking branch (new commits)",
17462
17529
  notes: Object.freeze({
17463
- "original-installer": "Use the original installer, package manager, or launcher to update this installation.",
17464
- "claude-policy-restricted": "Claude updates are restricted by the installation's settings or policy.",
17465
- "codebuddy-npm-required": "Use CodeBuddy's native updater or original package manager. Latest-version checks here require an identified npm installation.",
17466
- "deepseek-original-installer": "Update with the original installer. Python, desktop, and project-local installations are not upgraded through global npm.",
17467
- "kiro-native-updater": "Use Kiro CLI's original installer or native updater to check for and install updates.",
17468
- "zcode-desktop-updater": "The CLI ships inside ZCode Desktop. Update ZCode Desktop itself to update it.",
17469
- "qoder-check-unavailable": "This Qoder China release does not expose a non-installing update check. Use its original installer.",
17470
- "hermes-update-plan-unavailable": "This Hermes release does not expose a safe update plan. Use the original installer.",
17471
- "hermes-externally-managed": "This Hermes installation is managed externally. Update it through its desktop app, container, or original package manager.",
17472
- "hermes-update-channel": "Uses Hermes's configured update channel. Gateway restarts are deferred; existing processes keep their running code.",
17473
- "hermes-manual-update": "Use the native updater manually. Safe non-interactive updates require a clean source checkout, commit identity, and Gateway restart deferral."
17530
+ "original-installer": "Use the original installer, package manager, or launcher to update this installation."
17474
17531
  })
17475
17532
  });
17476
17533
  var harnessVersionChinese = Object.freeze({
17534
+ locale: "zh-CN",
17477
17535
  unknown: "\u672A\u77E5",
17478
17536
  trackingBranch: "\u8DDF\u8E2A\u5206\u652F\uFF08\u6709\u65B0\u63D0\u4EA4\uFF09",
17479
17537
  notes: Object.freeze({
17480
- "original-installer": "\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u7A0B\u5E8F\u3001\u5305\u7BA1\u7406\u5668\u6216\u542F\u52A8\u5668\u66F4\u65B0\u6B64\u5B89\u88C5\u3002",
17481
- "claude-policy-restricted": "\u6B64 Claude \u5B89\u88C5\u7684\u8BBE\u7F6E\u6216\u7B56\u7565\u9650\u5236\u4E86\u66F4\u65B0\u3002",
17482
- "codebuddy-npm-required": "\u8BF7\u4F7F\u7528 CodeBuddy \u539F\u751F\u66F4\u65B0\u5668\u6216\u539F\u5305\u7BA1\u7406\u5668\u66F4\u65B0\u3002\u6B64\u5904\u4EC5\u80FD\u67E5\u8BE2\u5DF2\u8BC6\u522B\u7684 npm \u5B89\u88C5\u7684\u6700\u65B0\u7248\u672C\u3002",
17483
- "deepseek-original-installer": "\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002Python\u3001\u684C\u9762\u5E94\u7528\u53CA\u9879\u76EE\u5185\u5B89\u88C5\u4E0D\u4F1A\u901A\u8FC7\u5168\u5C40 npm \u66F4\u65B0\u3002",
17484
- "kiro-native-updater": "\u8BF7\u4F7F\u7528 Kiro CLI \u539F\u5B89\u88C5\u7A0B\u5E8F\u6216\u539F\u751F\u66F4\u65B0\u5668\u68C0\u67E5\u5E76\u5B89\u88C5\u66F4\u65B0\u3002",
17485
- "zcode-desktop-updater": "CLI \u968F ZCode Desktop \u4E00\u8D77\u53D1\u5E03\uFF0C\u8BF7\u76F4\u63A5\u66F4\u65B0 ZCode Desktop\u3002",
17486
- "qoder-check-unavailable": "\u6B64 Qoder \u4E2D\u56FD\u7248\u5C1A\u4E0D\u652F\u6301\u53EA\u68C0\u67E5\u3001\u4E0D\u5B89\u88C5\u7684\u66F4\u65B0\u67E5\u8BE2\uFF0C\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002",
17487
- "hermes-update-plan-unavailable": "\u6B64 Hermes \u7248\u672C\u4E0D\u63D0\u4F9B\u5B89\u5168\u7684\u66F4\u65B0\u8BA1\u5212\uFF0C\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002",
17488
- "hermes-externally-managed": "\u6B64 Hermes \u5B89\u88C5\u7531\u5916\u90E8\u5DE5\u5177\u7BA1\u7406\uFF0C\u8BF7\u901A\u8FC7\u5176\u684C\u9762\u5E94\u7528\u3001\u5BB9\u5668\u6216\u539F\u5305\u7BA1\u7406\u5668\u66F4\u65B0\u3002",
17489
- "hermes-update-channel": "\u4F7F\u7528 Hermes \u914D\u7F6E\u7684\u66F4\u65B0\u6E20\u9053\uFF0C\u6682\u4E0D\u91CD\u542F Gateway\uFF1B\u73B0\u6709\u8FDB\u7A0B\u7EE7\u7EED\u8FD0\u884C\u539F\u6709\u4EE3\u7801\u3002",
17490
- "hermes-manual-update": "\u8BF7\u624B\u52A8\u4F7F\u7528\u539F\u751F\u66F4\u65B0\u5668\u3002\u5B89\u5168\u7684\u975E\u4EA4\u4E92\u66F4\u65B0\u8981\u6C42\u6E90\u7801\u76EE\u5F55\u65E0\u672A\u63D0\u4EA4\u4FEE\u6539\u3001\u53EF\u8BC6\u522B\u5F53\u524D\u63D0\u4EA4\uFF0C\u5E76\u652F\u6301\u63A8\u8FDF Gateway \u91CD\u542F\u3002"
17538
+ "original-installer": "\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u7A0B\u5E8F\u3001\u5305\u7BA1\u7406\u5668\u6216\u542F\u52A8\u5668\u66F4\u65B0\u6B64\u5B89\u88C5\u3002"
17491
17539
  })
17492
17540
  });
17493
17541
  function harnessVersionLabel(state, messages) {
@@ -17499,6 +17547,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17499
17547
  return state.latestVersion;
17500
17548
  }
17501
17549
  function harnessVersionNote(state, messages) {
17550
+ if (state?.notice) return localizeHarnessText(state.notice, messages.locale);
17502
17551
  const code = state?.messageCode;
17503
17552
  return code && Object.hasOwn(messages.notes, code) ? messages.notes[code] : void 0;
17504
17553
  }
@@ -18759,7 +18808,7 @@ ${error51.stderrTail}`] : []
18759
18808
  launchPathSaveError: "Could not save. Enter an existing absolute installation folder on this Host and check configuration permissions.",
18760
18809
  connectionOfficialWebsite: "Visit official website",
18761
18810
  connectionOpenHarnessWeb: "Open DeepSeek Harness Web",
18762
- connectionDeepSeekTestedVersions: "Supported DSH versions: 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1 and 0.2.0-rc.2. Versions newer than 0.2.0-rc.2 can be tried, but compatibility may be limited; versions older than 0.1.7-rc.1 must be upgraded first.",
18811
+ connectionDeepSeekTestedVersions: "Supported DSH versions: 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1, 0.2.0-rc.2, 0.2.1-rc.1 and 0.2.1-rc.2. Versions newer than 0.2.1-rc.2 can be tried, but compatibility may be limited; versions older than 0.1.7-rc.1 must be upgraded first.",
18763
18812
  connectionInstall: "Install",
18764
18813
  connectionInstallDescription: "This Harness was not detected.",
18765
18814
  connectionInstallRunning: "Installing on the selected Host. You can leave this page; login or setup may still be required afterward.",
@@ -19032,7 +19081,7 @@ ${error51.stderrTail}`] : []
19032
19081
  launchPathSaveError: "\u4FDD\u5B58\u5931\u8D25\u3002\u8BF7\u586B\u5199\u6B64 Host \u4E0A\u5B9E\u9645\u5B58\u5728\u7684\u5B89\u88C5\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u5E76\u786E\u8BA4\u914D\u7F6E\u76EE\u5F55\u53EF\u5199\u3002",
19033
19082
  connectionOfficialWebsite: "\u8BBF\u95EE\u5B98\u7F51",
19034
19083
  connectionOpenHarnessWeb: "\u6253\u5F00 DeepSeek Harness Web",
19035
- connectionDeepSeekTestedVersions: "\u652F\u6301 DSH \u7248\u672C\uFF1A0.1.7-rc.1\u30010.1.7-rc.2\u30010.2.0-rc.1 \u548C 0.2.0-rc.2\u3002\u9AD8\u4E8E 0.2.0-rc.2 \u7684\u7248\u672C\u53EF\u4EE5\u5C1D\u8BD5\u8FDE\u63A5\uFF0C\u4F46\u9002\u914D\u5EA6\u53EF\u80FD\u6709\u9650\uFF1B\u4F4E\u4E8E 0.1.7-rc.1 \u7684\u7248\u672C\u9700\u8981\u5148\u5347\u7EA7\u3002",
19084
+ connectionDeepSeekTestedVersions: "\u652F\u6301 DSH \u7248\u672C\uFF1A0.1.7-rc.1\u30010.1.7-rc.2\u30010.2.0-rc.1\u30010.2.0-rc.2\u30010.2.1-rc.1 \u548C 0.2.1-rc.2\u3002\u9AD8\u4E8E 0.2.1-rc.2 \u7684\u7248\u672C\u53EF\u4EE5\u5C1D\u8BD5\u8FDE\u63A5\uFF0C\u4F46\u9002\u914D\u5EA6\u53EF\u80FD\u6709\u9650\uFF1B\u4F4E\u4E8E 0.1.7-rc.1 \u7684\u7248\u672C\u9700\u8981\u5148\u5347\u7EA7\u3002",
19036
19085
  connectionInstall: "\u5B89\u88C5",
19037
19086
  connectionInstallDescription: "\u5C1A\u672A\u68C0\u6D4B\u5230\u8BE5 Harness\u3002",
19038
19087
  connectionInstallRunning: "\u6B63\u5728\u6240\u9009 Host \u4E0A\u5B89\u88C5\uFF0C\u79BB\u5F00\u9875\u9762\u4E0D\u4F1A\u4E2D\u65AD\u3002\u5B89\u88C5\u540E\u53EF\u80FD\u4ECD\u9700\u767B\u5F55\u6216\u914D\u7F6E\u3002",
@@ -19828,7 +19877,6 @@ ${error51.stderrTail}`] : []
19828
19877
  // src/renderer-usage-control.ts
19829
19878
  var ENGLISH_USAGE_MESSAGES = Object.freeze({
19830
19879
  usage: "Usage",
19831
- account: "Account",
19832
19880
  context: "Context",
19833
19881
  recordedCredits: "Recorded usage",
19834
19882
  latestCacheHit: "Latest cache hit (CH)",
@@ -19854,7 +19902,6 @@ ${error51.stderrTail}`] : []
19854
19902
  });
19855
19903
  var CHINESE_USAGE_MESSAGES = Object.freeze({
19856
19904
  usage: "\u7528\u91CF",
19857
- account: "\u8D26\u53F7",
19858
19905
  context: "\u4E0A\u4E0B\u6587",
19859
19906
  recordedCredits: "\u5DF2\u8BB0\u5F55\u6D88\u8017",
19860
19907
  latestCacheHit: "\u6700\u8FD1\u7F13\u5B58\u547D\u4E2D\uFF08CH\uFF09",
@@ -19966,10 +20013,10 @@ ${error51.stderrTail}`] : []
19966
20013
  popover.style.color = "CanvasText";
19967
20014
  popover.style.boxShadow = "light-dark(0 10px 24px rgba(15, 23, 42, 0.12), 0 20px 45px rgba(0, 0, 0, 0.42)), 0 2px 8px light-dark(rgba(15, 23, 42, 0.06), rgba(0, 0, 0, 0.28))";
19968
20015
  }
19969
- function addDetailRow(parent, label, value, wrap = false) {
20016
+ function addDetailRow(parent, label, value) {
19970
20017
  const row = document.createElement("div");
19971
20018
  row.style.display = "grid";
19972
- row.style.gridTemplateColumns = wrap ? "auto minmax(0, 1fr)" : "minmax(0, 1fr) auto";
20019
+ row.style.gridTemplateColumns = "minmax(0, 1fr) auto";
19973
20020
  row.style.gap = "20px";
19974
20021
  row.style.padding = "4px 0";
19975
20022
  const labelElement = document.createElement("span");
@@ -19979,10 +20026,6 @@ ${error51.stderrTail}`] : []
19979
20026
  valueElement.textContent = value;
19980
20027
  valueElement.style.fontVariantNumeric = "tabular-nums";
19981
20028
  valueElement.style.textAlign = "right";
19982
- if (wrap) {
19983
- valueElement.style.overflowWrap = "anywhere";
19984
- valueElement.title = value;
19985
- }
19986
20029
  row.append(labelElement, valueElement);
19987
20030
  parent.append(row);
19988
20031
  }
@@ -20033,14 +20076,13 @@ ${error51.stderrTail}`] : []
20033
20076
  if (note) addNote(parent, note);
20034
20077
  }
20035
20078
  }
20036
- function renderDetails(popover, usage, messages, locale, accountName) {
20079
+ function renderDetails(popover, usage, messages, locale) {
20037
20080
  popover.replaceChildren();
20038
20081
  const heading = document.createElement("div");
20039
20082
  heading.textContent = messages.usage;
20040
20083
  heading.style.fontWeight = "600";
20041
20084
  heading.style.marginBottom = "6px";
20042
20085
  popover.append(heading);
20043
- if (accountName) addDetailRow(popover, messages.account, accountName, true);
20044
20086
  if (usage?.contextUsagePercent !== void 0) {
20045
20087
  addContextRow(
20046
20088
  popover,
@@ -20272,7 +20314,7 @@ ${error51.stderrTail}`] : []
20272
20314
  document.body.append(popover);
20273
20315
  return control;
20274
20316
  }
20275
- function renderRendererUsageControl(control, usage, locale = control.locale, accountName = null) {
20317
+ function renderRendererUsageControl(control, usage, locale = control.locale) {
20276
20318
  control.locale = locale;
20277
20319
  const messages = rendererUsageMessages(locale);
20278
20320
  control.popover.setAttribute("aria-label", messages.threadUsageDetails);
@@ -20281,7 +20323,7 @@ ${error51.stderrTail}`] : []
20281
20323
  const totalCostUsd = usage?.totalCostUsd;
20282
20324
  const hasContext = usage?.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0;
20283
20325
  const hasTokenUsage = usage?.totalTokens !== void 0 || usage?.inputTokens !== void 0 || usage?.cachedInputTokens !== void 0 || usage?.cacheWriteInputTokens !== void 0 || usage?.outputTokens !== void 0;
20284
- const visible = rendererUsageHasDisplayData(usage) || Boolean(accountName);
20326
+ const visible = rendererUsageHasDisplayData(usage);
20285
20327
  control.root.style.display = visible ? "inline-flex" : "none";
20286
20328
  if (!visible) {
20287
20329
  closePopover(control);
@@ -20315,7 +20357,7 @@ ${error51.stderrTail}`] : []
20315
20357
  control.trigger.setAttribute("aria-label", accessibleSummary);
20316
20358
  control.trigger.title = accessibleSummary;
20317
20359
  control.label.textContent = compactSummary;
20318
- renderDetails(control.popover, usage, messages, locale, accountName);
20360
+ renderDetails(control.popover, usage, messages, locale);
20319
20361
  return true;
20320
20362
  }
20321
20363
 
@@ -20584,7 +20626,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
20584
20626
  loadingPermissions: "Loading permissions...",
20585
20627
  selecting: "Selecting...",
20586
20628
  permissionsUnavailable: "Permissions unavailable",
20587
- permissionModeFixedAtCreate: "Grok fixes its Permission Mode when the Session is created. Start a new Thread to change it.",
20629
+ permissionModeFixedAtCreate: "This Permission Mode is fixed when the Session is created. Start a new Thread to change it.",
20588
20630
  codexUsageGateUnavailable: "Could not separate this Harness from the Codex usage limit in this Desktop version. Codex usage limits still apply to sending.",
20589
20631
  modelSelectionRejected: "Couldn't switch Model",
20590
20632
  thinkingSelectionRejected: "Couldn't switch Thinking option"
@@ -20601,127 +20643,20 @@ Codex Fast mode prioritizes requests and may increase usage.`
20601
20643
  loadingPermissions: "\u6B63\u5728\u52A0\u8F7D\u6743\u9650...",
20602
20644
  selecting: "\u6B63\u5728\u9009\u62E9...",
20603
20645
  permissionsUnavailable: "\u6743\u9650\u4E0D\u53EF\u7528",
20604
- permissionModeFixedAtCreate: "Grok \u7684\u6743\u9650\u6A21\u5F0F\u5728\u4F1A\u8BDD\u521B\u5EFA\u65F6\u786E\u5B9A\uFF0C\u5982\u9700\u66F4\u6539\u8BF7\u65B0\u5EFA\u4F1A\u8BDD",
20646
+ permissionModeFixedAtCreate: "\u6B64\u6743\u9650\u6A21\u5F0F\u5728\u4F1A\u8BDD\u521B\u5EFA\u65F6\u786E\u5B9A\uFF0C\u5982\u9700\u66F4\u6539\u8BF7\u65B0\u5EFA\u4F1A\u8BDD",
20605
20647
  codexUsageGateUnavailable: "\u5F53\u524D Desktop \u7248\u672C\u65E0\u6CD5\u5C06\u6B64 Harness \u4E0E Codex \u989D\u5EA6\u9650\u5236\u5206\u79BB\uFF0C\u53D1\u9001\u4ECD\u53D7 Codex \u989D\u5EA6\u9650\u5236",
20606
20648
  modelSelectionRejected: "\u65E0\u6CD5\u5207\u6362\u6A21\u578B",
20607
20649
  thinkingSelectionRejected: "\u65E0\u6CD5\u5207\u6362\u601D\u8003\u9009\u9879"
20608
20650
  });
20609
- var ENGLISH_PERMISSION_MODE_LABELS = /* @__PURE__ */ new Map([
20610
- ["read-only", "Read only"],
20611
- ["workspace-write", "Workspace write"],
20612
- ["danger-full-access", "Full access (dangerous)"]
20613
- ]);
20614
- var CHINESE_PERMISSION_MODE_LABELS = /* @__PURE__ */ new Map([
20615
- ["Always ask", "\u59CB\u7EC8\u8BE2\u95EE"],
20616
- ["Write", "\u5199\u5165"],
20617
- ["Full access", "\u5B8C\u5168\u8BBF\u95EE"],
20618
- ["Plan mode", "\u89C4\u5212\u6A21\u5F0F"],
20619
- ["Default", "\u9ED8\u8BA4"],
20620
- ["Accept edits", "\u63A5\u53D7\u7F16\u8F91"],
20621
- ["Auto mode", "\u81EA\u52A8\u6A21\u5F0F"],
20622
- ["Bypass permissions", "\u7ED5\u8FC7\u6743\u9650"],
20623
- ["Ask", "\u8BE2\u95EE"],
20624
- ["Auto", "\u81EA\u52A8"],
20625
- ["Always approve", "\u59CB\u7EC8\u6279\u51C6"],
20626
- ["Allow all", "\u5168\u90E8\u5141\u8BB8"],
20627
- ["Read only", "\u53EA\u8BFB"],
20628
- ["Workspace write", "\u5DE5\u4F5C\u533A\u5199\u5165"],
20629
- ["Full access (dangerous)", "\u5B8C\u5168\u8BBF\u95EE\uFF08\u5371\u9669\uFF09"],
20630
- ["Configured permissions", "\u4F7F\u7528\u5DF2\u914D\u7F6E\u6743\u9650"],
20631
- ["Skip permissions", "\u8DF3\u8FC7\u6743\u9650\u68C0\u67E5"],
20632
- ["Always Ask", "\u59CB\u7EC8\u8BE2\u95EE"],
20633
- ["Accept Edits", "\u63A5\u53D7\u7F16\u8F91"],
20634
- ["Plan", "\u89C4\u5212\u6A21\u5F0F"],
20635
- ["Don't Ask", "\u4E0D\u8BE2\u95EE"],
20636
- ["Bypass Permissions", "\u7ED5\u8FC7\u6743\u9650"],
20637
- ["Full Access", "\u5B8C\u5168\u8BBF\u95EE"],
20638
- ["Delegate", "\u7531\u7236\u4F1A\u8BDD\u7BA1\u7406"]
20639
- ]);
20640
- var CHINESE_PERMISSION_MODE_DESCRIPTIONS = /* @__PURE__ */ new Map([
20641
- [
20642
- "Automatically allow reads and ask before write or execution actions.",
20643
- "\u81EA\u52A8\u5141\u8BB8\u8BFB\u53D6\uFF1B\u5199\u5165\u6216\u6267\u884C\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"
20644
- ],
20645
- [
20646
- "Automatically allow reads and writes; ask before execution actions.",
20647
- "\u81EA\u52A8\u5141\u8BB8\u8BFB\u53D6\u548C\u5199\u5165\uFF1B\u6267\u884C\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"
20648
- ],
20649
- ["Run all tool actions without approval prompts.", "\u65E0\u9700\u6279\u51C6\u63D0\u793A\u5373\u53EF\u8FD0\u884C\u6240\u6709\u5DE5\u5177\u64CD\u4F5C\u3002"],
20650
- [
20651
- "Explore and prepare a plan; approval exits planning and resumes the previous permission mode.",
20652
- "\u63A2\u7D22\u5E76\u5236\u5B9A\u8BA1\u5212\uFF1B\u6279\u51C6\u8BA1\u5212\u540E\u9000\u51FA\u89C4\u5212\uFF0C\u6062\u590D\u6B64\u524D\u7684\u6743\u9650\u6A21\u5F0F\u3002"
20653
- ],
20654
- ["Ask before edits and other protected actions.", "\u7F16\u8F91\u548C\u5176\u4ED6\u53D7\u4FDD\u62A4\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
20655
- ["Allow file edits and ask for other protected actions.", "\u5141\u8BB8\u6587\u4EF6\u7F16\u8F91\uFF1B\u5176\u4ED6\u53D7\u4FDD\u62A4\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
20656
- ["Let Claude classify permission requests.", "\u7531 Claude \u5224\u65AD\u6743\u9650\u8BF7\u6C42\u3002"],
20657
- ["Skip Claude Code permission checks.", "\u8DF3\u8FC7 Claude Code \u6743\u9650\u68C0\u67E5\u3002"],
20658
- [
20659
- "Use Grok Build's default interactive approval policy.",
20660
- "\u4F7F\u7528 Grok Build \u7684\u9ED8\u8BA4\u4EA4\u4E92\u5F0F\u6279\u51C6\u7B56\u7565\u3002"
20661
- ],
20662
- ["Ask before protected tool actions.", "\u6267\u884C\u53D7\u4FDD\u62A4\u7684\u5DE5\u5177\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
20663
- [
20664
- "Let Grok Build decide which tool actions may run automatically.",
20665
- "\u7531 Grok Build \u51B3\u5B9A\u54EA\u4E9B\u5DE5\u5177\u64CD\u4F5C\u53EF\u81EA\u52A8\u8FD0\u884C\u3002"
20666
- ],
20667
- ["Approve all tool actions without prompting.", "\u65E0\u9700\u63D0\u793A\u5373\u53EF\u6279\u51C6\u6240\u6709\u5DE5\u5177\u64CD\u4F5C\u3002"],
20668
- ["Use OpenCode's configured permission rules.", "\u4F7F\u7528 OpenCode \u5DF2\u914D\u7F6E\u7684\u6743\u9650\u89C4\u5219\u3002"],
20669
- ["Ask before protected OpenCode actions.", "\u6267\u884C\u53D7\u4FDD\u62A4\u7684 OpenCode \u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
20670
- ["Allow OpenCode actions without approval prompts.", "\u5141\u8BB8 OpenCode \u64CD\u4F5C\uFF0C\u65E0\u9700\u6279\u51C6\u63D0\u793A\u3002"],
20671
- [
20672
- "Use Antigravity CLI permission rules; headless prompts are denied safely.",
20673
- "\u4F7F\u7528 Antigravity CLI \u6743\u9650\u89C4\u5219\uFF1B\u65E0\u754C\u9762\u8FD0\u884C\u65F6\u5B89\u5168\u62D2\u7EDD\u9700\u8981\u4EA4\u4E92\u786E\u8BA4\u7684\u8BF7\u6C42\u3002"
20674
- ],
20675
- ["Auto-approve every Antigravity CLI tool action.", "\u81EA\u52A8\u6279\u51C6\u6240\u6709 Antigravity CLI \u5DE5\u5177\u64CD\u4F5C\u3002"],
20676
- ["Prompts for permission on first use of each tool", "\u9996\u6B21\u4F7F\u7528\u6BCF\u79CD\u5DE5\u5177\u65F6\u8BF7\u6C42\u6743\u9650\u3002"],
20677
- [
20678
- "Automatically accepts file edit permissions for the session",
20679
- "\u81EA\u52A8\u63A5\u53D7\u672C\u4F1A\u8BDD\u4E2D\u7684\u6587\u4EF6\u7F16\u8F91\u6743\u9650\u3002"
20680
- ],
20681
- [
20682
- "Agent can analyze but not modify files or execute commands",
20683
- "Agent \u53EF\u4EE5\u5206\u6790\uFF0C\u4F46\u4E0D\u80FD\u4FEE\u6539\u6587\u4EF6\u6216\u6267\u884C\u547D\u4EE4\u3002"
20684
- ],
20685
- [
20686
- "An AI classifier reviews actions that would normally prompt: safe ones are auto-approved, risky ones are denied. If the classifier is unavailable, the action falls back to a prompt (or is denied when prompts cannot be shown)",
20687
- "\u7531 AI \u5206\u7C7B\u5668\u8BC4\u4F30\u539F\u672C\u9700\u8981\u8BE2\u95EE\u7684\u64CD\u4F5C\uFF1A\u5B89\u5168\u64CD\u4F5C\u81EA\u52A8\u6279\u51C6\uFF0C\u98CE\u9669\u64CD\u4F5C\u62D2\u7EDD\u3002\u5206\u7C7B\u5668\u4E0D\u53EF\u7528\u65F6\u6539\u4E3A\u8BE2\u95EE\uFF1B\u65E0\u6CD5\u663E\u793A\u8BE2\u95EE\u65F6\u62D2\u7EDD\u3002"
20688
- ],
20689
- [
20690
- "Does not show permission prompts; pre-approved and safe read-only actions run, everything else that would prompt is denied",
20691
- "\u4E0D\u663E\u793A\u6743\u9650\u8BE2\u95EE\uFF1B\u5DF2\u83B7\u6279\u51C6\u548C\u5B89\u5168\u7684\u53EA\u8BFB\u64CD\u4F5C\u53EF\u4EE5\u6267\u884C\uFF0C\u5176\u4F59\u539F\u672C\u9700\u8981\u8BE2\u95EE\u7684\u64CD\u4F5C\u4F1A\u88AB\u62D2\u7EDD\u3002"
20692
- ],
20693
- ["Skips all permission prompts", "\u8DF3\u8FC7\u5E38\u89C4\u6743\u9650\u8BE2\u95EE\u3002"],
20694
- [
20695
- "Skips ALL permission checks including dangerous commands for all agents",
20696
- "\u4E3A\u6240\u6709 Agent \u8DF3\u8FC7\u5168\u90E8\u6743\u9650\u68C0\u67E5\uFF0C\u5305\u62EC\u5371\u9669\u547D\u4EE4\u3002"
20697
- ],
20698
- ["Permissions managed by parent session", "\u7531\u7236\u4F1A\u8BDD\u7BA1\u7406\u6743\u9650\u3002"],
20699
- [
20700
- "Native agent mode with Cursor tool approvals",
20701
- "\u6267\u884C\u4EFB\u52A1\uFF0C\u53EF\u4FEE\u6539\u6587\u4EF6\u548C\u8FD0\u884C\u547D\u4EE4\uFF1B\u9700\u8981\u5BA1\u6279\u7684\u64CD\u4F5C\u4ECD\u4F1A\u8BF7\u6C42\u786E\u8BA4\u3002"
20702
- ],
20703
- ["Native read-only planning mode", "\u53EA\u8BFB\u5206\u6790\u4EE3\u7801\u5E76\u5236\u5B9A\u5B9E\u65BD\u8BA1\u5212\uFF0C\u4E0D\u4FEE\u6539\u9879\u76EE\u6587\u4EF6\u3002"],
20704
- ["Native read-only question mode", "\u53EA\u8BFB\u67E5\u770B\u4EE3\u7801\u5E76\u56DE\u7B54\u95EE\u9898\uFF0C\u4E0D\u4FEE\u6539\u9879\u76EE\u6587\u4EF6\u3002"]
20705
- ]);
20706
20651
  function rendererHarnessMessages(locale) {
20707
20652
  return locale === "zh-CN" ? CHINESE_HARNESS_MESSAGES : ENGLISH_HARNESS_MESSAGES;
20708
20653
  }
20709
20654
  function rendererHarnessCommandPresentation(command, locale) {
20710
- if (locale === "zh-CN" && command.invocation === "/compact") {
20711
- return { label: "\u538B\u7F29\u4E0A\u4E0B\u6587", description: "\u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\u4E0A\u4E0B\u6587" };
20712
- }
20713
- return {
20714
- label: command.label,
20715
- description: command.description ?? command.label
20716
- };
20655
+ const presentation = localizeHarnessPresentation(command, locale);
20656
+ return { ...presentation, description: presentation.description ?? presentation.label };
20717
20657
  }
20718
20658
  function rendererPermissionModePresentation(mode, locale) {
20719
- const label = ENGLISH_PERMISSION_MODE_LABELS.get(mode.label) ?? mode.label;
20720
- if (locale !== "zh-CN") return { label, description: mode.description };
20721
- return {
20722
- label: CHINESE_PERMISSION_MODE_LABELS.get(label) ?? label,
20723
- description: mode.description === void 0 ? void 0 : CHINESE_PERMISSION_MODE_DESCRIPTIONS.get(mode.description) ?? mode.description
20724
- };
20659
+ return localizeHarnessPresentation(mode, locale);
20725
20660
  }
20726
20661
  function rendererLiveCommandsPendingNotice(locale, harnessLabel) {
20727
20662
  const harness2 = harnessLabel.replace(/\s*[((][^))]*[))]\s*$/u, "").trim() || harnessLabel;
@@ -22003,30 +21938,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
22003
21938
  return messages.account;
22004
21939
  }
22005
21940
  function productLabel(product, locale = "en") {
22006
- if (product === "GrokBuild") return "Build";
22007
- if (product === "GrokChat") return "Chat";
22008
- if (product === "GrokImagine") return "Imagine";
22009
- if (product === "GrokVoice") return "Voice";
22010
- const messages = rendererCreditsMessages(locale);
22011
- if (product === "5-hour window") return messages.fiveHour;
22012
- if (product === "7-day window") return messages.sevenDay;
22013
- if (product === "Weekly window") return messages.weekly;
22014
- if (product.endsWith(" \xB7 5-hour window")) {
22015
- return `${product.slice(0, -"5-hour window".length)}${messages.fiveHour}`;
22016
- }
22017
- if (product.endsWith(" \xB7 7-day window")) {
22018
- return `${product.slice(0, -"7-day window".length)}${messages.sevenDay}`;
22019
- }
22020
- if (product.endsWith(" \xB7 Weekly window")) {
22021
- return `${product.slice(0, -"Weekly window".length)}${messages.weekly}`;
22022
- }
22023
- if (product.endsWith(" \xB7 5-hour")) {
22024
- return `${product.slice(0, -"5-hour".length)}${messages.fiveHour}`;
22025
- }
22026
- if (product.endsWith(" \xB7 7-day")) {
22027
- return `${product.slice(0, -"7-day".length)}${messages.sevenDay}`;
22028
- }
22029
- return product;
21941
+ return accountCreditsWindowLabel(product, locale, (period) => creditsPeriodLabel(period, locale));
22030
21942
  }
22031
21943
  function toneColor(tone) {
22032
21944
  if (tone === "hot") return "#c45c4a";
@@ -22067,7 +21979,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
22067
21979
  top.style.marginBottom = "5px";
22068
21980
  const left = document.createElement("div");
22069
21981
  const label = document.createElement("div");
22070
- label.textContent = credits.label ? productLabel(credits.label, locale) : creditsPeriodLabel(credits.periodType, locale);
21982
+ label.textContent = productLabel(credits, locale);
22071
21983
  label.style.fontSize = "12.5px";
22072
21984
  label.style.fontWeight = "600";
22073
21985
  left.append(label);
@@ -22142,7 +22054,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
22142
22054
  popover.append(renderCreditsHeader(credits, locale, messages));
22143
22055
  const tiles = (credits.productUsage ?? []).map(
22144
22056
  (product) => renderCreditsTile(
22145
- productLabel(product.product, locale),
22057
+ productLabel(product, locale),
22146
22058
  product.usagePercent,
22147
22059
  locale,
22148
22060
  messages,
@@ -22310,7 +22222,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
22310
22222
  }
22311
22223
  const remaining = remainingPercent(accountCredits.usedPercent);
22312
22224
  const percent2 = formatRendererCreditsPercent(remaining);
22313
- const periodLabel = accountCredits.label ? productLabel(accountCredits.label, locale) : creditsPeriodLabel(accountCredits.periodType, locale);
22225
+ const periodLabel = accountCredits.label ? productLabel(accountCredits, locale) : creditsPeriodLabel(accountCredits.periodType, locale);
22314
22226
  const title = `${periodLabel} ${percent2}`;
22315
22227
  const tone = rendererCreditsTone(accountCredits.usedPercent);
22316
22228
  const ringSlot = control.trigger.querySelector("[data-codexhost-credits-ring]");
@@ -22899,14 +22811,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
22899
22811
  permissionModeVisible,
22900
22812
  locale
22901
22813
  );
22902
- const selectedCodexAccount = state.agent === "codex" && !ownershipError ? currentCodexAccount : void 0;
22903
22814
  if (control.usage) {
22904
- renderRendererUsageControl(
22905
- control.usage,
22906
- usage,
22907
- locale,
22908
- selectedCodexAccount?.email ?? selectedCodexAccount?.label ?? null
22909
- );
22815
+ renderRendererUsageControl(control.usage, usage, locale);
22910
22816
  }
22911
22817
  control.harnessCommands.setLocale(locale);
22912
22818
  control.harnessCommands.root.hidden = state.agent === "codex";
@@ -23046,62 +22952,141 @@ Codex Fast mode prioritizes requests and may increase usage.`
23046
22952
  }
23047
22953
  };
23048
22954
 
22955
+ // src/renderer-codex-usage-banner.ts
22956
+ var MAX_FIBERS = 2e4;
22957
+ function isRecord2(value) {
22958
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22959
+ }
22960
+ function isUsageBanner(props) {
22961
+ return isRecord2(props) && "banner" in props && "rateLimitStatus" in props && typeof props.sendBlocked === "boolean";
22962
+ }
22963
+ function isElement(value) {
22964
+ return isRecord2(value) && typeof value.setAttribute === "function" && isRecord2(value.style);
22965
+ }
22966
+ function hostElements(fiber, budget) {
22967
+ const result = [];
22968
+ const visit = (node) => {
22969
+ for (let current = node; isRecord2(current); current = current.sibling) {
22970
+ if (budget.remaining-- <= 0) return;
22971
+ const { stateNode } = current;
22972
+ if (isElement(stateNode)) result.push(stateNode);
22973
+ else visit(current.child);
22974
+ }
22975
+ };
22976
+ visit(fiber.child);
22977
+ return result;
22978
+ }
22979
+ function findCodexUsageBannerElements(owner) {
22980
+ if (!isRecord2(owner)) return [];
22981
+ const budget = { remaining: MAX_FIBERS };
22982
+ const found = [];
22983
+ const stack = [owner.child];
22984
+ while (stack.length > 0 && budget.remaining > 0) {
22985
+ const node = stack.pop();
22986
+ if (!isRecord2(node)) continue;
22987
+ budget.remaining -= 1;
22988
+ const fiber = node;
22989
+ stack.push(fiber.sibling);
22990
+ if (isUsageBanner(fiber.memoizedProps)) found.push(...hostElements(fiber, budget));
22991
+ else stack.push(fiber.child);
22992
+ }
22993
+ return budget.remaining > 0 ? found : [];
22994
+ }
22995
+ var HIDDEN_ATTRIBUTE = "data-codexhost-usage-banner-hidden";
22996
+ function createRendererCodexUsageBanner() {
22997
+ const hidden = /* @__PURE__ */ new Map();
22998
+ const show = (element) => {
22999
+ const previous = hidden.get(element);
23000
+ hidden.delete(element);
23001
+ if (!previous || element.getAttribute(HIDDEN_ATTRIBUTE) === null) return;
23002
+ element.removeAttribute(HIDDEN_ATTRIBUTE);
23003
+ if (previous.value) element.style.setProperty("display", previous.value, previous.priority);
23004
+ else element.style.removeProperty("display");
23005
+ };
23006
+ return {
23007
+ hide(owner) {
23008
+ const current = new Set(findCodexUsageBannerElements(owner));
23009
+ for (const element of [...hidden.keys()]) if (!current.has(element)) show(element);
23010
+ for (const element of current) {
23011
+ if (hidden.has(element)) continue;
23012
+ hidden.set(element, {
23013
+ value: element.style.getPropertyValue("display"),
23014
+ priority: element.style.getPropertyPriority("display")
23015
+ });
23016
+ element.setAttribute(HIDDEN_ATTRIBUTE, "");
23017
+ element.style.setProperty("display", "none", "important");
23018
+ }
23019
+ },
23020
+ restore() {
23021
+ for (const element of [...hidden.keys()]) show(element);
23022
+ }
23023
+ };
23024
+ }
23025
+
23049
23026
  // src/renderer-codex-usage-gate.ts
23050
23027
  var EDITOR_SELECTOR2 = '[contenteditable="true"][role="textbox"]';
23051
23028
  var MAX_HOOKS = 4096;
23052
23029
  var MAX_DOM_DEPTH = 12;
23053
23030
  var RETRY_DELAY_MS = 1e3;
23054
- function isRecord2(value) {
23031
+ function isRecord3(value) {
23055
23032
  return typeof value === "object" && value !== null && !Array.isArray(value);
23056
23033
  }
23057
23034
  function hooksOf(fiber) {
23058
23035
  const result = [];
23059
- let hook = isRecord2(fiber) ? fiber.memoizedState : null;
23060
- while (isRecord2(hook) && result.length < MAX_HOOKS) {
23036
+ let hook = isRecord3(fiber) ? fiber.memoizedState : null;
23037
+ while (isRecord3(hook) && result.length < MAX_HOOKS) {
23061
23038
  result.push(hook);
23062
23039
  hook = hook.next;
23063
23040
  }
23064
23041
  return hook == null ? result : [];
23065
23042
  }
23066
- function submitOwners(composer) {
23043
+ function submitOwners(composer, projections) {
23067
23044
  let element = composer.querySelector(EDITOR_SELECTOR2) ?? composer;
23068
23045
  for (let depth = 0; element && depth < MAX_DOM_DEPTH; depth += 1) {
23069
23046
  const key = Object.getOwnPropertyNames(element).find(
23070
23047
  (name) => name.startsWith("__reactFiber$")
23071
23048
  );
23072
23049
  if (key) {
23073
- const owners = committedReactAncestors(
23050
+ const ancestors = committedReactAncestors(
23074
23051
  Object.getOwnPropertyDescriptor(element, key)?.value
23075
- ).filter(
23076
- ({ memoizedProps: props }) => isRecord2(props) && "onLocalSubmitStart" in props && typeof props.submitDisabled === "boolean"
23077
23052
  );
23078
- return owners.filter((owner) => {
23079
- const gates = gateSubscriptions(owner);
23053
+ const scopes = [];
23054
+ ancestors.forEach(({ memoizedProps: props }, index) => {
23055
+ if (isRecord3(props) && "onLocalSubmitStart" in props && typeof props.submitDisabled === "boolean") {
23056
+ scopes.push({ owner: ancestors[index], fibers: ancestors.slice(0, index + 1) });
23057
+ }
23058
+ });
23059
+ const valid = scopes.filter((scope) => {
23060
+ const gates = gateSubscriptions(scope, projections);
23080
23061
  return !gates.invalid && gates.reserve.length > 0;
23081
23062
  });
23063
+ return valid.filter(
23064
+ (scope) => !valid.some((other) => other !== scope && scope.fibers.includes(other.owner))
23065
+ );
23082
23066
  }
23083
23067
  element = element.parentElement;
23084
23068
  }
23085
23069
  return [];
23086
23070
  }
23087
- function findSubmitOwner(composer) {
23088
- const owners = submitOwners(composer);
23089
- return owners.length === 1 ? owners[0] ?? null : null;
23071
+ function findSubmitScope(composer, projections) {
23072
+ const scopes = submitOwners(composer, projections);
23073
+ return scopes.length === 1 ? scopes[0] ?? null : null;
23090
23074
  }
23091
- function subscriptionAt(hook) {
23075
+ function subscriptionAt(hook, fiber) {
23092
23076
  const memo = hook.memoizedState;
23093
23077
  if (!Array.isArray(memo) || !Array.isArray(memo[1])) return null;
23094
23078
  const [subscriber, dependencies] = memo;
23095
23079
  if (dependencies.length !== 2) return null;
23096
23080
  const signal = dependencies[0];
23097
- const adapted = dependencies[1] === void 0 && isRecord2(signal) && typeof signal.get === "function" && typeof signal.subscribe === "function";
23081
+ const adapted = dependencies[1] === void 0 && isRecord3(signal) && typeof signal.get === "function" && typeof signal.subscribe === "function";
23098
23082
  const [store, atom] = adapted ? [signal.store, signal.atom] : dependencies;
23099
23083
  const instance = hook.next?.queue;
23100
23084
  const effect = hook.next?.next?.memoizedState;
23101
- if (!isRecord2(subscriber) || typeof subscriber.getSnapshot !== "function" || typeof subscriber.subscribe !== "function" || !isRecord2(store) || typeof store.get !== "function" || typeof store.sub !== "function" || !isRecord2(atom) || typeof atom.read !== "function" || "write" in atom || !isRecord2(instance) || typeof instance.value !== "boolean" || typeof instance.getSnapshot !== "function" || !isRecord2(effect) || typeof effect.create !== "function" || !Array.isArray(effect.deps) || effect.deps[0] !== subscriber.subscribe) {
23085
+ if (!isRecord3(subscriber) || typeof subscriber.getSnapshot !== "function" || typeof subscriber.subscribe !== "function" || !isRecord3(store) || typeof store.get !== "function" || typeof store.sub !== "function" || !isRecord3(atom) || typeof atom.read !== "function" || "write" in atom || !isRecord3(instance) || typeof instance.value !== "boolean" || typeof instance.getSnapshot !== "function" || !isRecord3(effect) || typeof effect.create !== "function" || !Array.isArray(effect.deps) || effect.deps[0] !== subscriber.subscribe) {
23102
23086
  return null;
23103
23087
  }
23104
23088
  return {
23089
+ fiber,
23105
23090
  subscriber,
23106
23091
  store,
23107
23092
  atom,
@@ -23139,10 +23124,10 @@ Codex Fast mode prioritizes requests and may increase usage.`
23139
23124
  visiting.delete(dependency);
23140
23125
  }
23141
23126
  }
23142
- if (!isRecord2(value)) return value;
23127
+ if (!isRecord3(value)) return value;
23143
23128
  if (typeof value.hardBlocked === "boolean") return trace(value, "reserve");
23144
23129
  if ("authMethod" in value) return trace(value, "auth");
23145
- if (isRecord2(value.data) && isRecord2(value.data.rate_limit)) {
23130
+ if (isRecord3(value.data) && isRecord3(value.data.rate_limit)) {
23146
23131
  return {
23147
23132
  ...value,
23148
23133
  data: { ...value.data, rate_limit: trace(value.data.rate_limit, "limit") }
@@ -23158,12 +23143,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
23158
23143
  }
23159
23144
  const reserve = read.has("reserve.hardBlocked") && !read.has("reserve.active");
23160
23145
  const account = read.has("auth.authMethod") && read.has("limit.allowed");
23161
- if (account && (read.has("reserve.hardBlocked") || read.has("reserve.active"))) return "mixed";
23146
+ if (account && read.has("reserve.hardBlocked")) return "mixed";
23162
23147
  if (reserve) return "reserve";
23163
23148
  if (account) return "account";
23164
23149
  return null;
23165
23150
  }
23166
- function snapshotsMatch({ subscriber, instance, store, atom }, projected) {
23151
+ function snapshotsMatch({ subscriber, instance, store, atom }, projections) {
23152
+ const projected = projections?.get(instance);
23167
23153
  try {
23168
23154
  if (typeof subscriber.createRender === "function" && subscriber.createRender() != null) {
23169
23155
  return false;
@@ -23176,35 +23162,40 @@ Codex Fast mode prioritizes requests and may increase usage.`
23176
23162
  return false;
23177
23163
  }
23178
23164
  }
23179
- function gateSubscriptions(owner, projections) {
23165
+ function gateSubscriptions(scope, projections) {
23180
23166
  const found = {
23181
23167
  account: [],
23182
23168
  reserve: [],
23183
23169
  invalid: false
23184
23170
  };
23185
- for (const hook of hooksOf(owner)) {
23186
- const subscription = subscriptionAt(hook);
23187
- const kind = subscription && gateKind(subscription);
23188
- if (subscription && kind) {
23189
- if (kind !== "mixed" && snapshotsMatch(subscription, projections?.get(kind))) {
23190
- found[kind].push(subscription);
23191
- } else found.invalid = true;
23171
+ for (const fiber of scope.fibers) {
23172
+ for (const hook of hooksOf(fiber)) {
23173
+ const subscription = subscriptionAt(hook, fiber);
23174
+ const kind = subscription && gateKind(subscription);
23175
+ if (subscription && kind) {
23176
+ if (kind !== "mixed" && snapshotsMatch(subscription, projections)) {
23177
+ found[kind].push(subscription);
23178
+ } else found.invalid = true;
23179
+ }
23192
23180
  }
23193
23181
  }
23194
23182
  return found;
23195
23183
  }
23196
- function discoverGates(owner, projections) {
23197
- const gates = gateSubscriptions(owner, projections);
23184
+ function discoverGates(scope, projections) {
23185
+ const gates = gateSubscriptions(scope, projections);
23198
23186
  if (gates.invalid) return null;
23199
- const found = /* @__PURE__ */ new Map();
23187
+ const found = [];
23200
23188
  for (const kind of ["account", "reserve"]) {
23201
- const subscriptions = gates[kind];
23202
- if (subscriptions.length > 1) return null;
23203
- if (subscriptions[0]) found.set(kind, subscriptions[0]);
23189
+ const fibers = /* @__PURE__ */ new Set();
23190
+ for (const subscription of gates[kind]) {
23191
+ if (fibers.has(subscription.fiber)) return null;
23192
+ fibers.add(subscription.fiber);
23193
+ found.push([kind, subscription]);
23194
+ }
23204
23195
  }
23205
23196
  return found;
23206
23197
  }
23207
- function project2({ subscriber, store, atom, instance, subscribeEffect }) {
23198
+ function project2(kind, { fiber, subscriber, store, atom, instance, subscribeEffect }) {
23208
23199
  for (const [target, key] of [
23209
23200
  [store, "sub"],
23210
23201
  [subscriber, "getSnapshot"],
@@ -23235,6 +23226,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
23235
23226
  instance.getSnapshot = allowed;
23236
23227
  if (instance.value !== false) onChange();
23237
23228
  return {
23229
+ kind,
23230
+ fiber,
23238
23231
  subscriber,
23239
23232
  instance,
23240
23233
  restore() {
@@ -23244,13 +23237,11 @@ Codex Fast mode prioritizes requests and may increase usage.`
23244
23237
  }
23245
23238
  };
23246
23239
  }
23247
- function isBound(owner, projections) {
23248
- const alternate = isRecord2(owner.alternate) ? owner.alternate : null;
23249
- const bound = [...projections];
23250
- return [owner, alternate].some((fiber) => {
23251
- const hooks = hooksOf(fiber);
23252
- return bound.every(
23253
- ({ subscriber, instance }) => hooks.some(
23240
+ function isBound(projections) {
23241
+ return [...projections].every(({ fiber, subscriber, instance }) => {
23242
+ const alternate = isRecord3(fiber.alternate) ? fiber.alternate : null;
23243
+ return [fiber, alternate].some(
23244
+ (candidate) => hooksOf(candidate).some(
23254
23245
  (hook) => Array.isArray(hook.memoizedState) && hook.memoizedState[0] === subscriber && hook.next?.queue === instance
23255
23246
  )
23256
23247
  );
@@ -23261,7 +23252,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
23261
23252
  const projections = /* @__PURE__ */ new Map();
23262
23253
  let retryAt = 0;
23263
23254
  let allowed = false;
23255
+ const banner = createRendererCodexUsageBanner();
23264
23256
  const release = () => {
23257
+ banner.restore();
23265
23258
  const previous = [...projections.values()];
23266
23259
  owner = null;
23267
23260
  projections.clear();
@@ -23273,26 +23266,33 @@ Codex Fast mode prioritizes requests and may increase usage.`
23273
23266
  }
23274
23267
  };
23275
23268
  const bind = () => {
23276
- const current = owner ?? findSubmitOwner(composer);
23269
+ const current = findSubmitScope(composer, projections);
23277
23270
  const gates = current && discoverGates(current, projections);
23278
- if (!current || !gates?.has("reserve")) throw new Error("Codex usage gate is unavailable");
23271
+ if (!current || !gates?.some(([kind]) => kind === "reserve")) {
23272
+ throw new Error("Codex usage gate is unavailable");
23273
+ }
23279
23274
  owner = current;
23280
23275
  for (const [kind, gate] of gates) {
23281
- if (!projections.has(kind)) projections.set(kind, project2(gate));
23276
+ if (!projections.has(gate.instance)) projections.set(gate.instance, project2(kind, gate));
23282
23277
  }
23283
23278
  return "bypassed";
23284
23279
  };
23285
23280
  const apply = () => {
23281
+ const status = applyGate();
23282
+ if (status === "bypassed" && owner) banner.hide(owner.owner);
23283
+ else banner.restore();
23284
+ return status;
23285
+ };
23286
+ const applyGate = () => {
23286
23287
  if (!allowed || !composer.isConnected) {
23287
23288
  release();
23288
23289
  retryAt = 0;
23289
23290
  return "native";
23290
23291
  }
23291
- if (owner && !isBound(owner, projections.values())) {
23292
+ if (owner && !isBound(projections.values())) {
23292
23293
  release();
23293
23294
  retryAt = 0;
23294
23295
  }
23295
- if (owner && projections.size === 2) return "bypassed";
23296
23296
  if (Date.now() < retryAt) return owner ? "bypassed" : "unsupported";
23297
23297
  retryAt = Date.now() + RETRY_DELAY_MS;
23298
23298
  try {
@@ -23417,13 +23417,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
23417
23417
  }
23418
23418
 
23419
23419
  // src/renderer-native-thread.ts
23420
- function isRecord3(value) {
23420
+ function isRecord4(value) {
23421
23421
  return typeof value === "object" && value !== null && !Array.isArray(value);
23422
23422
  }
23423
23423
  async function verifyNativeCodexThread(sendRequest, threadId) {
23424
23424
  const native = await sendRequest("thread/read", { threadId, includeTurns: false });
23425
- const thread = isRecord3(native) ? native.thread : null;
23426
- if (!isRecord3(thread) || thread.id !== threadId || typeof thread.modelProvider !== "string" || !thread.modelProvider || thread.modelProvider === "codexhost" || typeof thread.cliVersion !== "string" || !thread.cliVersion || thread.cliVersion === "codexhost") {
23425
+ const thread = isRecord4(native) ? native.thread : null;
23426
+ if (!isRecord4(thread) || thread.id !== threadId || typeof thread.modelProvider !== "string" || !thread.modelProvider || thread.modelProvider === "codexhost" || typeof thread.cliVersion !== "string" || !thread.cliVersion || thread.cliVersion === "codexhost") {
23427
23427
  throw new Error("Native Thread response cannot establish Codex ownership");
23428
23428
  }
23429
23429
  }
@@ -23502,15 +23502,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
23502
23502
  var CODEX_ACCOUNT_LIST_METHOD = "codexhost/account/list";
23503
23503
  var CODEX_ACCOUNT_REFRESH_METHOD = "codexhost/account/refresh";
23504
23504
  var CODEX_ACCOUNT_CHANGED_METHOD = "codexhost/account/changed";
23505
- function isRecord4(value) {
23505
+ function isRecord5(value) {
23506
23506
  return typeof value === "object" && value !== null && !Array.isArray(value);
23507
23507
  }
23508
23508
  function notifiedThreadId(notification) {
23509
- if (!isRecord4(notification) || !THREAD_USAGE_REFRESH_METHODS.includes(notification.method)) {
23509
+ if (!isRecord5(notification) || !THREAD_USAGE_REFRESH_METHODS.includes(notification.method)) {
23510
23510
  return null;
23511
23511
  }
23512
23512
  const params = notification.params;
23513
- if (!isRecord4(params)) return null;
23513
+ if (!isRecord5(params)) return null;
23514
23514
  const parsed = hostThreadIdSchema.safeParse(params.threadId);
23515
23515
  return parsed.success ? parsed.data : null;
23516
23516
  }
@@ -23828,7 +23828,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23828
23828
  throw new Error("Renderer Account notification callback is unavailable");
23829
23829
  }
23830
23830
  return notifications.addNotificationCallback(CODEX_ACCOUNT_CHANGED_METHOD, (notification) => {
23831
- if (!isRecord4(notification) || notification.method !== CODEX_ACCOUNT_CHANGED_METHOD) return;
23831
+ if (!isRecord5(notification) || notification.method !== CODEX_ACCOUNT_CHANGED_METHOD) return;
23832
23832
  const state = codexAccountChangedSchema.safeParse(notification.params);
23833
23833
  if (state.success) listener(state.data);
23834
23834
  });
@@ -23837,16 +23837,16 @@ Codex Fast mode prioritizes requests and may increase usage.`
23837
23837
  }
23838
23838
 
23839
23839
  // src/renderer-external-queue.ts
23840
- function isRecord5(value) {
23840
+ function isRecord6(value) {
23841
23841
  return value !== null && typeof value === "object" && !Array.isArray(value);
23842
23842
  }
23843
23843
  function installRendererExternalQueue(target) {
23844
- if (!isRecord5(target) || typeof target.getTurnCoordinator !== "function" || typeof target.getConversation !== "function") {
23844
+ if (!isRecord6(target) || typeof target.getTurnCoordinator !== "function" || typeof target.getConversation !== "function") {
23845
23845
  return null;
23846
23846
  }
23847
23847
  const coordinator = target.getTurnCoordinator();
23848
- const queue = isRecord5(coordinator) ? coordinator.serverQueue : null;
23849
- if (!isRecord5(queue) || typeof queue.isEnabled !== "function") return null;
23848
+ const queue = isRecord6(coordinator) ? coordinator.serverQueue : null;
23849
+ if (!isRecord6(queue) || typeof queue.isEnabled !== "function") return null;
23850
23850
  const descriptor = Object.getOwnPropertyDescriptor(queue, "isEnabled");
23851
23851
  if (!descriptor?.writable) return null;
23852
23852
  const original = queue.isEnabled;
@@ -23855,7 +23855,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23855
23855
  const threadId = args[0];
23856
23856
  if (typeof threadId === "string") {
23857
23857
  const conversation = getConversation.call(target, threadId);
23858
- if (isRecord5(conversation) && conversation.id === threadId && // Reserved transport marker from externalThreadValue, retained by
23858
+ if (isRecord6(conversation) && conversation.id === threadId && // Reserved transport marker from externalThreadValue, retained by
23859
23859
  // Desktop in both newly created and hydrated conversation metadata.
23860
23860
  conversation.modelProvider === "codexhost") {
23861
23861
  return false;
@@ -23871,19 +23871,19 @@ Codex Fast mode prioritizes requests and may increase usage.`
23871
23871
 
23872
23872
  // src/renderer-external-steering.ts
23873
23873
  var THREAD_OWNERSHIP_LIST_METHOD2 = "codexhost/thread/ownership/list";
23874
- function isRecord6(value) {
23874
+ function isRecord7(value) {
23875
23875
  return value !== null && typeof value === "object" && !Array.isArray(value);
23876
23876
  }
23877
23877
  function isManager(value) {
23878
- return isRecord6(value) && ["sendRequest", "steerTurn", "startTurn", "getTurnCoordinator"].every(
23878
+ return isRecord7(value) && ["sendRequest", "steerTurn", "startTurn", "getTurnCoordinator"].every(
23879
23879
  (key) => typeof value[key] === "function"
23880
23880
  );
23881
23881
  }
23882
23882
  function submissionHost(manager) {
23883
23883
  const coordinator = manager.getTurnCoordinator();
23884
- const options = isRecord6(coordinator) ? coordinator.options : null;
23885
- const host = isRecord6(options) ? options.submissionHost : null;
23886
- if (!isRecord6(host) || typeof host.getActiveTurnId !== "function" || typeof host.hasPendingTurnStart !== "function") {
23884
+ const options = isRecord7(coordinator) ? coordinator.options : null;
23885
+ const host = isRecord7(options) ? options.submissionHost : null;
23886
+ if (!isRecord7(host) || typeof host.getActiveTurnId !== "function" || typeof host.hasPendingTurnStart !== "function") {
23887
23887
  throw new Error("Desktop turn submission binding is unavailable");
23888
23888
  }
23889
23889
  return {
@@ -23925,20 +23925,20 @@ Codex Fast mode prioritizes requests and may increase usage.`
23925
23925
  var INTERRUPTED_QUEUE_REASON = "Interrupted before the steer was accepted.";
23926
23926
  async function preserveQueuedFollowUps(manager, threadId) {
23927
23927
  const coordinator = manager.getTurnCoordinator();
23928
- if (!isRecord6(coordinator) || typeof coordinator.loadMessages !== "function" || typeof coordinator.readMessages !== "function" || typeof coordinator.mutate !== "function") {
23928
+ if (!isRecord7(coordinator) || typeof coordinator.loadMessages !== "function" || typeof coordinator.readMessages !== "function" || typeof coordinator.mutate !== "function") {
23929
23929
  throw new Error("Desktop follow-up queue binding is unavailable");
23930
23930
  }
23931
23931
  await coordinator.loadMessages.call(coordinator, threadId);
23932
23932
  const messages = coordinator.readMessages.call(coordinator, threadId);
23933
23933
  if (!Array.isArray(messages)) throw new Error("Desktop follow-up queue is unavailable");
23934
23934
  const alreadyPaused = new Set(
23935
- messages.filter((message2) => isRecord6(message2) && message2.pausedReason != null).map((message2) => message2.id)
23935
+ messages.filter((message2) => isRecord7(message2) && message2.pausedReason != null).map((message2) => message2.id)
23936
23936
  );
23937
23937
  return () => {
23938
23938
  coordinator.mutate.call(coordinator, threadId, (current) => {
23939
23939
  if (!Array.isArray(current)) return current;
23940
23940
  return current.map((message2) => {
23941
- if (!isRecord6(message2) || alreadyPaused.has(message2.id) || message2.pausedReason !== INTERRUPTED_QUEUE_REASON)
23941
+ if (!isRecord7(message2) || alreadyPaused.has(message2.id) || message2.pausedReason !== INTERRUPTED_QUEUE_REASON)
23942
23942
  return message2;
23943
23943
  const resumed = { ...message2 };
23944
23944
  delete resumed.pausedReason;
@@ -23959,9 +23959,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
23959
23959
  if ((method === "turn/start" || method === "turn/steer") && prepareTurnInput) {
23960
23960
  params = prepareTurnInput(params);
23961
23961
  }
23962
- const messageId = isRecord6(params) ? params.clientUserMessageId : null;
23963
- const route = typeof messageId === "string" && isRecord6(params) ? routes.get(`${params.threadId}\0${messageId}`) : void 0;
23964
- if (method !== "turn/start" || !isRecord6(params) || !route || route.threadId !== params.threadId) {
23962
+ const messageId = isRecord7(params) ? params.clientUserMessageId : null;
23963
+ const route = typeof messageId === "string" && isRecord7(params) ? routes.get(`${params.threadId}\0${messageId}`) : void 0;
23964
+ if (method !== "turn/start" || !isRecord7(params) || !route || route.threadId !== params.threadId) {
23965
23965
  if (method === "turn/start" && sendTurnStart) {
23966
23966
  return sendTurnStart(params, (input) => {
23967
23967
  if (disposed) throw new Error("External submission binding was disposed");
@@ -23987,7 +23987,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23987
23987
  options
23988
23988
  )
23989
23989
  ).then((response) => {
23990
- if (!isRecord6(response) || typeof response.turnId !== "string" || !response.turnId) {
23990
+ if (!isRecord7(response) || typeof response.turnId !== "string" || !response.turnId) {
23991
23991
  throw new Error("External steering returned no replacement Turn identity");
23992
23992
  }
23993
23993
  return {
@@ -24018,7 +24018,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24018
24018
  ] = args;
24019
24019
  if (typeof threadId !== "string") return originalSteer.apply(manager, args);
24020
24020
  const role = manager.getStreamRole?.(threadId);
24021
- if (isRecord6(role) && role.role === "follower") return originalSteer.apply(manager, args);
24021
+ if (isRecord7(role) && role.role === "follower") return originalSteer.apply(manager, args);
24022
24022
  let host = null;
24023
24023
  let expectedTurnId;
24024
24024
  try {
@@ -24047,15 +24047,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
24047
24047
  if (owner === "codex") return originalSteer.apply(manager, args);
24048
24048
  if (!host) throw new Error("Desktop turn submission binding is unavailable");
24049
24049
  const currentRole = manager.getStreamRole?.(threadId);
24050
- if (isRecord6(currentRole) && currentRole.role === "follower")
24050
+ if (isRecord7(currentRole) && currentRole.role === "follower")
24051
24051
  return originalSteer.apply(manager, args);
24052
24052
  if (!Array.isArray(input) || input.length === 0 || input.some(
24053
- (item) => !isRecord6(item) || item.type !== "text" || typeof item.text !== "string"
24054
- ) || !input.some((item) => isRecord6(item) && typeof item.text === "string" && item.text.trim())) {
24053
+ (item) => !isRecord7(item) || item.type !== "text" || typeof item.text !== "string"
24054
+ ) || !input.some((item) => isRecord7(item) && typeof item.text === "string" && item.text.trim())) {
24055
24055
  throw new Error("External steering requires non-empty text input");
24056
24056
  }
24057
24057
  if (toolOutput != null) throw new Error("External steering cannot replace a tool response");
24058
- if (!isRecord6(restoreMessage) || !isRecord6(restoreMessage.context)) {
24058
+ if (!isRecord7(restoreMessage) || !isRecord7(restoreMessage.context)) {
24059
24059
  throw new Error("Desktop steering message context is unavailable");
24060
24060
  }
24061
24061
  const messageId = typeof clientUserMessageId === "string" && clientUserMessageId ? clientUserMessageId : typeof restoreMessage.id === "string" && restoreMessage.id ? restoreMessage.id : crypto.randomUUID();
@@ -24103,7 +24103,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24103
24103
  },
24104
24104
  onMessageAdded
24105
24105
  );
24106
- if (!isRecord6(response) || !isRecord6(response.turn) || typeof response.turn.id !== "string") {
24106
+ if (!isRecord7(response) || !isRecord7(response.turn) || typeof response.turn.id !== "string") {
24107
24107
  throw new Error("Desktop returned no replacement Turn identity");
24108
24108
  }
24109
24109
  try {
@@ -24134,7 +24134,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24134
24134
  }
24135
24135
 
24136
24136
  // src/renderer-remote-attachments.ts
24137
- function isRecord7(value) {
24137
+ function isRecord8(value) {
24138
24138
  return value !== null && typeof value === "object" && !Array.isArray(value);
24139
24139
  }
24140
24140
  var MAX_IMAGE_BYTES = 20 * 1024 * 1024;
@@ -24186,14 +24186,14 @@ Codex Fast mode prioritizes requests and may increase usage.`
24186
24186
  function createRemoteAttachmentSender(target, hostId2, isCurrent) {
24187
24187
  const prepared = /* @__PURE__ */ new WeakMap();
24188
24188
  return (params, send) => {
24189
- if (hostId2 === "local" || !isRecord7(target) || !isRecord7(params) || typeof params.threadId !== "string" || !Array.isArray(params.input) || typeof target.getConversation !== "function")
24189
+ if (hostId2 === "local" || !isRecord8(target) || !isRecord8(params) || typeof params.threadId !== "string" || !Array.isArray(params.input) || typeof target.getConversation !== "function")
24190
24190
  return send(params);
24191
24191
  const images = params.input.filter(
24192
- (item) => isRecord7(item) && (item.type === "image" || item.type === "localImage")
24192
+ (item) => isRecord8(item) && (item.type === "image" || item.type === "localImage")
24193
24193
  );
24194
24194
  if (images.length === 0) return send(params);
24195
24195
  const conversation = target.getConversation.call(target, params.threadId);
24196
- if (!isRecord7(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
24196
+ if (!isRecord8(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
24197
24197
  return send(params);
24198
24198
  const assertCurrent = () => {
24199
24199
  if (!isCurrent()) throw new Error("Remote attachment connection is no longer available");
@@ -24206,7 +24206,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24206
24206
  const cached2 = prepared.get(params);
24207
24207
  if (cached2) return cached2.then(dispatch);
24208
24208
  const input = params.input;
24209
- const text = input.filter((item) => isRecord7(item) && item.type === "text").map((item) => isRecord7(item) && typeof item.text === "string" ? item.text : "").join("\n");
24209
+ const text = input.filter((item) => isRecord8(item) && item.type === "text").map((item) => isRecord8(item) && typeof item.text === "string" ? item.text : "").join("\n");
24210
24210
  const existingPaths = nativeImagePaths(text);
24211
24211
  const prepare = async () => {
24212
24212
  if (existingPaths.length === images.length) return params;
@@ -24238,7 +24238,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24238
24238
  contents: file2.contents,
24239
24239
  label: `image-${index + 1}.${file2.extension}`
24240
24240
  });
24241
- if (!isRecord7(saved) || !filePath(saved.path) || saved.fsPath !== saved.path) {
24241
+ if (!isRecord8(saved) || !filePath(saved.path) || saved.fsPath !== saved.path) {
24242
24242
  throw new Error("Desktop returned an invalid remote attachment path");
24243
24243
  }
24244
24244
  created.push(saved.path);
@@ -24345,11 +24345,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24345
24345
  }
24346
24346
 
24347
24347
  // src/renderer-manual-compaction.ts
24348
- function isRecord8(value) {
24348
+ function isRecord9(value) {
24349
24349
  return value !== null && typeof value === "object" && !Array.isArray(value);
24350
24350
  }
24351
24351
  function installRendererManualCompaction(target, hostId2, messages) {
24352
- if (!messages || typeof messages.addEventListener !== "function" || typeof messages.removeEventListener !== "function" || !isRecord8(target) || typeof target.registerPendingManualContextCompaction !== "function" || typeof target.getConversation !== "function") {
24352
+ if (!messages || typeof messages.addEventListener !== "function" || typeof messages.removeEventListener !== "function" || !isRecord9(target) || typeof target.registerPendingManualContextCompaction !== "function" || typeof target.getConversation !== "function") {
24353
24353
  return null;
24354
24354
  }
24355
24355
  const register = target.registerPendingManualContextCompaction;
@@ -24358,18 +24358,18 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24358
24358
  const listener = (event) => {
24359
24359
  if (event.source != null && event.source !== messages) return;
24360
24360
  const message2 = event.data;
24361
- if (!isRecord8(message2) || message2.type !== "mcp-notification" || message2.hostId !== hostId2 || message2.method !== THREAD_MANUAL_COMPACTION_STARTED_METHOD) {
24361
+ if (!isRecord9(message2) || message2.type !== "mcp-notification" || message2.hostId !== hostId2 || message2.method !== THREAD_MANUAL_COMPACTION_STARTED_METHOD) {
24362
24362
  return;
24363
24363
  }
24364
24364
  const params = threadManualCompactionStartedSchema.safeParse(message2.params);
24365
24365
  if (!params.success) return;
24366
24366
  const { threadId } = params.data;
24367
24367
  const conversation = getConversation.call(target, threadId);
24368
- if (!isRecord8(conversation) || conversation.id !== threadId || conversation.modelProvider !== "codexhost") {
24368
+ if (!isRecord9(conversation) || conversation.id !== threadId || conversation.modelProvider !== "codexhost") {
24369
24369
  return;
24370
24370
  }
24371
24371
  const role = getStreamRole?.call(target, threadId);
24372
- if (isRecord8(role) && role.role === "follower") return;
24372
+ if (isRecord9(role) && role.role === "follower") return;
24373
24373
  register.call(target, threadId);
24374
24374
  };
24375
24375
  messages.addEventListener("message", listener);
@@ -24584,7 +24584,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24584
24584
  var SIDEBAR_THREAD_HOST_ID_ATTRIBUTE = "data-app-action-sidebar-thread-host-id";
24585
24585
  var SIDEBAR_AGENT_ICON_ATTRIBUTE = "data-codexhost-sidebar-agent-icon";
24586
24586
  var OWNERSHIP_RETRY_DELAYS_MS = [100, 300, 800, 1500, 3e3];
24587
- function isRecord9(value) {
24587
+ function isRecord10(value) {
24588
24588
  return typeof value === "object" && value !== null && !Array.isArray(value);
24589
24589
  }
24590
24590
  function sidebarThreadAttributes(element) {
@@ -24611,19 +24611,19 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24611
24611
  const fiberName = fiberNames[0];
24612
24612
  if (fiberNames.length !== 1 || !fiberName) return null;
24613
24613
  const firstFiber2 = Object.getOwnPropertyDescriptor(element, fiberName)?.value;
24614
- if (!isRecord9(firstFiber2)) return null;
24614
+ if (!isRecord10(firstFiber2)) return null;
24615
24615
  const candidates = /* @__PURE__ */ new Set();
24616
24616
  let fiber = firstFiber2;
24617
24617
  for (let depth = 0; fiber && depth < 12; depth += 1) {
24618
24618
  const props = fiber.memoizedProps;
24619
- if (isRecord9(props) && isRecord9(props.dataAttributes)) {
24619
+ if (isRecord10(props) && isRecord10(props.dataAttributes)) {
24620
24620
  const dataAttributes = props.dataAttributes;
24621
24621
  const threadId = hostThreadIdSchema.safeParse(props.conversationId);
24622
24622
  if (threadId.success && dataAttributes[SIDEBAR_THREAD_ROW_ATTRIBUTE] === rowMarker && dataAttributes[SIDEBAR_THREAD_ID_ATTRIBUTE] === taskKey && dataAttributes[SIDEBAR_THREAD_HOST_ID_ATTRIBUTE] === hostId2) {
24623
24623
  candidates.add(threadId.data);
24624
24624
  }
24625
24625
  }
24626
- fiber = isRecord9(fiber.return) ? fiber.return : null;
24626
+ fiber = isRecord10(fiber.return) ? fiber.return : null;
24627
24627
  }
24628
24628
  return candidates.size === 1 ? candidates.values().next().value ?? null : null;
24629
24629
  }
@@ -25033,7 +25033,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25033
25033
  if (row) finish(row);
25034
25034
  });
25035
25035
  }
25036
- function isRecord10(value) {
25036
+ function isRecord11(value) {
25037
25037
  return typeof value === "object" && value !== null && !Array.isArray(value);
25038
25038
  }
25039
25039
  function firstFiber(element) {
@@ -25043,7 +25043,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25043
25043
  const name = names[0];
25044
25044
  if (names.length !== 1 || !name) return null;
25045
25045
  const value = Object.getOwnPropertyDescriptor(element, name)?.value;
25046
- return isRecord10(value) ? value : null;
25046
+ return isRecord11(value) ? value : null;
25047
25047
  }
25048
25048
  function directForkAncestors(first) {
25049
25049
  const ancestors = [];
@@ -25053,7 +25053,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25053
25053
  if (seen.has(fiber)) return [];
25054
25054
  seen.add(fiber);
25055
25055
  ancestors.push(fiber);
25056
- fiber = isRecord10(fiber.return) ? fiber.return : null;
25056
+ fiber = isRecord11(fiber.return) ? fiber.return : null;
25057
25057
  }
25058
25058
  return ancestors;
25059
25059
  }
@@ -25071,7 +25071,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25071
25071
  let hasForkCallback = false;
25072
25072
  for (const fiber of ancestors) {
25073
25073
  const props = fiber.memoizedProps;
25074
- if (!isRecord10(props)) continue;
25074
+ if (!isRecord11(props)) continue;
25075
25075
  if (!hasForkCallback && typeof props.onFork !== "function" && ownsOtherCallback(fiber, props)) {
25076
25076
  return null;
25077
25077
  }
@@ -25103,7 +25103,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25103
25103
  if (!threadId.success || !turnId.success) return null;
25104
25104
  const fiber = firstFiber(button2);
25105
25105
  const buttonProps = fiber?.memoizedProps;
25106
- if (!fiber || !isRecord10(buttonProps) || !Object.hasOwn(buttonProps, "aria-busy")) return null;
25106
+ if (!fiber || !isRecord11(buttonProps) || !Object.hasOwn(buttonProps, "aria-busy")) return null;
25107
25107
  return forkTargetFromAncestors(button2, threadId.data, turnId.data, directForkAncestors(fiber)) ?? forkTargetFromAncestors(button2, threadId.data, turnId.data, committedReactAncestors(fiber));
25108
25108
  }
25109
25109
  var BrowserRendererForkDom = class {
@@ -25193,7 +25193,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25193
25193
  }
25194
25194
  var DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS = 1e4;
25195
25195
  var DRAFT_PREWARM_POLICY_POLL_INTERVAL_MS = 25;
25196
- function isRecord11(value) {
25196
+ function isRecord12(value) {
25197
25197
  return typeof value === "object" && value !== null && !Array.isArray(value);
25198
25198
  }
25199
25199
  function decodeOpenCodeTransportModelId(value) {
@@ -25358,7 +25358,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25358
25358
  let fiber = findComposerFiber(composer);
25359
25359
  for (let depth = 0; fiber && depth < 120; depth += 1) {
25360
25360
  const props = fiber.memoizedProps;
25361
- if (isRecord11(props) && "conversationId" in props && props.conversationId != null) {
25361
+ if (isRecord12(props) && "conversationId" in props && props.conversationId != null) {
25362
25362
  const candidate = hostThreadIdSchema.safeParse(props.conversationId);
25363
25363
  if (!candidate.success || threadId !== void 0 && threadId !== candidate.data) {
25364
25364
  return null;
@@ -25371,12 +25371,12 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25371
25371
  return threadId;
25372
25372
  }
25373
25373
  function isLegacySevenSlotDraftWrapper(value) {
25374
- if (!Array.isArray(value) || value.length !== 7 || value[3] !== value[5] || value[3] !== value[6] || !isRecord11(value[3]) || typeof value[3].get !== "function" || typeof value[2] !== "string" && value[2] !== null) {
25374
+ if (!Array.isArray(value) || value.length !== 7 || value[3] !== value[5] || value[3] !== value[6] || !isRecord12(value[3]) || typeof value[3].get !== "function" || typeof value[2] !== "string" && value[2] !== null) {
25375
25375
  return false;
25376
25376
  }
25377
25377
  try {
25378
25378
  const draft = value[3].get();
25379
- return isRecord11(draft) && "modelSettings" in draft && "isManuallyChanged" in draft;
25379
+ return isRecord12(draft) && "modelSettings" in draft && "isManuallyChanged" in draft;
25380
25380
  } catch {
25381
25381
  return false;
25382
25382
  }
@@ -25410,8 +25410,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25410
25410
  let fiber = findComposerFiber(composer);
25411
25411
  for (let depth = 0; fiber && depth < 120; depth += 1) {
25412
25412
  const updateQueue = fiber.updateQueue;
25413
- const memoCache = isRecord11(updateQueue) ? updateQueue.memoCache : null;
25414
- const data = isRecord11(memoCache) && Array.isArray(memoCache.data) ? memoCache.data : [];
25413
+ const memoCache = isRecord12(updateQueue) ? updateQueue.memoCache : null;
25414
+ const data = isRecord12(memoCache) && Array.isArray(memoCache.data) ? memoCache.data : [];
25415
25415
  for (const value of data) {
25416
25416
  const draftId = draftIdFromMemoValue(value);
25417
25417
  if (draftId) draftIds.add(draftId);
@@ -25439,7 +25439,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25439
25439
  return ["default", draftIds.values().next().value];
25440
25440
  }
25441
25441
  function isDraftPrewarmPolicyReady(value) {
25442
- return isRecord11(value) && value.state === "ready" && typeof value.hostId === "string" && value.hostId.length > 0 && typeof value.select === "function" && typeof value.clear === "function";
25442
+ return isRecord12(value) && value.state === "ready" && typeof value.hostId === "string" && value.hostId.length > 0 && typeof value.select === "function" && typeof value.clear === "function";
25443
25443
  }
25444
25444
  async function waitForRendererDraftPrewarmPolicy(target, composer) {
25445
25445
  const deadline = Date.now() + DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS;
@@ -25705,11 +25705,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25705
25705
  return null;
25706
25706
  }
25707
25707
  }
25708
- function isRecord12(value) {
25708
+ function isRecord13(value) {
25709
25709
  return typeof value === "object" && value !== null && !Array.isArray(value);
25710
25710
  }
25711
25711
  function parseExternalConfiguration(value) {
25712
- if (!isRecord12(value)) return void 0;
25712
+ if (!isRecord13(value)) return void 0;
25713
25713
  const model2 = harnessModelRefSchema.safeParse(value.model);
25714
25714
  if (!model2.success) return void 0;
25715
25715
  const thinkingOptionId = harnessThinkingOptionIdSchema.safeParse(value.thinkingOptionId);
@@ -25726,10 +25726,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25726
25726
  const raw = storage.getItem(RENDERER_NEW_THREAD_PREFERENCE_KEY);
25727
25727
  if (!raw) return void 0;
25728
25728
  const parsed = JSON.parse(raw);
25729
- if (!isRecord12(parsed) || parsed.version !== 1) return void 0;
25729
+ if (!isRecord13(parsed) || parsed.version !== 1) return void 0;
25730
25730
  if (parsed.lastAgent !== "codex" && !harnessPluginIdSchema.safeParse(parsed.lastAgent).success)
25731
25731
  return void 0;
25732
- const externalByAgent = isRecord12(parsed.externalByAgent) ? parsed.externalByAgent : {};
25732
+ const externalByAgent = isRecord13(parsed.externalByAgent) ? parsed.externalByAgent : {};
25733
25733
  const parsedExternal = Object.fromEntries(
25734
25734
  Object.keys(externalByAgent).filter((agent) => harnessPluginIdSchema.safeParse(agent).success).flatMap((agent) => {
25735
25735
  const configuration = parseExternalConfiguration(externalByAgent[agent]);
@@ -25855,7 +25855,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25855
25855
  var GET_LOCALE_OVERRIDE_URL = "vscode://codex/get-setting";
25856
25856
  var GET_LOCALE_INFO_URL = "vscode://codex/locale-info";
25857
25857
  var DEFAULT_LOCALE_REQUEST_TIMEOUT_MS = 750;
25858
- function isRecord13(value) {
25858
+ function isRecord14(value) {
25859
25859
  return typeof value === "object" && value !== null && !Array.isArray(value);
25860
25860
  }
25861
25861
  function canonicalLocale(value) {
@@ -25877,7 +25877,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25877
25877
  return new DOMException("The operation was aborted", "AbortError");
25878
25878
  }
25879
25879
  function parseLocaleOverride(value) {
25880
- if (!isRecord13(value) || !("value" in value)) {
25880
+ if (!isRecord14(value) || !("value" in value)) {
25881
25881
  throw new Error("Codex locale override response is malformed");
25882
25882
  }
25883
25883
  if (value.value === null) return { value: null };
@@ -25892,7 +25892,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25892
25892
  return locale;
25893
25893
  }
25894
25894
  function parseLocaleInfo(value) {
25895
- if (!isRecord13(value)) throw new Error("Codex locale info response is malformed");
25895
+ if (!isRecord14(value)) throw new Error("Codex locale info response is malformed");
25896
25896
  return {
25897
25897
  ideLocale: optionalLocale(value.ideLocale, "IDE locale"),
25898
25898
  systemLocale: optionalLocale(value.systemLocale, "system locale")
@@ -25921,7 +25921,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25921
25921
  const onAbort = () => settle(() => reject(abortError2()));
25922
25922
  const onMessage = (event) => {
25923
25923
  const message3 = event.data;
25924
- if (!isRecord13(message3) || message3.type !== "fetch-response") return;
25924
+ if (!isRecord14(message3) || message3.type !== "fetch-response") return;
25925
25925
  if (message3.requestId !== requestId) return;
25926
25926
  if (message3.responseType !== "success" || typeof message3.status !== "number" || message3.status < 200 || message3.status >= 300 || typeof message3.bodyJsonString !== "string") {
25927
25927
  settle(() => reject(new Error("Codex locale request failed")));
@@ -31012,10 +31012,10 @@ ${detail}` : ""}`
31012
31012
  let previousWasTranslation = false;
31013
31013
  paragraphLines.forEach((line, lineIndex) => {
31014
31014
  if (lineIndex > 0 && !primaryIsCjk && CJK_PATTERN.test(line)) {
31015
- const translation = document2.createElement("span");
31016
- translation.className = "release-note-translation";
31017
- appendInline(document2, translation, line);
31018
- paragraph.append(translation);
31015
+ const translation2 = document2.createElement("span");
31016
+ translation2.className = "release-note-translation";
31017
+ appendInline(document2, translation2, line);
31018
+ paragraph.append(translation2);
31019
31019
  previousWasTranslation = true;
31020
31020
  return;
31021
31021
  }
@@ -31745,17 +31745,6 @@ ${detail}` : ""}`
31745
31745
  if (periodType === "seven_day") return messages.accountCreditsPeriodSevenDay;
31746
31746
  return messages.accountCreditsPeriodUnknown;
31747
31747
  }
31748
- function creditsProductLabel(product, messages) {
31749
- if (product === "GrokBuild" || product === "Build") return messages.accountCreditsBuild;
31750
- if (product === "5-hour window") return messages.accountCreditsPeriodFiveHour;
31751
- if (product === "7-day window") return messages.accountCreditsPeriodSevenDay;
31752
- if (product.endsWith(" \xB7 monthly"))
31753
- return `${product.slice(0, -" \xB7 monthly".length)} \xB7 ${messages.accountCreditsPeriodMonthly}`;
31754
- if (product === "GrokChat") return "Chat";
31755
- if (product === "GrokImagine") return "Imagine";
31756
- if (product === "GrokVoice") return "Voice";
31757
- return product;
31758
- }
31759
31748
  function formatAccountCreditsReset(value, locale, now = /* @__PURE__ */ new Date()) {
31760
31749
  if (locale !== "zh-CN") return formatRendererCreditsReset(value, now);
31761
31750
  const date5 = new Date(value);
@@ -31782,36 +31771,22 @@ ${detail}` : ""}`
31782
31771
  if (periodType === "weekly" || periodType === "seven_day") return "seven_day";
31783
31772
  return null;
31784
31773
  }
31785
- function scopedUsageProduct(product) {
31786
- const suffixes = [
31787
- [" \xB7 5-hour window", "five_hour"],
31788
- [" \xB7 Weekly window", "seven_day"],
31789
- [" \xB7 7-day window", "seven_day"],
31790
- [" \xB7 5-hour", "five_hour"],
31791
- [" \xB7 7-day", "seven_day"]
31792
- ];
31793
- for (const [suffix, period] of suffixes) {
31794
- if (!product.endsWith(suffix)) continue;
31795
- const scope = product.slice(0, -suffix.length).trim();
31796
- if (scope) return { scope, period };
31797
- }
31798
- return null;
31799
- }
31800
31774
  function splitUsageWindows(credits, messages, filter) {
31801
31775
  const generic = { columns: {} };
31802
31776
  const scopedRows = /* @__PURE__ */ new Map();
31803
31777
  const additional = [];
31804
31778
  const addScoped = (scope, period, window2) => {
31805
- const rows2 = scopedRows.get(scope) ?? [];
31779
+ const scopeLabel = localizeHarnessPresentation(scope, messages.locale).label;
31780
+ const rows2 = scopedRows.get(scope.id) ?? [];
31806
31781
  let row = rows2.find((candidate) => !candidate.columns[period]);
31807
31782
  if (!row) {
31808
- row = { scope, columns: {} };
31783
+ row = { scope: scopeLabel, columns: {} };
31809
31784
  rows2.push(row);
31810
- scopedRows.set(scope, rows2);
31785
+ scopedRows.set(scope.id, rows2);
31811
31786
  }
31812
31787
  row.columns[period] = {
31813
31788
  ...window2,
31814
- label: `${scope} \xB7 ${creditsPeriodLabel2(period, messages)}`,
31789
+ label: window2.label,
31815
31790
  scoped: true
31816
31791
  };
31817
31792
  };
@@ -31821,29 +31796,30 @@ ${detail}` : ""}`
31821
31796
  else additional.push(window2);
31822
31797
  };
31823
31798
  const primary = {
31824
- label: credits.label ? creditsProductLabel(credits.label, messages) : creditsPeriodLabel2(credits.periodType, messages),
31799
+ label: accountCreditsWindowLabel(
31800
+ credits,
31801
+ messages.locale,
31802
+ (period) => creditsPeriodLabel2(period, messages)
31803
+ ),
31825
31804
  usedPercent: credits.usedPercent,
31826
31805
  amount: credits,
31827
31806
  resetsAt: credits.resetsAt,
31828
- scoped: Boolean(credits.label && scopedUsageProduct(credits.label))
31807
+ scoped: Boolean(credits.scope)
31829
31808
  };
31830
- const primaryScope = credits.label ? scopedUsageProduct(credits.label) : null;
31831
- addWindow(
31832
- primary,
31833
- primaryScope?.period ?? (credits.label ? null : comparisonPeriod(credits.periodType)),
31834
- primaryScope?.scope
31835
- );
31809
+ addWindow(primary, comparisonPeriod(credits.periodType), credits.scope);
31836
31810
  for (const product of credits.productUsage ?? []) {
31837
- const scoped = scopedUsageProduct(product.product);
31838
31811
  const window2 = {
31839
- label: creditsProductLabel(product.product, messages),
31812
+ label: accountCreditsWindowLabel(
31813
+ product,
31814
+ messages.locale,
31815
+ (period) => creditsPeriodLabel2(period, messages)
31816
+ ),
31840
31817
  usedPercent: product.usagePercent,
31841
31818
  amount: product,
31842
31819
  resetsAt: product.resetsAt,
31843
- scoped: Boolean(scoped)
31820
+ scoped: Boolean(product.scope)
31844
31821
  };
31845
- const genericPeriod = product.product === "5-hour window" ? "five_hour" : product.product === "7-day window" ? "seven_day" : null;
31846
- addWindow(window2, scoped?.period ?? genericPeriod, scoped?.scope);
31822
+ addWindow(window2, comparisonPeriod(product.periodType ?? "unknown"), product.scope);
31847
31823
  }
31848
31824
  const structured = [...scopedRows.values()].flat();
31849
31825
  let rows = Object.keys(generic.columns).length > 0 ? [generic, ...structured] : structured;
@@ -32235,8 +32211,7 @@ ${detail}` : ""}`
32235
32211
  { status: "ready", credits: account.credits, freshness: "live", observedAt: null },
32236
32212
  messages,
32237
32213
  display,
32238
- () => void 0,
32239
- account.harnessId === "grok" ? "weekly-only" : "all"
32214
+ () => void 0
32240
32215
  ) : renderAccountBalance(document2, messages, account.balance);
32241
32216
  personCell.title = messages.accountNativeManagementHint.replace("{harness}", account.harnessName);
32242
32217
  appendAccountExtras(personCell, [importAction]);
@@ -39147,12 +39122,8 @@ ${usage_default}`;
39147
39122
  const index = Math.max(0, Math.min(Math.trunc(attempt), rendererUsageRefreshDelays.length - 1));
39148
39123
  return rendererUsageRefreshDelays[index] ?? rendererUsageRefreshDelays[0];
39149
39124
  }
39150
- function externalAgentHasAccountCredits(agent) {
39151
- return agent === "codex" || agent === "grok" || agent === "claude-code";
39152
- }
39153
- function shouldRetryExternalThreadUsage(agent, usage, accountCredits = null) {
39154
- if (usage === null) return true;
39155
- return externalAgentHasAccountCredits(agent) && accountCredits === null;
39125
+ function shouldRetryExternalThreadUsage(accountCreditsSupported, usage, accountCredits = null) {
39126
+ return usage === null || accountCreditsSupported && accountCredits === null;
39156
39127
  }
39157
39128
  function shouldReloadExternalCatalogAfterAvailabilityRefresh(previous, next, configurationReady, explicitRefresh = false) {
39158
39129
  const initialDiscoveryReady = previous === "checking" && next === "ready";
@@ -39737,6 +39708,8 @@ ${usage_default}`;
39737
39708
  mounted.usageRequestGeneration += 1;
39738
39709
  mounted.usage = update.usage;
39739
39710
  mounted.accountCredits = update.accountCredits ?? null;
39711
+ if (update.accountCreditsSupported !== void 0)
39712
+ mounted.accountCreditsSupported = update.accountCreditsSupported;
39740
39713
  usageRefreshAttempts.delete(mounted.composer);
39741
39714
  renderMounted(mounted);
39742
39715
  }
@@ -39791,13 +39764,13 @@ ${usage_default}`;
39791
39764
  }
39792
39765
  mounted.usage = result.usage;
39793
39766
  mounted.accountCredits = result.accountCredits ?? null;
39794
- const agent = controller.get(mounted.composer).agent;
39795
- if (result.usage !== null && (!externalAgentHasAccountCredits(agent) || result.accountCredits)) {
39767
+ mounted.accountCreditsSupported = result.accountCreditsSupported ?? false;
39768
+ if (result.usage !== null && (!mounted.accountCreditsSupported || result.accountCredits)) {
39796
39769
  usageRefreshAttempts.delete(mounted.composer);
39797
39770
  }
39798
39771
  renderMounted(mounted);
39799
39772
  if (shouldRetryExternalThreadUsage(
39800
- controller.get(mounted.composer).agent,
39773
+ mounted.accountCreditsSupported,
39801
39774
  result.usage,
39802
39775
  result.accountCredits ?? null
39803
39776
  )) {
@@ -39806,7 +39779,7 @@ ${usage_default}`;
39806
39779
  } catch (error51) {
39807
39780
  if (mountedByComposer.get(mounted.composer) === mounted && mounted.usageRequestGeneration === generation) {
39808
39781
  renderMounted(mounted);
39809
- if (!(error51 instanceof RendererMethodUnavailableError) && shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null, null)) {
39782
+ if (!(error51 instanceof RendererMethodUnavailableError) && shouldRetryExternalThreadUsage(mounted.accountCreditsSupported, null, null)) {
39810
39783
  scheduleThreadUsageRefresh(mounted);
39811
39784
  }
39812
39785
  }
@@ -39914,14 +39887,7 @@ ${usage_default}`;
39914
39887
  renderMounted(mounted);
39915
39888
  if (mounted.ownershipStatus !== "error") void refreshCommands(mounted);
39916
39889
  sidebarAgentIcons.refresh();
39917
- if (mounted.ownershipStatus !== "error") {
39918
- const agent = controller.get(mounted.composer).agent;
39919
- if (agent === "codex") {
39920
- void refreshThreadUsage(mounted);
39921
- } else if (shouldRetryExternalThreadUsage(agent, mounted.usage, mounted.accountCredits)) {
39922
- scheduleThreadUsageRefresh(mounted);
39923
- }
39924
- }
39890
+ if (mounted.ownershipStatus !== "error") void refreshThreadUsage(mounted);
39925
39891
  } else if (isRetainedComposer(mounted) && controller.isCurrentOwnershipRequest(mounted.composer, generation) && orbitComposerKind(mounted.composer) === "unknown") {
39926
39892
  ownershipRecovery.set(mounted, generation);
39927
39893
  scheduleScan();
@@ -39951,7 +39917,7 @@ ${usage_default}`;
39951
39917
  if (resolution === "transfer") {
39952
39918
  mounted.ownershipStatus = "ready";
39953
39919
  renderMounted(mounted);
39954
- if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null, null)) {
39920
+ if (shouldRetryExternalThreadUsage(mounted.accountCreditsSupported, null, null)) {
39955
39921
  scheduleThreadUsageRefresh(mounted);
39956
39922
  }
39957
39923
  } else {
@@ -41042,6 +41008,7 @@ ${usage_default}`;
41042
41008
  threadConfiguration: inherited?.threadConfiguration,
41043
41009
  usage: inherited?.usage ?? null,
41044
41010
  accountCredits: inherited?.accountCredits ?? null,
41011
+ accountCreditsSupported: inherited?.accountCreditsSupported ?? false,
41045
41012
  hostId: inherited?.hostId ?? hostId2,
41046
41013
  usageRequestGeneration: 0,
41047
41014
  commandRequestGeneration: 0
@@ -41054,7 +41021,11 @@ ${usage_default}`;
41054
41021
  sidebarAgentIcons.refresh();
41055
41022
  if (threadIdFromComposerModelTarget(modelTarget) && !inherited) {
41056
41023
  void loadThreadOwnership(mounted);
41057
- } else if (threadIdFromComposerModelTarget(modelTarget) && inherited && shouldRetryExternalThreadUsage(state.agent, mounted.usage, mounted.accountCredits)) {
41024
+ } else if (threadIdFromComposerModelTarget(modelTarget) && inherited && shouldRetryExternalThreadUsage(
41025
+ mounted.accountCreditsSupported,
41026
+ mounted.usage,
41027
+ mounted.accountCredits
41028
+ )) {
41058
41029
  scheduleThreadUsageRefresh(mounted);
41059
41030
  } else if (state.agent !== "codex" && !isExternalConfigurationStable(mounted.modelView, mounted.permissionModeView)) {
41060
41031
  void loadExternalCatalog(mounted);