@karlorz/codexhost-cli-win32-x64 0.13.2-3 → 0.13.3-0

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.
@@ -18807,14 +18807,6 @@ ${error51.stderrTail}`] : []
18807
18807
  otherSection: "Other",
18808
18808
  appearanceDescription: "Conversation display and local resource management.",
18809
18809
  appearanceGroup: "Appearance",
18810
- hideCodexUsageBannerTitle: "Hide Codex usage warning",
18811
- hideCodexUsageBannerDescription: "On by default. Hide the out-of-usage card on every Composer.",
18812
- hideCodexUsageBannerHelpLabel: "About hiding the Codex usage warning",
18813
- hideCodexUsageBannerHelp: Object.freeze([
18814
- "The native card appears when the signed-in ChatGPT Codex quota is exhausted.",
18815
- "When this is on, that card is hidden on every Composer, including Codex threads. Reset usage and Upgrade stay available in Settings.",
18816
- "Turning this off only shows the native card again. Send on this Composer, including Codex threads, is already separated from that quota card."
18817
- ]),
18818
18810
  cpaLiveVoiceTitle: "Override live voice",
18819
18811
  cpaLiveVoiceDescription: "On by default. Host creates the realtime call instead of ChatGPT.",
18820
18812
  cpaLiveVoiceHelpLabel: "About overriding live voice",
@@ -18987,7 +18979,7 @@ ${error51.stderrTail}`] : []
18987
18979
  launchPathSaveError: "Could not save. Enter an existing absolute installation folder on this Host and check configuration permissions.",
18988
18980
  connectionOfficialWebsite: "Visit official website",
18989
18981
  connectionOpenHarnessWeb: "Open DeepSeek Harness Web",
18990
- connectionDeepSeekTestedVersions: "Supported DSH versions: 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1 and 0.2.0-rc.2. Versions newer than 0.2.0-rc.2 can be tried, but compatibility may be limited; versions older than 0.1.7-rc.1 must be upgraded first.",
18982
+ connectionDeepSeekTestedVersions: "Supported DSH versions: 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1, 0.2.0-rc.2, 0.2.1-rc.1 and 0.2.1-rc.2. Versions newer than 0.2.1-rc.2 can be tried, but compatibility may be limited; versions older than 0.1.7-rc.1 must be upgraded first.",
18991
18983
  connectionInstall: "Install",
18992
18984
  connectionInstallDescription: "This Harness was not detected.",
18993
18985
  connectionInstallRunning: "Installing on the selected Host. You can leave this page; login or setup may still be required afterward.",
@@ -19098,14 +19090,6 @@ ${error51.stderrTail}`] : []
19098
19090
  otherSection: "\u5176\u4ED6",
19099
19091
  appearanceDescription: "\u4F1A\u8BDD\u663E\u793A\u4E0E\u672C\u5730\u8D44\u6E90\u7BA1\u7406\u3002",
19100
19092
  appearanceGroup: "\u5916\u89C2",
19101
- hideCodexUsageBannerTitle: "\u9690\u85CF Codex \u989D\u5EA6\u8B66\u544A",
19102
- hideCodexUsageBannerDescription: "\u9ED8\u8BA4\u5F00\u542F\u3002\u5728\u6240\u6709 Composer \u4E0A\u9690\u85CF\u989D\u5EA6\u8017\u5C3D\u5361\u7247\u3002",
19103
- hideCodexUsageBannerHelpLabel: "\u9690\u85CF Codex \u989D\u5EA6\u8B66\u544A\u8BF4\u660E",
19104
- hideCodexUsageBannerHelp: Object.freeze([
19105
- "\u5DF2\u767B\u5F55\u7684 ChatGPT Codex \u989D\u5EA6\u8017\u5C3D\u65F6\uFF0CDesktop \u4F1A\u663E\u793A\u539F\u751F\u8B66\u544A\u5361\u7247\u3002",
19106
- "\u5F00\u542F\u540E\uFF0C\u6240\u6709 Composer \u90FD\u9690\u85CF\u8BE5\u5361\u7247\uFF0C\u5305\u62EC Codex \u4F1A\u8BDD\u3002\u300C\u91CD\u7F6E\u7528\u91CF\u300D\u548C\u300C\u5347\u7EA7\u300D\u4ECD\u53EF\u5728\u8BBE\u7F6E\u4E2D\u4F7F\u7528\u3002",
19107
- "\u5173\u95ED\u6B64\u5F00\u5173\u53EA\u4F1A\u91CD\u65B0\u663E\u793A\u539F\u751F\u5361\u7247\u3002\u5F53\u524D Composer \u7684\u53D1\u9001\uFF08\u5305\u62EC Codex \u4F1A\u8BDD\uFF09\u5DF2\u4E0E\u8BE5\u989D\u5EA6\u5361\u7247\u5206\u79BB\u3002"
19108
- ]),
19109
19093
  cpaLiveVoiceTitle: "\u6539\u5199\u5B9E\u65F6\u8BED\u97F3",
19110
19094
  cpaLiveVoiceDescription: "\u9ED8\u8BA4\u5F00\u542F\u3002\u7531 Host \u521B\u5EFA realtime \u901A\u8BDD\uFF0C\u800C\u4E0D\u662F ChatGPT\u3002",
19111
19095
  cpaLiveVoiceHelpLabel: "\u6539\u5199\u5B9E\u65F6\u8BED\u97F3\u8BF4\u660E",
@@ -19278,7 +19262,7 @@ ${error51.stderrTail}`] : []
19278
19262
  launchPathSaveError: "\u4FDD\u5B58\u5931\u8D25\u3002\u8BF7\u586B\u5199\u6B64 Host \u4E0A\u5B9E\u9645\u5B58\u5728\u7684\u5B89\u88C5\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u5E76\u786E\u8BA4\u914D\u7F6E\u76EE\u5F55\u53EF\u5199\u3002",
19279
19263
  connectionOfficialWebsite: "\u8BBF\u95EE\u5B98\u7F51",
19280
19264
  connectionOpenHarnessWeb: "\u6253\u5F00 DeepSeek Harness Web",
19281
- connectionDeepSeekTestedVersions: "\u652F\u6301 DSH \u7248\u672C\uFF1A0.1.7-rc.1\u30010.1.7-rc.2\u30010.2.0-rc.1 \u548C 0.2.0-rc.2\u3002\u9AD8\u4E8E 0.2.0-rc.2 \u7684\u7248\u672C\u53EF\u4EE5\u5C1D\u8BD5\u8FDE\u63A5\uFF0C\u4F46\u9002\u914D\u5EA6\u53EF\u80FD\u6709\u9650\uFF1B\u4F4E\u4E8E 0.1.7-rc.1 \u7684\u7248\u672C\u9700\u8981\u5148\u5347\u7EA7\u3002",
19265
+ connectionDeepSeekTestedVersions: "\u652F\u6301 DSH \u7248\u672C\uFF1A0.1.7-rc.1\u30010.1.7-rc.2\u30010.2.0-rc.1\u30010.2.0-rc.2\u30010.2.1-rc.1 \u548C 0.2.1-rc.2\u3002\u9AD8\u4E8E 0.2.1-rc.2 \u7684\u7248\u672C\u53EF\u4EE5\u5C1D\u8BD5\u8FDE\u63A5\uFF0C\u4F46\u9002\u914D\u5EA6\u53EF\u80FD\u6709\u9650\uFF1B\u4F4E\u4E8E 0.1.7-rc.1 \u7684\u7248\u672C\u9700\u8981\u5148\u5347\u7EA7\u3002",
19282
19266
  connectionInstall: "\u5B89\u88C5",
19283
19267
  connectionInstallDescription: "\u5C1A\u672A\u68C0\u6D4B\u5230\u8BE5 Harness\u3002",
19284
19268
  connectionInstallRunning: "\u6B63\u5728\u6240\u9009 Host \u4E0A\u5B89\u88C5\uFF0C\u79BB\u5F00\u9875\u9762\u4E0D\u4F1A\u4E2D\u65AD\u3002\u5B89\u88C5\u540E\u53EF\u80FD\u4ECD\u9700\u767B\u5F55\u6216\u914D\u7F6E\u3002",
@@ -20074,7 +20058,6 @@ ${error51.stderrTail}`] : []
20074
20058
  // src/renderer-usage-control.ts
20075
20059
  var ENGLISH_USAGE_MESSAGES = Object.freeze({
20076
20060
  usage: "Usage",
20077
- account: "Account",
20078
20061
  context: "Context",
20079
20062
  recordedCredits: "Recorded usage",
20080
20063
  latestCacheHit: "Latest cache hit (CH)",
@@ -20100,7 +20083,6 @@ ${error51.stderrTail}`] : []
20100
20083
  });
20101
20084
  var CHINESE_USAGE_MESSAGES = Object.freeze({
20102
20085
  usage: "\u7528\u91CF",
20103
- account: "\u8D26\u53F7",
20104
20086
  context: "\u4E0A\u4E0B\u6587",
20105
20087
  recordedCredits: "\u5DF2\u8BB0\u5F55\u6D88\u8017",
20106
20088
  latestCacheHit: "\u6700\u8FD1\u7F13\u5B58\u547D\u4E2D\uFF08CH\uFF09",
@@ -20212,10 +20194,10 @@ ${error51.stderrTail}`] : []
20212
20194
  popover.style.color = "CanvasText";
20213
20195
  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))";
20214
20196
  }
20215
- function addDetailRow(parent, label, value, wrap = false) {
20197
+ function addDetailRow(parent, label, value) {
20216
20198
  const row = document.createElement("div");
20217
20199
  row.style.display = "grid";
20218
- row.style.gridTemplateColumns = wrap ? "auto minmax(0, 1fr)" : "minmax(0, 1fr) auto";
20200
+ row.style.gridTemplateColumns = "minmax(0, 1fr) auto";
20219
20201
  row.style.gap = "20px";
20220
20202
  row.style.padding = "4px 0";
20221
20203
  const labelElement = document.createElement("span");
@@ -20225,10 +20207,6 @@ ${error51.stderrTail}`] : []
20225
20207
  valueElement.textContent = value;
20226
20208
  valueElement.style.fontVariantNumeric = "tabular-nums";
20227
20209
  valueElement.style.textAlign = "right";
20228
- if (wrap) {
20229
- valueElement.style.overflowWrap = "anywhere";
20230
- valueElement.title = value;
20231
- }
20232
20210
  row.append(labelElement, valueElement);
20233
20211
  parent.append(row);
20234
20212
  }
