dsh-plugin 1.6.0 → 1.6.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/README.en.md CHANGED
@@ -29,7 +29,7 @@
29
29
  DSH Plugin Hub is a **community plugin marketplace for DeepSeek Harness**: an open-source plugin built to the official plugin development spec. Installed under **Settings → Plugin Hub**, it lets you browse, search and install community plugins without leaving the app. This is an independent community project, not affiliated with DeepSeek Harness.
30
30
 
31
31
  <p align="center">
32
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-market-en.png" alt="DSH Plugin Hub plugin market UI" width="840">
32
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-market-en.png?v=1.6.0" alt="DSH Plugin Hub plugin market UI" width="840">
33
33
  </p>
34
34
 
35
35
  ## Plugin Hub Features
@@ -76,8 +76,8 @@ Questions, feature ideas or just want to talk plugins? Scan the QR code to join
76
76
  **Installed plugins · Custom install**
77
77
 
78
78
  <p align="center">
79
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-installed-en.png" alt="Installed plugins" width="400">
80
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-custom-install-en.png" alt="Custom install" width="400">
79
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-installed-en.png?v=1.6.0" alt="Installed plugins" width="400">
80
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-custom-install-en.png?v=1.6.0" alt="Custom install" width="400">
81
81
  </p>
82
82
 
83
83
  Manages every installed plugin with search, source filters and sorting, plus update / uninstall and reveal-in-Finder per row · Installs any plugin outside the catalog via three channels: npm package, GitHub source and DSH command
@@ -85,8 +85,8 @@ Manages every installed plugin with search, source filters and sorting, plus upd
85
85
  **Settings · System logs**
86
86
 
87
87
  <p align="center">
88
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-settings-en.png" alt="Settings" width="400">
89
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-system-logs-en.png" alt="System logs" width="400">
88
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-settings-en.png?v=1.6.0" alt="Settings" width="400">
89
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-system-logs-en.png?v=1.6.0" alt="System logs" width="400">
90
90
  </p>
91
91
 
92
92
  Centralizes update checks, npm mirror, proxy channel, trust toggles and log location · Records install / uninstall / settings / diagnostics trails, filterable by category and level, with a built-in viewer
@@ -94,8 +94,8 @@ Centralizes update checks, npm mirror, proxy channel, trust toggles and log loca
94
94
  **Confirm install · Confirm uninstall**
95
95
 
96
96
  <p align="center">
97
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-install-confirm-en.png" alt="Confirm install" width="400">
98
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-uninstall-confirm-en.png" alt="Confirm uninstall" width="400">
97
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-install-confirm-en.png?v=1.6.0" alt="Confirm install" width="400">
98
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-uninstall-confirm-en.png?v=1.6.0" alt="Confirm uninstall" width="400">
99
99
  </p>
100
100
 
101
101
  Shows the plugin, its source repo and the command before anything runs; the install starts only after confirmation · Shows what will be removed and its source; nothing is removed until the user confirms
@@ -103,8 +103,8 @@ Shows the plugin, its source repo and the command before anything runs; the inst
103
103
  **Confirm update · Notifications**
104
104
 
105
105
  <p align="center">
106
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-update-confirm-en.png" alt="Confirm update" width="400">
107
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-notifications-en.png" alt="Notifications" width="400">
106
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-update-confirm-en.png?v=1.6.0" alt="Confirm update" width="400">
107
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-notifications-en.png?v=1.6.0" alt="Notifications" width="400">
108
108
  </p>
109
109
 
110
110
  Pops up when a newer version is found; confirming overwrite-installs in place to the latest release · Gathers install / remove / update history, live task progress and pending-restart reminders in one place
package/README.md CHANGED
@@ -29,7 +29,7 @@
29
29
  DSH Plugin Hub 是 **DeepSeek Harness 社区插件市场**:一个遵循官方插件开发规范构建的开源插件,安装进「设置 → 插件市场」后,无需离开应用即可浏览、搜索并一键安装社区插件。本项目为独立社区项目,与 DeepSeek Harness 官方无隶属关系。
30
30
 
31
31
  <p align="center">
32
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-market-zh.png" alt="DSH Plugin Hub 插件市场界面" width="840">
32
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-market-zh.png?v=1.6.0" alt="DSH Plugin Hub 插件市场界面" width="840">
33
33
  </p>
34
34
 
35
35
  ## 插件市场特性
@@ -76,8 +76,8 @@ DSH Plugin Hub 是 **DeepSeek Harness 社区插件市场**:一个遵循官方
76
76
  **已安装插件列表 · 自定义安装**
77
77
 
78
78
  <p align="center">
79
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-installed-zh.png" alt="已安装插件列表" width="400">
80
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-custom-install-zh.png" alt="自定义安装" width="400">
79
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-installed-zh.png?v=1.6.0" alt="已安装插件列表" width="400">
80
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-custom-install-zh.png?v=1.6.0" alt="自定义安装" width="400">
81
81
  </p>
82
82
 
83
83
  集中管理当前环境已装的全部插件,支持搜索、来源筛选与排序,行尾提供更新、卸载与「在 Finder 中显示」 · 手动安装目录外的任意插件,支持 NPM 包、GitHub 源码与 DSH 命令行三种通道
@@ -85,8 +85,8 @@ DSH Plugin Hub 是 **DeepSeek Harness 社区插件市场**:一个遵循官方
85
85
  **设置 · 系统日志**
86
86
 
87
87
  <p align="center">
88
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-settings-zh.png" alt="设置" width="400">
89
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-system-logs-zh.png" alt="系统日志" width="400">
88
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-settings-zh.png?v=1.6.0" alt="设置" width="400">
89
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-system-logs-zh.png?v=1.6.0" alt="系统日志" width="400">
90
90
  </p>
91
91
 
92
92
  集中配置更新检查、NPM 镜像源、代理通道、安全信任与日志存放位置 · 记录安装、卸载、设置变更与诊断轨迹,按分类与级别筛选,内置日志查看器
@@ -94,8 +94,8 @@ DSH Plugin Hub 是 **DeepSeek Harness 社区插件市场**:一个遵循官方
94
94
  **确认安装 · 确认卸载**
95
95
 
96
96
  <p align="center">
97
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-install-confirm-zh.png" alt="确认安装" width="400">
98
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-uninstall-confirm-zh.png" alt="确认卸载" width="400">
97
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-install-confirm-zh.png?v=1.6.0" alt="确认安装" width="400">
98
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-uninstall-confirm-zh.png?v=1.6.0" alt="确认卸载" width="400">
99
99
  </p>
100
100
 
101
101
  安装前展示插件名称、来源仓库与执行命令,确认后才开始安装 · 卸载前展示待移除的插件,确认后才从环境移除,避免误删
@@ -103,8 +103,8 @@ DSH Plugin Hub 是 **DeepSeek Harness 社区插件市场**:一个遵循官方
103
103
  **确认更新 · 通知中心**
104
104
 
105
105
  <p align="center">
106
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-update-confirm-zh.png" alt="确认更新" width="400">
107
- <img src="https://api.dsh-plugin.org/images/releases/1-4-13/dsh-plugin-hub-notifications-zh.png" alt="通知中心" width="400">
106
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-update-confirm-zh.png?v=1.6.0" alt="确认更新" width="400">
107
+ <img src="https://api.dsh-plugin.org/images/releases/1-6-0/dsh-plugin-hub-notifications-zh.png?v=1.6.0" alt="通知中心" width="400">
108
108
  </p>
109
109
 
110
110
  检测到新版本时弹出,确认后原位覆盖安装到最新版 · 集中管理安装、卸载、更新的历史记录、实时进度与待重启提醒
package/client/client.js CHANGED
@@ -706,42 +706,42 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
706
706
  css: css$11
707
707
  });
708
708
  var Header_module_css_default = {
709
- "githubLink": "qikqja_githubLink",
709
+ "githubIcon": "qikqja_githubIcon",
710
+ "version": "qikqja_version",
711
+ "segBtnActive": "qikqja_segBtnActive",
710
712
  "resultSeg": "qikqja_resultSeg",
711
- "headerRight": "qikqja_headerRight",
712
- "segBtn": "qikqja_segBtn",
713
- "header": "qikqja_header",
714
713
  "searchRow": "qikqja_searchRow",
715
- "brandTitle": "qikqja_brandTitle",
716
- "tabsRow": "qikqja_tabsRow",
714
+ "tabActive": "qikqja_tabActive",
715
+ "tab": "qikqja_tab",
716
+ "headerRight": "qikqja_headerRight",
717
717
  "title": "qikqja_title",
718
- "langBtn": "qikqja_langBtn",
719
- "root": "qikqja_root",
720
- "headerTitleRow": "qikqja_headerTitleRow",
721
- "resultCount": "qikqja_resultCount",
722
- "segBtnActive": "qikqja_segBtnActive",
723
- "aboutBtn": "qikqja_aboutBtn",
724
- "version": "qikqja_version",
725
718
  "adBadge": "qikqja_adBadge",
726
- "githubIcon": "qikqja_githubIcon",
727
- "copyIcon": "qikqja_copyIcon",
728
- "segGroup": "qikqja_segGroup",
729
- "adText": "qikqja_adText",
730
- "tabActive": "qikqja_tabActive",
731
719
  "logoIcon": "qikqja_logoIcon",
720
+ "githubLink": "qikqja_githubLink",
721
+ "header": "qikqja_header",
732
722
  "taglineLink": "qikqja_taglineLink",
723
+ "tabs": "qikqja_tabs",
724
+ "sortGroup": "qikqja_sortGroup",
725
+ "search": "qikqja_search",
726
+ "tabCount": "qikqja_tabCount",
727
+ "brandTitle": "qikqja_brandTitle",
733
728
  "versionBtn": "qikqja_versionBtn",
729
+ "controls": "qikqja_controls",
730
+ "copyIcon": "qikqja_copyIcon",
731
+ "segGroup": "qikqja_segGroup",
732
+ "langBtn": "qikqja_langBtn",
733
+ "root": "qikqja_root",
734
+ "adText": "qikqja_adText",
735
+ "headerTitleRow": "qikqja_headerTitleRow",
734
736
  "hubUpdateBadge": "qikqja_hubUpdateBadge",
735
- "sortGroup": "qikqja_sortGroup",
737
+ "resultCount": "qikqja_resultCount",
738
+ "segLabel": "qikqja_segLabel",
739
+ "segBtn": "qikqja_segBtn",
736
740
  "tagline": "qikqja_tagline",
737
- "controls": "qikqja_controls",
738
- "tab": "qikqja_tab",
739
741
  "adBanner": "qikqja_adBanner",
740
- "tabCount": "qikqja_tabCount",
741
- "search": "qikqja_search",
742
- "tabs": "qikqja_tabs",
743
- "segLabel": "qikqja_segLabel",
744
- "adArrow": "qikqja_adArrow"
742
+ "aboutBtn": "qikqja_aboutBtn",
743
+ "adArrow": "qikqja_adArrow",
744
+ "tabsRow": "qikqja_tabsRow"
745
745
  };
