@codexhost/cli-darwin-x64 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3266,10 +3266,10 @@
3266
3266
  const shape = def.shape;
3267
3267
  const propValues = {};
3268
3268
  for (const key in shape) {
3269
- const field = shape[key]._zod;
3270
- if (field.values) {
3269
+ const field2 = shape[key]._zod;
3270
+ if (field2.values) {
3271
3271
  propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
3272
- for (const v of field.values)
3272
+ for (const v of field2.values)
3273
3273
  propValues[key].add(v);
3274
3274
  }
3275
3275
  }
@@ -14952,6 +14952,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14952
14952
  cachedInputTokens: count,
14953
14953
  cacheWriteInputTokens: count,
14954
14954
  cacheKnownInputTokens: count,
14955
+ cacheHitCachedInputTokens: count,
14956
+ cacheHitInputTokens: count,
14955
14957
  outputTokens: count,
14956
14958
  reasoningOutputTokens: count,
14957
14959
  /** USD at the public price, summed over the priced requests only. */
@@ -15059,6 +15061,53 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15059
15061
  var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
15060
15062
  var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
15061
15063
 
15064
+ // ../shared-contracts/dist/thread-questions.js
15065
+ var THREAD_QUESTIONS_LIST_METHOD = "codexhost/thread/questions/list";
15066
+ var THREAD_QUESTION_RESPOND_METHOD = "codexhost/thread/question/respond";
15067
+ var field = external_exports.discriminatedUnion("type", [
15068
+ external_exports.object({
15069
+ id: external_exports.string().min(1),
15070
+ type: external_exports.literal("choice"),
15071
+ prompt: external_exports.string(),
15072
+ options: external_exports.array(external_exports.object({
15073
+ value: external_exports.string().min(1),
15074
+ label: external_exports.string(),
15075
+ description: external_exports.string().optional()
15076
+ })).min(1),
15077
+ multiple: external_exports.boolean(),
15078
+ allowOther: external_exports.boolean(),
15079
+ optional: external_exports.boolean()
15080
+ }),
15081
+ external_exports.object({
15082
+ id: external_exports.string().min(1),
15083
+ type: external_exports.literal("text"),
15084
+ prompt: external_exports.string(),
15085
+ multiline: external_exports.boolean(),
15086
+ secret: external_exports.literal(false),
15087
+ optional: external_exports.boolean(),
15088
+ placeholder: external_exports.string().optional(),
15089
+ prefill: external_exports.string().optional()
15090
+ })
15091
+ ]);
15092
+ var threadQuestionSchema = external_exports.object({
15093
+ interactionId: external_exports.string().min(1),
15094
+ turnId: external_exports.string().min(1),
15095
+ title: external_exports.string().optional(),
15096
+ questions: external_exports.array(field).min(1)
15097
+ }).refine(({ questions }) => questions.some((q) => q.type === "choice" && q.multiple), {
15098
+ message: "Shared cards require at least one multi-select question"
15099
+ });
15100
+ var threadQuestionsListParamsSchema = external_exports.strictObject({ threadId: external_exports.string().min(1) });
15101
+ var threadQuestionsResultSchema = external_exports.object({ questions: external_exports.array(threadQuestionSchema) });
15102
+ var threadQuestionRespondParamsSchema = external_exports.strictObject({
15103
+ threadId: external_exports.string().min(1),
15104
+ turnId: external_exports.string().min(1),
15105
+ interactionId: external_exports.string().min(1),
15106
+ answers: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())),
15107
+ cancelled: external_exports.boolean().default(false)
15108
+ });
15109
+ var threadQuestionRespondResultSchema = external_exports.object({ accepted: external_exports.literal(true) });
15110
+
15062
15111
  // ../shared-contracts/dist/console.js
15063
15112
  var consoleAnnouncementSchema = external_exports.strictObject({
15064
15113
  title: external_exports.string().trim().min(1).max(200),
@@ -15363,7 +15412,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15363
15412
  external_exports.null()
15364
15413
  ]);