@@ -20279,14 +20257,13 @@ ${error51.stderrTail}`] : []
20279
20257
  if (note) addNote(parent, note);
20280
20258
  }
20281
20259
  }
20282
- function renderDetails(popover, usage, messages, locale, accountName) {
20260
+ function renderDetails(popover, usage, messages, locale) {
20283
20261
  popover.replaceChildren();
20284
20262
  const heading = document.createElement("div");
20285
20263
  heading.textContent = messages.usage;
20286
20264
  heading.style.fontWeight = "600";
20287
20265
  heading.style.marginBottom = "6px";
20288
20266
  popover.append(heading);
20289
- if (accountName) addDetailRow(popover, messages.account, accountName, true);
20290
20267
  if (usage?.contextUsagePercent !== void 0) {
20291
20268
  addContextRow(
20292
20269
  popover,
@@ -20518,7 +20495,7 @@ ${error51.stderrTail}`] : []
20518
20495
  document.body.append(popover);
20519
20496
  return control;
20520
20497
  }
20521
- function renderRendererUsageControl(control, usage, locale = control.locale, accountName = null) {
20498
+ function renderRendererUsageControl(control, usage, locale = control.locale) {
20522
20499
  control.locale = locale;
20523
20500
  const messages = rendererUsageMessages(locale);
20524
20501
  control.popover.setAttribute("aria-label", messages.threadUsageDetails);
@@ -20527,7 +20504,7 @@ ${error51.stderrTail}`] : []
20527
20504
  const totalCostUsd = usage?.totalCostUsd;
20528
20505
  const hasContext = usage?.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0;
20529
20506
  const hasTokenUsage = usage?.totalTokens !== void 0 || usage?.inputTokens !== void 0 || usage?.cachedInputTokens !== void 0 || usage?.cacheWriteInputTokens !== void 0 || usage?.outputTokens !== void 0;
20530
- const visible = rendererUsageHasDisplayData(usage) || Boolean(accountName);
20507
+ const visible = rendererUsageHasDisplayData(usage);
20531
20508
  control.root.style.display = visible ? "inline-flex" : "none";
20532
20509
  if (!visible) {
20533
20510
  closePopover(control);
@@ -20561,7 +20538,7 @@ ${error51.stderrTail}`] : []
20561
20538
  control.trigger.setAttribute("aria-label", accessibleSummary);
20562
20539
  control.trigger.title = accessibleSummary;
20563
20540
  control.label.textContent = compactSummary;
20564
- renderDetails(control.popover, usage, messages, locale, accountName);
20541
+ renderDetails(control.popover, usage, messages, locale);
20565
20542
  return true;
20566
20543
  }
20567
20544
 
@@ -22564,27 +22541,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
22564
22541
  };
22565
22542
  }
22566
22543
 
22567
- // src/renderer-codex-usage-banner-preference.ts
22568
- var CODEX_USAGE_BANNER_STORAGE_KEY = "codexhost.codex-usage-banner-hidden.v1";
22569
- var CODEX_USAGE_BANNER_CHANGE_EVENT = "codexhost:codex-usage-banner-changed";
22570
- function readCodexUsageBannerPreference(owner) {
22571
- if (!owner) return true;
22572
- try {
22573
- return owner.localStorage.getItem(CODEX_USAGE_BANNER_STORAGE_KEY) !== "0";
22574
- } catch {
22575
- return true;
22576
- }
22577
- }
22578
- function writeCodexUsageBannerPreference(owner, enabled) {
22579
- try {
22580
- owner.localStorage.setItem(CODEX_USAGE_BANNER_STORAGE_KEY, enabled ? "1" : "0");
22581
- } catch {
22582
- return false;
22583
- }
22584
- owner.dispatchEvent(new Event(CODEX_USAGE_BANNER_CHANGE_EVENT));
22585
- return true;
22586
- }
22587
-
22588
22544
  // src/renderer-composer-dom.ts
22589
22545
  var CODEX_COMPOSER_SELECTOR = "[data-codex-composer-root]";
22590
22546
  var EDITOR_SELECTOR = 'textarea, [contenteditable="true"], [role="textbox"]';
@@ -22757,17 +22713,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
22757
22713
  ].filter(isNativeContextUsageControlCandidate);
22758
22714
  return candidates.length === 1 ? candidates[0] ?? null : null;
22759
22715
  }
22760
- function isNativeUsageBannerCandidate(element) {
22761
- if (element.localName !== "aside") return false;
22762
- if (typeof element.querySelector !== "function") return false;
22763
- return element.querySelector("h3") !== null && element.querySelector("button") !== null;
22764
- }
22765
- function nativeUsageBannerForComposer(composer) {
22766
- const candidates = [...composer.querySelectorAll("aside")].filter(
22767
- isNativeUsageBannerCandidate
22768
- );
22769
- return candidates.length === 1 ? candidates[0] ?? null : null;
22770
- }
22771
22716
  function captureNativeControl(element) {
22772
22717
  return element ? {
22773
22718
  element,
@@ -22789,12 +22734,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
22789
22734
  restoreNativeControl(control.nativeContextUsageControl);
22790
22735
  control.nativeContextUsageControl = captureNativeControl(candidate);
22791
22736
  }
22792
- function refreshNativeUsageBanner(control) {
22793
- const candidate = nativeUsageBannerForComposer(control.composer);
22794
- if (candidate === control.nativeUsageBanner?.element) return;
22795
- restoreNativeControl(control.nativeUsageBanner);
22796
- control.nativeUsageBanner = captureNativeControl(candidate);
22797
- }
22798
22737
  function refreshNativeModelControl(control) {
22799
22738
  const candidate = nativeModelControlForComposer(control.composer);
22800
22739
  if (!candidate) return;
@@ -22913,20 +22852,12 @@ Codex Fast mode prioritizes requests and may increase usage.`
22913
22852
  refreshNativeContextUsageControl(control);
22914
22853
  refreshNativeModelControl(control);
22915
22854
  refreshNativePermissionModeControl(control);
22916
- refreshNativeUsageBanner(control);
22917
22855
  refreshTrailingClusterPlacement(control);
22918
22856
  refreshUsagePlacement(control);
22919
22857
  refreshCreditsPlacement(control);
22920
22858
  setNativeControlHidden(control.nativeModelControl, hideModel);
22921
22859
  setNativeControlHidden(control.nativeContextUsageControl, false);
22922
22860
  setNativeControlHidden(control.nativePermissionModeControl, hidePermissionMode);
22923
- setNativeControlHidden(
22924
- control.nativeUsageBanner,
22925
- readCodexUsageBannerPreference(preferenceOwner(control))
22926
- );
22927
- }
22928
- function preferenceOwner(control) {
22929
- return control.composer.ownerDocument?.defaultView ?? (typeof document !== "undefined" ? document.defaultView : null);
22930
22861
  }
22931
22862
  function mountComposerAgentControl(composer, composerId, sendButton, enabledAgents, onSelect, onDownload, onOpenProviderPicker, onSelectModel, onSelectThinking, onSelectPermissionMode, onOpenCommandMenu) {
22932
22863
  if (composer instanceof HTMLElement) composer.style.minWidth = "0";
@@ -22934,7 +22865,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
22934
22865
  const nativeContextUsageControl = captureNativeControl(
22935
22866
  nativeContextUsageControlForComposer(composer)
22936
22867
  );
22937
- const nativeUsageBanner = captureNativeControl(nativeUsageBannerForComposer(composer));
22938
22868
  const semanticNativePermissionModeControl = semanticNativePermissionModeControlForComposer(composer);
22939
22869
  const nativePermissionModeControl = captureNativeControl(semanticNativePermissionModeControl);
22940
22870
  const nativePermissionModeControlVerified = semanticNativePermissionModeControl !== null && nativePermissionModeControlForComposer(composer) === semanticNativePermissionModeControl;
@@ -22995,7 +22925,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
22995
22925
  nativeModelControl,
22996
22926
  nativePermissionModeControl,
22997
22927
  nativeContextUsageControl,
22998
- nativeUsageBanner,
22999
22928
  nativePermissionModeControlVerified,
23000
22929
  credits,
23001
22930
  usage: null,
@@ -23063,20 +22992,14 @@ Codex Fast mode prioritizes requests and may increase usage.`
23063
22992
  permissionModeVisible,
23064
22993
  locale
23065
22994
  );
23066
- const selectedCodexAccount = state.agent === "codex" && !ownershipError ? currentCodexAccount : void 0;
23067
22995
  if (control.usage) {
23068
- renderRendererUsageControl(
23069
- control.usage,
23070
- usage,
23071
- locale,
23072
- selectedCodexAccount?.email ?? selectedCodexAccount?.label ?? null
23073
- );
22996
+ renderRendererUsageControl(control.usage, usage, locale);
23074
22997
  }
23075
22998
  control.harnessCommands.setLocale(locale);
23076
22999
  control.harnessCommands.root.hidden = state.agent === "codex";
23077
23000
  control.harnessCommands.root.style.display = state.agent === "codex" ? "none" : "inline-flex";
23078
23001
  renderRendererCreditsControl(control.credits, accountCredits, locale);
23079
- return !submissionBlocked && (state.agent === "codex" || adapterState === "ready");
23002
+ return state.agent !== "codex" && adapterState === "ready" && !submissionBlocked;
23080
23003
  }
