@codexhost/cli-win32-arm64 0.1.6 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.1
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":"windows-arm64"}
1
+ {"schemaVersion":1,"version":"0.2.1","distribution":"npm","target":"windows-arm64"}
@@ -63,11 +63,6 @@ async function startControllerAttachmentServer(options) {
63
63
  );
64
64
  return;
65
65
  }
66
- if (line === `SHUTDOWN ${options.nonce}`) {
67
- respond(socket, "ready");
68
- queueMicrotask(() => void options.shutdown().catch(() => void 0));
69
- return;
70
- }
71
66
  respond(socket, "rejected");
72
67
  });
73
68
  });
@@ -334,7 +329,7 @@ var ELECTRON_MODULE_EXPRESSION = `(() => {
334
329
  return createRequire(process.execPath)('electron');
335
330
  })()`;
336
331
  var CONNECT_APP_HOST_CHANNEL = "codex_desktop:connect-app-host";
337
- var REVIEWED_TITLE_SERVICE_IDENTITIES = ["Dhe", "Nye", "wbe", "nxe"];
332
+ var REVIEWED_TITLE_SERVICE_IDENTITIES = ["Dhe", "Nye", "wbe", "nxe", "tTe"];
338
333
  var POLICY_STATE_SYMBOL = "codexhost.main-process-title-policy.v1";
339
334
  var SERVICE_OWNER_SYMBOL = "codexhost.main-process-title-policy.owner.v1";
340
335
  var RENDERER_READY_EXPRESSION = "(() => { Object.defineProperty(window, '__codexhostMainProcessTitlePolicyV1', { configurable: true, value: { state: 'ready' } }); return 'ready'; })()";
@@ -579,17 +574,62 @@ async function readMainProcessTitlePolicyCounters(inspector) {
579
574
  }
580
575
 
581
576
  // packages/desktop-control/src/renderer-draft-prewarm-runtime.ts
