@codexhost/cli-darwin-x64 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +2 -2
  2. package/THIRD_PARTY_NOTICES.txt +6 -2
  3. package/app/codexhost-distribution.json +1 -1
  4. package/app/console-server.mjs +59 -21
  5. package/app/console-web.js +49 -18
  6. package/app/desktop-controller.mjs +554 -34
  7. package/app/host-runtime.mjs +3436 -1846
  8. package/app/plugins/antigravity/plugin.mjs +39 -3
  9. package/app/plugins/claude-code/plugin.mjs +16 -7
  10. package/app/plugins/codebuddy/plugin.mjs +14 -1
  11. package/app/plugins/codex-usage/plugin.mjs +4 -1
  12. package/app/plugins/copilot/plugin.mjs +4 -1
  13. package/app/plugins/cursor-cli/plugin.mjs +13 -6
  14. package/app/plugins/deepseek-harness/plugin.mjs +463 -47
  15. package/app/plugins/devin/assets/icon.svg +1 -0
  16. package/app/plugins/devin/manifest.json +30 -0
  17. package/app/plugins/devin/plugin.mjs +23363 -0
  18. package/app/plugins/enabled.json +2 -0
  19. package/app/plugins/grok/plugin.mjs +476 -392
  20. package/app/plugins/hermes/plugin.mjs +457 -197
  21. package/app/plugins/kimi-code/plugin.mjs +4 -1
  22. package/app/plugins/kiro-cli/plugin.mjs +4 -1
  23. package/app/plugins/omp/plugin.mjs +4 -1
  24. package/app/plugins/opencode/plugin.mjs +4 -1
  25. package/app/plugins/pi/plugin.mjs +1464 -412
  26. package/app/plugins/qoder/plugin.mjs +9528 -8655
  27. package/app/plugins/qoder-cn/plugin.mjs +9528 -8655
  28. package/app/plugins/qwen-code/assets/icon.svg +1 -0
  29. package/app/plugins/qwen-code/manifest.json +29 -0
  30. package/app/plugins/qwen-code/plugin.mjs +29298 -0
  31. package/app/plugins/workbuddy/plugin.mjs +14 -1
  32. package/app/plugins/zcode/plugin.mjs +4 -1
  33. package/app/renderer-extension.js +510 -114
  34. package/bin/codexhost +0 -0
  35. package/libexec/codexhost-shim +0 -0
  36. package/libexec/codexhost-updater +0 -0
  37. package/licenses/Qwen-Code-SDK-LICENSE.txt +203 -0
  38. package/package.json +2 -2
@@ -227,13 +227,32 @@ var CdpClient = class _CdpClient {
227
227
  returnByValue: true
228
228
  });
229
229
  if (!isRecord(response)) throw new Error("Runtime.evaluate returned an invalid result");
230
- if (isRecord(response.exceptionDetails)) {
231
- throw new Error(cdpExceptionMessage(response.exceptionDetails, "Renderer evaluation failed"));
232
- }
233
- if (!isRecord(response.result) || !("value" in response.result)) {
234
- throw new Error("Runtime.evaluate did not return a value");
230
+ try {
231
+ if (isRecord(response.exceptionDetails)) {
232
+ throw new Error(
233
+ cdpExceptionMessage(response.exceptionDetails, "Renderer evaluation failed")
234
+ );
235
+ }
236
+ if (!isRecord(response.result) || !("value" in response.result)) {
237
+ throw new Error("Runtime.evaluate did not return a value");
238
+ }
239
+ return response.result.value;
240
+ } finally {
241
+ const objects = [
242
+ response.result,
243
+ isRecord(response.exceptionDetails) ? response.exceptionDetails.exception : void 0
244
+ ];
245
+ const ids = new Set(
246
+ objects.flatMap(
247
+ (object2) => isRecord(object2) && typeof object2.objectId === "string" ? [object2.objectId] : []
248
+ )
249
+ );
250
+ await Promise.all(
251
+ [...ids].map(
252
+ (objectId) => this.command("Runtime.releaseObject", { objectId }).catch(() => void 0)
253
+ )
254
+ );
235
255
  }
236
- return response.result.value;
237
256
  }
