@codexhost/cli-darwin-x64 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -285,270 +285,6 @@ var CdpClient = class _CdpClient {
285
285
  }
286
286
  };
287
287
 
288
- // packages/desktop-control/src/main-process-title-policy.ts
289
- function isRecord2(value) {
290
- return typeof value === "object" && value !== null && !Array.isArray(value);
291
- }
292
- function resultRecord(value, command) {
293
- if (!isRecord2(value)) throw new Error(`${command} returned an invalid result`);
294
- if (isRecord2(value.exceptionDetails)) {
295
- const exception = value.exceptionDetails.exception;
296
- const description = isRecord2(exception) ? exception.description : null;
297
- const text = value.exceptionDetails.text;
298
- throw new Error(
299
- typeof description === "string" ? description : typeof text === "string" ? text : `${command} failed`
300
- );
301
- }
302
- return value;
303
- }
304
- function remoteObjectId(value, label) {
305
- if (!isRecord2(value) || typeof value.objectId !== "string") {
306
- throw new Error(`${label} is unavailable`);
307
- }
308
- return value.objectId;
309
- }
310
- function properties(value, command) {
311
- const result = resultRecord(value, command).result;
312
- if (!Array.isArray(result)) throw new Error(`${command} returned invalid properties`);
313
- return result.filter(isRecord2);
314
- }
315
- var ELECTRON_MODULE_EXPRESSION = `(() => {
316
- const mainModule = process.mainModule;
317
- if (mainModule != null && typeof mainModule.require === 'function') {
318
- return mainModule.require('electron');
319
- }
320
- const { createRequire } = process.getBuiltinModule('module');
321
- return createRequire(process.execPath)('electron');
322
- })()`;
323
- var CONNECT_APP_HOST_CHANNEL = "codex_desktop:connect-app-host";
324
- var POLICY_STATE_SYMBOL = "codexhost.main-process-title-policy.v1";
325
- var SERVICE_OWNER_SYMBOL = "codexhost.main-process-title-policy.owner.v1";
326
- var RENDERER_READY_EXPRESSION = "(() => { Object.defineProperty(window, '__codexhostMainProcessTitlePolicyV1', { configurable: true, value: { state: 'ready' } }); return 'ready'; })()";
327
- var INSTALL_POLICY_FUNCTION = `async function (rendererWebContentsId) {
328
- const mainModule = process.mainModule;
329
- const electron = mainModule != null && typeof mainModule.require === 'function'
330
- ? mainModule.require('electron')
331
- : process.getBuiltinModule('module').createRequire(process.execPath)('electron');
332
- const selected = electron.webContents.fromId(rendererWebContentsId);
333
- if (selected == null || selected.isDestroyed() || selected.getType() !== 'window') {
334
- throw new Error('Owned Renderer unavailable for title policy');
335
- }
336
-
337
- const context = this(selected);
338
- if (context == null || typeof context.createAppHost !== 'function') {
339
- throw new Error('WindowContext unavailable for title policy');
340
- }
341
- const stateSymbol = Symbol.for(${JSON.stringify(POLICY_STATE_SYMBOL)});
342
- const ownerSymbol = Symbol.for(${JSON.stringify(SERVICE_OWNER_SYMBOL)});
343
- globalThis[stateSymbol]?.dispose?.();
344
-
345
- const originalCreateAppHost = context.createAppHost;
346
- const sampleHost = originalCreateAppHost.call(context, selected);
347
- const sampleService = sampleHost?.services?.threadMetadataGeneration;
348
- const servicePrototype = sampleService == null ? null : Object.getPrototypeOf(sampleService);
349
- const originalGenerateTitle = servicePrototype?.generateTitle;
350
- if (
351
- servicePrototype == null ||
352
- typeof originalGenerateTitle !== 'function' ||
353
- !Function.prototype.toString.call(originalGenerateTitle).includes('Failed to generate thread title')
354
- ) {
355
- throw new Error('ThreadMetadataGenerationService signature mismatch');
356
- }
357
- const counters = {
358
- codexTitleCalls: 0,
359
- piTitleSkips: 0,
360
- externalTitleSkips: 0,
361
- ambiguousTitleSkips: 0,
362
- };
363
- const ownedWebContentsIds = new Set();
364
- const ownService = (service, contents) => {
365
- const existingOwner = service[ownerSymbol];
366
- if (existingOwner != null && existingOwner !== contents) {
367
- throw new Error('Thread metadata service ownership mismatch');
368
- }
369
- if (existingOwner == null) {
370
- Object.defineProperty(service, ownerSymbol, { value: contents });
371
- }
372
- ownedWebContentsIds.add(contents.id);
373
- };
374
- ownService(sampleService, selected);
375
- const wrappedCreateAppHost = function (contents) {
376
- const host = originalCreateAppHost.call(this, contents);
377
- const service = host?.services?.threadMetadataGeneration;
378
- if (service != null) ownService(service, contents);
379
- return host;
380
- };
381
- const wrappedGenerateTitle = async function (params) {
382
- const owner = this[ownerSymbol];
383
- if (owner == null || owner.isDestroyed()) {
384
- counters.ambiguousTitleSkips += 1;
385
- return null;
386
- }
387
- let selection = null;
388
- try {
389
- selection = await owner.executeJavaScript(
390
- "window.__codexhostRendererBindingProbeV1?.lockedSelection() ?? null",
391
- true,
392
- );
393
- } catch {}
394
- if (selection?.phase !== 'locked') {
395
- counters.ambiguousTitleSkips += 1;
396
- return null;
397
- }
398
- if (selection.agent === 'pi') {
399
- counters.piTitleSkips += 1;
400
- return null;
401
- }
402
- if (selection.agent !== 'codex') {
403
- counters.externalTitleSkips += 1;
404
- return null;
405
- }
406
- counters.codexTitleCalls += 1;
407
- return originalGenerateTitle.call(this, params);
408
- };
409
-
410
- context.createAppHost = wrappedCreateAppHost;
411
- servicePrototype.generateTitle = wrappedGenerateTitle;
412
- const state = {
413
- counters,
414
- ownedWebContentsIds,
415
- dispose() {
416
- if (context.createAppHost === wrappedCreateAppHost) {
417
- context.createAppHost = originalCreateAppHost;
418
- }
419
- if (servicePrototype.generateTitle === wrappedGenerateTitle) {
420
- servicePrototype.generateTitle = originalGenerateTitle;
421
- }
422
- if (globalThis[stateSymbol] === state) delete globalThis[stateSymbol];
423
- },
424
- };
425
- globalThis[stateSymbol] = state;
426
- return {
427
- state: 'ready',
428
- reason: 'ready',
429
- requiresRendererReload: true,
430
- };
431
- }`;
432
- async function installMainProcessTitlePolicy(inspector, rendererWebContentsId) {
433
- if (!Number.isInteger(rendererWebContentsId) || rendererWebContentsId <= 0) {
434
- throw new Error("Renderer webContents ID must be a positive integer");
435
- }
436
- const listenerResponse = resultRecord(
437
- await inspector.command("Runtime.evaluate", {
438
- expression: `(${ELECTRON_MODULE_EXPRESSION}).ipcMain.listeners(${JSON.stringify(
439
- CONNECT_APP_HOST_CHANNEL
440
- )})[0]`
441
- }),
442
- "Runtime.evaluate"
443
- );
444
- const listener = listenerResponse.result;
445
- const listenerId = remoteObjectId(listener, "connect-app-host listener");
446
- const listenerProperties = resultRecord(
447
- await inspector.command("Runtime.getProperties", { objectId: listenerId }),
448
- "Runtime.getProperties"
449
- );
450
- const internalProperties = listenerProperties.internalProperties;
451
- if (!Array.isArray(internalProperties)) {
452
- throw new Error("connect-app-host listener scopes are unavailable");
453
- }
454
- const scopes = internalProperties.find(
455
- (property) => isRecord2(property) && property.name === "[[Scopes]]"
456
- );
457
- const scopesId = remoteObjectId(
458
- isRecord2(scopes) ? scopes.value : null,
459
- "connect-app-host listener scopes"
460
- );
461
- const scopeProperties = properties(
462
- await inspector.command("Runtime.getProperties", {
463
- objectId: scopesId,
464
- ownProperties: true
465
- }),
466
- "Runtime.getProperties"
467
- );
468
- const localScope = scopeProperties.find((property) => property.name === "0");
469
- const localScopeId = remoteObjectId(localScope?.value, "connect-app-host local scope");
470
- const localProperties = properties(
471
- await inspector.command("Runtime.getProperties", {
472
- objectId: localScopeId,
473
- ownProperties: true
474
- }),
475
- "Runtime.getProperties"
476
- );
477
- const getContext = localProperties.find(
478
- (property) => property.name === "f" && typeof property.value?.objectId === "string"
479
- );
480
- const getContextId = remoteObjectId(getContext?.value, "getContextForWebContents");
481
- const installPromise = resultRecord(
482
- await inspector.command("Runtime.callFunctionOn", {
483
- objectId: getContextId,
484
- functionDeclaration: INSTALL_POLICY_FUNCTION,
485
- arguments: [{ value: rendererWebContentsId }]
486
- }),
487
- "Runtime.callFunctionOn"
488
- );
489
- const promiseObjectId = remoteObjectId(
490
- installPromise.result,
491
- "Main-process title policy installation promise"
492
- );
493
- const installResponse = resultRecord(
494
- await inspector.command("Runtime.awaitPromise", {
495
- promiseObjectId,
496
- returnByValue: true
497
- }),
498
- "Runtime.awaitPromise"
499
- );
500
- const remoteResult = installResponse.result;
501
- const value = isRecord2(remoteResult) ? remoteResult.value : null;
502
- if (!isRecord2(value) || value.state !== "ready" || value.reason !== "ready" || value.requiresRendererReload !== true || Object.keys(value).length !== 3) {
503
- throw new Error("Main-process title policy returned an invalid status");
504
- }
505
- return value;
506
- }
507
- async function markRendererTitlePolicyReady(inspector, rendererWebContentsId) {
508
- if (!Number.isInteger(rendererWebContentsId) || rendererWebContentsId <= 0) {
509
- throw new Error("Renderer webContents ID must be a positive integer");
510
- }
511
- const value = await inspector.evaluate(`(async () => {
512
- const state = globalThis[Symbol.for(${JSON.stringify(POLICY_STATE_SYMBOL)})];
513
- if (state == null) throw new Error('Main-process title policy is unavailable');
514
- const mainModule = process.mainModule;
515
- const electron = mainModule != null && typeof mainModule.require === 'function'
516
- ? mainModule.require('electron')
517
- : process.getBuiltinModule('module').createRequire(process.execPath)('electron');
518
- const selected = electron.webContents.fromId(${rendererWebContentsId});
519
- if (selected == null || selected.isDestroyed() || selected.getType() !== 'window') {
520
- throw new Error('Owned Renderer unavailable for title policy readiness');
521
- }
522
- if (!state.ownedWebContentsIds.has(selected.id)) {
523
- throw new Error('Renderer metadata service ownership is unavailable');
524
- }
525
- const marker = selected.executeJavaScript(
526
- ${JSON.stringify(RENDERER_READY_EXPRESSION)},
527
- true,
528
- );
529
- const markerTimeout = new Promise((_, reject) => {
530
- setTimeout(() => reject(new Error('Renderer readiness marker timed out')), 2_000);
531
- });
532
- await Promise.race([marker, markerTimeout]);
533
- return { state: 'ready', reason: 'owned-metadata-service' };
534
- })()`);
535
- if (!isRecord2(value) || value.state !== "ready" || value.reason !== "owned-metadata-service") {
536
- throw new Error("Renderer title policy returned an invalid readiness status");
537
- }
538
- return value;
539
- }
540
- async function readMainProcessTitlePolicyCounters(inspector) {
541
- const value = await inspector.evaluate(`(() => {
542
- const state = globalThis[Symbol.for(${JSON.stringify(POLICY_STATE_SYMBOL)})];
543
- return state == null ? null : { ...state.counters };
544
- })()`);
545
- if (value === null) return null;
546
- if (!isRecord2(value) || !Number.isInteger(value.codexTitleCalls) || !Number.isInteger(value.piTitleSkips) || !Number.isInteger(value.externalTitleSkips) || !Number.isInteger(value.ambiguousTitleSkips)) {
547
- throw new Error("Main-process title policy returned invalid counters");
548
- }
549
- return value;
550
- }
551
-
552
288
  // packages/desktop-control/src/renderer-draft-prewarm-runtime.ts
