@codexhost/cli-darwin-x64 0.1.6 → 0.2.1

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.
@@ -7,8 +7,14 @@
7
7
  };
8
8
 
9
9
  // src/agent-selection-state.ts
10
- var KNOWN_RENDERER_AGENTS = ["codex", "pi", "claude-code"];
11
- var DEFAULT_RENDERER_AGENTS = ["codex", "pi", "claude-code"];
10
+ var KNOWN_RENDERER_AGENTS = [
11
+ "codex",
12
+ "pi",
13
+ "claude-code",
14
+ "deepseek-harness",
15
+ "grok"
16
+ ];
17
+ var DEFAULT_RENDERER_AGENTS = KNOWN_RENDERER_AGENTS;
12
18
  function defaultIdFactory(sequence) {
13
19
  return `codexhost-composer-${Date.now().toString(36)}-${sequence.toString(36)}`;
14
20
  }
@@ -112,19 +118,18 @@
112
118
  state.phase = "locked";
113
119
  if (agent === "pi" && model) state.piModel = model;
114
120
  if (agent === "claude-code" && model) state.claudeModel = model;
115
- if (agent === "pi" && thinkingOptionId) {
116
- state.piThinkingOptionId = thinkingOptionId;
117
- } else if (agent === "pi") {
118
- delete state.piThinkingOptionId;
119
- }
121
+ if (agent === "deepseek-harness" && model) state.deepSeekHarnessModel = model;
122
+ if (agent === "grok" && model) state.grokModel = model;
123
+ if (agent === "pi" && thinkingOptionId) state.piThinkingOptionId = thinkingOptionId;
124
+ else if (agent === "pi") delete state.piThinkingOptionId;
120
125
  if (agent === "claude-code" && thinkingOptionId) {
121
126
  state.claudeThinkingOptionId = thinkingOptionId;
122
- } else if (agent === "claude-code") {
123
- delete state.claudeThinkingOptionId;
124
- }
127
+ } else if (agent === "claude-code") delete state.claudeThinkingOptionId;
128
+ if (agent === "grok" && thinkingOptionId) state.grokThinkingOptionId = thinkingOptionId;
129
+ else if (agent === "grok") delete state.grokThinkingOptionId;
125
130
  if (agent !== "codex") {
126
131
  const permissionModeByAgent = {};
127
- for (const candidate of ["pi", "claude-code"]) {
132
+ for (const candidate of ["pi", "claude-code", "deepseek-harness", "grok"]) {
128
133
  const current = state.permissionModeByAgent?.[candidate];
129
134
  if (candidate !== agent && current) permissionModeByAgent[candidate] = current;
130
135
  }
@@ -139,11 +144,16 @@
139
144
  }
140
145
  modelForAgent(composer, agent) {
141
146
  const state = this.#state(composer);
142
- return agent === "pi" ? state.piModel : agent === "claude-code" ? state.claudeModel : void 0;
147
+ if (agent === "pi") return state.piModel;
148
+ if (agent === "claude-code") return state.claudeModel;
149
+ if (agent === "deepseek-harness") return state.deepSeekHarnessModel;
150
+ return agent === "grok" ? state.grokModel : void 0;
143
151
  }
144
152
  thinkingOptionForAgent(composer, agent) {
145
153
  const state = this.#state(composer);
146
- return agent === "pi" ? state.piThinkingOptionId : state.claudeThinkingOptionId;
154
+ if (agent === "pi") return state.piThinkingOptionId;
155
+ if (agent === "claude-code") return state.claudeThinkingOptionId;
156
+ return agent === "grok" ? state.grokThinkingOptionId : void 0;
147
157
  }
148
158
  permissionModeForAgent(composer, agent) {
149
159
  return this.#state(composer).permissionModeByAgent?.[agent];
@@ -159,7 +169,9 @@
159
169
  setExternalModel(composer, agent, model) {
160
170
  const state = this.#state(composer);
161
171
  if (agent === "pi") state.piModel = model;
162
- else state.claudeModel = model;
172
+ else if (agent === "claude-code") state.claudeModel = model;
173
+ else if (agent === "deepseek-harness") state.deepSeekHarnessModel = model;
174
+ else state.grokModel = model;
163
175
  return state;
164
176
  }
165
177
  setPiConfiguration(composer, model, thinkingOptionId) {
@@ -176,8 +188,15 @@
176
188
  const state = this.#state(composer);
177
189
  if (agent === "pi" && thinkingOptionId) state.piThinkingOptionId = thinkingOptionId;
178
190
  else if (agent === "pi") delete state.piThinkingOptionId;
179
- else if (thinkingOptionId) state.claudeThinkingOptionId = thinkingOptionId;
180
- else delete state.claudeThinkingOptionId;
191
+ else if (agent === "claude-code" && thinkingOptionId) {
192
+ state.claudeThinkingOptionId = thinkingOptionId;
193
+ } else if (agent === "claude-code") {
194
+ delete state.claudeThinkingOptionId;
195
+ } else if (agent === "grok" && thinkingOptionId) {
196
+ state.grokThinkingOptionId = thinkingOptionId;
197
+ } else if (agent === "grok") {
198
+ delete state.grokThinkingOptionId;
199
+ }
181
200
  return state;
182
201
  }
183
202
  setPiThinkingOption(composer, thinkingOptionId) {
@@ -14903,6 +14922,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14903
14922
  cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
14904
14923
  cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
14905
14924
  outputTokens: nonNegativeSafeIntegerSchema.optional(),
14925
+ outputTokensPerSecond: finiteNonNegativeNumberSchema.optional(),
14906
14926
  reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
14907
14927
  totalTokens: nonNegativeSafeIntegerSchema.optional(),
14908
14928
  totalCostUsd: finiteNonNegativeNumberSchema.optional(),
@@ -14930,12 +14950,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14930
14950
  });
14931
14951
  }
14932
14952
  });
14953
+ var usagePercentSchema = external_exports.number().finite().min(0).max(100);
14954
+ var accountCreditsProductUsageSchema = external_exports.object({
14955
+ product: external_exports.string().min(1),
14956
+ usagePercent: usagePercentSchema
14957
+ }).strict();
14958
+ var accountCreditsSnapshotSchema = external_exports.object({
14959
+ usedPercent: usagePercentSchema,
14960
+ resetsAt: external_exports.string().min(1).optional(),
14961
+ periodType: external_exports.enum(["weekly", "monthly", "unknown"]),
14962
+ productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional()
14963
+ }).strict();
14933
14964
  var threadUsageInspectionParamsSchema = external_exports.object({
14934
14965
  threadId: hostThreadIdSchema
14935
14966
  }).strict();
14936
14967
  var threadUsageInspectionSchema = external_exports.object({
14937
14968
  threadId: hostThreadIdSchema,
14938
- usage: threadUsageSnapshotSchema.nullable()
14969
+ usage: threadUsageSnapshotSchema.nullable(),
14970
+ accountCredits: accountCreditsSnapshotSchema.optional()
14939
14971
  }).strict();
14940
14972
 
14941
14973
  // ../shared-contracts/dist/harness-models.js
@@ -15292,11 +15324,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15292
15324
  // src/assets/codex-agent.png
15293
15325
  var codex_agent_default = "data:image/png;base64,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";
15294
15326
 
15327
+ // src/assets/grok-agent.png
15328
+ var grok_agent_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAAEk9JREFUeNrtnQdsHEUXx5fee40xnQiQ6b23IAiJAWHACV10AQHRRG8GDJgSOggEGAEBg6gGhAIBQknoppjeezGE3kybb3+je6f1fVdm93Z2Zy870iPmfN67mffmzSv/98bzLIxZZpml2ad2n7p86vWp36cBnwZ9UjlVpcHCWvUX1q6rsJbNnsvD/4ItPnX41Jcz0Rr1Fda4xSXGt/k0MWdO4sSat6XJ+FafpuaMSJ3gQWuSjG/yaUK+8M4RPGmyzfyxPk3LF9tZgjdjbTG/M1/gzFBn3Mzvzhc1c9QdF/N78sXMLPXkO386o5lnnllT3ZogP/OzRzPNNJOac8451bBhw0qFoDOKtZ8vasZ2Pv/uuOOOaoklltDCUPKesWH8/NzVyxjzfdapcePGqa222kr/XMFFbDIRgDzIkzGC4Yceeqg6/fTTKzG/GCwyCe/mi5ox5u+3337q4YcfVvPNN1851V9KrdUEII/tZ4z5e++9t/rmm2/UeuutV2v3F3MH1bJ6+cJmiPnt7e3q77//VieccIIp84XayglAntLNEPO33XZb9dtvv2nVP9tss5mo/iGp5HJgjnxxM8L8TTbZRKv9adOmqVVWWSXs7hdqCQpAR7642WD+hhtuqD777DPFOProo6MyH+oICkAO48oY8ydNmqTmmmuusKp/CLwsCOCcbgImLBg044wz6kUtpRlmmKH4npJwaqrMX3PNNdXHH3+smf/zzz+HsfqrUbNXQJw2dIQsyFx2zSKLLKKWWWYZtfrqq+uFFFpttdXUsssuqxZeeGE199xz6/cH/z4NgeBzV1hhBfX2228rGeecc04czIfavQLsuKESIsIwmI2RNGbMGHX++eere++9V73wwgvq888/Vz/88IP69ddf1e+//16kX375Rb+Omn3xxRf1+y+44AK1++67q1VXXVU/T55dh+oNxfyll15avfzyy0XmIwiLLbaY1mAxfEaXV8CeN8QZCS244IJq9OjR6tJLL1V9fX2aqeXGf//9p+nff/8tkrxWbvCcV155RV1++eVq1KhR+nPkM23NZ6mlllLPPfec/nz5fvvvv3+cn9nrFQoQMq3iUdXrrLOOuuiii9S77747hIn8/M8//9RNpc9855139Oet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";
15329
+
15295
15330
  // src/renderer-agent-icon.ts
15296
15331
  var RENDERER_AGENT_LABELS = {
15297
15332
  codex: "Codex",
15298
15333
  pi: "Pi",
15299
- "claude-code": "Claude Code"
15334
+ "claude-code": "Claude Code",
15335
+ "deepseek-harness": "DeepSeek Harness",
15336
+ grok: "Grok"
15300
15337
  };
15301
15338
  var PI_PATHS = [
15302
15339
  {
@@ -15305,10 +15342,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15305
15342
  },
15306
15343
  { d: "M17.5 12H23v11h-5.5V12z" }
15307
15344
  ];