746
746
  //#endregion
747
747
  //#region \0dsh-css:src/client/styles/Modal.module.css.mjs
@@ -760,136 +760,136 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
760
760
  css: css$10
761
761
  });
762
762
  var Modal_module_css_default = {
763
- "result": "BiQ1zG_result",
764
- "failDiagBtn": "BiQ1zG_failDiagBtn",
765
- "noticeRow": "BiQ1zG_noticeRow",
766
- "dangerConfirm": "BiQ1zG_dangerConfirm",
767
- "detailModal": "BiQ1zG_detailModal",
768
763
  "errorHint": "BiQ1zG_errorHint",
769
764
  "resultCheckIcon": "BiQ1zG_resultCheckIcon",
770
- "noticeBadgeOk": "BiQ1zG_noticeBadgeOk",
771
- "modalCopy": "BiQ1zG_modalCopy",
772
- "failRow": "BiQ1zG_failRow",
773
- "detailRow": "BiQ1zG_detailRow",
774
- "queueSection": "BiQ1zG_queueSection",
775
- "failBigIssue": "BiQ1zG_failBigIssue",
776
- "toastFail": "BiQ1zG_toastFail",
777
- "modalInstall": "BiQ1zG_modalInstall",
778
- "noticeUpdateGo": "BiQ1zG_noticeUpdateGo",
779
- "modalIn": "BiQ1zG_modalIn",
780
- "noticeMain": "BiQ1zG_noticeMain",
781
- "errorCopySoft": "BiQ1zG_errorCopySoft",
782
- "stripCancel": "BiQ1zG_stripCancel",
783
- "failList": "BiQ1zG_failList",
784
- "restartLater": "BiQ1zG_restartLater",
785
- "failedCopyHint": "BiQ1zG_failedCopyHint",
786
- "queueRowStatus": "BiQ1zG_queueRowStatus",
787
- "modalTitleBusy": "BiQ1zG_modalTitleBusy",
788
- "pendingRowStatus": "BiQ1zG_pendingRowStatus",
765
+ "linkIcon": "BiQ1zG_linkIcon",
766
+ "queuedHint": "BiQ1zG_queuedHint",
767
+ "failNetworkTarget": "BiQ1zG_failNetworkTarget",
768
+ "modalDesc": "BiQ1zG_modalDesc",
769
+ "queueRowBody": "BiQ1zG_queueRowBody",
770
+ "toastIn": "BiQ1zG_toastIn",
771
+ "queueRow": "BiQ1zG_queueRow",
772
+ "modalTitle": "BiQ1zG_modalTitle",
773
+ "modalValue": "BiQ1zG_modalValue",
774
+ "uninstallConfirm": "BiQ1zG_uninstallConfirm",
775
+ "modalLink": "BiQ1zG_modalLink",
776
+ "progressFillFail": "BiQ1zG_progressFillFail",
777
+ "detailGrid": "BiQ1zG_detailGrid",
778
+ "resultDesc": "BiQ1zG_resultDesc",
779
+ "failRepo": "BiQ1zG_failRepo",
780
+ "modalHead": "BiQ1zG_modalHead",
789
781
  "progressFill": "BiQ1zG_progressFill",
790
- "progressText": "BiQ1zG_progressText",
791
- "failKind": "BiQ1zG_failKind",
792
- "noticeVersion": "BiQ1zG_noticeVersion",
782
+ "errorBox": "BiQ1zG_errorBox",
793
783
  "detailDim": "BiQ1zG_detailDim",
794
- "pendingRowActions": "BiQ1zG_pendingRowActions",
795
- "modalCmd": "BiQ1zG_modalCmd",
796
- "detailGrid": "BiQ1zG_detailGrid",
797
- "noticeHead": "BiQ1zG_noticeHead",
798
- "hubUpdateMetaItem": "BiQ1zG_hubUpdateMetaItem",
799
- "modal": "BiQ1zG_modal",
800
- "aboutContent": "BiQ1zG_aboutContent",
801
- "hubUpdateMeta": "BiQ1zG_hubUpdateMeta",
784
+ "queueRowTarget": "BiQ1zG_queueRowTarget",
785
+ "overlay": "BiQ1zG_overlay",
802
786
  "overlayIn": "BiQ1zG_overlayIn",
803
- "modalClose": "BiQ1zG_modalClose",
804
- "progressTrack": "BiQ1zG_progressTrack",
805
- "modalCloseIcon": "BiQ1zG_modalCloseIcon",
806
- "queueRowBody": "BiQ1zG_queueRowBody",
807
- "modalCmdText": "BiQ1zG_modalCmdText",
808
- "errorBox": "BiQ1zG_errorBox",
809
- "confirmIcon": "BiQ1zG_confirmIcon",
810
- "detailValue": "BiQ1zG_detailValue",
811
- "detailPathBtn": "BiQ1zG_detailPathBtn",
787
+ "queueSectionTitle": "BiQ1zG_queueSectionTitle",
788
+ "modal": "BiQ1zG_modal",
812
789
  "restartNowWarning": "BiQ1zG_restartNowWarning",
790
+ "noticeRowOk": "BiQ1zG_noticeRowOk",
791
+ "modalIn": "BiQ1zG_modalIn",
792
+ "failDiagBtn": "BiQ1zG_failDiagBtn",
793
+ "modalCmdText": "BiQ1zG_modalCmdText",
794
+ "queueRowHead": "BiQ1zG_queueRowHead",
795
+ "failKindUninstall": "BiQ1zG_failKindUninstall",
796
+ "queueRowPct": "BiQ1zG_queueRowPct",
797
+ "modalCmd": "BiQ1zG_modalCmd",
813
798
  "noticeRemove": "BiQ1zG_noticeRemove",
814
- "modalWide": "BiQ1zG_modalWide",
815
- "resultDesc": "BiQ1zG_resultDesc",
816
- "linkIcon": "BiQ1zG_linkIcon",
817
- "failClear": "BiQ1zG_failClear",
818
- "noticeTextFail": "BiQ1zG_noticeTextFail",
819
- "modalValue": "BiQ1zG_modalValue",
799
+ "pendingRowActions": "BiQ1zG_pendingRowActions",
800
+ "modalCmdCopy": "BiQ1zG_modalCmdCopy",
801
+ "noticeIgnore": "BiQ1zG_noticeIgnore",
802
+ "confirmIcon": "BiQ1zG_confirmIcon",
803
+ "noticeBadgeOk": "BiQ1zG_noticeBadgeOk",
804
+ "trustHint": "BiQ1zG_trustHint",
805
+ "errorModal": "BiQ1zG_errorModal",
806
+ "pendingRowStatus": "BiQ1zG_pendingRowStatus",
807
+ "logModal": "BiQ1zG_logModal",
808
+ "queueSection": "BiQ1zG_queueSection",
809
+ "detailArrow": "BiQ1zG_detailArrow",
810
+ "detailStatusRunning": "BiQ1zG_detailStatusRunning",
820
811
  "restartNow": "BiQ1zG_restartNow",
821
- "errorTitle": "BiQ1zG_errorTitle",
822
- "modalTitleQueued": "BiQ1zG_modalTitleQueued",
823
- "detailPathText": "BiQ1zG_detailPathText",
824
- "resultCheck": "BiQ1zG_resultCheck",
825
812
  "detailStatusText": "BiQ1zG_detailStatusText",
826
- "toastIn": "BiQ1zG_toastIn",
827
- "queueRowDesc": "BiQ1zG_queueRowDesc",
828
- "failPrepareHint": "BiQ1zG_failPrepareHint",
829
- "confirmIconWrap": "BiQ1zG_confirmIconWrap",
813
+ "confirmPrimary": "BiQ1zG_confirmPrimary",
814
+ "modalCopy": "BiQ1zG_modalCopy",
830
815
  "detailPathActions": "BiQ1zG_detailPathActions",
816
+ "restartLater": "BiQ1zG_restartLater",
817
+ "noticeRow": "BiQ1zG_noticeRow",
818
+ "failPrepareHint": "BiQ1zG_failPrepareHint",
819
+ "hubUpdateMetaItem": "BiQ1zG_hubUpdateMetaItem",
820
+ "cliOnlyHint": "BiQ1zG_cliOnlyHint",
821
+ "resultRestarting": "BiQ1zG_resultRestarting",
822
+ "progress": "BiQ1zG_progress",
823
+ "noticeRowUpdate": "BiQ1zG_noticeRowUpdate",
824
+ "detailValue": "BiQ1zG_detailValue",
825
+ "modalWide": "BiQ1zG_modalWide",
826
+ "resultTitle": "BiQ1zG_resultTitle",
827
+ "noticeTime": "BiQ1zG_noticeTime",
828
+ "modalInstall": "BiQ1zG_modalInstall",
829
+ "modalCancel": "BiQ1zG_modalCancel",
830
+ "modalActions": "BiQ1zG_modalActions",
831
+ "failEmpty": "BiQ1zG_failEmpty",
832
+ "helpModal": "BiQ1zG_helpModal",
833
+ "hubUpdateMeta": "BiQ1zG_hubUpdateMeta",
831
834
  "detailUpdateHint": "BiQ1zG_detailUpdateHint",
832
- "overlay": "BiQ1zG_overlay",
833
- "failRepo": "BiQ1zG_failRepo",
834
- "queueRowTarget": "BiQ1zG_queueRowTarget",
835
- "detailArrow": "BiQ1zG_detailArrow",
835
+ "modalCloseIcon": "BiQ1zG_modalCloseIcon",
836
+ "detailLink": "BiQ1zG_detailLink",
837
+ "failCopy": "BiQ1zG_failCopy",
838
+ "detailStatusPending": "BiQ1zG_detailStatusPending",
839
+ "errorTitle": "BiQ1zG_errorTitle",
840
+ "hubUpdateNotes": "BiQ1zG_hubUpdateNotes",
836
841
  "progressHead": "BiQ1zG_progressHead",
837
- "toast": "BiQ1zG_toast",
838
- "uninstallConfirm": "BiQ1zG_uninstallConfirm",
842
+ "progressText": "BiQ1zG_progressText",
843
+ "progressTrack": "BiQ1zG_progressTrack",
844
+ "noticeBadgeFail": "BiQ1zG_noticeBadgeFail",
845
+ "detailModal": "BiQ1zG_detailModal",
846
+ "toastFail": "BiQ1zG_toastFail",
847
+ "queueRowStatus": "BiQ1zG_queueRowStatus",
848
+ "noticeRowMain": "BiQ1zG_noticeRowMain",
849
+ "errorCopySoft": "BiQ1zG_errorCopySoft",
850
+ "noticeMain": "BiQ1zG_noticeMain",
851
+ "detailRow": "BiQ1zG_detailRow",
852
+ "detailPath": "BiQ1zG_detailPath",
839
853
  "detailLabel": "BiQ1zG_detailLabel",
840
- "detailLink": "BiQ1zG_detailLink",
841
- "modalRow": "BiQ1zG_modalRow",
842
- "modalHead": "BiQ1zG_modalHead",
843
- "noticeIgnore": "BiQ1zG_noticeIgnore",
844
- "logModal": "BiQ1zG_logModal",
854
+ "noticeTextOk": "BiQ1zG_noticeTextOk",
855
+ "queueRowTrack": "BiQ1zG_queueRowTrack",
845
856
  "modalBody": "BiQ1zG_modalBody",
846
- "failEmpty": "BiQ1zG_failEmpty",
847
- "hubUpdateModal": "BiQ1zG_hubUpdateModal",
848
- "trustHint": "BiQ1zG_trustHint",
849
- "modalCancel": "BiQ1zG_modalCancel",
857
+ "stripCancel": "BiQ1zG_stripCancel",
858
+ "modalClose": "BiQ1zG_modalClose",
859
+ "confirmIconWrap": "BiQ1zG_confirmIconWrap",
860
+ "toast": "BiQ1zG_toast",
850
861
  "aboutModal": "BiQ1zG_aboutModal",
851
- "hubUpdateNotes": "BiQ1zG_hubUpdateNotes",
862
+ "detailPathText": "BiQ1zG_detailPathText",
863
+ "failBigIssue": "BiQ1zG_failBigIssue",
864
+ "modalTitleQueued": "BiQ1zG_modalTitleQueued",
865
+ "dangerConfirm": "BiQ1zG_dangerConfirm",
866
+ "result": "BiQ1zG_result",
867
+ "failList": "BiQ1zG_failList",
868
+ "modalTitleBusy": "BiQ1zG_modalTitleBusy",
869
+ "detailMono": "BiQ1zG_detailMono",
870
+ "aboutContent": "BiQ1zG_aboutContent",
871
+ "modalRow": "BiQ1zG_modalRow",
872
+ "detailStars": "BiQ1zG_detailStars",
873
+ "queueRowDesc": "BiQ1zG_queueRowDesc",
874
+ "failRow": "BiQ1zG_failRow",
875
+ "aboutMeta": "BiQ1zG_aboutMeta",
852
876
  "noticeList": "BiQ1zG_noticeList",
853
- "failKindUninstall": "BiQ1zG_failKindUninstall",
854
- "errorModal": "BiQ1zG_errorModal",
855
- "detailStatusRunning": "BiQ1zG_detailStatusRunning",
856
- "noticeRowOk": "BiQ1zG_noticeRowOk",
857
- "failCopy": "BiQ1zG_failCopy",
858
- "noticeFoot": "BiQ1zG_noticeFoot",
859
- "modalActions": "BiQ1zG_modalActions",
877
+ "failKind": "BiQ1zG_failKind",
878
+ "noticeTextFail": "BiQ1zG_noticeTextFail",
879
+ "resultCheck": "BiQ1zG_resultCheck",
860
880
  "modalLabel": "BiQ1zG_modalLabel",
861
- "noticeRowMain": "BiQ1zG_noticeRowMain",
862
- "queueRowPct": "BiQ1zG_queueRowPct",
863
- "queueRowTrack": "BiQ1zG_queueRowTrack",
864
- "progressFillFail": "BiQ1zG_progressFillFail",
865
- "detailStars": "BiQ1zG_detailStars",
866
- "queuedHint": "BiQ1zG_queuedHint",
867
- "resultTitle": "BiQ1zG_resultTitle",
868
- "noticeRowUpdate": "BiQ1zG_noticeRowUpdate",
869
- "queueSectionTitle": "BiQ1zG_queueSectionTitle",
870
- "noticeTextOk": "BiQ1zG_noticeTextOk",
871
- "queueRowHead": "BiQ1zG_queueRowHead",
872
881
  "noticeBadgeIcon": "BiQ1zG_noticeBadgeIcon",
882
+ "confirmIconDanger": "BiQ1zG_confirmIconDanger",
883
+ "failClear": "BiQ1zG_failClear",
884
+ "noticeVersion": "BiQ1zG_noticeVersion",
885
+ "hubUpdateModal": "BiQ1zG_hubUpdateModal",
886
+ "noticeFoot": "BiQ1zG_noticeFoot",
887
+ "detailPathBtn": "BiQ1zG_detailPathBtn",
873
888
  "failKindInstall": "BiQ1zG_failKindInstall",
874
- "helpModal": "BiQ1zG_helpModal",
875
- "aboutMeta": "BiQ1zG_aboutMeta",
876
- "detailStatusPending": "BiQ1zG_detailStatusPending",
877
- "modalDesc": "BiQ1zG_modalDesc",
878
- "queueRow": "BiQ1zG_queueRow",
879
- "noticeBadgeFail": "BiQ1zG_noticeBadgeFail",
880
- "cliOnlyHint": "BiQ1zG_cliOnlyHint",
881
- "noticeTime": "BiQ1zG_noticeTime",
882
- "detailPath": "BiQ1zG_detailPath",
883
- "detailMono": "BiQ1zG_detailMono",
884
- "modalTitle": "BiQ1zG_modalTitle",
885
- "confirmPrimary": "BiQ1zG_confirmPrimary",
889
+ "noticeHead": "BiQ1zG_noticeHead",
886
890
  "failHead": "BiQ1zG_failHead",
887
- "modalLink": "BiQ1zG_modalLink",
888
- "progress": "BiQ1zG_progress",
889
- "confirmIconDanger": "BiQ1zG_confirmIconDanger",
890
- "modalCmdCopy": "BiQ1zG_modalCmdCopy",
891
- "resultRestarting": "BiQ1zG_resultRestarting",
892
- "failNetworkTarget": "BiQ1zG_failNetworkTarget"
891
+ "failedCopyHint": "BiQ1zG_failedCopyHint",
892
+ "noticeUpdateGo": "BiQ1zG_noticeUpdateGo"
893
893
  };
