@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.
@@ -16818,9 +16818,10 @@ function isolateRendererPrewarmConsumption(manager, discardExternal) {
16818
16818
  }
16819
16819
 
16820
16820
  // packages/desktop-control/src/renderer-draft-prewarm-runtime.ts
16821
- function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewarmedThreadManager, isCurrentManager, retainResponses = retainRendererHostResponses, isolateConsumption = isolateRendererPrewarmConsumption) {
16821
+ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewarmedThreadManager, isCurrentManager, retainResponses = retainRendererHostResponses, isolateConsumption = isolateRendererPrewarmConsumption, sendControlRequest) {
16822
16822
  let disposed = false;
16823
16823
  const originalSend = bridge.sendRequest;
16824
+ const controlSend = (method, parameters) => sendControlRequest ? sendControlRequest(method, parameters) : originalSend.call(bridge, method, parameters);
16824
16825
  const originalPrewarm = bridge.prewarmThreadStart;
16825
16826
  const originalOnNotification = manager.onNotification;
16826
16827
  const originalDispatchAppServerResponse = manager.dispatchAppServerResponse;
@@ -16904,7 +16905,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
16904
16905
  bridgeRequests.clear();
16905
16906
  if (isRemoteControlHost && terminate) {
16906
16907
  void Promise.resolve(
16907
- originalSend.call(bridge, "process/kill", { processHandle: failedProcessHandle })
16908
+ controlSend("process/kill", { processHandle: failedProcessHandle })
16908
16909
  ).catch(() => void 0);
16909
16910
  }
16910
16911
  };
@@ -17067,7 +17068,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
17067
17068
  ];
17068
17069
  const startedProcessHandle = bridgeProcessHandle;