15345
+ var DEEPSEEK_HARNESS_WHALE_PATH = "M22.9168 1.43018C22.6713 1.31018 22.5658 1.53918 22.4223 1.65519C22.3733 1.69269 22.3318 1.74169 22.2903 1.78669C21.9317 2.1697 21.5127 2.42121 20.9657 2.39121C20.1657 2.34621 19.4827 2.59771 18.8787 3.20973C18.7502 2.45521 18.3236 2.0047 17.6746 1.71569C17.3351 1.56568 16.9916 1.41518 16.7536 1.08867C16.5876 0.856163 16.5421 0.597155 16.4591 0.341647C16.4061 0.187643 16.3536 0.0301382 16.1761 0.00363739C15.9836 -0.0263635 15.9081 0.135141 15.8326 0.270145C15.5306 0.822162 15.4136 1.43018 15.4251 2.0462C15.4516 3.43174 16.0366 4.53527 17.1991 5.3203C17.3311 5.4103 17.3651 5.5003 17.3236 5.63181C17.2441 5.90231 17.1501 6.16482 17.0671 6.43533C17.0141 6.60784 16.9351 6.64584 16.7501 6.57033C16.1121 6.30383 15.5611 5.90931 15.074 5.4328C14.2475 4.63328 13.5 3.75075 12.568 3.05973C12.349 2.89822 12.13 2.74822 11.9034 2.60522C10.9524 1.68169 12.028 0.923165 12.277 0.833162C12.5375 0.739159 12.3675 0.41615 11.5259 0.42015C10.6844 0.42365 9.91439 0.705658 8.93286 1.08117C8.78935 1.13767 8.63835 1.17867 8.48384 1.21267C7.59332 1.04367 6.66829 1.00617 5.70226 1.11517C3.88321 1.31768 2.43016 2.1777 1.36213 3.64575C0.0790928 5.4103 -0.222916 7.41536 0.146595 9.50642C0.535106 11.7105 1.66014 13.535 3.38869 14.9616C5.18125 16.4406 7.24581 17.1657 9.60138 17.0266C11.0319 16.9441 12.6245 16.7526 14.421 15.2321C14.874 15.4576 15.3496 15.5476 16.1381 15.6151C16.7456 15.6716 17.3306 15.5851 17.7836 15.4911C18.4931 15.3411 18.4441 14.6841 18.1876 14.5636C16.1081 13.595 16.5646 13.9891 16.1496 13.67C17.2061 12.42 18.8202 10.1979 19.3182 7.17235C19.3672 6.83834 19.4297 6.36783 19.4222 6.09732C19.4182 5.93231 19.4562 5.86831 19.6447 5.84931C20.1657 5.78931 20.6712 5.64681 21.1357 5.3913C22.4833 4.65528 23.0268 3.44624 23.1548 1.9972C23.1738 1.77569 23.1508 1.54668 22.9168 1.43018ZM11.1749 14.4736C9.15936 12.889 8.18184 12.3675 7.77832 12.39C7.40081 12.4125 7.46881 12.8445 7.55182 13.126C7.63882 13.404 7.75182 13.5955 7.91033 13.8396C8.01983 14.0011 8.09533 14.2411 7.80083 14.4216C7.15181 14.8231 6.02327 14.2866 5.97027 14.2601C4.65673 13.4865 3.5587 12.4655 2.78467 11.069C2.03715 9.72493 1.60314 8.28289 1.53164 6.74384C1.51264 6.37233 1.62214 6.24082 1.99215 6.17332C2.47916 6.08332 2.98118 6.06432 3.46769 6.13582C5.52476 6.43633 7.27581 7.35586 8.74385 8.8129C9.58188 9.64243 10.2159 10.634 10.8689 11.6025C11.5634 12.631 12.3105 13.611 13.262 14.4146C13.598 14.6961 13.866 14.9101 14.1225 15.0681C13.349 15.1546 12.058 15.1731 11.1749 14.4746L11.1749 14.4736ZM12.141 8.25988C12.141 8.09488 12.273 7.96338 12.439 7.96338C12.4765 7.96338 12.5105 7.97088 12.541 7.98188C12.5825 7.99688 12.6205 8.01938 12.6505 8.05338C12.7035 8.10588 12.7335 8.18088 12.7335 8.25988C12.7335 8.42489 12.6015 8.55639 12.4355 8.55639C12.2695 8.55639 12.141 8.42489 12.141 8.25988ZM15.1415 9.79893C14.949 9.87793 14.7565 9.94544 14.5715 9.95294C14.2845 9.96794 13.9715 9.85143 13.8015 9.70893C13.5375 9.48742 13.3485 9.36342 13.2695 8.97691C13.2355 8.8119 13.2545 8.55639 13.2845 8.40989C13.3525 8.09438 13.277 7.89187 13.0545 7.70787C12.8735 7.55786 12.643 7.51636 12.39 7.51636C12.2955 7.51636 12.209 7.47486 12.1445 7.44136C12.039 7.38886 11.9519 7.25735 12.035 7.09585C12.0615 7.04335 12.19 6.91584 12.22 6.89334C12.5635 6.69784 12.9595 6.76184 13.326 6.90834C13.6655 7.04735 13.9225 7.30236 14.292 7.66287C14.6695 8.09838 14.7375 8.21838 14.9525 8.54539C15.1225 8.8009 15.277 9.06341 15.3831 9.36392C15.4471 9.55142 15.3641 9.70493 15.1415 9.79893Z";
15308
15346
  var CLAUDE_PATH = "M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z";
15309
- function createSvgIcon(paths, color, size, ownerDocument) {
15347
+ function createSvgIcon(paths, color, size, ownerDocument, viewBox = "0 0 24 24") {
15310
15348
  const svg = ownerDocument.createElementNS("http://www.w3.org/2000/svg", "svg");
15311
- svg.setAttribute("viewBox", "0 0 24 24");
15349
+ svg.setAttribute("viewBox", viewBox);
15312
15350
  svg.setAttribute("aria-hidden", "true");
15313
15351
  svg.style.width = `${size}px`;
15314
15352
  svg.style.height = `${size}px`;
@@ -15335,13 +15373,36 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15335
15373
  return image;
15336
15374
  }
15337
15375
  if (agent === "pi") return createSvgIcon(PI_PATHS, "currentColor", size, ownerDocument);
15338
- return createSvgIcon([{ d: CLAUDE_PATH }], "#d97757", size, ownerDocument);
15376
+ if (agent === "claude-code") {
15377
+ return createSvgIcon([{ d: CLAUDE_PATH }], "#d97757", size, ownerDocument);
15378
+ }
15379
+ if (agent === "deepseek-harness") {
15380
+ return createSvgIcon(
15381
+ [{ d: DEEPSEEK_HARNESS_WHALE_PATH }],
15382
+ "#4D6BFE",
15383
+ size,
15384
+ ownerDocument,
15385
+ "0 0 23.16 17.04"
15386
+ );
15387
+ }
15388
+ const mark = ownerDocument.createElement("img");
15389
+ mark.src = grok_agent_default;
15390
+ mark.alt = "";
15391
+ mark.draggable = false;
15392
+ mark.style.width = `${size}px`;
15393
+ mark.style.height = `${size}px`;
15394
+ mark.style.objectFit = "contain";
15395
+ mark.style.borderRadius = "22.37%";
15396
+ mark.style.flex = "none";
15397
+ return mark;
15339
15398
  }
15340
15399
 
15341
15400
  // src/renderer-agent-picker.ts
15342
15401
  var RENDERER_AGENT_INSTALL_URLS = {
15343
15402
  pi: "https://pi.dev/",
15344
- "claude-code": "https://code.claude.com/docs/en/quickstart"
15403
+ "claude-code": "https://code.claude.com/docs/en/quickstart",
15404
+ "deepseek-harness": "https://github.com/deepseek-ai/deepseek-harness",
15405
+ grok: "https://grok.com/"
15345
15406
  };
15346
15407
  var CONTROL_ATTRIBUTE = "data-codexhost-agent-control";
15347
15408
  function rendererAgentPickerView(state, adapterState, switching, agents, availability = {}) {
@@ -15396,7 +15457,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15396
15457
  trigger.style.width = "30px";
15397
15458
  trigger.style.height = "28px";
15398
15459
  trigger.style.padding = "0";
15399
- trigger.style.border = "1px solid rgba(127, 127, 127, 0.28)";
15460
+ trigger.style.border = "0";
15400
15461
  trigger.style.borderRadius = "6px";
15401
15462
  trigger.style.background = "rgba(127, 127, 127, 0.08)";
15402
15463
  trigger.style.color = "inherit";
@@ -15436,7 +15497,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15436
15497
  menu.style.inset = "auto";
15437
15498
  menu.style.width = "190px";
15438
15499
  menu.style.padding = "4px";
15439
- menu.style.border = "1px solid rgba(127, 127, 127, 0.35)";
15500
+ menu.style.border = "0";
15440
15501
  menu.style.borderRadius = "6px";
15441
15502
  menu.style.background = "Canvas";
15442
15503
  menu.style.color = "CanvasText";
@@ -15665,9 +15726,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15665
15726
 
15666
15727
  // src/renderer-model-picker.ts
15667
15728
  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";
15668
- var MENU_CLASSES = "fixed z-50 overflow-hidden rounded-xl bg-token-dropdown-background/90 text-token-foreground shadow-lg ring-[0.5px] ring-token-border backdrop-blur-xl";
15729
+ var MENU_CLASSES = "fixed z-50 overflow-hidden rounded-xl bg-token-dropdown-background/90 text-token-foreground shadow-lg backdrop-blur-xl";
15669
15730
  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";
15670
15731
  var HEADING_CLASSES = "px-2 pb-1 pt-1.5 text-sm text-token-text-tertiary";
15732
+ var MAIN_MENU_MIN_WIDTH = 180;
15733
+ var MAIN_MENU_MAX_WIDTH = 210;
15734
+ var MODEL_MENU_PREFERRED_WIDTH = 320;
15735
+ var MODEL_MENU_MAX_WIDTH = 380;
15736
+ var MODEL_MENU_MAX_HEIGHT = 360;
15737
+ var MAIN_MENU_LEFT_OFFSET = 96;
15738
+ var MENU_GAP = 4;
15739
+ var VIEWPORT_MARGIN = 8;
15671
15740
  function popoverOpen2(menu) {
15672
15741
  return menu.matches(":popover-open");
15673
15742
  }
@@ -15707,24 +15776,47 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15707
15776
  };
15708
15777
  }
15709
15778
  function positionMainMenu(control) {
15710
- const rect = control.trigger.getBoundingClientRect();
15711
- const width = Math.min(280, Math.max(220, rect.width));
15712
- const left = Math.max(8, Math.min(rect.right - width, window.innerWidth - width - 8));
15713
- control.menu.style.width = `${width}px`;
15779
+ const triggerRect = control.trigger.getBoundingClientRect();
15780
+ const width = Math.min(MAIN_MENU_MAX_WIDTH, Math.max(MAIN_MENU_MIN_WIDTH, triggerRect.width));
15781
+ const modelMenuWidth = Math.min(
15782
+ MODEL_MENU_MAX_WIDTH,
15783
+ Math.min(MODEL_MENU_PREFERRED_WIDTH, window.innerWidth - VIEWPORT_MARGIN * 2)
15784
+ );
15785
+ const preferredLeft = triggerRect.right - width - MAIN_MENU_LEFT_OFFSET;
15786
+ const rightReservedLeft = window.innerWidth - VIEWPORT_MARGIN - modelMenuWidth - MENU_GAP - width;
15787
+ const maxLeft = window.innerWidth - VIEWPORT_MARGIN - width;
15788
+ const left = Math.max(
15789
+ VIEWPORT_MARGIN,
15790
+ Math.min(preferredLeft, Math.max(rightReservedLeft, VIEWPORT_MARGIN), maxLeft)
15791
+ );
15792
+ control.menu.style.setProperty("width", `${width}px`, "important");
15714
15793
  control.menu.style.left = `${left}px`;
15715
- control.menu.style.bottom = `${Math.max(8, window.innerHeight - rect.top + 6)}px`;
15794
+ control.menu.style.maxWidth = `${width}px`;
15795
+ control.menu.style.right = "auto";
15796
+ control.menu.style.top = "auto";
15797
+ control.menu.style.bottom = `${Math.max(
15798
+ VIEWPORT_MARGIN,
15799
+ window.innerHeight - triggerRect.top + 6
15800
+ )}px`;
15716
15801
  }
