@michengai/dsh-codex-ui 1.0.0 → 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 +30 -0
- package/CHANGELOG.zh-CN.md +30 -0
- 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/lib/client.js +1239 -72
- package/lib/index.mjs +57 -3
- package/lib/usage-frame.css +1 -0
- package/lib/usage-frame.js +489 -0
- package/package.json +8 -5
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。该兼容层只从本插件渲染
|
|
@@ -31,6 +171,7 @@ window.__ModuleLoader__.load({
|
|
|
31
171
|
let cancelPendingNavigation;
|
|
32
172
|
const SETTINGS_NAVIGATION_TIMEOUT_MS = 4e3;
|
|
33
173
|
const SETTINGS_TRIGGER_SELECTOR = "[data-dcu-settings-trigger],[aria-haspopup=\"dialog\"]";
|
|
174
|
+
const SETTINGS_OPEN_SECTION_EVENT = "dcu-settings-open-section";
|
|
34
175
|
/** 根入口与分区跳转使用同一触发器合约,兼容保留的宿主设置壳。 */
|
|
35
176
|
function openSettingsRoot(root) {
|
|
36
177
|
root?.querySelector(SETTINGS_TRIGGER_SELECTOR)?.click();
|
|
@@ -44,6 +185,14 @@ window.__ModuleLoader__.load({
|
|
|
44
185
|
}
|
|
45
186
|
const opening = cancelPendingNavigation !== void 0;
|
|
46
187
|
cancelPendingNavigation?.();
|
|
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
|
+
}
|
|
47
196
|
const pageSelector = trigger.hasAttribute("data-dcu-settings-trigger") ? "[data-dcu-settings-page]" : "[role=\"dialog\"]";
|
|
48
197
|
if (!opening && document.querySelector(pageSelector) === null) trigger.click();
|
|
49
198
|
let frame;
|
|
@@ -522,6 +671,82 @@ window.__ModuleLoader__.load({
|
|
|
522
671
|
* This source code is licensed under the ISC license.
|
|
523
672
|
* See the LICENSE file in the root directory of this source tree.
|
|
524
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
|
+
*/
|
|
525
750
|
const CircleQuestionMark = createLucideIcon("circle-question-mark", [
|
|
526
751
|
["circle", {
|
|
527
752
|
cx: "12",
|
|
@@ -670,6 +895,26 @@ window.__ModuleLoader__.load({
|
|
|
670
895
|
* This source code is licensed under the ISC license.
|
|
671
896
|
* See the LICENSE file in the root directory of this source tree.
|
|
672
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
|
+
*/
|
|
673
918
|
const Link = createLucideIcon("link", [["path", {
|
|
674
919
|
d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",
|
|
675
920
|
key: "1cjeqo"
|
|
@@ -733,6 +978,34 @@ window.__ModuleLoader__.load({
|
|
|
733
978
|
* This source code is licensed under the ISC license.
|
|
734
979
|
* See the LICENSE file in the root directory of this source tree.
|
|
735
980
|
*/
|
|
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
|
+
*/
|
|
736
1009
|
const Search = createLucideIcon("search", [["path", {
|
|
737
1010
|
d: "m21 21-4.34-4.34",
|
|
738
1011
|
key: "14j7rj"
|
|
@@ -866,6 +1139,44 @@ window.__ModuleLoader__.load({
|
|
|
866
1139
|
* This source code is licensed under the ISC license.
|
|
867
1140
|
* See the LICENSE file in the root directory of this source tree.
|
|
868
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
|
+
*/
|
|
869
1180
|
const User = createLucideIcon("user", [["path", {
|
|
870
1181
|
d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",
|
|
871
1182
|
key: "975kel"
|
|
@@ -2212,40 +2523,6 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2212
2523
|
return fallback !== void 0 && fallback.trim() !== "" ? fallback : void 0;
|
|
2213
2524
|
}
|
|
2214
2525
|
//#endregion
|
|
2215
|
-
//#region src/client/tree-expansion.ts
|
|
2216
|
-
const WORKSPACE_EXPANSION_STORAGE_KEY = "dsh-codex-ui.workspace-expansion.v1";
|
|
2217
|
-
const CHANNEL_EXPANSION_STORAGE_KEY = "dsh-codex-ui.channel-expansion.v1";
|
|
2218
|
-
const SCHEDULE_EXPANSION_STORAGE_KEY = "dsh-codex-ui.schedule-expansion.v1";
|
|
2219
|
-
const MAX_EXPANSION_ENTRIES = 500;
|
|
2220
|
-
const MAX_EXPANSION_KEY_LENGTH = 512;
|
|
2221
|
-
function browserStorage() {
|
|
2222
|
-
if (typeof window === "undefined") return void 0;
|
|
2223
|
-
try {
|
|
2224
|
-
return window.localStorage;
|
|
2225
|
-
} catch {
|
|
2226
|
-
return;
|
|
2227
|
-
}
|
|
2228
|
-
}
|
|
2229
|
-
function parseTreeExpansionState(value) {
|
|
2230
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) return {};
|
|
2231
|
-
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);
|
|
2232
|
-
return Object.fromEntries(entries);
|
|
2233
|
-
}
|
|
2234
|
-
function readTreeExpansionState(storage, key) {
|
|
2235
|
-
if (storage === void 0) return {};
|
|
2236
|
-
try {
|
|
2237
|
-
return parseTreeExpansionState(JSON.parse(storage.getItem(key) ?? "{}"));
|
|
2238
|
-
} catch {
|
|
2239
|
-
return {};
|
|
2240
|
-
}
|
|
2241
|
-
}
|
|
2242
|
-
function writeTreeExpansionState(storage, key, state) {
|
|
2243
|
-
if (storage === void 0) return;
|
|
2244
|
-
try {
|
|
2245
|
-
storage.setItem(key, JSON.stringify(parseTreeExpansionState(state)));
|
|
2246
|
-
} catch {}
|
|
2247
|
-
}
|
|
2248
|
-
//#endregion
|
|
2249
2526
|
//#region src/client/workspace-compat.ts
|
|
2250
2527
|
function hasStartSession(value) {
|
|
2251
2528
|
return value !== null && typeof value === "object" && "startSession" in value && typeof value.startSession === "function";
|
|
@@ -2648,7 +2925,8 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2648
2925
|
const stylesheet$4 = `
|
|
2649
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)}
|
|
2650
2927
|
.dcu-wb *{box-sizing:border-box}
|
|
2651
|
-
.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}
|
|
2652
2930
|
.dcu-wb-section+.dcu-wb-section{margin-top:12px}
|
|
2653
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}}
|
|
2654
2932
|
.dcu-wb-project{position:relative;min-width:0}
|
|
@@ -5714,6 +5992,340 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5714
5992
|
} catch {}
|
|
5715
5993
|
}
|
|
5716
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
|
|
5717
6329
|
//#region src/client/CodexSidebar.tsx
|
|
5718
6330
|
const subscribeEmptyCompanionTabs = () => () => {};
|
|
5719
6331
|
const getEmptyCompanionTabs = () => EMPTY_COMPANION_TABS;
|
|
@@ -5732,7 +6344,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5732
6344
|
});
|
|
5733
6345
|
}
|
|
5734
6346
|
const stylesheet$3 = `
|
|
5735
|
-
.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)}
|
|
5736
6348
|
/* 滤镜只作用于背景,避免为设置和搜索等 fixed 后代创建侧栏包含块。 */
|
|
5737
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}}
|
|
5738
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}
|
|
@@ -5780,7 +6392,23 @@ body[data-we-sidebar-glass] .dcu-expanded-shell,body[data-we-sidebar-glass] .dcu
|
|
|
5780
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}
|
|
5781
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}
|
|
5782
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}}
|
|
5783
|
-
[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}}
|
|
5784
6412
|
html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:has([data-dcu-official-turn-navigator]) .dcu-turn-navigator{display:none}
|
|
5785
6413
|
[data-dcu-official-turn-navigator]{right:auto!important;left:calc(12px - (var(--dsh-composer-side-clearance) + 16px))!important}
|
|
5786
6414
|
[data-dcu-official-turn-mark]{inset:0 auto 0 0!important}
|
|
@@ -6095,7 +6723,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
6095
6723
|
});
|
|
6096
6724
|
});
|
|
6097
6725
|
/** Codex 风格的 DSH 侧栏,只替换导航外观,项目浏览和设置仍由 DSH 官方组件提供。 */
|
|
6098
|
-
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 }) {
|
|
6099
6727
|
const compact = collapsed || width < 80;
|
|
6100
6728
|
const [visualCompact, setVisualCompact] = (0, react.useState)(compact);
|
|
6101
6729
|
const [collapsing, setCollapsing] = (0, react.useState)(false);
|
|
@@ -6272,6 +6900,13 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
6272
6900
|
"aria-label": t("sidebar.label"),
|
|
6273
6901
|
children: [
|
|
6274
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
|
+
}),
|
|
6275
6910
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6276
6911
|
className: "dcu-expanded-shell",
|
|
6277
6912
|
children: [
|
|
@@ -7177,9 +7812,56 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
7177
7812
|
/** 本插件独占的界面文案命名空间。 */
|
|
7178
7813
|
const NS = "michengai.codexUi";
|
|
7179
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": "打开原弹窗",
|
|
7180
7857
|
"settings.title": "设置",
|
|
7181
7858
|
"settings.back": "返回应用",
|
|
7182
7859
|
"settings.openDocument": "打开配置文件",
|
|
7860
|
+
"settings.advanced": "高级",
|
|
7861
|
+
"settings.documentTitle": "配置文件",
|
|
7862
|
+
"settings.documentDescription": "在外部编辑器中查看和编辑配置",
|
|
7863
|
+
"settings.documentOpen": "打开",
|
|
7864
|
+
"settings.documentOpening": "打开中…",
|
|
7183
7865
|
"settings.openDocumentError": "无法打开配置文件",
|
|
7184
7866
|
"settings.search": "搜索设置…",
|
|
7185
7867
|
"settings.personal": "个人",
|
|
@@ -7406,9 +8088,56 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
7406
8088
|
"meta.locale": "zh-CN"
|
|
7407
8089
|
};
|
|
7408
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",
|
|
7409
8133
|
"settings.title": "Settings",
|
|
7410
8134
|
"settings.back": "Back to app",
|
|
7411
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…",
|
|
7412
8141
|
"settings.openDocumentError": "Could not open configuration file",
|
|
7413
8142
|
"settings.search": "Search settings…",
|
|
7414
8143
|
"settings.personal": "Personal",
|
|
@@ -7769,9 +8498,216 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
7769
8498
|
};
|
|
7770
8499
|
}
|
|
7771
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
|
|
7772
8708
|
//#region src/client/settings-page-model.ts
|
|
7773
8709
|
function settingsGroup(id) {
|
|
7774
|
-
if (/archive|about
|
|
8710
|
+
if (/archive|about|^usage-statistics$/.test(id)) return "records";
|
|
7775
8711
|
if (/^(general|appearance|theme|language|shortcuts|voice|account)$/.test(id)) return "personal";
|
|
7776
8712
|
return "integrations";
|
|
7777
8713
|
}
|
|
@@ -7788,14 +8724,15 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
7788
8724
|
//#region src/client/settings-page-styles.ts
|
|
7789
8725
|
/** Codex 设置页的局部 tokens 与布局,不覆盖宿主其他弹窗。 */
|
|
7790
8726
|
const settingsPageStyles = `
|
|
7791
|
-
.dcu-settings-page{--sp-bg:#fff;--sp-nav
|
|
7792
|
-
body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav
|
|
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}
|
|
7793
8729
|
.dcu-settings-page *{box-sizing:border-box}
|
|
7794
8730
|
.dcu-settings-page button,.dcu-settings-page input{font:inherit}
|
|
7795
8731
|
.dcu-settings-page button{cursor:pointer}
|
|
7796
8732
|
.dcu-settings-page :focus-visible{outline:2px solid #459cff;outline-offset:3px}
|
|
7797
|
-
.dcu-settings-nav{display:flex;flex-direction:column;min-height:0;padding:18px 8px;background:var(--sp-nav);
|
|
7798
|
-
.dcu-settings-
|
|
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}
|
|
7799
8736
|
.dcu-settings-back:hover,.dcu-settings-link:hover{background:var(--sp-hover)}
|
|
7800
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)}
|
|
7801
8738
|
.dcu-settings-search:focus-within{border-color:#459cff}
|
|
@@ -7803,17 +8740,22 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
7803
8740
|
.dcu-settings-search input[type=search]{appearance:none;padding:0;border-radius:0;box-shadow:none;line-height:20px}
|
|
7804
8741
|
.dcu-settings-search input:focus,.dcu-settings-search input:focus-visible{outline:none;box-shadow:none}
|
|
7805
8742
|
.dcu-settings-search input::placeholder{color:var(--sp-muted)}
|
|
7806
|
-
.dcu-settings-group{margin:0 0
|
|
7807
|
-
.dcu-settings-group-label{margin:0 8px
|
|
7808
|
-
.dcu-settings-link{display:flex;align-items:center;gap:
|
|
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)}}
|
|
7809
8750
|
.dcu-settings-link[aria-current=page]{background:var(--sp-active)}
|
|
7810
|
-
.dcu-settings-link svg{flex:none;opacity
|
|
8751
|
+
.dcu-settings-link svg{flex:none;color:var(--dcu-sidebar-icon,var(--sp-text));opacity:1}
|
|
7811
8752
|
.dcu-settings-link span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
7812
8753
|
.dcu-settings-empty{padding:8px;color:var(--sp-muted);font-size:13px}
|
|
7813
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}
|
|
7814
|
-
.dcu-settings-inner{width:min(100%,864px);margin:0 auto;padding:
|
|
8755
|
+
.dcu-settings-inner{width:min(100%,864px);margin:0 auto;padding:48px 48px}
|
|
7815
8756
|
.dcu-settings-heading{display:flex;align-items:center;justify-content:space-between;gap:24px;margin-bottom:24px}
|
|
7816
|
-
.dcu-settings-heading h1{margin:0;font-size:24px;line-height:32px;font-weight:600;letter-spacing:-.4px}
|
|
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}
|
|
7817
8759
|
.dcu-settings-heading[data-own-title=false]{justify-content:flex-end;margin-bottom:16px}
|
|
7818
8760
|
.dcu-settings-heading:not(:has(h1,button,a,[role=button])){display:none}
|
|
7819
8761
|
.dcu-settings-actions{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end;color:var(--sp-muted)}
|
|
@@ -7826,6 +8768,13 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
7826
8768
|
.dcu-settings-row>[data-slot]>*{padding:12px 0!important;border-bottom:0!important;margin:0!important;min-width:0}
|
|
7827
8769
|
.dcu-settings-row button{font-size:13px;border-radius:8px}
|
|
7828
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}
|
|
7829
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}
|
|
7830
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}
|
|
7831
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)}
|
|
@@ -7842,6 +8791,24 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
7842
8791
|
@keyframes dcu-settings-enter{from{opacity:0}to{opacity:1}}
|
|
7843
8792
|
@keyframes dcu-settings-nav-enter{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}
|
|
7844
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)}
|
|
7845
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}}
|
|
7846
8813
|
.dcu-settings-page [data-slot="settings.section"]{min-width:0}
|
|
7847
8814
|
.dcu-settings-inner:has(.dcu-connector-frame){height:100%;display:flex;flex-direction:column}
|
|
@@ -7849,8 +8816,8 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
7849
8816
|
.dcu-settings-page .dcu-connectors:has(>.dcu-connector-frame){display:flex;flex-direction:column;flex:1 1 0;min-height:0}
|
|
7850
8817
|
.dcu-settings-page .dcu-connector-frame{flex:1 1 0;min-height:0;height:100%}
|
|
7851
8818
|
|
|
7852
|
-
@media(max-width:900px){.dcu-settings-
|
|
7853
|
-
@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-inner{padding:
|
|
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}}
|
|
7854
8821
|
`;
|
|
7855
8822
|
//#endregion
|
|
7856
8823
|
//#region src/client/settings-focus.ts
|
|
@@ -7876,6 +8843,7 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
7876
8843
|
editor: "settings.editor"
|
|
7877
8844
|
};
|
|
7878
8845
|
function sectionIcon(id) {
|
|
8846
|
+
if (id === "usage-statistics") return ChartColumn;
|
|
7879
8847
|
if (id === "market" || id === "plugin-marketplace") return Store;
|
|
7880
8848
|
if (id === "better-sidebar" || id === "sidebar-cards") return PanelRight;
|
|
7881
8849
|
if (/model/.test(id)) return Cpu;
|
|
@@ -7937,6 +8905,24 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
7937
8905
|
setActiveId(id);
|
|
7938
8906
|
setOpen(true);
|
|
7939
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
|
+
]);
|
|
7940
8926
|
(0, react.useEffect)(() => () => {
|
|
7941
8927
|
exitAnimation.current?.cancel();
|
|
7942
8928
|
}, []);
|
|
@@ -8031,7 +9017,7 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
8031
9017
|
"aria-expanded": open,
|
|
8032
9018
|
"aria-label": t("settings.title"),
|
|
8033
9019
|
onClick: () => {
|
|
8034
|
-
|
|
9020
|
+
openSection("general");
|
|
8035
9021
|
},
|
|
8036
9022
|
children: renderSlot("settings.trigger", { wide })
|
|
8037
9023
|
}),
|
|
@@ -8126,6 +9112,7 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
8126
9112
|
className: "dcu-settings-main",
|
|
8127
9113
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8128
9114
|
className: "dcu-settings-inner",
|
|
9115
|
+
"data-settings-section": active?.id,
|
|
8129
9116
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
8130
9117
|
className: "dcu-settings-heading",
|
|
8131
9118
|
"data-own-title": active?.id === "general",
|
|
@@ -8153,9 +9140,9 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
8153
9140
|
/** 每条偏好仍由原插件渲染和保存,只为公共条目添加可扩展的分组容器。 */
|
|
8154
9141
|
function CodexGeneralSettings({ items, renderSlot, t }) {
|
|
8155
9142
|
const rows = (0, react.useSyncExternalStore)(items.subscribe, items.getSnapshot);
|
|
8156
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
9143
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8157
9144
|
className: "dcu-settings-general",
|
|
8158
|
-
children: [
|
|
9145
|
+
children: [[
|
|
8159
9146
|
"permissions",
|
|
8160
9147
|
"general",
|
|
8161
9148
|
"editor"
|
|
@@ -8167,11 +9154,12 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
8167
9154
|
className: "dcu-settings-card",
|
|
8168
9155
|
children: entries.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8169
9156
|
className: "dcu-settings-row",
|
|
9157
|
+
"data-dcu-settings-item": row.id,
|
|
8170
9158
|
children: renderSlot("settings.general.item", {}, { only: row.id })
|
|
8171
9159
|
}, row.id))
|
|
8172
9160
|
})]
|
|
8173
9161
|
}, group);
|
|
8174
|
-
})
|
|
9162
|
+
}), renderSlot("settings.general.footer", {})]
|
|
8175
9163
|
});
|
|
8176
9164
|
}
|
|
8177
9165
|
//#endregion
|
|
@@ -8210,17 +9198,35 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
8210
9198
|
setOpening(false);
|
|
8211
9199
|
}
|
|
8212
9200
|
};
|
|
8213
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
8214
|
-
|
|
8215
|
-
children: t("settings.
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
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
|
+
})]
|
|
9229
|
+
});
|
|
8224
9230
|
}
|
|
8225
9231
|
//#endregion
|
|
8226
9232
|
//#region src/client/settings-page-registration.ts
|
|
@@ -8288,8 +9294,8 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
8288
9294
|
const remote = settingsCtx.get("remote");
|
|
8289
9295
|
if (!remote.$host.isLoopback) return;
|
|
8290
9296
|
const describe = settingsCtx.settingsScope.describe();
|
|
8291
|
-
settingsCtx.slots.inject("settings.
|
|
8292
|
-
name: "settings.
|
|
9297
|
+
settingsCtx.slots.inject("settings.general.footer", () => !owned ? () => {} : settingsCtx.slots.register({
|
|
9298
|
+
name: "settings.general.footer",
|
|
8293
9299
|
id: "open-document",
|
|
8294
9300
|
locale: NS,
|
|
8295
9301
|
inject: () => ({
|
|
@@ -8355,10 +9361,16 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
8355
9361
|
order: 0,
|
|
8356
9362
|
locale: NS,
|
|
8357
9363
|
label: () => t("settings.general"),
|
|
8358
|
-
children: {
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
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
|
+
},
|
|
8362
9374
|
inject: () => ({ items })
|
|
8363
9375
|
}, CodexGeneralSettings));
|
|
8364
9376
|
}
|
|
@@ -8482,6 +9494,105 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
8482
9494
|
};
|
|
8483
9495
|
}
|
|
8484
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
|
|
8485
9596
|
//#region src/client/official-turn-navigator.ts
|
|
8486
9597
|
const OFFICIAL_TURN_NAVIGATOR_ATTRIBUTE = "data-dcu-official-turn-navigator";
|
|
8487
9598
|
const OFFICIAL_TURN_MARK_ATTRIBUTE = "data-dcu-official-turn-mark";
|
|
@@ -9089,6 +10200,42 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
9089
10200
|
}, InputHistoryHint));
|
|
9090
10201
|
}
|
|
9091
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
|
|
9092
10239
|
//#region src/client/index.ts
|
|
9093
10240
|
const inject = [
|
|
9094
10241
|
"slots",
|
|
@@ -9126,20 +10273,34 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
9126
10273
|
}
|
|
9127
10274
|
/** 替换 DSH 的官方 sidebar 插槽,不修改 DSH 源码或会话数据。 */
|
|
9128
10275
|
function apply(ctx) {
|
|
10276
|
+
const widthStorage = browserStorage();
|
|
10277
|
+
if (widthStorage) initializeComposerWidth(widthStorage);
|
|
9129
10278
|
ctx.effect(() => ctx.locale.register(NS, {
|
|
9130
10279
|
zh,
|
|
9131
10280
|
en
|
|
9132
10281
|
}), "michengai-codex-ui: dictionaries");
|
|
9133
10282
|
const t = ctx.locale.bind(NS);
|
|
10283
|
+
ctx.effect(() => observeHeroWidthHandles(t("home.resizeInput")), "michengai-codex-ui: hero width handles");
|
|
9134
10284
|
registerInputHistory(ctx);
|
|
9135
10285
|
registerSettingsPage(ctx);
|
|
10286
|
+
registerUsageStatistics(ctx);
|
|
9136
10287
|
const connection = ctx.get("connection");
|
|
9137
10288
|
const openPath = (path) => openPathInHost(connection, path);
|
|
9138
10289
|
ctx.effect(() => observeSlimSidebar(), "michengai-codex-ui: slim sidebar");
|
|
9139
10290
|
ctx.effect(() => observeSettingsNavIcons(), "michengai-codex-ui: settings nav icons");
|
|
9140
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");
|
|
9141
10297
|
ctx.effect(() => observeConversationHeader(), "michengai-codex-ui: conversation header");
|
|
9142
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
|
+
});
|
|
9143
10304
|
const companionSlots = createCompanionTabSource(ctx.slots);
|
|
9144
10305
|
ctx.slots.inject("sidebar", () => ctx.slots.register({
|
|
9145
10306
|
name: "sidebar",
|
|
@@ -9168,6 +10329,12 @@ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--s
|
|
|
9168
10329
|
}
|
|
9169
10330
|
},
|
|
9170
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
|
+
},
|
|
9171
10338
|
openSession: (sessionId) => {
|
|
9172
10339
|
ctx.sessions.open(sessionId);
|
|
9173
10340
|
},
|