15365
15414
  function hasNoCircularReferences(value) {
15366
- const ancestors = /* @__PURE__ */ new WeakSet();
15415
+ const ancestors2 = /* @__PURE__ */ new WeakSet();
15367
15416
  const stack = [{ value, leaving: false }];
15368
15417
  try {
15369
15418
  while (stack.length > 0) {
@@ -15371,14 +15420,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15371
15420
  if (!frame)
15372
15421
  break;
15373
15422
  if (frame.leaving) {
15374
- ancestors.delete(frame.value);
15423
+ ancestors2.delete(frame.value);
15375
15424
  continue;
15376
15425
  }
15377
15426
  if (typeof frame.value !== "object" || frame.value === null)
15378
15427
  continue;
15379
- if (ancestors.has(frame.value))
15428
+ if (ancestors2.has(frame.value))
15380
15429
  return false;
15381
- ancestors.add(frame.value);
15430
+ ancestors2.add(frame.value);
15382
15431
  stack.push({ value: frame.value, leaving: true });
15383
15432
  for (const child of Object.values(frame.value)) {
15384
15433
  stack.push({ value: child, leaving: false });
@@ -16309,6 +16358,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16309
16358
  const candidates = [...urls].sort(
16310
16359
  (a, b) => Number(b.includes("/app-shared-")) - Number(a.includes("/app-shared-"))
16311
16360
  );
16361
+ const matches = /* @__PURE__ */ new Set();
16312
16362
  for (const url2 of candidates) {
16313
16363
  let module;
16314
16364
  try {
@@ -16316,11 +16366,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16316
16366
  } catch {
16317
16367
  continue;
16318
16368
  }
16319
- const matches = new Set(Object.values(module).filter(matchesServices));
16369
+ for (const value of Object.values(module).filter(matchesServices)) matches.add(value);
16320
16370
  if (matches.size > 1) throw new Error("Codex native services are unavailable in this window");
16321
- if (matches.size === 1) return [...matches][0] ?? null;
16322
16371
  }
16323
- return null;
16372
+ return [...matches][0] ?? null;
16324
16373
  }
16325
16374
 
16326
16375
  // src/codex-ssh-services.ts
@@ -16588,6 +16637,545 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16588
16637
  return control;
16589
16638
  }
16590
16639
 
16640
+ // ../../node_modules/lucide/dist/esm/defaultAttributes.mjs
16641
+ var defaultAttributes = {
16642
+ xmlns: "http://www.w3.org/2000/svg",
16643
+ width: 24,
16644
+ height: 24,
16645
+ viewBox: "0 0 24 24",
16646
+ fill: "none",
16647
+ stroke: "currentColor",
16648
+ "stroke-width": 2,
16649
+ "stroke-linecap": "round",
16650
+ "stroke-linejoin": "round"
16651
+ };
16652
+
16653
+ // ../../node_modules/lucide/dist/esm/createElement.mjs
16654
+ var createSVGElement = ([tag, attrs, children]) => {
16655
+ const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
16656
+ Object.keys(attrs).forEach((name) => {
16657
+ element.setAttribute(name, String(attrs[name]));
16658
+ });
16659
+ if (children?.length) {
16660
+ children.forEach((child) => {
16661
+ const childElement = createSVGElement(child);
16662
+ element.appendChild(childElement);
16663
+ });
16664
+ }
16665
+ return element;
16666
+ };
16667
+ var createElement = (iconNode, customAttrs = {}) => {
16668
+ const tag = "svg";
16669
+ const attrs = {
16670
+ ...defaultAttributes,
16671
+ ...customAttrs
16672
+ };
16673
+ return createSVGElement([tag, attrs, iconNode]);
16674
+ };
16675
+
16676
+ // ../../node_modules/lucide/dist/esm/icons/check.mjs
16677
+ var Check = [["path", { d: "M20 6 9 17l-5-5" }]];
16678
+
16679
+ // ../../node_modules/lucide/dist/esm/icons/message-circle-question-mark.mjs
16680
+ var MessageCircleQuestionMark = [
16681
+ [
16682
+ "path",
16683
+ {
16684
+ d: "M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"
16685
+ }
16686
+ ],
16687
+ ["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }],
16688
+ ["path", { d: "M12 17h.01" }]
16689
+ ];
16690
+
16691
+ // ../../node_modules/lucide/dist/esm/icons/pencil.mjs
16692
+ var Pencil = [
16693
+ [
16694
+ "path",
16695
+ {
16696
+ d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"
16697
+ }
16698
+ ],
16699
+ ["path", { d: "m15 5 4 4" }]
16700
+ ];
16701
+
16702
+ // ../../node_modules/lucide/dist/esm/icons/x.mjs
16703
+ var X = [
16704
+ ["path", { d: "M18 6 6 18" }],
16705
+ ["path", { d: "m6 6 12 12" }]
16706
+ ];
16707
+
16708
+ // src/renderer-question-card-style.ts
16709
+ var QUESTION_CARD_CSS = `
16710
+ :host {
16711
+ display: block;
16712
+ min-width: 0;
16713
+ margin: 8px 0;
16714
+ color-scheme: inherit;
16715
+ --question-text: light-dark(#171717, #ececec);
16716
+ --question-muted: light-dark(#737373, #a3a3a3);
16717
+ --question-border: light-dark(rgb(0 0 0 / 8%), rgb(255 255 255 / 8%));
16718
+ --question-selected: light-dark(#e9e9e9, #333333);
16719
+ --question-primary: light-dark(#202020, #ececec);
16720
+ --question-primary-text: light-dark(#fff, #171717);
16721
+ }
16722
+ *, ::before, ::after { box-sizing: border-box; }
16723
+ .card {
16724
+ display: flex;
16725
+ flex-direction: column;
16726
+ max-height: min(60vh, 560px);
16727
+ overflow: hidden;
16728
+ padding: 16px 12px 12px;
16729
+ border: 1px solid var(--question-border);
16730
+ border-radius: 24px;
16731
+ background: light-dark(#f7f7f7, #262626);
16732
+ color: var(--question-text);
16733
+ font: 13px/1.5 system-ui, sans-serif;
16734
+ }
16735
+ .title { display: flex; align-items: center; gap: 10px; flex-shrink: 0; margin: 0 6px 14px; color: var(--question-muted); font-weight: 400; }
16736
+ .question-icon { display: inline-flex; justify-content: center; align-items: center; width: 16px; height: 16px; flex-shrink: 0; }
16737
+ svg { display: block; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
16738
+ .body { min-height: 0; overflow: auto; }
16739
+ fieldset { min-width: 0; border: 0; padding: 0; margin: 0 0 14px; }
16740
+ fieldset:last-child { margin-bottom: 0; }
16741
+ legend { width: 100%; padding: 0 6px; margin-bottom: 14px; font: inherit; }
16742
+ .hint { color: var(--question-muted); font-size: 12px; margin: -10px 6px 10px; }
16743
+ .option {
16744
+ position: relative;
16745
+ display: flex;
16746
+ align-items: flex-start;
16747
+ gap: 10px;
16748
+ min-height: 34px;
16749
+ padding: 6px;
16750
+ margin: 2px 0;
16751
+ border-radius: 12px;
16752
+ cursor: pointer;
16753
+ background: transparent;
16754
+ overflow-wrap: anywhere;
16755
+ }
16756
+ .option:hover, .option:has(:checked) { background: var(--question-selected); }
16757
+ input[type=checkbox], input[type=radio] {
16758
+ appearance: none;
16759
+ display: block;
16760
+ flex: 0 0 21px;
16761
+ width: 21px;
16762
+ height: 21px;
16763
+ margin: 0;
16764
+ padding: 0;
16765
+ border: 1px solid var(--question-border);
16766
+ border-radius: 5px;
16767
+ background: light-dark(#ededed, #303030);
16768
+ cursor: pointer;
16769
+ }
16770
+ .shortcut { position: absolute; top: 6px; left: 6px; width: 21px; height: 21px; text-align: center; line-height: 21px; color: var(--question-muted); pointer-events: none; font-size: 12px; }
16771
+ .option-copy { flex: 1; min-width: 0; white-space: pre-wrap; }
16772
+ .option-name { display: block; font-weight: 400; }
16773
+ .description { display: block; color: var(--question-muted); font-size: 12px; margin-top: 1px; }
16774
+ .selected-indicator { align-self: center; visibility: hidden; color: var(--question-muted); padding-right: 4px; }
16775
+ :checked ~ .selected-indicator { visibility: visible; }
16776
+ .other { align-items: center; flex: 1; min-width: 0; margin: 0; }
16777
+ .other input[type=checkbox], .other input[type=radio] { background: transparent; border-color: transparent; }
16778
+ .other:has(:checked), .other:focus-within { background: var(--question-selected); }
16779
+ .other:has(:checked) .pencil { color: var(--question-text); }
16780
+ .pencil { display: flex; align-items: center; justify-content: center; }
16781
+ .other-copy { display: flex; flex: 1; min-width: 0; }
16782
+ input:not([type=checkbox]):not([type=radio]), textarea {
16783
+ appearance: none;
16784
+ display: block;
16785
+ min-width: 0;
16786
+ width: 100%;
16787
+ padding: 6px;
16788
+ border: 1px solid var(--question-border);
16789
+ border-radius: 8px;
16790
+ background: transparent;
16791
+ color: var(--question-text);
16792
+ font: inherit;
16793
+ }
16794
+ .other-copy input:not([type=checkbox]):not([type=radio]) { border: 0; padding: 0; }
16795
+ textarea { min-height: 60px; resize: vertical; }
16796
+ input::placeholder, textarea::placeholder { color: var(--question-muted); opacity: .65; }
16797
+ input:focus-visible, textarea:focus-visible, button:focus-visible {
16798
+ outline: 2px solid var(--question-muted);
16799
+ outline-offset: 2px;
16800
+ }
16801
+ .other-copy input:focus-visible { outline: none; }
16802
+ .other:has(input:focus-visible) { outline: 2px solid var(--question-muted); outline-offset: -2px; }
16803
+ .error { flex-shrink: 0; color: light-dark(#b42318, #ffaaa3); font-size: 12px; }
16804
+ .error:not(:empty) { margin: 8px 6px 0; }
16805
+ .footer { display: flex; align-items: center; gap: 8px; flex-shrink: 0; margin-top: 8px; }
16806
+ .actions { display: flex; justify-content: flex-end; gap: 8px; margin-left: auto; flex-shrink: 0; }
16807
+ button {
16808
+ appearance: none;
16809
+ min-height: 28px;
16810
+ padding: 3px 10px;
16811
+ border: 1px solid var(--question-border);
16812
+ border-radius: 999px;
16813
+ background: transparent;
16814
+ color: var(--question-text);
16815
+ font: inherit;
16816
+ font-weight: 400;
16817
+ cursor: pointer;
16818
+ }
16819
+ button:hover { background: var(--question-selected); }
16820
+ button.primary { background: var(--question-primary); color: var(--question-primary-text); border-color: transparent; }
16821
+ button.primary:hover { opacity: .85; }
16822
+ button.dismiss { display: flex; align-items: center; justify-content: center; border: 0; padding: 0; min-height: 24px; width: 24px; margin-left: auto; color: var(--question-muted); }
16823
+ :disabled { cursor: wait; opacity: .5; }
16824
+ @media (max-width: 420px) { .footer { flex-wrap: wrap; } .footer > .other { flex-basis: 100%; } }
16825
+ @media (forced-colors: active) {
16826
+ .card, input, textarea { background: Canvas; color: CanvasText; }
16827
+ button, .card, input[type=checkbox], input[type=radio] { border-color: ButtonBorder; }
16828
+ .option:has(:checked) { outline: 1px solid Highlight; outline-offset: -1px; }
16829
+ button.primary { background: Highlight; color: HighlightText; }
16830
+ }
16831
+ `;
16832
+
16833
+ // src/renderer-question-card.ts
16834
+ function createQuestionCard(document2, question, submit, initial = {}) {
16835
+ const icon2 = (node) => document2.adoptNode(
16836
+ createElement(node, {
16837
+ width: 16,
16838
+ height: 16,
16839
+ "aria-hidden": "true",
16840
+ focusable: "false"
16841
+ })
16842
+ );
16843
+ const selectedIndicator = () => {
16844
+ const selected = document2.createElement("span");
16845
+ selected.className = "selected-indicator";
16846
+ selected.setAttribute("aria-hidden", "true");
16847
+ selected.append(icon2(Check));
16848
+ return selected;
16849
+ };
16850
+ const root = document2.createElement("section");
16851
+ root.dataset.codexhostQuestion = question.interactionId;
16852
+ root.setAttribute("aria-label", question.title ?? "Question");
16853
+ root.addEventListener("keydown", (event) => {
16854
+ event.stopPropagation();
16855
+ if (event.key === "Enter" && event.composedPath()[0] instanceof HTMLInputElement)
16856
+ event.preventDefault();
16857
+ });
16858
+ const shadow = root.attachShadow({ mode: "open" });
16859
+ const style = document2.createElement("style");
16860
+ style.textContent = QUESTION_CARD_CSS;
16861
+ const surface = document2.createElement("div");
16862
+ surface.className = "card";
16863
+ shadow.append(style, surface);
16864
+ const title = document2.createElement("div");
16865
+ title.className = "title";
16866
+ const titleIcon = document2.createElement("span");
16867
+ titleIcon.className = "question-icon";
16868
+ titleIcon.append(icon2(MessageCircleQuestionMark));
16869
+ titleIcon.setAttribute("aria-hidden", "true");
16870
+ const titleText = document2.createElement("span");
16871
+ titleText.textContent = question.title?.trim() || "Question";
16872
+ const dismiss = document2.createElement("button");
16873
+ dismiss.type = "button";
16874
+ dismiss.className = "dismiss";
16875
+ dismiss.append(icon2(X));
16876
+ dismiss.setAttribute("aria-label", "Dismiss question");
16877
+ title.append(titleIcon, titleText, dismiss);
16878
+ const body = document2.createElement("div");
16879
+ body.className = "body";
16880
+ surface.append(title, body);
16881
+ const footer = document2.createElement("div");
16882
+ footer.className = "footer";
16883
+ const readers = /* @__PURE__ */ new Map();
16884
+ const controls = [dismiss];
16885
+ const validOther = [];
16886
+ for (const [index, field2] of question.questions.entries()) {
16887
+ const group = document2.createElement("fieldset");
16888
+ const legend = document2.createElement("legend");
16889
+ legend.textContent = field2.prompt;
16890
+ group.append(legend);
16891
+ const saved = initial[field2.id] ?? [];
16892
+ if (field2.type === "text") {
16893
+ const input = document2.createElement(field2.multiline ? "textarea" : "input");
16894
+ input.value = saved[0] ?? field2.prefill ?? "";
16895
+ input.placeholder = field2.placeholder ?? "Your answer";
16896
+ input.setAttribute("aria-label", field2.prompt);
16897
+ controls.push(input);
16898
+ group.append(input);
16899
+ readers.set(field2.id, () => input.value.trim() ? [input.value] : []);
16900
+ } else {
16901
+ const hint = document2.createElement("div");
16902
+ hint.className = "hint";
16903
+ hint.textContent = "Select all that apply";
16904
+ if (field2.multiple) group.append(hint);
16905
+ const inputs = [];
16906
+ const name = `codexhost-${question.interactionId}-${index}`;
16907
+ for (const [optionIndex, option] of field2.options.entries()) {
16908
+ const label = document2.createElement("label");
16909
+ label.className = "option";
16910
+ const input = document2.createElement("input");
16911
+ input.type = field2.multiple ? "checkbox" : "radio";
16912
+ input.name = name;
16913
+ input.value = option.value;
16914
+ input.checked = saved.includes(option.value);
16915
+ const shortcut = document2.createElement("span");
16916
+ shortcut.className = "shortcut";
16917
+ shortcut.setAttribute("aria-hidden", "true");
16918
+ shortcut.textContent = String(optionIndex + 1);
16919
+ const selected = selectedIndicator();
16920
+ const text = document2.createElement("span");
16921
+ text.className = "option-copy";
16922
+ const optionName = document2.createElement("span");
16923
+ optionName.className = "option-name";
16924
+ optionName.textContent = option.label;
16925
+ text.append(optionName);
16926
+ if (option.description) {
16927
+ const description = document2.createElement("span");
16928
+ description.className = "description";
16929
+ description.textContent = option.description;
16930
+ text.append(description);
16931
+ }
16932
+ label.append(input, shortcut, text, selected);
16933
+ group.append(label);
16934
+ inputs.push(input);
16935
+ controls.push(input);
16936
+ }
16937
+ let other;
16938
+ let notes;
16939
+ if (field2.allowOther) {
16940
+ const label = document2.createElement("label");
16941
+ label.className = "option other";
16942
+ other = document2.createElement("input");
16943
+ other.type = field2.multiple ? "checkbox" : "radio";
16944
+ other.name = name;
16945
+ other.setAttribute("aria-label", `Other: ${field2.prompt}`);
16946
+ const unknown2 = saved.find(
16947
+ (value) => !field2.options.some((option) => option.value === value)
16948
+ );
16949
+ other.checked = unknown2 !== void 0;
16950
+ notes = document2.createElement("input");
16951
+ notes.value = unknown2 ?? "";
16952
+ notes.placeholder = "Or write your own response";
16953
+ notes.setAttribute("aria-label", `${field2.prompt}: Other`);
16954
+ const checkbox = other;
16955
+ const otherText = notes;
16956
+ validOther.push(() => !checkbox.checked || otherText.value.trim().length > 0);
16957
+ notes.addEventListener("input", () => {
16958
+ checkbox.checked = true;
16959
+ });
16960
+ const copy = document2.createElement("span");
16961
+ copy.className = "other-copy";
16962
+ copy.append(notes);
16963
+ const pencil = document2.createElement("span");
16964
+ pencil.className = "shortcut pencil";
16965
+ pencil.append(icon2(Pencil));
16966
+ pencil.setAttribute("aria-hidden", "true");
16967
+ const selected = selectedIndicator();
16968
+ label.append(other, pencil, copy, selected);
16969
+ if (question.questions.length === 1) footer.append(label);
16970
+ else group.append(label);
16971
+ controls.push(other, notes);
16972
+ }
16973
+ readers.set(field2.id, () => [
16974
+ ...inputs.filter((input) => input.checked).map((input) => input.value),
16975
+ ...other?.checked && notes?.value.trim() ? [notes.value] : []
16976
+ ]);
16977
+ }
16978
+ body.append(group);
16979
+ }
16980
+ const error51 = document2.createElement("div");
16981
+ error51.setAttribute("role", "alert");
16982
+ error51.className = "error";
16983
+ const actions = document2.createElement("div");
16984
+ actions.className = "actions";
16985
+ const readAnswers = () => Object.fromEntries([...readers].map(([id, read]) => [id, read()]));
16986
+ let busy = false;
16987
+ const send = async (cancelled) => {
16988
+ if (busy) return;
16989
+ const answers = cancelled ? {} : readAnswers();
16990
+ if (!cancelled && validOther.some((valid) => !valid())) {
16991
+ error51.textContent = "Type an answer for each selected Other option.";
16992
+ return;
16993
+ }
16994
+ if (!cancelled && question.questions.some((field2) => !field2.optional && !answers[field2.id]?.length)) {
16995
+ error51.textContent = "Answer each required question before submitting.";
16996
+ return;
16997
+ }
16998
+ busy = true;
16999
+ error51.textContent = "";
17000
+ for (const control of controls) control.disabled = true;
17001
+ try {
17002
+ await submit(answers, cancelled);
17003
+ } catch {
17004
+ error51.textContent = "Could not submit. The question may have closed. Try again if it is still available.";
17005
+ } finally {
17006
+ busy = false;
17007
+ for (const control of controls) control.disabled = false;
17008
+ }
17009
+ };
17010
+ for (const [label, cancelled] of [
17011
+ ["Skip", true],
17012
+ ["Send", false]
17013
+ ]) {
17014
+ const button2 = document2.createElement("button");
17015
+ button2.type = "button";
17016
+ button2.textContent = label;
17017
+ if (!cancelled) button2.className = "primary";
17018
+ button2.addEventListener("click", () => {
17019
+ void send(cancelled);
17020
+ });
17021
+ controls.push(button2);
17022
+ actions.append(button2);
17023
+ }
17024
+ dismiss.addEventListener("click", () => {
17025
+ void send(true);
17026
+ });
17027
+ footer.append(actions);
17028
+ surface.append(error51, footer);
17029
+ return {
17030
+ root,
17031
+ readAnswers,
17032
+ dispose() {
17033
+ root.remove();
17034
+ }
17035
+ };
17036
+ }
17037
+
17038
+ // src/renderer-request-sender.ts
17039
+ var RendererMethodUnavailableError = class extends Error {
17040
+ constructor(method, cause) {
17041
+ super(`${method} is unsupported on this Host connection`, { cause });
17042
+ this.method = method;
17043
+ this.name = "RendererMethodUnavailableError";
17044
+ }
17045
+ method;
17046
+ code = -32601;
17047
+ };
17048
+ function isUnsupportedMethod(error51, method) {
17049
+ if (typeof error51 !== "object" || error51 === null) return false;
17050
+ const code = "code" in error51 ? error51.code : void 0;
17051
+ const message2 = "message" in error51 ? error51.message : void 0;
17052
+ return code === -32601 || code === -32600 && typeof message2 === "string" && message2.startsWith(`Invalid request: unknown variant \`${method}\``);
17053
+ }
17054
+ function createRendererRequestSender(send) {
17055
+ const unsupported = /* @__PURE__ */ new Map();
17056
+ return async (method, params, options) => {
17057
+ const known = unsupported.get(method);
17058
+ if (known) throw known;
17059
+ try {
17060
+ return await (options === void 0 ? send(method, params) : send(method, params, options));
17061
+ } catch (error51) {
17062
+ if (!method.startsWith("codexhost/") || !isUnsupportedMethod(error51, method)) throw error51;
17063
+ const unavailable = new RendererMethodUnavailableError(method, error51);
17064
+ unsupported.set(method, unavailable);
17065
+ throw unavailable;
17066
+ }
17067
+ };
17068
+ }
17069
+
17070
+ // src/renderer-questions.ts
17071
+ function same(a, b) {
17072
+ return a?.hostId === b?.hostId && a?.threadId === b?.threadId && a?.composer === b?.composer && a?.route === b?.route;
17073
+ }
17074
+ function installRendererQuestions(window2, readContext) {
17075
+ let disposed = false;
17076
+ let inFlight = false;
17077
+ let revision = 0;
17078
+ let context = null;
17079
+ let card = null;
17080
+ let cardKey = null;
17081
+ const unsupported = /* @__PURE__ */ new WeakSet();
17082
+ const drafts = /* @__PURE__ */ new Map();
17083
+ const clear = (retain = true) => {
17084
+ if (retain && card && cardKey) {
17085
+ drafts.set(cardKey, card.readAnswers());
17086
+ const oldest = drafts.keys().next().value;
17087
+ if (drafts.size > 50 && oldest !== void 0) drafts.delete(oldest);
17088
+ }
17089
+ card?.dispose();
17090
+ card = null;
17091
+ cardKey = null;
17092
+ };
17093
+ const refresh = async () => {
17094
+ if (disposed) return;
17095
+ const next = readContext();
17096
+ if (!same(context, next)) {
17097
+ clear();
17098
+ context = next;
17099
+ revision++;
17100
+ }
17101
+ const current = context;
17102
+ if (!current || inFlight || unsupported.has(current.route)) return;
17103
+ const startedRevision = revision;
17104
+ inFlight = true;
17105
+ try {
17106
+ const raw = await current.route.sendRequest(
17107
+ THREAD_QUESTIONS_LIST_METHOD,
17108
+ { threadId: current.threadId },
17109
+ { priority: "background", timeoutMs: 5e3 }
17110
+ );
17111
+ if (disposed || revision !== startedRevision || !same(current, readContext())) return;
17112
+ const question = threadQuestionsResultSchema.parse(raw).questions[0];
17113
+ if (!question) {
17114
+ if (cardKey) drafts.delete(cardKey);
17115
+ clear(false);
17116
+ return;
17117
+ }
17118
+ const key = JSON.stringify([
17119
+ current.hostId,
17120
+ current.threadId,
17121
+ question.turnId,
17122
+ question.interactionId
17123
+ ]);
17124
+ if (cardKey === key && card?.root.isConnected) return;
17125
+ clear(cardKey === key);
17126
+ cardKey = key;
17127
+ card = createQuestionCard(
17128
+ current.composer.ownerDocument,
17129
+ question,
17130
+ async (answers, cancelled) => {
17131
+ if (disposed || !same(current, readContext()) || cardKey !== key)
17132
+ throw new Error("Question owner changed");
17133
+ const raw2 = await current.route.sendRequest(
17134
+ THREAD_QUESTION_RESPOND_METHOD,
17135
+ {
17136
+ threadId: current.threadId,
17137
+ turnId: question.turnId,
17138
+ interactionId: question.interactionId,
17139
+ answers,
17140
+ cancelled
17141
+ },
17142
+ { priority: "interactive", timeoutMs: 1e4 }
17143
+ );
17144
+ threadQuestionRespondResultSchema.parse(raw2);
17145
+ drafts.delete(key);
17146
+ if (same(current, context)) {
17147
+ revision++;
17148
+ if (cardKey === key) clear(false);
17149
+ }
17150
+ },
17151
+ drafts.get(key)
17152
+ );
17153
+ current.composer.before(card.root);
17154
+ } catch (error51) {
17155
+ if (isUnsupportedMethod(error51, THREAD_QUESTIONS_LIST_METHOD)) unsupported.add(current.route);
17156
+ if (revision === startedRevision && same(current, context)) clear();
17157
+ } finally {
17158
+ inFlight = false;
17159
+ }
17160
+ };
17161
+ const timer = window2.setInterval(() => {
17162
+ void refresh();
17163
+ }, 750);
17164
+ void refresh();
17165
+ return {
17166
+ refresh,
17167
+ refreshContext() {
17168
+ if (!same(context, readContext()) || card && !card.root.isConnected) void refresh();
17169
+ },
17170
+ dispose() {
17171
+ disposed = true;
17172
+ window2.clearInterval(timer);
17173
+ clear(false);
17174
+ drafts.clear();
17175
+ }
17176
+ };
17177
+ }
17178
+
16591
17179
  // ../desktop-control/dist/renderer-react-ownership.js
16592
17180
  var REACT_FIBER_WALK_LIMIT_EVENT = "codexhost:react-fiber-walk-limit";
16593
17181
  function committedReactAncestors(value) {
@@ -16654,10 +17242,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16654
17242
  return [];
16655
17243
  seen.add(entry.node);
16656
17244
  if (entry.node === first || entry.node === alternate) {
16657
- const ancestors = [];
17245
+ const ancestors2 = [];
16658
17246
  for (let cursor = entry; cursor; cursor = cursor.parent)
16659
- ancestors.push(cursor.node);
16660
- return ancestors;
17247
+ ancestors2.push(cursor.node);
17248
+ return ancestors2;
16661
17249
  }
16662
17250
  const sibling = entry.parent && fiber(entry.node.sibling);
16663
17251
  if (sibling)
@@ -16669,6 +17257,402 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16669
17257
  return stack.length > 0 ? exhausted() : [];
16670
17258
  }
16671
17259
 
17260
+ // ../desktop-control/dist/renderer-native-schedule-sidebar.js
17261
+ var NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR = 'aside [data-sidebar-cycle-item][role="button"][aria-labelledby]';
17262
+ function readNativeScheduleSidebarThread(element) {
17263
+ if (!element.matches(NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR))
17264
+ return null;
17265
+ const keys = Object.keys(element).filter((key2) => key2.startsWith("__reactFiber$"));
17266
+ const key = keys[0];
17267
+ if (keys.length !== 1 || !key)
17268
+ return null;
17269
+ let scheduledContainer = false;
17270
+ const candidates = /* @__PURE__ */ new Set();
17271
+ let depth = 0;
17272
+ for (const fiber of committedReactAncestors(Reflect.get(element, key))) {
17273
+ if (++depth > 12)
17274
+ break;
17275
+ const props = fiber.memoizedProps;
17276
+ if (!props || typeof props !== "object")
17277
+ continue;
17278
+ if (Object.hasOwn(props, "data-selected-scheduled-task"))
17279
+ scheduledContainer = true;
17280
+ if (!scheduledContainer || !Object.hasOwn(props, "automation"))
17281
+ continue;
17282
+ const automation = props.automation;
17283
+ if (!automation || typeof automation !== "object" || automation.kind !== "heartbeat" || typeof automation.id !== "string" || !automation.id || props.hostId != null && props.hostId !== "local" || automation.hostId != null && automation.hostId !== "local")
17284
+ return null;
17285
+ const parsed = hostThreadIdSchema.safeParse(automation.targetThreadId);
17286
+ if (!parsed.success)
17287
+ return null;
17288
+ candidates.add(parsed.data);
17289
+ }
17290
+ return candidates.size === 1 ? candidates.values().next().value ?? null : null;
17291
+ }
17292
+
17293
+ // ../desktop-control/dist/renderer-scoped-draft-model.js
17294
+ function findScopedDraftModelBinding(composer, draftId) {
17295
+ let element = composer.querySelector?.('[data-codex-composer], [contenteditable="true"][role="textbox"]') ?? composer;
17296
+ let fiber;
17297
+ while (element && !fiber) {
17298
+ const key = Object.getOwnPropertyNames(element).find((name) => name.startsWith("__reactFiber$"));
17299
+ if (key)
17300
+ fiber = Object.getOwnPropertyDescriptor(element, key)?.value;
17301
+ element = element.parentElement;
17302
+ }
17303
+ const rows = [];
17304
+ const groups = /* @__PURE__ */ new Map();
17305
+ const updates = /* @__PURE__ */ new Set();
17306
+ for (const ancestor of committedReactAncestors(fiber)) {
17307
+ const queue = ancestor.updateQueue;
17308
+ const data = (queue?.memoCache?.data ?? []).filter(Array.isArray);
17309
+ for (const row of data) {
17310
+ rows.push(row);
17311
+ groups.set(row, data);
17312
+ if (!Array.isArray(row) || row.length !== 14 || row[6] !== draftId || row[7] !== draftId)
17313
+ continue;
17314
+ const result = row[13];
17315
+ if (result?.isNewThreadDraft === true && row[11] === true && result.draftSettings === row[10] && result.updateDraftSettings === row[9] && row[9] === row[12] && typeof row[9] === "function")
17316
+ updates.add(row[9]);
17317
+ }
17318
+ }
17319
+ let update;
17320
+ const modes = /* @__PURE__ */ new Set();
17321
+ const creationModes = /* @__PURE__ */ new Set();
17322
+ for (const row of rows) {
17323
+ if (row.length !== 24 || row[7] !== null || row[10] !== true || !updates.has(row[13]))
17324
+ continue;
17325
+ const context = row[12];
17326
+ const result = row[23];
17327
+ if (context && context === row[21] && typeof context.usesAccountPreferences === "boolean" && result?.usesAccountPreferences === context.usesAccountPreferences && typeof row[14] === "function" && row[14] === row[20] && result.setModelAndReasoningEffort === row[14]) {
17328
+ update ??= row[13];
17329
+ modes.add(context.usesAccountPreferences);
17330
+ const settings = result.modelSettings;
17331
+ const group = groups.get(row);
17332
+ const candidate = group?.[group.indexOf(row) - 1];
17333
+ const mode = candidate?.[44];
17334
+ const value = candidate?.[51];
17335
+ if (candidate?.length === 52 && settings && candidate[39] === settings.model && candidate[40] === settings.reasoningEffort && mode && mode === candidate[49] && mode.settings === candidate[41] && mode.settings?.model === settings.model && value?.activeMode === mode)
17336
+ creationModes.add(mode);
17337
+ }
17338
+ }
17339
+ const [usesAccountPreferences] = modes;
17340
+ return update && modes.size === 1 && usesAccountPreferences !== void 0 ? {
17341
+ update,
17342
+ usesAccountPreferences,
17343
+ ...creationModes.size ? { creationModes: [...creationModes] } : {}
17344
+ } : null;
17345
+ }
17346
+ function createScopedDraftModelWriter() {
17347
+ const captured = /* @__PURE__ */ new Map();
17348
+ const restore = (key) => {
17349
+ const entry = captured.get(key);
17350
+ if (!entry)
17351
+ return;
17352
+ entry.update((current) => {
17353
+ const settings = current.modelSettings;
17354
+ return settings?.model === entry.model && current.modelSettingsPersistAsDefault === false ? {
17355
+ ...current,
17356
+ modelSettings: entry.original.modelSettings,
17357
+ modelSettingsPersistAsDefault: entry.original.modelSettingsPersistAsDefault,
17358
+ isManuallyChanged: entry.original.isManuallyChanged
17359
+ } : current;
17360
+ });
17361
+ captured.delete(key);
17362
+ };
17363
+ return {
17364
+ has(key) {
17365
+ return captured.has(key);
17366
+ },
17367
+ apply(key, binding, model2) {
17368
+ if (model2 === null) {
17369
+ restore(key);
17370
+ return;
17371
+ }
17372
+ const { update, usesAccountPreferences } = binding;
17373
+ update((current) => {
17374
+ const previous = captured.get(key);
17375
+ captured.set(key, { update, original: previous?.original ?? current, model: model2 });
17376
+ const settings = current.modelSettings;
17377
+ if (settings?.model === model2 && settings.usesAccountPreferences === usesAccountPreferences && current.modelSettingsPersistAsDefault === false)
17378
+ return current;
17379
+ return {
17380
+ ...current,
17381
+ isManuallyChanged: true,
17382
+ modelSettingsPersistAsDefault: false,
17383
+ modelSettings: {
17384
+ ...settings,
17385
+ model: model2,
17386
+ reasoningEffort: settings?.reasoningEffort ?? null,
17387
+ profile: settings?.profile ?? null,
17388
+ usesAccountPreferences
17389
+ }
17390
+ };
17391
+ });
17392
+ },
17393
+ dispose() {
17394
+ for (const key of captured.keys())
17395
+ restore(key);
17396
+ }
17397
+ };
17398
+ }
17399
+
17400
+ // ../desktop-control/dist/renderer-native-schedule-form.js
17401
+ var record4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17402
+ function ancestors(element) {
17403
+ if (!record4(element))
17404
+ return [];
17405
+ const key = Object.getOwnPropertyNames(element).find((name) => name.startsWith("__reactFiber$"));
17406
+ return committedReactAncestors(key ? Object.getOwnPropertyDescriptor(element, key)?.value : null);
17407
+ }
17408
+ function readNativeScheduleForm(form) {
17409
+ const candidates = ancestors(form).flatMap(({ memoizedProps: props2 }) => {
17410
+ if (!record4(props2) || !record4(props2.setup) || props2.setup.triggerMode !== "create" || !record4(props2.draft) || !record4(props2.draft.scheduleConfig) || typeof props2.draft.scheduleDirty !== "boolean" || typeof props2.draft.prompt !== "string" || props2.draft.id != null || !["heartbeat", "cron"].includes(String(props2.draft.kind)) || !["local", "cloud"].includes(String(props2.executionLocation)) || typeof props2.onChange !== "function" || typeof props2.onSubmit !== "function" || typeof props2.isSaving !== "boolean" || props2.draft.model !== null && typeof props2.draft.model !== "string" || props2.draft.reasoningEffort !== null && typeof props2.draft.reasoningEffort !== "string")
17411
+ return [];
17412
+ return [props2];
17413
+ });
17414
+ const props = candidates[0];
17415
+ if (!props || candidates.some((other) => other.draft !== props.draft || other.onChange !== props.onChange || other.onSubmit !== props.onSubmit))
17416
+ return null;
17417
+ const draft = props.draft;
17418
+ const change = props.onChange;
17419
+ const supportsExternal = props.executionLocation === "local" && draft.kind === "heartbeat" && draft.cloudTeam == null && (!record4(props.creation) || props.creation.type === "task") && (!record4(draft.eventTrigger) || draft.eventTrigger.selected !== true) && (!Array.isArray(draft.webhookTriggers) || draft.webhookTriggers.length === 0);
17420
+ return {
17421
+ selection: {
17422
+ model: draft.model,
17423
+ reasoningEffort: draft.reasoningEffort
17424
+ },
17425
+ supportsExternal,
17426
+ hasTarget: draft.targetThreadId != null,
17427
+ isSaving: props.isSaving,
17428
+ title: (typeof draft.name === "string" ? draft.name.trim() : "") || String(draft.prompt).trim().replace(/\s+/gu, " ").slice(0, 80),
17429
+ targetThreadId: typeof draft.targetThreadId === "string" ? draft.targetThreadId : null,
17430
+ setTargetThread(threadId, expectedModel) {
17431
+ if (!supportsExternal || props.isSaving || draft.targetThreadId != null || !threadId || !expectedModel.startsWith("codexhost/plugin-v1@"))
17432
+ return;
17433
+ change((current) => current.id == null && current.targetThreadId == null && current.kind === "heartbeat" && current.cloudTeam == null && current.model === expectedModel ? { ...current, targetThreadId: threadId } : current);
17434
+ },
17435
+ setModel(selection) {
17436
+ if (props.isSaving || draft.targetThreadId != null)
17437
+ return;
17438
+ change((current) => current.id == null && current.targetThreadId == null && current.kind === draft.kind ? { ...current, ...selection } : current);
17439
+ }
17440
+ };
17441
+ }
17442
+ function nativeScheduleModelRows(form) {
17443
+ const rows = /* @__PURE__ */ new Set();
17444
+ for (const button2 of form.querySelectorAll("button")) {
17445
+ let host = null;
17446
+ for (const fiber of ancestors(button2)) {
17447
+ const node = fiber.stateNode;
17448
+ if (node === form)
17449
+ break;
17450
+ if (record4(node) && node.nodeType === 1 && typeof node.hidden === "boolean" && record4(node.style) && ["getPropertyValue", "getPropertyPriority", "setProperty"].every((method) => typeof node.style[method] === "function") && form.contains(node))
17451
+ host = node;
17452
+ const props = fiber.memoizedProps;
17453
+ const label = record4(props) && record4(props.label) ? props.label.props : null;
17454
+ if (record4(label) && ["inbox.automations.model.label", "automations.configuration.effort"].includes(String(label.id))) {
17455
+ if (host)
17456
+ rows.add(host);
17457
+ break;
17458
+ }
17459
+ }
17460
+ }
17461
+ return [...rows];
17462
+ }
17463
+
17464
+ // ../desktop-control/dist/renderer-host-discovery.js
17465
+ function requestManagerFromHookState(value, hostId2) {
17466
+ const record8 = (candidate) => typeof candidate === "object" && candidate !== null;
17467
+ const manager = (candidate) => {
17468
+ if (!record8(candidate) || !record8(candidate.requestClient) || !record8(candidate.prewarmedThreadManager))
17469
+ return null;
17470
+ const bridge = candidate.requestClient;
17471
+ return typeof candidate.sendRequest === "function" && typeof bridge.sendRequest === "function" && typeof bridge.prewarmThreadStart === "function" && typeof bridge.enqueueRequest === "function" && typeof candidate.prewarmedThreadManager.discardAllPrewarmedThreads === "function" ? candidate : null;
17472
+ };
17473
+ if (!record8(value))
17474
+ return null;
17475
+ const direct = manager(value) ?? manager(value.manager);
17476
+ if (direct)
17477
+ return direct;
17478
+ if (!hostId2 || typeof value.addManager !== "function" || typeof value.getForHostId !== "function")
17479
+ return null;
17480
+ try {
17481
+ return manager(value.getForHostId(hostId2));
17482
+ } catch {
17483
+ return null;
17484
+ }
17485
+ }
17486
+ function discoverRendererHosts(root, ancestors2 = committedReactAncestors, managerFrom = requestManagerFromHookState) {
17487
+ const editors = [
17488
+ ...root.querySelectorAll('[data-codex-composer], [contenteditable="true"][role="textbox"]')
17489
+ ];
17490
+ const hostIds = /* @__PURE__ */ new Set();
17491
+ const managers = /* @__PURE__ */ new Set();
17492
+ const registries = /* @__PURE__ */ new Set();
17493
+ const fibers = /* @__PURE__ */ new Set();
17494
+ for (const editor of editors) {
17495
+ let element = editor;
17496
+ let fiber;
17497
+ while (element && !fiber) {
17498
+ const key = Object.getOwnPropertyNames(element).find((name) => name.startsWith("__reactFiber$"));
17499
+ if (key)
17500
+ fiber = Object.getOwnPropertyDescriptor(element, key)?.value;
17501
+ element = element.parentElement ?? null;
17502
+ }
17503
+ for (const current of ancestors2(fiber)) {
17504
+ fibers.add(current);
17505
+ const props = current.memoizedProps;
17506
+ for (const key of ["executionTargetHostId", "permissionsHostId"]) {
17507
+ const hostId2 = props?.[key];
17508
+ if (typeof hostId2 === "string" && hostId2)
17509
+ hostIds.add(hostId2);
17510
+ }
17511
+ }
17512
+ }
17513
+ for (const fiber of fibers) {
17514
+ let hook = fiber.memoizedState;
17515
+ for (let index = 0; hook && index < 120; index += 1) {
17516
+ const value = hook.memoizedState;
17517
+ const manager = managerFrom(value);
17518
+ if (manager)
17519
+ managers.add(manager);
17520
+ if (value && typeof value === "object" && "addManager" in value && typeof value.addManager === "function" && "getForHostId" in value && typeof value.getForHostId === "function") {
17521
+ registries.add(value);
17522
+ }
17523
+ hook = hook.next && typeof hook.next === "object" ? hook.next : null;
17524
+ }
17525
+ }
17526
+ return {
17527
+ editorCount: editors.length,
17528
+ hostIds: [...hostIds],
17529
+ managers: [...managers],
17530
+ registries: [...registries]
17531
+ };
17532
+ }
17533
+
17534
+ // ../desktop-control/dist/renderer-schedule-workspace.js
17535
+ var record5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17536
+ function readNativeScheduleWorkspaces(root) {
17537
+ const projects = /* @__PURE__ */ new Map();
17538
+ const ambiguous = /* @__PURE__ */ new Set();
17539
+ const seen = /* @__PURE__ */ new Set();
17540
+ const add = (value) => {
17541
+ if (!record5(value) || value.source !== "codex" || !record5(value.group))
17542
+ return;
17543
+ const group = value.group;
17544
+ if (group.projectKind !== "local" || group.hostId != null && group.hostId !== "local" || typeof group.projectId !== "string" || !group.projectId || typeof group.label !== "string" || typeof group.path !== "string" || !Array.isArray(group.rootPaths) || !group.rootPaths.includes(group.path) || !/^(?:\/|[A-Za-z]:[\\/]|\\\\)/u.test(group.path) || group.path.includes("\0"))
17545
+ return;
17546
+ const next = { id: group.projectId, label: group.label || group.path, cwd: group.path };
17547
+ const previous = projects.get(next.id);
17548
+ if (previous && previous.cwd !== next.cwd)
17549
+ ambiguous.add(next.id);
17550
+ else
17551
+ projects.set(next.id, next);
17552
+ };
17553
+ for (const element of root.querySelectorAll("aside [data-sidebar-cycle-item]")) {
17554
+ const keys = Object.getOwnPropertyNames(element).filter((key2) => key2.startsWith("__reactFiber$"));
17555
+ const key = keys[0];
17556
+ if (keys.length !== 1 || !key)
17557
+ continue;
17558
+ for (const fiber of committedReactAncestors(Reflect.get(element, key))) {
17559
+ if (seen.has(fiber))
17560
+ break;
17561
+ seen.add(fiber);
17562
+ const props = fiber.memoizedProps;
17563
+ if (!record5(props))
17564
+ continue;
17565
+ add(props.project);
17566
+ if (props.projectByKey instanceof Map)
17567
+ for (const project3 of props.projectByKey.values())
17568
+ add(project3);
17569
+ }
17570
+ }
17571
+ return [...projects.values()].filter(({ id }) => !ambiguous.has(id));
17572
+ }
17573
+ function isNativeProjectThreadCreator(value) {
17574
+ if (typeof value !== "function" || value.length !== 1)
17575
+ return false;
17576
+ const source = Function.prototype.toString.call(value);
17577
+ return /^async function/u.test(source) && source.includes("startWithoutFirstTurn:") && source.includes("onSettled:") && source.includes("createThread config is not supported for delegated thread creation") && source.includes("createThread serviceName is only supported for local Electron root threads outside worktrees");
17578
+ }
17579
+ async function createNativeScheduleWorkspaceThread(root, routing, createThread, input, signal) {
17580
+ if (!decodeHarnessPluginRoute(input.model))
17581
+ throw new Error("An external Harness is required");
17582
+ const route = routing.forHost("local");
17583
+ const manager = route?.manager;
17584
+ if (!route?.policy.scopedCreation || !manager || typeof manager.getConversation !== "function" || typeof manager.archiveConversation !== "function")
17585
+ throw new Error("Native local chat creation is unavailable");
17586
+ const discovery = discoverRendererHosts({
17587
+ querySelectorAll: () => root.querySelectorAll("main")
17588
+ });
17589
+ const scopes = new Set(discovery.registries.flatMap((registry2) => {
17590
+ try {
17591
+ return registry2.getForHostId("local") === manager ? [Reflect.get(registry2, "scope")] : [];
17592
+ } catch {
17593
+ return [];
17594
+ }
17595
+ }));
17596
+ const scope = scopes.values().next().value;
17597
+ if (scopes.size !== 1 || !record5(scope) || typeof scope.get !== "function")
17598
+ throw new Error("Native local chat scope is missing or ambiguous");
17599
+ if (!readNativeScheduleWorkspaces(root).some(({ id, cwd }) => id === input.workspace.id && cwd === input.workspace.cwd))
17600
+ throw new Error("The selected workspace is no longer available");
17601
+ signal.throwIfAborted();
17602
+ let createdId = null;
17603
+ let released = false;
17604
+ const discard = () => {
17605
+ if (!createdId || released)
17606
+ return;
17607
+ const id = createdId;
17608
+ released = true;
17609
+ const conversation2 = manager.getConversation(id);
17610
+ if (!record5(conversation2) || !Array.isArray(conversation2.turns) || conversation2.turns.length || Array.isArray(conversation2.requests) && conversation2.requests.length > 0 || conversation2.pendingRequest != null)
17611
+ return;
17612
+ void Promise.resolve().then(() => manager.archiveConversation(id, {
17613
+ useAppServerPins: false,
17614
+ source: "automation_history"
17615
+ })).catch(() => void 0);
17616
+ };
17617
+ signal.addEventListener("abort", discard, { once: true });
17618
+ const remember = (result2) => {
17619
+ if (!record5(result2) || result2.status !== "created")
17620
+ return;
17621
+ const id = hostThreadIdSchema.safeParse(result2.conversationId);
17622
+ if (id.success)
17623
+ createdId = id.data;
17624
+ if (signal.aborted)
17625
+ discard();
17626
+ };
17627
+ const output = await createThread({
17628
+ scope,
17629
+ target: { type: "project", projectId: input.workspace.id, environment: { type: "local" } },
17630
+ model: input.model,
17631
+ title: input.title,
17632
+ prompt: "",
17633
+ startWithoutFirstTurn: true,
17634
+ onSettled: remember
17635
+ });
17636
+ const result = record5(output) && output.kind === "creation" ? output.result : null;
17637
+ remember(result);
17638
+ signal.throwIfAborted();
17639
+ if (!record5(result) || result.status !== "created" || !createdId || !record5(result.firstTurn) || result.firstTurn.status !== "not-requested")
17640
+ throw new Error("Chat creation was not confirmed. Check the chat list before creating another task.");
17641
+ if (routing.forHost("local")?.manager !== route.manager)
17642
+ throw new Error("The local connection changed. Reopen the task dialog.");
17643
+ const conversation = manager.getConversation(createdId);
17644
+ const mode = record5(conversation) ? conversation.latestCollaborationMode : null;
17645
+ if (!record5(conversation) || conversation.cwd !== input.workspace.cwd || !record5(mode) || !record5(mode.settings) || mode.settings.model !== input.model)
17646
+ throw new Error("The created chat's workspace or Model could not be confirmed");
17647
+ return {
17648
+ threadId: createdId,
17649
+ retain() {
17650
+ released = true;
17651
+ signal.removeEventListener("abort", discard);
17652
+ }
17653
+ };
17654
+ }
17655
+
16672
17656
  // src/renderer-composer-kind.ts
16673
17657
  function orbitComposerKind(composer) {
16674
17658
  let element = composer.querySelector('[contenteditable="true"], textarea, [role="textbox"]') ?? composer;
@@ -16917,42 +17901,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16917
17901
  return fallback;
16918
17902
  }
16919
17903
 
16920
- // ../../node_modules/lucide/dist/esm/defaultAttributes.mjs
16921
- var defaultAttributes = {
16922
- xmlns: "http://www.w3.org/2000/svg",
16923
- width: 24,
16924
- height: 24,
16925
- viewBox: "0 0 24 24",
16926
- fill: "none",
16927
- stroke: "currentColor",
16928
- "stroke-width": 2,
16929
- "stroke-linecap": "round",
16930
- "stroke-linejoin": "round"
16931
- };
16932
-
16933
- // ../../node_modules/lucide/dist/esm/createElement.mjs
16934
- var createSVGElement = ([tag, attrs, children]) => {
16935
- const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
16936
- Object.keys(attrs).forEach((name) => {
16937
- element.setAttribute(name, String(attrs[name]));
16938
- });
16939
- if (children?.length) {
16940
- children.forEach((child) => {
16941
- const childElement = createSVGElement(child);
16942
- element.appendChild(childElement);
16943
- });
16944
- }
16945
- return element;
16946
- };
16947
- var createElement = (iconNode, customAttrs = {}) => {
16948
- const tag = "svg";
16949
- const attrs = {
16950
- ...defaultAttributes,
16951
- ...customAttrs
16952
- };
16953
- return createSVGElement([tag, attrs, iconNode]);
16954
- };
16955
-
16956
17904
  // ../../node_modules/lucide/dist/esm/icons/boxes.mjs
16957
17905
  var Boxes = [
16958
17906
  [
@@ -16984,6 +17932,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16984
17932
  ["path", { d: "M12 13.5V8" }]
16985
17933
  ];
16986
17934
 
17935
+ // ../../node_modules/lucide/dist/esm/icons/calendar-clock.mjs
17936
+ var CalendarClock = [
17937
+ ["path", { d: "M16 14v2.2l1.6 1" }],
17938
+ ["path", { d: "M16 2v3" }],
17939
+ ["path", { d: "M21 7.338V5a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h2.338" }],
17940
+ ["path", { d: "M3 9h5.859" }],
17941
+ ["path", { d: "M8 2v3" }],
17942
+ ["circle", { cx: "16", cy: "16", r: "6" }]
17943
+ ];
17944
+
16987
17945
  // ../../node_modules/lucide/dist/esm/icons/circle-check.mjs
16988
17946
  var CircleCheck = [
16989
17947
  ["circle", { cx: "12", cy: "12", r: "10" }],
@@ -17257,12 +18215,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17257
18215
  ["path", { d: "M12 17h.01" }]
17258
18216
  ];
17259
18217
 
17260
- // ../../node_modules/lucide/dist/esm/icons/x.mjs
17261
- var X = [
17262
- ["path", { d: "M18 6 6 18" }],
17263
- ["path", { d: "m6 6 12 12" }]
17264
- ];
17265
-
17266
18218
  // ../../node_modules/lucide/dist/esm/icons/users.mjs
17267
18219
  var Users = [
17268
18220
  ["path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }],
@@ -17295,6 +18247,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17295
18247
  "routes",
17296
18248
  "gateway",
17297
18249
  "updates",
18250
+ "schedules",
17298
18251
  "about",
17299
18252
  "info",
17300
18253
  "external-link",
@@ -17346,6 +18299,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17346
18299
  routes: Route,
17347
18300
  gateway: Network,
17348
18301
  updates: CircleArrowUp,
18302
+ schedules: CalendarClock,
17349
18303
  about: Info,
17350
18304
  info: Info,
17351
18305
  "external-link": ExternalLink,
@@ -18966,12 +19920,13 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
18966
19920
  notAvailable: "Not available",
18967
19921
  runtimeCapabilityNotInstalled: "This runtime capability is not installed yet.",
18968
19922
  sessionImportHarness: "Harness",
19923
+ sessionImportSelectHost: "Select the Host to import sessions from",
18969
19924
  sessionImportDescription: "Sessions keep their original project path. If a folder is not in the Codex sidebar, add it as a project first. Original history remains managed by the Harness.",
18970
- sessionImportAvailabilityNote: "Available Harnesses come from the local Host. If activity is unknown, close the session in its native client before importing to avoid concurrent writes.",
19925
+ sessionImportAvailabilityNote: "Available Harnesses come from the selected Host. If activity is unknown, close the session in its native client before importing to avoid concurrent writes.",
18971
19926
  sessionImportRefresh: "Refresh",
18972
- sessionImportRefreshing: "Loading local sessions...",
18973
- sessionImportUnavailable: "Session import is unavailable for this local Harness or its current protocol. Update the Host/plugin or choose another Harness.",
18974
- sessionImportEmpty: "No local sessions are available to import.",
19927
+ sessionImportRefreshing: "Loading sessions from the selected Host...",
19928
+ sessionImportUnavailable: "Session import is unavailable for this Harness or the selected Host protocol. Update the Host/plugin or choose another Harness.",
19929
+ sessionImportEmpty: "No sessions are available to import on the selected Host.",
18975
19930
  sessionImportSearch: "Search",
18976
19931
  sessionImportSearchPlaceholder: "Search titles, session IDs or project paths",
18977
19932
  sessionImportNoMatches: "No sessions match your search.",
@@ -18979,7 +19934,7 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
18979
19934
  sessionImportPrevious: "Previous",
18980
19935
  sessionImportNext: "Next",
18981
19936
  sessionImportPageSummary: "Page {page} of {pages} \xB7 {total} sessions",
18982
- sessionImportLoadFailed: "Local sessions could not be loaded. Check directory access or duplicate session IDs, then retry.",
19937
+ sessionImportLoadFailed: "Sessions could not be loaded from the selected Host. Check directory access or duplicate session IDs, then retry.",
18983
19938
  sessionImportFailed: "The session could not be imported.",
18984
19939
  sessionImportUntitled: "Untitled session",
18985
19940
  sessionImportUpdatedAt: "Updated",
@@ -19135,7 +20090,6 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19135
20090
  updateLatestVersion: "Latest version",
19136
20091
  updateUpToDate: "You are up to date.",
19137
20092
  updateAvailable: "A new version is available.",
19138
- updateWindowsManualRequired: "Automatic updates are unavailable on Windows. Update manually below.",
19139
20093
  updateAndRestart: "Update",
19140
20094
  updateChecking: "Checking for updates...",
19141
20095
  updateDownloading: "Downloading update...",
@@ -19150,8 +20104,7 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19150
20104
  updateFailed: "Update failed.",
19151
20105
  updateRetry: "Retry",
19152
20106
  updateManualNpmDescription: "To update manually, quit codexhost and run this command:",
19153
- updateWindowsNpmDescription: "Automatic updates are unavailable on Windows. Quit codexhost and run this command in a terminal:",
19154
- updateWindowsInstallerDescription: "Automatic updates are unavailable on Windows. Download and run the installer for this system.",
20107
+ updateWindowsInstallerDescription: "To update manually, download and run the installer for this system.",
19155
20108
  updateManualTitle: "Manual update",
19156
20109
  updateManualFallbackDescription: "The automatic update did not complete. Run this command in a terminal instead, then quit Codex and relaunch it with codexhost.",
19157
20110
  updateCopyCommand: "Copy",
@@ -19246,12 +20199,13 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19246
20199
  notAvailable: "\u6682\u4E0D\u53EF\u7528",
19247
20200
  runtimeCapabilityNotInstalled: "\u8FD0\u884C\u65F6\u5C1A\u672A\u5B89\u88C5\u8BE5\u9879\u80FD\u529B\uFF0C\u56E0\u6B64\u6682\u4E0D\u53EF\u7528\u3002",
19248
20201
  sessionImportHarness: "Harness",
20202
+ sessionImportSelectHost: "\u8BF7\u9009\u62E9\u8981\u5BFC\u5165\u4F1A\u8BDD\u7684 Host",
19249
20203
  sessionImportDescription: "\u4F1A\u8BDD\u5C06\u4FDD\u7559\u539F\u59CB\u9879\u76EE\u8DEF\u5F84\uFF1B\u82E5\u8BE5\u6587\u4EF6\u5939\u5C1A\u672A\u51FA\u73B0\u5728 Codex \u4FA7\u680F\uFF0C\u8BF7\u5148\u5C06\u5176\u6DFB\u52A0\u4E3A\u9879\u76EE\u3002\u539F\u59CB\u5386\u53F2\u4ECD\u7531 Harness \u7BA1\u7406\u3002",
19250
- sessionImportAvailabilityNote: "\u53EF\u9009 Harness \u6765\u81EA\u672C\u5730 Host\u3002\u8FD0\u884C\u72B6\u6001\u672A\u77E5\u65F6\uFF0C\u8BF7\u5148\u5728\u539F\u751F\u5BA2\u6237\u7AEF\u5173\u95ED\u8BE5\u4F1A\u8BDD\u518D\u5BFC\u5165\uFF0C\u907F\u514D\u540C\u65F6\u5199\u5165\u3002",
20204
+ sessionImportAvailabilityNote: "\u53EF\u9009 Harness \u6765\u81EA\u5F53\u524D Host\u3002\u8FD0\u884C\u72B6\u6001\u672A\u77E5\u65F6\uFF0C\u8BF7\u5148\u5728\u539F\u751F\u5BA2\u6237\u7AEF\u5173\u95ED\u8BE5\u4F1A\u8BDD\u518D\u5BFC\u5165\uFF0C\u907F\u514D\u540C\u65F6\u5199\u5165\u3002",
19251
20205
  sessionImportRefresh: "\u5237\u65B0",
19252
- sessionImportRefreshing: "\u6B63\u5728\u8BFB\u53D6\u672C\u5730\u4F1A\u8BDD\u2026\u2026",
19253
- sessionImportUnavailable: "\u672C\u5730 Harness \u6216\u5F53\u524D\u534F\u8BAE\u6682\u4E0D\u652F\u6301\u4F1A\u8BDD\u5BFC\u5165\uFF0C\u8BF7\u66F4\u65B0 Host/\u63D2\u4EF6\u6216\u9009\u62E9\u5176\u4ED6 Harness\u3002",
19254
- sessionImportEmpty: "\u6CA1\u6709\u53EF\u5BFC\u5165\u7684\u672C\u5730\u4F1A\u8BDD\u3002",
20206
+ sessionImportRefreshing: "\u6B63\u5728\u8BFB\u53D6\u5F53\u524D Host \u4E0A\u7684\u4F1A\u8BDD\u2026\u2026",
20207
+ sessionImportUnavailable: "\u8BE5 Harness \u6216\u5F53\u524D Host \u534F\u8BAE\u6682\u4E0D\u652F\u6301\u4F1A\u8BDD\u5BFC\u5165\uFF0C\u8BF7\u66F4\u65B0 Host/\u63D2\u4EF6\u6216\u9009\u62E9\u5176\u4ED6 Harness\u3002",
20208
+ sessionImportEmpty: "\u5F53\u524D Host \u4E0A\u6CA1\u6709\u53EF\u5BFC\u5165\u7684\u4F1A\u8BDD\u3002",
19255
20209
  sessionImportSearch: "\u641C\u7D22",
19256
20210
  sessionImportSearchPlaceholder: "\u641C\u7D22\u6807\u9898\u3001\u4F1A\u8BDD ID \u6216\u9879\u76EE\u8DEF\u5F84",
19257
20211
  sessionImportNoMatches: "\u6CA1\u6709\u5339\u914D\u7684\u4F1A\u8BDD\u3002",
@@ -19259,7 +20213,7 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19259
20213
  sessionImportPrevious: "\u4E0A\u4E00\u9875",
19260
20214
  sessionImportNext: "\u4E0B\u4E00\u9875",
19261
20215
  sessionImportPageSummary: "\u7B2C {page} / {pages} \u9875 \xB7 \u5171 {total} \u6761",
19262
- sessionImportLoadFailed: "\u65E0\u6CD5\u8BFB\u53D6\u672C\u5730\u4F1A\u8BDD\uFF0C\u8BF7\u68C0\u67E5\u76EE\u5F55\u8BBF\u95EE\u6743\u9650\u6216\u91CD\u590D\u7684\u4F1A\u8BDD ID \u540E\u91CD\u8BD5\u3002",
20216
+ sessionImportLoadFailed: "\u65E0\u6CD5\u8BFB\u53D6\u5F53\u524D Host \u4E0A\u7684\u4F1A\u8BDD\uFF0C\u8BF7\u68C0\u67E5\u76EE\u5F55\u8BBF\u95EE\u6743\u9650\u6216\u91CD\u590D\u7684\u4F1A\u8BDD ID \u540E\u91CD\u8BD5\u3002",
19263
20217
  sessionImportFailed: "\u65E0\u6CD5\u5BFC\u5165\u8BE5\u4F1A\u8BDD\u3002",
19264
20218
  sessionImportUntitled: "\u672A\u547D\u540D\u4F1A\u8BDD",
19265
20219
  sessionImportUpdatedAt: "\u66F4\u65B0\u65F6\u95F4",
@@ -19415,7 +20369,6 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19415
20369
  updateLatestVersion: "\u6700\u65B0\u7248\u672C",
19416
20370
  updateUpToDate: "\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C\u3002",
19417
20371
  updateAvailable: "\u6709\u65B0\u7248\u672C\u53EF\u7528\u3002",
19418
- updateWindowsManualRequired: "Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u66F4\u65B0\uFF0C\u8BF7\u5728\u4E0B\u65B9\u624B\u52A8\u66F4\u65B0\u3002",
19419
20372
  updateAndRestart: "\u66F4\u65B0",
19420
20373
  updateChecking: "\u6B63\u5728\u68C0\u67E5\u66F4\u65B0...",
19421
20374
  updateDownloading: "\u6B63\u5728\u4E0B\u8F7D\u66F4\u65B0...",
@@ -19430,8 +20383,7 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
19430
20383
  updateFailed: "\u66F4\u65B0\u5931\u8D25\u3002",
19431
20384
  updateRetry: "\u91CD\u8BD5",
19432
20385
  updateManualNpmDescription: "\u5982\u9700\u624B\u52A8\u66F4\u65B0\uFF0C\u8BF7\u5728\u7EC8\u7AEF\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u3002\u66F4\u65B0\u5B8C\u6210\u540E\uFF0C\u8BF7\u9000\u51FA Codex \u5E76\u901A\u8FC7 codexhost \u91CD\u65B0\u542F\u52A8\u3002",
19433
- updateWindowsNpmDescription: "Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u66F4\u65B0\u3002\u8BF7\u9000\u51FA codexhost\uFF0C\u5728\u7EC8\u7AEF\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u5B8C\u6210\u66F4\u65B0\u3002",
19434
- updateWindowsInstallerDescription: "Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u66F4\u65B0\u3002\u8BF7\u4E0B\u8F7D\u5E76\u8FD0\u884C\u9002\u7528\u4E8E\u5F53\u524D\u7CFB\u7EDF\u7684\u5B89\u88C5\u5305\u3002",
20386
+ updateWindowsInstallerDescription: "\u5982\u9700\u624B\u52A8\u66F4\u65B0\uFF0C\u8BF7\u4E0B\u8F7D\u5E76\u8FD0\u884C\u9002\u7528\u4E8E\u5F53\u524D\u7CFB\u7EDF\u7684\u5B89\u88C5\u5305\u3002",
19435
20387
  updateManualTitle: "\u624B\u52A8\u66F4\u65B0",
19436
20388
  updateManualFallbackDescription: "\u81EA\u52A8\u66F4\u65B0\u672A\u80FD\u5B8C\u6210\uFF0C\u8BF7\u6539\u7528\u4E0B\u5217\u547D\u4EE4\u5728\u7EC8\u7AEF\u624B\u52A8\u66F4\u65B0\u3002\u5B8C\u6210\u540E\u8BF7\u9000\u51FA Codex \u5E76\u901A\u8FC7 codexhost \u91CD\u65B0\u542F\u52A8\u3002",
19437
20389
  updateCopyCommand: "\u590D\u5236",
@@ -20087,6 +21039,8 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
20087
21039
  var STYLE_ATTRIBUTE = "data-codexhost-trigger-chip-style";
20088
21040
  var TRIGGER_CHIP_CLASS = "codexhost-trigger-chip";
20089
21041
  var TRIGGER_CHIP_ROOT_CLASS = "codexhost-trigger-chip-root";
21042
+ var COMPACT_COMPOSER_ATTRIBUTE = "data-codexhost-compact-composer";
21043
+ var COMPACT_COMPOSER_WIDTH = 420;
20090
21044
  var TRIGGER_CHIP_SQUEEZE_MIN_WIDTH = "48px";
20091
21045
  function rendererModelTriggerMaxWidth() {
20092
21046
  return "min(200px, 26vw)";
@@ -20116,6 +21070,23 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
20116
21070
  trigger.style.maxWidth = "100%";
20117
21071
  trigger.style.overflow = "hidden";
20118
21072
  }
21073
+ function observeRendererCompactComposer(composer) {
21074
+ const update = () => {
21075
+ const width = composer.getBoundingClientRect().width;
21076
+ if (width > 0) {
21077
+ composer.toggleAttribute(COMPACT_COMPOSER_ATTRIBUTE, width <= COMPACT_COMPOSER_WIDTH);
21078
+ }
21079
+ };
21080
+ update();
21081
+ if (typeof ResizeObserver === "undefined")
21082
+ return () => composer.removeAttribute(COMPACT_COMPOSER_ATTRIBUTE);
21083
+ const observer = new ResizeObserver(update);
21084
+ observer.observe(composer, { box: "border-box" });
21085
+ return () => {
21086
+ observer.disconnect();
21087
+ composer.removeAttribute(COMPACT_COMPOSER_ATTRIBUTE);
21088
+ };
21089
+ }
20119
21090
  function ensureRendererTriggerChipStyle(ownerDocument) {
20120
21091
  if (ownerDocument.querySelector(`style[${STYLE_ATTRIBUTE}]`)) return;
20121
21092
  const style = ownerDocument.createElement("style");
@@ -20154,10 +21125,55 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
20154
21125
  cursor: not-allowed;
20155
21126
  opacity: 0.4;
20156
21127
  }
21128
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-model-control] [data-codexhost-model-thinking] {
21129
+ display: none !important;
21130
+ }
21131
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-mode-control] {
21132
+ min-width: 30px !important;
21133
+ max-width: 30px !important;
21134
+ }
21135
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-mode-control] .${TRIGGER_CHIP_CLASS} {
21136
+ padding-inline: 6px !important;
21137
+ }
21138
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-label],
21139
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-chevron],
21140
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-credits-label],
21141
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-usage-label] {
21142
+ display: none !important;
21143
+ }
21144
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-mode-control]:has([data-codexhost-permission-lock]:not([hidden])) [data-codexhost-permission-shield],
21145
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-mode-control]:has([data-codexhost-permission-error]:not([hidden])) [data-codexhost-permission-shield] {
21146
+ display: none !important;
21147
+ }
21148
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-credits-control],
21149
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-usage-control] {
21150
+ min-width: 28px !important;
21151
+ max-width: 28px !important;
21152
+ }
21153
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-credits-control] .${TRIGGER_CHIP_CLASS},
21154
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-usage-control] .${TRIGGER_CHIP_CLASS} {
21155
+ padding-inline: 6px !important;
21156
+ }
21157
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-usage-icon] {
21158
+ display: inline-flex !important;
21159
+ }
21160
+ [${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-agent-control] {
21161
+ margin-inline: 0 !important;
21162
+ }
20157
21163
  `;
20158
21164
  (ownerDocument.head ?? ownerDocument.documentElement).append(style);
20159
21165
  }
20160
21166
 
21167
+ // ../../node_modules/lucide/dist/esm/icons/activity.mjs
21168
+ var Activity = [
21169
+ [
21170
+ "path",
21171
+ {
21172
+ d: "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"
21173
+ }
21174
+ ]
21175
+ ];
21176
+
20161
21177
  // src/renderer-usage-control.ts
20162
21178
  var ENGLISH_USAGE_MESSAGES = Object.freeze({
20163
21179
  usage: "Usage",
@@ -20511,13 +21527,19 @@ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages
20511
21527
  trigger.style.lineHeight = "16px";
20512
21528
  trigger.style.fontVariantNumeric = "tabular-nums";
20513
21529
  trigger.style.letterSpacing = "0";
21530
+ const icon2 = document.createElement("span");
21531
+ icon2.dataset.codexhostUsageIcon = "";
21532
+ icon2.style.display = "none";
21533
+ icon2.style.alignItems = "center";
21534
+ icon2.append(createElement(Activity, { width: 16, height: 16, "aria-hidden": "true" }));
20514
21535
  const label = document.createElement("span");
21536
+ label.dataset.codexhostUsageLabel = "";
20515
21537
  label.style.display = "inline-block";
20516
21538
  label.style.maxWidth = "100%";
20517
21539
  label.style.overflow = "hidden";
20518
21540
  label.style.textOverflow = "ellipsis";
20519
21541
  label.style.whiteSpace = "nowrap";
20520
- trigger.append(label);
21542
+ trigger.append(icon2, label);
20521
21543
  const popover = document.createElement("div");
20522
21544
  popover.id = `${composerId}-usage-popover`;
20523
21545
  popover.setAttribute("role", "dialog");
@@ -21383,6 +22405,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
21383
22405
  label.style.textOverflow = "ellipsis";
21384
22406
  label.style.whiteSpace = "nowrap";
21385
22407
  const thinkingLabel = document.createElement("span");
22408
+ thinkingLabel.dataset.codexhostModelThinking = "";
21386
22409
  thinkingLabel.style.color = "var(--color-text-tertiary, #8f8f8f)";
21387
22410
  thinkingLabel.style.flex = "0 1 auto";
21388
22411
  thinkingLabel.style.maxWidth = "72px";
@@ -21828,9 +22851,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
21828
22851
  syncModelSelectionNotice(control, view, locale);
21829
22852
  }
21830
22853
 
21831
- // ../../node_modules/lucide/dist/esm/icons/check.mjs
21832
- var Check = [["path", { d: "M20 6 9 17l-5-5" }]];
21833
-
21834
22854
  // ../../node_modules/lucide/dist/esm/icons/lock.mjs
21835
22855
  var Lock = [
21836
22856
  ["rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2" }],
@@ -21945,9 +22965,11 @@ Codex Fast mode prioritizes requests and may increase usage.`
21945
22965
  trigger.className = TRIGGER_CHIP_CLASS;
21946
22966
  applyRendererTriggerChipSqueezeTrigger(trigger);
21947
22967
  const shield = document.createElement("span");
22968
+ shield.dataset.codexhostPermissionShield = "";
21948
22969
  shield.className = "inline-flex shrink-0 items-center";
21949
22970
  shield.append(icon(Shield, 15));
21950
22971
  const label = document.createElement("span");
22972
+ label.dataset.codexhostPermissionLabel = "";
21951
22973
  label.className = "truncate";
21952
22974
  label.style.flex = "1 1 auto";
21953
22975
  label.style.minWidth = "0";
@@ -21955,15 +22977,18 @@ Codex Fast mode prioritizes requests and may increase usage.`
21955
22977
  label.style.textOverflow = "ellipsis";
21956
22978
  label.style.whiteSpace = "nowrap";
21957
22979
  const chevron = document.createElement("span");
22980
+ chevron.dataset.codexhostPermissionChevron = "";
21958
22981
  chevron.className = "inline-flex shrink-0 items-center";
21959
22982
  chevron.style.color = "var(--color-text-tertiary, #8f8f8f)";
21960
22983
  chevron.append(icon(ChevronDown, 14));
21961
22984
  const lockMark = document.createElement("span");
22985
+ lockMark.dataset.codexhostPermissionLock = "";
21962
22986
  lockMark.className = "inline-flex shrink-0 items-center";
21963
22987
  lockMark.style.color = "var(--color-text-tertiary, #8f8f8f)";
21964
22988
  lockMark.hidden = true;
21965
22989
  lockMark.append(icon(Lock, 14));
21966
22990
  const errorMark = document.createElement("span");
22991
+ errorMark.dataset.codexhostPermissionError = "";
21967
22992
  errorMark.className = "inline-flex shrink-0 items-center";
21968
22993
  errorMark.style.color = "var(--color-text-danger, #c2413b)";
21969
22994
  errorMark.hidden = true;
@@ -22670,6 +23695,21 @@ Codex Fast mode prioritizes requests and may increase usage.`
22670
23695
  };