15717
15802
  function positionModelMenu(control) {
15718
- const rect = control.menu.getBoundingClientRect();
15719
- const width = Math.min(360, Math.max(280, rect.width));
15720
- const rightCandidate = rect.right + 4;
15721
- const left = rightCandidate + width <= window.innerWidth - 8 ? rightCandidate : Math.max(8, rect.left - width - 4);
15722
- control.modelMenu.style.width = `${width}px`;
15803
+ const mainRect = control.menu.getBoundingClientRect();
15804
+ const availableRight = window.innerWidth - mainRect.right - VIEWPORT_MARGIN;
15805
+ const width = Math.min(MODEL_MENU_MAX_WIDTH, Math.max(VIEWPORT_MARGIN, availableRight));
15806
+ const left = mainRect.right + MENU_GAP;
15807
+ control.modelMenu.style.setProperty("width", `${width}px`, "important");
15723
15808
  control.modelMenu.style.left = `${left}px`;
15724
- const height = control.modelMenu.getBoundingClientRect().height;
15725
- control.modelMenu.style.top = `${Math.max(
15726
- 8,
15727
- Math.min(rect.top, window.innerHeight - height - 8)
15809
+ control.modelMenu.style.maxWidth = `${width}px`;
15810
+ const maxHeight = Math.max(
15811
+ VIEWPORT_MARGIN,
15812
+ Math.min(MODEL_MENU_MAX_HEIGHT, window.innerHeight * 0.6, mainRect.bottom - VIEWPORT_MARGIN)
15813
+ );
15814
+ control.modelMenu.style.maxHeight = `${maxHeight}px`;
15815
+ control.modelMenu.style.right = "auto";
15816
+ control.modelMenu.style.top = "auto";
15817
+ control.modelMenu.style.bottom = `${Math.max(
15818
+ VIEWPORT_MARGIN,
15819
+ window.innerHeight - mainRect.bottom
15728
15820
  )}px`;
15729
15821
  }
15730
15822
  function syncRendererModelTriggerClass(control, nativeClassName) {
@@ -15784,9 +15876,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15784
15876
  menu.setAttribute("aria-label", "Model and Thinking");
15785
15877
  menu.setAttribute("popover", "auto");
15786
15878
  menu.className = MENU_CLASSES;
15879
+ menu.style.position = "fixed";
15787
15880
  menu.style.inset = "auto";
15788
15881
  menu.style.margin = "0";
15789
15882
  menu.style.padding = "4px";
15883
+ menu.style.border = "0";
15790
15884
  trigger.setAttribute("aria-controls", menu.id);
15791
15885
  const modelButton = document.createElement("button");
15792
15886
  modelButton.type = "button";
@@ -15801,9 +15895,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15801
15895
  modelMenu.setAttribute("aria-label", "Model");
15802
15896
  modelMenu.setAttribute("popover", "manual");
15803
15897
  modelMenu.className = MENU_CLASSES;
15898
+ modelMenu.style.position = "fixed";
15804
15899
  modelMenu.style.inset = "auto";
15805
15900
  modelMenu.style.margin = "0";
15806
15901
  modelMenu.style.padding = "4px";
15902
+ modelMenu.style.border = "0";
15807
15903
  modelMenu.style.maxHeight = "min(360px, 60vh)";
15808
15904
  modelMenu.style.overflowY = "auto";
15809
15905
  modelButton.setAttribute("aria-controls", modelMenu.id);
@@ -15825,8 +15921,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15825
15921
  };
15826
15922
  const open = () => {
15827
15923
  if (trigger.disabled || popoverOpen2(menu)) return;
15828
- positionMainMenu(control);
15829
15924
  menu.showPopover();
15925
+ positionMainMenu(control);
15830
15926
  };
15831
15927
  const onTriggerClick = () => {
15832
15928
  if (popoverOpen2(menu)) close();
@@ -15847,26 +15943,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15847
15943
  openModelMenu();
15848
15944
  return;
15849
15945
  }
15850
- if (target?.dataset.modelId) {
15851
- closeModelMenu();
15852
- modelButton.focus();
15853
- onSelectModel(target.dataset.modelId);
15854
- return;
15855
- }
15856
15946
  if (target?.dataset.thinkingOptionId) {
15857
15947
  close();
15858
15948
  trigger.focus();
15859
15949
  onSelectThinking(target.dataset.thinkingOptionId);
15860
15950
  }
15861
15951
  };
15952
+ const onModelMenuClick = (event) => {
15953
+ const target = event.target instanceof Element ? event.target.closest("button[data-model-id]") : null;
15954
+ if (!target?.dataset.modelId) return;
15955
+ closeModelMenu();
15956
+ modelButton.focus();
15957
+ onSelectModel(target.dataset.modelId);
15958
+ };
15862
15959
  const onModelHover = () => openModelMenu();
15960
+ const onViewportChange = () => {
15961
+ if (popoverOpen2(menu)) positionMainMenu(control);
15962
+ if (popoverOpen2(modelMenu)) positionModelMenu(control);
15963
+ };
15863
15964
  trigger.addEventListener("click", onTriggerClick);
15864
15965
  menu.addEventListener("toggle", onToggle);
15865
15966
  modelMenu.addEventListener("toggle", onModelToggle);
15866
15967
  modelButton.addEventListener("mouseenter", onModelHover);
15867
15968
  root.addEventListener("click", onRootClick);
15868
- menu.append(modelMenu);
15969
+ modelMenu.addEventListener("click", onModelMenuClick);
15970
+ window.addEventListener("resize", onViewportChange);
15971
+ window.addEventListener("scroll", onViewportChange, true);
15869
15972
  root.append(trigger, menu);
15973
+ document.body.append(modelMenu);
15870
15974
  const control = {
15871
15975
  root,
15872
15976
  trigger,
@@ -15885,6 +15989,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15885
15989
  modelMenu.removeEventListener("toggle", onModelToggle);
15886
15990
  modelButton.removeEventListener("mouseenter", onModelHover);
15887
15991
  root.removeEventListener("click", onRootClick);
15992
+ modelMenu.removeEventListener("click", onModelMenuClick);
15993
+ window.removeEventListener("resize", onViewportChange);
15994
+ window.removeEventListener("scroll", onViewportChange, true);
15995
+ modelMenu.remove();
15888
15996
  root.remove();
15889
15997
  }
15890
15998
  };
@@ -15943,7 +16051,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15943
16051
  control.options.set(model.ref.id, { button, check: check2 });
15944
16052
  control.modelMenu.append(button);
15945
16053
  }
15946
- control.menu.append(control.modelMenu);
15947
16054
  }
15948
16055
  function renderRendererModelPicker(control, view, visible) {
15949
16056
  control.root.style.display = visible ? "block" : "none";
@@ -16310,12 +16417,43 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16310
16417
  function formatRendererCost(value) {
16311
16418
  return `$${value.toFixed(3)}`;
16312
16419
  }
16420
+ function formatRendererTokenRate(value) {
16421
+ return `${decimal(value, 1)} tok/s`;
16422
+ }
16313
16423
  function formatRendererTokenCount(value) {
16314
16424
  const sign = value < 0 ? "-" : "";
16315
16425
  const absolute = Math.abs(value);
16316
16426
  if (absolute < 1e3) return `${sign}${Math.round(absolute)}`;
16317
16427
  return `${sign}${decimal(absolute / 1e3, 1)}k`;
16318
16428
  }
16429
+ function formatRendererCreditsPercent(value) {
16430
+ return `${decimal(value, 1)}%`;
16431
+ }
16432
+ function rendererUsageTriggerMaxWidth(hasAccountCredits) {
16433
+ return hasAccountCredits ? "min(300px, 44vw)" : "min(180px, 30vw)";
16434
+ }
16435
+ function formatRendererCreditsReset(value) {
16436
+ const date5 = new Date(value);
16437
+ if (Number.isNaN(date5.getTime())) return value;
16438
+ return date5.toLocaleString(void 0, {
16439
+ month: "long",
16440
+ day: "numeric",
16441
+ hour: "numeric",
16442
+ minute: "2-digit"
16443
+ });
16444
+ }
16445
+ function creditsPeriodLabel(periodType) {
16446
+ if (periodType === "weekly") return "Weekly limit";
16447
+ if (periodType === "monthly") return "Monthly limit";
16448
+ return "Account limit";
16449
+ }
16450
+ function productLabel(product) {
16451
+ if (product === "GrokBuild") return "Build";
16452
+ if (product === "GrokChat") return "Chat";
16453
+ if (product === "GrokImagine") return "Imagine";
16454
+ if (product === "GrokVoice") return "Voice";
16455
+ return product;
16456
+ }
16319
16457
  function addDetailRow(parent, label, value) {
16320
16458
  const row = document.createElement("div");
16321
16459
  row.style.display = "grid";
@@ -16332,14 +16470,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16332
16470
  row.append(labelElement, valueElement);
16333
16471
  parent.append(row);
16334
16472
  }
16335
- function renderDetails(popover, usage) {
16473
+ function renderDetails(popover, usage, accountCredits) {
16336
16474
  popover.replaceChildren();
16337
16475
  const heading = document.createElement("div");
16338
16476
  heading.textContent = "Usage";
16339
16477
  heading.style.fontWeight = "600";
16340
16478
  heading.style.marginBottom = "6px";
16341
16479
  popover.append(heading);
16342
- if (usage.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0) {
16480
+ if (accountCredits) {
16481
+ addDetailRow(
16482
+ popover,
16483
+ creditsPeriodLabel(accountCredits.periodType),
16484
+ formatRendererCreditsPercent(accountCredits.usedPercent)
16485
+ );
16486
+ if (accountCredits.resetsAt) {
16487
+ addDetailRow(popover, "Resets", formatRendererCreditsReset(accountCredits.resetsAt));
16488
+ }
16489
+ for (const product of accountCredits.productUsage ?? []) {
16490
+ addDetailRow(
16491
+ popover,
16492
+ productLabel(product.product),
16493
+ formatRendererCreditsPercent(product.usagePercent)
16494
+ );
16495
+ }
16496
+ }
16497
+ if (usage?.contextUsedTokens !== void 0 && usage.contextWindowTokens !== void 0) {
16343
16498
  const contextPercent = usage.contextWindowTokens > 0 ? usage.contextUsedTokens / usage.contextWindowTokens * 100 : null;
16344
16499
  addDetailRow(
16345
16500
  popover,
@@ -16347,27 +16502,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16347
16502
  contextPercent === null ? `/${formatRendererTokenCount(usage.contextWindowTokens)}` : `${decimal(contextPercent, 1)}% / ${formatRendererTokenCount(usage.contextWindowTokens)}`
16348
16503
  );
16349
16504
  }
16350
- if (usage.cacheHitRatePercent !== void 0) {
16505
+ if (usage?.cacheHitRatePercent !== void 0) {
16351
16506
  addDetailRow(
16352
16507
  popover,
16353
16508
  "Latest cache hit",
16354
16509
  formatRendererCacheHitRate(usage.cacheHitRatePercent)
16355
16510
  );
16356
16511
  }
16357
- if (usage.cachedInputTokens !== void 0) {
16512
+ if (usage?.outputTokensPerSecond !== void 0) {
16513
+ addDetailRow(popover, "Output speed", formatRendererTokenRate(usage.outputTokensPerSecond));
16514
+ }
16515
+ if (usage?.cachedInputTokens !== void 0) {
16358
16516
  addDetailRow(popover, "Cache read", formatRendererTokenCount(usage.cachedInputTokens));
16359
16517
  }
16360
- if (usage.cacheWriteInputTokens !== void 0) {
16518
+ if (usage?.cacheWriteInputTokens !== void 0) {
16361
16519
  addDetailRow(popover, "Cache write", formatRendererTokenCount(usage.cacheWriteInputTokens));
16362
16520
  }
16363
- if (usage.inputTokens !== void 0 || usage.outputTokens !== void 0) {
16521
+ if (usage?.reasoningOutputTokens !== void 0) {
16522
+ addDetailRow(popover, "Reasoning", formatRendererTokenCount(usage.reasoningOutputTokens));
16523
+ }
16524
+ if (usage?.inputTokens !== void 0 || usage?.outputTokens !== void 0) {
16364
16525
  addDetailRow(
16365
16526
  popover,
16366
16527
  "Input / output",
16367
16528
  `${formatRendererTokenCount(usage.inputTokens ?? 0)} / ${formatRendererTokenCount(usage.outputTokens ?? 0)}`
16368
16529
  );
16369
16530
  }
16370
- if (usage.totalCostUsd !== void 0) {
16531
+ if (usage?.totalCostUsd !== void 0) {
16371
16532
  addDetailRow(popover, "Session cost estimate", formatRendererCost(usage.totalCostUsd));
16372
16533
  }
16373
16534
  }
@@ -16425,7 +16586,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16425
16586
  trigger.style.display = "inline-flex";
16426
16587
  trigger.style.alignItems = "center";
16427
16588
  trigger.style.width = "fit-content";
16428
- trigger.style.maxWidth = "min(180px, 30vw)";
16589
+ trigger.style.maxWidth = rendererUsageTriggerMaxWidth(false);
16429
16590
  trigger.style.height = "24px";
16430
16591
  trigger.style.padding = "0 4px";
16431
16592
  trigger.style.borderRadius = "9999px";
@@ -16528,27 +16689,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16528
16689
  document.body.append(popover);
16529
16690
  return control;
16530
16691
  }
16531
- function renderRendererUsageControl(control, usage) {
16692
+ function renderRendererUsageControl(control, usage, accountCredits = null) {
16532
16693
  const cacheHitRatePercent = usage?.cacheHitRatePercent;
16694
+ const outputTokensPerSecond = usage?.outputTokensPerSecond;
16533
16695
  const totalCostUsd = usage?.totalCostUsd;
16534
16696
  const hasCacheHitRate = cacheHitRatePercent !== void 0;
16697
+ const hasOutputSpeed = outputTokensPerSecond !== void 0;
16535
16698
  const hasCost = totalCostUsd !== void 0;
16536
- const visible = hasCacheHitRate || hasCost;
16699
+ const hasCredits = accountCredits !== null;
16700
+ const visible = hasCacheHitRate || hasOutputSpeed || hasCost || hasCredits;
16537
16701
  control.root.style.display = visible ? "inline-flex" : "none";
16538
- if (!visible || !usage) {
16702
+ if (!visible) {
16539
16703
  closePopover(control);
16540
16704
  return false;
16541
16705
  }
16542
16706
  const summary = [
16707
+ accountCredits ? `${creditsPeriodLabel(accountCredits.periodType)} ${formatRendererCreditsPercent(accountCredits.usedPercent)}` : null,
16543
16708
  cacheHitRatePercent !== void 0 ? formatRendererCacheHitRate(cacheHitRatePercent) : null,
16709
+ outputTokensPerSecond !== void 0 ? formatRendererTokenRate(outputTokensPerSecond) : null,
16544
16710
  totalCostUsd !== void 0 ? formatRendererCost(totalCostUsd) : null
16545
16711
  ].filter((value) => value !== null);
16546
16712
  const compactSummary = summary.join(" \xB7 ");
16547
16713
  const accessibleSummary = `Thread Usage: ${compactSummary}`;
16714
+ control.trigger.style.maxWidth = rendererUsageTriggerMaxWidth(hasCredits);
16548
16715
  control.trigger.setAttribute("aria-label", accessibleSummary);
16549
16716
  control.trigger.title = accessibleSummary;
16550
16717
  control.label.textContent = compactSummary;
16551
- renderDetails(control.popover, usage);
16718
+ renderDetails(control.popover, usage, accountCredits);
16552
16719
  return true;
16553
16720
  }
16554
16721
 
@@ -16589,30 +16756,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16589
16756
  return event.key === "Enter" && !event.shiftKey && !event.isComposing;
16590
16757
  }
16591
16758
  function composerForEditor(editor) {
16592
- const codexComposer = editor.closest(CODEX_COMPOSER_SELECTOR);
16593
- if (codexComposer) return codexComposer;
16594
- const form = editor.closest("form");
16595
- if (form && sendButtonWithin(form)) return form;
16596
- let candidate = editor.parentElement;
16597
- for (let depth = 0; candidate && candidate !== document.body && depth < 8; depth += 1) {
16598
- if (sendButtonWithin(candidate)) return candidate;
16599
- candidate = candidate.parentElement;
16600
- }
16601
- return null;
16759
+ return editor.closest(CODEX_COMPOSER_SELECTOR);
16602
16760
  }
16603
16761
  function composerForElement(element) {
16604
- const codexComposer = element.closest(CODEX_COMPOSER_SELECTOR);
16605
- if (codexComposer) return codexComposer;
16606
- const mounted = element.closest(`[${CONTROL_ATTRIBUTE}]`);
16607
- if (mounted) return mounted.parentElement;
16608
- const editor = editorForElement(element);
16609
- if (editor) return composerForEditor(editor);
16610
- let candidate = element;
16611
- for (let depth = 0; candidate && candidate !== document.body && depth < 8; depth += 1) {
16612
- if (candidate.querySelector(`[${CONTROL_ATTRIBUTE}]`)) return candidate;
16613
- candidate = candidate.parentElement;
16614
- }
16615
- return null;
16762
+ return element.closest(CODEX_COMPOSER_SELECTOR);
16616
16763
  }
16617
16764
  function isRecord(value) {
16618
16765
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -16725,14 +16872,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16725
16872
  }
16726
16873
  control.usage.syncNativeModelClassName(candidate.className);
16727
16874
  }
16728
- function refreshNativeContextUsageControl(control) {
16729
- const candidate = nativeContextUsageControlForComposer(control.composer);
16730
- if (!candidate) {
16875
+ function usagePlacementAnchor(control) {
16876
+ const context = nativeContextUsageControlForComposer(control.composer);
16877
+ if (context?.parentElement) return context;
16878
+ const modelRoot = control.modelPicker.root;
16879
+ if (modelRoot.parentElement) return modelRoot;
16880
+ const native = control.nativeModelControl?.element;
16881
+ return native?.parentElement ? native : null;
16882
+ }
16883
+ function refreshUsagePlacement(control) {
16884
+ const anchor = usagePlacementAnchor(control);
16885
+ if (!anchor) {
16731
16886
  if (control.usage.anchor) control.usage.root.remove();
16732
16887
  control.usage.anchor = null;
16733
16888
  return;
16734
16889
  }
16735
- control.usage.place(candidate);
16890
+ control.usage.place(anchor);
16736
16891
  }
16737
16892
  function refreshNativePermissionModeControl(control) {
16738
16893
  const semanticCandidate = semanticNativePermissionModeControlForComposer(control.composer);
@@ -16764,7 +16919,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16764
16919
  }
16765
16920
  function reconcileComposerNativeControls(control, hideModel, hidePermissionMode) {
16766
16921
  refreshNativeModelControl(control);
16767
- refreshNativeContextUsageControl(control);
16922
+ refreshUsagePlacement(control);
16768
16923
  refreshNativePermissionModeControl(control);
16769
16924
  setNativeControlHidden(control.nativeModelControl, hideModel);
16770
16925
  setNativeControlHidden(control.nativePermissionModeControl, hidePermissionMode);
@@ -16813,10 +16968,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16813
16968
  sendButton,
16814
16969
  sendDisabledBeforeSwitch: null
16815
16970
  };
16816
- refreshNativeContextUsageControl(control);
16971
+ refreshUsagePlacement(control);
16817
16972
  return control;
16818
16973
  }
16819
- function renderComposerAgentControl(control, state, adapterState, switching, availability = {}, modelView = { status: "idle" }, permissionModeView = { status: "idle" }, usage = null) {
16974
+ function renderComposerAgentControl(control, state, adapterState, switching, availability = {}, modelView = { status: "idle" }, permissionModeView = { status: "idle" }, usage = null, accountCredits = null) {
16820
16975
  const selectedModel = modelView.selected;
16821
16976
  const selectedCatalogModel = modelView.catalog?.models.find(
16822
16977
  (model) => model.ref.id === selectedModel?.id
@@ -16853,7 +17008,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16853
17008
  permissionModeView,
16854
17009
  permissionModeVisible
16855
17010
  );
16856
- renderRendererUsageControl(control.usage, usage);
17011
+ renderRendererUsageControl(control.usage, usage, accountCredits);
16857
17012
  }
16858
17013
  function disposeComposerAgentControl(control) {
16859
17014
  if (control.sendDisabledBeforeSwitch !== null) {
@@ -16907,6 +17062,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16907
17062
  if (ownership.owner === "codex") return null;
16908
17063
  if (ownership.harnessId === "pi") return "pi";
16909
17064
  if (ownership.harnessId === "claude-code") return "claude-code";
17065
+ if (ownership.harnessId === "deepseek-harness") return "deepseek-harness";
17066
+ if (ownership.harnessId === "grok") return "grok";
16910
17067
  return null;
16911
17068
  }
16912
17069
  var BrowserSidebarAgentIconRow = class {
@@ -17009,7 +17166,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17009
17166
  const requestOwnership = (threadIds, client) => {
17010
17167
  for (const threadId of threadIds) pending.add(threadId);
17011
17168
  let succeeded = false;
17012
- void client.listThreadOwnership({ threadIds }).then(({ threads }) => {
17169
+ void Promise.resolve().then(() => client.listThreadOwnership({ threadIds })).then(({ threads }) => {
17013
17170
  if (disposed) return;
17014
17171
  for (const ownership of threads) {
17015
17172
  ownershipByThread.set(ownership.threadId, rendererAgentForThreadOwnership(ownership));
@@ -17377,6 +17534,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17377
17534
  var PI_TRANSPORT_MODEL_PREFIX = `${PI_TRANSPORT_MODEL_ID}@`;
17378
17535
  var CLAUDE_CODE_TRANSPORT_MODEL_ID = "codexhost/claude-code-native";
17379
17536
  var CLAUDE_CODE_TRANSPORT_MODEL_PREFIX = `${CLAUDE_CODE_TRANSPORT_MODEL_ID}@`;
17537
+ var DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID = "codexhost/deepseek-harness-native";
17538
+ var DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX = `${DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID}@`;
17539
+ var GROK_TRANSPORT_MODEL_ID = "codexhost/grok-native";
17540
+ var GROK_TRANSPORT_MODEL_PREFIX = `${GROK_TRANSPORT_MODEL_ID}@`;
17380
17541
  function transitionRendererAdapterStatus(current, next, publish) {
17381
17542
  if (current.state === next.state && current.reason === next.reason && current.hook === next.hook) {
17382
17543
  return false;
@@ -17392,11 +17553,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17392
17553
  function transportModelIdForAgent(agent) {
17393
17554
  if (agent === "pi") return PI_TRANSPORT_MODEL_ID;
17394
17555
  if (agent === "claude-code") return CLAUDE_CODE_TRANSPORT_MODEL_ID;
17556
+ if (agent === "deepseek-harness") return DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID;
17557
+ if (agent === "grok") return GROK_TRANSPORT_MODEL_ID;
17395
17558
  return null;
17396
17559
  }
17397
- function isTransportModelId(model) {
17398
- return isPiTransportModelId(model) || isClaudeTransportModelId(model);
17399
- }
17400
17560
  function isRecord5(value) {
17401
17561
  return typeof value === "object" && value !== null && !Array.isArray(value);
17402
17562
  }
@@ -17424,6 +17584,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17424
17584
  }
17425
17585
  return `${CLAUDE_CODE_TRANSPORT_MODEL_PREFIX}${parsedModel.id}${parsedPermissionMode ? `@${parsedPermissionMode}` : ""}`;
17426
17586
  }
17587
+ function grokTransportModelId(model, thinkingOptionId) {
17588
+ if (!model) {
17589
+ if (thinkingOptionId) throw new Error("Grok transport Thinking requires a Model Ref");
17590
+ return GROK_TRANSPORT_MODEL_ID;
17591
+ }
17592
+ const parsedModel = harnessModelRefSchema.parse(model);
17593
+ const parsedThinking = thinkingOptionId ? harnessThinkingOptionIdSchema.parse(thinkingOptionId) : void 0;
17594
+ return `${GROK_TRANSPORT_MODEL_PREFIX}${parsedModel.id}${parsedThinking ? `@@${parsedThinking}` : ""}`;
17595
+ }
17596
+ function decodeGrokTransportModelId(value) {
17597
+ if (value === GROK_TRANSPORT_MODEL_ID) return {};
17598
+ if (typeof value !== "string" || !value.startsWith(GROK_TRANSPORT_MODEL_PREFIX)) return null;
17599
+ const components = value.slice(GROK_TRANSPORT_MODEL_PREFIX.length).split("@");
17600
+ if (components.length !== 1 && components.length !== 3) return null;
17601
+ const [modelId, emptyPermissionMode, thinkingOptionId] = components;
17602
+ if (components.length === 3 && (emptyPermissionMode !== "" || !thinkingOptionId)) return null;
17603
+ const model = harnessModelRefSchema.safeParse({ id: modelId });
17604
+ if (!model.success) return null;
17605
+ const thinking = thinkingOptionId ? harnessThinkingOptionIdSchema.safeParse(thinkingOptionId) : null;
17606
+ if (thinking && !thinking.success) return null;
17607
+ return {
17608
+ model: model.data,
17609
+ ...thinking?.success ? { thinkingOptionId: thinking.data } : {}
17610
+ };
17611
+ }
17427
17612
  function decodeClaudeTransportModelId(value) {
17428
17613
  if (value === CLAUDE_CODE_TRANSPORT_MODEL_ID) return {};
17429
17614
  if (typeof value !== "string" || !value.startsWith(CLAUDE_CODE_TRANSPORT_MODEL_PREFIX)) {
@@ -17446,8 +17631,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17446
17631
  ...thinking?.success ? { thinkingOptionId: thinking.data } : {}
17447
17632
  };
17448
17633
  }
17449
- function isClaudeTransportModelId(value) {
17450
- return decodeClaudeTransportModelId(value) !== null;
17634
+ function deepSeekHarnessTransportModelId(model) {
17635
+ if (!model) return DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID;
17636
+ return `${DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX}${harnessModelRefSchema.parse(model).id}`;
17637
+ }
17638
+ function decodeDeepSeekHarnessTransportModelId(value) {
17639
+ if (value === DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID) return {};
17640
+ if (typeof value !== "string" || !value.startsWith(DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX)) {
17641
+ return null;
17642
+ }
17643
+ const model = harnessModelRefSchema.safeParse({
17644
+ id: value.slice(DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX.length)
17645
+ });
17646
+ return model.success ? { model: model.data } : null;
17451
17647
  }
17452
17648
  function isPiTransportModelId(value) {
17453
17649
  if (value === PI_TRANSPORT_MODEL_ID) return true;
@@ -17520,31 +17716,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17520
17716
  }
17521
17717
  return [...targets];
17522
17718
  }
17523
- function isModelAtomState(value) {
17524
- return isRecord5(value) && isRecord5(value.atom) && typeof value.get === "function" && typeof value.set === "function";
17525
- }
17526
- function isModelSelection(value) {
17527
- return value === null || isRecord5(value) && "model" in value && "reasoningEffort" in value;
17528
- }
17529
- function sameModelPowerSelection(left, right) {
17530
- return left === right || left !== null && right !== null && left.model === right.model && left.reasoningEffort === right.reasoningEffort;
17531
- }
17532
- function sameTarget2(left, right) {
17533
- return left.length === right.length && left.every((value, index) => value === right[index]);
17534
- }
17535
- function selectOptimisticModelAtom(pairs) {
17536
- const first = pairs[0];
17537
- if (!first) return null;
17538
- const value = first.optimistic.get();
17539
- if (isRecord5(value) && "modelSettings" in value) return first.optimistic;
17540
- if (first.optimistic.atom === first.committed.atom) return null;
17541
- if (!pairs.every(
17542
- (pair) => pair.optimistic.atom === first.optimistic.atom && pair.committed.atom === first.committed.atom && sameTarget2(pair.target, first.target)
17543
- )) {
17544
- return null;
17545
- }
17546
- return first.optimistic;
17547
- }
17548
17719
  function findComposerFiber(composer) {
17549
17720
  const selector = '[data-codex-composer], [contenteditable="true"][role="textbox"]';
17550
17721
  const editor = composer?.matches(selector) === true ? composer : (composer ?? document).querySelector(selector);
@@ -17559,165 +17730,60 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17559
17730
  }
17560
17731
  return fiberElement && fiberName ? Object.getOwnPropertyDescriptor(fiberElement, fiberName)?.value : null;
17561
17732
  }
17562
- function findReasoningEffort() {
17563
- const matches = [];
17564
- for (const button of document.querySelectorAll(
17565
- '[data-codex-composer-root] button[aria-haspopup="menu"]'
17566
- )) {
17567
- const fiberName = Object.getOwnPropertyNames(button).find(
17568
- (name) => name.startsWith("__reactFiber$")
17569
- );
17570
- let fiber = fiberName ? Object.getOwnPropertyDescriptor(button, fiberName)?.value : null;
17571
- for (let depth = 0; fiber && depth < 60; depth += 1) {
17572
- const props = fiber.memoizedProps;
17573
- if (isRecord5(props) && typeof props.onSelectModel === "function" && typeof props.onSelectReasoningEffort === "function" && "reasoningEffort" in props && isRecord5(props.fallbackPowerSelection)) {
17574
- matches.push({ callback: props.onSelectModel, value: props.reasoningEffort });
17733
+ function findComposerConversationThreadId(composer) {
17734
+ let threadId;
17735
+ let fiber = findComposerFiber(composer);
17736
+ for (let depth = 0; fiber && depth < 120; depth += 1) {
17737
+ const props = fiber.memoizedProps;
17738
+ if (isRecord5(props) && "conversationId" in props && props.conversationId != null) {
17739
+ const candidate = hostThreadIdSchema.safeParse(props.conversationId);
17740
+ if (!candidate.success || threadId !== void 0 && threadId !== candidate.data) {
17741
+ return null;
17575
17742
  }
17576
- const parent = fiber.return;
17577
- fiber = (typeof parent === "object" || typeof parent === "function") && parent !== null ? parent : null;
17743
+ threadId = candidate.data;
17578
17744
  }
17745
+ const parent = fiber.return;
17746
+ fiber = (typeof parent === "object" || typeof parent === "function") && parent !== null ? parent : null;
17579
17747
  }
17580
- const uniqueCallbacks = new Set(matches.map((match) => match.callback));
17581
- const first = matches[0];
17582
- return {
17583
- found: first !== void 0 && uniqueCallbacks.size === 1 && matches.every((match) => match.value === first.value),
17584
- value: first?.value
17585
- };
17748
+ return threadId;
17586
17749
  }
17587
- function findModelPickerControl(composer) {
17588
- let control;
17589
- for (const button of (composer ?? document).querySelectorAll(
17590
- 'button[aria-haspopup="menu"]'
17591
- )) {
17592
- const fiberName = Object.getOwnPropertyNames(button).find(
17593
- (name) => name.startsWith("__reactFiber$")
17594
- );
17595
- let fiber = fiberName ? Object.getOwnPropertyDescriptor(button, fiberName)?.value : null;
17596
- for (let depth = 0; fiber && depth < 60; depth += 1) {
17597
- const props = fiber.memoizedProps;
17598
- if (!control && isRecord5(props) && "model" in props && "reasoningEffort" in props && typeof props.onSelectModel === "function") {
17599
- const selection = { model: props.model, reasoningEffort: props.reasoningEffort };
17600
- const fallbackSelection = isRecord5(props.fallbackPowerSelection) ? props.fallbackPowerSelection : null;
17601
- control = {
17602
- codexSelection: isTransportModelId(selection.model) ? fallbackSelection : selection,
17603
- selection,
17604
- selectModel: props.onSelectModel
17605
- };
17606
- }
17607
- const parent = fiber.return;
17608
- fiber = (typeof parent === "object" || typeof parent === "function") && parent !== null ? parent : null;
17609
- }
17750
+ function isCurrentDraftWrapper(value) {
17751
+ if (!Array.isArray(value) || value.length !== 7 || value[3] !== value[5] || value[3] !== value[6] || !isRecord5(value[3]) || typeof value[3].get !== "function" || typeof value[2] !== "string" && value[2] !== null) {
17752
+ return false;
17753
+ }
17754
+ try {
17755
+ const draft = value[3].get();
17756
+ return isRecord5(draft) && "modelSettings" in draft && "isManuallyChanged" in draft;
17757
+ } catch {
17758
+ return false;
17610
17759
  }
17611
- return {
17612
- codexSelection: control?.codexSelection ?? null,
17613
- found: control !== void 0,
17614
- selection: control?.selection ?? { model: void 0, reasoningEffort: void 0 },
17615
- selectModel(model, reasoningEffort) {
17616
- control?.selectModel(model, reasoningEffort);
17617
- }
17618
- };
17619
17760
  }
17620
- function findModelAtomPairs(composer) {
17621
- const pairs = [];
17622
- const compactPairs = [];
17761
+ function findComposerModelTarget(composer) {
17762
+ const conversationThreadId = findComposerConversationThreadId(composer);
17763
+ if (conversationThreadId === null) return null;
17764
+ if (conversationThreadId !== void 0) return ["conversation", conversationThreadId];
17765
+ const draftIds = /* @__PURE__ */ new Set();
17623
17766
  let fiber = findComposerFiber(composer);
17624
17767
  for (let depth = 0; fiber && depth < 120; depth += 1) {
17625
17768
  const updateQueue = fiber.updateQueue;
17626
17769
  const memoCache = isRecord5(updateQueue) ? updateQueue.memoCache : null;
17627
17770
  const data = isRecord5(memoCache) && Array.isArray(memoCache.data) ? memoCache.data : [];
17628
- for (let index = 0; index + 1 < data.length; index += 1) {
17629
- const compact = data[index];
17630
- const resolved = data[index + 1];
17631
- if (!Array.isArray(compact) || !isModelAtomState(compact[1]) || !Array.isArray(resolved) || !isModelAtomState(resolved[3]) || resolved[2] !== null && typeof resolved[2] !== "string") {
17632
- continue;
17633
- }
17634
- let value;
17635
- try {
17636
- value = compact[1].get();
17637
- } catch {
17638
- continue;
17639
- }
17640
- if (!isRecord5(value) || !("modelSettings" in value)) continue;
17641
- const target = resolved[2] === null || resolved[2].startsWith("client-new-thread:") ? ["default", resolved[2]] : ["conversation", resolved[2]];
17642
- compactPairs.push({ optimistic: compact[1], committed: resolved[3], target });
17643
- }
17644
- for (let index = 0; index + 3 < data.length; index += 1) {
17645
- const first = data[index];
17646
- const firstResolved = data[index + 1];
17647
- const second = data[index + 2];
17648
- const secondResolved = data[index + 3];
17649
- if (!Array.isArray(first) || first.length !== 3 || !Array.isArray(firstResolved) || firstResolved.length !== 4 || !Array.isArray(second) || second.length !== 3 || !Array.isArray(secondResolved) || secondResolved.length !== 4) {
17650
- continue;
17651
- }
17652
- const target = firstResolved[2];
17653
- const secondTarget = secondResolved[2];
17654
- const optimistic = firstResolved[3];
17655
- const committed = secondResolved[3];
17656
- if (!Array.isArray(target) || !Array.isArray(secondTarget) || target !== secondTarget || target[0] !== "default" && target[0] !== "conversation" || !isModelAtomState(optimistic) || !isModelAtomState(committed)) {
17657
- continue;
17658
- }
17659
- let optimisticValue;
17660
- let committedValue;
17661
- try {
17662
- optimisticValue = optimistic.get();
17663
- committedValue = committed.get();
17664
- } catch {
17665
- continue;
17771
+ for (const value of data) {
17772
+ if (isCurrentDraftWrapper(value) && typeof value[2] === "string" && value[2].startsWith("client-new-thread:")) {
17773
+ draftIds.add(value[2]);
17666
17774
  }
17667
- if (!isModelSelection(optimisticValue) || !isModelSelection(committedValue)) continue;
17668
- pairs.push({ optimistic, committed, target });
17669
17775
  }
17670
17776
  const parent = fiber.return;
17671
17777
  fiber = (typeof parent === "object" || typeof parent === "function") && parent !== null ? parent : null;
17672
17778
  }
17673
- return pairs.length > 0 ? pairs : compactPairs;
17674
- }
17675
- function findComposerModelTarget(composer) {
17676
- const pairs = findModelAtomPairs(composer);
17677
- if (!selectOptimisticModelAtom(pairs)) return null;
17678
- return pairs[0]?.target ?? null;
17679
- }
17680
- function findModelStateController(composer) {
17681
- const pairs = findModelAtomPairs(composer);
17682
- const optimistic = selectOptimisticModelAtom(pairs);
17683
- if (!optimistic) return null;
17684
- const current = optimistic.get();
17685
- if (isModelSelection(current)) {
17686
- const reasoningEffort = findReasoningEffort();
17687
- const picker2 = findModelPickerControl(composer);
17688
- if (!reasoningEffort.found) return null;
17689
- return {
17690
- apply(selection) {
17691
- optimistic.set(selection);
17692
- },
17693
- codexSelection: current === null ? picker2.codexSelection : !isTransportModelId(current.model) ? current : picker2.codexSelection,
17694
- get current() {
17695
- const value = optimistic.get();
17696
- return isModelSelection(value) ? value : null;
17697
- },
17698
- format: "legacy",
17699
- reasoningEffort: reasoningEffort.value
17700
- };
17701
- }
17702
- if (!isRecord5(current) || !("modelSettings" in current)) return null;
17703
- const picker = findModelPickerControl(composer);
17704
- if (!picker.found) return null;
17705
- return {
17706
- apply(selection) {
17707
- if (selection) picker.selectModel(selection.model, selection.reasoningEffort);
17708
- else optimistic.set({ ...current, isManuallyChanged: true, modelSettings: null });
17709
- },
17710
- codexSelection: picker.codexSelection,
17711
- current: picker.selection,
17712
- format: "compact",
17713
- reasoningEffort: picker.selection.reasoningEffort
17714
- };
17779
+ if (draftIds.size !== 1) return null;
17780
+ return ["default", draftIds.values().next().value];
17715
17781
  }
17716
17782
  function isMainProcessTitlePolicyReady(value) {
17717
17783
  return isRecord5(value) && value.state === "ready";
17718
17784
  }
17719
17785
  function isDraftPrewarmPolicyReady(value) {
17720
- return isRecord5(value) && value.state === "ready" && typeof value.clear === "function";
17786
+ return isRecord5(value) && value.state === "ready" && typeof value.select === "function" && typeof value.clear === "function";
17721
17787
  }
17722
17788
  async function waitForRendererDraftPrewarmPolicy(target) {
17723
17789
  const deadline = Date.now() + DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS;
@@ -17732,15 +17798,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17732
17798
  }
17733
17799
  }
17734
17800
  function modelSelectionForAgent(officialSelection, reasoningEffort, agent, model, thinkingOptionId, permissionModeId) {
17735
- const transportModelId = agent === "pi" ? piTransportModelId(model, thinkingOptionId) : agent === "claude-code" ? claudeTransportModelId(model, permissionModeId, thinkingOptionId) : transportModelIdForAgent(agent);
17801
+ const transportModelId = agent === "pi" ? piTransportModelId(model, thinkingOptionId) : agent === "claude-code" ? claudeTransportModelId(model, permissionModeId, thinkingOptionId) : agent === "deepseek-harness" ? deepSeekHarnessTransportModelId(model) : agent === "grok" ? grokTransportModelId(model, thinkingOptionId) : transportModelIdForAgent(agent);
17736
17802
  return transportModelId ? { model: transportModelId, reasoningEffort } : officialSelection;
17737
17803
  }
17738
17804
  function installCurrentRendererAdapter() {
17739
17805
  let disposed = false;
17740
- let modelController = null;
17741
- let officialSelection = null;
17742
- let hasOfficialSelection = false;
17743
- let selectedAgent = "codex";
17744
17806
  let modelUpdates = 0;
17745
17807
  const liveStatus = {
17746
17808
  state: "installing",
@@ -17795,54 +17857,41 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17795
17857
  );
17796
17858
  }
17797
17859
  });
17798
- const captureController = () => {
17799
- const discovered = findModelStateController();
17800
- if (!discovered) return false;
17801
- modelController = discovered;
17802
- if (selectedAgent === "codex" && discovered.codexSelection !== null) {
17803
- officialSelection = discovered.codexSelection;
17804
- hasOfficialSelection = true;
17805
- } else if (selectedAgent === "codex" && discovered.current === null) {
17806
- officialSelection = null;
17807
- hasOfficialSelection = true;
17808
- }
17809
- if (!hasOfficialSelection) return false;
17810
- updateStatus("ready", "ready", "model-state");
17860
+ let routingPolicy = null;
17861
+ let policyTimer = null;
17862
+ const captureRoutingPolicy = () => {
17863
+ const discovered = window.__codexhostDraftPrewarmPolicyV1;
17864
+ if (!isDraftPrewarmPolicyReady(discovered)) return false;
17865
+ routingPolicy = discovered;
17866
+ if (policyTimer !== null) {
17867
+ window.clearInterval(policyTimer);
17868
+ policyTimer = null;
17869
+ }
17870
+ updateStatus("ready", "ready", "request-bridge");
17811
17871
  return true;
17812
17872
  };
17813
- const applyAgent = (agent, model, thinkingOptionId, permissionModeId, composer) => {
17814
- if (disposed) return false;
17815
- if (agent === "codex" && !hasOfficialSelection) {
17816
- selectedAgent = "codex";
17817
- return true;
17818
- }
17819
- const scopedController = composer ? findModelStateController(composer) : null;
17820
- const controller = scopedController ?? (modelController?.format === "legacy" ? modelController : composer ? null : modelController ?? findModelStateController());
17821
- if (!controller || !hasOfficialSelection) return false;
17822
- modelController = controller;
17873
+ if (!captureRoutingPolicy()) {
17874
+ updateStatus("installing", "draft-routing-policy-unavailable", null);
17875
+ policyTimer = window.setInterval(captureRoutingPolicy, DRAFT_PREWARM_POLICY_POLL_INTERVAL_MS);
17876
+ }
17877
+ const applyAgent = (agent, model, thinkingOptionId, permissionModeId) => {
17878
+ if (disposed || routingPolicy === null) return false;
17823
17879
  const selection = modelSelectionForAgent(
17824
- officialSelection,
17825
- controller.reasoningEffort,
17880
+ null,
17881
+ null,
17826
17882
  agent,
17827
17883
  model,
17828
17884
  thinkingOptionId,
17829
17885
  permissionModeId
17830
17886
  );
17831
- if (!sameModelPowerSelection(controller.current, selection)) {
17832
- controller.apply(selection);
17887
+ const carrier = selection?.model;
17888
+ if (carrier !== null && carrier !== void 0 && typeof carrier !== "string") return false;
17889
+ if (routingPolicy.select(carrier ?? null)) {
17833
17890
  modelUpdates += 1;
17834
17891
  liveStatus.modelUpdates = modelUpdates;
17835
17892
  }
17836
- selectedAgent = agent;
17837
17893
  return true;
17838
17894
  };
17839
- if (!captureController()) {
17840
- updateStatus("installing", "model-controller-unavailable", null);
17841
- }
17842
- const observer = new MutationObserver(() => {
17843
- captureController();
17844
- });
17845
- observer.observe(document.documentElement, { childList: true, subtree: true });
17846
17895
  return {
17847
17896
  status: liveStatus,
17848
17897
  modelControl,
@@ -17850,12 +17899,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17850
17899
  dispose() {
17851
17900
  if (disposed) return;
17852
17901
  disposed = true;
17853
- observer.disconnect();
17902
+ if (policyTimer !== null) window.clearInterval(policyTimer);
17903
+ routingPolicy?.select(null);
17904
+ routingPolicy = null;
17854
17905
  forkControl.dispose();
17855
17906
  usageSubscription.dispose();
17856
- modelController = null;
17857
- officialSelection = null;
17858
- hasOfficialSelection = false;
17859
17907
  }
17860
17908
  };
17861
17909
  }
@@ -17919,15 +17967,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17919
17967
  if (!isRecord6(parsed) || parsed.version !== 1) return void 0;
17920
17968
  if (!KNOWN_RENDERER_AGENTS.some((agent) => agent === parsed.lastAgent)) return void 0;
17921
17969
  const externalByAgent = isRecord6(parsed.externalByAgent) ? parsed.externalByAgent : {};
17922
- const pi = parseExternalConfiguration(externalByAgent.pi);
17923
- const claudeCode = parseExternalConfiguration(externalByAgent["claude-code"]);
17970
+ const parsedExternal = Object.fromEntries(
17971
+ KNOWN_RENDERER_AGENTS.filter(
17972
+ (agent) => agent !== "codex"
17973
+ ).flatMap((agent) => {
17974
+ const configuration2 = parseExternalConfiguration(externalByAgent[agent]);
17975
+ return configuration2 ? [[agent, configuration2]] : [];
17976
+ })
17977
+ );
17924
17978
  return {
17925
17979
  version: 1,
17926
17980
  lastAgent: parsed.lastAgent,
17927
- externalByAgent: {
17928
- ...pi ? { pi } : {},
17929
- ...claudeCode ? { "claude-code": claudeCode } : {}
17930
- }
17981
+ externalByAgent: parsedExternal
17931
17982
  };
17932
17983
  } catch {
17933
17984
  return void 0;
@@ -18557,6 +18608,124 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18557
18608
  }
18558
18609
  };
18559
18610
 
18611
+ // src/settings/release-notes.ts
18612
+ var HEADING_PATTERN = /^(#{1,6})[ \t]+(.+?)\s*$/u;
18613
+ var UNORDERED_ITEM_PATTERN = /^[-*][ \t]+(.+?)\s*$/u;
18614
+ var ORDERED_ITEM_PATTERN = /^\d+[.)][ \t]+(.+?)\s*$/u;
18615
+ var FENCE_PATTERN = /^```([\w+-]*)\s*$/u;
18616
+ var INLINE_PATTERN = /(`+)((?:(?!\1).)+)\1|\*\*(.+?)\*\*|\[([^\]]+)\]\(([^)\s]+)\)/gu;
18617
+ function createReleaseNotesElement(document2, markdown) {
18618
+ const root = document2.createElement("div");
18619
+ root.className = "settings-update-notes";
18620
+ appendReleaseNotesBlocks(document2, root, markdown);
18621
+ return root;
18622
+ }
18623
+ function appendReleaseNotesBlocks(document2, root, markdown) {
18624
+ const lines = markdown.replaceAll("\r\n", "\n").split("\n");
18625
+ let index = 0;
18626
+ while (index < lines.length) {
18627
+ const line = lines[index] ?? "";
18628
+ if (line.trim().length === 0) {
18629
+ index += 1;
18630
+ continue;
18631
+ }
18632
+ const fence = FENCE_PATTERN.exec(line);
18633
+ if (fence) {
18634
+ index = appendFencedCode(document2, root, lines, index, fence[1] ?? "");
18635
+ continue;
18636
+ }
18637
+ const heading = HEADING_PATTERN.exec(line);
18638
+ if (heading?.[1] && heading[2]) {
18639
+ const tag = `h${heading[1].length}`;
18640
+ const element = document2.createElement(tag);
18641
+ appendInline(document2, element, heading[2]);
18642
+ root.append(element);
18643
+ index += 1;
18644
+ continue;
18645
+ }
18646
+ if (UNORDERED_ITEM_PATTERN.test(line)) {
18647
+ index = appendList(document2, root, lines, index, "ul", UNORDERED_ITEM_PATTERN);
18648
+ continue;
18649
+ }
18650
+ if (ORDERED_ITEM_PATTERN.test(line)) {
18651
+ index = appendList(document2, root, lines, index, "ol", ORDERED_ITEM_PATTERN);
18652
+ continue;
18653
+ }
18654
+ index = appendParagraph(document2, root, lines, index);
18655
+ }
18656
+ }
18657
+ function appendFencedCode(document2, root, lines, start, language) {
18658
+ const body = [];
18659
+ let index = start + 1;
18660
+ while (index < lines.length && !FENCE_PATTERN.test(lines[index] ?? "")) {
18661
+ body.push(lines[index] ?? "");
18662
+ index += 1;
18663
+ }
18664
+ if (index < lines.length) index += 1;
18665
+ const pre = document2.createElement("pre");
18666
+ const code = document2.createElement("code");
18667
+ if (language.length > 0) code.className = `language-${language}`;
18668
+ code.textContent = body.join("\n");
18669
+ pre.append(code);
18670
+ root.append(pre);
18671
+ return index;
18672
+ }
18673
+ function appendList(document2, root, lines, start, tag, pattern) {
18674
+ const list = document2.createElement(tag);
18675
+ let index = start;
18676
+ while (index < lines.length) {
18677
+ const item = pattern.exec(lines[index] ?? "");
18678
+ if (!item?.[1]) break;
18679
+ const entry = document2.createElement("li");
18680
+ appendInline(document2, entry, item[1]);
18681
+ list.append(entry);
18682
+ index += 1;
18683
+ }
18684
+ root.append(list);
18685
+ return index;
18686
+ }
18687
+ function appendParagraph(document2, root, lines, start) {
18688
+ const paragraphLines = [];
18689
+ let index = start;
18690
+ while (index < lines.length) {
18691
+ const current = lines[index] ?? "";
18692
+ if (current.trim().length === 0 || FENCE_PATTERN.test(current) || HEADING_PATTERN.test(current) || UNORDERED_ITEM_PATTERN.test(current) || ORDERED_ITEM_PATTERN.test(current)) {
18693
+ break;
18694
+ }
18695
+ paragraphLines.push(current.trim());
18696
+ index += 1;
18697
+ }
18698
+ const paragraph = document2.createElement("p");
18699
+ appendInline(document2, paragraph, paragraphLines.join(" "));
18700
+ root.append(paragraph);
18701
+ return index;
18702
+ }
18703
+ function appendInline(document2, parent, text) {
18704
+ let lastIndex = 0;
18705
+ for (const match of text.matchAll(INLINE_PATTERN)) {
18706
+ const index = match.index ?? 0;
18707
+ if (index > lastIndex) parent.append(text.slice(lastIndex, index));
18708
+ if (match[2] !== void 0) {
18709
+ const code = document2.createElement("code");
18710
+ code.textContent = match[2];
18711
+ parent.append(code);
18712
+ } else if (match[3] !== void 0) {
18713
+ const strong = document2.createElement("strong");
18714
+ strong.textContent = match[3];
18715
+ parent.append(strong);
18716
+ } else {
18717
+ const link = document2.createElement("a");
18718
+ link.textContent = match[4] ?? "";
18719
+ link.setAttribute("href", match[5] ?? "");
18720
+ link.setAttribute("target", "_blank");
18721
+ link.setAttribute("rel", "noopener noreferrer");
18722
+ parent.append(link);
18723
+ }
18724
+ lastIndex = index + match[0].length;
18725
+ }
18726
+ if (lastIndex < text.length) parent.append(text.slice(lastIndex));
18727
+ }
18728
+
18560
18729
  // src/settings/update-request.ts
18561
18730
  var RENDERER_UPDATE_REQUEST_TIMEOUT_MS = 15e3;
18562
18731
  var RendererUpdateRequestTimeoutError = class extends Error {
@@ -18849,10 +19018,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18849
19018
  summary.textContent = operationMessage ?? (result.error ? messages.updateFailed : result.updateAvailable ? messages.updateAvailable : messages.updateUpToDate);
18850
19019
  panel.append(summary);
18851
19020
  if (result.releaseNotes) {
18852
- const releaseNotes = document2.createElement("div");
18853
- releaseNotes.className = "settings-update-notes";
18854
- releaseNotes.textContent = result.releaseNotes;
18855
- panel.append(releaseNotes);
19021
+ panel.append(createReleaseNotesElement(document2, result.releaseNotes));
18856
19022
  }
18857
19023
  if (result.status?.phase === "failed" && result.status.error) {
18858
19024
  const error51 = document2.createElement("p");
@@ -18923,7 +19089,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
18923
19089
  }
18924
19090
 
18925
19091
  // src/settings/shell.css
18926
- var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-icon-button.settings-star-link {\n width: auto;\n gap: 6px;\n padding-inline: 8px;\n font-size: 12px;\n line-height: 18px;\n text-decoration: none;\n border: 2px dashed #f5c542;\n white-space: nowrap;\n}\n\n.settings-star-link .codexhost-settings-icon {\n color: #f5c542;\n fill: currentColor;\n stroke: currentColor;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 40px;\n flex: none;\n gap: 12px;\n padding: 8px 12px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 10px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 7%);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 16px;\n min-height: 128px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-update-panel > strong,\n.settings-update-panel > span,\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-panel > span,\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-notes {\n max-height: 240px;\n padding: 14px;\n overflow: auto;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n background: rgb(255 255 255 / 4%);\n border: 1px solid var(--settings-divider);\n border-radius: 6px;\n}\n\n.settings-update-version-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 20px;\n min-height: 32px;\n color: var(--settings-muted);\n font-size: 13px;\n}\n\n.settings-update-version-row strong {\n color: var(--settings-text);\n font-size: 15px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 6px;\n margin-top: 14px;\n padding-inline: 4px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual code {\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-actions {\n display: flex;\n min-width: 0;\n margin-top: 16px;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-icon-button.settings-star-link {\n width: 28px;\n padding: 0;\n }\n\n .settings-star-link span {\n display: none;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
19092
+ var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-icon-button.settings-star-link {\n width: auto;\n gap: 6px;\n padding-inline: 8px;\n font-size: 12px;\n line-height: 18px;\n text-decoration: none;\n border: 2px dashed #f5c542;\n white-space: nowrap;\n}\n\n.settings-star-link .codexhost-settings-icon {\n color: #f5c542;\n fill: currentColor;\n stroke: currentColor;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 40px;\n flex: none;\n gap: 12px;\n padding: 8px 12px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 10px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 7%);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 16px;\n min-height: 128px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-update-panel > strong,\n.settings-update-panel > span,\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-panel > span,\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-notes {\n display: grid;\n gap: 10px;\n max-height: 320px;\n overflow: auto;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n overflow-wrap: anywhere;\n}\n\n.settings-update-notes > :first-child {\n margin-top: 0;\n}\n\n.settings-update-notes > :last-child {\n margin-bottom: 0;\n}\n\n.settings-update-notes h1,\n.settings-update-notes h2,\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n margin: 6px 0 0;\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes h1 {\n font-size: 16px;\n line-height: 24px;\n}\n\n.settings-update-notes h2 {\n font-size: 15px;\n line-height: 22px;\n}\n\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-notes p,\n.settings-update-notes ul,\n.settings-update-notes ol,\n.settings-update-notes pre {\n margin: 0;\n}\n\n.settings-update-notes ul,\n.settings-update-notes ol {\n padding-left: 20px;\n}\n\n.settings-update-notes li + li {\n margin-top: 4px;\n}\n\n.settings-update-notes strong {\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes a {\n color: #7cb8ff;\n text-decoration: none;\n}\n\n.settings-update-notes a:hover {\n text-decoration: underline;\n}\n\n.settings-update-notes code {\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n}\n\n.settings-update-notes :not(pre) > code {\n padding: 1px 5px;\n background: rgb(255 255 255 / 8%);\n border-radius: 4px;\n}\n\n.settings-update-notes pre {\n padding: 10px 12px;\n overflow: auto;\n background: rgb(0 0 0 / 28%);\n border-radius: 6px;\n}\n\n.settings-update-notes pre code {\n line-height: 18px;\n white-space: pre-wrap;\n}\n\n.settings-update-version-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 20px;\n min-height: 32px;\n color: var(--settings-muted);\n font-size: 13px;\n}\n\n.settings-update-version-row strong {\n color: var(--settings-text);\n font-size: 15px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 6px;\n margin-top: 14px;\n padding-inline: 4px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual code {\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-actions {\n display: flex;\n min-width: 0;\n margin-top: 16px;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-icon-button.settings-star-link {\n width: 28px;\n padding: 0;\n }\n\n .settings-star-link span {\n display: none;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
18927
19093
 
18928
19094
  // src/settings/shell.ts
18929
19095
  var SETTINGS_SHELL_ATTRIBUTE = "data-codexhost-settings-shell";
@@ -19555,16 +19721,25 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19555
19721
  // src/renderer-binding-probe.ts
19556
19722
  var externalHarnessIds = {
19557
19723
  pi: harnessIdSchema.parse("pi"),
19558
- "claude-code": harnessIdSchema.parse("claude-code")
19724
+ "claude-code": harnessIdSchema.parse("claude-code"),
19725
+ "deepseek-harness": harnessIdSchema.parse("deepseek-harness"),
19726
+ grok: harnessIdSchema.parse("grok")
19559
19727
  };
19560
- var externalAgents = ["pi", "claude-code"];
19728
+ var externalAgents = [
19729
+ "pi",
19730
+ "claude-code",
19731
+ "deepseek-harness",
19732
+ "grok"
19733
+ ];
19561
19734
  var rendererUsageRefreshDelays = [250, 500, 1e3, 2e3, 4e3, 8e3];
19562
19735
  function rendererUsageRefreshDelay(attempt) {
19563
19736
  const index = Math.max(0, Math.min(Math.trunc(attempt), rendererUsageRefreshDelays.length - 1));
19564
19737
  return rendererUsageRefreshDelays[index] ?? rendererUsageRefreshDelays[0];
19565
19738
  }
19566
- function shouldRetryExternalThreadUsage(agent, usage) {
19567
- return agent !== "codex" && usage === null;
19739
+ function shouldRetryExternalThreadUsage(agent, usage, accountCredits = null) {
19740
+ if (agent === "codex") return false;
19741
+ if (usage === null) return true;
19742
+ return agent === "grok" && accountCredits === null;
19568
19743
  }
19569
19744
  function selectableThinkingOptionId(state) {
19570
19745
  return state.effectiveThinkingOptionId && state.availableThinkingOptions?.some(({ id }) => id === state.effectiveThinkingOptionId) ? state.effectiveThinkingOptionId : void 0;
@@ -19590,6 +19765,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19590
19765
  ...inspection.effectivePermissionModeId ? { permissionModeId: inspection.effectivePermissionModeId } : {}
19591
19766
  };
19592
19767
  }
19768
+ if (inspection.harnessId === "grok") {
19769
+ const transportSelection = decodeGrokTransportModelId(inspection.transportModelId);
19770
+ if (!transportSelection) {
19771
+ throw new Error("Grok Thread reported an incompatible transport Model");
19772
+ }
19773
+ const model = inspection.effectiveModel ?? transportSelection.model;
19774
+ const thinkingOptionId = selectableThinkingOptionId(inspection) ?? transportSelection.thinkingOptionId;
19775
+ return {
19776
+ agent: "grok",
19777
+ ...model ? { model } : {},
19778
+ ...thinkingOptionId ? { thinkingOptionId } : {}
19779
+ };
19780
+ }
19593
19781
  if (inspection.harnessId === "claude-code") {
19594
19782
  const transportSelection = decodeClaudeTransportModelId(inspection.transportModelId);
19595
19783
  if (!transportSelection) {
@@ -19605,6 +19793,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19605
19793
  ...permissionModeId ? { permissionModeId } : {}
19606
19794
  };
19607
19795
  }
19796
+ if (inspection.harnessId === "deepseek-harness") {
19797
+ const transportSelection = decodeDeepSeekHarnessTransportModelId(inspection.transportModelId);
19798
+ if (!transportSelection) {
19799
+ throw new Error("DeepSeek Harness Thread reported an incompatible transport Model");
19800
+ }
19801
+ const model = inspection.effectiveModel ?? transportSelection.model;
19802
+ return { agent: "deepseek-harness", ...model ? { model } : {} };
19803
+ }
19608
19804
  throw new Error("Thread owner is not a Renderer Agent");
19609
19805
  }
19610
19806
  function isOwnershipSubmissionBlocked(status) {
@@ -19696,7 +19892,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19696
19892
  let availabilityRequest = null;
19697
19893
  const usageRefreshTimers = /* @__PURE__ */ new Map();
19698
19894
  const usageRefreshAttempts = /* @__PURE__ */ new Map();
19699
- const isCurrentModelRequest = (mounted, generation) => mounted.composer.isConnected && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentModelRequest(mounted.composer, generation);
19895
+ const isMountedComposer = (composer) => composer.isConnected && composer.matches(CODEX_COMPOSER_SELECTOR) && mountedByComposer.has(composer);
19896
+ const isCurrentModelRequest = (mounted, generation) => isMountedComposer(mounted.composer) && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentModelRequest(mounted.composer, generation);
19700
19897
  const isCurrentOwnershipRequest = (mounted, generation) => mounted.composer.isConnected && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentOwnershipRequest(mounted.composer, generation);
19701
19898
  const notifySubmission = (composer, trigger) => {
19702
19899
  const state = controller.recordSubmission(composer);
@@ -19730,7 +19927,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19730
19927
  harnessAvailability,
19731
19928
  mounted.modelView,
19732
19929
  mounted.permissionModeView,
19733
- mounted.usage
19930
+ mounted.usage,
19931
+ mounted.accountCredits
19734
19932
  );
19735
19933
  };
19736
19934
  const applyThreadUsageUpdate = (update) => {
@@ -19738,6 +19936,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19738
19936
  if (threadIdFromComposerModelTarget(mounted.modelTarget) !== update.threadId) continue;
19739
19937
  mounted.usageRequestGeneration += 1;
19740
19938
  mounted.usage = update.usage;
19939
+ mounted.accountCredits = update.accountCredits ?? null;
19741
19940
  usageRefreshAttempts.delete(mounted.composer);
19742
19941
  renderMounted(mounted);
19743
19942
  }
@@ -19746,6 +19945,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19746
19945
  const threadId = threadIdFromComposerModelTarget(mounted.modelTarget);
19747
19946
  if (!threadId || !modelControl || controller.get(mounted.composer).agent === "codex") {
19748
19947
  mounted.usage = null;
19948
+ mounted.accountCredits = null;
19749
19949
  usageRefreshAttempts.delete(mounted.composer);
19750
19950
  renderMounted(mounted);
19751
19951
  return;
@@ -19757,15 +19957,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19757
19957
  return;
19758
19958
  }
19759
19959
  mounted.usage = result.usage;
19760
- if (result.usage !== null) usageRefreshAttempts.delete(mounted.composer);
19960
+ mounted.accountCredits = result.accountCredits ?? null;
19961
+ const agent = controller.get(mounted.composer).agent;
19962
+ if (result.usage !== null && (agent !== "grok" || result.accountCredits)) {
19963
+ usageRefreshAttempts.delete(mounted.composer);
19964
+ }
19761
19965
  renderMounted(mounted);
19762
- if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, result.usage)) {
19966
+ if (shouldRetryExternalThreadUsage(
19967
+ controller.get(mounted.composer).agent,
19968
+ result.usage,
19969
+ result.accountCredits ?? null
19970
+ )) {
19763
19971
  scheduleThreadUsageRefresh(mounted);
19764
19972
  }
19765
19973
  } catch {
19766
19974
  if (mountedByComposer.get(mounted.composer) === mounted && mounted.usageRequestGeneration === generation) {
19767
19975
  renderMounted(mounted);
19768
- if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null)) {
19976
+ if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null, null)) {
19769
19977
  scheduleThreadUsageRefresh(mounted);
19770
19978
  }
19771
19979
  }
@@ -19854,7 +20062,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19854
20062
  } finally {
19855
20063
  if (isCurrentOwnershipRequest(mounted, generation)) {
19856
20064
  renderMounted(mounted);
19857
- if (mounted.ownershipStatus !== "error" && shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, mounted.usage)) {
20065
+ if (mounted.ownershipStatus !== "error" && shouldRetryExternalThreadUsage(
20066
+ controller.get(mounted.composer).agent,
20067
+ mounted.usage,
20068
+ mounted.accountCredits
20069
+ )) {
19858
20070
  scheduleThreadUsageRefresh(mounted);
19859
20071
  }
19860
20072
  }
@@ -19879,7 +20091,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19879
20091
  if (resolution === "transfer") {
19880
20092
  mounted.ownershipStatus = "ready";
19881
20093
  renderMounted(mounted);
19882
- if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null)) {
20094
+ if (shouldRetryExternalThreadUsage(controller.get(mounted.composer).agent, null, null)) {
19883
20095
  scheduleThreadUsageRefresh(mounted);
19884
20096
  }
19885
20097
  } else {
@@ -19889,6 +20101,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19889
20101
  mounted.threadConfiguration = void 0;
19890
20102
  mounted.ownershipStatus = "loading";
19891
20103
  mounted.usage = null;
20104
+ mounted.accountCredits = null;
19892
20105
  mounted.usageRequestGeneration += 1;
19893
20106
  usageRefreshAttempts.delete(mounted.composer);
19894
20107
  if (previousTarget?.[0] === "conversation") renderMounted(mounted);
@@ -19909,6 +20122,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19909
20122
  };
19910
20123
  mounted.permissionModeView = { status: "idle" };
19911
20124
  renderMounted(mounted);
20125
+ if (availability === "checking") void refreshHarnessAvailability();
19912
20126
  return;
19913
20127
  }
19914
20128
  mounted.modelView = {
@@ -20423,40 +20637,47 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20423
20637
  window.open(url2, "_blank", "noopener,noreferrer");
20424
20638
  };
20425
20639
  const refreshHarnessAvailability = (refresh = false) => {
20426
- if (adapterStatus.state !== "ready" || !modelControl) return Promise.resolve();
20640
+ if (!modelControl) return Promise.resolve();
20427
20641
  const client = modelControl;
20428
20642
  if (availabilityRequest?.client === client) return availabilityRequest.promise;
20643
+ harnessAvailability = Object.fromEntries(
20644
+ externalAgents.map((agent) => [
20645
+ agent,
20646
+ harnessAvailability[agent] === "ready" ? "ready" : "checking"
20647
+ ])
20648
+ );
20649
+ for (const mounted of mountedByComposer.values()) renderMounted(mounted);
20429
20650
  const generation = ++availabilityRequestGeneration;
20430
20651
  const promise2 = (async () => {
20431
- const inspections = await Promise.all(
20652
+ await Promise.all(
20432
20653
  externalAgents.map(async (agent) => {
20654
+ let status = "error";
20433
20655
  try {
20434
20656
  const inspection = await client.inspectHarness({
20435
20657
  harnessId: externalHarnessIds[agent],
20436
20658
  refresh
20437
20659
  });
20438
- return [agent, inspection.status === "ready" ? "ready" : inspection.status];
20660
+ status = inspection.status === "ready" ? "ready" : inspection.status;
20439
20661
  } catch {
20440
- return [agent, "error"];
20662
+ status = "error";
20663
+ }
20664
+ if (generation !== availabilityRequestGeneration || disposed) return;
20665
+ harnessAvailability = { ...harnessAvailability, [agent]: status };
20666
+ for (const mounted of mountedByComposer.values()) {
20667
+ const state = controller.get(mounted.composer);
20668
+ if (adapterStatus.state === "ready" && state.phase === "draft" && state.agent === agent && status !== "ready") {
20669
+ await switchComposerAgent(mounted, "codex");
20670
+ }
20671
+ }
20672
+ for (const mounted of mountedByComposer.values()) {
20673
+ const state = controller.get(mounted.composer);
20674
+ if (state.agent === agent) {
20675
+ void loadExternalCatalog(mounted);
20676
+ }
20677
+ renderMounted(mounted);
20441
20678
  }
20442
20679
  })
20443
20680
  );
20444
- if (generation !== availabilityRequestGeneration || disposed) return;
20445
- harnessAvailability = Object.fromEntries(inspections);
20446
- for (const mounted of mountedByComposer.values()) {
20447
- const state = controller.get(mounted.composer);
20448
- if (state.phase === "draft" && state.agent !== "codex" && harnessAvailability[state.agent] !== "ready") {
20449
- await switchComposerAgent(mounted, "codex");
20450
- }
20451
- }
20452
- for (const mounted of mountedByComposer.values()) {
20453
- const state = controller.get(mounted.composer);
20454
- if (state.agent !== "codex") {
20455
- void loadExternalCatalog(mounted);
20456
- } else {
20457
- renderMounted(mounted);
20458
- }
20459
- }
20460
20681
  })();
20461
20682
  const request = { client, promise: promise2 };
20462
20683
  availabilityRequest = request;
@@ -20471,7 +20692,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20471
20692
  return promise2;
20472
20693
  };
20473
20694
  const mount = (composer) => {
20474
- if (mountedByComposer.has(composer) || !composer.isConnected) return;
20695
+ if (mountedByComposer.has(composer) || !composer.isConnected || !composer.matches(CODEX_COMPOSER_SELECTOR)) {
20696
+ return;
20697
+ }
20475
20698
  const allButtons = [...composer.querySelectorAll("button")];
20476
20699
  const sendButton = sendButtonWithin(composer) ?? allButtons.at(-1) ?? null;
20477
20700
  if (!sendButton) return;
@@ -20519,6 +20742,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20519
20742
  ownershipStatus: threadIdFromComposerModelTarget(modelTarget) ? inherited ? "ready" : "loading" : "not-required",
20520
20743
  threadConfiguration: inherited?.threadConfiguration,
20521
20744
  usage: inherited?.usage ?? null,
20745
+ accountCredits: inherited?.accountCredits ?? null,
20522
20746
  usageRequestGeneration: 0
20523
20747
  };
20524
20748
  mountedByComposer.set(composer, mounted);
@@ -20534,7 +20758,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20534
20758
  renderMounted(mounted);
20535
20759
  if (threadIdFromComposerModelTarget(modelTarget) && !inherited) {
20536
20760
  void loadThreadOwnership(mounted);
20537
- } else if (threadIdFromComposerModelTarget(modelTarget) && inherited && shouldRetryExternalThreadUsage(state.agent, mounted.usage)) {
20761
+ } else if (threadIdFromComposerModelTarget(modelTarget) && inherited && shouldRetryExternalThreadUsage(state.agent, mounted.usage, mounted.accountCredits)) {
20538
20762
  scheduleThreadUsageRefresh(mounted);
20539
20763
  } else if (state.agent !== "codex" && !isExternalConfigurationReady(mounted)) {
20540
20764
  void loadExternalCatalog(mounted);
@@ -20558,7 +20782,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20558
20782
  }
20559
20783
  }
20560
20784
  for (const [composer, mounted] of mountedByComposer) {
20561
- if (!composer.isConnected || !mounted.control.root.isConnected) {
20785
+ if (!composer.isConnected || !composer.matches(CODEX_COMPOSER_SELECTOR) || !mounted.control.root.isConnected) {
20786
+ mounted.usageRequestGeneration += 1;
20787
+ usageRefreshAttempts.delete(composer);
20788
+ const timer = usageRefreshTimers.get(composer);
20789
+ if (timer !== void 0) {
20790
+ window.clearTimeout(timer);
20791
+ usageRefreshTimers.delete(composer);
20792
+ }
20562
20793
  disposeComposerAgentControl(mounted.control);
20563
20794
  mountedByComposer.delete(composer);
20564
20795
  continue;
@@ -20660,7 +20891,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20660
20891
  const composerForTarget = (target) => {
20661
20892
  const element = eventElement(target);
20662
20893
  const editor = element ? editorForElement(element) : null;
20663
- return editor ? composerForEditor(editor) : null;
20894
+ const composer = editor ? composerForEditor(editor) : null;
20895
+ return composer && isMountedComposer(composer) ? composer : null;
20664
20896
  };
20665
20897
  const onBeforeInput = (event) => {
20666
20898
  const composer = composerForTarget(event.target);
@@ -20671,7 +20903,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20671
20903
  };
20672
20904
  const onSubmit = (event) => {
20673
20905
  const element = eventElement(event.target);
20674
- const composer = element ? composerForElement(element) : null;
20906
+ const candidate = element ? composerForElement(element) : null;
20907
+ const composer = candidate && isMountedComposer(candidate) ? candidate : null;
20675
20908
  if (!composer) return;
20676
20909
  const prepared = prepareComposer(composer);
20677
20910
  if (prepared === null) return;
@@ -20707,7 +20940,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20707
20940
  const element = eventElement(event.target);
20708
20941
  const button = element?.closest("button");
20709
20942
  if (!button) return;
20710
- const composer = composerForElement(button);
20943
+ const candidate = composerForElement(button);
20944
+ const composer = candidate && isMountedComposer(candidate) ? candidate : null;
20711
20945
  const mounted = composer ? mountedByComposer.get(composer) : void 0;
20712
20946
  if (!composer || mounted?.control.sendButton !== button) return;
20713
20947
  if (!prepareComposer(composer)) {
@@ -20722,6 +20956,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20722
20956
  });
20723
20957
  const onAdapterStatus = () => {
20724
20958
  if (adapterStatus.state === "ready") {
20959
+ sidebarAgentIcons.refresh();
20725
20960
  void refreshHarnessAvailability();
20726
20961
  for (const mounted of mountedByComposer.values()) {
20727
20962
  if (mounted.modelView.status === "waitingForAdapter" && mounted.composer.isConnected && applyComposerAgent(mounted.composer)) {
@@ -20733,7 +20968,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20733
20968
  };
20734
20969
  mutationObserver.observe(document.documentElement, {
20735
20970
  attributes: true,
20736
- attributeFilter: ["hidden", "aria-hidden"],
20971
+ attributeFilter: ["hidden", "aria-hidden", "data-codex-composer-root"],
20737
20972
  characterData: true,
20738
20973
  childList: true,
20739
20974
  subtree: true