@karlorz/codexhost-cli-win32-x64 0.13.3-5 → 0.13.3-7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +844 -80
- package/app/console-web.js +1329 -223
- package/app/cpa-live-voice-hook.js +864 -164
- package/app/desktop-controller.mjs +138 -35
- package/app/host-runtime.mjs +1233 -573
- package/app/plugins/antigravity/plugin.mjs +72 -1
- package/app/plugins/claude-code/plugin.mjs +130 -12
- package/app/plugins/codebuddy/plugin.mjs +79 -5
- package/app/plugins/codex-usage/plugin.mjs +178 -67
- package/app/plugins/cursor-cli/plugin.mjs +20727 -44858
- package/app/plugins/deepseek-harness/plugin.mjs +79 -5
- package/app/plugins/grok/plugin.mjs +888 -157
- package/app/plugins/hermes/plugin.mjs +79 -5
- package/app/plugins/kimi-code/plugin.mjs +72 -1
- package/app/plugins/kiro-cli/plugin.mjs +72 -1
- package/app/plugins/omp/plugin.mjs +2335 -2072
- package/app/plugins/opencode/plugin.mjs +79 -5
- package/app/plugins/pi/plugin.mjs +2432 -2276
- package/app/plugins/qoder/plugin.mjs +79 -5
- package/app/plugins/qoder-cn/plugin.mjs +79 -5
- package/app/plugins/workbuddy/plugin.mjs +79 -5
- package/app/plugins/zcode/plugin.mjs +79 -5
- package/app/renderer-extension.js +2977 -912
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-node-repl.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/package.json +1 -1
|
@@ -6,149 +6,6 @@
|
|
|
6
6
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
// src/renderer-cpa-live-voice-preference.ts
|
|
10
|
-
var CPA_LIVE_VOICE_STORAGE_KEY = "codexhost.cpa-live-voice.v1";
|
|
11
|
-
function cpaLiveVoicePreferenceAllowsInstall(globalObject) {
|
|
12
|
-
const storage = globalObject.localStorage;
|
|
13
|
-
if (!storage) return true;
|
|
14
|
-
try {
|
|
15
|
-
return storage.getItem(CPA_LIVE_VOICE_STORAGE_KEY) !== "0";
|
|
16
|
-
} catch {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// src/renderer-cpa-live-voice-hook.ts
|
|
22
|
-
var CPA_LIVE_VOICE_HOOK_GLOBAL = "__codexhostCpaLiveVoiceHookV1";
|
|
23
|
-
var AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION = "26.1007.30912";
|
|
24
|
-
var AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET = "app-initial-6350d04672d0.js";
|
|
25
|
-
var THREAD_REALTIME_EXISTING_CALL_GATE = "206132468";
|
|
26
|
-
var originalCheckGate = /* @__PURE__ */ new WeakMap();
|
|
27
|
-
var DISCOVERY_TIMEOUT_MS = 6e4;
|
|
28
|
-
function isRecord(value) {
|
|
29
|
-
return typeof value === "object" && value !== null;
|
|
30
|
-
}
|
|
31
|
-
function readCpaLiveVoiceHookConfig(globalObject) {
|
|
32
|
-
const value = globalObject[CPA_LIVE_VOICE_HOOK_GLOBAL];
|
|
33
|
-
if (!isRecord(value) || value.enabled !== true) return null;
|
|
34
|
-
if (typeof value.auditedDesktopVersion !== "string" || typeof value.auditedAppInitialAsset !== "string") {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
return {
|
|
38
|
-
enabled: true,
|
|
39
|
-
auditedDesktopVersion: value.auditedDesktopVersion,
|
|
40
|
-
auditedAppInitialAsset: value.auditedAppInitialAsset,
|
|
41
|
-
...typeof value.desktopVersion === "string" ? { desktopVersion: value.desktopVersion } : {}
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function auditedAppInitialAssetPresent(resourceNames, asset) {
|
|
45
|
-
return resourceNames.some((name) => {
|
|
46
|
-
try {
|
|
47
|
-
const url2 = new URL(name, "app://-/");
|
|
48
|
-
return url2.protocol === "app:" && url2.hostname === "-" && url2.pathname === `/assets/${asset}`;
|
|
49
|
-
} catch {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
function resourceNamesFromPerformance(source) {
|
|
55
|
-
const target = source ?? (typeof performance === "undefined" ? void 0 : performance);
|
|
56
|
-
if (!target || typeof target.getEntriesByType !== "function") return [];
|
|
57
|
-
return target.getEntriesByType("resource").map((entry) => entry.name).filter((name) => typeof name === "string");
|
|
58
|
-
}
|
|
59
|
-
function loadedAssetNames(root, performanceSource) {
|
|
60
|
-
const names = resourceNamesFromPerformance(performanceSource);
|
|
61
|
-
if (!root || !("querySelectorAll" in root)) return names;
|
|
62
|
-
for (const element of root.querySelectorAll("script[src], link[href]")) {
|
|
63
|
-
const value = element.getAttribute("src") ?? element.getAttribute("href");
|
|
64
|
-
if (value) names.push(value);
|
|
65
|
-
}
|
|
66
|
-
return names;
|
|
67
|
-
}
|
|
68
|
-
function statsigClients(globalObject) {
|
|
69
|
-
const registry2 = globalObject.__STATSIG__;
|
|
70
|
-
if (!isRecord(registry2)) return [];
|
|
71
|
-
const clients = new Set(
|
|
72
|
-
isRecord(registry2.instances) ? Object.values(registry2.instances) : []
|
|
73
|
-
);
|
|
74
|
-
if (registry2.firstInstance) clients.add(registry2.firstInstance);
|
|
75
|
-
return [...clients].filter(
|
|
76
|
-
(client) => isRecord(client) && typeof client.checkGate === "function"
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
function wrapCheckGate(client) {
|
|
80
|
-
if (originalCheckGate.has(client)) return false;
|
|
81
|
-
const original = client.checkGate;
|
|
82
|
-
originalCheckGate.set(client, original);
|
|
83
|
-
client.checkGate = function(name, ...rest) {
|
|
84
|
-
return name === THREAD_REALTIME_EXISTING_CALL_GATE ? false : original.call(this, name, ...rest);
|
|
85
|
-
};
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
function restoreCheckGate(client) {
|
|
89
|
-
const original = originalCheckGate.get(client);
|
|
90
|
-
if (!original) return;
|
|
91
|
-
client.checkGate = original;
|
|
92
|
-
originalCheckGate.delete(client);
|
|
93
|
-
}
|
|
94
|
-
function configAllowsInstall(config2, resourceNames) {
|
|
95
|
-
if (config2.desktopVersion !== void 0 && config2.desktopVersion !== config2.auditedDesktopVersion) {
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
if (config2.auditedDesktopVersion !== AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION) return false;
|
|
99
|
-
if (config2.auditedAppInitialAsset !== AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET) return false;
|
|
100
|
-
return auditedAppInitialAssetPresent(resourceNames, config2.auditedAppInitialAsset);
|
|
101
|
-
}
|
|
102
|
-
function installCpaLiveVoiceHook(options = {}) {
|
|
103
|
-
const globalObject = options.globalThis ?? globalThis;
|
|
104
|
-
const config2 = options.config === void 0 ? readCpaLiveVoiceHookConfig(globalObject) : options.config;
|
|
105
|
-
if (!config2?.enabled || !cpaLiveVoicePreferenceAllowsInstall(globalObject)) {
|
|
106
|
-
return { status: "disabled", dispose() {
|
|
107
|
-
} };
|
|
108
|
-
}
|
|
109
|
-
const root = options.document ?? globalObject.document;
|
|
110
|
-
const wrapped = [];
|
|
111
|
-
let disposed = false;
|
|
112
|
-
let auditedAssetFound = false;
|
|
113
|
-
const handle = {
|
|
114
|
-
status: "pending",
|
|
115
|
-
dispose() {
|
|
116
|
-
disposed = true;
|
|
117
|
-
for (const client of wrapped) restoreCheckGate(client);
|
|
118
|
-
wrapped.length = 0;
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
const attempt = () => {
|
|
122
|
-
if (!auditedAssetFound) {
|
|
123
|
-
const resourceNames = options.resourceNames ?? loadedAssetNames(root);
|
|
124
|
-
auditedAssetFound = configAllowsInstall(config2, resourceNames);
|
|
125
|
-
if (!auditedAssetFound) return false;
|
|
126
|
-
}
|
|
127
|
-
for (const client of statsigClients(globalObject)) {
|
|
128
|
-
if (wrapCheckGate(client)) wrapped.push(client);
|
|
129
|
-
}
|
|
130
|
-
if (wrapped.length === 0) return false;
|
|
131
|
-
handle.status = "active";
|
|
132
|
-
return true;
|
|
133
|
-
};
|
|
134
|
-
if (attempt()) return handle;
|
|
135
|
-
if (options.resourceNames && !configAllowsInstall(config2, options.resourceNames)) {
|
|
136
|
-
handle.status = "unsupported";
|
|
137
|
-
return handle;
|
|
138
|
-
}
|
|
139
|
-
const started = Date.now();
|
|
140
|
-
const tick = () => {
|
|
141
|
-
if (disposed || attempt()) return;
|
|
142
|
-
if (Date.now() - started > DISCOVERY_TIMEOUT_MS) {
|
|
143
|
-
handle.status = "unsupported";
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
globalThis.setTimeout(tick, 250);
|
|
147
|
-
};
|
|
148
|
-
globalThis.setTimeout(tick, 250);
|
|
149
|
-
return handle;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
9
|
// ../../node_modules/zod/v4/classic/external.js
|
|
153
10
|
var external_exports = {};
|
|
154
11
|
__export(external_exports, {
|
|
@@ -14980,6 +14837,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14980
14837
|
url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
|
|
14981
14838
|
});
|
|
14982
14839
|
var CONSOLE_HOST_METHODS = Object.freeze([
|
|
14840
|
+
"codexhost/voice/gateway-status",
|
|
14983
14841
|
"codexhost/console/remote-connections",
|
|
14984
14842
|
"codexhost/runtime/status",
|
|
14985
14843
|
"codexhost/remote/ssh-setup",
|
|
@@ -14990,6 +14848,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14990
14848
|
"codexhost/harness/installation",
|
|
14991
14849
|
"codexhost/harness/launch-settings/get",
|
|
14992
14850
|
"codexhost/harness/launch-settings/set",
|
|
14851
|
+
"codexhost/harness/grok-computer-use/get",
|
|
14852
|
+
"codexhost/harness/grok-computer-use/set",
|
|
14993
14853
|
"codexhost/harness/web-ui/open",
|
|
14994
14854
|
"codexhost/harness/accounts/sources",
|
|
14995
14855
|
"codexhost/harness/accounts/list",
|
|
@@ -15518,7 +15378,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15518
15378
|
var harnessInspectParamsSchema = external_exports.object({
|
|
15519
15379
|
harnessId: harnessIdSchema,
|
|
15520
15380
|
cwd: nonBlankTextSchema2.max(16384).optional(),
|
|
15521
|
-
refresh: external_exports.boolean().optional()
|
|
15381
|
+
refresh: external_exports.boolean().optional(),
|
|
15382
|
+
/** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
|
|
15383
|
+
purpose: external_exports.literal("availability").optional()
|
|
15522
15384
|
}).strict();
|
|
15523
15385
|
var harnessWebUiOpenParamsSchema = external_exports.object({
|
|
15524
15386
|
harnessId: harnessIdSchema
|
|
@@ -15692,6 +15554,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15692
15554
|
restartRequired: external_exports.boolean()
|
|
15693
15555
|
}).strict();
|
|
15694
15556
|
|
|
15557
|
+
// ../shared-contracts/dist/grok-computer-use.js
|
|
15558
|
+
var grokComputerUseGetSchema = external_exports.object({}).strict();
|
|
15559
|
+
var grokComputerUseSetSchema = external_exports.object({
|
|
15560
|
+
enabled: external_exports.boolean().optional(),
|
|
15561
|
+
browser: external_exports.boolean().optional()
|
|
15562
|
+
}).strict().refine((value) => value.enabled !== void 0 || value.browser !== void 0, {
|
|
15563
|
+
message: "Expected enabled or browser"
|
|
15564
|
+
});
|
|
15565
|
+
var grokComputerUseSettingsSchema = external_exports.object({
|
|
15566
|
+
enabled: external_exports.boolean(),
|
|
15567
|
+
available: external_exports.boolean(),
|
|
15568
|
+
unavailableReason: external_exports.string().min(1).max(500).optional(),
|
|
15569
|
+
browser: external_exports.boolean().optional(),
|
|
15570
|
+
browserFilesPresent: external_exports.boolean().optional(),
|
|
15571
|
+
browserAvailable: external_exports.boolean().optional(),
|
|
15572
|
+
browserUnavailableReason: external_exports.string().min(1).max(500).optional(),
|
|
15573
|
+
applyFailed: external_exports.boolean().optional(),
|
|
15574
|
+
applyError: external_exports.string().min(1).max(500).optional()
|
|
15575
|
+
}).strict();
|
|
15576
|
+
|
|
15695
15577
|
// ../shared-contracts/dist/harness-installation.js
|
|
15696
15578
|
var harnessInstallationParamsSchema = external_exports.object({
|
|
15697
15579
|
harnessId: harnessIdSchema,
|
|
@@ -16084,18 +15966,296 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16084
15966
|
external_exports.strictObject({ error: external_exports.strictObject({ code: external_exports.number().int(), message: external_exports.string() }) })
|
|
16085
15967
|
]);
|
|
16086
15968
|
|
|
15969
|
+
// ../shared-contracts/dist/voice-settings.js
|
|
15970
|
+
var VOICE_GATEWAY_STATUS_METHOD = "codexhost/voice/gateway-status";
|
|
15971
|
+
var voiceRoutesSchema = external_exports.strictObject({
|
|
15972
|
+
chatExperience: external_exports.enum(["chatgpt", "codex"]),
|
|
15973
|
+
chatConnection: external_exports.enum(["desktop", "gateway"]),
|
|
15974
|
+
workConnection: external_exports.enum(["desktop", "gateway"])
|
|
15975
|
+
});
|
|
15976
|
+
var DEFAULT_VOICE_ROUTES = Object.freeze({
|
|
15977
|
+
chatExperience: "chatgpt",
|
|
15978
|
+
chatConnection: "desktop",
|
|
15979
|
+
workConnection: "gateway"
|
|
15980
|
+
});
|
|
15981
|
+
var voiceSettingsSchema = voiceRoutesSchema.extend({ inject: external_exports.boolean() });
|
|
15982
|
+
var voiceSettingsRequestSchema = external_exports.discriminatedUnion("operation", [
|
|
15983
|
+
external_exports.strictObject({
|
|
15984
|
+
operation: external_exports.literal("get"),
|
|
15985
|
+
runtime: external_exports.strictObject({
|
|
15986
|
+
id: external_exports.string().uuid(),
|
|
15987
|
+
revision: external_exports.string().max(64),
|
|
15988
|
+
activeCall: external_exports.boolean()
|
|
15989
|
+
}).optional()
|
|
15990
|
+
}),
|
|
15991
|
+
external_exports.strictObject({ operation: external_exports.literal("migrate"), routes: voiceRoutesSchema }),
|
|
15992
|
+
external_exports.strictObject({
|
|
15993
|
+
operation: external_exports.literal("set"),
|
|
15994
|
+
settings: voiceSettingsSchema,
|
|
15995
|
+
revision: external_exports.string().max(64)
|
|
15996
|
+
}),
|
|
15997
|
+
external_exports.strictObject({ operation: external_exports.literal("restart"), confirm: external_exports.literal(true) })
|
|
15998
|
+
]);
|
|
15999
|
+
var voiceSettingsStateSchema = external_exports.strictObject({
|
|
16000
|
+
settings: voiceSettingsSchema,
|
|
16001
|
+
initialized: external_exports.boolean(),
|
|
16002
|
+
revision: external_exports.string(),
|
|
16003
|
+
activeInject: external_exports.boolean().nullable(),
|
|
16004
|
+
envOverride: external_exports.enum(["0", "1"]).nullable(),
|
|
16005
|
+
activeEnvOverride: external_exports.enum(["0", "1"]).nullable(),
|
|
16006
|
+
routesActive: external_exports.boolean().nullable(),
|
|
16007
|
+
activeCall: external_exports.boolean().nullable(),
|
|
16008
|
+
gatewayReady: external_exports.boolean().nullable(),
|
|
16009
|
+
restartAvailable: external_exports.boolean(),
|
|
16010
|
+
restart: external_exports.strictObject({
|
|
16011
|
+
phase: external_exports.enum(["idle", "restarting", "succeeded", "failed"]),
|
|
16012
|
+
error: external_exports.string().nullable()
|
|
16013
|
+
})
|
|
16014
|
+
});
|
|
16015
|
+
|
|
16087
16016
|
// ../shared-contracts/dist/index.js
|
|
16088
16017
|
var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
|
|
16089
16018
|
|
|
16019
|
+
// src/renderer-cpa-live-voice-preference.ts
|
|
16020
|
+
var voiceStateOwner = globalThis;
|
|
16021
|
+
var { sharedRoutes, gatewayReady } = voiceStateOwner.__codexhostVoicePreferenceStateV1 ??= {
|
|
16022
|
+
sharedRoutes: /* @__PURE__ */ new WeakMap(),
|
|
16023
|
+
gatewayReady: /* @__PURE__ */ new WeakMap()
|
|
16024
|
+
};
|
|
16025
|
+
var SHARED_VOICE_CACHE = "codexhost.voice-routes-cache.v1";
|
|
16026
|
+
function cachedRoutes(owner) {
|
|
16027
|
+
const memory = sharedRoutes.get(owner);
|
|
16028
|
+
if (memory) return memory;
|
|
16029
|
+
try {
|
|
16030
|
+
const storage = owner.localStorage;
|
|
16031
|
+
const parsed = voiceRoutesSchema.safeParse(
|
|
16032
|
+
JSON.parse(storage?.getItem(SHARED_VOICE_CACHE) ?? "null")
|
|
16033
|
+
).data;
|
|
16034
|
+
if (parsed) sharedRoutes.set(owner, parsed);
|
|
16035
|
+
return parsed;
|
|
16036
|
+
} catch {
|
|
16037
|
+
return void 0;
|
|
16038
|
+
}
|
|
16039
|
+
}
|
|
16040
|
+
var CPA_LIVE_VOICE_STORAGE_KEY = "codexhost.cpa-live-voice.v1";
|
|
16041
|
+
var CHAT_LIVE_VOICE_STORAGE_KEY = "codexhost.chat-live-voice.v1";
|
|
16042
|
+
function readFlag(owner, key, enabledWhenUnset) {
|
|
16043
|
+
const storage = owner.localStorage;
|
|
16044
|
+
if (!storage) return enabledWhenUnset;
|
|
16045
|
+
try {
|
|
16046
|
+
const value = storage.getItem(key);
|
|
16047
|
+
return enabledWhenUnset ? value !== "0" : value === "1";
|
|
16048
|
+
} catch {
|
|
16049
|
+
return enabledWhenUnset;
|
|
16050
|
+
}
|
|
16051
|
+
}
|
|
16052
|
+
function readCpaLiveVoicePreference(owner) {
|
|
16053
|
+
const routes = cachedRoutes(owner);
|
|
16054
|
+
return routes ? routes.workConnection === "gateway" : readFlag(owner, CPA_LIVE_VOICE_STORAGE_KEY, true);
|
|
16055
|
+
}
|
|
16056
|
+
function readChatLiveVoicePreference(owner) {
|
|
16057
|
+
const routes = cachedRoutes(owner);
|
|
16058
|
+
return routes ? routes.chatExperience === "codex" && routes.chatConnection === "gateway" : readFlag(owner, CHAT_LIVE_VOICE_STORAGE_KEY, false);
|
|
16059
|
+
}
|
|
16060
|
+
function cpaLiveVoicePreferenceAllowsInstall(globalObject) {
|
|
16061
|
+
return readCpaLiveVoicePreference(globalObject);
|
|
16062
|
+
}
|
|
16063
|
+
function chatLiveVoicePreferenceAllowsOverride(globalObject) {
|
|
16064
|
+
return readChatLiveVoicePreference(globalObject);
|
|
16065
|
+
}
|
|
16066
|
+
|
|
16067
|
+
// src/renderer-cpa-live-voice-hook.ts
|
|
16068
|
+
var CPA_LIVE_VOICE_HOOK_GLOBAL = "__codexhostCpaLiveVoiceHookV1";
|
|
16069
|
+
var AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION = "26.1007.30912";
|
|
16070
|
+
var AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET = "app-initial-6350d04672d0.js";
|
|
16071
|
+
var THREAD_REALTIME_EXISTING_CALL_GATE = "206132468";
|
|
16072
|
+
var originalCheckGate = /* @__PURE__ */ new WeakMap();
|
|
16073
|
+
var DISCOVERY_TIMEOUT_MS = 6e4;
|
|
16074
|
+
function isRecord(value) {
|
|
16075
|
+
return typeof value === "object" && value !== null;
|
|
16076
|
+
}
|
|
16077
|
+
function readCpaLiveVoiceHookConfig(globalObject) {
|
|
16078
|
+
const value = globalObject[CPA_LIVE_VOICE_HOOK_GLOBAL];
|
|
16079
|
+
if (!isRecord(value) || value.enabled !== true) return null;
|
|
16080
|
+
if (typeof value.auditedDesktopVersion !== "string" || typeof value.auditedAppInitialAsset !== "string") {
|
|
16081
|
+
return null;
|
|
16082
|
+
}
|
|
16083
|
+
return {
|
|
16084
|
+
enabled: true,
|
|
16085
|
+
auditedDesktopVersion: value.auditedDesktopVersion,
|
|
16086
|
+
auditedAppInitialAsset: value.auditedAppInitialAsset,
|
|
16087
|
+
...typeof value.desktopVersion === "string" ? { desktopVersion: value.desktopVersion } : {}
|
|
16088
|
+
};
|
|
16089
|
+
}
|
|
16090
|
+
function auditedAppInitialAssetPresent(resourceNames, asset) {
|
|
16091
|
+
return resourceNames.some((name) => {
|
|
16092
|
+
try {
|
|
16093
|
+
const url2 = new URL(name, "app://-/");
|
|
16094
|
+
return url2.protocol === "app:" && url2.hostname === "-" && url2.pathname === `/assets/${asset}`;
|
|
16095
|
+
} catch {
|
|
16096
|
+
return false;
|
|
16097
|
+
}
|
|
16098
|
+
});
|
|
16099
|
+
}
|
|
16100
|
+
function resourceNamesFromPerformance(source) {
|
|
16101
|
+
const target = source ?? (typeof performance === "undefined" ? void 0 : performance);
|
|
16102
|
+
if (!target || typeof target.getEntriesByType !== "function") return [];
|
|
16103
|
+
return target.getEntriesByType("resource").map((entry) => entry.name).filter((name) => typeof name === "string");
|
|
16104
|
+
}
|
|
16105
|
+
function loadedAssetNames(root, performanceSource) {
|
|
16106
|
+
const names = resourceNamesFromPerformance(performanceSource);
|
|
16107
|
+
if (!root || !("querySelectorAll" in root)) return names;
|
|
16108
|
+
for (const element of root.querySelectorAll("script[src], link[href]")) {
|
|
16109
|
+
const value = element.getAttribute("src") ?? element.getAttribute("href");
|
|
16110
|
+
if (value) names.push(value);
|
|
16111
|
+
}
|
|
16112
|
+
return names;
|
|
16113
|
+
}
|
|
16114
|
+
function statsigClients(globalObject) {
|
|
16115
|
+
const registry2 = globalObject.__STATSIG__;
|
|
16116
|
+
if (!isRecord(registry2)) return [];
|
|
16117
|
+
const clients = new Set(
|
|
16118
|
+
isRecord(registry2.instances) ? Object.values(registry2.instances) : []
|
|
16119
|
+
);
|
|
16120
|
+
if (registry2.firstInstance) clients.add(registry2.firstInstance);
|
|
16121
|
+
return [...clients].filter(
|
|
16122
|
+
(client) => isRecord(client) && typeof client.checkGate === "function"
|
|
16123
|
+
);
|
|
16124
|
+
}
|
|
16125
|
+
function wrapCheckGate(client) {
|
|
16126
|
+
if (originalCheckGate.has(client)) return false;
|
|
16127
|
+
const original = client.checkGate;
|
|
16128
|
+
originalCheckGate.set(client, original);
|
|
16129
|
+
client.checkGate = function(name, ...rest) {
|
|
16130
|
+
return name === THREAD_REALTIME_EXISTING_CALL_GATE ? false : original.call(this, name, ...rest);
|
|
16131
|
+
};
|
|
16132
|
+
return true;
|
|
16133
|
+
}
|
|
16134
|
+
function restoreCheckGate(client) {
|
|
16135
|
+
const original = originalCheckGate.get(client);
|
|
16136
|
+
if (!original) return;
|
|
16137
|
+
client.checkGate = original;
|
|
16138
|
+
originalCheckGate.delete(client);
|
|
16139
|
+
}
|
|
16140
|
+
function configAllowsInstall(config2, resourceNames) {
|
|
16141
|
+
if (config2.desktopVersion !== void 0 && config2.desktopVersion !== config2.auditedDesktopVersion) {
|
|
16142
|
+
return false;
|
|
16143
|
+
}
|
|
16144
|
+
if (config2.auditedDesktopVersion !== AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION) return false;
|
|
16145
|
+
if (config2.auditedAppInitialAsset !== AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET) return false;
|
|
16146
|
+
return auditedAppInitialAssetPresent(resourceNames, config2.auditedAppInitialAsset);
|
|
16147
|
+
}
|
|
16148
|
+
function installCpaLiveVoiceHook(options = {}) {
|
|
16149
|
+
const globalObject = options.globalThis ?? globalThis;
|
|
16150
|
+
const config2 = options.config === void 0 ? readCpaLiveVoiceHookConfig(globalObject) : options.config;
|
|
16151
|
+
if (!config2?.enabled || !cpaLiveVoicePreferenceAllowsInstall(globalObject)) {
|
|
16152
|
+
return { status: "disabled", dispose() {
|
|
16153
|
+
} };
|
|
16154
|
+
}
|
|
16155
|
+
const root = options.document ?? globalObject.document;
|
|
16156
|
+
const wrapped = [];
|
|
16157
|
+
let disposed = false;
|
|
16158
|
+
let auditedAssetFound = false;
|
|
16159
|
+
const handle = {
|
|
16160
|
+
status: "pending",
|
|
16161
|
+
dispose() {
|
|
16162
|
+
disposed = true;
|
|
16163
|
+
for (const client of wrapped) restoreCheckGate(client);
|
|
16164
|
+
wrapped.length = 0;
|
|
16165
|
+
}
|
|
16166
|
+
};
|
|
16167
|
+
const attempt = () => {
|
|
16168
|
+
if (!auditedAssetFound) {
|
|
16169
|
+
const resourceNames = options.resourceNames ?? loadedAssetNames(root);
|
|
16170
|
+
auditedAssetFound = configAllowsInstall(config2, resourceNames);
|
|
16171
|
+
if (!auditedAssetFound) return false;
|
|
16172
|
+
}
|
|
16173
|
+
for (const client of statsigClients(globalObject)) {
|
|
16174
|
+
if (wrapCheckGate(client)) wrapped.push(client);
|
|
16175
|
+
}
|
|
16176
|
+
if (wrapped.length === 0) return false;
|
|
16177
|
+
handle.status = "active";
|
|
16178
|
+
return true;
|
|
16179
|
+
};
|
|
16180
|
+
if (attempt()) return handle;
|
|
16181
|
+
if (options.resourceNames && !configAllowsInstall(config2, options.resourceNames)) {
|
|
16182
|
+
handle.status = "unsupported";
|
|
16183
|
+
return handle;
|
|
16184
|
+
}
|
|
16185
|
+
const started = Date.now();
|
|
16186
|
+
const tick = () => {
|
|
16187
|
+
if (disposed || attempt()) return;
|
|
16188
|
+
if (Date.now() - started > DISCOVERY_TIMEOUT_MS) {
|
|
16189
|
+
handle.status = "unsupported";
|
|
16190
|
+
return;
|
|
16191
|
+
}
|
|
16192
|
+
globalThis.setTimeout(tick, 250);
|
|
16193
|
+
};
|
|
16194
|
+
globalThis.setTimeout(tick, 250);
|
|
16195
|
+
return handle;
|
|
16196
|
+
}
|
|
16197
|
+
|
|
16198
|
+
// src/renderer-voice-assets.ts
|
|
16199
|
+
function supportsVoiceVersion(profiles, version2) {
|
|
16200
|
+
return version2 === void 0 || profiles.some((profile) => profile.version === version2);
|
|
16201
|
+
}
|
|
16202
|
+
function selectVoiceAssets(profiles, names, version2) {
|
|
16203
|
+
const present = profiles.filter(
|
|
16204
|
+
(profile2) => [profile2.initial, profile2.shared].some((asset) => auditedAppInitialAssetPresent(names, asset))
|
|
16205
|
+
);
|
|
16206
|
+
const profile = present.length === 1 ? present[0] : void 0;
|
|
16207
|
+
return profile && (version2 === void 0 || profile.version === version2) && [profile.initial, profile.shared].every((asset) => auditedAppInitialAssetPresent(names, asset)) ? profile : void 0;
|
|
16208
|
+
}
|
|
16209
|
+
|
|
16210
|
+
// src/renderer-chat-voice-debug.ts
|
|
16211
|
+
var CHAT_VOICE_DEBUG_GLOBAL = "__codexhostChatVoiceDebug";
|
|
16212
|
+
var CHAT_VOICE_DEBUG_STORAGE_KEY = "codexhost.chat-voice-debug.v1";
|
|
16213
|
+
function chatVoiceDebug(event, detail = {}) {
|
|
16214
|
+
const entry = { t: Date.now(), event, ...detail };
|
|
16215
|
+
const owner = globalThis;
|
|
16216
|
+
const log = Array.isArray(owner[CHAT_VOICE_DEBUG_GLOBAL]) ? owner[CHAT_VOICE_DEBUG_GLOBAL] : [];
|
|
16217
|
+
log.push(entry);
|
|
16218
|
+
while (log.length > 40) log.shift();
|
|
16219
|
+
owner[CHAT_VOICE_DEBUG_GLOBAL] = log;
|
|
16220
|
+
try {
|
|
16221
|
+
owner.localStorage?.setItem(CHAT_VOICE_DEBUG_STORAGE_KEY, JSON.stringify(log));
|
|
16222
|
+
} catch {
|
|
16223
|
+
}
|
|
16224
|
+
owner.console?.info?.("[codexhost-chat-voice]", event, detail);
|
|
16225
|
+
}
|
|
16226
|
+
|
|
16227
|
+
// src/renderer-new-thread-preference.ts
|
|
16228
|
+
var RENDERER_NEW_THREAD_PREFERENCE_KEY = "codexhost.new-thread-preference.v1";
|
|
16229
|
+
|
|
16090
16230
|
// src/renderer-client-owned-voice.ts
|
|
16091
|
-
var CLIENT_OWNED_VOICE_VERSION = "26.
|
|
16092
|
-
var CLIENT_OWNED_VOICE_INITIAL_ASSET = "app-initial-
|
|
16093
|
-
var CLIENT_OWNED_VOICE_SHARED_ASSET = "app-shared-
|
|
16231
|
+
var CLIENT_OWNED_VOICE_VERSION = "26.1016.62342";
|
|
16232
|
+
var CLIENT_OWNED_VOICE_INITIAL_ASSET = "app-initial-dddef47d6ef6.js";
|
|
16233
|
+
var CLIENT_OWNED_VOICE_SHARED_ASSET = "app-shared-fc3316d48427.js";
|
|
16234
|
+
var CLIENT_OWNED_VOICE_SERVICES = "ist";
|
|
16235
|
+
var CLIENT_OWNED_VOICE_OVERLAY_ASSET = "avatar-overlay-native-page-ef8332c6a2fb.js";
|
|
16236
|
+
var CLIENT_OWNED_VOICE_ASSETS = [
|
|
16237
|
+
{
|
|
16238
|
+
version: CLIENT_OWNED_VOICE_VERSION,
|
|
16239
|
+
initial: CLIENT_OWNED_VOICE_INITIAL_ASSET,
|
|
16240
|
+
shared: CLIENT_OWNED_VOICE_SHARED_ASSET,
|
|
16241
|
+
overlay: CLIENT_OWNED_VOICE_OVERLAY_ASSET
|
|
16242
|
+
},
|
|
16243
|
+
{
|
|
16244
|
+
version: "26.1016.61520",
|
|
16245
|
+
initial: "app-initial-c95ddb62696e.js",
|
|
16246
|
+
shared: "app-shared-2eda13eb7044.js",
|
|
16247
|
+
overlay: "avatar-overlay-native-page-fcc17283519a.js"
|
|
16248
|
+
}
|
|
16249
|
+
];
|
|
16250
|
+
var SHARED_INIT = "Oit";
|
|
16251
|
+
var SHARED_FETCH = "Eit";
|
|
16252
|
+
var SHARED_BRIDGE = "AFt";
|
|
16253
|
+
var SHARED_RESPONSE_ERROR = "Mit";
|
|
16094
16254
|
var HOOK_GLOBAL = "__codexhostClientOwnedVoiceV1";
|
|
16095
16255
|
function object2(value) {
|
|
16096
16256
|
return value !== null && typeof value === "object";
|
|
16097
16257
|
}
|
|
16098
|
-
function
|
|
16258
|
+
function requestVoiceHost(bridge, params, method = REALTIME_CALL_METHOD) {
|
|
16099
16259
|
const id = `codexhost-voice:${crypto.randomUUID()}`;
|
|
16100
16260
|
return new Promise((resolve, reject) => {
|
|
16101
16261
|
let unsubscribe = () => {
|
|
@@ -16118,7 +16278,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16118
16278
|
try {
|
|
16119
16279
|
bridge.dispatchMessage("mcp-request", {
|
|
16120
16280
|
hostId: "local",
|
|
16121
|
-
request: { id, method
|
|
16281
|
+
request: { id, method, params }
|
|
16122
16282
|
});
|
|
16123
16283
|
} catch {
|
|
16124
16284
|
done();
|
|
@@ -16126,11 +16286,122 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16126
16286
|
}
|
|
16127
16287
|
});
|
|
16128
16288
|
}
|
|
16129
|
-
|
|
16289
|
+
var HOME_COMPOSER_MODE_STORAGE_KEY = "home-composer-mode-v1";
|
|
16290
|
+
function backendModelName(headers) {
|
|
16291
|
+
const raw = new Headers(headers).get("x-codex-turn-metadata");
|
|
16292
|
+
if (!raw) return "";
|
|
16293
|
+
try {
|
|
16294
|
+
const parsed = JSON.parse(raw);
|
|
16295
|
+
return typeof parsed.backend_model_name === "string" ? parsed.backend_model_name : "";
|
|
16296
|
+
} catch {
|
|
16297
|
+
return "";
|
|
16298
|
+
}
|
|
16299
|
+
}
|
|
16300
|
+
function isWorkBackendModel(name) {
|
|
16301
|
+
const model2 = name.toLowerCase();
|
|
16302
|
+
if (!model2) return false;
|
|
16303
|
+
if (model2.startsWith("codexhost/")) return true;
|
|
16304
|
+
return model2.includes("codex") && !model2.includes("gpt-live");
|
|
16305
|
+
}
|
|
16306
|
+
function visibleWorkComposer(owner) {
|
|
16307
|
+
const document = owner.document;
|
|
16308
|
+
if (!document?.querySelectorAll) return false;
|
|
16309
|
+
const work = [...document.querySelectorAll("[data-codex-composer-root]")].some((element) => {
|
|
16310
|
+
const box = element.getBoundingClientRect?.() ?? { width: 0 };
|
|
16311
|
+
return box.width > 0 && !element.closest?.("[hidden], [inert]");
|
|
16312
|
+
});
|
|
16313
|
+
return work && document.querySelectorAll("[data-chatgpt-composer]").length === 0;
|
|
16314
|
+
}
|
|
16315
|
+
function selectedWorkTab(owner) {
|
|
16316
|
+
const document = owner.document;
|
|
16317
|
+
if (!document?.querySelectorAll) return false;
|
|
16318
|
+
const controls = document.querySelectorAll("button, [role='tab'], a");
|
|
16319
|
+
let workSelected = false;
|
|
16320
|
+
let chatSelected = false;
|
|
16321
|
+
for (const element of controls) {
|
|
16322
|
+
const name = (element.textContent ?? "").replace(/\s+/gu, " ").trim();
|
|
16323
|
+
if (name !== "Chat" && name !== "Work") continue;
|
|
16324
|
+
const selected = element.getAttribute("aria-selected") === "true" || element.getAttribute("aria-pressed") === "true" || element.getAttribute("data-state") === "active" || element.getAttribute("data-state") === "on";
|
|
16325
|
+
if (!selected) continue;
|
|
16326
|
+
if (name === "Work") workSelected = true;
|
|
16327
|
+
if (name === "Chat") chatSelected = true;
|
|
16328
|
+
}
|
|
16329
|
+
return workSelected && !chatSelected;
|
|
16330
|
+
}
|
|
16331
|
+
function isWorkComposerSurface(owner = globalThis) {
|
|
16332
|
+
const storage = owner.localStorage;
|
|
16333
|
+
try {
|
|
16334
|
+
const raw = storage?.getItem(HOME_COMPOSER_MODE_STORAGE_KEY);
|
|
16335
|
+
if (raw != null && raw !== "") {
|
|
16336
|
+
let value = raw;
|
|
16337
|
+
if (raw.startsWith("{") || raw.startsWith('"') || raw.startsWith("[")) {
|
|
16338
|
+
try {
|
|
16339
|
+
value = JSON.parse(raw);
|
|
16340
|
+
} catch {
|
|
16341
|
+
value = raw;
|
|
16342
|
+
}
|
|
16343
|
+
}
|
|
16344
|
+
if (value === "work") return true;
|
|
16345
|
+
if (value === "chat") return false;
|
|
16346
|
+
}
|
|
16347
|
+
} catch {
|
|
16348
|
+
}
|
|
16349
|
+
return selectedWorkTab(owner) || visibleWorkComposer(owner);
|
|
16350
|
+
}
|
|
16351
|
+
function selectedComposerModel(owner) {
|
|
16352
|
+
const routing = owner.__codexhostHostRoutingV1;
|
|
16353
|
+
try {
|
|
16354
|
+
const model2 = routing?.forComposer()?.policy.selectedModel();
|
|
16355
|
+
return typeof model2 === "string" ? model2 : "";
|
|
16356
|
+
} catch {
|
|
16357
|
+
return "";
|
|
16358
|
+
}
|
|
16359
|
+
}
|
|
16360
|
+
var lastVoiceProductExperience;
|
|
16361
|
+
function rememberVoiceProductExperience(request) {
|
|
16362
|
+
const experience = object2(request) ? request.productExperience : void 0;
|
|
16363
|
+
lastVoiceProductExperience = experience === "chat" || experience === "work" ? experience : void 0;
|
|
16364
|
+
}
|
|
16365
|
+
function lastVoiceLaunchProductExperience() {
|
|
16366
|
+
return lastVoiceProductExperience;
|
|
16367
|
+
}
|
|
16368
|
+
function isExternalHarnessComposer(owner = globalThis) {
|
|
16369
|
+
if (lastVoiceProductExperience === "chat") return false;
|
|
16370
|
+
if (selectedComposerModel(owner).startsWith("codexhost/")) return true;
|
|
16371
|
+
if (lastVoiceProductExperience !== "work") return false;
|
|
16372
|
+
const storage = owner.localStorage;
|
|
16373
|
+
if (!storage) return false;
|
|
16374
|
+
try {
|
|
16375
|
+
const parsed = JSON.parse(storage.getItem(RENDERER_NEW_THREAD_PREFERENCE_KEY) ?? "");
|
|
16376
|
+
return typeof parsed.lastAgent === "string" && parsed.lastAgent !== "" && parsed.lastAgent !== "codex";
|
|
16377
|
+
} catch {
|
|
16378
|
+
return false;
|
|
16379
|
+
}
|
|
16380
|
+
}
|
|
16381
|
+
function wrapClientOwnedVoiceFetch(client, bridge, workOverride, responseError, chatOverride = () => false, workSurface = () => isWorkComposerSurface(), externalHarness = () => isExternalHarnessComposer()) {
|
|
16130
16382
|
const original = client.fetch;
|
|
16131
16383
|
const wrapped = async function(url2, options) {
|
|
16132
|
-
if (typeof url2 !== "string" || url2.split("?")[0] !== "/wham/realtime/calls" || options?.method !== "POST"
|
|
16384
|
+
if (typeof url2 !== "string" || url2.split("?")[0] !== "/wham/realtime/calls" || options?.method !== "POST")
|
|
16133
16385
|
return original.call(this, url2, options);
|
|
16386
|
+
const experience = lastVoiceLaunchProductExperience();
|
|
16387
|
+
const chat = experience === "chat";
|
|
16388
|
+
const model2 = backendModelName(options.headers);
|
|
16389
|
+
const work = !chat && (experience === "work" || isWorkBackendModel(model2) || workSurface());
|
|
16390
|
+
const external = !chat && (model2.startsWith("codexhost/") || externalHarness());
|
|
16391
|
+
const gateway = external || (work ? workOverride() : chatOverride());
|
|
16392
|
+
chatVoiceDebug("wham-create", {
|
|
16393
|
+
work,
|
|
16394
|
+
external,
|
|
16395
|
+
route: gateway ? "gateway" : "desktop",
|
|
16396
|
+
productExperience: experience ?? "unset"
|
|
16397
|
+
});
|
|
16398
|
+
if (!gateway) {
|
|
16399
|
+
if (!external && !work)
|
|
16400
|
+
chatVoiceDebug("chat-native-passthrough", {
|
|
16401
|
+
hasThreadId: new Headers(options.headers).has("Thread-Id")
|
|
16402
|
+
});
|
|
16403
|
+
return original.call(this, url2, options);
|
|
16404
|
+
}
|
|
16134
16405
|
if (typeof options.body !== "string") throw new Error("Unsupported native voice call request");
|
|
16135
16406
|
options.signal?.throwIfAborted();
|
|
16136
16407
|
const requestId2 = crypto.randomUUID();
|
|
@@ -16138,12 +16409,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16138
16409
|
const cancel = () => {
|
|
16139
16410
|
if (cancelled) return;
|
|
16140
16411
|
cancelled = true;
|
|
16141
|
-
void
|
|
16412
|
+
void requestVoiceHost(bridge, { operation: "cancel", requestId: requestId2 }).catch(() => void 0);
|
|
16142
16413
|
};
|
|
16143
16414
|
options.signal?.addEventListener("abort", cancel, { once: true });
|
|
16144
16415
|
try {
|
|
16145
16416
|
const result = realtimeCallResponseSchema.parse(
|
|
16146
|
-
await
|
|
16417
|
+
await requestVoiceHost(bridge, {
|
|
16147
16418
|
operation: "create",
|
|
16148
16419
|
requestId: requestId2,
|
|
16149
16420
|
body: options.body,
|
|
@@ -16155,7 +16426,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16155
16426
|
if (options.signal?.aborted) {
|
|
16156
16427
|
const callId = realtimeCallIdFromLocation(result.headers.location ?? "");
|
|
16157
16428
|
if (result.status >= 200 && result.status < 300 && isRealtimeCallId(callId))
|
|
16158
|
-
await
|
|
16429
|
+
await requestVoiceHost(bridge, { operation: "hangup", callId });
|
|
16159
16430
|
options.signal.throwIfAborted();
|
|
16160
16431
|
}
|
|
16161
16432
|
const response = new Response(result.status === 204 ? null : result.body, {
|
|
@@ -16181,10 +16452,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16181
16452
|
const existing = target[HOOK_GLOBAL];
|
|
16182
16453
|
if (existing) return existing;
|
|
16183
16454
|
const config2 = readCpaLiveVoiceHookConfig(target);
|
|
16184
|
-
if (!config2
|
|
16185
|
-
|
|
16186
|
-
|
|
16187
|
-
if (config2.desktopVersion !== void 0 && config2.desktopVersion !== CLIENT_OWNED_VOICE_VERSION)
|
|
16455
|
+
if (!config2) return { status: "disabled", dispose() {
|
|
16456
|
+
} };
|
|
16457
|
+
if (!supportsVoiceVersion(CLIENT_OWNED_VOICE_ASSETS, config2.desktopVersion))
|
|
16188
16458
|
return { status: "unsupported", dispose() {
|
|
16189
16459
|
} };
|
|
16190
16460
|
const importModule = options.importModule ?? ((url2) => import(url2));
|
|
@@ -16205,23 +16475,29 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16205
16475
|
const attempt = async () => {
|
|
16206
16476
|
if (disposed) return;
|
|
16207
16477
|
const names = loadedAssetNames(target.document, target.performance);
|
|
16208
|
-
|
|
16478
|
+
const assets = selectVoiceAssets(CLIENT_OWNED_VOICE_ASSETS, names, config2.desktopVersion);
|
|
16479
|
+
if (assets) {
|
|
16209
16480
|
try {
|
|
16210
|
-
const module = await importModule(`app://-/assets/${
|
|
16481
|
+
const module = await importModule(`app://-/assets/${assets.shared}`);
|
|
16211
16482
|
if (disposed) return;
|
|
16212
|
-
|
|
16213
|
-
|
|
16483
|
+
if (typeof module[SHARED_INIT] !== "function") throw new Error();
|
|
16484
|
+
module[SHARED_INIT]();
|
|
16485
|
+
const fetchClass = module[SHARED_FETCH];
|
|
16486
|
+
const bridgeClass = module[SHARED_BRIDGE];
|
|
16214
16487
|
if (!object2(fetchClass) && typeof fetchClass !== "function") throw new Error();
|
|
16215
16488
|
if (!object2(bridgeClass) && typeof bridgeClass !== "function") throw new Error();
|
|
16216
16489
|
const client = Reflect.get(fetchClass, "getInstance").call(fetchClass);
|
|
16217
16490
|
const bridge = Reflect.get(bridgeClass, "getInstance").call(bridgeClass);
|
|
16218
|
-
if (typeof client?.fetch !== "function" || typeof bridge?.dispatchMessage !== "function" || typeof bridge?.subscribe !== "function" || typeof module
|
|
16491
|
+
if (typeof client?.fetch !== "function" || typeof bridge?.dispatchMessage !== "function" || typeof bridge?.subscribe !== "function" || typeof module[SHARED_RESPONSE_ERROR] !== "function")
|
|
16219
16492
|
throw new Error();
|
|
16220
16493
|
restore = wrapClientOwnedVoiceFetch(
|
|
16221
16494
|
client,
|
|
16222
16495
|
bridge,
|
|
16223
16496
|
() => cpaLiveVoicePreferenceAllowsInstall(target),
|
|
16224
|
-
module
|
|
16497
|
+
module[SHARED_RESPONSE_ERROR],
|
|
16498
|
+
() => chatLiveVoicePreferenceAllowsOverride(target),
|
|
16499
|
+
() => isWorkComposerSurface(target),
|
|
16500
|
+
() => isExternalHarnessComposer(target)
|
|
16225
16501
|
);
|
|
16226
16502
|
handle.status = "active";
|
|
16227
16503
|
} catch {
|
|
@@ -16306,8 +16582,432 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16306
16582
|
};
|
|
16307
16583
|
}
|
|
16308
16584
|
|
|
16585
|
+
// ../desktop-control/dist/renderer-react-ownership.js
|
|
16586
|
+
function committedReactAncestors(value) {
|
|
16587
|
+
const MAX_VISITED_FIBERS = 2e5;
|
|
16588
|
+
const fiber = (value2) => typeof value2 === "object" && value2 !== null ? value2 : null;
|
|
16589
|
+
const exhausted = () => {
|
|
16590
|
+
const target = globalThis;
|
|
16591
|
+
if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function")
|
|
16592
|
+
target.dispatchEvent(new CustomEvent("codexhost:react-fiber-walk-limit", {
|
|
16593
|
+
detail: { limit: MAX_VISITED_FIBERS }
|
|
16594
|
+
}));
|
|
16595
|
+
return [];
|
|
16596
|
+
};
|
|
16597
|
+
const first = fiber(value);
|
|
16598
|
+
if (!first)
|
|
16599
|
+
return [];
|
|
16600
|
+
const previous = [];
|
|
16601
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16602
|
+
for (let node = first; node; node = fiber(node.return)) {
|
|
16603
|
+
if (seen.has(node))
|
|
16604
|
+
return [];
|
|
16605
|
+
if (seen.size >= MAX_VISITED_FIBERS)
|
|
16606
|
+
return exhausted();
|
|
16607
|
+
seen.add(node);
|
|
16608
|
+
previous.push(node);
|
|
16609
|
+
}
|
|
16610
|
+
const rootState = fiber(previous.at(-1)?.stateNode);
|
|
16611
|
+
if (!rootState || !("current" in rootState))
|
|
16612
|
+
return previous;
|
|
16613
|
+
const current = fiber(rootState.current);
|
|
16614
|
+
if (!current)
|
|
16615
|
+
return [];
|
|
16616
|
+
const alternate = fiber(first.alternate);
|
|
16617
|
+
const path = [current];
|
|
16618
|
+
seen.clear();
|
|
16619
|
+
seen.add(current);
|
|
16620
|
+
for (let index = previous.length - 2; index >= 0; index -= 1) {
|
|
16621
|
+
const expected = previous[index];
|
|
16622
|
+
const expectedAlternate = fiber(expected?.alternate);
|
|
16623
|
+
let child = fiber(path.at(-1)?.child);
|
|
16624
|
+
let matched = false;
|
|
16625
|
+
while (child && !seen.has(child) && seen.size < MAX_VISITED_FIBERS) {
|
|
16626
|
+
seen.add(child);
|
|
16627
|
+
if (child === expected || child === expectedAlternate) {
|
|
16628
|
+
matched = true;
|
|
16629
|
+
break;
|
|
16630
|
+
}
|
|
16631
|
+
child = fiber(child.sibling);
|
|
16632
|
+
}
|
|
16633
|
+
if (!matched || !child)
|
|
16634
|
+
break;
|
|
16635
|
+
path.push(child);
|
|
16636
|
+
}
|
|
16637
|
+
if (path.length === previous.length && (path.at(-1) === first || path.at(-1) === alternate)) {
|
|
16638
|
+
return path.reverse();
|
|
16639
|
+
}
|
|
16640
|
+
const stack = [{ node: current, parent: null }];
|
|
16641
|
+
seen.clear();
|
|
16642
|
+
while (stack.length > 0 && seen.size < MAX_VISITED_FIBERS) {
|
|
16643
|
+
const entry = stack.pop();
|
|
16644
|
+
if (!entry)
|
|
16645
|
+
break;
|
|
16646
|
+
if (seen.has(entry.node))
|
|
16647
|
+
return [];
|
|
16648
|
+
seen.add(entry.node);
|
|
16649
|
+
if (entry.node === first || entry.node === alternate) {
|
|
16650
|
+
const ancestors = [];
|
|
16651
|
+
for (let cursor = entry; cursor; cursor = cursor.parent)
|
|
16652
|
+
ancestors.push(cursor.node);
|
|
16653
|
+
return ancestors;
|
|
16654
|
+
}
|
|
16655
|
+
const sibling = entry.parent && fiber(entry.node.sibling);
|
|
16656
|
+
if (sibling)
|
|
16657
|
+
stack.push({ node: sibling, parent: entry.parent });
|
|
16658
|
+
const child = fiber(entry.node.child);
|
|
16659
|
+
if (child)
|
|
16660
|
+
stack.push({ node: child, parent: entry });
|
|
16661
|
+
}
|
|
16662
|
+
return stack.length > 0 ? exhausted() : [];
|
|
16663
|
+
}
|
|
16664
|
+
|
|
16665
|
+
// src/renderer-voice-capability.ts
|
|
16666
|
+
var INFERENCE_GATE = "3683713372";
|
|
16667
|
+
var record2 = (value) => value !== null && typeof value === "object";
|
|
16668
|
+
var capable = (value) => record2(value) && typeof value.isLoading === "boolean" && typeof value.isError === "boolean" && typeof value.isCapable === "boolean";
|
|
16669
|
+
var equal = (a, b) => a.isLoading === b.isLoading && a.isError === b.isError && a.isCapable === b.isCapable;
|
|
16670
|
+
function replayVoiceCapability(store, atom, gate) {
|
|
16671
|
+
const evaluate = (override) => {
|
|
16672
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
16673
|
+
let remaining = 512;
|
|
16674
|
+
let hits = 0;
|
|
16675
|
+
const read = (dependency) => {
|
|
16676
|
+
if (--remaining < 0) throw new Error("Voice capability dependency limit");
|
|
16677
|
+
const value = store.get(dependency);
|
|
16678
|
+
if (dependency === gate) {
|
|
16679
|
+
hits += 1;
|
|
16680
|
+
if (typeof value !== "boolean") throw new Error("Voice inference gate unavailable");
|
|
16681
|
+
return override ? false : value;
|
|
16682
|
+
}
|
|
16683
|
+
if (dependency.write || visiting.has(dependency)) return value;
|
|
16684
|
+
if (typeof dependency.read !== "function") throw new Error("Voice dependency unavailable");
|
|
16685
|
+
visiting.add(dependency);
|
|
16686
|
+
try {
|
|
16687
|
+
return dependency.read(read);
|
|
16688
|
+
} finally {
|
|
16689
|
+
visiting.delete(dependency);
|
|
16690
|
+
}
|
|
16691
|
+
};
|
|
16692
|
+
return { value: read(atom), hits };
|
|
16693
|
+
};
|
|
16694
|
+
try {
|
|
16695
|
+
const native = store.get(atom);
|
|
16696
|
+
if (!capable(native) || native.isLoading || native.isError) return null;
|
|
16697
|
+
const before = evaluate(false);
|
|
16698
|
+
if (!capable(before.value) || !equal(native, before.value)) return null;
|
|
16699
|
+
const after = evaluate(true);
|
|
16700
|
+
return after.hits > 0 && capable(after.value) && !after.value.isLoading && !after.value.isError ? after.value : null;
|
|
16701
|
+
} catch {
|
|
16702
|
+
return null;
|
|
16703
|
+
}
|
|
16704
|
+
}
|
|
16705
|
+
function hooks(fiber) {
|
|
16706
|
+
const result = [];
|
|
16707
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16708
|
+
let hook = fiber.memoizedState;
|
|
16709
|
+
while (record2(hook) && result.length < 4096 && !seen.has(hook)) {
|
|
16710
|
+
seen.add(hook);
|
|
16711
|
+
result.push(hook);
|
|
16712
|
+
hook = hook.next;
|
|
16713
|
+
}
|
|
16714
|
+
return hook == null ? result : [];
|
|
16715
|
+
}
|
|
16716
|
+
function bindVoiceCapabilitySubscriptions(currentFibers, family, gates, allowed, realtimeOnly = false) {
|
|
16717
|
+
const fibers = currentFibers();
|
|
16718
|
+
const restores = [];
|
|
16719
|
+
const bindings = [];
|
|
16720
|
+
try {
|
|
16721
|
+
for (const fiber of fibers) {
|
|
16722
|
+
const list = hooks(fiber);
|
|
16723
|
+
for (const memo of list) {
|
|
16724
|
+
const [signal, deps] = Array.isArray(memo.memoizedState) ? memo.memoizedState : [];
|
|
16725
|
+
if (!record2(signal) || !Array.isArray(deps) || deps.length !== 5 || deps[3] !== family || !(deps[1] instanceof Map) || deps[2] !== void 0)
|
|
16726
|
+
continue;
|
|
16727
|
+
const chain = deps[1];
|
|
16728
|
+
const node = chain.get(family.scope.id);
|
|
16729
|
+
const members = node?.familyBindings?.get(family);
|
|
16730
|
+
if (!node || !(members instanceof Map) || node.store !== signal.store) continue;
|
|
16731
|
+
const matches = [...members].filter(([, member]) => member.cacheKey === deps[0]);
|
|
16732
|
+
if (matches.length !== 1 || typeof matches[0]?.[0] !== "string") continue;
|
|
16733
|
+
const parameter = JSON.parse(matches[0][0]);
|
|
16734
|
+
if (!record2(parameter) || Object.keys(parameter).some((key) => key !== "name" && key !== "hostId") || parameter.name !== "voice.realtime" && parameter.name !== "voice.thread" || realtimeOnly && parameter.name !== "voice.realtime" || parameter.hostId !== void 0 && parameter.hostId !== "local" || parameter.name === "voice.thread" && parameter.hostId !== "local")
|
|
16735
|
+
continue;
|
|
16736
|
+
const subscriptions = list.filter((hook2) => {
|
|
16737
|
+
const state = hook2.memoizedState;
|
|
16738
|
+
return Array.isArray(state) && Array.isArray(state[1]) && state[1].length === 2 && state[1][0] === signal && state[1][1] === void 0 && typeof state[0]?.getSnapshot === "function";
|
|
16739
|
+
});
|
|
16740
|
+
if (subscriptions.length !== 1) throw new Error("Ambiguous voice subscription");
|
|
16741
|
+
const hook = subscriptions[0];
|
|
16742
|
+
const subscriber = hook.memoizedState[0];
|
|
16743
|
+
const instance = hook.next?.queue;
|
|
16744
|
+
const effect = hook.next?.next?.memoizedState;
|
|
16745
|
+
const store = signal.store;
|
|
16746
|
+
const gate = gates.resolve(node, chain, INFERENCE_GATE)?.atom;
|
|
16747
|
+
if (!gate || !instance || !record2(effect) || !Array.isArray(effect.deps) || effect.deps[0] !== subscriber.subscribe || typeof effect.create !== "function" || typeof instance.getSnapshot !== "function" || !capable(store.get(signal.atom)) || !capable(subscriber.getSnapshot()) || !capable(instance.getSnapshot()) || !equal(
|
|
16748
|
+
store.get(signal.atom),
|
|
16749
|
+
subscriber.getSnapshot()
|
|
16750
|
+
) || !equal(subscriber.getSnapshot(), instance.getSnapshot()) || subscriber.createRender?.() != null)
|
|
16751
|
+
throw new Error("Unsupported voice subscription");
|
|
16752
|
+
for (const [object3, key] of [
|
|
16753
|
+
[store, "sub"],
|
|
16754
|
+
[subscriber, "getSnapshot"],
|
|
16755
|
+
[instance, "getSnapshot"]
|
|
16756
|
+
])
|
|
16757
|
+
if (Object.getOwnPropertyDescriptor(object3, key)?.writable !== true)
|
|
16758
|
+
throw new Error("Voice subscription is not writable");
|
|
16759
|
+
let notify;
|
|
16760
|
+
const sub = store.sub;
|
|
16761
|
+
try {
|
|
16762
|
+
store.sub = (atom, listener) => {
|
|
16763
|
+
if (atom !== signal.atom || notify) throw new Error("Unexpected voice subscription");
|
|
16764
|
+
notify = listener;
|
|
16765
|
+
return () => {
|
|
16766
|
+
};
|
|
16767
|
+
};
|
|
16768
|
+
effect.create();
|
|
16769
|
+
} finally {
|
|
16770
|
+
store.sub = sub;
|
|
16771
|
+
}
|
|
16772
|
+
if (!notify) throw new Error("Voice listener unavailable");
|
|
16773
|
+
const original = subscriber.getSnapshot;
|
|
16774
|
+
const originalInstance = instance.getSnapshot;
|
|
16775
|
+
let previous;
|
|
16776
|
+
const snapshot = () => {
|
|
16777
|
+
const native = original.call(subscriber);
|
|
16778
|
+
if (!allowed()) return native;
|
|
16779
|
+
const projected = replayVoiceCapability(store, signal.atom, gate);
|
|
16780
|
+
if (!projected || !projected.isCapable) return native;
|
|
16781
|
+
if (!previous || !equal(previous, projected)) previous = projected;
|
|
16782
|
+
return previous;
|
|
16783
|
+
};
|
|
16784
|
+
subscriber.getSnapshot = snapshot;
|
|
16785
|
+
instance.getSnapshot = snapshot;
|
|
16786
|
+
const onChange = notify;
|
|
16787
|
+
restores.push(() => {
|
|
16788
|
+
if (subscriber.getSnapshot === snapshot) subscriber.getSnapshot = original;
|
|
16789
|
+
if (instance.getSnapshot === snapshot) instance.getSnapshot = originalInstance;
|
|
16790
|
+
onChange();
|
|
16791
|
+
});
|
|
16792
|
+
bindings.push({ subscriber, signal, instance });
|
|
16793
|
+
onChange();
|
|
16794
|
+
}
|
|
16795
|
+
}
|
|
16796
|
+
if (!restores.length) throw new Error("Owned voice capability unavailable");
|
|
16797
|
+
if (realtimeOnly && restores.length !== 1) throw new Error("Ambiguous voice starter");
|
|
16798
|
+
} catch (error51) {
|
|
16799
|
+
for (const restore of restores.reverse()) restore();
|
|
16800
|
+
throw error51;
|
|
16801
|
+
}
|
|
16802
|
+
return {
|
|
16803
|
+
dispose() {
|
|
16804
|
+
for (const restore of restores.splice(0).reverse()) restore();
|
|
16805
|
+
},
|
|
16806
|
+
current() {
|
|
16807
|
+
const current = [...currentFibers()].flatMap(hooks);
|
|
16808
|
+
return bindings.every(
|
|
16809
|
+
({ subscriber, signal, instance }) => current.some(
|
|
16810
|
+
(hook) => Array.isArray(hook.memoizedState) && hook.memoizedState[0] === subscriber && hook.memoizedState[1]?.[0] === signal && hook.next?.queue === instance && (!realtimeOnly || capable(hook.next?.memoizedState) && hook.next.memoizedState.isCapable)
|
|
16811
|
+
)
|
|
16812
|
+
);
|
|
16813
|
+
}
|
|
16814
|
+
};
|
|
16815
|
+
}
|
|
16816
|
+
|
|
16817
|
+
// src/renderer-voice-start-capability.ts
|
|
16818
|
+
var GLOBAL = "__codexhostVoiceStartCapabilityV1";
|
|
16819
|
+
var record3 = (v) => v !== null && typeof v === "object";
|
|
16820
|
+
function gatewayVoiceStartRequest(request, workGateway, chatGateway = false) {
|
|
16821
|
+
if (!record3(request) || request.productExperience !== "work" && request.productExperience !== "chat")
|
|
16822
|
+
return false;
|
|
16823
|
+
if (request.source === "composer_button_existing_thread") {
|
|
16824
|
+
if (!record3(request.locator) || request.locator.hostId !== "local") return false;
|
|
16825
|
+
} else if (request.source !== "composer_button_new_thread" || (request.hostId ?? "local") !== "local")
|
|
16826
|
+
return false;
|
|
16827
|
+
if (request.productExperience === "chat") return chatGateway;
|
|
16828
|
+
const mode = request.activeCollaborationMode;
|
|
16829
|
+
const settings = record3(mode) ? mode.settings : void 0;
|
|
16830
|
+
const model2 = record3(settings) ? settings.model : void 0;
|
|
16831
|
+
return workGateway || typeof model2 === "string" && model2.startsWith("codexhost/");
|
|
16832
|
+
}
|
|
16833
|
+
function wrapGatewayVoiceStarter(start, options) {
|
|
16834
|
+
let active;
|
|
16835
|
+
return {
|
|
16836
|
+
async start(...args) {
|
|
16837
|
+
if (!options.qualifies(args[0])) return start(...args);
|
|
16838
|
+
if (active) throw new Error("Voice gateway start is already pending");
|
|
16839
|
+
const attempt = {};
|
|
16840
|
+
active = attempt;
|
|
16841
|
+
const allowed = () => active === attempt && options.qualifies(args[0]);
|
|
16842
|
+
try {
|
|
16843
|
+
if (!await options.ready()) throw new Error("Voice gateway is not ready");
|
|
16844
|
+
if (!allowed()) throw new Error("Voice gateway start was cancelled");
|
|
16845
|
+
attempt.binding = await options.prepare(allowed);
|
|
16846
|
+
await options.committed(attempt.binding);
|
|
16847
|
+
if (!allowed()) throw new Error("Voice gateway start was cancelled");
|
|
16848
|
+
if (!attempt.binding.current()) throw new Error("Voice starter subscription changed");
|
|
16849
|
+
rememberVoiceProductExperience(args[0]);
|
|
16850
|
+
return await start(...args);
|
|
16851
|
+
} finally {
|
|
16852
|
+
attempt.binding?.dispose();
|
|
16853
|
+
if (active === attempt) active = void 0;
|
|
16854
|
+
}
|
|
16855
|
+
},
|
|
16856
|
+
cancel() {
|
|
16857
|
+
active?.binding?.dispose();
|
|
16858
|
+
active = void 0;
|
|
16859
|
+
}
|
|
16860
|
+
};
|
|
16861
|
+
}
|
|
16862
|
+
function overlayVoiceStarterFibers(document, page) {
|
|
16863
|
+
const fibers = /* @__PURE__ */ new Set();
|
|
16864
|
+
for (const element of document.querySelectorAll("[data-avatar-overlay-native-surface-id]")) {
|
|
16865
|
+
const key = Object.getOwnPropertyNames(element).find((key2) => key2.startsWith("__reactFiber$"));
|
|
16866
|
+
const ancestors = committedReactAncestors(
|
|
16867
|
+
key && Object.getOwnPropertyDescriptor(element, key)?.value
|
|
16868
|
+
);
|
|
16869
|
+
const boundary = ancestors.findIndex((fiber) => record3(fiber) && fiber.type === page);
|
|
16870
|
+
if (boundary < 0) continue;
|
|
16871
|
+
for (const fiber of ancestors.slice(0, boundary)) if (record3(fiber)) fibers.add(fiber);
|
|
16872
|
+
}
|
|
16873
|
+
return fibers;
|
|
16874
|
+
}
|
|
16875
|
+
function installVoiceStartCapabilityHook(options = {}) {
|
|
16876
|
+
const target = options.target ?? globalThis;
|
|
16877
|
+
if (target[GLOBAL]) return target[GLOBAL];
|
|
16878
|
+
const config2 = readCpaLiveVoiceHookConfig(target);
|
|
16879
|
+
if (!config2 || !isAvatarOverlayHref(target.location?.href ?? ""))
|
|
16880
|
+
return { status: "disabled", dispose() {
|
|
16881
|
+
} };
|
|
16882
|
+
if (!supportsVoiceVersion(CLIENT_OWNED_VOICE_ASSETS, config2.desktopVersion))
|
|
16883
|
+
return { status: "unsupported", dispose() {
|
|
16884
|
+
} };
|
|
16885
|
+
const importModule = options.importModule ?? ((url2) => import(url2));
|
|
16886
|
+
let disposed = false;
|
|
16887
|
+
let timer;
|
|
16888
|
+
let restore;
|
|
16889
|
+
const wrappers = /* @__PURE__ */ new Set();
|
|
16890
|
+
const started = Date.now();
|
|
16891
|
+
const handle = {
|
|
16892
|
+
status: "pending",
|
|
16893
|
+
dispose() {
|
|
16894
|
+
disposed = true;
|
|
16895
|
+
target.clearTimeout(timer);
|
|
16896
|
+
for (const wrapper of wrappers) wrapper.cancel();
|
|
16897
|
+
restore?.();
|
|
16898
|
+
if (target[GLOBAL] === handle) Reflect.deleteProperty(target, GLOBAL);
|
|
16899
|
+
}
|
|
16900
|
+
};
|
|
16901
|
+
target[GLOBAL] = handle;
|
|
16902
|
+
const attempt = async () => {
|
|
16903
|
+
if (disposed) return;
|
|
16904
|
+
try {
|
|
16905
|
+
const names = loadedAssetNames(target.document, target.performance);
|
|
16906
|
+
const assets = selectVoiceAssets(CLIENT_OWNED_VOICE_ASSETS, names, config2.desktopVersion);
|
|
16907
|
+
if (assets) {
|
|
16908
|
+
const shared = await importModule(`app://-/assets/${assets.shared}`);
|
|
16909
|
+
if (typeof shared.Oit !== "function") throw new Error("Voice bridge unavailable");
|
|
16910
|
+
shared.Oit();
|
|
16911
|
+
const services = shared[CLIENT_OWNED_VOICE_SERVICES];
|
|
16912
|
+
if (record3(services) && (record3(services.realtimeVoiceRuntime) || typeof services.realtimeVoiceRuntime === "function")) {
|
|
16913
|
+
const original = services.realtimeVoiceRuntime;
|
|
16914
|
+
const register = Reflect.get(original, "registerRealtimeStarter");
|
|
16915
|
+
if (typeof register !== "function") throw new Error("Voice starter unavailable");
|
|
16916
|
+
const wrapped = new Proxy(original, {
|
|
16917
|
+
get(service, key, receiver) {
|
|
16918
|
+
if (key === "registerRealtimeStarter")
|
|
16919
|
+
return (start, cancel, ...rest) => {
|
|
16920
|
+
if (typeof start !== "function" || typeof cancel !== "function")
|
|
16921
|
+
throw new Error("Voice starter callback unavailable");
|
|
16922
|
+
const wrapper = wrapGatewayVoiceStarter(start, {
|
|
16923
|
+
qualifies: (request) => !disposed && !!readCpaLiveVoiceHookConfig(target) && gatewayVoiceStartRequest(
|
|
16924
|
+
request,
|
|
16925
|
+
cpaLiveVoicePreferenceAllowsInstall(target),
|
|
16926
|
+
chatLiveVoicePreferenceAllowsOverride(target)
|
|
16927
|
+
),
|
|
16928
|
+
ready: async () => {
|
|
16929
|
+
const hook = target.__codexhostClientOwnedVoiceV1;
|
|
16930
|
+
if (!record3(hook) || hook.status !== "active") return false;
|
|
16931
|
+
const bridgeClass = shared.AFt;
|
|
16932
|
+
const result = await requestVoiceHost(
|
|
16933
|
+
bridgeClass.getInstance(),
|
|
16934
|
+
{},
|
|
16935
|
+
VOICE_GATEWAY_STATUS_METHOD
|
|
16936
|
+
);
|
|
16937
|
+
return result === true;
|
|
16938
|
+
},
|
|
16939
|
+
prepare: async (allowed) => {
|
|
16940
|
+
const names2 = loadedAssetNames(target.document, target.performance);
|
|
16941
|
+
if (!auditedAppInitialAssetPresent(names2, assets.overlay))
|
|
16942
|
+
throw new Error("Unaudited voice starter");
|
|
16943
|
+
const [initial, overlay] = await Promise.all([
|
|
16944
|
+
importModule(`app://-/assets/${assets.initial}`),
|
|
16945
|
+
importModule(`app://-/assets/${assets.overlay}`)
|
|
16946
|
+
]);
|
|
16947
|
+
if (typeof initial.njr !== "function" || typeof overlay.AvatarOverlayNativePage !== "function" || !target.document)
|
|
16948
|
+
throw new Error("Voice starter owner unavailable");
|
|
16949
|
+
const document = target.document;
|
|
16950
|
+
initial.njr();
|
|
16951
|
+
return bindVoiceCapabilitySubscriptions(
|
|
16952
|
+
() => overlayVoiceStarterFibers(document, overlay.AvatarOverlayNativePage),
|
|
16953
|
+
initial.tjr,
|
|
16954
|
+
initial.uBr,
|
|
16955
|
+
allowed,
|
|
16956
|
+
true
|
|
16957
|
+
);
|
|
16958
|
+
},
|
|
16959
|
+
// Wait for React's committed snapshot, including when the
|
|
16960
|
+
// persistent overlay is hidden. A stale closure fails closed.
|
|
16961
|
+
committed: async (binding) => {
|
|
16962
|
+
for (let i = 0; i < 40 && !disposed && !binding.current(); i += 1)
|
|
16963
|
+
await new Promise((resolve) => target.setTimeout(resolve, 50));
|
|
16964
|
+
}
|
|
16965
|
+
});
|
|
16966
|
+
wrappers.add(wrapper);
|
|
16967
|
+
return Reflect.apply(register, original, [
|
|
16968
|
+
wrapper.start,
|
|
16969
|
+
(...args) => {
|
|
16970
|
+
wrapper.cancel();
|
|
16971
|
+
return cancel(...args);
|
|
16972
|
+
},
|
|
16973
|
+
...rest
|
|
16974
|
+
]);
|
|
16975
|
+
};
|
|
16976
|
+
if (key === "unregisterRealtimeStarter")
|
|
16977
|
+
return (...args) => {
|
|
16978
|
+
for (const wrapper of wrappers) wrapper.cancel();
|
|
16979
|
+
wrappers.clear();
|
|
16980
|
+
return Reflect.apply(Reflect.get(service, key), service, args);
|
|
16981
|
+
};
|
|
16982
|
+
return Reflect.get(service, key, receiver);
|
|
16983
|
+
}
|
|
16984
|
+
});
|
|
16985
|
+
if (disposed) return;
|
|
16986
|
+
if (!Reflect.set(services, "realtimeVoiceRuntime", wrapped))
|
|
16987
|
+
throw new Error("Voice service is not writable");
|
|
16988
|
+
restore = () => {
|
|
16989
|
+
if (services.realtimeVoiceRuntime === wrapped) services.realtimeVoiceRuntime = original;
|
|
16990
|
+
};
|
|
16991
|
+
handle.status = "active";
|
|
16992
|
+
return;
|
|
16993
|
+
}
|
|
16994
|
+
}
|
|
16995
|
+
if (Date.now() - started >= 6e4) {
|
|
16996
|
+
handle.status = "unsupported";
|
|
16997
|
+
return;
|
|
16998
|
+
}
|
|
16999
|
+
timer = target.setTimeout(() => void attempt(), 25);
|
|
17000
|
+
} catch {
|
|
17001
|
+
handle.status = "unsupported";
|
|
17002
|
+
}
|
|
17003
|
+
};
|
|
17004
|
+
void attempt();
|
|
17005
|
+
return handle;
|
|
17006
|
+
}
|
|
17007
|
+
|
|
16309
17008
|
// src/cpa-live-voice-entry.ts
|
|
16310
17009
|
installCpaLiveVoiceHook();
|
|
16311
17010
|
installClientOwnedVoiceHook();
|
|
17011
|
+
installVoiceStartCapabilityHook();
|
|
16312
17012
|
installOverlayThreadIsolation();
|
|
16313
17013
|
})();
|