@codexhost/cli-darwin-x64 0.3.0-test.1 → 0.3.0-test.3
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 +19 -120
- package/app/host-runtime.mjs +78 -5
- package/app/renderer-extension.js +344 -151
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +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.3.0-test.
|
|
10
|
+
npm install -g @codexhost/cli@0.3.0-test.3
|
|
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.3.0-test.
|
|
1
|
+
{"schemaVersion":1,"version":"0.3.0-test.3","distribution":"npm","target":"macos-x64"}
|
|
@@ -560,55 +560,35 @@ async function readMainProcessTitlePolicyCounters(inspector) {
|
|
|
560
560
|
// packages/desktop-control/src/renderer-draft-prewarm-runtime.ts
|
|
561
561
|
function installDraftPrewarmPolicyBridge(bridge, hostId, target, prewarmedThreadManager) {
|
|
562
562
|
const existing = target.__codexhostDraftPrewarmPolicyV1;
|
|
563
|
-
if (existing?.owns?.(bridge, hostId) === true) {
|
|
563
|
+
if (existing?.owns?.length === 3 && existing.owns(bridge, hostId, prewarmedThreadManager) === true) {
|
|
564
564
|
return { state: "ready", reason: "owned-request-bridge" };
|
|
565
565
|
}
|
|
566
566
|
existing?.dispose?.();
|
|
567
567
|
const originalSend = bridge.sendRequest;
|
|
568
568
|
const originalPrewarm = bridge.prewarmThreadStart;
|
|
569
569
|
let selectedModel = null;
|
|
570
|
-
let clearInFlight = null;
|
|
571
570
|
const isRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
572
|
-
const
|
|
573
|
-
if (selectedModel === null || !isRecord5(parameters)
|
|
574
|
-
|
|
575
|
-
const settings = isRecord5(collaborationMode) ? collaborationMode.settings : null;
|
|
576
|
-
if (!isRecord5(collaborationMode) || !isRecord5(settings)) {
|
|
577
|
-
throw new Error(`Codex ${method} omitted collaborationMode.settings`);
|
|
571
|
+
const routeThreadStart = (parameters) => {
|
|
572
|
+
if (selectedModel === null || !isRecord5(parameters) || parameters.ephemeral === true) {
|
|
573
|
+
return parameters;
|
|
578
574
|
}
|
|
579
|
-
return {
|
|
580
|
-
...parameters,
|
|
581
|
-
collaborationMode: {
|
|
582
|
-
...collaborationMode,
|
|
583
|
-
settings: { ...settings, model: selectedModel }
|
|
584
|
-
}
|
|
585
|
-
};
|
|
586
|
-
};
|
|
587
|
-
const routeThreadStart = (method, parameters) => {
|
|
588
|
-
if (selectedModel === null || !isRecord5(parameters)) return parameters;
|
|
589
|
-
const direct = method === "thread/start";
|
|
590
|
-
const wrapped = method === "prewarm-thread-start-for-host" || method === "send-cli-request-for-host";
|
|
591
|
-
if (!direct && !wrapped) return parameters;
|
|
592
|
-
const threadParams = direct ? parameters : parameters.params;
|
|
593
|
-
if (!isRecord5(threadParams) || threadParams.ephemeral === true) return parameters;
|
|
594
|
-
if (direct) return { ...threadParams, model: selectedModel };
|
|
595
|
-
return { ...parameters, params: { ...threadParams, model: selectedModel } };
|
|
575
|
+
return { ...parameters, model: selectedModel };
|
|
596
576
|
};
|
|
597
577
|
const routedSend = (method, parameters, options) => {
|
|
598
|
-
const routedParameters = method === "start
|
|
578
|
+
const routedParameters = method === "thread/start" ? routeThreadStart(parameters) : parameters;
|
|
599
579
|
return options === void 0 ? originalSend.call(bridge, method, routedParameters) : originalSend.call(bridge, method, routedParameters, options);
|
|
600
580
|
};
|
|
601
581
|
const routedPrewarm = (parameters, options) => {
|
|
602
|
-
const routedParameters = routeThreadStart(
|
|
603
|
-
return options === void 0 ? originalPrewarm
|
|
582
|
+
const routedParameters = routeThreadStart(parameters);
|
|
583
|
+
return options === void 0 ? originalPrewarm.call(bridge, routedParameters) : originalPrewarm.call(bridge, routedParameters, options);
|
|
604
584
|
};
|
|
605
585
|
bridge.sendRequest = routedSend;
|
|
606
|
-
|
|
586
|
+
bridge.prewarmThreadStart = routedPrewarm;
|
|
607
587
|
const policy = Object.freeze({
|
|
608
588
|
state: "ready",
|
|
609
589
|
hostId,
|
|
610
|
-
owns(candidate, candidateHostId) {
|
|
611
|
-
return candidate === bridge && candidateHostId === hostId;
|
|
590
|
+
owns(candidate, candidateHostId, candidatePrewarmedThreadManager) {
|
|
591
|
+
return candidate === bridge && candidateHostId === hostId && candidatePrewarmedThreadManager === prewarmedThreadManager;
|
|
612
592
|
},
|
|
613
593
|
select(model) {
|
|
614
594
|
if (model !== null && (typeof model !== "string" || !model.startsWith("codexhost/"))) {
|
|
@@ -619,24 +599,13 @@ function installDraftPrewarmPolicyBridge(bridge, hostId, target, prewarmedThread
|
|
|
619
599
|
return true;
|
|
620
600
|
},
|
|
621
601
|
clear() {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
return Promise.resolve();
|
|
625
|
-
}
|
|
626
|
-
if (clearInFlight === null) {
|
|
627
|
-
clearInFlight = Promise.resolve(
|
|
628
|
-
originalSend.call(bridge, "clear-prewarmed-threads-for-host", { hostId })
|
|
629
|
-
).then(() => void 0).finally(() => {
|
|
630
|
-
clearInFlight = null;
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
return clearInFlight;
|
|
602
|
+
prewarmedThreadManager.discardAllPrewarmedThreads();
|
|
603
|
+
return Promise.resolve();
|
|
634
604
|
},
|
|
635
605
|
dispose() {
|
|
636
606
|
if (bridge.sendRequest === routedSend) bridge.sendRequest = originalSend;
|
|
637
607
|
if (bridge.prewarmThreadStart === routedPrewarm) {
|
|
638
|
-
|
|
639
|
-
else delete bridge.prewarmThreadStart;
|
|
608
|
+
bridge.prewarmThreadStart = originalPrewarm;
|
|
640
609
|
}
|
|
641
610
|
selectedModel = null;
|
|
642
611
|
}
|
|
@@ -685,84 +654,13 @@ async function installDraftPrewarmPolicyInRenderer(contents, findRequestManagerE
|
|
|
685
654
|
if (candidateCount !== 1 || typeof hostId !== "string" || hostId.length === 0 || typeof manager?.objectId !== "string") {
|
|
686
655
|
throw new Error("Renderer request manager is ambiguous");
|
|
687
656
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
});
|
|
691
|
-
const managerPropertyNames = new Set(
|
|
692
|
-
managerFunctions.result?.map((property) => String(property.name)) ?? []
|
|
693
|
-
);
|
|
694
|
-
let hostBridgeObjectId = managerPropertyNames.has("sendRequest") && managerPropertyNames.has("prewarmThreadStart") && managerPropertyNames.has("enqueueRequest") ? manager.objectId : void 0;
|
|
695
|
-
if (!hostBridgeObjectId) {
|
|
696
|
-
let managerSendRequestId = managerFunctions.result?.find(
|
|
697
|
-
(property) => property.name === "sendRequest"
|
|
698
|
-
)?.value?.objectId;
|
|
699
|
-
const managerPrototypeId = managerFunctions.internalProperties?.find(
|
|
700
|
-
(property) => property.name === "[[Prototype]]"
|
|
701
|
-
)?.value?.objectId;
|
|
702
|
-
if (typeof managerSendRequestId !== "string" && typeof managerPrototypeId === "string") {
|
|
703
|
-
const prototypeFunctions = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
704
|
-
objectId: managerPrototypeId,
|
|
705
|
-
ownProperties: true
|
|
706
|
-
});
|
|
707
|
-
managerSendRequestId = prototypeFunctions.result?.find(
|
|
708
|
-
(property) => property.name === "sendRequest"
|
|
709
|
-
)?.value?.objectId;
|
|
710
|
-
}
|
|
711
|
-
if (typeof managerSendRequestId !== "string") {
|
|
712
|
-
throw new Error("Renderer request manager sendRequest is unavailable");
|
|
713
|
-
}
|
|
714
|
-
const functionProperties = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
715
|
-
objectId: managerSendRequestId
|
|
716
|
-
});
|
|
717
|
-
const scopesId = functionProperties.internalProperties?.find(
|
|
718
|
-
(property) => property.name === "[[Scopes]]"
|
|
719
|
-
)?.value?.objectId;
|
|
720
|
-
const hostBridgeCandidates = [];
|
|
721
|
-
if (typeof scopesId === "string") {
|
|
722
|
-
const scopes = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
723
|
-
objectId: scopesId,
|
|
724
|
-
ownProperties: true
|
|
725
|
-
});
|
|
726
|
-
for (const scope of scopes.result ?? []) {
|
|
727
|
-
if (typeof scope.value?.objectId !== "string") continue;
|
|
728
|
-
const scopeProperties = await contents.debugger.sendCommand("Runtime.getProperties", {
|
|
729
|
-
objectId: scope.value.objectId,
|
|
730
|
-
ownProperties: true
|
|
731
|
-
});
|
|
732
|
-
for (const property of scopeProperties.result ?? []) {
|
|
733
|
-
if (property.value?.type !== "object" || typeof property.value.objectId !== "string") {
|
|
734
|
-
continue;
|
|
735
|
-
}
|
|
736
|
-
const candidateSignature = await contents.debugger.sendCommand(
|
|
737
|
-
"Runtime.callFunctionOn",
|
|
738
|
-
{
|
|
739
|
-
objectId: property.value.objectId,
|
|
740
|
-
functionDeclaration: "function(){const send=this.sendRequest;return typeof send==='function'&&Function.prototype.toString.call(send).includes('messageHandler')}",
|
|
741
|
-
returnByValue: true
|
|
742
|
-
}
|
|
743
|
-
);
|
|
744
|
-
if (candidateSignature.result?.value === true) {
|
|
745
|
-
hostBridgeCandidates.push({
|
|
746
|
-
name: String(property.name),
|
|
747
|
-
objectId: property.value.objectId
|
|
748
|
-
});
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
const hostBridge = hostBridgeCandidates[0];
|
|
754
|
-
if (hostBridgeCandidates.length !== 1 || !hostBridge) {
|
|
755
|
-
throw new Error("Renderer Host request bridge is ambiguous");
|
|
756
|
-
}
|
|
757
|
-
hostBridgeObjectId = hostBridge.objectId;
|
|
657
|
+
if (typeof prewarmedThreadManager?.objectId !== "string") {
|
|
658
|
+
throw new Error("Renderer prewarmed Thread manager is unavailable");
|
|
758
659
|
}
|
|
759
660
|
const installed = await contents.debugger.sendCommand("Runtime.callFunctionOn", {
|
|
760
|
-
objectId:
|
|
661
|
+
objectId: manager.objectId,
|
|
761
662
|
functionDeclaration: installRendererPolicyFunction,
|
|
762
|
-
arguments: [
|
|
763
|
-
{ value: hostId },
|
|
764
|
-
...typeof prewarmedThreadManager?.objectId === "string" ? [{ objectId: prewarmedThreadManager.objectId }] : []
|
|
765
|
-
],
|
|
663
|
+
arguments: [{ value: hostId }, { objectId: prewarmedThreadManager.objectId }],
|
|
766
664
|
awaitPromise: true,
|
|
767
665
|
returnByValue: true
|
|
768
666
|
});
|
|
@@ -825,6 +723,7 @@ var FIND_REQUEST_MANAGER_EXPRESSION = `(() => {
|
|
|
825
723
|
typeof value.requestClient.prewarmThreadStart === 'function' &&
|
|
826
724
|
typeof value.requestClient.sendRequest === 'function' &&
|
|
827
725
|
typeof value.requestClient.enqueueRequest === 'function' &&
|
|
726
|
+
typeof value.prewarmedThreadManager?.discardAllPrewarmedThreads === 'function' &&
|
|
828
727
|
typeof value.sendRequest === 'function'
|
|
829
728
|
) {
|
|
830
729
|
managers.add(value);
|
package/app/host-runtime.mjs
CHANGED
|
@@ -63915,6 +63915,20 @@ function decodeThreadForkRequest(request) {
|
|
|
63915
63915
|
...optionalField(params, "serviceTier")
|
|
63916
63916
|
};
|
|
63917
63917
|
}
|
|
63918
|
+
function decodeThreadRevertRequest(request) {
|
|
63919
|
+
if (request.method !== "thread/revert")
|
|
63920
|
+
return null;
|
|
63921
|
+
if (!isRecord26(request.params))
|
|
63922
|
+
throw new Error("thread/revert params must be an object");
|
|
63923
|
+
const { threadId: threadId2, beforeTurnId } = request.params;
|
|
63924
|
+
if (typeof threadId2 !== "string" || threadId2.length === 0) {
|
|
63925
|
+
throw new Error("thread/revert params.threadId must be non-empty text");
|
|
63926
|
+
}
|
|
63927
|
+
if (typeof beforeTurnId !== "string" || beforeTurnId.length === 0) {
|
|
63928
|
+
throw new Error("thread/revert params.beforeTurnId must be non-empty text");
|
|
63929
|
+
}
|
|
63930
|
+
return { threadId: threadId2, beforeTurnId: hostTurnIdSchema.parse(beforeTurnId) };
|
|
63931
|
+
}
|
|
63918
63932
|
function decodeThreadRollbackRequest(request) {
|
|
63919
63933
|
if (request.method !== "thread/rollback")
|
|
63920
63934
|
return null;
|
|
@@ -63957,6 +63971,9 @@ function mapExternalThreadHarnessError(error54, operation) {
|
|
|
63957
63971
|
return { code: -32076, message: `External Thread ${operation} failed` };
|
|
63958
63972
|
}
|
|
63959
63973
|
}
|
|
63974
|
+
function threadRevertResult(thread) {
|
|
63975
|
+
return { thread: { ...thread, turns: [] } };
|
|
63976
|
+
}
|
|
63960
63977
|
function threadRollbackResult(thread) {
|
|
63961
63978
|
return { thread };
|
|
63962
63979
|
}
|
|
@@ -65250,12 +65267,18 @@ async function executeCurrentLastTurnRollback(input) {
|
|
|
65250
65267
|
return { ok: true, thread };
|
|
65251
65268
|
}
|
|
65252
65269
|
async function executeExternalThreadRollback(input) {
|
|
65253
|
-
const { derived, rollback, adapters, repository, runtime } = input;
|
|
65270
|
+
const { derived, rollback, adapters, repository, runtime, expectedLastTurnId } = input;
|
|
65254
65271
|
if (derived.running) {
|
|
65255
65272
|
return { ok: false, error: { code: -32072, message: "External Thread has an active Turn" } };
|
|
65256
65273
|
}
|
|
65257
65274
|
const refreshError = await runtime.refresh(derived);
|
|
65258
65275
|
if (refreshError) return { ok: false, error: refreshError };
|
|
65276
|
+
if (expectedLastTurnId !== void 0 && derived.record.turnMappings.at(-1)?.hostTurnId !== expectedLastTurnId) {
|
|
65277
|
+
return {
|
|
65278
|
+
ok: false,
|
|
65279
|
+
error: { code: -32080, message: "External Revert boundary is unavailable" }
|
|
65280
|
+
};
|
|
65281
|
+
}
|
|
65259
65282
|
if (rollback.numTurns === 1 && derived.session.capabilities.history.rollbackLastTurn) {
|
|
65260
65283
|
return executeCurrentLastTurnRollback({
|
|
65261
65284
|
current: derived,
|
|
@@ -66209,6 +66232,7 @@ var EXPLICIT_EXTERNAL_THREAD_METHODS = /* @__PURE__ */ new Set([
|
|
|
66209
66232
|
"thread/name/set",
|
|
66210
66233
|
"thread/read",
|
|
66211
66234
|
"thread/resume",
|
|
66235
|
+
"thread/revert",
|
|
66212
66236
|
"thread/rollback",
|
|
66213
66237
|
"thread/turns/list",
|
|
66214
66238
|
"thread/unarchive",
|
|
@@ -66566,6 +66590,29 @@ var AppServerHost = class {
|
|
|
66566
66590
|
continue;
|
|
66567
66591
|
}
|
|
66568
66592
|
}
|
|
66593
|
+
if (request.method === "thread/revert") {
|
|
66594
|
+
const params = isRecord31(request.params) ? request.params : {};
|
|
66595
|
+
const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
|
|
66596
|
+
if (resolution.kind === "error") {
|
|
66597
|
+
await this.#writer.json(
|
|
66598
|
+
rpcError(request, resolution.error.code, resolution.error.message)
|
|
66599
|
+
);
|
|
66600
|
+
continue;
|
|
66601
|
+
}
|
|
66602
|
+
if (resolution.kind === "external") {
|
|
66603
|
+
let revert;
|
|
66604
|
+
try {
|
|
66605
|
+
const decoded = decodeThreadRevertRequest(request);
|
|
66606
|
+
if (!decoded) throw new Error("Expected thread/revert request");
|
|
66607
|
+
revert = decoded;
|
|
66608
|
+
} catch (error54) {
|
|
66609
|
+
await this.#writer.json(rpcError(request, -32602, errorMessage4(error54)));
|
|
66610
|
+
continue;
|
|
66611
|
+
}
|
|
66612
|
+
await this.#revertExternalThread(request, resolution.thread, revert);
|
|
66613
|
+
continue;
|
|
66614
|
+
}
|
|
66615
|
+
}
|
|
66569
66616
|
if (request.method === "thread/rollback") {
|
|
66570
66617
|
const params = isRecord31(request.params) ? request.params : {};
|
|
66571
66618
|
const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
|
|
@@ -67527,6 +67574,28 @@ var AppServerHost = class {
|
|
|
67527
67574
|
params: { thread: { ...thread, turns: [] } }
|
|
67528
67575
|
});
|
|
67529
67576
|
}
|
|
67577
|
+
async #revertExternalThread(request, thread, revert) {
|
|
67578
|
+
if (thread.record.historyMode !== "paginated") {
|
|
67579
|
+
await this.#writer.json(
|
|
67580
|
+
rpcError(request, -32602, "External thread/revert requires paginated history")
|
|
67581
|
+
);
|
|
67582
|
+
return;
|
|
67583
|
+
}
|
|
67584
|
+
const result = await executeExternalThreadRollback({
|
|
67585
|
+
derived: thread,
|
|
67586
|
+
rollback: { threadId: revert.threadId, numTurns: 1 },
|
|
67587
|
+
expectedLastTurnId: revert.beforeTurnId,
|
|
67588
|
+
adapters: this.#externalAdapters,
|
|
67589
|
+
repository: this.#repository,
|
|
67590
|
+
runtime: this.#externalRuntime
|
|
67591
|
+
});
|
|
67592
|
+
if (!result.ok) {
|
|
67593
|
+
await this.#writer.json(rpcError(request, result.error.code, result.error.message));
|
|
67594
|
+
return;
|
|
67595
|
+
}
|
|
67596
|
+
await this.#writer.json(rpcEnvelope(request, { result: threadRevertResult(result.thread) }));
|
|
67597
|
+
await this.#writer.json({ method: "thread/reverted", params: { threadId: thread.id } });
|
|
67598
|
+
}
|
|
67530
67599
|
async #rollbackExternalThread(request, derived, rollback) {
|
|
67531
67600
|
const result = await executeExternalThreadRollback({
|
|
67532
67601
|
derived,
|
|
@@ -69282,10 +69351,14 @@ function installManagedProfileBlock(contents, manifest) {
|
|
|
69282
69351
|
"export CODEXHOST_REMOTE_SSH_MANAGED='1'",
|
|
69283
69352
|
...manifest.claudeCommand ? [`export CODEXHOST_CLAUDE_COMMAND=${shellQuote(manifest.claudeCommand)}`] : []
|
|
69284
69353
|
];
|
|
69285
|
-
const block =
|
|
69286
|
-
|
|
69287
|
-
${
|
|
69288
|
-
|
|
69354
|
+
const block = [
|
|
69355
|
+
PROFILE_START,
|
|
69356
|
+
'if [ -n "${SSH_CONNECTION:-}" ] || [ -n "${SSH_CLIENT:-}" ]; then',
|
|
69357
|
+
...environment.map((entry) => ` ${entry}`),
|
|
69358
|
+
"fi",
|
|
69359
|
+
PROFILE_END,
|
|
69360
|
+
""
|
|
69361
|
+
].join("\n");
|
|
69289
69362
|
if (path24.basename(manifest.profilePath) === ".bashrc") return `${block}${base}`;
|
|
69290
69363
|
const separator = base.length > 0 && !base.endsWith("\n") ? "\n" : "";
|
|
69291
69364
|
return `${base}${separator}${block}`;
|