23081
23004
  function disposeComposerAgentControl(control) {
23082
23005
  if (control.sendDisabledBeforeSwitch !== null) {
@@ -23087,7 +23010,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
23087
23010
  }
23088
23011
  restoreNativeControl(control.nativeModelControl);
23089
23012
  restoreNativeControl(control.nativeContextUsageControl);
23090
- restoreNativeControl(control.nativeUsageBanner);
23091
23013
  restoreNativeControl(control.nativePermissionModeControl);
23092
23014
  control.credits.dispose();
23093
23015
  control.usage?.dispose();
@@ -23211,63 +23133,141 @@ Codex Fast mode prioritizes requests and may increase usage.`
23211
23133
  }
23212
23134
  };
23213
23135
 
23136
+ // src/renderer-codex-usage-banner.ts
23137
+ var MAX_FIBERS = 2e4;
23138
+ function isRecord3(value) {
23139
+ return typeof value === "object" && value !== null && !Array.isArray(value);
23140
+ }
23141
+ function isUsageBanner(props) {
23142
+ return isRecord3(props) && "banner" in props && "rateLimitStatus" in props && typeof props.sendBlocked === "boolean";
23143
+ }
23144
+ function isElement(value) {
23145
+ return isRecord3(value) && typeof value.setAttribute === "function" && isRecord3(value.style);
23146
+ }
23147
+ function hostElements(fiber, budget) {
23148
+ const result = [];
23149
+ const visit = (node) => {
23150
+ for (let current = node; isRecord3(current); current = current.sibling) {
23151
+ if (budget.remaining-- <= 0) return;
23152
+ const { stateNode } = current;
23153
+ if (isElement(stateNode)) result.push(stateNode);
23154
+ else visit(current.child);
23155
+ }
23156
+ };
23157
+ visit(fiber.child);
23158
+ return result;
23159
+ }
23160
+ function findCodexUsageBannerElements(owner) {
23161
+ if (!isRecord3(owner)) return [];
23162
+ const budget = { remaining: MAX_FIBERS };
23163
+ const found = [];
23164
+ const stack = [owner.child];
23165
+ while (stack.length > 0 && budget.remaining > 0) {
23166
+ const node = stack.pop();
23167
+ if (!isRecord3(node)) continue;
23168
+ budget.remaining -= 1;
23169
+ const fiber = node;
23170
+ stack.push(fiber.sibling);
23171
+ if (isUsageBanner(fiber.memoizedProps)) found.push(...hostElements(fiber, budget));
23172
+ else stack.push(fiber.child);
23173
+ }
23174
+ return budget.remaining > 0 ? found : [];
23175
+ }
23176
+ var HIDDEN_ATTRIBUTE = "data-codexhost-usage-banner-hidden";
23177
+ function createRendererCodexUsageBanner() {
23178
+ const hidden = /* @__PURE__ */ new Map();
23179
+ const show = (element) => {
23180
+ const previous = hidden.get(element);
23181
+ hidden.delete(element);
23182
+ if (!previous || element.getAttribute(HIDDEN_ATTRIBUTE) === null) return;
23183
+ element.removeAttribute(HIDDEN_ATTRIBUTE);
23184
+ if (previous.value) element.style.setProperty("display", previous.value, previous.priority);
23185
+ else element.style.removeProperty("display");
23186
+ };
23187
+ return {
23188
+ hide(owner) {
23189
+ const current = new Set(findCodexUsageBannerElements(owner));
23190
+ for (const element of [...hidden.keys()]) if (!current.has(element)) show(element);
23191
+ for (const element of current) {
23192
+ if (hidden.has(element)) continue;
23193
+ hidden.set(element, {
23194
+ value: element.style.getPropertyValue("display"),
23195
+ priority: element.style.getPropertyPriority("display")
23196
+ });
23197
+ element.setAttribute(HIDDEN_ATTRIBUTE, "");
23198
+ element.style.setProperty("display", "none", "important");
23199
+ }
23200
+ },
23201
+ restore() {
23202
+ for (const element of [...hidden.keys()]) show(element);
23203
+ }
23204
+ };
23205
+ }
23206
+
23214
23207
  // src/renderer-codex-usage-gate.ts
23215
23208
  var EDITOR_SELECTOR2 = '[contenteditable="true"][role="textbox"]';
23216
23209
  var MAX_HOOKS = 4096;
23217
23210
  var MAX_DOM_DEPTH = 12;
23218
23211
  var RETRY_DELAY_MS = 1e3;
23219
- function isRecord3(value) {
23212
+ function isRecord4(value) {
23220
23213
  return typeof value === "object" && value !== null && !Array.isArray(value);
23221
23214
  }
23222
23215
  function hooksOf(fiber) {
23223
23216
  const result = [];
23224
- let hook = isRecord3(fiber) ? fiber.memoizedState : null;
23225
- while (isRecord3(hook) && result.length < MAX_HOOKS) {
23217
+ let hook = isRecord4(fiber) ? fiber.memoizedState : null;
23218
+ while (isRecord4(hook) && result.length < MAX_HOOKS) {
23226
23219
  result.push(hook);
23227
23220
  hook = hook.next;
23228
23221
  }
23229
23222
  return hook == null ? result : [];
23230
23223
  }
23231
- function submitOwners(composer) {
23224
+ function submitOwners(composer, projections) {
23232
23225
  let element = composer.querySelector(EDITOR_SELECTOR2) ?? composer;
23233
23226
  for (let depth = 0; element && depth < MAX_DOM_DEPTH; depth += 1) {
23234
23227
  const key = Object.getOwnPropertyNames(element).find(
23235
23228
  (name) => name.startsWith("__reactFiber$")
23236
23229
  );
23237
23230
  if (key) {
23238
- const candidates = committedReactAncestors(
23231
+ const ancestors = committedReactAncestors(
23239
23232
  Object.getOwnPropertyDescriptor(element, key)?.value
23240
- ).filter(
23241
- ({ memoizedProps: props }) => isRecord3(props) && "onLocalSubmitStart" in props && typeof props.submitDisabled === "boolean"
23242
23233
  );
23243
- const owner = candidates.find((fiber) => {
23244
- const gates = subtreeGateSubscriptions(fiber);
23234
+ const scopes = [];
23235
+ ancestors.forEach(({ memoizedProps: props }, index) => {
23236
+ if (isRecord4(props) && "onLocalSubmitStart" in props && typeof props.submitDisabled === "boolean") {
23237
+ scopes.push({ owner: ancestors[index], fibers: ancestors.slice(0, index + 1) });
23238
+ }
23239
+ });
23240
+ const valid = scopes.filter((scope) => {
23241
+ const gates = gateSubscriptions(scope, projections);
23245
23242
  return !gates.invalid && gates.reserve.length > 0;
23246
23243
  });
23247
- return owner ? [owner] : candidates;
23244
+ return valid.filter(
23245
+ (scope) => !valid.some((other) => other !== scope && scope.fibers.includes(other.owner))
23246
+ );
23248
23247
  }
23249
23248
  element = element.parentElement;
23250
23249
  }
23251
23250
  return [];
23252
23251
  }
23253
- function findSubmitOwner(composer) {
23254
- const owners = submitOwners(composer);
23255
- return owners.length === 1 ? owners[0] ?? null : null;
23252
+ function findSubmitScope(composer, projections) {
23253
+ const scopes = submitOwners(composer, projections);
23254
+ return scopes.length === 1 ? scopes[0] ?? null : null;
23256
23255
  }
23257
- function subscriptionAt(hook) {
23256
+ function subscriptionAt(hook, fiber) {
23258
23257
  const memo = hook.memoizedState;
23259
23258
  if (!Array.isArray(memo) || !Array.isArray(memo[1])) return null;
23260
23259
  const [subscriber, dependencies] = memo;
23261
23260
  if (dependencies.length !== 2) return null;
23262
23261
  const signal = dependencies[0];
23263
- const adapted = dependencies[1] === void 0 && isRecord3(signal) && typeof signal.get === "function" && typeof signal.subscribe === "function";
23262
+ const adapted = dependencies[1] === void 0 && isRecord4(signal) && typeof signal.get === "function" && typeof signal.subscribe === "function";
23264
23263
  const [store, atom] = adapted ? [signal.store, signal.atom] : dependencies;
23265
23264
  const instance = hook.next?.queue;
23266
23265
  const effect = hook.next?.next?.memoizedState;
23267
- if (!isRecord3(subscriber) || typeof subscriber.getSnapshot !== "function" || typeof subscriber.subscribe !== "function" || !isRecord3(store) || typeof store.get !== "function" || typeof store.sub !== "function" || !isRecord3(atom) || typeof atom.read !== "function" || "write" in atom || !isRecord3(instance) || typeof instance.value !== "boolean" || typeof instance.getSnapshot !== "function" || !isRecord3(effect) || typeof effect.create !== "function" || !Array.isArray(effect.deps) || effect.deps[0] !== subscriber.subscribe) {
23266
+ if (!isRecord4(subscriber) || typeof subscriber.getSnapshot !== "function" || typeof subscriber.subscribe !== "function" || !isRecord4(store) || typeof store.get !== "function" || typeof store.sub !== "function" || !isRecord4(atom) || typeof atom.read !== "function" || "write" in atom || !isRecord4(instance) || typeof instance.value !== "boolean" || typeof instance.getSnapshot !== "function" || !isRecord4(effect) || typeof effect.create !== "function" || !Array.isArray(effect.deps) || effect.deps[0] !== subscriber.subscribe) {
23268
23267
  return null;
23269
23268
  }
23270
23269
  return {
23270
+ fiber,
23271
23271
  subscriber,
23272
23272
  store,
23273
23273
  atom,
@@ -23305,10 +23305,10 @@ Codex Fast mode prioritizes requests and may increase usage.`
23305
23305
  visiting.delete(dependency);
23306
23306
  }
23307
23307
  }
23308
- if (!isRecord3(value)) return value;
23308
+ if (!isRecord4(value)) return value;
23309
23309
  if (typeof value.hardBlocked === "boolean") return trace(value, "reserve");
23310
23310
  if ("authMethod" in value) return trace(value, "auth");
