dsh-plugin 1.1.2 → 1.2.1
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/client/client.js +4465 -1442
- package/client/client.js.map +1 -1
- package/lib/http/routes.js +438 -22
- package/lib/index.js +1 -1
- package/lib/services/install/install.js +4 -0
- package/lib/services/install/npm-check.js +55 -0
- package/lib/services/{npm-resolve.js → install/npm-resolve.js} +7 -5
- package/lib/services/{preflight.js → install/preflight.js} +15 -4
- package/lib/services/{task-queue.js → install/task-queue.js} +155 -66
- package/lib/services/loader.js +56 -1
- package/lib/services/log.js +138 -0
- package/lib/services/probe.js +157 -0
- package/lib/services/{profile.js → profile/profile.js} +29 -1
- package/lib/services/settings.js +60 -0
- package/lib/types/http/routes.d.ts +1 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/services/{install-types.d.ts → install/install-types.d.ts} +3 -0
- package/lib/types/services/{install.d.ts → install/install.d.ts} +5 -5
- package/lib/types/services/install/npm-check.d.ts +12 -0
- package/lib/types/services/{npm-resolve.d.ts → install/npm-resolve.d.ts} +2 -1
- package/lib/types/services/{task-queue.d.ts → install/task-queue.d.ts} +5 -1
- package/lib/types/services/loader.d.ts +14 -8
- package/lib/types/services/log.d.ts +49 -0
- package/lib/types/services/probe.d.ts +30 -0
- package/lib/types/services/{pending-restart.d.ts → profile/pending-restart.d.ts} +1 -1
- package/lib/types/services/{profile.d.ts → profile/profile.d.ts} +2 -0
- package/lib/types/services/settings.d.ts +24 -0
- package/package.json +1 -1
- package/src/client/components/PluginHubSection.tsx +341 -120
- package/src/client/components/{CatalogList.tsx → catalog/CatalogList.tsx} +11 -7
- package/src/client/components/{PluginCard.tsx → catalog/PluginCard.tsx} +5 -4
- package/src/client/components/layout/CatalogControls.tsx +80 -0
- package/src/client/components/{CatalogHeader.tsx → layout/CatalogHeader.tsx} +4 -4
- package/src/client/components/{CategoryTabs.tsx → layout/CategoryTabs.tsx} +3 -3
- package/src/client/components/layout/SectionTabs.tsx +60 -0
- package/src/client/components/{AboutModal.tsx → modals/AboutModal.tsx} +7 -7
- package/src/client/components/{HubUpdateModal.tsx → modals/HubUpdateModal.tsx} +5 -5
- package/src/client/components/modals/InstalledDetailModal.tsx +193 -0
- package/src/client/components/modals/LogsModal.tsx +301 -0
- package/src/client/components/modals/LogsPathModal.tsx +161 -0
- package/src/client/components/{NotificationsModal.tsx → modals/NotificationsModal.tsx} +47 -20
- package/src/client/components/{ProgressView.tsx → modals/ProgressView.tsx} +2 -2
- package/src/client/components/{modals.tsx → modals/modals.tsx} +117 -40
- package/src/client/components/{Dropdown.tsx → ui/Dropdown.tsx} +14 -6
- package/src/client/components/ui/Toggle.tsx +28 -0
- package/src/client/components/ui/icons.tsx +343 -0
- package/src/client/components/views/CustomInstallView.tsx +250 -0
- package/src/client/components/views/DiagnosticsView.tsx +172 -0
- package/src/client/components/views/InstalledView.tsx +328 -0
- package/src/client/components/views/LogsView.tsx +150 -0
- package/src/client/components/views/MarketView.tsx +66 -0
- package/src/client/components/views/SettingsView.tsx +273 -0
- package/src/client/data/catalog.ts +38 -0
- package/src/client/data/host.ts +107 -0
- package/src/client/data/hub.ts +41 -0
- package/src/client/hooks/useCatalog.ts +71 -115
- package/src/client/hooks/useIncrementalList.ts +46 -0
- package/src/client/hooks/useLanguage.ts +40 -0
- package/src/client/hooks/useSettings.ts +90 -0
- package/src/client/hooks/useTaskQueue.ts +156 -39
- package/src/client/locales.ts +358 -38
- package/src/client/logic/constants.ts +86 -0
- package/src/client/{lib → logic}/failures.ts +95 -74
- package/src/client/logic/install-command.ts +56 -0
- package/src/client/logic/installed.ts +207 -0
- package/src/client/logic/normalize.ts +52 -0
- package/src/client/logic/urls.ts +125 -0
- package/src/client/styles/CustomInstallView.module.css +191 -0
- package/src/client/styles/DiagnosticsView.module.css +231 -0
- package/src/client/styles/Dropdown.module.css +42 -41
- package/src/client/styles/Header.module.css +100 -132
- package/src/client/styles/InstalledView.module.css +447 -0
- package/src/client/styles/List.module.css +6 -0
- package/src/client/styles/LogsView.module.css +503 -0
- package/src/client/styles/Modal.module.css +352 -70
- package/src/client/styles/SectionTabs.module.css +142 -0
- package/src/client/styles/SettingsView.module.css +232 -0
- package/src/client/styles/Toggle.module.css +60 -0
- package/src/client/styles/tokens.module.css +1 -0
- package/src/client/types.ts +23 -3
- package/src/server/http/routes.ts +414 -22
- package/src/server/index.ts +1 -1
- package/src/server/services/{install-types.ts → install/install-types.ts} +3 -1
- package/src/server/services/{install.ts → install/install.ts} +5 -5
- package/src/server/services/install/npm-check.ts +53 -0
- package/src/server/services/{npm-resolve.ts → install/npm-resolve.ts} +7 -5
- package/src/server/services/{preflight.ts → install/preflight.ts} +16 -4
- package/src/server/services/{task-queue.ts → install/task-queue.ts} +157 -63
- package/src/server/services/loader.ts +55 -1
- package/src/server/services/log.ts +167 -0
- package/src/server/services/probe.ts +157 -0
- package/src/server/services/{pending-restart.ts → profile/pending-restart.ts} +1 -1
- package/src/server/services/{profile.ts → profile/profile.ts} +31 -1
- package/src/server/services/settings.ts +79 -0
- package/lib/services/install.js +0 -4
- package/src/client/components/CatalogControls.tsx +0 -108
- package/src/client/components/icons.tsx +0 -129
- package/src/client/lib/catalog.ts +0 -293
- package/src/client/lib/env.ts +0 -20
- /package/lib/services/{install-types.js → install/install-types.js} +0 -0
- /package/lib/services/{installed-versions.js → profile/installed-versions.js} +0 -0
- /package/lib/services/{pending-restart.js → profile/pending-restart.js} +0 -0
- /package/lib/services/{progress.js → profile/progress.js} +0 -0
- /package/lib/types/services/{preflight.d.ts → install/preflight.d.ts} +0 -0
- /package/lib/types/services/{installed-versions.d.ts → profile/installed-versions.d.ts} +0 -0
- /package/lib/types/services/{progress.d.ts → profile/progress.d.ts} +0 -0
- /package/src/client/{lib → logic}/format.ts +0 -0
- /package/src/client/{lib → logic}/renderMarkdown.ts +0 -0
- /package/src/server/services/{installed-versions.ts → profile/installed-versions.ts} +0 -0
- /package/src/server/services/{progress.ts → profile/progress.ts} +0 -0
|
@@ -223,16 +223,28 @@
|
|
|
223
223
|
text-overflow: ellipsis;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
/* 工具栏第二行:左侧筛选结果数 + 右侧排序按钮组(排序组靠 auto 顶到行尾);
|
|
227
|
+
分隔线收在行底,与插件列表之间一条横线 */
|
|
226
228
|
.controls {
|
|
227
229
|
display: flex;
|
|
228
230
|
align-items: center;
|
|
229
|
-
gap:
|
|
231
|
+
gap: 8px;
|
|
230
232
|
flex-shrink: 0;
|
|
231
|
-
|
|
233
|
+
padding: 0 2px 8px;
|
|
234
|
+
border-bottom: 1px solid var(--hub-border-1);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* 结果数里的数字:等宽数字 + 固定 5 位宽度;数字在预留位中始终居中,两侧位置都固定不跳动 */
|
|
238
|
+
.resultCount {
|
|
239
|
+
font-variant-numeric: tabular-nums;
|
|
240
|
+
min-width: 5ch;
|
|
241
|
+
text-align: center;
|
|
232
242
|
}
|
|
233
243
|
|
|
234
|
-
/*
|
|
235
|
-
|
|
244
|
+
/* —— result count —— */
|
|
245
|
+
|
|
246
|
+
/* 筛选结果数:弱化灰字信息「结果 N 条插件」,位于工具栏行最左侧 */
|
|
247
|
+
.resultSeg {
|
|
236
248
|
flex-shrink: 0;
|
|
237
249
|
display: inline-flex;
|
|
238
250
|
align-items: baseline;
|
|
@@ -240,13 +252,76 @@
|
|
|
240
252
|
line-height: 18px;
|
|
241
253
|
color: var(--hub-text-tertiary);
|
|
242
254
|
white-space: nowrap;
|
|
255
|
+
user-select: none;
|
|
243
256
|
}
|
|
244
257
|
|
|
245
|
-
/*
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
258
|
+
/* —— 排序按钮组(与已安装视图同款 segmented control)——
|
|
259
|
+
组前小标签 + 按钮组,靠 margin-left:auto 顶到结果数右侧行尾 */
|
|
260
|
+
|
|
261
|
+
/* 排序组容器:整体右对齐,独立一行内容不换行 */
|
|
262
|
+
.sortGroup {
|
|
263
|
+
margin-left: auto;
|
|
264
|
+
flex-shrink: 0;
|
|
265
|
+
display: inline-flex;
|
|
266
|
+
align-items: center;
|
|
267
|
+
gap: 8px;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* 组前小标签:灰字,标注这组按钮的作用 */
|
|
271
|
+
.segLabel {
|
|
272
|
+
flex-shrink: 0;
|
|
273
|
+
font-size: 11px;
|
|
274
|
+
line-height: 16px;
|
|
275
|
+
color: var(--hub-text-tertiary);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.segGroup {
|
|
279
|
+
display: inline-flex;
|
|
280
|
+
align-items: center;
|
|
281
|
+
flex-shrink: 0;
|
|
282
|
+
border: 1px solid var(--hub-border-2);
|
|
283
|
+
border-radius: 6px;
|
|
284
|
+
overflow: hidden;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.segBtn {
|
|
288
|
+
font-family: inherit;
|
|
289
|
+
font-size: 12px;
|
|
290
|
+
line-height: 24px;
|
|
291
|
+
height: 24px;
|
|
292
|
+
padding: 0 10px;
|
|
293
|
+
display: inline-flex;
|
|
294
|
+
align-items: center;
|
|
295
|
+
justify-content: center;
|
|
296
|
+
gap: 4px;
|
|
297
|
+
color: var(--hub-text-secondary);
|
|
298
|
+
background: transparent;
|
|
299
|
+
border: none;
|
|
300
|
+
cursor: pointer;
|
|
301
|
+
user-select: none;
|
|
302
|
+
white-space: nowrap;
|
|
303
|
+
transition: color 120ms ease, background 120ms ease;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/* 激活排序按钮上的方向箭头:随文字色着色、不可被压缩 */
|
|
307
|
+
.segBtn svg {
|
|
308
|
+
flex-shrink: 0;
|
|
309
|
+
display: block;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.segBtn + .segBtn {
|
|
313
|
+
border-left: 1px solid var(--hub-border-2);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.segBtn:hover {
|
|
317
|
+
color: var(--hub-text-primary);
|
|
318
|
+
background: var(--hub-bg-hover);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.segBtnActive,
|
|
322
|
+
.segBtnActive:hover {
|
|
323
|
+
color: #fff;
|
|
324
|
+
background: var(--hub-brand);
|
|
250
325
|
}
|
|
251
326
|
|
|
252
327
|
/* —— ad banner —— */
|
|
@@ -307,19 +382,23 @@
|
|
|
307
382
|
|
|
308
383
|
.searchRow {
|
|
309
384
|
display: flex;
|
|
385
|
+
align-items: center;
|
|
386
|
+
gap: 6px;
|
|
310
387
|
padding: 0 2px;
|
|
311
388
|
}
|
|
312
389
|
|
|
313
|
-
/*
|
|
390
|
+
/* 搜索框:整行占满(排序已移出到结果数下方的按钮组行,搜索框独占整行) */
|
|
314
391
|
.search {
|
|
315
|
-
|
|
392
|
+
flex: 1 1 auto;
|
|
393
|
+
min-width: 0;
|
|
394
|
+
height: 28px;
|
|
395
|
+
padding: 0 9px;
|
|
316
396
|
font-size: 12px;
|
|
317
|
-
line-height:
|
|
397
|
+
line-height: 26px;
|
|
318
398
|
color: inherit;
|
|
319
399
|
background: transparent;
|
|
320
400
|
border: 1px solid var(--hub-border-2);
|
|
321
401
|
border-radius: 6px;
|
|
322
|
-
padding: 4px 9px;
|
|
323
402
|
outline: none;
|
|
324
403
|
transition: border-color 120ms ease;
|
|
325
404
|
}
|
|
@@ -332,79 +411,6 @@
|
|
|
332
411
|
border-color: var(--hub-brand);
|
|
333
412
|
}
|
|
334
413
|
|
|
335
|
-
/* —— install-state filter —— */
|
|
336
|
-
|
|
337
|
-
/* 已安装 / 未安装:两个独立按钮,外观尺寸与「安装失败记录」按钮一致(高 24px);
|
|
338
|
-
各自点击筛选对应安装状态,再点一次恢复全部。公共规则统一无边框,
|
|
339
|
-
避免激活态回落到浏览器默认 2px 边框导致点击时按钮变粗跳动。 */
|
|
340
|
-
.installedBtn,
|
|
341
|
-
.installedBtnActive,
|
|
342
|
-
.installedBtnDisabled {
|
|
343
|
-
flex-shrink: 0;
|
|
344
|
-
display: inline-flex;
|
|
345
|
-
align-items: center;
|
|
346
|
-
gap: 5px;
|
|
347
|
-
height: 24px;
|
|
348
|
-
padding: 0 8px;
|
|
349
|
-
border: none;
|
|
350
|
-
border-radius: 6px;
|
|
351
|
-
font-size: 12px;
|
|
352
|
-
line-height: 22px;
|
|
353
|
-
cursor: pointer;
|
|
354
|
-
user-select: none;
|
|
355
|
-
transition: color 120ms ease, background 120ms ease;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
.installedBtn {
|
|
359
|
-
color: var(--hub-text-primary);
|
|
360
|
-
background: transparent;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/* 悬浮:明显加重底色,保证「看得见、点得准」。 */
|
|
364
|
-
.installedBtn:hover {
|
|
365
|
-
color: var(--hub-text-primary);
|
|
366
|
-
background: var(--hub-bg-hover);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/* 置灰:当前分类下无对应安装状态的插件时不可点;尺寸保持 24px 不塌陷,
|
|
370
|
-
文字弱化,配合 disabled 属性天然屏蔽 hover/点击。 */
|
|
371
|
-
.installedBtnDisabled,
|
|
372
|
-
.installedBtnDisabled:hover {
|
|
373
|
-
color: var(--hub-text-disabled);
|
|
374
|
-
background: transparent;
|
|
375
|
-
cursor: not-allowed;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
.installedBtnDisabled .segCount {
|
|
379
|
-
color: var(--hub-text-disabled);
|
|
380
|
-
background: rgba(128, 128, 128, 0.06);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
.installedBtnActive {
|
|
384
|
-
color: var(--hub-text-on-fill);
|
|
385
|
-
background: var(--hub-btn-fill);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
.segCount,
|
|
389
|
-
.segCountActive {
|
|
390
|
-
font-size: 10px;
|
|
391
|
-
line-height: 14px;
|
|
392
|
-
border-radius: 999px;
|
|
393
|
-
padding: 0 4px;
|
|
394
|
-
min-width: 14px;
|
|
395
|
-
text-align: center;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
.segCount {
|
|
399
|
-
color: var(--hub-text-tertiary);
|
|
400
|
-
background: var(--hub-bg-btn);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
.installedBtnActive .segCountActive {
|
|
404
|
-
color: var(--hub-text-on-fill);
|
|
405
|
-
background: var(--hub-bg-on-fill);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
414
|
/* —— category chips —— */
|
|
409
415
|
|
|
410
416
|
.tabs {
|
|
@@ -464,53 +470,15 @@
|
|
|
464
470
|
background: var(--hub-bg-on-fill);
|
|
465
471
|
}
|
|
466
472
|
|
|
467
|
-
/*
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
box-sizing: border-box 让 1px 边框包含在 24px 高度内,与「已安装/未安装」无边框按钮外尺寸一致;
|
|
471
|
-
有通知时右上角悬浮的红圈白字徽标成为提醒焦点 */
|
|
472
|
-
.failBtn {
|
|
473
|
-
position: relative;
|
|
474
|
-
flex-shrink: 0;
|
|
475
|
-
/* 与左侧操作按钮分开:自动吃掉剩余空间,把按钮顶到控件行最右 */
|
|
476
|
-
margin-left: auto;
|
|
477
|
-
display: inline-flex;
|
|
473
|
+
/* 一级导航行:tab 占满左侧 */
|
|
474
|
+
.tabsRow {
|
|
475
|
+
display: flex;
|
|
478
476
|
align-items: center;
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
padding: 0 10px;
|
|
482
|
-
border: 1px solid var(--hub-border-2);
|
|
483
|
-
border-radius: 6px;
|
|
484
|
-
font-size: 12px;
|
|
485
|
-
line-height: 22px;
|
|
486
|
-
color: var(--hub-text-primary);
|
|
487
|
-
background: var(--hub-bg-hover);
|
|
488
|
-
cursor: pointer;
|
|
489
|
-
user-select: none;
|
|
490
|
-
transition: color 120ms ease, background 120ms ease;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
.failBtn:hover {
|
|
494
|
-
color: var(--hub-text-primary);
|
|
495
|
-
background: rgba(128, 128, 128, 0.28);
|
|
477
|
+
gap: 10px;
|
|
478
|
+
flex-shrink: 0;
|
|
496
479
|
}
|
|
497
480
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
position: absolute;
|
|
502
|
-
top: -16px;
|
|
503
|
-
right: -7px;
|
|
504
|
-
z-index: 1;
|
|
505
|
-
min-width: 16px;
|
|
506
|
-
height: 16px;
|
|
507
|
-
padding: 0 5px;
|
|
508
|
-
border-radius: 999px;
|
|
509
|
-
font-size: 10px;
|
|
510
|
-
font-weight: 600;
|
|
511
|
-
line-height: 16px;
|
|
512
|
-
text-align: center;
|
|
513
|
-
color: #ffffff;
|
|
514
|
-
background: var(--hub-danger);
|
|
515
|
-
box-shadow: 0 1px 4px rgba(209, 36, 47, 0.4);
|
|
481
|
+
.tabsRow > :first-child {
|
|
482
|
+
flex: 1 1 auto;
|
|
483
|
+
min-width: 0;
|
|
516
484
|
}
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
/* DSH-Plugin Hub — the community plugin marketplace for DeepSeek Harness.
|
|
2
|
+
* Website: https://dsh-plugin.org
|
|
3
|
+
* GitHub: https://github.com/dshplugin/dsh-plugin-hub
|
|
4
|
+
*
|
|
5
|
+
* Installed view: searchable, sortable list of installed plugins mixing
|
|
6
|
+
* catalog plugins (full metadata) and custom installs (runtime info only,
|
|
7
|
+
* amber custom badge). The toolbar holds a search box plus two segmented
|
|
8
|
+
* radio-button groups (source filter + sort). Each row has three tidy
|
|
9
|
+
* lines: title line (running-status dot + name + version/update badges +
|
|
10
|
+
* fixed action buttons on the right), meta line (repo · category), and a
|
|
11
|
+
* one-line description. Colors resolve through the --hub-* tokens. */
|
|
12
|
+
|
|
13
|
+
.root {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: 8px;
|
|
17
|
+
min-width: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* —— 工具栏:「已安装插件」列表上方 ——
|
|
21
|
+
第一行搜索框(撑满整行),第二行来源筛选按钮组 + 排序按钮组;
|
|
22
|
+
hairline 与下方列表区隔 */
|
|
23
|
+
|
|
24
|
+
.toolbar {
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
gap: 8px;
|
|
28
|
+
flex-shrink: 0;
|
|
29
|
+
padding: 0 2px 10px;
|
|
30
|
+
border-bottom: 1px solid var(--hub-border-1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* 搜索框容器:撑满整行宽度,与按钮组等视觉高度 */
|
|
34
|
+
.searchWrap {
|
|
35
|
+
width: 100%;
|
|
36
|
+
height: 28px;
|
|
37
|
+
min-width: 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* 搜索输入:28px 与下拉触发器等高 */
|
|
41
|
+
.searchInput {
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 28px;
|
|
44
|
+
padding: 0 9px;
|
|
45
|
+
font-size: 12px;
|
|
46
|
+
line-height: 26px;
|
|
47
|
+
color: var(--hub-text-primary);
|
|
48
|
+
background: transparent;
|
|
49
|
+
border: 1px solid var(--hub-border-2);
|
|
50
|
+
border-radius: 6px;
|
|
51
|
+
outline: none;
|
|
52
|
+
transition: border-color 120ms ease;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.searchInput::placeholder {
|
|
56
|
+
color: var(--hub-text-tertiary);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.searchInput:focus {
|
|
60
|
+
border-color: var(--hub-brand);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* —— 单选按钮组(segmented control):来源筛选 / 排序 ——
|
|
64
|
+
一组一个描边容器,按钮间竖线分隔,选中项品牌色实底 */
|
|
65
|
+
|
|
66
|
+
.segRow {
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: 8px;
|
|
70
|
+
min-width: 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* 组前小标签:灰字,标注这组按钮的作用 */
|
|
74
|
+
.segLabel {
|
|
75
|
+
flex-shrink: 0;
|
|
76
|
+
font-size: 11px;
|
|
77
|
+
line-height: 16px;
|
|
78
|
+
color: var(--hub-text-tertiary);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.segGroup {
|
|
82
|
+
display: inline-flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
flex-shrink: 0;
|
|
85
|
+
border: 1px solid var(--hub-border-2);
|
|
86
|
+
border-radius: 6px;
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.segBtn {
|
|
91
|
+
font-family: inherit;
|
|
92
|
+
font-size: 12px;
|
|
93
|
+
line-height: 24px;
|
|
94
|
+
height: 24px;
|
|
95
|
+
padding: 0 10px;
|
|
96
|
+
display: inline-flex;
|
|
97
|
+
align-items: center;
|
|
98
|
+
justify-content: center;
|
|
99
|
+
gap: 4px;
|
|
100
|
+
color: var(--hub-text-secondary);
|
|
101
|
+
background: transparent;
|
|
102
|
+
border: none;
|
|
103
|
+
cursor: pointer;
|
|
104
|
+
user-select: none;
|
|
105
|
+
white-space: nowrap;
|
|
106
|
+
transition: color 120ms ease, background 120ms ease;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* 激活排序按钮上的方向箭头:随文字色着色、不可被压缩 */
|
|
110
|
+
.segBtn svg {
|
|
111
|
+
flex-shrink: 0;
|
|
112
|
+
display: block;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.segBtn + .segBtn {
|
|
116
|
+
border-left: 1px solid var(--hub-border-2);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.segBtn:hover {
|
|
120
|
+
color: var(--hub-text-primary);
|
|
121
|
+
background: var(--hub-bg-hover);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.segBtnActive,
|
|
125
|
+
.segBtnActive:hover {
|
|
126
|
+
color: #fff;
|
|
127
|
+
background: var(--hub-brand);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* —— 空态 / 搜索无结果 —— */
|
|
131
|
+
|
|
132
|
+
.empty {
|
|
133
|
+
display: flex;
|
|
134
|
+
flex-direction: column;
|
|
135
|
+
align-items: center;
|
|
136
|
+
gap: 4px;
|
|
137
|
+
padding: 36px 12px;
|
|
138
|
+
font-size: 12px;
|
|
139
|
+
line-height: 18px;
|
|
140
|
+
color: var(--hub-text-tertiary);
|
|
141
|
+
text-align: center;
|
|
142
|
+
border: 1px dashed var(--hub-border-2);
|
|
143
|
+
border-radius: 8px;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.emptyTitle {
|
|
147
|
+
font-size: 13px;
|
|
148
|
+
font-weight: 600;
|
|
149
|
+
color: var(--hub-text-secondary);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.emptyDesc {
|
|
153
|
+
color: var(--hub-text-tertiary);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* —— 行列表 —— */
|
|
157
|
+
|
|
158
|
+
.list {
|
|
159
|
+
display: flex;
|
|
160
|
+
flex-direction: column;
|
|
161
|
+
list-style: none;
|
|
162
|
+
margin: 0;
|
|
163
|
+
padding: 0;
|
|
164
|
+
border: 1px solid var(--hub-border-1);
|
|
165
|
+
border-radius: 8px;
|
|
166
|
+
overflow: hidden;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.row {
|
|
170
|
+
display: flex;
|
|
171
|
+
flex-direction: column;
|
|
172
|
+
gap: 4px;
|
|
173
|
+
padding: 8px 10px;
|
|
174
|
+
background: var(--hub-bg-1);
|
|
175
|
+
cursor: pointer;
|
|
176
|
+
user-select: none;
|
|
177
|
+
transition: background 120ms ease;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.row + .row {
|
|
181
|
+
border-top: 1px solid var(--hub-border-1);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.row:hover {
|
|
185
|
+
background: var(--hub-bg-2);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* 第一行:状态点 + 名称/版本/更新徽标 + 右侧固定操作按钮组 */
|
|
189
|
+
.rowTitleLine {
|
|
190
|
+
display: flex;
|
|
191
|
+
align-items: center;
|
|
192
|
+
gap: 8px;
|
|
193
|
+
min-width: 0;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* 第三行(仅目录插件):简介单独一行,超长省略号收尾;
|
|
197
|
+
左缩进对齐名称(8 状态点 + 8 间隔 = 16px) */
|
|
198
|
+
.rowDesc {
|
|
199
|
+
padding-left: 16px;
|
|
200
|
+
font-size: 11px;
|
|
201
|
+
line-height: 16px;
|
|
202
|
+
color: var(--hub-text-tertiary);
|
|
203
|
+
white-space: nowrap;
|
|
204
|
+
overflow: hidden;
|
|
205
|
+
text-overflow: ellipsis;
|
|
206
|
+
min-width: 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* 运行状态点:绿 = 已加载进 loader(运行中);琥珀 = 已安装未挂载(装完未重启) */
|
|
210
|
+
.statusDot {
|
|
211
|
+
flex-shrink: 0;
|
|
212
|
+
width: 8px;
|
|
213
|
+
height: 8px;
|
|
214
|
+
border-radius: 50%;
|
|
215
|
+
background: var(--hub-success);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.statusDot.statusPending {
|
|
219
|
+
background: var(--hub-warning);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* 非 dsh 插件(如官方示例项目):宿主不加载,灰色点表示「未启用」而非「待重启」 */
|
|
223
|
+
.statusDot.statusInactive {
|
|
224
|
+
background: var(--hub-text-tertiary);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* 主信息:名称 + 已装版本 + 有更新徽标 */
|
|
228
|
+
.rowMain {
|
|
229
|
+
display: flex;
|
|
230
|
+
align-items: baseline;
|
|
231
|
+
gap: 6px;
|
|
232
|
+
min-width: 0;
|
|
233
|
+
flex: 1 1 auto;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.rowTitle {
|
|
237
|
+
font-size: 12px;
|
|
238
|
+
line-height: 18px;
|
|
239
|
+
font-weight: 600;
|
|
240
|
+
color: var(--hub-text-primary);
|
|
241
|
+
min-width: 0;
|
|
242
|
+
white-space: nowrap;
|
|
243
|
+
overflow: hidden;
|
|
244
|
+
text-overflow: ellipsis;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* 已装版本:等宽弱化小字 */
|
|
248
|
+
.versionBadge {
|
|
249
|
+
flex-shrink: 0;
|
|
250
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
251
|
+
font-size: 11px;
|
|
252
|
+
line-height: 16px;
|
|
253
|
+
color: var(--hub-text-tertiary);
|
|
254
|
+
background: var(--hub-bg-hover);
|
|
255
|
+
border-radius: 4px;
|
|
256
|
+
padding: 0 5px;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* 有更新徽标:品牌色实底小圆标 */
|
|
260
|
+
.updateBadge {
|
|
261
|
+
flex-shrink: 0;
|
|
262
|
+
font-size: 11px;
|
|
263
|
+
line-height: 16px;
|
|
264
|
+
font-weight: 500;
|
|
265
|
+
color: var(--hub-brand);
|
|
266
|
+
background: var(--hub-brand-tint-strong);
|
|
267
|
+
border-radius: 4px;
|
|
268
|
+
padding: 0 5px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/* 来源标签列(行尾、操作按钮前):固定宽度等宽,所有条目标签在同一列右对齐(整齐不乱)。
|
|
272
|
+
「插件中心」= 目录插件(品牌蓝描边),「手动安装」= 命令行安装(琥珀描边)。
|
|
273
|
+
两词等宽(各 4 字),宽度固定后标签列严格对齐 */
|
|
274
|
+
.rowSourceTag {
|
|
275
|
+
flex-shrink: 0;
|
|
276
|
+
width: 60px;
|
|
277
|
+
box-sizing: border-box;
|
|
278
|
+
text-align: center;
|
|
279
|
+
font-size: 11px;
|
|
280
|
+
line-height: 16px;
|
|
281
|
+
font-weight: 500;
|
|
282
|
+
border-radius: 4px;
|
|
283
|
+
padding: 0 4px;
|
|
284
|
+
white-space: nowrap;
|
|
285
|
+
overflow: hidden;
|
|
286
|
+
text-overflow: ellipsis;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.rowSourceTagHub {
|
|
290
|
+
color: var(--hub-brand);
|
|
291
|
+
background: var(--hub-brand-tint);
|
|
292
|
+
border: 1px solid var(--hub-brand-border-soft);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.rowSourceTagManual {
|
|
296
|
+
color: var(--hub-warning);
|
|
297
|
+
background: var(--hub-warning-tint);
|
|
298
|
+
border: 1px solid var(--hub-warning-border);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* 示例项目徽标(非 dsh 插件,如官方示例仓库):品牌蓝描边 + 浅蓝底,
|
|
302
|
+
与「有更新」实底区分,表达「这是示例项目,宿主不加载」 */
|
|
303
|
+
.exampleBadge {
|
|
304
|
+
flex-shrink: 0;
|
|
305
|
+
font-size: 11px;
|
|
306
|
+
line-height: 16px;
|
|
307
|
+
font-weight: 500;
|
|
308
|
+
color: var(--hub-brand);
|
|
309
|
+
background: var(--hub-brand-tint);
|
|
310
|
+
border: 1px solid var(--hub-brand-border-soft);
|
|
311
|
+
border-radius: 4px;
|
|
312
|
+
padding: 0 5px;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* 示例项目徽标行:独立一行,左缩进对齐名称(8 状态点 + 8 间隔 = 16px),
|
|
316
|
+
标签可完整显示不换行,不受名称行宽度挤压 */
|
|
317
|
+
.exampleRow {
|
|
318
|
+
display: flex;
|
|
319
|
+
align-items: center;
|
|
320
|
+
padding-left: 16px;
|
|
321
|
+
min-width: 0;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* 第二行元信息:仓库 · 分类 —— 独立成行,左缩进与名称对齐,不再挤压名称 */
|
|
325
|
+
.rowMeta {
|
|
326
|
+
display: flex;
|
|
327
|
+
align-items: center;
|
|
328
|
+
gap: 8px;
|
|
329
|
+
padding-left: 16px;
|
|
330
|
+
min-width: 0;
|
|
331
|
+
overflow: hidden;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.rowRepo {
|
|
335
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
336
|
+
font-size: 11px;
|
|
337
|
+
line-height: 16px;
|
|
338
|
+
color: var(--hub-text-tertiary);
|
|
339
|
+
min-width: 0;
|
|
340
|
+
white-space: nowrap;
|
|
341
|
+
overflow: hidden;
|
|
342
|
+
text-overflow: ellipsis;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.rowCategory {
|
|
346
|
+
flex-shrink: 0;
|
|
347
|
+
font-size: 11px;
|
|
348
|
+
line-height: 16px;
|
|
349
|
+
color: var(--hub-text-tertiary);
|
|
350
|
+
background: var(--hub-bg-hover);
|
|
351
|
+
border-radius: 4px;
|
|
352
|
+
padding: 0 6px;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/* —— 行操作:详情 / 更新 / 卸载 —— */
|
|
356
|
+
|
|
357
|
+
.rowActions {
|
|
358
|
+
display: flex;
|
|
359
|
+
align-items: center;
|
|
360
|
+
gap: 4px;
|
|
361
|
+
flex-shrink: 0;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/* 详情:中性细边框按钮,与卸载同款描边样式(视觉成组) */
|
|
365
|
+
.rowDetail {
|
|
366
|
+
font-family: inherit;
|
|
367
|
+
font-size: 12px;
|
|
368
|
+
line-height: 18px;
|
|
369
|
+
color: var(--hub-text-secondary);
|
|
370
|
+
background: transparent;
|
|
371
|
+
border: 1px solid var(--hub-border-2);
|
|
372
|
+
border-radius: 6px;
|
|
373
|
+
padding: 2px 10px;
|
|
374
|
+
cursor: pointer;
|
|
375
|
+
user-select: none;
|
|
376
|
+
transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.rowDetail:hover {
|
|
380
|
+
color: var(--hub-text-primary);
|
|
381
|
+
border-color: var(--hub-border-ghost);
|
|
382
|
+
background: var(--hub-bg-hover);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* 重启:琥珀警告色描边小按钮,仅在「待重启」时出现 —— 装完未挂载,点了宿主重启后即生效。
|
|
386
|
+
重启属于「提醒/待办」语义,用警告色而非品牌蓝,与状态点的琥珀点呼应 */
|
|
387
|
+
.rowRestart {
|
|
388
|
+
font-family: inherit;
|
|
389
|
+
font-size: 12px;
|
|
390
|
+
line-height: 18px;
|
|
391
|
+
font-weight: 500;
|
|
392
|
+
color: var(--hub-warning);
|
|
393
|
+
background: var(--hub-warning-tint);
|
|
394
|
+
border: 1px solid var(--hub-warning-border);
|
|
395
|
+
border-radius: 6px;
|
|
396
|
+
padding: 2px 10px;
|
|
397
|
+
cursor: pointer;
|
|
398
|
+
user-select: none;
|
|
399
|
+
transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.rowRestart:hover {
|
|
403
|
+
color: #fff;
|
|
404
|
+
background: var(--hub-warning);
|
|
405
|
+
border-color: var(--hub-warning);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/* 更新:品牌色实底小按钮,仅在「有更新」时出现 */
|
|
409
|
+
.rowUpdate {
|
|
410
|
+
font-family: inherit;
|
|
411
|
+
font-size: 12px;
|
|
412
|
+
line-height: 18px;
|
|
413
|
+
font-weight: 500;
|
|
414
|
+
color: #fff;
|
|
415
|
+
background: var(--hub-brand);
|
|
416
|
+
border: none;
|
|
417
|
+
border-radius: 6px;
|
|
418
|
+
padding: 3px 10px;
|
|
419
|
+
cursor: pointer;
|
|
420
|
+
user-select: none;
|
|
421
|
+
transition: background 120ms ease;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.rowUpdate:hover {
|
|
425
|
+
background: var(--hub-brand-hover);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/* 卸载:危险色描边小按钮 */
|
|
429
|
+
.rowUninstall {
|
|
430
|
+
font-family: inherit;
|
|
431
|
+
font-size: 12px;
|
|
432
|
+
line-height: 18px;
|
|
433
|
+
color: var(--hub-danger);
|
|
434
|
+
background: transparent;
|
|
435
|
+
border: 1px solid var(--hub-danger-border-soft);
|
|
436
|
+
border-radius: 6px;
|
|
437
|
+
padding: 2px 10px;
|
|
438
|
+
cursor: pointer;
|
|
439
|
+
user-select: none;
|
|
440
|
+
transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.rowUninstall:hover {
|
|
444
|
+
color: #fff;
|
|
445
|
+
background: var(--hub-danger);
|
|
446
|
+
border-color: var(--hub-danger);
|
|
447
|
+
}
|