@codexhost/cli-linux-x64 0.2.3 → 0.2.5

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.
@@ -17275,14 +17275,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17275
17275
  var SIDEBAR_THREAD_ID_ATTRIBUTE = "data-app-action-sidebar-thread-id";
17276
17276
  var SIDEBAR_THREAD_HOST_ID_ATTRIBUTE = "data-app-action-sidebar-thread-host-id";
17277
17277
  var SIDEBAR_AGENT_ICON_ATTRIBUTE = "data-codexhost-sidebar-agent-icon";
17278
+ var OWNERSHIP_RETRY_DELAYS_MS = [100, 300, 800, 1500, 3e3];
17278
17279
  function isRecord2(value) {
17279
17280
  return typeof value === "object" && value !== null && !Array.isArray(value);
17280
17281
  }
17281
- function threadIdFromSidebarRowElement(element) {
17282
+ function sidebarThreadAttributes(element) {
17282
17283
  const taskKey = element.getAttribute(SIDEBAR_THREAD_ID_ATTRIBUTE);
17283
17284
  const hostId = element.getAttribute(SIDEBAR_THREAD_HOST_ID_ATTRIBUTE);
17284
17285
  const rowMarker = element.getAttribute(SIDEBAR_THREAD_ROW_ATTRIBUTE);
17285
17286
  if (taskKey === null || hostId === null || rowMarker === null) return null;
17287
+ return { taskKey, hostId, rowMarker };
17288
+ }
17289
+ function draftIdFromSidebarRowElement(element) {
17290
+ const attributes = sidebarThreadAttributes(element);
17291
+ if (!attributes) return null;
17292
+ const hostPrefix = `${attributes.hostId}:`;
17293
+ const taskKey = attributes.taskKey.startsWith(hostPrefix) ? attributes.taskKey.slice(hostPrefix.length) : attributes.taskKey;
17294
+ return taskKey.startsWith("client-new-thread:") ? taskKey : null;
17295
+ }
17296
+ function threadIdFromSidebarRowElement(element) {
17297
+ const attributes = sidebarThreadAttributes(element);
17298
+ if (!attributes) return null;
17299
+ const { taskKey, hostId, rowMarker } = attributes;
17286
17300
  const fiberNames = Object.getOwnPropertyNames(element).filter(
17287
17301
  (name) => name.startsWith("__reactFiber$")
17288
17302
  );
@@ -17324,6 +17338,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17324
17338
  threadId() {
17325
17339
  return threadIdFromSidebarRowElement(this.element);
17326
17340
  }
17341
+ draftId() {
17342
+ return draftIdFromSidebarRowElement(this.element);
17343
+ }
17327
17344
  render(agent) {
17328
17345
  const titleTrigger = this.element.querySelector("[data-thread-title-trigger]");
17329
17346
  const title = titleTrigger?.querySelector("[data-thread-title]");
@@ -17403,6 +17420,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17403
17420
  const ownershipByThread = /* @__PURE__ */ new Map();
17404
17421
  const pending = /* @__PURE__ */ new Set();
17405
17422
  const failed = /* @__PURE__ */ new Set();
17423
+ const provisionalCodex = /* @__PURE__ */ new Set();
17424
+ const ownershipRetryAttempts = /* @__PURE__ */ new Map();
17425
+ const ownershipRetryTimers = /* @__PURE__ */ new Map();
17406
17426
  let disposed = false;
17407
17427
  let scanScheduled = false;
17408
17428
  const scheduleScan = () => {
@@ -17410,6 +17430,30 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17410
17430
  scanScheduled = true;
17411
17431
  queueMicrotask(scan);
17412
17432
  };
17433
+ const clearOwnershipRetry = (threadId) => {
17434
+ const timer = ownershipRetryTimers.get(threadId);
17435
+ if (timer !== void 0) clearTimeout(timer);
17436
+ ownershipRetryTimers.delete(threadId);
17437
+ ownershipRetryAttempts.delete(threadId);
17438
+ provisionalCodex.delete(threadId);
17439
+ };
17440
+ const scheduleOwnershipRetry = (threadId) => {
17441
+ if (disposed || !provisionalCodex.has(threadId) || pending.has(threadId) || ownershipRetryTimers.has(threadId)) {
17442
+ return;
17443
+ }
17444
+ const attempt = ownershipRetryAttempts.get(threadId) ?? 0;
17445
+ const delay = OWNERSHIP_RETRY_DELAYS_MS[attempt];
17446
+ if (delay === void 0) return;
17447
+ ownershipRetryAttempts.set(threadId, attempt + 1);
17448
+ const timer = setTimeout(() => {
17449
+ ownershipRetryTimers.delete(threadId);
17450
+ if (disposed) return;
17451
+ failed.delete(threadId);
17452
+ ownershipByThread.delete(threadId);
17453
+ scheduleScan();
17454
+ }, delay);
17455
+ ownershipRetryTimers.set(threadId, timer);
17456
+ };
17413
17457
  const requestOwnership = (threadIds, client) => {
17414
17458
  for (const threadId of threadIds) pending.add(threadId);
17415
17459
  let succeeded = false;
@@ -17418,6 +17462,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17418
17462
  for (const ownership of threads) {
17419
17463
  ownershipByThread.set(ownership.threadId, rendererAgentForThreadOwnership(ownership));
17420
17464
  failed.delete(ownership.threadId);
17465
+ if (ownership.owner === "codex") {
17466
+ provisionalCodex.add(ownership.threadId);
17467
+ scheduleOwnershipRetry(ownership.threadId);
17468
+ } else {
17469
+ clearOwnershipRetry(ownership.threadId);
17470
+ }
17421
17471
  }
17422
17472
  succeeded = true;
17423
17473
  }).catch(() => {
@@ -17425,6 +17475,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17425
17475
  for (const threadId of threadIds) failed.add(threadId);
17426
17476
  }).finally(() => {
17427
17477
  for (const threadId of threadIds) pending.delete(threadId);
17478
+ for (const threadId of threadIds) scheduleOwnershipRetry(threadId);
17428
17479
  if (succeeded) scheduleScan();
17429
17480
  });
17430
17481
  };
@@ -17433,8 +17484,25 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17433
17484
  if (disposed) return;
17434
17485
  const unresolved = /* @__PURE__ */ new Set();
17435
17486
  for (const row of dom.rows()) {
17487
+ if (!row.isConnected()) {
17488
+ row.clear();
17489
+ continue;
17490
+ }
17436
17491
  const threadId = hostThreadIdSchema.safeParse(row.threadId());
17437
- if (!row.isConnected() || !threadId.success) {
17492
+ const localAgent = options.getLocalAgent?.({
17493
+ threadId: threadId.success ? threadId.data : null,
17494
+ draftId: row.draftId()
17495
+ });
17496
+ if (localAgent !== null && localAgent !== void 0) {
17497
+ if (threadId.success) {
17498
+ ownershipByThread.set(threadId.data, localAgent === "codex" ? null : localAgent);
17499
+ clearOwnershipRetry(threadId.data);
17500
+ }
17501
+ if (localAgent === "codex") row.clear();
17502
+ else row.render(localAgent);
17503
+ continue;
17504
+ }
17505
+ if (!threadId.success) {
17438
17506
  row.clear();
17439
17507
  continue;
17440
17508
  }
@@ -17461,6 +17529,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17461
17529
  return {
17462
17530
  refresh() {
17463
17531
  failed.clear();
17532
+ for (const threadId of provisionalCodex) {
17533
+ const timer = ownershipRetryTimers.get(threadId);
17534
+ if (timer !== void 0) clearTimeout(timer);
17535
+ ownershipRetryTimers.delete(threadId);
17536
+ ownershipRetryAttempts.delete(threadId);
17537
+ ownershipByThread.delete(threadId);
17538
+ }
17464
17539
  scheduleScan();
17465
17540
  },
17466
17541
  dispose() {
@@ -17471,6 +17546,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17471
17546
  ownershipByThread.clear();
17472
17547
  pending.clear();
17473
17548
  failed.clear();
17549
+ provisionalCodex.clear();
17550
+ for (const timer of ownershipRetryTimers.values()) clearTimeout(timer);
17551
+ ownershipRetryTimers.clear();
17552
+ ownershipRetryAttempts.clear();
17474
17553
  }
17475
17554
  };
17476
17555
  }
@@ -17916,6 +17995,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17916
17995
  return source.includes("send-cli-request-for-host") && hasPrewarmMethod(value.requestClient);
17917
17996
  }
17918
17997
  function matchesCurrentPrewarmSignature(target) {
17998
+ const bridge = target.requestClient ?? target;
17999
+ const stableApiShape = bridge.hostId === "local" && typeof bridge.sendRequest === "function" && typeof bridge.prewarmThreadStart === "function" && typeof bridge.enqueueRequest === "function";
18000
+ if (stableApiShape) return true;
17919
18001
  const prewarm = target.prewarmThreadStart ?? target.requestClient?.prewarmThreadStart;
17920
18002
  if (!prewarm) return false;
17921
18003
  const source = Function.prototype.toString.call(prewarm);
@@ -20177,8 +20259,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20177
20259
  let applyAdapterAgent = null;
20178
20260
  let modelControl = null;
20179
20261
  let usageNotificationDispose = null;
20262
+ const localAgentForSidebarThread = (input) => {
20263
+ for (const mounted of mountedByComposer.values()) {
20264
+ const target = mounted.modelTarget;
20265
+ if (target?.[0] === "default" && input.draftId !== null && target[1] === input.draftId) {
20266
+ return controller.get(mounted.composer).agent;
20267
+ }
20268
+ if (target?.[0] === "conversation" && input.threadId !== null && target[1] === input.threadId && mounted.ownershipStatus === "ready") {
20269
+ return controller.get(mounted.composer).agent;
20270
+ }
20271
+ }
20272
+ return null;
20273
+ };
20180
20274
  const sidebarAgentIcons = installRendererSidebarAgentIcons({
20181
- getClient: () => modelControl
20275
+ getClient: () => modelControl,
20276
+ getLocalAgent: localAgentForSidebarThread
20182
20277
  });
20183
20278
  const settingsLifecycle = installRendererSettingsLifecycle(window, {
20184
20279
  getUpdateClient: () => modelControl
@@ -20194,6 +20289,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20194
20289
  );
20195
20290
  let availabilityRequestGeneration = 0;
20196
20291
  let availabilityRequest = null;
20292
+ let availabilityRetryTimer = null;
20293
+ let availabilityRetryAttempt = 0;
20294
+ const availabilityRetryDelays = [500, 1e3, 2e3, 4e3, 8e3];
20197
20295
  const usageRefreshTimers = /* @__PURE__ */ new Map();
20198
20296
  const usageRefreshAttempts = /* @__PURE__ */ new Map();
20199
20297
  const isMountedComposer = (composer) => composer.isConnected && composer.matches(CODEX_COMPOSER_SELECTOR) && mountedByComposer.has(composer);
@@ -20366,6 +20464,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20366
20464
  } finally {
20367
20465
  if (isCurrentOwnershipRequest(mounted, generation)) {
20368
20466
  renderMounted(mounted);
20467
+ sidebarAgentIcons.refresh();
20369
20468
  if (mounted.ownershipStatus !== "error" && shouldRetryExternalThreadUsage(
20370
20469
  controller.get(mounted.composer).agent,
20371
20470
  mounted.usage,
@@ -20411,6 +20510,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20411
20510
  if (previousTarget?.[0] === "conversation") renderMounted(mounted);
20412
20511
  void loadThreadOwnership(mounted);
20413
20512
  }
20513
+ sidebarAgentIcons.refresh();
20414
20514
  return true;
20415
20515
  };
20416
20516
  const loadExternalCatalog = async (mounted) => {
@@ -20921,6 +21021,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20921
21021
  mounted.modelView = { status: "idle" };
20922
21022
  mounted.permissionModeView = { status: "idle" };
20923
21023
  }
21024
+ sidebarAgentIcons.refresh();
20924
21025
  return switched;
20925
21026
  } catch {
20926
21027
  adapterStatus = {
@@ -20940,7 +21041,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20940
21041
  const url2 = RENDERER_AGENT_INSTALL_URLS[agent];
20941
21042
  window.open(url2, "_blank", "noopener,noreferrer");
20942
21043
  };
20943
- const refreshHarnessAvailability = (refresh = false) => {
21044
+ const resetHarnessAvailabilityRetry = () => {
21045
+ if (availabilityRetryTimer !== null) {
21046
+ window.clearTimeout(availabilityRetryTimer);
21047
+ availabilityRetryTimer = null;
21048
+ }
21049
+ availabilityRetryAttempt = 0;
21050
+ };
21051
+ const scheduleHarnessAvailabilityRetry = () => {
21052
+ if (disposed || availabilityRetryTimer !== null || availabilityRetryAttempt >= availabilityRetryDelays.length) {
21053
+ return;
21054
+ }
21055
+ const delay = availabilityRetryDelays[availabilityRetryAttempt];
21056
+ availabilityRetryAttempt += 1;
21057
+ availabilityRetryTimer = window.setTimeout(() => {
21058
+ availabilityRetryTimer = null;
21059
+ void refreshHarnessAvailability(true, true);
21060
+ }, delay);
21061
+ };
21062
+ const refreshHarnessAvailability = (refresh = false, retry = false) => {
21063
+ if (!retry) resetHarnessAvailabilityRetry();
20944
21064
  if (!modelControl) return Promise.resolve();
20945
21065
  const client = modelControl;
20946
21066
  if (availabilityRequest?.client === client) return availabilityRequest.promise;
@@ -20982,6 +21102,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
20982
21102
  }
20983
21103
  })
20984
21104
  );
21105
+ if (externalAgents.every((agent) => harnessAvailability[agent] === "ready")) {
21106
+ resetHarnessAvailabilityRetry();
21107
+ } else {
21108
+ scheduleHarnessAvailabilityRetry();
21109
+ }
20985
21110
  })();
