@codexhost/cli-darwin-x64 0.3.2 → 0.3.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.
@@ -14950,7 +14950,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14950
14950
  totalCostUsd: finiteNonNegativeNumberSchema.optional(),
14951
14951
  cacheHitRatePercent: cacheHitRatePercentSchema.optional(),
14952
14952
  contextWindowTokens: nonNegativeSafeIntegerSchema.optional(),
14953
- contextUsedTokens: nonNegativeSafeIntegerSchema.optional()
14953
+ contextUsedTokens: nonNegativeSafeIntegerSchema.optional(),
14954
+ planFiveHourUsedPercent: cacheHitRatePercentSchema.optional(),
14955
+ planFiveHourResetsAtUnix: nonNegativeSafeIntegerSchema.optional(),
14956
+ planSevenDayUsedPercent: cacheHitRatePercentSchema.optional(),
14957
+ planSevenDayResetsAtUnix: nonNegativeSafeIntegerSchema.optional()
14954
14958
  }).strict().superRefine((usage, context) => {
14955
14959
  if (Object.keys(usage).length === 0) {
14956
14960
  context.addIssue({ code: "custom", message: "Thread Usage must contain a reliable field" });
@@ -14971,16 +14975,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14971
14975
  path: ["contextWindowTokens"]
14972
14976
  });
14973
14977
  }
14978
+ if (usage.planFiveHourResetsAtUnix !== void 0 && usage.planFiveHourUsedPercent === void 0) {
14979
+ context.addIssue({
14980
+ code: "custom",
14981
+ message: "Thread Usage planFiveHourResetsAtUnix must be provided with planFiveHourUsedPercent",
14982
+ path: ["planFiveHourResetsAtUnix"]
14983
+ });
14984
+ }
14985
+ if (usage.planSevenDayResetsAtUnix !== void 0 && usage.planSevenDayUsedPercent === void 0) {
14986
+ context.addIssue({
14987
+ code: "custom",
14988
+ message: "Thread Usage planSevenDayResetsAtUnix must be provided with planSevenDayUsedPercent",
14989
+ path: ["planSevenDayResetsAtUnix"]
14990
+ });
14991
+ }
14974
14992
  });
14975
14993
  var usagePercentSchema = external_exports.number().finite().min(0).max(100);
14976
14994
  var accountCreditsProductUsageSchema = external_exports.object({
14977
14995
  product: external_exports.string().min(1),
14978
- usagePercent: usagePercentSchema
14996
+ usagePercent: usagePercentSchema,
14997
+ resetsAt: external_exports.string().min(1).optional()
14979
14998
  }).strict();
14980
14999
  var accountCreditsSnapshotSchema = external_exports.object({
14981
15000
  usedPercent: usagePercentSchema,
14982
15001
  resetsAt: external_exports.string().min(1).optional(),
14983
- periodType: external_exports.enum(["weekly", "monthly", "unknown"]),
15002
+ periodType: external_exports.enum(["weekly", "monthly", "five_hour", "seven_day", "unknown"]),
14984
15003
  productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional()
14985
15004
  }).strict();
14986
15005
  var threadUsageInspectionParamsSchema = external_exports.object({
@@ -15094,7 +15113,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15094
15113
  selectThinkingOption: external_exports.boolean(),
15095
15114
  selectPermissionMode: external_exports.boolean()
15096
15115
  }).strict(),
15097
- history: harnessHistoryCapabilitiesSchema
15116
+ history: harnessHistoryCapabilitiesSchema,
15117
+ subagents: external_exports.object({
15118
+ observe: external_exports.boolean(),
15119
+ readTranscript: external_exports.boolean()
15120
+ }).strict().optional(),
15121
+ autonomousTurns: external_exports.object({
15122
+ observe: external_exports.boolean()
15123
+ }).strict().optional()
15098
15124
  }).strict();
15099
15125
  var harnessConfigurationStateSchema = external_exports.object({
15100
15126
  effectiveModel: harnessModelRefSchema.optional(),
@@ -15506,6 +15532,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15506
15532
  root.setAttribute(CONTROL_ATTRIBUTE, composerId);
15507
15533
  root.style.display = "inline-flex";
15508
15534
  root.style.alignItems = "center";
15535
+ root.style.alignSelf = "center";
15536
+ root.style.verticalAlign = "middle";
15509
15537
  root.style.width = "30px";
15510
15538
  root.style.height = "28px";
15511
15539
  root.style.marginInline = "4px";
@@ -15877,8 +15905,44 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15877
15905
  };
15878
15906
  }
15879
15907
 
15908
+ // src/renderer-trigger-chip-style.ts
15909
+ var STYLE_ATTRIBUTE = "data-codexhost-trigger-chip-style";
15910
+ var TRIGGER_CHIP_CLASS = "codexhost-trigger-chip";
15911
+ function ensureRendererTriggerChipStyle(ownerDocument) {
15912
+ if (ownerDocument.querySelector(`style[${STYLE_ATTRIBUTE}]`)) return;
15913
+ const style = ownerDocument.createElement("style");
15914
+ style.setAttribute(STYLE_ATTRIBUTE, "true");
15915
+ style.textContent = `
15916
+ .${TRIGGER_CHIP_CLASS} {
15917
+ display: inline-flex;
15918
+ align-items: center;
15919
+ justify-content: center;
15920
+ box-sizing: border-box;
15921
+ border: 0;
15922
+ border-radius: 9999px;
15923
+ background: transparent;
15924
+ color: inherit;
15925
+ white-space: nowrap;
15926
+ cursor: pointer;
15927
+ }
15928
+ .${TRIGGER_CHIP_CLASS}:hover:not(:disabled) {
15929
+ background: rgba(127, 127, 127, 0.08);
15930
+ }
15931
+ .${TRIGGER_CHIP_CLASS}:active:not(:disabled) {
15932
+ background: rgba(127, 127, 127, 0.16);
15933
+ }
15934
+ .${TRIGGER_CHIP_CLASS}[data-state="open"] {
15935
+ background: rgba(127, 127, 127, 0.08);
15936
+ }
15937
+ .${TRIGGER_CHIP_CLASS}:disabled {
15938
+ cursor: not-allowed;
15939
+ opacity: 0.4;
15940
+ }
15941
+ `;
15942
+ (ownerDocument.head ?? ownerDocument.documentElement).append(style);
15943
+ }
15944
+
15880
15945
  // src/renderer-model-picker.ts
15881
- var RENDERER_MODEL_TRIGGER_FALLBACK_CLASSES = "border-token-border no-drag cursor-interaction items-center gap-1 border whitespace-nowrap select-none focus:outline-none disabled:cursor-not-allowed disabled:opacity-40 flex rounded-full text-token-text-tertiary enabled:hover:bg-token-list-hover-background enabled:active:bg-token-foreground/15 data-[state=open]:bg-token-list-hover-background border-transparent h-token-button-composer px-2 py-0 text-sm leading-[18px] min-w-0";
15882
15946
  var MENU_CLASSES = "fixed z-50 overflow-hidden rounded-xl bg-token-dropdown-background/90 text-token-foreground shadow-lg backdrop-blur-xl";
15883
15947
  var SEARCH_INPUT_CLASSES = "mb-1 w-full shrink-0 rounded-lg border border-token-border bg-token-dropdown-background/95 px-2 py-1.5 text-sm text-token-foreground outline-none placeholder:text-token-text-tertiary disabled:cursor-not-allowed disabled:opacity-40";
15884
15948
  var OPTION_CLASSES = "flex w-full cursor-interaction items-center gap-2 rounded-lg px-2 py-2 text-left text-sm text-token-foreground outline-none enabled:hover:bg-token-list-hover-background enabled:active:bg-token-foreground/15 disabled:cursor-not-allowed disabled:opacity-40";
@@ -15996,8 +16060,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15996
16060
  control.modelMenu.style.top = placement.top === void 0 ? "auto" : `${placement.top}px`;
15997
16061
  control.modelMenu.style.bottom = placement.bottom === void 0 ? "auto" : `${placement.bottom}px`;
15998
16062
  }
15999
- function syncRendererModelTriggerClass(control, nativeClassName) {
16000
- control.trigger.className = nativeClassName?.trim() || RENDERER_MODEL_TRIGGER_FALLBACK_CLASSES;
16063
+ function syncRendererModelTriggerClass(control) {
16064
+ control.trigger.className = TRIGGER_CHIP_CLASS;
16001
16065
  control.trigger.style.width = "fit-content";
16002
16066
  control.trigger.style.maxWidth = MODEL_TRIGGER_MAX_WIDTH;
16003
16067
  }
@@ -16032,7 +16096,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16032
16096
  }
16033
16097
  control.searchEmpty.hidden = query.length === 0 || visibleCount > 0;
16034
16098
  }
