@michengai/dsh-codex-ui 0.2.113 → 1.1.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/CHANGELOG.md +55 -1
- package/CHANGELOG.zh-CN.md +55 -1
- package/README.md +9 -5
- package/README.zh-CN.md +9 -5
- package/assets/screenshots/conversation-light.png +0 -0
- package/assets/screenshots/conversation.png +0 -0
- package/assets/screenshots/settings-about.png +0 -0
- package/assets/screenshots/settings-general-light.png +0 -0
- package/assets/usage-frame.html +1 -0
- package/cordis.patch.yml +3 -1
- package/lib/client.js +2229 -112
- package/lib/index.mjs +59 -3
- package/lib/usage-frame.css +1 -0
- package/lib/usage-frame.js +489 -0
- package/package.json +10 -6
package/lib/client.js
CHANGED
|
@@ -7,6 +7,146 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
let react = require("react");
|
|
8
8
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
9
9
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
|
+
let react_dom = require("react-dom");
|
|
11
|
+
/** 按用户要求用最窄宽度替代宿主自适应默认;已有有效偏好不重置,拖拽起点沿用宿主存储。 */
|
|
12
|
+
function initializeComposerWidth(storage) {
|
|
13
|
+
const key = "dsh.conversation.contentWidth";
|
|
14
|
+
try {
|
|
15
|
+
const saved = Number(storage.getItem(key));
|
|
16
|
+
if (Number.isFinite(saved) && saved > 0) return;
|
|
17
|
+
storage.setItem(key, String(640));
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.warn("[codex-ui] 无法初始化输入区宽度,将使用宿主默认值。", error);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** 新建页没有宿主 WidthHandle,补充同一宽度偏好的拖拽入口。 */
|
|
23
|
+
function observeHeroWidthHandles(label) {
|
|
24
|
+
const mounted = /* @__PURE__ */ new Map();
|
|
25
|
+
const style = document.createElement("style");
|
|
26
|
+
style.textContent = `[data-phase=hero]:has([data-conversation-scroll]){position:relative}[data-dcu-width-handle]{position:absolute;top:0;bottom:0;width:32px;padding:0;border:0;background:transparent;cursor:col-resize;touch-action:none;z-index:8;outline-offset:-5px}[data-dcu-width-handle=left]{right:calc(50% + var(--dsh-chat-content-width) / 2 + 16px)}[data-dcu-width-handle=right]{left:calc(50% + var(--dsh-chat-content-width) / 2 + 16px)}[data-dcu-width-handle]::after{content:'';position:absolute;top:calc(var(--dcu-pointer-y,50%) - 50px);height:100px;width:3px;left:14px;border-radius:3px;background:linear-gradient(transparent,var(--dsw-alias-scrollbar-hover-l1,#888),transparent);opacity:0}[data-dcu-width-handle]:hover::after,[data-dcu-width-handle]:focus-visible::after,[data-dcu-width-handle][data-dragging]::after{opacity:1}[data-phase=hero]:has([data-conversation-composer-overlay]) [data-dcu-width-handle]{display:none}`;
|
|
27
|
+
document.head.append(style);
|
|
28
|
+
const sync = () => {
|
|
29
|
+
for (const [root, dispose] of mounted) if (!root.isConnected || root.dataset.phase !== "hero") {
|
|
30
|
+
dispose();
|
|
31
|
+
mounted.delete(root);
|
|
32
|
+
}
|
|
33
|
+
for (const root of document.querySelectorAll("[data-phase=hero]")) {
|
|
34
|
+
if (mounted.has(root) || !root.querySelector("[data-conversation-scroll]")) continue;
|
|
35
|
+
const clamp = (value) => Math.min(Math.max(640, value), Math.max(640, root.clientWidth - 176));
|
|
36
|
+
const current = () => {
|
|
37
|
+
const raw = getComputedStyle(root).getPropertyValue("--dsh-chat-user-width");
|
|
38
|
+
return clamp(parseFloat(raw) || 640);
|
|
39
|
+
};
|
|
40
|
+
const publish = (width, save) => {
|
|
41
|
+
const value = clamp(width);
|
|
42
|
+
root.style.setProperty("--dsh-chat-user-width", `${value}px`);
|
|
43
|
+
if (save) try {
|
|
44
|
+
localStorage.setItem("dsh.conversation.contentWidth", String(value));
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.warn("[codex-ui] 无法保存输入区宽度。", error);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const handles = ["left", "right"].map((side) => {
|
|
50
|
+
const handle = document.createElement("button");
|
|
51
|
+
handle.type = "button";
|
|
52
|
+
handle.dataset.dcuWidthHandle = side;
|
|
53
|
+
handle.setAttribute("aria-label", label);
|
|
54
|
+
let origin = 0;
|
|
55
|
+
let initial = 640;
|
|
56
|
+
let dragging = false;
|
|
57
|
+
handle.addEventListener("pointerdown", (event) => {
|
|
58
|
+
if (event.button !== 0) return;
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
origin = event.clientX;
|
|
61
|
+
initial = current();
|
|
62
|
+
dragging = true;
|
|
63
|
+
handle.dataset.dragging = "";
|
|
64
|
+
handle.setPointerCapture(event.pointerId);
|
|
65
|
+
});
|
|
66
|
+
handle.addEventListener("pointermove", (event) => {
|
|
67
|
+
handle.style.setProperty("--dcu-pointer-y", `${event.clientY - handle.getBoundingClientRect().top}px`);
|
|
68
|
+
if (dragging) publish(initial + (event.clientX - origin) * (side === "right" ? 2 : -2), false);
|
|
69
|
+
});
|
|
70
|
+
handle.addEventListener("pointerup", (event) => {
|
|
71
|
+
if (!dragging) return;
|
|
72
|
+
publish(initial + (event.clientX - origin) * (side === "right" ? 2 : -2), true);
|
|
73
|
+
dragging = false;
|
|
74
|
+
delete handle.dataset.dragging;
|
|
75
|
+
handle.releasePointerCapture(event.pointerId);
|
|
76
|
+
});
|
|
77
|
+
handle.addEventListener("lostpointercapture", () => {
|
|
78
|
+
if (dragging) publish(initial, false);
|
|
79
|
+
dragging = false;
|
|
80
|
+
delete handle.dataset.dragging;
|
|
81
|
+
});
|
|
82
|
+
handle.addEventListener("keydown", (event) => {
|
|
83
|
+
if (![
|
|
84
|
+
"ArrowLeft",
|
|
85
|
+
"ArrowRight",
|
|
86
|
+
"Home"
|
|
87
|
+
].includes(event.key)) return;
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
const delta = (event.key === "ArrowRight" ? 1 : -1) * (side === "right" ? 1 : -1) * 20;
|
|
90
|
+
publish(event.key === "Home" ? 640 : current() + delta, true);
|
|
91
|
+
});
|
|
92
|
+
root.append(handle);
|
|
93
|
+
return handle;
|
|
94
|
+
});
|
|
95
|
+
mounted.set(root, () => {
|
|
96
|
+
handles.forEach((handle) => handle.remove());
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const observer = new MutationObserver(sync);
|
|
101
|
+
observer.observe(document.body, {
|
|
102
|
+
childList: true,
|
|
103
|
+
subtree: true,
|
|
104
|
+
attributes: true,
|
|
105
|
+
attributeFilter: ["data-phase"]
|
|
106
|
+
});
|
|
107
|
+
sync();
|
|
108
|
+
return () => {
|
|
109
|
+
observer.disconnect();
|
|
110
|
+
mounted.forEach((dispose) => dispose());
|
|
111
|
+
mounted.clear();
|
|
112
|
+
style.remove();
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/client/tree-expansion.ts
|
|
117
|
+
const WORKSPACE_EXPANSION_STORAGE_KEY = "dsh-codex-ui.workspace-expansion.v1";
|
|
118
|
+
const CHANNEL_EXPANSION_STORAGE_KEY = "dsh-codex-ui.channel-expansion.v1";
|
|
119
|
+
const SCHEDULE_EXPANSION_STORAGE_KEY = "dsh-codex-ui.schedule-expansion.v1";
|
|
120
|
+
const MAX_EXPANSION_ENTRIES = 500;
|
|
121
|
+
const MAX_EXPANSION_KEY_LENGTH = 512;
|
|
122
|
+
function browserStorage() {
|
|
123
|
+
if (typeof window === "undefined") return void 0;
|
|
124
|
+
try {
|
|
125
|
+
return window.localStorage;
|
|
126
|
+
} catch {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function parseTreeExpansionState(value) {
|
|
131
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return {};
|
|
132
|
+
const entries = Object.entries(value).filter(([key, expanded]) => key.length > 0 && key.length <= MAX_EXPANSION_KEY_LENGTH && typeof expanded === "boolean").slice(0, MAX_EXPANSION_ENTRIES);
|
|
133
|
+
return Object.fromEntries(entries);
|
|
134
|
+
}
|
|
135
|
+
function readTreeExpansionState(storage, key) {
|
|
136
|
+
if (storage === void 0) return {};
|
|
137
|
+
try {
|
|
138
|
+
return parseTreeExpansionState(JSON.parse(storage.getItem(key) ?? "{}"));
|
|
139
|
+
} catch {
|
|
140
|
+
return {};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function writeTreeExpansionState(storage, key, state) {
|
|
144
|
+
if (storage === void 0) return;
|
|
145
|
+
try {
|
|
146
|
+
storage.setItem(key, JSON.stringify(parseTreeExpansionState(state)));
|
|
147
|
+
} catch {}
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
10
150
|
//#region src/client/settings-navigation.ts
|
|
11
151
|
/**
|
|
12
152
|
* DSH 设置壳暂未提供按 section id 打开的公开 API。该兼容层只从本插件渲染
|
|
@@ -30,16 +170,31 @@ window.__ModuleLoader__.load({
|
|
|
30
170
|
}
|
|
31
171
|
let cancelPendingNavigation;
|
|
32
172
|
const SETTINGS_NAVIGATION_TIMEOUT_MS = 4e3;
|
|
173
|
+
const SETTINGS_TRIGGER_SELECTOR = "[data-dcu-settings-trigger],[aria-haspopup=\"dialog\"]";
|
|
174
|
+
const SETTINGS_OPEN_SECTION_EVENT = "dcu-settings-open-section";
|
|
175
|
+
/** 根入口与分区跳转使用同一触发器合约,兼容保留的宿主设置壳。 */
|
|
176
|
+
function openSettingsRoot(root) {
|
|
177
|
+
root?.querySelector(SETTINGS_TRIGGER_SELECTOR)?.click();
|
|
178
|
+
}
|
|
33
179
|
function openSettingsSection(root, label, onMissing, onSelected) {
|
|
34
180
|
const labels = typeof label === "string" ? [label] : label;
|
|
35
|
-
const trigger = root?.querySelector(
|
|
181
|
+
const trigger = root?.querySelector(SETTINGS_TRIGGER_SELECTOR);
|
|
36
182
|
if (trigger === null || trigger === void 0) {
|
|
37
183
|
onMissing?.();
|
|
38
184
|
return;
|
|
39
185
|
}
|
|
40
186
|
const opening = cancelPendingNavigation !== void 0;
|
|
41
187
|
cancelPendingNavigation?.();
|
|
42
|
-
|
|
188
|
+
const request = new CustomEvent(SETTINGS_OPEN_SECTION_EVENT, {
|
|
189
|
+
detail: { labels },
|
|
190
|
+
cancelable: true
|
|
191
|
+
});
|
|
192
|
+
if (!trigger.dispatchEvent(request)) {
|
|
193
|
+
onSelected?.();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const pageSelector = trigger.hasAttribute("data-dcu-settings-trigger") ? "[data-dcu-settings-page]" : "[role=\"dialog\"]";
|
|
197
|
+
if (!opening && document.querySelector(pageSelector) === null) trigger.click();
|
|
43
198
|
let frame;
|
|
44
199
|
let finished = false;
|
|
45
200
|
const observer = new MutationObserver(() => {
|
|
@@ -54,7 +209,7 @@ window.__ModuleLoader__.load({
|
|
|
54
209
|
if (cancelPendingNavigation === cleanup) cancelPendingNavigation = void 0;
|
|
55
210
|
};
|
|
56
211
|
const select = () => {
|
|
57
|
-
const target = pickSettingsSectionButton([...document.querySelectorAll(
|
|
212
|
+
const target = pickSettingsSectionButton([...document.querySelectorAll(`${pageSelector} nav button`)], labels);
|
|
58
213
|
if (target === void 0) return false;
|
|
59
214
|
cleanup();
|
|
60
215
|
target.click();
|
|
@@ -483,6 +638,224 @@ window.__ModuleLoader__.load({
|
|
|
483
638
|
* This source code is licensed under the ISC license.
|
|
484
639
|
* See the LICENSE file in the root directory of this source tree.
|
|
485
640
|
*/
|
|
641
|
+
const ArrowLeft = createLucideIcon("arrow-left", [["path", {
|
|
642
|
+
d: "m12 19-7-7 7-7",
|
|
643
|
+
key: "1l729n"
|
|
644
|
+
}], ["path", {
|
|
645
|
+
d: "M19 12H5",
|
|
646
|
+
key: "x3x0zl"
|
|
647
|
+
}]]);
|
|
648
|
+
/**
|
|
649
|
+
* @license lucide-react v1.39.0 - ISC
|
|
650
|
+
*
|
|
651
|
+
* This source code is licensed under the ISC license.
|
|
652
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
653
|
+
*/
|
|
654
|
+
const Box = createLucideIcon("box", [
|
|
655
|
+
["path", {
|
|
656
|
+
d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z",
|
|
657
|
+
key: "hh9hay"
|
|
658
|
+
}],
|
|
659
|
+
["path", {
|
|
660
|
+
d: "m3.3 7 8.7 5 8.7-5",
|
|
661
|
+
key: "g66t2b"
|
|
662
|
+
}],
|
|
663
|
+
["path", {
|
|
664
|
+
d: "M12 22V12",
|
|
665
|
+
key: "d0xqtd"
|
|
666
|
+
}]
|
|
667
|
+
]);
|
|
668
|
+
/**
|
|
669
|
+
* @license lucide-react v1.39.0 - ISC
|
|
670
|
+
*
|
|
671
|
+
* This source code is licensed under the ISC license.
|
|
672
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
673
|
+
*/
|
|
674
|
+
const Bug = createLucideIcon("bug", [
|
|
675
|
+
["path", {
|
|
676
|
+
d: "M12 20v-9",
|
|
677
|
+
key: "1qisl0"
|
|
678
|
+
}],
|
|
679
|
+
["path", {
|
|
680
|
+
d: "M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z",
|
|
681
|
+
key: "uouzyp"
|
|
682
|
+
}],
|
|
683
|
+
["path", {
|
|
684
|
+
d: "M14.12 3.88 16 2",
|
|
685
|
+
key: "qol33r"
|
|
686
|
+
}],
|
|
687
|
+
["path", {
|
|
688
|
+
d: "M21 21a4 4 0 0 0-3.81-4",
|
|
689
|
+
key: "1b0z45"
|
|
690
|
+
}],
|
|
691
|
+
["path", {
|
|
692
|
+
d: "M21 5a4 4 0 0 1-3.55 3.97",
|
|
693
|
+
key: "5cxbf6"
|
|
694
|
+
}],
|
|
695
|
+
["path", {
|
|
696
|
+
d: "M22 13h-4",
|
|
697
|
+
key: "1jl80f"
|
|
698
|
+
}],
|
|
699
|
+
["path", {
|
|
700
|
+
d: "M3 21a4 4 0 0 1 3.81-4",
|
|
701
|
+
key: "1fjd4g"
|
|
702
|
+
}],
|
|
703
|
+
["path", {
|
|
704
|
+
d: "M3 5a4 4 0 0 0 3.55 3.97",
|
|
705
|
+
key: "1d7oge"
|
|
706
|
+
}],
|
|
707
|
+
["path", {
|
|
708
|
+
d: "M6 13H2",
|
|
709
|
+
key: "82j7cp"
|
|
710
|
+
}],
|
|
711
|
+
["path", {
|
|
712
|
+
d: "m8 2 1.88 1.88",
|
|
713
|
+
key: "fmnt4t"
|
|
714
|
+
}],
|
|
715
|
+
["path", {
|
|
716
|
+
d: "M9 7.13V6a3 3 0 1 1 6 0v1.13",
|
|
717
|
+
key: "1vgav8"
|
|
718
|
+
}]
|
|
719
|
+
]);
|
|
720
|
+
/**
|
|
721
|
+
* @license lucide-react v1.39.0 - ISC
|
|
722
|
+
*
|
|
723
|
+
* This source code is licensed under the ISC license.
|
|
724
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
725
|
+
*/
|
|
726
|
+
const ChartColumn = createLucideIcon("chart-column", [
|
|
727
|
+
["path", {
|
|
728
|
+
d: "M3 3v16a2 2 0 0 0 2 2h16",
|
|
729
|
+
key: "c24i48"
|
|
730
|
+
}],
|
|
731
|
+
["path", {
|
|
732
|
+
d: "M18 17V9",
|
|
733
|
+
key: "2bz60n"
|
|
734
|
+
}],
|
|
735
|
+
["path", {
|
|
736
|
+
d: "M13 17V5",
|
|
737
|
+
key: "1frdt8"
|
|
738
|
+
}],
|
|
739
|
+
["path", {
|
|
740
|
+
d: "M8 17v-3",
|
|
741
|
+
key: "17ska0"
|
|
742
|
+
}]
|
|
743
|
+
]);
|
|
744
|
+
/**
|
|
745
|
+
* @license lucide-react v1.39.0 - ISC
|
|
746
|
+
*
|
|
747
|
+
* This source code is licensed under the ISC license.
|
|
748
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
749
|
+
*/
|
|
750
|
+
const CircleQuestionMark = createLucideIcon("circle-question-mark", [
|
|
751
|
+
["circle", {
|
|
752
|
+
cx: "12",
|
|
753
|
+
cy: "12",
|
|
754
|
+
r: "10",
|
|
755
|
+
key: "1mglay"
|
|
756
|
+
}],
|
|
757
|
+
["path", {
|
|
758
|
+
d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",
|
|
759
|
+
key: "1u773s"
|
|
760
|
+
}],
|
|
761
|
+
["path", {
|
|
762
|
+
d: "M12 17h.01",
|
|
763
|
+
key: "p32p05"
|
|
764
|
+
}]
|
|
765
|
+
]);
|
|
766
|
+
/**
|
|
767
|
+
* @license lucide-react v1.39.0 - ISC
|
|
768
|
+
*
|
|
769
|
+
* This source code is licensed under the ISC license.
|
|
770
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
771
|
+
*/
|
|
772
|
+
const Clock = createLucideIcon("clock", [["circle", {
|
|
773
|
+
cx: "12",
|
|
774
|
+
cy: "12",
|
|
775
|
+
r: "10",
|
|
776
|
+
key: "1mglay"
|
|
777
|
+
}], ["path", {
|
|
778
|
+
d: "M12 6v6l4 2",
|
|
779
|
+
key: "mmk7yg"
|
|
780
|
+
}]]);
|
|
781
|
+
/**
|
|
782
|
+
* @license lucide-react v1.39.0 - ISC
|
|
783
|
+
*
|
|
784
|
+
* This source code is licensed under the ISC license.
|
|
785
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
786
|
+
*/
|
|
787
|
+
const Cpu = createLucideIcon("cpu", [
|
|
788
|
+
["path", {
|
|
789
|
+
d: "M12 20v2",
|
|
790
|
+
key: "1lh1kg"
|
|
791
|
+
}],
|
|
792
|
+
["path", {
|
|
793
|
+
d: "M12 2v2",
|
|
794
|
+
key: "tus03m"
|
|
795
|
+
}],
|
|
796
|
+
["path", {
|
|
797
|
+
d: "M17 20v2",
|
|
798
|
+
key: "1rnc9c"
|
|
799
|
+
}],
|
|
800
|
+
["path", {
|
|
801
|
+
d: "M17 2v2",
|
|
802
|
+
key: "11trls"
|
|
803
|
+
}],
|
|
804
|
+
["path", {
|
|
805
|
+
d: "M2 12h2",
|
|
806
|
+
key: "1t8f8n"
|
|
807
|
+
}],
|
|
808
|
+
["path", {
|
|
809
|
+
d: "M2 17h2",
|
|
810
|
+
key: "7oei6x"
|
|
811
|
+
}],
|
|
812
|
+
["path", {
|
|
813
|
+
d: "M2 7h2",
|
|
814
|
+
key: "asdhe0"
|
|
815
|
+
}],
|
|
816
|
+
["path", {
|
|
817
|
+
d: "M20 12h2",
|
|
818
|
+
key: "1q8mjw"
|
|
819
|
+
}],
|
|
820
|
+
["path", {
|
|
821
|
+
d: "M20 17h2",
|
|
822
|
+
key: "1fpfkl"
|
|
823
|
+
}],
|
|
824
|
+
["path", {
|
|
825
|
+
d: "M20 7h2",
|
|
826
|
+
key: "1o8tra"
|
|
827
|
+
}],
|
|
828
|
+
["path", {
|
|
829
|
+
d: "M7 20v2",
|
|
830
|
+
key: "4gnj0m"
|
|
831
|
+
}],
|
|
832
|
+
["path", {
|
|
833
|
+
d: "M7 2v2",
|
|
834
|
+
key: "1i4yhu"
|
|
835
|
+
}],
|
|
836
|
+
["rect", {
|
|
837
|
+
x: "4",
|
|
838
|
+
y: "4",
|
|
839
|
+
width: "16",
|
|
840
|
+
height: "16",
|
|
841
|
+
rx: "2",
|
|
842
|
+
key: "1vbyd7"
|
|
843
|
+
}],
|
|
844
|
+
["rect", {
|
|
845
|
+
x: "8",
|
|
846
|
+
y: "8",
|
|
847
|
+
width: "8",
|
|
848
|
+
height: "8",
|
|
849
|
+
rx: "1",
|
|
850
|
+
key: "z9xiuo"
|
|
851
|
+
}]
|
|
852
|
+
]);
|
|
853
|
+
/**
|
|
854
|
+
* @license lucide-react v1.39.0 - ISC
|
|
855
|
+
*
|
|
856
|
+
* This source code is licensed under the ISC license.
|
|
857
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
858
|
+
*/
|
|
486
859
|
const EyeOff = createLucideIcon("eye-off", [
|
|
487
860
|
["path", {
|
|
488
861
|
d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",
|
|
@@ -522,6 +895,39 @@ window.__ModuleLoader__.load({
|
|
|
522
895
|
* This source code is licensed under the ISC license.
|
|
523
896
|
* See the LICENSE file in the root directory of this source tree.
|
|
524
897
|
*/
|
|
898
|
+
const Hammer = createLucideIcon("hammer", [
|
|
899
|
+
["path", {
|
|
900
|
+
d: "m15 12-9.373 9.373a1 1 0 0 1-3.001-3L12 9",
|
|
901
|
+
key: "1hayfq"
|
|
902
|
+
}],
|
|
903
|
+
["path", {
|
|
904
|
+
d: "m18 15 4-4",
|
|
905
|
+
key: "16gjal"
|
|
906
|
+
}],
|
|
907
|
+
["path", {
|
|
908
|
+
d: "m21.5 11.5-1.914-1.914A2 2 0 0 1 19 8.172v-.344a2 2 0 0 0-.586-1.414l-1.657-1.657A6 6 0 0 0 12.516 3H9l1.243 1.243A6 6 0 0 1 12 8.485V10l2 2h1.172a2 2 0 0 1 1.414.586L18.5 14.5",
|
|
909
|
+
key: "15ts47"
|
|
910
|
+
}]
|
|
911
|
+
]);
|
|
912
|
+
/**
|
|
913
|
+
* @license lucide-react v1.39.0 - ISC
|
|
914
|
+
*
|
|
915
|
+
* This source code is licensed under the ISC license.
|
|
916
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
917
|
+
*/
|
|
918
|
+
const Link = createLucideIcon("link", [["path", {
|
|
919
|
+
d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",
|
|
920
|
+
key: "1cjeqo"
|
|
921
|
+
}], ["path", {
|
|
922
|
+
d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",
|
|
923
|
+
key: "19qd67"
|
|
924
|
+
}]]);
|
|
925
|
+
/**
|
|
926
|
+
* @license lucide-react v1.39.0 - ISC
|
|
927
|
+
*
|
|
928
|
+
* This source code is licensed under the ISC license.
|
|
929
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
930
|
+
*/
|
|
525
931
|
const MessageCircle = createLucideIcon("message-circle", [["path", {
|
|
526
932
|
d: "M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",
|
|
527
933
|
key: "1sd12s"
|
|
@@ -532,6 +938,33 @@ window.__ModuleLoader__.load({
|
|
|
532
938
|
* This source code is licensed under the ISC license.
|
|
533
939
|
* See the LICENSE file in the root directory of this source tree.
|
|
534
940
|
*/
|
|
941
|
+
const MessageSquare = createLucideIcon("message-square", [["path", {
|
|
942
|
+
d: "M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",
|
|
943
|
+
key: "18887p"
|
|
944
|
+
}]]);
|
|
945
|
+
/**
|
|
946
|
+
* @license lucide-react v1.39.0 - ISC
|
|
947
|
+
*
|
|
948
|
+
* This source code is licensed under the ISC license.
|
|
949
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
950
|
+
*/
|
|
951
|
+
const PanelRight = createLucideIcon("panel-right", [["rect", {
|
|
952
|
+
width: "18",
|
|
953
|
+
height: "18",
|
|
954
|
+
x: "3",
|
|
955
|
+
y: "3",
|
|
956
|
+
rx: "2",
|
|
957
|
+
key: "afitv7"
|
|
958
|
+
}], ["path", {
|
|
959
|
+
d: "M15 3v18",
|
|
960
|
+
key: "14nvp0"
|
|
961
|
+
}]]);
|
|
962
|
+
/**
|
|
963
|
+
* @license lucide-react v1.39.0 - ISC
|
|
964
|
+
*
|
|
965
|
+
* This source code is licensed under the ISC license.
|
|
966
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
967
|
+
*/
|
|
535
968
|
const Pin = createLucideIcon("pin", [["path", {
|
|
536
969
|
d: "M12 17v5",
|
|
537
970
|
key: "bb1du9"
|
|
@@ -545,12 +978,213 @@ window.__ModuleLoader__.load({
|
|
|
545
978
|
* This source code is licensed under the ISC license.
|
|
546
979
|
* See the LICENSE file in the root directory of this source tree.
|
|
547
980
|
*/
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
981
|
+
const ScanLine = createLucideIcon("scan-line", [
|
|
982
|
+
["path", {
|
|
983
|
+
d: "M3 7V5a2 2 0 0 1 2-2h2",
|
|
984
|
+
key: "aa7l1z"
|
|
985
|
+
}],
|
|
986
|
+
["path", {
|
|
987
|
+
d: "M17 3h2a2 2 0 0 1 2 2v2",
|
|
988
|
+
key: "4qcy5o"
|
|
989
|
+
}],
|
|
990
|
+
["path", {
|
|
991
|
+
d: "M21 17v2a2 2 0 0 1-2 2h-2",
|
|
992
|
+
key: "6vwrx8"
|
|
993
|
+
}],
|
|
994
|
+
["path", {
|
|
995
|
+
d: "M7 21H5a2 2 0 0 1-2-2v-2",
|
|
996
|
+
key: "ioqczr"
|
|
997
|
+
}],
|
|
998
|
+
["path", {
|
|
999
|
+
d: "M7 12h10",
|
|
1000
|
+
key: "b7w52i"
|
|
1001
|
+
}]
|
|
1002
|
+
]);
|
|
1003
|
+
/**
|
|
1004
|
+
* @license lucide-react v1.39.0 - ISC
|
|
1005
|
+
*
|
|
1006
|
+
* This source code is licensed under the ISC license.
|
|
1007
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1008
|
+
*/
|
|
1009
|
+
const Search = createLucideIcon("search", [["path", {
|
|
1010
|
+
d: "m21 21-4.34-4.34",
|
|
1011
|
+
key: "14j7rj"
|
|
1012
|
+
}], ["circle", {
|
|
1013
|
+
cx: "11",
|
|
1014
|
+
cy: "11",
|
|
1015
|
+
r: "8",
|
|
1016
|
+
key: "4ej97u"
|
|
1017
|
+
}]]);
|
|
1018
|
+
/**
|
|
1019
|
+
* @license lucide-react v1.39.0 - ISC
|
|
1020
|
+
*
|
|
1021
|
+
* This source code is licensed under the ISC license.
|
|
1022
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1023
|
+
*/
|
|
1024
|
+
const Settings = createLucideIcon("settings", [["path", {
|
|
1025
|
+
d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",
|
|
1026
|
+
key: "1i5ecw"
|
|
1027
|
+
}], ["circle", {
|
|
1028
|
+
cx: "12",
|
|
1029
|
+
cy: "12",
|
|
1030
|
+
r: "3",
|
|
1031
|
+
key: "1v7zrd"
|
|
1032
|
+
}]]);
|
|
1033
|
+
/**
|
|
1034
|
+
* @license lucide-react v1.39.0 - ISC
|
|
1035
|
+
*
|
|
1036
|
+
* This source code is licensed under the ISC license.
|
|
1037
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1038
|
+
*/
|
|
1039
|
+
const SlidersHorizontal = createLucideIcon("sliders-horizontal", [
|
|
1040
|
+
["path", {
|
|
1041
|
+
d: "M10 5H3",
|
|
1042
|
+
key: "1qgfaw"
|
|
1043
|
+
}],
|
|
1044
|
+
["path", {
|
|
1045
|
+
d: "M12 19H3",
|
|
1046
|
+
key: "yhmn1j"
|
|
1047
|
+
}],
|
|
1048
|
+
["path", {
|
|
1049
|
+
d: "M14 3v4",
|
|
1050
|
+
key: "1sua03"
|
|
1051
|
+
}],
|
|
1052
|
+
["path", {
|
|
1053
|
+
d: "M16 17v4",
|
|
1054
|
+
key: "1q0r14"
|
|
1055
|
+
}],
|
|
1056
|
+
["path", {
|
|
1057
|
+
d: "M21 12h-9",
|
|
1058
|
+
key: "1o4lsq"
|
|
1059
|
+
}],
|
|
1060
|
+
["path", {
|
|
1061
|
+
d: "M21 19h-5",
|
|
1062
|
+
key: "1rlt1p"
|
|
1063
|
+
}],
|
|
1064
|
+
["path", {
|
|
1065
|
+
d: "M21 5h-7",
|
|
1066
|
+
key: "1oszz2"
|
|
1067
|
+
}],
|
|
1068
|
+
["path", {
|
|
1069
|
+
d: "M8 10v4",
|
|
1070
|
+
key: "tgpxqk"
|
|
1071
|
+
}],
|
|
1072
|
+
["path", {
|
|
1073
|
+
d: "M8 12H3",
|
|
1074
|
+
key: "a7s4jb"
|
|
1075
|
+
}]
|
|
1076
|
+
]);
|
|
1077
|
+
/**
|
|
1078
|
+
* @license lucide-react v1.39.0 - ISC
|
|
1079
|
+
*
|
|
1080
|
+
* This source code is licensed under the ISC license.
|
|
1081
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1082
|
+
*/
|
|
1083
|
+
const Sparkles = createLucideIcon("sparkles", [
|
|
1084
|
+
["path", {
|
|
1085
|
+
d: "M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",
|
|
1086
|
+
key: "1s2grr"
|
|
1087
|
+
}],
|
|
1088
|
+
["path", {
|
|
1089
|
+
d: "M20 2v4",
|
|
1090
|
+
key: "1rf3ol"
|
|
1091
|
+
}],
|
|
1092
|
+
["path", {
|
|
1093
|
+
d: "M22 4h-4",
|
|
1094
|
+
key: "gwowj6"
|
|
1095
|
+
}],
|
|
1096
|
+
["circle", {
|
|
1097
|
+
cx: "4",
|
|
1098
|
+
cy: "20",
|
|
1099
|
+
r: "2",
|
|
1100
|
+
key: "6kqj1y"
|
|
1101
|
+
}]
|
|
1102
|
+
]);
|
|
1103
|
+
/**
|
|
1104
|
+
* @license lucide-react v1.39.0 - ISC
|
|
1105
|
+
*
|
|
1106
|
+
* This source code is licensed under the ISC license.
|
|
1107
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1108
|
+
*/
|
|
1109
|
+
const SquarePen = createLucideIcon("square-pen", [["path", {
|
|
1110
|
+
d: "M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7",
|
|
1111
|
+
key: "1m0v6g"
|
|
1112
|
+
}], ["path", {
|
|
1113
|
+
d: "M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",
|
|
1114
|
+
key: "ohrbg2"
|
|
1115
|
+
}]]);
|
|
1116
|
+
/**
|
|
1117
|
+
* @license lucide-react v1.39.0 - ISC
|
|
1118
|
+
*
|
|
1119
|
+
* This source code is licensed under the ISC license.
|
|
1120
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1121
|
+
*/
|
|
1122
|
+
const Store = createLucideIcon("store", [
|
|
1123
|
+
["path", {
|
|
1124
|
+
d: "M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5",
|
|
1125
|
+
key: "slp6dd"
|
|
1126
|
+
}],
|
|
1127
|
+
["path", {
|
|
1128
|
+
d: "M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244",
|
|
1129
|
+
key: "o0xfot"
|
|
1130
|
+
}],
|
|
1131
|
+
["path", {
|
|
1132
|
+
d: "M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05",
|
|
1133
|
+
key: "wn3emo"
|
|
1134
|
+
}]
|
|
1135
|
+
]);
|
|
1136
|
+
/**
|
|
1137
|
+
* @license lucide-react v1.39.0 - ISC
|
|
1138
|
+
*
|
|
1139
|
+
* This source code is licensed under the ISC license.
|
|
1140
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1141
|
+
*/
|
|
1142
|
+
const Telescope = createLucideIcon("telescope", [
|
|
1143
|
+
["path", {
|
|
1144
|
+
d: "m10.065 12.493-6.18 1.318a.934.934 0 0 1-1.108-.702l-.537-2.15a1.07 1.07 0 0 1 .691-1.265l13.504-4.44",
|
|
1145
|
+
key: "k4qptu"
|
|
1146
|
+
}],
|
|
1147
|
+
["path", {
|
|
1148
|
+
d: "m13.56 11.747 4.332-.924",
|
|
1149
|
+
key: "19l80z"
|
|
1150
|
+
}],
|
|
1151
|
+
["path", {
|
|
1152
|
+
d: "m16 21-3.105-6.21",
|
|
1153
|
+
key: "7oh9d"
|
|
1154
|
+
}],
|
|
1155
|
+
["path", {
|
|
1156
|
+
d: "M16.485 5.94a2 2 0 0 1 1.455-2.425l1.09-.272a1 1 0 0 1 1.212.727l1.515 6.06a1 1 0 0 1-.727 1.213l-1.09.272a2 2 0 0 1-2.425-1.455z",
|
|
1157
|
+
key: "m7xp4m"
|
|
1158
|
+
}],
|
|
1159
|
+
["path", {
|
|
1160
|
+
d: "m6.158 8.633 1.114 4.456",
|
|
1161
|
+
key: "74o979"
|
|
1162
|
+
}],
|
|
1163
|
+
["path", {
|
|
1164
|
+
d: "m8 21 3.105-6.21",
|
|
1165
|
+
key: "1fvxut"
|
|
1166
|
+
}],
|
|
1167
|
+
["circle", {
|
|
1168
|
+
cx: "12",
|
|
1169
|
+
cy: "13",
|
|
1170
|
+
r: "2",
|
|
1171
|
+
key: "1c1ljs"
|
|
1172
|
+
}]
|
|
1173
|
+
]);
|
|
1174
|
+
/**
|
|
1175
|
+
* @license lucide-react v1.39.0 - ISC
|
|
1176
|
+
*
|
|
1177
|
+
* This source code is licensed under the ISC license.
|
|
1178
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1179
|
+
*/
|
|
1180
|
+
const User = createLucideIcon("user", [["path", {
|
|
1181
|
+
d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",
|
|
1182
|
+
key: "975kel"
|
|
1183
|
+
}], ["circle", {
|
|
1184
|
+
cx: "12",
|
|
1185
|
+
cy: "7",
|
|
1186
|
+
r: "4",
|
|
1187
|
+
key: "17ys0d"
|
|
554
1188
|
}]]);
|
|
555
1189
|
//#endregion
|
|
556
1190
|
//#region src/client/session-tree.tsx
|
|
@@ -1889,40 +2523,6 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1889
2523
|
return fallback !== void 0 && fallback.trim() !== "" ? fallback : void 0;
|
|
1890
2524
|
}
|
|
1891
2525
|
//#endregion
|
|
1892
|
-
//#region src/client/tree-expansion.ts
|
|
1893
|
-
const WORKSPACE_EXPANSION_STORAGE_KEY = "dsh-codex-ui.workspace-expansion.v1";
|
|
1894
|
-
const CHANNEL_EXPANSION_STORAGE_KEY = "dsh-codex-ui.channel-expansion.v1";
|
|
1895
|
-
const SCHEDULE_EXPANSION_STORAGE_KEY = "dsh-codex-ui.schedule-expansion.v1";
|
|
1896
|
-
const MAX_EXPANSION_ENTRIES = 500;
|
|
1897
|
-
const MAX_EXPANSION_KEY_LENGTH = 512;
|
|
1898
|
-
function browserStorage() {
|
|
1899
|
-
if (typeof window === "undefined") return void 0;
|
|
1900
|
-
try {
|
|
1901
|
-
return window.localStorage;
|
|
1902
|
-
} catch {
|
|
1903
|
-
return;
|
|
1904
|
-
}
|
|
1905
|
-
}
|
|
1906
|
-
function parseTreeExpansionState(value) {
|
|
1907
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) return {};
|
|
1908
|
-
const entries = Object.entries(value).filter(([key, expanded]) => key.length > 0 && key.length <= MAX_EXPANSION_KEY_LENGTH && typeof expanded === "boolean").slice(0, MAX_EXPANSION_ENTRIES);
|
|
1909
|
-
return Object.fromEntries(entries);
|
|
1910
|
-
}
|
|
1911
|
-
function readTreeExpansionState(storage, key) {
|
|
1912
|
-
if (storage === void 0) return {};
|
|
1913
|
-
try {
|
|
1914
|
-
return parseTreeExpansionState(JSON.parse(storage.getItem(key) ?? "{}"));
|
|
1915
|
-
} catch {
|
|
1916
|
-
return {};
|
|
1917
|
-
}
|
|
1918
|
-
}
|
|
1919
|
-
function writeTreeExpansionState(storage, key, state) {
|
|
1920
|
-
if (storage === void 0) return;
|
|
1921
|
-
try {
|
|
1922
|
-
storage.setItem(key, JSON.stringify(parseTreeExpansionState(state)));
|
|
1923
|
-
} catch {}
|
|
1924
|
-
}
|
|
1925
|
-
//#endregion
|
|
1926
2526
|
//#region src/client/workspace-compat.ts
|
|
1927
2527
|
function hasStartSession(value) {
|
|
1928
2528
|
return value !== null && typeof value === "object" && "startSession" in value && typeof value.startSession === "function";
|
|
@@ -2325,7 +2925,8 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2325
2925
|
const stylesheet$4 = `
|
|
2326
2926
|
.dcu-wb{--dcu-wb-inset:8px;display:flex;flex:1;min-height:0;flex-direction:column;padding:4px var(--dcu-wb-inset) 8px;color:var(--dcu-sidebar-primary)}
|
|
2327
2927
|
.dcu-wb *{box-sizing:border-box}
|
|
2328
|
-
.dcu-wb-tree{flex:1;min-height:0;overflow-x:hidden;overflow-y:auto;padding-bottom:16px;scrollbar-gutter:auto;user-select:none;-webkit-user-select:none}
|
|
2928
|
+
.dcu-wb-tree{flex:1;min-height:0;overflow-x:hidden;overflow-y:auto;padding-bottom:16px;scrollbar-gutter:auto;scrollbar-width:none;user-select:none;-webkit-user-select:none}
|
|
2929
|
+
.dcu-wb-tree::-webkit-scrollbar{display:none}
|
|
2329
2930
|
.dcu-wb-section+.dcu-wb-section{margin-top:12px}
|
|
2330
2931
|
.dcu-wb-section-head{position:relative;display:flex;align-items:center;min-height:24px;padding:0;border-radius:6px}.dcu-wb-section-head:hover .dcu-wb-actions{display:flex}.dcu-wb-section-label{position:relative;display:flex;align-items:center;gap:4px;flex:1;min-width:0;min-height:24px;border:0;padding:2px 4px 2px 12px;background:transparent;color:var(--dcu-sidebar-tertiary);font:13px/20px var(--dcu-font,inherit);font-weight:400;letter-spacing:0;text-align:left;cursor:pointer}.dcu-wb-section-caret{display:grid;place-items:center;flex:none;width:12px;height:12px;color:currentColor;opacity:0;transform:rotate(0deg);transform-origin:50% 50%;transition:opacity 120ms ease,transform 160ms ease}.dcu-wb-section-head .dcu-wb-section-caret{position:absolute;left:0;top:6px}.dcu-wb-section-caret svg{display:block}.dcu-wb-section-head:hover .dcu-wb-section-caret,.dcu-wb-section-label:focus-visible .dcu-wb-section-caret{opacity:.78}.dcu-wb-section-label[aria-expanded=true] .dcu-wb-section-caret{transform:rotate(90deg)}.dcu-wb-section-body{display:block}.dcu-wb-section-body[data-open=false]{display:none}.dcu-wb-section-body>div{min-height:0}.dcu-wb-section-body[data-open=true]>div{animation:dcu-wb-section-in 140ms cubic-bezier(.16,1,.3,1)}@keyframes dcu-wb-section-in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){.dcu-wb-section-caret{transition:none}.dcu-wb-section-body[data-open=true]>div{animation:none}}
|
|
2331
2932
|
.dcu-wb-project{position:relative;min-width:0}
|
|
@@ -5391,6 +5992,340 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5391
5992
|
} catch {}
|
|
5392
5993
|
}
|
|
5393
5994
|
//#endregion
|
|
5995
|
+
//#region src/client/new-conversation-style.ts
|
|
5996
|
+
/** 新建页底部输入布局;保留宿主节点、插槽与 active 会话底部信息。 */
|
|
5997
|
+
const NEW_CONVERSATION_STYLE = `
|
|
5998
|
+
[data-phase=hero]:has([data-conversation-scroll]){container:dcu-new-conversation / inline-size}
|
|
5999
|
+
[data-phase=hero] [data-conversation-scroll][class]{--dsh-composer-side-clearance:16px;justify-content:flex-start;scrollbar-gutter:stable both-edges}
|
|
6000
|
+
[data-phase=hero] [data-composer-seat]{flex:1 0 auto;min-height:100%}
|
|
6001
|
+
[data-phase=hero] [data-composer-seat]>:has([class*="_composerHero"]){display:flex;flex:1;flex-direction:column}
|
|
6002
|
+
[data-phase=hero] [class*="_composerHero"]{box-sizing:border-box;flex:1;width:100%;max-width:none;min-width:0;margin-inline:auto;gap:0;padding-bottom:32px}
|
|
6003
|
+
[data-phase=hero] [class*="_composerHero"]>:first-child{box-sizing:border-box;flex:1;width:100%;max-width:768px;align-self:center;height:auto;min-height:340px;align-items:center;padding:32px 28px}
|
|
6004
|
+
[data-phase=hero] [class*="_composerHero"]>:first-child>[class$="_stack"]{width:100%;max-width:none;min-width:0;align-items:center;gap:32px}
|
|
6005
|
+
[data-phase=hero] [class*="_heroWorkspaceRow"]{box-sizing:border-box;flex:none;width:min(calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance) - 56px),calc(100% - 56px));align-self:center;justify-content:flex-start;flex-wrap:wrap;gap:8px;min-height:48px;margin:0 28px -10px;padding:6px 12px 16px;border-radius:18px 18px 0 0;background:color-mix(in srgb,var(--dsw-alias-label-primary) 4%,var(--dsw-alias-bg-base))}
|
|
6006
|
+
[data-phase=hero] [class*="_heroWorkspaceRow"]>[class$="_workspace"]{min-width:0;max-width:100%;font-weight:400}
|
|
6007
|
+
.dcu-home-suggestions{width:100%;color:var(--dsw-alias-label-primary);font:13px/20px var(--dsw-font-family,system-ui)}
|
|
6008
|
+
.dcu-home-cards{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}
|
|
6009
|
+
.dcu-home-card{appearance:none;display:flex;flex-direction:column;justify-content:space-between;gap:22px;min-width:0;min-height:106px;padding:16px;border:1px solid color-mix(in srgb,var(--dsw-alias-label-primary) 10%,transparent);border-radius:20px;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer;transition:background-color 150ms,border-color 150ms}
|
|
6010
|
+
.dcu-home-card:hover,.dcu-home-card[aria-pressed=true]{background:color-mix(in srgb,var(--dsw-alias-label-primary) 5%,transparent);border-color:color-mix(in srgb,var(--dsw-alias-label-primary) 20%,transparent)}
|
|
6011
|
+
.dcu-home-card svg{width:16px;height:16px;flex:none;color:var(--dcu-home-icon)}
|
|
6012
|
+
.dcu-home-card:focus-visible,.dcu-home-task:focus-visible{outline:2px solid var(--dsw-alias-label-primary);outline-offset:3px}
|
|
6013
|
+
.dcu-home-details,.dcu-home-status{display:grid}
|
|
6014
|
+
.dcu-home-suggestions[data-has-draft=true]{visibility:hidden;pointer-events:none}
|
|
6015
|
+
.dcu-home-tasks{grid-area:1/1;display:flex;flex-wrap:wrap;align-content:start;gap:8px;margin-top:16px}
|
|
6016
|
+
.dcu-home-details>[data-active=false],.dcu-home-status>[data-active=false]{visibility:hidden;pointer-events:none}
|
|
6017
|
+
.dcu-home-task{appearance:none;border:1px solid color-mix(in srgb,var(--dsw-alias-label-primary) 12%,transparent);border-radius:10px;padding:8px 12px;background:transparent;color:inherit;font:inherit;text-align:left;cursor:pointer}
|
|
6018
|
+
.dcu-home-task:hover{background:color-mix(in srgb,var(--dsw-alias-label-primary) 5%,transparent)}
|
|
6019
|
+
.dcu-home-hint{grid-area:1/1;margin:12px 0 0;color:var(--dsw-alias-label-secondary)}
|
|
6020
|
+
@container dcu-new-conversation (width < 640px){
|
|
6021
|
+
.dcu-home-cards{grid-template-columns:repeat(2,minmax(0,1fr))}
|
|
6022
|
+
[data-phase=hero] [class*="_composerHero"]>:first-child{padding:32px 24px;min-height:420px}
|
|
6023
|
+
}
|
|
6024
|
+
@media(prefers-reduced-motion:reduce){.dcu-home-card{transition:none}}
|
|
6025
|
+
`;
|
|
6026
|
+
//#endregion
|
|
6027
|
+
//#region src/client/composer-tool-menus.ts
|
|
6028
|
+
/** 只适配由输入区工具触发的菜单;保留原条目、选择回调及目录创建流程。 */
|
|
6029
|
+
const TOOL = "[class*=\"_heroWorkspaceRow\"] button,[data-composer-card] button[aria-haspopup],[data-composer-card] button[aria-expanded]";
|
|
6030
|
+
const MENU = "[role=\"menu\"],[role=\"listbox\"]";
|
|
6031
|
+
const COMPOSER_TOOL_MENU_STYLE = `
|
|
6032
|
+
[class*="_heroWorkspaceRow"] button{min-height:28px;border-radius:999px;font-size:13px;line-height:20px}
|
|
6033
|
+
[class*="_heroWorkspaceRow"] button:hover,[class*="_heroWorkspaceRow"] button[aria-expanded=true]{background:color-mix(in srgb,var(--dsw-alias-label-primary) 8%,transparent)}
|
|
6034
|
+
:is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]){box-sizing:border-box;min-width:0!important;width:262px;max-width:calc(100vw - 24px);max-height:var(--dcu-tool-menu-height,360px)!important;padding:5px!important;border-radius:18px!important;background:#fff!important;color:var(--dsw-alias-label-primary);box-shadow:0 8px 32px #0002,0 0 0 1px #0000000a!important;display:flex;flex-direction:column;gap:0;z-index:1100}
|
|
6035
|
+
[data-dcu-tool-menu=portal]{position:fixed!important;left:var(--dcu-tool-menu-x)!important;top:var(--dcu-tool-menu-y)!important;bottom:auto!important;right:auto!important}
|
|
6036
|
+
:is([data-dcu-tool-menu=inline],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]:not([data-dcu-tool-menu=portal])){width:320px;translate:var(--dcu-tool-menu-shift,0px) 0}
|
|
6037
|
+
[class*="_heroWorkspaceRow"] [data-gitgraph-popover]:not([data-dcu-tool-menu=portal]){top:auto!important;bottom:calc(100% + 4px)!important}
|
|
6038
|
+
body[data-ds-dark-theme] :is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]){background:#292929!important;box-shadow:0 8px 32px #0003,0 0 0 1px #ffffff08!important}
|
|
6039
|
+
:is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover])>[class*="_viewport"]{min-height:0;max-height:none;overflow-y:auto;scrollbar-width:thin}
|
|
6040
|
+
:is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]) :is([role=menuitem],[role=menuitemradio],[role=menuitemcheckbox],[role=option]){box-sizing:border-box;min-height:28px;padding:4px 9px;gap:8px;border-radius:8px;font-size:13px;line-height:20px}
|
|
6041
|
+
:is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]) :is([role=menuitem],[role=menuitemradio],[role=option]):hover:not(:disabled),:is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]) [class*="_selected"],:is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]) [aria-selected=true],:is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]) [aria-checked=true]{background:color-mix(in srgb,var(--dsw-alias-label-primary) 10%,transparent)}
|
|
6042
|
+
:is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]) [class*="_itemIcon"] svg{width:16px;height:16px}
|
|
6043
|
+
:is([data-dcu-tool-menu],[class*="_heroWorkspaceRow"] [data-gitgraph-popover]) [class*="_footer"]{flex:none;margin-top:5px;padding-top:5px;border-top:1px solid color-mix(in srgb,var(--dsw-alias-label-primary) 10%,transparent)}
|
|
6044
|
+
[data-dcu-tool-filter]{box-sizing:border-box;flex:none;width:100%;height:32px;padding:4px 10px;margin:0 0 1px;border:0;border-radius:8px;outline:none;background:transparent;color:inherit;font:13px/20px var(--dsw-font-family,system-ui)}
|
|
6045
|
+
[data-dcu-tool-filter]:focus-visible{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--dsw-alias-label-primary) 20%,transparent)}
|
|
6046
|
+
[data-dcu-tool-empty]{padding:8px 10px;font-size:13px;color:var(--dsw-alias-label-secondary)}
|
|
6047
|
+
[data-dcu-tool-filtered]{display:none!important}
|
|
6048
|
+
`;
|
|
6049
|
+
function observeComposerToolMenus(copy) {
|
|
6050
|
+
let anchor;
|
|
6051
|
+
let known = /* @__PURE__ */ new Set();
|
|
6052
|
+
let pendingUntil = 0;
|
|
6053
|
+
const mounted = /* @__PURE__ */ new Map();
|
|
6054
|
+
const now = () => Date.now();
|
|
6055
|
+
function capture(event) {
|
|
6056
|
+
const target = event.target instanceof Element ? event.target.closest(TOOL) : null;
|
|
6057
|
+
if (target === null || target.closest("[data-conversation-scroll]") === null) return;
|
|
6058
|
+
anchor = target;
|
|
6059
|
+
known = new Set(document.querySelectorAll(MENU));
|
|
6060
|
+
pendingUntil = now() + 1e3;
|
|
6061
|
+
}
|
|
6062
|
+
function mount(menu, trigger) {
|
|
6063
|
+
const portal = getComputedStyle(menu).position === "fixed";
|
|
6064
|
+
menu.setAttribute("data-dcu-tool-menu", portal ? "portal" : "inline");
|
|
6065
|
+
const isProject = trigger.matches("[class*=\"_heroWorkspaceRow\"]>button:first-child");
|
|
6066
|
+
const viewport = menu.querySelector(":scope>[class*=\"_viewport\"]");
|
|
6067
|
+
let input;
|
|
6068
|
+
let empty;
|
|
6069
|
+
if (isProject && viewport !== null && menu.querySelector("input") === null) {
|
|
6070
|
+
input = document.createElement("input");
|
|
6071
|
+
input.type = "search";
|
|
6072
|
+
input.placeholder = copy.search;
|
|
6073
|
+
input.setAttribute("aria-label", copy.search);
|
|
6074
|
+
input.setAttribute("data-dcu-tool-filter", "");
|
|
6075
|
+
empty = document.createElement("div");
|
|
6076
|
+
empty.setAttribute("data-dcu-tool-empty", "");
|
|
6077
|
+
empty.setAttribute("role", "status");
|
|
6078
|
+
empty.textContent = copy.empty;
|
|
6079
|
+
empty.hidden = true;
|
|
6080
|
+
menu.prepend(input);
|
|
6081
|
+
viewport.after(empty);
|
|
6082
|
+
input.addEventListener("input", () => {
|
|
6083
|
+
const query = input.value.trim().toLocaleLowerCase();
|
|
6084
|
+
let count = 0;
|
|
6085
|
+
for (const row of viewport.children) {
|
|
6086
|
+
const match = (row.textContent ?? "").toLocaleLowerCase().includes(query);
|
|
6087
|
+
row.toggleAttribute("data-dcu-tool-filtered", !match);
|
|
6088
|
+
if (match) count++;
|
|
6089
|
+
}
|
|
6090
|
+
empty.hidden = count > 0;
|
|
6091
|
+
place();
|
|
6092
|
+
});
|
|
6093
|
+
input.addEventListener("keydown", (event) => {
|
|
6094
|
+
if (event.key !== "ArrowDown" && event.key !== "Enter") return;
|
|
6095
|
+
const first = viewport.querySelector(":scope>:not([data-dcu-tool-filtered]) button:not(:disabled)");
|
|
6096
|
+
if (first !== null) {
|
|
6097
|
+
event.preventDefault();
|
|
6098
|
+
event.stopPropagation();
|
|
6099
|
+
first.focus();
|
|
6100
|
+
if (event.key === "Enter") first.click();
|
|
6101
|
+
}
|
|
6102
|
+
});
|
|
6103
|
+
}
|
|
6104
|
+
function place() {
|
|
6105
|
+
if (!trigger.isConnected || !menu.isConnected) return;
|
|
6106
|
+
const rect = trigger.getBoundingClientRect();
|
|
6107
|
+
const above = rect.top - 16;
|
|
6108
|
+
const below = window.innerHeight - rect.bottom - 16;
|
|
6109
|
+
const topSide = above >= Math.min(260, below);
|
|
6110
|
+
menu.style.setProperty("--dcu-tool-menu-height", `${Math.max(60, Math.min(360, topSide ? above : below))}px`);
|
|
6111
|
+
if (!portal) {
|
|
6112
|
+
const previous = parseFloat(menu.style.getPropertyValue("--dcu-tool-menu-shift")) || 0;
|
|
6113
|
+
const bounds = menu.getBoundingClientRect();
|
|
6114
|
+
const naturalLeft = bounds.left - previous;
|
|
6115
|
+
const left = Math.max(12, Math.min(naturalLeft, window.innerWidth - bounds.width - 12));
|
|
6116
|
+
menu.style.setProperty("--dcu-tool-menu-shift", `${left - naturalLeft}px`);
|
|
6117
|
+
return;
|
|
6118
|
+
}
|
|
6119
|
+
const bounds = menu.getBoundingClientRect();
|
|
6120
|
+
const x = Math.max(12, Math.min(rect.left, window.innerWidth - bounds.width - 12));
|
|
6121
|
+
const y = Math.max(12, topSide ? rect.top - bounds.height - 4 : rect.bottom + 4);
|
|
6122
|
+
menu.style.setProperty("--dcu-tool-menu-x", `${x}px`);
|
|
6123
|
+
menu.style.setProperty("--dcu-tool-menu-y", `${y}px`);
|
|
6124
|
+
}
|
|
6125
|
+
const resize = new ResizeObserver(place);
|
|
6126
|
+
resize.observe(menu);
|
|
6127
|
+
resize.observe(trigger);
|
|
6128
|
+
window.addEventListener("resize", place);
|
|
6129
|
+
window.addEventListener("scroll", place, true);
|
|
6130
|
+
place();
|
|
6131
|
+
mounted.set(menu, () => {
|
|
6132
|
+
resize.disconnect();
|
|
6133
|
+
window.removeEventListener("resize", place);
|
|
6134
|
+
window.removeEventListener("scroll", place, true);
|
|
6135
|
+
input?.remove();
|
|
6136
|
+
empty?.remove();
|
|
6137
|
+
menu.querySelectorAll("[data-dcu-tool-filtered]").forEach((row) => row.removeAttribute("data-dcu-tool-filtered"));
|
|
6138
|
+
menu.removeAttribute("data-dcu-tool-menu");
|
|
6139
|
+
for (const property of [
|
|
6140
|
+
"--dcu-tool-menu-x",
|
|
6141
|
+
"--dcu-tool-menu-y",
|
|
6142
|
+
"--dcu-tool-menu-height",
|
|
6143
|
+
"--dcu-tool-menu-shift"
|
|
6144
|
+
]) menu.style.removeProperty(property);
|
|
6145
|
+
});
|
|
6146
|
+
}
|
|
6147
|
+
function sync() {
|
|
6148
|
+
for (const [menu, dispose] of mounted) if (!menu.isConnected) {
|
|
6149
|
+
dispose();
|
|
6150
|
+
mounted.delete(menu);
|
|
6151
|
+
}
|
|
6152
|
+
if (anchor === void 0 || now() > pendingUntil) return;
|
|
6153
|
+
for (const menu of document.querySelectorAll(MENU)) {
|
|
6154
|
+
if (known.has(menu) || mounted.has(menu) || menu.parentElement?.closest(MENU) !== null) continue;
|
|
6155
|
+
if (menu.getClientRects().length === 0) continue;
|
|
6156
|
+
mount(menu, anchor);
|
|
6157
|
+
pendingUntil = 0;
|
|
6158
|
+
break;
|
|
6159
|
+
}
|
|
6160
|
+
}
|
|
6161
|
+
const observer = new MutationObserver(sync);
|
|
6162
|
+
observer.observe(document.body, {
|
|
6163
|
+
childList: true,
|
|
6164
|
+
subtree: true
|
|
6165
|
+
});
|
|
6166
|
+
document.addEventListener("pointerdown", capture, true);
|
|
6167
|
+
document.addEventListener("keydown", captureKey, true);
|
|
6168
|
+
function captureKey(event) {
|
|
6169
|
+
if ([
|
|
6170
|
+
"Enter",
|
|
6171
|
+
" ",
|
|
6172
|
+
"ArrowDown"
|
|
6173
|
+
].includes(event.key)) capture(event);
|
|
6174
|
+
}
|
|
6175
|
+
return () => {
|
|
6176
|
+
observer.disconnect();
|
|
6177
|
+
document.removeEventListener("pointerdown", capture, true);
|
|
6178
|
+
document.removeEventListener("keydown", captureKey, true);
|
|
6179
|
+
mounted.forEach((dispose) => dispose());
|
|
6180
|
+
mounted.clear();
|
|
6181
|
+
};
|
|
6182
|
+
}
|
|
6183
|
+
//#endregion
|
|
6184
|
+
//#region src/client/NewConversationSuggestions.tsx
|
|
6185
|
+
const categories = [
|
|
6186
|
+
{
|
|
6187
|
+
id: "explore",
|
|
6188
|
+
label: "home.explore",
|
|
6189
|
+
tasks: [{
|
|
6190
|
+
label: "home.explore.task1",
|
|
6191
|
+
prompt: "home.explore.prompt1"
|
|
6192
|
+
}, {
|
|
6193
|
+
label: "home.explore.task2",
|
|
6194
|
+
prompt: "home.explore.prompt2"
|
|
6195
|
+
}],
|
|
6196
|
+
Icon: Telescope,
|
|
6197
|
+
color: "#27aaff"
|
|
6198
|
+
},
|
|
6199
|
+
{
|
|
6200
|
+
id: "build",
|
|
6201
|
+
label: "home.build",
|
|
6202
|
+
tasks: [{
|
|
6203
|
+
label: "home.build.task1",
|
|
6204
|
+
prompt: "home.build.prompt1"
|
|
6205
|
+
}, {
|
|
6206
|
+
label: "home.build.task2",
|
|
6207
|
+
prompt: "home.build.prompt2"
|
|
6208
|
+
}],
|
|
6209
|
+
Icon: Hammer,
|
|
6210
|
+
color: "#a478e8"
|
|
6211
|
+
},
|
|
6212
|
+
{
|
|
6213
|
+
id: "review",
|
|
6214
|
+
label: "home.review",
|
|
6215
|
+
tasks: [{
|
|
6216
|
+
label: "home.review.task1",
|
|
6217
|
+
prompt: "home.review.prompt1"
|
|
6218
|
+
}, {
|
|
6219
|
+
label: "home.review.task2",
|
|
6220
|
+
prompt: "home.review.prompt2"
|
|
6221
|
+
}],
|
|
6222
|
+
Icon: ScanLine,
|
|
6223
|
+
color: "#44bd83"
|
|
6224
|
+
},
|
|
6225
|
+
{
|
|
6226
|
+
id: "fix",
|
|
6227
|
+
label: "home.fix",
|
|
6228
|
+
tasks: [{
|
|
6229
|
+
label: "home.fix.task1",
|
|
6230
|
+
prompt: "home.fix.prompt1"
|
|
6231
|
+
}, {
|
|
6232
|
+
label: "home.fix.task2",
|
|
6233
|
+
prompt: "home.fix.prompt2"
|
|
6234
|
+
}],
|
|
6235
|
+
Icon: Bug,
|
|
6236
|
+
color: "#f48235"
|
|
6237
|
+
}
|
|
6238
|
+
];
|
|
6239
|
+
const hints = {
|
|
6240
|
+
workspace: "home.workspace",
|
|
6241
|
+
draft: "home.draft",
|
|
6242
|
+
busy: "home.busy"
|
|
6243
|
+
};
|
|
6244
|
+
const emptyDraft = {
|
|
6245
|
+
getSnapshot: () => false,
|
|
6246
|
+
subscribe: () => () => {}
|
|
6247
|
+
};
|
|
6248
|
+
/** 只向宿主标题容器贡献自己的 React portal,不搬动标题、工具条或编辑器。 */
|
|
6249
|
+
function NewConversationSuggestions({ t, prefill, draftSource = emptyDraft }) {
|
|
6250
|
+
const hasDraft = (0, react.useSyncExternalStore)(draftSource.subscribe, draftSource.getSnapshot, emptyDraft.getSnapshot);
|
|
6251
|
+
const [target, setTarget] = (0, react.useState)(null);
|
|
6252
|
+
(0, react.useEffect)(() => {
|
|
6253
|
+
const sync = () => setTarget(document.querySelector("[data-phase=hero] [class*=\"_composerHero\"]>:first-child>[class$=\"_stack\"]"));
|
|
6254
|
+
sync();
|
|
6255
|
+
const observer = new MutationObserver(sync);
|
|
6256
|
+
observer.observe(document.body, {
|
|
6257
|
+
childList: true,
|
|
6258
|
+
subtree: true,
|
|
6259
|
+
attributes: true,
|
|
6260
|
+
attributeFilter: ["data-phase"]
|
|
6261
|
+
});
|
|
6262
|
+
return () => observer.disconnect();
|
|
6263
|
+
}, []);
|
|
6264
|
+
return target === null ? null : (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SuggestionCards, {
|
|
6265
|
+
t,
|
|
6266
|
+
prefill,
|
|
6267
|
+
hasDraft
|
|
6268
|
+
}), target);
|
|
6269
|
+
}
|
|
6270
|
+
function SuggestionCards({ t, prefill, hasDraft = false }) {
|
|
6271
|
+
const [selected, setSelected] = (0, react.useState)();
|
|
6272
|
+
const [hint, setHint] = (0, react.useState)("ready");
|
|
6273
|
+
function fill(text) {
|
|
6274
|
+
const result = prefill?.(text) ?? "workspace";
|
|
6275
|
+
setHint(result);
|
|
6276
|
+
if (result === "ready") document.querySelector("[data-phase=hero] [data-lexical-editor=true]")?.focus();
|
|
6277
|
+
if (result === "workspace") document.querySelector("[data-phase=hero] [class*=\"_heroWorkspaceRow\"]>button")?.click();
|
|
6278
|
+
}
|
|
6279
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6280
|
+
className: "dcu-home-suggestions",
|
|
6281
|
+
"data-has-draft": hasDraft,
|
|
6282
|
+
"aria-hidden": hasDraft,
|
|
6283
|
+
"aria-label": t("home.suggestions"),
|
|
6284
|
+
children: [
|
|
6285
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6286
|
+
className: "dcu-home-cards",
|
|
6287
|
+
children: categories.map(({ id, label, Icon, color }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
6288
|
+
type: "button",
|
|
6289
|
+
disabled: hasDraft,
|
|
6290
|
+
className: "dcu-home-card",
|
|
6291
|
+
style: { "--dcu-home-icon": color },
|
|
6292
|
+
"aria-pressed": selected === id,
|
|
6293
|
+
onClick: () => {
|
|
6294
|
+
setSelected(selected === id ? void 0 : id);
|
|
6295
|
+
setHint("ready");
|
|
6296
|
+
},
|
|
6297
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { "aria-hidden": "true" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(label) })]
|
|
6298
|
+
}, id))
|
|
6299
|
+
}),
|
|
6300
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6301
|
+
className: "dcu-home-details",
|
|
6302
|
+
children: categories.map((category) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6303
|
+
className: "dcu-home-tasks",
|
|
6304
|
+
"data-active": selected === category.id,
|
|
6305
|
+
"aria-hidden": selected !== category.id,
|
|
6306
|
+
children: category.tasks.map((task) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6307
|
+
type: "button",
|
|
6308
|
+
className: "dcu-home-task",
|
|
6309
|
+
disabled: hasDraft || selected !== category.id,
|
|
6310
|
+
onClick: () => fill(t(task.prompt)),
|
|
6311
|
+
children: t(task.label)
|
|
6312
|
+
}, task.label))
|
|
6313
|
+
}, category.id))
|
|
6314
|
+
}),
|
|
6315
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6316
|
+
className: "dcu-home-status",
|
|
6317
|
+
children: Object.keys(hints).map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6318
|
+
className: "dcu-home-hint",
|
|
6319
|
+
"data-active": hint === key,
|
|
6320
|
+
"aria-hidden": hint !== key,
|
|
6321
|
+
role: hint === key ? "status" : void 0,
|
|
6322
|
+
children: t(hints[key])
|
|
6323
|
+
}, key))
|
|
6324
|
+
})
|
|
6325
|
+
]
|
|
6326
|
+
});
|
|
6327
|
+
}
|
|
6328
|
+
//#endregion
|
|
5394
6329
|
//#region src/client/CodexSidebar.tsx
|
|
5395
6330
|
const subscribeEmptyCompanionTabs = () => () => {};
|
|
5396
6331
|
const getEmptyCompanionTabs = () => EMPTY_COMPANION_TABS;
|
|
@@ -5409,7 +6344,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5409
6344
|
});
|
|
5410
6345
|
}
|
|
5411
6346
|
const stylesheet$3 = `
|
|
5412
|
-
.dcu-root{--dcu-font:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei UI",sans-serif;--dcu-sidebar-primary:#393d3e;--dcu-sidebar-secondary:#676b6c;--dcu-sidebar-tertiary:#9a9f9f;--dcu-sidebar-navigation:#4e5253;--dcu-sidebar-icon:#4e5253;--dcu-sidebar-hover:#dfe8e5;--dcu-sidebar-border:rgba(37,46,41,.10);--dcu-tip-bg:#ffffff;--dcu-tip-shadow:0 10px 32px rgba(31,39,36,.22);width:100%;height:100%;min-width:0;box-sizing:border-box;display:flex;flex-direction:column;overflow:hidden;background
|
|
6347
|
+
.dcu-root{--dcu-font:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei UI",sans-serif;--dcu-sidebar-background:#eef7f5;--dcu-sidebar-primary:#393d3e;--dcu-sidebar-secondary:#676b6c;--dcu-sidebar-tertiary:#9a9f9f;--dcu-sidebar-navigation:#4e5253;--dcu-sidebar-icon:#4e5253;--dcu-sidebar-hover:#dfe8e5;--dcu-sidebar-border:rgba(37,46,41,.10);--dcu-tip-bg:#ffffff;--dcu-tip-shadow:0 10px 32px rgba(31,39,36,.22);width:100%;height:100%;min-width:0;box-sizing:border-box;display:flex;flex-direction:column;overflow:hidden;background:var(--dcu-sidebar-background);color:var(--dcu-sidebar-primary);font:14px/20px var(--dcu-font)}body[data-ds-dark-theme] .dcu-root{--dcu-sidebar-background:#1d2120;--dcu-sidebar-primary:#b9bab9;--dcu-sidebar-secondary:#909191;--dcu-sidebar-tertiary:#666867;--dcu-sidebar-navigation:#b9bab9;--dcu-sidebar-icon:#afafaf;--dcu-sidebar-hover:#303432;--dcu-sidebar-border:rgba(255,255,255,.08);--dcu-tip-bg:#2a2a2a;--dcu-tip-shadow:0 10px 30px rgba(0,0,0,.28)}
|
|
5413
6348
|
/* 滤镜只作用于背景,避免为设置和搜索等 fixed 后代创建侧栏包含块。 */
|
|
5414
6349
|
body[data-we-sidebar-glass] .dcu-root{position:relative;background:transparent}body[data-we-sidebar-glass] .dcu-root::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;background-color:color-mix(in srgb,var(--we-sidebar-color,#fff) calc(var(--we-sidebar-alpha,.15)*.66*100%),transparent);background-image:linear-gradient(180deg,rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.14)),rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.04)) 38%,rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.01)));-webkit-backdrop-filter:blur(var(--we-sidebar-blur,16px)) saturate(var(--we-sidebar-saturate,1.8)) brightness(var(--we-glass-brightness,1.04)) contrast(1.01);backdrop-filter:blur(var(--we-sidebar-blur,16px)) saturate(var(--we-sidebar-saturate,1.8)) brightness(var(--we-glass-brightness,1.04)) contrast(1.01);box-shadow:inset 0 1px 0 rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.32)),inset 0 -1px 0 rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.08)),inset 0 0 0 .5px rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.06))}body[data-ds-dark-theme][data-we-sidebar-glass] .dcu-root::before{background-color:color-mix(in srgb,var(--we-sidebar-color,#fff) calc(var(--we-sidebar-alpha,.15)*.33*100%),transparent)}body[data-we-appwindow][data-we-sidebar-glass] .dcu-root::before{-webkit-backdrop-filter:none;backdrop-filter:none}@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){body[data-we-sidebar-glass] .dcu-root{background:#eef7f5}body[data-ds-dark-theme][data-we-sidebar-glass] .dcu-root{background:#1d2120}body[data-we-sidebar-glass] .dcu-root::before{display:none}}
|
|
5415
6350
|
body[data-we-sidebar-glass] .dcu-expanded-shell,body[data-we-sidebar-glass] .dcu-compact-shell,body[data-we-sidebar-glass] .dcu-foot{position:relative}
|
|
@@ -5438,7 +6373,6 @@ body[data-we-sidebar-glass] .dcu-expanded-shell,body[data-we-sidebar-glass] .dcu
|
|
|
5438
6373
|
.dcu-footer-actions [data-testid="billing-rail-button"] svg{flex:none;width:24px;height:24px;stroke-width:1.5px}
|
|
5439
6374
|
.dcu-settings-seat [data-slot="settings.trigger"]{color:var(--dcu-sidebar-navigation)}
|
|
5440
6375
|
.dcu-settings-seat [data-slot="settings.trigger"]>svg{color:var(--dcu-sidebar-icon)}
|
|
5441
|
-
.dcu-root:not(.dcu-compact) .dcu-settings-seat [data-slot="settings.trigger"]>span{margin-left:4px}
|
|
5442
6376
|
@media (prefers-reduced-motion:reduce){.dcu-footer-actions :is([data-testid="billing-trigger"],[data-testid="billing-rail-button"]){transition:none}}
|
|
5443
6377
|
/* 宿主列负责缩放,宽态内容保持展开宽度,避免中文竖排与工作区逐帧重排。 */
|
|
5444
6378
|
.dcu-expanded-shell,.dcu-root:not(.dcu-compact)>.dcu-foot{width:var(--dcu-sidebar-expanded-width,240px);flex-shrink:0}
|
|
@@ -5457,9 +6391,24 @@ body[data-we-sidebar-glass] .dcu-expanded-shell,body[data-we-sidebar-glass] .dcu
|
|
|
5457
6391
|
@media (prefers-reduced-motion:reduce){[data-dcu-codex-sidebar-initialized],[data-dcu-codex-sidebar-initialized] [data-side="sidebar"],#root [data-dcu-codex-sidebar-initialized]:not([data-dragging]){transition:none}.dcu-root.dcu-collapsing .dcu-compact-shell{animation:none}}
|
|
5458
6392
|
.dcu-native-workspaces{flex-direction:column}.dcu-native-workspaces>[data-mcp-connector-top-mount=true]{flex:none}.dcu-root .mcpConnectorLauncher,.dcu-root [data-mcp-connector-top-mount=true]{display:none!important}
|
|
5459
6393
|
.dcu-dependency-notice{margin:0 10px 8px;border:1px solid var(--dcu-sidebar-border);border-radius:8px;padding:8px;color:var(--dcu-sidebar-secondary);font-size:12px;line-height:18px}
|
|
5460
|
-
[role="dialog"][aria-labelledby]{width:min(1000px,calc(100vw - 48px));max-width:calc(100vw - 48px);height:min(800px,calc(100vh - 48px))}
|
|
5461
6394
|
.dcu-search-scrim{position:fixed;z-index:10020;inset:0;display:flex;justify-content:center;align-items:flex-start;padding:72px 20px;background:color-mix(in srgb,#000 48%,transparent);animation:dcu-search-scrim-in 140ms ease-out}.dcu-search-dialog{width:min(560px,100%);max-height:min(640px,calc(100vh - 120px));overflow:auto;border:1px solid var(--dcu-sidebar-border);border-radius:16px;padding:10px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv4);animation:dcu-search-dialog-in 180ms cubic-bezier(.16,1,.3,1)}@keyframes dcu-search-scrim-in{from{opacity:0}to{opacity:1}}@keyframes dcu-search-dialog-in{from{opacity:0;transform:translateY(-6px) scale(.985)}to{opacity:1}}.dcu-search-input{margin-bottom:8px}.dcu-search-section{padding:6px 0}.dcu-search-title{padding:0 8px 4px;color:var(--dcu-sidebar-tertiary);font-size:12px;font-weight:600}.dcu-search-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;width:100%;min-height:34px;border:0;border-radius:8px;padding:6px 8px;background:transparent;color:var(--dcu-sidebar-primary);font:inherit;text-align:left;cursor:pointer}.dcu-search-row:hover,.dcu-search-row[data-active=true]{background:var(--dcu-sidebar-hover)}.dcu-search-main{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-search-detail{max-width:160px;overflow:hidden;color:var(--dcu-sidebar-tertiary);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.dcu-search-empty{padding:18px 8px;color:var(--dcu-sidebar-tertiary);font-size:13px}@media (prefers-reduced-motion:reduce){.dcu-expanded-shell,.dcu-root.dcu-compact .dcu-compact-shell,.dcu-foot,.dcu-search-scrim,.dcu-search-dialog,.dcu-extension-panel,.dcu-extension-leading svg{animation:none;transition:none}}
|
|
5462
|
-
[data-conversation-scroll]{--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px);--dsh-composer-side-clearance:24px
|
|
6395
|
+
[data-conversation-scroll]{--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px);--dsh-composer-side-clearance:24px;--dcu-composer-bg:var(--dsw-specific-input-major,#fff);--dcu-composer-shadow:0 0 0 1px #0000000a,0 2px 8px #0000000a,0 4px 80px 8px #00000006}
|
|
6396
|
+
body[data-ds-dark-theme] [data-conversation-scroll]{--dcu-composer-bg:var(--dsw-alias-bg-layer-2,#242424);--dcu-composer-shadow:inset 0 0 1px #fff3}
|
|
6397
|
+
[data-conversation-scroll] [data-composer-card]{padding-top:8px;gap:4px;border:0;border-radius:20px;background:var(--dcu-composer-bg);box-shadow:var(--dcu-composer-shadow)}
|
|
6398
|
+
[data-conversation-scroll] [data-input-mirror]{min-height:44px}
|
|
6399
|
+
[data-conversation-scroll] [data-composer-card] [data-input-scroll]{margin-right:0}
|
|
6400
|
+
[data-conversation-scroll] [data-input-scroll] [data-lexical-editor=true]{min-height:44px;padding:0 12px}
|
|
6401
|
+
[data-conversation-scroll] [data-composer-placeholder]{inset:0 12px auto}
|
|
6402
|
+
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div{padding:0 8px 8px;gap:5px}
|
|
6403
|
+
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div>div{gap:4px}
|
|
6404
|
+
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div>div>div{gap:4px}
|
|
6405
|
+
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div :is(button,select):not([role]){min-height:28px;height:28px}
|
|
6406
|
+
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div button[class$=_primary]{width:28px;transform:none;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-base)}
|
|
6407
|
+
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div button[class$=_primary]:hover:not(:disabled){background:var(--dsw-alias-label-secondary)}
|
|
6408
|
+
[data-conversation-scroll] [data-composer-card]>[data-input-scroll]+div :is(button,select):focus-visible{outline:2px solid var(--dsw-alias-label-secondary);outline-offset:2px}
|
|
6409
|
+
@supports(corner-shape:superellipse(1.5)){[data-conversation-scroll] [data-composer-card]{border-radius:25px;corner-shape:superellipse(1.5)}}
|
|
6410
|
+
@media(max-width:639px){[data-conversation-scroll]{--dcu-composer-shadow:0 0 0 1px #0000000a,0 2px 8px #0000000a,0 4px 40px 8px #00000006}}
|
|
6411
|
+
@media(forced-colors:active){[data-conversation-scroll] [data-composer-card]{outline:1px solid CanvasText}}
|
|
5463
6412
|
html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:has([data-dcu-official-turn-navigator]) .dcu-turn-navigator{display:none}
|
|
5464
6413
|
[data-dcu-official-turn-navigator]{right:auto!important;left:calc(12px - (var(--dsh-composer-side-clearance) + 16px))!important}
|
|
5465
6414
|
[data-dcu-official-turn-mark]{inset:0 auto 0 0!important}
|
|
@@ -5545,7 +6494,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
5545
6494
|
t
|
|
5546
6495
|
]);
|
|
5547
6496
|
const openSettings = (0, react.useCallback)(() => {
|
|
5548
|
-
settingsSeat.current
|
|
6497
|
+
openSettingsRoot(settingsSeat.current);
|
|
5549
6498
|
}, [settingsSeat]);
|
|
5550
6499
|
const entries = (0, react.useMemo)(() => {
|
|
5551
6500
|
const archived = new Set(workspaces.archivedSessionIds);
|
|
@@ -5774,7 +6723,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
5774
6723
|
});
|
|
5775
6724
|
});
|
|
5776
6725
|
/** Codex 风格的 DSH 侧栏,只替换导航外观,项目浏览和设置仍由 DSH 官方组件提供。 */
|
|
5777
|
-
function CodexSidebar({ collapsed, width, openSession, startSession, toggleSidebar, archiveSession, deleteSession, forkSession, moveSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useSessionPendingInteraction, useWorkspaces }) {
|
|
6726
|
+
function CodexSidebar({ collapsed, width, openSession, startSession, toggleSidebar, archiveSession, deleteSession, forkSession, moveSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useSessionPendingInteraction, useWorkspaces, prefillNewConversation, newConversationDraft }) {
|
|
5778
6727
|
const compact = collapsed || width < 80;
|
|
5779
6728
|
const [visualCompact, setVisualCompact] = (0, react.useState)(compact);
|
|
5780
6729
|
const [collapsing, setCollapsing] = (0, react.useState)(false);
|
|
@@ -5951,6 +6900,13 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
5951
6900
|
"aria-label": t("sidebar.label"),
|
|
5952
6901
|
children: [
|
|
5953
6902
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: stylesheet$3 }),
|
|
6903
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: NEW_CONVERSATION_STYLE }),
|
|
6904
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: COMPOSER_TOOL_MENU_STYLE }),
|
|
6905
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NewConversationSuggestions, {
|
|
6906
|
+
t,
|
|
6907
|
+
prefill: prefillNewConversation,
|
|
6908
|
+
draftSource: newConversationDraft
|
|
6909
|
+
}),
|
|
5954
6910
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5955
6911
|
className: "dcu-expanded-shell",
|
|
5956
6912
|
children: [
|
|
@@ -6856,6 +7812,70 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
6856
7812
|
/** 本插件独占的界面文案命名空间。 */
|
|
6857
7813
|
const NS = "michengai.codexUi";
|
|
6858
7814
|
const zh = {
|
|
7815
|
+
"home.resizeInput": "拖动调整输入区宽度",
|
|
7816
|
+
"home.projectSearch": "搜索项目",
|
|
7817
|
+
"home.projectEmpty": "没有匹配的项目",
|
|
7818
|
+
"home.suggestions": "开始一项任务",
|
|
7819
|
+
"home.workspace": "请先选择工作区,再选择任务。",
|
|
7820
|
+
"home.draft": "已保留当前草稿和附件;清空输入后可填入任务建议。",
|
|
7821
|
+
"home.busy": "当前输入正在处理中,请稍后再试。",
|
|
7822
|
+
"home.explore": "探索并理解代码",
|
|
7823
|
+
"home.build": "构建新功能、应用或工具",
|
|
7824
|
+
"home.review": "审查代码并提出修改建议",
|
|
7825
|
+
"home.fix": "修复问题和失败",
|
|
7826
|
+
"home.explore.task1": "了解项目结构",
|
|
7827
|
+
"home.explore.prompt1": "请探索当前工作区的代码,解释项目结构、主要入口和模块之间的关系。",
|
|
7828
|
+
"home.explore.task2": "理解一项功能",
|
|
7829
|
+
"home.explore.prompt2": "我想了解一项功能的实现。先问我具体是哪项功能,再沿调用关系解释。",
|
|
7830
|
+
"home.build.task1": "实现一项新功能",
|
|
7831
|
+
"home.build.prompt1": "我想在当前项目中实现一项新功能。先和我确认需求与验收标准,再实施。",
|
|
7832
|
+
"home.build.task2": "构建一个小工具",
|
|
7833
|
+
"home.build.prompt2": "我想构建一个小工具。先问我目标、输入和输出,再结合当前项目提出方案。",
|
|
7834
|
+
"home.review.task1": "评审当前改动",
|
|
7835
|
+
"home.review.prompt1": "请评审当前工作区的未提交改动,优先指出真实缺陷、回归风险和缺少的测试;先不要修改。",
|
|
7836
|
+
"home.review.task2": "检查代码质量",
|
|
7837
|
+
"home.review.prompt2": "请检查当前项目的代码质量,给出有源码依据的改进建议,先评估不改动。",
|
|
7838
|
+
"home.fix.task1": "排查一个问题",
|
|
7839
|
+
"home.fix.prompt1": "我遇到了一个问题。先问我复现步骤、预期和实际表现,再定位根因并修复。",
|
|
7840
|
+
"home.fix.task2": "修复失败的测试",
|
|
7841
|
+
"home.fix.prompt2": "请运行当前项目适用的测试,定位失败根因并做最小修复,保留有效的回归覆盖。",
|
|
7842
|
+
"host.transcript.normal": "标准",
|
|
7843
|
+
"host.transcript.compact": "紧凑",
|
|
7844
|
+
"host.command.compact": "压缩较早的对话历史",
|
|
7845
|
+
"host.command.export": "将当前会话日志下载为 ZIP 压缩包",
|
|
7846
|
+
"host.command.feedback": "记录对当前会话的反馈",
|
|
7847
|
+
"host.command.goal": "设置或查看长时间任务的目标",
|
|
7848
|
+
"host.command.permission": "切换权限预设(沙箱模式与审批策略)",
|
|
7849
|
+
"host.command.plan": "进入或退出计划模式",
|
|
7850
|
+
"usage.title": "使用统计",
|
|
7851
|
+
"usage.loading": "正在加载费用面板…",
|
|
7852
|
+
"usage.failed": "费用面板暂时无法嵌入,可重试或打开原弹窗。",
|
|
7853
|
+
"usage.closed": "费用面板已关闭。",
|
|
7854
|
+
"usage.reopen": "重新打开费用面板",
|
|
7855
|
+
"usage.retry": "重试",
|
|
7856
|
+
"usage.original": "打开原弹窗",
|
|
7857
|
+
"settings.title": "设置",
|
|
7858
|
+
"settings.back": "返回应用",
|
|
7859
|
+
"settings.openDocument": "打开配置文件",
|
|
7860
|
+
"settings.advanced": "高级",
|
|
7861
|
+
"settings.documentTitle": "配置文件",
|
|
7862
|
+
"settings.documentDescription": "在外部编辑器中查看和编辑配置",
|
|
7863
|
+
"settings.documentOpen": "打开",
|
|
7864
|
+
"settings.documentOpening": "打开中…",
|
|
7865
|
+
"settings.openDocumentError": "无法打开配置文件",
|
|
7866
|
+
"settings.search": "搜索设置…",
|
|
7867
|
+
"settings.personal": "个人",
|
|
7868
|
+
"settings.integrations": "集成",
|
|
7869
|
+
"settings.records": "记录与应用",
|
|
7870
|
+
"settings.general": "常规",
|
|
7871
|
+
"settings.permissions": "权限",
|
|
7872
|
+
"settings.editor": "编辑器",
|
|
7873
|
+
"settings.noResults": "没有匹配的设置分类",
|
|
7874
|
+
"settings.filterHint": "仅筛选导航,选择分类后切换当前页面。",
|
|
7875
|
+
"settings.disconnected": "连接异常",
|
|
7876
|
+
"settings.reconnect": "立即重连",
|
|
7877
|
+
"settings.connecting": "连接中",
|
|
7878
|
+
"settings.recovered": "连接成功",
|
|
6859
7879
|
"input.historyHint": "↑↓ 翻历史",
|
|
6860
7880
|
"sidebar.label": "DSH 导航",
|
|
6861
7881
|
"sidebar.expand": "展开侧边栏",
|
|
@@ -7068,6 +8088,70 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
7068
8088
|
"meta.locale": "zh-CN"
|
|
7069
8089
|
};
|
|
7070
8090
|
const en = {
|
|
8091
|
+
"home.resizeInput": "Drag to resize the input area",
|
|
8092
|
+
"home.projectSearch": "Search projects",
|
|
8093
|
+
"home.projectEmpty": "No matching projects",
|
|
8094
|
+
"home.suggestions": "Start a task",
|
|
8095
|
+
"home.workspace": "Choose a workspace first, then select a task.",
|
|
8096
|
+
"home.draft": "Your draft and attachments are preserved. Clear the input to use a suggestion.",
|
|
8097
|
+
"home.busy": "The input is busy. Please try again shortly.",
|
|
8098
|
+
"home.explore": "Explore and understand code",
|
|
8099
|
+
"home.build": "Build features, apps, or tools",
|
|
8100
|
+
"home.review": "Review code and suggest changes",
|
|
8101
|
+
"home.fix": "Fix bugs and failures",
|
|
8102
|
+
"home.explore.task1": "Explain the project structure",
|
|
8103
|
+
"home.explore.prompt1": "Explore this workspace and explain its structure, main entry points, and module relationships.",
|
|
8104
|
+
"home.explore.task2": "Understand a feature",
|
|
8105
|
+
"home.explore.prompt2": "Help me understand a feature. First ask which feature, then explain its implementation and call flow.",
|
|
8106
|
+
"home.build.task1": "Implement a feature",
|
|
8107
|
+
"home.build.prompt1": "Help me implement a feature in this project. First clarify requirements and acceptance criteria.",
|
|
8108
|
+
"home.build.task2": "Build a small tool",
|
|
8109
|
+
"home.build.prompt2": "Help me build a small tool. First ask about its goal, inputs, and outputs, then propose an approach.",
|
|
8110
|
+
"home.review.task1": "Review current changes",
|
|
8111
|
+
"home.review.prompt1": "Review uncommitted changes for bugs, regressions, and missing tests. Do not modify files yet.",
|
|
8112
|
+
"home.review.task2": "Inspect code quality",
|
|
8113
|
+
"home.review.prompt2": "Inspect code quality in this project and suggest improvements grounded in the source. Assess only; do not edit.",
|
|
8114
|
+
"home.fix.task1": "Investigate a bug",
|
|
8115
|
+
"home.fix.prompt1": "Help me fix a bug. First ask for reproduction steps, expected behavior, and actual behavior.",
|
|
8116
|
+
"home.fix.task2": "Fix failing tests",
|
|
8117
|
+
"home.fix.prompt2": "Run the applicable project tests, identify failure causes, and make minimal fixes with meaningful regression coverage.",
|
|
8118
|
+
"host.transcript.normal": "Normal",
|
|
8119
|
+
"host.transcript.compact": "Compact",
|
|
8120
|
+
"host.command.compact": "Compact older conversation history",
|
|
8121
|
+
"host.command.export": "Download this Session log as a ZIP archive",
|
|
8122
|
+
"host.command.feedback": "record feedback about this session",
|
|
8123
|
+
"host.command.goal": "set or view the goal for a long-running task",
|
|
8124
|
+
"host.command.permission": "Switch the permission preset (sandbox mode + approval policy)",
|
|
8125
|
+
"host.command.plan": "Enter or leave plan mode",
|
|
8126
|
+
"usage.title": "Usage statistics",
|
|
8127
|
+
"usage.loading": "Loading billing dashboard…",
|
|
8128
|
+
"usage.failed": "The embedded dashboard is unavailable. Retry or open the original dialog.",
|
|
8129
|
+
"usage.closed": "The billing dashboard is closed.",
|
|
8130
|
+
"usage.reopen": "Reopen billing dashboard",
|
|
8131
|
+
"usage.retry": "Retry",
|
|
8132
|
+
"usage.original": "Open original dialog",
|
|
8133
|
+
"settings.title": "Settings",
|
|
8134
|
+
"settings.back": "Back to app",
|
|
8135
|
+
"settings.openDocument": "Open configuration file",
|
|
8136
|
+
"settings.advanced": "Advanced",
|
|
8137
|
+
"settings.documentTitle": "Configuration file",
|
|
8138
|
+
"settings.documentDescription": "View and edit configuration in an external editor",
|
|
8139
|
+
"settings.documentOpen": "Open",
|
|
8140
|
+
"settings.documentOpening": "Opening…",
|
|
8141
|
+
"settings.openDocumentError": "Could not open configuration file",
|
|
8142
|
+
"settings.search": "Search settings…",
|
|
8143
|
+
"settings.personal": "Personal",
|
|
8144
|
+
"settings.integrations": "Integrations",
|
|
8145
|
+
"settings.records": "Records and app",
|
|
8146
|
+
"settings.general": "General",
|
|
8147
|
+
"settings.permissions": "Permissions",
|
|
8148
|
+
"settings.editor": "Editor",
|
|
8149
|
+
"settings.noResults": "No matching settings categories",
|
|
8150
|
+
"settings.filterHint": "Navigation is filtered. Select a category to switch pages.",
|
|
8151
|
+
"settings.disconnected": "Disconnected",
|
|
8152
|
+
"settings.reconnect": "Reconnect now",
|
|
8153
|
+
"settings.connecting": "Connecting",
|
|
8154
|
+
"settings.recovered": "Connected",
|
|
7071
8155
|
"input.historyHint": "↑↓ History",
|
|
7072
8156
|
"sidebar.label": "DSH navigation",
|
|
7073
8157
|
"sidebar.expand": "Expand sidebar",
|
|
@@ -7339,79 +8423,956 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
7339
8423
|
const text = label.trim();
|
|
7340
8424
|
for (const [aliases, id] of LABEL_ALIASES) if (aliases.includes(text)) return id;
|
|
7341
8425
|
}
|
|
7342
|
-
function applySettingsNavIcon(button) {
|
|
7343
|
-
const id = settingsNavIconId(button.textContent ?? "");
|
|
7344
|
-
if (id === void 0) return false;
|
|
7345
|
-
let changed = false;
|
|
7346
|
-
if (id === "about") {
|
|
7347
|
-
if (!button.hasAttribute("data-dcu-settings-about-last")) {
|
|
7348
|
-
button.setAttribute("data-dcu-settings-about-last", "");
|
|
7349
|
-
changed = true;
|
|
7350
|
-
}
|
|
7351
|
-
if (button.style.getPropertyValue("order") !== "2147483647" || button.style.getPropertyPriority("order") !== "important") {
|
|
7352
|
-
button.style.setProperty("order", ABOUT_SETTINGS_NAV_ORDER, "important");
|
|
7353
|
-
changed = true;
|
|
7354
|
-
}
|
|
8426
|
+
function applySettingsNavIcon(button) {
|
|
8427
|
+
const id = settingsNavIconId(button.textContent ?? "");
|
|
8428
|
+
if (id === void 0) return false;
|
|
8429
|
+
let changed = false;
|
|
8430
|
+
if (id === "about") {
|
|
8431
|
+
if (!button.hasAttribute("data-dcu-settings-about-last")) {
|
|
8432
|
+
button.setAttribute("data-dcu-settings-about-last", "");
|
|
8433
|
+
changed = true;
|
|
8434
|
+
}
|
|
8435
|
+
if (button.style.getPropertyValue("order") !== "2147483647" || button.style.getPropertyPriority("order") !== "important") {
|
|
8436
|
+
button.style.setProperty("order", ABOUT_SETTINGS_NAV_ORDER, "important");
|
|
8437
|
+
changed = true;
|
|
8438
|
+
}
|
|
8439
|
+
}
|
|
8440
|
+
const svg = button.querySelector("svg");
|
|
8441
|
+
if (svg === null) return changed;
|
|
8442
|
+
if (svg.getAttribute("data-dcu-nav-icon") === id) return changed;
|
|
8443
|
+
svg.setAttribute("data-dcu-nav-icon", id);
|
|
8444
|
+
svg.setAttribute("viewBox", id === "archive" ? "0 0 20 20" : id === "about" ? "0 0 14 14" : "0 0 16 16");
|
|
8445
|
+
svg.setAttribute("fill", "none");
|
|
8446
|
+
svg.innerHTML = SETTINGS_NAV_ICON_HTML[id];
|
|
8447
|
+
return true;
|
|
8448
|
+
}
|
|
8449
|
+
function applySettingsNavIcons(root) {
|
|
8450
|
+
let changed = 0;
|
|
8451
|
+
for (const button of root.querySelectorAll("[role=\"dialog\"] nav button")) if (applySettingsNavIcon(button)) changed += 1;
|
|
8452
|
+
return changed;
|
|
8453
|
+
}
|
|
8454
|
+
/** 设置壳只给少数分区画专用图标,这里把已安装插件的导航改成侧栏同款。 */
|
|
8455
|
+
function observeSettingsNavIcons() {
|
|
8456
|
+
if (typeof document === "undefined" || document.body === null) return () => {};
|
|
8457
|
+
let applying = false;
|
|
8458
|
+
let frame;
|
|
8459
|
+
const pendingRoots = /* @__PURE__ */ new Set([document]);
|
|
8460
|
+
const apply = () => {
|
|
8461
|
+
if (applying) return;
|
|
8462
|
+
applying = true;
|
|
8463
|
+
const roots = [...pendingRoots];
|
|
8464
|
+
pendingRoots.clear();
|
|
8465
|
+
try {
|
|
8466
|
+
for (const root of roots) applySettingsNavIcons(root);
|
|
8467
|
+
} finally {
|
|
8468
|
+
applying = false;
|
|
8469
|
+
}
|
|
8470
|
+
};
|
|
8471
|
+
const schedule = () => {
|
|
8472
|
+
if (frame !== void 0) return;
|
|
8473
|
+
frame = window.requestAnimationFrame(() => {
|
|
8474
|
+
frame = void 0;
|
|
8475
|
+
apply();
|
|
8476
|
+
});
|
|
8477
|
+
};
|
|
8478
|
+
apply();
|
|
8479
|
+
const observer = new MutationObserver((records) => {
|
|
8480
|
+
for (const record of records) {
|
|
8481
|
+
const button = (record.target.nodeType === 1 ? record.target : record.target.parentElement)?.closest("[role=\"dialog\"] nav button");
|
|
8482
|
+
if (button !== null && button !== void 0) pendingRoots.add(button.closest("[role=\"dialog\"]") ?? document);
|
|
8483
|
+
for (const node of record.addedNodes) {
|
|
8484
|
+
if (!(node instanceof Element)) continue;
|
|
8485
|
+
if (node.matches("[role=\"dialog\"] nav button")) pendingRoots.add(node.closest("[role=\"dialog\"]") ?? document);
|
|
8486
|
+
else if (node.querySelector("[role=\"dialog\"] nav button") !== null) pendingRoots.add(node);
|
|
8487
|
+
}
|
|
8488
|
+
}
|
|
8489
|
+
if (pendingRoots.size > 0) schedule();
|
|
8490
|
+
});
|
|
8491
|
+
observer.observe(document.body, {
|
|
8492
|
+
childList: true,
|
|
8493
|
+
subtree: true
|
|
8494
|
+
});
|
|
8495
|
+
return () => {
|
|
8496
|
+
observer.disconnect();
|
|
8497
|
+
if (frame !== void 0) window.cancelAnimationFrame(frame);
|
|
8498
|
+
};
|
|
8499
|
+
}
|
|
8500
|
+
//#endregion
|
|
8501
|
+
//#region src/usage-frame/contract.ts
|
|
8502
|
+
/** 同源费用承载页与宿主之间的最小能力桥;不暴露 Context 或远程服务全集。 */
|
|
8503
|
+
const USAGE_FRAME_PATH = "/api/dsh-codex-ui/usage/frame";
|
|
8504
|
+
const BILLING_ENTRY_ID = "usage-billing";
|
|
8505
|
+
//#endregion
|
|
8506
|
+
//#region src/client/UsageStatisticsSection.tsx
|
|
8507
|
+
/** 设置中的费用原面板承载区;不重建图表、计费或原面板的业务逻辑。 */
|
|
8508
|
+
function UsageStatisticsSection({ useStore, actions, billing, close, openOriginal, t }) {
|
|
8509
|
+
const snapshot = useStore((state) => state);
|
|
8510
|
+
const latest = (0, react.useRef)(snapshot);
|
|
8511
|
+
const listeners = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
8512
|
+
const frame = (0, react.useRef)(null);
|
|
8513
|
+
const [attempt, setAttempt] = (0, react.useState)(0);
|
|
8514
|
+
const [state, setState] = (0, react.useState)("loading");
|
|
8515
|
+
const disposeTheme = (0, react.useRef)(() => {});
|
|
8516
|
+
const timer = (0, react.useRef)(void 0);
|
|
8517
|
+
(0, react.useEffect)(() => {
|
|
8518
|
+
latest.current = snapshot;
|
|
8519
|
+
listeners.current.forEach((listener) => listener());
|
|
8520
|
+
}, [snapshot]);
|
|
8521
|
+
(0, react.useEffect)(() => {
|
|
8522
|
+
setState("loading");
|
|
8523
|
+
timer.current = setTimeout(() => {
|
|
8524
|
+
setState("failed");
|
|
8525
|
+
}, 15e3);
|
|
8526
|
+
return () => {
|
|
8527
|
+
clearTimeout(timer.current);
|
|
8528
|
+
disposeTheme.current();
|
|
8529
|
+
listeners.current.clear();
|
|
8530
|
+
};
|
|
8531
|
+
}, [attempt]);
|
|
8532
|
+
(0, react.useEffect)(() => {
|
|
8533
|
+
if ((state === "closed" || state === "failed") && document.activeElement === frame.current) frame.current?.parentElement?.querySelector("button")?.focus();
|
|
8534
|
+
}, [state]);
|
|
8535
|
+
const connect = () => {
|
|
8536
|
+
const target = frame.current?.contentWindow;
|
|
8537
|
+
if (!target) return;
|
|
8538
|
+
try {
|
|
8539
|
+
if (target.location.origin !== location.origin || target.location.pathname !== "/api/dsh-codex-ui/usage/frame") throw new Error("费用承载页地址不匹配");
|
|
8540
|
+
const document = target.document;
|
|
8541
|
+
if (!target.dcuUsageRuntimeReady || !document.getElementById("billing-root")) throw new Error("费用承载页未正确加载");
|
|
8542
|
+
const sync = () => {
|
|
8543
|
+
document.body.toggleAttribute("data-ds-dark-theme", window.document.body.hasAttribute("data-ds-dark-theme"));
|
|
8544
|
+
document.documentElement.lang = window.document.documentElement.lang;
|
|
8545
|
+
const tokens = getComputedStyle(window.document.body);
|
|
8546
|
+
for (const key of tokens) if (key.startsWith("--dsw-")) document.body.style.setProperty(key, tokens.getPropertyValue(key));
|
|
8547
|
+
};
|
|
8548
|
+
sync();
|
|
8549
|
+
disposeTheme.current();
|
|
8550
|
+
const observer = new MutationObserver(sync);
|
|
8551
|
+
observer.observe(window.document.body, {
|
|
8552
|
+
attributes: true,
|
|
8553
|
+
attributeFilter: [
|
|
8554
|
+
"data-ds-dark-theme",
|
|
8555
|
+
"class",
|
|
8556
|
+
"style"
|
|
8557
|
+
]
|
|
8558
|
+
});
|
|
8559
|
+
disposeTheme.current = () => observer.disconnect();
|
|
8560
|
+
target.dcuUsageHost = {
|
|
8561
|
+
getSnapshot: () => latest.current,
|
|
8562
|
+
subscribe: (listener) => {
|
|
8563
|
+
listeners.current.add(listener);
|
|
8564
|
+
return () => {
|
|
8565
|
+
listeners.current.delete(listener);
|
|
8566
|
+
};
|
|
8567
|
+
},
|
|
8568
|
+
actions,
|
|
8569
|
+
...billing,
|
|
8570
|
+
close,
|
|
8571
|
+
dismissed: () => {
|
|
8572
|
+
clearTimeout(timer.current);
|
|
8573
|
+
setState((current) => current === "failed" ? current : "closed");
|
|
8574
|
+
},
|
|
8575
|
+
focusOutside: (backward) => {
|
|
8576
|
+
const page = frame.current?.closest("[data-dcu-settings-page]");
|
|
8577
|
+
if (!page || !frame.current) return;
|
|
8578
|
+
const controls = [...page.querySelectorAll("button,input,select,textarea,a[href],[tabindex]")].filter((element) => element.tabIndex >= 0 && !element.matches(":disabled") && !element.closest("[inert]") && element.getClientRects().length > 0);
|
|
8579
|
+
controls[(controls.indexOf(frame.current) + (backward ? -1 : 1) + controls.length) % controls.length]?.focus();
|
|
8580
|
+
},
|
|
8581
|
+
ready: () => {
|
|
8582
|
+
clearTimeout(timer.current);
|
|
8583
|
+
setState((current) => current === "failed" ? current : "ready");
|
|
8584
|
+
},
|
|
8585
|
+
failed: (message) => {
|
|
8586
|
+
console.warn("[michengai-codex-ui] 费用承载失败:%s", message);
|
|
8587
|
+
clearTimeout(timer.current);
|
|
8588
|
+
setState("failed");
|
|
8589
|
+
}
|
|
8590
|
+
};
|
|
8591
|
+
target.postMessage({ type: "dcu-usage-init" }, location.origin);
|
|
8592
|
+
} catch (error) {
|
|
8593
|
+
console.warn("[michengai-codex-ui] 无法连接费用承载页", error);
|
|
8594
|
+
clearTimeout(timer.current);
|
|
8595
|
+
setState("failed");
|
|
8596
|
+
}
|
|
8597
|
+
};
|
|
8598
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
8599
|
+
className: "dcu-usage-section",
|
|
8600
|
+
"aria-label": t("usage.title"),
|
|
8601
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: t("usage.title") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8602
|
+
className: "dcu-usage-stage",
|
|
8603
|
+
"aria-busy": state === "loading",
|
|
8604
|
+
children: [
|
|
8605
|
+
state === "loading" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
8606
|
+
className: "dcu-usage-loading",
|
|
8607
|
+
role: "status",
|
|
8608
|
+
children: t("usage.loading")
|
|
8609
|
+
}),
|
|
8610
|
+
state === "closed" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8611
|
+
role: "status",
|
|
8612
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("usage.closed") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8613
|
+
onClick: () => setAttempt((value) => value + 1),
|
|
8614
|
+
children: t("usage.reopen")
|
|
8615
|
+
})]
|
|
8616
|
+
}),
|
|
8617
|
+
state === "failed" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8618
|
+
role: "alert",
|
|
8619
|
+
children: [
|
|
8620
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("usage.failed") }),
|
|
8621
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8622
|
+
onClick: () => {
|
|
8623
|
+
setAttempt((value) => value + 1);
|
|
8624
|
+
},
|
|
8625
|
+
children: t("usage.retry")
|
|
8626
|
+
}),
|
|
8627
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8628
|
+
onClick: () => {
|
|
8629
|
+
close();
|
|
8630
|
+
requestAnimationFrame(openOriginal);
|
|
8631
|
+
},
|
|
8632
|
+
children: t("usage.original")
|
|
8633
|
+
})
|
|
8634
|
+
]
|
|
8635
|
+
}),
|
|
8636
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
8637
|
+
ref: frame,
|
|
8638
|
+
title: t("usage.title"),
|
|
8639
|
+
src: USAGE_FRAME_PATH,
|
|
8640
|
+
onLoad: connect,
|
|
8641
|
+
"aria-hidden": state !== "ready",
|
|
8642
|
+
tabIndex: state === "ready" ? 0 : -1,
|
|
8643
|
+
style: { visibility: state === "ready" ? "visible" : "hidden" },
|
|
8644
|
+
className: "dcu-usage-frame"
|
|
8645
|
+
}, attempt)
|
|
8646
|
+
]
|
|
8647
|
+
})]
|
|
8648
|
+
});
|
|
8649
|
+
}
|
|
8650
|
+
//#endregion
|
|
8651
|
+
//#region src/client/usage-statistics.ts
|
|
8652
|
+
function registerUsageStatistics(ctx) {
|
|
8653
|
+
const t = ctx.locale.bind(NS);
|
|
8654
|
+
ctx.slots.inject("settings.section", () => {
|
|
8655
|
+
let current;
|
|
8656
|
+
let remove;
|
|
8657
|
+
const refresh = () => {
|
|
8658
|
+
const entry = ctx.slots.entriesOfSlot("sidebar.footer.action").find((item) => item.options.id === BILLING_ENTRY_ID);
|
|
8659
|
+
if (entry === current) return;
|
|
8660
|
+
remove?.();
|
|
8661
|
+
remove = void 0;
|
|
8662
|
+
current = entry;
|
|
8663
|
+
if (!entry?.store || typeof entry.store === "function" || !entry.locale || !entry.inject) return;
|
|
8664
|
+
const face = entry.inject();
|
|
8665
|
+
if (typeof face.checkModels !== "function" || typeof face.publishCosts !== "function") return;
|
|
8666
|
+
const billing = {
|
|
8667
|
+
translate: ctx.locale.bind(entry.locale),
|
|
8668
|
+
checkModels: face.checkModels,
|
|
8669
|
+
publishCosts: face.publishCosts
|
|
8670
|
+
};
|
|
8671
|
+
remove = ctx.slots.register({
|
|
8672
|
+
name: "settings.section",
|
|
8673
|
+
id: "usage-statistics",
|
|
8674
|
+
order: 90,
|
|
8675
|
+
label: () => t("usage.title"),
|
|
8676
|
+
locale: NS,
|
|
8677
|
+
store: entry.store,
|
|
8678
|
+
inject: () => ({
|
|
8679
|
+
billing,
|
|
8680
|
+
openOriginal: () => {
|
|
8681
|
+
ctx.get("billingMetrics")?.openDashboard?.();
|
|
8682
|
+
}
|
|
8683
|
+
})
|
|
8684
|
+
}, UsageStatisticsSection);
|
|
8685
|
+
};
|
|
8686
|
+
const unsubscribe = ctx.slots.subscribe("sidebar.footer.action", refresh);
|
|
8687
|
+
refresh();
|
|
8688
|
+
return () => {
|
|
8689
|
+
unsubscribe();
|
|
8690
|
+
remove?.();
|
|
8691
|
+
};
|
|
8692
|
+
});
|
|
8693
|
+
ctx.effect(() => {
|
|
8694
|
+
const onClick = (event) => {
|
|
8695
|
+
if (!(event.target instanceof Element) || !event.target.closest(".dcu-footer-actions [data-testid=\"billing-trigger\"],.dcu-footer-actions [data-testid=\"billing-rail-button\"]")) return;
|
|
8696
|
+
if (!ctx.slots.entriesOfSlot("settings.section").some((entry) => entry.options.id === "usage-statistics")) return;
|
|
8697
|
+
const seat = document.querySelector(".dcu-settings-seat");
|
|
8698
|
+
if (!seat?.querySelector("[data-dcu-settings-trigger]")) return;
|
|
8699
|
+
event.preventDefault();
|
|
8700
|
+
event.stopPropagation();
|
|
8701
|
+
openSettingsSection(seat, t("usage.title"));
|
|
8702
|
+
};
|
|
8703
|
+
document.addEventListener("click", onClick, true);
|
|
8704
|
+
return () => document.removeEventListener("click", onClick, true);
|
|
8705
|
+
}, "michengai-codex-ui: usage navigation");
|
|
8706
|
+
}
|
|
8707
|
+
//#endregion
|
|
8708
|
+
//#region src/client/settings-page-model.ts
|
|
8709
|
+
function settingsGroup(id) {
|
|
8710
|
+
if (/archive|about|^usage-statistics$/.test(id)) return "records";
|
|
8711
|
+
if (/^(general|appearance|theme|language|shortcuts|voice|account)$/.test(id)) return "personal";
|
|
8712
|
+
return "integrations";
|
|
8713
|
+
}
|
|
8714
|
+
function filterSettingsRows(rows, query) {
|
|
8715
|
+
const needle = query.trim().toLocaleLowerCase();
|
|
8716
|
+
return needle === "" ? rows : rows.filter((row) => `${row.label} ${row.id}`.toLocaleLowerCase().includes(needle));
|
|
8717
|
+
}
|
|
8718
|
+
function generalItemGroup(id) {
|
|
8719
|
+
if (/permission|approval|sandbox/.test(id)) return "permissions";
|
|
8720
|
+
if (/composer|font|conversation|chat|enter/.test(id)) return "editor";
|
|
8721
|
+
return "general";
|
|
8722
|
+
}
|
|
8723
|
+
//#endregion
|
|
8724
|
+
//#region src/client/settings-page-styles.ts
|
|
8725
|
+
/** Codex 设置页的局部 tokens 与布局,不覆盖宿主其他弹窗。 */
|
|
8726
|
+
const settingsPageStyles = `
|
|
8727
|
+
.dcu-settings-page{--sp-bg:#fff;--sp-nav:var(--dcu-sidebar-background,#eef7f5);--sp-card:#fafafa;--sp-border:#e5e5e5;--sp-text:#303030;--sp-muted:#737373;--sp-hover:#e9e9e9;--sp-active:#e4e4e4;position:fixed;inset:0;z-index:1000;display:grid;grid-template-columns:clamp(240px,var(--dcu-sidebar-expanded-width,275px),min(520px,calc(100vw - 320px))) minmax(0,1fr);background:var(--sp-bg);color:var(--sp-text);font:14px/1.5 var(--dcu-font,system-ui);text-align:left;isolation:isolate}
|
|
8728
|
+
body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:var(--dcu-sidebar-background,#1d2120);--sp-card:#232323;--sp-border:#333;--sp-text:#dedede;--sp-muted:#a1a1a1;--sp-hover:#292c2b;--sp-active:#303332;color-scheme:dark}
|
|
8729
|
+
.dcu-settings-page *{box-sizing:border-box}
|
|
8730
|
+
.dcu-settings-page button,.dcu-settings-page input{font:inherit}
|
|
8731
|
+
.dcu-settings-page button{cursor:pointer}
|
|
8732
|
+
.dcu-settings-page :focus-visible{outline:2px solid #459cff;outline-offset:3px}
|
|
8733
|
+
.dcu-settings-nav{--sp-text:var(--dcu-sidebar-navigation,#4e5253);--sp-muted:var(--dcu-sidebar-secondary,#676b6c);--sp-hover:var(--dcu-sidebar-hover,#dfe8e5);--sp-active:var(--dcu-sidebar-hover,#dfe8e5);--sp-border:var(--dcu-sidebar-border,rgba(37,46,41,.10));display:flex;flex-direction:column;min-height:0;padding:18px 8px;background:var(--sp-nav);box-shadow:inset -1px 0 var(--sp-border);overflow-y:auto}
|
|
8734
|
+
body[data-ds-dark-theme] .dcu-settings-nav{--sp-text:var(--dcu-sidebar-navigation,#b9bab9);--sp-muted:var(--dcu-sidebar-secondary,#909191);--sp-hover:var(--dcu-sidebar-hover,#303432);--sp-active:var(--dcu-sidebar-hover,#303432);--sp-border:var(--dcu-sidebar-border,rgba(255,255,255,.08))}
|
|
8735
|
+
.dcu-settings-back{display:flex;align-items:center;flex-shrink:0;gap:8px;width:100%;height:30px;padding:5px 8px;border:0;border-radius:10px;background:transparent;color:var(--sp-text);text-align:left}
|
|
8736
|
+
.dcu-settings-back:hover,.dcu-settings-link:hover{background:var(--sp-hover)}
|
|
8737
|
+
.dcu-settings-search{display:flex;align-items:center;gap:8px;padding:5px 9px;margin:12px 0 18px;background:var(--sp-hover);border:1px solid transparent;border-radius:8px;color:var(--sp-muted)}
|
|
8738
|
+
.dcu-settings-search:focus-within{border-color:#459cff}
|
|
8739
|
+
.dcu-settings-search input{width:100%;min-width:0;border:0;background:transparent;color:var(--sp-text);outline:none;font-size:13px}
|
|
8740
|
+
.dcu-settings-search input[type=search]{appearance:none;padding:0;border-radius:0;box-shadow:none;line-height:20px}
|
|
8741
|
+
.dcu-settings-search input:focus,.dcu-settings-search input:focus-visible{outline:none;box-shadow:none}
|
|
8742
|
+
.dcu-settings-search input::placeholder{color:var(--sp-muted)}
|
|
8743
|
+
.dcu-settings-group{flex-shrink:0;margin:0 0 16px}
|
|
8744
|
+
.dcu-settings-group-label{margin:0 8px 4px;color:var(--sp-muted);font-size:12px;font-weight:500}
|
|
8745
|
+
.dcu-settings-link{display:flex;align-items:center;gap:8px;height:30px;min-height:30px;min-width:0;width:100%;padding:5px 8px;border:0;border-radius:10px;overflow:hidden;background:transparent;color:var(--sp-text);text-align:left;font-size:14px!important}
|
|
8746
|
+
/* Codex Desktop SidebarItem / SidebarSection:30px 行高、1px 行距、内收焦点圈。 */
|
|
8747
|
+
.dcu-settings-link+.dcu-settings-link{margin-top:1px}
|
|
8748
|
+
.dcu-settings-back:focus-visible,.dcu-settings-link:focus-visible{outline-offset:-2px}
|
|
8749
|
+
@supports(corner-shape:superellipse(1.5)){.dcu-settings-back,.dcu-settings-link{border-radius:12.5px;corner-shape:superellipse(1.5)}}
|
|
8750
|
+
.dcu-settings-link[aria-current=page]{background:var(--sp-active)}
|
|
8751
|
+
.dcu-settings-link svg{flex:none;color:var(--dcu-sidebar-icon,var(--sp-text));opacity:1}
|
|
8752
|
+
.dcu-settings-link span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
8753
|
+
.dcu-settings-empty{padding:8px;color:var(--sp-muted);font-size:13px}
|
|
8754
|
+
.dcu-settings-main{min-width:0;min-height:0;overflow:auto;overscroll-behavior:contain;background:var(--sp-bg);scrollbar-width:thin;scrollbar-color:var(--sp-border) transparent}
|
|
8755
|
+
.dcu-settings-inner{width:min(100%,864px);margin:0 auto;padding:48px 48px}
|
|
8756
|
+
.dcu-settings-heading{display:flex;align-items:center;justify-content:space-between;gap:24px;margin-bottom:24px}
|
|
8757
|
+
.dcu-settings-heading h1,.dcu-settings-inner:is([data-settings-section=models],[data-settings-section=plugins],[data-settings-section=agent-presets]) [class$="_section"]>h2:is([class$="_title"],[class$="_heading"]){margin:0;font-size:24px;line-height:32px;font-weight:600;letter-spacing:-.4px}
|
|
8758
|
+
.dcu-settings-inner:is([data-settings-section=models],[data-settings-section=plugins],[data-settings-section=agent-presets]) [class$="_section"]>p[class$="_intro"]{margin:0;font-size:14px;line-height:22px}
|
|
8759
|
+
.dcu-settings-heading[data-own-title=false]{justify-content:flex-end;margin-bottom:16px}
|
|
8760
|
+
.dcu-settings-heading:not(:has(h1,button,a,[role=button])){display:none}
|
|
8761
|
+
.dcu-settings-actions{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end;color:var(--sp-muted)}
|
|
8762
|
+
.dcu-settings-actions button{font-size:12px}
|
|
8763
|
+
.dcu-settings-general-group{margin-bottom:44px}
|
|
8764
|
+
.dcu-settings-general-group h2{margin:0 0 16px;font-size:14px;font-weight:600;color:var(--sp-text)}
|
|
8765
|
+
.dcu-settings-card{border:1px solid var(--sp-border);border-radius:16px;background:var(--sp-card);padding:0 16px;overflow:hidden}
|
|
8766
|
+
.dcu-settings-row+.dcu-settings-row{border-top:1px solid var(--sp-border)}
|
|
8767
|
+
.dcu-settings-row>[data-slot]{display:contents}
|
|
8768
|
+
.dcu-settings-row>[data-slot]>*{padding:12px 0!important;border-bottom:0!important;margin:0!important;min-width:0}
|
|
8769
|
+
.dcu-settings-row button{font-size:13px;border-radius:8px}
|
|
8770
|
+
.dcu-settings-row input{max-width:100%}
|
|
8771
|
+
.dcu-settings-document{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:16px 0;font-size:14px;line-height:20px}
|
|
8772
|
+
.dcu-settings-document-copy{min-width:0}
|
|
8773
|
+
.dcu-settings-document p{margin:4px 0 0;font-size:12px;color:var(--sp-muted);overflow-wrap:anywhere}
|
|
8774
|
+
.dcu-settings-document button{flex:none;min-height:36px;padding:8px 16px;border:0;border-radius:8px;background:var(--sp-hover);color:var(--sp-text);font:inherit;font-size:13px;cursor:pointer;transition:background .15s}
|
|
8775
|
+
.dcu-settings-document button:hover:not(:disabled){background:color-mix(in srgb,var(--sp-text) 14%,transparent)}
|
|
8776
|
+
.dcu-settings-document button:focus-visible{outline:2px solid var(--sp-muted);outline-offset:3px}
|
|
8777
|
+
.dcu-settings-document button:disabled{opacity:.55;cursor:wait}
|
|
8778
|
+
.dcu-settings-trigger{appearance:none;box-sizing:border-box;display:flex;align-items:center;border:0;border-radius:8px;background:transparent;color:var(--dcu-sidebar-navigation,inherit);height:36px;min-height:36px;padding:0 4px;width:100%;font:400 14px/20px var(--dcu-font,system-ui);text-align:left;cursor:pointer;transition:background-color 160ms ease,color 160ms ease,transform 120ms ease}
|
|
8779
|
+
.dcu-settings-trigger-content{display:grid;grid-template-columns:20px minmax(0,1fr);column-gap:8px;align-items:center;width:100%;min-width:0}
|
|
8780
|
+
.dcu-settings-trigger-content svg{display:block;width:16px;height:16px;color:var(--dcu-sidebar-icon,currentColor);transition:transform 220ms cubic-bezier(.16,1,.3,1)}
|
|
8781
|
+
.dcu-settings-trigger:hover{background:var(--dcu-sidebar-hover,rgba(127,127,127,.12));color:var(--dcu-sidebar-primary,inherit)}
|
|
8782
|
+
.dcu-settings-trigger:hover svg{transform:rotate(18deg)}
|
|
8783
|
+
.dcu-settings-trigger:active{transform:scale(.98)}
|
|
8784
|
+
.dcu-settings-trigger:focus-visible{outline:2px solid #459cff;outline-offset:2px;background:var(--dcu-sidebar-hover,rgba(127,127,127,.12))}
|
|
8785
|
+
.dcu-settings-trigger[data-wide=false]{justify-content:center;width:36px;padding:0!important}
|
|
8786
|
+
.dcu-settings-trigger[data-wide=false] .dcu-settings-trigger-content{grid-template-columns:16px;justify-content:center}
|
|
8787
|
+
.dcu-settings-page{animation:dcu-settings-enter 180ms ease-out}
|
|
8788
|
+
.dcu-settings-nav{animation:dcu-settings-nav-enter 220ms cubic-bezier(.16,1,.3,1)}
|
|
8789
|
+
.dcu-settings-inner{animation:dcu-settings-content-enter 240ms cubic-bezier(.16,1,.3,1)}
|
|
8790
|
+
.dcu-settings-back,.dcu-settings-link{transition:background-color 160ms ease,color 160ms ease}
|
|
8791
|
+
@keyframes dcu-settings-enter{from{opacity:0}to{opacity:1}}
|
|
8792
|
+
@keyframes dcu-settings-nav-enter{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}
|
|
8793
|
+
@keyframes dcu-settings-content-enter{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
|
|
8794
|
+
/* 只有 Desktop 明确提供系统背景材质时才贯通透明层,普通浏览器保持实色。 */
|
|
8795
|
+
html[data-dsh-native-backdrop=mica]:has(.dcu-root),html[data-dsh-native-backdrop=mica]:has(.dcu-root) body,html[data-dsh-native-backdrop=mica] #root,html[data-dsh-native-backdrop=mica] #root>[data-slot=root],html[data-dsh-native-backdrop=mica] #root>[data-slot=root]>div{background:transparent!important}
|
|
8796
|
+
html[data-dsh-native-backdrop=mica] #root>[data-slot=root]>div>div:has(>[data-slot=sidebar]){background:transparent!important}
|
|
8797
|
+
html[data-dsh-native-backdrop=mica] #root :is([class$="_centerCol"],[class$="_detailsCol"]){background:var(--dsw-alias-bg-base,#fff)}
|
|
8798
|
+
html[data-dsh-native-backdrop=mica] :is(.dcu-root,.dcu-settings-nav){background:rgba(255,255,255,.18)}
|
|
8799
|
+
html[data-dsh-native-backdrop=mica] body[data-ds-dark-theme] :is(.dcu-root,.dcu-settings-nav){background:rgba(20,23,22,.18)}
|
|
8800
|
+
html[data-dsh-native-backdrop=mica] .dcu-root:has(.dcu-settings-page) [inert]{visibility:hidden}
|
|
8801
|
+
html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-backdrop=mica] .dcu-root:has(.dcu-settings-page){background:transparent}
|
|
8802
|
+
|
|
8803
|
+
.dcu-settings-inner:has(.dcu-usage-section){width:100%;height:100%;max-width:1280px;display:flex;flex-direction:column;padding-bottom:0}
|
|
8804
|
+
.dcu-settings-inner:has(.dcu-usage-section)>.dcu-settings-heading{display:none}
|
|
8805
|
+
.dcu-settings-inner:has(.dcu-usage-section)>[data-slot="settings.section"]{display:flex;flex:1;min-height:0;flex-direction:column}
|
|
8806
|
+
.dcu-usage-section{display:flex;flex-direction:column;flex:1;min-height:0;gap:16px}
|
|
8807
|
+
.dcu-usage-section h1{font-size:24px;font-weight:500;margin:0}
|
|
8808
|
+
.dcu-usage-section p{color:var(--sp-muted)}
|
|
8809
|
+
.dcu-usage-stage{position:relative;flex:1;min-height:420px;background:var(--sp-bg)}
|
|
8810
|
+
.dcu-usage-loading{position:absolute;inset:0;display:grid;place-items:center;margin:0}
|
|
8811
|
+
.dcu-usage-frame{position:absolute;inset:0;display:block;width:100%;height:100%;border:0;background:var(--sp-bg)}
|
|
8812
|
+
@media(prefers-reduced-motion:reduce){.dcu-settings-trigger,.dcu-settings-trigger-content svg,.dcu-settings-back,.dcu-settings-link{transition:none}.dcu-settings-trigger:hover svg,.dcu-settings-trigger:active{transform:none}.dcu-settings-page,.dcu-settings-nav,.dcu-settings-inner{animation:none}}
|
|
8813
|
+
.dcu-settings-page [data-slot="settings.section"]{min-width:0}
|
|
8814
|
+
.dcu-settings-inner:has(.dcu-connector-frame){height:100%;display:flex;flex-direction:column}
|
|
8815
|
+
.dcu-settings-inner:has(.dcu-connector-frame)>.dcu-settings-heading{flex:none}
|
|
8816
|
+
.dcu-settings-page .dcu-connectors:has(>.dcu-connector-frame){display:flex;flex-direction:column;flex:1 1 0;min-height:0}
|
|
8817
|
+
.dcu-settings-page .dcu-connector-frame{flex:1 1 0;min-height:0;height:100%}
|
|
8818
|
+
|
|
8819
|
+
@media(max-width:900px){.dcu-settings-inner{padding:32px 28px}.dcu-settings-heading{align-items:flex-start;flex-direction:column;gap:12px}}
|
|
8820
|
+
@media(max-width:600px){.dcu-settings-page{grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr)}.dcu-settings-nav{padding:8px 12px;max-height:220px;border-right:0;border-bottom:1px solid var(--sp-border)}.dcu-settings-search{margin:6px 0}.dcu-settings-groups{display:flex;gap:8px;overflow-x:auto;flex:none}.dcu-settings-group{display:flex;gap:4px;margin:0;flex:none}.dcu-settings-group-label{display:none}.dcu-settings-link{width:auto;min-height:40px;flex:none}.dcu-settings-link+.dcu-settings-link{margin-top:0}.dcu-settings-inner{padding:32px 16px}.dcu-settings-heading{margin-bottom:28px}.dcu-settings-heading h1,.dcu-settings-inner:is([data-settings-section=models],[data-settings-section=plugins],[data-settings-section=agent-presets]) [class$="_section"]>h2:is([class$="_title"],[class$="_heading"]){font-size:22px}.dcu-settings-card{padding:0 12px}.dcu-settings-row>[data-slot]>*{flex-wrap:wrap;gap:12px!important}.dcu-settings-general-group{margin-bottom:32px}}
|
|
8821
|
+
`;
|
|
8822
|
+
//#endregion
|
|
8823
|
+
//#region src/client/settings-focus.ts
|
|
8824
|
+
/** 设置页与宿主浮层共享的可交互判断,忽略隐藏及已被隔离的对话框。 */
|
|
8825
|
+
function settingsElementAvailable(element) {
|
|
8826
|
+
for (let node = element; node !== null; node = node.parentElement) {
|
|
8827
|
+
const style = getComputedStyle(node);
|
|
8828
|
+
if (node.inert || node.hidden || node.getAttribute("aria-hidden") === "true" || style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") return false;
|
|
7355
8829
|
}
|
|
7356
|
-
const svg = button.querySelector("svg");
|
|
7357
|
-
if (svg === null) return changed;
|
|
7358
|
-
if (svg.getAttribute("data-dcu-nav-icon") === id) return changed;
|
|
7359
|
-
svg.setAttribute("data-dcu-nav-icon", id);
|
|
7360
|
-
svg.setAttribute("viewBox", id === "archive" ? "0 0 20 20" : id === "about" ? "0 0 14 14" : "0 0 16 16");
|
|
7361
|
-
svg.setAttribute("fill", "none");
|
|
7362
|
-
svg.innerHTML = SETTINGS_NAV_ICON_HTML[id];
|
|
7363
8830
|
return true;
|
|
7364
8831
|
}
|
|
7365
|
-
function
|
|
7366
|
-
|
|
7367
|
-
for (const button of root.querySelectorAll("[role=\"dialog\"] nav button")) if (applySettingsNavIcon(button)) changed += 1;
|
|
7368
|
-
return changed;
|
|
8832
|
+
function settingsOverlays(selector = "[role=\"dialog\"],[role=\"alertdialog\"],[role=\"menu\"],[role=\"listbox\"]") {
|
|
8833
|
+
return [...document.querySelectorAll(selector)].filter(settingsElementAvailable);
|
|
7369
8834
|
}
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
8835
|
+
//#endregion
|
|
8836
|
+
//#region src/client/CodexSettingsPage.tsx
|
|
8837
|
+
const groupLabels = {
|
|
8838
|
+
personal: "settings.personal",
|
|
8839
|
+
integrations: "settings.integrations",
|
|
8840
|
+
records: "settings.records",
|
|
8841
|
+
permissions: "settings.permissions",
|
|
8842
|
+
general: "settings.general",
|
|
8843
|
+
editor: "settings.editor"
|
|
8844
|
+
};
|
|
8845
|
+
function sectionIcon(id) {
|
|
8846
|
+
if (id === "usage-statistics") return ChartColumn;
|
|
8847
|
+
if (id === "market" || id === "plugin-marketplace") return Store;
|
|
8848
|
+
if (id === "better-sidebar" || id === "sidebar-cards") return PanelRight;
|
|
8849
|
+
if (/model/.test(id)) return Cpu;
|
|
8850
|
+
if (/archive/.test(id)) return Archive;
|
|
8851
|
+
if (/about/.test(id)) return CircleQuestionMark;
|
|
8852
|
+
if (/expert|agency/.test(id)) return User;
|
|
8853
|
+
if (/skill/.test(id)) return Sparkles;
|
|
8854
|
+
if (/connector|mcp/.test(id)) return Link;
|
|
8855
|
+
if (/schedule|automation/.test(id)) return Clock;
|
|
8856
|
+
if (/im|assistant/.test(id)) return MessageSquare;
|
|
8857
|
+
if (id === "general") return Settings;
|
|
8858
|
+
if (/plugin/.test(id)) return SlidersHorizontal;
|
|
8859
|
+
return Box;
|
|
8860
|
+
}
|
|
8861
|
+
/** 独立设置视图复用原始 section/close 合约,退出时保留底层会话与输入状态。 */
|
|
8862
|
+
function CodexSettingsPage({ wide, sections, onboarding, connectionState, reconnect, useSessions, renderSlot, t }) {
|
|
8863
|
+
const rows = (0, react.useSyncExternalStore)(sections.subscribe, sections.getSnapshot);
|
|
8864
|
+
const steps = (0, react.useSyncExternalStore)(onboarding.subscribe, onboarding.getSnapshot);
|
|
8865
|
+
const connection = (0, react.useSyncExternalStore)(connectionState.subscribe, connectionState.getSnapshot);
|
|
8866
|
+
const onboardingActive = useSessions((state) => state.phase === "ready" && (state.current === void 0 || state.byId[state.current]?.blank === true));
|
|
8867
|
+
const [completed, setCompleted] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
8868
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
8869
|
+
const [activeId, setActiveId] = (0, react.useState)("general");
|
|
8870
|
+
const [query, setQuery] = (0, react.useState)("");
|
|
8871
|
+
const [recovered, setRecovered] = (0, react.useState)(false);
|
|
8872
|
+
const previousConnection = (0, react.useRef)(connection);
|
|
8873
|
+
const trigger = (0, react.useRef)(null);
|
|
8874
|
+
const page = (0, react.useRef)(null);
|
|
8875
|
+
const back = (0, react.useRef)(null);
|
|
8876
|
+
const onboardingRoot = (0, react.useRef)(null);
|
|
8877
|
+
const main = (0, react.useRef)(null);
|
|
8878
|
+
const wasOpen = (0, react.useRef)(false);
|
|
8879
|
+
const exitAnimation = (0, react.useRef)(null);
|
|
8880
|
+
const active = rows.find((row) => row.id === activeId) ?? rows[0];
|
|
8881
|
+
const step = onboardingActive ? steps.find((item) => !completed.has(item.id)) : void 0;
|
|
8882
|
+
const close = (0, react.useCallback)(() => {
|
|
8883
|
+
if (exitAnimation.current !== null) return;
|
|
8884
|
+
const finish = () => {
|
|
8885
|
+
exitAnimation.current = null;
|
|
8886
|
+
setOpen(false);
|
|
8887
|
+
setQuery("");
|
|
8888
|
+
};
|
|
8889
|
+
const element = page.current;
|
|
8890
|
+
if (element?.animate === void 0 || window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
|
|
8891
|
+
finish();
|
|
8892
|
+
return;
|
|
7385
8893
|
}
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
frame = void 0;
|
|
7391
|
-
apply();
|
|
8894
|
+
const animation = element.animate([{ opacity: getComputedStyle(element).opacity }, { opacity: 0 }], {
|
|
8895
|
+
duration: 140,
|
|
8896
|
+
easing: "ease-out",
|
|
8897
|
+
fill: "forwards"
|
|
7392
8898
|
});
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
8899
|
+
exitAnimation.current = animation;
|
|
8900
|
+
animation.onfinish = finish;
|
|
8901
|
+
}, []);
|
|
8902
|
+
const openSection = (0, react.useCallback)((id) => {
|
|
8903
|
+
exitAnimation.current?.cancel();
|
|
8904
|
+
exitAnimation.current = null;
|
|
8905
|
+
setActiveId(id);
|
|
8906
|
+
setOpen(true);
|
|
8907
|
+
}, []);
|
|
8908
|
+
(0, react.useEffect)(() => {
|
|
8909
|
+
const element = trigger.current;
|
|
8910
|
+
const navigate = (event) => {
|
|
8911
|
+
const labels = event.detail?.labels;
|
|
8912
|
+
if (!Array.isArray(labels)) return;
|
|
8913
|
+
const row = labels.flatMap((label) => rows.filter((item) => (item.id === "general" ? t("settings.general") : item.label) === label))[0];
|
|
8914
|
+
if (!row) return;
|
|
8915
|
+
event.preventDefault();
|
|
8916
|
+
setQuery("");
|
|
8917
|
+
openSection(row.id);
|
|
8918
|
+
};
|
|
8919
|
+
element?.addEventListener(SETTINGS_OPEN_SECTION_EVENT, navigate);
|
|
8920
|
+
return () => element?.removeEventListener(SETTINGS_OPEN_SECTION_EVENT, navigate);
|
|
8921
|
+
}, [
|
|
8922
|
+
rows,
|
|
8923
|
+
t,
|
|
8924
|
+
openSection
|
|
8925
|
+
]);
|
|
8926
|
+
(0, react.useEffect)(() => () => {
|
|
8927
|
+
exitAnimation.current?.cancel();
|
|
8928
|
+
}, []);
|
|
8929
|
+
(0, react.useEffect)(() => {
|
|
8930
|
+
if (!onboardingActive) setCompleted(/* @__PURE__ */ new Set());
|
|
8931
|
+
}, [onboardingActive]);
|
|
8932
|
+
(0, react.useEffect)(() => {
|
|
8933
|
+
const previous = previousConnection.current;
|
|
8934
|
+
previousConnection.current = connection;
|
|
8935
|
+
setRecovered(connection === "connected" && (previous === "disconnected" || previous === "connecting"));
|
|
8936
|
+
if (connection !== "connected") return;
|
|
8937
|
+
const timer = window.setTimeout(() => {
|
|
8938
|
+
setRecovered(false);
|
|
8939
|
+
}, 3e3);
|
|
8940
|
+
return () => {
|
|
8941
|
+
window.clearTimeout(timer);
|
|
8942
|
+
};
|
|
8943
|
+
}, [connection]);
|
|
8944
|
+
(0, react.useEffect)(() => {
|
|
8945
|
+
if (wasOpen.current && !open) trigger.current?.focus();
|
|
8946
|
+
wasOpen.current = open;
|
|
8947
|
+
if (!open || page.current === null) return;
|
|
8948
|
+
if (settingsElementAvailable(page.current) && settingsOverlays().length === 0) back.current?.focus();
|
|
8949
|
+
const hidden = /* @__PURE__ */ new Map();
|
|
8950
|
+
const guideModals = step === void 0 ? [] : settingsOverlays("[role=\"dialog\"][aria-modal=\"true\"],[role=\"alertdialog\"][aria-modal=\"true\"]");
|
|
8951
|
+
const isolate = (element) => {
|
|
8952
|
+
if (element === onboardingRoot.current || guideModals.includes(element)) return;
|
|
8953
|
+
if (guideModals.some((modal) => element.contains(modal))) {
|
|
8954
|
+
for (const child of element.children) if (child instanceof HTMLElement && !/^(STYLE|SCRIPT|LINK)$/.test(child.tagName)) isolate(child);
|
|
8955
|
+
return;
|
|
7403
8956
|
}
|
|
8957
|
+
hidden.set(element, element.inert);
|
|
8958
|
+
element.inert = true;
|
|
8959
|
+
};
|
|
8960
|
+
let branch = page.current;
|
|
8961
|
+
while (branch.parentElement !== null) {
|
|
8962
|
+
for (const sibling of branch.parentElement.children) {
|
|
8963
|
+
if (!(sibling instanceof HTMLElement) || sibling === branch || /^(STYLE|SCRIPT|LINK)$/.test(sibling.tagName)) continue;
|
|
8964
|
+
isolate(sibling);
|
|
8965
|
+
}
|
|
8966
|
+
branch = branch.parentElement;
|
|
8967
|
+
if (branch === document.body) break;
|
|
7404
8968
|
}
|
|
7405
|
-
|
|
8969
|
+
const onKeyDown = (event) => {
|
|
8970
|
+
if (event.key === "Escape" && !event.defaultPrevented && settingsOverlays().length === 0) {
|
|
8971
|
+
event.preventDefault();
|
|
8972
|
+
close();
|
|
8973
|
+
}
|
|
8974
|
+
};
|
|
8975
|
+
const keepFocus = (event) => {
|
|
8976
|
+
const target = event.target;
|
|
8977
|
+
if (!(target instanceof Node) || page.current === null || !settingsElementAvailable(page.current)) return;
|
|
8978
|
+
if (page.current.contains(target) || onboardingRoot.current?.contains(target) || settingsOverlays().some((overlay) => overlay.contains(target))) return;
|
|
8979
|
+
back.current?.focus();
|
|
8980
|
+
};
|
|
8981
|
+
const wrapFocus = (event) => {
|
|
8982
|
+
if (event.key !== "Tab" || event.defaultPrevented || page.current === null || !settingsElementAvailable(page.current) || settingsOverlays().length > 0) return;
|
|
8983
|
+
const items = [page.current, onboardingRoot.current].filter((root) => root !== null).flatMap((root) => [...root.querySelectorAll("button,input,select,textarea,a[href],[tabindex]")]).filter((element) => element.tabIndex >= 0 && !element.matches(":disabled") && settingsElementAvailable(element));
|
|
8984
|
+
const next = event.shiftKey ? items.at(-1) : items[0];
|
|
8985
|
+
if (document.activeElement === (event.shiftKey ? items[0] : items.at(-1))) {
|
|
8986
|
+
event.preventDefault();
|
|
8987
|
+
next?.focus();
|
|
8988
|
+
}
|
|
8989
|
+
};
|
|
8990
|
+
document.addEventListener("keydown", onKeyDown, true);
|
|
8991
|
+
document.addEventListener("keydown", wrapFocus);
|
|
8992
|
+
document.addEventListener("focusin", keepFocus);
|
|
8993
|
+
return () => {
|
|
8994
|
+
document.removeEventListener("keydown", onKeyDown, true);
|
|
8995
|
+
document.removeEventListener("keydown", wrapFocus);
|
|
8996
|
+
document.removeEventListener("focusin", keepFocus);
|
|
8997
|
+
for (const [element, inert] of hidden) element.inert = inert;
|
|
8998
|
+
};
|
|
8999
|
+
}, [
|
|
9000
|
+
open,
|
|
9001
|
+
close,
|
|
9002
|
+
step?.id
|
|
9003
|
+
]);
|
|
9004
|
+
(0, react.useEffect)(() => {
|
|
9005
|
+
if (main.current !== null) main.current.scrollTop = 0;
|
|
9006
|
+
}, [active?.id]);
|
|
9007
|
+
const visible = filterSettingsRows(rows, query);
|
|
9008
|
+
const connectionIndicator = connection === "disconnected" ? "disconnected" : connection === "connecting" ? "connecting" : recovered ? "recovered" : void 0;
|
|
9009
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
9010
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: settingsPageStyles }),
|
|
9011
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
9012
|
+
ref: trigger,
|
|
9013
|
+
type: "button",
|
|
9014
|
+
className: "dcu-settings-trigger",
|
|
9015
|
+
"data-dcu-settings-trigger": true,
|
|
9016
|
+
"data-wide": wide,
|
|
9017
|
+
"aria-expanded": open,
|
|
9018
|
+
"aria-label": t("settings.title"),
|
|
9019
|
+
onClick: () => {
|
|
9020
|
+
openSection("general");
|
|
9021
|
+
},
|
|
9022
|
+
children: renderSlot("settings.trigger", { wide })
|
|
9023
|
+
}),
|
|
9024
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.ConnectionIndicator, {
|
|
9025
|
+
state: wide ? connectionIndicator : void 0,
|
|
9026
|
+
disconnectedLabel: t("settings.disconnected"),
|
|
9027
|
+
reconnectLabel: t("settings.reconnect"),
|
|
9028
|
+
connectingLabel: t("settings.connecting"),
|
|
9029
|
+
recoveredLabel: t("settings.recovered"),
|
|
9030
|
+
reconnectActionLabel: t("settings.reconnect"),
|
|
9031
|
+
restartActionLabel: t("settings.reconnect"),
|
|
9032
|
+
onReconnect: reconnect
|
|
9033
|
+
}),
|
|
9034
|
+
open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9035
|
+
ref: page,
|
|
9036
|
+
className: "dcu-settings-page",
|
|
9037
|
+
"data-dcu-settings-page": true,
|
|
9038
|
+
role: "region",
|
|
9039
|
+
"aria-label": t("settings.title"),
|
|
9040
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
|
|
9041
|
+
className: "dcu-settings-nav",
|
|
9042
|
+
"aria-label": t("settings.title"),
|
|
9043
|
+
children: [
|
|
9044
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
9045
|
+
ref: back,
|
|
9046
|
+
type: "button",
|
|
9047
|
+
className: "dcu-settings-back",
|
|
9048
|
+
onClick: close,
|
|
9049
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArrowLeft, { size: 16 }), renderSlot("settings.close", {}) ?? t("settings.back")]
|
|
9050
|
+
}),
|
|
9051
|
+
renderSlot("settings.header", {}),
|
|
9052
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
9053
|
+
className: "dcu-settings-search",
|
|
9054
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Search, {
|
|
9055
|
+
size: 15,
|
|
9056
|
+
"aria-hidden": "true"
|
|
9057
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
9058
|
+
type: "search",
|
|
9059
|
+
value: query,
|
|
9060
|
+
"aria-label": t("settings.search"),
|
|
9061
|
+
placeholder: t("settings.search"),
|
|
9062
|
+
onChange: (event) => {
|
|
9063
|
+
setQuery(event.target.value);
|
|
9064
|
+
}
|
|
9065
|
+
})]
|
|
9066
|
+
}),
|
|
9067
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9068
|
+
className: "dcu-settings-groups",
|
|
9069
|
+
children: [
|
|
9070
|
+
"personal",
|
|
9071
|
+
"integrations",
|
|
9072
|
+
"records"
|
|
9073
|
+
].map((group) => {
|
|
9074
|
+
const entries = visible.filter((row) => settingsGroup(row.id) === group);
|
|
9075
|
+
return entries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
9076
|
+
className: "dcu-settings-group",
|
|
9077
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
9078
|
+
className: "dcu-settings-group-label",
|
|
9079
|
+
children: t(groupLabels[group])
|
|
9080
|
+
}), entries.map((row) => {
|
|
9081
|
+
const Icon = sectionIcon(row.id);
|
|
9082
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
9083
|
+
type: "button",
|
|
9084
|
+
className: "dcu-settings-link",
|
|
9085
|
+
"aria-current": row.id === active?.id ? "page" : void 0,
|
|
9086
|
+
onClick: () => {
|
|
9087
|
+
setActiveId(row.id);
|
|
9088
|
+
},
|
|
9089
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
9090
|
+
size: 16,
|
|
9091
|
+
strokeWidth: 1.6,
|
|
9092
|
+
"aria-hidden": "true"
|
|
9093
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: row.id === "general" ? t("settings.general") : row.label })]
|
|
9094
|
+
}, row.id);
|
|
9095
|
+
})]
|
|
9096
|
+
}, group);
|
|
9097
|
+
})
|
|
9098
|
+
}),
|
|
9099
|
+
visible.length > 0 && !visible.some((row) => row.id === active?.id) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
9100
|
+
className: "dcu-settings-empty",
|
|
9101
|
+
role: "status",
|
|
9102
|
+
children: t("settings.filterHint")
|
|
9103
|
+
}),
|
|
9104
|
+
visible.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
9105
|
+
className: "dcu-settings-empty",
|
|
9106
|
+
role: "status",
|
|
9107
|
+
children: t("settings.noResults")
|
|
9108
|
+
})
|
|
9109
|
+
]
|
|
9110
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9111
|
+
ref: main,
|
|
9112
|
+
className: "dcu-settings-main",
|
|
9113
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9114
|
+
className: "dcu-settings-inner",
|
|
9115
|
+
"data-settings-section": active?.id,
|
|
9116
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
9117
|
+
className: "dcu-settings-heading",
|
|
9118
|
+
"data-own-title": active?.id === "general",
|
|
9119
|
+
children: [active?.id === "general" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: t("settings.general") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9120
|
+
className: "dcu-settings-actions",
|
|
9121
|
+
children: renderSlot("settings.action", {})
|
|
9122
|
+
})]
|
|
9123
|
+
}), active !== void 0 && renderSlot("settings.section", { close }, { only: active.id })]
|
|
9124
|
+
})
|
|
9125
|
+
})]
|
|
9126
|
+
}),
|
|
9127
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9128
|
+
ref: onboardingRoot,
|
|
9129
|
+
style: { display: "contents" },
|
|
9130
|
+
children: step !== void 0 && renderSlot("settings.onboarding", {
|
|
9131
|
+
stepId: step.id,
|
|
9132
|
+
complete: () => {
|
|
9133
|
+
setCompleted((previous) => /* @__PURE__ */ new Set([...previous, step.id]));
|
|
9134
|
+
},
|
|
9135
|
+
openSection
|
|
9136
|
+
}, { only: step.id })
|
|
9137
|
+
})
|
|
9138
|
+
] });
|
|
9139
|
+
}
|
|
9140
|
+
/** 每条偏好仍由原插件渲染和保存,只为公共条目添加可扩展的分组容器。 */
|
|
9141
|
+
function CodexGeneralSettings({ items, renderSlot, t }) {
|
|
9142
|
+
const rows = (0, react.useSyncExternalStore)(items.subscribe, items.getSnapshot);
|
|
9143
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9144
|
+
className: "dcu-settings-general",
|
|
9145
|
+
children: [[
|
|
9146
|
+
"permissions",
|
|
9147
|
+
"general",
|
|
9148
|
+
"editor"
|
|
9149
|
+
].map((group) => {
|
|
9150
|
+
const entries = rows.filter((row) => generalItemGroup(row.id) === group);
|
|
9151
|
+
return entries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
9152
|
+
className: "dcu-settings-general-group",
|
|
9153
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: t(groupLabels[group]) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9154
|
+
className: "dcu-settings-card",
|
|
9155
|
+
children: entries.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9156
|
+
className: "dcu-settings-row",
|
|
9157
|
+
"data-dcu-settings-item": row.id,
|
|
9158
|
+
children: renderSlot("settings.general.item", {}, { only: row.id })
|
|
9159
|
+
}, row.id))
|
|
9160
|
+
})]
|
|
9161
|
+
}, group);
|
|
9162
|
+
}), renderSlot("settings.general.footer", {})]
|
|
7406
9163
|
});
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
9164
|
+
}
|
|
9165
|
+
//#endregion
|
|
9166
|
+
//#region src/client/SettingsDocumentAction.tsx
|
|
9167
|
+
/** 通过宿主公开接口打开配置文件,沿用共享元数据和路径无关的操作。 */
|
|
9168
|
+
function SettingsDocumentAction({ describe, openDocument, t }) {
|
|
9169
|
+
const snapshot = (0, react.useSyncExternalStore)((listener) => describe.subscribe(listener), () => describe.getSnapshot());
|
|
9170
|
+
const busy = (0, react.useRef)(false);
|
|
9171
|
+
const [opening, setOpening] = (0, react.useState)(false);
|
|
9172
|
+
const [error, setError] = (0, react.useState)(false);
|
|
9173
|
+
(0, react.useEffect)(() => {
|
|
9174
|
+
let active = true;
|
|
9175
|
+
setError(false);
|
|
9176
|
+
describe.ensure().catch(() => {
|
|
9177
|
+
if (active) setError(true);
|
|
9178
|
+
});
|
|
9179
|
+
return () => {
|
|
9180
|
+
active = false;
|
|
9181
|
+
};
|
|
9182
|
+
}, [describe]);
|
|
9183
|
+
if (!snapshot.view?.hasDocument) return error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9184
|
+
role: "alert",
|
|
9185
|
+
children: t("settings.openDocumentError")
|
|
9186
|
+
}) : null;
|
|
9187
|
+
const open = async () => {
|
|
9188
|
+
if (busy.current) return;
|
|
9189
|
+
busy.current = true;
|
|
9190
|
+
setOpening(true);
|
|
9191
|
+
setError(false);
|
|
9192
|
+
try {
|
|
9193
|
+
setError(!(await openDocument()).ok);
|
|
9194
|
+
} catch {
|
|
9195
|
+
setError(true);
|
|
9196
|
+
} finally {
|
|
9197
|
+
busy.current = false;
|
|
9198
|
+
setOpening(false);
|
|
9199
|
+
}
|
|
9200
|
+
};
|
|
9201
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
9202
|
+
className: "dcu-settings-general-group",
|
|
9203
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: t("settings.advanced") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9204
|
+
className: "dcu-settings-card",
|
|
9205
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9206
|
+
className: "dcu-settings-document",
|
|
9207
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9208
|
+
className: "dcu-settings-document-copy",
|
|
9209
|
+
children: [
|
|
9210
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: t("settings.documentTitle") }),
|
|
9211
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("settings.documentDescription") }),
|
|
9212
|
+
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
9213
|
+
role: "alert",
|
|
9214
|
+
children: t("settings.openDocumentError")
|
|
9215
|
+
})
|
|
9216
|
+
]
|
|
9217
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
9218
|
+
type: "button",
|
|
9219
|
+
"aria-label": t("settings.openDocument"),
|
|
9220
|
+
"aria-busy": opening,
|
|
9221
|
+
disabled: opening,
|
|
9222
|
+
onClick: () => {
|
|
9223
|
+
open();
|
|
9224
|
+
},
|
|
9225
|
+
children: t(opening ? "settings.documentOpening" : "settings.documentOpen")
|
|
9226
|
+
})]
|
|
9227
|
+
})
|
|
9228
|
+
})]
|
|
7410
9229
|
});
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
9230
|
+
}
|
|
9231
|
+
//#endregion
|
|
9232
|
+
//#region src/client/settings-page-registration.ts
|
|
9233
|
+
/** 用公开插槽替换设置壳,保留宿主的设置写入、连接恢复和首次使用引导。 */
|
|
9234
|
+
function registerSettingsPage(ctx) {
|
|
9235
|
+
const children = [
|
|
9236
|
+
"settings.trigger",
|
|
9237
|
+
"settings.header",
|
|
9238
|
+
"settings.action",
|
|
9239
|
+
"settings.close",
|
|
9240
|
+
"settings.section",
|
|
9241
|
+
"settings.onboarding",
|
|
9242
|
+
"settings.general.item"
|
|
9243
|
+
];
|
|
9244
|
+
const occupied = () => ctx.slots.entriesOfSlot("sidebar.settings").length > 0 || children.some((name) => ctx.slots.snapshot(name).length > 0);
|
|
9245
|
+
const warn = () => console.warn("[michengai-codex-ui] 已存在设置外壳,保留宿主设置;独立设置页需要 bundle patch 停用 ui-settings-general。");
|
|
9246
|
+
if (occupied()) {
|
|
9247
|
+
warn();
|
|
9248
|
+
return;
|
|
9249
|
+
}
|
|
9250
|
+
let owned = false;
|
|
9251
|
+
const t = ctx.locale.bind(NS);
|
|
9252
|
+
const connection = ctx.get("connection");
|
|
9253
|
+
const source = (name) => {
|
|
9254
|
+
let revision = "";
|
|
9255
|
+
let cached = [];
|
|
9256
|
+
return {
|
|
9257
|
+
getSnapshot: () => {
|
|
9258
|
+
const next = `${ctx.slots.getVersion(name)}:${ctx.locale.getSnapshot().revision}`;
|
|
9259
|
+
if (revision !== next) {
|
|
9260
|
+
revision = next;
|
|
9261
|
+
cached = ctx.slots.entriesOfSlot(name).map((entry) => ({
|
|
9262
|
+
id: entry.options.id ?? "",
|
|
9263
|
+
order: entry.options.order ?? 0,
|
|
9264
|
+
label: (typeof entry.options.label === "function" ? entry.options.label() : entry.options.label) ?? ""
|
|
9265
|
+
})).sort((a, b) => a.order - b.order);
|
|
9266
|
+
}
|
|
9267
|
+
return cached;
|
|
9268
|
+
},
|
|
9269
|
+
subscribe: (listener) => {
|
|
9270
|
+
const offSlots = ctx.slots.subscribe(name, listener);
|
|
9271
|
+
const offLocale = ctx.locale.subscribe(listener);
|
|
9272
|
+
return () => {
|
|
9273
|
+
offSlots();
|
|
9274
|
+
offLocale();
|
|
9275
|
+
};
|
|
9276
|
+
}
|
|
9277
|
+
};
|
|
7414
9278
|
};
|
|
9279
|
+
const sections = source("settings.section");
|
|
9280
|
+
const onboarding = source("settings.onboarding");
|
|
9281
|
+
const items = source("settings.general.item");
|
|
9282
|
+
ctx.slots.inject("settings.trigger", () => !owned ? () => {} : ctx.slots.register({
|
|
9283
|
+
name: "settings.trigger",
|
|
9284
|
+
locale: NS
|
|
9285
|
+
}, ({ wide }) => (0, react.createElement)("span", { className: "dcu-settings-trigger-content" }, (0, react.createElement)(Settings, {
|
|
9286
|
+
size: 16,
|
|
9287
|
+
strokeWidth: 1.6
|
|
9288
|
+
}), wide ? (0, react.createElement)("span", null, t("settings.title")) : null)));
|
|
9289
|
+
ctx.slots.inject("settings.close", () => !owned ? () => {} : ctx.slots.register({
|
|
9290
|
+
name: "settings.close",
|
|
9291
|
+
locale: NS
|
|
9292
|
+
}, () => t("settings.back")));
|
|
9293
|
+
ctx.inject(["settingsScope", "remote.settings"], (settingsCtx) => {
|
|
9294
|
+
const remote = settingsCtx.get("remote");
|
|
9295
|
+
if (!remote.$host.isLoopback) return;
|
|
9296
|
+
const describe = settingsCtx.settingsScope.describe();
|
|
9297
|
+
settingsCtx.slots.inject("settings.general.footer", () => !owned ? () => {} : settingsCtx.slots.register({
|
|
9298
|
+
name: "settings.general.footer",
|
|
9299
|
+
id: "open-document",
|
|
9300
|
+
locale: NS,
|
|
9301
|
+
inject: () => ({
|
|
9302
|
+
describe,
|
|
9303
|
+
openDocument: () => remote.settings.openSettingsDocument()
|
|
9304
|
+
})
|
|
9305
|
+
}, SettingsDocumentAction));
|
|
9306
|
+
});
|
|
9307
|
+
ctx.slots.inject("sidebar.settings", () => {
|
|
9308
|
+
if (occupied()) {
|
|
9309
|
+
warn();
|
|
9310
|
+
return () => {};
|
|
9311
|
+
}
|
|
9312
|
+
owned = true;
|
|
9313
|
+
const remove = ctx.slots.register({
|
|
9314
|
+
name: "sidebar.settings",
|
|
9315
|
+
priority: -1,
|
|
9316
|
+
locale: NS,
|
|
9317
|
+
children: {
|
|
9318
|
+
"settings.trigger": {
|
|
9319
|
+
kind: "single",
|
|
9320
|
+
scope: "root"
|
|
9321
|
+
},
|
|
9322
|
+
"settings.header": {
|
|
9323
|
+
kind: "single",
|
|
9324
|
+
scope: "root"
|
|
9325
|
+
},
|
|
9326
|
+
"settings.action": {
|
|
9327
|
+
kind: "list",
|
|
9328
|
+
scope: "root"
|
|
9329
|
+
},
|
|
9330
|
+
"settings.close": {
|
|
9331
|
+
kind: "single",
|
|
9332
|
+
scope: "root"
|
|
9333
|
+
},
|
|
9334
|
+
"settings.section": {
|
|
9335
|
+
kind: "list",
|
|
9336
|
+
scope: "root"
|
|
9337
|
+
},
|
|
9338
|
+
"settings.onboarding": {
|
|
9339
|
+
kind: "list",
|
|
9340
|
+
scope: "root"
|
|
9341
|
+
}
|
|
9342
|
+
},
|
|
9343
|
+
inject: () => ({
|
|
9344
|
+
sections,
|
|
9345
|
+
onboarding,
|
|
9346
|
+
connectionState: connection.state,
|
|
9347
|
+
reconnect: () => {
|
|
9348
|
+
connection.reconnect();
|
|
9349
|
+
}
|
|
9350
|
+
})
|
|
9351
|
+
}, CodexSettingsPage);
|
|
9352
|
+
return () => {
|
|
9353
|
+
owned = false;
|
|
9354
|
+
remove();
|
|
9355
|
+
};
|
|
9356
|
+
});
|
|
9357
|
+
ctx.slots.inject("settings.section", () => !owned ? () => {} : ctx.slots.register({
|
|
9358
|
+
name: "settings.section",
|
|
9359
|
+
id: "general",
|
|
9360
|
+
priority: -1,
|
|
9361
|
+
order: 0,
|
|
9362
|
+
locale: NS,
|
|
9363
|
+
label: () => t("settings.general"),
|
|
9364
|
+
children: {
|
|
9365
|
+
"settings.general.item": {
|
|
9366
|
+
kind: "list",
|
|
9367
|
+
scope: "root"
|
|
9368
|
+
},
|
|
9369
|
+
"settings.general.footer": {
|
|
9370
|
+
kind: "list",
|
|
9371
|
+
scope: "root"
|
|
9372
|
+
}
|
|
9373
|
+
},
|
|
9374
|
+
inject: () => ({ items })
|
|
9375
|
+
}, CodexGeneralSettings));
|
|
7415
9376
|
}
|
|
7416
9377
|
//#endregion
|
|
7417
9378
|
//#region src/client/permission-labels.ts
|
|
@@ -7533,6 +9494,105 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
7533
9494
|
};
|
|
7534
9495
|
}
|
|
7535
9496
|
//#endregion
|
|
9497
|
+
//#region src/client/host-copy.ts
|
|
9498
|
+
const commands = {
|
|
9499
|
+
compact: ["Compact older conversation history", "host.command.compact"],
|
|
9500
|
+
export: ["Download this Session log as a ZIP archive", "host.command.export"],
|
|
9501
|
+
feedback: ["record feedback about this session", "host.command.feedback"],
|
|
9502
|
+
goal: ["set or view the goal for a long-running task", "host.command.goal"],
|
|
9503
|
+
permission: ["Switch the permission preset (sandbox mode + approval policy)", "host.command.permission"],
|
|
9504
|
+
plan: ["Enter or leave plan mode", "host.command.plan"]
|
|
9505
|
+
};
|
|
9506
|
+
const transcript = {
|
|
9507
|
+
Normal: "host.transcript.normal",
|
|
9508
|
+
Compact: "host.transcript.compact"
|
|
9509
|
+
};
|
|
9510
|
+
/** 只补译已核对的宿主控件文本;保留原 Text 节点、事件和业务状态。 */
|
|
9511
|
+
function observeHostCopy(locale, t) {
|
|
9512
|
+
const owned = /* @__PURE__ */ new Map();
|
|
9513
|
+
const replace = (element, original, key) => {
|
|
9514
|
+
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT);
|
|
9515
|
+
let node;
|
|
9516
|
+
while ((node = walker.nextNode()) !== null) {
|
|
9517
|
+
if (node.nodeValue?.trim() !== original) continue;
|
|
9518
|
+
const text = node;
|
|
9519
|
+
const rendered = text.data.replace(original, t(key));
|
|
9520
|
+
owned.set(text, {
|
|
9521
|
+
original: text.data,
|
|
9522
|
+
rendered,
|
|
9523
|
+
key
|
|
9524
|
+
});
|
|
9525
|
+
if (text.data !== rendered) text.data = rendered;
|
|
9526
|
+
}
|
|
9527
|
+
};
|
|
9528
|
+
const apply = () => {
|
|
9529
|
+
for (const [node, state] of owned) {
|
|
9530
|
+
if (!node.isConnected || node.data !== state.rendered) {
|
|
9531
|
+
owned.delete(node);
|
|
9532
|
+
continue;
|
|
9533
|
+
}
|
|
9534
|
+
const next = state.original.replace(state.original.trim(), t(state.key));
|
|
9535
|
+
if (node.data !== next) node.data = next;
|
|
9536
|
+
state.rendered = next;
|
|
9537
|
+
}
|
|
9538
|
+
const selector = document.querySelector("[data-dcu-settings-item=\"transcript-view\"] button[aria-haspopup=\"menu\"]");
|
|
9539
|
+
if (selector) {
|
|
9540
|
+
for (const [original, key] of Object.entries(transcript)) replace(selector, original, key);
|
|
9541
|
+
if (selector.getAttribute("aria-expanded") === "true") for (const menu of document.querySelectorAll("[role=\"menu\"]")) {
|
|
9542
|
+
const items = [...menu.querySelectorAll("[role=\"menuitem\"],[role=\"menuitemradio\"]")];
|
|
9543
|
+
const labels = items.map((item) => item.textContent?.trim());
|
|
9544
|
+
if (items.length !== 2 || !["Normal", t("host.transcript.normal")].some((label) => labels.includes(label)) || !["Compact", t("host.transcript.compact")].some((label) => labels.includes(label))) continue;
|
|
9545
|
+
for (const item of items) for (const [original, key] of Object.entries(transcript)) replace(item, original, key);
|
|
9546
|
+
}
|
|
9547
|
+
}
|
|
9548
|
+
for (const option of document.querySelectorAll("[data-trigger-menu] button[role=\"option\"]")) {
|
|
9549
|
+
const spans = [...option.children].filter((child) => child.tagName === "SPAN" && child.getAttribute("aria-hidden") !== "true");
|
|
9550
|
+
const name = spans[0]?.textContent?.trim();
|
|
9551
|
+
if (!name || !Object.hasOwn(commands, name) || !spans[1]) continue;
|
|
9552
|
+
const [original, key] = commands[name];
|
|
9553
|
+
replace(spans[1], original, key);
|
|
9554
|
+
}
|
|
9555
|
+
};
|
|
9556
|
+
const scope = "[data-trigger-menu],[data-dcu-settings-item=\"transcript-view\"],[role=\"menu\"]";
|
|
9557
|
+
const roots = /* @__PURE__ */ new Map();
|
|
9558
|
+
const discover = () => {
|
|
9559
|
+
for (const [element, observer] of roots) if (!element.isConnected) {
|
|
9560
|
+
observer.disconnect();
|
|
9561
|
+
roots.delete(element);
|
|
9562
|
+
}
|
|
9563
|
+
for (const element of document.querySelectorAll(scope)) {
|
|
9564
|
+
if (roots.has(element)) continue;
|
|
9565
|
+
const observer = new MutationObserver(apply);
|
|
9566
|
+
observer.observe(element, {
|
|
9567
|
+
subtree: true,
|
|
9568
|
+
childList: true,
|
|
9569
|
+
characterData: true,
|
|
9570
|
+
attributes: true,
|
|
9571
|
+
attributeFilter: ["aria-expanded"]
|
|
9572
|
+
});
|
|
9573
|
+
roots.set(element, observer);
|
|
9574
|
+
}
|
|
9575
|
+
apply();
|
|
9576
|
+
};
|
|
9577
|
+
const observer = new MutationObserver((records) => {
|
|
9578
|
+
if (records.some((record) => [...record.addedNodes, ...record.removedNodes].some((node) => node instanceof Element && (node.matches(scope) || node.querySelector(scope) !== null)))) discover();
|
|
9579
|
+
});
|
|
9580
|
+
discover();
|
|
9581
|
+
observer.observe(document.body, {
|
|
9582
|
+
subtree: true,
|
|
9583
|
+
childList: true
|
|
9584
|
+
});
|
|
9585
|
+
const unsubscribe = locale.subscribe(apply);
|
|
9586
|
+
return () => {
|
|
9587
|
+
observer.disconnect();
|
|
9588
|
+
roots.forEach((observer) => observer.disconnect());
|
|
9589
|
+
roots.clear();
|
|
9590
|
+
unsubscribe();
|
|
9591
|
+
for (const [node, state] of owned) if (node.data === state.rendered) node.data = state.original;
|
|
9592
|
+
owned.clear();
|
|
9593
|
+
};
|
|
9594
|
+
}
|
|
9595
|
+
//#endregion
|
|
7536
9596
|
//#region src/client/official-turn-navigator.ts
|
|
7537
9597
|
const OFFICIAL_TURN_NAVIGATOR_ATTRIBUTE = "data-dcu-official-turn-navigator";
|
|
7538
9598
|
const OFFICIAL_TURN_MARK_ATTRIBUTE = "data-dcu-official-turn-mark";
|
|
@@ -8140,6 +10200,42 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
8140
10200
|
}, InputHistoryHint));
|
|
8141
10201
|
}
|
|
8142
10202
|
//#endregion
|
|
10203
|
+
//#region src/client/new-conversation-draft.ts
|
|
10204
|
+
/** 跟随当前会话的原草稿状态,覆盖输入、粘贴、历史召回和任务预填。 */
|
|
10205
|
+
function createDraftPresenceSource(selection, resolve) {
|
|
10206
|
+
return {
|
|
10207
|
+
getSnapshot: () => (resolve()?.getSnapshot().draft.length ?? 0) > 0,
|
|
10208
|
+
subscribe: (listener) => {
|
|
10209
|
+
let current;
|
|
10210
|
+
let offInput = () => {};
|
|
10211
|
+
const bind = () => {
|
|
10212
|
+
const next = resolve();
|
|
10213
|
+
if (next !== current) {
|
|
10214
|
+
offInput();
|
|
10215
|
+
current = next;
|
|
10216
|
+
offInput = next?.subscribe(listener) ?? (() => {});
|
|
10217
|
+
}
|
|
10218
|
+
listener();
|
|
10219
|
+
};
|
|
10220
|
+
const offSelection = selection.subscribe(bind);
|
|
10221
|
+
bind();
|
|
10222
|
+
return () => {
|
|
10223
|
+
offSelection();
|
|
10224
|
+
offInput();
|
|
10225
|
+
};
|
|
10226
|
+
}
|
|
10227
|
+
};
|
|
10228
|
+
}
|
|
10229
|
+
/** 任务建议只能填入空闲且空白的草稿,不覆盖附件、提及或正在提交的内容。 */
|
|
10230
|
+
function prefillNewConversation(input, text) {
|
|
10231
|
+
if (input === void 0) return "workspace";
|
|
10232
|
+
const state = input.state.getSnapshot();
|
|
10233
|
+
if (state.phase !== "plain") return "busy";
|
|
10234
|
+
if (state.draft.trim() !== "" || state.imageIds.length > 0 || state.occurrences.length > 0) return "draft";
|
|
10235
|
+
input.setDraft(text);
|
|
10236
|
+
return "ready";
|
|
10237
|
+
}
|
|
10238
|
+
//#endregion
|
|
8143
10239
|
//#region src/client/index.ts
|
|
8144
10240
|
const inject = [
|
|
8145
10241
|
"slots",
|
|
@@ -8177,19 +10273,34 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
8177
10273
|
}
|
|
8178
10274
|
/** 替换 DSH 的官方 sidebar 插槽,不修改 DSH 源码或会话数据。 */
|
|
8179
10275
|
function apply(ctx) {
|
|
10276
|
+
const widthStorage = browserStorage();
|
|
10277
|
+
if (widthStorage) initializeComposerWidth(widthStorage);
|
|
8180
10278
|
ctx.effect(() => ctx.locale.register(NS, {
|
|
8181
10279
|
zh,
|
|
8182
10280
|
en
|
|
8183
10281
|
}), "michengai-codex-ui: dictionaries");
|
|
8184
10282
|
const t = ctx.locale.bind(NS);
|
|
10283
|
+
ctx.effect(() => observeHeroWidthHandles(t("home.resizeInput")), "michengai-codex-ui: hero width handles");
|
|
8185
10284
|
registerInputHistory(ctx);
|
|
10285
|
+
registerSettingsPage(ctx);
|
|
10286
|
+
registerUsageStatistics(ctx);
|
|
8186
10287
|
const connection = ctx.get("connection");
|
|
8187
10288
|
const openPath = (path) => openPathInHost(connection, path);
|
|
8188
10289
|
ctx.effect(() => observeSlimSidebar(), "michengai-codex-ui: slim sidebar");
|
|
8189
10290
|
ctx.effect(() => observeSettingsNavIcons(), "michengai-codex-ui: settings nav icons");
|
|
8190
10291
|
ctx.effect(() => observePermissionLabels(ctx.locale), "michengai-codex-ui: permission labels");
|
|
10292
|
+
ctx.effect(() => observeComposerToolMenus({
|
|
10293
|
+
search: t("home.projectSearch"),
|
|
10294
|
+
empty: t("home.projectEmpty")
|
|
10295
|
+
}), "michengai-codex-ui: composer tool menus");
|
|
10296
|
+
ctx.effect(() => observeHostCopy(ctx.locale, t), "michengai-codex-ui: host copy");
|
|
8191
10297
|
ctx.effect(() => observeConversationHeader(), "michengai-codex-ui: conversation header");
|
|
8192
10298
|
ctx.effect(() => observeOfficialTurnNavigators(), "michengai-codex-ui: official turn navigator");
|
|
10299
|
+
const newConversationDraft = createDraftPresenceSource(ctx.sessions.list, () => {
|
|
10300
|
+
const id = ctx.sessions.list.getSnapshot().current;
|
|
10301
|
+
const binding = id === void 0 ? void 0 : ctx.sessions.binding(id);
|
|
10302
|
+
return binding === void 0 ? void 0 : ctx.conversation.input.for(binding.ctx).state;
|
|
10303
|
+
});
|
|
8193
10304
|
const companionSlots = createCompanionTabSource(ctx.slots);
|
|
8194
10305
|
ctx.slots.inject("sidebar", () => ctx.slots.register({
|
|
8195
10306
|
name: "sidebar",
|
|
@@ -8218,6 +10329,12 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
8218
10329
|
}
|
|
8219
10330
|
},
|
|
8220
10331
|
inject: () => ({
|
|
10332
|
+
newConversationDraft,
|
|
10333
|
+
prefillNewConversation: (text) => {
|
|
10334
|
+
const id = ctx.sessions.list.getSnapshot().current;
|
|
10335
|
+
const binding = id === void 0 ? void 0 : ctx.sessions.binding(id);
|
|
10336
|
+
return prefillNewConversation(binding === void 0 ? void 0 : ctx.conversation.input.for(binding.ctx), text);
|
|
10337
|
+
},
|
|
8221
10338
|
openSession: (sessionId) => {
|
|
8222
10339
|
ctx.sessions.open(sessionId);
|
|
8223
10340
|
},
|