894
894
  //#endregion
895
895
  //#region src/server/services/install/release-target.ts
@@ -1001,7 +1001,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
1001
1001
  * tsdown 构建时用 define 把 __PLUGIN_VERSION__ 替换成 package.json 的版本号;
1002
1002
  * node --test 直接 import 本模块时该标识符不存在,typeof 守卫兜底为空串。
1003
1003
  */
1004
- const PLUGIN_VERSION = "1.6.0";
1004
+ const PLUGIN_VERSION = "1.6.1";
1005
1005
  const CATEGORY_ORDER = [
1006
1006
  "interface",
1007
1007
  "session",
@@ -1638,7 +1638,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
1638
1638
  */
1639
1639
  const hubHasUpdate = (() => {
1640
1640
  if (!hubUpdateInfo) return false;
1641
- if (hubUpdateInfo.version === "1.6.0") return false;
1641
+ if (hubUpdateInfo.version === "1.6.1") return false;
1642
1642
  const publishedAt = hubUpdateInfo.publishedAt;
1643
1643
  if (publishedAt) {
1644
1644
  const publishedMs = Date.parse(publishedAt);
@@ -4278,40 +4278,40 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
4278
4278
  css: css$9
4279
4279
  });
4280
4280
  var List_module_css_default = {
4281
- "topic": "_3XaZHa_topic",
4282
4281
  "actions": "_3XaZHa_actions",
4283
- "diagBtn": "_3XaZHa_diagBtn",
4284
- "date": "_3XaZHa_date",
4285
- "installBtnUpdate": "_3XaZHa_installBtnUpdate",
4286
- "installBtnInstalled": "_3XaZHa_installBtnInstalled",
4287
- "cardTitle": "_3XaZHa_cardTitle",
4288
- "fork": "_3XaZHa_fork",
4289
- "retryBtn": "_3XaZHa_retryBtn",
4290
- "desc": "_3XaZHa_desc",
4291
- "state": "_3XaZHa_state",
4292
- "star": "_3XaZHa_star",
4293
- "uninstallBtn": "_3XaZHa_uninstallBtn",
4294
- "footLink": "_3XaZHa_footLink",
4295
- "updateBadge": "_3XaZHa_updateBadge",
4282
+ "detailBtn": "_3XaZHa_detailBtn",
4296
4283
  "versionBadge": "_3XaZHa_versionBadge",
4297
- "footer": "_3XaZHa_footer",
4298
- "list": "_3XaZHa_list",
4299
- "verified": "_3XaZHa_verified",
4284
+ "stateActions": "_3XaZHa_stateActions",
4285
+ "footLink": "_3XaZHa_footLink",
4286
+ "desc": "_3XaZHa_desc",
4287
+ "installBtn": "_3XaZHa_installBtn",
4300
4288
  "stateDesc": "_3XaZHa_stateDesc",
4301
- "cardHead": "_3XaZHa_cardHead",
4302
- "cardMain": "_3XaZHa_cardMain",
4289
+ "installBtnCopied": "_3XaZHa_installBtnCopied",
4290
+ "verified": "_3XaZHa_verified",
4291
+ "date": "_3XaZHa_date",
4292
+ "state": "_3XaZHa_state",
4293
+ "topic": "_3XaZHa_topic",
4303
4294
  "categoryBadge": "_3XaZHa_categoryBadge",
4295
+ "installBtnUpdate": "_3XaZHa_installBtnUpdate",
4304
4296
  "card": "_3XaZHa_card",
4297
+ "cardTitle": "_3XaZHa_cardTitle",
4298
+ "uninstallBtn": "_3XaZHa_uninstallBtn",
4299
+ "list": "_3XaZHa_list",
4300
+ "cardHead": "_3XaZHa_cardHead",
4301
+ "fork": "_3XaZHa_fork",
4302
+ "retryBtn": "_3XaZHa_retryBtn",
4303
+ "diagBtn": "_3XaZHa_diagBtn",
4304
+ "installBtnInstalled": "_3XaZHa_installBtnInstalled",
4305
+ "cardSide": "_3XaZHa_cardSide",
4305
4306
  "stats": "_3XaZHa_stats",
4306
- "installBtn": "_3XaZHa_installBtn",
4307
- "installBtnCopied": "_3XaZHa_installBtnCopied",
4308
- "stateActions": "_3XaZHa_stateActions",
4309
- "detailBtn": "_3XaZHa_detailBtn",
4310
- "stateTitle": "_3XaZHa_stateTitle",
4307
+ "footer": "_3XaZHa_footer",
4311
4308
  "topics": "_3XaZHa_topics",
4312
- "cardSide": "_3XaZHa_cardSide",
4309
+ "updateBadge": "_3XaZHa_updateBadge",
4310
+ "stateTitle": "_3XaZHa_stateTitle",
4311
+ "body": "_3XaZHa_body",
4313
4312
  "moreSentinel": "_3XaZHa_moreSentinel",
4314
- "body": "_3XaZHa_body"
4313
+ "cardMain": "_3XaZHa_cardMain",
4314
+ "star": "_3XaZHa_star"
4315
4315
  };
4316
4316
  //#endregion
4317
4317
  //#region src/client/hooks/useIncrementalList.ts
@@ -4519,14 +4519,14 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
4519
4519
  });