16035
- function mountRendererModelPicker(composerId, nativeClassName, onSelectModel, onSelectThinking) {
16099
+ function mountRendererModelPicker(composerId, onSelectModel, onSelectThinking) {
16100
+ ensureRendererTriggerChipStyle(document);
16036
16101
  const root = document.createElement("div");
16037
16102
  root.setAttribute("data-codexhost-model-control", composerId);
16038
16103
  root.className = "relative min-w-0";
@@ -16042,14 +16107,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16042
16107
  trigger.setAttribute("aria-haspopup", "menu");
16043
16108
  trigger.setAttribute("aria-expanded", "false");
16044
16109
  trigger.setAttribute("data-state", "closed");
16110
+ trigger.style.height = "28px";
16111
+ trigger.style.padding = "0 8px";
16112
+ trigger.style.gap = "4px";
16113
+ trigger.style.font = "400 13px/18px system-ui, sans-serif";
16114
+ trigger.style.letterSpacing = "0";
16045
16115
  const label = document.createElement("span");
16046
- label.className = "truncate text-token-foreground";
16116
+ label.style.color = "inherit";
16047
16117
  label.style.minWidth = "0";
16048
16118
  label.style.overflow = "hidden";
16049
16119
  label.style.textOverflow = "ellipsis";
16050
16120
  label.style.whiteSpace = "nowrap";
16051
16121
  const thinkingLabel = document.createElement("span");
16052
- thinkingLabel.className = "shrink-0 truncate text-token-text-tertiary";
16122
+ thinkingLabel.style.color = "var(--color-text-tertiary, #8f8f8f)";
16053
16123
  thinkingLabel.style.flex = "none";
16054
16124
  thinkingLabel.style.maxWidth = "96px";
16055
16125
  thinkingLabel.style.overflow = "hidden";
@@ -16276,7 +16346,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16276
16346
  root.remove();
16277
16347
  }
16278
16348
  };
16279
- syncRendererModelTriggerClass(control, nativeClassName);
16349
+ syncRendererModelTriggerClass(control);
16280
16350
  return control;
16281
16351
  }
16282
16352
  function rebuildOptions(control, view) {
@@ -16343,7 +16413,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16343
16413
  if (popoverOpen2(control.modelMenu)) control.searchInput.focus();
16344
16414
  }
16345
16415
  function renderRendererModelPicker(control, view, visible) {
16346
- control.root.style.display = visible ? "block" : "none";
16416
+ control.root.style.display = visible ? "inline-flex" : "none";
16417
+ control.root.style.alignItems = "center";
16418
+ control.root.style.alignSelf = "center";
16419
+ control.root.style.height = "28px";
16420
+ control.root.style.flex = "0 0 auto";
16421
+ control.root.style.verticalAlign = "middle";
16347
16422
  if (!visible) {
16348
16423
  control.close();
16349
16424
  return;
@@ -16456,7 +16531,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16456
16531
  ];
16457
16532
 
16458
16533
  // src/renderer-permission-mode-picker.ts
16459
- var FALLBACK_TRIGGER_CLASSES = "no-drag cursor-interaction items-center gap-1 border whitespace-nowrap select-none focus:outline-none disabled:cursor-not-allowed disabled:opacity-40 flex rounded-full text-token-text-tertiary enabled:hover:bg-token-list-hover-background enabled:active:bg-token-foreground/15 data-[state=open]:bg-token-list-hover-background border-transparent h-token-button-composer-sm px-1.5 py-0 text-sm leading-[18px] outline-hidden min-w-0";
16460
16534
  var MENU_CLASSES2 = "fixed z-50 overflow-hidden rounded-lg bg-token-dropdown-background/95 text-token-foreground shadow-lg ring-[0.5px] ring-token-border backdrop-blur-xl";
16461
16535
  var OPTION_CLASSES2 = "flex w-full cursor-interaction items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-token-foreground outline-none enabled:hover:bg-token-list-hover-background enabled:active:bg-token-foreground/15 disabled:cursor-not-allowed disabled:opacity-40";
16462
16536
  function icon(node, size) {
@@ -16498,12 +16572,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16498
16572
  control.menu.style.left = `${left}px`;
16499
16573
  control.menu.style.bottom = `${Math.max(8, window.innerHeight - rect.top + 6)}px`;
16500
16574
  }
16501
- function syncRendererPermissionModeTriggerClass(control, nativeClassName) {
16502
- control.trigger.className = nativeClassName?.trim() || FALLBACK_TRIGGER_CLASSES;
16575
+ function syncRendererPermissionModeTriggerClass(control) {
16576
+ control.trigger.className = TRIGGER_CHIP_CLASS;
16503
16577
  control.trigger.style.maxWidth = "min(220px, 34vw)";
16504
16578
  control.trigger.style.letterSpacing = "0";
16505
16579
  }
16506
- function mountRendererPermissionModePicker(composerId, nativeClassName, onSelect) {
16580
+ function mountRendererPermissionModePicker(composerId, onSelect) {
16581
+ ensureRendererTriggerChipStyle(document);
16507
16582
  const root = document.createElement("div");
16508
16583
  root.setAttribute("data-codexhost-permission-mode-control", composerId);
16509
16584
  root.className = "relative min-w-0";
@@ -16513,6 +16588,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16513
16588
  trigger.setAttribute("aria-haspopup", "menu");
16514
16589
  trigger.setAttribute("aria-expanded", "false");
16515
16590
  trigger.setAttribute("data-state", "closed");
16591
+ trigger.style.height = "28px";
16592
+ trigger.style.padding = "0 6px";
16593
+ trigger.style.gap = "4px";
16594
+ trigger.style.font = "400 13px/18px system-ui, sans-serif";
16516
16595
  const shield = document.createElement("span");
16517
16596
  shield.className = "inline-flex shrink-0 items-center";
16518
16597
  shield.append(icon(Shield, 15));
@@ -16523,7 +16602,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16523
16602
  label.style.textOverflow = "ellipsis";
16524
16603
  label.style.whiteSpace = "nowrap";
16525
16604
  const chevron = document.createElement("span");
16526
- chevron.className = "inline-flex shrink-0 items-center text-token-text-tertiary";
16605
+ chevron.className = "inline-flex shrink-0 items-center";
16606
+ chevron.style.color = "var(--color-text-tertiary, #8f8f8f)";
16527
16607
  chevron.append(icon(ChevronDown, 14));
16528
16608
  trigger.append(shield, label, chevron);
16529
16609
  const menu = document.createElement("div");
@@ -16632,7 +16712,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16632
16712
  root.remove();
16633
16713
  }
16634
16714
  };
16635
- syncRendererPermissionModeTriggerClass(control, nativeClassName);
16715
+ syncRendererPermissionModeTriggerClass(control);
16636
16716
  return control;
16637
16717
  }
16638
16718
  function rebuildOptions2(control, catalog) {
@@ -16674,7 +16754,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16674
16754
  }
16675
16755
  }
