@codexhost/cli-darwin-x64 0.13.1 → 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.
@@ -14754,6 +14754,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14754
14754
  var REMOTE_THREAD_REPLY_MAX_BYTES = 16 * 1024 * 1024;
14755
14755
  var REMOTE_THREAD_READ_TIMEOUT_MS = 35e3;
14756
14756
  var DELEGATION_READ_METHOD = "codexhost/thread/delegation-read";
14757
+ var THREAD_REFERENCE_SOURCE_HOST_PARAM = "codexhostSourceHostId";
14757
14758
  var delegationReadParamsSchema = external_exports.strictObject({
14758
14759
  threadId: external_exports.string().min(1).max(1024),
14759
14760
  view: external_exports.enum(["result", "messages"]),
@@ -14834,6 +14835,48 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14834
14835
  initializeOnly: external_exports.boolean().optional()
14835
14836
  });
14836
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
+
14837
14880
  // ../shared-contracts/dist/model-price-overrides.js
14838
14881
  var MODEL_PRICE_OVERRIDES_GET_METHOD = "codexhost/usage/model-prices/get";
14839
14882
  var MODEL_PRICE_OVERRIDES_SET_METHOD = "codexhost/usage/model-prices/set";
@@ -15178,8 +15221,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15178
15221
  }
15179
15222
  });
15180
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();
15181
15236
  var accountCreditsProductUsageSchema = external_exports.object({
15182
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(),
15183
15242
  used: external_exports.number().finite().nonnegative().optional(),
15184
15243
  // Zero is a real empty cap, not an absent field.
15185
15244
  limit: external_exports.number().finite().nonnegative().optional(),
@@ -15199,9 +15258,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15199
15258
  unit: external_exports.string().min(1).max(32).optional(),
15200
15259
  /** Native label when the primary limit is scoped to a model or product group. */
15201
15260
  label: external_exports.string().min(1).optional(),
15261
+ scope: accountCreditsScopeSchema.optional(),
15262
+ localizations: harnessLocalizationsSchema.optional(),
15202
15263
  usedPercent: usagePercentSchema,
15203
15264
  resetsAt: external_exports.string().min(1).optional(),
15204
- periodType: external_exports.enum(["weekly", "monthly", "five_hour", "seven_day", "unknown"]),
15265
+ periodType: accountCreditsPeriodSchema,
15205
15266
  productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional(),
15206
15267
  resetCredits: accountResetCreditsSchema.optional()
15207
15268
  }).strict();
@@ -15212,7 +15273,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15212
15273
  var threadUsageInspectionSchema = external_exports.object({
15213
15274
  threadId: hostThreadIdSchema,
15214
15275
  usage: threadUsageSnapshotSchema.nullable(),
15215
- 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()
15216
15279
  }).strict();
15217
15280
 
15218
15281
  // ../shared-contracts/dist/harness-accounts.js
@@ -15339,7 +15402,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15339
15402
  id: harnessPermissionModeIdSchema,
15340
15403
  label: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_LABEL_MAX_LENGTH),
15341
15404
  description: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_DESCRIPTION_MAX_LENGTH).optional(),
15342
- dangerous: external_exports.boolean().optional()
15405
+ dangerous: external_exports.boolean().optional(),
15406
+ localizations: harnessLocalizationsSchema.optional()
15343
15407
  }).strict();
15344
15408
  var harnessPermissionModeCatalogSchema = external_exports.object({
15345
15409
  modes: external_exports.array(harnessPermissionModeSchema).min(1).max(HARNESS_PERMISSION_MODE_CATALOG_MAX_LENGTH),
@@ -15762,6 +15826,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15762
15826
  // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15763
15827
  message: external_exports.string().max(2048).optional(),
15764
15828
  messageCode: external_exports.string().min(1).max(128).optional(),
15829
+ /** Safe plugin-owned explanation, distinct from raw diagnostic message. */
15830
+ notice: harnessLocalizedTextSchema.optional(),
15765
15831
  latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15766
15832
  }).strict();
15767
15833
 
@@ -15893,6 +15959,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15893
15959
  invocation: commandInvocationSchema,
15894
15960
  label: commandLabelSchema,
15895
15961
  description: commandDescriptionSchema.optional(),
15962
+ localizations: harnessLocalizationsSchema.optional(),
15896
15963
  argumentMode: external_exports.enum(["none", "text"]),
