@codexhost/cli-darwin-x64 0.12.0 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -71,6 +71,15 @@
71
71
  get(composer) {
72
72
  return this.#state(composer);
73
73
  }
74
+ /** Release the DOM identity while retaining configuration owned by a target.
75
+ * A cloud composer may reuse this element before a different native draft.
76
+ * A successful replacement transfer retains the shared submission marker.
77
+ */
78
+ detach(composer, preservePendingSubmission = false) {
79
+ const state = this.#states.get(composer);
80
+ if (state && !preservePendingSubmission) this.#pendingSubmissions.delete(state);
81
+ this.#states.delete(composer);
82
+ }
74
83
  mount(composer, target, preferredNewThreadAgent) {
75
84
  const bound = this.#targetState(target);
76
85
  if (bound) {
@@ -581,11 +590,11 @@
581
590
  list,
582
591
  save: (draft, previous, signal) => mutate(previous, draft, signal),
583
592
  remove: (previous, signal) => mutate(previous, null, signal),
584
- async connect(hostId, enabled, signal) {
585
- await request("set-remote-connection-auto-connect", { hostId, autoConnect: enabled }, signal);
593
+ async connect(hostId2, enabled, signal) {
594
+ await request("set-remote-connection-auto-connect", { hostId: hostId2, autoConnect: enabled }, signal);
586
595
  },
587
- async state(hostId, signal) {
588
- const result = await request("app-server-connection-state", { hostId }, signal);
596
+ async state(hostId2, signal) {
597
+ const result = await request("app-server-connection-state", { hostId: hostId2 }, signal);
589
598
  if (!record(result) || typeof result.state !== "string")
590
599
  throw new Error("Invalid Codex connection state");
591
600
  return {
@@ -629,7 +638,7 @@
629
638
  }
630
639
  const control = {
631
640
  ssh: createCodexSshClient(ownerWindow),
632
- async setup(connection, action, version2) {
641
+ async setup(connection, action, version2, uninstallPackage) {
633
642
  const client = getClient("local");
634
643
  if (!client?.setupSsh)
635
644
  throw new Error("SSH installation is unavailable; update local codexhost and restart");
@@ -638,20 +647,21 @@
638
647
  port: connection.sshPort,
639
648
  identity: connection.identity,
640
649
  action,
641
- version: version2 ?? null
650
+ version: version2 ?? null,
651
+ ...action === "uninstall" ? { uninstallPackage: uninstallPackage ?? false } : {}
642
652
  });
643
653
  },
644
- async runtime(hostId) {
645
- const client = getClient(hostId);
654
+ async runtime(hostId2) {
655
+ const client = getClient(hostId2);
646
656
  if (!client?.runtimeStatus)
647
657
  throw new Error(
648
658
  "Version management is unavailable; update codexhost on this host and reconnect"
649
659
  );
650
660
  return bounded(client.runtimeStatus());
651
661
  },
652
- async update(hostId, version2) {
653
- if (hostId === "local") throw new Error("Choose a remote SSH connection");
654
- const client = getClient(hostId);
662
+ async update(hostId2, version2) {
663
+ if (hostId2 === "local") throw new Error("Choose a remote SSH connection");
664
+ const client = getClient(hostId2);
655
665
  if (!client?.updateRemote)
656
666
  throw new Error("Remote update is unavailable; update this remote once and reconnect");
657
667
  return bounded(client.updateRemote(version2));
@@ -660,6 +670,111 @@
660
670
  return control;
661
671
  }
662
672
 
673
+ // ../desktop-control/dist/renderer-react-ownership.js
674
+ var REACT_FIBER_WALK_LIMIT_EVENT = "codexhost:react-fiber-walk-limit";
675
+ function committedReactAncestors(value) {
676
+ const MAX_VISITED_FIBERS = 2e5;
677
+ const fiber = (value2) => typeof value2 === "object" && value2 !== null ? value2 : null;
678
+ const exhausted = () => {
679
+ const target = globalThis;
680
+ if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function")
681
+ target.dispatchEvent(new CustomEvent("codexhost:react-fiber-walk-limit", {
682
+ detail: { limit: MAX_VISITED_FIBERS }
683
+ }));
684
+ return [];
685
+ };
686
+ const first = fiber(value);
687
+ if (!first)
688
+ return [];
689
+ const previous = [];
690
+ const seen = /* @__PURE__ */ new Set();
691
+ for (let node2 = first; node2; node2 = fiber(node2.return)) {
692
+ if (seen.has(node2))
693
+ return [];
694
+ if (seen.size >= MAX_VISITED_FIBERS)
695
+ return exhausted();
696
+ seen.add(node2);
697
+ previous.push(node2);
698
+ }
699
+ const rootState = fiber(previous.at(-1)?.stateNode);
700
+ if (!rootState || !("current" in rootState))
701
+ return previous;
702
+ const current = fiber(rootState.current);
703
+ if (!current)
704
+ return [];
705
+ const alternate = fiber(first.alternate);
706
+ const path = [current];
707
+ seen.clear();
708
+ seen.add(current);
709
+ for (let index = previous.length - 2; index >= 0; index -= 1) {
710
+ const expected = previous[index];
711
+ const expectedAlternate = fiber(expected?.alternate);
712
+ let child = fiber(path.at(-1)?.child);
713
+ let matched = false;
714
+ while (child && !seen.has(child) && seen.size < MAX_VISITED_FIBERS) {
715
+ seen.add(child);
716
+ if (child === expected || child === expectedAlternate) {
717
+ matched = true;
718
+ break;
719
+ }
720
+ child = fiber(child.sibling);
721
+ }
722
+ if (!matched || !child)
723
+ break;
724
+ path.push(child);
725
+ }
726
+ if (path.length === previous.length && (path.at(-1) === first || path.at(-1) === alternate)) {
727
+ return path.reverse();
728
+ }
729
+ const stack = [{ node: current, parent: null }];
730
+ seen.clear();
731
+ while (stack.length > 0 && seen.size < MAX_VISITED_FIBERS) {
732
+ const entry = stack.pop();
733
+ if (!entry)
734
+ break;
735
+ if (seen.has(entry.node))
736
+ return [];
737
+ seen.add(entry.node);
738
+ if (entry.node === first || entry.node === alternate) {
739
+ const ancestors = [];
740
+ for (let cursor = entry; cursor; cursor = cursor.parent)
741
+ ancestors.push(cursor.node);
742
+ return ancestors;
743
+ }
744
+ const sibling = entry.parent && fiber(entry.node.sibling);
745
+ if (sibling)
746
+ stack.push({ node: sibling, parent: entry.parent });
747
+ const child = fiber(entry.node.child);
748
+ if (child)
749
+ stack.push({ node: child, parent: entry });
750
+ }
751
+ return stack.length > 0 ? exhausted() : [];
752
+ }
753
+
754
+ // src/renderer-composer-kind.ts
755
+ function isOrbitComposer(composer) {
756
+ let element = composer.querySelector('[contenteditable="true"], textarea, [role="textbox"]') ?? composer;
757
+ for (let depth = 0; element && depth < 12; depth += 1) {
758
+ const key = Object.getOwnPropertyNames(element).find(
759
+ (name) => name.startsWith("__reactFiber$")
760
+ );
761
+ if (key) {
762
+ for (const fiber of committedReactAncestors(
763
+ Object.getOwnPropertyDescriptor(element, key)?.value
764
+ )) {
765
+ const props = fiber.memoizedProps;
766
+ if (typeof props === "object" && props !== null && "isOrbit" in props) {
767
+ const value = props.isOrbit;
768
+ if (typeof value === "boolean") return value;
769
+ }
770
+ }
771
+ return false;
772
+ }
773
+ element = element.parentElement;
774
+ }
775
+ return false;
776
+ }
777
+
663
778
  // ../../node_modules/zod/v4/classic/external.js
664
779
  var external_exports = {};
665
780
  __export(external_exports, {
@@ -15247,6 +15362,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15247
15362
  initializeOnly: external_exports.boolean().optional()
15248
15363
  });
15249
15364
 
15365
+ // ../shared-contracts/dist/ids.js
15366
+ var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
15367
+ message: "Identifier must not be empty or whitespace"
15368
+ });
15369
+ var harnessIdSchema = opaqueIdSchema.brand();
15370
+ var hostThreadIdSchema = opaqueIdSchema.brand();
15371
+ var hostTurnIdSchema = opaqueIdSchema.brand();
15372
+ var hostItemIdSchema = opaqueIdSchema.brand();
15373
+ var hostInteractionIdSchema = opaqueIdSchema.brand();
15374
+
15375
+ // ../shared-contracts/dist/thread-prewarm.js
15376
+ var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
15377
+ var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
15378
+
15250
15379
  // ../shared-contracts/dist/console.js
15251
15380
  var consoleAnnouncementSchema = external_exports.strictObject({
15252
15381
  title: external_exports.string().trim().min(1).max(200),
@@ -15260,6 +15389,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15260
15389
  url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
15261
15390
  });
15262
15391
  var CONSOLE_HOST_METHODS = Object.freeze([
15392
+ "codexhost/console/remote-connections",
15393
+ "codexhost/runtime/status",
15394
+ "codexhost/remote/ssh-setup",
15263
15395
  "codexhost/harness/plugins/list",
15264
15396
  "codexhost/harness/display-settings/get",
15265
15397
  "codexhost/harness/display-settings/set",
@@ -15328,16 +15460,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15328
15460
  inactiveMs: external_exports.number().nonnegative()
15329
15461
  }));
15330
15462
 
15331
- // ../shared-contracts/dist/ids.js
15332
- var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
15333
- message: "Identifier must not be empty or whitespace"
15334
- });
15335
- var harnessIdSchema = opaqueIdSchema.brand();
15336
- var hostThreadIdSchema = opaqueIdSchema.brand();
15337
- var hostTurnIdSchema = opaqueIdSchema.brand();
15338
- var hostItemIdSchema = opaqueIdSchema.brand();
15339
- var hostInteractionIdSchema = opaqueIdSchema.brand();
15340
-
15341
15463
  // ../shared-contracts/dist/manual-compaction.js
15342
15464
  var THREAD_MANUAL_COMPACTION_STARTED_METHOD = "codexhost/thread/manual-compaction/started";
15343
15465
  var threadManualCompactionStartedSchema = external_exports.strictObject({
@@ -15708,8 +15830,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15708
15830
  message: "Cross-cwd Fork requires exact history Fork support"
15709
15831
  });
15710
15832
  var harnessPermissionModeScopeSchema = external_exports.enum(["live", "atCreate"]);
15711
- function permissionModeFixedAtCreate(configuration2) {
15712
- return configuration2.permissionModeScope === "atCreate";
15833
+ function permissionModeFixedAtCreate(configuration) {
15834
+ return configuration.permissionModeScope === "atCreate";
15713
15835
  }
15714
15836
  var harnessSessionCapabilitiesSchema = external_exports.object({
15715
15837
  configuration: external_exports.object({
@@ -16316,14 +16438,80 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16316
16438
  hostname: external_exports.string().min(1).max(1024).refine((value) => !value.startsWith("-") && !/\s/u.test(value)),
16317
16439
  port: external_exports.number().int().min(1).max(65535).nullable(),
16318
16440
  identity: external_exports.string().max(4096).nullable(),
16319
- action: external_exports.enum(["inspect", "install", "update", "repair"]),
16441
+ action: external_exports.enum(["inspect", "install", "update", "repair", "uninstall"]),
16442
+ uninstallPackage: external_exports.boolean().optional(),
16320
16443
  version: external_exports.string().regex(/^\d+\.\d+\.\d+$/u).nullable()
16321
16444
  }).strict();
16322
16445
  var remoteSshSetupResultSchema = external_exports.object({ state: external_exports.enum(["installed", "not-installed"]) }).strict();
16323
16446
 
16447
+ // ../shared-contracts/dist/remote-connections.js
16448
+ var hostId = external_exports.string().min(1).max(1024);
16449
+ var codexSshConnectionSchema = external_exports.object({
16450
+ hostId,
16451
+ displayName: external_exports.string().min(1).max(1024),
16452
+ source: external_exports.enum(["codex-managed", "discovered"]),
16453
+ sshAlias: external_exports.string().max(1024).nullable(),
16454
+ sshHost: external_exports.string().min(1).max(1024),
16455
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
16456
+ identity: external_exports.string().max(4096).nullable(),
16457
+ autoConnect: external_exports.boolean(),
16458
+ connectionAnalyticsId: external_exports.string().max(1024).optional()
16459
+ });
16460
+ var codexSshDraftSchema = external_exports.strictObject({
16461
+ displayName: external_exports.string().min(1).max(1024),
16462
+ hostname: external_exports.string().min(1).max(1024),
16463
+ sshPort: external_exports.number().int().min(1).max(65535).nullable(),
16464
+ identity: external_exports.string().max(4096).nullable()
16465
+ });
16466
+ var remoteConnectionsRequestSchema = external_exports.discriminatedUnion("action", [
16467
+ external_exports.strictObject({ action: external_exports.literal("list") }),
16468
+ external_exports.strictObject({
16469
+ action: external_exports.literal("save"),
16470
+ draft: codexSshDraftSchema,
16471
+ previous: codexSshConnectionSchema.nullable()
16472
+ }),
16473
+ external_exports.strictObject({ action: external_exports.literal("remove"), previous: codexSshConnectionSchema }),
16474
+ external_exports.strictObject({ action: external_exports.literal("connect"), hostId, enabled: external_exports.boolean() }),
16475
+ external_exports.strictObject({ action: external_exports.literal("state"), hostId }),
16476
+ external_exports.strictObject({ action: external_exports.literal("runtime"), hostId }),
16477
+ external_exports.strictObject({
16478
+ action: external_exports.literal("update"),
16479
+ hostId: hostId.refine((id) => id !== "local"),
16480
+ version: remoteUpdateParamsSchema.shape.version
16481
+ })
16482
+ ]);
16483
+ var remoteConnectionsReplySchema = external_exports.union([
16484
+ external_exports.strictObject({ result: jsonValueSchema }),
16485
+ external_exports.strictObject({ error: external_exports.strictObject({ code: external_exports.number().int(), message: external_exports.string() }) })
16486
+ ]);
16487
+
16324
16488
  // ../shared-contracts/dist/index.js
16325
16489
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
16326
16490
 
16491
+ // src/remote-connections-request.ts
16492
+ async function handleRemoteConnectionsRequest(control, input) {
16493
+ const request = remoteConnectionsRequestSchema.parse(input);
16494
+ switch (request.action) {
16495
+ case "list":
16496
+ return control.ssh.list();
16497
+ case "save":
16498
+ await control.ssh.save(request.draft, request.previous);
16499
+ return null;
16500
+ case "remove":
16501
+ await control.ssh.remove(request.previous);
16502
+ return null;
16503
+ case "connect":
16504
+ await control.ssh.connect(request.hostId, request.enabled);
16505
+ return null;
16506
+ case "state":
16507
+ return control.ssh.state(request.hostId);
16508
+ case "runtime":
16509
+ return control.runtime(request.hostId);
16510
+ case "update":
16511
+ return control.update(request.hostId, request.version);
16512
+ }
16513
+ }
16514
+
16327
16515
  // src/agent-group-preference.ts
16328
16516
  var AGENT_GROUP_PREFERENCE_STORAGE_KEY = "codexhost.agentGroupPreference.v1";
16329
16517
  var EXTERNAL_AGENTS = KNOWN_RENDERER_AGENTS.filter(
@@ -16733,6 +16921,35 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16733
16921
  ["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }]
16734
16922
  ];
16735
16923
 
16924
+ // ../../node_modules/lucide/dist/esm/icons/eye.mjs
16925
+ var Eye = [
16926
+ [
16927
+ "path",
16928
+ {
16929
+ d: "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"
16930
+ }
16931
+ ],
16932
+ ["circle", { cx: "12", cy: "12", r: "3" }]
16933
+ ];
16934
+
16935
+ // ../../node_modules/lucide/dist/esm/icons/eye-off.mjs
16936
+ var EyeOff = [
16937
+ [
16938
+ "path",
16939
+ {
16940
+ d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"
16941
+ }
16942
+ ],
16943
+ ["path", { d: "M14.084 14.158a3 3 0 0 1-4.242-4.242" }],
16944
+ [
16945
+ "path",
16946
+ {
16947
+ d: "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"
16948
+ }
16949
+ ],
16950
+ ["path", { d: "m2 2 20 20" }]
16951
+ ];
16952
+
16736
16953
  // ../../node_modules/lucide/dist/esm/icons/ellipsis.mjs
16737
16954
  var Ellipsis = [
16738
16955
  ["circle", { cx: "12", cy: "12", r: "1" }],
@@ -16967,6 +17184,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16967
17184
  "info",
16968
17185
  "external-link",
16969
17186
  "refresh",
17187
+ "eye",
17188
+ "eye-off",
16970
17189
  "unavailable",
16971
17190
  "alert",
16972
17191
  "check",
@@ -17016,6 +17235,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17016
17235
  info: Info,
17017
17236
  "external-link": ExternalLink,
17018
17237
  refresh: RefreshCw,
17238
+ eye: Eye,
17239
+ "eye-off": EyeOff,
17019
17240
  unavailable: CircleOff,
17020
17241
  alert: TriangleAlert,
17021
17242
  check: CircleCheck,
@@ -17349,7 +17570,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17349
17570
  }
17350
17571
 
17351
17572
  // src/settings/harness-installation-panel.ts
17352
- function createHarnessInstallationPanel(document2, agent, hostId, messages, copy, installation) {
17573
+ function createHarnessInstallationPanel(document2, agent, hostId2, messages, copy, installation) {
17353
17574
  const zh = messages.locale === "zh-CN";
17354
17575
  const guide = harnessInstallationGuide(agent, messages.locale);
17355
17576
  const panel = document2.createElement("div");
@@ -17359,7 +17580,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17359
17580
  p.textContent = text;
17360
17581
  panel.append(p);
17361
17582
  };
17362
- if (hostId !== "local") {
17583
+ if (hostId2 !== "local") {
17363
17584
  paragraph(zh ? "\u8BF7\u5728\u8FDC\u7A0B Host \u4E0A\u5B89\u88C5\u3002" : "Install on the remote Host.");
17364
17585
  }
17365
17586
  if (guide.before) paragraph(guide.before);
@@ -17600,9 +17821,32 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17600
17821
  }
17601
17822
  };
17602
17823
  update.addEventListener("click", () => void run("update"));
17603
- signal.addEventListener("abort", render, { once: true });
17824
+ const owner = document2.defaultView;
17825
+ let checkFrame = null;
17826
+ let checkTimer = null;
17827
+ signal.addEventListener(
17828
+ "abort",
17829
+ () => {
17830
+ if (checkFrame !== null) owner?.cancelAnimationFrame(checkFrame);
17831
+ if (checkTimer !== null) owner?.clearTimeout(checkTimer);
17832
+ render();
17833
+ },
17834
+ { once: true }
17835
+ );
17836
+ status.textContent = messages.harnessVersionChecking;
17604
17837
  render();
17605
- void run("check");
17838
+ if (!signal.aborted && owner?.requestAnimationFrame) {
17839
+ checkFrame = owner.requestAnimationFrame(() => {
17840
+ checkFrame = null;
17841
+ if (signal.aborted) return;
17842
+ checkTimer = owner.setTimeout(() => {
17843
+ checkTimer = null;
17844
+ void run("check");
17845
+ }, 0);
17846
+ });
17847
+ } else {
17848
+ void run("check");
17849
+ }
17606
17850
  return panel;
17607
17851
  }
17608
17852
 
@@ -17627,11 +17871,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17627
17871
  if (availability === "notInstalled") return "setup";
17628
17872
  return "failed";
17629
17873
  }
17630
- function diagnosticText(hostId, item) {
17874
+ function diagnosticText(hostId2, item) {
17631
17875
  const error51 = item.error;
17632
17876
  return [
17633
17877
  "codexhost connection diagnostics",
17634
- `host: ${hostId}`,
17878
+ `host: ${hostId2}`,
17635
17879
  `agent: ${item.name}`,
17636
17880
  `status: ${item.availability}`,
17637
17881
  ...error51 ? [
@@ -17666,10 +17910,10 @@ ${error51.stderrTail}`] : []
17666
17910
  () => showCopyButtonFeedback(button, messages.connectionCopyFailed, restoreLabel)
17667
17911
  );
17668
17912
  }
17669
- function connectionHostName(hostId, messages) {
17670
- if (hostId === "local") return messages.connectionLocalHost;
17671
- const separator = hostId.lastIndexOf(":");
17672
- const encodedName = separator >= 0 ? hostId.slice(separator + 1) : hostId;
17913
+ function connectionHostName(hostId2, messages) {
17914
+ if (hostId2 === "local") return messages.connectionLocalHost;
17915
+ const separator = hostId2.lastIndexOf(":");
17916
+ const encodedName = separator >= 0 ? hostId2.slice(separator + 1) : hostId2;
17673
17917
  try {
17674
17918
  return decodeURIComponent(encodedName);
17675
17919
  } catch {
@@ -17864,7 +18108,7 @@ ${error51.stderrTail}`] : []
17864
18108
  header.append(identity, status);
17865
18109
  return header;
17866
18110
  }
17867
- function renderConnectionInspector(document2, inspector, item, hostId, messages, diagnostics, existingLaunchControls, refresh) {
18111
+ function renderConnectionInspector(document2, inspector, item, hostId2, messages, diagnostics, existingLaunchControls, refresh) {
17868
18112
  inspector.replaceChildren(createInspectorHeader(document2, item, messages));
17869
18113
  const body = document2.createElement("div");
17870
18114
  body.className = "settings-connection-inspector__body";
@@ -17894,7 +18138,7 @@ ${error51.stderrTail}`] : []
17894
18138
  createHarnessInstallationPanel(
17895
18139
  document2,
17896
18140
  item.agentSnapshot.agent,
17897
- hostId,
18141
+ hostId2,
17898
18142
  messages,
17899
18143
  (button, command, label) => copyDiagnosticsToClipboard(document2, button, command, messages, label),
17900
18144
  item.install ? {
@@ -17933,7 +18177,7 @@ ${error51.stderrTail}`] : []
17933
18177
  copy.type = "button";
17934
18178
  copy.className = "settings-command-button settings-command-button--secondary";
17935
18179
  setCopyButtonLabel(copy, messages.connectionCopyDetails);
17936
- const report = diagnosticText(hostId, item);
18180
+ const report = diagnosticText(hostId2, item);
17937
18181
  copy.addEventListener("click", () => {
17938
18182
  copyDiagnosticsToClipboard(document2, copy, report, messages, messages.connectionCopyDetails);
17939
18183
  });
@@ -17986,10 +18230,10 @@ ${error51.stderrTail}`] : []
17986
18230
  const agent = item.agentSnapshot?.agent;
17987
18231
  const getLaunchSettings = diagnostics?.getLaunchSettings?.bind(diagnostics);
17988
18232
  const setLaunchSettings = diagnostics?.setLaunchSettings?.bind(diagnostics);
17989
- if (hostId === "local" && (agent === "zcode" || agent === "workbuddy") && getLaunchSettings && setLaunchSettings) {
18233
+ if (hostId2 === "local" && (agent === "zcode" || agent === "workbuddy") && getLaunchSettings && setLaunchSettings) {
17990
18234
  launchControls = existingLaunchControls ?? createHarnessLaunchControls(document2, messages, agent, {
17991
- get: () => getLaunchSettings(hostId, agent),
17992
- set: (path) => setLaunchSettings(hostId, agent, path)
18235
+ get: () => getLaunchSettings(hostId2, agent),
18236
+ set: (path) => setLaunchSettings(hostId2, agent, path)
17993
18237
  });
17994
18238
  body.append(launchControls);
17995
18239
  }
@@ -18046,7 +18290,7 @@ ${error51.stderrTail}`] : []
18046
18290
  button.addEventListener("click", onReset);
18047
18291
  return button;
18048
18292
  }
18049
- function createConnectionsSettingsPage(messages, getDiagnostics, groupPreference = getSharedAgentGroupPreferenceStore()) {
18293
+ function createConnectionsSettingsPage(messages, getDiagnostics, groupPreference = getSharedAgentGroupPreferenceStore(), getRemoteConnections = () => null) {
18050
18294
  return Object.freeze({
18051
18295
  id: "connections",
18052
18296
  label: messages.pageLabels.connections,
@@ -18081,8 +18325,33 @@ ${error51.stderrTail}`] : []
18081
18325
  let launchControls = null;
18082
18326
  const versionPanels = /* @__PURE__ */ new Map();
18083
18327
  const updatingVersions = /* @__PURE__ */ new Set();
18328
+ const hostNames = /* @__PURE__ */ new Map();
18084
18329
  let latestSnapshot = null;
18085
18330
  let disposeHostScroller = () => void 0;
18331
+ let disposed = false;
18332
+ let renderQueued = false;
18333
+ let renderFrame = null;
18334
+ const scheduleRender = () => {
18335
+ if (disposed || context.signal.aborted || renderQueued) return;
18336
+ renderQueued = true;
18337
+ const flush = () => {
18338
+ renderFrame = null;
18339
+ renderQueued = false;
18340
+ if (!disposed && !context.signal.aborted) {
18341
+ render(diagnostics?.snapshot() ?? latestSnapshot);
18342
+ }
18343
+ };
18344
+ if (document2.defaultView?.requestAnimationFrame) {
18345
+ renderFrame = document2.defaultView.requestAnimationFrame(flush);
18346
+ } else {
18347
+ queueMicrotask(flush);
18348
+ }
18349
+ };
18350
+ const cancelRender = () => {
18351
+ disposed = true;
18352
+ if (renderFrame !== null) document2.defaultView?.cancelAnimationFrame(renderFrame);
18353
+ renderFrame = null;
18354
+ };
18086
18355
  const diagnostics = getDiagnostics();
18087
18356
  const installs = diagnostics ? harnessInstallStore(diagnostics) : null;
18088
18357
  const runRefresh = () => {
@@ -18172,7 +18441,7 @@ ${error51.stderrTail}`] : []
18172
18441
  tab.setAttribute("aria-controls", panelId);
18173
18442
  tab.setAttribute("aria-selected", String(host.hostId === selectedHost.hostId));
18174
18443
  tab.tabIndex = host.hostId === selectedHost.hostId ? 0 : -1;
18175
- const hostName = connectionHostName(host.hostId, messages);
18444
+ const hostName = hostNames.get(host.hostId) || connectionHostName(host.hostId, messages);
18176
18445
  tab.textContent = hostName;
18177
18446
  tab.title = host.active ? `${hostName} \xB7 ${messages.connectionActiveHost}` : hostName;
18178
18447
  tab.addEventListener("click", () => {
@@ -18266,14 +18535,14 @@ ${error51.stderrTail}`] : []
18266
18535
  const key = JSON.stringify([selectedHost.hostId, agent]);
18267
18536
  let panel = versionPanels.get(key);
18268
18537
  if (!panel) {
18269
- const hostId = selectedHost.hostId;
18538
+ const hostId2 = selectedHost.hostId;
18270
18539
  panel = createHarnessVersionPanel(document2, messages, context.signal, agent, {
18271
18540
  async run(action) {
18272
- if (action !== "update") return installation(hostId, agent, action);
18541
+ if (action !== "update") return installation(hostId2, agent, action);
18273
18542
  updatingVersions.add(key);
18274
18543
  if (diagnostics) render(diagnostics.snapshot());
18275
18544
  try {
18276
- return await installation(hostId, agent, action);
18545
+ return await installation(hostId2, agent, action);
18277
18546
  } finally {
18278
18547
  updatingVersions.delete(key);
18279
18548
  if (!context.signal.aborted && diagnostics) render(diagnostics.snapshot());
@@ -18465,20 +18734,31 @@ ${error51.stderrTail}`] : []
18465
18734
  }
18466
18735
  };
18467
18736
  render(diagnostics?.snapshot() ?? null);
18468
- const unsubscribeGroup = groupPreference.subscribe(
18469
- () => render(diagnostics?.snapshot() ?? latestSnapshot)
18737
+ void getRemoteConnections()?.ssh.list(context.signal).then(
18738
+ (connections) => {
18739
+ if (context.signal.aborted) return;
18740
+ for (const connection of connections) {
18741
+ hostNames.set(connection.hostId, connection.displayName.trim());
18742
+ }
18743
+ render(diagnostics?.snapshot() ?? null);
18744
+ },
18745
+ () => {
18746
+ }
18470
18747
  );
18748
+ const unsubscribeGroup = groupPreference.subscribe(scheduleRender);
18471
18749
  if (!diagnostics) {
18472
18750
  refresh.disabled = true;
18473
18751
  return () => {
18752
+ cancelRender();
18474
18753
  disposeHostScroller();
18475
18754
  unsubscribeGroup();
18476
18755
  };
18477
18756
  }
18478
18757
  refresh.addEventListener("click", runRefresh);
18479
- const unsubscribe = diagnostics.subscribe(() => render(diagnostics.snapshot()));
18480
- const unsubscribeInstalls = installs?.subscribe(() => render(diagnostics.snapshot()));
18758
+ const unsubscribe = diagnostics.subscribe(scheduleRender);
18759
+ const unsubscribeInstalls = installs?.subscribe(scheduleRender);
18481
18760
  return () => {
18761
+ cancelRender();
18482
18762
  disposeHostScroller();
18483
18763
  unsubscribeInstalls?.();
18484
18764
  unsubscribe();
@@ -18490,9 +18770,10 @@ ${error51.stderrTail}`] : []
18490
18770
 
18491
18771
  // src/settings/credential-import-messages.ts
18492
18772
  var credentialImportEnglish = {
18493
- column: "Use in Harness",
18494
18773
  sectionTitle: "Accounts in Pi",
18495
- sectionEmpty: "No logins in Pi yet. Use the Pi mark on a Codex or Grok account above to import one.",
18774
+ sectionHint: "Copy a local Codex or Grok login into a Pi model entry.",
18775
+ sectionImport: "Import account",
18776
+ sectionEmpty: "No logins in Pi yet. Use \u201CImport account\u201D, or \u201CImport into Pi\u201D on a Codex or Grok account above.",
18496
18777
  rowReimport: "Copy again",
18497
18778
  rowRemove: "Remove",
18498
18779
  othersTitle: "Pi's own logins",
@@ -18505,6 +18786,8 @@ ${error51.stderrTail}`] : []
18505
18786
  entry: "Entry in Pi",
18506
18787
  name: "Model entry name",
18507
18788
  source: "Source account",
18789
+ sourceCurrent: "Current login",
18790
+ sourceImported: "Already in Pi as {name}/\u2026; another entry can be added",
18508
18791
  preview: "Creates {name}/\u2026 in Pi. Existing Provider configurations remain unchanged.",
18509
18792
  warning: "Copies the current authorization once; it does not synchronize logins or add quota. Pi and the original app may refresh the same token, which can require signing in again. Usage follows this Provider's billing rules.",
18510
18793
  confirm: "Confirm import",
@@ -18520,9 +18803,10 @@ ${error51.stderrTail}`] : []
18520
18803
  close: "Done"
18521
18804
  };
18522
18805
  var credentialImportChinese = {
18523
- column: "\u7528\u4E8E Harness",
18524
18806
  sectionTitle: "Pi \u4E2D\u7684\u8D26\u53F7",
18525
- sectionEmpty: "Pi \u4E2D\u8FD8\u6CA1\u6709\u767B\u5F55\u3002\u70B9\u51FB\u4E0A\u65B9 Codex \u6216 Grok \u8D26\u53F7\u884C\u7684 Pi \u56FE\u6807\u5373\u53EF\u5BFC\u5165\u3002",
18807
+ sectionHint: "\u628A Codex\u3001Grok \u7684\u672C\u5730\u767B\u5F55\u590D\u5236\u6210 Pi \u7684\u6A21\u578B\u5165\u53E3",
18808
+ sectionImport: "\u5BFC\u5165\u8D26\u53F7",
18809
+ sectionEmpty: "Pi \u4E2D\u8FD8\u6CA1\u6709\u767B\u5F55\u3002\u70B9\u51FB\u300C\u5BFC\u5165\u8D26\u53F7\u300D\uFF0C\u6216\u4E0A\u65B9 Codex\u3001Grok \u8D26\u53F7\u884C\u7684\u300C\u5BFC\u5165\u5230 Pi\u300D\u5373\u53EF\u5BFC\u5165\u3002",
18526
18810
  rowReimport: "\u91CD\u65B0\u5BFC\u5165",
18527
18811
  rowRemove: "\u79FB\u9664",
18528
18812
  othersTitle: "Pi \u81EA\u6709\u914D\u7F6E",
@@ -18535,6 +18819,8 @@ ${error51.stderrTail}`] : []
18535
18819
  entry: "Pi \u4E2D\u7684\u5165\u53E3",
18536
18820
  name: "\u6A21\u578B\u5165\u53E3\u540D\u79F0",
18537
18821
  source: "\u6765\u6E90\u8D26\u53F7",
18822
+ sourceCurrent: "\u5F53\u524D\u767B\u5F55",
18823
+ sourceImported: "\u5DF2\u5BFC\u5165\u4E3A {name}/\u2026\uFF0C\u53EF\u518D\u65B0\u589E\u4E00\u4E2A\u5165\u53E3",
18538
18824
  preview: "\u5C06\u5728 Pi \u4E2D\u65B0\u589E {name}/\u2026\uFF0C\u4FDD\u7559\u5168\u90E8\u5DF2\u6709 Provider \u914D\u7F6E\u3002",
18539
18825
  warning: "\u4EC5\u590D\u5236\u5F53\u524D\u6388\u6743\uFF0C\u4E0D\u6301\u7EED\u540C\u6B65\u767B\u5F55\uFF0C\u4E5F\u4E0D\u589E\u52A0\u989D\u5EA6\u3002Pi \u4E0E\u539F\u751F\u5DE5\u5177\u5206\u522B\u5237\u65B0\u540C\u4E00\u51ED\u8BC1\u65F6\uFF0C\u53EF\u80FD\u9700\u8981\u91CD\u65B0\u767B\u5F55\u3002\u5B9E\u9645\u7528\u91CF\u9075\u5FAA\u8BE5 Provider \u7684\u8BA1\u8D39\u89C4\u5219\u3002",
18540
18826
  confirm: "\u786E\u8BA4\u5BFC\u5165",
@@ -18660,6 +18946,8 @@ ${error51.stderrTail}`] : []
18660
18946
  accountCreditsFailed: "Could not load limits",
18661
18947
  accountCreditsRetry: "Retry",
18662
18948
  accountCreditsRefresh: "Refresh limits",
18949
+ accountEmailsHide: "Hide emails",
18950
+ accountEmailsShow: "Show emails",
18663
18951
  accountLoadFailed: "Could not load Codex Accounts.",
18664
18952
  accountCreditsUsed: "Used",
18665
18953
  accountCreditsResetAt: "Quota resets: {time}",
@@ -18930,6 +19218,8 @@ ${error51.stderrTail}`] : []
18930
19218
  accountCreditsFailed: "\u989D\u5EA6\u8BFB\u53D6\u5931\u8D25",
18931
19219
  accountCreditsRetry: "\u91CD\u8BD5",
18932
19220
  accountCreditsRefresh: "\u5237\u65B0\u989D\u5EA6",
19221
+ accountEmailsHide: "\u9690\u85CF\u90AE\u7BB1",
19222
+ accountEmailsShow: "\u663E\u793A\u90AE\u7BB1",
18933
19223
  accountLoadFailed: "\u65E0\u6CD5\u52A0\u8F7D Codex \u8D26\u53F7\u3002",
18934
19224
  accountCreditsUsed: "\u5DF2\u7528",
18935
19225
  accountCreditsResetAt: "\u989D\u5EA6\u91CD\u7F6E\u65F6\u95F4\uFF1A{time}",
@@ -22184,10 +22474,11 @@ Codex Fast mode prioritizes requests and may increase usage.`
22184
22474
  return event.key === "Enter" && !event.shiftKey && !event.isComposing;
22185
22475
  }
22186
22476
  function composerForEditor(editor) {
22187
- return editor.closest(CODEX_COMPOSER_SELECTOR);
22477
+ return composerForElement(editor);
22188
22478
  }
22189
22479
  function composerForElement(element) {
22190
- return element.closest(CODEX_COMPOSER_SELECTOR);
22480
+ const composer = element.closest(CODEX_COMPOSER_SELECTOR);
22481
+ return composer && !isOrbitComposer(composer) ? composer : null;
22191
22482
  }
22192
22483
  function isRecord(value) {
22193
22484
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -22673,87 +22964,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
22673
22964
  }
22674
22965
  };
22675
22966
 
22676
- // ../desktop-control/dist/renderer-react-ownership.js
22677
- var REACT_FIBER_WALK_LIMIT_EVENT = "codexhost:react-fiber-walk-limit";
22678
- function committedReactAncestors(value) {
22679
- const MAX_VISITED_FIBERS = 2e5;
22680
- const fiber = (value2) => typeof value2 === "object" && value2 !== null ? value2 : null;
22681
- const exhausted = () => {
22682
- const target = globalThis;
22683
- if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function")
22684
- target.dispatchEvent(new CustomEvent("codexhost:react-fiber-walk-limit", {
22685
- detail: { limit: MAX_VISITED_FIBERS }
22686
- }));
22687
- return [];
22688
- };
22689
- const first = fiber(value);
22690
- if (!first)
22691
- return [];
22692
- const previous = [];
22693
- const seen = /* @__PURE__ */ new Set();
22694
- for (let node2 = first; node2; node2 = fiber(node2.return)) {
22695
- if (seen.has(node2))
22696
- return [];
22697
- if (seen.size >= MAX_VISITED_FIBERS)
22698
- return exhausted();
22699
- seen.add(node2);
22700
- previous.push(node2);
22701
- }
22702
- const rootState = fiber(previous.at(-1)?.stateNode);
22703
- if (!rootState || !("current" in rootState))
22704
- return previous;
22705
- const current = fiber(rootState.current);
22706
- if (!current)
22707
- return [];
22708
- const alternate = fiber(first.alternate);
22709
- const path = [current];
22710
- seen.clear();
22711
- seen.add(current);
22712
- for (let index = previous.length - 2; index >= 0; index -= 1) {
22713
- const expected = previous[index];
22714
- const expectedAlternate = fiber(expected?.alternate);
22715
- let child = fiber(path.at(-1)?.child);
22716
- let matched = false;
22717
- while (child && !seen.has(child) && seen.size < MAX_VISITED_FIBERS) {
22718
- seen.add(child);
22719
- if (child === expected || child === expectedAlternate) {
22720
- matched = true;
22721
- break;
22722
- }
22723
- child = fiber(child.sibling);
22724
- }
22725
- if (!matched || !child)
22726
- break;
22727
- path.push(child);
22728
- }
22729
- if (path.length === previous.length && (path.at(-1) === first || path.at(-1) === alternate)) {
22730
- return path.reverse();
22731
- }
22732
- const stack = [{ node: current, parent: null }];
22733
- seen.clear();
22734
- while (stack.length > 0 && seen.size < MAX_VISITED_FIBERS) {
22735
- const entry = stack.pop();
22736
- if (!entry)
22737
- break;
22738
- if (seen.has(entry.node))
22739
- return [];
22740
- seen.add(entry.node);
22741
- if (entry.node === first || entry.node === alternate) {
22742
- const ancestors = [];
22743
- for (let cursor = entry; cursor; cursor = cursor.parent)
22744
- ancestors.push(cursor.node);
22745
- return ancestors;
22746
- }
22747
- const sibling = entry.parent && fiber(entry.node.sibling);
22748
- if (sibling)
22749
- stack.push({ node: sibling, parent: entry.parent });
22750
- const child = fiber(entry.node.child);
22751
- if (child)
22752
- stack.push({ node: child, parent: entry });
22753
- }
22754
- return stack.length > 0 ? exhausted() : [];
22755
- }
22756
-
22757
22967
  // src/renderer-codex-usage-gate.ts
22758
22968
  var EDITOR_SELECTOR2 = '[contenteditable="true"][role="textbox"]';
22759
22969
  var MAX_HOOKS = 4096;
@@ -23869,7 +24079,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23869
24079
  function isRecord7(value) {
23870
24080
  return value !== null && typeof value === "object" && !Array.isArray(value);
23871
24081
  }
23872
- function installRendererManualCompaction(target, hostId, messages) {
24082
+ function installRendererManualCompaction(target, hostId2, messages) {
23873
24083
  if (!messages || typeof messages.addEventListener !== "function" || typeof messages.removeEventListener !== "function" || !isRecord7(target) || typeof target.registerPendingManualContextCompaction !== "function" || typeof target.getConversation !== "function") {
23874
24084
  return null;
23875
24085
  }
@@ -23879,7 +24089,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
23879
24089
  const listener = (event) => {
23880
24090
  if (event.source != null && event.source !== messages) return;
23881
24091
  const message = event.data;
23882
- if (!isRecord7(message) || message.type !== "mcp-notification" || message.hostId !== hostId || message.method !== THREAD_MANUAL_COMPACTION_STARTED_METHOD) {
24092
+ if (!isRecord7(message) || message.type !== "mcp-notification" || message.hostId !== hostId2 || message.method !== THREAD_MANUAL_COMPACTION_STARTED_METHOD) {
23883
24093
  return;
23884
24094
  }
23885
24095
  const params = threadManualCompactionStartedSchema.safeParse(message.params);
@@ -23903,9 +24113,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
23903
24113
  function createRendererHostClients(readRouting, messages = null) {
23904
24114
  let disposed = false;
23905
24115
  const entries = /* @__PURE__ */ new Map();
23906
- const retire = (hostId) => {
23907
- const entry = entries.get(hostId);
23908
- entries.delete(hostId);
24116
+ const retire = (hostId2) => {
24117
+ const entry = entries.get(hostId2);
24118
+ entries.delete(hostId2);
23909
24119
  for (const cleanup of entry?.cleanups ?? []) {
23910
24120
  try {
23911
24121
  cleanup();
@@ -23955,16 +24165,16 @@ Codex Fast mode prioritizes requests and may increase usage.`
23955
24165
  };
23956
24166
  return {
23957
24167
  forRoute,
23958
- forHost(hostId) {
24168
+ forHost(hostId2) {
23959
24169
  if (disposed) return null;
23960
- const route = readRouting()?.forHost(hostId) ?? null;
23961
- if (!route) retire(hostId);
24170
+ const route = readRouting()?.forHost(hostId2) ?? null;
24171
+ if (!route) retire(hostId2);
23962
24172
  return forRoute(route);
23963
24173
  },
23964
24174
  dispose() {
23965
24175
  if (disposed) return;
23966
24176
  disposed = true;
23967
- for (const hostId of entries.keys()) retire(hostId);
24177
+ for (const hostId2 of entries.keys()) retire(hostId2);
23968
24178
  }
23969
24179
  };
23970
24180
  }
@@ -24073,10 +24283,10 @@ Codex Fast mode prioritizes requests and may increase usage.`
24073
24283
  }
24074
24284
  function sidebarThreadAttributes(element) {
24075
24285
  const taskKey = element.getAttribute(SIDEBAR_THREAD_ID_ATTRIBUTE);
24076
- const hostId = element.getAttribute(SIDEBAR_THREAD_HOST_ID_ATTRIBUTE);
24286
+ const hostId2 = element.getAttribute(SIDEBAR_THREAD_HOST_ID_ATTRIBUTE);
24077
24287
  const rowMarker = element.getAttribute(SIDEBAR_THREAD_ROW_ATTRIBUTE);
24078
- if (taskKey === null || hostId === null || rowMarker === null) return null;
24079
- return { taskKey, hostId, rowMarker };
24288
+ if (taskKey === null || hostId2 === null || rowMarker === null) return null;
24289
+ return { taskKey, hostId: hostId2, rowMarker };
24080
24290
  }
24081
24291
  function draftIdFromSidebarRowElement(element) {
24082
24292
  const attributes = sidebarThreadAttributes(element);
@@ -24088,7 +24298,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24088
24298
  function threadIdFromSidebarRowElement(element) {
24089
24299
  const attributes = sidebarThreadAttributes(element);
24090
24300
  if (!attributes) return null;
24091
- const { taskKey, hostId, rowMarker } = attributes;
24301
+ const { taskKey, hostId: hostId2, rowMarker } = attributes;
24092
24302
  const fiberNames = Object.getOwnPropertyNames(element).filter(
24093
24303
  (name) => name.startsWith("__reactFiber$")
24094
24304
  );
@@ -24103,7 +24313,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24103
24313
  if (isRecord8(props) && isRecord8(props.dataAttributes)) {
24104
24314
  const dataAttributes = props.dataAttributes;
24105
24315
  const threadId = hostThreadIdSchema.safeParse(props.conversationId);
24106
- if (threadId.success && dataAttributes[SIDEBAR_THREAD_ROW_ATTRIBUTE] === rowMarker && dataAttributes[SIDEBAR_THREAD_ID_ATTRIBUTE] === taskKey && dataAttributes[SIDEBAR_THREAD_HOST_ID_ATTRIBUTE] === hostId) {
24316
+ if (threadId.success && dataAttributes[SIDEBAR_THREAD_ROW_ATTRIBUTE] === rowMarker && dataAttributes[SIDEBAR_THREAD_ID_ATTRIBUTE] === taskKey && dataAttributes[SIDEBAR_THREAD_HOST_ID_ATTRIBUTE] === hostId2) {
24107
24317
  candidates.add(threadId.data);
24108
24318
  }
24109
24319
  }
@@ -24253,7 +24463,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24253
24463
  const ownershipRetryTimers = /* @__PURE__ */ new Map();
24254
24464
  let disposed = false;
24255
24465
  let scanScheduled = false;
24256
- const ownershipKey = (hostId, threadId) => JSON.stringify([hostId, threadId]);
24466
+ const ownershipKey = (hostId2, threadId) => JSON.stringify([hostId2, threadId]);
24257
24467
  const scheduleScan = () => {
24258
24468
  if (disposed || scanScheduled) return;
24259
24469
  scanScheduled = true;
@@ -24267,8 +24477,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
24267
24477
  failed.delete(key);
24268
24478
  provisionalCodex.delete(key);
24269
24479
  };
24270
- const scheduleOwnershipRetry = (hostId, threadId) => {
24271
- const key = ownershipKey(hostId, threadId);
24480
+ const scheduleOwnershipRetry = (hostId2, threadId) => {
24481
+ const key = ownershipKey(hostId2, threadId);
24272
24482
  if (disposed || !failed.has(key) && !provisionalCodex.has(key) || pending.has(key) || ownershipRetryTimers.has(key)) {
24273
24483
  return;
24274
24484
  }
@@ -24285,19 +24495,19 @@ Codex Fast mode prioritizes requests and may increase usage.`
24285
24495
  }, delay);
24286
24496
  ownershipRetryTimers.set(key, timer);
24287
24497
  };
24288
- const requestOwnership = (hostId, threadIds, client) => {
24289
- for (const threadId of threadIds) pending.add(ownershipKey(hostId, threadId));
24498
+ const requestOwnership = (hostId2, threadIds, client) => {
24499
+ for (const threadId of threadIds) pending.add(ownershipKey(hostId2, threadId));
24290
24500
  let succeeded = false;
24291
24501
  let retryable = true;
24292
24502
  void Promise.resolve().then(() => client.listThreadOwnership({ threadIds })).then(({ threads }) => {
24293
24503
  if (disposed) return;
24294
24504
  for (const ownership of threads) {
24295
- const key = ownershipKey(hostId, ownership.threadId);
24505
+ const key = ownershipKey(hostId2, ownership.threadId);
24296
24506
  ownershipByThread.set(key, rendererAgentForThreadOwnership(ownership));
24297
24507
  failed.delete(key);
24298
24508
  if (ownership.owner === "codex") {
24299
24509
  provisionalCodex.add(key);
24300
- scheduleOwnershipRetry(hostId, ownership.threadId);
24510
+ scheduleOwnershipRetry(hostId2, ownership.threadId);
24301
24511
  } else {
24302
24512
  clearOwnershipRetry(key);
24303
24513
  }
@@ -24306,11 +24516,11 @@ Codex Fast mode prioritizes requests and may increase usage.`
24306
24516
  }).catch((error51) => {
24307
24517
  if (disposed) return;
24308
24518
  retryable = !(error51 instanceof RendererMethodUnavailableError);
24309
- for (const threadId of threadIds) failed.add(ownershipKey(hostId, threadId));
24519
+ for (const threadId of threadIds) failed.add(ownershipKey(hostId2, threadId));
24310
24520
  }).finally(() => {
24311
- for (const threadId of threadIds) pending.delete(ownershipKey(hostId, threadId));
24521
+ for (const threadId of threadIds) pending.delete(ownershipKey(hostId2, threadId));
24312
24522
  if (retryable) {
24313
- for (const threadId of threadIds) scheduleOwnershipRetry(hostId, threadId);
24523
+ for (const threadId of threadIds) scheduleOwnershipRetry(hostId2, threadId);
24314
24524
  }
24315
24525
  if (succeeded) scheduleScan();
24316
24526
  });
@@ -24324,20 +24534,20 @@ Codex Fast mode prioritizes requests and may increase usage.`
24324
24534
  row.clear();
24325
24535
  continue;
24326
24536
  }
24327
- const hostId = row.hostId();
24328
- if (!hostId) {
24537
+ const hostId2 = row.hostId();
24538
+ if (!hostId2) {
24329
24539
  row.clear();
24330
24540
  continue;
24331
24541
  }
24332
24542
  const threadId = hostThreadIdSchema.safeParse(row.threadId());
24333
24543
  const localAgent = options.getLocalAgent?.({
24334
- hostId,
24544
+ hostId: hostId2,
24335
24545
  threadId: threadId.success ? threadId.data : null,
24336
24546
  draftId: row.draftId()
24337
24547
  });
24338
24548
  if (localAgent !== null && localAgent !== void 0) {
24339
24549
  if (threadId.success) {
24340
- const key2 = ownershipKey(hostId, threadId.data);
24550
+ const key2 = ownershipKey(hostId2, threadId.data);
24341
24551
  ownershipByThread.set(key2, localAgent === "codex" ? null : localAgent);
24342
24552
  clearOwnershipRetry(key2);
24343
24553
  }
@@ -24349,7 +24559,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24349
24559
  row.clear();
24350
24560
  continue;
24351
24561
  }
24352
- const key = ownershipKey(hostId, threadId.data);
24562
+ const key = ownershipKey(hostId2, threadId.data);
24353
24563
  if (ownershipByThread.has(key)) {
24354
24564
  const agent = ownershipByThread.get(key);
24355
24565
  if (agent) row.render(agent);
@@ -24358,28 +24568,28 @@ Codex Fast mode prioritizes requests and may increase usage.`
24358
24568
  }
24359
24569
  row.clear();
24360
24570
  if (!pending.has(key) && !failed.has(key)) {
24361
- let unresolved = unresolvedByHost.get(hostId);
24571
+ let unresolved = unresolvedByHost.get(hostId2);
24362
24572
  if (!unresolved) {
24363
24573
  unresolved = /* @__PURE__ */ new Set();
24364
- unresolvedByHost.set(hostId, unresolved);
24574
+ unresolvedByHost.set(hostId2, unresolved);
24365
24575
  }
24366
24576
  unresolved.add(threadId.data);
24367
24577
  }
24368
24578
  }
24369
- for (const [hostId, unresolved] of unresolvedByHost) {
24370
- const client = options.getClient(hostId);
24579
+ for (const [hostId2, unresolved] of unresolvedByHost) {
24580
+ const client = options.getClient(hostId2);
24371
24581
  if (!client) {
24372
24582
  for (const threadId of unresolved) {
24373
- const key = ownershipKey(hostId, threadId);
24583
+ const key = ownershipKey(hostId2, threadId);
24374
24584
  failed.add(key);
24375
- scheduleOwnershipRetry(hostId, threadId);
24585
+ scheduleOwnershipRetry(hostId2, threadId);
24376
24586
  }
24377
24587
  continue;
24378
24588
  }
24379
24589
  const threadIds = [...unresolved];
24380
24590
  for (let index = 0; index < threadIds.length; index += THREAD_OWNERSHIP_LIST_MAX_LENGTH) {
24381
24591
  requestOwnership(
24382
- hostId,
24592
+ hostId2,
24383
24593
  threadIds.slice(index, index + THREAD_OWNERSHIP_LIST_MAX_LENGTH),
24384
24594
  client
24385
24595
  );
@@ -24984,6 +25194,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
24984
25194
  return draftIds;
24985
25195
  }
24986
25196
  function findComposerModelTarget(composer) {
25197
+ if (isOrbitComposer(composer)) return null;
24987
25198
  const draftIds = findComposerDraftIds(composer);
24988
25199
  const domIdentity = findComposerDomIdentity(composer);
24989
25200
  if (domIdentity.kind === "ambiguous") return null;
@@ -25064,7 +25275,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
25064
25275
  const localClient = disposed ? null : route?.hostId === "local" ? client : clients.forHost("local");
25065
25276
  idleReleaseSync.connect(localClient);
25066
25277
  const connected = !disposed && (client !== null || localClient !== null || (window.__codexhostHostRoutingV1?.knownHostIds?.() ?? []).some(
25067
- (hostId) => window.__codexhostHostRoutingV1?.forHost(hostId) != null
25278
+ (hostId2) => window.__codexhostHostRoutingV1?.forHost(hostId2) != null
25068
25279
  ));
25069
25280
  updateStatus(
25070
25281
  connected ? "ready" : "installing",
@@ -25092,7 +25303,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
25092
25303
  return disposed ? null : route?.hostId ?? window.__codexhostHostRoutingV1?.hostIdForComposer() ?? null;
25093
25304
  },
25094
25305
  knownHostIds: () => disposed ? [] : window.__codexhostHostRoutingV1?.knownHostIds?.() ?? [],
25095
- clientForHost: (hostId) => disposed ? null : clients.forHost(hostId),
25306
+ clientForHost: (hostId2) => disposed ? null : clients.forHost(hostId2),
25096
25307
  listHarnessPlugins: async () => {
25097
25308
  const client = settingsModelClient();
25098
25309
  if (!client.listHarnessPlugins) throw new Error("Harness plugin directory is unavailable");
@@ -25175,7 +25386,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
25175
25386
  window.addEventListener("codexhost:draft-prewarm-policy-changed", handleRoutingPolicyChange);
25176
25387
  currentRequestRoute();
25177
25388
  const applyAgent = (agent, model, thinkingOptionId, permissionModeId, composer) => {
25178
- if (disposed) return false;
25389
+ if (disposed || composer && isOrbitComposer(composer)) return false;
25179
25390
  const selection = modelSelectionForAgent(
25180
25391
  null,
25181
25392
  null,
@@ -25296,8 +25507,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
25296
25507
  KNOWN_RENDERER_AGENTS.filter(
25297
25508
  (agent) => agent !== "codex"
25298
25509
  ).flatMap((agent) => {
25299
- const configuration2 = parseExternalConfiguration(externalByAgent[agent]);
25300
- return configuration2 ? [[agent, configuration2]] : [];
25510
+ const configuration = parseExternalConfiguration(externalByAgent[agent]);
25511
+ return configuration ? [[agent, configuration]] : [];
25301
25512
  })
25302
25513
  );
25303
25514
  return {
@@ -25596,6 +25807,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
25596
25807
 
25597
25808
  // src/settings/remote-failure-messages.ts
25598
25809
  var REMOTE_FAILURE_CHINESE = Object.freeze({
25810
+ "Remote connection management is unavailable. Restart Codex through codexhost": "\u8FDC\u7A0B\u8FDE\u63A5\u7BA1\u7406\u6682\u4E0D\u53EF\u7528\uFF0C\u8BF7\u901A\u8FC7 codexhost \u91CD\u65B0\u542F\u52A8 Codex",
25811
+ "Remote connection request timed out. Refresh before retrying": "\u8FDC\u7A0B\u8FDE\u63A5\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u5237\u65B0\u540E\u518D\u8BD5",
25812
+ "Invalid remote connection request": "\u8FDC\u7A0B\u8FDE\u63A5\u8BF7\u6C42\u65E0\u6548",
25599
25813
  // SSH helper: installing, updating and repairing over SSH.
25600
25814
  "Invalid SSH address or port": "SSH \u5730\u5740\u6216\u7AEF\u53E3\u65E0\u6548",
25601
25815
  "Install requires a published stable version": "\u53EA\u80FD\u5B89\u88C5\u5DF2\u53D1\u5E03\u7684\u6B63\u5F0F\u7248\u672C",
@@ -25605,7 +25819,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
25605
25819
  "This release is not published on npm, or the remote computer cannot reach the registry": "\u8BE5\u7248\u672C\u5C1A\u672A\u53D1\u5E03\u5230 npm\uFF0C\u6216\u8FDC\u7A0B\u7535\u8111\u65E0\u6CD5\u8BBF\u95EE npm \u4ED3\u5E93",
25606
25820
  "codexhost was installed but is not on the remote PATH. Update this remote manually": "codexhost \u5DF2\u5B89\u88C5\uFF0C\u4F46\u4E0D\u5728\u8FDC\u7A0B\u7535\u8111\u7684 PATH \u4E2D\uFF0C\u8BF7\u5728\u8FDC\u7A0B\u7535\u8111\u4E0A\u624B\u52A8\u66F4\u65B0",
25607
25821
  "Only Mac and Linux remote computers are supported": "\u53EA\u652F\u6301 Mac \u548C Linux \u8FDC\u7A0B\u7535\u8111",
25608
- "Node.js, npm or Codex CLI was not found over SSH. Install them on the remote computer and make sure non-interactive SSH sessions have them on PATH": "\u901A\u8FC7 SSH \u627E\u4E0D\u5230 Node.js\u3001npm \u6216 Codex CLI\u3002\u8BF7\u5728\u8FDC\u7A0B\u7535\u8111\u4E0A\u5B89\u88C5\u5B83\u4EEC\uFF0C\u5E76\u786E\u4FDD\u975E\u4EA4\u4E92\u5F0F SSH \u4F1A\u8BDD\u7684 PATH \u4E2D\u5305\u542B\u5B83\u4EEC",
25822
+ "Node.js was not detected over SSH. Install it on the remote computer or add it to the login shell PATH, then retry": "\u901A\u8FC7 SSH \u672A\u68C0\u6D4B\u5230 Node.js\u3002\u8BF7\u5728\u8FDC\u7A0B\u7535\u8111\u4E0A\u5B89\u88C5\uFF0C\u6216\u5C06\u5DF2\u5B89\u88C5\u7684 Node.js \u52A0\u5165\u767B\u5F55 shell \u7684 PATH \u540E\u91CD\u8BD5",
25823
+ "npm was not detected over SSH. Install it on the remote computer or add it to the login shell PATH, then retry": "\u901A\u8FC7 SSH \u672A\u68C0\u6D4B\u5230 npm\u3002\u8BF7\u5728\u8FDC\u7A0B\u7535\u8111\u4E0A\u5B89\u88C5\uFF0C\u6216\u5C06\u5DF2\u5B89\u88C5\u7684 npm \u52A0\u5165\u767B\u5F55 shell \u7684 PATH \u540E\u91CD\u8BD5",
25824
+ "Codex CLI was not detected over SSH. Install the command-line tool on the remote computer or add it to the login shell PATH, then retry. Codex Desktop is not required": "\u901A\u8FC7 SSH \u672A\u68C0\u6D4B\u5230 Codex CLI\uFF08\u547D\u4EE4\u884C\u5DE5\u5177\uFF09\u3002\u8BF7\u5728\u8FDC\u7A0B\u7535\u8111\u4E0A\u5B89\u88C5\uFF0C\u6216\u5C06\u5DF2\u5B89\u88C5\u7684 Codex CLI \u52A0\u5165\u767B\u5F55 shell \u7684 PATH \u540E\u91CD\u8BD5\u3002\u65E0\u9700\u5B89\u88C5 Codex \u684C\u9762\u7AEF",
25825
+ "codexhost was not detected over SSH. Install it on the remote computer or add it to the login shell PATH, then retry": "\u901A\u8FC7 SSH \u672A\u68C0\u6D4B\u5230 codexhost\u3002\u8BF7\u5728\u8FDC\u7A0B\u7535\u8111\u4E0A\u5B89\u88C5\uFF0C\u6216\u5C06\u5DF2\u5B89\u88C5\u7684 codexhost \u52A0\u5165\u767B\u5F55 shell \u7684 PATH \u540E\u91CD\u8BD5",
25826
+ "The active codexhost does not match the global npm installation. Uninstall only the remote service, or remove the package manually on the remote computer": "\u5F53\u524D codexhost \u4E0E npm \u5168\u5C40\u5B89\u88C5\u4F4D\u7F6E\u4E0D\u5339\u914D\u3002\u8BF7\u9009\u62E9\u4EC5\u5378\u8F7D\u8FDC\u7A0B\u670D\u52A1\uFF0C\u6216\u5728\u8FDC\u7A0B\u7535\u8111\u4E0A\u624B\u52A8\u5378\u8F7D\u8F6F\u4EF6\u5305",
25827
+ "The remote service was uninstalled, but removing the codexhost package failed. Check npm permissions on the remote computer and retry": "\u8FDC\u7A0B\u670D\u52A1\u5DF2\u5378\u8F7D\uFF0C\u4F46 codexhost \u8F6F\u4EF6\u5305\u5378\u8F7D\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u8FDC\u7A0B\u7535\u8111\u4E0A\u7684 npm \u6743\u9650\u540E\u91CD\u8BD5",
25828
+ "Remote Node.js is unsupported. Select Node.js 22.19 or later in the 22.x series, or Node.js 24.x": "\u8FDC\u7A0B Node.js \u7248\u672C\u4E0D\u53D7\u652F\u6301\uFF0C\u8BF7\u9009\u62E9 Node.js 22.19 \u53CA\u4EE5\u4E0A\u7684 22.x \u7248\u672C\uFF0C\u6216 Node.js 24.x",
25609
25829
  "npm installation failed. Check network access and global installation permissions": "npm \u5B89\u88C5\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u548C\u5168\u5C40\u5B89\u88C5\u6743\u9650",
25610
25830
  "Remote service configuration failed. Check Codex CLI and the remote desktop login": "\u8FDC\u7A0B\u670D\u52A1\u914D\u7F6E\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 Codex CLI \u4EE5\u53CA\u8FDC\u7A0B\u7535\u8111\u7684\u684C\u9762\u767B\u5F55\u72B6\u6001",
25611
25831
  "Remote service could not stop. Check the remote service before retrying": "\u8FDC\u7A0B\u670D\u52A1\u65E0\u6CD5\u505C\u6B62\uFF0C\u8BF7\u68C0\u67E5\u8FDC\u7A0B\u670D\u52A1\u540E\u91CD\u8BD5",
@@ -25903,6 +26123,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
25903
26123
  }
25904
26124
  const serviceActions = remoteElement(document2, "div", "settings-remote-card__actions");
25905
26125
  if (!row.probing) {
26126
+ if (row.installation === "installed" && !remoteBusy(remote)) {
26127
+ serviceActions.append(command("uninstall", t("\u5378\u8F7D\u8FDC\u7A0B\u670D\u52A1", "Uninstall remote service")));
26128
+ }
25906
26129
  const outdated = !remote && !!row.remoteIssue?.outdated && row.installation !== "not-installed";
25907
26130
  if (outdated) {
25908
26131
  const upgrade = command("upgrade", t("\u66F4\u65B0\u8FDC\u7A0B\u670D\u52A1", "Update remote service"), true);
@@ -26219,6 +26442,61 @@ Codex Fast mode prioritizes requests and may increase usage.`
26219
26442
  });
26220
26443
  dialog.show(t("\u79FB\u9664", "Remove"), t("\u79FB\u9664\u4E2D\u2026", "Removing\u2026"), true);
26221
26444
  }
26445
+ function openRemoteServiceUninstall(options) {
26446
+ const { t, connection } = options;
26447
+ const dialog = createRemoteDialog(
26448
+ options,
26449
+ t(
26450
+ `\u5378\u8F7D\u201C${connection.displayName}\u201D\u7684\u8FDC\u7A0B\u670D\u52A1\uFF1F`,
26451
+ `Uninstall remote service on "${connection.displayName}"?`
26452
+ )
26453
+ );
26454
+ if (!dialog) return;
26455
+ const document2 = options.container.ownerDocument;
26456
+ dialog.body.append(
26457
+ remoteElement(
26458
+ document2,
26459
+ "p",
26460
+ "",
26461
+ t(
26462
+ "\u5378\u8F7D\u4F1A\u4E2D\u65AD codexhost \u542F\u52A8\u7684\u4F1A\u8BDD\u3002\u5982\u9700\u5728\u8BE5\u7535\u8111\u7EE7\u7EED\u4F7F\u7528\uFF0C\u8BF7\u624B\u52A8\u901A\u8FC7 codexhost \u91CD\u65B0\u542F\u52A8\u3002",
26463
+ "Uninstalling interrupts sessions started through codexhost. To keep using it on that computer, manually relaunch through codexhost."
26464
+ )
26465
+ )
26466
+ );
26467
+ const label = remoteElement(document2, "label", "settings-remote-dialog__package-option");
26468
+ const removePackage = remoteElement(document2, "input");
26469
+ removePackage.type = "checkbox";
26470
+ label.append(
26471
+ removePackage,
26472
+ t("\u540C\u65F6\u5378\u8F7D codexhost \u8F6F\u4EF6\u5305", "Also uninstall the codexhost package")
26473
+ );
26474
+ dialog.body.append(
26475
+ label,
26476
+ remoteElement(
26477
+ document2,
26478
+ "p",
26479
+ "",
26480
+ t(
26481
+ "\u52FE\u9009\u540E\uFF0C\u518D\u6B21\u4F7F\u7528\u524D\u9700\u91CD\u65B0\u5B89\u88C5 codexhost\u3002",
26482
+ "If selected, reinstall codexhost before using it again."
26483
+ )
26484
+ )
26485
+ );
26486
+ dialog.form.addEventListener("submit", (event) => {
26487
+ event.preventDefault();
26488
+ const selected = removePackage.checked;
26489
+ dialog.submit(async () => {
26490
+ removePackage.disabled = true;
26491
+ try {
26492
+ await options.uninstall(selected);
26493
+ } finally {
26494
+ removePackage.disabled = false;
26495
+ }
26496
+ });
26497
+ });
26498
+ dialog.show(t("\u5378\u8F7D", "Uninstall"), t("\u5378\u8F7D\u4E2D\u2026", "Uninstalling\u2026"), true);
26499
+ }
26222
26500
 
26223
26501
  // src/settings/remote-connections-page.ts
26224
26502
  var POLL_INTERVAL_MS = 5e3;
@@ -26347,17 +26625,17 @@ Codex Fast mode prioritizes requests and may increase usage.`
26347
26625
  banner.hidden = !loadError;
26348
26626
  bannerText.textContent = loadError ? `${t("\u8BFB\u53D6\u8FDE\u63A5\u5931\u8D25", "Could not load connections")}: ${localizeRemoteFailure(loadError, t)}` : "";
26349
26627
  renderPlaceholder();
26350
- for (const [hostId, card] of cards) {
26351
- if (rows.has(hostId)) continue;
26628
+ for (const [hostId2, card] of cards) {
26629
+ if (rows.has(hostId2)) continue;
26352
26630
  card.element.remove();
26353
- cards.delete(hostId);
26631
+ cards.delete(hostId2);
26354
26632
  }
26355
26633
  const active = focusedElement();
26356
- order.forEach((hostId, index) => {
26357
- const row = rows.get(hostId);
26634
+ order.forEach((hostId2, index) => {
26635
+ const row = rows.get(hostId2);
26358
26636
  if (!row) return;
26359
26637
  const signature = JSON.stringify([row, local]);
26360
- let card = cards.get(hostId);
26638
+ let card = cards.get(hostId2);
26361
26639
  if (card?.signature !== signature) {
26362
26640
  const element = renderRemoteCard(
26363
26641
  document2,
@@ -26369,7 +26647,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
26369
26647
  const focusedAction = active && card?.element.contains(active) ? active.dataset.action : void 0;
26370
26648
  if (card) card.element.replaceWith(element);
26371
26649
  card = { element, signature };
26372
- cards.set(hostId, card);
26650
+ cards.set(hostId2, card);
26373
26651
  if (focusedAction) focusAction(element, focusedAction);
26374
26652
  }
26375
26653
  if (list.children[index] !== card.element)
@@ -26381,38 +26659,41 @@ Codex Fast mode prioritizes requests and may increase usage.`
26381
26659
  target?.focus();
26382
26660
  }
26383
26661
  async function probe(row) {
26384
- const { hostId } = row.connection;
26385
- const token = (probeTokens.get(hostId) ?? 0) + 1;
26386
- probeTokens.set(hostId, token);
26387
- const state = await control.ssh.state(hostId, signal).catch((error51) => ({ state: "unknown", error: remoteErrorMessage(error51) }));
26662
+ const { hostId: hostId2 } = row.connection;
26663
+ const token = (probeTokens.get(hostId2) ?? 0) + 1;
26664
+ probeTokens.set(hostId2, token);
26665
+ const state = await control.ssh.state(hostId2, signal).catch((error51) => ({ state: "unknown", error: remoteErrorMessage(error51) }));
26388
26666
  let remote = null;
26389
26667
  let remoteIssue = null;
26390
26668
  if (state.state === "connected")
26391
- remote = await control.runtime(hostId).catch((error51) => {
26669
+ remote = await control.runtime(hostId2).catch((error51) => {
26392
26670
  remoteIssue = remoteVersionIssue(error51);
26393
26671
  return null;
26394
26672
  });
26673
+ if (signal.aborted || rows.get(hostId2) !== row || probeTokens.get(hostId2) !== token) return;
26395
26674
  let expectedGap = false;
26396
- if (remote && remoteBusy(remote)) restarting.set(hostId, Date.now() + RESTART_GRACE_MS);
26397
- else if (remote || (restarting.get(hostId) ?? 0) <= Date.now()) restarting.delete(hostId);
26675
+ if (remote && remoteBusy(remote)) restarting.set(hostId2, Date.now() + RESTART_GRACE_MS);
26676
+ else if (remote || (restarting.get(hostId2) ?? 0) <= Date.now()) restarting.delete(hostId2);
26398
26677
  else if (row.remote) {
26399
26678
  expectedGap = true;
26400
26679
  remote = { ...row.remote, update: { ...row.remote.update, phase: "restarting" } };
26401
26680
  remoteIssue = null;
26402
26681
  }
26403
- if (remote) installations.set(hostId, "installed");
26404
- else if (!installations.has(hostId) && Date.now() - (inspectFailures.get(hostId) ?? -INSPECT_RETRY_MS) >= INSPECT_RETRY_MS) {
26682
+ if (remote) installations.set(hostId2, "installed");
26683
+ else if (!installations.has(hostId2) && Date.now() - (inspectFailures.get(hostId2) ?? -INSPECT_RETRY_MS) >= INSPECT_RETRY_MS) {
26405
26684
  const inspected = await control.setup(row.connection, "inspect").catch(() => null);
26406
- if (inspected) installations.set(hostId, inspected.state);
26407
- else inspectFailures.set(hostId, Date.now());
26685
+ if (signal.aborted || rows.get(hostId2) !== row || probeTokens.get(hostId2) !== token)
26686
+ return;
26687
+ if (inspected) installations.set(hostId2, inspected.state);
26688
+ else inspectFailures.set(hostId2, Date.now());
26408
26689
  }
26409
- if (signal.aborted || rows.get(hostId) !== row || probeTokens.get(hostId) !== token) return;
26690
+ if (signal.aborted || rows.get(hostId2) !== row || probeTokens.get(hostId2) !== token) return;
26410
26691
  row.probing = false;
26411
26692
  row.state = expectedGap ? "connecting" : state.state;
26412
26693
  row.stateError = expectedGap ? null : state.error;
26413
26694
  row.remote = remote;
26414
26695
  row.remoteIssue = remoteIssue;
26415
- row.installation = installations.get(hostId) ?? "unknown";
26696
+ row.installation = installations.get(hostId2) ?? "unknown";
26416
26697
  render();
26417
26698
  }
26418
26699
  async function refresh(actingHostId, wait = "acting") {
@@ -26452,27 +26733,28 @@ Codex Fast mode prioritizes requests and may increase usage.`
26452
26733
  notice: null
26453
26734
  });
26454
26735
  }
26455
- for (const hostId of [...rows.keys()]) {
26456
- if (order.includes(hostId)) continue;
26457
- rows.delete(hostId);
26458
- installations.delete(hostId);
26459
- probeTokens.delete(hostId);
26460
- inspectFailures.delete(hostId);
26461
- restarting.delete(hostId);
26736
+ for (const hostId2 of [...rows.keys()]) {
26737
+ if (order.includes(hostId2)) continue;
26738
+ rows.delete(hostId2);
26739
+ installations.delete(hostId2);
26740
+ probeTokens.delete(hostId2);
26741
+ inspectFailures.delete(hostId2);
26742
+ restarting.delete(hostId2);
26462
26743
  }
26463
26744
  render();
26464
26745
  const probes = [...rows.values()].filter((row) => !row.pending || row.connection.hostId === actingHostId).map((row) => ({ hostId: row.connection.hostId, done: probe(row) }));
26465
26746
  const awaited = wait === "all" ? probes : probes.filter((p) => p.hostId === actingHostId);
26466
26747
  await Promise.all([localTask, ...awaited.map((p) => p.done)]);
26467
26748
  }
26468
- async function act(row, action, label, operation) {
26469
- const { hostId } = row.connection;
26749
+ async function act(row, action, label, operation, rethrow = false) {
26750
+ const { hostId: hostId2 } = row.connection;
26751
+ probeTokens.set(hostId2, (probeTokens.get(hostId2) ?? 0) + 1);
26470
26752
  row.pending = label;
26471
26753
  row.notice = null;
26472
26754
  render();
26473
26755
  try {
26474
26756
  const done = await operation();
26475
- await refresh(hostId);
26757
+ await refresh(hostId2);
26476
26758
  if (typeof done === "string") {
26477
26759
  const notice = { tone: "success", text: done };
26478
26760
  row.notice = notice;
@@ -26484,14 +26766,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
26484
26766
  }
26485
26767
  } catch (error51) {
26486
26768
  row.notice = { tone: "danger", text: remoteErrorMessage(error51) };
26487
- installations.delete(hostId);
26488
- inspectFailures.delete(hostId);
26489
- void refresh(hostId);
26769
+ installations.delete(hostId2);
26770
+ inspectFailures.delete(hostId2);
26771
+ void refresh(hostId2);
26772
+ if (rethrow) throw error51;
26490
26773
  } finally {
26491
26774
  row.pending = null;
26492
26775
  if (!signal.aborted) {
26493
26776
  render();
26494
- const card = cards.get(hostId)?.element;
26777
+ const card = cards.get(hostId2)?.element;
26495
26778
  if (card && !focusedElement()) focusAction(card, action);
26496
26779
  }
26497
26780
  }
@@ -26516,9 +26799,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
26516
26799
  function handle(row, action) {
26517
26800
  if (row.pending) return;
26518
26801
  const { connection } = row;
26519
- const { hostId } = connection;
26802
+ const { hostId: hostId2 } = connection;
26520
26803
  const setConnected = async (enabled) => {
26521
- const request = control.ssh.connect(hostId, enabled, signal);
26804
+ const request = control.ssh.connect(hostId2, enabled, signal);
26522
26805
  request.catch(() => void 0);
26523
26806
  await Promise.race([
26524
26807
  request,
@@ -26526,8 +26809,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
26526
26809
  ]);
26527
26810
  };
26528
26811
  const reconnect = async () => {
26529
- installations.delete(hostId);
26530
- inspectFailures.delete(hostId);
26812
+ installations.delete(hostId2);
26813
+ inspectFailures.delete(hostId2);
26531
26814
  await setConnected(true);
26532
26815
  };
26533
26816
  switch (action) {
@@ -26562,8 +26845,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
26562
26845
  break;
26563
26846
  case "recheck":
26564
26847
  void act(row, action, t("\u6B63\u5728\u91CD\u65B0\u68C0\u6D4B\u2026", "Checking again\u2026"), async () => {
26565
- installations.delete(hostId);
26566
- inspectFailures.delete(hostId);
26848
+ installations.delete(hostId2);
26849
+ inspectFailures.delete(hostId2);
26567
26850
  });
26568
26851
  break;
26569
26852
  case "install": {
@@ -26608,6 +26891,47 @@ Codex Fast mode prioritizes requests and may increase usage.`
26608
26891
  }
26609
26892
  );
26610
26893
  break;
26894
+ case "uninstall":
26895
+ if (row.installation !== "installed" || remoteBusy(row.remote)) break;
26896
+ openRemoteServiceUninstall({
26897
+ container: root,
26898
+ signal,
26899
+ t,
26900
+ connection,
26901
+ async uninstall(removePackage) {
26902
+ if (row.pending || remoteBusy(row.remote))
26903
+ throw new Error(
26904
+ t(
26905
+ "\u8FDC\u7A0B\u670D\u52A1\u6B63\u5728\u6267\u884C\u5176\u4ED6\u64CD\u4F5C\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5",
26906
+ "Another remote operation is active; retry shortly"
26907
+ )
26908
+ );
26909
+ await act(
26910
+ row,
26911
+ action,
26912
+ t("\u6B63\u5728\u5378\u8F7D\u8FDC\u7A0B\u670D\u52A1\u2026", "Uninstalling remote service\u2026"),
26913
+ async () => {
26914
+ await control.ssh.connect(hostId2, false, signal);
26915
+ await control.setup(connection, "uninstall", void 0, removePackage);
26916
+ installations.set(hostId2, "not-installed");
26917
+ inspectFailures.delete(hostId2);
26918
+ restarting.delete(hostId2);
26919
+ row.remote = null;
26920
+ row.remoteIssue = null;
26921
+ row.stateError = null;
26922
+ return removePackage ? t(
26923
+ "\u8FDC\u7A0B\u670D\u52A1\u548C codexhost \u8F6F\u4EF6\u5305\u5DF2\u5378\u8F7D",
26924
+ "Remote service and codexhost package uninstalled"
26925
+ ) : t(
26926
+ "\u8FDC\u7A0B\u670D\u52A1\u5DF2\u5378\u8F7D\uFF0Ccodexhost \u8F6F\u4EF6\u5305\u5DF2\u4FDD\u7559",
26927
+ "Remote service uninstalled; codexhost package kept"
26928
+ );
26929
+ },
26930
+ true
26931
+ );
26932
+ }
26933
+ });
26934
+ break;
26611
26935
  case "update": {
26612
26936
  const target = row.remote ? remoteMaintenanceTarget(local, row.remote) : null;
26613
26937
  if (!target) break;
@@ -26617,7 +26941,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
26617
26941
  action,
26618
26942
  restart ? t("\u6B63\u5728\u91CD\u542F\u8FDC\u7A0B\u670D\u52A1\u2026", "Restarting remote service\u2026") : t("\u6B63\u5728\u63D0\u4EA4\u66F4\u65B0\u2026", "Starting update\u2026"),
26619
26943
  async () => {
26620
- await control.update(hostId, target);
26944
+ await control.update(hostId2, target);
26621
26945
  await setConnected(true);
26622
26946
  }
26623
26947
  );
@@ -27313,7 +27637,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
27313
27637
  void context.runLatest(
27314
27638
  async (signal) => {
27315
27639
  const missing = new Set(
27316
- getDiagnostics()?.snapshot().hosts.find(({ hostId }) => hostId === "local")?.agents.filter(({ availability }) => availability === "notInstalled").map(({ agent }) => agent)
27640
+ getDiagnostics()?.snapshot().hosts.find(({ hostId: hostId2 }) => hostId2 === "local")?.agents.filter(({ availability }) => availability === "notInstalled").map(({ agent }) => agent)
27317
27641
  );
27318
27642
  const harnesses = (await client.listSessionImportSources()).harnesses.filter(
27319
27643
  ({ harnessId }) => !missing.has(harnessId)
@@ -27807,8 +28131,28 @@ Codex Fast mode prioritizes requests and may increase usage.`
27807
28131
  }
27808
28132
  }
27809
28133
 
28134
+ // src/settings/account-privacy.ts
28135
+ var EMAIL_PATTERN = /([^\s@]+)@([^\s@]+\.[^\s@]+)/gu;
28136
+ var MASK = "****";
28137
+ function maskEmailLocalPart(local) {
28138
+ const chars = Array.from(local);
28139
+ if (chars.length <= 1) return MASK;
28140
+ if (chars.length <= 4) return `${chars[0]}${MASK}${chars.length > 2 ? chars.at(-1) : ""}`;
28141
+ return `${chars.slice(0, 2).join("")}${MASK}${chars.slice(-2).join("")}`;
28142
+ }
28143
+ function maskEmails(text) {
28144
+ return text.replace(
28145
+ EMAIL_PATTERN,
28146
+ (_match, local, domain2) => `${maskEmailLocalPart(local)}@${domain2}`
28147
+ );
28148
+ }
28149
+ function accountDisplayText(text, hideEmails) {
28150
+ return hideEmails ? maskEmails(text) : text;
28151
+ }
28152
+
27810
28153
  // src/settings/credential-imports.ts
27811
28154
  var TARGET_HARNESS_ID = "pi";
28155
+ var SECTION_IMPORT_KEY = "section:import";
27812
28156
  var VENDOR_AGENTS = {
27813
28157
  "openai-codex": "codex",
27814
28158
  xai: "grok"
@@ -27843,9 +28187,17 @@ Codex Fast mode prioritizes requests and may increase usage.`
27843
28187
  let busy = false;
27844
28188
  let dialog;
27845
28189
  let othersExpanded = false;
28190
+ let sectionExpanded = true;
28191
+ let hideEmails = false;
28192
+ const shown = (text) => accountDisplayText(text, hideEmails);
27846
28193
  const targetButtons = /* @__PURE__ */ new Map();
27847
28194
  const importedRecords = () => snapshot.targets.find((target) => target.harnessId === TARGET_HARNESS_ID)?.imports ?? [];
27848
28195
  const sourceOf = (record4) => snapshot.sources.find((source) => source.id === record4.source.id);
28196
+ const piTarget = () => snapshot.targets.find((candidate) => candidate.harnessId === TARGET_HARNESS_ID);
28197
+ const compatibleSources = () => {
28198
+ const target = piTarget();
28199
+ return target ? snapshot.sources.filter((source) => target.providers.includes(source.provider)) : [];
28200
+ };
27849
28201
  const section = document2.createElement("section");
27850
28202
  section.className = "settings-pi-accounts";
27851
28203
  section.hidden = true;
@@ -27853,12 +28205,46 @@ Codex Fast mode prioritizes requests and may increase usage.`
27853
28205
  section.setAttribute("aria-label", messages.sectionTitle);
27854
28206
  const sectionHeader = document2.createElement("div");
27855
28207
  sectionHeader.className = "settings-pi-accounts__header";
28208
+ const sectionToggle = document2.createElement("button");
28209
+ sectionToggle.type = "button";
28210
+ sectionToggle.className = "settings-pi-accounts__fold";
28211
+ sectionToggle.setAttribute("aria-expanded", "true");
27856
28212
  const sectionTitle = document2.createElement("strong");
27857
28213
  sectionTitle.textContent = messages.sectionTitle;
27858
28214
  const sectionCount = document2.createElement("span");
27859
- sectionHeader.append(createRendererAgentIcon("pi", 16, document2), sectionTitle, sectionCount);
28215
+ sectionCount.className = "settings-pi-accounts__count";
28216
+ sectionToggle.append(
28217
+ createRendererSettingsIcon("chevron-right", 14),
28218
+ createRendererAgentIcon("pi", 16, document2),
28219
+ sectionTitle,
28220
+ sectionCount
28221
+ );
28222
+ const sectionHint = document2.createElement("span");
28223
+ sectionHint.className = "settings-pi-accounts__hint";
28224
+ sectionHint.textContent = messages.sectionHint;
28225
+ const sectionImport = document2.createElement("button");
28226
+ sectionImport.type = "button";
28227
+ sectionImport.className = "settings-pi-accounts__import";
28228
+ sectionImport.setAttribute("aria-haspopup", "dialog");
28229
+ sectionImport.append(createRendererSettingsIcon("add", 14), messages.sectionImport);
28230
+ sectionImport.addEventListener("click", () => {
28231
+ const sources = compatibleSources();
28232
+ const free = sources.find(
28233
+ (source2) => !importedRecords().some((record4) => record4.source.id === source2.id)
28234
+ );
28235
+ const source = free ?? sources[0];
28236
+ if (source) openDialog("add", { source, choose: true }, SECTION_IMPORT_KEY);
28237
+ });
28238
+ sectionHeader.append(sectionToggle, sectionHint, sectionImport);
27860
28239
  const card = document2.createElement("div");
27861
28240
  card.className = "settings-pi-accounts__card";
28241
+ card.id = "settings-pi-accounts-card";
28242
+ sectionToggle.setAttribute("aria-controls", card.id);
28243
+ sectionToggle.addEventListener("click", () => {
28244
+ sectionExpanded = !sectionExpanded;
28245
+ card.hidden = !sectionExpanded;
28246
+ sectionToggle.setAttribute("aria-expanded", String(sectionExpanded));
28247
+ });
27862
28248
  const othersToggle = document2.createElement("button");
27863
28249
  othersToggle.type = "button";
27864
28250
  othersToggle.className = "settings-pi-accounts__toggle";
@@ -27899,15 +28285,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
27899
28285
  row.className = "settings-pi-accounts__row";
27900
28286
  row.tabIndex = -1;
27901
28287
  row.dataset.importName = record4.name;
27902
- row.setAttribute("aria-label", record4.source.label);
28288
+ row.setAttribute("aria-label", shown(record4.source.label));
27903
28289
  const agent = KNOWN_RENDERER_AGENTS.find((candidate) => candidate === record4.source.harnessId);
27904
28290
  const mark = createMark(agent);
27905
28291
  const identity = document2.createElement("div");
27906
28292
  identity.className = "settings-pi-accounts__identity";
27907
28293
  const label = document2.createElement("strong");
27908
28294
  label.className = "settings-account-email";
27909
- label.textContent = record4.source.label;
27910
- label.title = record4.source.label;
28295
+ label.textContent = shown(record4.source.label);
28296
+ label.title = label.textContent;
27911
28297
  label.translate = false;
27912
28298
  const meta3 = document2.createElement("div");
27913
28299
  meta3.className = "settings-account-metadata";
@@ -27937,7 +28323,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
27937
28323
  reimport.type = "button";
27938
28324
  reimport.className = "settings-account-action";
27939
28325
  reimport.textContent = messages.rowReimport;
27940
- reimport.setAttribute("aria-label", `${messages.reimport}: ${record4.source.label}`);
28326
+ reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record4.source.label)}`);
27941
28327
  reimport.disabled = busy || !source;
27942
28328
  reimport.title = messages.reimport;
27943
28329
  reimport.addEventListener("click", () => {
@@ -27947,7 +28333,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
27947
28333
  remove.type = "button";
27948
28334
  remove.className = "settings-account-action settings-pi-accounts__remove";
27949
28335
  remove.textContent = messages.rowRemove;
27950
- remove.setAttribute("aria-label", `${messages.remove}: ${record4.source.label}`);
28336
+ remove.setAttribute("aria-label", `${messages.remove}: ${shown(record4.source.label)}`);
27951
28337
  remove.disabled = busy;
27952
28338
  remove.addEventListener("click", () => openDialog("remove", { record: record4 }, `row:${record4.name}`));
27953
28339
  if (source) actions.append(reimport);
@@ -27963,14 +28349,14 @@ Codex Fast mode prioritizes requests and may increase usage.`
27963
28349
  const agent = login.vendor ? VENDOR_AGENTS[login.vendor] : void 0;
27964
28350
  row.setAttribute(
27965
28351
  "aria-label",
27966
- [login.label ?? login.provider, agent && RENDERER_AGENT_LABELS[agent]].filter(Boolean).join(" \xB7 ")
28352
+ [shown(login.label ?? login.provider), agent && RENDERER_AGENT_LABELS[agent]].filter(Boolean).join(" \xB7 ")
27967
28353
  );
27968
28354
  const mark = createMark(agent);
27969
28355
  const identity = document2.createElement("div");
27970
28356
  identity.className = "settings-pi-accounts__identity";
27971
28357
  const title = document2.createElement("strong");
27972
28358
  title.className = "settings-account-email";
27973
- title.textContent = login.label ?? login.provider;
28359
+ title.textContent = shown(login.label ?? login.provider);
27974
28360
  title.title = title.textContent;
27975
28361
  title.translate = false;
27976
28362
  const meta3 = document2.createElement("div");
@@ -27991,11 +28377,14 @@ Codex Fast mode prioritizes requests and may increase usage.`
27991
28377
  return row;
27992
28378
  };
27993
28379
  const renderSection = () => {
27994
- const target = snapshot.targets.find((candidate) => candidate.harnessId === TARGET_HARNESS_ID);
28380
+ const target = piTarget();
27995
28381
  section.hidden = !target;
27996
28382
  const records = importedRecords();
27997
28383
  const others = target?.others ?? [];
27998
28384
  sectionCount.textContent = String(records.length + others.length);
28385
+ card.hidden = !sectionExpanded;
28386
+ sectionImport.hidden = compatibleSources().length === 0;
28387
+ sectionImport.disabled = busy;
27999
28388
  rows.clear();
28000
28389
  if (records.length + others.length === 0) {
28001
28390
  const empty = document2.createElement("p");
@@ -28058,6 +28447,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
28058
28447
  let state = initial;
28059
28448
  let mode = initialMode;
28060
28449
  let nameInput;
28450
+ let nameEdited = false;
28451
+ let sourceRadios = [];
28452
+ let refreshPreview = () => void 0;
28061
28453
  const command = (text, onClick, variant = "secondary") => {
28062
28454
  const button = document2.createElement("button");
28063
28455
  button.type = "button";
@@ -28081,9 +28473,50 @@ Codex Fast mode prioritizes requests and may increase usage.`
28081
28473
  paragraph.textContent = text;
28082
28474
  return paragraph;
28083
28475
  };
28476
+ const sourcePicker = (choices) => {
28477
+ const group = document2.createElement("fieldset");
28478
+ group.className = "settings-credential-dialog__sources";
28479
+ const legend = document2.createElement("legend");
28480
+ legend.textContent = messages.source;
28481
+ group.append(legend);
28482
+ for (const choice of choices) {
28483
+ const option = document2.createElement("label");
28484
+ option.className = "settings-credential-dialog__source";
28485
+ const radio = document2.createElement("input");
28486
+ radio.type = "radio";
28487
+ radio.name = "settings-credential-source";
28488
+ radio.value = choice.id;
28489
+ radio.checked = choice.id === state.source?.id;
28490
+ sourceRadios.push(radio);
28491
+ const copy = document2.createElement("span");
28492
+ const label = document2.createElement("strong");
28493
+ label.textContent = shown(choice.label);
28494
+ label.translate = false;
28495
+ const existing = importedRecords().find((record4) => record4.source.id === choice.id);
28496
+ const agent = KNOWN_RENDERER_AGENTS.find((candidate) => candidate === choice.harnessId);
28497
+ const detail = document2.createElement("span");
28498
+ detail.textContent = [
28499
+ agent && RENDERER_AGENT_LABELS[agent] || choice.harnessId,
28500
+ existing ? messages.sourceImported.replace("{name}", existing.name) : messages.sourceCurrent
28501
+ ].join(" \xB7 ");
28502
+ copy.append(label, detail);
28503
+ radio.addEventListener("change", () => {
28504
+ if (!radio.checked) return;
28505
+ state = { ...state, source: choice };
28506
+ if (nameInput && !nameEdited) {
28507
+ nameInput.value = defaultImportName(choice, importedRecords());
28508
+ }
28509
+ refreshPreview();
28510
+ });
28511
+ option.append(radio, copy);
28512
+ group.append(option);
28513
+ }
28514
+ return group;
28515
+ };
28084
28516
  const setBusy = (value) => {
28085
28517
  for (const child of controls.children) child.disabled = value;
28086
28518
  if (nameInput) nameInput.disabled = value;
28519
+ for (const radio of sourceRadios) radio.disabled = value;
28087
28520
  };
28088
28521
  const submit = async (request, next) => {
28089
28522
  error51.textContent = "";
@@ -28111,6 +28544,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
28111
28544
  mode = next;
28112
28545
  error51.textContent = "";
28113
28546
  nameInput = void 0;
28547
+ sourceRadios = [];
28114
28548
  body.replaceChildren();
28115
28549
  controls.replaceChildren();
28116
28550
  const { source, record: record4 } = state;
@@ -28119,7 +28553,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
28119
28553
  title.textContent = mode === "add" ? messages.add : messages.reimport;
28120
28554
  modal.setAttribute("aria-label", title.textContent);
28121
28555
  const active = source ?? record4?.source;
28122
- if (active) body.append(line(messages.source, active.label));
28556
+ const choices = mode === "add" && state.choose ? compatibleSources() : [];
28557
+ if (choices.length > 1) body.append(sourcePicker(choices));
28558
+ else if (active) body.append(line(messages.source, shown(active.label)));
28123
28559
  const input = document2.createElement("input");
28124
28560
  input.type = "text";
28125
28561
  input.maxLength = 48;
@@ -28127,6 +28563,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
28127
28563
  input.spellcheck = false;
28128
28564
  input.value = record4?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
28129
28565
  input.readOnly = Boolean(record4);
28566
+ input.addEventListener("input", () => {
28567
+ nameEdited = true;
28568
+ });
28130
28569
  nameInput = input;
28131
28570
  const label = document2.createElement("label");
28132
28571
  label.className = "settings-credential-dialog__field";
@@ -28138,6 +28577,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
28138
28577
  preview.textContent = (mode === "reimport" ? messages.reimportPreview : messages.preview).replace("{name}", input.value);
28139
28578
  };
28140
28579
  input.addEventListener("input", update);
28580
+ refreshPreview = update;
28141
28581
  update();
28142
28582
  body.append(label, preview, note(messages.warning));
28143
28583
  controls.append(
@@ -28145,7 +28585,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
28145
28585
  command(
28146
28586
  messages.confirm,
28147
28587
  async () => {
28148
- if (!source) return;
28588
+ const source2 = state.source;
28589
+ if (!source2) return;
28149
28590
  if (!credentialImportNameSchema.safeParse(input.value).success) {
28150
28591
  error51.textContent = messages.invalidName;
28151
28592
  input.focus();
@@ -28154,7 +28595,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
28154
28595
  await submit(
28155
28596
  {
28156
28597
  action: mode === "reimport" ? "reimport" : "import",
28157
- sourceId: source.id,
28598
+ sourceId: source2.id,
28158
28599
  name: record4?.name ?? input.value,
28159
28600
  confirmed: true
28160
28601
  },
@@ -28196,7 +28637,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
28196
28637
  modal.addEventListener("close", () => {
28197
28638
  modal.remove();
28198
28639
  dialog = void 0;
28199
- const target = returnKey ? targetButtons.get(returnKey) ?? rows.get(returnKey.replace(/^row:/, "")) : void 0;
28640
+ const target = returnKey ? returnKey === SECTION_IMPORT_KEY ? sectionImport : targetButtons.get(returnKey) ?? rows.get(returnKey.replace(/^row:/, "")) : void 0;
28200
28641
  (target?.isConnected ? target : section).focus();
28201
28642
  });
28202
28643
  show(initialMode);
@@ -28206,6 +28647,12 @@ Codex Fast mode prioritizes requests and may increase usage.`
28206
28647
  signal.addEventListener("abort", () => dialog?.remove(), { once: true });
28207
28648
  renderSection();
28208
28649
  return {
28650
+ /** Mask the middle of email addresses in the section and dialogs (screen sharing). */
28651
+ setHideEmails(value) {
28652
+ if (hideEmails === value) return;
28653
+ hideEmails = value;
28654
+ renderSection();
28655
+ },
28209
28656
  /** Dedicated "imported into Pi" section, rendered below the account table. */
28210
28657
  section,
28211
28658
  refresh: async () => {
@@ -28227,20 +28674,33 @@ Codex Fast mode prioritizes requests and may increase usage.`
28227
28674
  const key = `${harnessId}:${accountLabel}:import`;
28228
28675
  const button = document2.createElement("button");
28229
28676
  button.type = "button";
28230
- button.className = "settings-icon-button settings-account-harness-target";
28677
+ button.className = "settings-account-pi-import";
28231
28678
  button.dataset.accountFocus = key;
28232
28679
  button.disabled = busy;
28233
- if (record4) button.dataset.state = "imported";
28234
28680
  const hint = record4 ? messages.importedHint.replace("{name}", record4.name) : messages.add;
28235
28681
  button.title = hint;
28236
28682
  button.setAttribute("aria-label", hint);
28237
- button.setAttribute("aria-haspopup", "dialog");
28238
- button.append(createRendererAgentIcon("pi", 16, document2));
28683
+ button.append(createRendererAgentIcon("pi", 12, document2));
28684
+ if (record4) {
28685
+ button.dataset.state = "imported";
28686
+ const name = document2.createElement("code");
28687
+ name.textContent = `${record4.name}/\u2026`;
28688
+ name.translate = false;
28689
+ button.append(name, createRendererSettingsIcon("check", 12));
28690
+ } else {
28691
+ button.setAttribute("aria-haspopup", "dialog");
28692
+ button.append(messages.add);
28693
+ }
28239
28694
  button.addEventListener("click", () => {
28240
28695
  if (!record4) {
28241
28696
  openDialog("add", { source }, key);
28242
28697
  return;
28243
28698
  }
28699
+ if (!sectionExpanded) {
28700
+ sectionExpanded = true;
28701
+ renderSection();
28702
+ sectionToggle.setAttribute("aria-expanded", "true");
28703
+ }
28244
28704
  const row = rows.get(record4.name);
28245
28705
  row?.scrollIntoView({ block: "nearest", behavior: "smooth" });
28246
28706
  row?.focus();
@@ -28532,37 +28992,35 @@ Codex Fast mode prioritizes requests and may increase usage.`
28532
28992
  return { cells: [cell], continuationCells: [] };
28533
28993
  }
28534
28994
  const { rows, additional } = splitUsageWindows(state.credits, messages, filter);
28535
- const onlyRow = rows.length === 1 ? rows[0] : void 0;
28536
- if (additional.length && onlyRow && !Object.keys(onlyRow.columns).length) rows.pop();
28537
- for (let index = 0; index < additional.length; index += 2) {
28538
- const first = additional[index];
28539
- const second = additional[index + 1];
28540
- rows.push({
28541
- columns: {
28542
- ...first ? { five_hour: first } : {},
28543
- ...second ? { seven_day: second } : {}
28544
- }
28545
- });
28995
+ const windows = [
28996
+ ...rows.flatMap(
28997
+ (row) => ["five_hour", "seven_day"].flatMap(
28998
+ (period) => row.columns[period] ? [row.columns[period]] : []
28999
+ )
29000
+ ),
29001
+ ...additional
29002
+ ];
29003
+ const packed = [];
29004
+ for (let index = 0; index < windows.length; index += 2) {
29005
+ const pair = windows.slice(index, index + 2);
29006
+ packed.push(
29007
+ pair.map((window2) => {
29008
+ const cell = document2.createElement("td");
29009
+ cell.className = "settings-account-usage-cell";
29010
+ if (pair.length === 1) cell.colSpan = 2;
29011
+ cell.append(renderUsageWindow(document2, window2, messages, display));
29012
+ return cell;
29013
+ })
29014
+ );
28546
29015
  }
28547
- const renderCells = (row) => ["five_hour", "seven_day"].map((period) => {
29016
+ if (packed.length === 0) {
28548
29017
  const cell = document2.createElement("td");
28549
- cell.className = "settings-account-usage-cell";
28550
- const window2 = row.columns[period];
28551
- if (window2) cell.append(renderUsageWindow(document2, window2, messages, display));
28552
- else {
28553
- const missing = document2.createElement("div");
28554
- missing.className = "settings-account-usage__missing";
28555
- const dash = document2.createElement("span");
28556
- dash.textContent = "\u2014";
28557
- dash.setAttribute("aria-hidden", "true");
28558
- missing.append(dash);
28559
- cell.append(missing);
28560
- }
28561
- return cell;
28562
- });
28563
- const [firstRow = { columns: {} }, ...continuations] = rows;
28564
- const cells = renderCells(firstRow);
28565
- const continuationCells = continuations.map(renderCells);
29018
+ cell.colSpan = 2;
29019
+ cell.className = "settings-account-usage-cell settings-account-usage-cell--message";
29020
+ cell.textContent = messages.accountCreditsEmpty;
29021
+ packed.push([cell]);
29022
+ }
29023
+ const [cells = [], ...continuationCells] = packed;
28566
29024
  return { cells, continuationCells };
28567
29025
  }
28568
29026
  function renderAccountResetCredits(document2, credits, messages) {
@@ -28656,14 +29114,14 @@ Codex Fast mode prioritizes requests and may increase usage.`
28656
29114
  table.className = "settings-account-table";
28657
29115
  table.setAttribute("aria-label", messages.pageLabels.accounts);
28658
29116
  const columns = document2.createElement("colgroup");
28659
- for (const width of [32, 24, 24, 20]) {
29117
+ for (const width of [36, 32, 32]) {
28660
29118
  const column = document2.createElement("col");
28661
29119
  column.style.width = `${width}%`;
28662
29120
  columns.append(column);
28663
29121
  }
28664
29122
  const head = document2.createElement("thead");
28665
29123
  const row = document2.createElement("tr");
28666
- const headers = Array.from({ length: 3 }, (_, index) => {
29124
+ const headers = Array.from({ length: 2 }, (_, index) => {
28667
29125
  const cell = document2.createElement("th");
28668
29126
  cell.scope = index === 1 ? "colgroup" : "col";
28669
29127
  if (index === 1) cell.colSpan = 2;
@@ -28671,11 +29129,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
28671
29129
  return cell;
28672
29130
  });
28673
29131
  const updateDisplay = (display) => {
28674
- const labels = [
28675
- messages.accountColumnAccount,
28676
- accountUsageColumnLabel(display, messages),
28677
- messages.credentialImports.column
28678
- ];
29132
+ const labels = [messages.accountColumnAccount, accountUsageColumnLabel(display, messages)];
28679
29133
  headers.forEach((cell, index) => {
28680
29134
  cell.textContent = labels[index] ?? "";
28681
29135
  });
@@ -28727,11 +29181,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
28727
29181
  person.append(input.mark, identity);
28728
29182
  return person;
28729
29183
  }
28730
- function createTargetCell(document2, action) {
28731
- const cell = document2.createElement("td");
28732
- cell.className = action ? "settings-account-management-cell" : "settings-account-management-cell settings-account-management-cell--empty";
28733
- if (action) cell.append(action);
28734
- return cell;
29184
+ function appendAccountExtras(cell, items) {
29185
+ const present = items.filter((item) => Boolean(item));
29186
+ if (present.length === 0) return;
29187
+ const extras = cell.ownerDocument.createElement("div");
29188
+ extras.className = "settings-account-row__extras";
29189
+ extras.append(...present);
29190
+ cell.append(extras);
28735
29191
  }
28736
29192
  function renderAccountBalance(document2, messages, balance) {
28737
29193
  const cell = document2.createElement("td");
@@ -28756,8 +29212,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
28756
29212
  row.dataset.accountId = account.accountId;
28757
29213
  row.dataset.accountFocus = `${account.accountId}:row`;
28758
29214
  row.tabIndex = -1;
28759
- const name = codexAccountDisplayName(account);
28760
- row.setAttribute("aria-label", name.full);
29215
+ const name = accountDisplayText(codexAccountDisplayName(account).full, input.hideEmails === true);
29216
+ row.setAttribute("aria-label", name);
28761
29217
  const personCell = document2.createElement("td");
28762
29218
  personCell.className = "settings-account-person-cell";
28763
29219
  const mark = document2.createElement("div");
@@ -28767,7 +29223,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
28767
29223
  mark.append(createRendererAgentIcon("codex", 26, document2));
28768
29224
  personCell.append(
28769
29225
  createAccountPerson(document2, messages, {
28770
- name: name.full,
29226
+ name,
28771
29227
  agent: "Codex",
28772
29228
  plan: accountPlanLabel(account.planType),
28773
29229
  highlighted: account.planType === "pro" || account.planType === "prolite",
@@ -28783,8 +29239,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
28783
29239
  input.onRetry,
28784
29240
  account.planType === "pro" ? "weekly-only" : "all"
28785
29241
  );
28786
- const actionsCell = createTargetCell(document2, input.importAction);
28787
- if (input.importAction) row.className += " settings-account-row--targets";
28788
29242
  const continuationRows = usage.continuationCells.map((cells) => {
28789
29243
  const continuation = document2.createElement("tr");
28790
29244
  continuation.className = "settings-account-row settings-account-quota-continuation-row";
@@ -28795,18 +29249,19 @@ Codex Fast mode prioritizes requests and may increase usage.`
28795
29249
  if (continuationRows.length > 0) {
28796
29250
  personCell.rowSpan = continuationRows.length + 1;
28797
29251
  personCell.className += " settings-account-spanning-cell";
28798
- actionsCell.rowSpan = continuationRows.length + 1;
28799
- actionsCell.className += " settings-account-spanning-cell";
28800
29252
  }
28801
- row.append(personCell, ...usage.cells, actionsCell);
29253
+ row.append(personCell, ...usage.cells);
28802
29254
  const reset = input.usage?.status === "ready" ? renderAccountResetCredits(document2, input.usage.credits, messages) : null;
28803
- if (!reset) return [row, ...continuationRows];
29255
+ if (!reset) {
29256
+ appendAccountExtras(personCell, [input.importAction]);
29257
+ return [row, ...continuationRows];
29258
+ }
28804
29259
  const detailsRow = document2.createElement("tr");
28805
29260
  detailsRow.className = "settings-account-details-row";
28806
29261
  detailsRow.id = `settings-account-reset-${++resetDetailsSequence}`;
28807
29262
  detailsRow.hidden = !input.resetExpanded;
28808
29263
  const detailsCell = document2.createElement("td");
28809
- detailsCell.colSpan = 4;
29264
+ detailsCell.colSpan = 3;
28810
29265
  detailsCell.append(reset.details);
28811
29266
  detailsRow.append(detailsCell);
28812
29267
  reset.summary.dataset.accountFocus = `${account.accountId}:reset`;
@@ -28817,15 +29272,18 @@ Codex Fast mode prioritizes requests and may increase usage.`
28817
29272
  reset.summary.setAttribute("aria-expanded", String(!detailsRow.hidden));
28818
29273
  input.onResetExpanded(!detailsRow.hidden);
28819
29274
  });
28820
- personCell.append(reset.summary);
29275
+ appendAccountExtras(personCell, [reset.summary, input.importAction]);
28821
29276
  return [row, ...continuationRows, detailsRow];
28822
29277
  }
28823
- function renderHarnessAccountRows(document2, account, messages, display, importAction) {
29278
+ function renderHarnessAccountRows(document2, account, messages, display, importAction, hideEmails = false) {
28824
29279
  const row = document2.createElement("tr");
28825
29280
  row.className = "settings-account-row";
28826
29281
  row.dataset.harnessId = account.harnessId;
28827
29282
  row.tabIndex = -1;
28828
- const name = account.email ?? account.label ?? account.harnessName;
29283
+ const name = accountDisplayText(
29284
+ account.email ?? account.label ?? account.harnessName,
29285
+ hideEmails
29286
+ );
28829
29287
  row.setAttribute("aria-label", name);
28830
29288
  const personCell = document2.createElement("td");
28831
29289
  personCell.className = "settings-account-person-cell";
@@ -28850,9 +29308,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
28850
29308
  () => void 0,
28851
29309
  account.harnessId === "grok" ? "weekly-only" : "all"
28852
29310
  ) : renderAccountBalance(document2, messages, account.balance);
28853
- const managementCell = createTargetCell(document2, importAction);
28854
- if (importAction) row.className += " settings-account-row--targets";
28855
29311
  personCell.title = messages.accountNativeManagementHint.replace("{harness}", account.harnessName);
29312
+ appendAccountExtras(personCell, [importAction]);
28856
29313
  const continuationRows = usage.continuationCells.map((cells) => {
28857
29314
  const continuation = document2.createElement("tr");
28858
29315
  continuation.className = "settings-account-row settings-account-quota-continuation-row";
@@ -28863,10 +29320,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
28863
29320
  if (continuationRows.length > 0) {
28864
29321
  personCell.rowSpan = continuationRows.length + 1;
28865
29322
  personCell.className += " settings-account-spanning-cell";
28866
- managementCell.rowSpan = continuationRows.length + 1;
28867
- managementCell.className += " settings-account-spanning-cell";
28868
29323
  }
28869
- row.append(personCell, ...usage.cells, managementCell);
29324
+ row.append(personCell, ...usage.cells);
28870
29325
  return [row, ...continuationRows];
28871
29326
  }
28872
29327
 
@@ -29026,6 +29481,26 @@ Codex Fast mode prioritizes requests and may increase usage.`
29026
29481
  refreshUsage.title = messages.accountCreditsRefresh;
29027
29482
  refreshUsage.setAttribute("aria-label", messages.accountCreditsRefresh);
29028
29483
  refreshUsage.append(createRendererSettingsIcon("refresh", 16));
29484
+ let hideEmails = false;
29485
+ const privacyToggle = document2.createElement("button");
29486
+ privacyToggle.type = "button";
29487
+ privacyToggle.className = "settings-icon-button settings-account-privacy-toggle";
29488
+ const updatePrivacyToggle = () => {
29489
+ const label = hideEmails ? messages.accountEmailsShow : messages.accountEmailsHide;
29490
+ privacyToggle.title = label;
29491
+ privacyToggle.setAttribute("aria-label", label);
29492
+ privacyToggle.setAttribute("aria-pressed", String(hideEmails));
29493
+ privacyToggle.replaceChildren(
29494
+ createRendererSettingsIcon(hideEmails ? "eye-off" : "eye", 16)
29495
+ );
29496
+ };
29497
+ updatePrivacyToggle();
29498
+ privacyToggle.addEventListener("click", () => {
29499
+ hideEmails = !hideEmails;
29500
+ updatePrivacyToggle();
29501
+ credentialImports.setHideEmails(hideEmails);
29502
+ render();
29503
+ });
29029
29504
  refreshUsage.addEventListener("click", () => {
29030
29505
  usageByAccountId.clear();
29031
29506
  loadUsage(accounts);
@@ -29033,7 +29508,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
29033
29508
  void credentialImports.refresh();
29034
29509
  });
29035
29510
  search.addEventListener("input", () => render());
29036
- toolbar.append(connected, searchWrapper, displayControls, refreshUsage);
29511
+ toolbar.append(connected, privacyToggle, searchWrapper, displayControls, refreshUsage);
29037
29512
  const list = document2.createElement("div");
29038
29513
  list.className = "settings-account-list";
29039
29514
  const { table, body, updateDisplay } = createAccountsTable(document2, messages);
@@ -29078,7 +29553,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
29078
29553
  if (visibleAccounts.length + visibleHarnessAccounts.length === 0) {
29079
29554
  const emptyRow = document2.createElement("tr");
29080
29555
  const emptyCell = document2.createElement("td");
29081
- emptyCell.colSpan = 4;
29556
+ emptyCell.colSpan = 3;
29082
29557
  emptyCell.className = "settings-account-empty";
29083
29558
  emptyCell.textContent = query ? messages.accountNoMatches : messages.accountEmpty;
29084
29559
  emptyRow.append(emptyCell);
@@ -29088,10 +29563,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
29088
29563
  body.append(
29089
29564
  ...renderAccountRows(document2, account, messages, {
29090
29565
  current: accountPhase === "ready" && account.accountId === currentAccountId,
29091
- importAction: credentialImports.button(
29092
- "codex",
29093
- codexAccountDisplayName(account).full
29094
- ),
29095
29566
  usage: usageByAccountId.get(account.accountId),
29096
29567
  display: usageDisplay,
29097
29568
  resetExpanded: expandedResetAccounts.has(account.accountId),
@@ -29102,7 +29573,12 @@ Codex Fast mode prioritizes requests and may increase usage.`
29102
29573
  onResetExpanded: (open) => {
29103
29574
  if (open) expandedResetAccounts.add(account.accountId);
29104
29575
  else expandedResetAccounts.delete(account.accountId);
29105
- }
29576
+ },
29577
+ importAction: credentialImports.button(
29578
+ "codex",
29579
+ codexAccountDisplayName(account).full
29580
+ ),
29581
+ hideEmails
29106
29582
  })
29107
29583
  );
29108
29584
  }
@@ -29116,7 +29592,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
29116
29592
  credentialImports.button(
29117
29593
  account.harnessId,
29118
29594
  account.email ?? account.label ?? account.harnessName
29119
- )
29595
+ ),
29596
+ hideEmails
29120
29597
  )
29121
29598
  );
29122
29599
  }
@@ -29223,8 +29700,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
29223
29700
  } catch {
29224
29701
  }
29225
29702
  const harnessAccounts = createHarnessAccounts(context.signal, getClient, render);
29226
- void credentialImports.refresh();
29227
29703
  void harnessAccounts.refresh();
29704
+ void credentialImports.refresh();
29228
29705
  load();
29229
29706
  return () => {
29230
29707
  stopCountdowns();
@@ -29786,7 +30263,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
29786
30263
  }
29787
30264
  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) {
29788
30265
  return Object.freeze([
29789
- createConnectionsSettingsPage(messages, getDiagnostics),
30266
+ createConnectionsSettingsPage(messages, getDiagnostics, void 0, getRemoteConnections),
29790
30267
  createRemoteConnectionsPage(messages, getRemoteConnections),
29791
30268
  createAccountsSettingsPage(messages, getAccountClient),
29792
30269
  createSessionImportSettingsPage(
@@ -32302,6 +32779,23 @@ Codex Fast mode prioritizes requests and may increase usage.`
32302
32779
  outline-offset: -1px;
32303
32780
  }
32304
32781
 
32782
+ .settings-remote-dialog__package-option {
32783
+ display: flex;
32784
+ align-items: center;
32785
+ gap: 8px;
32786
+ cursor: pointer;
32787
+ }
32788
+
32789
+ .settings-remote-dialog .settings-remote-dialog__package-option input {
32790
+ flex: none;
32791
+ width: 16px;
32792
+ height: 16px;
32793
+ min-height: 16px;
32794
+ margin: 0;
32795
+ padding: 0;
32796
+ accent-color: var(--settings-focus);
32797
+ }
32798
+
32305
32799
  @keyframes settings-remote-spin {
32306
32800
  to {
32307
32801
  transform: rotate(360deg);
@@ -32406,6 +32900,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
32406
32900
  color: var(--settings-muted);
32407
32901
  font-variant-numeric: tabular-nums;
32408
32902
  }
32903
+ /* Email privacy belongs to the identity column, so it sits beside the account count on the
32904
+ left; quota controls (used/remaining, refresh) stay together on the right. */
32905
+ .settings-account-privacy-toggle {
32906
+ margin-left: -8px;
32907
+ }
32908
+ .settings-account-privacy-toggle[aria-pressed="true"] {
32909
+ color: var(--settings-text);
32910
+ background: var(--settings-active);
32911
+ }
32409
32912
  .settings-account-search {
32410
32913
  display: flex;
32411
32914
  align-items: center;
@@ -32475,10 +32978,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
32475
32978
  background: light-dark(#f8f8fa, #202024);
32476
32979
  font-size: 11px;
32477
32980
  font-weight: 500;
32478
- text-align: left;
32479
- }
32480
- .settings-account-table th:last-child {
32481
- text-align: right;
32981
+ text-align: center;
32482
32982
  }
32483
32983
  .settings-account-table td {
32484
32984
  padding: 17px 16px;
@@ -32798,26 +33298,11 @@ Codex Fast mode prioritizes requests and may increase usage.`
32798
33298
  border: 0;
32799
33299
  }
32800
33300
  .settings-account-person-cell,
32801
- .settings-account-management-cell,
33301
+ .settings-account-usage-cell[colspan="2"],
32802
33302
  .settings-account-usage-cell--message,
32803
33303
  .settings-account-balance-cell {
32804
33304
  grid-column: 1 / -1;
32805
33305
  }
32806
- .settings-account-table .settings-account-row > td.settings-account-management-cell--empty {
32807
- display: none;
32808
- }
32809
- .settings-account-row--targets {
32810
- position: relative;
32811
- }
32812
- .settings-account-row--targets .settings-account-person-cell {
32813
- padding-right: 32px;
32814
- }
32815
- .settings-account-table .settings-account-row--targets > td.settings-account-management-cell {
32816
- position: absolute;
32817
- top: 14px;
32818
- right: 12px;
32819
- width: auto;
32820
- }
32821
33306
  .settings-account-email {
32822
33307
  font-size: 13px;
32823
33308
  }
@@ -32835,32 +33320,57 @@ Codex Fast mode prioritizes requests and may increase usage.`
32835
33320
  }
32836
33321
  }
32837
33322
 
32838
- /* Small Harness target mark: muted when nothing is copied, full-strength with a dot when it is. */
32839
- .settings-account-harness-target {
32840
- position: relative;
32841
- width: 26px;
32842
- height: 28px;
32843
- color: var(--settings-subtle);
33323
+ /* Identity extras: reset cards and the Pi import chip share one wrapping line. */
33324
+ .settings-account-row__extras {
33325
+ display: flex;
33326
+ flex-wrap: wrap;
33327
+ align-items: center;
33328
+ gap: 4px 10px;
33329
+ margin-top: 6px;
33330
+ }
33331
+ /* Pi import chip: dashed "Import into Pi" until copied, then the entry name with a check. */
33332
+ .settings-account-pi-import {
33333
+ display: inline-flex;
33334
+ align-items: center;
33335
+ gap: 5px;
33336
+ min-height: 24px;
33337
+ padding: 2px 8px;
33338
+ color: var(--settings-muted);
33339
+ font: inherit;
33340
+ font-size: 11px;
33341
+ white-space: nowrap;
33342
+ background: transparent;
33343
+ border: 1px dashed var(--settings-border);
33344
+ border-radius: 6px;
33345
+ cursor: pointer;
32844
33346
  }
32845
- .settings-account-harness-target:hover:not(:disabled) {
33347
+ .settings-account-pi-import:hover:not(:disabled) {
32846
33348
  color: var(--settings-text);
33349
+ border-style: solid;
33350
+ background: var(--settings-hover);
32847
33351
  }
32848
- .settings-account-harness-target:disabled {
32849
- opacity: 0.4;
33352
+ .settings-account-pi-import:disabled {
33353
+ opacity: 0.45;
32850
33354
  cursor: default;
32851
33355
  }
32852
- .settings-account-harness-target[data-state] {
33356
+ .settings-account-pi-import[data-state="imported"] {
32853
33357
  color: var(--settings-text);
33358
+ background: var(--settings-inset);
33359
+ border-style: solid;
32854
33360
  }
32855
- .settings-account-harness-target[data-state]::after {
32856
- content: "";
32857
- position: absolute;
32858
- top: 5px;
32859
- right: 3px;
32860
- width: 6px;
32861
- height: 6px;
32862
- border-radius: 50%;
32863
- background: var(--settings-text);
33361
+ .settings-account-pi-import code {
33362
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
33363
+ font-size: 11px;
33364
+ }
33365
+ .settings-account-pi-import > svg {
33366
+ flex: none;
33367
+ }
33368
+ .settings-account-pi-import[data-state="imported"] > svg:last-child {
33369
+ color: light-dark(#2f7d4f, #7fd19b);
33370
+ }
33371
+ .settings-account-pi-import:focus-visible {
33372
+ outline: 2px solid var(--settings-focus);
33373
+ outline-offset: 1px;
32864
33374
  }
32865
33375
  /* Dedicated "imported into Pi" section: same card language as the account table, lighter header. */
32866
33376
  .settings-pi-accounts {
@@ -32871,18 +33381,67 @@ Codex Fast mode prioritizes requests and may increase usage.`
32871
33381
  }
32872
33382
  .settings-pi-accounts__header {
32873
33383
  display: flex;
33384
+ flex-wrap: wrap;
32874
33385
  align-items: center;
32875
- gap: 8px;
33386
+ gap: 8px 12px;
32876
33387
  padding: 0 2px 12px;
32877
33388
  font-size: 13px;
32878
33389
  }
32879
- .settings-pi-accounts__header > svg {
33390
+ .settings-pi-accounts__fold {
33391
+ display: inline-flex;
33392
+ align-items: center;
33393
+ gap: 8px;
33394
+ padding: 4px 0;
33395
+ color: var(--settings-text);
33396
+ font: inherit;
33397
+ background: transparent;
33398
+ border: 0;
33399
+ cursor: pointer;
33400
+ }
33401
+ .settings-pi-accounts__fold > svg {
32880
33402
  flex: none;
32881
33403
  }
32882
- .settings-pi-accounts__header > :last-child {
33404
+ .settings-pi-accounts__fold > svg:first-child {
33405
+ color: var(--settings-muted);
33406
+ transition: transform 120ms ease;
33407
+ }
33408
+ .settings-pi-accounts__fold[aria-expanded="true"] > svg:first-child {
33409
+ transform: rotate(90deg);
33410
+ }
33411
+ .settings-pi-accounts__count {
32883
33412
  color: var(--settings-muted);
32884
33413
  font-variant-numeric: tabular-nums;
32885
33414
  }
33415
+ .settings-pi-accounts__hint {
33416
+ margin-right: auto;
33417
+ color: var(--settings-muted);
33418
+ font-size: 12px;
33419
+ }
33420
+ .settings-pi-accounts__import {
33421
+ display: inline-flex;
33422
+ align-items: center;
33423
+ gap: 6px;
33424
+ min-height: 30px;
33425
+ padding: 4px 10px;
33426
+ color: var(--settings-text);
33427
+ font: inherit;
33428
+ font-size: 12px;
33429
+ background: light-dark(#ffffff, #232326);
33430
+ border: 1px solid var(--settings-border);
33431
+ border-radius: 7px;
33432
+ cursor: pointer;
33433
+ }
33434
+ .settings-pi-accounts__import:hover:not(:disabled) {
33435
+ background: var(--settings-hover);
33436
+ }
33437
+ .settings-pi-accounts__import:disabled {
33438
+ opacity: 0.45;
33439
+ cursor: default;
33440
+ }
33441
+ .settings-pi-accounts__import[hidden],
33442
+ .settings-pi-accounts__card[hidden] {
33443
+ display: none;
33444
+ }
32886
33445
  .settings-pi-accounts__card {
32887
33446
  container-type: inline-size;
32888
33447
  overflow: hidden;
@@ -33019,6 +33578,54 @@ Codex Fast mode prioritizes requests and may increase usage.`
33019
33578
  color: var(--settings-muted);
33020
33579
  font-size: 12px;
33021
33580
  }
33581
+ .settings-credential-dialog__sources {
33582
+ display: grid;
33583
+ gap: 8px;
33584
+ margin: 0;
33585
+ padding: 0;
33586
+ border: 0;
33587
+ }
33588
+ .settings-credential-dialog__sources > legend {
33589
+ margin-bottom: 6px;
33590
+ padding: 0;
33591
+ color: var(--settings-muted);
33592
+ font-size: 12px;
33593
+ }
33594
+ .settings-credential-dialog__source {
33595
+ display: flex;
33596
+ align-items: center;
33597
+ gap: 10px;
33598
+ padding: 9px 12px;
33599
+ border: 1px solid var(--settings-border);
33600
+ border-radius: 8px;
33601
+ cursor: pointer;
33602
+ }
33603
+ .settings-credential-dialog__source:has(input:checked) {
33604
+ border-color: var(--settings-focus);
33605
+ background: var(--settings-hover);
33606
+ }
33607
+ .settings-credential-dialog__source > span {
33608
+ display: grid;
33609
+ gap: 2px;
33610
+ min-width: 0;
33611
+ }
33612
+ .settings-credential-dialog__source strong {
33613
+ font-size: 13px;
33614
+ font-weight: 500;
33615
+ overflow-wrap: anywhere;
33616
+ }
33617
+ .settings-credential-dialog__source > span > span {
33618
+ color: var(--settings-muted);
33619
+ font-size: 12px;
33620
+ }
33621
+ .settings-credential-dialog .settings-credential-dialog__source input {
33622
+ flex: none;
33623
+ width: auto;
33624
+ min-height: 0;
33625
+ margin: 0;
33626
+ padding: 0;
33627
+ accent-color: var(--settings-focus);
33628
+ }
33022
33629
  .settings-credential-dialog input {
33023
33630
  width: 100%;
33024
33631
  box-sizing: border-box;
@@ -33065,9 +33672,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
33065
33672
  }
33066
33673
 
33067
33674
  @media (forced-colors: active) {
33068
- .settings-account-harness-target[data-state]::after {
33069
- background: Highlight;
33070
- }
33071
33675
  .settings-account-usage__bar {
33072
33676
  border: 1px solid CanvasText;
33073
33677
  }
@@ -34421,9 +35025,9 @@ ${accounts_default}`;
34421
35025
  var rendererUsageRefreshDelays = [250, 500, 1e3, 2e3, 4e3, 8e3];
34422
35026
  function refreshConnectionHosts(hostIds, refreshHost, pendingHost) {
34423
35027
  return Promise.all(
34424
- [...hostIds].map(async (hostId) => {
34425
- if (pendingHost) await pendingHost(hostId)?.catch(() => void 0);
34426
- await refreshHost(hostId);
35028
+ [...hostIds].map(async (hostId2) => {
35029
+ if (pendingHost) await pendingHost(hostId2)?.catch(() => void 0);
35030
+ await refreshHost(hostId2);
34427
35031
  })
34428
35032
  ).then(() => void 0);
34429
35033
  }
@@ -34648,9 +35252,9 @@ ${accounts_default}`;
34648
35252
  if (!isLateConversationTarget(mountedTarget, currentTarget)) return "none";
34649
35253
  return mountedTarget?.[0] === "default" && (sourcePhase === "locked" || submissionPending) ? "transfer" : "inspect";
34650
35254
  }
34651
- function scopedComposerTarget(target, hostId) {
34652
- if (target?.[0] !== "conversation" || !hostId) return target;
34653
- return ["conversation", target[1], hostId];
35255
+ function scopedComposerTarget(target, hostId2) {
35256
+ if (target?.[0] !== "conversation" || !hostId2) return target;
35257
+ return ["conversation", target[1], hostId2];
34654
35258
  }
34655
35259
  function isComposerModelWriteAllowed(target) {
34656
35260
  return target?.[0] === "default";
@@ -34723,7 +35327,7 @@ ${accounts_default}`;
34723
35327
  if (!modelControl) return null;
34724
35328
  return modelControl.currentHostId ? modelControl.currentHostId(composer) : "local";
34725
35329
  };
34726
- const controllerTarget = (target, hostId) => scopedComposerTarget(target, hostId);
35330
+ const controllerTarget = (target, hostId2) => scopedComposerTarget(target, hostId2);
34727
35331
  const usageSubscriptions = /* @__PURE__ */ new Map();
34728
35332
  const usageNotificationDispose = () => {
34729
35333
  for (const subscription of usageSubscriptions.values()) subscription.dispose();
@@ -34742,7 +35346,7 @@ ${accounts_default}`;
34742
35346
  return null;
34743
35347
  };
34744
35348
  const sidebarAgentIcons = installRendererSidebarAgentIcons({
34745
- getClient: (hostId) => modelClientForHost(hostId),
35349
+ getClient: (hostId2) => modelClientForHost(hostId2),
34746
35350
  getLocalAgent: localAgentForSidebarThread
34747
35351
  });
34748
35352
  let connectionDiagnostics = null;
@@ -34808,27 +35412,27 @@ ${accounts_default}`;
34808
35412
  retryAttempt: 0
34809
35413
  });
34810
35414
  const harnessAvailabilityByHost = /* @__PURE__ */ new Map();
34811
- const hostHarnessAvailabilityState = (hostId) => {
34812
- let state = harnessAvailabilityByHost.get(hostId);
35415
+ const hostHarnessAvailabilityState = (hostId2) => {
35416
+ let state = harnessAvailabilityByHost.get(hostId2);
34813
35417
  if (!state) {
34814
35418
  state = createHostHarnessAvailabilityState();
34815
- harnessAvailabilityByHost.set(hostId, state);
35419
+ harnessAvailabilityByHost.set(hostId2, state);
34816
35420
  }
34817
35421
  return state;
34818
35422
  };
34819
- const codexAccountsForHost = (hostId) => {
34820
- if (!hostId) return null;
34821
- const client = modelClientForHost(hostId);
35423
+ const codexAccountsForHost = (hostId2) => {
35424
+ if (!hostId2) return null;
35425
+ const client = modelClientForHost(hostId2);
34822
35426
  if (!client) return null;
34823
- const state = hostHarnessAvailabilityState(hostId);
35427
+ const state = hostHarnessAvailabilityState(hostId2);
34824
35428
  if (state.codexAccounts?.client !== client) {
34825
35429
  state.codexAccounts?.dispose();
34826
35430
  state.codexAccounts = new RendererCodexAccountState(client, () => {
34827
35431
  queueMicrotask(() => {
34828
- if (disposed || hostHarnessAvailabilityState(hostId).codexAccounts?.client !== client)
35432
+ if (disposed || hostHarnessAvailabilityState(hostId2).codexAccounts?.client !== client)
34829
35433
  return;
34830
35434
  for (const mounted of mountedByComposer.values()) {
34831
- if (mounted.hostId !== hostId) continue;
35435
+ if (mounted.hostId !== hostId2) continue;
34832
35436
  renderMounted(mounted);
34833
35437
  void refreshDraftCodexUsage(mounted);
34834
35438
  }
@@ -34847,9 +35451,9 @@ ${accounts_default}`;
34847
35451
  const availabilityRetryDelays = [500, 1e3, 2e3, 4e3, 8e3];
34848
35452
  const usageRefreshTimers = /* @__PURE__ */ new Map();
34849
35453
  const usageRefreshAttempts = /* @__PURE__ */ new Map();
34850
- const isMountedComposer = (composer) => composer.isConnected && composer.matches(CODEX_COMPOSER_SELECTOR) && mountedByComposer.has(composer);
35454
+ const isMountedComposer = (composer) => composer.isConnected && composer.matches(CODEX_COMPOSER_SELECTOR) && !isOrbitComposer(composer) && mountedByComposer.has(composer);
34851
35455
  const isCurrentModelRequest = (mounted, generation) => isMountedComposer(mounted.composer) && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentModelRequest(mounted.composer, generation);
34852
- const isCurrentOwnershipRequest = (mounted, generation) => mounted.composer.isConnected && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentOwnershipRequest(mounted.composer, generation);
35456
+ const isCurrentOwnershipRequest = (mounted, generation) => isMountedComposer(mounted.composer) && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentOwnershipRequest(mounted.composer, generation);
34853
35457
  const notifySubmission = (composer, trigger) => {
34854
35458
  const state = controller.recordSubmission(composer);
34855
35459
  writeNewThreadAgentPreference(state.agent);
@@ -34882,6 +35486,7 @@ ${accounts_default}`;
34882
35486
  const composerAvailability = (mounted) => mounted.hostId ? hostHarnessAvailabilityState(mounted.hostId).availability : {};
34883
35487
  const composerAdapterState = (mounted) => composerClient(mounted) ? "ready" : "installing";
34884
35488
  const renderMounted = (mounted) => {
35489
+ if (!isMountedComposer(mounted.composer)) return;
34885
35490
  const accounts = composerCodexAccounts(mounted.composer);
34886
35491
  const currentCodexAccount = accounts?.accounts.find(
34887
35492
  ({ accountId }) => accountId === accounts.readyAccountId
@@ -34915,8 +35520,8 @@ ${accounts_default}`;
34915
35520
  {
34916
35521
  const published = Reflect.get(window, "__codexhostDraftWorkspacesV1");
34917
35522
  if (typeof published === "object" && published !== null) {
34918
- for (const [hostId, cwd] of Object.entries(published)) {
34919
- if (typeof cwd === "string" && cwd.length > 0) draftWorkspaces.set(hostId, cwd);
35523
+ for (const [hostId2, cwd] of Object.entries(published)) {
35524
+ if (typeof cwd === "string" && cwd.length > 0) draftWorkspaces.set(hostId2, cwd);
34920
35525
  }
34921
35526
  }
34922
35527
  }
@@ -34924,17 +35529,17 @@ ${accounts_default}`;
34924
35529
  const generation = ++mounted.commandRequestGeneration;
34925
35530
  const agent = controller.get(mounted.composer).agent;
34926
35531
  const threadId = threadIdFromComposerModelTarget(mounted.modelTarget);
34927
- const hostId = threadId ? mounted.hostId : activeModelHostId(mounted.composer);
35532
+ const hostId2 = threadId ? mounted.hostId : activeModelHostId(mounted.composer);
34928
35533
  const requestControl = modelControl;
34929
- const client = modelClientForHostFrom(requestControl, hostId);
35534
+ const client = modelClientForHostFrom(requestControl, hostId2);
34930
35535
  if (!keepCurrent || agent === "codex") mounted.control.harnessCommands.setCommands([]);
34931
35536
  if (agent === "codex" || !client) return;
34932
35537
  try {
34933
35538
  const catalog = threadId ? await client.inspectThreadCommands({ threadId }) : await client.inspectHarnessCommands({
34934
35539
  harnessId: externalHarnessIds[agent],
34935
- ...hostId && draftWorkspaces.has(hostId) ? { cwd: draftWorkspaces.get(hostId) } : {}
35540
+ ...hostId2 && draftWorkspaces.has(hostId2) ? { cwd: draftWorkspaces.get(hostId2) } : {}
34936
35541
  });
34937
- if (disposed || mountedByComposer.get(mounted.composer) !== mounted || mounted.commandRequestGeneration !== generation || requestControl !== modelControl || (threadIdFromComposerModelTarget(mounted.modelTarget) ? mounted.hostId : activeModelHostId(mounted.composer)) !== hostId || controller.get(mounted.composer).agent !== agent)
35542
+ if (disposed || mountedByComposer.get(mounted.composer) !== mounted || mounted.commandRequestGeneration !== generation || requestControl !== modelControl || (threadIdFromComposerModelTarget(mounted.modelTarget) ? mounted.hostId : activeModelHostId(mounted.composer)) !== hostId2 || controller.get(mounted.composer).agent !== agent)
34938
35543
  return;
34939
35544
  mounted.control.harnessCommands.setCommands(
34940
35545
  catalog.commands,
@@ -34974,9 +35579,9 @@ ${accounts_default}`;
34974
35579
  }
34975
35580
  console.error("codexhost Harness command could not claim the current Composer editor");
34976
35581
  };
34977
- const applyThreadUsageUpdate = (hostId, update) => {
35582
+ const applyThreadUsageUpdate = (hostId2, update) => {
34978
35583
  for (const mounted of mountedByComposer.values()) {
34979
- if (mounted.hostId !== hostId || threadIdFromComposerModelTarget(mounted.modelTarget) !== update.threadId)
35584
+ if (mounted.hostId !== hostId2 || threadIdFromComposerModelTarget(mounted.modelTarget) !== update.threadId)
34980
35585
  continue;
34981
35586
  mounted.usageRequestGeneration += 1;
34982
35587
  mounted.usage = update.usage;
@@ -34992,7 +35597,7 @@ ${accounts_default}`;
34992
35597
  const accounts = composerCodexAccounts(mounted.composer);
34993
35598
  const client = accounts?.client;
34994
35599
  const accountId = accounts?.readyAccountId;
34995
- const hostId = mounted.hostId;
35600
+ const hostId2 = mounted.hostId;
34996
35601
  const generation = ++mounted.usageRequestGeneration;
34997
35602
  mounted.usage = null;
34998
35603
  mounted.accountCredits = null;
@@ -35000,7 +35605,7 @@ ${accounts_default}`;
35000
35605
  if (!accountId || !client?.inspectCodexAccountUsage) return;
35001
35606
  try {
35002
35607
  const result = await client.inspectCodexAccountUsage({ accountId });
35003
- if (disposed || mounted.hostId !== hostId || composerCodexAccounts(mounted.composer) !== accounts || !mounted.composer.isConnected || mountedByComposer.get(mounted.composer) !== mounted || mounted.usageRequestGeneration !== generation || controller.get(mounted.composer).agent !== "codex" || controller.get(mounted.composer).phase !== "draft" || controller.isSubmissionPending(mounted.composer) || threadIdFromComposerModelTarget(mounted.modelTarget) || accounts.readyAccountId !== accountId || result.accountId !== accountId)
35608
+ if (disposed || mounted.hostId !== hostId2 || composerCodexAccounts(mounted.composer) !== accounts || !mounted.composer.isConnected || mountedByComposer.get(mounted.composer) !== mounted || mounted.usageRequestGeneration !== generation || controller.get(mounted.composer).agent !== "codex" || controller.get(mounted.composer).phase !== "draft" || controller.isSubmissionPending(mounted.composer) || threadIdFromComposerModelTarget(mounted.modelTarget) || accounts.readyAccountId !== accountId || result.accountId !== accountId)
35004
35609
  return;
35005
35610
  mounted.usage = result.usage;
35006
35611
  mounted.accountCredits = result.accountCredits ?? null;
@@ -35021,7 +35626,7 @@ ${accounts_default}`;
35021
35626
  renderMounted(mounted);
35022
35627
  return;
35023
35628
  }
35024
- const hostId = mounted.hostId;
35629
+ const hostId2 = mounted.hostId;
35025
35630
  const client = composerClient(mounted);
35026
35631
  if (!client) return;
35027
35632
  const generation = ++mounted.usageRequestGeneration;
@@ -35030,7 +35635,7 @@ ${accounts_default}`;
35030
35635
  threadId,
35031
35636
  ...refresh ? { refresh } : {}
35032
35637
  });
35033
- if (disposed || mountedByComposer.get(mounted.composer) !== mounted || !mounted.composer.isConnected || mounted.usageRequestGeneration !== generation || mounted.hostId !== hostId || composerClient(mounted) !== client || threadIdFromComposerModelTarget(mounted.modelTarget) !== threadId || result.threadId !== threadId) {
35638
+ if (disposed || mountedByComposer.get(mounted.composer) !== mounted || !mounted.composer.isConnected || mounted.usageRequestGeneration !== generation || mounted.hostId !== hostId2 || composerClient(mounted) !== client || threadIdFromComposerModelTarget(mounted.modelTarget) !== threadId || result.threadId !== threadId) {
35034
35639
  return;
35035
35640
  }
35036
35641
  mounted.usage = result.usage;
@@ -35076,6 +35681,7 @@ ${accounts_default}`;
35076
35681
  await policy.clear();
35077
35682
  };
35078
35683
  const applyDraftAgentCarrier = (composer, agent) => {
35684
+ if (isOrbitComposer(composer)) return false;
35079
35685
  const model = controller.modelForAgent(composer, agent);
35080
35686
  const hasConcreteModel = model !== void 0;
35081
35687
  return applyAdapterAgent?.(
@@ -35093,6 +35699,7 @@ ${accounts_default}`;
35093
35699
  );
35094
35700
  };
35095
35701
  const loadThreadOwnership = async (mounted) => {
35702
+ if (!isMountedComposer(mounted.composer)) return;
35096
35703
  const threadId = threadIdFromComposerModelTarget(mounted.modelTarget);
35097
35704
  if (!threadId) {
35098
35705
  mounted.ownershipStatus = "not-required";
@@ -35836,13 +36443,13 @@ ${accounts_default}`;
35836
36443
  const loadCodexAccounts = async () => {
35837
36444
  const hostIds = new Set([...mountedByComposer.values()].map((mounted) => mounted.hostId));
35838
36445
  await Promise.all(
35839
- [...hostIds].map(async (hostId) => {
35840
- const accounts = codexAccountsForHost(hostId);
36446
+ [...hostIds].map(async (hostId2) => {
36447
+ const accounts = codexAccountsForHost(hostId2);
35841
36448
  if (!accounts) return;
35842
36449
  await accounts.refresh();
35843
- if (disposed || codexAccountsForHost(hostId) !== accounts) return;
36450
+ if (disposed || codexAccountsForHost(hostId2) !== accounts) return;
35844
36451
  for (const mounted of mountedByComposer.values()) {
35845
- if (mounted.hostId !== hostId) continue;
36452
+ if (mounted.hostId !== hostId2) continue;
35846
36453
  renderMounted(mounted);
35847
36454
  void refreshDraftCodexUsage(mounted);
35848
36455
  }
@@ -35853,16 +36460,16 @@ ${accounts_default}`;
35853
36460
  const url2 = RENDERER_AGENT_INSTALL_URLS[agent];
35854
36461
  window.open(url2, "_blank", "noopener,noreferrer");
35855
36462
  };
35856
- function resetHarnessAvailabilityRetry(hostId) {
35857
- const state = hostHarnessAvailabilityState(hostId);
36463
+ function resetHarnessAvailabilityRetry(hostId2) {
36464
+ const state = hostHarnessAvailabilityState(hostId2);
35858
36465
  if (state.retryTimer !== null) {
35859
36466
  window.clearTimeout(state.retryTimer);
35860
36467
  state.retryTimer = null;
35861
36468
  }
35862
36469
  state.retryAttempt = 0;
35863
36470
  }
35864
- function scheduleHarnessAvailabilityRetry(hostId) {
35865
- const state = hostHarnessAvailabilityState(hostId);
36471
+ function scheduleHarnessAvailabilityRetry(hostId2) {
36472
+ const state = hostHarnessAvailabilityState(hostId2);
35866
36473
  if (disposed || state.retryTimer !== null || state.retryAttempt >= availabilityRetryDelays.length) {
35867
36474
  return;
35868
36475
  }
@@ -35870,50 +36477,50 @@ ${accounts_default}`;
35870
36477
  state.retryAttempt += 1;
35871
36478
  state.retryTimer = window.setTimeout(() => {
35872
36479
  state.retryTimer = null;
35873
- void refreshHarnessAvailabilityForHost(hostId, true, true);
36480
+ void refreshHarnessAvailabilityForHost(hostId2, true, true);
35874
36481
  }, delay);
35875
36482
  }
35876
- function modelClientForHostFrom(control, hostId) {
35877
- if (!control || !hostId) return null;
35878
- if (control.clientForHost) return control.clientForHost(hostId);
35879
- if (!control.currentHostId) return hostId === "local" ? control : null;
35880
- return control.currentHostId() === hostId ? control : null;
36483
+ function modelClientForHostFrom(control, hostId2) {
36484
+ if (!control || !hostId2) return null;
36485
+ if (control.clientForHost) return control.clientForHost(hostId2);
36486
+ if (!control.currentHostId) return hostId2 === "local" ? control : null;
36487
+ return control.currentHostId() === hostId2 ? control : null;
35881
36488
  }
35882
- function modelClientForHost(hostId) {
35883
- return modelClientForHostFrom(modelControl, hostId);
36489
+ function modelClientForHost(hostId2) {
36490
+ return modelClientForHostFrom(modelControl, hostId2);
35884
36491
  }
35885
- function refreshHarnessAvailabilityForHost(hostId, refresh = false, retry = false, force = false) {
35886
- const state = hostHarnessAvailabilityState(hostId);
35887
- if (!retry) resetHarnessAvailabilityRetry(hostId);
35888
- const client = modelClientForHost(hostId);
36492
+ function refreshHarnessAvailabilityForHost(hostId2, refresh = false, retry = false, force = false) {
36493
+ const state = hostHarnessAvailabilityState(hostId2);
36494
+ if (!retry) resetHarnessAvailabilityRetry(hostId2);
36495
+ const client = modelClientForHost(hostId2);
35889
36496
  if (!client) {
35890
36497
  if (state.request) {
35891
36498
  state.requestGeneration += 1;
35892
36499
  state.request = null;
35893
36500
  }
35894
- if (force || [...mountedByComposer.values()].some((mounted) => mounted.hostId === hostId)) {
36501
+ if (force || [...mountedByComposer.values()].some((mounted) => mounted.hostId === hostId2)) {
35895
36502
  for (const agent of externalAgents) {
35896
36503
  state.availability[agent] = "error";
35897
36504
  state.errors[agent] = {
35898
36505
  code: "unavailable",
35899
- message: `Renderer connection is unavailable for Host ${hostId}`,
36506
+ message: `Renderer connection is unavailable for Host ${hostId2}`,
35900
36507
  retryable: true,
35901
36508
  stage: "request"
35902
36509
  };
35903
36510
  state.webUi[agent] = false;
35904
36511
  }
35905
36512
  publishConnectionStatus();
35906
- if (hostId === activeAvailabilityHostId) {
36513
+ if (hostId2 === activeAvailabilityHostId) {
35907
36514
  for (const mounted of mountedByComposer.values()) renderMounted(mounted);
35908
36515
  }
35909
36516
  }
35910
- scheduleHarnessAvailabilityRetry(hostId);
36517
+ scheduleHarnessAvailabilityRetry(hostId2);
35911
36518
  return Promise.resolve();
35912
36519
  }
35913
36520
  if (state.request?.client === client) return state.request.promise;
35914
36521
  const agentsToInspect = force ? externalAgents : passiveHarnessAvailabilityAgents(state.availability, state.errors);
35915
36522
  if (agentsToInspect.length === 0) {
35916
- resetHarnessAvailabilityRetry(hostId);
36523
+ resetHarnessAvailabilityRetry(hostId2);
35917
36524
  return Promise.resolve();
35918
36525
  }
35919
36526
  const nextAvailability = { ...state.availability };
@@ -35921,7 +36528,7 @@ ${accounts_default}`;
35921
36528
  nextAvailability[agent] = harnessAvailabilityDuringInspect(nextAvailability[agent]);
35922
36529
  }
35923
36530
  state.availability = nextAvailability;
35924
- if (hostId === activeAvailabilityHostId) {
36531
+ if (hostId2 === activeAvailabilityHostId) {
35925
36532
  publishConnectionStatus();
35926
36533
  for (const mounted of mountedByComposer.values()) renderMounted(mounted);
35927
36534
  }
@@ -35938,7 +36545,7 @@ ${accounts_default}`;
35938
36545
  { priority: "background" }
35939
36546
  );
35940
36547
  status = inspection.status === "ready" ? "ready" : inspection.status;
35941
- webUiAvailable = hostId === "local" && inspection.status === "ready" && inspection.webUi?.open === true;
36548
+ webUiAvailable = hostId2 === "local" && inspection.status === "ready" && inspection.webUi?.open === true;
35942
36549
  if (inspection.status !== "ready") {
35943
36550
  const error51 = inspection.error;
35944
36551
  nextError = {
@@ -35966,17 +36573,17 @@ ${accounts_default}`;
35966
36573
  state.availability = { ...state.availability, [agent]: status };
35967
36574
  state.webUi = { ...state.webUi, [agent]: webUiAvailable };
35968
36575
  for (const mounted of mountedByComposer.values()) {
35969
- if (mounted.hostId !== hostId) continue;
36576
+ if (mounted.hostId !== hostId2) continue;
35970
36577
  const composerState = controller.get(mounted.composer);
35971
36578
  if (composerAdapterState(mounted) === "ready" && composerState.phase === "draft" && composerState.agent === agent && status !== "ready") {
35972
36579
  await switchComposerAgent(mounted, "codex");
35973
36580
  }
35974
36581
  }
35975
36582
  for (const mounted of mountedByComposer.values()) {
35976
- if (mounted.hostId !== hostId) continue;
36583
+ if (mounted.hostId !== hostId2) continue;
35977
36584
  const composerState = controller.get(mounted.composer);
35978
36585
  const pendingCatalog = catalogRequests.get(mounted);
35979
- const loadingCurrentCatalog = pendingCatalog?.client === client && pendingCatalog.hostId === hostId && pendingCatalog.agent === agent && isCurrentModelRequest(mounted, pendingCatalog.generation);
36586
+ const loadingCurrentCatalog = pendingCatalog?.client === client && pendingCatalog.hostId === hostId2 && pendingCatalog.agent === agent && isCurrentModelRequest(mounted, pendingCatalog.generation);
35980
36587
  if (composerState.agent === agent && (status !== "ready" || !loadingCurrentCatalog || refresh && force) && shouldReloadExternalCatalogAfterAvailabilityRefresh(
35981
36588
  previousStatus,
35982
36589
  status,
@@ -35992,9 +36599,9 @@ ${accounts_default}`;
35992
36599
  );
35993
36600
  if (generation !== state.requestGeneration || disposed) return;
35994
36601
  if (retryableHarnessAvailabilityAgents(state.availability, state.errors).length === 0) {
35995
- resetHarnessAvailabilityRetry(hostId);
36602
+ resetHarnessAvailabilityRetry(hostId2);
35996
36603
  } else {
35997
- scheduleHarnessAvailabilityRetry(hostId);
36604
+ scheduleHarnessAvailabilityRetry(hostId2);
35998
36605
  }
35999
36606
  })();
36000
36607
  const request = { client, promise: promise2 };
@@ -36011,12 +36618,12 @@ ${accounts_default}`;
36011
36618
  }
36012
36619
  const reloadMountedOwnershipForHost = () => {
36013
36620
  for (const mounted of mountedByComposer.values()) {
36014
- const hostId = activeModelHostId(mounted.composer);
36015
- if (!hostId || mounted.hostId === hostId) continue;
36621
+ const hostId2 = activeModelHostId(mounted.composer);
36622
+ if (!hostId2 || mounted.hostId === hostId2) continue;
36016
36623
  if (!threadIdFromComposerModelTarget(mounted.modelTarget)) {
36017
36624
  controller.clearPendingSubmission(mounted.composer);
36018
36625
  controller.beginModelRequest(mounted.composer);
36019
- mounted.hostId = hostId;
36626
+ mounted.hostId = hostId2;
36020
36627
  mounted.modelView = { status: "idle" };
36021
36628
  mounted.permissionModeView = { status: "idle" };
36022
36629
  mounted.usage = null;
@@ -36029,13 +36636,13 @@ ${accounts_default}`;
36029
36636
  void loadExternalCatalog(mounted);
36030
36637
  continue;
36031
36638
  }
36032
- const target = controllerTarget(mounted.modelTarget, hostId);
36639
+ const target = controllerTarget(mounted.modelTarget, hostId2);
36033
36640
  if (controller.rebindConversation(mounted.composer, target) === null) {
36034
36641
  mounted.ownershipStatus = "error";
36035
36642
  renderMounted(mounted);
36036
36643
  continue;
36037
36644
  }
36038
- mounted.hostId = hostId;
36645
+ mounted.hostId = hostId2;
36039
36646
  mounted.composerId = controller.get(mounted.composer).composerId;
36040
36647
  mounted.modelView = { status: "idle" };
36041
36648
  mounted.permissionModeView = { status: "idle" };
@@ -36056,8 +36663,8 @@ ${accounts_default}`;
36056
36663
  sidebarAgentIcons.refresh();
36057
36664
  };
36058
36665
  function reconcileHarnessAvailabilityHost() {
36059
- for (const hostId2 of modelControl?.knownHostIds?.() ?? []) {
36060
- hostHarnessAvailabilityState(hostId2);
36666
+ for (const hostId3 of modelControl?.knownHostIds?.() ?? []) {
36667
+ hostHarnessAvailabilityState(hostId3);
36061
36668
  }
36062
36669
  reloadMountedOwnershipForHost();
36063
36670
  for (const target of new Set([...mountedByComposer.values()].map((m) => m.hostId))) {
@@ -36078,14 +36685,14 @@ ${accounts_default}`;
36078
36685
  } catch {
36079
36686
  }
36080
36687
  }
36081
- const hostId = activeModelHostId();
36082
- if (!hostId || hostId === activeAvailabilityHostId && [...mountedByComposer.values()].every((mounted) => mounted.hostId !== null))
36688
+ const hostId2 = activeModelHostId();
36689
+ if (!hostId2 || hostId2 === activeAvailabilityHostId && [...mountedByComposer.values()].every((mounted) => mounted.hostId !== null))
36083
36690
  return;
36084
- activeAvailabilityHostId = hostId;
36085
- hostHarnessAvailabilityState(hostId);
36691
+ activeAvailabilityHostId = hostId2;
36692
+ hostHarnessAvailabilityState(hostId2);
36086
36693
  publishConnectionStatus();
36087
36694
  for (const mounted of mountedByComposer.values()) renderMounted(mounted);
36088
- void refreshHarnessAvailabilityForHost(hostId);
36695
+ void refreshHarnessAvailabilityForHost(hostId2);
36089
36696
  }
36090
36697
  const refreshHarnessAvailability = async (refresh = false) => {
36091
36698
  reconcileHarnessAvailabilityHost();
@@ -36094,22 +36701,22 @@ ${accounts_default}`;
36094
36701
  if (mounted.hostId) hostIds.add(mounted.hostId);
36095
36702
  }
36096
36703
  await Promise.all(
36097
- [...hostIds].map((hostId) => refreshHarnessAvailabilityForHost(hostId, refresh))
36704
+ [...hostIds].map((hostId2) => refreshHarnessAvailabilityForHost(hostId2, refresh))
36098
36705
  );
36099
36706
  };
36100
36707
  connectionDiagnostics = {
36101
36708
  snapshot() {
36102
36709
  const hostIds = [
36103
36710
  "local",
36104
- ...[...harnessAvailabilityByHost.keys()].filter((hostId) => hostId !== "local").sort()
36711
+ ...[...harnessAvailabilityByHost.keys()].filter((hostId2) => hostId2 !== "local").sort()
36105
36712
  ];
36106
36713
  return {
36107
36714
  adapter: { ...adapterStatus },
36108
- hosts: hostIds.map((hostId) => {
36109
- const state = hostHarnessAvailabilityState(hostId);
36715
+ hosts: hostIds.map((hostId2) => {
36716
+ const state = hostHarnessAvailabilityState(hostId2);
36110
36717
  return {
36111
- hostId,
36112
- active: hostId === activeAvailabilityHostId,
36718
+ hostId: hostId2,
36719
+ active: hostId2 === activeAvailabilityHostId,
36113
36720
  agents: externalAgents.map((agent) => ({
36114
36721
  agent,
36115
36722
  availability: state.availability[agent] ?? "checking",
@@ -36120,10 +36727,10 @@ ${accounts_default}`;
36120
36727
  })
36121
36728
  };
36122
36729
  },
36123
- refresh(hostId) {
36124
- if (hostId !== void 0) {
36730
+ refresh(hostId2) {
36731
+ if (hostId2 !== void 0) {
36125
36732
  return refreshConnectionHosts(
36126
- [hostId],
36733
+ [hostId2],
36127
36734
  (target) => refreshHarnessAvailabilityForHost(target, true, false, true),
36128
36735
  (target) => hostHarnessAvailabilityState(target).request?.promise
36129
36736
  );
@@ -36134,25 +36741,25 @@ ${accounts_default}`;
36134
36741
  (target) => refreshHarnessAvailabilityForHost(target, true, false, true)
36135
36742
  );
36136
36743
  },
36137
- async installation(hostId, agent, action) {
36138
- const client = modelClientForHost(hostId);
36744
+ async installation(hostId2, agent, action) {
36745
+ const client = modelClientForHost(hostId2);
36139
36746
  if (!client?.installation)
36140
36747
  throw new Error("Harness version management is unavailable on this Host");
36141
36748
  return client.installation({ harnessId: externalHarnessIds[agent], action });
36142
36749
  },
36143
- async getLaunchSettings(hostId, agent) {
36144
- const client = hostId === "local" ? modelClientForHost(hostId) : null;
36750
+ async getLaunchSettings(hostId2, agent) {
36751
+ const client = hostId2 === "local" ? modelClientForHost(hostId2) : null;
36145
36752
  if (!client?.getHarnessLaunchSettings) throw new Error("Launch settings are unavailable");
36146
36753
  return client.getHarnessLaunchSettings({ harnessId: externalHarnessIds[agent] });
36147
36754
  },
36148
- async setLaunchSettings(hostId, agent, path) {
36149
- const client = hostId === "local" ? modelClientForHost(hostId) : null;
36755
+ async setLaunchSettings(hostId2, agent, path) {
36756
+ const client = hostId2 === "local" ? modelClientForHost(hostId2) : null;
36150
36757
  if (!client?.setHarnessLaunchSettings) throw new Error("Launch settings are unavailable");
36151
36758
  return client.setHarnessLaunchSettings({ harnessId: externalHarnessIds[agent], path });
36152
36759
  },
36153
- async openWebUi(hostId, agent) {
36154
- const state = hostHarnessAvailabilityState(hostId);
36155
- const client = hostId === "local" ? modelClientForHost(hostId) : null;
36760
+ async openWebUi(hostId2, agent) {
36761
+ const state = hostHarnessAvailabilityState(hostId2);
36762
+ const client = hostId2 === "local" ? modelClientForHost(hostId2) : null;
36156
36763
  if (state.availability[agent] !== "ready" || state.webUi[agent] !== true || !client?.openHarnessWebUi) {
36157
36764
  throw new Error("Harness Web UI is unavailable");
36158
36765
  }
@@ -36161,7 +36768,7 @@ ${accounts_default}`;
36161
36768
  } catch (error51) {
36162
36769
  state.webUi = { ...state.webUi, [agent]: false };
36163
36770
  publishConnectionStatus();
36164
- void refreshHarnessAvailabilityForHost(hostId, true, false, true).catch(() => void 0);
36771
+ void refreshHarnessAvailabilityForHost(hostId2, true, false, true).catch(() => void 0);
36165
36772
  throw error51;
36166
36773
  }
36167
36774
  },
@@ -36171,19 +36778,19 @@ ${accounts_default}`;
36171
36778
  }
36172
36779
  };
36173
36780
  const mount = (composer) => {
36174
- if (mountedByComposer.has(composer) || !composer.isConnected || !composer.matches(CODEX_COMPOSER_SELECTOR)) {
36781
+ if (mountedByComposer.has(composer) || !composer.isConnected || isOrbitComposer(composer) || !composer.matches(CODEX_COMPOSER_SELECTOR)) {
36175
36782
  return;
36176
36783
  }
36177
36784
  const allButtons = [...composer.querySelectorAll("button")];
36178
36785
  const sendButton = sendButtonWithin(composer) ?? allButtons.at(-1) ?? null;
36179
36786
  if (!sendButton) return;
36180
36787
  const modelTarget = findComposerModelTarget(composer);
36181
- const hostId = activeModelHostId(composer);
36788
+ const hostId2 = activeModelHostId(composer);
36182
36789
  const editor = composer.querySelector(EDITOR_SELECTOR);
36183
36790
  if (!editor) return;
36184
36791
  const state = controller.mount(
36185
36792
  composer,
36186
- controllerTarget(modelTarget, hostId),
36793
+ controllerTarget(modelTarget, hostId2),
36187
36794
  modelTarget?.[0] === "default" ? readNewThreadAgentPreference(enabledAgentSet) : void 0
36188
36795
  );
36189
36796
  const inherited = pendingReplacements.get(composer)?.source;
@@ -36233,7 +36840,7 @@ ${accounts_default}`;
36233
36840
  threadConfiguration: inherited?.threadConfiguration,
36234
36841
  usage: inherited?.usage ?? null,
36235
36842
  accountCredits: inherited?.accountCredits ?? null,
36236
- hostId: inherited?.hostId ?? hostId,
36843
+ hostId: inherited?.hostId ?? hostId2,
36237
36844
  usageRequestGeneration: 0,
36238
36845
  commandRequestGeneration: 0
36239
36846
  };
@@ -36259,11 +36866,12 @@ ${accounts_default}`;
36259
36866
  refreshTargetsOnNextScan = false;
36260
36867
  if (disposed) return;
36261
36868
  settingsLifecycle.refresh();
36869
+ const transferredComposers = /* @__PURE__ */ new Set();
36262
36870
  for (const [target, replacement] of pendingReplacements) {
36263
36871
  const sourceState = controller.get(replacement.source.composer);
36264
36872
  const replacementTarget = findComposerModelTarget(target);
36265
36873
  const replacementHostId = activeModelHostId(target);
36266
- if (!shouldTransferComposerState(
36874
+ if (isOrbitComposer(target) || !shouldTransferComposerState(
36267
36875
  replacement.sourceModelTarget,
36268
36876
  replacementTarget,
36269
36877
  sourceState.phase,
@@ -36274,10 +36882,12 @@ ${accounts_default}`;
36274
36882
  controllerTarget(replacementTarget, replacementHostId)
36275
36883
  )) {
36276
36884
  pendingReplacements.delete(target);
36885
+ } else {
36886
+ transferredComposers.add(replacement.source.composer);
36277
36887
  }
36278
36888
  }
36279
36889
  for (const [composer, mounted] of mountedByComposer) {
36280
- if (!composer.isConnected || !composer.matches(CODEX_COMPOSER_SELECTOR) || !mounted.control.root.isConnected) {
36890
+ if (!composer.isConnected || isOrbitComposer(composer) || !composer.matches(CODEX_COMPOSER_SELECTOR) || !mounted.control.root.isConnected) {
36281
36891
  mounted.usageRequestGeneration += 1;
36282
36892
  usageRefreshAttempts.delete(composer);
36283
36893
  const timer = usageRefreshTimers.get(composer);
@@ -36288,6 +36898,7 @@ ${accounts_default}`;
36288
36898
  mounted.codexUsageGate.dispose();
36289
36899
  disposeComposerAgentControl(mounted.control);
36290
36900
  mountedByComposer.delete(composer);
36901
+ controller.detach(composer, transferredComposers.has(composer));
36291
36902
  continue;
36292
36903
  }
36293
36904
  const state = controller.get(composer);
@@ -36359,6 +36970,7 @@ ${accounts_default}`;
36359
36970
  }
36360
36971
  };
36361
36972
  const applyComposerAgent = (composer) => {
36973
+ if (!isMountedComposer(composer)) return false;
36362
36974
  const state = controller.get(composer);
36363
36975
  const mounted = mountedByComposer.get(composer);
36364
36976
  if (mounted?.modelTarget?.[0] === "conversation") {
@@ -36459,8 +37071,8 @@ ${accounts_default}`;
36459
37071
  });
36460
37072
  const onHostRouteChange = () => {
36461
37073
  for (const mounted of mountedByComposer.values()) {
36462
- const hostId = activeModelHostId(mounted.composer);
36463
- if (hostId && mounted.hostId === hostId && !threadIdFromComposerModelTarget(mounted.modelTarget) && controller.get(mounted.composer).agent !== "codex" && !controller.isSwitching(mounted.composer) && isExternalConfigurationStable(mounted.modelView, mounted.permissionModeView)) {
37074
+ const hostId2 = activeModelHostId(mounted.composer);
37075
+ if (hostId2 && mounted.hostId === hostId2 && !threadIdFromComposerModelTarget(mounted.modelTarget) && controller.get(mounted.composer).agent !== "codex" && !controller.isSwitching(mounted.composer) && isExternalConfigurationStable(mounted.modelView, mounted.permissionModeView)) {
36464
37076
  applyComposerAgent(mounted.composer);
36465
37077
  }
36466
37078
  }
@@ -36523,11 +37135,11 @@ ${accounts_default}`;
36523
37135
  const onDraftWorkspace = (event) => {
36524
37136
  const detail = event.detail;
36525
37137
  if (typeof detail !== "object" || detail === null) return;
36526
- const { hostId, cwd } = detail;
36527
- if (typeof hostId !== "string" || typeof cwd !== "string" || cwd.length === 0) return;
36528
- draftWorkspaces.set(hostId, cwd);
37138
+ const { hostId: hostId2, cwd } = detail;
37139
+ if (typeof hostId2 !== "string" || typeof cwd !== "string" || cwd.length === 0) return;
37140
+ draftWorkspaces.set(hostId2, cwd);
36529
37141
  for (const mounted of mountedByComposer.values()) {
36530
- if (!threadIdFromComposerModelTarget(mounted.modelTarget) && activeModelHostId(mounted.composer) === hostId && controller.get(mounted.composer).agent !== "codex") {
37142
+ if (!threadIdFromComposerModelTarget(mounted.modelTarget) && activeModelHostId(mounted.composer) === hostId2 && controller.get(mounted.composer).agent !== "codex") {
36531
37143
  void refreshCommands(mounted, { keepCurrent: true });
36532
37144
  }
36533
37145
  }
@@ -36552,7 +37164,7 @@ ${accounts_default}`;
36552
37164
  },
36553
37165
  isComposerEditor: (editor) => {
36554
37166
  const composer = composerForElement(editor);
36555
- return composer !== null && mountedByComposer.has(composer);
37167
+ return composer !== null && isMountedComposer(composer);
36556
37168
  },
36557
37169
  readLocale: () => settingsLifecycle.locale,
36558
37170
  // Desktop's own suggestion menu hugs the input card and covers the
@@ -36580,9 +37192,10 @@ ${accounts_default}`;
36580
37192
  }
36581
37193
  });
36582
37194
  const connectedComposers = () => [...mountedByComposer.values()].filter(
36583
- (mounted) => mounted.composer.isConnected && mounted.control.root.isConnected
37195
+ (mounted) => isMountedComposer(mounted.composer) && mounted.control.root.isConnected
36584
37196
  );
36585
37197
  const api = {
37198
+ remoteConnections: (request) => handleRemoteConnectionsRequest(remoteConnections, request),
36586
37199
  currentThreadId() {
36587
37200
  const mounted = connectedComposers();
36588
37201
  return mounted.length === 1 && mounted[0] ? threadIdFromComposerModelTarget(mounted[0].modelTarget) ?? null : null;
@@ -36717,9 +37330,9 @@ ${accounts_default}`;
36717
37330
  }
36718
37331
 
36719
37332
  // src/install-renderer-binding.ts
36720
- function installRendererBinding(enabledAgents = DEFAULT_RENDERER_AGENTS, defaultAgent = "codex") {
37333
+ function installRendererBinding(enabledAgents = DEFAULT_RENDERER_AGENTS) {
36721
37334
  window.__codexhostRendererBindingProbeV1?.dispose();
36722
- const binding = installRendererBindingProbe({ enabledAgents, defaultAgent });
37335
+ const binding = installRendererBindingProbe({ enabledAgents });
36723
37336
  try {
36724
37337
  const adapter = installCurrentRendererAdapter();
36725
37338
  binding.setAdapter(adapter.status, adapter.dispose, adapter.applyAgent, adapter.modelControl);
@@ -36739,10 +37352,8 @@ ${accounts_default}`;
36739
37352
  }
36740
37353
 
36741
37354
  // src/production-entry.ts
36742
- var configuration = window.__codexhostProductionConfigV1;
36743
- delete window.__codexhostProductionConfigV1;
36744
37355
  var install = () => {
36745
- installRendererBinding(DEFAULT_RENDERER_AGENTS, configuration?.defaultAgent ?? "codex");
37356
+ installRendererBinding(DEFAULT_RENDERER_AGENTS);
36746
37357
  };
36747
37358
  if (document.documentElement && document.body) {
36748
37359
  install();
@@ -36765,6 +37376,8 @@ lucide/dist/esm/icons/circle-off.mjs:
36765
37376
  lucide/dist/esm/icons/copy.mjs:
36766
37377
  lucide/dist/esm/icons/download.mjs:
36767
37378
  lucide/dist/esm/icons/external-link.mjs:
37379
+ lucide/dist/esm/icons/eye.mjs:
37380
+ lucide/dist/esm/icons/eye-off.mjs:
36768
37381
  lucide/dist/esm/icons/ellipsis.mjs:
36769
37382
  lucide/dist/esm/icons/folder-input.mjs:
36770
37383
  lucide/dist/esm/icons/grip-vertical.mjs: