@codexhost/cli-darwin-arm64 0.2.0 → 0.2.2

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.
@@ -14950,12 +14950,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14950
14950
  });
14951
14951
  }
14952
14952
  });
14953
+ var usagePercentSchema = external_exports.number().finite().min(0).max(100);
14954
+ var accountCreditsProductUsageSchema = external_exports.object({
14955
+ product: external_exports.string().min(1),
14956
+ usagePercent: usagePercentSchema
14957
+ }).strict();
14958
+ var accountCreditsSnapshotSchema = external_exports.object({
14959
+ usedPercent: usagePercentSchema,
14960
+ resetsAt: external_exports.string().min(1).optional(),
14961
+ periodType: external_exports.enum(["weekly", "monthly", "unknown"]),
14962
+ productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional()
14963
+ }).strict();
14953
14964
  var threadUsageInspectionParamsSchema = external_exports.object({
14954
14965
  threadId: hostThreadIdSchema
14955
14966
  }).strict();
14956
14967
  var threadUsageInspectionSchema = external_exports.object({
14957
14968
  threadId: hostThreadIdSchema,
14958
- usage: threadUsageSnapshotSchema.nullable()
14969
+ usage: threadUsageSnapshotSchema.nullable(),
14970
+ accountCredits: accountCreditsSnapshotSchema.optional()
14959
14971
  }).strict();
14960
14972
 
14961
14973
  // ../shared-contracts/dist/harness-models.js
@@ -16414,6 +16426,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16414
16426
  if (absolute < 1e3) return `${sign}${Math.round(absolute)}`;
16415
16427
  return `${sign}${decimal(absolute / 1e3, 1)}k`;
16416
16428
  }