238
257
  close() {
239
258
  if (this.#closed) return;
@@ -15840,7 +15859,10 @@ var harnessPluginRouteSchema = external_exports.object({
15840
15859
  harnessId: harnessPluginIdSchema,
15841
15860
  model: harnessModelRefSchema.optional(),
15842
15861
  thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
15843
- permissionModeId: harnessPermissionModeIdSchema.optional()
15862
+ permissionModeId: harnessPermissionModeIdSchema.optional(),
15863
+ /** A draft prewarm create: stays unsubmitted until the user's first Turn.
15864
+ * Desktop forwards only the Model of a main-process prewarm to thread/start. */
15865
+ prewarm: external_exports.literal(true).optional()
15844
15866
  }).strict();
15845
15867
 
15846
15868
  // packages/shared-contracts/dist/harness-launch-settings.js
@@ -16706,20 +16728,20 @@ function retainRendererHostResponses(client, hostId2, target) {
16706
16728
 
16707
16729
  // packages/desktop-control/src/renderer-prewarm-consumption.ts
16708
16730
  function isolateRendererPrewarmConsumption(manager, discardExternal) {
16709
- const record2 = (value) => value !== null && typeof value === "object";
16710
- if (!record2(manager) || !record2(manager.threadCreation)) return null;
16731
+ const record3 = (value) => value !== null && typeof value === "object";
16732
+ if (!record3(manager) || !record3(manager.threadCreation)) return null;
16711
16733
  const creation = manager.threadCreation;
16712
16734
  const originalStart = manager.startConversation;
16713
16735
  const original = creation.createConversation;
16714
16736
  const params = creation.params;
16715
- if (typeof originalStart !== "function" || typeof original !== "function" || !record2(params))
16737
+ if (typeof originalStart !== "function" || typeof original !== "function" || !record3(params))
16716
16738
  return null;
16717
16739
  const prototype = Object.getPrototypeOf(creation);
16718
- if (!record2(prototype) || typeof prototype.constructor !== "function") return null;
16740
+ if (!record3(prototype) || typeof prototype.constructor !== "function") return null;
16719
16741
  if (Object.keys(creation).some((key) => key !== "params" && typeof creation[key] !== "function") || /#[A-Za-z_$]/u.test(Function.prototype.toString.call(prototype.constructor)))
16720
16742
  return null;
16721
16743
  const pool = params.prewarmedThreadManager;
16722
- if (!record2(pool) || typeof pool.hasPrewarmedThread !== "function" || typeof pool.consumePrewarmedThread !== "function" || typeof pool.deletePrewarmedThread !== "function")
16744
+ if (!record3(pool) || typeof pool.hasPrewarmedThread !== "function" || typeof pool.consumePrewarmedThread !== "function" || typeof pool.deletePrewarmedThread !== "function")
16723
16745
  return null;
16724
16746
  const consume = pool.consumePrewarmedThread;
16725
16747
  const hasPrewarm = pool.hasPrewarmedThread;
@@ -16727,14 +16749,14 @@ function isolateRendererPrewarmConsumption(manager, discardExternal) {
16727
16749
  const draftIdentity = /* @__PURE__ */ Symbol("codexhost draft creation");
16728
16750
  const external = (model2) => typeof model2 === "string" && model2.startsWith("codexhost/");
16729
16751
  const routedStart = function(input, options, ...args) {
16730
- const draftId = record2(options) ? options.clientThreadId : null;
16731
- const mode = record2(input) && record2(input.collaborationMode) ? input.collaborationMode : null;
16752
+ const draftId = record3(options) ? options.clientThreadId : null;
16753
+ const mode = record3(input) && record3(input.collaborationMode) ? input.collaborationMode : null;
16732
16754
  const origin = mode ? Reflect.get(mode, draftIdentity) : void 0;
16733
- if (mode && record2(mode.settings) && external(mode.settings.model))
16755
+ if (mode && record3(mode.settings) && external(mode.settings.model))
16734
16756
  return originalStart.call(this, input, options, ...args);
16735
16757
  const model2 = (typeof draftId === "string" ? draftModels.get(draftId) : void 0) ?? (typeof origin === "string" ? draftModels.get(origin) : void 0);
16736
16758
  if (!model2) return originalStart.call(this, input, options, ...args);
16737
- if (!record2(input) || !record2(input.collaborationMode) || !record2(input.collaborationMode.settings))
16759
+ if (!record3(input) || !record3(input.collaborationMode) || !record3(input.collaborationMode.settings))
16738
16760
  throw new Error("External draft creation is missing its native Model settings");
16739
16761
  const routed = {
16740
16762
  ...input,
@@ -16746,17 +16768,17 @@ function isolateRendererPrewarmConsumption(manager, discardExternal) {
16746
16768
  return originalStart.call(this, routed, options, ...args);
16747
16769
  };
16748
16770
  const wrapped = function(input, ...args) {
16749
- const mode = record2(input) && record2(input.collaborationMode) ? input.collaborationMode : null;
16750
- const expected = mode && record2(mode.settings) ? mode.settings.model : null;
16771
+ const mode = record3(input) && record3(input.collaborationMode) ? input.collaborationMode : null;
16772
+ const expected = mode && record3(mode.settings) ? mode.settings.model : null;
16751
16773
  const scopedPool = Object.create(pool);
16752
16774
  scopedPool.hasPrewarmedThread = (...parameters) => hasPrewarm.apply(pool, parameters);
16753
16775
  scopedPool.consumePrewarmedThread = async (...consumeArgs) => {
16754
16776
  const warmed = await consume.apply(pool, consumeArgs);
16755
- if (!record2(warmed) || !record2(warmed.response)) return warmed;
16777
+ if (!record3(warmed) || !record3(warmed.response)) return warmed;
16756
16778
  const response = warmed.response;
16757
16779
  if (!external(expected) && !external(response.model)) return warmed;
16758
16780
  if (external(expected) && expected === response.model) return warmed;
16759
- if (record2(response.thread) && typeof response.thread.id === "string") {
16781
+ if (record3(response.thread) && typeof response.thread.id === "string") {
16760
16782
  const threadId = response.thread.id;
16761
16783
  if (external(response.model)) discardExternal(threadId);
16762
16784
  else
@@ -17361,14 +17383,14 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
17361
17383
 
17362
17384
  // packages/desktop-control/src/renderer-host-discovery.ts
17363
17385
  function requestManagerFromHookState(value, hostId2) {
17364
- const record2 = (candidate) => typeof candidate === "object" && candidate !== null;
17386
+ const record3 = (candidate) => typeof candidate === "object" && candidate !== null;
17365
17387
  const manager = (candidate) => {
17366
- if (!record2(candidate) || !record2(candidate.requestClient) || !record2(candidate.prewarmedThreadManager))
17388
+ if (!record3(candidate) || !record3(candidate.requestClient) || !record3(candidate.prewarmedThreadManager))
17367
17389
  return null;
17368
17390
  const bridge = candidate.requestClient;
17369
17391
  return typeof candidate.sendRequest === "function" && typeof bridge.sendRequest === "function" && typeof bridge.prewarmThreadStart === "function" && typeof bridge.enqueueRequest === "function" && typeof candidate.prewarmedThreadManager.discardAllPrewarmedThreads === "function" ? candidate : null;
17370
17392
  };
17371
- if (!record2(value)) return null;
17393
+ if (!record3(value)) return null;
17372
17394
  const direct = manager(value) ?? manager(value.manager);
17373
17395
  if (direct) return direct;
17374
17396
  if (!hostId2 || typeof value.addManager !== "function" || typeof value.getForHostId !== "function")
@@ -17578,6 +17600,339 @@ function installRendererHostRouting(root, target, discover, resolve, createPolic
17578
17600
  return routing;
17579
17601
  }
17580
17602
 
17603
+ // packages/desktop-control/src/renderer-host-rpc-discovery.ts
17604
+ function findRendererAppScopeStore(root) {
17605
+ const MAX_VISITED_FIBERS = 5e4;
17606
+ const record3 = (value) => typeof value === "object" && value !== null;
17607
+ const container = root.getElementById?.("root");
17608
+ if (!record3(container)) return null;
17609
+ const key = Object.getOwnPropertyNames(container).find(
17610
+ (name) => name.startsWith("__reactContainer$")
17611
+ );
17612
+ const first = key ? container[key] : null;
17613
+ if (!record3(first)) return null;
17614
+ const isScopeHandle = (value) => record3(value) && record3(value.node) && "chain" in value && "scope" in value && typeof value.get === "function" && typeof value.set === "function" && typeof value.watch === "function";
17615
+ const stack = [first];
17616
+ const seen = /* @__PURE__ */ new Set();
17617
+ while (stack.length && seen.size < MAX_VISITED_FIBERS) {
17618
+ const fiber = stack.pop();
17619
+ if (seen.has(fiber)) continue;
17620
+ seen.add(fiber);
17621
+ let hook = fiber.memoizedState;
17622
+ for (let index = 0; record3(hook) && "next" in hook && index < 150; index += 1) {
17623
+ const state = hook.memoizedState;
17624
+ const handle = record3(state) ? state.current : null;
17625
+ if (isScopeHandle(handle)) {
17626
+ let node = handle.node;
17627
+ const nodes = /* @__PURE__ */ new Set();
17628
+ while (record3(node.parent) && !nodes.has(node.parent)) {
17629
+ nodes.add(node);
17630
+ node = node.parent;
17631
+ }
17632
+ const bindings = node.familyBindings;
17633
+ return record3(bindings) && typeof bindings.get === "function" && typeof bindings.entries === "function" ? node : null;
17634
+ }
17635
+ hook = hook.next;
17636
+ }
17637
+ if (record3(fiber.sibling)) stack.push(fiber.sibling);
17638
+ if (record3(fiber.child)) stack.push(fiber.child);
17639
+ }
17640
+ return null;
17641
+ }
17642
+ function findRendererHostRpcFamily(store) {
17643
+ const record3 = (value) => typeof value === "object" && value !== null;
17644
+ const families = /* @__PURE__ */ new Set();
17645
+ for (const [definition, members] of store.familyBindings) {
17646
+ if (!record3(definition) || definition.kind !== "signal-family") continue;
17647
+ if (!record3(members) || typeof members.get !== "function") continue;
17648
+ for (const [hostId2, member] of members) {
17649
+ if (typeof hostId2 !== "string" || !record3(member)) continue;
17650
+ const signal = member.value;
17651
+ if (!record3(signal) || typeof signal.get !== "function") continue;
17652
+ let value;
17653
+ try {
17654
+ value = signal.get();
17655
+ } catch {
17656
+ continue;
17657
+ }
17658
+ if (record3(value) && Object.keys(value).length === 2 && typeof value.status === "string" && record3(value.client) && value.client.hostId === hostId2 && "rpc" in value.client) {
17659
+ families.add(members);
17660
+ break;
17661
+ }
17662
+ }
17663
+ }
17664
+ if (families.size !== 1) return null;
17665
+ return { store, family: families.values().next().value };
17666
+ }
17667
+ function resolveRendererHostRpc(discovery, hostId2) {
17668
+ const record3 = (value2) => typeof value2 === "object" && value2 !== null;
17669
+ const signal = discovery.family.get(hostId2)?.value;
17670
+ if (!record3(signal) || typeof signal.get !== "function") return null;
17671
+ let value;
17672
+ try {
17673
+ value = signal.get();
17674
+ } catch {
17675
+ return null;
17676
+ }
17677
+ if (!record3(value) || value.status !== "ready" || !record3(value.client) || value.client.hostId !== hostId2)
17678
+ return null;
17679
+ const rpc = value.client.rpc;
17680
+ return typeof rpc === "function" || record3(rpc) ? rpc : null;
17681
+ }
17682
+ function rendererHostRpcHostIds(discovery) {
17683
+ return [...discovery.family.keys()].filter(
17684
+ (hostId2) => typeof hostId2 === "string"
17685
+ );
17686
+ }
17687
+
17688
+ // packages/desktop-control/src/renderer-host-rpc-routing.ts
17689
+ function installRendererHostRpcRouting(root, target, dependencies) {
17690
+ const existing = target.__codexhostHostRoutingV1;
17691
+ if (existing) return existing;
17692
+ let disposed = false;
17693
+ let discovery = null;
17694
+ const routes = /* @__PURE__ */ new Map();
17695
+ const read = () => {
17696
+ if (disposed) return null;
17697
+ if (!discovery) {
17698
+ const store = dependencies.findStore(root);
17699
+ discovery = store ? dependencies.findFamily(store) : null;
17700
+ }
17701
+ return discovery;
17702
+ };
17703
+ if (!read()) return null;
17704
+ const isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
17705
+ const externalDrafts = /* @__PURE__ */ new Map();
17706
+ const selectedModels = /* @__PURE__ */ new Map();
17707
+ const prewarmCarrier = (carrier) => {
17708
+ const prefix = "codexhost/plugin-v1@";
17709
+ if (!carrier.startsWith(prefix)) return null;
17710
+ try {
17711
+ const json2 = carrier.slice(prefix.length).replace(/[a-f0-9]{2}/gu, (byte) => String.fromCharCode(Number.parseInt(byte, 16)));
17712
+ const route = JSON.parse(json2);
17713
+ if (!isRecord3(route)) return null;
17714
+ const payload = [...JSON.stringify({ ...route, prewarm: true })].map((character) => character.charCodeAt(0).toString(16).padStart(2, "0")).join("");
17715
+ return `${prefix}${payload}`;
17716
+ } catch {
17717
+ return null;
17718
+ }
17719
+ };
17720
+ const publishDraftWorkspace = (hostId2, cwd) => {
17721
+ if (typeof cwd !== "string" || cwd.length === 0) return;
17722
+ const drafts = isRecord3(target.__codexhostDraftWorkspacesV1) ? target.__codexhostDraftWorkspacesV1 : {};
17723
+ if (drafts[hostId2] === cwd) return;
17724
+ drafts[hostId2] = cwd;
17725
+ Object.defineProperty(target, "__codexhostDraftWorkspacesV1", {
17726
+ configurable: true,
17727
+ value: drafts
17728
+ });
17729
+ if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function") {
17730
+ target.dispatchEvent(
17731
+ new CustomEvent("codexhost:draft-workspace", { detail: { hostId: hostId2, cwd } })
17732
+ );
17733
+ }
17734
+ };
17735
+ const routeCreationCall = (message) => {
17736
+ if (!Array.isArray(message) || message.length !== 2 || message[0] !== "push") return message;
17737
+ const expression = message[1];
17738
+ if (!Array.isArray(expression) || expression.length !== 4 || expression[0] !== "pipeline")
17739
+ return message;
17740
+ const [, importId, path3, args] = expression;
17741
+ if (!Array.isArray(path3) || path3.length !== 1 || !Array.isArray(args)) return message;
17742
+ const [input, options] = args;
17743
+ if (!isRecord3(input) || !isRecord3(input.collaborationMode)) return message;
17744
+ const settings = input.collaborationMode.settings;
17745
+ if (!isRecord3(settings)) return message;
17746
+ const nativeModel = typeof settings.model === "string" ? settings.model : null;
17747
+ let model2 = null;
17748
+ if (path3[0] === "startConversation") {
17749
+ const draftId = isRecord3(options) ? options.clientThreadId : null;
17750
+ model2 = typeof draftId === "string" ? externalDrafts.get(draftId)?.model ?? null : null;
17751
+ } else if (path3[0] === "prewarmConversation") {
17752
+ if (input.ephemeral !== true) publishDraftWorkspace("local", input.cwd);
17753
+ const selected = selectedModels.get("local") ?? null;
17754
+ const carrier = nativeModel?.startsWith("codexhost/") ? nativeModel : selected;
17755
+ model2 = carrier ? prewarmCarrier(carrier) : null;
17756
+ }
17757
+ if (!model2) return message;
17758
+ if (path3[0] === "startConversation" && nativeModel?.startsWith("codexhost/") && nativeModel !== model2)
17759
+ return message;
17760
+ return [
17761
+ "push",
17762
+ [
17763
+ "pipeline",
17764
+ importId,
17765
+ path3,
17766
+ [
17767
+ {
17768
+ ...input,
17769
+ collaborationMode: { ...input.collaborationMode, settings: { ...settings, model: model2 } }
17770
+ },
17771
+ ...args.slice(1)
17772
+ ]
17773
+ ]
17774
+ ];
17775
+ };
17776
+ const port = dependencies.portPrototype;
17777
+ const originalPostMessage = port.postMessage;
17778
+ const postMessage = function(message, ...rest) {
17779
+ let routed = message;
17780
+ try {
17781
+ routed = disposed ? message : routeCreationCall(message);
17782
+ } catch {
17783
+ routed = message;
17784
+ }
17785
+ return originalPostMessage.call(this, routed, ...rest);
17786
+ };
17787
+ port.postMessage = postMessage;
17788
+ const createRoute = (hostId2, rpc) => {
17789
+ let retired = false;
17790
+ const isCurrent = () => !retired && !disposed && routes.get(hostId2)?.rpc === rpc;
17791
+ const manager = Object.freeze({
17792
+ kind: "main-process-rpc",
17793
+ getHostId: () => hostId2,
17794
+ sendRequest(method, params, options) {
17795
+ if (!isCurrent())
17796
+ return Promise.reject(new Error(`Renderer request manager is retired for ${hostId2}`));
17797
+ return options === void 0 ? rpc.sendRequest(method, params) : rpc.sendRequest(method, params, options);
17798
+ },
17799
+ // The main process broadcasts every app-server notification to its windows,
17800
+ // including codexhost methods Desktop's own notification table drops.
17801
+ addNotificationCallback(methods, listener) {
17802
+ const accepted = new Set(typeof methods === "string" ? [methods] : methods);
17803
+ const onMessage = (event) => {
17804
+ const { source, data } = event;
17805
+ if (source != null && source !== target) return;
17806
+ if (!isRecord3(data) || data.type !== "mcp-notification" || data.hostId !== hostId2 || typeof data.method !== "string" || !accepted.has(data.method) || !isCurrent())
17807
+ return;
17808
+ listener({ method: data.method, params: data.params });
17809
+ };
17810
+ target.addEventListener?.("message", onMessage);
17811
+ return () => target.removeEventListener?.("message", onMessage);
17812
+ }
17813
+ });
17814
+ const clearDrafts = () => {
17815
+ for (const [draftId, draft] of externalDrafts) {
17816
+ if (draft.owner === policy) externalDrafts.delete(draftId);
17817
+ }
17818
+ };
17819
+ const clear = () => isCurrent() ? Promise.resolve(rpc.clearPrewarmedThreads()).then(() => void 0) : Promise.reject(new Error("Renderer request manager is retired"));
17820
+ const policy = Object.freeze({
17821
+ state: "ready",
17822
+ hostId: hostId2,
17823
+ scopedCreation: true,
17824
+ requestTarget: () => {
17825
+ if (!isCurrent()) throw new Error("Renderer request manager is retired");
17826
+ return manager;
17827
+ },
17828
+ select(model2, draftId) {
17829
+ if (!isCurrent()) throw new Error("Renderer request manager is retired");
17830
+ if (model2 !== null && (typeof model2 !== "string" || !model2.startsWith("codexhost/"))) {
17831
+ throw new Error("Draft route Model must be a codexhost transport carrier");
17832
+ }
17833
+ if (draftId === void 0) {
17834
+ if (model2 === null) clearDrafts();
17835
+ } else if (model2 === null) {
17836
+ if (externalDrafts.get(draftId)?.owner === policy) externalDrafts.delete(draftId);
17837
+ } else {
17838
+ if (!draftId.startsWith("client-new-thread:"))
17839
+ throw new Error("External draft route is missing its client Thread identity");
17840
+ externalDrafts.set(draftId, { model: model2, owner: policy });
17841
+ }
17842
+ if ((selectedModels.get(hostId2) ?? null) === model2) return false;
17843
+ if (model2 === null) selectedModels.delete(hostId2);
17844
+ else selectedModels.set(hostId2, model2);
17845
+ void clear().catch(() => void 0);
17846
+ return true;
17847
+ },
17848
+ clear,
17849
+ dispose() {
17850
+ if (retired) return;
17851
+ retired = true;
17852
+ clearDrafts();
17853
+ selectedModels.delete(hostId2);
17854
+ }
17855
+ });
17856
+ return { hostId: hostId2, manager, policy };
17857
+ };
17858
+ const retire = (hostId2) => {
17859
+ const entry = routes.get(hostId2);
17860
+ routes.delete(hostId2);
17861
+ entry?.route.policy.dispose();
17862
+ };
17863
+ const routeFor = (hostId2) => {
17864
+ const current = read();
17865
+ const rpc = current ? dependencies.resolve(current, hostId2) : null;
17866
+ const previous = routes.get(hostId2);
17867
+ if (rpc && previous?.rpc === rpc) return previous.route;
17868
+ retire(hostId2);
17869
+ if (!rpc) return null;
17870
+ const route = createRoute(hostId2, rpc);
17871
+ routes.set(hostId2, { route, rpc });
17872
+ return route;
17873
+ };
17874
+ const publish = (route) => {
17875
+ const policy = route?.policy;
17876
+ if (target.__codexhostDraftPrewarmPolicyV1 === policy) return;
17877
+ Object.defineProperty(target, "__codexhostDraftPrewarmPolicyV1", {
17878
+ configurable: true,
17879
+ value: policy
17880
+ });
17881
+ if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function") {
17882
+ target.dispatchEvent(new CustomEvent("codexhost:draft-prewarm-policy-changed"));
17883
+ }
17884
+ };
17885
+ const composerHostId = (composer) => {
17886
+ const hostIds = new Set(dependencies.composerHostIds(composer).hostIds);
17887
+ const hostId2 = hostIds.size === 1 ? hostIds.values().next().value : null;
17888
+ return typeof hostId2 === "string" && hostId2 ? hostId2 : null;
17889
+ };
17890
+ const routing = {
17891
+ knownHostIds() {
17892
+ const current = read();
17893
+ return current ? dependencies.hostIds(current) : [];
17894
+ },
17895
+ forHost(hostId2) {
17896
+ return hostId2 && !disposed ? routeFor(hostId2) : null;
17897
+ },
17898
+ hostIdForComposer(composer) {
17899
+ if (disposed) return null;
17900
+ try {
17901
+ return composerHostId(composer);
17902
+ } catch {
17903
+ return null;
17904
+ }
17905
+ },
17906
+ forComposer(composer) {
17907
+ if (disposed) return null;
17908
+ let hostId2;
17909
+ try {
17910
+ hostId2 = composerHostId(composer);
17911
+ } catch {
17912
+ hostId2 = null;
17913
+ }
17914
+ const route = hostId2 ? routeFor(hostId2) : null;
17915
+ if (!composer) publish(route);
17916
+ return route;
17917
+ },
17918
+ dispose() {
17919
+ if (disposed) return;
17920
+ disposed = true;
17921
+ for (const hostId2 of [...routes.keys()]) retire(hostId2);
17922
+ discovery = null;
17923
+ externalDrafts.clear();
17924
+ selectedModels.clear();
17925
+ if (port.postMessage === postMessage) port.postMessage = originalPostMessage;
17926
+ if (target.__codexhostHostRoutingV1 === routing) {
17927
+ delete target.__codexhostHostRoutingV1;
17928
+ publish(null);
17929
+ }
17930
+ }
17931
+ };
17932
+ Object.defineProperty(target, "__codexhostHostRoutingV1", { configurable: true, value: routing });
17933
+ return routing;
17934
+ }
17935
+
17581
17936
  // packages/desktop-control/src/renderer-draft-prewarm-policy.ts
17582
17937
  var REQUEST_MANAGER_WAIT_TIMEOUT_MS = 6e4;
17583
17938
  var REQUEST_MANAGER_POLL_INTERVAL_MS = 25;
@@ -17590,21 +17945,52 @@ function directRendererInstaller() {
17590
17945
  const retainRendererHostResponses = ${retainRendererHostResponses.toString()};
17591
17946
  const createDraftPrewarmPolicyBridge = ${createDraftPrewarmPolicyBridge.toString()};
17592
17947
  const isolateRendererPrewarmConsumption = ${isolateRendererPrewarmConsumption.toString()};
17593
- const routing = (${installRendererHostRouting.toString()})(
17594
- document, window,
17595
- (root) => discoverRendererHosts(root, committedReactAncestors, requestManagerFromHookState),
17948
+ const discover = (root) =>
17949
+ discoverRendererHosts(root, committedReactAncestors, requestManagerFromHookState);
17950
+ const installNative = () => (${installRendererHostRouting.toString()})(
17951
+ document, window, discover,
17596
17952
  (discovery, hostId) => resolveRendererHostManager(discovery, hostId, requestManagerFromHookState),
17597
17953
  (manager, bridge, hostId, target, prewarmed, isCurrent) => createDraftPrewarmPolicyBridge(
17598
17954
  manager, bridge, hostId, target, prewarmed, isCurrent, retainRendererHostResponses,
17599
17955
  isolateRendererPrewarmConsumption,
17600
17956
  ),
17601
17957
  );
17958
+ const installRpc = () => typeof MessagePort !== 'function' ? null : (${installRendererHostRpcRouting.toString()})(document, window, {
17959
+ findStore: ${findRendererAppScopeStore.toString()},
17960
+ findFamily: ${findRendererHostRpcFamily.toString()},
17961
+ resolve: ${resolveRendererHostRpc.toString()},
17962
+ hostIds: ${rendererHostRpcHostIds.toString()},
17963
+ composerHostIds: (composer) => {
17964
+ const source = composer?.matches?.('[data-codex-composer], [contenteditable="true"][role="textbox"]')
17965
+ ? { querySelectorAll: () => [composer] }
17966
+ : (composer ?? document);
17967
+ return discover(source);
17968
+ },
17969
+ portPrototype: MessagePort.prototype,
17970
+ });
17971
+ const connected = (routing) => routing.forComposer() !== null ||
17972
+ ['local', ...(routing.knownHostIds?.() ?? [])].some((hostId) => routing.forHost(hostId) !== null);
17973
+ 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.
17976
+ const routing = (() => {
17977
+ if (window.__codexhostHostRoutingV1) return window.__codexhostHostRoutingV1;
17978
+ const native = discover(document);
17979
+ if (native.managers.length || native.registries.length) {
17980
+ const routing = installNative();
17981
+ if (connected(routing)) {
17982
+ nativeReady = true;
17983
+ return routing;
17984
+ }
17985
+ routing.dispose();
17986
+ }
17987
+ const rpc = installRpc();
17988
+ if (rpc) return rpc;
17989
+ throw new Error('Renderer Host request manager is unavailable');
17990
+ })();
17602
17991
  // Publish a default draft policy only when its Host is unambiguous. Host
17603
17992
  // connections can be ready even when multiple Composers coexist.
17604
- const composerRoute = routing.forComposer();
17605
- const connected = composerRoute !== null ||
17606
- ['local', ...(routing.knownHostIds?.() ?? [])].some((hostId) => routing.forHost(hostId) !== null);
17607
- if (!connected) throw new Error('Renderer Host request manager is unavailable');
17993
+ if (!nativeReady && !connected(routing)) throw new Error('Renderer Host request manager is unavailable');
17608
17994
  return { state: 'ready', reason: 'owned-request-bridge' };
17609
17995
  })()`;
17610
17996
  }
@@ -17635,6 +18021,130 @@ function installRendererDraftPrewarmPolicyDirect(renderer) {
17635
18021
  );
17636
18022
  }
17637
18023
 
18024
+ // packages/desktop-control/src/renderer-loaded-modules.ts
18025
+ var record2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
18026
+ var MAX_MODULES = 4096;
18027
+ var STALE_CONTEXT_ERROR = /uniqueContextId not found|Cannot find context with specified id|Execution context was destroyed|Cannot find default execution context/i;
18028
+ function isStaleContextError(error51) {
18029
+ return error51 instanceof Error && STALE_CONTEXT_ERROR.test(error51.message);
18030
+ }
18031
+ function nativeModuleCatalogExpression(urls, complete, owner) {
18032
+ return `Object.defineProperty(globalThis, '__codexhostLoadedModulesV1', {
18033
+ configurable: true,
18034
+ value: Object.freeze({ owner: ${JSON.stringify(owner)}, documentUrl: location.href, complete: ${complete}, urls: Object.freeze(${JSON.stringify(urls)}) })
18035
+ }); void 0`;
18036
+ }
18037
+ async function installRendererLoadedModules(renderer) {
18038
+ const owner = crypto.randomUUID();
18039
+ const contexts = /* @__PURE__ */ new Map();
18040
+ const contextIds = /* @__PURE__ */ new Map();
18041
+ const dirty = /* @__PURE__ */ new Set();
18042
+ let ready = false;
18043
+ let disposed = false;
18044
+ let timer;
18045
+ let publishing = Promise.resolve();
18046
+ const flush = () => {
18047
+ clearTimeout(timer);
18048
+ timer = void 0;
18049
+ const pending = [...dirty];
18050
+ dirty.clear();
18051
+ publishing = publishing.catch(() => void 0).then(async () => {
18052
+ let failure;
18053
+ for (const uniqueId of pending) {
18054
+ const context = contexts.get(uniqueId);
18055
+ if (!context || disposed) continue;
18056
+ try {
18057
+ const response = await renderer.command("Runtime.evaluate", {
18058
+ expression: nativeModuleCatalogExpression([...context.urls], context.complete, owner),
18059
+ uniqueContextId: uniqueId
18060
+ });
18061
+ if (record2(response) && record2(response.exceptionDetails))
18062
+ throw new Error("Loaded Renderer module catalog publication failed");
18063
+ } catch (error51) {
18064
+ if (contexts.get(uniqueId) !== context) continue;
18065
+ if (isStaleContextError(error51)) {
18066
+ forget(uniqueId);
18067
+ continue;
18068
+ }
18069
+ failure ??= error51;
18070
+ }
18071
+ }
18072
+ if (failure !== void 0) throw failure;
18073
+ });
18074
+ return publishing;
18075
+ };
18076
+ const schedule = (uniqueId) => {
18077
+ dirty.add(uniqueId);
18078
+ if (ready && timer === void 0)
18079
+ timer = setTimeout(() => {
18080
+ void flush().catch((error51) => {
18081
+ console.error("Could not publish loaded Renderer modules", error51);
18082
+ });
18083
+ }, 10);
18084
+ };
18085
+ const forget = (uniqueId) => {
18086
+ contexts.delete(uniqueId);
18087
+ dirty.delete(uniqueId);
18088
+ for (const [id, value] of contextIds) if (value === uniqueId) contextIds.delete(id);
18089
+ };
18090
+ const remove = (params) => {
18091
+ const byId = typeof params.executionContextId === "number" ? contextIds.get(params.executionContextId) : void 0;
18092
+ const uniqueId = typeof params.executionContextUniqueId === "string" ? params.executionContextUniqueId : byId;
18093
+ if (uniqueId) forget(uniqueId);
18094
+ };
18095
+ const listeners = [
18096
+ renderer.on("Runtime.executionContextCreated", (params) => {
18097
+ const context = record2(params) ? params.context : null;
18098
+ if (!record2(context) || typeof context.id !== "number" || typeof context.uniqueId !== "string" || !record2(context.auxData) || context.auxData.isDefault !== true)
18099
+ return;
18100
+ contextIds.set(context.id, context.uniqueId);
18101
+ contexts.set(context.uniqueId, { urls: /* @__PURE__ */ new Set(), complete: true });
18102
+ schedule(context.uniqueId);
18103
+ }),
18104
+ renderer.on("Runtime.executionContextDestroyed", (params) => {
18105
+ if (record2(params)) remove(params);
18106
+ }),
18107
+ renderer.on("Runtime.executionContextsCleared", () => {
18108
+ contextIds.clear();
18109
+ contexts.clear();
18110
+ dirty.clear();
18111
+ }),
18112
+ renderer.on("Debugger.scriptParsed", (params) => {
18113
+ if (!record2(params) || params.isModule !== true || params.hasSourceURL === true || typeof params.url !== "string" || typeof params.executionContextId !== "number")
18114
+ return;
18115
+ const uniqueId = contextIds.get(params.executionContextId);
18116
+ const context = uniqueId ? contexts.get(uniqueId) : null;
18117
+ if (!context || !uniqueId || context.urls.has(params.url)) return;
18118
+ if (context.urls.size >= MAX_MODULES) context.complete = false;
18119
+ else context.urls.add(params.url);
18120
+ schedule(uniqueId);
18121
+ })
18122
+ ];
18123
+ const dispose = () => {
18124
+ disposed = true;
18125
+ clearTimeout(timer);
18126
+ for (const unsubscribe of listeners) unsubscribe();
18127
+ for (const uniqueId of contexts.keys())
18128
+ void renderer.command("Runtime.evaluate", {
18129
+ expression: `if (globalThis.__codexhostLoadedModulesV1 === undefined || globalThis.__codexhostLoadedModulesV1?.owner === ${JSON.stringify(owner)}) { ${nativeModuleCatalogExpression([], false, owner)} }`,
18130
+ uniqueContextId: uniqueId
18131
+ }).catch(() => void 0);
18132
+ contexts.clear();
18133
+ contextIds.clear();
18134
+ dirty.clear();
18135
+ };
18136
+ try {
18137
+ await renderer.command("Runtime.enable");
18138
+ await renderer.command("Debugger.enable");
18139
+ ready = true;
18140
+ await flush();
18141
+ return dispose;
18142
+ } catch (error51) {
18143
+ dispose();
18144
+ throw error51;
18145
+ }
18146
+ }
18147
+
17638
18148
  // packages/desktop-control/src/renderer-cdp-control-session.ts
17639
18149
  function isRecord2(value) {
17640
18150
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -17779,21 +18289,23 @@ async function waitForBinding(renderer, enabledAgents, timeoutMs, pollIntervalMs
17779
18289
  }
17780
18290
  async function installTarget(target, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations) {
17781
18291
  const renderer = await operations.connect(target.webSocketDebuggerUrl);
18292
+ let disposeModules;
17782
18293
  try {
17783
- await renderer.command("Runtime.enable");
18294
+ disposeModules = await installRendererLoadedModules(renderer);
17784
18295
  await renderer.command("Page.enable");
17785
18296
  await renderer.command("Page.addScriptToEvaluateOnNewDocument", { source: rendererSource });
17786
18297
  await evaluateSource(renderer, rendererSource);
17787
18298
  const draftPrewarmPolicy = await operations.installDraftPrewarmPolicy(renderer);
17788
18299
  const binding = await waitForBinding(renderer, enabledAgents, timeoutMs, pollIntervalMs);
17789
- return { renderer, snapshot: { target, draftPrewarmPolicy, binding } };
18300
+ return { renderer, snapshot: { target, draftPrewarmPolicy, binding }, disposeModules };
17790
18301
  } catch (error51) {
18302
+ disposeModules?.();
17791
18303
  renderer.close();
17792
18304
  throw error51;
17793
18305
  }
17794
18306
  }
17795
18307
  var InstalledRendererCdpControlSession = class {
17796
- constructor(renderer, rendererCdpEndpoint2, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, currentSnapshot) {
18308
+ constructor(renderer, rendererCdpEndpoint2, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, currentSnapshot, disposeModules) {
17797
18309
  this.renderer = renderer;
17798
18310
  this.rendererCdpEndpoint = rendererCdpEndpoint2;
17799
18311
  this.rendererSource = rendererSource;
@@ -17802,6 +18314,7 @@ var InstalledRendererCdpControlSession = class {
17802
18314
  this.pollIntervalMs = pollIntervalMs;
17803
18315
  this.operations = operations;
17804
18316
  this.currentSnapshot = currentSnapshot;
18317
+ this.disposeModules = disposeModules;
17805
18318
  }
17806
18319
  renderer;
17807
18320
  rendererCdpEndpoint;
@@ -17811,6 +18324,7 @@ var InstalledRendererCdpControlSession = class {
17811
18324
  pollIntervalMs;
17812
18325
  operations;
17813
18326
  currentSnapshot;
18327
+ disposeModules;
17814
18328
  #closed = false;
17815
18329
  get snapshot() {
17816
18330
  return this.currentSnapshot;
@@ -17833,8 +18347,10 @@ var InstalledRendererCdpControlSession = class {
17833
18347
  this.pollIntervalMs,
17834
18348
  this.operations
17835
18349
  );
18350
+ this.disposeModules();
17836
18351
  this.renderer.close();
17837
18352
  this.renderer = replacement.renderer;
18353
+ this.disposeModules = replacement.disposeModules;
17838
18354
  this.currentSnapshot = replacement.snapshot;
17839
18355
  return this.currentSnapshot;
17840
18356
  }
@@ -17859,8 +18375,10 @@ var InstalledRendererCdpControlSession = class {
17859
18375
  this.pollIntervalMs,
17860
18376
  this.operations
17861
18377
  );
18378
+ this.disposeModules();
17862
18379
  this.renderer.close();
17863
18380
  this.renderer = replacement.renderer;
18381
+ this.disposeModules = replacement.disposeModules;
17864
18382
  this.currentSnapshot = replacement.snapshot;
17865
18383
  return this.currentSnapshot;
17866
18384
  }
@@ -17877,6 +18395,7 @@ var InstalledRendererCdpControlSession = class {
17877
18395
  close() {
17878
18396
  if (this.#closed) return;
17879
18397
  this.#closed = true;
18398
+ this.disposeModules();
17880
18399
  this.renderer.close();
17881
18400
  }
17882
18401
  };
@@ -17914,7 +18433,8 @@ async function createRendererCdpControlSession(options) {
17914
18433
  timeoutMs,
17915
18434
  pollIntervalMs,
17916
18435
  operations,
17917
- installed.snapshot
18436
+ installed.snapshot,
18437
+ installed.disposeModules
17918
18438
  );
17919
18439
  }
17920
18440
  function installRendererCdpControlSession(options) {