17069
17070
  try {
17070
- const started = originalSend.call(bridge, "process/spawn", {
17071
+ const started = controlSend("process/spawn", {
17071
17072
  command,
17072
17073
  processHandle: startedProcessHandle,
17073
17074
  cwd: "C:\\",
@@ -17088,7 +17089,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
17088
17089
  const operation = async () => {
17089
17090
  await startBridge();
17090
17091
  if (bridgeState !== "ready") throw transportError("is not ready");
17091
- await originalSend.call(bridge, "process/writeStdin", {
17092
+ await controlSend("process/writeStdin", {
17092
17093
  processHandle: bridgeProcessHandle,
17093
17094
  deltaBase64: utf8Base64(`${JSON.stringify(value)}
17094
17095
  `)
@@ -17363,7 +17364,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
17363
17364
  bridgeReadyTimeout = null;
17364
17365
  if (isRemoteControlHost && (bridgeState === "starting" || bridgeState === "ready")) {
17365
17366
  void Promise.resolve(
17366
- originalSend.call(bridge, "process/kill", { processHandle: bridgeProcessHandle })
17367
+ controlSend("process/kill", { processHandle: bridgeProcessHandle })
17367
17368
  ).catch(() => void 0);
17368
17369
  }
17369
17370
  bridgeState = "disposed";
@@ -17465,10 +17466,11 @@ function resolveRendererHostManager(discovery, hostId2, managerFrom = requestMan
17465
17466
  }
17466
17467
 
17467
17468
  // packages/desktop-control/src/renderer-host-routing.ts
17468
- function installRendererHostRouting(root, target, discover, resolve, createPolicy) {
17469
+ function installRendererHostRouting(root, target, discover, resolve, createPolicy, readConnection, publishRouting = true) {
17469
17470
  const existing = target.__codexhostHostRoutingV1;
17470
- if (existing) return existing;
17471
- target.__codexhostDraftPrewarmPolicyV1?.dispose?.();
17471
+ if (publishRouting && existing) return existing;
17472
+ if (publishRouting)
17473
+ target.__codexhostDraftPrewarmPolicyV1?.dispose?.();
17472
17474
  let disposed = false;
17473
17475
  let lastDiscovery = null;
17474
17476
  const routes = /* @__PURE__ */ new Map();
@@ -17495,10 +17497,20 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
17495
17497
  routes.delete(hostId2);
17496
17498
  entry?.route.policy.dispose();
17497
17499
  };
17500
+ const connectionFor = (hostId2) => {
17501
+ if (!hostId2.startsWith("remote-control:")) return void 0;
17502
+ try {
17503
+ return readConnection?.(hostId2);
17504
+ } catch {
17505
+ return null;
17506
+ }
17507
+ };
17508
+ const sameConnection = (expected, current) => expected === void 0 ? current === void 0 : current?.owner === expected.owner && current.revision === expected.revision;
17498
17509
  const routeFor = (hostId2, discovery) => {
17499
17510
  const manager = lookup(hostId2, discovery);
17511
+ const connection = connectionFor(hostId2);
17500
17512
  const previous = routes.get(hostId2);
17501
- if (manager && previous?.route.manager === manager && previous.bridge === manager.requestClient && previous.prewarmed === manager.prewarmedThreadManager && previous.route.policy.owns(
17513
+ if (manager && previous?.route.manager === manager && previous.bridge === manager.requestClient && previous.prewarmed === manager.prewarmedThreadManager && sameConnection(previous.connection, connection) && previous.route.policy.owns(
17502
17514
  manager,
17503
17515
  manager.requestClient,
17504
17516
  hostId2,
@@ -17508,7 +17520,7 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
17508
17520
  return previous.route;
17509
17521
  }
17510
17522
  retire(hostId2);
17511
- if (!manager) return null;
17523
+ if (!manager || connection === null) return null;
17512
17524
  const bridge = manager.requestClient;
17513
17525
  const prewarmed = manager.prewarmedThreadManager;
17514
17526
  const policy = createPolicy(
@@ -17517,13 +17529,14 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
17517
17529
  hostId2,
17518
17530
  target,
17519
17531
  prewarmed,
17520
- () => lookup(hostId2) === manager && manager.requestClient === bridge && manager.prewarmedThreadManager === prewarmed
17532
+ () => lookup(hostId2) === manager && sameConnection(connection, connectionFor(hostId2)) && manager.requestClient === bridge && manager.prewarmedThreadManager === prewarmed
17521
17533
  );
17522
17534
  const route = { hostId: hostId2, manager, policy };
17523
- routes.set(hostId2, { route, bridge, prewarmed });
17535
+ routes.set(hostId2, { route, bridge, prewarmed, connection });
17524
17536
  return route;
17525
17537
  };
17526
17538
  const publish = (route) => {
17539
+ if (!publishRouting) return;
17527
17540
  const policy = route?.policy;
17528
17541
  if (target.__codexhostDraftPrewarmPolicyV1 === policy) return;
17529
17542
  Object.defineProperty(target, "__codexhostDraftPrewarmPolicyV1", {
@@ -17576,7 +17589,7 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
17576
17589
  if (!composer) {
17577
17590
  for (const [hostId3, entry] of routes) {
17578
17591
  const manager = lookup(hostId3, discovery);
17579
- if (manager !== entry.route.manager || manager.requestClient !== entry.bridge || manager.prewarmedThreadManager !== entry.prewarmed)
17592
+ if (manager !== entry.route.manager || manager.requestClient !== entry.bridge || manager.prewarmedThreadManager !== entry.prewarmed || !sameConnection(entry.connection, connectionFor(hostId3)))
17580
17593
  retire(hostId3);
17581
17594
  }
17582
17595
  }
@@ -17596,7 +17609,11 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
17596
17609
  }
17597
17610
  }
17598
17611
  };
17599
- Object.defineProperty(target, "__codexhostHostRoutingV1", { configurable: true, value: routing });
17612
+ if (publishRouting)
17613
+ Object.defineProperty(target, "__codexhostHostRoutingV1", {
17614
+ configurable: true,
17615
+ value: routing
17616
+ });
17600
17617
  return routing;
17601
17618
  }
17602
17619
 
@@ -17690,17 +17707,37 @@ function installRendererHostRpcRouting(root, target, dependencies) {
17690
17707
  const existing = target.__codexhostHostRoutingV1;
17691
17708
  if (existing) return existing;
17692
17709
  let disposed = false;
17710
+ let nativeRouting = null;
17693
17711
  let discovery = null;
17694
17712
  const routes = /* @__PURE__ */ new Map();
17695
17713
  const read = () => {
17696
17714
  if (disposed) return null;
17697
- if (!discovery) {
17715
+ try {
17698
17716
  const store = dependencies.findStore(root);
17699
17717
  discovery = store ? dependencies.findFamily(store) : null;
17718
+ } catch {
17719
+ discovery = null;
17700
17720
  }
17701
17721
  return discovery;
17702
17722
  };
17703
17723
  if (!read()) return null;
17724
+ const native = () => {
17725
+ if (disposed) return null;
17726
+ try {
17727
+ nativeRouting ??= dependencies.nativeRouting?.() ?? null;
17728
+ } catch {
17729
+ }
17730
+ return nativeRouting;
17731
+ };
17732
+ const connectionFor = (hostId2) => {
17733
+ if (!hostId2.startsWith("remote-control:")) return void 0;
17734
+ try {
17735
+ return dependencies.readConnection?.(hostId2);
17736
+ } catch {
17737
+ return null;
17738
+ }
17739
+ };
17740
+ const sameConnection = (previous, current) => previous === void 0 ? current === void 0 : current?.owner === previous.owner && current.revision === previous.revision;
17704
17741
  const isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17705
17742
  const externalDrafts = /* @__PURE__ */ new Map();
17706
17743
  const selectedModels = /* @__PURE__ */ new Map();
@@ -17778,16 +17815,25 @@ function installRendererHostRpcRouting(root, target, dependencies) {
17778
17815
  const postMessage = function(message, ...rest) {
17779
17816
  let routed = message;
17780
17817
  try {
17781
- routed = disposed ? message : routeCreationCall(message);
17818
+ routed = disposed || routes.size === 0 ? message : routeCreationCall(message);
17782
17819
  } catch {
17783
17820
  routed = message;
17784
17821
  }
17785
17822
  return originalPostMessage.call(this, routed, ...rest);
17786
17823
  };
17787
17824
  port.postMessage = postMessage;
17788
- const createRoute = (hostId2, rpc) => {
17825
+ const createRoute = (hostId2, rpc, connection) => {
17789
17826
  let retired = false;
17790
- const isCurrent = () => !retired && !disposed && routes.get(hostId2)?.rpc === rpc;
17827
+ const isCurrent = () => {
17828
+ if (retired || disposed || routes.get(hostId2)?.rpc !== rpc || !sameConnection(connection, connectionFor(hostId2)))
17829
+ return false;
17830
+ try {
17831
+ const current = read();
17832
+ return !!current && dependencies.resolve(current, hostId2) === rpc;
17833
+ } catch {
17834
+ return false;
17835
+ }
17836
+ };
17791
17837
  const manager = Object.freeze({
17792
17838
  kind: "main-process-rpc",
17793
17839
  getHostId: () => hostId2,
@@ -17860,15 +17906,23 @@ function installRendererHostRpcRouting(root, target, dependencies) {
17860
17906
  routes.delete(hostId2);
17861
17907
  entry?.route.policy.dispose();
17862
17908
  };
17863
- const routeFor = (hostId2) => {
17909
+ const routeFor = (hostId2, nativeRoute) => {
17910
+ if (disposed) return null;
17911
+ const connection = connectionFor(hostId2);
17912
+ const preferred = nativeRoute === void 0 ? native()?.forHost(hostId2) : nativeRoute;
17913
+ if (connection === null || preferred) {
17914
+ retire(hostId2);
17915
+ return connection === null ? null : preferred ?? null;
17916
+ }
17864
17917
  const current = read();
17865
17918
  const rpc = current ? dependencies.resolve(current, hostId2) : null;
17866
17919
  const previous = routes.get(hostId2);
17867
- if (rpc && previous?.rpc === rpc) return previous.route;
17920
+ if (rpc && previous?.rpc === rpc && sameConnection(previous.connection, connection))
17921
+ return previous.route;
17868
17922
  retire(hostId2);
17869
17923
  if (!rpc) return null;
17870
- const route = createRoute(hostId2, rpc);
17871
- routes.set(hostId2, { route, rpc });
17924
+ const route = createRoute(hostId2, rpc, connection);
17925
+ routes.set(hostId2, { route, rpc, connection });
17872
17926
  return route;
17873
17927
  };
17874
17928
  const publish = (route) => {
@@ -17883,14 +17937,22 @@ function installRendererHostRpcRouting(root, target, dependencies) {
17883
17937
  }
17884
17938
  };
17885
17939
  const composerHostId = (composer) => {
17940
+ const nativeHostId = native()?.hostIdForComposer(composer);
17941
+ if (nativeHostId) return nativeHostId;
17886
17942
  const hostIds = new Set(dependencies.composerHostIds(composer).hostIds);
17887
17943
  const hostId2 = hostIds.size === 1 ? hostIds.values().next().value : null;
17888
17944
  return typeof hostId2 === "string" && hostId2 ? hostId2 : null;
17889
17945
  };
17890
17946
  const routing = {
17891
17947
  knownHostIds() {
17948
+ if (disposed) return [];
17892
17949
  const current = read();
17893
- return current ? dependencies.hostIds(current) : [];
17950
+ return [
17951
+ .../* @__PURE__ */ new Set([
17952
+ ...current ? dependencies.hostIds(current) : [],
17953
+ ...native()?.knownHostIds?.() ?? []
17954
+ ])
17955
+ ];
17894
17956
  },
17895
17957
  forHost(hostId2) {
17896
17958
  return hostId2 && !disposed ? routeFor(hostId2) : null;
@@ -17906,18 +17968,22 @@ function installRendererHostRpcRouting(root, target, dependencies) {
17906
17968
  forComposer(composer) {
17907
17969
  if (disposed) return null;
17908
17970
  let hostId2;
17971
+ let preferred = null;
17909
17972
  try {
17910
- hostId2 = composerHostId(composer);
17973
+ preferred = native()?.forComposer(composer) ?? null;
17974
+ hostId2 = preferred?.hostId ?? composerHostId(composer);
17911
17975
  } catch {
17912
17976
  hostId2 = null;
17913
17977
  }
17914
- const route = hostId2 ? routeFor(hostId2) : null;
17978
+ const route = hostId2 ? routeFor(hostId2, preferred) : null;
17915
17979
  if (!composer) publish(route);
17916
17980
  return route;
17917
17981
  },
17918
17982
  dispose() {
17919
17983
  if (disposed) return;
17920
17984
  disposed = true;
17985
+ nativeRouting?.dispose();
17986
+ nativeRouting = null;
17921
17987
  for (const hostId2 of [...routes.keys()]) retire(hostId2);
17922
17988
  discovery = null;
17923
17989
  externalDrafts.clear();
@@ -17933,6 +17999,30 @@ function installRendererHostRpcRouting(root, target, dependencies) {
17933
17999
  return routing;
17934
18000
  }
17935
18001
 
18002
+ // packages/desktop-control/src/renderer-connection-generation.ts
18003
+ function readRendererConnectionGeneration(store, hostId2) {
18004
+ if (!store) return void 0;
18005
+ const record3 = (value) => value !== null && typeof value === "object";
18006
+ const candidates = /* @__PURE__ */ new Set();
18007
+ for (const members of store.familyBindings.values()) {
18008
+ const value = members.get(hostId2)?.value;
18009
+ if (record3(value) && record3(value.state$) && record3(value.revision$) && record3(value.appServerVersion$) && typeof value.state$.get === "function" && typeof value.revision$.get === "function")
18010
+ candidates.add(value);
18011
+ }
18012
+ if (!candidates.size) return void 0;
18013
+ if (candidates.size !== 1) return null;
18014
+ const owner = candidates.values().next().value;
18015
+ if (!owner) return null;
18016
+ const state = owner.state$;
18017
+ const revision = owner.revision$;
18018
+ try {
18019
+ const current = revision.get();
18020
+ return state.get() === "connected" && typeof current === "number" && Number.isSafeInteger(current) ? { owner, revision: current } : null;
18021
+ } catch {
18022
+ return null;
18023
+ }
18024
+ }
18025
+
17936
18026
  // packages/desktop-control/src/renderer-draft-prewarm-policy.ts
17937
18027
  var REQUEST_MANAGER_WAIT_TIMEOUT_MS = 6e4;
17938
18028
  var REQUEST_MANAGER_POLL_INTERVAL_MS = 25;
@@ -17945,15 +18035,19 @@ function directRendererInstaller() {
17945
18035
  const retainRendererHostResponses = ${retainRendererHostResponses.toString()};
17946
18036
  const createDraftPrewarmPolicyBridge = ${createDraftPrewarmPolicyBridge.toString()};
17947
18037
  const isolateRendererPrewarmConsumption = ${isolateRendererPrewarmConsumption.toString()};
18038
+ const findRendererAppScopeStore = ${findRendererAppScopeStore.toString()};
18039
+ const readRendererConnectionGeneration = ${readRendererConnectionGeneration.toString()};
17948
18040
  const discover = (root) =>
17949
18041
  discoverRendererHosts(root, committedReactAncestors, requestManagerFromHookState);
17950
- const installNative = () => (${installRendererHostRouting.toString()})(
18042
+ const installNative = (publishRouting = true) => (${installRendererHostRouting.toString()})(
17951
18043
  document, window, discover,
17952
18044
  (discovery, hostId) => resolveRendererHostManager(discovery, hostId, requestManagerFromHookState),
17953
18045
  (manager, bridge, hostId, target, prewarmed, isCurrent) => createDraftPrewarmPolicyBridge(
17954
18046
  manager, bridge, hostId, target, prewarmed, isCurrent, retainRendererHostResponses,
17955
18047
  isolateRendererPrewarmConsumption,
17956
18048
  ),
18049
+ (hostId) => readRendererConnectionGeneration(findRendererAppScopeStore(document), hostId),
18050
+ publishRouting,
17957
18051
  );
17958
18052
  const installRpc = () => typeof MessagePort !== 'function' ? null : (${installRendererHostRpcRouting.toString()})(document, window, {
17959
18053
  findStore: ${findRendererAppScopeStore.toString()},
@@ -17967,14 +18061,21 @@ function directRendererInstaller() {
17967
18061
  return discover(source);
17968
18062
  },
17969
18063
  portPrototype: MessagePort.prototype,
18064
+ nativeRouting: () => {
18065
+ const native = discover(document);
18066
+ return native.managers.length || native.registries.length ? installNative(false) : null;
18067
+ },
18068
+ readConnection: (hostId) => readRendererConnectionGeneration(findRendererAppScopeStore(document), hostId),
17970
18069
  });
17971
18070
  const connected = (routing) => routing.forComposer() !== null ||
17972
18071
  ['local', ...(routing.knownHostIds?.() ?? [])].some((hostId) => routing.forHost(hostId) !== null);
17973
18072
  let nativeReady = false;
17974
- // A legacy registry can remain mounted without a usable native manager.
17975
- // Prefer a ready native route, then try the identified main-process RPC store.
18073
+ // Mixed layouts can expose native managers for only some Hosts. Keep one
18074
+ // router that selects a native owner or the current ready RPC peer per Host.
17976
18075
  const routing = (() => {
17977
18076
  if (window.__codexhostHostRoutingV1) return window.__codexhostHostRoutingV1;
18077
+ const rpc = installRpc();
18078
+ if (rpc) return rpc;
17978
18079
  const native = discover(document);
17979
18080
  if (native.managers.length || native.registries.length) {
17980
18081
  const routing = installNative();
@@ -17984,8 +18085,6 @@ function directRendererInstaller() {
17984
18085
  }
17985
18086
  routing.dispose();
17986
18087
  }
17987
- const rpc = installRpc();
17988
- if (rpc) return rpc;
17989
18088
  throw new Error('Renderer Host request manager is unavailable');
17990
18089
  })();
17991
18090
  // Publish a default draft policy only when its Host is unambiguous. Host
@@ -18145,6 +18244,781 @@ async function installRendererLoadedModules(renderer) {
18145
18244
  }
18146
18245
  }
18147
18246
 
18247
+ // packages/desktop-control/src/renderer-native-rpc-discovery.ts
18248
+ function nativeManagerDependencies(factoryName, callers) {
18249
+ const identifier = "[$A-Z_a-z][$\\w]*";
18250
+ const escaped = factoryName.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
18251
+ const pattern = new RegExp(
18252
+ `${escaped}\\((${identifier}),(${identifier}),\\1\\.get\\((${identifier}),\\2\\),(${identifier})\\.bind\\(null,\\1\\),\\((${identifier}),(${identifier})\\)=>\\5\\((${identifier}),\\6\\)\\)`
18253
+ );
18254
+ const matches = callers.flatMap((source) => {
18255
+ const match = pattern.exec(source);
18256
+ return match?.[3] && match[4] && match[7] ? [
18257
+ {
18258
+ requestDefinition: match[3],
18259
+ isHostForConversation: match[4],
18260
+ imageDefinition: match[7]
18261
+ }
18262
+ ] : [];
18263
+ });
18264
+ return matches.length === 1 ? matches[0] : void 0;
18265
+ }
18266
+ function nativeRpcRole(source) {
18267
+ if (["dispatchMessageFromView", "threadProjectAssignments", "queuedMessageCoordination"].every(
18268
+ (part) => source.includes(part)
18269
+ ))
18270
+ return "createManager";
18271
+ if (["collectAppStateSnapshot", "getReviewPaneSnapshotMetrics", "registerReplayAdmission"].every(
18272
+ (part) => source.includes(part)
18273
+ ))
18274
+ return "createController";
18275
+ if (["getWorkInProgress", "getCachedThreadSearchSnapshot", "registerReplayAdmission"].every(
18276
+ (part) => source.includes(part)
18277
+ ))
18278
+ return "RpcManager";
18279
+ if (["prewarmedThreadManager", "onNotification", "dispatchAppServerResponse"].every(
18280
+ (part) => source.includes(part)
18281
+ ))
18282
+ return "Manager";
18283
+ return void 0;
18284
+ }
18285
+ function nativeRpcObjectShape(value) {
18286
+ if (value === null || typeof value !== "object")
18287
+ return { scope: false, services: false, controller: false };
18288
+ const candidate = value;
18289
+ const own = (keys) => keys.every((key) => Object.hasOwn(candidate, key));
18290
+ const methods = (keys) => keys.every((key) => typeof candidate[key] === "function");
18291
+ return {
18292
+ scope: own(["node", "scope", "get", "set", "watch"]) && methods(["get", "set", "watch"]),
18293
+ services: own(["appServerManagers", "remoteConnections", "applicationMenu"]) && typeof candidate.appServerManagers?.subscribe === "function",
18294
+ controller: own(["forHost", "collectAppStateSnapshot", "getReviewPaneSnapshotMetrics", "dispose"]) && methods(["forHost", "collectAppStateSnapshot", "getReviewPaneSnapshotMetrics", "dispose"])
18295
+ };
18296
+ }
18297
+ async function withNativeRpcComponents(client, install) {
18298
+ const group = `codexhost-native-rpc-${crypto.randomUUID()}`;
18299
+ const command = async (method, params) => client.command(method, params);
18300
+ const evaluate = (expression) => command("Runtime.evaluate", { expression, awaitPromise: true, objectGroup: group });
18301
+ const properties = (objectId) => command("Runtime.getProperties", { objectId, ownProperties: true });
18302
+ const call = (objectId, functionDeclaration, args = []) => command("Runtime.callFunctionOn", {
18303
+ objectId,
18304
+ functionDeclaration,
18305
+ arguments: args,
18306
+ objectGroup: group,
18307
+ returnByValue: true
18308
+ });
18309
+ try {
18310
+ const initial = await evaluate(String.raw`(() => {
18311
+ const catalog = globalThis.__codexhostLoadedModulesV1;
18312
+ if (!catalog?.complete || catalog.documentUrl !== location.href) return null;
18313
+ const urls = catalog.urls.filter(url => /^app:\/\/-\/assets\/(?:renderer-app-server-managers|app-shared)-[^/]+\.js$/.test(url));
18314
+ return { document, urls };
18315
+ })()`);
18316
+ if (!initial.result.objectId) return false;
18317
+ const holder = initial.result.objectId;
18318
+ const catalog = await call(holder, "function(){return this.urls}");
18319
+ const urls = catalog.result.value;
18320
+ if (!Array.isArray(urls) || urls.length !== 2) return false;
18321
+ const managerUrl = urls.find((url2) => url2.includes("renderer-app-server-managers"));
18322
+ const sharedUrl = urls.find((url2) => url2.includes("app-shared"));
18323
+ if (!managerUrl || !sharedUrl) return false;
18324
+ const attach = async (name, objectId) => {
18325
+ const result = await call(
18326
+ holder,
18327
+ "function(name,value){if(this.document!==document)throw Error('Renderer Realm changed');this[name]=value;return true}",
18328
+ [{ value: name }, { objectId }]
18329
+ );
18330
+ if (result.exceptionDetails) throw new Error("Native RPC discovery lost its Renderer Realm");
18331
+ };
18332
+ const imported = await evaluate(`import(${JSON.stringify(managerUrl)})`);
18333
+ if (!imported.result.objectId) return false;
18334
+ const exports = (await properties(imported.result.objectId)).result.filter(
18335
+ (entry) => entry.value?.type === "function"
18336
+ );
18337
+ let bindings = [];
18338
+ for (const entry of exports.slice(0, 3)) {
18339
+ if (!entry.value?.objectId) continue;
18340
+ const scopes = (await properties(entry.value.objectId)).internalProperties?.find(
18341
+ (entry2) => entry2.name === "[[Scopes]]"
18342
+ )?.value?.objectId;
18343
+ if (!scopes) continue;
18344
+ const modules = (await properties(scopes)).result.filter(
18345
+ (entry2) => entry2.value?.description?.startsWith("Module") && entry2.value.objectId
18346
+ );
18347
+ const moduleId = modules[0]?.value?.objectId;
18348
+ if (modules.length !== 1 || !moduleId) continue;
18349
+ bindings = (await properties(moduleId)).result;
18350
+ break;
18351
+ }
18352
+ const functions = bindings.filter((entry) => entry.value?.type === "function");
18353
+ const roles = /* @__PURE__ */ new Map();
18354
+ for (const entry of functions) {
18355
+ const role = nativeRpcRole(entry.value?.description ?? "");
18356
+ if (role) roles.set(role, [...roles.get(role) ?? [], entry]);
18357
+ }
18358
+ if (["createManager", "Manager", "RpcManager", "createController"].some(
18359
+ (role) => roles.get(role)?.length !== 1
18360
+ ))
18361
+ return false;
18362
+ const factory = roles.get("createManager")?.[0];
18363
+ if (!factory) return false;
18364
+ const dependencies = nativeManagerDependencies(
18365
+ factory.name,
18366
+ functions.map((entry) => entry.value?.description ?? "")
18367
+ );
18368
+ if (!dependencies) return false;
18369
+ for (const [role, entries] of roles) {
18370
+ const id = entries[0]?.value?.objectId;
18371
+ if (!id) return false;
18372
+ await attach(role, id);
18373
+ }
18374
+ for (const [role, name] of Object.entries(dependencies)) {
18375
+ const value = bindings.find((entry) => entry.name === name)?.value?.objectId;
18376
+ if (!value) return false;
18377
+ await attach(role, value);
18378
+ }
18379
+ const shared = await evaluate(`import(${JSON.stringify(sharedUrl)})`);
18380
+ if (!shared.result.objectId) return false;
18381
+ const sharedExports = (await properties(shared.result.objectId)).result;
18382
+ const sessions = sharedExports.filter(
18383
+ (entry) => entry.value?.type === "function" && ["getRemoteMain", "getStats", "drain", "getMainImport"].every(
18384
+ (word) => entry.value?.description?.includes(word)
18385
+ )
18386
+ );
18387
+ const sessionId = sessions[0]?.value?.objectId;
18388
+ if (sessions.length !== 1 || !sessionId) return false;
18389
+ await attach("RpcSession", sessionId);
18390
+ const serviceMatches = await command("Runtime.callFunctionOn", {
18391
+ objectId: shared.result.objectId,
18392
+ functionDeclaration: `function(){return [...new Set(Object.values(this).filter(value => (${nativeRpcObjectShape.toString()})(value).services))]}`,
18393
+ objectGroup: group
18394
+ });
18395
+ if (!serviceMatches.result.objectId) return false;
18396
+ const services = (await properties(serviceMatches.result.objectId)).result.flatMap(
18397
+ (entry) => entry.value?.type === "object" && entry.value.objectId ? [entry.value.objectId] : []
18398
+ );
18399
+ const serviceId = services[0];
18400
+ if (services.length !== 1 || !serviceId) return false;
18401
+ await attach("services", serviceId);
18402
+ const prototype = await evaluate("Object.getPrototypeOf(async function(){})");
18403
+ if (!prototype.result.objectId) return false;
18404
+ const objects = await command("Runtime.queryObjects", {
18405
+ prototypeObjectId: prototype.result.objectId,
18406
+ objectGroup: group
18407
+ });
18408
+ if (!objects.objects.objectId) return false;
18409
+ const filtered = await command("Runtime.callFunctionOn", {
18410
+ objectId: objects.objects.objectId,
18411
+ functionDeclaration: 'function(){return this.filter(fn=>fn.name==="collectAppStateSnapshot"&&String(fn).includes("collectSnapshot")).slice(0,9)}',
18412
+ objectGroup: group
18413
+ });
18414
+ if (!filtered.result.objectId) return false;
18415
+ const snapshots = (await properties(filtered.result.objectId)).result.filter(
18416
+ (entry) => entry.value?.type === "function"
18417
+ );
18418
+ if (snapshots.length > 8) return false;
18419
+ const owners = [];
18420
+ for (const snapshot of snapshots) {
18421
+ const fn = snapshot.value?.objectId;
18422
+ if (!fn) continue;
18423
+ const scopes = (await properties(fn)).internalProperties?.find(
18424
+ (entry) => entry.name === "[[Scopes]]"
18425
+ )?.value?.objectId;
18426
+ if (!scopes) continue;
18427
+ for (const scope of (await properties(scopes)).result) {
18428
+ if (!scope.value?.description?.startsWith("Closure") || !scope.value.objectId) continue;
18429
+ const candidates = (await properties(scope.value.objectId)).result;
18430
+ const controllers = [], handles = [];
18431
+ for (const binding of candidates) {
18432
+ if (binding.value?.type !== "object" || !binding.value.objectId) continue;
18433
+ const id = binding.value.objectId;
18434
+ const response = await call(
18435
+ id,
18436
+ `function(){return (${nativeRpcObjectShape.toString()})(this)}`
18437
+ );
18438
+ const shape = response.result.value;
18439
+ if (shape?.scope) handles.push(id);
18440
+ if (shape?.controller && (await call(id, "function(fn){return this.collectAppStateSnapshot===fn}", [
18441
+ { objectId: fn }
18442
+ ])).result.value === true)
18443
+ controllers.push(id);
18444
+ }
18445
+ const controller = controllers[0], handle = handles[0];
18446
+ if (controllers.length === 1 && handles.length === 1 && controller && handle)
18447
+ owners.push({ controller, scope: handle });
18448
+ }
18449
+ }
18450
+ const owner = owners[0];
18451
+ if (owners.length !== 1 || !owner) return false;
18452
+ await attach("controller", owner.controller);
18453
+ await attach("scope", owner.scope);
18454
+ return await install(holder);
18455
+ } finally {
18456
+ await client.command("Runtime.releaseObjectGroup", { objectGroup: group }).catch(() => void 0);
18457
+ }
18458
+ }
18459
+
18460
+ // packages/desktop-control/src/renderer-native-rpc-runtime.ts
18461
+ function installNativeRpcRemoteControl(components, target, dependencies) {
18462
+ if (target.__codexhostNativeRpcRemoteControlV1) return true;
18463
+ const routing = target.__codexhostHostRoutingV1;
18464
+ if (!routing) return false;
18465
+ const adapted = dependencies.createService(
18466
+ components,
18467
+ (hostId2, upstream) => dependencies.createManager(
18468
+ components,
18469
+ hostId2,
18470
+ upstream,
18471
+ target,
18472
+ dependencies.createPolicy,
18473
+ dependencies.createChannel,
18474
+ dependencies.retainInteractions
18475
+ )
18476
+ );
18477
+ const controller = components.controller;
18478
+ const originalHost = routing.forHost, originalComposer = routing.forComposer, originalDispose = routing.dispose;
18479
+ controller.dispose();
18480
+ let replacement;
18481
+ try {
18482
+ replacement = components.createController(components.scope, adapted.service);
18483
+ } catch (error51) {
18484
+ replacement = components.createController(
18485
+ components.scope,
18486
+ components.services.appServerManagers
18487
+ );
18488
+ throw error51;
18489
+ } finally {
18490
+ adapted.service[Symbol.dispose]();
18491
+ controller.forHost = (hostId2) => replacement.forHost(hostId2);
18492
+ controller.collectAppStateSnapshot = (hostId2, options) => replacement.collectAppStateSnapshot(hostId2, options);
18493
+ controller.getReviewPaneSnapshotMetrics = (hostId2) => replacement.getReviewPaneSnapshotMetrics(hostId2);
18494
+ controller.dispose = () => replacement.dispose();
18495
+ }
18496
+ const forHost = (hostId2) => {
18497
+ const route = adapted.route(hostId2);
18498
+ return route === void 0 ? originalHost.call(routing, hostId2) : route;
18499
+ };
18500
+ const forComposer = (composer) => {
18501
+ const hostId2 = routing.hostIdForComposer(composer);
18502
+ return hostId2 ? forHost(hostId2) : originalComposer.call(routing, composer);
18503
+ };
18504
+ routing.forHost = forHost;
18505
+ routing.forComposer = forComposer;
18506
+ const installation = {
18507
+ dispose() {
18508
+ if (target.__codexhostNativeRpcRemoteControlV1 !== installation) return;
18509
+ delete target.__codexhostNativeRpcRemoteControlV1;
18510
+ replacement.dispose();
18511
+ replacement = components.createController(
18512
+ components.scope,
18513
+ components.services.appServerManagers
18514
+ );
18515
+ if (routing.forHost === forHost) routing.forHost = originalHost;
18516
+ if (routing.forComposer === forComposer) routing.forComposer = originalComposer;
18517
+ routing.dispose = originalDispose;
18518
+ }
18519
+ };
18520
+ routing.dispose = () => {
18521
+ installation.dispose();
18522
+ originalDispose.call(routing);
18523
+ };
18524
+ target.__codexhostNativeRpcRemoteControlV1 = installation;
18525
+ return true;
18526
+ }
18527
+
18528
+ // packages/desktop-control/src/renderer-native-remote-manager.ts
18529
+ function createNativeRemoteManager(components, hostId2, original, target, createPolicy, createChannel, retainInteractions) {
18530
+ const source = components.scope.get(components.requestDefinition, hostId2);
18531
+ const upstream = original.dup();
18532
+ let manager;
18533
+ let policy;
18534
+ let interactions;
18535
+ let disposed = false;
18536
+ const pending = /* @__PURE__ */ new Set();
18537
+ const send = (method, params, options) => {
18538
+ const request = upstream.sendRequest(method, params, options);
18539
+ const result = Promise.resolve(request).finally(() => {
18540
+ request[Symbol.dispose]();
18541
+ pending.delete(result);
18542
+ });
18543
+ pending.add(result);
18544
+ return result;
18545
+ };
18546
+ const record3 = (value) => value !== null && typeof value === "object";
18547
+ const dispatch = (type, payload) => {
18548
+ if ((type === "mcp-request" || type === "thread-prewarm-start") && record3(payload) && record3(payload.request)) {
18549
+ const request = payload.request;
18550
+ const options = {};
18551
+ for (const key of ["priority", "timeoutMs", "source", "trace", "threadAccess"])
18552
+ if (payload[key] !== void 0) options[key] = payload[key];
18553
+ void send(String(request.method), request.params, options).then(
18554
+ (result) => {
18555
+ if (!disposed) client.onResult(request.id, result);
18556
+ },
18557
+ (error51) => {
18558
+ if (!disposed)
18559
+ client.onError(request.id, {
18560
+ code: record3(error51) ? error51.jsonRpcCode ?? error51.code ?? -32603 : -32603,
18561
+ message: error51 instanceof Error ? error51.message : String(error51)
18562
+ });
18563
+ }
18564
+ );
18565
+ return;
18566
+ }
18567
+ return source.dispatchMessage(type, payload);
18568
+ };
18569
+ const Constructor = source.constructor;
18570
+ let client;
18571
+ try {
18572
+ client = new Constructor(
18573
+ hostId2,
18574
+ dispatch,
18575
+ false,
18576
+ (id) => manager?.getConversation(id)?.threadAccess
18577
+ );
18578
+ client.setAppServerVersion(source.getAppServerVersion());
18579
+ manager = components.createManager(
18580
+ components.scope,
18581
+ hostId2,
18582
+ client,
18583
+ components.isHostForConversation.bind(null, components.scope),
18584
+ (get, id) => get(components.imageDefinition, id),
18585
+ { dispatchMessageFromView: dispatch }
18586
+ );
18587
+ manager.dispatchAppServerResponse = manager.sendAppServerResponse;
18588
+ const owned = manager;
18589
+ const ownedPolicy = createPolicy(
18590
+ owned,
18591
+ client,
18592
+ hostId2,
18593
+ target,
18594
+ owned.prewarmedThreadManager,
18595
+ () => !disposed,
18596
+ void 0,
18597
+ void 0,
18598
+ (method, params) => send(method, params, { priority: "critical" })
18599
+ );
18600
+ policy = ownedPolicy;
18601
+ owned.sendAppServerResponse = (...args) => owned.dispatchAppServerResponse(...args);
18602
+ const channel = createChannel(components, owned);
18603
+ const nativeInteractions = retainInteractions(upstream, owned, hostId2);
18604
+ interactions = nativeInteractions;
18605
+ const notify = (event) => {
18606
+ const { data, source: source2, origin } = event;
18607
+ if (disposed || source2 != null && source2 !== target || !record3(data) || data.hostId !== hostId2)
18608
+ return;
18609
+ const ownOrigin = record3(target.location) ? target.location.origin : void 0;
18610
+ if (source2 === target && ownOrigin && ownOrigin !== "null" && origin !== ownOrigin) return;
18611
+ if (data.type === "mcp-notification" && typeof data.method === "string" && !data.method.startsWith("process/"))
18612
+ owned.onNotification(data.method, data.params);
18613
+ if (data.type === "mcp-request") owned.onRequest(record3(data.request) ? data.request : data);
18614
+ };
18615
+ target.addEventListener?.("message", notify);
18616
+ return {
18617
+ route: { hostId: hostId2, manager: owned, policy: ownedPolicy },
18618
+ rpc: channel.rpc,
18619
+ ready: nativeInteractions.ready,
18620
+ dispose() {
18621
+ if (disposed) return;
18622
+ disposed = true;
18623
+ target.removeEventListener?.("message", notify);
18624
+ nativeInteractions.dispose();
18625
+ ownedPolicy.dispose();
18626
+ client.queuedRequests.length = 0;
18627
+ for (const id of [...client.requestPromises.keys()])
18628
+ client.onError(id, new Error("Remote Control connection retired"));
18629
+ channel.dispose();
18630
+ components.Manager.dispose(owned);
18631
+ void Promise.allSettled([...pending]).then(() => upstream[Symbol.dispose]());
18632
+ }
18633
+ };
18634
+ } catch (error51) {
18635
+ interactions?.dispose();
18636
+ policy?.dispose();
18637
+ if (manager) components.Manager.dispose(manager);
18638
+ upstream[Symbol.dispose]();
18639
+ throw error51;
18640
+ }
18641
+ }
18642
+
18643
+ // packages/desktop-control/src/renderer-native-rpc-channel.ts
18644
+ function createNativeRpcChannel(components, manager) {
18645
+ const channel = new MessageChannel();
18646
+ const transports = [];
18647
+ const transport = (port) => {
18648
+ const values = [];
18649
+ const readers = [];
18650
+ let closed = false;
18651
+ let failure;
18652
+ port.addEventListener("message", (event) => {
18653
+ const value = JSON.stringify(event.data);
18654
+ const reader = readers.shift();
18655
+ if (reader) reader.resolve(value);
18656
+ else values.push(value);
18657
+ });
18658
+ port.start();
18659
+ const result = {
18660
+ send(message) {
18661
+ if (closed) throw failure;
18662
+ port.postMessage(JSON.parse(message));
18663
+ },
18664
+ receive() {
18665
+ if (closed) return Promise.reject(failure);
18666
+ const value = values.shift();
18667
+ return value !== void 0 ? Promise.resolve(value) : new Promise((resolve, reject) => readers.push({ resolve, reject }));
18668
+ },
18669
+ abort(error51) {
18670
+ if (closed) return;
18671
+ closed = true;
18672
+ failure = error51 ?? new Error("Remote Control RPC manager retired");
18673
+ values.length = 0;
18674
+ for (const reader of readers.splice(0)) reader.reject(failure);
18675
+ port.close();
18676
+ }
18677
+ };
18678
+ transports.push(result);
18679
+ return result;
18680
+ };
18681
+ try {
18682
+ new components.RpcSession(transport(channel.port1), new components.RpcManager(() => manager));
18683
+ const session = new components.RpcSession(transport(channel.port2));
18684
+ const rpc = session.getRemoteMain();
18685
+ return {
18686
+ rpc,
18687
+ dispose() {
18688
+ rpc[Symbol.dispose]();
18689
+ for (const transport2 of transports) transport2.abort();
18690
+ }
18691
+ };
18692
+ } catch (error51) {
18693
+ for (const transport2 of transports) transport2.abort(error51);
18694
+ channel.port1.close();
18695
+ channel.port2.close();
18696
+ throw error51;
18697
+ }
18698
+ }
18699
+
18700
+ // packages/desktop-control/src/renderer-native-rpc-service.ts
18701
+ function createNativeRpcService(components, createRemote) {
18702
+ const source = components.services.appServerManagers.dup();
18703
+ const routes = /* @__PURE__ */ new Map();
18704
+ const subscriptions = /* @__PURE__ */ new Set();
18705
+ let refs = 1;
18706
+ const record3 = (value) => value !== null && typeof value === "object";
18707
+ const connectionSignals = (hostId2) => {
18708
+ let node = components.scope.node;
18709
+ const seen = /* @__PURE__ */ new Set();
18710
+ while (node.parent && !seen.has(node.parent) && seen.size < 100) {
18711
+ seen.add(node);
18712
+ node = node.parent;
18713
+ }
18714
+ const found = [];
18715
+ for (const members of node.familyBindings.values()) {
18716
+ const value = members.get(hostId2)?.value;
18717
+ if (record3(value) && Object.hasOwn(value, "state$") && Object.hasOwn(value, "revision$") && Object.hasOwn(value, "appServerVersion$"))
18718
+ found.push({ state$: value.state$, revision$: value.revision$ });
18719
+ }
18720
+ return found.length === 1 ? found[0] : void 0;
18721
+ };
18722
+ const service = {
18723
+ dup() {
18724
+ refs++;
18725
+ return service;
18726
+ },
18727
+ onRpcBroken(listener) {
18728
+ source.onRpcBroken(listener);
18729
+ },
18730
+ openAccount(hostId2) {
18731
+ return source.openAccount(hostId2);
18732
+ },
18733
+ subscribe(hostId2, listener) {
18734
+ if (!hostId2.startsWith("remote-control:")) return source.subscribe(hostId2, listener);
18735
+ let active = true;
18736
+ let generation = 0;
18737
+ let upstream;
18738
+ let platformRequest;
18739
+ let remote;
18740
+ let stopWatch;
18741
+ let previousRevision;
18742
+ let previousState;
18743
+ const retire = () => {
18744
+ generation++;
18745
+ platformRequest?.[Symbol.dispose]();
18746
+ platformRequest = void 0;
18747
+ remote?.dispose();
18748
+ remote = void 0;
18749
+ routes.set(hostId2, null);
18750
+ };
18751
+ const cleanup = () => {
18752
+ if (!active) return;
18753
+ active = false;
18754
+ stopWatch?.();
18755
+ retire();
18756
+ upstream?.[Symbol.dispose]();
18757
+ upstream = void 0;
18758
+ routes.delete(hostId2);
18759
+ subscriptions.delete(cleanup);
18760
+ };
18761
+ subscriptions.add(cleanup);
18762
+ const publish = async () => {
18763
+ const owner = upstream;
18764
+ const current = generation;
18765
+ if (!owner || !active) return;
18766
+ let request;
18767
+ try {
18768
+ request = owner.getCodexHome();
18769
+ platformRequest = request;
18770
+ const home = await request;
18771
+ if (!active || current !== generation || owner !== upstream) return;
18772
+ if (!/^(?:[A-Za-z]:[\\/]|\\\\)/u.test(home)) {
18773
+ routes.delete(hostId2);
18774
+ listener({ status: "ready", manager: owner });
18775
+ return;
18776
+ }
18777
+ const created = createRemote(hostId2, owner);
18778
+ remote = created;
18779
+ await created.ready;
18780
+ if (!active || current !== generation || owner !== upstream) return;
18781
+ routes.set(hostId2, created.route);
18782
+ listener({ status: "ready", manager: created.rpc });
18783
+ } catch {
18784
+ if (active && current === generation) {
18785
+ remote?.dispose();
18786
+ remote = void 0;
18787
+ routes.delete(hostId2);
18788
+ listener({ status: "ready", manager: owner });
18789
+ }
18790
+ } finally {
18791
+ if (platformRequest === request) {
18792
+ platformRequest = void 0;
18793
+ request?.[Symbol.dispose]();
18794
+ }
18795
+ }
18796
+ };
18797
+ const changed = (state) => {
18798
+ if (!active) return;
18799
+ stopWatch?.();
18800
+ stopWatch = void 0;
18801
+ retire();
18802
+ upstream?.[Symbol.dispose]();
18803
+ upstream = void 0;
18804
+ if (state.status !== "ready") {
18805
+ listener(state);
18806
+ return;
18807
+ }
18808
+ upstream = state.manager.dup();
18809
+ listener({ status: "connecting" });
18810
+ const signals = connectionSignals(hostId2);
18811
+ if (!signals) {
18812
+ void publish();
18813
+ return;
18814
+ }
18815
+ previousState = void 0;
18816
+ previousRevision = void 0;
18817
+ stopWatch = components.scope.watch(({ get }) => {
18818
+ const connection = get(signals.state$), revision = get(signals.revision$);
18819
+ if (connection === previousState && revision === previousRevision) return;
18820
+ previousState = connection;
18821
+ previousRevision = revision;
18822
+ retire();
18823
+ listener({ status: connection === "connected" ? "connecting" : "disconnected" });
18824
+ if (connection === "connected") void publish();
18825
+ });
18826
+ };
18827
+ const original = source.subscribe(hostId2, changed);
18828
+ const result = original.then((lease) => {
18829
+ if (!active) lease[Symbol.dispose]();
18830
+ return {
18831
+ onRpcBroken: (listener2) => lease.onRpcBroken(listener2),
18832
+ [Symbol.dispose]() {
18833
+ cleanup();
18834
+ lease[Symbol.dispose]();
18835
+ }
18836
+ };
18837
+ });
18838
+ Object.assign(result, {
18839
+ onRpcBroken: (listener2) => original.onRpcBroken(listener2),
18840
+ [Symbol.dispose]() {
18841
+ cleanup();
18842
+ original[Symbol.dispose]();
18843
+ }
18844
+ });
18845
+ return result;
18846
+ },
18847
+ [Symbol.dispose]() {
18848
+ if (--refs !== 0) return;
18849
+ for (const cleanup of [...subscriptions]) cleanup();
18850
+ source[Symbol.dispose]();
18851
+ }
18852
+ };
18853
+ return { service, route: (hostId2) => routes.get(hostId2) };
18854
+ }
18855
+
18856
+ // packages/desktop-control/src/renderer-native-rpc-interactions.ts
18857
+ function retainNativeRpcInteractions(upstream, manager, hostId2) {
18858
+ let disposed = false;
18859
+ const retained = /* @__PURE__ */ new Set();
18860
+ const requests = /* @__PURE__ */ new Map();
18861
+ const reads = /* @__PURE__ */ new Map();
18862
+ const record3 = (value) => value !== null && typeof value === "object";
18863
+ const read = (threadId) => {
18864
+ const existing = reads.get(threadId);
18865
+ if (existing) {
18866
+ existing.dirty = true;
18867
+ return existing.promise;
18868
+ }
18869
+ const entry = { promise: Promise.resolve(), dirty: false };
18870
+ reads.set(threadId, entry);
18871
+ entry.promise = Promise.resolve().then(async () => {
18872
+ do {
18873
+ if (disposed) break;
18874
+ entry.dirty = false;
18875
+ const pending = upstream.getConversation(threadId);
18876
+ retained.add(pending);
18877
+ try {
18878
+ const conversation = await pending;
18879
+ if (disposed || entry.dirty || !record3(conversation) || !Array.isArray(conversation.requests))
18880
+ continue;
18881
+ const previous = requests.get(threadId) ?? /* @__PURE__ */ new Set();
18882
+ const next = /* @__PURE__ */ new Set();
18883
+ for (const request of conversation.requests) {
18884
+ if (!record3(request) || typeof request.method !== "string" || !record3(request.params) || (request.params.threadId ?? request.params.conversationId) !== threadId || typeof request.id !== "string" && typeof request.id !== "number")
18885
+ continue;
18886
+ next.add(request.id);
18887
+ if (!previous.has(request.id)) manager.onRequest(request);
18888
+ }
18889
+ if (next.size) requests.set(threadId, next);
18890
+ else requests.delete(threadId);
18891
+ } finally {
18892
+ if (retained.delete(pending)) pending[Symbol.dispose]();
18893
+ }
18894
+ } while (!disposed && entry.dirty);
18895
+ }).finally(() => {
18896
+ reads.delete(threadId);
18897
+ });
18898
+ return entry.promise;
18899
+ };
18900
+ const event = (value) => {
18901
+ if (disposed || !record3(value) || typeof value.conversationId !== "string") return;
18902
+ void read(value.conversationId).catch(() => void 0);
18903
+ };
18904
+ const subscribe = (input) => {
18905
+ const pending = upstream.subscribe(input);
18906
+ retained.add(pending);
18907
+ return Promise.resolve(pending).then((lease) => {
18908
+ if (disposed) lease[Symbol.dispose]();
18909
+ else retained.add(lease);
18910
+ });
18911
+ };
18912
+ const subscriptions = [
18913
+ "approval-request",
18914
+ "user-input-request",
18915
+ "mcp-elicitation-request",
18916
+ "approval-resolved"
18917
+ ].map((name) => subscribe({ type: "event", key: { hostId: hostId2 }, event: name, listener: event }));
18918
+ subscriptions.push(
18919
+ subscribe({
18920
+ type: "notification",
18921
+ key: { hostId: hostId2 },
18922
+ methods: ["serverRequest/resolved"],
18923
+ listener(value) {
18924
+ if (record3(value) && record3(value.params) && typeof value.params.threadId === "string")
18925
+ event({ conversationId: value.params.threadId });
18926
+ }
18927
+ })
18928
+ );
18929
+ const ready = Promise.all(subscriptions).then(async () => {
18930
+ if (disposed) return;
18931
+ const pending = upstream.getWorkInProgress();
18932
+ retained.add(pending);
18933
+ try {
18934
+ const work = await pending;
18935
+ if (disposed) return;
18936
+ if (!Array.isArray(work)) throw new Error("Native RPC interaction snapshot is unavailable");
18937
+ const threadIds = new Set(
18938
+ work.flatMap(
18939
+ (item) => record3(item) && typeof item.conversationId === "string" ? [item.conversationId] : []
18940
+ )
18941
+ );
18942
+ await Promise.all([...threadIds].map(read));
18943
+ } finally {
18944
+ if (retained.delete(pending)) pending[Symbol.dispose]();
18945
+ }
18946
+ });
18947
+ return {
18948
+ ready,
18949
+ dispose() {
18950
+ if (disposed) return;
18951
+ disposed = true;
18952
+ for (const lease of retained) lease[Symbol.dispose]();
18953
+ retained.clear();
18954
+ requests.clear();
18955
+ }
18956
+ };
18957
+ }
18958
+
18959
+ // packages/desktop-control/src/renderer-native-rpc-install.ts
18960
+ async function installNativeRpcRemoteControlDirect(renderer) {
18961
+ let attempt;
18962
+ const probeId = crypto.randomUUID();
18963
+ try {
18964
+ attempt = await renderer.evaluate(`(() => {
18965
+ if (window.__codexhostNativeRpcRemoteControlV1) return null;
18966
+ const routing = window.__codexhostHostRoutingV1;
18967
+ const owner = routing?.forHost('local')?.manager;
18968
+ if (owner?.kind !== 'main-process-rpc') return null;
18969
+ const catalog = window.__codexhostLoadedModulesV1;
18970
+ if (!catalog?.complete) return null;
18971
+ const key = JSON.stringify([catalog.owner, catalog.urls.filter(url => /renderer-app-server-managers|app-shared/.test(url)).sort()]);
18972
+ const previous = window.__codexhostNativeRpcDiscoveryV1;
18973
+ const sameOwner = previous?.key === key && previous.owner === owner;
18974
+ if (sameOwner && (previous.state !== 'unavailable' || previous.attempts >= 3 || Date.now() < previous.nextRetryAt)) return null;
18975
+ const token = ${JSON.stringify(probeId)};
18976
+ window.__codexhostNativeRpcDiscoveryV1 = {
18977
+ key, owner, token, state: 'discovering', attempts: sameOwner ? previous.attempts + 1 : 1,
18978
+ };
18979
+ return token;
18980
+ })()`);
18981
+ } catch {
18982
+ return false;
18983
+ }
18984
+ if (attempt === null) return false;
18985
+ let installed = false;
18986
+ try {
18987
+ installed = await withNativeRpcComponents(renderer, async (objectId) => {
18988
+ const result = await renderer.command("Runtime.callFunctionOn", {
18989
+ objectId,
18990
+ functionDeclaration: `function() {
18991
+ if (this.document !== document) return false;
18992
+ const retainRendererHostResponses = ${retainRendererHostResponses.toString()};
18993
+ const isolateRendererPrewarmConsumption = ${isolateRendererPrewarmConsumption.toString()};
18994
+ return (${installNativeRpcRemoteControl.toString()})(this, window, {
18995
+ createPolicy: ${createDraftPrewarmPolicyBridge.toString()},
18996
+ createManager: ${createNativeRemoteManager.toString()},
18997
+ createChannel: ${createNativeRpcChannel.toString()},
18998
+ createService: ${createNativeRpcService.toString()},
18999
+ retainInteractions: ${retainNativeRpcInteractions.toString()},
19000
+ });
19001
+ }`,
19002
+ returnByValue: true
19003
+ });
19004
+ return !result.exceptionDetails && result.result?.value === true;
19005
+ });
19006
+ return installed;
19007
+ } catch {
19008
+ return false;
19009
+ } finally {
19010
+ await renderer.evaluate(
19011
+ `(() => {
19012
+ const status = window.__codexhostNativeRpcDiscoveryV1;
19013
+ if (status?.token === ${JSON.stringify(attempt)}) {
19014
+ status.state = ${JSON.stringify(installed ? "ready" : "unavailable")};
19015
+ status.nextRetryAt = Date.now() + 5000 * 2 ** (status.attempts - 1);
19016
+ }
19017
+ })()`
19018
+ ).catch(() => void 0);
19019
+ }
19020
+ }
19021
+
18148
19022
  // packages/desktop-control/src/renderer-cdp-control-session.ts
18149
19023
  function isRecord2(value) {
18150
19024
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -18402,7 +19276,11 @@ var InstalledRendererCdpControlSession = class {
18402
19276
  var defaultOperations = {
18403
19277
  listTargets: (endpoint, signal) => listCdpTargets(endpoint, fetch, signal),
18404
19278
  connect: (webSocketDebuggerUrl) => CdpClient.connect(webSocketDebuggerUrl),
18405
- installDraftPrewarmPolicy: installRendererDraftPrewarmPolicyDirect
19279
+ async installDraftPrewarmPolicy(renderer) {
19280
+ const status = await installRendererDraftPrewarmPolicyDirect(renderer);
19281
+ await installNativeRpcRemoteControlDirect(renderer);
19282
+ return status;
19283
+ }
18406
19284
  };
18407
19285
  async function createRendererCdpControlSession(options) {
18408
19286
  const enabledAgents = options.enabledAgents;