@codexhost/cli-darwin-x64 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ Run Pi and Claude Code as first-class external harnesses inside Codex Desktop.
7
7
  ## Install
8
8
 
9
9
  ```bash
10
- npm install -g @codexhost/cli@0.1.6
10
+ npm install -g @codexhost/cli@0.2.0
11
11
  ```
12
12
 
13
13
  Do not install this package directly. npm selects it through the optional dependencies of `@codexhost/cli`.
@@ -1 +1 @@
1
- {"schemaVersion":1,"version":"0.1.6","distribution":"npm","target":"macos-x64"}
1
+ {"schemaVersion":1,"version":"0.2.0","distribution":"npm","target":"macos-x64"}
@@ -579,17 +579,62 @@ async function readMainProcessTitlePolicyCounters(inspector) {
579
579
  }
580
580
 
581
581
  // packages/desktop-control/src/renderer-draft-prewarm-runtime.ts
582
- function installDraftPrewarmPolicyBridge(send, hostId, target) {
582
+ function installDraftPrewarmPolicyBridge(bridge, hostId, target) {
583
+ const existing = target.__codexhostDraftPrewarmPolicyV1;
584
+ existing?.dispose?.();
585
+ const originalSend = bridge.sendRequest;
586
+ let selectedModel = null;
583
587
  let clearInFlight = null;
588
+ const isRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
589
+ const routeCollaborationMode = (method, parameters) => {
590
+ if (selectedModel === null || !isRecord5(parameters)) return parameters;
591
+ const collaborationMode = parameters.collaborationMode;
592
+ const settings = isRecord5(collaborationMode) ? collaborationMode.settings : null;
593
+ if (!isRecord5(collaborationMode) || !isRecord5(settings)) {
594
+ throw new Error(`Codex ${method} omitted collaborationMode.settings`);
595
+ }
596
+ return {
597
+ ...parameters,
598
+ collaborationMode: {
599
+ ...collaborationMode,
600
+ settings: { ...settings, model: selectedModel }
601
+ }
602
+ };
603
+ };
604
+ const routeThreadStart = (method, parameters) => {
605
+ if (selectedModel === null || !isRecord5(parameters)) return parameters;
606
+ const threadParams = method === "prewarm-thread-start-for-host" ? parameters.params : parameters.method === "thread/start" ? parameters.params : null;
607
+ if (!isRecord5(threadParams) || threadParams.ephemeral === true) return parameters;
608
+ return { ...parameters, params: { ...threadParams, model: selectedModel } };
609
+ };
610
+ const routedSend = (method, parameters, options) => {
611
+ const routedParameters = method === "start-conversation" || method === "prewarm-conversation-for-host" ? routeCollaborationMode(method, parameters) : method === "prewarm-thread-start-for-host" || method === "send-cli-request-for-host" ? routeThreadStart(method, parameters) : parameters;
612
+ return options === void 0 ? originalSend.call(bridge, method, routedParameters) : originalSend.call(bridge, method, routedParameters, options);
613
+ };
614
+ bridge.sendRequest = routedSend;
584
615
  const policy = Object.freeze({
585
616
  state: "ready",
617
+ select(model) {
618
+ if (model !== null && (typeof model !== "string" || !model.startsWith("codexhost/"))) {
619
+ throw new Error("Draft route Model must be a codexhost transport carrier");
620
+ }
621
+ if (selectedModel === model) return false;
622
+ selectedModel = model;
623
+ return true;
624
+ },
586
625
  clear() {
587
626
  if (clearInFlight === null) {
588
- clearInFlight = Promise.resolve(send("clear-prewarmed-threads-for-host", { hostId })).then(() => void 0).finally(() => {
627
+ clearInFlight = Promise.resolve(
628
+ originalSend.call(bridge, "clear-prewarmed-threads-for-host", { hostId })
629
+ ).then(() => void 0).finally(() => {
589
630
  clearInFlight = null;
590
631
  });
591
632
  }
592
633
  return clearInFlight;
634
+ },
635
+ dispose() {
636
+ if (bridge.sendRequest === routedSend) bridge.sendRequest = originalSend;
637
+ selectedModel = null;
593
638
  }
594
639
  });
595
640
  Object.defineProperty(target, "__codexhostDraftPrewarmPolicyV1", {
@@ -712,16 +757,13 @@ function isRecord3(value) {
712
757
  return typeof value === "object" && value !== null && !Array.isArray(value);
713
758
  }
714
759
  var FIND_REQUEST_MANAGER_EXPRESSION = `(() => {
715
- const visibleEditors = [...document.querySelectorAll(
760
+ const editors = [...document.querySelectorAll(
716
761
  '[data-codex-composer], [contenteditable="true"][role="textbox"]',
717
- )].filter((editor) => {
718
- const bounds = editor.getBoundingClientRect();
719
- return bounds.width > 0 && bounds.height > 0;
720
- });
721
- if (visibleEditors.length !== 1) {
762
+ )];
763
+ if (editors.length !== 1) {
722
764
  return { candidateCount: 0, hostId: null, sendRequest: null };
723
765
  }
724
- let element = visibleEditors[0];
766
+ let element = editors[0];
725
767
  let fiber = null;
726
768
  while (element != null && fiber == null) {
727
769
  const key = Object.getOwnPropertyNames(element).find((name) =>
@@ -757,10 +799,10 @@ var FIND_REQUEST_MANAGER_EXPRESSION = `(() => {
757
799
  };
758
800
  })()`;
759
801
  var INSTALL_RENDERER_POLICY_FUNCTION = `function(hostId) {
760
- const bridge = this;
761
- const send = (method, parameters) => bridge.sendRequest(method, parameters);
762
- return (${installDraftPrewarmPolicyBridge.toString()})(send, hostId, window);
802
+ return (${installDraftPrewarmPolicyBridge.toString()})(this, hostId, window);
763
803
  }`;
804
+ var REQUEST_MANAGER_WAIT_TIMEOUT_MS = 6e4;
805
+ var REQUEST_MANAGER_POLL_INTERVAL_MS = 25;
764
806
  function mainProcessInstaller(rendererWebContentsId) {
765
807
  return `async function () {
766
808
  const mainModule = process.mainModule;
@@ -780,11 +822,23 @@ async function installRendererDraftPrewarmPolicy(inspector, rendererWebContentsI
780
822
  throw new Error("Renderer webContents ID must be a positive integer");
781
823
  }
782
824
  const installer = mainProcessInstaller(rendererWebContentsId);
783
- const value = await inspector.evaluate(`(${installer})()`);
784
- if (!isRecord3(value) || value.state !== "ready" || value.reason !== "owned-request-bridge") {
785
- throw new Error("Renderer draft prewarm policy returned an invalid status");
825
+ const deadline = Date.now() + REQUEST_MANAGER_WAIT_TIMEOUT_MS;
826
+ while (true) {
827
+ try {
828
+ const value = await inspector.evaluate(`(${installer})()`);
829
+ if (!isRecord3(value) || value.state !== "ready" || value.reason !== "owned-request-bridge") {
830
+ throw new Error("Renderer draft prewarm policy returned an invalid status");
831
+ }
832
+ return value;
833
+ } catch (error) {
834
+ const message = error instanceof Error ? error.message : String(error);
835
+ const remaining = deadline - Date.now();
836
+ if (!message.includes("Renderer request manager is ambiguous") || remaining <= 0) throw error;
837
+ await new Promise((resolve) => {
838
+ setTimeout(resolve, Math.min(REQUEST_MANAGER_POLL_INTERVAL_MS, remaining));
839
+ });
840
+ }
786
841
  }
787
- return value;
788
842
  }
789
843
 
790
844
  // packages/desktop-control/src/renderer-control-session.ts
@@ -951,6 +1005,11 @@ var defaultOperations = {
951
1005
  installTitlePolicy: installMainProcessTitlePolicy,
952
1006
  markTitlePolicyReady: markRendererTitlePolicyReady,
953
1007
  installDraftPrewarmPolicy: installRendererDraftPrewarmPolicy,
1008
+ readDraftPrewarmPolicy: (inspector, rendererWebContentsId) => executeInWebContents(
1009
+ inspector,
1010
+ rendererWebContentsId,
1011
+ "window.__codexhostDraftPrewarmPolicyV1?.state ?? null"
1012
+ ),
954
1013
  reload: reloadRenderer,
955
1014
  execute: executeInWebContents,
956
1015
  readBinding: (inspector, rendererWebContentsId) => executeInWebContents(
@@ -1022,15 +1081,41 @@ var InstalledRendererControlSession = class {
1022
1081
  );
1023
1082
  const existing = await this.operations.readBinding(this.inspector, selected.id).catch(() => null);
1024
1083
  if (existing !== null) {
1025
- const binding2 = validateBindingStatus(existing, this.enabledAgents);
1026
- this.#snapshot = { ...this.#snapshot, renderer: selected, binding: binding2 };
1084
+ const policyState = await this.operations.readDraftPrewarmPolicy?.(this.inspector, selected.id).catch(() => null);
1085
+ const draftPrewarmPolicy2 = policyState === "ready" ? this.#snapshot.draftPrewarmPolicy : await this.operations.installDraftPrewarmPolicy(this.inspector, selected.id);
1086
+ let binding2;
1087
+ try {
1088
+ binding2 = validateBindingStatus(existing, this.enabledAgents);
1089
+ } catch (error) {
1090
+ if (!(error instanceof RendererAdapterReadinessError)) throw error;
1091
+ await this.operations.execute(this.inspector, selected.id, this.rendererSource);
1092
+ binding2 = await waitForBinding(
1093
+ this.inspector,
1094
+ this.operations,
1095
+ selected.id,
1096
+ this.enabledAgents,
1097
+ this.timeoutMs,
1098
+ this.pollIntervalMs
1099
+ );
1100
+ }
1101
+ this.#snapshot = {
1102
+ ...this.#snapshot,
1103
+ renderer: selected,
1104
+ draftPrewarmPolicy: draftPrewarmPolicy2,
1105
+ binding: binding2
1106
+ };
1027
1107
  return this.#snapshot;
1028
1108
  }
1029
1109
  const titlePolicyReadiness = await waitForRendererTitlePolicyReady(
1030
1110
  () => this.operations.markTitlePolicyReady(this.inspector, selected.id),
1031
1111
  { timeoutMs: this.timeoutMs, pollIntervalMs: this.pollIntervalMs }
1032
1112
  );
1113
+ await activateElectronDesktop(this.inspector);
1033
1114
  await this.operations.execute(this.inspector, selected.id, this.rendererSource);
1115
+ const draftPrewarmPolicy = await this.operations.installDraftPrewarmPolicy(
1116
+ this.inspector,
1117
+ selected.id
1118
+ );
1034
1119
  const binding = await waitForBinding(
1035
1120
  this.inspector,
1036
1121
  this.operations,
@@ -1039,10 +1124,6 @@ var InstalledRendererControlSession = class {
1039
1124
  this.timeoutMs,
1040
1125
  this.pollIntervalMs
1041
1126
  );
1042
- const draftPrewarmPolicy = await this.operations.installDraftPrewarmPolicy(
1043
- this.inspector,
1044
- selected.id
1045
- );
1046
1127
  this.#snapshot = {
1047
1128
  ...this.#snapshot,
1048
1129
  renderer: selected,
@@ -1117,6 +1198,11 @@ async function createRendererControlSession(options) {
1117
1198
  );
1118
1199
  startupTrace("injecting Renderer bundle");
1119
1200
  await operations.execute(options.inspector, selected.id, options.rendererSource);
1201
+ startupTrace("installing draft routing policy");
1202
+ const draftPrewarmPolicy = await operations.installDraftPrewarmPolicy(
1203
+ options.inspector,
1204
+ selected.id
1205
+ );
1120
1206
  startupTrace("waiting for Renderer binding");
1121
1207
  const binding = await waitForBinding(
1122
1208
  options.inspector,
@@ -1126,11 +1212,6 @@ async function createRendererControlSession(options) {
1126
1212
  timeoutMs,
1127
1213
  pollIntervalMs
1128
1214
  );
1129
- startupTrace("installing draft prewarm policy");
1130
- const draftPrewarmPolicy = await operations.installDraftPrewarmPolicy(
1131
- options.inspector,
1132
- selected.id
1133
- );
1134
1215
  return new InstalledRendererControlSession(
1135
1216
  options.inspector,
1136
1217
  options.rendererSource,
@@ -1351,7 +1432,7 @@ async function runDesktopController(options, signal, dependencies = defaultDepen
1351
1432
  inspectorEndpoint: options.inspectorEndpoint,
1352
1433
  rendererSource: `${configuration}
1353
1434
  ${rendererSource}`,
1354
- enabledAgents: ["codex", "pi", "claude-code"],
1435
+ enabledAgents: ["codex", "pi", "claude-code", "deepseek-harness", "grok"],
1355
1436
  timeoutMs: PRODUCTION_INSTALL_TIMEOUT_MS
1356
1437
  },
1357
1438
  dependencies