16429
+ function formatRendererCreditsPercent(value) {
16430
+ return `${decimal(value, 1)}%`;
16431
+ }
16432
+ function rendererUsageTriggerMaxWidth() {
16433
+ return "min(180px, 30vw)";
16434
+ }
16417
16435
  function addDetailRow(parent, label, value) {
16418
16436
  const row = document.createElement("div");
16419
16437
  row.style.display = "grid";
@@ -16437,7 +16455,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16437
16455
  heading.style.fontWeight = "600";
16438
16456
  heading.style.marginBottom = "6px";
16439
16457
  popover.append(heading);
16440
- if (usage.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0) {
16458
+ if (usage?.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0) {
16441
16459
  const contextPercent = usage.contextWindowTokens > 0 ? usage.contextUsedTokens / usage.contextWindowTokens * 100 : null;
16442
16460
  addDetailRow(
16443
16461
  popover,
@@ -16445,33 +16463,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16445
16463
  contextPercent === null ? `/${formatRendererTokenCount(usage.contextWindowTokens)}` : `${decimal(contextPercent, 1)}% / ${formatRendererTokenCount(usage.contextWindowTokens)}`
16446
16464
  );
16447
16465
  }
16448
- if (usage.cacheHitRatePercent !== void 0) {
16466
+ if (usage?.cacheHitRatePercent !== void 0) {
16449
16467
  addDetailRow(
16450
16468
  popover,
16451
16469
  "Latest cache hit",
16452
16470
  formatRendererCacheHitRate(usage.cacheHitRatePercent)
16453
16471
  );
16454
16472
  }
16455
- if (usage.outputTokensPerSecond !== void 0) {
16473
+ if (usage?.outputTokensPerSecond !== void 0) {
16456
16474
  addDetailRow(popover, "Output speed", formatRendererTokenRate(usage.outputTokensPerSecond));
16457
16475
  }
16458
- if (usage.cachedInputTokens !== void 0) {
16476
+ if (usage?.cachedInputTokens !== void 0) {
16459
16477
  addDetailRow(popover, "Cache read", formatRendererTokenCount(usage.cachedInputTokens));
16460
16478
  }
16461
- if (usage.cacheWriteInputTokens !== void 0) {
16479
+ if (usage?.cacheWriteInputTokens !== void 0) {
16462
16480
  addDetailRow(popover, "Cache write", formatRendererTokenCount(usage.cacheWriteInputTokens));
16463
16481
  }
16464
- if (usage.reasoningOutputTokens !== void 0) {
16482
+ if (usage?.reasoningOutputTokens !== void 0) {
16465
16483
  addDetailRow(popover, "Reasoning", formatRendererTokenCount(usage.reasoningOutputTokens));
16466
16484
  }
16467
- if (usage.inputTokens !== void 0 || usage.outputTokens !== void 0) {
16485
+ if (usage?.inputTokens !== void 0 || usage?.outputTokens !== void 0) {
16468
16486
  addDetailRow(
16469
16487
  popover,
16470
16488
  "Input / output",
16471
16489
  `${formatRendererTokenCount(usage.inputTokens ?? 0)} / ${formatRendererTokenCount(usage.outputTokens ?? 0)}`
16472
16490
  );
16473
16491
  }
16474
- if (usage.totalCostUsd !== void 0) {
16492
+ if (usage?.totalCostUsd !== void 0) {
16475
16493
  addDetailRow(popover, "Session cost estimate", formatRendererCost(usage.totalCostUsd));
16476
16494
  }
16477
16495
  }
@@ -16529,7 +16547,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16529
16547
  trigger.style.display = "inline-flex";
16530
16548
  trigger.style.alignItems = "center";
16531
16549
  trigger.style.width = "fit-content";
16532
- trigger.style.maxWidth = "min(180px, 30vw)";
16550
+ trigger.style.maxWidth = rendererUsageTriggerMaxWidth();
16533
16551
  trigger.style.height = "24px";
16534
16552
  trigger.style.padding = "0 4px";
16535
16553
  trigger.style.borderRadius = "9999px";
@@ -16641,7 +16659,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16641
16659
  const hasCost = totalCostUsd !== void 0;
16642
16660
  const visible = hasCacheHitRate || hasOutputSpeed || hasCost;
16643
16661
  control.root.style.display = visible ? "inline-flex" : "none";
16644
- if (!visible || !usage) {
16662
+ if (!visible) {
16645
16663
  closePopover(control);
16646
16664
  return false;
16647
16665
  }
@@ -16652,6 +16670,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16652
16670
  ].filter((value) => value !== null);
16653
16671
  const compactSummary = summary.join(" \xB7 ");
16654
16672
  const accessibleSummary = `Thread Usage: ${compactSummary}`;
16673
+ control.trigger.style.maxWidth = rendererUsageTriggerMaxWidth();
16655
16674
  control.trigger.setAttribute("aria-label", accessibleSummary);
16656
16675
  control.trigger.title = accessibleSummary;
16657
16676
  control.label.textContent = compactSummary;
@@ -16659,6 +16678,256 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16659
16678
  return true;
16660
16679
  }
16661
16680
 
16681
+ // src/renderer-credits-control.ts
16682
+ function rendererCreditsTone(usedPercent) {
16683
+ if (usedPercent >= 90) return "hot";
16684
+ if (usedPercent >= 70) return "warn";
16685
+ return "ok";
16686
+ }
16687
+ function formatRendererCreditsReset(value) {
16688
+ const date5 = new Date(value);
16689
+ if (Number.isNaN(date5.getTime())) return value;
16690
+ return date5.toLocaleString(void 0, {
16691
+ month: "long",
16692
+ day: "numeric",
16693
+ hour: "numeric",
16694
+ minute: "2-digit"
16695
+ });
16696
+ }
16697
+ function creditsPeriodLabel(periodType) {
16698
+ if (periodType === "weekly") return "Weekly limit";
16699
+ if (periodType === "monthly") return "Monthly limit";
16700
+ return "Account limit";
16701
+ }
16702
+ function productLabel(product) {
16703
+ if (product === "GrokBuild") return "Build";
16704
+ if (product === "GrokChat") return "Chat";
16705
+ if (product === "GrokImagine") return "Imagine";
16706
+ if (product === "GrokVoice") return "Voice";
16707
+ return product;
16708
+ }
16709
+ function toneColor(tone) {
16710
+ if (tone === "hot") return "#c45c4a";
16711
+ if (tone === "warn") return "#c9a227";
16712
+ return "#3d9a64";
16713
+ }
16714
+ function addDetailRow2(parent, label, value) {
16715
+ const row = document.createElement("div");
16716
+ row.style.display = "grid";
16717
+ row.style.gridTemplateColumns = "minmax(0, 1fr) auto";
16718
+ row.style.gap = "20px";
16719
+ row.style.padding = "4px 0";
16720
+ const labelElement = document.createElement("span");
16721
+ labelElement.textContent = label;
16722
+ labelElement.style.color = "color-mix(in srgb, currentColor 68%, transparent)";
16723
+ const valueElement = document.createElement("span");
16724
+ valueElement.textContent = value;
16725
+ valueElement.style.fontVariantNumeric = "tabular-nums";
16726
+ valueElement.style.textAlign = "right";
16727
+ row.append(labelElement, valueElement);
16728
+ parent.append(row);
16729
+ }
16730
+ function renderDetails2(popover, credits) {
16731
+ popover.replaceChildren();
16732
+ const heading = document.createElement("div");
16733
+ heading.textContent = creditsPeriodLabel(credits.periodType);
16734
+ heading.style.fontWeight = "600";
16735
+ heading.style.marginBottom = "6px";
16736
+ popover.append(heading);
16737
+ addDetailRow2(popover, "Used", formatRendererCreditsPercent(credits.usedPercent));
16738
+ if (credits.resetsAt) {
16739
+ addDetailRow2(popover, "Resets", formatRendererCreditsReset(credits.resetsAt));
16740
+ }
16741
+ for (const product of credits.productUsage ?? []) {
16742
+ addDetailRow2(
16743
+ popover,
16744
+ productLabel(product.product),
16745
+ formatRendererCreditsPercent(product.usagePercent)
16746
+ );
16747
+ }
16748
+ }
16749
+ function popoverIsOpen2(popover) {
16750
+ try {
16751
+ return popover.matches(":popover-open");
16752
+ } catch {
16753
+ return !popover.hidden;
16754
+ }
16755
+ }
16756
+ function positionPopover2(control) {
16757
+ const triggerRect = control.trigger.getBoundingClientRect();
16758
+ const width = Math.min(280, Math.max(220, window.innerWidth - 24));
16759
+ const left = Math.max(12, Math.min(triggerRect.left, window.innerWidth - width - 12));
16760
+ control.popover.style.width = `${width}px`;
16761
+ control.popover.style.left = `${left}px`;
16762
+ control.popover.style.right = "auto";
16763
+ control.popover.style.top = "auto";
16764
+ control.popover.style.bottom = `${Math.max(12, window.innerHeight - triggerRect.top + 8)}px`;
16765
+ }
16766
+ function closePopover2(control) {
16767
+ if (popoverIsOpen2(control.popover) && typeof control.popover.hidePopover === "function") {
16768
+ control.popover.hidePopover();
16769
+ }
16770
+ control.popover.hidden = true;
16771
+ control.trigger.setAttribute("aria-expanded", "false");
16772
+ }
16773
+ function openPopover2(control) {
16774
+ positionPopover2(control);
16775
+ control.popover.hidden = false;
16776
+ if (typeof control.popover.showPopover === "function" && !popoverIsOpen2(control.popover)) {
16777
+ control.popover.showPopover();
16778
+ }
16779
+ control.trigger.setAttribute("aria-expanded", "true");
16780
+ }
16781
+ function togglePopover2(control) {
16782
+ if (control.trigger.getAttribute("aria-expanded") === "true") closePopover2(control);
16783
+ else openPopover2(control);
16784
+ }
16785
+ function mountRendererCreditsControl(composerId, nativeModelClassName) {
16786
+ const root = document.createElement("div");
16787
+ root.dataset.codexhostCreditsControl = composerId;
16788
+ root.className = "relative min-w-0";
16789
+ root.style.display = "none";
16790
+ const trigger = document.createElement("button");
16791
+ const syncNativeModelClassName = (className) => {
16792
+ trigger.className = className?.trim() || RENDERER_MODEL_TRIGGER_FALLBACK_CLASSES;
16793
+ };
16794
+ syncNativeModelClassName(nativeModelClassName);
16795
+ trigger.type = "button";
16796
+ trigger.setAttribute("aria-haspopup", "dialog");
16797
+ trigger.setAttribute("aria-expanded", "false");
16798
+ trigger.setAttribute("aria-label", "Account limit");
16799
+ trigger.title = "Account limit";
16800
+ trigger.style.display = "inline-flex";
16801
+ trigger.style.alignItems = "center";
16802
+ trigger.style.gap = "5px";
16803
+ trigger.style.width = "fit-content";
16804
+ trigger.style.maxWidth = "min(72px, 18vw)";
16805
+ trigger.style.height = "24px";
16806
+ trigger.style.padding = "0 6px";
16807
+ trigger.style.borderRadius = "9999px";
16808
+ trigger.style.fontSize = "12px";
16809
+ trigger.style.lineHeight = "16px";
16810
+ trigger.style.fontVariantNumeric = "tabular-nums";
16811
+ trigger.style.letterSpacing = "0";
16812
+ trigger.style.whiteSpace = "nowrap";
16813
+ trigger.style.cursor = "pointer";
16814
+ const dot = document.createElement("span");
16815
+ dot.dataset.codexhostCreditsDot = "";
16816
+ dot.setAttribute("aria-hidden", "true");
16817
+ dot.style.display = "inline-block";
16818
+ dot.style.width = "7px";
16819
+ dot.style.height = "7px";
16820
+ dot.style.borderRadius = "9999px";
16821
+ dot.style.flex = "0 0 auto";
16822
+ const label = document.createElement("span");
16823
+ label.dataset.codexhostCreditsLabel = "";
16824
+ label.style.display = "inline-block";
16825
+ label.style.maxWidth = "100%";
16826
+ label.style.overflow = "hidden";
16827
+ label.style.textOverflow = "ellipsis";
16828
+ label.style.whiteSpace = "nowrap";
16829
+ trigger.append(dot, label);
16830
+ const popover = document.createElement("div");
16831
+ popover.id = `${composerId}-credits-popover`;
16832
+ popover.setAttribute("role", "dialog");
16833
+ popover.setAttribute("aria-label", "Account limit details");
16834
+ popover.setAttribute("popover", "auto");
16835
+ popover.hidden = typeof popover.showPopover !== "function";
16836
+ popover.style.position = "fixed";
16837
+ popover.style.inset = "auto";
16838
+ popover.style.width = "240px";
16839
+ popover.style.maxWidth = "min(280px, calc(100vw - 24px))";
16840
+ popover.style.padding = "10px 12px";
16841
+ popover.style.border = "1px solid rgba(127, 127, 127, 0.35)";
16842
+ popover.style.borderRadius = "6px";
16843
+ popover.style.background = "Canvas";
16844
+ popover.style.color = "CanvasText";
16845
+ popover.style.boxShadow = "0 8px 24px rgba(0, 0, 0, 0.28)";
16846
+ popover.style.font = "13px/1.35 system-ui, sans-serif";
16847
+ popover.style.letterSpacing = "0";
16848
+ popover.style.zIndex = "2147483647";
16849
+ trigger.setAttribute("aria-controls", popover.id);
16850
+ let placementReference = null;
16851
+ const control = {
16852
+ root,
16853
+ trigger,
16854
+ popover,
16855
+ anchor: null,
16856
+ syncNativeModelClassName,
16857
+ dispose() {
16858
+ closePopover2(control);
16859
+ if (closeTimer !== null) window.clearTimeout(closeTimer);
16860
+ root.remove();
16861
+ popover.remove();
16862
+ placementReference = null;
16863
+ },
16864
+ place(anchor) {
16865
+ if (!anchor?.parentElement) return false;
16866
+ const parent = anchor.parentElement;
16867
+ const next = anchor.nextElementSibling;
16868
+ if (control.anchor === anchor && placementReference === anchor && root.parentElement === parent && root.previousElementSibling === anchor) {
16869
+ return true;
16870
+ }
16871
+ control.anchor = anchor;
16872
+ placementReference = anchor;
16873
+ if (next && next !== root) parent.insertBefore(root, next);
16874
+ else if (next !== root) parent.append(root);
16875
+ return true;
16876
+ }
16877
+ };
16878
+ let closeTimer = null;
16879
+ const cancelClose = () => {
16880
+ if (closeTimer === null) return;
16881
+ window.clearTimeout(closeTimer);
16882
+ closeTimer = null;
16883
+ };
16884
+ const scheduleClose = () => {
16885
+ cancelClose();
16886
+ closeTimer = window.setTimeout(() => {
16887
+ closeTimer = null;
16888
+ if (!trigger.matches(":hover") && !popover.matches(":hover")) closePopover2(control);
16889
+ }, 140);
16890
+ };
16891
+ trigger.addEventListener("click", () => togglePopover2(control));
16892
+ trigger.addEventListener("pointerenter", () => {
16893
+ cancelClose();
16894
+ openPopover2(control);
16895
+ });
16896
+ trigger.addEventListener("pointerleave", scheduleClose);
16897
+ trigger.addEventListener("focus", () => {
16898
+ cancelClose();
16899
+ openPopover2(control);
16900
+ });
16901
+ trigger.addEventListener("blur", scheduleClose);
16902
+ popover.addEventListener("pointerenter", cancelClose);
16903
+ popover.addEventListener("pointerleave", scheduleClose);
16904
+ popover.addEventListener("toggle", () => {
16905
+ trigger.setAttribute("aria-expanded", String(popoverIsOpen2(popover)));
16906
+ });
16907
+ root.append(trigger);
16908
+ document.body.append(popover);
16909
+ return control;
16910
+ }
16911
+ function renderRendererCreditsControl(control, accountCredits) {
16912
+ if (accountCredits === null) {
16913
+ control.root.style.display = "none";
16914
+ closePopover2(control);
16915
+ return false;
16916
+ }
16917
+ const percent = formatRendererCreditsPercent(accountCredits.usedPercent);
16918
+ const title = `${creditsPeriodLabel(accountCredits.periodType)} ${percent}`;
16919
+ const tone = rendererCreditsTone(accountCredits.usedPercent);
16920
+ const dot = control.trigger.querySelector("[data-codexhost-credits-dot]");
16921
+ const label = control.trigger.querySelector("[data-codexhost-credits-label]");
16922
+ if (dot) dot.style.background = toneColor(tone);
16923
+ if (label) label.textContent = percent;
16924
+ control.root.style.display = "inline-flex";
16925
+ control.trigger.setAttribute("aria-label", title);
16926
+ control.trigger.title = title;
16927
+ renderDetails2(control.popover, accountCredits);
16928
+ return true;
16929
+ }
16930
+
16662
16931
  // src/renderer-composer-dom.ts
16663
16932
  var CODEX_COMPOSER_SELECTOR = "[data-codex-composer-root]";
16664
16933
  var EDITOR_SELECTOR = 'textarea, [contenteditable="true"], [role="textbox"]';
@@ -16770,7 +17039,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16770
17039
  }
16771
17040
  var contextUsageDescriptionPattern = /(context|token|上下文|令牌)/iu;
16772
17041
  function isNativeContextUsageControlCandidate(element) {
16773
- if (element.hasAttribute("data-codexhost-usage-control")) return false;
17042
+ if (element.hasAttribute("data-codexhost-usage-control") || element.hasAttribute("data-codexhost-credits-control")) {
17043
+ return false;
17044
+ }
16774
17045
  const description = [
16775
17046
  element.getAttribute("aria-label"),
16776
17047
  element.getAttribute("title"),
@@ -16803,6 +17074,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16803
17074
  const candidate = nativeModelControlForComposer(control.composer);
16804
17075
  if (!candidate) {
16805
17076
  control.usage.syncNativeModelClassName();
17077
+ control.credits.syncNativeModelClassName();
16806
17078
  return;
16807
17079
  }
16808
17080
  if (candidate !== control.nativeModelControl?.element) {
@@ -16811,15 +17083,54 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16811
17083
  syncRendererModelTriggerClass(control.modelPicker, candidate.className);
16812
17084
  }
16813
17085
  control.usage.syncNativeModelClassName(candidate.className);
17086
+ control.credits.syncNativeModelClassName(candidate.className);
17087
+ }
17088
+ function usagePlacementAnchor(control) {
17089
+ const context = nativeContextUsageControlForComposer(control.composer);
17090
+ if (context?.parentElement) return context;
17091
+ const modelRoot = control.modelPicker.root;
17092
+ if (modelRoot.parentElement) return modelRoot;
17093
+ const native = control.nativeModelControl?.element;
17094
+ return native?.parentElement ? native : null;
17095
+ }
17096
+ function firstMaterialChild(parent) {
17097
+ for (const child of parent.children) {
17098
+ if (typeof child.hasAttribute !== "function") continue;
17099
+ const element = child;
17100
+ if (element.hasAttribute("data-codexhost-credits-control")) continue;
17101
+ return element;
17102
+ }
17103
+ return null;
16814
17104
  }
16815
- function refreshNativeContextUsageControl(control) {
16816
- const candidate = nativeContextUsageControlForComposer(control.composer);
16817
- if (!candidate) {
17105
+ function creditsPlacementAnchor(composer, usageRoot) {
17106
+ let current = usageRoot;
17107
+ while (current && current !== composer) {
17108
+ const parent = current.parentElement;
17109
+ if (!parent) break;
17110
+ const first = firstMaterialChild(parent);
17111
+ if (first && first !== current && !first.contains(usageRoot)) return first;
17112
+ if (parent === composer) break;
17113
+ current = parent;
17114
+ }
17115
+ return null;
17116
+ }
17117
+ function refreshUsagePlacement(control) {
17118
+ const anchor = usagePlacementAnchor(control);
17119
+ if (!anchor) {
16818
17120
  if (control.usage.anchor) control.usage.root.remove();
16819
17121
  control.usage.anchor = null;
17122
+ if (control.credits.anchor) control.credits.root.remove();
17123
+ control.credits.anchor = null;
17124
+ return;
17125
+ }
17126
+ control.usage.place(anchor);
17127
+ const leading = creditsPlacementAnchor(control.composer, control.usage.root);
17128
+ if (!leading) {
17129
+ if (control.credits.anchor) control.credits.root.remove();
17130
+ control.credits.anchor = null;
16820
17131
  return;
16821
17132
  }
16822
- control.usage.place(candidate);
17133
+ control.credits.place(leading);
16823
17134
  }
16824
17135
  function refreshNativePermissionModeControl(control) {
16825
17136
  const semanticCandidate = semanticNativePermissionModeControlForComposer(control.composer);
@@ -16851,7 +17162,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16851
17162
  }
16852
17163
  function reconcileComposerNativeControls(control, hideModel, hidePermissionMode) {
16853
17164
  refreshNativeModelControl(control);
16854
- refreshNativeContextUsageControl(control);
17165
+ refreshUsagePlacement(control);
16855
17166
  refreshNativePermissionModeControl(control);
16856
17167
  setNativeControlHidden(control.nativeModelControl, hideModel);
16857
17168
  setNativeControlHidden(control.nativePermissionModeControl, hidePermissionMode);
@@ -16874,6 +17185,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16874
17185
  onSelectPermissionMode
16875
17186
  );
16876
17187
  const usage = mountRendererUsageControl(composerId, nativeModelControl?.element.className);
17188
+ const credits = mountRendererCreditsControl(composerId, nativeModelControl?.element.className);
16877
17189
  const permissionParent = nativePermissionModeControl?.element.parentElement;
16878
17190
  if (permissionParent && nativePermissionModeControl && nativePermissionModeControlVerified) {
16879
17191
  permissionParent.insertBefore(permissionModePicker.root, nativePermissionModeControl.element);
@@ -16896,14 +17208,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16896
17208
  nativeModelControl,
16897
17209
  nativePermissionModeControl,
16898
17210
  nativePermissionModeControlVerified,
17211
+ credits,
16899
17212
  usage,
16900
17213
  sendButton,
16901
17214
  sendDisabledBeforeSwitch: null
16902
17215
  };
16903
- refreshNativeContextUsageControl(control);
17216
+ refreshUsagePlacement(control);
16904
17217
  return control;
16905
17218
  }
16906
- function renderComposerAgentControl(control, state, adapterState, switching, availability = {}, modelView = { status: "idle" }, permissionModeView = { status: "idle" }, usage = null) {
17219
+ function renderComposerAgentControl(control, state, adapterState, switching, availability = {}, modelView = { status: "idle" }, permissionModeView = { status: "idle" }, usage = null, accountCredits = null) {
16907
17220
  const selectedModel = modelView.selected;
16908
17221
  const selectedCatalogModel = modelView.catalog?.models.find(
16909
17222
  (model) => model.ref.id === selectedModel?.id
@@ -16941,6 +17254,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16941
17254
  permissionModeVisible
16942
17255
  );
16943
17256
  renderRendererUsageControl(control.usage, usage);
17257
+ renderRendererCreditsControl(control.credits, accountCredits);
16944
17258
  }
16945
17259
  function disposeComposerAgentControl(control) {
16946
17260
  if (control.sendDisabledBeforeSwitch !== null) {
@@ -16948,6 +17262,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16948
17262
  }
16949
17263
  restoreNativeControl(control.nativeModelControl);
16950
17264
  restoreNativeControl(control.nativePermissionModeControl);
17265
+ control.credits.dispose();
16951
17266
  control.usage.dispose();
16952
17267
  control.permissionModePicker.dispose();
16953
17268
  control.modelPicker.dispose();
@@ -18540,6 +18855,124 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18540
18855
  }
18541
18856
  };
18542
18857
 
18858
+ // src/settings/release-notes.ts
18859
+ var HEADING_PATTERN = /^(#{1,6})[ \t]+(.+?)\s*$/u;
18860
+ var UNORDERED_ITEM_PATTERN = /^[-*][ \t]+(.+?)\s*$/u;
18861
+ var ORDERED_ITEM_PATTERN = /^\d+[.)][ \t]+(.+?)\s*$/u;
18862
+ var FENCE_PATTERN = /^```([\w+-]*)\s*$/u;
18863
+ var INLINE_PATTERN = /(`+)((?:(?!\1).)+)\1|\*\*(.+?)\*\*|\[([^\]]+)\]\(([^)\s]+)\)/gu;
18864
+ function createReleaseNotesElement(document2, markdown) {
18865
+ const root = document2.createElement("div");
18866
+ root.className = "settings-update-notes";
18867
+ appendReleaseNotesBlocks(document2, root, markdown);
18868
+ return root;
18869
+ }
18870
+ function appendReleaseNotesBlocks(document2, root, markdown) {
18871
+ const lines = markdown.replaceAll("\r\n", "\n").split("\n");
18872
+ let index = 0;
18873
+ while (index < lines.length) {
18874
+ const line = lines[index] ?? "";
18875
+ if (line.trim().length === 0) {
18876
+ index += 1;
18877
+ continue;
18878
+ }
18879
+ const fence = FENCE_PATTERN.exec(line);
18880
+ if (fence) {
18881
+ index = appendFencedCode(document2, root, lines, index, fence[1] ?? "");
18882
+ continue;
18883
+ }
18884
+ const heading = HEADING_PATTERN.exec(line);
18885
+ if (heading?.[1] && heading[2]) {
18886
+ const tag = `h${heading[1].length}`;
18887
+ const element = document2.createElement(tag);
18888
+ appendInline(document2, element, heading[2]);
18889
+ root.append(element);
18890
+ index += 1;
18891
+ continue;
18892
+ }
18893
+ if (UNORDERED_ITEM_PATTERN.test(line)) {
18894
+ index = appendList(document2, root, lines, index, "ul", UNORDERED_ITEM_PATTERN);
18895
+ continue;
18896
+ }
18897
+ if (ORDERED_ITEM_PATTERN.test(line)) {
18898
+ index = appendList(document2, root, lines, index, "ol", ORDERED_ITEM_PATTERN);
18899
+ continue;
18900
+ }
18901
+ index = appendParagraph(document2, root, lines, index);
18902
+ }
18903
+ }
18904
+ function appendFencedCode(document2, root, lines, start, language) {
18905
+ const body = [];
18906
+ let index = start + 1;
18907
+ while (index < lines.length && !FENCE_PATTERN.test(lines[index] ?? "")) {
18908
+ body.push(lines[index] ?? "");
18909
+ index += 1;
18910
+ }
18911
+ if (index < lines.length) index += 1;
18912
+ const pre = document2.createElement("pre");
18913
+ const code = document2.createElement("code");
18914
+ if (language.length > 0) code.className = `language-${language}`;
18915
+ code.textContent = body.join("\n");
18916
+ pre.append(code);
18917
+ root.append(pre);
18918
+ return index;
18919
+ }
18920
+ function appendList(document2, root, lines, start, tag, pattern) {
18921
+ const list = document2.createElement(tag);
18922
+ let index = start;
18923
+ while (index < lines.length) {
18924
+ const item = pattern.exec(lines[index] ?? "");
18925
+ if (!item?.[1]) break;
18926
+ const entry = document2.createElement("li");
18927
+ appendInline(document2, entry, item[1]);
18928
+ list.append(entry);
18929
+ index += 1;
18930
+ }
18931
+ root.append(list);
18932
+ return index;
18933
+ }
18934
+ function appendParagraph(document2, root, lines, start) {
18935
+ const paragraphLines = [];
18936
+ let index = start;
18937
+ while (index < lines.length) {
18938
+ const current = lines[index] ?? "";
18939
+ if (current.trim().length === 0 || FENCE_PATTERN.test(current) || HEADING_PATTERN.test(current) || UNORDERED_ITEM_PATTERN.test(current) || ORDERED_ITEM_PATTERN.test(current)) {
18940
+ break;
18941
+ }
18942
+ paragraphLines.push(current.trim());
18943
+ index += 1;
18944
+ }
18945
+ const paragraph = document2.createElement("p");
18946
+ appendInline(document2, paragraph, paragraphLines.join(" "));
18947
+ root.append(paragraph);
18948
+ return index;
18949
+ }
18950
+ function appendInline(document2, parent, text) {
18951
+ let lastIndex = 0;
18952
+ for (const match of text.matchAll(INLINE_PATTERN)) {
18953
+ const index = match.index ?? 0;
18954
+ if (index > lastIndex) parent.append(text.slice(lastIndex, index));
18955
+ if (match[2] !== void 0) {
18956
+ const code = document2.createElement("code");
18957
+ code.textContent = match[2];
18958
+ parent.append(code);
18959
+ } else if (match[3] !== void 0) {
18960
+ const strong = document2.createElement("strong");
18961
+ strong.textContent = match[3];
18962
+ parent.append(strong);
18963
+ } else {
18964
+ const link = document2.createElement("a");
18965
+ link.textContent = match[4] ?? "";
18966
+ link.setAttribute("href", match[5] ?? "");
18967
+ link.setAttribute("target", "_blank");
18968
+ link.setAttribute("rel", "noopener noreferrer");
18969
+ parent.append(link);
18970
+ }
18971
+ lastIndex = index + match[0].length;
18972
+ }
18973
+ if (lastIndex < text.length) parent.append(text.slice(lastIndex));
18974
+ }
18975
+
18543
18976
  // src/settings/update-request.ts
18544
18977
  var RENDERER_UPDATE_REQUEST_TIMEOUT_MS = 15e3;
18545
18978
  var RendererUpdateRequestTimeoutError = class extends Error {
@@ -18832,10 +19265,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18832
19265
  summary.textContent = operationMessage ?? (result.error ? messages.updateFailed : result.updateAvailable ? messages.updateAvailable : messages.updateUpToDate);
18833
19266
  panel.append(summary);
18834
19267
  if (result.releaseNotes) {
18835
- const releaseNotes = document2.createElement("div");
18836
- releaseNotes.className = "settings-update-notes";
18837
- releaseNotes.textContent = result.releaseNotes;
18838
- panel.append(releaseNotes);
19268
+ panel.append(createReleaseNotesElement(document2, result.releaseNotes));
18839
19269
  }
18840
19270
  if (result.status?.phase === "failed" && result.status.error) {
18841
19271
  const error51 = document2.createElement("p");
@@ -18906,7 +19336,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18906
19336
  }
18907
19337
 
18908
19338
  // src/settings/shell.css
18909
- var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-icon-button.settings-star-link {\n width: auto;\n gap: 6px;\n padding-inline: 8px;\n font-size: 12px;\n line-height: 18px;\n text-decoration: none;\n border: 2px dashed #f5c542;\n white-space: nowrap;\n}\n\n.settings-star-link .codexhost-settings-icon {\n color: #f5c542;\n fill: currentColor;\n stroke: currentColor;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 40px;\n flex: none;\n gap: 12px;\n padding: 8px 12px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 10px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 7%);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 16px;\n min-height: 128px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-update-panel > strong,\n.settings-update-panel > span,\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-panel > span,\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-notes {\n max-height: 240px;\n padding: 14px;\n overflow: auto;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n background: rgb(255 255 255 / 4%);\n border: 1px solid var(--settings-divider);\n border-radius: 6px;\n}\n\n.settings-update-version-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 20px;\n min-height: 32px;\n color: var(--settings-muted);\n font-size: 13px;\n}\n\n.settings-update-version-row strong {\n color: var(--settings-text);\n font-size: 15px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 6px;\n margin-top: 14px;\n padding-inline: 4px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual code {\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-actions {\n display: flex;\n min-width: 0;\n margin-top: 16px;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-icon-button.settings-star-link {\n width: 28px;\n padding: 0;\n }\n\n .settings-star-link span {\n display: none;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
19339
+ var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-icon-button.settings-star-link {\n width: auto;\n gap: 6px;\n padding-inline: 8px;\n font-size: 12px;\n line-height: 18px;\n text-decoration: none;\n border: 2px dashed #f5c542;\n white-space: nowrap;\n}\n\n.settings-star-link .codexhost-settings-icon {\n color: #f5c542;\n fill: currentColor;\n stroke: currentColor;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 40px;\n flex: none;\n gap: 12px;\n padding: 8px 12px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 10px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 7%);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 16px;\n min-height: 128px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-update-panel > strong,\n.settings-update-panel > span,\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-panel > span,\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-notes {\n display: grid;\n gap: 10px;\n max-height: 320px;\n overflow: auto;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n overflow-wrap: anywhere;\n}\n\n.settings-update-notes > :first-child {\n margin-top: 0;\n}\n\n.settings-update-notes > :last-child {\n margin-bottom: 0;\n}\n\n.settings-update-notes h1,\n.settings-update-notes h2,\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n margin: 6px 0 0;\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes h1 {\n font-size: 16px;\n line-height: 24px;\n}\n\n.settings-update-notes h2 {\n font-size: 15px;\n line-height: 22px;\n}\n\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-notes p,\n.settings-update-notes ul,\n.settings-update-notes ol,\n.settings-update-notes pre {\n margin: 0;\n}\n\n.settings-update-notes ul,\n.settings-update-notes ol {\n padding-left: 20px;\n}\n\n.settings-update-notes li + li {\n margin-top: 4px;\n}\n\n.settings-update-notes strong {\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes a {\n color: #7cb8ff;\n text-decoration: none;\n}\n\n.settings-update-notes a:hover {\n text-decoration: underline;\n}\n\n.settings-update-notes code {\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n}\n\n.settings-update-notes :not(pre) > code {\n padding: 1px 5px;\n background: rgb(255 255 255 / 8%);\n border-radius: 4px;\n}\n\n.settings-update-notes pre {\n padding: 10px 12px;\n overflow: auto;\n background: rgb(0 0 0 / 28%);\n border-radius: 6px;\n}\n\n.settings-update-notes pre code {\n line-height: 18px;\n white-space: pre-wrap;\n}\n\n.settings-update-version-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 20px;\n min-height: 32px;\n color: var(--settings-muted);\n font-size: 13px;\n}\n\n.settings-update-version-row strong {\n color: var(--settings-text);\n font-size: 15px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 6px;\n margin-top: 14px;\n padding-inline: 4px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual code {\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-actions {\n display: flex;\n min-width: 0;\n margin-top: 16px;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-icon-button.settings-star-link {\n width: 28px;\n padding: 0;\n }\n\n .settings-star-link span {\n display: none;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
18910
19340
 
18911
19341
  // src/settings/shell.ts
18912
19342
  var SETTINGS_SHELL_ATTRIBUTE = "data-codexhost-settings-shell";
@@ -19553,8 +19983,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19553
19983
  const index = Math.max(0, Math.min(Math.trunc(attempt), rendererUsageRefreshDelays.length - 1));
19554
19984
  return rendererUsageRefreshDelays[index] ?? rendererUsageRefreshDelays[0];
19555
19985
  }
19556
- function shouldRetryExternalThreadUsage(agent, usage) {
19557
- return agent !== "codex" && usage === null;
19986
+ function shouldRetryExternalThreadUsage(agent, usage, accountCredits = null) {
19987
+ if (agent === "codex") return false;
19988
+ if (usage === null) return true;
19989
+ return agent === "grok" && accountCredits === null;
19558
19990
  }
19559
19991
  function selectableThinkingOptionId(state) {
19560
19992
  return state.effectiveThinkingOptionId && state.availableThinkingOptions?.some(({ id }) => id === state.effectiveThinkingOptionId) ? state.effectiveThinkingOptionId : void 0;
@@ -19742,7 +20174,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19742
20174
  harnessAvailability,
19743
20175
  mounted.modelView,
19744
20176
  mounted.permissionModeView,
19745
- mounted.usage
20177
+ mounted.usage,
20178
+ mounted.accountCredits
19746
20179
  );
19747
20180
  };
19748
20181
  const applyThreadUsageUpdate = (update) => {
@@ -19750,6 +20183,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19750
20183
  if (threadIdFromComposerModelTarget(mounted.modelTarget) !== update.threadId) continue;
19751
20184
  mounted.usageRequestGeneration += 1;
19752
20185
  mounted.usage = update.usage;
20186
+ mounted.accountCredits = update.accountCredits ?? null;
19753
20187
  usageRefreshAttempts.delete(mounted.composer);
19754
20188
  renderMounted(mounted);
19755
20189
  }
@@ -19758,6 +20192,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19758
20192
  const threadId = threadIdFromComposerModelTarget(mounted.modelTarget);
19759
20193
  if (!threadId || !modelControl || controller.get(mounted.composer).agent === "codex") {
19760
20194
  mounted.usage = null;
20195
+ mounted.accountCredits = null;
19761
20196
  usageRefreshAttempts.delete(mounted.composer);
19762
20197
  renderMounted(mounted);
19763
20198
  return;
@@ -19769,15 +20204,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19769
20204
  return;
19770
20205
  }
19771
20206
  mounted.usage = result.usage;
19772
- if (result.usage !== null) usageRefreshAttempts.delete(mounted.composer);
20207
+ mounted.accountCredits = result.accountCredits ?? null;
20208
+ const agent = controller.get(mounted.composer).agent;
20209
+ if (result.usage !== null && (agent !== "grok" || result.accountCredits)) {
20210
+ usageRefreshAttempts.delete(mounted.composer);
20211
+ }
19773
20212
  renderMounted(mounted);
19774
- if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, result.usage)) {
20213
+ if (shouldRetryExternalThreadUsage(
20214
+ controller.get(mounted.composer).agent,
20215
+ result.usage,
20216
+ result.accountCredits ?? null
20217
+ )) {
19775
20218
  scheduleThreadUsageRefresh(mounted);
19776
20219
  }
19777
20220
  } catch {
19778
20221
  if (mountedByComposer.get(mounted.composer) === mounted && mounted.usageRequestGeneration === generation) {
19779
20222
  renderMounted(mounted);
19780
- if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null)) {
20223
+ if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null, null)) {
19781
20224
  scheduleThreadUsageRefresh(mounted);
19782
20225
  }
19783
20226
  }
@@ -19866,7 +20309,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19866
20309
  } finally {
19867
20310
  if (isCurrentOwnershipRequest(mounted, generation)) {
19868
20311
  renderMounted(mounted);
19869
- if (mounted.ownershipStatus !== "error" && shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, mounted.usage)) {
20312
+ if (mounted.ownershipStatus !== "error" && shouldRetryExternalThreadUsage(
20313
+ controller.get(mounted.composer).agent,
20314
+ mounted.usage,
20315
+ mounted.accountCredits
20316
+ )) {
19870
20317
  scheduleThreadUsageRefresh(mounted);
19871
20318
  }
19872
20319
  }
@@ -19891,7 +20338,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19891
20338
  if (resolution === "transfer") {
19892
20339
  mounted.ownershipStatus = "ready";
19893
20340
  renderMounted(mounted);
19894
- if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null)) {
20341
+ if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null, null)) {
19895
20342
  scheduleThreadUsageRefresh(mounted);
19896
20343
  }
19897
20344
  } else {
@@ -19901,6 +20348,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19901
20348
  mounted.threadConfiguration = void 0;
19902
20349
  mounted.ownershipStatus = "loading";
19903
20350
  mounted.usage = null;
20351
+ mounted.accountCredits = null;
19904
20352
  mounted.usageRequestGeneration += 1;
19905
20353
  usageRefreshAttempts.delete(mounted.composer);
19906
20354
  if (previousTarget?.[0] === "conversation") renderMounted(mounted);
@@ -20438,11 +20886,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20438
20886
  const refreshHarnessAvailability = (refresh = false) => {
20439
20887
  if (!modelControl) return Promise.resolve();
20440
20888
  const client = modelControl;
20889
+ if (availabilityRequest?.client === client) return availabilityRequest.promise;
20441
20890
  harnessAvailability = Object.fromEntries(
20442
- externalAgents.map((agent) => [agent, "checking"])
20891
+ externalAgents.map((agent) => [
20892
+ agent,
20893
+ harnessAvailability[agent] === "ready" ? "ready" : "checking"
20894
+ ])
20443
20895
  );
20444
20896
  for (const mounted of mountedByComposer.values()) renderMounted(mounted);
20445
- if (availabilityRequest?.client === client) return availabilityRequest.promise;
20446
20897
  const generation = ++availabilityRequestGeneration;
20447
20898
  const promise2 = (async () => {
20448
20899
  await Promise.all(
@@ -20538,6 +20989,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20538
20989
  ownershipStatus: threadIdFromComposerModelTarget(modelTarget) ? inherited ? "ready" : "loading" : "not-required",
20539
20990
  threadConfiguration: inherited?.threadConfiguration,
20540
20991
  usage: inherited?.usage ?? null,
20992
+ accountCredits: inherited?.accountCredits ?? null,
20541
20993
  usageRequestGeneration: 0
20542
20994
  };
20543
20995
  mountedByComposer.set(composer, mounted);
@@ -20553,7 +21005,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20553
21005
  renderMounted(mounted);
20554
21006
  if (threadIdFromComposerModelTarget(modelTarget) && !inherited) {
20555
21007
  void loadThreadOwnership(mounted);
20556
- } else if (threadIdFromComposerModelTarget(modelTarget) && inherited && shouldRetryExternalThreadUsage(state.agent, mounted.usage)) {
21008
+ } else if (threadIdFromComposerModelTarget(modelTarget) && inherited && shouldRetryExternalThreadUsage(state.agent, mounted.usage, mounted.accountCredits)) {
20557
21009
  scheduleThreadUsageRefresh(mounted);
20558
21010
  } else if (state.agent !== "codex" && !isExternalConfigurationReady(mounted)) {
20559
21011
  void loadExternalCatalog(mounted);