@karlorz/codexhost-cli-win32-arm64 0.13.3-6 → 0.14.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +539 -95
- package/app/console-web.js +879 -73
- package/app/cpa-live-voice-hook.js +605 -37
- package/app/desktop-controller.mjs +94 -9
- package/app/host-runtime.mjs +1662 -642
- package/app/plugins/antigravity/plugin.mjs +113 -13
- package/app/plugins/claude-code/plugin.mjs +429 -26
- package/app/plugins/codebuddy/plugin.mjs +139 -22
- package/app/plugins/codex-usage/plugin.mjs +198 -74
- package/app/plugins/copilot/assets/icon.png +0 -0
- package/app/plugins/copilot/manifest.json +26 -0
- package/app/plugins/copilot/plugin.mjs +34645 -0
- package/app/plugins/cursor-cli/plugin.mjs +20877 -44973
- package/app/plugins/deepseek-harness/plugin.mjs +105 -11
- package/app/plugins/enabled.json +1 -0
- package/app/plugins/grok/plugin.mjs +1073 -214
- package/app/plugins/hermes/plugin.mjs +102 -9
- package/app/plugins/kimi-code/plugin.mjs +98 -7
- package/app/plugins/kiro-cli/plugin.mjs +98 -7
- package/app/plugins/omp/plugin.mjs +2177 -2000
- package/app/plugins/opencode/plugin.mjs +107 -11
- package/app/plugins/pi/plugin.mjs +2554 -2285
- package/app/plugins/qoder/plugin.mjs +105 -11
- package/app/plugins/qoder-cn/plugin.mjs +105 -11
- package/app/plugins/workbuddy/plugin.mjs +400 -46
- package/app/plugins/zcode/plugin.mjs +106 -11
- package/app/renderer-extension.js +2717 -1237
- 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
|
@@ -14657,10 +14657,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14657
14657
|
var project = external_exports.string().min(1).max(4096);
|
|
14658
14658
|
var usageStatisticsParamsSchema = external_exports.strictObject({
|
|
14659
14659
|
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
14660
|
+
/** Display timezone for ranges, dates and hourly buckets; omitted means the Host's local zone. */
|
|
14661
|
+
timeZone: external_exports.string().min(1).max(128).refine((value) => {
|
|
14662
|
+
try {
|
|
14663
|
+
new Intl.DateTimeFormat("en", { timeZone: value });
|
|
14664
|
+
return true;
|
|
14665
|
+
} catch {
|
|
14666
|
+
return false;
|
|
14667
|
+
}
|
|
14668
|
+
}, "Unsupported usage statistics timezone").optional(),
|
|
14660
14669
|
harness: harness.optional(),
|
|
14661
14670
|
model: model.nullable().optional(),
|
|
14662
14671
|
project: project.nullable().optional(),
|
|
14663
|
-
/** One
|
|
14672
|
+
/** One date in the query timezone inside the range. */
|
|
14664
14673
|
date: localDate.optional()
|
|
14665
14674
|
});
|
|
14666
14675
|
var usageStatisticsTotalsSchema = external_exports.strictObject({
|
|
@@ -14696,7 +14705,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14696
14705
|
});
|
|
14697
14706
|
var usageStatisticsResultSchema = external_exports.strictObject({
|
|
14698
14707
|
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
14699
|
-
/** First
|
|
14708
|
+
/** First date in the query timezone (Host local when omitted); null for all time. */
|
|
14700
14709
|
from: localDate.nullable(),
|
|
14701
14710
|
to: localDate,
|
|
14702
14711
|
/** The filters these figures apply, echoed so a late answer to older filters is recognised. */
|
|
@@ -14736,7 +14745,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14736
14745
|
totals: usageStatisticsTotalsSchema,
|
|
14737
14746
|
/** Each date and Harness of the range: every filter except the day. */
|
|
14738
14747
|
daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
|
|
14739
|
-
/**
|
|
14748
|
+
/** Weekday (0 = Sunday) and hour in the query timezone, all filters applied. */
|
|
14740
14749
|
hourly: external_exports.array(external_exports.strictObject({
|
|
14741
14750
|
weekday: external_exports.number().int().min(0).max(6),
|
|
14742
14751
|
hour: external_exports.number().int().min(0).max(23),
|
|
@@ -14846,8 +14855,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14846
14855
|
"codexhost/harness/display-settings/set",
|
|
14847
14856
|
"codexhost/harness/inspect",
|
|
14848
14857
|
"codexhost/harness/installation",
|
|
14858
|
+
"codexhost/harness/installation/start",
|
|
14859
|
+
"codexhost/harness/installation/status",
|
|
14849
14860
|
"codexhost/harness/launch-settings/get",
|
|
14850
14861
|
"codexhost/harness/launch-settings/set",
|
|
14862
|
+
"codexhost/harness/grok-computer-use/get",
|
|
14863
|
+
"codexhost/harness/grok-computer-use/set",
|
|
14851
14864
|
"codexhost/harness/web-ui/open",
|
|
14852
14865
|
"codexhost/harness/accounts/sources",
|
|
14853
14866
|
"codexhost/harness/accounts/list",
|
|
@@ -14921,7 +14934,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14921
14934
|
var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
|
|
14922
14935
|
var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
|
|
14923
14936
|
var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
14937
|
+
var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text) => text.length <= maximum));
|
|
14938
|
+
var composerIndicatorsSchema = external_exports.array(external_exports.object({
|
|
14939
|
+
kind: external_exports.literal("countdown"),
|
|
14940
|
+
id: external_exports.string().min(1).max(64),
|
|
14941
|
+
expiresAtUnix: nonNegativeSafeIntegerSchema,
|
|
14942
|
+
label: indicatorTextSchema(256).optional(),
|
|
14943
|
+
tooltip: indicatorTextSchema(1024).optional()
|
|
14944
|
+
}).strict()).max(2).refine((entries) => new Set(entries.map(({ id }) => id)).size === entries.length, {
|
|
14945
|
+
message: "Composer indicator IDs must be unique"
|
|
14946
|
+
});
|
|
14924
14947
|
var threadUsageSnapshotSchema = external_exports.object({
|
|
14948
|
+
composerIndicators: composerIndicatorsSchema.optional(),
|
|
14925
14949
|
inputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14926
14950
|
cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14927
14951
|
cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -15329,7 +15353,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15329
15353
|
}).strict().optional(),
|
|
15330
15354
|
autonomousTurns: external_exports.object({
|
|
15331
15355
|
observe: external_exports.boolean()
|
|
15332
|
-
}).strict().optional()
|
|
15356
|
+
}).strict().optional(),
|
|
15357
|
+
/** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
|
|
15358
|
+
steer: external_exports.boolean().optional()
|
|
15333
15359
|
}).strict();
|
|
15334
15360
|
var harnessConfigurationStateSchema = external_exports.object({
|
|
15335
15361
|
effectiveModel: harnessModelRefSchema.optional(),
|
|
@@ -15376,7 +15402,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15376
15402
|
var harnessInspectParamsSchema = external_exports.object({
|
|
15377
15403
|
harnessId: harnessIdSchema,
|
|
15378
15404
|
cwd: nonBlankTextSchema2.max(16384).optional(),
|
|
15379
|
-
refresh: external_exports.boolean().optional()
|
|
15405
|
+
refresh: external_exports.boolean().optional(),
|
|
15406
|
+
/** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
|
|
15407
|
+
purpose: external_exports.literal("availability").optional()
|
|
15380
15408
|
}).strict();
|
|
15381
15409
|
var harnessWebUiOpenParamsSchema = external_exports.object({
|
|
15382
15410
|
harnessId: harnessIdSchema
|
|
@@ -15459,6 +15487,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15459
15487
|
seen.add(thread.threadId);
|
|
15460
15488
|
}
|
|
15461
15489
|
});
|
|
15490
|
+
var threadSteeringInspectParamsSchema = external_exports.object({
|
|
15491
|
+
threadId: hostThreadIdSchema,
|
|
15492
|
+
/** The text about to be steered; a Harness command always stops and restarts. */
|
|
15493
|
+
text: external_exports.string().optional()
|
|
15494
|
+
}).strict();
|
|
15495
|
+
var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
|
|
15496
|
+
var threadSteeringInspectResultSchema = external_exports.object({
|
|
15497
|
+
delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
|
|
15498
|
+
}).strict();
|
|
15462
15499
|
|
|
15463
15500
|
// ../shared-contracts/dist/harness-plugins.js
|
|
15464
15501
|
var HARNESS_PLUGIN_MANIFEST_MAX_BYTES = 32 * 1024;
|
|
@@ -15550,6 +15587,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15550
15587
|
restartRequired: external_exports.boolean()
|
|
15551
15588
|
}).strict();
|
|
15552
15589
|
|
|
15590
|
+
// ../shared-contracts/dist/grok-computer-use.js
|
|
15591
|
+
var grokComputerUseGetSchema = external_exports.object({}).strict();
|
|
15592
|
+
var grokComputerUseSetSchema = external_exports.object({
|
|
15593
|
+
enabled: external_exports.boolean().optional(),
|
|
15594
|
+
browser: external_exports.boolean().optional()
|
|
15595
|
+
}).strict().refine((value) => value.enabled !== void 0 || value.browser !== void 0, {
|
|
15596
|
+
message: "Expected enabled or browser"
|
|
15597
|
+
});
|
|
15598
|
+
var grokComputerUseSettingsSchema = external_exports.object({
|
|
15599
|
+
enabled: external_exports.boolean(),
|
|
15600
|
+
available: external_exports.boolean(),
|
|
15601
|
+
unavailableReason: external_exports.string().min(1).max(500).optional(),
|
|
15602
|
+
browser: external_exports.boolean().optional(),
|
|
15603
|
+
browserFilesPresent: external_exports.boolean().optional(),
|
|
15604
|
+
browserAvailable: external_exports.boolean().optional(),
|
|
15605
|
+
browserUnavailableReason: external_exports.string().min(1).max(500).optional(),
|
|
15606
|
+
applyFailed: external_exports.boolean().optional(),
|
|
15607
|
+
applyError: external_exports.string().min(1).max(500).optional()
|
|
15608
|
+
}).strict();
|
|
15609
|
+
|
|
15553
15610
|
// ../shared-contracts/dist/harness-installation.js
|
|
15554
15611
|
var harnessInstallationParamsSchema = external_exports.object({
|
|
15555
15612
|
harnessId: harnessIdSchema,
|
|
@@ -15560,6 +15617,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15560
15617
|
latestVersion: external_exports.string().min(1).max(128),
|
|
15561
15618
|
updateAvailable: external_exports.boolean(),
|
|
15562
15619
|
canUpdate: external_exports.boolean(),
|
|
15620
|
+
/** Defaults to CLI; some Harnesses ship only inside a desktop application. */
|
|
15621
|
+
versionKind: external_exports.enum(["cli", "application"]).optional(),
|
|
15622
|
+
/** Official download opened by the user; does not imply an automatic installation. */
|
|
15623
|
+
manualUpdateUrl: external_exports.url().max(2048).refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Manual updates require a credential-free HTTPS URL").optional(),
|
|
15563
15624
|
// Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
|
|
15564
15625
|
message: external_exports.string().max(2048).optional(),
|
|
15565
15626
|
messageCode: external_exports.string().min(1).max(128).optional(),
|
|
@@ -15567,6 +15628,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15567
15628
|
notice: harnessLocalizedTextSchema.optional(),
|
|
15568
15629
|
latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
|
|
15569
15630
|
}).strict();
|
|
15631
|
+
var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
|
|
15632
|
+
var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
|
|
15633
|
+
external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
|
|
15634
|
+
external_exports.object({
|
|
15635
|
+
taskId: external_exports.string().uuid(),
|
|
15636
|
+
status: external_exports.literal("succeeded"),
|
|
15637
|
+
result: harnessInstallationStateSchema
|
|
15638
|
+
}).strict(),
|
|
15639
|
+
external_exports.object({
|
|
15640
|
+
taskId: external_exports.string().uuid(),
|
|
15641
|
+
status: external_exports.literal("failed"),
|
|
15642
|
+
error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
|
|
15643
|
+
}).strict()
|
|
15644
|
+
]);
|
|
15570
15645
|
|
|
15571
15646
|
// ../shared-contracts/dist/codex-accounts.js
|
|
15572
15647
|
var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
|
|
@@ -15943,6 +16018,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15943
16018
|
]);
|
|
15944
16019
|
|
|
15945
16020
|
// ../shared-contracts/dist/voice-settings.js
|
|
16021
|
+
var VOICE_GATEWAY_STATUS_METHOD = "codexhost/voice/gateway-status";
|
|
15946
16022
|
var voiceRoutesSchema = external_exports.strictObject({
|
|
15947
16023
|
chatExperience: external_exports.enum(["chatgpt", "codex"]),
|
|
15948
16024
|
chatConnection: external_exports.enum(["desktop", "gateway"]),
|
|
@@ -15992,7 +16068,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15992
16068
|
var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
|
|
15993
16069
|
|
|
15994
16070
|
// src/renderer-cpa-live-voice-preference.ts
|
|
15995
|
-
var
|
|
16071
|
+
var voiceStateOwner = globalThis;
|
|
16072
|
+
var { sharedRoutes, gatewayReady } = voiceStateOwner.__codexhostVoicePreferenceStateV1 ??= {
|
|
16073
|
+
sharedRoutes: /* @__PURE__ */ new WeakMap(),
|
|
16074
|
+
gatewayReady: /* @__PURE__ */ new WeakMap()
|
|
16075
|
+
};
|
|
15996
16076
|
var SHARED_VOICE_CACHE = "codexhost.voice-routes-cache.v1";
|
|
15997
16077
|
function cachedRoutes(owner) {
|
|
15998
16078
|
const memory = sharedRoutes.get(owner);
|
|
@@ -16166,6 +16246,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16166
16246
|
return handle;
|
|
16167
16247
|
}
|
|
16168
16248
|
|
|
16249
|
+
// src/renderer-voice-assets.ts
|
|
16250
|
+
function supportsVoiceVersion(profiles, version2) {
|
|
16251
|
+
return version2 === void 0 || profiles.some((profile) => profile.version === version2);
|
|
16252
|
+
}
|
|
16253
|
+
function selectVoiceAssets(profiles, names, version2) {
|
|
16254
|
+
const present = profiles.filter(
|
|
16255
|
+
(profile2) => [profile2.initial, profile2.shared].some((asset) => auditedAppInitialAssetPresent(names, asset))
|
|
16256
|
+
);
|
|
16257
|
+
const profile = present.length === 1 ? present[0] : void 0;
|
|
16258
|
+
return profile && (version2 === void 0 || profile.version === version2) && [profile.initial, profile.shared].every((asset) => auditedAppInitialAssetPresent(names, asset)) ? profile : void 0;
|
|
16259
|
+
}
|
|
16260
|
+
|
|
16169
16261
|
// src/renderer-chat-voice-debug.ts
|
|
16170
16262
|
var CHAT_VOICE_DEBUG_GLOBAL = "__codexhostChatVoiceDebug";
|
|
16171
16263
|
var CHAT_VOICE_DEBUG_STORAGE_KEY = "codexhost.chat-voice-debug.v1";
|
|
@@ -16187,14 +16279,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16187
16279
|
var RENDERER_NEW_THREAD_PREFERENCE_KEY = "codexhost.new-thread-preference.v1";
|
|
16188
16280
|
|
|
16189
16281
|
// src/renderer-client-owned-voice.ts
|
|
16190
|
-
var CLIENT_OWNED_VOICE_VERSION = "26.
|
|
16191
|
-
var CLIENT_OWNED_VOICE_INITIAL_ASSET = "app-initial-
|
|
16192
|
-
var CLIENT_OWNED_VOICE_SHARED_ASSET = "app-shared-
|
|
16282
|
+
var CLIENT_OWNED_VOICE_VERSION = "26.1016.62342";
|
|
16283
|
+
var CLIENT_OWNED_VOICE_INITIAL_ASSET = "app-initial-dddef47d6ef6.js";
|
|
16284
|
+
var CLIENT_OWNED_VOICE_SHARED_ASSET = "app-shared-fc3316d48427.js";
|
|
16285
|
+
var CLIENT_OWNED_VOICE_SERVICES = "ist";
|
|
16286
|
+
var CLIENT_OWNED_VOICE_OVERLAY_ASSET = "avatar-overlay-native-page-ef8332c6a2fb.js";
|
|
16287
|
+
var CLIENT_OWNED_VOICE_ASSETS = [
|
|
16288
|
+
{
|
|
16289
|
+
version: CLIENT_OWNED_VOICE_VERSION,
|
|
16290
|
+
initial: CLIENT_OWNED_VOICE_INITIAL_ASSET,
|
|
16291
|
+
shared: CLIENT_OWNED_VOICE_SHARED_ASSET,
|
|
16292
|
+
overlay: CLIENT_OWNED_VOICE_OVERLAY_ASSET
|
|
16293
|
+
},
|
|
16294
|
+
{
|
|
16295
|
+
version: "26.1016.61520",
|
|
16296
|
+
initial: "app-initial-c95ddb62696e.js",
|
|
16297
|
+
shared: "app-shared-2eda13eb7044.js",
|
|
16298
|
+
overlay: "avatar-overlay-native-page-fcc17283519a.js"
|
|
16299
|
+
}
|
|
16300
|
+
];
|
|
16301
|
+
var SHARED_INIT = "Oit";
|
|
16302
|
+
var SHARED_FETCH = "Eit";
|
|
16303
|
+
var SHARED_BRIDGE = "AFt";
|
|
16304
|
+
var SHARED_RESPONSE_ERROR = "Mit";
|
|
16193
16305
|
var HOOK_GLOBAL = "__codexhostClientOwnedVoiceV1";
|
|
16194
16306
|
function object2(value) {
|
|
16195
16307
|
return value !== null && typeof value === "object";
|
|
16196
16308
|
}
|
|
16197
|
-
function
|
|
16309
|
+
function requestVoiceHost(bridge, params, method = REALTIME_CALL_METHOD) {
|
|
16198
16310
|
const id = `codexhost-voice:${crypto.randomUUID()}`;
|
|
16199
16311
|
return new Promise((resolve, reject) => {
|
|
16200
16312
|
let unsubscribe = () => {
|
|
@@ -16217,7 +16329,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16217
16329
|
try {
|
|
16218
16330
|
bridge.dispatchMessage("mcp-request", {
|
|
16219
16331
|
hostId: "local",
|
|
16220
|
-
request: { id, method
|
|
16332
|
+
request: { id, method, params }
|
|
16221
16333
|
});
|
|
16222
16334
|
} catch {
|
|
16223
16335
|
done();
|
|
@@ -16242,24 +16354,50 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16242
16354
|
if (model2.startsWith("codexhost/")) return true;
|
|
16243
16355
|
return model2.includes("codex") && !model2.includes("gpt-live");
|
|
16244
16356
|
}
|
|
16357
|
+
function visibleWorkComposer(owner) {
|
|
16358
|
+
const document = owner.document;
|
|
16359
|
+
if (!document?.querySelectorAll) return false;
|
|
16360
|
+
const work = [...document.querySelectorAll("[data-codex-composer-root]")].some((element) => {
|
|
16361
|
+
const box = element.getBoundingClientRect?.() ?? { width: 0 };
|
|
16362
|
+
return box.width > 0 && !element.closest?.("[hidden], [inert]");
|
|
16363
|
+
});
|
|
16364
|
+
return work && document.querySelectorAll("[data-chatgpt-composer]").length === 0;
|
|
16365
|
+
}
|
|
16366
|
+
function selectedWorkTab(owner) {
|
|
16367
|
+
const document = owner.document;
|
|
16368
|
+
if (!document?.querySelectorAll) return false;
|
|
16369
|
+
const controls = document.querySelectorAll("button, [role='tab'], a");
|
|
16370
|
+
let workSelected = false;
|
|
16371
|
+
let chatSelected = false;
|
|
16372
|
+
for (const element of controls) {
|
|
16373
|
+
const name = (element.textContent ?? "").replace(/\s+/gu, " ").trim();
|
|
16374
|
+
if (name !== "Chat" && name !== "Work") continue;
|
|
16375
|
+
const selected = element.getAttribute("aria-selected") === "true" || element.getAttribute("aria-pressed") === "true" || element.getAttribute("data-state") === "active" || element.getAttribute("data-state") === "on";
|
|
16376
|
+
if (!selected) continue;
|
|
16377
|
+
if (name === "Work") workSelected = true;
|
|
16378
|
+
if (name === "Chat") chatSelected = true;
|
|
16379
|
+
}
|
|
16380
|
+
return workSelected && !chatSelected;
|
|
16381
|
+
}
|
|
16245
16382
|
function isWorkComposerSurface(owner = globalThis) {
|
|
16246
16383
|
const storage = owner.localStorage;
|
|
16247
|
-
if (!storage) return false;
|
|
16248
16384
|
try {
|
|
16249
|
-
const raw = storage
|
|
16250
|
-
if (raw
|
|
16251
|
-
|
|
16252
|
-
|
|
16253
|
-
|
|
16254
|
-
|
|
16255
|
-
|
|
16256
|
-
|
|
16385
|
+
const raw = storage?.getItem(HOME_COMPOSER_MODE_STORAGE_KEY);
|
|
16386
|
+
if (raw != null && raw !== "") {
|
|
16387
|
+
let value = raw;
|
|
16388
|
+
if (raw.startsWith("{") || raw.startsWith('"') || raw.startsWith("[")) {
|
|
16389
|
+
try {
|
|
16390
|
+
value = JSON.parse(raw);
|
|
16391
|
+
} catch {
|
|
16392
|
+
value = raw;
|
|
16393
|
+
}
|
|
16257
16394
|
}
|
|
16395
|
+
if (value === "work") return true;
|
|
16396
|
+
if (value === "chat") return false;
|
|
16258
16397
|
}
|
|
16259
|
-
return value === "work";
|
|
16260
16398
|
} catch {
|
|
16261
|
-
return false;
|
|
16262
16399
|
}
|
|
16400
|
+
return selectedWorkTab(owner) || visibleWorkComposer(owner);
|
|
16263
16401
|
}
|
|
16264
16402
|
function selectedComposerModel(owner) {
|
|
16265
16403
|
const routing = owner.__codexhostHostRoutingV1;
|
|
@@ -16271,6 +16409,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16271
16409
|
}
|
|
16272
16410
|
}
|
|
16273
16411
|
var lastVoiceProductExperience;
|
|
16412
|
+
function rememberVoiceProductExperience(request) {
|
|
16413
|
+
const experience = object2(request) ? request.productExperience : void 0;
|
|
16414
|
+
lastVoiceProductExperience = experience === "chat" || experience === "work" ? experience : void 0;
|
|
16415
|
+
}
|
|
16274
16416
|
function lastVoiceLaunchProductExperience() {
|
|
16275
16417
|
return lastVoiceProductExperience;
|
|
16276
16418
|
}
|
|
@@ -16292,16 +16434,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16292
16434
|
const wrapped = async function(url2, options) {
|
|
16293
16435
|
if (typeof url2 !== "string" || url2.split("?")[0] !== "/wham/realtime/calls" || options?.method !== "POST")
|
|
16294
16436
|
return original.call(this, url2, options);
|
|
16295
|
-
const
|
|
16437
|
+
const experience = lastVoiceLaunchProductExperience();
|
|
16438
|
+
const chat = experience === "chat";
|
|
16296
16439
|
const model2 = backendModelName(options.headers);
|
|
16297
|
-
const work = !chat && (isWorkBackendModel(model2) || workSurface());
|
|
16440
|
+
const work = !chat && (experience === "work" || isWorkBackendModel(model2) || workSurface());
|
|
16298
16441
|
const external = !chat && (model2.startsWith("codexhost/") || externalHarness());
|
|
16299
16442
|
const gateway = external || (work ? workOverride() : chatOverride());
|
|
16300
16443
|
chatVoiceDebug("wham-create", {
|
|
16301
16444
|
work,
|
|
16302
16445
|
external,
|
|
16303
16446
|
route: gateway ? "gateway" : "desktop",
|
|
16304
|
-
productExperience:
|
|
16447
|
+
productExperience: experience ?? "unset"
|
|
16305
16448
|
});
|
|
16306
16449
|
if (!gateway) {
|
|
16307
16450
|
if (!external && !work)
|
|
@@ -16317,12 +16460,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16317
16460
|
const cancel = () => {
|
|
16318
16461
|
if (cancelled) return;
|
|
16319
16462
|
cancelled = true;
|
|
16320
|
-
void
|
|
16463
|
+
void requestVoiceHost(bridge, { operation: "cancel", requestId: requestId2 }).catch(() => void 0);
|
|
16321
16464
|
};
|
|
16322
16465
|
options.signal?.addEventListener("abort", cancel, { once: true });
|
|
16323
16466
|
try {
|
|
16324
16467
|
const result = realtimeCallResponseSchema.parse(
|
|
16325
|
-
await
|
|
16468
|
+
await requestVoiceHost(bridge, {
|
|
16326
16469
|
operation: "create",
|
|
16327
16470
|
requestId: requestId2,
|
|
16328
16471
|
body: options.body,
|
|
@@ -16334,7 +16477,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16334
16477
|
if (options.signal?.aborted) {
|
|
16335
16478
|
const callId = realtimeCallIdFromLocation(result.headers.location ?? "");
|
|
16336
16479
|
if (result.status >= 200 && result.status < 300 && isRealtimeCallId(callId))
|
|
16337
|
-
await
|
|
16480
|
+
await requestVoiceHost(bridge, { operation: "hangup", callId });
|
|
16338
16481
|
options.signal.throwIfAborted();
|
|
16339
16482
|
}
|
|
16340
16483
|
const response = new Response(result.status === 204 ? null : result.body, {
|
|
@@ -16362,7 +16505,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16362
16505
|
const config2 = readCpaLiveVoiceHookConfig(target);
|
|
16363
16506
|
if (!config2) return { status: "disabled", dispose() {
|
|
16364
16507
|
} };
|
|
16365
|
-
if (
|
|
16508
|
+
if (!supportsVoiceVersion(CLIENT_OWNED_VOICE_ASSETS, config2.desktopVersion))
|
|
16366
16509
|
return { status: "unsupported", dispose() {
|
|
16367
16510
|
} };
|
|
16368
16511
|
const importModule = options.importModule ?? ((url2) => import(url2));
|
|
@@ -16383,25 +16526,26 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16383
16526
|
const attempt = async () => {
|
|
16384
16527
|
if (disposed) return;
|
|
16385
16528
|
const names = loadedAssetNames(target.document, target.performance);
|
|
16386
|
-
|
|
16529
|
+
const assets = selectVoiceAssets(CLIENT_OWNED_VOICE_ASSETS, names, config2.desktopVersion);
|
|
16530
|
+
if (assets) {
|
|
16387
16531
|
try {
|
|
16388
|
-
const module = await importModule(`app://-/assets/${
|
|
16532
|
+
const module = await importModule(`app://-/assets/${assets.shared}`);
|
|
16389
16533
|
if (disposed) return;
|
|
16390
|
-
if (typeof module
|
|
16391
|
-
module
|
|
16392
|
-
const fetchClass = module
|
|
16393
|
-
const bridgeClass = module
|
|
16534
|
+
if (typeof module[SHARED_INIT] !== "function") throw new Error();
|
|
16535
|
+
module[SHARED_INIT]();
|
|
16536
|
+
const fetchClass = module[SHARED_FETCH];
|
|
16537
|
+
const bridgeClass = module[SHARED_BRIDGE];
|
|
16394
16538
|
if (!object2(fetchClass) && typeof fetchClass !== "function") throw new Error();
|
|
16395
16539
|
if (!object2(bridgeClass) && typeof bridgeClass !== "function") throw new Error();
|
|
16396
16540
|
const client = Reflect.get(fetchClass, "getInstance").call(fetchClass);
|
|
16397
16541
|
const bridge = Reflect.get(bridgeClass, "getInstance").call(bridgeClass);
|
|
16398
|
-
if (typeof client?.fetch !== "function" || typeof bridge?.dispatchMessage !== "function" || typeof bridge?.subscribe !== "function" || typeof module
|
|
16542
|
+
if (typeof client?.fetch !== "function" || typeof bridge?.dispatchMessage !== "function" || typeof bridge?.subscribe !== "function" || typeof module[SHARED_RESPONSE_ERROR] !== "function")
|
|
16399
16543
|
throw new Error();
|
|
16400
16544
|
restore = wrapClientOwnedVoiceFetch(
|
|
16401
16545
|
client,
|
|
16402
16546
|
bridge,
|
|
16403
16547
|
() => cpaLiveVoicePreferenceAllowsInstall(target),
|
|
16404
|
-
module
|
|
16548
|
+
module[SHARED_RESPONSE_ERROR],
|
|
16405
16549
|
() => chatLiveVoicePreferenceAllowsOverride(target),
|
|
16406
16550
|
() => isWorkComposerSurface(target),
|
|
16407
16551
|
() => isExternalHarnessComposer(target)
|
|
@@ -16489,8 +16633,432 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16489
16633
|
};
|
|
16490
16634
|
}
|
|
16491
16635
|
|
|
16636
|
+
// ../desktop-control/dist/renderer-react-ownership.js
|
|
16637
|
+
function committedReactAncestors(value) {
|
|
16638
|
+
const MAX_VISITED_FIBERS = 2e5;
|
|
16639
|
+
const fiber = (value2) => typeof value2 === "object" && value2 !== null ? value2 : null;
|
|
16640
|
+
const exhausted = () => {
|
|
16641
|
+
const target = globalThis;
|
|
16642
|
+
if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function")
|
|
16643
|
+
target.dispatchEvent(new CustomEvent("codexhost:react-fiber-walk-limit", {
|
|
16644
|
+
detail: { limit: MAX_VISITED_FIBERS }
|
|
16645
|
+
}));
|
|
16646
|
+
return [];
|
|
16647
|
+
};
|
|
16648
|
+
const first = fiber(value);
|
|
16649
|
+
if (!first)
|
|
16650
|
+
return [];
|
|
16651
|
+
const previous = [];
|
|
16652
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16653
|
+
for (let node = first; node; node = fiber(node.return)) {
|
|
16654
|
+
if (seen.has(node))
|
|
16655
|
+
return [];
|
|
16656
|
+
if (seen.size >= MAX_VISITED_FIBERS)
|
|
16657
|
+
return exhausted();
|
|
16658
|
+
seen.add(node);
|
|
16659
|
+
previous.push(node);
|
|
16660
|
+
}
|
|
16661
|
+
const rootState = fiber(previous.at(-1)?.stateNode);
|
|
16662
|
+
if (!rootState || !("current" in rootState))
|
|
16663
|
+
return previous;
|
|
16664
|
+
const current = fiber(rootState.current);
|
|
16665
|
+
if (!current)
|
|
16666
|
+
return [];
|
|
16667
|
+
const alternate = fiber(first.alternate);
|
|
16668
|
+
const path = [current];
|
|
16669
|
+
seen.clear();
|
|
16670
|
+
seen.add(current);
|
|
16671
|
+
for (let index = previous.length - 2; index >= 0; index -= 1) {
|
|
16672
|
+
const expected = previous[index];
|
|
16673
|
+
const expectedAlternate = fiber(expected?.alternate);
|
|
16674
|
+
let child = fiber(path.at(-1)?.child);
|
|
16675
|
+
let matched = false;
|
|
16676
|
+
while (child && !seen.has(child) && seen.size < MAX_VISITED_FIBERS) {
|
|
16677
|
+
seen.add(child);
|
|
16678
|
+
if (child === expected || child === expectedAlternate) {
|
|
16679
|
+
matched = true;
|
|
16680
|
+
break;
|
|
16681
|
+
}
|
|
16682
|
+
child = fiber(child.sibling);
|
|
16683
|
+
}
|
|
16684
|
+
if (!matched || !child)
|
|
16685
|
+
break;
|
|
16686
|
+
path.push(child);
|
|
16687
|
+
}
|
|
16688
|
+
if (path.length === previous.length && (path.at(-1) === first || path.at(-1) === alternate)) {
|
|
16689
|
+
return path.reverse();
|
|
16690
|
+
}
|
|
16691
|
+
const stack = [{ node: current, parent: null }];
|
|
16692
|
+
seen.clear();
|
|
16693
|
+
while (stack.length > 0 && seen.size < MAX_VISITED_FIBERS) {
|
|
16694
|
+
const entry = stack.pop();
|
|
16695
|
+
if (!entry)
|
|
16696
|
+
break;
|
|
16697
|
+
if (seen.has(entry.node))
|
|
16698
|
+
return [];
|
|
16699
|
+
seen.add(entry.node);
|
|
16700
|
+
if (entry.node === first || entry.node === alternate) {
|
|
16701
|
+
const ancestors = [];
|
|
16702
|
+
for (let cursor = entry; cursor; cursor = cursor.parent)
|
|
16703
|
+
ancestors.push(cursor.node);
|
|
16704
|
+
return ancestors;
|
|
16705
|
+
}
|
|
16706
|
+
const sibling = entry.parent && fiber(entry.node.sibling);
|
|
16707
|
+
if (sibling)
|
|
16708
|
+
stack.push({ node: sibling, parent: entry.parent });
|
|
16709
|
+
const child = fiber(entry.node.child);
|
|
16710
|
+
if (child)
|
|
16711
|
+
stack.push({ node: child, parent: entry });
|
|
16712
|
+
}
|
|
16713
|
+
return stack.length > 0 ? exhausted() : [];
|
|
16714
|
+
}
|
|
16715
|
+
|
|
16716
|
+
// src/renderer-voice-capability.ts
|
|
16717
|
+
var INFERENCE_GATE = "3683713372";
|
|
16718
|
+
var record2 = (value) => value !== null && typeof value === "object";
|
|
16719
|
+
var capable = (value) => record2(value) && typeof value.isLoading === "boolean" && typeof value.isError === "boolean" && typeof value.isCapable === "boolean";
|
|
16720
|
+
var equal = (a, b) => a.isLoading === b.isLoading && a.isError === b.isError && a.isCapable === b.isCapable;
|
|
16721
|
+
function replayVoiceCapability(store, atom, gate) {
|
|
16722
|
+
const evaluate = (override) => {
|
|
16723
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
16724
|
+
let remaining = 512;
|
|
16725
|
+
let hits = 0;
|
|
16726
|
+
const read = (dependency) => {
|
|
16727
|
+
if (--remaining < 0) throw new Error("Voice capability dependency limit");
|
|
16728
|
+
const value = store.get(dependency);
|
|
16729
|
+
if (dependency === gate) {
|
|
16730
|
+
hits += 1;
|
|
16731
|
+
if (typeof value !== "boolean") throw new Error("Voice inference gate unavailable");
|
|
16732
|
+
return override ? false : value;
|
|
16733
|
+
}
|
|
16734
|
+
if (dependency.write || visiting.has(dependency)) return value;
|
|
16735
|
+
if (typeof dependency.read !== "function") throw new Error("Voice dependency unavailable");
|
|
16736
|
+
visiting.add(dependency);
|
|
16737
|
+
try {
|
|
16738
|
+
return dependency.read(read);
|
|
16739
|
+
} finally {
|
|
16740
|
+
visiting.delete(dependency);
|
|
16741
|
+
}
|
|
16742
|
+
};
|
|
16743
|
+
return { value: read(atom), hits };
|
|
16744
|
+
};
|
|
16745
|
+
try {
|
|
16746
|
+
const native = store.get(atom);
|
|
16747
|
+
if (!capable(native) || native.isLoading || native.isError) return null;
|
|
16748
|
+
const before = evaluate(false);
|
|
16749
|
+
if (!capable(before.value) || !equal(native, before.value)) return null;
|
|
16750
|
+
const after = evaluate(true);
|
|
16751
|
+
return after.hits > 0 && capable(after.value) && !after.value.isLoading && !after.value.isError ? after.value : null;
|
|
16752
|
+
} catch {
|
|
16753
|
+
return null;
|
|
16754
|
+
}
|
|
16755
|
+
}
|
|
16756
|
+
function hooks(fiber) {
|
|
16757
|
+
const result = [];
|
|
16758
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16759
|
+
let hook = fiber.memoizedState;
|
|
16760
|
+
while (record2(hook) && result.length < 4096 && !seen.has(hook)) {
|
|
16761
|
+
seen.add(hook);
|
|
16762
|
+
result.push(hook);
|
|
16763
|
+
hook = hook.next;
|
|
16764
|
+
}
|
|
16765
|
+
return hook == null ? result : [];
|
|
16766
|
+
}
|
|
16767
|
+
function bindVoiceCapabilitySubscriptions(currentFibers, family, gates, allowed, realtimeOnly = false) {
|
|
16768
|
+
const fibers = currentFibers();
|
|
16769
|
+
const restores = [];
|
|
16770
|
+
const bindings = [];
|
|
16771
|
+
try {
|
|
16772
|
+
for (const fiber of fibers) {
|
|
16773
|
+
const list = hooks(fiber);
|
|
16774
|
+
for (const memo of list) {
|
|
16775
|
+
const [signal, deps] = Array.isArray(memo.memoizedState) ? memo.memoizedState : [];
|
|
16776
|
+
if (!record2(signal) || !Array.isArray(deps) || deps.length !== 5 || deps[3] !== family || !(deps[1] instanceof Map) || deps[2] !== void 0)
|
|
16777
|
+
continue;
|
|
16778
|
+
const chain = deps[1];
|
|
16779
|
+
const node = chain.get(family.scope.id);
|
|
16780
|
+
const members = node?.familyBindings?.get(family);
|
|
16781
|
+
if (!node || !(members instanceof Map) || node.store !== signal.store) continue;
|
|
16782
|
+
const matches = [...members].filter(([, member]) => member.cacheKey === deps[0]);
|
|
16783
|
+
if (matches.length !== 1 || typeof matches[0]?.[0] !== "string") continue;
|
|
16784
|
+
const parameter = JSON.parse(matches[0][0]);
|
|
16785
|
+
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")
|
|
16786
|
+
continue;
|
|
16787
|
+
const subscriptions = list.filter((hook2) => {
|
|
16788
|
+
const state = hook2.memoizedState;
|
|
16789
|
+
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";
|
|
16790
|
+
});
|
|
16791
|
+
if (subscriptions.length !== 1) throw new Error("Ambiguous voice subscription");
|
|
16792
|
+
const hook = subscriptions[0];
|
|
16793
|
+
const subscriber = hook.memoizedState[0];
|
|
16794
|
+
const instance = hook.next?.queue;
|
|
16795
|
+
const effect = hook.next?.next?.memoizedState;
|
|
16796
|
+
const store = signal.store;
|
|
16797
|
+
const gate = gates.resolve(node, chain, INFERENCE_GATE)?.atom;
|
|
16798
|
+
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(
|
|
16799
|
+
store.get(signal.atom),
|
|
16800
|
+
subscriber.getSnapshot()
|
|
16801
|
+
) || !equal(subscriber.getSnapshot(), instance.getSnapshot()) || subscriber.createRender?.() != null)
|
|
16802
|
+
throw new Error("Unsupported voice subscription");
|
|
16803
|
+
for (const [object3, key] of [
|
|
16804
|
+
[store, "sub"],
|
|
16805
|
+
[subscriber, "getSnapshot"],
|
|
16806
|
+
[instance, "getSnapshot"]
|
|
16807
|
+
])
|
|
16808
|
+
if (Object.getOwnPropertyDescriptor(object3, key)?.writable !== true)
|
|
16809
|
+
throw new Error("Voice subscription is not writable");
|
|
16810
|
+
let notify;
|
|
16811
|
+
const sub = store.sub;
|
|
16812
|
+
try {
|
|
16813
|
+
store.sub = (atom, listener) => {
|
|
16814
|
+
if (atom !== signal.atom || notify) throw new Error("Unexpected voice subscription");
|
|
16815
|
+
notify = listener;
|
|
16816
|
+
return () => {
|
|
16817
|
+
};
|
|
16818
|
+
};
|
|
16819
|
+
effect.create();
|
|
16820
|
+
} finally {
|
|
16821
|
+
store.sub = sub;
|
|
16822
|
+
}
|
|
16823
|
+
if (!notify) throw new Error("Voice listener unavailable");
|
|
16824
|
+
const original = subscriber.getSnapshot;
|
|
16825
|
+
const originalInstance = instance.getSnapshot;
|
|
16826
|
+
let previous;
|
|
16827
|
+
const snapshot = () => {
|
|
16828
|
+
const native = original.call(subscriber);
|
|
16829
|
+
if (!allowed()) return native;
|
|
16830
|
+
const projected = replayVoiceCapability(store, signal.atom, gate);
|
|
16831
|
+
if (!projected || !projected.isCapable) return native;
|
|
16832
|
+
if (!previous || !equal(previous, projected)) previous = projected;
|
|
16833
|
+
return previous;
|
|
16834
|
+
};
|
|
16835
|
+
subscriber.getSnapshot = snapshot;
|
|
16836
|
+
instance.getSnapshot = snapshot;
|
|
16837
|
+
const onChange = notify;
|
|
16838
|
+
restores.push(() => {
|
|
16839
|
+
if (subscriber.getSnapshot === snapshot) subscriber.getSnapshot = original;
|
|
16840
|
+
if (instance.getSnapshot === snapshot) instance.getSnapshot = originalInstance;
|
|
16841
|
+
onChange();
|
|
16842
|
+
});
|
|
16843
|
+
bindings.push({ subscriber, signal, instance });
|
|
16844
|
+
onChange();
|
|
16845
|
+
}
|
|
16846
|
+
}
|
|
16847
|
+
if (!restores.length) throw new Error("Owned voice capability unavailable");
|
|
16848
|
+
if (realtimeOnly && restores.length !== 1) throw new Error("Ambiguous voice starter");
|
|
16849
|
+
} catch (error51) {
|
|
16850
|
+
for (const restore of restores.reverse()) restore();
|
|
16851
|
+
throw error51;
|
|
16852
|
+
}
|
|
16853
|
+
return {
|
|
16854
|
+
dispose() {
|
|
16855
|
+
for (const restore of restores.splice(0).reverse()) restore();
|
|
16856
|
+
},
|
|
16857
|
+
current() {
|
|
16858
|
+
const current = [...currentFibers()].flatMap(hooks);
|
|
16859
|
+
return bindings.every(
|
|
16860
|
+
({ subscriber, signal, instance }) => current.some(
|
|
16861
|
+
(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)
|
|
16862
|
+
)
|
|
16863
|
+
);
|
|
16864
|
+
}
|
|
16865
|
+
};
|
|
16866
|
+
}
|
|
16867
|
+
|
|
16868
|
+
// src/renderer-voice-start-capability.ts
|
|
16869
|
+
var GLOBAL = "__codexhostVoiceStartCapabilityV1";
|
|
16870
|
+
var record3 = (v) => v !== null && typeof v === "object";
|
|
16871
|
+
function gatewayVoiceStartRequest(request, workGateway, chatGateway = false) {
|
|
16872
|
+
if (!record3(request) || request.productExperience !== "work" && request.productExperience !== "chat")
|
|
16873
|
+
return false;
|
|
16874
|
+
if (request.source === "composer_button_existing_thread") {
|
|
16875
|
+
if (!record3(request.locator) || request.locator.hostId !== "local") return false;
|
|
16876
|
+
} else if (request.source !== "composer_button_new_thread" || (request.hostId ?? "local") !== "local")
|
|
16877
|
+
return false;
|
|
16878
|
+
if (request.productExperience === "chat") return chatGateway;
|
|
16879
|
+
const mode = request.activeCollaborationMode;
|
|
16880
|
+
const settings = record3(mode) ? mode.settings : void 0;
|
|
16881
|
+
const model2 = record3(settings) ? settings.model : void 0;
|
|
16882
|
+
return workGateway || typeof model2 === "string" && model2.startsWith("codexhost/");
|
|
16883
|
+
}
|
|
16884
|
+
function wrapGatewayVoiceStarter(start, options) {
|
|
16885
|
+
let active;
|
|
16886
|
+
return {
|
|
16887
|
+
async start(...args) {
|
|
16888
|
+
if (!options.qualifies(args[0])) return start(...args);
|
|
16889
|
+
if (active) throw new Error("Voice gateway start is already pending");
|
|
16890
|
+
const attempt = {};
|
|
16891
|
+
active = attempt;
|
|
16892
|
+
const allowed = () => active === attempt && options.qualifies(args[0]);
|
|
16893
|
+
try {
|
|
16894
|
+
if (!await options.ready()) throw new Error("Voice gateway is not ready");
|
|
16895
|
+
if (!allowed()) throw new Error("Voice gateway start was cancelled");
|
|
16896
|
+
attempt.binding = await options.prepare(allowed);
|
|
16897
|
+
await options.committed(attempt.binding);
|
|
16898
|
+
if (!allowed()) throw new Error("Voice gateway start was cancelled");
|
|
16899
|
+
if (!attempt.binding.current()) throw new Error("Voice starter subscription changed");
|
|
16900
|
+
rememberVoiceProductExperience(args[0]);
|
|
16901
|
+
return await start(...args);
|
|
16902
|
+
} finally {
|
|
16903
|
+
attempt.binding?.dispose();
|
|
16904
|
+
if (active === attempt) active = void 0;
|
|
16905
|
+
}
|
|
16906
|
+
},
|
|
16907
|
+
cancel() {
|
|
16908
|
+
active?.binding?.dispose();
|
|
16909
|
+
active = void 0;
|
|
16910
|
+
}
|
|
16911
|
+
};
|
|
16912
|
+
}
|
|
16913
|
+
function overlayVoiceStarterFibers(document, page) {
|
|
16914
|
+
const fibers = /* @__PURE__ */ new Set();
|
|
16915
|
+
for (const element of document.querySelectorAll("[data-avatar-overlay-native-surface-id]")) {
|
|
16916
|
+
const key = Object.getOwnPropertyNames(element).find((key2) => key2.startsWith("__reactFiber$"));
|
|
16917
|
+
const ancestors = committedReactAncestors(
|
|
16918
|
+
key && Object.getOwnPropertyDescriptor(element, key)?.value
|
|
16919
|
+
);
|
|
16920
|
+
const boundary = ancestors.findIndex((fiber) => record3(fiber) && fiber.type === page);
|
|
16921
|
+
if (boundary < 0) continue;
|
|
16922
|
+
for (const fiber of ancestors.slice(0, boundary)) if (record3(fiber)) fibers.add(fiber);
|
|
16923
|
+
}
|
|
16924
|
+
return fibers;
|
|
16925
|
+
}
|
|
16926
|
+
function installVoiceStartCapabilityHook(options = {}) {
|
|
16927
|
+
const target = options.target ?? globalThis;
|
|
16928
|
+
if (target[GLOBAL]) return target[GLOBAL];
|
|
16929
|
+
const config2 = readCpaLiveVoiceHookConfig(target);
|
|
16930
|
+
if (!config2 || !isAvatarOverlayHref(target.location?.href ?? ""))
|
|
16931
|
+
return { status: "disabled", dispose() {
|
|
16932
|
+
} };
|
|
16933
|
+
if (!supportsVoiceVersion(CLIENT_OWNED_VOICE_ASSETS, config2.desktopVersion))
|
|
16934
|
+
return { status: "unsupported", dispose() {
|
|
16935
|
+
} };
|
|
16936
|
+
const importModule = options.importModule ?? ((url2) => import(url2));
|
|
16937
|
+
let disposed = false;
|
|
16938
|
+
let timer;
|
|
16939
|
+
let restore;
|
|
16940
|
+
const wrappers = /* @__PURE__ */ new Set();
|
|
16941
|
+
const started = Date.now();
|
|
16942
|
+
const handle = {
|
|
16943
|
+
status: "pending",
|
|
16944
|
+
dispose() {
|
|
16945
|
+
disposed = true;
|
|
16946
|
+
target.clearTimeout(timer);
|
|
16947
|
+
for (const wrapper of wrappers) wrapper.cancel();
|
|
16948
|
+
restore?.();
|
|
16949
|
+
if (target[GLOBAL] === handle) Reflect.deleteProperty(target, GLOBAL);
|
|
16950
|
+
}
|
|
16951
|
+
};
|
|
16952
|
+
target[GLOBAL] = handle;
|
|
16953
|
+
const attempt = async () => {
|
|
16954
|
+
if (disposed) return;
|
|
16955
|
+
try {
|
|
16956
|
+
const names = loadedAssetNames(target.document, target.performance);
|
|
16957
|
+
const assets = selectVoiceAssets(CLIENT_OWNED_VOICE_ASSETS, names, config2.desktopVersion);
|
|
16958
|
+
if (assets) {
|
|
16959
|
+
const shared = await importModule(`app://-/assets/${assets.shared}`);
|
|
16960
|
+
if (typeof shared.Oit !== "function") throw new Error("Voice bridge unavailable");
|
|
16961
|
+
shared.Oit();
|
|
16962
|
+
const services = shared[CLIENT_OWNED_VOICE_SERVICES];
|
|
16963
|
+
if (record3(services) && (record3(services.realtimeVoiceRuntime) || typeof services.realtimeVoiceRuntime === "function")) {
|
|
16964
|
+
const original = services.realtimeVoiceRuntime;
|
|
16965
|
+
const register = Reflect.get(original, "registerRealtimeStarter");
|
|
16966
|
+
if (typeof register !== "function") throw new Error("Voice starter unavailable");
|
|
16967
|
+
const wrapped = new Proxy(original, {
|
|
16968
|
+
get(service, key, receiver) {
|
|
16969
|
+
if (key === "registerRealtimeStarter")
|
|
16970
|
+
return (start, cancel, ...rest) => {
|
|
16971
|
+
if (typeof start !== "function" || typeof cancel !== "function")
|
|
16972
|
+
throw new Error("Voice starter callback unavailable");
|
|
16973
|
+
const wrapper = wrapGatewayVoiceStarter(start, {
|
|
16974
|
+
qualifies: (request) => !disposed && !!readCpaLiveVoiceHookConfig(target) && gatewayVoiceStartRequest(
|
|
16975
|
+
request,
|
|
16976
|
+
cpaLiveVoicePreferenceAllowsInstall(target),
|
|
16977
|
+
chatLiveVoicePreferenceAllowsOverride(target)
|
|
16978
|
+
),
|
|
16979
|
+
ready: async () => {
|
|
16980
|
+
const hook = target.__codexhostClientOwnedVoiceV1;
|
|
16981
|
+
if (!record3(hook) || hook.status !== "active") return false;
|
|
16982
|
+
const bridgeClass = shared.AFt;
|
|
16983
|
+
const result = await requestVoiceHost(
|
|
16984
|
+
bridgeClass.getInstance(),
|
|
16985
|
+
{},
|
|
16986
|
+
VOICE_GATEWAY_STATUS_METHOD
|
|
16987
|
+
);
|
|
16988
|
+
return result === true;
|
|
16989
|
+
},
|
|
16990
|
+
prepare: async (allowed) => {
|
|
16991
|
+
const names2 = loadedAssetNames(target.document, target.performance);
|
|
16992
|
+
if (!auditedAppInitialAssetPresent(names2, assets.overlay))
|
|
16993
|
+
throw new Error("Unaudited voice starter");
|
|
16994
|
+
const [initial, overlay] = await Promise.all([
|
|
16995
|
+
importModule(`app://-/assets/${assets.initial}`),
|
|
16996
|
+
importModule(`app://-/assets/${assets.overlay}`)
|
|
16997
|
+
]);
|
|
16998
|
+
if (typeof initial.njr !== "function" || typeof overlay.AvatarOverlayNativePage !== "function" || !target.document)
|
|
16999
|
+
throw new Error("Voice starter owner unavailable");
|
|
17000
|
+
const document = target.document;
|
|
17001
|
+
initial.njr();
|
|
17002
|
+
return bindVoiceCapabilitySubscriptions(
|
|
17003
|
+
() => overlayVoiceStarterFibers(document, overlay.AvatarOverlayNativePage),
|
|
17004
|
+
initial.tjr,
|
|
17005
|
+
initial.uBr,
|
|
17006
|
+
allowed,
|
|
17007
|
+
true
|
|
17008
|
+
);
|
|
17009
|
+
},
|
|
17010
|
+
// Wait for React's committed snapshot, including when the
|
|
17011
|
+
// persistent overlay is hidden. A stale closure fails closed.
|
|
17012
|
+
committed: async (binding) => {
|
|
17013
|
+
for (let i = 0; i < 40 && !disposed && !binding.current(); i += 1)
|
|
17014
|
+
await new Promise((resolve) => target.setTimeout(resolve, 50));
|
|
17015
|
+
}
|
|
17016
|
+
});
|
|
17017
|
+
wrappers.add(wrapper);
|
|
17018
|
+
return Reflect.apply(register, original, [
|
|
17019
|
+
wrapper.start,
|
|
17020
|
+
(...args) => {
|
|
17021
|
+
wrapper.cancel();
|
|
17022
|
+
return cancel(...args);
|
|
17023
|
+
},
|
|
17024
|
+
...rest
|
|
17025
|
+
]);
|
|
17026
|
+
};
|
|
17027
|
+
if (key === "unregisterRealtimeStarter")
|
|
17028
|
+
return (...args) => {
|
|
17029
|
+
for (const wrapper of wrappers) wrapper.cancel();
|
|
17030
|
+
wrappers.clear();
|
|
17031
|
+
return Reflect.apply(Reflect.get(service, key), service, args);
|
|
17032
|
+
};
|
|
17033
|
+
return Reflect.get(service, key, receiver);
|
|
17034
|
+
}
|
|
17035
|
+
});
|
|
17036
|
+
if (disposed) return;
|
|
17037
|
+
if (!Reflect.set(services, "realtimeVoiceRuntime", wrapped))
|
|
17038
|
+
throw new Error("Voice service is not writable");
|
|
17039
|
+
restore = () => {
|
|
17040
|
+
if (services.realtimeVoiceRuntime === wrapped) services.realtimeVoiceRuntime = original;
|
|
17041
|
+
};
|
|
17042
|
+
handle.status = "active";
|
|
17043
|
+
return;
|
|
17044
|
+
}
|
|
17045
|
+
}
|
|
17046
|
+
if (Date.now() - started >= 6e4) {
|
|
17047
|
+
handle.status = "unsupported";
|
|
17048
|
+
return;
|
|
17049
|
+
}
|
|
17050
|
+
timer = target.setTimeout(() => void attempt(), 25);
|
|
17051
|
+
} catch {
|
|
17052
|
+
handle.status = "unsupported";
|
|
17053
|
+
}
|
|
17054
|
+
};
|
|
17055
|
+
void attempt();
|
|
17056
|
+
return handle;
|
|
17057
|
+
}
|
|
17058
|
+
|
|
16492
17059
|
// src/cpa-live-voice-entry.ts
|
|
16493
17060
|
installCpaLiveVoiceHook();
|
|
16494
17061
|
installClientOwnedVoiceHook();
|
|
17062
|
+
installVoiceStartCapabilityHook();
|
|
16495
17063
|
installOverlayThreadIsolation();
|
|
16496
17064
|
})();
|