@codexhost/cli-linux-arm64 0.13.3 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +109 -11
- package/app/console-web.js +649 -132
- package/app/desktop-controller.mjs +120 -12
- package/app/host-runtime.mjs +1124 -293
- package/app/plugins/antigravity/plugin.mjs +431 -66
- package/app/plugins/claude-code/plugin.mjs +761 -139
- package/app/plugins/codebuddy/plugin.mjs +322 -68
- package/app/plugins/codex-usage/plugin.mjs +249 -102
- package/app/plugins/copilot/assets/icon.png +0 -0
- package/app/plugins/copilot/manifest.json +26 -0
- package/app/plugins/copilot/plugin.mjs +34591 -0
- package/app/plugins/cursor-cli/plugin.mjs +21011 -44970
- package/app/plugins/deepseek-harness/plugin.mjs +160 -43
- package/app/plugins/enabled.json +1 -0
- package/app/plugins/grok/plugin.mjs +565 -107
- package/app/plugins/hermes/plugin.mjs +128 -12
- package/app/plugins/kimi-code/plugin.mjs +136 -22
- package/app/plugins/kiro-cli/plugin.mjs +136 -22
- package/app/plugins/omp/plugin.mjs +2236 -2036
- package/app/plugins/opencode/plugin.mjs +187 -68
- package/app/plugins/pi/plugin.mjs +2621 -2304
- package/app/plugins/qoder/plugin.mjs +153 -36
- package/app/plugins/qoder-cn/plugin.mjs +153 -36
- package/app/plugins/workbuddy/plugin.mjs +583 -92
- package/app/plugins/zcode/plugin.mjs +183 -40
- package/app/renderer-extension.js +1758 -392
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
|
@@ -178,9 +178,10 @@
|
|
|
178
178
|
clearPendingSubmission(composer) {
|
|
179
179
|
this.#pendingSubmissions.delete(this.#state(composer));
|
|
180
180
|
}
|
|
181
|
+
/** Only a draft's submission creates a Thread, so only it sets the next new-Thread Agent. */
|
|
181
182
|
recordSubmission(composer) {
|
|
182
183
|
const state = this.#state(composer);
|
|
183
|
-
this.#lastSubmittedAgent = state.agent;
|
|
184
|
+
if (state.phase === "draft") this.#lastSubmittedAgent = state.agent;
|
|
184
185
|
return state;
|
|
185
186
|
}
|
|
186
187
|
transfer(source, replacement, target = null) {
|
|
@@ -3265,10 +3266,10 @@
|
|
|
3265
3266
|
const shape = def.shape;
|
|
3266
3267
|
const propValues = {};
|
|
3267
3268
|
for (const key in shape) {
|
|
3268
|
-
const
|
|
3269
|
-
if (
|
|
3269
|
+
const field2 = shape[key]._zod;
|
|
3270
|
+
if (field2.values) {
|
|
3270
3271
|
propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
|
|
3271
|
-
for (const v of
|
|
3272
|
+
for (const v of field2.values)
|
|
3272
3273
|
propValues[key].add(v);
|
|
3273
3274
|
}
|
|
3274
3275
|
}
|
|
@@ -14930,10 +14931,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14930
14931
|
var project = external_exports.string().min(1).max(4096);
|
|
14931
14932
|
var usageStatisticsParamsSchema = external_exports.strictObject({
|
|
14932
14933
|
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
14934
|
+
/** Display timezone for ranges, dates and hourly buckets; omitted means the Host's local zone. */
|
|
14935
|
+
timeZone: external_exports.string().min(1).max(128).refine((value) => {
|
|
14936
|
+
try {
|
|
14937
|
+
new Intl.DateTimeFormat("en", { timeZone: value });
|
|
14938
|
+
return true;
|
|
14939
|
+
} catch {
|
|
14940
|
+
return false;
|
|
14941
|
+
}
|
|
14942
|
+
}, "Unsupported usage statistics timezone").optional(),
|
|
14933
14943
|
harness: harness.optional(),
|
|
14934
14944
|
model: model.nullable().optional(),
|
|
14935
14945
|
project: project.nullable().optional(),
|
|
14936
|
-
/** One
|
|
14946
|
+
/** One date in the query timezone inside the range. */
|
|
14937
14947
|
date: localDate.optional()
|
|
14938
14948
|
});
|
|
14939
14949
|
var usageStatisticsTotalsSchema = external_exports.strictObject({
|
|
@@ -14969,7 +14979,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14969
14979
|
});
|
|
14970
14980
|
var usageStatisticsResultSchema = external_exports.strictObject({
|
|
14971
14981
|
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
14972
|
-
/** First
|
|
14982
|
+
/** First date in the query timezone (Host local when omitted); null for all time. */
|
|
14973
14983
|
from: localDate.nullable(),
|
|
14974
14984
|
to: localDate,
|
|
14975
14985
|
/** The filters these figures apply, echoed so a late answer to older filters is recognised. */
|
|
@@ -15009,7 +15019,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15009
15019
|
totals: usageStatisticsTotalsSchema,
|
|
15010
15020
|
/** Each date and Harness of the range: every filter except the day. */
|
|
15011
15021
|
daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
|
|
15012
|
-
/**
|
|
15022
|
+
/** Weekday (0 = Sunday) and hour in the query timezone, all filters applied. */
|
|
15013
15023
|
hourly: external_exports.array(external_exports.strictObject({
|
|
15014
15024
|
weekday: external_exports.number().int().min(0).max(6),
|
|
15015
15025
|
hour: external_exports.number().int().min(0).max(23),
|
|
@@ -15049,6 +15059,53 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15049
15059
|
var threadPrewarmDiscardParamsSchema = external_exports.object({ threadId: hostThreadIdSchema });
|
|
15050
15060
|
var threadPrewarmDiscardResultSchema = external_exports.object({ discarded: external_exports.boolean() });
|
|
15051
15061
|
|
|
15062
|
+
// ../shared-contracts/dist/thread-questions.js
|
|
15063
|
+
var THREAD_QUESTIONS_LIST_METHOD = "codexhost/thread/questions/list";
|
|
15064
|
+
var THREAD_QUESTION_RESPOND_METHOD = "codexhost/thread/question/respond";
|
|
15065
|
+
var field = external_exports.discriminatedUnion("type", [
|
|
15066
|
+
external_exports.object({
|
|
15067
|
+
id: external_exports.string().min(1),
|
|
15068
|
+
type: external_exports.literal("choice"),
|
|
15069
|
+
prompt: external_exports.string(),
|
|
15070
|
+
options: external_exports.array(external_exports.object({
|
|
15071
|
+
value: external_exports.string().min(1),
|
|
15072
|
+
label: external_exports.string(),
|
|
15073
|
+
description: external_exports.string().optional()
|
|
15074
|
+
})).min(1),
|
|
15075
|
+
multiple: external_exports.boolean(),
|
|
15076
|
+
allowOther: external_exports.boolean(),
|
|
15077
|
+
optional: external_exports.boolean()
|
|
15078
|
+
}),
|
|
15079
|
+
external_exports.object({
|
|
15080
|
+
id: external_exports.string().min(1),
|
|
15081
|
+
type: external_exports.literal("text"),
|
|
15082
|
+
prompt: external_exports.string(),
|
|
15083
|
+
multiline: external_exports.boolean(),
|
|
15084
|
+
secret: external_exports.literal(false),
|
|
15085
|
+
optional: external_exports.boolean(),
|
|
15086
|
+
placeholder: external_exports.string().optional(),
|
|
15087
|
+
prefill: external_exports.string().optional()
|
|
15088
|
+
})
|
|
15089
|
+
]);
|
|
15090
|
+
var threadQuestionSchema = external_exports.object({
|
|
15091
|
+
interactionId: external_exports.string().min(1),
|
|
15092
|
+
turnId: external_exports.string().min(1),
|
|
15093
|
+
title: external_exports.string().optional(),
|
|
15094
|
+
questions: external_exports.array(field).min(1)
|
|
15095
|
+
}).refine(({ questions }) => questions.some((q) => q.type === "choice" && q.multiple), {
|
|
15096
|
+
message: "Shared cards require at least one multi-select question"
|
|
15097
|
+
});
|
|
15098
|
+
var threadQuestionsListParamsSchema = external_exports.strictObject({ threadId: external_exports.string().min(1) });
|
|
15099
|
+
var threadQuestionsResultSchema = external_exports.object({ questions: external_exports.array(threadQuestionSchema) });
|
|
15100
|
+
var threadQuestionRespondParamsSchema = external_exports.strictObject({
|
|
15101
|
+
threadId: external_exports.string().min(1),
|
|
15102
|
+
turnId: external_exports.string().min(1),
|
|
15103
|
+
interactionId: external_exports.string().min(1),
|
|
15104
|
+
answers: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())),
|
|
15105
|
+
cancelled: external_exports.boolean().default(false)
|
|
15106
|
+
});
|
|
15107
|
+
var threadQuestionRespondResultSchema = external_exports.object({ accepted: external_exports.literal(true) });
|
|
15108
|
+
|
|
15052
15109
|
// ../shared-contracts/dist/console.js
|
|
15053
15110
|
var consoleAnnouncementSchema = external_exports.strictObject({
|
|
15054
15111
|
title: external_exports.string().trim().min(1).max(200),
|
|
@@ -15070,6 +15127,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15070
15127
|
"codexhost/harness/display-settings/set",
|
|
15071
15128
|
"codexhost/harness/inspect",
|
|
15072
15129
|
"codexhost/harness/installation",
|
|
15130
|
+
"codexhost/harness/installation/start",
|
|
15131
|
+
"codexhost/harness/installation/status",
|
|
15073
15132
|
"codexhost/harness/launch-settings/get",
|
|
15074
15133
|
"codexhost/harness/launch-settings/set",
|
|
15075
15134
|
"codexhost/harness/web-ui/open",
|
|
@@ -15148,7 +15207,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15148
15207
|
var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
|
|
15149
15208
|
var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
|
|
15150
15209
|
var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
15210
|
+
var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text) => text.length <= maximum));
|
|
15211
|
+
var composerIndicatorsSchema = external_exports.array(external_exports.object({
|
|
15212
|
+
kind: external_exports.literal("countdown"),
|
|
15213
|
+
id: external_exports.string().min(1).max(64),
|
|
15214
|
+
expiresAtUnix: nonNegativeSafeIntegerSchema,
|
|
15215
|
+
label: indicatorTextSchema(256).optional(),
|
|
15216
|
+
tooltip: indicatorTextSchema(1024).optional()
|
|
15217
|
+
}).strict()).max(2).refine((entries) => new Set(entries.map(({ id }) => id)).size === entries.length, {
|
|
15218
|
+
message: "Composer indicator IDs must be unique"
|
|
15219
|
+
});
|
|
15151
15220
|
var threadUsageSnapshotSchema = external_exports.object({
|
|
15221
|
+
composerIndicators: composerIndicatorsSchema.optional(),
|
|
15152
15222
|
inputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15153
15223
|
cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
15154
15224
|
cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -15564,7 +15634,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15564
15634
|
}).strict().optional(),
|
|
15565
15635
|
autonomousTurns: external_exports.object({
|
|
15566
15636
|
observe: external_exports.boolean()
|
|
15567
|
-
}).strict().optional()
|
|
15637
|
+
}).strict().optional(),
|
|
15638
|
+
/** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
|
|
15639
|
+
steer: external_exports.boolean().optional()
|
|
15568
15640
|
}).strict();
|
|
15569
15641
|
var harnessConfigurationStateSchema = external_exports.object({
|
|
15570
15642
|
effectiveModel: harnessModelRefSchema.optional(),
|
|
@@ -15612,7 +15684,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15612
15684
|
var harnessInspectParamsSchema = external_exports.object({
|
|
15613
15685
|
harnessId: harnessIdSchema,
|
|
15614
15686
|
cwd: nonBlankTextSchema2.max(16384).optional(),
|
|
15615
|
-
refresh: external_exports.boolean().optional()
|
|
15687
|
+
refresh: external_exports.boolean().optional(),
|
|
15688
|
+
/** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
|
|
15689
|
+
purpose: external_exports.literal("availability").optional()
|
|
15616
15690
|
}).strict();
|
|
15617
15691
|
var harnessWebUiOpenParamsSchema = external_exports.object({
|
|
15618
15692
|
harnessId: harnessIdSchema
|
|
@@ -15695,6 +15769,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15695
15769
|
seen.add(thread.threadId);
|
|
15696
15770
|
}
|
|
15697
15771
|
});
|
|
15772
|
+
var threadSteeringInspectParamsSchema = external_exports.object({
|
|
15773
|
+
threadId: hostThreadIdSchema,
|
|
15774
|
+
/** The text about to be steered; a Harness command always stops and restarts. */
|
|
15775
|
+
text: external_exports.string().optional()
|
|
15776
|
+
}).strict();
|
|
15777
|
+
var THREAD_STEER_DELIVERY_PARAM = "codexhostSteerDelivery";
|
|
15778
|
+
var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
|
|
15779
|
+
var threadSteeringInspectResultSchema = external_exports.object({
|
|
15780
|
+
delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
|
|
15781
|
+
}).strict();
|
|
15698
15782
|
|
|
15699
15783
|
// ../shared-contracts/dist/harness-plugins.js
|
|
15700
15784
|
var HARNESS_PLUGIN_MANIFEST_MAX_BYTES = 32 * 1024;
|
|
@@ -15813,7 +15897,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15813
15897
|
}).strict();
|
|
15814
15898
|
|
|
15815
15899
|
// ../shared-contracts/dist/harness-installation.js
|
|
15816
|
-
var
|
|
15900
|
+
var HARNESS_INSTALLATION_START_METHOD = "codexhost/harness/installation/start";
|
|
15901
|
+
var HARNESS_INSTALLATION_STATUS_METHOD = "codexhost/harness/installation/status";
|
|
15817
15902
|
var harnessInstallationParamsSchema = external_exports.object({
|
|
15818
15903
|
harnessId: harnessIdSchema,
|
|
15819
15904
|
action: external_exports.enum(["check", "update", "install"])
|
|
@@ -15823,6 +15908,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15823
15908
|
latestVersion: external_exports.string().min(1).max(128),
|
|
15824
15909
|
updateAvailable: external_exports.boolean(),
|
|
15825
15910
|
canUpdate: external_exports.boolean(),
|
|
15911
|
+
/** Defaults to CLI; some Harnesses ship only inside a desktop application. */
|
|
15912
|
+
versionKind: external_exports.enum(["cli", "application"]).optional(),
|
|
15913
|
+
/** Official download opened by the user; does not imply an automatic installation. */
|
|
15914
|
+
manualUpdateUrl: external_exports.url().max(2048).refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Manual updates require a credential-free HTTPS URL").optional(),
|
|
15826
15915
|
// Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
|
|
15827
15916
|
message: external_exports.string().max(2048).optional(),
|
|
15828
15917
|
messageCode: external_exports.string().min(1).max(128).optional(),
|
|
@@ -15830,6 +15919,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15830
15919
|
notice: harnessLocalizedTextSchema.optional(),
|
|
15831
15920
|
latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
|
|
15832
15921
|
}).strict();
|
|
15922
|
+
var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
|
|
15923
|
+
var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
|
|
15924
|
+
external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
|
|
15925
|
+
external_exports.object({
|
|
15926
|
+
taskId: external_exports.string().uuid(),
|
|
15927
|
+
status: external_exports.literal("succeeded"),
|
|
15928
|
+
result: harnessInstallationStateSchema
|
|
15929
|
+
}).strict(),
|
|
15930
|
+
external_exports.object({
|
|
15931
|
+
taskId: external_exports.string().uuid(),
|
|
15932
|
+
status: external_exports.literal("failed"),
|
|
15933
|
+
error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
|
|
15934
|
+
}).strict()
|
|
15935
|
+
]);
|
|
15833
15936
|
|
|
15834
15937
|
// ../shared-contracts/dist/codex-accounts.js
|
|
15835
15938
|
var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
|
|
@@ -16240,9 +16343,63 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16240
16343
|
// ../shared-contracts/dist/index.js
|
|
16241
16344
|
var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
|
|
16242
16345
|
|
|
16243
|
-
// src/codex-
|
|
16346
|
+
// src/codex-native-services.ts
|
|
16347
|
+
async function loadCodexNativeServices(ownerWindow, matchesServices, importModule = (url2) => import(url2)) {
|
|
16348
|
+
if (!ownerWindow.document || !ownerWindow.location) return null;
|
|
16349
|
+
const page = new URL(ownerWindow.location.href);
|
|
16350
|
+
const urls = /* @__PURE__ */ new Set();
|
|
16351
|
+
for (const link of ownerWindow.document.querySelectorAll('link[rel="modulepreload"][href]')) {
|
|
16352
|
+
const url2 = new URL(link.getAttribute("href") ?? "", page);
|
|
16353
|
+
if (url2.protocol === page.protocol && url2.host === page.host && url2.pathname.endsWith(".js") && !url2.search && !url2.hash)
|
|
16354
|
+
urls.add(url2.href);
|
|
16355
|
+
}
|
|
16356
|
+
const candidates = [...urls].sort(
|
|
16357
|
+
(a, b) => Number(b.includes("/app-shared-")) - Number(a.includes("/app-shared-"))
|
|
16358
|
+
);
|
|
16359
|
+
const matches = /* @__PURE__ */ new Set();
|
|
16360
|
+
for (const url2 of candidates) {
|
|
16361
|
+
let module;
|
|
16362
|
+
try {
|
|
16363
|
+
module = await importModule(url2);
|
|
16364
|
+
} catch {
|
|
16365
|
+
continue;
|
|
16366
|
+
}
|
|
16367
|
+
for (const value of Object.values(module).filter(matchesServices)) matches.add(value);
|
|
16368
|
+
if (matches.size > 1) throw new Error("Codex native services are unavailable in this window");
|
|
16369
|
+
}
|
|
16370
|
+
return [...matches][0] ?? null;
|
|
16371
|
+
}
|
|
16372
|
+
|
|
16373
|
+
// src/codex-ssh-services.ts
|
|
16244
16374
|
var record2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16375
|
+
function isSshServices(value) {
|
|
16376
|
+
if (!record2(value) || !Object.hasOwn(value, "sshConnections") || !Object.hasOwn(value, "remoteConnections"))
|
|
16377
|
+
return false;
|
|
16378
|
+
const ssh = value.sshConnections;
|
|
16379
|
+
const remote = value.remoteConnections;
|
|
16380
|
+
return ssh != null && remote != null && typeof ssh.refresh === "function" && typeof ssh.save === "function" && typeof remote.getState === "function" && typeof remote.setAutoConnect === "function";
|
|
16381
|
+
}
|
|
16382
|
+
async function loadCodexSshServices(ownerWindow, importModule) {
|
|
16383
|
+
return loadCodexNativeServices(ownerWindow, isSshServices, importModule);
|
|
16384
|
+
}
|
|
16385
|
+
|
|
16386
|
+
// src/codex-ssh-adapter.ts
|
|
16387
|
+
var record3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16245
16388
|
function createCodexSshClient(ownerWindow) {
|
|
16389
|
+
let nativeServices;
|
|
16390
|
+
function services() {
|
|
16391
|
+
nativeServices ??= loadCodexSshServices(ownerWindow).then(
|
|
16392
|
+
(value) => {
|
|
16393
|
+
if (!value) nativeServices = void 0;
|
|
16394
|
+
return value;
|
|
16395
|
+
},
|
|
16396
|
+
(error51) => {
|
|
16397
|
+
nativeServices = void 0;
|
|
16398
|
+
throw error51;
|
|
16399
|
+
}
|
|
16400
|
+
);
|
|
16401
|
+
return nativeServices;
|
|
16402
|
+
}
|
|
16246
16403
|
function request(operation, params, signal) {
|
|
16247
16404
|
const bridge = ownerWindow.electronBridge;
|
|
16248
16405
|
if (!bridge?.sendMessageFromView)
|
|
@@ -16250,7 +16407,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16250
16407
|
if (signal?.aborted) return Promise.reject(new DOMException("Aborted", "AbortError"));
|
|
16251
16408
|
return new Promise((resolve, reject) => {
|
|
16252
16409
|
const requestId = ownerWindow.crypto.randomUUID();
|
|
16410
|
+
let settled = false;
|
|
16253
16411
|
const finish = (error51, value) => {
|
|
16412
|
+
if (settled) return;
|
|
16413
|
+
settled = true;
|
|
16254
16414
|
ownerWindow.clearTimeout(timer);
|
|
16255
16415
|
ownerWindow.removeEventListener("message", receive);
|
|
16256
16416
|
signal?.removeEventListener("abort", abort);
|
|
@@ -16260,10 +16420,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16260
16420
|
const abort = () => finish(new DOMException("Aborted", "AbortError"));
|
|
16261
16421
|
const receive = (event) => {
|
|
16262
16422
|
const message2 = event.data;
|
|
16263
|
-
if (!
|
|
16423
|
+
if (!record3(message2) || message2.type !== "fetch-response" || message2.requestId !== requestId)
|
|
16264
16424
|
return;
|
|
16265
16425
|
if (message2.responseType !== "success" || typeof message2.status !== "number" || message2.status < 200 || message2.status >= 300 || typeof message2.bodyJsonString !== "string") {
|
|
16266
|
-
|
|
16426
|
+
const detail = typeof message2.error === "string" ? `: ${message2.error}` : "";
|
|
16427
|
+
finish(
|
|
16428
|
+
new Error(`Codex SSH request failed; check the native Connections settings${detail}`)
|
|
16429
|
+
);
|
|
16267
16430
|
return;
|
|
16268
16431
|
}
|
|
16269
16432
|
try {
|
|
@@ -16278,30 +16441,47 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16278
16441
|
);
|
|
16279
16442
|
ownerWindow.addEventListener("message", receive);
|
|
16280
16443
|
signal?.addEventListener("abort", abort, { once: true });
|
|
16281
|
-
|
|
16282
|
-
|
|
16283
|
-
|
|
16444
|
+
void (async () => {
|
|
16445
|
+
const native = await services();
|
|
16446
|
+
if (settled) return;
|
|
16447
|
+
if (native) {
|
|
16448
|
+
let result;
|
|
16449
|
+
switch (operation) {
|
|
16450
|
+
case "refresh-remote-connections":
|
|
16451
|
+
result = await native.sshConnections.refresh();
|
|
16452
|
+
break;
|
|
16453
|
+
case "save-codex-managed-remote-ssh-connections":
|
|
16454
|
+
result = await native.sshConnections.save(params);
|
|
16455
|
+
break;
|
|
16456
|
+
case "set-remote-connection-auto-connect":
|
|
16457
|
+
result = await native.remoteConnections.setAutoConnect(params);
|
|
16458
|
+
break;
|
|
16459
|
+
case "app-server-connection-state":
|
|
16460
|
+
result = await native.remoteConnections.getState(String(params.hostId));
|
|
16461
|
+
break;
|
|
16462
|
+
}
|
|
16463
|
+
finish(null, result);
|
|
16464
|
+
} else {
|
|
16465
|
+
await bridge.sendMessageFromView({
|
|
16284
16466
|
type: "fetch",
|
|
16285
16467
|
requestId,
|
|
16286
16468
|
method: "POST",
|
|
16287
16469
|
url: `vscode://codex/${operation}`,
|
|
16288
16470
|
body: JSON.stringify(params),
|
|
16289
16471
|
reportUploadProgress: false
|
|
16290
|
-
})
|
|
16291
|
-
|
|
16292
|
-
}
|
|
16293
|
-
finish(error51);
|
|
16294
|
-
}
|
|
16472
|
+
});
|
|
16473
|
+
}
|
|
16474
|
+
})().catch((error51) => finish(error51));
|
|
16295
16475
|
});
|
|
16296
16476
|
}
|
|
16297
16477
|
async function list(signal) {
|
|
16298
16478
|
const result = await request("refresh-remote-connections", {}, signal);
|
|
16299
|
-
if (!
|
|
16479
|
+
if (!record3(result) || !Array.isArray(result.remoteConnections))
|
|
16300
16480
|
throw new Error("Invalid Codex SSH connection list");
|
|
16301
16481
|
return result.remoteConnections.filter(
|
|
16302
|
-
(item) => !(
|
|
16482
|
+
(item) => !(record3(item) && ["wsl", "remote-control"].includes(String(item.source)))
|
|
16303
16483
|
).map((item) => {
|
|
16304
|
-
if (!
|
|
16484
|
+
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)) {
|
|
16305
16485
|
throw new Error(
|
|
16306
16486
|
"This Codex version uses an unsupported SSH configuration; open native settings"
|
|
16307
16487
|
);
|
|
@@ -16373,11 +16553,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16373
16553
|
},
|
|
16374
16554
|
async state(hostId2, signal) {
|
|
16375
16555
|
const result = await request("app-server-connection-state", { hostId: hostId2 }, signal);
|
|
16376
|
-
if (!
|
|
16556
|
+
if (!record3(result) || typeof result.state !== "string")
|
|
16377
16557
|
throw new Error("Invalid Codex connection state");
|
|
16378
16558
|
return {
|
|
16379
16559
|
state: result.state,
|
|
16380
|
-
error: typeof result.error === "string" ? result.error :
|
|
16560
|
+
error: typeof result.error === "string" ? result.error : record3(result.error) && typeof result.error.message === "string" ? result.error.message : null
|
|
16381
16561
|
};
|
|
16382
16562
|
}
|
|
16383
16563
|
};
|
|
@@ -16455,6 +16635,545 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16455
16635
|
return control;
|
|
16456
16636
|
}
|
|
16457
16637
|
|
|
16638
|
+
// ../../node_modules/lucide/dist/esm/defaultAttributes.mjs
|
|
16639
|
+
var defaultAttributes = {
|
|
16640
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
16641
|
+
width: 24,
|
|
16642
|
+
height: 24,
|
|
16643
|
+
viewBox: "0 0 24 24",
|
|
16644
|
+
fill: "none",
|
|
16645
|
+
stroke: "currentColor",
|
|
16646
|
+
"stroke-width": 2,
|
|
16647
|
+
"stroke-linecap": "round",
|
|
16648
|
+
"stroke-linejoin": "round"
|
|
16649
|
+
};
|
|
16650
|
+
|
|
16651
|
+
// ../../node_modules/lucide/dist/esm/createElement.mjs
|
|
16652
|
+
var createSVGElement = ([tag, attrs, children]) => {
|
|
16653
|
+
const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
16654
|
+
Object.keys(attrs).forEach((name) => {
|
|
16655
|
+
element.setAttribute(name, String(attrs[name]));
|
|
16656
|
+
});
|
|
16657
|
+
if (children?.length) {
|
|
16658
|
+
children.forEach((child) => {
|
|
16659
|
+
const childElement = createSVGElement(child);
|
|
16660
|
+
element.appendChild(childElement);
|
|
16661
|
+
});
|
|
16662
|
+
}
|
|
16663
|
+
return element;
|
|
16664
|
+
};
|
|
16665
|
+
var createElement = (iconNode, customAttrs = {}) => {
|
|
16666
|
+
const tag = "svg";
|
|
16667
|
+
const attrs = {
|
|
16668
|
+
...defaultAttributes,
|
|
16669
|
+
...customAttrs
|
|
16670
|
+
};
|
|
16671
|
+
return createSVGElement([tag, attrs, iconNode]);
|
|
16672
|
+
};
|
|
16673
|
+
|
|
16674
|
+
// ../../node_modules/lucide/dist/esm/icons/check.mjs
|
|
16675
|
+
var Check = [["path", { d: "M20 6 9 17l-5-5" }]];
|
|
16676
|
+
|
|
16677
|
+
// ../../node_modules/lucide/dist/esm/icons/message-circle-question-mark.mjs
|
|
16678
|
+
var MessageCircleQuestionMark = [
|
|
16679
|
+
[
|
|
16680
|
+
"path",
|
|
16681
|
+
{
|
|
16682
|
+
d: "M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"
|
|
16683
|
+
}
|
|
16684
|
+
],
|
|
16685
|
+
["path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }],
|
|
16686
|
+
["path", { d: "M12 17h.01" }]
|
|
16687
|
+
];
|
|
16688
|
+
|
|
16689
|
+
// ../../node_modules/lucide/dist/esm/icons/pencil.mjs
|
|
16690
|
+
var Pencil = [
|
|
16691
|
+
[
|
|
16692
|
+
"path",
|
|
16693
|
+
{
|
|
16694
|
+
d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"
|
|
16695
|
+
}
|
|
16696
|
+
],
|
|
16697
|
+
["path", { d: "m15 5 4 4" }]
|
|
16698
|
+
];
|
|
16699
|
+
|
|
16700
|
+
// ../../node_modules/lucide/dist/esm/icons/x.mjs
|
|
16701
|
+
var X = [
|
|
16702
|
+
["path", { d: "M18 6 6 18" }],
|
|
16703
|
+
["path", { d: "m6 6 12 12" }]
|
|
16704
|
+
];
|
|
16705
|
+
|
|
16706
|
+
// src/renderer-question-card-style.ts
|
|
16707
|
+
var QUESTION_CARD_CSS = `
|
|
16708
|
+
:host {
|
|
16709
|
+
display: block;
|
|
16710
|
+
min-width: 0;
|
|
16711
|
+
margin: 8px 0;
|
|
16712
|
+
color-scheme: inherit;
|
|
16713
|
+
--question-text: light-dark(#171717, #ececec);
|
|
16714
|
+
--question-muted: light-dark(#737373, #a3a3a3);
|
|
16715
|
+
--question-border: light-dark(rgb(0 0 0 / 8%), rgb(255 255 255 / 8%));
|
|
16716
|
+
--question-selected: light-dark(#e9e9e9, #333333);
|
|
16717
|
+
--question-primary: light-dark(#202020, #ececec);
|
|
16718
|
+
--question-primary-text: light-dark(#fff, #171717);
|
|
16719
|
+
}
|
|
16720
|
+
*, ::before, ::after { box-sizing: border-box; }
|
|
16721
|
+
.card {
|
|
16722
|
+
display: flex;
|
|
16723
|
+
flex-direction: column;
|
|
16724
|
+
max-height: min(60vh, 560px);
|
|
16725
|
+
overflow: hidden;
|
|
16726
|
+
padding: 16px 12px 12px;
|
|
16727
|
+
border: 1px solid var(--question-border);
|
|
16728
|
+
border-radius: 24px;
|
|
16729
|
+
background: light-dark(#f7f7f7, #262626);
|
|
16730
|
+
color: var(--question-text);
|
|
16731
|
+
font: 13px/1.5 system-ui, sans-serif;
|
|
16732
|
+
}
|
|
16733
|
+
.title { display: flex; align-items: center; gap: 10px; flex-shrink: 0; margin: 0 6px 14px; color: var(--question-muted); font-weight: 400; }
|
|
16734
|
+
.question-icon { display: inline-flex; justify-content: center; align-items: center; width: 16px; height: 16px; flex-shrink: 0; }
|
|
16735
|
+
svg { display: block; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
|
|
16736
|
+
.body { min-height: 0; overflow: auto; }
|
|
16737
|
+
fieldset { min-width: 0; border: 0; padding: 0; margin: 0 0 14px; }
|
|
16738
|
+
fieldset:last-child { margin-bottom: 0; }
|
|
16739
|
+
legend { width: 100%; padding: 0 6px; margin-bottom: 14px; font: inherit; }
|
|
16740
|
+
.hint { color: var(--question-muted); font-size: 12px; margin: -10px 6px 10px; }
|
|
16741
|
+
.option {
|
|
16742
|
+
position: relative;
|
|
16743
|
+
display: flex;
|
|
16744
|
+
align-items: flex-start;
|
|
16745
|
+
gap: 10px;
|
|
16746
|
+
min-height: 34px;
|
|
16747
|
+
padding: 6px;
|
|
16748
|
+
margin: 2px 0;
|
|
16749
|
+
border-radius: 12px;
|
|
16750
|
+
cursor: pointer;
|
|
16751
|
+
background: transparent;
|
|
16752
|
+
overflow-wrap: anywhere;
|
|
16753
|
+
}
|
|
16754
|
+
.option:hover, .option:has(:checked) { background: var(--question-selected); }
|
|
16755
|
+
input[type=checkbox], input[type=radio] {
|
|
16756
|
+
appearance: none;
|
|
16757
|
+
display: block;
|
|
16758
|
+
flex: 0 0 21px;
|
|
16759
|
+
width: 21px;
|
|
16760
|
+
height: 21px;
|
|
16761
|
+
margin: 0;
|
|
16762
|
+
padding: 0;
|
|
16763
|
+
border: 1px solid var(--question-border);
|
|
16764
|
+
border-radius: 5px;
|
|
16765
|
+
background: light-dark(#ededed, #303030);
|
|
16766
|
+
cursor: pointer;
|
|
16767
|
+
}
|
|
16768
|
+
.shortcut { position: absolute; top: 6px; left: 6px; width: 21px; height: 21px; text-align: center; line-height: 21px; color: var(--question-muted); pointer-events: none; font-size: 12px; }
|
|
16769
|
+
.option-copy { flex: 1; min-width: 0; white-space: pre-wrap; }
|
|
16770
|
+
.option-name { display: block; font-weight: 400; }
|
|
16771
|
+
.description { display: block; color: var(--question-muted); font-size: 12px; margin-top: 1px; }
|
|
16772
|
+
.selected-indicator { align-self: center; visibility: hidden; color: var(--question-muted); padding-right: 4px; }
|
|
16773
|
+
:checked ~ .selected-indicator { visibility: visible; }
|
|
16774
|
+
.other { align-items: center; flex: 1; min-width: 0; margin: 0; }
|
|
16775
|
+
.other input[type=checkbox], .other input[type=radio] { background: transparent; border-color: transparent; }
|
|
16776
|
+
.other:has(:checked), .other:focus-within { background: var(--question-selected); }
|
|
16777
|
+
.other:has(:checked) .pencil { color: var(--question-text); }
|
|
16778
|
+
.pencil { display: flex; align-items: center; justify-content: center; }
|
|
16779
|
+
.other-copy { display: flex; flex: 1; min-width: 0; }
|
|
16780
|
+
input:not([type=checkbox]):not([type=radio]), textarea {
|
|
16781
|
+
appearance: none;
|
|
16782
|
+
display: block;
|
|
16783
|
+
min-width: 0;
|
|
16784
|
+
width: 100%;
|
|
16785
|
+
padding: 6px;
|
|
16786
|
+
border: 1px solid var(--question-border);
|
|
16787
|
+
border-radius: 8px;
|
|
16788
|
+
background: transparent;
|
|
16789
|
+
color: var(--question-text);
|
|
16790
|
+
font: inherit;
|
|
16791
|
+
}
|
|
16792
|
+
.other-copy input:not([type=checkbox]):not([type=radio]) { border: 0; padding: 0; }
|
|
16793
|
+
textarea { min-height: 60px; resize: vertical; }
|
|
16794
|
+
input::placeholder, textarea::placeholder { color: var(--question-muted); opacity: .65; }
|
|
16795
|
+
input:focus-visible, textarea:focus-visible, button:focus-visible {
|
|
16796
|
+
outline: 2px solid var(--question-muted);
|
|
16797
|
+
outline-offset: 2px;
|
|
16798
|
+
}
|
|
16799
|
+
.other-copy input:focus-visible { outline: none; }
|
|
16800
|
+
.other:has(input:focus-visible) { outline: 2px solid var(--question-muted); outline-offset: -2px; }
|
|
16801
|
+
.error { flex-shrink: 0; color: light-dark(#b42318, #ffaaa3); font-size: 12px; }
|
|
16802
|
+
.error:not(:empty) { margin: 8px 6px 0; }
|
|
16803
|
+
.footer { display: flex; align-items: center; gap: 8px; flex-shrink: 0; margin-top: 8px; }
|
|
16804
|
+
.actions { display: flex; justify-content: flex-end; gap: 8px; margin-left: auto; flex-shrink: 0; }
|
|
16805
|
+
button {
|
|
16806
|
+
appearance: none;
|
|
16807
|
+
min-height: 28px;
|
|
16808
|
+
padding: 3px 10px;
|
|
16809
|
+
border: 1px solid var(--question-border);
|
|
16810
|
+
border-radius: 999px;
|
|
16811
|
+
background: transparent;
|
|
16812
|
+
color: var(--question-text);
|
|
16813
|
+
font: inherit;
|
|
16814
|
+
font-weight: 400;
|
|
16815
|
+
cursor: pointer;
|
|
16816
|
+
}
|
|
16817
|
+
button:hover { background: var(--question-selected); }
|
|
16818
|
+
button.primary { background: var(--question-primary); color: var(--question-primary-text); border-color: transparent; }
|
|
16819
|
+
button.primary:hover { opacity: .85; }
|
|
16820
|
+
button.dismiss { display: flex; align-items: center; justify-content: center; border: 0; padding: 0; min-height: 24px; width: 24px; margin-left: auto; color: var(--question-muted); }
|
|
16821
|
+
:disabled { cursor: wait; opacity: .5; }
|
|
16822
|
+
@media (max-width: 420px) { .footer { flex-wrap: wrap; } .footer > .other { flex-basis: 100%; } }
|
|
16823
|
+
@media (forced-colors: active) {
|
|
16824
|
+
.card, input, textarea { background: Canvas; color: CanvasText; }
|
|
16825
|
+
button, .card, input[type=checkbox], input[type=radio] { border-color: ButtonBorder; }
|
|
16826
|
+
.option:has(:checked) { outline: 1px solid Highlight; outline-offset: -1px; }
|
|
16827
|
+
button.primary { background: Highlight; color: HighlightText; }
|
|
16828
|
+
}
|
|
16829
|
+
`;
|
|
16830
|
+
|
|
16831
|
+
// src/renderer-question-card.ts
|
|
16832
|
+
function createQuestionCard(document2, question, submit, initial = {}) {
|
|
16833
|
+
const icon2 = (node) => document2.adoptNode(
|
|
16834
|
+
createElement(node, {
|
|
16835
|
+
width: 16,
|
|
16836
|
+
height: 16,
|
|
16837
|
+
"aria-hidden": "true",
|
|
16838
|
+
focusable: "false"
|
|
16839
|
+
})
|
|
16840
|
+
);
|
|
16841
|
+
const selectedIndicator = () => {
|
|
16842
|
+
const selected = document2.createElement("span");
|
|
16843
|
+
selected.className = "selected-indicator";
|
|
16844
|
+
selected.setAttribute("aria-hidden", "true");
|
|
16845
|
+
selected.append(icon2(Check));
|
|
16846
|
+
return selected;
|
|
16847
|
+
};
|
|
16848
|
+
const root = document2.createElement("section");
|
|
16849
|
+
root.dataset.codexhostQuestion = question.interactionId;
|
|
16850
|
+
root.setAttribute("aria-label", question.title ?? "Question");
|
|
16851
|
+
root.addEventListener("keydown", (event) => {
|
|
16852
|
+
event.stopPropagation();
|
|
16853
|
+
if (event.key === "Enter" && event.composedPath()[0] instanceof HTMLInputElement)
|
|
16854
|
+
event.preventDefault();
|
|
16855
|
+
});
|
|
16856
|
+
const shadow = root.attachShadow({ mode: "open" });
|
|
16857
|
+
const style = document2.createElement("style");
|
|
16858
|
+
style.textContent = QUESTION_CARD_CSS;
|
|
16859
|
+
const surface = document2.createElement("div");
|
|
16860
|
+
surface.className = "card";
|
|
16861
|
+
shadow.append(style, surface);
|
|
16862
|
+
const title = document2.createElement("div");
|
|
16863
|
+
title.className = "title";
|
|
16864
|
+
const titleIcon = document2.createElement("span");
|
|
16865
|
+
titleIcon.className = "question-icon";
|
|
16866
|
+
titleIcon.append(icon2(MessageCircleQuestionMark));
|
|
16867
|
+
titleIcon.setAttribute("aria-hidden", "true");
|
|
16868
|
+
const titleText = document2.createElement("span");
|
|
16869
|
+
titleText.textContent = question.title?.trim() || "Question";
|
|
16870
|
+
const dismiss = document2.createElement("button");
|
|
16871
|
+
dismiss.type = "button";
|
|
16872
|
+
dismiss.className = "dismiss";
|
|
16873
|
+
dismiss.append(icon2(X));
|
|
16874
|
+
dismiss.setAttribute("aria-label", "Dismiss question");
|
|
16875
|
+
title.append(titleIcon, titleText, dismiss);
|
|
16876
|
+
const body = document2.createElement("div");
|
|
16877
|
+
body.className = "body";
|
|
16878
|
+
surface.append(title, body);
|
|
16879
|
+
const footer = document2.createElement("div");
|
|
16880
|
+
footer.className = "footer";
|
|
16881
|
+
const readers = /* @__PURE__ */ new Map();
|
|
16882
|
+
const controls = [dismiss];
|
|
16883
|
+
const validOther = [];
|
|
16884
|
+
for (const [index, field2] of question.questions.entries()) {
|
|
16885
|
+
const group = document2.createElement("fieldset");
|
|
16886
|
+
const legend = document2.createElement("legend");
|
|
16887
|
+
legend.textContent = field2.prompt;
|
|
16888
|
+
group.append(legend);
|
|
16889
|
+
const saved = initial[field2.id] ?? [];
|
|
16890
|
+
if (field2.type === "text") {
|
|
16891
|
+
const input = document2.createElement(field2.multiline ? "textarea" : "input");
|
|
16892
|
+
input.value = saved[0] ?? field2.prefill ?? "";
|
|
16893
|
+
input.placeholder = field2.placeholder ?? "Your answer";
|
|
16894
|
+
input.setAttribute("aria-label", field2.prompt);
|
|
16895
|
+
controls.push(input);
|
|
16896
|
+
group.append(input);
|
|
16897
|
+
readers.set(field2.id, () => input.value.trim() ? [input.value] : []);
|
|
16898
|
+
} else {
|
|
16899
|
+
const hint = document2.createElement("div");
|
|
16900
|
+
hint.className = "hint";
|
|
16901
|
+
hint.textContent = "Select all that apply";
|
|
16902
|
+
if (field2.multiple) group.append(hint);
|
|
16903
|
+
const inputs = [];
|
|
16904
|
+
const name = `codexhost-${question.interactionId}-${index}`;
|
|
16905
|
+
for (const [optionIndex, option] of field2.options.entries()) {
|
|
16906
|
+
const label = document2.createElement("label");
|
|
16907
|
+
label.className = "option";
|
|
16908
|
+
const input = document2.createElement("input");
|
|
16909
|
+
input.type = field2.multiple ? "checkbox" : "radio";
|
|
16910
|
+
input.name = name;
|
|
16911
|
+
input.value = option.value;
|
|
16912
|
+
input.checked = saved.includes(option.value);
|
|
16913
|
+
const shortcut = document2.createElement("span");
|
|
16914
|
+
shortcut.className = "shortcut";
|
|
16915
|
+
shortcut.setAttribute("aria-hidden", "true");
|
|
16916
|
+
shortcut.textContent = String(optionIndex + 1);
|
|
16917
|
+
const selected = selectedIndicator();
|
|
16918
|
+
const text = document2.createElement("span");
|
|
16919
|
+
text.className = "option-copy";
|
|
16920
|
+
const optionName = document2.createElement("span");
|
|
16921
|
+
optionName.className = "option-name";
|
|
16922
|
+
optionName.textContent = option.label;
|
|
16923
|
+
text.append(optionName);
|
|
16924
|
+
if (option.description) {
|
|
16925
|
+
const description = document2.createElement("span");
|
|
16926
|
+
description.className = "description";
|
|
16927
|
+
description.textContent = option.description;
|
|
16928
|
+
text.append(description);
|
|
16929
|
+
}
|
|
16930
|
+
label.append(input, shortcut, text, selected);
|
|
16931
|
+
group.append(label);
|
|
16932
|
+
inputs.push(input);
|
|
16933
|
+
controls.push(input);
|
|
16934
|
+
}
|
|
16935
|
+
let other;
|
|
16936
|
+
let notes;
|
|
16937
|
+
if (field2.allowOther) {
|
|
16938
|
+
const label = document2.createElement("label");
|
|
16939
|
+
label.className = "option other";
|
|
16940
|
+
other = document2.createElement("input");
|
|
16941
|
+
other.type = field2.multiple ? "checkbox" : "radio";
|
|
16942
|
+
other.name = name;
|
|
16943
|
+
other.setAttribute("aria-label", `Other: ${field2.prompt}`);
|
|
16944
|
+
const unknown2 = saved.find(
|
|
16945
|
+
(value) => !field2.options.some((option) => option.value === value)
|
|
16946
|
+
);
|
|
16947
|
+
other.checked = unknown2 !== void 0;
|
|
16948
|
+
notes = document2.createElement("input");
|
|
16949
|
+
notes.value = unknown2 ?? "";
|
|
16950
|
+
notes.placeholder = "Or write your own response";
|
|
16951
|
+
notes.setAttribute("aria-label", `${field2.prompt}: Other`);
|
|
16952
|
+
const checkbox = other;
|
|
16953
|
+
const otherText = notes;
|
|
16954
|
+
validOther.push(() => !checkbox.checked || otherText.value.trim().length > 0);
|
|
16955
|
+
notes.addEventListener("input", () => {
|
|
16956
|
+
checkbox.checked = true;
|
|
16957
|
+
});
|
|
16958
|
+
const copy = document2.createElement("span");
|
|
16959
|
+
copy.className = "other-copy";
|
|
16960
|
+
copy.append(notes);
|
|
16961
|
+
const pencil = document2.createElement("span");
|
|
16962
|
+
pencil.className = "shortcut pencil";
|
|
16963
|
+
pencil.append(icon2(Pencil));
|
|
16964
|
+
pencil.setAttribute("aria-hidden", "true");
|
|
16965
|
+
const selected = selectedIndicator();
|
|
16966
|
+
label.append(other, pencil, copy, selected);
|
|
16967
|
+
if (question.questions.length === 1) footer.append(label);
|
|
16968
|
+
else group.append(label);
|
|
16969
|
+
controls.push(other, notes);
|
|
16970
|
+
}
|
|
16971
|
+
readers.set(field2.id, () => [
|
|
16972
|
+
...inputs.filter((input) => input.checked).map((input) => input.value),
|
|
16973
|
+
...other?.checked && notes?.value.trim() ? [notes.value] : []
|
|
16974
|
+
]);
|
|
16975
|
+
}
|
|
16976
|
+
body.append(group);
|
|
16977
|
+
}
|
|
16978
|
+
const error51 = document2.createElement("div");
|
|
16979
|
+
error51.setAttribute("role", "alert");
|
|
16980
|
+
error51.className = "error";
|
|
16981
|
+
const actions = document2.createElement("div");
|
|
16982
|
+
actions.className = "actions";
|
|
16983
|
+
const readAnswers = () => Object.fromEntries([...readers].map(([id, read]) => [id, read()]));
|
|
16984
|
+
let busy = false;
|
|
16985
|
+
const send = async (cancelled) => {
|
|
16986
|
+
if (busy) return;
|
|
16987
|
+
const answers = cancelled ? {} : readAnswers();
|
|
16988
|
+
if (!cancelled && validOther.some((valid) => !valid())) {
|
|
16989
|
+
error51.textContent = "Type an answer for each selected Other option.";
|
|
16990
|
+
return;
|
|
16991
|
+
}
|
|
16992
|
+
if (!cancelled && question.questions.some((field2) => !field2.optional && !answers[field2.id]?.length)) {
|
|
16993
|
+
error51.textContent = "Answer each required question before submitting.";
|
|
16994
|
+
return;
|
|
16995
|
+
}
|
|
16996
|
+
busy = true;
|
|
16997
|
+
error51.textContent = "";
|
|
16998
|
+
for (const control of controls) control.disabled = true;
|
|
16999
|
+
try {
|
|
17000
|
+
await submit(answers, cancelled);
|
|
17001
|
+
} catch {
|
|
17002
|
+
error51.textContent = "Could not submit. The question may have closed. Try again if it is still available.";
|
|
17003
|
+
} finally {
|
|
17004
|
+
busy = false;
|
|
17005
|
+
for (const control of controls) control.disabled = false;
|
|
17006
|
+
}
|
|
17007
|
+
};
|
|
17008
|
+
for (const [label, cancelled] of [
|
|
17009
|
+
["Skip", true],
|
|
17010
|
+
["Send", false]
|
|
17011
|
+
]) {
|
|
17012
|
+
const button2 = document2.createElement("button");
|
|
17013
|
+
button2.type = "button";
|
|
17014
|
+
button2.textContent = label;
|
|
17015
|
+
if (!cancelled) button2.className = "primary";
|
|
17016
|
+
button2.addEventListener("click", () => {
|
|
17017
|
+
void send(cancelled);
|
|
17018
|
+
});
|
|
17019
|
+
controls.push(button2);
|
|
17020
|
+
actions.append(button2);
|
|
17021
|
+
}
|
|
17022
|
+
dismiss.addEventListener("click", () => {
|
|
17023
|
+
void send(true);
|
|
17024
|
+
});
|
|
17025
|
+
footer.append(actions);
|
|
17026
|
+
surface.append(error51, footer);
|
|
17027
|
+
return {
|
|
17028
|
+
root,
|
|
17029
|
+
readAnswers,
|
|
17030
|
+
dispose() {
|
|
17031
|
+
root.remove();
|
|
17032
|
+
}
|
|
17033
|
+
};
|
|
17034
|
+
}
|
|
17035
|
+
|
|
17036
|
+
// src/renderer-request-sender.ts
|
|
17037
|
+
var RendererMethodUnavailableError = class extends Error {
|
|
17038
|
+
constructor(method, cause) {
|
|
17039
|
+
super(`${method} is unsupported on this Host connection`, { cause });
|
|
17040
|
+
this.method = method;
|
|
17041
|
+
this.name = "RendererMethodUnavailableError";
|
|
17042
|
+
}
|
|
17043
|
+
method;
|
|
17044
|
+
code = -32601;
|
|
17045
|
+
};
|
|
17046
|
+
function isUnsupportedMethod(error51, method) {
|
|
17047
|
+
if (typeof error51 !== "object" || error51 === null) return false;
|
|
17048
|
+
const code = "code" in error51 ? error51.code : void 0;
|
|
17049
|
+
const message2 = "message" in error51 ? error51.message : void 0;
|
|
17050
|
+
return code === -32601 || code === -32600 && typeof message2 === "string" && message2.startsWith(`Invalid request: unknown variant \`${method}\``);
|
|
17051
|
+
}
|
|
17052
|
+
function createRendererRequestSender(send) {
|
|
17053
|
+
const unsupported = /* @__PURE__ */ new Map();
|
|
17054
|
+
return async (method, params, options) => {
|
|
17055
|
+
const known = unsupported.get(method);
|
|
17056
|
+
if (known) throw known;
|
|
17057
|
+
try {
|
|
17058
|
+
return await (options === void 0 ? send(method, params) : send(method, params, options));
|
|
17059
|
+
} catch (error51) {
|
|
17060
|
+
if (!method.startsWith("codexhost/") || !isUnsupportedMethod(error51, method)) throw error51;
|
|
17061
|
+
const unavailable = new RendererMethodUnavailableError(method, error51);
|
|
17062
|
+
unsupported.set(method, unavailable);
|
|
17063
|
+
throw unavailable;
|
|
17064
|
+
}
|
|
17065
|
+
};
|
|
17066
|
+
}
|
|
17067
|
+
|
|
17068
|
+
// src/renderer-questions.ts
|
|
17069
|
+
function same(a, b) {
|
|
17070
|
+
return a?.hostId === b?.hostId && a?.threadId === b?.threadId && a?.composer === b?.composer && a?.route === b?.route;
|
|
17071
|
+
}
|
|
17072
|
+
function installRendererQuestions(window2, readContext) {
|
|
17073
|
+
let disposed = false;
|
|
17074
|
+
let inFlight = false;
|
|
17075
|
+
let revision = 0;
|
|
17076
|
+
let context = null;
|
|
17077
|
+
let card = null;
|
|
17078
|
+
let cardKey = null;
|
|
17079
|
+
const unsupported = /* @__PURE__ */ new WeakSet();
|
|
17080
|
+
const drafts = /* @__PURE__ */ new Map();
|
|
17081
|
+
const clear = (retain = true) => {
|
|
17082
|
+
if (retain && card && cardKey) {
|
|
17083
|
+
drafts.set(cardKey, card.readAnswers());
|
|
17084
|
+
const oldest = drafts.keys().next().value;
|
|
17085
|
+
if (drafts.size > 50 && oldest !== void 0) drafts.delete(oldest);
|
|
17086
|
+
}
|
|
17087
|
+
card?.dispose();
|
|
17088
|
+
card = null;
|
|
17089
|
+
cardKey = null;
|
|
17090
|
+
};
|
|
17091
|
+
const refresh = async () => {
|
|
17092
|
+
if (disposed) return;
|
|
17093
|
+
const next = readContext();
|
|
17094
|
+
if (!same(context, next)) {
|
|
17095
|
+
clear();
|
|
17096
|
+
context = next;
|
|
17097
|
+
revision++;
|
|
17098
|
+
}
|
|
17099
|
+
const current = context;
|
|
17100
|
+
if (!current || inFlight || unsupported.has(current.route)) return;
|
|
17101
|
+
const startedRevision = revision;
|
|
17102
|
+
inFlight = true;
|
|
17103
|
+
try {
|
|
17104
|
+
const raw = await current.route.sendRequest(
|
|
17105
|
+
THREAD_QUESTIONS_LIST_METHOD,
|
|
17106
|
+
{ threadId: current.threadId },
|
|
17107
|
+
{ priority: "background", timeoutMs: 5e3 }
|
|
17108
|
+
);
|
|
17109
|
+
if (disposed || revision !== startedRevision || !same(current, readContext())) return;
|
|
17110
|
+
const question = threadQuestionsResultSchema.parse(raw).questions[0];
|
|
17111
|
+
if (!question) {
|
|
17112
|
+
if (cardKey) drafts.delete(cardKey);
|
|
17113
|
+
clear(false);
|
|
17114
|
+
return;
|
|
17115
|
+
}
|
|
17116
|
+
const key = JSON.stringify([
|
|
17117
|
+
current.hostId,
|
|
17118
|
+
current.threadId,
|
|
17119
|
+
question.turnId,
|
|
17120
|
+
question.interactionId
|
|
17121
|
+
]);
|
|
17122
|
+
if (cardKey === key && card?.root.isConnected) return;
|
|
17123
|
+
clear(cardKey === key);
|
|
17124
|
+
cardKey = key;
|
|
17125
|
+
card = createQuestionCard(
|
|
17126
|
+
current.composer.ownerDocument,
|
|
17127
|
+
question,
|
|
17128
|
+
async (answers, cancelled) => {
|
|
17129
|
+
if (disposed || !same(current, readContext()) || cardKey !== key)
|
|
17130
|
+
throw new Error("Question owner changed");
|
|
17131
|
+
const raw2 = await current.route.sendRequest(
|
|
17132
|
+
THREAD_QUESTION_RESPOND_METHOD,
|
|
17133
|
+
{
|
|
17134
|
+
threadId: current.threadId,
|
|
17135
|
+
turnId: question.turnId,
|
|
17136
|
+
interactionId: question.interactionId,
|
|
17137
|
+
answers,
|
|
17138
|
+
cancelled
|
|
17139
|
+
},
|
|
17140
|
+
{ priority: "interactive", timeoutMs: 1e4 }
|
|
17141
|
+
);
|
|
17142
|
+
threadQuestionRespondResultSchema.parse(raw2);
|
|
17143
|
+
drafts.delete(key);
|
|
17144
|
+
if (same(current, context)) {
|
|
17145
|
+
revision++;
|
|
17146
|
+
if (cardKey === key) clear(false);
|
|
17147
|
+
}
|
|
17148
|
+
},
|
|
17149
|
+
drafts.get(key)
|
|
17150
|
+
);
|
|
17151
|
+
current.composer.before(card.root);
|
|
17152
|
+
} catch (error51) {
|
|
17153
|
+
if (isUnsupportedMethod(error51, THREAD_QUESTIONS_LIST_METHOD)) unsupported.add(current.route);
|
|
17154
|
+
if (revision === startedRevision && same(current, context)) clear();
|
|
17155
|
+
} finally {
|
|
17156
|
+
inFlight = false;
|
|
17157
|
+
}
|
|
17158
|
+
};
|
|
17159
|
+
const timer = window2.setInterval(() => {
|
|
17160
|
+
void refresh();
|
|
17161
|
+
}, 750);
|
|
17162
|
+
void refresh();
|
|
17163
|
+
return {
|
|
17164
|
+
refresh,
|
|
17165
|
+
refreshContext() {
|
|
17166
|
+
if (!same(context, readContext()) || card && !card.root.isConnected) void refresh();
|
|
17167
|
+
},
|
|
17168
|
+
dispose() {
|
|
17169
|
+
disposed = true;
|
|
17170
|
+
window2.clearInterval(timer);
|
|
17171
|
+
clear(false);
|
|
17172
|
+
drafts.clear();
|
|
17173
|
+
}
|
|
17174
|
+
};
|
|
17175
|
+
}
|
|
17176
|
+
|
|
16458
17177
|
// ../desktop-control/dist/renderer-react-ownership.js
|
|
16459
17178
|
var REACT_FIBER_WALK_LIMIT_EVENT = "codexhost:react-fiber-walk-limit";
|
|
16460
17179
|
function committedReactAncestors(value) {
|
|
@@ -16784,42 +17503,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16784
17503
|
return fallback;
|
|
16785
17504
|
}
|
|
16786
17505
|
|
|
16787
|
-
// ../../node_modules/lucide/dist/esm/defaultAttributes.mjs
|
|
16788
|
-
var defaultAttributes = {
|
|
16789
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
16790
|
-
width: 24,
|
|
16791
|
-
height: 24,
|
|
16792
|
-
viewBox: "0 0 24 24",
|
|
16793
|
-
fill: "none",
|
|
16794
|
-
stroke: "currentColor",
|
|
16795
|
-
"stroke-width": 2,
|
|
16796
|
-
"stroke-linecap": "round",
|
|
16797
|
-
"stroke-linejoin": "round"
|
|
16798
|
-
};
|
|
16799
|
-
|
|
16800
|
-
// ../../node_modules/lucide/dist/esm/createElement.mjs
|
|
16801
|
-
var createSVGElement = ([tag, attrs, children]) => {
|
|
16802
|
-
const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
16803
|
-
Object.keys(attrs).forEach((name) => {
|
|
16804
|
-
element.setAttribute(name, String(attrs[name]));
|
|
16805
|
-
});
|
|
16806
|
-
if (children?.length) {
|
|
16807
|
-
children.forEach((child) => {
|
|
16808
|
-
const childElement = createSVGElement(child);
|
|
16809
|
-
element.appendChild(childElement);
|
|
16810
|
-
});
|
|
16811
|
-
}
|
|
16812
|
-
return element;
|
|
16813
|
-
};
|
|
16814
|
-
var createElement = (iconNode, customAttrs = {}) => {
|
|
16815
|
-
const tag = "svg";
|
|
16816
|
-
const attrs = {
|
|
16817
|
-
...defaultAttributes,
|
|
16818
|
-
...customAttrs
|
|
16819
|
-
};
|
|
16820
|
-
return createSVGElement([tag, attrs, iconNode]);
|
|
16821
|
-
};
|
|
16822
|
-
|
|
16823
17506
|
// ../../node_modules/lucide/dist/esm/icons/boxes.mjs
|
|
16824
17507
|
var Boxes = [
|
|
16825
17508
|
[
|
|
@@ -17124,12 +17807,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17124
17807
|
["path", { d: "M12 17h.01" }]
|
|
17125
17808
|
];
|
|
17126
17809
|
|
|
17127
|
-
// ../../node_modules/lucide/dist/esm/icons/x.mjs
|
|
17128
|
-
var X = [
|
|
17129
|
-
["path", { d: "M18 6 6 18" }],
|
|
17130
|
-
["path", { d: "m6 6 12 12" }]
|
|
17131
|
-
];
|
|
17132
|
-
|
|
17133
17810
|
// ../../node_modules/lucide/dist/esm/icons/users.mjs
|
|
17134
17811
|
var Users = [
|
|
17135
17812
|
["path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }],
|
|
@@ -17553,7 +18230,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17553
18230
|
}
|
|
17554
18231
|
|
|
17555
18232
|
// src/settings/harness-version-panel.ts
|
|
17556
|
-
function createHarnessVersionPanel(document2, messages, signal, agent, client) {
|
|
18233
|
+
function createHarnessVersionPanel(document2, messages, signal, agent, client, onChange = () => void 0) {
|
|
17557
18234
|
const panel = document2.createElement("section");
|
|
17558
18235
|
panel.className = "settings-harness-version";
|
|
17559
18236
|
panel.dataset.harnessVersion = agent;
|
|
@@ -17579,37 +18256,67 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17579
18256
|
panel.append(heading, versions, status, actions, note);
|
|
17580
18257
|
let state;
|
|
17581
18258
|
let busy = false;
|
|
18259
|
+
let updating = false;
|
|
17582
18260
|
let unsupported = false;
|
|
18261
|
+
let updatePromise = null;
|
|
17583
18262
|
const render = () => {
|
|
18263
|
+
heading.textContent = state?.versionKind === "application" ? messages.harnessVersionApplicationTitle : messages.harnessVersionTitle;
|
|
17584
18264
|
current.textContent = `${messages.harnessVersionCurrent}: ${state?.currentVersion ?? "\u2014"}`;
|
|
17585
18265
|
latest.textContent = `${messages.harnessVersionLatest}: ${harnessVersionLabel(state, messages.harnessVersion)}`;
|
|
17586
18266
|
update.disabled = busy || signal.aborted || !state?.canUpdate || !state.updateAvailable;
|
|
18267
|
+
const manualUrl = !state?.canUpdate && state?.updateAvailable ? state.manualUpdateUrl : void 0;
|
|
18268
|
+
actions.replaceChildren(update);
|
|
18269
|
+
update.hidden = !busy && !signal.aborted && Boolean(manualUrl);
|
|
18270
|
+
if (update.hidden && manualUrl) {
|
|
18271
|
+
const download2 = document2.createElement("a");
|
|
18272
|
+
download2.className = "settings-command-button settings-command-button--secondary";
|
|
18273
|
+
download2.dataset.harnessVersionAction = "download-update";
|
|
18274
|
+
download2.textContent = messages.harnessVersionDownloadUpdate;
|
|
18275
|
+
download2.href = manualUrl;
|
|
18276
|
+
download2.target = "_blank";
|
|
18277
|
+
download2.rel = "noopener noreferrer";
|
|
18278
|
+
actions.append(download2);
|
|
18279
|
+
}
|
|
17587
18280
|
update.textContent = state?.canUpdate && state.latestVersion !== "Unknown" && !state.updateAvailable ? messages.harnessVersionUpToDate : messages.harnessVersionUpdate;
|
|
17588
18281
|
const detail = harnessVersionNote(state, messages.harnessVersion);
|
|
17589
|
-
note.textContent = detail ? `${detail} ${messages.harnessVersionNote}` : messages.harnessVersionNote;
|
|
18282
|
+
note.textContent = detail ? !state?.canUpdate ? detail : `${detail} ${messages.harnessVersionNote}` : messages.harnessVersionNote;
|
|
17590
18283
|
};
|
|
17591
18284
|
const run = async (action) => {
|
|
17592
|
-
if (busy || unsupported || signal.aborted) return;
|
|
17593
|
-
if (action === "update" && (!state?.canUpdate || !state.updateAvailable)) return;
|
|
18285
|
+
if (busy || unsupported || signal.aborted) return false;
|
|
18286
|
+
if (action === "update" && (!state?.canUpdate || !state.updateAvailable)) return false;
|
|
17594
18287
|
busy = true;
|
|
18288
|
+
updating = action === "update";
|
|
18289
|
+
onChange();
|
|
17595
18290
|
status.textContent = action === "check" ? messages.harnessVersionChecking : messages.harnessVersionUpdating;
|
|
17596
18291
|
render();
|
|
17597
18292
|
try {
|
|
17598
18293
|
const result = await client.run(action);
|
|
17599
|
-
if (signal.aborted) return;
|
|
18294
|
+
if (signal.aborted) return false;
|
|
17600
18295
|
state = result;
|
|
17601
18296
|
status.textContent = !result.canUpdate ? messages.harnessVersionManual : action === "update" ? result.updateAvailable ? messages.harnessVersionFailed : messages.harnessVersionUpdated : "";
|
|
18297
|
+
return result.canUpdate && !result.updateAvailable;
|
|
17602
18298
|
} catch (error51) {
|
|
17603
|
-
if (signal.aborted) return;
|
|
18299
|
+
if (signal.aborted) return false;
|
|
17604
18300
|
unsupported = typeof error51 === "object" && error51 !== null && "code" in error51 && (error51.code === -32601 || error51.code === -32078);
|
|
17605
18301
|
status.textContent = unsupported ? messages.harnessVersionUnsupported : messages.harnessVersionFailed;
|
|
17606
18302
|
if (state) state = { ...state, canUpdate: false };
|
|
18303
|
+
return false;
|
|
17607
18304
|
} finally {
|
|
17608
18305
|
busy = false;
|
|
17609
|
-
|
|
18306
|
+
updating = false;
|
|
18307
|
+
if (!signal.aborted) {
|
|
18308
|
+
render();
|
|
18309
|
+
onChange();
|
|
18310
|
+
}
|
|
17610
18311
|
}
|
|
17611
18312
|
};
|
|
17612
|
-
|
|
18313
|
+
const updateVersion = () => {
|
|
18314
|
+
updatePromise ??= run("update").finally(() => {
|
|
18315
|
+
updatePromise = null;
|
|
18316
|
+
});
|
|
18317
|
+
return updatePromise;
|
|
18318
|
+
};
|
|
18319
|
+
update.addEventListener("click", () => void updateVersion());
|
|
17613
18320
|
const owner = document2.defaultView;
|
|
17614
18321
|
let checkFrame = null;
|
|
17615
18322
|
let checkTimer = null;
|
|
@@ -17636,7 +18343,95 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17636
18343
|
} else {
|
|
17637
18344
|
void run("check");
|
|
17638
18345
|
}
|
|
17639
|
-
return
|
|
18346
|
+
return {
|
|
18347
|
+
element: panel,
|
|
18348
|
+
get state() {
|
|
18349
|
+
return state;
|
|
18350
|
+
},
|
|
18351
|
+
get updating() {
|
|
18352
|
+
return updating;
|
|
18353
|
+
},
|
|
18354
|
+
update: updateVersion
|
|
18355
|
+
};
|
|
18356
|
+
}
|
|
18357
|
+
|
|
18358
|
+
// src/settings/connection-versions.ts
|
|
18359
|
+
function createConnectionVersions(document2, messages, signal, diagnostics, onChange) {
|
|
18360
|
+
const panels = /* @__PURE__ */ new Map();
|
|
18361
|
+
const installation = diagnostics?.installation?.bind(diagnostics);
|
|
18362
|
+
return {
|
|
18363
|
+
get(hostId2, agent) {
|
|
18364
|
+
if (!installation || signal.aborted) return void 0;
|
|
18365
|
+
const key = JSON.stringify([hostId2, agent]);
|
|
18366
|
+
let panel = panels.get(key);
|
|
18367
|
+
if (!panel) {
|
|
18368
|
+
panel = createHarnessVersionPanel(
|
|
18369
|
+
document2,
|
|
18370
|
+
messages,
|
|
18371
|
+
signal,
|
|
18372
|
+
agent,
|
|
18373
|
+
{
|
|
18374
|
+
run: (action) => installation(hostId2, agent, action)
|
|
18375
|
+
},
|
|
18376
|
+
onChange
|
|
18377
|
+
);
|
|
18378
|
+
panels.set(key, panel);
|
|
18379
|
+
}
|
|
18380
|
+
return panel;
|
|
18381
|
+
}
|
|
18382
|
+
};
|
|
18383
|
+
}
|
|
18384
|
+
|
|
18385
|
+
// src/settings/connection-updates.ts
|
|
18386
|
+
function createConnectionUpdates(document2, messages, signal, onChange) {
|
|
18387
|
+
const batches = /* @__PURE__ */ new Map();
|
|
18388
|
+
const eligible = (panels) => panels.filter((panel) => panel.state?.updateAvailable && panel.state.canUpdate);
|
|
18389
|
+
const start = async (hostId2, panels) => {
|
|
18390
|
+
if (signal.aborted || batches.get(hostId2)?.running) return;
|
|
18391
|
+
const targets = eligible(panels);
|
|
18392
|
+
if (!targets.length) return;
|
|
18393
|
+
const batch = { running: true, total: targets.length, succeeded: 0, failed: 0 };
|
|
18394
|
+
batches.set(hostId2, batch);
|
|
18395
|
+
onChange();
|
|
18396
|
+
await Promise.all(
|
|
18397
|
+
targets.map(async (panel) => {
|
|
18398
|
+
try {
|
|
18399
|
+
if (await panel.update()) batch.succeeded++;
|
|
18400
|
+
else batch.failed++;
|
|
18401
|
+
} catch {
|
|
18402
|
+
batch.failed++;
|
|
18403
|
+
}
|
|
18404
|
+
if (!signal.aborted) onChange();
|
|
18405
|
+
})
|
|
18406
|
+
);
|
|
18407
|
+
batch.running = false;
|
|
18408
|
+
if (!signal.aborted) onChange();
|
|
18409
|
+
};
|
|
18410
|
+
return {
|
|
18411
|
+
createControls(hostId2, panels) {
|
|
18412
|
+
const batch = batches.get(hostId2);
|
|
18413
|
+
const count3 = eligible(panels).length;
|
|
18414
|
+
const button2 = document2.createElement("button");
|
|
18415
|
+
button2.type = "button";
|
|
18416
|
+
button2.className = "settings-command-button settings-command-button--secondary settings-connection-update-all";
|
|
18417
|
+
button2.dataset.connectionAction = "update-all";
|
|
18418
|
+
button2.disabled = signal.aborted || Boolean(batch?.running) || !count3;
|
|
18419
|
+
button2.title = messages.harnessUpdateAllDescription;
|
|
18420
|
+
const label = batch?.running ? `${messages.harnessUpdateAllProgress} ${batch.succeeded + batch.failed}/${batch.total}` : count3 ? `${messages.harnessUpdateAll} (${count3})` : messages.harnessUpdateAll;
|
|
18421
|
+
button2.append(createRendererSettingsIcon("download", 15), label);
|
|
18422
|
+
button2.addEventListener("click", () => {
|
|
18423
|
+
if (!button2.disabled) void start(hostId2, panels);
|
|
18424
|
+
});
|
|
18425
|
+
const result = document2.createElement("p");
|
|
18426
|
+
result.className = "settings-connection-update-result";
|
|
18427
|
+
result.setAttribute("role", "status");
|
|
18428
|
+
result.hidden = !batch || batch.running;
|
|
18429
|
+
if (batch && !batch.running) {
|
|
18430
|
+
result.textContent = messages.harnessUpdateAllResult.replace("{succeeded}", String(batch.succeeded)).replace("{failed}", String(batch.failed));
|
|
18431
|
+
}
|
|
18432
|
+
return { button: button2, result };
|
|
18433
|
+
}
|
|
18434
|
+
};
|
|
17640
18435
|
}
|
|
17641
18436
|
|
|
17642
18437
|
// src/settings/connections-page.ts
|
|
@@ -17804,6 +18599,7 @@ ${error51.stderrTail}`] : []
|
|
|
17804
18599
|
status.dataset.connectionTone = connectionStatusTone(item.availability, item.error !== null);
|
|
17805
18600
|
status.setAttribute("role", "cell");
|
|
17806
18601
|
status.textContent = item.error?.code === "authenticationRequired" ? messages.connectionLoginRequired : item.error?.code === "configurationRequired" ? messages.connectionConfigurationRequired : connectionStatusLabel(item.availability, messages, item.error !== null);
|
|
18602
|
+
const version2 = item.version;
|
|
17807
18603
|
const action = document2.createElement("div");
|
|
17808
18604
|
action.className = "settings-connection-row__action";
|
|
17809
18605
|
action.setAttribute("role", "cell");
|
|
@@ -17833,6 +18629,31 @@ ${error51.stderrTail}`] : []
|
|
|
17833
18629
|
});
|
|
17834
18630
|
action.append(viewError);
|
|
17835
18631
|
}
|
|
18632
|
+
if (version2?.state?.updateAvailable && !version2.updating) {
|
|
18633
|
+
const available = document2.createElement("span");
|
|
18634
|
+
available.className = "settings-connection-version-available";
|
|
18635
|
+
available.textContent = messages.harnessVersionAvailable;
|
|
18636
|
+
available.title = `${messages.harnessVersionCurrent}: ${version2.state.currentVersion ?? "\u2014"}
|
|
18637
|
+
${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages.harnessVersion)}`;
|
|
18638
|
+
action.append(available);
|
|
18639
|
+
}
|
|
18640
|
+
if (version2?.state?.updateAvailable && version2.state.canUpdate) {
|
|
18641
|
+
const update = document2.createElement("button");
|
|
18642
|
+
update.type = "button";
|
|
18643
|
+
update.className = "settings-connection-install-link";
|
|
18644
|
+
update.dataset.connectionAction = "update";
|
|
18645
|
+
update.disabled = version2.updating;
|
|
18646
|
+
update.title = messages.harnessVersionUpdate;
|
|
18647
|
+
update.setAttribute("aria-label", `${messages.harnessVersionUpdate}: ${item.name}`);
|
|
18648
|
+
update.append(createRendererSettingsIcon("download", 17));
|
|
18649
|
+
update.addEventListener("click", (event) => {
|
|
18650
|
+
event.stopPropagation();
|
|
18651
|
+
if (update.disabled) return;
|
|
18652
|
+
void version2.update();
|
|
18653
|
+
select();
|
|
18654
|
+
});
|
|
18655
|
+
action.append(update);
|
|
18656
|
+
}
|
|
17836
18657
|
if (group) {
|
|
17837
18658
|
const toggle = document2.createElement("button");
|
|
17838
18659
|
toggle.type = "button";
|
|
@@ -18124,8 +18945,6 @@ ${error51.stderrTail}`] : []
|
|
|
18124
18945
|
let selectedHostId = null;
|
|
18125
18946
|
let selectedItemKey = null;
|
|
18126
18947
|
let launchControls = null;
|
|
18127
|
-
const versionPanels = /* @__PURE__ */ new Map();
|
|
18128
|
-
const updatingVersions = /* @__PURE__ */ new Set();
|
|
18129
18948
|
const hostNames = /* @__PURE__ */ new Map();
|
|
18130
18949
|
let latestSnapshot = null;
|
|
18131
18950
|
let disposeHostScroller = () => void 0;
|
|
@@ -18154,7 +18973,15 @@ ${error51.stderrTail}`] : []
|
|
|
18154
18973
|
renderFrame = null;
|
|
18155
18974
|
};
|
|
18156
18975
|
const diagnostics = getDiagnostics();
|
|
18976
|
+
const versions = createConnectionVersions(
|
|
18977
|
+
document2,
|
|
18978
|
+
messages,
|
|
18979
|
+
context.signal,
|
|
18980
|
+
diagnostics,
|
|
18981
|
+
scheduleRender
|
|
18982
|
+
);
|
|
18157
18983
|
const installs = diagnostics ? harnessInstallStore(diagnostics) : null;
|
|
18984
|
+
const updates = createConnectionUpdates(document2, messages, context.signal, scheduleRender);
|
|
18158
18985
|
const runRefresh = () => {
|
|
18159
18986
|
if (pending || !diagnostics) return;
|
|
18160
18987
|
pending = true;
|
|
@@ -18290,10 +19117,13 @@ ${error51.stderrTail}`] : []
|
|
|
18290
19117
|
const agent = item.agentSnapshot?.agent;
|
|
18291
19118
|
if (!agent) return item;
|
|
18292
19119
|
const state = installs?.get(selectedHost.hostId, agent);
|
|
19120
|
+
const availability = state?.status ?? item.availability;
|
|
19121
|
+
const version2 = item.agentSnapshot?.availability !== "notInstalled" && availability !== "installing" && availability !== "checking" ? versions.get(selectedHost.hostId, agent) : void 0;
|
|
18293
19122
|
return {
|
|
18294
19123
|
...item,
|
|
18295
19124
|
...state ? { availability: state.status } : {},
|
|
18296
|
-
...
|
|
19125
|
+
...version2 ? { version: version2 } : {},
|
|
19126
|
+
...version2?.updating ? { availability: "updating" } : {},
|
|
18297
19127
|
...state?.error ? { installError: state.error } : {},
|
|
18298
19128
|
...diagnostics?.installation && harnessHasInstallCommands(item.agentSnapshot?.plugin) ? {
|
|
18299
19129
|
install: () => {
|
|
@@ -18330,30 +19160,7 @@ ${error51.stderrTail}`] : []
|
|
|
18330
19160
|
runRefresh
|
|
18331
19161
|
);
|
|
18332
19162
|
launchControls = { hostId: selectedHost.hostId, itemKey: item.key, element };
|
|
18333
|
-
|
|
18334
|
-
const installation = diagnostics?.installation?.bind(diagnostics);
|
|
18335
|
-
if (agent && item.agentSnapshot?.availability !== "notInstalled" && item.availability !== "installing" && item.availability !== "checking" && installation) {
|
|
18336
|
-
const key = JSON.stringify([selectedHost.hostId, agent]);
|
|
18337
|
-
let panel = versionPanels.get(key);
|
|
18338
|
-
if (!panel) {
|
|
18339
|
-
const hostId2 = selectedHost.hostId;
|
|
18340
|
-
panel = createHarnessVersionPanel(document2, messages, context.signal, agent, {
|
|
18341
|
-
async run(action) {
|
|
18342
|
-
if (action !== "update") return installation(hostId2, agent, action);
|
|
18343
|
-
updatingVersions.add(key);
|
|
18344
|
-
if (diagnostics) render(diagnostics.snapshot());
|
|
18345
|
-
try {
|
|
18346
|
-
return await installation(hostId2, agent, action);
|
|
18347
|
-
} finally {
|
|
18348
|
-
updatingVersions.delete(key);
|
|
18349
|
-
if (!context.signal.aborted && diagnostics) render(diagnostics.snapshot());
|
|
18350
|
-
}
|
|
18351
|
-
}
|
|
18352
|
-
});
|
|
18353
|
-
versionPanels.set(key, panel);
|
|
18354
|
-
}
|
|
18355
|
-
inspector.append(panel);
|
|
18356
|
-
}
|
|
19163
|
+
if (item.version) inspector.append(item.version.element);
|
|
18357
19164
|
};
|
|
18358
19165
|
const pinnedItem = items.find((item) => item.key === "renderer-adapter");
|
|
18359
19166
|
if (pinnedItem) {
|
|
@@ -18509,7 +19316,14 @@ ${error51.stderrTail}`] : []
|
|
|
18509
19316
|
}
|
|
18510
19317
|
const selectedItem = items.find((item) => item.key === selectedItemKey) ?? items[0];
|
|
18511
19318
|
if (selectedItem) selectItem(selectedItem);
|
|
18512
|
-
|
|
19319
|
+
const updateControls = updates.createControls(
|
|
19320
|
+
selectedHost.hostId,
|
|
19321
|
+
items.flatMap((item) => item.version ? [item.version] : [])
|
|
19322
|
+
);
|
|
19323
|
+
const hostHeader = document2.createElement("div");
|
|
19324
|
+
hostHeader.className = "settings-connection-host-header";
|
|
19325
|
+
hostHeader.append(hostStrip, updateControls.button);
|
|
19326
|
+
list.append(hostHeader, updateControls.result, tableHeader, rows);
|
|
18513
19327
|
layout.append(list, inspector);
|
|
18514
19328
|
content.replaceChildren(layout);
|
|
18515
19329
|
disposeHostScroller = configureHostScroller(
|
|
@@ -18696,12 +19510,13 @@ ${error51.stderrTail}`] : []
|
|
|
18696
19510
|
notAvailable: "Not available",
|
|
18697
19511
|
runtimeCapabilityNotInstalled: "This runtime capability is not installed yet.",
|
|
18698
19512
|
sessionImportHarness: "Harness",
|
|
19513
|
+
sessionImportSelectHost: "Select the Host to import sessions from",
|
|
18699
19514
|
sessionImportDescription: "Sessions keep their original project path. If a folder is not in the Codex sidebar, add it as a project first. Original history remains managed by the Harness.",
|
|
18700
|
-
sessionImportAvailabilityNote: "Available Harnesses come from the
|
|
19515
|
+
sessionImportAvailabilityNote: "Available Harnesses come from the selected Host. If activity is unknown, close the session in its native client before importing to avoid concurrent writes.",
|
|
18701
19516
|
sessionImportRefresh: "Refresh",
|
|
18702
|
-
sessionImportRefreshing: "Loading
|
|
18703
|
-
sessionImportUnavailable: "Session import is unavailable for this
|
|
18704
|
-
sessionImportEmpty: "No
|
|
19517
|
+
sessionImportRefreshing: "Loading sessions from the selected Host...",
|
|
19518
|
+
sessionImportUnavailable: "Session import is unavailable for this Harness or the selected Host protocol. Update the Host/plugin or choose another Harness.",
|
|
19519
|
+
sessionImportEmpty: "No sessions are available to import on the selected Host.",
|
|
18705
19520
|
sessionImportSearch: "Search",
|
|
18706
19521
|
sessionImportSearchPlaceholder: "Search titles, session IDs or project paths",
|
|
18707
19522
|
sessionImportNoMatches: "No sessions match your search.",
|
|
@@ -18709,7 +19524,7 @@ ${error51.stderrTail}`] : []
|
|
|
18709
19524
|
sessionImportPrevious: "Previous",
|
|
18710
19525
|
sessionImportNext: "Next",
|
|
18711
19526
|
sessionImportPageSummary: "Page {page} of {pages} \xB7 {total} sessions",
|
|
18712
|
-
sessionImportLoadFailed: "
|
|
19527
|
+
sessionImportLoadFailed: "Sessions could not be loaded from the selected Host. Check directory access or duplicate session IDs, then retry.",
|
|
18713
19528
|
sessionImportFailed: "The session could not be imported.",
|
|
18714
19529
|
sessionImportUntitled: "Untitled session",
|
|
18715
19530
|
sessionImportUpdatedAt: "Updated",
|
|
@@ -18814,10 +19629,17 @@ ${error51.stderrTail}`] : []
|
|
|
18814
19629
|
connectionInstallRunning: "Installing on the selected Host. You can leave this page; login or setup may still be required afterward.",
|
|
18815
19630
|
harnessVersion: harnessVersionEnglish,
|
|
18816
19631
|
harnessVersionTitle: "Harness CLI version",
|
|
19632
|
+
harnessVersionApplicationTitle: "Application version",
|
|
18817
19633
|
harnessVersionCurrent: "Current version",
|
|
18818
19634
|
harnessVersionLatest: "Latest version",
|
|
18819
19635
|
harnessVersionChecking: "Checking versions\u2026",
|
|
19636
|
+
harnessVersionAvailable: "Update available",
|
|
18820
19637
|
harnessVersionUpdate: "Update",
|
|
19638
|
+
harnessVersionDownloadUpdate: "Download update",
|
|
19639
|
+
harnessUpdateAll: "Update all",
|
|
19640
|
+
harnessUpdateAllProgress: "Updating",
|
|
19641
|
+
harnessUpdateAllDescription: "Update all eligible Harnesses on the selected Host.",
|
|
19642
|
+
harnessUpdateAllResult: "Updated {succeeded}; failed {failed}.",
|
|
18821
19643
|
harnessVersionUpdating: "Updating\u2026",
|
|
18822
19644
|
harnessVersionUpToDate: "Up to date",
|
|
18823
19645
|
harnessVersionUpdated: "Update verified. New sessions will use the new version.",
|
|
@@ -18969,12 +19791,13 @@ ${error51.stderrTail}`] : []
|
|
|
18969
19791
|
notAvailable: "\u6682\u4E0D\u53EF\u7528",
|
|
18970
19792
|
runtimeCapabilityNotInstalled: "\u8FD0\u884C\u65F6\u5C1A\u672A\u5B89\u88C5\u8BE5\u9879\u80FD\u529B\uFF0C\u56E0\u6B64\u6682\u4E0D\u53EF\u7528\u3002",
|
|
18971
19793
|
sessionImportHarness: "Harness",
|
|
19794
|
+
sessionImportSelectHost: "\u8BF7\u9009\u62E9\u8981\u5BFC\u5165\u4F1A\u8BDD\u7684 Host",
|
|
18972
19795
|
sessionImportDescription: "\u4F1A\u8BDD\u5C06\u4FDD\u7559\u539F\u59CB\u9879\u76EE\u8DEF\u5F84\uFF1B\u82E5\u8BE5\u6587\u4EF6\u5939\u5C1A\u672A\u51FA\u73B0\u5728 Codex \u4FA7\u680F\uFF0C\u8BF7\u5148\u5C06\u5176\u6DFB\u52A0\u4E3A\u9879\u76EE\u3002\u539F\u59CB\u5386\u53F2\u4ECD\u7531 Harness \u7BA1\u7406\u3002",
|
|
18973
|
-
sessionImportAvailabilityNote: "\u53EF\u9009 Harness \u6765\u81EA\
|
|
19796
|
+
sessionImportAvailabilityNote: "\u53EF\u9009 Harness \u6765\u81EA\u5F53\u524D Host\u3002\u8FD0\u884C\u72B6\u6001\u672A\u77E5\u65F6\uFF0C\u8BF7\u5148\u5728\u539F\u751F\u5BA2\u6237\u7AEF\u5173\u95ED\u8BE5\u4F1A\u8BDD\u518D\u5BFC\u5165\uFF0C\u907F\u514D\u540C\u65F6\u5199\u5165\u3002",
|
|
18974
19797
|
sessionImportRefresh: "\u5237\u65B0",
|
|
18975
|
-
sessionImportRefreshing: "\u6B63\u5728\u8BFB\u53D6\
|
|
18976
|
-
sessionImportUnavailable: "\
|
|
18977
|
-
sessionImportEmpty: "\u6CA1\u6709\u53EF\u5BFC\u5165\u7684\
|
|
19798
|
+
sessionImportRefreshing: "\u6B63\u5728\u8BFB\u53D6\u5F53\u524D Host \u4E0A\u7684\u4F1A\u8BDD\u2026\u2026",
|
|
19799
|
+
sessionImportUnavailable: "\u8BE5 Harness \u6216\u5F53\u524D Host \u534F\u8BAE\u6682\u4E0D\u652F\u6301\u4F1A\u8BDD\u5BFC\u5165\uFF0C\u8BF7\u66F4\u65B0 Host/\u63D2\u4EF6\u6216\u9009\u62E9\u5176\u4ED6 Harness\u3002",
|
|
19800
|
+
sessionImportEmpty: "\u5F53\u524D Host \u4E0A\u6CA1\u6709\u53EF\u5BFC\u5165\u7684\u4F1A\u8BDD\u3002",
|
|
18978
19801
|
sessionImportSearch: "\u641C\u7D22",
|
|
18979
19802
|
sessionImportSearchPlaceholder: "\u641C\u7D22\u6807\u9898\u3001\u4F1A\u8BDD ID \u6216\u9879\u76EE\u8DEF\u5F84",
|
|
18980
19803
|
sessionImportNoMatches: "\u6CA1\u6709\u5339\u914D\u7684\u4F1A\u8BDD\u3002",
|
|
@@ -18982,7 +19805,7 @@ ${error51.stderrTail}`] : []
|
|
|
18982
19805
|
sessionImportPrevious: "\u4E0A\u4E00\u9875",
|
|
18983
19806
|
sessionImportNext: "\u4E0B\u4E00\u9875",
|
|
18984
19807
|
sessionImportPageSummary: "\u7B2C {page} / {pages} \u9875 \xB7 \u5171 {total} \u6761",
|
|
18985
|
-
sessionImportLoadFailed: "\u65E0\u6CD5\u8BFB\u53D6\
|
|
19808
|
+
sessionImportLoadFailed: "\u65E0\u6CD5\u8BFB\u53D6\u5F53\u524D Host \u4E0A\u7684\u4F1A\u8BDD\uFF0C\u8BF7\u68C0\u67E5\u76EE\u5F55\u8BBF\u95EE\u6743\u9650\u6216\u91CD\u590D\u7684\u4F1A\u8BDD ID \u540E\u91CD\u8BD5\u3002",
|
|
18986
19809
|
sessionImportFailed: "\u65E0\u6CD5\u5BFC\u5165\u8BE5\u4F1A\u8BDD\u3002",
|
|
18987
19810
|
sessionImportUntitled: "\u672A\u547D\u540D\u4F1A\u8BDD",
|
|
18988
19811
|
sessionImportUpdatedAt: "\u66F4\u65B0\u65F6\u95F4",
|
|
@@ -19087,10 +19910,17 @@ ${error51.stderrTail}`] : []
|
|
|
19087
19910
|
connectionInstallRunning: "\u6B63\u5728\u6240\u9009 Host \u4E0A\u5B89\u88C5\uFF0C\u79BB\u5F00\u9875\u9762\u4E0D\u4F1A\u4E2D\u65AD\u3002\u5B89\u88C5\u540E\u53EF\u80FD\u4ECD\u9700\u767B\u5F55\u6216\u914D\u7F6E\u3002",
|
|
19088
19911
|
harnessVersion: harnessVersionChinese,
|
|
19089
19912
|
harnessVersionTitle: "Harness CLI \u7248\u672C",
|
|
19913
|
+
harnessVersionApplicationTitle: "\u5E94\u7528\u7248\u672C",
|
|
19090
19914
|
harnessVersionCurrent: "\u5F53\u524D\u7248\u672C",
|
|
19091
19915
|
harnessVersionLatest: "\u6700\u65B0\u7248\u672C",
|
|
19092
19916
|
harnessVersionChecking: "\u6B63\u5728\u68C0\u67E5\u7248\u672C\u2026",
|
|
19917
|
+
harnessVersionAvailable: "\u6709\u66F4\u65B0",
|
|
19093
19918
|
harnessVersionUpdate: "\u66F4\u65B0",
|
|
19919
|
+
harnessVersionDownloadUpdate: "\u4E0B\u8F7D\u66F4\u65B0",
|
|
19920
|
+
harnessUpdateAll: "\u5168\u90E8\u66F4\u65B0",
|
|
19921
|
+
harnessUpdateAllProgress: "\u66F4\u65B0\u4E2D",
|
|
19922
|
+
harnessUpdateAllDescription: "\u66F4\u65B0\u5F53\u524D Host \u4E0A\u652F\u6301\u81EA\u52A8\u66F4\u65B0\u4E14\u6709\u65B0\u7248\u672C\u7684 Harness\u3002",
|
|
19923
|
+
harnessUpdateAllResult: "\u5DF2\u66F4\u65B0 {succeeded} \u9879\uFF0C{failed} \u9879\u5931\u8D25\u3002",
|
|
19094
19924
|
harnessVersionUpdating: "\u6B63\u5728\u66F4\u65B0\u2026",
|
|
19095
19925
|
harnessVersionUpToDate: "\u5DF2\u662F\u6700\u65B0",
|
|
19096
19926
|
harnessVersionUpdated: "\u5DF2\u786E\u8BA4\u66F4\u65B0\u6210\u529F\uFF0C\u65B0\u4F1A\u8BDD\u5C06\u4F7F\u7528\u65B0\u7248\u672C\u3002",
|
|
@@ -19803,6 +20633,8 @@ ${error51.stderrTail}`] : []
|
|
|
19803
20633
|
var STYLE_ATTRIBUTE = "data-codexhost-trigger-chip-style";
|
|
19804
20634
|
var TRIGGER_CHIP_CLASS = "codexhost-trigger-chip";
|
|
19805
20635
|
var TRIGGER_CHIP_ROOT_CLASS = "codexhost-trigger-chip-root";
|
|
20636
|
+
var COMPACT_COMPOSER_ATTRIBUTE = "data-codexhost-compact-composer";
|
|
20637
|
+
var COMPACT_COMPOSER_WIDTH = 420;
|
|
19806
20638
|
var TRIGGER_CHIP_SQUEEZE_MIN_WIDTH = "48px";
|
|
19807
20639
|
function rendererModelTriggerMaxWidth() {
|
|
19808
20640
|
return "min(200px, 26vw)";
|
|
@@ -19832,6 +20664,23 @@ ${error51.stderrTail}`] : []
|
|
|
19832
20664
|
trigger.style.maxWidth = "100%";
|
|
19833
20665
|
trigger.style.overflow = "hidden";
|
|
19834
20666
|
}
|
|
20667
|
+
function observeRendererCompactComposer(composer) {
|
|
20668
|
+
const update = () => {
|
|
20669
|
+
const width = composer.getBoundingClientRect().width;
|
|
20670
|
+
if (width > 0) {
|
|
20671
|
+
composer.toggleAttribute(COMPACT_COMPOSER_ATTRIBUTE, width <= COMPACT_COMPOSER_WIDTH);
|
|
20672
|
+
}
|
|
20673
|
+
};
|
|
20674
|
+
update();
|
|
20675
|
+
if (typeof ResizeObserver === "undefined")
|
|
20676
|
+
return () => composer.removeAttribute(COMPACT_COMPOSER_ATTRIBUTE);
|
|
20677
|
+
const observer = new ResizeObserver(update);
|
|
20678
|
+
observer.observe(composer, { box: "border-box" });
|
|
20679
|
+
return () => {
|
|
20680
|
+
observer.disconnect();
|
|
20681
|
+
composer.removeAttribute(COMPACT_COMPOSER_ATTRIBUTE);
|
|
20682
|
+
};
|
|
20683
|
+
}
|
|
19835
20684
|
function ensureRendererTriggerChipStyle(ownerDocument) {
|
|
19836
20685
|
if (ownerDocument.querySelector(`style[${STYLE_ATTRIBUTE}]`)) return;
|
|
19837
20686
|
const style = ownerDocument.createElement("style");
|
|
@@ -19870,10 +20719,55 @@ ${error51.stderrTail}`] : []
|
|
|
19870
20719
|
cursor: not-allowed;
|
|
19871
20720
|
opacity: 0.4;
|
|
19872
20721
|
}
|
|
20722
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-model-control] [data-codexhost-model-thinking] {
|
|
20723
|
+
display: none !important;
|
|
20724
|
+
}
|
|
20725
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-mode-control] {
|
|
20726
|
+
min-width: 30px !important;
|
|
20727
|
+
max-width: 30px !important;
|
|
20728
|
+
}
|
|
20729
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-mode-control] .${TRIGGER_CHIP_CLASS} {
|
|
20730
|
+
padding-inline: 6px !important;
|
|
20731
|
+
}
|
|
20732
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-label],
|
|
20733
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-chevron],
|
|
20734
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-credits-label],
|
|
20735
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-usage-label] {
|
|
20736
|
+
display: none !important;
|
|
20737
|
+
}
|
|
20738
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-mode-control]:has([data-codexhost-permission-lock]:not([hidden])) [data-codexhost-permission-shield],
|
|
20739
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-permission-mode-control]:has([data-codexhost-permission-error]:not([hidden])) [data-codexhost-permission-shield] {
|
|
20740
|
+
display: none !important;
|
|
20741
|
+
}
|
|
20742
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-credits-control],
|
|
20743
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-usage-control] {
|
|
20744
|
+
min-width: 28px !important;
|
|
20745
|
+
max-width: 28px !important;
|
|
20746
|
+
}
|
|
20747
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-credits-control] .${TRIGGER_CHIP_CLASS},
|
|
20748
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-usage-control] .${TRIGGER_CHIP_CLASS} {
|
|
20749
|
+
padding-inline: 6px !important;
|
|
20750
|
+
}
|
|
20751
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-usage-icon] {
|
|
20752
|
+
display: inline-flex !important;
|
|
20753
|
+
}
|
|
20754
|
+
[${COMPACT_COMPOSER_ATTRIBUTE}] [data-codexhost-agent-control] {
|
|
20755
|
+
margin-inline: 0 !important;
|
|
20756
|
+
}
|
|
19873
20757
|
`;
|
|
19874
20758
|
(ownerDocument.head ?? ownerDocument.documentElement).append(style);
|
|
19875
20759
|
}
|
|
19876
20760
|
|
|
20761
|
+
// ../../node_modules/lucide/dist/esm/icons/activity.mjs
|
|
20762
|
+
var Activity = [
|
|
20763
|
+
[
|
|
20764
|
+
"path",
|
|
20765
|
+
{
|
|
20766
|
+
d: "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"
|
|
20767
|
+
}
|
|
20768
|
+
]
|
|
20769
|
+
];
|
|
20770
|
+
|
|
19877
20771
|
// src/renderer-usage-control.ts
|
|
19878
20772
|
var ENGLISH_USAGE_MESSAGES = Object.freeze({
|
|
19879
20773
|
usage: "Usage",
|
|
@@ -20227,13 +21121,19 @@ ${error51.stderrTail}`] : []
|
|
|
20227
21121
|
trigger.style.lineHeight = "16px";
|
|
20228
21122
|
trigger.style.fontVariantNumeric = "tabular-nums";
|
|
20229
21123
|
trigger.style.letterSpacing = "0";
|
|
21124
|
+
const icon2 = document.createElement("span");
|
|
21125
|
+
icon2.dataset.codexhostUsageIcon = "";
|
|
21126
|
+
icon2.style.display = "none";
|
|
21127
|
+
icon2.style.alignItems = "center";
|
|
21128
|
+
icon2.append(createElement(Activity, { width: 16, height: 16, "aria-hidden": "true" }));
|
|
20230
21129
|
const label = document.createElement("span");
|
|
21130
|
+
label.dataset.codexhostUsageLabel = "";
|
|
20231
21131
|
label.style.display = "inline-block";
|
|
20232
21132
|
label.style.maxWidth = "100%";
|
|
20233
21133
|
label.style.overflow = "hidden";
|
|
20234
21134
|
label.style.textOverflow = "ellipsis";
|
|
20235
21135
|
label.style.whiteSpace = "nowrap";
|
|
20236
|
-
trigger.append(label);
|
|
21136
|
+
trigger.append(icon2, label);
|
|
20237
21137
|
const popover = document.createElement("div");
|
|
20238
21138
|
popover.id = `${composerId}-usage-popover`;
|
|
20239
21139
|
popover.setAttribute("role", "dialog");
|
|
@@ -21099,6 +21999,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
21099
21999
|
label.style.textOverflow = "ellipsis";
|
|
21100
22000
|
label.style.whiteSpace = "nowrap";
|
|
21101
22001
|
const thinkingLabel = document.createElement("span");
|
|
22002
|
+
thinkingLabel.dataset.codexhostModelThinking = "";
|
|
21102
22003
|
thinkingLabel.style.color = "var(--color-text-tertiary, #8f8f8f)";
|
|
21103
22004
|
thinkingLabel.style.flex = "0 1 auto";
|
|
21104
22005
|
thinkingLabel.style.maxWidth = "72px";
|
|
@@ -21544,9 +22445,6 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
21544
22445
|
syncModelSelectionNotice(control, view, locale);
|
|
21545
22446
|
}
|
|
21546
22447
|
|
|
21547
|
-
// ../../node_modules/lucide/dist/esm/icons/check.mjs
|
|
21548
|
-
var Check = [["path", { d: "M20 6 9 17l-5-5" }]];
|
|
21549
|
-
|
|
21550
22448
|
// ../../node_modules/lucide/dist/esm/icons/lock.mjs
|
|
21551
22449
|
var Lock = [
|
|
21552
22450
|
["rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2" }],
|
|
@@ -21661,9 +22559,11 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
21661
22559
|
trigger.className = TRIGGER_CHIP_CLASS;
|
|
21662
22560
|
applyRendererTriggerChipSqueezeTrigger(trigger);
|
|
21663
22561
|
const shield = document.createElement("span");
|
|
22562
|
+
shield.dataset.codexhostPermissionShield = "";
|
|
21664
22563
|
shield.className = "inline-flex shrink-0 items-center";
|
|
21665
22564
|
shield.append(icon(Shield, 15));
|
|
21666
22565
|
const label = document.createElement("span");
|
|
22566
|
+
label.dataset.codexhostPermissionLabel = "";
|
|
21667
22567
|
label.className = "truncate";
|
|
21668
22568
|
label.style.flex = "1 1 auto";
|
|
21669
22569
|
label.style.minWidth = "0";
|
|
@@ -21671,15 +22571,18 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
21671
22571
|
label.style.textOverflow = "ellipsis";
|
|
21672
22572
|
label.style.whiteSpace = "nowrap";
|
|
21673
22573
|
const chevron = document.createElement("span");
|
|
22574
|
+
chevron.dataset.codexhostPermissionChevron = "";
|
|
21674
22575
|
chevron.className = "inline-flex shrink-0 items-center";
|
|
21675
22576
|
chevron.style.color = "var(--color-text-tertiary, #8f8f8f)";
|
|
21676
22577
|
chevron.append(icon(ChevronDown, 14));
|
|
21677
22578
|
const lockMark = document.createElement("span");
|
|
22579
|
+
lockMark.dataset.codexhostPermissionLock = "";
|
|
21678
22580
|
lockMark.className = "inline-flex shrink-0 items-center";
|
|
21679
22581
|
lockMark.style.color = "var(--color-text-tertiary, #8f8f8f)";
|
|
21680
22582
|
lockMark.hidden = true;
|
|
21681
22583
|
lockMark.append(icon(Lock, 14));
|
|
21682
22584
|
const errorMark = document.createElement("span");
|
|
22585
|
+
errorMark.dataset.codexhostPermissionError = "";
|
|
21683
22586
|
errorMark.className = "inline-flex shrink-0 items-center";
|
|
21684
22587
|
errorMark.style.color = "var(--color-text-danger, #c2413b)";
|
|
21685
22588
|
errorMark.hidden = true;
|
|
@@ -22236,7 +23139,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22236
23139
|
})
|
|
22237
23140
|
);
|
|
22238
23141
|
}
|
|
22239
|
-
if (label) label.textContent =
|
|
23142
|
+
if (label) label.textContent = `${Math.round(remaining)}%`;
|
|
22240
23143
|
control.root.style.display = "inline-flex";
|
|
22241
23144
|
control.trigger.setAttribute("aria-label", title);
|
|
22242
23145
|
control.trigger.title = title;
|
|
@@ -22244,6 +23147,163 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22244
23147
|
return true;
|
|
22245
23148
|
}
|
|
22246
23149
|
|
|
23150
|
+
// src/renderer-composer-indicators.ts
|
|
23151
|
+
var SHOW_WITHIN_SECONDS = 50 * 60;
|
|
23152
|
+
function mountRendererComposerIndicators(composer) {
|
|
23153
|
+
const doc = composer.ownerDocument;
|
|
23154
|
+
ensureRendererTriggerChipStyle(doc);
|
|
23155
|
+
const root = doc.createElement("div");
|
|
23156
|
+
root.setAttribute("data-codexhost-composer-indicators", "true");
|
|
23157
|
+
applyRendererTriggerChipSqueezeRoot(root, "128px", "0");
|
|
23158
|
+
Object.assign(root.style, { alignItems: "center", gap: "2px", flexShrink: "100000" });
|
|
23159
|
+
let indicators = [];
|
|
23160
|
+
let locale = "en";
|
|
23161
|
+
let timer;
|
|
23162
|
+
let anchor = null;
|
|
23163
|
+
let contentKey = "";
|
|
23164
|
+
let tip = null;
|
|
23165
|
+
const hideTip = () => {
|
|
23166
|
+
tip?.remove();
|
|
23167
|
+
tip = null;
|
|
23168
|
+
};
|
|
23169
|
+
const showTip = (chip, textContent) => {
|
|
23170
|
+
hideTip();
|
|
23171
|
+
const el = doc.createElement("div");
|
|
23172
|
+
el.setAttribute("role", "tooltip");
|
|
23173
|
+
el.textContent = textContent;
|
|
23174
|
+
Object.assign(el.style, {
|
|
23175
|
+
position: "fixed",
|
|
23176
|
+
zIndex: "2147483647",
|
|
23177
|
+
pointerEvents: "none",
|
|
23178
|
+
padding: "4px 8px",
|
|
23179
|
+
borderRadius: "8px",
|
|
23180
|
+
fontSize: "12px",
|
|
23181
|
+
whiteSpace: "nowrap",
|
|
23182
|
+
background: "rgba(30, 30, 30, 0.92)",
|
|
23183
|
+
color: "#fff",
|
|
23184
|
+
visibility: "hidden"
|
|
23185
|
+
});
|
|
23186
|
+
(doc.body ?? doc.documentElement).append(el);
|
|
23187
|
+
const rect = chip.getBoundingClientRect();
|
|
23188
|
+
const width = el.offsetWidth;
|
|
23189
|
+
const left = Math.max(
|
|
23190
|
+
4,
|
|
23191
|
+
Math.min(rect.left + rect.width / 2 - width / 2, window.innerWidth - width - 4)
|
|
23192
|
+
);
|
|
23193
|
+
el.style.left = `${left}px`;
|
|
23194
|
+
el.style.top = `${Math.max(4, rect.top - el.offsetHeight - 6)}px`;
|
|
23195
|
+
el.style.visibility = "visible";
|
|
23196
|
+
tip = el;
|
|
23197
|
+
};
|
|
23198
|
+
const refresh = () => {
|
|
23199
|
+
const now = Date.now() / 1e3;
|
|
23200
|
+
const active = indicators.filter(
|
|
23201
|
+
(indicator) => indicator.expiresAtUnix > now && indicator.expiresAtUnix - now <= SHOW_WITHIN_SECONDS
|
|
23202
|
+
);
|
|
23203
|
+
const nextKey = JSON.stringify([
|
|
23204
|
+
locale,
|
|
23205
|
+
active.map((indicator) => [indicator, Math.ceil((indicator.expiresAtUnix - now) / 60)])
|
|
23206
|
+
]);
|
|
23207
|
+
if (nextKey !== contentKey) {
|
|
23208
|
+
contentKey = nextKey;
|
|
23209
|
+
hideTip();
|
|
23210
|
+
root.replaceChildren();
|
|
23211
|
+
for (const indicator of active) {
|
|
23212
|
+
const minutes = Math.ceil((indicator.expiresAtUnix - now) / 60);
|
|
23213
|
+
const remaining = locale === "zh-CN" ? `\u5269\u4F59 ${minutes} \u5206\u949F` : `${minutes}m remaining`;
|
|
23214
|
+
const label = indicator.label ? localizeHarnessText(indicator.label, locale) : "";
|
|
23215
|
+
const tooltip = indicator.tooltip ? localizeHarnessText(indicator.tooltip, locale) : "";
|
|
23216
|
+
const chip = doc.createElement("span");
|
|
23217
|
+
chip.className = TRIGGER_CHIP_CLASS;
|
|
23218
|
+
chip.setAttribute("data-indicator-id", indicator.id);
|
|
23219
|
+
const summary = [label, tooltip, remaining].filter(Boolean).join(" \xB7 ");
|
|
23220
|
+
chip.setAttribute("aria-label", summary);
|
|
23221
|
+
chip.addEventListener("mouseenter", () => showTip(chip, summary));
|
|
23222
|
+
chip.addEventListener("mouseleave", hideTip);
|
|
23223
|
+
Object.assign(chip.style, {
|
|
23224
|
+
height: "28px",
|
|
23225
|
+
padding: "0 6px",
|
|
23226
|
+
gap: "4px",
|
|
23227
|
+
fontSize: "12px",
|
|
23228
|
+
cursor: "default",
|
|
23229
|
+
flexShrink: "0"
|
|
23230
|
+
});
|
|
23231
|
+
const icon2 = doc.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
23232
|
+
icon2.setAttribute("viewBox", "0 0 24 24");
|
|
23233
|
+
icon2.setAttribute("width", "14");
|
|
23234
|
+
icon2.setAttribute("height", "14");
|
|
23235
|
+
icon2.setAttribute("fill", "none");
|
|
23236
|
+
icon2.setAttribute("stroke", "currentColor");
|
|
23237
|
+
icon2.setAttribute("stroke-width", "1.5");
|
|
23238
|
+
icon2.setAttribute("aria-hidden", "true");
|
|
23239
|
+
const path = doc.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
23240
|
+
path.setAttribute("d", "M12 8v4l3 2M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0");
|
|
23241
|
+
icon2.append(path);
|
|
23242
|
+
const text = doc.createElement("span");
|
|
23243
|
+
text.textContent = `${minutes}m`;
|
|
23244
|
+
chip.append(icon2, text);
|
|
23245
|
+
root.append(chip);
|
|
23246
|
+
}
|
|
23247
|
+
}
|
|
23248
|
+
const visible = active.length > 0 && anchor !== null;
|
|
23249
|
+
if (root.hidden === visible) root.hidden = !visible;
|
|
23250
|
+
const display = visible ? "inline-flex" : "none";
|
|
23251
|
+
if (root.style.display !== display) root.style.display = display;
|
|
23252
|
+
const visibility = root.scrollWidth > root.clientWidth ? "hidden" : "visible";
|
|
23253
|
+
if (root.style.visibility !== visibility) root.style.visibility = visibility;
|
|
23254
|
+
const pending = indicators.some(({ expiresAtUnix }) => expiresAtUnix > now);
|
|
23255
|
+
if (!pending && timer !== void 0) {
|
|
23256
|
+
clearInterval(timer);
|
|
23257
|
+
timer = void 0;
|
|
23258
|
+
}
|
|
23259
|
+
};
|
|
23260
|
+
const observer = new ResizeObserver(refresh);
|
|
23261
|
+
observer.observe(root);
|
|
23262
|
+
refresh();
|
|
23263
|
+
return {
|
|
23264
|
+
root,
|
|
23265
|
+
place(next) {
|
|
23266
|
+
anchor = next;
|
|
23267
|
+
if (!next?.parentElement) {
|
|
23268
|
+
anchor = null;
|
|
23269
|
+
root.remove();
|
|
23270
|
+
} else if (next.nextElementSibling !== root) {
|
|
23271
|
+
next.parentElement.insertBefore(root, next.nextSibling);
|
|
23272
|
+
}
|
|
23273
|
+
refresh();
|
|
23274
|
+
},
|
|
23275
|
+
render(next, nextLocale) {
|
|
23276
|
+
indicators = next;
|
|
23277
|
+
locale = nextLocale;
|
|
23278
|
+
refresh();
|
|
23279
|
+
if (timer === void 0 && indicators.some(({ expiresAtUnix }) => expiresAtUnix > Date.now() / 1e3)) {
|
|
23280
|
+
timer = setInterval(refresh, 6e4);
|
|
23281
|
+
}
|
|
23282
|
+
},
|
|
23283
|
+
dispose() {
|
|
23284
|
+
observer.disconnect();
|
|
23285
|
+
hideTip();
|
|
23286
|
+
if (timer !== void 0) clearInterval(timer);
|
|
23287
|
+
root.remove();
|
|
23288
|
+
}
|
|
23289
|
+
};
|
|
23290
|
+
}
|
|
23291
|
+
|
|
23292
|
+
// src/renderer-composer-request.ts
|
|
23293
|
+
var NATIVE_COMPOSER_REQUEST_ATTRIBUTES = [
|
|
23294
|
+
"data-codex-composer-request-navigation",
|
|
23295
|
+
"data-codex-composer-request"
|
|
23296
|
+
];
|
|
23297
|
+
var NATIVE_REQUEST_SELECTOR = NATIVE_COMPOSER_REQUEST_ATTRIBUTES.map(
|
|
23298
|
+
(attribute) => `[${attribute}]`
|
|
23299
|
+
).join(", ");
|
|
23300
|
+
function isNativeComposerRequest(element) {
|
|
23301
|
+
return element.closest(NATIVE_REQUEST_SELECTOR) !== null;
|
|
23302
|
+
}
|
|
23303
|
+
function hasNativeComposerRequest(composer) {
|
|
23304
|
+
return isNativeComposerRequest(composer) || composer.querySelector(NATIVE_REQUEST_SELECTOR) !== null;
|
|
23305
|
+
}
|
|
23306
|
+
|
|
22247
23307
|
// src/renderer-harness-command-control.ts
|
|
22248
23308
|
var CONTROL_ATTRIBUTE2 = "data-codexhost-harness-command-control";
|
|
22249
23309
|
var SVG_NS2 = "http://www.w3.org/2000/svg";
|
|
@@ -22376,7 +23436,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22376
23436
|
return controlDescription(button2);
|
|
22377
23437
|
}
|
|
22378
23438
|
function isOwnedRendererControl(element) {
|
|
22379
|
-
return element.hasAttribute(CONTROL_ATTRIBUTE) || element.hasAttribute("data-codexhost-model-control") || element.hasAttribute("data-codexhost-permission-mode-control") || element.hasAttribute("data-codexhost-usage-control") || element.hasAttribute("data-codexhost-credits-control") || element.hasAttribute("data-codexhost-harness-command-control");
|
|
23439
|
+
return element.hasAttribute(CONTROL_ATTRIBUTE) || element.hasAttribute("data-codexhost-model-control") || element.hasAttribute("data-codexhost-permission-mode-control") || element.hasAttribute("data-codexhost-usage-control") || element.hasAttribute("data-codexhost-credits-control") || element.hasAttribute("data-codexhost-composer-indicators") || element.hasAttribute("data-codexhost-harness-command-control");
|
|
22380
23440
|
}
|
|
22381
23441
|
function isComposerSubmitButton(button2) {
|
|
22382
23442
|
if (button2.type === "submit") return true;
|
|
@@ -22405,10 +23465,13 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22405
23465
|
const buttons = [...element.querySelectorAll("button")];
|
|
22406
23466
|
return buttons.length > 0 && buttons.every((button2) => isComposerTrailingActionButton(button2));
|
|
22407
23467
|
}
|
|
23468
|
+
function composerButtonsWithin(root) {
|
|
23469
|
+
return [...root.querySelectorAll("button")].filter(
|
|
23470
|
+
(button2) => !isNativeComposerRequest(button2)
|
|
23471
|
+
);
|
|
23472
|
+
}
|
|
22408
23473
|
function sendButtonWithin(root) {
|
|
22409
|
-
return
|
|
22410
|
-
(button2) => isComposerSubmitButton(button2)
|
|
22411
|
-
) ?? null;
|
|
23474
|
+
return composerButtonsWithin(root).find(isComposerSubmitButton) ?? null;
|
|
22412
23475
|
}
|
|
22413
23476
|
function leftmostTrailingSibling(container, before) {
|
|
22414
23477
|
for (const child of container.children) {
|
|
@@ -22451,7 +23514,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22451
23514
|
}
|
|
22452
23515
|
function composerForElement(element) {
|
|
22453
23516
|
const composer = element.closest(CODEX_COMPOSER_SELECTOR);
|
|
22454
|
-
return composer && !isOrbitComposer(composer) ? composer : null;
|
|
23517
|
+
return composer && !hasNativeComposerRequest(composer) && !isOrbitComposer(composer) ? composer : null;
|
|
22455
23518
|
}
|
|
22456
23519
|
function isRecord(value) {
|
|
22457
23520
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -22575,7 +23638,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22575
23638
|
return root?.parentElement ? root : null;
|
|
22576
23639
|
}
|
|
22577
23640
|
function lastNativeButtonWithin(composer) {
|
|
22578
|
-
const buttons =
|
|
23641
|
+
const buttons = composerButtonsWithin(composer);
|
|
22579
23642
|
for (let index = buttons.length - 1; index >= 0; index -= 1) {
|
|
22580
23643
|
const button2 = buttons[index];
|
|
22581
23644
|
if (button2 && !isInsideOwnedRendererControl(button2, composer)) return button2;
|
|
@@ -22589,6 +23652,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22589
23652
|
return false;
|
|
22590
23653
|
}
|
|
22591
23654
|
function refreshSendButton(control) {
|
|
23655
|
+
if (hasNativeComposerRequest(control.composer)) return null;
|
|
22592
23656
|
const current = control.sendButton;
|
|
22593
23657
|
if (current?.isConnected && control.composer.contains(current)) return current;
|
|
22594
23658
|
const replacement = sendButtonWithin(control.composer) ?? (current && !isComposerSubmitButton(current) ? lastNativeButtonWithin(control.composer) : null);
|
|
@@ -22674,6 +23738,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22674
23738
|
refreshTrailingClusterPlacement(control);
|
|
22675
23739
|
refreshUsagePlacement(control);
|
|
22676
23740
|
refreshCreditsPlacement(control);
|
|
23741
|
+
control.composerIndicators?.place(
|
|
23742
|
+
control.nativePermissionModeControlVerified ? control.nativePermissionModeControl?.element ?? null : null
|
|
23743
|
+
);
|
|
22677
23744
|
setNativeControlHidden(control.nativeModelControl, hideModel);
|
|
22678
23745
|
setNativeControlHidden(control.nativeContextUsageControl, false);
|
|
22679
23746
|
setNativeControlHidden(control.nativePermissionModeControl, hidePermissionMode);
|
|
@@ -22700,6 +23767,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22700
23767
|
onSelectPermissionMode
|
|
22701
23768
|
);
|
|
22702
23769
|
const credits = mountRendererCreditsControl(composerId);
|
|
23770
|
+
const composerIndicators = mountRendererComposerIndicators(composer);
|
|
22703
23771
|
const toolbar = sendButton.parentElement;
|
|
22704
23772
|
const harnessCommands = mountRendererHarnessCommandControl(
|
|
22705
23773
|
toolbar ?? composer,
|
|
@@ -22746,6 +23814,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22746
23814
|
nativeContextUsageControl,
|
|
22747
23815
|
nativePermissionModeControlVerified,
|
|
22748
23816
|
credits,
|
|
23817
|
+
composerIndicators,
|
|
22749
23818
|
usage: null,
|
|
22750
23819
|
harnessCommands,
|
|
22751
23820
|
sendButton,
|
|
@@ -22754,6 +23823,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22754
23823
|
refreshTrailingClusterPlacement(control);
|
|
22755
23824
|
refreshUsagePlacement(control);
|
|
22756
23825
|
refreshCreditsPlacement(control);
|
|
23826
|
+
control.stopCompactLayout = observeRendererCompactComposer(composer);
|
|
22757
23827
|
return control;
|
|
22758
23828
|
}
|
|
22759
23829
|
function nativeSendDisabled(button2, fallback) {
|
|
@@ -22811,6 +23881,10 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22811
23881
|
permissionModeVisible,
|
|
22812
23882
|
locale
|
|
22813
23883
|
);
|
|
23884
|
+
control.composerIndicators?.render(
|
|
23885
|
+
permissionModeVisible ? usage?.composerIndicators ?? [] : [],
|
|
23886
|
+
locale
|
|
23887
|
+
);
|
|
22814
23888
|
if (control.usage) {
|
|
22815
23889
|
renderRendererUsageControl(control.usage, usage, locale);
|
|
22816
23890
|
}
|
|
@@ -22821,6 +23895,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22821
23895
|
return state.agent !== "codex" && adapterState === "ready" && !submissionBlocked;
|
|
22822
23896
|
}
|
|
22823
23897
|
function disposeComposerAgentControl(control) {
|
|
23898
|
+
control.stopCompactLayout?.();
|
|
22824
23899
|
if (control.sendDisabledBeforeSwitch !== null) {
|
|
22825
23900
|
control.sendButton.disabled = nativeSendDisabled(
|
|
22826
23901
|
control.sendButton,
|
|
@@ -22830,6 +23905,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
22830
23905
|
restoreNativeControl(control.nativeModelControl);
|
|
22831
23906
|
restoreNativeControl(control.nativeContextUsageControl);
|
|
22832
23907
|
restoreNativeControl(control.nativePermissionModeControl);
|
|
23908
|
+
control.composerIndicators?.dispose();
|
|
22833
23909
|
control.credits.dispose();
|
|
22834
23910
|
control.usage?.dispose();
|
|
22835
23911
|
control.usage = null;
|
|
@@ -23384,36 +24460,24 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23384
24460
|
};
|
|
23385
24461
|
}
|
|
23386
24462
|
|
|
23387
|
-
// src/renderer-
|
|
23388
|
-
|
|
23389
|
-
|
|
23390
|
-
|
|
23391
|
-
|
|
23392
|
-
|
|
24463
|
+
// src/renderer-installation-client.ts
|
|
24464
|
+
async function runRendererInstallation(send, input) {
|
|
24465
|
+
const params = harnessInstallationParamsSchema.parse(input);
|
|
24466
|
+
const options = { priority: "background", timeoutMs: 15e3 };
|
|
24467
|
+
let task = harnessInstallationTaskSchema.parse(
|
|
24468
|
+
await send(HARNESS_INSTALLATION_START_METHOD, params, options)
|
|
24469
|
+
);
|
|
24470
|
+
const taskId = task.taskId;
|
|
24471
|
+
while (task.status === "running") {
|
|
24472
|
+
await new Promise((resolve) => globalThis.setTimeout(resolve, 500));
|
|
24473
|
+
task = harnessInstallationTaskSchema.parse(
|
|
24474
|
+
await send(HARNESS_INSTALLATION_STATUS_METHOD, { taskId }, options)
|
|
24475
|
+
);
|
|
24476
|
+
if (task.taskId !== taskId) throw new Error("Harness installation task identity changed");
|
|
23393
24477
|
}
|
|
23394
|
-
|
|
23395
|
-
|
|
23396
|
-
|
|
23397
|
-
function isUnsupportedMethod(error51, method) {
|
|
23398
|
-
if (typeof error51 !== "object" || error51 === null) return false;
|
|
23399
|
-
const code = "code" in error51 ? error51.code : void 0;
|
|
23400
|
-
const message2 = "message" in error51 ? error51.message : void 0;
|
|
23401
|
-
return code === -32601 || code === -32600 && typeof message2 === "string" && message2.startsWith(`Invalid request: unknown variant \`${method}\``);
|
|
23402
|
-
}
|
|
23403
|
-
function createRendererRequestSender(send) {
|
|
23404
|
-
const unsupported = /* @__PURE__ */ new Map();
|
|
23405
|
-
return async (method, params, options) => {
|
|
23406
|
-
const known = unsupported.get(method);
|
|
23407
|
-
if (known) throw known;
|
|
23408
|
-
try {
|
|
23409
|
-
return await (options === void 0 ? send(method, params) : send(method, params, options));
|
|
23410
|
-
} catch (error51) {
|
|
23411
|
-
if (!method.startsWith("codexhost/") || !isUnsupportedMethod(error51, method)) throw error51;
|
|
23412
|
-
const unavailable = new RendererMethodUnavailableError(method, error51);
|
|
23413
|
-
unsupported.set(method, unavailable);
|
|
23414
|
-
throw unavailable;
|
|
23415
|
-
}
|
|
23416
|
-
};
|
|
24478
|
+
if (task.status === "failed")
|
|
24479
|
+
throw Object.assign(new Error(task.error.message), { code: task.error.code });
|
|
24480
|
+
return task.result;
|
|
23417
24481
|
}
|
|
23418
24482
|
|
|
23419
24483
|
// src/renderer-native-thread.ts
|
|
@@ -23573,7 +24637,15 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23573
24637
|
};
|
|
23574
24638
|
const inspectHarness = async (input, options) => {
|
|
23575
24639
|
const params = harnessInspectParamsSchema.parse(input);
|
|
23576
|
-
|
|
24640
|
+
let result;
|
|
24641
|
+
try {
|
|
24642
|
+
result = await manager.sendRequest(HARNESS_INSPECT_METHOD, params, options);
|
|
24643
|
+
} catch (error51) {
|
|
24644
|
+
if (!params.purpose || !isInvalidParams(error51)) throw error51;
|
|
24645
|
+
const full = { ...params };
|
|
24646
|
+
delete full.purpose;
|
|
24647
|
+
result = await manager.sendRequest(HARNESS_INSPECT_METHOD, full, options);
|
|
24648
|
+
}
|
|
23577
24649
|
return harnessInspectionSchema.parse(result);
|
|
23578
24650
|
};
|
|
23579
24651
|
const inspectHarnessCommands = async (input) => {
|
|
@@ -23613,13 +24685,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23613
24685
|
};
|
|
23614
24686
|
return Object.freeze({
|
|
23615
24687
|
async installation(input) {
|
|
23616
|
-
return
|
|
23617
|
-
await manager.sendRequest(
|
|
23618
|
-
HARNESS_INSTALLATION_METHOD,
|
|
23619
|
-
harnessInstallationParamsSchema.parse(input),
|
|
23620
|
-
{ priority: "interactive" }
|
|
23621
|
-
)
|
|
23622
|
-
);
|
|
24688
|
+
return runRendererInstallation(manager.sendRequest, input);
|
|
23623
24689
|
},
|
|
23624
24690
|
async getHarnessDisplaySettings() {
|
|
23625
24691
|
return harnessDisplaySettingsSchema.parse(
|
|
@@ -23835,6 +24901,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23835
24901
|
}
|
|
23836
24902
|
});
|
|
23837
24903
|
}
|
|
24904
|
+
function isInvalidParams(error51) {
|
|
24905
|
+
return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === -32602;
|
|
24906
|
+
}
|
|
23838
24907
|
|
|
23839
24908
|
// src/renderer-external-queue.ts
|
|
23840
24909
|
function isRecord6(value) {
|
|
@@ -23870,6 +24939,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23870
24939
|
}
|
|
23871
24940
|
|
|
23872
24941
|
// src/renderer-external-steering.ts
|
|
24942
|
+
var THREAD_STEERING_INSPECT_METHOD = "codexhost/thread/steering/inspect";
|
|
23873
24943
|
var THREAD_OWNERSHIP_LIST_METHOD2 = "codexhost/thread/ownership/list";
|
|
23874
24944
|
function isRecord7(value) {
|
|
23875
24945
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -23953,6 +25023,7 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23953
25023
|
const originalSteer = manager.steerTurn;
|
|
23954
25024
|
const originalSend = manager.sendRequest;
|
|
23955
25025
|
const routes = /* @__PURE__ */ new Map();
|
|
25026
|
+
const activeTurnSteers = /* @__PURE__ */ new Map();
|
|
23956
25027
|
const pending = /* @__PURE__ */ new Map();
|
|
23957
25028
|
let disposed = false;
|
|
23958
25029
|
const send = function(method, params, options) {
|
|
@@ -23968,6 +25039,9 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23968
25039
|
return originalSend.call(manager, method, input, options);
|
|
23969
25040
|
});
|
|
23970
25041
|
}
|
|
25042
|
+
if (method === "turn/steer" && isRecord7(params) && typeof params.threadId === "string" && activeTurnSteers.has(params.threadId)) {
|
|
25043
|
+
params = { ...params, [THREAD_STEER_DELIVERY_PARAM]: "activeTurn" };
|
|
25044
|
+
}
|
|
23971
25045
|
return originalSend.call(manager, method, params, options);
|
|
23972
25046
|
}
|
|
23973
25047
|
if (disposed) return Promise.reject(new Error("External steering binding was disposed"));
|
|
@@ -23982,7 +25056,8 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
23982
25056
|
input: params.input,
|
|
23983
25057
|
additionalContext: params.additionalContext,
|
|
23984
25058
|
responsesapiClientMetadata: params.responsesapiClientMetadata,
|
|
23985
|
-
...params[THREAD_REFERENCE_SOURCE_HOST_PARAM] !== void 0 ? { [THREAD_REFERENCE_SOURCE_HOST_PARAM]: params[THREAD_REFERENCE_SOURCE_HOST_PARAM] } : {}
|
|
25059
|
+
...params[THREAD_REFERENCE_SOURCE_HOST_PARAM] !== void 0 ? { [THREAD_REFERENCE_SOURCE_HOST_PARAM]: params[THREAD_REFERENCE_SOURCE_HOST_PARAM] } : {},
|
|
25060
|
+
[THREAD_STEER_DELIVERY_PARAM]: "newTurn"
|
|
23986
25061
|
},
|
|
23987
25062
|
options
|
|
23988
25063
|
)
|
|
@@ -24004,6 +25079,34 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24004
25079
|
};
|
|
24005
25080
|
});
|
|
24006
25081
|
};
|
|
25082
|
+
const inspectDelivery = async (threadId, text) => {
|
|
25083
|
+
try {
|
|
25084
|
+
const response = await originalSend.call(manager, THREAD_STEERING_INSPECT_METHOD, {
|
|
25085
|
+
threadId,
|
|
25086
|
+
...text !== void 0 ? { text } : {}
|
|
25087
|
+
});
|
|
25088
|
+
return threadSteeringInspectResultSchema.parse(response).delivery;
|
|
25089
|
+
} catch (error51) {
|
|
25090
|
+
if (!isUnsupportedMethod(error51, THREAD_STEERING_INSPECT_METHOD)) throw error51;
|
|
25091
|
+
}
|
|
25092
|
+
let ownershipResponse;
|
|
25093
|
+
try {
|
|
25094
|
+
ownershipResponse = await originalSend.call(manager, THREAD_OWNERSHIP_LIST_METHOD2, {
|
|
25095
|
+
threadIds: [threadId]
|
|
25096
|
+
});
|
|
25097
|
+
} catch (error51) {
|
|
25098
|
+
if (!isUnsupportedMethod(error51, THREAD_OWNERSHIP_LIST_METHOD2)) throw error51;
|
|
25099
|
+
await verifyNativeCodexThread(
|
|
25100
|
+
(method, params) => originalSend.call(manager, method, params),
|
|
25101
|
+
threadId
|
|
25102
|
+
);
|
|
25103
|
+
return "official";
|
|
25104
|
+
}
|
|
25105
|
+
const ownership = threadOwnershipListResultSchema.parse(ownershipResponse);
|
|
25106
|
+
const owner = ownership.threads.find((thread) => thread.threadId === threadId)?.owner;
|
|
25107
|
+
if (!owner) throw new Error("Thread ownership could not be resolved for steering");
|
|
25108
|
+
return owner === "codex" ? "official" : "newTurn";
|
|
25109
|
+
};
|
|
24007
25110
|
const steer = async function(...args) {
|
|
24008
25111
|
const [
|
|
24009
25112
|
threadId,
|
|
@@ -24026,25 +25129,20 @@ Codex Fast mode prioritizes requests and may increase usage.`
|
|
|
24026
25129
|
expectedTurnId = host.getActiveTurnId(threadId);
|
|
24027
25130
|
} catch {
|
|
24028
25131
|
}
|
|
24029
|
-
|
|
24030
|
-
|
|
24031
|
-
ownershipResponse = await originalSend.call(manager, THREAD_OWNERSHIP_LIST_METHOD2, {
|
|
24032
|
-
threadIds: [threadId]
|
|
24033
|
-
});
|
|
24034
|
-
} catch (error51) {
|
|
24035
|
-
if (!isUnsupportedMethod(error51, THREAD_OWNERSHIP_LIST_METHOD2)) throw error51;
|
|
24036
|
-
await verifyNativeCodexThread(
|
|
24037
|
-
(method, params) => originalSend.call(manager, method, params),
|
|
24038
|
-
threadId
|
|
24039
|
-
);
|
|
24040
|
-
if (disposed) throw new Error("External steering binding was disposed");
|
|
24041
|
-
return originalSteer.apply(manager, args);
|
|
24042
|
-
}
|
|
24043
|
-
const ownership = threadOwnershipListResultSchema.parse(ownershipResponse);
|
|
24044
|
-
const owner = ownership.threads.find((thread) => thread.threadId === threadId)?.owner;
|
|
24045
|
-
if (!owner) throw new Error("Thread ownership could not be resolved for steering");
|
|
25132
|
+
const text = Array.isArray(input) ? input.filter((item) => isRecord7(item) && typeof item.text === "string").map((item) => item.text).join("\n") : void 0;
|
|
25133
|
+
const delivery = await inspectDelivery(threadId, text);
|
|
24046
25134
|
if (disposed) throw new Error("External steering binding was disposed");
|
|
24047
|
-
if (
|
|
25135
|
+
if (delivery === "official") return originalSteer.apply(manager, args);
|
|
25136
|
+
if (delivery === "activeTurn") {
|
|
25137
|
+
activeTurnSteers.set(threadId, (activeTurnSteers.get(threadId) ?? 0) + 1);
|
|
25138
|
+
try {
|
|
25139
|
+
return await originalSteer.apply(manager, args);
|
|
25140
|
+
} finally {
|
|
25141
|
+
const remaining = (activeTurnSteers.get(threadId) ?? 1) - 1;
|
|
25142
|
+
if (remaining > 0) activeTurnSteers.set(threadId, remaining);
|
|
25143
|
+
else activeTurnSteers.delete(threadId);
|
|
25144
|
+
}
|
|
25145
|
+
}
|
|
24048
25146
|
if (!host) throw new Error("Desktop turn submission binding is unavailable");
|
|
24049
25147
|
const currentRole = manager.getStreamRole?.(threadId);
|
|
24050
25148
|
if (isRecord7(currentRole) && currentRole.role === "follower")
|
|
@@ -24289,9 +25387,9 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
24289
25387
|
}
|
|
24290
25388
|
|
|
24291
25389
|
// src/renderer-thread-reference-capability.ts
|
|
24292
|
-
var
|
|
25390
|
+
var record4 = (value) => typeof value === "object" && value !== null;
|
|
24293
25391
|
function restoreThreadReferenceCapability(client, manager, isCurrent) {
|
|
24294
|
-
if (!
|
|
25392
|
+
if (!record4(manager) || !record4(manager.storage)) return client;
|
|
24295
25393
|
const storage = manager.storage;
|
|
24296
25394
|
const read = storage.readValue;
|
|
24297
25395
|
const write = storage.writeValue;
|
|
@@ -24326,14 +25424,14 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
24326
25424
|
}
|
|
24327
25425
|
|
|
24328
25426
|
// src/renderer-thread-reference-context.ts
|
|
24329
|
-
var
|
|
25427
|
+
var record5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24330
25428
|
function createThreadReferenceContext(manager, hostId2, isCurrent) {
|
|
24331
25429
|
const prepared = /* @__PURE__ */ new WeakMap();
|
|
24332
25430
|
return (params) => {
|
|
24333
|
-
if (hostId2 === "local" || !
|
|
25431
|
+
if (hostId2 === "local" || !record5(manager) || typeof manager.getConversation !== "function" || !record5(params) || typeof params.threadId !== "string")
|
|
24334
25432
|
return params;
|
|
24335
25433
|
const conversation = manager.getConversation.call(manager, params.threadId);
|
|
24336
|
-
if (!
|
|
25434
|
+
if (!record5(conversation) || conversation.id !== params.threadId || conversation.modelProvider !== "codexhost")
|
|
24337
25435
|
return params;
|
|
24338
25436
|
if (!isCurrent()) throw new Error("Thread reference connection is no longer available");
|
|
24339
25437
|
const cached2 = prepared.get(params);
|
|
@@ -25852,9 +26950,17 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25852
26950
|
}
|
|
25853
26951
|
|
|
25854
26952
|
// src/codex-locale-adapter.ts
|
|
25855
|
-
var GET_LOCALE_OVERRIDE_URL = "vscode://codex/get-setting";
|
|
25856
|
-
var GET_LOCALE_INFO_URL = "vscode://codex/locale-info";
|
|
25857
26953
|
var DEFAULT_LOCALE_REQUEST_TIMEOUT_MS = 750;
|
|
26954
|
+
function isNativeLocaleServices(value) {
|
|
26955
|
+
if (!isRecord14(value) || !Object.hasOwn(value, "appInfo")) return false;
|
|
26956
|
+
const appInfo = value.appInfo;
|
|
26957
|
+
return appInfo != null && typeof appInfo.getLocaleInfo === "function";
|
|
26958
|
+
}
|
|
26959
|
+
function isNativeSettingsServices(value) {
|
|
26960
|
+
if (!isRecord14(value) || !Object.hasOwn(value, "settings")) return false;
|
|
26961
|
+
const settings = value.settings;
|
|
26962
|
+
return typeof settings?.read === "function" && typeof settings?.write === "function";
|
|
26963
|
+
}
|
|
25858
26964
|
function isRecord14(value) {
|
|
25859
26965
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25860
26966
|
}
|
|
@@ -25876,19 +26982,19 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25876
26982
|
function abortError2() {
|
|
25877
26983
|
return new DOMException("The operation was aborted", "AbortError");
|
|
25878
26984
|
}
|
|
25879
|
-
function parseLocaleOverride(
|
|
25880
|
-
if (!isRecord14(
|
|
25881
|
-
throw new Error("Codex locale override response is malformed");
|
|
26985
|
+
function parseLocaleOverride(response) {
|
|
26986
|
+
if (!isRecord14(response) || !Object.hasOwn(response, "effective")) {
|
|
26987
|
+
throw new Error("Codex native locale override response is malformed");
|
|
25882
26988
|
}
|
|
25883
|
-
if (
|
|
25884
|
-
const locale = canonicalLocale(
|
|
26989
|
+
if (response.effective === null) return null;
|
|
26990
|
+
const locale = canonicalLocale(response.effective);
|
|
25885
26991
|
if (!locale) throw new Error("Codex locale override is invalid");
|
|
25886
|
-
return
|
|
26992
|
+
return locale;
|
|
25887
26993
|
}
|
|
25888
|
-
function optionalLocale(value,
|
|
26994
|
+
function optionalLocale(value, field2) {
|
|
25889
26995
|
if (value === void 0 || value === null) return void 0;
|
|
25890
26996
|
const locale = canonicalLocale(value);
|
|
25891
|
-
if (!locale) throw new Error(`Codex ${
|
|
26997
|
+
if (!locale) throw new Error(`Codex ${field2} is invalid`);
|
|
25892
26998
|
return locale;
|
|
25893
26999
|
}
|
|
25894
27000
|
function parseLocaleInfo(value) {
|
|
@@ -25898,87 +27004,39 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25898
27004
|
systemLocale: optionalLocale(value.systemLocale, "system locale")
|
|
25899
27005
|
};
|
|
25900
27006
|
}
|
|
25901
|
-
function
|
|
25902
|
-
const bridge = ownerWindow.electronBridge;
|
|
25903
|
-
if (typeof bridge?.sendMessageFromView !== "function") {
|
|
25904
|
-
return Promise.reject(new Error("Codex locale bridge is unavailable"));
|
|
25905
|
-
}
|
|
27007
|
+
function requestNativeLocale(ownerWindow, signal, timeoutMs, matchesServices, invoke) {
|
|
25906
27008
|
if (signal?.aborted) return Promise.reject(abortError2());
|
|
25907
|
-
const requestId = ownerWindow.crypto.randomUUID();
|
|
25908
27009
|
return new Promise((resolve, reject) => {
|
|
25909
27010
|
let settled = false;
|
|
25910
|
-
|
|
25911
|
-
ownerWindow.clearTimeout(timer);
|
|
25912
|
-
ownerWindow.removeEventListener("message", onMessage);
|
|
25913
|
-
signal?.removeEventListener("abort", onAbort);
|
|
25914
|
-
};
|
|
27011
|
+
let nativeRequest;
|
|
25915
27012
|
const settle = (operation) => {
|
|
25916
27013
|
if (settled) return;
|
|
25917
27014
|
settled = true;
|
|
25918
|
-
|
|
25919
|
-
|
|
25920
|
-
};
|
|
25921
|
-
const onAbort = () => settle(() => reject(abortError2()));
|
|
25922
|
-
const onMessage = (event) => {
|
|
25923
|
-
const message3 = event.data;
|
|
25924
|
-
if (!isRecord14(message3) || message3.type !== "fetch-response") return;
|
|
25925
|
-
if (message3.requestId !== requestId) return;
|
|
25926
|
-
if (message3.responseType !== "success" || typeof message3.status !== "number" || message3.status < 200 || message3.status >= 300 || typeof message3.bodyJsonString !== "string") {
|
|
25927
|
-
settle(() => reject(new Error("Codex locale request failed")));
|
|
25928
|
-
return;
|
|
25929
|
-
}
|
|
27015
|
+
ownerWindow.clearTimeout(timer);
|
|
27016
|
+
signal?.removeEventListener("abort", onAbort);
|
|
25930
27017
|
try {
|
|
25931
|
-
|
|
25932
|
-
|
|
25933
|
-
} catch {
|
|
25934
|
-
|
|
27018
|
+
nativeRequest?.[Symbol.dispose]?.();
|
|
27019
|
+
operation();
|
|
27020
|
+
} catch (error51) {
|
|
27021
|
+
reject(error51);
|
|
25935
27022
|
}
|
|
25936
27023
|
};
|
|
27024
|
+
const onAbort = () => settle(() => reject(abortError2()));
|
|
25937
27025
|
const timer = ownerWindow.setTimeout(
|
|
25938
27026
|
() => settle(() => reject(new Error("Codex locale request timed out"))),
|
|
25939
27027
|
timeoutMs
|
|
25940
27028
|
);
|
|
25941
|
-
ownerWindow.addEventListener("message", onMessage);
|
|
25942
27029
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
25943
|
-
|
|
25944
|
-
|
|
25945
|
-
|
|
25946
|
-
|
|
25947
|
-
|
|
25948
|
-
|
|
25949
|
-
|
|
25950
|
-
};
|
|
25951
|
-
try {
|
|
25952
|
-
Promise.resolve(bridge.sendMessageFromView(message2)).catch((error51) => {
|
|
25953
|
-
settle(() => reject(error51));
|
|
25954
|
-
});
|
|
25955
|
-
} catch (error51) {
|
|
25956
|
-
settle(() => reject(error51));
|
|
25957
|
-
}
|
|
27030
|
+
void (async () => {
|
|
27031
|
+
const native = await loadCodexNativeServices(ownerWindow, matchesServices);
|
|
27032
|
+
if (settled) return;
|
|
27033
|
+
if (!native) throw new Error("Codex native locale services are unavailable");
|
|
27034
|
+
nativeRequest = invoke(native);
|
|
27035
|
+
const response = await nativeRequest;
|
|
27036
|
+
settle(() => resolve(response));
|
|
27037
|
+
})().catch((error51) => settle(() => reject(error51)));
|
|
25958
27038
|
});
|
|
25959
27039
|
}
|
|
25960
|
-
async function readLocaleOverride(ownerWindow, signal, timeoutMs) {
|
|
25961
|
-
const response = await sendFixedLocaleRequest(
|
|
25962
|
-
{
|
|
25963
|
-
kind: "locale-override",
|
|
25964
|
-
url: GET_LOCALE_OVERRIDE_URL,
|
|
25965
|
-
body: JSON.stringify({ key: "localeOverride" })
|
|
25966
|
-
},
|
|
25967
|
-
ownerWindow,
|
|
25968
|
-
signal,
|
|
25969
|
-
timeoutMs
|
|
25970
|
-
);
|
|
25971
|
-
return parseLocaleOverride(response);
|
|
25972
|
-
}
|
|
25973
|
-
async function readLocaleInfo(ownerWindow, signal, timeoutMs) {
|
|
25974
|
-
const response = await sendFixedLocaleRequest(
|
|
25975
|
-
{ kind: "locale-info", url: GET_LOCALE_INFO_URL },
|
|
25976
|
-
ownerWindow,
|
|
25977
|
-
signal,
|
|
25978
|
-
timeoutMs
|
|
25979
|
-
);
|
|
25980
|
-
return parseLocaleInfo(response);
|
|
25981
|
-
}
|
|
25982
27040
|
async function readCodexLocaleSettings(options = {}) {
|
|
25983
27041
|
const ownerWindow = options.ownerWindow ?? window;
|
|
25984
27042
|
const timeoutMs = options.timeoutMs ?? DEFAULT_LOCALE_REQUEST_TIMEOUT_MS;
|
|
@@ -25987,13 +27045,25 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
25987
27045
|
}
|
|
25988
27046
|
if (options.signal?.aborted) throw abortError2();
|
|
25989
27047
|
const [overrideResult, localeInfoResult] = await Promise.allSettled([
|
|
25990
|
-
|
|
25991
|
-
|
|
27048
|
+
requestNativeLocale(
|
|
27049
|
+
ownerWindow,
|
|
27050
|
+
options.signal,
|
|
27051
|
+
timeoutMs,
|
|
27052
|
+
isNativeSettingsServices,
|
|
27053
|
+
(native) => native.settings.read("localeOverride")
|
|
27054
|
+
).then(parseLocaleOverride),
|
|
27055
|
+
requestNativeLocale(
|
|
27056
|
+
ownerWindow,
|
|
27057
|
+
options.signal,
|
|
27058
|
+
timeoutMs,
|
|
27059
|
+
isNativeLocaleServices,
|
|
27060
|
+
(native) => native.appInfo.getLocaleInfo()
|
|
27061
|
+
).then(parseLocaleInfo)
|
|
25992
27062
|
]);
|
|
25993
27063
|
if (options.signal?.aborted) throw abortError2();
|
|
25994
27064
|
const navigatorLocale = firstNavigatorLocale(ownerWindow);
|
|
25995
27065
|
const overrideKnown = overrideResult.status === "fulfilled";
|
|
25996
|
-
const localeOverride = overrideKnown ? overrideResult.value
|
|
27066
|
+
const localeOverride = overrideKnown ? overrideResult.value : void 0;
|
|
25997
27067
|
const localeInfo = localeInfoResult.status === "fulfilled" ? localeInfoResult.value : { ideLocale: void 0, systemLocale: void 0 };
|
|
25998
27068
|
if (typeof localeOverride === "string") {
|
|
25999
27069
|
return Object.freeze({
|
|
@@ -26064,6 +27134,34 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
26064
27134
|
return names.size === 1 ? names.values().next().value ?? model2 : model2;
|
|
26065
27135
|
}
|
|
26066
27136
|
|
|
27137
|
+
// src/console/usage/usage-hosts.ts
|
|
27138
|
+
var LOCAL_USAGE_HOST_ID = "local";
|
|
27139
|
+
function usageHostOptions(hosts, localLabel, selected) {
|
|
27140
|
+
const options = [{ key: LOCAL_USAGE_HOST_ID, label: localLabel }];
|
|
27141
|
+
const seen = /* @__PURE__ */ new Set([LOCAL_USAGE_HOST_ID]);
|
|
27142
|
+
const add = (hostId2, label) => {
|
|
27143
|
+
if (hostId2.length === 0 || seen.has(hostId2)) return;
|
|
27144
|
+
seen.add(hostId2);
|
|
27145
|
+
options.push({ key: hostId2, label: label !== void 0 && label.length > 0 ? label : hostId2 });
|
|
27146
|
+
};
|
|
27147
|
+
for (const host of hosts ?? []) add(host.hostId, host.label);
|
|
27148
|
+
if (!seen.has(selected)) add(selected, void 0);
|
|
27149
|
+
return options;
|
|
27150
|
+
}
|
|
27151
|
+
function createLatestKeyGuard() {
|
|
27152
|
+
let generation = 0;
|
|
27153
|
+
let key;
|
|
27154
|
+
return {
|
|
27155
|
+
begin(next) {
|
|
27156
|
+
generation += 1;
|
|
27157
|
+
key = next;
|
|
27158
|
+
const mine = generation;
|
|
27159
|
+
const selected = next;
|
|
27160
|
+
return () => generation === mine && Object.is(key, selected);
|
|
27161
|
+
}
|
|
27162
|
+
};
|
|
27163
|
+
}
|
|
27164
|
+
|
|
26067
27165
|
// src/console/usage/format.ts
|
|
26068
27166
|
var MEASURES = ["cost", "tokens"];
|
|
26069
27167
|
function fill(template, values) {
|
|
@@ -26310,7 +27408,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
26310
27408
|
var DECIMAL = /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/iu;
|
|
26311
27409
|
function modelPriceDraft(key, price) {
|
|
26312
27410
|
const prices = Object.fromEntries(
|
|
26313
|
-
MODEL_PRICE_FIELDS.map((
|
|
27411
|
+
MODEL_PRICE_FIELDS.map((field2) => [field2, price?.[field2]?.toString() ?? ""])
|
|
26314
27412
|
);
|
|
26315
27413
|
return { model: key, prices };
|
|
26316
27414
|
}
|
|
@@ -26321,18 +27419,18 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
26321
27419
|
return { error: { kind: "duplicate", key } };
|
|
26322
27420
|
}
|
|
26323
27421
|
const price = {};
|
|
26324
|
-
for (const
|
|
26325
|
-
const text = draft.prices[
|
|
27422
|
+
for (const field2 of MODEL_PRICE_FIELDS) {
|
|
27423
|
+
const text = draft.prices[field2].trim();
|
|
26326
27424
|
if (text === "") {
|
|
26327
|
-
if (
|
|
26328
|
-
return { error: { kind: "priceRequired", field } };
|
|
27425
|
+
if (field2 === "input" || field2 === "output")
|
|
27426
|
+
return { error: { kind: "priceRequired", field: field2 } };
|
|
26329
27427
|
continue;
|
|
26330
27428
|
}
|
|
26331
27429
|
const value = Number(text);
|
|
26332
27430
|
if (!DECIMAL.test(text) || !Number.isFinite(value)) {
|
|
26333
|
-
return { error: { kind: "priceInvalid", field } };
|
|
27431
|
+
return { error: { kind: "priceInvalid", field: field2 } };
|
|
26334
27432
|
}
|
|
26335
|
-
price[
|
|
27433
|
+
price[field2] = value;
|
|
26336
27434
|
}
|
|
26337
27435
|
return {
|
|
26338
27436
|
change: {
|
|
@@ -26352,7 +27450,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
26352
27450
|
}
|
|
26353
27451
|
function formatPrice(messages, price) {
|
|
26354
27452
|
return MODEL_PRICE_FIELDS.map(
|
|
26355
|
-
(
|
|
27453
|
+
(field2) => `${messages.fields[field2]} ${price[field2] ?? messages.unset}`
|
|
26356
27454
|
).join(" \xB7 ");
|
|
26357
27455
|
}
|
|
26358
27456
|
function draftErrorText(messages, error51) {
|
|
@@ -26420,18 +27518,18 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
26420
27518
|
function renderEditor(modelId, view, isCurrent) {
|
|
26421
27519
|
const existing = view.entries.find((entry) => entry.key === modelId);
|
|
26422
27520
|
const draft = modelPriceDraft(modelId, existing?.price ?? null);
|
|
26423
|
-
const
|
|
27521
|
+
const field2 = (label, value, placeholder = "") => h(document2, "input", {
|
|
26424
27522
|
type: "text",
|
|
26425
27523
|
className: "console-input",
|
|
26426
27524
|
value,
|
|
26427
27525
|
placeholder,
|
|
26428
27526
|
"aria-label": label
|
|
26429
27527
|
});
|
|
26430
|
-
const model2 =
|
|
27528
|
+
const model2 = field2(messages.model, modelId);
|
|
26431
27529
|
model2.readOnly = true;
|
|
26432
27530
|
const prices = Object.fromEntries(
|
|
26433
27531
|
MODEL_PRICE_FIELDS.map((name) => {
|
|
26434
|
-
const input =
|
|
27532
|
+
const input = field2(
|
|
26435
27533
|
messages.fields[name],
|
|
26436
27534
|
draft.prices[name],
|
|
26437
27535
|
name === "input" || name === "output" ? messages.required : messages.notSet
|
|
@@ -27243,8 +28341,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27243
28341
|
for (const cell of options.cells) {
|
|
27244
28342
|
const key = options.singleDay ? cell.hour : cell.weekday * 24 + cell.hour;
|
|
27245
28343
|
const totals2 = byHour.get(key) ?? emptyTotals();
|
|
27246
|
-
for (const
|
|
27247
|
-
totals2[
|
|
28344
|
+
for (const field2 of Object.keys(totals2))
|
|
28345
|
+
totals2[field2] += cell.totals[field2];
|
|
27248
28346
|
byHour.set(key, totals2);
|
|
27249
28347
|
}
|
|
27250
28348
|
const max = Math.max(0, ...[...byHour.values()].map((totals2) => measured(totals2, measure)));
|
|
@@ -27350,6 +28448,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27350
28448
|
const range = text("range");
|
|
27351
28449
|
const measure = text("measure");
|
|
27352
28450
|
const granularity = text("granularity");
|
|
28451
|
+
const hostId2 = text("hostId");
|
|
27353
28452
|
const harness2 = text("harness");
|
|
27354
28453
|
const model2 = text("model");
|
|
27355
28454
|
const project3 = text("project");
|
|
@@ -27358,6 +28457,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27358
28457
|
...range && USAGE_STATISTICS_RANGES.includes(range) ? { range } : {},
|
|
27359
28458
|
...measure && MEASURES.includes(measure) ? { measure } : {},
|
|
27360
28459
|
...granularity === "day" || granularity === "week" || granularity === "month" ? { granularity } : {},
|
|
28460
|
+
...hostId2 !== void 0 && hostId2.length > 0 ? { hostId: hostId2 } : {},
|
|
27361
28461
|
...harness2 !== void 0 ? { harness: harness2 } : {},
|
|
27362
28462
|
...model2 !== void 0 ? { model: model2 } : {},
|
|
27363
28463
|
...project3 !== void 0 ? { project: project3 } : {},
|
|
@@ -27396,7 +28496,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27396
28496
|
day.setDate(day.getDate() - (day.getDay() + 6) % 7);
|
|
27397
28497
|
return isoDate(day);
|
|
27398
28498
|
}
|
|
27399
|
-
function createUsageStatisticsPage(consoleMessages2, request, pageLocale) {
|
|
28499
|
+
function createUsageStatisticsPage(consoleMessages2, request, pageLocale, usageHosts) {
|
|
27400
28500
|
const messages = consoleMessages2.usageStatistics;
|
|
27401
28501
|
return Object.freeze({
|
|
27402
28502
|
id: "usage-statistics",
|
|
@@ -27405,10 +28505,12 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27405
28505
|
mount(context) {
|
|
27406
28506
|
const document2 = context.content.ownerDocument;
|
|
27407
28507
|
const locale = pageLocale ?? (document2.documentElement.lang || "en");
|
|
28508
|
+
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
27408
28509
|
const count3 = (value) => count2(value, locale);
|
|
27409
28510
|
const tokenCount2 = (totals2, value) => tokenCount(totals2, value, locale);
|
|
27410
28511
|
const saved = readView();
|
|
27411
28512
|
const view = {
|
|
28513
|
+
hostId: saved.hostId ?? LOCAL_USAGE_HOST_ID,
|
|
27412
28514
|
range: saved.range ?? "30d",
|
|
27413
28515
|
measure: saved.measure ?? "cost",
|
|
27414
28516
|
granularity: saved.granularity ?? null,
|
|
@@ -27439,7 +28541,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27439
28541
|
let projectLabel = /* @__PURE__ */ new Map();
|
|
27440
28542
|
const projectName = (key) => key === UNKNOWN ? messages.unknownProject : projectLabel.get(key) ?? baseName(key);
|
|
27441
28543
|
const measureLabel = (measure) => measure === "cost" ? messages.cost : messages.tokens;
|
|
27442
|
-
const dateFormat = (options) => new Intl.DateTimeFormat(locale, options);
|
|
28544
|
+
const dateFormat = (options) => new Intl.DateTimeFormat(locale, { ...options, timeZone });
|
|
27443
28545
|
const shortDate = dateFormat({ month: "short", day: "numeric" });
|
|
27444
28546
|
const longDate = dateFormat({
|
|
27445
28547
|
year: "numeric",
|
|
@@ -27458,10 +28560,51 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27458
28560
|
const prices = createModelPricesDialog(
|
|
27459
28561
|
document2,
|
|
27460
28562
|
consoleMessages2,
|
|
27461
|
-
request,
|
|
28563
|
+
(method, params2) => request(method, params2, view.hostId),
|
|
27462
28564
|
context.signal,
|
|
27463
28565
|
load
|
|
27464
28566
|
);
|
|
28567
|
+
let offeredHosts = usageHosts ? [] : void 0;
|
|
28568
|
+
const hostCombo = new ComboBox(document2, {
|
|
28569
|
+
label: messages.host,
|
|
28570
|
+
searchLabel: messages.search,
|
|
28571
|
+
emptyLabel: messages.noMatches,
|
|
28572
|
+
signal: context.signal,
|
|
28573
|
+
searchable: false,
|
|
28574
|
+
display: (option) => `${messages.host} \xB7 ${option.label}`,
|
|
28575
|
+
onChange: (key) => {
|
|
28576
|
+
if (key === view.hostId) return;
|
|
28577
|
+
view.hostId = key;
|
|
28578
|
+
view.harness = "";
|
|
28579
|
+
view.model = "";
|
|
28580
|
+
view.project = "";
|
|
28581
|
+
date5 = null;
|
|
28582
|
+
unpricedOnly = false;
|
|
28583
|
+
result = null;
|
|
28584
|
+
error51 = null;
|
|
28585
|
+
loadedAt = 0;
|
|
28586
|
+
names.clear();
|
|
28587
|
+
save();
|
|
28588
|
+
hostOptions();
|
|
28589
|
+
render();
|
|
28590
|
+
void refreshHarnessNames();
|
|
28591
|
+
load();
|
|
28592
|
+
}
|
|
28593
|
+
});
|
|
28594
|
+
const hostOptions = () => {
|
|
28595
|
+
const options = usageHostOptions(offeredHosts, messages.localHost, view.hostId);
|
|
28596
|
+
hostCombo.element.hidden = options.length < 2;
|
|
28597
|
+
hostCombo.update(options, view.hostId === LOCAL_USAGE_HOST_ID ? "" : view.hostId);
|
|
28598
|
+
};
|
|
28599
|
+
const offerHosts = () => {
|
|
28600
|
+
if (!usageHosts) return;
|
|
28601
|
+
void usageHosts().then((hosts) => {
|
|
28602
|
+
if (context.signal.aborted) return;
|
|
28603
|
+
offeredHosts = hosts;
|
|
28604
|
+
hostOptions();
|
|
28605
|
+
}).catch(() => void 0);
|
|
28606
|
+
};
|
|
28607
|
+
hostOptions();
|
|
27465
28608
|
const updated = h(document2, "span", { className: "console-muted console-usage-updated" });
|
|
27466
28609
|
const refresh = h(
|
|
27467
28610
|
document2,
|
|
@@ -27474,7 +28617,10 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27474
28617
|
},
|
|
27475
28618
|
createRendererSettingsIcon("refresh", 16)
|
|
27476
28619
|
);
|
|
27477
|
-
refresh.addEventListener("click", () =>
|
|
28620
|
+
refresh.addEventListener("click", () => {
|
|
28621
|
+
offerHosts();
|
|
28622
|
+
load();
|
|
28623
|
+
});
|
|
27478
28624
|
const auto = new ComboBox(document2, {
|
|
27479
28625
|
label: messages.autoRefresh,
|
|
27480
28626
|
searchLabel: messages.search,
|
|
@@ -27513,6 +28659,7 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27513
28659
|
document2,
|
|
27514
28660
|
"div",
|
|
27515
28661
|
{ className: "console-usage-toolbar" },
|
|
28662
|
+
hostCombo.element,
|
|
27516
28663
|
updated,
|
|
27517
28664
|
refresh,
|
|
27518
28665
|
auto.element,
|
|
@@ -27558,8 +28705,8 @@ ${text.includes("## My request:") ? "" : "\n## My request:\n"}`,
|
|
|
27558
28705
|
save();
|
|
27559
28706
|
load();
|
|
27560
28707
|
}
|
|
27561
|
-
function toggleFilter(
|
|
27562
|
-
view[
|
|
28708
|
+
function toggleFilter(field2, key) {
|
|
28709
|
+
view[field2] = view[field2] === key ? "" : key;
|
|
27563
28710
|
changed();
|
|
27564
28711
|
}
|
|
27565
28712
|
function selectDate(next) {
|
|
@@ -27975,8 +29122,8 @@ ${messages.creditsCoverage}: ${value.reportedRequests} / ${row.requests}` : void
|
|
|
27975
29122
|
}
|
|
27976
29123
|
];
|
|
27977
29124
|
}
|
|
27978
|
-
function rowFilter(
|
|
27979
|
-
const selected = view[
|
|
29125
|
+
function rowFilter(field2, key, label, detail) {
|
|
29126
|
+
const selected = view[field2] === key;
|
|
27980
29127
|
const button2 = focusKey(
|
|
27981
29128
|
h(
|
|
27982
29129
|
document2,
|
|
@@ -27990,9 +29137,9 @@ ${detail}` : ""}`
|
|
|
27990
29137
|
},
|
|
27991
29138
|
label
|
|
27992
29139
|
),
|
|
27993
|
-
`${
|
|
29140
|
+
`${field2}:row:${key}`
|
|
27994
29141
|
);
|
|
27995
|
-
button2.addEventListener("click", () => toggleFilter(
|
|
29142
|
+
button2.addEventListener("click", () => toggleFilter(field2, key));
|
|
27996
29143
|
return button2;
|
|
27997
29144
|
}
|
|
27998
29145
|
function panel(title, content, extra = null, wide = false) {
|
|
@@ -28151,7 +29298,6 @@ ${detail}` : ""}`
|
|
|
28151
29298
|
}
|
|
28152
29299
|
function hourlyPanel(data) {
|
|
28153
29300
|
const singleDay = data.filters.date !== null || data.range === "today";
|
|
28154
|
-
const zone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
28155
29301
|
return panel(
|
|
28156
29302
|
singleDay ? messages.hourlyDay : messages.hourly,
|
|
28157
29303
|
hourlyChart(document2, {
|
|
@@ -28166,7 +29312,7 @@ ${detail}` : ""}`
|
|
|
28166
29312
|
weekStartsOnMonday: !locale.startsWith("en"),
|
|
28167
29313
|
labels: { cost: messages.cost, tokens: messages.tokens }
|
|
28168
29314
|
}),
|
|
28169
|
-
h(document2, "span", { className: "console-muted console-usage-zone" },
|
|
29315
|
+
h(document2, "span", { className: "console-muted console-usage-zone" }, timeZone)
|
|
28170
29316
|
);
|
|
28171
29317
|
}
|
|
28172
29318
|
function sessionsPanel(title, rows, tableKey) {
|
|
@@ -28313,6 +29459,7 @@ ${detail}` : ""}`
|
|
|
28313
29459
|
const project3 = filterValue(view.project);
|
|
28314
29460
|
return {
|
|
28315
29461
|
range: view.range,
|
|
29462
|
+
timeZone,
|
|
28316
29463
|
...view.harness ? { harness: view.harness } : {},
|
|
28317
29464
|
...model2 !== void 0 ? { model: model2 } : {},
|
|
28318
29465
|
...project3 !== void 0 ? { project: project3 } : {},
|
|
@@ -28325,10 +29472,26 @@ ${detail}` : ""}`
|
|
|
28325
29472
|
if (result && !result.reading.complete) poll = window.setTimeout(load, POLL_MS);
|
|
28326
29473
|
else if (view.autoRefreshMs > 0) poll = window.setTimeout(load, view.autoRefreshMs);
|
|
28327
29474
|
}
|
|
29475
|
+
const harnessNamesRead = createLatestKeyGuard();
|
|
29476
|
+
async function refreshHarnessNames() {
|
|
29477
|
+
const hostId2 = view.hostId;
|
|
29478
|
+
const isCurrent = harnessNamesRead.begin(hostId2);
|
|
29479
|
+
names.clear();
|
|
29480
|
+
try {
|
|
29481
|
+
const value = await request(HARNESS_PLUGIN_LIST_METHOD2, {}, hostId2);
|
|
29482
|
+
if (!isCurrent()) return;
|
|
29483
|
+
for (const plugin of harnessPluginListResultSchema.parse(value).plugins) {
|
|
29484
|
+
names.set(plugin.id, plugin.name);
|
|
29485
|
+
}
|
|
29486
|
+
} catch {
|
|
29487
|
+
if (!isCurrent()) return;
|
|
29488
|
+
}
|
|
29489
|
+
if (!context.signal.aborted) render();
|
|
29490
|
+
}
|
|
28328
29491
|
function load() {
|
|
28329
29492
|
window.clearTimeout(poll);
|
|
28330
29493
|
const requested = params();
|
|
28331
|
-
void context.runLatest(() => request(USAGE_STATISTICS_METHOD, requested), {
|
|
29494
|
+
void context.runLatest(() => request(USAGE_STATISTICS_METHOD, requested, view.hostId), {
|
|
28332
29495
|
success(value) {
|
|
28333
29496
|
const parsed = usageStatisticsResultSchema.safeParse(value);
|
|
28334
29497
|
if (parsed.success) {
|
|
@@ -28353,12 +29516,8 @@ ${detail}` : ""}`
|
|
|
28353
29516
|
}
|
|
28354
29517
|
context.content.replaceChildren(header, prices.element, filters, notices, body);
|
|
28355
29518
|
render();
|
|
28356
|
-
|
|
28357
|
-
|
|
28358
|
-
names.set(plugin.id, plugin.name);
|
|
28359
|
-
}
|
|
28360
|
-
if (!context.signal.aborted) render();
|
|
28361
|
-
}).catch(() => void 0);
|
|
29519
|
+
offerHosts();
|
|
29520
|
+
void refreshHarnessNames();
|
|
28362
29521
|
load();
|
|
28363
29522
|
return () => {
|
|
28364
29523
|
window.clearTimeout(poll);
|
|
@@ -28451,6 +29610,8 @@ ${detail}` : ""}`
|
|
|
28451
29610
|
harness: "Harness",
|
|
28452
29611
|
model: "Model",
|
|
28453
29612
|
project: "Project",
|
|
29613
|
+
host: "Machine",
|
|
29614
|
+
localHost: "This machine",
|
|
28454
29615
|
filterModel: "Filter by model",
|
|
28455
29616
|
filterProject: "Filter by project",
|
|
28456
29617
|
unknownModel: "Unknown model",
|
|
@@ -28634,6 +29795,8 @@ ${detail}` : ""}`
|
|
|
28634
29795
|
harness: "Harness",
|
|
28635
29796
|
model: "\u6A21\u578B",
|
|
28636
29797
|
project: "\u9879\u76EE",
|
|
29798
|
+
host: "\u673A\u5668",
|
|
29799
|
+
localHost: "\u672C\u673A",
|
|
28637
29800
|
filterModel: "\u6309\u6A21\u578B\u7B5B\u9009",
|
|
28638
29801
|
filterProject: "\u6309\u9879\u76EE\u7B5B\u9009",
|
|
28639
29802
|
unknownModel: "\u672A\u77E5\u6A21\u578B",
|
|
@@ -29175,8 +30338,8 @@ ${detail}` : ""}`
|
|
|
29175
30338
|
return input;
|
|
29176
30339
|
}
|
|
29177
30340
|
function createNumberField(document2, input) {
|
|
29178
|
-
const
|
|
29179
|
-
|
|
30341
|
+
const field2 = document2.createElement("div");
|
|
30342
|
+
field2.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";
|
|
29180
30343
|
const control = document2.createElement("input");
|
|
29181
30344
|
control.type = "number";
|
|
29182
30345
|
control.id = input.id;
|
|
@@ -29189,8 +30352,8 @@ ${detail}` : ""}`
|
|
|
29189
30352
|
unit.className = "text-xs text-settings-muted";
|
|
29190
30353
|
unit.setAttribute("aria-hidden", "true");
|
|
29191
30354
|
unit.textContent = input.unit;
|
|
29192
|
-
|
|
29193
|
-
return { field, control };
|
|
30355
|
+
field2.append(control, unit);
|
|
30356
|
+
return { field: field2, control };
|
|
29194
30357
|
}
|
|
29195
30358
|
|
|
29196
30359
|
// src/settings/remote-connections-dialogs.ts
|
|
@@ -29274,7 +30437,7 @@ ${detail}` : ""}`
|
|
|
29274
30437
|
);
|
|
29275
30438
|
if (!dialog) return;
|
|
29276
30439
|
const document2 = options.container.ownerDocument;
|
|
29277
|
-
const
|
|
30440
|
+
const field2 = (label, value, placeholder = "", hint = "") => {
|
|
29278
30441
|
const wrapper = remoteElement(document2, "div", "settings-credential-dialog__field");
|
|
29279
30442
|
const input = remoteElement(document2, "input");
|
|
29280
30443
|
input.id = preferenceId("remote-field");
|
|
@@ -29294,13 +30457,13 @@ ${detail}` : ""}`
|
|
|
29294
30457
|
dialog.body.append(wrapper);
|
|
29295
30458
|
return input;
|
|
29296
30459
|
};
|
|
29297
|
-
const name =
|
|
30460
|
+
const name = field2(t("\u540D\u79F0", "Name"), previous?.displayName ?? "");
|
|
29298
30461
|
name.required = true;
|
|
29299
30462
|
const addressHint = t(
|
|
29300
30463
|
"user@hostname\uFF0C\u6216 ~/.ssh/config \u4E2D\u7684\u4E3B\u673A\u522B\u540D",
|
|
29301
30464
|
"user@hostname, or a host alias from ~/.ssh/config"
|
|
29302
30465
|
);
|
|
29303
|
-
const hostname3 =
|
|
30466
|
+
const hostname3 = field2(
|
|
29304
30467
|
t("SSH \u5730\u5740", "SSH address"),
|
|
29305
30468
|
previous?.sshHost ?? "",
|
|
29306
30469
|
"user@hostname",
|
|
@@ -29309,7 +30472,7 @@ ${detail}` : ""}`
|
|
|
29309
30472
|
hostname3.required = true;
|
|
29310
30473
|
hostname3.pattern = "[^\\s\\-]\\S*";
|
|
29311
30474
|
hostname3.title = addressHint;
|
|
29312
|
-
const port =
|
|
30475
|
+
const port = field2(
|
|
29313
30476
|
t("\u7AEF\u53E3\uFF08\u53EF\u9009\uFF09", "Port (optional)"),
|
|
29314
30477
|
previous?.sshPort?.toString() ?? "",
|
|
29315
30478
|
"22"
|
|
@@ -29318,7 +30481,7 @@ ${detail}` : ""}`
|
|
|
29318
30481
|
port.min = "1";
|
|
29319
30482
|
port.max = "65535";
|
|
29320
30483
|
port.step = "1";
|
|
29321
|
-
const identity =
|
|
30484
|
+
const identity = field2(
|
|
29322
30485
|
t("\u79C1\u94A5\u8DEF\u5F84\uFF08\u53EF\u9009\uFF09", "Identity file (optional)"),
|
|
29323
30486
|
previous?.identity ?? "",
|
|
29324
30487
|
"~/.ssh/id_ed25519"
|
|
@@ -30235,6 +31398,50 @@ ${detail}` : ""}`
|
|
|
30235
31398
|
};
|
|
30236
31399
|
setRefreshLabel(false);
|
|
30237
31400
|
header.append(heading, refresh);
|
|
31401
|
+
let selectedHostId;
|
|
31402
|
+
let availableHostIds = [];
|
|
31403
|
+
let displayedHostId = "";
|
|
31404
|
+
let hostsLocked = false;
|
|
31405
|
+
const hostButtons = [];
|
|
31406
|
+
const hostLabel = document2.createElement("div");
|
|
31407
|
+
hostLabel.className = "settings-session-import-host";
|
|
31408
|
+
const hostCaption = document2.createElement("span");
|
|
31409
|
+
hostCaption.textContent = "Host";
|
|
31410
|
+
const hostOptions = document2.createElement("div");
|
|
31411
|
+
hostOptions.className = "settings-connection-host-tabs";
|
|
31412
|
+
hostOptions.setAttribute("role", "group");
|
|
31413
|
+
hostOptions.setAttribute("aria-label", "Host");
|
|
31414
|
+
hostLabel.append(hostCaption, hostOptions);
|
|
31415
|
+
const lockHosts = (locked) => {
|
|
31416
|
+
hostsLocked = locked;
|
|
31417
|
+
for (const button2 of hostButtons) button2.disabled = locked;
|
|
31418
|
+
};
|
|
31419
|
+
const renderHosts = (client) => {
|
|
31420
|
+
const current = selectedHostId ?? (client ? client.hostId ?? "local" : "");
|
|
31421
|
+
availableHostIds = [
|
|
31422
|
+
.../* @__PURE__ */ new Set([
|
|
31423
|
+
...getDiagnostics()?.snapshot().hosts.map(({ hostId: hostId2 }) => hostId2) ?? [],
|
|
31424
|
+
...current ? [current] : []
|
|
31425
|
+
])
|
|
31426
|
+
];
|
|
31427
|
+
displayedHostId = current;
|
|
31428
|
+
const scrollLeft = hostOptions.scrollLeft;
|
|
31429
|
+
hostOptions.replaceChildren();
|
|
31430
|
+
hostButtons.length = 0;
|
|
31431
|
+
for (const hostId2 of availableHostIds) {
|
|
31432
|
+
const button2 = document2.createElement("button");
|
|
31433
|
+
button2.type = "button";
|
|
31434
|
+
button2.className = "settings-connection-host-tab";
|
|
31435
|
+
button2.dataset.sessionImportHost = hostId2;
|
|
31436
|
+
button2.textContent = connectionHostName(hostId2, messages);
|
|
31437
|
+
button2.setAttribute("aria-pressed", String(hostId2 === current));
|
|
31438
|
+
button2.disabled = hostsLocked;
|
|
31439
|
+
button2.addEventListener("click", () => selectHost(hostId2));
|
|
31440
|
+
hostButtons.push(button2);
|
|
31441
|
+
hostOptions.append(button2);
|
|
31442
|
+
}
|
|
31443
|
+
hostOptions.scrollLeft = scrollLeft;
|
|
31444
|
+
};
|
|
30238
31445
|
const harness2 = document2.createElement("div");
|
|
30239
31446
|
harness2.className = "settings-session-import-harness";
|
|
30240
31447
|
const harnessLabel = document2.createElement("span");
|
|
@@ -30295,6 +31502,7 @@ ${detail}` : ""}`
|
|
|
30295
31502
|
const listControls = createSessionImportListControls(document2, messages, () => load());
|
|
30296
31503
|
context.content.append(
|
|
30297
31504
|
header,
|
|
31505
|
+
hostLabel,
|
|
30298
31506
|
harness2,
|
|
30299
31507
|
description,
|
|
30300
31508
|
availabilityNote,
|
|
@@ -30304,9 +31512,11 @@ ${detail}` : ""}`
|
|
|
30304
31512
|
listControls.pagination
|
|
30305
31513
|
);
|
|
30306
31514
|
let candidates = [];
|
|
31515
|
+
let loadedClient = null;
|
|
30307
31516
|
let importingId = null;
|
|
30308
31517
|
let actions = [];
|
|
30309
31518
|
const updateImportActions = () => {
|
|
31519
|
+
lockHosts(importingId !== null);
|
|
30310
31520
|
listControls.setBusy(importingId !== null, importingId !== null);
|
|
30311
31521
|
for (const button2 of sourceButtons) button2.disabled = importingId !== null;
|
|
30312
31522
|
for (const { button: button2, candidate } of actions) {
|
|
@@ -30327,7 +31537,10 @@ ${detail}` : ""}`
|
|
|
30327
31537
|
listControls.setTotal(0);
|
|
30328
31538
|
candidates = [];
|
|
30329
31539
|
actions = [];
|
|
30330
|
-
const status = createStatus(
|
|
31540
|
+
const status = createStatus(
|
|
31541
|
+
document2,
|
|
31542
|
+
!displayedHostId && availableHostIds.length > 1 ? messages.sessionImportSelectHost : messages.sessionImportUnavailable
|
|
31543
|
+
);
|
|
30331
31544
|
content.replaceChildren(status);
|
|
30332
31545
|
if (focus) {
|
|
30333
31546
|
status.tabIndex = -1;
|
|
@@ -30352,7 +31565,7 @@ ${detail}` : ""}`
|
|
|
30352
31565
|
status.focus();
|
|
30353
31566
|
}
|
|
30354
31567
|
};
|
|
30355
|
-
const renderOpenRecovery = (candidate, threadId) => {
|
|
31568
|
+
const renderOpenRecovery = (candidate, threadId, hostId2) => {
|
|
30356
31569
|
if (!openImportedThread) return;
|
|
30357
31570
|
actions = [];
|
|
30358
31571
|
refresh.disabled = false;
|
|
@@ -30405,6 +31618,7 @@ ${detail}` : ""}`
|
|
|
30405
31618
|
retry.className = "settings-command-button";
|
|
30406
31619
|
retry.dataset.sessionImportAction = "retry-open";
|
|
30407
31620
|
const setRetrying = (pending) => {
|
|
31621
|
+
lockHosts(pending);
|
|
30408
31622
|
listControls.setBusy(pending, pending);
|
|
30409
31623
|
for (const button2 of sourceButtons) button2.disabled = pending;
|
|
30410
31624
|
retry.disabled = pending;
|
|
@@ -30419,12 +31633,12 @@ ${detail}` : ""}`
|
|
|
30419
31633
|
retry.addEventListener("click", () => {
|
|
30420
31634
|
if (retry.disabled) return;
|
|
30421
31635
|
setRetrying(true);
|
|
30422
|
-
void context.runLatest((signal) => openImportedThread(threadId, signal), {
|
|
31636
|
+
void context.runLatest((signal) => openImportedThread(threadId, signal, hostId2), {
|
|
30423
31637
|
success() {
|
|
30424
31638
|
setRetrying(false);
|
|
30425
31639
|
},
|
|
30426
31640
|
failure() {
|
|
30427
|
-
renderOpenRecovery(candidate, threadId);
|
|
31641
|
+
renderOpenRecovery(candidate, threadId, hostId2);
|
|
30428
31642
|
}
|
|
30429
31643
|
});
|
|
30430
31644
|
});
|
|
@@ -30501,7 +31715,7 @@ ${detail}` : ""}`
|
|
|
30501
31715
|
if (candidate.running === true || importingId !== null || selectedHarness === null)
|
|
30502
31716
|
return;
|
|
30503
31717
|
const harnessId = selectedHarness;
|
|
30504
|
-
const client =
|
|
31718
|
+
const client = loadedClient;
|
|
30505
31719
|
if (!client) {
|
|
30506
31720
|
renderUnavailable(true);
|
|
30507
31721
|
return;
|
|
@@ -30519,7 +31733,7 @@ ${detail}` : ""}`
|
|
|
30519
31733
|
});
|
|
30520
31734
|
committedThreadId = result.threadId;
|
|
30521
31735
|
if (!signal.aborted && openImportedThread)
|
|
30522
|
-
await openImportedThread(result.threadId, signal);
|
|
31736
|
+
await openImportedThread(result.threadId, signal, client.hostId);
|
|
30523
31737
|
},
|
|
30524
31738
|
{
|
|
30525
31739
|
success() {
|
|
@@ -30537,7 +31751,7 @@ ${detail}` : ""}`
|
|
|
30537
31751
|
updateImportActions();
|
|
30538
31752
|
refresh.disabled = false;
|
|
30539
31753
|
if (committedThreadId) {
|
|
30540
|
-
renderOpenRecovery(candidate, committedThreadId);
|
|
31754
|
+
renderOpenRecovery(candidate, committedThreadId, client.hostId);
|
|
30541
31755
|
} else {
|
|
30542
31756
|
renderFailure(error51, "import");
|
|
30543
31757
|
}
|
|
@@ -30555,23 +31769,22 @@ ${detail}` : ""}`
|
|
|
30555
31769
|
};
|
|
30556
31770
|
const load = () => {
|
|
30557
31771
|
if (importingId !== null || context.signal.aborted) return;
|
|
30558
|
-
|
|
30559
|
-
|
|
30560
|
-
|
|
30561
|
-
|
|
30562
|
-
|
|
30563
|
-
|
|
30564
|
-
|
|
30565
|
-
|
|
30566
|
-
|
|
30567
|
-
setRefreshLabel(true);
|
|
30568
|
-
content.replaceChildren(createStatus(document2, messages.sessionImportRefreshing));
|
|
31772
|
+
loadedClient = null;
|
|
31773
|
+
const client = getClient(selectedHostId);
|
|
31774
|
+
renderHosts(client);
|
|
31775
|
+
listControls.setBusy(client !== null);
|
|
31776
|
+
refresh.disabled = client !== null;
|
|
31777
|
+
setRefreshLabel(client !== null);
|
|
31778
|
+
if (client)
|
|
31779
|
+
content.replaceChildren(createStatus(document2, messages.sessionImportRefreshing));
|
|
31780
|
+
else renderUnavailable();
|
|
30569
31781
|
const requestedHarness = selectedHarness;
|
|
30570
31782
|
const pageParams = listControls.params();
|
|
30571
31783
|
void context.runLatest(
|
|
30572
31784
|
async (signal) => {
|
|
31785
|
+
if (!client) throw new RendererSessionImportUnavailableError();
|
|
30573
31786
|
const missing = new Set(
|
|
30574
|
-
getDiagnostics()?.snapshot().hosts.find(({ hostId: hostId2 }) => hostId2 === "local")?.agents.filter(({ availability }) => availability === "notInstalled").map(({ agent }) => agent)
|
|
31787
|
+
getDiagnostics()?.snapshot().hosts.find(({ hostId: hostId2 }) => hostId2 === (client.hostId ?? "local"))?.agents.filter(({ availability }) => availability === "notInstalled").map(({ agent }) => agent)
|
|
30575
31788
|
);
|
|
30576
31789
|
const harnesses = (await client.listSessionImportSources()).harnesses.filter(
|
|
30577
31790
|
({ harnessId }) => !missing.has(harnessId)
|
|
@@ -30589,6 +31802,7 @@ ${detail}` : ""}`
|
|
|
30589
31802
|
},
|
|
30590
31803
|
{
|
|
30591
31804
|
success(result) {
|
|
31805
|
+
loadedClient = client;
|
|
30592
31806
|
listControls.setBusy(false);
|
|
30593
31807
|
if (listControls.setTotal(result.total)) {
|
|
30594
31808
|
load();
|
|
@@ -30601,6 +31815,7 @@ ${detail}` : ""}`
|
|
|
30601
31815
|
else renderCandidates();
|
|
30602
31816
|
},
|
|
30603
31817
|
failure(error51) {
|
|
31818
|
+
loadedClient = null;
|
|
30604
31819
|
listControls.setBusy(false);
|
|
30605
31820
|
candidates = [];
|
|
30606
31821
|
refresh.disabled = false;
|
|
@@ -30610,6 +31825,19 @@ ${detail}` : ""}`
|
|
|
30610
31825
|
}
|
|
30611
31826
|
);
|
|
30612
31827
|
};
|
|
31828
|
+
const selectHost = (hostId2) => {
|
|
31829
|
+
if (hostsLocked || !availableHostIds.includes(hostId2) || hostId2 === selectedHostId) return;
|
|
31830
|
+
selectedHostId = hostId2;
|
|
31831
|
+
selectedHarness = null;
|
|
31832
|
+
sources = [];
|
|
31833
|
+
candidates = [];
|
|
31834
|
+
actions = [];
|
|
31835
|
+
importStatus.replaceChildren();
|
|
31836
|
+
listControls.reset();
|
|
31837
|
+
renderHarnessOptions();
|
|
31838
|
+
load();
|
|
31839
|
+
hostButtons.find((button2) => button2.dataset.sessionImportHost === hostId2)?.focus();
|
|
31840
|
+
};
|
|
30613
31841
|
refresh.addEventListener("click", load);
|
|
30614
31842
|
load();
|
|
30615
31843
|
return void 0;
|
|
@@ -30750,14 +31978,14 @@ ${detail}` : ""}`
|
|
|
30750
31978
|
description: messages.idleReleaseTimeoutDescription,
|
|
30751
31979
|
controlId: minutesId
|
|
30752
31980
|
});
|
|
30753
|
-
const { field, control: minutes } = createNumberField(document2, {
|
|
31981
|
+
const { field: field2, control: minutes } = createNumberField(document2, {
|
|
30754
31982
|
id: minutesId,
|
|
30755
31983
|
describedBy: timeout.description.id,
|
|
30756
31984
|
unit: messages.idleReleaseMinutes,
|
|
30757
31985
|
min: IDLE_RELEASE_TIMEOUT_MINUTES_MIN,
|
|
30758
31986
|
max: IDLE_RELEASE_TIMEOUT_MINUTES_MAX
|
|
30759
31987
|
});
|
|
30760
|
-
timeout.item.append(
|
|
31988
|
+
timeout.item.append(field2);
|
|
30761
31989
|
timeout.item.id = preferenceId("idle-release-timeout");
|
|
30762
31990
|
enabled.setAttribute("aria-controls", timeout.item.id);
|
|
30763
31991
|
card.append(toggle.item, timeout.item);
|
|
@@ -30778,7 +32006,7 @@ ${detail}` : ""}`
|
|
|
30778
32006
|
statusText.textContent = value === "applied" ? "" : statusMessages[value];
|
|
30779
32007
|
};
|
|
30780
32008
|
const setInvalid = (invalid) => {
|
|
30781
|
-
|
|
32009
|
+
field2.dataset.invalid = String(invalid);
|
|
30782
32010
|
timeout.description.dataset.invalid = String(invalid);
|
|
30783
32011
|
timeout.description.textContent = invalid ? messages.idleReleaseInvalid : messages.idleReleaseTimeoutDescription;
|
|
30784
32012
|
minutes.setAttribute("aria-invalid", String(invalid));
|
|
@@ -31103,7 +32331,7 @@ ${detail}` : ""}`
|
|
|
31103
32331
|
}
|
|
31104
32332
|
function defaultImportName(source, existing) {
|
|
31105
32333
|
const base = source.provider === "openai-codex" ? "codex" : "grok";
|
|
31106
|
-
const used = new Set(existing.map((
|
|
32334
|
+
const used = new Set(existing.map((record6) => record6.name));
|
|
31107
32335
|
const valid = (name) => credentialImportNameSchema.safeParse(name).success;
|
|
31108
32336
|
if (!used.has(base)) return base;
|
|
31109
32337
|
const local = source.label.includes("@") ? source.label.split("@")[0] ?? "" : "";
|
|
@@ -31126,7 +32354,7 @@ ${detail}` : ""}`
|
|
|
31126
32354
|
const shown = (text) => accountDisplayText(text, hideEmails);
|
|
31127
32355
|
const targetButtons = /* @__PURE__ */ new Map();
|
|
31128
32356
|
const importedRecords = () => snapshot.targets.find((target) => target.harnessId === TARGET_HARNESS_ID)?.imports ?? [];
|
|
31129
|
-
const sourceOf = (
|
|
32357
|
+
const sourceOf = (record6) => snapshot.sources.find((source) => source.id === record6.source.id);
|
|
31130
32358
|
const piTarget = () => snapshot.targets.find((candidate) => candidate.harnessId === TARGET_HARNESS_ID);
|
|
31131
32359
|
const compatibleSources = () => {
|
|
31132
32360
|
const target = piTarget();
|
|
@@ -31164,7 +32392,7 @@ ${detail}` : ""}`
|
|
|
31164
32392
|
sectionImport.addEventListener("click", () => {
|
|
31165
32393
|
const sources = compatibleSources();
|
|
31166
32394
|
const free = sources.find(
|
|
31167
|
-
(source2) => !importedRecords().some((
|
|
32395
|
+
(source2) => !importedRecords().some((record6) => record6.source.id === source2.id)
|
|
31168
32396
|
);
|
|
31169
32397
|
const source = free ?? sources[0];
|
|
31170
32398
|
if (source) openDialog("add", { source, choose: true }, SECTION_IMPORT_KEY);
|
|
@@ -31214,30 +32442,30 @@ ${detail}` : ""}`
|
|
|
31214
32442
|
mark.append(createRendererAgentIcon(agent ?? "pi", 26, document2, pluginFor(agent ?? "pi")));
|
|
31215
32443
|
return mark;
|
|
31216
32444
|
};
|
|
31217
|
-
const renderRow = (
|
|
32445
|
+
const renderRow = (record6) => {
|
|
31218
32446
|
const row = document2.createElement("div");
|
|
31219
32447
|
row.className = "settings-pi-accounts__row";
|
|
31220
32448
|
row.tabIndex = -1;
|
|
31221
|
-
row.dataset.importName =
|
|
31222
|
-
row.setAttribute("aria-label", shown(
|
|
31223
|
-
const agent =
|
|
32449
|
+
row.dataset.importName = record6.name;
|
|
32450
|
+
row.setAttribute("aria-label", shown(record6.source.label));
|
|
32451
|
+
const agent = record6.source.harnessId;
|
|
31224
32452
|
const mark = createMark(agent);
|
|
31225
32453
|
const identity = document2.createElement("div");
|
|
31226
32454
|
identity.className = "settings-pi-accounts__identity";
|
|
31227
32455
|
const label = document2.createElement("strong");
|
|
31228
32456
|
label.className = "settings-account-email";
|
|
31229
|
-
label.textContent = shown(
|
|
32457
|
+
label.textContent = shown(record6.source.label);
|
|
31230
32458
|
label.title = label.textContent;
|
|
31231
32459
|
label.translate = false;
|
|
31232
32460
|
const meta3 = document2.createElement("div");
|
|
31233
32461
|
meta3.className = "settings-account-metadata";
|
|
31234
|
-
const source = sourceOf(
|
|
32462
|
+
const source = sourceOf(record6);
|
|
31235
32463
|
const parts = [
|
|
31236
32464
|
metaPart(rendererAgentLabel(agent, pluginFor(agent)), "settings-pi-accounts__agent"),
|
|
31237
|
-
metaPart(`${
|
|
32465
|
+
metaPart(`${record6.name}/\u2026`, void 0, true),
|
|
31238
32466
|
metaPart(messages.copied)
|
|
31239
32467
|
];
|
|
31240
|
-
const time3 = formatImportedAt(
|
|
32468
|
+
const time3 = formatImportedAt(record6.importedAt);
|
|
31241
32469
|
if (time3) parts.push(metaPart(time3));
|
|
31242
32470
|
parts.forEach((part, index) => {
|
|
31243
32471
|
if (index > 0) {
|
|
@@ -31254,23 +32482,23 @@ ${detail}` : ""}`
|
|
|
31254
32482
|
reimport.type = "button";
|
|
31255
32483
|
reimport.className = "settings-account-action";
|
|
31256
32484
|
reimport.textContent = messages.rowReimport;
|
|
31257
|
-
reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(
|
|
32485
|
+
reimport.setAttribute("aria-label", `${messages.reimport}: ${shown(record6.source.label)}`);
|
|
31258
32486
|
reimport.disabled = busy || !source;
|
|
31259
32487
|
reimport.title = messages.reimport;
|
|
31260
32488
|
reimport.addEventListener("click", () => {
|
|
31261
|
-
if (source) openDialog("reimport", { source, record:
|
|
32489
|
+
if (source) openDialog("reimport", { source, record: record6 }, `row:${record6.name}`);
|
|
31262
32490
|
});
|
|
31263
32491
|
const remove = document2.createElement("button");
|
|
31264
32492
|
remove.type = "button";
|
|
31265
32493
|
remove.className = "settings-account-action settings-pi-accounts__remove";
|
|
31266
32494
|
remove.textContent = messages.rowRemove;
|
|
31267
|
-
remove.setAttribute("aria-label", `${messages.remove}: ${shown(
|
|
32495
|
+
remove.setAttribute("aria-label", `${messages.remove}: ${shown(record6.source.label)}`);
|
|
31268
32496
|
remove.disabled = busy;
|
|
31269
|
-
remove.addEventListener("click", () => openDialog("remove", { record:
|
|
32497
|
+
remove.addEventListener("click", () => openDialog("remove", { record: record6 }, `row:${record6.name}`));
|
|
31270
32498
|
if (source) actions.append(reimport);
|
|
31271
32499
|
actions.append(remove);
|
|
31272
32500
|
row.append(mark, identity, actions);
|
|
31273
|
-
rows.set(
|
|
32501
|
+
rows.set(record6.name, row);
|
|
31274
32502
|
return row;
|
|
31275
32503
|
};
|
|
31276
32504
|
const loginTypeLabel = (type) => type === "oauth" ? messages.typeOauth : type === "api_key" ? messages.typeApiKey : messages.typeOther;
|
|
@@ -31423,7 +32651,7 @@ ${detail}` : ""}`
|
|
|
31423
32651
|
const label = document2.createElement("strong");
|
|
31424
32652
|
label.textContent = shown(choice.label);
|
|
31425
32653
|
label.translate = false;
|
|
31426
|
-
const existing = importedRecords().find((
|
|
32654
|
+
const existing = importedRecords().find((record6) => record6.source.id === choice.id);
|
|
31427
32655
|
const agent = choice.harnessId;
|
|
31428
32656
|
const detail = document2.createElement("span");
|
|
31429
32657
|
detail.textContent = [
|
|
@@ -31464,7 +32692,7 @@ ${detail}` : ""}`
|
|
|
31464
32692
|
const name = request.action === "list" ? void 0 : request.name;
|
|
31465
32693
|
state = {
|
|
31466
32694
|
source: state.source,
|
|
31467
|
-
record: importedRecords().find((
|
|
32695
|
+
record: importedRecords().find((record6) => record6.name === name) ?? state.record
|
|
31468
32696
|
};
|
|
31469
32697
|
show(next);
|
|
31470
32698
|
} else {
|
|
@@ -31478,12 +32706,12 @@ ${detail}` : ""}`
|
|
|
31478
32706
|
sourceRadios = [];
|
|
31479
32707
|
body.replaceChildren();
|
|
31480
32708
|
controls.replaceChildren();
|
|
31481
|
-
const { source, record:
|
|
32709
|
+
const { source, record: record6 } = state;
|
|
31482
32710
|
const close = () => modal.close();
|
|
31483
32711
|
if (mode === "add" || mode === "reimport") {
|
|
31484
32712
|
title.textContent = mode === "add" ? messages.add : messages.reimport;
|
|
31485
32713
|
modal.setAttribute("aria-label", title.textContent);
|
|
31486
|
-
const active = source ??
|
|
32714
|
+
const active = source ?? record6?.source;
|
|
31487
32715
|
const choices = mode === "add" && state.choose ? compatibleSources() : [];
|
|
31488
32716
|
if (choices.length > 1) body.append(sourcePicker(choices));
|
|
31489
32717
|
else if (active) body.append(line(messages.source, shown(active.label)));
|
|
@@ -31492,8 +32720,8 @@ ${detail}` : ""}`
|
|
|
31492
32720
|
input.maxLength = 48;
|
|
31493
32721
|
input.autocomplete = "off";
|
|
31494
32722
|
input.spellcheck = false;
|
|
31495
|
-
input.value =
|
|
31496
|
-
input.readOnly = Boolean(
|
|
32723
|
+
input.value = record6?.name ?? (source ? defaultImportName(source, importedRecords()) : "codex");
|
|
32724
|
+
input.readOnly = Boolean(record6);
|
|
31497
32725
|
input.addEventListener("input", () => {
|
|
31498
32726
|
nameEdited = true;
|
|
31499
32727
|
});
|
|
@@ -31527,7 +32755,7 @@ ${detail}` : ""}`
|
|
|
31527
32755
|
{
|
|
31528
32756
|
action: mode === "reimport" ? "reimport" : "import",
|
|
31529
32757
|
sourceId: source2.id,
|
|
31530
|
-
name:
|
|
32758
|
+
name: record6?.name ?? input.value,
|
|
31531
32759
|
confirmed: true
|
|
31532
32760
|
},
|
|
31533
32761
|
"done"
|
|
@@ -31537,16 +32765,16 @@ ${detail}` : ""}`
|
|
|
31537
32765
|
)
|
|
31538
32766
|
);
|
|
31539
32767
|
(mode === "add" ? input : controls.children[0]).focus();
|
|
31540
|
-
} else if (mode === "remove" &&
|
|
32768
|
+
} else if (mode === "remove" && record6) {
|
|
31541
32769
|
title.textContent = messages.remove;
|
|
31542
32770
|
modal.setAttribute("aria-label", title.textContent);
|
|
31543
|
-
body.append(note(messages.removeWarning.replace("{name}",
|
|
32771
|
+
body.append(note(messages.removeWarning.replace("{name}", record6.name)));
|
|
31544
32772
|
const cancel = command(messages.cancel, close);
|
|
31545
32773
|
controls.append(
|
|
31546
32774
|
cancel,
|
|
31547
32775
|
command(
|
|
31548
32776
|
messages.remove,
|
|
31549
|
-
() => submit({ action: "remove", name:
|
|
32777
|
+
() => submit({ action: "remove", name: record6.name, confirmed: true }, null),
|
|
31550
32778
|
"danger"
|
|
31551
32779
|
)
|
|
31552
32780
|
);
|
|
@@ -31554,7 +32782,7 @@ ${detail}` : ""}`
|
|
|
31554
32782
|
} else {
|
|
31555
32783
|
title.textContent = messages.doneTitle;
|
|
31556
32784
|
modal.setAttribute("aria-label", title.textContent);
|
|
31557
|
-
const name =
|
|
32785
|
+
const name = record6?.name;
|
|
31558
32786
|
if (name) body.append(line(messages.entry, `${name}/\u2026`, true));
|
|
31559
32787
|
body.append(note(messages.done));
|
|
31560
32788
|
const done = command(messages.close, close, "primary");
|
|
@@ -31601,21 +32829,21 @@ ${detail}` : ""}`
|
|
|
31601
32829
|
(candidate) => candidate.harnessId === TARGET_HARNESS_ID && source && candidate.providers.includes(source.provider)
|
|
31602
32830
|
);
|
|
31603
32831
|
if (!source || !target) return null;
|
|
31604
|
-
const
|
|
32832
|
+
const record6 = target.imports.find((candidate) => candidate.source.id === source.id);
|
|
31605
32833
|
const key = `${harnessId}:${accountLabel}:import`;
|
|
31606
32834
|
const button2 = document2.createElement("button");
|
|
31607
32835
|
button2.type = "button";
|
|
31608
32836
|
button2.className = "settings-account-pi-import";
|
|
31609
32837
|
button2.dataset.accountFocus = key;
|
|
31610
32838
|
button2.disabled = busy;
|
|
31611
|
-
const hint =
|
|
32839
|
+
const hint = record6 ? messages.importedHint.replace("{name}", record6.name) : messages.add;
|
|
31612
32840
|
button2.title = hint;
|
|
31613
32841
|
button2.setAttribute("aria-label", hint);
|
|
31614
32842
|
button2.append(createRendererAgentIcon("pi", 12, document2, pluginFor("pi")));
|
|
31615
|
-
if (
|
|
32843
|
+
if (record6) {
|
|
31616
32844
|
button2.dataset.state = "imported";
|
|
31617
32845
|
const name = document2.createElement("code");
|
|
31618
|
-
name.textContent = `${
|
|
32846
|
+
name.textContent = `${record6.name}/\u2026`;
|
|
31619
32847
|
name.translate = false;
|
|
31620
32848
|
button2.append(name, createRendererSettingsIcon("check", 12));
|
|
31621
32849
|
} else {
|
|
@@ -31623,7 +32851,7 @@ ${detail}` : ""}`
|
|
|
31623
32851
|
button2.append(messages.add);
|
|
31624
32852
|
}
|
|
31625
32853
|
button2.addEventListener("click", () => {
|
|
31626
|
-
if (!
|
|
32854
|
+
if (!record6) {
|
|
31627
32855
|
openDialog("add", { source }, key);
|
|
31628
32856
|
return;
|
|
31629
32857
|
}
|
|
@@ -31632,7 +32860,7 @@ ${detail}` : ""}`
|
|
|
31632
32860
|
renderSection();
|
|
31633
32861
|
sectionToggle.setAttribute("aria-expanded", "true");
|
|
31634
32862
|
}
|
|
31635
|
-
const row = rows.get(
|
|
32863
|
+
const row = rows.get(record6.name);
|
|
31636
32864
|
row?.scrollIntoView({ block: "nearest", behavior: "smooth" });
|
|
31637
32865
|
row?.focus();
|
|
31638
32866
|
});
|
|
@@ -33177,7 +34405,7 @@ ${detail}` : ""}`
|
|
|
33177
34405
|
}
|
|
33178
34406
|
});
|
|
33179
34407
|
}
|
|
33180
|
-
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"))) {
|
|
34408
|
+
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")), usageStatisticsHosts) {
|
|
33181
34409
|
return Object.freeze([
|
|
33182
34410
|
createConnectionsSettingsPage(messages, getDiagnostics, void 0, getRemoteConnections),
|
|
33183
34411
|
createRemoteConnectionsPage(messages, getRemoteConnections),
|
|
@@ -33191,14 +34419,15 @@ ${detail}` : ""}`
|
|
|
33191
34419
|
createUsageStatisticsPage(
|
|
33192
34420
|
consoleMessages(messages.locale),
|
|
33193
34421
|
requestUsageStatistics,
|
|
33194
|
-
messages.locale
|
|
34422
|
+
messages.locale,
|
|
34423
|
+
usageStatisticsHosts
|
|
33195
34424
|
),
|
|
33196
34425
|
createAppearanceSettingsPage(messages, getLoadedSessionsClient),
|
|
33197
34426
|
updatesPage(messages, getUpdateClient),
|
|
33198
34427
|
aboutPage(messages, getUpdateClient)
|
|
33199
34428
|
]);
|
|
33200
34429
|
}
|
|
33201
|
-
function createDefaultRendererSettingsRegistry(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread, requestUsageStatistics) {
|
|
34430
|
+
function createDefaultRendererSettingsRegistry(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread, requestUsageStatistics, usageStatisticsHosts) {
|
|
33202
34431
|
return createRendererSettingsPageRegistry(
|
|
33203
34432
|
createDefaultRendererSettingsPages(
|
|
33204
34433
|
messages,
|
|
@@ -33209,7 +34438,8 @@ ${detail}` : ""}`
|
|
|
33209
34438
|
openImportedThread,
|
|
33210
34439
|
void 0,
|
|
33211
34440
|
void 0,
|
|
33212
|
-
requestUsageStatistics
|
|
34441
|
+
requestUsageStatistics,
|
|
34442
|
+
usageStatisticsHosts
|
|
33213
34443
|
)
|
|
33214
34444
|
);
|
|
33215
34445
|
}
|
|
@@ -33765,6 +34995,41 @@ ${detail}` : ""}`
|
|
|
33765
34995
|
margin-top: 0;
|
|
33766
34996
|
}
|
|
33767
34997
|
|
|
34998
|
+
.settings-session-import-host {
|
|
34999
|
+
display: flex;
|
|
35000
|
+
align-items: center;
|
|
35001
|
+
min-width: 0;
|
|
35002
|
+
gap: 12px;
|
|
35003
|
+
margin: -12px 0 12px;
|
|
35004
|
+
color: var(--settings-muted);
|
|
35005
|
+
font-size: 13px;
|
|
35006
|
+
}
|
|
35007
|
+
|
|
35008
|
+
.settings-session-import-host > span,
|
|
35009
|
+
.settings-session-import-host + .settings-session-import-harness > span {
|
|
35010
|
+
flex: none;
|
|
35011
|
+
min-width: 60px;
|
|
35012
|
+
}
|
|
35013
|
+
|
|
35014
|
+
.settings-session-import-host > .settings-connection-host-tabs {
|
|
35015
|
+
flex: 1;
|
|
35016
|
+
}
|
|
35017
|
+
|
|
35018
|
+
.settings-session-import-host .settings-connection-host-tab {
|
|
35019
|
+
height: 34px;
|
|
35020
|
+
padding: 0 12px;
|
|
35021
|
+
font-size: 13px;
|
|
35022
|
+
}
|
|
35023
|
+
|
|
35024
|
+
.settings-session-import-host .settings-connection-host-tab:disabled {
|
|
35025
|
+
opacity: 0.38;
|
|
35026
|
+
cursor: not-allowed;
|
|
35027
|
+
}
|
|
35028
|
+
|
|
35029
|
+
.settings-session-import-host + .settings-session-import-harness {
|
|
35030
|
+
margin-top: 0;
|
|
35031
|
+
}
|
|
35032
|
+
|
|
33768
35033
|
.settings-session-import-search,
|
|
33769
35034
|
.settings-session-import-pagination {
|
|
33770
35035
|
display: flex;
|
|
@@ -33983,6 +35248,20 @@ ${detail}` : ""}`
|
|
|
33983
35248
|
gap: 18px;
|
|
33984
35249
|
}
|
|
33985
35250
|
|
|
35251
|
+
.settings-connections-content {
|
|
35252
|
+
container: settings-connections / inline-size;
|
|
35253
|
+
}
|
|
35254
|
+
|
|
35255
|
+
@container settings-connections (max-width: 780px) {
|
|
35256
|
+
.settings-connections-layout {
|
|
35257
|
+
grid-template-columns: minmax(0, 1fr);
|
|
35258
|
+
}
|
|
35259
|
+
|
|
35260
|
+
.settings-connection-inspector {
|
|
35261
|
+
position: static;
|
|
35262
|
+
}
|
|
35263
|
+
}
|
|
35264
|
+
|
|
33986
35265
|
.settings-connection-list,
|
|
33987
35266
|
.settings-connection-inspector {
|
|
33988
35267
|
overflow: hidden;
|
|
@@ -33991,14 +35270,36 @@ ${detail}` : ""}`
|
|
|
33991
35270
|
border-radius: 10px;
|
|
33992
35271
|
}
|
|
33993
35272
|
|
|
35273
|
+
.settings-connection-host-header {
|
|
35274
|
+
display: flex;
|
|
35275
|
+
align-items: center;
|
|
35276
|
+
min-width: 0;
|
|
35277
|
+
border-bottom: 1px solid var(--settings-divider);
|
|
35278
|
+
}
|
|
35279
|
+
|
|
35280
|
+
.settings-connection-update-all {
|
|
35281
|
+
flex: none;
|
|
35282
|
+
margin-right: 10px;
|
|
35283
|
+
white-space: nowrap;
|
|
35284
|
+
}
|
|
35285
|
+
|
|
35286
|
+
.settings-connection-update-result {
|
|
35287
|
+
margin: 0;
|
|
35288
|
+
padding: 7px 10px;
|
|
35289
|
+
color: var(--settings-muted);
|
|
35290
|
+
font-size: 11px;
|
|
35291
|
+
line-height: 18px;
|
|
35292
|
+
border-bottom: 1px solid var(--settings-divider);
|
|
35293
|
+
}
|
|
35294
|
+
|
|
33994
35295
|
.settings-connection-host-strip {
|
|
33995
35296
|
display: grid;
|
|
35297
|
+
flex: 1;
|
|
33996
35298
|
grid-template-columns: 30px minmax(0, 1fr) 30px;
|
|
33997
35299
|
align-items: center;
|
|
33998
35300
|
min-width: 0;
|
|
33999
35301
|
gap: 5px;
|
|
34000
35302
|
padding: 9px 10px;
|
|
34001
|
-
border-bottom: 1px solid var(--settings-divider);
|
|
34002
35303
|
}
|
|
34003
35304
|
|
|
34004
35305
|
.settings-connection-host-scroll {
|
|
@@ -34085,7 +35386,8 @@ ${detail}` : ""}`
|
|
|
34085
35386
|
background: var(--settings-hover);
|
|
34086
35387
|
}
|
|
34087
35388
|
|
|
34088
|
-
.settings-connection-host-tab[aria-selected="true"]
|
|
35389
|
+
.settings-connection-host-tab[aria-selected="true"],
|
|
35390
|
+
.settings-connection-host-tab[aria-pressed="true"] {
|
|
34089
35391
|
color: var(--settings-text);
|
|
34090
35392
|
font-weight: 600;
|
|
34091
35393
|
background: var(--settings-active);
|
|
@@ -34095,7 +35397,7 @@ ${detail}` : ""}`
|
|
|
34095
35397
|
.settings-connection-table-header,
|
|
34096
35398
|
.settings-connection-row {
|
|
34097
35399
|
display: grid;
|
|
34098
|
-
grid-template-columns: minmax(160px, 1fr) minmax(92px, auto) 108px;
|
|
35400
|
+
grid-template-columns: minmax(160px, 1fr) minmax(92px, auto) minmax(108px, max-content);
|
|
34099
35401
|
align-items: center;
|
|
34100
35402
|
min-width: 0;
|
|
34101
35403
|
gap: 10px;
|
|
@@ -34188,6 +35490,14 @@ ${detail}` : ""}`
|
|
|
34188
35490
|
line-height: 18px;
|
|
34189
35491
|
}
|
|
34190
35492
|
|
|
35493
|
+
.settings-connection-version-available {
|
|
35494
|
+
flex: none;
|
|
35495
|
+
color: var(--settings-muted);
|
|
35496
|
+
font-size: 10px;
|
|
35497
|
+
line-height: 16px;
|
|
35498
|
+
white-space: nowrap;
|
|
35499
|
+
}
|
|
35500
|
+
|
|
34191
35501
|
.settings-connection-row__status::before {
|
|
34192
35502
|
width: 6px;
|
|
34193
35503
|
height: 6px;
|
|
@@ -34224,6 +35534,7 @@ ${detail}` : ""}`
|
|
|
34224
35534
|
justify-content: flex-end;
|
|
34225
35535
|
min-width: 0;
|
|
34226
35536
|
gap: 4px;
|
|
35537
|
+
white-space: nowrap;
|
|
34227
35538
|
}
|
|
34228
35539
|
|
|
34229
35540
|
.settings-connection-row__handle {
|
|
@@ -38372,16 +39683,17 @@ ${usage_default}`;
|
|
|
38372
39683
|
options.getConnectionDiagnostics ?? (() => null),
|
|
38373
39684
|
options.getAccountClient ?? (() => null),
|
|
38374
39685
|
options.getSessionImportClient ?? (() => null),
|
|
38375
|
-
async (threadId, signal) => {
|
|
39686
|
+
async (threadId, signal, hostId2) => {
|
|
38376
39687
|
if (!options.openImportedThread) {
|
|
38377
39688
|
throw new Error("Imported Thread navigation is unavailable");
|
|
38378
39689
|
}
|
|
38379
|
-
await options.openImportedThread(threadId, signal);
|
|
39690
|
+
await options.openImportedThread(threadId, signal, hostId2);
|
|
38380
39691
|
if (!disposed && !signal.aborted) shell?.close();
|
|
38381
39692
|
},
|
|
38382
39693
|
options.getLoadedSessionsClient ?? (() => null),
|
|
38383
39694
|
options.getRemoteConnections ?? (() => null),
|
|
38384
|
-
options.requestUsageStatistics
|
|
39695
|
+
options.requestUsageStatistics,
|
|
39696
|
+
options.usageStatisticsHosts
|
|
38385
39697
|
);
|
|
38386
39698
|
const nextShell = installRendererSettingsShell(definitions, messages, ownerWindow.document, {
|
|
38387
39699
|
onOpenChange(open) {
|
|
@@ -38530,6 +39842,30 @@ ${usage_default}`;
|
|
|
38530
39842
|
};
|
|
38531
39843
|
}
|
|
38532
39844
|
|
|
39845
|
+
// src/renderer-usage-statistics-source.ts
|
|
39846
|
+
function createRendererUsageStatisticsSource(options) {
|
|
39847
|
+
return {
|
|
39848
|
+
async request(method, params, hostId2) {
|
|
39849
|
+
const route = options.routing()?.forHost(hostId2);
|
|
39850
|
+
if (options.disposed() || !route) {
|
|
39851
|
+
throw new Error(`Host connection is unavailable (${hostId2})`);
|
|
39852
|
+
}
|
|
39853
|
+
return route.manager.sendRequest(method, params);
|
|
39854
|
+
},
|
|
39855
|
+
async hosts() {
|
|
39856
|
+
const connections = await options.listConnections().catch(() => []);
|
|
39857
|
+
const names = new Map(
|
|
39858
|
+
connections.map((connection) => [connection.hostId, connection.displayName])
|
|
39859
|
+
);
|
|
39860
|
+
const known = options.routing()?.knownHostIds?.() ?? [];
|
|
39861
|
+
return [.../* @__PURE__ */ new Set([...known, ...names.keys()])].map((hostId2) => {
|
|
39862
|
+
const label = names.get(hostId2);
|
|
39863
|
+
return label === void 0 ? { hostId: hostId2 } : { hostId: hostId2, label };
|
|
39864
|
+
});
|
|
39865
|
+
}
|
|
39866
|
+
};
|
|
39867
|
+
}
|
|
39868
|
+
|
|
38533
39869
|
// src/renderer-native-composer-controller.ts
|
|
38534
39870
|
var MAX_ELEMENT_DEPTH = 4;
|
|
38535
39871
|
var MAX_FIBER_DEPTH = 40;
|
|
@@ -39365,9 +40701,13 @@ ${usage_default}`;
|
|
|
39365
40701
|
function mutationMayAffectComposer(mutation) {
|
|
39366
40702
|
const target = mutation.target instanceof Element ? mutation.target : mutation.target.parentElement;
|
|
39367
40703
|
if (!target) return true;
|
|
39368
|
-
if (mutation.type === "attributes" && mutation.attributeName === "data-codex-composer-root")
|
|
40704
|
+
if (mutation.type === "attributes" && (mutation.attributeName === "data-codex-composer-root" || NATIVE_COMPOSER_REQUEST_ATTRIBUTES.some((attribute) => attribute === mutation.attributeName)))
|
|
39369
40705
|
return true;
|
|
39370
|
-
if (mutation.type !== "attributes" && editorForElement(target))
|
|
40706
|
+
if (mutation.type !== "attributes" && editorForElement(target)) {
|
|
40707
|
+
return mutation.type === "childList" && [...mutation.addedNodes, ...mutation.removedNodes].some(
|
|
40708
|
+
(node) => node instanceof Element && hasNativeComposerRequest(node)
|
|
40709
|
+
);
|
|
40710
|
+
}
|
|
39371
40711
|
if (target.closest(CODEX_COMPOSER_SELECTOR)) return true;
|
|
39372
40712
|
if (mutation.type === "characterData") return false;
|
|
39373
40713
|
if (!target.closest(
|
|
@@ -39458,30 +40798,35 @@ ${usage_default}`;
|
|
|
39458
40798
|
});
|
|
39459
40799
|
let connectionDiagnostics = null;
|
|
39460
40800
|
const remoteConnections = createRemoteConnectionsControl(window, modelClientForHost);
|
|
40801
|
+
const usageStatistics = createRendererUsageStatisticsSource({
|
|
40802
|
+
routing: () => window.__codexhostHostRoutingV1,
|
|
40803
|
+
listConnections: () => remoteConnections.ssh.list(),
|
|
40804
|
+
disposed: () => disposed
|
|
40805
|
+
});
|
|
39461
40806
|
const settingsLifecycle = installRendererSettingsLifecycle(window, {
|
|
39462
40807
|
getRemoteConnections: () => remoteConnections,
|
|
39463
40808
|
getUpdateClient: () => modelControl,
|
|
39464
40809
|
getAccountClient: () => modelControl,
|
|
39465
40810
|
getConnectionDiagnostics: () => connectionDiagnostics,
|
|
39466
40811
|
getLoadedSessionsClient: () => modelClientForHost("local"),
|
|
39467
|
-
|
|
39468
|
-
|
|
39469
|
-
|
|
39470
|
-
|
|
39471
|
-
|
|
39472
|
-
|
|
39473
|
-
const client = modelClientForHost("local");
|
|
40812
|
+
requestUsageStatistics: usageStatistics.request,
|
|
40813
|
+
usageStatisticsHosts: usageStatistics.hosts,
|
|
40814
|
+
getSessionImportClient: (requestedHostId) => {
|
|
40815
|
+
const hostId2 = requestedHostId ?? activeModelHostId();
|
|
40816
|
+
if (!hostId2) return null;
|
|
40817
|
+
const client = modelClientForHost(hostId2);
|
|
39474
40818
|
const sources = client?.listSessionImportSources;
|
|
39475
40819
|
const list = client?.listHarnessSessions;
|
|
39476
40820
|
const importSession = client?.importHarnessSession;
|
|
39477
40821
|
if (!sources || !list || !importSession) return null;
|
|
39478
40822
|
return {
|
|
40823
|
+
hostId: hostId2,
|
|
39479
40824
|
listSessionImportSources: () => sources(),
|
|
39480
40825
|
listHarnessSessions: (input) => list(input),
|
|
39481
40826
|
importHarnessSession: (input) => importSession(input)
|
|
39482
40827
|
};
|
|
39483
40828
|
},
|
|
39484
|
-
openImportedThread: (threadId, signal) => openRendererThread(threadId, { hostId: "local", signal }),
|
|
40829
|
+
openImportedThread: (threadId, signal, hostId2) => openRendererThread(threadId, { hostId: hostId2 ?? "local", signal }),
|
|
39485
40830
|
onLocaleChange() {
|
|
39486
40831
|
for (const mounted of mountedByComposer.values()) renderMounted(mounted);
|
|
39487
40832
|
}
|
|
@@ -39552,7 +40897,7 @@ ${usage_default}`;
|
|
|
39552
40897
|
const ownershipRecovery = /* @__PURE__ */ new WeakMap();
|
|
39553
40898
|
const modelRecovery = /* @__PURE__ */ new WeakMap();
|
|
39554
40899
|
const isRetainedComposer = (mounted) => mounted.composer.isConnected && mounted.composer.matches(CODEX_COMPOSER_SELECTOR) && mountedByComposer.get(mounted.composer) === mounted;
|
|
39555
|
-
const isMountedComposer = (composer) => composer.isConnected && composer.matches(CODEX_COMPOSER_SELECTOR) && orbitComposerKind(composer) === "codex" && mountedByComposer.has(composer);
|
|
40900
|
+
const isMountedComposer = (composer) => composer.isConnected && composer.matches(CODEX_COMPOSER_SELECTOR) && !hasNativeComposerRequest(composer) && orbitComposerKind(composer) === "codex" && mountedByComposer.has(composer);
|
|
39556
40901
|
const isCurrentModelRequest = (mounted, generation) => isMountedComposer(mounted.composer) && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentModelRequest(mounted.composer, generation);
|
|
39557
40902
|
const isCurrentOwnershipRequest = (mounted, generation) => isMountedComposer(mounted.composer) && mountedByComposer.get(mounted.composer) === mounted && controller.isCurrentOwnershipRequest(mounted.composer, generation);
|
|
39558
40903
|
const finishModelRequest = (mounted, generation) => {
|
|
@@ -39565,9 +40910,10 @@ ${usage_default}`;
|
|
|
39565
40910
|
};
|
|
39566
40911
|
const notifySubmission = (composer, trigger) => {
|
|
39567
40912
|
const state = controller.recordSubmission(composer);
|
|
40913
|
+
const createsThread = state.phase === "draft";
|
|
39568
40914
|
const preferenceStorage = rendererNewThreadPreferenceStorage(activeModelHostId(composer));
|
|
39569
|
-
writeNewThreadAgentPreference(state.agent, preferenceStorage);
|
|
39570
|
-
if (state.agent !== "codex") {
|
|
40915
|
+
if (createsThread) writeNewThreadAgentPreference(state.agent, preferenceStorage);
|
|
40916
|
+
if (createsThread && state.agent !== "codex") {
|
|
39571
40917
|
const model2 = controller.modelForAgent(composer, state.agent);
|
|
39572
40918
|
if (model2) {
|
|
39573
40919
|
writeNewThreadExternalConfigurationPreference(
|
|
@@ -40706,7 +42052,7 @@ ${usage_default}`;
|
|
|
40706
42052
|
let webUiAvailable = false;
|
|
40707
42053
|
try {
|
|
40708
42054
|
const inspection = await client.inspectHarness(
|
|
40709
|
-
{ harnessId: harnessIdSchema.parse(agent), refresh },
|
|
42055
|
+
{ harnessId: harnessIdSchema.parse(agent), refresh, purpose: "availability" },
|
|
40710
42056
|
{ priority: "background" }
|
|
40711
42057
|
);
|
|
40712
42058
|
status = inspection.status === "ready" ? "ready" : inspection.status;
|
|
@@ -40946,10 +42292,10 @@ ${usage_default}`;
|
|
|
40946
42292
|
}
|
|
40947
42293
|
};
|
|
40948
42294
|
const mount = (composer) => {
|
|
40949
|
-
if (mountedByComposer.has(composer) || !composer.isConnected || orbitComposerKind(composer) !== "codex" || !composer.matches(CODEX_COMPOSER_SELECTOR)) {
|
|
42295
|
+
if (mountedByComposer.has(composer) || !composer.isConnected || hasNativeComposerRequest(composer) || orbitComposerKind(composer) !== "codex" || !composer.matches(CODEX_COMPOSER_SELECTOR)) {
|
|
40950
42296
|
return;
|
|
40951
42297
|
}
|
|
40952
|
-
const allButtons =
|
|
42298
|
+
const allButtons = composerButtonsWithin(composer);
|
|
40953
42299
|
const sendButton = sendButtonWithin(composer) ?? allButtons.at(-1) ?? null;
|
|
40954
42300
|
if (!sendButton) return;
|
|
40955
42301
|
const modelTarget = findComposerModelTarget(composer);
|
|
@@ -41044,7 +42390,7 @@ ${usage_default}`;
|
|
|
41044
42390
|
const sourceState = controller.get(replacement.source.composer);
|
|
41045
42391
|
const replacementTarget = findComposerModelTarget(target);
|
|
41046
42392
|
const replacementHostId = activeModelHostId(target);
|
|
41047
|
-
if (orbitComposerKind(target) !== "codex" || !shouldTransferComposerState(
|
|
42393
|
+
if (hasNativeComposerRequest(target) || orbitComposerKind(target) !== "codex" || !shouldTransferComposerState(
|
|
41048
42394
|
replacement.sourceModelTarget,
|
|
41049
42395
|
replacementTarget,
|
|
41050
42396
|
sourceState.phase,
|
|
@@ -41061,7 +42407,7 @@ ${usage_default}`;
|
|
|
41061
42407
|
}
|
|
41062
42408
|
for (const [composer, mounted] of mountedByComposer) {
|
|
41063
42409
|
const kind = orbitComposerKind(composer);
|
|
41064
|
-
if (!composer.isConnected || kind === "orbit" || !composer.matches(CODEX_COMPOSER_SELECTOR) || !mounted.control.root.isConnected) {
|
|
42410
|
+
if (!composer.isConnected || hasNativeComposerRequest(composer) || kind === "orbit" || !composer.matches(CODEX_COMPOSER_SELECTOR) || !mounted.control.root.isConnected) {
|
|
41065
42411
|
mounted.usageRequestGeneration += 1;
|
|
41066
42412
|
usageRefreshAttempts.delete(composer);
|
|
41067
42413
|
const timer = usageRefreshTimers.get(composer);
|
|
@@ -41110,6 +42456,7 @@ ${usage_default}`;
|
|
|
41110
42456
|
void refreshHarnessAvailability();
|
|
41111
42457
|
}
|
|
41112
42458
|
pendingReplacements.clear();
|
|
42459
|
+
questions.refreshContext();
|
|
41113
42460
|
};
|
|
41114
42461
|
const scheduleScan = (refreshTargets = false) => {
|
|
41115
42462
|
refreshTargetsOnNextScan ||= refreshTargets;
|
|
@@ -41293,7 +42640,12 @@ ${usage_default}`;
|
|
|
41293
42640
|
};
|
|
41294
42641
|
mutationObserver.observe(document.documentElement, {
|
|
41295
42642
|
attributes: true,
|
|
41296
|
-
attributeFilter: [
|
|
42643
|
+
attributeFilter: [
|
|
42644
|
+
"hidden",
|
|
42645
|
+
"aria-hidden",
|
|
42646
|
+
"data-codex-composer-root",
|
|
42647
|
+
...NATIVE_COMPOSER_REQUEST_ATTRIBUTES
|
|
42648
|
+
],
|
|
41297
42649
|
characterData: true,
|
|
41298
42650
|
childList: true,
|
|
41299
42651
|
subtree: true
|
|
@@ -41390,6 +42742,16 @@ ${usage_default}`;
|
|
|
41390
42742
|
const connectedComposers = () => [...mountedByComposer.values()].filter(
|
|
41391
42743
|
(mounted) => isMountedComposer(mounted.composer) && mounted.control.root.isConnected
|
|
41392
42744
|
);
|
|
42745
|
+
const questions = installRendererQuestions(window, () => {
|
|
42746
|
+
const visible = connectedComposers().filter(
|
|
42747
|
+
(mounted2) => mounted2.composer.getClientRects().length > 0 && window.getComputedStyle(mounted2.composer).visibility === "visible" && !mounted2.composer.closest('[hidden], [inert], [aria-hidden="true"]') && controller.get(mounted2.composer).agent !== "codex"
|
|
42748
|
+
);
|
|
42749
|
+
const mounted = visible.length === 1 ? visible[0] : void 0;
|
|
42750
|
+
const threadId = mounted ? threadIdFromComposerModelTarget(findComposerModelTarget(mounted.composer)) : null;
|
|
42751
|
+
const hostId2 = mounted?.hostId;
|
|
42752
|
+
const route = hostId2 ? window.__codexhostHostRoutingV1?.forHost(hostId2) : null;
|
|
42753
|
+
return mounted && threadId && hostId2 && route ? { hostId: hostId2, threadId, composer: mounted.composer, route: route.manager } : null;
|
|
42754
|
+
});
|
|
41393
42755
|
const api = {
|
|
41394
42756
|
remoteConnections: (request) => handleRemoteConnectionsRequest(remoteConnections, request),
|
|
41395
42757
|
currentThreadId() {
|
|
@@ -41481,6 +42843,7 @@ ${usage_default}`;
|
|
|
41481
42843
|
dispose() {
|
|
41482
42844
|
if (disposed) return;
|
|
41483
42845
|
disposed = true;
|
|
42846
|
+
questions.dispose();
|
|
41484
42847
|
usageNotificationDispose();
|
|
41485
42848
|
adapterDispose?.();
|
|
41486
42849
|
adapterDispose = null;
|
|
@@ -41561,6 +42924,10 @@ ${usage_default}`;
|
|
|
41561
42924
|
|
|
41562
42925
|
lucide/dist/esm/defaultAttributes.mjs:
|
|
41563
42926
|
lucide/dist/esm/createElement.mjs:
|
|
42927
|
+
lucide/dist/esm/icons/check.mjs:
|
|
42928
|
+
lucide/dist/esm/icons/message-circle-question-mark.mjs:
|
|
42929
|
+
lucide/dist/esm/icons/pencil.mjs:
|
|
42930
|
+
lucide/dist/esm/icons/x.mjs:
|
|
41564
42931
|
lucide/dist/esm/icons/boxes.mjs:
|
|
41565
42932
|
lucide/dist/esm/icons/circle-check.mjs:
|
|
41566
42933
|
lucide/dist/esm/icons/chevron-down.mjs:
|
|
@@ -41596,11 +42963,10 @@ lucide/dist/esm/icons/terminal.mjs:
|
|
|
41596
42963
|
lucide/dist/esm/icons/scroll-text.mjs:
|
|
41597
42964
|
lucide/dist/esm/icons/search.mjs:
|
|
41598
42965
|
lucide/dist/esm/icons/circle-question-mark.mjs:
|
|
41599
|
-
lucide/dist/esm/icons/x.mjs:
|
|
41600
42966
|
lucide/dist/esm/icons/users.mjs:
|
|
41601
42967
|
lucide/dist/esm/icons/plus.mjs:
|
|
41602
42968
|
lucide/dist/esm/icons/circle-alert.mjs:
|
|
41603
|
-
lucide/dist/esm/icons/
|
|
42969
|
+
lucide/dist/esm/icons/activity.mjs:
|
|
41604
42970
|
lucide/dist/esm/icons/lock.mjs:
|
|
41605
42971
|
lucide/dist/esm/icons/shield.mjs:
|
|
41606
42972
|
lucide/dist/esm/icons/shield-alert.mjs:
|