dsh-plugin 1.6.11 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.en.md +1 -1
  2. package/README.md +1 -1
  3. package/client/client.js +705 -803
  4. package/client/client.js.map +1 -1
  5. package/lib/http/catalog.js +2 -3
  6. package/lib/http/diagnostics.js +6 -7
  7. package/lib/http/install.js +47 -213
  8. package/lib/http/logs.js +1 -2
  9. package/lib/http/npm-release-age.js +42 -0
  10. package/lib/http/routes.js +8 -7
  11. package/lib/http/settings.js +2 -2
  12. package/lib/http/shared.js +2 -2
  13. package/lib/http/task.js +1 -2
  14. package/lib/index.js +5 -6
  15. package/lib/services/install/install-types.js +4 -4
  16. package/lib/services/install/install.js +1 -1
  17. package/lib/services/install/npm-check.js +3 -2
  18. package/lib/services/install/npm-resolve.js +9 -96
  19. package/lib/services/install/package-entry.js +6 -11
  20. package/lib/services/install/registry-check.js +5 -16
  21. package/lib/services/install/release-target.js +8 -9
  22. package/lib/services/install/task-queue.js +74 -57
  23. package/lib/services/npm-release-age.js +119 -0
  24. package/lib/services/probe.js +4 -4
  25. package/lib/services/profile/installed-versions.js +15 -21
  26. package/lib/services/profile/profile.js +16 -44
  27. package/lib/services/profile/progress.js +8 -11
  28. package/lib/services/settings.js +2 -5
  29. package/lib/types/http/catalog.d.ts +1 -1
  30. package/lib/types/http/install.d.ts +2 -2
  31. package/lib/types/http/npm-release-age.d.ts +2 -0
  32. package/lib/types/http/routes.d.ts +10 -12
  33. package/lib/types/http/shared.d.ts +5 -6
  34. package/lib/types/index.d.ts +7 -8
  35. package/lib/types/services/install/install-types.d.ts +12 -13
  36. package/lib/types/services/install/install.d.ts +1 -1
  37. package/lib/types/services/install/npm-resolve.d.ts +4 -16
  38. package/lib/types/services/install/package-entry.d.ts +6 -11
  39. package/lib/types/services/install/release-target.d.ts +7 -8
  40. package/lib/types/services/install/task-queue.d.ts +32 -31
  41. package/lib/types/services/npm-release-age.d.ts +15 -0
  42. package/lib/types/services/probe.d.ts +4 -4
  43. package/lib/types/services/profile/installed-versions.d.ts +5 -7
  44. package/lib/types/services/profile/profile.d.ts +14 -18
  45. package/lib/types/services/profile/progress.d.ts +7 -10
  46. package/lib/types/services/settings.d.ts +0 -4
  47. package/package.json +1 -1
  48. package/src/client/components/PluginHubSection.tsx +23 -27
  49. package/src/client/components/catalog/CatalogList.tsx +2 -4
  50. package/src/client/components/catalog/PluginCard.tsx +2 -3
  51. package/src/client/components/layout/CatalogControls.tsx +5 -6
  52. package/src/client/components/layout/CatalogHeader.tsx +1 -2
  53. package/src/client/components/layout/CategoryTabs.tsx +2 -3
  54. package/src/client/components/layout/SectionTabs.tsx +3 -5
  55. package/src/client/components/modals/ConfirmDialog.tsx +4 -6
  56. package/src/client/components/modals/InstalledDetailModal.tsx +3 -6
  57. package/src/client/components/modals/LogsModal.tsx +7 -12
  58. package/src/client/components/modals/NotificationsModal.tsx +52 -24
  59. package/src/client/components/modals/ProgressView.tsx +3 -4
  60. package/src/client/components/modals/modals.tsx +58 -30
  61. package/src/client/components/ui/Dropdown.tsx +4 -6
  62. package/src/client/components/ui/Toggle.tsx +2 -3
  63. package/src/client/components/ui/icons.tsx +1 -2
  64. package/src/client/components/views/CustomInstallView.tsx +20 -178
  65. package/src/client/components/views/DiagnosticsView.tsx +3 -6
  66. package/src/client/components/views/InstalledView.tsx +6 -11
  67. package/src/client/components/views/MarketView.tsx +2 -4
  68. package/src/client/components/views/SettingsView.tsx +9 -32
  69. package/src/client/css-modules.d.ts +1 -1
  70. package/src/client/data/catalog.ts +2 -3
  71. package/src/client/data/host.ts +26 -3
  72. package/src/client/data/hub.ts +2 -3
  73. package/src/client/hooks/useCatalog.ts +79 -24
  74. package/src/client/hooks/useIncrementalList.ts +3 -5
  75. package/src/client/hooks/useLanguage.ts +4 -6
  76. package/src/client/hooks/useSettings.ts +4 -11
  77. package/src/client/hooks/useTaskQueue.ts +36 -42
  78. package/src/client/index.tsx +2 -3
  79. package/src/client/locales.ts +96 -123
  80. package/src/client/logic/constants.ts +1 -2
  81. package/src/client/logic/ensure-plugin-css.ts +8 -12
  82. package/src/client/logic/failures.ts +41 -28
  83. package/src/client/logic/format.ts +1 -1
  84. package/src/client/logic/install-command.ts +14 -35
  85. package/src/client/logic/installed.ts +15 -10
  86. package/src/client/logic/normalize.ts +3 -3
  87. package/src/client/logic/release-age.ts +19 -0
  88. package/src/client/logic/urls.ts +55 -50
  89. package/src/client/styles/CustomInstallView.module.css +3 -30
  90. package/src/client/styles/DiagnosticsView.module.css +3 -5
  91. package/src/client/styles/Dropdown.module.css +2 -4
  92. package/src/client/styles/Header.module.css +6 -7
  93. package/src/client/styles/InstalledView.module.css +4 -7
  94. package/src/client/styles/List.module.css +4 -5
  95. package/src/client/styles/LogsView.module.css +2 -3
  96. package/src/client/styles/Modal.module.css +4 -5
  97. package/src/client/styles/SectionTabs.module.css +2 -4
  98. package/src/client/styles/SettingsView.module.css +3 -5
  99. package/src/client/styles/Toggle.module.css +2 -4
  100. package/src/client/styles/tokens.module.css +14 -18
  101. package/src/client/types.ts +11 -11
  102. package/src/server/http/catalog.ts +2 -3
  103. package/src/server/http/diagnostics.ts +6 -7
  104. package/src/server/http/install.ts +47 -208
  105. package/src/server/http/logs.ts +1 -2
  106. package/src/server/http/npm-release-age.ts +42 -0
  107. package/src/server/http/routes.ts +12 -12
  108. package/src/server/http/settings.ts +2 -2
  109. package/src/server/http/shared.ts +5 -6
  110. package/src/server/http/task.ts +1 -2
  111. package/src/server/index.ts +7 -8
  112. package/src/server/services/install/install-types.ts +12 -13
  113. package/src/server/services/install/install.ts +0 -1
  114. package/src/server/services/install/npm-check.ts +3 -2
  115. package/src/server/services/install/npm-resolve.ts +9 -99
  116. package/src/server/services/install/package-entry.ts +6 -11
  117. package/src/server/services/install/registry-check.ts +5 -16
  118. package/src/server/services/install/release-target.ts +8 -9
  119. package/src/server/services/install/task-queue.ts +79 -63
  120. package/src/server/services/npm-release-age.ts +107 -0
  121. package/src/server/services/probe.ts +4 -4
  122. package/src/server/services/profile/installed-versions.ts +16 -22
  123. package/src/server/services/profile/profile.ts +16 -42
  124. package/src/server/services/profile/progress.ts +8 -11
  125. package/src/server/services/settings.ts +2 -9
  126. package/lib/services/install/preflight.js +0 -178
  127. package/lib/types/services/install/preflight.d.ts +0 -23
  128. package/src/server/services/install/preflight.ts +0 -184
@@ -3,7 +3,7 @@
3
3
  * Website: https://dsh-plugin.org
4
4
  * GitHub: https://github.com/dshplugin/dsh-plugin-hub
5
5
  *
6
- * zh/en dictionaries for the DSH Plugin Hub settings section.
6
+ * 插件中心设置板块的 zh/en 字典。
7
7
  */