23311
- if (isRecord3(value.data) && isRecord3(value.data.rate_limit)) {
23311
+ if (isRecord4(value.data) && isRecord4(value.data.rate_limit)) {
23312
23312
  return {
23313
23313
  ...value,
23314
23314
  data: { ...value.data, rate_limit: trace(value.data.rate_limit, "limit") }
@@ -23329,7 +23329,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
23329
23329
  if (account) return "account";
23330
23330
  return null;
23331
23331
  }
23332
- function snapshotsMatch({ subscriber, instance, store, atom }, projected) {
23332
+ function snapshotsMatch({ subscriber, instance, store, atom }, projections) {
23333
+ const projected = projections?.get(instance);
23333
23334
  try {
23334
23335
  if (typeof subscriber.createRender === "function" && subscriber.createRender() != null) {
23335
23336
  return false;
@@ -23342,67 +23343,40 @@ Codex Fast mode prioritizes requests and may increase usage.`
23342
23343
  return false;
23343
23344
  }
23344
23345
  }
23345
- function projectionFor(projections, instance) {
23346
- return projections?.get(instance);
23347
- }
23348
- function sameLogicalGate(subscriptions) {
23349
- const first = subscriptions[0];
23350
- if (!first) return true;
23351
- return subscriptions.every((item) => item.store === first.store && item.atom === first.atom);
23352
- }
23353
- var MAX_SUBTREE_FIBERS = 1024;
23354
- function subtreeFibers(root) {
23355
- const result = [];
23356
- const stack = [root.child];
23357
- while (stack.length > 0) {
23358
- const fiber = stack.pop();
23359
- if (!isRecord3(fiber)) continue;
23360
- result.push(fiber);
23361
- if (result.length >= MAX_SUBTREE_FIBERS) return [];
23362
- stack.push(fiber.child, fiber.sibling);
23363
- }
23364
- return result;
23365
- }
23366
- function gateSubscriptions(owner, projections) {
23346
+ function gateSubscriptions(scope, projections) {
23367
23347
  const found = {
23368
23348
  account: [],
23369
23349
  reserve: [],
23370
23350
  invalid: false
23371
23351
  };
23372
- for (const hook of hooksOf(owner)) {
23373
- const subscription = subscriptionAt(hook);
23374
- const kind = subscription && gateKind(subscription);
23375
- if (subscription && kind) {
23376
- if (kind !== "mixed" && snapshotsMatch(subscription, projectionFor(projections, subscription.instance))) {
23377
- found[kind].push(subscription);
23378
- } else found.invalid = true;
23352
+ for (const fiber of scope.fibers) {
23353
+ for (const hook of hooksOf(fiber)) {
23354
+ const subscription = subscriptionAt(hook, fiber);
23355
+ const kind = subscription && gateKind(subscription);
23356
+ if (subscription && kind) {
23357
+ if (kind !== "mixed" && snapshotsMatch(subscription, projections)) {
23358
+ found[kind].push(subscription);
23359
+ } else found.invalid = true;
23360
+ }
23379
23361
  }
23380
23362
  }
23381
23363
  return found;
23382
23364
  }
23383
- function subtreeGateSubscriptions(owner, projections) {
23384
- const combined = {
23385
- account: [],
23386
- reserve: [],
23387
- invalid: false
23388
- };
23389
- for (const fiber of [owner, ...subtreeFibers(owner)]) {
23390
- const gates = gateSubscriptions(fiber, projections);
23391
- if (gates.invalid) combined.invalid = true;
23392
- combined.account.push(...gates.account);
23393
- combined.reserve.push(...gates.reserve);
23394
- }
23395
- if (!sameLogicalGate(combined.account) || !sameLogicalGate(combined.reserve)) {
23396
- combined.invalid = true;
23397
- }
23398
- return combined;
23399
- }
23400
- function discoverGates(owner, projections) {
23401
- const gates = subtreeGateSubscriptions(owner, projections);
23365
+ function discoverGates(scope, projections) {
23366
+ const gates = gateSubscriptions(scope, projections);
23402
23367
  if (gates.invalid) return null;
23403
- return { account: gates.account, reserve: gates.reserve };
23368
+ const found = [];
23369
+ for (const kind of ["account", "reserve"]) {
23370
+ const fibers = /* @__PURE__ */ new Set();
23371
+ for (const subscription of gates[kind]) {
23372
+ if (fibers.has(subscription.fiber)) return null;
23373
+ fibers.add(subscription.fiber);
23374
+ found.push([kind, subscription]);
23375
+ }
23376
+ }
23377
+ return found;
23404
23378
  }
23405
- function project2({ subscriber, store, atom, instance, subscribeEffect }) {
23379
+ function project2(kind, { fiber, subscriber, store, atom, instance, subscribeEffect }) {
23406
23380
  for (const [target, key] of [
23407
23381
  [store, "sub"],
23408
23382
  [subscriber, "getSnapshot"],
@@ -23433,6 +23407,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
23433
23407
  instance.getSnapshot = allowed;
23434
23408
  if (instance.value !== false) onChange();
23435
23409
  return {
23410
+ kind,
23411
+ fiber,
23436
23412
  subscriber,
23437
23413
  instance,
23438
23414
  restore() {
@@ -23442,16 +23418,11 @@ Codex Fast mode prioritizes requests and may increase usage.`
23442
23418
  }
23443
23419
  };
23444
23420
  }
23445
- function isBound(owner, projections) {
23446
- const alternate = isRecord3(owner.alternate) ? owner.alternate : null;
23447
- const bound = [...projections];
23448
- const subtrees = [owner, alternate].flatMap(
23449
- (fiber) => fiber ? [[fiber, ...subtreeFibers(fiber)]] : []
23450
- );
23451
- return subtrees.some((fibers) => {
23452
- const hooks = fibers.flatMap((fiber) => hooksOf(fiber));
23453
- return bound.every(
23454
- ({ subscriber, instance }) => hooks.some(
23421
+ function isBound(projections) {
23422
+ return [...projections].every(({ fiber, subscriber, instance }) => {
23423
+ const alternate = isRecord4(fiber.alternate) ? fiber.alternate : null;
23424
+ return [fiber, alternate].some(
23425
+ (candidate) => hooksOf(candidate).some(
23455
23426
  (hook) => Array.isArray(hook.memoizedState) && hook.memoizedState[0] === subscriber && hook.next?.queue === instance
23456
23427
  )
23457
23428
  );
@@ -23462,7 +23433,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
23462
23433
  const projections = /* @__PURE__ */ new Map();
23463
23434
  let retryAt = 0;
23464
23435
  let allowed = false;
23436
+ const banner = createRendererCodexUsageBanner();
23465
23437
  const release = () => {
23438
+ banner.restore();
23466
23439
  const previous = [...projections.values()];
23467
23440
  owner = null;
23468
23441
  projections.clear();
@@ -23474,24 +23447,30 @@ Codex Fast mode prioritizes requests and may increase usage.`
23474
23447
  }
23475
23448
  };
23476
23449
  const bind = () => {
23477
- const current = owner ?? findSubmitOwner(composer);
23450
+ const current = findSubmitScope(composer, projections);
23478
23451
  const gates = current && discoverGates(current, projections);
23479
- if (!current || !gates || gates.reserve.length === 0) {
23452
+ if (!current || !gates?.some(([kind]) => kind === "reserve")) {
23480
23453
  throw new Error("Codex usage gate is unavailable");
23481
23454
  }
23482
23455
  owner = current;
23483
- for (const gate of [...gates.reserve, ...gates.account]) {
23484
- if (!projections.has(gate.instance)) projections.set(gate.instance, project2(gate));
23456
+ for (const [kind, gate] of gates) {
23457
+ if (!projections.has(gate.instance)) projections.set(gate.instance, project2(kind, gate));
23485
23458
  }
23486
23459
  return "bypassed";
23487
23460
  };
23488
23461
  const apply = () => {
23462
+ const status = applyGate();
23463
+ if (status === "bypassed" && owner) banner.hide(owner.owner);
23464
+ else banner.restore();
23465
+ return status;
23466
+ };
23467
+ const applyGate = () => {
23489
23468
  if (!allowed || !composer.isConnected) {
23490
23469
  release();
23491
23470
  retryAt = 0;
23492
23471
  return "native";
23493
23472
  }
23494
- if (owner && !isBound(owner, projections.values())) {
23473
+ if (owner && !isBound(projections.values())) {
23495
23474
  release();
23496
23475
  retryAt = 0;
23497
23476
  }
@@ -23619,13 +23598,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
23619
23598
  }
23620
23599
 
23621
23600
  // src/renderer-native-thread.ts
23622
- function isRecord4(value) {
23601
+ function isRecord5(value) {
23623
23602
  return typeof value === "object" && value !== null && !Array.isArray(value);
23624
23603
  }
23625
23604
  async function verifyNativeCodexThread(sendRequest, threadId) {
23626
23605
  const native = await sendRequest("thread/read", { threadId, includeTurns: false });
23627
- const thread = isRecord4(native) ? native.thread : null;
23628
- if (!isRecord4(thread) || thread.id !== threadId || typeof thread.modelProvider !== "string" || !thread.modelProvider || thread.modelProvider === "codexhost" || typeof thread.cliVersion !== "string" || !thread.cliVersion || thread.cliVersion === "codexhost") {
23606
+ const thread = isRecord5(native) ? native.thread : null;
23607
+ if (!isRecord5(thread) || thread.id !== threadId || typeof thread.modelProvider !== "string" || !thread.modelProvider || thread.modelProvider === "codexhost" || typeof thread.cliVersion !== "string" || !thread.cliVersion || thread.cliVersion === "codexhost") {
23629
23608
  throw new Error("Native Thread response cannot establish Codex ownership");
23630
23609
  }
23631
23610
  }
@@ -23704,15 +23683,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
23704
23683
  var CODEX_ACCOUNT_LIST_METHOD = "codexhost/account/list";
23705
23684
  var CODEX_ACCOUNT_REFRESH_METHOD = "codexhost/account/refresh";
23706
23685
  var CODEX_ACCOUNT_CHANGED_METHOD = "codexhost/account/changed";
23707
- function isRecord5(value) {
23686
+ function isRecord6(value) {
23708
23687
  return typeof value === "object" && value !== null && !Array.isArray(value);
23709
23688
  }
23710
23689
  function notifiedThreadId(notification) {
23711
- if (!isRecord5(notification) || !THREAD_USAGE_REFRESH_METHODS.includes(notification.method)) {
23690
+ if (!isRecord6(notification) || !THREAD_USAGE_REFRESH_METHODS.includes(notification.method)) {
23712
23691
  return null;
23713
23692
  }
23714
23693
  const params = notification.params;
23715
- if (!isRecord5(params)) return null;
23694
+ if (!isRecord6(params)) return null;
23716
23695
  const parsed = hostThreadIdSchema.safeParse(params.threadId);
23717
23696
  return parsed.success ? parsed.data : null;
23718
23697
  }
@@ -24030,7 +24009,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24030
24009
  throw new Error("Renderer Account notification callback is unavailable");
24031
24010
  }
24032
24011
  return notifications.addNotificationCallback(CODEX_ACCOUNT_CHANGED_METHOD, (notification) => {
24033
- if (!isRecord5(notification) || notification.method !== CODEX_ACCOUNT_CHANGED_METHOD) return;
24012
+ if (!isRecord6(notification) || notification.method !== CODEX_ACCOUNT_CHANGED_METHOD) return;
24034
24013
  const state = codexAccountChangedSchema.safeParse(notification.params);
24035
24014
  if (state.success) listener(state.data);
24036
24015
  });
@@ -24039,16 +24018,16 @@ Codex Fast mode prioritizes requests and may increase usage.`
24039
24018
  }
24040
24019
 
24041
24020
  // src/renderer-external-queue.ts
24042
- function isRecord6(value) {
24021
+ function isRecord7(value) {
24043
24022
  return value !== null && typeof value === "object" && !Array.isArray(value);
24044
24023
  }
24045
24024
  function installRendererExternalQueue(target) {
24046
- if (!isRecord6(target) || typeof target.getTurnCoordinator !== "function" || typeof target.getConversation !== "function") {
24025
+ if (!isRecord7(target) || typeof target.getTurnCoordinator !== "function" || typeof target.getConversation !== "function") {
24047
24026
  return null;
24048
24027
  }
24049
24028
  const coordinator = target.getTurnCoordinator();
24050
- const queue = isRecord6(coordinator) ? coordinator.serverQueue : null;
24051
- if (!isRecord6(queue) || typeof queue.isEnabled !== "function") return null;
24029
+ const queue = isRecord7(coordinator) ? coordinator.serverQueue : null;
24030
+ if (!isRecord7(queue) || typeof queue.isEnabled !== "function") return null;
24052
24031
  const descriptor = Object.getOwnPropertyDescriptor(queue, "isEnabled");
24053
24032
  if (!descriptor?.writable) return null;
24054
24033
  const original = queue.isEnabled;
@@ -24057,7 +24036,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24057
24036
  const threadId = args[0];
24058
24037
  if (typeof threadId === "string") {
24059
24038
  const conversation = getConversation.call(target, threadId);
24060
- if (isRecord6(conversation) && conversation.id === threadId && // Reserved transport marker from externalThreadValue, retained by
24039
+ if (isRecord7(conversation) && conversation.id === threadId && // Reserved transport marker from externalThreadValue, retained by
24061
24040
  // Desktop in both newly created and hydrated conversation metadata.
24062
24041
  conversation.modelProvider === "codexhost") {
24063
24042
  return false;
@@ -24073,19 +24052,19 @@ Codex Fast mode prioritizes requests and may increase usage.`
24073
24052
 
24074
24053
  // src/renderer-external-steering.ts
24075
24054
  var THREAD_OWNERSHIP_LIST_METHOD2 = "codexhost/thread/ownership/list";
24076
- function isRecord7(value) {
24055
+ function isRecord8(value) {
24077
24056
  return value !== null && typeof value === "object" && !Array.isArray(value);
24078
24057
  }
24079
24058
  function isManager(value) {
24080
- return isRecord7(value) && ["sendRequest", "steerTurn", "startTurn", "getTurnCoordinator"].every(
24059
+ return isRecord8(value) && ["sendRequest", "steerTurn", "startTurn", "getTurnCoordinator"].every(
24081
24060
  (key) => typeof value[key] === "function"
24082
24061
  );
24083
24062
  }
24084
24063
  function submissionHost(manager) {
24085
24064
  const coordinator = manager.getTurnCoordinator();
24086
- const options = isRecord7(coordinator) ? coordinator.options : null;
24087
- const host = isRecord7(options) ? options.submissionHost : null;
24088
- if (!isRecord7(host) || typeof host.getActiveTurnId !== "function" || typeof host.hasPendingTurnStart !== "function") {
24065
+ const options = isRecord8(coordinator) ? coordinator.options : null;
24066
+ const host = isRecord8(options) ? options.submissionHost : null;
24067
+ if (!isRecord8(host) || typeof host.getActiveTurnId !== "function" || typeof host.hasPendingTurnStart !== "function") {
24089
24068
  throw new Error("Desktop turn submission binding is unavailable");
24090
24069
  }
24091
24070
  return {
@@ -24127,20 +24106,20 @@ Codex Fast mode prioritizes requests and may increase usage.`
24127
24106
  var INTERRUPTED_QUEUE_REASON = "Interrupted before the steer was accepted.";
24128
24107
  async function preserveQueuedFollowUps(manager, threadId) {
24129
24108
  const coordinator = manager.getTurnCoordinator();
24130
- if (!isRecord7(coordinator) || typeof coordinator.loadMessages !== "function" || typeof coordinator.readMessages !== "function" || typeof coordinator.mutate !== "function") {
24109
+ if (!isRecord8(coordinator) || typeof coordinator.loadMessages !== "function" || typeof coordinator.readMessages !== "function" || typeof coordinator.mutate !== "function") {
24131
24110
  throw new Error("Desktop follow-up queue binding is unavailable");
24132
24111
  }
24133
24112
  await coordinator.loadMessages.call(coordinator, threadId);
24134
24113
  const messages = coordinator.readMessages.call(coordinator, threadId);
24135
24114
  if (!Array.isArray(messages)) throw new Error("Desktop follow-up queue is unavailable");
24136
24115
  const alreadyPaused = new Set(
24137
- messages.filter((message2) => isRecord7(message2) && message2.pausedReason != null).map((message2) => message2.id)
24116
+ messages.filter((message2) => isRecord8(message2) && message2.pausedReason != null).map((message2) => message2.id)
24138
24117
  );
24139
24118
  return () => {
24140
24119
  coordinator.mutate.call(coordinator, threadId, (current) => {
24141
24120
  if (!Array.isArray(current)) return current;
24142
24121
  return current.map((message2) => {
24143
- if (!isRecord7(message2) || alreadyPaused.has(message2.id) || message2.pausedReason !== INTERRUPTED_QUEUE_REASON)
24122
+ if (!isRecord8(message2) || alreadyPaused.has(message2.id) || message2.pausedReason !== INTERRUPTED_QUEUE_REASON)
24144
24123
  return message2;
24145
24124
  const resumed = { ...message2 };
24146
24125
  delete resumed.pausedReason;
@@ -24161,9 +24140,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
24161
24140
  if ((method === "turn/start" || method === "turn/steer") && prepareTurnInput) {
24162
24141
  params = prepareTurnInput(params);
24163
24142
  }
24164
- const messageId = isRecord7(params) ? params.clientUserMessageId : null;
24165
- const route = typeof messageId === "string" && isRecord7(params) ? routes.get(`${params.threadId}\0${messageId}`) : void 0;
24166
- if (method !== "turn/start" || !isRecord7(params) || !route || route.threadId !== params.threadId) {
24143
+ const messageId = isRecord8(params) ? params.clientUserMessageId : null;
24144
+ const route = typeof messageId === "string" && isRecord8(params) ? routes.get(`${params.threadId}\0${messageId}`) : void 0;
24145
+ if (method !== "turn/start" || !isRecord8(params) || !route || route.threadId !== params.threadId) {
24167
24146
  if (method === "turn/start" && sendTurnStart) {
24168
24147
  return sendTurnStart(params, (input) => {
24169
24148
  if (disposed) throw new Error("External submission binding was disposed");
@@ -24189,7 +24168,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24189
24168
  options
24190
24169
  )
24191
24170
  ).then((response) => {
24192
- if (!isRecord7(response) || typeof response.turnId !== "string" || !response.turnId) {
24171
+ if (!isRecord8(response) || typeof response.turnId !== "string" || !response.turnId) {
24193
24172
  throw new Error("External steering returned no replacement Turn identity");
24194
24173
  }
24195
24174
  return {
@@ -24220,7 +24199,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24220
24199
  ] = args;
24221
24200
  if (typeof threadId !== "string") return originalSteer.apply(manager, args);
24222
24201
  const role = manager.getStreamRole?.(threadId);
24223
- if (isRecord7(role) && role.role === "follower") return originalSteer.apply(manager, args);
24202
+ if (isRecord8(role) && role.role === "follower") return originalSteer.apply(manager, args);
24224
24203
  let host = null;
24225
24204
  let expectedTurnId;
24226
24205
  try {
@@ -24249,15 +24228,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
24249
24228
  if (owner === "codex") return originalSteer.apply(manager, args);
24250
24229
  if (!host) throw new Error("Desktop turn submission binding is unavailable");
24251
24230
  const currentRole = manager.getStreamRole?.(threadId);
24252
- if (isRecord7(currentRole) && currentRole.role === "follower")
24231
+ if (isRecord8(currentRole) && currentRole.role === "follower")
24253
24232
  return originalSteer.apply(manager, args);
24254
24233
  if (!Array.isArray(input) || input.length === 0 || input.some(
24255
- (item) => !isRecord7(item) || item.type !== "text" || typeof item.text !== "string"
24256
- ) || !input.some((item) => isRecord7(item) && typeof item.text === "string" && item.text.trim())) {
24234
+ (item) => !isRecord8(item) || item.type !== "text" || typeof item.text !== "string"
24235
+ ) || !input.some((item) => isRecord8(item) && typeof item.text === "string" && item.text.trim())) {
24257
24236
  throw new Error("External steering requires non-empty text input");
24258
24237
  }
24259
24238
  if (toolOutput != null) throw new Error("External steering cannot replace a tool response");
24260
- if (!isRecord7(restoreMessage) || !isRecord7(restoreMessage.context)) {
24239
+ if (!isRecord8(restoreMessage) || !isRecord8(restoreMessage.context)) {
24261
24240
  throw new Error("Desktop steering message context is unavailable");
24262
24241
  }
24263
24242
  const messageId = typeof clientUserMessageId === "string" && clientUserMessageId ? clientUserMessageId : typeof restoreMessage.id === "string" && restoreMessage.id ? restoreMessage.id : crypto.randomUUID();
@@ -24305,7 +24284,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24305
24284
  },
24306
24285
  onMessageAdded
24307
24286
  );
24308
- if (!isRecord7(response) || !isRecord7(response.turn) || typeof response.turn.id !== "string") {
24287
+ if (!isRecord8(response) || !isRecord8(response.turn) || typeof response.turn.id !== "string") {
24309
24288
  throw new Error("Desktop returned no replacement Turn identity");
24310
24289
  }
24311
24290
  try {
@@ -24336,7 +24315,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24336
24315
  }
24337
24316
 
24338
24317
  // src/renderer-remote-attachments.ts
24339
- function isRecord8(value) {
24318
+ function isRecord9(value) {
24340
24319
  return value !== null && typeof value === "object" && !Array.isArray(value);
24341
24320
  }
24342
24321
  var MAX_IMAGE_BYTES = 20 * 1024 * 1024;
@@ -24388,14 +24367,14 @@ Codex Fast mode prioritizes requests and may increase usage.`
24388
24367
  function createRemoteAttachmentSender(target, hostId2, isCurrent) {
24389
24368
  const prepared = /* @__PURE__ */ new WeakMap();
24390
24369
  return (params, send) => {
24391
- if (hostId2 === "local" || !isRecord8(target) || !isRecord8(params) || typeof params.threadId !== "string" || !Array.isArray(params.input) || typeof target.getConversation !== "function")
24370
+ if (hostId2 === "local" || !isRecord9(target) || !isRecord9(params) || typeof params.threadId !== "string" || !Array.isArray(params.input) || typeof target.getConversation !== "function")
24392
24371
  return send(params);
24393
24372
  const images = params.input.filter(
24394
- (item) => isRecord8(item) && (item.type === "image" || item.type === "localImage")
24373
+ (item) => isRecord9(item) && (item.type === "image" || item.type === "localImage")
24395
24374
  );
24396
24375
  if (images.length === 0) return send(params);
24397
24376
  const conversation = target.getConversation.call(target, params.threadId);
24398
- if (!isRecord8(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
24377
+ if (!isRecord9(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
24399
24378
  return send(params);
24400
24379
  const assertCurrent = () => {
24401
24380
  if (!isCurrent()) throw new Error("Remote attachment connection is no longer available");
@@ -24408,7 +24387,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24408
24387
  const cached2 = prepared.get(params);
24409
24388
  if (cached2) return cached2.then(dispatch);
24410
24389
  const input = params.input;
24411
- const text = input.filter((item) => isRecord8(item) && item.type === "text").map((item) => isRecord8(item) && typeof item.text === "string" ? item.text : "").join("\n");
24390
+ const text = input.filter((item) => isRecord9(item) && item.type === "text").map((item) => isRecord9(item) && typeof item.text === "string" ? item.text : "").join("\n");
24412
24391
  const existingPaths = nativeImagePaths(text);
24413
24392
  const prepare = async () => {
24414
24393
  if (existingPaths.length === images.length) return params;
@@ -24440,7 +24419,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24440
24419
  contents: file2.contents,
24441
24420
  label: `image-${index + 1}.${file2.extension}`
24442
24421
  });
24443
- if (!isRecord8(saved) || !filePath(saved.path) || saved.fsPath !== saved.path) {
24422
+ if (!isRecord9(saved) || !filePath(saved.path) || saved.fsPath !== saved.path) {
24444
24423
  throw new Error("Desktop returned an invalid remote attachment path");
24445
24424
  }
24446
24425
  created.push(saved.path);
@@ -24547,11 +24526,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24547
24526
  }
24548
24527
 
24549
24528
  // src/renderer-manual-compaction.ts
24550
- function isRecord9(value) {
24529
+ function isRecord10(value) {
24551
24530
  return value !== null && typeof value === "object" && !Array.isArray(value);
24552
24531
  }
24553
24532
  function installRendererManualCompaction(target, hostId2, messages) {
24554
- if (!messages || typeof messages.addEventListener !== "function" || typeof messages.removeEventListener !== "function" || !isRecord9(target) || typeof target.registerPendingManualContextCompaction !== "function" || typeof target.getConversation !== "function") {
24533
+ if (!messages || typeof messages.addEventListener !== "function" || typeof messages.removeEventListener !== "function" || !isRecord10(target) || typeof target.registerPendingManualContextCompaction !== "function" || typeof target.getConversation !== "function") {
24555
24534
  return null;
24556
24535
  }
24557
24536
  const register = target.registerPendingManualContextCompaction;
@@ -24560,18 +24539,18 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24560
24539
  const listener = (event) => {
24561
24540
  if (event.source != null && event.source !== messages) return;
24562
24541
  const message2 = event.data;
24563
- if (!isRecord9(message2) || message2.type !== "mcp-notification" || message2.hostId !== hostId2 || message2.method !== THREAD_MANUAL_COMPACTION_STARTED_METHOD) {
24542
+ if (!isRecord10(message2) || message2.type !== "mcp-notification" || message2.hostId !== hostId2 || message2.method !== THREAD_MANUAL_COMPACTION_STARTED_METHOD) {
24564
24543
  return;
24565
24544
  }
24566
24545
  const params = threadManualCompactionStartedSchema.safeParse(message2.params);
24567
24546
  if (!params.success) return;
24568
24547
  const { threadId } = params.data;
24569
24548
  const conversation = getConversation.call(target, threadId);
24570
- if (!isRecord9(conversation) || conversation.id !== threadId || conversation.modelProvider !== "codexhost") {
24549
+ if (!isRecord10(conversation) || conversation.id !== threadId || conversation.modelProvider !== "codexhost") {
24571
24550
  return;
24572
24551
  }
24573
24552
  const role = getStreamRole?.call(target, threadId);
24574
- if (isRecord9(role) && role.role === "follower") return;
24553
+ if (isRecord10(role) && role.role === "follower") return;
24575
24554
  register.call(target, threadId);
24576
24555
  };
24577
24556
  messages.addEventListener("message", listener);
@@ -24786,7 +24765,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24786
24765
  var SIDEBAR_THREAD_HOST_ID_ATTRIBUTE = "data-app-action-sidebar-thread-host-id";
24787
24766
  var SIDEBAR_AGENT_ICON_ATTRIBUTE = "data-codexhost-sidebar-agent-icon";
24788
24767
  var OWNERSHIP_RETRY_DELAYS_MS = [100, 300, 800, 1500, 3e3];
24789
- function isRecord10(value) {
24768
+ function isRecord11(value) {
24790
24769
  return typeof value === "object" && value !== null && !Array.isArray(value);
24791
24770
  }
24792
24771
  function sidebarThreadAttributes(element) {
@@ -24813,19 +24792,19 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24813
24792
  const fiberName = fiberNames[0];
24814
24793
  if (fiberNames.length !== 1 || !fiberName) return null;
24815
24794
  const firstFiber2 = Object.getOwnPropertyDescriptor(element, fiberName)?.value;
24816
- if (!isRecord10(firstFiber2)) return null;
24795
+ if (!isRecord11(firstFiber2)) return null;
24817
24796
  const candidates = /* @__PURE__ */ new Set();
24818
24797
  let fiber = firstFiber2;
24819
24798
  for (let depth = 0; fiber && depth < 12; depth += 1) {
24820
24799
  const props = fiber.memoizedProps;
24821
- if (isRecord10(props) && isRecord10(props.dataAttributes)) {
24800
+ if (isRecord11(props) && isRecord11(props.dataAttributes)) {
24822
24801
  const dataAttributes = props.dataAttributes;
24823
24802
  const threadId = hostThreadIdSchema.safeParse(props.conversationId);
24824
24803
  if (threadId.success && dataAttributes[SIDEBAR_THREAD_ROW_ATTRIBUTE] === rowMarker && dataAttributes[SIDEBAR_THREAD_ID_ATTRIBUTE] === taskKey && dataAttributes[SIDEBAR_THREAD_HOST_ID_ATTRIBUTE] === hostId2) {
24825
24804
  candidates.add(threadId.data);
24826
24805
  }
24827
24806
  }
24828
- fiber = isRecord10(fiber.return) ? fiber.return : null;
24807
+ fiber = isRecord11(fiber.return) ? fiber.return : null;
24829
24808
  }
24830
24809
  return candidates.size === 1 ? candidates.values().next().value ?? null : null;
24831
24810
  }
@@ -25235,7 +25214,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25235
25214
  if (row) finish(row);
25236
25215
  });
25237
25216
  }
25238
- function isRecord11(value) {
25217
+ function isRecord12(value) {
25239
25218
  return typeof value === "object" && value !== null && !Array.isArray(value);
25240
25219
  }
25241
25220
  function firstFiber(element) {
@@ -25245,7 +25224,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25245
25224
  const name = names[0];
25246
25225
  if (names.length !== 1 || !name) return null;
25247
25226
  const value = Object.getOwnPropertyDescriptor(element, name)?.value;
25248
- return isRecord11(value) ? value : null;
25227
+ return isRecord12(value) ? value : null;
25249
25228
  }
25250
25229
  function directForkAncestors(first) {
25251
25230
  const ancestors = [];
@@ -25255,7 +25234,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25255
25234
  if (seen.has(fiber)) return [];
25256
25235
  seen.add(fiber);
25257
25236
  ancestors.push(fiber);
25258
- fiber = isRecord11(fiber.return) ? fiber.return : null;
25237
+ fiber = isRecord12(fiber.return) ? fiber.return : null;
25259
25238
  }
25260
25239
  return ancestors;
25261
25240
  }
@@ -25273,7 +25252,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25273
25252
  let hasForkCallback = false;
25274
25253
  for (const fiber of ancestors) {
25275
25254
  const props = fiber.memoizedProps;
25276
- if (!isRecord11(props)) continue;
25255
+ if (!isRecord12(props)) continue;
25277
25256
  if (!hasForkCallback && typeof props.onFork !== "function" && ownsOtherCallback(fiber, props)) {
25278
25257
  return null;
25279
25258
  }
@@ -25305,7 +25284,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25305
25284
  if (!threadId.success || !turnId.success) return null;
25306
25285
  const fiber = firstFiber(button2);
25307
25286
  const buttonProps = fiber?.memoizedProps;
25308
- if (!fiber || !isRecord11(buttonProps) || !Object.hasOwn(buttonProps, "aria-busy")) return null;
25287
+ if (!fiber || !isRecord12(buttonProps) || !Object.hasOwn(buttonProps, "aria-busy")) return null;
25309
25288
  return forkTargetFromAncestors(button2, threadId.data, turnId.data, directForkAncestors(fiber)) ?? forkTargetFromAncestors(button2, threadId.data, turnId.data, committedReactAncestors(fiber));
25310
25289
  }
25311
25290
  var BrowserRendererForkDom = class {
@@ -25395,7 +25374,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25395
25374
  }
25396
25375
  var DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS = 1e4;
25397
25376
  var DRAFT_PREWARM_POLICY_POLL_INTERVAL_MS = 25;
25398
- function isRecord12(value) {
25377
+ function isRecord13(value) {
25399
25378
  return typeof value === "object" && value !== null && !Array.isArray(value);
25400
25379
  }
25401
25380
  function decodeOpenCodeTransportModelId(value) {
@@ -25560,7 +25539,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25560
25539
  let fiber = findComposerFiber(composer);
25561
25540
  for (let depth = 0; fiber && depth < 120; depth += 1) {
25562
25541
  const props = fiber.memoizedProps;
25563
- if (isRecord12(props) && "conversationId" in props && props.conversationId != null) {
25542
+ if (isRecord13(props) && "conversationId" in props && props.conversationId != null) {
25564
25543
  const candidate = hostThreadIdSchema.safeParse(props.conversationId);
25565
25544
  if (!candidate.success || threadId !== void 0 && threadId !== candidate.data) {
25566
25545
  return null;
@@ -25573,12 +25552,12 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25573
25552
  return threadId;
25574
25553
  }
25575
25554
  function isLegacySevenSlotDraftWrapper(value) {
25576
- if (!Array.isArray(value) || value.length !== 7 || value[3] !== value[5] || value[3] !== value[6] || !isRecord12(value[3]) || typeof value[3].get !== "function" || typeof value[2] !== "string" && value[2] !== null) {
25555
+ if (!Array.isArray(value) || value.length !== 7 || value[3] !== value[5] || value[3] !== value[6] || !isRecord13(value[3]) || typeof value[3].get !== "function" || typeof value[2] !== "string" && value[2] !== null) {
25577
25556
  return false;
25578
25557
  }
25579
25558
  try {
25580
25559
  const draft = value[3].get();
25581
- return isRecord12(draft) && "modelSettings" in draft && "isManuallyChanged" in draft;
25560
+ return isRecord13(draft) && "modelSettings" in draft && "isManuallyChanged" in draft;
25582
25561
  } catch {
25583
25562
  return false;
25584
25563
  }
@@ -25612,8 +25591,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25612
25591
  let fiber = findComposerFiber(composer);
25613
25592
  for (let depth = 0; fiber && depth < 120; depth += 1) {
25614
25593
  const updateQueue = fiber.updateQueue;
25615
- const memoCache = isRecord12(updateQueue) ? updateQueue.memoCache : null;
25616
- const data = isRecord12(memoCache) && Array.isArray(memoCache.data) ? memoCache.data : [];
25594
+ const memoCache = isRecord13(updateQueue) ? updateQueue.memoCache : null;
25595
+ const data = isRecord13(memoCache) && Array.isArray(memoCache.data) ? memoCache.data : [];
25617
25596
  for (const value of data) {
25618
25597
  const draftId = draftIdFromMemoValue(value);
25619
25598
  if (draftId) draftIds.add(draftId);
@@ -25641,7 +25620,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25641
25620
  return ["default", draftIds.values().next().value];
25642
25621
  }
25643
25622
  function isDraftPrewarmPolicyReady(value) {
25644
- return isRecord12(value) && value.state === "ready" && typeof value.hostId === "string" && value.hostId.length > 0 && typeof value.select === "function" && typeof value.clear === "function";
25623
+ return isRecord13(value) && value.state === "ready" && typeof value.hostId === "string" && value.hostId.length > 0 && typeof value.select === "function" && typeof value.clear === "function";
25645
25624
  }
25646
25625
  async function waitForRendererDraftPrewarmPolicy(target, composer) {
25647
25626
  const deadline = Date.now() + DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS;
@@ -25907,11 +25886,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25907
25886
  return null;
25908
25887
  }
25909
25888
  }
25910
- function isRecord13(value) {
25889
+ function isRecord14(value) {
25911
25890
  return typeof value === "object" && value !== null && !Array.isArray(value);
25912
25891
  }
25913
25892
  function parseExternalConfiguration(value) {
25914
- if (!isRecord13(value)) return void 0;
25893
+ if (!isRecord14(value)) return void 0;
25915
25894
  const model2 = harnessModelRefSchema.safeParse(value.model);
25916
25895
  if (!model2.success) return void 0;
25917
25896
  const thinkingOptionId = harnessThinkingOptionIdSchema.safeParse(value.thinkingOptionId);
@@ -25928,10 +25907,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25928
25907
  const raw = storage.getItem(RENDERER_NEW_THREAD_PREFERENCE_KEY);
25929
25908
  if (!raw) return void 0;
25930
25909
  const parsed = JSON.parse(raw);
25931
- if (!isRecord13(parsed) || parsed.version !== 1) return void 0;
25910
+ if (!isRecord14(parsed) || parsed.version !== 1) return void 0;
25932
25911
  if (parsed.lastAgent !== "codex" && !harnessPluginIdSchema.safeParse(parsed.lastAgent).success)
25933
25912
  return void 0;
25934
- const externalByAgent = isRecord13(parsed.externalByAgent) ? parsed.externalByAgent : {};
25913
+ const externalByAgent = isRecord14(parsed.externalByAgent) ? parsed.externalByAgent : {};
25935
25914
  const parsedExternal = Object.fromEntries(
25936
25915
  Object.keys(externalByAgent).filter((agent) => harnessPluginIdSchema.safeParse(agent).success).flatMap((agent) => {
25937
25916
  const configuration = parseExternalConfiguration(externalByAgent[agent]);
@@ -26057,7 +26036,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26057
26036
  var GET_LOCALE_OVERRIDE_URL = "vscode://codex/get-setting";
26058
26037
  var GET_LOCALE_INFO_URL = "vscode://codex/locale-info";
26059
26038
  var DEFAULT_LOCALE_REQUEST_TIMEOUT_MS = 750;
26060
- function isRecord14(value) {
26039
+ function isRecord15(value) {
26061
26040
  return typeof value === "object" && value !== null && !Array.isArray(value);
26062
26041
  }
26063
26042
  function canonicalLocale(value) {
@@ -26079,7 +26058,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26079
26058
  return new DOMException("The operation was aborted", "AbortError");
26080
26059
  }
26081
26060
  function parseLocaleOverride(value) {
26082
- if (!isRecord14(value) || !("value" in value)) {
26061
+ if (!isRecord15(value) || !("value" in value)) {
26083
26062
  throw new Error("Codex locale override response is malformed");
26084
26063
  }
26085
26064
  if (value.value === null) return { value: null };
@@ -26094,7 +26073,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26094
26073
  return locale;
26095
26074
  }
26096
26075
  function parseLocaleInfo(value) {
26097
- if (!isRecord14(value)) throw new Error("Codex locale info response is malformed");
26076
+ if (!isRecord15(value)) throw new Error("Codex locale info response is malformed");
26098
26077
  return {
26099
26078
  ideLocale: optionalLocale(value.ideLocale, "IDE locale"),
26100
26079
  systemLocale: optionalLocale(value.systemLocale, "system locale")
@@ -26123,7 +26102,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26123
26102
  const onAbort = () => settle(() => reject(abortError2()));
26124
26103
  const onMessage = (event) => {
26125
26104
  const message3 = event.data;
26126
- if (!isRecord14(message3) || message3.type !== "fetch-response") return;
26105
+ if (!isRecord15(message3) || message3.type !== "fetch-response") return;
26127
26106
  if (message3.requestId !== requestId) return;
26128
26107
  if (message3.responseType !== "success" || typeof message3.status !== "number" || message3.status < 200 || message3.status >= 300 || typeof message3.bodyJsonString !== "string") {
26129
26108
  settle(() => reject(new Error("Codex locale request failed")));
@@ -31049,31 +31028,6 @@ ${detail}` : ""}`
31049
31028
  description.className = "settings-page-description";
31050
31029
  description.textContent = messages.appearanceDescription;
31051
31030
  const { group, card } = createPreferenceGroup(document2, messages.appearanceGroup);
31052
- const usageBannerId = preferenceId("hide-codex-usage-banner");
31053
- const usageBannerRow = createPreferenceItem(document2, {
31054
- title: messages.hideCodexUsageBannerTitle,
31055
- description: messages.hideCodexUsageBannerDescription,
31056
- controlId: usageBannerId,
31057
- help: {
31058
- label: messages.hideCodexUsageBannerHelpLabel,
31059
- lines: messages.hideCodexUsageBannerHelp
31060
- }
31061
- });
31062
- const usageBanner = createPreferenceSwitch(
31063
- document2,
31064
- usageBannerId,
31065
- usageBannerRow.description.id
31066
- );
31067
- usageBanner.checked = readCodexUsageBannerPreference(ownerWindow);
31068
- usageBanner.addEventListener("change", () => {
31069
- writeCodexUsageBannerPreference(ownerWindow, usageBanner.checked);
31070
- });
31071
- const syncUsageBanner = () => {
31072
- usageBanner.checked = readCodexUsageBannerPreference(ownerWindow);
31073
- };
31074
- ownerWindow.addEventListener(CODEX_USAGE_BANNER_CHANGE_EVENT, syncUsageBanner);
31075
- usageBannerRow.item.append(usageBanner);
31076
- card.append(usageBannerRow.item);
31077
31031
  const liveVoiceId = preferenceId("cpa-live-voice");
31078
31032
  const liveVoiceRow = createPreferenceItem(document2, {
31079
31033
  title: messages.cpaLiveVoiceTitle,
@@ -31123,7 +31077,6 @@ ${detail}` : ""}`
31123
31077
  getLoadedSessionsClient
31124
31078
  );
31125
31079
  return () => {
31126
- ownerWindow.removeEventListener(CODEX_USAGE_BANNER_CHANGE_EVENT, syncUsageBanner);
31127
31080
  ownerWindow.removeEventListener(CPA_LIVE_VOICE_CHANGE_EVENT, syncLiveVoice);
31128
31081
  ownerWindow.removeEventListener(REASONING_SOFT_WRAP_CHANGE_EVENT, sync);
31129
31082
  disposeIdleRelease();
@@ -39867,7 +39820,7 @@ ${usage_default}`;
39867
39820
  const currentCodexAccount = accounts?.accounts.find(
39868
39821
  ({ accountId }) => accountId === accounts.readyAccountId
39869
39822
  );
39870
- const usageGateAllowed = renderComposerAgentControl(
39823
+ const externalSubmissionReady = renderComposerAgentControl(
39871
39824
  mounted.control,
39872
39825
  controller.get(mounted.composer),
39873
39826
  composerAdapterState(mounted),
@@ -39881,7 +39834,7 @@ ${usage_default}`;
39881
39834
  currentCodexAccount ?? null,
39882
39835
  mounted.ownershipStatus === "error"
39883
39836
  );
39884
- showCodexUsageGateStatus(mounted, mounted.codexUsageGate.update(usageGateAllowed));
39837
+ showCodexUsageGateStatus(mounted, mounted.codexUsageGate.update(externalSubmissionReady));
39885
39838
  if (mounted.control.usage) {
39886
39839
  mounted.control.usage.onOpen = () => {
39887
39840
  void refreshThreadUsage(
@@ -41586,23 +41539,10 @@ ${usage_default}`;
41586
41539
  }
41587
41540
  }
41588
41541
  };
41589
- const onUsageBannerPreference = () => {
41590
- for (const mounted of mountedByComposer.values()) {
41591
- const hideCodexControls = controller.isSwitching(mounted.composer) || controller.get(mounted.composer).agent !== "codex";
41592
- reconcileComposerNativeControls(mounted.control, hideCodexControls, hideCodexControls);
41593
- }
41594
- };
41595
- const onUsageBannerStorage = (event) => {
41596
- if (event.key === CODEX_USAGE_BANNER_STORAGE_KEY || event.key === null) {
41597
- onUsageBannerPreference();
41598
- }
41599
- };
41600
41542
  window.addEventListener("codexhost:draft-prewarm-policy-changed", onHostRouteChange);
41601
41543
  window.addEventListener("codexhost:draft-workspace", onDraftWorkspace);
41602
41544
  window.addEventListener("codexhost:renderer-adapter-status", onAdapterStatus);
41603
41545
  window.addEventListener("focus", onWindowFocus);
41604
- window.addEventListener(CODEX_USAGE_BANNER_CHANGE_EVENT, onUsageBannerPreference);
41605
- window.addEventListener("storage", onUsageBannerStorage);
41606
41546
  delegationMention = installRendererDelegationMention(document, {
41607
41547
  onOpen: (editor) => {
41608
41548
  const composer = composerForElement(editor);
@@ -41766,8 +41706,6 @@ ${usage_default}`;
41766
41706
  window.removeEventListener("codexhost:draft-workspace", onDraftWorkspace);
41767
41707
  window.removeEventListener("codexhost:renderer-adapter-status", onAdapterStatus);
41768
41708
  window.removeEventListener("focus", onWindowFocus);
41769
- window.removeEventListener(CODEX_USAGE_BANNER_CHANGE_EVENT, onUsageBannerPreference);
41770
- window.removeEventListener("storage", onUsageBannerStorage);
41771
41709
  for (const state of harnessAvailabilityByHost.values()) {
41772
41710
  state.requestGeneration += 1;
41773
41711
  state.codexAccounts?.dispose();
@@ -41816,8 +41754,127 @@ ${usage_default}`;
41816
41754
  return binding;
41817
41755
  }
41818
41756
 
41757
+ // src/renderer-external-voice-launch.ts
41758
+ var HOOK_GLOBAL = "__codexhostExternalVoiceLaunchV1";
41759
+ var SHARED_ASSET = "app-shared-8bd9d0399038.js";
41760
+ function isRecord16(value) {
41761
+ return typeof value === "object" && value !== null && !Array.isArray(value);
41762
+ }
41763
+ function routeExternalVoiceLaunch(request, routing) {
41764
+ if (!routing || !isRecord16(request) || request.source !== "composer_button_new_thread")
41765
+ return request;
41766
+ const hostId2 = request.hostId ?? "local";
41767
+ if (typeof hostId2 !== "string" || !hostId2) return request;
41768
+ const route = routing.forComposer();
41769
+ if (!route || route.hostId !== hostId2 || routing.forHost(hostId2) !== route) return request;
41770
+ const model2 = route.policy.selectedModel();
41771
+ if (!model2?.startsWith("codexhost/")) return request;
41772
+ const mode = request.activeCollaborationMode;
41773
+ if (mode !== void 0 && mode !== null && !isRecord16(mode)) return request;
41774
+ const settings = isRecord16(mode) ? mode.settings : void 0;
41775
+ if (settings !== void 0 && settings !== null && !isRecord16(settings)) return request;
41776
+ return {
41777
+ ...request,
41778
+ activeCollaborationMode: {
41779
+ ...isRecord16(mode) ? mode : { mode: "default" },
41780
+ settings: {
41781
+ reasoning_effort: null,
41782
+ developer_instructions: null,
41783
+ ...isRecord16(settings) ? settings : {},
41784
+ model: model2
41785
+ }
41786
+ }
41787
+ };
41788
+ }
41789
+ function installExternalVoiceLaunchHook(options = {}) {
41790
+ const target = options.target ?? globalThis;
41791
+ const existing = target[HOOK_GLOBAL];
41792
+ if (existing) return existing;
41793
+ const config2 = readCpaLiveVoiceHookConfig(target);
41794
+ if (!config2) return { status: "disabled", dispose() {
41795
+ } };
41796
+ if (config2.auditedDesktopVersion !== AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION || config2.auditedAppInitialAsset !== AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET || config2.desktopVersion !== void 0 && config2.desktopVersion !== config2.auditedDesktopVersion)
41797
+ return { status: "unsupported", dispose() {
41798
+ } };
41799
+ const importModule = options.importModule ?? ((url2) => import(url2));
41800
+ let disposed = false;
41801
+ let timer;
41802
+ let restore;
41803
+ let module;
41804
+ const started = Date.now();
41805
+ const handle = {
41806
+ status: "pending",
41807
+ dispose() {
41808
+ disposed = true;
41809
+ if (timer !== void 0) target.clearTimeout(timer);
41810
+ restore?.();
41811
+ if (target[HOOK_GLOBAL] === handle) Reflect.deleteProperty(target, HOOK_GLOBAL);
41812
+ }
41813
+ };
41814
+ target[HOOK_GLOBAL] = handle;
41815
+ const attempt = async () => {
41816
+ if (disposed) return;
41817
+ try {
41818
+ const names = target.performance?.getEntriesByType("resource").map((entry) => entry.name) ?? [];
41819
+ for (const element of target.document?.querySelectorAll("script[src], link[href]") ?? []) {
41820
+ const name = element.getAttribute("src") ?? element.getAttribute("href");
41821
+ if (name) names.push(name);
41822
+ }
41823
+ if (auditedAppInitialAssetPresent(names, AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET) && auditedAppInitialAssetPresent(names, SHARED_ASSET)) {
41824
+ module ??= await importModule(`app://-/assets/${SHARED_ASSET}`);
41825
+ if (disposed) return;
41826
+ const services = module?.fN;
41827
+ if (isRecord16(services)) {
41828
+ const original = services.realtimeVoiceRuntime;
41829
+ if (typeof original === "function" || isRecord16(original)) {
41830
+ const start = Reflect.get(original, "requestRealtimeStart");
41831
+ if (typeof start !== "function") {
41832
+ handle.status = "unsupported";
41833
+ return;
41834
+ }
41835
+ const launch = (...args) => {
41836
+ let request = args[0];
41837
+ try {
41838
+ request = routeExternalVoiceLaunch(request, target.__codexhostHostRoutingV1);
41839
+ } catch {
41840
+ }
41841
+ return Reflect.apply(start, original, [request, ...args.slice(1)]);
41842
+ };
41843
+ const wrapped = new Proxy(original, {
41844
+ get(service, key, receiver) {
41845
+ return key === "requestRealtimeStart" ? launch : Reflect.get(service, key, receiver);
41846
+ }
41847
+ });
41848
+ if (!Reflect.set(services, "realtimeVoiceRuntime", wrapped)) {
41849
+ handle.status = "unsupported";
41850
+ return;
41851
+ }
41852
+ restore = () => {
41853
+ if (services.realtimeVoiceRuntime === wrapped)
41854
+ services.realtimeVoiceRuntime = original;
41855
+ };
41856
+ handle.status = "active";
41857
+ return;
41858
+ }
41859
+ }
41860
+ }
41861
+ } catch {
41862
+ handle.status = "unsupported";
41863
+ return;
41864
+ }
41865
+ if (Date.now() - started >= 6e4) {
41866
+ handle.status = "unsupported";
41867
+ return;
41868
+ }
41869
+ timer = target.setTimeout(() => void attempt(), 250);
41870
+ };
41871
+ void attempt();
41872
+ return handle;
41873
+ }
41874
+
41819
41875
  // src/production-entry.ts
41820
41876
  installCpaLiveVoiceHook();
41877
+ installExternalVoiceLaunchHook();
41821
41878
  var installBinding = () => {
41822
41879
  installRendererBinding();
41823
41880
  };