@codexhost/cli-darwin-arm64 0.17.0 → 0.17.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 +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-web.js +1 -1
- package/app/desktop-controller.mjs +909 -31
- package/app/host-runtime.mjs +910 -34
- package/app/plugins/antigravity/plugin.mjs +27 -7
- package/app/plugins/cursor-cli/plugin.mjs +19 -3
- package/app/plugins/kimi-code/plugin.mjs +50 -3
- package/app/plugins/pi/plugin.mjs +208 -88
- package/app/plugins/zcode/plugin.mjs +142 -9
- package/app/renderer-extension.js +1 -1
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
package/app/host-runtime.mjs
CHANGED
|
@@ -22685,9 +22685,10 @@ function isolateRendererPrewarmConsumption(manager, discardExternal) {
|
|
|
22685
22685
|
}
|
|
22686
22686
|
|
|
22687
22687
|
// packages/desktop-control/dist/renderer-draft-prewarm-runtime.js
|
|
22688
|
-
function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewarmedThreadManager, isCurrentManager, retainResponses = retainRendererHostResponses, isolateConsumption = isolateRendererPrewarmConsumption) {
|
|
22688
|
+
function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewarmedThreadManager, isCurrentManager, retainResponses = retainRendererHostResponses, isolateConsumption = isolateRendererPrewarmConsumption, sendControlRequest) {
|
|
22689
22689
|
let disposed = false;
|
|
22690
22690
|
const originalSend = bridge.sendRequest;
|
|
22691
|
+
const controlSend = (method, parameters) => sendControlRequest ? sendControlRequest(method, parameters) : originalSend.call(bridge, method, parameters);
|
|
22691
22692
|
const originalPrewarm = bridge.prewarmThreadStart;
|
|
22692
22693
|
const originalOnNotification = manager.onNotification;
|
|
22693
22694
|
const originalDispatchAppServerResponse = manager.dispatchAppServerResponse;
|
|
@@ -22773,7 +22774,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22773
22774
|
bridge.onError(requestId, error51);
|
|
22774
22775
|
bridgeRequests.clear();
|
|
22775
22776
|
if (isRemoteControlHost && terminate) {
|
|
22776
|
-
void Promise.resolve(
|
|
22777
|
+
void Promise.resolve(controlSend("process/kill", { processHandle: failedProcessHandle })).catch(() => void 0);
|
|
22777
22778
|
}
|
|
22778
22779
|
};
|
|
22779
22780
|
const resetFailedBridge = () => {
|
|
@@ -22936,7 +22937,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22936
22937
|
];
|
|
22937
22938
|
const startedProcessHandle = bridgeProcessHandle;
|
|
22938
22939
|
try {
|
|
22939
|
-
const started =
|
|
22940
|
+
const started = controlSend("process/spawn", {
|
|
22940
22941
|
command,
|
|
22941
22942
|
processHandle: startedProcessHandle,
|
|
22942
22943
|
cwd: "C:\\",
|
|
@@ -22959,7 +22960,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22959
22960
|
await startBridge();
|
|
22960
22961
|
if (bridgeState !== "ready")
|
|
22961
22962
|
throw transportError("is not ready");
|
|
22962
|
-
await
|
|
22963
|
+
await controlSend("process/writeStdin", {
|
|
22963
22964
|
processHandle: bridgeProcessHandle,
|
|
22964
22965
|
deltaBase64: utf8Base64(`${JSON.stringify(value2)}
|
|
22965
22966
|
`)
|
|
@@ -23240,7 +23241,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
23240
23241
|
globalThis.clearTimeout(bridgeReadyTimeout);
|
|
23241
23242
|
bridgeReadyTimeout = null;
|
|
23242
23243
|
if (isRemoteControlHost && (bridgeState === "starting" || bridgeState === "ready")) {
|
|
23243
|
-
void Promise.resolve(
|
|
23244
|
+
void Promise.resolve(controlSend("process/kill", { processHandle: bridgeProcessHandle })).catch(() => void 0);
|
|
23244
23245
|
}
|
|
23245
23246
|
bridgeState = "disposed";
|
|
23246
23247
|
const disposedError = transportError("was disposed");
|
|
@@ -23342,11 +23343,12 @@ function resolveRendererHostManager(discovery, hostId2, managerFrom = requestMan
|
|
|
23342
23343
|
}
|
|
23343
23344
|
|
|
23344
23345
|
// packages/desktop-control/dist/renderer-host-routing.js
|
|
23345
|
-
function installRendererHostRouting(root, target, discover, resolve, createPolicy) {
|
|
23346
|
+
function installRendererHostRouting(root, target, discover, resolve, createPolicy, readConnection, publishRouting = true) {
|
|
23346
23347
|
const existing = target.__codexhostHostRoutingV1;
|
|
23347
|
-
if (existing)
|
|
23348
|
+
if (publishRouting && existing)
|
|
23348
23349
|
return existing;
|
|
23349
|
-
|
|
23350
|
+
if (publishRouting)
|
|
23351
|
+
target.__codexhostDraftPrewarmPolicyV1?.dispose?.();
|
|
23350
23352
|
let disposed = false;
|
|
23351
23353
|
let lastDiscovery = null;
|
|
23352
23354
|
const routes = /* @__PURE__ */ new Map();
|
|
@@ -23374,23 +23376,36 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
|
|
|
23374
23376
|
routes.delete(hostId2);
|
|
23375
23377
|
entry?.route.policy.dispose();
|
|
23376
23378
|
};
|
|
23379
|
+
const connectionFor = (hostId2) => {
|
|
23380
|
+
if (!hostId2.startsWith("remote-control:"))
|
|
23381
|
+
return void 0;
|
|
23382
|
+
try {
|
|
23383
|
+
return readConnection?.(hostId2);
|
|
23384
|
+
} catch {
|
|
23385
|
+
return null;
|
|
23386
|
+
}
|
|
23387
|
+
};
|
|
23388
|
+
const sameConnection = (expected, current) => expected === void 0 ? current === void 0 : current?.owner === expected.owner && current.revision === expected.revision;
|
|
23377
23389
|
const routeFor = (hostId2, discovery) => {
|
|
23378
23390
|
const manager = lookup(hostId2, discovery);
|
|
23391
|
+
const connection = connectionFor(hostId2);
|
|
23379
23392
|
const previous = routes.get(hostId2);
|
|
23380
|
-
if (manager && previous?.route.manager === manager && previous.bridge === manager.requestClient && previous.prewarmed === manager.prewarmedThreadManager && previous.route.policy.owns(manager, manager.requestClient, hostId2, manager.prewarmedThreadManager, true)) {
|
|
23393
|
+
if (manager && previous?.route.manager === manager && previous.bridge === manager.requestClient && previous.prewarmed === manager.prewarmedThreadManager && sameConnection(previous.connection, connection) && previous.route.policy.owns(manager, manager.requestClient, hostId2, manager.prewarmedThreadManager, true)) {
|
|
23381
23394
|
return previous.route;
|
|
23382
23395
|
}
|
|
23383
23396
|
retire(hostId2);
|
|
23384
|
-
if (!manager)
|
|
23397
|
+
if (!manager || connection === null)
|
|
23385
23398
|
return null;
|
|
23386
23399
|
const bridge = manager.requestClient;
|
|
23387
23400
|
const prewarmed = manager.prewarmedThreadManager;
|
|
23388
|
-
const policy = createPolicy(manager, bridge, hostId2, target, prewarmed, () => lookup(hostId2) === manager && manager.requestClient === bridge && manager.prewarmedThreadManager === prewarmed);
|
|
23401
|
+
const policy = createPolicy(manager, bridge, hostId2, target, prewarmed, () => lookup(hostId2) === manager && sameConnection(connection, connectionFor(hostId2)) && manager.requestClient === bridge && manager.prewarmedThreadManager === prewarmed);
|
|
23389
23402
|
const route = { hostId: hostId2, manager, policy };
|
|
23390
|
-
routes.set(hostId2, { route, bridge, prewarmed });
|
|
23403
|
+
routes.set(hostId2, { route, bridge, prewarmed, connection });
|
|
23391
23404
|
return route;
|
|
23392
23405
|
};
|
|
23393
23406
|
const publish = (route) => {
|
|
23407
|
+
if (!publishRouting)
|
|
23408
|
+
return;
|
|
23394
23409
|
const policy = route?.policy;
|
|
23395
23410
|
if (target.__codexhostDraftPrewarmPolicyV1 === policy)
|
|
23396
23411
|
return;
|
|
@@ -23444,7 +23459,7 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
|
|
|
23444
23459
|
if (!composer) {
|
|
23445
23460
|
for (const [hostId3, entry] of routes) {
|
|
23446
23461
|
const manager = lookup(hostId3, discovery);
|
|
23447
|
-
if (manager !== entry.route.manager || manager.requestClient !== entry.bridge || manager.prewarmedThreadManager !== entry.prewarmed)
|
|
23462
|
+
if (manager !== entry.route.manager || manager.requestClient !== entry.bridge || manager.prewarmedThreadManager !== entry.prewarmed || !sameConnection(entry.connection, connectionFor(hostId3)))
|
|
23448
23463
|
retire(hostId3);
|
|
23449
23464
|
}
|
|
23450
23465
|
}
|
|
@@ -23467,7 +23482,11 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
|
|
|
23467
23482
|
}
|
|
23468
23483
|
}
|
|
23469
23484
|
};
|
|
23470
|
-
|
|
23485
|
+
if (publishRouting)
|
|
23486
|
+
Object.defineProperty(target, "__codexhostHostRoutingV1", {
|
|
23487
|
+
configurable: true,
|
|
23488
|
+
value: routing
|
|
23489
|
+
});
|
|
23471
23490
|
return routing;
|
|
23472
23491
|
}
|
|
23473
23492
|
|
|
@@ -23569,19 +23588,41 @@ function installRendererHostRpcRouting(root, target, dependencies2) {
|
|
|
23569
23588
|
if (existing)
|
|
23570
23589
|
return existing;
|
|
23571
23590
|
let disposed = false;
|
|
23591
|
+
let nativeRouting = null;
|
|
23572
23592
|
let discovery = null;
|
|
23573
23593
|
const routes = /* @__PURE__ */ new Map();
|
|
23574
23594
|
const read = () => {
|
|
23575
23595
|
if (disposed)
|
|
23576
23596
|
return null;
|
|
23577
|
-
|
|
23597
|
+
try {
|
|
23578
23598
|
const store = dependencies2.findStore(root);
|
|
23579
23599
|
discovery = store ? dependencies2.findFamily(store) : null;
|
|
23600
|
+
} catch {
|
|
23601
|
+
discovery = null;
|
|
23580
23602
|
}
|
|
23581
23603
|
return discovery;
|
|
23582
23604
|
};
|
|
23583
23605
|
if (!read())
|
|
23584
23606
|
return null;
|
|
23607
|
+
const native = () => {
|
|
23608
|
+
if (disposed)
|
|
23609
|
+
return null;
|
|
23610
|
+
try {
|
|
23611
|
+
nativeRouting ??= dependencies2.nativeRouting?.() ?? null;
|
|
23612
|
+
} catch {
|
|
23613
|
+
}
|
|
23614
|
+
return nativeRouting;
|
|
23615
|
+
};
|
|
23616
|
+
const connectionFor = (hostId2) => {
|
|
23617
|
+
if (!hostId2.startsWith("remote-control:"))
|
|
23618
|
+
return void 0;
|
|
23619
|
+
try {
|
|
23620
|
+
return dependencies2.readConnection?.(hostId2);
|
|
23621
|
+
} catch {
|
|
23622
|
+
return null;
|
|
23623
|
+
}
|
|
23624
|
+
};
|
|
23625
|
+
const sameConnection = (previous, current) => previous === void 0 ? current === void 0 : current?.owner === previous.owner && current.revision === previous.revision;
|
|
23585
23626
|
const isRecord19 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
23586
23627
|
const externalDrafts = /* @__PURE__ */ new Map();
|
|
23587
23628
|
const selectedModels = /* @__PURE__ */ new Map();
|
|
@@ -23667,16 +23708,25 @@ function installRendererHostRpcRouting(root, target, dependencies2) {
|
|
|
23667
23708
|
const postMessage = function(message2, ...rest) {
|
|
23668
23709
|
let routed = message2;
|
|
23669
23710
|
try {
|
|
23670
|
-
routed = disposed ? message2 : routeCreationCall(message2);
|
|
23711
|
+
routed = disposed || routes.size === 0 ? message2 : routeCreationCall(message2);
|
|
23671
23712
|
} catch {
|
|
23672
23713
|
routed = message2;
|
|
23673
23714
|
}
|
|
23674
23715
|
return originalPostMessage.call(this, routed, ...rest);
|
|
23675
23716
|
};
|
|
23676
23717
|
port.postMessage = postMessage;
|
|
23677
|
-
const createRoute = (hostId2, rpc) => {
|
|
23718
|
+
const createRoute = (hostId2, rpc, connection) => {
|
|
23678
23719
|
let retired = false;
|
|
23679
|
-
const isCurrent = () =>
|
|
23720
|
+
const isCurrent = () => {
|
|
23721
|
+
if (retired || disposed || routes.get(hostId2)?.rpc !== rpc || !sameConnection(connection, connectionFor(hostId2)))
|
|
23722
|
+
return false;
|
|
23723
|
+
try {
|
|
23724
|
+
const current = read();
|
|
23725
|
+
return !!current && dependencies2.resolve(current, hostId2) === rpc;
|
|
23726
|
+
} catch {
|
|
23727
|
+
return false;
|
|
23728
|
+
}
|
|
23729
|
+
};
|
|
23680
23730
|
const manager = Object.freeze({
|
|
23681
23731
|
kind: "main-process-rpc",
|
|
23682
23732
|
getHostId: () => hostId2,
|
|
@@ -23759,17 +23809,25 @@ function installRendererHostRpcRouting(root, target, dependencies2) {
|
|
|
23759
23809
|
routes.delete(hostId2);
|
|
23760
23810
|
entry?.route.policy.dispose();
|
|
23761
23811
|
};
|
|
23762
|
-
const routeFor = (hostId2) => {
|
|
23812
|
+
const routeFor = (hostId2, nativeRoute) => {
|
|
23813
|
+
if (disposed)
|
|
23814
|
+
return null;
|
|
23815
|
+
const connection = connectionFor(hostId2);
|
|
23816
|
+
const preferred = nativeRoute === void 0 ? native()?.forHost(hostId2) : nativeRoute;
|
|
23817
|
+
if (connection === null || preferred) {
|
|
23818
|
+
retire(hostId2);
|
|
23819
|
+
return connection === null ? null : preferred ?? null;
|
|
23820
|
+
}
|
|
23763
23821
|
const current = read();
|
|
23764
23822
|
const rpc = current ? dependencies2.resolve(current, hostId2) : null;
|
|
23765
23823
|
const previous = routes.get(hostId2);
|
|
23766
|
-
if (rpc && previous?.rpc === rpc)
|
|
23824
|
+
if (rpc && previous?.rpc === rpc && sameConnection(previous.connection, connection))
|
|
23767
23825
|
return previous.route;
|
|
23768
23826
|
retire(hostId2);
|
|
23769
23827
|
if (!rpc)
|
|
23770
23828
|
return null;
|
|
23771
|
-
const route = createRoute(hostId2, rpc);
|
|
23772
|
-
routes.set(hostId2, { route, rpc });
|
|
23829
|
+
const route = createRoute(hostId2, rpc, connection);
|
|
23830
|
+
routes.set(hostId2, { route, rpc, connection });
|
|
23773
23831
|
return route;
|
|
23774
23832
|
};
|
|
23775
23833
|
const publish = (route) => {
|
|
@@ -23785,14 +23843,24 @@ function installRendererHostRpcRouting(root, target, dependencies2) {
|
|
|
23785
23843
|
}
|
|
23786
23844
|
};
|
|
23787
23845
|
const composerHostId = (composer) => {
|
|
23846
|
+
const nativeHostId = native()?.hostIdForComposer(composer);
|
|
23847
|
+
if (nativeHostId)
|
|
23848
|
+
return nativeHostId;
|
|
23788
23849
|
const hostIds = new Set(dependencies2.composerHostIds(composer).hostIds);
|
|
23789
23850
|
const hostId2 = hostIds.size === 1 ? hostIds.values().next().value : null;
|
|
23790
23851
|
return typeof hostId2 === "string" && hostId2 ? hostId2 : null;
|
|
23791
23852
|
};
|
|
23792
23853
|
const routing = {
|
|
23793
23854
|
knownHostIds() {
|
|
23855
|
+
if (disposed)
|
|
23856
|
+
return [];
|
|
23794
23857
|
const current = read();
|
|
23795
|
-
return
|
|
23858
|
+
return [
|
|
23859
|
+
.../* @__PURE__ */ new Set([
|
|
23860
|
+
...current ? dependencies2.hostIds(current) : [],
|
|
23861
|
+
...native()?.knownHostIds?.() ?? []
|
|
23862
|
+
])
|
|
23863
|
+
];
|
|
23796
23864
|
},
|
|
23797
23865
|
forHost(hostId2) {
|
|
23798
23866
|
return hostId2 && !disposed ? routeFor(hostId2) : null;
|
|
@@ -23810,12 +23878,14 @@ function installRendererHostRpcRouting(root, target, dependencies2) {
|
|
|
23810
23878
|
if (disposed)
|
|
23811
23879
|
return null;
|
|
23812
23880
|
let hostId2;
|
|
23881
|
+
let preferred = null;
|
|
23813
23882
|
try {
|
|
23814
|
-
|
|
23883
|
+
preferred = native()?.forComposer(composer) ?? null;
|
|
23884
|
+
hostId2 = preferred?.hostId ?? composerHostId(composer);
|
|
23815
23885
|
} catch {
|
|
23816
23886
|
hostId2 = null;
|
|
23817
23887
|
}
|
|
23818
|
-
const route = hostId2 ? routeFor(hostId2) : null;
|
|
23888
|
+
const route = hostId2 ? routeFor(hostId2, preferred) : null;
|
|
23819
23889
|
if (!composer)
|
|
23820
23890
|
publish(route);
|
|
23821
23891
|
return route;
|
|
@@ -23824,6 +23894,8 @@ function installRendererHostRpcRouting(root, target, dependencies2) {
|
|
|
23824
23894
|
if (disposed)
|
|
23825
23895
|
return;
|
|
23826
23896
|
disposed = true;
|
|
23897
|
+
nativeRouting?.dispose();
|
|
23898
|
+
nativeRouting = null;
|
|
23827
23899
|
for (const hostId2 of [...routes.keys()])
|
|
23828
23900
|
retire(hostId2);
|
|
23829
23901
|
discovery = null;
|
|
@@ -23841,6 +23913,34 @@ function installRendererHostRpcRouting(root, target, dependencies2) {
|
|
|
23841
23913
|
return routing;
|
|
23842
23914
|
}
|
|
23843
23915
|
|
|
23916
|
+
// packages/desktop-control/dist/renderer-connection-generation.js
|
|
23917
|
+
function readRendererConnectionGeneration(store, hostId2) {
|
|
23918
|
+
if (!store)
|
|
23919
|
+
return void 0;
|
|
23920
|
+
const record6 = (value2) => value2 !== null && typeof value2 === "object";
|
|
23921
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
23922
|
+
for (const members of store.familyBindings.values()) {
|
|
23923
|
+
const value2 = members.get(hostId2)?.value;
|
|
23924
|
+
if (record6(value2) && record6(value2.state$) && record6(value2.revision$) && record6(value2.appServerVersion$) && typeof value2.state$.get === "function" && typeof value2.revision$.get === "function")
|
|
23925
|
+
candidates.add(value2);
|
|
23926
|
+
}
|
|
23927
|
+
if (!candidates.size)
|
|
23928
|
+
return void 0;
|
|
23929
|
+
if (candidates.size !== 1)
|
|
23930
|
+
return null;
|
|
23931
|
+
const owner = candidates.values().next().value;
|
|
23932
|
+
if (!owner)
|
|
23933
|
+
return null;
|
|
23934
|
+
const state = owner.state$;
|
|
23935
|
+
const revision = owner.revision$;
|
|
23936
|
+
try {
|
|
23937
|
+
const current = revision.get();
|
|
23938
|
+
return state.get() === "connected" && typeof current === "number" && Number.isSafeInteger(current) ? { owner, revision: current } : null;
|
|
23939
|
+
} catch {
|
|
23940
|
+
return null;
|
|
23941
|
+
}
|
|
23942
|
+
}
|
|
23943
|
+
|
|
23844
23944
|
// packages/desktop-control/dist/renderer-draft-prewarm-policy.js
|
|
23845
23945
|
var REQUEST_MANAGER_WAIT_TIMEOUT_MS = 6e4;
|
|
23846
23946
|
var REQUEST_MANAGER_POLL_INTERVAL_MS = 25;
|
|
@@ -23853,15 +23953,19 @@ function directRendererInstaller() {
|
|
|
23853
23953
|
const retainRendererHostResponses = ${retainRendererHostResponses.toString()};
|
|
23854
23954
|
const createDraftPrewarmPolicyBridge = ${createDraftPrewarmPolicyBridge.toString()};
|
|
23855
23955
|
const isolateRendererPrewarmConsumption = ${isolateRendererPrewarmConsumption.toString()};
|
|
23956
|
+
const findRendererAppScopeStore = ${findRendererAppScopeStore.toString()};
|
|
23957
|
+
const readRendererConnectionGeneration = ${readRendererConnectionGeneration.toString()};
|
|
23856
23958
|
const discover = (root) =>
|
|
23857
23959
|
discoverRendererHosts(root, committedReactAncestors, requestManagerFromHookState);
|
|
23858
|
-
const installNative = () => (${installRendererHostRouting.toString()})(
|
|
23960
|
+
const installNative = (publishRouting = true) => (${installRendererHostRouting.toString()})(
|
|
23859
23961
|
document, window, discover,
|
|
23860
23962
|
(discovery, hostId) => resolveRendererHostManager(discovery, hostId, requestManagerFromHookState),
|
|
23861
23963
|
(manager, bridge, hostId, target, prewarmed, isCurrent) => createDraftPrewarmPolicyBridge(
|
|
23862
23964
|
manager, bridge, hostId, target, prewarmed, isCurrent, retainRendererHostResponses,
|
|
23863
23965
|
isolateRendererPrewarmConsumption,
|
|
23864
23966
|
),
|
|
23967
|
+
(hostId) => readRendererConnectionGeneration(findRendererAppScopeStore(document), hostId),
|
|
23968
|
+
publishRouting,
|
|
23865
23969
|
);
|
|
23866
23970
|
const installRpc = () => typeof MessagePort !== 'function' ? null : (${installRendererHostRpcRouting.toString()})(document, window, {
|
|
23867
23971
|
findStore: ${findRendererAppScopeStore.toString()},
|
|
@@ -23875,14 +23979,21 @@ function directRendererInstaller() {
|
|
|
23875
23979
|
return discover(source);
|
|
23876
23980
|
},
|
|
23877
23981
|
portPrototype: MessagePort.prototype,
|
|
23982
|
+
nativeRouting: () => {
|
|
23983
|
+
const native = discover(document);
|
|
23984
|
+
return native.managers.length || native.registries.length ? installNative(false) : null;
|
|
23985
|
+
},
|
|
23986
|
+
readConnection: (hostId) => readRendererConnectionGeneration(findRendererAppScopeStore(document), hostId),
|
|
23878
23987
|
});
|
|
23879
23988
|
const connected = (routing) => routing.forComposer() !== null ||
|
|
23880
23989
|
['local', ...(routing.knownHostIds?.() ?? [])].some((hostId) => routing.forHost(hostId) !== null);
|
|
23881
23990
|
let nativeReady = false;
|
|
23882
|
-
//
|
|
23883
|
-
//
|
|
23991
|
+
// Mixed layouts can expose native managers for only some Hosts. Keep one
|
|
23992
|
+
// router that selects a native owner or the current ready RPC peer per Host.
|
|
23884
23993
|
const routing = (() => {
|
|
23885
23994
|
if (window.__codexhostHostRoutingV1) return window.__codexhostHostRoutingV1;
|
|
23995
|
+
const rpc = installRpc();
|
|
23996
|
+
if (rpc) return rpc;
|
|
23886
23997
|
const native = discover(document);
|
|
23887
23998
|
if (native.managers.length || native.registries.length) {
|
|
23888
23999
|
const routing = installNative();
|
|
@@ -23892,8 +24003,6 @@ function directRendererInstaller() {
|
|
|
23892
24003
|
}
|
|
23893
24004
|
routing.dispose();
|
|
23894
24005
|
}
|
|
23895
|
-
const rpc = installRpc();
|
|
23896
|
-
if (rpc) return rpc;
|
|
23897
24006
|
throw new Error('Renderer Host request manager is unavailable');
|
|
23898
24007
|
})();
|
|
23899
24008
|
// Publish a default draft policy only when its Host is unambiguous. Host
|
|
@@ -24062,6 +24171,765 @@ async function installRendererLoadedModules(renderer) {
|
|
|
24062
24171
|
}
|
|
24063
24172
|
}
|
|
24064
24173
|
|
|
24174
|
+
// packages/desktop-control/dist/renderer-native-rpc-discovery.js
|
|
24175
|
+
function nativeManagerDependencies(factoryName, callers) {
|
|
24176
|
+
const identifier = "[$A-Z_a-z][$\\w]*";
|
|
24177
|
+
const escaped = factoryName.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
24178
|
+
const pattern = new RegExp(`${escaped}\\((${identifier}),(${identifier}),\\1\\.get\\((${identifier}),\\2\\),(${identifier})\\.bind\\(null,\\1\\),\\((${identifier}),(${identifier})\\)=>\\5\\((${identifier}),\\6\\)\\)`);
|
|
24179
|
+
const matches = callers.flatMap((source) => {
|
|
24180
|
+
const match = pattern.exec(source);
|
|
24181
|
+
return match?.[3] && match[4] && match[7] ? [
|
|
24182
|
+
{
|
|
24183
|
+
requestDefinition: match[3],
|
|
24184
|
+
isHostForConversation: match[4],
|
|
24185
|
+
imageDefinition: match[7]
|
|
24186
|
+
}
|
|
24187
|
+
] : [];
|
|
24188
|
+
});
|
|
24189
|
+
return matches.length === 1 ? matches[0] : void 0;
|
|
24190
|
+
}
|
|
24191
|
+
function nativeRpcRole(source) {
|
|
24192
|
+
if (["dispatchMessageFromView", "threadProjectAssignments", "queuedMessageCoordination"].every((part) => source.includes(part)))
|
|
24193
|
+
return "createManager";
|
|
24194
|
+
if (["collectAppStateSnapshot", "getReviewPaneSnapshotMetrics", "registerReplayAdmission"].every((part) => source.includes(part)))
|
|
24195
|
+
return "createController";
|
|
24196
|
+
if (["getWorkInProgress", "getCachedThreadSearchSnapshot", "registerReplayAdmission"].every((part) => source.includes(part)))
|
|
24197
|
+
return "RpcManager";
|
|
24198
|
+
if (["prewarmedThreadManager", "onNotification", "dispatchAppServerResponse"].every((part) => source.includes(part)))
|
|
24199
|
+
return "Manager";
|
|
24200
|
+
return void 0;
|
|
24201
|
+
}
|
|
24202
|
+
function nativeRpcObjectShape(value2) {
|
|
24203
|
+
if (value2 === null || typeof value2 !== "object")
|
|
24204
|
+
return { scope: false, services: false, controller: false };
|
|
24205
|
+
const candidate = value2;
|
|
24206
|
+
const own = (keys) => keys.every((key) => Object.hasOwn(candidate, key));
|
|
24207
|
+
const methods = (keys) => keys.every((key) => typeof candidate[key] === "function");
|
|
24208
|
+
return {
|
|
24209
|
+
scope: own(["node", "scope", "get", "set", "watch"]) && methods(["get", "set", "watch"]),
|
|
24210
|
+
services: own(["appServerManagers", "remoteConnections", "applicationMenu"]) && typeof candidate.appServerManagers?.subscribe === "function",
|
|
24211
|
+
controller: own(["forHost", "collectAppStateSnapshot", "getReviewPaneSnapshotMetrics", "dispose"]) && methods(["forHost", "collectAppStateSnapshot", "getReviewPaneSnapshotMetrics", "dispose"])
|
|
24212
|
+
};
|
|
24213
|
+
}
|
|
24214
|
+
async function withNativeRpcComponents(client, install) {
|
|
24215
|
+
const group = `codexhost-native-rpc-${crypto.randomUUID()}`;
|
|
24216
|
+
const command = async (method, params) => client.command(method, params);
|
|
24217
|
+
const evaluate = (expression) => command("Runtime.evaluate", { expression, awaitPromise: true, objectGroup: group });
|
|
24218
|
+
const properties = (objectId) => command("Runtime.getProperties", { objectId, ownProperties: true });
|
|
24219
|
+
const call = (objectId, functionDeclaration, args = []) => command("Runtime.callFunctionOn", {
|
|
24220
|
+
objectId,
|
|
24221
|
+
functionDeclaration,
|
|
24222
|
+
arguments: args,
|
|
24223
|
+
objectGroup: group,
|
|
24224
|
+
returnByValue: true
|
|
24225
|
+
});
|
|
24226
|
+
try {
|
|
24227
|
+
const initial = await evaluate(String.raw`(() => {
|
|
24228
|
+
const catalog = globalThis.__codexhostLoadedModulesV1;
|
|
24229
|
+
if (!catalog?.complete || catalog.documentUrl !== location.href) return null;
|
|
24230
|
+
const urls = catalog.urls.filter(url => /^app:\/\/-\/assets\/(?:renderer-app-server-managers|app-shared)-[^/]+\.js$/.test(url));
|
|
24231
|
+
return { document, urls };
|
|
24232
|
+
})()`);
|
|
24233
|
+
if (!initial.result.objectId)
|
|
24234
|
+
return false;
|
|
24235
|
+
const holder = initial.result.objectId;
|
|
24236
|
+
const catalog = await call(holder, "function(){return this.urls}");
|
|
24237
|
+
const urls = catalog.result.value;
|
|
24238
|
+
if (!Array.isArray(urls) || urls.length !== 2)
|
|
24239
|
+
return false;
|
|
24240
|
+
const managerUrl = urls.find((url2) => url2.includes("renderer-app-server-managers"));
|
|
24241
|
+
const sharedUrl = urls.find((url2) => url2.includes("app-shared"));
|
|
24242
|
+
if (!managerUrl || !sharedUrl)
|
|
24243
|
+
return false;
|
|
24244
|
+
const attach = async (name, objectId) => {
|
|
24245
|
+
const result = await call(holder, "function(name,value){if(this.document!==document)throw Error('Renderer Realm changed');this[name]=value;return true}", [{ value: name }, { objectId }]);
|
|
24246
|
+
if (result.exceptionDetails)
|
|
24247
|
+
throw new Error("Native RPC discovery lost its Renderer Realm");
|
|
24248
|
+
};
|
|
24249
|
+
const imported = await evaluate(`import(${JSON.stringify(managerUrl)})`);
|
|
24250
|
+
if (!imported.result.objectId)
|
|
24251
|
+
return false;
|
|
24252
|
+
const exports = (await properties(imported.result.objectId)).result.filter((entry) => entry.value?.type === "function");
|
|
24253
|
+
let bindings = [];
|
|
24254
|
+
for (const entry of exports.slice(0, 3)) {
|
|
24255
|
+
if (!entry.value?.objectId)
|
|
24256
|
+
continue;
|
|
24257
|
+
const scopes = (await properties(entry.value.objectId)).internalProperties?.find((entry2) => entry2.name === "[[Scopes]]")?.value?.objectId;
|
|
24258
|
+
if (!scopes)
|
|
24259
|
+
continue;
|
|
24260
|
+
const modules = (await properties(scopes)).result.filter((entry2) => entry2.value?.description?.startsWith("Module") && entry2.value.objectId);
|
|
24261
|
+
const moduleId = modules[0]?.value?.objectId;
|
|
24262
|
+
if (modules.length !== 1 || !moduleId)
|
|
24263
|
+
continue;
|
|
24264
|
+
bindings = (await properties(moduleId)).result;
|
|
24265
|
+
break;
|
|
24266
|
+
}
|
|
24267
|
+
const functions = bindings.filter((entry) => entry.value?.type === "function");
|
|
24268
|
+
const roles = /* @__PURE__ */ new Map();
|
|
24269
|
+
for (const entry of functions) {
|
|
24270
|
+
const role = nativeRpcRole(entry.value?.description ?? "");
|
|
24271
|
+
if (role)
|
|
24272
|
+
roles.set(role, [...roles.get(role) ?? [], entry]);
|
|
24273
|
+
}
|
|
24274
|
+
if (["createManager", "Manager", "RpcManager", "createController"].some((role) => roles.get(role)?.length !== 1))
|
|
24275
|
+
return false;
|
|
24276
|
+
const factory = roles.get("createManager")?.[0];
|
|
24277
|
+
if (!factory)
|
|
24278
|
+
return false;
|
|
24279
|
+
const dependencies2 = nativeManagerDependencies(factory.name, functions.map((entry) => entry.value?.description ?? ""));
|
|
24280
|
+
if (!dependencies2)
|
|
24281
|
+
return false;
|
|
24282
|
+
for (const [role, entries] of roles) {
|
|
24283
|
+
const id2 = entries[0]?.value?.objectId;
|
|
24284
|
+
if (!id2)
|
|
24285
|
+
return false;
|
|
24286
|
+
await attach(role, id2);
|
|
24287
|
+
}
|
|
24288
|
+
for (const [role, name] of Object.entries(dependencies2)) {
|
|
24289
|
+
const value2 = bindings.find((entry) => entry.name === name)?.value?.objectId;
|
|
24290
|
+
if (!value2)
|
|
24291
|
+
return false;
|
|
24292
|
+
await attach(role, value2);
|
|
24293
|
+
}
|
|
24294
|
+
const shared = await evaluate(`import(${JSON.stringify(sharedUrl)})`);
|
|
24295
|
+
if (!shared.result.objectId)
|
|
24296
|
+
return false;
|
|
24297
|
+
const sharedExports = (await properties(shared.result.objectId)).result;
|
|
24298
|
+
const sessions = sharedExports.filter((entry) => entry.value?.type === "function" && ["getRemoteMain", "getStats", "drain", "getMainImport"].every((word) => entry.value?.description?.includes(word)));
|
|
24299
|
+
const sessionId = sessions[0]?.value?.objectId;
|
|
24300
|
+
if (sessions.length !== 1 || !sessionId)
|
|
24301
|
+
return false;
|
|
24302
|
+
await attach("RpcSession", sessionId);
|
|
24303
|
+
const serviceMatches = await command("Runtime.callFunctionOn", {
|
|
24304
|
+
objectId: shared.result.objectId,
|
|
24305
|
+
functionDeclaration: `function(){return [...new Set(Object.values(this).filter(value => (${nativeRpcObjectShape.toString()})(value).services))]}`,
|
|
24306
|
+
objectGroup: group
|
|
24307
|
+
});
|
|
24308
|
+
if (!serviceMatches.result.objectId)
|
|
24309
|
+
return false;
|
|
24310
|
+
const services = (await properties(serviceMatches.result.objectId)).result.flatMap((entry) => entry.value?.type === "object" && entry.value.objectId ? [entry.value.objectId] : []);
|
|
24311
|
+
const serviceId = services[0];
|
|
24312
|
+
if (services.length !== 1 || !serviceId)
|
|
24313
|
+
return false;
|
|
24314
|
+
await attach("services", serviceId);
|
|
24315
|
+
const prototype = await evaluate("Object.getPrototypeOf(async function(){})");
|
|
24316
|
+
if (!prototype.result.objectId)
|
|
24317
|
+
return false;
|
|
24318
|
+
const objects = await command("Runtime.queryObjects", {
|
|
24319
|
+
prototypeObjectId: prototype.result.objectId,
|
|
24320
|
+
objectGroup: group
|
|
24321
|
+
});
|
|
24322
|
+
if (!objects.objects.objectId)
|
|
24323
|
+
return false;
|
|
24324
|
+
const filtered = await command("Runtime.callFunctionOn", {
|
|
24325
|
+
objectId: objects.objects.objectId,
|
|
24326
|
+
functionDeclaration: 'function(){return this.filter(fn=>fn.name==="collectAppStateSnapshot"&&String(fn).includes("collectSnapshot")).slice(0,9)}',
|
|
24327
|
+
objectGroup: group
|
|
24328
|
+
});
|
|
24329
|
+
if (!filtered.result.objectId)
|
|
24330
|
+
return false;
|
|
24331
|
+
const snapshots = (await properties(filtered.result.objectId)).result.filter((entry) => entry.value?.type === "function");
|
|
24332
|
+
if (snapshots.length > 8)
|
|
24333
|
+
return false;
|
|
24334
|
+
const owners = [];
|
|
24335
|
+
for (const snapshot2 of snapshots) {
|
|
24336
|
+
const fn = snapshot2.value?.objectId;
|
|
24337
|
+
if (!fn)
|
|
24338
|
+
continue;
|
|
24339
|
+
const scopes = (await properties(fn)).internalProperties?.find((entry) => entry.name === "[[Scopes]]")?.value?.objectId;
|
|
24340
|
+
if (!scopes)
|
|
24341
|
+
continue;
|
|
24342
|
+
for (const scope of (await properties(scopes)).result) {
|
|
24343
|
+
if (!scope.value?.description?.startsWith("Closure") || !scope.value.objectId)
|
|
24344
|
+
continue;
|
|
24345
|
+
const candidates = (await properties(scope.value.objectId)).result;
|
|
24346
|
+
const controllers = [], handles = [];
|
|
24347
|
+
for (const binding of candidates) {
|
|
24348
|
+
if (binding.value?.type !== "object" || !binding.value.objectId)
|
|
24349
|
+
continue;
|
|
24350
|
+
const id2 = binding.value.objectId;
|
|
24351
|
+
const response = await call(id2, `function(){return (${nativeRpcObjectShape.toString()})(this)}`);
|
|
24352
|
+
const shape = response.result.value;
|
|
24353
|
+
if (shape?.scope)
|
|
24354
|
+
handles.push(id2);
|
|
24355
|
+
if (shape?.controller && (await call(id2, "function(fn){return this.collectAppStateSnapshot===fn}", [
|
|
24356
|
+
{ objectId: fn }
|
|
24357
|
+
])).result.value === true)
|
|
24358
|
+
controllers.push(id2);
|
|
24359
|
+
}
|
|
24360
|
+
const controller = controllers[0], handle = handles[0];
|
|
24361
|
+
if (controllers.length === 1 && handles.length === 1 && controller && handle)
|
|
24362
|
+
owners.push({ controller, scope: handle });
|
|
24363
|
+
}
|
|
24364
|
+
}
|
|
24365
|
+
const owner = owners[0];
|
|
24366
|
+
if (owners.length !== 1 || !owner)
|
|
24367
|
+
return false;
|
|
24368
|
+
await attach("controller", owner.controller);
|
|
24369
|
+
await attach("scope", owner.scope);
|
|
24370
|
+
return await install(holder);
|
|
24371
|
+
} finally {
|
|
24372
|
+
await client.command("Runtime.releaseObjectGroup", { objectGroup: group }).catch(() => void 0);
|
|
24373
|
+
}
|
|
24374
|
+
}
|
|
24375
|
+
|
|
24376
|
+
// packages/desktop-control/dist/renderer-native-rpc-runtime.js
|
|
24377
|
+
function installNativeRpcRemoteControl(components, target, dependencies2) {
|
|
24378
|
+
if (target.__codexhostNativeRpcRemoteControlV1)
|
|
24379
|
+
return true;
|
|
24380
|
+
const routing = target.__codexhostHostRoutingV1;
|
|
24381
|
+
if (!routing)
|
|
24382
|
+
return false;
|
|
24383
|
+
const adapted = dependencies2.createService(components, (hostId2, upstream) => dependencies2.createManager(components, hostId2, upstream, target, dependencies2.createPolicy, dependencies2.createChannel, dependencies2.retainInteractions));
|
|
24384
|
+
const controller = components.controller;
|
|
24385
|
+
const originalHost = routing.forHost, originalComposer = routing.forComposer, originalDispose = routing.dispose;
|
|
24386
|
+
controller.dispose();
|
|
24387
|
+
let replacement;
|
|
24388
|
+
try {
|
|
24389
|
+
replacement = components.createController(components.scope, adapted.service);
|
|
24390
|
+
} catch (error51) {
|
|
24391
|
+
replacement = components.createController(components.scope, components.services.appServerManagers);
|
|
24392
|
+
throw error51;
|
|
24393
|
+
} finally {
|
|
24394
|
+
adapted.service[Symbol.dispose]();
|
|
24395
|
+
controller.forHost = (hostId2) => replacement.forHost(hostId2);
|
|
24396
|
+
controller.collectAppStateSnapshot = (hostId2, options) => replacement.collectAppStateSnapshot(hostId2, options);
|
|
24397
|
+
controller.getReviewPaneSnapshotMetrics = (hostId2) => replacement.getReviewPaneSnapshotMetrics(hostId2);
|
|
24398
|
+
controller.dispose = () => replacement.dispose();
|
|
24399
|
+
}
|
|
24400
|
+
const forHost = (hostId2) => {
|
|
24401
|
+
const route = adapted.route(hostId2);
|
|
24402
|
+
return route === void 0 ? originalHost.call(routing, hostId2) : route;
|
|
24403
|
+
};
|
|
24404
|
+
const forComposer = (composer) => {
|
|
24405
|
+
const hostId2 = routing.hostIdForComposer(composer);
|
|
24406
|
+
return hostId2 ? forHost(hostId2) : originalComposer.call(routing, composer);
|
|
24407
|
+
};
|
|
24408
|
+
routing.forHost = forHost;
|
|
24409
|
+
routing.forComposer = forComposer;
|
|
24410
|
+
const installation2 = {
|
|
24411
|
+
dispose() {
|
|
24412
|
+
if (target.__codexhostNativeRpcRemoteControlV1 !== installation2)
|
|
24413
|
+
return;
|
|
24414
|
+
delete target.__codexhostNativeRpcRemoteControlV1;
|
|
24415
|
+
replacement.dispose();
|
|
24416
|
+
replacement = components.createController(components.scope, components.services.appServerManagers);
|
|
24417
|
+
if (routing.forHost === forHost)
|
|
24418
|
+
routing.forHost = originalHost;
|
|
24419
|
+
if (routing.forComposer === forComposer)
|
|
24420
|
+
routing.forComposer = originalComposer;
|
|
24421
|
+
routing.dispose = originalDispose;
|
|
24422
|
+
}
|
|
24423
|
+
};
|
|
24424
|
+
routing.dispose = () => {
|
|
24425
|
+
installation2.dispose();
|
|
24426
|
+
originalDispose.call(routing);
|
|
24427
|
+
};
|
|
24428
|
+
target.__codexhostNativeRpcRemoteControlV1 = installation2;
|
|
24429
|
+
return true;
|
|
24430
|
+
}
|
|
24431
|
+
|
|
24432
|
+
// packages/desktop-control/dist/renderer-native-remote-manager.js
|
|
24433
|
+
function createNativeRemoteManager(components, hostId2, original, target, createPolicy, createChannel, retainInteractions) {
|
|
24434
|
+
const source = components.scope.get(components.requestDefinition, hostId2);
|
|
24435
|
+
const upstream = original.dup();
|
|
24436
|
+
let manager;
|
|
24437
|
+
let policy;
|
|
24438
|
+
let interactions;
|
|
24439
|
+
let disposed = false;
|
|
24440
|
+
const pending = /* @__PURE__ */ new Set();
|
|
24441
|
+
const send = (method, params, options) => {
|
|
24442
|
+
const request = upstream.sendRequest(method, params, options);
|
|
24443
|
+
const result = Promise.resolve(request).finally(() => {
|
|
24444
|
+
request[Symbol.dispose]();
|
|
24445
|
+
pending.delete(result);
|
|
24446
|
+
});
|
|
24447
|
+
pending.add(result);
|
|
24448
|
+
return result;
|
|
24449
|
+
};
|
|
24450
|
+
const record6 = (value2) => value2 !== null && typeof value2 === "object";
|
|
24451
|
+
const dispatch = (type, payload) => {
|
|
24452
|
+
if ((type === "mcp-request" || type === "thread-prewarm-start") && record6(payload) && record6(payload.request)) {
|
|
24453
|
+
const request = payload.request;
|
|
24454
|
+
const options = {};
|
|
24455
|
+
for (const key of ["priority", "timeoutMs", "source", "trace", "threadAccess"])
|
|
24456
|
+
if (payload[key] !== void 0)
|
|
24457
|
+
options[key] = payload[key];
|
|
24458
|
+
void send(String(request.method), request.params, options).then((result) => {
|
|
24459
|
+
if (!disposed)
|
|
24460
|
+
client.onResult(request.id, result);
|
|
24461
|
+
}, (error51) => {
|
|
24462
|
+
if (!disposed)
|
|
24463
|
+
client.onError(request.id, {
|
|
24464
|
+
code: record6(error51) ? error51.jsonRpcCode ?? error51.code ?? -32603 : -32603,
|
|
24465
|
+
message: error51 instanceof Error ? error51.message : String(error51)
|
|
24466
|
+
});
|
|
24467
|
+
});
|
|
24468
|
+
return;
|
|
24469
|
+
}
|
|
24470
|
+
return source.dispatchMessage(type, payload);
|
|
24471
|
+
};
|
|
24472
|
+
const Constructor = source.constructor;
|
|
24473
|
+
let client;
|
|
24474
|
+
try {
|
|
24475
|
+
client = new Constructor(hostId2, dispatch, false, (id2) => manager?.getConversation(id2)?.threadAccess);
|
|
24476
|
+
client.setAppServerVersion(source.getAppServerVersion());
|
|
24477
|
+
manager = components.createManager(components.scope, hostId2, client, components.isHostForConversation.bind(null, components.scope), (get, id2) => get(components.imageDefinition, id2), { dispatchMessageFromView: dispatch });
|
|
24478
|
+
manager.dispatchAppServerResponse = manager.sendAppServerResponse;
|
|
24479
|
+
const owned = manager;
|
|
24480
|
+
const ownedPolicy = createPolicy(owned, client, hostId2, target, owned.prewarmedThreadManager, () => !disposed, void 0, void 0, (method, params) => send(method, params, { priority: "critical" }));
|
|
24481
|
+
policy = ownedPolicy;
|
|
24482
|
+
owned.sendAppServerResponse = (...args) => owned.dispatchAppServerResponse(...args);
|
|
24483
|
+
const channel = createChannel(components, owned);
|
|
24484
|
+
const nativeInteractions = retainInteractions(upstream, owned, hostId2);
|
|
24485
|
+
interactions = nativeInteractions;
|
|
24486
|
+
const notify = (event) => {
|
|
24487
|
+
const { data, source: source2, origin } = event;
|
|
24488
|
+
if (disposed || source2 != null && source2 !== target || !record6(data) || data.hostId !== hostId2)
|
|
24489
|
+
return;
|
|
24490
|
+
const ownOrigin = record6(target.location) ? target.location.origin : void 0;
|
|
24491
|
+
if (source2 === target && ownOrigin && ownOrigin !== "null" && origin !== ownOrigin)
|
|
24492
|
+
return;
|
|
24493
|
+
if (data.type === "mcp-notification" && typeof data.method === "string" && !data.method.startsWith("process/"))
|
|
24494
|
+
owned.onNotification(data.method, data.params);
|
|
24495
|
+
if (data.type === "mcp-request")
|
|
24496
|
+
owned.onRequest(record6(data.request) ? data.request : data);
|
|
24497
|
+
};
|
|
24498
|
+
target.addEventListener?.("message", notify);
|
|
24499
|
+
return {
|
|
24500
|
+
route: { hostId: hostId2, manager: owned, policy: ownedPolicy },
|
|
24501
|
+
rpc: channel.rpc,
|
|
24502
|
+
ready: nativeInteractions.ready,
|
|
24503
|
+
dispose() {
|
|
24504
|
+
if (disposed)
|
|
24505
|
+
return;
|
|
24506
|
+
disposed = true;
|
|
24507
|
+
target.removeEventListener?.("message", notify);
|
|
24508
|
+
nativeInteractions.dispose();
|
|
24509
|
+
ownedPolicy.dispose();
|
|
24510
|
+
client.queuedRequests.length = 0;
|
|
24511
|
+
for (const id2 of [...client.requestPromises.keys()])
|
|
24512
|
+
client.onError(id2, new Error("Remote Control connection retired"));
|
|
24513
|
+
channel.dispose();
|
|
24514
|
+
components.Manager.dispose(owned);
|
|
24515
|
+
void Promise.allSettled([...pending]).then(() => upstream[Symbol.dispose]());
|
|
24516
|
+
}
|
|
24517
|
+
};
|
|
24518
|
+
} catch (error51) {
|
|
24519
|
+
interactions?.dispose();
|
|
24520
|
+
policy?.dispose();
|
|
24521
|
+
if (manager)
|
|
24522
|
+
components.Manager.dispose(manager);
|
|
24523
|
+
upstream[Symbol.dispose]();
|
|
24524
|
+
throw error51;
|
|
24525
|
+
}
|
|
24526
|
+
}
|
|
24527
|
+
|
|
24528
|
+
// packages/desktop-control/dist/renderer-native-rpc-channel.js
|
|
24529
|
+
function createNativeRpcChannel(components, manager) {
|
|
24530
|
+
const channel = new MessageChannel();
|
|
24531
|
+
const transports = [];
|
|
24532
|
+
const transport = (port) => {
|
|
24533
|
+
const values = [];
|
|
24534
|
+
const readers = [];
|
|
24535
|
+
let closed = false;
|
|
24536
|
+
let failure;
|
|
24537
|
+
port.addEventListener("message", (event) => {
|
|
24538
|
+
const value2 = JSON.stringify(event.data);
|
|
24539
|
+
const reader = readers.shift();
|
|
24540
|
+
if (reader)
|
|
24541
|
+
reader.resolve(value2);
|
|
24542
|
+
else
|
|
24543
|
+
values.push(value2);
|
|
24544
|
+
});
|
|
24545
|
+
port.start();
|
|
24546
|
+
const result = {
|
|
24547
|
+
send(message2) {
|
|
24548
|
+
if (closed)
|
|
24549
|
+
throw failure;
|
|
24550
|
+
port.postMessage(JSON.parse(message2));
|
|
24551
|
+
},
|
|
24552
|
+
receive() {
|
|
24553
|
+
if (closed)
|
|
24554
|
+
return Promise.reject(failure);
|
|
24555
|
+
const value2 = values.shift();
|
|
24556
|
+
return value2 !== void 0 ? Promise.resolve(value2) : new Promise((resolve, reject) => readers.push({ resolve, reject }));
|
|
24557
|
+
},
|
|
24558
|
+
abort(error51) {
|
|
24559
|
+
if (closed)
|
|
24560
|
+
return;
|
|
24561
|
+
closed = true;
|
|
24562
|
+
failure = error51 ?? new Error("Remote Control RPC manager retired");
|
|
24563
|
+
values.length = 0;
|
|
24564
|
+
for (const reader of readers.splice(0))
|
|
24565
|
+
reader.reject(failure);
|
|
24566
|
+
port.close();
|
|
24567
|
+
}
|
|
24568
|
+
};
|
|
24569
|
+
transports.push(result);
|
|
24570
|
+
return result;
|
|
24571
|
+
};
|
|
24572
|
+
try {
|
|
24573
|
+
new components.RpcSession(transport(channel.port1), new components.RpcManager(() => manager));
|
|
24574
|
+
const session = new components.RpcSession(transport(channel.port2));
|
|
24575
|
+
const rpc = session.getRemoteMain();
|
|
24576
|
+
return {
|
|
24577
|
+
rpc,
|
|
24578
|
+
dispose() {
|
|
24579
|
+
rpc[Symbol.dispose]();
|
|
24580
|
+
for (const transport2 of transports)
|
|
24581
|
+
transport2.abort();
|
|
24582
|
+
}
|
|
24583
|
+
};
|
|
24584
|
+
} catch (error51) {
|
|
24585
|
+
for (const transport2 of transports)
|
|
24586
|
+
transport2.abort(error51);
|
|
24587
|
+
channel.port1.close();
|
|
24588
|
+
channel.port2.close();
|
|
24589
|
+
throw error51;
|
|
24590
|
+
}
|
|
24591
|
+
}
|
|
24592
|
+
|
|
24593
|
+
// packages/desktop-control/dist/renderer-native-rpc-service.js
|
|
24594
|
+
function createNativeRpcService(components, createRemote) {
|
|
24595
|
+
const source = components.services.appServerManagers.dup();
|
|
24596
|
+
const routes = /* @__PURE__ */ new Map();
|
|
24597
|
+
const subscriptions = /* @__PURE__ */ new Set();
|
|
24598
|
+
let refs = 1;
|
|
24599
|
+
const record6 = (value2) => value2 !== null && typeof value2 === "object";
|
|
24600
|
+
const connectionSignals = (hostId2) => {
|
|
24601
|
+
let node = components.scope.node;
|
|
24602
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24603
|
+
while (node.parent && !seen.has(node.parent) && seen.size < 100) {
|
|
24604
|
+
seen.add(node);
|
|
24605
|
+
node = node.parent;
|
|
24606
|
+
}
|
|
24607
|
+
const found = [];
|
|
24608
|
+
for (const members of node.familyBindings.values()) {
|
|
24609
|
+
const value2 = members.get(hostId2)?.value;
|
|
24610
|
+
if (record6(value2) && Object.hasOwn(value2, "state$") && Object.hasOwn(value2, "revision$") && Object.hasOwn(value2, "appServerVersion$"))
|
|
24611
|
+
found.push({ state$: value2.state$, revision$: value2.revision$ });
|
|
24612
|
+
}
|
|
24613
|
+
return found.length === 1 ? found[0] : void 0;
|
|
24614
|
+
};
|
|
24615
|
+
const service = {
|
|
24616
|
+
dup() {
|
|
24617
|
+
refs++;
|
|
24618
|
+
return service;
|
|
24619
|
+
},
|
|
24620
|
+
onRpcBroken(listener) {
|
|
24621
|
+
source.onRpcBroken(listener);
|
|
24622
|
+
},
|
|
24623
|
+
openAccount(hostId2) {
|
|
24624
|
+
return source.openAccount(hostId2);
|
|
24625
|
+
},
|
|
24626
|
+
subscribe(hostId2, listener) {
|
|
24627
|
+
if (!hostId2.startsWith("remote-control:"))
|
|
24628
|
+
return source.subscribe(hostId2, listener);
|
|
24629
|
+
let active = true;
|
|
24630
|
+
let generation = 0;
|
|
24631
|
+
let upstream;
|
|
24632
|
+
let platformRequest;
|
|
24633
|
+
let remote;
|
|
24634
|
+
let stopWatch;
|
|
24635
|
+
let previousRevision;
|
|
24636
|
+
let previousState;
|
|
24637
|
+
const retire = () => {
|
|
24638
|
+
generation++;
|
|
24639
|
+
platformRequest?.[Symbol.dispose]();
|
|
24640
|
+
platformRequest = void 0;
|
|
24641
|
+
remote?.dispose();
|
|
24642
|
+
remote = void 0;
|
|
24643
|
+
routes.set(hostId2, null);
|
|
24644
|
+
};
|
|
24645
|
+
const cleanup = () => {
|
|
24646
|
+
if (!active)
|
|
24647
|
+
return;
|
|
24648
|
+
active = false;
|
|
24649
|
+
stopWatch?.();
|
|
24650
|
+
retire();
|
|
24651
|
+
upstream?.[Symbol.dispose]();
|
|
24652
|
+
upstream = void 0;
|
|
24653
|
+
routes.delete(hostId2);
|
|
24654
|
+
subscriptions.delete(cleanup);
|
|
24655
|
+
};
|
|
24656
|
+
subscriptions.add(cleanup);
|
|
24657
|
+
const publish = async () => {
|
|
24658
|
+
const owner = upstream;
|
|
24659
|
+
const current = generation;
|
|
24660
|
+
if (!owner || !active)
|
|
24661
|
+
return;
|
|
24662
|
+
let request;
|
|
24663
|
+
try {
|
|
24664
|
+
request = owner.getCodexHome();
|
|
24665
|
+
platformRequest = request;
|
|
24666
|
+
const home = await request;
|
|
24667
|
+
if (!active || current !== generation || owner !== upstream)
|
|
24668
|
+
return;
|
|
24669
|
+
if (!/^(?:[A-Za-z]:[\\/]|\\\\)/u.test(home)) {
|
|
24670
|
+
routes.delete(hostId2);
|
|
24671
|
+
listener({ status: "ready", manager: owner });
|
|
24672
|
+
return;
|
|
24673
|
+
}
|
|
24674
|
+
const created = createRemote(hostId2, owner);
|
|
24675
|
+
remote = created;
|
|
24676
|
+
await created.ready;
|
|
24677
|
+
if (!active || current !== generation || owner !== upstream)
|
|
24678
|
+
return;
|
|
24679
|
+
routes.set(hostId2, created.route);
|
|
24680
|
+
listener({ status: "ready", manager: created.rpc });
|
|
24681
|
+
} catch {
|
|
24682
|
+
if (active && current === generation) {
|
|
24683
|
+
remote?.dispose();
|
|
24684
|
+
remote = void 0;
|
|
24685
|
+
routes.delete(hostId2);
|
|
24686
|
+
listener({ status: "ready", manager: owner });
|
|
24687
|
+
}
|
|
24688
|
+
} finally {
|
|
24689
|
+
if (platformRequest === request) {
|
|
24690
|
+
platformRequest = void 0;
|
|
24691
|
+
request?.[Symbol.dispose]();
|
|
24692
|
+
}
|
|
24693
|
+
}
|
|
24694
|
+
};
|
|
24695
|
+
const changed = (state) => {
|
|
24696
|
+
if (!active)
|
|
24697
|
+
return;
|
|
24698
|
+
stopWatch?.();
|
|
24699
|
+
stopWatch = void 0;
|
|
24700
|
+
retire();
|
|
24701
|
+
upstream?.[Symbol.dispose]();
|
|
24702
|
+
upstream = void 0;
|
|
24703
|
+
if (state.status !== "ready") {
|
|
24704
|
+
listener(state);
|
|
24705
|
+
return;
|
|
24706
|
+
}
|
|
24707
|
+
upstream = state.manager.dup();
|
|
24708
|
+
listener({ status: "connecting" });
|
|
24709
|
+
const signals = connectionSignals(hostId2);
|
|
24710
|
+
if (!signals) {
|
|
24711
|
+
void publish();
|
|
24712
|
+
return;
|
|
24713
|
+
}
|
|
24714
|
+
previousState = void 0;
|
|
24715
|
+
previousRevision = void 0;
|
|
24716
|
+
stopWatch = components.scope.watch(({ get }) => {
|
|
24717
|
+
const connection = get(signals.state$), revision = get(signals.revision$);
|
|
24718
|
+
if (connection === previousState && revision === previousRevision)
|
|
24719
|
+
return;
|
|
24720
|
+
previousState = connection;
|
|
24721
|
+
previousRevision = revision;
|
|
24722
|
+
retire();
|
|
24723
|
+
listener({ status: connection === "connected" ? "connecting" : "disconnected" });
|
|
24724
|
+
if (connection === "connected")
|
|
24725
|
+
void publish();
|
|
24726
|
+
});
|
|
24727
|
+
};
|
|
24728
|
+
const original = source.subscribe(hostId2, changed);
|
|
24729
|
+
const result = original.then((lease) => {
|
|
24730
|
+
if (!active)
|
|
24731
|
+
lease[Symbol.dispose]();
|
|
24732
|
+
return {
|
|
24733
|
+
onRpcBroken: (listener2) => lease.onRpcBroken(listener2),
|
|
24734
|
+
[Symbol.dispose]() {
|
|
24735
|
+
cleanup();
|
|
24736
|
+
lease[Symbol.dispose]();
|
|
24737
|
+
}
|
|
24738
|
+
};
|
|
24739
|
+
});
|
|
24740
|
+
Object.assign(result, {
|
|
24741
|
+
onRpcBroken: (listener2) => original.onRpcBroken(listener2),
|
|
24742
|
+
[Symbol.dispose]() {
|
|
24743
|
+
cleanup();
|
|
24744
|
+
original[Symbol.dispose]();
|
|
24745
|
+
}
|
|
24746
|
+
});
|
|
24747
|
+
return result;
|
|
24748
|
+
},
|
|
24749
|
+
[Symbol.dispose]() {
|
|
24750
|
+
if (--refs !== 0)
|
|
24751
|
+
return;
|
|
24752
|
+
for (const cleanup of [...subscriptions])
|
|
24753
|
+
cleanup();
|
|
24754
|
+
source[Symbol.dispose]();
|
|
24755
|
+
}
|
|
24756
|
+
};
|
|
24757
|
+
return { service, route: (hostId2) => routes.get(hostId2) };
|
|
24758
|
+
}
|
|
24759
|
+
|
|
24760
|
+
// packages/desktop-control/dist/renderer-native-rpc-interactions.js
|
|
24761
|
+
function retainNativeRpcInteractions(upstream, manager, hostId2) {
|
|
24762
|
+
let disposed = false;
|
|
24763
|
+
const retained = /* @__PURE__ */ new Set();
|
|
24764
|
+
const requests = /* @__PURE__ */ new Map();
|
|
24765
|
+
const reads = /* @__PURE__ */ new Map();
|
|
24766
|
+
const record6 = (value2) => value2 !== null && typeof value2 === "object";
|
|
24767
|
+
const read = (threadId2) => {
|
|
24768
|
+
const existing = reads.get(threadId2);
|
|
24769
|
+
if (existing) {
|
|
24770
|
+
existing.dirty = true;
|
|
24771
|
+
return existing.promise;
|
|
24772
|
+
}
|
|
24773
|
+
const entry = { promise: Promise.resolve(), dirty: false };
|
|
24774
|
+
reads.set(threadId2, entry);
|
|
24775
|
+
entry.promise = Promise.resolve().then(async () => {
|
|
24776
|
+
do {
|
|
24777
|
+
if (disposed)
|
|
24778
|
+
break;
|
|
24779
|
+
entry.dirty = false;
|
|
24780
|
+
const pending = upstream.getConversation(threadId2);
|
|
24781
|
+
retained.add(pending);
|
|
24782
|
+
try {
|
|
24783
|
+
const conversation = await pending;
|
|
24784
|
+
if (disposed || entry.dirty || !record6(conversation) || !Array.isArray(conversation.requests))
|
|
24785
|
+
continue;
|
|
24786
|
+
const previous = requests.get(threadId2) ?? /* @__PURE__ */ new Set();
|
|
24787
|
+
const next = /* @__PURE__ */ new Set();
|
|
24788
|
+
for (const request of conversation.requests) {
|
|
24789
|
+
if (!record6(request) || typeof request.method !== "string" || !record6(request.params) || (request.params.threadId ?? request.params.conversationId) !== threadId2 || typeof request.id !== "string" && typeof request.id !== "number")
|
|
24790
|
+
continue;
|
|
24791
|
+
next.add(request.id);
|
|
24792
|
+
if (!previous.has(request.id))
|
|
24793
|
+
manager.onRequest(request);
|
|
24794
|
+
}
|
|
24795
|
+
if (next.size)
|
|
24796
|
+
requests.set(threadId2, next);
|
|
24797
|
+
else
|
|
24798
|
+
requests.delete(threadId2);
|
|
24799
|
+
} finally {
|
|
24800
|
+
if (retained.delete(pending))
|
|
24801
|
+
pending[Symbol.dispose]();
|
|
24802
|
+
}
|
|
24803
|
+
} while (!disposed && entry.dirty);
|
|
24804
|
+
}).finally(() => {
|
|
24805
|
+
reads.delete(threadId2);
|
|
24806
|
+
});
|
|
24807
|
+
return entry.promise;
|
|
24808
|
+
};
|
|
24809
|
+
const event = (value2) => {
|
|
24810
|
+
if (disposed || !record6(value2) || typeof value2.conversationId !== "string")
|
|
24811
|
+
return;
|
|
24812
|
+
void read(value2.conversationId).catch(() => void 0);
|
|
24813
|
+
};
|
|
24814
|
+
const subscribe = (input) => {
|
|
24815
|
+
const pending = upstream.subscribe(input);
|
|
24816
|
+
retained.add(pending);
|
|
24817
|
+
return Promise.resolve(pending).then((lease) => {
|
|
24818
|
+
if (disposed)
|
|
24819
|
+
lease[Symbol.dispose]();
|
|
24820
|
+
else
|
|
24821
|
+
retained.add(lease);
|
|
24822
|
+
});
|
|
24823
|
+
};
|
|
24824
|
+
const subscriptions = [
|
|
24825
|
+
"approval-request",
|
|
24826
|
+
"user-input-request",
|
|
24827
|
+
"mcp-elicitation-request",
|
|
24828
|
+
"approval-resolved"
|
|
24829
|
+
].map((name) => subscribe({ type: "event", key: { hostId: hostId2 }, event: name, listener: event }));
|
|
24830
|
+
subscriptions.push(subscribe({
|
|
24831
|
+
type: "notification",
|
|
24832
|
+
key: { hostId: hostId2 },
|
|
24833
|
+
methods: ["serverRequest/resolved"],
|
|
24834
|
+
listener(value2) {
|
|
24835
|
+
if (record6(value2) && record6(value2.params) && typeof value2.params.threadId === "string")
|
|
24836
|
+
event({ conversationId: value2.params.threadId });
|
|
24837
|
+
}
|
|
24838
|
+
}));
|
|
24839
|
+
const ready = Promise.all(subscriptions).then(async () => {
|
|
24840
|
+
if (disposed)
|
|
24841
|
+
return;
|
|
24842
|
+
const pending = upstream.getWorkInProgress();
|
|
24843
|
+
retained.add(pending);
|
|
24844
|
+
try {
|
|
24845
|
+
const work = await pending;
|
|
24846
|
+
if (disposed)
|
|
24847
|
+
return;
|
|
24848
|
+
if (!Array.isArray(work))
|
|
24849
|
+
throw new Error("Native RPC interaction snapshot is unavailable");
|
|
24850
|
+
const threadIds = new Set(work.flatMap((item) => record6(item) && typeof item.conversationId === "string" ? [item.conversationId] : []));
|
|
24851
|
+
await Promise.all([...threadIds].map(read));
|
|
24852
|
+
} finally {
|
|
24853
|
+
if (retained.delete(pending))
|
|
24854
|
+
pending[Symbol.dispose]();
|
|
24855
|
+
}
|
|
24856
|
+
});
|
|
24857
|
+
return {
|
|
24858
|
+
ready,
|
|
24859
|
+
dispose() {
|
|
24860
|
+
if (disposed)
|
|
24861
|
+
return;
|
|
24862
|
+
disposed = true;
|
|
24863
|
+
for (const lease of retained)
|
|
24864
|
+
lease[Symbol.dispose]();
|
|
24865
|
+
retained.clear();
|
|
24866
|
+
requests.clear();
|
|
24867
|
+
}
|
|
24868
|
+
};
|
|
24869
|
+
}
|
|
24870
|
+
|
|
24871
|
+
// packages/desktop-control/dist/renderer-native-rpc-install.js
|
|
24872
|
+
async function installNativeRpcRemoteControlDirect(renderer) {
|
|
24873
|
+
let attempt;
|
|
24874
|
+
const probeId = crypto.randomUUID();
|
|
24875
|
+
try {
|
|
24876
|
+
attempt = await renderer.evaluate(`(() => {
|
|
24877
|
+
if (window.__codexhostNativeRpcRemoteControlV1) return null;
|
|
24878
|
+
const routing = window.__codexhostHostRoutingV1;
|
|
24879
|
+
const owner = routing?.forHost('local')?.manager;
|
|
24880
|
+
if (owner?.kind !== 'main-process-rpc') return null;
|
|
24881
|
+
const catalog = window.__codexhostLoadedModulesV1;
|
|
24882
|
+
if (!catalog?.complete) return null;
|
|
24883
|
+
const key = JSON.stringify([catalog.owner, catalog.urls.filter(url => /renderer-app-server-managers|app-shared/.test(url)).sort()]);
|
|
24884
|
+
const previous = window.__codexhostNativeRpcDiscoveryV1;
|
|
24885
|
+
const sameOwner = previous?.key === key && previous.owner === owner;
|
|
24886
|
+
if (sameOwner && (previous.state !== 'unavailable' || previous.attempts >= 3 || Date.now() < previous.nextRetryAt)) return null;
|
|
24887
|
+
const token = ${JSON.stringify(probeId)};
|
|
24888
|
+
window.__codexhostNativeRpcDiscoveryV1 = {
|
|
24889
|
+
key, owner, token, state: 'discovering', attempts: sameOwner ? previous.attempts + 1 : 1,
|
|
24890
|
+
};
|
|
24891
|
+
return token;
|
|
24892
|
+
})()`);
|
|
24893
|
+
} catch {
|
|
24894
|
+
return false;
|
|
24895
|
+
}
|
|
24896
|
+
if (attempt === null)
|
|
24897
|
+
return false;
|
|
24898
|
+
let installed = false;
|
|
24899
|
+
try {
|
|
24900
|
+
installed = await withNativeRpcComponents(renderer, async (objectId) => {
|
|
24901
|
+
const result = await renderer.command("Runtime.callFunctionOn", {
|
|
24902
|
+
objectId,
|
|
24903
|
+
functionDeclaration: `function() {
|
|
24904
|
+
if (this.document !== document) return false;
|
|
24905
|
+
const retainRendererHostResponses = ${retainRendererHostResponses.toString()};
|
|
24906
|
+
const isolateRendererPrewarmConsumption = ${isolateRendererPrewarmConsumption.toString()};
|
|
24907
|
+
return (${installNativeRpcRemoteControl.toString()})(this, window, {
|
|
24908
|
+
createPolicy: ${createDraftPrewarmPolicyBridge.toString()},
|
|
24909
|
+
createManager: ${createNativeRemoteManager.toString()},
|
|
24910
|
+
createChannel: ${createNativeRpcChannel.toString()},
|
|
24911
|
+
createService: ${createNativeRpcService.toString()},
|
|
24912
|
+
retainInteractions: ${retainNativeRpcInteractions.toString()},
|
|
24913
|
+
});
|
|
24914
|
+
}`,
|
|
24915
|
+
returnByValue: true
|
|
24916
|
+
});
|
|
24917
|
+
return !result.exceptionDetails && result.result?.value === true;
|
|
24918
|
+
});
|
|
24919
|
+
return installed;
|
|
24920
|
+
} catch {
|
|
24921
|
+
return false;
|
|
24922
|
+
} finally {
|
|
24923
|
+
await renderer.evaluate(`(() => {
|
|
24924
|
+
const status = window.__codexhostNativeRpcDiscoveryV1;
|
|
24925
|
+
if (status?.token === ${JSON.stringify(attempt)}) {
|
|
24926
|
+
status.state = ${JSON.stringify(installed ? "ready" : "unavailable")};
|
|
24927
|
+
status.nextRetryAt = Date.now() + 5000 * 2 ** (status.attempts - 1);
|
|
24928
|
+
}
|
|
24929
|
+
})()`).catch(() => void 0);
|
|
24930
|
+
}
|
|
24931
|
+
}
|
|
24932
|
+
|
|
24065
24933
|
// packages/desktop-control/dist/renderer-cdp-control-session.js
|
|
24066
24934
|
function isRecord2(value2) {
|
|
24067
24935
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
@@ -24289,7 +25157,11 @@ var InstalledRendererCdpControlSession = class {
|
|
|
24289
25157
|
var defaultOperations = {
|
|
24290
25158
|
listTargets: (endpoint, signal) => listCdpTargets(endpoint, fetch, signal),
|
|
24291
25159
|
connect: (webSocketDebuggerUrl) => CdpClient.connect(webSocketDebuggerUrl),
|
|
24292
|
-
installDraftPrewarmPolicy
|
|
25160
|
+
async installDraftPrewarmPolicy(renderer) {
|
|
25161
|
+
const status2 = await installRendererDraftPrewarmPolicyDirect(renderer);
|
|
25162
|
+
await installNativeRpcRemoteControlDirect(renderer);
|
|
25163
|
+
return status2;
|
|
25164
|
+
}
|
|
24293
25165
|
};
|
|
24294
25166
|
async function createRendererCdpControlSession(options) {
|
|
24295
25167
|
const enabledAgents = options.enabledAgents;
|
|
@@ -34263,12 +35135,13 @@ var ExternalThreadRuntime = class {
|
|
|
34263
35135
|
}
|
|
34264
35136
|
try {
|
|
34265
35137
|
const aligned = await this.#repository.alignSnapshot(thread.record, snapshot2.value);
|
|
35138
|
+
const turns = aligned.record.state === "creating" && !aligned.record.nativeSessionRef && snapshot2.value.turns.length === 0 ? thread.turns : aligned.turns;
|
|
34266
35139
|
thread.record = aligned.record;
|
|
34267
|
-
thread.turns =
|
|
35140
|
+
thread.turns = turns;
|
|
34268
35141
|
thread.historyHydrated = true;
|
|
34269
35142
|
thread.thread = externalThreadValue({
|
|
34270
35143
|
record: aligned.record,
|
|
34271
|
-
turns
|
|
35144
|
+
turns,
|
|
34272
35145
|
sessionId: thread.sessionId,
|
|
34273
35146
|
running: thread.running
|
|
34274
35147
|
});
|
|
@@ -42058,7 +42931,10 @@ var AppServerHost = class {
|
|
|
42058
42931
|
request,
|
|
42059
42932
|
location,
|
|
42060
42933
|
(hostThreadId) => this.#repository.setArchived(hostThreadId, archived),
|
|
42061
|
-
"External Thread archive state could not be persisted"
|
|
42934
|
+
"External Thread archive state could not be persisted",
|
|
42935
|
+
// A loaded Thread whose deferred native Session never arrived (its first Turn
|
|
42936
|
+
// failed first) is still on Desktop's list and must remain archivable.
|
|
42937
|
+
true
|
|
42062
42938
|
);
|
|
42063
42939
|
if (!updated) return;
|
|
42064
42940
|
await this.#writer.json(
|