15897
15964
  /**
15898
15965
  * Native distinction reported by the Harness. Omitted when the Harness does
@@ -17456,37 +17523,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17456
17523
 
17457
17524
  // src/settings/harness-version-messages.ts
17458
17525
  var harnessVersionEnglish = Object.freeze({
17526
+ locale: "en",
17459
17527
  unknown: "Unknown",
17460
17528
  trackingBranch: "Tracking branch (new commits)",
17461
17529
  notes: Object.freeze({
17462
- "original-installer": "Use the original installer, package manager, or launcher to update this installation.",
17463
- "claude-policy-restricted": "Claude updates are restricted by the installation's settings or policy.",
17464
- "codebuddy-npm-required": "Use CodeBuddy's native updater or original package manager. Latest-version checks here require an identified npm installation.",
17465
- "deepseek-original-installer": "Update with the original installer. Python, desktop, and project-local installations are not upgraded through global npm.",
17466
- "kiro-native-updater": "Use Kiro CLI's original installer or native updater to check for and install updates.",
17467
- "zcode-desktop-updater": "The CLI ships inside ZCode Desktop. Update ZCode Desktop itself to update it.",
17468
- "qoder-check-unavailable": "This Qoder China release does not expose a non-installing update check. Use its original installer.",
17469
- "hermes-update-plan-unavailable": "This Hermes release does not expose a safe update plan. Use the original installer.",
17470
- "hermes-externally-managed": "This Hermes installation is managed externally. Update it through its desktop app, container, or original package manager.",
17471
- "hermes-update-channel": "Uses Hermes's configured update channel. Gateway restarts are deferred; existing processes keep their running code.",
17472
- "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."
17473
17531
  })
17474
17532
  });
17475
17533
  var harnessVersionChinese = Object.freeze({
17534
+ locale: "zh-CN",
17476
17535
  unknown: "\u672A\u77E5",
17477
17536
  trackingBranch: "\u8DDF\u8E2A\u5206\u652F\uFF08\u6709\u65B0\u63D0\u4EA4\uFF09",
17478
17537
  notes: Object.freeze({
17479
- "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",
17480
- "claude-policy-restricted": "\u6B64 Claude \u5B89\u88C5\u7684\u8BBE\u7F6E\u6216\u7B56\u7565\u9650\u5236\u4E86\u66F4\u65B0\u3002",
17481
- "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",
17482
- "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",
17483
- "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",
17484
- "zcode-desktop-updater": "CLI \u968F ZCode Desktop \u4E00\u8D77\u53D1\u5E03\uFF0C\u8BF7\u76F4\u63A5\u66F4\u65B0 ZCode Desktop\u3002",
17485
- "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",
17486
- "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",
17487
- "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",
17488
- "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",
17489
- "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"
17490
17539
  })
17491
17540
  });
17492
17541
  function harnessVersionLabel(state, messages) {
@@ -17498,6 +17547,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17498
17547
  return state.latestVersion;
17499
17548
  }
17500
17549
  function harnessVersionNote(state, messages) {
17550
+ if (state?.notice) return localizeHarnessText(state.notice, messages.locale);
17501
17551
  const code = state?.messageCode;
17502
17552
  return code && Object.hasOwn(messages.notes, code) ? messages.notes[code] : void 0;
17503
17553
  }
@@ -18758,7 +18808,7 @@ ${error51.stderrTail}`] : []
18758
18808
  launchPathSaveError: "Could not save. Enter an existing absolute installation folder on this Host and check configuration permissions.",
18759
18809
  connectionOfficialWebsite: "Visit official website",
18760
18810
  connectionOpenHarnessWeb: "Open DeepSeek Harness Web",
18761
- 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.",
18762
18812
  connectionInstall: "Install",
18763
18813
  connectionInstallDescription: "This Harness was not detected.",
18764
18814
  connectionInstallRunning: "Installing on the selected Host. You can leave this page; login or setup may still be required afterward.",
@@ -19031,7 +19081,7 @@ ${error51.stderrTail}`] : []
19031
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",
19032
19082
  connectionOfficialWebsite: "\u8BBF\u95EE\u5B98\u7F51",
19033
19083
  connectionOpenHarnessWeb: "\u6253\u5F00 DeepSeek Harness Web",
19034
- 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",
19035
19085
  connectionInstall: "\u5B89\u88C5",
19036
19086
  connectionInstallDescription: "\u5C1A\u672A\u68C0\u6D4B\u5230\u8BE5 Harness\u3002",
19037
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",
@@ -19827,7 +19877,6 @@ ${error51.stderrTail}`] : []
19827
19877
  // src/renderer-usage-control.ts
19828
19878
  var ENGLISH_USAGE_MESSAGES = Object.freeze({
19829
19879
  usage: "Usage",
19830
- account: "Account",
19831
19880
  context: "Context",
19832
19881
  recordedCredits: "Recorded usage",
19833
19882
  latestCacheHit: "Latest cache hit (CH)",
@@ -19853,7 +19902,6 @@ ${error51.stderrTail}`] : []
19853
19902
  });
19854
19903
  var CHINESE_USAGE_MESSAGES = Object.freeze({
19855
19904
  usage: "\u7528\u91CF",
19856
- account: "\u8D26\u53F7",
19857
19905
  context: "\u4E0A\u4E0B\u6587",
19858
19906
  recordedCredits: "\u5DF2\u8BB0\u5F55\u6D88\u8017",
19859
19907
  latestCacheHit: "\u6700\u8FD1\u7F13\u5B58\u547D\u4E2D\uFF08CH\uFF09",
@@ -19965,10 +20013,10 @@ ${error51.stderrTail}`] : []
19965
20013
  popover.style.color = "CanvasText";
19966
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))";
19967
20015
  }
19968
- function addDetailRow(parent, label, value, wrap = false) {
20016
+ function addDetailRow(parent, label, value) {
19969
20017
  const row = document.createElement("div");
19970
20018
  row.style.display = "grid";
19971
- row.style.gridTemplateColumns = wrap ? "auto minmax(0, 1fr)" : "minmax(0, 1fr) auto";
20019
+ row.style.gridTemplateColumns = "minmax(0, 1fr) auto";
19972
20020
  row.style.gap = "20px";
19973
20021
  row.style.padding = "4px 0";
19974
20022
  const labelElement = document.createElement("span");
@@ -19978,10 +20026,6 @@ ${error51.stderrTail}`] : []
19978
20026
  valueElement.textContent = value;
19979
20027
  valueElement.style.fontVariantNumeric = "tabular-nums";
19980
20028
  valueElement.style.textAlign = "right";
19981
- if (wrap) {
19982
- valueElement.style.overflowWrap = "anywhere";
19983
- valueElement.title = value;
19984
- }
19985
20029
  row.append(labelElement, valueElement);
19986
20030
  parent.append(row);
19987
20031
  }
@@ -20032,14 +20076,13 @@ ${error51.stderrTail}`] : []
20032
20076
  if (note) addNote(parent, note);
20033
20077
  }
20034
20078
  }
20035
- function renderDetails(popover, usage, messages, locale, accountName) {
20079
+ function renderDetails(popover, usage, messages, locale) {
20036
20080
  popover.replaceChildren();
20037
20081
  const heading = document.createElement("div");
20038
20082
  heading.textContent = messages.usage;
20039
20083
  heading.style.fontWeight = "600";
20040
20084
  heading.style.marginBottom = "6px";
20041
20085
  popover.append(heading);
20042
- if (accountName) addDetailRow(popover, messages.account, accountName, true);
20043
20086
  if (usage?.contextUsagePercent !== void 0) {
20044
20087
  addContextRow(
20045
20088
  popover,
@@ -20271,7 +20314,7 @@ ${error51.stderrTail}`] : []
20271
20314
  document.body.append(popover);
20272
20315
  return control;
20273
20316
  }
20274
- function renderRendererUsageControl(control, usage, locale = control.locale, accountName = null) {
20317
+ function renderRendererUsageControl(control, usage, locale = control.locale) {
20275
20318
  control.locale = locale;
20276
20319
  const messages = rendererUsageMessages(locale);
20277
20320
  control.popover.setAttribute("aria-label", messages.threadUsageDetails);
@@ -20280,7 +20323,7 @@ ${error51.stderrTail}`] : []
20280
20323
  const totalCostUsd = usage?.totalCostUsd;
20281
20324
  const hasContext = usage?.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0;
20282
20325
  const hasTokenUsage = usage?.totalTokens !== void 0 || usage?.inputTokens !== void 0 || usage?.cachedInputTokens !== void 0 || usage?.cacheWriteInputTokens !== void 0 || usage?.outputTokens !== void 0;
20283
- const visible = rendererUsageHasDisplayData(usage) || Boolean(accountName);
20326
+ const visible = rendererUsageHasDisplayData(usage);
20284
20327
  control.root.style.display = visible ? "inline-flex" : "none";
20285
20328
  if (!visible) {
20286
20329
  closePopover(control);
@@ -20314,7 +20357,7 @@ ${error51.stderrTail}`] : []
20314
20357
  control.trigger.setAttribute("aria-label", accessibleSummary);
20315
20358
  control.trigger.title = accessibleSummary;
20316
20359
  control.label.textContent = compactSummary;
20317
- renderDetails(control.popover, usage, messages, locale, accountName);
20360
+ renderDetails(control.popover, usage, messages, locale);
20318
20361
  return true;
20319
20362
  }
20320
20363
 
@@ -20583,7 +20626,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
20583
20626
  loadingPermissions: "Loading permissions...",
20584
20627
  selecting: "Selecting...",
20585
20628
  permissionsUnavailable: "Permissions unavailable",
20586
- 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.",
20587
20630
  codexUsageGateUnavailable: "Could not separate this Harness from the Codex usage limit in this Desktop version. Codex usage limits still apply to sending.",
20588
20631
  modelSelectionRejected: "Couldn't switch Model",
20589
20632
  thinkingSelectionRejected: "Couldn't switch Thinking option"
@@ -20600,127 +20643,20 @@ Codex Fast mode prioritizes requests and may increase usage.`
20600
20643
  loadingPermissions: "\u6B63\u5728\u52A0\u8F7D\u6743\u9650...",
20601
20644
  selecting: "\u6B63\u5728\u9009\u62E9...",
20602
20645
  permissionsUnavailable: "\u6743\u9650\u4E0D\u53EF\u7528",
20603
- 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",
20604
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",
20605
20648
  modelSelectionRejected: "\u65E0\u6CD5\u5207\u6362\u6A21\u578B",
20606
20649
  thinkingSelectionRejected: "\u65E0\u6CD5\u5207\u6362\u601D\u8003\u9009\u9879"
20607
20650
  });
20608
- var ENGLISH_PERMISSION_MODE_LABELS = /* @__PURE__ */ new Map([
20609
- ["read-only", "Read only"],
20610
- ["workspace-write", "Workspace write"],
20611
- ["danger-full-access", "Full access (dangerous)"]
20612
- ]);
20613
- var CHINESE_PERMISSION_MODE_LABELS = /* @__PURE__ */ new Map([
20614
- ["Always ask", "\u59CB\u7EC8\u8BE2\u95EE"],
20615
- ["Write", "\u5199\u5165"],
20616
- ["Full access", "\u5B8C\u5168\u8BBF\u95EE"],
20617
- ["Plan mode", "\u89C4\u5212\u6A21\u5F0F"],
20618
- ["Default", "\u9ED8\u8BA4"],
20619
- ["Accept edits", "\u63A5\u53D7\u7F16\u8F91"],
20620
- ["Auto mode", "\u81EA\u52A8\u6A21\u5F0F"],
20621
- ["Bypass permissions", "\u7ED5\u8FC7\u6743\u9650"],
20622
- ["Ask", "\u8BE2\u95EE"],
20623
- ["Auto", "\u81EA\u52A8"],
20624
- ["Always approve", "\u59CB\u7EC8\u6279\u51C6"],
20625
- ["Allow all", "\u5168\u90E8\u5141\u8BB8"],
20626
- ["Read only", "\u53EA\u8BFB"],
20627
- ["Workspace write", "\u5DE5\u4F5C\u533A\u5199\u5165"],
20628
- ["Full access (dangerous)", "\u5B8C\u5168\u8BBF\u95EE\uFF08\u5371\u9669\uFF09"],
20629
- ["Configured permissions", "\u4F7F\u7528\u5DF2\u914D\u7F6E\u6743\u9650"],
20630
- ["Skip permissions", "\u8DF3\u8FC7\u6743\u9650\u68C0\u67E5"],
20631
- ["Always Ask", "\u59CB\u7EC8\u8BE2\u95EE"],
20632
- ["Accept Edits", "\u63A5\u53D7\u7F16\u8F91"],
20633
- ["Plan", "\u89C4\u5212\u6A21\u5F0F"],
20634
- ["Don't Ask", "\u4E0D\u8BE2\u95EE"],
20635
- ["Bypass Permissions", "\u7ED5\u8FC7\u6743\u9650"],
20636
- ["Full Access", "\u5B8C\u5168\u8BBF\u95EE"],
20637
- ["Delegate", "\u7531\u7236\u4F1A\u8BDD\u7BA1\u7406"]
20638
- ]);
20639
- var CHINESE_PERMISSION_MODE_DESCRIPTIONS = /* @__PURE__ */ new Map([
20640
- [
20641
- "Automatically allow reads and ask before write or execution actions.",
20642
- "\u81EA\u52A8\u5141\u8BB8\u8BFB\u53D6\uFF1B\u5199\u5165\u6216\u6267\u884C\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"
20643
- ],
20644
- [
20645
- "Automatically allow reads and writes; ask before execution actions.",
20646
- "\u81EA\u52A8\u5141\u8BB8\u8BFB\u53D6\u548C\u5199\u5165\uFF1B\u6267\u884C\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"
20647
- ],
20648
- ["Run all tool actions without approval prompts.", "\u65E0\u9700\u6279\u51C6\u63D0\u793A\u5373\u53EF\u8FD0\u884C\u6240\u6709\u5DE5\u5177\u64CD\u4F5C\u3002"],
20649
- [
20650
- "Explore and prepare a plan; approval exits planning and resumes the previous permission mode.",
20651
- "\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"
20652
- ],
20653
- ["Ask before edits and other protected actions.", "\u7F16\u8F91\u548C\u5176\u4ED6\u53D7\u4FDD\u62A4\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
20654
- ["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"],
20655
- ["Let Claude classify permission requests.", "\u7531 Claude \u5224\u65AD\u6743\u9650\u8BF7\u6C42\u3002"],
20656
- ["Skip Claude Code permission checks.", "\u8DF3\u8FC7 Claude Code \u6743\u9650\u68C0\u67E5\u3002"],
20657
- [
20658
- "Use Grok Build's default interactive approval policy.",
20659
- "\u4F7F\u7528 Grok Build \u7684\u9ED8\u8BA4\u4EA4\u4E92\u5F0F\u6279\u51C6\u7B56\u7565\u3002"
20660
- ],
20661
- ["Ask before protected tool actions.", "\u6267\u884C\u53D7\u4FDD\u62A4\u7684\u5DE5\u5177\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
20662
- [
20663
- "Let Grok Build decide which tool actions may run automatically.",
20664
- "\u7531 Grok Build \u51B3\u5B9A\u54EA\u4E9B\u5DE5\u5177\u64CD\u4F5C\u53EF\u81EA\u52A8\u8FD0\u884C\u3002"
20665
- ],
20666
- ["Approve all tool actions without prompting.", "\u65E0\u9700\u63D0\u793A\u5373\u53EF\u6279\u51C6\u6240\u6709\u5DE5\u5177\u64CD\u4F5C\u3002"],
20667
- ["Use OpenCode's configured permission rules.", "\u4F7F\u7528 OpenCode \u5DF2\u914D\u7F6E\u7684\u6743\u9650\u89C4\u5219\u3002"],
20668
- ["Ask before protected OpenCode actions.", "\u6267\u884C\u53D7\u4FDD\u62A4\u7684 OpenCode \u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
20669
- ["Allow OpenCode actions without approval prompts.", "\u5141\u8BB8 OpenCode \u64CD\u4F5C\uFF0C\u65E0\u9700\u6279\u51C6\u63D0\u793A\u3002"],
20670
- [
20671
- "Use Antigravity CLI permission rules; headless prompts are denied safely.",
20672
- "\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"
20673
- ],
20674
- ["Auto-approve every Antigravity CLI tool action.", "\u81EA\u52A8\u6279\u51C6\u6240\u6709 Antigravity CLI \u5DE5\u5177\u64CD\u4F5C\u3002"],
20675
- ["Prompts for permission on first use of each tool", "\u9996\u6B21\u4F7F\u7528\u6BCF\u79CD\u5DE5\u5177\u65F6\u8BF7\u6C42\u6743\u9650\u3002"],
20676
- [
20677
- "Automatically accepts file edit permissions for the session",
20678
- "\u81EA\u52A8\u63A5\u53D7\u672C\u4F1A\u8BDD\u4E2D\u7684\u6587\u4EF6\u7F16\u8F91\u6743\u9650\u3002"
20679
- ],
20680
- [
20681
- "Agent can analyze but not modify files or execute commands",
20682
- "Agent \u53EF\u4EE5\u5206\u6790\uFF0C\u4F46\u4E0D\u80FD\u4FEE\u6539\u6587\u4EF6\u6216\u6267\u884C\u547D\u4EE4\u3002"
20683
- ],
20684
- [
20685
- "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)",
20686
- "\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"
20687
- ],
20688
- [
20689
- "Does not show permission prompts; pre-approved and safe read-only actions run, everything else that would prompt is denied",
20690
- "\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"
20691
- ],
20692
- ["Skips all permission prompts", "\u8DF3\u8FC7\u5E38\u89C4\u6743\u9650\u8BE2\u95EE\u3002"],
20693
- [
20694
- "Skips ALL permission checks including dangerous commands for all agents",
20695
- "\u4E3A\u6240\u6709 Agent \u8DF3\u8FC7\u5168\u90E8\u6743\u9650\u68C0\u67E5\uFF0C\u5305\u62EC\u5371\u9669\u547D\u4EE4\u3002"
20696
- ],
20697
- ["Permissions managed by parent session", "\u7531\u7236\u4F1A\u8BDD\u7BA1\u7406\u6743\u9650\u3002"],
20698
- [
20699
- "Native agent mode with Cursor tool approvals",
20700
- "\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"
20701
- ],
20702
- ["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"],
20703
- ["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"]
20704
- ]);
20705
20651
  function rendererHarnessMessages(locale) {
20706
20652
  return locale === "zh-CN" ? CHINESE_HARNESS_MESSAGES : ENGLISH_HARNESS_MESSAGES;
20707
20653
  }
20708
20654
  function rendererHarnessCommandPresentation(command, locale) {
20709
- if (locale === "zh-CN" && command.invocation === "/compact") {
20710
- return { label: "\u538B\u7F29\u4E0A\u4E0B\u6587", description: "\u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\u4E0A\u4E0B\u6587" };
20711
- }
20712
- return {
20713
- label: command.label,
20714
- description: command.description ?? command.label
20715
- };
20655
+ const presentation = localizeHarnessPresentation(command, locale);
20656
+ return { ...presentation, description: presentation.description ?? presentation.label };
20716
20657
  }
20717
20658
  function rendererPermissionModePresentation(mode, locale) {
20718
- const label = ENGLISH_PERMISSION_MODE_LABELS.get(mode.label) ?? mode.label;
20719
- if (locale !== "zh-CN") return { label, description: mode.description };
20720
- return {
20721
- label: CHINESE_PERMISSION_MODE_LABELS.get(label) ?? label,
20722
- description: mode.description === void 0 ? void 0 : CHINESE_PERMISSION_MODE_DESCRIPTIONS.get(mode.description) ?? mode.description
20723
- };
20659
+ return localizeHarnessPresentation(mode, locale);
20724
20660
  }
20725
20661
  function rendererLiveCommandsPendingNotice(locale, harnessLabel) {
20726
20662
  const harness2 = harnessLabel.replace(/\s*[((][^))]*[))]\s*$/u, "").trim() || harnessLabel;
@@ -22002,30 +21938,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
22002
21938
  return messages.account;
22003
21939
  }
22004
21940
  function productLabel(product, locale = "en") {
22005
- if (product === "GrokBuild") return "Build";
22006
- if (product === "GrokChat") return "Chat";
22007
- if (product === "GrokImagine") return "Imagine";
22008
- if (product === "GrokVoice") return "Voice";
22009
- const messages = rendererCreditsMessages(locale);
22010
- if (product === "5-hour window") return messages.fiveHour;
22011
- if (product === "7-day window") return messages.sevenDay;
22012
- if (product === "Weekly window") return messages.weekly;
22013
- if (product.endsWith(" \xB7 5-hour window")) {
22014
- return `${product.slice(0, -"5-hour window".length)}${messages.fiveHour}`;
22015
- }
22016
- if (product.endsWith(" \xB7 7-day window")) {
22017
- return `${product.slice(0, -"7-day window".length)}${messages.sevenDay}`;
22018
- }
22019
- if (product.endsWith(" \xB7 Weekly window")) {
22020
- return `${product.slice(0, -"Weekly window".length)}${messages.weekly}`;
22021
- }
22022
- if (product.endsWith(" \xB7 5-hour")) {
22023
- return `${product.slice(0, -"5-hour".length)}${messages.fiveHour}`;
22024
- }
22025
- if (product.endsWith(" \xB7 7-day")) {
22026
- return `${product.slice(0, -"7-day".length)}${messages.sevenDay}`;
22027
- }
22028
- return product;
21941
+ return accountCreditsWindowLabel(product, locale, (period) => creditsPeriodLabel(period, locale));
22029
21942
  }
22030
21943
  function toneColor(tone) {
22031
21944
  if (tone === "hot") return "#c45c4a";
@@ -22066,7 +21979,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
22066
21979
  top.style.marginBottom = "5px";
22067
21980
  const left = document.createElement("div");
22068
21981
  const label = document.createElement("div");
22069
- label.textContent = credits.label ? productLabel(credits.label, locale) : creditsPeriodLabel(credits.periodType, locale);
21982
+ label.textContent = productLabel(credits, locale);
22070
21983
  label.style.fontSize = "12.5px";
22071
21984
  label.style.fontWeight = "600";
22072
21985
  left.append(label);
@@ -22141,7 +22054,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
22141
22054
  popover.append(renderCreditsHeader(credits, locale, messages));
22142
22055
  const tiles = (credits.productUsage ?? []).map(
22143
22056
  (product) => renderCreditsTile(
22144
- productLabel(product.product, locale),
22057
+ productLabel(product, locale),
22145
22058
  product.usagePercent,
22146
22059
  locale,
22147
22060
  messages,
@@ -22309,7 +22222,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
22309
22222
  }
22310
22223
  const remaining = remainingPercent(accountCredits.usedPercent);
22311
22224
  const percent2 = formatRendererCreditsPercent(remaining);
22312
- const periodLabel = accountCredits.label ? productLabel(accountCredits.label, locale) : creditsPeriodLabel(accountCredits.periodType, locale);
22225
+ const periodLabel = accountCredits.label ? productLabel(accountCredits, locale) : creditsPeriodLabel(accountCredits.periodType, locale);
22313
22226
  const title = `${periodLabel} ${percent2}`;
22314
22227
  const tone = rendererCreditsTone(accountCredits.usedPercent);
22315
22228
  const ringSlot = control.trigger.querySelector("[data-codexhost-credits-ring]");
@@ -22898,14 +22811,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
22898
22811
  permissionModeVisible,
22899
22812
  locale
22900
22813
  );
22901
- const selectedCodexAccount = state.agent === "codex" && !ownershipError ? currentCodexAccount : void 0;
22902
22814
  if (control.usage) {
22903
- renderRendererUsageControl(
22904
- control.usage,
22905
- usage,
22906
- locale,
22907
- selectedCodexAccount?.email ?? selectedCodexAccount?.label ?? null
22908
- );
22815
+ renderRendererUsageControl(control.usage, usage, locale);
22909
22816
  }
22910
22817
  control.harnessCommands.setLocale(locale);
22911
22818
  control.harnessCommands.root.hidden = state.agent === "codex";
@@ -23045,62 +22952,141 @@ Codex Fast mode prioritizes requests and may increase usage.`
23045
22952
  }
23046
22953
  };
23047
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
+
23048
23026
  // src/renderer-codex-usage-gate.ts
23049
23027
  var EDITOR_SELECTOR2 = '[contenteditable="true"][role="textbox"]';
23050
23028
  var MAX_HOOKS = 4096;
23051
23029
  var MAX_DOM_DEPTH = 12;
23052
23030
  var RETRY_DELAY_MS = 1e3;
23053
- function isRecord2(value) {
23031
+ function isRecord3(value) {
23054
23032
  return typeof value === "object" && value !== null && !Array.isArray(value);
23055
23033
  }
23056
23034
  function hooksOf(fiber) {
23057
23035
  const result = [];
23058
- let hook = isRecord2(fiber) ? fiber.memoizedState : null;
23059
- while (isRecord2(hook) && result.length < MAX_HOOKS) {
23036
+ let hook = isRecord3(fiber) ? fiber.memoizedState : null;
23037
+ while (isRecord3(hook) && result.length < MAX_HOOKS) {
23060
23038
  result.push(hook);
23061
23039
  hook = hook.next;
23062
23040
  }
23063
23041
  return hook == null ? result : [];
23064
23042
  }
23065
- function submitOwners(composer) {
23043
+ function submitOwners(composer, projections) {
23066
23044
  let element = composer.querySelector(EDITOR_SELECTOR2) ?? composer;
23067
23045
  for (let depth = 0; element && depth < MAX_DOM_DEPTH; depth += 1) {
23068
23046
  const key = Object.getOwnPropertyNames(element).find(
23069
23047
  (name) => name.startsWith("__reactFiber$")
23070
23048
  );
23071
23049
  if (key) {
23072
- const owners = committedReactAncestors(
23050
+ const ancestors = committedReactAncestors(
23073
23051
  Object.getOwnPropertyDescriptor(element, key)?.value
23074
- ).filter(
23075
- ({ memoizedProps: props }) => isRecord2(props) && "onLocalSubmitStart" in props && typeof props.submitDisabled === "boolean"
23076
23052
  );
23077
- return owners.filter((owner) => {
23078
- 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);
23079
23061
  return !gates.invalid && gates.reserve.length > 0;
23080
23062
  });
23063
+ return valid.filter(
23064
+ (scope) => !valid.some((other) => other !== scope && scope.fibers.includes(other.owner))
23065
+ );
23081
23066
  }
23082
23067
  element = element.parentElement;
23083
23068
  }
23084
23069
  return [];
23085
23070
  }
23086
- function findSubmitOwner(composer) {
23087
- const owners = submitOwners(composer);
23088
- 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;
23089
23074
  }
23090
- function subscriptionAt(hook) {
23075
+ function subscriptionAt(hook, fiber) {
23091
23076
  const memo = hook.memoizedState;
23092
23077
  if (!Array.isArray(memo) || !Array.isArray(memo[1])) return null;
23093
23078
  const [subscriber, dependencies] = memo;
23094
23079
  if (dependencies.length !== 2) return null;
23095
23080
  const signal = dependencies[0];
23096
- 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";
23097
23082
  const [store, atom] = adapted ? [signal.store, signal.atom] : dependencies;
23098
23083
  const instance = hook.next?.queue;
23099
23084
  const effect = hook.next?.next?.memoizedState;
23100
- 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) {
23101
23086
  return null;
23102
23087
  }
23103
23088
  return {
23089
+ fiber,
23104
23090
  subscriber,
23105
23091
  store,
23106
23092
  atom,
@@ -23138,10 +23124,10 @@ Codex Fast mode prioritizes requests and may increase usage.`
23138
23124
  visiting.delete(dependency);
23139
23125
  }
23140
23126
  }