16676
16756
  function renderRendererPermissionModePicker(control, view, visible) {
16677
- control.root.style.display = visible ? "block" : "none";
16757
+ control.root.style.display = visible ? "inline-flex" : "none";
16758
+ control.root.style.alignItems = "center";
16759
+ control.root.style.alignSelf = "center";
16760
+ control.root.style.height = "28px";
16761
+ control.root.style.flex = "0 0 auto";
16762
+ control.root.style.verticalAlign = "middle";
16678
16763
  if (!visible) {
16679
16764
  control.close();
16680
16765
  return;
@@ -16721,9 +16806,72 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16721
16806
  function formatRendererCreditsPercent(value) {
16722
16807
  return `${decimal(value, 1)}%`;
16723
16808
  }
16809
+ var SVG_NS = "http://www.w3.org/2000/svg";
16810
+ function createRendererUsageRing(percent, options) {
16811
+ const { size, strokeWidth, color } = options;
16812
+ const trackColor = options.trackColor ?? "color-mix(in srgb, currentColor 18%, transparent)";
16813
+ const radius = (size - strokeWidth) / 2;
16814
+ const circumference = 2 * Math.PI * radius;
16815
+ const clamped = Math.min(100, Math.max(0, percent));
16816
+ const offset = circumference * (1 - clamped / 100);
16817
+ const center = size / 2;
16818
+ const svg = document.createElementNS(SVG_NS, "svg");
16819
+ svg.setAttribute("width", String(size));
16820
+ svg.setAttribute("height", String(size));
16821
+ svg.setAttribute("viewBox", `0 0 ${size} ${size}`);
16822
+ svg.setAttribute("aria-hidden", "true");
16823
+ svg.style.display = "block";
16824
+ svg.style.flex = "0 0 auto";
16825
+ svg.style.transform = "rotate(-90deg)";
16826
+ const track = document.createElementNS(SVG_NS, "circle");
16827
+ track.setAttribute("cx", String(center));
16828
+ track.setAttribute("cy", String(center));
16829
+ track.setAttribute("r", String(radius));
16830
+ track.setAttribute("fill", "none");
16831
+ track.setAttribute("stroke", trackColor);
16832
+ track.setAttribute("stroke-width", String(strokeWidth));
16833
+ const fill = document.createElementNS(SVG_NS, "circle");
16834
+ fill.setAttribute("cx", String(center));
16835
+ fill.setAttribute("cy", String(center));
16836
+ fill.setAttribute("r", String(radius));
16837
+ fill.setAttribute("fill", "none");
16838
+ fill.setAttribute("stroke", color);
16839
+ fill.setAttribute("stroke-width", String(strokeWidth));
16840
+ fill.setAttribute("stroke-linecap", "round");
16841
+ fill.setAttribute("stroke-dasharray", String(circumference));
16842
+ fill.setAttribute("stroke-dashoffset", String(offset));
16843
+ svg.append(track, fill);
16844
+ return svg;
16845
+ }
16846
+ function formatRendererPlanReset(unixSeconds) {
16847
+ const date5 = new Date(unixSeconds * 1e3);
16848
+ if (Number.isNaN(date5.getTime())) return "";
16849
+ return date5.toLocaleString(void 0, {
16850
+ month: "long",
16851
+ day: "numeric",
16852
+ hour: "numeric",
16853
+ minute: "2-digit"
16854
+ });
16855
+ }
16856
+ function formatRendererPlanWindow(usedPercent, resetsAtUnix) {
16857
+ const percent = formatRendererCreditsPercent(usedPercent);
16858
+ if (resetsAtUnix === void 0) return percent;
16859
+ const reset = formatRendererPlanReset(resetsAtUnix);
16860
+ return reset.length > 0 ? `${percent} \xB7 ${reset}` : percent;
16861
+ }
16724
16862
  function rendererUsageTriggerMaxWidth() {
16725
16863
  return "min(180px, 30vw)";
16726
16864
  }
16865
+ function rendererUsageHasDisplayData(usage) {
16866
+ return usage?.cacheHitRatePercent !== void 0 || usage?.outputTokensPerSecond !== void 0 || usage?.totalCostUsd !== void 0 || usage?.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0 || usage?.totalTokens !== void 0 || usage?.inputTokens !== void 0 || usage?.cachedInputTokens !== void 0 || usage?.cacheWriteInputTokens !== void 0 || usage?.outputTokens !== void 0 || usage?.reasoningOutputTokens !== void 0 || usage?.planFiveHourUsedPercent !== void 0 || usage?.planSevenDayUsedPercent !== void 0;
16867
+ }
16868
+ function applyRendererPopoverChrome(popover) {
16869
+ popover.style.border = "1px solid light-dark(rgba(15, 23, 42, 0.10), color-mix(in srgb, CanvasText 16%, transparent))";
16870
+ popover.style.borderRadius = "14px";
16871
+ popover.style.backgroundColor = "light-dark(Canvas, color-mix(in srgb, Canvas 88%, white 12%))";
16872
+ popover.style.color = "CanvasText";
16873
+ 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))";
16874
+ }
16727
16875
  function addDetailRow(parent, label, value) {
16728
16876
  const row = document.createElement("div");
16729
16877
  row.style.display = "grid";
@@ -16774,6 +16922,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16774
16922
  if (usage?.reasoningOutputTokens !== void 0) {
16775
16923
  addDetailRow(popover, "Reasoning", formatRendererTokenCount(usage.reasoningOutputTokens));
16776
16924
  }
16925
+ if (usage?.totalTokens !== void 0) {
16926
+ addDetailRow(popover, "Total tokens", formatRendererTokenCount(usage.totalTokens));
16927
+ }
16777
16928
  if (usage?.inputTokens !== void 0 || usage?.outputTokens !== void 0) {
16778
16929
  addDetailRow(
16779
16930
  popover,
@@ -16781,6 +16932,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16781
16932
  `${formatRendererTokenCount(usage.inputTokens ?? 0)} / ${formatRendererTokenCount(usage.outputTokens ?? 0)}`
16782
16933
  );
16783
16934
  }
16935
+ if (usage?.planFiveHourUsedPercent !== void 0) {
16936
+ addDetailRow(
16937
+ popover,
16938
+ "5-hour limit",
16939
+ formatRendererPlanWindow(usage.planFiveHourUsedPercent, usage.planFiveHourResetsAtUnix)
16940
+ );
16941
+ }
16942
+ if (usage?.planSevenDayUsedPercent !== void 0) {
16943
+ addDetailRow(
16944
+ popover,
16945
+ "7-day limit",
16946
+ formatRendererPlanWindow(usage.planSevenDayUsedPercent, usage.planSevenDayResetsAtUnix)
16947
+ );
16948
+ }
16784
16949
  if (usage?.totalCostUsd !== void 0) {
16785
16950
  addDetailRow(popover, "Session cost estimate", formatRendererCost(usage.totalCostUsd));
16786
16951
  }
@@ -16821,34 +16986,35 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16821
16986
  if (control.trigger.getAttribute("aria-expanded") === "true") closePopover(control);
16822
16987
  else openPopover(control);
16823
16988
  }
