@morehao/dsh-github-trending 0.8.6 → 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/client.js +375 -241
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v0.8.7] - 2026-11-02
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **ui**: polish identity bar tabs and about dialog (#84)
|
|
8
|
+
|
|
9
|
+
**Full Changelog**: https://github.com/morehao/dsh-github-trending/compare/v0.8.6...v0.8.7
|
|
10
|
+
|
|
3
11
|
## [v0.8.6] - 2026-11-02
|
|
4
12
|
|
|
5
13
|
### Features
|
package/README.en.md
CHANGED
|
@@ -33,7 +33,7 @@ Open the workbench from the sidebar **GitHub Trending** or `Settings → GitHub
|
|
|
33
33
|
|
|
34
34
|
### Overview
|
|
35
35
|
|
|
36
|
-
Answers "when will it run next, are the four readiness checks all green, what was delivered last time" at a glance. The top shows the plugin identity bar (version / package name / check for updates); the right side keeps the next run and readiness N/4 always visible.
|
|
36
|
+
Answers "when will it run next, are the four readiness checks all green, what was delivered last time" at a glance. The top shows the plugin identity bar (version / package name / GitHub / check for updates); click the package name to open About. The right side keeps the next run and readiness N/4 always visible.
|
|
37
37
|
|
|
38
38
|

|
|
39
39
|
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ GitHub 趋势榜的 **DeepSeek Harness 插件**:按日 / 周 / 月周期定时
|
|
|
33
33
|
|
|
34
34
|
### 概览
|
|
35
35
|
|
|
36
|
-
一屏回答「下次什么时候跑、四项就绪检查是否齐、上次交付了什么」。顶部是插件身份条(版本 / 包名 /
|
|
36
|
+
一屏回答「下次什么时候跑、四项就绪检查是否齐、上次交付了什么」。顶部是插件身份条(版本 / 包名 / GitHub / 检查更新),点包名打开「关于」弹层;右侧常驻下次运行与就绪 N/4。
|
|
37
37
|
|
|
38
38
|

|
|
39
39
|
|
package/client.js
CHANGED
|
@@ -54,8 +54,7 @@ var DICT = {
|
|
|
54
54
|
"st.model": "模型",
|
|
55
55
|
"st.repo": "仓库",
|
|
56
56
|
"st.auth": "认证",
|
|
57
|
-
"st.scope": "
|
|
58
|
-
"st.summarize": "摘要与用量",
|
|
57
|
+
"st.scope": "榜单",
|
|
59
58
|
"st.releases": "订阅",
|
|
60
59
|
"st.schedule": "调度",
|
|
61
60
|
"card.source.title": "内容来源",
|
|
@@ -284,9 +283,10 @@ var DICT = {
|
|
|
284
283
|
"shell.update.confirmHint": "更新会重装插件,需重启 DSH 生效",
|
|
285
284
|
"shell.update.confirmYes": "确认更新",
|
|
286
285
|
"shell.update.cancel": "取消",
|
|
287
|
-
"
|
|
288
|
-
"
|
|
289
|
-
"
|
|
286
|
+
"restoreNotice.title": "已更新到 v{version}",
|
|
287
|
+
"restoreNotice.titleBare": "更新已安装",
|
|
288
|
+
"restoreNotice.body": "请彻底退出 DSH(⌘Q)再重新打开,更新才会生效。",
|
|
289
|
+
"restoreNotice.dismiss": "知道了",
|
|
290
290
|
"time.in.minutes": "{minutes} 分钟后",
|
|
291
291
|
"time.in.hours": "{hours} 小时 {minutes} 分后",
|
|
292
292
|
"time.in.days": "{days} 天后",
|
|
@@ -438,7 +438,6 @@ var DICT = {
|
|
|
438
438
|
"runs.detail.tokensNone": "—",
|
|
439
439
|
"runs.footer.total": "历史累计 tokens:{total}",
|
|
440
440
|
"card.summarize.title": "摘要与用量",
|
|
441
|
-
"card.summarize.hint": "对应核心 summarize.*(core 0.4.1+)",
|
|
442
441
|
"summarize.batchSize": "批量大小",
|
|
443
442
|
"summarize.batchSize.help": "每次模型调用处理的仓库数;批次越大速度越快,单次提示词也越长。",
|
|
444
443
|
"summarize.maxRetries": "失败重试",
|
|
@@ -585,16 +584,15 @@ var DICT = {
|
|
|
585
584
|
"overview.releases.repos": "仓库",
|
|
586
585
|
"overview.tokens.note": "概览一屏带出「这次任务共花了多少 token / 历史上累计多少 / 订阅仓库有几个新版本」;只给总用量,不拆维度;本次任务总量已含订阅阶段消耗。旧核心无数据时对应小块整体隐藏,不留 0。",
|
|
587
586
|
"about.title": "关于",
|
|
588
|
-
"about.copy": "
|
|
587
|
+
"about.copy": "复制包名",
|
|
589
588
|
"about.copied": "已复制",
|
|
590
589
|
"about.close": "关闭",
|
|
590
|
+
"about.pkg": "包名",
|
|
591
591
|
"about.repo": "GitHub 仓库",
|
|
592
592
|
"about.repo.missing": "package.json 没有可解析的仓库地址",
|
|
593
593
|
"about.license": "许可",
|
|
594
594
|
"about.core": "核心",
|
|
595
|
-
"about.core.repo": "打开核心 GitHub 仓库"
|
|
596
|
-
"about.env": "运行环境",
|
|
597
|
-
"about.env.value": "DSH Web · Node 插件"
|
|
595
|
+
"about.core.repo": "打开核心 GitHub 仓库"
|
|
598
596
|
},
|
|
599
597
|
en: {
|
|
600
598
|
"section.title": "GitHub Trending",
|
|
@@ -605,8 +603,7 @@ var DICT = {
|
|
|
605
603
|
"st.model": "Model",
|
|
606
604
|
"st.repo": "Repository",
|
|
607
605
|
"st.auth": "Auth",
|
|
608
|
-
"st.scope": "
|
|
609
|
-
"st.summarize": "Summary & usage",
|
|
606
|
+
"st.scope": "Board",
|
|
610
607
|
"st.releases": "Subscriptions",
|
|
611
608
|
"st.schedule": "Schedule",
|
|
612
609
|
"card.source.title": "Content source",
|
|
@@ -835,9 +832,10 @@ var DICT = {
|
|
|
835
832
|
"shell.update.confirmHint": "Reinstalls the plugin; restart DSH to apply",
|
|
836
833
|
"shell.update.confirmYes": "Confirm",
|
|
837
834
|
"shell.update.cancel": "Cancel",
|
|
838
|
-
"
|
|
839
|
-
"
|
|
840
|
-
"
|
|
835
|
+
"restoreNotice.title": "Updated to v{version}",
|
|
836
|
+
"restoreNotice.titleBare": "Update installed",
|
|
837
|
+
"restoreNotice.body": "Quit DSH completely (⌘Q) and reopen it so the update takes effect.",
|
|
838
|
+
"restoreNotice.dismiss": "Got it",
|
|
841
839
|
"time.in.minutes": "in {minutes} min",
|
|
842
840
|
"time.in.hours": "in {hours} h {minutes} min",
|
|
843
841
|
"time.in.days": "in {days} d",
|
|
@@ -989,7 +987,6 @@ var DICT = {
|
|
|
989
987
|
"runs.detail.tokensNone": "—",
|
|
990
988
|
"runs.footer.total": "All-time tokens: {total}",
|
|
991
989
|
"card.summarize.title": "Summary & usage",
|
|
992
|
-
"card.summarize.hint": "Maps to core summarize.* (core 0.4.1+)",
|
|
993
990
|
"summarize.batchSize": "Batch size",
|
|
994
991
|
"summarize.batchSize.help": "Repos per model call; larger batches run faster but make each prompt longer.",
|
|
995
992
|
"summarize.maxRetries": "Retries",
|
|
@@ -1136,16 +1133,15 @@ var DICT = {
|
|
|
1136
1133
|
"overview.releases.repos": "Repos",
|
|
1137
1134
|
"overview.tokens.note": 'The overview surfaces "how many tokens this run spent / all-time accumulated / how many new versions across subscribed repos"; total only, not split by dimension; this run total already includes the subscriptions stage. With an old core that has no data, the corresponding tile is hidden entirely, never shown as 0.',
|
|
1138
1135
|
"about.title": "About",
|
|
1139
|
-
"about.copy": "Copy
|
|
1136
|
+
"about.copy": "Copy package name",
|
|
1140
1137
|
"about.copied": "Copied",
|
|
1141
1138
|
"about.close": "Close",
|
|
1139
|
+
"about.pkg": "Package",
|
|
1142
1140
|
"about.repo": "GitHub repository",
|
|
1143
1141
|
"about.repo.missing": "package.json has no resolvable repository URL",
|
|
1144
1142
|
"about.license": "License",
|
|
1145
1143
|
"about.core": "Core",
|
|
1146
|
-
"about.core.repo": "Open core GitHub repository"
|
|
1147
|
-
"about.env": "Runtime",
|
|
1148
|
-
"about.env.value": "DSH Web · Node plugin"
|
|
1144
|
+
"about.core.repo": "Open core GitHub repository"
|
|
1149
1145
|
}
|
|
1150
1146
|
};
|
|
1151
1147
|
function activeLang(locale) {
|
|
@@ -1190,6 +1186,7 @@ var CSS = `
|
|
|
1190
1186
|
.dshgt-card-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
|
|
1191
1187
|
.dshgt-card-h h3{margin:0;font-size:13px;font-weight:600;white-space:nowrap;}
|
|
1192
1188
|
.dshgt-hint{color:var(--gt-muted);font-size:12px;}
|
|
1189
|
+
.dshgt-card .dshgt-hint.dshgt-mono{overflow-wrap:anywhere;}
|
|
1193
1190
|
.dshgt-desc{margin:0;color:var(--gt-muted);font-size:12px;}
|
|
1194
1191
|
.dshgt-subhead{margin:4px 0 0;padding-top:8px;border-top:1px solid var(--gt-border);font-size:12px;font-weight:600;color:var(--gt-muted);}
|
|
1195
1192
|
.dshgt-row{display:flex;gap:10px;align-items:center;min-height:28px;flex-wrap:wrap;}
|
|
@@ -1244,6 +1241,14 @@ var CSS = `
|
|
|
1244
1241
|
.dshgt-modal-mask{position:fixed;inset:0;background:var(--dsw-alias-bg-mask-1,rgba(15,23,42,.38));display:flex;align-items:center;justify-content:center;z-index:2147483000;}
|
|
1245
1242
|
.dshgt-modal{background:var(--gt-bg);border-radius:12px;border:1px solid var(--gt-border);max-width:640px;width:calc(100% - 32px);max-height:80vh;overflow:auto;padding:16px;display:flex;flex-direction:column;gap:10px;box-shadow:0 20px 50px rgba(15,23,42,.25);}
|
|
1246
1243
|
|
|
1244
|
+
/* ——— 自更新后的恢复提示(右下角,约 6 秒后自动消失) ——— */
|
|
1245
|
+
.dshgt-restore{position:fixed;right:20px;bottom:20px;z-index:2147483000;max-width:360px;display:flex;flex-direction:column;gap:10px;padding:14px 16px;border-radius:12px;border:1px solid var(--gt-border);background:var(--gt-bg);box-shadow:0 16px 40px rgba(15,23,42,.28);animation:dshgt-restore-in .18s ease-out;}
|
|
1246
|
+
.dshgt-restore-text{display:flex;flex-direction:column;gap:4px;}
|
|
1247
|
+
.dshgt-restore-title{font-size:13px;font-weight:600;color:var(--gt-fg);}
|
|
1248
|
+
.dshgt-restore-body{font-size:12px;line-height:1.5;color:var(--gt-muted);}
|
|
1249
|
+
.dshgt-restore-actions{display:flex;justify-content:flex-end;gap:8px;}
|
|
1250
|
+
@keyframes dshgt-restore-in{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:translateY(0);}}
|
|
1251
|
+
|
|
1247
1252
|
/* ——— GitHub 设备码登录弹窗 ——— */
|
|
1248
1253
|
.dshgt-authmodal{max-width:420px;gap:14px;}
|
|
1249
1254
|
.dshgt-authmodal-head{display:flex;align-items:center;justify-content:space-between;gap:8px;}
|
|
@@ -1256,7 +1261,8 @@ var CSS = `
|
|
|
1256
1261
|
.dshgt-authwait{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--gt-muted);}
|
|
1257
1262
|
.dshgt-authwait-dot{width:8px;height:8px;border-radius:50%;background:var(--gt-accent);animation:dshgt-pulse 1.1s ease-in-out infinite;}
|
|
1258
1263
|
@keyframes dshgt-pulse{0%,100%{opacity:.25;transform:scale(.8);}50%{opacity:1;transform:scale(1);}}
|
|
1259
|
-
.dshgt-authmodal-footer{display:flex;align-items:center;justify-content:
|
|
1264
|
+
.dshgt-authmodal-footer{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:8px;border-top:1px solid var(--gt-border);padding-top:10px;}
|
|
1265
|
+
.dshgt-authmodal-footer .dshgt-hint{margin-right:auto;}
|
|
1260
1266
|
|
|
1261
1267
|
/* ——— 01 工作台外壳 ——— */
|
|
1262
1268
|
.dshgt-shell{gap:0;height:100%;min-height:0;overflow:hidden;}
|
|
@@ -1306,29 +1312,29 @@ var CSS = `
|
|
|
1306
1312
|
.dshgt-inline-tag{margin-left:6px;vertical-align:1px;}
|
|
1307
1313
|
|
|
1308
1314
|
/* ——— 顶部身份条(第一行):名称 / 版本 / 完整包名 / GitHub / 检查更新 ——— */
|
|
1309
|
-
.dshgt-idbar{display:flex;align-items:center;gap:
|
|
1310
|
-
.dshgt-idbar .dshgt-brand{display:flex;align-items:center;gap:9px;padding:0;flex:none;}
|
|
1315
|
+
.dshgt-idbar{display:flex;align-items:center;gap:9px;height:48px;padding:0 18px;border-bottom:1px solid var(--gt-border);flex:none;background:var(--gt-bg);min-width:0;}
|
|
1316
|
+
.dshgt-idbar .dshgt-brand{display:flex;align-items:center;gap:9px;padding:0;flex:none;min-width:0;}
|
|
1311
1317
|
.dshgt-idbar .dshgt-brand svg{width:22px;height:22px;flex:none;border-radius:6px;}
|
|
1312
1318
|
.dshgt-brand-name{font-size:13.5px;font-weight:650;letter-spacing:-.01em;white-space:nowrap;line-height:1.3;}
|
|
1313
|
-
.dshgt-id-ver{
|
|
1314
|
-
.dshgt-id-ver:hover{border-color:color-mix(in srgb,var(--gt-accent) 45%,var(--gt-border));}
|
|
1319
|
+
.dshgt-id-ver{display:inline-flex;align-items:center;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;color:var(--gt-fg);background:var(--gt-card);border:1px solid var(--gt-border);border-radius:999px;padding:1px 7px;line-height:16px;flex:none;white-space:nowrap;}
|
|
1315
1320
|
.dshgt-id-sep{width:1px;height:16px;background:var(--gt-border);flex:none;}
|
|
1316
|
-
.dshgt-id-pkg{appearance:none;border:0;background:none;padding:2px 4px;border-radius:5px;color:var(--gt-muted);cursor:pointer;font-size:12px;max-width:44vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:
|
|
1321
|
+
.dshgt-id-pkg{appearance:none;border:0;background:none;padding:2px 4px;border-radius:5px;color:var(--gt-muted);cursor:pointer;font-size:12px;max-width:min(44vw,360px);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 1 auto;}
|
|
1317
1322
|
.dshgt-id-pkg:hover{color:var(--gt-fg);background:color-mix(in srgb,var(--gt-fg) 5%,var(--gt-bg));}
|
|
1318
|
-
.dshgt-idbar-right{margin-left:auto;display:flex;align-items:center;gap:10px;flex:none;}
|
|
1319
|
-
.dshgt-id-gh{display:inline-flex;align-items:center;justify-content:center;width:
|
|
1323
|
+
.dshgt-idbar-right{margin-left:auto;display:flex;align-items:center;gap:10px;flex:none;min-width:0;}
|
|
1324
|
+
.dshgt-id-gh{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:6px;color:var(--gt-muted);border:1px solid transparent;flex:none;}
|
|
1320
1325
|
.dshgt-id-gh:hover{color:var(--gt-fg);background:color-mix(in srgb,var(--gt-fg) 6%,var(--gt-bg));border-color:var(--gt-border);}
|
|
1321
|
-
.dshgt-id-upd{display:flex;align-items:center;gap:10px;}
|
|
1322
|
-
.dshgt-id-status{font-size:12px;color:var(--gt-muted);white-space:nowrap;display:inline-flex;align-items:center;gap:6px;}
|
|
1326
|
+
.dshgt-id-upd{display:flex;align-items:center;gap:10px;min-width:0;}
|
|
1327
|
+
.dshgt-id-status{font-size:12px;color:var(--gt-muted);white-space:nowrap;display:inline-flex;align-items:center;gap:6px;min-width:0;overflow:hidden;text-overflow:ellipsis;}
|
|
1323
1328
|
.dshgt-id-status.ok{color:var(--gt-ok);}
|
|
1324
1329
|
.dshgt-id-status.new{color:var(--gt-warn);}
|
|
1325
1330
|
.dshgt-id-status.err{color:var(--gt-err);}
|
|
1326
|
-
.dshgt-id-actions{display:flex;align-items:center;gap:8px;}
|
|
1331
|
+
.dshgt-id-actions{display:flex;align-items:center;gap:8px;flex:none;}
|
|
1327
1332
|
|
|
1328
1333
|
/* ——— 横向 tab(第二行)+ 右侧状态 ——— */
|
|
1329
|
-
.dshgt-tabsbar{display:flex;align-items:stretch;gap:
|
|
1330
|
-
.dshgt-tabnav{display:flex;align-items:stretch;gap:2px;height:100%;}
|
|
1331
|
-
.dshgt-
|
|
1334
|
+
.dshgt-tabsbar{display:flex;align-items:stretch;gap:12px;height:46px;padding:0 18px;border-bottom:1px solid var(--gt-border);flex:none;background:var(--gt-bg);min-width:0;}
|
|
1335
|
+
.dshgt-tabnav{display:flex;align-items:stretch;gap:2px;height:100%;min-width:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;}
|
|
1336
|
+
.dshgt-tabnav::-webkit-scrollbar{display:none;}
|
|
1337
|
+
.dshgt-tab{display:flex;align-items:center;gap:7px;padding:0 12px;border:0;background:none;color:var(--gt-muted);cursor:pointer;font:inherit;font-size:13.5px;position:relative;border-bottom:2px solid transparent;margin-bottom:-1px;flex:none;white-space:nowrap;}
|
|
1332
1338
|
.dshgt-tab svg{opacity:.8;}
|
|
1333
1339
|
.dshgt-tab:hover{color:var(--gt-fg);}
|
|
1334
1340
|
.dshgt-tab.on{color:var(--gt-fg);font-weight:600;border-bottom-color:var(--gt-accent);}
|
|
@@ -1340,7 +1346,10 @@ var CSS = `
|
|
|
1340
1346
|
.dshgt-status-val{color:var(--gt-fg);font-weight:600;}
|
|
1341
1347
|
.dshgt-status-sub{color:var(--gt-muted);}
|
|
1342
1348
|
@media (max-width:1100px){ .dshgt-id-pkg{max-width:26vw;} }
|
|
1343
|
-
@media (max-width:
|
|
1349
|
+
@media (max-width:900px){
|
|
1350
|
+
.dshgt-id-pkg{max-width:22vw;}
|
|
1351
|
+
.dshgt-status-item.dshgt-next{display:none;}
|
|
1352
|
+
}
|
|
1344
1353
|
|
|
1345
1354
|
/* ——— 概览 ——— */
|
|
1346
1355
|
.dshgt-delivery{border:1px solid var(--gt-border);border-radius:12px;padding:18px 20px 16px;background:var(--gt-card);display:flex;flex-direction:column;gap:6px;}
|
|
@@ -1483,7 +1492,7 @@ var CSS = `
|
|
|
1483
1492
|
.dshgt-run-what{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;}
|
|
1484
1493
|
.dshgt-run-muted{color:var(--gt-muted);font-size:12px;margin-left:6px;}
|
|
1485
1494
|
.dshgt-run-files,.dshgt-run-duration{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--gt-muted);text-align:right;}
|
|
1486
|
-
.dshgt-run-tokens{font-size:11.5px;color:var(--gt-muted);text-align:right;white-space:nowrap;}
|
|
1495
|
+
.dshgt-run-tokens{font-size:11.5px;color:var(--gt-muted);text-align:right;white-space:nowrap;min-width:0;overflow:hidden;text-overflow:ellipsis;}
|
|
1487
1496
|
.dshgt-run-item.has-tokens .dshgt-run-row{grid-template-columns:18px 120px 56px minmax(0,1fr) 64px 78px 74px 20px;}
|
|
1488
1497
|
.dshgt-run-chev{color:var(--gt-muted);text-align:center;transition:transform .15s;}
|
|
1489
1498
|
.dshgt-run-item.open .dshgt-run-chev{transform:rotate(90deg);}
|
|
@@ -1507,29 +1516,29 @@ var CSS = `
|
|
|
1507
1516
|
.dshgt-log-head .dshgt-btn{margin-left:auto;}
|
|
1508
1517
|
.dshgt-log-pre{margin:0;max-height:52vh;overflow:auto;padding:12px;border-radius:8px;background:color-mix(in srgb,var(--gt-fg) 5%,var(--gt-card));font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.6;white-space:pre-wrap;word-break:break-word;}
|
|
1509
1518
|
.dshgt-log-foot{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
|
|
1510
|
-
.dshgt-about{max-width:
|
|
1519
|
+
.dshgt-about{max-width:460px;width:100%;}
|
|
1511
1520
|
.dshgt-about-head{display:flex;align-items:center;gap:10px;}
|
|
1512
|
-
.dshgt-about-title{margin:0;font-size:
|
|
1513
|
-
.dshgt-about-
|
|
1514
|
-
.dshgt-about-
|
|
1515
|
-
|
|
1516
|
-
.dshgt-about-
|
|
1517
|
-
.dshgt-about-
|
|
1518
|
-
.dshgt-about
|
|
1521
|
+
.dshgt-about-title{margin:0;font-size:15px;font-weight:600;}
|
|
1522
|
+
.dshgt-about-close{margin-left:auto;appearance:none;font:inherit;font-size:12px;cursor:pointer;border-radius:7px;border:1px solid var(--gt-border);background:var(--gt-bg);padding:4px 11px;color:var(--gt-muted);}
|
|
1523
|
+
.dshgt-about-close:hover{color:var(--gt-fg);border-color:color-mix(in srgb,var(--gt-accent) 40%,var(--gt-border));}
|
|
1524
|
+
/* 居中的应用身份区块:logo / 名称 / 版本胶囊 */
|
|
1525
|
+
.dshgt-about-identity{display:flex;flex-direction:column;align-items:center;gap:10px;padding:14px 0 18px;}
|
|
1526
|
+
.dshgt-about-logo svg{width:56px;height:56px;border-radius:14px;display:block;box-shadow:0 4px 14px rgba(0,0,0,.18);}
|
|
1527
|
+
.dshgt-about-name{font-size:16px;font-weight:650;letter-spacing:-.01em;}
|
|
1528
|
+
.dshgt-about-ver{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;color:var(--gt-fg);background:var(--gt-card);border:1px solid var(--gt-border);border-radius:999px;padding:1px 9px;line-height:17px;}
|
|
1529
|
+
/* 信息表:上方一条分割线,左对齐 label/value */
|
|
1530
|
+
.dshgt-about .dshgt-kv{grid-template-columns:88px minmax(0,1fr);border-top:1px solid var(--gt-border);padding-top:2px;}
|
|
1519
1531
|
.dshgt-about .dshgt-kv a{color:var(--gt-accent);text-decoration:none;}
|
|
1520
1532
|
.dshgt-about .dshgt-kv a:hover{text-decoration:underline;}
|
|
1521
|
-
.dshgt-about-
|
|
1522
|
-
|
|
1523
|
-
.dshgt-about-
|
|
1533
|
+
.dshgt-about .dshgt-kv dd{min-width:0;overflow-wrap:anywhere;}
|
|
1534
|
+
/* 包名行:整行可点复制,无独立按钮;复制后行尾浮现「已复制」 */
|
|
1535
|
+
.dshgt-about-pkgrow{padding:0 !important;}
|
|
1536
|
+
.dshgt-about-pkglink{appearance:none;font:inherit;border:0;background:none;padding:9px 6px;margin:-9px -6px;border-radius:6px;width:calc(100% + 12px);display:flex;align-items:center;gap:8px;text-align:left;cursor:pointer;color:inherit;}
|
|
1537
|
+
.dshgt-about-pkglink:hover{background:color-mix(in srgb,var(--gt-fg) 5%,var(--gt-bg));}
|
|
1538
|
+
.dshgt-about-pkglink-name{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;user-select:text;}
|
|
1539
|
+
.dshgt-about-copied{opacity:0;transition:opacity .12s ease;font-size:11px;color:var(--gt-ok);flex:none;}
|
|
1540
|
+
.dshgt-about-pkglink.is-copied .dshgt-about-copied{opacity:1;}
|
|
1524
1541
|
.dshgt-gh{width:15px;height:15px;display:block;fill:currentColor;}
|
|
1525
|
-
/* 关于弹层的更新行:与身份条同构(左侧状态 + 右侧单按钮),无标题、无说明。 */
|
|
1526
|
-
.dshgt-about-upd{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:6px;padding-top:12px;border-top:1px solid color-mix(in srgb,var(--gt-border) 70%,transparent);}
|
|
1527
|
-
.dshgt-about-status{display:inline-flex;align-items:center;gap:7px;font-size:12px;color:var(--gt-muted);}
|
|
1528
|
-
.dshgt-about-status::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor;flex:none;opacity:.9;}
|
|
1529
|
-
.dshgt-about-status.ok{color:var(--gt-ok);}
|
|
1530
|
-
.dshgt-about-status.new{color:var(--gt-warn);}
|
|
1531
|
-
.dshgt-about-status.err{color:var(--gt-err);}
|
|
1532
|
-
.dshgt-about-actions{display:flex;align-items:center;gap:8px;flex:none;}
|
|
1533
1542
|
|
|
1534
1543
|
/* ——— 订阅:命令栏 + 四列表格 + 选择条 + 发版记录抽屉 ——— */
|
|
1535
1544
|
.dshgt-subs{gap:12px;padding-bottom:10px;}
|
|
@@ -1662,7 +1671,6 @@ var CSS = `
|
|
|
1662
1671
|
}
|
|
1663
1672
|
|
|
1664
1673
|
@media (max-width:1100px){
|
|
1665
|
-
.dshgt-app{grid-template-columns:190px minmax(0,1fr);}
|
|
1666
1674
|
.dshgt-page-head{padding:18px 22px 12px;}
|
|
1667
1675
|
.dshgt-view{padding:18px 22px 30px;}
|
|
1668
1676
|
.dshgt-facts{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:10px;}
|
|
@@ -1676,11 +1684,57 @@ var CSS = `
|
|
|
1676
1684
|
.dshgt-dateselect{min-width:180px;}
|
|
1677
1685
|
}
|
|
1678
1686
|
@media (max-width:980px){
|
|
1679
|
-
.dshgt-app{grid-template-columns:172px minmax(0,1fr);}
|
|
1680
1687
|
.dshgt-page-head h1{font-size:19px;}
|
|
1681
1688
|
.dshgt-dek{font-size:12.5px;}
|
|
1682
1689
|
.dshgt-main-body > .dshgt-settings{padding:14px 18px 18px;}
|
|
1683
1690
|
}
|
|
1691
|
+
@media (max-width:900px){
|
|
1692
|
+
.dshgt-main-body > .dshgt-settings{padding:14px 16px 18px;}
|
|
1693
|
+
}
|
|
1694
|
+
@media (max-width:760px){
|
|
1695
|
+
.dshgt-idbar{padding:0 14px;gap:8px;}
|
|
1696
|
+
.dshgt-id-pkg{max-width:26vw;}
|
|
1697
|
+
.dshgt-id-status{display:none;}
|
|
1698
|
+
.dshgt-tabsbar{padding:0 14px;gap:8px;}
|
|
1699
|
+
.dshgt-tabsbar-status{display:none;}
|
|
1700
|
+
.dshgt-page-head{flex-wrap:wrap;padding:16px 18px 12px;gap:10px 16px;}
|
|
1701
|
+
.dshgt-head-actions{margin-left:0;width:100%;justify-content:flex-start;padding-top:0;flex-wrap:wrap;}
|
|
1702
|
+
.dshgt-view{padding:16px 18px 28px;}
|
|
1703
|
+
.dshgt-runs-filter{margin-left:0;width:100%;flex-wrap:wrap;}
|
|
1704
|
+
.dshgt-run-row{grid-template-columns:14px 92px 46px minmax(0,1fr) 20px;gap:8px;padding:0 2px;}
|
|
1705
|
+
.dshgt-run-item.has-tokens .dshgt-run-row{grid-template-columns:14px 92px 46px minmax(0,1fr) 64px 20px;}
|
|
1706
|
+
.dshgt-run-duration{display:none;}
|
|
1707
|
+
.dshgt-settings{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);gap:10px;}
|
|
1708
|
+
.dshgt-vtabs{flex-direction:row;flex-wrap:wrap;overflow:visible;border-right:0;border-bottom:1px solid var(--gt-border);padding:0 0 8px;}
|
|
1709
|
+
.dshgt-vtabs::-webkit-scrollbar{display:none;}
|
|
1710
|
+
.dshgt-vtab{flex:none;white-space:nowrap;}
|
|
1711
|
+
.dshgt-vpanel{padding-right:0;}
|
|
1712
|
+
.dshgt-facts{grid-template-columns:minmax(0,1fr);row-gap:8px;}
|
|
1713
|
+
.dshgt-fact{padding:0;}
|
|
1714
|
+
.dshgt-fact + .dshgt-fact{border-left:0;padding-top:8px;border-top:1px solid color-mix(in srgb,var(--gt-border) 70%,transparent);}
|
|
1715
|
+
.dshgt-detail-grid{grid-template-columns:minmax(0,1fr);}
|
|
1716
|
+
}
|
|
1717
|
+
@media (max-width:560px){
|
|
1718
|
+
.dshgt-modal{width:calc(100% - 20px);padding:14px;max-height:88vh;}
|
|
1719
|
+
.dshgt-about{max-width:none;}
|
|
1720
|
+
.dshgt-about .dshgt-kv{grid-template-columns:88px minmax(0,1fr);}
|
|
1721
|
+
.dshgt-authmodal-footer .dshgt-hint{flex-basis:100%;}
|
|
1722
|
+
}
|
|
1723
|
+
@media (max-width:480px){
|
|
1724
|
+
.dshgt-brand-name{display:none;}
|
|
1725
|
+
.dshgt-id-pkg{max-width:30vw;}
|
|
1726
|
+
.dshgt-tab{padding:0 9px;gap:5px;font-size:13px;}
|
|
1727
|
+
.dshgt-tab-tail{display:none;}
|
|
1728
|
+
}
|
|
1729
|
+
@media (max-width:380px){
|
|
1730
|
+
.dshgt-tab svg{display:none;}
|
|
1731
|
+
.dshgt-tab{padding:0 10px;}
|
|
1732
|
+
}
|
|
1733
|
+
@media (max-width:420px){
|
|
1734
|
+
.dshgt-about .dshgt-kv{grid-template-columns:minmax(0,1fr);gap:2px 0;}
|
|
1735
|
+
.dshgt-about .dshgt-kv dt{margin-top:6px;}
|
|
1736
|
+
.dshgt-authcode-value{font-size:24px;letter-spacing:4px;}
|
|
1737
|
+
}
|
|
1684
1738
|
`;
|
|
1685
1739
|
function injectStyles() {
|
|
1686
1740
|
if (typeof document === "undefined") return () => void 0;
|
|
@@ -2104,8 +2158,8 @@ function credentialView(model, t) {
|
|
|
2104
2158
|
|
|
2105
2159
|
// client/settings.ts
|
|
2106
2160
|
var LANGUAGES = ["all", "typescript", "python", "go", "rust", "java", "c", "cpp", "javascript", "csharp"];
|
|
2107
|
-
var SECTIONS = ["source", "model", "repo", "auth", "scope", "
|
|
2108
|
-
var EMPTY_DIRTY = { source: false, model: false, repo: false, auth: false, scope: false,
|
|
2161
|
+
var SECTIONS = ["source", "model", "repo", "auth", "scope", "releases"];
|
|
2162
|
+
var EMPTY_DIRTY = { source: false, model: false, repo: false, auth: false, scope: false, releases: false };
|
|
2109
2163
|
function cloneSettings(settings) {
|
|
2110
2164
|
return JSON.parse(JSON.stringify(settings));
|
|
2111
2165
|
}
|
|
@@ -2120,9 +2174,7 @@ function sectionSlice(settings, section) {
|
|
|
2120
2174
|
case "auth":
|
|
2121
2175
|
return { github: settings.github };
|
|
2122
2176
|
case "scope":
|
|
2123
|
-
return { trending: settings.trending, schedule: settings.schedule };
|
|
2124
|
-
case "summarize":
|
|
2125
|
-
return { summarize: settings.summarize };
|
|
2177
|
+
return { trending: settings.trending, schedule: settings.schedule, summarize: settings.summarize };
|
|
2126
2178
|
case "releases":
|
|
2127
2179
|
return { releases: settings.releases };
|
|
2128
2180
|
}
|
|
@@ -2387,7 +2439,6 @@ function SettingsView(props) {
|
|
|
2387
2439
|
{ id: "repo", label: t("st.repo") },
|
|
2388
2440
|
{ id: "auth", label: t("st.auth") },
|
|
2389
2441
|
{ id: "scope", label: t("st.scope") },
|
|
2390
|
-
{ id: "summarize", label: t("st.summarize") },
|
|
2391
2442
|
{ id: "releases", label: t("st.releases") }
|
|
2392
2443
|
];
|
|
2393
2444
|
const sourceCard = h(
|
|
@@ -2659,11 +2710,8 @@ function SettingsView(props) {
|
|
|
2659
2710
|
{ label: t("schedule.periods") },
|
|
2660
2711
|
h("span", { className: "dshgt-hint" }, t("schedule.periods.value"))
|
|
2661
2712
|
),
|
|
2662
|
-
h("p", { className: "dshgt-hint" }, t("schedule.source"))
|
|
2663
|
-
|
|
2664
|
-
const summarizeCard = h(
|
|
2665
|
-
Card,
|
|
2666
|
-
{ title: t("card.summarize.title"), hint: t("card.summarize.hint") },
|
|
2713
|
+
h("p", { className: "dshgt-hint" }, t("schedule.source")),
|
|
2714
|
+
h("h4", { className: "dshgt-subhead" }, t("card.summarize.title")),
|
|
2667
2715
|
h(
|
|
2668
2716
|
Row,
|
|
2669
2717
|
{ label: t("summarize.batchSize"), help: t("summarize.batchSize.help") },
|
|
@@ -2808,7 +2856,7 @@ function SettingsView(props) {
|
|
|
2808
2856
|
})
|
|
2809
2857
|
)
|
|
2810
2858
|
);
|
|
2811
|
-
const currentCard = section === "source" ? sourceCard : section === "model" ? modelCard : section === "repo" ? repoCard : section === "auth" ? authCard : section === "scope" ? scopeCard :
|
|
2859
|
+
const currentCard = section === "source" ? sourceCard : section === "model" ? modelCard : section === "repo" ? repoCard : section === "auth" ? authCard : section === "scope" ? scopeCard : releasesCard;
|
|
2812
2860
|
return h(
|
|
2813
2861
|
"div",
|
|
2814
2862
|
{ className: "dshgt-settings" },
|
|
@@ -5432,6 +5480,114 @@ function SubscriptionsView(props) {
|
|
|
5432
5480
|
);
|
|
5433
5481
|
}
|
|
5434
5482
|
|
|
5483
|
+
// client/about.ts
|
|
5484
|
+
function logo() {
|
|
5485
|
+
return h(
|
|
5486
|
+
"svg",
|
|
5487
|
+
{ viewBox: "0 0 64 64", "aria-hidden": "true" },
|
|
5488
|
+
h("rect", { x: 4, y: 4, width: 56, height: 56, rx: 14, fill: "#0d1117" }),
|
|
5489
|
+
h("path", {
|
|
5490
|
+
d: "M18 46V22l14 12 14-12v24",
|
|
5491
|
+
fill: "none",
|
|
5492
|
+
stroke: "#58a6ff",
|
|
5493
|
+
strokeWidth: 4,
|
|
5494
|
+
strokeLinecap: "round",
|
|
5495
|
+
strokeLinejoin: "round"
|
|
5496
|
+
}),
|
|
5497
|
+
h("circle", { cx: 32, cy: 45, r: 3, fill: "#3fb950" })
|
|
5498
|
+
);
|
|
5499
|
+
}
|
|
5500
|
+
function AboutDialog(props) {
|
|
5501
|
+
const { t, state } = props;
|
|
5502
|
+
const [copied, setCopied] = import_react.default.useState(false);
|
|
5503
|
+
const plugin = state.plugin;
|
|
5504
|
+
const fullName = `${plugin.name}@${plugin.version}`;
|
|
5505
|
+
const repository = plugin.repository;
|
|
5506
|
+
const ownerRepo = repository === void 0 ? void 0 : repository.replace(/^https?:\/\/github\.com\//, "");
|
|
5507
|
+
const core = state.core;
|
|
5508
|
+
const coreRepo = core.repository;
|
|
5509
|
+
const coreOwnerRepo = coreRepo === void 0 ? void 0 : coreRepo.replace(/^https?:\/\/github\.com\//, "");
|
|
5510
|
+
import_react.default.useEffect(() => {
|
|
5511
|
+
const onKey = (event) => {
|
|
5512
|
+
if (event.key === "Escape") props.onClose();
|
|
5513
|
+
};
|
|
5514
|
+
document.addEventListener("keydown", onKey);
|
|
5515
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
5516
|
+
}, [props]);
|
|
5517
|
+
const copy = () => {
|
|
5518
|
+
void copyText(fullName).then((ok) => {
|
|
5519
|
+
if (!ok) return;
|
|
5520
|
+
setCopied(true);
|
|
5521
|
+
setTimeout(() => setCopied(false), 1400);
|
|
5522
|
+
});
|
|
5523
|
+
};
|
|
5524
|
+
const pkgRow = h(
|
|
5525
|
+
"dd",
|
|
5526
|
+
{ className: "dshgt-about-pkgrow" },
|
|
5527
|
+
h(
|
|
5528
|
+
"button",
|
|
5529
|
+
{
|
|
5530
|
+
type: "button",
|
|
5531
|
+
className: `dshgt-about-pkglink${copied ? " is-copied" : ""}`,
|
|
5532
|
+
title: copied ? t("about.copied") : t("about.copy"),
|
|
5533
|
+
"aria-label": `${t("about.copy")}: ${fullName}`,
|
|
5534
|
+
onClick: copy
|
|
5535
|
+
},
|
|
5536
|
+
h("span", { className: "dshgt-mono dshgt-about-pkglink-name" }, fullName),
|
|
5537
|
+
h("span", { className: "dshgt-about-copied" }, t("about.copied"))
|
|
5538
|
+
)
|
|
5539
|
+
);
|
|
5540
|
+
const coreValue = () => {
|
|
5541
|
+
if (coreRepo !== void 0 && coreOwnerRepo !== void 0) {
|
|
5542
|
+
return h("a", { className: "dshgt-mono", href: coreRepo, target: "_blank", rel: "noreferrer" }, coreOwnerRepo);
|
|
5543
|
+
}
|
|
5544
|
+
return core.version === void 0 ? "—" : `trendradar ${core.version}`;
|
|
5545
|
+
};
|
|
5546
|
+
return h(
|
|
5547
|
+
"div",
|
|
5548
|
+
{ className: "dshgt-root" },
|
|
5549
|
+
h(
|
|
5550
|
+
"div",
|
|
5551
|
+
{ className: "dshgt-modal-mask", onClick: (event) => {
|
|
5552
|
+
if (event.target === event.currentTarget) props.onClose();
|
|
5553
|
+
} },
|
|
5554
|
+
h(
|
|
5555
|
+
"div",
|
|
5556
|
+
{ className: "dshgt-modal dshgt-about", role: "dialog", "aria-modal": "true", "aria-label": t("about.title") },
|
|
5557
|
+
h(
|
|
5558
|
+
"div",
|
|
5559
|
+
{ className: "dshgt-about-head" },
|
|
5560
|
+
h("h3", { className: "dshgt-about-title" }, t("about.title")),
|
|
5561
|
+
h("button", { type: "button", className: "dshgt-about-close", onClick: () => props.onClose() }, t("about.close"))
|
|
5562
|
+
),
|
|
5563
|
+
h(
|
|
5564
|
+
"div",
|
|
5565
|
+
{ className: "dshgt-about-identity" },
|
|
5566
|
+
h("div", { className: "dshgt-about-logo" }, logo()),
|
|
5567
|
+
h("div", { className: "dshgt-about-name" }, t("section.title")),
|
|
5568
|
+
h("span", { className: "dshgt-about-ver dshgt-mono" }, `v${plugin.version}`)
|
|
5569
|
+
),
|
|
5570
|
+
h(
|
|
5571
|
+
"dl",
|
|
5572
|
+
{ className: "dshgt-kv dshgt-about-kv" },
|
|
5573
|
+
h("dt", null, t("about.pkg")),
|
|
5574
|
+
pkgRow,
|
|
5575
|
+
h("dt", null, t("about.repo")),
|
|
5576
|
+
h(
|
|
5577
|
+
"dd",
|
|
5578
|
+
null,
|
|
5579
|
+
repository === void 0 || ownerRepo === void 0 ? h("span", { className: "dshgt-hint" }, t("about.repo.missing")) : h("a", { href: repository, target: "_blank", rel: "noreferrer" }, ownerRepo)
|
|
5580
|
+
),
|
|
5581
|
+
h("dt", null, t("about.core")),
|
|
5582
|
+
h("dd", null, coreValue()),
|
|
5583
|
+
h("dt", null, t("about.license")),
|
|
5584
|
+
h("dd", null, "MIT")
|
|
5585
|
+
)
|
|
5586
|
+
)
|
|
5587
|
+
)
|
|
5588
|
+
);
|
|
5589
|
+
}
|
|
5590
|
+
|
|
5435
5591
|
// node_modules/@morehao/dsh-plugin-kit/dist/update-client.js
|
|
5436
5592
|
var IDLE = { status: "idle", view: null, error: null };
|
|
5437
5593
|
function errorOf(error) {
|
|
@@ -5540,156 +5696,115 @@ function usePluginUpdate() {
|
|
|
5540
5696
|
return [state, controller];
|
|
5541
5697
|
}
|
|
5542
5698
|
|
|
5543
|
-
//
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5699
|
+
// node_modules/@morehao/dsh-plugin-kit/dist/update-restore.js
|
|
5700
|
+
var PENDING_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
5701
|
+
var DEFAULT_KEY_PREFIX = "dsh-plugin-update:";
|
|
5702
|
+
var FUTURE_TOLERANCE_MS = 60 * 1e3;
|
|
5703
|
+
function resolveStorage(explicit) {
|
|
5704
|
+
if (explicit !== void 0) {
|
|
5705
|
+
try {
|
|
5706
|
+
const probeKey = "__dsh_pending_probe__";
|
|
5707
|
+
explicit.setItem(probeKey, "1");
|
|
5708
|
+
explicit.removeItem(probeKey);
|
|
5709
|
+
return explicit;
|
|
5710
|
+
} catch {
|
|
5711
|
+
return null;
|
|
5551
5712
|
}
|
|
5552
|
-
}
|
|
5713
|
+
}
|
|
5714
|
+
try {
|
|
5715
|
+
const w = typeof globalThis !== "undefined" ? globalThis : void 0;
|
|
5716
|
+
const s = w?.localStorage;
|
|
5717
|
+
if (!s) return null;
|
|
5718
|
+
const probeKey = "__dsh_pending_probe__";
|
|
5719
|
+
s.setItem(probeKey, "1");
|
|
5720
|
+
s.removeItem(probeKey);
|
|
5721
|
+
return s;
|
|
5722
|
+
} catch {
|
|
5723
|
+
return null;
|
|
5724
|
+
}
|
|
5553
5725
|
}
|
|
5554
|
-
function
|
|
5555
|
-
const
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
const [confirming, setConfirming] = import_react.default.useState(false);
|
|
5567
|
-
const [cmdCopied, setCmdCopied] = import_react.default.useState(false);
|
|
5568
|
-
import_react.default.useEffect(() => {
|
|
5569
|
-
if (update.status === "applying" || update.status === "restart-required" || update.status === "applied") setConfirming(false);
|
|
5570
|
-
}, [update.status]);
|
|
5571
|
-
const view = update.view;
|
|
5572
|
-
const status = update.status;
|
|
5573
|
-
const busy = status === "checking" || status === "applying";
|
|
5574
|
-
const settled = status === "restart-required" || status === "applied";
|
|
5575
|
-
const latestVersion = view === null ? "" : view.latestVersion ?? "";
|
|
5576
|
-
const actionable = view !== null && view.updateAvailable && view.canApply && !settled && !busy;
|
|
5577
|
-
const manual = view !== null && (!view.canApply || view.checkFailed) ? view.manualCommand ?? null : null;
|
|
5578
|
-
const line = updateLine(t, update, fallbackVersion);
|
|
5579
|
-
const copyCmd = () => {
|
|
5580
|
-
if (manual === null) return;
|
|
5581
|
-
void copyText(manual).then((ok) => {
|
|
5582
|
-
if (!ok) return;
|
|
5583
|
-
setCmdCopied(true);
|
|
5584
|
-
setTimeout(() => setCmdCopied(false), 1400);
|
|
5585
|
-
});
|
|
5586
|
-
};
|
|
5587
|
-
function action() {
|
|
5588
|
-
if (status === "applying") return h(Btn, { small: true, disabled: true }, t("shell.update.applyingShort"));
|
|
5589
|
-
if (actionable) {
|
|
5590
|
-
if (confirming) {
|
|
5591
|
-
return [
|
|
5592
|
-
h(Btn, { key: "yes", small: true, variant: "danger", onClick: () => {
|
|
5593
|
-
setConfirming(false);
|
|
5594
|
-
void controller.apply();
|
|
5595
|
-
} }, t("shell.update.confirmYes")),
|
|
5596
|
-
h(Btn, { key: "no", small: true, onClick: () => setConfirming(false) }, t("shell.update.cancel"))
|
|
5597
|
-
];
|
|
5598
|
-
}
|
|
5599
|
-
return h(Btn, { small: true, variant: "primary", onClick: () => setConfirming(true) }, t("shell.update.apply", { version: latestVersion }));
|
|
5726
|
+
function createPendingStore(options = {}) {
|
|
5727
|
+
const keyPrefix = options.keyPrefix === void 0 ? DEFAULT_KEY_PREFIX : options.keyPrefix;
|
|
5728
|
+
const key = `${keyPrefix}update-pending`;
|
|
5729
|
+
const ttlMs = options.ttlMs === void 0 ? PENDING_TTL_MS : options.ttlMs;
|
|
5730
|
+
const now = options.now === void 0 ? Date.now : options.now;
|
|
5731
|
+
const storage = () => resolveStorage(options.storage);
|
|
5732
|
+
function removeKey() {
|
|
5733
|
+
const s = storage();
|
|
5734
|
+
if (!s) return;
|
|
5735
|
+
try {
|
|
5736
|
+
s.removeItem(key);
|
|
5737
|
+
} catch {
|
|
5600
5738
|
}
|
|
5601
|
-
if (manual !== null) return h(Btn, { small: true, onClick: copyCmd }, cmdCopied ? t("shell.update.copied") : t("shell.update.copyCmd"));
|
|
5602
|
-
return h(Btn, { small: true, disabled: busy, onClick: () => void controller.check({ fresh: true }) }, t("shell.update.check"));
|
|
5603
5739
|
}
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
)
|
|
5740
|
+
function write(from, to) {
|
|
5741
|
+
const s = storage();
|
|
5742
|
+
if (!s) return;
|
|
5743
|
+
const value = { from: String(from || ""), to: String(to || ""), at: now() };
|
|
5744
|
+
try {
|
|
5745
|
+
s.setItem(key, JSON.stringify(value));
|
|
5746
|
+
} catch {
|
|
5747
|
+
}
|
|
5748
|
+
}
|
|
5749
|
+
function read() {
|
|
5750
|
+
const s = storage();
|
|
5751
|
+
if (!s) return null;
|
|
5752
|
+
let raw;
|
|
5753
|
+
try {
|
|
5754
|
+
raw = s.getItem(key);
|
|
5755
|
+
} catch {
|
|
5756
|
+
return null;
|
|
5757
|
+
}
|
|
5758
|
+
if (raw === null || raw === "") return null;
|
|
5759
|
+
let value;
|
|
5760
|
+
try {
|
|
5761
|
+
value = JSON.parse(raw);
|
|
5762
|
+
} catch {
|
|
5763
|
+
removeKey();
|
|
5764
|
+
return null;
|
|
5765
|
+
}
|
|
5766
|
+
if (!value || typeof value !== "object") return null;
|
|
5767
|
+
const { from, to, at } = value;
|
|
5768
|
+
if (typeof at !== "number" || !Number.isFinite(at)) {
|
|
5769
|
+
removeKey();
|
|
5770
|
+
return null;
|
|
5771
|
+
}
|
|
5772
|
+
const current = now();
|
|
5773
|
+
if (current - at > ttlMs || at > current + FUTURE_TOLERANCE_MS) {
|
|
5774
|
+
removeKey();
|
|
5775
|
+
return null;
|
|
5776
|
+
}
|
|
5777
|
+
return { from: typeof from === "string" ? from : "", to: typeof to === "string" ? to : "", at };
|
|
5778
|
+
}
|
|
5779
|
+
function clear() {
|
|
5780
|
+
removeKey();
|
|
5781
|
+
}
|
|
5782
|
+
return { write, read, clear };
|
|
5614
5783
|
}
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
void copyText(fullName).then((ok) => {
|
|
5636
|
-
if (!ok) return;
|
|
5637
|
-
setCopied(true);
|
|
5638
|
-
setTimeout(() => setCopied(false), 1400);
|
|
5639
|
-
});
|
|
5640
|
-
};
|
|
5641
|
-
const coreValue = () => {
|
|
5642
|
-
if (coreVersion === "") return "—";
|
|
5643
|
-
if (coreRepo === void 0) return coreVersion;
|
|
5644
|
-
return h(
|
|
5645
|
-
"span",
|
|
5646
|
-
{ className: "dshgt-about-core" },
|
|
5647
|
-
h("a", { href: coreRepo, target: "_blank", rel: "noreferrer" }, coreVersion),
|
|
5648
|
-
h(
|
|
5649
|
-
"a",
|
|
5650
|
-
{ className: "dshgt-about-gh", href: coreRepo, target: "_blank", rel: "noreferrer", title: t("about.core.repo"), "aria-label": t("about.core.repo") },
|
|
5651
|
-
githubIcon()
|
|
5652
|
-
)
|
|
5653
|
-
);
|
|
5654
|
-
};
|
|
5655
|
-
const dialog = h(
|
|
5656
|
-
"div",
|
|
5657
|
-
{ className: "dshgt-modal-mask", onClick: (event) => {
|
|
5658
|
-
if (event.target === event.currentTarget) props.onClose();
|
|
5659
|
-
} },
|
|
5660
|
-
h(
|
|
5661
|
-
"div",
|
|
5662
|
-
{ className: "dshgt-modal dshgt-about", role: "dialog", "aria-modal": "true", "aria-label": t("about.title") },
|
|
5663
|
-
h(
|
|
5664
|
-
"div",
|
|
5665
|
-
{ className: "dshgt-about-head" },
|
|
5666
|
-
h("h3", { className: "dshgt-about-title" }, t("about.title")),
|
|
5667
|
-
h(Btn, { small: true, onClick: () => props.onClose() }, t("about.close"))
|
|
5668
|
-
),
|
|
5669
|
-
h(
|
|
5670
|
-
"button",
|
|
5671
|
-
{ type: "button", className: `dshgt-about-pkg${copied ? " is-copied" : ""}`, onClick: copy },
|
|
5672
|
-
h("span", { className: "dshgt-mono" }, fullName)
|
|
5673
|
-
),
|
|
5674
|
-
h(KV, {
|
|
5675
|
-
items: [
|
|
5676
|
-
[
|
|
5677
|
-
t("about.repo"),
|
|
5678
|
-
repository === void 0 || repoVersion === void 0 ? h("span", { className: "dshgt-hint" }, t("about.repo.missing")) : h("a", { href: repository, target: "_blank", rel: "noreferrer" }, repoVersion)
|
|
5679
|
-
],
|
|
5680
|
-
[t("about.license"), "MIT"],
|
|
5681
|
-
[t("about.core"), coreValue()],
|
|
5682
|
-
[t("about.env"), t("about.env.value")]
|
|
5683
|
-
]
|
|
5684
|
-
}),
|
|
5685
|
-
h(UpdateRow, { t, update: updateState, controller: updateController, fallbackVersion: plugin.version })
|
|
5686
|
-
)
|
|
5687
|
-
);
|
|
5688
|
-
return h("div", { className: "dshgt-root" }, dialog);
|
|
5784
|
+
|
|
5785
|
+
// client/update-store.ts
|
|
5786
|
+
var PREFIX = "dsh-github-trending:";
|
|
5787
|
+
function browserStorage() {
|
|
5788
|
+
try {
|
|
5789
|
+
const w = typeof window !== "undefined" ? window : void 0;
|
|
5790
|
+
return w?.localStorage ?? void 0;
|
|
5791
|
+
} catch {
|
|
5792
|
+
return void 0;
|
|
5793
|
+
}
|
|
5794
|
+
}
|
|
5795
|
+
var pendingStore = createPendingStore({ keyPrefix: PREFIX, storage: browserStorage() });
|
|
5796
|
+
function writePendingUpdate(from, to) {
|
|
5797
|
+
pendingStore.write(from, to);
|
|
5798
|
+
}
|
|
5799
|
+
function readPendingUpdate() {
|
|
5800
|
+
return pendingStore.read();
|
|
5801
|
+
}
|
|
5802
|
+
function clearPendingUpdate() {
|
|
5803
|
+
pendingStore.clear();
|
|
5689
5804
|
}
|
|
5690
5805
|
|
|
5691
5806
|
// client/identity-bar.ts
|
|
5692
|
-
function
|
|
5807
|
+
function logo2() {
|
|
5693
5808
|
return h(
|
|
5694
5809
|
"svg",
|
|
5695
5810
|
{ width: 22, height: 22, viewBox: "0 0 64 64", "aria-hidden": "true" },
|
|
@@ -5698,44 +5813,26 @@ function logo() {
|
|
|
5698
5813
|
h("circle", { cx: 32, cy: 45, r: 3, fill: "#3fb950" })
|
|
5699
5814
|
);
|
|
5700
5815
|
}
|
|
5701
|
-
function
|
|
5816
|
+
function githubIcon() {
|
|
5702
5817
|
return h("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true" }, h("path", {
|
|
5703
5818
|
d: "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"
|
|
5704
5819
|
}));
|
|
5705
5820
|
}
|
|
5706
5821
|
function IdentityBar(props) {
|
|
5707
5822
|
const { t, plugin } = props;
|
|
5708
|
-
const [copied, setCopied] = import_react.default.useState(false);
|
|
5709
5823
|
const [confirming, setConfirming] = import_react.default.useState(false);
|
|
5710
|
-
const [cmdCopied, setCmdCopied] = import_react.default.useState(false);
|
|
5711
5824
|
const [updateState, controller] = usePluginUpdate();
|
|
5712
5825
|
const view = updateState.view;
|
|
5713
5826
|
const status = updateState.status;
|
|
5714
5827
|
import_react.default.useEffect(() => {
|
|
5715
5828
|
if (status === "applying" || status === "restart-required" || status === "applied") setConfirming(false);
|
|
5716
5829
|
}, [status]);
|
|
5717
|
-
const copyPkg = () => {
|
|
5718
|
-
void copyText(plugin.name).then((ok) => {
|
|
5719
|
-
if (!ok) return;
|
|
5720
|
-
setCopied(true);
|
|
5721
|
-
setTimeout(() => setCopied(false), 1400);
|
|
5722
|
-
});
|
|
5723
|
-
};
|
|
5724
5830
|
const busy = status === "checking" || status === "applying";
|
|
5725
5831
|
const settled = status === "restart-required" || status === "applied";
|
|
5726
5832
|
const latestVersion = view === null ? "" : view.latestVersion ?? "";
|
|
5727
5833
|
const updateAvailable = view !== null && view.updateAvailable;
|
|
5728
5834
|
const actionable = updateAvailable && view !== null && view.canApply && !settled && !busy;
|
|
5729
|
-
const manual = view !== null && (!view.canApply || view.checkFailed) ? view.manualCommand ?? null : null;
|
|
5730
5835
|
const currentVersion = view === null ? plugin.version : view.currentVersion ?? plugin.version;
|
|
5731
|
-
const copyCmd = () => {
|
|
5732
|
-
if (manual === void 0 || manual === null) return;
|
|
5733
|
-
void copyText(manual).then((ok) => {
|
|
5734
|
-
if (!ok) return;
|
|
5735
|
-
setCmdCopied(true);
|
|
5736
|
-
setTimeout(() => setCmdCopied(false), 1400);
|
|
5737
|
-
});
|
|
5738
|
-
};
|
|
5739
5836
|
function statusLine() {
|
|
5740
5837
|
if (status === "checking" || view === null) return { text: t("shell.update.checking"), kind: "muted" };
|
|
5741
5838
|
if (status === "applying") return { text: t("shell.update.applying", { version: latestVersion }), kind: "muted" };
|
|
@@ -5752,6 +5849,7 @@ function IdentityBar(props) {
|
|
|
5752
5849
|
return [
|
|
5753
5850
|
h(Btn, { key: "yes", small: true, variant: "danger", onClick: () => {
|
|
5754
5851
|
setConfirming(false);
|
|
5852
|
+
writePendingUpdate(currentVersion, latestVersion);
|
|
5755
5853
|
void controller.apply();
|
|
5756
5854
|
} }, t("shell.update.confirmYes")),
|
|
5757
5855
|
h(Btn, { key: "no", small: true, onClick: () => setConfirming(false) }, t("shell.update.cancel"))
|
|
@@ -5759,25 +5857,27 @@ function IdentityBar(props) {
|
|
|
5759
5857
|
}
|
|
5760
5858
|
return h(Btn, { small: true, variant: "primary", onClick: () => setConfirming(true) }, t("shell.update.apply", { version: latestVersion }));
|
|
5761
5859
|
}
|
|
5762
|
-
if (manual !== null) return h(Btn, { small: true, onClick: copyCmd }, cmdCopied ? t("shell.update.copied") : t("shell.update.copyCmd"));
|
|
5763
5860
|
return h(Btn, { small: true, disabled: busy, onClick: () => void controller.check({ fresh: true }) }, t("shell.update.check"));
|
|
5764
5861
|
}
|
|
5765
5862
|
const line = statusLine();
|
|
5766
5863
|
return h(
|
|
5767
5864
|
"div",
|
|
5768
5865
|
{ className: "dshgt-idbar" },
|
|
5769
|
-
h("div", { className: "dshgt-brand" },
|
|
5770
|
-
h("
|
|
5771
|
-
h("span", { className: "dshgt-id-sep" }),
|
|
5866
|
+
h("div", { className: "dshgt-brand" }, logo2(), h("span", { className: "dshgt-brand-name" }, t("section.title"))),
|
|
5867
|
+
h("span", { className: "dshgt-id-ver dshgt-mono" }, `v${plugin.version}`),
|
|
5868
|
+
h("span", { className: "dshgt-id-sep dshgt-id-sep-pkg" }),
|
|
5772
5869
|
h(
|
|
5773
5870
|
"button",
|
|
5774
|
-
{ type: "button", className: "dshgt-id-pkg dshgt-mono", title:
|
|
5775
|
-
|
|
5871
|
+
{ type: "button", className: "dshgt-id-pkg dshgt-mono", title: t("about.title"), onClick: () => props.onOpenAbout() },
|
|
5872
|
+
plugin.name
|
|
5776
5873
|
),
|
|
5874
|
+
plugin.repository === void 0 ? null : [
|
|
5875
|
+
h("span", { key: "gh-sep", className: "dshgt-id-sep dshgt-id-sep-gh" }),
|
|
5876
|
+
h("a", { key: "gh", className: "dshgt-id-gh", href: plugin.repository, target: "_blank", rel: "noreferrer", title: t("about.repo"), "aria-label": t("about.repo") }, githubIcon())
|
|
5877
|
+
],
|
|
5777
5878
|
h(
|
|
5778
5879
|
"div",
|
|
5779
5880
|
{ className: "dshgt-idbar-right" },
|
|
5780
|
-
plugin.repository === void 0 ? null : h("a", { className: "dshgt-id-gh", href: plugin.repository, target: "_blank", rel: "noreferrer", title: t("about.repo"), "aria-label": t("about.repo") }, githubIcon2()),
|
|
5781
5881
|
h(
|
|
5782
5882
|
"span",
|
|
5783
5883
|
{ className: "dshgt-id-upd" },
|
|
@@ -5787,8 +5887,30 @@ function IdentityBar(props) {
|
|
|
5787
5887
|
)
|
|
5788
5888
|
);
|
|
5789
5889
|
}
|
|
5790
|
-
|
|
5791
|
-
|
|
5890
|
+
|
|
5891
|
+
// client/restore-notice.ts
|
|
5892
|
+
var AUTO_DISMISS_MS = 6e3;
|
|
5893
|
+
function RestoreNotice({ t, version, onDismiss }) {
|
|
5894
|
+
import_react.default.useEffect(() => {
|
|
5895
|
+
const timer = setTimeout(() => onDismiss(), AUTO_DISMISS_MS);
|
|
5896
|
+
return () => clearTimeout(timer);
|
|
5897
|
+
}, [onDismiss]);
|
|
5898
|
+
const title = version !== void 0 && version !== "" ? t("restoreNotice.title", { version }) : t("restoreNotice.titleBare");
|
|
5899
|
+
return h(
|
|
5900
|
+
"div",
|
|
5901
|
+
{ className: "dshgt-restore", role: "status", "aria-live": "polite" },
|
|
5902
|
+
h(
|
|
5903
|
+
"div",
|
|
5904
|
+
{ className: "dshgt-restore-text" },
|
|
5905
|
+
h("div", { className: "dshgt-restore-title" }, title),
|
|
5906
|
+
h("div", { className: "dshgt-restore-body" }, t("restoreNotice.body"))
|
|
5907
|
+
),
|
|
5908
|
+
h(
|
|
5909
|
+
"div",
|
|
5910
|
+
{ className: "dshgt-restore-actions" },
|
|
5911
|
+
h(Btn, { small: true, variant: "primary", onClick: () => onDismiss() }, t("restoreNotice.dismiss"))
|
|
5912
|
+
)
|
|
5913
|
+
);
|
|
5792
5914
|
}
|
|
5793
5915
|
|
|
5794
5916
|
// client/panel-icon.ts
|
|
@@ -5821,8 +5943,8 @@ var inject = ["slots", "locale"];
|
|
|
5821
5943
|
var NAV = [
|
|
5822
5944
|
{ id: "overview", label: "nav.overview", icon: "grid" },
|
|
5823
5945
|
{ id: "digest", label: "nav.digest", icon: "doc" },
|
|
5824
|
-
{ id: "runs", label: "nav.runs", icon: "list" },
|
|
5825
5946
|
{ id: "subscriptions", label: "nav.subscriptions", icon: "rss" },
|
|
5947
|
+
{ id: "runs", label: "nav.runs", icon: "list" },
|
|
5826
5948
|
{ id: "settings", label: "nav.settings", icon: "sliders" }
|
|
5827
5949
|
];
|
|
5828
5950
|
function navIcon(name, size = 16) {
|
|
@@ -5926,6 +6048,10 @@ function apply(ctx) {
|
|
|
5926
6048
|
const [view, setView] = import_react.default.useState("overview");
|
|
5927
6049
|
const [digestTarget2, setDigestTarget] = import_react.default.useState(void 0);
|
|
5928
6050
|
const [aboutOpen, setAboutOpen] = import_react.default.useState(false);
|
|
6051
|
+
const [pendingUpdate, setPendingUpdate] = import_react.default.useState(null);
|
|
6052
|
+
import_react.default.useEffect(() => {
|
|
6053
|
+
setPendingUpdate(readPendingUpdate());
|
|
6054
|
+
}, []);
|
|
5929
6055
|
const openDigest = import_react.default.useCallback((target) => {
|
|
5930
6056
|
if (target !== void 0) setDigestTarget(target);
|
|
5931
6057
|
setView("digest");
|
|
@@ -6063,7 +6189,15 @@ function apply(ctx) {
|
|
|
6063
6189
|
h("div", { className: "dshgt-main-body" }, view === "settings" ? viewNode : h("div", { className: "dshgt-scroll" }, viewNode))
|
|
6064
6190
|
)
|
|
6065
6191
|
),
|
|
6066
|
-
aboutOpen && state !== null ? h(AboutDialog, { t, state, onClose: () => setAboutOpen(false) }) : null
|
|
6192
|
+
aboutOpen && state !== null ? h(AboutDialog, { t, state, onClose: () => setAboutOpen(false) }) : null,
|
|
6193
|
+
pendingUpdate ? h(RestoreNotice, {
|
|
6194
|
+
t,
|
|
6195
|
+
version: pendingUpdate.to,
|
|
6196
|
+
onDismiss: () => {
|
|
6197
|
+
clearPendingUpdate();
|
|
6198
|
+
setPendingUpdate(null);
|
|
6199
|
+
}
|
|
6200
|
+
}) : null
|
|
6067
6201
|
);
|
|
6068
6202
|
}
|
|
6069
6203
|
disposers.push(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morehao/dsh-github-trending",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.8",
|
|
4
4
|
"description": "GitHub 趋势日报的 DeepSeek Harness 插件:按日 / 周 / 月周期定时 spawn 本地 trendradar 核心,抓取 Trending、生成中文简介与周期总结,并可选把订阅仓库的新 Release 合成中文摘要,一起提交到你的仓库、自动开 PR 合并;内置概览 / 榜单 / 运行记录 / 订阅 / 设置工作台。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@morehao/dsh-plugin-kit": "^0.
|
|
54
|
+
"@morehao/dsh-plugin-kit": "^0.4.0",
|
|
55
55
|
"@morehao/trendradar-contract": "0.5.0"
|
|
56
56
|
},
|
|
57
57
|
"dsh": {
|