4520
4520
  var SectionTabs_module_css_default = {
4521
4521
  "tab": "_7tvizq_tab",
4522
- "noticeIcon": "_7tvizq_noticeIcon",
4523
- "tabCountActive": "_7tvizq_tabCountActive",
4524
- "root": "_7tvizq_root",
4525
- "noticeCount": "_7tvizq_noticeCount",
4522
+ "tabIcon": "_7tvizq_tabIcon",
4526
4523
  "tabActive": "_7tvizq_tabActive",
4527
- "tabCount": "_7tvizq_tabCount",
4524
+ "tabCountActive": "_7tvizq_tabCountActive",
4528
4525
  "noticeBtn": "_7tvizq_noticeBtn",
4529
- "tabIcon": "_7tvizq_tabIcon"
4526
+ "tabCount": "_7tvizq_tabCount",
4527
+ "root": "_7tvizq_root",
4528
+ "noticeIcon": "_7tvizq_noticeIcon",
4529
+ "noticeCount": "_7tvizq_noticeCount"
4530
4530
  };
4531
4531
  //#endregion
4532
4532
  //#region src/client/components/layout/SectionTabs.tsx
@@ -4603,42 +4603,42 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
4603
4603
  css: css$7
4604
4604
  });
4605
4605
  var InstalledView_module_css_default = {
4606
- "searchInput": "_1nXeGW_searchInput",
4607
- "row": "_1nXeGW_row",
4608
- "rowTitle": "_1nXeGW_rowTitle",
4609
- "rowCategory": "_1nXeGW_rowCategory",
4606
+ "versionBadge": "_1nXeGW_versionBadge",
4610
4607
  "statusPending": "_1nXeGW_statusPending",
4611
- "rowMain": "_1nXeGW_rowMain",
4612
4608
  "rowRestart": "_1nXeGW_rowRestart",
4609
+ "statusDot": "_1nXeGW_statusDot",
4610
+ "statusInactive": "_1nXeGW_statusInactive",
4611
+ "empty": "_1nXeGW_empty",
4612
+ "rowMain": "_1nXeGW_rowMain",
4613
+ "searchInput": "_1nXeGW_searchInput",
4614
+ "root": "_1nXeGW_root",
4613
4615
  "rowDesc": "_1nXeGW_rowDesc",
4614
- "segBtn": "_1nXeGW_segBtn",
4616
+ "segLabel": "_1nXeGW_segLabel",
4617
+ "list": "_1nXeGW_list",
4615
4618
  "rowUpdate": "_1nXeGW_rowUpdate",
4619
+ "segRow": "_1nXeGW_segRow",
4620
+ "segBtn": "_1nXeGW_segBtn",
4621
+ "rowTitleLine": "_1nXeGW_rowTitleLine",
4622
+ "rowTitle": "_1nXeGW_rowTitle",
4623
+ "toolbar": "_1nXeGW_toolbar",
4616
4624
  "emptyTitle": "_1nXeGW_emptyTitle",
4617
- "statusDot": "_1nXeGW_statusDot",
4618
- "rowMeta": "_1nXeGW_rowMeta",
4619
4625
  "rowUninstall": "_1nXeGW_rowUninstall",
4620
- "segRow": "_1nXeGW_segRow",
4621
- "searchWrap": "_1nXeGW_searchWrap",
4622
- "segLabel": "_1nXeGW_segLabel",
4623
- "exampleBadge": "_1nXeGW_exampleBadge",
4624
- "empty": "_1nXeGW_empty",
4626
+ "emptyDesc": "_1nXeGW_emptyDesc",
4625
4627
  "rowRepo": "_1nXeGW_rowRepo",
4626
- "versionBadge": "_1nXeGW_versionBadge",
4627
- "updateBadge": "_1nXeGW_updateBadge",
4628
- "list": "_1nXeGW_list",
4629
- "rowSourceTagManual": "_1nXeGW_rowSourceTagManual",
4628
+ "rowDetail": "_1nXeGW_rowDetail",
4629
+ "rowActions": "_1nXeGW_rowActions",
4630
4630
  "rowSourceTag": "_1nXeGW_rowSourceTag",
4631
- "root": "_1nXeGW_root",
4632
- "segGroup": "_1nXeGW_segGroup",
4633
- "exampleRow": "_1nXeGW_exampleRow",
4634
- "statusInactive": "_1nXeGW_statusInactive",
4635
- "emptyDesc": "_1nXeGW_emptyDesc",
4636
- "rowTitleLine": "_1nXeGW_rowTitleLine",
4631
+ "row": "_1nXeGW_row",
4637
4632
  "segBtnActive": "_1nXeGW_segBtnActive",
4633
+ "exampleBadge": "_1nXeGW_exampleBadge",
4634
+ "rowCategory": "_1nXeGW_rowCategory",
4635
+ "segGroup": "_1nXeGW_segGroup",
4636
+ "rowMeta": "_1nXeGW_rowMeta",
4638
4637
  "rowSourceTagHub": "_1nXeGW_rowSourceTagHub",
4639
- "rowActions": "_1nXeGW_rowActions",
4640
- "rowDetail": "_1nXeGW_rowDetail",
4641
- "toolbar": "_1nXeGW_toolbar"
4638
+ "rowSourceTagManual": "_1nXeGW_rowSourceTagManual",
4639
+ "exampleRow": "_1nXeGW_exampleRow",
4640
+ "searchWrap": "_1nXeGW_searchWrap",
4641
+ "updateBadge": "_1nXeGW_updateBadge"
4642
4642
  };
4643
4643
  //#endregion
4644
4644
  //#region src/client/components/views/InstalledView.tsx
@@ -4884,28 +4884,28 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
4884
4884
  css: css$6
4885
4885
  });
4886
4886
  var CustomInstallView_module_css_default = {
4887
- "helpNote": "zISxCG_helpNote",
4888
- "helpCmd": "zISxCG_helpCmd",
4889
- "installInsertBtn": "zISxCG_installInsertBtn",
4887
+ "channelOffBtn": "zISxCG_channelOffBtn",
4890
4888
  "root": "zISxCG_root",
4891
- "installCard": "zISxCG_installCard",
4889
+ "installCards": "zISxCG_installCards",
4890
+ "channelOff": "zISxCG_channelOff",
4891
+ "channelOffText": "zISxCG_channelOffText",
4892
+ "installError": "zISxCG_installError",
4893
+ "installInput": "zISxCG_installInput",
4894
+ "installRow": "zISxCG_installRow",
4895
+ "installCardDisabled": "zISxCG_installCardDisabled",
4892
4896
  "desc": "zISxCG_desc",
4897
+ "installExample": "zISxCG_installExample",
4898
+ "installCardHead": "zISxCG_installCardHead",
4893
4899
  "installBtn": "zISxCG_installBtn",
4900
+ "helpBody": "zISxCG_helpBody",
4901
+ "helpNote": "zISxCG_helpNote",
4902
+ "helpCmd": "zISxCG_helpCmd",
4903
+ "installHelpBtn": "zISxCG_installHelpBtn",
4894
4904
  "installInputError": "zISxCG_installInputError",
4895
4905
  "helpLine": "zISxCG_helpLine",
4896
- "channelOff": "zISxCG_channelOff",
4906
+ "installCard": "zISxCG_installCard",
4897
4907
  "installLabel": "zISxCG_installLabel",
4898
- "installInput": "zISxCG_installInput",
4899
- "installError": "zISxCG_installError",
4900
- "channelOffText": "zISxCG_channelOffText",
4901
- "channelOffBtn": "zISxCG_channelOffBtn",
4902
- "installHelpBtn": "zISxCG_installHelpBtn",
4903
- "installCardHead": "zISxCG_installCardHead",
4904
- "installCards": "zISxCG_installCards",
4905
- "installExample": "zISxCG_installExample",
4906
- "installRow": "zISxCG_installRow",
4907
- "installCardDisabled": "zISxCG_installCardDisabled",
4908
- "helpBody": "zISxCG_helpBody"
4908
+ "installInsertBtn": "zISxCG_installInsertBtn"
4909
4909
  };