23141
- if (!isRecord2(value)) return value;
23127
+ if (!isRecord3(value)) return value;
23142
23128
  if (typeof value.hardBlocked === "boolean") return trace(value, "reserve");
23143
23129
  if ("authMethod" in value) return trace(value, "auth");
23144
- if (isRecord2(value.data) && isRecord2(value.data.rate_limit)) {
23130
+ if (isRecord3(value.data) && isRecord3(value.data.rate_limit)) {
23145
23131
  return {
23146
23132
  ...value,
23147
23133
  data: { ...value.data, rate_limit: trace(value.data.rate_limit, "limit") }
@@ -23157,12 +23143,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
23157
23143
  }
23158
23144
  const reserve = read.has("reserve.hardBlocked") && !read.has("reserve.active");
23159
23145
  const account = read.has("auth.authMethod") && read.has("limit.allowed");
23160
- if (account && (read.has("reserve.hardBlocked") || read.has("reserve.active"))) return "mixed";
23146
+ if (account && read.has("reserve.hardBlocked")) return "mixed";
23161
23147
  if (reserve) return "reserve";
23162
23148
  if (account) return "account";
23163
23149
  return null;
23164
23150
  }
23165
- function snapshotsMatch({ subscriber, instance, store, atom }, projected) {
23151
+ function snapshotsMatch({ subscriber, instance, store, atom }, projections) {
23152
+ const projected = projections?.get(instance);
23166
23153
  try {
23167
23154
  if (typeof subscriber.createRender === "function" && subscriber.createRender() != null) {
23168
23155
  return false;
@@ -23175,35 +23162,40 @@ Codex Fast mode prioritizes requests and may increase usage.`
23175
23162
  return false;
23176
23163
  }
23177
23164
  }
23178
- function gateSubscriptions(owner, projections) {
23165
+ function gateSubscriptions(scope, projections) {
23179
23166
  const found = {
23180
23167
  account: [],
23181
23168
  reserve: [],
23182
23169
  invalid: false
23183
23170
  };
23184
- for (const hook of hooksOf(owner)) {
23185
- const subscription = subscriptionAt(hook);
23186
- const kind = subscription && gateKind(subscription);
23187
- if (subscription && kind) {
23188
- if (kind !== "mixed" && snapshotsMatch(subscription, projections?.get(kind))) {
23189
- found[kind].push(subscription);
23190
- } 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
+ }
23191
23180
  }
23192
23181
  }
23193
23182
  return found;
23194
23183
  }
23195
- function discoverGates(owner, projections) {
23196
- const gates = gateSubscriptions(owner, projections);
23184
+ function discoverGates(scope, projections) {
23185
+ const gates = gateSubscriptions(scope, projections);
23197
23186
  if (gates.invalid) return null;
23198
- const found = /* @__PURE__ */ new Map();
23187
+ const found = [];
23199
23188
  for (const kind of ["account", "reserve"]) {
23200
- const subscriptions = gates[kind];
23201
- if (subscriptions.length > 1) return null;
23202
- 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
+ }
23203
23195
  }
23204
23196
  return found;
23205
23197
  }
23206
- function project2({ subscriber, store, atom, instance, subscribeEffect }) {
23198
+ function project2(kind, { fiber, subscriber, store, atom, instance, subscribeEffect }) {
23207
23199
  for (const [target, key] of [
23208
23200
  [store, "sub"],
23209
23201
  [subscriber, "getSnapshot"],
@@ -23234,6 +23226,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
23234
23226
  instance.getSnapshot = allowed;
23235
23227
  if (instance.value !== false) onChange();
23236
23228
  return {
23229
+ kind,
23230
+ fiber,
23237
23231
  subscriber,
23238
23232
  instance,
23239
23233
  restore() {
@@ -23243,13 +23237,11 @@ Codex Fast mode prioritizes requests and may increase usage.`
23243
23237
  }
23244
23238
  };
23245
23239
  }
23246
- function isBound(owner, projections) {
23247
- const alternate = isRecord2(owner.alternate) ? owner.alternate : null;
23248
- const bound = [...projections];
23249
- return [owner, alternate].some((fiber) => {
23250
- const hooks = hooksOf(fiber);
23251
- return bound.every(
23252
- ({ 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(
23253
23245
  (hook) => Array.isArray(hook.memoizedState) && hook.memoizedState[0] === subscriber && hook.next?.queue === instance
23254
23246
  )
23255
23247
  );
@@ -23260,7 +23252,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
23260
23252
  const projections = /* @__PURE__ */ new Map();
23261
23253
  let retryAt = 0;
23262
23254
  let allowed = false;
23255
+ const banner = createRendererCodexUsageBanner();
23263
23256
  const release = () => {
23257
+ banner.restore();
23264
23258
  const previous = [...projections.values()];
23265
23259
  owner = null;
23266
23260
  projections.clear();
@@ -23272,26 +23266,33 @@ Codex Fast mode prioritizes requests and may increase usage.`
23272
23266
  }
23273
23267
  };
23274
23268
  const bind = () => {
23275
- const current = owner ?? findSubmitOwner(composer);
23269
+ const current = findSubmitScope(composer, projections);
23276
23270
  const gates = current && discoverGates(current, projections);
23277
- 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
+ }
23278
23274
  owner = current;
23279
23275
  for (const [kind, gate] of gates) {
23280
- if (!projections.has(kind)) projections.set(kind, project2(gate));
23276
+ if (!projections.has(gate.instance)) projections.set(gate.instance, project2(kind, gate));
23281
23277
  }
23282
23278
  return "bypassed";
23283
23279
  };
23284
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 = () => {
23285
23287
  if (!allowed || !composer.isConnected) {
23286
23288
  release();
23287
23289
  retryAt = 0;
23288
23290
  return "native";
23289
23291
  }
23290
- if (owner && !isBound(owner, projections.values())) {
23292
+ if (owner && !isBound(projections.values())) {
23291
23293
  release();
23292
23294
  retryAt = 0;
23293
23295
  }
23294
- if (owner && projections.size === 2) return "bypassed";
23295
23296
  if (Date.now() < retryAt) return owner ? "bypassed" : "unsupported";
23296
23297
  retryAt = Date.now() + RETRY_DELAY_MS;
23297
23298
  try {
@@ -23416,13 +23417,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
23416
23417
  }
23417
23418
 
23418
23419
  // src/renderer-native-thread.ts
23419
- function isRecord3(value) {
23420
+ function isRecord4(value) {
23420
23421
  return typeof value === "object" && value !== null && !Array.isArray(value);
23421
23422
  }
23422
23423
  async function verifyNativeCodexThread(sendRequest, threadId) {
23423
23424
  const native = await sendRequest("thread/read", { threadId, includeTurns: false });
23424
- const thread = isRecord3(native) ? native.thread : null;
23425
- 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") {
23426
23427
  throw new Error("Native Thread response cannot establish Codex ownership");
23427
23428
  }
23428
23429
  }
@@ -23501,15 +23502,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
23501
23502
  var CODEX_ACCOUNT_LIST_METHOD = "codexhost/account/list";
23502
23503
  var CODEX_ACCOUNT_REFRESH_METHOD = "codexhost/account/refresh";
23503
23504
  var CODEX_ACCOUNT_CHANGED_METHOD = "codexhost/account/changed";
23504
- function isRecord4(value) {
23505
+ function isRecord5(value) {
23505
23506
  return typeof value === "object" && value !== null && !Array.isArray(value);
23506
23507
  }
23507
23508
  function notifiedThreadId(notification) {
23508
- if (!isRecord4(notification) || !THREAD_USAGE_REFRESH_METHODS.includes(notification.method)) {
23509
+ if (!isRecord5(notification) || !THREAD_USAGE_REFRESH_METHODS.includes(notification.method)) {
23509
23510
  return null;
23510
23511
  }
23511
23512
  const params = notification.params;
23512
- if (!isRecord4(params)) return null;
23513
+ if (!isRecord5(params)) return null;
23513
23514
  const parsed = hostThreadIdSchema.safeParse(params.threadId);
23514
23515
  return parsed.success ? parsed.data : null;
23515
23516
  }
@@ -23827,7 +23828,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23827
23828
  throw new Error("Renderer Account notification callback is unavailable");
23828
23829
  }
23829
23830
  return notifications.addNotificationCallback(CODEX_ACCOUNT_CHANGED_METHOD, (notification) => {
23830
- if (!isRecord4(notification) || notification.method !== CODEX_ACCOUNT_CHANGED_METHOD) return;
23831
+ if (!isRecord5(notification) || notification.method !== CODEX_ACCOUNT_CHANGED_METHOD) return;
23831
23832
  const state = codexAccountChangedSchema.safeParse(notification.params);
23832
23833
  if (state.success) listener(state.data);
23833
23834
  });
@@ -23836,16 +23837,16 @@ Codex Fast mode prioritizes requests and may increase usage.`
23836
23837
  }
23837
23838
 
23838
23839
  // src/renderer-external-queue.ts
23839
- function isRecord5(value) {
23840
+ function isRecord6(value) {
23840
23841
  return value !== null && typeof value === "object" && !Array.isArray(value);
23841
23842
  }
23842
23843
  function installRendererExternalQueue(target) {
23843
- if (!isRecord5(target) || typeof target.getTurnCoordinator !== "function" || typeof target.getConversation !== "function") {
23844
+ if (!isRecord6(target) || typeof target.getTurnCoordinator !== "function" || typeof target.getConversation !== "function") {
23844
23845
  return null;
23845
23846
  }
23846
23847
  const coordinator = target.getTurnCoordinator();
23847
- const queue = isRecord5(coordinator) ? coordinator.serverQueue : null;
23848
- 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;
23849
23850
  const descriptor = Object.getOwnPropertyDescriptor(queue, "isEnabled");
23850
23851
  if (!descriptor?.writable) return null;
23851
23852
  const original = queue.isEnabled;
@@ -23854,7 +23855,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23854
23855
  const threadId = args[0];
23855
23856
  if (typeof threadId === "string") {
23856
23857
  const conversation = getConversation.call(target, threadId);
23857
- 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
23858
23859
  // Desktop in both newly created and hydrated conversation metadata.
23859
23860
  conversation.modelProvider === "codexhost") {
23860
23861
  return false;
@@ -23870,19 +23871,19 @@ Codex Fast mode prioritizes requests and may increase usage.`
23870
23871
 
23871
23872
  // src/renderer-external-steering.ts
23872
23873
  var THREAD_OWNERSHIP_LIST_METHOD2 = "codexhost/thread/ownership/list";
23873
- function isRecord6(value) {
23874
+ function isRecord7(value) {
23874
23875
  return value !== null && typeof value === "object" && !Array.isArray(value);
23875
23876
  }
23876
23877
  function isManager(value) {
23877
- return isRecord6(value) && ["sendRequest", "steerTurn", "startTurn", "getTurnCoordinator"].every(
23878
+ return isRecord7(value) && ["sendRequest", "steerTurn", "startTurn", "getTurnCoordinator"].every(
23878
23879
  (key) => typeof value[key] === "function"
23879
23880
  );
23880
23881
  }
23881
23882
  function submissionHost(manager) {
23882
23883
  const coordinator = manager.getTurnCoordinator();
23883
- const options = isRecord6(coordinator) ? coordinator.options : null;
23884
- const host = isRecord6(options) ? options.submissionHost : null;
23885
- 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") {
23886
23887
  throw new Error("Desktop turn submission binding is unavailable");
23887
23888
  }
23888
23889
  return {
@@ -23924,20 +23925,20 @@ Codex Fast mode prioritizes requests and may increase usage.`
23924
23925
  var INTERRUPTED_QUEUE_REASON = "Interrupted before the steer was accepted.";
23925
23926
  async function preserveQueuedFollowUps(manager, threadId) {
23926
23927
  const coordinator = manager.getTurnCoordinator();
23927
- 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") {
23928
23929
  throw new Error("Desktop follow-up queue binding is unavailable");
23929
23930
  }
23930
23931
  await coordinator.loadMessages.call(coordinator, threadId);
23931
23932
  const messages = coordinator.readMessages.call(coordinator, threadId);
23932
23933
  if (!Array.isArray(messages)) throw new Error("Desktop follow-up queue is unavailable");
23933
23934
  const alreadyPaused = new Set(
23934
- 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)
23935
23936
  );
23936
23937
  return () => {
23937
23938
  coordinator.mutate.call(coordinator, threadId, (current) => {
23938
23939
  if (!Array.isArray(current)) return current;
23939
23940
  return current.map((message2) => {
23940
- 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)
23941
23942
  return message2;
23942
23943
  const resumed = { ...message2 };
23943
23944
  delete resumed.pausedReason;
@@ -23946,7 +23947,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23946
23947
  });
23947
23948
  };
23948
23949
  }
23949
- function installRendererExternalSteering(target, sendTurnStart) {
23950
+ function installRendererExternalSteering(target, sendTurnStart, prepareTurnInput) {
23950
23951
  if (!isManager(target)) return null;
23951
23952
  const manager = target;
23952
23953
  const originalSteer = manager.steerTurn;
@@ -23955,9 +23956,12 @@ Codex Fast mode prioritizes requests and may increase usage.`
23955
23956
  const pending = /* @__PURE__ */ new Map();
23956
23957
  let disposed = false;
23957
23958
  const send = function(method, params, options) {
23958
- const messageId = isRecord6(params) ? params.clientUserMessageId : null;
23959
- const route = typeof messageId === "string" && isRecord6(params) ? routes.get(`${params.threadId}\0${messageId}`) : void 0;
23960
- if (method !== "turn/start" || !isRecord6(params) || !route || route.threadId !== params.threadId) {
23959
+ if ((method === "turn/start" || method === "turn/steer") && prepareTurnInput) {
23960
+ params = prepareTurnInput(params);
23961
+ }
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) {
23961
23965
  if (method === "turn/start" && sendTurnStart) {
23962
23966
  return sendTurnStart(params, (input) => {
23963
23967
  if (disposed) throw new Error("External submission binding was disposed");
@@ -23977,12 +23981,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
23977
23981
  clientUserMessageId: messageId,
23978
23982
  input: params.input,
23979
23983
  additionalContext: params.additionalContext,
23980
- responsesapiClientMetadata: params.responsesapiClientMetadata
23984
+ responsesapiClientMetadata: params.responsesapiClientMetadata,
23985
+ ...params[THREAD_REFERENCE_SOURCE_HOST_PARAM] !== void 0 ? { [THREAD_REFERENCE_SOURCE_HOST_PARAM]: params[THREAD_REFERENCE_SOURCE_HOST_PARAM] } : {}
23981
23986
  },
23982
23987
  options
23983
23988
  )
23984
23989
  ).then((response) => {
23985
- if (!isRecord6(response) || typeof response.turnId !== "string" || !response.turnId) {
23990
+ if (!isRecord7(response) || typeof response.turnId !== "string" || !response.turnId) {
23986
23991
  throw new Error("External steering returned no replacement Turn identity");
23987
23992
  }
23988
23993
  return {
@@ -24013,7 +24018,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24013
24018
  ] = args;
24014
24019
  if (typeof threadId !== "string") return originalSteer.apply(manager, args);
24015
24020
  const role = manager.getStreamRole?.(threadId);
24016
- if (isRecord6(role) && role.role === "follower") return originalSteer.apply(manager, args);
24021
+ if (isRecord7(role) && role.role === "follower") return originalSteer.apply(manager, args);
24017
24022
  let host = null;
24018
24023
  let expectedTurnId;
24019
24024
  try {
@@ -24042,15 +24047,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
24042
24047
  if (owner === "codex") return originalSteer.apply(manager, args);
24043
24048
  if (!host) throw new Error("Desktop turn submission binding is unavailable");
24044
24049
  const currentRole = manager.getStreamRole?.(threadId);
24045
- if (isRecord6(currentRole) && currentRole.role === "follower")
24050
+ if (isRecord7(currentRole) && currentRole.role === "follower")
24046
24051
  return originalSteer.apply(manager, args);
24047
24052
  if (!Array.isArray(input) || input.length === 0 || input.some(
24048
- (item) => !isRecord6(item) || item.type !== "text" || typeof item.text !== "string"
24049
- ) || !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())) {
24050
24055
  throw new Error("External steering requires non-empty text input");
24051
24056
  }
24052
24057
  if (toolOutput != null) throw new Error("External steering cannot replace a tool response");
24053
- if (!isRecord6(restoreMessage) || !isRecord6(restoreMessage.context)) {
24058
+ if (!isRecord7(restoreMessage) || !isRecord7(restoreMessage.context)) {
24054
24059
  throw new Error("Desktop steering message context is unavailable");
24055
24060
  }
24056
24061
  const messageId = typeof clientUserMessageId === "string" && clientUserMessageId ? clientUserMessageId : typeof restoreMessage.id === "string" && restoreMessage.id ? restoreMessage.id : crypto.randomUUID();
@@ -24098,7 +24103,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24098
24103
  },
24099
24104
  onMessageAdded
24100
24105
  );
24101
- if (!isRecord6(response) || !isRecord6(response.turn) || typeof response.turn.id !== "string") {
24106
+ if (!isRecord7(response) || !isRecord7(response.turn) || typeof response.turn.id !== "string") {
24102
24107
  throw new Error("Desktop returned no replacement Turn identity");
24103
24108
  }
24104
24109
  try {
@@ -24129,7 +24134,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24129
24134
  }
24130
24135
 
24131
24136
  // src/renderer-remote-attachments.ts
24132
- function isRecord7(value) {
24137
+ function isRecord8(value) {
24133
24138
  return value !== null && typeof value === "object" && !Array.isArray(value);
24134
24139
  }
24135
24140
  var MAX_IMAGE_BYTES = 20 * 1024 * 1024;
@@ -24181,14 +24186,14 @@ Codex Fast mode prioritizes requests and may increase usage.`
24181
24186
  function createRemoteAttachmentSender(target, hostId2, isCurrent) {
24182
24187
  const prepared = /* @__PURE__ */ new WeakMap();
24183
24188
  return (params, send) => {
24184
- 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")
24185
24190
  return send(params);
24186
24191
  const images = params.input.filter(
24187
- (item) => isRecord7(item) && (item.type === "image" || item.type === "localImage")
24192
+ (item) => isRecord8(item) && (item.type === "image" || item.type === "localImage")
24188
24193
  );
24189
24194
  if (images.length === 0) return send(params);
24190
24195
  const conversation = target.getConversation.call(target, params.threadId);
24191
- if (!isRecord7(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
24196
+ if (!isRecord8(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
24192
24197
  return send(params);
24193
24198
  const assertCurrent = () => {
24194
24199
  if (!isCurrent()) throw new Error("Remote attachment connection is no longer available");
@@ -24201,7 +24206,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24201
24206
  const cached2 = prepared.get(params);
24202
24207
  if (cached2) return cached2.then(dispatch);
24203
24208
  const input = params.input;
24204
- 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");
24205
24210
  const existingPaths = nativeImagePaths(text);
24206
24211
  const prepare = async () => {
24207
24212
  if (existingPaths.length === images.length) return params;
@@ -24233,7 +24238,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24233
24238
  contents: file2.contents,
24234
24239
  label: `image-${index + 1}.${file2.extension}`
24235
24240
  });
24236
- if (!isRecord7(saved) || !filePath(saved.path) || saved.fsPath !== saved.path) {
24241
+ if (!isRecord8(saved) || !filePath(saved.path) || saved.fsPath !== saved.path) {
24237
24242
  throw new Error("Desktop returned an invalid remote attachment path");
24238
24243
  }
24239
24244
  created.push(saved.path);
@@ -24320,12 +24325,31 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24320
24325
  return Object.freeze({ ...client, inspectThread });
24321
24326
  }
24322
24327
 
24328
+ // src/renderer-thread-reference-context.ts
24329
+ var record4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24330
+ function createThreadReferenceContext(manager, hostId2, isCurrent) {
24331
+ const prepared = /* @__PURE__ */ new WeakMap();
24332
+ return (params) => {
24333
+ if (hostId2 === "local" || !record4(manager) || typeof manager.getConversation !== "function" || !record4(params) || typeof params.threadId !== "string")
24334
+ return params;
24335
+ const conversation = manager.getConversation.call(manager, params.threadId);
24336
+ if (!record4(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
24337
+ return params;
24338
+ if (!isCurrent()) throw new Error("Thread reference connection is no longer available");
24339
+ const cached2 = prepared.get(params);
24340
+ if (cached2) return cached2;
24341
+ const result = { ...params, [THREAD_REFERENCE_SOURCE_HOST_PARAM]: hostId2 };
24342
+ prepared.set(params, result);
24343
+ return result;
24344
+ };
24345
+ }
24346
+
24323
24347
  // src/renderer-manual-compaction.ts
24324
- function isRecord8(value) {
24348
+ function isRecord9(value) {
24325
24349
  return value !== null && typeof value === "object" && !Array.isArray(value);
24326
24350
  }
24327
24351
  function installRendererManualCompaction(target, hostId2, messages) {
24328
- 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") {
24329
24353
  return null;
24330
24354
  }
24331
24355
  const register = target.registerPendingManualContextCompaction;
@@ -24334,18 +24358,18 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24334
24358
  const listener = (event) => {
24335
24359
  if (event.source != null && event.source !== messages) return;
24336
24360
  const message2 = event.data;
24337
- 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) {
24338
24362
  return;
24339
24363
  }
24340
24364
  const params = threadManualCompactionStartedSchema.safeParse(message2.params);
24341
24365
  if (!params.success) return;
24342
24366
  const { threadId } = params.data;
24343
24367
  const conversation = getConversation.call(target, threadId);
24344
- if (!isRecord8(conversation) || conversation.id !== threadId || conversation.modelProvider !== "codexhost") {
24368
+ if (!isRecord9(conversation) || conversation.id !== threadId || conversation.modelProvider !== "codexhost") {
24345
24369
  return;
24346
24370
  }
24347
24371
  const role = getStreamRole?.call(target, threadId);
24348
- if (isRecord8(role) && role.role === "follower") return;
24372
+ if (isRecord9(role) && role.role === "follower") return;
24349
24373
  register.call(target, threadId);
24350
24374
  };
24351
24375
  messages.addEventListener("message", listener);
@@ -24427,6 +24451,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24427
24451
  target,
24428
24452
  route.hostId,
24429
24453
  () => !disposed && readRouting()?.forHost(route.hostId) === route
24454
+ ),
24455
+ createThreadReferenceContext(
24456
+ target,
24457
+ route.hostId,
24458
+ () => !disposed && readRouting()?.forHost(route.hostId) === route
24430
24459
  )
24431
24460
  ),
24432
24461
  () => installRendererManualCompaction(target, route.hostId, messages)
@@ -24555,7 +24584,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24555
24584
  var SIDEBAR_THREAD_HOST_ID_ATTRIBUTE = "data-app-action-sidebar-thread-host-id";
24556
24585
  var SIDEBAR_AGENT_ICON_ATTRIBUTE = "data-codexhost-sidebar-agent-icon";
24557
24586
  var OWNERSHIP_RETRY_DELAYS_MS = [100, 300, 800, 1500, 3e3];
24558
- function isRecord9(value) {
24587
+ function isRecord10(value) {
24559
24588
  return typeof value === "object" && value !== null && !Array.isArray(value);
24560
24589
  }
24561
24590
  function sidebarThreadAttributes(element) {
@@ -24582,19 +24611,19 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24582
24611
  const fiberName = fiberNames[0];
24583
24612
  if (fiberNames.length !== 1 || !fiberName) return null;
24584
24613
  const firstFiber2 = Object.getOwnPropertyDescriptor(element, fiberName)?.value;
24585
- if (!isRecord9(firstFiber2)) return null;
24614
+ if (!isRecord10(firstFiber2)) return null;
24586
24615
  const candidates = /* @__PURE__ */ new Set();
24587
24616
  let fiber = firstFiber2;
24588
24617
  for (let depth = 0; fiber && depth < 12; depth += 1) {
24589
24618
  const props = fiber.memoizedProps;
24590
- if (isRecord9(props) && isRecord9(props.dataAttributes)) {
24619
+ if (isRecord10(props) && isRecord10(props.dataAttributes)) {
24591
24620
  const dataAttributes = props.dataAttributes;
24592
24621
  const threadId = hostThreadIdSchema.safeParse(props.conversationId);
24593
24622
  if (threadId.success && dataAttributes[SIDEBAR_THREAD_ROW_ATTRIBUTE] === rowMarker && dataAttributes[SIDEBAR_THREAD_ID_ATTRIBUTE] === taskKey && dataAttributes[SIDEBAR_THREAD_HOST_ID_ATTRIBUTE] === hostId2) {
24594
24623
  candidates.add(threadId.data);
24595
24624
  }
24596
24625
  }
24597
- fiber = isRecord9(fiber.return) ? fiber.return : null;
24626
+ fiber = isRecord10(fiber.return) ? fiber.return : null;
24598
24627
  }
24599
24628
  return candidates.size === 1 ? candidates.values().next().value ?? null : null;
24600
24629
  }
@@ -25004,7 +25033,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25004
25033
  if (row) finish(row);
25005
25034
  });
25006
25035
  }
25007
- function isRecord10(value) {
25036
+ function isRecord11(value) {
25008
25037
  return typeof value === "object" && value !== null && !Array.isArray(value);
25009
25038
  }
25010
25039
  function firstFiber(element) {
@@ -25014,7 +25043,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25014
25043
  const name = names[0];
25015
25044
  if (names.length !== 1 || !name) return null;
25016
25045
  const value = Object.getOwnPropertyDescriptor(element, name)?.value;
25017
- return isRecord10(value) ? value : null;
25046
+ return isRecord11(value) ? value : null;
25018
25047
  }
25019
25048
  function directForkAncestors(first) {
25020
25049
  const ancestors = [];
@@ -25024,7 +25053,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25024
25053
  if (seen.has(fiber)) return [];
25025
25054
  seen.add(fiber);
25026
25055
  ancestors.push(fiber);
25027
- fiber = isRecord10(fiber.return) ? fiber.return : null;
25056
+ fiber = isRecord11(fiber.return) ? fiber.return : null;
25028
25057
  }
25029
25058
  return ancestors;
25030
25059
  }
@@ -25042,7 +25071,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25042
25071
  let hasForkCallback = false;
25043
25072
  for (const fiber of ancestors) {
25044
25073
  const props = fiber.memoizedProps;
25045
- if (!isRecord10(props)) continue;
25074
+ if (!isRecord11(props)) continue;
25046
25075
  if (!hasForkCallback && typeof props.onFork !== "function" && ownsOtherCallback(fiber, props)) {
25047
25076
  return null;
25048
25077
  }
@@ -25074,7 +25103,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25074
25103
  if (!threadId.success || !turnId.success) return null;
25075
25104
  const fiber = firstFiber(button2);
25076
25105
  const buttonProps = fiber?.memoizedProps;
25077
- if (!fiber || !isRecord10(buttonProps) || !Object.hasOwn(buttonProps, "aria-busy")) return null;
25106
+ if (!fiber || !isRecord11(buttonProps) || !Object.hasOwn(buttonProps, "aria-busy")) return null;
25078
25107
  return forkTargetFromAncestors(button2, threadId.data, turnId.data, directForkAncestors(fiber)) ?? forkTargetFromAncestors(button2, threadId.data, turnId.data, committedReactAncestors(fiber));
25079
25108
  }
25080
25109
  var BrowserRendererForkDom = class {
@@ -25164,7 +25193,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25164
25193
  }
25165
25194
  var DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS = 1e4;
25166
25195
  var DRAFT_PREWARM_POLICY_POLL_INTERVAL_MS = 25;
25167
- function isRecord11(value) {
25196
+ function isRecord12(value) {
25168
25197
  return typeof value === "object" && value !== null && !Array.isArray(value);
25169
25198
  }
25170
25199
  function decodeOpenCodeTransportModelId(value) {
@@ -25329,7 +25358,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25329
25358
  let fiber = findComposerFiber(composer);
25330
25359
  for (let depth = 0; fiber && depth < 120; depth += 1) {
25331
25360
  const props = fiber.memoizedProps;
25332
- if (isRecord11(props) && "conversationId" in props && props.conversationId != null) {
25361
+ if (isRecord12(props) && "conversationId" in props && props.conversationId != null) {
25333
25362
  const candidate = hostThreadIdSchema.safeParse(props.conversationId);
25334
25363
  if (!candidate.success || threadId !== void 0 && threadId !== candidate.data) {
25335
25364
  return null;
@@ -25342,12 +25371,12 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25342
25371
  return threadId;
25343
25372
  }
25344
25373
  function isLegacySevenSlotDraftWrapper(value) {
25345
- 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) {
25346
25375
  return false;
25347
25376
  }
25348
25377
  try {
25349
25378
  const draft = value[3].get();
25350
- return isRecord11(draft) && "modelSettings" in draft && "isManuallyChanged" in draft;
25379
+ return isRecord12(draft) && "modelSettings" in draft && "isManuallyChanged" in draft;
25351
25380
  } catch {
25352
25381
  return false;
25353
25382
  }
@@ -25381,8 +25410,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25381
25410
  let fiber = findComposerFiber(composer);
25382
25411
  for (let depth = 0; fiber && depth < 120; depth += 1) {
25383
25412
  const updateQueue = fiber.updateQueue;
25384
- const memoCache = isRecord11(updateQueue) ? updateQueue.memoCache : null;
25385
- 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 : [];
25386
25415
  for (const value of data) {
25387
25416
  const draftId = draftIdFromMemoValue(value);
25388
25417
  if (draftId) draftIds.add(draftId);
@@ -25410,7 +25439,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25410
25439
  return ["default", draftIds.values().next().value];
25411
25440
  }
25412
25441
  function isDraftPrewarmPolicyReady(value) {
25413
- 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";
25414
25443
  }
25415
25444
  async function waitForRendererDraftPrewarmPolicy(target, composer) {
25416
25445
  const deadline = Date.now() + DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS;
@@ -25676,11 +25705,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25676
25705
  return null;
25677
25706
  }
25678
25707
  }
25679
- function isRecord12(value) {
25708
+ function isRecord13(value) {
25680
25709
  return typeof value === "object" && value !== null && !Array.isArray(value);
25681
25710
  }
25682
25711
  function parseExternalConfiguration(value) {
25683
- if (!isRecord12(value)) return void 0;
25712
+ if (!isRecord13(value)) return void 0;
25684
25713
  const model2 = harnessModelRefSchema.safeParse(value.model);
25685
25714
  if (!model2.success) return void 0;
25686
25715
  const thinkingOptionId = harnessThinkingOptionIdSchema.safeParse(value.thinkingOptionId);
@@ -25697,10 +25726,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25697
25726
  const raw = storage.getItem(RENDERER_NEW_THREAD_PREFERENCE_KEY);
25698
25727
  if (!raw) return void 0;
25699
25728
  const parsed = JSON.parse(raw);
25700
- if (!isRecord12(parsed) || parsed.version !== 1) return void 0;
25729
+ if (!isRecord13(parsed) || parsed.version !== 1) return void 0;
25701
25730
  if (parsed.lastAgent !== "codex" && !harnessPluginIdSchema.safeParse(parsed.lastAgent).success)
25702
25731
  return void 0;
25703
- const externalByAgent = isRecord12(parsed.externalByAgent) ? parsed.externalByAgent : {};
25732
+ const externalByAgent = isRecord13(parsed.externalByAgent) ? parsed.externalByAgent : {};
25704
25733
  const parsedExternal = Object.fromEntries(
25705
25734
  Object.keys(externalByAgent).filter((agent) => harnessPluginIdSchema.safeParse(agent).success).flatMap((agent) => {
25706
25735
  const configuration = parseExternalConfiguration(externalByAgent[agent]);
@@ -25826,7 +25855,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25826
25855
  var GET_LOCALE_OVERRIDE_URL = "vscode://codex/get-setting";
25827
25856
  var GET_LOCALE_INFO_URL = "vscode://codex/locale-info";
25828
25857
  var DEFAULT_LOCALE_REQUEST_TIMEOUT_MS = 750;
25829
- function isRecord13(value) {
25858
+ function isRecord14(value) {
25830
25859
  return typeof value === "object" && value !== null && !Array.isArray(value);
25831
25860
  }
25832
25861
  function canonicalLocale(value) {
@@ -25848,7 +25877,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25848
25877
  return new DOMException("The operation was aborted", "AbortError");
25849
25878
  }
25850
25879
  function parseLocaleOverride(value) {
25851
- if (!isRecord13(value) || !("value" in value)) {
25880
+ if (!isRecord14(value) || !("value" in value)) {
25852
25881
  throw new Error("Codex locale override response is malformed");
25853
25882
  }
25854
25883
  if (value.value === null) return { value: null };
@@ -25863,7 +25892,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25863
25892
  return locale;
25864
25893
  }
25865
25894
  function parseLocaleInfo(value) {
25866
- 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");
25867
25896
  return {
25868
25897
  ideLocale: optionalLocale(value.ideLocale, "IDE locale"),
25869
25898
  systemLocale: optionalLocale(value.systemLocale, "system locale")
@@ -25892,7 +25921,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25892
25921
  const onAbort = () => settle(() => reject(abortError2()));
25893
25922
  const onMessage = (event) => {
25894
25923
  const message3 = event.data;
25895
- if (!isRecord13(message3) || message3.type !== "fetch-response") return;
25924
+ if (!isRecord14(message3) || message3.type !== "fetch-response") return;
25896
25925
  if (message3.requestId !== requestId) return;
25897
25926
  if (message3.responseType !== "success" || typeof message3.status !== "number" || message3.status < 200 || message3.status >= 300 || typeof message3.bodyJsonString !== "string") {
25898
25927
  settle(() => reject(new Error("Codex locale request failed")));
@@ -30983,10 +31012,10 @@ ${detail}` : ""}`
30983
31012
  let previousWasTranslation = false;
30984
31013
  paragraphLines.forEach((line, lineIndex) => {
30985
31014
  if (lineIndex > 0 && !primaryIsCjk && CJK_PATTERN.test(line)) {
30986
- const translation = document2.createElement("span");
30987
- translation.className = "release-note-translation";
30988
- appendInline(document2, translation, line);
30989
- paragraph.append(translation);
31015
+ const translation2 = document2.createElement("span");
31016
+ translation2.className = "release-note-translation";
31017
+ appendInline(document2, translation2, line);
31018
+ paragraph.append(translation2);
30990
31019
  previousWasTranslation = true;
30991
31020
  return;
30992
31021
  }
@@ -31074,7 +31103,7 @@ ${detail}` : ""}`
31074
31103
  }
31075
31104
  function defaultImportName(source, existing) {
31076
31105
  const base = source.provider === "openai-codex" ? "codex" : "grok";
31077
- const used = new Set(existing.map((record4) => record4.name));
31106
+ const used = new Set(existing.map((record5) => record5.name));
31078
31107
  const valid = (name) => credentialImportNameSchema.safeParse(name).success;
31079
31108
  if (!used.has(base)) return base;
31080
31109
  const local = source.label.includes("@") ? source.label.split("@")[0] ?? "" : "";
@@ -31097,7 +31126,7 @@ ${detail}` : ""}`
31097
31126
  const shown = (text) => accountDisplayText(text, hideEmails);
31098
31127
  const targetButtons = /* @__PURE__ */ new Map();
31099
31128
  const importedRecords = () => snapshot.targets.find((target) => target.harnessId === TARGET_HARNESS_ID)?.imports ?? [];
31100
- const sourceOf = (record4) => snapshot.sources.find((source) => source.id === record4.source.id);
31129
+ const sourceOf = (record5) => snapshot.sources.find((source) => source.id === record5.source.id);
31101
31130
  const piTarget = () => snapshot.targets.find((candidate) => candidate.harnessId === TARGET_HARNESS_ID);
31102
31131
  const compatibleSources = () => {
31103
31132
  const target = piTarget();
@@ -31135,7 +31164,7 @@ ${detail}` : ""}`
31135
31164
  sectionImport.addEventListener("click", () => {
31136
31165
  const sources = compatibleSources();
31137
31166
  const free = sources.find(
31138
- (source2) => !importedRecords().some((record4) => record4.source.id === source2.id)
31167
+ (source2) => !importedRecords().some((record5) => record5.source.id === source2.id)
31139
31168
  );
31140
31169
  const source = free ?? sources[0];
31141
31170
  if (source) openDialog("add", { source, choose: true }, SECTION_IMPORT_KEY);
@@ -31185,30 +31214,30 @@ ${detail}` : ""}`
31185
31214
  mark.append(createRendererAgentIcon(agent ?? "pi", 26, document2, pluginFor(agent ?? "pi")));
31186
31215
  return mark;
31187
31216
  };
31188
- const renderRow = (record4) => {
31217
+ const renderRow = (record5) => {
31189
31218
  const row = document2.createElement("div");
31190
31219
  row.className = "settings-pi-accounts__row";
31191
31220
  row.tabIndex = -1;
31192
- row.dataset.importName = record4.name;
31193
- row.setAttribute("aria-label", shown(record4.source.label));
31194
- const agent = record4.source.harnessId;
31221
+ row.dataset.importName = record5.name;
31222
+ row.setAttribute("aria-label", shown(record5.source.label));
31223
+ const agent = record5.source.harnessId;
31195
31224
  const mark = createMark(agent);
31196
31225
  const identity = document2.createElement("div");
31197
31226
  identity.className = "settings-pi-accounts__identity";
31198
31227
  const label = document2.createElement("strong");
31199
31228
  label.className = "settings-account-email";
31200
- label.textContent = shown(record4.source.label);
31229
+ label.textContent = shown(record5.source.label);
31201
31230
  label.title = label.textContent;
31202
31231
  label.translate = false;
31203
31232
  const meta3 = document2.createElement("div");
31204
31233
  meta3.className = "settings-account-metadata";
31205
- const source = sourceOf(record4);
31234
+ const source = sourceOf(record5);
31206
31235
  const parts = [
31207
31236
  metaPart(rendererAgentLabel(agent, pluginFor(agent)), "settings-pi-accounts__agent"),
31208
- metaPart(`${record4.name}/\u2026`, void 0, true),
31237
+ metaPart(`${record5.name}/\u2026`, void 0, true),
31209
31238
  metaPart(messages.copied)
31210
31239
  ];
31211
- const time3 = formatImportedAt(record4.importedAt);
31240
+ const time3 = formatImportedAt(record5.importedAt);
31212
31241
  if (time3) parts.push(metaPart(time3));
31213
31242
  parts.forEach((part, index) => {
31214
31243
  if (index > 0) {
@@ -31225,23 +31254,23 @@ ${detail}` : ""}`
31225
31254
  reimport.type = "button";
31226
31255
  reimport.className = "settings-account-action";
31227
31256
  reimport.textContent = messages.rowReimport;
31228
- reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record4.source.label)}`);
31257
+ reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record5.source.label)}`);
31229
31258
  reimport.disabled = busy || !source;
31230
31259
  reimport.title = messages.reimport;
31231
31260
  reimport.addEventListener("click", () => {
31232
- if (source) openDialog("reimport", { source, record: record4 }, `row:${record4.name}`);
31261
+ if (source) openDialog("reimport", { source, record: record5 }, `row:${record5.name}`);
31233
31262
  });
31234
31263
  const remove = document2.createElement("button");
31235
31264
  remove.type = "button";
31236
31265
  remove.className = "settings-account-action settings-pi-accounts__remove";
31237
31266
  remove.textContent = messages.rowRemove;
31238
- remove.setAttribute("aria-label", `${messages.remove}: ${shown(record4.source.label)}`);
31267
+ remove.setAttribute("aria-label", `${messages.remove}: ${shown(record5.source.label)}`);
31239
31268
  remove.disabled = busy;
31240
- remove.addEventListener("click", () => openDialog("remove", { record: record4 }, `row:${record4.name}`));
31269
+ remove.addEventListener("click", () => openDialog("remove", { record: record5 }, `row:${record5.name}`));
31241
31270
  if (source) actions.append(reimport);
31242
31271
  actions.append(remove);
31243
31272
  row.append(mark, identity, actions);
31244
- rows.set(record4.name, row);
31273
+ rows.set(record5.name, row);
31245
31274
  return row;
31246
31275
  };
31247
31276
  const loginTypeLabel = (type) => type === "oauth" ? messages.typeOauth : type === "api_key" ? messages.typeApiKey : messages.typeOther;
@@ -31394,7 +31423,7 @@ ${detail}` : ""}`
31394
31423
  const label = document2.createElement("strong");
31395
31424
  label.textContent = shown(choice.label);
31396
31425
  label.translate = false;
31397
- const existing = importedRecords().find((record4) => record4.source.id === choice.id);
31426
+ const existing = importedRecords().find((record5) => record5.source.id === choice.id);
31398
31427
  const agent = choice.harnessId;
31399
31428
  const detail = document2.createElement("span");
31400
31429
  detail.textContent = [
@@ -31435,7 +31464,7 @@ ${detail}` : ""}`
31435
31464
  const name = request.action === "list" ? void 0 : request.name;
31436
31465
  state = {
31437
31466
  source: state.source,
31438
- record: importedRecords().find((record4) => record4.name === name) ?? state.record
31467
+ record: importedRecords().find((record5) => record5.name === name) ?? state.record
31439
31468
  };
31440
31469
  show(next);
31441
31470
  } else {
@@ -31449,12 +31478,12 @@ ${detail}` : ""}`
31449
31478
  sourceRadios = [];
31450
31479
  body.replaceChildren();
31451
31480
  controls.replaceChildren();
31452
- const { source, record: record4 } = state;
31481
+ const { source, record: record5 } = state;
31453
31482
  const close = () => modal.close();
31454
31483
  if (mode === "add" || mode === "reimport") {
31455
31484
  title.textContent = mode === "add" ? messages.add : messages.reimport;
31456
31485
  modal.setAttribute("aria-label", title.textContent);
31457
- const active = source ?? record4?.source;
31486
+ const active = source ?? record5?.source;
31458
31487
  const choices = mode === "add" && state.choose ? compatibleSources() : [];
31459
31488
  if (choices.length > 1) body.append(sourcePicker(choices));
31460
31489
  else if (active) body.append(line(messages.source, shown(active.label)));
@@ -31463,8 +31492,8 @@ ${detail}` : ""}`
31463
31492
  input.maxLength = 48;
31464
31493
  input.autocomplete = "off";
31465
31494
  input.spellcheck = false;
31466
- input.value = record4?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
31467
- input.readOnly = Boolean(record4);
31495
+ input.value = record5?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
31496
+ input.readOnly = Boolean(record5);
31468
31497
  input.addEventListener("input", () => {
31469
31498
  nameEdited = true;
31470
31499
  });
@@ -31498,7 +31527,7 @@ ${detail}` : ""}`
31498
31527
  {
31499
31528
  action: mode === "reimport" ? "reimport" : "import",
31500
31529
  sourceId: source2.id,
31501
- name: record4?.name ?? input.value,
31530
+ name: record5?.name ?? input.value,
31502
31531
  confirmed: true
31503
31532
  },
31504
31533
  "done"
@@ -31508,16 +31537,16 @@ ${detail}` : ""}`
31508
31537
  )
31509
31538
  );
31510
31539
  (mode === "add" ? input : controls.children[0]).focus();
31511
- } else if (mode === "remove" && record4) {
31540
+ } else if (mode === "remove" && record5) {
31512
31541
  title.textContent = messages.remove;
31513
31542
  modal.setAttribute("aria-label", title.textContent);
31514
- body.append(note(messages.removeWarning.replace("{name}", record4.name)));
31543
+ body.append(note(messages.removeWarning.replace("{name}", record5.name)));
31515
31544
  const cancel = command(messages.cancel, close);
31516
31545
  controls.append(
31517
31546
  cancel,
31518
31547
  command(
31519
31548
  messages.remove,
31520
- () => submit({ action: "remove", name: record4.name, confirmed: true }, null),
31549
+ () => submit({ action: "remove", name: record5.name, confirmed: true }, null),
31521
31550
  "danger"
31522
31551
  )
31523
31552
  );
@@ -31525,7 +31554,7 @@ ${detail}` : ""}`
31525
31554
  } else {
31526
31555
  title.textContent = messages.doneTitle;
31527
31556
  modal.setAttribute("aria-label", title.textContent);
31528
- const name = record4?.name;
31557
+ const name = record5?.name;
31529
31558
  if (name) body.append(line(messages.entry, `${name}/\u2026`, true));
31530
31559
  body.append(note(messages.done));
31531
31560
  const done = command(messages.close, close, "primary");
@@ -31572,21 +31601,21 @@ ${detail}` : ""}`
31572
31601
  (candidate) => candidate.harnessId === TARGET_HARNESS_ID && source && candidate.providers.includes(source.provider)
31573
31602
  );
31574
31603
  if (!source || !target) return null;
31575
- const record4 = target.imports.find((candidate) => candidate.source.id === source.id);
31604
+ const record5 = target.imports.find((candidate) => candidate.source.id === source.id);
31576
31605
  const key = `${harnessId}:${accountLabel}:import`;
31577
31606
  const button2 = document2.createElement("button");
31578
31607
  button2.type = "button";
31579
31608
  button2.className = "settings-account-pi-import";
31580
31609
  button2.dataset.accountFocus = key;
31581
31610
  button2.disabled = busy;
31582
- const hint = record4 ? messages.importedHint.replace("{name}", record4.name) : messages.add;
31611
+ const hint = record5 ? messages.importedHint.replace("{name}", record5.name) : messages.add;
31583
31612
  button2.title = hint;
31584
31613
  button2.setAttribute("aria-label", hint);
31585
31614
  button2.append(createRendererAgentIcon("pi", 12, document2, pluginFor("pi")));
31586
- if (record4) {
31615
+ if (record5) {
31587
31616
  button2.dataset.state = "imported";
31588
31617
  const name = document2.createElement("code");
31589
- name.textContent = `${record4.name}/\u2026`;
31618
+ name.textContent = `${record5.name}/\u2026`;
31590
31619
  name.translate = false;
31591
31620
  button2.append(name, createRendererSettingsIcon("check", 12));
31592
31621
  } else {
@@ -31594,7 +31623,7 @@ ${detail}` : ""}`
31594
31623
  button2.append(messages.add);
31595
31624
  }
31596
31625
  button2.addEventListener("click", () => {
31597
- if (!record4) {
31626
+ if (!record5) {
31598
31627
  openDialog("add", { source }, key);
31599
31628
  return;
31600
31629
  }
@@ -31603,7 +31632,7 @@ ${detail}` : ""}`
31603
31632
  renderSection();
31604
31633
  sectionToggle.setAttribute("aria-expanded", "true");
31605
31634
  }
31606
- const row = rows.get(record4.name);
31635
+ const row = rows.get(record5.name);
31607
31636
  row?.scrollIntoView({ block: "nearest", behavior: "smooth" });
31608
31637
  row?.focus();
31609
31638
  });
@@ -31716,17 +31745,6 @@ ${detail}` : ""}`
31716
31745
  if (periodType === "seven_day") return messages.accountCreditsPeriodSevenDay;
31717
31746
  return messages.accountCreditsPeriodUnknown;
31718
31747
  }
31719
- function creditsProductLabel(product, messages) {
31720
- if (product === "GrokBuild" || product === "Build") return messages.accountCreditsBuild;
31721
- if (product === "5-hour window") return messages.accountCreditsPeriodFiveHour;
31722
- if (product === "7-day window") return messages.accountCreditsPeriodSevenDay;
31723
- if (product.endsWith(" \xB7 monthly"))
31724
- return `${product.slice(0, -" \xB7 monthly".length)} \xB7 ${messages.accountCreditsPeriodMonthly}`;
31725
- if (product === "GrokChat") return "Chat";
31726
- if (product === "GrokImagine") return "Imagine";
31727
- if (product === "GrokVoice") return "Voice";
31728
- return product;
31729
- }
31730
31748
  function formatAccountCreditsReset(value, locale, now = /* @__PURE__ */ new Date()) {
31731
31749
  if (locale !== "zh-CN") return formatRendererCreditsReset(value, now);
31732
31750
  const date5 = new Date(value);
@@ -31753,36 +31771,22 @@ ${detail}` : ""}`
31753
31771
  if (periodType === "weekly" || periodType === "seven_day") return "seven_day";
31754
31772
  return null;
31755
31773
  }
31756
- function scopedUsageProduct(product) {
31757
- const suffixes = [
31758
- [" \xB7 5-hour window", "five_hour"],
31759
- [" \xB7 Weekly window", "seven_day"],
31760
- [" \xB7 7-day window", "seven_day"],
31761
- [" \xB7 5-hour", "five_hour"],
31762
- [" \xB7 7-day", "seven_day"]
31763
- ];
31764
- for (const [suffix, period] of suffixes) {
31765
- if (!product.endsWith(suffix)) continue;
31766
- const scope = product.slice(0, -suffix.length).trim();
31767
- if (scope) return { scope, period };
31768
- }
31769
- return null;
31770
- }
31771
31774
  function splitUsageWindows(credits, messages, filter) {
31772
31775
  const generic = { columns: {} };
31773
31776
  const scopedRows = /* @__PURE__ */ new Map();
31774
31777
  const additional = [];
31775
31778
  const addScoped = (scope, period, window2) => {
31776
- const rows2 = scopedRows.get(scope) ?? [];
31779
+ const scopeLabel = localizeHarnessPresentation(scope, messages.locale).label;
31780
+ const rows2 = scopedRows.get(scope.id) ?? [];
31777
31781
  let row = rows2.find((candidate) => !candidate.columns[period]);
31778
31782
  if (!row) {
31779
- row = { scope, columns: {} };
31783
+ row = { scope: scopeLabel, columns: {} };
31780
31784
  rows2.push(row);
31781
- scopedRows.set(scope, rows2);
31785
+ scopedRows.set(scope.id, rows2);
31782
31786
  }
31783
31787
  row.columns[period] = {
31784
31788
  ...window2,
31785
- label: `${scope} \xB7 ${creditsPeriodLabel2(period, messages)}`,
31789
+ label: window2.label,
31786
31790
  scoped: true
31787
31791
  };
31788
31792
  };
@@ -31792,29 +31796,30 @@ ${detail}` : ""}`
31792
31796
  else additional.push(window2);
31793
31797
  };
31794
31798
  const primary = {
31795
- 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
+ ),
31796
31804
  usedPercent: credits.usedPercent,
31797
31805
  amount: credits,
31798
31806
  resetsAt: credits.resetsAt,
31799
- scoped: Boolean(credits.label && scopedUsageProduct(credits.label))
31807
+ scoped: Boolean(credits.scope)
31800
31808
  };
31801
- const primaryScope = credits.label ? scopedUsageProduct(credits.label) : null;
31802
- addWindow(
31803
- primary,
31804
- primaryScope?.period ?? (credits.label ? null : comparisonPeriod(credits.periodType)),
31805
- primaryScope?.scope
31806
- );
31809
+ addWindow(primary, comparisonPeriod(credits.periodType), credits.scope);
31807
31810
  for (const product of credits.productUsage ?? []) {
31808
- const scoped = scopedUsageProduct(product.product);
31809
31811
  const window2 = {
31810
- label: creditsProductLabel(product.product, messages),
31812
+ label: accountCreditsWindowLabel(
31813
+ product,
31814
+ messages.locale,
31815
+ (period) => creditsPeriodLabel2(period, messages)
31816
+ ),
31811
31817
  usedPercent: product.usagePercent,
31812
31818
  amount: product,
31813
31819
  resetsAt: product.resetsAt,
31814
- scoped: Boolean(scoped)
31820
+ scoped: Boolean(product.scope)
31815
31821
  };
31816
- const genericPeriod = product.product === "5-hour window" ? "five_hour" : product.product === "7-day window" ? "seven_day" : null;
31817
- addWindow(window2, scoped?.period ?? genericPeriod, scoped?.scope);
31822
+ addWindow(window2, comparisonPeriod(product.periodType ?? "unknown"), product.scope);
31818
31823
  }
31819
31824
  const structured = [...scopedRows.values()].flat();
31820
31825
  let rows = Object.keys(generic.columns).length > 0 ? [generic, ...structured] : structured;
@@ -32206,8 +32211,7 @@ ${detail}` : ""}`
32206
32211
  { status: "ready", credits: account.credits, freshness: "live", observedAt: null },
32207
32212
  messages,
32208
32213
  display,
32209
- () => void 0,
32210
- account.harnessId === "grok" ? "weekly-only" : "all"
32214
+ () => void 0
32211
32215
  ) : renderAccountBalance(document2, messages, account.balance);
32212
32216
  personCell.title = messages.accountNativeManagementHint.replace("{harness}", account.harnessName);
32213
32217
  appendAccountExtras(personCell, [importAction]);
@@ -39118,12 +39122,8 @@ ${usage_default}`;
39118
39122
  const index = Math.max(0, Math.min(Math.trunc(attempt), rendererUsageRefreshDelays.length - 1));
39119
39123
  return rendererUsageRefreshDelays[index] ?? rendererUsageRefreshDelays[0];
39120
39124
  }
39121
- function externalAgentHasAccountCredits(agent) {
39122
- return agent === "codex" || agent === "grok" || agent === "claude-code";
39123
- }
39124
- function shouldRetryExternalThreadUsage(agent, usage, accountCredits = null) {
39125
- if (usage === null) return true;
39126
- return externalAgentHasAccountCredits(agent) && accountCredits === null;
39125
+ function shouldRetryExternalThreadUsage(accountCreditsSupported, usage, accountCredits = null) {
39126
+ return usage === null || accountCreditsSupported && accountCredits === null;
39127
39127
  }
39128
39128
  function shouldReloadExternalCatalogAfterAvailabilityRefresh(previous, next, configurationReady, explicitRefresh = false) {
39129
39129
  const initialDiscoveryReady = previous === "checking" && next === "ready";
@@ -39708,6 +39708,8 @@ ${usage_default}`;
39708
39708
  mounted.usageRequestGeneration += 1;
39709
39709
  mounted.usage = update.usage;
39710
39710
  mounted.accountCredits = update.accountCredits ?? null;
39711
+ if (update.accountCreditsSupported !== void 0)
39712
+ mounted.accountCreditsSupported = update.accountCreditsSupported;
39711
39713
  usageRefreshAttempts.delete(mounted.composer);
39712
39714
  renderMounted(mounted);
39713
39715
  }
@@ -39762,13 +39764,13 @@ ${usage_default}`;
39762
39764
  }
39763
39765
  mounted.usage = result.usage;
39764
39766
  mounted.accountCredits = result.accountCredits ?? null;
39765
- const agent = controller.get(mounted.composer).agent;
39766
- if (result.usage !== null && (!externalAgentHasAccountCredits(agent) || result.accountCredits)) {
39767
+ mounted.accountCreditsSupported = result.accountCreditsSupported ?? false;
39768
+ if (result.usage !== null && (!mounted.accountCreditsSupported || result.accountCredits)) {
39767
39769
  usageRefreshAttempts.delete(mounted.composer);
39768
39770
  }
39769
39771
  renderMounted(mounted);
39770
39772
  if (shouldRetryExternalThreadUsage(
39771
- controller.get(mounted.composer).agent,
39773
+ mounted.accountCreditsSupported,
39772
39774
  result.usage,
39773
39775
  result.accountCredits ?? null
39774
39776
  )) {
@@ -39777,7 +39779,7 @@ ${usage_default}`;
39777
39779
  } catch (error51) {
39778
39780
  if (mountedByComposer.get(mounted.composer) === mounted && mounted.usageRequestGeneration === generation) {
39779
39781
  renderMounted(mounted);
39780
- if (!(error51 instanceof RendererMethodUnavailableError) && shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null, null)) {
39782
+ if (!(error51 instanceof RendererMethodUnavailableError) && shouldRetryExternalThreadUsage(mounted.accountCreditsSupported, null, null)) {
39781
39783
  scheduleThreadUsageRefresh(mounted);
39782
39784
  }
39783
39785
  }
@@ -39885,14 +39887,7 @@ ${usage_default}`;
39885
39887
  renderMounted(mounted);
39886
39888
  if (mounted.ownershipStatus !== "error") void refreshCommands(mounted);
39887
39889
  sidebarAgentIcons.refresh();
39888
- if (mounted.ownershipStatus !== "error") {
39889
- const agent = controller.get(mounted.composer).agent;
39890
- if (agent === "codex") {
39891
- void refreshThreadUsage(mounted);
39892
- } else if (shouldRetryExternalThreadUsage(agent, mounted.usage, mounted.accountCredits)) {
39893
- scheduleThreadUsageRefresh(mounted);
39894
- }
39895
- }
39890
+ if (mounted.ownershipStatus !== "error") void refreshThreadUsage(mounted);
39896
39891
  } else if (isRetainedComposer(mounted) && controller.isCurrentOwnershipRequest(mounted.composer, generation) && orbitComposerKind(mounted.composer) === "unknown") {
39897
39892
  ownershipRecovery.set(mounted, generation);
39898
39893
  scheduleScan();
@@ -39922,7 +39917,7 @@ ${usage_default}`;
39922
39917
  if (resolution === "transfer") {
39923
39918
  mounted.ownershipStatus = "ready";
39924
39919
  renderMounted(mounted);
39925
- if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null, null)) {
39920
+ if (shouldRetryExternalThreadUsage(mounted.accountCreditsSupported, null, null)) {
39926
39921
  scheduleThreadUsageRefresh(mounted);
39927
39922
  }
39928
39923
  } else {
@@ -41013,6 +41008,7 @@ ${usage_default}`;
41013
41008
  threadConfiguration: inherited?.threadConfiguration,
41014
41009
  usage: inherited?.usage ?? null,
41015
41010
  accountCredits: inherited?.accountCredits ?? null,
41011
+ accountCreditsSupported: inherited?.accountCreditsSupported ?? false,
41016
41012
  hostId: inherited?.hostId ?? hostId2,
41017
41013
  usageRequestGeneration: 0,
41018
41014
  commandRequestGeneration: 0
@@ -41025,7 +41021,11 @@ ${usage_default}`;
41025
41021
  sidebarAgentIcons.refresh();
41026
41022
  if (threadIdFromComposerModelTarget(modelTarget) && !inherited) {
41027
41023
  void loadThreadOwnership(mounted);
41028
- } 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
+ )) {
41029
41029
  scheduleThreadUsageRefresh(mounted);
41030
41030
  } else if (state.agent !== "codex" && !isExternalConfigurationStable(mounted.modelView, mounted.permissionModeView)) {
41031
41031
  void loadExternalCatalog(mounted);