16824
- function mountRendererUsageControl(composerId, nativeModelClassName) {
16989
+ function mountRendererUsageControl(composerId) {
16990
+ ensureRendererTriggerChipStyle(document);
16825
16991
  const root = document.createElement("div");
16826
16992
  root.dataset.codexhostUsageControl = composerId;
16827
16993
  root.className = "relative min-w-0";
16828
16994
  root.style.display = "none";
16995
+ root.style.alignItems = "center";
16996
+ root.style.alignSelf = "center";
16997
+ root.style.height = "28px";
16998
+ root.style.flex = "0 0 auto";
16999
+ root.style.verticalAlign = "middle";
16829
17000
  const trigger = document.createElement("button");
16830
- const syncNativeModelClassName = (className) => {
16831
- trigger.className = className?.trim() || RENDERER_MODEL_TRIGGER_FALLBACK_CLASSES;
16832
- };
16833
- syncNativeModelClassName(nativeModelClassName);
17001
+ trigger.className = TRIGGER_CHIP_CLASS;
16834
17002
  trigger.type = "button";
16835
17003
  trigger.setAttribute("aria-haspopup", "dialog");
16836
17004
  trigger.setAttribute("aria-expanded", "false");
16837
17005
  trigger.setAttribute("aria-label", "Thread Usage");
16838
17006
  trigger.title = "Thread Usage";
16839
- trigger.style.display = "inline-flex";
16840
- trigger.style.alignItems = "center";
17007
+ trigger.style.color = "var(--color-text-tertiary, #8f8f8f)";
17008
+ trigger.style.gap = "4px";
16841
17009
  trigger.style.width = "fit-content";
16842
17010
  trigger.style.maxWidth = rendererUsageTriggerMaxWidth();
16843
- trigger.style.height = "24px";
16844
- trigger.style.padding = "0 4px";
16845
- trigger.style.borderRadius = "9999px";
17011
+ trigger.style.height = "28px";
17012
+ trigger.style.padding = "0 8px";
17013
+ trigger.style.verticalAlign = "middle";
16846
17014
  trigger.style.fontSize = "12px";
16847
17015
  trigger.style.lineHeight = "16px";
16848
17016
  trigger.style.fontVariantNumeric = "tabular-nums";
16849
17017
  trigger.style.letterSpacing = "0";
16850
- trigger.style.whiteSpace = "nowrap";
16851
- trigger.style.cursor = "pointer";
16852
17018
  const label = document.createElement("span");
16853
17019
  label.style.display = "inline-block";
16854
17020
  label.style.maxWidth = "100%";
@@ -16867,11 +17033,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16867
17033
  popover.style.width = "260px";
16868
17034
  popover.style.maxWidth = "min(320px, calc(100vw - 24px))";
16869
17035
  popover.style.padding = "10px 12px";
16870
- popover.style.border = "1px solid rgba(127, 127, 127, 0.35)";
16871
- popover.style.borderRadius = "6px";
16872
- popover.style.background = "Canvas";
16873
- popover.style.color = "CanvasText";
16874
- popover.style.boxShadow = "0 8px 24px rgba(0, 0, 0, 0.28)";
17036
+ applyRendererPopoverChrome(popover);
16875
17037
  popover.style.font = "13px/1.35 system-ui, sans-serif";
16876
17038
  popover.style.letterSpacing = "0";
16877
17039
  popover.style.zIndex = "2147483647";
@@ -16883,7 +17045,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16883
17045
  popover,
16884
17046
  anchor: null,
16885
17047
  label,
16886
- syncNativeModelClassName,
16887
17048
  dispose() {
16888
17049
  closePopover(control);
16889
17050
  if (closeTimer !== null) window.clearTimeout(closeTimer);
@@ -16893,18 +17054,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16893
17054
  },
16894
17055
  place(anchor) {
16895
17056
  if (!anchor?.parentElement) return false;
16896
- let reference = anchor;
16897
- let container = anchor.parentElement;
16898
- while (container.parentElement && (getComputedStyle(container).display === "inline" || container.tagName === "SPAN" && container.attributes.length === 0)) {
16899
- reference = container;
16900
- container = container.parentElement;
16901
- }
16902
- if (control.anchor === anchor && placementReference === reference && root.parentElement === container && root.nextElementSibling === reference) {
17057
+ const container = anchor.parentElement;
17058
+ if (control.anchor === anchor && placementReference === anchor && root.parentElement === container && root.nextElementSibling === anchor) {
16903
17059
  return true;
16904
17060
  }
16905
17061
  control.anchor = anchor;
16906
- placementReference = reference;
16907
- container.insertBefore(root, reference);
17062
+ placementReference = anchor;
17063
+ container.insertBefore(root, anchor);
16908
17064
  return true;
16909
17065
  }
16910
17066
  };
@@ -16946,10 +17102,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16946
17102
  const cacheHitRatePercent = usage?.cacheHitRatePercent;
16947
17103
  const outputTokensPerSecond = usage?.outputTokensPerSecond;
16948
17104
  const totalCostUsd = usage?.totalCostUsd;
16949
- const hasCacheHitRate = cacheHitRatePercent !== void 0;
16950
- const hasOutputSpeed = outputTokensPerSecond !== void 0;
16951
- const hasCost = totalCostUsd !== void 0;
16952
- const visible = hasCacheHitRate || hasOutputSpeed || hasCost;
17105
+ const hasContext = usage?.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0;
17106
+ const hasTokenUsage = usage?.totalTokens !== void 0 || usage?.inputTokens !== void 0 || usage?.cachedInputTokens !== void 0 || usage?.cacheWriteInputTokens !== void 0 || usage?.outputTokens !== void 0 || usage?.reasoningOutputTokens !== void 0;
17107
+ const hasPlanLimit = usage?.planFiveHourUsedPercent !== void 0 || usage?.planSevenDayUsedPercent !== void 0;
17108
+ const visible = rendererUsageHasDisplayData(usage);
16953
17109
  control.root.style.display = visible ? "inline-flex" : "none";
16954
17110
  if (!visible) {
16955
17111
  closePopover(control);
@@ -16960,6 +17116,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16960
17116
  outputTokensPerSecond !== void 0 ? formatRendererTokenRate(outputTokensPerSecond) : null,
16961
17117
  totalCostUsd !== void 0 ? formatRendererCost(totalCostUsd) : null
16962
17118
  ].filter((value) => value !== null);
17119
+ if (summary.length === 0 && hasContext && usage?.contextWindowTokens !== void 0 && usage.contextWindowTokens > 0) {
17120
+ summary.push(
17121
+ `${decimal((usage.contextUsedTokens ?? 0) / usage.contextWindowTokens * 100, 1)}% context`
17122
+ );
17123
+ }
17124
+ if (summary.length === 0 && usage?.totalTokens !== void 0) {
17125
+ summary.push(`${formatRendererTokenCount(usage.totalTokens)} tokens`);
17126
+ }
17127
+ if (summary.length === 0 && hasTokenUsage) {
17128
+ summary.push(
17129
+ `${formatRendererTokenCount((usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0))} tokens`
17130
+ );
17131
+ }
17132
+ if (summary.length === 0 && hasPlanLimit) {
17133
+ summary.push(
17134
+ usage?.planFiveHourUsedPercent !== void 0 ? `5h ${formatRendererCreditsPercent(usage.planFiveHourUsedPercent)}` : `7d ${formatRendererCreditsPercent(usage?.planSevenDayUsedPercent ?? 0)}`
17135
+ );
17136
+ }
16963
17137
  const compactSummary = summary.join(" \xB7 ");
16964
17138
  const accessibleSummary = `Thread Usage: ${compactSummary}`;
16965
17139
  control.trigger.style.maxWidth = rendererUsageTriggerMaxWidth();
@@ -16976,11 +17150,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16976
17150
  if (usedPercent >= 70) return "warn";
16977
17151
  return "ok";
16978
17152
  }
16979
- function formatRendererCreditsReset(value) {
17153
+ function formatRendererCreditsReset(value, now = /* @__PURE__ */ new Date()) {
16980
17154
  const date5 = new Date(value);
16981
17155
  if (Number.isNaN(date5.getTime())) return value;
17156
+ const isToday = date5.getFullYear() === now.getFullYear() && date5.getMonth() === now.getMonth() && date5.getDate() === now.getDate();
17157
+ if (isToday) {
17158
+ return `${date5.toLocaleTimeString(void 0, { hour: "numeric", minute: "2-digit" })} today`;
17159
+ }
16982
17160
  return date5.toLocaleString(void 0, {
16983
- month: "long",
17161
+ month: "short",
16984
17162
  day: "numeric",
16985
17163
  hour: "numeric",
16986
17164
  minute: "2-digit"
@@ -16989,6 +17167,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16989
17167
  function creditsPeriodLabel(periodType) {
16990
17168
  if (periodType === "weekly") return "Weekly limit";
16991
17169
  if (periodType === "monthly") return "Monthly limit";
17170
+ if (periodType === "five_hour") return "5-hour limit";
17171
+ if (periodType === "seven_day") return "7-day limit";
16992
17172
  return "Account limit";
16993
17173
  }
16994
17174
  function productLabel(product) {
@@ -17003,40 +17183,97 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17003
17183
  if (tone === "warn") return "#c9a227";
17004
17184
  return "#3d9a64";
17005
17185
  }
17006
- function addDetailRow2(parent, label, value) {
17007
- const row = document.createElement("div");
17008
- row.style.display = "grid";
17009
- row.style.gridTemplateColumns = "minmax(0, 1fr) auto";
17010
- row.style.gap = "20px";
17011
- row.style.padding = "4px 0";
17012
- const labelElement = document.createElement("span");
17013
- labelElement.textContent = label;
17014
- labelElement.style.color = "color-mix(in srgb, currentColor 68%, transparent)";
17015
- const valueElement = document.createElement("span");
17016
- valueElement.textContent = value;
17017
- valueElement.style.fontVariantNumeric = "tabular-nums";
17018
- valueElement.style.textAlign = "right";
17019
- row.append(labelElement, valueElement);
17020
- parent.append(row);
17186
+ function renderCreditsBar(usagePercent, color) {
17187
+ const track = document.createElement("div");
17188
+ track.dataset.codexhostCreditsBar = "";
17189
+ track.style.height = "6px";
17190
+ track.style.borderRadius = "9999px";
17191
+ track.style.background = "color-mix(in srgb, currentColor 16%, transparent)";
17192
+ track.style.overflow = "hidden";
17193
+ const fill = document.createElement("span");
17194
+ fill.style.display = "block";
17195
+ fill.style.height = "100%";
17196
+ fill.style.borderRadius = "9999px";
17197
+ fill.style.width = `${Math.min(100, Math.max(0, usagePercent))}%`;
17198
+ fill.style.background = color;
17199
+ track.append(fill);
17200
+ return track;
17201
+ }
17202
+ function renderCreditsHeader(credits) {
17203
+ const wrapper = document.createElement("div");
17204
+ wrapper.style.marginBottom = "11px";
17205
+ const top = document.createElement("div");
17206
+ top.style.display = "flex";
17207
+ top.style.alignItems = "flex-start";
17208
+ top.style.justifyContent = "space-between";
17209
+ top.style.gap = "12px";
17210
+ top.style.marginBottom = "5px";
17211
+ const left = document.createElement("div");
17212
+ const label = document.createElement("div");
17213
+ label.textContent = creditsPeriodLabel(credits.periodType);
17214
+ label.style.fontSize = "12.5px";
17215
+ label.style.fontWeight = "600";
17216
+ left.append(label);
17217
+ if (credits.resetsAt) {
17218
+ const reset = document.createElement("div");
17219
+ reset.textContent = `resets ${formatRendererCreditsReset(credits.resetsAt)}`;
17220
+ reset.style.fontSize = "11px";
17221
+ reset.style.color = "color-mix(in srgb, currentColor 62%, transparent)";
17222
+ left.append(reset);
17223
+ }
17224
+ const color = toneColor(rendererCreditsTone(credits.usedPercent));
17225
+ const percent = document.createElement("span");
17226
+ percent.textContent = formatRendererCreditsPercent(credits.usedPercent);
17227
+ percent.style.fontSize = "26px";
17228
+ percent.style.fontWeight = "700";
17229
+ percent.style.fontVariantNumeric = "tabular-nums";
17230
+ percent.style.color = color;
17231
+ top.append(left, percent);
17232
+ wrapper.append(top, renderCreditsBar(credits.usedPercent, color));
17233
+ return wrapper;
17234
+ }
17235
+ function renderCreditsTile(label, usagePercent, resetsAt) {
17236
+ const color = toneColor(rendererCreditsTone(usagePercent));
17237
+ const tile = document.createElement("div");
17238
+ tile.style.marginBottom = "11px";
17239
+ const top = document.createElement("div");
17240
+ top.style.display = "flex";
17241
+ top.style.alignItems = "flex-start";
17242
+ top.style.justifyContent = "space-between";
17243
+ top.style.gap = "12px";
17244
+ top.style.marginBottom = "5px";
17245
+ const left = document.createElement("div");
17246
+ const name = document.createElement("span");
17247
+ name.textContent = label;
17248
+ name.style.fontSize = "12px";
17249
+ left.append(name);
17250
+ if (resetsAt) {
17251
+ const reset = document.createElement("div");
17252
+ reset.textContent = `resets ${formatRendererCreditsReset(resetsAt)}`;
17253
+ reset.style.fontSize = "10.5px";
17254
+ reset.style.color = "color-mix(in srgb, currentColor 62%, transparent)";
17255
+ left.append(reset);
17256
+ }
17257
+ const percent = document.createElement("span");
17258
+ percent.textContent = formatRendererCreditsPercent(usagePercent);
17259
+ percent.style.fontSize = "12px";
17260
+ percent.style.fontVariantNumeric = "tabular-nums";
17261
+ percent.style.color = color;
17262
+ top.append(left, percent);
17263
+ tile.append(top, renderCreditsBar(usagePercent, color));
17264
+ return tile;
17021
17265
  }
17022
17266
  function renderDetails2(popover, credits) {
17267
+ const glowColor = toneColor(rendererCreditsTone(credits.usedPercent));
17268
+ popover.style.backgroundImage = `radial-gradient(160px 100px at 18% -10%, color-mix(in srgb, ${glowColor} 20%, transparent), transparent 70%)`;
17023
17269
  popover.replaceChildren();
17024
- const heading = document.createElement("div");
17025
- heading.textContent = creditsPeriodLabel(credits.periodType);
17026
- heading.style.fontWeight = "600";
17027
- heading.style.marginBottom = "6px";
17028
- popover.append(heading);
17029
- addDetailRow2(popover, "Used", formatRendererCreditsPercent(credits.usedPercent));
17030
- if (credits.resetsAt) {
17031
- addDetailRow2(popover, "Resets", formatRendererCreditsReset(credits.resetsAt));
17032
- }
17033
- for (const product of credits.productUsage ?? []) {
17034
- addDetailRow2(
17035
- popover,
17036
- productLabel(product.product),
17037
- formatRendererCreditsPercent(product.usagePercent)
17038
- );
17039
- }
17270
+ popover.append(renderCreditsHeader(credits));
17271
+ const tiles = (credits.productUsage ?? []).map(
17272
+ (product) => renderCreditsTile(productLabel(product.product), product.usagePercent, product.resetsAt)
17273
+ );
17274
+ const lastTile = tiles.at(-1);
17275
+ if (lastTile) lastTile.style.marginBottom = "0";
17276
+ popover.append(...tiles);
17040
17277
  }
17041
17278
  function popoverIsOpen2(popover) {
17042
17279
  try {
@@ -17074,43 +17311,38 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17074
17311
  if (control.trigger.getAttribute("aria-expanded") === "true") closePopover2(control);
17075
17312
  else openPopover2(control);
17076
17313
  }
17077
- function mountRendererCreditsControl(composerId, nativeModelClassName) {
17314
+ function mountRendererCreditsControl(composerId) {
17315
+ ensureRendererTriggerChipStyle(document);
17078
17316
  const root = document.createElement("div");
17079
17317
  root.dataset.codexhostCreditsControl = composerId;
17080
17318
  root.className = "relative min-w-0";
17081
17319
  root.style.display = "none";
17320
+ root.style.alignItems = "center";
17321
+ root.style.alignSelf = "center";
17322
+ root.style.height = "28px";
17323
+ root.style.flex = "0 0 auto";
17324
+ root.style.verticalAlign = "middle";
17082
17325
  const trigger = document.createElement("button");
17083
- const syncNativeModelClassName = (className) => {
17084
- trigger.className = className?.trim() || RENDERER_MODEL_TRIGGER_FALLBACK_CLASSES;
17085
- };
17086
- syncNativeModelClassName(nativeModelClassName);
17326
+ trigger.className = TRIGGER_CHIP_CLASS;
17087
17327
  trigger.type = "button";
17088
17328
  trigger.setAttribute("aria-haspopup", "dialog");
17089
17329
  trigger.setAttribute("aria-expanded", "false");
17090
17330
  trigger.setAttribute("aria-label", "Account limit");
17091
17331
  trigger.title = "Account limit";
17092
- trigger.style.display = "inline-flex";
17093
- trigger.style.alignItems = "center";
17094
17332
  trigger.style.gap = "5px";
17095
17333
  trigger.style.width = "fit-content";
17096
17334
  trigger.style.maxWidth = "min(72px, 18vw)";
17097
- trigger.style.height = "24px";
17098
- trigger.style.padding = "0 6px";
17099
- trigger.style.borderRadius = "9999px";
17335
+ trigger.style.height = "28px";
17336
+ trigger.style.padding = "0 8px";
17337
+ trigger.style.verticalAlign = "middle";
17100
17338
  trigger.style.fontSize = "12px";
17101
17339
  trigger.style.lineHeight = "16px";
17102
17340
  trigger.style.fontVariantNumeric = "tabular-nums";
17103
17341
  trigger.style.letterSpacing = "0";
17104
- trigger.style.whiteSpace = "nowrap";
17105
- trigger.style.cursor = "pointer";
17106
- const dot = document.createElement("span");
17107
- dot.dataset.codexhostCreditsDot = "";
17108
- dot.setAttribute("aria-hidden", "true");
17109
- dot.style.display = "inline-block";
17110
- dot.style.width = "7px";
17111
- dot.style.height = "7px";
17112
- dot.style.borderRadius = "9999px";
17113
- dot.style.flex = "0 0 auto";
17342
+ const ringSlot = document.createElement("span");
17343
+ ringSlot.dataset.codexhostCreditsRing = "";
17344
+ ringSlot.style.display = "inline-flex";
17345
+ ringSlot.style.flex = "0 0 auto";
17114
17346
  const label = document.createElement("span");
17115
17347
  label.dataset.codexhostCreditsLabel = "";
17116
17348
  label.style.display = "inline-block";
@@ -17118,7 +17350,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17118
17350
  label.style.overflow = "hidden";
17119
17351
  label.style.textOverflow = "ellipsis";
17120
17352
  label.style.whiteSpace = "nowrap";
17121
- trigger.append(dot, label);
17353
+ trigger.append(ringSlot, label);
17122
17354
  const popover = document.createElement("div");
17123
17355
  popover.id = `${composerId}-credits-popover`;
17124
17356
  popover.setAttribute("role", "dialog");
@@ -17130,11 +17362,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17130
17362
  popover.style.width = "240px";
17131
17363
  popover.style.maxWidth = "min(280px, calc(100vw - 24px))";
17132
17364
  popover.style.padding = "10px 12px";
17133
- popover.style.border = "1px solid rgba(127, 127, 127, 0.35)";
17134
- popover.style.borderRadius = "6px";
17135
- popover.style.background = "Canvas";
17136
- popover.style.color = "CanvasText";
17137
- popover.style.boxShadow = "0 8px 24px rgba(0, 0, 0, 0.28)";
17365
+ applyRendererPopoverChrome(popover);
17138
17366
  popover.style.font = "13px/1.35 system-ui, sans-serif";
17139
17367
  popover.style.letterSpacing = "0";
17140
17368
  popover.style.zIndex = "2147483647";
@@ -17145,7 +17373,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17145
17373
  trigger,
17146
17374
  popover,
17147
17375
  anchor: null,
17148
- syncNativeModelClassName,
17149
17376
  dispose() {
17150
17377
  closePopover2(control);
17151
17378
  if (closeTimer !== null) window.clearTimeout(closeTimer);
@@ -17156,14 +17383,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17156
17383
  place(anchor) {
17157
17384
  if (!anchor?.parentElement) return false;
17158
17385
  const parent = anchor.parentElement;
17159
- const next = anchor.nextElementSibling;
17160
- if (control.anchor === anchor && placementReference === anchor && root.parentElement === parent && root.previousElementSibling === anchor) {
17386
+ if (control.anchor === anchor && placementReference === anchor && root.parentElement === parent && root.nextElementSibling === anchor) {
17161
17387
  return true;
17162
17388
  }
17163
17389
  control.anchor = anchor;
17164
17390
  placementReference = anchor;
17165
- if (next && next !== root) parent.insertBefore(root, next);
17166
- else if (next !== root) parent.append(root);
17391
+ if (root !== anchor) parent.insertBefore(root, anchor);
17167
17392
  return true;
17168
17393
  }
17169
17394
  };
@@ -17209,9 +17434,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17209
17434
  const percent = formatRendererCreditsPercent(accountCredits.usedPercent);
17210
17435
  const title = `${creditsPeriodLabel(accountCredits.periodType)} ${percent}`;
17211
17436
  const tone = rendererCreditsTone(accountCredits.usedPercent);
17212
- const dot = control.trigger.querySelector("[data-codexhost-credits-dot]");
17437
+ const ringSlot = control.trigger.querySelector("[data-codexhost-credits-ring]");
17213
17438
  const label = control.trigger.querySelector("[data-codexhost-credits-label]");
17214
- if (dot) dot.style.background = toneColor(tone);
17439
+ if (ringSlot) {
17440
+ ringSlot.replaceChildren(
17441
+ createRendererUsageRing(accountCredits.usedPercent, {
17442
+ size: 14,
17443
+ strokeWidth: 2.4,
17444
+ color: toneColor(tone)
17445
+ })
17446
+ );
17447
+ }
17215
17448
  if (label) label.textContent = percent;
17216
17449
  control.root.style.display = "inline-flex";
17217
17450
  control.trigger.setAttribute("aria-label", title);
@@ -17226,21 +17459,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17226
17459
  var MENU_WIDTH = 320;
17227
17460
  var VIEWPORT_MARGIN = 8;
17228
17461
  var MENU_GAP2 = 8;
17229
- var SVG_NS = "http://www.w3.org/2000/svg";
17462
+ var SVG_NS2 = "http://www.w3.org/2000/svg";
17230
17463
  var COMMAND_ICON_PATHS = [
17231
17464
  "M409.6 377.6h204.8a32 32 0 0 1 32 32v204.8a32 32 0 0 1-32 32H409.6a32 32 0 0 1-32-32V409.6a32 32 0 0 1 32-32z m172.8 64h-140.8v140.8h140.8z",
17232
17465
  "M332.8 800a108.8 108.8 0 0 1 0-217.6h76.8a32 32 0 0 1 32 32v76.8a108.928 108.928 0 0 1-108.8 108.8z m0-153.6a44.8 44.8 0 1 0 44.8 44.8v-44.8zM409.6 441.6H332.8a108.8 108.8 0 1 1 108.8-108.8v76.8a32 32 0 0 1-32 32z m-76.8-153.6a44.8 44.8 0 0 0 0 89.6h44.8V332.8A44.842667 44.842667 0 0 0 332.8 288zM691.2 441.6h-76.8a32 32 0 0 1-32-32V332.8a108.8 108.8 0 1 1 108.8 108.8z m-44.8-64h44.8a44.8 44.8 0 1 0-44.8-44.8zM691.2 800a108.928 108.928 0 0 1-108.8-108.8v-76.8a32 32 0 0 1 32-32h76.8a108.8 108.8 0 0 1 0 217.6z m-44.8-153.6v44.8a44.8 44.8 0 1 0 44.8-44.8z",
17233
17466
  "M640 970.666667H384c-118.186667 0-198.272-25.002667-251.946667-78.72S53.333333 758.186667 53.333333 640V384c0-118.186667 25.002667-198.272 78.72-251.946667S265.813333 53.333333 384 53.333333h256c118.186667 0 198.272 25.002667 251.946667 78.72S970.666667 265.813333 970.666667 384v256c0 118.186667-25.002667 198.272-78.72 251.946667S758.186667 970.666667 640 970.666667z m-256-853.333334c-100.096 0-165.802667 19.2-206.72 59.946667S117.333333 283.904 117.333333 384v256c0 100.096 19.072 165.802667 59.946667 206.72S283.904 906.666667 384 906.666667h256c100.096 0 165.802667-19.072 206.72-59.946667S906.666667 740.096 906.666667 640V384c0-100.096-19.072-165.802667-59.946667-206.72S740.096 117.333333 640 117.333333z"
17234
17467
  ];
17235
17468
  function commandIcon(ownerDocument) {
17236
- const svg = ownerDocument.createElementNS(SVG_NS, "svg");
17469
+ const svg = ownerDocument.createElementNS(SVG_NS2, "svg");
17237
17470
  svg.setAttribute("viewBox", "0 0 1024 1024");
17238
17471
  svg.setAttribute("width", "15");
17239
17472
  svg.setAttribute("height", "15");
17240
17473
  svg.setAttribute("fill", "currentColor");
17241
17474
  svg.setAttribute("aria-hidden", "true");
17242
17475
  for (const path of COMMAND_ICON_PATHS) {
17243
- const element = ownerDocument.createElementNS(SVG_NS, "path");
17476
+ const element = ownerDocument.createElementNS(SVG_NS2, "path");
17244
17477
  element.setAttribute("d", path);
17245
17478
  svg.append(element);
17246
17479
  }
@@ -17560,7 +17793,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17560
17793
  }
17561
17794
  var VOICE_CONTROL_PATTERN = /(dictat|microphone|speech(?:[-_\s]?to[-_\s]?text)?|voice[-_\s]?input|(^|\s)voice(\s|$)|composer[-_](?:speech|dictat|mic)|语音|听写|麦克风|pause|暂停|stop recording|stop dictation|停止录音|停止听写|(^|\s)stop(\s|$))/iu;
17562
17795
  var CANCEL_CONTROL_PATTERN = /(cancel|discard|close|dismiss|取消|关闭|丢弃)/iu;
17563
- var ATTACH_CONTROL_PATTERN = /(add files|attach files|attach file|attachment|composer[-_]attach|添加文件|附件)/iu;
17564
17796
  var TRAILING_ACTION_WALK_DEPTH = 3;
17565
17797
  function isComposerCancelButton(element) {
17566
17798
  if (isOwnedRendererControl(element)) return false;
@@ -17572,10 +17804,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17572
17804
  if (/(^|\s)(send|submit|发送|提交)(\s|$)/u.test(description)) return false;
17573
17805
  return VOICE_CONTROL_PATTERN.test(description);
17574
17806
  }
17575
- function isComposerAttachButton(element) {
17576
- if (isOwnedRendererControl(element)) return false;
17577
- return ATTACH_CONTROL_PATTERN.test(controlDescription(element));
17578
- }
17579
17807
  function isComposerTrailingActionButton(element) {
17580
17808
  return isComposerVoiceButton(element) || isComposerSubmitButton(element);
17581
17809
  }
@@ -17586,14 +17814,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17586
17814
  const buttons = [...element.querySelectorAll("button")];
17587
17815
  return buttons.length > 0 && buttons.every((button) => isComposerTrailingActionButton(button));
17588
17816
  }
17589
- function attachControlWithin(root) {
17590
- if (isComposerAttachButton(root)) return root;
17591
- if (typeof root.querySelectorAll !== "function") return null;
17592
- const matches = [
17593
- ...root.querySelectorAll("button, [aria-label], [title], [data-testid]")
17594
- ].filter(isComposerAttachButton);
17595
- return matches.length === 1 ? matches[0] ?? null : null;
17596
- }
17597
17817
  function sendButtonWithin(root) {
17598
17818
  return [...root.querySelectorAll("button")].find(
17599
17819
  (button) => isComposerSubmitButton(button)
@@ -17708,23 +17928,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17708
17928
  ].filter((element) => isNativeModelControlCandidate(element));
17709
17929
  return candidates.length === 1 ? candidates[0] ?? null : null;
17710
17930
  }
17711
- var contextUsageDescriptionPattern = /(context|token|上下文|令牌)/iu;
17712
17931
  function isNativeContextUsageControlCandidate(element) {
17713
17932
  if (element.hasAttribute("data-codexhost-usage-control") || element.hasAttribute("data-codexhost-credits-control")) {
17714
17933
  return false;
17715
17934
  }
17716
- const description = [
17717
- element.getAttribute("aria-label"),
17718
- element.getAttribute("title"),
17719
- element.getAttribute("data-testid")
17720
- ].filter((value) => value !== null).join(" ");
17721
- return contextUsageDescriptionPattern.test(description);
17935
+ return element.matches('span[role="img"][aria-label]') && element.querySelectorAll("svg > circle").length === 2;
17722
17936
  }
17723
17937
  function nativeContextUsageControlForComposer(composer) {
17724
17938
  const candidates = [
17725
- ...composer.querySelectorAll(
17726
- 'button, [role="button"], [aria-label], [title], [data-testid]'
17727
- )
17939
+ ...composer.querySelectorAll('span[role="img"][aria-label]')
17728
17940
  ].filter(isNativeContextUsageControlCandidate);
17729
17941
  return candidates.length === 1 ? candidates[0] ?? null : null;
17730
17942
  }
@@ -17741,53 +17953,29 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17741
17953
  if (state.ariaHidden === null) state.element.removeAttribute("aria-hidden");
17742
17954
  else state.element.setAttribute("aria-hidden", state.ariaHidden);
17743
17955
  }
17956
+ function refreshNativeContextUsageControl(control) {
17957
+ const candidate = nativeContextUsageControlForComposer(control.composer);
17958
+ if (candidate === control.nativeContextUsageControl?.element) return;
17959
+ restoreNativeControl(control.nativeContextUsageControl);
17960
+ control.nativeContextUsageControl = captureNativeControl(candidate);
17961
+ }
17744
17962
  function refreshNativeModelControl(control) {
17745
17963
  const candidate = nativeModelControlForComposer(control.composer);
17746
- if (!candidate) {
17747
- control.usage.syncNativeModelClassName();
17748
- control.credits.syncNativeModelClassName();
17749
- return;
17750
- }
17964
+ if (!candidate) return;
17751
17965
  if (candidate !== control.nativeModelControl?.element) {
17752
17966
  restoreNativeControl(control.nativeModelControl);
17753
17967
  control.nativeModelControl = captureNativeControl(candidate);
17754
- syncRendererModelTriggerClass(control.modelPicker, candidate.className);
17968
+ syncRendererModelTriggerClass(control.modelPicker);
17755
17969
  }
17756
- control.usage.syncNativeModelClassName(candidate.className);
17757
- control.credits.syncNativeModelClassName(candidate.className);
17758
17970
  }
17759
17971
  function usagePlacementAnchor(control) {
17760
- const context = nativeContextUsageControlForComposer(control.composer);
17761
- if (context?.parentElement) return context;
17762
- const modelRoot = control.modelPicker.root;
17763
- if (modelRoot.parentElement) return modelRoot;
17764
- const native = control.nativeModelControl?.element;
17765
- return native?.parentElement ? native : null;
17766
- }
17767
- function firstMaterialChild(parent) {
17768
- for (const child of parent.children) {
17769
- if (typeof child.hasAttribute !== "function") continue;
17770
- const element = child;
17771
- if (element.hasAttribute("data-codexhost-credits-control") || element.hasAttribute("data-codexhost-harness-command-control") || isTrailingActionNode(element)) {
17772
- continue;
17773
- }
17774
- return element;
17775
- }
17776
- return null;
17972
+ const context = control.nativeContextUsageControl?.element;
17973
+ const contextWrapper = context?.parentElement;
17974
+ return contextWrapper?.parentElement ? contextWrapper : null;
17777
17975
  }
17778
- function creditsPlacementAnchor(composer, usageRoot) {
17779
- let current = usageRoot;
17780
- while (current && current !== composer) {
17781
- const parent = current.parentElement;
17782
- if (!parent) break;
17783
- const first = firstMaterialChild(parent);
17784
- if (first && first !== current && !first.contains(usageRoot)) {
17785
- return attachControlWithin(first) ?? first;
17786
- }
17787
- if (parent === composer) break;
17788
- current = parent;
17789
- }
17790
- return null;
17976
+ function creditsPlacementAnchor(control) {
17977
+ const root = control.permissionModePicker?.root;
17978
+ return root?.parentElement ? root : null;
17791
17979
  }
17792
17980
  function refreshTrailingClusterPlacement(control) {
17793
17981
  const sendButton = control.sendButton;
@@ -17805,11 +17993,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17805
17993
  }
17806
17994
  function refreshUsagePlacement(control) {
17807
17995
  const anchor = usagePlacementAnchor(control);
17808
- if (!anchor) {
17809
- if (control.usage.anchor) control.usage.root.remove();
17810
- control.usage.anchor = null;
17811
- if (control.credits.anchor) control.credits.root.remove();
17812
- control.credits.anchor = null;
17996
+ if (!anchor || !control.usage) {
17997
+ if (control.usage?.anchor) control.usage.root.remove();
17998
+ if (control.usage) control.usage.anchor = null;
17813
17999
  return;
17814
18000
  }
17815
18001
  const previousUsageParent = control.usage.root.parentElement;
@@ -17817,13 +18003,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17817
18003
  control.usage.place(anchor);
17818
18004
  const usagePositionChanged = previousUsageParent !== control.usage.root.parentElement || previousUsageNextSibling !== control.usage.root.nextElementSibling;
17819
18005
  if (usagePositionChanged) control.harnessCommands?.placeBefore(control.usage.root);
17820
- const leading = creditsPlacementAnchor(control.composer, control.usage.root);
17821
- if (!leading) {
18006
+ }
18007
+ function refreshCreditsPlacement(control) {
18008
+ const anchor = creditsPlacementAnchor(control);
18009
+ if (!anchor) {
17822
18010
  if (control.credits.anchor) control.credits.root.remove();
17823
18011
  control.credits.anchor = null;
17824
18012
  return;
17825
18013
  }
17826
- control.credits.place(leading);
18014
+ control.credits.place(anchor);
17827
18015
  }
17828
18016
  function refreshNativePermissionModeControl(control) {
17829
18017
  const semanticCandidate = semanticNativePermissionModeControlForComposer(control.composer);
@@ -17834,7 +18022,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17834
18022
  const candidate = nativePermissionModeControlForComposer(control.composer);
17835
18023
  control.nativePermissionModeControlVerified = candidate === semanticCandidate && candidate !== null;
17836
18024
  if (!candidate) return;
17837
- syncRendererPermissionModeTriggerClass(control.permissionModePicker, candidate.className);
18025
+ syncRendererPermissionModeTriggerClass(control.permissionModePicker);
17838
18026
  const parent = candidate.parentElement;
17839
18027
  if (parent && (control.permissionModePicker.root.parentElement !== parent || control.permissionModePicker.root.nextElementSibling !== candidate)) {
17840
18028
  parent.insertBefore(control.permissionModePicker.root, candidate);
@@ -17847,39 +18035,40 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17847
18035
  return;
17848
18036
  }
17849
18037
  if (state.element.hidden && state.element.getAttribute("aria-hidden") === "true") return;
17850
- const active = document.activeElement;
17851
- if (active instanceof HTMLElement && state.element.contains(active)) active.blur();
18038
+ const active = typeof document !== "undefined" ? document.activeElement : null;
18039
+ if (active && typeof active.blur === "function" && state.element.contains(active)) {
18040
+ active.blur();
18041
+ }
17852
18042
  if (state.element.getAttribute("aria-expanded") === "true") state.element.click();
17853
18043
  state.element.hidden = true;
17854
18044
  state.element.setAttribute("aria-hidden", "true");
17855
18045
  }
17856
18046
  function reconcileComposerNativeControls(control, hideModel, hidePermissionMode) {
18047
+ refreshNativeContextUsageControl(control);
17857
18048
  refreshNativeModelControl(control);
18049
+ refreshNativePermissionModeControl(control);
17858
18050
  refreshTrailingClusterPlacement(control);
17859
18051
  refreshUsagePlacement(control);
17860
- refreshNativePermissionModeControl(control);
18052
+ refreshCreditsPlacement(control);
17861
18053
  setNativeControlHidden(control.nativeModelControl, hideModel);
18054
+ setNativeControlHidden(control.nativeContextUsageControl, false);
17862
18055
  setNativeControlHidden(control.nativePermissionModeControl, hidePermissionMode);
17863
18056
  }
17864
18057
  function mountComposerAgentControl(composer, composerId, sendButton, enabledAgents, onSelect, onDownload, onSelectModel, onSelectThinking, onSelectPermissionMode, onSelectCommand) {
17865
18058
  const nativeModelControl = captureNativeControl(nativeModelControlForComposer(composer));
18059
+ const nativeContextUsageControl = captureNativeControl(
18060
+ nativeContextUsageControlForComposer(composer)
18061
+ );
17866
18062
  const semanticNativePermissionModeControl = semanticNativePermissionModeControlForComposer(composer);
17867
18063
  const nativePermissionModeControl = captureNativeControl(semanticNativePermissionModeControl);
17868
18064
  const nativePermissionModeControlVerified = semanticNativePermissionModeControl !== null && nativePermissionModeControlForComposer(composer) === semanticNativePermissionModeControl;
17869
18065
  const picker = mountRendererAgentPicker(composerId, enabledAgents, onSelect, onDownload);
17870
- const modelPicker = mountRendererModelPicker(
17871
- composerId,
17872
- nativeModelControl?.element.className,
17873
- onSelectModel,
17874
- onSelectThinking
17875
- );
18066
+ const modelPicker = mountRendererModelPicker(composerId, onSelectModel, onSelectThinking);
17876
18067
  const permissionModePicker = mountRendererPermissionModePicker(
17877
18068
  composerId,
17878
- nativePermissionModeControl?.element.className,
17879
18069
  onSelectPermissionMode
17880
18070
  );
17881
- const usage = mountRendererUsageControl(composerId, nativeModelControl?.element.className);
17882
- const credits = mountRendererCreditsControl(composerId, nativeModelControl?.element.className);
18071
+ const credits = mountRendererCreditsControl(composerId);
17883
18072
  const toolbar = sendButton.parentElement;
17884
18073
  const harnessCommands = mountRendererHarnessCommandControl(
17885
18074
  toolbar ?? composer,
@@ -17895,24 +18084,30 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17895
18084
  if (!toolbar) composer.append(modelPicker.root, picker.root);
17896
18085
  const control = {
17897
18086
  composer,
18087
+ composerId,
17898
18088
  root: picker.root,
17899
18089
  picker,
17900
18090
  modelPicker,
17901
18091
  permissionModePicker,
17902
18092
  nativeModelControl,
17903
18093
  nativePermissionModeControl,
18094
+ nativeContextUsageControl,
17904
18095
  nativePermissionModeControlVerified,
17905
18096
  credits,
17906
- usage,
18097
+ usage: null,
17907
18098
  harnessCommands,
17908
18099
  sendButton,
17909
18100
  sendDisabledBeforeSwitch: null
17910
18101
  };
17911
18102
  refreshTrailingClusterPlacement(control);
17912
18103
  refreshUsagePlacement(control);
18104
+ refreshCreditsPlacement(control);
17913
18105
  return control;
17914
18106
  }
17915
18107
  function renderComposerAgentControl(control, state, adapterState, switching, availability = {}, modelView = { status: "idle" }, permissionModeView = { status: "idle" }, usage = null, accountCredits = null) {
18108
+ if (control.usage === null) {
18109
+ control.usage = mountRendererUsageControl(control.composerId);
18110
+ }
17916
18111
  const selectedModel = modelView.selected;
17917
18112
  const selectedCatalogModel = modelView.catalog?.models.find(
17918
18113
  (model) => model.ref.id === selectedModel?.id
@@ -17949,7 +18144,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17949
18144
  permissionModeView,
17950
18145
  permissionModeVisible
17951
18146
  );
17952
- renderRendererUsageControl(control.usage, usage);
18147
+ if (control.usage) renderRendererUsageControl(control.usage, usage);
17953
18148
  renderRendererCreditsControl(control.credits, accountCredits);
17954
18149
  }
17955
18150
  function disposeComposerAgentControl(control) {
@@ -17957,9 +18152,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17957
18152
  control.sendButton.disabled = control.sendDisabledBeforeSwitch;
17958
18153
  }
17959
18154
  restoreNativeControl(control.nativeModelControl);
18155
+ restoreNativeControl(control.nativeContextUsageControl);
17960
18156
  restoreNativeControl(control.nativePermissionModeControl);
17961
18157
  control.credits.dispose();
17962
- control.usage.dispose();
18158
+ control.usage?.dispose();
18159
+ control.usage = null;
17963
18160
  control.harnessCommands.dispose();
17964
18161
  control.permissionModePicker.dispose();
17965
18162
  control.modelPicker.dispose();
@@ -21274,6 +21471,8 @@ ${error51.stderrTail}`] : []
21274
21471
  clearUpdateRetry();
21275
21472
  retryUpdateClient = client;
21276
21473
  updateRetryAttempt = 0;
21474
+ } else if (updateRetryTimer !== null) {
21475
+ return;
21277
21476
  }
21278
21477
  checkedUpdateClient = client;
21279
21478
  const generation = ++updateCheckGeneration;
@@ -21353,15 +21552,33 @@ ${error51.stderrTail}`] : []
21353
21552
  "deepseek-harness",
21354
21553
  "grok"
21355
21554
  ];
21555
+ function isRetryableHarnessAvailability(availability, error51) {
21556
+ return availability !== void 0 && availability !== "ready" && availability !== "notInstalled" && error51?.retryable === true;
21557
+ }
21558
+ function retryableHarnessAvailabilityAgents(availability, errors) {
21559
+ return externalAgents.filter(
21560
+ (agent) => isRetryableHarnessAvailability(availability[agent], errors[agent])
21561
+ );
21562
+ }
21563
+ function passiveHarnessAvailabilityAgents(availability, errors) {
21564
+ return externalAgents.filter(
21565
+ (agent) => availability[agent] === "checking" || isRetryableHarnessAvailability(availability[agent], errors[agent])
21566
+ );
21567
+ }
21356
21568
  var rendererUsageRefreshDelays = [250, 500, 1e3, 2e3, 4e3, 8e3];
21357
21569
  function rendererUsageRefreshDelay(attempt) {
21358
21570
  const index = Math.max(0, Math.min(Math.trunc(attempt), rendererUsageRefreshDelays.length - 1));
21359
21571
  return rendererUsageRefreshDelays[index] ?? rendererUsageRefreshDelays[0];
21360
21572
  }
21573
+ function externalAgentHasAccountCredits(agent) {
21574
+ return agent === "codex" || agent === "grok" || agent === "claude-code";
21575
+ }
21361
21576
  function shouldRetryExternalThreadUsage(agent, usage, accountCredits = null) {
21362
- if (agent === "codex") return false;
21363
21577
  if (usage === null) return true;
21364
- return agent === "grok" && accountCredits === null;
21578
+ return externalAgentHasAccountCredits(agent) && accountCredits === null;
21579
+ }
21580
+ function shouldReloadExternalCatalogAfterAvailabilityRefresh(previous, next, configurationReady) {
21581
+ return previous !== next || !configurationReady;
21365
21582
  }
21366
21583
  function selectableThinkingOptionId(state) {
21367
21584
  return state.effectiveThinkingOptionId && state.availableThinkingOptions?.some(({ id }) => id === state.effectiveThinkingOptionId) ? state.effectiveThinkingOptionId : void 0;
@@ -21662,7 +21879,7 @@ ${error51.stderrTail}`] : []
21662
21879
  };
21663
21880
  const refreshThreadUsage = async (mounted) => {
21664
21881
  const threadId = threadIdFromComposerModelTarget(mounted.modelTarget);
21665
- if (!threadId || !modelControl || controller.get(mounted.composer).agent === "codex") {
21882
+ if (!threadId || !modelControl) {
21666
21883
  mounted.usage = null;
21667
21884
  mounted.accountCredits = null;
21668
21885
  usageRefreshAttempts.delete(mounted.composer);
@@ -21678,7 +21895,7 @@ ${error51.stderrTail}`] : []
21678
21895
  mounted.usage = result.usage;
21679
21896
  mounted.accountCredits = result.accountCredits ?? null;
21680
21897
  const agent = controller.get(mounted.composer).agent;
21681
- if (result.usage !== null && (agent !== "grok" || result.accountCredits)) {
21898
+ if (result.usage !== null && (!externalAgentHasAccountCredits(agent) || result.accountCredits)) {
21682
21899
  usageRefreshAttempts.delete(mounted.composer);
21683
21900
  }
21684
21901
  renderMounted(mounted);
@@ -21787,12 +22004,13 @@ ${error51.stderrTail}`] : []
21787
22004
  renderMounted(mounted);
21788
22005
  if (mounted.ownershipStatus !== "error") void refreshCommands(mounted);
21789
22006
  sidebarAgentIcons.refresh();
21790
- if (mounted.ownershipStatus !== "error" && shouldRetryExternalThreadUsage(
21791
- controller.get(mounted.composer).agent,
21792
- mounted.usage,
21793
- mounted.accountCredits
21794
- )) {
21795
- scheduleThreadUsageRefresh(mounted);
22007
+ if (mounted.ownershipStatus !== "error") {
22008
+ const agent = controller.get(mounted.composer).agent;
22009
+ if (agent === "codex" && mounted.usage === null) {
22010
+ void refreshThreadUsage(mounted);
22011
+ } else if (shouldRetryExternalThreadUsage(agent, mounted.usage, mounted.accountCredits)) {
22012
+ scheduleThreadUsageRefresh(mounted);
22013
+ }
21796
22014
  }
21797
22015
  }
21798
22016
  }
@@ -22432,7 +22650,7 @@ ${error51.stderrTail}`] : []
22432
22650
  const currentHostId = modelControl.currentHostId?.() ?? "local";
22433
22651
  return currentHostId === hostId ? modelControl : null;
22434
22652
  }
22435
- function refreshHarnessAvailabilityForHost(hostId, refresh = false, retry = false) {
22653
+ function refreshHarnessAvailabilityForHost(hostId, refresh = false, retry = false, force = false) {
22436
22654
  const state = hostHarnessAvailabilityState(hostId);
22437
22655
  if (!retry) resetHarnessAvailabilityRetry(hostId);
22438
22656
  const client = modelClientForHost(hostId);
@@ -22441,12 +22659,16 @@ ${error51.stderrTail}`] : []
22441
22659
  return Promise.resolve();
22442
22660
  }
22443
22661
  if (state.request?.client === client) return state.request.promise;
22444
- state.availability = Object.fromEntries(
22445
- externalAgents.map((agent) => [
22446
- agent,
22447
- state.availability[agent] === "ready" ? "ready" : "checking"
22448
- ])
22449
- );
22662
+ const agentsToInspect = force ? externalAgents : passiveHarnessAvailabilityAgents(state.availability, state.errors);
22663
+ if (agentsToInspect.length === 0) {
22664
+ resetHarnessAvailabilityRetry(hostId);
22665
+ return Promise.resolve();
22666
+ }
22667
+ const nextAvailability = { ...state.availability };
22668
+ for (const agent of agentsToInspect) {
22669
+ if (nextAvailability[agent] !== "ready") nextAvailability[agent] = "checking";
22670
+ }
22671
+ state.availability = nextAvailability;
22450
22672
  if (hostId === activeAvailabilityHostId) {
22451
22673
  publishConnectionStatus();
22452
22674
  for (const mounted of mountedByComposer.values()) renderMounted(mounted);
@@ -22454,7 +22676,7 @@ ${error51.stderrTail}`] : []
22454
22676
  const generation = ++state.requestGeneration;
22455
22677
  const promise2 = (async () => {
22456
22678
  await Promise.all(
22457
- externalAgents.map(async (agent) => {
22679
+ agentsToInspect.map(async (agent) => {
22458
22680
  let status = "error";
22459
22681
  let nextError;
22460
22682
  try {
@@ -22485,6 +22707,7 @@ ${error51.stderrTail}`] : []
22485
22707
  };
22486
22708
  }
22487
22709
  if (generation !== state.requestGeneration || disposed) return;
22710
+ const previousStatus = state.availability[agent];
22488
22711
  state.errors[agent] = nextError;
22489
22712
  state.availability = { ...state.availability, [agent]: status };
22490
22713
  if (hostId !== activeAvailabilityHostId) {
@@ -22499,7 +22722,11 @@ ${error51.stderrTail}`] : []
22499
22722
  }
22500
22723
  for (const mounted of mountedByComposer.values()) {
22501
22724
  const composerState = controller.get(mounted.composer);
22502
- if (composerState.agent === agent) {
22725
+ if (composerState.agent === agent && shouldReloadExternalCatalogAfterAvailabilityRefresh(
22726
+ previousStatus,
22727
+ status,
22728
+ isExternalConfigurationReady(mounted)
22729
+ )) {
22503
22730
  void loadExternalCatalog(mounted);
22504
22731
  }
22505
22732
  renderMounted(mounted);
@@ -22508,7 +22735,7 @@ ${error51.stderrTail}`] : []
22508
22735
  })
22509
22736
  );
22510
22737
  if (generation !== state.requestGeneration || disposed) return;
22511
- if (externalAgents.every((agent) => state.availability[agent] === "ready")) {
22738
+ if (retryableHarnessAvailabilityAgents(state.availability, state.errors).length === 0) {
22512
22739
  resetHarnessAvailabilityRetry(hostId);
22513
22740
  } else {
22514
22741
  scheduleHarnessAvailabilityRetry(hostId);
@@ -22595,7 +22822,7 @@ ${error51.stderrTail}`] : []
22595
22822
  },
22596
22823
  refresh() {
22597
22824
  for (const hostId of harnessAvailabilityByHost.keys()) {
22598
- void refreshHarnessAvailabilityForHost(hostId, true);
22825
+ void refreshHarnessAvailabilityForHost(hostId, true, false, true);
22599
22826
  }
22600
22827
  return Promise.resolve();
22601
22828
  },
@@ -22727,8 +22954,8 @@ ${error51.stderrTail}`] : []
22727
22954
  continue;
22728
22955
  }
22729
22956
  const state = controller.get(composer);
22730
- const hideNativeControls = controller.isSwitching(composer) || state.agent !== "codex";
22731
- reconcileComposerNativeControls(mounted.control, hideNativeControls, hideNativeControls);
22957
+ const hideCodexControls = controller.isSwitching(composer) || state.agent !== "codex";
22958
+ reconcileComposerNativeControls(mounted.control, hideCodexControls, hideCodexControls);
22732
22959
  if (refreshTargets) refreshMountedConversationTarget(mounted);
22733
22960
  }
22734
22961
  for (const editor of document.querySelectorAll(EDITOR_SELECTOR)) {