4910
4910
  //#endregion
4911
4911
  //#region src/client/components/views/CustomInstallView.tsx
@@ -5195,30 +5195,30 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
5195
5195
  css: css$5
5196
5196
  });
5197
5197
  var SettingsView_module_css_default = {
5198
- "navItem": "_506LLG_navItem",
5199
- "root": "_506LLG_root",
5200
5198
  "pageHeader": "_506LLG_pageHeader",
5201
- "navItemActive": "_506LLG_navItemActive",
5199
+ "content": "_506LLG_content",
5202
5200
  "pageDesc": "_506LLG_pageDesc",
5203
- "proxyHintOk": "_506LLG_proxyHintOk",
5204
- "resetBtn": "_506LLG_resetBtn",
5201
+ "settingTitle": "_506LLG_settingTitle",
5202
+ "settingControlStack": "_506LLG_settingControlStack",
5203
+ "navItemActive": "_506LLG_navItemActive",
5204
+ "root": "_506LLG_root",
5205
5205
  "sidebar": "_506LLG_sidebar",
5206
- "settingDesc": "_506LLG_settingDesc",
5207
- "content": "_506LLG_content",
5208
- "settingLabel": "_506LLG_settingLabel",
5209
- "card": "_506LLG_card",
5210
- "proxyHintFail": "_506LLG_proxyHintFail",
5211
- "navIcon": "_506LLG_navIcon",
5212
- "pageTitle": "_506LLG_pageTitle",
5206
+ "proxyControl": "_506LLG_proxyControl",
5213
5207
  "settingRow": "_506LLG_settingRow",
5214
- "settingTitle": "_506LLG_settingTitle",
5208
+ "proxyHintFail": "_506LLG_proxyHintFail",
5215
5209
  "controlDropdown": "_506LLG_controlDropdown",
5216
- "settingControlStack": "_506LLG_settingControlStack",
5210
+ "navIcon": "_506LLG_navIcon",
5211
+ "settingDesc": "_506LLG_settingDesc",
5212
+ "navItem": "_506LLG_navItem",
5217
5213
  "proxyHint": "_506LLG_proxyHint",
5218
- "proxyControl": "_506LLG_proxyControl",
5219
5214
  "settingControl": "_506LLG_settingControl",
5220
5215
  "settingRowStack": "_506LLG_settingRowStack",
5221
- "textInput": "_506LLG_textInput"
5216
+ "proxyHintOk": "_506LLG_proxyHintOk",
5217
+ "pageTitle": "_506LLG_pageTitle",
5218
+ "settingLabel": "_506LLG_settingLabel",
5219
+ "card": "_506LLG_card",
5220
+ "textInput": "_506LLG_textInput",
5221
+ "resetBtn": "_506LLG_resetBtn"
5222
5222
  };
5223
5223
  //#endregion
5224
5224
  //#region \0dsh-css:src/client/styles/Dropdown.module.css.mjs
@@ -5237,18 +5237,18 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
5237
5237
  css: css$4
5238
5238
  });
5239
5239
  var Dropdown_module_css_default = {
5240
- "dropdownItem": "B_Gxsq_dropdownItem",
5241
- "dropdownItemActive": "B_Gxsq_dropdownItemActive",
5240
+ "dropdown": "B_Gxsq_dropdown",
5241
+ "dropdownFill": "B_Gxsq_dropdownFill",
5242
+ "dropdownBtn": "B_Gxsq_dropdownBtn",
5242
5243
  "dropdownPanel": "B_Gxsq_dropdownPanel",
5243
- "dropdownArrowOpen": "B_Gxsq_dropdownArrowOpen",
5244
5244
  "dropdownArrow": "B_Gxsq_dropdownArrow",
5245
- "dropdownCountActive": "B_Gxsq_dropdownCountActive",
5246
- "dropdownBtn": "B_Gxsq_dropdownBtn",
5247
- "dropdownFill": "B_Gxsq_dropdownFill",
5248
- "dropdown": "B_Gxsq_dropdown",
5249
5245
  "dropdownLabel": "B_Gxsq_dropdownLabel",
5250
- "dropdownItemLabel": "B_Gxsq_dropdownItemLabel",
5251
- "dropdownCount": "B_Gxsq_dropdownCount"
5246
+ "dropdownItem": "B_Gxsq_dropdownItem",
5247
+ "dropdownCount": "B_Gxsq_dropdownCount",
5248
+ "dropdownCountActive": "B_Gxsq_dropdownCountActive",
5249
+ "dropdownArrowOpen": "B_Gxsq_dropdownArrowOpen",
5250
+ "dropdownItemActive": "B_Gxsq_dropdownItemActive",
5251
+ "dropdownItemLabel": "B_Gxsq_dropdownItemLabel"
5252
5252
  };
5253
5253
  //#endregion
5254
5254
  //#region \0dsh-css:src/client/styles/Toggle.module.css.mjs
@@ -5267,8 +5267,8 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
5267
5267
  css: css$3
5268
5268
  });
5269
5269
  var Toggle_module_css_default = {
5270
- "knob": "k-cD4G_knob",
5271
5270
  "toggleOn": "k-cD4G_toggleOn",
5271
+ "knob": "k-cD4G_knob",
5272
5272
  "toggle": "k-cD4G_toggle"
5273
5273
  };
5274
5274
  //#endregion
@@ -5369,29 +5369,29 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
5369
5369
  css: css$2
5370
5370
  });
5371
5371
  var DiagnosticsView_module_css_default = {
5372
- "name": "k9eRya_name",
5373
- "envLabel": "k9eRya_envLabel",
5374
- "badgeIdle": "k9eRya_badgeIdle",
5375
- "envTitle": "k9eRya_envTitle",
5376
- "panel": "k9eRya_panel",
5377
- "badgeOk": "k9eRya_badgeOk",
5378
5372
  "envDesc": "k9eRya_envDesc",
5373
+ "row": "k9eRya_row",
5374
+ "summaryRunning": "k9eRya_summaryRunning",
5379
5375
  "badgeRunning": "k9eRya_badgeRunning",
5380
- "headHint": "k9eRya_headHint",
5376
+ "envRow": "k9eRya_envRow",
5377
+ "head": "k9eRya_head",
5378
+ "badgeFail": "k9eRya_badgeFail",
5379
+ "summaryOk": "k9eRya_summaryOk",
5380
+ "envLabel": "k9eRya_envLabel",
5381
5381
  "badge": "k9eRya_badge",
5382
- "summaryRunning": "k9eRya_summaryRunning",
5383
- "diagPulse": "k9eRya_diagPulse",
5384
- "summaryFail": "k9eRya_summaryFail",
5385
5382
  "runBtn": "k9eRya_runBtn",
5383
+ "headHint": "k9eRya_headHint",
5384
+ "envTitle": "k9eRya_envTitle",
5385
+ "badgeOk": "k9eRya_badgeOk",
5386
5386
  "meta": "k9eRya_meta",
5387
- "summaryOk": "k9eRya_summaryOk",
5388
- "envCopyBtn": "k9eRya_envCopyBtn",
5389
- "row": "k9eRya_row",
5390
- "envRow": "k9eRya_envRow",
5391
- "display": "k9eRya_display",
5392
- "badgeFail": "k9eRya_badgeFail",
5393
5387
  "summary": "k9eRya_summary",
5394
- "head": "k9eRya_head"
5388
+ "name": "k9eRya_name",
5389
+ "diagPulse": "k9eRya_diagPulse",
5390
+ "summaryFail": "k9eRya_summaryFail",
5391
+ "display": "k9eRya_display",
5392
+ "badgeIdle": "k9eRya_badgeIdle",
5393
+ "panel": "k9eRya_panel",
5394
+ "envCopyBtn": "k9eRya_envCopyBtn"
5395
5395
  };
5396
5396
  //#endregion
5397
5397
  //#region src/client/components/views/DiagnosticsView.tsx
@@ -5569,57 +5569,57 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
5569
5569
  css: css$1
5570
5570
  });