22671
23696
  }
22672
23697
 
23698
+ // src/renderer-composer-request.ts
23699
+ var NATIVE_COMPOSER_REQUEST_ATTRIBUTES = [
23700
+ "data-codex-composer-request-navigation",
23701
+ "data-codex-composer-request"
23702
+ ];
23703
+ var NATIVE_REQUEST_SELECTOR = NATIVE_COMPOSER_REQUEST_ATTRIBUTES.map(
23704
+ (attribute) => `[${attribute}]`
23705
+ ).join(", ");
23706
+ function isNativeComposerRequest(element) {
23707
+ return element.closest(NATIVE_REQUEST_SELECTOR) !== null;
23708
+ }
23709
+ function hasNativeComposerRequest(composer) {
23710
+ return isNativeComposerRequest(composer) || composer.querySelector(NATIVE_REQUEST_SELECTOR) !== null;
23711
+ }
23712
+
22673
23713
  // src/renderer-harness-command-control.ts
22674
23714
  var CONTROL_ATTRIBUTE2 = "data-codexhost-harness-command-control";
22675
23715
  var SVG_NS2 = "http://www.w3.org/2000/svg";
@@ -22831,10 +23871,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
22831
23871
  const buttons = [...element.querySelectorAll("button")];
22832
23872
  return buttons.length > 0 && buttons.every((button2) => isComposerTrailingActionButton(button2));
22833
23873
  }
23874
+ function composerButtonsWithin(root) {
23875
+ return [...root.querySelectorAll("button")].filter(
23876
+ (button2) => !isNativeComposerRequest(button2)
23877
+ );
23878
+ }
22834
23879
  function sendButtonWithin(root) {
22835
- return [...root.querySelectorAll("button")].find(
22836
- (button2) => isComposerSubmitButton(button2)
22837
- ) ?? null;
23880
+ return composerButtonsWithin(root).find(isComposerSubmitButton) ?? null;
22838
23881
  }
