@codexhost/cli-win32-arm64 0.2.2 → 0.2.4
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 +2 -3
- package/app/codexhost-distribution.json +1 -1
- package/app/desktop-controller.mjs +107 -89
- package/app/host-runtime.mjs +353 -229
- package/app/renderer-extension.js +198 -14
- 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.2.
|
|
10
|
+
npm install -g @codexhost/cli@0.2.4
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Do not install this package directly. npm selects it through the optional dependencies of `@codexhost/cli`.
|
|
@@ -20,8 +20,7 @@ This package is platform-specific (`os=win32`, `cpu=arm64`).
|
|
|
20
20
|
codexhost
|
|
21
21
|
codexhost --version
|
|
22
22
|
codexhost inspect
|
|
23
|
-
codexhost launch
|
|
24
|
-
codexhost launch --agent codex
|
|
23
|
+
codexhost launch
|
|
25
24
|
```
|
|
26
25
|
|
|
27
26
|
The `codexhost` command launches the packaged Rust launcher with:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schemaVersion":1,"version":"0.2.
|
|
1
|
+
{"schemaVersion":1,"version":"0.2.4","distribution":"npm","target":"windows-arm64"}
|
|
@@ -329,7 +329,6 @@ var ELECTRON_MODULE_EXPRESSION = `(() => {
|
|
|
329
329
|
return createRequire(process.execPath)('electron');
|
|
330
330
|
})()`;
|
|
331
331
|
var CONNECT_APP_HOST_CHANNEL = "codex_desktop:connect-app-host";
|
|
332
|
-
var REVIEWED_TITLE_SERVICE_IDENTITIES = ["Dhe", "Nye", "wbe", "nxe", "tTe"];
|
|
333
332
|
var POLICY_STATE_SYMBOL = "codexhost.main-process-title-policy.v1";
|
|
334
333
|
var SERVICE_OWNER_SYMBOL = "codexhost.main-process-title-policy.owner.v1";
|
|
335
334
|
var RENDERER_READY_EXPRESSION = "(() => { Object.defineProperty(window, '__codexhostMainProcessTitlePolicyV1', { configurable: true, value: { state: 'ready' } }); return 'ready'; })()";
|
|
@@ -363,18 +362,6 @@ var INSTALL_POLICY_FUNCTION = `async function (rendererWebContentsId) {
|
|
|
363
362
|
) {
|
|
364
363
|
throw new Error('ThreadMetadataGenerationService signature mismatch');
|
|
365
364
|
}
|
|
366
|
-
const rawServiceClass = sampleService?.constructor?.name;
|
|
367
|
-
const serviceClass = typeof rawServiceClass === 'string' && /^[A-Za-z_$][A-Za-z0-9_$]{0,63}$/.test(rawServiceClass)
|
|
368
|
-
? rawServiceClass
|
|
369
|
-
: 'unknown';
|
|
370
|
-
const warnings = ${JSON.stringify(REVIEWED_TITLE_SERVICE_IDENTITIES)}.includes(serviceClass)
|
|
371
|
-
? []
|
|
372
|
-
: [{
|
|
373
|
-
capability: 'title-isolation',
|
|
374
|
-
reason: 'unreviewed-title-service-identity',
|
|
375
|
-
observedIdentity: serviceClass,
|
|
376
|
-
}];
|
|
377
|
-
|
|
378
365
|
const counters = {
|
|
379
366
|
codexTitleCalls: 0,
|
|
380
367
|
piTitleSkips: 0,
|
|
@@ -448,7 +435,6 @@ var INSTALL_POLICY_FUNCTION = `async function (rendererWebContentsId) {
|
|
|
448
435
|
state: 'ready',
|
|
449
436
|
reason: 'ready',
|
|
450
437
|
requiresRendererReload: true,
|
|
451
|
-
warnings,
|
|
452
438
|
};
|
|
453
439
|
}`;
|
|
454
440
|
async function installMainProcessTitlePolicy(inspector, rendererWebContentsId) {
|
|
@@ -521,9 +507,7 @@ async function installMainProcessTitlePolicy(inspector, rendererWebContentsId) {
|
|
|
521
507
|
);
|
|
522
508
|
const remoteResult = installResponse.result;
|
|
523
509
|
const value = isRecord2(remoteResult) ? remoteResult.value : null;
|
|
524
|
-
if (!isRecord2(value) || value.state !== "ready" || value.reason !== "ready" || value.requiresRendererReload !== true ||
|
|
525
|
-
(warning) => !isRecord2(warning) || warning.capability !== "title-isolation" || warning.reason !== "unreviewed-title-service-identity" || typeof warning.observedIdentity !== "string" || !/^[A-Za-z_$][A-Za-z0-9_$]{0,63}$/.test(warning.observedIdentity) || Object.keys(warning).length !== 3
|
|
526
|
-
)) {
|
|
510
|
+
if (!isRecord2(value) || value.state !== "ready" || value.reason !== "ready" || value.requiresRendererReload !== true || Object.keys(value).length !== 3) {
|
|
527
511
|
throw new Error("Main-process title policy returned an invalid status");
|
|
528
512
|
}
|
|
529
513
|
return value;
|
|
@@ -574,10 +558,11 @@ async function readMainProcessTitlePolicyCounters(inspector) {
|
|
|
574
558
|
}
|
|
575
559
|
|
|
576
560
|
// packages/desktop-control/src/renderer-draft-prewarm-runtime.ts
|
|
577
|
-
function installDraftPrewarmPolicyBridge(bridge, hostId, target) {
|
|
561
|
+
function installDraftPrewarmPolicyBridge(bridge, hostId, target, prewarmedThreadManager) {
|
|
578
562
|
const existing = target.__codexhostDraftPrewarmPolicyV1;
|
|
579
563
|
existing?.dispose?.();
|
|
580
564
|
const originalSend = bridge.sendRequest;
|
|
565
|
+
const originalPrewarm = bridge.prewarmThreadStart;
|
|
581
566
|
let selectedModel = null;
|
|
582
567
|
let clearInFlight = null;
|
|
583
568
|
const isRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -598,15 +583,24 @@ function installDraftPrewarmPolicyBridge(bridge, hostId, target) {
|
|
|
598
583
|
};
|
|
599
584
|
const routeThreadStart = (method, parameters) => {
|
|
600
585
|
if (selectedModel === null || !isRecord5(parameters)) return parameters;
|
|
601
|
-
const
|
|
586
|
+
const direct = method === "thread/start";
|
|
587
|
+
const wrapped = method === "prewarm-thread-start-for-host" || method === "send-cli-request-for-host";
|
|
588
|
+
if (!direct && !wrapped) return parameters;
|
|
589
|
+
const threadParams = direct ? parameters : parameters.params;
|
|
602
590
|
if (!isRecord5(threadParams) || threadParams.ephemeral === true) return parameters;
|
|
591
|
+
if (direct) return { ...threadParams, model: selectedModel };
|
|
603
592
|
return { ...parameters, params: { ...threadParams, model: selectedModel } };
|
|
604
593
|
};
|
|
605
594
|
const routedSend = (method, parameters, options) => {
|
|
606
|
-
const routedParameters = method === "start-conversation" || method === "prewarm-conversation-for-host" ? routeCollaborationMode(method, parameters) :
|
|
595
|
+
const routedParameters = method === "start-conversation" || method === "prewarm-conversation-for-host" ? routeCollaborationMode(method, parameters) : routeThreadStart(method, parameters);
|
|
607
596
|
return options === void 0 ? originalSend.call(bridge, method, routedParameters) : originalSend.call(bridge, method, routedParameters, options);
|
|
608
597
|
};
|
|
598
|
+
const routedPrewarm = (parameters, options) => {
|
|
599
|
+
const routedParameters = routeThreadStart("thread/start", parameters);
|
|
600
|
+
return options === void 0 ? originalPrewarm?.call(bridge, routedParameters) : originalPrewarm?.call(bridge, routedParameters, options);
|
|
601
|
+
};
|
|
609
602
|
bridge.sendRequest = routedSend;
|
|
603
|
+
if (originalPrewarm) bridge.prewarmThreadStart = routedPrewarm;
|
|
610
604
|
const policy = Object.freeze({
|
|
611
605
|
state: "ready",
|
|
612
606
|
select(model) {
|
|
@@ -618,6 +612,10 @@ function installDraftPrewarmPolicyBridge(bridge, hostId, target) {
|
|
|
618
612
|
return true;
|
|
619
613
|
},
|
|
620
614
|
clear() {
|
|
615
|
+
if (prewarmedThreadManager?.discardAllPrewarmedThreads) {
|
|
616
|
+
prewarmedThreadManager.discardAllPrewarmedThreads();
|
|
617
|
+
return Promise.resolve();
|
|
618
|
+
}
|
|
621
619
|
if (clearInFlight === null) {
|
|
622
620
|
clearInFlight = Promise.resolve(
|
|
623
621
|
originalSend.call(bridge, "clear-prewarmed-threads-for-host", { hostId })
|
|
@@ -629,6 +627,10 @@ function installDraftPrewarmPolicyBridge(bridge, hostId, target) {
|
|
|
629
627
|
},
|
|
630
628
|
dispose() {
|
|
631
629
|
if (bridge.sendRequest === routedSend) bridge.sendRequest = originalSend;
|
|
630
|
+
if (bridge.prewarmThreadStart === routedPrewarm) {
|
|
631
|
+
if (originalPrewarm) bridge.prewarmThreadStart = originalPrewarm;
|
|
632
|
+
else delete bridge.prewarmThreadStart;
|
|
633
|
+
}
|
|
632
634
|
selectedModel = null;
|
|
633
635
|
}
|
|
634
636
|
});
|
|
@@ -667,77 +669,90 @@ async function installDraftPrewarmPolicyInRenderer(contents, findRequestManagerE
|
|
|
667
669
|
const manager = managerProperties.result?.find(
|
|
668
670
|
(property) => property.name === "manager"
|
|
669
671
|
)?.value;
|
|
672
|
+
const prewarmedThreadManager = managerProperties.result?.find(
|
|
673
|
+
(property) => property.name === "prewarmedThreadManager"
|
|
674
|
+
)?.value;
|
|
670
675
|
if (candidateCount !== 1 || hostId !== "local" || typeof manager?.objectId !== "string") {
|
|
671
676
|
throw new Error("Renderer request manager is ambiguous");
|
|
672
677
|
}
|
|
673
678
|
const managerFunctions = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
674
679
|
objectId: manager.objectId
|
|
675
680
|
});
|
|
676
|
-
|
|
677
|
-
(property) => property.name
|
|
678
|
-
)
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
if (typeof managerSendRequestId !== "string" && typeof managerPrototypeId === "string") {
|
|
683
|
-
const prototypeFunctions = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
684
|
-
objectId: managerPrototypeId,
|
|
685
|
-
ownProperties: true
|
|
686
|
-
});
|
|
687
|
-
managerSendRequestId = prototypeFunctions.result?.find(
|
|
681
|
+
const managerPropertyNames = new Set(
|
|
682
|
+
managerFunctions.result?.map((property) => String(property.name)) ?? []
|
|
683
|
+
);
|
|
684
|
+
let hostBridgeObjectId = managerPropertyNames.has("sendRequest") && managerPropertyNames.has("prewarmThreadStart") && managerPropertyNames.has("enqueueRequest") ? manager.objectId : void 0;
|
|
685
|
+
if (!hostBridgeObjectId) {
|
|
686
|
+
let managerSendRequestId = managerFunctions.result?.find(
|
|
688
687
|
(property) => property.name === "sendRequest"
|
|
689
688
|
)?.value?.objectId;
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
689
|
+
const managerPrototypeId = managerFunctions.internalProperties?.find(
|
|
690
|
+
(property) => property.name === "[[Prototype]]"
|
|
691
|
+
)?.value?.objectId;
|
|
692
|
+
if (typeof managerSendRequestId !== "string" && typeof managerPrototypeId === "string") {
|
|
693
|
+
const prototypeFunctions = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
694
|
+
objectId: managerPrototypeId,
|
|
695
|
+
ownProperties: true
|
|
696
|
+
});
|
|
697
|
+
managerSendRequestId = prototypeFunctions.result?.find(
|
|
698
|
+
(property) => property.name === "sendRequest"
|
|
699
|
+
)?.value?.objectId;
|
|
700
|
+
}
|
|
701
|
+
if (typeof managerSendRequestId !== "string") {
|
|
702
|
+
throw new Error("Renderer request manager sendRequest is unavailable");
|
|
703
|
+
}
|
|
704
|
+
const functionProperties = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
705
|
+
objectId: managerSendRequestId
|
|
705
706
|
});
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
707
|
+
const scopesId = functionProperties.internalProperties?.find(
|
|
708
|
+
(property) => property.name === "[[Scopes]]"
|
|
709
|
+
)?.value?.objectId;
|
|
710
|
+
const hostBridgeCandidates = [];
|
|
711
|
+
if (typeof scopesId === "string") {
|
|
712
|
+
const scopes = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
713
|
+
objectId: scopesId,
|
|
710
714
|
ownProperties: true
|
|
711
715
|
});
|
|
712
|
-
for (const
|
|
713
|
-
if (
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
716
|
+
for (const scope of scopes.result ?? []) {
|
|
717
|
+
if (typeof scope.value?.objectId !== "string") continue;
|
|
718
|
+
const scopeProperties = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
719
|
+
objectId: scope.value.objectId,
|
|
720
|
+
ownProperties: true
|
|
721
|
+
});
|
|
722
|
+
for (const property of scopeProperties.result ?? []) {
|
|
723
|
+
if (property.value?.type !== "object" || typeof property.value.objectId !== "string") {
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
const candidateSignature = await contents.debugger.sendCommand(
|
|
727
|
+
"Runtime.callFunctionOn",
|
|
728
|
+
{
|
|
729
|
+
objectId: property.value.objectId,
|
|
730
|
+
functionDeclaration: "function(){const send=this.sendRequest;return typeof send==='function'&&Function.prototype.toString.call(send).includes('messageHandler')}",
|
|
731
|
+
returnByValue: true
|
|
732
|
+
}
|
|
733
|
+
);
|
|
734
|
+
if (candidateSignature.result?.value === true) {
|
|
735
|
+
hostBridgeCandidates.push({
|
|
736
|
+
name: String(property.name),
|
|
737
|
+
objectId: property.value.objectId
|
|
738
|
+
});
|
|
722
739
|
}
|
|
723
|
-
);
|
|
724
|
-
if (candidateSignature.result?.value === true) {
|
|
725
|
-
hostBridgeCandidates.push({
|
|
726
|
-
name: String(property.name),
|
|
727
|
-
objectId: property.value.objectId
|
|
728
|
-
});
|
|
729
740
|
}
|
|
730
741
|
}
|
|
731
742
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
743
|
+
const hostBridge = hostBridgeCandidates[0];
|
|
744
|
+
if (hostBridgeCandidates.length !== 1 || !hostBridge) {
|
|
745
|
+
throw new Error("Renderer Host request bridge is ambiguous");
|
|
746
|
+
}
|
|
747
|
+
hostBridgeObjectId = hostBridge.objectId;
|
|
736
748
|
}
|
|
737
749
|
const installed = await contents.debugger.sendCommand("Runtime.callFunctionOn", {
|
|
738
|
-
objectId:
|
|
750
|
+
objectId: hostBridgeObjectId,
|
|
739
751
|
functionDeclaration: installRendererPolicyFunction,
|
|
740
|
-
arguments: [
|
|
752
|
+
arguments: [
|
|
753
|
+
{ value: hostId },
|
|
754
|
+
...typeof prewarmedThreadManager?.objectId === "string" ? [{ objectId: prewarmedThreadManager.objectId }] : []
|
|
755
|
+
],
|
|
741
756
|
awaitPromise: true,
|
|
742
757
|
returnByValue: true
|
|
743
758
|
});
|
|
@@ -777,24 +792,31 @@ var FIND_REQUEST_MANAGER_EXPRESSION = `(() => {
|
|
|
777
792
|
typeof value === 'object' &&
|
|
778
793
|
value.requestClient != null &&
|
|
779
794
|
typeof value.requestClient.prewarmThreadStart === 'function' &&
|
|
780
|
-
typeof value.sendRequest === 'function' &&
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
)
|
|
795
|
+
typeof value.requestClient.sendRequest === 'function' &&
|
|
796
|
+
typeof value.requestClient.enqueueRequest === 'function' &&
|
|
797
|
+
typeof value.sendRequest === 'function'
|
|
784
798
|
) {
|
|
785
799
|
managers.add(value);
|
|
786
800
|
}
|
|
787
801
|
}
|
|
788
802
|
}
|
|
789
803
|
const manager = managers.size === 1 ? managers.values().next().value : null;
|
|
804
|
+
const requestClient =
|
|
805
|
+
manager != null &&
|
|
806
|
+
typeof manager.requestClient?.sendRequest === 'function' &&
|
|
807
|
+
typeof manager.requestClient?.prewarmThreadStart === 'function' &&
|
|
808
|
+
typeof manager.requestClient?.enqueueRequest === 'function'
|
|
809
|
+
? manager.requestClient
|
|
810
|
+
: manager;
|
|
790
811
|
return {
|
|
791
812
|
candidateCount: managers.size,
|
|
792
|
-
hostId: manager?.getHostId?.() ?? null,
|
|
793
|
-
manager,
|
|
813
|
+
hostId: manager?.getHostId?.() ?? requestClient?.hostId ?? null,
|
|
814
|
+
manager: requestClient,
|
|
815
|
+
prewarmedThreadManager: manager?.prewarmedThreadManager ?? null,
|
|
794
816
|
};
|
|
795
817
|
})()`;
|
|
796
|
-
var INSTALL_RENDERER_POLICY_FUNCTION = `function(hostId) {
|
|
797
|
-
return (${installDraftPrewarmPolicyBridge.toString()})(this, hostId, window);
|
|
818
|
+
var INSTALL_RENDERER_POLICY_FUNCTION = `function(hostId, prewarmedThreadManager) {
|
|
819
|
+
return (${installDraftPrewarmPolicyBridge.toString()})(this, hostId, window, prewarmedThreadManager);
|
|
798
820
|
}`;
|
|
799
821
|
var REQUEST_MANAGER_WAIT_TIMEOUT_MS = 6e4;
|
|
800
822
|
var REQUEST_MANAGER_POLL_INTERVAL_MS = 25;
|
|
@@ -1252,9 +1274,6 @@ function startupTrace2(stage, detail) {
|
|
|
1252
1274
|
}
|
|
1253
1275
|
function validCompatibilityIssue(state, issue) {
|
|
1254
1276
|
const keys = Object.keys(issue);
|
|
1255
|
-
if (state === "compatible-with-warning") {
|
|
1256
|
-
return issue.capability === "title-isolation" && issue.reason === "unreviewed-title-service-identity" && typeof issue.observedIdentity === "string" && /^[A-Za-z_$][A-Za-z0-9_$]{0,63}$/.test(issue.observedIdentity) && keys.length === 3;
|
|
1257
|
-
}
|
|
1258
1277
|
if (state === "degraded") {
|
|
1259
1278
|
return [
|
|
1260
1279
|
"permission-control",
|
|
@@ -1262,12 +1281,12 @@ function validCompatibilityIssue(state, issue) {
|
|
|
1262
1281
|
"fork-control",
|
|
1263
1282
|
"usage-surface",
|
|
1264
1283
|
"settings-surface"
|
|
1265
|
-
].includes(issue.capability) && issue.reason === "capability-unavailable" &&
|
|
1284
|
+
].includes(issue.capability) && issue.reason === "capability-unavailable" && keys.length === 2;
|
|
1266
1285
|
}
|
|
1267
1286
|
return false;
|
|
1268
1287
|
}
|
|
1269
1288
|
function serializeDesktopControllerReadiness(readiness) {
|
|
1270
|
-
if (readiness.schemaVersion !== 2 || !["compatible", "
|
|
1289
|
+
if (readiness.schemaVersion !== 2 || !["compatible", "degraded"].includes(readiness.state) || !Array.isArray(readiness.issues) || readiness.issues.length > 1 || readiness.state === "compatible" && readiness.issues.length !== 0 || readiness.state !== "compatible" && (readiness.issues.length !== 1 || !readiness.issues[0] || !validCompatibilityIssue(readiness.state, readiness.issues[0])) || Object.keys(readiness).length !== 3) {
|
|
1271
1290
|
throw new Error("Desktop Controller readiness is invalid");
|
|
1272
1291
|
}
|
|
1273
1292
|
const line = JSON.stringify(readiness);
|
|
@@ -1476,12 +1495,11 @@ ${rendererSource}`,
|
|
|
1476
1495
|
})
|
|
1477
1496
|
});
|
|
1478
1497
|
startupTrace2("attachment server ready");
|
|
1479
|
-
const issues = session?.snapshot.titlePolicy.warnings ?? [];
|
|
1480
1498
|
startupTrace2("publishing readiness");
|
|
1481
1499
|
dependencies.ready({
|
|
1482
1500
|
schemaVersion: 2,
|
|
1483
|
-
state:
|
|
1484
|
-
issues
|
|
1501
|
+
state: "compatible",
|
|
1502
|
+
issues: []
|
|
1485
1503
|
});
|
|
1486
1504
|
while (!signal.aborted) {
|
|
1487
1505
|
await dependencies.sleep(dependencies.monitorIntervalMs);
|