8
8
  export const zh = {
9
9
  nav: '插件市场',
@@ -47,39 +47,26 @@ export const zh = {
47
47
  viewSettings: '设置',
48
48
  viewMarketHint: '浏览与发现插件',
49
49
  viewInstalledHint: '管理已安装插件',
50
- viewCustomHint: '手动安装 NPM 包或 GitHub 源码',
50
+ viewCustomHint: '手动安装 NPM 包',
51
51
  viewSettingsHint: '网络通道与偏好设置',
52
52
  // 已安装视图
53
53
  installedEmpty: '还没有安装插件',
54
- installedEmptyDesc: '可以去「自定义安装」,手动安装 NPM 包或 GitHub 源码',
54
+ installedEmptyDesc: '可以去「自定义安装」,手动安装 NPM 包',
55
55
  npmInstallLabel: 'NPM 包 / 命令',
56
56
  npmInstallPlaceholder: 'npm install <包名> 或直接输包名',
57
57
  npmInstallExample: '支持原生命令:npm install lodash、npm i lodash、pnpm add @scope/pkg',
58
58
  npmInstallExample2: '全局安装 CLI:npm install -g @scope/cli;或直接输入包名 lodash',
59
59
  npmInstallInvalid: '请输入 npm 包名(如 lodash、@scope/pkg),或原生安装命令(如 npm install lodash、npm i lodash、pnpm add @scope/pkg、npm install -g @scope/cli)',
60
- gitInstallLabel: 'GitHub 源码',
61
- gitInstallPlaceholder: '输入仓库地址',
62
- gitInstallExample: '例如:owner/repo 或 https://github.com/owner/repo',
63
- gitInstallInvalid: '请输入 GitHub 仓库地址,例如:owner/repo 或 https://github.com/owner/repo',
64
- dshCmdLabel: 'DeepSeek Harness 命令',
65
- dshCmdPlaceholder: '粘贴官方 dsh plugin 命令',
66
- dshCmdInsertHubUpdate: '插入更新命令',
67
- // 示例/校验文案里的 profile 用运行时当前宿主 profile 渲染({profile} 占位符),
68
- // 不写死 web —— 桌面端当前 profile 是 desktop,照抄写死的 web 会装进宿主永不加载的档
69
- dshCmdExample: '例如:dsh plugin --profile {profile} add github:owner/repo,或 dsh plugin --profile {profile} update dsh-plugin',
70
- dshCmdInvalid: '请输入官方 dsh plugin 命令(--profile 必填,支持 add / update)。例如:dsh plugin --profile {profile} update dsh-plugin',
71
60
  installHelp: '帮助',
72
61
  helpModalTitle: '支持的命令格式',
73
62
  npmInstallHelp: 'lodash、@scope/pkg\t直接输入包名\nnpm install lodash\nnpm i lodash\npnpm add @scope/pkg\npnpm i @scope/pkg\nnpm install -g @scope/cli\t全局安装 CLI 工具,不进「已安装」列表',
74
- gitInstallHelp: 'owner/repo\nhttps://github.com/owner/repo\ngithub:owner/repo\ngit+https://github.com/owner/repo.git\ngit@github.com:owner/repo.git',
75
- dshCmdHelp: 'dsh plugin --profile {profile} add <目标>\t安装\ndsh plugin --profile {profile} update <目标>\t更新已安装目标到最新版本\ndsh plugin --profile={profile} add <目标>\ndsh plugin --profile={profile} update <目标>\n\t--profile 必填(此处已填当前 profile),官方 CLI 无 -p 简写;<目标> 可为 npm 包名或 github:owner/repo;卸载请用「已安装」列表',
76
63
  globalNpmHint: '将全局安装 CLI 工具(npm install -g),不会出现在「已安装」列表,无需重启宿主',
77
64
  installCliBtn: '安装',
78
65
  // 安装通道关闭(安全信任开关关掉后,对应卡片禁用并引导去设置打开)
79
66
  channelDisabledHint: '该安装通道已关闭,请在「设置 → 安全信任」中打开开关',
80
67
  goToSettings: '前往设置',
81
68
  // 自定义安装视图:独立一级导航,说明文字
82
- customViewDesc: '手动安装目录外的 NPM 包、GitHub 源码,或粘贴官方 dsh plugin 命令。装完的条目会出现在「已安装」列表,并标记为自定义安装。',
69
+ customViewDesc: '手动安装目录外的 NPM 包。装完的条目会出现在「已安装」列表,并标记为自定义安装。',
83
70
  customLabel: '自定义安装',
84
71
  installedSearch: '搜索已安装的插件…',
85
72
  installedFilterCatalog: '目录插件',
@@ -134,13 +121,9 @@ export const zh = {
134
121
  mirrorTencent: '腾讯云镜像',
135
122
  mirrorTsinghua: '清华大学 TUNA 镜像',
136
123
  settingsSecurity: '安全信任',
137
- settingsSecurityDesc: '命令行安装的三个通道开关:NPM 包、GitHub 源码与 DSH 命令',
124
+ settingsSecurityDesc: '命令行安装的开关:NPM 包',
138
125
  settingsEnableNpm: '启用 NPM 安装',
139
126
  settingsEnableNpmDesc: '允许通过命令行安装 npm 包;关闭后输入包名安装会被拦截',
140
- settingsEnableGit: '启用 GitHub 源码安装',
141
- settingsEnableGitDesc: '允许通过命令行安装 GitHub 源码;关闭后输入仓库地址安装会被拦截',
142
- settingsEnableDsh: '启用 DSH 命令安装',
143
- settingsEnableDshDesc: '允许通过命令行粘贴 dsh plugin 命令安装;关闭后命令输入会被禁用',
144
127
  settingsDiagnostics: '系统诊断',
145
128
  settingsDiagnosticsDesc: '检测 npm 源 / GitHub / 目录站点等安装通道的连通状态',
146
129
  settingsLogs: '系统日志',
@@ -308,6 +291,10 @@ export const zh = {
308
291
  errorTitleUninstall: '卸载失败',
309
292
  // 更新失败(通知中心区分安装/更新):更新目标覆盖重装失败,与首次安装失败不同语义
310
293
  errorTitleUpdate: '更新失败',
294
+ // 动作词:失败提示与上报正文统一取词,不写死「安装」
295
+ actionInstall: '安装',
296
+ actionUpdate: '更新',
297
+ actionUninstall: '卸载',
311
298
  errorPlugin: '插件',
312
299
  errorClose: '知道了',
313
300
  errorCopy: '复制错误信息',
@@ -315,31 +302,34 @@ export const zh = {
315
302
  failCopy: '复制完整错误信息',
316
303
  failIssueHint: '带着错误日志去作者仓库一键提交 Issue(正文含官网收录链接)',
317
304
  failIssueBig: '一键提交 BUG 到 GitHub Issue 为开源作贡献',
318
- // 非插件侧失败(未知原因 / pnpm allowBuilds 拦截)改为引导到插件中心仓库排查
305
+ // 非插件侧失败(未知原因)改为引导到插件中心仓库排查
319
306
  failHubIssueHint: '此失败已被判定为环境或插件中心自身问题(非插件作者问题),带着错误日志到插件中心仓库一键提交 Issue',
320
307
  failHubIssueBig: '反馈给插件中心排查',
321
308
  // 未知失败兜底:不归到插件作者,引导到插件中心仓库排查
322
- failUnclassifiedHint: '安装失败,原因未能自动识别。这通常不是插件自身的问题(可能与本机环境或插件中心有关),请将错误信息反馈给插件中心,由维护者排查。',
309
+ failUnclassifiedHint: '{action}失败,原因未能自动识别。这通常不是插件自身的问题(可能与本机环境或插件中心有关),请将错误信息反馈给插件中心,由维护者排查。',
323
310
  // 插件中心自身状态类消息(插件未安装 / 不在此处卸载 / 已在队列中):已安装列表与实读快照不同步,非插件问题,不引导提 Issue
324
- failHubStateHint: '插件列表状态已过期或与本地不一致:该插件可能已经装过了(无需重复安装,要升级请点「更新」),也可能已不在已安装列表中,或已在队列中。这不是插件本身的问题 —— 请刷新页面后重试。',
325
- // 安装命令超时被强杀:可能其实已装成功(安装器超时后会先核对已安装列表),给可行动提示,不引导提 Issue
326
- failTimeoutHint: '安装耗时超过本地上限、已被中断 —— 但很可能其实已经装上了(安装器在超时后会先核对本地已安装列表)。请刷新页面确认该插件是否已装上;若确实没装上,可在终端手动执行一次安装命令查看完整输出。这不是插件本身的问题。',
327
- failProfileLockHint: 'DSH 在写入插件清单时等不到文件锁、超时中止 —— 通常是同时有另一个 DSH 进程或安装任务在写同一个 profile(也可能是上一次的进程没退干净留下的锁)。请先关掉其他 dsh 窗口或正在跑的命令,再重试一次;若反复出现,重启一次 DSH。这不是插件本身的问题,也不需要重复安装。',
328
- // prepare 构建脚本实际执行失败(git 分发缺子模块/构建产物):插件打包分发问题,应提 Issue
329
- failPrepareHint: '该插件安装时的构建脚本执行失败(git 分发常缺失子模块或构建产物),属插件打包分发问题。请向作者仓库提交 Issue 反馈。',
330
- // 「插件打包问题」分支的次要入口:该判据由插件中心自己的预检/装后校验产出(不是 pnpm 原文),
311
+ failHubStateHint: '插件列表状态已过期或与本地不一致:这次{action}的目标可能已经在列表里了(要升级请点「更新」),也可能已经不在已安装列表中,或已在队列中。这不是插件本身的问题 —— 请刷新页面后重试。',
312
+ // 超时被强杀,可能其实已生效:给提示,不引导提 Issue。措辞动作中性(卸载场景说「已经装上了」不通)
313
+ failTimeoutHint: '本次操作耗时超过本地上限、已被中断 —— 但很可能其实已经生效了(安装器在超时后会先核对本地已安装列表)。请刷新页面确认当前状态;若确实没生效,可在终端手动执行一次对应命令查看完整输出。这不是插件本身的问题。',
314
+ failProfileLockHint: 'DSH 在写入插件清单时等不到文件锁、超时中止 —— 通常是同时有另一个 DSH 进程或安装任务在写同一个 profile(也可能是上一次的进程没退干净留下的锁)。请先关掉其他 dsh 窗口或正在跑的命令,再重试一次;若反复出现,重启一次 DSH。这不是插件本身的问题,也不需要重复{action}。',
315
+ // 宿主自身入口起不来:环境问题,给提示、不引导提 Issue
316
+ failHostCliSpawnHint: 'DSH 没能启动自身来完成这次操作(系统报「找不到可执行文件」):通常是因为 DSH 的安装目录被移动或正在更新,或该 profile 目录还不存在。请重启一次 DSH 后重试;若反复出现,重新安装 DSH。这不是插件本身的问题,换别的插件也一样。',
317
+ // prepare 构建脚本实际执行失败:插件打包分发问题,应提 Issue
318
+ failPrepareHint: '该插件安装时的构建脚本执行失败(npm 分发物不完整),属插件打包分发问题。请向作者仓库提交 Issue 反馈。',
319
+ // 「插件打包问题」分支的次要入口:该判据由插件中心自己的装后校验产出(不是 pnpm 原文),
331
320
  // 一旦误报,用户会被引导去作者仓库、插件中心永远收不到反馈 —— 故留一条反馈路径
332
321
  failMisjudgeHint: '如果这个插件其实能正常安装(上面这个判定是插件中心误报的),请反馈给插件中心:文字提示里的判据由市场自身产出,误报只有靠你的反馈才能被发现。',
333
322
  failMisjudgeLink: '插件能装却被拦下?反馈给插件中心',
334
- // 安装前预检 / 装后校验拦截([packaging]):git 分发缺插件需要的文件(入口 / 补丁 mount 的入口 / bundle 补丁)= 插件未适配官方默认安装方式
335
- failPackagingHint: '该插件不支持官方默认安装方式:其 git 分发缺少它需要的文件(`main` / `exports` 声明的入口、补丁按本包名 mount 的入口,或 `dsh.bundle.patch` 声明的补丁),说明作者未适配官方安装流程。请到作者仓库提交 Issue 反馈,请其提交构建产物、改用预构建 release `.tgz` 直链(`releases/download/<tag>/<asset>.tgz`),或发布完整的 npm 版。',
336
- // 原生依赖构建脚本被 pnpm 默认拦截(如 node-pty 的 ERR_PNPM_IGNORED_BUILDS):不单独算插件问题,引导到插件中心仓库排查
337
- failIgnoredBuild: '该插件(或其依赖)需要在安装时执行构建脚本,被 pnpm 的安全白名单(allowBuilds)默认拦截,安装因此失败(如原生模块 node-pty,或 git 安装时插件自己的 prepare 脚本)。安装器已自动放行该 key 并重试过一次;仍失败通常说明构建本身没通过。可先在终端手动执行一次安装命令查看完整构建错误;若确属插件的构建/分发问题,建议作者预置构建产物、发布 npm 包或预构建 .tgz。需要协助排查时也可反馈给插件中心。',
323
+ // 装后校验拦截([packaging]):npm 分发物缺插件需要的文件(入口 / 补丁 mount 的入口 / bundle 补丁)= 插件分发不完整
324
+ failPackagingHint: '该插件的 npm 分发物不完整:缺少它需要的文件(`main` / `exports` 声明的入口、补丁按本包名 mount 的入口,或 `dsh.bundle.patch` 声明的补丁)。请到作者仓库提交 Issue 反馈,请其发布包含完整构建产物的 npm 包。',
325
+ // 原生依赖构建脚本被 pnpm 默认拦截(如 node-pty 的 ERR_PNPM_IGNORED_BUILDS):插件的依赖需在用户机器上编译原生模块,
326
+ // 自动放行 allowBuilds 重试一次仍失败即任何用户都装不上 —— 属作者侧,引导到作者仓库提 Issue
327
+ failIgnoredBuild: '该插件(或其依赖)需要在安装时执行构建脚本,被 pnpm 的安全白名单(allowBuilds)默认拦截,本次操作因此失败(如原生模块 node-pty,或 git 安装时插件自己的 prepare 脚本)。安装器已自动放行该 key 并重试过一次;仍失败说明构建本身没通过、任何用户都装不上。可先在终端手动执行一次安装命令查看完整构建错误;这属插件的构建/分发问题,请到作者仓库反馈:建议作者预置构建产物、发布含构建产物的 npm 包或提供预构建 .tgz。',
338
328
  // npm arborist 内部崩溃(edgesOut)+ 本机 npm 版本过低:npm 自身已知缺陷,不是插件问题,升级 npm 即可
339
329
  failNpmTooLow: '怀疑本机 npm 版本过低:npm 解析插件依赖时内部崩溃(这是 npm 自身的已知缺陷,不是插件问题)。请升级 npm 后重试:npm install -g npm@latest',
340
330
  failNpmTooLowV: '本机 npm 版本过低(当前 v{v}):npm 解析插件依赖时内部崩溃(这是 npm 自身的已知缺陷,不是插件问题)。请升级 npm 后重试:npm install -g npm@latest',
341
- // 安装前连通性预检 / 安装日志里的连接失败([network] / git fetch 超时 / DNS / TLS):本机网络或代理问题,不是插件问题,不引导提 Issue
342
- failNetworkHint: '安装前检测到网络不通:无法连接到安装源(可能是断网、DNS 解析失败、被防火墙拦截,或代理配置有问题)。这不是插件本身的问题 —— 请检查网络连接,或到「设置」里确认 HTTP 代理配置,再到「系统诊断」运行一次连通性检测,然后重试。',
331
+ // 安装前连通性探测 / 安装日志里的连接失败([network] / 连接超时 / DNS / TLS):本机网络或代理问题,不是插件问题,不引导提 Issue
332
+ failNetworkHint: '{action}前检测到网络不通:无法连接到安装源(可能是断网、DNS 解析失败、被防火墙拦截,或代理配置有问题)。这不是插件本身的问题 —— 请检查网络连接,或到「设置」里确认 HTTP 代理配置,再到「系统诊断」运行一次连通性检测,然后重试。',
343
333
  // 网络失败弹窗里的「无法访问 …」醒目行:直接告诉用户具体哪个地址连不上({url} 为提取的不可达地址)
344
334
  failNetworkRegistryHint: '你的 npm/pnpm 源(registry)被配置为 {host},插件包需从该源下载但失败了。这通常是内网/自定义源没有同步该包(或需要内网认证)—— 请把 npm/pnpm 的 registry 指回官方源 https://registry.npmjs.org(或确认此源可访问该包)后重试。',
345
335
  failNetworkTarget: '无法访问 {url} —— 你的网络连接不通',
@@ -371,10 +361,8 @@ export const zh = {
371
361
  // minimumReleaseAge 专属:从报错里算出确切的可重试时刻({time}),让用户知道「何时能再装」,
372
362
  // 而不是笼统地让等 24 小时
373
363
  failPnpmReleaseAgeHint: '安装器调用 pnpm 时被其供应链安全策略拦住了,任何插件装进这个 profile 都会先撞上它——与插件本身无关。原因是这个包发布还不满 24 小时,pnpm 11 出于安全会拒收刚发布的新包,这段时间内该 profile 的安装与卸载都会被拦下。可重试时间:{time}(即该包发布满 24 小时后)。如确需立刻安装,可在 profile 目录(~/.dsh/profiles/<profile>)的 pnpm-workspace.yaml 里加 minimumReleaseAge: 0 豁免,但这会放宽整个 profile 的供应链保护。',
374
- // 自定义安装三卡片入口的渠道名(报错/日志溯源:本次安装从哪个入口发起)
364
+ // 自定义安装入口的渠道名(报错/日志溯源:本次安装从哪个入口发起)
375
365
  installChannelNpm: 'NPM 包',
376
- installChannelGit: 'GitHub 源码',
377
- installChannelDsh: 'DSH 命令',
378
366
  // 报错/通知中心的入口溯源行:前缀在错误正文顶部,精准指出自定义安装是从哪张卡片发起的
379
367
  installEntryLine: '安装入口:{c}。',
380
368
  reportIssue: '去插件仓库提交 Issue',
@@ -421,7 +409,7 @@ export const zh = {
421
409
  export const en = {
422
410
  nav: 'Plugin Hub',
423
411
  title: 'DSH Plugin Hub',
424
- // Plugin counts are filled from the live /api/stats.json ({total}/{verified}), never hardcoded
412
+ // 收录/精选数量由组件从实时 /api/stats.json({total}/{verified})填充,不写死
425
413
  tagline: 'DSH Plugin Hub: a human-verified, free marketplace for DeepSeek Harness plugins',
426
414
  adBadge: 'Featured',
427
415
  ad: 'DSH Plugin Hub: {total} plugins indexed, {verified} human-verified, updated daily',
@@ -438,59 +426,48 @@ export const en = {
438
426
  fork: 'Fork',
439
427
  loading: 'Loading plugin data…',
440
428
  failed: 'Failed to load plugin data',
441
- // Precise hints when the catalog cannot load: distinguished by whether a proxy is configured
429
+ // 目录加载失败时的精准提示:按是否配置了代理区分
442
430
  failedDescNoProxy: 'Your network seems unreachable, so the plugin catalog could not be loaded. Please check your connection and retry; or open the hub in your browser with the button above.',
443
431
  failedDescProxy: 'Your network seems unreachable, or the HTTP proxy in Settings is unreachable, so the plugin catalog could not be loaded. Please check the proxy address and your connection, then retry; or open the hub in your browser with the button above.',
444
432
  retry: 'Retry',
445
433
  install: 'Install',
446
- // Plugins that must be installed by hand (webInstallable=false): one wording for both cases —
447
- // the web UI cannot run the command at all (npx installers, local links), or it can run it but
448
- // the install needs terminal-side work (repos with a prepare build hook, sub-directory assembly).
434
+ // 需在终端手动安装的插件(webInstallable=false):两种情形共用一套措辞 ——
435
+ // 网页端完全跑不了该命令(npx 安装器 / 本地 link),或能跑但装机过程要在终端完成
436
+ //(仓库带 prepare 构建钩子、需要装配子目录)。
449
437
  cliOnlyHint: 'This plugin has to be installed in your dsh terminal (the web UI cannot run the build or assembly steps it needs) — copy the command above and run it there',
450
- // Manual-intervention flag (manualInstall): the install needs a build / step-by-step assembly in the terminal.
451
- // The key cannot be manualInstallHint — that one is the source filter on the Installed page.
438
+ // 人工干预标记(manualInstall):安装要在终端里跑构建/分步装配,网页一键安装替不了终端。
439
+ // 注意 key 不能叫 manualInstallHint —— 那个是「已安装」页来源筛选的文案(目录插件 / 手动安装)。
452
440
  manualInstallOnlyHint: 'This plugin has to be installed by hand in your dsh terminal — one-click install from the web UI cannot run the build and assembly steps it needs. Copy the command above and run it there (Git Bash or PowerShell on Windows, Terminal on macOS/Linux); the author\'s repo has the full steps.',
453
441
  failedCopyHint: 'Install failed. Copy the command above and run it manually in your dsh terminal (native build scripts may need manual approval, e.g. pnpm approve-builds)',
454
442
  toastCopied: 'Install command copied — paste it in your dsh terminal',
455
443
  installed: 'Installed',
456
- // Primary navigation: Market / Installed / Custom / Settings
444
+ // 一级导航:插件市场 / 已安装 / 自定义安装 / 设置
457
445
  viewMarket: 'Market',
458
446
  viewInstalled: 'Installed',
459
447
  viewCustom: 'Custom',
460
448
  viewSettings: 'Settings',
461
449
  viewMarketHint: 'Browse and discover plugins',
462
450
  viewInstalledHint: 'Manage installed plugins',
463
- viewCustomHint: 'Install npm packages or GitHub sources manually',
451
+ viewCustomHint: 'Install npm packages manually',
464
452
  viewSettingsHint: 'Network sources and preferences',
465
- // Installed view
453
+ // 已安装视图
466
454
  installedEmpty: 'No plugins installed yet',
467
- installedEmptyDesc: 'Go to Custom to add an npm package or GitHub source manually',
455
+ installedEmptyDesc: 'Go to Custom to add an npm package manually',
468
456
  npmInstallLabel: 'npm package / command',
469
457
  npmInstallPlaceholder: 'npm install <pkg> or a bare package name',
470
458
  npmInstallExample: 'Native commands: npm install lodash, npm i lodash, pnpm add @scope/pkg',
471
459
  npmInstallExample2: 'Global CLI: npm install -g @scope/cli; or just type a package name like lodash',
472
460
  npmInstallInvalid: 'Enter an npm package name (e.g. lodash, @scope/pkg), or a native install command (e.g. npm install lodash, npm i lodash, pnpm add @scope/pkg, npm install -g @scope/cli)',
473
- gitInstallLabel: 'GitHub source',
474
- gitInstallPlaceholder: 'Repository address',
475
- gitInstallExample: 'e.g. owner/repo or https://github.com/owner/repo',
476
- gitInstallInvalid: 'Enter a GitHub repository address, e.g. owner/repo or https://github.com/owner/repo',
477
- dshCmdLabel: 'DeepSeek Harness command',
478
- dshCmdPlaceholder: 'Paste an official dsh plugin command',
479
- dshCmdInsertHubUpdate: 'Insert update command',
480
- dshCmdExample: 'e.g. dsh plugin --profile {profile} add github:owner/repo, or dsh plugin --profile {profile} update dsh-plugin',
481
- dshCmdInvalid: 'Paste an official dsh plugin command (--profile required, add / update), e.g. dsh plugin --profile {profile} update dsh-plugin',
482
461
  installHelp: 'Help',
483
462
  helpModalTitle: 'Supported command formats',
484
463
  npmInstallHelp: 'lodash or @scope/pkg\tjust type the package name\nnpm install lodash\nnpm i lodash\npnpm add @scope/pkg\npnpm i @scope/pkg\nnpm install -g @scope/cli\tinstalls the CLI globally, not shown in Installed',
485
- gitInstallHelp: 'owner/repo\nhttps://github.com/owner/repo\ngithub:owner/repo\ngit+https://github.com/owner/repo.git\ngit@github.com:owner/repo.git',
486
- dshCmdHelp: 'dsh plugin --profile {profile} add <target>\tinstall\ndsh plugin --profile {profile} update <target>\tupdate an installed target to the latest version\ndsh plugin --profile={profile} add <target>\ndsh plugin --profile={profile} update <target>\n\t--profile is required (prefilled with the current profile here) and there is no -p shorthand; <target> can be an npm package or github:owner/repo; uninstall from the Installed list',
487
464
  globalNpmHint: 'This installs CLI tools globally (npm install -g). They won\'t appear in Installed and no host restart is needed.',
488
465
  installCliBtn: 'Install',
489
- // Install channel disabled (security-trust toggle off → card disabled, guides to settings)
466
+ // 安装通道关闭(安全信任开关关掉后,对应卡片禁用并引导去设置打开)
490
467
  channelDisabledHint: 'This install channel is disabled — enable it in Settings → Security & Trust',
491
468
  goToSettings: 'Go to Settings',
492
- // Custom install view: standalone top-level section, description text
493
- customViewDesc: 'Manually install an npm package, a GitHub source, or paste an official dsh plugin command. Finished installs appear in Installed, marked as custom.',
469
+ // 自定义安装视图:独立一级导航,说明文字
470
+ customViewDesc: 'Manually install an npm package outside the catalog. Finished installs appear in Installed, marked as custom.',
494
471
  customLabel: 'Custom install',
495
472
  installedSearch: 'Search installed plugins…',
496
473
  installedFilterCatalog: 'Catalog',
@@ -524,7 +501,7 @@ export const en = {
524
501
  detailCatalog: 'View details',
525
502
  packageName: 'Package',
526
503
  versionUpHint: 'v{from} → v{to} available — Update reinstalls in place',
527
- // Settings view: Updates & Sources / Security & Trust / Diagnostics / System Logs
504
+ // 设置视图:更新与通道 / 安全与信任 / 诊断 / 系统日志
528
505
  settingsUpdate: 'Update Settings',
529
506
  settingsUpdateDesc: 'Update checks and the network channels used for installs',
530
507
  settingsCheckOnStart: 'Check for updates on startup',
@@ -533,12 +510,11 @@ export const en = {
533
510
  settingsAutoInstallDesc: 'Install detected updates in the background without asking (a host restart applies them)',
534
511
  settingsProxy: 'HTTP proxy',
535
512
  settingsProxyDesc: 'Route npm, git and catalog requests through this proxy; leave empty to connect directly',
536
- // Live proxy reachability probe: reported after the user stops typing (an unreachable
537
- // address can still be saved — users may fill it in before actually starting the proxy)
513
+ // 代理连通性实时探测:输入停笔后提示检测结果(不通仍可保存,先填地址后开代理也合法)
538
514
  proxyCheckChecking: 'Testing this proxy address…',
539
515
  proxyCheckOk: 'Reachable — installs and catalog requests will route through it',
540
516
  proxyCheckFail: 'Unreachable, but you can still save it; make sure the proxy is running and the address and port are correct',
541
- // Failure reason: Windows Schannel aborts the handshake when revocation info (CRL/OCSP) is unreachable — not a bad proxy address
517
+ // 失败细分原因:Windows Schannel 必须取到证书吊销信息,取不到即中断握手 —— 不是代理地址不通
542
518
  proxyCheckRevocation: 'Certificate revocation check blocked (Windows Schannel could not fetch CRL/OCSP), so the handshake was aborted — a local TLS issue, not a bad proxy address',
543
519
  settingsMirror: 'npm mirror',
544
520
  settingsMirrorDesc: 'Unset by default — follows local npm config; pick a domestic mirror if slow',
@@ -548,13 +524,9 @@ export const en = {
548
524
  mirrorTencent: 'Tencent Cloud mirror',
549
525
  mirrorTsinghua: 'Tsinghua TUNA mirror',
550
526
  settingsSecurity: 'Security & Trust',
551
- settingsSecurityDesc: 'Toggles for the three command-line install channels: npm packages, GitHub sources and DSH commands',
527
+ settingsSecurityDesc: 'Toggles for command-line installs: npm packages',
552
528
  settingsEnableNpm: 'Enable npm installs',
553
529
  settingsEnableNpmDesc: 'Allow installing npm packages from the command line; turning this off rejects package-name installs',
554
- settingsEnableGit: 'Enable GitHub source installs',
555
- settingsEnableGitDesc: 'Allow installing from GitHub sources on the command line; turning this off rejects repository-address installs',
556
- settingsEnableDsh: 'Enable DSH command installs',
557
- settingsEnableDshDesc: 'Allow pasting a dsh plugin command to install; turning this off disables the command input',
558
530
  settingsDiagnostics: 'System Diagnostics',
559
531
  settingsDiagnosticsDesc: 'Check the connectivity of install channels: npm registry, GitHub and the catalog site',
560
532
  settingsLogs: 'System Logs',
@@ -565,7 +537,7 @@ export const en = {
565
537
  logsLoading: 'Reading log…',
566
538
  logsEmpty: 'No log entries yet',
567
539
  logsLoadFail: 'Failed to read the log; try again later',
568
- // Log-viewer dialog: a built-in window that loads the log in pages, filterable by type × level
540
+ // 日志查看器弹窗:内置窗口分页加载日志,可按类型 × 级别筛选
569
541
  logModalTitle: 'Log viewer',
570
542
  logViewerOpen: 'Open log viewer',
571
543
  logViewerDesc: 'View the local log in a built-in window; filter by type and level to pinpoint install / uninstall / update incompatibilities',
@@ -610,9 +582,9 @@ export const en = {
610
582
  logCount: '{n} entries',
611
583
  logEmptyFilter: 'No matching log entries',
612
584
  settingsDiagFail: 'Unreachable',
613
- // System diagnostics channel list: one-click full check + one row per channel, click to re-probe
585
+ // 系统诊断通道列表:一键全检 + 每通道一行,点击重测
614
586
  diagNpm: 'npm registry',
615
- // Diagnostics npm row: shown when no mirror is configured (probe still targets the official registry, the fallback)
587
+ // 诊断 npm 行:未配置镜像时显示的兜底文案(探测仍打官方源)
616
588
  diagNpmUnset: 'Unset (follow local npm config)',
617
589
  diagGithub: 'GitHub',
618
590
  diagCatalog: 'Catalog site',
@@ -627,20 +599,20 @@ export const en = {
627
599
  diagSummaryRunning: 'Checking channels…',
628
600
  diagSummaryOk: 'All channels reachable',
629
601
  diagSummaryFail: 'Unreachable channel(s) — click a row to re-check',
630
- // Failure reason: Windows Schannel aborts the handshake when revocation info (CRL/OCSP) is unreachable (easily mistaken for a network outage)
602
+ // 失败细分原因:Windows Schannel 取不到证书吊销信息即中断握手(易被误判为网络不通)
631
603
  diagFailRevocation: 'Cert check blocked',
632
604
  diagFailRevocationHint: 'The system curl cannot fetch certificate revocation info (CRL/OCSP, required by Windows Schannel), so the TLS handshake is aborted — this is not a network outage, and npm/git may still work. curl 7.70+ downgrades the check to best-effort, or switch to a network that can reach the revocation service.',
633
605
  settingsEnvSnapshot: 'System version',
634
606
  settingsEnvSnapshotDesc: 'Copy host version and system info for pasting into issue reports',
635
607
  settingsEnvCopy: 'Copy',
636
- // Restore defaults: first-level menu + its own settings card
608
+ // 恢复默认:一级菜单 + 独立设置卡片
637
609
  settingsReset: 'Restore Defaults',
638
610
  settingsResetDesc: 'Restore update policy, npm mirror, proxy and security restrictions to factory defaults in one go',
639
611
  settingsResetDetail: 'Reset update policy, npm mirror, proxy and security restrictions to factory defaults',
640
612
  settingsResetRun: 'Restore Defaults',
641
613
  settingsResetConfirm: 'Restore Defaults',
642
614
  settingsResetConfirmDetail: 'Reset all settings to factory defaults? Update policy, npm mirror, proxy and security restrictions will be cleared.',
643
- // Update notice (notification center item title)
615
+ // 更新提醒(通知中心条目标题)
644
616
  updateNoticeTitle: 'Update available',
645
617
  updateNoticeGo: 'Update',
646
618
  ignoreUpdateRun: 'Ignore this update',
@@ -668,11 +640,11 @@ export const en = {
668
640
  installNow: 'Install',
669
641
  installing: 'Installing…',
670
642
  installDone: 'Installed',
671
- // Updated (notification center distinguishes install/update): update = in-place reinstall to latest
643
+ // 已更新(通知中心区分安装/更新):更新 = 原位覆盖重装到最新版
672
644
  updateDone: 'Updated',
673
645
  installResultTitle: 'Plugin installed successfully',
674
646
  installResultDesc: '',
675
- // Update semantics: the "update" action re-runs add in place — copy differentiates install vs update
647
+ // 更新语义:更新动作原位重跑 add —— 文案区分安装与更新
676
648
  confirmUpdateTitle: 'Confirm update',
677
649
  updateNow: 'Update',
678
650
  updating: 'Updating…',
@@ -683,15 +655,14 @@ export const en = {
683
655
  requestTimeout: 'Request timed out: GitHub may be unreachable or the network is unstable — try again later',
684
656
  confirmCancel: 'Cancel',
685
657
  doneBtn: 'Done',
686
- // Result-view fallback: the single "Restart now" only appears when a refresh cannot help
687
- // (hot-mount failure / non-dsh plugin / update); closing the modal means "later"
658
+ // 结果视图兜底:仅刷新解决不了时(热挂载失败 / 非 dsh 插件 / 更新)才给单个「立即重启」;
659
+ // 关闭弹窗即视为「稍后」
688
660
  restartNow: 'Restart now',
689
661
  restarting: 'Restarting…',
690
662
  restartHint: 'Restarting interrupts any in-progress install / uninstall task — its progress will be lost. Some plugins (such as plugin markets / top-level bundles) only take effect after a restart.',
691
- // Desktop: the app shell owns the host, so plugins cannot restart it — tell the user to quit and reopen
663
+ // 桌面端:宿主由应用壳托管,插件重启不了它 —— 提示用户退出后重开
692
664
  toastRestartDesktop: 'In the desktop app the host is managed by the app: quit from the app menu (or tray) and open it again — the change takes effect after that restart',
693
- // Applied without a restart: the install was hot-mounted into the running loader;
694
- // the page auto-refreshes on close (no manual refresh button)
665
+ // 免重启即生效:安装已热挂载进运行中 loader;关闭弹窗时页面自动刷新(不给手动刷新按钮)
695
666
  reloadHint: 'The plugin is loaded — closing this window will refresh the page automatically.',
696
667
  toastInstalledLive: 'Installed — active now',
697
668
  toastInstalledReload: 'Installed — refreshing the page automatically…',
@@ -720,8 +691,12 @@ export const en = {
720
691
  errorTitle: 'Operation failed',
721
692
  errorTitleInstall: 'Install failed',
722
693
  errorTitleUninstall: 'Removal failed',
723
- // Update failed (notification center distinguishes install/update): update target reinstall failed
694
+ // 更新失败(通知中心区分安装/更新):更新目标覆盖重装失败
724
695
  errorTitleUpdate: 'Update failed',
696
+ // 动作词:失败提示与上报正文的措辞都取自这里
697
+ actionInstall: 'install',
698
+ actionUpdate: 'update',
699
+ actionUninstall: 'removal',
725
700
  errorPlugin: 'Plugin',
726
701
  errorClose: 'Got it',
727
702
  errorCopy: 'Copy error',
@@ -729,39 +704,40 @@ export const en = {
729
704
  failCopy: 'Copy full log',
730
705
  failIssueHint: 'Open a pre-filled issue on the author repo with this error log (includes catalog links)',
731
706
  failIssueBig: 'Report this bug to GitHub — contribute to open source',
732
- // Non-plugin-side failures (unclassified / pnpm allowBuilds block) now route to the hub repo for triage
707
+ // 非插件侧失败(未分类)改为投递到插件中心仓库分诊
733
708
  failHubIssueHint: 'This failure was classified as an environment or Plugin Hub issue (not a plugin-author issue). Open a pre-filled issue on the Plugin Hub repo with this error log.',
734
709
  failHubIssueBig: 'Report to the Plugin Hub for triage',
735
- // Unknown-failure fallback: not routed to the plugin author, but to the hub repo for triage
736
- failUnclassifiedHint: 'The install failed and the cause could not be identified automatically. This is usually not the plugin itself (it may relate to your local environment or the Plugin Hub). Please report the error to the Plugin Hub so the maintainers can triage it.',
737
- // The hub's own state-guard messages (plugin not installed / cannot be uninstalled here / already queued / already installed): the installed list is out of sync with the live snapshot — not a plugin issue, no issue prompt
738
- failHubStateHint: 'The plugin list is out of date or out of sync: this plugin may already be installed (no need to reinstall — use "Update" to upgrade), or may no longer be in the installed list, or may already be queued. This is not a plugin problem — refresh the page and retry.',
739
- // The install command hit the local time limit and was killed: it may well have installed successfully (the installer re-checks the installed list after a timeout) — actionable hint, no issue prompt
740
- failTimeoutHint: 'The install exceeded the local time limit and was interrupted — but it may well have completed already (the installer re-checks your installed list after a timeout). Refresh the page to see whether the plugin is installed; if it is not, run the install command in a terminal to see the full output. This is not a plugin problem.',
741
- failProfileLockHint: 'DSH timed out waiting for the file lock while writing the plugin list — usually because another DSH process or install task is writing the same profile (sometimes a previous run left the lock behind). Close other dsh windows or running commands, then retry; if it keeps happening, restart DSH once. This is not a plugin problem, and the plugin does not need to be reinstalled.',
742
- // prepare script actually failed (git tarball misses submodules/build output): a packaging issue of the plugin itself — file an issue
743
- failPrepareHint: 'This plugin failed while running its build scripts during install (git tarballs often miss submodules or build output). This is a packaging issue of the plugin itself — please report it to the author repository.',
744
- // Secondary entry on the "plugin packaging" branch: that verdict comes from the hub's own
745
- // pre/post-install check, not from pnpm output — a false positive sends users to the author
746
- // repo and the hub never hears about it, so keep a feedback path here.
710
+ // 未知失败兜底:不投插件作者,改投插件中心仓库分诊
711
+ failUnclassifiedHint: 'The {action} failed and the cause could not be identified automatically. This is usually not the plugin itself (it may relate to your local environment or the Plugin Hub). Please report the error to the Plugin Hub so the maintainers can triage it.',
712
+ // 插件中心自身的状态守卫消息(未安装 / 不在此处卸载 / 已在队列中 / 已安装):已装列表与实读快照不同步 —— 不是插件问题,不引导提 Issue
713
+ failHubStateHint: 'The plugin list is out of date or out of sync: the target of this {action} may already be in the list (use "Update" to upgrade), may no longer be in the installed list, or may already be queued. This is not a plugin problem — refresh the page and retry.',
714
+ // 命令跑满本机时限被强杀:可能其实已生效(安装器超时后会复核已装列表)—— 给可行动提示,不引导提 Issue
715
+ failTimeoutHint: 'This operation exceeded the local time limit and was interrupted — but it may well have taken effect already (the installer re-checks the installed list after a timeout). Refresh the page to confirm the current state; if it did not take effect, run the corresponding command in a terminal to see the full output. This is not a plugin problem.',
716
+ failProfileLockHint: 'DSH timed out waiting for the file lock while writing the plugin list — usually because another DSH process or install task is writing the same profile (sometimes a previous run left the lock behind). Close other dsh windows or running commands, then retry; if it keeps happening, restart DSH once. This is not a plugin problem, and there is no need to repeat the {action}.',
717
+ // 宿主自身入口起不来:不是插件问题 —— 只给提示,不引导提 Issue
718
+ failHostCliSpawnHint: 'DSH could not start itself to perform this operation (the system reported that the executable was not found). This usually means the DSH installation folder has been moved or is being updated, or that the profile directory does not exist yet. Restart DSH and retry; if it keeps happening, reinstall DSH. This is not a plugin problem — other plugins would fail the same way.',
719
+ // prepare 构建脚本实际执行失败:插件自身打包分发问题 —— 引导提 Issue
720
+ failPrepareHint: 'This plugin failed while running its build scripts during install (the published npm package is incomplete). This is a packaging issue of the plugin itself — please report it to the author repository.',
721
+ // 「插件打包问题」分支的次要入口:该判定来自插件中心自己的装前/装后校验,不是 pnpm 原文 ——
722
+ // 一旦误报,用户会被送去作者仓库、我们永远收不到反馈,故在此保留一条反馈通道。
747
723
  failMisjudgeHint: 'If this plugin actually installs fine (the verdict above is the Plugin Hub misjudging it), please report it to the Hub: that verdict is produced by the marketplace itself, so a false positive can only be found through your feedback.',
748
724
  failMisjudgeLink: 'Plugin installs fine but got blocked? Report to the Plugin Hub',
749
- // Pre-install / post-install guard hit ([packaging]): git distribution lacks a file the package needs (entry / entry a patch mounts / bundle patch) = not adapted to the official default install method
725
+ // 装前/装后校验命中([packaging]):git 分发缺包所需的文件(入口 / 补丁按包名 mount 的入口 / bundle 补丁)= 未适配官方默认安装方式
750
726
  failPackagingHint: 'This plugin does not support the official default install method: its git distribution lacks a file the package needs (the entry from `main` / `exports`, an entry its own patch mounts by name, or the patch declared by `dsh.bundle.patch`), so it has not been adapted to the official install flow. Please file an Issue on the author\'s repo asking for committed build output, a prebuilt release `.tgz` (`releases/download/<tag>/<asset>.tgz`), or a complete npm release.',
751
- // native-module build scripts ignored by pnpm by default (e.g. node-pty, ERR_PNPM_IGNORED_BUILDS): not a plugin-side issue on its own, route to the hub repo for triage
752
- failIgnoredBuild: 'This plugin (or one of its dependencies) needs to run build scripts at install time, which pnpm blocks by default via its allowBuilds allowlist — so the install fails (e.g. native modules like node-pty, or the plugin\'s own prepare script on git installs). The installer already auto-allows that key and retries once; if it still fails, the build itself is usually the problem. Run the install command in a terminal to see the full build error; if it is indeed the plugin\'s build or distribution, the author can ship prebuilt output, an npm release, or a prebuilt .tgz. You can also report it to the Plugin Hub for triage.',
727
+ // pnpm 默认忽略的原生模块构建脚本(如 node-pty,ERR_PNPM_IGNORED_BUILDS):插件的依赖需在用户机器上编译原生模块,
728
+ // 自动放行 allowBuilds 重试一次仍失败即任何用户都装不上 —— 属作者侧,引导到作者仓库提 Issue
729
+ failIgnoredBuild: 'This plugin (or one of its dependencies) needs to run build scripts at install time, which pnpm blocks by default via its allowBuilds allowlist — so this operation fails (e.g. native modules like node-pty, or the plugin\'s own prepare script on git installs). The installer already auto-allows that key and retries once; if it still fails, the build itself is the problem, so no user can install it. Run the install command in a terminal to see the full build error; this is a build/distribution issue of the plugin itself — please report it to the author repository, asking them to ship prebuilt output, a complete npm release, or a prebuilt .tgz.',
753
730
  failNpmTooLow: 'Your local npm may be too old: npm crashed internally while resolving the plugin\'s dependencies (a known npm bug — not a plugin issue). Please upgrade npm and retry: npm install -g npm@latest',
754
731
  failNpmTooLowV: 'Your local npm is too old (v{v}): npm crashed internally while resolving the plugin\'s dependencies (a known npm bug — not a plugin issue). Please upgrade npm and retry: npm install -g npm@latest',
755
- // Pre-install connectivity probe / connection failure in the install log ([network] / git fetch timeout / DNS / TLS): a local network or proxy issue, not a plugin issue — no issue link
756
- failNetworkHint: 'The network could not be reached before install: the install source is unreachable (offline, DNS failure, firewall block, or a misconfigured proxy). This is not a problem with the plugin itself — please check your connection, confirm the HTTP proxy in Settings, run a connectivity check under System Diagnostics, then retry.',
757
- // Prominent "cannot reach …" line in the network-failure dialog: shows the exact unreachable address ({url})
732
+ // 安装前网络探测 / 安装日志里的连接失败([network] / git fetch 超时 / DNS / TLS):本机网络或代理问题,不是插件问题 —— 不引导提 Issue
733
+ failNetworkHint: 'The network could not be reached before the {action}: the install source is unreachable (offline, DNS failure, firewall block, or a misconfigured proxy). This is not a problem with the plugin itself — please check your connection, confirm the HTTP proxy in Settings, run a connectivity check under System Diagnostics, then retry.',
734
+ // 网络失败弹窗里的「无法访问 …」醒目行:显示具体的不可达地址({url})
758
735
  failNetworkRegistryHint: 'Your npm/pnpm registry is set to {host}, and the package tarball could not be downloaded from it. This usually means a private/internal mirror that has not synced the package (or requires intranet auth) — point the registry back to https://registry.npmjs.org (or make sure this source can serve the package), then retry.',
759
736
  failNetworkTarget: 'Cannot reach {url} — your network connection is down',
760
- // Diagnostics shortcut button under the network-down hint: jumps to Settings → System Diagnostics
737
+ // 网络不通提示下的诊断快捷按钮:跳到设置 → 系统诊断
761
738
  failNetworkRunDiag: 'Run a network diagnostic',
762
- // The request origin did not pass the local hub service check (403 untrusted origin): the request
763
- // never reached the install flow — nothing to do with the plugin, so point at the local address
764
- // and do not offer an issue link
739
+ // 请求来源没通过本地 hub 服务校验(403 untrusted origin):请求根本没进安装流程 ——
740
+ // 与插件无关,故引导从本机地址重开,不引导提 Issue。
765
741
  failOriginRejectedHint: 'This install request did not pass the marketplace origin check and was rejected by the local service, so the install never started — this is not about the plugin itself. It usually means the marketplace page was not opened from a local address (for example a LAN IP), or the host page origin was not recognized. Reopen the marketplace from localhost and retry; on the desktop app, restart the host once. If it still fails after restarting the host, your dsh-plugin version is incompatible with the host — upgrade the marketplace with dsh plugin --profile {profile} add dsh-plugin@latest, then restart the host again.',
766
742
  failDshMissingHint: 'The dsh command could not be found (it is not on the system PATH), so the installer could not run. Please make sure DeepSeek Harness is installed correctly and dsh is on your PATH (or reinstall it), then retry. This is not a problem with the plugin itself.',
767
743
  failGitMissingHint: 'The git command could not be found (Git is not installed or not on the system PATH), so GitHub-source plugins cannot be installed. Please install Git (e.g. from git-scm.com/downloads) or add git to your PATH, restart DSH, then retry. This is not a problem with the plugin itself.',
@@ -769,8 +745,7 @@ export const en = {
769
745
  failNpmMissingHint: 'The npm command could not be found (npm is not installed or not on the system PATH), so a global install cannot run. Please install Node.js (which bundles npm), make sure npm is on your PATH, then retry. This is not a problem with the plugin itself.',
770
746
  failPnpmStoreHint: 'pnpm reported an unexpected store location (ERR_PNPM_UNEXPECTED_STORE): the profile directory was previously set up with a different major version of pnpm, and the current pnpm refuses to reuse it — no plugin can be installed into that profile. Delete node_modules and pnpm-lock.yaml under the profile directory (see System Logs or ~/.dsh/profiles/<profile>/hub.log for the full output), then reinstall. This is not a problem with the plugin itself.',
771
747
  failPnpmUnusedPatchHint: 'pnpm reported that some patches were not used (ERR_PNPM_UNUSED_PATCH): your profile still holds a patch entry for an older dsh-plugin version (for example dsh-plugin@1.4.2), while this install resolved a different version, so pnpm aborts the whole install for safety — no plugin can be installed into that profile. This is not a problem with the plugin itself. Remove that dsh-plugin patch entry from pnpm-workspace.yaml (pnpm 11+) or from pnpm.patchedDependencies in package.json (pnpm 10) inside the profile directory (~/.dsh/profiles/<profile>), then retry.',
772
- // Missing dependency: name the package that 404'd (the line is skipped when it cannot be parsed),
773
- // then give the removal instructions
748
+ // 缺失依赖:点名 404 的包(解析不出时跳过该行),再给删除指引
774
749
  failPnpmMissingDepTarget: '{pkg} was not found on the npm registry (404)',
775
750
  failPnpmMissingDepHint: 'pnpm reported that a package does not exist on the npm registry (ERR_PNPM_FETCH_404): your profile keeps a dependency on a package that was never published, and pnpm hits it every time it resolves dependencies — no plugin can be installed into that profile. This is not a problem with the plugin itself. Remove that dependency from package.json inside the profile directory (~/.dsh/profiles/<profile>) — along with its entry in pnpm-lock.yaml, or the lockfile itself — then retry.',
776
751
  failRegistryMirrorLagHint: 'pnpm reported that a package does not exist on the npm registry (ERR_PNPM_FETCH_404): that package does exist on the official npm registry, but the npm/pnpm registry (or mirror) configured on your machine has not synced it. Point the npm/pnpm registry back at the official one (https://registry.npmjs.org), or switch to a mirror that has the package, then retry. This is not a problem with the plugin itself.',
@@ -784,14 +759,12 @@ export const en = {
784
759
  failPnpmWorkspaceHint: 'pnpm refused to add the dependency to the workspace root (ERR_PNPM_ADDING_TO_ROOT): the profile directory is treated as a pnpm workspace root, and this install command did not declare that it operates at the root, so pnpm rejected it outright — no plugin can be installed into that profile. This is not a problem with the plugin itself. Add `ignore-workspace-root-check=true` to the `.npmrc` inside the profile directory (~/.dsh/profiles/<profile>) and retry, or upgrade DeepSeek Harness and try again.',
785
760
  failPnpmTarballIntegrityHint: 'pnpm reported ERR_PNPM_MISSING_TARBALL_INTEGRITY: a tarball entry in the lockfile has no checksum to verify the downloaded package. Read the full log, fully quit DeepSeek Harness, and inspect and back up package.json, pnpm-lock.yaml and pnpm-workspace.yaml in the affected profile. Once the dependency sources are verified, rename pnpm-lock.yaml to preserve it, then use the same DSH installer to install a plugin version compatible with the host and regenerate the lockfile. This resolves profile dependencies again: compare the old and new versions, and keep integrity checks enabled.',
786
761
  failPnpmPolicyHint: 'The installer was blocked by pnpm supply-chain security policy — every plugin install would hit the same wall, so this is not a problem with the plugin itself. Two cases: ① "Minimum release age" (ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION): the package was published less than 24 hours ago, and pnpm 11 refuses freshly-published packages for safety. Add minimumReleaseAge: 0 to your pnpm config (pnpm-workspace.yaml) to opt out, or wait until the 24 hours have passed and retry. ② "untrusted origin" (ERR_PNPM_UNTRUSTED_ORIGIN): a dependency source is not trusted by this machine, usually because plugins were previously installed via github: or a non-official npm registry, so the lockfile records an untrusted source. Delete node_modules and pnpm-lock.yaml under the profile directory (see System Logs or ~/.dsh/profiles/<profile>/hub.log for the full output), then reinstall.',
787
- // minimumReleaseAge only: compute the exact retry time ({time}) from the error so the user knows
788
- // when installs will work again, instead of the vague "wait 24 hours"
762
+ // 仅 minimumReleaseAge 场景:从报错算出确切的可重试时刻({time}),让用户知道何时能装,
763
+ // 而不是笼统的「等 24 小时」
789
764
  failPnpmReleaseAgeHint: 'The installer was blocked by pnpm supply-chain security policy, and every plugin installed into this profile would hit the same wall — this is not a problem with the plugin itself. The package was published less than 24 hours ago, and pnpm 11 refuses freshly-published packages for safety, so both installs and removals are blocked for this profile in the meantime. Retry after: {time} (i.e. 24 hours after the package was published). If you must install right now, add minimumReleaseAge: 0 to pnpm-workspace.yaml inside the profile directory (~/.dsh/profiles/<profile>) to opt out, but that loosens supply-chain protection for the whole profile.',
790
- // Custom install entry channel names (the three cards) — used in error/log traceability
765
+ // 自定义安装入口渠道名 —— 用于报错/日志溯源
791
766
  installChannelNpm: 'NPM package',
792
- installChannelGit: 'GitHub source',
793
- installChannelDsh: 'DSH command',
794
- // Entry traceability line prefixed at the top of the error text: which card initiated this install
767
+ // 错误正文顶部的入口溯源行:指出从哪张卡片发起本次安装
795
768
  installEntryLine: 'Install entry: {c}.',
796
769
  reportIssue: 'Report an Issue to the plugin repo',
797
770
  detail: 'Open details',
@@ -802,12 +775,12 @@ export const en = {
802
775
  monthsAgo: 'updated {months}mo ago',
803
776
  yearsAgo: 'updated {years}y ago',
804
777
  pluginsTotal: 'Results: {n} plugins',
805
- // Category chips carry no counts; the filtered result count shows in the list header
778
+ // 分类 chip 不带计数;筛选结果数显示在列表头部
806
779
  filterResults: 'Results: {n} plugins',
807
780
  more: '{n} more on the website',
808
781
  browseAll: 'Browse all {n} plugins',
809
782
  verified: 'Verified',
810
- // Version & updates: repos with a release are compared by tag; repos without one by last push time (new commits → update)
783
+ // 版本与更新:有 release 的仓库比 tag,没有的比最近推送时间(有新提交即有更新)
811
784
  version: 'Version',
812
785
  update: 'Update',
813
786
  updateAvailable: 'Update available',
@@ -821,10 +794,10 @@ export const en = {
821
794
  versionHint: 'View version info and changelog',
822
795
  hubCurrentTitle: 'Current version',
823
796
  hubCurrentDesc: 'You are on v{version} — this is the latest version.',
824
- // Deferred notice: a newer release exists but is still inside pnpm's 24h supply-chain window
797
+ // 暂缓提示:确有新版本,但仍在 pnpm 24h 供应链门禁窗口内
825
798
  hubPendingDesc: 'v{version} has been released, but it is still within the 24-hour window where pnpm silently falls back to the older version, so the update is not offered yet. The update entry will appear here shortly.',
826
799
  hubUpToDate: 'Up to date',
827
- // Header "Follow us" modal: platform intro + user feedback group QR (content pushed via Worker /about Markdown)
800
+ // 头部「关注我们」弹窗:平台介绍 + 用户反馈群二维码(内容由 Worker /about 以 Markdown 推送)
828
801
  followUs: 'Follow us',
829
802
  aboutTitle: 'Follow us',
830
803
  aboutDesc: 'Learn what DSH Plugin Hub does and join our user feedback group.',
@@ -3,8 +3,7 @@
3
3
  * Website: https://dsh-plugin.org
4
4
  * GitHub: https://github.com/dshplugin/dsh-plugin-hub
5
5
  *
6
- * Constants: site URLs, category metadata and sort keys. Pure data — no
7
- * side effects, no network — so every consumer shares one definition.
6
+ * 常量:站点地址、分类元数据与排序 key。纯数据、无副作用、无网络,供所有使用方共享同一份定义。
8
7
  */
9
8
  import type { LocaleId } from '../types.ts'
10
9
 
@@ -1,17 +1,13 @@
1
1
  /**
2
- * Self-heal missing plugin CSS tags.
2
+ * 自愈缺失的插件 CSS 标签。
3
3
  *
4
- * CSS injection is a one-shot side effect of the bundle factory (guarded by
5
- * "tag already present"). When the host restarts the page survives, but the
6
- * host HMR chain may remove the <style data-plugin> tags while the in-memory
7
- * module cache still holds the old factory — so the factory never re-runs and
8
- * the styles never come back until some interaction triggers a reload.
4
+ * CSS 注入是 bundle 工厂的一次性副作用(以「标签已存在」为守卫)。宿主重启后页面仍在,
5
+ * 但宿主 HMR 链可能移除 <style data-plugin> 标签,而内存模块缓存仍持有旧工厂,工厂不再
6
+ * 重跑,样式就一直缺失,直到某次交互触发刷新才恢复。
9
7
  *
10
- * The tsdown `dsh-css-modules-inline` build plugin registers every module's
11
- * { tagId, css } into the global list `__DSH_PLUGIN_CSS__` at factory time.
12
- * This helper compares that list against the live DOM and re-injects any
13
- * missing tags, turning the "click around to fix it" self-heal into an
14
- * automatic one on mount / view switch.
8
+ * tsdown 的 `dsh-css-modules-inline` 构建插件会在工厂执行时把每个模块的 { tagId, css }
9
+ * 登记进全局列表 `__DSH_PLUGIN_CSS__`。此工具随后比对列表与实时 DOM,补注入缺失的标签,
10
+ * 把「点一圈才自愈」变成挂载 / 切换视图时自动完成。
15
11
  */
16
12
 
17
13
  interface PluginCssEntry {
@@ -25,7 +21,7 @@ declare global {
25
21
  }
26
22
  }
27
23
 
28
- /** Re-inject any registered stylesheet that is missing from the DOM. Idempotent. */
24
+ /** 补注入 DOM 中缺失的已登记样式表,幂等。 */
29
25
  export function ensurePluginCss(): void {
30
26
  if (typeof document === 'undefined') return
31
27
  const registry = window.__DSH_PLUGIN_CSS__