@codexhost/cli-linux-x64 0.3.0-test.1 → 0.3.0-test.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/desktop-controller.mjs +19 -120
- package/app/host-runtime.mjs +78 -5
- package/app/renderer-extension.js +344 -151
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
|
@@ -18032,6 +18032,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18032
18032
|
isConnected() {
|
|
18033
18033
|
return this.element.isConnected;
|
|
18034
18034
|
}
|
|
18035
|
+
hostId() {
|
|
18036
|
+
return sidebarThreadAttributes(this.element)?.hostId ?? null;
|
|
18037
|
+
}
|
|
18035
18038
|
threadId() {
|
|
18036
18039
|
return threadIdFromSidebarRowElement(this.element);
|
|
18037
18040
|
}
|
|
@@ -18101,7 +18104,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18101
18104
|
const observer = new MutationObserver(onChange);
|
|
18102
18105
|
observer.observe(this.root, {
|
|
18103
18106
|
attributes: true,
|
|
18104
|
-
attributeFilter: [SIDEBAR_THREAD_ID_ATTRIBUTE],
|
|
18107
|
+
attributeFilter: [SIDEBAR_THREAD_ID_ATTRIBUTE, SIDEBAR_THREAD_HOST_ID_ATTRIBUTE],
|
|
18105
18108
|
childList: true,
|
|
18106
18109
|
subtree: true
|
|
18107
18110
|
});
|
|
@@ -18122,78 +18125,88 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18122
18125
|
const ownershipRetryTimers = /* @__PURE__ */ new Map();
|
|
18123
18126
|
let disposed = false;
|
|
18124
18127
|
let scanScheduled = false;
|
|
18128
|
+
const ownershipKey = (hostId, threadId) => JSON.stringify([hostId, threadId]);
|
|
18125
18129
|
const scheduleScan = () => {
|
|
18126
18130
|
if (disposed || scanScheduled) return;
|
|
18127
18131
|
scanScheduled = true;
|
|
18128
18132
|
queueMicrotask(scan);
|
|
18129
18133
|
};
|
|
18130
|
-
const clearOwnershipRetry = (
|
|
18131
|
-
const timer = ownershipRetryTimers.get(
|
|
18134
|
+
const clearOwnershipRetry = (key) => {
|
|
18135
|
+
const timer = ownershipRetryTimers.get(key);
|
|
18132
18136
|
if (timer !== void 0) clearTimeout(timer);
|
|
18133
|
-
ownershipRetryTimers.delete(
|
|
18134
|
-
ownershipRetryAttempts.delete(
|
|
18135
|
-
provisionalCodex.delete(
|
|
18137
|
+
ownershipRetryTimers.delete(key);
|
|
18138
|
+
ownershipRetryAttempts.delete(key);
|
|
18139
|
+
provisionalCodex.delete(key);
|
|
18136
18140
|
};
|
|
18137
|
-
const scheduleOwnershipRetry = (threadId) => {
|
|
18138
|
-
|
|
18141
|
+
const scheduleOwnershipRetry = (hostId, threadId) => {
|
|
18142
|
+
const key = ownershipKey(hostId, threadId);
|
|
18143
|
+
if (disposed || !provisionalCodex.has(key) || pending.has(key) || ownershipRetryTimers.has(key)) {
|
|
18139
18144
|
return;
|
|
18140
18145
|
}
|
|
18141
|
-
const attempt = ownershipRetryAttempts.get(
|
|
18146
|
+
const attempt = ownershipRetryAttempts.get(key) ?? 0;
|
|
18142
18147
|
const delay = OWNERSHIP_RETRY_DELAYS_MS[attempt];
|
|
18143
18148
|
if (delay === void 0) return;
|
|
18144
|
-
ownershipRetryAttempts.set(
|
|
18149
|
+
ownershipRetryAttempts.set(key, attempt + 1);
|
|
18145
18150
|
const timer = setTimeout(() => {
|
|
18146
|
-
ownershipRetryTimers.delete(
|
|
18151
|
+
ownershipRetryTimers.delete(key);
|
|
18147
18152
|
if (disposed) return;
|
|
18148
|
-
failed.delete(
|
|
18149
|
-
ownershipByThread.delete(
|
|
18153
|
+
failed.delete(key);
|
|
18154
|
+
ownershipByThread.delete(key);
|
|
18150
18155
|
scheduleScan();
|
|
18151
18156
|
}, delay);
|
|
18152
|
-
ownershipRetryTimers.set(
|
|
18157
|
+
ownershipRetryTimers.set(key, timer);
|
|
18153
18158
|
};
|
|
18154
|
-
const requestOwnership = (threadIds, client) => {
|
|
18155
|
-
for (const threadId of threadIds) pending.add(threadId);
|
|
18159
|
+
const requestOwnership = (hostId, threadIds, client) => {
|
|
18160
|
+
for (const threadId of threadIds) pending.add(ownershipKey(hostId, threadId));
|
|
18156
18161
|
let succeeded = false;
|
|
18157
18162
|
void Promise.resolve().then(() => client.listThreadOwnership({ threadIds })).then(({ threads }) => {
|
|
18158
18163
|
if (disposed) return;
|
|
18159
18164
|
for (const ownership of threads) {
|
|
18160
|
-
|
|
18161
|
-
|
|
18165
|
+
const key = ownershipKey(hostId, ownership.threadId);
|
|
18166
|
+
ownershipByThread.set(key, rendererAgentForThreadOwnership(ownership));
|
|
18167
|
+
failed.delete(key);
|
|
18162
18168
|
if (ownership.owner === "codex") {
|
|
18163
|
-
provisionalCodex.add(
|
|
18164
|
-
scheduleOwnershipRetry(ownership.threadId);
|
|
18169
|
+
provisionalCodex.add(key);
|
|
18170
|
+
scheduleOwnershipRetry(hostId, ownership.threadId);
|
|
18165
18171
|
} else {
|
|
18166
|
-
clearOwnershipRetry(
|
|
18172
|
+
clearOwnershipRetry(key);
|
|
18167
18173
|
}
|
|
18168
18174
|
}
|
|
18169
18175
|
succeeded = true;
|
|
18170
18176
|
}).catch(() => {
|
|
18171
18177
|
if (disposed) return;
|
|
18172
|
-
for (const threadId of threadIds) failed.add(threadId);
|
|
18178
|
+
for (const threadId of threadIds) failed.add(ownershipKey(hostId, threadId));
|
|
18173
18179
|
}).finally(() => {
|
|
18174
|
-
for (const threadId of threadIds) pending.delete(threadId);
|
|
18175
|
-
for (const threadId of threadIds) scheduleOwnershipRetry(threadId);
|
|
18180
|
+
for (const threadId of threadIds) pending.delete(ownershipKey(hostId, threadId));
|
|
18181
|
+
for (const threadId of threadIds) scheduleOwnershipRetry(hostId, threadId);
|
|
18176
18182
|
if (succeeded) scheduleScan();
|
|
18177
18183
|
});
|
|
18178
18184
|
};
|
|
18179
18185
|
const scan = () => {
|
|
18180
18186
|
scanScheduled = false;
|
|
18181
18187
|
if (disposed) return;
|
|
18182
|
-
const
|
|
18188
|
+
const unresolvedByHost = /* @__PURE__ */ new Map();
|
|
18183
18189
|
for (const row of dom.rows()) {
|
|
18184
18190
|
if (!row.isConnected()) {
|
|
18185
18191
|
row.clear();
|
|
18186
18192
|
continue;
|
|
18187
18193
|
}
|
|
18194
|
+
const hostId = row.hostId();
|
|
18195
|
+
if (!hostId) {
|
|
18196
|
+
row.clear();
|
|
18197
|
+
continue;
|
|
18198
|
+
}
|
|
18188
18199
|
const threadId = hostThreadIdSchema.safeParse(row.threadId());
|
|
18189
18200
|
const localAgent = options.getLocalAgent?.({
|
|
18201
|
+
hostId,
|
|
18190
18202
|
threadId: threadId.success ? threadId.data : null,
|
|
18191
18203
|
draftId: row.draftId()
|
|
18192
18204
|
});
|
|
18193
18205
|
if (localAgent !== null && localAgent !== void 0) {
|
|
18194
18206
|
if (threadId.success) {
|
|
18195
|
-
|
|
18196
|
-
|
|
18207
|
+
const key2 = ownershipKey(hostId, threadId.data);
|
|
18208
|
+
ownershipByThread.set(key2, localAgent === "codex" ? null : localAgent);
|
|
18209
|
+
clearOwnershipRetry(key2);
|
|
18197
18210
|
}
|
|
18198
18211
|
if (localAgent === "codex") row.clear();
|
|
18199
18212
|
else row.render(localAgent);
|
|
@@ -18203,22 +18216,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18203
18216
|
row.clear();
|
|
18204
18217
|
continue;
|
|
18205
18218
|
}
|
|
18206
|
-
|
|
18207
|
-
|
|
18219
|
+
const key = ownershipKey(hostId, threadId.data);
|
|
18220
|
+
if (ownershipByThread.has(key)) {
|
|
18221
|
+
const agent = ownershipByThread.get(key);
|
|
18208
18222
|
if (agent) row.render(agent);
|
|
18209
18223
|
else row.clear();
|
|
18210
18224
|
continue;
|
|
18211
18225
|
}
|
|
18212
18226
|
row.clear();
|
|
18213
|
-
if (!pending.has(
|
|
18227
|
+
if (!pending.has(key) && !failed.has(key)) {
|
|
18228
|
+
let unresolved = unresolvedByHost.get(hostId);
|
|
18229
|
+
if (!unresolved) {
|
|
18230
|
+
unresolved = /* @__PURE__ */ new Set();
|
|
18231
|
+
unresolvedByHost.set(hostId, unresolved);
|
|
18232
|
+
}
|
|
18214
18233
|
unresolved.add(threadId.data);
|
|
18215
18234
|
}
|
|
18216
18235
|
}
|
|
18217
|
-
const
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18236
|
+
for (const [hostId, unresolved] of unresolvedByHost) {
|
|
18237
|
+
const client = options.getClient(hostId);
|
|
18238
|
+
if (!client) continue;
|
|
18239
|
+
const threadIds = [...unresolved];
|
|
18240
|
+
for (let index = 0; index < threadIds.length; index += THREAD_OWNERSHIP_LIST_MAX_LENGTH) {
|
|
18241
|
+
requestOwnership(
|
|
18242
|
+
hostId,
|
|
18243
|
+
threadIds.slice(index, index + THREAD_OWNERSHIP_LIST_MAX_LENGTH),
|
|
18244
|
+
client
|
|
18245
|
+
);
|
|
18246
|
+
}
|
|
18222
18247
|
}
|
|
18223
18248
|
};
|
|
18224
18249
|
const stopObserving = dom.observe(scheduleScan);
|
|
@@ -18226,12 +18251,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18226
18251
|
return {
|
|
18227
18252
|
refresh() {
|
|
18228
18253
|
failed.clear();
|
|
18229
|
-
for (const
|
|
18230
|
-
const timer = ownershipRetryTimers.get(
|
|
18254
|
+
for (const key of provisionalCodex) {
|
|
18255
|
+
const timer = ownershipRetryTimers.get(key);
|
|
18231
18256
|
if (timer !== void 0) clearTimeout(timer);
|
|
18232
|
-
ownershipRetryTimers.delete(
|
|
18233
|
-
ownershipRetryAttempts.delete(
|
|
18234
|
-
ownershipByThread.delete(
|
|
18257
|
+
ownershipRetryTimers.delete(key);
|
|
18258
|
+
ownershipRetryAttempts.delete(key);
|
|
18259
|
+
ownershipByThread.delete(key);
|
|
18235
18260
|
}
|
|
18236
18261
|
scheduleScan();
|
|
18237
18262
|
},
|
|
@@ -18722,22 +18747,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18722
18747
|
}
|
|
18723
18748
|
return hostThreadIdSchema.parse(target[1]);
|
|
18724
18749
|
}
|
|
18725
|
-
function
|
|
18726
|
-
return (typeof value === "
|
|
18727
|
-
}
|
|
18728
|
-
function isActiveRequestManager(value) {
|
|
18729
|
-
if (!isRecord5(value) || typeof value.sendRequest !== "function") return false;
|
|
18730
|
-
const source = Function.prototype.toString.call(value.sendRequest);
|
|
18731
|
-
return source.includes("send-cli-request-for-host") && hasPrewarmMethod(value.requestClient);
|
|
18732
|
-
}
|
|
18733
|
-
function matchesCurrentPrewarmSignature(target) {
|
|
18734
|
-
const bridge = target.requestClient ?? target;
|
|
18735
|
-
const stableApiShape = typeof bridge.hostId === "string" && bridge.hostId.length > 0 && typeof bridge.sendRequest === "function" && typeof bridge.prewarmThreadStart === "function" && typeof bridge.enqueueRequest === "function";
|
|
18736
|
-
if (stableApiShape) return true;
|
|
18737
|
-
const prewarm = target.prewarmThreadStart ?? target.requestClient?.prewarmThreadStart;
|
|
18738
|
-
if (!prewarm) return false;
|
|
18739
|
-
const source = Function.prototype.toString.call(prewarm);
|
|
18740
|
-
return source.includes("enqueueRequest") && source.includes("thread-prewarm-start") || source.includes("prewarm-thread-start-for-host");
|
|
18750
|
+
function isCurrentRequestBridge(value) {
|
|
18751
|
+
return isRecord5(value) && typeof value.hostId === "string" && value.hostId.length > 0 && typeof value.sendRequest === "function" && typeof value.prewarmThreadStart === "function" && typeof value.enqueueRequest === "function";
|
|
18741
18752
|
}
|
|
18742
18753
|
function findActivePrewarmTargets(root) {
|
|
18743
18754
|
const editor = root.querySelector(
|
|
@@ -18767,10 +18778,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18767
18778
|
const hookState = hook.memoizedState;
|
|
18768
18779
|
if (isRecord5(hookState)) {
|
|
18769
18780
|
const requestClient = hookState.requestClient;
|
|
18770
|
-
|
|
18771
|
-
|
|
18772
|
-
|
|
18773
|
-
targets.add(typeof hookState.sendRequest === "function" ? hookState : requestClient);
|
|
18781
|
+
const bridge = isCurrentRequestBridge(requestClient) ? requestClient : isCurrentRequestBridge(hookState) ? hookState : null;
|
|
18782
|
+
if (bridge) {
|
|
18783
|
+
targets.add(typeof hookState.sendRequest === "function" ? hookState : bridge);
|
|
18774
18784
|
}
|
|
18775
18785
|
}
|
|
18776
18786
|
hook = typeof hook.next === "object" && hook.next !== null ? hook.next : null;
|
|
@@ -18872,13 +18882,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18872
18882
|
function isDraftPrewarmPolicyReady(value) {
|
|
18873
18883
|
return isRecord5(value) && value.state === "ready" && typeof value.hostId === "string" && value.hostId.length > 0 && typeof value.select === "function" && typeof value.clear === "function";
|
|
18874
18884
|
}
|
|
18885
|
+
function prewarmTargetHostId(target) {
|
|
18886
|
+
const bridge = target.requestClient ?? target;
|
|
18887
|
+
const hostId = target.getHostId?.() ?? bridge.hostId;
|
|
18888
|
+
return typeof hostId === "string" && hostId.length > 0 ? hostId : null;
|
|
18889
|
+
}
|
|
18890
|
+
function rendererRequestTargetsForHost(targets, hostId) {
|
|
18891
|
+
const matching = targets.filter((target) => prewarmTargetHostId(target) === hostId);
|
|
18892
|
+
return matching.length === 1 ? matching : null;
|
|
18893
|
+
}
|
|
18875
18894
|
function activeRendererDraftPrewarmTargets(policy, targets) {
|
|
18876
18895
|
if (!isDraftPrewarmPolicyReady(policy)) return null;
|
|
18877
|
-
|
|
18878
|
-
const bridge = target.requestClient ?? target;
|
|
18879
|
-
return (target.getHostId?.() ?? bridge.hostId) === policy.hostId;
|
|
18880
|
-
});
|
|
18881
|
-
return activeTargets.length === 1 ? activeTargets : null;
|
|
18896
|
+
return rendererRequestTargetsForHost(targets, policy.hostId);
|
|
18882
18897
|
}
|
|
18883
18898
|
function resolveRendererRequestRoute(policy, discoveredTargets, previous) {
|
|
18884
18899
|
const activeTargets = activeRendererDraftPrewarmTargets(policy, discoveredTargets);
|
|
@@ -18943,13 +18958,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18943
18958
|
() => findActivePrewarmTargets(document)
|
|
18944
18959
|
);
|
|
18945
18960
|
const currentRequestRoute = () => requestRouteResolver.resolve();
|
|
18961
|
+
const clientsByTarget = /* @__PURE__ */ new WeakMap();
|
|
18962
|
+
const modelClientForTargets = (targets) => {
|
|
18963
|
+
const target = targets[0];
|
|
18964
|
+
if (targets.length !== 1 || !target) return null;
|
|
18965
|
+
const cached2 = clientsByTarget.get(target);
|
|
18966
|
+
if (cached2) return cached2;
|
|
18967
|
+
const client = createRendererModelClient([target]);
|
|
18968
|
+
if (client) clientsByTarget.set(target, client);
|
|
18969
|
+
return client;
|
|
18970
|
+
};
|
|
18946
18971
|
const currentModelClient = () => {
|
|
18947
|
-
const client =
|
|
18972
|
+
const client = modelClientForTargets(currentRequestRoute()?.targets ?? []);
|
|
18948
18973
|
if (!client) throw new Error("Renderer Model request manager is unavailable");
|
|
18949
18974
|
usageSubscription.connect(client);
|
|
18950
18975
|
return client;
|
|
18951
18976
|
};
|
|
18952
18977
|
const modelControl = Object.freeze({
|
|
18978
|
+
currentHostId: () => currentRequestRoute()?.policy.hostId ?? null,
|
|
18979
|
+
clientForHost(hostId) {
|
|
18980
|
+
const targets = rendererRequestTargetsForHost(findActivePrewarmTargets(document), hostId);
|
|
18981
|
+
return modelClientForTargets(targets ?? []);
|
|
18982
|
+
},
|
|
18953
18983
|
forkThread: (input) => currentModelClient().forkThread(input),
|
|
18954
18984
|
inspectHarness: (input) => currentModelClient().inspectHarness(input),
|
|
18955
18985
|
inspectThread: (input) => currentModelClient().inspectThread(input),
|
|
@@ -19368,6 +19398,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19368
19398
|
runtimeCapabilityNotInstalled: "This runtime capability is not installed yet.",
|
|
19369
19399
|
connectionsDescription: "Inspect the adapter and each Agent runtime used by the picker. Failed checks keep their error details here.",
|
|
19370
19400
|
connectionAdapter: "Renderer adapter",
|
|
19401
|
+
connectionHosts: "Hosts",
|
|
19402
|
+
connectionLocalHost: "Local",
|
|
19403
|
+
connectionRemoteHost: "Remote Host",
|
|
19404
|
+
connectionActiveHost: "Current",
|
|
19371
19405
|
connectionReason: "Reason",
|
|
19372
19406
|
connectionRefresh: "Run connection diagnostics",
|
|
19373
19407
|
connectionRefreshing: "Running diagnostics...",
|
|
@@ -19436,6 +19470,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19436
19470
|
runtimeCapabilityNotInstalled: "\u8FD0\u884C\u65F6\u5C1A\u672A\u5B89\u88C5\u8BE5\u9879\u80FD\u529B\uFF0C\u56E0\u6B64\u6682\u4E0D\u53EF\u7528\u3002",
|
|
19437
19471
|
connectionsDescription: "\u67E5\u770B\u9002\u914D\u5668\u548C Agent \u8FD0\u884C\u65F6\u7684\u771F\u5B9E\u68C0\u67E5\u7ED3\u679C\u3002\u5931\u8D25\u68C0\u67E5\u4F1A\u4FDD\u7559\u9519\u8BEF\u8BE6\u60C5\uFF0C\u65B9\u4FBF\u6392\u67E5\u65E0\u6CD5\u9009\u62E9\u7684\u95EE\u9898\u3002",
|
|
19438
19472
|
connectionAdapter: "Renderer \u9002\u914D\u5668",
|
|
19473
|
+
connectionHosts: "Host \u5217\u8868",
|
|
19474
|
+
connectionLocalHost: "\u672C\u5730",
|
|
19475
|
+
connectionRemoteHost: "\u8FDC\u7A0B Host",
|
|
19476
|
+
connectionActiveHost: "\u5F53\u524D",
|
|
19439
19477
|
connectionReason: "\u539F\u56E0",
|
|
19440
19478
|
connectionRefresh: "\u91CD\u65B0\u8BCA\u65AD\u8FDE\u63A5",
|
|
19441
19479
|
connectionRefreshing: "\u6B63\u5728\u8BCA\u65AD...",
|
|
@@ -20079,10 +20117,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
20079
20117
|
if (availability === "checking" || availability === "installing") return "checking";
|
|
20080
20118
|
return "failed";
|
|
20081
20119
|
}
|
|
20082
|
-
function diagnosticText(name, snapshot) {
|
|
20120
|
+
function diagnosticText(hostId, name, snapshot) {
|
|
20083
20121
|
const error51 = snapshot.error;
|
|
20084
20122
|
const lines = [
|
|
20085
20123
|
"codexhost connection diagnostics",
|
|
20124
|
+
`host: ${hostId}`,
|
|
20086
20125
|
`agent: ${name}`,
|
|
20087
20126
|
`status: ${snapshot.availability}`,
|
|
20088
20127
|
...error51 ? [
|
|
@@ -20128,7 +20167,7 @@ ${error51.stderrTail}`] : []
|
|
|
20128
20167
|
() => showCopyButtonFeedback(button, messages.connectionCopyFailed, restoreLabel)
|
|
20129
20168
|
);
|
|
20130
20169
|
}
|
|
20131
|
-
function appendConnectionRow(document2, parent, name, availability, detail, error51, messages, rowAttribute, diagnosticSnapshot) {
|
|
20170
|
+
function appendConnectionRow(document2, parent, name, availability, detail, error51, messages, rowAttribute, diagnosticSnapshot, diagnosticHostId) {
|
|
20132
20171
|
const row = document2.createElement("div");
|
|
20133
20172
|
row.className = "settings-connection-row";
|
|
20134
20173
|
if (rowAttribute) row.dataset.connectionAgent = rowAttribute;
|
|
@@ -20191,7 +20230,7 @@ ${error51.stderrTail}`] : []
|
|
|
20191
20230
|
copyDiagnosticsToClipboard(
|
|
20192
20231
|
document2,
|
|
20193
20232
|
copy,
|
|
20194
|
-
diagnosticText(name, diagnosticSnapshot),
|
|
20233
|
+
diagnosticText(diagnosticHostId ?? "unknown", name, diagnosticSnapshot),
|
|
20195
20234
|
messages,
|
|
20196
20235
|
messages.connectionCopyDetails
|
|
20197
20236
|
);
|
|
@@ -20207,6 +20246,18 @@ ${error51.stderrTail}`] : []
|
|
|
20207
20246
|
row.append(identity, status, detailElement, details);
|
|
20208
20247
|
parent.append(row);
|
|
20209
20248
|
}
|
|
20249
|
+
function connectionHostLabel(hostId, active, messages) {
|
|
20250
|
+
const activeLabel = active ? ` \xB7 ${messages.connectionActiveHost}` : "";
|
|
20251
|
+
if (hostId === "local") return `${messages.connectionLocalHost}${activeLabel}`;
|
|
20252
|
+
const separator = hostId.lastIndexOf(":");
|
|
20253
|
+
const encodedName = separator >= 0 ? hostId.slice(separator + 1) : hostId;
|
|
20254
|
+
let name = encodedName;
|
|
20255
|
+
try {
|
|
20256
|
+
name = decodeURIComponent(encodedName);
|
|
20257
|
+
} catch {
|
|
20258
|
+
}
|
|
20259
|
+
return `${messages.connectionRemoteHost}: ${name}${activeLabel}`;
|
|
20260
|
+
}
|
|
20210
20261
|
function connectionsPage(messages, getDiagnostics) {
|
|
20211
20262
|
return Object.freeze({
|
|
20212
20263
|
id: "connections",
|
|
@@ -20237,7 +20288,10 @@ ${error51.stderrTail}`] : []
|
|
|
20237
20288
|
content.className = "settings-connection-list";
|
|
20238
20289
|
context.content.append(heading, description, actions, content);
|
|
20239
20290
|
let pending = false;
|
|
20291
|
+
let selectedHostId = "local";
|
|
20292
|
+
let latestSnapshot = null;
|
|
20240
20293
|
const render = (snapshot) => {
|
|
20294
|
+
latestSnapshot = snapshot;
|
|
20241
20295
|
content.replaceChildren();
|
|
20242
20296
|
if (!snapshot) {
|
|
20243
20297
|
const empty = document2.createElement("div");
|
|
@@ -20256,19 +20310,50 @@ ${error51.stderrTail}`] : []
|
|
|
20256
20310
|
messages,
|
|
20257
20311
|
"renderer-adapter"
|
|
20258
20312
|
);
|
|
20259
|
-
|
|
20313
|
+
const selectedHost = snapshot.hosts.find((host) => host.hostId === selectedHostId) ?? snapshot.hosts.find((host) => host.hostId === "local") ?? snapshot.hosts[0];
|
|
20314
|
+
if (!selectedHost) return;
|
|
20315
|
+
selectedHostId = selectedHost.hostId;
|
|
20316
|
+
const tabs = document2.createElement("div");
|
|
20317
|
+
tabs.className = "settings-connection-host-tabs";
|
|
20318
|
+
tabs.setAttribute("role", "tablist");
|
|
20319
|
+
tabs.setAttribute("aria-label", messages.connectionHosts);
|
|
20320
|
+
const hostSection = document2.createElement("section");
|
|
20321
|
+
hostSection.className = "settings-connection-host";
|
|
20322
|
+
hostSection.dataset.connectionHost = selectedHost.hostId;
|
|
20323
|
+
hostSection.setAttribute("role", "tabpanel");
|
|
20324
|
+
const panelId = "codexhost-settings-connection-host-panel";
|
|
20325
|
+
hostSection.id = panelId;
|
|
20326
|
+
for (const host of snapshot.hosts) {
|
|
20327
|
+
const tab = document2.createElement("button");
|
|
20328
|
+
tab.type = "button";
|
|
20329
|
+
tab.className = "settings-connection-host-tab";
|
|
20330
|
+
tab.dataset.connectionHostTab = host.hostId;
|
|
20331
|
+
tab.setAttribute("role", "tab");
|
|
20332
|
+
tab.setAttribute("aria-controls", panelId);
|
|
20333
|
+
tab.setAttribute("aria-selected", String(host.hostId === selectedHost.hostId));
|
|
20334
|
+
tab.tabIndex = host.hostId === selectedHost.hostId ? 0 : -1;
|
|
20335
|
+
tab.textContent = connectionHostLabel(host.hostId, host.active, messages);
|
|
20336
|
+
tab.addEventListener("click", () => {
|
|
20337
|
+
selectedHostId = host.hostId;
|
|
20338
|
+
render(latestSnapshot);
|
|
20339
|
+
});
|
|
20340
|
+
tabs.append(tab);
|
|
20341
|
+
}
|
|
20342
|
+
for (const agent of selectedHost.agents) {
|
|
20260
20343
|
appendConnectionRow(
|
|
20261
20344
|
document2,
|
|
20262
|
-
|
|
20345
|
+
hostSection,
|
|
20263
20346
|
RENDERER_AGENT_LABELS[agent.agent],
|
|
20264
20347
|
agent.availability,
|
|
20265
20348
|
null,
|
|
20266
20349
|
agent.error,
|
|
20267
20350
|
messages,
|
|
20268
20351
|
agent.agent,
|
|
20269
|
-
agent
|
|
20352
|
+
agent,
|
|
20353
|
+
selectedHost.hostId
|
|
20270
20354
|
);
|
|
20271
20355
|
}
|
|
20356
|
+
content.append(tabs, hostSection);
|
|
20272
20357
|
};
|
|
20273
20358
|
const diagnostics = getDiagnostics();
|
|
20274
20359
|
render(diagnostics?.snapshot() ?? null);
|
|
@@ -20278,7 +20363,11 @@ ${error51.stderrTail}`] : []
|
|
|
20278
20363
|
}
|
|
20279
20364
|
copyAll.addEventListener("click", () => {
|
|
20280
20365
|
const snapshot = diagnostics.snapshot();
|
|
20281
|
-
const report = snapshot.
|
|
20366
|
+
const report = snapshot.hosts.flatMap(
|
|
20367
|
+
(host) => host.agents.map(
|
|
20368
|
+
(agent) => diagnosticText(host.hostId, RENDERER_AGENT_LABELS[agent.agent], agent)
|
|
20369
|
+
)
|
|
20370
|
+
).join("\n\n");
|
|
20282
20371
|
copyDiagnosticsToClipboard(document2, copyAll, report, messages, messages.connectionCopyAll);
|
|
20283
20372
|
});
|
|
20284
20373
|
const unsubscribe = diagnostics.subscribe(() => render(diagnostics.snapshot()));
|
|
@@ -20307,17 +20396,21 @@ ${error51.stderrTail}`] : []
|
|
|
20307
20396
|
createRendererSettingsIcon("diagnose", 16),
|
|
20308
20397
|
messages.connectionRefresh
|
|
20309
20398
|
);
|
|
20399
|
+
const snapshot = diagnostics.snapshot();
|
|
20310
20400
|
render({
|
|
20311
|
-
...
|
|
20312
|
-
|
|
20313
|
-
...
|
|
20314
|
-
|
|
20315
|
-
|
|
20316
|
-
|
|
20317
|
-
|
|
20318
|
-
|
|
20319
|
-
|
|
20320
|
-
|
|
20401
|
+
...snapshot,
|
|
20402
|
+
hosts: snapshot.hosts.map((host) => ({
|
|
20403
|
+
...host,
|
|
20404
|
+
agents: host.agents.map((agent) => ({
|
|
20405
|
+
...agent,
|
|
20406
|
+
availability: "error",
|
|
20407
|
+
error: {
|
|
20408
|
+
code: "internalError",
|
|
20409
|
+
message: error51 instanceof Error ? error51.message : String(error51),
|
|
20410
|
+
retryable: true,
|
|
20411
|
+
stage: "request"
|
|
20412
|
+
}
|
|
20413
|
+
}))
|
|
20321
20414
|
}))
|
|
20322
20415
|
});
|
|
20323
20416
|
}
|
|
@@ -20617,7 +20710,7 @@ ${error51.stderrTail}`] : []
|
|
|
20617
20710
|
}
|
|
20618
20711
|
|
|
20619
20712
|
// src/settings/shell.css
|
|
20620
|
-
var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-icon-button.settings-star-link {\n width: auto;\n gap: 6px;\n padding-inline: 8px;\n font-size: 12px;\n line-height: 18px;\n text-decoration: none;\n border: 2px dashed #f5c542;\n white-space: nowrap;\n}\n\n.settings-star-link .codexhost-settings-icon {\n color: #f5c542;\n fill: currentColor;\n stroke: currentColor;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 40px;\n flex: none;\n gap: 12px;\n padding: 8px 12px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 10px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 7%);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-page-description {\n max-width: 760px;\n margin: -12px 0 24px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-connection-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.settings-connection-list {\n min-width: 0;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row {\n display: grid;\n grid-template-columns: minmax(180px, 1fr) auto minmax(260px, 1.5fr);\n align-items: center;\n min-width: 0;\n min-height: 76px;\n gap: 24px;\n padding: 14px 0;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n gap: 10px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 20px;\n}\n\n.settings-connection-row__identity strong {\n min-width: 0;\n overflow-wrap: anywhere;\n font-weight: 500;\n}\n\n.settings-connection-row__dot {\n width: 9px;\n height: 9px;\n flex: none;\n border-radius: 50%;\n background: var(--settings-muted);\n}\n\n.settings-connection-row__dot[data-connection-tone="ready"] {\n background: #22c55e;\n}\n\n.settings-connection-row__dot[data-connection-tone="checking"] {\n background: #f5c542;\n}\n\n.settings-connection-row__dot[data-connection-tone="failed"] {\n background: #ef4444;\n}\n\n.settings-status-badge[data-connection-tone="ready"] {\n color: #4ade80;\n}\n\n.settings-status-badge[data-connection-tone="checking"] {\n color: #f5c542;\n}\n\n.settings-status-badge[data-connection-tone="failed"] {\n color: #f87171;\n}\n\n.settings-connection-row__detail {\n display: grid;\n min-width: 0;\n align-items: center;\n gap: 2px 12px;\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-connection-row__reason {\n min-width: 0;\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n\n.settings-connection-details-toggle {\n width: fit-content;\n padding: 0;\n color: var(--settings-focus);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n background: transparent;\n border: 0;\n cursor: pointer;\n}\n\n.settings-connection-details-toggle:hover {\n text-decoration: underline;\n}\n\n.settings-connection-details {\n display: grid;\n grid-column: 1 / -1;\n gap: 6px;\n min-width: 0;\n margin: 4px 0 2px 32px;\n padding: 12px;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 4%);\n border-left: 2px solid #ef4444;\n border-radius: 4px;\n}\n\n.settings-connection-detail-line {\n display: grid;\n grid-template-columns: 112px minmax(0, 1fr);\n gap: 12px;\n min-width: 0;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-connection-detail-line span {\n color: var(--settings-muted);\n}\n\n.settings-connection-detail-line code {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n white-space: pre-wrap;\n}\n\n.settings-connection-stderr {\n max-height: 220px;\n min-width: 0;\n margin: 4px 0 0;\n padding: 10px;\n overflow: auto;\n color: #fca5a5;\n font:\n 12px/18px ui-monospace,\n "SFMono-Regular",\n Consolas,\n "Liberation Mono",\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n background: rgb(0 0 0 / 28%);\n border-radius: 4px;\n}\n\n.settings-connection-details .settings-command-button {\n justify-self: start;\n min-height: 30px;\n font-size: 12px;\n}\n\n.settings-connection-row__detail time {\n color: var(--settings-muted);\n opacity: 0.8;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 16px;\n min-height: 128px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-update-panel > strong,\n.settings-update-panel > span,\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-panel > span,\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-notes {\n display: grid;\n min-width: 0;\n gap: 12px;\n color: var(--settings-muted);\n font-size: 14px;\n line-height: 22px;\n overflow-wrap: anywhere;\n}\n\n.settings-update-notes > :first-child {\n margin-top: 0;\n}\n\n.settings-update-notes > :last-child {\n margin-bottom: 0;\n}\n\n.settings-update-notes h1,\n.settings-update-notes h2,\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n margin: 6px 0 0;\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes h1 {\n font-size: 18px;\n line-height: 26px;\n}\n\n.settings-update-notes h2 {\n font-size: 17px;\n line-height: 24px;\n}\n\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n font-size: 14px;\n line-height: 22px;\n}\n\n.settings-update-notes p,\n.settings-update-notes ul,\n.settings-update-notes ol,\n.settings-update-notes pre,\n.settings-update-notes blockquote {\n margin: 0;\n}\n\n.settings-update-notes ul,\n.settings-update-notes ol {\n padding-left: 24px;\n}\n\n.settings-update-notes li {\n padding-left: 4px;\n}\n\n.settings-update-notes li::marker {\n color: var(--settings-muted);\n font-size: 0.85em;\n}\n\n.settings-update-notes li + li {\n margin-top: 14px;\n}\n\n.settings-update-notes .release-note-translation {\n display: block;\n margin-top: 3px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-notes blockquote {\n padding: 8px 12px;\n color: var(--settings-muted);\n border-left: 3px solid var(--settings-focus);\n background: rgb(255 255 255 / 4%);\n}\n\n.settings-update-notes hr {\n width: 100%;\n margin: 2px 0;\n border: 0;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-update-notes strong {\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes a {\n color: #7cb8ff;\n text-decoration: none;\n}\n\n.settings-update-notes a:hover {\n text-decoration: underline;\n}\n\n.settings-update-notes code {\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n}\n\n.settings-update-notes :not(pre) > code {\n padding: 1px 5px;\n background: rgb(255 255 255 / 8%);\n border-radius: 4px;\n}\n\n.settings-update-notes pre {\n min-width: 0;\n max-width: 100%;\n padding: 10px 12px;\n overflow-x: auto;\n overflow-y: hidden;\n background: rgb(0 0 0 / 28%);\n border-radius: 6px;\n}\n\n.settings-update-notes pre code {\n line-height: 18px;\n white-space: pre-wrap;\n}\n\n.settings-update-version-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 20px;\n min-height: 32px;\n color: var(--settings-muted);\n font-size: 13px;\n}\n\n.settings-update-version-row strong {\n color: var(--settings-text);\n font-size: 15px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 6px;\n margin-top: 14px;\n padding-inline: 4px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual code {\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-actions {\n display: flex;\n min-width: 0;\n margin-top: 16px;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-icon-button.settings-star-link {\n width: 28px;\n padding: 0;\n }\n\n .settings-star-link span {\n display: none;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-connection-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 10px 16px;\n }\n\n .settings-connection-row__detail {\n grid-column: 1 / -1;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
|
|
20713
|
+
var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-icon-button.settings-star-link {\n width: auto;\n gap: 6px;\n padding-inline: 8px;\n font-size: 12px;\n line-height: 18px;\n text-decoration: none;\n border: 2px dashed #f5c542;\n white-space: nowrap;\n}\n\n.settings-star-link .codexhost-settings-icon {\n color: #f5c542;\n fill: currentColor;\n stroke: currentColor;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 40px;\n flex: none;\n gap: 12px;\n padding: 8px 12px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 10px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 7%);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-page-description {\n max-width: 760px;\n margin: -12px 0 24px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-connection-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.settings-connection-list {\n min-width: 0;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-connection-host-tabs {\n display: flex;\n gap: 6px;\n padding: 20px 0 8px;\n overflow-x: auto;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-host-tab {\n flex: none;\n padding: 7px 12px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: var(--settings-muted);\n font: inherit;\n font-size: 13px;\n line-height: 18px;\n cursor: pointer;\n}\n\n.settings-connection-host-tab:hover {\n background: var(--settings-hover);\n color: var(--settings-text);\n}\n\n.settings-connection-host-tab[aria-selected="true"] {\n background: var(--settings-active);\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-connection-host-tab:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: -2px;\n}\n\n.settings-connection-row {\n display: grid;\n grid-template-columns: minmax(180px, 1fr) auto minmax(260px, 1.5fr);\n align-items: center;\n min-width: 0;\n min-height: 76px;\n gap: 24px;\n padding: 14px 0;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n gap: 10px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 20px;\n}\n\n.settings-connection-row__identity strong {\n min-width: 0;\n overflow-wrap: anywhere;\n font-weight: 500;\n}\n\n.settings-connection-row__dot {\n width: 9px;\n height: 9px;\n flex: none;\n border-radius: 50%;\n background: var(--settings-muted);\n}\n\n.settings-connection-row__dot[data-connection-tone="ready"] {\n background: #22c55e;\n}\n\n.settings-connection-row__dot[data-connection-tone="checking"] {\n background: #f5c542;\n}\n\n.settings-connection-row__dot[data-connection-tone="failed"] {\n background: #ef4444;\n}\n\n.settings-status-badge[data-connection-tone="ready"] {\n color: #4ade80;\n}\n\n.settings-status-badge[data-connection-tone="checking"] {\n color: #f5c542;\n}\n\n.settings-status-badge[data-connection-tone="failed"] {\n color: #f87171;\n}\n\n.settings-connection-row__detail {\n display: grid;\n min-width: 0;\n align-items: center;\n gap: 2px 12px;\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-connection-row__reason {\n min-width: 0;\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n\n.settings-connection-details-toggle {\n width: fit-content;\n padding: 0;\n color: var(--settings-focus);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n background: transparent;\n border: 0;\n cursor: pointer;\n}\n\n.settings-connection-details-toggle:hover {\n text-decoration: underline;\n}\n\n.settings-connection-details {\n display: grid;\n grid-column: 1 / -1;\n gap: 6px;\n min-width: 0;\n margin: 4px 0 2px 32px;\n padding: 12px;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 4%);\n border-left: 2px solid #ef4444;\n border-radius: 4px;\n}\n\n.settings-connection-detail-line {\n display: grid;\n grid-template-columns: 112px minmax(0, 1fr);\n gap: 12px;\n min-width: 0;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-connection-detail-line span {\n color: var(--settings-muted);\n}\n\n.settings-connection-detail-line code {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n white-space: pre-wrap;\n}\n\n.settings-connection-stderr {\n max-height: 220px;\n min-width: 0;\n margin: 4px 0 0;\n padding: 10px;\n overflow: auto;\n color: #fca5a5;\n font:\n 12px/18px ui-monospace,\n "SFMono-Regular",\n Consolas,\n "Liberation Mono",\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n background: rgb(0 0 0 / 28%);\n border-radius: 4px;\n}\n\n.settings-connection-details .settings-command-button {\n justify-self: start;\n min-height: 30px;\n font-size: 12px;\n}\n\n.settings-connection-row__detail time {\n color: var(--settings-muted);\n opacity: 0.8;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 16px;\n min-height: 128px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-update-panel > strong,\n.settings-update-panel > span,\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-panel > span,\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-notes {\n display: grid;\n min-width: 0;\n gap: 12px;\n color: var(--settings-muted);\n font-size: 14px;\n line-height: 22px;\n overflow-wrap: anywhere;\n}\n\n.settings-update-notes > :first-child {\n margin-top: 0;\n}\n\n.settings-update-notes > :last-child {\n margin-bottom: 0;\n}\n\n.settings-update-notes h1,\n.settings-update-notes h2,\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n margin: 6px 0 0;\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes h1 {\n font-size: 18px;\n line-height: 26px;\n}\n\n.settings-update-notes h2 {\n font-size: 17px;\n line-height: 24px;\n}\n\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n font-size: 14px;\n line-height: 22px;\n}\n\n.settings-update-notes p,\n.settings-update-notes ul,\n.settings-update-notes ol,\n.settings-update-notes pre,\n.settings-update-notes blockquote {\n margin: 0;\n}\n\n.settings-update-notes ul,\n.settings-update-notes ol {\n padding-left: 24px;\n}\n\n.settings-update-notes li {\n padding-left: 4px;\n}\n\n.settings-update-notes li::marker {\n color: var(--settings-muted);\n font-size: 0.85em;\n}\n\n.settings-update-notes li + li {\n margin-top: 14px;\n}\n\n.settings-update-notes .release-note-translation {\n display: block;\n margin-top: 3px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-notes blockquote {\n padding: 8px 12px;\n color: var(--settings-muted);\n border-left: 3px solid var(--settings-focus);\n background: rgb(255 255 255 / 4%);\n}\n\n.settings-update-notes hr {\n width: 100%;\n margin: 2px 0;\n border: 0;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-update-notes strong {\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes a {\n color: #7cb8ff;\n text-decoration: none;\n}\n\n.settings-update-notes a:hover {\n text-decoration: underline;\n}\n\n.settings-update-notes code {\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n}\n\n.settings-update-notes :not(pre) > code {\n padding: 1px 5px;\n background: rgb(255 255 255 / 8%);\n border-radius: 4px;\n}\n\n.settings-update-notes pre {\n min-width: 0;\n max-width: 100%;\n padding: 10px 12px;\n overflow-x: auto;\n overflow-y: hidden;\n background: rgb(0 0 0 / 28%);\n border-radius: 6px;\n}\n\n.settings-update-notes pre code {\n line-height: 18px;\n white-space: pre-wrap;\n}\n\n.settings-update-version-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 20px;\n min-height: 32px;\n color: var(--settings-muted);\n font-size: 13px;\n}\n\n.settings-update-version-row strong {\n color: var(--settings-text);\n font-size: 15px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 6px;\n margin-top: 14px;\n padding-inline: 4px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual code {\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-actions {\n display: flex;\n min-width: 0;\n margin-top: 16px;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-icon-button.settings-star-link {\n width: 28px;\n padding: 0;\n }\n\n .settings-star-link span {\n display: none;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-connection-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 10px 16px;\n }\n\n .settings-connection-row__detail {\n grid-column: 1 / -1;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
|
|
20621
20714
|
|
|
20622
20715
|
// src/settings/shell.ts
|
|
20623
20716
|
var SETTINGS_SHELL_ATTRIBUTE = "data-codexhost-settings-shell";
|
|
@@ -21413,6 +21506,8 @@ ${error51.stderrTail}`] : []
|
|
|
21413
21506
|
let modelControl = null;
|
|
21414
21507
|
let usageNotificationDispose = null;
|
|
21415
21508
|
const localAgentForSidebarThread = (input) => {
|
|
21509
|
+
const mountedHostId = modelControl?.currentHostId?.() ?? "local";
|
|
21510
|
+
if (input.hostId !== mountedHostId) return null;
|
|
21416
21511
|
for (const mounted of mountedByComposer.values()) {
|
|
21417
21512
|
const target = mounted.modelTarget;
|
|
21418
21513
|
if (target?.[0] === "default" && input.draftId !== null && target[1] === input.draftId) {
|
|
@@ -21425,7 +21520,7 @@ ${error51.stderrTail}`] : []
|
|
|
21425
21520
|
return null;
|
|
21426
21521
|
};
|
|
21427
21522
|
const sidebarAgentIcons = installRendererSidebarAgentIcons({
|
|
21428
|
-
getClient: () =>
|
|
21523
|
+
getClient: (hostId) => modelClientForHost(hostId),
|
|
21429
21524
|
getLocalAgent: localAgentForSidebarThread
|
|
21430
21525
|
});
|
|
21431
21526
|
let connectionDiagnostics = null;
|
|
@@ -21439,23 +21534,36 @@ ${error51.stderrTail}`] : []
|
|
|
21439
21534
|
modelUpdates: 0,
|
|
21440
21535
|
hook: null
|
|
21441
21536
|
};
|
|
21442
|
-
|
|
21443
|
-
|
|
21444
|
-
|
|
21445
|
-
|
|
21446
|
-
|
|
21447
|
-
|
|
21448
|
-
|
|
21449
|
-
|
|
21537
|
+
const createHostHarnessAvailabilityState = () => ({
|
|
21538
|
+
availability: Object.fromEntries(
|
|
21539
|
+
externalAgents.map((agent) => [agent, "checking"])
|
|
21540
|
+
),
|
|
21541
|
+
errors: {
|
|
21542
|
+
pi: void 0,
|
|
21543
|
+
"claude-code": void 0,
|
|
21544
|
+
"deepseek-harness": void 0,
|
|
21545
|
+
grok: void 0
|
|
21546
|
+
},
|
|
21547
|
+
requestGeneration: 0,
|
|
21548
|
+
request: null,
|
|
21549
|
+
retryTimer: null,
|
|
21550
|
+
retryAttempt: 0
|
|
21551
|
+
});
|
|
21552
|
+
const harnessAvailabilityByHost = /* @__PURE__ */ new Map();
|
|
21553
|
+
const hostHarnessAvailabilityState = (hostId) => {
|
|
21554
|
+
let state = harnessAvailabilityByHost.get(hostId);
|
|
21555
|
+
if (!state) {
|
|
21556
|
+
state = createHostHarnessAvailabilityState();
|
|
21557
|
+
harnessAvailabilityByHost.set(hostId, state);
|
|
21558
|
+
}
|
|
21559
|
+
return state;
|
|
21450
21560
|
};
|
|
21561
|
+
let activeAvailabilityHostId = "local";
|
|
21562
|
+
const activeHarnessAvailabilityState = () => hostHarnessAvailabilityState(activeAvailabilityHostId);
|
|
21451
21563
|
const connectionListeners = /* @__PURE__ */ new Set();
|
|
21452
21564
|
const publishConnectionStatus = () => {
|
|
21453
21565
|
for (const listener of connectionListeners) listener();
|
|
21454
21566
|
};
|
|
21455
|
-
let availabilityRequestGeneration = 0;
|
|
21456
|
-
let availabilityRequest = null;
|
|
21457
|
-
let availabilityRetryTimer = null;
|
|
21458
|
-
let availabilityRetryAttempt = 0;
|
|
21459
21567
|
const availabilityRetryDelays = [500, 1e3, 2e3, 4e3, 8e3];
|
|
21460
21568
|
const usageRefreshTimers = /* @__PURE__ */ new Map();
|
|
21461
21569
|
const usageRefreshAttempts = /* @__PURE__ */ new Map();
|
|
@@ -21492,7 +21600,7 @@ ${error51.stderrTail}`] : []
|
|
|
21492
21600
|
controller.get(mounted.composer),
|
|
21493
21601
|
adapterStatus.state,
|
|
21494
21602
|
controller.isSwitching(mounted.composer) || isOwnershipSubmissionBlocked(mounted.ownershipStatus),
|
|
21495
|
-
|
|
21603
|
+
activeHarnessAvailabilityState().availability,
|
|
21496
21604
|
mounted.modelView,
|
|
21497
21605
|
mounted.permissionModeView,
|
|
21498
21606
|
mounted.usage,
|
|
@@ -21719,7 +21827,7 @@ ${error51.stderrTail}`] : []
|
|
|
21719
21827
|
const state = controller.get(mounted.composer);
|
|
21720
21828
|
if (state.agent === "codex") return;
|
|
21721
21829
|
const agent = state.agent;
|
|
21722
|
-
const availability =
|
|
21830
|
+
const availability = activeHarnessAvailabilityState().availability[agent];
|
|
21723
21831
|
if (availability !== "ready") {
|
|
21724
21832
|
mounted.modelView = {
|
|
21725
21833
|
status: adapterStatus.state !== "ready" || availability === "checking" ? "waitingForAdapter" : "error",
|
|
@@ -22232,7 +22340,9 @@ ${error51.stderrTail}`] : []
|
|
|
22232
22340
|
}
|
|
22233
22341
|
};
|
|
22234
22342
|
const switchComposerAgent = async (mounted, agent) => {
|
|
22235
|
-
if (agent !== "codex" &&
|
|
22343
|
+
if (agent !== "codex" && activeHarnessAvailabilityState().availability[agent] !== "ready") {
|
|
22344
|
+
return false;
|
|
22345
|
+
}
|
|
22236
22346
|
controller.clearPendingSubmission(mounted.composer);
|
|
22237
22347
|
const composerId = controller.get(mounted.composer).composerId;
|
|
22238
22348
|
controller.invalidateModelRequests(mounted.composer);
|
|
@@ -22279,53 +22389,67 @@ ${error51.stderrTail}`] : []
|
|
|
22279
22389
|
const url2 = RENDERER_AGENT_INSTALL_URLS[agent];
|
|
22280
22390
|
window.open(url2, "_blank", "noopener,noreferrer");
|
|
22281
22391
|
};
|
|
22282
|
-
|
|
22283
|
-
|
|
22284
|
-
|
|
22285
|
-
|
|
22392
|
+
function resetHarnessAvailabilityRetry(hostId) {
|
|
22393
|
+
const state = hostHarnessAvailabilityState(hostId);
|
|
22394
|
+
if (state.retryTimer !== null) {
|
|
22395
|
+
window.clearTimeout(state.retryTimer);
|
|
22396
|
+
state.retryTimer = null;
|
|
22286
22397
|
}
|
|
22287
|
-
|
|
22288
|
-
}
|
|
22289
|
-
|
|
22290
|
-
|
|
22398
|
+
state.retryAttempt = 0;
|
|
22399
|
+
}
|
|
22400
|
+
function scheduleHarnessAvailabilityRetry(hostId) {
|
|
22401
|
+
const state = hostHarnessAvailabilityState(hostId);
|
|
22402
|
+
if (disposed || state.retryTimer !== null || state.retryAttempt >= availabilityRetryDelays.length) {
|
|
22291
22403
|
return;
|
|
22292
22404
|
}
|
|
22293
|
-
const delay = availabilityRetryDelays[
|
|
22294
|
-
|
|
22295
|
-
|
|
22296
|
-
|
|
22297
|
-
void
|
|
22405
|
+
const delay = availabilityRetryDelays[state.retryAttempt];
|
|
22406
|
+
state.retryAttempt += 1;
|
|
22407
|
+
state.retryTimer = window.setTimeout(() => {
|
|
22408
|
+
state.retryTimer = null;
|
|
22409
|
+
void refreshHarnessAvailabilityForHost(hostId, true, true);
|
|
22298
22410
|
}, delay);
|
|
22299
|
-
}
|
|
22300
|
-
|
|
22301
|
-
if (!
|
|
22302
|
-
|
|
22303
|
-
|
|
22304
|
-
|
|
22305
|
-
|
|
22411
|
+
}
|
|
22412
|
+
function modelClientForHost(hostId) {
|
|
22413
|
+
if (!modelControl) return null;
|
|
22414
|
+
const selected = modelControl.clientForHost?.(hostId);
|
|
22415
|
+
if (selected) return selected;
|
|
22416
|
+
const currentHostId = modelControl.currentHostId?.() ?? "local";
|
|
22417
|
+
return currentHostId === hostId ? modelControl : null;
|
|
22418
|
+
}
|
|
22419
|
+
function refreshHarnessAvailabilityForHost(hostId, refresh = false, retry = false) {
|
|
22420
|
+
const state = hostHarnessAvailabilityState(hostId);
|
|
22421
|
+
if (!retry) resetHarnessAvailabilityRetry(hostId);
|
|
22422
|
+
const client = modelClientForHost(hostId);
|
|
22423
|
+
if (!client) {
|
|
22424
|
+
scheduleHarnessAvailabilityRetry(hostId);
|
|
22425
|
+
return Promise.resolve();
|
|
22426
|
+
}
|
|
22427
|
+
if (state.request?.client === client) return state.request.promise;
|
|
22428
|
+
state.availability = Object.fromEntries(
|
|
22306
22429
|
externalAgents.map((agent) => [
|
|
22307
22430
|
agent,
|
|
22308
|
-
|
|
22431
|
+
state.availability[agent] === "ready" ? "ready" : "checking"
|
|
22309
22432
|
])
|
|
22310
22433
|
);
|
|
22311
|
-
|
|
22312
|
-
|
|
22313
|
-
|
|
22434
|
+
if (hostId === activeAvailabilityHostId) {
|
|
22435
|
+
publishConnectionStatus();
|
|
22436
|
+
for (const mounted of mountedByComposer.values()) renderMounted(mounted);
|
|
22437
|
+
}
|
|
22438
|
+
const generation = ++state.requestGeneration;
|
|
22314
22439
|
const promise2 = (async () => {
|
|
22315
22440
|
await Promise.all(
|
|
22316
22441
|
externalAgents.map(async (agent) => {
|
|
22317
22442
|
let status = "error";
|
|
22443
|
+
let nextError;
|
|
22318
22444
|
try {
|
|
22319
22445
|
const inspection = await client.inspectHarness({
|
|
22320
22446
|
harnessId: externalHarnessIds[agent],
|
|
22321
22447
|
refresh
|
|
22322
22448
|
});
|
|
22323
22449
|
status = inspection.status === "ready" ? "ready" : inspection.status;
|
|
22324
|
-
if (inspection.status
|
|
22325
|
-
harnessAvailabilityErrors[agent] = void 0;
|
|
22326
|
-
} else {
|
|
22450
|
+
if (inspection.status !== "ready") {
|
|
22327
22451
|
const error51 = inspection.error;
|
|
22328
|
-
|
|
22452
|
+
nextError = {
|
|
22329
22453
|
code: error51.code,
|
|
22330
22454
|
message: error51.message,
|
|
22331
22455
|
retryable: error51.retryable,
|
|
@@ -22337,24 +22461,29 @@ ${error51.stderrTail}`] : []
|
|
|
22337
22461
|
}
|
|
22338
22462
|
} catch (error51) {
|
|
22339
22463
|
status = "error";
|
|
22340
|
-
|
|
22464
|
+
nextError = {
|
|
22341
22465
|
code: "internalError",
|
|
22342
22466
|
message: error51 instanceof Error ? error51.message : String(error51),
|
|
22343
22467
|
retryable: true,
|
|
22344
22468
|
stage: "request"
|
|
22345
22469
|
};
|
|
22346
22470
|
}
|
|
22347
|
-
if (generation !==
|
|
22348
|
-
|
|
22471
|
+
if (generation !== state.requestGeneration || disposed) return;
|
|
22472
|
+
state.errors[agent] = nextError;
|
|
22473
|
+
state.availability = { ...state.availability, [agent]: status };
|
|
22474
|
+
if (hostId !== activeAvailabilityHostId) {
|
|
22475
|
+
publishConnectionStatus();
|
|
22476
|
+
return;
|
|
22477
|
+
}
|
|
22349
22478
|
for (const mounted of mountedByComposer.values()) {
|
|
22350
|
-
const
|
|
22351
|
-
if (adapterStatus.state === "ready" &&
|
|
22479
|
+
const composerState = controller.get(mounted.composer);
|
|
22480
|
+
if (adapterStatus.state === "ready" && composerState.phase === "draft" && composerState.agent === agent && status !== "ready") {
|
|
22352
22481
|
await switchComposerAgent(mounted, "codex");
|
|
22353
22482
|
}
|
|
22354
22483
|
}
|
|
22355
22484
|
for (const mounted of mountedByComposer.values()) {
|
|
22356
|
-
const
|
|
22357
|
-
if (
|
|
22485
|
+
const composerState = controller.get(mounted.composer);
|
|
22486
|
+
if (composerState.agent === agent) {
|
|
22358
22487
|
void loadExternalCatalog(mounted);
|
|
22359
22488
|
}
|
|
22360
22489
|
renderMounted(mounted);
|
|
@@ -22362,37 +22491,66 @@ ${error51.stderrTail}`] : []
|
|
|
22362
22491
|
publishConnectionStatus();
|
|
22363
22492
|
})
|
|
22364
22493
|
);
|
|
22365
|
-
if (
|
|
22366
|
-
|
|
22494
|
+
if (generation !== state.requestGeneration || disposed) return;
|
|
22495
|
+
if (externalAgents.every((agent) => state.availability[agent] === "ready")) {
|
|
22496
|
+
resetHarnessAvailabilityRetry(hostId);
|
|
22367
22497
|
} else {
|
|
22368
|
-
scheduleHarnessAvailabilityRetry();
|
|
22498
|
+
scheduleHarnessAvailabilityRetry(hostId);
|
|
22369
22499
|
}
|
|
22370
22500
|
})();
|
|
22371
22501
|
const request = { client, promise: promise2 };
|
|
22372
|
-
|
|
22502
|
+
state.request = request;
|
|
22373
22503
|
void promise2.then(
|
|
22374
22504
|
() => {
|
|
22375
|
-
if (
|
|
22505
|
+
if (state.request === request) state.request = null;
|
|
22376
22506
|
},
|
|
22377
22507
|
() => {
|
|
22378
|
-
if (
|
|
22508
|
+
if (state.request === request) state.request = null;
|
|
22379
22509
|
}
|
|
22380
22510
|
);
|
|
22381
22511
|
return promise2;
|
|
22512
|
+
}
|
|
22513
|
+
function reconcileHarnessAvailabilityHost() {
|
|
22514
|
+
const reportedHostId = modelControl?.currentHostId?.();
|
|
22515
|
+
const hostId = reportedHostId ?? (modelControl?.currentHostId ? activeAvailabilityHostId : "local");
|
|
22516
|
+
if (hostId === activeAvailabilityHostId) return;
|
|
22517
|
+
activeAvailabilityHostId = hostId;
|
|
22518
|
+
hostHarnessAvailabilityState(hostId);
|
|
22519
|
+
publishConnectionStatus();
|
|
22520
|
+
for (const mounted of mountedByComposer.values()) renderMounted(mounted);
|
|
22521
|
+
void refreshHarnessAvailabilityForHost(hostId);
|
|
22522
|
+
}
|
|
22523
|
+
const refreshHarnessAvailability = (refresh = false) => {
|
|
22524
|
+
reconcileHarnessAvailabilityHost();
|
|
22525
|
+
return refreshHarnessAvailabilityForHost(activeAvailabilityHostId, refresh);
|
|
22382
22526
|
};
|
|
22383
22527
|
connectionDiagnostics = {
|
|
22384
22528
|
snapshot() {
|
|
22529
|
+
const hostIds = [
|
|
22530
|
+
"local",
|
|
22531
|
+
...[...harnessAvailabilityByHost.keys()].filter((hostId) => hostId !== "local").sort()
|
|
22532
|
+
];
|
|
22385
22533
|
return {
|
|
22386
22534
|
adapter: { ...adapterStatus },
|
|
22387
|
-
|
|
22388
|
-
|
|
22389
|
-
|
|
22390
|
-
|
|
22391
|
-
|
|
22535
|
+
hosts: hostIds.map((hostId) => {
|
|
22536
|
+
const state = hostHarnessAvailabilityState(hostId);
|
|
22537
|
+
return {
|
|
22538
|
+
hostId,
|
|
22539
|
+
active: hostId === activeAvailabilityHostId,
|
|
22540
|
+
agents: externalAgents.map((agent) => ({
|
|
22541
|
+
agent,
|
|
22542
|
+
availability: state.availability[agent] ?? "checking",
|
|
22543
|
+
error: state.errors[agent] ?? null
|
|
22544
|
+
}))
|
|
22545
|
+
};
|
|
22546
|
+
})
|
|
22392
22547
|
};
|
|
22393
22548
|
},
|
|
22394
22549
|
refresh() {
|
|
22395
|
-
|
|
22550
|
+
for (const hostId of harnessAvailabilityByHost.keys()) {
|
|
22551
|
+
void refreshHarnessAvailabilityForHost(hostId, true);
|
|
22552
|
+
}
|
|
22553
|
+
return Promise.resolve();
|
|
22396
22554
|
},
|
|
22397
22555
|
subscribe(listener) {
|
|
22398
22556
|
connectionListeners.add(listener);
|
|
@@ -22523,6 +22681,16 @@ ${error51.stderrTail}`] : []
|
|
|
22523
22681
|
const composer = composerForEditor(editor);
|
|
22524
22682
|
if (composer) mount(composer);
|
|
22525
22683
|
}
|
|
22684
|
+
const localAvailability = hostHarnessAvailabilityState("local").availability;
|
|
22685
|
+
if (externalAgents.some((agent) => localAvailability[agent] === "checking")) {
|
|
22686
|
+
void refreshHarnessAvailabilityForHost("local");
|
|
22687
|
+
}
|
|
22688
|
+
reconcileHarnessAvailabilityHost();
|
|
22689
|
+
if (externalAgents.some(
|
|
22690
|
+
(agent) => activeHarnessAvailabilityState().availability[agent] === "checking"
|
|
22691
|
+
)) {
|
|
22692
|
+
void refreshHarnessAvailability();
|
|
22693
|
+
}
|
|
22526
22694
|
pendingReplacements.clear();
|
|
22527
22695
|
};
|
|
22528
22696
|
const scheduleScan = (refreshTargets = false) => {
|
|
@@ -22677,10 +22845,15 @@ ${error51.stderrTail}`] : []
|
|
|
22677
22845
|
transferReplacedComposers(mutations);
|
|
22678
22846
|
scheduleScan(mutations.some(mutationMayChangeComposerTarget));
|
|
22679
22847
|
});
|
|
22848
|
+
const onHostRouteChange = () => {
|
|
22849
|
+
reconcileHarnessAvailabilityHost();
|
|
22850
|
+
void refreshHarnessAvailability();
|
|
22851
|
+
};
|
|
22680
22852
|
const onAdapterStatus = () => {
|
|
22681
22853
|
publishConnectionStatus();
|
|
22682
22854
|
if (adapterStatus.state === "ready") {
|
|
22683
22855
|
sidebarAgentIcons.refresh();
|
|
22856
|
+
void refreshHarnessAvailabilityForHost("local");
|
|
22684
22857
|
void refreshHarnessAvailability();
|
|
22685
22858
|
for (const mounted of mountedByComposer.values()) {
|
|
22686
22859
|
if (mounted.modelView.status === "waitingForAdapter" && mounted.composer.isConnected && applyComposerAgent(mounted.composer)) {
|
|
@@ -22702,10 +22875,17 @@ ${error51.stderrTail}`] : []
|
|
|
22702
22875
|
document.addEventListener("keydown", onKeyDown, true);
|
|
22703
22876
|
document.addEventListener("click", onClick, true);
|
|
22704
22877
|
const onWindowFocus = () => {
|
|
22705
|
-
|
|
22878
|
+
reconcileHarnessAvailabilityHost();
|
|
22879
|
+
const local = hostHarnessAvailabilityState("local");
|
|
22880
|
+
if (externalAgents.some((agent) => local.availability[agent] !== "ready")) {
|
|
22881
|
+
void refreshHarnessAvailabilityForHost("local", true);
|
|
22882
|
+
}
|
|
22883
|
+
const active = activeHarnessAvailabilityState();
|
|
22884
|
+
if (externalAgents.some((agent) => active.availability[agent] !== "ready")) {
|
|
22706
22885
|
void refreshHarnessAvailability(true);
|
|
22707
22886
|
}
|
|
22708
22887
|
};
|
|
22888
|
+
window.addEventListener("codexhost:draft-prewarm-policy-changed", onHostRouteChange);
|
|
22709
22889
|
window.addEventListener("codexhost:renderer-adapter-status", onAdapterStatus);
|
|
22710
22890
|
window.addEventListener("focus", onWindowFocus);
|
|
22711
22891
|
const connectedComposers = () => [...mountedByComposer.values()].filter(
|
|
@@ -22722,7 +22902,7 @@ ${error51.stderrTail}`] : []
|
|
|
22722
22902
|
version: 2,
|
|
22723
22903
|
mountedComposers: selections.length,
|
|
22724
22904
|
enabledAgents: [...enabledAgents],
|
|
22725
|
-
availability: { ...
|
|
22905
|
+
availability: { ...activeHarnessAvailabilityState().availability },
|
|
22726
22906
|
selections,
|
|
22727
22907
|
adapter: { ...adapterStatus }
|
|
22728
22908
|
};
|
|
@@ -22769,8 +22949,16 @@ ${error51.stderrTail}`] : []
|
|
|
22769
22949
|
} catch {
|
|
22770
22950
|
}
|
|
22771
22951
|
});
|
|
22952
|
+
for (const state of harnessAvailabilityByHost.values()) {
|
|
22953
|
+
state.requestGeneration += 1;
|
|
22954
|
+
state.request = null;
|
|
22955
|
+
if (state.retryTimer !== null) window.clearTimeout(state.retryTimer);
|
|
22956
|
+
}
|
|
22957
|
+
harnessAvailabilityByHost.clear();
|
|
22958
|
+
activeAvailabilityHostId = "local";
|
|
22772
22959
|
sidebarAgentIcons.refresh();
|
|
22773
|
-
void
|
|
22960
|
+
void refreshHarnessAvailabilityForHost("local");
|
|
22961
|
+
reconcileHarnessAvailabilityHost();
|
|
22774
22962
|
const connected = connectedComposers();
|
|
22775
22963
|
if (connected.length === 1) {
|
|
22776
22964
|
const mounted = connected[0];
|
|
@@ -22803,9 +22991,14 @@ ${error51.stderrTail}`] : []
|
|
|
22803
22991
|
document.removeEventListener("submit", onSubmit, true);
|
|
22804
22992
|
document.removeEventListener("keydown", onKeyDown, true);
|
|
22805
22993
|
document.removeEventListener("click", onClick, true);
|
|
22994
|
+
window.removeEventListener("codexhost:draft-prewarm-policy-changed", onHostRouteChange);
|
|
22806
22995
|
window.removeEventListener("codexhost:renderer-adapter-status", onAdapterStatus);
|
|
22807
22996
|
window.removeEventListener("focus", onWindowFocus);
|
|
22808
|
-
|
|
22997
|
+
for (const state of harnessAvailabilityByHost.values()) {
|
|
22998
|
+
state.requestGeneration += 1;
|
|
22999
|
+
if (state.retryTimer !== null) window.clearTimeout(state.retryTimer);
|
|
23000
|
+
}
|
|
23001
|
+
harnessAvailabilityByHost.clear();
|
|
22809
23002
|
for (const timer of usageRefreshTimers.values()) window.clearTimeout(timer);
|
|
22810
23003
|
usageRefreshTimers.clear();
|
|
22811
23004
|
for (const mounted of mountedByComposer.values()) {
|