@codexhost/cli-win32-arm64 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 +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/desktop-controller.mjs +109 -28
- package/app/host-runtime.mjs +9434 -358
- package/app/renderer-extension.js +348 -318
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/package.json +1 -1
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.
|
|
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
|
+
{"schemaVersion":1,"version":"0.2.0","distribution":"npm","target":"windows-arm64"}
|
|
@@ -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(
|
|
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(
|
|
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
|
|
760
|
+
const editors = [...document.querySelectorAll(
|
|
716
761
|
'[data-codex-composer], [contenteditable="true"][role="textbox"]',
|
|
717
|
-
)]
|
|
718
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
784
|
-
|
|
785
|
-
|
|
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
|
|
1026
|
-
|
|
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
|