dsh-plugin 1.1.0 → 1.1.2
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.en.md +5 -5
- package/README.md +5 -5
- package/client/client.js +648 -190
- package/client/client.js.map +1 -1
- package/lib/http/routes.js +15 -8
- package/lib/index.js +4 -0
- package/lib/services/install-types.js +8 -2
- package/lib/services/install.js +1 -1
- package/lib/services/installed-versions.js +5 -1
- package/lib/services/loader.js +16 -5
- package/lib/services/npm-resolve.js +4 -0
- package/lib/services/pending-restart.js +1 -1
- package/lib/services/preflight.js +9 -4
- package/lib/services/profile.js +30 -3
- package/lib/services/progress.js +4 -0
- package/lib/services/task-queue.js +21 -10
- package/lib/types/index.d.ts +4 -0
- package/lib/types/services/install-types.d.ts +12 -4
- package/lib/types/services/install.d.ts +5 -1
- package/lib/types/services/loader.d.ts +10 -4
- package/lib/types/services/pending-restart.d.ts +8 -2
- package/lib/types/services/profile.d.ts +4 -2
- package/lib/types/services/progress.d.ts +4 -0
- package/package.json +1 -1
- package/src/client/components/AboutModal.tsx +76 -0
- package/src/client/components/CatalogControls.tsx +4 -0
- package/src/client/components/CatalogHeader.tsx +34 -5
- package/src/client/components/CatalogList.tsx +4 -0
- package/src/client/components/CategoryTabs.tsx +4 -0
- package/src/client/components/Dropdown.tsx +4 -0
- package/src/client/components/HubUpdateModal.tsx +88 -0
- package/src/client/components/NotificationsModal.tsx +25 -8
- package/src/client/components/PluginCard.tsx +8 -1
- package/src/client/components/PluginHubSection.tsx +67 -7
- package/src/client/components/ProgressView.tsx +4 -0
- package/src/client/components/icons.tsx +4 -0
- package/src/client/components/modals.tsx +35 -10
- package/src/client/hooks/useCatalog.ts +89 -17
- package/src/client/hooks/useTaskQueue.ts +52 -35
- package/src/client/index.tsx +4 -0
- package/src/client/lib/catalog.ts +59 -6
- package/src/client/lib/env.ts +4 -0
- package/src/client/lib/failures.ts +5 -1
- package/src/client/lib/format.ts +4 -0
- package/src/client/lib/renderMarkdown.ts +120 -0
- package/src/client/locales.ts +48 -1
- package/src/client/styles/Dropdown.module.css +5 -1
- package/src/client/styles/Header.module.css +88 -4
- package/src/client/styles/List.module.css +5 -1
- package/src/client/styles/Modal.module.css +279 -1
- package/src/client/styles/tokens.module.css +5 -1
- package/src/client/types.ts +7 -1
- package/src/server/http/routes.ts +14 -8
- package/src/server/index.ts +4 -0
- package/src/server/services/install-types.ts +12 -4
- package/src/server/services/install.ts +5 -1
- package/src/server/services/installed-versions.ts +5 -1
- package/src/server/services/loader.ts +16 -5
- package/src/server/services/npm-resolve.ts +4 -0
- package/src/server/services/pending-restart.ts +8 -2
- package/src/server/services/preflight.ts +9 -4
- package/src/server/services/profile.ts +27 -3
- package/src/server/services/progress.ts +4 -0
- package/src/server/services/task-queue.ts +21 -10
package/client/client.js
CHANGED
|
@@ -6,7 +6,13 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
let react = require("react");
|
|
8
8
|
//#region src/client/locales.ts
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
11
|
+
* Website: https://dsh-plugin.org
|
|
12
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
13
|
+
*
|
|
14
|
+
* zh/en dictionaries for the DSH-Plugin Hub settings section.
|
|
15
|
+
*/
|
|
10
16
|
const zh = {
|
|
11
17
|
nav: "插件中心",
|
|
12
18
|
title: "DSH-Plugin Hub",
|
|
@@ -27,6 +33,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
27
33
|
failedDesc: "请稍后重试,或点击右上角按钮在浏览器中打开插件中心。",
|
|
28
34
|
retry: "重试",
|
|
29
35
|
install: "安装",
|
|
36
|
+
cliOnlyHint: "此插件可能需命令行辅助,失败时复制上方命令到 dsh 终端",
|
|
37
|
+
failedCopyHint: "安装失败。请复制上方安装命令到 dsh 终端手动执行(原生依赖构建脚本可能需要人工放行,如 pnpm approve-builds)",
|
|
30
38
|
toastCopied: "安装命令已复制,去 dsh 终端粘贴即可安装",
|
|
31
39
|
installed: "已安装",
|
|
32
40
|
notInstalled: "未安装",
|
|
@@ -69,6 +77,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
69
77
|
restartLater: "稍后重启",
|
|
70
78
|
restarting: "正在重启…",
|
|
71
79
|
restartHint: "部分插件(如插件市场、顶层 bundle)需重启后才会生效。",
|
|
80
|
+
done: "完成",
|
|
72
81
|
restartPendingHint: "安装成功,重启后生效",
|
|
73
82
|
restartPendingHintUninstall: "卸载成功,重启后移除",
|
|
74
83
|
sectionPendingRestart: "待重启",
|
|
@@ -115,6 +124,21 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
115
124
|
update: "可更新",
|
|
116
125
|
updateAvailable: "有更新",
|
|
117
126
|
updateAvailableHint: "检测到更新:有版本号的仓库比对版本号,无版本号的仓库比对仓库最近更新时间",
|
|
127
|
+
hubUpdateHint: "检测到 DSH-Plugin Hub 新版本,点击查看更新内容并更新",
|
|
128
|
+
hubUpdateTitle: "DSH-Plugin Hub 有新版本",
|
|
129
|
+
hubUpdateDesc: "v{version} 已发布,点击下方按钮即可更新,完成后需重启宿主生效。",
|
|
130
|
+
hubUpdatePublished: "发布于",
|
|
131
|
+
hubUpdateNotes: "更新记录",
|
|
132
|
+
hubUpdateLater: "稍后再说",
|
|
133
|
+
versionHint: "查看版本信息与更新记录",
|
|
134
|
+
hubCurrentTitle: "当前版本",
|
|
135
|
+
hubCurrentDesc: "你正在使用 v{version},已是最新版本。",
|
|
136
|
+
hubUpToDate: "已是最新版本",
|
|
137
|
+
followUs: "关注我们",
|
|
138
|
+
aboutTitle: "关注我们",
|
|
139
|
+
aboutDesc: "了解 DSH-Plugin Hub 是做什么的,加入用户反馈群随时交流。",
|
|
140
|
+
aboutEmpty: "内容暂未发布,敬请期待。",
|
|
141
|
+
aboutUpdated: "更新于",
|
|
118
142
|
empty: "该分类暂无插件",
|
|
119
143
|
dataFrom: "数据源 dsh-plugin.org · 每日人工更新"
|
|
120
144
|
};
|
|
@@ -139,6 +163,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
139
163
|
failedDesc: "Please retry, or open the hub in your browser with the button above.",
|
|
140
164
|
retry: "Retry",
|
|
141
165
|
install: "Install",
|
|
166
|
+
cliOnlyHint: "This plugin may need command-line help; if it fails, copy the command above and run it in your dsh terminal",
|
|
167
|
+
failedCopyHint: "Install failed. Copy the command above and run it manually in your dsh terminal (native build scripts may need manual approval, e.g. pnpm approve-builds)",
|
|
142
168
|
toastCopied: "Install command copied — paste it in your dsh terminal",
|
|
143
169
|
installed: "Installed",
|
|
144
170
|
notInstalled: "Not installed",
|
|
@@ -181,6 +207,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
181
207
|
restartLater: "Later",
|
|
182
208
|
restarting: "Restarting…",
|
|
183
209
|
restartHint: "Some plugins (such as plugin markets / top-level bundles) only take effect after a restart.",
|
|
210
|
+
done: "Done",
|
|
184
211
|
restartPendingHint: "Installed — takes effect after restart",
|
|
185
212
|
restartPendingHintUninstall: "Removed — cleaned up after restart",
|
|
186
213
|
sectionPendingRestart: "Pending restart",
|
|
@@ -227,12 +254,27 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
227
254
|
update: "Update",
|
|
228
255
|
updateAvailable: "Update available",
|
|
229
256
|
updateAvailableHint: "An update was detected: repos with a release are compared by tag, repos without one by last push time",
|
|
257
|
+
hubUpdateHint: "A new DSH-Plugin Hub version is available — click to view the changelog and update",
|
|
258
|
+
hubUpdateTitle: "A new DSH-Plugin Hub version is available",
|
|
259
|
+
hubUpdateDesc: "v{version} has been released — click below to update, then restart the host to apply it.",
|
|
260
|
+
hubUpdatePublished: "Published",
|
|
261
|
+
hubUpdateNotes: "What's new",
|
|
262
|
+
hubUpdateLater: "Later",
|
|
263
|
+
versionHint: "View version info and changelog",
|
|
264
|
+
hubCurrentTitle: "Current version",
|
|
265
|
+
hubCurrentDesc: "You are on v{version} — this is the latest version.",
|
|
266
|
+
hubUpToDate: "Up to date",
|
|
267
|
+
followUs: "Follow us",
|
|
268
|
+
aboutTitle: "Follow us",
|
|
269
|
+
aboutDesc: "Learn what DSH-Plugin Hub does and join our user feedback group.",
|
|
270
|
+
aboutEmpty: "Content not published yet — stay tuned.",
|
|
271
|
+
aboutUpdated: "Updated",
|
|
230
272
|
empty: "No plugins in this category yet",
|
|
231
273
|
dataFrom: "Data from dsh-plugin.org · curated daily"
|
|
232
274
|
};
|
|
233
275
|
//#endregion
|
|
234
276
|
//#region \0dsh-css:src/client/styles/Header.module.css.mjs
|
|
235
|
-
const css$4 = ".qikqja_root{min-width:0;height:100%;color:var(--hub-text-primary);flex-direction:column;gap:8px;display:flex}.qikqja_header{flex-direction:column;gap:2px;padding:2px 2px 0;display:flex}.qikqja_headerRight{flex-shrink:0;align-items:center;gap:2px;display:inline-flex}.qikqja_langBtn{height:24px;color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;padding:0 8px;font-size:12px;font-weight:600;transition:color .15s,background-color .15s;display:inline-flex}.qikqja_langBtn:hover{color:var(--hub-purple-1);background-color:var(--hub-purple-tint)}.qikqja_githubLink{color:var(--hub-text-tertiary);cursor:pointer;border-radius:6px;flex-shrink:0;align-items:center;padding:3px;text-decoration:none;transition:color .15s,background-color .15s;display:inline-flex}.qikqja_githubLink:hover{color:var(--hub-purple-1);background-color:var(--hub-purple-tint)}.qikqja_githubIcon{flex-shrink:0;display:block}.
|
|
277
|
+
const css$4 = ".qikqja_root{min-width:0;height:100%;color:var(--hub-text-primary);flex-direction:column;gap:8px;display:flex}.qikqja_header{flex-direction:column;gap:2px;padding:2px 2px 0;display:flex}.qikqja_headerRight{flex-shrink:0;align-items:center;gap:2px;margin-left:auto;display:inline-flex}.qikqja_langBtn{height:24px;color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;padding:0 8px;font-size:12px;font-weight:600;transition:color .15s,background-color .15s;display:inline-flex}.qikqja_langBtn:hover{color:var(--hub-purple-1);background-color:var(--hub-purple-tint)}.qikqja_githubLink{color:var(--hub-text-tertiary);cursor:pointer;border-radius:6px;flex-shrink:0;align-items:center;padding:3px;text-decoration:none;transition:color .15s,background-color .15s;display:inline-flex}.qikqja_githubLink:hover{color:var(--hub-purple-1);background-color:var(--hub-purple-tint)}.qikqja_githubIcon{flex-shrink:0;display:block}.qikqja_aboutBtn{height:24px;color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;padding:0 8px;font-size:12px;font-weight:600;line-height:1;transition:color .15s,background-color .15s;display:inline-flex}.qikqja_aboutBtn:hover{color:var(--hub-purple-1);background-color:var(--hub-purple-tint)}.qikqja_headerTitleRow{align-items:center;gap:8px;min-width:0;display:flex}.qikqja_brandTitle{min-width:0;color:inherit;cursor:pointer;align-items:center;gap:10px;text-decoration:none;display:flex}.qikqja_taglineLink{min-width:0;max-width:100%;color:inherit;cursor:pointer;align-self:flex-start;text-decoration:none}.qikqja_title{margin:0;font-size:14px;font-weight:600;line-height:20px}.qikqja_version{color:var(--hub-text-secondary)}.qikqja_versionBtn{height:20px;color:var(--hub-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:5px;flex-shrink:0;align-items:center;gap:5px;padding:0 6px;font-size:12px;font-weight:600;line-height:1;transition:color .12s;display:inline-flex}.qikqja_versionBtn:hover{color:var(--hub-text-secondary)}.qikqja_hubUpdateBadge{letter-spacing:.02em;color:#fff;background:var(--hub-danger);-webkit-user-select:none;user-select:none;border-radius:999px;flex-shrink:0;align-items:center;height:18px;padding:0 7px;font-size:11px;font-weight:700;line-height:1;transition:background .12s,box-shadow .12s,transform .12s;display:inline-flex;box-shadow:0 1px 4px #d1242f66}.qikqja_hubUpdateBadge:hover{background:var(--hub-danger-hover);transform:translateY(-1px);box-shadow:0 2px 8px #d1242f80}.qikqja_logoIcon{flex-shrink:0;display:block}.qikqja_copyIcon{flex-shrink:0}.qikqja_tagline{color:var(--hub-text-tertiary);white-space:nowrap;text-overflow:ellipsis;margin:0;font-size:12px;line-height:18px;overflow:hidden}.qikqja_controls{flex-shrink:0;align-items:center;gap:4px;display:flex}.qikqja_filterResults{color:var(--hub-text-tertiary);white-space:nowrap;flex-shrink:0;align-items:baseline;font-size:12px;line-height:18px;display:inline-flex}.qikqja_resultCount{font-variant-numeric:tabular-nums;text-align:center;min-width:5ch}.qikqja_adBanner{border:1px solid var(--hub-purple-border);background:linear-gradient(90deg, var(--hub-purple-1) 0%, var(--hub-purple-2) 100%);color:#fff;cursor:pointer;-webkit-user-select:none;user-select:none;box-shadow:0 2px 10px var(--hub-purple-shadow);border-radius:8px;align-items:center;gap:8px;padding:7px 12px;text-decoration:none;transition:filter .15s,box-shadow .15s;display:flex}.qikqja_adBanner:hover{filter:brightness(1.1);box-shadow:0 4px 16px var(--hub-purple-shadow-strong)}.qikqja_adBadge{letter-spacing:.04em;color:#fff;white-space:nowrap;background:#ffffff29;border:1px solid #ffffff8c;border-radius:4px;flex-shrink:0;padding:3px 6px;font-size:10px;font-weight:700;line-height:1}.qikqja_adText{text-overflow:ellipsis;white-space:nowrap;color:#fff;min-width:0;font-size:12px;line-height:18px;overflow:hidden}.qikqja_adArrow{color:#fff;flex-shrink:0;margin-left:auto;font-size:13px}.qikqja_searchRow{padding:0 2px;display:flex}.qikqja_search{width:50%;color:inherit;border:1px solid var(--hub-border-2);background:0 0;border-radius:6px;outline:none;padding:4px 9px;font-size:12px;line-height:18px;transition:border-color .12s}.qikqja_search::placeholder{color:var(--hub-text-tertiary)}.qikqja_search:focus{border-color:var(--hub-brand)}.qikqja_installedBtn,.qikqja_installedBtnActive,.qikqja_installedBtnDisabled{cursor:pointer;-webkit-user-select:none;user-select:none;border:none;border-radius:6px;flex-shrink:0;align-items:center;gap:5px;height:24px;padding:0 8px;font-size:12px;line-height:22px;transition:color .12s,background .12s;display:inline-flex}.qikqja_installedBtn{color:var(--hub-text-primary);background:0 0}.qikqja_installedBtn:hover{color:var(--hub-text-primary);background:var(--hub-bg-hover)}.qikqja_installedBtnDisabled,.qikqja_installedBtnDisabled:hover{color:var(--hub-text-disabled);cursor:not-allowed;background:0 0}.qikqja_installedBtnDisabled .qikqja_segCount{color:var(--hub-text-disabled);background:#8080800f}.qikqja_installedBtnActive{color:var(--hub-text-on-fill);background:var(--hub-btn-fill)}.qikqja_segCount,.qikqja_segCountActive{text-align:center;border-radius:999px;min-width:14px;padding:0 4px;font-size:10px;line-height:14px}.qikqja_segCount{color:var(--hub-text-tertiary);background:var(--hub-bg-btn)}.qikqja_installedBtnActive .qikqja_segCountActive{color:var(--hub-text-on-fill);background:var(--hub-bg-on-fill)}.qikqja_tabs{border-bottom:1px solid var(--hub-border-1);flex-wrap:wrap;align-items:center;gap:6px;padding:2px 2px 8px;display:flex}.qikqja_tab,.qikqja_tabActive{cursor:pointer;-webkit-user-select:none;user-select:none;border:none;border-radius:999px;flex-shrink:0;align-items:center;gap:6px;padding:3px 10px;font-size:12px;line-height:18px;transition:color .12s,background .12s;display:inline-flex}.qikqja_tab{color:var(--hub-text-secondary);background:0 0}.qikqja_tab:hover{color:var(--hub-text-primary);background:var(--hub-bg-hover)}.qikqja_tabActive{color:var(--hub-text-on-fill);background:var(--hub-btn-fill)}.qikqja_tabCount{text-align:center;min-width:16px;color:var(--hub-text-tertiary);background:var(--hub-bg-btn);border-radius:999px;padding:0 5px;font-size:10px;line-height:14px}.qikqja_tabActive .qikqja_tabCount{color:var(--hub-text-on-fill);background:var(--hub-bg-on-fill)}.qikqja_failBtn{box-sizing:border-box;border:1px solid var(--hub-border-2);height:24px;color:var(--hub-text-primary);background:var(--hub-bg-hover);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:6px;flex-shrink:0;align-items:center;margin-left:auto;padding:0 10px;font-size:12px;line-height:22px;transition:color .12s,background .12s;display:inline-flex;position:relative}.qikqja_failBtn:hover{color:var(--hub-text-primary);background:#80808047}.qikqja_failBadge{z-index:1;text-align:center;color:#fff;background:var(--hub-danger);border-radius:999px;min-width:16px;height:16px;padding:0 5px;font-size:10px;font-weight:600;line-height:16px;position:absolute;top:-16px;right:-7px;box-shadow:0 1px 4px #d1242f66}";
|
|
236
278
|
const tagId$4 = "dsh-plugin/Header.module.css";
|
|
237
279
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
238
280
|
const tag = document.createElement("style");
|
|
@@ -242,40 +284,43 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
242
284
|
document.head.appendChild(tag);
|
|
243
285
|
}
|
|
244
286
|
var Header_module_css_default = {
|
|
245
|
-
"
|
|
246
|
-
"tab": "qikqja_tab",
|
|
247
|
-
"copyIcon": "qikqja_copyIcon",
|
|
287
|
+
"tagline": "qikqja_tagline",
|
|
248
288
|
"filterResults": "qikqja_filterResults",
|
|
249
|
-
"
|
|
250
|
-
"headerRight": "qikqja_headerRight",
|
|
251
|
-
"brandTitle": "qikqja_brandTitle",
|
|
252
|
-
"taglineLink": "qikqja_taglineLink",
|
|
253
|
-
"search": "qikqja_search",
|
|
289
|
+
"adBanner": "qikqja_adBanner",
|
|
254
290
|
"installedBtn": "qikqja_installedBtn",
|
|
255
|
-
"
|
|
256
|
-
"
|
|
257
|
-
"
|
|
291
|
+
"version": "qikqja_version",
|
|
292
|
+
"brandTitle": "qikqja_brandTitle",
|
|
293
|
+
"hubUpdateBadge": "qikqja_hubUpdateBadge",
|
|
294
|
+
"title": "qikqja_title",
|
|
295
|
+
"segCount": "qikqja_segCount",
|
|
296
|
+
"headerTitleRow": "qikqja_headerTitleRow",
|
|
297
|
+
"githubLink": "qikqja_githubLink",
|
|
298
|
+
"headerRight": "qikqja_headerRight",
|
|
258
299
|
"adArrow": "qikqja_adArrow",
|
|
300
|
+
"tabActive": "qikqja_tabActive",
|
|
301
|
+
"copyIcon": "qikqja_copyIcon",
|
|
302
|
+
"tab": "qikqja_tab",
|
|
259
303
|
"controls": "qikqja_controls",
|
|
260
304
|
"installedBtnDisabled": "qikqja_installedBtnDisabled",
|
|
261
|
-
"
|
|
262
|
-
"
|
|
305
|
+
"failBadge": "qikqja_failBadge",
|
|
306
|
+
"taglineLink": "qikqja_taglineLink",
|
|
307
|
+
"search": "qikqja_search",
|
|
263
308
|
"header": "qikqja_header",
|
|
264
|
-
"logoIcon": "qikqja_logoIcon",
|
|
265
|
-
"tabs": "qikqja_tabs",
|
|
266
|
-
"adBanner": "qikqja_adBanner",
|
|
267
|
-
"failBtn": "qikqja_failBtn",
|
|
268
309
|
"githubIcon": "qikqja_githubIcon",
|
|
310
|
+
"tabCount": "qikqja_tabCount",
|
|
311
|
+
"failBtn": "qikqja_failBtn",
|
|
269
312
|
"adBadge": "qikqja_adBadge",
|
|
270
|
-
"
|
|
271
|
-
"
|
|
272
|
-
"title": "qikqja_title",
|
|
313
|
+
"logoIcon": "qikqja_logoIcon",
|
|
314
|
+
"searchRow": "qikqja_searchRow",
|
|
273
315
|
"installedBtnActive": "qikqja_installedBtnActive",
|
|
274
|
-
"
|
|
316
|
+
"adText": "qikqja_adText",
|
|
317
|
+
"root": "qikqja_root",
|
|
318
|
+
"tabs": "qikqja_tabs",
|
|
319
|
+
"aboutBtn": "qikqja_aboutBtn",
|
|
320
|
+
"segCountActive": "qikqja_segCountActive",
|
|
275
321
|
"langBtn": "qikqja_langBtn",
|
|
276
|
-
"
|
|
277
|
-
"
|
|
278
|
-
"searchRow": "qikqja_searchRow"
|
|
322
|
+
"resultCount": "qikqja_resultCount",
|
|
323
|
+
"versionBtn": "qikqja_versionBtn"
|
|
279
324
|
};
|
|
280
325
|
//#endregion
|
|
281
326
|
//#region src/client/lib/failures.ts
|
|
@@ -409,18 +454,28 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
409
454
|
/** 插件中心源码仓库:头部右上角 GitHub 图标的跳转地址 */
|
|
410
455
|
const GITHUB_URL = "https://github.com/dshplugin/dsh-plugin-hub";
|
|
411
456
|
/**
|
|
457
|
+
* Hub 自我更新版本控制中心(Cloudflare Worker:dsh-update)。
|
|
458
|
+
* 发新版后向 Worker 管理接口写入最新版本 + Markdown 变更记录(见
|
|
459
|
+
* dsh-update-worker 的 POST /admin/hub),所有已装用户的「可更新」徽标即时出现,
|
|
460
|
+
* 不再依赖主站目录数据管道(每日刷新 + 重建站点)。
|
|
461
|
+
* 响应:{ version: string | null, publishedAt: string | null, notes: string | {zh,en} | null }
|
|
462
|
+
*/
|
|
463
|
+
const HUB_UPDATE_URL = "https://hub.dsh-plugin.org/hub";
|
|
464
|
+
/** Worker「关注我们」内容接口(同款 Worker,key = hub:about,Markdown 推送非写死)。 */
|
|
465
|
+
const HUB_ABOUT_URL = "https://hub.dsh-plugin.org/about";
|
|
466
|
+
/**
|
|
412
467
|
* 插件当前版本号,供头部标题展示「DSH-Plugin Hub v0.1.1」。
|
|
413
468
|
* tsdown 构建时用 define 把 __PLUGIN_VERSION__ 替换成 package.json 的版本号;
|
|
414
469
|
* node --test 直接 import 本模块时该标识符不存在,typeof 守卫兜底为空串。
|
|
415
470
|
*/
|
|
416
|
-
const PLUGIN_VERSION = "1.1.
|
|
471
|
+
const PLUGIN_VERSION = "1.1.2";
|
|
417
472
|
/** dsh-plugin.org 中文页挂在 /zh/ 前缀下,英文在根路径。 */
|
|
418
473
|
function langPathOf(lang) {
|
|
419
474
|
return lang === "zh" ? "zh/" : "";
|
|
420
475
|
}
|
|
421
476
|
/**
|
|
422
477
|
* 官网详情页两级路径:/plugins/{ownerSlug}/{slug};
|
|
423
|
-
*
|
|
478
|
+
* 缺 ownerSlug 时从 repo 推导(卡片详情按钮与弹窗来源行共用)。
|
|
424
479
|
*/
|
|
425
480
|
function pluginDetailUrl(plugin, langPath) {
|
|
426
481
|
const repo = plugin.source?.repo ?? "";
|
|
@@ -455,7 +510,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
455
510
|
"",
|
|
456
511
|
`## [DSH-Plugin 插件中心](${SITE_URL}) · 安装 Plugin 失败错误信息`,
|
|
457
512
|
`本错误信息由 [dsh-plugin-hub](${GITHUB_URL}) 插件中心的安装程序自动生成,随本次安装失败一并提交。`,
|
|
458
|
-
`- 实际执行的安装命令:\`${command ?? `dsh plugin${env?.profile ? ` --profile ${env.profile}` : ""} add github
|
|
513
|
+
`- 实际执行的安装命令:\`${command ?? `dsh plugin${env?.profile ? ` --profile ${env.profile}` : ""} add git+https://github.com/${repo}.git`}\``,
|
|
459
514
|
`- 执行结果:安装失败,未能安装该插件。`,
|
|
460
515
|
...attempts && attempts.length > 0 ? [
|
|
461
516
|
"",
|
|
@@ -465,7 +520,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
465
520
|
.../\[packaging\]/i.test(message) ? [
|
|
466
521
|
"",
|
|
467
522
|
"## 安装方式说明",
|
|
468
|
-
"DSH 插件支持两种官方安装通道:`dsh plugin add <npm-package>`(npm 分发,需发布完整构建产物)与 `dsh plugin add github
|
|
523
|
+
"DSH 插件支持两种官方安装通道:`dsh plugin add <npm-package>`(npm 分发,需发布完整构建产物)与 `dsh plugin add git+https://github.com/owner/repo.git`(Git 直装,仓库需提交构建产物或在 package.json 提供 `prepare` 脚本)。当前插件的分发物缺少 package.json 声明的入口文件,请按所用通道补齐后重新发布。"
|
|
469
524
|
] : [],
|
|
470
525
|
"",
|
|
471
526
|
"## Environment",
|
|
@@ -540,6 +595,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
540
595
|
repo: typeof raw.r.repo === "string" ? raw.r.repo : void 0,
|
|
541
596
|
npmPackage: typeof raw.r.npmPackage === "string" ? raw.r.npmPackage : void 0
|
|
542
597
|
} : void 0,
|
|
598
|
+
install: raw.wi === false ? { webInstallable: false } : void 0,
|
|
543
599
|
compatibility: typeof raw.v === "string" ? { status: raw.v } : void 0,
|
|
544
600
|
dates: {
|
|
545
601
|
repoUpdatedAt: typeof raw.u === "string" ? raw.u : void 0,
|
|
@@ -569,10 +625,25 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
569
625
|
via: "github"
|
|
570
626
|
};
|
|
571
627
|
}
|
|
572
|
-
/** 展示用安装命令(复制/弹窗):npm 通道显示包名,git
|
|
628
|
+
/** 展示用安装命令(复制/弹窗):npm 通道显示包名,git 通道显示显式 HTTPS URL。 */
|
|
573
629
|
function installCommandOf(p, withProfile = false) {
|
|
574
630
|
const { target, via } = installTargetOf(p);
|
|
575
|
-
return via === "npm" ? `dsh plugin${withProfile ? " --profile web" : ""} add ${target}` : `dsh plugin${withProfile ? " --profile web" : ""} add github
|
|
631
|
+
return via === "npm" ? `dsh plugin${withProfile ? " --profile web" : ""} add ${target}` : `dsh plugin${withProfile ? " --profile web" : ""} add git+https://github.com/${target}.git`;
|
|
632
|
+
}
|
|
633
|
+
/** Normalize a task/install target to its owner/repo display identity. */
|
|
634
|
+
function repoFromInstallTarget(value) {
|
|
635
|
+
const input = value.trim();
|
|
636
|
+
if (/^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/.test(input)) return input;
|
|
637
|
+
for (const pattern of [
|
|
638
|
+
/^github:([^/]+)\/([^/]+)$/i,
|
|
639
|
+
/^(?:git\+)?https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:[?#].*)?$/i,
|
|
640
|
+
/^(?:git\+)?ssh:\/\/(?:git@)?github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:[?#].*)?$/i,
|
|
641
|
+
/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?(?:[?#].*)?$/i
|
|
642
|
+
]) {
|
|
643
|
+
const match = pattern.exec(input);
|
|
644
|
+
if (match !== null) return `${match[1]}/${match[2]}`;
|
|
645
|
+
}
|
|
646
|
+
return value;
|
|
576
647
|
}
|
|
577
648
|
const CATEGORY_LABELS = {
|
|
578
649
|
interface: {
|
|
@@ -683,6 +754,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
683
754
|
//#endregion
|
|
684
755
|
//#region src/client/hooks/useCatalog.ts
|
|
685
756
|
/**
|
|
757
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
758
|
+
* Website: https://dsh-plugin.org
|
|
759
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
760
|
+
*
|
|
686
761
|
* Catalog data + view state for the Plugin Hub section.
|
|
687
762
|
*
|
|
688
763
|
* Owns the online-data pipeline (live fetch from dsh-plugin.org), the local
|
|
@@ -691,6 +766,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
691
766
|
*/
|
|
692
767
|
const PLUGINS_URL = (lang) => `https://dsh-plugin.org/api/plugins.${lang}.json`;
|
|
693
768
|
const STATS_URL = "https://dsh-plugin.org/api/stats.json";
|
|
769
|
+
/** 插件市场自身仓库:DSH-Plugin Hub 不显示在目录里(自己不进自己的插件列表) */
|
|
770
|
+
const SELF_REPO = "dshplugin/dsh-plugin-hub";
|
|
694
771
|
function useCatalog(lang) {
|
|
695
772
|
/** 目录插件(仅保留人工验证通过的条目) */
|
|
696
773
|
const [plugins, setPlugins] = (0, react.useState)(null);
|
|
@@ -708,6 +785,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
708
785
|
/** 安装时记录的目录信号:repo(小写) -> { version, updatedAt }(来自宿主本地路由);
|
|
709
786
|
* npmPackage 为 npm 优先通道反查命中的包名映射(目录数据未下发时客户端靠它把依赖 key 匹配回仓库) */
|
|
710
787
|
const [versions, setVersions] = (0, react.useState)({});
|
|
788
|
+
/** Hub 自我更新信息:来自 CF Worker 版本控制中心(hub.dsh-plugin.org),与目录数据解耦 */
|
|
789
|
+
const [hubUpdateInfo, setHubUpdateInfo] = (0, react.useState)(null);
|
|
790
|
+
/** 头部「关注我们」弹窗内容(平台介绍 + 反馈群二维码):来自同款 Worker /about,Markdown 推送非写死 */
|
|
791
|
+
const [hubAboutInfo, setHubAboutInfo] = (0, react.useState)(null);
|
|
711
792
|
(0, react.useEffect)(() => {
|
|
712
793
|
let cancelled = false;
|
|
713
794
|
setPlugins(null);
|
|
@@ -717,20 +798,23 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
717
798
|
if (!res.ok) throw new Error(String(res.status));
|
|
718
799
|
return res.json();
|
|
719
800
|
});
|
|
720
|
-
fetchData(PLUGINS_URL(lang))
|
|
801
|
+
const load = () => Promise.all([fetchData(PLUGINS_URL(lang)), fetchData(STATS_URL)]);
|
|
802
|
+
load().then(([data, s]) => {
|
|
721
803
|
if (cancelled) return;
|
|
722
804
|
const list = (Array.isArray(data) ? data : []).map((item) => normalize(item));
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
if (!cancelled) setFailed(true);
|
|
726
|
-
});
|
|
727
|
-
fetchData(STATS_URL).then((s) => {
|
|
805
|
+
const hadSelf = list.some((p) => p.source?.repo === SELF_REPO);
|
|
806
|
+
setPlugins(list.filter((p) => p.compatibility?.status === "verified" && p.source?.repo !== SELF_REPO));
|
|
728
807
|
const stats = s;
|
|
729
|
-
if (
|
|
808
|
+
if (stats && typeof stats.total === "number" && typeof stats.verified === "number") setStats(hadSelf ? {
|
|
809
|
+
total: stats.total - 1,
|
|
810
|
+
verified: stats.verified - 1
|
|
811
|
+
} : {
|
|
730
812
|
total: stats.total,
|
|
731
813
|
verified: stats.verified
|
|
732
814
|
});
|
|
733
|
-
}).catch(() => {
|
|
815
|
+
}).catch(() => {
|
|
816
|
+
if (!cancelled) setFailed(true);
|
|
817
|
+
});
|
|
734
818
|
return () => {
|
|
735
819
|
cancelled = true;
|
|
736
820
|
};
|
|
@@ -748,12 +832,52 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
748
832
|
(0, react.useEffect)(() => {
|
|
749
833
|
refreshInstalled();
|
|
750
834
|
}, []);
|
|
751
|
-
|
|
835
|
+
(0, react.useEffect)(() => {
|
|
836
|
+
let cancelled = false;
|
|
837
|
+
fetch(HUB_UPDATE_URL, { cache: "no-store" }).then((res) => res.ok ? res.json() : Promise.resolve(null)).then((data) => {
|
|
838
|
+
if (cancelled || !data) {
|
|
839
|
+
if (!cancelled) setHubUpdateInfo(null);
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
const version = typeof data.version === "string" && data.version.length > 0 ? data.version : null;
|
|
843
|
+
setHubUpdateInfo(version === null ? null : {
|
|
844
|
+
version,
|
|
845
|
+
publishedAt: data.publishedAt ?? null,
|
|
846
|
+
notes: data.notes ?? null
|
|
847
|
+
});
|
|
848
|
+
}).catch(() => {
|
|
849
|
+
if (!cancelled) setHubUpdateInfo(null);
|
|
850
|
+
});
|
|
851
|
+
return () => {
|
|
852
|
+
cancelled = true;
|
|
853
|
+
};
|
|
854
|
+
}, [reloadKey]);
|
|
855
|
+
(0, react.useEffect)(() => {
|
|
856
|
+
let cancelled = false;
|
|
857
|
+
fetch(HUB_ABOUT_URL, { cache: "no-store" }).then((res) => res.ok ? res.json() : Promise.resolve(null)).then((data) => {
|
|
858
|
+
if (cancelled) return;
|
|
859
|
+
if (!data || data.content === null || data.content === void 0) {
|
|
860
|
+
setHubAboutInfo(null);
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
const content = typeof data.content === "string" || typeof data.content === "object" ? data.content : null;
|
|
864
|
+
setHubAboutInfo(content === null ? null : {
|
|
865
|
+
content,
|
|
866
|
+
updatedAt: data.updatedAt ?? null
|
|
867
|
+
});
|
|
868
|
+
}).catch(() => {
|
|
869
|
+
if (!cancelled) setHubAboutInfo(null);
|
|
870
|
+
});
|
|
871
|
+
return () => {
|
|
872
|
+
cancelled = true;
|
|
873
|
+
};
|
|
874
|
+
}, [reloadKey]);
|
|
875
|
+
/** 插件是否已安装:匹配 Git spec 中的 owner/repo,或 npm 通道安装的依赖包名;命中返回 npm 包名。 */
|
|
752
876
|
const installedName = (p) => {
|
|
753
877
|
const repo = p.source?.repo;
|
|
754
878
|
if (!repo) return null;
|
|
755
|
-
const needle =
|
|
756
|
-
for (const [name, spec] of Object.entries(installed)) if (spec.toLowerCase()
|
|
879
|
+
const needle = repo.toLowerCase();
|
|
880
|
+
for (const [name, spec] of Object.entries(installed)) if (repoFromInstallTarget(spec).toLowerCase() === needle) return name;
|
|
757
881
|
const pkg = ((p.source?.npmPackage || versions[repo.toLowerCase()]?.npmPackage) ?? "").toLowerCase();
|
|
758
882
|
if (pkg) {
|
|
759
883
|
for (const name of Object.keys(installed)) if (name.toLowerCase() === pkg) return name;
|
|
@@ -781,6 +905,16 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
781
905
|
const current = p.dates?.repoUpdatedAt;
|
|
782
906
|
return Boolean(current && rec.updatedAt && current > rec.updatedAt);
|
|
783
907
|
};
|
|
908
|
+
/**
|
|
909
|
+
* Hub 自身是否有可用更新:Hub 就是当前运行的应用(始终已安装,无需 installedName 命中)。
|
|
910
|
+
* 以 Worker 版本控制中心返回的「最新版本」为准,与当前运行的版本号比对——
|
|
911
|
+
* 构建时注入的 PLUGIN_VERSION 是运行 bundle 的真实版本;测试/异常场景缺失时
|
|
912
|
+
* 回退到安装时记录的版本。版本号不等即新版(版本号只在发版时变更,绝无降级场景)。
|
|
913
|
+
*/
|
|
914
|
+
const hubHasUpdate = (() => {
|
|
915
|
+
if (!hubUpdateInfo) return false;
|
|
916
|
+
return hubUpdateInfo.version !== "1.1.2";
|
|
917
|
+
})();
|
|
784
918
|
/** 当前分类下的插件(「全部」时为整个目录)。 */
|
|
785
919
|
const categoryPlugins = (0, react.useMemo)(() => {
|
|
786
920
|
if (!plugins) return [];
|
|
@@ -839,6 +973,9 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
839
973
|
installedName,
|
|
840
974
|
installedVersion,
|
|
841
975
|
hasUpdate,
|
|
976
|
+
hubHasUpdate,
|
|
977
|
+
hubUpdateInfo,
|
|
978
|
+
hubAboutInfo,
|
|
842
979
|
refreshInstalled,
|
|
843
980
|
category,
|
|
844
981
|
setCategory,
|
|
@@ -858,6 +995,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
858
995
|
//#endregion
|
|
859
996
|
//#region src/client/hooks/useTaskQueue.ts
|
|
860
997
|
/**
|
|
998
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
999
|
+
* Website: https://dsh-plugin.org
|
|
1000
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
1001
|
+
*
|
|
861
1002
|
* Background install/remove task queue for the Plugin Hub.
|
|
862
1003
|
*
|
|
863
1004
|
* Mirrors the server-side FIFO active queue by polling /active, settles
|
|
@@ -908,7 +1049,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
908
1049
|
queueRef.current = next;
|
|
909
1050
|
setQueue(next);
|
|
910
1051
|
};
|
|
911
|
-
/**
|
|
1052
|
+
/** 解析服务端待重启列表(安装目标归一化为 owner/repo,与安装任务对齐)。 */
|
|
912
1053
|
const parsePendingRestarts = (value) => {
|
|
913
1054
|
if (!Array.isArray(value)) return [];
|
|
914
1055
|
const out = [];
|
|
@@ -918,7 +1059,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
918
1059
|
if (typeof target !== "string" || target === "") continue;
|
|
919
1060
|
const at = x.at;
|
|
920
1061
|
out.push({
|
|
921
|
-
target: target
|
|
1062
|
+
target: repoFromInstallTarget(target),
|
|
922
1063
|
kind: x.kind === "uninstall" ? "uninstall" : "install",
|
|
923
1064
|
at: typeof at === "number" ? at : 0
|
|
924
1065
|
});
|
|
@@ -967,14 +1108,14 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
967
1108
|
refreshInstalled();
|
|
968
1109
|
if (q.kind === "uninstall") {
|
|
969
1110
|
syncInstalledVersion(q.repo, void 0, void 0);
|
|
970
|
-
onUninstallDone(modalTaskRef.current === q.id, q.repo);
|
|
1111
|
+
onUninstallDone(modalTaskRef.current === q.id, q.repo, q.needsRestart);
|
|
971
1112
|
} else {
|
|
972
1113
|
syncInstalledVersion(q.repo, q.version, q.updatedAt);
|
|
973
1114
|
pendingInfoRef.current.set(q.target, {
|
|
974
1115
|
desc: q.desc,
|
|
975
1116
|
version: q.version
|
|
976
1117
|
});
|
|
977
|
-
onInstallDone(modalTaskRef.current === q.id, q.repo);
|
|
1118
|
+
onInstallDone(modalTaskRef.current === q.id, q.repo, q.needsRestart);
|
|
978
1119
|
}
|
|
979
1120
|
} else {
|
|
980
1121
|
const detail = lines.length > 0 ? [...lines].reverse().join("\n") : q.kind === "uninstall" ? t("uninstallFail") : t("installFail");
|
|
@@ -1017,23 +1158,33 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1017
1158
|
try {
|
|
1018
1159
|
const res = await fetch(`/dsh-plugin-hub/status?task=${q.id}`, { cache: "no-store" });
|
|
1019
1160
|
if (res.ok) {
|
|
1020
|
-
const
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1161
|
+
const task = (await res.json()).task;
|
|
1162
|
+
if (task !== void 0) {
|
|
1163
|
+
status = task.status ?? "failed";
|
|
1164
|
+
lines = task.lines ?? [];
|
|
1165
|
+
attempts = Array.isArray(task.attempts) ? task.attempts : void 0;
|
|
1166
|
+
const needsRestart = typeof task.needsRestart === "boolean" ? task.needsRestart : q.needsRestart;
|
|
1167
|
+
if (status === "done") {
|
|
1168
|
+
const settled = {
|
|
1169
|
+
...q,
|
|
1170
|
+
needsRestart
|
|
1171
|
+
};
|
|
1172
|
+
if (q.kind === "uninstall") settleDone(settled, lines);
|
|
1173
|
+
else finishQueueTask(true, settled, lines);
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
if (status === "failed") {
|
|
1177
|
+
finishQueueTask(false, {
|
|
1178
|
+
...q,
|
|
1179
|
+
attempts
|
|
1180
|
+
}, lines);
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1024
1184
|
}
|
|
1025
1185
|
} catch {}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
else finishQueueTask(true, q, lines);
|
|
1029
|
-
} else if (status === "failed") finishQueueTask(false, {
|
|
1030
|
-
...q,
|
|
1031
|
-
attempts
|
|
1032
|
-
}, lines);
|
|
1033
|
-
else {
|
|
1034
|
-
applyQueue((prev) => prev.filter((x) => x.id !== q.id));
|
|
1035
|
-
maybeStopPoll();
|
|
1036
|
-
}
|
|
1186
|
+
applyQueue((prev) => prev.filter((x) => x.id !== q.id));
|
|
1187
|
+
maybeStopPoll();
|
|
1037
1188
|
};
|
|
1038
1189
|
/** 轮询整个队列:合并服务端 /active(running 在前、pending 在后),
|
|
1039
1190
|
* 消失的任务查终态收尾;队列清空即停止轮询。 */
|
|
@@ -1057,15 +1208,16 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1057
1208
|
next.push({
|
|
1058
1209
|
id,
|
|
1059
1210
|
kind: isRemove ? "uninstall" : "install",
|
|
1060
|
-
target: typeof a.target === "string" ? a.target
|
|
1211
|
+
target: typeof a.target === "string" ? repoFromInstallTarget(a.target) : prevTask?.target ?? "",
|
|
1061
1212
|
desc: prevTask?.desc,
|
|
1062
|
-
repo: prevTask?.repo ?? (isRemove ? null : typeof a.target === "string" ? a.target
|
|
1213
|
+
repo: prevTask?.repo ?? (isRemove ? null : typeof a.target === "string" ? repoFromInstallTarget(a.target) : null),
|
|
1063
1214
|
version: prevTask?.version,
|
|
1064
1215
|
updatedAt: prevTask?.updatedAt,
|
|
1065
1216
|
status: a.status === "running" ? "running" : "pending",
|
|
1066
1217
|
progress: typeof a.progress === "number" ? a.progress : prevTask?.progress ?? 0,
|
|
1067
1218
|
lines: Array.isArray(a.lines) ? a.lines : prevTask?.lines ?? [],
|
|
1068
|
-
attempts: Array.isArray(a.attempts) ? a.attempts : prevTask?.attempts ?? []
|
|
1219
|
+
attempts: Array.isArray(a.attempts) ? a.attempts : prevTask?.attempts ?? [],
|
|
1220
|
+
needsRestart: typeof a.needsRestart === "boolean" ? a.needsRestart : prevTask?.needsRestart ?? true
|
|
1069
1221
|
});
|
|
1070
1222
|
}
|
|
1071
1223
|
const keepOpt = prev.filter((q) => q.optimistic && !next.some((x) => x.id === q.id));
|
|
@@ -1098,8 +1250,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1098
1250
|
applyPending(parsePendingRestarts(data.pendingRestarts));
|
|
1099
1251
|
const items = (data.tasks ?? []).filter((a) => typeof a.id === "number").map((a) => {
|
|
1100
1252
|
const isRemove = a.action === "remove";
|
|
1101
|
-
const display = typeof a.displayTarget === "string" ? a.displayTarget
|
|
1102
|
-
const fallback = typeof a.target === "string" ? a.target
|
|
1253
|
+
const display = typeof a.displayTarget === "string" ? repoFromInstallTarget(a.displayTarget) : "";
|
|
1254
|
+
const fallback = typeof a.target === "string" ? repoFromInstallTarget(a.target) : "";
|
|
1103
1255
|
return {
|
|
1104
1256
|
id: a.id,
|
|
1105
1257
|
kind: isRemove ? "uninstall" : "install",
|
|
@@ -1108,7 +1260,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1108
1260
|
status: a.status === "running" ? "running" : "pending",
|
|
1109
1261
|
progress: typeof a.progress === "number" ? a.progress : 0,
|
|
1110
1262
|
lines: Array.isArray(a.lines) ? a.lines : [],
|
|
1111
|
-
attempts: Array.isArray(a.attempts) ? a.attempts : []
|
|
1263
|
+
attempts: Array.isArray(a.attempts) ? a.attempts : [],
|
|
1264
|
+
needsRestart: typeof a.needsRestart === "boolean" ? a.needsRestart : true
|
|
1112
1265
|
};
|
|
1113
1266
|
});
|
|
1114
1267
|
if (items.length > 0 || pendingRef.current.length > 0) {
|
|
@@ -1147,7 +1300,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1147
1300
|
lines: [],
|
|
1148
1301
|
optimistic: true,
|
|
1149
1302
|
command: installCommandOf(p, true),
|
|
1150
|
-
attempts: []
|
|
1303
|
+
attempts: [],
|
|
1304
|
+
needsRestart: true
|
|
1151
1305
|
}]);
|
|
1152
1306
|
setSubmitting(true);
|
|
1153
1307
|
try {
|
|
@@ -1219,7 +1373,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1219
1373
|
repo,
|
|
1220
1374
|
status: "pending",
|
|
1221
1375
|
progress: 0,
|
|
1222
|
-
lines: []
|
|
1376
|
+
lines: [],
|
|
1377
|
+
needsRestart: true
|
|
1223
1378
|
}]);
|
|
1224
1379
|
pollQueue();
|
|
1225
1380
|
} catch {
|
|
@@ -1266,7 +1421,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1266
1421
|
}
|
|
1267
1422
|
//#endregion
|
|
1268
1423
|
//#region \0dsh-css:src/client/styles/Modal.module.css.mjs
|
|
1269
|
-
const css$3 = ".BiQ1zG_overlay{z-index:998;-webkit-user-select:none;user-select:none;background:#00000061;justify-content:center;align-items:center;animation:.16s ease-out BiQ1zG_overlayIn;display:flex;position:fixed;top:0;bottom:0;left:0;right:0}.BiQ1zG_modal,.BiQ1zG_errorModal{background:var(--hub-bg-1);border:1px solid var(--hub-border-2);border-radius:10px;flex-direction:column;gap:10px;width:420px;max-width:calc(100vw - 32px);max-height:calc(100vh - 64px);padding:14px 16px;animation:.18s ease-out BiQ1zG_modalIn;display:flex;box-shadow:0 12px 40px #0000003d}.BiQ1zG_errorModal{width:640px;max-width:calc(100vw - 48px)}.BiQ1zG_modalHead{flex-shrink:0;justify-content:space-between;align-items:center;gap:8px;display:flex}.BiQ1zG_modalTitle{color:var(--hub-text-primary);font-size:14px;font-weight:600;line-height:20px}.BiQ1zG_modalTitleBusy{color:var(--hub-brand)}.BiQ1zG_modalTitleQueued{color:var(--hub-warning)}.BiQ1zG_modalClose{width:24px;height:24px;color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;font-size:16px;line-height:1;display:inline-flex}.BiQ1zG_modalClose:hover{color:var(--hub-text-primary);background:var(--hub-bg-hover)}.BiQ1zG_modalCloseIcon{flex-shrink:0;width:14px;height:14px}.BiQ1zG_modalDesc{color:var(--hub-text-secondary);font-size:12px;line-height:18px}.BiQ1zG_trustHint{color:var(--hub-danger-text);background:var(--hub-danger-tint);border:1px solid var(--hub-danger-border-soft);border-radius:6px;padding:6px 10px;font-size:12px;font-weight:500;line-height:18px}.BiQ1zG_modalRow{align-items:baseline;gap:8px;min-width:0;font-size:12px;line-height:18px;display:flex}.BiQ1zG_modalLabel{min-width:64px;color:var(--hub-text-tertiary);flex-shrink:0}.BiQ1zG_modalValue{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--hub-text-primary);font-weight:500;overflow:hidden}.BiQ1zG_modalLink{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--hub-brand);cursor:pointer;-webkit-user-select:none;user-select:none;align-items:center;gap:4px;font-weight:500;text-decoration:none;transition:color .12s;display:inline-flex;overflow:hidden}.BiQ1zG_modalLink:hover{color:var(--hub-brand-hover);text-decoration:underline}.BiQ1zG_linkIcon{flex-shrink:0}.BiQ1zG_modalCmd{color:var(--hub-text-primary);background:var(--hub-bg-2);border:1px solid var(--hub-border-2);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:6px;justify-content:space-between;align-items:center;gap:8px;padding:6px 6px 6px 10px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;line-height:18px;transition:border-color .12s,background .12s;display:flex}.BiQ1zG_modalCmd:hover{border-color:var(--hub-border-ghost);background:var(--hub-bg-3)}.BiQ1zG_modalCmdText{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.BiQ1zG_modalCmdCopy{color:var(--hub-brand);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:4px;flex-shrink:0;align-items:center;gap:3px;padding:1px 7px;font-family:inherit;font-size:11px;line-height:16px;transition:color .12s,background .12s;display:inline-flex}.BiQ1zG_modalCmdCopy:hover{color:var(--hub-brand-hover);background:var(--hub-bg-2)}.BiQ1zG_modalActions{justify-content:flex-end;align-items:center;gap:8px;margin-top:2px;display:flex}.BiQ1zG_modalBody{flex-direction:column;flex:auto;gap:10px;min-height:0;display:flex;overflow-y:auto}.BiQ1zG_toast{z-index:1000;background:var(--hub-btn-fill);color:var(--hub-text-on-fill);pointer-events:none;white-space:nowrap;border:none;border-radius:8px;padding:10px 16px;font-size:12px;font-weight:500;line-height:18px;animation:.22s ease-out BiQ1zG_toastIn;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);box-shadow:0 6px 24px #00000047}@keyframes BiQ1zG_toastIn{0%{opacity:0;transform:translate(-50%,-44%)}to{opacity:1;transform:translate(-50%,-50%)}}.BiQ1zG_toastFail{background:var(--hub-danger);color:#fff;border-color:#ffffff3d}.BiQ1zG_queueSection{flex-direction:column;gap:6px;display:flex}.BiQ1zG_queueSectionTitle{color:var(--hub-text-secondary);padding:4px 2px 0;font-size:12px;font-weight:600;line-height:18px}.BiQ1zG_pendingRowStatus{color:var(--hub-warn);flex-shrink:0;font-weight:500}.BiQ1zG_pendingRowActions{flex-shrink:0;gap:8px;margin-left:auto;display:flex}.BiQ1zG_queueRow{border:1px solid var(--hub-border-2);background:var(--hub-bg-2);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:8px;flex-direction:column;gap:5px;padding:8px 10px;font-size:12px;line-height:18px;transition:background .12s;display:flex}.BiQ1zG_queueRow:hover{background:var(--hub-brand-tint)}.BiQ1zG_queueRowHead{align-items:center;gap:10px;display:flex}.BiQ1zG_queueRowTarget{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--hub-text-primary);flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow:hidden}.BiQ1zG_queueRowDesc{color:var(--hub-text-tertiary);-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.BiQ1zG_queueRowBody{align-items:center;gap:8px;display:flex}.BiQ1zG_queueRowStatus{color:var(--hub-brand);flex-shrink:0;font-weight:500}.BiQ1zG_queueRowTrack{flex:1;min-width:0}.BiQ1zG_queueRowPct{color:var(--hub-text-tertiary);font-variant-numeric:tabular-nums;flex-shrink:0}.BiQ1zG_stripCancel{color:var(--hub-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;flex-shrink:0;padding:2px 10px;font-size:12px;line-height:18px;transition:background .12s,color .12s}.BiQ1zG_stripCancel:hover{background:var(--hub-danger-tint);color:var(--hub-danger-text)}.BiQ1zG_stripCancel:disabled{opacity:.45;cursor:default}.BiQ1zG_queuedHint{color:var(--hub-brand);background:var(--hub-brand-tint);border:1px solid var(--hub-brand-border-soft);border-radius:6px;padding:5px 10px;font-size:12px;line-height:18px}.BiQ1zG_errorTitle{color:var(--hub-danger-text);font-size:14px;font-weight:600;line-height:20px}.BiQ1zG_errorBox{border:1px solid var(--hub-danger-border);background:var(--hub-danger-tint-weak);max-height:240px;color:var(--hub-text-primary);white-space:pre-wrap;word-break:break-word;-webkit-user-select:none;user-select:none;border-radius:6px;margin:0;padding:10px 12px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;line-height:17px;overflow:auto}.BiQ1zG_errorCopySoft{color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:4px;flex-shrink:0;align-items:center;padding:2px 8px;font-size:11px;line-height:16px;transition:color .12s,background .12s;display:inline-flex}.BiQ1zG_errorCopySoft:hover{color:var(--hub-text-secondary);background:var(--hub-bg-2)}.BiQ1zG_errorHint{color:var(--hub-text-tertiary);font-size:12px;line-height:18px}.BiQ1zG_modalCancel,.BiQ1zG_modalCopy{color:var(--hub-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;padding:5px 14px;font-size:12px;line-height:18px;transition:color .12s,background .12s}.BiQ1zG_modalCancel:hover,.BiQ1zG_modalCopy:hover{color:var(--hub-text-primary);background:var(--hub-bg-hover)}.BiQ1zG_modalInstall{color:var(--hub-text-on-fill);background:var(--hub-btn-fill);cursor:pointer;-webkit-user-select:none;user-select:none;border:none;border-radius:6px;padding:5px 14px;font-size:12px;font-weight:600;line-height:18px;transition:background .12s}.BiQ1zG_modalInstall:hover{background:var(--hub-btn-hover)}.BiQ1zG_modalCopy:disabled,.BiQ1zG_modalInstall:disabled,.BiQ1zG_modalCancel:disabled,.BiQ1zG_modalClose:disabled,.BiQ1zG_uninstallConfirm:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.BiQ1zG_uninstallConfirm{color:#fff;background:var(--hub-danger);cursor:pointer;-webkit-user-select:none;user-select:none;border:none;border-radius:6px;padding:5px 14px;font-size:12px;font-weight:600;line-height:18px;transition:background .12s}.BiQ1zG_uninstallConfirm:hover{background:var(--hub-danger-hover)}.BiQ1zG_result{text-align:center;flex-direction:column;align-items:center;gap:5px;padding:10px 0 2px;display:flex}.BiQ1zG_resultCheck{background:var(--hub-success-tint);width:40px;height:40px;color:var(--hub-success);border-radius:50%;justify-content:center;align-items:center;margin-bottom:3px;display:inline-flex}.BiQ1zG_resultCheckIcon{flex-shrink:0;width:20px;height:20px}.BiQ1zG_resultTitle{color:var(--hub-text-primary);font-size:13px;font-weight:600;line-height:20px}.BiQ1zG_resultDesc{color:var(--hub-text-secondary);font-size:12px;line-height:18px}.BiQ1zG_resultRestarting{color:var(--hub-text-tertiary);padding:12px 0 6px;font-size:12px;line-height:18px}.BiQ1zG_restartLater{color:var(--hub-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;padding:5px 14px;font-size:12px;line-height:18px;transition:color .12s,background .12s}.BiQ1zG_restartLater:hover{color:var(--hub-text-primary);background:var(--hub-bg-hover)}.BiQ1zG_restartNow{color:var(--hub-text-on-fill);background:var(--hub-btn-fill);cursor:pointer;-webkit-user-select:none;user-select:none;border:none;border-radius:6px;padding:5px 14px;font-size:12px;font-weight:600;line-height:18px;transition:background .12s}.BiQ1zG_restartNow:hover{background:var(--hub-btn-hover)}.BiQ1zG_restartNow:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.BiQ1zG_result .BiQ1zG_modalActions{justify-content:center;gap:10px;margin-top:0;padding:6px 0 2px}.BiQ1zG_result .BiQ1zG_modalActions .BiQ1zG_restartLater,.BiQ1zG_result .BiQ1zG_modalActions .BiQ1zG_restartNow{min-width:100px}.BiQ1zG_progress{margin:10px 0 2px}.BiQ1zG_progressHead{justify-content:flex-end;align-items:center;margin-bottom:3px;display:flex}.BiQ1zG_progressText{color:var(--hub-text-secondary);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;line-height:14px}.BiQ1zG_progressTrack{background:var(--hub-border-2);border-radius:2px;height:4px;overflow:hidden}.BiQ1zG_progressFill{background:var(--hub-brand);border-radius:2px;height:100%;transition:width .32s}.BiQ1zG_progressFillFail{background:var(--hub-danger)}@keyframes BiQ1zG_overlayIn{0%{opacity:0}to{opacity:1}}@keyframes BiQ1zG_modalIn{0%{opacity:0;transform:translateY(6px)scale(.98)}to{opacity:1;transform:translateY(0)scale(1)}}.BiQ1zG_noticeList{flex-direction:column;gap:10px;padding-right:2px;display:flex}.BiQ1zG_noticeRow{border:1px solid var(--hub-border-2);background:var(--hub-bg-2);border-radius:8px;flex-direction:column;align-items:stretch;gap:6px;padding:10px 12px;display:flex}.BiQ1zG_noticeRowMain{align-items:center;gap:10px;width:100%;min-width:0;display:flex}.BiQ1zG_noticeBadgeOk,.BiQ1zG_noticeBadgeFail{border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:28px;height:28px;display:inline-flex;box-shadow:0 2px 6px #0000002e}.BiQ1zG_noticeBadgeOk{background:var(--hub-success)}.BiQ1zG_noticeBadgeFail{background:var(--hub-danger)}.BiQ1zG_noticeBadgeIcon{flex-shrink:0;width:12px;height:12px}.BiQ1zG_noticeMain{flex-direction:column;flex:1;gap:8px;min-width:0;display:flex}.BiQ1zG_noticeHead{align-items:center;gap:8px;min-width:0;display:flex}.BiQ1zG_noticeTextOk{color:var(--hub-success);flex-shrink:0;font-size:12px;font-weight:600;line-height:18px}.BiQ1zG_noticeTextFail{color:var(--hub-danger-text);flex-shrink:0;font-size:12px;font-weight:600;line-height:18px}.BiQ1zG_failList{flex-direction:column;gap:12px;padding-right:2px;display:flex}.BiQ1zG_failRow{border:1px solid var(--hub-border-2);background:var(--hub-bg-2);border-radius:8px;flex-direction:column;gap:8px;padding:10px 12px;display:flex}.BiQ1zG_failHead{align-items:center;gap:8px;min-width:0;display:flex}.BiQ1zG_failKind{border:1px solid #0000;border-radius:4px;flex-shrink:0;padding:0 6px;font-size:10px;font-weight:500;line-height:16px}.BiQ1zG_failKindInstall{color:var(--hub-danger-text);border-color:var(--hub-danger-border);background:var(--hub-danger-tint)}.BiQ1zG_failKindUninstall{color:var(--hub-warn);border-color:var(--hub-warn-border);background:var(--hub-warn-tint)}.BiQ1zG_failRepo{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--hub-brand);cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:18px;text-decoration:none;overflow:hidden}.BiQ1zG_failRepo:hover{text-decoration:underline}.BiQ1zG_noticeFoot{justify-content:flex-end;align-items:center;display:flex}.BiQ1zG_noticeTime{color:var(--hub-text-tertiary);font-variant-numeric:tabular-nums;flex-shrink:0;font-size:11px;line-height:16px}.BiQ1zG_noticeRemove{width:22px;height:22px;color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:5px;flex-shrink:0;justify-content:center;align-items:center;margin-left:auto;transition:color .12s,background .12s;display:inline-flex}.BiQ1zG_noticeRemove:hover{color:var(--hub-danger-text);background:var(--hub-danger-tint)}.BiQ1zG_failCopy{color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:4px;flex-shrink:0;align-items:center;padding:2px 8px;font-size:11px;line-height:16px;transition:color .12s,background .12s;display:inline-flex}.BiQ1zG_failCopy:hover{color:var(--hub-text-secondary);background:var(--hub-bg-2)}.BiQ1zG_failEmpty{text-align:center;color:var(--hub-text-tertiary);padding:24px 0;font-size:12px;line-height:18px}.BiQ1zG_failClear{color:var(--hub-danger);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;padding:5px 14px;font-size:12px;line-height:18px;transition:color .12s,background .12s}.BiQ1zG_failClear:hover{color:#fff;background:var(--hub-danger)}.BiQ1zG_failBigIssue{box-sizing:border-box;text-align:center;color:#fff;background:var(--hub-danger);border:1px solid var(--hub-danger);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:8px;width:100%;margin-top:4px;padding:3px 16px;font-size:13px;font-weight:600;line-height:18px;text-decoration:none;transition:background .12s,border-color .12s,box-shadow .12s;display:block}.BiQ1zG_failBigIssue:hover{background:var(--hub-danger-hover);border-color:var(--hub-danger-hover);box-shadow:0 3px 10px #d1242f59}.BiQ1zG_failPrepareHint{color:var(--hub-warning);background:var(--hub-warning-tint);border:1px solid var(--hub-warning-border);border-radius:6px;margin-top:6px;padding:8px 12px;font-size:12px;line-height:18px}";
|
|
1424
|
+
const css$3 = ".BiQ1zG_overlay{z-index:998;-webkit-user-select:none;user-select:none;background:#00000061;justify-content:center;align-items:center;animation:.16s ease-out BiQ1zG_overlayIn;display:flex;position:fixed;top:0;bottom:0;left:0;right:0}.BiQ1zG_modal,.BiQ1zG_errorModal{background:var(--hub-bg-1);border:1px solid var(--hub-border-2);border-radius:10px;flex-direction:column;gap:10px;width:420px;max-width:calc(100vw - 32px);max-height:calc(100vh - 64px);padding:14px 16px;animation:.18s ease-out BiQ1zG_modalIn;display:flex;box-shadow:0 12px 40px #0000003d}.BiQ1zG_errorModal{width:640px;max-width:calc(100vw - 48px)}.BiQ1zG_modalHead{flex-shrink:0;justify-content:space-between;align-items:center;gap:8px;display:flex}.BiQ1zG_modalTitle{color:var(--hub-text-primary);font-size:14px;font-weight:600;line-height:20px}.BiQ1zG_modalTitleBusy{color:var(--hub-brand)}.BiQ1zG_modalTitleQueued{color:var(--hub-warning)}.BiQ1zG_modalClose{width:24px;height:24px;color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;flex-shrink:0;justify-content:center;align-items:center;font-size:16px;line-height:1;display:inline-flex}.BiQ1zG_modalClose:hover{color:var(--hub-text-primary);background:var(--hub-bg-hover)}.BiQ1zG_modalCloseIcon{flex-shrink:0;width:14px;height:14px}.BiQ1zG_modalDesc{color:var(--hub-text-secondary);font-size:12px;line-height:18px}.BiQ1zG_trustHint{color:var(--hub-danger-text);background:var(--hub-danger-tint);border:1px solid var(--hub-danger-border-soft);border-radius:6px;padding:6px 10px;font-size:12px;font-weight:500;line-height:18px}.BiQ1zG_cliOnlyHint{color:var(--hub-text-secondary);background:var(--hub-bg-hover);border-radius:6px;padding:6px 10px;font-size:12px;line-height:18px}.BiQ1zG_failedCopyHint{color:var(--hub-danger-text);background:var(--hub-danger-tint);border:1px solid var(--hub-danger-border-soft);border-radius:6px;padding:6px 10px;font-size:12px;font-weight:500;line-height:18px}.BiQ1zG_modalRow{align-items:baseline;gap:8px;min-width:0;font-size:12px;line-height:18px;display:flex}.BiQ1zG_modalLabel{min-width:64px;color:var(--hub-text-tertiary);flex-shrink:0}.BiQ1zG_modalValue{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--hub-text-primary);font-weight:500;overflow:hidden}.BiQ1zG_modalLink{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--hub-brand);cursor:pointer;-webkit-user-select:none;user-select:none;align-items:center;gap:4px;font-weight:500;text-decoration:none;transition:color .12s;display:inline-flex;overflow:hidden}.BiQ1zG_modalLink:hover{color:var(--hub-brand-hover);text-decoration:underline}.BiQ1zG_linkIcon{flex-shrink:0}.BiQ1zG_modalCmd{color:var(--hub-text-primary);background:var(--hub-bg-2);border:1px solid var(--hub-border-2);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:6px;justify-content:space-between;align-items:center;gap:8px;padding:6px 6px 6px 10px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;line-height:18px;transition:border-color .12s,background .12s;display:flex}.BiQ1zG_modalCmd:hover{border-color:var(--hub-border-ghost);background:var(--hub-bg-3)}.BiQ1zG_modalCmdText{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.BiQ1zG_modalCmdCopy{color:var(--hub-brand);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:4px;flex-shrink:0;align-items:center;gap:3px;padding:1px 7px;font-family:inherit;font-size:11px;line-height:16px;transition:color .12s,background .12s;display:inline-flex}.BiQ1zG_modalCmdCopy:hover{color:var(--hub-brand-hover);background:var(--hub-bg-2)}.BiQ1zG_modalActions{justify-content:flex-end;align-items:center;gap:8px;margin-top:2px;display:flex}.BiQ1zG_modalBody{flex-direction:column;flex:auto;gap:10px;min-height:0;display:flex;overflow-y:auto}.BiQ1zG_toast{z-index:1000;background:var(--hub-btn-fill);color:var(--hub-text-on-fill);pointer-events:none;white-space:nowrap;border:none;border-radius:8px;padding:10px 16px;font-size:12px;font-weight:500;line-height:18px;animation:.22s ease-out BiQ1zG_toastIn;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);box-shadow:0 6px 24px #00000047}@keyframes BiQ1zG_toastIn{0%{opacity:0;transform:translate(-50%,-44%)}to{opacity:1;transform:translate(-50%,-50%)}}.BiQ1zG_toastFail{background:var(--hub-danger);color:#fff;border-color:#ffffff3d}.BiQ1zG_queueSection{flex-direction:column;gap:6px;display:flex}.BiQ1zG_queueSectionTitle{color:var(--hub-text-secondary);padding:4px 2px 0;font-size:12px;font-weight:600;line-height:18px}.BiQ1zG_pendingRowStatus{color:var(--hub-warn);flex-shrink:0;font-weight:500}.BiQ1zG_pendingRowActions{flex-shrink:0;gap:8px;margin-left:auto;display:flex}.BiQ1zG_queueRow{border:1px solid var(--hub-border-2);background:var(--hub-bg-2);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:8px;flex-direction:column;gap:5px;padding:8px 10px;font-size:12px;line-height:18px;transition:background .12s;display:flex}.BiQ1zG_queueRow:hover{background:var(--hub-brand-tint)}.BiQ1zG_queueRowHead{align-items:center;gap:10px;display:flex}.BiQ1zG_queueRowTarget{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--hub-text-primary);flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow:hidden}.BiQ1zG_queueRowDesc{color:var(--hub-text-tertiary);-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.BiQ1zG_queueRowBody{align-items:center;gap:8px;display:flex}.BiQ1zG_queueRowStatus{color:var(--hub-brand);flex-shrink:0;font-weight:500}.BiQ1zG_queueRowTrack{flex:1;min-width:0}.BiQ1zG_queueRowPct{color:var(--hub-text-tertiary);font-variant-numeric:tabular-nums;flex-shrink:0}.BiQ1zG_stripCancel{color:var(--hub-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;flex-shrink:0;padding:2px 10px;font-size:12px;line-height:18px;transition:background .12s,color .12s}.BiQ1zG_stripCancel:hover{background:var(--hub-danger-tint);color:var(--hub-danger-text)}.BiQ1zG_stripCancel:disabled{opacity:.45;cursor:default}.BiQ1zG_queuedHint{color:var(--hub-brand);background:var(--hub-brand-tint);border:1px solid var(--hub-brand-border-soft);border-radius:6px;padding:5px 10px;font-size:12px;line-height:18px}.BiQ1zG_errorTitle{color:var(--hub-danger-text);font-size:14px;font-weight:600;line-height:20px}.BiQ1zG_errorBox{border:1px solid var(--hub-danger-border);background:var(--hub-danger-tint-weak);max-height:240px;color:var(--hub-text-primary);white-space:pre-wrap;word-break:break-word;-webkit-user-select:none;user-select:none;border-radius:6px;margin:0;padding:10px 12px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;line-height:17px;overflow:auto}.BiQ1zG_errorCopySoft{color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:4px;flex-shrink:0;align-items:center;padding:2px 8px;font-size:11px;line-height:16px;transition:color .12s,background .12s;display:inline-flex}.BiQ1zG_errorCopySoft:hover{color:var(--hub-text-secondary);background:var(--hub-bg-2)}.BiQ1zG_errorHint{color:var(--hub-text-tertiary);font-size:12px;line-height:18px}.BiQ1zG_modalCancel,.BiQ1zG_modalCopy{color:var(--hub-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;padding:5px 14px;font-size:12px;line-height:18px;transition:color .12s,background .12s}.BiQ1zG_modalCancel:hover,.BiQ1zG_modalCopy:hover{color:var(--hub-text-primary);background:var(--hub-bg-hover)}.BiQ1zG_modalInstall{color:var(--hub-text-on-fill);background:var(--hub-btn-fill);cursor:pointer;-webkit-user-select:none;user-select:none;border:none;border-radius:6px;padding:5px 14px;font-size:12px;font-weight:600;line-height:18px;transition:background .12s}.BiQ1zG_modalInstall:hover{background:var(--hub-btn-hover)}.BiQ1zG_modalCopy:disabled,.BiQ1zG_modalInstall:disabled,.BiQ1zG_modalCancel:disabled,.BiQ1zG_modalClose:disabled,.BiQ1zG_uninstallConfirm:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.BiQ1zG_uninstallConfirm{color:#fff;background:var(--hub-danger);cursor:pointer;-webkit-user-select:none;user-select:none;border:none;border-radius:6px;padding:5px 14px;font-size:12px;font-weight:600;line-height:18px;transition:background .12s}.BiQ1zG_uninstallConfirm:hover{background:var(--hub-danger-hover)}.BiQ1zG_result{text-align:center;flex-direction:column;align-items:center;gap:5px;padding:10px 0 2px;display:flex}.BiQ1zG_resultCheck{background:var(--hub-success-tint);width:40px;height:40px;color:var(--hub-success);border-radius:50%;justify-content:center;align-items:center;margin-bottom:3px;display:inline-flex}.BiQ1zG_resultCheckIcon{flex-shrink:0;width:20px;height:20px}.BiQ1zG_resultTitle{color:var(--hub-text-primary);font-size:13px;font-weight:600;line-height:20px}.BiQ1zG_resultDesc{color:var(--hub-text-secondary);font-size:12px;line-height:18px}.BiQ1zG_resultRestarting{color:var(--hub-text-tertiary);padding:12px 0 6px;font-size:12px;line-height:18px}.BiQ1zG_restartLater{color:var(--hub-text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;padding:5px 14px;font-size:12px;line-height:18px;transition:color .12s,background .12s}.BiQ1zG_restartLater:hover{color:var(--hub-text-primary);background:var(--hub-bg-hover)}.BiQ1zG_restartNow{color:var(--hub-text-on-fill);background:var(--hub-btn-fill);cursor:pointer;-webkit-user-select:none;user-select:none;border:none;border-radius:6px;padding:5px 14px;font-size:12px;font-weight:600;line-height:18px;transition:background .12s}.BiQ1zG_restartNow:hover{background:var(--hub-btn-hover)}.BiQ1zG_restartNow:disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.BiQ1zG_result .BiQ1zG_modalActions{justify-content:center;gap:10px;margin-top:0;padding:6px 0 2px}.BiQ1zG_result .BiQ1zG_modalActions .BiQ1zG_restartLater,.BiQ1zG_result .BiQ1zG_modalActions .BiQ1zG_restartNow{min-width:100px}.BiQ1zG_progress{margin:10px 0 2px}.BiQ1zG_progressHead{justify-content:flex-end;align-items:center;margin-bottom:3px;display:flex}.BiQ1zG_progressText{color:var(--hub-text-secondary);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;line-height:14px}.BiQ1zG_progressTrack{background:var(--hub-border-2);border-radius:2px;height:4px;overflow:hidden}.BiQ1zG_progressFill{background:var(--hub-brand);border-radius:2px;height:100%;transition:width .32s}.BiQ1zG_progressFillFail{background:var(--hub-danger)}@keyframes BiQ1zG_overlayIn{0%{opacity:0}to{opacity:1}}@keyframes BiQ1zG_modalIn{0%{opacity:0;transform:translateY(6px)scale(.98)}to{opacity:1;transform:translateY(0)scale(1)}}.BiQ1zG_noticeList{flex-direction:column;gap:10px;padding-right:2px;display:flex}.BiQ1zG_noticeRow{border:1px solid var(--hub-border-2);background:var(--hub-bg-2);border-radius:8px;flex-direction:column;align-items:stretch;gap:6px;padding:10px 12px;display:flex}.BiQ1zG_noticeRowMain{align-items:center;gap:10px;width:100%;min-width:0;display:flex}.BiQ1zG_noticeBadgeOk,.BiQ1zG_noticeBadgeFail{border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:28px;height:28px;display:inline-flex;box-shadow:0 2px 6px #0000002e}.BiQ1zG_noticeBadgeOk{background:var(--hub-success)}.BiQ1zG_noticeBadgeFail{background:var(--hub-danger)}.BiQ1zG_noticeBadgeIcon{flex-shrink:0;width:12px;height:12px}.BiQ1zG_noticeMain{flex-direction:column;flex:1;gap:8px;min-width:0;display:flex}.BiQ1zG_noticeHead{align-items:center;gap:8px;min-width:0;display:flex}.BiQ1zG_noticeTextOk{color:var(--hub-success);flex-shrink:0;font-size:12px;font-weight:600;line-height:18px}.BiQ1zG_noticeTextFail{color:var(--hub-danger-text);flex-shrink:0;font-size:12px;font-weight:600;line-height:18px}.BiQ1zG_failList{flex-direction:column;gap:12px;padding-right:2px;display:flex}.BiQ1zG_failRow{border:1px solid var(--hub-border-2);background:var(--hub-bg-2);border-radius:8px;flex-direction:column;gap:8px;padding:10px 12px;display:flex}.BiQ1zG_failHead{align-items:center;gap:8px;min-width:0;display:flex}.BiQ1zG_failKind{border:1px solid #0000;border-radius:4px;flex-shrink:0;padding:0 6px;font-size:10px;font-weight:500;line-height:16px}.BiQ1zG_failKindInstall{color:var(--hub-danger-text);border-color:var(--hub-danger-border);background:var(--hub-danger-tint)}.BiQ1zG_failKindUninstall{color:var(--hub-warn);border-color:var(--hub-warn-border);background:var(--hub-warn-tint)}.BiQ1zG_failRepo{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--hub-brand);cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:18px;text-decoration:none;overflow:hidden}.BiQ1zG_failRepo:hover{text-decoration:underline}.BiQ1zG_noticeFoot{justify-content:flex-end;align-items:center;display:flex}.BiQ1zG_noticeTime{color:var(--hub-text-tertiary);font-variant-numeric:tabular-nums;flex-shrink:0;font-size:11px;line-height:16px}.BiQ1zG_noticeRemove{width:22px;height:22px;color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:5px;flex-shrink:0;justify-content:center;align-items:center;margin-left:auto;transition:color .12s,background .12s;display:inline-flex}.BiQ1zG_noticeRemove:hover{color:var(--hub-danger-text);background:var(--hub-danger-tint)}.BiQ1zG_noticeRowOk .BiQ1zG_noticeRemove{margin-left:0}.BiQ1zG_noticeRowOk .BiQ1zG_noticeTime{margin-left:auto}.BiQ1zG_failCopy{color:var(--hub-text-tertiary);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:4px;flex-shrink:0;align-items:center;padding:2px 8px;font-size:11px;line-height:16px;transition:color .12s,background .12s;display:inline-flex}.BiQ1zG_failCopy:hover{color:var(--hub-text-secondary);background:var(--hub-bg-2)}.BiQ1zG_failEmpty{text-align:center;color:var(--hub-text-tertiary);padding:24px 0;font-size:12px;line-height:18px}.BiQ1zG_failClear{color:var(--hub-danger);cursor:pointer;-webkit-user-select:none;user-select:none;background:0 0;border:none;border-radius:6px;padding:5px 14px;font-size:12px;line-height:18px;transition:color .12s,background .12s}.BiQ1zG_failClear:hover{color:#fff;background:var(--hub-danger)}.BiQ1zG_failBigIssue{box-sizing:border-box;text-align:center;color:#fff;background:var(--hub-danger);border:1px solid var(--hub-danger);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:8px;width:100%;margin-top:4px;padding:3px 16px;font-size:13px;font-weight:600;line-height:18px;text-decoration:none;transition:background .12s,border-color .12s,box-shadow .12s;display:block}.BiQ1zG_failBigIssue:hover{background:var(--hub-danger-hover);border-color:var(--hub-danger-hover);box-shadow:0 3px 10px #d1242f59}.BiQ1zG_failPrepareHint{color:var(--hub-warning);background:var(--hub-warning-tint);border:1px solid var(--hub-warning-border);border-radius:6px;margin-top:6px;padding:8px 12px;font-size:12px;line-height:18px}.BiQ1zG_aboutModal{width:460px;max-width:calc(100vw - 48px)}.BiQ1zG_aboutContent{min-height:0;max-height:340px;color:var(--hub-text-secondary);background:var(--hub-bg-2);border:1px solid var(--hub-border-2);border-radius:8px;flex:auto;padding:10px 12px;font-size:12px;line-height:18px;overflow-y:auto}.BiQ1zG_aboutContent>:first-child{margin-top:0}.BiQ1zG_aboutContent>:last-child{margin-bottom:0}.BiQ1zG_aboutContent h2,.BiQ1zG_aboutContent h3,.BiQ1zG_aboutContent h4,.BiQ1zG_aboutContent h5{color:var(--hub-text-primary);margin:10px 0 4px;font-size:13px;font-weight:600;line-height:20px}.BiQ1zG_aboutContent h2{font-size:14px}.BiQ1zG_aboutContent p{margin:4px 0}.BiQ1zG_aboutContent ul,.BiQ1zG_aboutContent ol{margin:4px 0;padding-left:18px}.BiQ1zG_aboutContent li{margin:2px 0}.BiQ1zG_aboutContent code{background:var(--hub-bg-hover);color:var(--hub-text-primary);border-radius:4px;padding:1px 4px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px}.BiQ1zG_aboutContent pre{background:var(--hub-bg-1);border:1px solid var(--hub-border-2);border-radius:6px;margin:6px 0;padding:8px 10px;overflow-x:auto}.BiQ1zG_aboutContent pre code{background:0 0;border-radius:0;padding:0}.BiQ1zG_aboutContent blockquote{border-left:3px solid var(--hub-brand);background:var(--hub-bg-hover);color:var(--hub-text-tertiary);border-radius:0 6px 6px 0;margin:6px 0;padding:2px 10px}.BiQ1zG_aboutContent a{color:var(--hub-brand);text-decoration:none}.BiQ1zG_aboutContent a:hover{color:var(--hub-brand-hover);text-decoration:underline}.BiQ1zG_aboutContent img{border-radius:8px;max-width:100%;max-height:220px;margin:8px auto;display:block;box-shadow:0 2px 8px #0000001f}.BiQ1zG_aboutMeta{color:var(--hub-text-tertiary);font-size:11px;line-height:16px}.BiQ1zG_hubUpdateModal{width:520px;max-width:calc(100vw - 48px)}.BiQ1zG_hubUpdateMeta{flex-wrap:wrap;align-items:center;gap:4px 14px;font-size:12px;line-height:18px;display:flex}.BiQ1zG_hubUpdateMetaItem{color:var(--hub-text-tertiary)}.BiQ1zG_hubUpdateNotes{min-height:0;max-height:300px;color:var(--hub-text-secondary);background:var(--hub-bg-2);border:1px solid var(--hub-border-2);border-radius:8px;flex:auto;padding:10px 12px;font-size:12px;line-height:18px;overflow-y:auto}.BiQ1zG_hubUpdateNotes>:first-child{margin-top:0}.BiQ1zG_hubUpdateNotes>:last-child{margin-bottom:0}.BiQ1zG_hubUpdateNotes h2,.BiQ1zG_hubUpdateNotes h3,.BiQ1zG_hubUpdateNotes h4,.BiQ1zG_hubUpdateNotes h5{color:var(--hub-text-primary);margin:10px 0 4px;font-size:13px;font-weight:600;line-height:20px}.BiQ1zG_hubUpdateNotes h2{font-size:14px}.BiQ1zG_hubUpdateNotes p{margin:4px 0}.BiQ1zG_hubUpdateNotes ul,.BiQ1zG_hubUpdateNotes ol{margin:4px 0;padding-left:18px}.BiQ1zG_hubUpdateNotes li{margin:2px 0}.BiQ1zG_hubUpdateNotes code{background:var(--hub-bg-hover);color:var(--hub-text-primary);border-radius:4px;padding:1px 4px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px}.BiQ1zG_hubUpdateNotes pre{background:var(--hub-bg-1);border:1px solid var(--hub-border-2);border-radius:6px;margin:6px 0;padding:8px 10px;overflow-x:auto}.BiQ1zG_hubUpdateNotes pre code{background:0 0;border-radius:0;padding:0}.BiQ1zG_hubUpdateNotes blockquote{border-left:3px solid var(--hub-brand);background:var(--hub-bg-hover);color:var(--hub-text-tertiary);border-radius:0 6px 6px 0;margin:6px 0;padding:2px 10px}.BiQ1zG_hubUpdateNotes a{color:var(--hub-brand);text-decoration:none}.BiQ1zG_hubUpdateNotes a:hover{color:var(--hub-brand-hover);text-decoration:underline}";
|
|
1270
1425
|
const tagId$3 = "dsh-plugin/Modal.module.css";
|
|
1271
1426
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
1272
1427
|
const tag = document.createElement("style");
|
|
@@ -1276,97 +1431,111 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1276
1431
|
document.head.appendChild(tag);
|
|
1277
1432
|
}
|
|
1278
1433
|
var Modal_module_css_default = {
|
|
1434
|
+
"resultDesc": "BiQ1zG_resultDesc",
|
|
1435
|
+
"hubUpdateMetaItem": "BiQ1zG_hubUpdateMetaItem",
|
|
1436
|
+
"modalBody": "BiQ1zG_modalBody",
|
|
1279
1437
|
"queueRowTarget": "BiQ1zG_queueRowTarget",
|
|
1280
|
-
"
|
|
1281
|
-
"
|
|
1438
|
+
"queueRowDesc": "BiQ1zG_queueRowDesc",
|
|
1439
|
+
"trustHint": "BiQ1zG_trustHint",
|
|
1440
|
+
"uninstallConfirm": "BiQ1zG_uninstallConfirm",
|
|
1441
|
+
"progressText": "BiQ1zG_progressText",
|
|
1442
|
+
"noticeList": "BiQ1zG_noticeList",
|
|
1443
|
+
"noticeRowMain": "BiQ1zG_noticeRowMain",
|
|
1444
|
+
"queueRowHead": "BiQ1zG_queueRowHead",
|
|
1445
|
+
"result": "BiQ1zG_result",
|
|
1446
|
+
"restartNow": "BiQ1zG_restartNow",
|
|
1447
|
+
"modalIn": "BiQ1zG_modalIn",
|
|
1448
|
+
"modalInstall": "BiQ1zG_modalInstall",
|
|
1449
|
+
"errorBox": "BiQ1zG_errorBox",
|
|
1450
|
+
"toastIn": "BiQ1zG_toastIn",
|
|
1451
|
+
"noticeRemove": "BiQ1zG_noticeRemove",
|
|
1452
|
+
"resultTitle": "BiQ1zG_resultTitle",
|
|
1453
|
+
"progressHead": "BiQ1zG_progressHead",
|
|
1454
|
+
"modal": "BiQ1zG_modal",
|
|
1455
|
+
"modalCmd": "BiQ1zG_modalCmd",
|
|
1456
|
+
"pendingRowActions": "BiQ1zG_pendingRowActions",
|
|
1457
|
+
"modalCmdText": "BiQ1zG_modalCmdText",
|
|
1282
1458
|
"modalTitleQueued": "BiQ1zG_modalTitleQueued",
|
|
1283
|
-
"
|
|
1459
|
+
"queuedHint": "BiQ1zG_queuedHint",
|
|
1460
|
+
"noticeBadgeIcon": "BiQ1zG_noticeBadgeIcon",
|
|
1461
|
+
"progressFill": "BiQ1zG_progressFill",
|
|
1462
|
+
"noticeTextFail": "BiQ1zG_noticeTextFail",
|
|
1463
|
+
"aboutModal": "BiQ1zG_aboutModal",
|
|
1464
|
+
"failList": "BiQ1zG_failList",
|
|
1465
|
+
"modalHead": "BiQ1zG_modalHead",
|
|
1284
1466
|
"noticeRow": "BiQ1zG_noticeRow",
|
|
1285
1467
|
"toast": "BiQ1zG_toast",
|
|
1286
|
-
"restartLater": "BiQ1zG_restartLater",
|
|
1287
|
-
"resultCheckIcon": "BiQ1zG_resultCheckIcon",
|
|
1288
|
-
"linkIcon": "BiQ1zG_linkIcon",
|
|
1289
|
-
"failKindUninstall": "BiQ1zG_failKindUninstall",
|
|
1290
|
-
"failRepo": "BiQ1zG_failRepo",
|
|
1291
|
-
"modalCmd": "BiQ1zG_modalCmd",
|
|
1292
|
-
"modal": "BiQ1zG_modal",
|
|
1293
|
-
"queueRowPct": "BiQ1zG_queueRowPct",
|
|
1294
|
-
"failKind": "BiQ1zG_failKind",
|
|
1295
|
-
"modalTitle": "BiQ1zG_modalTitle",
|
|
1296
|
-
"modalTitleBusy": "BiQ1zG_modalTitleBusy",
|
|
1297
|
-
"modalBody": "BiQ1zG_modalBody",
|
|
1298
1468
|
"modalCloseIcon": "BiQ1zG_modalCloseIcon",
|
|
1299
|
-
"
|
|
1469
|
+
"failEmpty": "BiQ1zG_failEmpty",
|
|
1470
|
+
"noticeRowOk": "BiQ1zG_noticeRowOk",
|
|
1471
|
+
"aboutMeta": "BiQ1zG_aboutMeta",
|
|
1472
|
+
"resultRestarting": "BiQ1zG_resultRestarting",
|
|
1300
1473
|
"modalCancel": "BiQ1zG_modalCancel",
|
|
1301
|
-
"
|
|
1302
|
-
"
|
|
1303
|
-
"modalCopy": "BiQ1zG_modalCopy",
|
|
1304
|
-
"modalCmdText": "BiQ1zG_modalCmdText",
|
|
1474
|
+
"restartLater": "BiQ1zG_restartLater",
|
|
1475
|
+
"noticeTime": "BiQ1zG_noticeTime",
|
|
1305
1476
|
"queueSection": "BiQ1zG_queueSection",
|
|
1306
|
-
"
|
|
1307
|
-
"errorHint": "BiQ1zG_errorHint",
|
|
1308
|
-
"noticeMain": "BiQ1zG_noticeMain",
|
|
1309
|
-
"noticeFoot": "BiQ1zG_noticeFoot",
|
|
1310
|
-
"failCopy": "BiQ1zG_failCopy",
|
|
1311
|
-
"failBigIssue": "BiQ1zG_failBigIssue",
|
|
1477
|
+
"modalTitleBusy": "BiQ1zG_modalTitleBusy",
|
|
1312
1478
|
"modalRow": "BiQ1zG_modalRow",
|
|
1313
|
-
"
|
|
1314
|
-
"
|
|
1315
|
-
"
|
|
1316
|
-
"
|
|
1479
|
+
"failBigIssue": "BiQ1zG_failBigIssue",
|
|
1480
|
+
"resultCheckIcon": "BiQ1zG_resultCheckIcon",
|
|
1481
|
+
"queueSectionTitle": "BiQ1zG_queueSectionTitle",
|
|
1482
|
+
"hubUpdateModal": "BiQ1zG_hubUpdateModal",
|
|
1483
|
+
"modalCmdCopy": "BiQ1zG_modalCmdCopy",
|
|
1484
|
+
"overlayIn": "BiQ1zG_overlayIn",
|
|
1485
|
+
"modalClose": "BiQ1zG_modalClose",
|
|
1486
|
+
"failRow": "BiQ1zG_failRow",
|
|
1487
|
+
"noticeBadgeFail": "BiQ1zG_noticeBadgeFail",
|
|
1488
|
+
"failRepo": "BiQ1zG_failRepo",
|
|
1317
1489
|
"noticeHead": "BiQ1zG_noticeHead",
|
|
1318
|
-
"
|
|
1319
|
-
"
|
|
1320
|
-
"
|
|
1321
|
-
"
|
|
1322
|
-
"pendingRowActions": "BiQ1zG_pendingRowActions",
|
|
1323
|
-
"resultTitle": "BiQ1zG_resultTitle",
|
|
1324
|
-
"restartNow": "BiQ1zG_restartNow",
|
|
1325
|
-
"noticeBadgeIcon": "BiQ1zG_noticeBadgeIcon",
|
|
1326
|
-
"failPrepareHint": "BiQ1zG_failPrepareHint",
|
|
1327
|
-
"noticeBadgeOk": "BiQ1zG_noticeBadgeOk",
|
|
1328
|
-
"failEmpty": "BiQ1zG_failEmpty",
|
|
1329
|
-
"result": "BiQ1zG_result",
|
|
1330
|
-
"modalInstall": "BiQ1zG_modalInstall",
|
|
1490
|
+
"noticeFoot": "BiQ1zG_noticeFoot",
|
|
1491
|
+
"aboutContent": "BiQ1zG_aboutContent",
|
|
1492
|
+
"errorModal": "BiQ1zG_errorModal",
|
|
1493
|
+
"failKindUninstall": "BiQ1zG_failKindUninstall",
|
|
1331
1494
|
"noticeTextOk": "BiQ1zG_noticeTextOk",
|
|
1332
|
-
"
|
|
1333
|
-
"
|
|
1334
|
-
"stripCancel": "BiQ1zG_stripCancel",
|
|
1495
|
+
"progressTrack": "BiQ1zG_progressTrack",
|
|
1496
|
+
"noticeBadgeOk": "BiQ1zG_noticeBadgeOk",
|
|
1335
1497
|
"progress": "BiQ1zG_progress",
|
|
1336
|
-
"
|
|
1337
|
-
"modalIn": "BiQ1zG_modalIn",
|
|
1338
|
-
"errorTitle": "BiQ1zG_errorTitle",
|
|
1339
|
-
"failList": "BiQ1zG_failList",
|
|
1340
|
-
"noticeTime": "BiQ1zG_noticeTime",
|
|
1341
|
-
"queuedHint": "BiQ1zG_queuedHint",
|
|
1342
|
-
"resultDesc": "BiQ1zG_resultDesc",
|
|
1343
|
-
"trustHint": "BiQ1zG_trustHint",
|
|
1344
|
-
"noticeRowMain": "BiQ1zG_noticeRowMain",
|
|
1345
|
-
"queueRowDesc": "BiQ1zG_queueRowDesc",
|
|
1346
|
-
"modalHead": "BiQ1zG_modalHead",
|
|
1347
|
-
"queueRowStatus": "BiQ1zG_queueRowStatus",
|
|
1348
|
-
"uninstallConfirm": "BiQ1zG_uninstallConfirm",
|
|
1349
|
-
"failKindInstall": "BiQ1zG_failKindInstall",
|
|
1498
|
+
"linkIcon": "BiQ1zG_linkIcon",
|
|
1350
1499
|
"toastFail": "BiQ1zG_toastFail",
|
|
1351
|
-
"
|
|
1352
|
-
"resultRestarting": "BiQ1zG_resultRestarting",
|
|
1353
|
-
"resultCheck": "BiQ1zG_resultCheck",
|
|
1354
|
-
"failRow": "BiQ1zG_failRow",
|
|
1500
|
+
"modalDesc": "BiQ1zG_modalDesc",
|
|
1355
1501
|
"pendingRowStatus": "BiQ1zG_pendingRowStatus",
|
|
1356
|
-
"
|
|
1357
|
-
"
|
|
1358
|
-
"
|
|
1502
|
+
"queueRowPct": "BiQ1zG_queueRowPct",
|
|
1503
|
+
"resultCheck": "BiQ1zG_resultCheck",
|
|
1504
|
+
"queueRowTrack": "BiQ1zG_queueRowTrack",
|
|
1505
|
+
"failPrepareHint": "BiQ1zG_failPrepareHint",
|
|
1506
|
+
"queueRow": "BiQ1zG_queueRow",
|
|
1507
|
+
"failKindInstall": "BiQ1zG_failKindInstall",
|
|
1508
|
+
"failCopy": "BiQ1zG_failCopy",
|
|
1509
|
+
"cliOnlyHint": "BiQ1zG_cliOnlyHint",
|
|
1510
|
+
"modalLabel": "BiQ1zG_modalLabel",
|
|
1511
|
+
"overlay": "BiQ1zG_overlay",
|
|
1359
1512
|
"modalActions": "BiQ1zG_modalActions",
|
|
1360
|
-
"
|
|
1513
|
+
"queueRowBody": "BiQ1zG_queueRowBody",
|
|
1361
1514
|
"modalLink": "BiQ1zG_modalLink",
|
|
1362
|
-
"
|
|
1363
|
-
"
|
|
1364
|
-
"
|
|
1365
|
-
"
|
|
1515
|
+
"queueRowStatus": "BiQ1zG_queueRowStatus",
|
|
1516
|
+
"stripCancel": "BiQ1zG_stripCancel",
|
|
1517
|
+
"errorTitle": "BiQ1zG_errorTitle",
|
|
1518
|
+
"failedCopyHint": "BiQ1zG_failedCopyHint",
|
|
1519
|
+
"modalValue": "BiQ1zG_modalValue",
|
|
1520
|
+
"errorCopySoft": "BiQ1zG_errorCopySoft",
|
|
1521
|
+
"errorHint": "BiQ1zG_errorHint",
|
|
1522
|
+
"modalCopy": "BiQ1zG_modalCopy",
|
|
1523
|
+
"failClear": "BiQ1zG_failClear",
|
|
1524
|
+
"hubUpdateMeta": "BiQ1zG_hubUpdateMeta",
|
|
1525
|
+
"noticeMain": "BiQ1zG_noticeMain",
|
|
1526
|
+
"progressFillFail": "BiQ1zG_progressFillFail",
|
|
1527
|
+
"modalTitle": "BiQ1zG_modalTitle",
|
|
1528
|
+
"failHead": "BiQ1zG_failHead",
|
|
1529
|
+
"failKind": "BiQ1zG_failKind",
|
|
1530
|
+
"hubUpdateNotes": "BiQ1zG_hubUpdateNotes"
|
|
1366
1531
|
};
|
|
1367
1532
|
//#endregion
|
|
1368
1533
|
//#region src/client/components/icons.tsx
|
|
1369
1534
|
/**
|
|
1535
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
1536
|
+
* Website: https://dsh-plugin.org
|
|
1537
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
1538
|
+
*
|
|
1370
1539
|
* Inline SVG icons used across the client. Icons inherit currentColor so
|
|
1371
1540
|
* they adapt to themes and disabled states automatically.
|
|
1372
1541
|
*/
|
|
@@ -1522,6 +1691,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1522
1691
|
//#endregion
|
|
1523
1692
|
//#region src/client/components/ProgressView.tsx
|
|
1524
1693
|
/**
|
|
1694
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
1695
|
+
* Website: https://dsh-plugin.org
|
|
1696
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
1697
|
+
*
|
|
1525
1698
|
* Inline progress block shared by the install and uninstall dialogs:
|
|
1526
1699
|
* a real percentage bar (server-estimated, client-polled). No live terminal
|
|
1527
1700
|
* window — pnpm emits nothing during git clone/build, so a log pane would be
|
|
@@ -1536,13 +1709,20 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1536
1709
|
//#endregion
|
|
1537
1710
|
//#region src/client/components/modals.tsx
|
|
1538
1711
|
/**
|
|
1712
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
1713
|
+
* Website: https://dsh-plugin.org
|
|
1714
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
1715
|
+
*
|
|
1539
1716
|
* Dialog layer for the Plugin Hub: the install-confirm dialog, the uninstall
|
|
1540
1717
|
* dialog and the global toast. Both dialogs lock themselves while a mutation
|
|
1541
1718
|
* or restart is running, then switch to a result view offering an immediate
|
|
1542
1719
|
* restart or a "later" deferral.
|
|
1543
1720
|
*/
|
|
1544
|
-
/** 完成结果视图:绿色对勾 +
|
|
1545
|
-
|
|
1721
|
+
/** 完成结果视图:绿色对勾 + 标题/描述;
|
|
1722
|
+
* needsRestart=true(插件需重启才生效)→ 「稍后重启 / 立即重启」按钮对,点稍后重启后
|
|
1723
|
+
* 通知中心待重启条目常驻(服务端登记,内存态),直到用户点「立即重启」真正重启后才消失;
|
|
1724
|
+
* needsRestart=false(卸载已即时生效)→ 仅「完成」关闭。 */
|
|
1725
|
+
function ResultView({ title, desc, t, restarting, needsRestart, onRestart, onClose }) {
|
|
1546
1726
|
return (0, react.createElement)("div", { className: Modal_module_css_default.result }, (0, react.createElement)("div", { className: Modal_module_css_default.resultCheck }, (0, react.createElement)("svg", {
|
|
1547
1727
|
className: Modal_module_css_default.resultCheckIcon,
|
|
1548
1728
|
viewBox: "0 0 16 16",
|
|
@@ -1556,7 +1736,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1556
1736
|
strokeWidth: 2,
|
|
1557
1737
|
strokeLinecap: "round",
|
|
1558
1738
|
strokeLinejoin: "round"
|
|
1559
|
-
}))), (0, react.createElement)("div", { className: Modal_module_css_default.resultTitle }, title), desc ? (0, react.createElement)("div", { className: Modal_module_css_default.resultDesc }, desc) : null, (0, react.createElement)("div", { className: Modal_module_css_default.resultRestarting }, restarting ? t("restarting") : t("restartHint")), (0, react.createElement)("div", { className: Modal_module_css_default.modalActions }, (0, react.createElement)("button", {
|
|
1739
|
+
}))), (0, react.createElement)("div", { className: Modal_module_css_default.resultTitle }, title), desc ? (0, react.createElement)("div", { className: Modal_module_css_default.resultDesc }, desc) : null, needsRestart ? (0, react.createElement)("div", null, [(0, react.createElement)("div", { className: Modal_module_css_default.resultRestarting }, restarting ? t("restarting") : t("restartHint")), (0, react.createElement)("div", { className: Modal_module_css_default.modalActions }, (0, react.createElement)("button", {
|
|
1560
1740
|
className: Modal_module_css_default.restartLater,
|
|
1561
1741
|
onClick: onClose,
|
|
1562
1742
|
disabled: restarting
|
|
@@ -1564,14 +1744,17 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1564
1744
|
className: Modal_module_css_default.restartNow,
|
|
1565
1745
|
onClick: onRestart,
|
|
1566
1746
|
disabled: restarting
|
|
1567
|
-
}, restarting ? t("restarting") : t("restartNow"))))
|
|
1747
|
+
}, restarting ? t("restarting") : t("restartNow")))]) : (0, react.createElement)("div", { className: Modal_module_css_default.modalActions }, (0, react.createElement)("button", {
|
|
1748
|
+
className: Modal_module_css_default.restartNow,
|
|
1749
|
+
onClick: onClose
|
|
1750
|
+
}, t("done"))));
|
|
1568
1751
|
}
|
|
1569
1752
|
/**
|
|
1570
1753
|
* 信任确认弹窗:安装进入后台队列后弹窗仍可关闭(任务继续),
|
|
1571
1754
|
* 只在本任务执行中展示实时进度;完成后切换为结果视图,与卸载一致。
|
|
1572
1755
|
*/
|
|
1573
1756
|
function InstallModal(props) {
|
|
1574
|
-
const { plugin, done, task, t, langPath, restarting, submitting, update, onClose, onCopy, onInstall, onRestart } = props;
|
|
1757
|
+
const { plugin, done, task, t, langPath, restarting, submitting, update, cliOnly, needsRestart, onClose, onCopy, onInstall, onRestart } = props;
|
|
1575
1758
|
const busy = submitting || task !== null && (task.status === "pending" || task.status === "running");
|
|
1576
1759
|
const name = plugin.displayName ?? plugin.slug;
|
|
1577
1760
|
const busyTitle = (label) => langPath === "zh/" ? `${name} 插件${label}` : `${label} ${name}`;
|
|
@@ -1594,6 +1777,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1594
1777
|
desc: update ? t("updateResultDesc") : t("installResultDesc"),
|
|
1595
1778
|
t,
|
|
1596
1779
|
restarting,
|
|
1780
|
+
needsRestart,
|
|
1597
1781
|
onRestart,
|
|
1598
1782
|
onClose
|
|
1599
1783
|
}) : (0, react.createElement)("div", { className: Modal_module_css_default.modalBody }, (0, react.createElement)("div", { className: Modal_module_css_default.trustHint }, t("confirmDesc")), (0, react.createElement)("div", { className: Modal_module_css_default.modalRow }, (0, react.createElement)("span", { className: Modal_module_css_default.modalLabel }, t("confirmPlugin")), (0, react.createElement)("span", {
|
|
@@ -1611,7 +1795,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1611
1795
|
title: t("copyInstallCommand"),
|
|
1612
1796
|
role: "button",
|
|
1613
1797
|
tabIndex: 0
|
|
1614
|
-
}, (0, react.createElement)("span", { className: Modal_module_css_default.modalCmdText }, installCommandOf(plugin)), (0, react.createElement)("span", { className: Modal_module_css_default.modalCmdCopy }, (0, react.createElement)(CopyIcon), t("copyCmdLabel"))), task && task.status === "pending" ? (0, react.createElement)("div", { className: Modal_module_css_default.queuedHint }, t("queuedHint")) : null, task ? (0, react.createElement)(ProgressView, { task }) : null, (0, react.createElement)("div", { className: Modal_module_css_default.modalActions }, (0, react.createElement)("button", {
|
|
1798
|
+
}, (0, react.createElement)("span", { className: Modal_module_css_default.modalCmdText }, installCommandOf(plugin)), (0, react.createElement)("span", { className: Modal_module_css_default.modalCmdCopy }, (0, react.createElement)(CopyIcon), t("copyCmdLabel"))), cliOnly ? (0, react.createElement)("div", { className: Modal_module_css_default.cliOnlyHint }, t("cliOnlyHint")) : null, task && task.status === "pending" ? (0, react.createElement)("div", { className: Modal_module_css_default.queuedHint }, t("queuedHint")) : null, task ? (0, react.createElement)(ProgressView, { task }) : null, task && task.status === "failed" ? (0, react.createElement)("div", { className: Modal_module_css_default.failedCopyHint }, t("failedCopyHint")) : null, (0, react.createElement)("div", { className: Modal_module_css_default.modalActions }, (0, react.createElement)("button", {
|
|
1615
1799
|
className: Modal_module_css_default.modalCopy,
|
|
1616
1800
|
disabled: busy,
|
|
1617
1801
|
onClick: onCopy
|
|
@@ -1623,7 +1807,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1623
1807
|
}
|
|
1624
1808
|
/** 卸载确认弹窗:确认/进行中(后台队列,可关闭);完成后切换为结果视图(成功即生效,仅「完成」关闭)。 */
|
|
1625
1809
|
function UninstallModal(props) {
|
|
1626
|
-
const { plugin, done, task, t, langPath, restarting, submitting, onClose, onCancel, onCopyCommand, onConfirm, onRestart } = props;
|
|
1810
|
+
const { plugin, done, task, t, langPath, restarting, submitting, needsRestart, onClose, onCancel, onCopyCommand, onConfirm, onRestart } = props;
|
|
1627
1811
|
const busy = submitting || task !== null && (task.status === "pending" || task.status === "running");
|
|
1628
1812
|
const name = plugin.displayName ?? plugin.slug;
|
|
1629
1813
|
const busyTitle = (label) => langPath === "zh/" ? `${name} 插件${label}` : `${label} ${name}`;
|
|
@@ -1646,6 +1830,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1646
1830
|
desc: t("uninstallResultDesc"),
|
|
1647
1831
|
t,
|
|
1648
1832
|
restarting,
|
|
1833
|
+
needsRestart,
|
|
1649
1834
|
onRestart,
|
|
1650
1835
|
onClose
|
|
1651
1836
|
}) : (0, react.createElement)("div", { className: Modal_module_css_default.modalBody }, (0, react.createElement)("div", { className: Modal_module_css_default.modalDesc }, t("uninstallDesc")), (0, react.createElement)("div", { className: Modal_module_css_default.modalRow }, (0, react.createElement)("span", { className: Modal_module_css_default.modalLabel }, t("confirmPlugin")), (0, react.createElement)("span", {
|
|
@@ -1723,8 +1908,193 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1723
1908
|
}, text);
|
|
1724
1909
|
}
|
|
1725
1910
|
//#endregion
|
|
1911
|
+
//#region src/client/lib/renderMarkdown.ts
|
|
1912
|
+
/**
|
|
1913
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
1914
|
+
* Website: https://dsh-plugin.org
|
|
1915
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
1916
|
+
*
|
|
1917
|
+
* 轻量 Markdown 渲染器:仅用于 Hub 自我更新的变更记录(Worker 下发的 notes)。
|
|
1918
|
+
*
|
|
1919
|
+
* 内容由插件作者自己编写、属可信内容,但渲染端仍先整体 HTML 转义,再按
|
|
1920
|
+
* Markdown 语法输出结构,杜绝任何未转义的原始 HTML 注入;链接仅放行 http(s)。
|
|
1921
|
+
*
|
|
1922
|
+
* 支持:标题(#~####)、有序/无序列表、代码块(```)、行内代码、加粗、斜体、
|
|
1923
|
+
* 链接、图片(,如反馈群二维码)、引用(>)、段落;其余语法一律按
|
|
1924
|
+
* 纯文本处理,不引入外部依赖。图片仅放行 http(s),限定最大宽度不撑破弹窗。
|
|
1925
|
+
*/
|
|
1926
|
+
/** HTML 转义:所有文本先进这里,再进入结构变换,保证输出里没有未转义的用户输入。 */
|
|
1927
|
+
function escapeHtml(s) {
|
|
1928
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1929
|
+
}
|
|
1930
|
+
/** 行内变换:链接 / 加粗 / 斜体 / 行内代码(代码先占位保护,最后还原)。 */
|
|
1931
|
+
function inline(s) {
|
|
1932
|
+
let out = escapeHtml(s);
|
|
1933
|
+
const codeSpans = [];
|
|
1934
|
+
out = out.replace(/`([^`]+)`/g, (_m, code) => {
|
|
1935
|
+
codeSpans.push(String(code));
|
|
1936
|
+
return `\u0000${codeSpans.length - 1}\u0000`;
|
|
1937
|
+
});
|
|
1938
|
+
out = out.replace(/!\[([^\]]*)\]\(([^)\s]+)\)/g, (m, alt, url) => /^https?:\/\//i.test(String(url)) && !/[\u0000]/.test(String(url)) ? `<img src="${String(url)}" alt="${String(alt)}" loading="lazy">` : m);
|
|
1939
|
+
out = out.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (m, text, url) => /^https?:\/\//i.test(String(url)) && !/[\u0000]/.test(String(url)) ? `<a href="${String(url)}" target="_blank" rel="noopener noreferrer">${String(text)}</a>` : m);
|
|
1940
|
+
out = out.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
|
|
1941
|
+
out = out.replace(/(^|[^*])\*([^*]+)\*/g, "$1<em>$2</em>");
|
|
1942
|
+
return out.replace(/\u0000(\d+)\u0000/g, (_m, idx) => `<code>${codeSpans[Number(idx)]}</code>`);
|
|
1943
|
+
}
|
|
1944
|
+
/** 把变更记录 Markdown 渲染为安全的 HTML 字符串(由弹窗用 dangerouslySetInnerHTML 注入)。 */
|
|
1945
|
+
function renderMarkdown(md) {
|
|
1946
|
+
const lines = md.replace(/\r\n?/g, "\n").split("\n");
|
|
1947
|
+
const blocks = [];
|
|
1948
|
+
let i = 0;
|
|
1949
|
+
while (i < lines.length) {
|
|
1950
|
+
const line = lines[i];
|
|
1951
|
+
if (/^\s*```/.test(line)) {
|
|
1952
|
+
const buf = [];
|
|
1953
|
+
i++;
|
|
1954
|
+
while (i < lines.length && !/^\s*```/.test(lines[i])) {
|
|
1955
|
+
buf.push(lines[i]);
|
|
1956
|
+
i++;
|
|
1957
|
+
}
|
|
1958
|
+
i++;
|
|
1959
|
+
blocks.push(`<pre><code>${escapeHtml(buf.join("\n"))}</code></pre>`);
|
|
1960
|
+
continue;
|
|
1961
|
+
}
|
|
1962
|
+
if (line.trim() === "") {
|
|
1963
|
+
i++;
|
|
1964
|
+
continue;
|
|
1965
|
+
}
|
|
1966
|
+
const heading = line.match(/^(#{1,4})\s+(.*)/);
|
|
1967
|
+
if (heading) {
|
|
1968
|
+
const level = heading[1].length + 1;
|
|
1969
|
+
blocks.push(`<h${level}>${inline(heading[2])}</h${level}>`);
|
|
1970
|
+
i++;
|
|
1971
|
+
continue;
|
|
1972
|
+
}
|
|
1973
|
+
if (/^\s*[-*+]\s+/.test(line) || /^\s*\d+[.)]\s+/.test(line)) {
|
|
1974
|
+
const ordered = /^\s*\d+[.)]\s+/.test(line);
|
|
1975
|
+
const items = [];
|
|
1976
|
+
while (i < lines.length && (/^\s*[-*+]\s+/.test(lines[i]) || /^\s*\d+[.)]\s+/.test(lines[i]))) {
|
|
1977
|
+
items.push(`<li>${inline(lines[i].replace(/^\s*[-*+]|\s*\d+[.)]\s*/, "").trim())}</li>`);
|
|
1978
|
+
i++;
|
|
1979
|
+
}
|
|
1980
|
+
blocks.push(`<${ordered ? "ol" : "ul"}>${items.join("")}</${ordered ? "ol" : "ul"}>`);
|
|
1981
|
+
continue;
|
|
1982
|
+
}
|
|
1983
|
+
if (/^\s*>\s?/.test(line)) {
|
|
1984
|
+
const buf = [];
|
|
1985
|
+
while (i < lines.length && /^\s*>\s?/.test(lines[i])) {
|
|
1986
|
+
buf.push(inline(lines[i].replace(/^\s*>\s?/, "")));
|
|
1987
|
+
i++;
|
|
1988
|
+
}
|
|
1989
|
+
blocks.push(`<blockquote>${buf.join("<br>")}</blockquote>`);
|
|
1990
|
+
continue;
|
|
1991
|
+
}
|
|
1992
|
+
const buf = [];
|
|
1993
|
+
while (i < lines.length && lines[i].trim() !== "" && !/^\s*```/.test(lines[i]) && !/^#{1,4}\s+/.test(lines[i]) && !/^\s*([-*+]|\d+[.)])\s+/.test(lines[i])) {
|
|
1994
|
+
buf.push(inline(lines[i]));
|
|
1995
|
+
i++;
|
|
1996
|
+
}
|
|
1997
|
+
blocks.push(`<p>${buf.join("<br>")}</p>`);
|
|
1998
|
+
}
|
|
1999
|
+
return blocks.join("");
|
|
2000
|
+
}
|
|
2001
|
+
//#endregion
|
|
2002
|
+
//#region src/client/components/AboutModal.tsx
|
|
2003
|
+
/**
|
|
2004
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2005
|
+
* Website: https://dsh-plugin.org
|
|
2006
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2007
|
+
*
|
|
2008
|
+
* 头部「关注我们」弹窗:介绍 DSH-Plugin Hub 是干什么的 + 用户反馈群二维码。
|
|
2009
|
+
* 内容以 Markdown 形式由 dsh-update Worker 的 /about 接口下发(key = hub:about),
|
|
2010
|
+
* 作者想怎么写就怎么写、随写随推,客户端只负责渲染 —— 非写死。
|
|
2011
|
+
* 图片(反馈群二维码)经 renderMarkdown 的  语法嵌入,居中、最大高度受控。
|
|
2012
|
+
*/
|
|
2013
|
+
function AboutModal({ info, lang, t, onClose }) {
|
|
2014
|
+
const contentRaw = info ? typeof info.content === "string" ? info.content : info.content && typeof info.content === "object" ? lang === "en" ? info.content.en ?? info.content.zh ?? "" : info.content.zh ?? info.content.en ?? "" : "" : "";
|
|
2015
|
+
const contentHtml = contentRaw.trim() ? renderMarkdown(contentRaw) : null;
|
|
2016
|
+
let updated = null;
|
|
2017
|
+
if (info?.updatedAt) {
|
|
2018
|
+
const d = new Date(info.updatedAt);
|
|
2019
|
+
if (!Number.isNaN(d.getTime())) updated = d.toLocaleString(lang === "en" ? "en-US" : "zh-CN");
|
|
2020
|
+
}
|
|
2021
|
+
return (0, react.createElement)("div", {
|
|
2022
|
+
className: Modal_module_css_default.overlay,
|
|
2023
|
+
onClick: (e) => {
|
|
2024
|
+
if (e.target === e.currentTarget) onClose();
|
|
2025
|
+
}
|
|
2026
|
+
}, (0, react.createElement)("div", {
|
|
2027
|
+
className: `${Modal_module_css_default.modal} ${Modal_module_css_default.aboutModal}`,
|
|
2028
|
+
role: "dialog",
|
|
2029
|
+
"aria-modal": "true"
|
|
2030
|
+
}, (0, react.createElement)("div", { className: Modal_module_css_default.modalHead }, (0, react.createElement)("div", { className: Modal_module_css_default.modalTitle }, t("aboutTitle")), (0, react.createElement)("button", {
|
|
2031
|
+
className: Modal_module_css_default.modalClose,
|
|
2032
|
+
"aria-label": t("confirmCancel"),
|
|
2033
|
+
onClick: () => onClose()
|
|
2034
|
+
}, (0, react.createElement)(CloseIcon))), (0, react.createElement)("div", { className: Modal_module_css_default.modalDesc }, t("aboutDesc")), contentHtml ? (0, react.createElement)("div", {
|
|
2035
|
+
className: Modal_module_css_default.aboutContent,
|
|
2036
|
+
dangerouslySetInnerHTML: { __html: contentHtml }
|
|
2037
|
+
}) : (0, react.createElement)("div", { className: Modal_module_css_default.aboutContent }, t("aboutEmpty")), updated ? (0, react.createElement)("div", { className: Modal_module_css_default.aboutMeta }, `${t("aboutUpdated")} ${updated}`) : null, (0, react.createElement)("div", { className: Modal_module_css_default.modalActions }, (0, react.createElement)("button", {
|
|
2038
|
+
className: Modal_module_css_default.modalInstall,
|
|
2039
|
+
onClick: onClose
|
|
2040
|
+
}, t("doneBtn")))));
|
|
2041
|
+
}
|
|
2042
|
+
//#endregion
|
|
2043
|
+
//#region src/client/components/HubUpdateModal.tsx
|
|
2044
|
+
/**
|
|
2045
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2046
|
+
* Website: https://dsh-plugin.org
|
|
2047
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2048
|
+
*
|
|
2049
|
+
* Hub 版本信息 / 自我更新说明弹窗:
|
|
2050
|
+
* - 有更新(hasUpdate=true):标题「有新版本」,展示新版本号、发布时间与 Worker 下发的
|
|
2051
|
+
* Markdown 变更记录(renderMarkdown 渲染,双语言按界面语言取 {zh,en} 对象),
|
|
2052
|
+
* 按钮「稍后再说 / 直接更新」,确认后进入安装弹窗执行覆盖重装。
|
|
2053
|
+
* - 无更新(hasUpdate=false):标题「当前版本」,展示当前版本信息与更新记录,已是最新。
|
|
2054
|
+
* 点击头部版本号(或「可更新」徽标)打开 —— 无论有无更新都能看到更新内容。
|
|
2055
|
+
*/
|
|
2056
|
+
function HubUpdateModal({ info, lang, t, hasUpdate, onProceed, onClose }) {
|
|
2057
|
+
const notesRaw = typeof info.notes === "string" ? info.notes : info.notes && typeof info.notes === "object" ? lang === "en" ? info.notes.en ?? info.notes.zh ?? "" : info.notes.zh ?? info.notes.en ?? "" : "";
|
|
2058
|
+
const notesHtml = notesRaw.trim() ? renderMarkdown(notesRaw) : null;
|
|
2059
|
+
let published = null;
|
|
2060
|
+
if (info.publishedAt) {
|
|
2061
|
+
const d = new Date(info.publishedAt);
|
|
2062
|
+
if (!Number.isNaN(d.getTime())) published = d.toLocaleString(lang === "en" ? "en-US" : "zh-CN");
|
|
2063
|
+
}
|
|
2064
|
+
return (0, react.createElement)("div", {
|
|
2065
|
+
className: Modal_module_css_default.overlay,
|
|
2066
|
+
onClick: (e) => {
|
|
2067
|
+
if (e.target === e.currentTarget) onClose();
|
|
2068
|
+
}
|
|
2069
|
+
}, (0, react.createElement)("div", {
|
|
2070
|
+
className: `${Modal_module_css_default.modal} ${Modal_module_css_default.hubUpdateModal}`,
|
|
2071
|
+
role: "dialog",
|
|
2072
|
+
"aria-modal": "true"
|
|
2073
|
+
}, (0, react.createElement)("div", { className: Modal_module_css_default.modalHead }, (0, react.createElement)("div", { className: Modal_module_css_default.modalTitle }, t(hasUpdate ? "hubUpdateTitle" : "hubCurrentTitle")), (0, react.createElement)("button", {
|
|
2074
|
+
className: Modal_module_css_default.modalClose,
|
|
2075
|
+
"aria-label": t("confirmCancel"),
|
|
2076
|
+
onClick: () => onClose()
|
|
2077
|
+
}, (0, react.createElement)(CloseIcon))), (0, react.createElement)("div", { className: Modal_module_css_default.modalDesc }, t(hasUpdate ? "hubUpdateDesc" : "hubCurrentDesc", { version: info.version })), (0, react.createElement)("div", { className: Modal_module_css_default.hubUpdateMeta }, (0, react.createElement)("span", { className: Modal_module_css_default.hubUpdateMetaItem }, `${t("version")} ${info.version}`), published ? (0, react.createElement)("span", { className: Modal_module_css_default.hubUpdateMetaItem }, `${t("hubUpdatePublished")} ${published}`) : null), notesHtml ? (0, react.createElement)("div", {
|
|
2078
|
+
className: Modal_module_css_default.hubUpdateNotes,
|
|
2079
|
+
dangerouslySetInnerHTML: { __html: notesHtml }
|
|
2080
|
+
}) : null, (0, react.createElement)("div", { className: Modal_module_css_default.modalActions }, hasUpdate ? [(0, react.createElement)("button", {
|
|
2081
|
+
className: Modal_module_css_default.restartLater,
|
|
2082
|
+
onClick: onClose
|
|
2083
|
+
}, t("hubUpdateLater")), (0, react.createElement)("button", {
|
|
2084
|
+
className: Modal_module_css_default.modalInstall,
|
|
2085
|
+
onClick: onProceed
|
|
2086
|
+
}, t("updateNow"))] : (0, react.createElement)("button", {
|
|
2087
|
+
className: Modal_module_css_default.modalInstall,
|
|
2088
|
+
onClick: onClose
|
|
2089
|
+
}, t("hubUpToDate")))));
|
|
2090
|
+
}
|
|
2091
|
+
//#endregion
|
|
1726
2092
|
//#region src/client/components/NotificationsModal.tsx
|
|
1727
2093
|
/**
|
|
2094
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2095
|
+
* Website: https://dsh-plugin.org
|
|
2096
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2097
|
+
*
|
|
1728
2098
|
* Notification-center dialog: a persistent log of every settled install /
|
|
1729
2099
|
* remove task — successes and failures alike.
|
|
1730
2100
|
*
|
|
@@ -1816,7 +2186,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1816
2186
|
})), (0, react.createElement)("span", { className: Modal_module_css_default.queueRowPct }, `${q.progress}%`))))) : null]) : null, records.length === 0 ? (0, react.createElement)("div", { className: Modal_module_css_default.failEmpty }, t("notificationsEmpty")) : (0, react.createElement)("div", { className: Modal_module_css_default.noticeList }, records.map((r) => {
|
|
1817
2187
|
return (0, react.createElement)("div", {
|
|
1818
2188
|
key: r.id,
|
|
1819
|
-
className: Modal_module_css_default.noticeRow
|
|
2189
|
+
className: r.ok ? `${Modal_module_css_default.noticeRow} ${Modal_module_css_default.noticeRowOk}` : Modal_module_css_default.noticeRow
|
|
1820
2190
|
}, (0, react.createElement)("div", { className: Modal_module_css_default.noticeRowMain }, (0, react.createElement)("div", { className: r.ok ? Modal_module_css_default.noticeBadgeOk : Modal_module_css_default.noticeBadgeFail }, (0, react.createElement)(BadgeGlyph, { ok: r.ok })), (0, react.createElement)("div", { className: Modal_module_css_default.noticeMain }, (0, react.createElement)("div", { className: Modal_module_css_default.noticeHead }, (0, react.createElement)("span", { className: r.ok ? Modal_module_css_default.noticeTextOk : Modal_module_css_default.noticeTextFail }, r.ok ? r.kind === "install" ? t("installDone") : t("uninstallDone") : r.kind === "install" ? t("errorTitleInstall") : t("errorTitleUninstall")), r.repo ? (0, react.createElement)("a", {
|
|
1821
2191
|
className: Modal_module_css_default.failRepo,
|
|
1822
2192
|
href: pluginSiteUrl(r.repo),
|
|
@@ -1826,7 +2196,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1826
2196
|
}, r.repo) : null, !r.ok && (0, react.createElement)("button", {
|
|
1827
2197
|
className: Modal_module_css_default.failCopy,
|
|
1828
2198
|
onClick: () => onCopy(r.message)
|
|
1829
|
-
}, t("failCopy")), (0, react.createElement)("
|
|
2199
|
+
}, t("failCopy")), r.ok ? (0, react.createElement)("span", {
|
|
2200
|
+
className: Modal_module_css_default.noticeTime,
|
|
2201
|
+
title: new Date(r.at).toLocaleString()
|
|
2202
|
+
}, fmtTime(r.at)) : null, (0, react.createElement)("button", {
|
|
1830
2203
|
className: Modal_module_css_default.noticeRemove,
|
|
1831
2204
|
"aria-label": t("removeNotification"),
|
|
1832
2205
|
title: t("removeNotification"),
|
|
@@ -1850,10 +2223,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1850
2223
|
rel: "noopener noreferrer",
|
|
1851
2224
|
title: t("failIssueHint")
|
|
1852
2225
|
}, t("failIssueBig")) : null;
|
|
1853
|
-
})())), (0, react.createElement)("div", { className: Modal_module_css_default.noticeFoot }, (0, react.createElement)("span", {
|
|
2226
|
+
})())), !r.ok ? (0, react.createElement)("div", { className: Modal_module_css_default.noticeFoot }, (0, react.createElement)("span", {
|
|
1854
2227
|
className: Modal_module_css_default.noticeTime,
|
|
1855
2228
|
title: new Date(r.at).toLocaleString()
|
|
1856
|
-
}, fmtTime(r.at))));
|
|
2229
|
+
}, fmtTime(r.at))) : null);
|
|
1857
2230
|
})), (0, react.createElement)("div", { className: Modal_module_css_default.modalActions }, records.length > 0 ? (0, react.createElement)("button", {
|
|
1858
2231
|
className: Modal_module_css_default.failClear,
|
|
1859
2232
|
onClick: onClear
|
|
@@ -1865,10 +2238,14 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1865
2238
|
//#endregion
|
|
1866
2239
|
//#region src/client/components/CatalogHeader.tsx
|
|
1867
2240
|
/**
|
|
2241
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2242
|
+
* Website: https://dsh-plugin.org
|
|
2243
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2244
|
+
*
|
|
1868
2245
|
* Section header: brand title row (H1 + open-site button) + tagline, followed
|
|
1869
2246
|
* by the purple ad banner that promotes the catalog stats.
|
|
1870
2247
|
*/
|
|
1871
|
-
function CatalogHeader({ t, langPath, statsTotal, statsVerified, onToggleLang }) {
|
|
2248
|
+
function CatalogHeader({ t, langPath, statsTotal, statsVerified, onToggleLang, hubUpdate, onVersionClick, onAboutClick }) {
|
|
1872
2249
|
return (0, react.createElement)(react.Fragment, null, (0, react.createElement)("div", { className: Header_module_css_default.header }, (0, react.createElement)("div", { className: Header_module_css_default.headerTitleRow }, (0, react.createElement)("a", {
|
|
1873
2250
|
className: Header_module_css_default.brandTitle,
|
|
1874
2251
|
href: `${SITE_URL}${langPath}`,
|
|
@@ -1876,13 +2253,25 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1876
2253
|
rel: "noopener noreferrer",
|
|
1877
2254
|
title: t("openHint"),
|
|
1878
2255
|
"aria-label": t("openHint")
|
|
1879
|
-
}, (0, react.createElement)(LogoIcon), (0, react.createElement)("h1", { className: Header_module_css_default.title }, t("title")
|
|
2256
|
+
}, (0, react.createElement)(LogoIcon), (0, react.createElement)("h1", { className: Header_module_css_default.title }, t("title"))), (0, react.createElement)("button", {
|
|
2257
|
+
className: Header_module_css_default.versionBtn,
|
|
2258
|
+
type: "button",
|
|
2259
|
+
onClick: onVersionClick,
|
|
2260
|
+
title: t(hubUpdate ? "hubUpdateHint" : "versionHint"),
|
|
2261
|
+
"aria-label": t(hubUpdate ? "hubUpdateHint" : "versionHint")
|
|
2262
|
+
}, `v${PLUGIN_VERSION}`, hubUpdate && (0, react.createElement)("span", { className: Header_module_css_default.hubUpdateBadge }, t("update"))), (0, react.createElement)("div", { className: Header_module_css_default.headerRight }, (0, react.createElement)("button", {
|
|
1880
2263
|
className: Header_module_css_default.langBtn,
|
|
1881
2264
|
type: "button",
|
|
1882
2265
|
onClick: onToggleLang,
|
|
1883
2266
|
title: t("toggleLangHint"),
|
|
1884
2267
|
"aria-label": t("toggleLangHint")
|
|
1885
|
-
}, langPath === "zh/" ? "EN" : "中文"), (0, react.createElement)("
|
|
2268
|
+
}, langPath === "zh/" ? "EN" : "中文"), (0, react.createElement)("button", {
|
|
2269
|
+
className: Header_module_css_default.aboutBtn,
|
|
2270
|
+
type: "button",
|
|
2271
|
+
onClick: onAboutClick,
|
|
2272
|
+
title: t("aboutDesc"),
|
|
2273
|
+
"aria-label": t("aboutTitle")
|
|
2274
|
+
}, t("followUs")), (0, react.createElement)("a", {
|
|
1886
2275
|
className: Header_module_css_default.githubLink,
|
|
1887
2276
|
href: GITHUB_URL,
|
|
1888
2277
|
target: "_blank",
|
|
@@ -1911,6 +2300,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1911
2300
|
//#endregion
|
|
1912
2301
|
//#region src/client/components/CategoryTabs.tsx
|
|
1913
2302
|
/**
|
|
2303
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2304
|
+
* Website: https://dsh-plugin.org
|
|
2305
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2306
|
+
*
|
|
1914
2307
|
* Category tabs: an "all" chip followed by one chip per catalog category.
|
|
1915
2308
|
* The "all" chip carries the total plugin count; the per-category chips
|
|
1916
2309
|
* carry no counts so their widths stay uniform.
|
|
@@ -1938,21 +2331,25 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
1938
2331
|
document.head.appendChild(tag);
|
|
1939
2332
|
}
|
|
1940
2333
|
var Dropdown_module_css_default = {
|
|
1941
|
-
"dropdownPanel": "B_Gxsq_dropdownPanel",
|
|
1942
|
-
"dropdownArrowOpen": "B_Gxsq_dropdownArrowOpen",
|
|
1943
|
-
"dropdownItemActive": "B_Gxsq_dropdownItemActive",
|
|
1944
|
-
"dropdownCountActive": "B_Gxsq_dropdownCountActive",
|
|
1945
2334
|
"dropdownLabel": "B_Gxsq_dropdownLabel",
|
|
2335
|
+
"dropdownItemActive": "B_Gxsq_dropdownItemActive",
|
|
1946
2336
|
"dropdown": "B_Gxsq_dropdown",
|
|
1947
|
-
"dropdownArrow": "B_Gxsq_dropdownArrow",
|
|
1948
2337
|
"dropdownBtn": "B_Gxsq_dropdownBtn",
|
|
1949
2338
|
"dropdownItem": "B_Gxsq_dropdownItem",
|
|
1950
|
-
"
|
|
1951
|
-
"dropdownCount": "B_Gxsq_dropdownCount"
|
|
2339
|
+
"dropdownPanel": "B_Gxsq_dropdownPanel",
|
|
2340
|
+
"dropdownCount": "B_Gxsq_dropdownCount",
|
|
2341
|
+
"dropdownCountActive": "B_Gxsq_dropdownCountActive",
|
|
2342
|
+
"dropdownArrow": "B_Gxsq_dropdownArrow",
|
|
2343
|
+
"dropdownArrowOpen": "B_Gxsq_dropdownArrowOpen",
|
|
2344
|
+
"dropdownItemLabel": "B_Gxsq_dropdownItemLabel"
|
|
1952
2345
|
};
|
|
1953
2346
|
//#endregion
|
|
1954
2347
|
//#region src/client/components/Dropdown.tsx
|
|
1955
2348
|
/**
|
|
2349
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2350
|
+
* Website: https://dsh-plugin.org
|
|
2351
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2352
|
+
*
|
|
1956
2353
|
* Custom dropdown (native <select> replacement).
|
|
1957
2354
|
*
|
|
1958
2355
|
* macOS/浏览器原生下拉无法跟随宿主主题,这里自绘:触发器按钮 + 绝对定位面板,
|
|
@@ -2005,6 +2402,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2005
2402
|
//#endregion
|
|
2006
2403
|
//#region src/client/components/CatalogControls.tsx
|
|
2007
2404
|
/**
|
|
2405
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2406
|
+
* Website: https://dsh-plugin.org
|
|
2407
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2408
|
+
*
|
|
2008
2409
|
* Toolbar above the list: search input + sort dropdown + installed / not
|
|
2009
2410
|
* installed filter buttons + the notifications entry. All buttons share the
|
|
2010
2411
|
* same size (24px high, like the notification entry button).
|
|
@@ -2063,37 +2464,37 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2063
2464
|
document.head.appendChild(tag);
|
|
2064
2465
|
}
|
|
2065
2466
|
var List_module_css_default = {
|
|
2066
|
-
"
|
|
2067
|
-
"verified": "_3XaZHa_verified",
|
|
2068
|
-
"uninstallBtn": "_3XaZHa_uninstallBtn",
|
|
2069
|
-
"actions": "_3XaZHa_actions",
|
|
2070
|
-
"stateTitle": "_3XaZHa_stateTitle",
|
|
2071
|
-
"cardMain": "_3XaZHa_cardMain",
|
|
2072
|
-
"installBtn": "_3XaZHa_installBtn",
|
|
2073
|
-
"cardTitle": "_3XaZHa_cardTitle",
|
|
2467
|
+
"body": "_3XaZHa_body",
|
|
2074
2468
|
"star": "_3XaZHa_star",
|
|
2075
|
-
"
|
|
2076
|
-
"
|
|
2077
|
-
"
|
|
2078
|
-
"stateDesc": "_3XaZHa_stateDesc",
|
|
2079
|
-
"retryBtn": "_3XaZHa_retryBtn",
|
|
2469
|
+
"footer": "_3XaZHa_footer",
|
|
2470
|
+
"footLink": "_3XaZHa_footLink",
|
|
2471
|
+
"installBtnUpdate": "_3XaZHa_installBtnUpdate",
|
|
2080
2472
|
"updateBadge": "_3XaZHa_updateBadge",
|
|
2081
|
-
"
|
|
2473
|
+
"stateTitle": "_3XaZHa_stateTitle",
|
|
2474
|
+
"fork": "_3XaZHa_fork",
|
|
2082
2475
|
"versionBadge": "_3XaZHa_versionBadge",
|
|
2476
|
+
"topic": "_3XaZHa_topic",
|
|
2083
2477
|
"state": "_3XaZHa_state",
|
|
2084
2478
|
"date": "_3XaZHa_date",
|
|
2479
|
+
"cardSide": "_3XaZHa_cardSide",
|
|
2480
|
+
"verified": "_3XaZHa_verified",
|
|
2085
2481
|
"stats": "_3XaZHa_stats",
|
|
2086
|
-
"
|
|
2482
|
+
"installBtn": "_3XaZHa_installBtn",
|
|
2483
|
+
"topics": "_3XaZHa_topics",
|
|
2484
|
+
"stateDesc": "_3XaZHa_stateDesc",
|
|
2485
|
+
"categoryBadge": "_3XaZHa_categoryBadge",
|
|
2486
|
+
"uninstallBtn": "_3XaZHa_uninstallBtn",
|
|
2087
2487
|
"cardHead": "_3XaZHa_cardHead",
|
|
2488
|
+
"detailBtn": "_3XaZHa_detailBtn",
|
|
2088
2489
|
"list": "_3XaZHa_list",
|
|
2089
2490
|
"installBtnCopied": "_3XaZHa_installBtnCopied",
|
|
2090
|
-
"
|
|
2091
|
-
"
|
|
2092
|
-
"topics": "_3XaZHa_topics",
|
|
2491
|
+
"actions": "_3XaZHa_actions",
|
|
2492
|
+
"cardTitle": "_3XaZHa_cardTitle",
|
|
2093
2493
|
"installBtnInstalled": "_3XaZHa_installBtnInstalled",
|
|
2494
|
+
"cardMain": "_3XaZHa_cardMain",
|
|
2094
2495
|
"desc": "_3XaZHa_desc",
|
|
2095
|
-
"
|
|
2096
|
-
"
|
|
2496
|
+
"retryBtn": "_3XaZHa_retryBtn",
|
|
2497
|
+
"card": "_3XaZHa_card"
|
|
2097
2498
|
};
|
|
2098
2499
|
//#endregion
|
|
2099
2500
|
//#region src/client/lib/format.ts
|
|
@@ -2116,6 +2517,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2116
2517
|
//#endregion
|
|
2117
2518
|
//#region src/client/components/PluginCard.tsx
|
|
2118
2519
|
/**
|
|
2520
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2521
|
+
* Website: https://dsh-plugin.org
|
|
2522
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2523
|
+
*
|
|
2119
2524
|
* One plugin card in the catalog list: name/category/verified badge,
|
|
2120
2525
|
* description + topics, star/fork/date stats, and the detail/install/
|
|
2121
2526
|
* uninstall actions.
|
|
@@ -2163,6 +2568,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2163
2568
|
//#endregion
|
|
2164
2569
|
//#region src/client/components/CatalogList.tsx
|
|
2165
2570
|
/**
|
|
2571
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2572
|
+
* Website: https://dsh-plugin.org
|
|
2573
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2574
|
+
*
|
|
2166
2575
|
* Catalog list: the scrollable container with the loading / failed / empty
|
|
2167
2576
|
* states, the plugin cards, and the count footer. Resets scroll position when
|
|
2168
2577
|
* the category or install-status filter changes so the replaced content is
|
|
@@ -2202,10 +2611,14 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2202
2611
|
//#endregion
|
|
2203
2612
|
//#region src/client/components/PluginHubSection.tsx
|
|
2204
2613
|
/**
|
|
2614
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2615
|
+
* Website: https://dsh-plugin.org
|
|
2616
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
2617
|
+
*
|
|
2205
2618
|
* Plugin Hub section: wires the catalog data pipeline, the background task
|
|
2206
2619
|
* queue and the feedback state together. Data/queue logic lives in hooks/,
|
|
2207
2620
|
* rendering is delegated to the small presentational components in this
|
|
2208
|
-
* folder;
|
|
2621
|
+
* folder; it hosts the dialogs/toast and the section-level copy actions.
|
|
2209
2622
|
*/
|
|
2210
2623
|
function PluginHubSection({ t: _hostT, locale }) {
|
|
2211
2624
|
/** 界面语言:默认跟随宿主(系统)语言;右上角按钮可手动切换,切换后以手动选择为准 */
|
|
@@ -2227,11 +2640,19 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2227
2640
|
const [confirmPlugin, setConfirmPlugin] = (0, react.useState)(null);
|
|
2228
2641
|
/** 弹窗动作是否为「更新」:已安装插件点「更新」→ 走同一条 add 命令原位覆盖重装,文案区分安装/更新 */
|
|
2229
2642
|
const [confirmIsUpdate, setConfirmIsUpdate] = (0, react.useState)(false);
|
|
2643
|
+
/** Hub 自我更新说明弹窗:点「可更新」徽标先展示版本 + Markdown 变更记录,确认后再进安装弹窗 */
|
|
2644
|
+
const [showHubUpdate, setShowHubUpdate] = (0, react.useState)(false);
|
|
2645
|
+
/** 「关注我们」弹窗:GitHub 图标后按钮点击打开,展示平台介绍 + 用户反馈群二维码(Worker /about 推送) */
|
|
2646
|
+
const [showAbout, setShowAbout] = (0, react.useState)(false);
|
|
2230
2647
|
/** 卸载确认弹窗:记录待卸载的插件 */
|
|
2231
2648
|
const [uninstallPlugin, setUninstallPlugin] = (0, react.useState)(null);
|
|
2232
2649
|
/** 安装/卸载完成后的结果视图:停留弹窗内,点「完成」关闭 */
|
|
2233
2650
|
const [installDone, setInstallDone] = (0, react.useState)(false);
|
|
2234
2651
|
const [uninstallDone, setUninstallDone] = (0, react.useState)(false);
|
|
2652
|
+
/** 结果视图是否给「立即重启」:服务端任务终态带出(卸载时 loader 已即时移除 → false 只给「完成」;
|
|
2653
|
+
* true 时通知中心待重启条目同步常驻,直到用户点「立即重启」真正重启后才消失) */
|
|
2654
|
+
const [installNeedsRestart, setInstallNeedsRestart] = (0, react.useState)(true);
|
|
2655
|
+
const [uninstallNeedsRestart, setUninstallNeedsRestart] = (0, react.useState)(true);
|
|
2235
2656
|
/** 结果视图「立即重启」:请求宿主重启后进入等待,服务回来后整页刷新 */
|
|
2236
2657
|
const [restarting, setRestarting] = (0, react.useState)(false);
|
|
2237
2658
|
/** 操作失败完整信息 + 所属插件仓库 + 失败类型(决定弹窗标题「安装失败/卸载失败」)+ 实际执行的安装命令 + 尝试过的安装方式(issue 预填用) */
|
|
@@ -2253,7 +2674,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2253
2674
|
const queue = useTaskQueue({
|
|
2254
2675
|
t,
|
|
2255
2676
|
refreshInstalled: catalog.refreshInstalled,
|
|
2256
|
-
onInstallDone: (viaModal, repo) => {
|
|
2677
|
+
onInstallDone: (viaModal, repo, needsRestart) => {
|
|
2678
|
+
setInstallNeedsRestart(needsRestart);
|
|
2257
2679
|
if (viaModal) setInstallDone(true);
|
|
2258
2680
|
else setToast({
|
|
2259
2681
|
id: Date.now(),
|
|
@@ -2264,7 +2686,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2264
2686
|
repo: repo ?? ""
|
|
2265
2687
|
}));
|
|
2266
2688
|
},
|
|
2267
|
-
onUninstallDone: (viaModal, repo) => {
|
|
2689
|
+
onUninstallDone: (viaModal, repo, needsRestart) => {
|
|
2690
|
+
setUninstallNeedsRestart(needsRestart);
|
|
2268
2691
|
if (viaModal) setUninstallDone(true);
|
|
2269
2692
|
else setToast({
|
|
2270
2693
|
id: Date.now(),
|
|
@@ -2303,12 +2726,14 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2303
2726
|
}
|
|
2304
2727
|
});
|
|
2305
2728
|
(0, react.useEffect)(() => {
|
|
2306
|
-
if (!confirmPlugin && !uninstallPlugin && !showNotifications) return;
|
|
2729
|
+
if (!confirmPlugin && !uninstallPlugin && !showNotifications && !showHubUpdate && !showAbout) return;
|
|
2307
2730
|
const onKey = (e) => {
|
|
2308
2731
|
if (e.key === "Escape") {
|
|
2309
2732
|
setConfirmPlugin(null);
|
|
2310
2733
|
setUninstallPlugin(null);
|
|
2311
2734
|
setUninstallDone(false);
|
|
2735
|
+
setShowHubUpdate(false);
|
|
2736
|
+
setShowAbout(false);
|
|
2312
2737
|
setShowNotifications(false);
|
|
2313
2738
|
}
|
|
2314
2739
|
};
|
|
@@ -2317,7 +2742,9 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2317
2742
|
}, [
|
|
2318
2743
|
confirmPlugin,
|
|
2319
2744
|
uninstallPlugin,
|
|
2320
|
-
showNotifications
|
|
2745
|
+
showNotifications,
|
|
2746
|
+
showHubUpdate,
|
|
2747
|
+
showAbout
|
|
2321
2748
|
]);
|
|
2322
2749
|
(0, react.useEffect)(() => {
|
|
2323
2750
|
if (!toast) return;
|
|
@@ -2402,12 +2829,16 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2402
2829
|
const statsTotal = catalog.stats?.total ?? total;
|
|
2403
2830
|
const statsVerified = catalog.stats?.verified ?? 0;
|
|
2404
2831
|
const count = catalog.visible.length;
|
|
2832
|
+
const hubEntry = catalog.plugins?.find((p) => p.source?.repo === "dshplugin/dsh-plugin-hub") ?? null;
|
|
2405
2833
|
return (0, react.createElement)("div", { className: Header_module_css_default.root }, (0, react.createElement)(CatalogHeader, {
|
|
2406
2834
|
t,
|
|
2407
2835
|
langPath,
|
|
2408
2836
|
statsTotal,
|
|
2409
2837
|
statsVerified,
|
|
2410
|
-
onToggleLang: () => setManualLang(lang === "en" ? "zh" : "en")
|
|
2838
|
+
onToggleLang: () => setManualLang(lang === "en" ? "zh" : "en"),
|
|
2839
|
+
hubUpdate: catalog.hubHasUpdate,
|
|
2840
|
+
onVersionClick: () => setShowHubUpdate(true),
|
|
2841
|
+
onAboutClick: () => setShowAbout(true)
|
|
2411
2842
|
}), (0, react.createElement)(CategoryTabs, {
|
|
2412
2843
|
category: catalog.category,
|
|
2413
2844
|
setCategory: catalog.setCategory,
|
|
@@ -2453,6 +2884,26 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2453
2884
|
queue.clearModalTask();
|
|
2454
2885
|
setUninstallPlugin(p);
|
|
2455
2886
|
}
|
|
2887
|
+
}), showHubUpdate && (0, react.createElement)(HubUpdateModal, {
|
|
2888
|
+
info: catalog.hubUpdateInfo ?? { version: "1.1.2" },
|
|
2889
|
+
lang,
|
|
2890
|
+
t,
|
|
2891
|
+
hasUpdate: catalog.hubHasUpdate,
|
|
2892
|
+
onClose: () => setShowHubUpdate(false),
|
|
2893
|
+
onProceed: () => {
|
|
2894
|
+
setShowHubUpdate(false);
|
|
2895
|
+
if (hubEntry) {
|
|
2896
|
+
setInstallDone(false);
|
|
2897
|
+
setConfirmIsUpdate(true);
|
|
2898
|
+
queue.clearModalTask();
|
|
2899
|
+
setConfirmPlugin(hubEntry);
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
}), showAbout && (0, react.createElement)(AboutModal, {
|
|
2903
|
+
info: catalog.hubAboutInfo ?? null,
|
|
2904
|
+
lang,
|
|
2905
|
+
t,
|
|
2906
|
+
onClose: () => setShowAbout(false)
|
|
2456
2907
|
}), confirmPlugin && (0, react.createElement)(InstallModal, {
|
|
2457
2908
|
plugin: confirmPlugin,
|
|
2458
2909
|
done: installDone,
|
|
@@ -2461,7 +2912,9 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2461
2912
|
langPath,
|
|
2462
2913
|
restarting,
|
|
2463
2914
|
update: confirmIsUpdate,
|
|
2915
|
+
cliOnly: confirmPlugin.install?.webInstallable === false,
|
|
2464
2916
|
submitting: queue.submitting,
|
|
2917
|
+
needsRestart: installNeedsRestart,
|
|
2465
2918
|
onClose: () => setConfirmPlugin(null),
|
|
2466
2919
|
onCopy: () => copyCommand(confirmPlugin),
|
|
2467
2920
|
onInstall: () => queue.installNow(confirmPlugin, confirmIsUpdate ? { update: true } : void 0),
|
|
@@ -2476,6 +2929,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2476
2929
|
langPath,
|
|
2477
2930
|
restarting,
|
|
2478
2931
|
submitting: queue.submitting,
|
|
2932
|
+
needsRestart: uninstallNeedsRestart,
|
|
2479
2933
|
onClose: () => {
|
|
2480
2934
|
setUninstallDone(false);
|
|
2481
2935
|
setUninstallPlugin(null);
|
|
@@ -2542,6 +2996,10 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
|
|
|
2542
2996
|
//#endregion
|
|
2543
2997
|
//#region src/client/index.tsx
|
|
2544
2998
|
/**
|
|
2999
|
+
* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
3000
|
+
* Website: https://dsh-plugin.org
|
|
3001
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
3002
|
+
*
|
|
2545
3003
|
* dsh-plugin client entry: wires the Plugin Hub into the host settings via
|
|
2546
3004
|
* the module-loader bundle (see tsdown.config.ts). All UI logic lives in
|
|
2547
3005
|
* PluginHubSection; this file only performs the cordis apply wiring.
|