5571
5571
  var LogsView_module_css_default = {
5572
- "badgeDebug": "_3j77BW_badgeDebug",
5573
- "catSystem": "_3j77BW_catSystem",
5574
- "pathLabel": "_3j77BW_pathLabel",
5575
- "headActions": "_3j77BW_headActions",
5576
- "linkBtn": "_3j77BW_linkBtn",
5577
- "catSettings": "_3j77BW_catSettings",
5578
- "time": "_3j77BW_time",
5579
- "message": "_3j77BW_message",
5580
- "badgeError": "_3j77BW_badgeError",
5581
- "headHint": "_3j77BW_headHint",
5582
- "pathDialog": "_3j77BW_pathDialog",
5583
- "searchInput": "_3j77BW_searchInput",
5584
- "empty": "_3j77BW_empty",
5585
- "clearBtn": "_3j77BW_clearBtn",
5586
- "badgeWarn": "_3j77BW_badgeWarn",
5587
- "filterChip": "_3j77BW_filterChip",
5588
- "panel": "_3j77BW_panel",
5589
5572
  "logList": "_3j77BW_logList",
5590
- "pathDialogReset": "_3j77BW_pathDialogReset",
5591
5573
  "footCount": "_3j77BW_footCount",
5592
- "filterBar": "_3j77BW_filterBar",
5593
- "previewRow": "_3j77BW_previewRow",
5594
- "pathText": "_3j77BW_pathText",
5595
- "badgeInfo": "_3j77BW_badgeInfo",
5596
- "pathDialogDesc": "_3j77BW_pathDialogDesc",
5597
- "filterChipActive": "_3j77BW_filterChipActive",
5574
+ "catSettings": "_3j77BW_catSettings",
5575
+ "catInstall": "_3j77BW_catInstall",
5576
+ "headActions": "_3j77BW_headActions",
5577
+ "catUpdate": "_3j77BW_catUpdate",
5598
5578
  "badge": "_3j77BW_badge",
5599
- "actions": "_3j77BW_actions",
5579
+ "pathLabel": "_3j77BW_pathLabel",
5600
5580
  "catBadge": "_3j77BW_catBadge",
5601
- "search": "_3j77BW_search",
5602
- "entry": "_3j77BW_entry",
5581
+ "filterChip": "_3j77BW_filterChip",
5603
5582
  "badgeSuccess": "_3j77BW_badgeSuccess",
5604
- "list": "_3j77BW_list",
5605
- "pathDialogHint": "_3j77BW_pathDialogHint",
5606
- "more": "_3j77BW_more",
5607
- "footPath": "_3j77BW_footPath",
5608
- "catInstall": "_3j77BW_catInstall",
5609
- "catUninstall": "_3j77BW_catUninstall",
5583
+ "pathDialogRow": "_3j77BW_pathDialogRow",
5584
+ "head": "_3j77BW_head",
5610
5585
  "footFail": "_3j77BW_footFail",
5611
- "event": "_3j77BW_event",
5612
- "catUpdate": "_3j77BW_catUpdate",
5586
+ "headHint": "_3j77BW_headHint",
5587
+ "linkBtn": "_3j77BW_linkBtn",
5613
5588
  "pathDraft": "_3j77BW_pathDraft",
5614
- "pathRow": "_3j77BW_pathRow",
5615
- "pathDialogFoot": "_3j77BW_pathDialogFoot",
5589
+ "search": "_3j77BW_search",
5616
5590
  "btn": "_3j77BW_btn",
5591
+ "clearBtn": "_3j77BW_clearBtn",
5592
+ "panel": "_3j77BW_panel",
5593
+ "message": "_3j77BW_message",
5594
+ "more": "_3j77BW_more",
5595
+ "footPath": "_3j77BW_footPath",
5596
+ "pathDialogFoot": "_3j77BW_pathDialogFoot",
5597
+ "badgeWarn": "_3j77BW_badgeWarn",
5598
+ "searchInput": "_3j77BW_searchInput",
5599
+ "badgeInfo": "_3j77BW_badgeInfo",
5600
+ "pathDialog": "_3j77BW_pathDialog",
5601
+ "previewRow": "_3j77BW_previewRow",
5617
5602
  "moreEnd": "_3j77BW_moreEnd",
5618
- "head": "_3j77BW_head",
5619
- "pathDialogRow": "_3j77BW_pathDialogRow",
5620
- "footActions": "_3j77BW_footActions",
5603
+ "pathDialogDesc": "_3j77BW_pathDialogDesc",
5604
+ "pathRow": "_3j77BW_pathRow",
5605
+ "pathText": "_3j77BW_pathText",
5606
+ "catUninstall": "_3j77BW_catUninstall",
5607
+ "pathDialogReset": "_3j77BW_pathDialogReset",
5608
+ "list": "_3j77BW_list",
5609
+ "badgeError": "_3j77BW_badgeError",
5610
+ "entry": "_3j77BW_entry",
5611
+ "actions": "_3j77BW_actions",
5621
5612
  "foot": "_3j77BW_foot",
5622
- "catDiagnostics": "_3j77BW_catDiagnostics"
5613
+ "footActions": "_3j77BW_footActions",
5614
+ "badgeDebug": "_3j77BW_badgeDebug",
5615
+ "catDiagnostics": "_3j77BW_catDiagnostics",
5616
+ "catSystem": "_3j77BW_catSystem",
5617
+ "empty": "_3j77BW_empty",
5618
+ "filterChipActive": "_3j77BW_filterChipActive",
5619
+ "event": "_3j77BW_event",
5620
+ "pathDialogHint": "_3j77BW_pathDialogHint",
5621
+ "filterBar": "_3j77BW_filterBar",
5622
+ "time": "_3j77BW_time"
5623
5623
  };
5624
5624
  //#endregion
5625
5625
  //#region src/client/components/modals/LogsModal.tsx
