@codexhost/cli-linux-arm64 0.3.5 → 0.4.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/desktop-controller.mjs +3 -0
- package/app/host-runtime.mjs +6858 -2707
- package/app/renderer-extension.js +1484 -681
- package/bin/codexhost +0 -0
- package/libexec/codexhost-shim +0 -0
- package/libexec/codexhost-updater +0 -0
- package/package.json +1 -1
|
@@ -16559,6 +16559,86 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16559
16559
|
["path", { d: "M12 16h.01" }]
|
|
16560
16560
|
];
|
|
16561
16561
|
|
|
16562
|
+
// src/renderer-harness-localization.ts
|
|
16563
|
+
var ENGLISH_HARNESS_MESSAGES = Object.freeze({
|
|
16564
|
+
commands: "Commands",
|
|
16565
|
+
harnessCommands: "Harness commands",
|
|
16566
|
+
textArgument: "Text",
|
|
16567
|
+
permissionMode: "Permission mode",
|
|
16568
|
+
permissions: "Permissions",
|
|
16569
|
+
loadingPermissions: "Loading permissions...",
|
|
16570
|
+
selecting: "Selecting...",
|
|
16571
|
+
permissionsUnavailable: "Permissions unavailable"
|
|
16572
|
+
});
|
|
16573
|
+
var CHINESE_HARNESS_MESSAGES = Object.freeze({
|
|
16574
|
+
commands: "\u547D\u4EE4",
|
|
16575
|
+
harnessCommands: "Harness \u547D\u4EE4",
|
|
16576
|
+
textArgument: "\u6587\u672C",
|
|
16577
|
+
permissionMode: "\u6743\u9650\u6A21\u5F0F",
|
|
16578
|
+
permissions: "\u6743\u9650",
|
|
16579
|
+
loadingPermissions: "\u6B63\u5728\u52A0\u8F7D\u6743\u9650...",
|
|
16580
|
+
selecting: "\u6B63\u5728\u9009\u62E9...",
|
|
16581
|
+
permissionsUnavailable: "\u6743\u9650\u4E0D\u53EF\u7528"
|
|
16582
|
+
});
|
|
16583
|
+
var CHINESE_PERMISSION_MODE_LABELS = /* @__PURE__ */ new Map([
|
|
16584
|
+
["Always ask", "\u59CB\u7EC8\u8BE2\u95EE"],
|
|
16585
|
+
["Write", "\u5199\u5165"],
|
|
16586
|
+
["Full access", "\u5B8C\u5168\u8BBF\u95EE"],
|
|
16587
|
+
["Plan mode", "\u89C4\u5212\u6A21\u5F0F"],
|
|
16588
|
+
["Default", "\u9ED8\u8BA4"],
|
|
16589
|
+
["Accept edits", "\u63A5\u53D7\u7F16\u8F91"],
|
|
16590
|
+
["Auto mode", "\u81EA\u52A8\u6A21\u5F0F"],
|
|
16591
|
+
["Bypass permissions", "\u7ED5\u8FC7\u6743\u9650"],
|
|
16592
|
+
["Ask", "\u8BE2\u95EE"],
|
|
16593
|
+
["Auto", "\u81EA\u52A8"],
|
|
16594
|
+
["Always approve", "\u59CB\u7EC8\u6279\u51C6"]
|
|
16595
|
+
]);
|
|
16596
|
+
var CHINESE_PERMISSION_MODE_DESCRIPTIONS = /* @__PURE__ */ new Map([
|
|
16597
|
+
[
|
|
16598
|
+
"Automatically allow reads and ask before write or execution actions.",
|
|
16599
|
+
"\u81EA\u52A8\u5141\u8BB8\u8BFB\u53D6\uFF1B\u5199\u5165\u6216\u6267\u884C\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"
|
|
16600
|
+
],
|
|
16601
|
+
[
|
|
16602
|
+
"Automatically allow reads and writes; ask before execution actions.",
|
|
16603
|
+
"\u81EA\u52A8\u5141\u8BB8\u8BFB\u53D6\u548C\u5199\u5165\uFF1B\u6267\u884C\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"
|
|
16604
|
+
],
|
|
16605
|
+
["Run all tool actions without approval prompts.", "\u65E0\u9700\u6279\u51C6\u63D0\u793A\u5373\u53EF\u8FD0\u884C\u6240\u6709\u5DE5\u5177\u64CD\u4F5C\u3002"],
|
|
16606
|
+
["Analyze and plan without executing tools.", "\u4EC5\u5206\u6790\u548C\u89C4\u5212\uFF0C\u4E0D\u6267\u884C\u5DE5\u5177\u3002"],
|
|
16607
|
+
["Ask before edits and other protected actions.", "\u7F16\u8F91\u548C\u5176\u4ED6\u53D7\u4FDD\u62A4\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
|
|
16608
|
+
["Allow file edits and ask for other protected actions.", "\u5141\u8BB8\u6587\u4EF6\u7F16\u8F91\uFF1B\u5176\u4ED6\u53D7\u4FDD\u62A4\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
|
|
16609
|
+
["Let Claude classify permission requests.", "\u7531 Claude \u5224\u65AD\u6743\u9650\u8BF7\u6C42\u3002"],
|
|
16610
|
+
["Skip Claude Code permission checks.", "\u8DF3\u8FC7 Claude Code \u6743\u9650\u68C0\u67E5\u3002"],
|
|
16611
|
+
[
|
|
16612
|
+
"Use Grok Build's default interactive approval policy.",
|
|
16613
|
+
"\u4F7F\u7528 Grok Build \u7684\u9ED8\u8BA4\u4EA4\u4E92\u5F0F\u6279\u51C6\u7B56\u7565\u3002"
|
|
16614
|
+
],
|
|
16615
|
+
["Ask before protected tool actions.", "\u6267\u884C\u53D7\u4FDD\u62A4\u7684\u5DE5\u5177\u64CD\u4F5C\u524D\u8BE2\u95EE\u3002"],
|
|
16616
|
+
[
|
|
16617
|
+
"Let Grok Build decide which tool actions may run automatically.",
|
|
16618
|
+
"\u7531 Grok Build \u51B3\u5B9A\u54EA\u4E9B\u5DE5\u5177\u64CD\u4F5C\u53EF\u81EA\u52A8\u8FD0\u884C\u3002"
|
|
16619
|
+
],
|
|
16620
|
+
["Approve all tool actions without prompting.", "\u65E0\u9700\u63D0\u793A\u5373\u53EF\u6279\u51C6\u6240\u6709\u5DE5\u5177\u64CD\u4F5C\u3002"]
|
|
16621
|
+
]);
|
|
16622
|
+
function rendererHarnessMessages(locale) {
|
|
16623
|
+
return locale === "zh-CN" ? CHINESE_HARNESS_MESSAGES : ENGLISH_HARNESS_MESSAGES;
|
|
16624
|
+
}
|
|
16625
|
+
function rendererHarnessCommandPresentation(command, locale) {
|
|
16626
|
+
if (locale === "zh-CN" && command.invocation === "/compact") {
|
|
16627
|
+
return { label: "\u538B\u7F29\u4E0A\u4E0B\u6587", description: "\u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\u4E0A\u4E0B\u6587" };
|
|
16628
|
+
}
|
|
16629
|
+
return {
|
|
16630
|
+
label: command.label,
|
|
16631
|
+
description: command.description ?? command.label
|
|
16632
|
+
};
|
|
16633
|
+
}
|
|
16634
|
+
function rendererPermissionModePresentation(mode, locale) {
|
|
16635
|
+
if (locale !== "zh-CN") return { label: mode.label, description: mode.description };
|
|
16636
|
+
return {
|
|
16637
|
+
label: CHINESE_PERMISSION_MODE_LABELS.get(mode.label) ?? mode.label,
|
|
16638
|
+
description: mode.description === void 0 ? void 0 : CHINESE_PERMISSION_MODE_DESCRIPTIONS.get(mode.description) ?? mode.description
|
|
16639
|
+
};
|
|
16640
|
+
}
|
|
16641
|
+
|
|
16562
16642
|
// src/renderer-permission-mode-picker.ts
|
|
16563
16643
|
var MENU_CLASSES2 = "fixed z-50 overflow-hidden rounded-lg bg-token-dropdown-background/95 text-token-foreground shadow-lg ring-[0.5px] ring-token-border backdrop-blur-xl";
|
|
16564
16644
|
var OPTION_CLASSES2 = "flex w-full cursor-interaction items-start gap-2 rounded-md px-2 py-2 text-left text-sm text-token-foreground outline-none enabled:hover:bg-token-list-hover-background enabled:active:bg-token-foreground/15 disabled:cursor-not-allowed disabled:opacity-40";
|
|
@@ -16585,13 +16665,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16585
16665
|
if (view.status === "unsupported") return true;
|
|
16586
16666
|
return (view.status === "ready" || view.status === "error") && selectedMode(view) !== void 0;
|
|
16587
16667
|
}
|
|
16588
|
-
function rendererPermissionModeLabel(view) {
|
|
16668
|
+
function rendererPermissionModeLabel(view, locale = "en") {
|
|
16589
16669
|
const selected = selectedMode(view);
|
|
16590
|
-
if (selected) return selected.label;
|
|
16591
|
-
|
|
16592
|
-
if (view.status === "
|
|
16593
|
-
if (view.status === "
|
|
16594
|
-
|
|
16670
|
+
if (selected) return rendererPermissionModePresentation(selected, locale).label;
|
|
16671
|
+
const messages = rendererHarnessMessages(locale);
|
|
16672
|
+
if (view.status === "loading") return messages.loadingPermissions;
|
|
16673
|
+
if (view.status === "selecting") return messages.selecting;
|
|
16674
|
+
if (view.status === "error") return messages.permissionsUnavailable;
|
|
16675
|
+
return messages.permissions;
|
|
16595
16676
|
}
|
|
16596
16677
|
function positionMenu(control) {
|
|
16597
16678
|
const rect = control.trigger.getBoundingClientRect();
|
|
@@ -16606,7 +16687,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16606
16687
|
control.trigger.style.maxWidth = "min(220px, 34vw)";
|
|
16607
16688
|
control.trigger.style.letterSpacing = "0";
|
|
16608
16689
|
}
|
|
16609
|
-
function mountRendererPermissionModePicker(composerId, onSelect) {
|
|
16690
|
+
function mountRendererPermissionModePicker(composerId, onSelect, locale = "en") {
|
|
16610
16691
|
ensureRendererTriggerChipStyle(document);
|
|
16611
16692
|
const root = document.createElement("div");
|
|
16612
16693
|
root.setAttribute("data-codexhost-permission-mode-control", composerId);
|
|
@@ -16638,7 +16719,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16638
16719
|
const menu = document.createElement("div");
|
|
16639
16720
|
menu.id = `${composerId}-permission-mode-menu`;
|
|
16640
16721
|
menu.setAttribute("role", "menu");
|
|
16641
|
-
menu.setAttribute("aria-label",
|
|
16722
|
+
menu.setAttribute("aria-label", rendererHarnessMessages(locale).permissionMode);
|
|
16642
16723
|
menu.setAttribute("popover", "auto");
|
|
16643
16724
|
menu.hidden = typeof menu.showPopover !== "function";
|
|
16644
16725
|
menu.className = MENU_CLASSES2;
|
|
@@ -16728,6 +16809,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16728
16809
|
label,
|
|
16729
16810
|
menu,
|
|
16730
16811
|
options,
|
|
16812
|
+
locale,
|
|
16731
16813
|
close,
|
|
16732
16814
|
dispose() {
|
|
16733
16815
|
close();
|
|
@@ -16744,10 +16826,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16744
16826
|
syncRendererPermissionModeTriggerClass(control);
|
|
16745
16827
|
return control;
|
|
16746
16828
|
}
|
|
16747
|
-
function rebuildOptions2(control, catalog) {
|
|
16829
|
+
function rebuildOptions2(control, catalog, locale) {
|
|
16748
16830
|
control.options.clear();
|
|
16749
16831
|
control.menu.replaceChildren();
|
|
16750
16832
|
for (const mode of catalog.modes) {
|
|
16833
|
+
const presentation = rendererPermissionModePresentation(mode, locale);
|
|
16751
16834
|
const button = document.createElement("button");
|
|
16752
16835
|
button.type = "button";
|
|
16753
16836
|
button.dataset.permissionModeId = mode.id;
|
|
@@ -16761,13 +16844,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16761
16844
|
const copy = document.createElement("span");
|
|
16762
16845
|
copy.className = "min-w-0 flex-1";
|
|
16763
16846
|
const title = document.createElement("span");
|
|
16764
|
-
title.textContent =
|
|
16847
|
+
title.textContent = presentation.label;
|
|
16765
16848
|
title.className = "block font-medium";
|
|
16766
16849
|
title.style.letterSpacing = "0";
|
|
16767
16850
|
copy.append(title);
|
|
16768
|
-
if (
|
|
16851
|
+
if (presentation.description) {
|
|
16769
16852
|
const description = document.createElement("span");
|
|
16770
|
-
description.textContent =
|
|
16853
|
+
description.textContent = presentation.description;
|
|
16771
16854
|
description.className = "mt-0.5 block text-xs text-token-text-tertiary";
|
|
16772
16855
|
description.style.lineHeight = "16px";
|
|
16773
16856
|
description.style.letterSpacing = "0";
|
|
@@ -16782,7 +16865,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16782
16865
|
control.menu.append(button);
|
|
16783
16866
|
}
|
|
16784
16867
|
}
|
|
16785
|
-
function renderRendererPermissionModePicker(control, view, visible) {
|
|
16868
|
+
function renderRendererPermissionModePicker(control, view, visible, locale = control.locale) {
|
|
16869
|
+
control.locale = locale;
|
|
16870
|
+
const messages = rendererHarnessMessages(locale);
|
|
16871
|
+
control.menu.setAttribute("aria-label", messages.permissionMode);
|
|
16786
16872
|
control.root.style.display = visible ? "inline-flex" : "none";
|
|
16787
16873
|
control.root.style.alignItems = "center";
|
|
16788
16874
|
control.root.style.alignSelf = "center";
|
|
@@ -16793,15 +16879,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16793
16879
|
control.close();
|
|
16794
16880
|
return;
|
|
16795
16881
|
}
|
|
16796
|
-
const signature = JSON.stringify(view.catalog)
|
|
16882
|
+
const signature = `${locale}:${JSON.stringify(view.catalog)}`;
|
|
16797
16883
|
if (view.catalog && control.root.dataset.catalogSignature !== signature) {
|
|
16798
|
-
rebuildOptions2(control, view.catalog);
|
|
16884
|
+
rebuildOptions2(control, view.catalog, locale);
|
|
16799
16885
|
control.root.dataset.catalogSignature = signature;
|
|
16800
16886
|
}
|
|
16801
|
-
const label = rendererPermissionModeLabel(view);
|
|
16887
|
+
const label = rendererPermissionModeLabel(view, locale);
|
|
16802
16888
|
if (control.label.textContent !== label) control.label.textContent = label;
|
|
16803
16889
|
control.trigger.title = view.error ? `${label}: ${view.error}` : label;
|
|
16804
|
-
control.trigger.setAttribute("aria-label",
|
|
16890
|
+
control.trigger.setAttribute("aria-label", `${messages.permissionMode}: ${label}`);
|
|
16805
16891
|
control.trigger.disabled = view.status === "loading" || view.status === "selecting" || view.catalog === void 0;
|
|
16806
16892
|
control.trigger.setAttribute("aria-busy", String(view.status === "selecting"));
|
|
16807
16893
|
if (control.trigger.disabled) control.close();
|
|
@@ -16814,6 +16900,51 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16814
16900
|
}
|
|
16815
16901
|
|
|
16816
16902
|
// src/renderer-usage-control.ts
|
|
16903
|
+
var ENGLISH_USAGE_MESSAGES = Object.freeze({
|
|
16904
|
+
usage: "Usage",
|
|
16905
|
+
context: "Context",
|
|
16906
|
+
latestCacheHit: "Latest cache hit",
|
|
16907
|
+
outputSpeed: "Output speed",
|
|
16908
|
+
cacheRead: "Cache read",
|
|
16909
|
+
cacheWrite: "Cache write",
|
|
16910
|
+
reasoning: "Reasoning",
|
|
16911
|
+
totalTokens: "Total tokens",
|
|
16912
|
+
inputOutput: "Input / output",
|
|
16913
|
+
fiveHourLimit: "5-hour limit",
|
|
16914
|
+
sevenDayLimit: "7-day limit",
|
|
16915
|
+
sessionCostEstimate: "Session cost estimate",
|
|
16916
|
+
threadUsage: "Thread Usage",
|
|
16917
|
+
threadUsageDetails: "Thread Usage details",
|
|
16918
|
+
contextSummary: "context",
|
|
16919
|
+
tokensSummary: "tokens",
|
|
16920
|
+
tokensPerSecond: "tok/s",
|
|
16921
|
+
fiveHourSummary: "5h",
|
|
16922
|
+
sevenDaySummary: "7d"
|
|
16923
|
+
});
|
|
16924
|
+
var CHINESE_USAGE_MESSAGES = Object.freeze({
|
|
16925
|
+
usage: "\u7528\u91CF",
|
|
16926
|
+
context: "\u4E0A\u4E0B\u6587",
|
|
16927
|
+
latestCacheHit: "\u6700\u8FD1\u7F13\u5B58\u547D\u4E2D\u7387",
|
|
16928
|
+
outputSpeed: "\u8F93\u51FA\u901F\u5EA6",
|
|
16929
|
+
cacheRead: "\u7F13\u5B58\u8BFB\u53D6",
|
|
16930
|
+
cacheWrite: "\u7F13\u5B58\u5199\u5165",
|
|
16931
|
+
reasoning: "\u63A8\u7406",
|
|
16932
|
+
totalTokens: "Token \u603B\u6570",
|
|
16933
|
+
inputOutput: "\u8F93\u5165 / \u8F93\u51FA",
|
|
16934
|
+
fiveHourLimit: "5 \u5C0F\u65F6\u9650\u989D",
|
|
16935
|
+
sevenDayLimit: "7 \u5929\u9650\u989D",
|
|
16936
|
+
sessionCostEstimate: "\u4F1A\u8BDD\u8D39\u7528\u4F30\u7B97",
|
|
16937
|
+
threadUsage: "\u5BF9\u8BDD\u7528\u91CF",
|
|
16938
|
+
threadUsageDetails: "\u5BF9\u8BDD\u7528\u91CF\u8BE6\u60C5",
|
|
16939
|
+
contextSummary: "\u4E0A\u4E0B\u6587",
|
|
16940
|
+
tokensSummary: "Token",
|
|
16941
|
+
tokensPerSecond: "Token/\u79D2",
|
|
16942
|
+
fiveHourSummary: "5 \u5C0F\u65F6",
|
|
16943
|
+
sevenDaySummary: "7 \u5929"
|
|
16944
|
+
});
|
|
16945
|
+
function rendererUsageMessages(locale) {
|
|
16946
|
+
return locale === "zh-CN" ? CHINESE_USAGE_MESSAGES : ENGLISH_USAGE_MESSAGES;
|
|
16947
|
+
}
|
|
16817
16948
|
function decimal(value, fractionDigits) {
|
|
16818
16949
|
return value.toFixed(fractionDigits).replace(/\.?0+$/u, "");
|
|
16819
16950
|
}
|
|
@@ -16823,14 +16954,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16823
16954
|
function formatRendererCost(value) {
|
|
16824
16955
|
return `$${value.toFixed(3)}`;
|
|
16825
16956
|
}
|
|
16826
|
-
function formatRendererTokenRate(value) {
|
|
16827
|
-
return `${decimal(value, 1)}
|
|
16957
|
+
function formatRendererTokenRate(value, locale = "en") {
|
|
16958
|
+
return `${decimal(value, 1)} ${rendererUsageMessages(locale).tokensPerSecond}`;
|
|
16828
16959
|
}
|
|
16829
16960
|
function formatRendererTokenCount(value) {
|
|
16830
16961
|
const sign = value < 0 ? "-" : "";
|
|
16831
16962
|
const absolute = Math.abs(value);
|
|
16832
16963
|
if (absolute < 1e3) return `${sign}${Math.round(absolute)}`;
|
|
16833
|
-
return `${sign}${decimal(absolute / 1e3, 1)}k`;
|
|
16964
|
+
if (absolute < 1e6) return `${sign}${decimal(absolute / 1e3, 1)}k`;
|
|
16965
|
+
if (absolute < 1e9) return `${sign}${decimal(absolute / 1e6, 1)}M`;
|
|
16966
|
+
return `${sign}${decimal(absolute / 1e9, 1)}B`;
|
|
16834
16967
|
}
|
|
16835
16968
|
function formatRendererCreditsPercent(value) {
|
|
16836
16969
|
return `${decimal(value, 1)}%`;
|
|
@@ -16872,20 +17005,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16872
17005
|
svg.append(track, fill);
|
|
16873
17006
|
return svg;
|
|
16874
17007
|
}
|
|
16875
|
-
function formatRendererPlanReset(unixSeconds) {
|
|
17008
|
+
function formatRendererPlanReset(unixSeconds, locale) {
|
|
16876
17009
|
const date5 = new Date(unixSeconds * 1e3);
|
|
16877
17010
|
if (Number.isNaN(date5.getTime())) return "";
|
|
16878
|
-
return date5.toLocaleString(void 0, {
|
|
17011
|
+
return date5.toLocaleString(locale === "zh-CN" ? "zh-CN" : void 0, {
|
|
16879
17012
|
month: "long",
|
|
16880
17013
|
day: "numeric",
|
|
16881
17014
|
hour: "numeric",
|
|
16882
17015
|
minute: "2-digit"
|
|
16883
17016
|
});
|
|
16884
17017
|
}
|
|
16885
|
-
function formatRendererPlanWindow(usedPercent, resetsAtUnix) {
|
|
17018
|
+
function formatRendererPlanWindow(usedPercent, resetsAtUnix, locale) {
|
|
16886
17019
|
const percent = formatRendererCreditsPercent(usedPercent);
|
|
16887
17020
|
if (resetsAtUnix === void 0) return percent;
|
|
16888
|
-
const reset = formatRendererPlanReset(resetsAtUnix);
|
|
17021
|
+
const reset = formatRendererPlanReset(resetsAtUnix, locale);
|
|
16889
17022
|
return reset.length > 0 ? `${percent} \xB7 ${reset}` : percent;
|
|
16890
17023
|
}
|
|
16891
17024
|
function rendererUsageTriggerMaxWidth() {
|
|
@@ -16917,10 +17050,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16917
17050
|
row.append(labelElement, valueElement);
|
|
16918
17051
|
parent.append(row);
|
|
16919
17052
|
}
|
|
16920
|
-
function renderDetails(popover, usage) {
|
|
17053
|
+
function renderDetails(popover, usage, messages, locale) {
|
|
16921
17054
|
popover.replaceChildren();
|
|
16922
17055
|
const heading = document.createElement("div");
|
|
16923
|
-
heading.textContent =
|
|
17056
|
+
heading.textContent = messages.usage;
|
|
16924
17057
|
heading.style.fontWeight = "600";
|
|
16925
17058
|
heading.style.marginBottom = "6px";
|
|
16926
17059
|
popover.append(heading);
|
|
@@ -16928,55 +17061,75 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
16928
17061
|
const contextPercent = usage.contextWindowTokens > 0 ? usage.contextUsedTokens / usage.contextWindowTokens * 100 : null;
|
|
16929
17062
|
addDetailRow(
|
|
16930
17063
|
popover,
|
|
16931
|
-
|
|
17064
|
+
messages.context,
|
|
16932
17065
|
contextPercent === null ? `/${formatRendererTokenCount(usage.contextWindowTokens)}` : `${decimal(contextPercent, 1)}% / ${formatRendererTokenCount(usage.contextWindowTokens)}`
|
|
16933
17066
|
);
|
|
16934
17067
|
}
|
|
16935
17068
|
if (usage?.cacheHitRatePercent !== void 0) {
|
|
16936
17069
|
addDetailRow(
|
|
16937
17070
|
popover,
|
|
16938
|
-
|
|
17071
|
+
messages.latestCacheHit,
|
|
16939
17072
|
formatRendererCacheHitRate(usage.cacheHitRatePercent)
|
|
16940
17073
|
);
|
|
16941
17074
|
}
|
|
16942
17075
|
if (usage?.outputTokensPerSecond !== void 0) {
|
|
16943
|
-
addDetailRow(
|
|
17076
|
+
addDetailRow(
|
|
17077
|
+
popover,
|
|
17078
|
+
messages.outputSpeed,
|
|
17079
|
+
formatRendererTokenRate(usage.outputTokensPerSecond, locale)
|
|
17080
|
+
);
|
|
16944
17081
|
}
|
|
16945
17082
|
if (usage?.cachedInputTokens !== void 0) {
|
|
16946
|
-
addDetailRow(popover,
|
|
17083
|
+
addDetailRow(popover, messages.cacheRead, formatRendererTokenCount(usage.cachedInputTokens));
|
|
16947
17084
|
}
|
|
16948
17085
|
if (usage?.cacheWriteInputTokens !== void 0) {
|
|
16949
|
-
addDetailRow(
|
|
17086
|
+
addDetailRow(
|
|
17087
|
+
popover,
|
|
17088
|
+
messages.cacheWrite,
|
|
17089
|
+
formatRendererTokenCount(usage.cacheWriteInputTokens)
|
|
17090
|
+
);
|
|
16950
17091
|
}
|
|
16951
17092
|
if (usage?.reasoningOutputTokens !== void 0) {
|
|
16952
|
-
addDetailRow(
|
|
17093
|
+
addDetailRow(
|
|
17094
|
+
popover,
|
|
17095
|
+
messages.reasoning,
|
|
17096
|
+
formatRendererTokenCount(usage.reasoningOutputTokens)
|
|
17097
|
+
);
|
|
16953
17098
|
}
|
|
16954
17099
|
if (usage?.totalTokens !== void 0) {
|
|
16955
|
-
addDetailRow(popover,
|
|
17100
|
+
addDetailRow(popover, messages.totalTokens, formatRendererTokenCount(usage.totalTokens));
|
|
16956
17101
|
}
|
|
16957
17102
|
if (usage?.inputTokens !== void 0 || usage?.outputTokens !== void 0) {
|
|
16958
17103
|
addDetailRow(
|
|
16959
17104
|
popover,
|
|
16960
|
-
|
|
17105
|
+
messages.inputOutput,
|
|
16961
17106
|
`${formatRendererTokenCount(usage.inputTokens ?? 0)} / ${formatRendererTokenCount(usage.outputTokens ?? 0)}`
|
|
16962
17107
|
);
|
|
16963
17108
|
}
|
|
16964
17109
|
if (usage?.planFiveHourUsedPercent !== void 0) {
|
|
16965
17110
|
addDetailRow(
|
|
16966
17111
|
popover,
|
|
16967
|
-
|
|
16968
|
-
formatRendererPlanWindow(
|
|
17112
|
+
messages.fiveHourLimit,
|
|
17113
|
+
formatRendererPlanWindow(
|
|
17114
|
+
usage.planFiveHourUsedPercent,
|
|
17115
|
+
usage.planFiveHourResetsAtUnix,
|
|
17116
|
+
locale
|
|
17117
|
+
)
|
|
16969
17118
|
);
|
|
16970
17119
|
}
|
|
16971
17120
|
if (usage?.planSevenDayUsedPercent !== void 0) {
|
|
16972
17121
|
addDetailRow(
|
|
16973
17122
|
popover,
|
|
16974
|
-
|
|
16975
|
-
formatRendererPlanWindow(
|
|
17123
|
+
messages.sevenDayLimit,
|
|
17124
|
+
formatRendererPlanWindow(
|
|
17125
|
+
usage.planSevenDayUsedPercent,
|
|
17126
|
+
usage.planSevenDayResetsAtUnix,
|
|
17127
|
+
locale
|
|
17128
|
+
)
|
|
16976
17129
|
);
|
|
16977
17130
|
}
|
|
16978
17131
|
if (usage?.totalCostUsd !== void 0) {
|
|
16979
|
-
addDetailRow(popover,
|
|
17132
|
+
addDetailRow(popover, messages.sessionCostEstimate, formatRendererCost(usage.totalCostUsd));
|
|
16980
17133
|
}
|
|
16981
17134
|
}
|
|
16982
17135
|
function popoverIsOpen(popover) {
|
|
@@ -17017,8 +17170,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17017
17170
|
if (control.trigger.getAttribute("aria-expanded") === "true") closePopover(control);
|
|
17018
17171
|
else openPopover(control);
|
|
17019
17172
|
}
|
|
17020
|
-
function mountRendererUsageControl(composerId) {
|
|
17173
|
+
function mountRendererUsageControl(composerId, locale = "en") {
|
|
17021
17174
|
ensureRendererTriggerChipStyle(document);
|
|
17175
|
+
const messages = rendererUsageMessages(locale);
|
|
17022
17176
|
const root = document.createElement("div");
|
|
17023
17177
|
root.dataset.codexhostUsageControl = composerId;
|
|
17024
17178
|
root.className = "relative min-w-0";
|
|
@@ -17033,8 +17187,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17033
17187
|
trigger.type = "button";
|
|
17034
17188
|
trigger.setAttribute("aria-haspopup", "dialog");
|
|
17035
17189
|
trigger.setAttribute("aria-expanded", "false");
|
|
17036
|
-
trigger.setAttribute("aria-label",
|
|
17037
|
-
trigger.title =
|
|
17190
|
+
trigger.setAttribute("aria-label", messages.threadUsage);
|
|
17191
|
+
trigger.title = messages.threadUsage;
|
|
17038
17192
|
trigger.style.color = "var(--color-text-tertiary, #8f8f8f)";
|
|
17039
17193
|
trigger.style.gap = "4px";
|
|
17040
17194
|
trigger.style.width = "fit-content";
|
|
@@ -17056,7 +17210,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17056
17210
|
const popover = document.createElement("div");
|
|
17057
17211
|
popover.id = `${composerId}-usage-popover`;
|
|
17058
17212
|
popover.setAttribute("role", "dialog");
|
|
17059
|
-
popover.setAttribute("aria-label",
|
|
17213
|
+
popover.setAttribute("aria-label", messages.threadUsageDetails);
|
|
17060
17214
|
popover.setAttribute("popover", "auto");
|
|
17061
17215
|
popover.hidden = typeof popover.showPopover !== "function";
|
|
17062
17216
|
popover.style.position = "fixed";
|
|
@@ -17076,6 +17230,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17076
17230
|
popover,
|
|
17077
17231
|
anchor: null,
|
|
17078
17232
|
label,
|
|
17233
|
+
locale,
|
|
17079
17234
|
onOpen: null,
|
|
17080
17235
|
dispose() {
|
|
17081
17236
|
closePopover(control);
|
|
@@ -17130,7 +17285,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17130
17285
|
document.body.append(popover);
|
|
17131
17286
|
return control;
|
|
17132
17287
|
}
|
|
17133
|
-
function renderRendererUsageControl(control, usage) {
|
|
17288
|
+
function renderRendererUsageControl(control, usage, locale = control.locale) {
|
|
17289
|
+
control.locale = locale;
|
|
17290
|
+
const messages = rendererUsageMessages(locale);
|
|
17291
|
+
control.popover.setAttribute("aria-label", messages.threadUsageDetails);
|
|
17134
17292
|
const cacheHitRatePercent = usage?.cacheHitRatePercent;
|
|
17135
17293
|
const outputTokensPerSecond = usage?.outputTokensPerSecond;
|
|
17136
17294
|
const totalCostUsd = usage?.totalCostUsd;
|
|
@@ -17145,34 +17303,34 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17145
17303
|
}
|
|
17146
17304
|
const summary = [
|
|
17147
17305
|
cacheHitRatePercent !== void 0 ? formatRendererCacheHitRate(cacheHitRatePercent) : null,
|
|
17148
|
-
outputTokensPerSecond !== void 0 ? formatRendererTokenRate(outputTokensPerSecond) : null,
|
|
17306
|
+
outputTokensPerSecond !== void 0 ? formatRendererTokenRate(outputTokensPerSecond, locale) : null,
|
|
17149
17307
|
totalCostUsd !== void 0 ? formatRendererCost(totalCostUsd) : null
|
|
17150
17308
|
].filter((value) => value !== null);
|
|
17151
17309
|
if (summary.length === 0 && hasContext && usage?.contextWindowTokens !== void 0 && usage.contextWindowTokens > 0) {
|
|
17152
17310
|
summary.push(
|
|
17153
|
-
`${decimal((usage.contextUsedTokens ?? 0) / usage.contextWindowTokens * 100, 1)}%
|
|
17311
|
+
`${decimal((usage.contextUsedTokens ?? 0) / usage.contextWindowTokens * 100, 1)}% ${messages.contextSummary}`
|
|
17154
17312
|
);
|
|
17155
17313
|
}
|
|
17156
17314
|
if (summary.length === 0 && usage?.totalTokens !== void 0) {
|
|
17157
|
-
summary.push(`${formatRendererTokenCount(usage.totalTokens)}
|
|
17315
|
+
summary.push(`${formatRendererTokenCount(usage.totalTokens)} ${messages.tokensSummary}`);
|
|
17158
17316
|
}
|
|
17159
17317
|
if (summary.length === 0 && hasTokenUsage) {
|
|
17160
17318
|
summary.push(
|
|
17161
|
-
`${formatRendererTokenCount((usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0))}
|
|
17319
|
+
`${formatRendererTokenCount((usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0))} ${messages.tokensSummary}`
|
|
17162
17320
|
);
|
|
17163
17321
|
}
|
|
17164
17322
|
if (summary.length === 0 && hasPlanLimit) {
|
|
17165
17323
|
summary.push(
|
|
17166
|
-
usage?.planFiveHourUsedPercent !== void 0 ?
|
|
17324
|
+
usage?.planFiveHourUsedPercent !== void 0 ? `${messages.fiveHourSummary} ${formatRendererCreditsPercent(usage.planFiveHourUsedPercent)}` : `${messages.sevenDaySummary} ${formatRendererCreditsPercent(usage?.planSevenDayUsedPercent ?? 0)}`
|
|
17167
17325
|
);
|
|
17168
17326
|
}
|
|
17169
17327
|
const compactSummary = summary.join(" \xB7 ");
|
|
17170
|
-
const accessibleSummary =
|
|
17328
|
+
const accessibleSummary = `${messages.threadUsage}: ${compactSummary}`;
|
|
17171
17329
|
control.trigger.style.maxWidth = rendererUsageTriggerMaxWidth();
|
|
17172
17330
|
control.trigger.setAttribute("aria-label", accessibleSummary);
|
|
17173
17331
|
control.trigger.title = accessibleSummary;
|
|
17174
17332
|
control.label.textContent = compactSummary;
|
|
17175
|
-
renderDetails(control.popover, usage);
|
|
17333
|
+
renderDetails(control.popover, usage, messages, locale);
|
|
17176
17334
|
return true;
|
|
17177
17335
|
}
|
|
17178
17336
|
|
|
@@ -17511,12 +17669,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17511
17669
|
}
|
|
17512
17670
|
return svg;
|
|
17513
17671
|
}
|
|
17514
|
-
function menuItem(ownerDocument, command, onSelect) {
|
|
17672
|
+
function menuItem(ownerDocument, command, locale, messages, onSelect) {
|
|
17673
|
+
const presentation = rendererHarnessCommandPresentation(command, locale);
|
|
17515
17674
|
const item = ownerDocument.createElement("button");
|
|
17516
17675
|
item.type = "button";
|
|
17517
17676
|
item.setAttribute("role", "menuitem");
|
|
17518
17677
|
item.setAttribute("data-command-id", command.id);
|
|
17519
|
-
item.setAttribute("aria-label", `${command.invocation} ${
|
|
17678
|
+
item.setAttribute("aria-label", `${command.invocation} ${presentation.label}`);
|
|
17520
17679
|
item.style.display = "flex";
|
|
17521
17680
|
item.style.alignItems = "center";
|
|
17522
17681
|
item.style.width = "100%";
|
|
@@ -17547,14 +17706,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17547
17706
|
title.style.font = "600 13px/18px system-ui, sans-serif";
|
|
17548
17707
|
title.style.whiteSpace = "nowrap";
|
|
17549
17708
|
const description = ownerDocument.createElement("span");
|
|
17550
|
-
description.textContent =
|
|
17709
|
+
description.textContent = presentation.description;
|
|
17551
17710
|
description.style.overflow = "hidden";
|
|
17552
17711
|
description.style.color = "rgba(127, 127, 127, 0.9)";
|
|
17553
17712
|
description.style.font = "400 11px/16px system-ui, sans-serif";
|
|
17554
17713
|
description.style.textOverflow = "ellipsis";
|
|
17555
17714
|
description.style.whiteSpace = "nowrap";
|
|
17556
17715
|
const hint = ownerDocument.createElement("span");
|
|
17557
|
-
hint.textContent = command.argumentMode === "text" ?
|
|
17716
|
+
hint.textContent = command.argumentMode === "text" ? messages.textArgument : "\u21B5";
|
|
17558
17717
|
hint.style.flex = "0 0 auto";
|
|
17559
17718
|
hint.style.color = "rgba(127, 127, 127, 0.75)";
|
|
17560
17719
|
hint.style.font = "400 11px/16px ui-monospace, SFMono-Regular, Menlo, monospace";
|
|
@@ -17580,8 +17739,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17580
17739
|
button.style.cursor = "pointer";
|
|
17581
17740
|
button.style.whiteSpace = "nowrap";
|
|
17582
17741
|
}
|
|
17583
|
-
function mountRendererHarnessCommandControl(parent, insertBefore, onCommandSelected) {
|
|
17742
|
+
function mountRendererHarnessCommandControl(parent, insertBefore, onCommandSelected, initialLocale = "en") {
|
|
17584
17743
|
const ownerDocument = parent.ownerDocument;
|
|
17744
|
+
let locale = initialLocale;
|
|
17745
|
+
let messages = rendererHarnessMessages(locale);
|
|
17585
17746
|
const root = ownerDocument.createElement("div");
|
|
17586
17747
|
root.setAttribute(CONTROL_ATTRIBUTE2, "true");
|
|
17587
17748
|
root.style.display = "inline-flex";
|
|
@@ -17591,15 +17752,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17591
17752
|
trigger.type = "button";
|
|
17592
17753
|
trigger.setAttribute("aria-haspopup", "menu");
|
|
17593
17754
|
trigger.setAttribute("aria-expanded", "false");
|
|
17594
|
-
trigger.setAttribute("aria-label",
|
|
17595
|
-
trigger.title =
|
|
17755
|
+
trigger.setAttribute("aria-label", messages.harnessCommands);
|
|
17756
|
+
trigger.title = messages.harnessCommands;
|
|
17596
17757
|
setButtonClass(trigger);
|
|
17597
17758
|
trigger.append(commandIcon(ownerDocument));
|
|
17598
17759
|
root.append(trigger);
|
|
17599
17760
|
const menu = ownerDocument.createElement("div");
|
|
17600
17761
|
menu.setAttribute(MENU_ATTRIBUTE, "true");
|
|
17601
17762
|
menu.setAttribute("role", "menu");
|
|
17602
|
-
menu.setAttribute("aria-label",
|
|
17763
|
+
menu.setAttribute("aria-label", messages.harnessCommands);
|
|
17603
17764
|
menu.hidden = true;
|
|
17604
17765
|
menu.style.position = "fixed";
|
|
17605
17766
|
menu.style.inset = "auto";
|
|
@@ -17677,12 +17838,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17677
17838
|
const renderItems = () => {
|
|
17678
17839
|
menu.replaceChildren();
|
|
17679
17840
|
const header = ownerDocument.createElement("div");
|
|
17680
|
-
header.textContent =
|
|
17841
|
+
header.textContent = messages.commands;
|
|
17681
17842
|
header.style.padding = "5px 8px 4px";
|
|
17682
17843
|
header.style.color = "rgba(127, 127, 127, 0.75)";
|
|
17683
17844
|
header.style.font = "600 11px/16px system-ui, sans-serif";
|
|
17684
17845
|
menu.append(header);
|
|
17685
|
-
items = commands.map(
|
|
17846
|
+
items = commands.map(
|
|
17847
|
+
(command) => menuItem(ownerDocument, command, locale, messages, () => select(command))
|
|
17848
|
+
);
|
|
17686
17849
|
menu.append(...items);
|
|
17687
17850
|
activeIndex = Math.min(activeIndex, Math.max(0, items.length - 1));
|
|
17688
17851
|
if (executingCommandId !== null) {
|
|
@@ -17780,6 +17943,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
17780
17943
|
trigger.style.opacity = commandId !== null ? "0.65" : "1";
|
|
17781
17944
|
syncTriggerBackground();
|
|
17782
17945
|
},
|
|
17946
|
+
setLocale(nextLocale) {
|
|
17947
|
+
if (locale === nextLocale) return;
|
|
17948
|
+
locale = nextLocale;
|
|
17949
|
+
messages = rendererHarnessMessages(locale);
|
|
17950
|
+
trigger.setAttribute("aria-label", messages.harnessCommands);
|
|
17951
|
+
trigger.title = messages.harnessCommands;
|
|
17952
|
+
menu.setAttribute("aria-label", messages.harnessCommands);
|
|
17953
|
+
renderItems();
|
|
17954
|
+
},
|
|
17783
17955
|
close,
|
|
17784
17956
|
dispose() {
|
|
17785
17957
|
if (disposed) return;
|
|
@@ -18138,9 +18310,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18138
18310
|
refreshCreditsPlacement(control);
|
|
18139
18311
|
return control;
|
|
18140
18312
|
}
|
|
18141
|
-
function renderComposerAgentControl(control, state, adapterState, switching, availability = {}, modelView = { status: "idle" }, permissionModeView = { status: "idle" }, usage = null, accountCredits = null) {
|
|
18313
|
+
function renderComposerAgentControl(control, state, adapterState, switching, availability = {}, modelView = { status: "idle" }, permissionModeView = { status: "idle" }, usage = null, accountCredits = null, locale = "en") {
|
|
18142
18314
|
if (control.usage === null) {
|
|
18143
|
-
control.usage = mountRendererUsageControl(control.composerId);
|
|
18315
|
+
control.usage = mountRendererUsageControl(control.composerId, locale);
|
|
18144
18316
|
}
|
|
18145
18317
|
const selectedModel = modelView.selected;
|
|
18146
18318
|
const selectedCatalogModel = modelView.catalog?.models.find(
|
|
@@ -18176,9 +18348,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18176
18348
|
renderRendererPermissionModePicker(
|
|
18177
18349
|
control.permissionModePicker,
|
|
18178
18350
|
permissionModeView,
|
|
18179
|
-
permissionModeVisible
|
|
18351
|
+
permissionModeVisible,
|
|
18352
|
+
locale
|
|
18180
18353
|
);
|
|
18181
|
-
if (control.usage) renderRendererUsageControl(control.usage, usage);
|
|
18354
|
+
if (control.usage) renderRendererUsageControl(control.usage, usage, locale);
|
|
18355
|
+
control.harnessCommands.setLocale(locale);
|
|
18182
18356
|
renderRendererCreditsControl(control.credits, accountCredits);
|
|
18183
18357
|
}
|
|
18184
18358
|
function disposeComposerAgentControl(control) {
|
|
@@ -18679,7 +18853,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18679
18853
|
const parsed = hostThreadIdSchema.safeParse(params.threadId);
|
|
18680
18854
|
return parsed.success ? parsed.data : null;
|
|
18681
18855
|
}
|
|
18682
|
-
function
|
|
18856
|
+
function notificationTarget(manager) {
|
|
18683
18857
|
if (typeof manager.addNotificationCallback === "function") return manager;
|
|
18684
18858
|
const nested = manager.requestClient;
|
|
18685
18859
|
return nested && typeof nested.addNotificationCallback === "function" ? nested : null;
|
|
@@ -18780,7 +18954,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18780
18954
|
},
|
|
18781
18955
|
inspectThreadUsage,
|
|
18782
18956
|
subscribeThreadUsage(listener) {
|
|
18783
|
-
const notifications =
|
|
18957
|
+
const notifications = notificationTarget(manager);
|
|
18784
18958
|
if (!notifications?.addNotificationCallback) {
|
|
18785
18959
|
throw new Error("Renderer Usage notification callback is unavailable");
|
|
18786
18960
|
}
|
|
@@ -18956,19 +19130,33 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
18956
19130
|
...thinking?.success ? { thinkingOptionId: thinking.data } : {}
|
|
18957
19131
|
};
|
|
18958
19132
|
}
|
|
18959
|
-
function deepSeekHarnessTransportModelId(model) {
|
|
18960
|
-
if (!model)
|
|
18961
|
-
|
|
19133
|
+
function deepSeekHarnessTransportModelId(model, permissionModeId) {
|
|
19134
|
+
if (!model) {
|
|
19135
|
+
if (permissionModeId) {
|
|
19136
|
+
throw new Error("DeepSeek Harness transport Permission Mode requires a Model Ref");
|
|
19137
|
+
}
|
|
19138
|
+
return DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID;
|
|
19139
|
+
}
|
|
19140
|
+
const parsedPermissionModeId = permissionModeId ? harnessPermissionModeIdSchema.parse(permissionModeId) : void 0;
|
|
19141
|
+
return `${DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX}${harnessModelRefSchema.parse(model).id}${parsedPermissionModeId ? `@${parsedPermissionModeId}` : ""}`;
|
|
18962
19142
|
}
|
|
18963
19143
|
function decodeDeepSeekHarnessTransportModelId(value) {
|
|
18964
19144
|
if (value === DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID) return {};
|
|
18965
19145
|
if (typeof value !== "string" || !value.startsWith(DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX)) {
|
|
18966
19146
|
return null;
|
|
18967
19147
|
}
|
|
18968
|
-
const
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
19148
|
+
const components = value.slice(DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX.length).split("@");
|
|
19149
|
+
if (components.length < 1 || components.length > 2) return null;
|
|
19150
|
+
const [modelId, permissionModeId] = components;
|
|
19151
|
+
if (components.length === 2 && !permissionModeId) return null;
|
|
19152
|
+
const model = harnessModelRefSchema.safeParse({ id: modelId });
|
|
19153
|
+
if (!model.success) return null;
|
|
19154
|
+
const permissionMode = permissionModeId ? harnessPermissionModeIdSchema.safeParse(permissionModeId) : null;
|
|
19155
|
+
if (permissionMode && !permissionMode.success) return null;
|
|
19156
|
+
return {
|
|
19157
|
+
model: model.data,
|
|
19158
|
+
...permissionMode?.success ? { permissionModeId: permissionMode.data } : {}
|
|
19159
|
+
};
|
|
18972
19160
|
}
|
|
18973
19161
|
function decodePiTransportModelId(value) {
|
|
18974
19162
|
if (value === PI_TRANSPORT_MODEL_ID) return {};
|
|
@@ -19145,12 +19333,32 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19145
19333
|
const hostId = target.getHostId?.() ?? bridge.hostId;
|
|
19146
19334
|
return typeof hostId === "string" && hostId.length > 0 ? hostId : null;
|
|
19147
19335
|
}
|
|
19336
|
+
function isRendererRequestTarget(value) {
|
|
19337
|
+
if (!isRecord5(value) || typeof value.sendRequest !== "function") return false;
|
|
19338
|
+
return isCurrentRequestBridge(value.requestClient ?? value);
|
|
19339
|
+
}
|
|
19340
|
+
function hasPolicyRequestTarget(policy) {
|
|
19341
|
+
return "requestTarget" in policy;
|
|
19342
|
+
}
|
|
19343
|
+
function exactRendererRequestTarget(policy) {
|
|
19344
|
+
if (typeof policy.requestTarget !== "function") return null;
|
|
19345
|
+
try {
|
|
19346
|
+
const target = policy.requestTarget();
|
|
19347
|
+
if (!isRendererRequestTarget(target) || prewarmTargetHostId(target) !== policy.hostId) {
|
|
19348
|
+
return null;
|
|
19349
|
+
}
|
|
19350
|
+
return [target];
|
|
19351
|
+
} catch {
|
|
19352
|
+
return null;
|
|
19353
|
+
}
|
|
19354
|
+
}
|
|
19148
19355
|
function rendererRequestTargetsForHost(targets, hostId) {
|
|
19149
19356
|
const matching = targets.filter((target) => prewarmTargetHostId(target) === hostId);
|
|
19150
19357
|
return matching.length === 1 ? matching : null;
|
|
19151
19358
|
}
|
|
19152
19359
|
function activeRendererDraftPrewarmTargets(policy, targets) {
|
|
19153
19360
|
if (!isDraftPrewarmPolicyReady(policy)) return null;
|
|
19361
|
+
if (hasPolicyRequestTarget(policy)) return exactRendererRequestTarget(policy);
|
|
19154
19362
|
return rendererRequestTargetsForHost(targets, policy.hostId);
|
|
19155
19363
|
}
|
|
19156
19364
|
function resolveRendererRequestRoute(policy, discoveredTargets, previous) {
|
|
@@ -19158,13 +19366,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19158
19366
|
if (isDraftPrewarmPolicyReady(policy) && activeTargets) {
|
|
19159
19367
|
return { policy, targets: activeTargets };
|
|
19160
19368
|
}
|
|
19369
|
+
if (isDraftPrewarmPolicyReady(policy) && hasPolicyRequestTarget(policy)) return null;
|
|
19161
19370
|
return discoveredTargets.length === 0 && isDraftPrewarmPolicyReady(policy) && previous?.policy === policy ? previous : null;
|
|
19162
19371
|
}
|
|
19163
19372
|
function createRendererRequestRouteResolver(readPolicy, discoverTargets) {
|
|
19164
19373
|
let route = null;
|
|
19165
19374
|
return {
|
|
19166
19375
|
resolve() {
|
|
19167
|
-
|
|
19376
|
+
const policy = readPolicy();
|
|
19377
|
+
const discoveredTargets = isDraftPrewarmPolicyReady(policy) && hasPolicyRequestTarget(policy) ? [] : discoverTargets();
|
|
19378
|
+
route = resolveRendererRequestRoute(policy, discoveredTargets, route);
|
|
19168
19379
|
return route;
|
|
19169
19380
|
},
|
|
19170
19381
|
clear() {
|
|
@@ -19185,7 +19396,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19185
19396
|
}
|
|
19186
19397
|
}
|
|
19187
19398
|
function modelSelectionForAgent(officialSelection, reasoningEffort, agent, model, thinkingOptionId, permissionModeId) {
|
|
19188
|
-
const transportModelId = agent === "pi" ? piTransportModelId(model, thinkingOptionId) : agent === "claude-code" ? claudeTransportModelId(model, permissionModeId, thinkingOptionId) : agent === "deepseek-harness" ? deepSeekHarnessTransportModelId(model) : agent === "grok" ? grokTransportModelId(model, permissionModeId, thinkingOptionId) : agent === "omp" ? ompTransportModelId(model, thinkingOptionId) : transportModelIdForAgent(agent);
|
|
19399
|
+
const transportModelId = agent === "pi" ? piTransportModelId(model, thinkingOptionId) : agent === "claude-code" ? claudeTransportModelId(model, permissionModeId, thinkingOptionId) : agent === "deepseek-harness" ? deepSeekHarnessTransportModelId(model, permissionModeId) : agent === "grok" ? grokTransportModelId(model, permissionModeId, thinkingOptionId) : agent === "omp" ? ompTransportModelId(model, thinkingOptionId) : transportModelIdForAgent(agent);
|
|
19189
19400
|
return transportModelId ? { model: transportModelId, reasoningEffort } : officialSelection;
|
|
19190
19401
|
}
|
|
19191
19402
|
function installCurrentRendererAdapter() {
|
|
@@ -19215,7 +19426,6 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19215
19426
|
() => window.__codexhostDraftPrewarmPolicyV1,
|
|
19216
19427
|
() => findActivePrewarmTargets(document)
|
|
19217
19428
|
);
|
|
19218
|
-
const currentRequestRoute = () => requestRouteResolver.resolve();
|
|
19219
19429
|
const clientsByTarget = /* @__PURE__ */ new WeakMap();
|
|
19220
19430
|
const modelClientForTargets = (targets) => {
|
|
19221
19431
|
const target = targets[0];
|
|
@@ -19226,8 +19436,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19226
19436
|
if (client) clientsByTarget.set(target, client);
|
|
19227
19437
|
return client;
|
|
19228
19438
|
};
|
|
19439
|
+
let activeRoutePolicy = null;
|
|
19440
|
+
let activeRouteClient = null;
|
|
19441
|
+
const syncActiveRoute = (route) => {
|
|
19442
|
+
const policy = route?.policy ?? null;
|
|
19443
|
+
const client = route ? modelClientForTargets(route.targets) : null;
|
|
19444
|
+
if (activeRoutePolicy === policy && activeRouteClient === client) return client;
|
|
19445
|
+
activeRoutePolicy = policy;
|
|
19446
|
+
activeRouteClient = client;
|
|
19447
|
+
return client;
|
|
19448
|
+
};
|
|
19449
|
+
const currentRequestRoute = () => {
|
|
19450
|
+
const route = requestRouteResolver.resolve();
|
|
19451
|
+
syncActiveRoute(route);
|
|
19452
|
+
return route;
|
|
19453
|
+
};
|
|
19229
19454
|
const currentModelClient = () => {
|
|
19230
|
-
const client =
|
|
19455
|
+
const client = currentRequestRoute() ? activeRouteClient : null;
|
|
19231
19456
|
if (!client) throw new Error("Renderer Model request manager is unavailable");
|
|
19232
19457
|
usageSubscription.connect(client);
|
|
19233
19458
|
return client;
|
|
@@ -19235,6 +19460,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19235
19460
|
const modelControl = Object.freeze({
|
|
19236
19461
|
currentHostId: () => currentRequestRoute()?.policy.hostId ?? null,
|
|
19237
19462
|
clientForHost(hostId) {
|
|
19463
|
+
const route = currentRequestRoute();
|
|
19464
|
+
if (route?.policy.hostId === hostId) return modelClientForTargets(route.targets);
|
|
19465
|
+
const policy = window.__codexhostDraftPrewarmPolicyV1;
|
|
19466
|
+
if (isDraftPrewarmPolicyReady(policy) && hasPolicyRequestTarget(policy)) return null;
|
|
19238
19467
|
const targets = rendererRequestTargetsForHost(findActivePrewarmTargets(document), hostId);
|
|
19239
19468
|
return modelClientForTargets(targets ?? []);
|
|
19240
19469
|
},
|
|
@@ -19268,25 +19497,76 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19268
19497
|
});
|
|
19269
19498
|
let routingPolicy = null;
|
|
19270
19499
|
let policyTimer = null;
|
|
19500
|
+
let policyRecaptureObserver = null;
|
|
19501
|
+
let hasCapturedRoutingPolicy = false;
|
|
19502
|
+
let selectedRoutingPolicy = null;
|
|
19503
|
+
let selectedCarrier = null;
|
|
19271
19504
|
let desiredCarrier = null;
|
|
19505
|
+
const stopPolicyCapture = () => {
|
|
19506
|
+
if (policyTimer === null) return;
|
|
19507
|
+
window.clearInterval(policyTimer);
|
|
19508
|
+
policyTimer = null;
|
|
19509
|
+
};
|
|
19510
|
+
const stopPolicyRecapture = () => {
|
|
19511
|
+
policyRecaptureObserver?.disconnect();
|
|
19512
|
+
policyRecaptureObserver = null;
|
|
19513
|
+
};
|
|
19272
19514
|
const captureRoutingPolicy = () => {
|
|
19273
19515
|
const route = currentRequestRoute();
|
|
19274
19516
|
if (!route) return false;
|
|
19275
19517
|
routingPolicy = route.policy;
|
|
19276
|
-
|
|
19277
|
-
if (
|
|
19278
|
-
|
|
19279
|
-
|
|
19518
|
+
stopPolicyRecapture();
|
|
19519
|
+
if (selectedRoutingPolicy !== routingPolicy || selectedCarrier !== desiredCarrier) {
|
|
19520
|
+
try {
|
|
19521
|
+
routingPolicy.select(desiredCarrier);
|
|
19522
|
+
} catch {
|
|
19523
|
+
updateStatus("installing", "draft-routing-policy-unavailable", null);
|
|
19524
|
+
return false;
|
|
19525
|
+
}
|
|
19526
|
+
selectedRoutingPolicy = routingPolicy;
|
|
19527
|
+
selectedCarrier = desiredCarrier;
|
|
19280
19528
|
}
|
|
19529
|
+
hasCapturedRoutingPolicy = true;
|
|
19530
|
+
stopPolicyCapture();
|
|
19281
19531
|
updateStatus("ready", "ready", "request-bridge");
|
|
19282
19532
|
return true;
|
|
19283
19533
|
};
|
|
19534
|
+
const startPolicyCapture = () => {
|
|
19535
|
+
stopPolicyCapture();
|
|
19536
|
+
policyTimer = window.setInterval(captureRoutingPolicy, DRAFT_PREWARM_POLICY_POLL_INTERVAL_MS);
|
|
19537
|
+
};
|
|
19538
|
+
const startPolicyRecapture = () => {
|
|
19539
|
+
stopPolicyRecapture();
|
|
19540
|
+
policyRecaptureObserver = new MutationObserver(() => {
|
|
19541
|
+
captureRoutingPolicy();
|
|
19542
|
+
});
|
|
19543
|
+
policyRecaptureObserver.observe(document.documentElement, {
|
|
19544
|
+
attributes: true,
|
|
19545
|
+
attributeFilter: ["hidden", "aria-hidden", "data-codex-composer-root"],
|
|
19546
|
+
characterData: true,
|
|
19547
|
+
childList: true,
|
|
19548
|
+
subtree: true
|
|
19549
|
+
});
|
|
19550
|
+
};
|
|
19284
19551
|
if (!captureRoutingPolicy()) {
|
|
19285
19552
|
updateStatus("installing", "draft-routing-policy-unavailable", null);
|
|
19286
|
-
|
|
19553
|
+
const policy = window.__codexhostDraftPrewarmPolicyV1;
|
|
19554
|
+
if (!isDraftPrewarmPolicyReady(policy) || !hasPolicyRequestTarget(policy)) {
|
|
19555
|
+
startPolicyCapture();
|
|
19556
|
+
}
|
|
19287
19557
|
}
|
|
19288
19558
|
const handleRoutingPolicyChange = () => {
|
|
19289
|
-
|
|
19559
|
+
stopPolicyRecapture();
|
|
19560
|
+
if (captureRoutingPolicy()) return;
|
|
19561
|
+
const policy = window.__codexhostDraftPrewarmPolicyV1;
|
|
19562
|
+
if (isDraftPrewarmPolicyReady(policy) && hasPolicyRequestTarget(policy)) {
|
|
19563
|
+
stopPolicyCapture();
|
|
19564
|
+
}
|
|
19565
|
+
if (!hasCapturedRoutingPolicy) return;
|
|
19566
|
+
updateStatus("installing", "draft-routing-policy-unavailable", null);
|
|
19567
|
+
if (isDraftPrewarmPolicyReady(policy) && !hasPolicyRequestTarget(policy)) {
|
|
19568
|
+
startPolicyRecapture();
|
|
19569
|
+
}
|
|
19290
19570
|
};
|
|
19291
19571
|
window.addEventListener("codexhost:draft-prewarm-policy-changed", handleRoutingPolicyChange);
|
|
19292
19572
|
const applyAgent = (agent, model, thinkingOptionId, permissionModeId) => {
|
|
@@ -19305,9 +19585,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19305
19585
|
const route = currentRequestRoute();
|
|
19306
19586
|
if (!route) return false;
|
|
19307
19587
|
routingPolicy = route.policy;
|
|
19308
|
-
|
|
19309
|
-
|
|
19310
|
-
|
|
19588
|
+
try {
|
|
19589
|
+
if (route.policy.select(desiredCarrier)) {
|
|
19590
|
+
modelUpdates += 1;
|
|
19591
|
+
liveStatus.modelUpdates = modelUpdates;
|
|
19592
|
+
}
|
|
19593
|
+
selectedRoutingPolicy = route.policy;
|
|
19594
|
+
selectedCarrier = desiredCarrier;
|
|
19595
|
+
} catch {
|
|
19596
|
+
updateStatus("installing", "draft-routing-policy-unavailable", null);
|
|
19597
|
+
return false;
|
|
19311
19598
|
}
|
|
19312
19599
|
return true;
|
|
19313
19600
|
};
|
|
@@ -19318,16 +19605,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19318
19605
|
dispose() {
|
|
19319
19606
|
if (disposed) return;
|
|
19320
19607
|
disposed = true;
|
|
19321
|
-
|
|
19608
|
+
stopPolicyCapture();
|
|
19609
|
+
stopPolicyRecapture();
|
|
19322
19610
|
window.removeEventListener(
|
|
19323
19611
|
"codexhost:draft-prewarm-policy-changed",
|
|
19324
19612
|
handleRoutingPolicyChange
|
|
19325
19613
|
);
|
|
19326
|
-
routingPolicy
|
|
19614
|
+
const activeRoutingPolicy = routingPolicy;
|
|
19327
19615
|
routingPolicy = null;
|
|
19328
19616
|
requestRouteResolver.clear();
|
|
19329
|
-
|
|
19330
|
-
|
|
19617
|
+
const cleanups = [
|
|
19618
|
+
() => activeRoutingPolicy?.select(null),
|
|
19619
|
+
() => syncActiveRoute(null),
|
|
19620
|
+
() => forkControl.dispose(),
|
|
19621
|
+
() => usageSubscription.dispose()
|
|
19622
|
+
];
|
|
19623
|
+
for (const cleanup of cleanups) {
|
|
19624
|
+
try {
|
|
19625
|
+
cleanup();
|
|
19626
|
+
} catch {
|
|
19627
|
+
}
|
|
19628
|
+
}
|
|
19331
19629
|
}
|
|
19332
19630
|
};
|
|
19333
19631
|
}
|
|
@@ -19650,11 +19948,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19650
19948
|
close: "Close settings",
|
|
19651
19949
|
starOnGitHub: "Give us a Star~",
|
|
19652
19950
|
sectionsLabel: "Settings sections",
|
|
19951
|
+
generalSection: "General",
|
|
19952
|
+
otherSection: "Other",
|
|
19653
19953
|
pageUnavailable: "Page unavailable",
|
|
19654
19954
|
inDevelopment: "In development",
|
|
19655
19955
|
notAvailable: "Not available",
|
|
19656
19956
|
runtimeCapabilityNotInstalled: "This runtime capability is not installed yet.",
|
|
19657
|
-
connectionsDescription: "
|
|
19957
|
+
connectionsDescription: "View runtime status by Host. Select an item to inspect details or complete its setup.",
|
|
19658
19958
|
connectionAdapter: "Renderer adapter",
|
|
19659
19959
|
connectionHosts: "Hosts",
|
|
19660
19960
|
connectionLocalHost: "Local",
|
|
@@ -19663,9 +19963,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19663
19963
|
connectionReason: "Reason",
|
|
19664
19964
|
connectionRefresh: "Run connection diagnostics",
|
|
19665
19965
|
connectionRefreshing: "Running diagnostics...",
|
|
19666
|
-
|
|
19966
|
+
connectionViewError: "View error",
|
|
19667
19967
|
connectionCopyDetails: "Copy diagnostics",
|
|
19668
|
-
connectionCopyAll: "Copy all diagnostics",
|
|
19669
19968
|
connectionCopied: "Copied",
|
|
19670
19969
|
connectionCopyFailed: "Copy failed",
|
|
19671
19970
|
connectionErrorCode: "Error code",
|
|
@@ -19682,6 +19981,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19682
19981
|
connectionStatusError: "Error",
|
|
19683
19982
|
connectionStatusInstalling: "Installing",
|
|
19684
19983
|
connectionStatusUnsupported: "Unsupported",
|
|
19984
|
+
connectionComponent: "Component",
|
|
19985
|
+
connectionStatus: "Status",
|
|
19986
|
+
connectionHostsScrollLeft: "Show previous Hosts",
|
|
19987
|
+
connectionHostsScrollRight: "Show more Hosts",
|
|
19988
|
+
connectionOpenInstallation: "Open official installation page",
|
|
19989
|
+
connectionInstall: "Install",
|
|
19990
|
+
connectionInstallDescription: "This Harness was not detected. Follow its official installation guide, then return here and run the check again.",
|
|
19991
|
+
connectionErrorTitle: "Connection check failed",
|
|
19992
|
+
connectionErrorLog: "Error log",
|
|
19993
|
+
connectionOpenIssue: "Open GitHub Issue",
|
|
19994
|
+
connectionIssueDescription: "Copy the error log and include the Host and reproduction steps when reporting the issue.",
|
|
19995
|
+
connectionReadyDescription: "This component is available on the selected Host.",
|
|
19996
|
+
connectionUnavailableDescription: "This component is not currently available on the selected Host.",
|
|
19997
|
+
enabled: "Enabled",
|
|
19998
|
+
disabled: "Disabled",
|
|
19685
19999
|
openSettings: "Open codexhost settings",
|
|
19686
20000
|
settingsButtonTitle: "codexhost settings",
|
|
19687
20001
|
settingsUnavailableTitle: "codexhost settings unavailable",
|
|
@@ -19694,7 +20008,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19694
20008
|
updateLatestVersion: "Latest version",
|
|
19695
20009
|
updateUpToDate: "You are up to date.",
|
|
19696
20010
|
updateAvailable: "A new version is available.",
|
|
19697
|
-
|
|
20011
|
+
updateWindowsManualRequired: "Automatic updates are unavailable on Windows. Update manually below.",
|
|
20012
|
+
updateAndRestart: "Update",
|
|
19698
20013
|
updateChecking: "Checking for updates...",
|
|
19699
20014
|
updateDownloading: "Downloading update...",
|
|
19700
20015
|
updatePreparing: "Preparing update...",
|
|
@@ -19707,13 +20022,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19707
20022
|
updateFailed: "Update failed.",
|
|
19708
20023
|
updateRetry: "Retry",
|
|
19709
20024
|
updateManualNpmDescription: "To update manually, quit codexhost and run this command:",
|
|
20025
|
+
updateWindowsNpmDescription: "Automatic updates are unavailable on Windows. Quit codexhost and run this command in a terminal:",
|
|
20026
|
+
updateWindowsInstallerDescription: "Automatic updates are unavailable on Windows. Download and run the installer for this system.",
|
|
20027
|
+
updateManualTitle: "Manual update",
|
|
20028
|
+
updateManualFallbackDescription: "The automatic update did not complete. Run this command in a terminal instead, then quit Codex and relaunch it with codexhost.",
|
|
20029
|
+
updateCopyCommand: "Copy",
|
|
20030
|
+
updateCommandCopied: "Copied",
|
|
20031
|
+
updateCopyFailed: "Copy failed",
|
|
19710
20032
|
updateDownloadFromReleases: "Download from GitHub Releases",
|
|
20033
|
+
updateDownloadWindowsInstaller: "Download Windows installer",
|
|
20034
|
+
aboutTagline: "Run Pi and other Harnesses in Codex Desktop",
|
|
20035
|
+
aboutParagraphs: Object.freeze([
|
|
20036
|
+
"We believe Codex Desktop offers the best desktop development experience available today.",
|
|
20037
|
+
"But Codex is not the only excellent Agent Harness. Some developers prefer Claude Code or Pi Agent.",
|
|
20038
|
+
"codexhost lets you choose the Agent that actually executes tasks inside Codex Desktop, while preserving the native Codex experience and enabling them to collaborate."
|
|
20039
|
+
]),
|
|
20040
|
+
aboutOpenSource: "codexhost is an open-source project. The source code is available at:",
|
|
20041
|
+
aboutStarCallout: "\u2B50 If this project helps you, please give us a Star! \u2B50",
|
|
20042
|
+
aboutRepository: "Open-source repository",
|
|
19711
20043
|
pageLabels: Object.freeze({
|
|
19712
20044
|
connections: "Connections",
|
|
19713
|
-
|
|
19714
|
-
|
|
19715
|
-
gateway: "Gateway",
|
|
19716
|
-
updates: "Updates"
|
|
20045
|
+
updates: "Updates",
|
|
20046
|
+
about: "About"
|
|
19717
20047
|
})
|
|
19718
20048
|
});
|
|
19719
20049
|
var CHINESE_MESSAGES = Object.freeze({
|
|
@@ -19722,11 +20052,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19722
20052
|
close: "\u5173\u95ED\u8BBE\u7F6E",
|
|
19723
20053
|
starOnGitHub: "\u70B9\u4E2A Star~",
|
|
19724
20054
|
sectionsLabel: "\u8BBE\u7F6E\u5206\u7C7B",
|
|
20055
|
+
generalSection: "\u901A\u7528",
|
|
20056
|
+
otherSection: "\u5176\u4ED6",
|
|
19725
20057
|
pageUnavailable: "\u9875\u9762\u4E0D\u53EF\u7528",
|
|
19726
20058
|
inDevelopment: "\u5F00\u53D1\u4E2D",
|
|
19727
20059
|
notAvailable: "\u6682\u4E0D\u53EF\u7528",
|
|
19728
20060
|
runtimeCapabilityNotInstalled: "\u8FD0\u884C\u65F6\u5C1A\u672A\u5B89\u88C5\u8BE5\u9879\u80FD\u529B\uFF0C\u56E0\u6B64\u6682\u4E0D\u53EF\u7528\u3002",
|
|
19729
|
-
connectionsDescription: "\u67E5\u770B\
|
|
20061
|
+
connectionsDescription: "\u6309 Host \u67E5\u770B\u8FD0\u884C\u65F6\u72B6\u6001\u3002\u9009\u62E9\u4E00\u9879\uFF0C\u5728\u53F3\u4FA7\u68C0\u67E5\u8BE6\u60C5\u6216\u5B8C\u6210\u914D\u7F6E\u3002",
|
|
19730
20062
|
connectionAdapter: "Renderer \u9002\u914D\u5668",
|
|
19731
20063
|
connectionHosts: "Host \u5217\u8868",
|
|
19732
20064
|
connectionLocalHost: "\u672C\u5730",
|
|
@@ -19735,9 +20067,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19735
20067
|
connectionReason: "\u539F\u56E0",
|
|
19736
20068
|
connectionRefresh: "\u91CD\u65B0\u8BCA\u65AD\u8FDE\u63A5",
|
|
19737
20069
|
connectionRefreshing: "\u6B63\u5728\u8BCA\u65AD...",
|
|
19738
|
-
|
|
20070
|
+
connectionViewError: "\u67E5\u770B\u9519\u8BEF",
|
|
19739
20071
|
connectionCopyDetails: "\u590D\u5236\u8BCA\u65AD\u4FE1\u606F",
|
|
19740
|
-
connectionCopyAll: "\u590D\u5236\u5168\u90E8\u8BCA\u65AD\u4FE1\u606F",
|
|
19741
20072
|
connectionCopied: "\u5DF2\u590D\u5236",
|
|
19742
20073
|
connectionCopyFailed: "\u590D\u5236\u5931\u8D25",
|
|
19743
20074
|
connectionErrorCode: "\u9519\u8BEF\u7801",
|
|
@@ -19754,6 +20085,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19754
20085
|
connectionStatusError: "\u9519\u8BEF",
|
|
19755
20086
|
connectionStatusInstalling: "\u5B89\u88C5\u4E2D",
|
|
19756
20087
|
connectionStatusUnsupported: "\u4E0D\u652F\u6301",
|
|
20088
|
+
connectionComponent: "\u7EC4\u4EF6",
|
|
20089
|
+
connectionStatus: "\u72B6\u6001",
|
|
20090
|
+
connectionHostsScrollLeft: "\u67E5\u770B\u524D\u9762\u7684 Host",
|
|
20091
|
+
connectionHostsScrollRight: "\u67E5\u770B\u66F4\u591A Host",
|
|
20092
|
+
connectionOpenInstallation: "\u524D\u5F80\u5B98\u65B9\u5B89\u88C5\u9875\u9762",
|
|
20093
|
+
connectionInstall: "\u5B89\u88C5",
|
|
20094
|
+
connectionInstallDescription: "\u5C1A\u672A\u68C0\u6D4B\u5230\u8BE5 Harness\u3002\u8BF7\u6309\u7167\u5B98\u65B9\u5B89\u88C5\u6307\u5357\u5B8C\u6210\u5B89\u88C5\uFF0C\u7136\u540E\u8FD4\u56DE\u6B64\u9875\u9762\u91CD\u65B0\u68C0\u67E5\u3002",
|
|
20095
|
+
connectionErrorTitle: "\u8FDE\u63A5\u68C0\u67E5\u5931\u8D25",
|
|
20096
|
+
connectionErrorLog: "\u9519\u8BEF\u65E5\u5FD7",
|
|
20097
|
+
connectionOpenIssue: "\u63D0\u4EA4 GitHub Issue",
|
|
20098
|
+
connectionIssueDescription: "\u63D0\u4EA4\u524D\u8BF7\u590D\u5236\u9519\u8BEF\u65E5\u5FD7\uFF0C\u5E76\u5728 Issue \u4E2D\u8BF4\u660E\u5F53\u524D Host \u4E0E\u590D\u73B0\u6B65\u9AA4\u3002",
|
|
20099
|
+
connectionReadyDescription: "\u8BE5\u7EC4\u4EF6\u5728\u5F53\u524D Host \u4E0A\u53EF\u7528\u3002",
|
|
20100
|
+
connectionUnavailableDescription: "\u8BE5\u7EC4\u4EF6\u5F53\u524D\u65E0\u6CD5\u5728\u6240\u9009 Host \u4E0A\u4F7F\u7528\u3002",
|
|
20101
|
+
enabled: "\u5DF2\u5F00\u542F",
|
|
20102
|
+
disabled: "\u5DF2\u5173\u95ED",
|
|
19757
20103
|
openSettings: "\u6253\u5F00 codexhost \u8BBE\u7F6E",
|
|
19758
20104
|
settingsButtonTitle: "codexhost \u8BBE\u7F6E",
|
|
19759
20105
|
settingsUnavailableTitle: "codexhost \u8BBE\u7F6E\u4E0D\u53EF\u7528",
|
|
@@ -19766,7 +20112,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19766
20112
|
updateLatestVersion: "\u6700\u65B0\u7248\u672C",
|
|
19767
20113
|
updateUpToDate: "\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C\u3002",
|
|
19768
20114
|
updateAvailable: "\u6709\u65B0\u7248\u672C\u53EF\u7528\u3002",
|
|
19769
|
-
|
|
20115
|
+
updateWindowsManualRequired: "Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u66F4\u65B0\uFF0C\u8BF7\u5728\u4E0B\u65B9\u624B\u52A8\u66F4\u65B0\u3002",
|
|
20116
|
+
updateAndRestart: "\u66F4\u65B0",
|
|
19770
20117
|
updateChecking: "\u6B63\u5728\u68C0\u67E5\u66F4\u65B0...",
|
|
19771
20118
|
updateDownloading: "\u6B63\u5728\u4E0B\u8F7D\u66F4\u65B0...",
|
|
19772
20119
|
updatePreparing: "\u6B63\u5728\u51C6\u5907\u66F4\u65B0...",
|
|
@@ -19779,13 +20126,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19779
20126
|
updateFailed: "\u66F4\u65B0\u5931\u8D25\u3002",
|
|
19780
20127
|
updateRetry: "\u91CD\u8BD5",
|
|
19781
20128
|
updateManualNpmDescription: "\u5982\u9700\u624B\u52A8\u66F4\u65B0\uFF0C\u8BF7\u5728\u7EC8\u7AEF\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u3002\u66F4\u65B0\u5B8C\u6210\u540E\uFF0C\u8BF7\u9000\u51FA Codex \u5E76\u901A\u8FC7 codexhost \u91CD\u65B0\u542F\u52A8\u3002",
|
|
20129
|
+
updateWindowsNpmDescription: "Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u66F4\u65B0\u3002\u8BF7\u9000\u51FA codexhost\uFF0C\u5728\u7EC8\u7AEF\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u5B8C\u6210\u66F4\u65B0\u3002",
|
|
20130
|
+
updateWindowsInstallerDescription: "Windows \u6682\u4E0D\u652F\u6301\u81EA\u52A8\u66F4\u65B0\u3002\u8BF7\u4E0B\u8F7D\u5E76\u8FD0\u884C\u9002\u7528\u4E8E\u5F53\u524D\u7CFB\u7EDF\u7684\u5B89\u88C5\u5305\u3002",
|
|
20131
|
+
updateManualTitle: "\u624B\u52A8\u66F4\u65B0",
|
|
20132
|
+
updateManualFallbackDescription: "\u81EA\u52A8\u66F4\u65B0\u672A\u80FD\u5B8C\u6210\uFF0C\u8BF7\u6539\u7528\u4E0B\u5217\u547D\u4EE4\u5728\u7EC8\u7AEF\u624B\u52A8\u66F4\u65B0\u3002\u5B8C\u6210\u540E\u8BF7\u9000\u51FA Codex \u5E76\u901A\u8FC7 codexhost \u91CD\u65B0\u542F\u52A8\u3002",
|
|
20133
|
+
updateCopyCommand: "\u590D\u5236",
|
|
20134
|
+
updateCommandCopied: "\u5DF2\u590D\u5236",
|
|
20135
|
+
updateCopyFailed: "\u590D\u5236\u5931\u8D25",
|
|
19782
20136
|
updateDownloadFromReleases: "\u524D\u5F80 GitHub Releases \u4E0B\u8F7D",
|
|
20137
|
+
updateDownloadWindowsInstaller: "\u4E0B\u8F7D Windows \u5B89\u88C5\u5305",
|
|
20138
|
+
aboutTagline: "\u5728 Codex Desktop \u4E2D\u8FD0\u884C Pi \u548C\u5176\u4ED6 Harness",
|
|
20139
|
+
aboutParagraphs: Object.freeze([
|
|
20140
|
+
"\u6211\u4EEC\u8BA4\u4E3A Codex Desktop \u63D0\u4F9B\u4E86\u76EE\u524D\u6700\u597D\u7684\u684C\u9762\u5F00\u53D1\u4EA4\u4E92\u4F53\u9A8C\u3002",
|
|
20141
|
+
"\u4F46 Codex \u5E76\u4E0D\u662F\u552F\u4E00\u4F18\u79C0\u7684 Agent Harness\uFF0C\u4E5F\u6709\u4EBA\u504F\u597D Claude Code \u548C Pi Agent\u3002",
|
|
20142
|
+
"codexhost \u8BA9\u4F60\u5728 Codex Desktop \u4E2D\u9009\u62E9\u771F\u6B63\u6267\u884C\u4EFB\u52A1\u7684 Agent\uFF0C\u540C\u65F6\u4FDD\u7559 Codex \u7684\u539F\u751F\u4F53\u9A8C\uFF0C\u5E76\u8BA9\u5B83\u4EEC\u534F\u4F5C\u5B8C\u6210\u4EFB\u52A1\u3002"
|
|
20143
|
+
]),
|
|
20144
|
+
aboutOpenSource: "codexhost \u662F\u4E00\u4E2A\u5F00\u6E90\u9879\u76EE\uFF0C\u5F00\u6E90\u5730\u5740\uFF1A",
|
|
20145
|
+
aboutStarCallout: "\u2B50 \u5982\u679C\u8FD9\u4E2A\u9879\u76EE\u5BF9\u4F60\u6709\u5E2E\u52A9\uFF0C\u8BF7\u7ED9\u6211\u4EEC\u4E00\u4E2A Star\uFF01\u2B50",
|
|
20146
|
+
aboutRepository: "\u5F00\u6E90\u4ED3\u5E93",
|
|
19783
20147
|
pageLabels: Object.freeze({
|
|
19784
20148
|
connections: "\u8FDE\u63A5",
|
|
19785
|
-
|
|
19786
|
-
|
|
19787
|
-
gateway: "\u7F51\u5173",
|
|
19788
|
-
updates: "\u66F4\u65B0"
|
|
20149
|
+
updates: "\u66F4\u65B0",
|
|
20150
|
+
about: "\u5173\u4E8E"
|
|
19789
20151
|
})
|
|
19790
20152
|
});
|
|
19791
20153
|
var DEFAULT_RENDERER_SETTINGS_MESSAGES = ENGLISH_MESSAGES;
|
|
@@ -19839,6 +20201,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19839
20201
|
["path", { d: "M12 13.5V8" }]
|
|
19840
20202
|
];
|
|
19841
20203
|
|
|
20204
|
+
// ../../node_modules/lucide/dist/esm/icons/circle-check.mjs
|
|
20205
|
+
var CircleCheck = [
|
|
20206
|
+
["circle", { cx: "12", cy: "12", r: "10" }],
|
|
20207
|
+
["path", { d: "m9 12 2 2 4-4" }]
|
|
20208
|
+
];
|
|
20209
|
+
|
|
20210
|
+
// ../../node_modules/lucide/dist/esm/icons/chevron-left.mjs
|
|
20211
|
+
var ChevronLeft = [["path", { d: "m15 18-6-6 6-6" }]];
|
|
20212
|
+
|
|
20213
|
+
// ../../node_modules/lucide/dist/esm/icons/chevron-right.mjs
|
|
20214
|
+
var ChevronRight = [["path", { d: "m9 18 6-6-6-6" }]];
|
|
20215
|
+
|
|
19842
20216
|
// ../../node_modules/lucide/dist/esm/icons/circle-off.mjs
|
|
19843
20217
|
var CircleOff = [
|
|
19844
20218
|
["path", { d: "m2 2 20 20" }],
|
|
@@ -19866,6 +20240,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19866
20240
|
["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }]
|
|
19867
20241
|
];
|
|
19868
20242
|
|
|
20243
|
+
// ../../node_modules/lucide/dist/esm/icons/info.mjs
|
|
20244
|
+
var Info = [
|
|
20245
|
+
["circle", { cx: "12", cy: "12", r: "10" }],
|
|
20246
|
+
["path", { d: "M12 16v-4" }],
|
|
20247
|
+
["path", { d: "M12 8h.01" }]
|
|
20248
|
+
];
|
|
20249
|
+
|
|
19869
20250
|
// ../../node_modules/lucide/dist/esm/icons/languages.mjs
|
|
19870
20251
|
var Languages = [
|
|
19871
20252
|
["path", { d: "m5 8 6 6" }],
|
|
@@ -19939,6 +20320,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19939
20320
|
]
|
|
19940
20321
|
];
|
|
19941
20322
|
|
|
20323
|
+
// ../../node_modules/lucide/dist/esm/icons/triangle-alert.mjs
|
|
20324
|
+
var TriangleAlert = [
|
|
20325
|
+
["path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }],
|
|
20326
|
+
["path", { d: "M12 9v4" }],
|
|
20327
|
+
["path", { d: "M12 17h.01" }]
|
|
20328
|
+
];
|
|
20329
|
+
|
|
19942
20330
|
// ../../node_modules/lucide/dist/esm/icons/x.mjs
|
|
19943
20331
|
var X = [
|
|
19944
20332
|
["path", { d: "M18 6 6 18" }],
|
|
@@ -19959,11 +20347,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19959
20347
|
"routes",
|
|
19960
20348
|
"gateway",
|
|
19961
20349
|
"updates",
|
|
20350
|
+
"about",
|
|
19962
20351
|
"external-link",
|
|
19963
20352
|
"refresh",
|
|
19964
20353
|
"unavailable",
|
|
20354
|
+
"alert",
|
|
20355
|
+
"check",
|
|
19965
20356
|
"diagnose",
|
|
19966
|
-
"copy"
|
|
20357
|
+
"copy",
|
|
20358
|
+
"download",
|
|
20359
|
+
"chevron-left",
|
|
20360
|
+
"chevron-right"
|
|
19967
20361
|
];
|
|
19968
20362
|
var iconNodes = {
|
|
19969
20363
|
settings: Settings,
|
|
@@ -19975,11 +20369,17 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19975
20369
|
routes: Route,
|
|
19976
20370
|
gateway: Network,
|
|
19977
20371
|
updates: Download,
|
|
20372
|
+
about: Info,
|
|
19978
20373
|
"external-link": ExternalLink,
|
|
19979
20374
|
refresh: RefreshCw,
|
|
19980
20375
|
unavailable: CircleOff,
|
|
20376
|
+
alert: TriangleAlert,
|
|
20377
|
+
check: CircleCheck,
|
|
19981
20378
|
diagnose: Stethoscope,
|
|
19982
|
-
copy: Copy
|
|
20379
|
+
copy: Copy,
|
|
20380
|
+
download: Download,
|
|
20381
|
+
"chevron-left": ChevronLeft,
|
|
20382
|
+
"chevron-right": ChevronRight
|
|
19983
20383
|
};
|
|
19984
20384
|
function isRendererSettingsIconName(value) {
|
|
19985
20385
|
return RENDERER_SETTINGS_ICON_NAMES.includes(value);
|
|
@@ -20112,103 +20512,652 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
20112
20512
|
}
|
|
20113
20513
|
};
|
|
20114
20514
|
|
|
20115
|
-
// src/settings/
|
|
20116
|
-
var
|
|
20117
|
-
var
|
|
20118
|
-
|
|
20119
|
-
|
|
20120
|
-
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
function
|
|
20125
|
-
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
return
|
|
20515
|
+
// src/settings/connections-page.ts
|
|
20516
|
+
var CODEXHOST_GITHUB_ISSUES_NEW_URL = "https://github.com/BytePioneer-AI/codex-host/issues/new";
|
|
20517
|
+
var HARNESS_INSTALL_URLS = Object.freeze({
|
|
20518
|
+
pi: "https://pi.dev/",
|
|
20519
|
+
"claude-code": "https://code.claude.com/docs/en/quickstart",
|
|
20520
|
+
"deepseek-harness": "https://deepseek-harness.github.io/deepseek-harness/",
|
|
20521
|
+
grok: "https://grok.com/",
|
|
20522
|
+
omp: "https://github.com/can1357/oh-my-pi"
|
|
20523
|
+
});
|
|
20524
|
+
function connectionStatusLabel(availability, messages, hasError = false) {
|
|
20525
|
+
if (hasError && availability !== "notInstalled") return messages.connectionStatusError;
|
|
20526
|
+
if (availability === "ready") return messages.connectionStatusReady;
|
|
20527
|
+
if (availability === "checking") return messages.connectionStatusChecking;
|
|
20528
|
+
if (availability === "notInstalled") return messages.connectionStatusNotInstalled;
|
|
20529
|
+
if (availability === "unavailable" || availability === "error") {
|
|
20530
|
+
return availability === "error" ? messages.connectionStatusError : messages.connectionStatusUnavailable;
|
|
20531
|
+
}
|
|
20532
|
+
return availability === "installing" ? messages.connectionStatusInstalling : messages.connectionStatusUnsupported;
|
|
20129
20533
|
}
|
|
20130
|
-
function
|
|
20131
|
-
|
|
20132
|
-
|
|
20133
|
-
|
|
20134
|
-
|
|
20135
|
-
|
|
20136
|
-
|
|
20137
|
-
|
|
20138
|
-
|
|
20139
|
-
|
|
20140
|
-
|
|
20141
|
-
|
|
20142
|
-
|
|
20143
|
-
}
|
|
20144
|
-
|
|
20145
|
-
|
|
20146
|
-
|
|
20147
|
-
|
|
20148
|
-
|
|
20149
|
-
|
|
20150
|
-
|
|
20151
|
-
|
|
20152
|
-
|
|
20153
|
-
|
|
20154
|
-
|
|
20155
|
-
|
|
20156
|
-
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
|
|
20160
|
-
|
|
20161
|
-
|
|
20162
|
-
|
|
20163
|
-
|
|
20164
|
-
|
|
20165
|
-
|
|
20166
|
-
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
20534
|
+
function connectionStatusTone(availability, hasError = false) {
|
|
20535
|
+
if (hasError && availability !== "notInstalled") return "failed";
|
|
20536
|
+
if (availability === "ready") return "ready";
|
|
20537
|
+
if (availability === "checking" || availability === "installing") return "checking";
|
|
20538
|
+
if (availability === "notInstalled") return "setup";
|
|
20539
|
+
return "failed";
|
|
20540
|
+
}
|
|
20541
|
+
function diagnosticText(hostId, item) {
|
|
20542
|
+
const error51 = item.error;
|
|
20543
|
+
return [
|
|
20544
|
+
"codexhost connection diagnostics",
|
|
20545
|
+
`host: ${hostId}`,
|
|
20546
|
+
`agent: ${item.name}`,
|
|
20547
|
+
`status: ${item.availability}`,
|
|
20548
|
+
...error51 ? [
|
|
20549
|
+
`error.code: ${error51.code}`,
|
|
20550
|
+
`error.message: ${error51.message}`,
|
|
20551
|
+
`retryable: ${error51.retryable}`,
|
|
20552
|
+
...error51.stage ? [`stage: ${error51.stage}`] : [],
|
|
20553
|
+
...error51.durationMs !== void 0 ? [`durationMs: ${error51.durationMs}`] : [],
|
|
20554
|
+
...error51.diagnostic ? [`diagnostic: ${error51.diagnostic}`] : [],
|
|
20555
|
+
...error51.stderrTail ? [`stderr:
|
|
20556
|
+
${error51.stderrTail}`] : []
|
|
20557
|
+
] : []
|
|
20558
|
+
].join("\n");
|
|
20559
|
+
}
|
|
20560
|
+
function detailLine(document2, label, value) {
|
|
20561
|
+
const line = document2.createElement("div");
|
|
20562
|
+
line.className = "settings-connection-detail-line";
|
|
20563
|
+
const name = document2.createElement("span");
|
|
20564
|
+
name.textContent = label;
|
|
20565
|
+
const content = document2.createElement("code");
|
|
20566
|
+
content.textContent = value;
|
|
20567
|
+
line.append(name, content);
|
|
20568
|
+
return line;
|
|
20569
|
+
}
|
|
20570
|
+
function setCopyButtonLabel(button, label) {
|
|
20571
|
+
button.replaceChildren(createRendererSettingsIcon("copy", 16), label);
|
|
20572
|
+
}
|
|
20573
|
+
function showCopyButtonFeedback(button, label, restoreLabel) {
|
|
20574
|
+
setCopyButtonLabel(button, label);
|
|
20575
|
+
button.ownerDocument.defaultView?.setTimeout(() => {
|
|
20576
|
+
setCopyButtonLabel(button, restoreLabel);
|
|
20577
|
+
}, 2e3);
|
|
20578
|
+
}
|
|
20579
|
+
function copyDiagnosticsToClipboard(document2, button, report, messages, restoreLabel) {
|
|
20580
|
+
const clipboard = document2.defaultView?.navigator.clipboard;
|
|
20581
|
+
if (!clipboard) {
|
|
20582
|
+
showCopyButtonFeedback(button, messages.connectionCopyFailed, restoreLabel);
|
|
20583
|
+
return;
|
|
20171
20584
|
}
|
|
20585
|
+
void clipboard.writeText(report).then(
|
|
20586
|
+
() => showCopyButtonFeedback(button, messages.connectionCopied, restoreLabel),
|
|
20587
|
+
() => showCopyButtonFeedback(button, messages.connectionCopyFailed, restoreLabel)
|
|
20588
|
+
);
|
|
20172
20589
|
}
|
|
20173
|
-
function
|
|
20174
|
-
|
|
20175
|
-
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20590
|
+
function connectionHostName(hostId, messages) {
|
|
20591
|
+
if (hostId === "local") return messages.connectionLocalHost;
|
|
20592
|
+
const separator = hostId.lastIndexOf(":");
|
|
20593
|
+
const encodedName = separator >= 0 ? hostId.slice(separator + 1) : hostId;
|
|
20594
|
+
try {
|
|
20595
|
+
return decodeURIComponent(encodedName);
|
|
20596
|
+
} catch {
|
|
20597
|
+
return encodedName;
|
|
20179
20598
|
}
|
|
20180
|
-
if (index < lines.length) index += 1;
|
|
20181
|
-
const pre = document2.createElement("pre");
|
|
20182
|
-
const code = document2.createElement("code");
|
|
20183
|
-
if (language.length > 0) code.className = `language-${language}`;
|
|
20184
|
-
code.textContent = body.join("\n");
|
|
20185
|
-
pre.append(code);
|
|
20186
|
-
root.append(pre);
|
|
20187
|
-
return index;
|
|
20188
20599
|
}
|
|
20189
|
-
function
|
|
20190
|
-
const
|
|
20191
|
-
|
|
20192
|
-
|
|
20193
|
-
|
|
20194
|
-
|
|
20195
|
-
|
|
20196
|
-
|
|
20197
|
-
|
|
20600
|
+
function createHostScrollButton(document2, direction, messages) {
|
|
20601
|
+
const button = document2.createElement("button");
|
|
20602
|
+
button.type = "button";
|
|
20603
|
+
button.className = "settings-connection-host-scroll";
|
|
20604
|
+
button.dataset.connectionHostScroll = direction;
|
|
20605
|
+
const label = direction === "left" ? messages.connectionHostsScrollLeft : messages.connectionHostsScrollRight;
|
|
20606
|
+
button.setAttribute("aria-label", label);
|
|
20607
|
+
button.title = label;
|
|
20608
|
+
button.append(
|
|
20609
|
+
createRendererSettingsIcon(direction === "left" ? "chevron-left" : "chevron-right", 16)
|
|
20610
|
+
);
|
|
20611
|
+
return button;
|
|
20612
|
+
}
|
|
20613
|
+
function configureHostScroller(document2, strip, tabs, left, right) {
|
|
20614
|
+
const maxScrollLeft = () => Math.max(0, (tabs.scrollWidth || 0) - (tabs.clientWidth || 0));
|
|
20615
|
+
const updateButtons = () => {
|
|
20616
|
+
const maximum = maxScrollLeft();
|
|
20617
|
+
strip.dataset.connectionHostOverflow = String(maximum > 1);
|
|
20618
|
+
left.disabled = tabs.scrollLeft <= 1;
|
|
20619
|
+
right.disabled = maximum <= 1 || tabs.scrollLeft >= maximum - 1;
|
|
20620
|
+
};
|
|
20621
|
+
const scroll = (direction) => {
|
|
20622
|
+
const distance = Math.max(180, Math.round((tabs.clientWidth || 250) * 0.72));
|
|
20623
|
+
if (typeof tabs.scrollBy === "function") {
|
|
20624
|
+
tabs.scrollBy({ left: direction * distance, behavior: "smooth" });
|
|
20625
|
+
} else {
|
|
20626
|
+
tabs.scrollLeft += direction * distance;
|
|
20627
|
+
updateButtons();
|
|
20628
|
+
}
|
|
20629
|
+
};
|
|
20630
|
+
const onLeft = () => scroll(-1);
|
|
20631
|
+
const onRight = () => scroll(1);
|
|
20632
|
+
const onWheel = (event) => {
|
|
20633
|
+
const delta = Math.abs(event.deltaX) > Math.abs(event.deltaY) ? event.deltaX : event.deltaY;
|
|
20634
|
+
const maximum = maxScrollLeft();
|
|
20635
|
+
const canScroll = delta < 0 ? tabs.scrollLeft > 1 : tabs.scrollLeft < maximum - 1;
|
|
20636
|
+
if (!delta || maximum <= 1 || !canScroll) return;
|
|
20637
|
+
event.preventDefault();
|
|
20638
|
+
tabs.scrollLeft += delta;
|
|
20639
|
+
};
|
|
20640
|
+
left.addEventListener("click", onLeft);
|
|
20641
|
+
right.addEventListener("click", onRight);
|
|
20642
|
+
tabs.addEventListener("scroll", updateButtons, { passive: true });
|
|
20643
|
+
tabs.addEventListener("wheel", onWheel, { passive: false });
|
|
20644
|
+
const ownerWindow = document2.defaultView;
|
|
20645
|
+
ownerWindow?.addEventListener("resize", updateButtons);
|
|
20646
|
+
ownerWindow?.setTimeout(updateButtons, 0);
|
|
20647
|
+
updateButtons();
|
|
20648
|
+
return () => {
|
|
20649
|
+
left.removeEventListener("click", onLeft);
|
|
20650
|
+
right.removeEventListener("click", onRight);
|
|
20651
|
+
tabs.removeEventListener("scroll", updateButtons);
|
|
20652
|
+
tabs.removeEventListener("wheel", onWheel);
|
|
20653
|
+
ownerWindow?.removeEventListener("resize", updateButtons);
|
|
20654
|
+
};
|
|
20655
|
+
}
|
|
20656
|
+
function createConnectionIdentityIcon(document2, item, size) {
|
|
20657
|
+
const container = document2.createElement("span");
|
|
20658
|
+
container.className = item.agentSnapshot ? "settings-connection-row__mark settings-connection-row__mark--logo" : "settings-connection-row__mark";
|
|
20659
|
+
container.setAttribute("aria-hidden", "true");
|
|
20660
|
+
if (item.agentSnapshot) {
|
|
20661
|
+
container.append(createRendererAgentIcon(item.agentSnapshot.agent, size, document2));
|
|
20662
|
+
} else {
|
|
20663
|
+
container.textContent = "CH";
|
|
20198
20664
|
}
|
|
20199
|
-
|
|
20200
|
-
appendInline(document2, paragraph, content.join(" ").trim());
|
|
20201
|
-
blockquote.append(paragraph);
|
|
20202
|
-
root.append(blockquote);
|
|
20203
|
-
return index;
|
|
20665
|
+
return container;
|
|
20204
20666
|
}
|
|
20205
|
-
function
|
|
20206
|
-
const
|
|
20207
|
-
|
|
20208
|
-
|
|
20209
|
-
|
|
20210
|
-
|
|
20211
|
-
|
|
20667
|
+
function createConnectionRow(document2, item, messages, selected, select) {
|
|
20668
|
+
const row = document2.createElement("div");
|
|
20669
|
+
row.className = "settings-connection-row";
|
|
20670
|
+
row.dataset.connectionItem = item.key;
|
|
20671
|
+
row.dataset.connectionSelected = String(selected);
|
|
20672
|
+
row.tabIndex = selected ? 0 : -1;
|
|
20673
|
+
row.setAttribute("role", "row");
|
|
20674
|
+
const identity = document2.createElement("div");
|
|
20675
|
+
identity.className = "settings-connection-row__identity";
|
|
20676
|
+
identity.setAttribute("role", "cell");
|
|
20677
|
+
const label = document2.createElement("strong");
|
|
20678
|
+
label.textContent = item.name;
|
|
20679
|
+
identity.append(createConnectionIdentityIcon(document2, item, 19), label);
|
|
20680
|
+
const status = document2.createElement("span");
|
|
20681
|
+
status.className = "settings-connection-row__status";
|
|
20682
|
+
status.dataset.connectionTone = connectionStatusTone(item.availability, item.error !== null);
|
|
20683
|
+
status.setAttribute("role", "cell");
|
|
20684
|
+
status.textContent = connectionStatusLabel(item.availability, messages, item.error !== null);
|
|
20685
|
+
const action = document2.createElement("div");
|
|
20686
|
+
action.className = "settings-connection-row__action";
|
|
20687
|
+
action.setAttribute("role", "cell");
|
|
20688
|
+
if (item.agentSnapshot?.availability === "notInstalled") {
|
|
20689
|
+
const install = document2.createElement("a");
|
|
20690
|
+
install.className = "settings-connection-install-link";
|
|
20691
|
+
install.href = HARNESS_INSTALL_URLS[item.agentSnapshot.agent];
|
|
20692
|
+
install.target = "_blank";
|
|
20693
|
+
install.rel = "noopener noreferrer";
|
|
20694
|
+
install.setAttribute("aria-label", `${messages.connectionOpenInstallation}: ${item.name}`);
|
|
20695
|
+
install.title = messages.connectionOpenInstallation;
|
|
20696
|
+
install.append(createRendererSettingsIcon("download", 17));
|
|
20697
|
+
action.append(install);
|
|
20698
|
+
} else if (item.error) {
|
|
20699
|
+
const viewError = document2.createElement("button");
|
|
20700
|
+
viewError.type = "button";
|
|
20701
|
+
viewError.className = "settings-connection-view-error";
|
|
20702
|
+
viewError.textContent = messages.connectionViewError;
|
|
20703
|
+
viewError.addEventListener("click", (event) => {
|
|
20704
|
+
event.stopPropagation();
|
|
20705
|
+
select();
|
|
20706
|
+
});
|
|
20707
|
+
action.append(viewError);
|
|
20708
|
+
}
|
|
20709
|
+
row.addEventListener("click", (event) => {
|
|
20710
|
+
const target = event.target;
|
|
20711
|
+
if (target?.closest?.("a")) return;
|
|
20712
|
+
select();
|
|
20713
|
+
});
|
|
20714
|
+
row.addEventListener("keydown", (event) => {
|
|
20715
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
20716
|
+
event.preventDefault();
|
|
20717
|
+
select();
|
|
20718
|
+
});
|
|
20719
|
+
row.append(identity, status, action);
|
|
20720
|
+
return row;
|
|
20721
|
+
}
|
|
20722
|
+
function createInspectorHeader(document2, item, messages) {
|
|
20723
|
+
const header = document2.createElement("header");
|
|
20724
|
+
header.className = "settings-connection-inspector__header";
|
|
20725
|
+
const identity = document2.createElement("div");
|
|
20726
|
+
identity.className = "settings-connection-inspector__identity";
|
|
20727
|
+
const title = document2.createElement("strong");
|
|
20728
|
+
title.textContent = item.name;
|
|
20729
|
+
identity.append(createConnectionIdentityIcon(document2, item, 20), title);
|
|
20730
|
+
const status = document2.createElement("span");
|
|
20731
|
+
status.className = "settings-connection-row__status";
|
|
20732
|
+
status.dataset.connectionTone = connectionStatusTone(item.availability, item.error !== null);
|
|
20733
|
+
status.textContent = connectionStatusLabel(item.availability, messages, item.error !== null);
|
|
20734
|
+
header.append(identity, status);
|
|
20735
|
+
return header;
|
|
20736
|
+
}
|
|
20737
|
+
function renderConnectionInspector(document2, inspector, item, hostId, messages) {
|
|
20738
|
+
inspector.replaceChildren(createInspectorHeader(document2, item, messages));
|
|
20739
|
+
const body = document2.createElement("div");
|
|
20740
|
+
body.className = "settings-connection-inspector__body";
|
|
20741
|
+
if (item.agentSnapshot?.availability === "notInstalled") {
|
|
20742
|
+
const callout = document2.createElement("div");
|
|
20743
|
+
callout.className = "settings-connection-install-callout";
|
|
20744
|
+
const icon2 = document2.createElement("span");
|
|
20745
|
+
icon2.className = "settings-connection-install-callout__icon";
|
|
20746
|
+
icon2.append(createRendererSettingsIcon("download", 18));
|
|
20747
|
+
const copy = document2.createElement("div");
|
|
20748
|
+
const title = document2.createElement("strong");
|
|
20749
|
+
title.textContent = `${messages.connectionInstall} ${item.name}`;
|
|
20750
|
+
const description = document2.createElement("p");
|
|
20751
|
+
description.textContent = messages.connectionInstallDescription;
|
|
20752
|
+
copy.append(title, description);
|
|
20753
|
+
callout.append(icon2, copy);
|
|
20754
|
+
const install = document2.createElement("a");
|
|
20755
|
+
install.className = "settings-command-button settings-connection-install-button";
|
|
20756
|
+
install.href = HARNESS_INSTALL_URLS[item.agentSnapshot.agent];
|
|
20757
|
+
install.target = "_blank";
|
|
20758
|
+
install.rel = "noopener noreferrer";
|
|
20759
|
+
install.append(
|
|
20760
|
+
messages.connectionOpenInstallation,
|
|
20761
|
+
createRendererSettingsIcon("external-link", 14)
|
|
20762
|
+
);
|
|
20763
|
+
body.append(callout, install);
|
|
20764
|
+
} else if (item.error) {
|
|
20765
|
+
const summary = document2.createElement("div");
|
|
20766
|
+
summary.className = "settings-connection-error-summary";
|
|
20767
|
+
const title = document2.createElement("strong");
|
|
20768
|
+
title.textContent = messages.connectionErrorTitle;
|
|
20769
|
+
const description = document2.createElement("p");
|
|
20770
|
+
description.textContent = item.error.message;
|
|
20771
|
+
summary.append(title, description);
|
|
20772
|
+
const metadata = document2.createElement("div");
|
|
20773
|
+
metadata.className = "settings-connection-error-metadata";
|
|
20774
|
+
metadata.append(
|
|
20775
|
+
detailLine(document2, messages.connectionErrorCode, item.error.code),
|
|
20776
|
+
detailLine(document2, messages.connectionRetryable, String(item.error.retryable))
|
|
20777
|
+
);
|
|
20778
|
+
if (item.error.stage) {
|
|
20779
|
+
metadata.append(detailLine(document2, messages.connectionFailureStage, item.error.stage));
|
|
20780
|
+
}
|
|
20781
|
+
if (item.error.durationMs !== void 0) {
|
|
20782
|
+
metadata.append(
|
|
20783
|
+
detailLine(document2, messages.connectionDuration, `${item.error.durationMs} ms`)
|
|
20784
|
+
);
|
|
20785
|
+
}
|
|
20786
|
+
if (item.error.diagnostic) {
|
|
20787
|
+
metadata.append(detailLine(document2, messages.connectionDiagnostic, item.error.diagnostic));
|
|
20788
|
+
}
|
|
20789
|
+
const logHeader = document2.createElement("div");
|
|
20790
|
+
logHeader.className = "settings-connection-error-log-header";
|
|
20791
|
+
const logTitle = document2.createElement("strong");
|
|
20792
|
+
logTitle.textContent = messages.connectionErrorLog;
|
|
20793
|
+
const copy = document2.createElement("button");
|
|
20794
|
+
copy.type = "button";
|
|
20795
|
+
copy.className = "settings-command-button settings-command-button--secondary";
|
|
20796
|
+
setCopyButtonLabel(copy, messages.connectionCopyDetails);
|
|
20797
|
+
const report = diagnosticText(hostId, item);
|
|
20798
|
+
copy.addEventListener("click", () => {
|
|
20799
|
+
copyDiagnosticsToClipboard(document2, copy, report, messages, messages.connectionCopyDetails);
|
|
20800
|
+
});
|
|
20801
|
+
logHeader.append(logTitle, copy);
|
|
20802
|
+
const log = document2.createElement("pre");
|
|
20803
|
+
log.className = "settings-connection-stderr";
|
|
20804
|
+
log.textContent = item.error.stderrTail ?? item.error.diagnostic ?? report;
|
|
20805
|
+
const actions = document2.createElement("div");
|
|
20806
|
+
actions.className = "settings-connection-error-actions";
|
|
20807
|
+
const issue2 = document2.createElement("a");
|
|
20808
|
+
issue2.className = "settings-command-button settings-command-button--secondary";
|
|
20809
|
+
issue2.href = CODEXHOST_GITHUB_ISSUES_NEW_URL;
|
|
20810
|
+
issue2.target = "_blank";
|
|
20811
|
+
issue2.rel = "noopener noreferrer";
|
|
20812
|
+
issue2.append(messages.connectionOpenIssue, createRendererSettingsIcon("external-link", 14));
|
|
20813
|
+
actions.append(issue2);
|
|
20814
|
+
const issueNote = document2.createElement("p");
|
|
20815
|
+
issueNote.className = "settings-connection-issue-note";
|
|
20816
|
+
issueNote.textContent = messages.connectionIssueDescription;
|
|
20817
|
+
body.append(summary, metadata, logHeader, log, actions, issueNote);
|
|
20818
|
+
} else {
|
|
20819
|
+
const status = document2.createElement("div");
|
|
20820
|
+
status.className = "settings-connection-state-summary";
|
|
20821
|
+
const title = document2.createElement("strong");
|
|
20822
|
+
title.textContent = connectionStatusLabel(item.availability, messages);
|
|
20823
|
+
const description = document2.createElement("p");
|
|
20824
|
+
description.textContent = item.availability === "ready" ? messages.connectionReadyDescription : messages.connectionUnavailableDescription;
|
|
20825
|
+
status.append(title, description);
|
|
20826
|
+
body.append(status);
|
|
20827
|
+
}
|
|
20828
|
+
inspector.append(body);
|
|
20829
|
+
}
|
|
20830
|
+
function connectionItems(snapshot, host, messages) {
|
|
20831
|
+
return [
|
|
20832
|
+
{
|
|
20833
|
+
key: "renderer-adapter",
|
|
20834
|
+
name: messages.connectionAdapter,
|
|
20835
|
+
availability: snapshot.adapter.state,
|
|
20836
|
+
error: null
|
|
20837
|
+
},
|
|
20838
|
+
...host.agents.map((agent) => ({
|
|
20839
|
+
key: agent.agent,
|
|
20840
|
+
name: RENDERER_AGENT_LABELS[agent.agent],
|
|
20841
|
+
availability: agent.availability,
|
|
20842
|
+
error: agent.availability === "notInstalled" ? null : agent.error,
|
|
20843
|
+
agentSnapshot: agent
|
|
20844
|
+
}))
|
|
20845
|
+
];
|
|
20846
|
+
}
|
|
20847
|
+
function createConnectionsSettingsPage(messages, getDiagnostics) {
|
|
20848
|
+
return Object.freeze({
|
|
20849
|
+
id: "connections",
|
|
20850
|
+
label: messages.pageLabels.connections,
|
|
20851
|
+
icon: "connections",
|
|
20852
|
+
mount(context) {
|
|
20853
|
+
const document2 = context.content.ownerDocument;
|
|
20854
|
+
const header = document2.createElement("div");
|
|
20855
|
+
header.className = "settings-connection-page-header";
|
|
20856
|
+
const headingCopy = document2.createElement("div");
|
|
20857
|
+
const heading = document2.createElement("div");
|
|
20858
|
+
heading.className = "settings-section-label";
|
|
20859
|
+
heading.textContent = messages.pageLabels.connections;
|
|
20860
|
+
const description = document2.createElement("p");
|
|
20861
|
+
description.className = "settings-page-description";
|
|
20862
|
+
description.textContent = messages.connectionsDescription;
|
|
20863
|
+
headingCopy.append(heading, description);
|
|
20864
|
+
const refresh = document2.createElement("button");
|
|
20865
|
+
refresh.type = "button";
|
|
20866
|
+
refresh.className = "settings-command-button settings-command-button--secondary";
|
|
20867
|
+
refresh.dataset.connectionAction = "refresh";
|
|
20868
|
+
refresh.append(createRendererSettingsIcon("diagnose", 16), messages.connectionRefresh);
|
|
20869
|
+
header.append(headingCopy, refresh);
|
|
20870
|
+
const content = document2.createElement("div");
|
|
20871
|
+
content.className = "settings-connections-content";
|
|
20872
|
+
context.content.append(header, content);
|
|
20873
|
+
let pending = false;
|
|
20874
|
+
let selectedHostId = null;
|
|
20875
|
+
let selectedItemKey = null;
|
|
20876
|
+
let latestSnapshot = null;
|
|
20877
|
+
let disposeHostScroller = () => void 0;
|
|
20878
|
+
const diagnostics = getDiagnostics();
|
|
20879
|
+
const runRefresh = () => {
|
|
20880
|
+
if (pending || !diagnostics) return;
|
|
20881
|
+
pending = true;
|
|
20882
|
+
refresh.disabled = true;
|
|
20883
|
+
refresh.replaceChildren(
|
|
20884
|
+
createRendererSettingsIcon("diagnose", 16),
|
|
20885
|
+
messages.connectionRefreshing
|
|
20886
|
+
);
|
|
20887
|
+
void context.runLatest(() => diagnostics.refresh(), {
|
|
20888
|
+
success() {
|
|
20889
|
+
pending = false;
|
|
20890
|
+
refresh.disabled = false;
|
|
20891
|
+
refresh.replaceChildren(
|
|
20892
|
+
createRendererSettingsIcon("diagnose", 16),
|
|
20893
|
+
messages.connectionRefresh
|
|
20894
|
+
);
|
|
20895
|
+
render(diagnostics.snapshot());
|
|
20896
|
+
},
|
|
20897
|
+
failure(error51) {
|
|
20898
|
+
pending = false;
|
|
20899
|
+
refresh.disabled = false;
|
|
20900
|
+
refresh.replaceChildren(
|
|
20901
|
+
createRendererSettingsIcon("diagnose", 16),
|
|
20902
|
+
messages.connectionRefresh
|
|
20903
|
+
);
|
|
20904
|
+
const snapshot = diagnostics.snapshot();
|
|
20905
|
+
render({
|
|
20906
|
+
...snapshot,
|
|
20907
|
+
hosts: snapshot.hosts.map((host) => ({
|
|
20908
|
+
...host,
|
|
20909
|
+
agents: host.agents.map((agent) => ({
|
|
20910
|
+
...agent,
|
|
20911
|
+
availability: "error",
|
|
20912
|
+
error: {
|
|
20913
|
+
code: "internalError",
|
|
20914
|
+
message: error51 instanceof Error ? error51.message : String(error51),
|
|
20915
|
+
retryable: true,
|
|
20916
|
+
stage: "request"
|
|
20917
|
+
}
|
|
20918
|
+
}))
|
|
20919
|
+
}))
|
|
20920
|
+
});
|
|
20921
|
+
}
|
|
20922
|
+
});
|
|
20923
|
+
};
|
|
20924
|
+
const render = (snapshot) => {
|
|
20925
|
+
latestSnapshot = snapshot;
|
|
20926
|
+
disposeHostScroller();
|
|
20927
|
+
disposeHostScroller = () => void 0;
|
|
20928
|
+
content.replaceChildren();
|
|
20929
|
+
if (!snapshot) {
|
|
20930
|
+
const empty = document2.createElement("div");
|
|
20931
|
+
empty.className = "settings-empty";
|
|
20932
|
+
empty.textContent = messages.connectionNoRuntime;
|
|
20933
|
+
content.append(empty);
|
|
20934
|
+
return;
|
|
20935
|
+
}
|
|
20936
|
+
const selectedHost = (selectedHostId ? snapshot.hosts.find((host) => host.hostId === selectedHostId) : void 0) ?? snapshot.hosts.find((host) => host.active) ?? snapshot.hosts.find((host) => host.hostId === "local") ?? snapshot.hosts[0];
|
|
20937
|
+
if (!selectedHost) return;
|
|
20938
|
+
selectedHostId = selectedHost.hostId;
|
|
20939
|
+
const layout = document2.createElement("div");
|
|
20940
|
+
layout.className = "settings-connections-layout";
|
|
20941
|
+
const list = document2.createElement("section");
|
|
20942
|
+
list.className = "settings-connection-list";
|
|
20943
|
+
const hostStrip = document2.createElement("div");
|
|
20944
|
+
hostStrip.className = "settings-connection-host-strip";
|
|
20945
|
+
const scrollLeft = createHostScrollButton(document2, "left", messages);
|
|
20946
|
+
const tabs = document2.createElement("div");
|
|
20947
|
+
tabs.className = "settings-connection-host-tabs";
|
|
20948
|
+
tabs.setAttribute("role", "tablist");
|
|
20949
|
+
tabs.setAttribute("aria-label", messages.connectionHosts);
|
|
20950
|
+
const scrollRight = createHostScrollButton(document2, "right", messages);
|
|
20951
|
+
const panelId = "codexhost-settings-connection-host-panel";
|
|
20952
|
+
snapshot.hosts.forEach((host, index) => {
|
|
20953
|
+
const tab = document2.createElement("button");
|
|
20954
|
+
tab.type = "button";
|
|
20955
|
+
tab.className = "settings-connection-host-tab";
|
|
20956
|
+
tab.dataset.connectionHostTab = host.hostId;
|
|
20957
|
+
tab.dataset.connectionHostActive = String(host.active);
|
|
20958
|
+
tab.setAttribute("role", "tab");
|
|
20959
|
+
tab.setAttribute("aria-controls", panelId);
|
|
20960
|
+
tab.setAttribute("aria-selected", String(host.hostId === selectedHost.hostId));
|
|
20961
|
+
tab.tabIndex = host.hostId === selectedHost.hostId ? 0 : -1;
|
|
20962
|
+
const hostName = connectionHostName(host.hostId, messages);
|
|
20963
|
+
tab.textContent = hostName;
|
|
20964
|
+
tab.title = host.active ? `${hostName} \xB7 ${messages.connectionActiveHost}` : hostName;
|
|
20965
|
+
tab.addEventListener("click", () => {
|
|
20966
|
+
selectedHostId = host.hostId;
|
|
20967
|
+
render(latestSnapshot);
|
|
20968
|
+
});
|
|
20969
|
+
tab.addEventListener("keydown", (event) => {
|
|
20970
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
|
|
20971
|
+
event.preventDefault();
|
|
20972
|
+
const direction = event.key === "ArrowRight" ? 1 : -1;
|
|
20973
|
+
const next = snapshot.hosts[(index + direction + snapshot.hosts.length) % snapshot.hosts.length];
|
|
20974
|
+
if (!next) return;
|
|
20975
|
+
selectedHostId = next.hostId;
|
|
20976
|
+
render(latestSnapshot);
|
|
20977
|
+
const nextTab = [
|
|
20978
|
+
...content.querySelectorAll("[data-connection-host-tab]")
|
|
20979
|
+
].find((candidate) => candidate.dataset.connectionHostTab === next.hostId);
|
|
20980
|
+
nextTab?.focus();
|
|
20981
|
+
});
|
|
20982
|
+
tabs.append(tab);
|
|
20983
|
+
});
|
|
20984
|
+
hostStrip.append(scrollLeft, tabs, scrollRight);
|
|
20985
|
+
const tableHeader = document2.createElement("div");
|
|
20986
|
+
tableHeader.className = "settings-connection-table-header";
|
|
20987
|
+
tableHeader.setAttribute("role", "row");
|
|
20988
|
+
const componentHeading = document2.createElement("span");
|
|
20989
|
+
componentHeading.textContent = messages.connectionComponent;
|
|
20990
|
+
componentHeading.setAttribute("role", "columnheader");
|
|
20991
|
+
const statusHeading = document2.createElement("span");
|
|
20992
|
+
statusHeading.textContent = messages.connectionStatus;
|
|
20993
|
+
statusHeading.setAttribute("role", "columnheader");
|
|
20994
|
+
const actionHeading = document2.createElement("span");
|
|
20995
|
+
actionHeading.setAttribute("aria-hidden", "true");
|
|
20996
|
+
tableHeader.append(componentHeading, statusHeading, actionHeading);
|
|
20997
|
+
const rows = document2.createElement("div");
|
|
20998
|
+
rows.className = "settings-connection-rows";
|
|
20999
|
+
rows.id = panelId;
|
|
21000
|
+
rows.dataset.connectionHost = selectedHost.hostId;
|
|
21001
|
+
rows.setAttribute("role", "rowgroup");
|
|
21002
|
+
const inspector = document2.createElement("aside");
|
|
21003
|
+
inspector.className = "settings-connection-inspector";
|
|
21004
|
+
inspector.setAttribute("aria-live", "polite");
|
|
21005
|
+
const items = connectionItems(snapshot, selectedHost, messages);
|
|
21006
|
+
if (!items.some((item) => item.key === selectedItemKey)) {
|
|
21007
|
+
selectedItemKey = items.find(
|
|
21008
|
+
(item) => item.agentSnapshot?.availability === "notInstalled" || item.error !== null
|
|
21009
|
+
)?.key ?? items[0]?.key ?? null;
|
|
21010
|
+
}
|
|
21011
|
+
const rowElements = /* @__PURE__ */ new Map();
|
|
21012
|
+
const selectItem = (item) => {
|
|
21013
|
+
selectedItemKey = item.key;
|
|
21014
|
+
for (const [key, row] of rowElements) {
|
|
21015
|
+
const selected = key === item.key;
|
|
21016
|
+
row.dataset.connectionSelected = String(selected);
|
|
21017
|
+
row.tabIndex = selected ? 0 : -1;
|
|
21018
|
+
}
|
|
21019
|
+
renderConnectionInspector(document2, inspector, item, selectedHost.hostId, messages);
|
|
21020
|
+
};
|
|
21021
|
+
for (const item of items) {
|
|
21022
|
+
const row = createConnectionRow(
|
|
21023
|
+
document2,
|
|
21024
|
+
item,
|
|
21025
|
+
messages,
|
|
21026
|
+
item.key === selectedItemKey,
|
|
21027
|
+
() => selectItem(item)
|
|
21028
|
+
);
|
|
21029
|
+
rowElements.set(item.key, row);
|
|
21030
|
+
rows.append(row);
|
|
21031
|
+
}
|
|
21032
|
+
const selectedItem = items.find((item) => item.key === selectedItemKey) ?? items[0];
|
|
21033
|
+
if (selectedItem) selectItem(selectedItem);
|
|
21034
|
+
list.append(hostStrip, tableHeader, rows);
|
|
21035
|
+
layout.append(list, inspector);
|
|
21036
|
+
content.append(layout);
|
|
21037
|
+
disposeHostScroller = configureHostScroller(
|
|
21038
|
+
document2,
|
|
21039
|
+
hostStrip,
|
|
21040
|
+
tabs,
|
|
21041
|
+
scrollLeft,
|
|
21042
|
+
scrollRight
|
|
21043
|
+
);
|
|
21044
|
+
const selectedTab = [...tabs.children].find(
|
|
21045
|
+
(child) => child.getAttribute("aria-selected") === "true"
|
|
21046
|
+
);
|
|
21047
|
+
selectedTab?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
21048
|
+
};
|
|
21049
|
+
render(diagnostics?.snapshot() ?? null);
|
|
21050
|
+
if (!diagnostics) {
|
|
21051
|
+
refresh.disabled = true;
|
|
21052
|
+
return void 0;
|
|
21053
|
+
}
|
|
21054
|
+
refresh.addEventListener("click", runRefresh);
|
|
21055
|
+
const unsubscribe = diagnostics.subscribe(() => render(diagnostics.snapshot()));
|
|
21056
|
+
return () => {
|
|
21057
|
+
disposeHostScroller();
|
|
21058
|
+
unsubscribe();
|
|
21059
|
+
};
|
|
21060
|
+
}
|
|
21061
|
+
});
|
|
21062
|
+
}
|
|
21063
|
+
|
|
21064
|
+
// src/settings/release-notes.ts
|
|
21065
|
+
var HEADING_PATTERN = /^(#{1,6})[ \t]+(.+?)\s*$/u;
|
|
21066
|
+
var BLOCKQUOTE_PATTERN = /^>[ \t]?(.*?)\s*$/u;
|
|
21067
|
+
var UNORDERED_ITEM_PATTERN = /^[-*][ \t]+(.+?)\s*$/u;
|
|
21068
|
+
var CONTINUATION_PATTERN = /^[ \t]+(.+?)\s*$/u;
|
|
21069
|
+
var ORDERED_ITEM_PATTERN = /^\d+[.)][ \t]+(.+?)\s*$/u;
|
|
21070
|
+
var FENCE_PATTERN = /^```([\w+-]*)\s*$/u;
|
|
21071
|
+
var THEMATIC_BREAK_PATTERN = /^(?:---|___|\*\*\*)[ \t]*$/u;
|
|
21072
|
+
var INLINE_PATTERN = /(`+)((?:(?!\1).)+)\1|\*\*(.+?)\*\*|\[([^\]]+)\]\(([^)\s]+)\)/gu;
|
|
21073
|
+
function createReleaseNotesElement(document2, markdown) {
|
|
21074
|
+
const root = document2.createElement("div");
|
|
21075
|
+
root.className = "settings-update-notes";
|
|
21076
|
+
appendReleaseNotesBlocks(document2, root, markdown);
|
|
21077
|
+
return root;
|
|
21078
|
+
}
|
|
21079
|
+
function appendReleaseNotesBlocks(document2, root, markdown) {
|
|
21080
|
+
const lines = markdown.replaceAll("\r\n", "\n").split("\n");
|
|
21081
|
+
let index = 0;
|
|
21082
|
+
while (index < lines.length) {
|
|
21083
|
+
const line = lines[index] ?? "";
|
|
21084
|
+
if (line.trim().length === 0) {
|
|
21085
|
+
index += 1;
|
|
21086
|
+
continue;
|
|
21087
|
+
}
|
|
21088
|
+
const fence = FENCE_PATTERN.exec(line);
|
|
21089
|
+
if (fence) {
|
|
21090
|
+
index = appendFencedCode(document2, root, lines, index, fence[1] ?? "");
|
|
21091
|
+
continue;
|
|
21092
|
+
}
|
|
21093
|
+
const heading = HEADING_PATTERN.exec(line);
|
|
21094
|
+
if (heading?.[1] && heading[2]) {
|
|
21095
|
+
const tag = `h${heading[1].length}`;
|
|
21096
|
+
const element = document2.createElement(tag);
|
|
21097
|
+
appendInline(document2, element, heading[2]);
|
|
21098
|
+
root.append(element);
|
|
21099
|
+
index += 1;
|
|
21100
|
+
continue;
|
|
21101
|
+
}
|
|
21102
|
+
if (BLOCKQUOTE_PATTERN.test(line)) {
|
|
21103
|
+
index = appendBlockquote(document2, root, lines, index);
|
|
21104
|
+
continue;
|
|
21105
|
+
}
|
|
21106
|
+
if (THEMATIC_BREAK_PATTERN.test(line)) {
|
|
21107
|
+
root.append(document2.createElement("hr"));
|
|
21108
|
+
index += 1;
|
|
21109
|
+
continue;
|
|
21110
|
+
}
|
|
21111
|
+
if (UNORDERED_ITEM_PATTERN.test(line)) {
|
|
21112
|
+
index = appendList(document2, root, lines, index, "ul", UNORDERED_ITEM_PATTERN);
|
|
21113
|
+
continue;
|
|
21114
|
+
}
|
|
21115
|
+
if (ORDERED_ITEM_PATTERN.test(line)) {
|
|
21116
|
+
index = appendList(document2, root, lines, index, "ol", ORDERED_ITEM_PATTERN);
|
|
21117
|
+
continue;
|
|
21118
|
+
}
|
|
21119
|
+
index = appendParagraph(document2, root, lines, index);
|
|
21120
|
+
}
|
|
21121
|
+
}
|
|
21122
|
+
function appendFencedCode(document2, root, lines, start, language) {
|
|
21123
|
+
const body = [];
|
|
21124
|
+
let index = start + 1;
|
|
21125
|
+
while (index < lines.length && !FENCE_PATTERN.test(lines[index] ?? "")) {
|
|
21126
|
+
body.push(lines[index] ?? "");
|
|
21127
|
+
index += 1;
|
|
21128
|
+
}
|
|
21129
|
+
if (index < lines.length) index += 1;
|
|
21130
|
+
const pre = document2.createElement("pre");
|
|
21131
|
+
const code = document2.createElement("code");
|
|
21132
|
+
if (language.length > 0) code.className = `language-${language}`;
|
|
21133
|
+
code.textContent = body.join("\n");
|
|
21134
|
+
pre.append(code);
|
|
21135
|
+
root.append(pre);
|
|
21136
|
+
return index;
|
|
21137
|
+
}
|
|
21138
|
+
function appendBlockquote(document2, root, lines, start) {
|
|
21139
|
+
const blockquote = document2.createElement("blockquote");
|
|
21140
|
+
const content = [];
|
|
21141
|
+
let index = start;
|
|
21142
|
+
while (index < lines.length) {
|
|
21143
|
+
const match = BLOCKQUOTE_PATTERN.exec(lines[index] ?? "");
|
|
21144
|
+
if (!match) break;
|
|
21145
|
+
content.push(match[1] ?? "");
|
|
21146
|
+
index += 1;
|
|
21147
|
+
}
|
|
21148
|
+
const paragraph = document2.createElement("p");
|
|
21149
|
+
appendInline(document2, paragraph, content.join(" ").trim());
|
|
21150
|
+
blockquote.append(paragraph);
|
|
21151
|
+
root.append(blockquote);
|
|
21152
|
+
return index;
|
|
21153
|
+
}
|
|
21154
|
+
function appendList(document2, root, lines, start, tag, pattern) {
|
|
21155
|
+
const list = document2.createElement(tag);
|
|
21156
|
+
let index = start;
|
|
21157
|
+
while (index < lines.length) {
|
|
21158
|
+
const item = pattern.exec(lines[index] ?? "");
|
|
21159
|
+
if (!item?.[1]) break;
|
|
21160
|
+
const entry = document2.createElement("li");
|
|
20212
21161
|
appendInline(document2, entry, item[1]);
|
|
20213
21162
|
index += 1;
|
|
20214
21163
|
const continuationLines = [];
|
|
@@ -20266,427 +21215,110 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
20266
21215
|
if (!isSafeLink(href)) {
|
|
20267
21216
|
parent.append(match[4] ?? "");
|
|
20268
21217
|
} else {
|
|
20269
|
-
const link = document2.createElement("a");
|
|
20270
|
-
link.textContent = match[4] ?? "";
|
|
20271
|
-
link.setAttribute("href", href);
|
|
20272
|
-
link.setAttribute("target", "_blank");
|
|
20273
|
-
link.setAttribute("rel", "noopener noreferrer");
|
|
20274
|
-
parent.append(link);
|
|
20275
|
-
}
|
|
20276
|
-
}
|
|
20277
|
-
lastIndex = index + match[0].length;
|
|
20278
|
-
}
|
|
20279
|
-
if (lastIndex < text.length) parent.append(text.slice(lastIndex));
|
|
20280
|
-
}
|
|
20281
|
-
function isSafeLink(href) {
|
|
20282
|
-
try {
|
|
20283
|
-
const url2 = new URL(href, "https://codexhost.invalid");
|
|
20284
|
-
return url2.protocol === "http:" || url2.protocol === "https:";
|
|
20285
|
-
} catch {
|
|
20286
|
-
return false;
|
|
20287
|
-
}
|
|
20288
|
-
}
|
|
20289
|
-
|
|
20290
|
-
// src/settings/update-request.ts
|
|
20291
|
-
var RENDERER_UPDATE_REQUEST_TIMEOUT_MS = 15e3;
|
|
20292
|
-
var RendererUpdateRequestTimeoutError = class extends Error {
|
|
20293
|
-
constructor() {
|
|
20294
|
-
super("Update request timed out");
|
|
20295
|
-
this.name = "RendererUpdateRequestTimeoutError";
|
|
20296
|
-
}
|
|
20297
|
-
};
|
|
20298
|
-
function runBoundedRendererUpdateRequest(operation, signal, timeoutMs = RENDERER_UPDATE_REQUEST_TIMEOUT_MS) {
|
|
20299
|
-
return new Promise((resolve, reject) => {
|
|
20300
|
-
let settled = false;
|
|
20301
|
-
const settle = (handler) => {
|
|
20302
|
-
if (settled) return;
|
|
20303
|
-
settled = true;
|
|
20304
|
-
clearTimeout(timeout);
|
|
20305
|
-
signal.removeEventListener("abort", abort);
|
|
20306
|
-
handler();
|
|
20307
|
-
};
|
|
20308
|
-
const timeout = setTimeout(() => {
|
|
20309
|
-
settle(() => reject(new RendererUpdateRequestTimeoutError()));
|
|
20310
|
-
}, timeoutMs);
|
|
20311
|
-
const abort = () => {
|
|
20312
|
-
settle(() => reject(new Error("Update request was aborted")));
|
|
20313
|
-
};
|
|
20314
|
-
const rejectRequest = (error51) => {
|
|
20315
|
-
settle(() => reject(error51));
|
|
20316
|
-
};
|
|
20317
|
-
if (signal.aborted) {
|
|
20318
|
-
abort();
|
|
20319
|
-
return;
|
|
20320
|
-
}
|
|
20321
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
20322
|
-
try {
|
|
20323
|
-
void operation().then(
|
|
20324
|
-
(value) => settle(() => resolve(value)),
|
|
20325
|
-
(error51) => rejectRequest(error51)
|
|
20326
|
-
);
|
|
20327
|
-
} catch (error51) {
|
|
20328
|
-
rejectRequest(error51);
|
|
20329
|
-
}
|
|
20330
|
-
});
|
|
20331
|
-
}
|
|
20332
|
-
|
|
20333
|
-
// src/settings/pages.ts
|
|
20334
|
-
var CODEXHOST_RELEASES_LATEST_URL = "https://github.com/BytePioneer-AI/codex-host/releases/latest";
|
|
20335
|
-
var CODEXHOST_NPM_MANUAL_UPDATE_COMMAND = "npm install -g @codexhost/cli@latest";
|
|
20336
|
-
var DEFAULT_RENDERER_SETTINGS_PAGE_IDS = [
|
|
20337
|
-
"connections",
|
|
20338
|
-
"model-pool",
|
|
20339
|
-
"routes",
|
|
20340
|
-
"gateway",
|
|
20341
|
-
"updates"
|
|
20342
|
-
];
|
|
20343
|
-
function appendUnavailableStatus(content, messages) {
|
|
20344
|
-
const status = content.ownerDocument.createElement("div");
|
|
20345
|
-
status.className = "settings-empty";
|
|
20346
|
-
const copy = content.ownerDocument.createElement("div");
|
|
20347
|
-
const title = content.ownerDocument.createElement("strong");
|
|
20348
|
-
title.textContent = messages.inDevelopment;
|
|
20349
|
-
copy.append(title);
|
|
20350
|
-
status.append(copy);
|
|
20351
|
-
content.append(status);
|
|
20352
|
-
}
|
|
20353
|
-
function unavailablePage(id, messages) {
|
|
20354
|
-
return Object.freeze({
|
|
20355
|
-
id,
|
|
20356
|
-
label: messages.pageLabels[id],
|
|
20357
|
-
icon: id,
|
|
20358
|
-
mount(context) {
|
|
20359
|
-
appendUnavailableStatus(context.content, messages);
|
|
20360
|
-
return void 0;
|
|
20361
|
-
}
|
|
20362
|
-
});
|
|
20363
|
-
}
|
|
20364
|
-
function connectionStatusLabel(availability, messages) {
|
|
20365
|
-
if (availability === "ready") return messages.connectionStatusReady;
|
|
20366
|
-
if (availability === "checking") return messages.connectionStatusChecking;
|
|
20367
|
-
if (availability === "notInstalled") return messages.connectionStatusNotInstalled;
|
|
20368
|
-
if (availability === "unavailable" || availability === "error") {
|
|
20369
|
-
return availability === "error" ? messages.connectionStatusError : messages.connectionStatusUnavailable;
|
|
20370
|
-
}
|
|
20371
|
-
return availability === "installing" ? messages.connectionStatusInstalling : messages.connectionStatusUnsupported;
|
|
20372
|
-
}
|
|
20373
|
-
function connectionStatusTone(availability) {
|
|
20374
|
-
if (availability === "ready") return "ready";
|
|
20375
|
-
if (availability === "checking" || availability === "installing") return "checking";
|
|
20376
|
-
return "failed";
|
|
20377
|
-
}
|
|
20378
|
-
function diagnosticText(hostId, name, snapshot) {
|
|
20379
|
-
const error51 = snapshot.error;
|
|
20380
|
-
const lines = [
|
|
20381
|
-
"codexhost connection diagnostics",
|
|
20382
|
-
`host: ${hostId}`,
|
|
20383
|
-
`agent: ${name}`,
|
|
20384
|
-
`status: ${snapshot.availability}`,
|
|
20385
|
-
...error51 ? [
|
|
20386
|
-
`error.code: ${error51.code}`,
|
|
20387
|
-
`error.message: ${error51.message}`,
|
|
20388
|
-
`retryable: ${error51.retryable}`,
|
|
20389
|
-
...error51.stage ? [`stage: ${error51.stage}`] : [],
|
|
20390
|
-
...error51.durationMs !== void 0 ? [`durationMs: ${error51.durationMs}`] : [],
|
|
20391
|
-
...error51.diagnostic ? [`diagnostic: ${error51.diagnostic}`] : [],
|
|
20392
|
-
...error51.stderrTail ? [`stderr:
|
|
20393
|
-
${error51.stderrTail}`] : []
|
|
20394
|
-
] : []
|
|
20395
|
-
];
|
|
20396
|
-
return lines.join("\n");
|
|
20397
|
-
}
|
|
20398
|
-
function detailLine(document2, label, value) {
|
|
20399
|
-
const line = document2.createElement("div");
|
|
20400
|
-
line.className = "settings-connection-detail-line";
|
|
20401
|
-
const name = document2.createElement("span");
|
|
20402
|
-
name.textContent = label;
|
|
20403
|
-
const content = document2.createElement("code");
|
|
20404
|
-
content.textContent = value;
|
|
20405
|
-
line.append(name, content);
|
|
20406
|
-
return line;
|
|
20407
|
-
}
|
|
20408
|
-
function setCopyButtonLabel(button, label) {
|
|
20409
|
-
button.replaceChildren(createRendererSettingsIcon("copy", 16), label);
|
|
20410
|
-
}
|
|
20411
|
-
function showCopyButtonFeedback(button, label, restoreLabel) {
|
|
20412
|
-
setCopyButtonLabel(button, label);
|
|
20413
|
-
button.ownerDocument.defaultView?.setTimeout(() => {
|
|
20414
|
-
setCopyButtonLabel(button, restoreLabel);
|
|
20415
|
-
}, 2e3);
|
|
20416
|
-
}
|
|
20417
|
-
function copyDiagnosticsToClipboard(document2, button, report, messages, restoreLabel) {
|
|
20418
|
-
const clipboard = document2.defaultView?.navigator.clipboard;
|
|
20419
|
-
if (!clipboard) {
|
|
20420
|
-
showCopyButtonFeedback(button, messages.connectionCopyFailed, restoreLabel);
|
|
20421
|
-
return;
|
|
20422
|
-
}
|
|
20423
|
-
void clipboard.writeText(report).then(
|
|
20424
|
-
() => showCopyButtonFeedback(button, messages.connectionCopied, restoreLabel),
|
|
20425
|
-
() => showCopyButtonFeedback(button, messages.connectionCopyFailed, restoreLabel)
|
|
20426
|
-
);
|
|
20427
|
-
}
|
|
20428
|
-
function appendConnectionRow(document2, parent, name, availability, detail, error51, messages, rowAttribute, diagnosticSnapshot, diagnosticHostId) {
|
|
20429
|
-
const row = document2.createElement("div");
|
|
20430
|
-
row.className = "settings-connection-row";
|
|
20431
|
-
if (rowAttribute) row.dataset.connectionAgent = rowAttribute;
|
|
20432
|
-
const identity = document2.createElement("div");
|
|
20433
|
-
identity.className = "settings-connection-row__identity";
|
|
20434
|
-
const dot = document2.createElement("span");
|
|
20435
|
-
dot.className = "settings-connection-row__dot";
|
|
20436
|
-
dot.dataset.connectionTone = connectionStatusTone(availability);
|
|
20437
|
-
dot.setAttribute("aria-hidden", "true");
|
|
20438
|
-
const label = document2.createElement("strong");
|
|
20439
|
-
label.textContent = name;
|
|
20440
|
-
identity.append(dot, label);
|
|
20441
|
-
const status = document2.createElement("span");
|
|
20442
|
-
status.className = "settings-status-badge";
|
|
20443
|
-
status.dataset.connectionTone = connectionStatusTone(availability);
|
|
20444
|
-
status.textContent = connectionStatusLabel(availability, messages);
|
|
20445
|
-
const detailElement = document2.createElement("div");
|
|
20446
|
-
detailElement.className = "settings-connection-row__detail";
|
|
20447
|
-
const summary = document2.createElement("span");
|
|
20448
|
-
summary.className = "settings-connection-row__reason";
|
|
20449
|
-
summary.textContent = error51 ? `${messages.connectionReason}: ${error51.code}: ${error51.message}` : detail ? `${messages.connectionReason}: ${detail}` : "";
|
|
20450
|
-
detailElement.append(summary);
|
|
20451
|
-
let toggle = null;
|
|
20452
|
-
if (error51) {
|
|
20453
|
-
toggle = document2.createElement("button");
|
|
20454
|
-
toggle.type = "button";
|
|
20455
|
-
toggle.className = "settings-connection-details-toggle";
|
|
20456
|
-
toggle.textContent = messages.connectionViewDetails;
|
|
20457
|
-
toggle.setAttribute("aria-expanded", "true");
|
|
20458
|
-
detailElement.append(toggle);
|
|
20459
|
-
}
|
|
20460
|
-
const details = document2.createElement("div");
|
|
20461
|
-
details.className = "settings-connection-details";
|
|
20462
|
-
details.hidden = !error51;
|
|
20463
|
-
if (error51) {
|
|
20464
|
-
details.append(
|
|
20465
|
-
detailLine(document2, messages.connectionErrorCode, error51.code),
|
|
20466
|
-
detailLine(document2, messages.connectionErrorMessage, error51.message),
|
|
20467
|
-
detailLine(document2, messages.connectionRetryable, String(error51.retryable))
|
|
20468
|
-
);
|
|
20469
|
-
if (error51.stage)
|
|
20470
|
-
details.append(detailLine(document2, messages.connectionFailureStage, error51.stage));
|
|
20471
|
-
if (error51.durationMs !== void 0) {
|
|
20472
|
-
details.append(detailLine(document2, messages.connectionDuration, `${error51.durationMs} ms`));
|
|
20473
|
-
}
|
|
20474
|
-
if (error51.diagnostic)
|
|
20475
|
-
details.append(detailLine(document2, messages.connectionDiagnostic, error51.diagnostic));
|
|
20476
|
-
if (error51.stderrTail) {
|
|
20477
|
-
const stderr = document2.createElement("pre");
|
|
20478
|
-
stderr.className = "settings-connection-stderr";
|
|
20479
|
-
stderr.textContent = error51.stderrTail;
|
|
20480
|
-
details.append(stderr);
|
|
21218
|
+
const link = document2.createElement("a");
|
|
21219
|
+
link.textContent = match[4] ?? "";
|
|
21220
|
+
link.setAttribute("href", href);
|
|
21221
|
+
link.setAttribute("target", "_blank");
|
|
21222
|
+
link.setAttribute("rel", "noopener noreferrer");
|
|
21223
|
+
parent.append(link);
|
|
21224
|
+
}
|
|
20481
21225
|
}
|
|
20482
|
-
|
|
20483
|
-
copy.type = "button";
|
|
20484
|
-
copy.className = "settings-command-button settings-command-button--secondary";
|
|
20485
|
-
setCopyButtonLabel(copy, messages.connectionCopyDetails);
|
|
20486
|
-
copy.addEventListener("click", () => {
|
|
20487
|
-
if (!diagnosticSnapshot) return;
|
|
20488
|
-
copyDiagnosticsToClipboard(
|
|
20489
|
-
document2,
|
|
20490
|
-
copy,
|
|
20491
|
-
diagnosticText(diagnosticHostId ?? "unknown", name, diagnosticSnapshot),
|
|
20492
|
-
messages,
|
|
20493
|
-
messages.connectionCopyDetails
|
|
20494
|
-
);
|
|
20495
|
-
});
|
|
20496
|
-
details.append(copy);
|
|
20497
|
-
}
|
|
20498
|
-
if (toggle) {
|
|
20499
|
-
toggle.addEventListener("click", () => {
|
|
20500
|
-
details.hidden = !details.hidden;
|
|
20501
|
-
toggle?.setAttribute("aria-expanded", String(!details.hidden));
|
|
20502
|
-
});
|
|
21226
|
+
lastIndex = index + match[0].length;
|
|
20503
21227
|
}
|
|
20504
|
-
|
|
20505
|
-
parent.append(row);
|
|
21228
|
+
if (lastIndex < text.length) parent.append(text.slice(lastIndex));
|
|
20506
21229
|
}
|
|
20507
|
-
function
|
|
20508
|
-
const activeLabel = active ? ` \xB7 ${messages.connectionActiveHost}` : "";
|
|
20509
|
-
if (hostId === "local") return `${messages.connectionLocalHost}${activeLabel}`;
|
|
20510
|
-
const separator = hostId.lastIndexOf(":");
|
|
20511
|
-
const encodedName = separator >= 0 ? hostId.slice(separator + 1) : hostId;
|
|
20512
|
-
let name = encodedName;
|
|
21230
|
+
function isSafeLink(href) {
|
|
20513
21231
|
try {
|
|
20514
|
-
|
|
21232
|
+
const url2 = new URL(href, "https://codexhost.invalid");
|
|
21233
|
+
return url2.protocol === "http:" || url2.protocol === "https:";
|
|
20515
21234
|
} catch {
|
|
21235
|
+
return false;
|
|
20516
21236
|
}
|
|
20517
|
-
return `${messages.connectionRemoteHost}: ${name}${activeLabel}`;
|
|
20518
21237
|
}
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20528
|
-
|
|
20529
|
-
|
|
20530
|
-
|
|
20531
|
-
|
|
20532
|
-
|
|
20533
|
-
|
|
20534
|
-
|
|
20535
|
-
|
|
20536
|
-
|
|
20537
|
-
|
|
20538
|
-
|
|
20539
|
-
|
|
20540
|
-
|
|
20541
|
-
|
|
20542
|
-
|
|
20543
|
-
|
|
20544
|
-
|
|
20545
|
-
|
|
20546
|
-
|
|
20547
|
-
|
|
20548
|
-
|
|
20549
|
-
|
|
20550
|
-
|
|
20551
|
-
|
|
20552
|
-
|
|
20553
|
-
|
|
20554
|
-
|
|
20555
|
-
|
|
20556
|
-
|
|
20557
|
-
|
|
20558
|
-
|
|
20559
|
-
return;
|
|
20560
|
-
}
|
|
20561
|
-
appendConnectionRow(
|
|
20562
|
-
document2,
|
|
20563
|
-
content,
|
|
20564
|
-
messages.connectionAdapter,
|
|
20565
|
-
snapshot.adapter.state,
|
|
20566
|
-
`reason=${snapshot.adapter.reason}, hook=${snapshot.adapter.hook ?? "none"}`,
|
|
20567
|
-
null,
|
|
20568
|
-
messages,
|
|
20569
|
-
"renderer-adapter"
|
|
20570
|
-
);
|
|
20571
|
-
const selectedHost = snapshot.hosts.find((host) => host.hostId === selectedHostId) ?? snapshot.hosts.find((host) => host.hostId === "local") ?? snapshot.hosts[0];
|
|
20572
|
-
if (!selectedHost) return;
|
|
20573
|
-
selectedHostId = selectedHost.hostId;
|
|
20574
|
-
const tabs = document2.createElement("div");
|
|
20575
|
-
tabs.className = "settings-connection-host-tabs";
|
|
20576
|
-
tabs.setAttribute("role", "tablist");
|
|
20577
|
-
tabs.setAttribute("aria-label", messages.connectionHosts);
|
|
20578
|
-
const hostSection = document2.createElement("section");
|
|
20579
|
-
hostSection.className = "settings-connection-host";
|
|
20580
|
-
hostSection.dataset.connectionHost = selectedHost.hostId;
|
|
20581
|
-
hostSection.setAttribute("role", "tabpanel");
|
|
20582
|
-
const panelId = "codexhost-settings-connection-host-panel";
|
|
20583
|
-
hostSection.id = panelId;
|
|
20584
|
-
for (const host of snapshot.hosts) {
|
|
20585
|
-
const tab = document2.createElement("button");
|
|
20586
|
-
tab.type = "button";
|
|
20587
|
-
tab.className = "settings-connection-host-tab";
|
|
20588
|
-
tab.dataset.connectionHostTab = host.hostId;
|
|
20589
|
-
tab.setAttribute("role", "tab");
|
|
20590
|
-
tab.setAttribute("aria-controls", panelId);
|
|
20591
|
-
tab.setAttribute("aria-selected", String(host.hostId === selectedHost.hostId));
|
|
20592
|
-
tab.tabIndex = host.hostId === selectedHost.hostId ? 0 : -1;
|
|
20593
|
-
tab.textContent = connectionHostLabel(host.hostId, host.active, messages);
|
|
20594
|
-
tab.addEventListener("click", () => {
|
|
20595
|
-
selectedHostId = host.hostId;
|
|
20596
|
-
render(latestSnapshot);
|
|
20597
|
-
});
|
|
20598
|
-
tabs.append(tab);
|
|
20599
|
-
}
|
|
20600
|
-
for (const agent of selectedHost.agents) {
|
|
20601
|
-
appendConnectionRow(
|
|
20602
|
-
document2,
|
|
20603
|
-
hostSection,
|
|
20604
|
-
RENDERER_AGENT_LABELS[agent.agent],
|
|
20605
|
-
agent.availability,
|
|
20606
|
-
null,
|
|
20607
|
-
agent.error,
|
|
20608
|
-
messages,
|
|
20609
|
-
agent.agent,
|
|
20610
|
-
agent,
|
|
20611
|
-
selectedHost.hostId
|
|
20612
|
-
);
|
|
20613
|
-
}
|
|
20614
|
-
content.append(tabs, hostSection);
|
|
20615
|
-
};
|
|
20616
|
-
const diagnostics = getDiagnostics();
|
|
20617
|
-
render(diagnostics?.snapshot() ?? null);
|
|
20618
|
-
if (!diagnostics) {
|
|
20619
|
-
copyAll.disabled = true;
|
|
20620
|
-
return void 0;
|
|
20621
|
-
}
|
|
20622
|
-
copyAll.addEventListener("click", () => {
|
|
20623
|
-
const snapshot = diagnostics.snapshot();
|
|
20624
|
-
const report = snapshot.hosts.flatMap(
|
|
20625
|
-
(host) => host.agents.map(
|
|
20626
|
-
(agent) => diagnosticText(host.hostId, RENDERER_AGENT_LABELS[agent.agent], agent)
|
|
20627
|
-
)
|
|
20628
|
-
).join("\n\n");
|
|
20629
|
-
copyDiagnosticsToClipboard(document2, copyAll, report, messages, messages.connectionCopyAll);
|
|
20630
|
-
});
|
|
20631
|
-
const unsubscribe = diagnostics.subscribe(() => render(diagnostics.snapshot()));
|
|
20632
|
-
refresh.addEventListener("click", () => {
|
|
20633
|
-
if (pending) return;
|
|
20634
|
-
pending = true;
|
|
20635
|
-
refresh.disabled = true;
|
|
20636
|
-
refresh.replaceChildren(
|
|
20637
|
-
createRendererSettingsIcon("diagnose", 16),
|
|
20638
|
-
messages.connectionRefreshing
|
|
20639
|
-
);
|
|
20640
|
-
void context.runLatest(() => diagnostics.refresh(), {
|
|
20641
|
-
success() {
|
|
20642
|
-
pending = false;
|
|
20643
|
-
refresh.disabled = false;
|
|
20644
|
-
refresh.replaceChildren(
|
|
20645
|
-
createRendererSettingsIcon("diagnose", 16),
|
|
20646
|
-
messages.connectionRefresh
|
|
20647
|
-
);
|
|
20648
|
-
render(diagnostics.snapshot());
|
|
20649
|
-
},
|
|
20650
|
-
failure(error51) {
|
|
20651
|
-
pending = false;
|
|
20652
|
-
refresh.disabled = false;
|
|
20653
|
-
refresh.replaceChildren(
|
|
20654
|
-
createRendererSettingsIcon("diagnose", 16),
|
|
20655
|
-
messages.connectionRefresh
|
|
20656
|
-
);
|
|
20657
|
-
const snapshot = diagnostics.snapshot();
|
|
20658
|
-
render({
|
|
20659
|
-
...snapshot,
|
|
20660
|
-
hosts: snapshot.hosts.map((host) => ({
|
|
20661
|
-
...host,
|
|
20662
|
-
agents: host.agents.map((agent) => ({
|
|
20663
|
-
...agent,
|
|
20664
|
-
availability: "error",
|
|
20665
|
-
error: {
|
|
20666
|
-
code: "internalError",
|
|
20667
|
-
message: error51 instanceof Error ? error51.message : String(error51),
|
|
20668
|
-
retryable: true,
|
|
20669
|
-
stage: "request"
|
|
20670
|
-
}
|
|
20671
|
-
}))
|
|
20672
|
-
}))
|
|
20673
|
-
});
|
|
20674
|
-
}
|
|
20675
|
-
});
|
|
20676
|
-
});
|
|
20677
|
-
return unsubscribe;
|
|
21238
|
+
|
|
21239
|
+
// src/settings/update-request.ts
|
|
21240
|
+
var RENDERER_UPDATE_REQUEST_TIMEOUT_MS = 15e3;
|
|
21241
|
+
var RendererUpdateRequestTimeoutError = class extends Error {
|
|
21242
|
+
constructor() {
|
|
21243
|
+
super("Update request timed out");
|
|
21244
|
+
this.name = "RendererUpdateRequestTimeoutError";
|
|
21245
|
+
}
|
|
21246
|
+
};
|
|
21247
|
+
function runBoundedRendererUpdateRequest(operation, signal, timeoutMs = RENDERER_UPDATE_REQUEST_TIMEOUT_MS) {
|
|
21248
|
+
return new Promise((resolve, reject) => {
|
|
21249
|
+
let settled = false;
|
|
21250
|
+
const settle = (handler) => {
|
|
21251
|
+
if (settled) return;
|
|
21252
|
+
settled = true;
|
|
21253
|
+
clearTimeout(timeout);
|
|
21254
|
+
signal.removeEventListener("abort", abort);
|
|
21255
|
+
handler();
|
|
21256
|
+
};
|
|
21257
|
+
const timeout = setTimeout(() => {
|
|
21258
|
+
settle(() => reject(new RendererUpdateRequestTimeoutError()));
|
|
21259
|
+
}, timeoutMs);
|
|
21260
|
+
const abort = () => {
|
|
21261
|
+
settle(() => reject(new Error("Update request was aborted")));
|
|
21262
|
+
};
|
|
21263
|
+
const rejectRequest = (error51) => {
|
|
21264
|
+
settle(() => reject(error51));
|
|
21265
|
+
};
|
|
21266
|
+
if (signal.aborted) {
|
|
21267
|
+
abort();
|
|
21268
|
+
return;
|
|
21269
|
+
}
|
|
21270
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
21271
|
+
try {
|
|
21272
|
+
void operation().then(
|
|
21273
|
+
(value) => settle(() => resolve(value)),
|
|
21274
|
+
(error51) => rejectRequest(error51)
|
|
21275
|
+
);
|
|
21276
|
+
} catch (error51) {
|
|
21277
|
+
rejectRequest(error51);
|
|
20678
21278
|
}
|
|
20679
21279
|
});
|
|
20680
21280
|
}
|
|
20681
|
-
|
|
20682
|
-
|
|
20683
|
-
|
|
20684
|
-
|
|
20685
|
-
|
|
20686
|
-
|
|
20687
|
-
|
|
20688
|
-
|
|
20689
|
-
|
|
21281
|
+
|
|
21282
|
+
// src/settings/pages.ts
|
|
21283
|
+
var CODEXHOST_GITHUB_REPOSITORY_URL = "https://github.com/BytePioneer-AI/codex-host";
|
|
21284
|
+
var CODEXHOST_RELEASES_LATEST_URL = `${CODEXHOST_GITHUB_REPOSITORY_URL}/releases/latest`;
|
|
21285
|
+
var CODEXHOST_NPM_MANUAL_UPDATE_COMMAND = "npm install -g @codexhost/cli@latest";
|
|
21286
|
+
function rendererUserAgentData(navigator2) {
|
|
21287
|
+
return navigator2.userAgentData;
|
|
21288
|
+
}
|
|
21289
|
+
function isWindowsRenderer(window2) {
|
|
21290
|
+
const navigator2 = window2?.navigator;
|
|
21291
|
+
if (!navigator2) return false;
|
|
21292
|
+
const identity = `${rendererUserAgentData(navigator2)?.platform ?? ""} ${navigator2.platform ?? ""} ${navigator2.userAgent}`;
|
|
21293
|
+
return /windows|win32|win64/iu.test(identity);
|
|
21294
|
+
}
|
|
21295
|
+
function windowsInstallerDownloadUrl(window2, version2) {
|
|
21296
|
+
const navigator2 = window2?.navigator;
|
|
21297
|
+
const hints = navigator2 ? rendererUserAgentData(navigator2) : void 0;
|
|
21298
|
+
const identity = `${hints?.architecture ?? ""} ${hints?.platform ?? ""} ${navigator2?.platform ?? ""} ${navigator2?.userAgent ?? ""}`;
|
|
21299
|
+
const architecture = /arm64|aarch64|\barm\b/iu.test(identity) ? "arm64" : "x64";
|
|
21300
|
+
return `https://github.com/BytePioneer-AI/codex-host/releases/download/v${version2}/codexhost-${version2}-windows-${architecture}.exe`;
|
|
21301
|
+
}
|
|
21302
|
+
function panelIconName(view) {
|
|
21303
|
+
if (view === "failed" || view === "error") return "alert";
|
|
21304
|
+
if (view === "unavailable") return "unavailable";
|
|
21305
|
+
if (view === "current") return "check";
|
|
21306
|
+
return "updates";
|
|
21307
|
+
}
|
|
21308
|
+
function createPanelHead(document2, view, title) {
|
|
21309
|
+
const head = document2.createElement("div");
|
|
21310
|
+
head.className = "settings-update-panel__head";
|
|
21311
|
+
const label = document2.createElement("strong");
|
|
21312
|
+
label.className = "settings-update-panel__title";
|
|
21313
|
+
label.textContent = title;
|
|
21314
|
+
head.append(createRendererSettingsIcon(panelIconName(view), 16), label);
|
|
21315
|
+
return head;
|
|
21316
|
+
}
|
|
21317
|
+
function createPanelActions(document2, ...buttons) {
|
|
21318
|
+
const actions = document2.createElement("div");
|
|
21319
|
+
actions.className = "settings-update-actions";
|
|
21320
|
+
actions.append(...buttons);
|
|
21321
|
+
return actions;
|
|
20690
21322
|
}
|
|
20691
21323
|
function installationLabel(installation, messages) {
|
|
20692
21324
|
if (installation === "npm") return messages.updateInstallationNpm;
|
|
@@ -20723,6 +21355,57 @@ ${error51.stderrTail}`] : []
|
|
|
20723
21355
|
}
|
|
20724
21356
|
return `${scaled.toFixed(scaled >= 10 ? 0 : 1)} ${unit}`;
|
|
20725
21357
|
}
|
|
21358
|
+
function aboutPage(messages) {
|
|
21359
|
+
return Object.freeze({
|
|
21360
|
+
id: "about",
|
|
21361
|
+
label: messages.pageLabels.about,
|
|
21362
|
+
icon: "about",
|
|
21363
|
+
mount(context) {
|
|
21364
|
+
const document2 = context.content.ownerDocument;
|
|
21365
|
+
const heading = document2.createElement("div");
|
|
21366
|
+
heading.className = "settings-section-label";
|
|
21367
|
+
heading.textContent = messages.pageLabels.about;
|
|
21368
|
+
const panel = document2.createElement("section");
|
|
21369
|
+
panel.className = "settings-about-panel";
|
|
21370
|
+
const product = document2.createElement("strong");
|
|
21371
|
+
product.className = "settings-about-product";
|
|
21372
|
+
product.textContent = "CodexHost";
|
|
21373
|
+
const tagline = document2.createElement("strong");
|
|
21374
|
+
tagline.className = "settings-about-tagline";
|
|
21375
|
+
tagline.textContent = messages.aboutTagline;
|
|
21376
|
+
const introduction = document2.createElement("div");
|
|
21377
|
+
introduction.className = "settings-about-copy";
|
|
21378
|
+
for (const paragraphText of messages.aboutParagraphs) {
|
|
21379
|
+
const paragraph = document2.createElement("p");
|
|
21380
|
+
paragraph.textContent = paragraphText;
|
|
21381
|
+
introduction.append(paragraph);
|
|
21382
|
+
}
|
|
21383
|
+
const starCallout = document2.createElement("p");
|
|
21384
|
+
starCallout.className = "settings-about-star-callout";
|
|
21385
|
+
starCallout.textContent = messages.aboutStarCallout;
|
|
21386
|
+
const repositorySection = document2.createElement("div");
|
|
21387
|
+
repositorySection.className = "settings-about-repository";
|
|
21388
|
+
const openSource = document2.createElement("p");
|
|
21389
|
+
openSource.textContent = messages.aboutOpenSource;
|
|
21390
|
+
const repository = document2.createElement("a");
|
|
21391
|
+
repository.className = "settings-about-repository-link";
|
|
21392
|
+
repository.href = CODEXHOST_GITHUB_REPOSITORY_URL;
|
|
21393
|
+
repository.target = "_blank";
|
|
21394
|
+
repository.rel = "noopener noreferrer";
|
|
21395
|
+
const repositoryUrl = document2.createElement("code");
|
|
21396
|
+
repositoryUrl.textContent = CODEXHOST_GITHUB_REPOSITORY_URL;
|
|
21397
|
+
repository.append(
|
|
21398
|
+
createRendererSettingsIcon("external-link", 14),
|
|
21399
|
+
messages.aboutRepository,
|
|
21400
|
+
repositoryUrl
|
|
21401
|
+
);
|
|
21402
|
+
repositorySection.append(openSource, repository);
|
|
21403
|
+
panel.append(product, tagline, introduction, starCallout, repositorySection);
|
|
21404
|
+
context.content.append(heading, panel);
|
|
21405
|
+
return void 0;
|
|
21406
|
+
}
|
|
21407
|
+
});
|
|
21408
|
+
}
|
|
20726
21409
|
function updatesPage(messages, getClient) {
|
|
20727
21410
|
return Object.freeze({
|
|
20728
21411
|
id: "updates",
|
|
@@ -20730,37 +21413,90 @@ ${error51.stderrTail}`] : []
|
|
|
20730
21413
|
icon: "updates",
|
|
20731
21414
|
mount(context) {
|
|
20732
21415
|
const document2 = context.content.ownerDocument;
|
|
21416
|
+
const windows = isWindowsRenderer(document2.defaultView);
|
|
20733
21417
|
const heading = document2.createElement("div");
|
|
20734
21418
|
heading.className = "settings-section-label";
|
|
20735
21419
|
heading.textContent = messages.pageLabels.updates;
|
|
20736
21420
|
const metadata = document2.createElement("div");
|
|
20737
21421
|
metadata.className = "settings-update-metadata";
|
|
20738
|
-
const
|
|
20739
|
-
|
|
20740
|
-
|
|
20741
|
-
|
|
20742
|
-
|
|
20743
|
-
|
|
20744
|
-
|
|
20745
|
-
|
|
20746
|
-
|
|
20747
|
-
|
|
20748
|
-
|
|
20749
|
-
const
|
|
20750
|
-
|
|
20751
|
-
|
|
20752
|
-
metadata.append(currentVersion, installation);
|
|
21422
|
+
const createMetadataItem = (label) => {
|
|
21423
|
+
const item = document2.createElement("div");
|
|
21424
|
+
item.className = "settings-update-metadata__item";
|
|
21425
|
+
const name = document2.createElement("span");
|
|
21426
|
+
name.textContent = label;
|
|
21427
|
+
const value = document2.createElement("strong");
|
|
21428
|
+
value.textContent = "-";
|
|
21429
|
+
item.append(name, value);
|
|
21430
|
+
metadata.append(item);
|
|
21431
|
+
return value;
|
|
21432
|
+
};
|
|
21433
|
+
const currentVersionValue = createMetadataItem(messages.updateCurrentVersion);
|
|
21434
|
+
const latestVersionValue = createMetadataItem(messages.updateLatestVersion);
|
|
21435
|
+
const installationValue = createMetadataItem(messages.updateInstallation);
|
|
20753
21436
|
const panel = document2.createElement("section");
|
|
20754
21437
|
panel.className = "settings-update-panel";
|
|
20755
21438
|
panel.setAttribute("aria-live", "polite");
|
|
21439
|
+
const controls = document2.createElement("div");
|
|
21440
|
+
controls.className = "settings-update-controls";
|
|
21441
|
+
const manualTitle = document2.createElement("div");
|
|
21442
|
+
manualTitle.className = "settings-update-manual-title";
|
|
21443
|
+
manualTitle.textContent = messages.updateManualTitle;
|
|
20756
21444
|
const manualNpm = document2.createElement("div");
|
|
20757
21445
|
manualNpm.className = "settings-update-manual";
|
|
20758
21446
|
manualNpm.hidden = true;
|
|
20759
|
-
const manualNpmDescription = document2.createElement("
|
|
21447
|
+
const manualNpmDescription = document2.createElement("p");
|
|
21448
|
+
manualNpmDescription.className = "settings-update-manual-description";
|
|
20760
21449
|
manualNpmDescription.textContent = messages.updateManualNpmDescription;
|
|
21450
|
+
const manualNpmCommandRow = document2.createElement("div");
|
|
21451
|
+
manualNpmCommandRow.className = "settings-update-command";
|
|
20761
21452
|
const manualNpmCommand = document2.createElement("code");
|
|
20762
21453
|
manualNpmCommand.textContent = CODEXHOST_NPM_MANUAL_UPDATE_COMMAND;
|
|
20763
|
-
|
|
21454
|
+
const copyCommand = document2.createElement("button");
|
|
21455
|
+
copyCommand.type = "button";
|
|
21456
|
+
copyCommand.className = "settings-update-command__copy";
|
|
21457
|
+
const setCopyLabel = (label) => {
|
|
21458
|
+
copyCommand.replaceChildren(createRendererSettingsIcon("copy", 14), label);
|
|
21459
|
+
};
|
|
21460
|
+
setCopyLabel(messages.updateCopyCommand);
|
|
21461
|
+
copyCommand.addEventListener("click", () => {
|
|
21462
|
+
const clipboard = document2.defaultView?.navigator.clipboard;
|
|
21463
|
+
const restore = (label) => {
|
|
21464
|
+
setCopyLabel(label);
|
|
21465
|
+
document2.defaultView?.setTimeout(() => setCopyLabel(messages.updateCopyCommand), 2e3);
|
|
21466
|
+
};
|
|
21467
|
+
if (!clipboard) {
|
|
21468
|
+
restore(messages.updateCopyFailed);
|
|
21469
|
+
return;
|
|
21470
|
+
}
|
|
21471
|
+
void clipboard.writeText(CODEXHOST_NPM_MANUAL_UPDATE_COMMAND).then(
|
|
21472
|
+
() => restore(messages.updateCommandCopied),
|
|
21473
|
+
() => restore(messages.updateCopyFailed)
|
|
21474
|
+
);
|
|
21475
|
+
});
|
|
21476
|
+
manualNpmCommandRow.append(manualNpmCommand, copyCommand);
|
|
21477
|
+
manualNpm.append(manualNpmDescription, manualNpmCommandRow);
|
|
21478
|
+
const manualWindowsInstaller = document2.createElement("div");
|
|
21479
|
+
manualWindowsInstaller.className = "settings-update-manual";
|
|
21480
|
+
manualWindowsInstaller.hidden = true;
|
|
21481
|
+
const manualWindowsInstallerDescription = document2.createElement("p");
|
|
21482
|
+
manualWindowsInstallerDescription.className = "settings-update-manual-description";
|
|
21483
|
+
manualWindowsInstallerDescription.textContent = messages.updateWindowsInstallerDescription;
|
|
21484
|
+
const manualWindowsInstallerActions = document2.createElement("div");
|
|
21485
|
+
manualWindowsInstallerActions.className = "settings-update-actions";
|
|
21486
|
+
const manualWindowsInstallerLink = document2.createElement("a");
|
|
21487
|
+
manualWindowsInstallerLink.className = "settings-update-link";
|
|
21488
|
+
manualWindowsInstallerLink.href = CODEXHOST_RELEASES_LATEST_URL;
|
|
21489
|
+
manualWindowsInstallerLink.target = "_blank";
|
|
21490
|
+
manualWindowsInstallerLink.rel = "noopener noreferrer";
|
|
21491
|
+
manualWindowsInstallerLink.append(
|
|
21492
|
+
messages.updateDownloadWindowsInstaller,
|
|
21493
|
+
createRendererSettingsIcon("external-link", 14)
|
|
21494
|
+
);
|
|
21495
|
+
manualWindowsInstallerActions.append(manualWindowsInstallerLink);
|
|
21496
|
+
manualWindowsInstaller.append(
|
|
21497
|
+
manualWindowsInstallerDescription,
|
|
21498
|
+
manualWindowsInstallerActions
|
|
21499
|
+
);
|
|
20764
21500
|
const actions = document2.createElement("div");
|
|
20765
21501
|
actions.className = "settings-update-actions";
|
|
20766
21502
|
const releaseLink = document2.createElement("a");
|
|
@@ -20773,7 +21509,14 @@ ${error51.stderrTail}`] : []
|
|
|
20773
21509
|
createRendererSettingsIcon("external-link", 14)
|
|
20774
21510
|
);
|
|
20775
21511
|
actions.append(releaseLink);
|
|
20776
|
-
|
|
21512
|
+
controls.append(manualTitle, manualNpm, manualWindowsInstaller, actions);
|
|
21513
|
+
const notes = document2.createElement("div");
|
|
21514
|
+
notes.className = "settings-update-notes-section";
|
|
21515
|
+
context.content.append(heading, metadata, panel, controls, notes);
|
|
21516
|
+
const setManualFallback = (fallback) => {
|
|
21517
|
+
manualNpmDescription.textContent = windows ? messages.updateWindowsNpmDescription : fallback ? messages.updateManualFallbackDescription : messages.updateManualNpmDescription;
|
|
21518
|
+
manualNpmDescription.className = fallback ? "settings-update-manual-description is-fallback" : "settings-update-manual-description";
|
|
21519
|
+
};
|
|
20777
21520
|
let pollTimer;
|
|
20778
21521
|
let pollAttempts = 0;
|
|
20779
21522
|
let pending = false;
|
|
@@ -20786,11 +21529,11 @@ ${error51.stderrTail}`] : []
|
|
|
20786
21529
|
const renderUnavailable = (detail) => {
|
|
20787
21530
|
panel.dataset.updateState = "unavailable";
|
|
20788
21531
|
panel.replaceChildren();
|
|
20789
|
-
const
|
|
20790
|
-
|
|
20791
|
-
const copy = document2.createElement("span");
|
|
21532
|
+
const copy = document2.createElement("p");
|
|
21533
|
+
copy.className = "settings-update-summary";
|
|
20792
21534
|
copy.textContent = detail;
|
|
20793
|
-
panel.append(
|
|
21535
|
+
panel.append(createPanelHead(document2, "unavailable", messages.notAvailable), copy);
|
|
21536
|
+
notes.replaceChildren();
|
|
20794
21537
|
};
|
|
20795
21538
|
const renderRequestFailure = (error51) => {
|
|
20796
21539
|
renderPendingStatus(
|
|
@@ -20826,9 +21569,8 @@ ${error51.stderrTail}`] : []
|
|
|
20826
21569
|
const renderPendingStatus = (status, message, viewPhase = status?.phase ?? "pending") => {
|
|
20827
21570
|
panel.dataset.updateState = viewPhase;
|
|
20828
21571
|
panel.replaceChildren();
|
|
20829
|
-
|
|
20830
|
-
|
|
20831
|
-
panel.append(state);
|
|
21572
|
+
panel.append(createPanelHead(document2, viewPhase, message));
|
|
21573
|
+
setManualFallback(viewPhase === "failed");
|
|
20832
21574
|
if (status?.phase === "downloading" && status.totalBytes !== void 0 && status.downloadedBytes !== void 0) {
|
|
20833
21575
|
const progress = document2.createElement("progress");
|
|
20834
21576
|
progress.className = "settings-update-progress";
|
|
@@ -20850,7 +21592,7 @@ ${error51.stderrTail}`] : []
|
|
|
20850
21592
|
retry.className = "settings-command-button";
|
|
20851
21593
|
retry.append(createRendererSettingsIcon("refresh", 16), messages.updateRetry);
|
|
20852
21594
|
retry.addEventListener("click", () => void load());
|
|
20853
|
-
panel.append(retry);
|
|
21595
|
+
panel.append(createPanelActions(document2, retry));
|
|
20854
21596
|
}
|
|
20855
21597
|
};
|
|
20856
21598
|
const start = (client) => {
|
|
@@ -20877,8 +21619,19 @@ ${error51.stderrTail}`] : []
|
|
|
20877
21619
|
};
|
|
20878
21620
|
const renderCheck = (result, client) => {
|
|
20879
21621
|
currentVersionValue.textContent = `v${result.currentVersion}`;
|
|
21622
|
+
latestVersionValue.textContent = result.latestVersion ? `v${result.latestVersion}` : "-";
|
|
21623
|
+
latestVersionValue.className = result.updateAvailable ? "settings-update-metadata__value--newer" : "";
|
|
20880
21624
|
installationValue.textContent = installationLabel(result.installation, messages);
|
|
20881
21625
|
manualNpm.hidden = result.installation !== "npm";
|
|
21626
|
+
manualWindowsInstaller.hidden = !windows || result.installation !== "windows-installer";
|
|
21627
|
+
releaseLink.hidden = windows;
|
|
21628
|
+
manualTitle.hidden = windows && !["npm", "windows-installer"].includes(result.installation ?? "");
|
|
21629
|
+
if (windows && result.installation === "windows-installer" && result.latestVersion) {
|
|
21630
|
+
manualWindowsInstallerLink.href = windowsInstallerDownloadUrl(
|
|
21631
|
+
document2.defaultView,
|
|
21632
|
+
result.latestVersion
|
|
21633
|
+
);
|
|
21634
|
+
}
|
|
20882
21635
|
if (result.releaseNotesUrl) releaseLink.href = result.releaseNotesUrl;
|
|
20883
21636
|
const operationMessage = statusMessage(result.status, messages);
|
|
20884
21637
|
if (isPendingStatus(result.status)) {
|
|
@@ -20886,42 +21639,53 @@ ${error51.stderrTail}`] : []
|
|
|
20886
21639
|
scheduleStatusPoll(client, true);
|
|
20887
21640
|
return;
|
|
20888
21641
|
}
|
|
20889
|
-
|
|
21642
|
+
const actionableStatus = result.status?.phase === "failed" && result.status.version === result.latestVersion ? result.status : null;
|
|
21643
|
+
const view = result.error ? "error" : result.updateAvailable ? "available" : "current";
|
|
21644
|
+
panel.dataset.updateState = view;
|
|
20890
21645
|
panel.replaceChildren();
|
|
20891
|
-
|
|
20892
|
-
|
|
21646
|
+
setManualFallback(Boolean(result.error) || actionableStatus !== null);
|
|
21647
|
+
if (result.error || !result.updateAvailable || windows || actionableStatus) {
|
|
21648
|
+
panel.append(
|
|
21649
|
+
createPanelHead(
|
|
21650
|
+
document2,
|
|
21651
|
+
view,
|
|
21652
|
+
actionableStatus ? statusMessage(actionableStatus, messages) ?? messages.updateFailed : result.error ? messages.updateFailed : result.updateAvailable ? messages.updateWindowsManualRequired : messages.updateUpToDate
|
|
21653
|
+
)
|
|
21654
|
+
);
|
|
20893
21655
|
}
|
|
20894
|
-
|
|
20895
|
-
|
|
20896
|
-
|
|
20897
|
-
|
|
20898
|
-
|
|
20899
|
-
panel.append(createReleaseNotesElement(document2, result.releaseNotes));
|
|
21656
|
+
if (actionableStatus?.error) {
|
|
21657
|
+
const error51 = document2.createElement("p");
|
|
21658
|
+
error51.className = "settings-update-error";
|
|
21659
|
+
error51.textContent = actionableStatus.error;
|
|
21660
|
+
panel.append(error51);
|
|
20900
21661
|
}
|
|
20901
|
-
if (result.
|
|
21662
|
+
if (result.error) {
|
|
20902
21663
|
const error51 = document2.createElement("p");
|
|
20903
21664
|
error51.className = "settings-update-error";
|
|
20904
|
-
error51.textContent = result.
|
|
21665
|
+
error51.textContent = result.error;
|
|
20905
21666
|
panel.append(error51);
|
|
20906
21667
|
}
|
|
20907
|
-
|
|
21668
|
+
const buttons = [];
|
|
21669
|
+
if (!windows && result.updateAvailable && result.installationAvailable) {
|
|
20908
21670
|
const update = document2.createElement("button");
|
|
20909
21671
|
update.type = "button";
|
|
20910
21672
|
update.className = "settings-command-button";
|
|
20911
21673
|
update.append(createRendererSettingsIcon("updates", 16), messages.updateAndRestart);
|
|
20912
21674
|
update.addEventListener("click", () => start(client));
|
|
20913
|
-
|
|
21675
|
+
buttons.push(update);
|
|
20914
21676
|
}
|
|
20915
21677
|
if (result.error) {
|
|
20916
|
-
const error51 = document2.createElement("p");
|
|
20917
|
-
error51.className = "settings-update-error";
|
|
20918
|
-
error51.textContent = result.error;
|
|
20919
21678
|
const retry = document2.createElement("button");
|
|
20920
21679
|
retry.type = "button";
|
|
20921
21680
|
retry.className = "settings-command-button settings-command-button--secondary";
|
|
20922
21681
|
retry.append(createRendererSettingsIcon("refresh", 16), messages.updateRetry);
|
|
20923
21682
|
retry.addEventListener("click", () => void load());
|
|
20924
|
-
|
|
21683
|
+
buttons.push(retry);
|
|
21684
|
+
}
|
|
21685
|
+
if (buttons.length > 0) panel.append(createPanelActions(document2, ...buttons));
|
|
21686
|
+
notes.replaceChildren();
|
|
21687
|
+
if (result.releaseNotes) {
|
|
21688
|
+
notes.append(createReleaseNotesElement(document2, result.releaseNotes));
|
|
20925
21689
|
}
|
|
20926
21690
|
};
|
|
20927
21691
|
const load = () => {
|
|
@@ -20952,13 +21716,10 @@ ${error51.stderrTail}`] : []
|
|
|
20952
21716
|
});
|
|
20953
21717
|
}
|
|
20954
21718
|
function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null) {
|
|
20955
|
-
const unavailableIds = DEFAULT_RENDERER_SETTINGS_PAGE_IDS.filter(
|
|
20956
|
-
(id) => id !== "updates" && id !== "connections"
|
|
20957
|
-
);
|
|
20958
21719
|
return Object.freeze([
|
|
20959
|
-
|
|
20960
|
-
|
|
20961
|
-
|
|
21720
|
+
createConnectionsSettingsPage(messages, getDiagnostics),
|
|
21721
|
+
updatesPage(messages, getUpdateClient),
|
|
21722
|
+
aboutPage(messages)
|
|
20962
21723
|
]);
|
|
20963
21724
|
}
|
|
20964
21725
|
function createDefaultRendererSettingsRegistry(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null) {
|
|
@@ -20968,11 +21729,10 @@ ${error51.stderrTail}`] : []
|
|
|
20968
21729
|
}
|
|
20969
21730
|
|
|
20970
21731
|
// src/settings/shell.css
|
|
20971
|
-
var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-icon-button.settings-star-link {\n width: auto;\n gap: 6px;\n padding-inline: 8px;\n font-size: 12px;\n line-height: 18px;\n text-decoration: none;\n border: 2px dashed #f5c542;\n white-space: nowrap;\n}\n\n.settings-star-link .codexhost-settings-icon {\n color: #f5c542;\n fill: currentColor;\n stroke: currentColor;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 40px;\n flex: none;\n gap: 12px;\n padding: 8px 12px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 10px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 7%);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-page-description {\n max-width: 760px;\n margin: -12px 0 24px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-connection-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-bottom: 16px;\n}\n\n.settings-connection-list {\n min-width: 0;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-connection-host-tabs {\n display: flex;\n gap: 6px;\n padding: 20px 0 8px;\n overflow-x: auto;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-host-tab {\n flex: none;\n padding: 7px 12px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: var(--settings-muted);\n font: inherit;\n font-size: 13px;\n line-height: 18px;\n cursor: pointer;\n}\n\n.settings-connection-host-tab:hover {\n background: var(--settings-hover);\n color: var(--settings-text);\n}\n\n.settings-connection-host-tab[aria-selected="true"] {\n background: var(--settings-active);\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-connection-host-tab:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: -2px;\n}\n\n.settings-connection-row {\n display: grid;\n grid-template-columns: minmax(180px, 1fr) auto minmax(260px, 1.5fr);\n align-items: center;\n min-width: 0;\n min-height: 76px;\n gap: 24px;\n padding: 14px 0;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n gap: 10px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 20px;\n}\n\n.settings-connection-row__identity strong {\n min-width: 0;\n overflow-wrap: anywhere;\n font-weight: 500;\n}\n\n.settings-connection-row__dot {\n width: 9px;\n height: 9px;\n flex: none;\n border-radius: 50%;\n background: var(--settings-muted);\n}\n\n.settings-connection-row__dot[data-connection-tone="ready"] {\n background: #22c55e;\n}\n\n.settings-connection-row__dot[data-connection-tone="checking"] {\n background: #f5c542;\n}\n\n.settings-connection-row__dot[data-connection-tone="failed"] {\n background: #ef4444;\n}\n\n.settings-status-badge[data-connection-tone="ready"] {\n color: #4ade80;\n}\n\n.settings-status-badge[data-connection-tone="checking"] {\n color: #f5c542;\n}\n\n.settings-status-badge[data-connection-tone="failed"] {\n color: #f87171;\n}\n\n.settings-connection-row__detail {\n display: grid;\n min-width: 0;\n align-items: center;\n gap: 2px 12px;\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-connection-row__reason {\n min-width: 0;\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n}\n\n.settings-connection-details-toggle {\n width: fit-content;\n padding: 0;\n color: var(--settings-focus);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n background: transparent;\n border: 0;\n cursor: pointer;\n}\n\n.settings-connection-details-toggle:hover {\n text-decoration: underline;\n}\n\n.settings-connection-details {\n display: grid;\n grid-column: 1 / -1;\n gap: 6px;\n min-width: 0;\n margin: 4px 0 2px 32px;\n padding: 12px;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 4%);\n border-left: 2px solid #ef4444;\n border-radius: 4px;\n}\n\n.settings-connection-detail-line {\n display: grid;\n grid-template-columns: 112px minmax(0, 1fr);\n gap: 12px;\n min-width: 0;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-connection-detail-line span {\n color: var(--settings-muted);\n}\n\n.settings-connection-detail-line code {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n white-space: pre-wrap;\n}\n\n.settings-connection-stderr {\n max-height: 220px;\n min-width: 0;\n margin: 4px 0 0;\n padding: 10px;\n overflow: auto;\n color: #fca5a5;\n font:\n 12px/18px ui-monospace,\n "SFMono-Regular",\n Consolas,\n "Liberation Mono",\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n background: rgb(0 0 0 / 28%);\n border-radius: 4px;\n}\n\n.settings-connection-details .settings-command-button {\n justify-self: start;\n min-height: 30px;\n font-size: 12px;\n}\n\n.settings-connection-row__detail time {\n color: var(--settings-muted);\n opacity: 0.8;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 16px;\n min-height: 128px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-update-panel > strong,\n.settings-update-panel > span,\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-panel > span,\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-notes {\n display: grid;\n min-width: 0;\n gap: 12px;\n color: var(--settings-muted);\n font-size: 14px;\n line-height: 22px;\n overflow-wrap: anywhere;\n}\n\n.settings-update-notes > :first-child {\n margin-top: 0;\n}\n\n.settings-update-notes > :last-child {\n margin-bottom: 0;\n}\n\n.settings-update-notes h1,\n.settings-update-notes h2,\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n margin: 6px 0 0;\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes h1 {\n font-size: 18px;\n line-height: 26px;\n}\n\n.settings-update-notes h2 {\n font-size: 17px;\n line-height: 24px;\n}\n\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n font-size: 14px;\n line-height: 22px;\n}\n\n.settings-update-notes p,\n.settings-update-notes ul,\n.settings-update-notes ol,\n.settings-update-notes pre,\n.settings-update-notes blockquote {\n margin: 0;\n}\n\n.settings-update-notes ul,\n.settings-update-notes ol {\n padding-left: 24px;\n}\n\n.settings-update-notes li {\n padding-left: 4px;\n}\n\n.settings-update-notes li::marker {\n color: var(--settings-muted);\n font-size: 0.85em;\n}\n\n.settings-update-notes li + li {\n margin-top: 14px;\n}\n\n.settings-update-notes .release-note-translation {\n display: block;\n margin-top: 3px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-notes blockquote {\n padding: 8px 12px;\n color: var(--settings-muted);\n border-left: 3px solid var(--settings-focus);\n background: rgb(255 255 255 / 4%);\n}\n\n.settings-update-notes hr {\n width: 100%;\n margin: 2px 0;\n border: 0;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-update-notes strong {\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes a {\n color: #7cb8ff;\n text-decoration: none;\n}\n\n.settings-update-notes a:hover {\n text-decoration: underline;\n}\n\n.settings-update-notes code {\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n}\n\n.settings-update-notes :not(pre) > code {\n padding: 1px 5px;\n background: rgb(255 255 255 / 8%);\n border-radius: 4px;\n}\n\n.settings-update-notes pre {\n min-width: 0;\n max-width: 100%;\n padding: 10px 12px;\n overflow-x: auto;\n overflow-y: hidden;\n background: rgb(0 0 0 / 28%);\n border-radius: 6px;\n}\n\n.settings-update-notes pre code {\n line-height: 18px;\n white-space: pre-wrap;\n}\n\n.settings-update-version-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 20px;\n min-height: 32px;\n color: var(--settings-muted);\n font-size: 13px;\n}\n\n.settings-update-version-row strong {\n color: var(--settings-text);\n font-size: 15px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 6px;\n margin-top: 14px;\n padding-inline: 4px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual code {\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-actions {\n display: flex;\n min-width: 0;\n margin-top: 16px;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-icon-button.settings-star-link {\n width: 28px;\n padding: 0;\n }\n\n .settings-star-link span {\n display: none;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-connection-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 10px 16px;\n }\n\n .settings-connection-row__detail {\n grid-column: 1 / -1;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
|
|
21732
|
+
var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-section-label {\n min-height: 28px;\n padding: 7px 12px 3px;\n color: #777;\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n}\n\n.settings-nav-section-label:not(:first-child) {\n margin-top: 14px;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 48px;\n flex: none;\n gap: 14px;\n padding: 10px 14px;\n color: var(--settings-text);\n font-size: 14px;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 12px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-nav-star-link {\n margin-top: 0;\n color: var(--settings-text);\n text-decoration: none;\n}\n\n.settings-nav-star-link .codexhost-settings-icon {\n color: #f5c542;\n}\n\n.settings-nav-star-link:hover {\n color: #fff4bd;\n background: rgb(245 197 66 / 8%);\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: rgb(255 255 255 / 7%);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-page-description {\n max-width: 760px;\n margin: -12px 0 24px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-preference-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 32px;\n min-height: 88px;\n padding: 18px 0;\n border-top: 1px solid var(--settings-divider);\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-preference-row__copy {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n min-width: 0;\n gap: 5px;\n}\n\n.settings-preference-row__copy strong {\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-preference-row__copy span {\n max-width: 680px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-preference-switch {\n display: inline-flex;\n align-items: center;\n width: 42px;\n height: 24px;\n flex: none;\n padding: 2px;\n border: 0;\n border-radius: 999px;\n background: rgb(255 255 255 / 16%);\n cursor: pointer;\n transition: background 120ms ease;\n}\n\n.settings-preference-switch[aria-checked="true"] {\n justify-content: flex-end;\n background: var(--settings-focus);\n}\n\n.settings-preference-switch:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.settings-preference-switch__thumb {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: white;\n box-shadow: 0 1px 3px rgb(0 0 0 / 35%);\n}\n\n.settings-connection-page-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 24px;\n margin-bottom: 24px;\n}\n\n.settings-connection-page-header .settings-section-label {\n padding-bottom: 0;\n}\n\n.settings-connection-page-header .settings-page-description {\n margin: 8px 0 0;\n}\n\n.settings-connections-content,\n.settings-connections-layout,\n.settings-connection-list,\n.settings-connection-rows {\n min-width: 0;\n}\n\n.settings-connections-layout {\n display: grid;\n grid-template-columns: minmax(0, 1.55fr) minmax(280px, 0.85fr);\n align-items: start;\n gap: 18px;\n}\n\n.settings-connection-list,\n.settings-connection-inspector {\n overflow: hidden;\n background: rgb(255 255 255 / 2%);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-connection-host-strip {\n display: grid;\n grid-template-columns: 30px minmax(0, 1fr) 30px;\n align-items: center;\n min-width: 0;\n gap: 6px;\n padding: 12px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-host-scroll {\n display: none;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 34px;\n padding: 0;\n color: var(--settings-muted);\n background: rgb(0 0 0 / 18%);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-connection-host-strip[data-connection-host-overflow="true"]\n .settings-connection-host-scroll {\n display: inline-flex;\n}\n\n.settings-connection-host-strip:not([data-connection-host-overflow="true"]) {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.settings-connection-host-scroll:hover:not(:disabled) {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-connection-host-scroll:disabled {\n cursor: default;\n opacity: 0.35;\n}\n\n.settings-connection-host-scroll:focus-visible,\n.settings-connection-host-tab:focus-visible,\n.settings-connection-row:focus-visible,\n.settings-connection-install-link:focus-visible,\n.settings-connection-view-error:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-connection-host-tabs {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 6px;\n overflow-x: auto;\n overflow-y: hidden;\n overscroll-behavior-x: contain;\n scrollbar-width: none;\n scroll-behavior: smooth;\n scroll-snap-type: x proximity;\n touch-action: pan-x;\n}\n\n.settings-connection-host-tabs::-webkit-scrollbar {\n display: none;\n}\n\n.settings-connection-host-tab {\n display: inline-flex;\n align-items: center;\n height: 34px;\n min-width: max-content;\n flex: none;\n padding: 0 11px;\n color: var(--settings-muted);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n white-space: nowrap;\n background: rgb(0 0 0 / 18%);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n cursor: pointer;\n scroll-snap-align: start;\n}\n\n.settings-connection-host-tab:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-connection-host-tab[aria-selected="true"] {\n color: #e8f3ff;\n font-weight: 600;\n background: var(--settings-active);\n border-color: rgb(51 156 255 / 50%);\n}\n\n.settings-connection-table-header,\n.settings-connection-row {\n display: grid;\n grid-template-columns: minmax(160px, 1fr) minmax(92px, auto) 82px;\n align-items: center;\n min-width: 0;\n gap: 14px;\n}\n\n.settings-connection-table-header {\n min-height: 36px;\n padding: 0 12px;\n color: var(--settings-muted);\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n background: rgb(255 255 255 / 2%);\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row {\n min-height: 64px;\n padding: 10px 12px;\n cursor: pointer;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row:last-child {\n border-bottom: 0;\n}\n\n.settings-connection-row:hover {\n background: var(--settings-hover);\n}\n\n.settings-connection-row[data-connection-selected="true"] {\n background: var(--settings-active);\n}\n\n.settings-connection-row__identity,\n.settings-connection-inspector__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n gap: 9px;\n color: var(--settings-text);\n}\n\n.settings-connection-row__identity strong,\n.settings-connection-inspector__identity strong {\n min-width: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n font-weight: 600;\n line-height: 19px;\n}\n\n.settings-connection-row__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n color: #d4d8de;\n font-size: 10px;\n font-weight: 700;\n background: rgb(255 255 255 / 6%);\n border-radius: 7px;\n}\n\n.settings-connection-row__mark--logo {\n color: var(--settings-text);\n background: transparent;\n}\n\n.settings-connection-row__mark--logo > img,\n.settings-connection-row__mark--logo > svg {\n display: block;\n max-width: 22px;\n max-height: 22px;\n}\n\n.settings-connection-row__status {\n display: inline-flex;\n align-items: center;\n width: fit-content;\n gap: 6px;\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n}\n\n.settings-connection-row__status::before {\n width: 7px;\n height: 7px;\n flex: none;\n content: "";\n background: currentColor;\n border-radius: 50%;\n}\n\n.settings-connection-row__status[data-connection-tone="ready"] {\n color: #4ade80;\n}\n\n.settings-connection-row__status[data-connection-tone="checking"] {\n color: #f5c542;\n}\n\n.settings-connection-row__status[data-connection-tone="setup"] {\n color: var(--settings-muted);\n}\n\n.settings-connection-row__status[data-connection-tone="setup"]::before {\n background: transparent;\n border: 1.5px solid currentColor;\n}\n\n.settings-connection-row__status[data-connection-tone="failed"] {\n color: #f87171;\n}\n\n.settings-connection-row__action {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-width: 0;\n}\n\n.settings-connection-install-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n color: var(--settings-focus);\n text-decoration: none;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 7px;\n}\n\n.settings-connection-install-link:hover {\n color: #8cc5ff;\n background: rgb(51 156 255 / 10%);\n border-color: rgb(51 156 255 / 22%);\n}\n\n.settings-connection-view-error {\n padding: 4px 7px;\n color: #f87171;\n font: inherit;\n font-size: 11px;\n line-height: 18px;\n background: transparent;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-connection-view-error:hover {\n color: #fca5a5;\n background: rgb(239 68 68 / 9%);\n}\n\n.settings-connection-inspector {\n position: sticky;\n top: 24px;\n}\n\n.settings-connection-inspector__header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n min-width: 0;\n gap: 12px;\n padding: 16px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-inspector__body {\n display: grid;\n min-width: 0;\n gap: 14px;\n padding: 16px;\n}\n\n.settings-connection-install-callout {\n display: grid;\n grid-template-columns: 32px minmax(0, 1fr);\n gap: 10px;\n padding: 14px;\n background: linear-gradient(rgb(51 156 255 / 8%), rgb(51 156 255 / 4%));\n border: 1px solid rgb(51 156 255 / 20%);\n border-radius: 10px;\n}\n\n.settings-connection-install-callout__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n color: var(--settings-focus);\n background: var(--settings-active);\n border-radius: 8px;\n}\n\n.settings-connection-install-callout strong,\n.settings-connection-error-summary strong,\n.settings-connection-state-summary strong {\n display: block;\n margin: 0 0 4px;\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 600;\n line-height: 19px;\n}\n\n.settings-connection-install-callout p,\n.settings-connection-error-summary p,\n.settings-connection-state-summary p,\n.settings-connection-issue-note {\n margin: 0;\n color: var(--settings-muted);\n font-size: 11px;\n line-height: 17px;\n}\n\n.settings-connection-install-button {\n width: 100%;\n}\n\n.settings-connection-error-summary {\n padding: 13px 14px;\n color: #fecaca;\n background: rgb(239 68 68 / 7%);\n border: 1px solid rgb(239 68 68 / 20%);\n border-radius: 10px;\n}\n\n.settings-connection-error-metadata {\n display: grid;\n gap: 7px;\n padding: 12px;\n background: rgb(0 0 0 / 18%);\n border: 1px solid var(--settings-border);\n border-radius: 9px;\n}\n\n.settings-connection-detail-line {\n display: grid;\n grid-template-columns: 92px minmax(0, 1fr);\n gap: 10px;\n min-width: 0;\n color: var(--settings-muted);\n font-size: 10px;\n line-height: 16px;\n}\n\n.settings-connection-detail-line code {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n white-space: pre-wrap;\n}\n\n.settings-connection-error-log-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n}\n\n.settings-connection-error-log-header strong {\n color: var(--settings-text);\n font-size: 11px;\n font-weight: 600;\n}\n\n.settings-connection-error-log-header .settings-command-button {\n min-height: 30px;\n padding: 5px 9px;\n font-size: 11px;\n}\n\n.settings-connection-stderr {\n max-height: 220px;\n min-width: 0;\n margin: 0;\n padding: 11px;\n overflow: auto;\n color: #e3e5e8;\n font:\n 10px/16px ui-monospace,\n "SFMono-Regular",\n Consolas,\n "Liberation Mono",\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n background: rgb(0 0 0 / 28%);\n border: 1px solid var(--settings-border);\n border-radius: 9px;\n}\n\n.settings-connection-error-actions {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: 8px;\n}\n\n.settings-connection-error-actions .settings-command-button {\n width: 100%;\n}\n\n.settings-connection-issue-note {\n margin-top: -4px;\n}\n\n.settings-connection-state-summary {\n padding: 14px;\n background: rgb(255 255 255 / 3%);\n border: 1px solid var(--settings-border);\n border-radius: 10px;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-about-panel {\n display: grid;\n max-width: 720px;\n gap: 18px;\n padding: 28px;\n background: rgb(255 255 255 / 2%);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-about-product {\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 700;\n line-height: 32px;\n}\n\n.settings-about-tagline {\n color: var(--settings-text);\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n\n.settings-about-copy {\n display: grid;\n max-width: 660px;\n gap: 12px;\n}\n\n.settings-about-copy p,\n.settings-about-repository p {\n margin: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 21px;\n}\n\n.settings-about-star-callout {\n margin: 2px 0;\n color: #f5c542;\n font-size: 14px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-about-repository {\n display: grid;\n gap: 10px;\n padding-top: 18px;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-about-repository-link {\n display: flex;\n align-items: center;\n width: fit-content;\n min-width: 0;\n max-width: 100%;\n gap: 8px;\n color: #7cb8ff;\n font-size: 13px;\n font-weight: 600;\n text-decoration: none;\n}\n\n.settings-about-repository-link:hover {\n text-decoration: underline;\n}\n\n.settings-about-repository-link code {\n min-width: 0;\n overflow: hidden;\n color: var(--settings-muted);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 11px;\n font-weight: 400;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n/* The only emphasis on this screen: a latest version newer than the installed one. */\n.settings-update-metadata__value--newer {\n color: #4aa3f0;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 12px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-update-panel__head {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-update-panel__head .codexhost-settings-icon {\n color: var(--settings-muted);\n}\n\n.settings-update-panel[data-update-state="available"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="downloading"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="installing"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="restarting"] .codexhost-settings-icon {\n color: #4aa3f0;\n}\n\n.settings-update-panel[data-update-state="current"] .codexhost-settings-icon {\n color: #4ade80;\n}\n\n.settings-update-panel[data-update-state="failed"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="error"] .codexhost-settings-icon {\n color: #ef4444;\n}\n\n.settings-update-panel__title {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n/* Release notes scroll with the page; a scroller inside a scroller traps the wheel. */\n.settings-update-notes-section {\n min-width: 0;\n margin-top: 24px;\n padding-top: 24px;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-update-notes-section:empty {\n display: none;\n}\n\n.settings-update-notes {\n display: grid;\n min-width: 0;\n gap: 12px;\n color: var(--settings-muted);\n font-size: 14px;\n line-height: 22px;\n overflow-wrap: anywhere;\n}\n\n.settings-update-notes > :first-child {\n margin-top: 0;\n}\n\n.settings-update-notes > :last-child {\n margin-bottom: 0;\n}\n\n.settings-update-notes h1,\n.settings-update-notes h2,\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n margin: 6px 0 0;\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes h1 {\n font-size: 18px;\n line-height: 26px;\n}\n\n.settings-update-notes h2 {\n font-size: 17px;\n line-height: 24px;\n}\n\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n font-size: 14px;\n line-height: 22px;\n}\n\n.settings-update-notes p,\n.settings-update-notes ul,\n.settings-update-notes ol,\n.settings-update-notes pre,\n.settings-update-notes blockquote {\n margin: 0;\n}\n\n.settings-update-notes ul,\n.settings-update-notes ol {\n padding-left: 24px;\n}\n\n.settings-update-notes li {\n padding-left: 4px;\n}\n\n.settings-update-notes li::marker {\n color: var(--settings-muted);\n font-size: 0.85em;\n}\n\n.settings-update-notes li + li {\n margin-top: 14px;\n}\n\n.settings-update-notes .release-note-translation {\n display: block;\n margin-top: 3px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-notes blockquote {\n padding: 8px 12px;\n color: var(--settings-muted);\n border-left: 3px solid var(--settings-focus);\n background: rgb(255 255 255 / 4%);\n}\n\n.settings-update-notes hr {\n width: 100%;\n margin: 2px 0;\n border: 0;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-update-notes strong {\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes a {\n color: #7cb8ff;\n text-decoration: none;\n}\n\n.settings-update-notes a:hover {\n text-decoration: underline;\n}\n\n.settings-update-notes code {\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n}\n\n.settings-update-notes :not(pre) > code {\n padding: 1px 5px;\n background: rgb(255 255 255 / 8%);\n border-radius: 4px;\n}\n\n.settings-update-notes pre {\n min-width: 0;\n max-width: 100%;\n padding: 10px 12px;\n overflow-x: auto;\n overflow-y: hidden;\n background: rgb(0 0 0 / 28%);\n border-radius: 6px;\n}\n\n.settings-update-notes pre code {\n line-height: 18px;\n white-space: pre-wrap;\n}\n\n/* Manual update sits directly under the status panel, not behind a disclosure:\n automatic updates can fail for machine-local reasons and this is the way out. */\n.settings-update-controls {\n display: grid;\n min-width: 0;\n gap: 10px;\n margin-top: 24px;\n}\n\n.settings-update-manual-title {\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual-description {\n margin: 0;\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual-description.is-fallback {\n color: #ef4444;\n}\n\n.settings-update-command {\n display: flex;\n align-items: stretch;\n min-width: 0;\n overflow: hidden;\n border: 1px solid var(--settings-border);\n border-radius: 6px;\n}\n\n.settings-update-command code {\n min-width: 0;\n flex: 1;\n padding: 9px 12px;\n overflow-x: auto;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 20px;\n white-space: nowrap;\n}\n\n.settings-update-command__copy {\n display: inline-flex;\n align-items: center;\n flex: none;\n gap: 6px;\n padding: 0 12px;\n color: var(--settings-muted);\n font-size: 12px;\n background: transparent;\n border: 0;\n border-left: 1px solid var(--settings-border);\n cursor: pointer;\n}\n\n.settings-update-command__copy:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-update-command__copy:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: -2px;\n}\n\n.settings-update-actions {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-section-label {\n display: none;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-nav-star-link {\n margin-top: 0;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-update-metadata {\n grid-template-columns: minmax(0, 1fr);\n gap: 16px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-connection-page-header {\n flex-direction: column;\n }\n\n .settings-connection-page-header > .settings-command-button {\n width: 100%;\n }\n\n .settings-connections-layout {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .settings-connection-inspector {\n position: static;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
|
|
20972
21733
|
|
|
20973
21734
|
// src/settings/shell.ts
|
|
20974
21735
|
var SETTINGS_SHELL_ATTRIBUTE = "data-codexhost-settings-shell";
|
|
20975
|
-
var CODEXHOST_GITHUB_REPOSITORY_URL = "https://github.com/BytePioneer-AI/codex-host";
|
|
20976
21736
|
function isRendererSettingsDialogSupported(dialog) {
|
|
20977
21737
|
return typeof dialog.showModal === "function" && typeof dialog.close === "function";
|
|
20978
21738
|
}
|
|
@@ -21019,23 +21779,13 @@ ${error51.stderrTail}`] : []
|
|
|
21019
21779
|
brand.append(brandMark, brandCopy);
|
|
21020
21780
|
const headerActions = ownerDocument.createElement("div");
|
|
21021
21781
|
headerActions.className = "settings-header-actions";
|
|
21022
|
-
const starLink = ownerDocument.createElement("a");
|
|
21023
|
-
starLink.className = "settings-icon-button settings-star-link";
|
|
21024
|
-
starLink.href = CODEXHOST_GITHUB_REPOSITORY_URL;
|
|
21025
|
-
starLink.target = "_blank";
|
|
21026
|
-
starLink.rel = "noopener noreferrer";
|
|
21027
|
-
starLink.setAttribute("aria-label", messages.starOnGitHub);
|
|
21028
|
-
starLink.title = messages.starOnGitHub;
|
|
21029
|
-
const starLabel = ownerDocument.createElement("span");
|
|
21030
|
-
starLabel.textContent = messages.starOnGitHub;
|
|
21031
|
-
starLink.append(createRendererSettingsIcon("star", 16), starLabel);
|
|
21032
21782
|
const closeButton = ownerDocument.createElement("button");
|
|
21033
21783
|
closeButton.type = "button";
|
|
21034
21784
|
closeButton.className = "settings-icon-button";
|
|
21035
21785
|
closeButton.setAttribute("aria-label", messages.close);
|
|
21036
21786
|
closeButton.title = messages.close;
|
|
21037
21787
|
closeButton.append(createRendererSettingsIcon("close", 18));
|
|
21038
|
-
headerActions.append(
|
|
21788
|
+
headerActions.append(closeButton);
|
|
21039
21789
|
header.append(brand, headerActions);
|
|
21040
21790
|
const layout = ownerDocument.createElement("div");
|
|
21041
21791
|
layout.className = "settings-layout";
|
|
@@ -21101,7 +21851,19 @@ ${error51.stderrTail}`] : []
|
|
|
21101
21851
|
renderMountFailure();
|
|
21102
21852
|
}
|
|
21103
21853
|
};
|
|
21854
|
+
const appendNavigationSection = (label) => {
|
|
21855
|
+
const section = ownerDocument.createElement("div");
|
|
21856
|
+
section.className = "settings-nav-section-label";
|
|
21857
|
+
section.textContent = label;
|
|
21858
|
+
navigation.append(section);
|
|
21859
|
+
};
|
|
21860
|
+
let otherSectionAdded = false;
|
|
21861
|
+
appendNavigationSection(messages.generalSection);
|
|
21104
21862
|
for (const definition of resolvedRegistry.pages) {
|
|
21863
|
+
if (definition.id === "about" && !otherSectionAdded) {
|
|
21864
|
+
appendNavigationSection(messages.otherSection);
|
|
21865
|
+
otherSectionAdded = true;
|
|
21866
|
+
}
|
|
21105
21867
|
const button = ownerDocument.createElement("button");
|
|
21106
21868
|
button.type = "button";
|
|
21107
21869
|
button.className = "settings-nav-button";
|
|
@@ -21113,6 +21875,18 @@ ${error51.stderrTail}`] : []
|
|
|
21113
21875
|
navigationButtons.set(definition.id, button);
|
|
21114
21876
|
navigation.append(button);
|
|
21115
21877
|
}
|
|
21878
|
+
const starLink = ownerDocument.createElement("a");
|
|
21879
|
+
starLink.className = "settings-nav-button settings-nav-star-link";
|
|
21880
|
+
starLink.href = CODEXHOST_GITHUB_REPOSITORY_URL;
|
|
21881
|
+
starLink.target = "_blank";
|
|
21882
|
+
starLink.rel = "noopener noreferrer";
|
|
21883
|
+
starLink.setAttribute("aria-label", messages.starOnGitHub);
|
|
21884
|
+
starLink.title = messages.starOnGitHub;
|
|
21885
|
+
starLink.append(createRendererSettingsIcon("star", 17));
|
|
21886
|
+
const starLabel = ownerDocument.createElement("span");
|
|
21887
|
+
starLabel.textContent = messages.starOnGitHub;
|
|
21888
|
+
starLink.append(starLabel);
|
|
21889
|
+
navigation.append(starLink);
|
|
21116
21890
|
const supported = isRendererSettingsDialogSupported(dialog);
|
|
21117
21891
|
const focusActiveNavigation = () => {
|
|
21118
21892
|
navigationButtons.get(navigationState.activePageId)?.focus();
|
|
@@ -21454,6 +22228,7 @@ ${error51.stderrTail}`] : []
|
|
|
21454
22228
|
trigger = null;
|
|
21455
22229
|
shell = null;
|
|
21456
22230
|
const mounted = mount();
|
|
22231
|
+
options.onLocaleChange?.(locale);
|
|
21457
22232
|
if (reopen) {
|
|
21458
22233
|
const opener = mounted.trigger.root?.querySelector("button") ?? void 0;
|
|
21459
22234
|
mounted.shell.openSettings(opener, activePageId);
|
|
@@ -21595,6 +22370,9 @@ ${error51.stderrTail}`] : []
|
|
|
21595
22370
|
);
|
|
21596
22371
|
}
|
|
21597
22372
|
var rendererUsageRefreshDelays = [250, 500, 1e3, 2e3, 4e3, 8e3];
|
|
22373
|
+
function refreshConnectionHosts(hostIds, refreshHost) {
|
|
22374
|
+
return Promise.all([...hostIds].map((hostId) => refreshHost(hostId))).then(() => void 0);
|
|
22375
|
+
}
|
|
21598
22376
|
function rendererUsageRefreshDelay(attempt) {
|
|
21599
22377
|
const index = Math.max(0, Math.min(Math.trunc(attempt), rendererUsageRefreshDelays.length - 1));
|
|
21600
22378
|
return rendererUsageRefreshDelays[index] ?? rendererUsageRefreshDelays[0];
|
|
@@ -21619,6 +22397,13 @@ ${error51.stderrTail}`] : []
|
|
|
21619
22397
|
function draftPermissionMode(catalog, requested) {
|
|
21620
22398
|
return catalog.modes.find(({ id }) => id === requested)?.id ?? catalog.modes.find(({ id }) => id === catalog.defaultModeId)?.id ?? catalog.defaultModeId;
|
|
21621
22399
|
}
|
|
22400
|
+
function lockedPermissionMode(catalog, effective, carrier) {
|
|
22401
|
+
const restored = effective ?? carrier;
|
|
22402
|
+
if (restored && !catalog.modes.some(({ id }) => id === restored)) {
|
|
22403
|
+
throw new Error("Existing Thread Permission Mode is absent from the current Catalog");
|
|
22404
|
+
}
|
|
22405
|
+
return restored;
|
|
22406
|
+
}
|
|
21622
22407
|
function shouldPersistNewThreadConfigurationSelection(phase) {
|
|
21623
22408
|
return phase === "draft";
|
|
21624
22409
|
}
|
|
@@ -21685,7 +22470,12 @@ ${error51.stderrTail}`] : []
|
|
|
21685
22470
|
throw new Error("DeepSeek Harness Thread reported an incompatible transport Model");
|
|
21686
22471
|
}
|
|
21687
22472
|
const model = inspection.effectiveModel ?? transportSelection.model;
|
|
21688
|
-
|
|
22473
|
+
const permissionModeId = inspection.effectivePermissionModeId ?? transportSelection.permissionModeId;
|
|
22474
|
+
return {
|
|
22475
|
+
agent: "deepseek-harness",
|
|
22476
|
+
...model ? { model } : {},
|
|
22477
|
+
...permissionModeId ? { permissionModeId } : {}
|
|
22478
|
+
};
|
|
21689
22479
|
}
|
|
21690
22480
|
throw new Error("Thread owner is not a Renderer Agent");
|
|
21691
22481
|
}
|
|
@@ -21792,7 +22582,10 @@ ${error51.stderrTail}`] : []
|
|
|
21792
22582
|
let connectionDiagnostics = null;
|
|
21793
22583
|
const settingsLifecycle = installRendererSettingsLifecycle(window, {
|
|
21794
22584
|
getUpdateClient: () => modelControl,
|
|
21795
|
-
getConnectionDiagnostics: () => connectionDiagnostics
|
|
22585
|
+
getConnectionDiagnostics: () => connectionDiagnostics,
|
|
22586
|
+
onLocaleChange() {
|
|
22587
|
+
for (const mounted of mountedByComposer.values()) renderMounted(mounted);
|
|
22588
|
+
}
|
|
21796
22589
|
});
|
|
21797
22590
|
let adapterStatus = {
|
|
21798
22591
|
state: "installing",
|
|
@@ -21871,7 +22664,8 @@ ${error51.stderrTail}`] : []
|
|
|
21871
22664
|
mounted.modelView,
|
|
21872
22665
|
mounted.permissionModeView,
|
|
21873
22666
|
mounted.usage,
|
|
21874
|
-
mounted.accountCredits
|
|
22667
|
+
mounted.accountCredits,
|
|
22668
|
+
settingsLifecycle.locale
|
|
21875
22669
|
);
|
|
21876
22670
|
if (mounted.control.usage) {
|
|
21877
22671
|
mounted.control.usage.onOpen = () => {
|
|
@@ -22159,11 +22953,15 @@ ${error51.stderrTail}`] : []
|
|
|
22159
22953
|
throw new Error("External Harness omitted its Permission Mode catalog");
|
|
22160
22954
|
}
|
|
22161
22955
|
mounted.permissionModeView = { status: "loading", catalog: permissionModes };
|
|
22162
|
-
const
|
|
22956
|
+
const restoredPermissionModeId = current.phase === "locked" ? lockedPermissionMode(
|
|
22957
|
+
permissionModes,
|
|
22958
|
+
mounted.threadConfiguration?.effectivePermissionModeId,
|
|
22959
|
+
previousPermissionModeId
|
|
22960
|
+
) : void 0;
|
|
22163
22961
|
const preferredPermissionModeId = preferredConfiguration?.permissionModeId ?? (agent === "claude-code" ? readClaudePermissionModePreference(permissionModes) : void 0);
|
|
22164
22962
|
selectedPermissionModeId = draftPermissionMode(
|
|
22165
22963
|
permissionModes,
|
|
22166
|
-
|
|
22964
|
+
restoredPermissionModeId ?? previousPermissionModeId ?? preferredPermissionModeId
|
|
22167
22965
|
);
|
|
22168
22966
|
mounted.permissionModeView = {
|
|
22169
22967
|
status: "loading",
|
|
@@ -22871,10 +23669,10 @@ ${error51.stderrTail}`] : []
|
|
|
22871
23669
|
};
|
|
22872
23670
|
},
|
|
22873
23671
|
refresh() {
|
|
22874
|
-
|
|
22875
|
-
|
|
22876
|
-
|
|
22877
|
-
|
|
23672
|
+
return refreshConnectionHosts(
|
|
23673
|
+
harnessAvailabilityByHost.keys(),
|
|
23674
|
+
(hostId) => refreshHarnessAvailabilityForHost(hostId, true, false, true)
|
|
23675
|
+
);
|
|
22878
23676
|
},
|
|
22879
23677
|
subscribe(listener) {
|
|
22880
23678
|
connectionListeners.add(listener);
|
|
@@ -23382,10 +24180,14 @@ lucide/dist/esm/icons/chevron-down.mjs:
|
|
|
23382
24180
|
lucide/dist/esm/icons/shield.mjs:
|
|
23383
24181
|
lucide/dist/esm/icons/shield-alert.mjs:
|
|
23384
24182
|
lucide/dist/esm/icons/boxes.mjs:
|
|
24183
|
+
lucide/dist/esm/icons/circle-check.mjs:
|
|
24184
|
+
lucide/dist/esm/icons/chevron-left.mjs:
|
|
24185
|
+
lucide/dist/esm/icons/chevron-right.mjs:
|
|
23385
24186
|
lucide/dist/esm/icons/circle-off.mjs:
|
|
23386
24187
|
lucide/dist/esm/icons/copy.mjs:
|
|
23387
24188
|
lucide/dist/esm/icons/download.mjs:
|
|
23388
24189
|
lucide/dist/esm/icons/external-link.mjs:
|
|
24190
|
+
lucide/dist/esm/icons/info.mjs:
|
|
23389
24191
|
lucide/dist/esm/icons/languages.mjs:
|
|
23390
24192
|
lucide/dist/esm/icons/network.mjs:
|
|
23391
24193
|
lucide/dist/esm/icons/plug-zap.mjs:
|
|
@@ -23394,6 +24196,7 @@ lucide/dist/esm/icons/route.mjs:
|
|
|
23394
24196
|
lucide/dist/esm/icons/settings.mjs:
|
|
23395
24197
|
lucide/dist/esm/icons/stethoscope.mjs:
|
|
23396
24198
|
lucide/dist/esm/icons/star.mjs:
|
|
24199
|
+
lucide/dist/esm/icons/triangle-alert.mjs:
|
|
23397
24200
|
lucide/dist/esm/icons/x.mjs:
|
|
23398
24201
|
(**
|
|
23399
24202
|
* @license lucide v1.28.0 - ISC
|