dsh-ui-fortifier 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/README.zh.md +3 -3
- package/lib/client.js +111 -83
- package/lib/index.js +22 -22
- package/lib/types/client/index.d.ts +4 -4
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/client/open-dsh-folder/OpenDshFolderAction.d.ts +3 -3
- package/lib/types/client/open-dsh-folder/index.d.ts +2 -2
- package/lib/types/client/settings/FortifierSettingsPage.d.ts +13 -8
- package/lib/types/client/settings/index.d.ts +10 -7
- package/lib/types/index.d.ts +57 -12
- package/lib/types/open-dsh-folder.d.ts +4 -4
- package/lib/types/types.d.ts +12 -9
- package/package.json +27 -24
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ dsh plugin --profile web add dsh-ui-fortifier
|
|
|
18
18
|
|
|
19
19
|
## Features
|
|
20
20
|
|
|
21
|
-
Adds a
|
|
21
|
+
Adds a configuration area to this plugin's own card on the sidebar's Plugins page, toggling every feature module of this plugin.
|
|
22
22
|
|
|
23
23
|
| Feature | Description |
|
|
24
24
|
| --- | --- |
|
|
@@ -26,12 +26,12 @@ Adds a "ui-fortifier" tab in Settings to toggle every feature module of this plu
|
|
|
26
26
|
| compact-button | Compact-context button at the right end of the composer tool row's left group; runs `/compact`. |
|
|
27
27
|
| provider-label | Shows the currently selected provider to the left of the model selector. |
|
|
28
28
|
| model-picker | Cascading model picker (provider → model) next to the model selector in the input row. |
|
|
29
|
-
| open-dsh-folder | Adds an "Open
|
|
29
|
+
| open-dsh-folder | Adds an "Open dshHome folder" button next to "Open configuration file" at the top-right of the Settings page. |
|
|
30
30
|
| settings-frame | Makes the Settings panel draggable and resizable. |
|
|
31
31
|
|
|
32
32
|
## dsh version used for development
|
|
33
33
|
|
|
34
|
-
- dsh version used for development: `0.1.
|
|
34
|
+
- dsh version used for development: `0.1.7-rc.2`. `@deepseek-ai/dsh-*` dependencies use `workspace:^`.
|
|
35
35
|
|
|
36
36
|
## Secondary Development
|
|
37
37
|
|
package/README.zh.md
CHANGED
|
@@ -18,7 +18,7 @@ dsh plugin --profile web add dsh-ui-fortifier
|
|
|
18
18
|
|
|
19
19
|
## 功能
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
在侧边栏「插件」页本插件自己的卡片上提供配置区,集中开关本插件各功能模块。
|
|
22
22
|
|
|
23
23
|
| 功能 | 描述 |
|
|
24
24
|
| --- | --- |
|
|
@@ -26,12 +26,12 @@ dsh plugin --profile web add dsh-ui-fortifier
|
|
|
26
26
|
| compact-button | 输入框工具行左组右端提供压缩上下文按钮,等价于提交 `/compact` 指令。 |
|
|
27
27
|
| provider-label | 在模型选择按钮左侧显示当前选择的提供方。 |
|
|
28
28
|
| model-picker | 输入行模型选择器旁提供级联模型选择器(提供商 → 模型)。 |
|
|
29
|
-
| open-dsh-folder | 在设置页右上角「打开配置文件」旁增加「打开
|
|
29
|
+
| open-dsh-folder | 在设置页右上角「打开配置文件」旁增加「打开dshHome文件夹」。 |
|
|
30
30
|
| settings-frame | 设置面板可拖动位置与拖动大小。 |
|
|
31
31
|
|
|
32
32
|
## 构建时使用的 dsh 版本
|
|
33
33
|
|
|
34
|
-
- 构建时使用的 dsh 版本:`0.1.
|
|
34
|
+
- 构建时使用的 dsh 版本:`0.1.7-rc.2`;`@deepseek-ai/dsh-*` 依赖使用 `workspace:^`。
|
|
35
35
|
|
|
36
36
|
## 二次开发说明
|
|
37
37
|
|
package/lib/client.js
CHANGED
|
@@ -4,12 +4,12 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
-
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
-
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
9
7
|
let react = require("react");
|
|
8
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
9
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
10
|
let react_dom = require("react-dom");
|
|
11
11
|
//#region \0dsh-css:D:\data\code\deepseek-harness\packages\my\dsh-ui-fortifier\src\client\settings\FortifierSettingsPage.module.css.mjs
|
|
12
|
-
const css$6 = ".t1_2kq_page{flex-direction:column;gap:8px;
|
|
12
|
+
const css$6 = ".t1_2kq_page{flex-direction:column;gap:8px;padding:16px;display:flex}.t1_2kq_heading{color:var(--dsw-alias-label-primary);margin:0;font-size:16px;line-height:24px}.t1_2kq_list{flex-direction:column;margin:0;padding:0;list-style:none;display:flex}.t1_2kq_row{justify-content:space-between;align-items:center;gap:12px;padding:10px 12px;display:flex}.t1_2kq_row+.t1_2kq_row{border-top:.5px solid var(--dsw-alias-border-l3)}.t1_2kq_row:hover{background:var(--dsw-alias-interactive-bg-hover)}.t1_2kq_rowLabel{color:var(--dsw-alias-label-primary);font-size:13px;line-height:20px}";
|
|
13
13
|
const tagId$6 = "dsh-ui-fortifier/FortifierSettingsPage.module.css";
|
|
14
14
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$6) + "]") === null) {
|
|
15
15
|
const tag = document.createElement("style");
|
|
@@ -23,23 +23,57 @@ window.__ModuleLoader__.load({
|
|
|
23
23
|
"list": "t1_2kq_list",
|
|
24
24
|
"page": "t1_2kq_page",
|
|
25
25
|
"row": "t1_2kq_row",
|
|
26
|
-
"rowLabel": "t1_2kq_rowLabel"
|
|
27
|
-
"switch": "t1_2kq_switch",
|
|
28
|
-
"switchOn": "t1_2kq_switchOn",
|
|
29
|
-
"thumb": "t1_2kq_thumb"
|
|
26
|
+
"rowLabel": "t1_2kq_rowLabel"
|
|
30
27
|
};
|
|
31
28
|
//#endregion
|
|
32
29
|
//#region src/client/settings/FortifierSettingsPage.tsx
|
|
33
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* 配置区:插件页上本包卡片里的六个功能开关。
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* 渲染六个功能开关。
|
|
35
|
+
* @param props - 组装后的插槽 props。
|
|
36
|
+
* @returns 插件页本包卡片上的配置区。
|
|
37
|
+
*/
|
|
34
38
|
function FortifierSettingsPage(props) {
|
|
35
39
|
const t = props.t;
|
|
36
40
|
const rows = props.useToggles((value) => value);
|
|
41
|
+
const [local, setLocal] = (0, react.useState)(() => /* @__PURE__ */ new Map());
|
|
42
|
+
const [pendingWrites, setPendingWrites] = (0, react.useState)(0);
|
|
43
|
+
const synced = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
44
|
+
(0, react.useEffect)(() => {
|
|
45
|
+
const host = new Map(rows.map((row) => [row.field, row.value]));
|
|
46
|
+
const unchanged = [...host].every(([field, value]) => synced.current.get(field) === value) && host.size === synced.current.size;
|
|
47
|
+
if (pendingWrites > 0 || unchanged) return;
|
|
48
|
+
synced.current = host;
|
|
49
|
+
setLocal(/* @__PURE__ */ new Map());
|
|
50
|
+
}, [rows, pendingWrites]);
|
|
51
|
+
/** 记一次未落定的写入,落定后减一;被拒或传输失败也照样放行,好让宿主值接管。 */
|
|
52
|
+
const trackWrite = (write) => {
|
|
53
|
+
setPendingWrites((count) => count + 1);
|
|
54
|
+
write.catch(() => false).finally(() => {
|
|
55
|
+
setPendingWrites((count) => Math.max(0, count - 1));
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* 提交一个开关:先落在本地(控件立即显示新值),再写宿主。
|
|
60
|
+
* @param row - 要切换的开关行。
|
|
61
|
+
*/
|
|
62
|
+
const commit = (row) => {
|
|
63
|
+
const next = !(local.get(row.field) ?? row.value);
|
|
64
|
+
const pending = new Map(local);
|
|
65
|
+
pending.set(row.field, next);
|
|
66
|
+
setLocal(pending);
|
|
67
|
+
synced.current = new Map(synced.current).set(row.field, next);
|
|
68
|
+
trackWrite(props.set(row.field, next));
|
|
69
|
+
};
|
|
70
|
+
if (props.view === "summary") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: t("nav") });
|
|
37
71
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38
72
|
className: FortifierSettingsPage_module_css_default.page,
|
|
39
73
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
40
74
|
className: FortifierSettingsPage_module_css_default.heading,
|
|
41
75
|
children: t("nav")
|
|
42
|
-
}),
|
|
76
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
43
77
|
className: FortifierSettingsPage_module_css_default.list,
|
|
44
78
|
children: rows.map((row) => {
|
|
45
79
|
const label = t(`config.${row.field}`);
|
|
@@ -48,16 +82,12 @@ window.__ModuleLoader__.load({
|
|
|
48
82
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
49
83
|
className: FortifierSettingsPage_module_css_default.rowLabel,
|
|
50
84
|
children: label
|
|
51
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
onClick: () => {
|
|
58
|
-
props.set(row.field, !row.value);
|
|
59
|
-
},
|
|
60
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: FortifierSettingsPage_module_css_default.thumb })
|
|
85
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
86
|
+
checked: local.get(row.field) ?? row.value,
|
|
87
|
+
label,
|
|
88
|
+
onChange: () => {
|
|
89
|
+
commit(row);
|
|
90
|
+
}
|
|
61
91
|
})]
|
|
62
92
|
}, row.field);
|
|
63
93
|
})
|
|
@@ -69,15 +99,14 @@ window.__ModuleLoader__.load({
|
|
|
69
99
|
/** 英文文案。 */
|
|
70
100
|
const en = {
|
|
71
101
|
nav: "ui-fortifier",
|
|
72
|
-
empty: "No feature modules registered.",
|
|
73
102
|
"config.provider-label": "Input - Provider",
|
|
74
|
-
"config.open-dsh-folder": "Settings top-right - Open
|
|
103
|
+
"config.open-dsh-folder": "Settings top-right - Open dshHome folder",
|
|
75
104
|
"config.settings-frame": "Settings panel - Drag and resize",
|
|
76
105
|
"config.model-picker": "Input - Cascading model picker",
|
|
77
106
|
"config.session-id-copy": "Session header - Copy session ID",
|
|
78
107
|
"config.compact-button": "Input left group - Compact context",
|
|
79
|
-
openDshFolder: "Open
|
|
80
|
-
"openDshFolder.error": "Could not open the
|
|
108
|
+
openDshFolder: "Open dshHome folder",
|
|
109
|
+
"openDshFolder.error": "Could not open the dshHome folder",
|
|
81
110
|
"openDshFolder.pathLabel": "Path: ",
|
|
82
111
|
"settingsFrame.drag": "Drag the settings panel",
|
|
83
112
|
"settingsFrame.resize": "Resize the settings panel",
|
|
@@ -104,15 +133,14 @@ window.__ModuleLoader__.load({
|
|
|
104
133
|
/** 中文文案。 */
|
|
105
134
|
const zh = {
|
|
106
135
|
nav: "ui-fortifier",
|
|
107
|
-
empty: "没有已注册的功能模块。",
|
|
108
136
|
"config.provider-label": "输入框 - 提供商",
|
|
109
|
-
"config.open-dsh-folder": "设置右上角 - 打开
|
|
137
|
+
"config.open-dsh-folder": "设置右上角 - 打开dshHome文件夹",
|
|
110
138
|
"config.settings-frame": "设置面板 - 拖动与缩放",
|
|
111
139
|
"config.model-picker": "输入框 - 级联模型选择器",
|
|
112
140
|
"config.session-id-copy": "会话标题栏 - 复制 Session ID",
|
|
113
141
|
"config.compact-button": "输入框左组 - 压缩上下文",
|
|
114
|
-
openDshFolder: "打开
|
|
115
|
-
"openDshFolder.error": "无法打开
|
|
142
|
+
openDshFolder: "打开dshHome文件夹",
|
|
143
|
+
"openDshFolder.error": "无法打开dshHome文件夹",
|
|
116
144
|
"openDshFolder.pathLabel": "路径:",
|
|
117
145
|
"settingsFrame.drag": "拖动设置面板",
|
|
118
146
|
"settingsFrame.resize": "缩放设置面板",
|
|
@@ -138,63 +166,58 @@ window.__ModuleLoader__.load({
|
|
|
138
166
|
};
|
|
139
167
|
//#endregion
|
|
140
168
|
//#region src/client/settings/index.ts
|
|
141
|
-
/**
|
|
169
|
+
/** 本插件在 profile 里的入口 id,同时是设置契约的命名空间。 */
|
|
142
170
|
const UI_FORTIFIER = "ui-fortifier";
|
|
143
171
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
172
|
+
* 本插件在 profile 里的包名,也是插件页派发配置区的键。
|
|
173
|
+
*
|
|
174
|
+
* 该页以 `pkg.name` 派发(`renderSlot('plugins.bundle.config', ..., { entryKey: pkg.name })`),
|
|
175
|
+
* 所以这里的值必须与 package.json 的 `name` 逐字一致;写错不会报错,只会让配置区静默
|
|
176
|
+
* 地不出现。
|
|
177
|
+
*/
|
|
178
|
+
const BUNDLE_NAME = "dsh-ui-fortifier";
|
|
179
|
+
/**
|
|
180
|
+
* 注册配置区并把入口配置的表单绑成本页的数据源。
|
|
181
|
+
* @param ctx - 需已提供 slots/locale/configForms 的客户端上下文。
|
|
182
|
+
* @param moduleOrder - 功能开关字段的显示顺序。
|
|
183
|
+
* @returns 本入口的表单,供调用方控制子模块注册。
|
|
148
184
|
*/
|
|
149
185
|
function installSettings(ctx, moduleOrder) {
|
|
150
186
|
ctx.effect(() => ctx.locale.register(UI_FORTIFIER, {
|
|
151
187
|
zh,
|
|
152
188
|
en
|
|
153
189
|
}), "dsh-ui-fortifier: copy dictionaries");
|
|
154
|
-
const
|
|
155
|
-
const
|
|
156
|
-
const view = () => mirror.getSnapshot().view?.namespaces.find((row) => row.ns === UI_FORTIFIER);
|
|
157
|
-
const sectionInjected = () => {
|
|
190
|
+
const form = ctx.configForms.get(UI_FORTIFIER);
|
|
191
|
+
const injected = () => {
|
|
158
192
|
let cached = [];
|
|
159
|
-
let
|
|
193
|
+
let signature = "";
|
|
160
194
|
return {
|
|
161
195
|
hooks: { toggles: {
|
|
162
196
|
getSnapshot: () => {
|
|
163
|
-
const value =
|
|
197
|
+
const value = form.getSnapshot().value;
|
|
164
198
|
const rows = moduleOrder.map((field) => ({
|
|
165
199
|
field,
|
|
166
|
-
value: value[field] ?? true
|
|
200
|
+
value: value?.[field] ?? true
|
|
167
201
|
}));
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
202
|
+
const current = JSON.stringify(rows);
|
|
203
|
+
if (current !== signature) {
|
|
170
204
|
cached = rows;
|
|
171
|
-
|
|
205
|
+
signature = current;
|
|
172
206
|
}
|
|
173
207
|
return cached;
|
|
174
208
|
},
|
|
175
|
-
subscribe: (listener) =>
|
|
176
|
-
const offScope = scope.subscribe(listener);
|
|
177
|
-
const offMirror = mirror.subscribe(listener);
|
|
178
|
-
return () => {
|
|
179
|
-
offScope();
|
|
180
|
-
offMirror();
|
|
181
|
-
};
|
|
182
|
-
}
|
|
209
|
+
subscribe: (listener) => form.subscribe(listener)
|
|
183
210
|
} },
|
|
184
|
-
set: (field, value) =>
|
|
185
|
-
scope.set(field, value);
|
|
186
|
-
}
|
|
211
|
+
set: (field, value) => form.set(field, value)
|
|
187
212
|
};
|
|
188
213
|
};
|
|
189
|
-
ctx.slots.inject("
|
|
190
|
-
name: "
|
|
191
|
-
|
|
192
|
-
order: 30,
|
|
193
|
-
label: () => ctx.locale.bind(UI_FORTIFIER)("nav"),
|
|
214
|
+
ctx.slots.inject("plugins.bundle.config", () => ctx.slots.register({
|
|
215
|
+
name: "plugins.bundle.config",
|
|
216
|
+
key: BUNDLE_NAME,
|
|
194
217
|
locale: UI_FORTIFIER,
|
|
195
|
-
inject:
|
|
218
|
+
inject: injected
|
|
196
219
|
}, FortifierSettingsPage));
|
|
197
|
-
return
|
|
220
|
+
return form;
|
|
198
221
|
}
|
|
199
222
|
//#endregion
|
|
200
223
|
//#region \0dsh-css:D:\data\code\deepseek-harness\packages\my\dsh-ui-fortifier\src\client\provider-label\ProviderLabel.module.css.mjs
|
|
@@ -252,7 +275,7 @@ window.__ModuleLoader__.load({
|
|
|
252
275
|
//#endregion
|
|
253
276
|
//#region src/client/open-dsh-folder/OpenDshFolderAction.tsx
|
|
254
277
|
/**
|
|
255
|
-
* 渲染「打开
|
|
278
|
+
* 渲染「打开 dshHome 文件夹」操作,点击后请求 Host 打开 dshHome 目录。
|
|
256
279
|
* @param props - header owner 参数、本地化文案与注入的打开回调。
|
|
257
280
|
* @returns 操作按钮及其结果提示。
|
|
258
281
|
*/
|
|
@@ -301,7 +324,7 @@ window.__ModuleLoader__.load({
|
|
|
301
324
|
/** 本模块文案命名空间(与 host 侧一致)。 */
|
|
302
325
|
const NS$2 = "ui-fortifier";
|
|
303
326
|
/**
|
|
304
|
-
* 注册「打开
|
|
327
|
+
* 注册「打开 dshHome 文件夹」到设置页右上角操作区,仅在回环连接下注册。
|
|
305
328
|
* @param ctx - 需已提供 slots/connection 的客户端上下文。
|
|
306
329
|
* @returns 停止注入并卸载注册的 disposer。
|
|
307
330
|
*/
|
|
@@ -640,7 +663,7 @@ window.__ModuleLoader__.load({
|
|
|
640
663
|
}
|
|
641
664
|
//#endregion
|
|
642
665
|
//#region \0dsh-css:D:\data\code\deepseek-harness\packages\my\dsh-ui-fortifier\src\client\model-picker\ModelPicker.module.css.mjs
|
|
643
|
-
const css$2 = ".AGI7WG_root{flex:none;display:inline-flex}.AGI7WG_trigger{box-sizing:border-box;width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:14px;justify-content:center;align-items:center;padding:0;display:inline-flex}.AGI7WG_trigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.AGI7WG_trigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.AGI7WG_triggerIcon{flex:none;width:14px;height:14px}.AGI7WG_menu{z-index:1100;box-sizing:border-box
|
|
666
|
+
const css$2 = ".AGI7WG_root{flex:none;display:inline-flex}.AGI7WG_trigger{box-sizing:border-box;width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:14px;justify-content:center;align-items:center;padding:0;display:inline-flex}.AGI7WG_trigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.AGI7WG_trigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.AGI7WG_triggerIcon{flex:none;width:14px;height:14px}.AGI7WG_menu{z-index:1100;box-sizing:border-box;--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);min-width:min(420px,100vw - 32px);max-width:min(520px,100vw - 32px);height:min(420px,100vh - 96px);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border:0;flex-direction:column;padding:6px;display:flex;position:fixed;overflow:hidden}.AGI7WG_search{box-sizing:border-box;background:var(--dsw-alias-bg-layer-2);border:.5px solid var(--dsw-alias-border-l3);border-radius:10px;flex:none;align-items:center;gap:6px;height:28px;margin:0 2px 6px;padding:0 8px;display:flex}.AGI7WG_search:focus-within{border-color:var(--dsw-alias-brand-primary)}.AGI7WG_searchIcon{color:var(--dsw-alias-label-tertiary);flex:none;display:inline-flex}.AGI7WG_searchIcon svg{width:13px;height:13px}.AGI7WG_searchInput{min-width:0;color:var(--dsw-alias-label-primary);font:inherit;background:0 0;border:none;outline:none;flex:1;padding:0;font-size:13px;line-height:20px}.AGI7WG_searchInput::placeholder{color:var(--dsw-alias-label-tertiary)}.AGI7WG_columns{flex:1;min-height:0;display:flex;overflow:hidden}.AGI7WG_providers{flex:none;width:160px;padding-right:4px;overflow-y:auto}.AGI7WG_models{flex:1;min-width:0;padding-left:4px;overflow-y:auto}.AGI7WG_columnTitle{color:var(--dsw-alias-label-tertiary);padding:5px 8px 3px;font-size:12px;font-weight:500;line-height:18px}.AGI7WG_cell{box-sizing:border-box;width:100%;min-height:34px;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:10px;align-items:center;gap:8px;padding:6px 8px;display:flex}.AGI7WG_cell:hover:not(:disabled),.AGI7WG_cell:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}.AGI7WG_cellActive{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary)}.AGI7WG_cellSelected{color:var(--dsw-alias-label-primary);font-weight:500}.AGI7WG_cell:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.AGI7WG_modelName{overflow-wrap:anywhere;flex:1;min-width:0}.AGI7WG_check{color:var(--dsw-alias-brand-primary);flex:none}.AGI7WG_status{color:var(--dsw-alias-label-tertiary);padding:10px;font-size:13px;line-height:20px}.AGI7WG_error{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);border-radius:8px;justify-content:space-between;align-items:flex-start;gap:8px;margin-bottom:4px;padding:7px 8px;font-size:12px;line-height:18px;display:flex}.AGI7WG_retry{color:inherit;font:inherit;cursor:pointer;background:0 0;border:none;flex:none;padding:0;font-weight:600}";
|
|
644
667
|
const tagId$2 = "dsh-ui-fortifier/ModelPicker.module.css";
|
|
645
668
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
646
669
|
const tag = document.createElement("style");
|
|
@@ -973,7 +996,7 @@ window.__ModuleLoader__.load({
|
|
|
973
996
|
})
|
|
974
997
|
]
|
|
975
998
|
})
|
|
976
|
-
}), picker.open && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
999
|
+
}), picker.open && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.MenuSurface, {
|
|
977
1000
|
ref: menuRef,
|
|
978
1001
|
className: ModelPicker_module_css_default.menu,
|
|
979
1002
|
role: "dialog",
|
|
@@ -1199,7 +1222,7 @@ window.__ModuleLoader__.load({
|
|
|
1199
1222
|
className: SessionIdCopyAction_module_css_default.button,
|
|
1200
1223
|
"aria-label": t("sessionIdCopy.action"),
|
|
1201
1224
|
onClick: copy,
|
|
1202
|
-
children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
1225
|
+
children: copied ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HashGlyph, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutlineRegular, {})] })
|
|
1203
1226
|
})
|
|
1204
1227
|
});
|
|
1205
1228
|
}
|
|
@@ -1224,7 +1247,7 @@ window.__ModuleLoader__.load({
|
|
|
1224
1247
|
}
|
|
1225
1248
|
//#endregion
|
|
1226
1249
|
//#region \0dsh-css:D:\data\code\deepseek-harness\packages\my\dsh-ui-fortifier\src\client\compact-button\CompactContextButton.module.css.mjs
|
|
1227
|
-
const css = ".zxJg-q_root{flex:none;display:inline-flex}.zxJg-q_button{corner-shape:round;background:var(--dsw-specific-selector);width:28px;height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:999px;flex:none;place-items:center;display:grid}.zxJg-q_button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.zxJg-q_button:disabled{opacity:.5;cursor:default}.zxJg-q_glyph{fill:currentColor;flex:none;width:16px;height:16px;overflow:hidden}.zxJg-q_popover{z-index:1100;box-sizing:border-box;
|
|
1250
|
+
const css = ".zxJg-q_root{flex:none;display:inline-flex}.zxJg-q_button{corner-shape:round;background:var(--dsw-specific-selector);width:28px;height:28px;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:999px;flex:none;place-items:center;display:grid}.zxJg-q_button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.zxJg-q_button:disabled{opacity:.5;cursor:default}.zxJg-q_glyph{fill:currentColor;flex:none;width:16px;height:16px;overflow:hidden}.zxJg-q_popover{z-index:1100;box-sizing:border-box;max-width:min(260px,100vw - 32px);box-shadow:var(--dsw-elevation-prominent);color:var(--dsw-alias-label-primary);flex-direction:column;align-items:flex-start;gap:10px;padding:10px 12px;display:flex;position:fixed}.zxJg-q_popoverText{margin:0;font-size:13px;line-height:20px}";
|
|
1228
1251
|
const tagId = "dsh-ui-fortifier/CompactContextButton.module.css";
|
|
1229
1252
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
1230
1253
|
const tag = document.createElement("style");
|
|
@@ -1341,8 +1364,9 @@ window.__ModuleLoader__.load({
|
|
|
1341
1364
|
},
|
|
1342
1365
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CompressGlyph, {})
|
|
1343
1366
|
})
|
|
1344
|
-
}), open && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1367
|
+
}), open && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.MenuSurface, {
|
|
1345
1368
|
ref: panelRef,
|
|
1369
|
+
compact: true,
|
|
1346
1370
|
className: CompactContextButton_module_css_default.popover,
|
|
1347
1371
|
role: "dialog",
|
|
1348
1372
|
"aria-label": props.t("compactButton.confirmTitle"),
|
|
@@ -1380,7 +1404,7 @@ window.__ModuleLoader__.load({
|
|
|
1380
1404
|
}
|
|
1381
1405
|
//#endregion
|
|
1382
1406
|
//#region src/client/index.ts
|
|
1383
|
-
/** 功能模块清单:字段名(
|
|
1407
|
+
/** 功能模块清单:字段名(配置开关 key) → 模块安装面。 */
|
|
1384
1408
|
const modules = {
|
|
1385
1409
|
"provider-label": {
|
|
1386
1410
|
module: installProviderLabel,
|
|
@@ -1407,7 +1431,7 @@ window.__ModuleLoader__.load({
|
|
|
1407
1431
|
dispose: void 0
|
|
1408
1432
|
}
|
|
1409
1433
|
};
|
|
1410
|
-
/**
|
|
1434
|
+
/** 配置区开关行的显示顺序:按各模块在界面上的位置,从会话标题栏到输入行再到插件页。 */
|
|
1411
1435
|
const MODULE_ORDER = [
|
|
1412
1436
|
"session-id-copy",
|
|
1413
1437
|
"compact-button",
|
|
@@ -1419,7 +1443,7 @@ window.__ModuleLoader__.load({
|
|
|
1419
1443
|
const inject = [
|
|
1420
1444
|
"slots",
|
|
1421
1445
|
"locale",
|
|
1422
|
-
"
|
|
1446
|
+
"configForms",
|
|
1423
1447
|
"modelDirectories",
|
|
1424
1448
|
"connection",
|
|
1425
1449
|
"sessions",
|
|
@@ -1428,22 +1452,26 @@ window.__ModuleLoader__.load({
|
|
|
1428
1452
|
"remote.commands"
|
|
1429
1453
|
];
|
|
1430
1454
|
/**
|
|
1431
|
-
*
|
|
1432
|
-
* @param ctx - 需已提供 slots/locale/
|
|
1455
|
+
* 客户端插件体:注册插件页上的配置区并据开关状态挂载各功能模块。
|
|
1456
|
+
* @param ctx - 需已提供 slots/locale/configForms/modelDirectories/connection/sessions/remote 的客户端上下文。
|
|
1433
1457
|
*/
|
|
1434
1458
|
function apply(ctx) {
|
|
1435
|
-
const
|
|
1436
|
-
|
|
1459
|
+
const form = installSettings(ctx, MODULE_ORDER);
|
|
1460
|
+
const mounted = /* @__PURE__ */ new Map();
|
|
1461
|
+
const sync = (snapshot, field) => {
|
|
1462
|
+
const enabled = snapshot.value?.[field] ?? true;
|
|
1463
|
+
if (mounted.get(field) === enabled) return;
|
|
1464
|
+
mounted.set(field, enabled);
|
|
1437
1465
|
const item = modules[field];
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1466
|
+
item.dispose?.();
|
|
1467
|
+
item.dispose = enabled ? item.module(ctx) : void 0;
|
|
1468
|
+
};
|
|
1469
|
+
const syncAll = () => {
|
|
1470
|
+
const snapshot = form.getSnapshot();
|
|
1471
|
+
for (const field of Object.keys(modules)) sync(snapshot, field);
|
|
1472
|
+
};
|
|
1473
|
+
form.subscribe(syncAll);
|
|
1474
|
+
syncAll();
|
|
1447
1475
|
}
|
|
1448
1476
|
//#endregion
|
|
1449
1477
|
exports.MODULE_ORDER = MODULE_ORDER;
|
package/lib/index.js
CHANGED
|
@@ -93,7 +93,7 @@ async function openWindowsFolderInForeground(path, signal) {
|
|
|
93
93
|
windowsOpenScript(path)
|
|
94
94
|
], signal);
|
|
95
95
|
}
|
|
96
|
-
/** 用系统默认方式打开
|
|
96
|
+
/** 用系统默认方式打开 dshHome 文件夹;无原生打开器时返回路径让 UI 展示。 */
|
|
97
97
|
let OpenDshFolderService = (() => {
|
|
98
98
|
let _classSuper = TypertRemoteService;
|
|
99
99
|
let _instanceExtraInitializers = [];
|
|
@@ -125,9 +125,9 @@ let OpenDshFolderService = (() => {
|
|
|
125
125
|
__runInitializers(this, _instanceExtraInitializers);
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
|
-
* 打开
|
|
128
|
+
* 打开 dshHome 文件夹。
|
|
129
129
|
* @param signal - 调用方可取消信号。
|
|
130
|
-
* @returns opened 为 false 时 path 为
|
|
130
|
+
* @returns opened 为 false 时 path 为 dshHome 文件夹路径。
|
|
131
131
|
*/
|
|
132
132
|
async openDshFolder(signal) {
|
|
133
133
|
const home = resolveDshHome();
|
|
@@ -143,7 +143,7 @@ let OpenDshFolderService = (() => {
|
|
|
143
143
|
path: home
|
|
144
144
|
};
|
|
145
145
|
} catch (error) {
|
|
146
|
-
if (signal.aborted) throw new RemoteError("gateway/cancelled", "
|
|
146
|
+
if (signal.aborted) throw new RemoteError("gateway/cancelled", "dshHome folder open was aborted", {});
|
|
147
147
|
throw new RemoteError("gateway/internal", `path open failed: ${messageOf(error)}`, {}, { cause: error });
|
|
148
148
|
}
|
|
149
149
|
}
|
|
@@ -154,30 +154,30 @@ function messageOf(error) {
|
|
|
154
154
|
}
|
|
155
155
|
//#endregion
|
|
156
156
|
//#region lib/types/index.js
|
|
157
|
-
/**
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
/**
|
|
158
|
+
* 插件配置 schema。
|
|
159
|
+
*
|
|
160
|
+
* 不写成 `z<Config>`:`Config` 的字段是 `Volatile<T>`,而 volatile 字段的 schema 类型
|
|
161
|
+
* 处于 `"volatile-defined"` 模式,两者在双向方差下互不可赋值,加了注解反而编译不过
|
|
162
|
+
* (官方与已迁移的插件同样只写 `z.object`)。
|
|
163
|
+
*/
|
|
160
164
|
const Config = z.object({
|
|
161
|
-
"provider-label": z.boolean().default(true),
|
|
162
|
-
"open-dsh-folder": z.boolean().default(true),
|
|
163
|
-
"settings-frame": z.boolean().default(true),
|
|
164
|
-
"model-picker": z.boolean().default(true),
|
|
165
|
-
"session-id-copy": z.boolean().default(true),
|
|
166
|
-
"compact-button": z.boolean().default(true)
|
|
165
|
+
"provider-label": z.boolean().default(true).volatile(),
|
|
166
|
+
"open-dsh-folder": z.boolean().default(true).volatile(),
|
|
167
|
+
"settings-frame": z.boolean().default(true).volatile(),
|
|
168
|
+
"model-picker": z.boolean().default(true).volatile(),
|
|
169
|
+
"session-id-copy": z.boolean().default(true).volatile(),
|
|
170
|
+
"compact-button": z.boolean().default(true).volatile()
|
|
167
171
|
});
|
|
168
172
|
/**
|
|
169
|
-
*
|
|
170
|
-
* @param ctx -
|
|
171
|
-
* @param config - 插件配置,作为 base 层。
|
|
173
|
+
* 挂载插件:暴露打开 dshHome 文件夹的 Remote 服务,并声明本插件自带配置区。
|
|
174
|
+
* @param ctx - 需已提供 reflect(Typert 网关)的 Cordis 上下文。
|
|
172
175
|
*/
|
|
173
|
-
function apply(ctx
|
|
176
|
+
function apply(ctx) {
|
|
174
177
|
new OpenDshFolderService(ctx);
|
|
175
178
|
ctx.inject(["settings"], (settingsCtx) => {
|
|
176
|
-
settingsCtx.settings.
|
|
177
|
-
setSource: () => {},
|
|
178
|
-
onChange: () => {}
|
|
179
|
-
});
|
|
179
|
+
settingsCtx.effect(() => settingsCtx.settings.configure({ auto: false }, ctx.fiber));
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
182
|
//#endregion
|
|
183
|
-
export { Config,
|
|
183
|
+
export { Config, apply };
|
|
@@ -8,14 +8,14 @@ interface ModuleEntry {
|
|
|
8
8
|
/** 当前注册的 disposer;归位后为 undefined。 */
|
|
9
9
|
dispose: (() => void) | undefined;
|
|
10
10
|
}
|
|
11
|
-
/** 功能模块清单:字段名(
|
|
11
|
+
/** 功能模块清单:字段名(配置开关 key) → 模块安装面。 */
|
|
12
12
|
export declare const modules: Record<keyof Config, ModuleEntry>;
|
|
13
|
-
/**
|
|
13
|
+
/** 配置区开关行的显示顺序:按各模块在界面上的位置,从会话标题栏到输入行再到插件页。 */
|
|
14
14
|
export declare const MODULE_ORDER: readonly (keyof Config)[];
|
|
15
15
|
export declare const inject: string[];
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
* @param ctx - 需已提供 slots/locale/
|
|
17
|
+
* 客户端插件体:注册插件页上的配置区并据开关状态挂载各功能模块。
|
|
18
|
+
* @param ctx - 需已提供 slots/locale/configForms/modelDirectories/connection/sessions/remote 的客户端上下文。
|
|
19
19
|
*/
|
|
20
20
|
export declare function apply(ctx: Context): void;
|
|
21
21
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** dsh-ui-fortifier 的文案。 */
|
|
2
2
|
/** locale key。 */
|
|
3
|
-
export type UiFortifierLocaleKey = 'nav' | '
|
|
3
|
+
export type UiFortifierLocaleKey = 'nav' | 'config.provider-label' | 'config.open-dsh-folder' | 'config.settings-frame' | 'config.model-picker' | 'config.session-id-copy' | 'config.compact-button' | 'openDshFolder' | 'openDshFolder.error' | 'openDshFolder.pathLabel' | 'settingsFrame.drag' | 'settingsFrame.resize' | 'modelPicker.trigger' | 'modelPicker.searchPlaceholder' | 'modelPicker.providers' | 'modelPicker.models' | 'modelPicker.emptyProviders' | 'modelPicker.emptySearch' | 'modelPicker.emptyModels' | 'modelPicker.loading' | 'modelPicker.loadError' | 'modelPicker.retry' | 'modelPicker.provider' | 'modelPicker.model' | 'sessionIdCopy.action' | 'sessionIdCopy.hint' | 'sessionIdCopy.copied' | 'compactButton.action' | 'compactButton.confirmTitle' | 'compactButton.confirmText' | 'compactButton.confirm';
|
|
4
4
|
/** 英文文案。 */
|
|
5
5
|
export declare const en: Record<UiFortifierLocaleKey, string>;
|
|
6
6
|
/** 中文文案。 */
|
|
@@ -2,15 +2,15 @@ import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-cli
|
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
import type { ConnectionRpcResult } from '@deepseek-ai/dsh-client-connection/client';
|
|
4
4
|
import type { DshFolderOpenValue } from '../../types.ts';
|
|
5
|
-
/** 打开
|
|
5
|
+
/** 打开 dshHome 文件夹的注入面。 */
|
|
6
6
|
export interface OpenDshFolderInjected {
|
|
7
|
-
/** 请求 Host 打开
|
|
7
|
+
/** 请求 Host 打开 dshHome 文件夹。 */
|
|
8
8
|
openDshFolder: () => Promise<ConnectionRpcResult<DshFolderOpenValue>>;
|
|
9
9
|
}
|
|
10
10
|
/** header 操作区的 owner 参数、本地化文案与注入回调。 */
|
|
11
11
|
export type OpenDshFolderActionProps = PropsRuntime<'settings.action'> & PropsLocale<'ui-fortifier'> & InjectFace<OpenDshFolderInjected>;
|
|
12
12
|
/**
|
|
13
|
-
* 渲染「打开
|
|
13
|
+
* 渲染「打开 dshHome 文件夹」操作,点击后请求 Host 打开 dshHome 目录。
|
|
14
14
|
* @param props - header owner 参数、本地化文案与注入的打开回调。
|
|
15
15
|
* @returns 操作按钮及其结果提示。
|
|
16
16
|
*/
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* open-dsh-folder 功能:在设置页右上角「打开配置文件」旁增加「打开
|
|
2
|
+
* open-dsh-folder 功能:在设置页右上角「打开配置文件」旁增加「打开 dshHome 文件夹」。
|
|
3
3
|
*/
|
|
4
4
|
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
5
5
|
export type { OpenDshFolderActionProps, OpenDshFolderInjected } from './OpenDshFolderAction.tsx';
|
|
6
6
|
/**
|
|
7
|
-
* 注册「打开
|
|
7
|
+
* 注册「打开 dshHome 文件夹」到设置页右上角操作区,仅在回环连接下注册。
|
|
8
8
|
* @param ctx - 需已提供 slots/connection 的客户端上下文。
|
|
9
9
|
* @returns 停止注入并卸载注册的 disposer。
|
|
10
10
|
*/
|
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
import type { HostObservable, InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { Config } from '../../types.ts';
|
|
2
3
|
/** 一个功能开关行的状态。 */
|
|
3
4
|
export interface FortifierToggleRow {
|
|
4
|
-
/** 字段名(
|
|
5
|
-
field:
|
|
5
|
+
/** 字段名(即配置的 key)。 */
|
|
6
|
+
field: keyof Config;
|
|
6
7
|
/** 当前值。 */
|
|
7
8
|
value: boolean;
|
|
8
9
|
}
|
|
9
|
-
/**
|
|
10
|
+
/** 配置区渲染所需的面。 */
|
|
10
11
|
export interface FortifierPageInjected {
|
|
11
12
|
hooks: {
|
|
12
13
|
/** 所有功能开关的当前值(响应式)。 */
|
|
13
14
|
toggles: HostObservable<readonly FortifierToggleRow[]>;
|
|
14
15
|
};
|
|
15
|
-
/** 写入一个开关值(user 层)。 */
|
|
16
|
-
set: (field:
|
|
16
|
+
/** 写入一个开关值(user 层);落定后 resolve。 */
|
|
17
|
+
set: (field: keyof Config, value: boolean) => Promise<boolean>;
|
|
17
18
|
}
|
|
18
|
-
/**
|
|
19
|
-
export type FortifierSettingsPageProps = PropsRuntime<'
|
|
20
|
-
/**
|
|
19
|
+
/** 配置区 props:挂在插件页本包详情页的 `plugins.bundle.config` 上。 */
|
|
20
|
+
export type FortifierSettingsPageProps = PropsRuntime<'plugins.bundle.config'> & PropsLocale<'ui-fortifier'> & InjectFace<FortifierPageInjected>;
|
|
21
|
+
/**
|
|
22
|
+
* 渲染六个功能开关。
|
|
23
|
+
* @param props - 组装后的插槽 props。
|
|
24
|
+
* @returns 插件页本包卡片上的配置区。
|
|
25
|
+
*/
|
|
21
26
|
export declare function FortifierSettingsPage(props: FortifierSettingsPageProps): import("react").JSX.Element;
|
|
22
27
|
//# sourceMappingURL=FortifierSettingsPage.d.ts.map
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 注册本插件的配置区(插件页上本包自己的卡片),并把入口配置的表单绑成本页的数据源。
|
|
3
|
+
*/
|
|
1
4
|
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
2
|
-
import type {
|
|
5
|
+
import type { ConfigForm } from '@deepseek-ai/dsh-client-ui-settings/client';
|
|
3
6
|
import type { Config } from '../../types.ts';
|
|
4
7
|
export type { FortifierPageInjected, FortifierSettingsPageProps } from './FortifierSettingsPage.tsx';
|
|
5
|
-
/**
|
|
8
|
+
/** 本插件在 profile 里的入口 id,同时是设置契约的命名空间。 */
|
|
6
9
|
export declare const UI_FORTIFIER = "ui-fortifier";
|
|
7
10
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @param ctx - 需已提供 slots/locale/
|
|
10
|
-
* @param moduleOrder -
|
|
11
|
-
* @returns
|
|
11
|
+
* 注册配置区并把入口配置的表单绑成本页的数据源。
|
|
12
|
+
* @param ctx - 需已提供 slots/locale/configForms 的客户端上下文。
|
|
13
|
+
* @param moduleOrder - 功能开关字段的显示顺序。
|
|
14
|
+
* @returns 本入口的表单,供调用方控制子模块注册。
|
|
12
15
|
*/
|
|
13
|
-
export declare function installSettings(ctx: ClientContext, moduleOrder: readonly
|
|
16
|
+
export declare function installSettings(ctx: ClientContext, moduleOrder: readonly (keyof Config)[]): ConfigForm<Config>;
|
|
14
17
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,17 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* dsh-ui-fortifier 的宿主半侧。
|
|
3
|
+
*
|
|
4
|
+
* 只做两件事:暴露「打开 dshHome 文件夹」的 Remote 服务,以及声明本插件自带配置区。
|
|
5
|
+
* 六个功能开关的值由浏览器半侧经设置表单读写(见 `src/client/settings/index.ts`),
|
|
6
|
+
* 宿主不读它们,因此 `apply` 不接配置参数。
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-ui-fortifier
|
|
9
|
+
*/
|
|
10
|
+
import type { Context, Volatile } from '@deepseek-ai/cordis';
|
|
2
11
|
import z from '@deepseek-ai/schemastery';
|
|
3
|
-
import type { Config as FortifierConfig } from './types.ts';
|
|
4
|
-
/** 插件配置类型(定义见 `./types.ts`,与 Client 面共享)。 */
|
|
5
|
-
export type Config = FortifierConfig;
|
|
6
12
|
export type { DshFolderOpenValue } from './types.ts';
|
|
7
|
-
/** 功能开关的 settings 命名空间。 */
|
|
8
|
-
export declare const UI_FORTIFIER_SETTINGS_NAMESPACE = "ui-fortifier";
|
|
9
|
-
/** 插件配置 schema。 */
|
|
10
|
-
export declare const Config: z<FortifierConfig>;
|
|
11
13
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
14
|
+
* 插件配置。
|
|
15
|
+
*
|
|
16
|
+
* 六个字段都是 **volatile 引用**:设置表单只投影入口 `Config` 里声明为 `.volatile()`
|
|
17
|
+
* 的字段,写入由 Loader 经 `updateVolatile` 落回本入口的 profile patch。volatile 引用
|
|
18
|
+
* 原地更新,所以表单每次 `.get()` 都拿到当前值,不必重挂插件。
|
|
19
|
+
* 解引用之后的普通值见 [src/types.ts](./types.ts) 的 `Config`。
|
|
20
|
+
*/
|
|
21
|
+
export interface Config {
|
|
22
|
+
/** 输入框显示当前提供商。 */
|
|
23
|
+
'provider-label': Volatile<boolean>;
|
|
24
|
+
/** 插件页右上角显示打开 dshHome 文件夹按钮。 */
|
|
25
|
+
'open-dsh-folder': Volatile<boolean>;
|
|
26
|
+
/** 设置面板可拖动位置与大小。 */
|
|
27
|
+
'settings-frame': Volatile<boolean>;
|
|
28
|
+
/** 输入框右侧显示级联模型选择器(先选提供商、再选模型)。 */
|
|
29
|
+
'model-picker': Volatile<boolean>;
|
|
30
|
+
/** 会话标题栏显示复制会话 ID 按钮。 */
|
|
31
|
+
'session-id-copy': Volatile<boolean>;
|
|
32
|
+
/** 输入框工具行左组右端显示压缩上下文按钮。 */
|
|
33
|
+
'compact-button': Volatile<boolean>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 插件配置 schema。
|
|
37
|
+
*
|
|
38
|
+
* 不写成 `z<Config>`:`Config` 的字段是 `Volatile<T>`,而 volatile 字段的 schema 类型
|
|
39
|
+
* 处于 `"volatile-defined"` 模式,两者在双向方差下互不可赋值,加了注解反而编译不过
|
|
40
|
+
* (官方与已迁移的插件同样只写 `z.object`)。
|
|
41
|
+
*/
|
|
42
|
+
export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
43
|
+
'provider-label': z<boolean, boolean, "volatile-defined">;
|
|
44
|
+
'open-dsh-folder': z<boolean, boolean, "volatile-defined">;
|
|
45
|
+
'settings-frame': z<boolean, boolean, "volatile-defined">;
|
|
46
|
+
'model-picker': z<boolean, boolean, "volatile-defined">;
|
|
47
|
+
'session-id-copy': z<boolean, boolean, "volatile-defined">;
|
|
48
|
+
'compact-button': z<boolean, boolean, "volatile-defined">;
|
|
49
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
50
|
+
'provider-label': z<boolean, boolean, "volatile-defined">;
|
|
51
|
+
'open-dsh-folder': z<boolean, boolean, "volatile-defined">;
|
|
52
|
+
'settings-frame': z<boolean, boolean, "volatile-defined">;
|
|
53
|
+
'model-picker': z<boolean, boolean, "volatile-defined">;
|
|
54
|
+
'session-id-copy': z<boolean, boolean, "volatile-defined">;
|
|
55
|
+
'compact-button': z<boolean, boolean, "volatile-defined">;
|
|
56
|
+
}>>, "plain">;
|
|
57
|
+
/**
|
|
58
|
+
* 挂载插件:暴露打开 dshHome 文件夹的 Remote 服务,并声明本插件自带配置区。
|
|
59
|
+
* @param ctx - 需已提供 reflect(Typert 网关)的 Cordis 上下文。
|
|
15
60
|
*/
|
|
16
|
-
export declare function apply(ctx: Context
|
|
61
|
+
export declare function apply(ctx: Context): void;
|
|
17
62
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 打开本机
|
|
2
|
+
* 打开本机 dshHome 文件夹的 Host Remote 服务。
|
|
3
3
|
* 端点 `uiFortifier/openDshFolder` 由网关的 SRC 反射发现,无需 typert 生成器产物。
|
|
4
4
|
*/
|
|
5
5
|
import { Context } from '@deepseek-ai/cordis';
|
|
6
6
|
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
7
7
|
import type { DshFolderOpenValue } from './types.ts';
|
|
8
8
|
export type { DshFolderOpenValue };
|
|
9
|
-
/** 用系统默认方式打开
|
|
9
|
+
/** 用系统默认方式打开 dshHome 文件夹;无原生打开器时返回路径让 UI 展示。 */
|
|
10
10
|
export declare class OpenDshFolderService extends TypertRemoteService {
|
|
11
11
|
constructor(ctx: Context);
|
|
12
12
|
/**
|
|
13
|
-
* 打开
|
|
13
|
+
* 打开 dshHome 文件夹。
|
|
14
14
|
* @param signal - 调用方可取消信号。
|
|
15
|
-
* @returns opened 为 false 时 path 为
|
|
15
|
+
* @returns opened 为 false 时 path 为 dshHome 文件夹路径。
|
|
16
16
|
*/
|
|
17
17
|
openDshFolder(signal: AbortSignal): Promise<DshFolderOpenValue>;
|
|
18
18
|
}
|
package/lib/types/types.d.ts
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 本包 Host/Client 两面共享的类型。
|
|
3
3
|
* 仅类型、无运行时代码:双面工程各自编译本文件,无需跨面引用。
|
|
4
|
+
*
|
|
5
|
+
* 这里的 `Config` 是**解引用之后的普通值**,也就是配置区读写的那一份;Host 面的
|
|
6
|
+
* `Config` 六个字段都包在 volatile 引用里,见 [src/index.ts](./index.ts)。
|
|
4
7
|
*/
|
|
5
8
|
/** 插件配置:功能开关状态(配置默认值)。 */
|
|
6
9
|
export interface Config {
|
|
7
10
|
/** 输入框显示当前提供商。 */
|
|
8
|
-
'provider-label': boolean;
|
|
9
|
-
/**
|
|
10
|
-
'open-dsh-folder': boolean;
|
|
11
|
+
readonly 'provider-label': boolean;
|
|
12
|
+
/** 插件页右上角显示打开 dshHome 文件夹按钮。 */
|
|
13
|
+
readonly 'open-dsh-folder': boolean;
|
|
11
14
|
/** 设置面板可拖动位置与大小。 */
|
|
12
|
-
'settings-frame': boolean;
|
|
15
|
+
readonly 'settings-frame': boolean;
|
|
13
16
|
/** 输入框右侧显示级联模型选择器(先选提供商、再选模型)。 */
|
|
14
|
-
'model-picker': boolean;
|
|
17
|
+
readonly 'model-picker': boolean;
|
|
15
18
|
/** 会话标题栏显示复制会话 ID 按钮。 */
|
|
16
|
-
'session-id-copy': boolean;
|
|
19
|
+
readonly 'session-id-copy': boolean;
|
|
17
20
|
/** 输入框工具行左组右端显示压缩上下文按钮。 */
|
|
18
|
-
'compact-button': boolean;
|
|
21
|
+
readonly 'compact-button': boolean;
|
|
19
22
|
}
|
|
20
|
-
/** 打开
|
|
23
|
+
/** 打开 dshHome 文件夹的返回值。 */
|
|
21
24
|
export interface DshFolderOpenValue {
|
|
22
25
|
/** 是否已发起系统打开。 */
|
|
23
26
|
readonly opened: boolean;
|
|
24
|
-
/**
|
|
27
|
+
/** dshHome 文件夹绝对路径(未打开时供 UI 展示)。 */
|
|
25
28
|
readonly path: string;
|
|
26
29
|
}
|
|
27
30
|
//# sourceMappingURL=types.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-ui-fortifier",
|
|
3
3
|
"description": "UI 强化",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"contributors": [
|
|
7
7
|
"pgnqukezrdxmhjso"
|
|
@@ -44,35 +44,36 @@
|
|
|
44
44
|
"lib/types/**/*.d.ts"
|
|
45
45
|
],
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
48
|
-
"@deepseek-ai/dsh-
|
|
49
|
-
"@deepseek-ai/dsh-
|
|
50
|
-
"@deepseek-ai/dsh-typert-protocol": "^0.1.
|
|
51
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
47
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
48
|
+
"@deepseek-ai/dsh-native-command": "^0.1.7-rc.2",
|
|
49
|
+
"@deepseek-ai/dsh-home-paths": "^0.1.7-rc.2",
|
|
50
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.7-rc.2",
|
|
51
|
+
"@deepseek-ai/schemastery": "^3.18.4"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/react": "~18.3.1",
|
|
55
55
|
"@types/react-dom": "~18.3.0",
|
|
56
56
|
"react": "^18.2.0",
|
|
57
57
|
"react-dom": "^18.2.0",
|
|
58
|
-
"@deepseek-ai/
|
|
59
|
-
"@deepseek-ai/dsh-
|
|
60
|
-
"@deepseek-ai/
|
|
61
|
-
"@deepseek-ai/dsh-client-connection": "^0.1.
|
|
62
|
-
"@deepseek-ai/dsh-client-ui-
|
|
63
|
-
"@deepseek-ai/dsh-
|
|
64
|
-
"@deepseek-ai/dsh-client-ui-
|
|
65
|
-
"@deepseek-ai/dsh-client-ui-
|
|
66
|
-
"@deepseek-ai/dsh-client-ui-
|
|
67
|
-
"@deepseek-ai/dsh-
|
|
68
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1.
|
|
69
|
-
"@deepseek-ai/dsh-client-
|
|
70
|
-
"@deepseek-ai/dsh-client-
|
|
71
|
-
"@deepseek-ai/dsh-
|
|
72
|
-
"@deepseek-ai/dsh-
|
|
73
|
-
"@deepseek-ai/
|
|
74
|
-
"@deepseek-ai/dsh-
|
|
75
|
-
"@deepseek-ai/
|
|
58
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.7-rc.2",
|
|
60
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.7-rc.2",
|
|
61
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.7-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-model-selection": "^0.1.7-rc.2",
|
|
63
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.7-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager": "^0.1.7-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.2",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.7-rc.2",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-session": "^0.1.7-rc.2",
|
|
70
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.7-rc.2",
|
|
71
|
+
"@deepseek-ai/dsh-home-paths": "^0.1.7-rc.2",
|
|
72
|
+
"@deepseek-ai/dsh-native-command": "^0.1.7-rc.2",
|
|
73
|
+
"@deepseek-ai/dsh-session": "^0.1.7-rc.2",
|
|
74
|
+
"@deepseek-ai/dsh-settings": "^0.1.7-rc.2",
|
|
75
|
+
"@deepseek-ai/schemastery": "^3.18.4",
|
|
76
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.7-rc.2"
|
|
76
77
|
},
|
|
77
78
|
"dsh": {
|
|
78
79
|
"bundle": {
|
|
@@ -85,6 +86,7 @@
|
|
|
85
86
|
"@deepseek-ai/dsh-client-connection",
|
|
86
87
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
87
88
|
"@deepseek-ai/dsh-client-ui-model-selection",
|
|
89
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager",
|
|
88
90
|
"@deepseek-ai/dsh-client-ui-renderer",
|
|
89
91
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
90
92
|
"@deepseek-ai/dsh-client-locale"
|
|
@@ -98,6 +100,7 @@
|
|
|
98
100
|
"verify": "node ../dsh-pgnqukezrdxmhjso-base/verify.mjs",
|
|
99
101
|
"pub": "pnpm run build && pnpm login --registry=https://registry.npmjs.org && pnpm publish --registry=https://registry.npmjs.org --no-git-checks",
|
|
100
102
|
"pack": "pnpm run build && pnpm pack --pack-destination lib",
|
|
103
|
+
"link-test-i": "pnpm run build && (pnpm dsh plugin --profile pkgtest remove %npm_package_name% & pnpm dsh plugin --profile pkgtest add link:./)",
|
|
101
104
|
"pack-test-i": "pnpm run pack && (pnpm dsh plugin --profile pkgtest remove %npm_package_name% & pnpm dsh plugin --profile pkgtest add ./lib/%npm_package_name%-%npm_package_version%.tgz)",
|
|
102
105
|
"npm-test-i": "pnpm dsh plugin --profile pkgtest remove %npm_package_name% & pnpm dsh plugin --profile pkgtest add --registry=https://registry.npmjs.org %npm_package_name%@%npm_package_version%",
|
|
103
106
|
"test-create": "pnpm dsh --profile pkgtest --from-default-profile web",
|