@@ -6868,7 +6868,7 @@ window.__ModuleLoader__.load({ id: "dsh-plugin", factory: (require) => {
6868
6868
  openSection: settingsSection,
6869
6869
  onConsumedOpenSection: () => setSettingsSection(null)
6870
6870
  }), showHubUpdate && (0, react.createElement)(HubUpdateModal, {
6871
- info: catalog.hubUpdateInfo ?? { version: "1.6.0" },
6871
+ info: catalog.hubUpdateInfo ?? { version: "1.6.1" },
6872
6872
  lang,
6873
6873
  t,
6874
6874
  hasUpdate: catalog.hubHasUpdate,
@@ -13,7 +13,7 @@ import { homedir, release } from 'node:os';
13
13
  import { dirname, join, resolve } from 'node:path';
14
14
  import { spawn, spawnSync } from 'node:child_process';
15
15
  import { fetchViaCurl, gitLsRemote, probeUrl, systemProxy } from '../services/probe.js';
16
- import { activeTask, cancelTask, dumpLoaderEntries, getTask, githubRepoOf, githubTarget, globalNpmPackagesOf, hasQueuedTarget, installTargetOf, listPendingRestarts, readProfileArg, startPluginMutation, validPackageName } from '../services/install/install.js';
16
+ import { activeTask, cancelTask, dumpLoaderEntries, getTask, githubRefOf, githubRepoOf, githubTarget, globalNpmPackagesOf, hasQueuedTarget, installTargetOf, listPendingRestarts, readProfileArg, startPluginMutation, validPackageName } from '../services/install/install.js';
17
17
  import { githubReleaseTarget } from '../services/install/release-target.js';
18
18
  import { recordInstalledVersion, recordResolvedNpmPackage, readInstalledVersions, removeInstalledVersion } from '../services/profile/installed-versions.js';
19
19
  import { isDshNpmPackageForRepo, resolveNpmPackage } from '../services/install/npm-resolve.js';
@@ -808,7 +808,10 @@ export function mountPluginHubRoutes(webServer, profile, loader) {
808
808
  // githubRepoOf 先把各种 GitHub 地址归一成 owner/repo,让「输入地址即装」兼容粘贴完整链接。
809
809
  const gitRepo = githubRepoOf(rawRepo);
810
810
  const release = githubReleaseTarget(rawRepo);
811
- const repoTarget = gitRepo !== null && release === null ? githubTarget(gitRepo) : null;
811
+ // 显式 pin 的 Git ref(`#tag` / `#commit`)是用户意图:保留它,且不让 npm 反查
812
+ // 把这个精确修订换成 registry 上的默认版本(见 issue #130)。
813
+ const pinnedRef = githubRefOf(rawRepo);
814
+ const repoTarget = gitRepo !== null && release === null ? githubTarget(gitRepo, pinnedRef) : null;
812
815
  let target = release?.target ?? repoTarget ?? (validPackageName(rawRepo) ? rawRepo : null);
813
816
  if (target === null) {
814
817
  sendJson(response, 400, { error: 'unsupported install target' });
@@ -848,7 +851,9 @@ export function mountPluginHubRoutes(webServer, profile, loader) {
848
851
  // 通用机制,不针对具体插件。
849
852
  // 反查本身计入「已尝试的安装方式」:组织 scope 与 GitHub 用户名不一致时仅凭
850
853
  // 仓库名猜不到包名,失败提 Issue 时作者看到我们查过的命令就能直接指认正确包名。
851
- if (repoTarget !== null) {
854
+ // 显式 pin 了 Git ref 时跳过 npm 反查:用户要的就是那个精确修订,
855
+ // 不能用 registry 上的默认版本覆盖它(issue #130)。
856
+ if (repoTarget !== null && pinnedRef === null) {
852
857
  // 反查/记录统一用归一化后的 owner/repo(gitRepo),保证「输入完整链接」也走同一套 npm 反查
853
858
  const repoIdentity = gitRepo ?? rawRepo;
854
859
  const npmName = await resolveNpmPackage(repoIdentity, settings.npmRegistry);
@@ -916,7 +921,9 @@ export function mountPluginHubRoutes(webServer, profile, loader) {
916
921
  // (见 issue #71)。握手失败时再用 curl 复核一次主页连通性:只有两者都不通
917
922
  // 才判「网络不通」;仅握手失败(仓库不存在、私有仓库、需要凭据)放行,
918
923
  // 交给后续预检与真实安装给出准确原因。
919
- const gitProbeTarget = repoTarget === null ? null : repoTarget.replace(/^git\+/, '');
924
+ // 探针只握手仓库本身(去掉 git+ 前缀与 #ref 片段):ls-remote 认的是仓库地址,
925
+ // 带 ref 片段会干扰 URL 解析
926
+ const gitProbeTarget = repoTarget === null ? null : repoTarget.replace(/^git\+/, '').replace(/#.*$/, '');
920
927
  let net;
921
928
  if (gitProbeTarget !== null) {
922
929
  net = await gitLsRemote(gitProbeTarget, effectiveProxy, 6000);
@@ -1,4 +1,4 @@
1
1
  export { addPendingRestart, clearPendingRestart, listPendingRestarts } from '../profile/pending-restart.js';
2
2
  export { dumpLoaderEntries, removeLoadedEntry } from '../loader.js';
3
- export { addAllowBuildsKey, githubRepoOf, githubTarget, globalNpmPackagesOf, installTargetOf, parseAllowBuildsKey, readProfileArg, validPackageName } from '../profile/profile.js';
3
+ export { addAllowBuildsKey, githubRefOf, githubRepoOf, githubTarget, globalNpmPackagesOf, installTargetOf, parseAllowBuildsKey, readProfileArg, validPackageName } from '../profile/profile.js';
4
4
  export { activeTask, cancelTask, getTask, hasQueuedTarget, hasRunningTask, runPluginMutation, startPluginMutation } from './task-queue.js';
@@ -17,7 +17,7 @@ import { tmpdir } from 'node:os';
17
17
  import { join } from 'node:path';
18
18
  import { pipeline } from 'node:stream/promises';
19
19
  import { promisify } from 'node:util';
20
- import { githubRepoOf } from '../profile/profile.js';
20
+ import { githubRefOf, githubRepoOf } from '../profile/profile.js';
21
21
  import { githubReleaseTarget } from './release-target.js';
22
22
  import { resolvePackageEntry } from './package-entry.js';
23
23
  const execFileAsync = promisify(execFile);
@@ -33,18 +33,10 @@ export async function preflightTarget(target) {
33
33
  if (source === null)
34
34
  return { ok: true, missing: null, name: null };
35
35
  const [owner, repo] = source.split('/');
36
- let commit = '';
37
- try {
38
- const { stdout } = await execFileAsync('git', ['ls-remote', `https://github.com/${owner}/${repo}.git`, 'HEAD'], {
39
- timeout: PREFLIGHT_TIMEOUT_MS,
40
- maxBuffer: 1024 * 1024,
41
- });
42
- commit = stdout.split(/\s+/)[0] ?? '';
43
- }
44
- catch {
45
- return { ok: true, missing: null, name: null };
46
- }
47
- if (!commit)
36
+ // 显式 pin 的 Git ref 要在它自己的修订上预检:默认分支常是 monorepo 根,与 pin 的发布包
37
+ // 形态不同,拿 HEAD 校验会把完整产物误判成缺入口文件(或反之)。无 pin 时仍查 HEAD。
38
+ const commit = await remoteCommit(owner, repo, githubRefOf(target));
39
+ if (commit === null)
48
40
  return { ok: true, missing: null, name: null };
49
41
  const dir = mkdtempSync(join(tmpdir(), 'dsh-preflight-'));
50
42
  try {
@@ -68,6 +60,29 @@ export async function preflightTarget(target) {
68
60
  rmSync(dir, { recursive: true, force: true });
69
61
  }
70
62
  }
63
+ /**
64
+ * Resolve the commit to inspect: the pinned `ref` when given, otherwise the
65
+ * repository default branch (`HEAD`). A full commit SHA passes through as-is;
66
+ * annotated tags are peeled to their commit. Any git/network failure returns
67
+ * null and the caller falls back to "no preflight".
68
+ */
69
+ async function remoteCommit(owner, repo, ref) {
70
+ if (ref !== null && /^[0-9a-f]{40}$/i.test(ref))
71
+ return ref;
72
+ try {
73
+ const { stdout } = await execFileAsync('git', ['ls-remote', `https://github.com/${owner}/${repo}.git`, ref ?? 'HEAD'], {
74
+ timeout: PREFLIGHT_TIMEOUT_MS,
75
+ maxBuffer: 1024 * 1024,
76
+ });
77
+ const lines = stdout.split(/\r?\n/).filter((line) => line !== '');
78
+ // Annotated tags list the tag object and the peeled commit (`<ref>^{}`): prefer the peel.
79
+ const chosen = lines.find((line) => line.endsWith('^{}')) ?? lines[lines.length - 1];
80
+ return chosen?.split(/\s+/)[0] ?? null;
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
71
86
  function download(url, dest) {
72
87
  return new Promise((resolve, reject) => {
73
88
  const req = get(url, { timeout: PREFLIGHT_TIMEOUT_MS }, (res) => {
@@ -50,11 +50,39 @@ export function profileFromArgv(argv, fallback = 'web') {
50
50
  export function profileDirectory(profile) {
51
51
  return join(process.env.DSH_HOME ?? join(homedir(), '.dsh'), 'profiles', profile);
52
52
  }
53
- /** Build a safe explicit HTTPS Git target, or null when the repo is unsafe. */
54
- export function githubTarget(repo) {
53
+ /** Build a safe explicit HTTPS Git target, or null when the repo is unsafe.
54
+ * When `ref` is given it is appended as a Git ref (`#tag` / `#commit`) so an
55
+ * explicitly pinned revision reaches the installer instead of being dropped. */
56
+ export function githubTarget(repo, ref) {
55
57
  if (typeof repo !== 'string' || !REPO_RE.test(repo))
56
58
  return null;
57
- return `git+https://github.com/${repo}.git`;
59
+ const url = `git+https://github.com/${repo}.git`;
60
+ return ref === undefined || ref === null || ref === '' ? url : `${url}#${ref}`;
61
+ }
62
+ /**
63
+ * Extract a validated explicit Git ref (`#<ref>`) from a GitHub spec, or null.
64
+ * Only the fragment of a Git-style address qualifies — a pinned tag/commit is
65
+ * user intent and must survive target normalization, whereas `#…` on a plain
66
+ * web URL (`https://github.com/o/r#readme`) is a page anchor, not a ref.
67
+ * Git-style = `git+…` / `github:` / `git@…` / `…​.git` / bare `owner/repo`.
68
+ * Grammar mirrors a Git ref: no leading `.`/`-`, no `#`/whitespace.
69
+ */
70
+ const GIT_REF_RE = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;
71
+ export function githubRefOf(value) {
72
+ if (typeof value !== 'string')
73
+ return null;
74
+ const input = value.trim();
75
+ const hash = input.indexOf('#');
76
+ if (hash <= 0)
77
+ return null;
78
+ const base = input.slice(0, hash);
79
+ if (githubRepoOf(base) === null)
80
+ return null;
81
+ const gitStyle = /^(?:git\+|github:|git@)/i.test(base) || /\.git$/i.test(base) || !base.includes('://');
82
+ if (!gitStyle)
83
+ return null;
84
+ const ref = input.slice(hash + 1);
85
+ return GIT_REF_RE.test(ref) ? ref : null;
58
86
  }
59
87
  /**
60
88
  * DSH 命令行前缀(官方唯一形式 `dsh plugin --profile <name> <add|update> <target>`)—— 提取其中的安装目标;
@@ -18,5 +18,5 @@ export type { InstallResult, InstallTask, Invocation, PendingRestart, QueueItem
18
18
  export type { LoaderHandle } from '../loader.ts';
19
19
  export { addPendingRestart, clearPendingRestart, listPendingRestarts } from '../profile/pending-restart.ts';
20
20
  export { dumpLoaderEntries, removeLoadedEntry } from '../loader.ts';
21
- export { addAllowBuildsKey, githubRepoOf, githubTarget, globalNpmPackagesOf, installTargetOf, parseAllowBuildsKey, readProfileArg, validPackageName } from '../profile/profile.ts';
21
+ export { addAllowBuildsKey, githubRefOf, githubRepoOf, githubTarget, globalNpmPackagesOf, installTargetOf, parseAllowBuildsKey, readProfileArg, validPackageName } from '../profile/profile.ts';
22
22
  export { activeTask, cancelTask, getTask, hasQueuedTarget, hasRunningTask, runPluginMutation, startPluginMutation } from './task-queue.ts';
@@ -12,8 +12,11 @@ export declare function readProfileArg(fallback?: string): string;
12
12
  export declare function profileFromArgv(argv: readonly string[], fallback?: string): string;
13
13
  /** Resolve a profile directory (`DSH_HOME` or `~/.dsh`). */
14
14
  export declare function profileDirectory(profile: string): string;
15
- /** Build a safe explicit HTTPS Git target, or null when the repo is unsafe. */
16
- export declare function githubTarget(repo: string): string | null;
15
+ /** Build a safe explicit HTTPS Git target, or null when the repo is unsafe.
16
+ * When `ref` is given it is appended as a Git ref (`#tag` / `#commit`) so an
17
+ * explicitly pinned revision reaches the installer instead of being dropped. */
18
+ export declare function githubTarget(repo: string, ref?: string | null): string | null;
19
+ export declare function githubRefOf(value: string): string | null;
17
20
  export declare function installTargetOf(value: string): string;
18
21
  export declare function globalNpmPackagesOf(value: string): string[] | null;
19
22
  /** Extract an owner/repo identity from a catalog value or an installed Git spec. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "A community plugin marketplace for DeepSeek Harness, built to the official plugin spec — browse, search and install 10000+ human-curated community plugins without leaving the app. · DeepSeek Harness 社区插件市场(遵循官方开发规范):10000+ 人工精选社区插件,每日更新。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -14,7 +14,7 @@ import { homedir, release } from 'node:os'
14
14
  import { dirname, join, resolve } from 'node:path'
15
15
  import { spawn, spawnSync } from 'node:child_process'
16
16
  import { fetchViaCurl, gitLsRemote, probeUrl, systemProxy } from '../services/probe.ts'
17
- import { activeTask, cancelTask, dumpLoaderEntries, getTask, githubRepoOf, githubTarget, globalNpmPackagesOf, hasQueuedTarget, installTargetOf, listPendingRestarts, readProfileArg, startPluginMutation, validPackageName, type LoaderHandle } from '../services/install/install.ts'
17
+ import { activeTask, cancelTask, dumpLoaderEntries, getTask, githubRefOf, githubRepoOf, githubTarget, globalNpmPackagesOf, hasQueuedTarget, installTargetOf, listPendingRestarts, readProfileArg, startPluginMutation, validPackageName, type LoaderHandle } from '../services/install/install.ts'
18
18
  import { githubReleaseTarget } from '../services/install/release-target.ts'
19
19
  import { recordInstalledVersion, recordResolvedNpmPackage, readInstalledVersions, removeInstalledVersion } from '../services/profile/installed-versions.ts'
20
20
  import { isDshNpmPackageForRepo, resolveNpmPackage } from '../services/install/npm-resolve.ts'
@@ -798,7 +798,10 @@ export function mountPluginHubRoutes(webServer: WebServerService, profile: strin
798
798
  // githubRepoOf 先把各种 GitHub 地址归一成 owner/repo,让「输入地址即装」兼容粘贴完整链接。
799
799
  const gitRepo = githubRepoOf(rawRepo)
800
800
  const release = githubReleaseTarget(rawRepo)
801
- const repoTarget = gitRepo !== null && release === null ? githubTarget(gitRepo) : null
801
+ // 显式 pin 的 Git ref(`#tag` / `#commit`)是用户意图:保留它,且不让 npm 反查
802
+ // 把这个精确修订换成 registry 上的默认版本(见 issue #130)。
803
+ const pinnedRef = githubRefOf(rawRepo)
804
+ const repoTarget = gitRepo !== null && release === null ? githubTarget(gitRepo, pinnedRef) : null
802
805
  let target: string | null = release?.target ?? repoTarget ?? (validPackageName(rawRepo) ? rawRepo : null)
803
806
  if (target === null) {
804
807
  sendJson(response, 400, { error: 'unsupported install target' })
@@ -837,7 +840,9 @@ export function mountPluginHubRoutes(webServer: WebServerService, profile: strin
837
840
  // 通用机制,不针对具体插件。
838
841
  // 反查本身计入「已尝试的安装方式」:组织 scope 与 GitHub 用户名不一致时仅凭
839
842
  // 仓库名猜不到包名,失败提 Issue 时作者看到我们查过的命令就能直接指认正确包名。
840
- if (repoTarget !== null) {
843
+ // 显式 pin 了 Git ref 时跳过 npm 反查:用户要的就是那个精确修订,
844
+ // 不能用 registry 上的默认版本覆盖它(issue #130)。
845
+ if (repoTarget !== null && pinnedRef === null) {
841
846
  // 反查/记录统一用归一化后的 owner/repo(gitRepo),保证「输入完整链接」也走同一套 npm 反查
842
847
  const repoIdentity = gitRepo ?? rawRepo
843
848
  const npmName = await resolveNpmPackage(repoIdentity, settings.npmRegistry)
@@ -904,7 +909,9 @@ export function mountPluginHubRoutes(webServer: WebServerService, profile: strin
904
909
  // (见 issue #71)。握手失败时再用 curl 复核一次主页连通性:只有两者都不通
905
910
  // 才判「网络不通」;仅握手失败(仓库不存在、私有仓库、需要凭据)放行,
906
911
  // 交给后续预检与真实安装给出准确原因。
907
- const gitProbeTarget = repoTarget === null ? null : repoTarget.replace(/^git\+/, '')
912
+ // 探针只握手仓库本身(去掉 git+ 前缀与 #ref 片段):ls-remote 认的是仓库地址,
913
+ // 带 ref 片段会干扰 URL 解析
914
+ const gitProbeTarget = repoTarget === null ? null : repoTarget.replace(/^git\+/, '').replace(/#.*$/, '')
908
915
  let net: Awaited<ReturnType<typeof probeUrl>>
909
916
  if (gitProbeTarget !== null) {
910
917
  net = await gitLsRemote(gitProbeTarget, effectiveProxy, 6000)
@@ -18,5 +18,5 @@ export type { InstallResult, InstallTask, Invocation, PendingRestart, QueueItem
18
18
  export type { LoaderHandle } from '../loader.ts'
19
19
  export { addPendingRestart, clearPendingRestart, listPendingRestarts } from '../profile/pending-restart.ts'
20
20
  export { dumpLoaderEntries, removeLoadedEntry } from '../loader.ts'
21
- export { addAllowBuildsKey, githubRepoOf, githubTarget, globalNpmPackagesOf, installTargetOf, parseAllowBuildsKey, readProfileArg, validPackageName } from '../profile/profile.ts'
21
+ export { addAllowBuildsKey, githubRefOf, githubRepoOf, githubTarget, globalNpmPackagesOf, installTargetOf, parseAllowBuildsKey, readProfileArg, validPackageName } from '../profile/profile.ts'
22
22
  export { activeTask, cancelTask, getTask, hasQueuedTarget, hasRunningTask, runPluginMutation, startPluginMutation } from './task-queue.ts'
@@ -17,7 +17,7 @@ import { tmpdir } from 'node:os'
17
17
  import { join } from 'node:path'
18
18
  import { pipeline } from 'node:stream/promises'
19
19
  import { promisify } from 'node:util'
20
- import { githubRepoOf } from '../profile/profile.ts'
20
+ import { githubRefOf, githubRepoOf } from '../profile/profile.ts'
21
21
  import { githubReleaseTarget } from './release-target.ts'
22
22
  import { resolvePackageEntry } from './package-entry.ts'
23
23
 
@@ -44,17 +44,10 @@ export async function preflightTarget(target: string): Promise<PreflightResult>
44
44
  const source = githubRepoOf(target)
45
45
  if (source === null) return { ok: true, missing: null, name: null }
46
46
  const [owner, repo] = source.split('/')
47
- let commit = ''
48
- try {
49
- const { stdout } = await execFileAsync('git', ['ls-remote', `https://github.com/${owner}/${repo}.git`, 'HEAD'], {
50
- timeout: PREFLIGHT_TIMEOUT_MS,
51
- maxBuffer: 1024 * 1024,
52
- })
53
- commit = stdout.split(/\s+/)[0] ?? ''
54
- } catch {
55
- return { ok: true, missing: null, name: null }
56
- }
57
- if (!commit) return { ok: true, missing: null, name: null }
47
+ // 显式 pin 的 Git ref 要在它自己的修订上预检:默认分支常是 monorepo 根,与 pin 的发布包
48
+ // 形态不同,拿 HEAD 校验会把完整产物误判成缺入口文件(或反之)。无 pin 时仍查 HEAD。
49
+ const commit = await remoteCommit(owner, repo, githubRefOf(target))
50
+ if (commit === null) return { ok: true, missing: null, name: null }
58
51
  const dir = mkdtempSync(join(tmpdir(), 'dsh-preflight-'))
59
52
  try {
60
53
  const tar = join(dir, 'pkg.tar.gz')
@@ -74,6 +67,28 @@ export async function preflightTarget(target: string): Promise<PreflightResult>
74
67
  }
75
68
  }
76
69
 
70
+ /**
71
+ * Resolve the commit to inspect: the pinned `ref` when given, otherwise the
72
+ * repository default branch (`HEAD`). A full commit SHA passes through as-is;
73
+ * annotated tags are peeled to their commit. Any git/network failure returns
74
+ * null and the caller falls back to "no preflight".
75
+ */
76
+ async function remoteCommit(owner: string, repo: string, ref: string | null): Promise<string | null> {
77
+ if (ref !== null && /^[0-9a-f]{40}$/i.test(ref)) return ref
78
+ try {
79
+ const { stdout } = await execFileAsync('git', ['ls-remote', `https://github.com/${owner}/${repo}.git`, ref ?? 'HEAD'], {
80
+ timeout: PREFLIGHT_TIMEOUT_MS,
81
+ maxBuffer: 1024 * 1024,
82
+ })
83
+ const lines = stdout.split(/\r?\n/).filter((line) => line !== '')
84
+ // Annotated tags list the tag object and the peeled commit (`<ref>^{}`): prefer the peel.
85
+ const chosen = lines.find((line) => line.endsWith('^{}')) ?? lines[lines.length - 1]
86
+ return chosen?.split(/\s+/)[0] ?? null
87
+ } catch {
88
+ return null
89
+ }
90
+ }
91
+
77
92
  function download(url: string, dest: string): Promise<void> {
78
93
  return new Promise((resolve, reject) => {
79
94
  const req = get(url, { timeout: PREFLIGHT_TIMEOUT_MS }, (res) => {
@@ -49,10 +49,36 @@ export function profileDirectory(profile: string): string {
49
49
  return join(process.env.DSH_HOME ?? join(homedir(), '.dsh'), 'profiles', profile)
50
50
  }
51
51
 
52
- /** Build a safe explicit HTTPS Git target, or null when the repo is unsafe. */
53
- export function githubTarget(repo: string): string | null {
52
+ /** Build a safe explicit HTTPS Git target, or null when the repo is unsafe.
53
+ * When `ref` is given it is appended as a Git ref (`#tag` / `#commit`) so an
54
+ * explicitly pinned revision reaches the installer instead of being dropped. */
55
+ export function githubTarget(repo: string, ref?: string | null): string | null {
54
56
  if (typeof repo !== 'string' || !REPO_RE.test(repo)) return null
55
- return `git+https://github.com/${repo}.git`
57
+ const url = `git+https://github.com/${repo}.git`
58
+ return ref === undefined || ref === null || ref === '' ? url : `${url}#${ref}`
59
+ }
60
+
61
+ /**
62
+ * Extract a validated explicit Git ref (`#<ref>`) from a GitHub spec, or null.
63
+ * Only the fragment of a Git-style address qualifies — a pinned tag/commit is
64
+ * user intent and must survive target normalization, whereas `#…` on a plain
65
+ * web URL (`https://github.com/o/r#readme`) is a page anchor, not a ref.
66
+ * Git-style = `git+…` / `github:` / `git@…` / `…​.git` / bare `owner/repo`.
67
+ * Grammar mirrors a Git ref: no leading `.`/`-`, no `#`/whitespace.
68
+ */
69
+ const GIT_REF_RE = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/
70
+
71
+ export function githubRefOf(value: string): string | null {
72
+ if (typeof value !== 'string') return null
73
+ const input = value.trim()
74
+ const hash = input.indexOf('#')
75
+ if (hash <= 0) return null
76
+ const base = input.slice(0, hash)
77
+ if (githubRepoOf(base) === null) return null
78
+ const gitStyle = /^(?:git\+|github:|git@)/i.test(base) || /\.git$/i.test(base) || !base.includes('://')
79
+ if (!gitStyle) return null
80
+ const ref = input.slice(hash + 1)
81
+ return GIT_REF_RE.test(ref) ? ref : null
56
82
  }
57
83
 
58
84
  /**