20986
21111
  const request = { client, promise: promise2 };
20987
21112
  availabilityRequest = request;
@@ -21060,6 +21185,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
21060
21185
  );
21061
21186
  }
21062
21187
  renderMounted(mounted);
21188
+ sidebarAgentIcons.refresh();
21063
21189
  if (threadIdFromComposerModelTarget(modelTarget) && !inherited) {
21064
21190
  void loadThreadOwnership(mounted);
21065
21191
  } else if (threadIdFromComposerModelTarget(modelTarget) && inherited && shouldRetryExternalThreadUsage(state.agent, mounted.usage, mounted.accountCredits)) {
@@ -21384,6 +21510,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
21384
21510
  document.removeEventListener("click", onClick, true);
21385
21511
  window.removeEventListener("codexhost:renderer-adapter-status", onAdapterStatus);
21386
21512
  window.removeEventListener("focus", onWindowFocus);
21513
+ resetHarnessAvailabilityRetry();
21387
21514
  for (const timer of usageRefreshTimers.values()) window.clearTimeout(timer);
21388
21515
  usageRefreshTimers.clear();
21389
21516
  for (const mounted of mountedByComposer.values()) {
package/bin/codexhost CHANGED
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codexhost/cli-linux-x64",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Run Pi and Claude Code as first-class external harnesses inside Codex Desktop.",
5
5
  "type": "module",
6
6
  "files": [