582
- function installDraftPrewarmPolicyBridge(send, hostId, target) {
577
+ function installDraftPrewarmPolicyBridge(bridge, hostId, target) {
578
+ const existing = target.__codexhostDraftPrewarmPolicyV1;
579
+ existing?.dispose?.();
580
+ const originalSend = bridge.sendRequest;
581
+ let selectedModel = null;
583
582
  let clearInFlight = null;
583
+ const isRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
584
+ const routeCollaborationMode = (method, parameters) => {
585
+ if (selectedModel === null || !isRecord5(parameters)) return parameters;
586
+ const collaborationMode = parameters.collaborationMode;
587
+ const settings = isRecord5(collaborationMode) ? collaborationMode.settings : null;
588
+ if (!isRecord5(collaborationMode) || !isRecord5(settings)) {
589
+ throw new Error(`Codex ${method} omitted collaborationMode.settings`);
590
+ }
591
+ return {
592
+ ...parameters,
593
+ collaborationMode: {
594
+ ...collaborationMode,
595
+ settings: { ...settings, model: selectedModel }
596
+ }
597
+ };
598
+ };
599
+ const routeThreadStart = (method, parameters) => {
600
+ if (selectedModel === null || !isRecord5(parameters)) return parameters;
601
+ const threadParams = method === "prewarm-thread-start-for-host" ? parameters.params : parameters.method === "thread/start" ? parameters.params : null;
602
+ if (!isRecord5(threadParams) || threadParams.ephemeral === true) return parameters;
603
+ return { ...parameters, params: { ...threadParams, model: selectedModel } };
604
+ };
605
+ const routedSend = (method, parameters, options) => {
606
+ 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;
607
+ return options === void 0 ? originalSend.call(bridge, method, routedParameters) : originalSend.call(bridge, method, routedParameters, options);
608
+ };
609
+ bridge.sendRequest = routedSend;
584
610
  const policy = Object.freeze({
585
611
  state: "ready",
612
+ select(model) {
613
+ if (model !== null && (typeof model !== "string" || !model.startsWith("codexhost/"))) {
614
+ throw new Error("Draft route Model must be a codexhost transport carrier");
615
+ }
616
+ if (selectedModel === model) return false;
617
+ selectedModel = model;
618
+ return true;
619
+ },
586
620
  clear() {
587
621
  if (clearInFlight === null) {
588
- clearInFlight = Promise.resolve(send("clear-prewarmed-threads-for-host", { hostId })).then(() => void 0).finally(() => {
622
+ clearInFlight = Promise.resolve(
623
+ originalSend.call(bridge, "clear-prewarmed-threads-for-host", { hostId })
624
+ ).then(() => void 0).finally(() => {
589
625
  clearInFlight = null;
590
626
  });
591
627
  }
592
628
  return clearInFlight;
629
+ },
630
+ dispose() {
631
+ if (bridge.sendRequest === routedSend) bridge.sendRequest = originalSend;
632
+ selectedModel = null;
593
633
  }
594
634
  });
595
635
  Object.defineProperty(target, "__codexhostDraftPrewarmPolicyV1", {
@@ -712,16 +752,13 @@ function isRecord3(value) {
712
752
  return typeof value === "object" && value !== null && !Array.isArray(value);
713
753
  }
714
754
  var FIND_REQUEST_MANAGER_EXPRESSION = `(() => {
715
- const visibleEditors = [...document.querySelectorAll(
755
+ const editors = [...document.querySelectorAll(
716
756
  '[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) {
757
+ )];
758
+ if (editors.length !== 1) {
722
759
  return { candidateCount: 0, hostId: null, sendRequest: null };
723
760
  }
724
- let element = visibleEditors[0];
761
+ let element = editors[0];
725
762
  let fiber = null;
726
763
  while (element != null && fiber == null) {
727
764
  const key = Object.getOwnPropertyNames(element).find((name) =>
@@ -757,10 +794,10 @@ var FIND_REQUEST_MANAGER_EXPRESSION = `(() => {
757
794
  };
758
795
  })()`;
759
796
  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);
797
+ return (${installDraftPrewarmPolicyBridge.toString()})(this, hostId, window);
763
798
  }`;
799
+ var REQUEST_MANAGER_WAIT_TIMEOUT_MS = 6e4;
800
+ var REQUEST_MANAGER_POLL_INTERVAL_MS = 25;
764
801
  function mainProcessInstaller(rendererWebContentsId) {
765
802
  return `async function () {
766
803
  const mainModule = process.mainModule;
@@ -780,11 +817,23 @@ async function installRendererDraftPrewarmPolicy(inspector, rendererWebContentsI
780
817
  throw new Error("Renderer webContents ID must be a positive integer");
781
818
  }
782
819
  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");
820
+ const deadline = Date.now() + REQUEST_MANAGER_WAIT_TIMEOUT_MS;
821
+ while (true) {
822
+ try {
823
+ const value = await inspector.evaluate(`(${installer})()`);
824
+ if (!isRecord3(value) || value.state !== "ready" || value.reason !== "owned-request-bridge") {
825
+ throw new Error("Renderer draft prewarm policy returned an invalid status");
826
+ }
827
+ return value;
828
+ } catch (error) {
829
+ const message = error instanceof Error ? error.message : String(error);
830
+ const remaining = deadline - Date.now();
831
+ if (!message.includes("Renderer request manager is ambiguous") || remaining <= 0) throw error;
832
+ await new Promise((resolve) => {
833
+ setTimeout(resolve, Math.min(REQUEST_MANAGER_POLL_INTERVAL_MS, remaining));
834
+ });
835
+ }
786
836
  }
787
- return value;
788
837
  }
789
838
 
790
839
  // packages/desktop-control/src/renderer-control-session.ts
@@ -926,14 +975,6 @@ async function activateElectronDesktop(inspector) {
926
975
  }
927
976
  return value;
928
977
  }
929
- async function quitElectronDesktop(inspector) {
930
- const accepted = await inspector.evaluate(`(() => {
931
- const { app } = ${electronModuleExpression};
932
- setTimeout(() => app.quit(), 100);
933
- return true;
934
- })()`);
935
- if (accepted !== true) throw new Error("Electron Desktop did not accept the quit request");
936
- }
937
978
  async function executeInWebContents(inspector, rendererWebContentsId, source) {
938
979
  return inspector.evaluate(`(async () => {
939
980
  const { webContents } = ${electronModuleExpression};
@@ -951,6 +992,11 @@ var defaultOperations = {
951
992
  installTitlePolicy: installMainProcessTitlePolicy,
952
993
  markTitlePolicyReady: markRendererTitlePolicyReady,
953
994
  installDraftPrewarmPolicy: installRendererDraftPrewarmPolicy,
995
+ readDraftPrewarmPolicy: (inspector, rendererWebContentsId) => executeInWebContents(
996
+ inspector,
997
+ rendererWebContentsId,
998
+ "window.__codexhostDraftPrewarmPolicyV1?.state ?? null"
999
+ ),
954
1000
  reload: reloadRenderer,
955
1001
  execute: executeInWebContents,
956
1002
  readBinding: (inspector, rendererWebContentsId) => executeInWebContents(
@@ -958,8 +1004,7 @@ var defaultOperations = {
958
1004
  rendererWebContentsId,
959
1005
  "window.__codexhostRendererBindingProbeV1?.status() ?? null"
960
1006
  ),
961
- readTitlePolicyCounters: readMainProcessTitlePolicyCounters,
962
- quitDesktop: quitElectronDesktop
1007
+ readTitlePolicyCounters: readMainProcessTitlePolicyCounters
963
1008
  };
964
1009
  async function waitForRenderer(inspector, operations, timeoutMs, pollIntervalMs) {
965
1010
  const deadline = Date.now() + timeoutMs;
@@ -1022,15 +1067,41 @@ var InstalledRendererControlSession = class {
1022
1067
  );
1023
1068
  const existing = await this.operations.readBinding(this.inspector, selected.id).catch(() => null);
1024
1069
  if (existing !== null) {
1025
- const binding2 = validateBindingStatus(existing, this.enabledAgents);
1026
- this.#snapshot = { ...this.#snapshot, renderer: selected, binding: binding2 };
1070
+ const policyState = await this.operations.readDraftPrewarmPolicy?.(this.inspector, selected.id).catch(() => null);
1071
+ const draftPrewarmPolicy2 = policyState === "ready" ? this.#snapshot.draftPrewarmPolicy : await this.operations.installDraftPrewarmPolicy(this.inspector, selected.id);
1072
+ let binding2;
1073
+ try {
1074
+ binding2 = validateBindingStatus(existing, this.enabledAgents);
1075
+ } catch (error) {
1076
+ if (!(error instanceof RendererAdapterReadinessError)) throw error;
1077
+ await this.operations.execute(this.inspector, selected.id, this.rendererSource);
1078
+ binding2 = await waitForBinding(
1079
+ this.inspector,
1080
+ this.operations,
1081
+ selected.id,
1082
+ this.enabledAgents,
1083
+ this.timeoutMs,
1084
+ this.pollIntervalMs
1085
+ );
1086
+ }
1087
+ this.#snapshot = {
1088
+ ...this.#snapshot,
1089
+ renderer: selected,
1090
+ draftPrewarmPolicy: draftPrewarmPolicy2,
1091
+ binding: binding2
1092
+ };
1027
1093
  return this.#snapshot;
1028
1094
  }
1029
1095
  const titlePolicyReadiness = await waitForRendererTitlePolicyReady(
1030
1096
  () => this.operations.markTitlePolicyReady(this.inspector, selected.id),
1031
1097
  { timeoutMs: this.timeoutMs, pollIntervalMs: this.pollIntervalMs }
1032
1098
  );
1099
+ await activateElectronDesktop(this.inspector);
1033
1100
  await this.operations.execute(this.inspector, selected.id, this.rendererSource);
1101
+ const draftPrewarmPolicy = await this.operations.installDraftPrewarmPolicy(
1102
+ this.inspector,
1103
+ selected.id
1104
+ );
1034
1105
  const binding = await waitForBinding(
1035
1106
  this.inspector,
1036
1107
  this.operations,
@@ -1039,10 +1110,6 @@ var InstalledRendererControlSession = class {
1039
1110
  this.timeoutMs,
1040
1111
  this.pollIntervalMs
1041
1112
  );
1042
- const draftPrewarmPolicy = await this.operations.installDraftPrewarmPolicy(
1043
- this.inspector,
1044
- selected.id
1045
- );
1046
1113
  this.#snapshot = {
1047
1114
  ...this.#snapshot,
1048
1115
  renderer: selected,
@@ -1056,10 +1123,6 @@ var InstalledRendererControlSession = class {
1056
1123
  if (this.#closed) return Promise.reject(new Error("Renderer Control Session is closed"));
1057
1124
  return activateElectronDesktop(this.inspector);
1058
1125
  }
1059
- quitDesktop() {
1060
- if (this.#closed) return Promise.reject(new Error("Renderer Control Session is closed"));
1061
- return this.operations.quitDesktop(this.inspector);
1062
- }
1063
1126
  async requestCompatibilityUpdate() {
1064
1127
  const value = await this.executeRenderer(
1065
1128
  "window.__codexhostRendererBindingProbeV1?.requestCompatibilityUpdate?.() ?? 'unavailable'"
@@ -1117,6 +1180,11 @@ async function createRendererControlSession(options) {
1117
1180
  );
1118
1181
  startupTrace("injecting Renderer bundle");
1119
1182
  await operations.execute(options.inspector, selected.id, options.rendererSource);
1183
+ startupTrace("installing draft routing policy");
1184
+ const draftPrewarmPolicy = await operations.installDraftPrewarmPolicy(
1185
+ options.inspector,
1186
+ selected.id
1187
+ );
1120
1188
  startupTrace("waiting for Renderer binding");
1121
1189
  const binding = await waitForBinding(
1122
1190
  options.inspector,
@@ -1126,11 +1194,6 @@ async function createRendererControlSession(options) {
1126
1194
  timeoutMs,
1127
1195
  pollIntervalMs
1128
1196
  );
1129
- startupTrace("installing draft prewarm policy");
1130
- const draftPrewarmPolicy = await operations.installDraftPrewarmPolicy(
1131
- options.inspector,
1132
- selected.id
1133
- );
1134
1197
  return new InstalledRendererControlSession(
1135
1198
  options.inspector,
1136
1199
  options.rendererSource,
@@ -1351,7 +1414,7 @@ async function runDesktopController(options, signal, dependencies = defaultDepen
1351
1414
  inspectorEndpoint: options.inspectorEndpoint,
1352
1415
  rendererSource: `${configuration}
1353
1416
  ${rendererSource}`,
1354
- enabledAgents: ["codex", "pi", "claude-code"],
1417
+ enabledAgents: ["codex", "pi", "claude-code", "deepseek-harness", "grok"],
1355
1418
  timeoutMs: PRODUCTION_INSTALL_TIMEOUT_MS
1356
1419
  },
1357
1420
  dependencies
@@ -1410,10 +1473,6 @@ ${rendererSource}`,
1410
1473
  compatibilityUpdate: () => useSession(async () => {
1411
1474
  const current = await recoverSession();
1412
1475
  return current.requestCompatibilityUpdate();
1413
- }),
1414
- shutdown: () => useSession(async () => {
1415
- const current = await recoverSession();
1416
- await current.quitDesktop();
1417
1476
  })
1418
1477
  });
1419
1478
  startupTrace2("attachment server ready");