553
289
  function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewarmedThreadManager) {
554
290
  const existing = target.__codexhostDraftPrewarmPolicyV1;
@@ -561,7 +297,7 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
561
297
  const originalOnNotification = manager.onNotification;
562
298
  const originalDispatchAppServerResponse = manager.dispatchAppServerResponse;
563
299
  let selectedModel = null;
564
- const isRecord5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
300
+ const isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
565
301
  const isRemoteControlHost = hostId.startsWith("remote-control:");
566
302
  const knownExternalThreadIds = /* @__PURE__ */ new Set();
567
303
  const knownOfficialThreadIds = /* @__PURE__ */ new Set();
@@ -645,14 +381,14 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
645
381
  bridgeState = "idle";
646
382
  };
647
383
  const rememberExternalThread = (value) => {
648
- if (!isRecord5(value) || typeof value.id !== "string") return;
384
+ if (!isRecord4(value) || typeof value.id !== "string") return;
649
385
  if (value.modelProvider === "codexhost" || value.cliVersion === "codexhost") {
650
386
  knownExternalThreadIds.add(value.id);
651
387
  knownOfficialThreadIds.delete(value.id);
652
388
  }
653
389
  };
654
390
  const observeBridgeResult = (request, result) => {
655
- if (!request || !isRecord5(result)) return;
391
+ if (!request || !isRecord4(result)) return;
656
392
  if (request.method === "thread/list" && Array.isArray(result.data)) {
657
393
  for (const thread of result.data) rememberExternalThread(thread);
658
394
  return;
@@ -661,7 +397,7 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
661
397
  rememberExternalThread(result.thread);
662
398
  return;
663
399
  }
664
- if (request.method === "codexhost/thread/inspect" && isRecord5(request.parameters) && typeof request.parameters.threadId === "string") {
400
+ if (request.method === "codexhost/thread/inspect" && isRecord4(request.parameters) && typeof request.parameters.threadId === "string") {
665
401
  if (result.owner === "external") {
666
402
  knownExternalThreadIds.add(request.parameters.threadId);
667
403
  knownOfficialThreadIds.delete(request.parameters.threadId);
@@ -671,18 +407,18 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
671
407
  }
672
408
  return;
673
409
  }
674
- if (request.method === "thread/delete" && isRecord5(request.parameters) && typeof request.parameters.threadId === "string") {
410
+ if (request.method === "thread/delete" && isRecord4(request.parameters) && typeof request.parameters.threadId === "string") {
675
411
  knownExternalThreadIds.delete(request.parameters.threadId);
676
412
  knownOfficialThreadIds.delete(request.parameters.threadId);
677
413
  }
678
414
  };
679
415
  const handleBridgeFrame = (value) => {
680
- if (!isRecord5(value)) {
416
+ if (!isRecord4(value)) {
681
417
  failBridge("received a non-object app-server frame");
682
418
  return;
683
419
  }
684
420
  if (value.method === bridgeReadyMethod && value.id === void 0) {
685
- if (isRecord5(value.params) && value.params.protocolVersion === 1) {
421
+ if (isRecord4(value.params) && value.params.protocolVersion === 1) {
686
422
  bridgeState = "ready";
687
423
  if (bridgeReadyTimeout !== null) globalThis.clearTimeout(bridgeReadyTimeout);
688
424
  bridgeReadyTimeout = null;
@@ -695,7 +431,7 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
695
431
  return;
696
432
  }
697
433
  if (typeof value.method === "string" && value.id === void 0) {
698
- if (value.method === "thread/started" && isRecord5(value.params)) {
434
+ if (value.method === "thread/started" && isRecord4(value.params)) {
699
435
  rememberExternalThread(value.params.thread);
700
436
  }
701
437
  originalOnNotification.call(manager, value.method, value.params);
@@ -746,7 +482,7 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
746
482
  }
747
483
  };
748
484
  const handleOuterNotification = (method, parameters) => {
749
- if (method === "process/exited" && isRecord5(parameters) && parameters.processHandle === bridgeProcessHandle) {
485
+ if (method === "process/exited" && isRecord4(parameters) && parameters.processHandle === bridgeProcessHandle) {
750
486
  const exitCode = typeof parameters.exitCode === "number" ? parameters.exitCode : "unknown";
751
487
  const stderr = typeof parameters.stderr === "string" ? parameters.stderr.trim() : "";
752
488
  failBridge(
@@ -755,7 +491,7 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
755
491
  );
756
492
  return true;
757
493
  }
758
- if (method !== "process/outputDelta" || !isRecord5(parameters) || parameters.processHandle !== bridgeProcessHandle || parameters.stream !== "stdout" && parameters.stream !== "stderr" || typeof parameters.deltaBase64 !== "string") {
494
+ if (method !== "process/outputDelta" || !isRecord4(parameters) || parameters.processHandle !== bridgeProcessHandle || parameters.stream !== "stdout" && parameters.stream !== "stderr" || typeof parameters.deltaBase64 !== "string") {
759
495
  return false;
760
496
  }
761
497
  if (parameters.capReached === true) {
@@ -860,7 +596,7 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
860
596
  return bridgeInitialization;
861
597
  };
862
598
  const threadIdFromParameters = (parameters) => {
863
- if (!isRecord5(parameters)) return null;
599
+ if (!isRecord4(parameters)) return null;
864
600
  const value = parameters.threadId ?? parameters.conversationId;
865
601
  return typeof value === "string" ? value : null;
866
602
  };
@@ -875,9 +611,9 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
875
611
  threadIds: [threadId]
876
612
  })
877
613
  ).then((value) => {
878
- const ownerships = isRecord5(value) && Array.isArray(value.threads) ? value.threads : null;
614
+ const ownerships = isRecord4(value) && Array.isArray(value.threads) ? value.threads : null;
879
615
  const ownership = ownerships?.[0];
880
- if (!ownerships || !isRecord5(ownership) || ownerships.length !== 1 || ownership.threadId !== threadId || ownership.owner !== "external" && ownership.owner !== "codex") {
616
+ if (!ownerships || !isRecord4(ownership) || ownerships.length !== 1 || ownership.threadId !== threadId || ownership.owner !== "external" && ownership.owner !== "codex") {
881
617
  throw transportError("Thread ownership lookup returned an invalid result");
882
618
  }
883
619
  if (ownership.owner === "external") {
@@ -913,7 +649,7 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
913
649
  if (method.startsWith("codexhost/")) return true;
914
650
  if (method === "thread/list") return true;
915
651
  if (method === "thread/start") {
916
- return isRecord5(parameters) && typeof parameters.model === "string" && parameters.model.startsWith("codexhost/");
652
+ return isRecord4(parameters) && typeof parameters.model === "string" && parameters.model.startsWith("codexhost/");
917
653
  }
918
654
  const threadId = threadIdFromParameters(parameters);
919
655
  if (threadId && knownExternalThreadIds.has(threadId)) return true;
@@ -921,7 +657,7 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
921
657
  return selectedModel !== null && (method.startsWith("thread/") || method.startsWith("turn/") || method.startsWith("review/"));
922
658
  };
923
659
  const routeThreadStart = (parameters) => {
924
- if (selectedModel === null || !isRecord5(parameters) || parameters.ephemeral === true) {
660
+ if (selectedModel === null || !isRecord4(parameters) || parameters.ephemeral === true) {
925
661
  return parameters;
926
662
  }
927
663
  return { ...parameters, model: selectedModel };
@@ -951,7 +687,7 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
951
687
  bridge.prewarmThreadStart = routedPrewarm;
952
688
  const routedWindowMessage = (event) => {
953
689
  const message = event.data;
954
- if (!isRecord5(message) || message.type !== "mcp-notification" || message.hostId !== hostId || typeof message.method !== "string") {
690
+ if (!isRecord4(message) || message.type !== "mcp-notification" || message.hostId !== hostId || typeof message.method !== "string") {
955
691
  return;
956
692
  }
957
693
  handleOuterNotification(message.method, message.params);
@@ -1041,63 +777,6 @@ function installDraftPrewarmPolicyBridge(manager, bridge, hostId, target, prewar
1041
777
  }
1042
778
  return { state: "ready", reason: "owned-request-bridge" };
1043
779
  }
1044
- async function installDraftPrewarmPolicyInRenderer(contents, findRequestManagerExpression, installRendererPolicyFunction) {
1045
- if (contents === null || contents.isDestroyed() || contents.getType() !== "window") {
1046
- throw new Error("Owned Renderer is unavailable for draft prewarm policy");
1047
- }
1048
- let attachedHere = false;
1049
- try {
1050
- if (!contents.debugger.isAttached()) {
1051
- contents.debugger.attach("1.3");
1052
- attachedHere = true;
1053
- }
1054
- await contents.debugger.sendCommand("Runtime.enable");
1055
- const managerResult = await contents.debugger.sendCommand("Runtime.evaluate", {
1056
- expression: findRequestManagerExpression
1057
- });
1058
- const managerResultId = managerResult.result?.objectId;
1059
- if (typeof managerResultId !== "string") {
1060
- throw new Error("Renderer request manager inspection failed");
1061
- }
1062
- const managerProperties = await contents.debugger.sendCommand("Runtime.getProperties", {
1063
- objectId: managerResultId,
1064
- ownProperties: true
1065
- });
1066
- const candidateCount = managerProperties.result?.find(
1067
- (property) => property.name === "candidateCount"
1068
- )?.value?.value;
1069
- const hostId = managerProperties.result?.find((property) => property.name === "hostId")?.value?.value;
1070
- const manager = managerProperties.result?.find(
1071
- (property) => property.name === "manager"
1072
- )?.value;
1073
- const requestClient = managerProperties.result?.find(
1074
- (property) => property.name === "requestClient"
1075
- )?.value;
1076
- const prewarmedThreadManager = managerProperties.result?.find(
1077
- (property) => property.name === "prewarmedThreadManager"
1078
- )?.value;
1079
- if (candidateCount !== 1 || typeof hostId !== "string" || hostId.length === 0 || typeof manager?.objectId !== "string" || typeof requestClient?.objectId !== "string") {
1080
- throw new Error("Renderer request manager is ambiguous");
1081
- }
1082
- if (typeof prewarmedThreadManager?.objectId !== "string") {
1083
- throw new Error("Renderer prewarmed Thread manager is unavailable");
1084
- }
1085
- const installed = await contents.debugger.sendCommand("Runtime.callFunctionOn", {
1086
- objectId: manager.objectId,
1087
- functionDeclaration: installRendererPolicyFunction,
1088
- arguments: [
1089
- { objectId: requestClient.objectId },
1090
- { value: hostId },
1091
- { objectId: prewarmedThreadManager.objectId }
1092
- ],
1093
- awaitPromise: true,
1094
- returnByValue: true
1095
- });
1096
- return installed.result?.value;
1097
- } finally {
1098
- if (attachedHere && contents.debugger.isAttached()) contents.debugger.detach();
1099
- }
1100
- }
1101
780
 
1102
781
  // packages/desktop-control/src/renderer-draft-prewarm-policy.ts
1103
782
  function selectRendererRequestManager(candidates, activeHostIds) {
@@ -1113,7 +792,7 @@ function selectRendererRequestManager(candidates, activeHostIds) {
1113
792
  );
1114
793
  return eligible.length === 1 ? eligible[0] ?? null : null;
1115
794
  }
1116
- function isRecord3(value) {
795
+ function isRecord2(value) {
1117
796
  return typeof value === "object" && value !== null && !Array.isArray(value);
1118
797
  }
1119
798
  var FIND_REQUEST_MANAGER_EXPRESSION = `(() => {
@@ -1193,30 +872,36 @@ var INSTALL_RENDERER_POLICY_FUNCTION = `function(requestClient, hostId, prewarme
1193
872
  }`;
1194
873
  var REQUEST_MANAGER_WAIT_TIMEOUT_MS = 6e4;
1195
874
  var REQUEST_MANAGER_POLL_INTERVAL_MS = 25;
1196
- function mainProcessInstaller(rendererWebContentsId) {
1197
- return `async function () {
1198
- const mainModule = process.mainModule;
1199
- const electron = mainModule != null && typeof mainModule.require === 'function'
1200
- ? mainModule.require('electron')
1201
- : process.getBuiltinModule('module').createRequire(process.execPath)('electron');
1202
- const contents = electron.webContents.fromId(${rendererWebContentsId});
1203
- return (${installDraftPrewarmPolicyInRenderer.toString()})(
1204
- contents,
1205
- ${JSON.stringify(FIND_REQUEST_MANAGER_EXPRESSION)},
1206
- ${JSON.stringify(INSTALL_RENDERER_POLICY_FUNCTION)}
875
+ function directRendererInstaller() {
876
+ return `(async () => {
877
+ const selected = ${FIND_REQUEST_MANAGER_EXPRESSION};
878
+ if (
879
+ selected.candidateCount !== 1 ||
880
+ typeof selected.hostId !== 'string' ||
881
+ selected.hostId.length === 0 ||
882
+ selected.manager == null ||
883
+ selected.requestClient == null
884
+ ) {
885
+ throw new Error('Renderer request manager is ambiguous');
886
+ }
887
+ if (selected.prewarmedThreadManager == null) {
888
+ throw new Error('Renderer prewarmed Thread manager is unavailable');
889
+ }
890
+ return (${installDraftPrewarmPolicyBridge.toString()})(
891
+ selected.manager,
892
+ selected.requestClient,
893
+ selected.hostId,
894
+ window,
895
+ selected.prewarmedThreadManager,
1207
896
  );
1208
- }`;
897
+ })()`;
1209
898
  }
1210
- async function installRendererDraftPrewarmPolicy(inspector, rendererWebContentsId) {
1211
- if (!Number.isInteger(rendererWebContentsId) || rendererWebContentsId <= 0) {
1212
- throw new Error("Renderer webContents ID must be a positive integer");
1213
- }
1214
- const installer = mainProcessInstaller(rendererWebContentsId);
899
+ async function waitForDraftPrewarmPolicy(evaluate, expression) {
1215
900
  const deadline = Date.now() + REQUEST_MANAGER_WAIT_TIMEOUT_MS;
1216
901
  while (true) {
1217
902
  try {
1218
- const value = await inspector.evaluate(`(${installer})()`);
1219
- if (!isRecord3(value) || value.state !== "ready" || value.reason !== "owned-request-bridge") {
903
+ const value = await evaluate(expression);
904
+ if (!isRecord2(value) || value.state !== "ready" || value.reason !== "owned-request-bridge") {
1220
905
  throw new Error("Renderer draft prewarm policy returned an invalid status");
1221
906
  }
1222
907
  return value;
@@ -1230,9 +915,15 @@ async function installRendererDraftPrewarmPolicy(inspector, rendererWebContentsI
1230
915
  }
1231
916
  }
1232
917
  }
918
+ function installRendererDraftPrewarmPolicyDirect(renderer) {
919
+ return waitForDraftPrewarmPolicy(
920
+ (expression) => renderer.evaluate(expression),
921
+ directRendererInstaller()
922
+ );
923
+ }
1233
924
 
1234
- // packages/desktop-control/src/renderer-control-session.ts
1235
- function isRecord4(value) {
925
+ // packages/desktop-control/src/renderer-cdp-control-session.ts
926
+ function isRecord3(value) {
1236
927
  return typeof value === "object" && value !== null && !Array.isArray(value);
1237
928
  }
1238
929
  function sleep(milliseconds) {
@@ -1241,6 +932,20 @@ function sleep(milliseconds) {
1241
932
  function sameAgents(actual, expected) {
1242
933
  return actual.length === expected.length && actual.every((agent, index) => agent === expected[index]);
1243
934
  }
935
+ function isPrimaryRendererUrl(value) {
936
+ try {
937
+ const url = new URL(value);
938
+ return url.protocol === "app:" && url.hostname === "-" && url.pathname === "/index.html" && url.search === "" && url.hash === "";
939
+ } catch {
940
+ return false;
941
+ }
942
+ }
943
+ function selectPrimaryRendererTarget(targets, preferredTargetId) {
944
+ const candidates = targets.filter(
945
+ (target) => target.type === "page" && isPrimaryRendererUrl(target.url)
946
+ );
947
+ return candidates.find((target) => target.id === preferredTargetId) ?? candidates.at(0) ?? null;
948
+ }
1244
949
  var RendererAdapterReadinessError = class extends Error {
1245
950
  constructor(state, reason) {
1246
951
  super(`Production Renderer Adapter is ${state}: ${reason}`);
@@ -1252,7 +957,7 @@ var RendererAdapterReadinessError = class extends Error {
1252
957
  reason;
1253
958
  };
1254
959
  function validateBindingStatus(value, expectedAgents) {
1255
- if (!isRecord4(value) || value.version !== 2 || !Array.isArray(value.enabledAgents) || value.enabledAgents.some((agent) => typeof agent !== "string") || !sameAgents(value.enabledAgents, expectedAgents) || !isRecord4(value.adapter)) {
960
+ if (!isRecord3(value) || value.version !== 2 || !Array.isArray(value.enabledAgents) || value.enabledAgents.some((agent) => typeof agent !== "string") || !sameAgents(value.enabledAgents, expectedAgents) || !isRecord3(value.adapter)) {
1256
961
  throw new Error("Production Renderer binding returned an invalid status");
1257
962
  }
1258
963
  if (value.adapter.state !== "ready" || typeof value.adapter.reason !== "string") {
@@ -1262,161 +967,45 @@ function validateBindingStatus(value, expectedAgents) {
1262
967
  }
1263
968
  return value;
1264
969
  }
1265
- function selectRendererWebContents(contents, preferredRendererId) {
1266
- const candidates = contents.filter(
1267
- (item) => item.type === "window" && item.surface === "primary" && item.runtime.available && item.runtime.elementCount !== null
1268
- ).toSorted(
1269
- (left, right) => (right.runtime.elementCount ?? 0) - (left.runtime.elementCount ?? 0)
1270
- );
1271
- const preferred = candidates.find(
1272
- (candidate) => candidate.id === preferredRendererId && (candidate.runtime.elementCount ?? 0) > 0
1273
- );
1274
- if (preferred) return preferred;
1275
- return candidates.find((candidate) => (candidate.runtime.elementCount ?? 0) > 0) ?? null;
1276
- }
1277
- async function waitForRendererTitlePolicyReady(markReadiness, options = {}) {
1278
- const timeoutMs = options.timeoutMs ?? 3e4;
1279
- const pollIntervalMs = options.pollIntervalMs ?? 250;
1280
- const now = options.now ?? Date.now;
1281
- const wait = options.sleep ?? sleep;
1282
- const deadline = now() + timeoutMs;
1283
- let lastError;
1284
- while (now() < deadline) {
1285
- try {
1286
- return await markReadiness();
1287
- } catch (error) {
1288
- lastError = error;
1289
- }
1290
- await wait(pollIntervalMs);
1291
- }
1292
- const detail = lastError instanceof Error ? `: ${lastError.message}` : "";
1293
- throw new Error(`Renderer title policy ownership did not become ready${detail}`);
1294
- }
1295
- async function waitForInspectorTarget(endpoint, options = {}) {
1296
- const timeoutMs = options.timeoutMs ?? 3e4;
1297
- const pollIntervalMs = options.pollIntervalMs ?? 250;
970
+ async function waitForPrimaryTarget(endpoint, operations, timeoutMs, pollIntervalMs, preferredTargetId) {
1298
971
  const deadline = Date.now() + timeoutMs;
1299
972
  let lastError;
1300
973
  while (Date.now() < deadline) {
1301
974
  try {
1302
- const targets = await listCdpTargets(endpoint, options.fetchImpl);
1303
- const inspector = targets.find((target) => target.type === "node");
1304
- if (inspector) return inspector;
1305
- lastError = new Error("Inspector has no Node target");
975
+ const target = selectPrimaryRendererTarget(
976
+ await operations.listTargets(endpoint),
977
+ preferredTargetId
978
+ );
979
+ if (target) return target;
980
+ lastError = new Error("Renderer CDP has no primary app://-/index.html page target");
1306
981
  } catch (error) {
1307
982
  lastError = error;
1308
983
  }
1309
984
  await sleep(pollIntervalMs);
1310
985
  }
1311
986
  const detail = lastError instanceof Error ? `: ${lastError.message}` : "";
1312
- throw new Error(`Electron main-process Inspector did not become ready${detail}`);
987
+ throw new Error(`Primary Codex Renderer CDP target did not become ready${detail}`);
1313
988
  }
1314
- var electronModuleExpression = `(() => {
1315
- const mainModule = process.mainModule;
1316
- if (mainModule != null && typeof mainModule.require === 'function') {
1317
- return mainModule.require('electron');
1318
- }
1319
- const { createRequire } = process.getBuiltinModule('module');
1320
- return createRequire(process.execPath)('electron');
1321
- })()`;
1322
- var webContentsRuntimeExpression = "(() => ({ elementCount: document.querySelectorAll('*').length }))()";
1323
- async function inspectElectronWebContents(inspector) {
1324
- const value = await inspector.evaluate(`(async () => {
1325
- const { webContents } = ${electronModuleExpression};
1326
- const result = await Promise.all(webContents.getAllWebContents().map(async (contents) => {
1327
- let runtime = { available: false, elementCount: null };
1328
- try {
1329
- const evaluation = contents.executeJavaScript(${JSON.stringify(webContentsRuntimeExpression)}, true);
1330
- const timeout = new Promise((_, reject) => {
1331
- setTimeout(() => reject(new Error('Renderer inspection timed out')), 2_000);
1332
- });
1333
- runtime = { available: true, ...(await Promise.race([evaluation, timeout])) };
1334
- } catch {}
1335
- return {
1336
- id: contents.id,
1337
- type: contents.getType(),
1338
- surface: contents.getURL().includes('avatar-overlay') ? 'overlay' : 'primary',
1339
- runtime,
1340
- };
1341
- }));
1342
- return result;
1343
- })()`);
1344
- if (!Array.isArray(value)) throw new Error("Electron webContents inspection returned an array");
1345
- return value.map((item) => {
1346
- if (!isRecord4(item) || !Number.isInteger(item.id) || typeof item.type !== "string" || !["primary", "overlay"].includes(String(item.surface)) || !isRecord4(item.runtime)) {
1347
- throw new Error("Electron webContents inspection returned an invalid item");
1348
- }
1349
- return {
1350
- id: item.id,
1351
- type: item.type,
1352
- surface: item.surface,
1353
- runtime: {
1354
- available: item.runtime.available === true,
1355
- elementCount: Number.isInteger(item.runtime.elementCount) ? item.runtime.elementCount : null
1356
- }
1357
- };
989
+ async function evaluateSource(renderer, source) {
990
+ const response = await renderer.command("Runtime.evaluate", {
991
+ expression: source,
992
+ awaitPromise: true
1358
993
  });
1359
- }
1360
- async function activateElectronDesktop(inspector) {
1361
- const value = await inspector.evaluate(`(() => {
1362
- const { BrowserWindow } = ${electronModuleExpression};
1363
- const windows = BrowserWindow.getAllWindows().filter((window) => !window.isDestroyed());
1364
- for (const window of windows) {
1365
- if (window.isMinimized()) window.restore();
1366
- window.show();
1367
- window.focus();
1368
- }
1369
- return windows.length;
1370
- })()`);
1371
- if (!Number.isInteger(value) || value < 1) {
1372
- throw new Error("Electron Desktop activation found no live window");
994
+ if (!isRecord3(response)) throw new Error("Renderer source evaluation returned an invalid result");
995
+ if (isRecord3(response.exceptionDetails)) {
996
+ const text = typeof response.exceptionDetails.text === "string" ? response.exceptionDetails.text : "Renderer source evaluation failed";
997
+ throw new Error(text);
1373
998
  }
1374
- return value;
1375
- }
1376
- async function executeInWebContents(inspector, rendererWebContentsId, source) {
1377
- return inspector.evaluate(`(async () => {
1378
- const { webContents } = ${electronModuleExpression};
1379
- const contents = webContents.fromId(${rendererWebContentsId});
1380
- if (contents == null || contents.isDestroyed()) throw new Error('Renderer webContents is unavailable');
1381
- const result = await contents.executeJavaScript(${JSON.stringify(source)}, true);
1382
- return result === undefined ? null : result;
1383
- })()`);
1384
999
  }
1385
- async function reloadRenderer(inspector, rendererWebContentsId) {
1386
- await executeInWebContents(inspector, rendererWebContentsId, "location.reload(); null");
1387
- }
1388
- var defaultOperations = {
1389
- inspect: inspectElectronWebContents,
1390
- installTitlePolicy: installMainProcessTitlePolicy,
1391
- markTitlePolicyReady: markRendererTitlePolicyReady,
1392
- installDraftPrewarmPolicy: installRendererDraftPrewarmPolicy,
1393
- reload: reloadRenderer,
1394
- execute: executeInWebContents,
1395
- readBinding: (inspector, rendererWebContentsId) => executeInWebContents(
1396
- inspector,
1397
- rendererWebContentsId,
1398
- "window.__codexhostRendererBindingProbeV1?.status() ?? null"
1399
- ),
1400
- readTitlePolicyCounters: readMainProcessTitlePolicyCounters
1401
- };
1402
- async function waitForRenderer(inspector, operations, timeoutMs, pollIntervalMs, preferredRendererId) {
1403
- const deadline = Date.now() + timeoutMs;
1404
- let candidateCount = 0;
1405
- while (Date.now() < deadline) {
1406
- const inventory = await operations.inspect(inspector);
1407
- candidateCount = inventory.length;
1408
- const renderer = selectRendererWebContents(inventory, preferredRendererId);
1409
- if (renderer) return renderer;
1410
- await sleep(pollIntervalMs);
1411
- }
1412
- throw new Error(`Inspector did not find a live Electron Renderer (${candidateCount} seen)`);
1000
+ async function readBinding(renderer) {
1001
+ return renderer.evaluate("window.__codexhostRendererBindingProbeV1?.status() ?? null");
1413
1002
  }
1414
- async function waitForBinding(inspector, operations, rendererWebContentsId, enabledAgents, timeoutMs, pollIntervalMs) {
1003
+ async function waitForBinding(renderer, enabledAgents, timeoutMs, pollIntervalMs) {
1415
1004
  const deadline = Date.now() + timeoutMs;
1416
1005
  let lastError;
1417
1006
  while (Date.now() < deadline) {
1418
1007
  try {
1419
- const value = await operations.readBinding(inspector, rendererWebContentsId);
1008
+ const value = await readBinding(renderer);
1420
1009
  if (value !== null) return validateBindingStatus(value, enabledAgents);
1421
1010
  } catch (error) {
1422
1011
  lastError = error;
@@ -1429,218 +1018,163 @@ async function waitForBinding(inspector, operations, rendererWebContentsId, enab
1429
1018
  const detail = lastError instanceof Error ? `: ${lastError.message}` : "";
1430
1019
  throw new Error(`Production Renderer binding did not become ready${detail}`);
1431
1020
  }
1432
- var InstalledRendererControlSession = class {
1433
- constructor(inspector, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, snapshot) {
1434
- this.inspector = inspector;
1021
+ async function installTarget(target, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations) {
1022
+ const renderer = await operations.connect(target.webSocketDebuggerUrl);
1023
+ try {
1024
+ await renderer.command("Runtime.enable");
1025
+ await renderer.command("Page.enable");
1026
+ await renderer.command("Page.addScriptToEvaluateOnNewDocument", { source: rendererSource });
1027
+ await evaluateSource(renderer, rendererSource);
1028
+ const draftPrewarmPolicy = await operations.installDraftPrewarmPolicy(renderer);
1029
+ const binding = await waitForBinding(renderer, enabledAgents, timeoutMs, pollIntervalMs);
1030
+ return { renderer, snapshot: { target, draftPrewarmPolicy, binding } };
1031
+ } catch (error) {
1032
+ renderer.close();
1033
+ throw error;
1034
+ }
1035
+ }
1036
+ var InstalledRendererCdpControlSession = class {
1037
+ constructor(renderer, rendererCdpEndpoint2, rendererSource, enabledAgents, timeoutMs, pollIntervalMs, operations, currentSnapshot) {
1038
+ this.renderer = renderer;
1039
+ this.rendererCdpEndpoint = rendererCdpEndpoint2;
1435
1040
  this.rendererSource = rendererSource;
1436
1041
  this.enabledAgents = enabledAgents;
1437
1042
  this.timeoutMs = timeoutMs;
1438
1043
  this.pollIntervalMs = pollIntervalMs;
1439
1044
  this.operations = operations;
1440
- this.#snapshot = snapshot;
1045
+ this.currentSnapshot = currentSnapshot;
1441
1046
  }
1442
- inspector;
1047
+ renderer;
1048
+ rendererCdpEndpoint;
1443
1049
  rendererSource;
1444
1050
  enabledAgents;
1445
1051
  timeoutMs;
1446
1052
  pollIntervalMs;
1447
1053
  operations;
1054
+ currentSnapshot;
1448
1055
  #closed = false;
1449
- #snapshot;
1450
1056
  get snapshot() {
1451
- return this.#snapshot;
1057
+ return this.currentSnapshot;
1452
1058
  }
1453
1059
  async ensureInstalled() {
1454
- if (this.#closed) throw new Error("Renderer Control Session is closed");
1455
- const selected = await waitForRenderer(
1456
- this.inspector,
1060
+ if (this.#closed) throw new Error("Renderer CDP Control Session is closed");
1061
+ const target = await waitForPrimaryTarget(
1062
+ this.rendererCdpEndpoint,
1457
1063
  this.operations,
1458
1064
  this.timeoutMs,
1459
1065
  this.pollIntervalMs,
1460
- this.#snapshot.renderer.id
1066
+ this.currentSnapshot.target.id
1461
1067
  );
1462
- const existing = await this.operations.readBinding(this.inspector, selected.id).catch(() => null);
1463
- if (existing !== null) {
1464
- const draftPrewarmPolicy2 = await this.operations.installDraftPrewarmPolicy(
1465
- this.inspector,
1466
- selected.id
1068
+ if (target.id !== this.currentSnapshot.target.id) {
1069
+ const replacement = await installTarget(
1070
+ target,
1071
+ this.rendererSource,
1072
+ this.enabledAgents,
1073
+ this.timeoutMs,
1074
+ this.pollIntervalMs,
1075
+ this.operations
1467
1076
  );
1468
- let binding2;
1469
- try {
1470
- binding2 = validateBindingStatus(existing, this.enabledAgents);
1471
- } catch (error) {
1472
- if (!(error instanceof RendererAdapterReadinessError)) throw error;
1473
- await this.operations.execute(this.inspector, selected.id, this.rendererSource);
1474
- binding2 = await waitForBinding(
1475
- this.inspector,
1476
- this.operations,
1477
- selected.id,
1478
- this.enabledAgents,
1479
- this.timeoutMs,
1480
- this.pollIntervalMs
1481
- );
1482
- }
1483
- this.#snapshot = {
1484
- ...this.#snapshot,
1485
- renderer: selected,
1486
- draftPrewarmPolicy: draftPrewarmPolicy2,
1487
- binding: binding2
1488
- };
1489
- return this.#snapshot;
1077
+ this.renderer.close();
1078
+ this.renderer = replacement.renderer;
1079
+ this.currentSnapshot = replacement.snapshot;
1080
+ return this.currentSnapshot;
1081
+ }
1082
+ try {
1083
+ const existing = await readBinding(this.renderer);
1084
+ if (existing === null) await evaluateSource(this.renderer, this.rendererSource);
1085
+ else validateBindingStatus(existing, this.enabledAgents);
1086
+ const draftPrewarmPolicy = await this.operations.installDraftPrewarmPolicy(this.renderer);
1087
+ const binding = await waitForBinding(
1088
+ this.renderer,
1089
+ this.enabledAgents,
1090
+ this.timeoutMs,
1091
+ this.pollIntervalMs
1092
+ );
1093
+ this.currentSnapshot = { target, draftPrewarmPolicy, binding };
1094
+ return this.currentSnapshot;
1095
+ } catch {
1096
+ const replacement = await installTarget(
1097
+ target,
1098
+ this.rendererSource,
1099
+ this.enabledAgents,
1100
+ this.timeoutMs,
1101
+ this.pollIntervalMs,
1102
+ this.operations
1103
+ );
1104
+ this.renderer.close();
1105
+ this.renderer = replacement.renderer;
1106
+ this.currentSnapshot = replacement.snapshot;
1107
+ return this.currentSnapshot;
1490
1108
  }
1491
- const titlePolicyReadiness = await waitForRendererTitlePolicyReady(
1492
- () => this.operations.markTitlePolicyReady(this.inspector, selected.id),
1493
- { timeoutMs: this.timeoutMs, pollIntervalMs: this.pollIntervalMs }
1494
- );
1495
- await activateElectronDesktop(this.inspector);
1496
- await this.operations.execute(this.inspector, selected.id, this.rendererSource);
1497
- const draftPrewarmPolicy = await this.operations.installDraftPrewarmPolicy(
1498
- this.inspector,
1499
- selected.id
1500
- );
1501
- const binding = await waitForBinding(
1502
- this.inspector,
1503
- this.operations,
1504
- selected.id,
1505
- this.enabledAgents,
1506
- this.timeoutMs,
1507
- this.pollIntervalMs
1508
- );
1509
- this.#snapshot = {
1510
- ...this.#snapshot,
1511
- renderer: selected,
1512
- titlePolicyReadiness,
1513
- draftPrewarmPolicy,
1514
- binding
1515
- };
1516
- return this.#snapshot;
1517
1109
  }
1518
- activateDesktop() {
1519
- if (this.#closed) return Promise.reject(new Error("Renderer Control Session is closed"));
1520
- return activateElectronDesktop(this.inspector);
1110
+ async activateDesktop() {
1111
+ if (this.#closed) throw new Error("Renderer CDP Control Session is closed");
1112
+ await this.renderer.command("Page.bringToFront");
1113
+ return 1;
1521
1114
  }
1522
1115
  executeRenderer(expression) {
1523
- if (this.#closed) return Promise.reject(new Error("Renderer Control Session is closed"));
1524
- return this.operations.execute(
1525
- this.inspector,
1526
- this.#snapshot.renderer.id,
1527
- expression
1528
- );
1529
- }
1530
- readTitlePolicyCounters() {
1531
- if (this.#closed) return Promise.reject(new Error("Renderer Control Session is closed"));
1532
- return this.operations.readTitlePolicyCounters(this.inspector);
1116
+ if (this.#closed) return Promise.reject(new Error("Renderer CDP Control Session is closed"));
1117
+ return this.renderer.evaluate(expression);
1533
1118
  }
1534
1119
  close() {
1535
1120
  if (this.#closed) return;
1536
1121
  this.#closed = true;
1537
- this.inspector.close();
1122
+ this.renderer.close();
1538
1123
  }
1539
1124
  };
1540
- var startupTraceStartedAt = Date.now();
1541
- function startupTrace(stage) {
1542
- if (process.env.CODEXHOST_STARTUP_TRACE !== "1") return;
1543
- console.error(
1544
- `[codexhost startup +${Date.now() - startupTraceStartedAt}ms] renderer-session: ${stage}`
1545
- );
1546
- }
1547
- async function createRendererControlSession(options) {
1125
+ var defaultOperations = {
1126
+ listTargets: (endpoint) => listCdpTargets(endpoint),
1127
+ connect: (webSocketDebuggerUrl) => CdpClient.connect(webSocketDebuggerUrl),
1128
+ installDraftPrewarmPolicy: installRendererDraftPrewarmPolicyDirect
1129
+ };
1130
+ async function createRendererCdpControlSession(options) {
1548
1131
  const enabledAgents = options.enabledAgents ?? ["codex", "pi"];
1549
1132
  const timeoutMs = options.timeoutMs ?? 3e4;
1550
1133
  const pollIntervalMs = options.pollIntervalMs ?? 250;
1551
1134
  const operations = options.operations ?? defaultOperations;
1552
- startupTrace("waiting for initial Renderer");
1553
- const initial = await waitForRenderer(options.inspector, operations, timeoutMs, pollIntervalMs);
1554
- startupTrace("installing title policy");
1555
- const titlePolicy = await operations.installTitlePolicy(options.inspector, initial.id);
1556
- startupTrace("reloading Renderer");
1557
- await operations.reload(options.inspector, initial.id);
1558
- startupTrace("waiting for reloaded Renderer");
1559
- const selected = await waitForRenderer(
1560
- options.inspector,
1135
+ const target = await waitForPrimaryTarget(
1136
+ options.rendererCdpEndpoint,
1561
1137
  operations,
1562
1138
  timeoutMs,
1563
- pollIntervalMs,
1564
- initial.id
1565
- );
1566
- startupTrace("waiting for title policy readiness");
1567
- const titlePolicyReadiness = await waitForRendererTitlePolicyReady(
1568
- () => operations.markTitlePolicyReady(options.inspector, selected.id),
1569
- {
1570
- timeoutMs,
1571
- pollIntervalMs
1572
- }
1573
- );
1574
- startupTrace("injecting Renderer bundle");
1575
- await operations.execute(options.inspector, selected.id, options.rendererSource);
1576
- startupTrace("installing draft routing policy");
1577
- const draftPrewarmPolicy = await operations.installDraftPrewarmPolicy(
1578
- options.inspector,
1579
- selected.id
1139
+ pollIntervalMs
1580
1140
  );
1581
- startupTrace("waiting for Renderer binding");
1582
- const binding = await waitForBinding(
1583
- options.inspector,
1584
- operations,
1585
- selected.id,
1141
+ const installed = await installTarget(
1142
+ target,
1143
+ options.rendererSource,
1586
1144
  enabledAgents,
1587
1145
  timeoutMs,
1588
- pollIntervalMs
1146
+ pollIntervalMs,
1147
+ operations
1589
1148
  );
1590
- return new InstalledRendererControlSession(
1591
- options.inspector,
1149
+ return new InstalledRendererCdpControlSession(
1150
+ installed.renderer,
1151
+ options.rendererCdpEndpoint,
1592
1152
  options.rendererSource,
1593
1153
  enabledAgents,
1594
1154
  timeoutMs,
1595
1155
  pollIntervalMs,
1596
1156
  operations,
1597
- {
1598
- renderer: selected,
1599
- titlePolicy,
1600
- titlePolicyReadiness,
1601
- draftPrewarmPolicy,
1602
- binding
1603
- }
1157
+ installed.snapshot
1604
1158
  );
1605
1159
  }
1606
- async function installRendererControlSession(options) {
1607
- const timeoutMs = options.timeoutMs ?? 3e4;
1608
- const pollIntervalMs = options.pollIntervalMs ?? 250;
1609
- startupTrace("waiting for Electron Inspector target");
1610
- const target = await waitForInspectorTarget(options.inspectorEndpoint, {
1611
- timeoutMs,
1612
- pollIntervalMs
1613
- });
1614
- startupTrace("connecting to Electron Inspector");
1615
- const inspector = await CdpClient.connect(target.webSocketDebuggerUrl);
1616
- try {
1617
- startupTrace("enabling Inspector Runtime domain");
1618
- await inspector.command("Runtime.enable");
1619
- return await createRendererControlSession({
1620
- ...options,
1621
- inspector,
1622
- timeoutMs,
1623
- pollIntervalMs
1624
- });
1625
- } catch (error) {
1626
- inspector.close();
1627
- throw error;
1628
- }
1160
+ function installRendererCdpControlSession(options) {
1161
+ return createRendererCdpControlSession(options);
1629
1162
  }
1630
1163
 
1631
1164
  // packages/desktop-control/src/production-controller.ts
1632
1165
  var PRODUCTION_INSTALL_TIMEOUT_MS = 9e4;
1166
+ var RENDERER_CSP_BOOTSTRAP = "globalThis.__zod_globalConfig ??= {}; globalThis.__zod_globalConfig.jitless = true;";
1633
1167
  var DESKTOP_CONTROLLER_READINESS_MAX_BYTES = 512;
1634
1168
  var TRANSIENT_INSTALL_ATTEMPTS = 3;
1635
1169
  var TRANSIENT_INSTALL_RETRY_MS = 250;
1636
1170
  var RECOVERY_RETRY_INITIAL_MS = 3e4;
1637
1171
  var RECOVERY_RETRY_MAX_MS = 3e5;
1638
- var startupTraceStartedAt2 = Date.now();
1639
- function startupTrace2(stage, detail) {
1172
+ var startupTraceStartedAt = Date.now();
1173
+ function startupTrace(stage, detail) {
1640
1174
  if (process.env.CODEXHOST_STARTUP_TRACE !== "1") return;
1641
1175
  const suffix = detail === void 0 ? "" : `: ${detail instanceof Error ? detail.message : String(detail)}`;
1642
1176
  console.error(
1643
- `[codexhost startup +${Date.now() - startupTraceStartedAt2}ms] controller: ${stage}${suffix}`
1177
+ `[codexhost startup +${Date.now() - startupTraceStartedAt}ms] controller: ${stage}${suffix}`
1644
1178
  );
1645
1179
  }
1646
1180
  function serializeDesktopControllerReadiness(readiness) {
@@ -1655,7 +1189,7 @@ function serializeDesktopControllerReadiness(readiness) {
1655
1189
  }
1656
1190
  var defaultDependencies = {
1657
1191
  readRenderer: (filePath) => readFile(filePath, "utf8"),
1658
- install: installRendererControlSession,
1192
+ install: installRendererCdpControlSession,
1659
1193
  startAttachmentServer: startControllerAttachmentServer,
1660
1194
  ready: (readiness) => {
1661
1195
  process.stdout.write(`${serializeDesktopControllerReadiness(readiness)}
@@ -1664,10 +1198,10 @@ var defaultDependencies = {
1664
1198
  sleep: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
1665
1199
  monitorIntervalMs: 500
1666
1200
  };
1667
- function inspectorEndpoint(value) {
1201
+ function rendererCdpEndpoint(value) {
1668
1202
  const url = new URL(value);
1669
1203
  if (url.protocol !== "http:" || !["127.0.0.1", "localhost", "[::1]"].includes(url.hostname) || !url.port || url.username || url.password || url.pathname !== "/" && url.pathname !== "" || url.search || url.hash) {
1670
- throw new Error("--inspector-endpoint must be a loopback HTTP origin with an explicit port");
1204
+ throw new Error("--renderer-cdp-endpoint must be a loopback HTTP origin with an explicit port");
1671
1205
  }
1672
1206
  return url.origin;
1673
1207
  }
@@ -1680,10 +1214,12 @@ function parseDesktopControllerArguments(arguments_) {
1680
1214
  for (let index = 0; index < arguments_.length; index += 1) {
1681
1215
  const argument = arguments_[index];
1682
1216
  const value = arguments_[index + 1];
1683
- if (argument === "--inspector-endpoint") {
1684
- if (endpoint !== void 0) throw new Error("--inspector-endpoint may only be provided once");
1685
- if (!value) throw new Error("--inspector-endpoint requires a value");
1686
- endpoint = inspectorEndpoint(value);
1217
+ if (argument === "--renderer-cdp-endpoint") {
1218
+ if (endpoint !== void 0) {
1219
+ throw new Error("--renderer-cdp-endpoint may only be provided once");
1220
+ }
1221
+ if (!value) throw new Error("--renderer-cdp-endpoint requires a value");
1222
+ endpoint = rendererCdpEndpoint(value);
1687
1223
  index += 1;
1688
1224
  continue;
1689
1225
  }
@@ -1729,20 +1265,20 @@ function parseDesktopControllerArguments(arguments_) {
1729
1265
  }
1730
1266
  throw new Error(`unknown Desktop Controller option: ${argument}`);
1731
1267
  }
1732
- if (endpoint === void 0) throw new Error("--inspector-endpoint is required");
1268
+ if (endpoint === void 0) throw new Error("--renderer-cdp-endpoint is required");
1733
1269
  if (rendererPath === void 0) throw new Error("--renderer is required");
1734
1270
  if (defaultAgent === void 0) throw new Error("--default-agent is required");
1735
1271
  if (attachmentPort === void 0) throw new Error("--attachment-port is required");
1736
1272
  if (attachmentNonce === void 0) throw new Error("--attachment-nonce is required");
1737
1273
  return {
1738
- inspectorEndpoint: endpoint,
1274
+ rendererCdpEndpoint: endpoint,
1739
1275
  rendererPath,
1740
1276
  defaultAgent,
1741
1277
  attachmentPort,
1742
1278
  attachmentNonce
1743
1279
  };
1744
1280
  }
1745
- function isTransientElectronInstallError(error) {
1281
+ function isTransientRendererInstallError(error) {
1746
1282
  let current = error;
1747
1283
  for (let depth = 0; depth < 4; depth += 1) {
1748
1284
  const message = current instanceof Error ? current.message : String(current);
@@ -1759,7 +1295,7 @@ async function installProductionSession(options, dependencies) {
1759
1295
  try {
1760
1296
  return await dependencies.install(options);
1761
1297
  } catch (error) {
1762
- if (attempt === TRANSIENT_INSTALL_ATTEMPTS || !isTransientElectronInstallError(error)) {
1298
+ if (attempt === TRANSIENT_INSTALL_ATTEMPTS || !isTransientRendererInstallError(error)) {
1763
1299
  throw error;
1764
1300
  }
1765
1301
  await dependencies.sleep(TRANSIENT_INSTALL_RETRY_MS);
@@ -1782,14 +1318,15 @@ async function runDesktopController(options, signal, dependencies = defaultDepen
1782
1318
  recoveryDelayMs = RECOVERY_RETRY_INITIAL_MS;
1783
1319
  };
1784
1320
  const createSession = async () => {
1785
- startupTrace2("reading Renderer bundle");
1321
+ startupTrace("reading Renderer bundle");
1786
1322
  const rendererSource = await dependencies.readRenderer(options.rendererPath);
1787
1323
  if (rendererSource.trim().length === 0) throw new Error("production Renderer Bundle is empty");
1788
- startupTrace2("installing Renderer Session");
1324
+ startupTrace("installing Renderer Session");
1789
1325
  const installed = await installProductionSession(
1790
1326
  {
1791
- inspectorEndpoint: options.inspectorEndpoint,
1792
- rendererSource: `${configuration}
1327
+ rendererCdpEndpoint: options.rendererCdpEndpoint,
1328
+ rendererSource: `${RENDERER_CSP_BOOTSTRAP}
1329
+ ${configuration}
1793
1330
  ${rendererSource}`,
1794
1331
  enabledAgents: [
1795
1332
  "codex",
@@ -1798,21 +1335,22 @@ ${rendererSource}`,
1798
1335
  "deepseek-harness",
1799
1336
  "opencode",
1800
1337
  "grok",
1801
- "omp"
1338
+ "omp",
1339
+ "antigravity"
1802
1340
  ],
1803
1341
  timeoutMs: PRODUCTION_INSTALL_TIMEOUT_MS
1804
1342
  },
1805
1343
  dependencies
1806
1344
  );
1807
- startupTrace2("Renderer Session installed");
1345
+ startupTrace("Renderer Session installed");
1808
1346
  return installed;
1809
1347
  };
1810
- startupTrace2("initialization started");
1348
+ startupTrace("initialization started");
1811
1349
  try {
1812
1350
  session = await createSession();
1813
1351
  recordRecoverySuccess();
1814
1352
  } catch (error) {
1815
- startupTrace2("initial Renderer Session unavailable", error);
1353
+ startupTrace("initial Renderer Session unavailable", error);
1816
1354
  session = void 0;
1817
1355
  recordRecoveryFailure();
1818
1356
  }
@@ -1847,7 +1385,7 @@ ${rendererSource}`,
1847
1385
  };
1848
1386
  let attachmentServer;
1849
1387
  try {
1850
- startupTrace2("starting attachment server");
1388
+ startupTrace("starting attachment server");
1851
1389
  attachmentServer = await dependencies.startAttachmentServer({
1852
1390
  port: options.attachmentPort,
1853
1391
  nonce: options.attachmentNonce,
@@ -1856,8 +1394,8 @@ ${rendererSource}`,
1856
1394
  await current.activateDesktop();
1857
1395
  })
1858
1396
  });
1859
- startupTrace2("attachment server ready");
1860
- startupTrace2("publishing readiness");
1397
+ startupTrace("attachment server ready");
1398
+ startupTrace("publishing readiness");
1861
1399
  dependencies.ready({
1862
1400
  schemaVersion: 2,
1863
1401
  state: "compatible",