@karlorz/codexhost-cli-win32-arm64 0.13.3-4 → 0.13.3-6
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 +432 -31
- package/app/console-web.js +806 -186
- package/app/cpa-live-voice-hook.js +16310 -31
- package/app/desktop-controller.mjs +147 -37
- package/app/host-runtime.mjs +3535 -3126
- package/app/plugins/antigravity/plugin.mjs +77 -0
- package/app/plugins/claude-code/plugin.mjs +152 -29
- package/app/plugins/codebuddy/plugin.mjs +109 -32
- package/app/plugins/codex-usage/plugin.mjs +77 -0
- package/app/plugins/cursor-cli/plugin.mjs +120 -43
- package/app/plugins/deepseek-harness/plugin.mjs +82 -5
- package/app/plugins/grok/plugin.mjs +138 -24
- package/app/plugins/hermes/plugin.mjs +77 -0
- package/app/plugins/kimi-code/plugin.mjs +99 -22
- package/app/plugins/kiro-cli/plugin.mjs +99 -22
- package/app/plugins/omp/plugin.mjs +92 -15
- package/app/plugins/opencode/plugin.mjs +77 -0
- package/app/plugins/pi/plugin.mjs +98 -21
- package/app/plugins/qoder/plugin.mjs +85 -8
- package/app/plugins/qoder-cn/plugin.mjs +85 -8
- package/app/plugins/workbuddy/plugin.mjs +109 -32
- package/app/plugins/zcode/plugin.mjs +100 -23
- package/app/renderer-extension.js +2238 -860
- 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,396 +6,103 @@
|
|
|
6
6
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
//
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
owner.localStorage.setItem(CPA_LIVE_VOICE_STORAGE_KEY, enabled ? "1" : "0");
|
|
22
|
-
} catch {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
owner.dispatchEvent(new Event(CPA_LIVE_VOICE_CHANGE_EVENT));
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
function cpaLiveVoicePreferenceAllowsInstall(globalObject) {
|
|
29
|
-
const storage = globalObject.localStorage;
|
|
30
|
-
if (!storage) return true;
|
|
31
|
-
try {
|
|
32
|
-
return storage.getItem(CPA_LIVE_VOICE_STORAGE_KEY) !== "0";
|
|
33
|
-
} catch {
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// src/renderer-cpa-live-voice-hook.ts
|
|
39
|
-
var CPA_LIVE_VOICE_HOOK_GLOBAL = "__codexhostCpaLiveVoiceHookV1";
|
|
40
|
-
var AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION = "26.1007.30912";
|
|
41
|
-
var AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET = "app-initial-6350d04672d0.js";
|
|
42
|
-
var THREAD_REALTIME_EXISTING_CALL_GATE = "206132468";
|
|
43
|
-
var originalCheckGate = /* @__PURE__ */ new WeakMap();
|
|
44
|
-
var DISCOVERY_TIMEOUT_MS = 6e4;
|
|
45
|
-
function isRecord(value) {
|
|
46
|
-
return typeof value === "object" && value !== null;
|
|
47
|
-
}
|
|
48
|
-
function readCpaLiveVoiceHookConfig(globalObject) {
|
|
49
|
-
const value = globalObject[CPA_LIVE_VOICE_HOOK_GLOBAL];
|
|
50
|
-
if (!isRecord(value) || value.enabled !== true) return null;
|
|
51
|
-
if (typeof value.auditedDesktopVersion !== "string" || typeof value.auditedAppInitialAsset !== "string") {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
return {
|
|
55
|
-
enabled: true,
|
|
56
|
-
auditedDesktopVersion: value.auditedDesktopVersion,
|
|
57
|
-
auditedAppInitialAsset: value.auditedAppInitialAsset,
|
|
58
|
-
...typeof value.desktopVersion === "string" ? { desktopVersion: value.desktopVersion } : {}
|
|
9
|
+
// ../desktop-control/dist/renderer-react-ownership.js
|
|
10
|
+
var REACT_FIBER_WALK_LIMIT_EVENT = "codexhost:react-fiber-walk-limit";
|
|
11
|
+
function committedReactAncestors(value) {
|
|
12
|
+
const MAX_VISITED_FIBERS = 2e5;
|
|
13
|
+
const fiber = (value2) => typeof value2 === "object" && value2 !== null ? value2 : null;
|
|
14
|
+
const exhausted = () => {
|
|
15
|
+
const target = globalThis;
|
|
16
|
+
if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function")
|
|
17
|
+
target.dispatchEvent(new CustomEvent("codexhost:react-fiber-walk-limit", {
|
|
18
|
+
detail: { limit: MAX_VISITED_FIBERS }
|
|
19
|
+
}));
|
|
20
|
+
return [];
|
|
59
21
|
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return resourceNames.some((name) => {
|
|
63
|
-
try {
|
|
64
|
-
const url2 = new URL(name, "app://-/");
|
|
65
|
-
return url2.protocol === "app:" && url2.hostname === "-" && url2.pathname === `/assets/${asset}`;
|
|
66
|
-
} catch {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
function resourceNamesFromPerformance() {
|
|
72
|
-
if (typeof performance === "undefined" || typeof performance.getEntriesByType !== "function") {
|
|
22
|
+
const first = fiber(value);
|
|
23
|
+
if (!first)
|
|
73
24
|
return [];
|
|
25
|
+
const previous = [];
|
|
26
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27
|
+
for (let node = first; node; node = fiber(node.return)) {
|
|
28
|
+
if (seen.has(node))
|
|
29
|
+
return [];
|
|
30
|
+
if (seen.size >= MAX_VISITED_FIBERS)
|
|
31
|
+
return exhausted();
|
|
32
|
+
seen.add(node);
|
|
33
|
+
previous.push(node);
|
|
74
34
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
if (!
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
client.checkGate = function(name, ...rest) {
|
|
102
|
-
return name === THREAD_REALTIME_EXISTING_CALL_GATE ? false : original.call(this, name, ...rest);
|
|
103
|
-
};
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
function restoreCheckGate(client) {
|
|
107
|
-
const original = originalCheckGate.get(client);
|
|
108
|
-
if (!original) return;
|
|
109
|
-
client.checkGate = original;
|
|
110
|
-
originalCheckGate.delete(client);
|
|
111
|
-
}
|
|
112
|
-
function configAllowsInstall(config2, resourceNames) {
|
|
113
|
-
if (config2.desktopVersion !== void 0 && config2.desktopVersion !== config2.auditedDesktopVersion) {
|
|
114
|
-
return false;
|
|
35
|
+
const rootState = fiber(previous.at(-1)?.stateNode);
|
|
36
|
+
if (!rootState || !("current" in rootState))
|
|
37
|
+
return previous;
|
|
38
|
+
const current = fiber(rootState.current);
|
|
39
|
+
if (!current)
|
|
40
|
+
return [];
|
|
41
|
+
const alternate = fiber(first.alternate);
|
|
42
|
+
const path = [current];
|
|
43
|
+
seen.clear();
|
|
44
|
+
seen.add(current);
|
|
45
|
+
for (let index = previous.length - 2; index >= 0; index -= 1) {
|
|
46
|
+
const expected = previous[index];
|
|
47
|
+
const expectedAlternate = fiber(expected?.alternate);
|
|
48
|
+
let child = fiber(path.at(-1)?.child);
|
|
49
|
+
let matched = false;
|
|
50
|
+
while (child && !seen.has(child) && seen.size < MAX_VISITED_FIBERS) {
|
|
51
|
+
seen.add(child);
|
|
52
|
+
if (child === expected || child === expectedAlternate) {
|
|
53
|
+
matched = true;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
child = fiber(child.sibling);
|
|
57
|
+
}
|
|
58
|
+
if (!matched || !child)
|
|
59
|
+
break;
|
|
60
|
+
path.push(child);
|
|
115
61
|
}
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
return auditedAppInitialAssetPresent(resourceNames, config2.auditedAppInitialAsset);
|
|
119
|
-
}
|
|
120
|
-
function installCpaLiveVoiceHook(options = {}) {
|
|
121
|
-
const globalObject = options.globalThis ?? globalThis;
|
|
122
|
-
const config2 = options.config === void 0 ? readCpaLiveVoiceHookConfig(globalObject) : options.config;
|
|
123
|
-
if (!config2?.enabled || !cpaLiveVoicePreferenceAllowsInstall(globalObject)) {
|
|
124
|
-
return { status: "disabled", dispose() {
|
|
125
|
-
} };
|
|
62
|
+
if (path.length === previous.length && (path.at(-1) === first || path.at(-1) === alternate)) {
|
|
63
|
+
return path.reverse();
|
|
126
64
|
}
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const resourceNames = options.resourceNames ?? resourceNamesFromDocument(root);
|
|
142
|
-
auditedAssetFound = configAllowsInstall(config2, resourceNames);
|
|
143
|
-
if (!auditedAssetFound) return false;
|
|
144
|
-
}
|
|
145
|
-
for (const client of statsigClients(globalObject)) {
|
|
146
|
-
if (wrapCheckGate(client)) wrapped.push(client);
|
|
65
|
+
const stack = [{ node: current, parent: null }];
|
|
66
|
+
seen.clear();
|
|
67
|
+
while (stack.length > 0 && seen.size < MAX_VISITED_FIBERS) {
|
|
68
|
+
const entry = stack.pop();
|
|
69
|
+
if (!entry)
|
|
70
|
+
break;
|
|
71
|
+
if (seen.has(entry.node))
|
|
72
|
+
return [];
|
|
73
|
+
seen.add(entry.node);
|
|
74
|
+
if (entry.node === first || entry.node === alternate) {
|
|
75
|
+
const ancestors = [];
|
|
76
|
+
for (let cursor = entry; cursor; cursor = cursor.parent)
|
|
77
|
+
ancestors.push(cursor.node);
|
|
78
|
+
return ancestors;
|
|
147
79
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
handle.status = "unsupported";
|
|
155
|
-
return handle;
|
|
80
|
+
const sibling = entry.parent && fiber(entry.node.sibling);
|
|
81
|
+
if (sibling)
|
|
82
|
+
stack.push({ node: sibling, parent: entry.parent });
|
|
83
|
+
const child = fiber(entry.node.child);
|
|
84
|
+
if (child)
|
|
85
|
+
stack.push({ node: child, parent: entry });
|
|
156
86
|
}
|
|
157
|
-
|
|
158
|
-
const tick = () => {
|
|
159
|
-
if (disposed || attempt()) return;
|
|
160
|
-
if (Date.now() - started > DISCOVERY_TIMEOUT_MS) {
|
|
161
|
-
handle.status = "unsupported";
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
globalThis.setTimeout(tick, 250);
|
|
165
|
-
};
|
|
166
|
-
globalThis.setTimeout(tick, 250);
|
|
167
|
-
return handle;
|
|
87
|
+
return stack.length > 0 ? exhausted() : [];
|
|
168
88
|
}
|
|
169
89
|
|
|
170
|
-
// src/
|
|
171
|
-
var
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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;
|
|
90
|
+
// src/renderer-chat-voice-debug.ts
|
|
91
|
+
var CHAT_VOICE_DEBUG_GLOBAL = "__codexhostChatVoiceDebug";
|
|
92
|
+
var CHAT_VOICE_DEBUG_STORAGE_KEY = "codexhost.chat-voice-debug.v1";
|
|
93
|
+
function chatVoiceDebug(event, detail = {}) {
|
|
94
|
+
const entry = { t: Date.now(), event, ...detail };
|
|
95
|
+
const owner = globalThis;
|
|
96
|
+
const log = Array.isArray(owner[CHAT_VOICE_DEBUG_GLOBAL]) ? owner[CHAT_VOICE_DEBUG_GLOBAL] : [];
|
|
97
|
+
log.push(entry);
|
|
98
|
+
while (log.length > 40) log.shift();
|
|
99
|
+
owner[CHAT_VOICE_DEBUG_GLOBAL] = log;
|
|
100
|
+
try {
|
|
101
|
+
owner.localStorage?.setItem(CHAT_VOICE_DEBUG_STORAGE_KEY, JSON.stringify(log));
|
|
102
|
+
} catch {
|
|
397
103
|
}
|
|
398
|
-
|
|
104
|
+
owner.console?.info?.("[codexhost-chat-voice]", event, detail);
|
|
105
|
+
}
|
|
399
106
|
|
|
400
107
|
// ../../node_modules/zod/v4/classic/external.js
|
|
401
108
|
var external_exports = {};
|
|
@@ -1119,9 +826,9 @@
|
|
|
1119
826
|
return ratio - roundedRatio;
|
|
1120
827
|
}
|
|
1121
828
|
var EVALUATING = /* @__PURE__ */ Symbol("evaluating");
|
|
1122
|
-
function defineLazy(
|
|
829
|
+
function defineLazy(object3, key, getter) {
|
|
1123
830
|
let value = void 0;
|
|
1124
|
-
Object.defineProperty(
|
|
831
|
+
Object.defineProperty(object3, key, {
|
|
1125
832
|
get() {
|
|
1126
833
|
if (value === EVALUATING) {
|
|
1127
834
|
return void 0;
|
|
@@ -1133,7 +840,7 @@
|
|
|
1133
840
|
return value;
|
|
1134
841
|
},
|
|
1135
842
|
set(v) {
|
|
1136
|
-
Object.defineProperty(
|
|
843
|
+
Object.defineProperty(object3, key, {
|
|
1137
844
|
value: v
|
|
1138
845
|
// configurable: true,
|
|
1139
846
|
});
|
|
@@ -15210,6 +14917,55 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15210
14917
|
var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
|
|
15211
14918
|
var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
|
|
15212
14919
|
|
|
14920
|
+
// ../shared-contracts/dist/realtime-call.js
|
|
14921
|
+
var REALTIME_CALL_METHOD = "codexhost/realtime/call";
|
|
14922
|
+
var REALTIME_CALL_FORWARDED_HEADERS = [
|
|
14923
|
+
"openai-alpha",
|
|
14924
|
+
"thread-id",
|
|
14925
|
+
"session-id",
|
|
14926
|
+
"originator",
|
|
14927
|
+
"x-codex-turn-metadata"
|
|
14928
|
+
];
|
|
14929
|
+
var FORWARDED_HEADERS = new Set(REALTIME_CALL_FORWARDED_HEADERS);
|
|
14930
|
+
function filterRealtimeCallHeaders(headers) {
|
|
14931
|
+
const result = {};
|
|
14932
|
+
for (const [name, value] of Object.entries(headers ?? {})) {
|
|
14933
|
+
const key = name.toLowerCase();
|
|
14934
|
+
if (FORWARDED_HEADERS.has(key) && value.length > 0 && value.length <= 4096)
|
|
14935
|
+
result[key] = value;
|
|
14936
|
+
}
|
|
14937
|
+
return result;
|
|
14938
|
+
}
|
|
14939
|
+
var REALTIME_CALL_ID_PATTERN = /^rtc_[A-Za-z0-9_-]{1,128}$/u;
|
|
14940
|
+
function isRealtimeCallId(value) {
|
|
14941
|
+
return typeof value === "string" && REALTIME_CALL_ID_PATTERN.test(value);
|
|
14942
|
+
}
|
|
14943
|
+
function realtimeCallIdFromLocation(location) {
|
|
14944
|
+
const path = location.split(/[?#]/u)[0] ?? "";
|
|
14945
|
+
if (/^[A-Za-z0-9_-]{1,128}$/u.test(path))
|
|
14946
|
+
return path;
|
|
14947
|
+
return /\/(?:calls|live)\/([A-Za-z0-9_-]{1,128})$/u.exec(path)?.[1];
|
|
14948
|
+
}
|
|
14949
|
+
var requestId = external_exports.string().min(1).max(128);
|
|
14950
|
+
var realtimeCallParamsSchema = external_exports.discriminatedUnion("operation", [
|
|
14951
|
+
external_exports.object({
|
|
14952
|
+
operation: external_exports.literal("create"),
|
|
14953
|
+
requestId,
|
|
14954
|
+
body: external_exports.string().min(1).max(16 << 20),
|
|
14955
|
+
headers: external_exports.record(external_exports.string(), external_exports.string()).default({})
|
|
14956
|
+
}),
|
|
14957
|
+
external_exports.object({ operation: external_exports.literal("cancel"), requestId }),
|
|
14958
|
+
external_exports.object({
|
|
14959
|
+
operation: external_exports.literal("hangup"),
|
|
14960
|
+
callId: external_exports.string().regex(REALTIME_CALL_ID_PATTERN)
|
|
14961
|
+
})
|
|
14962
|
+
]);
|
|
14963
|
+
var realtimeCallResponseSchema = external_exports.object({
|
|
14964
|
+
status: external_exports.number().int().min(200).max(599),
|
|
14965
|
+
body: external_exports.string(),
|
|
14966
|
+
headers: external_exports.record(external_exports.string(), external_exports.string())
|
|
14967
|
+
});
|
|
14968
|
+
|
|
15213
14969
|
// ../shared-contracts/dist/console.js
|
|
15214
14970
|
var consoleAnnouncementSchema = external_exports.strictObject({
|
|
15215
14971
|
title: external_exports.string().trim().min(1).max(200),
|
|
@@ -15223,6 +14979,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15223
14979
|
url: external_exports.string().max(2048).regex(/^http:\/\/(?:127\.0\.0\.1|localhost):\d{1,5}\/(?:\?.*)?$/u)
|
|
15224
14980
|
});
|
|
15225
14981
|
var CONSOLE_HOST_METHODS = Object.freeze([
|
|
14982
|
+
"codexhost/voice/gateway-status",
|
|
15226
14983
|
"codexhost/console/remote-connections",
|
|
15227
14984
|
"codexhost/runtime/status",
|
|
15228
14985
|
"codexhost/remote/ssh-setup",
|
|
@@ -16398,11 +16155,1323 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16398
16155
|
external_exports.strictObject({ error: external_exports.strictObject({ code: external_exports.number().int(), message: external_exports.string() }) })
|
|
16399
16156
|
]);
|
|
16400
16157
|
|
|
16158
|
+
// ../shared-contracts/dist/voice-settings.js
|
|
16159
|
+
var VOICE_SETTINGS_METHOD = "codexhost/voice/settings";
|
|
16160
|
+
var voiceRoutesSchema = external_exports.strictObject({
|
|
16161
|
+
chatExperience: external_exports.enum(["chatgpt", "codex"]),
|
|
16162
|
+
chatConnection: external_exports.enum(["desktop", "gateway"]),
|
|
16163
|
+
workConnection: external_exports.enum(["desktop", "gateway"])
|
|
16164
|
+
});
|
|
16165
|
+
var DEFAULT_VOICE_ROUTES = Object.freeze({
|
|
16166
|
+
chatExperience: "chatgpt",
|
|
16167
|
+
chatConnection: "desktop",
|
|
16168
|
+
workConnection: "gateway"
|
|
16169
|
+
});
|
|
16170
|
+
var voiceSettingsSchema = voiceRoutesSchema.extend({ inject: external_exports.boolean() });
|
|
16171
|
+
var voiceSettingsRequestSchema = external_exports.discriminatedUnion("operation", [
|
|
16172
|
+
external_exports.strictObject({
|
|
16173
|
+
operation: external_exports.literal("get"),
|
|
16174
|
+
runtime: external_exports.strictObject({
|
|
16175
|
+
id: external_exports.string().uuid(),
|
|
16176
|
+
revision: external_exports.string().max(64),
|
|
16177
|
+
activeCall: external_exports.boolean()
|
|
16178
|
+
}).optional()
|
|
16179
|
+
}),
|
|
16180
|
+
external_exports.strictObject({ operation: external_exports.literal("migrate"), routes: voiceRoutesSchema }),
|
|
16181
|
+
external_exports.strictObject({
|
|
16182
|
+
operation: external_exports.literal("set"),
|
|
16183
|
+
settings: voiceSettingsSchema,
|
|
16184
|
+
revision: external_exports.string().max(64)
|
|
16185
|
+
}),
|
|
16186
|
+
external_exports.strictObject({ operation: external_exports.literal("restart"), confirm: external_exports.literal(true) })
|
|
16187
|
+
]);
|
|
16188
|
+
var voiceSettingsStateSchema = external_exports.strictObject({
|
|
16189
|
+
settings: voiceSettingsSchema,
|
|
16190
|
+
initialized: external_exports.boolean(),
|
|
16191
|
+
revision: external_exports.string(),
|
|
16192
|
+
activeInject: external_exports.boolean().nullable(),
|
|
16193
|
+
envOverride: external_exports.enum(["0", "1"]).nullable(),
|
|
16194
|
+
activeEnvOverride: external_exports.enum(["0", "1"]).nullable(),
|
|
16195
|
+
routesActive: external_exports.boolean().nullable(),
|
|
16196
|
+
activeCall: external_exports.boolean().nullable(),
|
|
16197
|
+
gatewayReady: external_exports.boolean().nullable(),
|
|
16198
|
+
restartAvailable: external_exports.boolean(),
|
|
16199
|
+
restart: external_exports.strictObject({
|
|
16200
|
+
phase: external_exports.enum(["idle", "restarting", "succeeded", "failed"]),
|
|
16201
|
+
error: external_exports.string().nullable()
|
|
16202
|
+
})
|
|
16203
|
+
});
|
|
16204
|
+
|
|
16401
16205
|
// ../shared-contracts/dist/index.js
|
|
16402
16206
|
var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
|
|
16403
16207
|
|
|
16208
|
+
// src/renderer-cpa-live-voice-preference.ts
|
|
16209
|
+
var sharedRoutes = /* @__PURE__ */ new WeakMap();
|
|
16210
|
+
var SHARED_VOICE_CACHE = "codexhost.voice-routes-cache.v1";
|
|
16211
|
+
function cachedRoutes(owner) {
|
|
16212
|
+
const memory = sharedRoutes.get(owner);
|
|
16213
|
+
if (memory) return memory;
|
|
16214
|
+
try {
|
|
16215
|
+
const storage = owner.localStorage;
|
|
16216
|
+
const parsed = voiceRoutesSchema.safeParse(
|
|
16217
|
+
JSON.parse(storage?.getItem(SHARED_VOICE_CACHE) ?? "null")
|
|
16218
|
+
).data;
|
|
16219
|
+
if (parsed) sharedRoutes.set(owner, parsed);
|
|
16220
|
+
return parsed;
|
|
16221
|
+
} catch {
|
|
16222
|
+
return void 0;
|
|
16223
|
+
}
|
|
16224
|
+
}
|
|
16225
|
+
function applySharedVoiceRoutes(owner, routes) {
|
|
16226
|
+
const snapshot = voiceRoutesSchema.parse({
|
|
16227
|
+
chatExperience: routes.chatExperience,
|
|
16228
|
+
chatConnection: routes.chatConnection,
|
|
16229
|
+
workConnection: routes.workConnection
|
|
16230
|
+
});
|
|
16231
|
+
sharedRoutes.set(owner, snapshot);
|
|
16232
|
+
try {
|
|
16233
|
+
owner.localStorage?.setItem(
|
|
16234
|
+
SHARED_VOICE_CACHE,
|
|
16235
|
+
JSON.stringify(snapshot)
|
|
16236
|
+
);
|
|
16237
|
+
} catch {
|
|
16238
|
+
}
|
|
16239
|
+
}
|
|
16240
|
+
function nativeChatVoicePreferenceAllowsStart(owner) {
|
|
16241
|
+
const routes = cachedRoutes(owner);
|
|
16242
|
+
return routes ? routes.chatExperience === "chatgpt" : !readFlag(owner, CHAT_LIVE_VOICE_STORAGE_KEY, false);
|
|
16243
|
+
}
|
|
16244
|
+
function legacyVoiceRoutes(owner) {
|
|
16245
|
+
return {
|
|
16246
|
+
chatExperience: readFlag(owner, CHAT_LIVE_VOICE_STORAGE_KEY, false) ? "codex" : "chatgpt",
|
|
16247
|
+
chatConnection: readFlag(owner, CHAT_LIVE_VOICE_STORAGE_KEY, false) ? "gateway" : "desktop",
|
|
16248
|
+
workConnection: readFlag(owner, CPA_LIVE_VOICE_STORAGE_KEY, true) ? "gateway" : "desktop"
|
|
16249
|
+
};
|
|
16250
|
+
}
|
|
16251
|
+
var CPA_LIVE_VOICE_STORAGE_KEY = "codexhost.cpa-live-voice.v1";
|
|
16252
|
+
var CHAT_LIVE_VOICE_STORAGE_KEY = "codexhost.chat-live-voice.v1";
|
|
16253
|
+
function readFlag(owner, key, enabledWhenUnset) {
|
|
16254
|
+
const storage = owner.localStorage;
|
|
16255
|
+
if (!storage) return enabledWhenUnset;
|
|
16256
|
+
try {
|
|
16257
|
+
const value = storage.getItem(key);
|
|
16258
|
+
return enabledWhenUnset ? value !== "0" : value === "1";
|
|
16259
|
+
} catch {
|
|
16260
|
+
return enabledWhenUnset;
|
|
16261
|
+
}
|
|
16262
|
+
}
|
|
16263
|
+
function readCpaLiveVoicePreference(owner) {
|
|
16264
|
+
const routes = cachedRoutes(owner);
|
|
16265
|
+
return routes ? routes.workConnection === "gateway" : readFlag(owner, CPA_LIVE_VOICE_STORAGE_KEY, true);
|
|
16266
|
+
}
|
|
16267
|
+
function readChatLiveVoicePreference(owner) {
|
|
16268
|
+
const routes = cachedRoutes(owner);
|
|
16269
|
+
return routes ? routes.chatExperience === "codex" && routes.chatConnection === "gateway" : readFlag(owner, CHAT_LIVE_VOICE_STORAGE_KEY, false);
|
|
16270
|
+
}
|
|
16271
|
+
function cpaLiveVoicePreferenceAllowsInstall(globalObject) {
|
|
16272
|
+
return readCpaLiveVoicePreference(globalObject);
|
|
16273
|
+
}
|
|
16274
|
+
function chatLiveVoicePreferenceAllowsOverride(globalObject) {
|
|
16275
|
+
return readChatLiveVoicePreference(globalObject);
|
|
16276
|
+
}
|
|
16277
|
+
|
|
16278
|
+
// src/renderer-cpa-live-voice-hook.ts
|
|
16279
|
+
var CPA_LIVE_VOICE_HOOK_GLOBAL = "__codexhostCpaLiveVoiceHookV1";
|
|
16280
|
+
var AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION = "26.1007.30912";
|
|
16281
|
+
var AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET = "app-initial-6350d04672d0.js";
|
|
16282
|
+
var THREAD_REALTIME_EXISTING_CALL_GATE = "206132468";
|
|
16283
|
+
var originalCheckGate = /* @__PURE__ */ new WeakMap();
|
|
16284
|
+
var DISCOVERY_TIMEOUT_MS = 6e4;
|
|
16285
|
+
function isRecord(value) {
|
|
16286
|
+
return typeof value === "object" && value !== null;
|
|
16287
|
+
}
|
|
16288
|
+
function readCpaLiveVoiceHookConfig(globalObject) {
|
|
16289
|
+
const value = globalObject[CPA_LIVE_VOICE_HOOK_GLOBAL];
|
|
16290
|
+
if (!isRecord(value) || value.enabled !== true) return null;
|
|
16291
|
+
if (typeof value.auditedDesktopVersion !== "string" || typeof value.auditedAppInitialAsset !== "string") {
|
|
16292
|
+
return null;
|
|
16293
|
+
}
|
|
16294
|
+
return {
|
|
16295
|
+
enabled: true,
|
|
16296
|
+
auditedDesktopVersion: value.auditedDesktopVersion,
|
|
16297
|
+
auditedAppInitialAsset: value.auditedAppInitialAsset,
|
|
16298
|
+
...typeof value.desktopVersion === "string" ? { desktopVersion: value.desktopVersion } : {}
|
|
16299
|
+
};
|
|
16300
|
+
}
|
|
16301
|
+
function auditedAppInitialAssetPresent(resourceNames, asset) {
|
|
16302
|
+
return resourceNames.some((name) => {
|
|
16303
|
+
try {
|
|
16304
|
+
const url2 = new URL(name, "app://-/");
|
|
16305
|
+
return url2.protocol === "app:" && url2.hostname === "-" && url2.pathname === `/assets/${asset}`;
|
|
16306
|
+
} catch {
|
|
16307
|
+
return false;
|
|
16308
|
+
}
|
|
16309
|
+
});
|
|
16310
|
+
}
|
|
16311
|
+
function resourceNamesFromPerformance(source) {
|
|
16312
|
+
const target = source ?? (typeof performance === "undefined" ? void 0 : performance);
|
|
16313
|
+
if (!target || typeof target.getEntriesByType !== "function") return [];
|
|
16314
|
+
return target.getEntriesByType("resource").map((entry) => entry.name).filter((name) => typeof name === "string");
|
|
16315
|
+
}
|
|
16316
|
+
function loadedAssetNames(root, performanceSource) {
|
|
16317
|
+
const names = resourceNamesFromPerformance(performanceSource);
|
|
16318
|
+
if (!root || !("querySelectorAll" in root)) return names;
|
|
16319
|
+
for (const element of root.querySelectorAll("script[src], link[href]")) {
|
|
16320
|
+
const value = element.getAttribute("src") ?? element.getAttribute("href");
|
|
16321
|
+
if (value) names.push(value);
|
|
16322
|
+
}
|
|
16323
|
+
return names;
|
|
16324
|
+
}
|
|
16325
|
+
function statsigClients(globalObject) {
|
|
16326
|
+
const registry2 = globalObject.__STATSIG__;
|
|
16327
|
+
if (!isRecord(registry2)) return [];
|
|
16328
|
+
const clients = new Set(
|
|
16329
|
+
isRecord(registry2.instances) ? Object.values(registry2.instances) : []
|
|
16330
|
+
);
|
|
16331
|
+
if (registry2.firstInstance) clients.add(registry2.firstInstance);
|
|
16332
|
+
return [...clients].filter(
|
|
16333
|
+
(client) => isRecord(client) && typeof client.checkGate === "function"
|
|
16334
|
+
);
|
|
16335
|
+
}
|
|
16336
|
+
function wrapCheckGate(client) {
|
|
16337
|
+
if (originalCheckGate.has(client)) return false;
|
|
16338
|
+
const original = client.checkGate;
|
|
16339
|
+
originalCheckGate.set(client, original);
|
|
16340
|
+
client.checkGate = function(name, ...rest) {
|
|
16341
|
+
return name === THREAD_REALTIME_EXISTING_CALL_GATE ? false : original.call(this, name, ...rest);
|
|
16342
|
+
};
|
|
16343
|
+
return true;
|
|
16344
|
+
}
|
|
16345
|
+
function restoreCheckGate(client) {
|
|
16346
|
+
const original = originalCheckGate.get(client);
|
|
16347
|
+
if (!original) return;
|
|
16348
|
+
client.checkGate = original;
|
|
16349
|
+
originalCheckGate.delete(client);
|
|
16350
|
+
}
|
|
16351
|
+
function configAllowsInstall(config2, resourceNames) {
|
|
16352
|
+
if (config2.desktopVersion !== void 0 && config2.desktopVersion !== config2.auditedDesktopVersion) {
|
|
16353
|
+
return false;
|
|
16354
|
+
}
|
|
16355
|
+
if (config2.auditedDesktopVersion !== AUDITED_CPA_LIVE_VOICE_DESKTOP_VERSION) return false;
|
|
16356
|
+
if (config2.auditedAppInitialAsset !== AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET) return false;
|
|
16357
|
+
return auditedAppInitialAssetPresent(resourceNames, config2.auditedAppInitialAsset);
|
|
16358
|
+
}
|
|
16359
|
+
function installCpaLiveVoiceHook(options = {}) {
|
|
16360
|
+
const globalObject = options.globalThis ?? globalThis;
|
|
16361
|
+
const config2 = options.config === void 0 ? readCpaLiveVoiceHookConfig(globalObject) : options.config;
|
|
16362
|
+
if (!config2?.enabled || !cpaLiveVoicePreferenceAllowsInstall(globalObject)) {
|
|
16363
|
+
return { status: "disabled", dispose() {
|
|
16364
|
+
} };
|
|
16365
|
+
}
|
|
16366
|
+
const root = options.document ?? globalObject.document;
|
|
16367
|
+
const wrapped = [];
|
|
16368
|
+
let disposed = false;
|
|
16369
|
+
let auditedAssetFound = false;
|
|
16370
|
+
const handle = {
|
|
16371
|
+
status: "pending",
|
|
16372
|
+
dispose() {
|
|
16373
|
+
disposed = true;
|
|
16374
|
+
for (const client of wrapped) restoreCheckGate(client);
|
|
16375
|
+
wrapped.length = 0;
|
|
16376
|
+
}
|
|
16377
|
+
};
|
|
16378
|
+
const attempt = () => {
|
|
16379
|
+
if (!auditedAssetFound) {
|
|
16380
|
+
const resourceNames = options.resourceNames ?? loadedAssetNames(root);
|
|
16381
|
+
auditedAssetFound = configAllowsInstall(config2, resourceNames);
|
|
16382
|
+
if (!auditedAssetFound) return false;
|
|
16383
|
+
}
|
|
16384
|
+
for (const client of statsigClients(globalObject)) {
|
|
16385
|
+
if (wrapCheckGate(client)) wrapped.push(client);
|
|
16386
|
+
}
|
|
16387
|
+
if (wrapped.length === 0) return false;
|
|
16388
|
+
handle.status = "active";
|
|
16389
|
+
return true;
|
|
16390
|
+
};
|
|
16391
|
+
if (attempt()) return handle;
|
|
16392
|
+
if (options.resourceNames && !configAllowsInstall(config2, options.resourceNames)) {
|
|
16393
|
+
handle.status = "unsupported";
|
|
16394
|
+
return handle;
|
|
16395
|
+
}
|
|
16396
|
+
const started = Date.now();
|
|
16397
|
+
const tick = () => {
|
|
16398
|
+
if (disposed || attempt()) return;
|
|
16399
|
+
if (Date.now() - started > DISCOVERY_TIMEOUT_MS) {
|
|
16400
|
+
handle.status = "unsupported";
|
|
16401
|
+
return;
|
|
16402
|
+
}
|
|
16403
|
+
globalThis.setTimeout(tick, 250);
|
|
16404
|
+
};
|
|
16405
|
+
globalThis.setTimeout(tick, 250);
|
|
16406
|
+
return handle;
|
|
16407
|
+
}
|
|
16408
|
+
|
|
16409
|
+
// src/agent-selection-state.ts
|
|
16410
|
+
var DEFAULT_RENDERER_AGENTS = ["codex"];
|
|
16411
|
+
function defaultIdFactory(sequence) {
|
|
16412
|
+
return `codexhost-composer-${Date.now().toString(36)}-${sequence.toString(36)}`;
|
|
16413
|
+
}
|
|
16414
|
+
function isDefaultTarget(target) {
|
|
16415
|
+
return target?.[0] === "default";
|
|
16416
|
+
}
|
|
16417
|
+
function isConversationTarget(target) {
|
|
16418
|
+
return target?.[0] === "conversation";
|
|
16419
|
+
}
|
|
16420
|
+
function isIdentifiedTarget(target) {
|
|
16421
|
+
return target?.[0] === "conversation" || target?.[0] === "default" && typeof target[1] === "string" && target[1].startsWith("client-new-thread:");
|
|
16422
|
+
}
|
|
16423
|
+
function sameTarget(left, right) {
|
|
16424
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
16425
|
+
}
|
|
16426
|
+
var DraftAgentController = class {
|
|
16427
|
+
#idFactory;
|
|
16428
|
+
#defaultAgent;
|
|
16429
|
+
#enabledAgents;
|
|
16430
|
+
#targetStates = [];
|
|
16431
|
+
#modelRequestGenerations = /* @__PURE__ */ new WeakMap();
|
|
16432
|
+
#ownershipRequestGenerations = /* @__PURE__ */ new WeakMap();
|
|
16433
|
+
#states = /* @__PURE__ */ new WeakMap();
|
|
16434
|
+
#switching = /* @__PURE__ */ new Set();
|
|
16435
|
+
#pendingSubmissions = /* @__PURE__ */ new Set();
|
|
16436
|
+
#composerSequence = 0;
|
|
16437
|
+
#modelRequestSequence = 0;
|
|
16438
|
+
#ownershipRequestSequence = 0;
|
|
16439
|
+
#lastSubmittedAgent;
|
|
16440
|
+
constructor(options = {}) {
|
|
16441
|
+
this.#idFactory = options.idFactory ?? defaultIdFactory;
|
|
16442
|
+
this.#enabledAgents = new Set(options.enabledAgents ?? DEFAULT_RENDERER_AGENTS);
|
|
16443
|
+
if (!this.#enabledAgents.has("codex"))
|
|
16444
|
+
throw new Error("Renderer enabled Agents must include Codex");
|
|
16445
|
+
this.#defaultAgent = options.defaultAgent ?? "codex";
|
|
16446
|
+
this.#lastSubmittedAgent = this.#defaultAgent;
|
|
16447
|
+
}
|
|
16448
|
+
setEnabledAgents(agents) {
|
|
16449
|
+
this.#enabledAgents = /* @__PURE__ */ new Set(["codex", ...agents]);
|
|
16450
|
+
}
|
|
16451
|
+
get(composer) {
|
|
16452
|
+
return this.#state(composer);
|
|
16453
|
+
}
|
|
16454
|
+
detach(composer, preservePendingSubmission = false) {
|
|
16455
|
+
const state = this.#states.get(composer);
|
|
16456
|
+
if (state && !preservePendingSubmission) this.#pendingSubmissions.delete(state);
|
|
16457
|
+
this.#states.delete(composer);
|
|
16458
|
+
}
|
|
16459
|
+
mount(composer, target, preferredNewThreadAgent) {
|
|
16460
|
+
const bound = this.#targetState(target);
|
|
16461
|
+
if (bound) {
|
|
16462
|
+
this.#states.set(composer, bound);
|
|
16463
|
+
return bound;
|
|
16464
|
+
}
|
|
16465
|
+
const preferredAgent = preferredNewThreadAgent ?? this.#lastSubmittedAgent;
|
|
16466
|
+
const state = this.#state(composer, isDefaultTarget(target) ? preferredAgent : "codex");
|
|
16467
|
+
if (isIdentifiedTarget(target)) this.#targetStates.push({ target, state });
|
|
16468
|
+
return state;
|
|
16469
|
+
}
|
|
16470
|
+
isSwitching(composer) {
|
|
16471
|
+
return this.#switching.has(this.#state(composer));
|
|
16472
|
+
}
|
|
16473
|
+
beginModelRequest(composer) {
|
|
16474
|
+
const state = this.#state(composer);
|
|
16475
|
+
const generation = ++this.#modelRequestSequence;
|
|
16476
|
+
this.#modelRequestGenerations.set(state, generation);
|
|
16477
|
+
return generation;
|
|
16478
|
+
}
|
|
16479
|
+
invalidateModelRequests(composer) {
|
|
16480
|
+
this.beginModelRequest(composer);
|
|
16481
|
+
}
|
|
16482
|
+
isCurrentModelRequest(composer, generation) {
|
|
16483
|
+
return (this.#modelRequestGenerations.get(this.#state(composer)) ?? 0) === generation;
|
|
16484
|
+
}
|
|
16485
|
+
beginOwnershipRequest(composer) {
|
|
16486
|
+
const generation = ++this.#ownershipRequestSequence;
|
|
16487
|
+
this.#ownershipRequestGenerations.set(this.#state(composer), generation);
|
|
16488
|
+
return generation;
|
|
16489
|
+
}
|
|
16490
|
+
isCurrentOwnershipRequest(composer, generation) {
|
|
16491
|
+
return (this.#ownershipRequestGenerations.get(this.#state(composer)) ?? 0) === generation;
|
|
16492
|
+
}
|
|
16493
|
+
rebindConversation(composer, target) {
|
|
16494
|
+
if (!isConversationTarget(target)) return null;
|
|
16495
|
+
const previous = this.#state(composer);
|
|
16496
|
+
this.#pendingSubmissions.delete(previous);
|
|
16497
|
+
this.#modelRequestGenerations.set(previous, ++this.#modelRequestSequence);
|
|
16498
|
+
this.#ownershipRequestGenerations.set(previous, ++this.#ownershipRequestSequence);
|
|
16499
|
+
let state = this.#targetState(target);
|
|
16500
|
+
if (!state) {
|
|
16501
|
+
state = {
|
|
16502
|
+
agent: "codex",
|
|
16503
|
+
phase: "draft",
|
|
16504
|
+
composerId: this.#idFactory(++this.#composerSequence)
|
|
16505
|
+
};
|
|
16506
|
+
this.#targetStates.push({ target, state });
|
|
16507
|
+
}
|
|
16508
|
+
this.#states.set(composer, state);
|
|
16509
|
+
this.#modelRequestGenerations.set(state, ++this.#modelRequestSequence);
|
|
16510
|
+
this.#ownershipRequestGenerations.set(state, ++this.#ownershipRequestSequence);
|
|
16511
|
+
return state;
|
|
16512
|
+
}
|
|
16513
|
+
restore(composer, agent, model2, thinkingOptionId, permissionModeId) {
|
|
16514
|
+
const state = this.#state(composer);
|
|
16515
|
+
this.#pendingSubmissions.delete(state);
|
|
16516
|
+
state.agent = agent;
|
|
16517
|
+
state.phase = "locked";
|
|
16518
|
+
if (agent !== "codex") {
|
|
16519
|
+
state.configurationByAgent = {
|
|
16520
|
+
...state.configurationByAgent,
|
|
16521
|
+
[agent]: {
|
|
16522
|
+
...model2 ? { model: model2 } : {},
|
|
16523
|
+
...thinkingOptionId ? { thinkingOptionId } : {},
|
|
16524
|
+
...permissionModeId ? { permissionModeId } : {}
|
|
16525
|
+
}
|
|
16526
|
+
};
|
|
16527
|
+
}
|
|
16528
|
+
return state;
|
|
16529
|
+
}
|
|
16530
|
+
clearConfiguration(composer) {
|
|
16531
|
+
delete this.#state(composer).configurationByAgent;
|
|
16532
|
+
}
|
|
16533
|
+
modelForAgent(composer, agent) {
|
|
16534
|
+
return this.#state(composer).configurationByAgent?.[agent]?.model;
|
|
16535
|
+
}
|
|
16536
|
+
thinkingOptionForAgent(composer, agent) {
|
|
16537
|
+
return this.#state(composer).configurationByAgent?.[agent]?.thinkingOptionId;
|
|
16538
|
+
}
|
|
16539
|
+
permissionModeForAgent(composer, agent) {
|
|
16540
|
+
return this.#state(composer).configurationByAgent?.[agent]?.permissionModeId;
|
|
16541
|
+
}
|
|
16542
|
+
setExternalPermissionMode(composer, agent, permissionModeId) {
|
|
16543
|
+
return this.#configure(composer, agent, { permissionModeId });
|
|
16544
|
+
}
|
|
16545
|
+
setExternalModel(composer, agent, model2) {
|
|
16546
|
+
return this.#configure(composer, agent, { model: model2 });
|
|
16547
|
+
}
|
|
16548
|
+
setExternalThinkingOption(composer, agent, thinkingOptionId) {
|
|
16549
|
+
const state = this.#configure(composer, agent, {});
|
|
16550
|
+
const configuration = state.configurationByAgent?.[agent];
|
|
16551
|
+
if (!configuration) return state;
|
|
16552
|
+
if (thinkingOptionId) configuration.thinkingOptionId = thinkingOptionId;
|
|
16553
|
+
else delete configuration.thinkingOptionId;
|
|
16554
|
+
return state;
|
|
16555
|
+
}
|
|
16556
|
+
#configure(composer, agent, patch) {
|
|
16557
|
+
const state = this.#state(composer);
|
|
16558
|
+
state.configurationByAgent = {
|
|
16559
|
+
...state.configurationByAgent,
|
|
16560
|
+
[agent]: { ...state.configurationByAgent?.[agent], ...patch }
|
|
16561
|
+
};
|
|
16562
|
+
return state;
|
|
16563
|
+
}
|
|
16564
|
+
lock(composer) {
|
|
16565
|
+
const state = this.#state(composer);
|
|
16566
|
+
this.#pendingSubmissions.delete(state);
|
|
16567
|
+
state.phase = "locked";
|
|
16568
|
+
return state;
|
|
16569
|
+
}
|
|
16570
|
+
markSubmissionPending(composer) {
|
|
16571
|
+
const state = this.#state(composer);
|
|
16572
|
+
if (state.phase === "draft") this.#pendingSubmissions.add(state);
|
|
16573
|
+
return state;
|
|
16574
|
+
}
|
|
16575
|
+
isSubmissionPending(composer) {
|
|
16576
|
+
return this.#pendingSubmissions.has(this.#state(composer));
|
|
16577
|
+
}
|
|
16578
|
+
clearPendingSubmission(composer) {
|
|
16579
|
+
this.#pendingSubmissions.delete(this.#state(composer));
|
|
16580
|
+
}
|
|
16581
|
+
recordSubmission(composer) {
|
|
16582
|
+
const state = this.#state(composer);
|
|
16583
|
+
this.#lastSubmittedAgent = state.agent;
|
|
16584
|
+
return state;
|
|
16585
|
+
}
|
|
16586
|
+
transfer(source, replacement, target = null) {
|
|
16587
|
+
const state = this.#states.get(source);
|
|
16588
|
+
if (!state) return false;
|
|
16589
|
+
const bound = this.#targetState(target);
|
|
16590
|
+
if (bound && bound !== state) return false;
|
|
16591
|
+
if (source !== replacement) {
|
|
16592
|
+
if (this.#states.has(replacement)) return false;
|
|
16593
|
+
this.#states.set(replacement, state);
|
|
16594
|
+
}
|
|
16595
|
+
if (isIdentifiedTarget(target) && !bound) this.#targetStates.push({ target, state });
|
|
16596
|
+
if (isConversationTarget(target) && this.#pendingSubmissions.delete(state))
|
|
16597
|
+
state.phase = "locked";
|
|
16598
|
+
return true;
|
|
16599
|
+
}
|
|
16600
|
+
async switchAgent(composer, nextAgent, operations) {
|
|
16601
|
+
const state = this.#state(composer);
|
|
16602
|
+
if (!this.#enabledAgents.has(nextAgent)) return false;
|
|
16603
|
+
if (state.phase !== "draft" || this.#switching.has(state)) return false;
|
|
16604
|
+
if (state.agent === nextAgent) return true;
|
|
16605
|
+
this.#pendingSubmissions.delete(state);
|
|
16606
|
+
this.#switching.add(state);
|
|
16607
|
+
try {
|
|
16608
|
+
if (!operations.applyAgent(nextAgent)) return false;
|
|
16609
|
+
try {
|
|
16610
|
+
await operations.clearPrewarm();
|
|
16611
|
+
} catch (error51) {
|
|
16612
|
+
if (!operations.applyAgent(state.agent))
|
|
16613
|
+
throw new Error("Draft Agent switch could not restore the prior Agent", { cause: error51 });
|
|
16614
|
+
return false;
|
|
16615
|
+
}
|
|
16616
|
+
state.agent = nextAgent;
|
|
16617
|
+
return true;
|
|
16618
|
+
} finally {
|
|
16619
|
+
this.#switching.delete(state);
|
|
16620
|
+
}
|
|
16621
|
+
}
|
|
16622
|
+
#targetState(target) {
|
|
16623
|
+
if (!isIdentifiedTarget(target)) return null;
|
|
16624
|
+
return this.#targetStates.find((candidate) => sameTarget(candidate.target, target))?.state ?? null;
|
|
16625
|
+
}
|
|
16626
|
+
#state(composer, initialAgent) {
|
|
16627
|
+
const existing = this.#states.get(composer);
|
|
16628
|
+
if (existing) return existing;
|
|
16629
|
+
const created = {
|
|
16630
|
+
agent: initialAgent ?? this.#defaultAgent,
|
|
16631
|
+
phase: "draft",
|
|
16632
|
+
composerId: this.#idFactory(++this.#composerSequence)
|
|
16633
|
+
};
|
|
16634
|
+
this.#states.set(composer, created);
|
|
16635
|
+
return created;
|
|
16636
|
+
}
|
|
16637
|
+
};
|
|
16638
|
+
|
|
16639
|
+
// src/renderer-new-thread-preference.ts
|
|
16640
|
+
var RENDERER_NEW_THREAD_PREFERENCE_KEY = "codexhost.new-thread-preference.v1";
|
|
16641
|
+
function rendererNewThreadPreferenceStorage(hostId2 = "local") {
|
|
16642
|
+
if (!hostId2) return null;
|
|
16643
|
+
try {
|
|
16644
|
+
const storage = window.localStorage;
|
|
16645
|
+
if (hostId2 === "local") return storage;
|
|
16646
|
+
const scopedKey = (key) => `${key}.host.${encodeURIComponent(hostId2)}`;
|
|
16647
|
+
return {
|
|
16648
|
+
getItem: (key) => storage.getItem(scopedKey(key)),
|
|
16649
|
+
setItem: (key, value) => storage.setItem(scopedKey(key), value)
|
|
16650
|
+
};
|
|
16651
|
+
} catch {
|
|
16652
|
+
return null;
|
|
16653
|
+
}
|
|
16654
|
+
}
|
|
16655
|
+
function isRecord2(value) {
|
|
16656
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16657
|
+
}
|
|
16658
|
+
function parseExternalConfiguration(value) {
|
|
16659
|
+
if (!isRecord2(value)) return void 0;
|
|
16660
|
+
const model2 = harnessModelRefSchema.safeParse(value.model);
|
|
16661
|
+
if (!model2.success) return void 0;
|
|
16662
|
+
const thinkingOptionId = harnessThinkingOptionIdSchema.safeParse(value.thinkingOptionId);
|
|
16663
|
+
const permissionModeId = harnessPermissionModeIdSchema.safeParse(value.permissionModeId);
|
|
16664
|
+
return {
|
|
16665
|
+
model: model2.data,
|
|
16666
|
+
...thinkingOptionId.success ? { thinkingOptionId: thinkingOptionId.data } : {},
|
|
16667
|
+
...permissionModeId.success ? { permissionModeId: permissionModeId.data } : {}
|
|
16668
|
+
};
|
|
16669
|
+
}
|
|
16670
|
+
function readPreference(storage) {
|
|
16671
|
+
if (!storage) return void 0;
|
|
16672
|
+
try {
|
|
16673
|
+
const raw = storage.getItem(RENDERER_NEW_THREAD_PREFERENCE_KEY);
|
|
16674
|
+
if (!raw) return void 0;
|
|
16675
|
+
const parsed = JSON.parse(raw);
|
|
16676
|
+
if (!isRecord2(parsed) || parsed.version !== 1) return void 0;
|
|
16677
|
+
if (parsed.lastAgent !== "codex" && !harnessPluginIdSchema.safeParse(parsed.lastAgent).success)
|
|
16678
|
+
return void 0;
|
|
16679
|
+
const externalByAgent = isRecord2(parsed.externalByAgent) ? parsed.externalByAgent : {};
|
|
16680
|
+
const parsedExternal = Object.fromEntries(
|
|
16681
|
+
Object.keys(externalByAgent).filter((agent) => harnessPluginIdSchema.safeParse(agent).success).flatMap((agent) => {
|
|
16682
|
+
const configuration = parseExternalConfiguration(externalByAgent[agent]);
|
|
16683
|
+
return configuration ? [[agent, configuration]] : [];
|
|
16684
|
+
})
|
|
16685
|
+
);
|
|
16686
|
+
return {
|
|
16687
|
+
version: 1,
|
|
16688
|
+
lastAgent: parsed.lastAgent,
|
|
16689
|
+
externalByAgent: parsedExternal
|
|
16690
|
+
};
|
|
16691
|
+
} catch {
|
|
16692
|
+
return void 0;
|
|
16693
|
+
}
|
|
16694
|
+
}
|
|
16695
|
+
function writePreference(preference, storage) {
|
|
16696
|
+
if (!storage) return;
|
|
16697
|
+
try {
|
|
16698
|
+
storage.setItem(RENDERER_NEW_THREAD_PREFERENCE_KEY, JSON.stringify(preference));
|
|
16699
|
+
} catch {
|
|
16700
|
+
}
|
|
16701
|
+
}
|
|
16702
|
+
function readNewThreadAgentPreference(enabledAgents, storage = rendererNewThreadPreferenceStorage()) {
|
|
16703
|
+
const agent = readPreference(storage)?.lastAgent;
|
|
16704
|
+
return agent && (!enabledAgents || enabledAgents.has(agent)) ? agent : void 0;
|
|
16705
|
+
}
|
|
16706
|
+
function readNewThreadExternalConfigurationPreference(agent, catalog, permissionModes, storage = rendererNewThreadPreferenceStorage()) {
|
|
16707
|
+
const preference = readPreference(storage)?.externalByAgent[agent];
|
|
16708
|
+
if (!preference) return void 0;
|
|
16709
|
+
const catalogModel = catalogModelForRef(catalog, preference.model);
|
|
16710
|
+
if (!catalogModel) return void 0;
|
|
16711
|
+
const thinkingOptionId = preference.thinkingOptionId && catalogModel.supportedThinkingOptionIds?.includes(preference.thinkingOptionId) ? preference.thinkingOptionId : void 0;
|
|
16712
|
+
const permissionModeId = preference.permissionModeId && permissionModes?.modes.some(({ id }) => id === preference.permissionModeId) ? preference.permissionModeId : void 0;
|
|
16713
|
+
return {
|
|
16714
|
+
model: catalogModel.ref,
|
|
16715
|
+
...thinkingOptionId ? { thinkingOptionId } : {},
|
|
16716
|
+
...permissionModeId ? { permissionModeId } : {}
|
|
16717
|
+
};
|
|
16718
|
+
}
|
|
16719
|
+
function writeNewThreadAgentPreference(agent, storage = rendererNewThreadPreferenceStorage()) {
|
|
16720
|
+
const current = readPreference(storage);
|
|
16721
|
+
writePreference(
|
|
16722
|
+
{
|
|
16723
|
+
version: 1,
|
|
16724
|
+
lastAgent: agent,
|
|
16725
|
+
externalByAgent: current?.externalByAgent ?? {}
|
|
16726
|
+
},
|
|
16727
|
+
storage
|
|
16728
|
+
);
|
|
16729
|
+
}
|
|
16730
|
+
function writeNewThreadExternalConfigurationPreference(agent, model2, thinkingOptionId, permissionModeId, storage = rendererNewThreadPreferenceStorage()) {
|
|
16731
|
+
const current = readPreference(storage);
|
|
16732
|
+
writePreference(
|
|
16733
|
+
{
|
|
16734
|
+
version: 1,
|
|
16735
|
+
lastAgent: current?.lastAgent ?? "codex",
|
|
16736
|
+
externalByAgent: {
|
|
16737
|
+
...current?.externalByAgent,
|
|
16738
|
+
[agent]: {
|
|
16739
|
+
model: harnessModelRefSchema.parse(model2),
|
|
16740
|
+
...thinkingOptionId ? { thinkingOptionId: harnessThinkingOptionIdSchema.parse(thinkingOptionId) } : {},
|
|
16741
|
+
...permissionModeId ? { permissionModeId: harnessPermissionModeIdSchema.parse(permissionModeId) } : {}
|
|
16742
|
+
}
|
|
16743
|
+
}
|
|
16744
|
+
},
|
|
16745
|
+
storage
|
|
16746
|
+
);
|
|
16747
|
+
}
|
|
16748
|
+
|
|
16749
|
+
// src/renderer-client-owned-voice.ts
|
|
16750
|
+
var CLIENT_OWNED_VOICE_VERSION = "26.1013.40934";
|
|
16751
|
+
var CLIENT_OWNED_VOICE_INITIAL_ASSET = "app-initial-90eb42395b7d.js";
|
|
16752
|
+
var CLIENT_OWNED_VOICE_SHARED_ASSET = "app-shared-52443cbe9ac4.js";
|
|
16753
|
+
var HOOK_GLOBAL = "__codexhostClientOwnedVoiceV1";
|
|
16754
|
+
function object2(value) {
|
|
16755
|
+
return value !== null && typeof value === "object";
|
|
16756
|
+
}
|
|
16757
|
+
function requestHost(bridge, params) {
|
|
16758
|
+
const id = `codexhost-voice:${crypto.randomUUID()}`;
|
|
16759
|
+
return new Promise((resolve, reject) => {
|
|
16760
|
+
let unsubscribe = () => {
|
|
16761
|
+
};
|
|
16762
|
+
const timer = setTimeout(() => {
|
|
16763
|
+
unsubscribe();
|
|
16764
|
+
reject(new Error("Voice gateway did not answer in time"));
|
|
16765
|
+
}, 3e4);
|
|
16766
|
+
const done = () => {
|
|
16767
|
+
clearTimeout(timer);
|
|
16768
|
+
unsubscribe();
|
|
16769
|
+
};
|
|
16770
|
+
unsubscribe = bridge.subscribe("mcp-response", (event) => {
|
|
16771
|
+
if (!object2(event) || event.hostId !== "local" || !object2(event.message) || event.message.id !== id)
|
|
16772
|
+
return;
|
|
16773
|
+
done();
|
|
16774
|
+
if (event.message.error) reject(new Error("Configured voice gateway request failed"));
|
|
16775
|
+
else resolve(event.message.result);
|
|
16776
|
+
});
|
|
16777
|
+
try {
|
|
16778
|
+
bridge.dispatchMessage("mcp-request", {
|
|
16779
|
+
hostId: "local",
|
|
16780
|
+
request: { id, method: REALTIME_CALL_METHOD, params }
|
|
16781
|
+
});
|
|
16782
|
+
} catch {
|
|
16783
|
+
done();
|
|
16784
|
+
reject(new Error("Voice gateway Host connection is unavailable"));
|
|
16785
|
+
}
|
|
16786
|
+
});
|
|
16787
|
+
}
|
|
16788
|
+
var HOME_COMPOSER_MODE_STORAGE_KEY = "home-composer-mode-v1";
|
|
16789
|
+
function backendModelName(headers) {
|
|
16790
|
+
const raw = new Headers(headers).get("x-codex-turn-metadata");
|
|
16791
|
+
if (!raw) return "";
|
|
16792
|
+
try {
|
|
16793
|
+
const parsed = JSON.parse(raw);
|
|
16794
|
+
return typeof parsed.backend_model_name === "string" ? parsed.backend_model_name : "";
|
|
16795
|
+
} catch {
|
|
16796
|
+
return "";
|
|
16797
|
+
}
|
|
16798
|
+
}
|
|
16799
|
+
function isWorkBackendModel(name) {
|
|
16800
|
+
const model2 = name.toLowerCase();
|
|
16801
|
+
if (!model2) return false;
|
|
16802
|
+
if (model2.startsWith("codexhost/")) return true;
|
|
16803
|
+
return model2.includes("codex") && !model2.includes("gpt-live");
|
|
16804
|
+
}
|
|
16805
|
+
function isWorkComposerSurface(owner = globalThis) {
|
|
16806
|
+
const storage = owner.localStorage;
|
|
16807
|
+
if (!storage) return false;
|
|
16808
|
+
try {
|
|
16809
|
+
const raw = storage.getItem(HOME_COMPOSER_MODE_STORAGE_KEY);
|
|
16810
|
+
if (raw == null || raw === "") return false;
|
|
16811
|
+
let value = raw;
|
|
16812
|
+
if (raw.startsWith("{") || raw.startsWith('"') || raw.startsWith("[")) {
|
|
16813
|
+
try {
|
|
16814
|
+
value = JSON.parse(raw);
|
|
16815
|
+
} catch {
|
|
16816
|
+
value = raw;
|
|
16817
|
+
}
|
|
16818
|
+
}
|
|
16819
|
+
return value === "work";
|
|
16820
|
+
} catch {
|
|
16821
|
+
return false;
|
|
16822
|
+
}
|
|
16823
|
+
}
|
|
16824
|
+
function selectedComposerModel(owner) {
|
|
16825
|
+
const routing = owner.__codexhostHostRoutingV1;
|
|
16826
|
+
try {
|
|
16827
|
+
const model2 = routing?.forComposer()?.policy.selectedModel();
|
|
16828
|
+
return typeof model2 === "string" ? model2 : "";
|
|
16829
|
+
} catch {
|
|
16830
|
+
return "";
|
|
16831
|
+
}
|
|
16832
|
+
}
|
|
16833
|
+
var lastVoiceProductExperience;
|
|
16834
|
+
function rememberVoiceProductExperience(request) {
|
|
16835
|
+
const experience = object2(request) ? request.productExperience : void 0;
|
|
16836
|
+
lastVoiceProductExperience = experience === "chat" || experience === "work" ? experience : void 0;
|
|
16837
|
+
}
|
|
16838
|
+
function lastVoiceLaunchProductExperience() {
|
|
16839
|
+
return lastVoiceProductExperience;
|
|
16840
|
+
}
|
|
16841
|
+
function isExternalHarnessComposer(owner = globalThis) {
|
|
16842
|
+
if (lastVoiceProductExperience === "chat") return false;
|
|
16843
|
+
if (selectedComposerModel(owner).startsWith("codexhost/")) return true;
|
|
16844
|
+
if (lastVoiceProductExperience !== "work") return false;
|
|
16845
|
+
const storage = owner.localStorage;
|
|
16846
|
+
if (!storage) return false;
|
|
16847
|
+
try {
|
|
16848
|
+
const parsed = JSON.parse(storage.getItem(RENDERER_NEW_THREAD_PREFERENCE_KEY) ?? "");
|
|
16849
|
+
return typeof parsed.lastAgent === "string" && parsed.lastAgent !== "" && parsed.lastAgent !== "codex";
|
|
16850
|
+
} catch {
|
|
16851
|
+
return false;
|
|
16852
|
+
}
|
|
16853
|
+
}
|
|
16854
|
+
function wrapClientOwnedVoiceFetch(client, bridge, workOverride, responseError, chatOverride = () => false, workSurface = () => isWorkComposerSurface(), externalHarness = () => isExternalHarnessComposer()) {
|
|
16855
|
+
const original = client.fetch;
|
|
16856
|
+
const wrapped = async function(url2, options) {
|
|
16857
|
+
if (typeof url2 !== "string" || url2.split("?")[0] !== "/wham/realtime/calls" || options?.method !== "POST")
|
|
16858
|
+
return original.call(this, url2, options);
|
|
16859
|
+
const chat = lastVoiceLaunchProductExperience() === "chat";
|
|
16860
|
+
const model2 = backendModelName(options.headers);
|
|
16861
|
+
const work = !chat && (isWorkBackendModel(model2) || workSurface());
|
|
16862
|
+
const external = !chat && (model2.startsWith("codexhost/") || externalHarness());
|
|
16863
|
+
const gateway = external || (work ? workOverride() : chatOverride());
|
|
16864
|
+
chatVoiceDebug("wham-create", {
|
|
16865
|
+
work,
|
|
16866
|
+
external,
|
|
16867
|
+
route: gateway ? "gateway" : "desktop",
|
|
16868
|
+
productExperience: lastVoiceLaunchProductExperience() ?? "unset"
|
|
16869
|
+
});
|
|
16870
|
+
if (!gateway) {
|
|
16871
|
+
if (!external && !work)
|
|
16872
|
+
chatVoiceDebug("chat-native-passthrough", {
|
|
16873
|
+
hasThreadId: new Headers(options.headers).has("Thread-Id")
|
|
16874
|
+
});
|
|
16875
|
+
return original.call(this, url2, options);
|
|
16876
|
+
}
|
|
16877
|
+
if (typeof options.body !== "string") throw new Error("Unsupported native voice call request");
|
|
16878
|
+
options.signal?.throwIfAborted();
|
|
16879
|
+
const requestId2 = crypto.randomUUID();
|
|
16880
|
+
let cancelled = false;
|
|
16881
|
+
const cancel = () => {
|
|
16882
|
+
if (cancelled) return;
|
|
16883
|
+
cancelled = true;
|
|
16884
|
+
void requestHost(bridge, { operation: "cancel", requestId: requestId2 }).catch(() => void 0);
|
|
16885
|
+
};
|
|
16886
|
+
options.signal?.addEventListener("abort", cancel, { once: true });
|
|
16887
|
+
try {
|
|
16888
|
+
const result = realtimeCallResponseSchema.parse(
|
|
16889
|
+
await requestHost(bridge, {
|
|
16890
|
+
operation: "create",
|
|
16891
|
+
requestId: requestId2,
|
|
16892
|
+
body: options.body,
|
|
16893
|
+
// Drop Desktop OAuth, ChatGPT account identity and cookies at the bridge
|
|
16894
|
+
// boundary; the Host allowlist repeats this check before sending.
|
|
16895
|
+
headers: filterRealtimeCallHeaders(Object.fromEntries(new Headers(options.headers)))
|
|
16896
|
+
})
|
|
16897
|
+
);
|
|
16898
|
+
if (options.signal?.aborted) {
|
|
16899
|
+
const callId = realtimeCallIdFromLocation(result.headers.location ?? "");
|
|
16900
|
+
if (result.status >= 200 && result.status < 300 && isRealtimeCallId(callId))
|
|
16901
|
+
await requestHost(bridge, { operation: "hangup", callId });
|
|
16902
|
+
options.signal.throwIfAborted();
|
|
16903
|
+
}
|
|
16904
|
+
const response = new Response(result.status === 204 ? null : result.body, {
|
|
16905
|
+
status: result.status,
|
|
16906
|
+
headers: result.headers
|
|
16907
|
+
});
|
|
16908
|
+
if (!response.ok) throw await responseError(response, url2);
|
|
16909
|
+
return response;
|
|
16910
|
+
} catch (error51) {
|
|
16911
|
+
cancel();
|
|
16912
|
+
throw error51;
|
|
16913
|
+
} finally {
|
|
16914
|
+
options.signal?.removeEventListener("abort", cancel);
|
|
16915
|
+
}
|
|
16916
|
+
};
|
|
16917
|
+
client.fetch = wrapped;
|
|
16918
|
+
return () => {
|
|
16919
|
+
if (client.fetch === wrapped) client.fetch = original;
|
|
16920
|
+
};
|
|
16921
|
+
}
|
|
16922
|
+
function installClientOwnedVoiceHook(options = {}) {
|
|
16923
|
+
const target = options.target ?? globalThis;
|
|
16924
|
+
const existing = target[HOOK_GLOBAL];
|
|
16925
|
+
if (existing) return existing;
|
|
16926
|
+
const config2 = readCpaLiveVoiceHookConfig(target);
|
|
16927
|
+
if (!config2) return { status: "disabled", dispose() {
|
|
16928
|
+
} };
|
|
16929
|
+
if (config2.desktopVersion !== void 0 && config2.desktopVersion !== CLIENT_OWNED_VOICE_VERSION)
|
|
16930
|
+
return { status: "unsupported", dispose() {
|
|
16931
|
+
} };
|
|
16932
|
+
const importModule = options.importModule ?? ((url2) => import(url2));
|
|
16933
|
+
let disposed = false;
|
|
16934
|
+
let timer;
|
|
16935
|
+
let restore;
|
|
16936
|
+
const started = Date.now();
|
|
16937
|
+
const handle = {
|
|
16938
|
+
status: "pending",
|
|
16939
|
+
dispose() {
|
|
16940
|
+
disposed = true;
|
|
16941
|
+
if (timer !== void 0) target.clearTimeout(timer);
|
|
16942
|
+
restore?.();
|
|
16943
|
+
if (target[HOOK_GLOBAL] === handle) Reflect.deleteProperty(target, HOOK_GLOBAL);
|
|
16944
|
+
}
|
|
16945
|
+
};
|
|
16946
|
+
target[HOOK_GLOBAL] = handle;
|
|
16947
|
+
const attempt = async () => {
|
|
16948
|
+
if (disposed) return;
|
|
16949
|
+
const names = loadedAssetNames(target.document, target.performance);
|
|
16950
|
+
if (auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_INITIAL_ASSET) && auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_SHARED_ASSET)) {
|
|
16951
|
+
try {
|
|
16952
|
+
const module = await importModule(`app://-/assets/${CLIENT_OWNED_VOICE_SHARED_ASSET}`);
|
|
16953
|
+
if (disposed) return;
|
|
16954
|
+
if (typeof module.frt !== "function") throw new Error();
|
|
16955
|
+
module.frt();
|
|
16956
|
+
const fetchClass = module.urt;
|
|
16957
|
+
const bridgeClass = module.mPt;
|
|
16958
|
+
if (!object2(fetchClass) && typeof fetchClass !== "function") throw new Error();
|
|
16959
|
+
if (!object2(bridgeClass) && typeof bridgeClass !== "function") throw new Error();
|
|
16960
|
+
const client = Reflect.get(fetchClass, "getInstance").call(fetchClass);
|
|
16961
|
+
const bridge = Reflect.get(bridgeClass, "getInstance").call(bridgeClass);
|
|
16962
|
+
if (typeof client?.fetch !== "function" || typeof bridge?.dispatchMessage !== "function" || typeof bridge?.subscribe !== "function" || typeof module.grt !== "function")
|
|
16963
|
+
throw new Error();
|
|
16964
|
+
restore = wrapClientOwnedVoiceFetch(
|
|
16965
|
+
client,
|
|
16966
|
+
bridge,
|
|
16967
|
+
() => cpaLiveVoicePreferenceAllowsInstall(target),
|
|
16968
|
+
module.grt,
|
|
16969
|
+
() => chatLiveVoicePreferenceAllowsOverride(target),
|
|
16970
|
+
() => isWorkComposerSurface(target),
|
|
16971
|
+
() => isExternalHarnessComposer(target)
|
|
16972
|
+
);
|
|
16973
|
+
handle.status = "active";
|
|
16974
|
+
} catch {
|
|
16975
|
+
handle.status = "unsupported";
|
|
16976
|
+
}
|
|
16977
|
+
return;
|
|
16978
|
+
}
|
|
16979
|
+
if (Date.now() - started >= 6e4) {
|
|
16980
|
+
handle.status = "unsupported";
|
|
16981
|
+
return;
|
|
16982
|
+
}
|
|
16983
|
+
timer = target.setTimeout(() => void attempt(), 250);
|
|
16984
|
+
};
|
|
16985
|
+
void attempt();
|
|
16986
|
+
return handle;
|
|
16987
|
+
}
|
|
16988
|
+
|
|
16989
|
+
// src/renderer-native-chat-voice-state.ts
|
|
16990
|
+
function observeNativeChatVoiceState(scope, initial) {
|
|
16991
|
+
const store = Reflect.apply(initial.ejn, void 0, [
|
|
16992
|
+
scope
|
|
16993
|
+
]);
|
|
16994
|
+
let last = "";
|
|
16995
|
+
const report = () => {
|
|
16996
|
+
const state = store.getState();
|
|
16997
|
+
const connection = state.server?.connectionState;
|
|
16998
|
+
const microphone = initial.sUn == null ? void 0 : scope.get(initial.sUn);
|
|
16999
|
+
const detail = {
|
|
17000
|
+
active: state.isVoiceModeActive === true,
|
|
17001
|
+
connectedOnce: state.hasConnectedOnce === true,
|
|
17002
|
+
sessionStarted: state.hasVoiceSessionStarted === true,
|
|
17003
|
+
serverConversationReady: typeof state.earlyServerThreadId === "string" && /^[a-f\d]{8}(?:-[a-f\d]{4}){3}-[a-f\d]{12}$/i.test(state.earlyServerThreadId),
|
|
17004
|
+
connection: typeof connection === "string" && ["disconnected", "connecting", "connected", "reconnecting", "signalReconnecting"].includes(
|
|
17005
|
+
connection
|
|
17006
|
+
) ? connection : "unknown",
|
|
17007
|
+
microphone: typeof microphone === "string" && ["unknown", "pending", "granted", "denied"].includes(microphone) ? microphone : "unknown"
|
|
17008
|
+
};
|
|
17009
|
+
const next = JSON.stringify(detail);
|
|
17010
|
+
if (next === last) return;
|
|
17011
|
+
last = next;
|
|
17012
|
+
chatVoiceDebug("native-chat-state", detail);
|
|
17013
|
+
};
|
|
17014
|
+
const unsubscribe = store.subscribe(report);
|
|
17015
|
+
report();
|
|
17016
|
+
return unsubscribe;
|
|
17017
|
+
}
|
|
17018
|
+
|
|
17019
|
+
// src/renderer-native-chat-voice-selection.ts
|
|
17020
|
+
var UUID = /^[a-f\d]{8}(?:-[a-f\d]{4}){3}-[a-f\d]{12}$/i;
|
|
17021
|
+
function nativeChatVoiceDraftSelection(binding, initial, shared, origin, signal) {
|
|
17022
|
+
const draft = binding.props.conversationId;
|
|
17023
|
+
const navigate = initial.uIr;
|
|
17024
|
+
const conversationPath = shared.xat;
|
|
17025
|
+
if (binding.backendConversationId !== void 0 || !draft.startsWith("local-chatgpt:") || !UUID.test(draft.slice("local-chatgpt:".length)) || origin == null || initial.FFr == null || initial.kZn == null || initial.SZn == null || typeof navigate !== "function" || typeof conversationPath !== "function")
|
|
17026
|
+
return () => {
|
|
17027
|
+
};
|
|
17028
|
+
const store = Reflect.apply(initial.ejn, void 0, [
|
|
17029
|
+
binding.scope
|
|
17030
|
+
]);
|
|
17031
|
+
let session = store.getState().voiceSessionId;
|
|
17032
|
+
let activeSeen = store.getState().isVoiceModeActive;
|
|
17033
|
+
let finished = false;
|
|
17034
|
+
return () => {
|
|
17035
|
+
if (finished) return;
|
|
17036
|
+
try {
|
|
17037
|
+
const state = store.getState();
|
|
17038
|
+
if (signal.aborted || binding.scope.get(initial.FFr) !== origin || activeSeen && (!state.isVoiceModeActive || state.voiceSessionId !== session)) {
|
|
17039
|
+
finished = true;
|
|
17040
|
+
return;
|
|
17041
|
+
}
|
|
17042
|
+
if (!state.isVoiceModeActive) return;
|
|
17043
|
+
if (!activeSeen) {
|
|
17044
|
+
session = state.voiceSessionId;
|
|
17045
|
+
activeSeen = true;
|
|
17046
|
+
}
|
|
17047
|
+
if (state.isWorkMode !== false || state.conversationId !== draft) {
|
|
17048
|
+
finished = true;
|
|
17049
|
+
return;
|
|
17050
|
+
}
|
|
17051
|
+
if (!state.hasVoiceSessionStarted || state.server.connectionState !== "connected") return;
|
|
17052
|
+
const backend = binding.scope.get(initial.pZn, draft);
|
|
17053
|
+
if (typeof backend !== "string" || !UUID.test(backend)) return;
|
|
17054
|
+
const mapping = binding.scope.get(initial.kZn, draft);
|
|
17055
|
+
const currentNode = binding.scope.get(initial.SZn, draft);
|
|
17056
|
+
if (mapping == null || typeof mapping !== "object" || typeof currentNode !== "string" || !mapping[currentNode]?.message)
|
|
17057
|
+
return;
|
|
17058
|
+
finished = true;
|
|
17059
|
+
const path = Reflect.apply(conversationPath, void 0, [draft]);
|
|
17060
|
+
const accepted = Reflect.apply(navigate, void 0, [binding.scope, path]);
|
|
17061
|
+
void Promise.resolve(accepted).then(
|
|
17062
|
+
(result) => chatVoiceDebug(
|
|
17063
|
+
result === false ? "native-chat-selection-declined" : "native-chat-draft-selection-requested"
|
|
17064
|
+
),
|
|
17065
|
+
() => chatVoiceDebug("native-chat-selection-failed")
|
|
17066
|
+
);
|
|
17067
|
+
} catch {
|
|
17068
|
+
finished = true;
|
|
17069
|
+
chatVoiceDebug("native-chat-selection-failed");
|
|
17070
|
+
}
|
|
17071
|
+
};
|
|
17072
|
+
}
|
|
17073
|
+
|
|
17074
|
+
// src/renderer-native-chat-voice.ts
|
|
17075
|
+
var HOOK_GLOBAL2 = "__codexhostNativeChatVoiceV1";
|
|
17076
|
+
var START_ASSET = "start-voice-954090654801.js";
|
|
17077
|
+
var PREWARM_ASSET = "voice-prewarm-fb2c91219553.js";
|
|
17078
|
+
var BUTTON = "data-codexhost-chat-voice-start";
|
|
17079
|
+
var CONVERSATION_UUID = /^[a-f\d]{8}(?:-[a-f\d]{4}){3}-[a-f\d]{12}$/i;
|
|
17080
|
+
var record2 = (value) => value !== null && typeof value === "object";
|
|
17081
|
+
function scopeRefs(owner, definition) {
|
|
17082
|
+
const scopes = /* @__PURE__ */ new Map();
|
|
17083
|
+
let hook = owner.memoizedState;
|
|
17084
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17085
|
+
while (record2(hook) && seen.size < 4096 && !seen.has(hook)) {
|
|
17086
|
+
seen.add(hook);
|
|
17087
|
+
const state = hook.memoizedState;
|
|
17088
|
+
const scope = record2(state) ? state.current : void 0;
|
|
17089
|
+
if (record2(scope) && scope.scope === definition && typeof scope.get === "function" && typeof scope.set === "function" && scope.chain instanceof Map && scope.chain.get(definition.id) === scope.node)
|
|
17090
|
+
scopes.set(scope.node, scope);
|
|
17091
|
+
hook = hook.next;
|
|
17092
|
+
}
|
|
17093
|
+
return hook == null ? scopes : /* @__PURE__ */ new Map();
|
|
17094
|
+
}
|
|
17095
|
+
function detectNativeChatVoiceBinding(composer, native) {
|
|
17096
|
+
const key = Object.getOwnPropertyNames(composer).find((key2) => key2.startsWith("__reactFiber$"));
|
|
17097
|
+
if (!key) return;
|
|
17098
|
+
const ancestors = committedReactAncestors(Object.getOwnPropertyDescriptor(composer, key)?.value);
|
|
17099
|
+
for (const owner of ancestors) {
|
|
17100
|
+
const props = owner.memoizedProps;
|
|
17101
|
+
if (!record2(props) || typeof props.isWorkConversation !== "boolean" || typeof props.isTemporaryChat !== "boolean" || typeof props.conversationId !== "string")
|
|
17102
|
+
continue;
|
|
17103
|
+
if (props.isWorkConversation || props.isTemporaryChat || props.shouldBlockExternalEgress !== false || props.readOnly === true || !record2(props.composerSelectionContext) || props.composerSelectionContext.conversationId !== props.conversationId)
|
|
17104
|
+
return;
|
|
17105
|
+
const scopes = scopeRefs(owner, native.scopeDefinition);
|
|
17106
|
+
if (scopes.size !== 1) return;
|
|
17107
|
+
const scope = [...scopes.values()][0];
|
|
17108
|
+
if (!scope) return;
|
|
17109
|
+
const backendId = scope.get(native.backendConversationId, props.conversationId);
|
|
17110
|
+
const hasBackendId = typeof backendId === "string" && CONVERSATION_UUID.test(backendId);
|
|
17111
|
+
const isDraft = backendId == null && props.conversationId.startsWith("local-chatgpt:") && CONVERSATION_UUID.test(props.conversationId.slice("local-chatgpt:".length));
|
|
17112
|
+
if (!hasBackendId && !isDraft) return;
|
|
17113
|
+
const draftScopes = /* @__PURE__ */ new Map();
|
|
17114
|
+
if (isDraft) {
|
|
17115
|
+
for (const fiber of ancestors)
|
|
17116
|
+
for (const [node, ref] of scopeRefs(fiber, native.composerScopeDefinition))
|
|
17117
|
+
if (ref.chain.get(native.scopeDefinition.id) === scope.node) draftScopes.set(node, ref);
|
|
17118
|
+
}
|
|
17119
|
+
const contexts = /* @__PURE__ */ new Set();
|
|
17120
|
+
let composerContext;
|
|
17121
|
+
for (const fiber of ancestors) {
|
|
17122
|
+
let dependency = record2(fiber.dependencies) ? fiber.dependencies.firstContext : void 0;
|
|
17123
|
+
const seenDependencies = /* @__PURE__ */ new Set();
|
|
17124
|
+
while (record2(dependency) && seenDependencies.size < 4096 && !seenDependencies.has(dependency)) {
|
|
17125
|
+
seenDependencies.add(dependency);
|
|
17126
|
+
const context = dependency.context;
|
|
17127
|
+
const chain = dependency.memoizedValue;
|
|
17128
|
+
if (record2(context) && context.displayName === native.scopeDefinition.__scopeBrand && chain instanceof Map && chain.get(native.scopeDefinition.id) === scope.node)
|
|
17129
|
+
contexts.add(context);
|
|
17130
|
+
if (!composerContext && record2(context) && context.displayName === native.composerScopeDefinition.__scopeBrand && chain instanceof Map && chain.get(native.scopeDefinition.id) === scope.node) {
|
|
17131
|
+
const node = chain.get(native.composerScopeDefinition.id);
|
|
17132
|
+
if (record2(node) && record2(node.value) && (node.value.kind === "chatgpt" && record2(node.value.chatGptSelectionContext) && node.value.chatGptSelectionContext.conversationId === props.conversationId || isDraft && node.value.kind === "new" && native.draftConversationId != null && draftScopes.get(node)?.get(native.draftConversationId) === props.conversationId))
|
|
17133
|
+
composerContext = { context, chain };
|
|
17134
|
+
else return;
|
|
17135
|
+
}
|
|
17136
|
+
dependency = dependency.next;
|
|
17137
|
+
}
|
|
17138
|
+
}
|
|
17139
|
+
if (contexts.size !== 1 || !composerContext) return;
|
|
17140
|
+
return {
|
|
17141
|
+
composer,
|
|
17142
|
+
props,
|
|
17143
|
+
scope,
|
|
17144
|
+
context: [...contexts][0],
|
|
17145
|
+
composerContext,
|
|
17146
|
+
backendConversationId: hasBackendId ? backendId : void 0
|
|
17147
|
+
};
|
|
17148
|
+
}
|
|
17149
|
+
}
|
|
17150
|
+
function startNativeChatVoiceForRequest(request, target = globalThis) {
|
|
17151
|
+
if (!record2(request) || request.productExperience !== "chat" || !nativeChatVoicePreferenceAllowsStart(target))
|
|
17152
|
+
return;
|
|
17153
|
+
const hook = target[HOOK_GLOBAL2];
|
|
17154
|
+
if (!hook || hook.status === "disabled") return;
|
|
17155
|
+
return hook.start();
|
|
17156
|
+
}
|
|
17157
|
+
function installNativeChatVoiceHook(options = {}) {
|
|
17158
|
+
const target = options.target ?? globalThis;
|
|
17159
|
+
const existing = target[HOOK_GLOBAL2];
|
|
17160
|
+
if (existing) return existing;
|
|
17161
|
+
const config2 = readCpaLiveVoiceHookConfig(target);
|
|
17162
|
+
const unavailable = (status) => ({
|
|
17163
|
+
status,
|
|
17164
|
+
dispose() {
|
|
17165
|
+
},
|
|
17166
|
+
start: async () => {
|
|
17167
|
+
throw new Error("Native Chat voice is unavailable");
|
|
17168
|
+
}
|
|
17169
|
+
});
|
|
17170
|
+
if (!config2) return unavailable("disabled");
|
|
17171
|
+
if (config2.desktopVersion !== void 0 && config2.desktopVersion !== CLIENT_OWNED_VOICE_VERSION)
|
|
17172
|
+
return unavailable("unsupported");
|
|
17173
|
+
const doc = target.document;
|
|
17174
|
+
if (!doc) return unavailable("unsupported");
|
|
17175
|
+
const importModule = options.importModule ?? ((url2) => import(url2));
|
|
17176
|
+
let disposed = false;
|
|
17177
|
+
let timer;
|
|
17178
|
+
let modules;
|
|
17179
|
+
let boundScope;
|
|
17180
|
+
let mounted;
|
|
17181
|
+
let button2;
|
|
17182
|
+
const overlayButtons = /* @__PURE__ */ new Map();
|
|
17183
|
+
let controller;
|
|
17184
|
+
let starting = false;
|
|
17185
|
+
let selectDraft;
|
|
17186
|
+
let renderFailed = false;
|
|
17187
|
+
const started = Date.now();
|
|
17188
|
+
const removeButton = () => {
|
|
17189
|
+
button2?.remove();
|
|
17190
|
+
button2 = void 0;
|
|
17191
|
+
};
|
|
17192
|
+
const release = () => {
|
|
17193
|
+
selectDraft = void 0;
|
|
17194
|
+
controller?.abort();
|
|
17195
|
+
controller = void 0;
|
|
17196
|
+
removeButton();
|
|
17197
|
+
for (const [control, [display, priority]] of overlayButtons)
|
|
17198
|
+
if (control.style.getPropertyValue("display") === "none" && control.style.getPropertyPriority("display") === "important")
|
|
17199
|
+
control.style.setProperty("display", display, priority);
|
|
17200
|
+
overlayButtons.clear();
|
|
17201
|
+
mounted?.dispose();
|
|
17202
|
+
mounted = void 0;
|
|
17203
|
+
boundScope = void 0;
|
|
17204
|
+
};
|
|
17205
|
+
const findBinding = () => {
|
|
17206
|
+
if (!modules || !nativeChatVoicePreferenceAllowsStart(target)) return;
|
|
17207
|
+
const forms = [...doc.querySelectorAll("[data-chatgpt-composer]")].filter(
|
|
17208
|
+
(form2) => form2.getBoundingClientRect().width > 0 && !form2.closest("[hidden], [inert]")
|
|
17209
|
+
);
|
|
17210
|
+
if (forms.length !== 1) return;
|
|
17211
|
+
const form = forms[0];
|
|
17212
|
+
if (!form) return;
|
|
17213
|
+
return detectNativeChatVoiceBinding(form, {
|
|
17214
|
+
scopeDefinition: modules.shared.Cot,
|
|
17215
|
+
backendConversationId: modules.initial.pZn,
|
|
17216
|
+
draftConversationId: modules.initial.lXt,
|
|
17217
|
+
composerScopeDefinition: modules.initial.xAt.scope
|
|
17218
|
+
});
|
|
17219
|
+
};
|
|
17220
|
+
const handle = {
|
|
17221
|
+
get activeCall() {
|
|
17222
|
+
if (starting) return true;
|
|
17223
|
+
if (!boundScope || !modules || typeof modules.initial.ejn !== "function") return false;
|
|
17224
|
+
try {
|
|
17225
|
+
return modules.initial.ejn(boundScope).getState().isVoiceModeActive;
|
|
17226
|
+
} catch {
|
|
17227
|
+
return false;
|
|
17228
|
+
}
|
|
17229
|
+
},
|
|
17230
|
+
status: "pending",
|
|
17231
|
+
async start() {
|
|
17232
|
+
if (disposed || starting) return;
|
|
17233
|
+
const current = findBinding();
|
|
17234
|
+
if (!current || !modules || current.scope.node !== mounted?.node)
|
|
17235
|
+
throw new Error("Select a ChatGPT conversation to start Chat voice");
|
|
17236
|
+
starting = true;
|
|
17237
|
+
controller = new AbortController();
|
|
17238
|
+
const signal = controller.signal;
|
|
17239
|
+
let origin;
|
|
17240
|
+
try {
|
|
17241
|
+
if (modules.initial.FFr != null) origin = current.scope.get(modules.initial.FFr);
|
|
17242
|
+
} catch {
|
|
17243
|
+
chatVoiceDebug("native-chat-selection-failed");
|
|
17244
|
+
}
|
|
17245
|
+
selectDraft = void 0;
|
|
17246
|
+
chatVoiceDebug("native-chat-start", {
|
|
17247
|
+
hasConversationId: current.backendConversationId !== void 0
|
|
17248
|
+
});
|
|
17249
|
+
try {
|
|
17250
|
+
await Reflect.apply(modules.start.n, void 0, [
|
|
17251
|
+
current.scope,
|
|
17252
|
+
current.props,
|
|
17253
|
+
{ event_source: "composer" },
|
|
17254
|
+
signal
|
|
17255
|
+
]);
|
|
17256
|
+
chatVoiceDebug("native-chat-start-returned");
|
|
17257
|
+
try {
|
|
17258
|
+
selectDraft = nativeChatVoiceDraftSelection(
|
|
17259
|
+
current,
|
|
17260
|
+
modules.initial,
|
|
17261
|
+
modules.shared,
|
|
17262
|
+
origin,
|
|
17263
|
+
signal
|
|
17264
|
+
);
|
|
17265
|
+
selectDraft();
|
|
17266
|
+
} catch {
|
|
17267
|
+
chatVoiceDebug("native-chat-selection-failed");
|
|
17268
|
+
}
|
|
17269
|
+
} catch {
|
|
17270
|
+
chatVoiceDebug("native-chat-start-failed");
|
|
17271
|
+
throw new Error("Native Chat voice could not start");
|
|
17272
|
+
} finally {
|
|
17273
|
+
starting = false;
|
|
17274
|
+
}
|
|
17275
|
+
},
|
|
17276
|
+
dispose() {
|
|
17277
|
+
disposed = true;
|
|
17278
|
+
if (timer !== void 0) target.clearTimeout(timer);
|
|
17279
|
+
release();
|
|
17280
|
+
if (target[HOOK_GLOBAL2] === handle) Reflect.deleteProperty(target, HOOK_GLOBAL2);
|
|
17281
|
+
}
|
|
17282
|
+
};
|
|
17283
|
+
target[HOOK_GLOBAL2] = handle;
|
|
17284
|
+
const refresh = async () => {
|
|
17285
|
+
if (disposed) return;
|
|
17286
|
+
try {
|
|
17287
|
+
if (renderFailed) throw new Error();
|
|
17288
|
+
if (!modules) {
|
|
17289
|
+
const names = loadedAssetNames(doc, target.performance);
|
|
17290
|
+
if (!auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_INITIAL_ASSET) || !auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_SHARED_ASSET)) {
|
|
17291
|
+
if (Date.now() - started >= 6e4) {
|
|
17292
|
+
handle.status = "unsupported";
|
|
17293
|
+
return;
|
|
17294
|
+
}
|
|
17295
|
+
return;
|
|
17296
|
+
}
|
|
17297
|
+
const [shared, initial, start, prewarm] = await Promise.all(
|
|
17298
|
+
[
|
|
17299
|
+
CLIENT_OWNED_VOICE_SHARED_ASSET,
|
|
17300
|
+
CLIENT_OWNED_VOICE_INITIAL_ASSET,
|
|
17301
|
+
START_ASSET,
|
|
17302
|
+
PREWARM_ASSET
|
|
17303
|
+
].map((asset) => importModule(`app://-/assets/${asset}`))
|
|
17304
|
+
);
|
|
17305
|
+
if (disposed) return;
|
|
17306
|
+
if (!shared || !initial || !start || !prewarm || typeof start.t !== "function" || typeof start.n !== "function" || typeof initial.jw !== "function" || typeof initial.ejn !== "function" || typeof shared.yzt !== "function" || typeof shared.vMt !== "function" || typeof prewarm.VoiceInstantConnectCacheController !== "function")
|
|
17307
|
+
throw new Error();
|
|
17308
|
+
initial.jw();
|
|
17309
|
+
start.t();
|
|
17310
|
+
if (!record2(shared.Cot) || !initial.pZn || !initial.lXt || !initial.Aw || !record2(initial.xAt) || !record2(initial.xAt.scope))
|
|
17311
|
+
throw new Error();
|
|
17312
|
+
modules = { shared, initial, start, prewarm };
|
|
17313
|
+
}
|
|
17314
|
+
const current = findBinding();
|
|
17315
|
+
selectDraft?.();
|
|
17316
|
+
if (!current) {
|
|
17317
|
+
if (handle.activeCall) return;
|
|
17318
|
+
release();
|
|
17319
|
+
handle.status = "pending";
|
|
17320
|
+
return;
|
|
17321
|
+
}
|
|
17322
|
+
if (mounted && current.scope.node !== mounted.node) release();
|
|
17323
|
+
boundScope = current.scope;
|
|
17324
|
+
if (!mounted) {
|
|
17325
|
+
const { scope } = current;
|
|
17326
|
+
const initial = modules.initial;
|
|
17327
|
+
const previous = scope.get(initial.Aw);
|
|
17328
|
+
const container = doc.createElement("div");
|
|
17329
|
+
container.setAttribute("data-codexhost-chat-voice-prewarm", "");
|
|
17330
|
+
doc.body.append(container);
|
|
17331
|
+
const react = Reflect.apply(modules.shared.yzt, void 0, []);
|
|
17332
|
+
const reactDom = Reflect.apply(modules.shared.vMt, void 0, []);
|
|
17333
|
+
const root = reactDom.createRoot(container, {
|
|
17334
|
+
onUncaughtError() {
|
|
17335
|
+
renderFailed = true;
|
|
17336
|
+
}
|
|
17337
|
+
});
|
|
17338
|
+
const stopObserving = observeNativeChatVoiceState(scope, initial);
|
|
17339
|
+
let appChain;
|
|
17340
|
+
let composerChain;
|
|
17341
|
+
mounted = {
|
|
17342
|
+
node: scope.node,
|
|
17343
|
+
render(next) {
|
|
17344
|
+
if (appChain === next.scope.chain && composerChain === next.composerContext.chain)
|
|
17345
|
+
return;
|
|
17346
|
+
appChain = next.scope.chain;
|
|
17347
|
+
composerChain = next.composerContext.chain;
|
|
17348
|
+
root.render(
|
|
17349
|
+
react.createElement(
|
|
17350
|
+
next.context,
|
|
17351
|
+
{ value: appChain },
|
|
17352
|
+
react.createElement(
|
|
17353
|
+
next.composerContext.context,
|
|
17354
|
+
{ value: composerChain },
|
|
17355
|
+
react.createElement(modules?.prewarm.VoiceInstantConnectCacheController, null)
|
|
17356
|
+
)
|
|
17357
|
+
)
|
|
17358
|
+
);
|
|
17359
|
+
},
|
|
17360
|
+
dispose() {
|
|
17361
|
+
stopObserving();
|
|
17362
|
+
root.unmount();
|
|
17363
|
+
container.remove();
|
|
17364
|
+
if (scope.get(initial.Aw) === true) scope.set(initial.Aw, previous);
|
|
17365
|
+
chatVoiceDebug("native-chat-unbound");
|
|
17366
|
+
}
|
|
17367
|
+
};
|
|
17368
|
+
scope.set(initial.Aw, true);
|
|
17369
|
+
chatVoiceDebug("native-chat-bound", {
|
|
17370
|
+
hasConversationId: current.backendConversationId !== void 0
|
|
17371
|
+
});
|
|
17372
|
+
}
|
|
17373
|
+
mounted.render(current);
|
|
17374
|
+
if (!button2 || !current.composer.contains(button2)) {
|
|
17375
|
+
removeButton();
|
|
17376
|
+
const dictate = current.composer.querySelector(
|
|
17377
|
+
'button[aria-label="Dictate"]'
|
|
17378
|
+
);
|
|
17379
|
+
if (dictate?.parentElement) {
|
|
17380
|
+
button2 = doc.createElement("button");
|
|
17381
|
+
button2.type = "button";
|
|
17382
|
+
button2.className = dictate.className;
|
|
17383
|
+
button2.setAttribute(BUTTON, "");
|
|
17384
|
+
button2.setAttribute("aria-label", "Start Voice");
|
|
17385
|
+
button2.title = "Start Voice";
|
|
17386
|
+
button2.innerHTML = '<svg width="20" height="20" viewBox="0 0 20 20" fill="none" aria-hidden="true"><path d="M3 8v4m4-7v10m6-12v14m4-9v4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
|
|
17387
|
+
button2.addEventListener("click", () => {
|
|
17388
|
+
void handle.start().catch(() => {
|
|
17389
|
+
if (button2) button2.title = "Chat voice could not start. Try again.";
|
|
17390
|
+
});
|
|
17391
|
+
});
|
|
17392
|
+
dictate.parentElement.append(button2);
|
|
17393
|
+
}
|
|
17394
|
+
}
|
|
17395
|
+
if (button2)
|
|
17396
|
+
for (const control of current.composer.querySelectorAll(
|
|
17397
|
+
'button[aria-label="Start new voice chat"], button[aria-label="Start voice chat"]'
|
|
17398
|
+
)) {
|
|
17399
|
+
if (!overlayButtons.has(control))
|
|
17400
|
+
overlayButtons.set(control, [
|
|
17401
|
+
control.style.getPropertyValue("display"),
|
|
17402
|
+
control.style.getPropertyPriority("display")
|
|
17403
|
+
]);
|
|
17404
|
+
control.style.setProperty("display", "none", "important");
|
|
17405
|
+
}
|
|
17406
|
+
if (button2)
|
|
17407
|
+
button2.disabled = starting || current.props.isStreaming === true || modules.initial.ejn instanceof Function && modules.initial.ejn(current.scope).getState().isVoiceModeActive;
|
|
17408
|
+
handle.status = "active";
|
|
17409
|
+
} catch {
|
|
17410
|
+
release();
|
|
17411
|
+
handle.status = "unsupported";
|
|
17412
|
+
chatVoiceDebug("native-chat-binding-failed");
|
|
17413
|
+
return;
|
|
17414
|
+
} finally {
|
|
17415
|
+
if (!disposed && handle.status !== "unsupported")
|
|
17416
|
+
timer = target.setTimeout(() => void refresh(), 500);
|
|
17417
|
+
}
|
|
17418
|
+
};
|
|
17419
|
+
void refresh();
|
|
17420
|
+
return handle;
|
|
17421
|
+
}
|
|
17422
|
+
|
|
17423
|
+
// src/voice-settings-sync.ts
|
|
17424
|
+
function desktopVoiceCallActive(owner) {
|
|
17425
|
+
const hook = Reflect.get(owner, "__codexhostNativeChatVoiceV1");
|
|
17426
|
+
if (hook?.activeCall) return true;
|
|
17427
|
+
return [
|
|
17428
|
+
...owner.document.querySelectorAll(
|
|
17429
|
+
'button[aria-label="End Voice"],button[aria-label="End voice"],button[aria-label="End voice chat"]'
|
|
17430
|
+
)
|
|
17431
|
+
].some((button2) => button2.getBoundingClientRect().width > 0);
|
|
17432
|
+
}
|
|
17433
|
+
function startVoiceSettingsSync(owner, request, intervalMs = 2e3) {
|
|
17434
|
+
let disposed = false;
|
|
17435
|
+
let busy = false;
|
|
17436
|
+
let revision = "";
|
|
17437
|
+
const id = crypto.randomUUID();
|
|
17438
|
+
const refresh = async () => {
|
|
17439
|
+
if (busy || disposed) return;
|
|
17440
|
+
busy = true;
|
|
17441
|
+
try {
|
|
17442
|
+
let state = voiceSettingsStateSchema.parse(
|
|
17443
|
+
await request(VOICE_SETTINGS_METHOD, {
|
|
17444
|
+
operation: "get",
|
|
17445
|
+
runtime: { id, revision, activeCall: desktopVoiceCallActive(owner) }
|
|
17446
|
+
})
|
|
17447
|
+
);
|
|
17448
|
+
if (disposed) return;
|
|
17449
|
+
if (!state.initialized)
|
|
17450
|
+
state = voiceSettingsStateSchema.parse(
|
|
17451
|
+
await request(VOICE_SETTINGS_METHOD, {
|
|
17452
|
+
operation: "migrate",
|
|
17453
|
+
routes: legacyVoiceRoutes(owner)
|
|
17454
|
+
})
|
|
17455
|
+
);
|
|
17456
|
+
if (!disposed && !desktopVoiceCallActive(owner)) {
|
|
17457
|
+
applySharedVoiceRoutes(owner, state.settings);
|
|
17458
|
+
revision = state.revision;
|
|
17459
|
+
}
|
|
17460
|
+
} catch {
|
|
17461
|
+
} finally {
|
|
17462
|
+
busy = false;
|
|
17463
|
+
}
|
|
17464
|
+
};
|
|
17465
|
+
void refresh();
|
|
17466
|
+
const timer = owner.setInterval(() => void refresh(), intervalMs);
|
|
17467
|
+
return () => {
|
|
17468
|
+
disposed = true;
|
|
17469
|
+
owner.clearInterval(timer);
|
|
17470
|
+
};
|
|
17471
|
+
}
|
|
17472
|
+
|
|
16404
17473
|
// src/codex-ssh-adapter.ts
|
|
16405
|
-
var
|
|
17474
|
+
var record3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16406
17475
|
function createCodexSshClient(ownerWindow) {
|
|
16407
17476
|
function request(operation, params, signal) {
|
|
16408
17477
|
const bridge = ownerWindow.electronBridge;
|
|
@@ -16410,7 +17479,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16410
17479
|
return Promise.reject(new Error("Codex SSH settings are unavailable in this window"));
|
|
16411
17480
|
if (signal?.aborted) return Promise.reject(new DOMException("Aborted", "AbortError"));
|
|
16412
17481
|
return new Promise((resolve, reject) => {
|
|
16413
|
-
const
|
|
17482
|
+
const requestId2 = ownerWindow.crypto.randomUUID();
|
|
16414
17483
|
const finish = (error51, value) => {
|
|
16415
17484
|
ownerWindow.clearTimeout(timer);
|
|
16416
17485
|
ownerWindow.removeEventListener("message", receive);
|
|
@@ -16421,7 +17490,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16421
17490
|
const abort = () => finish(new DOMException("Aborted", "AbortError"));
|
|
16422
17491
|
const receive = (event) => {
|
|
16423
17492
|
const message2 = event.data;
|
|
16424
|
-
if (!
|
|
17493
|
+
if (!record3(message2) || message2.type !== "fetch-response" || message2.requestId !== requestId2)
|
|
16425
17494
|
return;
|
|
16426
17495
|
if (message2.responseType !== "success" || typeof message2.status !== "number" || message2.status < 200 || message2.status >= 300 || typeof message2.bodyJsonString !== "string") {
|
|
16427
17496
|
finish(new Error("Codex SSH request failed; check the native Connections settings"));
|
|
@@ -16443,7 +17512,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16443
17512
|
Promise.resolve(
|
|
16444
17513
|
bridge.sendMessageFromView({
|
|
16445
17514
|
type: "fetch",
|
|
16446
|
-
requestId,
|
|
17515
|
+
requestId: requestId2,
|
|
16447
17516
|
method: "POST",
|
|
16448
17517
|
url: `vscode://codex/${operation}`,
|
|
16449
17518
|
body: JSON.stringify(params),
|
|
@@ -16457,12 +17526,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16457
17526
|
}
|
|
16458
17527
|
async function list(signal) {
|
|
16459
17528
|
const result = await request("refresh-remote-connections", {}, signal);
|
|
16460
|
-
if (!
|
|
17529
|
+
if (!record3(result) || !Array.isArray(result.remoteConnections))
|
|
16461
17530
|
throw new Error("Invalid Codex SSH connection list");
|
|
16462
17531
|
return result.remoteConnections.filter(
|
|
16463
|
-
(item) => !(
|
|
17532
|
+
(item) => !(record3(item) && ["wsl", "remote-control"].includes(String(item.source)))
|
|
16464
17533
|
).map((item) => {
|
|
16465
|
-
if (!
|
|
17534
|
+
if (!record3(item) || typeof item.hostId !== "string" || typeof item.displayName !== "string" || !["codex-managed", "discovered"].includes(String(item.source)) || typeof item.sshHost !== "string" || typeof item.autoConnect !== "boolean" || !(item.sshAlias == null || typeof item.sshAlias === "string") || !(item.identity == null || typeof item.identity === "string") || !(item.sshPort == null || Number.isInteger(item.sshPort) && Number(item.sshPort) > 0 && Number(item.sshPort) <= 65535)) {
|
|
16466
17535
|
throw new Error(
|
|
16467
17536
|
"This Codex version uses an unsupported SSH configuration; open native settings"
|
|
16468
17537
|
);
|
|
@@ -16534,11 +17603,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16534
17603
|
},
|
|
16535
17604
|
async state(hostId2, signal) {
|
|
16536
17605
|
const result = await request("app-server-connection-state", { hostId: hostId2 }, signal);
|
|
16537
|
-
if (!
|
|
17606
|
+
if (!record3(result) || typeof result.state !== "string")
|
|
16538
17607
|
throw new Error("Invalid Codex connection state");
|
|
16539
17608
|
return {
|
|
16540
17609
|
state: result.state,
|
|
16541
|
-
error: typeof result.error === "string" ? result.error :
|
|
17610
|
+
error: typeof result.error === "string" ? result.error : record3(result.error) && typeof result.error.message === "string" ? result.error.message : null
|
|
16542
17611
|
};
|
|
16543
17612
|
}
|
|
16544
17613
|
};
|
|
@@ -16616,87 +17685,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16616
17685
|
return control;
|
|
16617
17686
|
}
|
|
16618
17687
|
|
|
16619
|
-
// ../desktop-control/dist/renderer-react-ownership.js
|
|
16620
|
-
var REACT_FIBER_WALK_LIMIT_EVENT = "codexhost:react-fiber-walk-limit";
|
|
16621
|
-
function committedReactAncestors(value) {
|
|
16622
|
-
const MAX_VISITED_FIBERS = 2e5;
|
|
16623
|
-
const fiber = (value2) => typeof value2 === "object" && value2 !== null ? value2 : null;
|
|
16624
|
-
const exhausted = () => {
|
|
16625
|
-
const target = globalThis;
|
|
16626
|
-
if (typeof target.dispatchEvent === "function" && typeof CustomEvent === "function")
|
|
16627
|
-
target.dispatchEvent(new CustomEvent("codexhost:react-fiber-walk-limit", {
|
|
16628
|
-
detail: { limit: MAX_VISITED_FIBERS }
|
|
16629
|
-
}));
|
|
16630
|
-
return [];
|
|
16631
|
-
};
|
|
16632
|
-
const first = fiber(value);
|
|
16633
|
-
if (!first)
|
|
16634
|
-
return [];
|
|
16635
|
-
const previous = [];
|
|
16636
|
-
const seen = /* @__PURE__ */ new Set();
|
|
16637
|
-
for (let node = first; node; node = fiber(node.return)) {
|
|
16638
|
-
if (seen.has(node))
|
|
16639
|
-
return [];
|
|
16640
|
-
if (seen.size >= MAX_VISITED_FIBERS)
|
|
16641
|
-
return exhausted();
|
|
16642
|
-
seen.add(node);
|
|
16643
|
-
previous.push(node);
|
|
16644
|
-
}
|
|
16645
|
-
const rootState = fiber(previous.at(-1)?.stateNode);
|
|
16646
|
-
if (!rootState || !("current" in rootState))
|
|
16647
|
-
return previous;
|
|
16648
|
-
const current = fiber(rootState.current);
|
|
16649
|
-
if (!current)
|
|
16650
|
-
return [];
|
|
16651
|
-
const alternate = fiber(first.alternate);
|
|
16652
|
-
const path = [current];
|
|
16653
|
-
seen.clear();
|
|
16654
|
-
seen.add(current);
|
|
16655
|
-
for (let index = previous.length - 2; index >= 0; index -= 1) {
|
|
16656
|
-
const expected = previous[index];
|
|
16657
|
-
const expectedAlternate = fiber(expected?.alternate);
|
|
16658
|
-
let child = fiber(path.at(-1)?.child);
|
|
16659
|
-
let matched = false;
|
|
16660
|
-
while (child && !seen.has(child) && seen.size < MAX_VISITED_FIBERS) {
|
|
16661
|
-
seen.add(child);
|
|
16662
|
-
if (child === expected || child === expectedAlternate) {
|
|
16663
|
-
matched = true;
|
|
16664
|
-
break;
|
|
16665
|
-
}
|
|
16666
|
-
child = fiber(child.sibling);
|
|
16667
|
-
}
|
|
16668
|
-
if (!matched || !child)
|
|
16669
|
-
break;
|
|
16670
|
-
path.push(child);
|
|
16671
|
-
}
|
|
16672
|
-
if (path.length === previous.length && (path.at(-1) === first || path.at(-1) === alternate)) {
|
|
16673
|
-
return path.reverse();
|
|
16674
|
-
}
|
|
16675
|
-
const stack = [{ node: current, parent: null }];
|
|
16676
|
-
seen.clear();
|
|
16677
|
-
while (stack.length > 0 && seen.size < MAX_VISITED_FIBERS) {
|
|
16678
|
-
const entry = stack.pop();
|
|
16679
|
-
if (!entry)
|
|
16680
|
-
break;
|
|
16681
|
-
if (seen.has(entry.node))
|
|
16682
|
-
return [];
|
|
16683
|
-
seen.add(entry.node);
|
|
16684
|
-
if (entry.node === first || entry.node === alternate) {
|
|
16685
|
-
const ancestors = [];
|
|
16686
|
-
for (let cursor = entry; cursor; cursor = cursor.parent)
|
|
16687
|
-
ancestors.push(cursor.node);
|
|
16688
|
-
return ancestors;
|
|
16689
|
-
}
|
|
16690
|
-
const sibling = entry.parent && fiber(entry.node.sibling);
|
|
16691
|
-
if (sibling)
|
|
16692
|
-
stack.push({ node: sibling, parent: entry.parent });
|
|
16693
|
-
const child = fiber(entry.node.child);
|
|
16694
|
-
if (child)
|
|
16695
|
-
stack.push({ node: child, parent: entry });
|
|
16696
|
-
}
|
|
16697
|
-
return stack.length > 0 ? exhausted() : [];
|
|
16698
|
-
}
|
|
16699
|
-
|
|
16700
17688
|
// src/renderer-composer-kind.ts
|
|
16701
17689
|
function orbitComposerKind(composer) {
|
|
16702
17690
|
let element = composer.querySelector('[contenteditable="true"], textarea, [role="textbox"]') ?? composer;
|
|
@@ -18815,16 +19803,6 @@ ${error51.stderrTail}`] : []
|
|
|
18815
19803
|
"When this is on, that card is hidden on every Composer, including Codex threads. Reset usage and Upgrade stay available in Settings.",
|
|
18816
19804
|
"Turning this off only shows the native card again. Send on this Composer, including Codex threads, is already separated from that quota card."
|
|
18817
19805
|
]),
|
|
18818
|
-
cpaLiveVoiceTitle: "Override live voice",
|
|
18819
|
-
cpaLiveVoiceDescription: "On by default. Host creates the realtime call instead of ChatGPT.",
|
|
18820
|
-
cpaLiveVoiceHelpLabel: "About overriding live voice",
|
|
18821
|
-
cpaLiveVoiceHelp: Object.freeze([
|
|
18822
|
-
"Overrides Desktop's existing-call path on audited 26.1007.30912 so a local host can create the WebRTC call.",
|
|
18823
|
-
"This switch applies on the next voice session. No relaunch.",
|
|
18824
|
-
"Also set both keys in ~/.codex/config.toml and relaunch Codex: experimental_realtime_ws_base_url and experimental_realtime_webrtc_call_base_url, each pointing at your realtime host /v1.",
|
|
18825
|
-
"CODEXHOST_CPA_LIVE_VOICE=0 is not live. Relaunch Codex after changing that environment variable."
|
|
18826
|
-
]),
|
|
18827
|
-
cpaLiveVoiceRestartRequired: "This override is not injected. Unset CODEXHOST_CPA_LIVE_VOICE=0 and relaunch Codex. The switch cannot take effect until then.",
|
|
18828
19806
|
loadedSessions: {
|
|
18829
19807
|
title: "Loaded sessions",
|
|
18830
19808
|
description: "Local external Harnesses only. Refreshes every 10 seconds without waking sessions or resetting activity. Released sessions disappear from this list.",
|
|
@@ -19080,6 +20058,7 @@ ${error51.stderrTail}`] : []
|
|
|
19080
20058
|
connections: "Connections",
|
|
19081
20059
|
"remote-connections": "Remote connections",
|
|
19082
20060
|
appearance: "General",
|
|
20061
|
+
voice: "Voice",
|
|
19083
20062
|
accounts: "Accounts",
|
|
19084
20063
|
"session-import": "Session Import",
|
|
19085
20064
|
"usage-statistics": "Usage statistics",
|
|
@@ -19106,16 +20085,6 @@ ${error51.stderrTail}`] : []
|
|
|
19106
20085
|
"\u5F00\u542F\u540E\uFF0C\u6240\u6709 Composer \u90FD\u9690\u85CF\u8BE5\u5361\u7247\uFF0C\u5305\u62EC Codex \u4F1A\u8BDD\u3002\u300C\u91CD\u7F6E\u7528\u91CF\u300D\u548C\u300C\u5347\u7EA7\u300D\u4ECD\u53EF\u5728\u8BBE\u7F6E\u4E2D\u4F7F\u7528\u3002",
|
|
19107
20086
|
"\u5173\u95ED\u6B64\u5F00\u5173\u53EA\u4F1A\u91CD\u65B0\u663E\u793A\u539F\u751F\u5361\u7247\u3002\u5F53\u524D Composer \u7684\u53D1\u9001\uFF08\u5305\u62EC Codex \u4F1A\u8BDD\uFF09\u5DF2\u4E0E\u8BE5\u989D\u5EA6\u5361\u7247\u5206\u79BB\u3002"
|
|
19108
20087
|
]),
|
|
19109
|
-
cpaLiveVoiceTitle: "\u6539\u5199\u5B9E\u65F6\u8BED\u97F3",
|
|
19110
|
-
cpaLiveVoiceDescription: "\u9ED8\u8BA4\u5F00\u542F\u3002\u7531 Host \u521B\u5EFA realtime \u901A\u8BDD\uFF0C\u800C\u4E0D\u662F ChatGPT\u3002",
|
|
19111
|
-
cpaLiveVoiceHelpLabel: "\u6539\u5199\u5B9E\u65F6\u8BED\u97F3\u8BF4\u660E",
|
|
19112
|
-
cpaLiveVoiceHelp: Object.freeze([
|
|
19113
|
-
"\u5728\u5DF2\u5BA1\u8BA1\u7684 Desktop 26.1007.30912 \u4E0A\u8986\u76D6 existing-call \u8DEF\u5F84\uFF0C\u8BA9\u672C\u5730 Host \u521B\u5EFA WebRTC \u901A\u8BDD\u3002",
|
|
19114
|
-
"\u6B64\u5F00\u5173\u5728\u4E0B\u4E00\u6B21\u8BED\u97F3\u4F1A\u8BDD\u751F\u6548\uFF0C\u65E0\u9700\u91CD\u65B0\u542F\u52A8\u3002",
|
|
19115
|
-
"\u8FD8\u9700\u8981\u5728 ~/.codex/config.toml \u8BBE\u7F6E experimental_realtime_ws_base_url \u4E0E experimental_realtime_webrtc_call_base_url\uFF0C\u90FD\u6307\u5411\u4F60\u7684 realtime \u4E3B\u673A /v1\uFF0C\u7136\u540E\u91CD\u65B0\u542F\u52A8 Codex\u3002",
|
|
19116
|
-
"CODEXHOST_CPA_LIVE_VOICE=0 \u4E0D\u4F1A\u5373\u65F6\u751F\u6548\u3002\u4FEE\u6539\u8BE5\u73AF\u5883\u53D8\u91CF\u540E\u5FC5\u987B\u91CD\u65B0\u542F\u52A8 Codex\u3002"
|
|
19117
|
-
]),
|
|
19118
|
-
cpaLiveVoiceRestartRequired: "\u5F53\u524D\u672A\u6CE8\u5165\u6B64\u6539\u5199\u3002\u8BF7\u53D6\u6D88 CODEXHOST_CPA_LIVE_VOICE=0 \u5E76\u91CD\u65B0\u542F\u52A8 Codex\uFF0C\u672C\u5F00\u5173\u624D\u4F1A\u751F\u6548\u3002",
|
|
19119
20088
|
loadedSessions: {
|
|
19120
20089
|
title: "\u5DF2\u52A0\u8F7D\u4F1A\u8BDD",
|
|
19121
20090
|
description: "\u4EC5\u663E\u793A\u672C\u5730\u5916\u90E8 Harness\u3002\u6BCF 10 \u79D2\u5237\u65B0\uFF0C\u4E0D\u5524\u9192\u4F1A\u8BDD\u3001\u4E0D\u91CD\u7F6E\u6D3B\u52A8\u65F6\u95F4\u3002\u91CA\u653E\u540E\u7684\u4F1A\u8BDD\u4ECE\u5217\u8868\u79FB\u9664\u3002",
|
|
@@ -19371,6 +20340,7 @@ ${error51.stderrTail}`] : []
|
|
|
19371
20340
|
connections: "\u8FDE\u63A5",
|
|
19372
20341
|
"remote-connections": "\u8FDC\u7A0B\u8FDE\u63A5",
|
|
19373
20342
|
appearance: "\u901A\u7528",
|
|
20343
|
+
voice: "\u8BED\u97F3",
|
|
19374
20344
|
accounts: "\u8D26\u53F7",
|
|
19375
20345
|
"session-import": "\u4F1A\u8BDD\u5BFC\u5165",
|
|
19376
20346
|
"usage-statistics": "\u7528\u91CF\u7EDF\u8BA1",
|
|
@@ -22671,7 +23641,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22671
23641
|
const composer = element.closest(CODEX_COMPOSER_SELECTOR);
|
|
22672
23642
|
return composer && !isOrbitComposer(composer) ? composer : null;
|
|
22673
23643
|
}
|
|
22674
|
-
function
|
|
23644
|
+
function isRecord3(value) {
|
|
22675
23645
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22676
23646
|
}
|
|
22677
23647
|
function isNativeModelControlCandidate(element) {
|
|
@@ -22687,7 +23657,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22687
23657
|
let fiber = fiberName ? Object.getOwnPropertyDescriptor(element, fiberName)?.value : null;
|
|
22688
23658
|
for (let depth = 0; fiber && depth < 60; depth += 1) {
|
|
22689
23659
|
const props = fiber.memoizedProps;
|
|
22690
|
-
if (
|
|
23660
|
+
if (isRecord3(props) && typeof props.onSelectModel === "function" && typeof props.onSelectReasoningEffort === "function" && "reasoningEffort" in props && isRecord3(props.fallbackPowerSelection)) {
|
|
22691
23661
|
return true;
|
|
22692
23662
|
}
|
|
22693
23663
|
const parent = fiber.return;
|
|
@@ -22707,7 +23677,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22707
23677
|
let ownsComposerPermissionState = false;
|
|
22708
23678
|
for (let depth = 0; fiber && depth < 60; depth += 1) {
|
|
22709
23679
|
const props = fiber.memoizedProps;
|
|
22710
|
-
if (
|
|
23680
|
+
if (isRecord3(props)) {
|
|
22711
23681
|
if (props["data-composer-navigation-target"] === "permissions" && props["aria-haspopup"] === "menu") {
|
|
22712
23682
|
ownsTrigger = true;
|
|
22713
23683
|
}
|
|
@@ -23200,19 +24170,19 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23200
24170
|
|
|
23201
24171
|
// src/renderer-codex-usage-banner.ts
|
|
23202
24172
|
var MAX_FIBERS = 2e4;
|
|
23203
|
-
function
|
|
24173
|
+
function isRecord4(value) {
|
|
23204
24174
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23205
24175
|
}
|
|
23206
24176
|
function isUsageBanner(props) {
|
|
23207
|
-
return
|
|
24177
|
+
return isRecord4(props) && "banner" in props && "rateLimitStatus" in props && typeof props.sendBlocked === "boolean";
|
|
23208
24178
|
}
|
|
23209
24179
|
function isElement(value) {
|
|
23210
|
-
return
|
|
24180
|
+
return isRecord4(value) && typeof value.setAttribute === "function" && isRecord4(value.style);
|
|
23211
24181
|
}
|
|
23212
24182
|
function hostElements(fiber, budget) {
|
|
23213
24183
|
const result = [];
|
|
23214
24184
|
const visit = (node) => {
|
|
23215
|
-
for (let current = node;
|
|
24185
|
+
for (let current = node; isRecord4(current); current = current.sibling) {
|
|
23216
24186
|
if (budget.remaining-- <= 0) return;
|
|
23217
24187
|
const { stateNode } = current;
|
|
23218
24188
|
if (isElement(stateNode)) result.push(stateNode);
|
|
@@ -23223,13 +24193,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23223
24193
|
return result;
|
|
23224
24194
|
}
|
|
23225
24195
|
function findCodexUsageBannerElements(owner) {
|
|
23226
|
-
if (!
|
|
24196
|
+
if (!isRecord4(owner)) return [];
|
|
23227
24197
|
const budget = { remaining: MAX_FIBERS };
|
|
23228
24198
|
const found = [];
|
|
23229
24199
|
const stack = [owner.child];
|
|
23230
24200
|
while (stack.length > 0 && budget.remaining > 0) {
|
|
23231
24201
|
const node = stack.pop();
|
|
23232
|
-
if (!
|
|
24202
|
+
if (!isRecord4(node)) continue;
|
|
23233
24203
|
budget.remaining -= 1;
|
|
23234
24204
|
const fiber = node;
|
|
23235
24205
|
stack.push(fiber.sibling);
|
|
@@ -23274,13 +24244,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23274
24244
|
var MAX_HOOKS = 4096;
|
|
23275
24245
|
var MAX_DOM_DEPTH = 12;
|
|
23276
24246
|
var RETRY_DELAY_MS = 1e3;
|
|
23277
|
-
function
|
|
24247
|
+
function isRecord5(value) {
|
|
23278
24248
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23279
24249
|
}
|
|
23280
24250
|
function hooksOf(fiber) {
|
|
23281
24251
|
const result = [];
|
|
23282
|
-
let hook =
|
|
23283
|
-
while (
|
|
24252
|
+
let hook = isRecord5(fiber) ? fiber.memoizedState : null;
|
|
24253
|
+
while (isRecord5(hook) && result.length < MAX_HOOKS) {
|
|
23284
24254
|
result.push(hook);
|
|
23285
24255
|
hook = hook.next;
|
|
23286
24256
|
}
|
|
@@ -23298,7 +24268,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23298
24268
|
);
|
|
23299
24269
|
const scopes = [];
|
|
23300
24270
|
ancestors.forEach(({ memoizedProps: props }, index) => {
|
|
23301
|
-
if (
|
|
24271
|
+
if (isRecord5(props) && "onLocalSubmitStart" in props && typeof props.submitDisabled === "boolean") {
|
|
23302
24272
|
scopes.push({ owner: ancestors[index], fibers: ancestors.slice(0, index + 1) });
|
|
23303
24273
|
}
|
|
23304
24274
|
});
|
|
@@ -23324,11 +24294,11 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23324
24294
|
const [subscriber, dependencies] = memo;
|
|
23325
24295
|
if (dependencies.length !== 2) return null;
|
|
23326
24296
|
const signal = dependencies[0];
|
|
23327
|
-
const adapted = dependencies[1] === void 0 &&
|
|
24297
|
+
const adapted = dependencies[1] === void 0 && isRecord5(signal) && typeof signal.get === "function" && typeof signal.subscribe === "function";
|
|
23328
24298
|
const [store, atom] = adapted ? [signal.store, signal.atom] : dependencies;
|
|
23329
24299
|
const instance = hook.next?.queue;
|
|
23330
24300
|
const effect = hook.next?.next?.memoizedState;
|
|
23331
|
-
if (!
|
|
24301
|
+
if (!isRecord5(subscriber) || typeof subscriber.getSnapshot !== "function" || typeof subscriber.subscribe !== "function" || !isRecord5(store) || typeof store.get !== "function" || typeof store.sub !== "function" || !isRecord5(atom) || typeof atom.read !== "function" || "write" in atom || !isRecord5(instance) || typeof instance.value !== "boolean" || typeof instance.getSnapshot !== "function" || !isRecord5(effect) || typeof effect.create !== "function" || !Array.isArray(effect.deps) || effect.deps[0] !== subscriber.subscribe) {
|
|
23332
24302
|
return null;
|
|
23333
24303
|
}
|
|
23334
24304
|
return {
|
|
@@ -23370,10 +24340,10 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23370
24340
|
visiting.delete(dependency);
|
|
23371
24341
|
}
|
|
23372
24342
|
}
|
|
23373
|
-
if (!
|
|
24343
|
+
if (!isRecord5(value)) return value;
|
|
23374
24344
|
if (typeof value.hardBlocked === "boolean") return trace(value, "reserve");
|
|
23375
24345
|
if ("authMethod" in value) return trace(value, "auth");
|
|
23376
|
-
if (
|
|
24346
|
+
if (isRecord5(value.data) && isRecord5(value.data.rate_limit)) {
|
|
23377
24347
|
return {
|
|
23378
24348
|
...value,
|
|
23379
24349
|
data: { ...value.data, rate_limit: trace(value.data.rate_limit, "limit") }
|
|
@@ -23485,7 +24455,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23485
24455
|
}
|
|
23486
24456
|
function isBound(projections) {
|
|
23487
24457
|
return [...projections].every(({ fiber, subscriber, instance }) => {
|
|
23488
|
-
const alternate =
|
|
24458
|
+
const alternate = isRecord5(fiber.alternate) ? fiber.alternate : null;
|
|
23489
24459
|
return [fiber, alternate].some(
|
|
23490
24460
|
(candidate) => hooksOf(candidate).some(
|
|
23491
24461
|
(hook) => Array.isArray(hook.memoizedState) && hook.memoizedState[0] === subscriber && hook.next?.queue === instance
|
|
@@ -23665,13 +24635,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23665
24635
|
}
|
|
23666
24636
|
|
|
23667
24637
|
// src/renderer-native-thread.ts
|
|
23668
|
-
function
|
|
24638
|
+
function isRecord6(value) {
|
|
23669
24639
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23670
24640
|
}
|
|
23671
24641
|
async function verifyNativeCodexThread(sendRequest, threadId) {
|
|
23672
24642
|
const native = await sendRequest("thread/read", { threadId, includeTurns: false });
|
|
23673
|
-
const thread =
|
|
23674
|
-
if (!
|
|
24643
|
+
const thread = isRecord6(native) ? native.thread : null;
|
|
24644
|
+
if (!isRecord6(thread) || thread.id !== threadId || typeof thread.modelProvider !== "string" || !thread.modelProvider || thread.modelProvider === "codexhost" || typeof thread.cliVersion !== "string" || !thread.cliVersion || thread.cliVersion === "codexhost") {
|
|
23675
24645
|
throw new Error("Native Thread response cannot establish Codex ownership");
|
|
23676
24646
|
}
|
|
23677
24647
|
}
|
|
@@ -23750,15 +24720,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23750
24720
|
var CODEX_ACCOUNT_LIST_METHOD = "codexhost/account/list";
|
|
23751
24721
|
var CODEX_ACCOUNT_REFRESH_METHOD = "codexhost/account/refresh";
|
|
23752
24722
|
var CODEX_ACCOUNT_CHANGED_METHOD = "codexhost/account/changed";
|
|
23753
|
-
function
|
|
24723
|
+
function isRecord7(value) {
|
|
23754
24724
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23755
24725
|
}
|
|
23756
24726
|
function notifiedThreadId(notification) {
|
|
23757
|
-
if (!
|
|
24727
|
+
if (!isRecord7(notification) || !THREAD_USAGE_REFRESH_METHODS.includes(notification.method)) {
|
|
23758
24728
|
return null;
|
|
23759
24729
|
}
|
|
23760
24730
|
const params = notification.params;
|
|
23761
|
-
if (!
|
|
24731
|
+
if (!isRecord7(params)) return null;
|
|
23762
24732
|
const parsed = hostThreadIdSchema.safeParse(params.threadId);
|
|
23763
24733
|
return parsed.success ? parsed.data : null;
|
|
23764
24734
|
}
|
|
@@ -24076,7 +25046,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24076
25046
|
throw new Error("Renderer Account notification callback is unavailable");
|
|
24077
25047
|
}
|
|
24078
25048
|
return notifications.addNotificationCallback(CODEX_ACCOUNT_CHANGED_METHOD, (notification) => {
|
|
24079
|
-
if (!
|
|
25049
|
+
if (!isRecord7(notification) || notification.method !== CODEX_ACCOUNT_CHANGED_METHOD) return;
|
|
24080
25050
|
const state = codexAccountChangedSchema.safeParse(notification.params);
|
|
24081
25051
|
if (state.success) listener(state.data);
|
|
24082
25052
|
});
|
|
@@ -24085,16 +25055,16 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24085
25055
|
}
|
|
24086
25056
|
|
|
24087
25057
|
// src/renderer-external-queue.ts
|
|
24088
|
-
function
|
|
25058
|
+
function isRecord8(value) {
|
|
24089
25059
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
24090
25060
|
}
|
|
24091
25061
|
function installRendererExternalQueue(target) {
|
|
24092
|
-
if (!
|
|
25062
|
+
if (!isRecord8(target) || typeof target.getTurnCoordinator !== "function" || typeof target.getConversation !== "function") {
|
|
24093
25063
|
return null;
|
|
24094
25064
|
}
|
|
24095
25065
|
const coordinator = target.getTurnCoordinator();
|
|
24096
|
-
const queue =
|
|
24097
|
-
if (!
|
|
25066
|
+
const queue = isRecord8(coordinator) ? coordinator.serverQueue : null;
|
|
25067
|
+
if (!isRecord8(queue) || typeof queue.isEnabled !== "function") return null;
|
|
24098
25068
|
const descriptor = Object.getOwnPropertyDescriptor(queue, "isEnabled");
|
|
24099
25069
|
if (!descriptor?.writable) return null;
|
|
24100
25070
|
const original = queue.isEnabled;
|
|
@@ -24103,7 +25073,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24103
25073
|
const threadId = args[0];
|
|
24104
25074
|
if (typeof threadId === "string") {
|
|
24105
25075
|
const conversation = getConversation.call(target, threadId);
|
|
24106
|
-
if (
|
|
25076
|
+
if (isRecord8(conversation) && conversation.id === threadId && // Reserved transport marker from externalThreadValue, retained by
|
|
24107
25077
|
// Desktop in both newly created and hydrated conversation metadata.
|
|
24108
25078
|
conversation.modelProvider === "codexhost") {
|
|
24109
25079
|
return false;
|
|
@@ -24119,19 +25089,19 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24119
25089
|
|
|
24120
25090
|
// src/renderer-external-steering.ts
|
|
24121
25091
|
var THREAD_OWNERSHIP_LIST_METHOD2 = "codexhost/thread/ownership/list";
|
|
24122
|
-
function
|
|
25092
|
+
function isRecord9(value) {
|
|
24123
25093
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
24124
25094
|
}
|
|
24125
25095
|
function isManager(value) {
|
|
24126
|
-
return
|
|
25096
|
+
return isRecord9(value) && ["sendRequest", "steerTurn", "startTurn", "getTurnCoordinator"].every(
|
|
24127
25097
|
(key) => typeof value[key] === "function"
|
|
24128
25098
|
);
|
|
24129
25099
|
}
|
|
24130
25100
|
function submissionHost(manager) {
|
|
24131
25101
|
const coordinator = manager.getTurnCoordinator();
|
|
24132
|
-
const options =
|
|
24133
|
-
const host =
|
|
24134
|
-
if (!
|
|
25102
|
+
const options = isRecord9(coordinator) ? coordinator.options : null;
|
|
25103
|
+
const host = isRecord9(options) ? options.submissionHost : null;
|
|
25104
|
+
if (!isRecord9(host) || typeof host.getActiveTurnId !== "function" || typeof host.hasPendingTurnStart !== "function") {
|
|
24135
25105
|
throw new Error("Desktop turn submission binding is unavailable");
|
|
24136
25106
|
}
|
|
24137
25107
|
return {
|
|
@@ -24173,20 +25143,20 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24173
25143
|
var INTERRUPTED_QUEUE_REASON = "Interrupted before the steer was accepted.";
|
|
24174
25144
|
async function preserveQueuedFollowUps(manager, threadId) {
|
|
24175
25145
|
const coordinator = manager.getTurnCoordinator();
|
|
24176
|
-
if (!
|
|
25146
|
+
if (!isRecord9(coordinator) || typeof coordinator.loadMessages !== "function" || typeof coordinator.readMessages !== "function" || typeof coordinator.mutate !== "function") {
|
|
24177
25147
|
throw new Error("Desktop follow-up queue binding is unavailable");
|
|
24178
25148
|
}
|
|
24179
25149
|
await coordinator.loadMessages.call(coordinator, threadId);
|
|
24180
25150
|
const messages = coordinator.readMessages.call(coordinator, threadId);
|
|
24181
25151
|
if (!Array.isArray(messages)) throw new Error("Desktop follow-up queue is unavailable");
|
|
24182
25152
|
const alreadyPaused = new Set(
|
|
24183
|
-
messages.filter((message2) =>
|
|
25153
|
+
messages.filter((message2) => isRecord9(message2) && message2.pausedReason != null).map((message2) => message2.id)
|
|
24184
25154
|
);
|
|
24185
25155
|
return () => {
|
|
24186
25156
|
coordinator.mutate.call(coordinator, threadId, (current) => {
|
|
24187
25157
|
if (!Array.isArray(current)) return current;
|
|
24188
25158
|
return current.map((message2) => {
|
|
24189
|
-
if (!
|
|
25159
|
+
if (!isRecord9(message2) || alreadyPaused.has(message2.id) || message2.pausedReason !== INTERRUPTED_QUEUE_REASON)
|
|
24190
25160
|
return message2;
|
|
24191
25161
|
const resumed = { ...message2 };
|
|
24192
25162
|
delete resumed.pausedReason;
|
|
@@ -24207,9 +25177,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24207
25177
|
if ((method === "turn/start" || method === "turn/steer") && prepareTurnInput) {
|
|
24208
25178
|
params = prepareTurnInput(params);
|
|
24209
25179
|
}
|
|
24210
|
-
const messageId =
|
|
24211
|
-
const route = typeof messageId === "string" &&
|
|
24212
|
-
if (method !== "turn/start" || !
|
|
25180
|
+
const messageId = isRecord9(params) ? params.clientUserMessageId : null;
|
|
25181
|
+
const route = typeof messageId === "string" && isRecord9(params) ? routes.get(`${params.threadId}\0${messageId}`) : void 0;
|
|
25182
|
+
if (method !== "turn/start" || !isRecord9(params) || !route || route.threadId !== params.threadId) {
|
|
24213
25183
|
if (method === "turn/start" && sendTurnStart) {
|
|
24214
25184
|
return sendTurnStart(params, (input) => {
|
|
24215
25185
|
if (disposed) throw new Error("External submission binding was disposed");
|
|
@@ -24235,7 +25205,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24235
25205
|
options
|
|
24236
25206
|
)
|
|
24237
25207
|
).then((response) => {
|
|
24238
|
-
if (!
|
|
25208
|
+
if (!isRecord9(response) || typeof response.turnId !== "string" || !response.turnId) {
|
|
24239
25209
|
throw new Error("External steering returned no replacement Turn identity");
|
|
24240
25210
|
}
|
|
24241
25211
|
return {
|
|
@@ -24266,7 +25236,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24266
25236
|
] = args;
|
|
24267
25237
|
if (typeof threadId !== "string") return originalSteer.apply(manager, args);
|
|
24268
25238
|
const role = manager.getStreamRole?.(threadId);
|
|
24269
|
-
if (
|
|
25239
|
+
if (isRecord9(role) && role.role === "follower") return originalSteer.apply(manager, args);
|
|
24270
25240
|
let host = null;
|
|
24271
25241
|
let expectedTurnId;
|
|
24272
25242
|
try {
|
|
@@ -24295,15 +25265,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24295
25265
|
if (owner === "codex") return originalSteer.apply(manager, args);
|
|
24296
25266
|
if (!host) throw new Error("Desktop turn submission binding is unavailable");
|
|
24297
25267
|
const currentRole = manager.getStreamRole?.(threadId);
|
|
24298
|
-
if (
|
|
25268
|
+
if (isRecord9(currentRole) && currentRole.role === "follower")
|
|
24299
25269
|
return originalSteer.apply(manager, args);
|
|
24300
25270
|
if (!Array.isArray(input) || input.length === 0 || input.some(
|
|
24301
|
-
(item) => !
|
|
24302
|
-
) || !input.some((item) =>
|
|
25271
|
+
(item) => !isRecord9(item) || item.type !== "text" || typeof item.text !== "string"
|
|
25272
|
+
) || !input.some((item) => isRecord9(item) && typeof item.text === "string" && item.text.trim())) {
|
|
24303
25273
|
throw new Error("External steering requires non-empty text input");
|
|
24304
25274
|
}
|
|
24305
25275
|
if (toolOutput != null) throw new Error("External steering cannot replace a tool response");
|
|
24306
|
-
if (!
|
|
25276
|
+
if (!isRecord9(restoreMessage) || !isRecord9(restoreMessage.context)) {
|
|
24307
25277
|
throw new Error("Desktop steering message context is unavailable");
|
|
24308
25278
|
}
|
|
24309
25279
|
const messageId = typeof clientUserMessageId === "string" && clientUserMessageId ? clientUserMessageId : typeof restoreMessage.id === "string" && restoreMessage.id ? restoreMessage.id : crypto.randomUUID();
|
|
@@ -24351,7 +25321,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24351
25321
|
},
|
|
24352
25322
|
onMessageAdded
|
|
24353
25323
|
);
|
|
24354
|
-
if (!
|
|
25324
|
+
if (!isRecord9(response) || !isRecord9(response.turn) || typeof response.turn.id !== "string") {
|
|
24355
25325
|
throw new Error("Desktop returned no replacement Turn identity");
|
|
24356
25326
|
}
|
|
24357
25327
|
try {
|
|
@@ -24382,7 +25352,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24382
25352
|
}
|
|
24383
25353
|
|
|
24384
25354
|
// src/renderer-remote-attachments.ts
|
|
24385
|
-
function
|
|
25355
|
+
function isRecord10(value) {
|
|
24386
25356
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
24387
25357
|
}
|
|
24388
25358
|
var MAX_IMAGE_BYTES = 20 * 1024 * 1024;
|
|
@@ -24434,14 +25404,14 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24434
25404
|
function createRemoteAttachmentSender(target, hostId2, isCurrent) {
|
|
24435
25405
|
const prepared = /* @__PURE__ */ new WeakMap();
|
|
24436
25406
|
return (params, send) => {
|
|
24437
|
-
if (hostId2 === "local" || !
|
|
25407
|
+
if (hostId2 === "local" || !isRecord10(target) || !isRecord10(params) || typeof params.threadId !== "string" || !Array.isArray(params.input) || typeof target.getConversation !== "function")
|
|
24438
25408
|
return send(params);
|
|
24439
25409
|
const images = params.input.filter(
|
|
24440
|
-
(item) =>
|
|
25410
|
+
(item) => isRecord10(item) && (item.type === "image" || item.type === "localImage")
|
|
24441
25411
|
);
|
|
24442
25412
|
if (images.length === 0) return send(params);
|
|
24443
25413
|
const conversation = target.getConversation.call(target, params.threadId);
|
|
24444
|
-
if (!
|
|
25414
|
+
if (!isRecord10(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
|
|
24445
25415
|
return send(params);
|
|
24446
25416
|
const assertCurrent = () => {
|
|
24447
25417
|
if (!isCurrent()) throw new Error("Remote attachment connection is no longer available");
|
|
@@ -24454,7 +25424,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24454
25424
|
const cached2 = prepared.get(params);
|
|
24455
25425
|
if (cached2) return cached2.then(dispatch);
|
|
24456
25426
|
const input = params.input;
|
|
24457
|
-
const text = input.filter((item) =>
|
|
25427
|
+
const text = input.filter((item) => isRecord10(item) && item.type === "text").map((item) => isRecord10(item) && typeof item.text === "string" ? item.text : "").join("\n");
|
|
24458
25428
|
const existingPaths = nativeImagePaths(text);
|
|
24459
25429
|
const prepare = async () => {
|
|
24460
25430
|
if (existingPaths.length === images.length) return params;
|
|
@@ -24486,7 +25456,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24486
25456
|
contents: file2.contents,
|
|
24487
25457
|
label: `image-${index + 1}.${file2.extension}`
|
|
24488
25458
|
});
|
|
24489
|
-
if (!
|
|
25459
|
+
if (!isRecord10(saved) || !filePath(saved.path) || saved.fsPath !== saved.path) {
|
|
24490
25460
|
throw new Error("Desktop returned an invalid remote attachment path");
|
|
24491
25461
|
}
|
|
24492
25462
|
created.push(saved.path);
|
|
@@ -24537,9 +25507,9 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
24537
25507
|
}
|
|
24538
25508
|
|
|
24539
25509
|
// src/renderer-thread-reference-capability.ts
|
|
24540
|
-
var
|
|
25510
|
+
var record4 = (value) => typeof value === "object" && value !== null;
|
|
24541
25511
|
function restoreThreadReferenceCapability(client, manager, isCurrent) {
|
|
24542
|
-
if (!
|
|
25512
|
+
if (!record4(manager) || !record4(manager.storage)) return client;
|
|
24543
25513
|
const storage = manager.storage;
|
|
24544
25514
|
const read = storage.readValue;
|
|
24545
25515
|
const write = storage.writeValue;
|
|
@@ -24574,14 +25544,14 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
24574
25544
|
}
|
|
24575
25545
|
|
|
24576
25546
|
// src/renderer-thread-reference-context.ts
|
|
24577
|
-
var
|
|
25547
|
+
var record5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24578
25548
|
function createThreadReferenceContext(manager, hostId2, isCurrent) {
|
|
24579
25549
|
const prepared = /* @__PURE__ */ new WeakMap();
|
|
24580
25550
|
return (params) => {
|
|
24581
|
-
if (hostId2 === "local" || !
|
|
25551
|
+
if (hostId2 === "local" || !record5(manager) || typeof manager.getConversation !== "function" || !record5(params) || typeof params.threadId !== "string")
|
|
24582
25552
|
return params;
|
|
24583
25553
|
const conversation = manager.getConversation.call(manager, params.threadId);
|
|
24584
|
-
if (!
|
|
25554
|
+
if (!record5(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
|
|
24585
25555
|
return params;
|
|
24586
25556
|
if (!isCurrent()) throw new Error("Thread reference connection is no longer available");
|
|
24587
25557
|
const cached2 = prepared.get(params);
|
|
@@ -24593,11 +25563,11 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
24593
25563
|
}
|
|
24594
25564
|
|
|
24595
25565
|
// src/renderer-manual-compaction.ts
|
|
24596
|
-
function
|
|
25566
|
+
function isRecord11(value) {
|
|
24597
25567
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
24598
25568
|
}
|
|
24599
25569
|
function installRendererManualCompaction(target, hostId2, messages) {
|
|
24600
|
-
if (!messages || typeof messages.addEventListener !== "function" || typeof messages.removeEventListener !== "function" || !
|
|
25570
|
+
if (!messages || typeof messages.addEventListener !== "function" || typeof messages.removeEventListener !== "function" || !isRecord11(target) || typeof target.registerPendingManualContextCompaction !== "function" || typeof target.getConversation !== "function") {
|
|
24601
25571
|
return null;
|
|
24602
25572
|
}
|
|
24603
25573
|
const register = target.registerPendingManualContextCompaction;
|
|
@@ -24606,18 +25576,18 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
24606
25576
|
const listener = (event) => {
|
|
24607
25577
|
if (event.source != null && event.source !== messages) return;
|
|
24608
25578
|
const message2 = event.data;
|
|
24609
|
-
if (!
|
|
25579
|
+
if (!isRecord11(message2) || message2.type !== "mcp-notification" || message2.hostId !== hostId2 || message2.method !== THREAD_MANUAL_COMPACTION_STARTED_METHOD) {
|
|
24610
25580
|
return;
|
|
24611
25581
|
}
|
|
24612
25582
|
const params = threadManualCompactionStartedSchema.safeParse(message2.params);
|
|
24613
25583
|
if (!params.success) return;
|
|
24614
25584
|
const { threadId } = params.data;
|
|
24615
25585
|
const conversation = getConversation.call(target, threadId);
|
|
24616
|
-
if (!
|
|
25586
|
+
if (!isRecord11(conversation) || conversation.id !== threadId || conversation.modelProvider !== "codexhost") {
|
|
24617
25587
|
return;
|
|
24618
25588
|
}
|
|
24619
25589
|
const role = getStreamRole?.call(target, threadId);
|
|
24620
|
-
if (
|
|
25590
|
+
if (isRecord11(role) && role.role === "follower") return;
|
|
24621
25591
|
register.call(target, threadId);
|
|
24622
25592
|
};
|
|
24623
25593
|
messages.addEventListener("message", listener);
|
|
@@ -24832,7 +25802,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
24832
25802
|
var SIDEBAR_THREAD_HOST_ID_ATTRIBUTE = "data-app-action-sidebar-thread-host-id";
|
|
24833
25803
|
var SIDEBAR_AGENT_ICON_ATTRIBUTE = "data-codexhost-sidebar-agent-icon";
|
|
24834
25804
|
var OWNERSHIP_RETRY_DELAYS_MS = [100, 300, 800, 1500, 3e3];
|
|
24835
|
-
function
|
|
25805
|
+
function isRecord12(value) {
|
|
24836
25806
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24837
25807
|
}
|
|
24838
25808
|
function sidebarThreadAttributes(element) {
|
|
@@ -24859,19 +25829,19 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
24859
25829
|
const fiberName = fiberNames[0];
|
|
24860
25830
|
if (fiberNames.length !== 1 || !fiberName) return null;
|
|
24861
25831
|
const firstFiber2 = Object.getOwnPropertyDescriptor(element, fiberName)?.value;
|
|
24862
|
-
if (!
|
|
25832
|
+
if (!isRecord12(firstFiber2)) return null;
|
|
24863
25833
|
const candidates = /* @__PURE__ */ new Set();
|
|
24864
25834
|
let fiber = firstFiber2;
|
|
24865
25835
|
for (let depth = 0; fiber && depth < 12; depth += 1) {
|
|
24866
25836
|
const props = fiber.memoizedProps;
|
|
24867
|
-
if (
|
|
25837
|
+
if (isRecord12(props) && isRecord12(props.dataAttributes)) {
|
|
24868
25838
|
const dataAttributes = props.dataAttributes;
|
|
24869
25839
|
const threadId = hostThreadIdSchema.safeParse(props.conversationId);
|
|
24870
25840
|
if (threadId.success && dataAttributes[SIDEBAR_THREAD_ROW_ATTRIBUTE] === rowMarker && dataAttributes[SIDEBAR_THREAD_ID_ATTRIBUTE] === taskKey && dataAttributes[SIDEBAR_THREAD_HOST_ID_ATTRIBUTE] === hostId2) {
|
|
24871
25841
|
candidates.add(threadId.data);
|
|
24872
25842
|
}
|
|
24873
25843
|
}
|
|
24874
|
-
fiber =
|
|
25844
|
+
fiber = isRecord12(fiber.return) ? fiber.return : null;
|
|
24875
25845
|
}
|
|
24876
25846
|
return candidates.size === 1 ? candidates.values().next().value ?? null : null;
|
|
24877
25847
|
}
|
|
@@ -25281,7 +26251,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25281
26251
|
if (row) finish(row);
|
|
25282
26252
|
});
|
|
25283
26253
|
}
|
|
25284
|
-
function
|
|
26254
|
+
function isRecord13(value) {
|
|
25285
26255
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25286
26256
|
}
|
|
25287
26257
|
function firstFiber(element) {
|
|
@@ -25291,7 +26261,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25291
26261
|
const name = names[0];
|
|
25292
26262
|
if (names.length !== 1 || !name) return null;
|
|
25293
26263
|
const value = Object.getOwnPropertyDescriptor(element, name)?.value;
|
|
25294
|
-
return
|
|
26264
|
+
return isRecord13(value) ? value : null;
|
|
25295
26265
|
}
|
|
25296
26266
|
function directForkAncestors(first) {
|
|
25297
26267
|
const ancestors = [];
|
|
@@ -25301,7 +26271,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25301
26271
|
if (seen.has(fiber)) return [];
|
|
25302
26272
|
seen.add(fiber);
|
|
25303
26273
|
ancestors.push(fiber);
|
|
25304
|
-
fiber =
|
|
26274
|
+
fiber = isRecord13(fiber.return) ? fiber.return : null;
|
|
25305
26275
|
}
|
|
25306
26276
|
return ancestors;
|
|
25307
26277
|
}
|
|
@@ -25319,7 +26289,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25319
26289
|
let hasForkCallback = false;
|
|
25320
26290
|
for (const fiber of ancestors) {
|
|
25321
26291
|
const props = fiber.memoizedProps;
|
|
25322
|
-
if (!
|
|
26292
|
+
if (!isRecord13(props)) continue;
|
|
25323
26293
|
if (!hasForkCallback && typeof props.onFork !== "function" && ownsOtherCallback(fiber, props)) {
|
|
25324
26294
|
return null;
|
|
25325
26295
|
}
|
|
@@ -25351,7 +26321,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25351
26321
|
if (!threadId.success || !turnId.success) return null;
|
|
25352
26322
|
const fiber = firstFiber(button2);
|
|
25353
26323
|
const buttonProps = fiber?.memoizedProps;
|
|
25354
|
-
if (!fiber || !
|
|
26324
|
+
if (!fiber || !isRecord13(buttonProps) || !Object.hasOwn(buttonProps, "aria-busy")) return null;
|
|
25355
26325
|
return forkTargetFromAncestors(button2, threadId.data, turnId.data, directForkAncestors(fiber)) ?? forkTargetFromAncestors(button2, threadId.data, turnId.data, committedReactAncestors(fiber));
|
|
25356
26326
|
}
|
|
25357
26327
|
var BrowserRendererForkDom = class {
|
|
@@ -25441,7 +26411,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25441
26411
|
}
|
|
25442
26412
|
var DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS = 1e4;
|
|
25443
26413
|
var DRAFT_PREWARM_POLICY_POLL_INTERVAL_MS = 25;
|
|
25444
|
-
function
|
|
26414
|
+
function isRecord14(value) {
|
|
25445
26415
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25446
26416
|
}
|
|
25447
26417
|
function decodeOpenCodeTransportModelId(value) {
|
|
@@ -25606,7 +26576,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25606
26576
|
let fiber = findComposerFiber(composer);
|
|
25607
26577
|
for (let depth = 0; fiber && depth < 120; depth += 1) {
|
|
25608
26578
|
const props = fiber.memoizedProps;
|
|
25609
|
-
if (
|
|
26579
|
+
if (isRecord14(props) && "conversationId" in props && props.conversationId != null) {
|
|
25610
26580
|
const candidate = hostThreadIdSchema.safeParse(props.conversationId);
|
|
25611
26581
|
if (!candidate.success || threadId !== void 0 && threadId !== candidate.data) {
|
|
25612
26582
|
return null;
|
|
@@ -25619,12 +26589,12 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25619
26589
|
return threadId;
|
|
25620
26590
|
}
|
|
25621
26591
|
function isLegacySevenSlotDraftWrapper(value) {
|
|
25622
|
-
if (!Array.isArray(value) || value.length !== 7 || value[3] !== value[5] || value[3] !== value[6] || !
|
|
26592
|
+
if (!Array.isArray(value) || value.length !== 7 || value[3] !== value[5] || value[3] !== value[6] || !isRecord14(value[3]) || typeof value[3].get !== "function" || typeof value[2] !== "string" && value[2] !== null) {
|
|
25623
26593
|
return false;
|
|
25624
26594
|
}
|
|
25625
26595
|
try {
|
|
25626
26596
|
const draft = value[3].get();
|
|
25627
|
-
return
|
|
26597
|
+
return isRecord14(draft) && "modelSettings" in draft && "isManuallyChanged" in draft;
|
|
25628
26598
|
} catch {
|
|
25629
26599
|
return false;
|
|
25630
26600
|
}
|
|
@@ -25658,8 +26628,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25658
26628
|
let fiber = findComposerFiber(composer);
|
|
25659
26629
|
for (let depth = 0; fiber && depth < 120; depth += 1) {
|
|
25660
26630
|
const updateQueue = fiber.updateQueue;
|
|
25661
|
-
const memoCache =
|
|
25662
|
-
const data =
|
|
26631
|
+
const memoCache = isRecord14(updateQueue) ? updateQueue.memoCache : null;
|
|
26632
|
+
const data = isRecord14(memoCache) && Array.isArray(memoCache.data) ? memoCache.data : [];
|
|
25663
26633
|
for (const value of data) {
|
|
25664
26634
|
const draftId = draftIdFromMemoValue(value);
|
|
25665
26635
|
if (draftId) draftIds.add(draftId);
|
|
@@ -25687,7 +26657,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25687
26657
|
return ["default", draftIds.values().next().value];
|
|
25688
26658
|
}
|
|
25689
26659
|
function isDraftPrewarmPolicyReady(value) {
|
|
25690
|
-
return
|
|
26660
|
+
return isRecord14(value) && value.state === "ready" && typeof value.hostId === "string" && value.hostId.length > 0 && typeof value.select === "function" && typeof value.clear === "function";
|
|
25691
26661
|
}
|
|
25692
26662
|
async function waitForRendererDraftPrewarmPolicy(target, composer) {
|
|
25693
26663
|
const deadline = Date.now() + DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS;
|
|
@@ -25937,116 +26907,6 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25937
26907
|
}
|
|
25938
26908
|
}
|
|
25939
26909
|
|
|
25940
|
-
// src/renderer-new-thread-preference.ts
|
|
25941
|
-
var RENDERER_NEW_THREAD_PREFERENCE_KEY = "codexhost.new-thread-preference.v1";
|
|
25942
|
-
function rendererNewThreadPreferenceStorage(hostId2 = "local") {
|
|
25943
|
-
if (!hostId2) return null;
|
|
25944
|
-
try {
|
|
25945
|
-
const storage = window.localStorage;
|
|
25946
|
-
if (hostId2 === "local") return storage;
|
|
25947
|
-
const scopedKey = (key) => `${key}.host.${encodeURIComponent(hostId2)}`;
|
|
25948
|
-
return {
|
|
25949
|
-
getItem: (key) => storage.getItem(scopedKey(key)),
|
|
25950
|
-
setItem: (key, value) => storage.setItem(scopedKey(key), value)
|
|
25951
|
-
};
|
|
25952
|
-
} catch {
|
|
25953
|
-
return null;
|
|
25954
|
-
}
|
|
25955
|
-
}
|
|
25956
|
-
function isRecord14(value) {
|
|
25957
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25958
|
-
}
|
|
25959
|
-
function parseExternalConfiguration(value) {
|
|
25960
|
-
if (!isRecord14(value)) return void 0;
|
|
25961
|
-
const model2 = harnessModelRefSchema.safeParse(value.model);
|
|
25962
|
-
if (!model2.success) return void 0;
|
|
25963
|
-
const thinkingOptionId = harnessThinkingOptionIdSchema.safeParse(value.thinkingOptionId);
|
|
25964
|
-
const permissionModeId = harnessPermissionModeIdSchema.safeParse(value.permissionModeId);
|
|
25965
|
-
return {
|
|
25966
|
-
model: model2.data,
|
|
25967
|
-
...thinkingOptionId.success ? { thinkingOptionId: thinkingOptionId.data } : {},
|
|
25968
|
-
...permissionModeId.success ? { permissionModeId: permissionModeId.data } : {}
|
|
25969
|
-
};
|
|
25970
|
-
}
|
|
25971
|
-
function readPreference(storage) {
|
|
25972
|
-
if (!storage) return void 0;
|
|
25973
|
-
try {
|
|
25974
|
-
const raw = storage.getItem(RENDERER_NEW_THREAD_PREFERENCE_KEY);
|
|
25975
|
-
if (!raw) return void 0;
|
|
25976
|
-
const parsed = JSON.parse(raw);
|
|
25977
|
-
if (!isRecord14(parsed) || parsed.version !== 1) return void 0;
|
|
25978
|
-
if (parsed.lastAgent !== "codex" && !harnessPluginIdSchema.safeParse(parsed.lastAgent).success)
|
|
25979
|
-
return void 0;
|
|
25980
|
-
const externalByAgent = isRecord14(parsed.externalByAgent) ? parsed.externalByAgent : {};
|
|
25981
|
-
const parsedExternal = Object.fromEntries(
|
|
25982
|
-
Object.keys(externalByAgent).filter((agent) => harnessPluginIdSchema.safeParse(agent).success).flatMap((agent) => {
|
|
25983
|
-
const configuration = parseExternalConfiguration(externalByAgent[agent]);
|
|
25984
|
-
return configuration ? [[agent, configuration]] : [];
|
|
25985
|
-
})
|
|
25986
|
-
);
|
|
25987
|
-
return {
|
|
25988
|
-
version: 1,
|
|
25989
|
-
lastAgent: parsed.lastAgent,
|
|
25990
|
-
externalByAgent: parsedExternal
|
|
25991
|
-
};
|
|
25992
|
-
} catch {
|
|
25993
|
-
return void 0;
|
|
25994
|
-
}
|
|
25995
|
-
}
|
|
25996
|
-
function writePreference(preference, storage) {
|
|
25997
|
-
if (!storage) return;
|
|
25998
|
-
try {
|
|
25999
|
-
storage.setItem(RENDERER_NEW_THREAD_PREFERENCE_KEY, JSON.stringify(preference));
|
|
26000
|
-
} catch {
|
|
26001
|
-
}
|
|
26002
|
-
}
|
|
26003
|
-
function readNewThreadAgentPreference(enabledAgents, storage = rendererNewThreadPreferenceStorage()) {
|
|
26004
|
-
const agent = readPreference(storage)?.lastAgent;
|
|
26005
|
-
return agent && (!enabledAgents || enabledAgents.has(agent)) ? agent : void 0;
|
|
26006
|
-
}
|
|
26007
|
-
function readNewThreadExternalConfigurationPreference(agent, catalog, permissionModes, storage = rendererNewThreadPreferenceStorage()) {
|
|
26008
|
-
const preference = readPreference(storage)?.externalByAgent[agent];
|
|
26009
|
-
if (!preference) return void 0;
|
|
26010
|
-
const catalogModel = catalogModelForRef(catalog, preference.model);
|
|
26011
|
-
if (!catalogModel) return void 0;
|
|
26012
|
-
const thinkingOptionId = preference.thinkingOptionId && catalogModel.supportedThinkingOptionIds?.includes(preference.thinkingOptionId) ? preference.thinkingOptionId : void 0;
|
|
26013
|
-
const permissionModeId = preference.permissionModeId && permissionModes?.modes.some(({ id }) => id === preference.permissionModeId) ? preference.permissionModeId : void 0;
|
|
26014
|
-
return {
|
|
26015
|
-
model: catalogModel.ref,
|
|
26016
|
-
...thinkingOptionId ? { thinkingOptionId } : {},
|
|
26017
|
-
...permissionModeId ? { permissionModeId } : {}
|
|
26018
|
-
};
|
|
26019
|
-
}
|
|
26020
|
-
function writeNewThreadAgentPreference(agent, storage = rendererNewThreadPreferenceStorage()) {
|
|
26021
|
-
const current = readPreference(storage);
|
|
26022
|
-
writePreference(
|
|
26023
|
-
{
|
|
26024
|
-
version: 1,
|
|
26025
|
-
lastAgent: agent,
|
|
26026
|
-
externalByAgent: current?.externalByAgent ?? {}
|
|
26027
|
-
},
|
|
26028
|
-
storage
|
|
26029
|
-
);
|
|
26030
|
-
}
|
|
26031
|
-
function writeNewThreadExternalConfigurationPreference(agent, model2, thinkingOptionId, permissionModeId, storage = rendererNewThreadPreferenceStorage()) {
|
|
26032
|
-
const current = readPreference(storage);
|
|
26033
|
-
writePreference(
|
|
26034
|
-
{
|
|
26035
|
-
version: 1,
|
|
26036
|
-
lastAgent: current?.lastAgent ?? "codex",
|
|
26037
|
-
externalByAgent: {
|
|
26038
|
-
...current?.externalByAgent,
|
|
26039
|
-
[agent]: {
|
|
26040
|
-
model: harnessModelRefSchema.parse(model2),
|
|
26041
|
-
...thinkingOptionId ? { thinkingOptionId: harnessThinkingOptionIdSchema.parse(thinkingOptionId) } : {},
|
|
26042
|
-
...permissionModeId ? { permissionModeId: harnessPermissionModeIdSchema.parse(permissionModeId) } : {}
|
|
26043
|
-
}
|
|
26044
|
-
}
|
|
26045
|
-
},
|
|
26046
|
-
storage
|
|
26047
|
-
);
|
|
26048
|
-
}
|
|
26049
|
-
|
|
26050
26910
|
// src/renderer-harness-command-claim.ts
|
|
26051
26911
|
function inputEvent(editor, text) {
|
|
26052
26912
|
const view = editor.ownerDocument.defaultView;
|
|
@@ -26152,7 +27012,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
26152
27012
|
return Promise.reject(new Error("Codex locale bridge is unavailable"));
|
|
26153
27013
|
}
|
|
26154
27014
|
if (signal?.aborted) return Promise.reject(abortError2());
|
|
26155
|
-
const
|
|
27015
|
+
const requestId2 = ownerWindow.crypto.randomUUID();
|
|
26156
27016
|
return new Promise((resolve, reject) => {
|
|
26157
27017
|
let settled = false;
|
|
26158
27018
|
const cleanup = () => {
|
|
@@ -26170,7 +27030,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
26170
27030
|
const onMessage = (event) => {
|
|
26171
27031
|
const message3 = event.data;
|
|
26172
27032
|
if (!isRecord15(message3) || message3.type !== "fetch-response") return;
|
|
26173
|
-
if (message3.requestId !==
|
|
27033
|
+
if (message3.requestId !== requestId2) return;
|
|
26174
27034
|
if (message3.responseType !== "success" || typeof message3.status !== "number" || message3.status < 200 || message3.status >= 300 || typeof message3.bodyJsonString !== "string") {
|
|
26175
27035
|
settle(() => reject(new Error("Codex locale request failed")));
|
|
26176
27036
|
return;
|
|
@@ -26190,7 +27050,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
26190
27050
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
26191
27051
|
const message2 = {
|
|
26192
27052
|
type: "fetch",
|
|
26193
|
-
requestId,
|
|
27053
|
+
requestId: requestId2,
|
|
26194
27054
|
method: "POST",
|
|
26195
27055
|
url: request.url,
|
|
26196
27056
|
...request.body === void 0 ? {} : { body: request.body },
|
|
@@ -26304,6 +27164,518 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
26304
27164
|
return element;
|
|
26305
27165
|
}
|
|
26306
27166
|
|
|
27167
|
+
// src/settings/preference-ui.ts
|
|
27168
|
+
var nextPreferenceId = 0;
|
|
27169
|
+
function preferenceId(prefix) {
|
|
27170
|
+
nextPreferenceId += 1;
|
|
27171
|
+
return `codexhost-${prefix}-${nextPreferenceId}`;
|
|
27172
|
+
}
|
|
27173
|
+
function createPreferenceGroup(document2, title) {
|
|
27174
|
+
const group = document2.createElement("section");
|
|
27175
|
+
group.className = "mt-7 first-of-type:mt-0";
|
|
27176
|
+
const header = document2.createElement("div");
|
|
27177
|
+
header.className = "mb-2 flex min-h-6 items-center gap-2 px-1";
|
|
27178
|
+
const heading = document2.createElement("h3");
|
|
27179
|
+
heading.id = preferenceId("preference-group");
|
|
27180
|
+
heading.className = "m-0 text-[13px] leading-5 font-semibold text-settings-text";
|
|
27181
|
+
heading.textContent = title;
|
|
27182
|
+
header.append(heading);
|
|
27183
|
+
const card = document2.createElement("div");
|
|
27184
|
+
card.className = "rounded-[10px] border border-settings-border bg-settings-panel";
|
|
27185
|
+
group.setAttribute("aria-labelledby", heading.id);
|
|
27186
|
+
group.append(header, card);
|
|
27187
|
+
return { group, header, card };
|
|
27188
|
+
}
|
|
27189
|
+
function createPreferenceItem(document2, input) {
|
|
27190
|
+
const item = document2.createElement("div");
|
|
27191
|
+
item.className = "flex min-h-[60px] items-center justify-between gap-6 border-t border-settings-divider px-4 py-3 first:border-t-0";
|
|
27192
|
+
const copy = document2.createElement("div");
|
|
27193
|
+
copy.className = "flex min-w-0 flex-col gap-0.5";
|
|
27194
|
+
const heading = document2.createElement("div");
|
|
27195
|
+
heading.className = "flex items-center gap-1.5";
|
|
27196
|
+
const title = document2.createElement("label");
|
|
27197
|
+
title.htmlFor = input.controlId;
|
|
27198
|
+
title.className = "cursor-pointer text-[13px] leading-5 font-medium text-settings-text";
|
|
27199
|
+
title.textContent = input.title;
|
|
27200
|
+
heading.append(title);
|
|
27201
|
+
if (input.help) heading.append(createHelpTooltip(document2, input.help.label, input.help.lines));
|
|
27202
|
+
const description = document2.createElement("div");
|
|
27203
|
+
description.id = preferenceId("preference-description");
|
|
27204
|
+
description.className = "text-xs leading-[18px] text-settings-muted data-[invalid=true]:text-settings-danger";
|
|
27205
|
+
description.textContent = input.description;
|
|
27206
|
+
copy.append(heading, description);
|
|
27207
|
+
item.append(copy);
|
|
27208
|
+
return { item, description };
|
|
27209
|
+
}
|
|
27210
|
+
function createHelpTooltip(document2, label, lines) {
|
|
27211
|
+
const wrapper = document2.createElement("span");
|
|
27212
|
+
wrapper.className = "group relative inline-flex";
|
|
27213
|
+
const button2 = document2.createElement("button");
|
|
27214
|
+
button2.type = "button";
|
|
27215
|
+
button2.className = "inline-flex size-4 cursor-help items-center justify-center rounded-full border-0 bg-transparent p-0 text-settings-subtle transition-colors hover:text-settings-text focus-visible:text-settings-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-settings-focus";
|
|
27216
|
+
button2.setAttribute("aria-label", label);
|
|
27217
|
+
button2.append(createRendererSettingsIcon("help", 14));
|
|
27218
|
+
const tooltip = document2.createElement("div");
|
|
27219
|
+
tooltip.id = preferenceId("preference-tooltip");
|
|
27220
|
+
tooltip.setAttribute("role", "tooltip");
|
|
27221
|
+
tooltip.className = "pointer-events-none invisible absolute top-full left-0 z-20 mt-2 w-80 rounded-lg border border-settings-border bg-settings-panel px-3 py-2.5 text-xs leading-[18px] font-normal text-settings-text opacity-0 shadow-[0_10px_30px_rgb(0_0_0/0.22)] transition-opacity duration-150 group-hover:visible group-hover:opacity-100 group-focus-within:visible group-focus-within:opacity-100";
|
|
27222
|
+
const list = document2.createElement("ul");
|
|
27223
|
+
list.className = "m-0 grid list-disc gap-1 pl-4 marker:text-settings-subtle";
|
|
27224
|
+
for (const line of lines) {
|
|
27225
|
+
const item = document2.createElement("li");
|
|
27226
|
+
item.textContent = line;
|
|
27227
|
+
list.append(item);
|
|
27228
|
+
}
|
|
27229
|
+
tooltip.append(list);
|
|
27230
|
+
button2.setAttribute("aria-describedby", tooltip.id);
|
|
27231
|
+
button2.addEventListener("keydown", (event) => {
|
|
27232
|
+
if (event.key === "Escape") button2.blur();
|
|
27233
|
+
});
|
|
27234
|
+
wrapper.append(button2, tooltip);
|
|
27235
|
+
return wrapper;
|
|
27236
|
+
}
|
|
27237
|
+
function createPreferenceSwitch(document2, id, describedBy) {
|
|
27238
|
+
const input = document2.createElement("input");
|
|
27239
|
+
input.type = "checkbox";
|
|
27240
|
+
input.id = id;
|
|
27241
|
+
input.setAttribute("role", "switch");
|
|
27242
|
+
input.setAttribute("aria-describedby", describedBy);
|
|
27243
|
+
input.className = "relative m-0 h-5 w-9 shrink-0 cursor-pointer appearance-none rounded-full bg-settings-surface-hover ring-1 ring-settings-border transition-colors ring-inset before:absolute before:top-0.5 before:left-0.5 before:size-4 before:rounded-full before:bg-white before:shadow-[0_1px_2px_rgb(0_0_0/0.3)] before:transition-transform checked:bg-settings-focus checked:ring-transparent checked:before:translate-x-4 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-settings-focus";
|
|
27244
|
+
return input;
|
|
27245
|
+
}
|
|
27246
|
+
function createNumberField(document2, input) {
|
|
27247
|
+
const field = document2.createElement("div");
|
|
27248
|
+
field.className = "flex h-8 shrink-0 items-center gap-1.5 rounded-md border border-settings-border bg-settings-surface px-2.5 transition-colors focus-within:border-settings-focus data-[invalid=true]:border-settings-danger";
|
|
27249
|
+
const control = document2.createElement("input");
|
|
27250
|
+
control.type = "number";
|
|
27251
|
+
control.id = input.id;
|
|
27252
|
+
control.min = String(input.min);
|
|
27253
|
+
control.max = String(input.max);
|
|
27254
|
+
control.step = "1";
|
|
27255
|
+
control.setAttribute("aria-describedby", input.describedBy);
|
|
27256
|
+
control.className = "w-14 border-0 bg-transparent p-0 text-right text-[13px] leading-5 text-settings-text tabular-nums outline-none";
|
|
27257
|
+
const unit = document2.createElement("span");
|
|
27258
|
+
unit.className = "text-xs text-settings-muted";
|
|
27259
|
+
unit.setAttribute("aria-hidden", "true");
|
|
27260
|
+
unit.textContent = input.unit;
|
|
27261
|
+
field.append(control, unit);
|
|
27262
|
+
return { field, control };
|
|
27263
|
+
}
|
|
27264
|
+
|
|
27265
|
+
// src/settings/voice-messages.ts
|
|
27266
|
+
function voiceMessages(locale) {
|
|
27267
|
+
const en = {
|
|
27268
|
+
title: "Voice",
|
|
27269
|
+
description: "Choose voice for Chat and Work. Shared on this Mac.",
|
|
27270
|
+
chat: "Chat",
|
|
27271
|
+
experience: "Voice experience",
|
|
27272
|
+
chatHint: "ChatGPT stays in your current Chat conversation.",
|
|
27273
|
+
codexConnection: "Codex connection",
|
|
27274
|
+
codexHint: "Available when Codex voice is selected.",
|
|
27275
|
+
work: "Work",
|
|
27276
|
+
connection: "Voice connection",
|
|
27277
|
+
workHint: "Desktop default applies to Codex Work. External Harness voice uses the configured gateway.",
|
|
27278
|
+
desktop: "Desktop default",
|
|
27279
|
+
gateway: "Configured gateway",
|
|
27280
|
+
configuration: "Configuration",
|
|
27281
|
+
gatewayTitle: "Gateway",
|
|
27282
|
+
gatewayHint: "Used only when Configured gateway is selected.",
|
|
27283
|
+
configured: "Configured",
|
|
27284
|
+
needsSetup: "Needs setup",
|
|
27285
|
+
unknown: "Not checked",
|
|
27286
|
+
configure: "Configure",
|
|
27287
|
+
setup: "Gateway setup",
|
|
27288
|
+
setupHint: "Gateway settings use your local Codex configuration and the selected provider\u2019s credential. End voice before editing configuration. Never paste credentials here.",
|
|
27289
|
+
advanced: "Advanced",
|
|
27290
|
+
advancedHint: "Voice integration and diagnostics.",
|
|
27291
|
+
inject: "Enable voice integration",
|
|
27292
|
+
injectHint: "Enables the ChatGPT voice control and gateway routing. Changing this requires restarting codexhost.",
|
|
27293
|
+
environment: "Voice integration is controlled by this launch environment.",
|
|
27294
|
+
loading: "Loading voice settings\u2026",
|
|
27295
|
+
unavailable: "Voice settings are unavailable. Check the local Host connection.",
|
|
27296
|
+
retry: "Reload",
|
|
27297
|
+
cancel: "Cancel",
|
|
27298
|
+
apply: "Apply changes",
|
|
27299
|
+
applyRestart: "Apply and restart codexhost",
|
|
27300
|
+
retryRestart: "Retry restart",
|
|
27301
|
+
saving: "Saving settings\u2026",
|
|
27302
|
+
restarting: "Restarting codexhost\u2026",
|
|
27303
|
+
ready: "No pending changes",
|
|
27304
|
+
edited: "Unsaved changes",
|
|
27305
|
+
nextCall: "Voice choices apply to the next call.",
|
|
27306
|
+
pending: "Saved \u2014 waiting for Desktop to apply voice choices.",
|
|
27307
|
+
restartNeeded: "Saved \u2014 restart required",
|
|
27308
|
+
activeUnknown: "Saved \u2014 active setting is unknown.",
|
|
27309
|
+
activeCall: "End your voice call to apply changes.",
|
|
27310
|
+
integrationOff: "Voice integration is off. Enable it in Advanced to use these choices.",
|
|
27311
|
+
restartWarning: "Restart codexhost to apply voice integration? This may interrupt running tasks. End voice before continuing.",
|
|
27312
|
+
confirm: "Apply and restart",
|
|
27313
|
+
restartFailed: "Settings are saved, but restart failed.",
|
|
27314
|
+
conflict: "Settings changed in another window. Reload before applying.",
|
|
27315
|
+
gatewayWarning: "The selected gateway needs setup before voice can connect."
|
|
27316
|
+
};
|
|
27317
|
+
if (locale !== "zh-CN") return en;
|
|
27318
|
+
return {
|
|
27319
|
+
...en,
|
|
27320
|
+
title: "\u8BED\u97F3",
|
|
27321
|
+
description: "\u9009\u62E9 Chat \u548C Work \u7684\u8BED\u97F3\u65B9\u5F0F\u3002\u5728\u6B64 Mac \u4E0A\u5171\u4EAB\u3002",
|
|
27322
|
+
experience: "\u8BED\u97F3\u4F53\u9A8C",
|
|
27323
|
+
chatHint: "ChatGPT \u8BED\u97F3\u4FDD\u7559\u5728\u5F53\u524D Chat \u5BF9\u8BDD\u4E2D\u3002",
|
|
27324
|
+
codexConnection: "Codex \u8FDE\u63A5",
|
|
27325
|
+
codexHint: "\u9009\u62E9 Codex \u8BED\u97F3\u540E\u53EF\u7528\u3002",
|
|
27326
|
+
connection: "\u8BED\u97F3\u8FDE\u63A5",
|
|
27327
|
+
workHint: "Desktop \u9ED8\u8BA4\u9002\u7528\u4E8E Codex Work\u3002\u5916\u90E8 Harness \u8BED\u97F3\u4F7F\u7528\u5DF2\u914D\u7F6E\u7684\u7F51\u5173\u3002",
|
|
27328
|
+
desktop: "Desktop \u9ED8\u8BA4",
|
|
27329
|
+
gateway: "\u5DF2\u914D\u7F6E\u7684\u7F51\u5173",
|
|
27330
|
+
configuration: "\u914D\u7F6E",
|
|
27331
|
+
gatewayTitle: "\u7F51\u5173",
|
|
27332
|
+
gatewayHint: "\u4EC5\u5728\u9009\u62E9\u5DF2\u914D\u7F6E\u7684\u7F51\u5173\u65F6\u4F7F\u7528\u3002",
|
|
27333
|
+
configured: "\u5DF2\u914D\u7F6E",
|
|
27334
|
+
needsSetup: "\u9700\u8981\u914D\u7F6E",
|
|
27335
|
+
unknown: "\u672A\u68C0\u67E5",
|
|
27336
|
+
configure: "\u914D\u7F6E",
|
|
27337
|
+
setup: "\u7F51\u5173\u914D\u7F6E",
|
|
27338
|
+
setupHint: "\u7F51\u5173\u4F7F\u7528\u672C\u5730 Codex \u914D\u7F6E\u53CA\u6240\u9009 Provider \u7684\u51ED\u636E\u3002\u7F16\u8F91\u524D\u8BF7\u7ED3\u675F\u8BED\u97F3\u3002\u8BF7\u52FF\u5728\u6B64\u7C98\u8D34\u51ED\u636E\u3002",
|
|
27339
|
+
advanced: "\u9AD8\u7EA7",
|
|
27340
|
+
advancedHint: "\u8BED\u97F3\u96C6\u6210\u4E0E\u8BCA\u65AD\u3002",
|
|
27341
|
+
inject: "\u542F\u7528\u8BED\u97F3\u96C6\u6210",
|
|
27342
|
+
injectHint: "\u542F\u7528 ChatGPT \u8BED\u97F3\u6309\u94AE\u4E0E\u7F51\u5173\u8DEF\u7531\u3002\u66F4\u6539\u6B64\u9879\u9700\u8981\u91CD\u542F codexhost\u3002",
|
|
27343
|
+
environment: "\u5F53\u524D\u542F\u52A8\u73AF\u5883\u63A7\u5236\u8BED\u97F3\u96C6\u6210\u3002",
|
|
27344
|
+
loading: "\u6B63\u5728\u52A0\u8F7D\u8BED\u97F3\u8BBE\u7F6E\u2026",
|
|
27345
|
+
unavailable: "\u8BED\u97F3\u8BBE\u7F6E\u4E0D\u53EF\u7528\uFF0C\u8BF7\u68C0\u67E5\u672C\u5730 Host \u8FDE\u63A5\u3002",
|
|
27346
|
+
retry: "\u91CD\u65B0\u52A0\u8F7D",
|
|
27347
|
+
cancel: "\u53D6\u6D88",
|
|
27348
|
+
apply: "\u5E94\u7528\u66F4\u6539",
|
|
27349
|
+
applyRestart: "\u5E94\u7528\u5E76\u91CD\u542F codexhost",
|
|
27350
|
+
retryRestart: "\u91CD\u8BD5\u91CD\u542F",
|
|
27351
|
+
saving: "\u6B63\u5728\u4FDD\u5B58\u8BBE\u7F6E\u2026",
|
|
27352
|
+
restarting: "\u6B63\u5728\u91CD\u542F codexhost\u2026",
|
|
27353
|
+
ready: "\u6CA1\u6709\u5F85\u5E94\u7528\u7684\u66F4\u6539",
|
|
27354
|
+
edited: "\u66F4\u6539\u5C1A\u672A\u4FDD\u5B58",
|
|
27355
|
+
nextCall: "\u8BED\u97F3\u9009\u62E9\u4ECE\u4E0B\u6B21\u901A\u8BDD\u751F\u6548\u3002",
|
|
27356
|
+
pending: "\u5DF2\u4FDD\u5B58\uFF0C\u7B49\u5F85 Desktop \u5E94\u7528\u8BED\u97F3\u9009\u62E9\u3002",
|
|
27357
|
+
restartNeeded: "\u5DF2\u4FDD\u5B58\uFF0C\u9700\u8981\u91CD\u542F",
|
|
27358
|
+
activeUnknown: "\u5DF2\u4FDD\u5B58\uFF0C\u5F53\u524D\u751F\u6548\u72B6\u6001\u672A\u77E5\u3002",
|
|
27359
|
+
activeCall: "\u8BF7\u7ED3\u675F\u8BED\u97F3\u540E\u518D\u5E94\u7528\u66F4\u6539\u3002",
|
|
27360
|
+
integrationOff: "\u8BED\u97F3\u96C6\u6210\u5DF2\u5173\u95ED\uFF0C\u8BF7\u5728\u9AD8\u7EA7\u8BBE\u7F6E\u4E2D\u542F\u7528\u540E\u4F7F\u7528\u8FD9\u4E9B\u9009\u9879\u3002",
|
|
27361
|
+
restartWarning: "\u91CD\u542F codexhost \u4EE5\u5E94\u7528\u8BED\u97F3\u96C6\u6210\uFF1F\u8FD9\u53EF\u80FD\u4E2D\u65AD\u8FD0\u884C\u4E2D\u7684\u4EFB\u52A1\uFF0C\u8BF7\u5148\u7ED3\u675F\u8BED\u97F3\u3002",
|
|
27362
|
+
confirm: "\u5E94\u7528\u5E76\u91CD\u542F",
|
|
27363
|
+
restartFailed: "\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\uFF0C\u4F46\u91CD\u542F\u5931\u8D25\u3002",
|
|
27364
|
+
conflict: "\u5176\u4ED6\u7A97\u53E3\u66F4\u6539\u4E86\u8BBE\u7F6E\uFF0C\u8BF7\u91CD\u65B0\u52A0\u8F7D\u540E\u518D\u5E94\u7528\u3002",
|
|
27365
|
+
gatewayWarning: "\u6240\u9009\u7F51\u5173\u9700\u8981\u914D\u7F6E\u540E\u624D\u80FD\u8FDE\u63A5\u8BED\u97F3\u3002"
|
|
27366
|
+
};
|
|
27367
|
+
}
|
|
27368
|
+
|
|
27369
|
+
// src/settings/voice-page.ts
|
|
27370
|
+
function createVoiceSettingsPage(locale, request, options = {}) {
|
|
27371
|
+
const m = voiceMessages(locale);
|
|
27372
|
+
return Object.freeze({
|
|
27373
|
+
id: options.id ?? "voice",
|
|
27374
|
+
label: m.title,
|
|
27375
|
+
icon: "settings",
|
|
27376
|
+
mount(context) {
|
|
27377
|
+
const doc = context.content.ownerDocument;
|
|
27378
|
+
let state = null;
|
|
27379
|
+
let base = null;
|
|
27380
|
+
let draft = null;
|
|
27381
|
+
let offline = false;
|
|
27382
|
+
let busy = false;
|
|
27383
|
+
let refreshing = false;
|
|
27384
|
+
let generation = 0;
|
|
27385
|
+
let disposed = false;
|
|
27386
|
+
let confirm = false;
|
|
27387
|
+
let advanced = false;
|
|
27388
|
+
let setup = false;
|
|
27389
|
+
let error51 = null;
|
|
27390
|
+
const ids = /* @__PURE__ */ new Map();
|
|
27391
|
+
const controlId = (key) => {
|
|
27392
|
+
const existing = ids.get(key);
|
|
27393
|
+
if (existing) return existing;
|
|
27394
|
+
const id = preferenceId(key);
|
|
27395
|
+
ids.set(key, id);
|
|
27396
|
+
return id;
|
|
27397
|
+
};
|
|
27398
|
+
const dirty = () => !!draft && JSON.stringify(draft) !== JSON.stringify(base?.settings);
|
|
27399
|
+
const isActiveCall = () => state?.activeCall === true || options.desktop && !!doc.defaultView && desktopVoiceCallActive(doc.defaultView);
|
|
27400
|
+
const needsRestart = () => !!draft && !!state && (state.activeInject === null ? draft.inject !== base?.settings.inject : (state.envOverride ? state.envOverride === "1" : draft.inject) !== state.activeInject);
|
|
27401
|
+
const load = async (reset = false) => {
|
|
27402
|
+
if (refreshing || busy || disposed) return;
|
|
27403
|
+
refreshing = true;
|
|
27404
|
+
const currentGeneration = generation;
|
|
27405
|
+
try {
|
|
27406
|
+
const next = voiceSettingsStateSchema.parse(await request({ operation: "get" }));
|
|
27407
|
+
if (disposed || generation !== currentGeneration) return;
|
|
27408
|
+
const changed = JSON.stringify(state) !== JSON.stringify(next) || offline || reset;
|
|
27409
|
+
if (reset || !dirty()) {
|
|
27410
|
+
base = next;
|
|
27411
|
+
draft = { ...next.settings };
|
|
27412
|
+
}
|
|
27413
|
+
state = next;
|
|
27414
|
+
offline = false;
|
|
27415
|
+
if (reset) {
|
|
27416
|
+
error51 = null;
|
|
27417
|
+
confirm = false;
|
|
27418
|
+
}
|
|
27419
|
+
if (changed) render();
|
|
27420
|
+
} catch {
|
|
27421
|
+
if (!disposed && generation === currentGeneration) {
|
|
27422
|
+
offline = true;
|
|
27423
|
+
render();
|
|
27424
|
+
}
|
|
27425
|
+
} finally {
|
|
27426
|
+
refreshing = false;
|
|
27427
|
+
}
|
|
27428
|
+
};
|
|
27429
|
+
const apply = async (restart) => {
|
|
27430
|
+
if (!draft || !base || busy || isActiveCall()) return;
|
|
27431
|
+
busy = true;
|
|
27432
|
+
generation += 1;
|
|
27433
|
+
error51 = null;
|
|
27434
|
+
confirm = false;
|
|
27435
|
+
render();
|
|
27436
|
+
try {
|
|
27437
|
+
const current = voiceSettingsStateSchema.parse(await request({ operation: "get" }));
|
|
27438
|
+
if (disposed) return;
|
|
27439
|
+
if (current.activeCall || isActiveCall()) throw new Error(m.activeCall);
|
|
27440
|
+
if (current.revision !== base.revision) throw new Error(m.conflict);
|
|
27441
|
+
if (dirty()) {
|
|
27442
|
+
const saved = voiceSettingsStateSchema.parse(
|
|
27443
|
+
await request({
|
|
27444
|
+
operation: "set",
|
|
27445
|
+
settings: draft,
|
|
27446
|
+
revision: base.revision
|
|
27447
|
+
})
|
|
27448
|
+
);
|
|
27449
|
+
if (disposed) return;
|
|
27450
|
+
state = saved;
|
|
27451
|
+
base = saved;
|
|
27452
|
+
draft = { ...saved.settings };
|
|
27453
|
+
}
|
|
27454
|
+
if (restart) await request({ operation: "restart", confirm: true });
|
|
27455
|
+
} catch (failure) {
|
|
27456
|
+
if (!disposed) error51 = failure instanceof Error ? failure.message : m.unavailable;
|
|
27457
|
+
} finally {
|
|
27458
|
+
busy = false;
|
|
27459
|
+
if (!disposed) {
|
|
27460
|
+
render();
|
|
27461
|
+
void load();
|
|
27462
|
+
}
|
|
27463
|
+
}
|
|
27464
|
+
};
|
|
27465
|
+
const render = () => {
|
|
27466
|
+
if (disposed) return;
|
|
27467
|
+
const tree = context.content.getRootNode();
|
|
27468
|
+
const focused = tree.activeElement;
|
|
27469
|
+
const focusedId = focused && context.content.contains(focused) ? focused.id : "";
|
|
27470
|
+
const root = h(doc, "div", { className: "settings-voice" });
|
|
27471
|
+
root.append(
|
|
27472
|
+
h(doc, "div", { className: "settings-section-label" }, m.title),
|
|
27473
|
+
h(doc, "p", { className: "settings-page-description" }, m.description)
|
|
27474
|
+
);
|
|
27475
|
+
if (!draft || !state) {
|
|
27476
|
+
root.append(h(doc, "p", { role: "status" }, offline ? m.unavailable : m.loading));
|
|
27477
|
+
if (offline) root.append(button(doc, m.retry, () => void load(true)));
|
|
27478
|
+
context.content.replaceChildren(root);
|
|
27479
|
+
return;
|
|
27480
|
+
}
|
|
27481
|
+
const unavailable = busy || offline || state.restart.phase === "restarting";
|
|
27482
|
+
const row = (card, title, description, key, choices, disabled = false) => {
|
|
27483
|
+
const id = controlId(`voice-${key}`);
|
|
27484
|
+
const item = createPreferenceItem(doc, { title, description, controlId: id });
|
|
27485
|
+
item.item.classList.add("settings-voice__row");
|
|
27486
|
+
const select = h(doc, "select", {
|
|
27487
|
+
id,
|
|
27488
|
+
className: "settings-voice__select",
|
|
27489
|
+
"aria-describedby": item.description.id
|
|
27490
|
+
});
|
|
27491
|
+
for (const [value, label] of choices) select.append(h(doc, "option", { value }, label));
|
|
27492
|
+
select.value = draft?.[key] ?? "";
|
|
27493
|
+
select.disabled = unavailable || disabled;
|
|
27494
|
+
select.addEventListener("change", () => {
|
|
27495
|
+
if (!draft) return;
|
|
27496
|
+
draft = { ...draft, [key]: select.value };
|
|
27497
|
+
confirm = false;
|
|
27498
|
+
render();
|
|
27499
|
+
});
|
|
27500
|
+
item.item.append(select);
|
|
27501
|
+
card.append(item.item);
|
|
27502
|
+
};
|
|
27503
|
+
const connections = [
|
|
27504
|
+
["desktop", m.desktop],
|
|
27505
|
+
["gateway", m.gateway]
|
|
27506
|
+
];
|
|
27507
|
+
const chat = createPreferenceGroup(doc, m.chat);
|
|
27508
|
+
row(chat.card, m.experience, m.chatHint, "chatExperience", [
|
|
27509
|
+
["chatgpt", "ChatGPT"],
|
|
27510
|
+
["codex", "Codex"]
|
|
27511
|
+
]);
|
|
27512
|
+
row(
|
|
27513
|
+
chat.card,
|
|
27514
|
+
m.codexConnection,
|
|
27515
|
+
m.codexHint,
|
|
27516
|
+
"chatConnection",
|
|
27517
|
+
connections,
|
|
27518
|
+
draft.chatExperience !== "codex"
|
|
27519
|
+
);
|
|
27520
|
+
const work = createPreferenceGroup(doc, m.work);
|
|
27521
|
+
row(work.card, m.connection, m.workHint, "workConnection", connections);
|
|
27522
|
+
const config2 = createPreferenceGroup(doc, m.configuration);
|
|
27523
|
+
const gateway = createPreferenceItem(doc, {
|
|
27524
|
+
title: m.gatewayTitle,
|
|
27525
|
+
description: m.gatewayHint,
|
|
27526
|
+
controlId: preferenceId("gateway-config")
|
|
27527
|
+
});
|
|
27528
|
+
gateway.item.classList.add("settings-voice__row");
|
|
27529
|
+
const configure = button(doc, m.configure, () => {
|
|
27530
|
+
setup = !setup;
|
|
27531
|
+
render();
|
|
27532
|
+
});
|
|
27533
|
+
configure.id = gateway.item.querySelector("label")?.htmlFor ?? "";
|
|
27534
|
+
configure.setAttribute("aria-expanded", String(setup));
|
|
27535
|
+
const gatewayActions = h(
|
|
27536
|
+
doc,
|
|
27537
|
+
"div",
|
|
27538
|
+
{ className: "settings-voice__gateway-actions" },
|
|
27539
|
+
h(
|
|
27540
|
+
doc,
|
|
27541
|
+
"span",
|
|
27542
|
+
{},
|
|
27543
|
+
state.gatewayReady === null ? m.unknown : state.gatewayReady ? m.configured : m.needsSetup
|
|
27544
|
+
),
|
|
27545
|
+
configure
|
|
27546
|
+
);
|
|
27547
|
+
gateway.item.append(gatewayActions);
|
|
27548
|
+
config2.card.append(gateway.item);
|
|
27549
|
+
if (setup) {
|
|
27550
|
+
const details = h(
|
|
27551
|
+
doc,
|
|
27552
|
+
"div",
|
|
27553
|
+
{ className: "settings-voice__details" },
|
|
27554
|
+
h(doc, "strong", {}, m.setup),
|
|
27555
|
+
h(doc, "p", {}, m.setupHint)
|
|
27556
|
+
);
|
|
27557
|
+
details.append(
|
|
27558
|
+
h(doc, "code", {}, "~/.codex/config.toml"),
|
|
27559
|
+
h(
|
|
27560
|
+
doc,
|
|
27561
|
+
"p",
|
|
27562
|
+
{},
|
|
27563
|
+
"experimental_realtime_webrtc_call_base_url \xB7 experimental_realtime_ws_base_url"
|
|
27564
|
+
)
|
|
27565
|
+
);
|
|
27566
|
+
config2.card.append(details);
|
|
27567
|
+
}
|
|
27568
|
+
const adv = createPreferenceItem(doc, {
|
|
27569
|
+
title: m.advanced,
|
|
27570
|
+
description: m.advancedHint,
|
|
27571
|
+
controlId: preferenceId("voice-advanced")
|
|
27572
|
+
});
|
|
27573
|
+
const expand = button(doc, advanced ? "\u2303" : "\u203A", () => {
|
|
27574
|
+
advanced = !advanced;
|
|
27575
|
+
render();
|
|
27576
|
+
});
|
|
27577
|
+
expand.id = adv.item.querySelector("label")?.htmlFor ?? "";
|
|
27578
|
+
expand.setAttribute("aria-label", m.advanced);
|
|
27579
|
+
expand.setAttribute("aria-expanded", String(advanced));
|
|
27580
|
+
adv.item.append(expand);
|
|
27581
|
+
config2.card.append(adv.item);
|
|
27582
|
+
if (advanced) {
|
|
27583
|
+
const id = controlId("voice-inject");
|
|
27584
|
+
const injection = createPreferenceItem(doc, {
|
|
27585
|
+
title: m.inject,
|
|
27586
|
+
description: m.injectHint,
|
|
27587
|
+
controlId: id
|
|
27588
|
+
});
|
|
27589
|
+
injection.item.classList.add("settings-voice__row");
|
|
27590
|
+
const toggle = createPreferenceSwitch(doc, id, injection.description.id);
|
|
27591
|
+
toggle.checked = draft.inject;
|
|
27592
|
+
toggle.disabled = unavailable || !!state.envOverride;
|
|
27593
|
+
toggle.addEventListener("change", () => {
|
|
27594
|
+
if (draft) draft = { ...draft, inject: toggle.checked };
|
|
27595
|
+
confirm = false;
|
|
27596
|
+
render();
|
|
27597
|
+
});
|
|
27598
|
+
injection.item.append(toggle);
|
|
27599
|
+
config2.card.append(injection.item);
|
|
27600
|
+
if (state.envOverride || state.activeEnvOverride)
|
|
27601
|
+
config2.card.append(
|
|
27602
|
+
h(doc, "p", { className: "settings-voice__details" }, m.environment)
|
|
27603
|
+
);
|
|
27604
|
+
}
|
|
27605
|
+
root.append(chat.group, work.group, config2.group);
|
|
27606
|
+
const restarting = state.restart.phase === "restarting";
|
|
27607
|
+
const failed = state.restart.phase === "failed";
|
|
27608
|
+
const status = busy ? m.saving : restarting ? m.restarting : isActiveCall() ? m.activeCall : offline ? m.unavailable : dirty() ? m.edited : needsRestart() ? m.restartNeeded : state.activeInject === null ? m.activeUnknown : state.routesActive === false ? m.pending : state.routesActive === null ? m.activeUnknown : m.ready;
|
|
27609
|
+
const footer = h(
|
|
27610
|
+
doc,
|
|
27611
|
+
"div",
|
|
27612
|
+
{ className: "settings-voice__footer" },
|
|
27613
|
+
h(doc, "div", { role: "status" }, h(doc, "div", {}, status), h(doc, "p", {}, m.nextCall))
|
|
27614
|
+
);
|
|
27615
|
+
const actions = h(doc, "div", { className: "settings-voice__actions" });
|
|
27616
|
+
const cancel = button(doc, m.cancel, () => {
|
|
27617
|
+
draft = base ? { ...base.settings } : null;
|
|
27618
|
+
confirm = false;
|
|
27619
|
+
error51 = null;
|
|
27620
|
+
render();
|
|
27621
|
+
});
|
|
27622
|
+
cancel.disabled = busy || !dirty() && !confirm;
|
|
27623
|
+
const submit = button(
|
|
27624
|
+
doc,
|
|
27625
|
+
failed && needsRestart() && !dirty() ? m.retryRestart : needsRestart() && state.restartAvailable ? m.applyRestart : m.apply,
|
|
27626
|
+
() => {
|
|
27627
|
+
if (needsRestart() && state?.restartAvailable) {
|
|
27628
|
+
confirm = true;
|
|
27629
|
+
render();
|
|
27630
|
+
} else void apply(false);
|
|
27631
|
+
},
|
|
27632
|
+
"primary"
|
|
27633
|
+
);
|
|
27634
|
+
submit.disabled = unavailable || !!isActiveCall() || !dirty() && !(needsRestart() && state.restartAvailable);
|
|
27635
|
+
actions.append(cancel, submit);
|
|
27636
|
+
footer.append(actions);
|
|
27637
|
+
root.append(footer);
|
|
27638
|
+
if (confirm)
|
|
27639
|
+
root.append(
|
|
27640
|
+
h(
|
|
27641
|
+
doc,
|
|
27642
|
+
"div",
|
|
27643
|
+
{ className: "settings-voice__confirmation" },
|
|
27644
|
+
h(doc, "p", {}, m.restartWarning),
|
|
27645
|
+
button(doc, m.confirm, () => void apply(true), "primary"),
|
|
27646
|
+
button(doc, m.cancel, () => {
|
|
27647
|
+
confirm = false;
|
|
27648
|
+
render();
|
|
27649
|
+
})
|
|
27650
|
+
)
|
|
27651
|
+
);
|
|
27652
|
+
if (failed)
|
|
27653
|
+
root.append(
|
|
27654
|
+
h(doc, "p", { role: "alert" }, `${m.restartFailed} ${state.restart.error ?? ""}`)
|
|
27655
|
+
);
|
|
27656
|
+
if (error51) root.append(h(doc, "p", { role: "alert" }, error51));
|
|
27657
|
+
const gatewaySelected = draft.workConnection === "gateway" || draft.chatExperience === "codex" && draft.chatConnection === "gateway";
|
|
27658
|
+
if (gatewaySelected && state.gatewayReady === false)
|
|
27659
|
+
root.append(h(doc, "p", { className: "settings-voice__hint" }, m.gatewayWarning));
|
|
27660
|
+
if (!draft.inject)
|
|
27661
|
+
root.append(h(doc, "p", { className: "settings-voice__hint" }, m.integrationOff));
|
|
27662
|
+
if (offline || base?.revision !== state.revision)
|
|
27663
|
+
root.append(button(doc, m.retry, () => void load(true)));
|
|
27664
|
+
context.content.replaceChildren(root);
|
|
27665
|
+
if (focusedId)
|
|
27666
|
+
root.querySelector(`#${focusedId}`)?.focus({ preventScroll: true });
|
|
27667
|
+
};
|
|
27668
|
+
render();
|
|
27669
|
+
void load();
|
|
27670
|
+
const timer = doc.defaultView?.setInterval(() => void load(), 3e3);
|
|
27671
|
+
return () => {
|
|
27672
|
+
disposed = true;
|
|
27673
|
+
if (timer !== void 0) doc.defaultView?.clearInterval(timer);
|
|
27674
|
+
};
|
|
27675
|
+
}
|
|
27676
|
+
});
|
|
27677
|
+
}
|
|
27678
|
+
|
|
26307
27679
|
// src/console/usage/model-labels.ts
|
|
26308
27680
|
function usageModelLabel(model2, labels, harness2) {
|
|
26309
27681
|
const names = new Set(
|
|
@@ -28631,6 +30003,12 @@ ${detail}` : ""}`
|
|
|
28631
30003
|
stopped: "codexhost is not running",
|
|
28632
30004
|
stoppedDetail: "Start codexhost to use Codex Desktop with your Harnesses.",
|
|
28633
30005
|
start: "Start codexhost",
|
|
30006
|
+
restart: "Restart codexhost",
|
|
30007
|
+
restartConfirm: "Restart now",
|
|
30008
|
+
restartCancel: "Cancel",
|
|
30009
|
+
restartWarning: "Restart closes Desktop and may interrupt a voice call or running tasks. Finish or stop them before continuing. Saved chats remain available; Desktop controls which chat reopens.",
|
|
30010
|
+
restarting: "Restarting codexhost\u2026 Waiting for the new Desktop controller.",
|
|
30011
|
+
restarted: "Restart complete. The new Desktop controller is ready.",
|
|
28634
30012
|
starting: "Starting\u2026",
|
|
28635
30013
|
startingTitle: "codexhost is starting",
|
|
28636
30014
|
startingDetail: "Preparing Codex Desktop. Please wait; there is no need to start it again.",
|
|
@@ -28814,6 +30192,12 @@ ${detail}` : ""}`
|
|
|
28814
30192
|
stopped: "codexhost \u672A\u8FD0\u884C",
|
|
28815
30193
|
stoppedDetail: "\u542F\u52A8 codexhost \u540E\u5373\u53EF\u5728 Codex Desktop \u4E2D\u4F7F\u7528\u5404\u4E2A Harness\u3002",
|
|
28816
30194
|
start: "\u542F\u52A8 codexhost",
|
|
30195
|
+
restart: "\u91CD\u65B0\u542F\u52A8 codexhost",
|
|
30196
|
+
restartConfirm: "\u7ACB\u5373\u91CD\u65B0\u542F\u52A8",
|
|
30197
|
+
restartCancel: "\u53D6\u6D88",
|
|
30198
|
+
restartWarning: "\u91CD\u65B0\u542F\u52A8\u4F1A\u5173\u95ED Desktop\uFF0C\u53EF\u80FD\u4E2D\u65AD\u8BED\u97F3\u901A\u8BDD\u6216\u8FD0\u884C\u4E2D\u7684\u4EFB\u52A1\u3002\u8BF7\u5148\u5B8C\u6210\u6216\u505C\u6B62\u5B83\u4EEC\u3002\u5DF2\u4FDD\u5B58\u804A\u5929\u4ECD\u53EF\u4F7F\u7528\uFF1B\u91CD\u65B0\u6253\u5F00\u54EA\u4E2A\u804A\u5929\u7531 Desktop \u51B3\u5B9A\u3002",
|
|
30199
|
+
restarting: "\u6B63\u5728\u91CD\u65B0\u542F\u52A8 codexhost\u2026 \u7B49\u5F85\u65B0\u7684 Desktop \u63A7\u5236\u5668\u3002",
|
|
30200
|
+
restarted: "\u91CD\u65B0\u542F\u52A8\u5B8C\u6210\u3002\u65B0\u7684 Desktop \u63A7\u5236\u5668\u5DF2\u5C31\u7EEA\u3002",
|
|
28817
30201
|
starting: "\u6B63\u5728\u542F\u52A8\u2026",
|
|
28818
30202
|
startingTitle: "codexhost \u6B63\u5728\u542F\u52A8",
|
|
28819
30203
|
startingDetail: "\u6B63\u5728\u51C6\u5907 Codex Desktop\uFF0C\u8BF7\u7A0D\u5019\uFF0C\u65E0\u9700\u91CD\u590D\u542F\u52A8\u3002",
|
|
@@ -29343,104 +30727,6 @@ ${detail}` : ""}`
|
|
|
29343
30727
|
return card;
|
|
29344
30728
|
}
|
|
29345
30729
|
|
|
29346
|
-
// src/settings/preference-ui.ts
|
|
29347
|
-
var nextPreferenceId = 0;
|
|
29348
|
-
function preferenceId(prefix) {
|
|
29349
|
-
nextPreferenceId += 1;
|
|
29350
|
-
return `codexhost-${prefix}-${nextPreferenceId}`;
|
|
29351
|
-
}
|
|
29352
|
-
function createPreferenceGroup(document2, title) {
|
|
29353
|
-
const group = document2.createElement("section");
|
|
29354
|
-
group.className = "mt-7 first-of-type:mt-0";
|
|
29355
|
-
const header = document2.createElement("div");
|
|
29356
|
-
header.className = "mb-2 flex min-h-6 items-center gap-2 px-1";
|
|
29357
|
-
const heading = document2.createElement("h3");
|
|
29358
|
-
heading.id = preferenceId("preference-group");
|
|
29359
|
-
heading.className = "m-0 text-[13px] leading-5 font-semibold text-settings-text";
|
|
29360
|
-
heading.textContent = title;
|
|
29361
|
-
header.append(heading);
|
|
29362
|
-
const card = document2.createElement("div");
|
|
29363
|
-
card.className = "rounded-[10px] border border-settings-border bg-settings-panel";
|
|
29364
|
-
group.setAttribute("aria-labelledby", heading.id);
|
|
29365
|
-
group.append(header, card);
|
|
29366
|
-
return { group, header, card };
|
|
29367
|
-
}
|
|
29368
|
-
function createPreferenceItem(document2, input) {
|
|
29369
|
-
const item = document2.createElement("div");
|
|
29370
|
-
item.className = "flex min-h-[60px] items-center justify-between gap-6 border-t border-settings-divider px-4 py-3 first:border-t-0";
|
|
29371
|
-
const copy = document2.createElement("div");
|
|
29372
|
-
copy.className = "flex min-w-0 flex-col gap-0.5";
|
|
29373
|
-
const heading = document2.createElement("div");
|
|
29374
|
-
heading.className = "flex items-center gap-1.5";
|
|
29375
|
-
const title = document2.createElement("label");
|
|
29376
|
-
title.htmlFor = input.controlId;
|
|
29377
|
-
title.className = "cursor-pointer text-[13px] leading-5 font-medium text-settings-text";
|
|
29378
|
-
title.textContent = input.title;
|
|
29379
|
-
heading.append(title);
|
|
29380
|
-
if (input.help) heading.append(createHelpTooltip(document2, input.help.label, input.help.lines));
|
|
29381
|
-
const description = document2.createElement("div");
|
|
29382
|
-
description.id = preferenceId("preference-description");
|
|
29383
|
-
description.className = "text-xs leading-[18px] text-settings-muted data-[invalid=true]:text-settings-danger";
|
|
29384
|
-
description.textContent = input.description;
|
|
29385
|
-
copy.append(heading, description);
|
|
29386
|
-
item.append(copy);
|
|
29387
|
-
return { item, description };
|
|
29388
|
-
}
|
|
29389
|
-
function createHelpTooltip(document2, label, lines) {
|
|
29390
|
-
const wrapper = document2.createElement("span");
|
|
29391
|
-
wrapper.className = "group relative inline-flex";
|
|
29392
|
-
const button2 = document2.createElement("button");
|
|
29393
|
-
button2.type = "button";
|
|
29394
|
-
button2.className = "inline-flex size-4 cursor-help items-center justify-center rounded-full border-0 bg-transparent p-0 text-settings-subtle transition-colors hover:text-settings-text focus-visible:text-settings-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-settings-focus";
|
|
29395
|
-
button2.setAttribute("aria-label", label);
|
|
29396
|
-
button2.append(createRendererSettingsIcon("help", 14));
|
|
29397
|
-
const tooltip = document2.createElement("div");
|
|
29398
|
-
tooltip.id = preferenceId("preference-tooltip");
|
|
29399
|
-
tooltip.setAttribute("role", "tooltip");
|
|
29400
|
-
tooltip.className = "pointer-events-none invisible absolute top-full left-0 z-20 mt-2 w-80 rounded-lg border border-settings-border bg-settings-panel px-3 py-2.5 text-xs leading-[18px] font-normal text-settings-text opacity-0 shadow-[0_10px_30px_rgb(0_0_0/0.22)] transition-opacity duration-150 group-hover:visible group-hover:opacity-100 group-focus-within:visible group-focus-within:opacity-100";
|
|
29401
|
-
const list = document2.createElement("ul");
|
|
29402
|
-
list.className = "m-0 grid list-disc gap-1 pl-4 marker:text-settings-subtle";
|
|
29403
|
-
for (const line of lines) {
|
|
29404
|
-
const item = document2.createElement("li");
|
|
29405
|
-
item.textContent = line;
|
|
29406
|
-
list.append(item);
|
|
29407
|
-
}
|
|
29408
|
-
tooltip.append(list);
|
|
29409
|
-
button2.setAttribute("aria-describedby", tooltip.id);
|
|
29410
|
-
button2.addEventListener("keydown", (event) => {
|
|
29411
|
-
if (event.key === "Escape") button2.blur();
|
|
29412
|
-
});
|
|
29413
|
-
wrapper.append(button2, tooltip);
|
|
29414
|
-
return wrapper;
|
|
29415
|
-
}
|
|
29416
|
-
function createPreferenceSwitch(document2, id, describedBy) {
|
|
29417
|
-
const input = document2.createElement("input");
|
|
29418
|
-
input.type = "checkbox";
|
|
29419
|
-
input.id = id;
|
|
29420
|
-
input.setAttribute("role", "switch");
|
|
29421
|
-
input.setAttribute("aria-describedby", describedBy);
|
|
29422
|
-
input.className = "relative m-0 h-5 w-9 shrink-0 cursor-pointer appearance-none rounded-full bg-settings-surface-hover ring-1 ring-settings-border transition-colors ring-inset before:absolute before:top-0.5 before:left-0.5 before:size-4 before:rounded-full before:bg-white before:shadow-[0_1px_2px_rgb(0_0_0/0.3)] before:transition-transform checked:bg-settings-focus checked:ring-transparent checked:before:translate-x-4 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-settings-focus";
|
|
29423
|
-
return input;
|
|
29424
|
-
}
|
|
29425
|
-
function createNumberField(document2, input) {
|
|
29426
|
-
const field = document2.createElement("div");
|
|
29427
|
-
field.className = "flex h-8 shrink-0 items-center gap-1.5 rounded-md border border-settings-border bg-settings-surface px-2.5 transition-colors focus-within:border-settings-focus data-[invalid=true]:border-settings-danger";
|
|
29428
|
-
const control = document2.createElement("input");
|
|
29429
|
-
control.type = "number";
|
|
29430
|
-
control.id = input.id;
|
|
29431
|
-
control.min = String(input.min);
|
|
29432
|
-
control.max = String(input.max);
|
|
29433
|
-
control.step = "1";
|
|
29434
|
-
control.setAttribute("aria-describedby", input.describedBy);
|
|
29435
|
-
control.className = "w-14 border-0 bg-transparent p-0 text-right text-[13px] leading-5 text-settings-text tabular-nums outline-none";
|
|
29436
|
-
const unit = document2.createElement("span");
|
|
29437
|
-
unit.className = "text-xs text-settings-muted";
|
|
29438
|
-
unit.setAttribute("aria-hidden", "true");
|
|
29439
|
-
unit.textContent = input.unit;
|
|
29440
|
-
field.append(control, unit);
|
|
29441
|
-
return { field, control };
|
|
29442
|
-
}
|
|
29443
|
-
|
|
29444
30730
|
// src/settings/remote-connections-dialogs.ts
|
|
29445
30731
|
function createRemoteDialog({ container, signal, t }, title) {
|
|
29446
30732
|
if (signal.aborted || container.querySelector("dialog")) return null;
|
|
@@ -31120,31 +32406,6 @@ ${detail}` : ""}`
|
|
|
31120
32406
|
ownerWindow.addEventListener(CODEX_USAGE_BANNER_CHANGE_EVENT, syncUsageBanner);
|
|
31121
32407
|
usageBannerRow.item.append(usageBanner);
|
|
31122
32408
|
card.append(usageBannerRow.item);
|
|
31123
|
-
const liveVoiceId = preferenceId("cpa-live-voice");
|
|
31124
|
-
const liveVoiceRow = createPreferenceItem(document2, {
|
|
31125
|
-
title: messages.cpaLiveVoiceTitle,
|
|
31126
|
-
description: messages.cpaLiveVoiceDescription,
|
|
31127
|
-
controlId: liveVoiceId,
|
|
31128
|
-
help: { label: messages.cpaLiveVoiceHelpLabel, lines: messages.cpaLiveVoiceHelp }
|
|
31129
|
-
});
|
|
31130
|
-
const liveVoice = createPreferenceSwitch(document2, liveVoiceId, liveVoiceRow.description.id);
|
|
31131
|
-
liveVoice.checked = readCpaLiveVoicePreference(ownerWindow);
|
|
31132
|
-
liveVoice.addEventListener("change", () => {
|
|
31133
|
-
writeCpaLiveVoicePreference(ownerWindow, liveVoice.checked);
|
|
31134
|
-
});
|
|
31135
|
-
const syncLiveVoice = () => {
|
|
31136
|
-
liveVoice.checked = readCpaLiveVoicePreference(ownerWindow);
|
|
31137
|
-
};
|
|
31138
|
-
ownerWindow.addEventListener(CPA_LIVE_VOICE_CHANGE_EVENT, syncLiveVoice);
|
|
31139
|
-
liveVoiceRow.item.append(liveVoice);
|
|
31140
|
-
if (!readCpaLiveVoiceHookConfig(ownerWindow)) {
|
|
31141
|
-
const warning = document2.createElement("div");
|
|
31142
|
-
warning.className = "text-xs leading-[18px] text-settings-warning";
|
|
31143
|
-
warning.setAttribute("role", "status");
|
|
31144
|
-
warning.textContent = messages.cpaLiveVoiceRestartRequired;
|
|
31145
|
-
liveVoiceRow.description.after(warning);
|
|
31146
|
-
}
|
|
31147
|
-
card.append(liveVoiceRow.item);
|
|
31148
32409
|
const softWrapId = preferenceId("reasoning-soft-wrap");
|
|
31149
32410
|
const row = createPreferenceItem(document2, {
|
|
31150
32411
|
title: messages.reasoningSoftWrapTitle,
|
|
@@ -31170,7 +32431,6 @@ ${detail}` : ""}`
|
|
|
31170
32431
|
);
|
|
31171
32432
|
return () => {
|
|
31172
32433
|
ownerWindow.removeEventListener(CODEX_USAGE_BANNER_CHANGE_EVENT, syncUsageBanner);
|
|
31173
|
-
ownerWindow.removeEventListener(CPA_LIVE_VOICE_CHANGE_EVENT, syncLiveVoice);
|
|
31174
32434
|
ownerWindow.removeEventListener(REASONING_SOFT_WRAP_CHANGE_EVENT, sync);
|
|
31175
32435
|
disposeIdleRelease();
|
|
31176
32436
|
};
|
|
@@ -31403,7 +32663,7 @@ ${detail}` : ""}`
|
|
|
31403
32663
|
}
|
|
31404
32664
|
function defaultImportName(source, existing) {
|
|
31405
32665
|
const base = source.provider === "openai-codex" ? "codex" : "grok";
|
|
31406
|
-
const used = new Set(existing.map((
|
|
32666
|
+
const used = new Set(existing.map((record6) => record6.name));
|
|
31407
32667
|
const valid = (name) => credentialImportNameSchema.safeParse(name).success;
|
|
31408
32668
|
if (!used.has(base)) return base;
|
|
31409
32669
|
const local = source.label.includes("@") ? source.label.split("@")[0] ?? "" : "";
|
|
@@ -31426,7 +32686,7 @@ ${detail}` : ""}`
|
|
|
31426
32686
|
const shown = (text) => accountDisplayText(text, hideEmails);
|
|
31427
32687
|
const targetButtons = /* @__PURE__ */ new Map();
|
|
31428
32688
|
const importedRecords = () => snapshot.targets.find((target) => target.harnessId === TARGET_HARNESS_ID)?.imports ?? [];
|
|
31429
|
-
const sourceOf = (
|
|
32689
|
+
const sourceOf = (record6) => snapshot.sources.find((source) => source.id === record6.source.id);
|
|
31430
32690
|
const piTarget = () => snapshot.targets.find((candidate) => candidate.harnessId === TARGET_HARNESS_ID);
|
|
31431
32691
|
const compatibleSources = () => {
|
|
31432
32692
|
const target = piTarget();
|
|
@@ -31464,7 +32724,7 @@ ${detail}` : ""}`
|
|
|
31464
32724
|
sectionImport.addEventListener("click", () => {
|
|
31465
32725
|
const sources = compatibleSources();
|
|
31466
32726
|
const free = sources.find(
|
|
31467
|
-
(source2) => !importedRecords().some((
|
|
32727
|
+
(source2) => !importedRecords().some((record6) => record6.source.id === source2.id)
|
|
31468
32728
|
);
|
|
31469
32729
|
const source = free ?? sources[0];
|
|
31470
32730
|
if (source) openDialog("add", { source, choose: true }, SECTION_IMPORT_KEY);
|
|
@@ -31514,30 +32774,30 @@ ${detail}` : ""}`
|
|
|
31514
32774
|
mark.append(createRendererAgentIcon(agent ?? "pi", 26, document2, pluginFor(agent ?? "pi")));
|
|
31515
32775
|
return mark;
|
|
31516
32776
|
};
|
|
31517
|
-
const renderRow = (
|
|
32777
|
+
const renderRow = (record6) => {
|
|
31518
32778
|
const row = document2.createElement("div");
|
|
31519
32779
|
row.className = "settings-pi-accounts__row";
|
|
31520
32780
|
row.tabIndex = -1;
|
|
31521
|
-
row.dataset.importName =
|
|
31522
|
-
row.setAttribute("aria-label", shown(
|
|
31523
|
-
const agent =
|
|
32781
|
+
row.dataset.importName = record6.name;
|
|
32782
|
+
row.setAttribute("aria-label", shown(record6.source.label));
|
|
32783
|
+
const agent = record6.source.harnessId;
|
|
31524
32784
|
const mark = createMark(agent);
|
|
31525
32785
|
const identity = document2.createElement("div");
|
|
31526
32786
|
identity.className = "settings-pi-accounts__identity";
|
|
31527
32787
|
const label = document2.createElement("strong");
|
|
31528
32788
|
label.className = "settings-account-email";
|
|
31529
|
-
label.textContent = shown(
|
|
32789
|
+
label.textContent = shown(record6.source.label);
|
|
31530
32790
|
label.title = label.textContent;
|
|
31531
32791
|
label.translate = false;
|
|
31532
32792
|
const meta3 = document2.createElement("div");
|
|
31533
32793
|
meta3.className = "settings-account-metadata";
|
|
31534
|
-
const source = sourceOf(
|
|
32794
|
+
const source = sourceOf(record6);
|
|
31535
32795
|
const parts = [
|
|
31536
32796
|
metaPart(rendererAgentLabel(agent, pluginFor(agent)), "settings-pi-accounts__agent"),
|
|
31537
|
-
metaPart(`${
|
|
32797
|
+
metaPart(`${record6.name}/\u2026`, void 0, true),
|
|
31538
32798
|
metaPart(messages.copied)
|
|
31539
32799
|
];
|
|
31540
|
-
const time3 = formatImportedAt(
|
|
32800
|
+
const time3 = formatImportedAt(record6.importedAt);
|
|
31541
32801
|
if (time3) parts.push(metaPart(time3));
|
|
31542
32802
|
parts.forEach((part, index) => {
|
|
31543
32803
|
if (index > 0) {
|
|
@@ -31554,23 +32814,23 @@ ${detail}` : ""}`
|
|
|
31554
32814
|
reimport.type = "button";
|
|
31555
32815
|
reimport.className = "settings-account-action";
|
|
31556
32816
|
reimport.textContent = messages.rowReimport;
|
|
31557
|
-
reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(
|
|
32817
|
+
reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record6.source.label)}`);
|
|
31558
32818
|
reimport.disabled = busy || !source;
|
|
31559
32819
|
reimport.title = messages.reimport;
|
|
31560
32820
|
reimport.addEventListener("click", () => {
|
|
31561
|
-
if (source) openDialog("reimport", { source, record:
|
|
32821
|
+
if (source) openDialog("reimport", { source, record: record6 }, `row:${record6.name}`);
|
|
31562
32822
|
});
|
|
31563
32823
|
const remove = document2.createElement("button");
|
|
31564
32824
|
remove.type = "button";
|
|
31565
32825
|
remove.className = "settings-account-action settings-pi-accounts__remove";
|
|
31566
32826
|
remove.textContent = messages.rowRemove;
|
|
31567
|
-
remove.setAttribute("aria-label", `${messages.remove}: ${shown(
|
|
32827
|
+
remove.setAttribute("aria-label", `${messages.remove}: ${shown(record6.source.label)}`);
|
|
31568
32828
|
remove.disabled = busy;
|
|
31569
|
-
remove.addEventListener("click", () => openDialog("remove", { record:
|
|
32829
|
+
remove.addEventListener("click", () => openDialog("remove", { record: record6 }, `row:${record6.name}`));
|
|
31570
32830
|
if (source) actions.append(reimport);
|
|
31571
32831
|
actions.append(remove);
|
|
31572
32832
|
row.append(mark, identity, actions);
|
|
31573
|
-
rows.set(
|
|
32833
|
+
rows.set(record6.name, row);
|
|
31574
32834
|
return row;
|
|
31575
32835
|
};
|
|
31576
32836
|
const loginTypeLabel = (type) => type === "oauth" ? messages.typeOauth : type === "api_key" ? messages.typeApiKey : messages.typeOther;
|
|
@@ -31723,7 +32983,7 @@ ${detail}` : ""}`
|
|
|
31723
32983
|
const label = document2.createElement("strong");
|
|
31724
32984
|
label.textContent = shown(choice.label);
|
|
31725
32985
|
label.translate = false;
|
|
31726
|
-
const existing = importedRecords().find((
|
|
32986
|
+
const existing = importedRecords().find((record6) => record6.source.id === choice.id);
|
|
31727
32987
|
const agent = choice.harnessId;
|
|
31728
32988
|
const detail = document2.createElement("span");
|
|
31729
32989
|
detail.textContent = [
|
|
@@ -31764,7 +33024,7 @@ ${detail}` : ""}`
|
|
|
31764
33024
|
const name = request.action === "list" ? void 0 : request.name;
|
|
31765
33025
|
state = {
|
|
31766
33026
|
source: state.source,
|
|
31767
|
-
record: importedRecords().find((
|
|
33027
|
+
record: importedRecords().find((record6) => record6.name === name) ?? state.record
|
|
31768
33028
|
};
|
|
31769
33029
|
show(next);
|
|
31770
33030
|
} else {
|
|
@@ -31778,12 +33038,12 @@ ${detail}` : ""}`
|
|
|
31778
33038
|
sourceRadios = [];
|
|
31779
33039
|
body.replaceChildren();
|
|
31780
33040
|
controls.replaceChildren();
|
|
31781
|
-
const { source, record:
|
|
33041
|
+
const { source, record: record6 } = state;
|
|
31782
33042
|
const close = () => modal.close();
|
|
31783
33043
|
if (mode === "add" || mode === "reimport") {
|
|
31784
33044
|
title.textContent = mode === "add" ? messages.add : messages.reimport;
|
|
31785
33045
|
modal.setAttribute("aria-label", title.textContent);
|
|
31786
|
-
const active = source ??
|
|
33046
|
+
const active = source ?? record6?.source;
|
|
31787
33047
|
const choices = mode === "add" && state.choose ? compatibleSources() : [];
|
|
31788
33048
|
if (choices.length > 1) body.append(sourcePicker(choices));
|
|
31789
33049
|
else if (active) body.append(line(messages.source, shown(active.label)));
|
|
@@ -31792,8 +33052,8 @@ ${detail}` : ""}`
|
|
|
31792
33052
|
input.maxLength = 48;
|
|
31793
33053
|
input.autocomplete = "off";
|
|
31794
33054
|
input.spellcheck = false;
|
|
31795
|
-
input.value =
|
|
31796
|
-
input.readOnly = Boolean(
|
|
33055
|
+
input.value = record6?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
|
|
33056
|
+
input.readOnly = Boolean(record6);
|
|
31797
33057
|
input.addEventListener("input", () => {
|
|
31798
33058
|
nameEdited = true;
|
|
31799
33059
|
});
|
|
@@ -31827,7 +33087,7 @@ ${detail}` : ""}`
|
|
|
31827
33087
|
{
|
|
31828
33088
|
action: mode === "reimport" ? "reimport" : "import",
|
|
31829
33089
|
sourceId: source2.id,
|
|
31830
|
-
name:
|
|
33090
|
+
name: record6?.name ?? input.value,
|
|
31831
33091
|
confirmed: true
|
|
31832
33092
|
},
|
|
31833
33093
|
"done"
|
|
@@ -31837,16 +33097,16 @@ ${detail}` : ""}`
|
|
|
31837
33097
|
)
|
|
31838
33098
|
);
|
|
31839
33099
|
(mode === "add" ? input : controls.children[0]).focus();
|
|
31840
|
-
} else if (mode === "remove" &&
|
|
33100
|
+
} else if (mode === "remove" && record6) {
|
|
31841
33101
|
title.textContent = messages.remove;
|
|
31842
33102
|
modal.setAttribute("aria-label", title.textContent);
|
|
31843
|
-
body.append(note(messages.removeWarning.replace("{name}",
|
|
33103
|
+
body.append(note(messages.removeWarning.replace("{name}", record6.name)));
|
|
31844
33104
|
const cancel = command(messages.cancel, close);
|
|
31845
33105
|
controls.append(
|
|
31846
33106
|
cancel,
|
|
31847
33107
|
command(
|
|
31848
33108
|
messages.remove,
|
|
31849
|
-
() => submit({ action: "remove", name:
|
|
33109
|
+
() => submit({ action: "remove", name: record6.name, confirmed: true }, null),
|
|
31850
33110
|
"danger"
|
|
31851
33111
|
)
|
|
31852
33112
|
);
|
|
@@ -31854,7 +33114,7 @@ ${detail}` : ""}`
|
|
|
31854
33114
|
} else {
|
|
31855
33115
|
title.textContent = messages.doneTitle;
|
|
31856
33116
|
modal.setAttribute("aria-label", title.textContent);
|
|
31857
|
-
const name =
|
|
33117
|
+
const name = record6?.name;
|
|
31858
33118
|
if (name) body.append(line(messages.entry, `${name}/\u2026`, true));
|
|
31859
33119
|
body.append(note(messages.done));
|
|
31860
33120
|
const done = command(messages.close, close, "primary");
|
|
@@ -31901,21 +33161,21 @@ ${detail}` : ""}`
|
|
|
31901
33161
|
(candidate) => candidate.harnessId === TARGET_HARNESS_ID && source && candidate.providers.includes(source.provider)
|
|
31902
33162
|
);
|
|
31903
33163
|
if (!source || !target) return null;
|
|
31904
|
-
const
|
|
33164
|
+
const record6 = target.imports.find((candidate) => candidate.source.id === source.id);
|
|
31905
33165
|
const key = `${harnessId}:${accountLabel}:import`;
|
|
31906
33166
|
const button2 = document2.createElement("button");
|
|
31907
33167
|
button2.type = "button";
|
|
31908
33168
|
button2.className = "settings-account-pi-import";
|
|
31909
33169
|
button2.dataset.accountFocus = key;
|
|
31910
33170
|
button2.disabled = busy;
|
|
31911
|
-
const hint =
|
|
33171
|
+
const hint = record6 ? messages.importedHint.replace("{name}", record6.name) : messages.add;
|
|
31912
33172
|
button2.title = hint;
|
|
31913
33173
|
button2.setAttribute("aria-label", hint);
|
|
31914
33174
|
button2.append(createRendererAgentIcon("pi", 12, document2, pluginFor("pi")));
|
|
31915
|
-
if (
|
|
33175
|
+
if (record6) {
|
|
31916
33176
|
button2.dataset.state = "imported";
|
|
31917
33177
|
const name = document2.createElement("code");
|
|
31918
|
-
name.textContent = `${
|
|
33178
|
+
name.textContent = `${record6.name}/\u2026`;
|
|
31919
33179
|
name.translate = false;
|
|
31920
33180
|
button2.append(name, createRendererSettingsIcon("check", 12));
|
|
31921
33181
|
} else {
|
|
@@ -31923,7 +33183,7 @@ ${detail}` : ""}`
|
|
|
31923
33183
|
button2.append(messages.add);
|
|
31924
33184
|
}
|
|
31925
33185
|
button2.addEventListener("click", () => {
|
|
31926
|
-
if (!
|
|
33186
|
+
if (!record6) {
|
|
31927
33187
|
openDialog("add", { source }, key);
|
|
31928
33188
|
return;
|
|
31929
33189
|
}
|
|
@@ -31932,7 +33192,7 @@ ${detail}` : ""}`
|
|
|
31932
33192
|
renderSection();
|
|
31933
33193
|
sectionToggle.setAttribute("aria-expanded", "true");
|
|
31934
33194
|
}
|
|
31935
|
-
const row = rows.get(
|
|
33195
|
+
const row = rows.get(record6.name);
|
|
31936
33196
|
row?.scrollIntoView({ block: "nearest", behavior: "smooth" });
|
|
31937
33197
|
row?.focus();
|
|
31938
33198
|
});
|
|
@@ -33477,7 +34737,7 @@ ${detail}` : ""}`
|
|
|
33477
34737
|
}
|
|
33478
34738
|
});
|
|
33479
34739
|
}
|
|
33480
|
-
function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable")), getLoadedSessionsClient = () => null, getRemoteConnections = () => null, requestUsageStatistics = () => Promise.reject(new Error("Local Host connection is unavailable"))) {
|
|
34740
|
+
function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable")), getLoadedSessionsClient = () => null, getRemoteConnections = () => null, requestUsageStatistics = () => Promise.reject(new Error("Local Host connection is unavailable")), requestVoiceSettings = () => Promise.reject(new Error("Local Host connection is unavailable"))) {
|
|
33481
34741
|
return Object.freeze([
|
|
33482
34742
|
createConnectionsSettingsPage(messages, getDiagnostics, void 0, getRemoteConnections),
|
|
33483
34743
|
createRemoteConnectionsPage(messages, getRemoteConnections),
|
|
@@ -33494,6 +34754,7 @@ ${detail}` : ""}`
|
|
|
33494
34754
|
messages.locale
|
|
33495
34755
|
),
|
|
33496
34756
|
createAppearanceSettingsPage(messages, getLoadedSessionsClient),
|
|
34757
|
+
createVoiceSettingsPage(messages.locale, requestVoiceSettings, { desktop: true }),
|
|
33497
34758
|
updatesPage(messages, getUpdateClient),
|
|
33498
34759
|
aboutPage(messages, getUpdateClient)
|
|
33499
34760
|
]);
|
|
@@ -36051,6 +37312,97 @@ ${detail}` : ""}`
|
|
|
36051
37312
|
animation: none !important;
|
|
36052
37313
|
}
|
|
36053
37314
|
}
|
|
37315
|
+
.settings-voice__select {
|
|
37316
|
+
flex: none;
|
|
37317
|
+
width: 190px;
|
|
37318
|
+
max-width: 100%;
|
|
37319
|
+
min-height: 34px;
|
|
37320
|
+
padding: 6px 10px;
|
|
37321
|
+
border: 1px solid var(--settings-border);
|
|
37322
|
+
border-radius: 6px;
|
|
37323
|
+
color: var(--settings-text);
|
|
37324
|
+
background: var(--settings-panel);
|
|
37325
|
+
font: inherit;
|
|
37326
|
+
font-size: 13px;
|
|
37327
|
+
}
|
|
37328
|
+
|
|
37329
|
+
.settings-voice :disabled {
|
|
37330
|
+
opacity: 0.45;
|
|
37331
|
+
cursor: not-allowed;
|
|
37332
|
+
}
|
|
37333
|
+
.settings-voice__footer {
|
|
37334
|
+
display: flex;
|
|
37335
|
+
align-items: center;
|
|
37336
|
+
justify-content: space-between;
|
|
37337
|
+
flex-wrap: wrap;
|
|
37338
|
+
gap: 16px;
|
|
37339
|
+
margin-top: 28px;
|
|
37340
|
+
padding-top: 18px;
|
|
37341
|
+
border-top: 1px solid var(--settings-divider);
|
|
37342
|
+
font-size: 13px;
|
|
37343
|
+
}
|
|
37344
|
+
.settings-voice__footer p,
|
|
37345
|
+
.settings-voice__hint {
|
|
37346
|
+
margin: 4px 0 0;
|
|
37347
|
+
color: var(--settings-muted);
|
|
37348
|
+
font-size: 12px;
|
|
37349
|
+
line-height: 18px;
|
|
37350
|
+
}
|
|
37351
|
+
.settings-voice__actions,
|
|
37352
|
+
.settings-voice__gateway-actions {
|
|
37353
|
+
display: flex;
|
|
37354
|
+
align-items: center;
|
|
37355
|
+
flex-wrap: wrap;
|
|
37356
|
+
gap: 12px;
|
|
37357
|
+
}
|
|
37358
|
+
.settings-voice__gateway-actions {
|
|
37359
|
+
color: var(--settings-muted);
|
|
37360
|
+
font-size: 12px;
|
|
37361
|
+
}
|
|
37362
|
+
.settings-voice__details {
|
|
37363
|
+
padding: 12px 16px;
|
|
37364
|
+
border-top: 1px solid var(--settings-divider);
|
|
37365
|
+
color: var(--settings-muted);
|
|
37366
|
+
font-size: 12px;
|
|
37367
|
+
line-height: 18px;
|
|
37368
|
+
overflow-wrap: anywhere;
|
|
37369
|
+
}
|
|
37370
|
+
.settings-voice__confirmation {
|
|
37371
|
+
margin-top: 12px;
|
|
37372
|
+
font-size: 13px;
|
|
37373
|
+
line-height: 20px;
|
|
37374
|
+
}
|
|
37375
|
+
.settings-voice__confirmation button + button {
|
|
37376
|
+
margin-left: 8px;
|
|
37377
|
+
}
|
|
37378
|
+
.settings-voice [role="alert"] {
|
|
37379
|
+
color: var(--settings-danger);
|
|
37380
|
+
font-size: 13px;
|
|
37381
|
+
overflow-wrap: anywhere;
|
|
37382
|
+
}
|
|
37383
|
+
.settings-voice {
|
|
37384
|
+
container-type: inline-size;
|
|
37385
|
+
}
|
|
37386
|
+
@container (max-width: 620px) {
|
|
37387
|
+
.settings-voice__row {
|
|
37388
|
+
align-items: stretch;
|
|
37389
|
+
flex-direction: column;
|
|
37390
|
+
gap: 10px;
|
|
37391
|
+
}
|
|
37392
|
+
.settings-voice__select {
|
|
37393
|
+
width: 100%;
|
|
37394
|
+
}
|
|
37395
|
+
.settings-voice__row input[role="switch"] {
|
|
37396
|
+
align-self: flex-start;
|
|
37397
|
+
}
|
|
37398
|
+
.settings-voice__footer {
|
|
37399
|
+
align-items: stretch;
|
|
37400
|
+
flex-direction: column;
|
|
37401
|
+
}
|
|
37402
|
+
.settings-voice__actions > button {
|
|
37403
|
+
flex: 1;
|
|
37404
|
+
}
|
|
37405
|
+
}
|
|
36054
37406
|
`;
|
|
36055
37407
|
|
|
36056
37408
|
// src/settings/accounts.css
|
|
@@ -36942,6 +38294,17 @@ ${detail}` : ""}`
|
|
|
36942
38294
|
gap: 8px;
|
|
36943
38295
|
}
|
|
36944
38296
|
|
|
38297
|
+
.console-restart {
|
|
38298
|
+
width: 100%;
|
|
38299
|
+
min-width: 0;
|
|
38300
|
+
}
|
|
38301
|
+
|
|
38302
|
+
.console-restart > p {
|
|
38303
|
+
flex-basis: 100%;
|
|
38304
|
+
margin: 0;
|
|
38305
|
+
overflow-wrap: anywhere;
|
|
38306
|
+
}
|
|
38307
|
+
|
|
36945
38308
|
.console-muted {
|
|
36946
38309
|
margin: 0;
|
|
36947
38310
|
color: var(--settings-muted);
|
|
@@ -38099,7 +39462,7 @@ th[aria-sort] .console-usage-sort__mark {
|
|
|
38099
39462
|
`;
|
|
38100
39463
|
|
|
38101
39464
|
// src/settings/tailwind.css
|
|
38102
|
-
var tailwind_default = '@layer properties, theme, base, components, utilities;\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.top-full{top:100%}.left-0{left:0}.z-20{z-index:20}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-7{margin-top:calc(var(--spacing) * 7)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:var(--spacing)}.ml-\\[45px\\]{margin-left:45px}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.list-item{display:list-item}.table{display:table}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-8{height:calc(var(--spacing) * 8)}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-\\[60px\\]{min-height:60px}.w-9{width:calc(var(--spacing) * 9)}.w-14{width:calc(var(--spacing) * 14)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-px{width:1px}.max-w-64{max-width:calc(var(--spacing) * 64)}.min-w-0{min-width:0}.flex-shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-x-auto{overflow-x:auto}.rounded-\\[10px\\]{border-radius:10px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-settings-border{border-color:var(--settings-border)}.border-settings-divider{border-color:var(--settings-divider)}.bg-settings-panel{background-color:var(--settings-panel)}.bg-settings-subtle{background-color:var(--settings-subtle)}.bg-settings-surface{background-color:var(--settings-surface)}.bg-settings-surface-hover{background-color:var(--settings-surface-hover)}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-4{padding:calc(var(--spacing) * 4)}.\\!px-0{padding-inline:0!important}.px-1{padding-inline:var(--spacing)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pl-4{padding-left:calc(var(--spacing) * 4)}.\\!text-right{text-align:right!important}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[11px\\]{font-size:11px}.text-\\[13px\\]{font-size:13px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.text-wrap{text-wrap:wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.text-settings-muted{color:var(--settings-muted)}.text-settings-subtle{color:var(--settings-subtle)}.text-settings-text{color:var(--settings-text)}.text-settings-warning{color:var(--settings-warning)}.lowercase{text-transform:lowercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\\[0_10px_30px_rgb\\(0_0_0\\/0\\.22\\)\\]{--tw-shadow:0 10px 30px var(--tw-shadow-color,#00000038);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-settings-border{--tw-ring-color:var(--settings-border)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.ring-inset{--tw-ring-inset:inset}.group-focus-within\\:visible:is(:where(.group):focus-within *){visibility:visible}.group-focus-within\\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\\:visible:is(:where(.group):hover *){visibility:visible}.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}}.group-data-\\[state\\=failed\\]\\/status\\:bg-settings-danger:is(:where(.group\\/status)[data-state=failed] *){background-color:var(--settings-danger)}.group-data-\\[state\\=unavailable\\]\\/status\\:bg-settings-warning:is(:where(.group\\/status)[data-state=unavailable] *){background-color:var(--settings-warning)}.marker\\:text-settings-subtle ::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle ::-webkit-details-marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::-webkit-details-marker{color:var(--settings-subtle)}.before\\:absolute:before{content:var(--tw-content);position:absolute}.before\\:top-0\\.5:before{content:var(--tw-content);top:calc(var(--spacing) * .5)}.before\\:left-0\\.5:before{content:var(--tw-content);left:calc(var(--spacing) * .5)}.before\\:size-4:before{content:var(--tw-content);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.before\\:rounded-full:before{content:var(--tw-content);border-radius:3.40282e38px}.before\\:bg-white:before{content:var(--tw-content);background-color:#fff}.before\\:shadow-\\[0_1px_2px_rgb\\(0_0_0\\/0\\.3\\)\\]:before{content:var(--tw-content);--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.before\\:transition-transform:before{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.first\\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}.first-of-type\\:mt-0:first-of-type{margin-top:0}.checked\\:bg-settings-focus:checked{background-color:var(--settings-focus)}.checked\\:ring-transparent:checked{--tw-ring-color:transparent}.checked\\:before\\:translate-x-4:checked:before{content:var(--tw-content);--tw-translate-x:calc(var(--spacing) * 4);translate:var(--tw-translate-x) var(--tw-translate-y)}.focus-within\\:border-settings-focus:focus-within{border-color:var(--settings-focus)}@media (hover:hover){.hover\\:text-settings-text:hover{color:var(--settings-text)}}.focus-visible\\:text-settings-text:focus-visible{color:var(--settings-text)}.focus-visible\\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-settings-focus:focus-visible{outline-color:var(--settings-focus)}.data-\\[invalid\\=true\\]\\:border-settings-danger[data-invalid=true]{border-color:var(--settings-danger)}.data-\\[invalid\\=true\\]\\:text-settings-danger[data-invalid=true],.data-\\[state\\=failed\\]\\:text-settings-danger[data-state=failed]{color:var(--settings-danger)}.data-\\[state\\=unavailable\\]\\:text-settings-warning[data-state=unavailable]{color:var(--settings-warning)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@layer properties{\n *, ::before, ::after, ::backdrop{--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-alpha:100%;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-offset-width:0;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-drop-shadow-alpha:100%;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}\n';
|
|
39465
|
+
var tailwind_default = '@layer properties, theme, base, components, utilities;\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.top-full{top:100%}.left-0{left:0}.z-20{z-index:20}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-7{margin-top:calc(var(--spacing) * 7)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-16{margin-top:calc(var(--spacing) * 16)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:var(--spacing)}.ml-\\[45px\\]{margin-left:45px}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.list-item{display:list-item}.table{display:table}.size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-8{height:calc(var(--spacing) * 8)}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-\\[60px\\]{min-height:60px}.w-9{width:calc(var(--spacing) * 9)}.w-14{width:calc(var(--spacing) * 14)}.w-80{width:calc(var(--spacing) * 80)}.w-full{width:100%}.w-px{width:1px}.max-w-64{max-width:calc(var(--spacing) * 64)}.min-w-0{min-width:0}.flex-shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.overflow-x-auto{overflow-x:auto}.rounded-\\[10px\\]{border-radius:10px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-settings-border{border-color:var(--settings-border)}.border-settings-divider{border-color:var(--settings-divider)}.bg-settings-panel{background-color:var(--settings-panel)}.bg-settings-subtle{background-color:var(--settings-subtle)}.bg-settings-surface{background-color:var(--settings-surface)}.bg-settings-surface-hover{background-color:var(--settings-surface-hover)}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-4{padding:calc(var(--spacing) * 4)}.\\!px-0{padding-inline:0!important}.px-1{padding-inline:var(--spacing)}.px-2\\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pl-4{padding-left:calc(var(--spacing) * 4)}.\\!text-right{text-align:right!important}.text-left{text-align:left}.text-right{text-align:right}.align-top{vertical-align:top}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[11px\\]{font-size:11px}.text-\\[13px\\]{font-size:13px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.text-wrap{text-wrap:wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.text-settings-muted{color:var(--settings-muted)}.text-settings-subtle{color:var(--settings-subtle)}.text-settings-text{color:var(--settings-text)}.lowercase{text-transform:lowercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\\[0_10px_30px_rgb\\(0_0_0\\/0\\.22\\)\\]{--tw-shadow:0 10px 30px var(--tw-shadow-color,#00000038);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-settings-border{--tw-ring-color:var(--settings-border)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.ring-inset{--tw-ring-inset:inset}.group-focus-within\\:visible:is(:where(.group):focus-within *){visibility:visible}.group-focus-within\\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\\:visible:is(:where(.group):hover *){visibility:visible}.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}}.group-data-\\[state\\=failed\\]\\/status\\:bg-settings-danger:is(:where(.group\\/status)[data-state=failed] *){background-color:var(--settings-danger)}.group-data-\\[state\\=unavailable\\]\\/status\\:bg-settings-warning:is(:where(.group\\/status)[data-state=unavailable] *){background-color:var(--settings-warning)}.marker\\:text-settings-subtle ::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle ::-webkit-details-marker{color:var(--settings-subtle)}.marker\\:text-settings-subtle::-webkit-details-marker{color:var(--settings-subtle)}.before\\:absolute:before{content:var(--tw-content);position:absolute}.before\\:top-0\\.5:before{content:var(--tw-content);top:calc(var(--spacing) * .5)}.before\\:left-0\\.5:before{content:var(--tw-content);left:calc(var(--spacing) * .5)}.before\\:size-4:before{content:var(--tw-content);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.before\\:rounded-full:before{content:var(--tw-content);border-radius:3.40282e38px}.before\\:bg-white:before{content:var(--tw-content);background-color:#fff}.before\\:shadow-\\[0_1px_2px_rgb\\(0_0_0\\/0\\.3\\)\\]:before{content:var(--tw-content);--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.before\\:transition-transform:before{content:var(--tw-content);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.first\\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}.first-of-type\\:mt-0:first-of-type{margin-top:0}.checked\\:bg-settings-focus:checked{background-color:var(--settings-focus)}.checked\\:ring-transparent:checked{--tw-ring-color:transparent}.checked\\:before\\:translate-x-4:checked:before{content:var(--tw-content);--tw-translate-x:calc(var(--spacing) * 4);translate:var(--tw-translate-x) var(--tw-translate-y)}.focus-within\\:border-settings-focus:focus-within{border-color:var(--settings-focus)}@media (hover:hover){.hover\\:text-settings-text:hover{color:var(--settings-text)}}.focus-visible\\:text-settings-text:focus-visible{color:var(--settings-text)}.focus-visible\\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-settings-focus:focus-visible{outline-color:var(--settings-focus)}.data-\\[invalid\\=true\\]\\:border-settings-danger[data-invalid=true]{border-color:var(--settings-danger)}.data-\\[invalid\\=true\\]\\:text-settings-danger[data-invalid=true],.data-\\[state\\=failed\\]\\:text-settings-danger[data-state=failed]{color:var(--settings-danger)}.data-\\[state\\=unavailable\\]\\:text-settings-warning[data-state=unavailable]{color:var(--settings-warning)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@layer properties{\n *, ::before, ::after, ::backdrop{--tw-border-style:solid;--tw-shadow:0 0 #0000;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-alpha:100%;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-offset-width:0;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-drop-shadow-alpha:100%;--tw-content:"";--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}\n';
|
|
38103
39466
|
|
|
38104
39467
|
// src/settings/trigger.ts
|
|
38105
39468
|
var SETTINGS_TRIGGER_ATTRIBUTE = "data-codexhost-settings-trigger";
|
|
@@ -38344,7 +39707,7 @@ th[aria-sort] .console-usage-sort__mark {
|
|
|
38344
39707
|
place();
|
|
38345
39708
|
const observer = ownerWindow ? new ownerWindow.MutationObserver((records) => {
|
|
38346
39709
|
const titlebar = source?.closest("[data-app-shell-titlebar]");
|
|
38347
|
-
if (!source?.isConnected || records.some((
|
|
39710
|
+
if (!source?.isConnected || records.some((record6) => titlebar?.contains(record6.target))) {
|
|
38348
39711
|
place();
|
|
38349
39712
|
}
|
|
38350
39713
|
}) : null;
|
|
@@ -38778,7 +40141,8 @@ ${usage_default}`;
|
|
|
38778
40141
|
},
|
|
38779
40142
|
options.getLoadedSessionsClient ?? (() => null),
|
|
38780
40143
|
options.getRemoteConnections ?? (() => null),
|
|
38781
|
-
options.requestUsageStatistics
|
|
40144
|
+
options.requestUsageStatistics,
|
|
40145
|
+
options.requestVoiceSettings
|
|
38782
40146
|
);
|
|
38783
40147
|
const nextShell = installRendererSettingsShell(definitions, messages, ownerWindow.document, {
|
|
38784
40148
|
onOpenChange(open) {
|
|
@@ -39855,7 +41219,14 @@ ${usage_default}`;
|
|
|
39855
41219
|
});
|
|
39856
41220
|
let connectionDiagnostics = null;
|
|
39857
41221
|
const remoteConnections = createRemoteConnectionsControl(window, modelClientForHost);
|
|
41222
|
+
const requestLocalSettings = async (method, params) => {
|
|
41223
|
+
const route = window.__codexhostHostRoutingV1?.forHost("local");
|
|
41224
|
+
if (disposed || !route) throw new Error("Local Host connection is unavailable");
|
|
41225
|
+
return route.manager.sendRequest(method, params);
|
|
41226
|
+
};
|
|
41227
|
+
const stopVoiceSync = startVoiceSettingsSync(window, requestLocalSettings);
|
|
39858
41228
|
const settingsLifecycle = installRendererSettingsLifecycle(window, {
|
|
41229
|
+
requestVoiceSettings: (params) => requestLocalSettings("codexhost/voice/settings", params),
|
|
39859
41230
|
getRemoteConnections: () => remoteConnections,
|
|
39860
41231
|
getUpdateClient: () => modelControl,
|
|
39861
41232
|
getAccountClient: () => modelControl,
|
|
@@ -41901,6 +43272,7 @@ ${usage_default}`;
|
|
|
41901
43272
|
disposeReasoningSoftWrap();
|
|
41902
43273
|
delegationMention?.dispose();
|
|
41903
43274
|
sidebarAgentIcons.dispose();
|
|
43275
|
+
stopVoiceSync();
|
|
41904
43276
|
settingsLifecycle.dispose();
|
|
41905
43277
|
document.removeEventListener("beforeinput", onBeforeInput, true);
|
|
41906
43278
|
document.removeEventListener("submit", onSubmit, true);
|
|
@@ -41961,14 +43333,16 @@ ${usage_default}`;
|
|
|
41961
43333
|
}
|
|
41962
43334
|
|
|
41963
43335
|
// src/renderer-external-voice-launch.ts
|
|
41964
|
-
var
|
|
43336
|
+
var HOOK_GLOBAL3 = "__codexhostExternalVoiceLaunchV1";
|
|
41965
43337
|
var SHARED_ASSET = "app-shared-8bd9d0399038.js";
|
|
41966
43338
|
function isRecord16(value) {
|
|
41967
43339
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41968
43340
|
}
|
|
41969
43341
|
function routeExternalVoiceLaunch(request, routing) {
|
|
43342
|
+
rememberVoiceProductExperience(request);
|
|
41970
43343
|
if (!routing || !isRecord16(request) || request.source !== "composer_button_new_thread")
|
|
41971
43344
|
return request;
|
|
43345
|
+
if (request.productExperience === "chat") return request;
|
|
41972
43346
|
const hostId2 = request.hostId ?? "local";
|
|
41973
43347
|
if (typeof hostId2 !== "string" || !hostId2) return request;
|
|
41974
43348
|
const route = routing.forComposer();
|
|
@@ -41994,12 +43368,12 @@ ${usage_default}`;
|
|
|
41994
43368
|
}
|
|
41995
43369
|
function installExternalVoiceLaunchHook(options = {}) {
|
|
41996
43370
|
const target = options.target ?? globalThis;
|
|
41997
|
-
const existing = target[
|
|
43371
|
+
const existing = target[HOOK_GLOBAL3];
|
|
41998
43372
|
if (existing) return existing;
|
|
41999
43373
|
const config2 = readCpaLiveVoiceHookConfig(target);
|
|
42000
43374
|
if (!config2) return { status: "disabled", dispose() {
|
|
42001
43375
|
} };
|
|
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)
|
|
43376
|
+
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
43377
|
return { status: "unsupported", dispose() {
|
|
42004
43378
|
} };
|
|
42005
43379
|
const importModule = options.importModule ?? ((url2) => import(url2));
|
|
@@ -42014,22 +43388,22 @@ ${usage_default}`;
|
|
|
42014
43388
|
disposed = true;
|
|
42015
43389
|
if (timer !== void 0) target.clearTimeout(timer);
|
|
42016
43390
|
restore?.();
|
|
42017
|
-
if (target[
|
|
43391
|
+
if (target[HOOK_GLOBAL3] === handle) Reflect.deleteProperty(target, HOOK_GLOBAL3);
|
|
42018
43392
|
}
|
|
42019
43393
|
};
|
|
42020
|
-
target[
|
|
43394
|
+
target[HOOK_GLOBAL3] = handle;
|
|
42021
43395
|
const attempt = async () => {
|
|
42022
43396
|
if (disposed) return;
|
|
42023
43397
|
try {
|
|
42024
|
-
const names = target.
|
|
42025
|
-
|
|
42026
|
-
|
|
42027
|
-
|
|
42028
|
-
|
|
42029
|
-
|
|
42030
|
-
|
|
43398
|
+
const names = loadedAssetNames(target.document, target.performance);
|
|
43399
|
+
const clientOwned = auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_INITIAL_ASSET) && auditedAppInitialAssetPresent(names, CLIENT_OWNED_VOICE_SHARED_ASSET);
|
|
43400
|
+
const legacy = auditedAppInitialAssetPresent(names, AUDITED_CPA_LIVE_VOICE_APP_INITIAL_ASSET) && auditedAppInitialAssetPresent(names, SHARED_ASSET);
|
|
43401
|
+
if (clientOwned || legacy) {
|
|
43402
|
+
module ??= await importModule(
|
|
43403
|
+
`app://-/assets/${clientOwned ? CLIENT_OWNED_VOICE_SHARED_ASSET : SHARED_ASSET}`
|
|
43404
|
+
);
|
|
42031
43405
|
if (disposed) return;
|
|
42032
|
-
const services = module?.fN;
|
|
43406
|
+
const services = clientOwned ? module?.Kat : module?.fN;
|
|
42033
43407
|
if (isRecord16(services)) {
|
|
42034
43408
|
const original = services.realtimeVoiceRuntime;
|
|
42035
43409
|
if (typeof original === "function" || isRecord16(original)) {
|
|
@@ -42040,6 +43414,8 @@ ${usage_default}`;
|
|
|
42040
43414
|
}
|
|
42041
43415
|
const launch = (...args) => {
|
|
42042
43416
|
let request = args[0];
|
|
43417
|
+
const chatStart = startNativeChatVoiceForRequest(request, target);
|
|
43418
|
+
if (chatStart) return chatStart;
|
|
42043
43419
|
try {
|
|
42044
43420
|
request = routeExternalVoiceLaunch(request, target.__codexhostHostRoutingV1);
|
|
42045
43421
|
} catch {
|
|
@@ -42080,7 +43456,9 @@ ${usage_default}`;
|
|
|
42080
43456
|
|
|
42081
43457
|
// src/production-entry.ts
|
|
42082
43458
|
installCpaLiveVoiceHook();
|
|
43459
|
+
installClientOwnedVoiceHook();
|
|
42083
43460
|
installExternalVoiceLaunchHook();
|
|
43461
|
+
installNativeChatVoiceHook();
|
|
42084
43462
|
var installBinding = () => {
|
|
42085
43463
|
installRendererBinding();
|
|
42086
43464
|
};
|