22839
23882
  function leftmostTrailingSibling(container, before) {
22840
23883
  for (const child of container.children) {
@@ -22877,7 +23920,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
22877
23920
  }
22878
23921
  function composerForElement(element) {
22879
23922
  const composer = element.closest(CODEX_COMPOSER_SELECTOR);
22880
- return composer && !isOrbitComposer(composer) ? composer : null;
23923
+ return composer && !hasNativeComposerRequest(composer) && !isOrbitComposer(composer) ? composer : null;
22881
23924
  }
22882
23925
  function isRecord(value) {
22883
23926
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -23001,7 +24044,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23001
24044
  return root?.parentElement ? root : null;
23002
24045
  }
23003
24046
  function lastNativeButtonWithin(composer) {
23004
- const buttons = [...composer.querySelectorAll("button")];
24047
+ const buttons = composerButtonsWithin(composer);
23005
24048
  for (let index = buttons.length - 1; index >= 0; index -= 1) {
23006
24049
  const button2 = buttons[index];
23007
24050
  if (button2 && !isInsideOwnedRendererControl(button2, composer)) return button2;
@@ -23015,6 +24058,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23015
24058
  return false;
23016
24059
  }
23017
24060
  function refreshSendButton(control) {
24061
+ if (hasNativeComposerRequest(control.composer)) return null;
23018
24062
  const current = control.sendButton;
23019
24063
  if (current?.isConnected && control.composer.contains(current)) return current;
23020
24064
  const replacement = sendButtonWithin(control.composer) ?? (current && !isComposerSubmitButton(current) ? lastNativeButtonWithin(control.composer) : null);
@@ -23185,6 +24229,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23185
24229
  refreshTrailingClusterPlacement(control);
23186
24230
  refreshUsagePlacement(control);
23187
24231
  refreshCreditsPlacement(control);
24232
+ control.stopCompactLayout = observeRendererCompactComposer(composer);
23188
24233
  return control;
23189
24234
  }
23190
24235
  function nativeSendDisabled(button2, fallback) {
@@ -23256,6 +24301,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23256
24301
  return state.agent !== "codex" && adapterState === "ready" && !submissionBlocked;
23257
24302
  }
23258
24303
  function disposeComposerAgentControl(control) {
24304
+ control.stopCompactLayout?.();
23259
24305
  if (control.sendDisabledBeforeSwitch !== null) {
23260
24306
  control.sendButton.disabled = nativeSendDisabled(
23261
24307
  control.sendButton,
@@ -23483,13 +24529,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
23483
24529
  (name) => name.startsWith("__reactFiber$")
23484
24530
  );
23485
24531
  if (key) {
23486
- const ancestors = committedReactAncestors(
24532
+ const ancestors2 = committedReactAncestors(
23487
24533
  Object.getOwnPropertyDescriptor(element, key)?.value
23488
24534
  );
23489
24535
  const scopes = [];
23490
- ancestors.forEach(({ memoizedProps: props }, index) => {
24536
+ ancestors2.forEach(({ memoizedProps: props }, index) => {
23491
24537
  if (isRecord3(props) && "onLocalSubmitStart" in props && typeof props.submitDisabled === "boolean") {
23492
- scopes.push({ owner: ancestors[index], fibers: ancestors.slice(0, index + 1) });
24538
+ scopes.push({ owner: ancestors2[index], fibers: ancestors2.slice(0, index + 1) });
23493
24539
  }
23494
24540
  });
23495
24541
  const valid = scopes.filter((scope) => {
@@ -23840,38 +24886,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
23840
24886
  return task.result;
23841
24887
  }
23842
24888
 
23843
- // src/renderer-request-sender.ts
23844
- var RendererMethodUnavailableError = class extends Error {
23845
- constructor(method, cause) {
23846
- super(`${method} is unsupported on this Host connection`, { cause });
23847
- this.method = method;
23848
- this.name = "RendererMethodUnavailableError";
23849
- }
23850
- method;
23851
- code = -32601;
23852
- };
23853
- function isUnsupportedMethod(error51, method) {
23854
- if (typeof error51 !== "object" || error51 === null) return false;
23855
- const code = "code" in error51 ? error51.code : void 0;
23856
- const message2 = "message" in error51 ? error51.message : void 0;
23857
- return code === -32601 || code === -32600 && typeof message2 === "string" && message2.startsWith(`Invalid request: unknown variant \`${method}\``);
23858
- }
23859
- function createRendererRequestSender(send) {
23860
- const unsupported = /* @__PURE__ */ new Map();
23861
- return async (method, params, options) => {
23862
- const known = unsupported.get(method);
23863
- if (known) throw known;
23864
- try {
23865
- return await (options === void 0 ? send(method, params) : send(method, params, options));
23866
- } catch (error51) {
23867
- if (!method.startsWith("codexhost/") || !isUnsupportedMethod(error51, method)) throw error51;
23868
- const unavailable = new RendererMethodUnavailableError(method, error51);
23869
- unsupported.set(method, unavailable);
23870
- throw unavailable;
23871
- }
23872
- };
23873
- }
23874
-
23875
24889
  // src/renderer-native-thread.ts
23876
24890
  function isRecord4(value) {
23877
24891
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -24779,9 +25793,9 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24779
25793
  }
24780
25794
 
24781
25795
  // src/renderer-thread-reference-capability.ts
24782
- var record4 = (value) => typeof value === "object" && value !== null;
25796
+ var record6 = (value) => typeof value === "object" && value !== null;
24783
25797
  function restoreThreadReferenceCapability(client, manager, isCurrent) {
24784
- if (!record4(manager) || !record4(manager.storage)) return client;
25798
+ if (!record6(manager) || !record6(manager.storage)) return client;
24785
25799
  const storage = manager.storage;
24786
25800
  const read = storage.readValue;
24787
25801
  const write = storage.writeValue;
@@ -24816,14 +25830,14 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
24816
25830
  }
24817
25831
 
24818
25832
  // src/renderer-thread-reference-context.ts
24819
- var record5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
25833
+ var record7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24820
25834
  function createThreadReferenceContext(manager, hostId2, isCurrent) {
24821
25835
  const prepared = /* @__PURE__ */ new WeakMap();
24822
25836
  return (params) => {
24823
- if (hostId2 === "local" || !record5(manager) || typeof manager.getConversation !== "function" || !record5(params) || typeof params.threadId !== "string")
25837
+ if (hostId2 === "local" || !record7(manager) || typeof manager.getConversation !== "function" || !record7(params) || typeof params.threadId !== "string")
24824
25838
  return params;
24825
25839
  const conversation = manager.getConversation.call(manager, params.threadId);
24826
- if (!record5(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
25840
+ if (!record7(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
24827
25841
  return params;
24828
25842
  if (!isCurrent()) throw new Error("Thread reference connection is no longer available");
24829
25843
  const cached2 = prepared.get(params);
@@ -25073,6 +26087,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25073
26087
  var SIDEBAR_THREAD_ID_ATTRIBUTE = "data-app-action-sidebar-thread-id";
25074
26088
  var SIDEBAR_THREAD_HOST_ID_ATTRIBUTE = "data-app-action-sidebar-thread-host-id";
25075
26089
  var SIDEBAR_AGENT_ICON_ATTRIBUTE = "data-codexhost-sidebar-agent-icon";
26090
+ var SIDEBAR_AGENT_ICON_ROW_SELECTOR = `${SIDEBAR_THREAD_ROW_SELECTOR}, ${NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR}`;
25076
26091
  var OWNERSHIP_RETRY_DELAYS_MS = [100, 300, 800, 1500, 3e3];
25077
26092
  function isRecord10(value) {
25078
26093
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -25118,7 +26133,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25118
26133
  return candidates.size === 1 ? candidates.values().next().value ?? null : null;
25119
26134
  }
25120
26135
  function rendererAgentForThreadOwnership(ownership) {
25121
- if (ownership.owner === "codex") return null;
26136
+ if (ownership.owner === "codex") return "codex";
25122
26137
  return ownership.harnessId;
25123
26138
  }
25124
26139
  function sidebarAgentIconAnchor(titleTrigger, title) {
@@ -25136,22 +26151,30 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25136
26151
  this.element = element;
25137
26152
  }
25138
26153
  element;
26154
+ #scheduledThread;
25139
26155
  isConnected() {
25140
26156
  return this.element.isConnected;
25141
26157
  }
25142
26158
  hostId() {
25143
- return sidebarThreadAttributes(this.element)?.hostId ?? null;
26159
+ const attributes = sidebarThreadAttributes(this.element);
26160
+ this.#scheduledThread = attributes ? void 0 : readNativeScheduleSidebarThread(this.element);
26161
+ return attributes?.hostId ?? (this.#scheduledThread ? "local" : null);
25144
26162
  }
25145
26163
  threadId() {
25146
- return threadIdFromSidebarRowElement(this.element);
26164
+ const threadId = sidebarThreadAttributes(this.element) ? threadIdFromSidebarRowElement(this.element) : this.#scheduledThread !== void 0 ? this.#scheduledThread : readNativeScheduleSidebarThread(this.element);
26165
+ this.#scheduledThread = void 0;
26166
+ return threadId;
25147
26167
  }
25148
26168
  draftId() {
25149
26169
  return draftIdFromSidebarRowElement(this.element);
25150
26170
  }
25151
26171
  render(agent, plugin) {
25152
26172
  const presentation = JSON.stringify([agent, plugin?.name, plugin?.icon, plugin?.iconStyle]);
25153
- const titleTrigger = this.element.querySelector("[data-thread-title-trigger]");
25154
- const title = titleTrigger?.querySelector("[data-thread-title]");
26173
+ const scheduled = !this.element.hasAttribute(SIDEBAR_THREAD_ROW_ATTRIBUTE) && this.element.matches(NATIVE_SCHEDULE_SIDEBAR_ROW_SELECTOR);
26174
+ const titleTrigger = scheduled ? this.element : this.element.querySelector("[data-thread-title-trigger]");
26175
+ const title = scheduled ? [...this.element.querySelectorAll("[data-thread-title][id]")].find(
26176
+ (node) => node.id === this.element.getAttribute("aria-labelledby")
26177
+ ) : titleTrigger?.querySelector("[data-thread-title]");
25155
26178
  if (!titleTrigger || !title) {
25156
26179
  this.clear();
25157
26180
  return;
@@ -25200,7 +26223,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25200
26223
  row = new BrowserSidebarAgentIconRow(element);
25201
26224
  this.#rowsByElement.set(element, row);
25202
26225
  }
25203
- if (element.isConnected && element.matches(SIDEBAR_THREAD_ROW_SELECTOR))
26226
+ if (element.isConnected && element.matches(SIDEBAR_AGENT_ICON_ROW_SELECTOR))
25204
26227
  this.#trackedRows.add(row);
25205
26228
  else this.#trackedRows.delete(row);
25206
26229
  return row;
@@ -25209,7 +26232,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25209
26232
  for (const row of this.#trackedRows) {
25210
26233
  if (!row.isConnected()) this.#trackedRows.delete(row);
25211
26234
  }
25212
- return [...this.root.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR)].map(
26235
+ return [...this.root.querySelectorAll(SIDEBAR_AGENT_ICON_ROW_SELECTOR)].map(
25213
26236
  (element) => this.#row(element)
25214
26237
  );
25215
26238
  }
@@ -25218,13 +26241,14 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25218
26241
  const changed = /* @__PURE__ */ new Set();
25219
26242
  const collect = (node) => {
25220
26243
  if (!(node instanceof Element)) return;
25221
- if (node.matches(SIDEBAR_THREAD_ROW_SELECTOR)) changed.add(this.#row(node));
25222
- for (const element of node.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR))
26244
+ if (node.matches(SIDEBAR_AGENT_ICON_ROW_SELECTOR))
26245
+ changed.add(this.#row(node));
26246
+ for (const element of node.querySelectorAll(SIDEBAR_AGENT_ICON_ROW_SELECTOR))
25223
26247
  changed.add(this.#row(element));
25224
26248
  };
25225
26249
  for (const mutation of mutations) {
25226
26250
  const target = mutation.target instanceof Element ? mutation.target : mutation.target.parentElement;
25227
- const row = target?.closest(SIDEBAR_THREAD_ROW_SELECTOR);
26251
+ const row = target?.closest(SIDEBAR_AGENT_ICON_ROW_SELECTOR);
25228
26252
  if (row) changed.add(this.#row(row));
25229
26253
  else if (target && this.#rowsByElement.has(target))
25230
26254
  changed.add(this.#row(target));
@@ -25238,7 +26262,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25238
26262
  attributeFilter: [
25239
26263
  SIDEBAR_THREAD_ROW_ATTRIBUTE,
25240
26264
  SIDEBAR_THREAD_ID_ATTRIBUTE,
25241
- SIDEBAR_THREAD_HOST_ID_ATTRIBUTE
26265
+ SIDEBAR_THREAD_HOST_ID_ATTRIBUTE,
26266
+ "data-sidebar-cycle-item",
26267
+ "aria-labelledby",
26268
+ "role"
25242
26269
  ],
25243
26270
  childList: true,
25244
26271
  subtree: true
@@ -25308,7 +26335,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25308
26335
  ownershipRetryTimers.delete(key);
25309
26336
  if (disposed) return;
25310
26337
  failed.delete(key);
25311
- ownershipByThread.delete(key);
26338
+ const cached2 = ownershipByThread.get(key);
26339
+ if (cached2) cached2.stale = true;
25312
26340
  scheduleScan(rowsByThread.get(key) ?? []);
25313
26341
  }, delay);
25314
26342
  ownershipRetryTimers.set(key, timer);
@@ -25321,7 +26349,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25321
26349
  if (disposed) return;
25322
26350
  for (const ownership of threads) {
25323
26351
  const key = ownershipKey(hostId2, ownership.threadId);
25324
- ownershipByThread.set(key, rendererAgentForThreadOwnership(ownership));
26352
+ ownershipByThread.set(key, {
26353
+ agent: rendererAgentForThreadOwnership(ownership),
26354
+ stale: false
26355
+ });
25325
26356
  failed.delete(key);
25326
26357
  if (ownership.owner === "codex") {
25327
26358
  provisionalCodex.add(key);
@@ -25354,6 +26385,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25354
26385
  const unresolvedByHost = /* @__PURE__ */ new Map();
25355
26386
  const pluginsByHost = /* @__PURE__ */ new Map();
25356
26387
  const getPlugin = (hostId2, agent) => {
26388
+ if (agent === "codex") return void 0;
25357
26389
  if (!pluginsByHost.has(hostId2)) pluginsByHost.set(hostId2, options.getPlugins?.(hostId2));
25358
26390
  return pluginsByHost.get(hostId2)?.find(({ id }) => id === agent);
25359
26391
  };
@@ -25379,11 +26411,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25379
26411
  if (localAgent !== null && localAgent !== void 0) {
25380
26412
  if (threadId.success) {
25381
26413
  const key2 = ownershipKey(hostId2, threadId.data);
25382
- ownershipByThread.set(key2, localAgent === "codex" ? null : localAgent);
26414
+ ownershipByThread.set(key2, { agent: localAgent, stale: false });
25383
26415
  clearOwnershipRetry(key2);
25384
26416
  }
25385
- if (localAgent === "codex") row.clear();
25386
- else row.render(localAgent, getPlugin(hostId2, localAgent));
26417
+ row.render(localAgent, getPlugin(hostId2, localAgent));
25387
26418
  continue;
25388
26419
  }
25389
26420
  if (!threadId.success) {
@@ -25391,13 +26422,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25391
26422
  continue;
25392
26423
  }
25393
26424
  const key = ownershipKey(hostId2, threadId.data);
25394
- if (ownershipByThread.has(key)) {
25395
- const agent = ownershipByThread.get(key);
25396
- if (agent) row.render(agent, getPlugin(hostId2, agent));
25397
- else row.clear();
25398
- continue;
25399
- }
25400
- row.clear();
26425
+ const cached2 = ownershipByThread.get(key);
26426
+ if (cached2) {
26427
+ row.render(cached2.agent, getPlugin(hostId2, cached2.agent));
26428
+ if (!cached2.stale) continue;
26429
+ } else row.clear();
25401
26430
  if (!pending.has(key) && !failed.has(key)) {
25402
26431
  let unresolved = unresolvedByHost.get(hostId2);
25403
26432
  if (!unresolved) {
@@ -25437,7 +26466,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25437
26466
  for (const timer of ownershipRetryTimers.values()) clearTimeout(timer);
25438
26467
  ownershipRetryTimers.clear();
25439
26468
  ownershipRetryAttempts.clear();
25440
- for (const key of provisionalCodex) ownershipByThread.delete(key);
26469
+ for (const key of provisionalCodex) {
26470
+ const cached2 = ownershipByThread.get(key);
26471
+ if (cached2) cached2.stale = true;
26472
+ }
25441
26473
  provisionalCodex.clear();
25442
26474
  scheduleScan(dom.rows());
25443
26475
  },
@@ -25536,16 +26568,16 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25536
26568
  return isRecord11(value) ? value : null;
25537
26569
  }
25538
26570
  function directForkAncestors(first) {
25539
- const ancestors = [];
26571
+ const ancestors2 = [];
25540
26572
  const seen = /* @__PURE__ */ new Set();
25541
26573
  let fiber = first;
25542
- while (fiber && ancestors.length < FAST_FORK_OWNER_DEPTH) {
26574
+ while (fiber && ancestors2.length < FAST_FORK_OWNER_DEPTH) {
25543
26575
  if (seen.has(fiber)) return [];
25544
26576
  seen.add(fiber);
25545
- ancestors.push(fiber);
26577
+ ancestors2.push(fiber);
25546
26578
  fiber = isRecord11(fiber.return) ? fiber.return : null;
25547
26579
  }
25548
- return ancestors;
26580
+ return ancestors2;
25549
26581
  }
25550
26582
  function ownsOtherCallback(fiber, props) {
25551
26583
  if (typeof fiber.type === "string") return false;
@@ -25553,13 +26585,13 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
25553
26585
  (name) => /^on[A-Z]/.test(name) && name !== "onClick" && name !== "onFork" && typeof props[name] === "function"
25554
26586
  );
25555
26587
  }
25556
- function forkTargetFromAncestors(button2, threadId, turnId, ancestors) {
26588
+ function forkTargetFromAncestors(button2, threadId, turnId, ancestors2) {
25557
26589
  const conversationIds = /* @__PURE__ */ new Set();
25558
26590
  const turnIds = /* @__PURE__ */ new Set();
25559
26591
  const hostIds = /* @__PURE__ */ new Set();
25560
26592
  const projectlessStates = /* @__PURE__ */ new Set();
25561
26593
  let hasForkCallback = false;
25562
- for (const fiber of ancestors) {
26594
+ for (const fiber of ancestors2) {
25563
26595
  const props = fiber.memoizedProps;
25564
26596
  if (!isRecord11(props)) continue;
25565
26597
  if (!hasForkCallback && typeof props.onFork !== "function" && ownsOtherCallback(fiber, props)) {
@@ -26096,6 +27128,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26096
27128
  }
26097
27129
  });
26098
27130
  const selectedPolicies = /* @__PURE__ */ new Map();
27131
+ const draftModels = createScopedDraftModelWriter();
26099
27132
  const handleRoutingPolicyChange = () => {
26100
27133
  currentRequestRoute();
26101
27134
  };
@@ -26116,7 +27149,16 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26116
27149
  const route = window.__codexhostHostRoutingV1?.forComposer(composer);
26117
27150
  if (!route) return false;
26118
27151
  try {
26119
- if (route.policy.select(carrier ?? null)) {
27152
+ const target = composer ? findComposerModelTarget(composer) : null;
27153
+ if (target?.[0] === "conversation") return true;
27154
+ if (target?.[0] !== "default" || typeof target[1] !== "string" || !composer)
27155
+ return agent === "codex";
27156
+ const binding = findScopedDraftModelBinding(composer, target[1]);
27157
+ const draftKey = target[1];
27158
+ if (!binding || !route.policy.scopedCreation)
27159
+ return agent === "codex" && !draftModels.has(draftKey);
27160
+ draftModels.apply(draftKey, binding, carrier ?? null);
27161
+ if (route.policy.select(carrier ?? null, draftKey, binding.creationModes)) {
26120
27162
  modelUpdates += 1;
26121
27163
  liveStatus.modelUpdates = modelUpdates;
26122
27164
  }
@@ -26134,6 +27176,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26134
27176
  dispose() {
26135
27177
  if (disposed) return;
26136
27178
  disposed = true;
27179
+ draftModels.dispose();
26137
27180
  window.removeEventListener(
26138
27181
  "codexhost:draft-prewarm-policy-changed",
26139
27182
  handleRoutingPolicyChange
@@ -26342,14 +27385,17 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26342
27385
  }
26343
27386
 
26344
27387
  // src/codex-locale-adapter.ts
26345
- var GET_LOCALE_OVERRIDE_URL = "vscode://codex/get-setting";
26346
- var GET_LOCALE_INFO_URL = "vscode://codex/locale-info";
26347
27388
  var DEFAULT_LOCALE_REQUEST_TIMEOUT_MS = 750;
26348
27389
  function isNativeLocaleServices(value) {
26349
27390
  if (!isRecord14(value) || !Object.hasOwn(value, "appInfo")) return false;
26350
27391
  const appInfo = value.appInfo;
26351
27392
  return appInfo != null && typeof appInfo.getLocaleInfo === "function";
26352
27393
  }
27394
+ function isNativeSettingsServices(value) {
27395
+ if (!isRecord14(value) || !Object.hasOwn(value, "settings")) return false;
27396
+ const settings = value.settings;
27397
+ return typeof settings?.read === "function" && typeof settings?.write === "function";
27398
+ }
26353
27399
  function isRecord14(value) {
26354
27400
  return typeof value === "object" && value !== null && !Array.isArray(value);
26355
27401
  }
@@ -26371,19 +27417,19 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26371
27417
  function abortError2() {
26372
27418
  return new DOMException("The operation was aborted", "AbortError");
26373
27419
  }
26374
- function parseLocaleOverride(value) {
26375
- if (!isRecord14(value) || !("value" in value)) {
26376
- throw new Error("Codex locale override response is malformed");
27420
+ function parseLocaleOverride(response) {
27421
+ if (!isRecord14(response) || !Object.hasOwn(response, "effective")) {
27422
+ throw new Error("Codex native locale override response is malformed");
26377
27423
  }
26378
- if (value.value === null) return { value: null };
26379
- const locale = canonicalLocale(value.value);
27424
+ if (response.effective === null) return null;
27425
+ const locale = canonicalLocale(response.effective);
26380
27426
  if (!locale) throw new Error("Codex locale override is invalid");
26381
- return { value: locale };
27427
+ return locale;
26382
27428
  }
26383
- function optionalLocale(value, field) {
27429
+ function optionalLocale(value, field2) {
26384
27430
  if (value === void 0 || value === null) return void 0;
26385
27431
  const locale = canonicalLocale(value);
26386
- if (!locale) throw new Error(`Codex ${field} is invalid`);
27432
+ if (!locale) throw new Error(`Codex ${field2} is invalid`);
26387
27433
  return locale;
26388
27434
  }
26389
27435
  function parseLocaleInfo(value) {
@@ -26393,95 +27439,39 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26393
27439
  systemLocale: optionalLocale(value.systemLocale, "system locale")
26394
27440
  };
26395
27441
  }
26396
- function sendFixedLocaleRequest(request, ownerWindow, signal, timeoutMs) {
26397
- const bridge = ownerWindow.electronBridge;
26398
- if (request.kind !== "locale-info" && typeof bridge?.sendMessageFromView !== "function") {
26399
- return Promise.reject(new Error("Codex locale bridge is unavailable"));
26400
- }
27442
+ function requestNativeLocale(ownerWindow, signal, timeoutMs, matchesServices, invoke) {
26401
27443
  if (signal?.aborted) return Promise.reject(abortError2());
26402
- const requestId = ownerWindow.crypto.randomUUID();
26403
27444
  return new Promise((resolve, reject) => {
26404
27445
  let settled = false;
26405
- const cleanup = () => {
26406
- ownerWindow.clearTimeout(timer);
26407
- ownerWindow.removeEventListener("message", onMessage);
26408
- signal?.removeEventListener("abort", onAbort);
26409
- };
27446
+ let nativeRequest;
26410
27447
  const settle = (operation) => {
26411
27448
  if (settled) return;
26412
27449
  settled = true;
26413
- cleanup();
26414
- operation();
26415
- };
26416
- const onAbort = () => settle(() => reject(abortError2()));
26417
- const onMessage = (event) => {
26418
- const message3 = event.data;
26419
- if (!isRecord14(message3) || message3.type !== "fetch-response") return;
26420
- if (message3.requestId !== requestId) return;
26421
- if (message3.responseType !== "success" || typeof message3.status !== "number" || message3.status < 200 || message3.status >= 300 || typeof message3.bodyJsonString !== "string") {
26422
- settle(() => reject(new Error("Codex locale request failed")));
26423
- return;
26424
- }
27450
+ ownerWindow.clearTimeout(timer);
27451
+ signal?.removeEventListener("abort", onAbort);
26425
27452
  try {
26426
- const body = JSON.parse(message3.bodyJsonString);
26427
- settle(() => resolve(body));
26428
- } catch {
26429
- settle(() => reject(new Error("Codex locale response is not valid JSON")));
27453
+ nativeRequest?.[Symbol.dispose]?.();
27454
+ operation();
27455
+ } catch (error51) {
27456
+ reject(error51);
26430
27457
  }
26431
27458
  };
27459
+ const onAbort = () => settle(() => reject(abortError2()));
26432
27460
  const timer = ownerWindow.setTimeout(
26433
27461
  () => settle(() => reject(new Error("Codex locale request timed out"))),
26434
27462
  timeoutMs
26435
27463
  );
26436
- ownerWindow.addEventListener("message", onMessage);
26437
27464
  signal?.addEventListener("abort", onAbort, { once: true });
26438
- const message2 = {
26439
- type: "fetch",
26440
- requestId,
26441
- method: "POST",
26442
- url: request.url,
26443
- ...request.body === void 0 ? {} : { body: request.body },
26444
- reportUploadProgress: false
26445
- };
26446
27465
  void (async () => {
26447
- if (request.kind === "locale-info") {
26448
- const native = await loadCodexNativeServices(ownerWindow, isNativeLocaleServices);
26449
- if (settled) return;
26450
- if (native) {
26451
- const response = await native.appInfo.getLocaleInfo();
26452
- settle(() => resolve(response));
26453
- return;
26454
- }
26455
- }
26456
- if (typeof bridge?.sendMessageFromView !== "function") {
26457
- throw new Error("Codex locale bridge is unavailable");
26458
- }
26459
- await bridge.sendMessageFromView(message2);
27466
+ const native = await loadCodexNativeServices(ownerWindow, matchesServices);
27467
+ if (settled) return;
27468
+ if (!native) throw new Error("Codex native locale services are unavailable");
27469
+ nativeRequest = invoke(native);
27470
+ const response = await nativeRequest;
27471
+ settle(() => resolve(response));
26460
27472
  })().catch((error51) => settle(() => reject(error51)));
26461
27473
  });
26462
27474
  }
26463
- async function readLocaleOverride(ownerWindow, signal, timeoutMs) {
26464
- const response = await sendFixedLocaleRequest(
26465
- {
26466
- kind: "locale-override",
26467
- url: GET_LOCALE_OVERRIDE_URL,
26468
- body: JSON.stringify({ key: "localeOverride" })
26469
- },
26470
- ownerWindow,
26471
- signal,
26472
- timeoutMs
26473
- );
26474
- return parseLocaleOverride(response);
26475
- }
26476
- async function readLocaleInfo(ownerWindow, signal, timeoutMs) {
26477
- const response = await sendFixedLocaleRequest(
26478
- { kind: "locale-info", url: GET_LOCALE_INFO_URL },
26479
- ownerWindow,
26480
- signal,
26481
- timeoutMs
26482
- );
26483
- return parseLocaleInfo(response);
26484
- }
26485
27475
  async function readCodexLocaleSettings(options = {}) {
26486
27476
  const ownerWindow = options.ownerWindow ?? window;
26487
27477
  const timeoutMs = options.timeoutMs ?? DEFAULT_LOCALE_REQUEST_TIMEOUT_MS;
@@ -26490,13 +27480,25 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26490
27480
  }
26491
27481
  if (options.signal?.aborted) throw abortError2();
26492
27482
  const [overrideResult, localeInfoResult] = await Promise.allSettled([
26493
- readLocaleOverride(ownerWindow, options.signal, timeoutMs),
26494
- readLocaleInfo(ownerWindow, options.signal, timeoutMs)
27483
+ requestNativeLocale(
27484
+ ownerWindow,
27485
+ options.signal,
27486
+ timeoutMs,
27487
+ isNativeSettingsServices,
27488
+ (native) => native.settings.read("localeOverride")
27489
+ ).then(parseLocaleOverride),
27490
+ requestNativeLocale(
27491
+ ownerWindow,
27492
+ options.signal,
27493
+ timeoutMs,
27494
+ isNativeLocaleServices,
27495
+ (native) => native.appInfo.getLocaleInfo()
27496
+ ).then(parseLocaleInfo)
26495
27497
  ]);
26496
27498
  if (options.signal?.aborted) throw abortError2();
26497
27499
  const navigatorLocale = firstNavigatorLocale(ownerWindow);
26498
27500
  const overrideKnown = overrideResult.status === "fulfilled";
26499
- const localeOverride = overrideKnown ? overrideResult.value.value : void 0;
27501
+ const localeOverride = overrideKnown ? overrideResult.value : void 0;
26500
27502
  const localeInfo = localeInfoResult.status === "fulfilled" ? localeInfoResult.value : { ideLocale: void 0, systemLocale: void 0 };
26501
27503
  if (typeof localeOverride === "string") {
26502
27504
  return Object.freeze({
@@ -26610,6 +27612,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26610
27612
  cachedInputTokens: 0,
26611
27613
  cacheWriteInputTokens: 0,
26612
27614
  cacheKnownInputTokens: 0,
27615
+ cacheHitCachedInputTokens: 0,
27616
+ cacheHitInputTokens: 0,
26613
27617
  outputTokens: 0,
26614
27618
  reasoningOutputTokens: 0,
26615
27619
  costUsd: 0,
@@ -26623,6 +27627,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26623
27627
  target.cachedInputTokens += source.cachedInputTokens;
26624
27628
  target.cacheWriteInputTokens += source.cacheWriteInputTokens;
26625
27629
  target.cacheKnownInputTokens += source.cacheKnownInputTokens;
27630
+ target.cacheHitCachedInputTokens += source.cacheHitCachedInputTokens;
27631
+ target.cacheHitInputTokens += source.cacheHitInputTokens;
26626
27632
  target.outputTokens += source.outputTokens;
26627
27633
  target.reasoningOutputTokens += source.reasoningOutputTokens;
26628
27634
  target.costUsd += source.costUsd;
@@ -26677,7 +27683,9 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26677
27683
  };
26678
27684
  }
26679
27685
  function cacheHitRate(totals2) {
26680
- return totals2.cacheKnownInputTokens > 0 ? formatRendererCacheHitRate(totals2.cachedInputTokens / totals2.cacheKnownInputTokens * 100) : "\u2014";
27686
+ return totals2.cacheHitInputTokens > 0 ? formatRendererCacheHitRate(
27687
+ totals2.cacheHitCachedInputTokens / totals2.cacheHitInputTokens * 100
27688
+ ) : "\u2014";
26681
27689
  }
26682
27690
  function formatMeasure(measure, value, locale = "en") {
26683
27691
  return measure === "cost" ? money(value) : count2(value, locale);
@@ -26841,7 +27849,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26841
27849
  var DECIMAL = /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/iu;
26842
27850
  function modelPriceDraft(key, price) {
26843
27851
  const prices = Object.fromEntries(
26844
- MODEL_PRICE_FIELDS.map((field) => [field, price?.[field]?.toString() ?? ""])
27852
+ MODEL_PRICE_FIELDS.map((field2) => [field2, price?.[field2]?.toString() ?? ""])
26845
27853
  );
26846
27854
  return { model: key, prices };
26847
27855
  }
@@ -26852,18 +27860,18 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26852
27860
  return { error: { kind: "duplicate", key } };
26853
27861
  }
26854
27862
  const price = {};
26855
- for (const field of MODEL_PRICE_FIELDS) {
26856
- const text = draft.prices[field].trim();
27863
+ for (const field2 of MODEL_PRICE_FIELDS) {
27864
+ const text = draft.prices[field2].trim();
26857
27865
  if (text === "") {
26858
- if (field === "input" || field === "output")
26859
- return { error: { kind: "priceRequired", field } };
27866
+ if (field2 === "input" || field2 === "output")
27867
+ return { error: { kind: "priceRequired", field: field2 } };
26860
27868
  continue;
26861
27869
  }
26862
27870
  const value = Number(text);
26863
27871
  if (!DECIMAL.test(text) || !Number.isFinite(value)) {
26864
- return { error: { kind: "priceInvalid", field } };
27872
+ return { error: { kind: "priceInvalid", field: field2 } };
26865
27873
  }
26866
- price[field] = value;
27874
+ price[field2] = value;
26867
27875
  }
26868
27876
  return {
26869
27877
  change: {
@@ -26883,7 +27891,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26883
27891
  }
26884
27892
  function formatPrice(messages, price) {
26885
27893
  return MODEL_PRICE_FIELDS.map(
26886
- (field) => `${messages.fields[field]} ${price[field] ?? messages.unset}`
27894
+ (field2) => `${messages.fields[field2]} ${price[field2] ?? messages.unset}`
26887
27895
  ).join(" \xB7 ");
26888
27896
  }
26889
27897
  function draftErrorText(messages, error51) {
@@ -26951,18 +27959,18 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26951
27959
  function renderEditor(modelId, view, isCurrent) {
26952
27960
  const existing = view.entries.find((entry) => entry.key === modelId);
26953
27961
  const draft = modelPriceDraft(modelId, existing?.price ?? null);
26954
- const field = (label, value, placeholder = "") => h(document2, "input", {
27962
+ const field2 = (label, value, placeholder = "") => h(document2, "input", {
26955
27963
  type: "text",
26956
27964
  className: "console-input",
26957
27965
  value,
26958
27966
  placeholder,
26959
27967
  "aria-label": label
26960
27968
  });
26961
- const model2 = field(messages.model, modelId);
27969
+ const model2 = field2(messages.model, modelId);
26962
27970
  model2.readOnly = true;
26963
27971
  const prices = Object.fromEntries(
26964
27972
  MODEL_PRICE_FIELDS.map((name) => {
26965
- const input = field(
27973
+ const input = field2(
26966
27974
  messages.fields[name],
26967
27975
  draft.prices[name],
26968
27976
  name === "input" || name === "output" ? messages.required : messages.notSet
@@ -27774,8 +28782,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
27774
28782
  for (const cell of options.cells) {
27775
28783
  const key = options.singleDay ? cell.hour : cell.weekday * 24 + cell.hour;
27776
28784
  const totals2 = byHour.get(key) ?? emptyTotals();
27777
- for (const field of Object.keys(totals2))
27778
- totals2[field] += cell.totals[field];
28785
+ for (const field2 of Object.keys(totals2))
28786
+ totals2[field2] += cell.totals[field2];
27779
28787
  byHour.set(key, totals2);
27780
28788
  }
27781
28789
  const max = Math.max(0, ...[...byHour.values()].map((totals2) => measured(totals2, measure)));
@@ -28138,8 +29146,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
28138
29146
  save();
28139
29147
  load();
28140
29148
  }
28141
- function toggleFilter(field, key) {
28142
- view[field] = view[field] === key ? "" : key;
29149
+ function toggleFilter(field2, key) {
29150
+ view[field2] = view[field2] === key ? "" : key;
28143
29151
  changed();
28144
29152
  }
28145
29153
  function selectDate(next) {
@@ -28544,7 +29552,7 @@ ${messages.creditsCoverage}: ${value.reportedRequests} / ${row.requests}` : void
28544
29552
  {
28545
29553
  key: "hit",
28546
29554
  label: messages.cacheHit,
28547
- sort: (row) => row.cacheKnownInputTokens > 0 ? row.cachedInputTokens / row.cacheKnownInputTokens : -1,
29555
+ sort: (row) => row.cacheHitInputTokens > 0 ? row.cacheHitCachedInputTokens / row.cacheHitInputTokens : -1,
28548
29556
  cell: (row) => cacheHitRate(row)
28549
29557
  },
28550
29558
  {
@@ -28555,8 +29563,8 @@ ${messages.creditsCoverage}: ${value.reportedRequests} / ${row.requests}` : void
28555
29563
  }
28556
29564
  ];
28557
29565
  }
28558
- function rowFilter(field, key, label, detail) {
28559
- const selected = view[field] === key;
29566
+ function rowFilter(field2, key, label, detail) {
29567
+ const selected = view[field2] === key;
28560
29568
  const button2 = focusKey(
28561
29569
  h(
28562
29570
  document2,
@@ -28570,9 +29578,9 @@ ${detail}` : ""}`
28570
29578
  },
28571
29579
  label
28572
29580
  ),
28573
- `${field}:row:${key}`
29581
+ `${field2}:row:${key}`
28574
29582
  );
28575
- button2.addEventListener("click", () => toggleFilter(field, key));
29583
+ button2.addEventListener("click", () => toggleFilter(field2, key));
28576
29584
  return button2;
28577
29585
  }
28578
29586
  function panel(title, content, extra = null, wide = false) {
@@ -29771,8 +30779,8 @@ ${detail}` : ""}`
29771
30779
  return input;
29772
30780
  }
29773
30781
  function createNumberField(document2, input) {
29774
- const field = document2.createElement("div");
29775
- field.className = "flex h-8 shrink-0 items-center gap-1.5 rounded-md border border-settings-border bg-settings-surface px-2.5 transition-colors focus-within:border-settings-focus data-[invalid=true]:border-settings-danger";
30782
+ const field2 = document2.createElement("div");
30783
+ field2.className = "flex h-8 shrink-0 items-center gap-1.5 rounded-md border border-settings-border bg-settings-surface px-2.5 transition-colors focus-within:border-settings-focus data-[invalid=true]:border-settings-danger";
29776
30784
  const control = document2.createElement("input");
29777
30785
  control.type = "number";
29778
30786
  control.id = input.id;
@@ -29785,8 +30793,8 @@ ${detail}` : ""}`
29785
30793
  unit.className = "text-xs text-settings-muted";
29786
30794
  unit.setAttribute("aria-hidden", "true");
29787
30795
  unit.textContent = input.unit;
29788
- field.append(control, unit);
29789
- return { field, control };
30796
+ field2.append(control, unit);
30797
+ return { field: field2, control };
29790
30798
  }
29791
30799
 
29792
30800
  // src/settings/remote-connections-dialogs.ts
@@ -29870,7 +30878,7 @@ ${detail}` : ""}`
29870
30878
  );
29871
30879
  if (!dialog) return;
29872
30880
  const document2 = options.container.ownerDocument;
29873
- const field = (label, value, placeholder = "", hint = "") => {
30881
+ const field2 = (label, value, placeholder = "", hint = "") => {
29874
30882
  const wrapper = remoteElement(document2, "div", "settings-credential-dialog__field");
29875
30883
  const input = remoteElement(document2, "input");
29876
30884
  input.id = preferenceId("remote-field");
@@ -29890,13 +30898,13 @@ ${detail}` : ""}`
29890
30898
  dialog.body.append(wrapper);
29891
30899
  return input;
29892
30900
  };
29893
- const name = field(t("\u540D\u79F0", "Name"), previous?.displayName ?? "");
30901
+ const name = field2(t("\u540D\u79F0", "Name"), previous?.displayName ?? "");
29894
30902
  name.required = true;
29895
30903
  const addressHint = t(
29896
30904
  "user@hostname\uFF0C\u6216 ~/.ssh/config \u4E2D\u7684\u4E3B\u673A\u522B\u540D",
29897
30905
  "user@hostname, or a host alias from ~/.ssh/config"
29898
30906
  );
29899
- const hostname3 = field(
30907
+ const hostname3 = field2(
29900
30908
  t("SSH \u5730\u5740", "SSH address"),
29901
30909
  previous?.sshHost ?? "",
29902
30910
  "user@hostname",
@@ -29905,7 +30913,7 @@ ${detail}` : ""}`
29905
30913
  hostname3.required = true;
29906
30914
  hostname3.pattern = "[^\\s\\-]\\S*";
29907
30915
  hostname3.title = addressHint;
29908
- const port = field(
30916
+ const port = field2(
29909
30917
  t("\u7AEF\u53E3\uFF08\u53EF\u9009\uFF09", "Port (optional)"),
29910
30918
  previous?.sshPort?.toString() ?? "",
29911
30919
  "22"
@@ -29914,7 +30922,7 @@ ${detail}` : ""}`
29914
30922
  port.min = "1";
29915
30923
  port.max = "65535";
29916
30924
  port.step = "1";
29917
- const identity = field(
30925
+ const identity = field2(
29918
30926
  t("\u79C1\u94A5\u8DEF\u5F84\uFF08\u53EF\u9009\uFF09", "Identity file (optional)"),
29919
30927
  previous?.identity ?? "",
29920
30928
  "~/.ssh/id_ed25519"
@@ -30831,6 +31839,50 @@ ${detail}` : ""}`
30831
31839
  };
30832
31840
  setRefreshLabel(false);
30833
31841
  header.append(heading, refresh);
31842
+ let selectedHostId;
31843
+ let availableHostIds = [];
31844
+ let displayedHostId = "";
31845
+ let hostsLocked = false;
31846
+ const hostButtons = [];
31847
+ const hostLabel = document2.createElement("div");
31848
+ hostLabel.className = "settings-session-import-host";
31849
+ const hostCaption = document2.createElement("span");
31850
+ hostCaption.textContent = "Host";
31851
+ const hostOptions = document2.createElement("div");
31852
+ hostOptions.className = "settings-connection-host-tabs";
31853
+ hostOptions.setAttribute("role", "group");
31854
+ hostOptions.setAttribute("aria-label", "Host");
31855
+ hostLabel.append(hostCaption, hostOptions);
31856
+ const lockHosts = (locked) => {
31857
+ hostsLocked = locked;
31858
+ for (const button2 of hostButtons) button2.disabled = locked;
31859
+ };
31860
+ const renderHosts = (client) => {
31861
+ const current = selectedHostId ?? (client ? client.hostId ?? "local" : "");
31862
+ availableHostIds = [
31863
+ .../* @__PURE__ */ new Set([
31864
+ ...getDiagnostics()?.snapshot().hosts.map(({ hostId: hostId2 }) => hostId2) ?? [],
31865
+ ...current ? [current] : []
31866
+ ])
31867
+ ];
31868
+ displayedHostId = current;
31869
+ const scrollLeft = hostOptions.scrollLeft;
31870
+ hostOptions.replaceChildren();
31871
+ hostButtons.length = 0;
31872
+ for (const hostId2 of availableHostIds) {
31873
+ const button2 = document2.createElement("button");
31874
+ button2.type = "button";
31875
+ button2.className = "settings-connection-host-tab";
31876
+ button2.dataset.sessionImportHost = hostId2;
31877
+ button2.textContent = connectionHostName(hostId2, messages);
31878
+ button2.setAttribute("aria-pressed", String(hostId2 === current));
31879
+ button2.disabled = hostsLocked;
31880
+ button2.addEventListener("click", () => selectHost(hostId2));
31881
+ hostButtons.push(button2);
31882
+ hostOptions.append(button2);
31883
+ }
31884
+ hostOptions.scrollLeft = scrollLeft;
31885
+ };
30834
31886
  const harness2 = document2.createElement("div");
30835
31887
  harness2.className = "settings-session-import-harness";
30836
31888
  const harnessLabel = document2.createElement("span");
@@ -30891,6 +31943,7 @@ ${detail}` : ""}`
30891
31943
  const listControls = createSessionImportListControls(document2, messages, () => load());
30892
31944
  context.content.append(
30893
31945
  header,
31946
+ hostLabel,
30894
31947
  harness2,
30895
31948
  description,
30896
31949
  availabilityNote,
@@ -30900,9 +31953,11 @@ ${detail}` : ""}`
30900
31953
  listControls.pagination
30901
31954
  );
30902
31955
  let candidates = [];
31956
+ let loadedClient = null;
30903
31957
  let importingId = null;
30904
31958
  let actions = [];
30905
31959
  const updateImportActions = () => {
31960
+ lockHosts(importingId !== null);
30906
31961
  listControls.setBusy(importingId !== null, importingId !== null);
30907
31962
  for (const button2 of sourceButtons) button2.disabled = importingId !== null;
30908
31963
  for (const { button: button2, candidate } of actions) {
@@ -30923,7 +31978,10 @@ ${detail}` : ""}`
30923
31978
  listControls.setTotal(0);
30924
31979
  candidates = [];
30925
31980
  actions = [];
30926
- const status = createStatus(document2, messages.sessionImportUnavailable);
31981
+ const status = createStatus(
31982
+ document2,
31983
+ !displayedHostId && availableHostIds.length > 1 ? messages.sessionImportSelectHost : messages.sessionImportUnavailable
31984
+ );
30927
31985
  content.replaceChildren(status);
30928
31986
  if (focus) {
30929
31987
  status.tabIndex = -1;
@@ -30948,7 +32006,7 @@ ${detail}` : ""}`
30948
32006
  status.focus();
30949
32007
  }
30950
32008
  };
30951
- const renderOpenRecovery = (candidate, threadId) => {
32009
+ const renderOpenRecovery = (candidate, threadId, hostId2) => {
30952
32010
  if (!openImportedThread) return;
30953
32011
  actions = [];
30954
32012
  refresh.disabled = false;
@@ -31001,6 +32059,7 @@ ${detail}` : ""}`
31001
32059
  retry.className = "settings-command-button";
31002
32060
  retry.dataset.sessionImportAction = "retry-open";
31003
32061
  const setRetrying = (pending) => {
32062
+ lockHosts(pending);
31004
32063
  listControls.setBusy(pending, pending);
31005
32064
  for (const button2 of sourceButtons) button2.disabled = pending;
31006
32065
  retry.disabled = pending;
@@ -31015,12 +32074,12 @@ ${detail}` : ""}`
31015
32074
  retry.addEventListener("click", () => {
31016
32075
  if (retry.disabled) return;
31017
32076
  setRetrying(true);
31018
- void context.runLatest((signal) => openImportedThread(threadId, signal), {
32077
+ void context.runLatest((signal) => openImportedThread(threadId, signal, hostId2), {
31019
32078
  success() {
31020
32079
  setRetrying(false);
31021
32080
  },
31022
32081
  failure() {
31023
- renderOpenRecovery(candidate, threadId);
32082
+ renderOpenRecovery(candidate, threadId, hostId2);
31024
32083
  }
31025
32084
  });
31026
32085
  });
@@ -31097,7 +32156,7 @@ ${detail}` : ""}`
31097
32156
  if (candidate.running === true || importingId !== null || selectedHarness === null)
31098
32157
  return;
31099
32158
  const harnessId = selectedHarness;
31100
- const client = getClient();
32159
+ const client = loadedClient;
31101
32160
  if (!client) {
31102
32161
  renderUnavailable(true);
31103
32162
  return;
@@ -31115,7 +32174,7 @@ ${detail}` : ""}`
31115
32174
  });
31116
32175
  committedThreadId = result.threadId;
31117
32176
  if (!signal.aborted && openImportedThread)
31118
- await openImportedThread(result.threadId, signal);
32177
+ await openImportedThread(result.threadId, signal, client.hostId);
31119
32178
  },
31120
32179
  {
31121
32180
  success() {
@@ -31133,7 +32192,7 @@ ${detail}` : ""}`
31133
32192
  updateImportActions();
31134
32193
  refresh.disabled = false;
31135
32194
  if (committedThreadId) {
31136
- renderOpenRecovery(candidate, committedThreadId);
32195
+ renderOpenRecovery(candidate, committedThreadId, client.hostId);
31137
32196
  } else {
31138
32197
  renderFailure(error51, "import");
31139
32198
  }
@@ -31151,23 +32210,22 @@ ${detail}` : ""}`
31151
32210
  };
31152
32211
  const load = () => {
31153
32212
  if (importingId !== null || context.signal.aborted) return;
31154
- const client = getClient();
31155
- if (!client) {
31156
- refresh.disabled = false;
31157
- setRefreshLabel(false);
31158
- renderUnavailable();
31159
- return;
31160
- }
31161
- listControls.setBusy(true);
31162
- refresh.disabled = true;
31163
- setRefreshLabel(true);
31164
- content.replaceChildren(createStatus(document2, messages.sessionImportRefreshing));
32213
+ loadedClient = null;
32214
+ const client = getClient(selectedHostId);
32215
+ renderHosts(client);
32216
+ listControls.setBusy(client !== null);
32217
+ refresh.disabled = client !== null;
32218
+ setRefreshLabel(client !== null);
32219
+ if (client)
32220
+ content.replaceChildren(createStatus(document2, messages.sessionImportRefreshing));
32221
+ else renderUnavailable();
31165
32222
  const requestedHarness = selectedHarness;
31166
32223
  const pageParams = listControls.params();
31167
32224
  void context.runLatest(
31168
32225
  async (signal) => {
32226
+ if (!client) throw new RendererSessionImportUnavailableError();
31169
32227
  const missing = new Set(
31170
- getDiagnostics()?.snapshot().hosts.find(({ hostId: hostId2 }) => hostId2 === "local")?.agents.filter(({ availability }) => availability === "notInstalled").map(({ agent }) => agent)
32228
+ getDiagnostics()?.snapshot().hosts.find(({ hostId: hostId2 }) => hostId2 === (client.hostId ?? "local"))?.agents.filter(({ availability }) => availability === "notInstalled").map(({ agent }) => agent)
31171
32229
  );
31172
32230
  const harnesses = (await client.listSessionImportSources()).harnesses.filter(
31173
32231
  ({ harnessId }) => !missing.has(harnessId)
@@ -31185,6 +32243,7 @@ ${detail}` : ""}`
31185
32243
  },
31186
32244
  {
31187
32245
  success(result) {
32246
+ loadedClient = client;
31188
32247
  listControls.setBusy(false);
31189
32248
  if (listControls.setTotal(result.total)) {
31190
32249
  load();
@@ -31197,6 +32256,7 @@ ${detail}` : ""}`
31197
32256
  else renderCandidates();
31198
32257
  },
31199
32258
  failure(error51) {
32259
+ loadedClient = null;
31200
32260
  listControls.setBusy(false);
31201
32261
  candidates = [];
31202
32262
  refresh.disabled = false;
@@ -31206,6 +32266,19 @@ ${detail}` : ""}`
31206
32266
  }
31207
32267
  );
31208
32268
  };
32269
+ const selectHost = (hostId2) => {
32270
+ if (hostsLocked || !availableHostIds.includes(hostId2) || hostId2 === selectedHostId) return;
32271
+ selectedHostId = hostId2;
32272
+ selectedHarness = null;
32273
+ sources = [];
32274
+ candidates = [];
32275
+ actions = [];
32276
+ importStatus.replaceChildren();
32277
+ listControls.reset();
32278
+ renderHarnessOptions();
32279
+ load();
32280
+ hostButtons.find((button2) => button2.dataset.sessionImportHost === hostId2)?.focus();
32281
+ };
31209
32282
  refresh.addEventListener("click", load);
31210
32283
  load();
31211
32284
  return void 0;
@@ -31346,14 +32419,14 @@ ${detail}` : ""}`
31346
32419
  description: messages.idleReleaseTimeoutDescription,
31347
32420
  controlId: minutesId
31348
32421
  });
31349
- const { field, control: minutes } = createNumberField(document2, {
32422
+ const { field: field2, control: minutes } = createNumberField(document2, {
31350
32423
  id: minutesId,
31351
32424
  describedBy: timeout.description.id,
31352
32425
  unit: messages.idleReleaseMinutes,
31353
32426
  min: IDLE_RELEASE_TIMEOUT_MINUTES_MIN,
31354
32427
  max: IDLE_RELEASE_TIMEOUT_MINUTES_MAX
31355
32428
  });
31356
- timeout.item.append(field);
32429
+ timeout.item.append(field2);
31357
32430
  timeout.item.id = preferenceId("idle-release-timeout");
31358
32431
  enabled.setAttribute("aria-controls", timeout.item.id);
31359
32432
  card.append(toggle.item, timeout.item);
@@ -31374,7 +32447,7 @@ ${detail}` : ""}`
31374
32447
  statusText.textContent = value === "applied" ? "" : statusMessages[value];
31375
32448
  };
31376
32449
  const setInvalid = (invalid) => {
31377
- field.dataset.invalid = String(invalid);
32450
+ field2.dataset.invalid = String(invalid);
31378
32451
  timeout.description.dataset.invalid = String(invalid);
31379
32452
  timeout.description.textContent = invalid ? messages.idleReleaseInvalid : messages.idleReleaseTimeoutDescription;
31380
32453
  minutes.setAttribute("aria-invalid", String(invalid));
@@ -31699,7 +32772,7 @@ ${detail}` : ""}`
31699
32772
  }
31700
32773
  function defaultImportName(source, existing) {
31701
32774
  const base = source.provider === "openai-codex" ? "codex" : "grok";
31702
- const used = new Set(existing.map((record6) => record6.name));
32775
+ const used = new Set(existing.map((record8) => record8.name));
31703
32776
  const valid = (name) => credentialImportNameSchema.safeParse(name).success;
31704
32777
  if (!used.has(base)) return base;
31705
32778
  const local = source.label.includes("@") ? source.label.split("@")[0] ?? "" : "";
@@ -31722,7 +32795,7 @@ ${detail}` : ""}`
31722
32795
  const shown = (text) => accountDisplayText(text, hideEmails);
31723
32796
  const targetButtons = /* @__PURE__ */ new Map();
31724
32797
  const importedRecords = () => snapshot.targets.find((target) => target.harnessId === TARGET_HARNESS_ID)?.imports ?? [];
31725
- const sourceOf = (record6) => snapshot.sources.find((source) => source.id === record6.source.id);
32798
+ const sourceOf = (record8) => snapshot.sources.find((source) => source.id === record8.source.id);
31726
32799
  const piTarget = () => snapshot.targets.find((candidate) => candidate.harnessId === TARGET_HARNESS_ID);
31727
32800
  const compatibleSources = () => {
31728
32801
  const target = piTarget();
@@ -31760,7 +32833,7 @@ ${detail}` : ""}`
31760
32833
  sectionImport.addEventListener("click", () => {
31761
32834
  const sources = compatibleSources();
31762
32835
  const free = sources.find(
31763
- (source2) => !importedRecords().some((record6) => record6.source.id === source2.id)
32836
+ (source2) => !importedRecords().some((record8) => record8.source.id === source2.id)
31764
32837
  );
31765
32838
  const source = free ?? sources[0];
31766
32839
  if (source) openDialog("add", { source, choose: true }, SECTION_IMPORT_KEY);
@@ -31810,30 +32883,30 @@ ${detail}` : ""}`
31810
32883
  mark.append(createRendererAgentIcon(agent ?? "pi", 26, document2, pluginFor(agent ?? "pi")));
31811
32884
  return mark;
31812
32885
  };
31813
- const renderRow = (record6) => {
32886
+ const renderRow = (record8) => {
31814
32887
  const row = document2.createElement("div");
31815
32888
  row.className = "settings-pi-accounts__row";
31816
32889
  row.tabIndex = -1;
31817
- row.dataset.importName = record6.name;
31818
- row.setAttribute("aria-label", shown(record6.source.label));
31819
- const agent = record6.source.harnessId;
32890
+ row.dataset.importName = record8.name;
32891
+ row.setAttribute("aria-label", shown(record8.source.label));
32892
+ const agent = record8.source.harnessId;
31820
32893
  const mark = createMark(agent);
31821
32894
  const identity = document2.createElement("div");
31822
32895
  identity.className = "settings-pi-accounts__identity";
31823
32896
  const label = document2.createElement("strong");
31824
32897
  label.className = "settings-account-email";
31825
- label.textContent = shown(record6.source.label);
32898
+ label.textContent = shown(record8.source.label);
31826
32899
  label.title = label.textContent;
31827
32900
  label.translate = false;
31828
32901
  const meta3 = document2.createElement("div");
31829
32902
  meta3.className = "settings-account-metadata";
31830
- const source = sourceOf(record6);
32903
+ const source = sourceOf(record8);
31831
32904
  const parts = [
31832
32905
  metaPart(rendererAgentLabel(agent, pluginFor(agent)), "settings-pi-accounts__agent"),
31833
- metaPart(`${record6.name}/\u2026`, void 0, true),
32906
+ metaPart(`${record8.name}/\u2026`, void 0, true),
31834
32907
  metaPart(messages.copied)
31835
32908
  ];
31836
- const time3 = formatImportedAt(record6.importedAt);
32909
+ const time3 = formatImportedAt(record8.importedAt);
31837
32910
  if (time3) parts.push(metaPart(time3));
31838
32911
  parts.forEach((part, index) => {
31839
32912
  if (index > 0) {
@@ -31850,23 +32923,23 @@ ${detail}` : ""}`
31850
32923
  reimport.type = "button";
31851
32924
  reimport.className = "settings-account-action";
31852
32925
  reimport.textContent = messages.rowReimport;
31853
- reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record6.source.label)}`);
32926
+ reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record8.source.label)}`);
31854
32927
  reimport.disabled = busy || !source;
31855
32928
  reimport.title = messages.reimport;
31856
32929
  reimport.addEventListener("click", () => {
31857
- if (source) openDialog("reimport", { source, record: record6 }, `row:${record6.name}`);
32930
+ if (source) openDialog("reimport", { source, record: record8 }, `row:${record8.name}`);
31858
32931
  });
31859
32932
  const remove = document2.createElement("button");
31860
32933
  remove.type = "button";
31861
32934
  remove.className = "settings-account-action settings-pi-accounts__remove";
31862
32935
  remove.textContent = messages.rowRemove;
31863
- remove.setAttribute("aria-label", `${messages.remove}: ${shown(record6.source.label)}`);
32936
+ remove.setAttribute("aria-label", `${messages.remove}: ${shown(record8.source.label)}`);
31864
32937
  remove.disabled = busy;
31865
- remove.addEventListener("click", () => openDialog("remove", { record: record6 }, `row:${record6.name}`));
32938
+ remove.addEventListener("click", () => openDialog("remove", { record: record8 }, `row:${record8.name}`));
31866
32939
  if (source) actions.append(reimport);
31867
32940
  actions.append(remove);
31868
32941
  row.append(mark, identity, actions);
31869
- rows.set(record6.name, row);
32942
+ rows.set(record8.name, row);
31870
32943
  return row;
31871
32944
  };
31872
32945
  const loginTypeLabel = (type) => type === "oauth" ? messages.typeOauth : type === "api_key" ? messages.typeApiKey : messages.typeOther;
@@ -32019,7 +33092,7 @@ ${detail}` : ""}`
32019
33092
  const label = document2.createElement("strong");
32020
33093
  label.textContent = shown(choice.label);
32021
33094
  label.translate = false;
32022
- const existing = importedRecords().find((record6) => record6.source.id === choice.id);
33095
+ const existing = importedRecords().find((record8) => record8.source.id === choice.id);
32023
33096
  const agent = choice.harnessId;
32024
33097
  const detail = document2.createElement("span");
32025
33098
  detail.textContent = [
@@ -32060,7 +33133,7 @@ ${detail}` : ""}`
32060
33133
  const name = request.action === "list" ? void 0 : request.name;
32061
33134
  state = {
32062
33135
  source: state.source,
32063
- record: importedRecords().find((record6) => record6.name === name) ?? state.record
33136
+ record: importedRecords().find((record8) => record8.name === name) ?? state.record
32064
33137
  };
32065
33138
  show(next);
32066
33139
  } else {
@@ -32074,12 +33147,12 @@ ${detail}` : ""}`
32074
33147
  sourceRadios = [];
32075
33148
  body.replaceChildren();
32076
33149
  controls.replaceChildren();
32077
- const { source, record: record6 } = state;
33150
+ const { source, record: record8 } = state;
32078
33151
  const close = () => modal.close();
32079
33152
  if (mode === "add" || mode === "reimport") {
32080
33153
  title.textContent = mode === "add" ? messages.add : messages.reimport;
32081
33154
  modal.setAttribute("aria-label", title.textContent);
32082
- const active = source ?? record6?.source;
33155
+ const active = source ?? record8?.source;
32083
33156
  const choices = mode === "add" && state.choose ? compatibleSources() : [];
32084
33157
  if (choices.length > 1) body.append(sourcePicker(choices));
32085
33158
  else if (active) body.append(line(messages.source, shown(active.label)));
@@ -32088,8 +33161,8 @@ ${detail}` : ""}`
32088
33161
  input.maxLength = 48;
32089
33162
  input.autocomplete = "off";
32090
33163
  input.spellcheck = false;
32091
- input.value = record6?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
32092
- input.readOnly = Boolean(record6);
33164
+ input.value = record8?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
33165
+ input.readOnly = Boolean(record8);
32093
33166
  input.addEventListener("input", () => {
32094
33167
  nameEdited = true;
32095
33168
  });
@@ -32123,7 +33196,7 @@ ${detail}` : ""}`
32123
33196
  {
32124
33197
  action: mode === "reimport" ? "reimport" : "import",
32125
33198
  sourceId: source2.id,
32126
- name: record6?.name ?? input.value,
33199
+ name: record8?.name ?? input.value,
32127
33200
  confirmed: true
32128
33201
  },
32129
33202
  "done"
@@ -32133,16 +33206,16 @@ ${detail}` : ""}`
32133
33206
  )
32134
33207
  );
32135
33208
  (mode === "add" ? input : controls.children[0]).focus();
32136
- } else if (mode === "remove" && record6) {
33209
+ } else if (mode === "remove" && record8) {
32137
33210
  title.textContent = messages.remove;
32138
33211
  modal.setAttribute("aria-label", title.textContent);
32139
- body.append(note(messages.removeWarning.replace("{name}", record6.name)));
33212
+ body.append(note(messages.removeWarning.replace("{name}", record8.name)));
32140
33213
  const cancel = command(messages.cancel, close);
32141
33214
  controls.append(
32142
33215
  cancel,
32143
33216
  command(
32144
33217
  messages.remove,
32145
- () => submit({ action: "remove", name: record6.name, confirmed: true }, null),
33218
+ () => submit({ action: "remove", name: record8.name, confirmed: true }, null),
32146
33219
  "danger"
32147
33220
  )
32148
33221
  );
@@ -32150,7 +33223,7 @@ ${detail}` : ""}`
32150
33223
  } else {
32151
33224
  title.textContent = messages.doneTitle;
32152
33225
  modal.setAttribute("aria-label", title.textContent);
32153
- const name = record6?.name;
33226
+ const name = record8?.name;
32154
33227
  if (name) body.append(line(messages.entry, `${name}/\u2026`, true));
32155
33228
  body.append(note(messages.done));
32156
33229
  const done = command(messages.close, close, "primary");
@@ -32197,21 +33270,21 @@ ${detail}` : ""}`
32197
33270
  (candidate) => candidate.harnessId === TARGET_HARNESS_ID && source && candidate.providers.includes(source.provider)
32198
33271
  );
32199
33272
  if (!source || !target) return null;
32200
- const record6 = target.imports.find((candidate) => candidate.source.id === source.id);
33273
+ const record8 = target.imports.find((candidate) => candidate.source.id === source.id);
32201
33274
  const key = `${harnessId}:${accountLabel}:import`;
32202
33275
  const button2 = document2.createElement("button");
32203
33276
  button2.type = "button";
32204
33277
  button2.className = "settings-account-pi-import";
32205
33278
  button2.dataset.accountFocus = key;
32206
33279
  button2.disabled = busy;
32207
- const hint = record6 ? messages.importedHint.replace("{name}", record6.name) : messages.add;
33280
+ const hint = record8 ? messages.importedHint.replace("{name}", record8.name) : messages.add;
32208
33281
  button2.title = hint;
32209
33282
  button2.setAttribute("aria-label", hint);
32210
33283
  button2.append(createRendererAgentIcon("pi", 12, document2, pluginFor("pi")));
32211
- if (record6) {
33284
+ if (record8) {
32212
33285
  button2.dataset.state = "imported";
32213
33286
  const name = document2.createElement("code");
32214
- name.textContent = `${record6.name}/\u2026`;
33287
+ name.textContent = `${record8.name}/\u2026`;
32215
33288
  name.translate = false;
32216
33289
  button2.append(name, createRendererSettingsIcon("check", 12));
32217
33290
  } else {
@@ -32219,7 +33292,7 @@ ${detail}` : ""}`
32219
33292
  button2.append(messages.add);
32220
33293
  }
32221
33294
  button2.addEventListener("click", () => {
32222
- if (!record6) {
33295
+ if (!record8) {
32223
33296
  openDialog("add", { source }, key);
32224
33297
  return;
32225
33298
  }
@@ -32228,7 +33301,7 @@ ${detail}` : ""}`
32228
33301
  renderSection();
32229
33302
  sectionToggle.setAttribute("aria-expanded", "true");
32230
33303
  }
32231
- const row = rows.get(record6.name);
33304
+ const row = rows.get(record8.name);
32232
33305
  row?.scrollIntoView({ block: "nearest", behavior: "smooth" });
32233
33306
  row?.focus();
32234
33307
  });
@@ -33223,6 +34296,43 @@ ${detail}` : ""}`
33223
34296
  });
33224
34297
  }
33225
34298
 
34299
+ // src/settings/harness-schedules-page.ts
34300
+ function createHarnessSchedulesPage(messages, options) {
34301
+ const t = (zh, en) => messages.locale === "zh-CN" ? zh : en;
34302
+ return {
34303
+ id: "harness-schedules",
34304
+ label: t("\u5B9A\u65F6\u4EFB\u52A1", "Schedules"),
34305
+ icon: "schedules",
34306
+ mount(context) {
34307
+ const navigate = () => {
34308
+ context.content.replaceChildren();
34309
+ void context.runLatest((signal) => options.openSchedules(signal), {
34310
+ success() {
34311
+ },
34312
+ failure() {
34313
+ const document2 = context.content.ownerDocument;
34314
+ const status = document2.createElement("p");
34315
+ status.setAttribute("role", "status");
34316
+ status.className = "text-sm text-settings-muted";
34317
+ status.textContent = t(
34318
+ "\u65E0\u6CD5\u6253\u5F00\u5B98\u65B9\u5B9A\u65F6\u4EFB\u52A1\u9875\uFF0C\u8BF7\u91CD\u8BD5\u6216\u4ECE\u5B98\u65B9\u4FA7\u680F\u8FDB\u5165\u3002",
34319
+ "Could not open the official schedules page. Retry or use the Desktop sidebar."
34320
+ );
34321
+ const retry = document2.createElement("button");
34322
+ retry.type = "button";
34323
+ retry.className = "rounded-lg px-3 py-2 text-sm text-settings-text hover:bg-settings-hover focus-visible:outline-2 focus-visible:outline-settings-focus";
34324
+ retry.textContent = t("\u91CD\u8BD5", "Retry");
34325
+ retry.addEventListener("click", navigate);
34326
+ context.content.replaceChildren(status, retry);
34327
+ }
34328
+ });
34329
+ };
34330
+ navigate();
34331
+ return void 0;
34332
+ }
34333
+ };
34334
+ }
34335
+
33226
34336
  // src/settings/update-request.ts
33227
34337
  var RENDERER_UPDATE_REQUEST_TIMEOUT_MS = 15e3;
33228
34338
  var RendererUpdateRequestTimeoutError = class extends Error {
@@ -33550,8 +34660,8 @@ ${detail}` : ""}`
33550
34660
  const starBanner = updateStarBanner(document2, messages);
33551
34661
  context.content.append(heading, metadata, panel, controls, starBanner, notes);
33552
34662
  const setManualFallback = (fallback) => {
33553
- controls.className = !fallback && !windows ? "settings-update-controls is-quiet" : "settings-update-controls";
33554
- manualNpmDescription.textContent = windows ? messages.updateWindowsNpmDescription : fallback ? messages.updateManualFallbackDescription : messages.updateManualNpmDescription;
34663
+ controls.className = fallback ? "settings-update-controls" : "settings-update-controls is-quiet";
34664
+ manualNpmDescription.textContent = fallback ? messages.updateManualFallbackDescription : messages.updateManualNpmDescription;
33555
34665
  manualNpmDescription.className = fallback ? "settings-update-manual-description is-fallback" : "settings-update-manual-description";
33556
34666
  };
33557
34667
  let pollTimer;
@@ -33701,14 +34811,14 @@ ${detail}` : ""}`
33701
34811
  panel.dataset.updateState = view;
33702
34812
  panel.replaceChildren();
33703
34813
  setManualFallback(Boolean(result.error) || actionableStatus !== null);
33704
- const inlineUpdate = !result.error && !windows && !actionableStatus && result.updateAvailable;
34814
+ const inlineUpdate = !result.error && !actionableStatus && result.updateAvailable;
33705
34815
  if (inlineUpdate) panel.dataset.inline = "";
33706
34816
  else delete panel.dataset.inline;
33707
34817
  panel.append(
33708
34818
  createPanelHead(
33709
34819
  document2,
33710
34820
  view,
33711
- actionableStatus ? statusMessage(actionableStatus, messages) ?? messages.updateFailed : result.error ? messages.updateFailed : result.updateAvailable ? windows ? messages.updateWindowsManualRequired : messages.updateAvailable : messages.updateUpToDate
34821
+ actionableStatus ? statusMessage(actionableStatus, messages) ?? messages.updateFailed : result.error ? messages.updateFailed : result.updateAvailable ? messages.updateAvailable : messages.updateUpToDate
33712
34822
  )
33713
34823
  );
33714
34824
  if (actionableStatus?.error) {
@@ -33724,7 +34834,7 @@ ${detail}` : ""}`
33724
34834
  panel.append(error51);
33725
34835
  }
33726
34836
  const buttons = [];
33727
- if (!windows && result.updateAvailable && result.installationAvailable) {
34837
+ if (result.updateAvailable && result.installationAvailable) {
33728
34838
  const update = document2.createElement("button");
33729
34839
  update.type = "button";
33730
34840
  update.className = "settings-command-button";
@@ -33773,11 +34883,12 @@ ${detail}` : ""}`
33773
34883
  }
33774
34884
  });
33775
34885
  }
33776
- function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable")), getLoadedSessionsClient = () => null, getRemoteConnections = () => null, requestUsageStatistics = () => Promise.reject(new Error("Local Host connection is unavailable")), usageStatisticsHosts) {
34886
+ function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable")), getLoadedSessionsClient = () => null, getRemoteConnections = () => null, requestUsageStatistics = () => Promise.reject(new Error("Local Host connection is unavailable")), usageStatisticsHosts, harnessSchedules) {
33777
34887
  return Object.freeze([
33778
34888
  createConnectionsSettingsPage(messages, getDiagnostics, void 0, getRemoteConnections),
33779
34889
  createRemoteConnectionsPage(messages, getRemoteConnections),
33780
34890
  createAccountsSettingsPage(messages, getAccountClient),
34891
+ ...harnessSchedules ? [createHarnessSchedulesPage(messages, harnessSchedules)] : [],
33781
34892
  createSessionImportSettingsPage(
33782
34893
  messages,
33783
34894
  getSessionImportClient,
@@ -34363,6 +35474,41 @@ ${detail}` : ""}`
34363
35474
  margin-top: 0;
34364
35475
  }
34365
35476
 
35477
+ .settings-session-import-host {
35478
+ display: flex;
35479
+ align-items: center;
35480
+ min-width: 0;
35481
+ gap: 12px;
35482
+ margin: -12px 0 12px;
35483
+ color: var(--settings-muted);
35484
+ font-size: 13px;
35485
+ }
35486
+
35487
+ .settings-session-import-host > span,
35488
+ .settings-session-import-host + .settings-session-import-harness > span {
35489
+ flex: none;
35490
+ min-width: 60px;
35491
+ }
35492
+
35493
+ .settings-session-import-host > .settings-connection-host-tabs {
35494
+ flex: 1;
35495
+ }
35496
+
35497
+ .settings-session-import-host .settings-connection-host-tab {
35498
+ height: 34px;
35499
+ padding: 0 12px;
35500
+ font-size: 13px;
35501
+ }
35502
+
35503
+ .settings-session-import-host .settings-connection-host-tab:disabled {
35504
+ opacity: 0.38;
35505
+ cursor: not-allowed;
35506
+ }
35507
+
35508
+ .settings-session-import-host + .settings-session-import-harness {
35509
+ margin-top: 0;
35510
+ }
35511
+
34366
35512
  .settings-session-import-search,
34367
35513
  .settings-session-import-pagination {
34368
35514
  display: flex;
@@ -34719,7 +35865,8 @@ ${detail}` : ""}`
34719
35865
  background: var(--settings-hover);
34720
35866
  }
34721
35867
 
34722
- .settings-connection-host-tab[aria-selected="true"] {
35868
+ .settings-connection-host-tab[aria-selected="true"],
35869
+ .settings-connection-host-tab[aria-pressed="true"] {
34723
35870
  color: var(--settings-text);
34724
35871
  font-weight: 600;
34725
35872
  background: var(--settings-active);
@@ -38442,7 +39589,7 @@ th[aria-sort] .console-usage-sort__mark {
38442
39589
  `;
38443
39590
 
38444
39591
  // src/settings/tailwind.css
38445
- var tailwind_default = '@layer properties, theme, base, components, utilities;\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.top-full{top:100%}.left-0{left:0}.z-20{z-index:20}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-7{margin-top:calc(var(--spacing) * 7)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:var(--spacing)}.ml-\\[45px\\]{margin-left:45px}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.list-item{display:list-item}.table{display:table}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-8{height:calc(var(--spacing) * 8)}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-\\[60px\\]{min-height:60px}.w-9{width:calc(var(--spacing) * 9)}.w-14{width:calc(var(--spacing) * 14)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-px{width:1px}.max-w-64{max-width:calc(var(--spacing) * 64)}.min-w-0{min-width:0}.flex-shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-x-auto{overflow-x:auto}.rounded-\\[10px\\]{border-radius:10px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-settings-border{border-color:var(--settings-border)}.border-settings-divider{border-color:var(--settings-divider)}.bg-settings-panel{background-color:var(--settings-panel)}.bg-settings-subtle{background-color:var(--settings-subtle)}.bg-settings-surface{background-color:var(--settings-surface)}.bg-settings-surface-hover{background-color:var(--settings-surface-hover)}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-4{padding:calc(var(--spacing) * 4)}.\\!px-0{padding-inline:0!important}.px-1{padding-inline:var(--spacing)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pl-4{padding-left:calc(var(--spacing) * 4)}.\\!text-right{text-align:right!important}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[11px\\]{font-size:11px}.text-\\[13px\\]{font-size:13px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.text-wrap{text-wrap:wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.text-settings-muted{color:var(--settings-muted)}.text-settings-subtle{color:var(--settings-subtle)}.text-settings-text{color:var(--settings-text)}.lowercase{text-transform:lowercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\\[0_10px_30px_rgb\\(0_0_0\\/0\\.22\\)\\]{--tw-shadow:0 10px 30px var(--tw-shadow-color,#00000038);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-settings-border{--tw-ring-color:var(--settings-border)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.ring-inset{--tw-ring-inset:inset}.group-focus-within\\:visible:is(:where(.group):focus-within *){visibility:visible}.group-focus-within\\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\\:visible:is(:where(.group):hover *){visibility:visible}.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}}.group-data-\\[state\\=failed\\]\\/status\\:bg-settings-danger:is(:where(.group\\/status)[data-state=failed] *){background-color:var(--settings-danger)}.group-data-\\[state\\=unavailable\\]\\/status\\:bg-settings-warning:is(:where(.group\\/status)[data-state=unavailable] *){background-color:var(--settings-warning)}.marker\\:text-settings-subtle ::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle ::-webkit-details-marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::-webkit-details-marker{color:var(--settings-subtle)}.before\\:absolute:before{content:var(--tw-content);position:absolute}.before\\:top-0\\.5:before{content:var(--tw-content);top:calc(var(--spacing) * .5)}.before\\:left-0\\.5:before{content:var(--tw-content);left:calc(var(--spacing) * .5)}.before\\:size-4:before{content:var(--tw-content);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.before\\:rounded-full:before{content:var(--tw-content);border-radius:3.40282e38px}.before\\:bg-white:before{content:var(--tw-content);background-color:#fff}.before\\:shadow-\\[0_1px_2px_rgb\\(0_0_0\\/0\\.3\\)\\]:before{content:var(--tw-content);--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.before\\:transition-transform:before{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.first\\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}.first-of-type\\:mt-0:first-of-type{margin-top:0}.checked\\:bg-settings-focus:checked{background-color:var(--settings-focus)}.checked\\:ring-transparent:checked{--tw-ring-color:transparent}.checked\\:before\\:translate-x-4:checked:before{content:var(--tw-content);--tw-translate-x:calc(var(--spacing) * 4);translate:var(--tw-translate-x) var(--tw-translate-y)}.focus-within\\:border-settings-focus:focus-within{border-color:var(--settings-focus)}@media (hover:hover){.hover\\:text-settings-text:hover{color:var(--settings-text)}}.focus-visible\\:text-settings-text:focus-visible{color:var(--settings-text)}.focus-visible\\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-settings-focus:focus-visible{outline-color:var(--settings-focus)}.data-\\[invalid\\=true\\]\\:border-settings-danger[data-invalid=true]{border-color:var(--settings-danger)}.data-\\[invalid\\=true\\]\\:text-settings-danger[data-invalid=true],.data-\\[state\\=failed\\]\\:text-settings-danger[data-state=failed]{color:var(--settings-danger)}.data-\\[state\\=unavailable\\]\\:text-settings-warning[data-state=unavailable]{color:var(--settings-warning)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@layer properties{\n *, ::before, ::after, ::backdrop{--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-alpha:100%;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-offset-width:0;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-drop-shadow-alpha:100%;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}\n';
39592
+ var tailwind_default = '@layer properties, theme, base, components, utilities;\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.top-full{top:100%}.left-0{left:0}.z-20{z-index:20}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-7{margin-top:calc(var(--spacing) * 7)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:var(--spacing)}.ml-\\[45px\\]{margin-left:45px}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.list-item{display:list-item}.table{display:table}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-8{height:calc(var(--spacing) * 8)}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-\\[60px\\]{min-height:60px}.w-9{width:calc(var(--spacing) * 9)}.w-14{width:calc(var(--spacing) * 14)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-px{width:1px}.max-w-64{max-width:calc(var(--spacing) * 64)}.min-w-0{min-width:0}.flex-shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-x-auto{overflow-x:auto}.rounded-\\[10px\\]{border-radius:10px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-settings-border{border-color:var(--settings-border)}.border-settings-divider{border-color:var(--settings-divider)}.bg-settings-panel{background-color:var(--settings-panel)}.bg-settings-subtle{background-color:var(--settings-subtle)}.bg-settings-surface{background-color:var(--settings-surface)}.bg-settings-surface-hover{background-color:var(--settings-surface-hover)}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-4{padding:calc(var(--spacing) * 4)}.\\!px-0{padding-inline:0!important}.px-1{padding-inline:var(--spacing)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pl-4{padding-left:calc(var(--spacing) * 4)}.\\!text-right{text-align:right!important}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[11px\\]{font-size:11px}.text-\\[13px\\]{font-size:13px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.text-wrap{text-wrap:wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.text-settings-muted{color:var(--settings-muted)}.text-settings-subtle{color:var(--settings-subtle)}.text-settings-text{color:var(--settings-text)}.lowercase{text-transform:lowercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\\[0_10px_30px_rgb\\(0_0_0\\/0\\.22\\)\\]{--tw-shadow:0 10px 30px var(--tw-shadow-color,#00000038);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-settings-border{--tw-ring-color:var(--settings-border)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.ring-inset{--tw-ring-inset:inset}.group-focus-within\\:visible:is(:where(.group):focus-within *){visibility:visible}.group-focus-within\\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\\:visible:is(:where(.group):hover *){visibility:visible}.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}}.group-data-\\[state\\=failed\\]\\/status\\:bg-settings-danger:is(:where(.group\\/status)[data-state=failed] *){background-color:var(--settings-danger)}.group-data-\\[state\\=unavailable\\]\\/status\\:bg-settings-warning:is(:where(.group\\/status)[data-state=unavailable] *){background-color:var(--settings-warning)}.marker\\:text-settings-subtle ::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle ::-webkit-details-marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::-webkit-details-marker{color:var(--settings-subtle)}.before\\:absolute:before{content:var(--tw-content);position:absolute}.before\\:top-0\\.5:before{content:var(--tw-content);top:calc(var(--spacing) * .5)}.before\\:left-0\\.5:before{content:var(--tw-content);left:calc(var(--spacing) * .5)}.before\\:size-4:before{content:var(--tw-content);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.before\\:rounded-full:before{content:var(--tw-content);border-radius:3.40282e38px}.before\\:bg-white:before{content:var(--tw-content);background-color:#fff}.before\\:shadow-\\[0_1px_2px_rgb\\(0_0_0\\/0\\.3\\)\\]:before{content:var(--tw-content);--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.before\\:transition-transform:before{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.first\\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}.first-of-type\\:mt-0:first-of-type{margin-top:0}.checked\\:bg-settings-focus:checked{background-color:var(--settings-focus)}.checked\\:ring-transparent:checked{--tw-ring-color:transparent}.checked\\:before\\:translate-x-4:checked:before{content:var(--tw-content);--tw-translate-x:calc(var(--spacing) * 4);translate:var(--tw-translate-x) var(--tw-translate-y)}.focus-within\\:border-settings-focus:focus-within{border-color:var(--settings-focus)}@media (hover:hover){.hover\\:bg-settings-hover:hover{background-color:var(--settings-hover)}.hover\\:text-settings-text:hover{color:var(--settings-text)}}.focus-visible\\:text-settings-text:focus-visible{color:var(--settings-text)}.focus-visible\\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-settings-focus:focus-visible{outline-color:var(--settings-focus)}.data-\\[invalid\\=true\\]\\:border-settings-danger[data-invalid=true]{border-color:var(--settings-danger)}.data-\\[invalid\\=true\\]\\:text-settings-danger[data-invalid=true],.data-\\[state\\=failed\\]\\:text-settings-danger[data-state=failed]{color:var(--settings-danger)}.data-\\[state\\=unavailable\\]\\:text-settings-warning[data-state=unavailable]{color:var(--settings-warning)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@layer properties{\n *, ::before, ::after, ::backdrop{--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-alpha:100%;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-offset-width:0;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-drop-shadow-alpha:100%;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}\n';
38446
39593
 
38447
39594
  // src/settings/trigger.ts
38448
39595
  var SETTINGS_TRIGGER_ATTRIBUTE = "data-codexhost-settings-trigger";
@@ -39009,23 +40156,30 @@ ${usage_default}`;
39009
40156
  let disposed = false;
39010
40157
  const mount = () => {
39011
40158
  const messages = rendererSettingsMessages(locale);
40159
+ const schedules = options.harnessSchedules;
39012
40160
  const definitions = createDefaultRendererSettingsPages(
39013
40161
  messages,
39014
40162
  options.getUpdateClient ?? (() => null),
39015
40163
  options.getConnectionDiagnostics ?? (() => null),
39016
40164
  options.getAccountClient ?? (() => null),
39017
40165
  options.getSessionImportClient ?? (() => null),
39018
- async (threadId, signal) => {
40166
+ async (threadId, signal, hostId2) => {
39019
40167
  if (!options.openImportedThread) {
39020
40168
  throw new Error("Imported Thread navigation is unavailable");
39021
40169
  }
39022
- await options.openImportedThread(threadId, signal);
40170
+ await options.openImportedThread(threadId, signal, hostId2);
39023
40171
  if (!disposed && !signal.aborted) shell?.close();
39024
40172
  },
39025
40173
  options.getLoadedSessionsClient ?? (() => null),
39026
40174
  options.getRemoteConnections ?? (() => null),
39027
40175
  options.requestUsageStatistics,
39028
- options.usageStatisticsHosts
40176
+ options.usageStatisticsHosts,
40177
+ schedules ? {
40178
+ openSchedules: async (signal) => {
40179
+ await schedules.openSchedules(signal);
40180
+ if (!disposed && !signal.aborted) shell?.close();
40181
+ }
40182
+ } : void 0
39029
40183
  );
39030
40184
  const nextShell = installRendererSettingsShell(definitions, messages, ownerWindow.document, {
39031
40185
  onOpenChange(open) {
@@ -39759,6 +40913,803 @@ ${usage_default}`;
39759
40913
  return event.defaultPrevented;
39760
40914
  }
39761
40915
 
40916
+ // src/codex-schedule-navigation.ts
40917
+ function isNavigationBus(value) {
40918
+ if (typeof value !== "object" || value === null) return false;
40919
+ const bus = value;
40920
+ return bus.handlers instanceof Map && bus.handlers.has("navigate-to-route") && typeof bus.dispatchHostMessage === "function";
40921
+ }
40922
+ function hasArrived(ownerWindow) {
40923
+ const paths = ["/automations", "/scheduled"];
40924
+ const pages = ownerWindow.document.querySelectorAll('[data-app-shell-active-page="true"]');
40925
+ if (pages.length > 0) {
40926
+ const page = pages[0];
40927
+ if (pages.length !== 1 || !page) return false;
40928
+ const fiberKey = Object.keys(page).find((key) => key.startsWith("__reactFiber$"));
40929
+ if (!fiberKey) return false;
40930
+ for (const ancestor of committedReactAncestors(Reflect.get(page, fiberKey))) {
40931
+ const props = ancestor.memoizedProps;
40932
+ const value = props?.value;
40933
+ if (value?.navigationType === "POP" || value?.navigationType === "PUSH" || value?.navigationType === "REPLACE") {
40934
+ return typeof value.location?.pathname === "string" && paths.includes(value.location.pathname);
40935
+ }
40936
+ }
40937
+ return false;
40938
+ }
40939
+ return paths.includes(ownerWindow.location.pathname);
40940
+ }
40941
+ async function openCodexSchedules(signal, ownerWindow = window) {
40942
+ signal.throwIfAborted();
40943
+ const bus = await loadCodexNativeServices(ownerWindow, isNavigationBus);
40944
+ signal.throwIfAborted();
40945
+ if (!bus) throw new Error("Codex navigation is unavailable");
40946
+ await new Promise((resolve, reject) => {
40947
+ let settled = false;
40948
+ const finish = (error51) => {
40949
+ if (settled) return;
40950
+ settled = true;
40951
+ ownerWindow.clearInterval(poll);
40952
+ ownerWindow.clearTimeout(timeout);
40953
+ signal.removeEventListener("abort", onAbort);
40954
+ if (error51) reject(error51);
40955
+ else resolve();
40956
+ };
40957
+ const arrived = () => hasArrived(ownerWindow);
40958
+ const onAbort = () => finish(arrived() ? void 0 : signal.reason);
40959
+ const poll = ownerWindow.setInterval(() => {
40960
+ if (arrived()) finish();
40961
+ }, 25);
40962
+ const timeout = ownerWindow.setTimeout(
40963
+ () => finish(new Error("Codex did not open the requested page")),
40964
+ 5e3
40965
+ );
40966
+ signal.addEventListener("abort", onAbort, { once: true });
40967
+ try {
40968
+ bus.dispatchHostMessage({ type: "navigate-to-route", path: "/automations" });
40969
+ if (arrived()) finish();
40970
+ } catch (error51) {
40971
+ finish(error51);
40972
+ }
40973
+ });
40974
+ }
40975
+
40976
+ // src/renderer-native-schedule-picker.ts
40977
+ var schedulePickerStyles = `
40978
+ .picker { position:relative; display:flex; justify-content:flex-end; min-width:0; max-width:100%; }
40979
+ .trigger { display:flex; align-items:center; gap:8px; min-width:0; max-width:100%; height:32px; padding:0 8px 0 10px; border:0; border-radius:10px; color:var(--muted); background:transparent; font:inherit; text-align:right; cursor:pointer; transition:background-color .12s, color .12s; }
40980
+ .trigger:hover:not(:disabled), .trigger[aria-expanded="true"] { color:var(--text); background:var(--hover); }
40981
+ .trigger:focus-visible { outline:2px solid var(--focus); outline-offset:1px; }
40982
+ .trigger:disabled { cursor:default; }
40983
+ .trigger > svg, .trigger > img, .trigger > span.icon, .item > svg, .item > img, .item > span.icon { flex:none; }
40984
+ .label { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
40985
+ .trigger[data-stale] .label { opacity:.6; }
40986
+ .trigger[data-shimmer] .label { background:linear-gradient(90deg,var(--muted) 0%,var(--muted) 35%,color-mix(in srgb,var(--muted) 30%,transparent) 50%,var(--muted) 65%,var(--muted) 100%) 100% 0/250% 100%; -webkit-background-clip:text; background-clip:text; color:transparent; animation:shimmer 1.4s ease-in-out infinite; }
40987
+ .chevron { flex:none; width:6px; height:6px; margin:0 3px 2px 2px; border-right:1.5px solid; border-bottom:1.5px solid; transform:rotate(45deg); transition:transform .12s; }
40988
+ .trigger[aria-expanded="true"] .chevron { transform:translateY(2px) rotate(225deg); }
40989
+ .trigger[aria-busy="true"] .chevron { display:none; }
40990
+ .spinner { flex:none; width:12px; height:12px; margin:0 1px; border:1.5px solid color-mix(in srgb,currentColor 25%,transparent); border-top-color:currentColor; border-radius:50%; animation:spin .8s linear infinite; }
40991
+ .menu { position:fixed; inset:auto; margin:0; padding:4px; min-width:200px; max-width:calc(100vw - 16px); overflow:auto; overscroll-behavior:contain; border:1px solid var(--border); border-radius:12px; color:var(--text); background:var(--surface); box-shadow:0 8px 28px rgba(0,0,0,.22),0 1px 3px rgba(0,0,0,.12); font:inherit; }
40992
+ .menu:not(:popover-open):not([data-open]) { display:none; }
40993
+ .item { display:flex; align-items:center; gap:10px; min-height:36px; padding:6px 8px; border-radius:8px; cursor:pointer; outline:none; }
40994
+ .item:hover:not([aria-disabled="true"]), .item:focus-visible { background:var(--hover); }
40995
+ .item:focus-visible { box-shadow:inset 0 0 0 2px var(--focus); }
40996
+ .item[aria-disabled="true"] { opacity:.45; cursor:default; }
40997
+ .item .label { flex:1; }
40998
+ .check { flex:none; width:5px; height:9px; margin:0 6px 2px 4px; border-right:1.5px solid; border-bottom:1.5px solid; transform:rotate(45deg); visibility:hidden; }
40999
+ .item[aria-selected="true"] .check { visibility:visible; }
41000
+ @keyframes shimmer { to { background-position:-100% 0; } }
41001
+ @keyframes spin { to { transform:rotate(360deg); } }
41002
+ @media(prefers-reduced-motion:reduce) { .spinner, .trigger[data-shimmer] .label { animation:none; } .trigger, .chevron { transition:none; } }
41003
+ `;
41004
+ function createSchedulePicker(document2, options) {
41005
+ const view = document2.defaultView ?? window;
41006
+ const root = document2.createElement("div");
41007
+ root.className = "picker";
41008
+ const trigger = document2.createElement("button");
41009
+ trigger.type = "button";
41010
+ trigger.className = "trigger";
41011
+ trigger.setAttribute("aria-label", options.label);
41012
+ trigger.setAttribute("aria-haspopup", "listbox");
41013
+ trigger.setAttribute("aria-expanded", "false");
41014
+ const menu = document2.createElement("div");
41015
+ menu.className = "menu";
41016
+ menu.setAttribute("role", "listbox");
41017
+ menu.setAttribute("aria-label", options.listLabel);
41018
+ const supportsPopover = typeof menu.showPopover === "function";
41019
+ if (supportsPopover) menu.setAttribute("popover", "manual");
41020
+ root.append(trigger, menu);
41021
+ let items = [];
41022
+ let stale = null;
41023
+ let value = "";
41024
+ let disabled = false;
41025
+ let busy = false;
41026
+ let placeholder = "";
41027
+ let shimmer = false;
41028
+ let isOpen = false;
41029
+ let isDisabled = () => false;
41030
+ const optionElements = /* @__PURE__ */ new Map();
41031
+ const selectedItem = () => items.find((item) => item.value === value) ?? stale;
41032
+ const cloneIcon = (item) => item.icon?.cloneNode(true) ?? null;
41033
+ const renderTrigger = () => {
41034
+ const item = selectedItem();
41035
+ const label = document2.createElement("span");
41036
+ label.className = "label";
41037
+ label.textContent = item?.label ?? placeholder;
41038
+ const icon2 = item ? cloneIcon(item) : null;
41039
+ const tail = document2.createElement("span");
41040
+ tail.className = busy ? "spinner" : "chevron";
41041
+ tail.setAttribute("aria-hidden", "true");
41042
+ trigger.replaceChildren(...icon2 ? [icon2] : [], label, tail);
41043
+ trigger.toggleAttribute("data-stale", Boolean(item && !items.includes(item)));
41044
+ trigger.toggleAttribute("data-shimmer", shimmer && !item);
41045
+ trigger.dataset.value = item ? value : "";
41046
+ trigger.setAttribute("aria-busy", String(busy));
41047
+ trigger.disabled = disabled;
41048
+ if (disabled && isOpen) close();
41049
+ };
41050
+ const renderItems = () => {
41051
+ optionElements.clear();
41052
+ const elements = items.map((item) => {
41053
+ const option = document2.createElement("div");
41054
+ option.className = "item";
41055
+ option.setAttribute("role", "option");
41056
+ option.tabIndex = -1;
41057
+ option.dataset.value = item.value;
41058
+ option.setAttribute("aria-selected", String(item.value === value));
41059
+ if (item.disabled || isDisabled(item.value)) option.setAttribute("aria-disabled", "true");
41060
+ const icon2 = cloneIcon(item);
41061
+ const label = document2.createElement("span");
41062
+ label.className = "label";
41063
+ label.textContent = item.label;
41064
+ const check2 = document2.createElement("span");
41065
+ check2.className = "check";
41066
+ check2.setAttribute("aria-hidden", "true");
41067
+ option.append(...icon2 ? [icon2] : [], label, check2);
41068
+ optionElements.set(item.value, option);
41069
+ return option;
41070
+ });
41071
+ menu.replaceChildren(...elements);
41072
+ };
41073
+ const enabledOptions = () => [...optionElements.values()].filter((el) => el.getAttribute("aria-disabled") !== "true");
41074
+ const focusOption = (el) => {
41075
+ el?.focus();
41076
+ el?.scrollIntoView({ block: "nearest" });
41077
+ };
41078
+ const position = () => {
41079
+ const rect = trigger.getBoundingClientRect();
41080
+ const margin = 8;
41081
+ menu.style.minWidth = `${Math.max(200, Math.min(rect.width, view.innerWidth - 2 * margin))}px`;
41082
+ menu.style.maxHeight = "";
41083
+ const height = menu.offsetHeight;
41084
+ const below = view.innerHeight - rect.bottom - margin - 4;
41085
+ const above = rect.top - margin - 4;
41086
+ const placeBelow = height <= below || below >= above;
41087
+ const room = Math.max(120, placeBelow ? below : above);
41088
+ menu.style.maxHeight = `${room}px`;
41089
+ const used = Math.min(height, room);
41090
+ menu.style.top = `${placeBelow ? rect.bottom + 4 : rect.top - 4 - used}px`;
41091
+ const width = menu.offsetWidth;
41092
+ const left = Math.min(Math.max(margin, rect.right - width), view.innerWidth - width - margin);
41093
+ menu.style.left = `${Math.max(margin, left)}px`;
41094
+ };
41095
+ const onWindowKey = (event) => {
41096
+ if (event.key !== "Escape") return;
41097
+ event.preventDefault();
41098
+ event.stopImmediatePropagation();
41099
+ close();
41100
+ trigger.focus();
41101
+ };
41102
+ const onOutside = (event) => {
41103
+ if (!event.composedPath().includes(root)) close();
41104
+ };
41105
+ const onDismiss = () => close();
41106
+ function open() {
41107
+ if (isOpen || disabled) return;
41108
+ options.onOpen?.();
41109
+ if (!items.length) return;
41110
+ isOpen = true;
41111
+ trigger.setAttribute("aria-expanded", "true");
41112
+ if (supportsPopover) menu.showPopover();
41113
+ else menu.setAttribute("data-open", "");
41114
+ position();
41115
+ focusOption(optionElements.get(value) ?? enabledOptions()[0]);
41116
+ view.addEventListener("keydown", onWindowKey, true);
41117
+ document2.addEventListener("pointerdown", onOutside, true);
41118
+ view.addEventListener("resize", onDismiss);
41119
+ view.addEventListener("blur", onDismiss);
41120
+ document2.addEventListener("scroll", onDismiss, true);
41121
+ }
41122
+ function close() {
41123
+ if (!isOpen) return;
41124
+ isOpen = false;
41125
+ trigger.setAttribute("aria-expanded", "false");
41126
+ if (supportsPopover && menu.matches(":popover-open")) menu.hidePopover();
41127
+ menu.removeAttribute("data-open");
41128
+ view.removeEventListener("keydown", onWindowKey, true);
41129
+ document2.removeEventListener("pointerdown", onOutside, true);
41130
+ view.removeEventListener("resize", onDismiss);
41131
+ view.removeEventListener("blur", onDismiss);
41132
+ document2.removeEventListener("scroll", onDismiss, true);
41133
+ }
41134
+ const choose = (el) => {
41135
+ if (el.getAttribute("aria-disabled") === "true") return;
41136
+ const next = el.dataset.value ?? "";
41137
+ close();
41138
+ trigger.focus();
41139
+ if (next === value) return;
41140
+ picker.value = next;
41141
+ options.onChange(next);
41142
+ };
41143
+ trigger.addEventListener("click", () => isOpen ? close() : open());
41144
+ trigger.addEventListener("keydown", (event) => {
41145
+ if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
41146
+ event.preventDefault();
41147
+ open();
41148
+ });
41149
+ menu.addEventListener("click", (event) => {
41150
+ const el = event.target.closest('[role="option"]');
41151
+ if (el) choose(el);
41152
+ });
41153
+ menu.addEventListener("keydown", (event) => {
41154
+ const list = enabledOptions();
41155
+ const active = menu.getRootNode().activeElement;
41156
+ const at = active ? list.indexOf(active) : -1;
41157
+ if (event.key === "ArrowDown") focusOption(list[Math.min(list.length - 1, at + 1)]);
41158
+ else if (event.key === "ArrowUp") focusOption(list[Math.max(0, at - 1)]);
41159
+ else if (event.key === "Home") focusOption(list[0]);
41160
+ else if (event.key === "End") focusOption(list.at(-1));
41161
+ else if (event.key === "Enter" || event.key === " ") {
41162
+ if (active?.getAttribute("role") === "option") choose(active);
41163
+ } else if (event.key === "Tab") {
41164
+ close();
41165
+ trigger.focus();
41166
+ return;
41167
+ } else return;
41168
+ event.preventDefault();
41169
+ });
41170
+ const picker = {
41171
+ root,
41172
+ trigger,
41173
+ get value() {
41174
+ return value;
41175
+ },
41176
+ set value(next) {
41177
+ if (next === value) return;
41178
+ stale = null;
41179
+ value = next;
41180
+ for (const [key, el] of optionElements)
41181
+ el.setAttribute("aria-selected", String(key === next));
41182
+ renderTrigger();
41183
+ },
41184
+ get disabled() {
41185
+ return disabled;
41186
+ },
41187
+ set disabled(next) {
41188
+ if (next === disabled) return;
41189
+ disabled = next;
41190
+ renderTrigger();
41191
+ },
41192
+ get busy() {
41193
+ return busy;
41194
+ },
41195
+ set busy(next) {
41196
+ if (next === busy) return;
41197
+ busy = next;
41198
+ renderTrigger();
41199
+ },
41200
+ setItems(next) {
41201
+ const previous = selectedItem();
41202
+ stale = options.retainMissing && previous && !next.some((item) => item.value === value) ? { ...previous, disabled: true } : null;
41203
+ items = next;
41204
+ renderItems();
41205
+ renderTrigger();
41206
+ },
41207
+ setDisabledValues(next) {
41208
+ isDisabled = next;
41209
+ for (const item of items) {
41210
+ const el = optionElements.get(item.value);
41211
+ if (!el) continue;
41212
+ if (item.disabled || next(item.value)) el.setAttribute("aria-disabled", "true");
41213
+ else el.removeAttribute("aria-disabled");
41214
+ }
41215
+ },
41216
+ setPlaceholder(text, shimmerText = false) {
41217
+ if (text === placeholder && shimmerText === shimmer) return;
41218
+ placeholder = text;
41219
+ shimmer = shimmerText;
41220
+ renderTrigger();
41221
+ },
41222
+ close
41223
+ };
41224
+ renderTrigger();
41225
+ return picker;
41226
+ }
41227
+
41228
+ // src/renderer-native-schedule-controls.ts
41229
+ function restoreRow(row, appearance) {
41230
+ row.hidden = appearance.hidden;
41231
+ row.style.setProperty("display", appearance.display, appearance.priority);
41232
+ }
41233
+ function installRendererNativeScheduleControls(document2, options) {
41234
+ const view = document2.defaultView ?? window;
41235
+ const mounted = /* @__PURE__ */ new Map();
41236
+ let disposed = false;
41237
+ let frame = null;
41238
+ const text = (zh, en) => options.locale() === "zh-CN" ? zh : en;
41239
+ const schedule = () => {
41240
+ if (!disposed && frame === null) frame = view.requestAnimationFrame(scan);
41241
+ };
41242
+ function mount(form) {
41243
+ const root = document2.createElement("div");
41244
+ root.dataset.codexhostScheduleControls = "true";
41245
+ const shadow = root.attachShadow({ mode: "open" });
41246
+ const style = document2.createElement("style");
41247
+ style.textContent = `
41248
+ :host { display:block; contain:inline-size; margin:0 0 16px; color:inherit; font:inherit; --text:var(--color-text-primary,CanvasText); --muted:var(--color-text-secondary,light-dark(#6b6b6b,#b5b5b5)); --border:var(--color-border-default,light-dark(#e1e1e1,#454545)); --hover:var(--color-token-list-hover-background,light-dark(rgba(0,0,0,.05),rgba(255,255,255,.08))); --surface:var(--color-token-dropdown-background,var(--color-background-surface,Canvas)); --focus:var(--color-text-info,#387aff); }
41249
+ * { box-sizing:border-box; }
41250
+ fieldset { border:1px solid var(--border); border-radius:16px; padding:0 12px; margin:0; min-width:0; }
41251
+ .row { display:flex; align-items:center; justify-content:space-between; gap:16px; min-width:0; min-height:52px; padding:8px 0 8px 4px; font:inherit; }
41252
+ .row + .row { border-top:1px solid var(--border); }
41253
+ .name { flex:none; }
41254
+ .value { display:flex; justify-content:flex-end; min-width:0; max-width:72%; }
41255
+ fieldset:disabled { opacity:.6; }
41256
+ ${schedulePickerStyles}
41257
+ .message { display:flex; align-items:baseline; gap:8px; margin:8px 4px 0; color:var(--muted); font-size:12px; line-height:1.5; }
41258
+ p { margin:0; min-width:0; overflow-wrap:anywhere; }
41259
+ button.retry { border:0; border-radius:4px; padding:2px 4px; color:inherit; background:transparent; font:inherit; text-decoration:underline; cursor:pointer; flex-shrink:0; }
41260
+ button.retry:focus-visible { outline:2px solid var(--focus); outline-offset:2px; }
41261
+ [hidden] { display:none!important; }
41262
+ `;
41263
+ const fields = document2.createElement("fieldset");
41264
+ const harness2 = createSchedulePicker(document2, {
41265
+ label: "Harness",
41266
+ listLabel: text("\u9009\u62E9 Harness", "Choose a Harness"),
41267
+ retainMissing: true,
41268
+ onChange: () => onHarness()
41269
+ });
41270
+ const model2 = createSchedulePicker(document2, {
41271
+ label: text("\u6A21\u578B", "Model"),
41272
+ listLabel: text("\u9009\u62E9\u6A21\u578B", "Choose a Model"),
41273
+ retainMissing: true,
41274
+ onChange: () => applyModel()
41275
+ });
41276
+ const workspace = createSchedulePicker(document2, {
41277
+ label: text("\u5DE5\u4F5C\u533A", "Workspace"),
41278
+ listLabel: text("\u9009\u62E9\u5DE5\u4F5C\u533A", "Choose a workspace"),
41279
+ retainMissing: true,
41280
+ onOpen: () => refreshWorkspaces(),
41281
+ onChange: () => {
41282
+ const next = workspaces.find(({ id }) => id === workspace.value) ?? null;
41283
+ if (next?.id === selectedWorkspace?.id && next?.cwd === selectedWorkspace?.cwd) return;
41284
+ selectedWorkspace = next;
41285
+ void loadModels({ preserveSelection: models.length > 0 });
41286
+ }
41287
+ });
41288
+ const label = (name, picker) => {
41289
+ const row = document2.createElement("div");
41290
+ row.className = "row";
41291
+ const title = document2.createElement("span");
41292
+ title.className = "name";
41293
+ title.textContent = name;
41294
+ const value = document2.createElement("div");
41295
+ value.className = "value";
41296
+ value.append(picker.root);
41297
+ row.append(title, value);
41298
+ fields.append(row);
41299
+ return row;
41300
+ };
41301
+ label("Harness", harness2);
41302
+ const modelRow = label(text("\u6A21\u578B", "Model"), model2);
41303
+ const workspaceRow = label(text("\u5DE5\u4F5C\u533A", "Workspace"), workspace);
41304
+ const status = document2.createElement("p");
41305
+ status.setAttribute("role", "status");
41306
+ const retry = document2.createElement("button");
41307
+ retry.type = "button";
41308
+ retry.className = "retry";
41309
+ retry.textContent = text("\u91CD\u8BD5", "Retry");
41310
+ retry.hidden = true;
41311
+ const messageRow = document2.createElement("div");
41312
+ messageRow.className = "message";
41313
+ messageRow.append(status, retry);
41314
+ shadow.append(style, fields, messageRow);
41315
+ const editor = form.querySelector('[contenteditable="true"][role="textbox"], textarea');
41316
+ const container = editor?.closest("fieldset")?.querySelector(":scope > div") ?? form;
41317
+ container.prepend(root);
41318
+ let retired = false;
41319
+ let client = options.getClient();
41320
+ let selectedHarness = "codex";
41321
+ let availablePlugins = [];
41322
+ let generation = 0;
41323
+ let loading = false;
41324
+ let confirming = false;
41325
+ let confirmationTimer;
41326
+ let error51 = "";
41327
+ let models = [];
41328
+ let workspaces = [];
41329
+ let selectedWorkspace = null;
41330
+ let workspaceCreation = null;
41331
+ let carrier = null;
41332
+ let original = null;
41333
+ let restoring = null;
41334
+ const hiddenRows = /* @__PURE__ */ new Map();
41335
+ const external = () => selectedHarness !== "codex";
41336
+ const available = () => options.getAvailablePlugins().some((plugin) => plugin.id === selectedHarness);
41337
+ const harnessItem = (id, name, plugin) => ({
41338
+ value: id,
41339
+ label: name,
41340
+ icon: createRendererAgentIcon(id, 18, document2, plugin)
41341
+ });
41342
+ harness2.setItems([harnessItem("codex", "Codex")]);
41343
+ harness2.value = "codex";
41344
+ const syncAvailablePlugins = () => {
41345
+ const next = options.getAvailablePlugins();
41346
+ if (next.length === availablePlugins.length && next.every(
41347
+ (plugin, index) => plugin.id === availablePlugins[index]?.id && plugin.name === availablePlugins[index]?.name
41348
+ ))
41349
+ return;
41350
+ availablePlugins = next;
41351
+ harness2.setItems([
41352
+ harnessItem("codex", "Codex"),
41353
+ ...next.map((plugin) => harnessItem(plugin.id, plugin.name, plugin))
41354
+ ]);
41355
+ harness2.value = selectedHarness;
41356
+ };
41357
+ function refreshWorkspaces() {
41358
+ workspaces = readNativeScheduleWorkspaces(document2);
41359
+ workspace.setItems([
41360
+ { value: "", label: text("\u81EA\u52A8\u5206\u914D", "Automatic") },
41361
+ ...workspaces.map(({ id, label: label2, cwd }) => ({ value: id, label: `${label2} \xB7 ${cwd}` }))
41362
+ ]);
41363
+ workspace.value = selectedWorkspace?.id ?? "";
41364
+ update();
41365
+ }
41366
+ const cancelConfirmation = () => {
41367
+ if (confirmationTimer !== void 0) view.clearTimeout(confirmationTimer);
41368
+ confirmationTimer = void 0;
41369
+ confirming = false;
41370
+ };
41371
+ const restoredSelection = (selection) => restoring && (restoring.model === null ? !selection.model?.startsWith("codexhost/") : selection.model === restoring.model && selection.reasoningEffort === restoring.reasoningEffort);
41372
+ const confirmSelection = () => {
41373
+ cancelConfirmation();
41374
+ confirming = true;
41375
+ const deadline = Date.now() + 5e3;
41376
+ const check2 = () => {
41377
+ if (retired) return;
41378
+ const binding = readNativeScheduleForm(form);
41379
+ const confirmed = binding && (external() ? binding.selection.model === carrier : !restoring || restoredSelection(binding.selection));
41380
+ if (!binding || !options.canRouteExternal() || client !== options.getClient() || confirmed || Date.now() >= deadline)
41381
+ cancelConfirmation();
41382
+ else confirmationTimer = view.setTimeout(check2, 50);
41383
+ update();
41384
+ };
41385
+ confirmationTimer = view.setTimeout(check2, 0);
41386
+ };
41387
+ const restore = () => {
41388
+ const binding = readNativeScheduleForm(form);
41389
+ if (original && carrier && (!binding || binding.selection.model === carrier || confirming)) {
41390
+ restoring = original;
41391
+ binding?.setModel(original);
41392
+ confirmSelection();
41393
+ }
41394
+ carrier = null;
41395
+ original = null;
41396
+ selectedWorkspace = null;
41397
+ workspace.value = "";
41398
+ };
41399
+ const applyModel = () => {
41400
+ const binding = readNativeScheduleForm(form);
41401
+ const selected = models.find((entry) => entry.ref.id === model2.value);
41402
+ if (!external() || workspaceCreation !== null || !binding?.supportsExternal || !available() || binding.hasTarget || binding.isSaving || !selected)
41403
+ return;
41404
+ original ??= restoring ?? binding.selection;
41405
+ restoring = null;
41406
+ carrier = encodeHarnessPluginRoute({
41407
+ harnessId: selectedHarness,
41408
+ model: selected.ref
41409
+ });
41410
+ binding.setModel({ model: carrier, reasoningEffort: null });
41411
+ confirmSelection();
41412
+ update();
41413
+ };
41414
+ const loadModels = async ({ preserveSelection = false } = {}) => {
41415
+ const request = ++generation;
41416
+ const previousModel = model2.value;
41417
+ if (!preserveSelection) {
41418
+ cancelConfirmation();
41419
+ models = [];
41420
+ model2.setItems([]);
41421
+ model2.value = "";
41422
+ model2.setPlaceholder(text("\u6B63\u5728\u52A0\u8F7D\u6A21\u578B\u2026", "Loading models\u2026"), true);
41423
+ }
41424
+ error51 = "";
41425
+ loading = true;
41426
+ update();
41427
+ const requestedHarness = selectedHarness;
41428
+ const selectedClient = client;
41429
+ try {
41430
+ if (!selectedClient) throw Error(text("\u672C\u5730\u8FDE\u63A5\u4E0D\u53EF\u7528\u3002", "Local connection unavailable."));
41431
+ const result = await selectedClient.inspectHarness({
41432
+ harnessId: requestedHarness,
41433
+ ...selectedWorkspace ? { cwd: selectedWorkspace.cwd } : {}
41434
+ });
41435
+ if (retired || request !== generation || selectedClient !== options.getClient()) return;
41436
+ if (result.status !== "ready")
41437
+ throw Error(text("\u6240\u9009 Harness \u4E0D\u53EF\u7528\u3002", "The selected Harness is unavailable."));
41438
+ const selectedModel = preserveSelection ? model2.value : previousModel;
41439
+ const next = result.catalog.models;
41440
+ const changed = next.length !== models.length || next.some(
41441
+ (entry, index) => entry.ref.id !== models[index]?.ref.id || entry.label !== models[index]?.label
41442
+ );
41443
+ models = next;
41444
+ if (changed || !preserveSelection)
41445
+ model2.setItems(models.map((entry) => ({ value: entry.ref.id, label: entry.label })));
41446
+ const defaultModel = result.catalog.defaultModel;
41447
+ model2.value = preserveSelection || models.some((entry) => entry.ref.id === selectedModel) ? selectedModel : defaultModel && models.some((entry) => entry.ref.id === defaultModel.id) ? defaultModel.id : models[0]?.ref.id ?? "";
41448
+ model2.setPlaceholder("");
41449
+ if (!models.length) throw Error(text("\u6CA1\u6709\u53EF\u7528\u6A21\u578B\u3002", "No models are available."));
41450
+ if (!preserveSelection) applyModel();
41451
+ } catch (cause) {
41452
+ if (retired || request !== generation) return;
41453
+ error51 = cause instanceof Error ? cause.message : text("\u6A21\u578B\u8BFB\u53D6\u5931\u8D25\u3002", "Could not read models.");
41454
+ if (!preserveSelection) model2.setPlaceholder(text("\u6A21\u578B\u52A0\u8F7D\u5931\u8D25", "Models unavailable"));
41455
+ } finally {
41456
+ if (!retired && request === generation) {
41457
+ loading = false;
41458
+ update();
41459
+ }
41460
+ }
41461
+ };
41462
+ const onHarness = () => {
41463
+ const binding = readNativeScheduleForm(form);
41464
+ if (binding?.hasTarget || binding?.isSaving || workspaceCreation) return;
41465
+ selectedHarness = harness2.value;
41466
+ client = options.getClient();
41467
+ if (!external()) restore();
41468
+ generation++;
41469
+ models = [];
41470
+ model2.setItems([]);
41471
+ model2.value = "";
41472
+ model2.setPlaceholder("");
41473
+ error51 = "";
41474
+ loading = false;
41475
+ if (external()) {
41476
+ refreshWorkspaces();
41477
+ void loadModels();
41478
+ }
41479
+ update();
41480
+ };
41481
+ retry.addEventListener("click", () => {
41482
+ if (error51) void loadModels({ preserveSelection: models.length > 0 });
41483
+ else applyModel();
41484
+ });
41485
+ function blockedReason() {
41486
+ const binding = readNativeScheduleForm(form);
41487
+ if (!external()) {
41488
+ const restored = binding && restoredSelection(binding.selection);
41489
+ if (restoring && !restored)
41490
+ return text(
41491
+ "\u6B63\u5728\u6062\u590D Codex \u914D\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u63D0\u4EA4\u3002",
41492
+ "Restoring Codex settings. Submit again once ready."
41493
+ );
41494
+ restoring = null;
41495
+ if (binding?.selection.model?.startsWith("codexhost/"))
41496
+ return text(
41497
+ "\u4EFB\u52A1\u4ECD\u643A\u5E26\u5916\u90E8 Model\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5F39\u7A97\u3002",
41498
+ "The task still carries an external Model. Reopen the dialog."
41499
+ );
41500
+ return "";
41501
+ }
41502
+ if (!binding || !options.canRouteExternal() || client !== options.getClient())
41503
+ return text(
41504
+ "\u4EFB\u52A1\u63A5\u5165\u6216\u672C\u5730\u8FDE\u63A5\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5F39\u7A97\u3002",
41505
+ "Task binding or local connection unavailable. Reopen the dialog."
41506
+ );
41507
+ if (!available())
41508
+ return text(
41509
+ "\u6240\u9009 Harness \u5DF2\u4E0D\u5728\u672C\u5730\u53EF\u7528\u5217\u8868\u4E2D\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002",
41510
+ "The selected Harness is no longer available locally. Choose another Harness."
41511
+ );
41512
+ if (!binding.supportsExternal)
41513
+ return text(
41514
+ "\u5916\u90E8 Harness \u4EC5\u652F\u6301\u672C\u5730\u56FA\u5B9A\u804A\u5929\uFF1A\u8BF7\u542F\u7528\u201C\u5728\u6B64\u7535\u8111\u4E0A\u8FD0\u884C\u201D\uFF0C\u5173\u95ED\u201C\u6BCF\u6B21\u8FD0\u884C\u90FD\u5F00\u542F\u65B0\u804A\u5929\u201D\uFF0C\u5E76\u9009\u62E9\u4E2A\u4EBA\u5B9A\u65F6\u4EFB\u52A1\u3002",
41515
+ "External Harnesses require a personal local task in the same chat. Enable Run on this computer and disable Start each run in new chat."
41516
+ );
41517
+ if (workspaceCreation?.error) return workspaceCreation.error;
41518
+ if (workspaceCreation?.pending)
41519
+ return text("\u6B63\u5728\u521B\u5EFA\u5DE5\u4F5C\u533A\u4F1A\u8BDD\u2026", "Creating workspace chat\u2026");
41520
+ const chosen = selectedWorkspace;
41521
+ if (chosen && !binding.hasTarget && !workspaces.some(({ id, cwd }) => id === chosen.id && cwd === chosen.cwd))
41522
+ return text(
41523
+ "\u6240\u9009\u5DE5\u4F5C\u533A\u5DF2\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002",
41524
+ "The selected workspace is no longer available. Choose another workspace."
41525
+ );
41526
+ if (error51) return error51;
41527
+ if (loading)
41528
+ return models.length > 0 ? text(
41529
+ "\u6B63\u5728\u786E\u8BA4\u5DE5\u4F5C\u533A\u7684\u6A21\u578B\u914D\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u63D0\u4EA4\u3002",
41530
+ "Checking workspace models. Submit again once ready."
41531
+ ) : text("\u8BF7\u7B49\u5F85\u5E76\u9009\u62E9\u53EF\u7528\u7684 Model\u3002", "Wait for an available Model and select it.");
41532
+ if (!carrier || !models.some((entry) => entry.ref.id === model2.value))
41533
+ return text(
41534
+ "\u5F53\u524D\u6A21\u578B\u5728\u6B64\u5DE5\u4F5C\u533A\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u6A21\u578B\u3002",
41535
+ "The selected Model is unavailable in this workspace. Choose another Model."
41536
+ );
41537
+ if (binding.selection.model !== carrier && confirming)
41538
+ return text("\u6B63\u5728\u5E94\u7528\u6A21\u578B\u2026", "Applying Model\u2026");
41539
+ if (binding.selection.model !== carrier)
41540
+ return text(
41541
+ "\u4EFB\u52A1\u7684 Model \u5C1A\u672A\u786E\u8BA4\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9 Model\u3002",
41542
+ "The task Model is not confirmed. Select the Model again."
41543
+ );
41544
+ return "";
41545
+ }
41546
+ function update() {
41547
+ if (retired) return;
41548
+ syncAvailablePlugins();
41549
+ const binding = readNativeScheduleForm(form);
41550
+ const active = external();
41551
+ modelRow.hidden = !active;
41552
+ workspaceRow.hidden = !active;
41553
+ fields.disabled = Boolean(binding?.isSaving || binding?.hasTarget || workspaceCreation);
41554
+ workspace.disabled = loading && models.length === 0 || confirming || !binding?.supportsExternal || !available();
41555
+ const modelBusy = loading && models.length === 0 || confirming && active;
41556
+ model2.disabled = modelBusy || models.length === 0 || !binding?.supportsExternal || !available();
41557
+ model2.busy = modelBusy;
41558
+ harness2.busy = confirming && !active;
41559
+ harness2.disabled = fields.disabled;
41560
+ const externalBlocked = !binding?.supportsExternal || !options.canRouteExternal();
41561
+ harness2.setDisabledValues(externalBlocked ? (id) => id !== "codex" : () => false);
41562
+ const blocked = blockedReason();
41563
+ const message2 = loading && models.length === 0 || confirming ? "" : active ? blocked : blocked || error51 || (!binding?.supportsExternal ? text(
41564
+ "\u5916\u90E8 Harness \u9700\u8981\u5728\u9AD8\u7EA7\u8BBE\u7F6E\u4E2D\u9009\u62E9\u672C\u5730\u3001\u56FA\u5B9A\u804A\u5929\u3002",
41565
+ "For external Harnesses, choose local execution in the same chat under Advanced."
41566
+ ) : "");
41567
+ if (status.textContent !== message2) status.textContent = message2;
41568
+ messageRow.hidden = !message2;
41569
+ retry.hidden = !active || loading || confirming || Boolean(workspaceCreation) || !error51 && models.length > 0 && !models.some((entry) => entry.ref.id === model2.value) || !message2 || !binding?.supportsExternal || Boolean(binding.hasTarget || binding.isSaving) || client !== options.getClient() || !options.canRouteExternal() || !available();
41570
+ const rows = active ? new Set(nativeScheduleModelRows(form)) : /* @__PURE__ */ new Set();
41571
+ for (const [row, appearance] of hiddenRows) {
41572
+ if (rows.has(row)) continue;
41573
+ restoreRow(row, appearance);
41574
+ hiddenRows.delete(row);
41575
+ }
41576
+ for (const row of rows) {
41577
+ if (!hiddenRows.has(row))
41578
+ hiddenRows.set(row, {
41579
+ hidden: row.hidden,
41580
+ display: row.style.getPropertyValue("display"),
41581
+ priority: row.style.getPropertyPriority("display")
41582
+ });
41583
+ row.hidden = true;
41584
+ row.style.setProperty("display", "none", "important");
41585
+ }
41586
+ }
41587
+ async function prepareWorkspace(chosen, routeModel) {
41588
+ if (workspaceCreation) return;
41589
+ const attempt = {
41590
+ controller: new AbortController(),
41591
+ pending: true,
41592
+ error: "",
41593
+ thread: void 0
41594
+ };
41595
+ workspaceCreation = attempt;
41596
+ update();
41597
+ try {
41598
+ const binding = readNativeScheduleForm(form);
41599
+ if (!binding) throw Error("Task binding unavailable");
41600
+ attempt.thread = await options.createWorkspaceThread(
41601
+ { workspace: chosen, model: routeModel, title: binding.title },
41602
+ attempt.controller.signal
41603
+ );
41604
+ attempt.controller.signal.throwIfAborted();
41605
+ if (retired || !form.isConnected) throw Error("Task dialog closed");
41606
+ const current = readNativeScheduleForm(form);
41607
+ if (!current?.supportsExternal || current.selection.model !== routeModel || client !== options.getClient())
41608
+ throw Error("Task configuration or connection changed. Reopen the dialog.");
41609
+ current.setTargetThread(attempt.thread.threadId, routeModel);
41610
+ const deadline = Date.now() + 5e3;
41611
+ while (readNativeScheduleForm(form)?.targetThreadId !== attempt.thread.threadId) {
41612
+ attempt.controller.signal.throwIfAborted();
41613
+ if (Date.now() >= deadline)
41614
+ throw Error("The task's target chat was not confirmed. Reopen the dialog.");
41615
+ await new Promise((resolve) => view.setTimeout(resolve, 25));
41616
+ }
41617
+ attempt.controller.signal.throwIfAborted();
41618
+ attempt.pending = false;
41619
+ update();
41620
+ form.requestSubmit();
41621
+ } catch (cause) {
41622
+ attempt.error = `${cause instanceof Error ? cause.message : text("\u4F1A\u8BDD\u521B\u5EFA\u5931\u8D25\u3002", "Chat creation failed.")} ${text("\u8BF7\u5148\u68C0\u67E5\u4F1A\u8BDD\u5217\u8868\uFF0C\u52FF\u91CD\u590D\u521B\u5EFA\u3002", "Check the chat list before creating another task.")}`;
41623
+ } finally {
41624
+ attempt.pending = false;
41625
+ if (!retired) update();
41626
+ }
41627
+ }
41628
+ const onSubmit = (event) => {
41629
+ if (external() && selectedWorkspace) refreshWorkspaces();
41630
+ const reason = blockedReason();
41631
+ if (!reason) {
41632
+ if (external() && selectedWorkspace) {
41633
+ const binding = readNativeScheduleForm(form);
41634
+ const button2 = form.querySelector('button[type="submit"]');
41635
+ if (!button2 || button2.matches(":disabled") || binding?.isSaving) {
41636
+ event.preventDefault();
41637
+ event.stopImmediatePropagation();
41638
+ return;
41639
+ }
41640
+ if (!binding?.hasTarget && carrier) {
41641
+ event.preventDefault();
41642
+ event.stopImmediatePropagation();
41643
+ void prepareWorkspace(selectedWorkspace, carrier);
41644
+ return;
41645
+ }
41646
+ workspaceCreation?.thread?.retain();
41647
+ }
41648
+ return;
41649
+ }
41650
+ event.preventDefault();
41651
+ event.stopImmediatePropagation();
41652
+ messageRow.hidden = loading && models.length === 0 || confirming;
41653
+ status.textContent = reason;
41654
+ };
41655
+ form.addEventListener("submit", onSubmit, true);
41656
+ update();
41657
+ return {
41658
+ root,
41659
+ update,
41660
+ dispose() {
41661
+ retired = true;
41662
+ generation++;
41663
+ if (form.isConnected) restore();
41664
+ cancelConfirmation();
41665
+ harness2.close();
41666
+ model2.close();
41667
+ workspace.close();
41668
+ if (form.isConnected && workspaceCreation?.thread && readNativeScheduleForm(form)?.targetThreadId === workspaceCreation.thread.threadId)
41669
+ workspaceCreation.thread.retain();
41670
+ workspaceCreation?.controller.abort();
41671
+ for (const [row, appearance] of hiddenRows) restoreRow(row, appearance);
41672
+ form.removeEventListener("submit", onSubmit, true);
41673
+ root.remove();
41674
+ }
41675
+ };
41676
+ }
41677
+ function scan() {
41678
+ frame = null;
41679
+ if (disposed) return;
41680
+ for (const [form, control] of mounted) {
41681
+ if (!form.isConnected || !control.root.isConnected) {
41682
+ control.dispose();
41683
+ mounted.delete(form);
41684
+ } else control.update();
41685
+ }
41686
+ for (const form of document2.querySelectorAll('form[data-density="form"]')) {
41687
+ if (!mounted.has(form) && readNativeScheduleForm(form)) mounted.set(form, mount(form));
41688
+ }
41689
+ }
41690
+ const unsubscribeAvailability = options.subscribeAvailability(schedule);
41691
+ const observer = new MutationObserver(schedule);
41692
+ observer.observe(document2.documentElement, { childList: true, subtree: true });
41693
+ document2.addEventListener("change", schedule, true);
41694
+ document2.addEventListener("click", schedule, true);
41695
+ view.addEventListener("codexhost:draft-prewarm-policy-changed", schedule);
41696
+ scan();
41697
+ return {
41698
+ refresh: schedule,
41699
+ dispose() {
41700
+ disposed = true;
41701
+ if (frame !== null) view.cancelAnimationFrame(frame);
41702
+ observer.disconnect();
41703
+ unsubscribeAvailability();
41704
+ document2.removeEventListener("change", schedule, true);
41705
+ document2.removeEventListener("click", schedule, true);
41706
+ view.removeEventListener("codexhost:draft-prewarm-policy-changed", schedule);
41707
+ for (const control of mounted.values()) control.dispose();
41708
+ mounted.clear();
41709
+ }
41710
+ };
41711
+ }
41712
+
39762
41713
  // src/renderer-binding-probe.ts
39763
41714
  var EMPTY_PLUGINS = [];
39764
41715
  function isRetryableHarnessAvailability(availability, error51) {
@@ -40033,9 +41984,13 @@ ${usage_default}`;
40033
41984
  function mutationMayAffectComposer(mutation) {
40034
41985
  const target = mutation.target instanceof Element ? mutation.target : mutation.target.parentElement;
40035
41986
  if (!target) return true;
40036
- if (mutation.type === "attributes" && mutation.attributeName === "data-codex-composer-root")
41987
+ if (mutation.type === "attributes" && (mutation.attributeName === "data-codex-composer-root" || NATIVE_COMPOSER_REQUEST_ATTRIBUTES.some((attribute) => attribute === mutation.attributeName)))
40037
41988
  return true;
40038
- if (mutation.type !== "attributes" && editorForElement(target)) return false;
41989
+ if (mutation.type !== "attributes" && editorForElement(target)) {
41990
+ return mutation.type === "childList" && [...mutation.addedNodes, ...mutation.removedNodes].some(
41991
+ (node) => node instanceof Element && hasNativeComposerRequest(node)
41992
+ );
41993
+ }
40039
41994
  if (target.closest(CODEX_COMPOSER_SELECTOR)) return true;
40040
41995
  if (mutation.type === "characterData") return false;
40041
41996
  if (!target.closest(
@@ -40132,6 +42087,9 @@ ${usage_default}`;
40132
42087
  disposed: () => disposed
40133
42088
  });
40134
42089
  const settingsLifecycle = installRendererSettingsLifecycle(window, {
42090
+ harnessSchedules: {
42091
+ openSchedules: (signal) => openCodexSchedules(signal)
42092
+ },
40135
42093
  getRemoteConnections: () => remoteConnections,
40136
42094
  getUpdateClient: () => modelControl,
40137
42095
  getAccountClient: () => modelControl,
@@ -40139,19 +42097,22 @@ ${usage_default}`;
40139
42097
  getLoadedSessionsClient: () => modelClientForHost("local"),
40140
42098
  requestUsageStatistics: usageStatistics.request,
40141
42099
  usageStatisticsHosts: usageStatistics.hosts,
40142
- getSessionImportClient: () => {
40143
- const client = modelClientForHost("local");
42100
+ getSessionImportClient: (requestedHostId) => {
42101
+ const hostId2 = requestedHostId ?? activeModelHostId();
42102
+ if (!hostId2) return null;
42103
+ const client = modelClientForHost(hostId2);
40144
42104
  const sources = client?.listSessionImportSources;
40145
42105
  const list = client?.listHarnessSessions;
40146
42106
  const importSession = client?.importHarnessSession;
40147
42107
  if (!sources || !list || !importSession) return null;
40148
42108
  return {
42109
+ hostId: hostId2,
40149
42110
  listSessionImportSources: () => sources(),
40150
42111
  listHarnessSessions: (input) => list(input),
40151
42112
  importHarnessSession: (input) => importSession(input)
40152
42113
  };
40153
42114
  },
40154
- openImportedThread: (threadId, signal) => openRendererThread(threadId, { hostId: "local", signal }),
42115
+ openImportedThread: (threadId, signal, hostId2) => openRendererThread(threadId, { hostId: hostId2 ?? "local", signal }),
40155
42116
  onLocaleChange() {
40156
42117
  for (const mounted of mountedByComposer.values()) renderMounted(mounted);
40157
42118
  }
@@ -40222,7 +42183,7 @@ ${usage_default}`;
40222
42183
  const ownershipRecovery = /* @__PURE__ */ new WeakMap();
40223
42184
  const modelRecovery = /* @__PURE__ */ new WeakMap();
40224
42185
  const isRetainedComposer = (mounted) => mounted.composer.isConnected && mounted.composer.matches(CODEX_COMPOSER_SELECTOR) && mountedByComposer.get(mounted.composer) === mounted;
40225
- const isMountedComposer = (composer) => composer.isConnected && composer.matches(CODEX_COMPOSER_SELECTOR) && orbitComposerKind(composer) === "codex" && mountedByComposer.has(composer);
42186
+ const isMountedComposer = (composer) => composer.isConnected && composer.matches(CODEX_COMPOSER_SELECTOR) && !hasNativeComposerRequest(composer) && orbitComposerKind(composer) === "codex" && mountedByComposer.has(composer);
40226
42187
  const isCurrentModelRequest = (mounted, generation) => isMountedComposer(mounted.composer) && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentModelRequest(mounted.composer, generation);
40227
42188
  const isCurrentOwnershipRequest = (mounted, generation) => isMountedComposer(mounted.composer) && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentOwnershipRequest(mounted.composer, generation);
40228
42189
  const finishModelRequest = (mounted, generation) => {
@@ -41616,11 +43577,35 @@ ${usage_default}`;
41616
43577
  return () => connectionListeners.delete(listener);
41617
43578
  }
41618
43579
  };
43580
+ const nativeScheduleControls = installRendererNativeScheduleControls(document, {
43581
+ getClient: () => modelClientForHost("local"),
43582
+ getAvailablePlugins: () => {
43583
+ const client = modelClientForHost("local");
43584
+ const state = hostHarnessAvailabilityState("local");
43585
+ if (!client || state.directoryClient !== client) return [];
43586
+ return (state.plugins ?? []).filter((plugin) => plugin.kind !== "usage" && state.availability[plugin.id] === "ready").map((plugin) => pluginForHost("local", plugin.id) ?? plugin);
43587
+ },
43588
+ subscribeAvailability: (listener) => {
43589
+ connectionListeners.add(listener);
43590
+ return () => connectionListeners.delete(listener);
43591
+ },
43592
+ canRouteExternal: () => window.__codexhostHostRoutingV1?.forHost("local")?.policy.scopedCreation === true,
43593
+ async createWorkspaceThread(input, signal) {
43594
+ const routing = window.__codexhostHostRoutingV1;
43595
+ const manager = routing?.forHost("local")?.manager;
43596
+ const create = await loadCodexNativeServices(window, isNativeProjectThreadCreator);
43597
+ signal.throwIfAborted();
43598
+ if (!routing || !manager || routing.forHost("local")?.manager !== manager || !create)
43599
+ throw new Error("Native workspace chat creation is unavailable. Reopen the task dialog.");
43600
+ return createNativeScheduleWorkspaceThread(document, routing, create, input, signal);
43601
+ },
43602
+ locale: () => settingsLifecycle.locale
43603
+ });
41619
43604
  const mount = (composer) => {
41620
- if (mountedByComposer.has(composer) || !composer.isConnected || orbitComposerKind(composer) !== "codex" || !composer.matches(CODEX_COMPOSER_SELECTOR)) {
43605
+ if (mountedByComposer.has(composer) || !composer.isConnected || hasNativeComposerRequest(composer) || orbitComposerKind(composer) !== "codex" || !composer.matches(CODEX_COMPOSER_SELECTOR)) {
41621
43606
  return;
41622
43607
  }
41623
- const allButtons = [...composer.querySelectorAll("button")];
43608
+ const allButtons = composerButtonsWithin(composer);
41624
43609
  const sendButton = sendButtonWithin(composer) ?? allButtons.at(-1) ?? null;
41625
43610
  if (!sendButton) return;
41626
43611
  const modelTarget = findComposerModelTarget(composer);
@@ -41715,7 +43700,7 @@ ${usage_default}`;
41715
43700
  const sourceState = controller.get(replacement.source.composer);
41716
43701
  const replacementTarget = findComposerModelTarget(target);
41717
43702
  const replacementHostId = activeModelHostId(target);
41718
- if (orbitComposerKind(target) !== "codex" || !shouldTransferComposerState(
43703
+ if (hasNativeComposerRequest(target) || orbitComposerKind(target) !== "codex" || !shouldTransferComposerState(
41719
43704
  replacement.sourceModelTarget,
41720
43705
  replacementTarget,
41721
43706
  sourceState.phase,
@@ -41732,7 +43717,7 @@ ${usage_default}`;
41732
43717
  }
41733
43718
  for (const [composer, mounted] of mountedByComposer) {
41734
43719
  const kind = orbitComposerKind(composer);
41735
- if (!composer.isConnected || kind === "orbit" || !composer.matches(CODEX_COMPOSER_SELECTOR) || !mounted.control.root.isConnected) {
43720
+ if (!composer.isConnected || hasNativeComposerRequest(composer) || kind === "orbit" || !composer.matches(CODEX_COMPOSER_SELECTOR) || !mounted.control.root.isConnected) {
41736
43721
  mounted.usageRequestGeneration += 1;
41737
43722
  usageRefreshAttempts.delete(composer);
41738
43723
  const timer = usageRefreshTimers.get(composer);
@@ -41781,6 +43766,7 @@ ${usage_default}`;
41781
43766
  void refreshHarnessAvailability();
41782
43767
  }
41783
43768
  pendingReplacements.clear();
43769
+ questions.refreshContext();
41784
43770
  };
41785
43771
  const scheduleScan = (refreshTargets = false) => {
41786
43772
  refreshTargetsOnNextScan ||= refreshTargets;
@@ -41949,6 +43935,7 @@ ${usage_default}`;
41949
43935
  const onAdapterStatus = () => {
41950
43936
  publishConnectionStatus();
41951
43937
  if (shouldRefreshCodexAccountsForAdapterState(adapterStatus.state)) {
43938
+ reconcileHarnessAvailabilityHost();
41952
43939
  void loadCodexAccounts();
41953
43940
  sidebarAgentIcons.refresh();
41954
43941
  void refreshHarnessAvailabilityForHost("local");
@@ -41964,7 +43951,12 @@ ${usage_default}`;
41964
43951
  };
41965
43952
  mutationObserver.observe(document.documentElement, {
41966
43953
  attributes: true,
41967
- attributeFilter: ["hidden", "aria-hidden", "data-codex-composer-root"],
43954
+ attributeFilter: [
43955
+ "hidden",
43956
+ "aria-hidden",
43957
+ "data-codex-composer-root",
43958
+ ...NATIVE_COMPOSER_REQUEST_ATTRIBUTES
43959
+ ],
41968
43960
  characterData: true,
41969
43961
  childList: true,
41970
43962
  subtree: true
@@ -42061,6 +44053,16 @@ ${usage_default}`;
42061
44053
  const connectedComposers = () => [...mountedByComposer.values()].filter(
42062
44054
  (mounted) => isMountedComposer(mounted.composer) && mounted.control.root.isConnected
42063
44055
  );
44056
+ const questions = installRendererQuestions(window, () => {
44057
+ const visible = connectedComposers().filter(
44058
+ (mounted2) => mounted2.composer.getClientRects().length > 0 && window.getComputedStyle(mounted2.composer).visibility === "visible" && !mounted2.composer.closest('[hidden], [inert], [aria-hidden="true"]') && controller.get(mounted2.composer).agent !== "codex"
44059
+ );
44060
+ const mounted = visible.length === 1 ? visible[0] : void 0;
44061
+ const threadId = mounted ? threadIdFromComposerModelTarget(findComposerModelTarget(mounted.composer)) : null;
44062
+ const hostId2 = mounted?.hostId;
44063
+ const route = hostId2 ? window.__codexhostHostRoutingV1?.forHost(hostId2) : null;
44064
+ return mounted && threadId && hostId2 && route ? { hostId: hostId2, threadId, composer: mounted.composer, route: route.manager } : null;
44065
+ });
42064
44066
  const api = {
42065
44067
  remoteConnections: (request) => handleRemoteConnectionsRequest(remoteConnections, request),
42066
44068
  currentThreadId() {
@@ -42112,6 +44114,7 @@ ${usage_default}`;
42112
44114
  if (disposed || modelControl !== installedModelControl) return;
42113
44115
  try {
42114
44116
  settingsLifecycle.refresh();
44117
+ nativeScheduleControls.refresh();
42115
44118
  } catch {
42116
44119
  }
42117
44120
  });
@@ -42152,6 +44155,7 @@ ${usage_default}`;
42152
44155
  dispose() {
42153
44156
  if (disposed) return;
42154
44157
  disposed = true;
44158
+ questions.dispose();
42155
44159
  usageNotificationDispose();
42156
44160
  adapterDispose?.();
42157
44161
  adapterDispose = null;
@@ -42161,6 +44165,7 @@ ${usage_default}`;
42161
44165
  disposeReasoningSoftWrap();
42162
44166
  delegationMention?.dispose();
42163
44167
  sidebarAgentIcons.dispose();
44168
+ nativeScheduleControls.dispose();
42164
44169
  settingsLifecycle.dispose();
42165
44170
  document.removeEventListener("beforeinput", onBeforeInput, true);
42166
44171
  document.removeEventListener("submit", onSubmit, true);
@@ -42232,7 +44237,12 @@ ${usage_default}`;
42232
44237
 
42233
44238
  lucide/dist/esm/defaultAttributes.mjs:
42234
44239
  lucide/dist/esm/createElement.mjs:
44240
+ lucide/dist/esm/icons/check.mjs:
44241
+ lucide/dist/esm/icons/message-circle-question-mark.mjs:
44242
+ lucide/dist/esm/icons/pencil.mjs:
44243
+ lucide/dist/esm/icons/x.mjs:
42235
44244
  lucide/dist/esm/icons/boxes.mjs:
44245
+ lucide/dist/esm/icons/calendar-clock.mjs:
42236
44246
  lucide/dist/esm/icons/circle-check.mjs:
42237
44247
  lucide/dist/esm/icons/chevron-down.mjs:
42238
44248
  lucide/dist/esm/icons/chevron-left.mjs:
@@ -42267,11 +44277,10 @@ lucide/dist/esm/icons/terminal.mjs:
42267
44277
  lucide/dist/esm/icons/scroll-text.mjs:
42268
44278
  lucide/dist/esm/icons/search.mjs:
42269
44279
  lucide/dist/esm/icons/circle-question-mark.mjs:
42270
- lucide/dist/esm/icons/x.mjs:
42271
44280
  lucide/dist/esm/icons/users.mjs:
42272
44281
  lucide/dist/esm/icons/plus.mjs:
42273
44282
  lucide/dist/esm/icons/circle-alert.mjs:
42274
- lucide/dist/esm/icons/check.mjs:
44283
+ lucide/dist/esm/icons/activity.mjs:
42275
44284
  lucide/dist/esm/icons/lock.mjs:
42276
44285
  lucide/dist/esm/icons/shield.mjs:
42277
44286
  lucide/dist/esm/icons/shield-alert.mjs: