@karlorz/codexhost-cli-linux-arm64 0.14.0-0 → 0.14.0-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/cpa-live-voice-hook.js +679 -111
- package/app/desktop-controller.mjs +71 -32
- package/app/host-runtime.mjs +368 -134
- package/app/renderer-extension.js +864 -201
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
|
@@ -14522,6 +14522,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14522
14522
|
|
|
14523
14523
|
// ../shared-contracts/dist/delegation-read.js
|
|
14524
14524
|
var REMOTE_THREAD_REPLY_MAX_BYTES = 16 * 1024 * 1024;
|
|
14525
|
+
var THREAD_REFERENCE_SOURCE_HOST_PARAM = "codexhostSourceHostId";
|
|
14525
14526
|
var delegationReadParamsSchema = external_exports.strictObject({
|
|
14526
14527
|
threadId: external_exports.string().min(1).max(1024),
|
|
14527
14528
|
view: external_exports.enum(["result", "messages"]),
|
|
@@ -15492,6 +15493,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15492
15493
|
/** The text about to be steered; a Harness command always stops and restarts. */
|
|
15493
15494
|
text: external_exports.string().optional()
|
|
15494
15495
|
}).strict();
|
|
15496
|
+
var THREAD_STEER_DELIVERY_PARAM = "codexhostSteerDelivery";
|
|
15495
15497
|
var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
|
|
15496
15498
|
var threadSteeringInspectResultSchema = external_exports.object({
|
|
15497
15499
|
delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
|
|
@@ -16150,13 +16152,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16150
16152
|
}
|
|
16151
16153
|
function resourceNamesFromPerformance(source) {
|
|
16152
16154
|
const target = source ?? (typeof performance === "undefined" ? void 0 : performance);
|
|
16153
|
-
if (!target
|
|
16154
|
-
|
|
16155
|
+
if (!target) return [];
|
|
16156
|
+
const names = [];
|
|
16157
|
+
const push = (name) => {
|
|
16158
|
+
if (typeof name === "string" && name) names.push(name);
|
|
16159
|
+
};
|
|
16160
|
+
if (typeof target.getEntries === "function") {
|
|
16161
|
+
for (const entry of target.getEntries()) push(entry.name);
|
|
16162
|
+
} else if (typeof target.getEntriesByType === "function") {
|
|
16163
|
+
for (const entry of target.getEntriesByType("resource")) push(entry.name);
|
|
16164
|
+
}
|
|
16165
|
+
return names;
|
|
16155
16166
|
}
|
|
16156
16167
|
function loadedAssetNames(root, performanceSource) {
|
|
16157
16168
|
const names = resourceNamesFromPerformance(performanceSource);
|
|
16158
16169
|
if (!root || !("querySelectorAll" in root)) return names;
|
|
16159
|
-
for (const element of root.querySelectorAll(
|
|
16170
|
+
for (const element of root.querySelectorAll(
|
|
16171
|
+
'script[src], link[href], link[rel="modulepreload"], link[rel="preload"]'
|
|
16172
|
+
)) {
|
|
16160
16173
|
const value = element.getAttribute("src") ?? element.getAttribute("href");
|
|
16161
16174
|
if (value) names.push(value);
|
|
16162
16175
|
}
|
|
@@ -16254,8 +16267,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16254
16267
|
const present = profiles.filter(
|
|
16255
16268
|
(profile2) => [profile2.initial, profile2.shared].some((asset) => auditedAppInitialAssetPresent(names, asset))
|
|
16256
16269
|
);
|
|
16270
|
+
if (version2 !== void 0) {
|
|
16271
|
+
const profile2 = profiles.find((entry) => entry.version === version2);
|
|
16272
|
+
if (!profile2) return void 0;
|
|
16273
|
+
if (present.some((entry) => entry.version !== version2)) return void 0;
|
|
16274
|
+
const complete = [profile2.initial, profile2.shared].every(
|
|
16275
|
+
(asset) => auditedAppInitialAssetPresent(names, asset)
|
|
16276
|
+
);
|
|
16277
|
+
return complete || present.length === 0 ? profile2 : void 0;
|
|
16278
|
+
}
|
|
16257
16279
|
const profile = present.length === 1 ? present[0] : void 0;
|
|
16258
|
-
return profile &&
|
|
16280
|
+
return profile && [profile.initial, profile.shared].every((asset) => auditedAppInitialAssetPresent(names, asset)) ? profile : void 0;
|
|
16259
16281
|
}
|
|
16260
16282
|
|
|
16261
16283
|
// src/renderer-chat-voice-debug.ts
|
|
@@ -16279,28 +16301,54 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16279
16301
|
var RENDERER_NEW_THREAD_PREFERENCE_KEY = "codexhost.new-thread-preference.v1";
|
|
16280
16302
|
|
|
16281
16303
|
// src/renderer-client-owned-voice.ts
|
|
16282
|
-
var CLIENT_OWNED_VOICE_VERSION = "26.
|
|
16283
|
-
var CLIENT_OWNED_VOICE_INITIAL_ASSET = "app-initial-
|
|
16284
|
-
var CLIENT_OWNED_VOICE_SHARED_ASSET = "app-shared-
|
|
16285
|
-
var
|
|
16286
|
-
var CLIENT_OWNED_VOICE_OVERLAY_ASSET = "avatar-overlay-native-page-ef8332c6a2fb.js";
|
|
16304
|
+
var CLIENT_OWNED_VOICE_VERSION = "26.1021.31345";
|
|
16305
|
+
var CLIENT_OWNED_VOICE_INITIAL_ASSET = "app-initial-feb30b196d11.js";
|
|
16306
|
+
var CLIENT_OWNED_VOICE_SHARED_ASSET = "app-shared-2cae01273bae.js";
|
|
16307
|
+
var CLIENT_OWNED_VOICE_OVERLAY_ASSET = "avatar-overlay-native-page-d549db3706f1.js";
|
|
16287
16308
|
var CLIENT_OWNED_VOICE_ASSETS = [
|
|
16288
16309
|
{
|
|
16289
16310
|
version: CLIENT_OWNED_VOICE_VERSION,
|
|
16290
16311
|
initial: CLIENT_OWNED_VOICE_INITIAL_ASSET,
|
|
16291
16312
|
shared: CLIENT_OWNED_VOICE_SHARED_ASSET,
|
|
16292
|
-
overlay: CLIENT_OWNED_VOICE_OVERLAY_ASSET
|
|
16313
|
+
overlay: CLIENT_OWNED_VOICE_OVERLAY_ASSET,
|
|
16314
|
+
fetch: "Htr",
|
|
16315
|
+
fetchFrom: "initial",
|
|
16316
|
+
bridge: "bIt",
|
|
16317
|
+
services: "Qot",
|
|
16318
|
+
capabilityInit: "l0n",
|
|
16319
|
+
capabilityFamily: "c0n",
|
|
16320
|
+
inferenceGateFamily: "Cnr"
|
|
16321
|
+
},
|
|
16322
|
+
{
|
|
16323
|
+
version: "26.1016.62342",
|
|
16324
|
+
initial: "app-initial-dddef47d6ef6.js",
|
|
16325
|
+
shared: "app-shared-fc3316d48427.js",
|
|
16326
|
+
overlay: "avatar-overlay-native-page-ef8332c6a2fb.js",
|
|
16327
|
+
init: "Oit",
|
|
16328
|
+
fetch: "Eit",
|
|
16329
|
+
bridge: "AFt",
|
|
16330
|
+
responseError: "Mit",
|
|
16331
|
+
services: "ist",
|
|
16332
|
+
capabilityInit: "njr",
|
|
16333
|
+
capabilityFamily: "tjr",
|
|
16334
|
+
inferenceGateFamily: "uBr"
|
|
16293
16335
|
},
|
|
16294
16336
|
{
|
|
16295
16337
|
version: "26.1016.61520",
|
|
16296
16338
|
initial: "app-initial-c95ddb62696e.js",
|
|
16297
16339
|
shared: "app-shared-2eda13eb7044.js",
|
|
16298
|
-
overlay: "avatar-overlay-native-page-fcc17283519a.js"
|
|
16340
|
+
overlay: "avatar-overlay-native-page-fcc17283519a.js",
|
|
16341
|
+
init: "Oit",
|
|
16342
|
+
fetch: "Eit",
|
|
16343
|
+
bridge: "AFt",
|
|
16344
|
+
responseError: "Mit",
|
|
16345
|
+
services: "ist",
|
|
16346
|
+
capabilityInit: "njr",
|
|
16347
|
+
capabilityFamily: "tjr",
|
|
16348
|
+
inferenceGateFamily: "uBr"
|
|
16299
16349
|
}
|
|
16300
16350
|
];
|
|
16301
16351
|
var SHARED_INIT = "Oit";
|
|
16302
|
-
var SHARED_FETCH = "Eit";
|
|
16303
|
-
var SHARED_BRIDGE = "AFt";
|
|
16304
16352
|
var SHARED_RESPONSE_ERROR = "Mit";
|
|
16305
16353
|
var HOOK_GLOBAL = "__codexhostClientOwnedVoiceV1";
|
|
16306
16354
|
function object2(value) {
|
|
@@ -16357,11 +16405,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16357
16405
|
function visibleWorkComposer(owner) {
|
|
16358
16406
|
const document = owner.document;
|
|
16359
16407
|
if (!document?.querySelectorAll) return false;
|
|
16360
|
-
const
|
|
16408
|
+
const visible = (element) => {
|
|
16361
16409
|
const box = element.getBoundingClientRect?.() ?? { width: 0 };
|
|
16362
16410
|
return box.width > 0 && !element.closest?.("[hidden], [inert]");
|
|
16363
|
-
}
|
|
16364
|
-
return
|
|
16411
|
+
};
|
|
16412
|
+
return [...document.querySelectorAll("[data-codex-composer-root]")].some(visible) && ![...document.querySelectorAll("[data-chatgpt-composer]")].some(visible);
|
|
16365
16413
|
}
|
|
16366
16414
|
function selectedWorkTab(owner) {
|
|
16367
16415
|
const document = owner.document;
|
|
@@ -16411,7 +16459,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16411
16459
|
var lastVoiceProductExperience;
|
|
16412
16460
|
function rememberVoiceProductExperience(request) {
|
|
16413
16461
|
const experience = object2(request) ? request.productExperience : void 0;
|
|
16414
|
-
lastVoiceProductExperience = experience === "chat" || experience === "work" ? experience : void 0;
|
|
16462
|
+
lastVoiceProductExperience = experience === "chat" || experience === "work" || experience === "codex" ? experience : void 0;
|
|
16415
16463
|
}
|
|
16416
16464
|
function lastVoiceLaunchProductExperience() {
|
|
16417
16465
|
return lastVoiceProductExperience;
|
|
@@ -16437,7 +16485,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16437
16485
|
const experience = lastVoiceLaunchProductExperience();
|
|
16438
16486
|
const chat = experience === "chat";
|
|
16439
16487
|
const model2 = backendModelName(options.headers);
|
|
16440
|
-
const work = !chat && (experience === "work" || isWorkBackendModel(model2) || workSurface());
|
|
16488
|
+
const work = !chat && (experience === "work" || experience === "codex" || isWorkBackendModel(model2) || workSurface());
|
|
16441
16489
|
const external = !chat && (model2.startsWith("codexhost/") || externalHarness());
|
|
16442
16490
|
const gateway = external || (work ? workOverride() : chatOverride());
|
|
16443
16491
|
chatVoiceDebug("wham-create", {
|
|
@@ -16529,33 +16577,44 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16529
16577
|
const assets = selectVoiceAssets(CLIENT_OWNED_VOICE_ASSETS, names, config2.desktopVersion);
|
|
16530
16578
|
if (assets) {
|
|
16531
16579
|
try {
|
|
16532
|
-
const
|
|
16580
|
+
const sharedModule = await importModule(`app://-/assets/${assets.shared}`);
|
|
16581
|
+
const fetchFrom = "fetchFrom" in assets ? assets.fetchFrom : "shared";
|
|
16582
|
+
const fetchModule = fetchFrom === "initial" ? await importModule(`app://-/assets/${assets.initial}`) : sharedModule;
|
|
16533
16583
|
if (disposed) return;
|
|
16534
|
-
|
|
16535
|
-
|
|
16536
|
-
const
|
|
16537
|
-
const
|
|
16584
|
+
const init = "init" in assets ? assets.init : SHARED_INIT;
|
|
16585
|
+
const fetchName = assets.fetch;
|
|
16586
|
+
const bridgeName = assets.bridge;
|
|
16587
|
+
const errorName = "responseError" in assets ? assets.responseError : SHARED_RESPONSE_ERROR;
|
|
16588
|
+
if (typeof init === "string" && typeof fetchModule[init] === "function") {
|
|
16589
|
+
fetchModule[init]();
|
|
16590
|
+
} else if (typeof init === "string" && typeof sharedModule[init] === "function") {
|
|
16591
|
+
sharedModule[init]();
|
|
16592
|
+
}
|
|
16593
|
+
const fetchClass = typeof fetchName === "string" ? fetchModule[fetchName] : void 0;
|
|
16594
|
+
const bridgeClass = typeof bridgeName === "string" ? sharedModule[bridgeName] : void 0;
|
|
16538
16595
|
if (!object2(fetchClass) && typeof fetchClass !== "function") throw new Error();
|
|
16539
16596
|
if (!object2(bridgeClass) && typeof bridgeClass !== "function") throw new Error();
|
|
16540
16597
|
const client = Reflect.get(fetchClass, "getInstance").call(fetchClass);
|
|
16541
16598
|
const bridge = Reflect.get(bridgeClass, "getInstance").call(bridgeClass);
|
|
16542
|
-
|
|
16599
|
+
const responseError = typeof errorName === "string" && typeof sharedModule[errorName] === "function" ? sharedModule[errorName] : async (response) => {
|
|
16600
|
+
throw Object.assign(new Error(await response.text()), { status: response.status });
|
|
16601
|
+
};
|
|
16602
|
+
if (typeof client?.fetch !== "function" || typeof bridge?.dispatchMessage !== "function" || typeof bridge?.subscribe !== "function")
|
|
16543
16603
|
throw new Error();
|
|
16544
16604
|
restore = wrapClientOwnedVoiceFetch(
|
|
16545
16605
|
client,
|
|
16546
16606
|
bridge,
|
|
16547
16607
|
() => cpaLiveVoicePreferenceAllowsInstall(target),
|
|
16548
|
-
|
|
16608
|
+
responseError,
|
|
16549
16609
|
() => chatLiveVoicePreferenceAllowsOverride(target),
|
|
16550
16610
|
() => isWorkComposerSurface(target),
|
|
16551
16611
|
() => isExternalHarnessComposer(target)
|
|
16552
16612
|
);
|
|
16553
16613
|
handle.status = "active";
|
|
16554
16614
|
} catch {
|
|
16555
|
-
handle.status = "unsupported";
|
|
16556
16615
|
}
|
|
16557
|
-
return;
|
|
16558
16616
|
}
|
|
16617
|
+
if (handle.status === "active") return;
|
|
16559
16618
|
if (Date.now() - started >= 6e4) {
|
|
16560
16619
|
handle.status = "unsupported";
|
|
16561
16620
|
return;
|
|
@@ -16566,73 +16625,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16566
16625
|
return handle;
|
|
16567
16626
|
}
|
|
16568
16627
|
|
|
16569
|
-
// src/renderer-overlay-thread-isolation.ts
|
|
16570
|
-
function isRecord2(value) {
|
|
16571
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
16572
|
-
}
|
|
16573
|
-
var BLOCKED_METHODS = /* @__PURE__ */ new Set(["thread/started"]);
|
|
16574
|
-
function isAvatarOverlayHref(href) {
|
|
16575
|
-
try {
|
|
16576
|
-
const url2 = new URL(href);
|
|
16577
|
-
if (url2.pathname === "/avatar-overlay.html") return true;
|
|
16578
|
-
return url2.searchParams.get("initialRoute") === "/avatar-overlay";
|
|
16579
|
-
} catch {
|
|
16580
|
-
return false;
|
|
16581
|
-
}
|
|
16582
|
-
}
|
|
16583
|
-
function overlayBlocksHostNotification(method, threadId, allowedRealtimeThreadIds) {
|
|
16584
|
-
if (method.startsWith("thread/realtime/")) {
|
|
16585
|
-
return false;
|
|
16586
|
-
}
|
|
16587
|
-
if (threadId !== void 0 && allowedRealtimeThreadIds.has(threadId)) {
|
|
16588
|
-
return false;
|
|
16589
|
-
}
|
|
16590
|
-
if (BLOCKED_METHODS.has(method)) return true;
|
|
16591
|
-
return method.startsWith("turn/") || method.startsWith("item/");
|
|
16592
|
-
}
|
|
16593
|
-
function notificationThreadId(params) {
|
|
16594
|
-
if (!isRecord2(params)) return void 0;
|
|
16595
|
-
if (typeof params.threadId === "string" && params.threadId.length > 0) return params.threadId;
|
|
16596
|
-
const thread = params.thread;
|
|
16597
|
-
if (isRecord2(thread) && typeof thread.id === "string" && thread.id.length > 0) {
|
|
16598
|
-
return thread.id;
|
|
16599
|
-
}
|
|
16600
|
-
return void 0;
|
|
16601
|
-
}
|
|
16602
|
-
function installOverlayThreadIsolation(target = typeof globalThis === "undefined" ? null : globalThis) {
|
|
16603
|
-
if (!target || typeof target.addEventListener !== "function") {
|
|
16604
|
-
return { status: "disabled", dispose() {
|
|
16605
|
-
} };
|
|
16606
|
-
}
|
|
16607
|
-
const href = target.location?.href;
|
|
16608
|
-
if (typeof href !== "string" || !isAvatarOverlayHref(href)) {
|
|
16609
|
-
return { status: "disabled", dispose() {
|
|
16610
|
-
} };
|
|
16611
|
-
}
|
|
16612
|
-
const voiceThreadIds = /* @__PURE__ */ new Set();
|
|
16613
|
-
const listener = (event) => {
|
|
16614
|
-
const message = event.data;
|
|
16615
|
-
if (!isRecord2(message) || message.type !== "mcp-notification") return;
|
|
16616
|
-
if (typeof message.method !== "string") return;
|
|
16617
|
-
const threadId = notificationThreadId(message.params);
|
|
16618
|
-
if (message.method === "thread/realtime/started" && threadId) {
|
|
16619
|
-
voiceThreadIds.add(threadId);
|
|
16620
|
-
return;
|
|
16621
|
-
}
|
|
16622
|
-
if (overlayBlocksHostNotification(message.method, threadId, voiceThreadIds)) {
|
|
16623
|
-
event.stopImmediatePropagation();
|
|
16624
|
-
}
|
|
16625
|
-
if (message.method === "thread/deleted" && threadId) voiceThreadIds.delete(threadId);
|
|
16626
|
-
};
|
|
16627
|
-
target.addEventListener("message", listener, true);
|
|
16628
|
-
return {
|
|
16629
|
-
status: "active",
|
|
16630
|
-
dispose() {
|
|
16631
|
-
target.removeEventListener("message", listener, true);
|
|
16632
|
-
}
|
|
16633
|
-
};
|
|
16634
|
-
}
|
|
16635
|
-
|
|
16636
16628
|
// ../desktop-control/dist/renderer-react-ownership.js
|
|
16637
16629
|
function committedReactAncestors(value) {
|
|
16638
16630
|
const MAX_VISITED_FIBERS = 2e5;
|
|
@@ -16713,6 +16705,553 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16713
16705
|
return stack.length > 0 ? exhausted() : [];
|
|
16714
16706
|
}
|
|
16715
16707
|
|
|
16708
|
+
// src/renderer-external-queue.ts
|
|
16709
|
+
function isRecord2(value) {
|
|
16710
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
16711
|
+
}
|
|
16712
|
+
function installRendererExternalQueue(target) {
|
|
16713
|
+
if (!isRecord2(target) || typeof target.getTurnCoordinator !== "function" || typeof target.getConversation !== "function") {
|
|
16714
|
+
return null;
|
|
16715
|
+
}
|
|
16716
|
+
if (typeof target.getStreamRole === "function") return null;
|
|
16717
|
+
const coordinator = target.getTurnCoordinator();
|
|
16718
|
+
const queue = isRecord2(coordinator) ? coordinator.serverQueue : null;
|
|
16719
|
+
if (!isRecord2(queue) || typeof queue.isEnabled !== "function") return null;
|
|
16720
|
+
const descriptor = Object.getOwnPropertyDescriptor(queue, "isEnabled");
|
|
16721
|
+
if (!descriptor?.writable) return null;
|
|
16722
|
+
const original = queue.isEnabled;
|
|
16723
|
+
const getConversation = target.getConversation;
|
|
16724
|
+
const isEnabled = (...args) => {
|
|
16725
|
+
const threadId = args[0];
|
|
16726
|
+
if (typeof threadId === "string") {
|
|
16727
|
+
const conversation = getConversation.call(target, threadId);
|
|
16728
|
+
if (isRecord2(conversation) && conversation.id === threadId && // Reserved transport marker from externalThreadValue, retained by
|
|
16729
|
+
// Desktop in both newly created and hydrated conversation metadata.
|
|
16730
|
+
conversation.modelProvider === "codexhost") {
|
|
16731
|
+
return false;
|
|
16732
|
+
}
|
|
16733
|
+
}
|
|
16734
|
+
return original.apply(queue, args);
|
|
16735
|
+
};
|
|
16736
|
+
queue.isEnabled = isEnabled;
|
|
16737
|
+
return () => {
|
|
16738
|
+
if (queue.isEnabled === isEnabled) Object.defineProperty(queue, "isEnabled", descriptor);
|
|
16739
|
+
};
|
|
16740
|
+
}
|
|
16741
|
+
|
|
16742
|
+
// src/renderer-native-thread.ts
|
|
16743
|
+
function isRecord3(value) {
|
|
16744
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16745
|
+
}
|
|
16746
|
+
async function verifyNativeCodexThread(sendRequest, threadId) {
|
|
16747
|
+
const native = await sendRequest("thread/read", { threadId, includeTurns: false });
|
|
16748
|
+
const thread = isRecord3(native) ? native.thread : null;
|
|
16749
|
+
if (!isRecord3(thread) || thread.id !== threadId || typeof thread.modelProvider !== "string" || !thread.modelProvider || thread.modelProvider === "codexhost" || typeof thread.cliVersion !== "string" || !thread.cliVersion || thread.cliVersion === "codexhost") {
|
|
16750
|
+
throw new Error("Native Thread response cannot establish Codex ownership");
|
|
16751
|
+
}
|
|
16752
|
+
}
|
|
16753
|
+
|
|
16754
|
+
// src/renderer-request-sender.ts
|
|
16755
|
+
function isUnsupportedMethod(error51, method) {
|
|
16756
|
+
if (typeof error51 !== "object" || error51 === null) return false;
|
|
16757
|
+
const code = "code" in error51 ? error51.code : void 0;
|
|
16758
|
+
const message = "message" in error51 ? error51.message : void 0;
|
|
16759
|
+
return code === -32601 || code === -32600 && typeof message === "string" && message.startsWith(`Invalid request: unknown variant \`${method}\``);
|
|
16760
|
+
}
|
|
16761
|
+
|
|
16762
|
+
// src/renderer-external-steering.ts
|
|
16763
|
+
var THREAD_STEERING_INSPECT_METHOD = "codexhost/thread/steering/inspect";
|
|
16764
|
+
var THREAD_OWNERSHIP_LIST_METHOD = "codexhost/thread/ownership/list";
|
|
16765
|
+
function isRecord4(value) {
|
|
16766
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
16767
|
+
}
|
|
16768
|
+
function isManager(value) {
|
|
16769
|
+
return isRecord4(value) && ["sendRequest", "steerTurn", "startTurn", "getTurnCoordinator"].every(
|
|
16770
|
+
(key) => typeof value[key] === "function"
|
|
16771
|
+
);
|
|
16772
|
+
}
|
|
16773
|
+
function inputText(input) {
|
|
16774
|
+
if (!Array.isArray(input)) return "";
|
|
16775
|
+
return input.filter(
|
|
16776
|
+
(item) => isRecord4(item) && typeof item.text === "string"
|
|
16777
|
+
).map((item) => item.text).join("\n");
|
|
16778
|
+
}
|
|
16779
|
+
function queuedFollowUpText(message) {
|
|
16780
|
+
if (!isRecord4(message)) return "";
|
|
16781
|
+
if (typeof message.text === "string" && message.text.trim()) return message.text;
|
|
16782
|
+
const context = message.context;
|
|
16783
|
+
if (isRecord4(context) && typeof context.prompt === "string" && context.prompt.trim()) {
|
|
16784
|
+
return context.prompt;
|
|
16785
|
+
}
|
|
16786
|
+
return "";
|
|
16787
|
+
}
|
|
16788
|
+
function restoreQueuedTurnStartText(manager, params) {
|
|
16789
|
+
if (!isManager(manager) || !isRecord4(params) || typeof params.threadId !== "string")
|
|
16790
|
+
return params;
|
|
16791
|
+
if (inputText(params.input).trim()) return params;
|
|
16792
|
+
const messageId = params.clientUserMessageId;
|
|
16793
|
+
if (typeof messageId !== "string" || !messageId) return params;
|
|
16794
|
+
const coordinator = manager.getTurnCoordinator();
|
|
16795
|
+
if (!isRecord4(coordinator) || typeof coordinator.readMessages !== "function") return params;
|
|
16796
|
+
const messages = coordinator.readMessages.call(coordinator, params.threadId);
|
|
16797
|
+
if (!Array.isArray(messages)) return params;
|
|
16798
|
+
const match = messages.find((message) => isRecord4(message) && message.id === messageId);
|
|
16799
|
+
const text = queuedFollowUpText(match);
|
|
16800
|
+
if (!text) return params;
|
|
16801
|
+
return { ...params, input: [{ type: "text", text, text_elements: [] }] };
|
|
16802
|
+
}
|
|
16803
|
+
function submissionHost(manager) {
|
|
16804
|
+
const coordinator = manager.getTurnCoordinator();
|
|
16805
|
+
const options = isRecord4(coordinator) ? coordinator.options : null;
|
|
16806
|
+
const host = isRecord4(options) ? options.submissionHost : null;
|
|
16807
|
+
if (!isRecord4(host) || typeof host.getActiveTurnId !== "function" || typeof host.hasPendingTurnStart !== "function") {
|
|
16808
|
+
throw new Error("Desktop turn submission binding is unavailable");
|
|
16809
|
+
}
|
|
16810
|
+
return {
|
|
16811
|
+
getActiveTurnId: (threadId) => host.getActiveTurnId.call(host, threadId),
|
|
16812
|
+
hasPendingTurnStart: (threadId) => host.hasPendingTurnStart.call(host, threadId)
|
|
16813
|
+
};
|
|
16814
|
+
}
|
|
16815
|
+
function installSteeringMethods(manager, replacements) {
|
|
16816
|
+
const originalPrototype = Object.getPrototypeOf(manager);
|
|
16817
|
+
const overrides = Object.create(originalPrototype);
|
|
16818
|
+
const names = Object.keys(replacements).filter(
|
|
16819
|
+
(name) => typeof replacements[name] === "function"
|
|
16820
|
+
);
|
|
16821
|
+
const descriptors = new Map(
|
|
16822
|
+
names.map((name) => [name, Object.getOwnPropertyDescriptor(manager, name)])
|
|
16823
|
+
);
|
|
16824
|
+
for (const name of names) {
|
|
16825
|
+
const own = descriptors.get(name);
|
|
16826
|
+
Object.defineProperty(own ? manager : overrides, name, {
|
|
16827
|
+
configurable: own?.configurable ?? true,
|
|
16828
|
+
enumerable: own?.enumerable ?? false,
|
|
16829
|
+
writable: true,
|
|
16830
|
+
value: replacements[name]
|
|
16831
|
+
});
|
|
16832
|
+
}
|
|
16833
|
+
if (names.some((name) => !descriptors.get(name))) {
|
|
16834
|
+
Object.setPrototypeOf(manager, overrides);
|
|
16835
|
+
}
|
|
16836
|
+
return (name) => {
|
|
16837
|
+
const own = descriptors.get(name);
|
|
16838
|
+
const holder = own ? manager : overrides;
|
|
16839
|
+
if (Reflect.get(holder, name) === replacements[name]) {
|
|
16840
|
+
if (own) Object.defineProperty(manager, name, own);
|
|
16841
|
+
else Reflect.deleteProperty(overrides, name);
|
|
16842
|
+
}
|
|
16843
|
+
if (Object.getPrototypeOf(manager) === overrides && names.every((key) => !Object.hasOwn(overrides, key))) {
|
|
16844
|
+
Object.setPrototypeOf(manager, originalPrototype);
|
|
16845
|
+
}
|
|
16846
|
+
};
|
|
16847
|
+
}
|
|
16848
|
+
var INTERRUPTED_QUEUE_REASON = "Interrupted before the steer was accepted.";
|
|
16849
|
+
async function preserveQueuedFollowUps(manager, threadId) {
|
|
16850
|
+
const coordinator = manager.getTurnCoordinator();
|
|
16851
|
+
if (!isRecord4(coordinator) || typeof coordinator.loadMessages !== "function" || typeof coordinator.readMessages !== "function" || typeof coordinator.mutate !== "function") {
|
|
16852
|
+
throw new Error("Desktop follow-up queue binding is unavailable");
|
|
16853
|
+
}
|
|
16854
|
+
await coordinator.loadMessages.call(coordinator, threadId);
|
|
16855
|
+
const messages = coordinator.readMessages.call(coordinator, threadId);
|
|
16856
|
+
if (!Array.isArray(messages)) throw new Error("Desktop follow-up queue is unavailable");
|
|
16857
|
+
const alreadyPaused = new Set(
|
|
16858
|
+
messages.filter((message) => isRecord4(message) && message.pausedReason != null).map((message) => message.id)
|
|
16859
|
+
);
|
|
16860
|
+
return () => {
|
|
16861
|
+
coordinator.mutate.call(coordinator, threadId, (current) => {
|
|
16862
|
+
if (!Array.isArray(current)) return current;
|
|
16863
|
+
return current.map((message) => {
|
|
16864
|
+
if (!isRecord4(message) || alreadyPaused.has(message.id) || message.pausedReason !== INTERRUPTED_QUEUE_REASON)
|
|
16865
|
+
return message;
|
|
16866
|
+
const resumed = { ...message };
|
|
16867
|
+
delete resumed.pausedReason;
|
|
16868
|
+
return resumed;
|
|
16869
|
+
});
|
|
16870
|
+
});
|
|
16871
|
+
};
|
|
16872
|
+
}
|
|
16873
|
+
function installRendererExternalSteering(target, sendTurnStart, prepareTurnInput) {
|
|
16874
|
+
if (!isManager(target)) return null;
|
|
16875
|
+
const manager = target;
|
|
16876
|
+
const originalSteer = manager.steerTurn;
|
|
16877
|
+
const originalSend = manager.sendRequest;
|
|
16878
|
+
const routes = /* @__PURE__ */ new Map();
|
|
16879
|
+
const activeTurnSteers = /* @__PURE__ */ new Map();
|
|
16880
|
+
const pending = /* @__PURE__ */ new Map();
|
|
16881
|
+
let disposed = false;
|
|
16882
|
+
const send = function(method, params, options) {
|
|
16883
|
+
if ((method === "turn/start" || method === "turn/steer") && prepareTurnInput) {
|
|
16884
|
+
params = prepareTurnInput(params);
|
|
16885
|
+
}
|
|
16886
|
+
if (method === "turn/start") params = restoreQueuedTurnStartText(manager, params);
|
|
16887
|
+
const messageId = isRecord4(params) ? params.clientUserMessageId : null;
|
|
16888
|
+
const route = typeof messageId === "string" && isRecord4(params) ? routes.get(`${params.threadId}\0${messageId}`) : void 0;
|
|
16889
|
+
if (method !== "turn/start" || !isRecord4(params) || !route || route.threadId !== params.threadId) {
|
|
16890
|
+
if (method === "turn/start" && sendTurnStart) {
|
|
16891
|
+
return sendTurnStart(params, (input) => {
|
|
16892
|
+
if (disposed) throw new Error("External submission binding was disposed");
|
|
16893
|
+
return originalSend.call(manager, method, input, options);
|
|
16894
|
+
});
|
|
16895
|
+
}
|
|
16896
|
+
if (method === "turn/steer" && isRecord4(params) && typeof params.threadId === "string" && activeTurnSteers.has(params.threadId)) {
|
|
16897
|
+
params = { ...params, [THREAD_STEER_DELIVERY_PARAM]: "activeTurn" };
|
|
16898
|
+
}
|
|
16899
|
+
return originalSend.call(manager, method, params, options);
|
|
16900
|
+
}
|
|
16901
|
+
if (disposed) return Promise.reject(new Error("External steering binding was disposed"));
|
|
16902
|
+
return Promise.resolve(
|
|
16903
|
+
originalSend.call(
|
|
16904
|
+
manager,
|
|
16905
|
+
"turn/steer",
|
|
16906
|
+
{
|
|
16907
|
+
threadId: route.threadId,
|
|
16908
|
+
expectedTurnId: route.expectedTurnId,
|
|
16909
|
+
clientUserMessageId: messageId,
|
|
16910
|
+
input: params.input,
|
|
16911
|
+
additionalContext: params.additionalContext,
|
|
16912
|
+
responsesapiClientMetadata: params.responsesapiClientMetadata,
|
|
16913
|
+
...params[THREAD_REFERENCE_SOURCE_HOST_PARAM] !== void 0 ? { [THREAD_REFERENCE_SOURCE_HOST_PARAM]: params[THREAD_REFERENCE_SOURCE_HOST_PARAM] } : {},
|
|
16914
|
+
[THREAD_STEER_DELIVERY_PARAM]: "newTurn"
|
|
16915
|
+
},
|
|
16916
|
+
options
|
|
16917
|
+
)
|
|
16918
|
+
).then((response) => {
|
|
16919
|
+
if (!isRecord4(response) || typeof response.turnId !== "string" || !response.turnId) {
|
|
16920
|
+
throw new Error("External steering returned no replacement Turn identity");
|
|
16921
|
+
}
|
|
16922
|
+
return {
|
|
16923
|
+
turn: {
|
|
16924
|
+
id: response.turnId,
|
|
16925
|
+
status: "inProgress",
|
|
16926
|
+
items: [],
|
|
16927
|
+
error: null,
|
|
16928
|
+
startedAt: null,
|
|
16929
|
+
completedAt: null,
|
|
16930
|
+
durationMs: null,
|
|
16931
|
+
itemsView: "full"
|
|
16932
|
+
}
|
|
16933
|
+
};
|
|
16934
|
+
});
|
|
16935
|
+
};
|
|
16936
|
+
const inspectDelivery = async (threadId, text) => {
|
|
16937
|
+
try {
|
|
16938
|
+
const response = await originalSend.call(manager, THREAD_STEERING_INSPECT_METHOD, {
|
|
16939
|
+
threadId,
|
|
16940
|
+
...text !== void 0 ? { text } : {}
|
|
16941
|
+
});
|
|
16942
|
+
return threadSteeringInspectResultSchema.parse(response).delivery;
|
|
16943
|
+
} catch (error51) {
|
|
16944
|
+
if (!isUnsupportedMethod(error51, THREAD_STEERING_INSPECT_METHOD)) throw error51;
|
|
16945
|
+
}
|
|
16946
|
+
let ownershipResponse;
|
|
16947
|
+
try {
|
|
16948
|
+
ownershipResponse = await originalSend.call(manager, THREAD_OWNERSHIP_LIST_METHOD, {
|
|
16949
|
+
threadIds: [threadId]
|
|
16950
|
+
});
|
|
16951
|
+
} catch (error51) {
|
|
16952
|
+
if (!isUnsupportedMethod(error51, THREAD_OWNERSHIP_LIST_METHOD)) throw error51;
|
|
16953
|
+
await verifyNativeCodexThread(
|
|
16954
|
+
(method, params) => originalSend.call(manager, method, params),
|
|
16955
|
+
threadId
|
|
16956
|
+
);
|
|
16957
|
+
return "official";
|
|
16958
|
+
}
|
|
16959
|
+
const ownership = threadOwnershipListResultSchema.parse(ownershipResponse);
|
|
16960
|
+
const owner = ownership.threads.find((thread) => thread.threadId === threadId)?.owner;
|
|
16961
|
+
if (!owner) throw new Error("Thread ownership could not be resolved for steering");
|
|
16962
|
+
return owner === "codex" ? "official" : "newTurn";
|
|
16963
|
+
};
|
|
16964
|
+
const steer = async function(...args) {
|
|
16965
|
+
const [
|
|
16966
|
+
threadId,
|
|
16967
|
+
input,
|
|
16968
|
+
restoreMessage,
|
|
16969
|
+
serviceTier,
|
|
16970
|
+
attachments,
|
|
16971
|
+
clientUserMessageId,
|
|
16972
|
+
additionalContext,
|
|
16973
|
+
toolOutput,
|
|
16974
|
+
onMessageAdded
|
|
16975
|
+
] = args;
|
|
16976
|
+
if (typeof threadId !== "string") return originalSteer.apply(manager, args);
|
|
16977
|
+
const role = manager.getStreamRole?.(threadId);
|
|
16978
|
+
if (isRecord4(role) && role.role === "follower") return originalSteer.apply(manager, args);
|
|
16979
|
+
let host = null;
|
|
16980
|
+
let expectedTurnId;
|
|
16981
|
+
try {
|
|
16982
|
+
host = submissionHost(manager);
|
|
16983
|
+
expectedTurnId = host.getActiveTurnId(threadId);
|
|
16984
|
+
} catch {
|
|
16985
|
+
}
|
|
16986
|
+
const text = Array.isArray(input) ? inputText(input) : void 0;
|
|
16987
|
+
const delivery = await inspectDelivery(threadId, text);
|
|
16988
|
+
if (disposed) throw new Error("External steering binding was disposed");
|
|
16989
|
+
if (delivery === "official") return originalSteer.apply(manager, args);
|
|
16990
|
+
if (delivery === "activeTurn") {
|
|
16991
|
+
activeTurnSteers.set(threadId, (activeTurnSteers.get(threadId) ?? 0) + 1);
|
|
16992
|
+
try {
|
|
16993
|
+
return await originalSteer.apply(manager, args);
|
|
16994
|
+
} finally {
|
|
16995
|
+
const remaining = (activeTurnSteers.get(threadId) ?? 1) - 1;
|
|
16996
|
+
if (remaining > 0) activeTurnSteers.set(threadId, remaining);
|
|
16997
|
+
else activeTurnSteers.delete(threadId);
|
|
16998
|
+
}
|
|
16999
|
+
}
|
|
17000
|
+
if (!host) throw new Error("Desktop turn submission binding is unavailable");
|
|
17001
|
+
const currentRole = manager.getStreamRole?.(threadId);
|
|
17002
|
+
if (isRecord4(currentRole) && currentRole.role === "follower")
|
|
17003
|
+
return originalSteer.apply(manager, args);
|
|
17004
|
+
if (!Array.isArray(input) || input.length === 0 || input.some(
|
|
17005
|
+
(item) => !isRecord4(item) || item.type !== "text" || typeof item.text !== "string"
|
|
17006
|
+
) || !input.some((item) => isRecord4(item) && typeof item.text === "string" && item.text.trim())) {
|
|
17007
|
+
throw new Error("External steering requires non-empty text input");
|
|
17008
|
+
}
|
|
17009
|
+
if (toolOutput != null) throw new Error("External steering cannot replace a tool response");
|
|
17010
|
+
if (!isRecord4(restoreMessage) || !isRecord4(restoreMessage.context)) {
|
|
17011
|
+
throw new Error("Desktop steering message context is unavailable");
|
|
17012
|
+
}
|
|
17013
|
+
const messageId = typeof clientUserMessageId === "string" && clientUserMessageId ? clientUserMessageId : typeof restoreMessage.id === "string" && restoreMessage.id ? restoreMessage.id : crypto.randomUUID();
|
|
17014
|
+
const fingerprint = JSON.stringify(input);
|
|
17015
|
+
const existing = pending.get(threadId);
|
|
17016
|
+
if (existing) {
|
|
17017
|
+
if (existing.messageId === messageId && existing.fingerprint === fingerprint)
|
|
17018
|
+
return existing.promise;
|
|
17019
|
+
throw new Error("This Thread is already changing direction");
|
|
17020
|
+
}
|
|
17021
|
+
if (expectedTurnId != null && (typeof expectedTurnId !== "string" || !expectedTurnId)) {
|
|
17022
|
+
throw new Error("Desktop active Turn identity is invalid");
|
|
17023
|
+
}
|
|
17024
|
+
if (expectedTurnId == null && host.hasPendingTurnStart(threadId)) {
|
|
17025
|
+
throw new Error("Previous Turn submission has not been confirmed yet");
|
|
17026
|
+
}
|
|
17027
|
+
const context = restoreMessage.context;
|
|
17028
|
+
const routeKey = `${threadId}\0${messageId}`;
|
|
17029
|
+
if (typeof expectedTurnId === "string") routes.set(routeKey, { threadId, expectedTurnId });
|
|
17030
|
+
const promise2 = Promise.resolve().then(async () => {
|
|
17031
|
+
if (disposed) throw new Error("External steering binding was disposed");
|
|
17032
|
+
const resumeQueue = await preserveQueuedFollowUps(manager, threadId);
|
|
17033
|
+
if (disposed) throw new Error("External steering binding was disposed");
|
|
17034
|
+
const response = await manager.startTurn(
|
|
17035
|
+
threadId,
|
|
17036
|
+
{
|
|
17037
|
+
request: {
|
|
17038
|
+
threadId,
|
|
17039
|
+
input,
|
|
17040
|
+
clientUserMessageId: messageId,
|
|
17041
|
+
additionalContext,
|
|
17042
|
+
responsesapiClientMetadata: restoreMessage.responsesapiClientMetadata,
|
|
17043
|
+
cwd: restoreMessage.cwd,
|
|
17044
|
+
serviceTier,
|
|
17045
|
+
model: null,
|
|
17046
|
+
effort: null,
|
|
17047
|
+
collaborationMode: context.collaborationMode ?? null
|
|
17048
|
+
},
|
|
17049
|
+
context: {
|
|
17050
|
+
attachments: attachments ?? [],
|
|
17051
|
+
commentAttachments: context.commentAttachments ?? [],
|
|
17052
|
+
mcpAppModelContextAttachments: context.mcpAppModelContextAttachments,
|
|
17053
|
+
useAppServerPermissionDefault: true
|
|
17054
|
+
}
|
|
17055
|
+
},
|
|
17056
|
+
onMessageAdded
|
|
17057
|
+
);
|
|
17058
|
+
if (!isRecord4(response) || !isRecord4(response.turn) || typeof response.turn.id !== "string") {
|
|
17059
|
+
throw new Error("Desktop returned no replacement Turn identity");
|
|
17060
|
+
}
|
|
17061
|
+
try {
|
|
17062
|
+
resumeQueue();
|
|
17063
|
+
} catch {
|
|
17064
|
+
console.error("codexhost could not restore follow-up queue state after steering");
|
|
17065
|
+
}
|
|
17066
|
+
return { turnId: response.turn.id };
|
|
17067
|
+
}).finally(() => {
|
|
17068
|
+
routes.delete(routeKey);
|
|
17069
|
+
pending.delete(threadId);
|
|
17070
|
+
});
|
|
17071
|
+
pending.set(threadId, { messageId, fingerprint, promise: promise2 });
|
|
17072
|
+
return promise2;
|
|
17073
|
+
};
|
|
17074
|
+
const originalRole = manager.getStreamRole;
|
|
17075
|
+
const getStreamRole = typeof originalRole === "function" ? (...args) => {
|
|
17076
|
+
const threadId = args[0];
|
|
17077
|
+
if (typeof threadId === "string" && typeof manager.getConversation === "function") {
|
|
17078
|
+
const conversation = manager.getConversation(threadId);
|
|
17079
|
+
if (isRecord4(conversation) && conversation.id === threadId && conversation.modelProvider === "codexhost") {
|
|
17080
|
+
return { role: "owner" };
|
|
17081
|
+
}
|
|
17082
|
+
}
|
|
17083
|
+
return originalRole.apply(manager, args);
|
|
17084
|
+
} : void 0;
|
|
17085
|
+
const restoreMethod = installSteeringMethods(manager, {
|
|
17086
|
+
sendRequest: send,
|
|
17087
|
+
steerTurn: steer,
|
|
17088
|
+
...getStreamRole ? { getStreamRole } : {}
|
|
17089
|
+
});
|
|
17090
|
+
return () => {
|
|
17091
|
+
disposed = true;
|
|
17092
|
+
restoreMethod("steerTurn");
|
|
17093
|
+
if (getStreamRole) restoreMethod("getStreamRole");
|
|
17094
|
+
if (pending.size === 0) {
|
|
17095
|
+
restoreMethod("sendRequest");
|
|
17096
|
+
} else {
|
|
17097
|
+
void Promise.allSettled([...pending.values()].map(({ promise: promise2 }) => promise2)).then(() => {
|
|
17098
|
+
restoreMethod("sendRequest");
|
|
17099
|
+
});
|
|
17100
|
+
}
|
|
17101
|
+
};
|
|
17102
|
+
}
|
|
17103
|
+
|
|
17104
|
+
// src/renderer-overlay-thread-isolation.ts
|
|
17105
|
+
function isRecord5(value) {
|
|
17106
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
17107
|
+
}
|
|
17108
|
+
var BLOCKED_METHODS = /* @__PURE__ */ new Set(["thread/started"]);
|
|
17109
|
+
function isAvatarOverlayHref(href) {
|
|
17110
|
+
try {
|
|
17111
|
+
const url2 = new URL(href);
|
|
17112
|
+
if (url2.pathname === "/avatar-overlay.html") return true;
|
|
17113
|
+
return url2.searchParams.get("initialRoute") === "/avatar-overlay";
|
|
17114
|
+
} catch {
|
|
17115
|
+
return false;
|
|
17116
|
+
}
|
|
17117
|
+
}
|
|
17118
|
+
function overlayBlocksHostNotification(method, threadId, allowedRealtimeThreadIds) {
|
|
17119
|
+
if (method.startsWith("thread/realtime/")) {
|
|
17120
|
+
return false;
|
|
17121
|
+
}
|
|
17122
|
+
if (threadId !== void 0 && allowedRealtimeThreadIds.has(threadId)) {
|
|
17123
|
+
return false;
|
|
17124
|
+
}
|
|
17125
|
+
if (BLOCKED_METHODS.has(method)) return true;
|
|
17126
|
+
return method.startsWith("turn/") || method.startsWith("item/");
|
|
17127
|
+
}
|
|
17128
|
+
function notificationThreadId(params) {
|
|
17129
|
+
if (!isRecord5(params)) return void 0;
|
|
17130
|
+
if (typeof params.threadId === "string" && params.threadId.length > 0) return params.threadId;
|
|
17131
|
+
const thread = params.thread;
|
|
17132
|
+
if (isRecord5(thread) && typeof thread.id === "string" && thread.id.length > 0) {
|
|
17133
|
+
return thread.id;
|
|
17134
|
+
}
|
|
17135
|
+
return void 0;
|
|
17136
|
+
}
|
|
17137
|
+
function installOverlayThreadIsolation(target = typeof globalThis === "undefined" ? null : globalThis) {
|
|
17138
|
+
if (!target || typeof target.addEventListener !== "function") {
|
|
17139
|
+
return { status: "disabled", dispose() {
|
|
17140
|
+
} };
|
|
17141
|
+
}
|
|
17142
|
+
const href = target.location?.href;
|
|
17143
|
+
if (typeof href !== "string" || !isAvatarOverlayHref(href)) {
|
|
17144
|
+
return { status: "disabled", dispose() {
|
|
17145
|
+
} };
|
|
17146
|
+
}
|
|
17147
|
+
const voiceThreadIds = /* @__PURE__ */ new Set();
|
|
17148
|
+
const listener = (event) => {
|
|
17149
|
+
const message = event.data;
|
|
17150
|
+
if (!isRecord5(message) || message.type !== "mcp-notification") return;
|
|
17151
|
+
if (typeof message.method !== "string") return;
|
|
17152
|
+
const threadId = notificationThreadId(message.params);
|
|
17153
|
+
if (message.method === "thread/realtime/started" && threadId) {
|
|
17154
|
+
voiceThreadIds.add(threadId);
|
|
17155
|
+
return;
|
|
17156
|
+
}
|
|
17157
|
+
if (overlayBlocksHostNotification(message.method, threadId, voiceThreadIds)) {
|
|
17158
|
+
event.stopImmediatePropagation();
|
|
17159
|
+
}
|
|
17160
|
+
if (message.method === "thread/deleted" && threadId) voiceThreadIds.delete(threadId);
|
|
17161
|
+
};
|
|
17162
|
+
target.addEventListener("message", listener, true);
|
|
17163
|
+
return {
|
|
17164
|
+
status: "active",
|
|
17165
|
+
dispose() {
|
|
17166
|
+
target.removeEventListener("message", listener, true);
|
|
17167
|
+
}
|
|
17168
|
+
};
|
|
17169
|
+
}
|
|
17170
|
+
|
|
17171
|
+
// src/renderer-overlay-external-followups.ts
|
|
17172
|
+
var DISCOVERY_MS = 6e4;
|
|
17173
|
+
var INTERVAL_MS = 50;
|
|
17174
|
+
var HOOK_WALK_LIMIT = 120;
|
|
17175
|
+
function isRecord6(value) {
|
|
17176
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
17177
|
+
}
|
|
17178
|
+
function isFollowUpManager(value) {
|
|
17179
|
+
return isRecord6(value) && ["sendRequest", "steerTurn", "startTurn", "getTurnCoordinator", "getConversation"].every(
|
|
17180
|
+
(key) => typeof value[key] === "function"
|
|
17181
|
+
);
|
|
17182
|
+
}
|
|
17183
|
+
function managerFromHookState(value) {
|
|
17184
|
+
if (isFollowUpManager(value)) return value;
|
|
17185
|
+
return isRecord6(value) && isFollowUpManager(value.manager) ? value.manager : null;
|
|
17186
|
+
}
|
|
17187
|
+
function overlayFollowUpManagers(document) {
|
|
17188
|
+
const managers = /* @__PURE__ */ new Set();
|
|
17189
|
+
const surfaces = [...document.querySelectorAll("[data-avatar-overlay-native-surface-id]")];
|
|
17190
|
+
const roots = surfaces.length > 0 ? surfaces : [document.documentElement];
|
|
17191
|
+
for (const element of roots) {
|
|
17192
|
+
const key = Object.getOwnPropertyNames(element).find(
|
|
17193
|
+
(name) => name.startsWith("__reactFiber$")
|
|
17194
|
+
);
|
|
17195
|
+
const fiber = key ? Object.getOwnPropertyDescriptor(element, key)?.value : void 0;
|
|
17196
|
+
for (const current of committedReactAncestors(fiber)) {
|
|
17197
|
+
let hook = current.memoizedState;
|
|
17198
|
+
for (let index = 0; hook && index < HOOK_WALK_LIMIT; index += 1) {
|
|
17199
|
+
const manager = managerFromHookState(hook.memoizedState);
|
|
17200
|
+
if (manager) managers.add(manager);
|
|
17201
|
+
hook = hook.next && typeof hook.next === "object" ? hook.next : null;
|
|
17202
|
+
}
|
|
17203
|
+
}
|
|
17204
|
+
}
|
|
17205
|
+
return [...managers];
|
|
17206
|
+
}
|
|
17207
|
+
function installOverlayExternalFollowUps(target = typeof globalThis === "undefined" ? null : globalThis) {
|
|
17208
|
+
const href = target?.location?.href;
|
|
17209
|
+
if (!target || typeof href !== "string" || !isAvatarOverlayHref(href)) {
|
|
17210
|
+
return { status: "disabled", dispose() {
|
|
17211
|
+
} };
|
|
17212
|
+
}
|
|
17213
|
+
const wrapped = /* @__PURE__ */ new WeakSet();
|
|
17214
|
+
const cleanups = /* @__PURE__ */ new Set();
|
|
17215
|
+
let disposed = false;
|
|
17216
|
+
let timer;
|
|
17217
|
+
const started = Date.now();
|
|
17218
|
+
const handle = {
|
|
17219
|
+
status: "pending",
|
|
17220
|
+
dispose() {
|
|
17221
|
+
disposed = true;
|
|
17222
|
+
if (timer !== void 0) target.clearTimeout(timer);
|
|
17223
|
+
for (const cleanup of cleanups) {
|
|
17224
|
+
try {
|
|
17225
|
+
cleanup();
|
|
17226
|
+
} catch {
|
|
17227
|
+
}
|
|
17228
|
+
}
|
|
17229
|
+
cleanups.clear();
|
|
17230
|
+
}
|
|
17231
|
+
};
|
|
17232
|
+
const attempt = () => {
|
|
17233
|
+
if (disposed) return;
|
|
17234
|
+
const document = target.document;
|
|
17235
|
+
if (document) {
|
|
17236
|
+
for (const manager of overlayFollowUpManagers(document)) {
|
|
17237
|
+
if (wrapped.has(manager)) continue;
|
|
17238
|
+
const queue = installRendererExternalQueue(manager);
|
|
17239
|
+
const steering = installRendererExternalSteering(manager);
|
|
17240
|
+
if (!queue && !steering) continue;
|
|
17241
|
+
wrapped.add(manager);
|
|
17242
|
+
if (queue) cleanups.add(queue);
|
|
17243
|
+
if (steering) cleanups.add(steering);
|
|
17244
|
+
handle.status = "active";
|
|
17245
|
+
}
|
|
17246
|
+
}
|
|
17247
|
+
if (disposed || handle.status === "active") return;
|
|
17248
|
+
if (Date.now() - started >= DISCOVERY_MS) return;
|
|
17249
|
+
timer = target.setTimeout(attempt, INTERVAL_MS);
|
|
17250
|
+
};
|
|
17251
|
+
attempt();
|
|
17252
|
+
return handle;
|
|
17253
|
+
}
|
|
17254
|
+
|
|
16716
17255
|
// src/renderer-voice-capability.ts
|
|
16717
17256
|
var INFERENCE_GATE = "3683713372";
|
|
16718
17257
|
var record2 = (value) => value !== null && typeof value === "object";
|
|
@@ -16753,6 +17292,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16753
17292
|
return null;
|
|
16754
17293
|
}
|
|
16755
17294
|
}
|
|
17295
|
+
function isFamily(value) {
|
|
17296
|
+
return record2(value) && record2(value.scope) && typeof value.resolve === "function";
|
|
17297
|
+
}
|
|
17298
|
+
function initializeVoiceCapabilityFamilies(module, assets) {
|
|
17299
|
+
const initialize = module[assets.capabilityInit];
|
|
17300
|
+
if (typeof initialize !== "function") throw new Error("Voice capability initializer unavailable");
|
|
17301
|
+
initialize();
|
|
17302
|
+
const family = module[assets.capabilityFamily];
|
|
17303
|
+
const gates = module[assets.inferenceGateFamily];
|
|
17304
|
+
if (!isFamily(family) || !isFamily(gates))
|
|
17305
|
+
throw new Error("Voice capability families unavailable");
|
|
17306
|
+
return { family, gates };
|
|
17307
|
+
}
|
|
16756
17308
|
function hooks(fiber) {
|
|
16757
17309
|
const result = [];
|
|
16758
17310
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -16764,7 +17316,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16764
17316
|
}
|
|
16765
17317
|
return hook == null ? result : [];
|
|
16766
17318
|
}
|
|
16767
|
-
function bindVoiceCapabilitySubscriptions(currentFibers, family, gates, allowed, realtimeOnly = false) {
|
|
17319
|
+
function bindVoiceCapabilitySubscriptions(currentFibers, family, gates, allowed, realtimeOnly = false, names = ["voice.realtime", "voice.thread"]) {
|
|
16768
17320
|
const fibers = currentFibers();
|
|
16769
17321
|
const restores = [];
|
|
16770
17322
|
const bindings = [];
|
|
@@ -16782,7 +17334,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16782
17334
|
const matches = [...members].filter(([, member]) => member.cacheKey === deps[0]);
|
|
16783
17335
|
if (matches.length !== 1 || typeof matches[0]?.[0] !== "string") continue;
|
|
16784
17336
|
const parameter = JSON.parse(matches[0][0]);
|
|
16785
|
-
if (!record2(parameter) || Object.keys(parameter).some((key) => key !== "name" && key !== "hostId") ||
|
|
17337
|
+
if (!record2(parameter) || Object.keys(parameter).some((key) => key !== "name" && key !== "hostId") || !names.some((name) => parameter.name === name) || realtimeOnly && parameter.name !== "voice.realtime" || parameter.hostId !== void 0 && parameter.hostId !== "local" || parameter.name === "voice.thread" && parameter.hostId !== "local")
|
|
16786
17338
|
continue;
|
|
16787
17339
|
const subscriptions = list.filter((hook2) => {
|
|
16788
17340
|
const state = hook2.memoizedState;
|
|
@@ -16856,11 +17408,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16856
17408
|
},
|
|
16857
17409
|
current() {
|
|
16858
17410
|
const current = [...currentFibers()].flatMap(hooks);
|
|
16859
|
-
return bindings.every(
|
|
16860
|
-
|
|
16861
|
-
|
|
16862
|
-
|
|
16863
|
-
|
|
17411
|
+
return bindings.every(({ subscriber, signal, instance }) => {
|
|
17412
|
+
try {
|
|
17413
|
+
const snapshot = subscriber.getSnapshot();
|
|
17414
|
+
const instanceSnapshot = instance.getSnapshot();
|
|
17415
|
+
if (!capable(snapshot) || !capable(instanceSnapshot) || !equal(snapshot, instanceSnapshot))
|
|
17416
|
+
return false;
|
|
17417
|
+
return current.some((hook) => {
|
|
17418
|
+
const committed = hook.next?.memoizedState;
|
|
17419
|
+
return Array.isArray(hook.memoizedState) && hook.memoizedState[0] === subscriber && hook.memoizedState[1]?.[0] === signal && hook.next?.queue === instance && capable(committed) && equal(committed, snapshot) && (!realtimeOnly || snapshot.isCapable);
|
|
17420
|
+
});
|
|
17421
|
+
} catch {
|
|
17422
|
+
return false;
|
|
17423
|
+
}
|
|
17424
|
+
});
|
|
16864
17425
|
}
|
|
16865
17426
|
};
|
|
16866
17427
|
}
|
|
@@ -16869,7 +17430,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16869
17430
|
var GLOBAL = "__codexhostVoiceStartCapabilityV1";
|
|
16870
17431
|
var record3 = (v) => v !== null && typeof v === "object";
|
|
16871
17432
|
function gatewayVoiceStartRequest(request, workGateway, chatGateway = false) {
|
|
16872
|
-
if (!record3(request) || request.productExperience !== "work" && request.productExperience !== "chat")
|
|
17433
|
+
if (!record3(request) || request.productExperience !== "work" && request.productExperience !== "codex" && request.productExperience !== "chat")
|
|
16873
17434
|
return false;
|
|
16874
17435
|
if (request.source === "composer_button_existing_thread") {
|
|
16875
17436
|
if (!record3(request.locator) || request.locator.hostId !== "local") return false;
|
|
@@ -16957,9 +17518,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16957
17518
|
const assets = selectVoiceAssets(CLIENT_OWNED_VOICE_ASSETS, names, config2.desktopVersion);
|
|
16958
17519
|
if (assets) {
|
|
16959
17520
|
const shared = await importModule(`app://-/assets/${assets.shared}`);
|
|
16960
|
-
|
|
16961
|
-
shared
|
|
16962
|
-
|
|
17521
|
+
const init = "init" in assets ? assets.init : void 0;
|
|
17522
|
+
if (typeof init === "string" && typeof shared[init] === "function") {
|
|
17523
|
+
shared[init]();
|
|
17524
|
+
}
|
|
17525
|
+
const services = shared[assets.services];
|
|
16963
17526
|
if (record3(services) && (record3(services.realtimeVoiceRuntime) || typeof services.realtimeVoiceRuntime === "function")) {
|
|
16964
17527
|
const original = services.realtimeVoiceRuntime;
|
|
16965
17528
|
const register = Reflect.get(original, "registerRealtimeStarter");
|
|
@@ -16979,7 +17542,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16979
17542
|
ready: async () => {
|
|
16980
17543
|
const hook = target.__codexhostClientOwnedVoiceV1;
|
|
16981
17544
|
if (!record3(hook) || hook.status !== "active") return false;
|
|
16982
|
-
const bridgeClass = shared.
|
|
17545
|
+
const bridgeClass = shared[assets.bridge];
|
|
16983
17546
|
const result = await requestVoiceHost(
|
|
16984
17547
|
bridgeClass.getInstance(),
|
|
16985
17548
|
{},
|
|
@@ -16989,20 +17552,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16989
17552
|
},
|
|
16990
17553
|
prepare: async (allowed) => {
|
|
16991
17554
|
const names2 = loadedAssetNames(target.document, target.performance);
|
|
16992
|
-
if (
|
|
17555
|
+
if (selectVoiceAssets(
|
|
17556
|
+
CLIENT_OWNED_VOICE_ASSETS,
|
|
17557
|
+
names2,
|
|
17558
|
+
config2.desktopVersion
|
|
17559
|
+
) !== assets)
|
|
16993
17560
|
throw new Error("Unaudited voice starter");
|
|
16994
17561
|
const [initial, overlay] = await Promise.all([
|
|
16995
17562
|
importModule(`app://-/assets/${assets.initial}`),
|
|
16996
17563
|
importModule(`app://-/assets/${assets.overlay}`)
|
|
16997
17564
|
]);
|
|
16998
|
-
if (typeof
|
|
17565
|
+
if (typeof overlay.AvatarOverlayNativePage !== "function" || !target.document)
|
|
16999
17566
|
throw new Error("Voice starter owner unavailable");
|
|
17000
17567
|
const document = target.document;
|
|
17001
|
-
initial
|
|
17568
|
+
const { family, gates } = initializeVoiceCapabilityFamilies(initial, assets);
|
|
17002
17569
|
return bindVoiceCapabilitySubscriptions(
|
|
17003
17570
|
() => overlayVoiceStarterFibers(document, overlay.AvatarOverlayNativePage),
|
|
17004
|
-
|
|
17005
|
-
|
|
17571
|
+
family,
|
|
17572
|
+
gates,
|
|
17006
17573
|
allowed,
|
|
17007
17574
|
true
|
|
17008
17575
|
);
|
|
@@ -17061,4 +17628,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17061
17628
|
installClientOwnedVoiceHook();
|
|
17062
17629
|
installVoiceStartCapabilityHook();
|
|
17063
17630
|
installOverlayThreadIsolation();
|
|
17631
|
+
installOverlayExternalFollowUps();
|
|
17064
17632
|
})();
|