@karlorz/codexhost-cli-win32-x64 0.13.3-3 → 0.13.3-5

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.
@@ -68,14 +68,13 @@
68
68
  }
69
69
  });
70
70
  }
71
- function resourceNamesFromPerformance() {
72
- if (typeof performance === "undefined" || typeof performance.getEntriesByType !== "function") {
73
- return [];
74
- }
75
- return performance.getEntriesByType("resource").map((entry) => entry.name).filter((name) => typeof name === "string");
71
+ function resourceNamesFromPerformance(source) {
72
+ const target = source ?? (typeof performance === "undefined" ? void 0 : performance);
73
+ if (!target || typeof target.getEntriesByType !== "function") return [];
74
+ return target.getEntriesByType("resource").map((entry) => entry.name).filter((name) => typeof name === "string");
76
75
  }
77
- function resourceNamesFromDocument(root) {
78
- const names = resourceNamesFromPerformance();
76
+ function loadedAssetNames(root, performanceSource) {
77
+ const names = resourceNamesFromPerformance(performanceSource);
79
78
  if (!root || !("querySelectorAll" in root)) return names;
80
79
  for (const element of root.querySelectorAll("script[src], link[href]")) {
81
80
  const value = element.getAttribute("src") ?? element.getAttribute("href");
@@ -138,7 +137,7 @@
138
137
  };
139
138
  const attempt = () => {
140
139
  if (!auditedAssetFound) {
141
- const resourceNames = options.resourceNames ?? resourceNamesFromDocument(root);
140
+ const resourceNames = options.resourceNames ?? loadedAssetNames(root);
142
141
  auditedAssetFound = configAllowsInstall(config2, resourceNames);
143
142
  if (!auditedAssetFound) return false;
144
143
  }
@@ -167,236 +166,6 @@
167
166
  return handle;
168
167
  }
169
168
 
170
- // src/agent-selection-state.ts
171
- var DEFAULT_RENDERER_AGENTS = ["codex"];
172
- function defaultIdFactory(sequence) {
173
- return `codexhost-composer-${Date.now().toString(36)}-${sequence.toString(36)}`;
174
- }
175
- function isDefaultTarget(target) {
176
- return target?.[0] === "default";
177
- }
178
- function isConversationTarget(target) {
179
- return target?.[0] === "conversation";
180
- }
181
- function isIdentifiedTarget(target) {
182
- return target?.[0] === "conversation" || target?.[0] === "default" && typeof target[1] === "string" && target[1].startsWith("client-new-thread:");
183
- }
184
- function sameTarget(left, right) {
185
- return left.length === right.length && left.every((value, index) => value === right[index]);
186
- }
187
- var DraftAgentController = class {
188
- #idFactory;
189
- #defaultAgent;
190
- #enabledAgents;
191
- #targetStates = [];
192
- #modelRequestGenerations = /* @__PURE__ */ new WeakMap();
193
- #ownershipRequestGenerations = /* @__PURE__ */ new WeakMap();
194
- #states = /* @__PURE__ */ new WeakMap();
195
- #switching = /* @__PURE__ */ new Set();
196
- #pendingSubmissions = /* @__PURE__ */ new Set();
197
- #composerSequence = 0;
198
- #modelRequestSequence = 0;
199
- #ownershipRequestSequence = 0;
200
- #lastSubmittedAgent;
201
- constructor(options = {}) {
202
- this.#idFactory = options.idFactory ?? defaultIdFactory;
203
- this.#enabledAgents = new Set(options.enabledAgents ?? DEFAULT_RENDERER_AGENTS);
204
- if (!this.#enabledAgents.has("codex"))
205
- throw new Error("Renderer enabled Agents must include Codex");
206
- this.#defaultAgent = options.defaultAgent ?? "codex";
207
- this.#lastSubmittedAgent = this.#defaultAgent;
208
- }
209
- setEnabledAgents(agents) {
210
- this.#enabledAgents = /* @__PURE__ */ new Set(["codex", ...agents]);
211
- }
212
- get(composer) {
213
- return this.#state(composer);
214
- }
215
- detach(composer, preservePendingSubmission = false) {
216
- const state = this.#states.get(composer);
217
- if (state && !preservePendingSubmission) this.#pendingSubmissions.delete(state);
218
- this.#states.delete(composer);
219
- }
220
- mount(composer, target, preferredNewThreadAgent) {
221
- const bound = this.#targetState(target);
222
- if (bound) {
223
- this.#states.set(composer, bound);
224
- return bound;
225
- }
226
- const preferredAgent = preferredNewThreadAgent ?? this.#lastSubmittedAgent;
227
- const state = this.#state(composer, isDefaultTarget(target) ? preferredAgent : "codex");
228
- if (isIdentifiedTarget(target)) this.#targetStates.push({ target, state });
229
- return state;
230
- }
231
- isSwitching(composer) {
232
- return this.#switching.has(this.#state(composer));
233
- }
234
- beginModelRequest(composer) {
235
- const state = this.#state(composer);
236
- const generation = ++this.#modelRequestSequence;
237
- this.#modelRequestGenerations.set(state, generation);
238
- return generation;
239
- }
240
- invalidateModelRequests(composer) {
241
- this.beginModelRequest(composer);
242
- }
243
- isCurrentModelRequest(composer, generation) {
244
- return (this.#modelRequestGenerations.get(this.#state(composer)) ?? 0) === generation;
245
- }
246
- beginOwnershipRequest(composer) {
247
- const generation = ++this.#ownershipRequestSequence;
248
- this.#ownershipRequestGenerations.set(this.#state(composer), generation);
249
- return generation;
250
- }
251
- isCurrentOwnershipRequest(composer, generation) {
252
- return (this.#ownershipRequestGenerations.get(this.#state(composer)) ?? 0) === generation;
253
- }
254
- rebindConversation(composer, target) {
255
- if (!isConversationTarget(target)) return null;
256
- const previous = this.#state(composer);
257
- this.#pendingSubmissions.delete(previous);
258
- this.#modelRequestGenerations.set(previous, ++this.#modelRequestSequence);
259
- this.#ownershipRequestGenerations.set(previous, ++this.#ownershipRequestSequence);
260
- let state = this.#targetState(target);
261
- if (!state) {
262
- state = {
263
- agent: "codex",
264
- phase: "draft",
265
- composerId: this.#idFactory(++this.#composerSequence)
266
- };
267
- this.#targetStates.push({ target, state });
268
- }
269
- this.#states.set(composer, state);
270
- this.#modelRequestGenerations.set(state, ++this.#modelRequestSequence);
271
- this.#ownershipRequestGenerations.set(state, ++this.#ownershipRequestSequence);
272
- return state;
273
- }
274
- restore(composer, agent, model2, thinkingOptionId, permissionModeId) {
275
- const state = this.#state(composer);
276
- this.#pendingSubmissions.delete(state);
277
- state.agent = agent;
278
- state.phase = "locked";
279
- if (agent !== "codex") {
280
- state.configurationByAgent = {
281
- ...state.configurationByAgent,
282
- [agent]: {
283
- ...model2 ? { model: model2 } : {},
284
- ...thinkingOptionId ? { thinkingOptionId } : {},
285
- ...permissionModeId ? { permissionModeId } : {}
286
- }
287
- };
288
- }
289
- return state;
290
- }
291
- clearConfiguration(composer) {
292
- delete this.#state(composer).configurationByAgent;
293
- }
294
- modelForAgent(composer, agent) {
295
- return this.#state(composer).configurationByAgent?.[agent]?.model;
296
- }
297
- thinkingOptionForAgent(composer, agent) {
298
- return this.#state(composer).configurationByAgent?.[agent]?.thinkingOptionId;
299
- }
300
- permissionModeForAgent(composer, agent) {
301
- return this.#state(composer).configurationByAgent?.[agent]?.permissionModeId;
302
- }
303
- setExternalPermissionMode(composer, agent, permissionModeId) {
304
- return this.#configure(composer, agent, { permissionModeId });
305
- }
306
- setExternalModel(composer, agent, model2) {
307
- return this.#configure(composer, agent, { model: model2 });
308
- }
309
- setExternalThinkingOption(composer, agent, thinkingOptionId) {
310
- const state = this.#configure(composer, agent, {});
311
- const configuration = state.configurationByAgent?.[agent];
312
- if (!configuration) return state;
313
- if (thinkingOptionId) configuration.thinkingOptionId = thinkingOptionId;
314
- else delete configuration.thinkingOptionId;
315
- return state;
316
- }
317
- #configure(composer, agent, patch) {
318
- const state = this.#state(composer);
319
- state.configurationByAgent = {
320
- ...state.configurationByAgent,
321
- [agent]: { ...state.configurationByAgent?.[agent], ...patch }
322
- };
323
- return state;
324
- }
325
- lock(composer) {
326
- const state = this.#state(composer);
327
- this.#pendingSubmissions.delete(state);
328
- state.phase = "locked";
329
- return state;
330
- }
331
- markSubmissionPending(composer) {
332
- const state = this.#state(composer);
333
- if (state.phase === "draft") this.#pendingSubmissions.add(state);
334
- return state;
335
- }
336
- isSubmissionPending(composer) {
337
- return this.#pendingSubmissions.has(this.#state(composer));
338
- }
339
- clearPendingSubmission(composer) {
340
- this.#pendingSubmissions.delete(this.#state(composer));
341
- }
342
- recordSubmission(composer) {
343
- const state = this.#state(composer);
344
- this.#lastSubmittedAgent = state.agent;
345
- return state;
346
- }
347
- transfer(source, replacement, target = null) {
348
- const state = this.#states.get(source);
349
- if (!state) return false;
350
- const bound = this.#targetState(target);
351
- if (bound && bound !== state) return false;
352
- if (source !== replacement) {
353
- if (this.#states.has(replacement)) return false;
354
- this.#states.set(replacement, state);
355
- }
356
- if (isIdentifiedTarget(target) && !bound) this.#targetStates.push({ target, state });
357
- if (isConversationTarget(target) && this.#pendingSubmissions.delete(state))
358
- state.phase = "locked";
359
- return true;
360
- }
361
- async switchAgent(composer, nextAgent, operations) {
362
- const state = this.#state(composer);
363
- if (!this.#enabledAgents.has(nextAgent)) return false;
364
- if (state.phase !== "draft" || this.#switching.has(state)) return false;
365
- if (state.agent === nextAgent) return true;
366
- this.#pendingSubmissions.delete(state);
367
- this.#switching.add(state);
368
- try {
369
- if (!operations.applyAgent(nextAgent)) return false;
370
- try {
371
- await operations.clearPrewarm();
372
- } catch (error51) {
373
- if (!operations.applyAgent(state.agent))
374
- throw new Error("Draft Agent switch could not restore the prior Agent", { cause: error51 });
375
- return false;
376
- }
377
- state.agent = nextAgent;
378
- return true;
379
- } finally {
380
- this.#switching.delete(state);
381
- }
382
- }
383
- #targetState(target) {
384
- if (!isIdentifiedTarget(target)) return null;
385
- return this.#targetStates.find((candidate) => sameTarget(candidate.target, target))?.state ?? null;
386
- }
387
- #state(composer, initialAgent) {
388
- const existing = this.#states.get(composer);
389
- if (existing) return existing;
390
- const created = {
391
- agent: initialAgent ?? this.#defaultAgent,
392
- phase: "draft",
393
- composerId: this.#idFactory(++this.#composerSequence)
394
- };
395
- this.#states.set(composer, created);
396
- return created;
397
- }
398
- };
399
-
400
169
  // ../../node_modules/zod/v4/classic/external.js
401
170
  var external_exports = {};
402
171
  __export(external_exports, {
@@ -1119,9 +888,9 @@
1119
888
  return ratio - roundedRatio;
1120
889
  }
1121
890
  var EVALUATING = /* @__PURE__ */ Symbol("evaluating");
1122
- function defineLazy(object2, key, getter) {
891
+ function defineLazy(object3, key, getter) {
1123
892
  let value = void 0;
1124
- Object.defineProperty(object2, key, {
893
+ Object.defineProperty(object3, key, {
1125
894
  get() {
1126
895
  if (value === EVALUATING) {
1127
896
  return void 0;
@@ -1133,7 +902,7 @@
1133
902
  return value;
1134
903
  },
1135
904
  set(v) {
1136
- Object.defineProperty(object2, key, {
905
+ Object.defineProperty(object3, key, {
1137
906
  value: v
1138
907
  // configurable: true,
1139
908
  });
@@ -15210,6 +14979,55 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15210
14979
  var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
15211
14980
  var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
15212
14981
 
14982
+ // ../shared-contracts/dist/realtime-call.js
14983
+ var REALTIME_CALL_METHOD = "codexhost/realtime/call";
14984
+ var REALTIME_CALL_FORWARDED_HEADERS = [
14985
+ "openai-alpha",
14986
+ "thread-id",
14987
+ "session-id",
14988
+ "originator",
14989
+ "x-codex-turn-metadata"
14990
+ ];
14991
+ var FORWARDED_HEADERS = new Set(REALTIME_CALL_FORWARDED_HEADERS);
14992
+ function filterRealtimeCallHeaders(headers) {
14993
+ const result = {};
14994
+ for (const [name, value] of Object.entries(headers ?? {})) {
14995
+ const key = name.toLowerCase();
14996
+ if (FORWARDED_HEADERS.has(key) && value.length > 0 && value.length <= 4096)
14997
+ result[key] = value;
14998
+ }
14999
+ return result;
15000
+ }
15001
+ var REALTIME_CALL_ID_PATTERN = /^rtc_[A-Za-z0-9_-]{1,128}$/u;
15002
+ function isRealtimeCallId(value) {
15003
+ return typeof value === "string" && REALTIME_CALL_ID_PATTERN.test(value);
15004
+ }
15005
+ function realtimeCallIdFromLocation(location) {
15006
+ const path = location.split(/[?#]/u)[0] ?? "";
15007
+ if (/^[A-Za-z0-9_-]{1,128}$/u.test(path))
15008
+ return path;
15009
+ return /\/(?:calls|live)\/([A-Za-z0-9_-]{1,128})$/u.exec(path)?.[1];
15010
+ }
15011
+ var requestId = external_exports.string().min(1).max(128);
15012
+ var realtimeCallParamsSchema = external_exports.discriminatedUnion("operation", [
15013
+ external_exports.object({
15014
+ operation: external_exports.literal("create"),
15015
+ requestId,
15016
+ body: external_exports.string().min(1).max(16 << 20),
15017
+ headers: external_exports.record(external_exports.string(), external_exports.string()).default({})
15018
+ }),
15019
+ external_exports.object({ operation: external_exports.literal("cancel"), requestId }),
15020
+ external_exports.object({
15021
+ operation: external_exports.literal("hangup"),
15022
+ callId: external_exports.string().regex(REALTIME_CALL_ID_PATTERN)
15023
+ })
15024
+ ]);
15025
+ var realtimeCallResponseSchema = external_exports.object({
15026
+ status: external_exports.number().int().min(200).max(599),
15027
+ body: external_exports.string(),
15028
+ headers: external_exports.record(external_exports.string(), external_exports.string())
15029
+ });
15030
+
15213
15031
  // ../shared-contracts/dist/console.js
15214
15032
  var consoleAnnouncementSchema = external_exports.strictObject({
15215
15033
  title: external_exports.string().trim().min(1).max(200),
@@ -16401,6 +16219,388 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16401
16219
  // ../shared-contracts/dist/index.js
16402
16220
  var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
16403
16221
 
16222
+ // src/renderer-client-owned-voice.ts
16223
+ var CLIENT_OWNED_VOICE_VERSION = "26.1013.40934";
16224
+ var CLIENT_OWNED_VOICE_INITIAL_ASSET = "app-initial-90eb42395b7d.js";
16225
+ var CLIENT_OWNED_VOICE_SHARED_ASSET = "app-shared-52443cbe9ac4.js";
16226
+ var HOOK_GLOBAL = "__codexhostClientOwnedVoiceV1";
16227
+ function object2(value) {
16228
+ return value !== null && typeof value === "object";
16229
+ }
16230
+ function requestHost(bridge, params) {
16231
+ const id = `codexhost-voice:${crypto.randomUUID()}`;
16232
+ return new Promise((resolve, reject) => {
16233
+ let unsubscribe = () => {
16234
+ };
16235
+ const timer = setTimeout(() => {
16236
+ unsubscribe();
16237
+ reject(new Error("Voice gateway did not answer in time"));
16238
+ }, 3e4);
16239
+ const done = () => {
16240
+ clearTimeout(timer);
16241
+ unsubscribe();
16242
+ };
16243
+ unsubscribe = bridge.subscribe("mcp-response", (event) => {
16244
+ if (!object2(event) || event.hostId !== "local" || !object2(event.message) || event.message.id !== id)
16245
+ return;
16246
+ done();
16247
+ if (event.message.error) reject(new Error("Configured voice gateway request failed"));
16248
+ else resolve(event.message.result);
16249
+ });
16250
+ try {
16251
+ bridge.dispatchMessage("mcp-request", {
16252
+ hostId: "local",
16253
+ request: { id, method: REALTIME_CALL_METHOD, params }
16254
+ });
16255
+ } catch {
16256
+ done();
16257
+ reject(new Error("Voice gateway Host connection is unavailable"));
16258
+ }
16259
+ });
16260
+ }
16261
+ function wrapClientOwnedVoiceFetch(client, bridge, enabled, responseError) {
16262
+ const original = client.fetch;
16263
+ const wrapped = async function(url2, options) {
16264
+ if (typeof url2 !== "string" || url2.split("?")[0] !== "/wham/realtime/calls" || options?.method !== "POST" || !enabled())
16265
+ return original.call(this, url2, options);
16266
+ if (typeof options.body !== "string") throw new Error("Unsupported native voice call request");
16267
+ options.signal?.throwIfAborted();
16268
+ const requestId2 = crypto.randomUUID();
16269
+ let cancelled = false;
16270
+ const cancel = () => {
16271
+ if (cancelled) return;
16272
+ cancelled = true;
16273
+ void requestHost(bridge, { operation: "cancel", requestId: requestId2 }).catch(() => void 0);
16274
+ };
16275
+ options.signal?.addEventListener("abort", cancel, { once: true });
16276
+ try {
16277
+ const result = realtimeCallResponseSchema.parse(
16278
+ await requestHost(bridge, {
16279
+ operation: "create",
16280
+ requestId: requestId2,
16281
+ body: options.body,
16282
+ // Drop Desktop OAuth, ChatGPT account identity and cookies at the bridge
16283
+ // boundary; the Host allowlist repeats this check before sending.
16284
+ headers: filterRealtimeCallHeaders(Object.fromEntries(new Headers(options.headers)))
16285
+ })
16286
+ );
16287
+ if (options.signal?.aborted) {
16288
+ const callId = realtimeCallIdFromLocation(result.headers.location ?? "");
16289
+ if (result.status >= 200 && result.status < 300 && isRealtimeCallId(callId))
16290
+ await requestHost(bridge, { operation: "hangup", callId });
16291
+ options.signal.throwIfAborted();
16292
+ }
16293
+ const response = new Response(result.status === 204 ? null : result.body, {
16294
+ status: result.status,
16295
+ headers: result.headers
16296
+ });
16297
+ if (!response.ok) throw await responseError(response, url2);
16298
+ return response;
16299
+ } catch (error51) {
16300
+ cancel();
16301
+ throw error51;
16302
+ } finally {
16303
+ options.signal?.removeEventListener("abort", cancel);
16304
+ }
16305
+ };
16306
+ client.fetch = wrapped;
16307
+ return () => {
16308
+ if (client.fetch === wrapped) client.fetch = original;
16309
+ };
16310
+ }
16311
+ function installClientOwnedVoiceHook(options = {}) {
16312
+ const target = options.target ?? globalThis;
16313
+ const existing = target[HOOK_GLOBAL];
16314
+ if (existing) return existing;
16315
+ const config2 = readCpaLiveVoiceHookConfig(target);
16316
+ if (!config2 || !cpaLiveVoicePreferenceAllowsInstall(target))
16317
+ return { status: "disabled", dispose() {
16318
+ } };
16319
+ if (config2.desktopVersion !== void 0 && config2.desktopVersion !== CLIENT_OWNED_VOICE_VERSION)
16320
+ return { status: "unsupported", dispose() {
16321
+ } };
16322
+ const importModule = options.importModule ?? ((url2) => import(url2));
16323
+ let disposed = false;
16324
+ let timer;
16325
+ let restore;
16326
+ const started = Date.now();
16327
+ const handle = {
16328
+ status: "pending",
16329
+ dispose() {
16330
+ disposed = true;
16331
+ if (timer !== void 0) target.clearTimeout(timer);
16332
+ restore?.();
16333
+ if (target[HOOK_GLOBAL] === handle) Reflect.deleteProperty(target, HOOK_GLOBAL);
16334
+ }
16335
+ };
16336
+ target[HOOK_GLOBAL] = handle;
16337
+ const attempt = async () => {
16338
+ if (disposed) return;
16339
+ const names = loadedAssetNames(target.document, target.performance);
16340
+ if (auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_INITIAL_ASSET) && auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_SHARED_ASSET)) {
16341
+ try {
16342
+ const module = await importModule(`app://-/assets/${CLIENT_OWNED_VOICE_SHARED_ASSET}`);
16343
+ if (disposed) return;
16344
+ const fetchClass = module.urt;
16345
+ const bridgeClass = module.mPt;
16346
+ if (!object2(fetchClass) && typeof fetchClass !== "function") throw new Error();
16347
+ if (!object2(bridgeClass) && typeof bridgeClass !== "function") throw new Error();
16348
+ const client = Reflect.get(fetchClass, "getInstance").call(fetchClass);
16349
+ const bridge = Reflect.get(bridgeClass, "getInstance").call(bridgeClass);
16350
+ if (typeof client?.fetch !== "function" || typeof bridge?.dispatchMessage !== "function" || typeof bridge?.subscribe !== "function" || typeof module.grt !== "function")
16351
+ throw new Error();
16352
+ restore = wrapClientOwnedVoiceFetch(
16353
+ client,
16354
+ bridge,
16355
+ () => cpaLiveVoicePreferenceAllowsInstall(target),
16356
+ module.grt
16357
+ );
16358
+ handle.status = "active";
16359
+ } catch {
16360
+ handle.status = "unsupported";
16361
+ }
16362
+ return;
16363
+ }
16364
+ if (Date.now() - started >= 6e4) {
16365
+ handle.status = "unsupported";
16366
+ return;
16367
+ }
16368
+ timer = target.setTimeout(() => void attempt(), 250);
16369
+ };
16370
+ void attempt();
16371
+ return handle;
16372
+ }
16373
+
16374
+ // src/agent-selection-state.ts
16375
+ var DEFAULT_RENDERER_AGENTS = ["codex"];
16376
+ function defaultIdFactory(sequence) {
16377
+ return `codexhost-composer-${Date.now().toString(36)}-${sequence.toString(36)}`;
16378
+ }
16379
+ function isDefaultTarget(target) {
16380
+ return target?.[0] === "default";
16381
+ }
16382
+ function isConversationTarget(target) {
16383
+ return target?.[0] === "conversation";
16384
+ }
16385
+ function isIdentifiedTarget(target) {
16386
+ return target?.[0] === "conversation" || target?.[0] === "default" && typeof target[1] === "string" && target[1].startsWith("client-new-thread:");
16387
+ }
16388
+ function sameTarget(left, right) {
16389
+ return left.length === right.length && left.every((value, index) => value === right[index]);
16390
+ }
16391
+ var DraftAgentController = class {
16392
+ #idFactory;
16393
+ #defaultAgent;
16394
+ #enabledAgents;
16395
+ #targetStates = [];
16396
+ #modelRequestGenerations = /* @__PURE__ */ new WeakMap();
16397
+ #ownershipRequestGenerations = /* @__PURE__ */ new WeakMap();
16398
+ #states = /* @__PURE__ */ new WeakMap();
16399
+ #switching = /* @__PURE__ */ new Set();
16400
+ #pendingSubmissions = /* @__PURE__ */ new Set();
16401
+ #composerSequence = 0;
16402
+ #modelRequestSequence = 0;
16403
+ #ownershipRequestSequence = 0;
16404
+ #lastSubmittedAgent;
16405
+ constructor(options = {}) {
16406
+ this.#idFactory = options.idFactory ?? defaultIdFactory;
16407
+ this.#enabledAgents = new Set(options.enabledAgents ?? DEFAULT_RENDERER_AGENTS);
16408
+ if (!this.#enabledAgents.has("codex"))
16409
+ throw new Error("Renderer enabled Agents must include Codex");
16410
+ this.#defaultAgent = options.defaultAgent ?? "codex";
16411
+ this.#lastSubmittedAgent = this.#defaultAgent;
16412
+ }
16413
+ setEnabledAgents(agents) {
16414
+ this.#enabledAgents = /* @__PURE__ */ new Set(["codex", ...agents]);
16415
+ }
16416
+ get(composer) {
16417
+ return this.#state(composer);
16418
+ }
16419
+ detach(composer, preservePendingSubmission = false) {
16420
+ const state = this.#states.get(composer);
16421
+ if (state && !preservePendingSubmission) this.#pendingSubmissions.delete(state);
16422
+ this.#states.delete(composer);
16423
+ }
16424
+ mount(composer, target, preferredNewThreadAgent) {
16425
+ const bound = this.#targetState(target);
16426
+ if (bound) {
16427
+ this.#states.set(composer, bound);
16428
+ return bound;
16429
+ }
16430
+ const preferredAgent = preferredNewThreadAgent ?? this.#lastSubmittedAgent;
16431
+ const state = this.#state(composer, isDefaultTarget(target) ? preferredAgent : "codex");
16432
+ if (isIdentifiedTarget(target)) this.#targetStates.push({ target, state });
16433
+ return state;
16434
+ }
16435
+ isSwitching(composer) {
16436
+ return this.#switching.has(this.#state(composer));
16437
+ }
16438
+ beginModelRequest(composer) {
16439
+ const state = this.#state(composer);
16440
+ const generation = ++this.#modelRequestSequence;
16441
+ this.#modelRequestGenerations.set(state, generation);
16442
+ return generation;
16443
+ }
16444
+ invalidateModelRequests(composer) {
16445
+ this.beginModelRequest(composer);
16446
+ }
16447
+ isCurrentModelRequest(composer, generation) {
16448
+ return (this.#modelRequestGenerations.get(this.#state(composer)) ?? 0) === generation;
16449
+ }
16450
+ beginOwnershipRequest(composer) {
16451
+ const generation = ++this.#ownershipRequestSequence;
16452
+ this.#ownershipRequestGenerations.set(this.#state(composer), generation);
16453
+ return generation;
16454
+ }
16455
+ isCurrentOwnershipRequest(composer, generation) {
16456
+ return (this.#ownershipRequestGenerations.get(this.#state(composer)) ?? 0) === generation;
16457
+ }
16458
+ rebindConversation(composer, target) {
16459
+ if (!isConversationTarget(target)) return null;
16460
+ const previous = this.#state(composer);
16461
+ this.#pendingSubmissions.delete(previous);
16462
+ this.#modelRequestGenerations.set(previous, ++this.#modelRequestSequence);
16463
+ this.#ownershipRequestGenerations.set(previous, ++this.#ownershipRequestSequence);
16464
+ let state = this.#targetState(target);
16465
+ if (!state) {
16466
+ state = {
16467
+ agent: "codex",
16468
+ phase: "draft",
16469
+ composerId: this.#idFactory(++this.#composerSequence)
16470
+ };
16471
+ this.#targetStates.push({ target, state });
16472
+ }
16473
+ this.#states.set(composer, state);
16474
+ this.#modelRequestGenerations.set(state, ++this.#modelRequestSequence);
16475
+ this.#ownershipRequestGenerations.set(state, ++this.#ownershipRequestSequence);
16476
+ return state;
16477
+ }
16478
+ restore(composer, agent, model2, thinkingOptionId, permissionModeId) {
16479
+ const state = this.#state(composer);
16480
+ this.#pendingSubmissions.delete(state);
16481
+ state.agent = agent;
16482
+ state.phase = "locked";
16483
+ if (agent !== "codex") {
16484
+ state.configurationByAgent = {
16485
+ ...state.configurationByAgent,
16486
+ [agent]: {
16487
+ ...model2 ? { model: model2 } : {},
16488
+ ...thinkingOptionId ? { thinkingOptionId } : {},
16489
+ ...permissionModeId ? { permissionModeId } : {}
16490
+ }
16491
+ };
16492
+ }
16493
+ return state;
16494
+ }
16495
+ clearConfiguration(composer) {
16496
+ delete this.#state(composer).configurationByAgent;
16497
+ }
16498
+ modelForAgent(composer, agent) {
16499
+ return this.#state(composer).configurationByAgent?.[agent]?.model;
16500
+ }
16501
+ thinkingOptionForAgent(composer, agent) {
16502
+ return this.#state(composer).configurationByAgent?.[agent]?.thinkingOptionId;
16503
+ }
16504
+ permissionModeForAgent(composer, agent) {
16505
+ return this.#state(composer).configurationByAgent?.[agent]?.permissionModeId;
16506
+ }
16507
+ setExternalPermissionMode(composer, agent, permissionModeId) {
16508
+ return this.#configure(composer, agent, { permissionModeId });
16509
+ }
16510
+ setExternalModel(composer, agent, model2) {
16511
+ return this.#configure(composer, agent, { model: model2 });
16512
+ }
16513
+ setExternalThinkingOption(composer, agent, thinkingOptionId) {
16514
+ const state = this.#configure(composer, agent, {});
16515
+ const configuration = state.configurationByAgent?.[agent];
16516
+ if (!configuration) return state;
16517
+ if (thinkingOptionId) configuration.thinkingOptionId = thinkingOptionId;
16518
+ else delete configuration.thinkingOptionId;
16519
+ return state;
16520
+ }
16521
+ #configure(composer, agent, patch) {
16522
+ const state = this.#state(composer);
16523
+ state.configurationByAgent = {
16524
+ ...state.configurationByAgent,
16525
+ [agent]: { ...state.configurationByAgent?.[agent], ...patch }
16526
+ };
16527
+ return state;
16528
+ }
16529
+ lock(composer) {
16530
+ const state = this.#state(composer);
16531
+ this.#pendingSubmissions.delete(state);
16532
+ state.phase = "locked";
16533
+ return state;
16534
+ }
16535
+ markSubmissionPending(composer) {
16536
+ const state = this.#state(composer);
16537
+ if (state.phase === "draft") this.#pendingSubmissions.add(state);
16538
+ return state;
16539
+ }
16540
+ isSubmissionPending(composer) {
16541
+ return this.#pendingSubmissions.has(this.#state(composer));
16542
+ }
16543
+ clearPendingSubmission(composer) {
16544
+ this.#pendingSubmissions.delete(this.#state(composer));
16545
+ }
16546
+ recordSubmission(composer) {
16547
+ const state = this.#state(composer);
16548
+ this.#lastSubmittedAgent = state.agent;
16549
+ return state;
16550
+ }
16551
+ transfer(source, replacement, target = null) {
16552
+ const state = this.#states.get(source);
16553
+ if (!state) return false;
16554
+ const bound = this.#targetState(target);
16555
+ if (bound && bound !== state) return false;
16556
+ if (source !== replacement) {
16557
+ if (this.#states.has(replacement)) return false;
16558
+ this.#states.set(replacement, state);
16559
+ }
16560
+ if (isIdentifiedTarget(target) && !bound) this.#targetStates.push({ target, state });
16561
+ if (isConversationTarget(target) && this.#pendingSubmissions.delete(state))
16562
+ state.phase = "locked";
16563
+ return true;
16564
+ }
16565
+ async switchAgent(composer, nextAgent, operations) {
16566
+ const state = this.#state(composer);
16567
+ if (!this.#enabledAgents.has(nextAgent)) return false;
16568
+ if (state.phase !== "draft" || this.#switching.has(state)) return false;
16569
+ if (state.agent === nextAgent) return true;
16570
+ this.#pendingSubmissions.delete(state);
16571
+ this.#switching.add(state);
16572
+ try {
16573
+ if (!operations.applyAgent(nextAgent)) return false;
16574
+ try {
16575
+ await operations.clearPrewarm();
16576
+ } catch (error51) {
16577
+ if (!operations.applyAgent(state.agent))
16578
+ throw new Error("Draft Agent switch could not restore the prior Agent", { cause: error51 });
16579
+ return false;
16580
+ }
16581
+ state.agent = nextAgent;
16582
+ return true;
16583
+ } finally {
16584
+ this.#switching.delete(state);
16585
+ }
16586
+ }
16587
+ #targetState(target) {
16588
+ if (!isIdentifiedTarget(target)) return null;
16589
+ return this.#targetStates.find((candidate) => sameTarget(candidate.target, target))?.state ?? null;
16590
+ }
16591
+ #state(composer, initialAgent) {
16592
+ const existing = this.#states.get(composer);
16593
+ if (existing) return existing;
16594
+ const created = {
16595
+ agent: initialAgent ?? this.#defaultAgent,
16596
+ phase: "draft",
16597
+ composerId: this.#idFactory(++this.#composerSequence)
16598
+ };
16599
+ this.#states.set(composer, created);
16600
+ return created;
16601
+ }
16602
+ };
16603
+
16404
16604
  // src/codex-ssh-adapter.ts
16405
16605
  var record2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
16406
16606
  function createCodexSshClient(ownerWindow) {
@@ -16410,7 +16610,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16410
16610
  return Promise.reject(new Error("Codex SSH settings are unavailable in this window"));
16411
16611
  if (signal?.aborted) return Promise.reject(new DOMException("Aborted", "AbortError"));
16412
16612
  return new Promise((resolve, reject) => {
16413
- const requestId = ownerWindow.crypto.randomUUID();
16613
+ const requestId2 = ownerWindow.crypto.randomUUID();
16414
16614
  const finish = (error51, value) => {
16415
16615
  ownerWindow.clearTimeout(timer);
16416
16616
  ownerWindow.removeEventListener("message", receive);
@@ -16421,7 +16621,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16421
16621
  const abort = () => finish(new DOMException("Aborted", "AbortError"));
16422
16622
  const receive = (event) => {
16423
16623
  const message2 = event.data;
16424
- if (!record2(message2) || message2.type !== "fetch-response" || message2.requestId !== requestId)
16624
+ if (!record2(message2) || message2.type !== "fetch-response" || message2.requestId !== requestId2)
16425
16625
  return;
16426
16626
  if (message2.responseType !== "success" || typeof message2.status !== "number" || message2.status < 200 || message2.status >= 300 || typeof message2.bodyJsonString !== "string") {
16427
16627
  finish(new Error("Codex SSH request failed; check the native Connections settings"));
@@ -16443,7 +16643,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16443
16643
  Promise.resolve(
16444
16644
  bridge.sendMessageFromView({
16445
16645
  type: "fetch",
16446
- requestId,
16646
+ requestId: requestId2,
16447
16647
  method: "POST",
16448
16648
  url: `vscode://codex/${operation}`,
16449
16649
  body: JSON.stringify(params),
@@ -26152,7 +26352,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26152
26352
  return Promise.reject(new Error("Codex locale bridge is unavailable"));
26153
26353
  }
26154
26354
  if (signal?.aborted) return Promise.reject(abortError2());
26155
- const requestId = ownerWindow.crypto.randomUUID();
26355
+ const requestId2 = ownerWindow.crypto.randomUUID();
26156
26356
  return new Promise((resolve, reject) => {
26157
26357
  let settled = false;
26158
26358
  const cleanup = () => {
@@ -26170,7 +26370,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26170
26370
  const onMessage = (event) => {
26171
26371
  const message3 = event.data;
26172
26372
  if (!isRecord15(message3) || message3.type !== "fetch-response") return;
26173
- if (message3.requestId !== requestId) return;
26373
+ if (message3.requestId !== requestId2) return;
26174
26374
  if (message3.responseType !== "success" || typeof message3.status !== "number" || message3.status < 200 || message3.status >= 300 || typeof message3.bodyJsonString !== "string") {
26175
26375
  settle(() => reject(new Error("Codex locale request failed")));
26176
26376
  return;
@@ -26190,7 +26390,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
26190
26390
  signal?.addEventListener("abort", onAbort, { once: true });
26191
26391
  const message2 = {
26192
26392
  type: "fetch",
26193
- requestId,
26393
+ requestId: requestId2,
26194
26394
  method: "POST",
26195
26395
  url: request.url,
26196
26396
  ...request.body === void 0 ? {} : { body: request.body },
@@ -41961,7 +42161,7 @@ ${usage_default}`;
41961
42161
  }
41962
42162
 
41963
42163
  // src/renderer-external-voice-launch.ts
41964
- var HOOK_GLOBAL = "__codexhostExternalVoiceLaunchV1";
42164
+ var HOOK_GLOBAL2 = "__codexhostExternalVoiceLaunchV1";
41965
42165
  var SHARED_ASSET = "app-shared-8bd9d0399038.js";
41966
42166
  function isRecord16(value) {
41967
42167
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -41994,12 +42194,12 @@ ${usage_default}`;
41994
42194
  }
41995
42195
  function installExternalVoiceLaunchHook(options = {}) {
41996
42196
  const target = options.target ?? globalThis;
41997
- const existing = target[HOOK_GLOBAL];
42197
+ const existing = target[HOOK_GLOBAL2];
41998
42198
  if (existing) return existing;
41999
42199
  const config2 = readCpaLiveVoiceHookConfig(target);
42000
42200
  if (!config2) return { status: "disabled", dispose() {
42001
42201
  } };
42002
- if (config2.auditedDesktopVersion !== AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION || config2.auditedAppInitialAsset !== AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET || config2.desktopVersion !== void 0 && config2.desktopVersion !== config2.auditedDesktopVersion)
42202
+ if (config2.auditedDesktopVersion !== AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION || config2.auditedAppInitialAsset !== AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET || config2.desktopVersion !== void 0 && config2.desktopVersion !== config2.auditedDesktopVersion && config2.desktopVersion !== CLIENT_OWNED_VOICE_VERSION)
42003
42203
  return { status: "unsupported", dispose() {
42004
42204
  } };
42005
42205
  const importModule = options.importModule ?? ((url2) => import(url2));
@@ -42014,22 +42214,22 @@ ${usage_default}`;
42014
42214
  disposed = true;
42015
42215
  if (timer !== void 0) target.clearTimeout(timer);
42016
42216
  restore?.();
42017
- if (target[HOOK_GLOBAL] === handle) Reflect.deleteProperty(target, HOOK_GLOBAL);
42217
+ if (target[HOOK_GLOBAL2] === handle) Reflect.deleteProperty(target, HOOK_GLOBAL2);
42018
42218
  }
42019
42219
  };
42020
- target[HOOK_GLOBAL] = handle;
42220
+ target[HOOK_GLOBAL2] = handle;
42021
42221
  const attempt = async () => {
42022
42222
  if (disposed) return;
42023
42223
  try {
42024
- const names = target.performance?.getEntriesByType("resource").map((entry) => entry.name) ?? [];
42025
- for (const element of target.document?.querySelectorAll("script[src], link[href]") ?? []) {
42026
- const name = element.getAttribute("src") ?? element.getAttribute("href");
42027
- if (name) names.push(name);
42028
- }
42029
- if (auditedAppInitialAssetPresent(names, AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET) && auditedAppInitialAssetPresent(names, SHARED_ASSET)) {
42030
- module ??= await importModule(`app://-/assets/${SHARED_ASSET}`);
42224
+ const names = loadedAssetNames(target.document, target.performance);
42225
+ const clientOwned = auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_INITIAL_ASSET) && auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_SHARED_ASSET);
42226
+ const legacy = auditedAppInitialAssetPresent(names, AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET) && auditedAppInitialAssetPresent(names, SHARED_ASSET);
42227
+ if (clientOwned || legacy) {
42228
+ module ??= await importModule(
42229
+ `app://-/assets/${clientOwned ? CLIENT_OWNED_VOICE_SHARED_ASSET : SHARED_ASSET}`
42230
+ );
42031
42231
  if (disposed) return;
42032
- const services = module?.fN;
42232
+ const services = clientOwned ? module?.Kat : module?.fN;
42033
42233
  if (isRecord16(services)) {
42034
42234
  const original = services.realtimeVoiceRuntime;
42035
42235
  if (typeof original === "function" || isRecord16(original)) {
@@ -42080,6 +42280,7 @@ ${usage_default}`;
42080
42280
 
42081
42281
  // src/production-entry.ts
42082
42282
  installCpaLiveVoiceHook();
42283
+ installClientOwnedVoiceHook();
42083
42284
  installExternalVoiceLaunchHook();
42084
42285
  var installBinding = () => {
42085
42286
  installRendererBinding();