dsh-plugin 1.3.0 → 1.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["installTargetOf","SORT_DEFAULT_DIR","useState","useMemo","useState","useState","useCallback","useState","useRef","installTargetOf","h","modalStyles","headerStyles","h","styles","h","styles","h","styles","h","styles","h","styles","h","styles","h","Fragment","styles","h","styles","SegBtn","h","styles","Fragment","useState","useRef","h","styles","useRef","h","styles","h","Fragment","h","styles","h","styles","useState","useMemo","useState","h","styles","modal","useState","useRef","h","styles","h","styles","useState","useRef","useCallback","h","styles","h","view","useState","useRef","useCallback","styles","useState","h","styles","view","useState","useRef","useCallback","h","styles","h","styles","useState","modalStyles","useState","useRef","h","styles","modalStyles","h"],"sources":["../src/client/locales.ts","../src/client/logic/install-command.ts","../src/client/logic/constants.ts","../src/client/data/host.ts","../src/client/logic/normalize.ts","../src/client/data/catalog.ts","../src/client/data/hub.ts","../src/client/logic/installed.ts","../src/client/hooks/useCatalog.ts","../src/client/logic/failures.ts","../src/client/logic/urls.ts","../src/client/hooks/useLanguage.ts","../src/client/hooks/useSettings.ts","../src/client/hooks/useTaskQueue.ts","../src/client/components/ui/icons.tsx","../src/client/components/modals/ProgressView.tsx","../src/client/components/modals/modals.tsx","../src/client/logic/renderMarkdown.ts","../src/client/components/modals/AboutModal.tsx","../src/client/components/modals/HubUpdateModal.tsx","../src/client/logic/format.ts","../src/client/components/modals/InstalledDetailModal.tsx","../src/client/components/modals/NotificationsModal.tsx","../src/client/components/layout/CatalogHeader.tsx","../src/client/components/layout/CategoryTabs.tsx","../src/client/components/layout/CatalogControls.tsx","../src/client/hooks/useIncrementalList.ts","../src/client/components/catalog/PluginCard.tsx","../src/client/components/catalog/CatalogList.tsx","../src/client/components/views/MarketView.tsx","../src/client/components/layout/SectionTabs.tsx","../src/client/components/views/InstalledView.tsx","../src/client/components/views/CustomInstallView.tsx","../src/client/components/ui/Dropdown.tsx","../src/client/components/ui/Toggle.tsx","../src/client/components/views/DiagnosticsView.tsx","../src/client/components/modals/LogsModal.tsx","../src/client/components/modals/LogsPathModal.tsx","../src/client/components/views/LogsView.tsx","../src/client/components/views/SettingsView.tsx","../src/client/components/PluginHubSection.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * zh/en dictionaries for the DSH Plugin Hub settings section.\n */\nexport const zh = {\n nav: '插件中心',\n title: 'DSH Plugin Hub',\n // 收录/精选数量由组件从官网 /api/stats.json 实时拉取填充({total}/{verified}),不写死\n tagline: 'DSH Plugin 插件中心:面向 DeepSeek Harness 插件收录平台,人工审验、来源可溯,免费安装',\n adBadge: '推荐',\n // 紫色广告横幅:突出数量(显眼)+ 更新节奏,与 tagline 职责分开、不重复\n ad: 'DSH Plugin 插件中心:收录 {total} 款插件,{verified} 款人工精选验证,每日更新',\n search: '搜索插件名称、描述、标签…',\n all: '全部',\n sortStars: 'Star',\n sortForks: 'Fork',\n sortUpdated: '最近更新',\n sortNewest: '最新收录',\n sortAria: '插件排序方式',\n openHint: '打开 dsh-plugin.org',\n toggleLangHint: '切换界面语言',\n fork: 'Fork',\n loading: '正在加载插件数据…',\n failed: '插件数据加载失败',\n failedDesc: '请稍后重试,或点击右上角按钮在浏览器中打开插件中心。',\n retry: '重试',\n install: '安装',\n // AI 识别可能需要命令行辅助的插件(webInstallable=false):仍可尝试一键安装,失败时复制命令去 dsh 终端\n cliOnlyHint: '此插件可能需命令行辅助,失败时复制上方命令到 dsh 终端',\n failedCopyHint: '安装失败。请复制上方安装命令到 dsh 终端手动执行(原生依赖构建脚本可能需要人工放行,如 pnpm approve-builds)',\n toastCopied: '安装命令已复制,去 dsh 终端粘贴即可安装',\n installed: '已安装',\n // 一级导航:插件中心 / 已安装 / 自定义安装 / 设置\n viewMarket: '插件中心',\n viewInstalled: '已安装',\n viewCustom: '自定义安装',\n viewSettings: '设置',\n viewMarketHint: '浏览与发现插件',\n viewInstalledHint: '管理已安装插件',\n viewCustomHint: '手动安装 NPM 包或 GitHub 源码',\n viewSettingsHint: '网络通道与偏好设置',\n // 已安装视图\n installedEmpty: '还没有安装插件',\n installedEmptyDesc: '可以去「自定义安装」,手动安装 NPM 包或 GitHub 源码',\n npmInstallLabel: 'NPM 包 / 命令',\n npmInstallPlaceholder: 'npm install <包名> 或直接输包名',\n npmInstallExample: '支持原生命令:npm install lodash、npm i lodash、pnpm add @scope/pkg',\n npmInstallExample2: '全局安装 CLI:npm install -g @scope/cli;或直接输入包名 lodash',\n npmInstallInvalid: '请输入 npm 包名(如 lodash、@scope/pkg),或原生安装命令(如 npm install lodash、npm i lodash、pnpm add @scope/pkg、npm install -g @scope/cli)',\n gitInstallLabel: 'GitHub 源码',\n gitInstallPlaceholder: '输入仓库地址',\n gitInstallExample: '例如:owner/repo 或 https://github.com/owner/repo',\n gitInstallInvalid: '请输入 GitHub 仓库地址,例如:owner/repo 或 https://github.com/owner/repo',\n dshCmdLabel: 'DeepSeek Harness 命令',\n dshCmdPlaceholder: '粘贴官方 dsh plugin 命令',\n dshCmdExample: '例如:dsh plugin --profile web add github:owner/repo',\n dshCmdInvalid: '请输入官方 dsh plugin 安装命令(--profile 必填)。例如:dsh plugin --profile web add github:owner/repo',\n installHelp: '帮助',\n helpModalTitle: '支持的命令格式',\n 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 工具,不进「已安装」列表',\n gitInstallHelp: 'owner/repo\\nhttps://github.com/owner/repo\\ngithub:owner/repo\\ngit+https://github.com/owner/repo.git\\ngit@github.com:owner/repo.git',\n dshCmdHelp: 'dsh plugin --profile web add <目标>\\ndsh plugin --profile=web add <目标>\\n\\t--profile 必填,官方 CLI 无 -p 简写;<目标> 可为 npm 包名或 github:owner/repo',\n globalNpmHint: '将全局安装 CLI 工具(npm install -g),不会出现在「已安装」列表,无需重启宿主',\n installCliBtn: '安装',\n // 安装通道关闭(安全信任开关关掉后,对应卡片禁用并引导去设置打开)\n channelDisabledHint: '该安装通道已关闭,请在「设置 → 安全信任」中打开开关',\n goToSettings: '前往设置',\n // 自定义安装视图:独立一级导航,说明文字\n customViewDesc: '手动安装目录外的 NPM 包、GitHub 源码,或粘贴官方 dsh plugin 命令。装完的条目会出现在「已安装」列表,并标记为自定义安装。',\n customLabel: '自定义安装',\n installedSearch: '搜索已安装的插件…',\n installedFilterCatalog: '目录插件',\n hubInstall: '插件中心',\n hubInstallHint: '来自插件中心收录的目录插件',\n manualInstall: '手动安装',\n manualInstallHint: '非目录收录,通过命令行手动安装',\n filterByLabel: '来源',\n sortByLabel: '排序',\n sortName: '名称',\n sortInstalledAt: '最近',\n detailTitle: '插件详情',\n detailCategory: '分类',\n detailStats: '仓库统计',\n statusLabel: '安装状态',\n statusRunning: '运行中',\n statusPending: '待重启',\n exampleLabel: 'DeepSeek Harness 内置示例项目',\n exampleHint: 'DeepSeek Harness 内置示例项目:不是插件市场的 dsh 插件,宿主不会加载它,无需重启',\n restart: '重启',\n installedVersionLabel: '已安装版本',\n catalogLatest: '目录最新',\n installPath: '安装路径',\n copyPath: '复制路径',\n openFolder: '在文件夹中显示',\n openFolderFail: '无法打开文件夹,请复制路径手动打开',\n revealFolder: '在 Finder 中显示',\n installedAtLabel: '安装时间',\n lastUpdatedLabel: '最后更新',\n detailCatalog: '查看详情',\n packageName: '包名',\n versionUpHint: '发现新版本 v{from} → v{to},点击「更新」原位覆盖重装',\n // 设置视图:更新与通道 / 安全与信任 / 诊断 / 系统日志\n settingsUpdate: '更新设置',\n settingsUpdateDesc: '更新检查方式与安装走到的网络通道',\n settingsCheckOnStart: '启动时检查更新',\n settingsCheckOnStartDesc: '打开插件中心时检查已安装插件是否有新版,发现更新会提示',\n settingsMirror: 'npm 镜像源',\n settingsMirrorDesc: 'npm 安装与版本反查走自定义镜像,网络不佳时更稳定;留空使用官方源',\n mirrorOfficial: '官方源 registry.npmjs.org',\n mirrorNpmmirror: '阿里云 npmmirror',\n mirrorTencent: '腾讯云镜像',\n mirrorCustom: '自定义镜像源',\n settingsProxy: 'HTTP 代理',\n settingsProxyDesc: 'npm / git / 目录数据请求统一走该代理;留空直连',\n settingsSecurity: '安全信任',\n settingsSecurityDesc: '命令行安装的三个通道开关:NPM 包、GitHub 源码与 DSH 命令',\n settingsEnableNpm: '启用 NPM 安装',\n settingsEnableNpmDesc: '允许通过命令行安装 npm 包;关闭后输入包名安装会被拦截',\n settingsEnableGit: '启用 GitHub 源码安装',\n settingsEnableGitDesc: '允许通过命令行安装 GitHub 源码;关闭后输入仓库地址安装会被拦截',\n settingsEnableDsh: '启用 DSH 命令安装',\n settingsEnableDshDesc: '允许通过命令行粘贴 dsh plugin 命令安装;关闭后命令输入会被禁用',\n settingsDiagnostics: '系统诊断',\n settingsDiagnosticsDesc: '检测 npm 源 / GitHub / 目录站点等安装通道的连通状态',\n settingsLogs: '系统日志',\n settingsLogsDesc: '本地记录的安装 / 卸载 / 设置变更与诊断结果,可导出全文排查问题',\n logsHeadHint: '记录安装、卸载、设置变更与诊断结果,保留最近 2000 条',\n logsRefresh: '刷新日志',\n logsExport: '导出日志',\n logsLoading: '正在读取日志…',\n logsEmpty: '暂无日志记录',\n logsLoadFail: '读取日志失败,请稍后重试',\n // 系统日志查看器弹窗:内置窗口分页加载,按类别 × 级别筛选\n logModalTitle: '日志查看器',\n logViewerOpen: '打开日志查看器',\n logViewerDesc: '内置窗口直接查看本地日志,按类型与级别筛选,可定位安装 / 卸载 / 更新时的不兼容点',\n logPathLabel: '日志文件',\n logOpenFile: '打开文件',\n logOpenFileTip: '在系统文件管理器中定位日志文件',\n logOpenFileFail: '打开失败,请在文件管理器中手动定位',\n logPathSettingTitle: '日志存放位置',\n logPathSettingDesc: '默认存于宿主配置目录,可填目录或 .log 文件路径改存别处',\n logPathPlaceholder: '留空恢复默认',\n logPathReset: '恢复默认',\n logPathResetHint: '文本框显示当前生效位置',\n logPathSave: '保存',\n logPathSaving: '保存中…',\n logPathSaved: '已保存,新日志将写入该位置',\n logPathSaveFail: '保存失败:该位置不可写或不可用',\n logPathChange: '修改',\n logPathBrowse: '选择目录…',\n logPathBrowseFail: '选择目录不可用,请手动输入路径',\n logCatAll: '全部类型',\n logCatInstall: '安装',\n logCatUninstall: '卸载',\n logCatUpdate: '更新',\n logCatDiagnostics: '诊断',\n logCatSettings: '设置',\n logCatSystem: '系统',\n logLvAll: '全部级别',\n logLvError: '错误',\n logLvWarn: '警告',\n logLvSuccess: '成功',\n logLvInfo: '信息',\n logLvDebug: '调试',\n logSearchPlaceholder: '搜索事件或描述…',\n logLoadMore: '加载更多',\n logNoMore: '已加载全部,共 {n} 条',\n logCount: '共 {n} 条',\n logEmptyFilter: '没有符合条件的日志',\n settingsDiagFail: '不可达',\n // 系统诊断通道列表:一键全量诊断 + 一行一个,可点重测\n diagNpm: 'npm 源',\n diagGithub: 'GitHub',\n diagCatalog: '目录站点',\n diagOk: 'OK',\n diagChecking: '检测中…',\n diagIdle: '未检测',\n diagRecheck: '点击重测该通道',\n diagRunAll: '立即诊断',\n diagHeadHint: '共 {n} 个通道,点击任意一行可单独重测',\n diagSummaryRunning: '正在检测通道…',\n diagSummaryOk: '全部通道正常',\n diagSummaryFail: '存在不可达通道,点击对应行可重测',\n settingsEnvSnapshot: '系统版本',\n settingsEnvSnapshotDesc: '复制宿主版本与系统信息,提交 Issue 时粘贴到正文便于复现',\n settingsEnvCopy: '复制',\n // 恢复默认:一级菜单 + 独立设置卡片\n settingsReset: '恢复默认',\n settingsResetDesc: '更新策略、镜像源、代理与安全限制一次性恢复为出厂默认值',\n settingsResetDetail: '恢复更新策略、镜像源、代理与安全限制为出厂默认值',\n settingsResetRun: '恢复默认',\n settingsResetConfirm: '确认恢复',\n settingsResetConfirmDetail: '确定要恢复默认设置吗?更新策略、镜像源、代理与安全限制将全部回到出厂默认值。',\n // 启动更新策略提示\n updatesFound: '发现 {n} 个插件可更新,已加入通知中心',\n updateNoticeTitle: '发现新版本',\n updateNoticeGo: '去更新',\n ignoreUpdateRun: '忽略本次更新',\n ignoreUpdateConfirmTitle: '忽略本次更新?',\n ignoreUpdateConfirmDetail: '忽略后本次版本不再提醒;待插件发布下一个新版本时,会再次通知你。',\n ignoreUpdateConfirm: '确认忽略',\n uninstall: '卸载',\n uninstalling: '卸载中…',\n uninstallTitle: '确认卸载?',\n uninstallDesc: '将从当前环境卸载该插件。',\n uninstallDone: '卸载成功',\n uninstallFail: '卸载失败,请稍后重试',\n uninstallResultTitle: '卸载完成',\n uninstallResultDesc: '插件已从当前环境移除。',\n confirmTitle: '确认安装',\n confirmDesc: '安装前请前往插件仓库仔细阅读源码,确认可信后再安装',\n confirmPlugin: '插件',\n confirmSource: '来源',\n confirmCommand: '安装命令',\n copyInstallCommand: '复制安装命令',\n copyCmdLabel: '复制',\n copyUninstallCommand: '复制卸载命令',\n cancelUninstall: '取消卸载',\n uninstallConfirm: '确认卸载',\n installNow: '直接安装',\n installing: '安装中…',\n installDone: '安装成功',\n installResultTitle: '插件安装成功',\n installResultDesc: '',\n // 更新语义:已安装插件点「更新」走同一条 add 命令原位覆盖重装,弹窗文案区分安装/更新\n confirmUpdateTitle: '确认更新',\n updateNow: '直接更新',\n updating: '更新中…',\n queuedUpdateTitle: '已加入更新排队',\n updateResultTitle: '更新完成',\n updateResultDesc: '插件已更新到最新版本。',\n installFail: '安装失败',\n requestTimeout: '请求超时:无法访问 GitHub 或网络不稳定,请稍后重试',\n confirmCancel: '取消',\n doneBtn: '完成',\n // 结果视图:部分插件需重启后才挂载,提供「立即重启 / 稍后重启」选择\n restartNow: '立即重启',\n restartLater: '稍后重启',\n restarting: '正在重启…',\n restartHint: '部分插件(如插件市场、顶层 bundle)需重启后才会生效。',\n done: '完成',\n // 待重启:装完没重启的插件常驻提醒,直到宿主真正重启\n restartPendingHint: '安装成功,重启后生效',\n restartPendingHintUninstall: '卸载成功,重启后移除',\n sectionPendingRestart: '待重启',\n sectionInProgress: '进行中',\n // 通知中心:安装/卸载任务成败的持久记录(工具栏铃铛入口按钮打开)\n notifications: '通知',\n notificationsHint: '查看安装/卸载/更新通知',\n notificationsDesc: '安装、卸载任务与更新提醒都会记录在这里,即使错过提示也能随时回来查看。',\n notificationsEmpty: '暂无通知记录',\n notificationsClear: '清空通知',\n removeNotification: '删除这条通知',\n // 串行队列:安装/卸载弹窗内可后台关闭,排队任务自动串行执行\n queuedTitle: '已加入安装排队',\n queuedUninstallTitle: '已加入卸载排队',\n queuedHint: '已加入排队,前序任务完成后将自动开始,可关闭本窗口继续浏览。',\n cancelTask: '取消任务',\n cancelling: '正在取消…',\n errorTitle: '操作失败',\n errorTitleInstall: '安装失败',\n errorTitleUninstall: '卸载失败',\n errorPlugin: '插件',\n errorClose: '知道了',\n errorCopy: '复制错误信息',\n errCopied: '错误信息已复制',\n failCopy: '复制完整错误信息',\n failIssueHint: '带着错误日志去作者仓库一键提交 Issue(正文含官网收录链接)',\n failIssueBig: '一键提交 BUG 到 GitHub Issue 为开源作贡献',\n // prepare 构建脚本实际执行失败(git 分发缺子模块/构建产物):插件打包分发问题,应提 Issue\n failPrepareHint: '该插件安装时的构建脚本执行失败(git 分发常缺失子模块或构建产物),属插件打包分发问题。请向作者仓库提交 Issue 反馈。',\n // 安装前预检 / 装后校验拦截([packaging]):git 分发缺构建产物、入口文件不存在 = 插件未适配官方默认安装方式\n failPackagingHint: '该插件不支持官方默认安装方式:其 git 分发缺少构建产物(package.json 声明的入口文件在仓库中不存在),说明作者未适配官方安装流程。请到作者仓库提交 Issue 反馈,请其提交构建产物或发布 npm 版。',\n // 原生依赖构建脚本被 pnpm 默认拦截(如 node-pty 的 ERR_PNPM_IGNORED_BUILDS):只影响带原生模块的插件,属插件依赖打包问题,应提 Issue\n failIgnoredBuild: '该插件依赖了需要编译的原生模块(如 node-pty),pnpm 默认拦截这类构建脚本导致安装失败 —— 其他插件不受影响,属该插件的依赖/打包问题。建议向作者仓库一键反馈,请作者改用预编译版本(如 node-pty-prebuilt-multiarch)。',\n // npm arborist 内部崩溃(edgesOut)+ 本机 npm 版本过低:npm 自身已知缺陷,不是插件问题,升级 npm 即可\n failNpmTooLow: '怀疑本机 npm 版本过低:npm 解析插件依赖时内部崩溃(这是 npm 自身的已知缺陷,不是插件问题)。请升级 npm 后重试:npm install -g npm@latest',\n failNpmTooLowV: '本机 npm 版本过低(当前 v{v}):npm 解析插件依赖时内部崩溃(这是 npm 自身的已知缺陷,不是插件问题)。请升级 npm 后重试:npm install -g npm@latest',\n reportIssue: '去插件仓库提交 Issue',\n detail: '打开详情',\n noResult: '没有找到匹配的插件',\n noResultDesc: '换个关键词试试,或前往网站浏览全部插件。',\n today: '今天更新',\n daysAgo: '更新于 {days} 天前',\n monthsAgo: '更新于 {months} 个月前',\n yearsAgo: '更新于 {years} 年前',\n pluginsTotal: '结果 {n} 条插件',\n // 分类按钮不带数量,选中分类后在列表头部显示筛选结果数\n filterResults: '结果 {n} 条插件',\n more: '还有 {n} 个插件,去网站查看全部',\n browseAll: '浏览全部 {n} 个插件',\n verified: '已验证',\n // 版本与更新:有 release 比版本号;无 release 的仓库比仓库最近更新时间(有新提交即提示更新)\n version: '版本',\n update: '可更新',\n updateAvailable: '有更新',\n updateAvailableHint: '检测到更新:有版本号的仓库比对版本号,无版本号的仓库比对仓库最近更新时间',\n hubUpdateHint: '检测到 DSH Plugin Hub 新版本,点击查看更新内容并更新',\n hubUpdateTitle: 'DSH Plugin Hub 有新版本',\n hubUpdateDesc: 'v{version} 已发布,点击下方按钮即可更新,完成后需重启宿主生效。',\n hubUpdatePublished: '发布于',\n hubUpdateNotes: '更新记录',\n hubUpdateLater: '稍后再说',\n versionHint: '查看版本信息与更新记录',\n hubCurrentTitle: '当前版本',\n hubCurrentDesc: '你正在使用 v{version},已是最新版本。',\n hubUpToDate: '已是最新版本',\n // 头部「关注我们」弹窗:平台介绍 + 用户反馈群二维码(内容由 Worker /about Markdown 推送,非写死)\n followUs: '关注我们',\n aboutTitle: '关注我们',\n aboutDesc: '了解 DSH Plugin Hub 是做什么的,加入用户反馈群随时交流。',\n aboutEmpty: '内容暂未发布,敬请期待。',\n aboutUpdated: '更新于',\n empty: '该分类暂无插件',\n dataFrom: '数据源 api.dsh-plugin.org · 每日人工更新',\n}\n\nexport const en = {\n nav: 'Plugin Hub',\n title: 'DSH Plugin Hub',\n // Plugin counts are filled from the live /api/stats.json ({total}/{verified}), never hardcoded\n tagline: 'DSH Plugin Hub: a human-verified, free marketplace for DeepSeek Harness plugins',\n adBadge: 'Featured',\n ad: 'DSH Plugin Hub: {total} plugins indexed, {verified} human-verified, updated daily',\n search: 'Search plugins by name, description, tags…',\n all: 'All',\n sortStars: 'Stars',\n sortForks: 'Forks',\n sortUpdated: 'Recently updated',\n sortNewest: 'Newest added',\n sortAria: 'Plugin sort order',\n openHint: 'Open dsh-plugin.org',\n toggleLangHint: 'Switch language',\n githubHint: 'View source on GitHub',\n fork: 'Fork',\n loading: 'Loading plugin data…',\n failed: 'Failed to load plugin data',\n failedDesc: 'Please retry, or open the hub in your browser with the button above.',\n retry: 'Retry',\n install: 'Install',\n // AI-flagged plugins that may need command-line help (webInstallable=false): one-click install still allowed,\n // on failure the user is guided to copy the command into the dsh terminal\n cliOnlyHint: 'This plugin may need command-line help; if it fails, copy the command above and run it in your dsh terminal',\n 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)',\n toastCopied: 'Install command copied — paste it in your dsh terminal',\n installed: 'Installed',\n // Primary navigation: Market / Installed / Custom / Settings\n viewMarket: 'Market',\n viewInstalled: 'Installed',\n viewCustom: 'Custom',\n viewSettings: 'Settings',\n viewMarketHint: 'Browse and discover plugins',\n viewInstalledHint: 'Manage installed plugins',\n viewCustomHint: 'Install npm packages or GitHub sources manually',\n viewSettingsHint: 'Network sources and preferences',\n // Installed view\n installedEmpty: 'No plugins installed yet',\n installedEmptyDesc: 'Go to Custom to add an npm package or GitHub source manually',\n npmInstallLabel: 'npm package / command',\n npmInstallPlaceholder: 'npm install <pkg> or a bare package name',\n npmInstallExample: 'Native commands: npm install lodash, npm i lodash, pnpm add @scope/pkg',\n npmInstallExample2: 'Global CLI: npm install -g @scope/cli; or just type a package name like lodash',\n 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)',\n gitInstallLabel: 'GitHub source',\n gitInstallPlaceholder: 'Repository address',\n gitInstallExample: 'e.g. owner/repo or https://github.com/owner/repo',\n gitInstallInvalid: 'Enter a GitHub repository address, e.g. owner/repo or https://github.com/owner/repo',\n dshCmdLabel: 'DeepSeek Harness command',\n dshCmdPlaceholder: 'Paste an official dsh plugin command',\n dshCmdExample: 'e.g. dsh plugin --profile web add github:owner/repo',\n dshCmdInvalid: 'Paste an official dsh plugin install command (--profile required), e.g. dsh plugin --profile web add github:owner/repo',\n installHelp: 'Help',\n helpModalTitle: 'Supported command formats',\n 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',\n gitInstallHelp: 'owner/repo\\nhttps://github.com/owner/repo\\ngithub:owner/repo\\ngit+https://github.com/owner/repo.git\\ngit@github.com:owner/repo.git',\n dshCmdHelp: 'dsh plugin --profile web add <target>\\ndsh plugin --profile=web add <target>\\n\\t--profile is required and there is no -p shorthand; <target> can be an npm package or github:owner/repo',\n globalNpmHint: 'This installs CLI tools globally (npm install -g). They won\\'t appear in Installed and no host restart is needed.',\n installCliBtn: 'Install',\n // Install channel disabled (security-trust toggle off → card disabled, guides to settings)\n channelDisabledHint: 'This install channel is disabled — enable it in Settings → Security & Trust',\n goToSettings: 'Go to Settings',\n // Custom install view: standalone top-level section, description text\n customViewDesc: 'Manually install an npm package, a GitHub source, or paste an official dsh plugin command. Finished installs appear in Installed, marked as custom.',\n customLabel: 'Custom install',\n installedSearch: 'Search installed plugins…',\n installedFilterCatalog: 'Catalog',\n hubInstall: 'Hub',\n hubInstallHint: 'From the plugin hub catalog',\n manualInstall: 'Manual',\n manualInstallHint: 'Not from the catalog — installed via the command line',\n filterByLabel: 'Source',\n sortByLabel: 'Sort',\n sortName: 'Name',\n sortInstalledAt: 'Recent',\n detailTitle: 'Plugin details',\n detailCategory: 'Category',\n detailStats: 'Repo stats',\n statusLabel: 'Status',\n statusRunning: 'Running',\n statusPending: 'Restart pending',\n exampleLabel: 'DeepSeek Harness built-in example',\n exampleHint: 'DeepSeek Harness built-in example — not a marketplace dsh plugin, the host does not load it, no restart needed',\n restart: 'Restart',\n installedVersionLabel: 'Installed version',\n catalogLatest: 'latest in catalog',\n installPath: 'Install path',\n copyPath: 'Copy path',\n openFolder: 'Show in folder',\n openFolderFail: 'Could not open the folder — copy the path instead',\n revealFolder: 'Show in Finder',\n installedAtLabel: 'Installed at',\n lastUpdatedLabel: 'Last updated',\n detailCatalog: 'View details',\n packageName: 'Package',\n versionUpHint: 'v{from} → v{to} available — Update reinstalls in place',\n // Settings view: Updates & Sources / Security & Trust / Diagnostics / System Logs\n settingsUpdate: 'Update Settings',\n settingsUpdateDesc: 'Update checks and the network channels used for installs',\n settingsCheckOnStart: 'Check for updates on startup',\n settingsCheckOnStartDesc: 'Check installed plugins for new versions when the hub opens; you will be notified when updates are found',\n settingsAutoInstall: 'Auto-install updates',\n settingsAutoInstallDesc: 'Install detected updates in the background without asking (a host restart applies them)',\n settingsMirror: 'npm registry mirror',\n settingsMirrorDesc: 'Route npm installs and lookups through a mirror for unstable networks; leave empty for the official registry',\n mirrorOfficial: 'Official registry.npmjs.org',\n mirrorNpmmirror: 'Alibaba npmmirror',\n mirrorTencent: 'Tencent Cloud mirror',\n mirrorCustom: 'Custom mirror',\n settingsProxy: 'HTTP proxy',\n settingsProxyDesc: 'Route npm, git and catalog requests through this proxy; leave empty to connect directly',\n settingsSecurity: 'Security & Trust',\n settingsSecurityDesc: 'Toggles for the three command-line install channels: npm packages, GitHub sources and DSH commands',\n settingsEnableNpm: 'Enable npm installs',\n settingsEnableNpmDesc: 'Allow installing npm packages from the command line; turning this off rejects package-name installs',\n settingsEnableGit: 'Enable GitHub source installs',\n settingsEnableGitDesc: 'Allow installing from GitHub sources on the command line; turning this off rejects repository-address installs',\n settingsEnableDsh: 'Enable DSH command installs',\n settingsEnableDshDesc: 'Allow pasting a dsh plugin command to install; turning this off disables the command input',\n settingsDiagnostics: 'System Diagnostics',\n settingsDiagnosticsDesc: 'Check the connectivity of install channels: npm registry, GitHub and the catalog site',\n settingsLogs: 'System Logs',\n settingsLogsDesc: 'Local record of installs / uninstalls, settings changes and diagnostics — export the full log to troubleshoot',\n logsHeadHint: 'Records installs, uninstalls, settings changes and diagnostics; keeps the latest 2,000 entries',\n logsRefresh: 'Refresh log',\n logsExport: 'Export log',\n logsLoading: 'Reading log…',\n logsEmpty: 'No log entries yet',\n logsLoadFail: 'Failed to read the log; try again later',\n // Log-viewer dialog: a built-in window that loads the log in pages, filterable by type × level\n logModalTitle: 'Log viewer',\n logViewerOpen: 'Open log viewer',\n logViewerDesc: 'View the local log in a built-in window; filter by type and level to pinpoint install / uninstall / update incompatibilities',\n logPathLabel: 'Log file',\n logOpenFile: 'Reveal',\n logOpenFileTip: 'Reveal the log file in your system file manager',\n logOpenFileFail: 'Could not open; locate the file manually',\n logPathSettingTitle: 'Log Location',\n logPathSettingDesc: 'Stored in the host config directory by default — set a directory or a .log file path to store elsewhere',\n logPathPlaceholder: 'Leave empty for default',\n logPathReset: 'Reset to default',\n logPathResetHint: 'The field shows the location currently in use',\n logPathSave: 'Save',\n logPathSaving: 'Saving…',\n logPathSaved: 'Saved — new logs will be written there',\n logPathSaveFail: 'Could not save: the location is not writable',\n logPathChange: 'Change',\n logPathBrowse: 'Browse…',\n logPathBrowseFail: 'Folder picker unavailable — type the path manually',\n logCatAll: 'All types',\n logCatInstall: 'Install',\n logCatUninstall: 'Uninstall',\n logCatUpdate: 'Update',\n logCatDiagnostics: 'Diagnostics',\n logCatSettings: 'Settings',\n logCatSystem: 'System',\n logLvAll: 'All levels',\n logLvError: 'Error',\n logLvWarn: 'Warn',\n logLvSuccess: 'Success',\n logLvInfo: 'Info',\n logLvDebug: 'Debug',\n logSearchPlaceholder: 'Search event or message…',\n logLoadMore: 'Load more',\n logNoMore: 'All loaded · {n} total',\n logCount: '{n} entries',\n logEmptyFilter: 'No matching log entries',\n settingsDiagFail: 'Unreachable',\n // System diagnostics channel list: one-click full check + one row per channel, click to re-probe\n diagNpm: 'npm registry',\n diagGithub: 'GitHub',\n diagCatalog: 'Catalog site',\n diagOk: 'OK',\n diagChecking: 'Checking…',\n diagIdle: 'Not checked',\n diagRecheck: 'Click to re-check this channel',\n diagRunAll: 'Run diagnostics',\n diagHeadHint: '{n} channels — click any row to re-check it alone',\n diagSummaryRunning: 'Checking channels…',\n diagSummaryOk: 'All channels reachable',\n diagSummaryFail: 'Unreachable channel(s) — click a row to re-check',\n settingsEnvSnapshot: 'System version',\n settingsEnvSnapshotDesc: 'Copy host version and system info for pasting into issue reports',\n settingsEnvCopy: 'Copy',\n // Restore defaults: first-level menu + its own settings card\n settingsReset: 'Restore Defaults',\n settingsResetDesc: 'Restore update policy, npm mirror, proxy and security restrictions to factory defaults in one go',\n settingsResetDetail: 'Reset update policy, npm mirror, proxy and security restrictions to factory defaults',\n settingsResetRun: 'Restore Defaults',\n settingsResetConfirm: 'Restore Defaults',\n settingsResetConfirmDetail: 'Reset all settings to factory defaults? Update policy, npm mirror, proxy and security restrictions will be cleared.',\n // Startup update policy hints\n updatesFound: '{n} plugin(s) have updates — check the notification center',\n updateNoticeTitle: 'Update available',\n updateNoticeGo: 'Update',\n ignoreUpdateRun: 'Ignore this update',\n ignoreUpdateConfirmTitle: 'Ignore this update?',\n ignoreUpdateConfirmDetail: 'This version will no longer notify you. You will be alerted again when the next version is released.',\n ignoreUpdateConfirm: 'Ignore',\n uninstall: 'Uninstall',\n uninstalling: 'Removing…',\n uninstallTitle: 'Confirm uninstall?',\n uninstallDesc: 'The plugin will be removed from this environment.',\n uninstallDone: 'Uninstalled',\n uninstallFail: 'Removal failed — try again',\n uninstallResultTitle: 'Removed',\n uninstallResultDesc: 'The plugin has been removed from this environment.',\n confirmTitle: 'Confirm install',\n confirmDesc: 'Review the plugin repository source code carefully before installing.',\n confirmPlugin: 'Plugin',\n confirmSource: 'Source',\n confirmCommand: 'Command',\n copyInstallCommand: 'Copy install command',\n copyCmdLabel: 'Copy',\n copyUninstallCommand: 'Copy uninstall command',\n cancelUninstall: 'Cancel uninstall',\n uninstallConfirm: 'Confirm uninstall',\n installNow: 'Install',\n installing: 'Installing…',\n installDone: 'Installed',\n installResultTitle: 'Plugin installed successfully',\n installResultDesc: '',\n // Update semantics: the \"update\" action re-runs add in place — copy differentiates install vs update\n confirmUpdateTitle: 'Confirm update',\n updateNow: 'Update',\n updating: 'Updating…',\n queuedUpdateTitle: 'Queued for update…',\n updateResultTitle: 'Updated',\n updateResultDesc: 'The plugin has been updated to the latest version.',\n installFail: 'Install failed — copy the command instead',\n requestTimeout: 'Request timed out: GitHub may be unreachable or the network is unstable — try again later',\n confirmCancel: 'Cancel',\n doneBtn: 'Done',\n // Result view: some plugins need a restart to mount — offer restart now / later\n restartNow: 'Restart now',\n restartLater: 'Later',\n restarting: 'Restarting…',\n restartHint: 'Some plugins (such as plugin markets / top-level bundles) only take effect after a restart.',\n done: 'Done',\n restartPendingHint: 'Installed — takes effect after restart',\n restartPendingHintUninstall: 'Removed — cleaned up after restart',\n sectionPendingRestart: 'Pending restart',\n sectionInProgress: 'In progress',\n // 通知中心:安装/卸载任务成败的持久记录(工具栏铃铛入口按钮打开)\n notifications: 'Notifications',\n notificationsHint: 'View install/remove/update notifications',\n notificationsDesc: 'Every install, remove and update notice is logged here — even if you missed the prompt, you can always check back.',\n notificationsEmpty: 'No notifications yet',\n notificationsClear: 'Clear notifications',\n removeNotification: 'Remove this notification',\n queuedTitle: 'Queued…',\n queuedUninstallTitle: 'Queued for removal…',\n queuedHint: 'Queued — starts automatically after earlier tasks finish. You may close this window.',\n cancelTask: 'Cancel task',\n cancel: 'Cancel',\n cancelling: 'Cancelling…',\n errorTitle: 'Operation failed',\n errorTitleInstall: 'Install failed',\n errorTitleUninstall: 'Removal failed',\n errorPlugin: 'Plugin',\n errorClose: 'Got it',\n errorCopy: 'Copy error',\n errCopied: 'Error copied',\n failCopy: 'Copy full log',\n failIssueHint: 'Open a pre-filled issue on the author repo with this error log (includes catalog links)',\n failIssueBig: 'Report this bug to GitHub — contribute to open source',\n // prepare script actually failed (git tarball misses submodules/build output): a packaging issue of the plugin itself — file an issue\n 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.',\n // Pre-install / post-install guard hit ([packaging]): git distribution lacks build output, entry file missing = not adapted to the official default install method\n failPackagingHint: 'This plugin does not support the official default install method: its git distribution lacks the build output (the entry file declared in package.json is not in the repository), 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 or an npm release.',\n // native-module build scripts ignored by pnpm by default (e.g. node-pty, ERR_PNPM_IGNORED_BUILDS): only affects plugins with native deps — a dependency/packaging issue of the plugin itself, file an issue\n failIgnoredBuild: 'This plugin depends on a native module (e.g. node-pty) whose build script pnpm blocks by default, so the install fails — other plugins are unaffected. This is a dependency/packaging issue of the plugin itself. Please report it to the author repository and ask the author to switch to a prebuilt variant (e.g. node-pty-prebuilt-multiarch).',\n 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',\n 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',\n reportIssue: 'Report an Issue to the plugin repo',\n detail: 'Open details',\n noResult: 'No plugins match your search',\n noResultDesc: 'Try another keyword, or browse all plugins on the website.',\n today: 'updated today',\n daysAgo: 'updated {days}d ago',\n monthsAgo: 'updated {months}mo ago',\n yearsAgo: 'updated {years}y ago',\n pluginsTotal: 'Results: {n} plugins',\n // Category chips carry no counts; the filtered result count shows in the list header\n filterResults: 'Results: {n} plugins',\n more: '{n} more on the website',\n browseAll: 'Browse all {n} plugins',\n verified: 'Verified',\n // Version & updates: repos with a release are compared by tag; repos without one by last push time (new commits → update)\n version: 'Version',\n update: 'Update',\n updateAvailable: 'Update available',\n updateAvailableHint: 'An update was detected: repos with a release are compared by tag, repos without one by last push time',\n hubUpdateHint: 'A new DSH Plugin Hub version is available — click to view the changelog and update',\n hubUpdateTitle: 'A new DSH Plugin Hub version is available',\n hubUpdateDesc: 'v{version} has been released — click below to update, then restart the host to apply it.',\n hubUpdatePublished: 'Published',\n hubUpdateNotes: \"What's new\",\n hubUpdateLater: 'Later',\n versionHint: 'View version info and changelog',\n hubCurrentTitle: 'Current version',\n hubCurrentDesc: 'You are on v{version} — this is the latest version.',\n hubUpToDate: 'Up to date',\n // Header \"Follow us\" modal: platform intro + user feedback group QR (content pushed via Worker /about Markdown)\n followUs: 'Follow us',\n aboutTitle: 'Follow us',\n aboutDesc: 'Learn what DSH Plugin Hub does and join our user feedback group.',\n aboutEmpty: 'Content not published yet — stay tuned.',\n aboutUpdated: 'Updated',\n empty: 'No plugins in this category yet',\n dataFrom: 'Data from api.dsh-plugin.org · curated daily',\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Install target/command helpers: decide the install channel (npm package\n * vs explicit-HTTPS GitHub), build the display command and normalize a raw\n * install spec back to its owner/repo identity.\n */\nimport type { HubPlugin } from '../types.ts'\n\n/**\n * 安装通道决策(用户无感知):目录探测到 npm 包名 → 用 npm 包名安装\n * (走 npm registry tarball,更快、与 GitHub 网络无关);无 npm 包名 → git 直装。\n * 返回值 target 即传给后端 /install 的安装目标(npm 包名 或 owner/repo)。\n */\nexport function installTargetOf(p: HubPlugin): { target: string; via: 'npm' | 'github' } {\n const pkg = (p.source?.npmPackage ?? '').trim()\n const repo = (p.source?.repo ?? '').trim()\n if (pkg && repo) return { target: pkg, via: 'npm' }\n return { target: repo, via: 'github' }\n}\n\n/** 展示用安装命令(复制/弹窗):目录下发的权威命令优先(CLI-only 插件如 dsh-tui\n * 需专属 profile(--profile dsh-tui),无法从 repo/npm 包名推断,必须用官方命令);\n * 常规插件无目录命令时按通道回退生成:npm 显示包名,git 显示显式 HTTPS URL。 */\nexport function installCommandOf(p: HubPlugin, withProfile = false): string {\n const { target, via } = installTargetOf(p)\n if (via === 'npm') {\n const cmd = p.install?.command\n if (cmd) return cmd\n } else {\n const cmd = p.install?.githubCommand\n if (cmd) return cmd\n }\n return via === 'npm'\n ? `dsh plugin${withProfile ? ' --profile web' : ''} add ${target}`\n : `dsh plugin${withProfile ? ' --profile web' : ''} add git+https://github.com/${target}.git`\n}\n\n/** Normalize a task/install target to its owner/repo display identity. */\nexport function repoFromInstallTarget(value: string): string {\n const input = value.trim()\n if (/^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$/.test(input)) return input\n const patterns = [\n /^github:([^/]+)\\/([^/]+)$/i,\n /^(?:git\\+)?https:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?(?:[?#].*)?$/i,\n /^(?:git\\+)?ssh:\\/\\/(?:git@)?github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?(?:[?#].*)?$/i,\n /^git@github\\.com:([^/]+)\\/([^/]+?)(?:\\.git)?(?:[?#].*)?$/i,\n ]\n for (const pattern of patterns) {\n const match = pattern.exec(input)\n if (match !== null) return `${match[1]}/${match[2]}`\n }\n return value\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Constants: site URLs, category metadata and sort keys. Pure data — no\n * side effects, no network — so every consumer shares one definition.\n */\nimport type { LocaleId } from '../types.ts'\n\n/** 插件中心官网地址。 */\nexport const SITE_URL = 'https://dsh-plugin.org/'\n\n/** 插件中心源码仓库:头部右上角 GitHub 图标的跳转地址 */\nexport const GITHUB_URL = 'https://github.com/dshplugin/dsh-plugin-hub'\n\n/** Hub 自身在目录数据里的仓库标识:头部版本号旁的「可更新」徽标按它定位自己。 */\nexport const HUB_REPO = 'dshplugin/dsh-plugin-hub'\n\n/**\n * Hub 自我更新版本控制(接口中心 Pages:api.dsh-plugin.org,静态 JSON 发布)。\n * 发新版 = 在 api-center 的 releases/ 写发版记录 + 重新部署,hub.json 随之更新,\n * 所有已装用户的「可更新」徽标即可见,不再依赖主站目录数据管道。\n * 响应:{ version: string | null, publishedAt: string | null, notes: string | {zh,en} | null }\n */\nexport const HUB_UPDATE_URL = 'https://api.dsh-plugin.org/hub.json'\n\n/** 接口中心「关注我们」内容(静态 JSON,由 api-center 的 about.md 构建生成,Markdown)。 */\nexport const HUB_ABOUT_URL = 'https://api.dsh-plugin.org/about.json'\n\n/** 构建时由 tsdown 从 package.json 注入的插件版本号(见 tsdown.config.ts define)。 */\ndeclare const __PLUGIN_VERSION__: string\n\n/**\n * 插件当前版本号,供头部标题展示「DSH Plugin Hub v0.1.1」。\n * tsdown 构建时用 define 把 __PLUGIN_VERSION__ 替换成 package.json 的版本号;\n * node --test 直接 import 本模块时该标识符不存在,typeof 守卫兜底为空串。\n */\nexport const PLUGIN_VERSION: string =\n typeof __PLUGIN_VERSION__ === 'string' ? __PLUGIN_VERSION__ : ''\n\nexport const CATEGORY_ORDER = [\n 'interface', 'session', 'memory', 'tools', 'agent', 'workflow',\n 'integration', 'model', 'dev', 'knowledge', 'fun',\n]\n\n/** 分类标签按界面语言取词;未知 key 原样返回。 */\nexport function categoryLabel(\n map: Record<string, { zh: string; en: string }>,\n key: string,\n lang: LocaleId,\n): string {\n return map[key]?.[lang] ?? key\n}\n\nexport const CATEGORY_LABELS: Record<string, { zh: string; en: string }> = {\n interface: { zh: '界面与体验', en: 'UI & Experience' },\n session: { zh: '会话与消息', en: 'Sessions & Messages' },\n memory: { zh: '记忆与上下文', en: 'Memory & Context' },\n tools: { zh: '工具与能力', en: 'Tools & Capabilities' },\n agent: { zh: '技能与智能体', en: 'Skills & Agents' },\n workflow: { zh: '工作流与自动化', en: 'Workflow & Automation' },\n integration: { zh: '集成与连接', en: 'Integrations & Connections' },\n model: { zh: '模型与推理', en: 'Models & Reasoning' },\n dev: { zh: '开发与运维', en: 'Development & Operations' },\n knowledge: { zh: '数据与知识', en: 'Data & Knowledge' },\n fun: { zh: '娱乐', en: 'Entertainment' },\n}\n\n/** 分类 Tab 的紧凑标签(英文模式空间受限时使用)。 */\nexport const CATEGORY_SHORT_LABELS: Record<string, { zh: string; en: string }> = {\n interface: { zh: '界面体验', en: 'UI Exp' },\n session: { zh: '会话消息', en: 'Sessions' },\n memory: { zh: '记忆上下文', en: 'Memory' },\n tools: { zh: '工具能力', en: 'Tools' },\n agent: { zh: '技能智能体', en: 'Agents' },\n workflow: { zh: '工作流', en: 'Workflow' },\n integration: { zh: '集成连接', en: 'Integrations' },\n model: { zh: '模型推理', en: 'Models' },\n dev: { zh: '开发运维', en: 'Dev' },\n knowledge: { zh: '数据知识', en: 'Knowledge' },\n fun: { zh: '娱乐', en: 'Fun' },\n}\n\nexport const SORTS = ['sortStars', 'sortForks', 'sortUpdated', 'sortNewest'] as const\nexport type SortKey = (typeof SORTS)[number]\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Host repository: the local routes served by the DSH harness (installed\n * plugin table + environment snapshot). A host without the plugin's server\n * routes degrades to null / empty tables instead of throwing.\n */\nimport type { EnvInfo } from '../types.ts'\nimport type { InstalledVersionSignal } from '../logic/installed.ts'\n\nexport interface HostInstalled {\n installed: Record<string, string>\n versions: Record<string, InstalledVersionSignal>\n /** 每个依赖在系统上的安装目录(profile/node_modules/<包名>),宿主未提供为 null */\n paths: Record<string, string> | null\n /** 已加载进运行中 loader 的包名(官方 ctx.loader.entries() 对账):装完未重启的新插件不在其中 */\n loaded: string[] | null\n /** 真正的 dsh 插件包名(包内声明 dsh 配置 / 在 profile bundles 清单):非 dsh 插件(如官方示例仓库)装上也不会被宿主加载,不提示待重启 */\n dshCapable: string[] | null\n}\n\n/** 当前 profile 已安装插件表(npm 包名 -> manifest spec)+ 安装时记录的目录信号 + 安装路径 + 运行状态。 */\nexport async function fetchInstalled(): Promise<HostInstalled | null> {\n try {\n const res = await fetch('/dsh-plugin-hub/installed', { cache: 'no-store' })\n if (!res.ok) return null\n const data = await res.json() as {\n installed?: Record<string, string>\n versions?: Record<string, InstalledVersionSignal>\n paths?: Record<string, string>\n loaded?: string[]\n dshCapable?: string[]\n }\n return {\n installed: data.installed ?? {},\n versions: data.versions ?? {},\n paths: data.paths ?? null,\n loaded: data.loaded ?? null,\n dshCapable: data.dshCapable ?? null,\n }\n } catch {\n return null\n }\n}\n\nlet envPromise: Promise<EnvInfo | null> | null = null\n\n/** 在系统文件管理器里定位并打开已安装插件的目录(服务端 spawn open,跨平台);失败返回 false。 */\nexport async function revealInstallFolder(name: string): Promise<boolean> {\n try {\n const res = await fetch('/dsh-plugin-hub/open-path', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name }),\n cache: 'no-store',\n })\n return res.ok\n } catch {\n return false\n }\n}\n\n/** 在系统文件管理器里定位日志文件(服务端 spawn open,跨平台);失败返回 false。 */\nexport async function openLogFile(): Promise<boolean> {\n try {\n const res = await fetch('/dsh-plugin-hub/open-log', {\n method: 'POST',\n cache: 'no-store',\n })\n return res.ok\n } catch {\n return false\n }\n}\n\n/**\n * 系统目录选择器:弹原生文件夹对话框让用户挑日志存放目录(服务端 spawn\n * osascript / FolderBrowserDialog / zenity);选中返回绝对路径,取消或\n * 平台不支持(无 osascript / zenity)时返回 null。\n */\nexport async function chooseLogDir(): Promise<string | null> {\n try {\n const res = await fetch('/dsh-plugin-hub/choose-log-dir', {\n method: 'POST',\n cache: 'no-store',\n })\n if (!res.ok) return null\n const data = await res.json() as { path?: string }\n return typeof data.path === 'string' && data.path !== '' ? data.path : null\n } catch {\n return null\n }\n}\n\n/**\n * 宿主机器环境快照(/dsh-plugin-hub/env):提交 bug 时拼进 issue 正文。\n * 懒加载 + 模块级缓存:环境在会话期间不会变化;拉取失败降级为 null\n * (issue 链接照常生成,只是少环境段)。\n */\nexport function getEnv(): Promise<EnvInfo | null> {\n envPromise ??= fetch('/dsh-plugin-hub/env', { cache: 'no-store' })\n .then((res) => (res.ok ? (res.json() as Promise<EnvInfo>) : null))\n .catch(() => null)\n return envPromise\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Normalizer: maps the online API's short-key payload (s/o/n/vr/c/t/f/d/r/v/u/a/sg/fk)\n * to HubPlugin so rendering only ever sees one shape.\n */\nimport type { HubPlugin } from '../types.ts'\n\nexport function normalize(raw: Record<string, unknown>): HubPlugin {\n if (typeof raw.s === 'string') {\n return {\n slug: raw.s,\n ownerSlug: typeof raw.o === 'string' ? raw.o : undefined,\n displayName: typeof raw.n === 'string' ? raw.n : undefined,\n version: typeof raw.vr === 'string' ? raw.vr : undefined,\n category: typeof raw.c === 'string' ? raw.c : undefined,\n topics: Array.isArray(raw.t) ? (raw.t as string[]) : undefined,\n features: Array.isArray(raw.f) ? (raw.f as string[]) : undefined,\n description: typeof raw.d === 'string' ? raw.d : undefined,\n // source 双形态:字符串 repo,或 { repo, npmPackage } 对象\n source: typeof raw.r === 'string'\n ? { repo: raw.r }\n : raw.r !== null && typeof raw.r === 'object'\n ? {\n repo: typeof (raw.r as { repo?: unknown }).repo === 'string' ? (raw.r as { repo: string }).repo : undefined,\n npmPackage: typeof (raw.r as { npmPackage?: unknown }).npmPackage === 'string' ? (raw.r as { npmPackage: string }).npmPackage : undefined,\n }\n : undefined,\n // 安装信息:wi 仅在 false 时下发(缺省视为 true 可一键安装);\n // ic/igc = 目录下发的权威安装命令(npm/git 通道各一条,CLI-only 插件如 dsh-tui 必须用)\n install: raw.wi === false || typeof raw.ic === 'string' || typeof raw.igc === 'string'\n ? {\n webInstallable: raw.wi === false ? false : undefined,\n command: typeof raw.ic === 'string' ? raw.ic : undefined,\n githubCommand: typeof raw.igc === 'string' ? raw.igc : undefined,\n }\n : undefined,\n compatibility: typeof raw.v === 'string' ? { status: raw.v } : undefined,\n dates: {\n repoUpdatedAt: typeof raw.u === 'string' ? raw.u : undefined,\n addedAt: typeof raw.a === 'string' ? raw.a : undefined,\n },\n stats: {\n stargazers_count: typeof raw.sg === 'number' ? raw.sg : undefined,\n forks_count: typeof raw.fk === 'number' ? raw.fk : undefined,\n },\n }\n }\n return raw as unknown as HubPlugin\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Catalog repository: fetches the plugin directory and the collection stats\n * from the online API and normalizes them. Components never see URLs or\n * fetch — the repository is the only place that knows where data lives.\n */\nimport type { HubPlugin, LocaleId } from '../types.ts'\nimport { normalize } from '../logic/normalize.ts'\n\n// 目录/统计数据经服务端 /catalog 代理路由获取(curl 子进程注入设置里的代理),\n// 与 npm / git 安装通道同一代理口径 —— 浏览器不再直连 api.dsh-plugin.org。\nconst PROXY_BASE = '/dsh-plugin-hub/catalog'\nconst PLUGINS_URL = (lang: LocaleId) => `${PROXY_BASE}?lang=${lang}`\nconst STATS_URL = `${PROXY_BASE}?stats=1`\n\nasync function fetchJson(url: string): Promise<unknown> {\n const res = await fetch(url, { cache: 'no-store' })\n if (!res.ok) throw new Error(String(res.status))\n return res.json()\n}\n\n/** 目录插件列表(在线 API 已只返回 verified;过滤与排序由上层负责)。 */\nexport async function fetchCatalog(lang: LocaleId): Promise<HubPlugin[]> {\n const data = await fetchJson(PLUGINS_URL(lang))\n return (Array.isArray(data) ? data : []).map((item) => normalize(item as Record<string, unknown>))\n}\n\n/** 收录/精选统计(/api/stats.json);字段不完整返回 null。 */\nexport async function fetchStats(): Promise<{ total: number; verified: number } | null> {\n const s = await fetchJson(STATS_URL) as { total?: number; verified?: number }\n if (s && typeof s.total === 'number' && typeof s.verified === 'number') {\n return { total: s.total, verified: s.verified }\n }\n return null\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Hub meta repository: the Cloudflare Worker endpoints behind the self-update\n * check and the \"About us\" content. Failures degrade to null — the caller\n * decides how to fall back (no badge, placeholder copy), never throws.\n */\nimport type { HubAboutInfo, HubUpdateInfo } from '../types.ts'\nimport { HUB_ABOUT_URL, HUB_UPDATE_URL } from '../logic/constants.ts'\n\n/** 版本接口是 Pages 静态文件,默认带 CDN 缓存(Cache-Control: public, max-age=43200,\n * 即 12 小时),客户端 no-store 管不到 CDN 边缘,会拿到旧公告。\n * 静态资产请求免费且无限,因此所有版本检查一律带时间戳 query:URL 每次不同 →\n * CDN 缓存 key 不同 → 强制回源拉到最新公告,无任何配额顾虑。 */\nfunction busted(url: string): string {\n const sep = url.includes('?') ? '&' : '?'\n return `${url}${sep}_t=${Date.now()}`\n}\n\n/** Worker 版本控制中心:最新版本 + Markdown 变更记录;不可用返回 null。 */\nexport async function fetchHubUpdate(): Promise<HubUpdateInfo | null> {\n try {\n const res = await fetch(busted(HUB_UPDATE_URL), { cache: 'no-store' })\n if (!res.ok) return null\n const data = await res.json() as HubUpdateInfo | null\n if (!data) return null\n const version = typeof data.version === 'string' && data.version.length > 0 ? data.version : null\n if (version === null) return null\n return { version, publishedAt: data.publishedAt ?? null, notes: data.notes ?? null }\n } catch {\n return null\n }\n}\n\n/** Worker「关注我们」内容(平台介绍 + 反馈群二维码,Markdown);未推送返回 null。 */\nexport async function fetchHubAbout(): Promise<HubAboutInfo | null> {\n try {\n const res = await fetch(busted(HUB_ABOUT_URL), { cache: 'no-store' })\n if (!res.ok) return null\n const data = await res.json() as HubAboutInfo | null\n if (!data || data.content === null || data.content === undefined) return null\n const content = typeof data.content === 'string' || typeof data.content === 'object' ? data.content : null\n if (content === null) return null\n return { content, updatedAt: data.updatedAt ?? null }\n } catch {\n return null\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Installed-plugin model (pure logic, zero React/UI dependencies).\n *\n * Merges the local installed table (from the host's `/installed` route:\n * npm name → manifest spec) with the catalog projection into a single\n * `InstalledItem` view-model consumed by the Installed view. Also hosts the\n * install matching / update detection used by the market view, so both\n * views share one source of truth.\n */\nimport type { HubPlugin } from '../types.ts'\nimport { HUB_REPO } from './constants.ts'\nimport { repoFromInstallTarget } from './install-command.ts'\n\n/** 安装时记录的目录信号(versions 表项)。 */\nexport interface InstalledVersionSignal {\n version: string\n updatedAt: string\n installedAt?: string\n npmPackage?: string\n}\n\n/** 已安装项统一模型:目录元数据 + 宿主运行时信息的合并视图(驱动「已安装」tab)。 */\nexport interface InstalledItem {\n /** npm 包名(profile 依赖 key) */\n name: string\n /** manifest spec(github:owner/repo、git+https://…、或 npm 版本号) */\n spec: string\n /** 目录里匹配到的插件;目录外/未收录的安装为 null */\n plugin: HubPlugin | null\n /** 仓库身份(owner/repo);纯 npm 安装无法识别时为 null */\n repo: string | null\n /** 安装到系统上的路径(profile/node_modules/<包名>);宿主未提供为 null */\n installPath: string | null\n /** 安装时记录的目录版本(无记录为 null) */\n installedVersion: string | null\n /** 安装时间(ISO,无记录为 null) */\n installedAt: string | null\n /** 目录当前最新版本(仓库无 release 为 null) */\n catalogVersion: string | null\n /** 是否有可用更新(有版本比版本,无版本比仓库更新时间) */\n hasUpdate: boolean\n /** 是否已加载进运行中 loader(官方 ctx.loader 对账);false = 已安装但未挂载(装完未重启) */\n loaded: boolean\n /** 是否真正的 dsh 插件(包内声明 dsh 配置 / 在 profile bundles 清单):\n * 非 dsh 插件(如 GitHub 官方示例仓库)装上也不会被宿主加载,不提示「待重启」 */\n dshCapable: boolean\n}\n\n/** 安装时记录的目录信号(按仓库小写 key 查表)。 */\nfunction signalOf(repo: string | null, versions: Record<string, InstalledVersionSignal>): InstalledVersionSignal | null {\n if (!repo) return null\n return versions[repo.toLowerCase()] ?? null\n}\n\n/** 插件是否已安装:匹配 Git spec 中的 owner/repo,或 npm 通道安装的依赖包名;命中返回 npm 包名。 */\nexport function installedNameOf(\n plugin: HubPlugin,\n installed: Record<string, string>,\n versions: Record<string, InstalledVersionSignal>,\n): string | null {\n const repo = plugin.source?.repo\n if (!repo) return null\n const needle = repo.toLowerCase()\n for (const [name, spec] of Object.entries(installed)) {\n if (repoFromInstallTarget(spec).toLowerCase() === needle) return name\n }\n // npm 通道安装:profile 依赖 key 直接是 npm 包名。包名来源两处——目录数据(npmPackage),\n // 或服务端 npm 优先反查持久化的映射(versions[repo].npmPackage,覆盖组织 scope 与 GitHub\n // 用户名不一致、目录未下发包名的场景);命中任一并依赖 key 真实存在即视为已安装。\n // 只认 npm 安装的依赖(spec 无法解析出仓库身份):git/本地安装的依赖身份由仓库匹配决定,\n // 包名同名不代表同仓库——否则「git 装 A 仓库」会被「npm 包名同名但仓库不同」的目录条目\n // 误认领成已安装(假阳性),installedItems 里出现同 key 双条目,排序一变化就渲染出幽灵行。\n const pkg = ((plugin.source?.npmPackage || versions[repo.toLowerCase()]?.npmPackage) ?? '').toLowerCase()\n if (pkg) {\n for (const [name, spec] of Object.entries(installed)) {\n if (isRepoLike(repoFromInstallTarget(spec))) continue\n if (name.toLowerCase() === pkg) return name\n }\n }\n return null\n}\n\n/** 该插件安装时记录的目录版本(无记录/未安装 → null)。 */\nexport function installedVersionOf(plugin: HubPlugin, versions: Record<string, InstalledVersionSignal>): string | null {\n const repo = plugin.source?.repo\n if (!repo) return null\n return versions[repo.toLowerCase()]?.version ?? null\n}\n\n/**\n * 是否有更新:仅对已安装插件有意义。\n * 双信号判定——有 release 版本的比版本;无版本(repo 不打 tag)的比仓库最近更新时间\n * (repoUpdatedAt,ISO 字符串字典序 = 时间序),更新时间变新说明有新提交。\n */\nexport function hasUpdateOf(\n plugin: HubPlugin,\n installed: Record<string, string>,\n versions: Record<string, InstalledVersionSignal>,\n): boolean {\n if (installedNameOf(plugin, installed, versions) === null) return false\n const repo = plugin.source?.repo\n if (!repo) return false\n const rec = versions[repo.toLowerCase()]\n if (!rec) return false\n if (plugin.version) return plugin.version !== rec.version\n const current = plugin.dates?.repoUpdatedAt\n return Boolean(current && rec.updatedAt && current > rec.updatedAt)\n}\n\n/** 依赖 spec 能否解析出仓库身份(owner/repo 形态才算)。 */\nfunction isRepoLike(value: string): boolean {\n return /^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$/.test(value)\n}\n\n/** 已安装项 → 弹窗可用的伪插件对象:卸载确认弹窗只读名称/来源行,\n * 自定义安装(目录外)没有完整目录数据,用它把 InstalledItem 适配成 HubPlugin。 */\nexport function pluginOfItem(item: InstalledItem): HubPlugin {\n return {\n slug: item.name,\n displayName: item.plugin?.displayName ?? item.name,\n source: item.repo ? { repo: item.repo } : undefined,\n description: item.plugin?.description,\n }\n}\n\n/**\n * Hub 自身(本插件 dsh-plugin)的识别:三维互证,杜绝误伤同名第三方包。\n * 1) 依赖 key 固定为 `dsh-plugin`(本插件 npm 包名);\n * 2) spec 为 `file:`/`link:` 本地链接(hub 以 file: 安装进宿主);\n * 3) 或 spec 解析出的仓库身份就是自营仓库 `dshplugin/dsh-plugin-hub`。\n * 命中即视为宿主内置本体:永不出现在「自定义安装」里,卸载接口也早已对\n * 它 400 拒绝(服务端多维防线之一)——显示出来只会让用户误点卸载。\n */\nfunction isHubSelf(name: string, spec: string): boolean {\n if (name !== 'dsh-plugin') return false\n if (spec.startsWith('file:') || spec.startsWith('link:')) return true\n const repo = repoFromInstallTarget(spec)\n return isRepoLike(repo) && repo.toLowerCase() === HUB_REPO.toLowerCase()\n}\n\n/**\n * 构建已安装项列表:目录插件按命中关系合并(拥有完整元数据),\n * 剩余未认领的依赖 key 归为自定义安装(目录外,仅运行时信息)。\n */\nexport function installedItemsOf(\n plugins: HubPlugin[] | null,\n installed: Record<string, string>,\n versions: Record<string, InstalledVersionSignal>,\n paths: Record<string, string> | null,\n loadedNames: string[] | null,\n dshCapableNames: string[] | null,\n): InstalledItem[] {\n const items: InstalledItem[] = []\n // 已被目录条目认领的依赖 key:同一依赖只归属一个目录条目(React key 必须唯一,\n // 否则同名双条目排序一变化就渲染出幽灵行);剩余未认领的归自定义安装。\n const claimed = new Set<string>()\n // 目录匹配:遍历目录插件,命中 installedNameOf 即视为已安装并合并元数据\n for (const p of plugins ?? []) {\n const name = installedNameOf(p, installed, versions)\n if (name === null || claimed.has(name)) continue\n claimed.add(name)\n const repo = p.source?.repo ?? null\n const rec = signalOf(repo, versions)\n items.push({\n name,\n spec: installed[name],\n plugin: p,\n repo,\n installPath: paths?.[name] ?? null,\n installedVersion: rec?.version ?? null,\n installedAt: rec?.installedAt ?? null,\n catalogVersion: p.version ?? null,\n hasUpdate: hasUpdateOf(p, installed, versions),\n loaded: loadedNames?.includes(name) ?? false,\n dshCapable: dshCapableNames?.includes(name) ?? false,\n })\n }\n // 自定义安装:依赖表里没被任何目录插件认领的条目(命令行安装的目录外插件)\n for (const [name, spec] of Object.entries(installed)) {\n if (claimed.has(name)) continue\n // Hub 自身(本插件 dsh-plugin)由宿主内置加载,不是可管理的插件:永不进已安装列表,\n // 避免出现在「自定义安装」里被误点卸载(服务端卸载接口对它的 400 拒绝是最后一道防线)\n if (isHubSelf(name, spec)) continue\n const parsed = repoFromInstallTarget(spec)\n const repo = isRepoLike(parsed) ? parsed : null\n const rec = signalOf(repo, versions)\n items.push({\n name,\n spec,\n plugin: null,\n repo,\n installPath: paths?.[name] ?? null,\n installedVersion: rec?.version ?? null,\n installedAt: rec?.installedAt ?? null,\n catalogVersion: null,\n // 目录外没有目录信号可比,无法判断是否有更新\n hasUpdate: false,\n loaded: loadedNames?.includes(name) ?? false,\n dshCapable: dshCapableNames?.includes(name) ?? false,\n })\n }\n return items\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Catalog data + view state for the Plugin Hub section.\n *\n * Owns the online-data pipeline (live fetch from api.dsh-plugin.org), the local\n * installed-plugin table, and the filter/search/sort/install-status view\n * state, exposing the derived visible list and per-category counts.\n */\nimport { useEffect, useMemo, useState } from 'react'\nimport type { HubPlugin, LocaleId } from '../types.ts'\nimport { HUB_REPO, PLUGIN_VERSION } from '../logic/constants.ts'\nimport type { HubAboutInfo, HubUpdateInfo } from '../types.ts'\nimport type { SortKey } from '../logic/constants.ts'\nimport { fetchCatalog, fetchStats } from '../data/catalog.ts'\nimport { fetchHubAbout, fetchHubUpdate } from '../data/hub.ts'\nimport { fetchInstalled } from '../data/host.ts'\nimport {\n hasUpdateOf, installedItemsOf, installedNameOf, installedVersionOf,\n} from '../logic/installed.ts'\nimport type { InstalledItem, InstalledVersionSignal } from '../logic/installed.ts'\n\n/** 插件市场自身仓库:DSH Plugin Hub 不显示在目录里(自己不进自己的插件列表) */\nconst SELF_REPO = 'dshplugin/dsh-plugin-hub'\n\n/** 市场各排序的默认方向:全部按倒序(Star/Fork 多、更新/收录近的在前) */\nconst SORT_DEFAULT_DIR: Record<SortKey, 'asc' | 'desc'> = {\n sortStars: 'desc', sortForks: 'desc', sortUpdated: 'desc', sortNewest: 'desc',\n}\n\nexport function useCatalog(lang: LocaleId) {\n /** 目录插件(仅保留人工验证通过的条目) */\n const [plugins, setPlugins] = useState<HubPlugin[] | null>(null)\n /** Hub 自身目录条目(dshplugin/dsh-plugin-hub):目录过滤会排除自身(不进插件列表),\n * 此处单独保留,供头部「可更新」徽标 → 「直接更新」覆盖重装使用。 */\n const [hubPlugin, setHubPlugin] = useState<HubPlugin | null>(null)\n /** 收录/精选统计(官网 /api/stats.json 实时拉取) */\n const [stats, setStats] = useState<{ total: number; verified: number } | null>(null)\n const [failed, setFailed] = useState(false)\n const [reloadKey, setReloadKey] = useState(0)\n const [category, setCategory] = useState('all')\n const [query, setQuery] = useState('')\n const [sort, setSort] = useState<SortKey>('sortStars')\n /** 当前排序方向:点同一个排序按钮切换 正序/倒序;点新排序用该排序的默认方向(与已安装视图一致) */\n const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc')\n\n /** 点击排序按钮:同一按钮切换正/倒序,新按钮用默认方向 */\n function toggleSort(key: SortKey) {\n if (key === sort) setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))\n else { setSort(key); setSortDir(SORT_DEFAULT_DIR[key]) }\n }\n /**\n * 强制刷新 Hub 版本与「关注我们」信息:点击头部版本号/徽标时触发。\n * 挂载期的 useEffect 只在进入/reload 时拉一次,发版后已打开的界面点版本号\n * 仍显示旧数据;此处重新拉接口中心,最新版本与变更记录点击即见。\n * 失败静默为 null(弹窗兜底展示当前版本号),与挂载期拉取口径一致。\n */\n const refreshHub = async () => {\n // 版本接口已恒带时间戳绕过 CDN,手动/自动拉取都能拿到最新公告\n const [info, about] = await Promise.all([fetchHubUpdate(), fetchHubAbout()])\n setHubUpdateInfo(info)\n setHubAboutInfo(about)\n }\n\n /** 当前 profile 已安装插件:npm 包名 -> manifest spec(来自宿主本地路由) */\n const [installed, setInstalled] = useState<Record<string, string>>({})\n /** 安装时记录的目录信号:repo(小写) -> { version, updatedAt }(来自宿主本地路由);\n * npmPackage 为 npm 优先通道反查命中的包名映射(目录数据未下发时客户端靠它把依赖 key 匹配回仓库) */\n const [versions, setVersions] = useState<Record<string, InstalledVersionSignal>>({})\n /** 每个依赖在系统上的安装目录(profile/node_modules/<包名>),详情视图展示用 */\n const [installPaths, setInstallPaths] = useState<Record<string, string> | null>(null)\n /** 已加载进运行中 loader 的包名(官方 ctx.loader 对账):装完未重启的新插件不在其中 */\n const [loadedNames, setLoadedNames] = useState<string[] | null>(null)\n /** 真正的 dsh 插件包名(包内声明 dsh 配置 / 在 profile bundles 清单):非 dsh 插件不提示「待重启」 */\n const [dshCapableNames, setDshCapableNames] = useState<string[] | null>(null)\n /** Hub 自我更新信息:来自接口中心 Pages(api.dsh-plugin.org),与目录数据解耦 */\n const [hubUpdateInfo, setHubUpdateInfo] = useState<HubUpdateInfo | null>(null)\n /** 头部「关注我们」弹窗内容(平台介绍 + 反馈群二维码):来自接口中心 /about,Markdown 推送非写死 */\n const [hubAboutInfo, setHubAboutInfo] = useState<HubAboutInfo | null>(null)\n\n // 拉取目录 + 统计。在线 API 已只返回 verified;再过滤一次,保证只展示人工验证通过的插件。\n useEffect(() => {\n let cancelled = false\n setPlugins(null)\n setHubPlugin(null)\n setStats(null)\n setFailed(false)\n // 目录数据直拉:hub 自身版本由独立 Worker 版本控制中心管理,不再依赖主站版本号接口。\n const load = () => Promise.all([fetchCatalog(lang), fetchStats()])\n load()\n .then(([list, stats]) => {\n if (cancelled) return\n // 插件市场不显示自己:DSH Plugin Hub 从目录里排除自身条目,\n // 防止「自己出现在自己的插件列表里、还能自己安装自己」;统计计数同步减 1 保持与列表一致。\n // 目录数据已排除自身,此处再兜底过滤一次,防旧快照仍含自身条目。\n const hadSelf = list.some((p) => p.source?.repo === SELF_REPO)\n // 过滤前单独保留 hub 自身条目:它不进目录列表,但「可更新」徽标的直接更新需要它作为重装目标\n setHubPlugin(list.find((p) => p.source?.repo === SELF_REPO) ?? null)\n setPlugins(list.filter((p) => p.compatibility?.status === 'verified' && p.source?.repo !== SELF_REPO))\n if (stats) {\n setStats(hadSelf\n ? { total: stats.total - 1, verified: stats.verified - 1 }\n : { total: stats.total, verified: stats.verified })\n }\n })\n .catch(() => {\n if (!cancelled) setFailed(true)\n })\n return () => { cancelled = true }\n // lang 必须进依赖:切换界面语言要重新拉对应语言的数据文件,\n // 否则英文模式仍停留在 plugins.zh.json,描述/名称全是中文\n }, [reloadKey, lang])\n\n /** 刷新当前 profile 已安装插件表;宿主未挂本地路由时静默降级为空表。 */\n const refreshInstalled = async () => {\n const data = await fetchInstalled()\n if (data === null) return\n setInstalled(data.installed)\n setVersions(data.versions)\n setInstallPaths(data.paths)\n setLoadedNames(data.loaded)\n setDshCapableNames(data.dshCapable)\n }\n\n // 首次进入拉取已安装表(依赖宿主 webServer 服务)\n useEffect(() => { refreshInstalled() }, [])\n\n // Hub 自身版本检查走独立 Worker(版本控制中心):发新版后写一次 Worker KV,\n // 所有已装用户立即看到「可更新」+ Markdown 变更记录,不再依赖主站目录数据管道。\n // 失败静默降级为 null(徽标不出现,不影响目录本身加载)。\n useEffect(() => {\n let cancelled = false\n void fetchHubUpdate().then((info) => { if (!cancelled) setHubUpdateInfo(info) })\n return () => { cancelled = true }\n }, [reloadKey])\n\n // 「关注我们」内容走同一套 Worker:作者写好 Markdown(平台介绍 + 反馈群二维码)推送 /admin/about,\n // 客户端下次进入拉 /about 即可看到最新,非写死。失败静默为 null(弹窗展示兜底文案,不阻塞)。\n useEffect(() => {\n let cancelled = false\n void fetchHubAbout().then((info) => { if (!cancelled) setHubAboutInfo(info) })\n return () => { cancelled = true }\n }, [reloadKey])\n\n /** 插件是否已安装:匹配 Git spec 中的 owner/repo,或 npm 通道安装的依赖包名;命中返回 npm 包名。 */\n const installedName = (p: HubPlugin): string | null => installedNameOf(p, installed, versions)\n\n /** 该插件安装时记录的目录版本(无记录/未安装 → null)。 */\n const installedVersion = (p: HubPlugin): string | null => installedVersionOf(p, versions)\n\n /**\n * 是否有更新:仅对已安装插件有意义。\n * 双信号判定——有 release 版本的比版本;无版本(repo 不打 tag)的比仓库最近更新时间\n * (repoUpdatedAt,ISO 字符串字典序 = 时间序),更新时间变新说明有新提交。\n */\n const hasUpdate = (p: HubPlugin): boolean => hasUpdateOf(p, installed, versions)\n\n /** 已安装项统一列表(目录元数据 + 运行时信息合并):驱动「已安装」tab。 */\n const installedItems = useMemo<InstalledItem[]>(\n () => installedItemsOf(plugins, installed, versions, installPaths, loadedNames, dshCapableNames),\n [plugins, installed, versions, installPaths, loadedNames, dshCapableNames],\n )\n\n /**\n * Hub 自身是否有可用更新:Hub 就是当前运行的应用(始终已安装,无需 installedName 命中)。\n * 以 Worker 版本控制中心返回的「最新版本」为准,与当前运行的版本号比对——\n * 构建时注入的 PLUGIN_VERSION 是运行 bundle 的真实版本;测试/异常场景缺失时\n * 回退到安装时记录的版本。版本号不等即新版(版本号只在发版时变更,绝无降级场景)。\n */\n const hubHasUpdate = (() => {\n if (!hubUpdateInfo) return false\n const current = PLUGIN_VERSION || versions[HUB_REPO]?.version || null\n return current !== null && hubUpdateInfo.version !== current\n })()\n\n /** 当前分类下的插件(「全部」时为整个目录)。 */\n const categoryPlugins = useMemo(() => {\n if (!plugins) return []\n if (category === 'all') return plugins\n return plugins.filter((p) => p.category === category)\n }, [plugins, category])\n\n const visible = useMemo(() => {\n if (!plugins) return []\n const q = query.trim().toLowerCase()\n const list = plugins.filter((p) => {\n if (category !== 'all' && p.category !== category) return false\n if (!q) return true\n return (\n (p.displayName ?? '').toLowerCase().includes(q) ||\n (p.description ?? '').toLowerCase().includes(q) ||\n (p.topics ?? []).some((topic) => topic.toLowerCase().includes(q))\n )\n })\n const dir = sortDir === 'asc' ? 1 : -1\n return [...list].sort((a, b) => {\n // 比较器统一用「升序写法」再乘 dir:desc 时 dir=-1 翻成降序(Star/Fork 最多、更新/收录最近在前)\n if (sort === 'sortStars') return ((a.stats?.stargazers_count ?? 0) - (b.stats?.stargazers_count ?? 0)) * dir\n if (sort === 'sortForks') return ((a.stats?.forks_count ?? 0) - (b.stats?.forks_count ?? 0)) * dir\n if (sort === 'sortNewest') return (a.dates?.addedAt ?? '').localeCompare(b.dates?.addedAt ?? '') * dir\n return (a.dates?.repoUpdatedAt ?? '').localeCompare(b.dates?.repoUpdatedAt ?? '') * dir\n })\n }, [plugins, category, query, sort, sortDir, installed])\n\n /** Per-category plugin counts shown on the category chips. */\n const categoryCounts = useMemo(() => {\n const counts: Record<string, number> = {}\n for (const p of plugins ?? []) {\n if (p.category) counts[p.category] = (counts[p.category] ?? 0) + 1\n }\n return counts\n }, [plugins])\n\n return {\n plugins,\n hubPlugin,\n stats,\n failed,\n reload: () => setReloadKey((k) => k + 1),\n installed,\n installedItems,\n installedName,\n installedVersion,\n hasUpdate,\n hubHasUpdate,\n hubUpdateInfo,\n hubAboutInfo,\n refreshHub,\n refreshInstalled,\n category,\n setCategory,\n query,\n setQuery,\n sort,\n sortDir,\n toggleSort,\n visible,\n total: plugins?.length ?? 0,\n categoryCounts,\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Failure classification, issue-body summarization and persistent\n * install/remove notifications.\n *\n * Every settled task is recorded two ways: the server-side system log\n * (hub.log) and a client-side localStorage record that feeds the\n * notification center — so a result is never lost even when the dialog\n * was dismissed or nobody was watching the progress strip.\n */\nexport interface NotificationRecord {\n id: number\n kind: 'install' | 'uninstall' | 'update'\n /** true = 成功(轻量记录);false = 失败(message 携带完整错误日志) */\n ok: boolean\n /** owner/repo(可能为空:请求层失败但拿不到仓库时) */\n repo: string\n /** 失败时的完整错误日志;成功记录为空串 */\n message: string\n /** 更新提醒:目录里的新版本号(展示用;其余通知省略) */\n version?: string\n /** 实际执行的安装/卸载命令(issue 预填时如实展示);历史记录可能缺失 */\n command?: string\n /** 尝试过的安装方式(npm registry 反查 + 实际执行命令,按先后顺序):失败提 Issue 时贴给作者,便于反推正确的 npm 包名 */\n attempts?: string[]\n /** 结束时间(epoch ms) */\n at: number\n}\n\nconst KEY = 'gro.ngilp-hsd.failure-records'\nconst MAX = 50\n\n/** 运行时 localStorage 访问:类型上不依赖 DOM lib(Node 测试环境也能编译),浏览器里取 window。 */\nconst storage = (): Storage | undefined =>\n (globalThis as { localStorage?: Storage }).localStorage\n\n/** 读取本地通知记录(损坏/不可用时返回空列表,不抛错)。列表最新在前,全部保留,只由「清空」按钮手动移除。 */\nexport function loadNotifications(): NotificationRecord[] {\n try {\n const raw = storage()?.getItem(KEY)\n if (!raw) return []\n const list = JSON.parse(raw) as unknown\n if (!Array.isArray(list)) return []\n return list\n .filter((r): r is NotificationRecord =>\n !!r && typeof r === 'object' && typeof (r as { message?: unknown }).message === 'string')\n // ok 字段缺省时按失败渲染\n .map((r) => ({ ...r, ok: r.ok === true }))\n } catch {\n return []\n }\n}\n\nfunction save(list: NotificationRecord[]): void {\n try {\n storage()?.setItem(KEY, JSON.stringify(list))\n } catch {\n /* storage full / unavailable:仅保留内存态,界面仍可查看 */\n }\n}\n\n/** 追加一条通知记录并持久化,返回更新后的完整列表(最新在前,超上限裁剪)。\n * 每次成功/失败都各自留痕:同一插件的安装/卸载记录都完整保留、只由「清空」按钮手动移除,\n * 不会因后续操作被自动覆盖清除。 */\nexport function addNotification(record: Omit<NotificationRecord, 'id' | 'at'>): NotificationRecord[] {\n const prev = loadNotifications()\n let id = Date.now()\n while (prev.some((r) => r.id === id)) id += 1\n const next = [{ ...record, id, at: id }, ...prev].slice(0, MAX)\n save(next)\n return next\n}\n\n/** 记录一次失败:携带完整错误日志,供通知中心查看/复制/提 Issue。 */\nexport function addFailure(record: Omit<NotificationRecord, 'id' | 'at' | 'ok'>): NotificationRecord[] {\n return addNotification({ ...record, ok: false })\n}\n\n/** 记录一次成功:轻量记录,不带日志。 */\nexport function addSuccess(record: Omit<NotificationRecord, 'id' | 'at' | 'ok' | 'message'>): NotificationRecord[] {\n return addNotification({ ...record, ok: true, message: '' })\n}\n\n/** 记录一条「发现新版本」更新提醒:成功类轻量记录,携带目录新版本号供通知中心展示。\n * 同一插件同一新版本已在通知中心时跳过:宿主重载会重新触发启动检查,不更新时\n * 通知里已有的提醒保持单条,不重复追加。 */\nexport function addUpdateNotice(record: Omit<NotificationRecord, 'id' | 'at' | 'ok' | 'message'>): NotificationRecord[] {\n const prev = loadNotifications()\n const dup = prev.some((r) =>\n r.kind === 'update' && r.repo === record.repo && (r.version ?? undefined) === (record.version ?? undefined))\n if (dup) return prev\n return addNotification({ ...record, ok: true, message: '' })\n}\n\n/** 已忽略的更新提醒持久化 key:`owner/repo@version` 字符串数组。 */\nconst IGNORE_KEY = 'gro.ngilp-hsd.ignored-updates'\n\n/** 读取已忽略的更新提醒(`owner/repo@version` 字符串集合);损坏/不可用时返回空集合。 */\nexport function loadIgnoredUpdates(): Set<string> {\n try {\n const raw = storage()?.getItem(IGNORE_KEY)\n if (!raw) return new Set()\n const list = JSON.parse(raw) as unknown\n if (!Array.isArray(list)) return new Set()\n return new Set(list.filter((x): x is string => typeof x === 'string'))\n } catch {\n return new Set()\n }\n}\n\nfunction saveIgnoredUpdates(ignored: Set<string>): void {\n try {\n storage()?.setItem(IGNORE_KEY, JSON.stringify([...ignored]))\n } catch {\n /* storage full / unavailable:仅保留内存态 */\n }\n}\n\n/** 忽略某插件本次更新(repo+version 持久化入忽略集):本次版本不再提醒,直到下一个新版本发布。 */\nexport function ignoreUpdate(repo: string, version?: string): Set<string> {\n const next = loadIgnoredUpdates()\n next.add(`${repo}@${version ?? ''}`)\n saveIgnoredUpdates(next)\n return next\n}\n\n/** 移除某插件某版本的更新提醒记录(忽略本次更新时一并清理通知),返回更新后的列表。 */\nexport function removeUpdateNotice(repo: string, version?: string): NotificationRecord[] {\n const next = loadNotifications().filter((r) =>\n !(r.kind === 'update' && r.repo === repo && (r.version ?? undefined) === (version ?? undefined)))\n save(next)\n return next\n}\n\n/** 清空全部通知记录,返回空列表。 */\nexport function clearNotifications(): NotificationRecord[] {\n save([])\n return []\n}\n\n/** 按 id 删除单条通知记录,返回更新后的列表(仅移除该条,不影响其余记录)。 */\nexport function removeNotification(id: number): NotificationRecord[] {\n const next = loadNotifications().filter((r) => r.id !== id)\n save(next)\n return next\n}\n\nexport type FailureKind = 'npmTooOld' | 'pnpmIgnoredBuild' | 'pluginPrepare' | 'repo'\n\n/**\n * 失败归类,四态。无论底层机制如何(pnpm 白名单拦截 / 构建脚本被忽略 / prepare 失败),\n * 对用户而言结果都一样 —— 当前安装通道(npm 或 git)装不上,就是插件分发/依赖的问题,\n * 一律引导提 Issue;唯一例外是本机 npm 自身版本过低导致的内部崩溃(见 npmTooOld):\n * - npmTooOld:失败输出含 npm arborist 的 `edgesOut` 崩溃特征(build-ideal-tree.js 解 peer 依赖时\n * 内部抛错,npm 11.6.0 前必现的已知缺陷,npm/cli#8261、#9787),或服务端已核实本机版本低于\n * 阈值并打了 `[npm-too-low]` 标记 —— 是本机 npm 版本过低/自身缺陷,不是插件问题 → 引导升级 npm\n * - pnpmIgnoredBuild:插件依赖里的原生模块构建脚本被 pnpm 默认拦截(如 node-pty,\n * `ERR_PNPM_IGNORED_BUILDS`)。只影响带原生模块的插件,其他插件不受影响 —— 差异在\n * 插件的依赖选择,属插件依赖/打包问题 → 引导去仓库提 Issue(建议改用预编译版本)\n * - pluginPrepare:插件的 prepare/构建脚本实际执行失败(git tarball 常因缺失子模块或\n * 构建产物导致)—— 属插件打包/分发问题,应引导去仓库提 Issue\n * - repo:其余失败(含 git prepare 被 pnpm 白名单拦截等),默认按插件仓库问题引导提 Issue\n */\nexport function classifyFailure(message: string): FailureKind {\n // npm 内部崩溃(edgesOut)或服务端 [npm-too-low] 标记:是本机 npm 版本过低/自身缺陷,\n // 不是插件问题 —— 必须最先判,否则该报错会被外层 ERR_PNPM_PREPARE_PACKAGE 吞成\n // 「插件打包分发问题」,误导用户去提 Issue\n if (/\\[npm-too-low\\]|edgesOut/i.test(message)) return 'npmTooOld'\n // 装后校验拦截(服务端 verifyInstalledEntry 标记):入口文件缺失 = git 分发缺构建产物,\n // 与 pluginPrepare 同类(插件打包/分发问题),引导去仓库提 Issue\n if (/\\[packaging\\]|entry file missing/i.test(message)) return 'pluginPrepare'\n // 原生模块构建被忽略(IGNORED_BUILDS)要在 prepare 判定之前:dsh 尾部固定提示语带\n // allowBuilds/pnpm-workspace.yaml,不能据此把插件自身问题误判成通用失败\n if (/ERR_PNPM_IGNORED_BUILDS|Ignored build scripts:/i.test(message)) return 'pnpmIgnoredBuild'\n // 再判 prepare 实际执行失败:只有构建脚本真的跑挂了才是插件问题\n if (/ERR_PNPM_PREPARE_PACKAGE|ELIFECYCLE|Command failed|prepare-guard/i.test(message)) return 'pluginPrepare'\n // 其余失败(含 git prepare 被 pnpm 白名单拦截):当前通道装不上 = 插件分发/依赖的问题,一律提 Issue\n return 'repo'\n}\n\n/** 从服务端 `[npm-too-low]` 标记行提取本机 npm 版本(如 `[npm-too-low] npm@11.3.0` → \"11.3.0\");\n * 历史记录无标记时返回 null,前端据此决定提示文案是否带具体版本。 */\nexport function npmTooLowVersion(message: string): string | null {\n const m = message.match(/\\[npm-too-low\\]\\s*npm@(\\d+\\.\\d+\\.\\d+)/i)\n return m ? m[1] : null\n}\n\n/** 核心行特征:错误代码 / 生命周期脚本失败 / prepare 失败 / 描述性报错(子模块缺失、找不到等)/ 退出与宿主提示信息。 */\nconst CORE_LINE_RE = /ERR_[A-Z_]+|ELIFECYCLE|Command failed|prepare-guard|Failed to prepare|exit code|\\bprepare\\b|pnpm failed in profile|git-hosted plugins build|submodule|not found|cannot find|no such|unable to|fatal|missing|error/i\n/** 提交 issue 时正文里错误摘要的上限字符数。GitHub 请求行上限 8192 字节,\n * 固定模板与 URL 编码开销约 1~2K,核心错误(以 ASCII 日志为主)可安全带到 ~5K;\n * 仍超长时 pluginIssueUrl 会逐档缩小核心预算,最终 URL 不会超限。 */\nexport const MAX_CORE_CHARS = 5000\n/** 摘要里单行上限:允许构建 key 等长行也被截短。 */\nconst MAX_LINE_CHARS = 400\n\n/**\n * 核心错误收集器:从完整安装输出里挑出真正说明问题的行(错误代码、构建脚本失败、\n * 退出与宿主提示),去重后拼接,单行与总量都截断 —— 只把「重点 + 原因」带进 issue 正文,\n * 避免完整日志塞进 URL 导致请求过长。无关键行时退化为「头部 + 尾部」快照。\n * maxChars 可由调用方按最终 URL 长度收紧(pluginIssueUrl 超限时逐档缩小)。\n */\nexport function summarizeError(message: string, maxChars: number = MAX_CORE_CHARS): string {\n const seen = new Set<string>()\n const core: string[] = []\n for (const raw of message.split(/\\r?\\n/)) {\n const line = raw.trim()\n if (!line || !CORE_LINE_RE.test(line)) continue\n const short = line.length > MAX_LINE_CHARS ? `${line.slice(0, MAX_LINE_CHARS)}…` : line\n if (!seen.has(short)) {\n seen.add(short)\n core.push(short)\n }\n }\n let out: string\n if (core.length === 0) {\n // 无关键行时退化为「头部 + 尾部」快照:优先保尾部完整,头部按预算压缩,总长不超上限\n const tail = message.trimEnd().slice(-1000)\n const sep = '\\n…\\n'\n const headBudget = Math.max(maxChars - tail.length - sep.length, 0)\n const head = message.slice(0, 500).trim()\n out = `${head.length > headBudget ? head.slice(0, headBudget) : head}${sep}${tail}`\n } else {\n out = core.join('\\n')\n }\n return out.length > maxChars ? `${out.slice(0, maxChars)}\\n… (truncated)` : out\n}\n\n/** 提取首个错误代码(如 ERR_PNPM_PREPARE_PACKAGE),无则 null。 */\nexport function coreErrorCode(message: string): string | null {\n const m = message.match(/\\[?ERR_[A-Z_]+\\]?/)\n return m ? m[0].replace(/^\\[|\\]$/g, '') : null\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * URL builders: catalog detail pages, plugin site links and the pre-filled\n * GitHub issue URL used by the failure modal. Pure functions — the issue\n * URL stays within GitHub's 8192-byte request limit.\n */\nimport type { EnvInfo, HubPlugin, LocaleId } from '../types.ts'\nimport { GITHUB_URL, PLUGIN_VERSION, SITE_URL } from './constants.ts'\nimport { MAX_CORE_CHARS, classifyFailure, coreErrorCode, summarizeError } from './failures.ts'\n\n/** dsh-plugin.org 中文页挂在 /zh/ 前缀下,英文在根路径。 */\nexport function langPathOf(lang: LocaleId): string {\n return lang === 'zh' ? 'zh/' : ''\n}\n\n/**\n * 官网详情页两级路径:/plugins/{ownerSlug}/{slug};\n * 缺 ownerSlug 时从 repo 推导(卡片详情按钮与弹窗来源行共用)。\n */\nexport function pluginDetailUrl(plugin: HubPlugin, langPath: string): string {\n const repo = plugin.source?.repo ?? ''\n return `${SITE_URL}${langPath}plugins/${plugin.ownerSlug ?? repo.split('/')[0]?.toLowerCase() ?? ''}/${plugin.slug}`\n}\n\n/**\n * 失败弹窗里仓库地址的跳转目标:官网详情页(含插件收录信息),\n * 与 issue 正文的 Catalog 链接同一形式(单级 /plugins/{repo})。\n */\nexport function pluginSiteUrl(repo: string): string {\n return `${SITE_URL}plugins/${repo}`\n}\n\n/**\n * 一键反馈 GitHub Issue 的预填链接:标题带「来自 dsh-plugin.org」标识,正文只带\n * 核心信息 —— 原因判定 + 关键错误代码 + 尝试过的安装方式 + 宿主机器环境快照 +\n * 错误核心摘要(完整日志太长,塞进 URL 会被 GitHub 以「request URL too long」拒绝,\n * 故只收集重点)。错误弹窗、失败记录共用此逻辑。\n * env 取不到时为 null,链接照常生成、只是少环境段。\n * attempts(尝试过的安装方式,npm 反查 + 实际执行命令):作者看到我们查过/试过的命令,\n * 组织 scope 与 GitHub 用户名不一致时也能直接指认正确的 npm 包名。\n */\nexport function pluginIssueUrl(repo: string, message: string, env?: EnvInfo | null, command?: string, attempts?: string[]): string {\n const title = `[dsh-plugin.org | dsh-plugin-hub] Install/Remove failed: ${repo}`\n // 原因判定:按失败类型归类,便于作者判断问题是否出在插件侧。\n // [packaging](预检/装后校验拦截)单独列:无论走 npm 还是 git 通道,都是分发物不完整\n // (package.json 声明的入口文件在发布物里缺失),作者照此补齐即可。\n const kind = classifyFailure(message)\n const reason = /\\[packaging\\]/i.test(message)\n ? 'plugin distribution is incomplete — the entry file declared in package.json is missing from the published package (github tarball or npm package); please commit build output or publish a complete package'\n : kind === 'pluginPrepare'\n ? 'plugin prepare/build script failed during install (packaging/distribution issue)'\n : kind === 'pnpmIgnoredBuild'\n ? 'plugin depends on a native module whose build script pnpm blocks by default (use a prebuilt variant)'\n : 'plugin-side install failure'\n const code = coreErrorCode(message)\n // 按给定核心摘要预算构建完整预填 URL(含 URL 编码);预算可调,供超长时逐档缩小\n const build = (coreChars: number): string => {\n const body = [\n '## Summary',\n `- Cause: ${reason}`,\n ...(code ? [`- Key error: \\`${code}\\``] : []),\n '',\n // 来源说明:标题(链官网)+ 一句来源(链仓库)+ 实际执行的安装命令(含 --profile)与执行结果,链接由常量动态拼接\n `## [DSH Plugin 插件中心](${SITE_URL}) · 安装 Plugin 失败错误信息`,\n `本错误信息由 [dsh-plugin-hub](${GITHUB_URL}) 插件中心的安装程序自动生成,随本次安装失败一并提交。`,\n `- 实际执行的安装命令:\\`${command ?? `dsh plugin${env?.profile ? ` --profile ${env.profile}` : ''} add git+https://github.com/${repo}.git`}\\``,\n `- 执行结果:安装失败,未能安装该插件。`,\n // 尝试过的安装方式(npm 反查 + 实际执行命令,按先后顺序):作者据此反推正确的\n // npm 包名 —— 组织 scope 与 GitHub 用户名不一致时仅凭仓库名猜不到,作者看到我们\n // 查过/试过的命令就能直接指认\n ...(attempts && attempts.length > 0\n ? ['', '## Attempted install channels(已尝试的安装方式)', ...attempts.map((a) => `- ${a}`)]\n : []),\n // [packaging] 场景:说明两种官方安装通道(npm 包 / git 直装),当前插件在对应通道下分发不完整\n ...(/\\[packaging\\]/i.test(message)\n ? [\n '',\n '## 安装方式说明',\n 'DSH 插件支持两种官方安装通道:`dsh plugin add <npm-package>`(npm 分发,需发布完整构建产物)与 `dsh plugin add git+https://github.com/owner/repo.git`(Git 直装,仓库需提交构建产物或在 package.json 提供 `prepare` 脚本)。当前插件的分发物缺少 package.json 声明的入口文件,请按所用通道补齐后重新发布。',\n ]\n : []),\n '',\n '## Environment',\n `- Plugin: \\`${repo}\\``,\n // 宿主机器环境快照:便于作者本地复现;某字段缺失时如实写 unknown,不编造\n ...(env\n ? [\n `- DSH: ${env.dshVersion ? `v${env.dshVersion}` : 'unknown'}`,\n `- Plugin Hub: v${PLUGIN_VERSION}`,\n `- Node: ${env.nodeVersion}`,\n `- OS: ${env.platform} ${env.arch} (${env.release})`,\n `- Profile: \\`${env.profile}\\``,\n `- DSH Home: \\`${env.dshHome}\\``,\n ]\n : []),\n // 该插件在插件中心的收录位置(详情页链接)\n `- Catalog: [${pluginSiteUrl(repo)}](${pluginSiteUrl(repo)})`,\n '',\n '## Error (core)',\n '',\n '```',\n // 核心错误收集器:只挑关键行(错误代码/构建失败/退出信息),去重截断,URL 才不至于超长\n summarizeError(message, coreChars),\n '```',\n '',\n '---',\n // 底部署名:报错来自内置在 DeepSeek Harness 里的 dsh-plugin-hub 安装程序\n `This error was produced by the [dsh-plugin-hub](${GITHUB_URL}) installer bundled with DeepSeek Harness.`,\n ].join('\\n')\n return `https://github.com/${repo}/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`\n }\n // GitHub 请求行上限 8192 字节:先用宽松预算(最多 ~5K 核心错误)构建,超长再逐档缩小,保证最终 URL 不超限\n const MAX_URL_CHARS = 7600\n let url = build(MAX_CORE_CHARS)\n if (url.length > MAX_URL_CHARS) {\n for (const budget of [4000, 2500, 1400, 800, 400]) {\n url = build(budget)\n if (url.length <= MAX_URL_CHARS) break\n }\n }\n return url\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Language state for the section: follows the host (system) locale by\n * default, with an optional manual toggle that wins until the user changes\n * it back. Exposes the localized dictionary lookup `t()` plus the zh/en\n * language flag and the /zh/ URL path prefix.\n */\nimport { useState } from 'react'\nimport type { LocaleId, SectionProps } from '../types.ts'\nimport { en, zh } from '../locales.ts'\nimport { langPathOf } from '../logic/urls.ts'\n\nexport function useLanguage(locale: SectionProps['locale']) {\n /** 界面语言:默认跟随宿主(系统)语言;右上角按钮可手动切换,切换后以手动选择为准 */\n const [manualLang, setManualLang] = useState<LocaleId | null>(null)\n const lang: LocaleId = manualLang ?? locale.getSnapshot().active\n const langKey: LocaleId = lang === 'en' ? 'en' : 'zh'\n // dsh-plugin.org keeps zh pages under the /zh/ prefix; en is the root.\n const langPath = langPathOf(lang)\n\n // 界面语言跟随宿主(系统)locale 自动切换;宿主的 t() 绑定宿主 locale,\n // 这里基于本地字典自建翻译函数,与宿主 locale 保持一致。\n // (settings.section 的导航 label 仍在 apply 里用宿主 t(),跟随宿主语言。)\n const dict: Record<string, string> = langKey === 'en' ? en : zh\n const t = (key: string, params?: Record<string, string | number>): string => {\n const raw = dict[key] ?? key\n return params ? raw.replace(/\\{(\\w+)\\}/g, (_, k) => String(params[k] ?? '')) : raw\n }\n\n return {\n lang,\n langKey,\n langPath,\n t,\n toggleLang: () => setManualLang(lang === 'en' ? 'zh' : 'en'),\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Hub settings state: loaded once from the host's local /settings route\n * (persisted at ~/.dsh/profiles/<profile>/hub-settings.json), updated\n * optimistically. Every change POSTs the patch immediately so a toggled\n * switch survives a reload; a host without the server routes falls back to\n * the defaults and keeps working (settings simply do not persist).\n */\nimport { useCallback, useEffect, useState } from 'react'\n\nexport interface HubSettings {\n /** 启动时检查目录插件更新,发现可更新时在通知中心提示(安装不自动进行) */\n checkUpdatesOnStart: boolean\n /** npm 镜像源 registry 地址(空串 = 官方 https://registry.npmjs.org) */\n npmRegistry: string\n /** HTTP(S) 代理地址,用于 npm / git / 目录请求(空串 = 直连) */\n proxy: string\n /** 启用命令行安装 NPM 包(默认开) */\n enableNpmInstall: boolean\n /** 启用命令行安装 GitHub 源码(默认开) */\n enableGitInstall: boolean\n /** 启用命令行粘贴 dsh plugin 命令安装(默认开) */\n enableDshInstall: boolean\n /** 日志存放位置覆盖(空串 = 默认 ~/.dsh/profiles/<profile>/hub.log) */\n logPath: string\n}\n\nexport const DEFAULT_SETTINGS: HubSettings = {\n checkUpdatesOnStart: true,\n npmRegistry: '',\n proxy: '',\n enableNpmInstall: true,\n enableGitInstall: true,\n enableDshInstall: true,\n logPath: '',\n}\n\nasync function loadRemote(): Promise<HubSettings> {\n try {\n const res = await fetch('/dsh-plugin-hub/settings', { cache: 'no-store' })\n if (!res.ok) throw new Error(`settings ${res.status}`)\n const data = await res.json() as Partial<HubSettings>\n return { ...DEFAULT_SETTINGS, ...data }\n } catch {\n return DEFAULT_SETTINGS\n }\n}\n\nexport function useSettings() {\n const [settings, setSettings] = useState<HubSettings>(DEFAULT_SETTINGS)\n /** 服务端配置是否已加载:更新策略等启动期逻辑须等真实值,避免用默认值误触发 */\n const [ready, setReady] = useState(false)\n\n useEffect(() => {\n let alive = true\n void loadRemote().then((s) => {\n if (!alive) return\n setSettings(s)\n setReady(true)\n })\n return () => { alive = false }\n }, [])\n\n /** 部分更新:本地立即生效(乐观),同时 POST 持久化;持久化失败静默(本次会话仍生效)。 */\n const update = useCallback((patch: Partial<HubSettings>) => {\n setSettings((prev) => ({ ...prev, ...patch }))\n void fetch('/dsh-plugin-hub/settings', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(patch),\n cache: 'no-store',\n }).catch(() => { /* 宿主未挂路由:仅本次会话生效 */ })\n }, [])\n\n /** 重置为默认设置:本地立即回默认,同时通知服务端删除设置文件;失败静默。 */\n const reset = useCallback(() => {\n setSettings({ ...DEFAULT_SETTINGS })\n void fetch('/dsh-plugin-hub/settings/reset', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: '{}',\n cache: 'no-store',\n }).catch(() => { /* 宿主未挂路由:仅本次会话回默认 */ })\n }, [])\n\n return { settings, ready, update, reset }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Background install/remove task queue for the Plugin Hub.\n *\n * Mirrors the server-side FIFO active queue by polling /active, settles\n * vanished tasks against /status, and exposes the queue actions (install,\n * uninstall, cancel) plus the modal task lookups used by the dialogs.\n */\nimport { useEffect, useRef, useState } from 'react'\nimport type { HubPlugin, Translate } from '../types.ts'\nimport { installCommandOf, installTargetOf, repoFromInstallTarget } from '../logic/install-command.ts'\nimport type { InstalledItem } from '../logic/installed.ts'\n\n/** 安装/卸载请求超时(ms):服务端 preflight + npm 反查可能耗时(各自都有超时,合计约 20~30s),\n * 给足余量;超时主动中止,避免服务端 preflight 网络挂起时前端永久卡「安装中 0%」。 */\nconst REQUEST_TIMEOUT_MS = 60_000\n\n/** 客户端任务队列项:镜像服务端 active 任务(running 在前、pending 在后)。 */\nexport interface QueueTask {\n id: number\n kind: 'install' | 'uninstall'\n /** 展示目标:owner/repo(安装)或 npm 包名(卸载) */\n target: string\n /** 插件中文简介(入队时从插件数据带过来,轮询合并时保留):展示在仓库名下方,标识排队中的插件 */\n desc?: string\n /** 所属插件仓库(owner/repo):失败时错误弹窗据此提供「去仓库反馈」入口;卸载为 null */\n repo: string | null\n /** 安装时的目录信号快照(版本 + 仓库更新时间):任务成功后在本地记录,供「有更新」比对 */\n version?: string\n updatedAt?: string\n /** pending 排队中 / running 执行中 / cancelling 取消中(客户端乐观过渡态) */\n status: 'pending' | 'running' | 'cancelling'\n progress: number\n lines: string[]\n /** 乐观入队条目:点击安装后立即显示「正在安装中」,等 POST 响应回来再换成真实任务 id。\n * 服务端还没登记(preflight 中),轮询合并/消失检测都必须跳过,避免被当作已结束任务收尾。 */\n optimistic?: boolean\n /** 实际执行的安装命令(npm/git 通道随插件数据决定):失败时 issue 预填如实展示 */\n command?: string\n /** 尝试过的安装方式(npm registry 反查 + 实际执行命令,按先后顺序):失败时 issue 预填一并贴给作者 */\n attempts?: string[]\n /** 完成结果是否需要重启才生效(服务端任务终态带出;默认 true 保持老行为:弹窗给重启选项)。\n * 卸载时 loader 已即时移除 → false,结果视图只显示「完成」;true 时弹窗给「稍后重启/立即重启」,\n * 通知中心待重启条目(服务端登记)同步常驻,直到用户点「立即重启」。 */\n needsRestart: boolean\n}\n\n/** 客户端待重启项:镜像服务端内存列表 + 本地补齐的展示信息(简介/版本)。 */\nexport interface PendingRestart {\n /** owner/repo(展示用,已从安装目标归一化) */\n target: string\n /** 待重启语义:install 装完等挂载 / uninstall 卸完等清理 */\n kind: 'install' | 'uninstall'\n at: number\n desc?: string\n version?: string\n}\n\nexport interface TaskQueueOptions {\n t: Translate\n refreshInstalled: () => void\n /** 任务成功完成:viaModal 表示任务对应当前打开弹窗(弹窗切结果视图),否则走 Toast;repo 供成功通知记录;\n * needsRestart 表示该任务完成后是否仍需宿主重启(结果视图据此给「重启 / 仅完成」)。 */\n onInstallDone: (viaModal: boolean, repo: string | null, needsRestart: boolean) => void\n onUninstallDone: (viaModal: boolean, repo: string | null, needsRestart: boolean) => void\n /** 任务失败:完整输出或兜底文案 + 所属插件仓库 + 操作类型(安装/卸载)+ 实际执行的安装命令(issue 预填用,可缺省)+ 尝试过的安装方式(npm 反查/执行命令,可缺省)。 */\n onError: (message: string, repo: string | null, kind: 'install' | 'uninstall', command?: string, attempts?: string[]) => void\n /** 当前打开的安装/卸载弹窗插件:用于在弹窗内匹配进行中的任务。 */\n installPlugin: HubPlugin | null\n /** 当前打开的自定义安装(命令行)确认弹窗目标:与应用商店同一弹窗机制,匹配进行中的 custom 安装任务。 */\n installCustomTarget?: string | null\n /** 当前打开的全局 npm 安装(`npm install -g <pkgs>`)确认弹窗身份(包列表空格拼接):\n * 匹配服务端登记的全局安装任务(target = 包列表 join(' '))。 */\n installGlobalTarget?: string | null\n uninstallPlugin: HubPlugin | null\n /** 已安装视图发起的卸载目标(npm 包名):目录插件走 uninstallPlugin,自定义安装走包名直卸。 */\n uninstallName: string | null\n installedName: (p: HubPlugin) => string | null\n /** 待重启项展示信息补齐:按 owner/repo 从插件目录解析简介/版本;找不到返回 null。 */\n resolvePending: (repo: string) => { desc?: string; version?: string } | null\n}\n\nexport function useTaskQueue(opts: TaskQueueOptions) {\n const {\n t, refreshInstalled, onInstallDone, onUninstallDone, onError,\n installPlugin, installCustomTarget, installGlobalTarget, uninstallPlugin, uninstallName, installedName, resolvePending,\n } = opts\n const [queue, setQueue] = useState<QueueTask[]>([])\n const queueRef = useRef<QueueTask[]>([])\n /** 待重启列表(服务端内存态 + 本地展示信息补齐);与 queue 一样以 ref 为唯一事实来源。 */\n const [pendingRestarts, setPendingRestarts] = useState<PendingRestart[]>([])\n const pendingRef = useRef<PendingRestart[]>([])\n /** 本次会话内安装成功插件的展示信息(目标 → 简介/版本):轮询合并待重启列表时补齐,刷新后由 resolvePending 兜底。 */\n const pendingInfoRef = useRef<Map<string, { desc?: string; version?: string }>>(new Map())\n /** 保持最新的 resolvePending:轮询闭包捕获的是调用那一刻的目录状态,目录晚加载时也能补齐。 */\n const resolvePendingRef = useRef(resolvePending)\n resolvePendingRef.current = resolvePending\n /** 当前打开弹窗所对应的任务 id:该任务完成时弹窗切换为结果视图 */\n const modalTaskRef = useRef<number | null>(null)\n /** 已开始收尾但尚未结束的任务 id(服务端 /active 已消失 → 查 /status 中):并发轮询时跳过,避免重复收尾 */\n const settlingRef = useRef<Set<number>>(new Set())\n /** 轮询定时器句柄(队列清空/组件卸载时清理) */\n const pollRef = useRef<number | null>(null)\n /** 请求在途的目标集合(同步防重):双击安装/卸载时第二击直接忽略。\n * 本地队列任务要等 fetch 返回后才入队,仅靠 queueRef 检查拦不住请求窗口内的重复点击。 */\n const submittingRef = useRef<Set<string>>(new Set())\n /** 乐观入队临时 id 计数器:递减产生唯一负数,与服务端自增正数 id 永不冲突。 */\n const tempIdRef = useRef(0)\n /** 请求在途标记:弹窗据此禁用确认按钮,避免等待响应期间被再次点击。 */\n const [submitting, setSubmitting] = useState(false)\n\n /** 停止后台任务轮询(任务结束或组件卸载时清理)。 */\n const stopPoll = () => {\n if (pollRef.current !== null) {\n window.clearInterval(pollRef.current)\n pollRef.current = null\n }\n }\n\n /** 队列与待重启都清空才停轮询:待重启期间持续轮询,宿主一重启(内存列表清空)立刻感知并消失。 */\n const maybeStopPoll = () => {\n if (queueRef.current.length === 0 && pendingRef.current.length === 0) stopPoll()\n }\n\n // 组件卸载时兜底清理轮询定时器\n useEffect(() => stopPoll, [])\n\n /** 更新队列(同步镜像到 ref:queueRef 是唯一事实来源,state 只负责触发渲染,\n * 避免依赖 React updater 的异步调度时序导致 gone/stopPoll/防重复入队读到旧值)。 */\n const applyQueue = (updater: (prev: QueueTask[]) => QueueTask[]) => {\n const next = updater(queueRef.current)\n queueRef.current = next\n setQueue(next)\n }\n\n /** 解析服务端待重启列表(安装目标归一化为 owner/repo,与安装任务对齐)。 */\n const parsePendingRestarts = (value: unknown): PendingRestart[] => {\n if (!Array.isArray(value)) return []\n const out: PendingRestart[] = []\n for (const x of value) {\n if (typeof x !== 'object' || x === null) continue\n const target = (x as { target?: unknown }).target\n if (typeof target !== 'string' || target === '') continue\n const at = (x as { at?: unknown }).at\n out.push({\n target: repoFromInstallTarget(target),\n kind: (x as { kind?: unknown }).kind === 'uninstall' ? 'uninstall' : 'install',\n at: typeof at === 'number' ? at : 0,\n })\n }\n return out\n }\n\n /** 合并服务端待重启列表:保留已有展示信息,缺失时用会话内记录 / 目录解析补齐。 */\n const applyPending = (raw: PendingRestart[]) => {\n const prev = pendingRef.current\n const next = raw.map((p) => {\n const old = prev.find((q) => q.target === p.target)\n if (old?.desc !== undefined) return { ...p, desc: old.desc, version: old.version }\n const info = pendingInfoRef.current.get(p.target) ?? resolvePendingRef.current?.(p.target) ?? null\n return info ? { ...p, desc: info.desc, version: info.version } : p\n })\n pendingRef.current = next\n setPendingRestarts(next)\n }\n\n /** 向宿主记录某插件的安装时目录信号(version + updatedAt);version 为空时清除记录(卸载)。 */\n const syncInstalledVersion = async (repo: string | null, version: string | undefined, updatedAt: string | undefined) => {\n if (!repo) return\n try {\n await fetch('/dsh-plugin-hub/installed-version', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo, version: version ?? null, updatedAt }),\n })\n } catch {\n // 宿主未挂本地路由:静默忽略,仅本机展示受影响\n }\n }\n\n /** 后台任务结束(active 中消失后查终态确认):完成 → 刷新安装表 + 结果视图/toast;失败 → 完整错误弹窗 */\n const finishQueueTask = (ok: boolean, q: QueueTask, lines: string[]) => {\n applyQueue((prev) => prev.filter((x) => x.id !== q.id))\n if (ok) {\n refreshInstalled()\n if (q.kind === 'uninstall') {\n // 卸载成功:清掉本地版本记录\n void syncInstalledVersion(q.repo, undefined, undefined)\n onUninstallDone(modalTaskRef.current === q.id, q.repo, q.needsRestart)\n } else {\n // 安装成功:记录安装时的目录信号(版本 + 仓库更新时间),供「有更新」比对;\n // 同时缓存展示信息,待重启列表(服务端已登记)合并时直接补齐简介/版本\n void syncInstalledVersion(q.repo, q.version, q.updatedAt)\n pendingInfoRef.current.set(q.target, { desc: q.desc, version: q.version })\n onInstallDone(modalTaskRef.current === q.id, q.repo, q.needsRestart)\n }\n } else {\n // 失败:完整展示全部输出行(最新在前,逆序为日志阅读顺序),不裁剪\n const detail = lines.length > 0\n ? [...lines].reverse().join('\\n')\n : q.kind === 'uninstall' ? t('uninstallFail') : t('installFail')\n onError(detail, q.repo, q.kind, q.command, q.attempts)\n }\n maybeStopPoll()\n }\n\n /** 卸载成功收尾前的进度过渡:任务已在服务端结束,但保留本地展示,\n * 让进度条在 ~2.4s 内缓缓跑到 100% 再切结果/Toast,给用户一个交互过程,\n * 而不是命令一执行进度条就一闪消失。 */\n const settleDone = (q: QueueTask, lines: string[]) => {\n // 收尾动画期间停止轮询:任务已从服务端 /active 消失,无需再查;\n // 停掉可避免 pollQueue 的 gone 检测把它当「再消失一次」而重复收尾\n stopPoll()\n const from = Math.min(q.progress, 90) // 起点最多 90,给进度条留出跑满的缓冲空间\n const steps = 20\n const stepMs = 120 // 20 步 × 120ms = 2.4s\n let step = 0\n // 动画期间固定显示「卸载中」:任务实已结束,但进度在跑,与「排队中」文案更协调\n applyQueue((prev) => prev.map((x) => (x.id === q.id ? { ...x, status: 'running' as const } : x)))\n const timer = window.setInterval(() => {\n step += 1\n const progress = Math.round(from + (100 - from) * (step / steps))\n applyQueue((prev) => prev.map((x) => (x.id === q.id ? { ...x, progress } : x)))\n if (step >= steps) {\n window.clearInterval(timer)\n finishQueueTask(true, q, lines)\n // 队列若还有其它已在排队/执行的任务,恢复轮询继续盯;已清空则自然停住\n if (queueRef.current.length > 0) pollQueue()\n }\n }, stepMs)\n }\n\n /** 任务在 /active 中消失 = 已结束:查 /status 拿终态并收尾(cancelled 静默移除)。 */\n const settleTask = async (q: QueueTask) => {\n let status = 'failed'\n let lines: string[] = []\n let attempts: string[] | undefined\n try {\n const res = await fetch(`/dsh-plugin-hub/status?task=${q.id}`, { cache: 'no-store' })\n if (res.ok) {\n const data = await res.json() as { task?: { status?: string; lines?: string[]; attempts?: string[]; needsRestart?: unknown } }\n const task = data.task\n if (task !== undefined) {\n status = task.status ?? 'failed'\n lines = task.lines ?? []\n attempts = Array.isArray(task.attempts) ? task.attempts : undefined\n // 终态带出的「是否需要重启」覆盖本地(服务端 done 时按 loader 即时移除情况设置)\n const needsRestart = typeof task.needsRestart === 'boolean' ? task.needsRestart : q.needsRestart\n if (status === 'done') {\n const settled = { ...q, needsRestart }\n // 卸载成功走进度过渡动画;安装成功直接收尾\n if (q.kind === 'uninstall') settleDone(settled, lines)\n else finishQueueTask(true, settled, lines)\n return\n }\n if (status === 'failed') {\n // 服务端终态带出的尝试记录覆盖本地:以实际执行为准\n finishQueueTask(false, { ...q, attempts }, lines)\n return\n }\n }\n }\n } catch { /* 服务端不可达:按失败处理 */ }\n applyQueue((prev) => prev.filter((x) => x.id !== q.id)) // cancelled / 未知\n maybeStopPoll()\n }\n\n /** 轮询整个队列:合并服务端 /active(running 在前、pending 在后),\n * 消失的任务查终态收尾;队列清空即停止轮询。 */\n const pollQueue = () => {\n stopPoll()\n pollRef.current = window.setInterval(async () => {\n try {\n const res = await fetch('/dsh-plugin-hub/active', { cache: 'no-store' })\n if (!res.ok) throw new Error(`active ${res.status}`)\n const data = await res.json() as {\n tasks?: { id?: unknown; action?: unknown; target?: unknown; status?: unknown; progress?: unknown; lines?: unknown; attempts?: unknown; needsRestart?: unknown }[]\n pendingRestarts?: unknown\n }\n const active = (data.tasks ?? []).filter((a) => typeof a.id === 'number')\n const byId = new Map(active.map((a) => [a.id as number, a]))\n // 先捕获旧队列:gone 是「旧队列里服务端已消失的任务」的差集,必须在 applyQueue 更新前取\n const prevQueue = queueRef.current\n // 待重启列表同步(服务端内存态:宿主重启后自然变空,这里随之清空 UI)\n applyPending(parsePendingRestarts(data.pendingRestarts))\n // 合并:running 在前、pending 在后(与服务端一致),新出现任务补入队列\n applyQueue((prev) => {\n const next: QueueTask[] = []\n for (const a of active) {\n const id = a.id as number\n const prevTask = prev.find((q) => q.id === id)\n const isRemove = a.action === 'remove'\n next.push({\n id,\n kind: isRemove ? 'uninstall' : 'install',\n target: typeof a.target === 'string' ? repoFromInstallTarget(a.target) : (prevTask?.target ?? ''),\n desc: prevTask?.desc,\n repo: prevTask?.repo ?? (isRemove ? null : (typeof a.target === 'string' ? repoFromInstallTarget(a.target) : null)),\n // 安装时快照的目录信号:轮询合并时保留,任务成功后记录到本地\n version: prevTask?.version,\n updatedAt: prevTask?.updatedAt,\n status: a.status === 'running' ? 'running' : 'pending',\n progress: typeof a.progress === 'number' ? a.progress : prevTask?.progress ?? 0,\n lines: Array.isArray(a.lines) ? (a.lines as string[]) : (prevTask?.lines ?? []),\n attempts: Array.isArray(a.attempts) ? (a.attempts as string[]) : (prevTask?.attempts ?? []),\n needsRestart: typeof a.needsRestart === 'boolean' ? a.needsRestart : (prevTask?.needsRestart ?? true),\n })\n }\n // 保留乐观条目:服务端尚未登记(preflight 中),无真实 id,不能因 active 缺它就被合并吞掉\n const keepOpt = prev.filter((q) => q.optimistic && !next.some((x) => x.id === q.id))\n if (keepOpt.length > 0) next.push(...keepOpt)\n // 保留「已从服务端消失、但尚未收尾」的任务:收尾(settleTask)负责移除。\n // 若在这里提前摘除,卸载/安装完成的那一瞬队列会先变空,弹窗闪回「确认」态\n // (busy=false 且未 done),表现为「卸载中 → 卸载 → 卸载完成」的中间回退。\n const keepGone = prev.filter((q) =>\n !byId.has(q.id) && !next.some((x) => x.id === q.id) && q.status !== 'cancelling' && !q.optimistic)\n if (keepGone.length > 0) next.push(...keepGone)\n return next\n })\n // 本地有、服务端已消失 → 已结束:逐个查终态收尾\n // (cancelling 是客户端乐观过渡态,交给 cancelTask 的定时移除,不在轮询里提前收敛;\n // optimistic 是点击后尚未登记的占位,服务端 /status 查不到,跳过免误判成失败;\n // settling 是上一轮已开始收尾的任务,并发轮询直接跳过,避免重复收尾)\n const gone = prevQueue.filter((q) =>\n !byId.has(q.id) && q.status !== 'cancelling' && !q.optimistic && !settlingRef.current.has(q.id))\n for (const q of gone) {\n // 防御:同 id 任务可能已被上一轮收尾移除(极端时序下轮询合并出的重复条目),跳过避免重复收尾\n if (!queueRef.current.some((x) => x.id === q.id)) continue\n settlingRef.current.add(q.id)\n try { await settleTask(q) } finally { settlingRef.current.delete(q.id) }\n }\n } catch {\n // 服务端暂不可达:静默等待下一轮\n }\n }, 600)\n }\n\n // 刷新后恢复任务队列与待重启列表:任务注册表在服务端内存里,只要宿主进程没重启就还在;\n // 重新拉取 /active(数组)继续轮询,界面上显示「进行中」状态条,可展开查看实时输出。\n useEffect(() => {\n let cancelled = false\n const restore = async () => {\n try {\n const res = await fetch('/dsh-plugin-hub/active', { cache: 'no-store' })\n if (!res.ok) return\n const data = await res.json() as {\n tasks?: { id?: unknown; action?: unknown; target?: unknown; status?: unknown; progress?: unknown; lines?: unknown; attempts?: unknown; needsRestart?: unknown }[]\n pendingRestarts?: unknown\n }\n if (cancelled) return\n // 待重启:装完没重启的持久提醒,刷新页面也要恢复\n applyPending(parsePendingRestarts(data.pendingRestarts))\n const items: QueueTask[] = (data.tasks ?? [])\n .filter((a) => typeof a.id === 'number')\n .map((a) => {\n const isRemove = a.action === 'remove'\n // 服务端任务的 target:显式 HTTPS Git URL(安装)/ npm 包名(npm 安装/卸载)。\n // 恢复展示统一用 displayTarget(owner/repo,服务端固定传):npm 安装时 target 是包名,\n // 直接展示会让用户看到「安装方式」的内部细节,违背无感知原则;卸载保持包名(匹配已装表)。\n const display = typeof (a as { displayTarget?: unknown }).displayTarget === 'string' ? repoFromInstallTarget((a as { displayTarget: string }).displayTarget) : ''\n const fallback = typeof a.target === 'string' ? repoFromInstallTarget(a.target) : ''\n return {\n id: a.id as number,\n kind: (isRemove ? 'uninstall' : 'install') as 'install' | 'uninstall',\n target: isRemove ? fallback : (display || fallback),\n repo: isRemove ? null : (display || fallback),\n status: a.status === 'running' ? 'running' : 'pending',\n progress: typeof a.progress === 'number' ? a.progress : 0,\n lines: Array.isArray(a.lines) ? (a.lines as string[]) : [],\n attempts: Array.isArray((a as { attempts?: unknown }).attempts) ? ((a as { attempts: string[] }).attempts) : [],\n needsRestart: typeof (a as { needsRestart?: unknown }).needsRestart === 'boolean' ? (a as { needsRestart: boolean }).needsRestart : true,\n }\n })\n if (items.length > 0 || pendingRef.current.length > 0) {\n applyQueue((prev) => [...prev, ...items.filter((n) => !prev.some((p) => p.id === n.id))])\n // 刷新后恢复的任务同样保持折叠:摘要条提示进行中,点开才看明细/日志\n pollQueue()\n }\n } catch { /* host without the plugin's server routes */ }\n }\n void restore()\n return () => { cancelled = true }\n }, [])\n\n /** 弹窗动作:直接安装。请求宿主本地路由,任务进入服务端队列(FIFO),弹窗内实时显示进度。 */\n /** 安装入队核心:目录插件(catalog,后端走目录白名单)与命令行安装(custom,\n * 受安全开关控制)共用。队列条目一律用仓库名(repo)展示/防重,只有发给后端的\n * 实际安装目标(target)随通道变化(npm 包名 / github: 源)。 */\n const submitInstall = async (input: {\n /** 发给后端的实际安装目标:npm 包名或 github: 源(服务端再决定最终通道) */\n target: string\n /** 队列展示与防重用的仓库名 */\n repo: string\n desc?: string\n version?: string\n updatedAt?: string\n command: string\n source: 'catalog' | 'custom'\n /** 更新已安装目标(放行 add 覆盖重装) */\n update?: boolean\n /** 全局 npm 安装包列表(`npm install -g <pkgs>`):非空时服务端执行全局安装,不进任何 profile */\n globalNpm?: string[]\n }) => {\n // 防重复入队:同一目标已在排队/执行中则忽略\n if (queueRef.current.some((q) => q.kind === 'install' && q.target === input.repo)) return\n // 请求在途防重:任务要等响应回来才进本地队列,这之前再次点击(双击)直接忽略\n if (submittingRef.current.has(input.repo)) return\n submittingRef.current.add(input.repo)\n // 乐观入队:点击安装立即显示「正在安装中」,不等 POST 响应。\n // 服务端 /install 会先跑预检(preflight,可能耗时数秒)再入队,若等响应才入队列,\n // 用户点完安装立刻去看任务会看不到 —— 只有刷新后 restore 才拉回来。\n // 用负临时 id 占位,响应回来换成真实 task id;失败/出错则移除该占位。\n tempIdRef.current -= 1\n const tempId = tempIdRef.current\n modalTaskRef.current = tempId\n applyQueue((prev) => [...prev, {\n id: tempId, kind: 'install', target: input.repo, repo: input.repo, desc: input.desc,\n version: input.version, updatedAt: input.updatedAt,\n status: 'running', progress: 0, lines: [], optimistic: true,\n command: input.command,\n // 服务端登记后 /active 会带回真实尝试记录(npm 反查 + 执行命令),先占位空列表\n attempts: [], needsRestart: true,\n }])\n setSubmitting(true)\n const controller = new AbortController()\n const timeout = window.setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS)\n try {\n const res = await fetch('/dsh-plugin-hub/install', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n repo: input.target,\n display: input.repo,\n source: input.source,\n mode: input.update ? 'update' : undefined,\n ...(input.globalNpm && input.globalNpm.length > 0 ? { globalNpm: input.globalNpm } : {}),\n }),\n signal: controller.signal,\n })\n const data = await res.json() as { ok?: boolean; task?: number; error?: string; attempts?: string[] }\n if (!data.ok || typeof data.task !== 'number') {\n // 请求层失败(重复安装 409 / 参数错误 / 安全开关 403 等):移除乐观条目 + 完整错误弹窗\n applyQueue((prev) => prev.filter((x) => x.id !== tempId))\n // 同步 400(如预检拦截)服务端会附上已尝试的安装方式,issue 预填一并展示;\n // 用 || 而非 ?? :error 为空字符串时回退 HTTP 状态,避免复制出来是空白\n onError(data.error || `HTTP ${res.status}`, input.repo, 'install', input.command, data.attempts)\n return\n }\n const taskId = data.task\n modalTaskRef.current = taskId\n // 用真实任务 id 替换乐观占位,解除 optimistic 标记(此后归正常收尾/轮询处理)\n applyQueue((prev) => prev.map((x) => (x.id === tempId\n ? { ...x, id: taskId, optimistic: undefined }\n : x)))\n // 提前缓存展示信息:安装成功后服务端登记待重启,轮询合并时不用等目录解析\n pendingInfoRef.current.set(input.repo, { desc: input.desc, version: input.version })\n // 摘要条常驻顶部(含实时进度),明细面板保持折叠,想看时再点开\n pollQueue()\n } catch (err) {\n // 网络异常:移除乐观条目 + 兜底错误弹窗(附上底层原因,避免只剩一句笼统的「安装失败」)\n applyQueue((prev) => prev.filter((x) => x.id !== tempId))\n const aborted = (err as { name?: string } | null)?.name === 'AbortError'\n const reason = aborted\n ? t('requestTimeout')\n : err instanceof Error && err.message ? err.message : String(err ?? '')\n onError(reason ? `${t('installFail')} — ${reason}` : t('installFail'), input.repo, 'install', input.command)\n } finally {\n window.clearTimeout(timeout)\n submittingRef.current.delete(input.repo)\n setSubmitting(false)\n }\n }\n\n /** 目录插件安装:通道由目录数据(npmPackage)决定,走 catalog 白名单。 */\n const installNow = async (p: HubPlugin, opts?: { update?: boolean }) => {\n const repo = p.source?.repo ?? ''\n if (!repo) return\n // 安装通道决策(用户无感知):有 npm 包名 → 走 npm;否则 git 直装。\n const { target } = installTargetOf(p)\n if (!target) return\n await submitInstall({\n target,\n repo,\n desc: p.description,\n version: p.version,\n updatedAt: p.dates?.repoUpdatedAt,\n command: installCommandOf(p, true),\n source: 'catalog',\n update: opts?.update,\n })\n }\n\n /** 命令行安装:用户手输 npm 包名或 GitHub 地址,走 custom 源(受安全开关控制)。\n * update=true 时对已安装目标放行覆盖重装(与目录插件「更新」同一语义)。\n * 队列展示/防重一律用归一化身份(owner/repo 或 npm 包名):与服务端 /active 合并、\n * 弹窗目标匹配同口径,npm 包名透传不受影响。 */\n const installCustom = async (raw: string, opts?: { update?: boolean }) => {\n const target = raw.trim()\n if (!target) return\n const repo = repoFromInstallTarget(target)\n await submitInstall({\n target,\n repo,\n command: `pnpm add ${target}`,\n source: 'custom',\n update: opts?.update,\n })\n }\n\n /** 全局 npm 安装(官方 README 的 `npm install -g <pkgs>`):不进任何 profile、无需宿主重启。\n * 队列展示/防重用包列表空格拼接的身份(与服务端 target 同口径)。 */\n const installGlobalNpm = async (pkgs: string[], opts?: { update?: boolean }) => {\n const list = (pkgs ?? []).map((p) => p.trim()).filter((p) => p !== '')\n if (list.length === 0) return\n const identity = list.join(' ')\n await submitInstall({\n target: identity,\n repo: identity,\n command: `npm install -g ${identity}`,\n source: 'custom',\n globalNpm: list,\n update: opts?.update,\n })\n }\n\n /** 卸载入队核心:按 npm 包名直卸(目录插件与自定义安装共用,弹窗进度匹配同源)。 */\n const enqueueUninstall = async (name: string, repo: string | null, desc?: string) => {\n if (!name) return\n if (queueRef.current.some((q) => q.kind === 'uninstall' && q.target === name)) return\n // 请求在途防重:与安装一致,响应回来前再次点击直接忽略\n if (submittingRef.current.has(name)) return\n submittingRef.current.add(name)\n setSubmitting(true)\n const controller = new AbortController()\n const timeout = window.setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS)\n try {\n const res = await fetch('/dsh-plugin-hub/uninstall', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name, repo: repo ?? undefined }),\n signal: controller.signal,\n })\n const data = await res.json() as { ok?: boolean; task?: number; error?: string }\n if (!data.ok || typeof data.task !== 'number') {\n onError(data.error || `HTTP ${res.status}`, repo, 'uninstall')\n return\n }\n const taskId = data.task\n modalTaskRef.current = taskId\n applyQueue((prev) => [...prev, { id: taskId, kind: 'uninstall', target: name, desc, repo, status: 'pending', progress: 0, lines: [], needsRestart: true }])\n // 摘要条常驻顶部(含实时进度),明细面板保持折叠,想看时再点开\n pollQueue()\n } catch (err) {\n // 网络异常:附上底层原因,避免只剩一句笼统的「卸载失败」\n const aborted = (err as { name?: string } | null)?.name === 'AbortError'\n const reason = aborted\n ? t('requestTimeout')\n : err instanceof Error && err.message ? err.message : String(err ?? '')\n onError(reason ? `${t('uninstallFail')} — ${reason}` : t('uninstallFail'), repo, 'uninstall')\n } finally {\n window.clearTimeout(timeout)\n submittingRef.current.delete(name)\n setSubmitting(false)\n }\n }\n\n /** 弹窗动作:直接卸载(目录插件入口)。与安装同一队列机制,弹窗内实时显示进度。 */\n const uninstallNow = async (p: HubPlugin) => {\n const name = installedName(p)\n if (!name) return\n await enqueueUninstall(name, p.source?.repo ?? null, p.description)\n }\n\n /** 已安装视图动作:按已安装项卸载(覆盖目录外自定义安装,无目录数据也能卸)。 */\n const uninstallItem = async (item: InstalledItem) => {\n await enqueueUninstall(item.name, item.repo, item.plugin?.description)\n }\n\n /** 取消任务:排队中立即出队,执行中终止子进程;先标记「正在取消」短暂过渡后再移除。 */\n const cancelTask = async (id: number) => {\n if (modalTaskRef.current === id) modalTaskRef.current = null\n // 乐观标记「正在取消」,给用户一个可见反馈,而不是瞬间消失\n applyQueue((prev) => prev.map((q) => (q.id === id ? { ...q, status: 'cancelling' as const } : q)))\n try {\n await fetch('/dsh-plugin-hub/cancel', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n } catch { /* 服务端不可达:仍按取消处理,稍后移除 */ }\n // 短暂展示「正在取消」后移除;队列清空则停止轮询\n window.setTimeout(() => {\n applyQueue((prev) => prev.filter((x) => x.id !== id))\n maybeStopPoll()\n }, 700)\n }\n\n /** 打开新弹窗前清空任务匹配:避免旧任务 id 误匹配到新弹窗。 */\n const clearModalTask = () => { modalTaskRef.current = null }\n\n // 弹窗对应任务:优先当前弹窗发起任务,其次按目标匹配(重新打开弹窗 / 目标已在队列时也能展示实时进度)\n // 目录插件按 source.repo 匹配;命令行安装(custom)按归一化后的仓库身份/包名匹配;\n // 全局 npm 安装按包列表身份(空格拼接)匹配;\n // 排除 cancelling:取消中的任务不再关联到弹窗,弹窗回到「确认」态可重新操作\n const installModalTarget = installPlugin?.source?.repo\n ?? (installCustomTarget ? repoFromInstallTarget(installCustomTarget) : null)\n ?? installGlobalTarget ?? null\n const installModalTask = (installPlugin || installCustomTarget || installGlobalTarget)\n ? (queue.find((q) => q.id === modalTaskRef.current && q.kind === 'install' && q.status !== 'cancelling')\n ?? queue.find((q) => q.kind === 'install' && q.target === installModalTarget && q.status !== 'cancelling')\n ?? null)\n : null\n const uninstallModalTask = (uninstallPlugin || uninstallName)\n ? (queue.find((q) => q.id === modalTaskRef.current && q.status !== 'cancelling')\n ?? queue.find((q) => q.kind === 'uninstall' && q.target === (uninstallName ?? installedName(uninstallPlugin!) ?? '') && q.status !== 'cancelling')\n ?? null)\n : null\n\n return {\n queue,\n pendingRestarts,\n installModalTask,\n uninstallModalTask,\n submitting,\n installNow,\n installCustom,\n installGlobalNpm,\n uninstallNow,\n uninstallItem,\n cancelTask,\n clearModalTask,\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Inline SVG icons used across the client. Icons inherit currentColor so\n * they adapt to themes and disabled states automatically.\n */\nimport { createElement as h } from 'react'\nimport headerStyles from '../../styles/Header.module.css'\nimport modalStyles from '../../styles/Modal.module.css'\n\n/** 弹窗右上角关闭按钮图标:内联 SVG 十字(stroke 继承 currentColor),随按钮禁用态一起变淡。 */\nexport function CloseIcon() {\n return h('svg', {\n className: modalStyles.modalCloseIcon,\n viewBox: '0 0 16 16',\n width: 14,\n height: 14,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M3 3l10 10M13 3L3 13',\n stroke: 'currentColor',\n strokeWidth: 1.6,\n strokeLinecap: 'round',\n }))\n}\n\n/** 来源链接图标:链节(stroke 继承 currentColor),弹窗里官网收录地址旁提示「可点击跳转」。 */\nexport function LinkIcon() {\n return h('svg', {\n className: modalStyles.linkIcon,\n viewBox: '0 0 24 24',\n width: 13,\n height: 13,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71',\n stroke: 'currentColor',\n strokeWidth: 1.8,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71',\n stroke: 'currentColor',\n strokeWidth: 1.8,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }))\n}\n\n/** 帮助图标:圆圈 + 问号(stroke 继承 currentColor),自定义安装卡片标题旁的「帮助」按钮用。 */\nexport function HelpIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 13,\n height: 13,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('circle', {\n cx: 8, cy: 8, r: 6.3,\n stroke: 'currentColor', strokeWidth: 1.4,\n }),\n h('path', {\n d: 'M6.3 6.5a1.9 1.9 0 1 1 2.7 1.7c-.7.3-1 .8-1 1.4',\n stroke: 'currentColor', strokeWidth: 1.4, strokeLinecap: 'round',\n }),\n h('circle', { cx: 8, cy: 11.6, r: 0.95, fill: 'currentColor' }),\n )\n}\n\n/** 品牌 logo 图标:蓝紫渐变圆角方块 + 白色拼图块(2x2 错落),标题左侧的品牌标识。 */\nexport function LogoIcon() {\n return h('svg', {\n className: headerStyles.logoIcon,\n viewBox: '0 0 24 24',\n width: 20,\n height: 20,\n 'aria-hidden': 'true',\n },\n h('defs', null,\n h('linearGradient', { id: 'dshLogoGrad', x1: '0', y1: '0', x2: '1', y2: '1' },\n h('stop', { offset: '0%', stopColor: '#4f46e5' }),\n h('stop', { offset: '100%', stopColor: '#7c3aed' }),\n ),\n ),\n h('rect', { x: 1, y: 1, width: 22, height: 22, rx: 6, fill: 'url(#dshLogoGrad)' }),\n h('rect', { x: 5.5, y: 5.5, width: 5.5, height: 5.5, rx: 1.5, fill: '#ffffff' }),\n h('rect', { x: 13, y: 5.5, width: 5.5, height: 5.5, rx: 1.5, fill: '#ffffff', opacity: 0.55 }),\n h('rect', { x: 5.5, y: 13, width: 5.5, height: 5.5, rx: 1.5, fill: '#ffffff', opacity: 0.55 }),\n h('rect', { x: 13, y: 13, width: 5.5, height: 5.5, rx: 1.5, fill: '#ffffff' }),\n )\n}\n\n/** GitHub 图标:官方 GitHub Mark(octocat),fill 继承 currentColor,头部右上角源码链接用。 */\nexport function GitHubIcon() {\n return h('svg', {\n className: headerStyles.githubIcon,\n viewBox: '0 0 24 24',\n width: 18,\n height: 18,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12',\n }))\n}\n\n/** 复制图标:双层矩形(stroke 继承 currentColor),手动命令旁的复制按钮用。 */\nexport function CopyIcon() {\n return h('svg', {\n className: headerStyles.copyIcon,\n viewBox: '0 0 16 16',\n width: 12,\n height: 12,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('rect', {\n x: 5.5, y: 5.5, width: 7, height: 7, rx: 1.5,\n stroke: 'currentColor', strokeWidth: 1.4,\n }),\n h('path', {\n d: 'M10.5 5.5v-2a1.5 1.5 0 0 0-1.5-1.5H4.5A1.5 1.5 0 0 0 3 3.5v4A1.5 1.5 0 0 0 4.5 9h1',\n stroke: 'currentColor', strokeWidth: 1.4, strokeLinecap: 'round',\n }),\n )\n}\n\n/** 文件夹图标(Material folder):「在文件夹中显示」按钮用,fill 继承 currentColor。 */\nexport function FolderIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 13,\n height: 13,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z',\n }))\n}\n\n/** 下拉箭头图标:向下 V 形(stroke 继承 currentColor),下拉按钮触发器右侧提示可展开。 */\nexport function ChevronDownIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 12,\n height: 12,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M3.5 5.5L8 10l4.5-4.5',\n stroke: 'currentColor',\n strokeWidth: 1.6,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }))\n}\n\n/** 排序方向小箭头:正序(up) 朝上 / 倒序(down) 朝下,随 currentColor 着色,仅当前排序按钮显示 */\nexport function SortArrowIcon({ up }: { up: boolean }) {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 10,\n height: 10,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: up ? 'M4 9.5L8 5.5l4 4' : 'M4 6.5L8 10.5l4-4',\n stroke: 'currentColor',\n strokeWidth: 1.8,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }))\n}\n\n/** 插件中心图标:店面货架(stroke 继承 currentColor),一级导航「插件中心」tab 用。 */\nexport function MarketIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 16,\n height: 16,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M4 10L5.6 4.5h12.8L20 10',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M4 10a2.2 2.2 0 0 0 4.4 0 2.2 2.2 0 0 0 4.4 0 2.2 2.2 0 0 0 4.4 0',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M5 13v6.5A1.5 1.5 0 0 0 6.5 21h11a1.5 1.5 0 0 0 1.5-1.5V13',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 自定义安装图标:终端窗口 + 提示符(stroke 继承 currentColor),一级导航「自定义安装」tab 用。 */\nexport function TerminalIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 16,\n height: 16,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('rect', {\n x: 3, y: 4.5, width: 18, height: 15, rx: 2.5,\n stroke: 'currentColor', strokeWidth: 1.8,\n }),\n h('path', {\n d: 'M6.8 9.2l3.4 2.8-3.4 2.8',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M12.5 14.8h4.5',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round',\n }),\n )\n}\n\n/** 已安装图标:插件包(圆角方盒 + 盒盖线)+ 对勾(stroke 继承 currentColor),一级导航「已安装」tab 用。 */\nexport function InstalledIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 16,\n height: 16,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('rect', {\n x: 4.5, y: 6.5, width: 15, height: 13, rx: 2.5,\n stroke: 'currentColor', strokeWidth: 1.8,\n }),\n h('path', {\n d: 'M4.5 11h15',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round',\n }),\n h('path', {\n d: 'M9.2 15.2l2.1 2.1 3.6-4',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 通知铃铛图标:实心铃铛(fill 继承 currentColor),采用 Material 官方 notifications 路径,一级导航通知中心入口用。 */\nexport function BellIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 15,\n height: 15,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M12 22c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z',\n }))\n}\n\n/** 设置图标:实心齿轮(fill 继承 currentColor),采用 Material 官方 settings 路径,齿形清晰、辨识度高。 */\nexport function SettingsIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 16,\n height: 16,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41L9.25 5.35C8.66 5.59 8.12 5.92 7.63 6.29L5.24 5.33c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.22-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61L19.14 12.94zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z',\n }))\n}\n\n/** 更新与通道图标:循环同步箭头(fill 继承 currentColor),采用 Material 官方 sync 路径,设置左侧导航「更新与通道」用。 */\nexport function UpdatesIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 15,\n height: 15,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z',\n }))\n}\n\n/** 安全与信任图标:盾牌 + 对勾(stroke 继承 currentColor),设置左侧导航「安全与信任」用。 */\nexport function SecurityIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 15,\n height: 15,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M8 1.8L13.8 3.8v4.3c0 3.5-2.2 6.3-5.8 7.6-3.6-1.3-5.8-4.1-5.8-7.6V3.8L8 1.8z',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M5.6 8.1l1.7 1.7 3.2-3.4',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 诊断图标:心跳脉冲线(stroke 继承 currentColor),设置左侧导航「诊断」用。 */\nexport function DiagnosticsIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 15,\n height: 15,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M1.6 8h3l1.9-4.2 2.9 8.4 1.9-4.2h3.1',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 恢复默认图标:逆时针还原箭头(stroke 继承 currentColor),设置左侧导航「恢复默认」用。 */\nexport function ResetIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 15,\n height: 15,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M3 5.2A5.6 5.6 0 1 1 2.4 9.6',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M2.6 2.6v2.6h2.6',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 系统日志图标:文档纸 + 三行文字(stroke 继承 currentColor),设置左侧导航「系统日志」用。 */\nexport function LogsIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 15,\n height: 15,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M4.2 1.8h4.8l2.8 2.8v9.6H4.2z',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M9 1.8v2.8h2.8',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M5.6 9.2h4.8M5.6 11.2h4.8',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round',\n }))\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Inline progress block shared by the install and uninstall dialogs:\n * a real percentage bar (server-estimated, client-polled). No live terminal\n * window — pnpm emits nothing during git clone/build, so a log pane would be\n * empty for most of the run; failures surface their full output in ErrorModal.\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { TaskState } from '../../types.ts'\n\nexport function ProgressView({ task }: { task: TaskState }) {\n return h('div', { className: styles.progress },\n h('div', { className: styles.progressHead },\n h('span', { className: styles.progressText }, `${Math.round(task.progress)}%`),\n ),\n h('div', { className: styles.progressTrack },\n h('div', {\n className: task.status === 'failed' ? `${styles.progressFill} ${styles.progressFillFail}` : styles.progressFill,\n style: { width: `${task.progress}%` },\n }),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Dialog layer for the Plugin Hub: the install-confirm dialog, the uninstall\n * dialog and the global toast. Both dialogs lock themselves while a mutation\n * or restart is running, then switch to a result view offering an immediate\n * restart or a \"later\" deferral.\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { EnvInfo, HubPlugin, TaskState, ToastState, Translate } from '../../types.ts'\nimport { CloseIcon, CopyIcon, LinkIcon } from '../ui/icons.tsx'\nimport { ProgressView } from './ProgressView.tsx'\nimport { installCommandOf } from '../../logic/install-command.ts'\nimport { pluginDetailUrl, pluginIssueUrl, pluginSiteUrl } from '../../logic/urls.ts'\nimport { classifyFailure, npmTooLowVersion } from '../../logic/failures.ts'\n\n/** 完成结果视图:绿色对勾 + 标题/描述;\n * needsRestart=true(插件需重启才生效)→ 「稍后重启 / 立即重启」按钮对,点稍后重启后\n * 通知中心待重启条目常驻(服务端登记,内存态),直到用户点「立即重启」真正重启后才消失;\n * needsRestart=false(卸载已即时生效)→ 仅「完成」关闭。 */\nfunction ResultView({\n title, desc, t, restarting, needsRestart, onRestart, onClose,\n}: {\n title: string\n desc: string\n t: Translate\n restarting: boolean\n needsRestart: boolean\n onRestart: () => void\n onClose: () => void\n}) {\n return h('div', { className: styles.result },\n h('div', { className: styles.resultCheck },\n h('svg', {\n className: styles.resultCheckIcon,\n viewBox: '0 0 16 16',\n width: 20,\n height: 20,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M2.5 8.5l3.5 3.5 7.5-7.5',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n })),\n ),\n h('div', { className: styles.resultTitle }, title),\n desc ? h('div', { className: styles.resultDesc }, desc) : null,\n needsRestart\n ? h('div', null, [\n h('div', { className: styles.resultRestarting }, restarting ? t('restarting') : t('restartHint')),\n h('div', { className: styles.modalActions },\n h('button', { className: styles.restartLater, onClick: onClose, disabled: restarting }, t('restartLater')),\n h('button', { className: styles.restartNowWarning, onClick: onRestart, disabled: restarting },\n restarting ? t('restarting') : t('restartNow')),\n ),\n ])\n : h('div', { className: styles.modalActions },\n h('button', { className: styles.restartNow, onClick: onClose }, t('done'))),\n )\n}\n\nexport interface InstallModalProps {\n /** 目录插件(有完整元数据);命令行安装(custom)传 null 走 customTarget 模式 */\n plugin: HubPlugin | null\n /** 命令行安装目标(无目录元数据):提供时按裸目标展示确认/进度/结果,命令条显示 pnpm add <target> */\n customTarget?: string\n /** 全局 npm 安装(官方 README 的 `npm install -g <pkgs>`):提供时按包列表展示确认/进度/结果,\n * 命令条显示 npm install -g <pkgs> —— 装的是系统级 CLI 工具,不进插件列表、无需重启 */\n globalNpm?: string[]\n done: boolean\n task: TaskState | null\n t: Translate\n langPath: string\n restarting: boolean\n /** 已安装插件的覆盖更新(走同一条 add 命令原位重装,文案区分安装/更新) */\n update: boolean\n /** 仅命令行插件(webInstallable=false):不提供一键安装,只展示命令供复制到 dsh 终端 */\n cliOnly: boolean\n /** 安装请求在途(fetch 等待响应):此时任务尚未入队,需禁用确认按钮防止二次点击 */\n submitting: boolean\n /** 完成结果是否需重启才生效:true → 「稍后重启 / 立即重启」;false → 仅「完成」 */\n needsRestart: boolean\n onClose: () => void\n onCopy: () => void\n onInstall: () => void\n onRestart: () => void\n}\n\n/**\n * 信任确认弹窗:安装进入后台队列后弹窗仍可关闭(任务继续),\n * 只在本任务执行中展示实时进度;完成后切换为结果视图,与卸载一致。\n * 目录插件与命令行安装(customTarget 模式)共用同一套确认/进度/结果流程。\n */\nexport function InstallModal(props: InstallModalProps) {\n const { plugin, customTarget, globalNpm, done, task, t, langPath, restarting, submitting, update, cliOnly, needsRestart, onClose, onCopy, onInstall, onRestart } = props\n const busy = submitting || (task !== null && (task.status === 'pending' || task.status === 'running'))\n // 进行中标题带上插件名(中文「XX 插件安装中」;英文状态词在前更自然),并用状态色区分;\n // 命令行安装无插件元数据 → 直接用输入的目标展示;全局 npm 安装 → 包列表空格拼接\n const name = customTarget ?? (globalNpm !== undefined && globalNpm.length > 0 ? globalNpm.join(' ') : undefined) ?? plugin?.displayName ?? plugin?.slug ?? ''\n const busyTitle = (label: string) => langPath === 'zh/' ? `${name} 插件${label}` : `${label} ${name}`\n const title = busy\n ? task && task.status === 'pending'\n ? busyTitle(update ? t('queuedUpdateTitle') : t('queuedTitle'))\n : busyTitle(update ? t('updating') : t('installing'))\n : done\n ? update ? t('updateResultTitle') : t('installResultTitle')\n : update ? t('confirmUpdateTitle') : t('confirmTitle')\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: styles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', {\n className: busy\n ? `${styles.modalTitle} ${task && task.status === 'pending' ? styles.modalTitleQueued : styles.modalTitleBusy}`\n : styles.modalTitle,\n }, title),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: () => onClose(),\n }, h(CloseIcon)),\n ),\n done\n // 安装完成:结果视图(成功即生效,仅「完成」关闭);更新时标题/描述区分语义\n ? h(ResultView, {\n title: update ? t('updateResultTitle') : t('installResultTitle'),\n desc: update ? t('updateResultDesc') : t('installResultDesc'),\n t,\n restarting,\n needsRestart,\n onRestart,\n onClose,\n })\n // 确认/进行中:来源行 + 安装命令 + 实时进度 + 操作按钮\n : h('div', { className: styles.modalBody },\n h('div', { className: styles.trustHint }, t('confirmDesc')),\n h('div', { className: styles.modalRow },\n h('span', { className: styles.modalLabel }, t('confirmPlugin')),\n h('span', { className: styles.modalValue, title: name }, name),\n ),\n plugin?.source?.repo ? h('div', { className: styles.modalRow },\n h('span', { className: styles.modalLabel }, t('confirmSource')),\n // 来源仓库:可点击跳转官网收录详情页(新窗口打开)\n h('a', {\n className: styles.modalLink,\n href: pluginDetailUrl(plugin, langPath),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: plugin.source.repo,\n }, h(LinkIcon), plugin.source.repo),\n ) : null,\n // 手动命令条:整条点击即复制,右侧再放一个显式复制按钮;\n // 命令行安装(无目录数据)直接展示 pnpm add <target>;全局 npm 安装展示 npm install -g <pkgs>\n h('div', {\n className: styles.modalCmd,\n onClick: onCopy,\n title: t('copyInstallCommand'),\n role: 'button',\n tabIndex: 0,\n },\n h('span', { className: styles.modalCmdText },\n globalNpm !== undefined && globalNpm.length > 0\n ? `npm install -g ${globalNpm.join(' ')}`\n : customTarget ? `pnpm add ${customTarget}` : installCommandOf(plugin!)),\n h('span', { className: styles.modalCmdCopy }, h(CopyIcon), t('copyCmdLabel')),\n ),\n // 全局 npm 安装说明:装的是系统级 CLI 工具,不进插件列表、无需重启宿主\n globalNpm !== undefined && globalNpm.length > 0\n ? h('div', { className: styles.cliOnlyHint }, t('globalNpmHint'))\n : null,\n // AI 识别可能需要命令行辅助的插件(webInstallable=false):提示但不拦截,仍允许尝试一键安装\n cliOnly ? h('div', { className: styles.cliOnlyHint }, t('cliOnlyHint')) : null,\n task && task.status === 'pending' ? h('div', { className: styles.queuedHint }, t('queuedHint')) : null,\n task ? h(ProgressView, { task }) : null,\n // 安装失败:引导用户复制上方命令到 dsh 终端手动安装(如 node-pty 等原生依赖构建脚本需人工放行)\n task && task.status === 'failed' ? h('div', { className: styles.failedCopyHint }, t('failedCopyHint')) : null,\n h('div', { className: styles.modalActions },\n h('button', {\n className: styles.modalCopy,\n disabled: busy,\n onClick: onCopy,\n }, t('copyInstallCommand')),\n h('button', {\n className: styles.modalInstall,\n disabled: busy,\n onClick: onInstall,\n }, busy\n ? (task && task.status === 'pending'\n ? (update ? t('queuedUpdateTitle') : t('queuedTitle'))\n : (update ? t('updating') : t('installing')))\n : (update ? t('updateNow') : t('installNow'))),\n ),\n ),\n ),\n )\n}\n\nexport interface UninstallModalProps {\n plugin: HubPlugin\n done: boolean\n task: TaskState | null\n t: Translate\n langPath: string\n restarting: boolean\n /** 卸载请求在途(fetch 等待响应):此时任务尚未入队,需禁用确认按钮防止二次点击 */\n submitting: boolean\n /** 完成结果是否需重启才生效:true → 「稍后重启 / 立即重启」;false(loader 已即时移除)→ 仅「完成」 */\n needsRestart: boolean\n onClose: () => void\n onCancel: () => void\n onCopyCommand: () => void\n onConfirm: () => void\n onRestart: () => void\n}\n\n/** 卸载确认弹窗:确认/进行中(后台队列,可关闭);完成后切换为结果视图(成功即生效,仅「完成」关闭)。 */\nexport function UninstallModal(props: UninstallModalProps) {\n const { plugin, done, task, t, langPath, restarting, submitting, needsRestart, onClose, onCancel, onCopyCommand, onConfirm, onRestart } = props\n const busy = submitting || (task !== null && (task.status === 'pending' || task.status === 'running'))\n // 进行中标题带上插件名,与安装弹窗一致,并用状态色区分\n const name = plugin.displayName ?? plugin.slug\n const busyTitle = (label: string) => langPath === 'zh/' ? `${name} 插件${label}` : `${label} ${name}`\n const title = busy\n ? task && task.status === 'pending' ? busyTitle(t('queuedUninstallTitle')) : busyTitle(t('uninstalling'))\n : done ? t('uninstallResultTitle') : t('uninstallTitle')\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: styles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', {\n className: busy\n // 注意 task 判空:submitting(请求在途)时任务尚未入队,task 为 null,不能直接解引用\n ? `${styles.modalTitle} ${task !== null && task.status === 'pending' ? styles.modalTitleQueued : styles.modalTitleBusy}`\n : styles.modalTitle,\n }, title),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: () => onClose(),\n }, h(CloseIcon)),\n ),\n done\n // 卸载完成:结果视图(成功即生效,仅「完成」关闭)\n ? h(ResultView, {\n title: t('uninstallResultTitle'),\n desc: t('uninstallResultDesc'),\n t,\n restarting,\n needsRestart,\n onRestart,\n onClose,\n })\n // 确认/进行中:来源行 + 实时进度 + 操作按钮\n : h('div', { className: styles.modalBody },\n h('div', { className: styles.modalDesc }, t('uninstallDesc')),\n h('div', { className: styles.modalRow },\n h('span', { className: styles.modalLabel }, t('confirmPlugin')),\n h('span', { className: styles.modalValue, title: plugin.displayName ?? plugin.slug },\n plugin.displayName ?? plugin.slug),\n ),\n // 显示仓库来源:github 用户名 + 仓库名,让用户确认卸载的是哪一个仓库\n plugin.source?.repo ? h('div', { className: styles.modalRow },\n h('span', { className: styles.modalLabel }, t('confirmSource')),\n // 来源仓库:可点击跳转官网收录详情页(新窗口打开)\n h('a', {\n className: styles.modalLink,\n href: pluginDetailUrl(plugin, langPath),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: plugin.source.repo,\n }, h(LinkIcon), plugin.source.repo),\n ) : null,\n task && task.status === 'pending' ? h('div', { className: styles.queuedHint }, t('queuedHint')) : null,\n task ? h(ProgressView, { task }) : null,\n h('div', { className: styles.modalActions },\n // 复制卸载命令:万一直接卸载失败,可去终端手动执行\n h('button', {\n className: styles.modalCopy,\n disabled: busy,\n onClick: onCopyCommand,\n }, t('copyUninstallCommand')),\n // 确认框语义:取消动作需明确指向「卸载」,避免歧义\n h('button', {\n className: styles.modalCancel,\n onClick: onCancel,\n }, t('cancelUninstall')),\n h('button', {\n className: styles.uninstallConfirm,\n disabled: busy,\n onClick: onConfirm,\n }, busy ? (task && task.status === 'pending' ? t('queuedUninstallTitle') : t('uninstalling')) : t('uninstallConfirm')),\n ),\n ),\n ),\n )\n}\n\n/** 预填插件仓库的 GitHub Issue 链接:标题带插件名,正文附完整错误信息,方便用户一键反馈。 */\n/** 安装/卸载失败弹窗:布局与失败记录一致(类型徽标 + 仓库超链接 + 隐蔽复制按钮),报错完整展示,底部一键提交 Issue。 */\nexport function ErrorModal({ message, repo, kind, command, attempts, t, env, onCopy, onClose }: {\n message: string\n repo: string | null\n kind: 'install' | 'uninstall'\n command?: string\n /** 尝试过的安装方式(npm 反查 + 实际执行命令):issue 预填一并贴给作者,便于反推正确的 npm 包名 */\n attempts?: string[]\n t: Translate\n env: EnvInfo | null\n onCopy: (text: string) => void\n onClose: () => void\n}) {\n // 失败归类:当前安装通道(npm/git)装不上 = 插件分发/依赖的问题,一律引导提 Issue\n const failureKind = classifyFailure(message)\n // 服务端 [npm-too-low] 标记里带的本机 npm 版本(无标记为 null,提示文案降级为「怀疑」)\n const npmVersion = npmTooLowVersion(message)\n // 复制完整错误:实际执行/尝试过的安装命令(如有)+ 完整错误正文。\n // 只复制 message 会丢上下文 —— 命令行安装输入的目标、执行过的命令都在 command/attempts 里,\n // 光拷一句「unsupported install target」出去没人看得懂\n const copyText = [\n ...(command ? [command] : []),\n ...(attempts ?? []),\n message,\n ].join('\\n')\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: styles.errorModal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n // 标题按操作类型明确区分:安装失败 / 卸载失败\n h('div', { className: styles.errorTitle }, kind === 'install' ? t('errorTitleInstall') : t('errorTitleUninstall')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n // 与失败记录一致的布局:类型徽标 + 仓库超链接 + 顶部隐蔽复制按钮\n h('div', { className: styles.failRow },\n h('div', { className: styles.failHead },\n h('span', {\n className: kind === 'install' ? styles.failKindInstall : styles.failKindUninstall,\n }, kind === 'install' ? t('install') : t('uninstall')),\n // 仓库地址(用户名/仓库)统一显示为可点击超链接,跳转到官网详情页(含插件收录信息),而非直接跳 GitHub\n repo ? h('a', {\n className: styles.failRepo,\n href: pluginSiteUrl(repo),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: repo,\n }, repo) : null,\n // 复制按钮放最上面、浅灰隐蔽;报错正文不允许鼠标选择复制,只能点这里\n h('button', { className: styles.errorCopySoft, onClick: () => onCopy(copyText) }, t('errorCopy')),\n ),\n // 报错信息完整展示(可滚动),比失败记录的预览看得更多\n h('pre', { className: styles.errorBox }, message),\n // npm 内部崩溃(edgesOut)+ 本机 npm 版本过低:npm 自身已知缺陷,不是插件问题 ——\n // 直接给升级指引,不引导提 Issue(提了也是 npm 的问题,插件作者无法修复)\n failureKind === 'npmTooOld'\n ? h('div', { className: styles.failPrepareHint },\n t(npmVersion ? 'failNpmTooLowV' : 'failNpmTooLow', npmVersion ? { v: npmVersion } : undefined))\n : failureKind === 'pluginPrepare' || failureKind === 'pnpmIgnoredBuild'\n ? h('div', null, [\n // [packaging](预检/装后校验拦截:git 分发缺产物)与\n // prepare 构建脚本实际执行失败 / 原生依赖构建被 pnpm 拦截:都是插件打包分发问题 —— 先说明原因,按钮在下方提交\n h('div', { className: styles.failPrepareHint }, failureKind === 'pnpmIgnoredBuild'\n ? t('failIgnoredBuild')\n : /\\[packaging\\]/i.test(message) ? t('failPackagingHint') : t('failPrepareHint')),\n repo ? h('a', {\n className: styles.failBigIssue,\n href: pluginIssueUrl(repo, message, env, command, attempts),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('failIssueHint'),\n }, t('failIssueBig')) : null,\n ])\n : repo ? h('a', {\n className: styles.failBigIssue,\n href: pluginIssueUrl(repo, message, env, command, attempts),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('failIssueHint'),\n }, t('failIssueBig')) : null,\n ),\n h('div', { className: styles.modalActions },\n h('button', { className: styles.restartLater, onClick: onClose }, t('errorClose')),\n ),\n ),\n ),\n )\n}\n\n/** 全局反馈 Toast:复制成功(反色)/ 安装完成(反色)/ 安装失败(红色)/ 卸载结果 */\nexport function Toast({ toast, t }: { toast: ToastState; t: Translate }) {\n const text = toast.kind === 'copied' ? t('toastCopied')\n : toast.kind === 'errCopied' ? t('errCopied')\n : toast.kind === 'done' ? t('installDone')\n : toast.kind === 'fail' ? t('installFail')\n : toast.kind === 'removed' ? t('uninstallDone')\n : toast.kind === 'revealFail' ? t('openFolderFail')\n : toast.kind === 'updates' ? t('updatesFound', { n: toast.n ?? 0 })\n : t('uninstallFail')\n const fail = toast.kind === 'fail' || toast.kind === 'removeFail' || toast.kind === 'revealFail'\n return h('div', {\n key: toast.id,\n className: fail ? `${styles.toast} ${styles.toastFail}` : styles.toast,\n }, text)\n}\n\n/** 待重启确认弹窗:已安装列表行内「重启」按钮点击后弹出,\n * 与通知中心待重启条目同一交互(说明 + 稍后重启 / 立即重启),\n * 避免行内按钮误触直接触发宿主重启。 */\nexport function RestartConfirmModal({ t, restarting, onClose, onRestartNow }: {\n t: Translate\n restarting: boolean\n onClose: () => void\n onRestartNow: () => void\n}) {\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) onClose() },\n },\n h('div', { className: styles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('sectionPendingRestart')),\n h('button', {\n className: styles.modalClose,\n type: 'button',\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n h('div', { className: styles.failPrepareHint }, t('restartHint')),\n h('div', { className: styles.modalActions },\n h('button', {\n className: styles.restartLater,\n type: 'button',\n disabled: restarting,\n onClick: onClose,\n }, t('restartLater')),\n h('button', {\n className: styles.restartNowWarning,\n type: 'button',\n disabled: restarting,\n onClick: onRestartNow,\n }, restarting ? t('restarting') : t('restartNow')),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * 轻量 Markdown 渲染器:仅用于 Hub 自我更新的变更记录(Worker 下发的 notes)。\n *\n * 内容由插件作者自己编写、属可信内容,但渲染端仍先整体 HTML 转义,再按\n * Markdown 语法输出结构,杜绝任何未转义的原始 HTML 注入;链接仅放行 http(s)。\n *\n * 支持:标题(#~####)、有序/无序列表、代码块(```)、行内代码、加粗、斜体、\n * 链接、图片(![alt](url),如反馈群二维码)、引用(>)、段落;其余语法一律按\n * 纯文本处理,不引入外部依赖。图片仅放行 http(s),限定最大宽度不撑破弹窗。\n */\n\n/** HTML 转义:所有文本先进这里,再进入结构变换,保证输出里没有未转义的用户输入。 */\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\n/** 行内变换:链接 / 加粗 / 斜体 / 行内代码(代码先占位保护,最后还原)。 */\nfunction inline(s: string): string {\n let out = escapeHtml(s)\n // 行内代码先占位:避免其中的 * [ ] 被后续链接/加粗/斜体规则破坏\n const codeSpans: string[] = []\n out = out.replace(/`([^`]+)`/g, (_m, code) => {\n codeSpans.push(String(code))\n return `\\u0000${codeSpans.length - 1}\\u0000`\n })\n // 图片 ![alt](url):仅放行 http(s),用于展示反馈群二维码等;limited by CSS\n out = out.replace(/!\\[([^\\]]*)\\]\\(([^)\\s]+)\\)/g, (m, alt, url) =>\n /^https?:\\/\\//i.test(String(url)) && !/[\\u0000]/.test(String(url))\n ? `<img src=\"${String(url)}\" alt=\"${String(alt)}\" loading=\"lazy\">`\n : m,\n )\n // 链接 [text](url):仅放行 http(s),新窗口打开\n out = out.replace(/\\[([^\\]]+)\\]\\(([^)\\s]+)\\)/g, (m, text, url) =>\n /^https?:\\/\\//i.test(String(url)) && !/[\\u0000]/.test(String(url))\n ? `<a href=\"${String(url)}\" target=\"_blank\" rel=\"noopener noreferrer\">${String(text)}</a>`\n : m,\n )\n out = out.replace(/\\*\\*([^*]+)\\*\\*/g, '<strong>$1</strong>')\n out = out.replace(/(^|[^*])\\*([^*]+)\\*/g, '$1<em>$2</em>')\n return out.replace(/\\u0000(\\d+)\\u0000/g, (_m, idx) => `<code>${codeSpans[Number(idx)]}</code>`)\n}\n\n/** 把变更记录 Markdown 渲染为安全的 HTML 字符串(由弹窗用 dangerouslySetInnerHTML 注入)。 */\nexport function renderMarkdown(md: string): string {\n const lines = md.replace(/\\r\\n?/g, '\\n').split('\\n')\n const blocks: string[] = []\n let i = 0\n while (i < lines.length) {\n const line = lines[i]\n // 围栏代码块\n if (/^\\s*```/.test(line)) {\n const buf: string[] = []\n i++\n while (i < lines.length && !/^\\s*```/.test(lines[i])) {\n buf.push(lines[i])\n i++\n }\n i++ // 跳过闭合围栏\n blocks.push(`<pre><code>${escapeHtml(buf.join('\\n'))}</code></pre>`)\n continue\n }\n // 空行:段落分隔符\n if (line.trim() === '') {\n i++\n continue\n }\n // 标题:# 到 #### 映射为 h2~h5(弹窗标题用 modalTitle,不与其冲突)\n const heading = line.match(/^(#{1,4})\\s+(.*)/)\n if (heading) {\n const level = heading[1].length + 1\n blocks.push(`<h${level}>${inline(heading[2])}</h${level}>`)\n i++\n continue\n }\n // 有序 / 无序列表(连续收集为一个列表块)\n if (/^\\s*[-*+]\\s+/.test(line) || /^\\s*\\d+[.)]\\s+/.test(line)) {\n const ordered = /^\\s*\\d+[.)]\\s+/.test(line)\n const items: string[] = []\n while (i < lines.length && (/^\\s*[-*+]\\s+/.test(lines[i]) || /^\\s*\\d+[.)]\\s+/.test(lines[i]))) {\n items.push(`<li>${inline(lines[i].replace(/^\\s*[-*+]|\\s*\\d+[.)]\\s*/, '').trim())}</li>`)\n i++\n }\n blocks.push(`<${ordered ? 'ol' : 'ul'}>${items.join('')}</${ordered ? 'ol' : 'ul'}>`)\n continue\n }\n // 引用\n if (/^\\s*>\\s?/.test(line)) {\n const buf: string[] = []\n while (i < lines.length && /^\\s*>\\s?/.test(lines[i])) {\n buf.push(inline(lines[i].replace(/^\\s*>\\s?/, '')))\n i++\n }\n blocks.push(`<blockquote>${buf.join('<br>')}</blockquote>`)\n continue\n }\n // 普通段落:收集连续非空、非特殊开头的行\n const buf: string[] = []\n while (\n i < lines.length\n && lines[i].trim() !== ''\n && !/^\\s*```/.test(lines[i])\n && !/^#{1,4}\\s+/.test(lines[i])\n && !/^\\s*([-*+]|\\d+[.)])\\s+/.test(lines[i])\n ) {\n buf.push(inline(lines[i]))\n i++\n }\n blocks.push(`<p>${buf.join('<br>')}</p>`)\n }\n return blocks.join('')\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * 头部「关注我们」弹窗:介绍 DSH Plugin Hub 的功能定位 + 用户反馈群二维码。\n * 内容以 Markdown 形式由 dsh-update Worker 的 /about 接口下发(key = hub:about),\n * 客户端按接口返回渲染,不内置固定文案。\n * 图片(反馈群二维码)经 renderMarkdown 的 ![](url) 语法嵌入,居中、最大高度受控。\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { HubAboutInfo } from '../../types.ts'\nimport type { LocaleId, Translate } from '../../types.ts'\nimport { renderMarkdown } from '../../logic/renderMarkdown.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\nexport function AboutModal({ info, lang, t, onClose }: {\n info: HubAboutInfo | null\n lang: LocaleId\n t: Translate\n onClose: () => void\n}) {\n // 内容:字符串直接使用;{zh,en} 对象按界面语言取,缺哪种补哪种,全缺则展示兜底文案。\n // Worker 未推送(info 为 null / content 为空)时弹窗仍能打开,显示「暂未发布」而非报错。\n const contentRaw = info\n ? typeof info.content === 'string'\n ? info.content\n : info.content && typeof info.content === 'object'\n ? lang === 'en'\n ? (info.content.en ?? info.content.zh ?? '')\n : (info.content.zh ?? info.content.en ?? '')\n : ''\n : ''\n const contentHtml = contentRaw.trim() ? renderMarkdown(contentRaw) : null\n // 更新时间:ISO 字符串转本地可读格式;非法值静默隐藏\n let updated: string | null = null\n if (info?.updatedAt) {\n const d = new Date(info.updatedAt)\n if (!Number.isNaN(d.getTime())) {\n updated = d.toLocaleString(lang === 'en' ? 'en-US' : 'zh-CN')\n }\n }\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.modal} ${styles.aboutModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('aboutTitle')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: () => onClose(),\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalDesc }, t('aboutDesc')),\n contentHtml\n ? h('div', {\n className: styles.aboutContent,\n dangerouslySetInnerHTML: { __html: contentHtml },\n })\n : h('div', { className: styles.aboutContent }, t('aboutEmpty')),\n updated\n ? h('div', { className: styles.aboutMeta }, `${t('aboutUpdated')} ${updated}`)\n : null,\n h('div', { className: styles.modalActions },\n h('button', { className: styles.modalInstall, onClick: onClose }, t('doneBtn')),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Hub 版本信息 / 自我更新说明弹窗:\n * - 有更新(hasUpdate=true):标题「有新版本」,展示新版本号、发布时间与 Worker 下发的\n * Markdown 变更记录(renderMarkdown 渲染,双语言按界面语言取 {zh,en} 对象),\n * 按钮「稍后再说 / 直接更新」,确认后进入安装弹窗执行覆盖重装。\n * - 无更新(hasUpdate=false):标题「当前版本」,展示当前版本信息与更新记录,已是最新。\n * 点击头部版本号(或「可更新」徽标)打开 —— 无论有无更新都能看到更新内容。\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { HubUpdateInfo } from '../../types.ts'\nimport type { LocaleId, Translate } from '../../types.ts'\nimport { renderMarkdown } from '../../logic/renderMarkdown.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\nexport function HubUpdateModal({ info, lang, t, hasUpdate, onProceed, onClose }: {\n info: HubUpdateInfo\n lang: LocaleId\n t: Translate\n /** 是否有可用更新:有则显示「直接更新」,无则显示「已是最新」 */\n hasUpdate: boolean\n /** 点「直接更新」:关闭本弹窗,进入安装弹窗的更新流程 */\n onProceed: () => void\n onClose: () => void\n}) {\n // 变更记录:字符串直接使用;{zh,en} 对象按界面语言取,缺哪种补哪种,全缺则不出记录区\n const notesRaw = typeof info.notes === 'string'\n ? info.notes\n : info.notes && typeof info.notes === 'object'\n ? lang === 'en'\n ? (info.notes.en ?? info.notes.zh ?? '')\n : (info.notes.zh ?? info.notes.en ?? '')\n : ''\n const notesHtml = notesRaw.trim() ? renderMarkdown(notesRaw) : null\n // 发布时间:ISO 字符串转本地可读格式;非法值静默隐藏\n let published: string | null = null\n if (info.publishedAt) {\n const d = new Date(info.publishedAt)\n if (!Number.isNaN(d.getTime())) {\n published = d.toLocaleString(lang === 'en' ? 'en-US' : 'zh-CN')\n }\n }\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.modal} ${styles.hubUpdateModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t(hasUpdate ? 'hubUpdateTitle' : 'hubCurrentTitle')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: () => onClose(),\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalDesc },\n t(hasUpdate ? 'hubUpdateDesc' : 'hubCurrentDesc', { version: info.version })),\n h('div', { className: styles.hubUpdateMeta },\n h('span', { className: styles.hubUpdateMetaItem }, `${t('version')} ${info.version}`),\n published\n ? h('span', { className: styles.hubUpdateMetaItem }, `${t('hubUpdatePublished')} ${published}`)\n : null,\n ),\n notesHtml\n ? h('div', {\n className: styles.hubUpdateNotes,\n dangerouslySetInnerHTML: { __html: notesHtml },\n })\n : null,\n h('div', { className: styles.modalActions },\n hasUpdate\n ? [\n h('button', { className: styles.restartLater, onClick: onClose }, t('hubUpdateLater')),\n h('button', { className: styles.modalInstall, onClick: onProceed }, t('updateNow')),\n ]\n : h('button', { className: styles.modalInstall, onClick: onClose }, t('hubUpToDate')),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Presentation formatters shared across the catalog list and the cards.\n */\nimport type { Translate } from '../types.ts'\n\n/** 星数/分支数的紧凑展示:<1k 原样;千级 1.2k;十万级取整。 */\nexport function fmtStars(count?: number): string {\n if (!count || count <= 0) return '0'\n if (count < 1000) return String(count)\n const k = count / 1000\n return `${k >= 100 ? Math.round(k) : k.toFixed(1).replace(/\\.0$/, '')}k`\n}\n\n/** 相对时间:今天 / N 天前 / N 个月前 / N 年前。 */\nexport function relTime(iso: string | undefined, t: Translate): string {\n if (!iso) return ''\n const days = Math.floor((Date.now() - new Date(iso).getTime()) / 86400000)\n if (days <= 0) return t('today')\n if (days < 30) return t('daysAgo', { days })\n if (days < 365) return t('monthsAgo', { months: Math.floor(days / 30) })\n return t('yearsAgo', { years: Math.floor(days / 365) })\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Installed-plugin detail dialog: opens from the Installed view (row click\n * or the detail button) and shows everything we know about an installed\n * entry — the catalog metadata (category, catalog entry, stars/forks,\n * latest version) merged with the host runtime facts (install path, installed\n * version, install time, last update). Update / uninstall actions are\n * offered from here too, mirroring the row actions.\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { LocaleId, Translate } from '../../types.ts'\nimport type { InstalledItem } from '../../logic/installed.ts'\nimport { CATEGORY_LABELS, categoryLabel } from '../../logic/constants.ts'\nimport { pluginDetailUrl } from '../../logic/urls.ts'\nimport { fmtStars } from '../../logic/format.ts'\nimport { CloseIcon, CopyIcon, FolderIcon, LinkIcon } from '../ui/icons.tsx'\n\n/** ISO 安装时间 → 本地可读;非法值返回 null(行内不显示)。 */\nfunction fmtDate(iso: string | null, lang: LocaleId): string | null {\n if (!iso) return null\n const d = new Date(iso)\n return Number.isNaN(d.getTime()) ? null : d.toLocaleString(lang === 'en' ? 'en-US' : 'zh-CN')\n}\n\nexport function InstalledDetailModal({ item, t, lang, langPath, onClose, onUpdate, onUninstall, onCopyPath, onReveal }: {\n item: InstalledItem\n t: Translate\n lang: LocaleId\n langPath: string\n onClose: () => void\n /** 更新:仅目录插件且有更新时展示(点击后关闭详情、走安装确认弹窗的更新语义) */\n onUpdate: (item: InstalledItem) => void\n onUninstall: (item: InstalledItem) => void\n /** 复制安装路径:成功提示由调用方 toast 反馈 */\n onCopyPath: (path: string) => void\n /** 在系统文件管理器里定位安装目录(服务端 spawn open):失败提示由调用方 toast 反馈 */\n onReveal: (item: InstalledItem) => void\n}) {\n const p = item.plugin\n const name = p?.displayName ?? item.name\n const installedAt = fmtDate(item.installedAt, lang)\n // 最后更新:目录插件取仓库最近提交时间(live 数据);自定义安装无目录信号\n const lastUpdated = fmtDate(p?.dates?.repoUpdatedAt ?? null, lang)\n const hasUpdate = item.hasUpdate && item.plugin !== null\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.modal} ${styles.detailModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, name),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n // 描述:目录收录的插件简介\n p?.description ? h('div', { className: styles.modalDesc }, p.description) : null,\n // 有可用更新:醒目提示条(版本号存在时给出升级路径)\n hasUpdate\n ? h('div', { className: styles.detailUpdateHint },\n item.installedVersion && item.catalogVersion\n ? t('versionUpHint', { from: item.installedVersion, to: item.catalogVersion })\n : t('updateAvailableHint'))\n : null,\n // 详情信息网格:分类 / 状态 / 版本 / 收录入口 / 包名 / 统计 / 安装路径 / 安装时间 / 最后更新\n h('div', { className: styles.detailGrid },\n p?.category\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('detailCategory')),\n h('span', { className: styles.detailValue },\n categoryLabel(CATEGORY_LABELS, p.category, lang)))\n : null,\n h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('statusLabel')),\n h('span', { className: styles.detailValue },\n h('span', {\n className: item.loaded ? styles.detailStatusRunning : styles.detailStatusPending,\n 'aria-hidden': 'true',\n }),\n h('span', { className: styles.detailStatusText },\n item.loaded ? t('statusRunning') : t('statusPending')))),\n item.installedVersion\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('installedVersionLabel')),\n h('span', { className: styles.detailValue },\n h('span', { className: styles.detailMono }, item.installedVersion),\n // 目录有更新版本且与已装版本不同:给出「→ 目录最新」\n item.catalogVersion && item.catalogVersion !== item.installedVersion\n ? h('span', { className: styles.detailArrow },\n '\\u2192', h('span', { className: styles.detailMono }, item.catalogVersion),\n h('span', { className: styles.detailDim }, t('catalogLatest')))\n : null))\n : null,\n // 收录入口:仓库名 → 官网详情页(目录插件跳收录页;自定义安装回退到 GitHub 仓库)\n item.repo\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('detailCatalog')),\n h('a', {\n className: styles.detailLink,\n href: p ? pluginDetailUrl(p, langPath) : `https://github.com/${item.repo}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n title: item.repo,\n }, h(LinkIcon), item.repo))\n : null,\n item.plugin?.source?.npmPackage\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('packageName')),\n h('span', { className: styles.detailValue },\n h('span', { className: styles.detailMono }, item.plugin.source.npmPackage)))\n : null,\n p?.stats && (p.stats.stargazers_count ?? 0) > 0\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('detailStats')),\n h('span', { className: styles.detailValue },\n h('span', { className: styles.detailStars }, '\\u2605 ', fmtStars(p.stats.stargazers_count)),\n h('span', { className: styles.detailDim }, t('fork'), ' ', fmtStars(p.stats.forks_count))))\n : null,\n item.installPath\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('installPath')),\n h('div', { className: styles.detailPath },\n // 整条点击复制路径(等宽文本省略号)\n h('span', {\n className: styles.detailPathText,\n title: t('copyPath'),\n onClick: () => onCopyPath(item.installPath!),\n }, item.installPath),\n h('span', { className: styles.detailPathActions },\n h('button', {\n className: styles.detailPathBtn,\n type: 'button',\n title: t('copyPath'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation()\n onCopyPath(item.installPath!)\n },\n }, h(CopyIcon)),\n h('button', {\n className: styles.detailPathBtn,\n type: 'button',\n title: t('openFolder'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation()\n onReveal(item)\n },\n }, h(FolderIcon)),\n )))\n : null,\n installedAt\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('installedAtLabel')),\n h('span', { className: styles.detailValue }, installedAt))\n : null,\n // 最后更新时间:与安装时间成对展示(目录插件才有)\n lastUpdated\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('lastUpdatedLabel')),\n h('span', { className: styles.detailValue }, lastUpdated))\n : null,\n ),\n ),\n // 底部操作:完成 / 更新 / 卸载(复制路径与打开文件夹已在路径行内)\n h('div', { className: styles.modalActions },\n h('button', {\n className: styles.restartLater,\n onClick: onClose,\n }, t('done')),\n hasUpdate\n ? h('button', {\n className: styles.modalInstall,\n onClick: () => onUpdate(item),\n }, t('update'))\n : null,\n h('button', {\n className: styles.uninstallConfirm,\n onClick: () => onUninstall(item),\n }, t('uninstall')),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Notification-center dialog: a persistent log of every settled install /\n * remove task — successes and failures alike.\n *\n * Records are written to localStorage at settle time (see logic/failures.ts),\n * so a result is never lost even when the dialog was dismissed or the user\n * was away. Each entry carries a circular status badge (green check for\n * success, red cross for failure) with white glyph and message text;\n * failures keep their copy / fix / file-an-issue actions. Opened from the\n * header entry button (after the Settings tab).\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { EnvInfo, Translate } from '../../types.ts'\nimport type { NotificationRecord } from '../../logic/failures.ts'\nimport { classifyFailure, npmTooLowVersion } from '../../logic/failures.ts'\nimport type { PendingRestart, QueueTask } from '../../hooks/useTaskQueue.ts'\nimport { pluginIssueUrl, pluginSiteUrl } from '../../logic/urls.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\n/** 记录时间完整展示:YYYY-MM-DD HH:mm:ss(每条通知都带精确到秒的时间戳)。 */\nfunction fmtTime(at: number): string {\n const d = new Date(at)\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`\n}\n\n/** 圆形状态徽标内的白色图形:成功为对勾、失败为叉。 */\nfunction BadgeGlyph({ ok }: { ok: boolean }) {\n return h('svg', {\n className: styles.noticeBadgeIcon,\n viewBox: '0 0 16 16',\n width: 12,\n height: 12,\n fill: 'none',\n 'aria-hidden': 'true',\n }, ok\n ? h('path', {\n d: 'M3 8.5l3.5 3.5 6.5-6.5',\n stroke: '#ffffff',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n })\n : h('path', {\n d: 'M4 4l8 8M12 4L4 12',\n stroke: '#ffffff',\n strokeWidth: 2,\n strokeLinecap: 'round',\n }))\n}\n\nexport function NotificationsModal({ records, tasks, pendingRestarts, t, env, onClose, onCopy, onClear, onRemove, onUpdate, onIgnoreUpdate, cancelTask, restarting, onRestart }: {\n records: NotificationRecord[]\n /** 进行中的安装/卸载任务(实时进度,与队列弹窗同一数据源) */\n tasks: QueueTask[]\n /** 待重启插件:装完没重启的常驻提醒 */\n pendingRestarts: PendingRestart[]\n t: Translate\n env: EnvInfo | null\n onClose: () => void\n onCopy: (text: string) => void\n onClear: () => void\n /** 删除单条通知记录 */\n onRemove: (id: number) => void\n /** 更新提醒通知点击:跳去该插件的更新确认弹窗 */\n onUpdate: (repo: string) => void\n /** 更新提醒「忽略本次更新」:先弹确认,确认后本次版本不再提醒,下一个新版本再通知 */\n onIgnoreUpdate: (repo: string, version?: string) => void\n cancelTask: (id: number) => void\n restarting: boolean\n onRestart: () => void\n}) {\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: styles.errorModal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('notifications')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n h('div', { className: styles.errorHint }, t('notificationsDesc')),\n // 进行中的安装/卸载任务实时进度也进通知中心:与队列弹窗同一套行结构,\n // 关掉任务弹窗后仍可在这里盯着进度;待重启插件可在此直接触发重启\n (tasks.length > 0 || pendingRestarts.length > 0)\n ? h('div', null, [\n pendingRestarts.length > 0\n ? h('div', { className: styles.queueSection },\n h('div', { className: styles.queueSectionTitle }, t('sectionPendingRestart')),\n pendingRestarts.map((p) => h('div', { key: `restart-${p.target}`, className: styles.queueRow },\n h('div', { className: styles.queueRowHead },\n h('span', {\n className: `${styles.failKind} ${p.kind === 'uninstall' ? styles.failKindUninstall : styles.failKindInstall}`,\n }, p.kind === 'uninstall' ? t('uninstall') : t('install')),\n h('span', { className: styles.queueRowTarget, title: p.target }, p.target),\n ),\n p.desc ? h('div', { className: styles.queueRowDesc, title: p.desc }, p.desc) : null,\n h('div', { className: styles.queueRowBody },\n h('span', { className: styles.pendingRowStatus },\n p.kind === 'uninstall' ? t('restartPendingHintUninstall') : t('restartPendingHint')),\n h('span', { className: styles.pendingRowActions },\n h('button', {\n className: styles.restartLater,\n disabled: restarting,\n onClick: onClose,\n }, t('restartLater')),\n h('button', {\n className: styles.restartNow,\n disabled: restarting,\n onClick: onRestart,\n }, restarting ? t('restarting') : t('restartNow')),\n ),\n ),\n )),\n )\n : null,\n tasks.length > 0\n ? h('div', { className: styles.queueSection },\n h('div', { className: styles.queueSectionTitle }, t('sectionInProgress')),\n tasks.map((q) => h('div', { key: q.id, className: styles.queueRow },\n h('div', { className: styles.queueRowHead },\n h('span', {\n className: `${styles.failKind} ${q.kind === 'install' ? styles.failKindInstall : styles.failKindUninstall}`,\n }, q.kind === 'install' ? t('install') : t('uninstall')),\n h('span', { className: styles.queueRowTarget, title: q.target }, q.target),\n h('button', {\n className: styles.stripCancel,\n disabled: q.status === 'cancelling',\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); cancelTask(q.id) },\n }, t('cancelTask')),\n ),\n q.desc ? h('div', { className: styles.queueRowDesc, title: q.desc }, q.desc) : null,\n h('div', { className: styles.queueRowBody },\n h('span', { className: styles.queueRowStatus },\n q.status === 'running'\n ? (q.kind === 'install' ? t('installing') : t('uninstalling'))\n : q.status === 'cancelling'\n ? t('cancelling')\n : (q.kind === 'install' ? t('queuedTitle') : t('queuedUninstallTitle'))),\n h('div', { className: `${styles.progressTrack} ${styles.queueRowTrack}` },\n h('div', { className: styles.progressFill, style: { width: `${q.progress}%` } }),\n ),\n h('span', { className: styles.queueRowPct }, `${q.progress}%`),\n ),\n )),\n )\n : null,\n ])\n : null,\n records.length === 0\n ? h('div', { className: styles.failEmpty }, t('notificationsEmpty'))\n : h('div', { className: styles.noticeList },\n records.map((r) => {\n const isUpdate = r.kind === 'update'\n return h('div', {\n key: r.id,\n // 更新提醒:整行可点击直达更新确认弹窗;install/uninstall 记录维持原交互\n className: r.ok\n ? `${styles.noticeRow} ${styles.noticeRowOk}${isUpdate ? ` ${styles.noticeRowUpdate}` : ''}`\n : styles.noticeRow,\n ...(isUpdate ? { onClick: () => onUpdate(r.repo), title: t('updateNoticeGo') } : {}),\n },\n h('div', { className: styles.noticeRowMain },\n h('div', {\n className: r.ok ? styles.noticeBadgeOk : styles.noticeBadgeFail,\n }, h(BadgeGlyph, { ok: r.ok })),\n h('div', { className: styles.noticeMain },\n h('div', { className: styles.noticeHead },\n h('span', {\n className: r.ok ? styles.noticeTextOk : styles.noticeTextFail,\n }, r.ok\n ? (isUpdate ? t('updateNoticeTitle') : (r.kind === 'install' ? t('installDone') : t('uninstallDone')))\n : (r.kind === 'install' ? t('errorTitleInstall') : t('errorTitleUninstall'))),\n // 更新提醒:新版本号紧随标题展示;repo 为纯文本(整行点击即去更新,不跳官网外链)\n isUpdate && r.version\n ? h('span', { className: styles.noticeVersion, title: r.version }, `v${r.version}`)\n : null,\n r.repo\n ? (isUpdate\n ? h('span', { className: styles.failRepo, title: r.repo }, r.repo)\n : h('a', {\n className: styles.failRepo,\n // 跳转到官网详情页(含插件收录信息),不在通知弹窗直接跳 GitHub\n href: pluginSiteUrl(r.repo),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: r.repo,\n }, r.repo))\n : null,\n !r.ok && h('button', {\n className: styles.failCopy,\n onClick: () => onCopy(r.message),\n }, t('failCopy')),\n // 成功通知:时间戳并入本行右侧,与图标/文字垂直居中 ——\n // 不再单独占底部一行,卡片只有一行内容,图标文字整体居中不顶头\n r.ok\n ? h('span', {\n className: styles.noticeTime,\n title: new Date(r.at).toLocaleString(),\n }, fmtTime(r.at))\n : null,\n // 更新提醒:行尾「去更新」按钮直达更新确认弹窗(整行也可点击)\n isUpdate\n ? h('button', {\n className: styles.noticeUpdateGo,\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onUpdate(r.repo) },\n }, t('updateNoticeGo'))\n : null,\n // 更新提醒:「忽略本次更新」按钮 —— 先弹确认,确认后本次版本不再提醒\n isUpdate\n ? h('button', {\n className: styles.noticeIgnore,\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onIgnoreUpdate(r.repo, r.version) },\n }, t('ignoreUpdateRun'))\n : null,\n // 每条通知右侧的删除按钮:单独移除这一条\n h('button', {\n className: styles.noticeRemove,\n 'aria-label': t('removeNotification'),\n title: t('removeNotification'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onRemove(r.id) },\n }, h(CloseIcon)),\n ),\n // 每条失败记录是一个独立卡片:头部(状态/仓库/时间/复制完整日志)→ 修复或提 Issue 动作。\n // 卡片不展示错误日志预览,完整日志靠「复制完整日志」按钮带走,避免每条卡片被日志撑高\n !r.ok && (() => {\n const kind = classifyFailure(r.message)\n if (kind === 'npmTooOld') {\n // npm 内部崩溃(edgesOut)+ 本机 npm 版本过低:npm 自身已知缺陷,不是插件问题 ——\n // 直接给升级指引,不引导提 Issue\n const v = npmTooLowVersion(r.message)\n return h('div', { className: styles.failPrepareHint },\n t(v ? 'failNpmTooLowV' : 'failNpmTooLow', v ? { v } : undefined))\n }\n if (kind === 'pluginPrepare' || kind === 'pnpmIgnoredBuild') {\n // [packaging](预检/装后校验拦截:git 分发缺产物)与\n // prepare 构建脚本实际执行失败 / 原生依赖构建被 pnpm 拦截:都是插件打包分发问题 —— 先说明原因,按钮在下方提交\n return h('div', null, [\n h('div', { className: styles.failPrepareHint }, kind === 'pnpmIgnoredBuild'\n ? t('failIgnoredBuild')\n : /\\[packaging\\]/i.test(r.message) ? t('failPackagingHint') : t('failPrepareHint')),\n r.repo ? h('a', {\n className: styles.failBigIssue,\n href: pluginIssueUrl(r.repo, r.message, env, r.command, r.attempts),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('failIssueHint'),\n }, t('failIssueBig')) : null,\n ])\n }\n return r.repo ? h('a', {\n className: styles.failBigIssue,\n href: pluginIssueUrl(r.repo, r.message, env, r.command, r.attempts),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('failIssueHint'),\n }, t('failIssueBig')) : null\n })(),\n ),\n ),\n // 失败通知:时间戳保留独立底部行(右下角);成功通知已并入头部行右侧\n !r.ok\n ? h('div', { className: styles.noticeFoot },\n h('span', {\n className: styles.noticeTime,\n title: new Date(r.at).toLocaleString(),\n }, fmtTime(r.at)),\n )\n : null,\n )\n }),\n ),\n h('div', { className: styles.modalActions },\n records.length > 0 ? h('button', {\n className: styles.failClear,\n onClick: onClear,\n }, t('notificationsClear')) : null,\n h('button', { className: styles.restartNow, onClick: onClose }, t('errorClose')),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Section header: brand title row (H1 + open-site button) + tagline, followed\n * by the purple ad banner that promotes the catalog stats.\n */\nimport { createElement as h, Fragment } from 'react'\nimport styles from '../../styles/Header.module.css'\nimport type { Translate } from '../../types.ts'\nimport { GITHUB_URL, PLUGIN_VERSION, SITE_URL } from '../../logic/constants.ts'\nimport { GitHubIcon, LogoIcon } from '../ui/icons.tsx'\n\nexport function CatalogHeader({ t, langPath, statsTotal, statsVerified, onToggleLang, hubUpdate, onVersionClick, onAboutClick }: {\n t: Translate\n langPath: string\n statsTotal: number\n statsVerified: number\n onToggleLang: () => void\n /** Hub 自身是否有可用更新:有则版本号后紧跟红色「可更新」徽标(整体一个可点入口) */\n hubUpdate: boolean\n /** 点击版本号(含红色徽标,同一入口):无论有无更新都打开更新记录弹窗 */\n onVersionClick: () => void\n /** 点击「关注我们」:打开平台介绍 + 用户反馈群二维码弹窗 */\n onAboutClick: () => void\n}) {\n return h(Fragment, null,\n h('div', { className: styles.header },\n // 第一行:logo + 标题(官网链接)与 GitHub 源码图标同行,GitHub 顶到标题行末尾\n h('div', { className: styles.headerTitleRow },\n h('a', {\n className: styles.brandTitle,\n href: `${SITE_URL}${langPath}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('openHint'),\n 'aria-label': t('openHint'),\n },\n h(LogoIcon),\n h('h1', { className: styles.title }, t('title')),\n ),\n // 版本号:紧跟标题「DSH Plugin Hub」之后,常驻可点入口(<a> 内不能嵌套按钮,故从官网链接里移出放在旁边)。\n // 点击打开更新记录弹窗 —— 有更新看新版本内容,无更新看当前版本内容。\n // 有更新时版本号后直接跟一个红色「可更新」徽标(同一按钮内,不分开成两个元素),静态显示不闪烁。\n h('button', {\n className: styles.versionBtn,\n type: 'button',\n onClick: onVersionClick,\n title: t(hubUpdate ? 'hubUpdateHint' : 'versionHint'),\n 'aria-label': t(hubUpdate ? 'hubUpdateHint' : 'versionHint'),\n },\n `v${PLUGIN_VERSION}`,\n hubUpdate && h('span', { className: styles.hubUpdateBadge }, t('update')),\n ),\n // 右侧控件组:语言切换 + GitHub 源码图标(独立链接,brandTitle 是官网 <a> 不能嵌套),\n // 一起 space-between 顶到标题行最右\n h('div', { className: styles.headerRight },\n // 语言切换:按钮文字始终显示「要切到的语言」,点击即切,无需图标\n h('button', {\n className: styles.langBtn,\n type: 'button',\n onClick: onToggleLang,\n title: t('toggleLangHint'),\n 'aria-label': t('toggleLangHint'),\n }, langPath === 'zh/' ? 'EN' : '中文'),\n // 「关注我们」:点击打开平台介绍 + 用户反馈群二维码弹窗\n h('button', {\n className: styles.aboutBtn,\n type: 'button',\n onClick: onAboutClick,\n title: t('aboutDesc'),\n 'aria-label': t('aboutTitle'),\n }, t('followUs')),\n // GitHub 源码图标:独立链接(brandTitle 是官网 <a> 不能嵌套),放在控件组最后\n h('a', {\n className: styles.githubLink,\n href: GITHUB_URL,\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('githubHint'),\n 'aria-label': t('githubHint'),\n }, h(GitHubIcon)),\n ),\n ),\n // 第二行:副标题仍是官网链接,点击跳 dsh-plugin.org\n h('a', {\n className: styles.taglineLink,\n href: `${SITE_URL}${langPath}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('openHint'),\n },\n h('div', { className: styles.tagline }, t('tagline', { total: statsTotal, verified: statsVerified })),\n ),\n ),\n h('a', {\n className: styles.adBanner,\n href: `${SITE_URL}${langPath}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n },\n h('span', { className: styles.adBadge }, t('adBadge')),\n h('span', { className: styles.adText }, t('ad', { total: statsTotal, verified: statsVerified })),\n h('span', { className: styles.adArrow }, '\\u2197')),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Category tabs: an \"all\" chip followed by one chip per catalog category.\n * The \"all\" chip carries the total plugin count; the per-category chips\n * carry no counts so their widths stay uniform.\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/Header.module.css'\nimport type { LocaleId } from '../../types.ts'\nimport { CATEGORY_ORDER, CATEGORY_SHORT_LABELS, categoryLabel } from '../../logic/constants.ts'\n\nexport function CategoryTabs({ category, setCategory, allLabel, totalCount, langKey }: {\n category: string\n setCategory: (value: string) => void\n allLabel: string\n totalCount: number\n langKey: LocaleId\n}) {\n return h('div', { className: styles.tabs },\n // 第一个按钮固定为「全部」:展示全部分类,直接显示插件总数;\n // 其余分类按钮不带数量,保持排版整齐\n h('button', {\n key: 'all',\n className: category === 'all' ? styles.tabActive : styles.tab,\n onClick: () => setCategory('all'),\n },\n allLabel,\n h('span', { className: styles.tabCount }, totalCount)),\n CATEGORY_ORDER.map((id) => h('button', {\n key: id,\n className: category === id ? styles.tabActive : styles.tab,\n onClick: () => setCategory(id),\n },\n categoryLabel(CATEGORY_SHORT_LABELS, id, langKey))),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Toolbar above the market list:\n * row 1 — full-width search input;\n * row 2 — result count on the left, sort segmented control on the right\n * (mirrors the Installed view: clicking the same sort toggles\n * ascending/descending, a new sort uses its default order; the active\n * button shows an up/down arrow for the current direction).\n */\nimport { createElement as h, Fragment } from 'react'\nimport type { FormEvent, ReactNode } from 'react'\nimport styles from '../../styles/Header.module.css'\nimport type { Translate } from '../../types.ts'\nimport { SORTS } from '../../logic/constants.ts'\nimport type { SortKey } from '../../logic/constants.ts'\nimport { SortArrowIcon } from '../ui/icons.tsx'\n\n/** 单选按钮组中的一个按钮(segmented control,与已安装视图排序按钮同款) */\nfunction SegBtn({ active, onClick, label, icon }: {\n active: boolean\n onClick: () => void\n label: string\n icon?: ReactNode\n}) {\n return h('button', {\n type: 'button',\n className: active ? `${styles.segBtn} ${styles.segBtnActive}` : styles.segBtn,\n 'aria-pressed': active,\n onClick,\n }, label, icon)\n}\n\nexport function CatalogControls({ query, setQuery, sort, sortDir, toggleSort, t, resultText }: {\n query: string\n setQuery: (value: string) => void\n sort: SortKey\n /** 当前排序方向:决定激活排序按钮上的箭头朝上(正序)/朝下(倒序) */\n sortDir: 'asc' | 'desc'\n toggleSort: (value: SortKey) => void\n t: Translate\n resultText: string | null\n}) {\n return h(Fragment, null,\n // 第一行:搜索框占满整行(搜插件名称、描述、标签)\n h('div', { className: styles.searchRow },\n h('input', {\n className: styles.search,\n type: 'search',\n placeholder: t('search'),\n value: query,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) =>\n setQuery((e.target as HTMLInputElement).value),\n }),\n ),\n // 第二行:左侧筛选结果数「结果 N 条插件」(数字等宽预留 5 位不跳动),\n // 右侧排序按钮组(与已安装视图同款 segmented control,激活按钮带正/倒序箭头)\n h('div', { className: styles.controls },\n resultText ? h('span', { className: styles.resultSeg },\n ...resultText.split(/(\\d+)/).map((part, i) =>\n /^\\d+$/.test(part)\n ? h('span', { key: i, className: styles.resultCount }, part)\n : part)) : null,\n h('div', { className: styles.sortGroup },\n h('span', { className: styles.segLabel }, t('sortByLabel')),\n h('div', { className: styles.segGroup, role: 'radiogroup', 'aria-label': t('sortAria') },\n SORTS.map((key) => SegBtn({\n active: sort === key,\n onClick: () => toggleSort(key),\n label: t(key),\n icon: sort === key ? h(SortArrowIcon, { up: sortDir === 'asc' }) : null,\n })),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Incremental list: renders only the first batch of a (potentially huge)\n * result set and appends the next batch whenever the end sentinel scrolls\n * into view, so the plugin center never mounts thousands of cards at once.\n * The items reference is the list identity — category / search / sort\n * changes produce a new array, which resets the window to the first batch.\n */\nimport { useEffect, useRef, useState } from 'react'\n\n/** 首批渲染条数 & 每次滚到底追加的增量(单卡约 80px 高,100 条已远超一屏) */\nconst PAGE_SIZE = 100\n/** 哨兵进入视口底部前 800px 就提前加载下一批,滚到底时无感知衔接 */\nconst PRELOAD_MARGIN = '800px 0px'\n\nexport function useIncrementalList<T>(items: T[]) {\n const [limit, setLimit] = useState(PAGE_SIZE)\n const sentinelRef = useRef<HTMLDivElement | null>(null)\n\n // 筛选/分类/排序变化 → items 引用变化 → 窗口重置回首批\n useEffect(() => {\n setLimit(PAGE_SIZE)\n }, [items])\n\n // 哨兵进入视口(含预加载区)→ 追加下一批;已全部渲染则不再观察\n useEffect(() => {\n const el = sentinelRef.current\n if (!el || limit >= items.length) return\n const io = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) setLimit((cur) => Math.min(cur + PAGE_SIZE, items.length))\n }\n }, { rootMargin: PRELOAD_MARGIN })\n io.observe(el)\n return () => io.disconnect()\n }, [items.length, limit])\n\n return {\n shown: items.slice(0, limit),\n hasMore: limit < items.length,\n sentinelRef,\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * One plugin card in the catalog list: name/category/verified badge,\n * description + topics, star/fork/date stats, and the detail/install/\n * uninstall actions.\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/List.module.css'\nimport type { HubPlugin, LocaleId, Translate } from '../../types.ts'\nimport { CATEGORY_LABELS, categoryLabel } from '../../logic/constants.ts'\nimport { pluginDetailUrl } from '../../logic/urls.ts'\nimport { fmtStars, relTime } from '../../logic/format.ts'\n\nexport function PluginCard({ plugin: p, copied, installedName, installedVersion, hasUpdate, t, langKey, langPath, onInstall, onUninstall }: {\n plugin: HubPlugin\n copied: string | null\n installedName: (p: HubPlugin) => string | null\n /** 已安装版本号(安装时从目录信号记录;无 release 的仓库为空,无版本号可展示) */\n installedVersion: (p: HubPlugin) => string | null\n /** 已安装且目录有更新(有版本比版本、无版本比仓库更新时间) */\n hasUpdate: (p: HubPlugin) => boolean\n t: Translate\n langKey: LocaleId\n langPath: string\n /** 第二个参数标记「更新」(已安装目标的覆盖安装):按钮/弹窗据此走更新语义 */\n onInstall: (p: HubPlugin, opts?: { update?: boolean }) => void\n onUninstall: (p: HubPlugin) => void\n}) {\n const repo = p.source?.repo ?? ''\n const isCopied = copied === repo\n const pkg = installedName(p)\n const isInstalled = pkg !== null\n const update = hasUpdate(p)\n // 版本号展示:已安装 → 当前已装版本(最能反映用户状态);未安装 → 目录最新版本\n const versionShown = isInstalled ? installedVersion(p) : p.version\n\n return h('div', { className: styles.card },\n h('div', { className: styles.cardMain },\n h('div', { className: styles.cardHead },\n h('div', { className: styles.cardTitle, title: p.description ?? '' }, p.displayName ?? p.slug),\n // 版本号紧跟插件名称:有版本才显示(无 release 的仓库不展示版本号)\n versionShown ? h('span', { className: styles.versionBadge, title: t('version') }, versionShown) : null,\n // 已安装且有更新:醒目提示(有 release 比版本号、无 release 比仓库最近更新时间)\n update ? h('span', { className: styles.updateBadge, title: t('updateAvailableHint') }, t('updateAvailable')) : null,\n p.category ? h('span', { className: styles.categoryBadge }, categoryLabel(CATEGORY_LABELS, p.category, langKey)) : null,\n p.compatibility?.status === 'verified'\n ? h('span', { className: styles.verified }, t('verified'))\n : null,\n ),\n // 描述始终显示:站点英文数据缺翻译时 description 回退成中文也照常展示,\n // 描述是了解插件的第一入口,比隐藏更实用(不再为求语言一致而砍内容)。\n p.description ? h('p', { className: styles.desc }, p.description) : null,\n (p.topics?.length ?? 0) > 0\n ? h('div', { className: styles.topics },\n p.topics!.slice(0, 3).map((topic) => h('span', { key: topic, className: styles.topic }, topic)),\n )\n : null,\n ),\n h('div', { className: styles.cardSide },\n h('div', { className: styles.stats },\n h('span', { className: styles.star }, '\\u2605 ', fmtStars(p.stats?.stargazers_count)),\n h('span', { className: styles.fork }, t('fork'), ' ', fmtStars(p.stats?.forks_count)),\n h('span', { className: styles.date }, relTime(p.dates?.repoUpdatedAt, t)),\n ),\n repo\n ? h('div', { className: styles.actions },\n // 查看详情:未安装/已安装都始终显示,跳转官网详情页\n h('a', {\n className: styles.detailBtn,\n // 两级路径:/plugins/{ownerSlug}/{slug};缺 ownerSlug 时从 repo 推导\n href: pluginDetailUrl(p, langPath),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: p.slug,\n }, t('detail')),\n isInstalled\n // 已安装且有更新:按钮变「可更新」,点击直接覆盖安装(安装完成自动记录新版本)\n ? (update\n ? h('button', {\n className: styles.installBtnUpdate,\n title: t('updateAvailableHint'),\n onClick: () => onInstall(p, { update: true }),\n }, t('update'))\n : h('button', {\n className: styles.installBtnInstalled,\n disabled: true,\n title: t('installed'),\n }, t('installed')))\n // 未安装:按钮恒为「安装」,点击先弹信任确认;AI 识别为「可能需要命令行辅助」\n // 的插件(webInstallable=false)不拦截,允许尝试一键安装,弹窗内会给出提示与\n // 复制命令通道,安装失败时引导去 dsh 终端手动执行\n : h('button', {\n className: isCopied ? styles.installBtnCopied : styles.installBtn,\n // 文字恒定避免按钮宽度变化导致卡片跳动;点击先弹信任确认,\n // 弹窗内可选择复制命令或直接安装\n onClick: () => onInstall(p),\n }, t('install')),\n isInstalled\n // 已安装:卸载按钮(危险色),保留明确状态语义\n ? h('button', {\n className: styles.uninstallBtn,\n onClick: () => onUninstall(p),\n }, t('uninstall'))\n : null,\n )\n : null,\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Catalog list: the scrollable container with the loading / failed / empty\n * states, the plugin cards, and the count footer. Resets scroll position when\n * the category or install-status filter changes so the replaced content is\n * not mistaken for a no-op update.\n */\nimport { createElement as h, useEffect, useRef } from 'react'\nimport styles from '../../styles/List.module.css'\nimport type { HubPlugin, LocaleId, Translate } from '../../types.ts'\nimport { SITE_URL } from '../../logic/constants.ts'\nimport { useIncrementalList } from '../../hooks/useIncrementalList.ts'\nimport { PluginCard } from './PluginCard.tsx'\n\nexport function CatalogList({ plugins, failed, visible, total, t, langPath, reload, category, copied, installedName, installedVersion, hasUpdate, langKey, onInstall, onUninstall }: {\n plugins: HubPlugin[] | null\n failed: boolean\n visible: HubPlugin[]\n total: number\n t: Translate\n langPath: string\n reload: () => void\n category: string\n copied: string | null\n installedName: (p: HubPlugin) => string | null\n installedVersion: (p: HubPlugin) => string | null\n hasUpdate: (p: HubPlugin) => boolean\n langKey: LocaleId\n onInstall: (p: HubPlugin, opts?: { update?: boolean }) => void\n onUninstall: (p: HubPlugin) => void\n}) {\n /** 列表滚动容器:分类/搜索切换后列表内容替换但 scrollTop 保留,会让用户误以为列表没更新,需重置回顶部 */\n const listRef = useRef<HTMLDivElement | null>(null)\n /** 增量渲染:全量目录太大(4400+),只渲染首批,滚动接近底部时自动追加下一批 */\n const { shown, hasMore, sentinelRef } = useIncrementalList(visible)\n\n useEffect(() => {\n listRef.current?.scrollTo({ top: 0 })\n }, [category])\n\n return h('div', { className: styles.body },\n h('div', { ref: listRef, className: styles.list },\n plugins === null && !failed && h('div', { className: styles.state }, t('loading')),\n failed && h('div', { className: styles.state },\n h('div', { className: styles.stateTitle }, t('failed')),\n h('div', { className: styles.stateDesc }, t('failedDesc')),\n h('button', { className: styles.retryBtn, onClick: () => reload() }, t('retry')),\n ),\n plugins !== null && !failed && visible.length === 0 && h('div', { className: styles.state },\n h('div', { className: styles.stateTitle }, t('noResult')),\n h('div', { className: styles.stateDesc }, t('noResultDesc')),\n ),\n plugins !== null && !failed && shown.map((p) => h(PluginCard, {\n // 唯一 key:数据重构后同一 slug 可能对应多个作者仓库,仅用 slug 会撞 key,\n // 导致切换分类时 React 复用旧 DOM、列表不刷新。\n key: p.ownerSlug ? `${p.ownerSlug}/${p.slug}` : p.slug,\n plugin: p,\n copied,\n installedName,\n installedVersion,\n hasUpdate,\n t,\n langKey,\n langPath,\n onInstall,\n onUninstall,\n })),\n // 滚动加载哨兵:透明 1px 元素,进入视口即触发下一批渲染(加载是纯追加,无需按钮)\n hasMore && h('div', { ref: sentinelRef, className: styles.moreSentinel, 'aria-hidden': 'true' }),\n ),\n plugins !== null && !failed && h('div', { className: styles.footer },\n h('a', {\n className: styles.footLink,\n href: `${SITE_URL}${langPath}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n }, t('browseAll', { n: total })),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Market view: the browse experience for the catalog — category tabs,\n * search/sort/install-state controls and the plugin list. Owns nothing;\n * it wires catalog state (query/sort/filter/category) to the small\n * presentational components so PluginHubSection stays free of view internals.\n */\nimport { createElement as h, Fragment } from 'react'\nimport type { HubPlugin, LocaleId } from '../../types.ts'\nimport type { useCatalog } from '../../hooks/useCatalog.ts'\nimport { CategoryTabs } from '../layout/CategoryTabs.tsx'\nimport { CatalogControls } from '../layout/CatalogControls.tsx'\nimport { CatalogList } from '../catalog/CatalogList.tsx'\n\ntype CatalogState = ReturnType<typeof useCatalog>\n\nexport function MarketView({ catalog, t, langPath, langKey, copied, resultText, onInstall, onUninstall }: {\n catalog: CatalogState\n t: (key: string, params?: Record<string, string | number>) => string\n langPath: string\n langKey: LocaleId\n copied: string | null\n resultText: string | null\n onInstall: (p: HubPlugin, opts?: { update?: boolean }) => void\n onUninstall: (p: HubPlugin) => void\n}) {\n return h(Fragment, null,\n // 分类行保持原位原样:全部 + 各分类 chips\n h(CategoryTabs, {\n category: catalog.category,\n setCategory: catalog.setCategory,\n allLabel: t('all'),\n totalCount: catalog.total,\n langKey,\n }),\n h(CatalogControls, {\n query: catalog.query,\n setQuery: catalog.setQuery,\n sort: catalog.sort,\n sortDir: catalog.sortDir,\n toggleSort: catalog.toggleSort,\n t,\n resultText,\n }),\n h(CatalogList, {\n plugins: catalog.plugins,\n failed: catalog.failed,\n visible: catalog.visible,\n total: catalog.total,\n t,\n langPath,\n reload: catalog.reload,\n category: catalog.category,\n copied,\n installedName: catalog.installedName,\n installedVersion: catalog.installedVersion,\n hasUpdate: catalog.hasUpdate,\n langKey,\n onInstall,\n onUninstall,\n }),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Primary navigation: a compact segmented control switching between the\n * four top-level sections — Market (browse), Installed (manage), Custom\n * (manual command installs) and Settings (network sources & preferences).\n * Kept visually distinct from the category chips so the hierarchy reads:\n * section → category → plugin.\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/SectionTabs.module.css'\nimport { BellIcon, InstalledIcon, MarketIcon, SettingsIcon, TerminalIcon } from '../ui/icons.tsx'\n\nexport type SectionView = 'market' | 'installed' | 'custom' | 'settings'\n\nconst ORDER: Array<{ id: SectionView; labelKey: string; hintKey: string; Icon: () => ReturnType<typeof h> }> = [\n { id: 'market', labelKey: 'viewMarket', hintKey: 'viewMarketHint', Icon: MarketIcon },\n { id: 'installed', labelKey: 'viewInstalled', hintKey: 'viewInstalledHint', Icon: InstalledIcon },\n { id: 'custom', labelKey: 'viewCustom', hintKey: 'viewCustomHint', Icon: TerminalIcon },\n { id: 'settings', labelKey: 'viewSettings', hintKey: 'viewSettingsHint', Icon: SettingsIcon },\n]\n\nexport function SectionTabs({ view, setView, installedCount, t, noticeCount, onOpenNotifications }: {\n view: SectionView\n setView: (value: SectionView) => void\n installedCount: number\n t: (key: string) => string\n /** 通知中心红圈计数(记录 + 进行中任务 + 待重启);0 时不显示徽标 */\n noticeCount: number\n /** 点击打开通知中心 */\n onOpenNotifications: () => void\n}) {\n return h('div', { className: styles.root, role: 'tablist' },\n ORDER.map(({ id, labelKey, hintKey, Icon }) => h('button', {\n key: id,\n role: 'tab',\n 'aria-selected': view === id,\n title: t(hintKey),\n className: view === id ? styles.tabActive : styles.tab,\n onClick: () => setView(id),\n },\n h('span', { className: styles.tabIcon }, h(Icon)),\n t(labelKey),\n id === 'installed' && installedCount > 0\n ? h('span', { className: view === id ? styles.tabCountActive : styles.tabCount }, installedCount)\n : null)),\n // 通知入口:设置在最后一个 tab 后边,靠右对齐 —— 铃铛 + 红底白字计数(内联跟在铃铛后,不悬浮)\n h('button', {\n type: 'button',\n className: styles.noticeBtn,\n onClick: onOpenNotifications,\n title: t('notificationsHint'),\n 'aria-label': t('notificationsHint'),\n },\n h('span', { className: styles.noticeIcon }, h(BellIcon)),\n noticeCount > 0 ? h('span', { className: styles.noticeCount }, noticeCount > 99 ? '99+' : String(noticeCount)) : null),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Installed view: manages the plugins installed into the current profile.\n * Follows the mainstream extension-manager pattern (VSCode Installed tab) —\n * a searchable, sortable list of installed entries that mixes catalog\n * plugins (full metadata) and custom command installs (outside the catalog,\n * only runtime info, tagged with a custom badge). The toolbar carries a\n * search box plus two segmented radio-button groups: source filter\n * (all / catalog / custom) and sort (name / recently installed / stars / forks).\n * Each row carries restart (when pending), update and uninstall actions\n * and opens a detail modal with the full install metadata.\n *\n * Pure presentational: owns only local search/sort state; the InstalledItem\n * model arrives from the catalog hook and actions bubble up via callbacks.\n */\nimport { createElement as h, useMemo, useState } from 'react'\nimport type { FormEvent, MouseEvent, ReactNode } from 'react'\nimport styles from '../../styles/InstalledView.module.css'\nimport type { LocaleId, Translate } from '../../types.ts'\nimport type { InstalledItem } from '../../logic/installed.ts'\nimport { CATEGORY_LABELS, categoryLabel } from '../../logic/constants.ts'\nimport { SortArrowIcon } from '../ui/icons.tsx'\n\nconst INSTALLED_SORTS = ['sortName', 'sortInstalledAt', 'sortStars', 'sortForks'] as const\ntype InstalledSortKey = (typeof INSTALLED_SORTS)[number]\n\n/** 各排序的默认方向:名称按字母正序,最近安装 / Star / Fork 按数值倒序 */\nconst SORT_DEFAULT_DIR: Record<InstalledSortKey, 'asc' | 'desc'> = {\n sortName: 'asc', sortInstalledAt: 'desc', sortStars: 'desc', sortForks: 'desc',\n}\n\n/** 已安装列表的来源筛选:全部 / 目录收录 / 自定义安装 */\ntype SourceFilter = 'all' | 'catalog' | 'custom'\n\n/** 单选按钮组中的一个按钮(segmented control,与排序/来源筛选共用);\n 可带尾随图标(排序按钮激活时显示当前方向箭头) */\nfunction SegBtn({ active, onClick, label, icon }: {\n active: boolean\n onClick: () => void\n label: string\n icon?: ReactNode\n}) {\n return h('button', {\n type: 'button',\n className: active ? `${styles.segBtn} ${styles.segBtnActive}` : styles.segBtn,\n 'aria-pressed': active,\n onClick,\n }, label, icon)\n}\n\nfunction InstalledRow({ item, t, langKey, canReveal, revealLabel, onOpenDetail, onReveal, onUpdate, onUninstall, onRestart }: {\n item: InstalledItem\n t: Translate\n langKey: LocaleId\n /** 系统文件管理器可定位安装目录的平台(macOS / Linux):行内显示打开目录按钮 */\n canReveal: boolean\n /** 打开目录按钮文案(macOS = 在 Finder 中显示,Linux = 在文件夹中显示) */\n revealLabel: string\n onOpenDetail: (item: InstalledItem) => void\n /** 在系统文件管理器里定位安装目录(macOS Finder / Linux 文件管理器) */\n onReveal: (item: InstalledItem) => void\n onUpdate: (item: InstalledItem) => void\n onUninstall: (item: InstalledItem) => void\n /** 重启宿主:仅待重启(装完未挂载)条目展示,重启后该插件才生效 */\n onRestart: () => void\n}) {\n const name = item.plugin?.displayName ?? item.name\n const repo = item.repo\n const category = item.plugin?.category\n const desc = item.plugin?.description\n // 命令行安装进来的插件没有目录元数据(plugin === null):列表里打「自定义安装」标签区分\n const isCustom = item.plugin === null\n return h('li', {\n className: styles.row,\n onClick: () => onOpenDetail(item),\n role: 'button',\n tabIndex: 0,\n title: t('detail'),\n onKeyDown: (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n onOpenDetail(item)\n }\n },\n },\n // 第一行:状态点 + 名称/版本/更新徽标 + 行尾来源标签列 + 右侧固定操作按钮组\n h('div', { className: styles.rowTitleLine },\n // 运行状态点:绿 = 已加载进 loader;橙 = 待重启(装完未挂载的 dsh 插件);\n // 灰 = 非 dsh 插件(如官方示例项目,宿主不加载,无需重启)\n h('span', {\n className: item.loaded ? styles.statusDot\n : item.dshCapable ? `${styles.statusDot} ${styles.statusPending}`\n : `${styles.statusDot} ${styles.statusInactive}`,\n title: item.loaded ? t('statusRunning')\n : item.dshCapable ? t('statusPending')\n : t('exampleHint'),\n 'aria-label': item.loaded ? t('statusRunning')\n : item.dshCapable ? t('statusPending')\n : t('exampleHint'),\n }),\n // 主信息:名称 + 已装版本 + 有更新徽标(flex 撑满,超长省略)\n h('div', { className: styles.rowMain },\n h('span', { className: styles.rowTitle }, name),\n item.installedVersion\n ? h('span', { className: styles.versionBadge, title: t('installedVersionLabel') }, item.installedVersion)\n : null,\n item.hasUpdate\n ? h('span', { className: styles.updateBadge, title: t('updateAvailableHint') }, t('updateAvailable'))\n : null,\n ),\n // 来源标签列(行尾、操作按钮前,右对齐固定):目录插件 →「插件中心」(品牌色),\n // 命令行安装 →「手动安装」(琥珀色);两词 4 字等宽,所有条目标签同列对齐\n h('span', {\n className: isCustom\n ? `${styles.rowSourceTag} ${styles.rowSourceTagManual}`\n : `${styles.rowSourceTag} ${styles.rowSourceTagHub}`,\n title: isCustom ? t('manualInstallHint') : t('hubInstallHint'),\n }, isCustom ? t('manualInstall') : t('hubInstall')),\n // 行操作:重启(dsh 插件待重启时)/ 详情 / 更新(有更新时)/ 卸载 —— 按钮点击不触发行打开详情\n h('div', { className: styles.rowActions },\n // 装完未挂载的 dsh 插件:给「重启」入口,点了宿主重启后插件即生效;非 dsh 插件不提示(重启无用)\n !item.loaded && item.dshCapable\n ? h('button', {\n className: styles.rowRestart,\n type: 'button',\n title: t('restartPendingHint'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onRestart() },\n }, t('restart'))\n : null,\n // 支持文件管理器定位的平台(macOS / Linux):行内该位改为打开安装目录按钮;\n // 行点击本身即打开详情弹窗,故不支持的平台(如 Windows)不显示此按钮\n canReveal\n ? h('button', {\n className: styles.rowDetail,\n type: 'button',\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onReveal(item) },\n }, revealLabel)\n : null,\n item.hasUpdate && item.plugin\n ? h('button', {\n className: styles.rowUpdate,\n type: 'button',\n title: t('updateAvailableHint'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onUpdate(item) },\n }, t('update'))\n : null,\n h('button', {\n className: styles.rowUninstall,\n type: 'button',\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onUninstall(item) },\n }, t('uninstall')),\n ),\n ),\n // 示例项目徽标单独一行(非 dsh 插件):标签较长也能完整显示,不挤压名称行\n !item.dshCapable\n ? h('div', { className: styles.exampleRow },\n h('span', { className: styles.exampleBadge, title: t('exampleHint') }, t('exampleLabel')),\n )\n : null,\n // 第二行:仓库 · 分类(与名称左对齐缩进,独立成行不再挤压名称)\n repo || category\n ? h('div', { className: styles.rowMeta },\n item.repo ? h('span', { className: styles.rowRepo }, item.repo) : null,\n category ? h('span', { className: styles.rowCategory },\n categoryLabel(CATEGORY_LABELS, category, langKey)) : null,\n )\n : null,\n // 第三行(仅目录插件):简介单独一行展示,超长以省略号收尾\n desc ? h('div', { className: styles.rowDesc, title: desc }, desc) : null,\n )\n}\n\n/** 行列表:单个已安装列表(自定义安装与目录插件混排,靠徽标区分)。 */\nfunction RowList({ items, t, langKey, canReveal, revealLabel, onOpenDetail, onReveal, onUpdate, onUninstall, onRestart }: {\n items: InstalledItem[]\n t: Translate\n langKey: LocaleId\n canReveal: boolean\n revealLabel: string\n onOpenDetail: (item: InstalledItem) => void\n onReveal: (item: InstalledItem) => void\n onUpdate: (item: InstalledItem) => void\n onUninstall: (item: InstalledItem) => void\n onRestart: () => void\n}) {\n return h('ul', { className: styles.list },\n items.map((item) => h(InstalledRow, {\n key: item.name,\n item,\n t,\n langKey,\n canReveal,\n revealLabel,\n onOpenDetail,\n onReveal,\n onUpdate,\n onUninstall,\n onRestart,\n })),\n )\n}\n\nexport function InstalledView({ items, t, langKey, platform, onOpenDetail, onReveal, onUpdate, onUninstall, onRestart }: {\n items: InstalledItem[]\n t: Translate\n langKey: LocaleId\n /** 宿主系统平台(node process.platform):支持文件管理器定位(macOS / Linux)时行内显示打开目录按钮 */\n platform: string\n onOpenDetail: (item: InstalledItem) => void\n onReveal: (item: InstalledItem) => void\n /** 更新:仅目录插件且有更新时触发(自定义安装无目录信号可比) */\n onUpdate: (item: InstalledItem) => void\n onUninstall: (item: InstalledItem) => void\n /** 重启宿主:待重启条目行内按钮触发(装完未挂载的插件重启后生效) */\n onRestart: () => void\n}) {\n const [query, setQuery] = useState('')\n /** 默认按「最近安装」排序(最新在前);点其他排序按钮用该排序的默认方向(Star/Fork 最多在前、名称正序) */\n const [sort, setSort] = useState<InstalledSortKey>('sortInstalledAt')\n /** 当前排序方向:点同一个排序按钮切换 正/倒序;点新排序用该排序的默认方向 */\n const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc')\n /** 已安装列表的来源筛选:全部 / 目录收录 / 自定义安装(单选按钮组) */\n const [sourceFilter, setSourceFilter] = useState<SourceFilter>('all')\n\n /** 点击排序按钮:同一按钮切换正/倒序,新按钮用默认方向 */\n function pickSort(key: InstalledSortKey) {\n if (key === sort) setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))\n else { setSort(key); setSortDir(SORT_DEFAULT_DIR[key]) }\n }\n\n // 搜索 + 排序后的展示列表:搜索命中名称/包名/仓库/描述;排序支持名称/最近安装/Star/Fork\n const list = useMemo(() => {\n const q = query.trim().toLowerCase()\n const filtered = items.filter((item) => {\n if (!q) return true\n return (item.plugin?.displayName ?? item.name).toLowerCase().includes(q)\n || item.name.toLowerCase().includes(q)\n || (item.repo ?? '').toLowerCase().includes(q)\n || (item.plugin?.description ?? '').toLowerCase().includes(q)\n })\n const dir = sortDir === 'asc' ? 1 : -1\n return [...filtered].sort((a, b) => {\n if (sort === 'sortName') return (a.plugin?.displayName ?? a.name).localeCompare(b.plugin?.displayName ?? b.name) * dir\n // Star / Fork:目录插件按数量比较(正/倒序随 dir);自定义安装(无目录数据,stats 缺失)永远排最后\n if (sort === 'sortStars' || sort === 'sortForks') {\n const metric = sort === 'sortStars' ? 'stargazers_count' : 'forks_count'\n const sa = a.plugin?.stats?.[metric]\n const sb = b.plugin?.stats?.[metric]\n if (sa == null && sb == null) return 0\n if (sa == null) return 1\n if (sb == null) return -1\n return (sa - sb) * dir\n }\n // 最近安装:按安装时间比较;无安装时间记录的永远排最后\n const av = a.installedAt ?? ''\n const bv = b.installedAt ?? ''\n if (av === bv) return 0\n if (av === '') return 1\n if (bv === '') return -1\n return av.localeCompare(bv) * dir\n })\n }, [items, query, sort, sortDir])\n\n const catalogItems = list.filter((item) => item.plugin !== null)\n const customItems = list.filter((item) => item.plugin === null)\n // 已安装列表:搜索 + 排序后,再按来源筛选(全部 / 目录收录 / 自定义安装)\n const filtered = sourceFilter === 'all' ? list\n : sourceFilter === 'catalog' ? catalogItems : customItems\n\n // 行列表公共参数:macOS 文案特指 Finder,Windows / Linux 用通用「在文件夹中显示」\n const rowListProps = {\n t, langKey,\n canReveal: platform === 'darwin' || platform === 'win32' || platform === 'linux',\n revealLabel: platform === 'darwin' ? t('revealFolder') : t('openFolder'),\n onOpenDetail, onReveal, onUpdate, onUninstall, onRestart,\n }\n\n // 工具栏:第一行搜索框撑满,第二行来源筛选按钮组 + 排序按钮组(单选按钮组形态)\n const listToolbar = h('div', { className: styles.toolbar },\n h('div', { className: styles.searchWrap },\n h('input', {\n className: styles.searchInput,\n type: 'search',\n placeholder: t('installedSearch'),\n value: query,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) =>\n setQuery((e.target as HTMLInputElement).value),\n }),\n ),\n h('div', { className: styles.segRow },\n h('span', { className: styles.segLabel }, t('filterByLabel')),\n h('div', { className: styles.segGroup, role: 'radiogroup', 'aria-label': t('filterByLabel') },\n SegBtn({ active: sourceFilter === 'all', onClick: () => setSourceFilter('all'), label: t('all') }),\n SegBtn({ active: sourceFilter === 'catalog', onClick: () => setSourceFilter('catalog'), label: t('installedFilterCatalog') }),\n SegBtn({ active: sourceFilter === 'custom', onClick: () => setSourceFilter('custom'), label: t('customLabel') }),\n ),\n h('span', { className: styles.segLabel }, t('sortByLabel')),\n h('div', { className: styles.segGroup, role: 'radiogroup', 'aria-label': t('sortAria') },\n INSTALLED_SORTS.map((key) => SegBtn({\n active: sort === key,\n onClick: () => pickSort(key),\n label: t(key),\n icon: sort === key ? h(SortArrowIcon, { up: sortDir === 'asc' }) : null,\n })),\n ),\n ),\n )\n\n return h('div', { className: styles.root },\n listToolbar,\n // 筛选后的列表;一个都没装 → 引导空态,搜索/筛选无结果 → 无结果空态\n filtered.length === 0\n ? items.length === 0\n ? h('div', { className: styles.empty },\n h('div', { className: styles.emptyTitle }, t('installedEmpty')),\n h('div', { className: styles.emptyDesc }, t('installedEmptyDesc')),\n )\n : h('div', { className: styles.empty },\n h('div', { className: styles.emptyTitle }, t('noResult')),\n h('div', { className: styles.emptyDesc }, t('noResultDesc')),\n )\n : h(RowList, { items: filtered, ...rowListProps }),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Custom install view: a standalone top-level section for manually\n * installing npm packages or GitHub sources outside the catalog. Three\n * installer cards, one per channel — npm package (bare name or a full\n * npm/pnpm install command, including the official global `npm install -g`),\n * GitHub source and the official `dsh plugin ... add <target>` command —\n * each with a placeholder example above the input and its own format check.\n * The cards stay separate so a user never has to guess which format goes\n * where. Finished installs surface in the Installed view, marked as custom.\n *\n * Pure presentational: owns only the three local input/error states; the\n * actual install (custom source, gated by the security toggles) bubbles up\n * via onInstallCustom.\n */\nimport { createElement as h, useState } from 'react'\nimport type { FormEvent, MouseEvent } from 'react'\nimport styles from '../../styles/CustomInstallView.module.css'\nimport modal from '../../styles/Modal.module.css'\nimport type { Translate } from '../../types.ts'\nimport { CloseIcon, HelpIcon } from '../ui/icons.tsx'\n\n/* —— 自定义安装输入预检 ——\n * 提交前校验「输入是否符合该通道格式」,识别不了的输入不发请求,就地提示推荐格式。\n * 三个通道严格分开:npm 框认裸包名或完整 npm/pnpm 安装命令(含全局 `npm install -g`),\n * git 框只认 GitHub 地址,命令框只认官方 `dsh plugin --profile <name> add <target>`(--profile 必填,无 -p 简写)。\n * 这里只做格式校验,真正归一化/安装由服务端完成。 */\n\n/** GitHub 地址(带前缀形态):github:、https://github.com/、git+https://github.com/、git@github.com: */\nconst GITHUB_URL_RE = /^(?:github:|https?:\\/\\/github\\.com\\/|git\\+https?:\\/\\/github\\.com\\/|git@github\\.com:)([A-Za-z0-9._-]+)\\/([A-Za-z0-9._-]+?)(?:\\.git)?$/\n/** 裸 owner/repo(npm 包名只有 @scope/pkg 才带斜杠,无 @ 前缀的 a/b 一定是 GitHub 仓库) */\nconst GITHUB_BARE_RE = /^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$/\n/** npm 包名(含 @scope/pkg) */\nconst NPM_PACKAGE_RE = /^(?:@[a-z0-9._-]+\\/)?[a-z0-9._-]+$/\n\n/** DSH 命令行前缀(官方唯一形式 `dsh plugin --profile <name> add <target>`)—— 提取其中的安装目标。\n * 官方 CLI(apps/cli/src/args.ts,commander):--profile 为必填长选项(无 -p 简写,省略即报错),\n * 支持 `--profile=<name>` 等号形式;命令大小写不敏感。与 server 端 installTargetOf 口径一致。 */\nconst DSH_PLUGIN_CMD_RE = /^dsh\\s+plugin\\s+--profile(?:\\s+|=)\\S+\\s+add\\s+(.+)$/i\n\n/** npm 全局安装命令(官方 README 格式,如 `npm install -g @deepseek-ai/dsh @deepseek-harness-tui/dsh-tui`)——\n * 提取 -g 之后的包列表;任一包名非法返回 null(交给格式错误提示)。与 server 端 globalNpmPackagesOf 口径一致。 */\nconst NPM_GLOBAL_CMD_RE = /^npm\\s+(?:install|i)\\s+(?:-g|--global)\\s+(.+)$/i\n\n/** 常规 npm/pnpm 安装命令(装进当前 profile,如 `npm install lodash`、`pnpm add @scope/pkg`)——\n * 提取命令后的包列表;包列表在 splitPackages 里逐个校验。 */\nconst NPM_INSTALL_CMD_RE = /^(?:npm\\s+(?:install|i)|pnpm\\s+(?:add|i|install))\\s+(.+)$/i\n\nfunction installTargetOf(raw: string): string {\n const input = raw.trim()\n const match = DSH_PLUGIN_CMD_RE.exec(input)\n return match !== null ? match[1].trim() : input\n}\n\n/** 空格分隔的包列表:逐个按 npm 包名语法校验 + 拒绝以 - 开头的 token(npm 会把 --xxx 当参数而非包名),\n * 任一非法返回 null(交给格式错误提示)。与 server 端 globalNpmPackagesOf 同口径。 */\nfunction splitPackages(raw: string): string[] | null {\n const packages = raw.trim().split(/\\s+/).filter((p) => p !== '')\n if (packages.length === 0 || packages.some((p) => !NPM_PACKAGE_RE.test(p) || p.startsWith('-'))) return null\n return packages\n}\n\n/** NPM 框输入解析结果:\n * - pkg:裸包名或常规安装命令(npm install / npm i / pnpm add / pnpm i),提取单个安装目标;\n * - global:官方全局安装命令(npm install -g <pkgs>),提取包列表走全局通道。 */\ntype NpmInputParse =\n | { kind: 'pkg'; target: string }\n | { kind: 'global'; pkgs: string[] }\n\nfunction parseNpmInput(raw: string): NpmInputParse | null {\n const input = raw.trim()\n // 裸包名(含 @scope/pkg)\n if (NPM_PACKAGE_RE.test(input)) return { kind: 'pkg', target: input }\n // 官方全局安装 npm install -g <pkgs>(装系统级 CLI 工具)\n const global = NPM_GLOBAL_CMD_RE.exec(input)\n if (global !== null) {\n const pkgs = splitPackages(global[1])\n if (pkgs !== null) return { kind: 'global', pkgs }\n return null\n }\n // 常规安装命令 npm install <pkgs> / pnpm add <pkgs> —— 装进当前 profile,一次一个包\n const install = NPM_INSTALL_CMD_RE.exec(input)\n if (install !== null) {\n const pkgs = splitPackages(install[1])\n if (pkgs !== null && pkgs.length === 1) return { kind: 'pkg', target: pkgs[0] }\n return null\n }\n return null\n}\n\nfunction isGitHubInput(raw: string): boolean {\n const input = raw.trim()\n return GITHUB_URL_RE.test(input) || GITHUB_BARE_RE.test(input)\n}\n\nfunction isDshCommand(raw: string): boolean {\n return DSH_PLUGIN_CMD_RE.test(raw.trim())\n}\n\n/** 卡片标题旁的「帮助」弹窗:三块卡片各自的标题与格式清单语言包 key。 */\nconst HELP_CARDS = {\n npm: { titleKey: 'npmInstallLabel', contentKey: 'npmInstallHelp' },\n git: { titleKey: 'gitInstallLabel', contentKey: 'gitInstallHelp' },\n cmd: { titleKey: 'dshCmdLabel', contentKey: 'dshCmdHelp' },\n} as const\n\ntype HelpTarget = keyof typeof HELP_CARDS\n\nexport function CustomInstallView({ t, onInstallCustom, enableNpm, enableGit, enableDsh, onOpenSettings }: {\n t: Translate\n /** 命令行安装:输入 npm 包名 / npm、pnpm 安装命令 / GitHub 地址 / dsh plugin 命令即装\n * (custom 源,受安全设置开关控制);opts.globalNpm 表示官方 npm 全局安装命令(npm install -g),附带解析出的包列表 */\n onInstallCustom: (raw: string, opts?: { globalNpm?: string[] }) => void\n /** 安全信任三通道开关:关掉后对应输入卡片禁用(不提交),并引导去设置打开 */\n enableNpm: boolean\n enableGit: boolean\n enableDsh: boolean\n /** 引导去「设置 → 安全信任」打开被关闭的通道开关 */\n onOpenSettings: () => void\n}) {\n /** 自定义安装:NPM 包输入与格式错误('' = 无错误) */\n const [npmQuery, setNpmQuery] = useState('')\n const [npmError, setNpmError] = useState('')\n /** 自定义安装:GitHub 源码输入与格式错误('' = 无错误) */\n const [gitQuery, setGitQuery] = useState('')\n const [gitError, setGitError] = useState('')\n /** 自定义安装:DSH 命令输入与格式错误('' = 无错误) */\n const [cmdQuery, setCmdQuery] = useState('')\n const [cmdError, setCmdError] = useState('')\n /** 卡片标题旁「帮助」弹窗:null = 未打开;'npm' | 'git' | 'cmd' = 打开对应卡片的格式清单 */\n const [helpFor, setHelpFor] = useState<HelpTarget | null>(null)\n\n /** 通道关闭提示行:开关关掉后替代示例与输入行,引导去设置打开 */\n const channelOffRow = h('div', { className: styles.channelOff },\n h('span', { className: styles.channelOffText }, t('channelDisabledHint')),\n h('button', {\n type: 'button',\n className: styles.channelOffBtn,\n onClick: onOpenSettings,\n }, t('goToSettings')),\n )\n\n // 三个通道分开校验 —— 识别不了的输入不发请求,就地提示推荐写法。\n // NPM 框认裸包名或完整 npm/pnpm 命令(含全局 npm install -g,走 globalNpm 通道);\n // 命令框只认官方 dsh plugin 命令,提交时剥成裸目标发给服务端。\n const submitNpm = () => {\n const raw = npmQuery.trim()\n if (!raw) return\n const parsed = parseNpmInput(raw)\n if (parsed === null) { setNpmError(t('npmInstallInvalid')); return }\n if (parsed.kind === 'global') {\n onInstallCustom(raw, { globalNpm: parsed.pkgs })\n } else {\n onInstallCustom(parsed.target)\n }\n setNpmQuery('')\n setNpmError('')\n }\n const submitGit = () => {\n const target = gitQuery.trim()\n if (!target) return\n if (!isGitHubInput(target)) { setGitError(t('gitInstallInvalid')); return }\n onInstallCustom(target)\n setGitQuery('')\n setGitError('')\n }\n const submitCmd = () => {\n const raw = cmdQuery.trim()\n if (!raw) return\n if (!isDshCommand(raw)) { setCmdError(t('dshCmdInvalid')); return }\n onInstallCustom(installTargetOf(raw))\n setCmdQuery('')\n setCmdError('')\n }\n\n return h('div', { className: styles.root },\n // 页面说明:独立一级导航,交代「装完去哪看」\n h('p', { className: styles.desc }, t('customViewDesc')),\n // 三块卡片(一行一个):label + 文本框上方示例 + 输入行 + 错误区;\n // 安全信任开关关掉对应通道时,卡片禁用并显示「前往设置」提示行\n h('div', { className: styles.installCards },\n // NPM 包:输入包名或原生 npm/pnpm 安装命令即装(含官方全局 npm install -g)\n h('div', { className: enableNpm ? styles.installCard : `${styles.installCard} ${styles.installCardDisabled}` },\n h('div', { className: styles.installCardHead },\n h('span', { className: styles.installLabel }, t('npmInstallLabel')),\n // 标题旁帮助:点开该卡片的格式清单弹窗\n h('button', {\n type: 'button',\n className: styles.installHelpBtn,\n title: t('installHelp'),\n 'aria-label': t('installHelp'),\n onClick: () => setHelpFor('npm'),\n }, h(HelpIcon)),\n ),\n !enableNpm\n ? channelOffRow\n : [\n // 文本框上方的示例:把支持的原生命令模式写清楚(两行)\n h('div', { className: styles.installExample },\n t('npmInstallExample'), h('br'), t('npmInstallExample2')),\n h('div', { className: styles.installRow },\n h('input', {\n className: npmError ? `${styles.installInput} ${styles.installInputError}` : styles.installInput,\n type: 'text',\n placeholder: t('npmInstallPlaceholder'),\n value: npmQuery,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) => {\n setNpmQuery((e.target as HTMLInputElement).value)\n // 重新输入即清掉格式错误提示\n setNpmError('')\n },\n onKeyDown: (e: KeyboardEvent) => { if (e.key === 'Enter') submitNpm() },\n }),\n h('button', {\n className: styles.installBtn,\n type: 'button',\n disabled: npmQuery.trim() === '',\n onClick: submitNpm,\n }, t('installCliBtn')),\n ),\n // 格式错误:识别不了的包名就地说明,并给出推荐写法\n npmError ? h('div', { className: styles.installError }, npmError) : null,\n ],\n ),\n // GitHub 源码:输入仓库地址即装\n h('div', { className: enableGit ? styles.installCard : `${styles.installCard} ${styles.installCardDisabled}` },\n h('div', { className: styles.installCardHead },\n h('span', { className: styles.installLabel }, t('gitInstallLabel')),\n h('button', {\n type: 'button',\n className: styles.installHelpBtn,\n title: t('installHelp'),\n 'aria-label': t('installHelp'),\n onClick: () => setHelpFor('git'),\n }, h(HelpIcon)),\n ),\n !enableGit\n ? channelOffRow\n : [\n h('div', { className: styles.installExample }, t('gitInstallExample')),\n h('div', { className: styles.installRow },\n h('input', {\n className: gitError ? `${styles.installInput} ${styles.installInputError}` : styles.installInput,\n type: 'text',\n placeholder: t('gitInstallPlaceholder'),\n value: gitQuery,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) => {\n setGitQuery((e.target as HTMLInputElement).value)\n setGitError('')\n },\n onKeyDown: (e: KeyboardEvent) => { if (e.key === 'Enter') submitGit() },\n }),\n h('button', {\n className: styles.installBtn,\n type: 'button',\n disabled: gitQuery.trim() === '',\n onClick: submitGit,\n }, t('installCliBtn')),\n ),\n gitError ? h('div', { className: styles.installError }, gitError) : null,\n ],\n ),\n // 命令卡片:粘贴官方 dsh plugin 命令即装 —— 只认完整命令(--profile 必填,可含 = 等号,剥成裸目标安装)\n h('div', { className: enableDsh ? styles.installCard : `${styles.installCard} ${styles.installCardDisabled}` },\n h('div', { className: styles.installCardHead },\n h('span', { className: styles.installLabel }, t('dshCmdLabel')),\n h('button', {\n type: 'button',\n className: styles.installHelpBtn,\n title: t('installHelp'),\n 'aria-label': t('installHelp'),\n onClick: () => setHelpFor('cmd'),\n }, h(HelpIcon)),\n ),\n !enableDsh\n ? channelOffRow\n : [\n h('div', { className: styles.installExample }, t('dshCmdExample')),\n h('div', { className: styles.installRow },\n h('input', {\n className: cmdError ? `${styles.installInput} ${styles.installInputError}` : styles.installInput,\n type: 'text',\n placeholder: t('dshCmdPlaceholder'),\n value: cmdQuery,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) => {\n setCmdQuery((e.target as HTMLInputElement).value)\n setCmdError('')\n },\n onKeyDown: (e: KeyboardEvent) => { if (e.key === 'Enter') submitCmd() },\n }),\n h('button', {\n className: styles.installBtn,\n type: 'button',\n disabled: cmdQuery.trim() === '',\n onClick: submitCmd,\n }, t('installCliBtn')),\n ),\n cmdError ? h('div', { className: styles.installError }, cmdError) : null,\n ],\n ),\n ),\n // 帮助弹窗:点卡片标题旁的问号打开 —— 宽窗(720px)把该通道支持的命令格式整行展示,防止折行\n helpFor !== null\n ? h('div', {\n className: modal.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) setHelpFor(null) },\n },\n h('div', { className: `${modal.errorModal} ${modal.helpModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: modal.modalHead },\n h('div', { className: modal.modalTitle }, `${t(HELP_CARDS[helpFor].titleKey)} · ${t('helpModalTitle')}`),\n h('button', {\n className: modal.modalClose,\n 'aria-label': t('errorClose'),\n onClick: () => setHelpFor(null),\n }, h(CloseIcon)),\n ),\n h('div', { className: modal.modalBody },\n // 格式清单:一行一条;`命令\\t说明` 的说明跟在命令后,纯说明行以 \\t 开头\n h('div', { className: styles.helpBody },\n t(HELP_CARDS[helpFor].contentKey).split('\\n').map((line, i) => {\n const [cmd, note] = line.split('\\t')\n return h('div', { key: i, className: styles.helpLine },\n cmd !== '' ? h('span', { className: styles.helpCmd }, cmd) : null,\n note !== undefined ? h('span', { className: styles.helpNote }, note) : null,\n )\n }),\n ),\n ),\n ),\n )\n : null,\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Button-style dropdown (native <select> replacement).\n *\n * The trigger is a compact toolbar button — hairline border + subtle grey\n * fill + current value + chevron — so it sits naturally next to the other\n * toolbar buttons and takes a single slot of horizontal space. Clicking\n * outside or pressing Esc closes the panel; options get a hover fill and\n * the active one a brand highlight, all driven by the --hub-* tokens.\n */\nimport { createElement as h, useEffect, useRef, useState } from 'react'\nimport type { JSX } from 'react'\nimport styles from '../../styles/Dropdown.module.css'\nimport { ChevronDownIcon } from './icons.tsx'\n\nexport interface DropdownOption<T extends string> {\n value: T\n label: string\n /** 可选计数徽标(如「已安装 12」) */\n count?: number\n}\n\ninterface DropdownProps<T extends string> {\n value: T\n options: DropdownOption<T>[]\n onChange: (value: T) => void\n title?: string\n /** 额外挂到根节点上的类名(如 margin 微调) */\n className?: string\n}\n\nexport function Dropdown<T extends string>({ value, options, onChange, title, className }: DropdownProps<T>): JSX.Element {\n const [open, setOpen] = useState(false)\n const rootRef = useRef<HTMLDivElement | null>(null)\n\n // 面板展开时:点面板外部或按 Esc 关闭。\n useEffect(() => {\n if (!open) return\n const onDoc = (e: MouseEvent) => {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false)\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('mousedown', onDoc)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onDoc)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n const current = options.find((o) => o.value === value)\n\n return h('div', {\n className: className ? `${styles.dropdown} ${className}` : styles.dropdown,\n ref: rootRef,\n },\n h('button', {\n className: styles.dropdownBtn,\n type: 'button',\n title,\n 'aria-haspopup': 'listbox',\n 'aria-expanded': open,\n onClick: () => setOpen((v) => !v),\n },\n h('span', { className: styles.dropdownLabel }, current?.label ?? value),\n h('span', { className: open ? styles.dropdownArrowOpen : styles.dropdownArrow }, h(ChevronDownIcon)),\n ),\n open && h('div', { className: styles.dropdownPanel, role: 'listbox' },\n options.map((o) => h('button', {\n key: o.value,\n type: 'button',\n role: 'option',\n 'aria-selected': o.value === value,\n className: o.value === value ? styles.dropdownItemActive : styles.dropdownItem,\n onClick: () => {\n onChange(o.value)\n setOpen(false)\n },\n },\n h('span', { className: styles.dropdownItemLabel }, o.label),\n typeof o.count === 'number'\n ? h('span', { className: o.value === value ? styles.dropdownCountActive : styles.dropdownCount }, o.count)\n : null,\n )),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Compact switch used by the settings rows. Native-button based so it is\n * keyboard focusable and announces state via aria-checked; styling driven\n * by the --hub-* tokens (on = brand fill, off = neutral track).\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/Toggle.module.css'\n\nexport function Toggle({ checked, onChange, title, disabled }: {\n checked: boolean\n onChange: (next: boolean) => void\n title?: string\n disabled?: boolean\n}) {\n return h('button', {\n type: 'button',\n role: 'switch',\n 'aria-checked': checked,\n disabled,\n title,\n className: checked ? styles.toggleOn : styles.toggle,\n onClick: () => onChange(!checked),\n }, h('span', { className: styles.knob }))\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * System diagnostics list: one row per connectivity channel (npm registry /\n * GitHub API / catalog site), each with a live status badge — 200 OK in\n * green, Unreachable in red, Checking… while probing. The list runs\n * automatically when the page opens; every row is a button that re-probes\n * just that channel, so a click always yields visible feedback\n * (row pulses → badge flips → latency refreshes).\n */\nimport { createElement as h, useCallback, useEffect, useRef, useState } from 'react'\nimport styles from '../../styles/DiagnosticsView.module.css'\nimport type { EnvInfo, Translate } from '../../types.ts'\nimport { PLUGIN_VERSION } from '../../logic/constants.ts'\n\ntype ProbeKey = 'npm' | 'github' | 'catalog'\n\n/** 系统版本文本:提交 Issue 时粘贴到正文,方便作者复现。 */\nfunction formatEnv(env: EnvInfo): string {\n return [\n `DSH Plugin Hub ${PLUGIN_VERSION}`,\n `DSH ${env.dshVersion ?? 'unknown'}`,\n `Node ${env.nodeVersion}`,\n `${env.platform} ${env.arch} (${env.release})`,\n `Profile ${env.profile}`,\n env.dshHome ? `Home ${env.dshHome}` : '',\n ].filter(Boolean).join('\\n')\n}\n\ninterface RowState {\n key: ProbeKey\n /** 目标地址展示(registry 地址 / github.com / dsh-plugin.org) */\n display: string\n nameKey: string\n status: 'idle' | 'running' | 'ok' | 'fail'\n ms: number | null\n statusCode: number | null\n}\n\nconst INITIAL_ROWS: RowState[] = [\n { key: 'npm', display: 'registry.npmjs.org', nameKey: 'diagNpm', status: 'idle', ms: null, statusCode: null },\n { key: 'github', display: 'github.com', nameKey: 'diagGithub', status: 'idle', ms: null, statusCode: null },\n { key: 'catalog', display: 'api.dsh-plugin.org', nameKey: 'diagCatalog', status: 'idle', ms: null, statusCode: null },\n]\n\nexport function DiagnosticsView({ t, env, onCopy }: {\n t: Translate\n env: EnvInfo | null\n onCopy: (text: string) => void\n}) {\n const [rows, setRows] = useState<RowState[]>(INITIAL_ROWS)\n /** 当前探测请求:重测/卸载时 abort 旧请求,避免乱序结果覆盖 */\n const runningRef = useRef<AbortController | null>(null)\n\n const patchRows = (key: ProbeKey | undefined, patch: Partial<RowState>) => {\n setRows((prev) => prev.map((r) => (key === undefined || r.key === key ? { ...r, ...patch } : r)))\n }\n\n /** 探测:key 缺省 = 全量串行;传 key = 只重测该通道 */\n const run = useCallback((key?: ProbeKey) => {\n runningRef.current?.abort()\n const controller = new AbortController()\n runningRef.current = controller\n patchRows(key, { status: 'running', ms: null, statusCode: null })\n\n void (async () => {\n try {\n const res = await fetch('/dsh-plugin-hub/diagnostics', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: key === undefined ? '{}' : JSON.stringify({ key }),\n cache: 'no-store',\n signal: controller.signal,\n })\n if (!res.ok || res.body === null) throw new Error(`http ${res.status}`)\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n let nl = buf.indexOf('\\n')\n while (nl !== -1) {\n const raw = buf.slice(0, nl).trim()\n buf = buf.slice(nl + 1)\n if (raw !== '') {\n const ev = JSON.parse(raw) as { type?: string; key?: string; ms?: number | null; status?: number | null }\n if (ev.type === 'ok' || ev.type === 'fail') {\n patchRows(ev.key as ProbeKey, {\n status: ev.type === 'ok' ? 'ok' : 'fail',\n ms: typeof ev.ms === 'number' ? ev.ms : null,\n statusCode: typeof ev.status === 'number' ? ev.status : null,\n })\n }\n }\n nl = buf.indexOf('\\n')\n }\n }\n } catch {\n // 连接本地服务失败:该项标记失败(被新请求 abort 的旧请求直接忽略)\n if (controller.signal.aborted) return\n patchRows(key, { status: 'fail', ms: null, statusCode: null })\n }\n })()\n }, [])\n\n // 进入页面自动全量探测一轮;卸载时中断\n useEffect(() => {\n run()\n return () => runningRef.current?.abort()\n }, [run])\n\n const anyRunning = rows.some((r) => r.status === 'running')\n const allOk = !anyRunning && rows.every((r) => r.status === 'ok')\n const anyFail = !anyRunning && rows.some((r) => r.status === 'fail')\n\n return h('div', { className: styles.panel },\n // 最顶部:系统版本 —— 复制当前宿主版本与系统信息,提 Issue 时粘贴到正文便于复现\n h('div', { className: styles.envRow },\n h('div', { className: styles.envLabel },\n h('div', { className: styles.envTitle }, t('settingsEnvSnapshot')),\n h('div', { className: styles.envDesc }, t('settingsEnvSnapshotDesc')),\n ),\n h('button', {\n type: 'button',\n className: styles.envCopyBtn,\n disabled: env === null,\n onClick: () => { if (env) onCopy(formatEnv(env)) },\n }, t('settingsEnvCopy')),\n ),\n // 头部:右侧「立即诊断」按钮,点击全量重测所有通道\n h('div', { className: styles.head },\n h('span', { className: styles.headHint }, t('diagHeadHint', { n: rows.length })),\n h('button', {\n type: 'button',\n className: styles.runBtn,\n disabled: anyRunning,\n onClick: () => run(),\n }, t('diagRunAll')),\n ),\n rows.map((r) => {\n const badge = r.status === 'running'\n ? h('span', { className: `${styles.badge} ${styles.badgeRunning}` }, t('diagChecking'))\n : r.status === 'ok'\n ? h('span', { className: `${styles.badge} ${styles.badgeOk}` },\n r.statusCode !== null ? `HTTP ${r.statusCode} ${t('diagOk')}` : t('diagOk'))\n : r.status === 'fail'\n ? h('span', { className: `${styles.badge} ${styles.badgeFail}` }, t('settingsDiagFail'))\n : h('span', { className: `${styles.badge} ${styles.badgeIdle}` }, t('diagIdle'))\n return h('button', {\n key: r.key,\n type: 'button',\n className: styles.row,\n disabled: r.status === 'running',\n onClick: () => run(r.key),\n title: t('diagRecheck'),\n },\n h('span', { className: styles.name }, t(r.nameKey)),\n h('span', { className: styles.display }, r.display),\n h('span', { className: styles.meta }, r.status === 'ok' && r.ms !== null ? `${r.ms} ms` : ''),\n badge,\n )\n }),\n // 底部总览:全部通过 / 存在异常 / 检测中,汇总整体状态\n h('div', {\n className: `${styles.summary} ${anyRunning ? styles.summaryRunning : allOk ? styles.summaryOk : styles.summaryFail}`,\n }, anyRunning ? t('diagSummaryRunning') : allOk ? t('diagSummaryOk') : t('diagSummaryFail')),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Built-in log viewer dialog: no external software needed — the app opens\n * its own window and loads the local system log (JSONL at\n * ~/.dsh/profiles/<profile>/hub.log) straight from the server, one page at\n * a time.\n *\n * Every line is categorized twice: a function area (install / uninstall /\n * update / diagnostics / settings / system) and a severity level (debug /\n * info / success / warn / error). Filtering on both axes lets you target,\n * say, only install errors — so the exact incompatible step of an install\n * (or uninstall) is easy to spot. Search narrows by event code or message.\n *\n * Server pagination: GET /dsh-plugin-hub/logs?offset=&limit=&category=\n * &level=&query= → { entries, total, hasMore, path }. The footer shows the\n * real file location and reveals it in the system file manager.\n */\nimport { createElement as h, useCallback, useEffect, useRef, useState } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport view from '../../styles/LogsView.module.css'\nimport type { Translate } from '../../types.ts'\nimport { openLogFile } from '../../data/host.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\n/** 与服务端 /logs 返回的 LogEntry 对齐的客户端投影。 */\nexport interface LogEntryView {\n /** 毫秒时间戳 */\n at: number\n level: 'debug' | 'info' | 'success' | 'warn' | 'error'\n category: 'install' | 'uninstall' | 'update' | 'diagnostics' | 'settings' | 'system'\n /** 机器可读事件码,如 install.start */\n event: string\n message: string\n}\n\nexport type LogCategoryFilter = 'all' | LogEntryView['category']\nexport type LogLevelFilter = 'all' | LogEntryView['level']\n\nconst PAGE = 100\n\n/** 类别筛选标签:值 → 语言包 key(弹窗内 chip 与行内类别徽章共用)。 */\nconst CAT_LABEL: Record<LogEntryView['category'], string> = {\n install: 'logCatInstall',\n uninstall: 'logCatUninstall',\n update: 'logCatUpdate',\n diagnostics: 'logCatDiagnostics',\n settings: 'logCatSettings',\n system: 'logCatSystem',\n}\n\nconst CAT_FILTERS: Array<{ value: LogCategoryFilter; key: string }> = [\n { value: 'all', key: 'logCatAll' },\n { value: 'install', key: 'logCatInstall' },\n { value: 'uninstall', key: 'logCatUninstall' },\n { value: 'update', key: 'logCatUpdate' },\n { value: 'diagnostics', key: 'logCatDiagnostics' },\n { value: 'settings', key: 'logCatSettings' },\n { value: 'system', key: 'logCatSystem' },\n]\n\nconst LEVEL_FILTERS: Array<{ value: LogLevelFilter; key: string }> = [\n { value: 'all', key: 'logLvAll' },\n { value: 'error', key: 'logLvError' },\n { value: 'warn', key: 'logLvWarn' },\n { value: 'success', key: 'logLvSuccess' },\n { value: 'info', key: 'logLvInfo' },\n { value: 'debug', key: 'logLvDebug' },\n]\n\n/** 级别徽章文案:弹窗 chip 与行内级别徽章共用同一语言包 key。 */\nconst LEVEL_LABEL: Record<LogEntryView['level'], string> = {\n debug: 'logLvDebug',\n info: 'logLvInfo',\n success: 'logLvSuccess',\n warn: 'logLvWarn',\n error: 'logLvError',\n}\n\n/** 时间:YYYY-MM-DD HH:mm:ss(每条都精确到秒)。 */\nexport function fmtLogTime(at: number): string {\n const d = new Date(at)\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`\n}\n\n/** 导出文件名时间戳:2026-08-24_21-35-00。 */\nfunction fmtFileStamp(at: number): string {\n const d = new Date(at)\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}_${pad(d.getHours())}-${pad(d.getMinutes())}-${pad(d.getSeconds())}`\n}\n\n/** 单条日志行:时间 + 级别徽章 + 类别徽章 + 事件码 + 描述。查看器弹窗与设置页预览共用。 */\nexport function LogEntryRow({ e, t }: { e: LogEntryView; t: Translate }) {\n return h('div', { className: view.entry, title: e.message },\n h('span', { className: view.time }, fmtLogTime(e.at)),\n h('span', { className: `${view.badge} ${view[`badge${e.level}`]}` }, t(LEVEL_LABEL[e.level])),\n h('span', { className: `${view.catBadge} ${view[`cat${e.category}`]}` }, t(CAT_LABEL[e.category])),\n h('span', { className: view.event }, e.event),\n h('span', { className: view.message }, e.message),\n )\n}\n\nexport function LogsModal({ t, onClose }: {\n t: Translate\n onClose: () => void\n}) {\n const [category, setCategory] = useState<LogCategoryFilter>('all')\n const [level, setLevel] = useState<LogLevelFilter>('all')\n const [query, setQuery] = useState('')\n const [entries, setEntries] = useState<LogEntryView[]>([])\n const [total, setTotal] = useState(0)\n const [hasMore, setHasMore] = useState(false)\n const [path, setPath] = useState('')\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState(false)\n const [opening, setOpening] = useState(false)\n const [openFailed, setOpenFailed] = useState(false)\n const offsetRef = useRef(0)\n\n /** 拉一页:过滤参数取当前 state,偏移量由调用方给出。 */\n const fetchPage = useCallback(async (offset: number): Promise<{ entries: LogEntryView[]; total: number; hasMore: boolean; path: string } | null> => {\n try {\n const qs = new URLSearchParams({ offset: String(offset), limit: String(PAGE) })\n if (category !== 'all') qs.set('category', category)\n if (level !== 'all') qs.set('level', level)\n const q = query.trim()\n if (q !== '') qs.set('query', q)\n const res = await fetch(`/dsh-plugin-hub/logs?${qs.toString()}`, { cache: 'no-store' })\n if (!res.ok) return null\n return await res.json() as { entries: LogEntryView[]; total: number; hasMore: boolean; path: string }\n } catch {\n return null\n }\n }, [category, level, query])\n\n /** 从第一页重新加载(换筛选/搜索时)。 */\n const reload = useCallback(async () => {\n setLoading(true)\n const data = await fetchPage(0)\n if (data === null) {\n setError(true)\n setLoading(false)\n return\n }\n offsetRef.current = data.entries.length\n setEntries(data.entries)\n setTotal(data.total)\n setHasMore(data.hasMore)\n if (data.path !== '') setPath(data.path)\n setError(false)\n setLoading(false)\n }, [fetchPage])\n\n /** 追加下一页(「加载更多」)。 */\n const loadMore = useCallback(async () => {\n if (loading) return\n setLoading(true)\n const data = await fetchPage(offsetRef.current)\n if (data === null) {\n setError(true)\n setLoading(false)\n return\n }\n offsetRef.current += data.entries.length\n setEntries((prev) => [...prev, ...data.entries])\n setTotal(data.total)\n setHasMore(data.hasMore)\n setLoading(false)\n }, [fetchPage, loading])\n\n // 首次进入 + 类别/级别/搜索变化(搜索 280ms 防抖)都重查第一页\n const first = useRef(true)\n useEffect(() => {\n if (first.current) {\n first.current = false\n void reload()\n return\n }\n const id = window.setTimeout(() => { void reload() }, 280)\n return () => window.clearTimeout(id)\n }, [reload])\n\n /** 在系统文件管理器中定位日志文件(服务端 spawn open)。 */\n const openFile = async () => {\n if (opening) return\n setOpening(true)\n setOpenFailed(false)\n const ok = await openLogFile()\n setOpening(false)\n if (!ok) setOpenFailed(true)\n }\n\n /** 导出:拼纯文本 → Blob → 触发浏览器下载 .log 文件 */\n const exportFile = () => {\n const text = entries.map((e) => `[${fmtLogTime(e.at)}] [${e.level}] [${e.category}] [${e.event}] ${e.message}`).join('\\n')\n if (text === '') return\n const blob = new Blob([text], { type: 'text/plain;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `dsh-plugin-hub-log-${fmtFileStamp(Date.now())}.log`\n document.body.appendChild(a)\n a.click()\n a.remove()\n URL.revokeObjectURL(url)\n }\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.errorModal} ${styles.logModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('logModalTitle')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n // 类别筛选行:安装/卸载/更新… 功能域区分\n h('div', { className: view.filterBar },\n CAT_FILTERS.map((f) => h('button', {\n key: f.value,\n type: 'button',\n className: category === f.value ? `${view.filterChip} ${view.filterChipActive}` : view.filterChip,\n onClick: () => setCategory(f.value),\n }, t(f.key))),\n ),\n // 级别筛选行 + 搜索框:按级别区分报错与正常,便于针对性排查\n h('div', { className: view.filterBar },\n LEVEL_FILTERS.map((f) => h('button', {\n key: f.value,\n type: 'button',\n className: level === f.value ? `${view.filterChip} ${view.filterChipActive}` : view.filterChip,\n onClick: () => setLevel(f.value),\n }, t(f.key))),\n h('div', { className: view.search },\n h('input', {\n className: view.searchInput,\n type: 'search',\n value: query,\n placeholder: t('logSearchPlaceholder'),\n 'aria-label': t('logSearchPlaceholder'),\n onChange: (e) => setQuery((e.target as HTMLInputElement).value),\n }),\n ),\n ),\n h('div', { className: view.logList },\n error\n ? h('div', { className: view.empty }, t('logsLoadFail'))\n : loading && entries.length === 0\n ? h('div', { className: view.empty }, t('logsLoading'))\n : entries.length === 0\n ? h('div', { className: view.empty }, t('logEmptyFilter'))\n : entries.map((e, i) => h(LogEntryRow, { key: `${e.at}-${i}`, e, t })),\n // 分页:还有就「加载更多」,拉完了给个总数收尾\n entries.length > 0 && (hasMore\n ? h('button', {\n type: 'button',\n className: view.more,\n disabled: loading,\n onClick: () => void loadMore(),\n }, loading ? t('logsLoading') : t('logLoadMore'))\n : h('div', { className: view.moreEnd }, t('logNoMore', { n: total }))),\n ),\n ),\n // 底部:日志真实路径 + 打开文件 / 导出日志\n h('div', { className: view.foot },\n h('span', { className: view.footPath, title: path },\n `${t('logPathLabel')}: ${path === '' ? '…' : path}`),\n openFailed\n ? h('span', { className: view.footFail }, t('logOpenFileFail'))\n : h('span', { className: view.footCount }, t('logCount', { n: total })),\n h('div', { className: view.footActions },\n h('button', {\n type: 'button',\n className: view.btn,\n disabled: opening || path === '',\n title: t('logOpenFileTip'),\n onClick: () => void openFile(),\n }, t('logOpenFile')),\n h('button', {\n type: 'button',\n className: `${view.btn} ${view.btnPrimary}`,\n disabled: entries.length === 0,\n onClick: exportFile,\n }, t('logsExport')),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * 日志存放位置弹窗:设置页不内联长表单(挡视线),点「修改」弹窗编辑。\n * 两种输入方式并存 —— 手输目录 / .log 文件路径,或点「选择目录」调系统\n * 原生文件夹对话框(服务端 spawn osascript / FolderBrowserDialog / zenity)。\n * 文本框预填当前生效位置,目录选择器也从该位置打开 —— 默认地址是动态的\n * (随用户主目录/平台变化,如 ~/.dsh/profiles/<profile>/hub.log),必须实时展示。\n * 留空或点「恢复默认」= 回到默认;保存前服务端预验证可写。\n */\nimport { createElement as h, useEffect, useState } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport view from '../../styles/LogsView.module.css'\nimport type { Translate } from '../../types.ts'\nimport { chooseLogDir } from '../../data/host.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\nexport function LogsPathModal({ t, defaultPath, currentPath, onSaved, onClose }: {\n t: Translate\n /** 真正默认位置(服务端动态算出的 ~/.dsh/profiles/<profile>/hub.log),跨机器/平台不同 */\n defaultPath: string\n /** 当前生效的真实路径(可能已被自定义覆盖) */\n currentPath: string\n /** 保存成功回调(写入设置;父级据此刷新生效路径与日志列表) */\n onSaved: (value: string) => void\n onClose: () => void\n}) {\n // 打开即显示当前生效位置 —— 用户一眼看到日志现在存在哪,也方便在此基础上微调\n const [draft, setDraft] = useState(currentPath)\n const [saving, setSaving] = useState(false)\n const [fail, setFail] = useState(false)\n const [browsing, setBrowsing] = useState(false)\n const [browseFail, setBrowseFail] = useState(false)\n\n // Esc 关闭:与其它弹窗交互一致\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose() }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [onClose])\n\n /** 保存:空串 = 回默认;填回默认位置同样按「未自定义」处理(设置里保持干净)。\n * 服务端预建目录验证可写,失败给出反馈。 */\n const save = async () => {\n if (saving) return\n setSaving(true)\n setFail(false)\n try {\n const value = draft.trim()\n const normalized = value === '' || value === defaultPath ? '' : value\n const res = await fetch('/dsh-plugin-hub/settings', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ logPath: normalized }),\n cache: 'no-store',\n })\n if (!res.ok) {\n setFail(true)\n return\n }\n // 保存成功即关:主界面路径行随即刷新为新位置,本身就是反馈\n onSaved(normalized)\n onClose()\n } catch {\n setFail(true)\n } finally {\n setSaving(false)\n }\n }\n\n /** 选择目录:系统对话框从默认位置打开,选中路径回填输入框(仍可手改)。 */\n const browse = async () => {\n if (browsing) return\n setBrowsing(true)\n setBrowseFail(false)\n const picked = await chooseLogDir()\n setBrowsing(false)\n if (picked !== null) {\n setDraft(picked)\n setFail(false)\n } else {\n setBrowseFail(true)\n }\n }\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: { target: unknown; currentTarget: unknown }) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.modal} ${styles.modalWide}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('logPathSettingTitle')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n h('div', { className: view.pathDialog },\n h('div', { className: view.pathDialogDesc }, t('logPathSettingDesc')),\n // 手输路径 + 系统目录选择器两条路并行\n h('div', { className: view.pathDialogRow },\n h('input', {\n type: 'text',\n className: view.pathDraft,\n value: draft,\n placeholder: t('logPathPlaceholder'),\n spellCheck: false,\n onChange: (e: { currentTarget: HTMLInputElement }) => {\n setDraft(e.currentTarget.value)\n setFail(false)\n setBrowseFail(false)\n },\n }),\n h('button', {\n type: 'button',\n className: view.btn,\n disabled: browsing,\n title: t('logPathBrowse'),\n onClick: () => void browse(),\n }, browsing ? t('logPathSaving') : t('logPathBrowse')),\n ),\n // 提示 + 「恢复默认」:提示左、动作右,一行内不挤\n h('div', { className: view.pathDialogReset },\n h('span', { className: view.pathDialogHint }, t('logPathResetHint')),\n h('button', {\n type: 'button',\n className: view.linkBtn,\n onClick: () => {\n setDraft(defaultPath)\n setFail(false)\n setBrowseFail(false)\n },\n }, t('logPathReset')),\n ),\n browseFail && h('div', { className: view.footFail }, t('logPathBrowseFail')),\n fail && h('div', { className: view.footFail }, t('logPathSaveFail')),\n h('div', { className: view.pathDialogFoot },\n h('button', {\n type: 'button',\n className: view.btn,\n disabled: saving,\n onClick: onClose,\n }, t('confirmCancel')),\n h('button', {\n type: 'button',\n className: `${view.btn} ${view.btnPrimary}`,\n disabled: saving,\n onClick: () => void save(),\n }, saving ? t('logPathSaving') : t('logPathSave')),\n ),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * 系统日志入口视图:不在这里堆全文,而是给出「打开日志查看器」窗口入口 +\n * 日志文件真实路径(可一键在系统文件管理器中定位)+ 最近若干条预览。\n * 完整阅读/筛选/分页在 LogsModal 内置查看器弹窗里完成 —— 无需借助任何\n * 外部软件,点击即弹出自己的窗口加载本地 JSONL 日志。\n */\nimport { createElement as h, useCallback, useEffect, useRef, useState } from 'react'\nimport styles from '../../styles/LogsView.module.css'\nimport type { Translate } from '../../types.ts'\nimport { openLogFile } from '../../data/host.ts'\nimport { LogsModal, LogEntryRow, fmtLogTime, type LogEntryView } from '../modals/LogsModal.tsx'\nimport { LogsPathModal } from '../modals/LogsPathModal.tsx'\n\n/** 设置页预览条数:只放最近一小段,给用户快速感观,完整内容进查看器。 */\nconst PREVIEW = 12\n\nexport function LogsView({ t, logPath, onLogPathSaved }: {\n t: Translate\n /** 设置里已保存的日志位置覆盖(空串 = 默认位置) */\n logPath: string\n /** 保存自定义日志位置(写入设置,服务端同时预建目录验证可写) */\n onLogPathSaved: (value: string) => void\n}) {\n const [entries, setEntries] = useState<LogEntryView[]>([])\n const [path, setPath] = useState('')\n // 真正默认位置(~/.dsh/profiles/<profile>/hub.log,跨机器/平台动态):弹窗「恢复默认」用\n const [defaultPath, setDefaultPath] = useState('')\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState(false)\n const [open, setOpen] = useState(false)\n const [opening, setOpening] = useState(false)\n const [openFailed, setOpenFailed] = useState(false)\n // 日志存放位置弹窗:点「修改」打开,手输或选目录\n const [showPathModal, setShowPathModal] = useState(false)\n const mountedRef = useRef(true)\n\n const load = useCallback(async () => {\n setLoading(true)\n try {\n const res = await fetch('/dsh-plugin-hub/logs', { cache: 'no-store' })\n if (!res.ok) throw new Error(`http ${res.status}`)\n const data = await res.json() as { entries: LogEntryView[]; path: string; defaultPath?: string }\n if (mountedRef.current) {\n setEntries(data.entries)\n if (data.path !== '') setPath(data.path)\n if (data.defaultPath !== undefined) setDefaultPath(data.defaultPath)\n setError(false)\n }\n } catch {\n if (mountedRef.current) setError(true)\n } finally {\n if (mountedRef.current) setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n mountedRef.current = true\n void load()\n return () => { mountedRef.current = false }\n }, [load])\n\n /** 导出:拼纯文本 → Blob → 触发浏览器下载 .log 文件 */\n const exportFile = () => {\n const text = entries.map((e) => `[${fmtLogTime(e.at)}] [${e.level}] [${e.category}] [${e.event}] ${e.message}`).join('\\n')\n if (text === '') return\n const blob = new Blob([text], { type: 'text/plain;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = 'dsh-plugin-hub-log.log'\n document.body.appendChild(a)\n a.click()\n a.remove()\n URL.revokeObjectURL(url)\n }\n\n /** 在系统文件管理器中定位日志文件。 */\n const openFile = async () => {\n if (opening) return\n setOpening(true)\n setOpenFailed(false)\n const ok = await openLogFile()\n setOpening(false)\n if (!ok) setOpenFailed(true)\n }\n\n const preview = entries.slice(0, PREVIEW)\n return h('div', { className: styles.panel },\n h('div', { className: styles.head },\n h('span', { className: styles.headHint }, t('logsHeadHint')),\n h('div', { className: styles.actions },\n h('button', {\n type: 'button',\n className: `${styles.btn} ${styles.btnPrimary}`,\n onClick: () => setOpen(true),\n }, t('logViewerOpen')),\n h('button', { type: 'button', className: styles.btn, disabled: entries.length === 0, onClick: exportFile }, t('logsExport')),\n h('button', { type: 'button', className: styles.btn, disabled: loading, onClick: () => void load() }, t('logsRefresh')),\n ),\n ),\n // 日志存放位置:一行展示真实路径 + 「修改」弹窗编辑(手输 / 选目录)+ 一键定位文件\n h('div', { className: styles.pathRow },\n h('span', { className: styles.pathLabel }, t('logPathSettingTitle')),\n h('span', { className: styles.pathText, title: path }, path === '' ? '…' : path),\n openFailed && h('span', { className: styles.footFail }, t('logOpenFileFail')),\n h('button', {\n type: 'button',\n className: styles.btn,\n onClick: () => setShowPathModal(true),\n }, t('logPathChange')),\n h('button', {\n type: 'button',\n className: styles.btn,\n disabled: opening || path === '',\n title: t('logOpenFileTip'),\n onClick: () => void openFile(),\n }, t('logOpenFile')),\n ),\n error\n ? h('div', { className: styles.empty }, t('logsLoadFail'))\n : loading && entries.length === 0\n ? h('div', { className: styles.empty }, t('logsLoading'))\n : entries.length === 0\n ? h('div', { className: styles.empty }, t('logsEmpty'))\n : h('div', { className: styles.list },\n preview.map((e, i) => h('button', {\n key: `${e.at}-${i}`,\n type: 'button',\n className: styles.previewRow,\n onClick: () => setOpen(true),\n title: t('logViewerOpen'),\n }, h(LogEntryRow, { e, t }))),\n ),\n open && h(LogsModal, { t, onClose: () => setOpen(false) }),\n showPathModal && h(LogsPathModal, {\n t,\n defaultPath,\n currentPath: path,\n onSaved: (v: string) => {\n onLogPathSaved(v)\n void load() // 刷新生效路径与最近日志(新位置若已写入则立即可见)\n },\n onClose: () => setShowPathModal(false),\n }),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Settings view: desktop-settings navigation — a fixed left sidebar lists\n * the sections (icon + label, click to switch), the right pane shows the\n * active section's rows. New settings only add rows, new areas only add a\n * sidebar entry.\n *\n * Sections mirror what the local server actually enforces:\n * Updates & Sources — startup update check / npm mirror / HTTP proxy\n * (all wired into the install command path)\n * Security & Trust — restricted custom installs (server 403 gate)\n * Diagnostics — live connectivity probe + environment snapshot\n * Logs — system log viewer + storage location\n */\nimport { createElement as h, useState } from 'react'\nimport type { ChangeEvent, MouseEvent, ReactNode } from 'react'\nimport styles from '../../styles/SettingsView.module.css'\nimport modalStyles from '../../styles/Modal.module.css'\nimport { Dropdown } from '../ui/Dropdown.tsx'\nimport { Toggle } from '../ui/Toggle.tsx'\nimport { DiagnosticsView } from './DiagnosticsView.tsx'\nimport { LogsView } from './LogsView.tsx'\nimport {\n CloseIcon, DiagnosticsIcon, LogsIcon, ResetIcon, SecurityIcon, UpdatesIcon,\n} from '../ui/icons.tsx'\nimport type { EnvInfo, Translate } from '../../types.ts'\nimport type { HubSettings } from '../../hooks/useSettings.ts'\n\ntype SettingsSection = 'updates' | 'security' | 'diagnostics' | 'logs' | 'reset'\n\n/** 左侧导航:顺序即展示顺序;labelKey 是分组标题,icon 是行内小图标。 */\nconst NAV: Array<{ key: SettingsSection; labelKey: string; icon: () => ReturnType<typeof h> }> = [\n { key: 'updates', labelKey: 'settingsUpdate', icon: UpdatesIcon },\n { key: 'security', labelKey: 'settingsSecurity', icon: SecurityIcon },\n { key: 'diagnostics', labelKey: 'settingsDiagnostics', icon: DiagnosticsIcon },\n { key: 'logs', labelKey: 'settingsLogs', icon: LogsIcon },\n { key: 'reset', labelKey: 'settingsReset', icon: ResetIcon },\n]\n\n/** npm 镜像源预设:空串 = 官方源;值相等即视为选中对应预设,其余进入「自定义」输入。 */\nconst MIRROR_PRESETS: Array<{ value: string; labelKey: string }> = [\n { value: '', labelKey: 'mirrorOfficial' },\n { value: 'https://registry.npmmirror.com', labelKey: 'mirrorNpmmirror' },\n { value: 'https://mirrors.cloud.tencent.com/npm/', labelKey: 'mirrorTencent' },\n]\n\n/** 设置行:默认标签左控件右;stack=true 时控件独占一行(文本框整行显示),hairline 分隔。 */\nfunction SettingRow({ title, desc, children, stack = false }: {\n title: string\n desc?: string\n children: ReactNode\n stack?: boolean\n}) {\n return h('div', { className: stack ? styles.settingRowStack : styles.settingRow },\n h('div', { className: styles.settingLabel },\n h('div', { className: styles.settingTitle }, title),\n desc ? h('div', { className: styles.settingDesc }, desc) : null,\n ),\n h('div', { className: stack ? styles.settingControlStack : styles.settingControl }, children),\n )\n}\n\nexport function SettingsView({ t, settings, update, reset, env, onCopy }: {\n t: Translate\n settings: HubSettings\n update: (patch: Partial<HubSettings>) => void\n reset: () => void\n env: EnvInfo | null\n onCopy: (text: string) => void\n}) {\n /** 当前激活的分组:左侧导航点击切换,右侧只渲染这一组 */\n const [section, setSection] = useState<SettingsSection>('updates')\n /** 恢复默认确认弹窗:点按钮先弹窗询问,确认后才真正 reset(不做两段式按钮) */\n const [resetConfirm, setResetConfirm] = useState(false)\n\n const mirrorCustom = !MIRROR_PRESETS.some((p) => p.value === settings.npmRegistry)\n const onMirrorChange = (value: string) => {\n if (value === 'custom') return // 进入自定义输入:保持当前值,下方出现输入框\n update({ npmRegistry: value })\n }\n const onMirrorInput = (e: ChangeEvent<HTMLInputElement>) => update({ npmRegistry: e.target.value })\n const onProxyChange = (e: ChangeEvent<HTMLInputElement>) => update({ proxy: e.target.value })\n\n /** 每个分组的页面副标题(导航标题之上再补一句说明,保持桌面设置质感) */\n const pageDesc: Record<SettingsSection, string> = {\n updates: t('settingsUpdateDesc'),\n security: t('settingsSecurityDesc'),\n diagnostics: t('settingsDiagnosticsDesc'),\n logs: t('settingsLogsDesc'),\n reset: t('settingsResetDesc'),\n }\n const activeNav = NAV.find((n) => n.key === section) ?? NAV[0]\n\n // —— 各分组的设置卡片(一页一个 card,内部一行一设置) ——\n\n const updatesCard = h('div', { className: styles.card },\n h(SettingRow, {\n title: t('settingsCheckOnStart'),\n desc: t('settingsCheckOnStartDesc'),\n children: h(Toggle, {\n checked: settings.checkUpdatesOnStart,\n onChange: (v) => update({ checkUpdatesOnStart: v }),\n title: t('settingsCheckOnStart'),\n }),\n }),\n h(SettingRow, {\n title: t('settingsMirror'),\n desc: t('settingsMirrorDesc'),\n children: h(Dropdown, {\n value: mirrorCustom ? 'custom' : settings.npmRegistry,\n options: [\n ...MIRROR_PRESETS.map((p) => ({ value: p.value, label: t(p.labelKey) })),\n { value: 'custom', label: t('mirrorCustom') },\n ],\n onChange: onMirrorChange,\n title: t('settingsMirror'),\n className: styles.controlDropdown,\n }),\n }),\n // 自定义镜像源:下拉选中「自定义」或已存非预设值时,追加一行输入框(文本框独占一行)\n mirrorCustom && h(SettingRow, {\n title: t('mirrorCustom'),\n stack: true,\n children: h('input', {\n className: styles.textInput,\n type: 'url',\n value: settings.npmRegistry,\n placeholder: 'https://registry.npmjs.org',\n spellCheck: false,\n onChange: onMirrorInput,\n }),\n }),\n // 代理地址:文本框独占一行,整行输入,便于粘贴长代理地址\n h(SettingRow, {\n title: t('settingsProxy'),\n desc: t('settingsProxyDesc'),\n stack: true,\n children: h('input', {\n className: styles.textInput,\n type: 'text',\n value: settings.proxy,\n placeholder: 'http://127.0.0.1:7890',\n spellCheck: false,\n onChange: onProxyChange,\n }),\n }),\n )\n\n const securityCard = h('div', { className: styles.card },\n // 安全与信任:命令行安装的三个通道开关(NPM 包 / GitHub 源码 / DSH 命令)——\n // 服务端按通道门禁 403 拦截(npm 目标吃 enableNpmInstall、git 目标吃 enableGitInstall),\n // DSH 命令框为纯客户端通道:关掉后命令输入卡片禁用并引导去设置打开;\n // 目录内收录的插件安装不受影响(默认全部开启)\n h(SettingRow, {\n title: t('settingsEnableNpm'),\n desc: t('settingsEnableNpmDesc'),\n children: h(Toggle, {\n checked: settings.enableNpmInstall,\n onChange: (v) => update({ enableNpmInstall: v }),\n title: t('settingsEnableNpm'),\n }),\n }),\n h(SettingRow, {\n title: t('settingsEnableGit'),\n desc: t('settingsEnableGitDesc'),\n children: h(Toggle, {\n checked: settings.enableGitInstall,\n onChange: (v) => update({ enableGitInstall: v }),\n title: t('settingsEnableGit'),\n }),\n }),\n h(SettingRow, {\n title: t('settingsEnableDsh'),\n desc: t('settingsEnableDshDesc'),\n children: h(Toggle, {\n checked: settings.enableDshInstall,\n onChange: (v) => update({ enableDshInstall: v }),\n title: t('settingsEnableDsh'),\n }),\n }),\n )\n\n const diagnosticsCard = h('div', { className: styles.card },\n // 系统版本(最顶部)+ 通道状态列表:进入页面自动探测一轮,整行可点击重测单项,实时反馈\n h(DiagnosticsView, { t, env, onCopy }),\n )\n\n const logsCard = h('div', { className: styles.card },\n // 系统日志列表:操作记录(安装/卸载/设置/诊断),可刷新/复制/导出,点击弹窗查看;\n // 日志存放位置可设置(留空用默认),改动会写入设置并立即生效\n h(LogsView, {\n t,\n logPath: settings.logPath,\n onLogPathSaved: (v: string) => update({ logPath: v }),\n }),\n )\n\n const resetCard = h('div', { className: styles.card },\n h(SettingRow, {\n title: t('settingsReset'),\n desc: t('settingsResetDetail'),\n children: h('button', {\n type: 'button',\n className: styles.resetBtn,\n onClick: () => setResetConfirm(true),\n }, t('settingsResetRun')),\n }),\n )\n\n return h('div', { className: styles.root },\n // 左侧导航:固定宽度菜单栏,图标 + 名称,点击切换右侧内容\n h('nav', { className: styles.sidebar, 'aria-label': t('viewSettings') },\n NAV.map((item) => h('button', {\n key: item.key,\n type: 'button',\n className: section === item.key ? styles.navItemActive : styles.navItem,\n onClick: () => setSection(item.key),\n 'aria-current': section === item.key ? 'page' : undefined,\n title: t(item.labelKey),\n },\n h('span', { className: styles.navIcon }, h(item.icon)),\n h('span', { className: styles.navLabel }, t(item.labelKey)),\n )),\n ),\n // 右侧内容:只渲染当前分组,独立滚动\n h('div', { className: styles.content },\n h('div', { className: styles.pageHeader },\n h('div', { className: styles.pageTitle }, t(activeNav.labelKey)),\n h('div', { className: styles.pageDesc }, pageDesc[section]),\n ),\n section === 'updates' ? updatesCard\n : section === 'security' ? securityCard\n : section === 'diagnostics' ? diagnosticsCard\n : section === 'logs' ? logsCard\n : resetCard,\n ),\n // 恢复默认确认弹窗:点「恢复默认」先弹窗确认,确认后才真正 reset(替代两段式按钮)\n resetConfirm && h('div', {\n className: modalStyles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) setResetConfirm(false) },\n },\n h('div', { className: modalStyles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: modalStyles.modalHead },\n h('div', { className: modalStyles.modalTitle }, t('settingsReset')),\n h('button', {\n className: modalStyles.modalClose,\n type: 'button',\n 'aria-label': t('errorClose'),\n onClick: () => setResetConfirm(false),\n }, h(CloseIcon)),\n ),\n h('div', { className: modalStyles.modalBody },\n h('div', { className: modalStyles.failPrepareHint }, t('settingsResetConfirmDetail')),\n h('div', { className: modalStyles.modalActions },\n h('button', {\n className: modalStyles.restartLater,\n type: 'button',\n onClick: () => setResetConfirm(false),\n }, t('cancel')),\n h('button', {\n className: modalStyles.restartNowWarning,\n type: 'button',\n onClick: () => { setResetConfirm(false); reset() },\n }, t('settingsResetConfirm')),\n ),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Plugin Hub section: wires the catalog data pipeline, the background task\n * queue and the feedback state together. Data/queue logic lives in hooks/,\n * rendering is delegated to the small presentational components in this\n * folder; it hosts the dialogs/toast and the section-level copy actions.\n */\nimport { createElement as h, useEffect, useRef, useState } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../styles/Header.module.css'\nimport modalStyles from '../styles/Modal.module.css'\nimport type { EnvInfo, HubPlugin, SectionProps, ToastState } from '../types.ts'\nimport { installCommandOf, repoFromInstallTarget } from '../logic/install-command.ts'\nimport { PLUGIN_VERSION } from '../logic/constants.ts'\nimport { getEnv, revealInstallFolder } from '../data/host.ts'\nimport { useCatalog } from '../hooks/useCatalog.ts'\nimport { useLanguage } from '../hooks/useLanguage.ts'\nimport { useSettings } from '../hooks/useSettings.ts'\nimport { useTaskQueue } from '../hooks/useTaskQueue.ts'\nimport { ErrorModal, InstallModal, RestartConfirmModal, UninstallModal, Toast } from './modals/modals.tsx'\nimport { AboutModal } from './modals/AboutModal.tsx'\nimport { HubUpdateModal } from './modals/HubUpdateModal.tsx'\nimport { InstalledDetailModal } from './modals/InstalledDetailModal.tsx'\nimport { NotificationsModal } from './modals/NotificationsModal.tsx'\nimport { addFailure, addSuccess, addUpdateNotice, clearNotifications, ignoreUpdate, loadIgnoredUpdates, loadNotifications, removeNotification, removeUpdateNotice } from '../logic/failures.ts'\nimport type { NotificationRecord } from '../logic/failures.ts'\nimport { CatalogHeader } from './layout/CatalogHeader.tsx'\nimport { MarketView } from './views/MarketView.tsx'\nimport { SectionTabs } from './layout/SectionTabs.tsx'\nimport type { SectionView } from './layout/SectionTabs.tsx'\nimport { InstalledView } from './views/InstalledView.tsx'\nimport { CustomInstallView } from './views/CustomInstallView.tsx'\nimport { SettingsView } from './views/SettingsView.tsx'\nimport { CloseIcon } from './ui/icons.tsx'\nimport type { InstalledItem } from '../logic/installed.ts'\nimport { pluginOfItem } from '../logic/installed.ts'\n\nexport function PluginHubSection({ t: _hostT, locale }: SectionProps) {\n const { lang, langKey, langPath, t, toggleLang } = useLanguage(locale)\n const catalog = useCatalog(lang)\n /** 设置状态:服务端 hub-settings.json 持久化,本地乐观更新即时生效 */\n const { settings: hubSettings, ready: settingsReady, update: updateSettings, reset: resetSettings } = useSettings()\n\n /** 一级导航:插件中心 / 已安装 / 自定义安装 / 设置 */\n const [view, setView] = useState<SectionView>('market')\n\n /** 全局反馈 Toast:{id} 用于重复触发时重新走入场动画,kind 决定文案与配色 */\n const [toast, setToast] = useState<ToastState | null>(null)\n /** 复制反馈:记录刚复制安装命令的仓库,按钮短暂切换为「已复制」样式 */\n const [copied, setCopied] = useState<string | null>(null)\n /** 信任确认弹窗:记录待安装的插件,确认后才执行复制 */\n const [confirmPlugin, setConfirmPlugin] = useState<HubPlugin | null>(null)\n /** 弹窗动作是否为「更新」:已安装插件点「更新」→ 走同一条 add 命令原位覆盖重装,文案区分安装/更新 */\n const [confirmIsUpdate, setConfirmIsUpdate] = useState(false)\n /** 命令行安装确认弹窗:记录待安装的裸目标(npm 包名 / GitHub 地址,DSH 命令已剥成裸目标)——\n * 与应用商店同一套确认/进度/结果弹窗,提供时 plugin 传 null 走 customTarget 模式 */\n const [confirmCustomTarget, setConfirmCustomTarget] = useState<string | null>(null)\n /** 全局 npm 安装确认弹窗(官方 `npm install -g <pkgs>`):记录原始命令 + 解析出的包列表,\n * 走与应用商店同一套确认/进度/结果弹窗(plugin 传 null,InstallModal 走 globalNpm 模式) */\n const [confirmGlobalNpm, setConfirmGlobalNpm] = useState<{ raw: string; pkgs: string[] } | null>(null)\n /** Hub 自我更新说明弹窗:点「可更新」徽标先展示版本 + Markdown 变更记录,确认后再进安装弹窗 */\n const [showHubUpdate, setShowHubUpdate] = useState(false)\n /** 「关注我们」弹窗:GitHub 图标后按钮点击打开,展示平台介绍 + 用户反馈群二维码(Worker /about 推送) */\n const [showAbout, setShowAbout] = useState(false)\n /** 卸载确认弹窗:记录待卸载的插件(目录内) */\n const [uninstallPlugin, setUninstallPlugin] = useState<HubPlugin | null>(null)\n /** 卸载确认弹窗:记录待卸载的已安装项(自定义安装无目录数据,按包名直卸) */\n const [uninstallItem, setUninstallItem] = useState<InstalledItem | null>(null)\n /** 已安装详情弹窗:记录当前查看的已安装项(行点击 / 详情按钮打开) */\n const [detailItem, setDetailItem] = useState<InstalledItem | null>(null)\n /** 待重启确认弹窗:已安装列表行内「重启」先弹「立即重启 / 稍后重启」确认(与通知中心一致),\n * 确认后才真正触发宿主重启,避免误触 */\n const [showRestartConfirm, setShowRestartConfirm] = useState(false)\n /** 安装/卸载完成后的结果视图:停留弹窗内,点「完成」关闭 */\n const [installDone, setInstallDone] = useState(false)\n const [uninstallDone, setUninstallDone] = useState(false)\n /** 结果视图是否给「立即重启」:服务端任务终态带出(卸载时 loader 已即时移除 → false 只给「完成」;\n * true 时通知中心待重启条目同步常驻,直到用户点「立即重启」真正重启后才消失) */\n const [installNeedsRestart, setInstallNeedsRestart] = useState(true)\n const [uninstallNeedsRestart, setUninstallNeedsRestart] = useState(true)\n /** 结果视图「立即重启」:请求宿主重启后进入等待,服务回来后整页刷新 */\n const [restarting, setRestarting] = useState(false)\n /** 操作失败完整信息 + 所属插件仓库 + 失败类型(决定弹窗标题「安装失败/卸载失败」)+ 实际执行的安装命令 + 尝试过的安装方式(issue 预填用) */\n const [errorMsg, setErrorMsg] = useState<{ message: string; repo: string | null; kind: 'install' | 'uninstall'; command?: string; attempts?: string[] } | null>(null)\n /** 通知中心记录:localStorage 持久化,每次安装/卸载任务成败都留痕(启动时读回) */\n const [notifications, setNotifications] = useState<NotificationRecord[]>(() => loadNotifications())\n /** 通知中心弹窗:一级导航「设置」tab 后边的铃铛入口按钮打开 */\n const [showNotifications, setShowNotifications] = useState(false)\n /** 「忽略本次更新」确认弹窗:{ repo, version };null = 关闭 */\n const [ignoreTarget, setIgnoreTarget] = useState<{ repo: string; version?: string } | null>(null)\n /** 宿主机器环境快照:提交 bug 的 issue 正文附带;取不到为 null(链接少环境段,不阻塞) */\n const [env, setEnv] = useState<EnvInfo | null>(null)\n useEffect(() => {\n let alive = true\n void getEnv().then((info) => { if (alive) setEnv(info) })\n return () => { alive = false }\n }, [])\n\n const queue = useTaskQueue({\n t,\n refreshInstalled: catalog.refreshInstalled,\n onInstallDone: (viaModal, repo, needsRestart) => {\n setInstallNeedsRestart(needsRestart)\n if (viaModal) setInstallDone(true)\n else setToast({ id: Date.now(), kind: 'done' })\n // 安装成功也写入通知记录:通知中心里成功与失败都能看到\n setNotifications(addSuccess({ kind: 'install', repo: repo ?? '' }))\n },\n onUninstallDone: (viaModal, repo, needsRestart) => {\n setUninstallNeedsRestart(needsRestart)\n if (viaModal) setUninstallDone(true)\n else setToast({ id: Date.now(), kind: 'removed' })\n setNotifications(addSuccess({ kind: 'uninstall', repo: repo ?? '' }))\n },\n onError: (message, repo, kind, command, attempts) => {\n setErrorMsg({ message, repo, kind, command, attempts })\n // 失败自动写入通知记录:任务在后台结束时没人盯着也能留痕\n setNotifications(addFailure({ kind, repo: repo ?? '', message, command, attempts }))\n },\n installPlugin: confirmPlugin,\n installCustomTarget: confirmCustomTarget,\n installGlobalTarget: confirmGlobalNpm ? confirmGlobalNpm.pkgs.join(' ') : null,\n uninstallPlugin,\n uninstallName: uninstallItem ? uninstallItem.name : null,\n installedName: catalog.installedName,\n // 待重启项展示信息补齐:从目录按 owner/repo 解析插件简介/版本(找不到返回 null,行内只显示仓库名)\n resolvePending: (repo) => {\n const p = catalog.plugins?.find((x) => x.source?.repo === repo)\n return p ? { desc: p.description, version: p.version } : null\n },\n })\n\n /** 补齐更新提醒:把「当前有更新但通知中心还没有」的插件补写进通知(repo+version 去重)。\n * 返回本次实际新增的条数(0 = 无可更新或全部已提示过)。启动检查与打开通知中心共用,\n * 保证通知中心始终反映可更新状态:同一版本只一条、清空/删除后重开恢复、更新完成后消失。 */\n const syncUpdateNotices = (): number => {\n const updatable = catalog.installedItems.filter((i) => i.hasUpdate && i.plugin)\n if (updatable.length === 0) return 0\n const known = new Set(loadIgnoredUpdates())\n // 已忽略(repo+version 持久化)与通知中心已有的更新提醒都不再补写:\n // 忽略本次版本后不再提醒,直到下一个新版本(version 变化)才重新提示\n for (const r of loadNotifications()) {\n if (r.kind === 'update') known.add(`${r.repo}@${r.version ?? ''}`)\n }\n const fresh = updatable.filter((item) =>\n item.repo !== null && !known.has(`${item.repo}@${item.catalogVersion ?? ''}`))\n if (fresh.length === 0) return 0\n for (const item of fresh) {\n if (item.repo) addUpdateNotice({ kind: 'update', repo: item.repo, version: item.catalogVersion ?? undefined })\n }\n setNotifications(loadNotifications())\n return fresh.length\n }\n\n // 启动更新策略:目录数据与设置都就绪后触发一次 —— 开启「启动时检查更新」→ 发现可更新插件\n // 即写入通知中心(每条一条,点击可去更新),toast 同步提示已入通知。\n // 绝不自动安装:是否更新完全由用户决定。\n // ref 守卫保证只跑一次,后续目录刷新/设置变化不会重复打扰。\n const startupCheckedRef = useRef(false)\n useEffect(() => {\n if (startupCheckedRef.current) return\n if (!settingsReady || catalog.plugins === null || catalog.failed) return\n startupCheckedRef.current = true\n if (!hubSettings.checkUpdatesOnStart) return\n const added = syncUpdateNotices()\n if (added > 0) setToast({ id: Date.now(), kind: 'updates', n: added })\n }, [settingsReady, hubSettings, catalog.plugins, catalog.failed, catalog.installedItems, queue])\n\n // 信任/卸载/更新说明弹窗打开时按 Esc 关闭;任务进入后台队列后可随时关闭(任务继续)\n useEffect(() => {\n if (!confirmPlugin && !confirmCustomTarget && !confirmGlobalNpm && !uninstallPlugin && !uninstallItem && !detailItem && !showHubUpdate && !showAbout && !showNotifications && !ignoreTarget) return\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setConfirmPlugin(null)\n setConfirmCustomTarget(null)\n setConfirmGlobalNpm(null)\n setUninstallPlugin(null)\n setUninstallItem(null)\n setDetailItem(null)\n setUninstallDone(false)\n setShowHubUpdate(false)\n setShowAbout(false)\n setShowNotifications(false)\n setIgnoreTarget(null)\n }\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [confirmPlugin, confirmCustomTarget, uninstallPlugin, uninstallItem, detailItem, showHubUpdate, showAbout, showNotifications, ignoreTarget])\n\n // Toast 统一自动消失\n useEffect(() => {\n if (!toast) return\n const timer = window.setTimeout(() => setToast(null), 2400)\n return () => window.clearTimeout(timer)\n }, [toast])\n\n /** 复制文本到剪贴板,返回是否成功(Clipboard API + 隐藏 textarea 兜底)。 */\n const doCopy = async (text: string): Promise<boolean> => {\n try {\n await navigator.clipboard.writeText(text)\n return true\n } catch {\n // Clipboard API unavailable (permissions/iframe) — fall back to the\n // legacy hidden-textarea trick, which works in any context.\n const ta = document.createElement('textarea')\n ta.value = text\n ta.style.position = 'fixed'\n ta.style.opacity = '0'\n document.body.appendChild(ta)\n ta.select()\n let ok = false\n try {\n ok = document.execCommand('copy')\n } catch {\n ok = false\n }\n document.body.removeChild(ta)\n return ok\n }\n }\n\n /** 命令行安装目标是否已安装(与服务端 already 判定同口径):GitHub 地址按仓库身份匹配\n * (归一化后比对已装项的 repo/spec),npm 包名按依赖 key 直查。命中 → 弹窗转「更新」语义\n * (mode=update 放行覆盖重装),避免重复点击撞 409 报错。 */\n const customTargetInstalled = (raw: string): boolean => {\n const target = raw.trim()\n if (!target) return false\n const repo = repoFromInstallTarget(target)\n const isRepo = /^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$/.test(repo)\n if (isRepo) {\n const needle = repo.toLowerCase()\n return catalog.installedItems.some((i) =>\n (i.repo !== null && i.repo.toLowerCase() === needle) ||\n repoFromInstallTarget(i.spec).toLowerCase() === needle)\n }\n return catalog.installedItems.some((i) => i.name === target)\n }\n\n /** 弹窗动作一:复制安装命令到剪贴板,引导去终端粘贴执行(npm 通道显示包名命令)。 */\n const copyCommand = async (p: HubPlugin) => {\n const repo = p.source?.repo ?? ''\n const ok = await doCopy(installCommandOf(p))\n if (ok) {\n setCopied(repo)\n setToast({ id: Date.now(), kind: 'copied' })\n window.setTimeout(() => setCopied((cur) => (cur === repo ? null : cur)), 1600)\n }\n setConfirmPlugin(null)\n }\n\n /** 卸载弹窗动作:复制卸载命令,万一直接卸载失败可去终端手动执行。\n * 自定义安装(无目录数据)按已安装项包名直卸,同样给复制通道。 */\n const copyUninstallCommand = async () => {\n const name = uninstallItem ? uninstallItem.name : (uninstallPlugin ? catalog.installedName(uninstallPlugin) : null)\n if (!name) return\n const ok = await doCopy(`dsh plugin remove ${name}`)\n if (ok) setToast({ id: Date.now(), kind: 'copied' })\n }\n\n /** 详情弹窗动作:在系统文件管理器里定位安装目录;服务端失败给 toast 提示。 */\n const revealFolder = async (item: InstalledItem) => {\n const ok = await revealInstallFolder(item.name)\n if (!ok) setToast({ id: Date.now(), kind: 'revealFail' })\n }\n\n /** 「立即重启」:POST 同源 /restart,宿主进程自杀重启;随后轮询服务恢复后整页刷新。 */\n const requestRestart = async () => {\n if (restarting) return\n setRestarting(true)\n try {\n // 响应可能在宿主进程被 kill 前返回,也可能直接断连 —— 两种都属正常\n await fetch('/dsh-plugin-hub/restart', { method: 'POST' })\n } catch {\n /* 服务已终止,无需处理 */\n }\n // 轮询同源端点,服务恢复后整页 reload(让新挂载的 bundle 完全初始化)\n let attempts = 0\n const poll = async () => {\n attempts += 1\n try {\n const res = await fetch('/dsh-plugin-hub/active', { method: 'GET', cache: 'no-store' })\n if (res.ok) {\n window.location.reload()\n return\n }\n } catch {\n /* 服务尚未恢复 */\n }\n if (attempts < 60) {\n window.setTimeout(poll, 1000)\n } else {\n setRestarting(false)\n setToast({ id: Date.now(), kind: 'fail' })\n }\n }\n window.setTimeout(poll, 1200)\n }\n\n const { total, installedName, installedVersion, hasUpdate } = catalog\n // 统计数字:官网 /api/stats.json 优先;拉取失败时用已加载列表兜底,避免展示 undefined。\n const statsTotal = catalog.stats?.total ?? total\n const statsVerified = catalog.stats?.verified ?? 0\n\n const count = catalog.visible.length\n\n // Hub 自身条目(目录数据里的 dshplugin/dsh-plugin-hub):头部「可更新」徽标的更新目标。\n // useCatalog 在过滤目录(自身不进插件列表)前单独保留该条目;目录可能尚未加载(此时为 null,徽标不渲染)。\n const hubEntry = catalog.hubPlugin\n\n return h('div', { className: styles.root },\n h(CatalogHeader, {\n t,\n langPath,\n statsTotal,\n statsVerified,\n onToggleLang: toggleLang,\n // Hub 自身版本信息入口:版本号常驻可点(无更新也看得到当前版本更新内容),\n // 有可用更新时版本号后紧跟红色「可更新」徽标(同一入口),点击都打开同一个更新说明弹窗。\n // 有更新弹窗显示新版本 + Markdown 变更记录,点「直接更新」进安装弹窗覆盖重装。\n hubUpdate: catalog.hubHasUpdate,\n // 点击版本号/徽标:先强制刷新拉取最新版本信息(发版后点击即见新版本),再打开弹窗\n onVersionClick: () => {\n void catalog.refreshHub().then(() => setShowHubUpdate(true))\n },\n onAboutClick: () => setShowAbout(true),\n }),\n // 一级导航行:tab 占满左侧,通知入口靠右(「设置」tab 后边,右对齐)\n h('div', { className: styles.tabsRow },\n // 「已安装」徽标 = 目录插件 + 自定义安装总数(installedItems 已排除 hub 自身)\n h(SectionTabs, {\n view,\n setView,\n installedCount: catalog.installedItems.length,\n t,\n // 通知中心入口:红圈徽标 = 记录数 + 进行中任务 + 待重启(有动静才醒目)\n noticeCount: notifications.length + queue.queue.length + queue.pendingRestarts.length,\n onOpenNotifications: () => {\n // 打开弹窗时补齐更新提醒(受「启动时检查更新」开关约束):同一版本只一条,\n // 清空/删除后重开仍恢复,直到插件更新完成才消失\n if (hubSettings.checkUpdatesOnStart) syncUpdateNotices()\n setShowNotifications(true)\n },\n }),\n ),\n view === 'market'\n ? h(MarketView, {\n catalog,\n t,\n langPath,\n langKey,\n copied,\n // 列表头部「筛选出 N 条」:分类/搜索/安装状态筛选后的结果数;全部视图且未筛选时显示总数\n resultText: catalog.plugins === null || catalog.failed\n ? null\n : catalog.category === 'all' && count === total\n ? t('pluginsTotal', { n: count })\n : t('filterResults', { n: count }),\n onInstall: (p, opts) => {\n setInstallDone(false)\n setConfirmIsUpdate(opts?.update ?? false)\n // 与卸载一致:重置弹窗关联任务,避免新弹窗误匹配到进行中的任务而禁用安装按钮\n queue.clearModalTask()\n setConfirmPlugin(p)\n },\n onUninstall: (p) => {\n setUninstallDone(false)\n queue.clearModalTask()\n setUninstallPlugin(p)\n },\n })\n : view === 'installed'\n ? h(InstalledView, {\n items: catalog.installedItems,\n langKey,\n t,\n // 支持系统文件管理器定位的平台(macOS / Linux)上,行内「打开详情」替换为\n // 打开安装目录按钮(行点击本身即打开详情弹窗);Windows 不支持则按钮不显示\n platform: env?.platform ?? '',\n // 行点击 / 详情按钮:打开已安装详情弹窗(完整元数据 + 运行时信息)\n onOpenDetail: (item) => setDetailItem(item),\n onReveal: (item) => { void revealFolder(item) },\n // 更新:已安装视图的「更新」= 目录插件覆盖重装,与市场列表内更新同一流程\n onUpdate: (item) => {\n if (!item.plugin) return\n setDetailItem(null)\n setInstallDone(false)\n setConfirmIsUpdate(true)\n queue.clearModalTask()\n setConfirmPlugin(item.plugin)\n },\n // 卸载:目录插件与自定义安装统一按已安装项走卸载确认弹窗(自定义无目录数据,按包名直卸)\n onUninstall: (item) => {\n setDetailItem(null)\n setUninstallDone(false)\n queue.clearModalTask()\n setUninstallItem(item)\n },\n // 重启:待重启条目行内按钮 → 先弹「立即重启 / 稍后重启」确认(与通知中心一致),确认后才触发宿主重启\n onRestart: () => setShowRestartConfirm(true),\n })\n : view === 'custom'\n ? h(CustomInstallView, {\n t,\n // 命令行安装:与应用商店同一套确认/进度/结果弹窗 —— 输入 npm 包名 / GitHub 地址 /\n // dsh plugin 命令即装(custom 源,受安全设置三开关控制)。点安装先弹确认窗,\n // 确认后走队列安装(实时进度 + 成功结果视图);目标已安装 → 弹窗转「更新」覆盖重装,\n // 不再撞「already installed」报错(第一次安装没有反馈才导致用户重复点击)。\n // 安全信任开关关掉对应通道 → 卡片禁用并提示去设置打开(onOpenSettings 跳到设置页)。\n enableNpm: hubSettings.enableNpmInstall,\n enableGit: hubSettings.enableGitInstall,\n enableDsh: hubSettings.enableDshInstall,\n onOpenSettings: () => setView('settings'),\n onInstallCustom: (raw, opts) => {\n const target = raw.trim()\n if (!target) return\n setInstallDone(false)\n // 与目录安装一致:重置弹窗关联任务,避免新弹窗误匹配到进行中的任务\n queue.clearModalTask()\n // 官方全局 npm 安装(npm install -g <pkgs>):弹窗走 globalNpm 模式(系统级 CLI 工具,\n // 不进插件列表,不做「已安装→更新」判定 —— npm install -g 对已装包是原位覆盖更新,天然幂等)\n if (opts?.globalNpm && opts.globalNpm.length > 0) {\n setConfirmCustomTarget(null)\n setConfirmIsUpdate(false)\n setConfirmGlobalNpm({ raw, pkgs: opts.globalNpm })\n return\n }\n setConfirmGlobalNpm(null)\n setConfirmIsUpdate(customTargetInstalled(target))\n setConfirmCustomTarget(target)\n },\n })\n : h(SettingsView, {\n t,\n settings: hubSettings,\n update: updateSettings,\n reset: resetSettings,\n env,\n onCopy: (text: string) => {\n doCopy(text)\n setToast({ id: Date.now(), kind: 'copied' })\n },\n }),\n // Hub 版本信息弹窗:版本号/徽标点击打开 —— 有更新显示新版本 + 变更记录 + 「直接更新」,\n // 无更新显示当前版本 + 记录 + 「已是最新」。Worker 拉取失败时兜底展示当前版本号。\n showHubUpdate && h(HubUpdateModal, {\n info: catalog.hubUpdateInfo ?? { version: PLUGIN_VERSION },\n lang,\n t,\n hasUpdate: catalog.hubHasUpdate,\n onClose: () => setShowHubUpdate(false),\n onProceed: () => {\n setShowHubUpdate(false)\n // 与列表内更新同一流程:覆盖重装 dsh-plugin + 结果视图「立即重启」\n if (hubEntry) {\n setInstallDone(false)\n setConfirmIsUpdate(true)\n queue.clearModalTask()\n setConfirmPlugin(hubEntry)\n }\n },\n }),\n // 「关注我们」弹窗:GitHub 图标后按钮点击打开 —— 平台介绍 + 用户反馈群二维码,\n // 内容由 dsh-update Worker 的 /about 接口以 Markdown 形式推送,作者随时可改,非写死。\n // Worker 未推送(info 为 null)时弹窗仍能打开并展示兜底文案,不影响其他功能。\n showAbout && h(AboutModal, {\n info: catalog.hubAboutInfo ?? null,\n lang,\n t,\n onClose: () => setShowAbout(false),\n }),\n // 安装/卸载任务通知中心:本地持久化的成败清单,随时可回来查看/复制/清空;\n // 进行中的任务(实时进度)与待重启插件也一并展示,关掉任务弹窗后仍可盯着\n showNotifications && h(NotificationsModal, {\n records: notifications,\n tasks: queue.queue,\n pendingRestarts: queue.pendingRestarts,\n t,\n env,\n onClose: () => setShowNotifications(false),\n onCopy: (text) => {\n doCopy(text)\n setToast({ id: Date.now(), kind: 'errCopied' })\n },\n onClear: () => setNotifications(clearNotifications()),\n onRemove: (id: number) => setNotifications(removeNotification(id)),\n // 更新提醒通知:点击直接进该插件的更新确认弹窗(与已安装列表「更新」同一流程)\n onUpdate: (repo: string) => {\n const plugin = catalog.installedItems.find((i) => i.repo === repo)?.plugin\n if (!plugin) return\n setShowNotifications(false)\n setInstallDone(false)\n setConfirmIsUpdate(true)\n queue.clearModalTask()\n setConfirmPlugin(plugin)\n },\n // 更新提醒「忽略本次更新」:先弹确认弹窗,确认后该版本不再提醒(持久化),直到下一个新版本\n onIgnoreUpdate: (repo: string, version?: string) => setIgnoreTarget({ repo, version }),\n cancelTask: queue.cancelTask,\n restarting,\n onRestart: () => { void requestRestart() },\n }),\n // 「忽略本次更新」确认弹窗:确认后该版本写入忽略集(持久化)并从通知中心移除,\n // 本次版本不再提醒,直到插件发布下一个新版本\n ignoreTarget && h('div', {\n className: modalStyles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) setIgnoreTarget(null) },\n },\n h('div', { className: modalStyles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: modalStyles.modalHead },\n h('div', { className: modalStyles.modalTitle }, t('ignoreUpdateConfirmTitle')),\n h('button', {\n className: modalStyles.modalClose,\n type: 'button',\n 'aria-label': t('errorClose'),\n onClick: () => setIgnoreTarget(null),\n }, h(CloseIcon)),\n ),\n h('div', { className: modalStyles.modalBody },\n h('div', { className: modalStyles.failPrepareHint }, t('ignoreUpdateConfirmDetail')),\n h('div', { className: modalStyles.modalActions },\n h('button', {\n className: modalStyles.restartLater,\n type: 'button',\n onClick: () => setIgnoreTarget(null),\n }, t('confirmCancel')),\n h('button', {\n className: modalStyles.restartNow,\n type: 'button',\n onClick: () => {\n ignoreUpdate(ignoreTarget.repo, ignoreTarget.version)\n setNotifications(removeUpdateNotice(ignoreTarget.repo, ignoreTarget.version))\n setIgnoreTarget(null)\n },\n }, t('ignoreUpdateConfirm')),\n ),\n ),\n ),\n ),\n // 安装确认弹窗:锁定/进度/结果视图逻辑收敛在 modals.tsx;更新与安装同入口,仅标记 update\n confirmPlugin && h(InstallModal, {\n plugin: confirmPlugin,\n done: installDone,\n task: queue.installModalTask,\n t,\n langPath,\n restarting,\n update: confirmIsUpdate,\n // 仅命令行插件(webInstallable=false):弹窗只展示命令供复制,不提供一键安装\n cliOnly: confirmPlugin.install?.webInstallable === false,\n submitting: queue.submitting,\n needsRestart: installNeedsRestart,\n onClose: () => setConfirmPlugin(null),\n onCopy: () => copyCommand(confirmPlugin),\n onInstall: () => queue.installNow(confirmPlugin, confirmIsUpdate ? { update: true } : undefined),\n onRestart: () => { void requestRestart() },\n }),\n // 命令行安装确认弹窗:与目录安装同一套确认/进度/结果流程(plugin 传 null 走 customTarget 模式)。\n // 已安装目标 → update 标记,确认后走覆盖重装(服务端 mode=update 放行),不再 409 报错。\n confirmCustomTarget && h(InstallModal, {\n plugin: null,\n customTarget: confirmCustomTarget,\n done: installDone,\n task: queue.installModalTask,\n t,\n langPath,\n restarting,\n update: confirmIsUpdate,\n cliOnly: false,\n submitting: queue.submitting,\n needsRestart: installNeedsRestart,\n onClose: () => {\n setInstallDone(false)\n setConfirmCustomTarget(null)\n },\n onCopy: () => {\n doCopy(`pnpm add ${confirmCustomTarget}`)\n setToast({ id: Date.now(), kind: 'copied' })\n },\n onInstall: () => void queue.installCustom(confirmCustomTarget, confirmIsUpdate ? { update: true } : undefined),\n onRestart: () => { void requestRestart() },\n }),\n // 全局 npm 安装确认弹窗(官方 `npm install -g <pkgs>`):与应用商店同一套确认/进度/结果流程。\n // 装的是系统级 CLI 工具(如 @deepseek-ai/dsh),不进任何 profile、无需宿主重启;\n // 服务端任务终态 needsRestart=false → 结果视图仅「完成」。\n confirmGlobalNpm && h(InstallModal, {\n plugin: null,\n globalNpm: confirmGlobalNpm.pkgs,\n done: installDone,\n task: queue.installModalTask,\n t,\n langPath,\n restarting,\n update: false,\n cliOnly: false,\n submitting: queue.submitting,\n needsRestart: installNeedsRestart,\n onClose: () => {\n setInstallDone(false)\n setConfirmGlobalNpm(null)\n },\n onCopy: () => {\n doCopy(`npm install -g ${confirmGlobalNpm.pkgs.join(' ')}`)\n setToast({ id: Date.now(), kind: 'copied' })\n },\n onInstall: () => void queue.installGlobalNpm(confirmGlobalNpm.pkgs),\n onRestart: () => { void requestRestart() },\n }),\n // 卸载确认弹窗:确认/进度/结果视图逻辑收敛在 modals.tsx。\n // 已安装视图的自定义安装(目录外)没有完整目录数据,按已安装项伪插件适配后走同一弹窗\n (uninstallPlugin || uninstallItem) && h(UninstallModal, {\n plugin: uninstallPlugin ?? pluginOfItem(uninstallItem!),\n done: uninstallDone,\n task: queue.uninstallModalTask,\n t,\n langPath,\n restarting,\n submitting: queue.submitting,\n needsRestart: uninstallNeedsRestart,\n onClose: () => {\n setUninstallDone(false)\n setUninstallPlugin(null)\n setUninstallItem(null)\n },\n onCancel: () => {\n setUninstallPlugin(null)\n setUninstallItem(null)\n },\n onCopyCommand: copyUninstallCommand,\n onConfirm: () => {\n if (uninstallItem) void queue.uninstallItem(uninstallItem)\n else if (uninstallPlugin) void queue.uninstallNow(uninstallPlugin)\n },\n onRestart: () => { void requestRestart() },\n }),\n // 已安装详情弹窗:目录元数据 + 宿主运行时信息的完整展示,操作(更新/卸载/复制路径)由此发起\n detailItem && h(InstalledDetailModal, {\n item: detailItem,\n t,\n lang: langKey,\n langPath,\n onClose: () => setDetailItem(null),\n onUpdate: (item) => {\n if (!item.plugin) return\n setDetailItem(null)\n setInstallDone(false)\n setConfirmIsUpdate(true)\n queue.clearModalTask()\n setConfirmPlugin(item.plugin)\n },\n onUninstall: (item) => {\n setDetailItem(null)\n setUninstallDone(false)\n queue.clearModalTask()\n setUninstallItem(item)\n },\n onCopyPath: (path) => {\n doCopy(path)\n setToast({ id: Date.now(), kind: 'copied' })\n },\n onReveal: (item) => { void revealFolder(item) },\n }),\n toast && h(Toast, { toast, t }),\n // 操作失败:完整错误弹窗(重复安装、CLI 失败、请求错误等),可复制并去插件仓库反馈\n errorMsg && h(ErrorModal, {\n message: errorMsg.message,\n repo: errorMsg.repo,\n kind: errorMsg.kind,\n command: errorMsg.command,\n attempts: errorMsg.attempts,\n t,\n env,\n onCopy: (text: string) => {\n doCopy(text)\n setToast({ id: Date.now(), kind: 'errCopied' })\n },\n onClose: () => setErrorMsg(null),\n }),\n // 待重启确认弹窗:已安装列表行内「重启」按钮点击后弹出,稍后重启 / 立即重启\n showRestartConfirm && h(RestartConfirmModal, {\n t,\n restarting,\n onClose: () => setShowRestartConfirm(false),\n onRestartNow: () => {\n setShowRestartConfirm(false)\n void requestRestart()\n },\n }),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * dsh-plugin client entry: wires the Plugin Hub into the host settings via\n * the module-loader bundle (see tsdown.config.ts). All UI logic lives in\n * PluginHubSection; this file only performs the cordis apply wiring.\n */\nimport { createElement as h } from 'react'\nimport type { HubClientContext } from './types.ts'\nimport { en, zh } from './locales.ts'\nimport { PluginHubSection } from './components/PluginHubSection.tsx'\nimport './styles/tokens.module.css'\n\nconst NS = 'dsh-plugin'\n\nexport const name = NS\nexport const inject = ['slots', 'locale']\n\nexport function apply(ctx: HubClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), `${NS}: dictionaries`)\n const t = ctx.locale.bind(NS)\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: NS,\n order: 60,\n label: () => t('nav'),\n locale: NS,\n inject: () => ({ t, locale: ctx.locale }),\n }, () => h(PluginHubSection, { t, locale: ctx.locale })))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["installTargetOf","SORT_DEFAULT_DIR","useState","useMemo","useState","useState","useCallback","useState","useRef","installTargetOf","h","modalStyles","headerStyles","h","styles","h","styles","h","styles","h","styles","h","styles","h","styles","h","Fragment","styles","h","styles","SegBtn","h","styles","Fragment","useState","useRef","h","styles","useRef","h","styles","h","Fragment","h","styles","h","styles","useState","useMemo","useState","h","styles","modal","useState","useRef","h","styles","h","styles","useState","useRef","useCallback","h","styles","h","view","useState","useRef","useCallback","styles","useState","h","styles","view","useState","useRef","useCallback","h","styles","h","styles","useState","modalStyles","useState","useRef","h","styles","modalStyles","h"],"sources":["../src/client/locales.ts","../src/client/logic/install-command.ts","../src/client/logic/constants.ts","../src/client/data/host.ts","../src/client/logic/normalize.ts","../src/client/data/catalog.ts","../src/client/data/hub.ts","../src/client/logic/installed.ts","../src/client/hooks/useCatalog.ts","../src/client/logic/failures.ts","../src/client/logic/urls.ts","../src/client/hooks/useLanguage.ts","../src/client/hooks/useSettings.ts","../src/client/hooks/useTaskQueue.ts","../src/client/components/ui/icons.tsx","../src/client/components/modals/ProgressView.tsx","../src/client/components/modals/modals.tsx","../src/client/logic/renderMarkdown.ts","../src/client/components/modals/AboutModal.tsx","../src/client/components/modals/HubUpdateModal.tsx","../src/client/logic/format.ts","../src/client/components/modals/InstalledDetailModal.tsx","../src/client/components/modals/NotificationsModal.tsx","../src/client/components/layout/CatalogHeader.tsx","../src/client/components/layout/CategoryTabs.tsx","../src/client/components/layout/CatalogControls.tsx","../src/client/hooks/useIncrementalList.ts","../src/client/components/catalog/PluginCard.tsx","../src/client/components/catalog/CatalogList.tsx","../src/client/components/views/MarketView.tsx","../src/client/components/layout/SectionTabs.tsx","../src/client/components/views/InstalledView.tsx","../src/client/components/views/CustomInstallView.tsx","../src/client/components/ui/Dropdown.tsx","../src/client/components/ui/Toggle.tsx","../src/client/components/views/DiagnosticsView.tsx","../src/client/components/modals/LogsModal.tsx","../src/client/components/modals/LogsPathModal.tsx","../src/client/components/views/LogsView.tsx","../src/client/components/views/SettingsView.tsx","../src/client/components/PluginHubSection.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * zh/en dictionaries for the DSH Plugin Hub settings section.\n */\nexport const zh = {\n nav: '插件中心',\n title: 'DSH Plugin Hub',\n // 收录/精选数量由组件从官网 /api/stats.json 实时拉取填充({total}/{verified}),不写死\n tagline: 'DSH Plugin 插件中心:面向 DeepSeek Harness 插件收录平台,人工审验、来源可溯,免费安装',\n adBadge: '推荐',\n // 紫色广告横幅:突出数量(显眼)+ 更新节奏,与 tagline 职责分开、不重复\n ad: 'DSH Plugin 插件中心:收录 {total} 款插件,{verified} 款人工精选验证,每日更新',\n search: '搜索插件名称、描述、标签…',\n all: '全部',\n sortStars: 'Star',\n sortForks: 'Fork',\n sortUpdated: '最近更新',\n sortNewest: '最新收录',\n sortAria: '插件排序方式',\n openHint: '打开 dsh-plugin.org',\n toggleLangHint: '切换界面语言',\n fork: 'Fork',\n loading: '正在加载插件数据…',\n failed: '插件数据加载失败',\n failedDesc: '请稍后重试,或点击右上角按钮在浏览器中打开插件中心。',\n retry: '重试',\n install: '安装',\n // AI 识别可能需要命令行辅助的插件(webInstallable=false):仍可尝试一键安装,失败时复制命令去 dsh 终端\n cliOnlyHint: '此插件可能需命令行辅助,失败时复制上方命令到 dsh 终端',\n failedCopyHint: '安装失败。请复制上方安装命令到 dsh 终端手动执行(原生依赖构建脚本可能需要人工放行,如 pnpm approve-builds)',\n toastCopied: '安装命令已复制,去 dsh 终端粘贴即可安装',\n installed: '已安装',\n // 一级导航:插件中心 / 已安装 / 自定义安装 / 设置\n viewMarket: '插件中心',\n viewInstalled: '已安装',\n viewCustom: '自定义安装',\n viewSettings: '设置',\n viewMarketHint: '浏览与发现插件',\n viewInstalledHint: '管理已安装插件',\n viewCustomHint: '手动安装 NPM 包或 GitHub 源码',\n viewSettingsHint: '网络通道与偏好设置',\n // 已安装视图\n installedEmpty: '还没有安装插件',\n installedEmptyDesc: '可以去「自定义安装」,手动安装 NPM 包或 GitHub 源码',\n npmInstallLabel: 'NPM 包 / 命令',\n npmInstallPlaceholder: 'npm install <包名> 或直接输包名',\n npmInstallExample: '支持原生命令:npm install lodash、npm i lodash、pnpm add @scope/pkg',\n npmInstallExample2: '全局安装 CLI:npm install -g @scope/cli;或直接输入包名 lodash',\n npmInstallInvalid: '请输入 npm 包名(如 lodash、@scope/pkg),或原生安装命令(如 npm install lodash、npm i lodash、pnpm add @scope/pkg、npm install -g @scope/cli)',\n gitInstallLabel: 'GitHub 源码',\n gitInstallPlaceholder: '输入仓库地址',\n gitInstallExample: '例如:owner/repo 或 https://github.com/owner/repo',\n gitInstallInvalid: '请输入 GitHub 仓库地址,例如:owner/repo 或 https://github.com/owner/repo',\n dshCmdLabel: 'DeepSeek Harness 命令',\n dshCmdPlaceholder: '粘贴官方 dsh plugin 命令',\n dshCmdExample: '例如:dsh plugin --profile web add github:owner/repo',\n dshCmdInvalid: '请输入官方 dsh plugin 安装命令(--profile 必填)。例如:dsh plugin --profile web add github:owner/repo',\n installHelp: '帮助',\n helpModalTitle: '支持的命令格式',\n 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 工具,不进「已安装」列表',\n gitInstallHelp: 'owner/repo\\nhttps://github.com/owner/repo\\ngithub:owner/repo\\ngit+https://github.com/owner/repo.git\\ngit@github.com:owner/repo.git',\n dshCmdHelp: 'dsh plugin --profile web add <目标>\\ndsh plugin --profile=web add <目标>\\n\\t--profile 必填,官方 CLI 无 -p 简写;<目标> 可为 npm 包名或 github:owner/repo',\n globalNpmHint: '将全局安装 CLI 工具(npm install -g),不会出现在「已安装」列表,无需重启宿主',\n installCliBtn: '安装',\n // 安装通道关闭(安全信任开关关掉后,对应卡片禁用并引导去设置打开)\n channelDisabledHint: '该安装通道已关闭,请在「设置 → 安全信任」中打开开关',\n goToSettings: '前往设置',\n // 自定义安装视图:独立一级导航,说明文字\n customViewDesc: '手动安装目录外的 NPM 包、GitHub 源码,或粘贴官方 dsh plugin 命令。装完的条目会出现在「已安装」列表,并标记为自定义安装。',\n customLabel: '自定义安装',\n installedSearch: '搜索已安装的插件…',\n installedFilterCatalog: '目录插件',\n hubInstall: '插件中心',\n hubInstallHint: '来自插件中心收录的目录插件',\n manualInstall: '手动安装',\n manualInstallHint: '非目录收录,通过命令行手动安装',\n filterByLabel: '来源',\n sortByLabel: '排序',\n sortName: '名称',\n sortInstalledAt: '最近',\n detailTitle: '插件详情',\n detailCategory: '分类',\n detailStats: '仓库统计',\n statusLabel: '安装状态',\n statusRunning: '运行中',\n statusPending: '待重启',\n exampleLabel: 'DeepSeek Harness 内置示例项目',\n exampleHint: 'DeepSeek Harness 内置示例项目:不是插件市场的 dsh 插件,宿主不会加载它,无需重启',\n restart: '重启',\n installedVersionLabel: '已安装版本',\n catalogLatest: '目录最新',\n installPath: '安装路径',\n copyPath: '复制路径',\n openFolder: '在文件夹中显示',\n openFolderFail: '无法打开文件夹,请复制路径手动打开',\n revealFolder: '在 Finder 中显示',\n installedAtLabel: '安装时间',\n lastUpdatedLabel: '最后更新',\n detailCatalog: '查看详情',\n packageName: '包名',\n versionUpHint: '发现新版本 v{from} → v{to},点击「更新」原位覆盖重装',\n // 设置视图:更新与通道 / 安全与信任 / 诊断 / 系统日志\n settingsUpdate: '更新设置',\n settingsUpdateDesc: '更新检查方式与安装走到的网络通道',\n settingsCheckOnStart: '启动时检查更新',\n settingsCheckOnStartDesc: '打开插件中心时检查已安装插件是否有新版,发现更新会提示',\n settingsMirror: 'npm 镜像源',\n settingsMirrorDesc: 'npm 安装与版本反查走自定义镜像,网络不佳时更稳定;留空使用官方源',\n mirrorOfficial: '官方源 registry.npmjs.org',\n mirrorNpmmirror: '阿里云 npmmirror',\n mirrorTencent: '腾讯云镜像',\n mirrorCustom: '自定义镜像源',\n settingsProxy: 'HTTP 代理',\n settingsProxyDesc: 'npm / git / 目录数据请求统一走该代理;留空直连',\n settingsSecurity: '安全信任',\n settingsSecurityDesc: '命令行安装的三个通道开关:NPM 包、GitHub 源码与 DSH 命令',\n settingsEnableNpm: '启用 NPM 安装',\n settingsEnableNpmDesc: '允许通过命令行安装 npm 包;关闭后输入包名安装会被拦截',\n settingsEnableGit: '启用 GitHub 源码安装',\n settingsEnableGitDesc: '允许通过命令行安装 GitHub 源码;关闭后输入仓库地址安装会被拦截',\n settingsEnableDsh: '启用 DSH 命令安装',\n settingsEnableDshDesc: '允许通过命令行粘贴 dsh plugin 命令安装;关闭后命令输入会被禁用',\n settingsDiagnostics: '系统诊断',\n settingsDiagnosticsDesc: '检测 npm 源 / GitHub / 目录站点等安装通道的连通状态',\n settingsLogs: '系统日志',\n settingsLogsDesc: '本地记录的安装 / 卸载 / 设置变更与诊断结果,可导出全文排查问题',\n logsHeadHint: '记录安装、卸载、设置变更与诊断结果,保留最近 2000 条',\n logsRefresh: '刷新日志',\n logsExport: '导出日志',\n logsLoading: '正在读取日志…',\n logsEmpty: '暂无日志记录',\n logsLoadFail: '读取日志失败,请稍后重试',\n // 系统日志查看器弹窗:内置窗口分页加载,按类别 × 级别筛选\n logModalTitle: '日志查看器',\n logViewerOpen: '打开日志查看器',\n logViewerDesc: '内置窗口直接查看本地日志,按类型与级别筛选,可定位安装 / 卸载 / 更新时的不兼容点',\n logPathLabel: '日志文件',\n logOpenFile: '打开文件',\n logOpenFileTip: '在系统文件管理器中定位日志文件',\n logOpenFileFail: '打开失败,请在文件管理器中手动定位',\n logPathSettingTitle: '日志存放位置',\n logPathSettingDesc: '默认存于宿主配置目录,可填目录或 .log 文件路径改存别处',\n logPathPlaceholder: '留空恢复默认',\n logPathReset: '恢复默认',\n logPathResetHint: '文本框显示当前生效位置',\n logPathSave: '保存',\n logPathSaving: '保存中…',\n logPathSaved: '已保存,新日志将写入该位置',\n logPathSaveFail: '保存失败:该位置不可写或不可用',\n logPathChange: '修改',\n logPathBrowse: '选择目录…',\n logPathBrowseFail: '选择目录不可用,请手动输入路径',\n logCatAll: '全部类型',\n logCatInstall: '安装',\n logCatUninstall: '卸载',\n logCatUpdate: '更新',\n logCatDiagnostics: '诊断',\n logCatSettings: '设置',\n logCatSystem: '系统',\n logLvAll: '全部级别',\n logLvError: '错误',\n logLvWarn: '警告',\n logLvSuccess: '成功',\n logLvInfo: '信息',\n logLvDebug: '调试',\n logSearchPlaceholder: '搜索事件或描述…',\n logLoadMore: '加载更多',\n logNoMore: '已加载全部,共 {n} 条',\n logCount: '共 {n} 条',\n logEmptyFilter: '没有符合条件的日志',\n settingsDiagFail: '不可达',\n // 系统诊断通道列表:一键全量诊断 + 一行一个,可点重测\n diagNpm: 'npm 源',\n diagGithub: 'GitHub',\n diagCatalog: '目录站点',\n diagOk: 'OK',\n diagChecking: '检测中…',\n diagIdle: '未检测',\n diagRecheck: '点击重测该通道',\n diagRunAll: '立即诊断',\n diagHeadHint: '共 {n} 个通道,点击任意一行可单独重测',\n diagSummaryRunning: '正在检测通道…',\n diagSummaryOk: '全部通道正常',\n diagSummaryFail: '存在不可达通道,点击对应行可重测',\n settingsEnvSnapshot: '系统版本',\n settingsEnvSnapshotDesc: '复制宿主版本与系统信息,提交 Issue 时粘贴到正文便于复现',\n settingsEnvCopy: '复制',\n // 恢复默认:一级菜单 + 独立设置卡片\n settingsReset: '恢复默认',\n settingsResetDesc: '更新策略、镜像源、代理与安全限制一次性恢复为出厂默认值',\n settingsResetDetail: '恢复更新策略、镜像源、代理与安全限制为出厂默认值',\n settingsResetRun: '恢复默认',\n settingsResetConfirm: '确认恢复',\n settingsResetConfirmDetail: '确定要恢复默认设置吗?更新策略、镜像源、代理与安全限制将全部回到出厂默认值。',\n // 启动更新策略提示\n updatesFound: '发现 {n} 个插件可更新,已加入通知中心',\n updateNoticeTitle: '发现新版本',\n updateNoticeGo: '去更新',\n ignoreUpdateRun: '忽略本次更新',\n ignoreUpdateConfirmTitle: '忽略本次更新?',\n ignoreUpdateConfirmDetail: '忽略后本次版本不再提醒;待插件发布下一个新版本时,会再次通知你。',\n ignoreUpdateConfirm: '确认忽略',\n uninstall: '卸载',\n uninstalling: '卸载中…',\n uninstallTitle: '确认卸载?',\n uninstallDesc: '将从当前环境卸载该插件。',\n uninstallDone: '卸载成功',\n uninstallFail: '卸载失败,请稍后重试',\n uninstallResultTitle: '卸载完成',\n uninstallResultDesc: '插件已从当前环境移除。',\n confirmTitle: '确认安装',\n confirmDesc: '安装前请前往插件仓库仔细阅读源码,确认可信后再安装',\n confirmPlugin: '插件',\n confirmSource: '来源',\n confirmCommand: '安装命令',\n copyInstallCommand: '复制安装命令',\n copyCmdLabel: '复制',\n copyUninstallCommand: '复制卸载命令',\n cancelUninstall: '取消卸载',\n uninstallConfirm: '确认卸载',\n installNow: '直接安装',\n installing: '安装中…',\n installDone: '安装成功',\n installResultTitle: '插件安装成功',\n installResultDesc: '',\n // 更新语义:已安装插件点「更新」走同一条 add 命令原位覆盖重装,弹窗文案区分安装/更新\n confirmUpdateTitle: '确认更新',\n updateNow: '直接更新',\n updating: '更新中…',\n queuedUpdateTitle: '已加入更新排队',\n updateResultTitle: '更新完成',\n updateResultDesc: '插件已更新到最新版本。',\n installFail: '安装失败',\n requestTimeout: '请求超时:无法访问 GitHub 或网络不稳定,请稍后重试',\n confirmCancel: '取消',\n doneBtn: '完成',\n // 结果视图:部分插件需重启后才挂载,提供「立即重启 / 稍后重启」选择\n restartNow: '立即重启',\n restartLater: '稍后重启',\n restarting: '正在重启…',\n restartHint: '部分插件(如插件市场、顶层 bundle)需重启后才会生效。',\n done: '完成',\n // 待重启:装完没重启的插件常驻提醒,直到宿主真正重启\n restartPendingHint: '安装成功,重启后生效',\n restartPendingHintUninstall: '卸载成功,重启后移除',\n sectionPendingRestart: '待重启',\n sectionInProgress: '进行中',\n // 通知中心:安装/卸载任务成败的持久记录(工具栏铃铛入口按钮打开)\n notifications: '通知',\n notificationsHint: '查看安装/卸载/更新通知',\n notificationsDesc: '安装、卸载任务与更新提醒都会记录在这里,即使错过提示也能随时回来查看。',\n notificationsEmpty: '暂无通知记录',\n notificationsClear: '清空通知',\n removeNotification: '删除这条通知',\n // 串行队列:安装/卸载弹窗内可后台关闭,排队任务自动串行执行\n queuedTitle: '已加入安装排队',\n queuedUninstallTitle: '已加入卸载排队',\n queuedHint: '已加入排队,前序任务完成后将自动开始,可关闭本窗口继续浏览。',\n cancelTask: '取消任务',\n cancelling: '正在取消…',\n errorTitle: '操作失败',\n errorTitleInstall: '安装失败',\n errorTitleUninstall: '卸载失败',\n errorPlugin: '插件',\n errorClose: '知道了',\n errorCopy: '复制错误信息',\n errCopied: '错误信息已复制',\n failCopy: '复制完整错误信息',\n failIssueHint: '带着错误日志去作者仓库一键提交 Issue(正文含官网收录链接)',\n failIssueBig: '一键提交 BUG 到 GitHub Issue 为开源作贡献',\n // prepare 构建脚本实际执行失败(git 分发缺子模块/构建产物):插件打包分发问题,应提 Issue\n failPrepareHint: '该插件安装时的构建脚本执行失败(git 分发常缺失子模块或构建产物),属插件打包分发问题。请向作者仓库提交 Issue 反馈。',\n // 安装前预检 / 装后校验拦截([packaging]):git 分发缺构建产物、入口文件不存在 = 插件未适配官方默认安装方式\n failPackagingHint: '该插件不支持官方默认安装方式:其 git 分发缺少构建产物(package.json 声明的入口文件在仓库中不存在),说明作者未适配官方安装流程。请到作者仓库提交 Issue 反馈,请其提交构建产物或发布 npm 版。',\n // 原生依赖构建脚本被 pnpm 默认拦截(如 node-pty 的 ERR_PNPM_IGNORED_BUILDS):只影响带原生模块的插件,属插件依赖打包问题,应提 Issue\n failIgnoredBuild: '该插件依赖了需要编译的原生模块(如 node-pty),pnpm 默认拦截这类构建脚本导致安装失败 —— 其他插件不受影响,属该插件的依赖/打包问题。建议向作者仓库一键反馈,请作者改用预编译版本(如 node-pty-prebuilt-multiarch)。',\n // npm arborist 内部崩溃(edgesOut)+ 本机 npm 版本过低:npm 自身已知缺陷,不是插件问题,升级 npm 即可\n failNpmTooLow: '怀疑本机 npm 版本过低:npm 解析插件依赖时内部崩溃(这是 npm 自身的已知缺陷,不是插件问题)。请升级 npm 后重试:npm install -g npm@latest',\n failNpmTooLowV: '本机 npm 版本过低(当前 v{v}):npm 解析插件依赖时内部崩溃(这是 npm 自身的已知缺陷,不是插件问题)。请升级 npm 后重试:npm install -g npm@latest',\n reportIssue: '去插件仓库提交 Issue',\n detail: '打开详情',\n noResult: '没有找到匹配的插件',\n noResultDesc: '换个关键词试试,或前往网站浏览全部插件。',\n today: '今天更新',\n daysAgo: '更新于 {days} 天前',\n monthsAgo: '更新于 {months} 个月前',\n yearsAgo: '更新于 {years} 年前',\n pluginsTotal: '结果 {n} 条插件',\n // 分类按钮不带数量,选中分类后在列表头部显示筛选结果数\n filterResults: '结果 {n} 条插件',\n more: '还有 {n} 个插件,去网站查看全部',\n browseAll: '浏览全部 {n} 个插件',\n verified: '已验证',\n // 版本与更新:有 release 比版本号;无 release 的仓库比仓库最近更新时间(有新提交即提示更新)\n version: '版本',\n update: '可更新',\n updateAvailable: '有更新',\n updateAvailableHint: '检测到更新:有版本号的仓库比对版本号,无版本号的仓库比对仓库最近更新时间',\n hubUpdateHint: '检测到 DSH Plugin Hub 新版本,点击查看更新内容并更新',\n hubUpdateTitle: 'DSH Plugin Hub 有新版本',\n hubUpdateDesc: 'v{version} 已发布,点击下方按钮即可更新,完成后需重启宿主生效。',\n hubUpdatePublished: '发布于',\n hubUpdateNotes: '更新记录',\n hubUpdateLater: '稍后再说',\n versionHint: '查看版本信息与更新记录',\n hubCurrentTitle: '当前版本',\n hubCurrentDesc: '你正在使用 v{version},已是最新版本。',\n hubUpToDate: '已是最新版本',\n // 头部「关注我们」弹窗:平台介绍 + 用户反馈群二维码(内容由 Worker /about Markdown 推送,非写死)\n followUs: '关注我们',\n aboutTitle: '关注我们',\n aboutDesc: '了解 DSH Plugin Hub 是做什么的,加入用户反馈群随时交流。',\n aboutEmpty: '内容暂未发布,敬请期待。',\n aboutUpdated: '更新于',\n empty: '该分类暂无插件',\n dataFrom: '数据源 api.dsh-plugin.org · 每日人工更新',\n}\n\nexport const en = {\n nav: 'Plugin Hub',\n title: 'DSH Plugin Hub',\n // Plugin counts are filled from the live /api/stats.json ({total}/{verified}), never hardcoded\n tagline: 'DSH Plugin Hub: a human-verified, free marketplace for DeepSeek Harness plugins',\n adBadge: 'Featured',\n ad: 'DSH Plugin Hub: {total} plugins indexed, {verified} human-verified, updated daily',\n search: 'Search plugins by name, description, tags…',\n all: 'All',\n sortStars: 'Stars',\n sortForks: 'Forks',\n sortUpdated: 'Recently updated',\n sortNewest: 'Newest added',\n sortAria: 'Plugin sort order',\n openHint: 'Open dsh-plugin.org',\n toggleLangHint: 'Switch language',\n githubHint: 'View source on GitHub',\n fork: 'Fork',\n loading: 'Loading plugin data…',\n failed: 'Failed to load plugin data',\n failedDesc: 'Please retry, or open the hub in your browser with the button above.',\n retry: 'Retry',\n install: 'Install',\n // AI-flagged plugins that may need command-line help (webInstallable=false): one-click install still allowed,\n // on failure the user is guided to copy the command into the dsh terminal\n cliOnlyHint: 'This plugin may need command-line help; if it fails, copy the command above and run it in your dsh terminal',\n 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)',\n toastCopied: 'Install command copied — paste it in your dsh terminal',\n installed: 'Installed',\n // Primary navigation: Market / Installed / Custom / Settings\n viewMarket: 'Market',\n viewInstalled: 'Installed',\n viewCustom: 'Custom',\n viewSettings: 'Settings',\n viewMarketHint: 'Browse and discover plugins',\n viewInstalledHint: 'Manage installed plugins',\n viewCustomHint: 'Install npm packages or GitHub sources manually',\n viewSettingsHint: 'Network sources and preferences',\n // Installed view\n installedEmpty: 'No plugins installed yet',\n installedEmptyDesc: 'Go to Custom to add an npm package or GitHub source manually',\n npmInstallLabel: 'npm package / command',\n npmInstallPlaceholder: 'npm install <pkg> or a bare package name',\n npmInstallExample: 'Native commands: npm install lodash, npm i lodash, pnpm add @scope/pkg',\n npmInstallExample2: 'Global CLI: npm install -g @scope/cli; or just type a package name like lodash',\n 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)',\n gitInstallLabel: 'GitHub source',\n gitInstallPlaceholder: 'Repository address',\n gitInstallExample: 'e.g. owner/repo or https://github.com/owner/repo',\n gitInstallInvalid: 'Enter a GitHub repository address, e.g. owner/repo or https://github.com/owner/repo',\n dshCmdLabel: 'DeepSeek Harness command',\n dshCmdPlaceholder: 'Paste an official dsh plugin command',\n dshCmdExample: 'e.g. dsh plugin --profile web add github:owner/repo',\n dshCmdInvalid: 'Paste an official dsh plugin install command (--profile required), e.g. dsh plugin --profile web add github:owner/repo',\n installHelp: 'Help',\n helpModalTitle: 'Supported command formats',\n 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',\n gitInstallHelp: 'owner/repo\\nhttps://github.com/owner/repo\\ngithub:owner/repo\\ngit+https://github.com/owner/repo.git\\ngit@github.com:owner/repo.git',\n dshCmdHelp: 'dsh plugin --profile web add <target>\\ndsh plugin --profile=web add <target>\\n\\t--profile is required and there is no -p shorthand; <target> can be an npm package or github:owner/repo',\n globalNpmHint: 'This installs CLI tools globally (npm install -g). They won\\'t appear in Installed and no host restart is needed.',\n installCliBtn: 'Install',\n // Install channel disabled (security-trust toggle off → card disabled, guides to settings)\n channelDisabledHint: 'This install channel is disabled — enable it in Settings → Security & Trust',\n goToSettings: 'Go to Settings',\n // Custom install view: standalone top-level section, description text\n customViewDesc: 'Manually install an npm package, a GitHub source, or paste an official dsh plugin command. Finished installs appear in Installed, marked as custom.',\n customLabel: 'Custom install',\n installedSearch: 'Search installed plugins…',\n installedFilterCatalog: 'Catalog',\n hubInstall: 'Hub',\n hubInstallHint: 'From the plugin hub catalog',\n manualInstall: 'Manual',\n manualInstallHint: 'Not from the catalog — installed via the command line',\n filterByLabel: 'Source',\n sortByLabel: 'Sort',\n sortName: 'Name',\n sortInstalledAt: 'Recent',\n detailTitle: 'Plugin details',\n detailCategory: 'Category',\n detailStats: 'Repo stats',\n statusLabel: 'Status',\n statusRunning: 'Running',\n statusPending: 'Restart pending',\n exampleLabel: 'DeepSeek Harness built-in example',\n exampleHint: 'DeepSeek Harness built-in example — not a marketplace dsh plugin, the host does not load it, no restart needed',\n restart: 'Restart',\n installedVersionLabel: 'Installed version',\n catalogLatest: 'latest in catalog',\n installPath: 'Install path',\n copyPath: 'Copy path',\n openFolder: 'Show in folder',\n openFolderFail: 'Could not open the folder — copy the path instead',\n revealFolder: 'Show in Finder',\n installedAtLabel: 'Installed at',\n lastUpdatedLabel: 'Last updated',\n detailCatalog: 'View details',\n packageName: 'Package',\n versionUpHint: 'v{from} → v{to} available — Update reinstalls in place',\n // Settings view: Updates & Sources / Security & Trust / Diagnostics / System Logs\n settingsUpdate: 'Update Settings',\n settingsUpdateDesc: 'Update checks and the network channels used for installs',\n settingsCheckOnStart: 'Check for updates on startup',\n settingsCheckOnStartDesc: 'Check installed plugins for new versions when the hub opens; you will be notified when updates are found',\n settingsAutoInstall: 'Auto-install updates',\n settingsAutoInstallDesc: 'Install detected updates in the background without asking (a host restart applies them)',\n settingsMirror: 'npm registry mirror',\n settingsMirrorDesc: 'Route npm installs and lookups through a mirror for unstable networks; leave empty for the official registry',\n mirrorOfficial: 'Official registry.npmjs.org',\n mirrorNpmmirror: 'Alibaba npmmirror',\n mirrorTencent: 'Tencent Cloud mirror',\n mirrorCustom: 'Custom mirror',\n settingsProxy: 'HTTP proxy',\n settingsProxyDesc: 'Route npm, git and catalog requests through this proxy; leave empty to connect directly',\n settingsSecurity: 'Security & Trust',\n settingsSecurityDesc: 'Toggles for the three command-line install channels: npm packages, GitHub sources and DSH commands',\n settingsEnableNpm: 'Enable npm installs',\n settingsEnableNpmDesc: 'Allow installing npm packages from the command line; turning this off rejects package-name installs',\n settingsEnableGit: 'Enable GitHub source installs',\n settingsEnableGitDesc: 'Allow installing from GitHub sources on the command line; turning this off rejects repository-address installs',\n settingsEnableDsh: 'Enable DSH command installs',\n settingsEnableDshDesc: 'Allow pasting a dsh plugin command to install; turning this off disables the command input',\n settingsDiagnostics: 'System Diagnostics',\n settingsDiagnosticsDesc: 'Check the connectivity of install channels: npm registry, GitHub and the catalog site',\n settingsLogs: 'System Logs',\n settingsLogsDesc: 'Local record of installs / uninstalls, settings changes and diagnostics — export the full log to troubleshoot',\n logsHeadHint: 'Records installs, uninstalls, settings changes and diagnostics; keeps the latest 2,000 entries',\n logsRefresh: 'Refresh log',\n logsExport: 'Export log',\n logsLoading: 'Reading log…',\n logsEmpty: 'No log entries yet',\n logsLoadFail: 'Failed to read the log; try again later',\n // Log-viewer dialog: a built-in window that loads the log in pages, filterable by type × level\n logModalTitle: 'Log viewer',\n logViewerOpen: 'Open log viewer',\n logViewerDesc: 'View the local log in a built-in window; filter by type and level to pinpoint install / uninstall / update incompatibilities',\n logPathLabel: 'Log file',\n logOpenFile: 'Reveal',\n logOpenFileTip: 'Reveal the log file in your system file manager',\n logOpenFileFail: 'Could not open; locate the file manually',\n logPathSettingTitle: 'Log Location',\n logPathSettingDesc: 'Stored in the host config directory by default — set a directory or a .log file path to store elsewhere',\n logPathPlaceholder: 'Leave empty for default',\n logPathReset: 'Reset to default',\n logPathResetHint: 'The field shows the location currently in use',\n logPathSave: 'Save',\n logPathSaving: 'Saving…',\n logPathSaved: 'Saved — new logs will be written there',\n logPathSaveFail: 'Could not save: the location is not writable',\n logPathChange: 'Change',\n logPathBrowse: 'Browse…',\n logPathBrowseFail: 'Folder picker unavailable — type the path manually',\n logCatAll: 'All types',\n logCatInstall: 'Install',\n logCatUninstall: 'Uninstall',\n logCatUpdate: 'Update',\n logCatDiagnostics: 'Diagnostics',\n logCatSettings: 'Settings',\n logCatSystem: 'System',\n logLvAll: 'All levels',\n logLvError: 'Error',\n logLvWarn: 'Warn',\n logLvSuccess: 'Success',\n logLvInfo: 'Info',\n logLvDebug: 'Debug',\n logSearchPlaceholder: 'Search event or message…',\n logLoadMore: 'Load more',\n logNoMore: 'All loaded · {n} total',\n logCount: '{n} entries',\n logEmptyFilter: 'No matching log entries',\n settingsDiagFail: 'Unreachable',\n // System diagnostics channel list: one-click full check + one row per channel, click to re-probe\n diagNpm: 'npm registry',\n diagGithub: 'GitHub',\n diagCatalog: 'Catalog site',\n diagOk: 'OK',\n diagChecking: 'Checking…',\n diagIdle: 'Not checked',\n diagRecheck: 'Click to re-check this channel',\n diagRunAll: 'Run diagnostics',\n diagHeadHint: '{n} channels — click any row to re-check it alone',\n diagSummaryRunning: 'Checking channels…',\n diagSummaryOk: 'All channels reachable',\n diagSummaryFail: 'Unreachable channel(s) — click a row to re-check',\n settingsEnvSnapshot: 'System version',\n settingsEnvSnapshotDesc: 'Copy host version and system info for pasting into issue reports',\n settingsEnvCopy: 'Copy',\n // Restore defaults: first-level menu + its own settings card\n settingsReset: 'Restore Defaults',\n settingsResetDesc: 'Restore update policy, npm mirror, proxy and security restrictions to factory defaults in one go',\n settingsResetDetail: 'Reset update policy, npm mirror, proxy and security restrictions to factory defaults',\n settingsResetRun: 'Restore Defaults',\n settingsResetConfirm: 'Restore Defaults',\n settingsResetConfirmDetail: 'Reset all settings to factory defaults? Update policy, npm mirror, proxy and security restrictions will be cleared.',\n // Startup update policy hints\n updatesFound: '{n} plugin(s) have updates — check the notification center',\n updateNoticeTitle: 'Update available',\n updateNoticeGo: 'Update',\n ignoreUpdateRun: 'Ignore this update',\n ignoreUpdateConfirmTitle: 'Ignore this update?',\n ignoreUpdateConfirmDetail: 'This version will no longer notify you. You will be alerted again when the next version is released.',\n ignoreUpdateConfirm: 'Ignore',\n uninstall: 'Uninstall',\n uninstalling: 'Removing…',\n uninstallTitle: 'Confirm uninstall?',\n uninstallDesc: 'The plugin will be removed from this environment.',\n uninstallDone: 'Uninstalled',\n uninstallFail: 'Removal failed — try again',\n uninstallResultTitle: 'Removed',\n uninstallResultDesc: 'The plugin has been removed from this environment.',\n confirmTitle: 'Confirm install',\n confirmDesc: 'Review the plugin repository source code carefully before installing.',\n confirmPlugin: 'Plugin',\n confirmSource: 'Source',\n confirmCommand: 'Command',\n copyInstallCommand: 'Copy install command',\n copyCmdLabel: 'Copy',\n copyUninstallCommand: 'Copy uninstall command',\n cancelUninstall: 'Cancel uninstall',\n uninstallConfirm: 'Confirm uninstall',\n installNow: 'Install',\n installing: 'Installing…',\n installDone: 'Installed',\n installResultTitle: 'Plugin installed successfully',\n installResultDesc: '',\n // Update semantics: the \"update\" action re-runs add in place — copy differentiates install vs update\n confirmUpdateTitle: 'Confirm update',\n updateNow: 'Update',\n updating: 'Updating…',\n queuedUpdateTitle: 'Queued for update…',\n updateResultTitle: 'Updated',\n updateResultDesc: 'The plugin has been updated to the latest version.',\n installFail: 'Install failed — copy the command instead',\n requestTimeout: 'Request timed out: GitHub may be unreachable or the network is unstable — try again later',\n confirmCancel: 'Cancel',\n doneBtn: 'Done',\n // Result view: some plugins need a restart to mount — offer restart now / later\n restartNow: 'Restart now',\n restartLater: 'Later',\n restarting: 'Restarting…',\n restartHint: 'Some plugins (such as plugin markets / top-level bundles) only take effect after a restart.',\n done: 'Done',\n restartPendingHint: 'Installed — takes effect after restart',\n restartPendingHintUninstall: 'Removed — cleaned up after restart',\n sectionPendingRestart: 'Pending restart',\n sectionInProgress: 'In progress',\n // 通知中心:安装/卸载任务成败的持久记录(工具栏铃铛入口按钮打开)\n notifications: 'Notifications',\n notificationsHint: 'View install/remove/update notifications',\n notificationsDesc: 'Every install, remove and update notice is logged here — even if you missed the prompt, you can always check back.',\n notificationsEmpty: 'No notifications yet',\n notificationsClear: 'Clear notifications',\n removeNotification: 'Remove this notification',\n queuedTitle: 'Queued…',\n queuedUninstallTitle: 'Queued for removal…',\n queuedHint: 'Queued — starts automatically after earlier tasks finish. You may close this window.',\n cancelTask: 'Cancel task',\n cancel: 'Cancel',\n cancelling: 'Cancelling…',\n errorTitle: 'Operation failed',\n errorTitleInstall: 'Install failed',\n errorTitleUninstall: 'Removal failed',\n errorPlugin: 'Plugin',\n errorClose: 'Got it',\n errorCopy: 'Copy error',\n errCopied: 'Error copied',\n failCopy: 'Copy full log',\n failIssueHint: 'Open a pre-filled issue on the author repo with this error log (includes catalog links)',\n failIssueBig: 'Report this bug to GitHub — contribute to open source',\n // prepare script actually failed (git tarball misses submodules/build output): a packaging issue of the plugin itself — file an issue\n 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.',\n // Pre-install / post-install guard hit ([packaging]): git distribution lacks build output, entry file missing = not adapted to the official default install method\n failPackagingHint: 'This plugin does not support the official default install method: its git distribution lacks the build output (the entry file declared in package.json is not in the repository), 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 or an npm release.',\n // native-module build scripts ignored by pnpm by default (e.g. node-pty, ERR_PNPM_IGNORED_BUILDS): only affects plugins with native deps — a dependency/packaging issue of the plugin itself, file an issue\n failIgnoredBuild: 'This plugin depends on a native module (e.g. node-pty) whose build script pnpm blocks by default, so the install fails — other plugins are unaffected. This is a dependency/packaging issue of the plugin itself. Please report it to the author repository and ask the author to switch to a prebuilt variant (e.g. node-pty-prebuilt-multiarch).',\n 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',\n 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',\n reportIssue: 'Report an Issue to the plugin repo',\n detail: 'Open details',\n noResult: 'No plugins match your search',\n noResultDesc: 'Try another keyword, or browse all plugins on the website.',\n today: 'updated today',\n daysAgo: 'updated {days}d ago',\n monthsAgo: 'updated {months}mo ago',\n yearsAgo: 'updated {years}y ago',\n pluginsTotal: 'Results: {n} plugins',\n // Category chips carry no counts; the filtered result count shows in the list header\n filterResults: 'Results: {n} plugins',\n more: '{n} more on the website',\n browseAll: 'Browse all {n} plugins',\n verified: 'Verified',\n // Version & updates: repos with a release are compared by tag; repos without one by last push time (new commits → update)\n version: 'Version',\n update: 'Update',\n updateAvailable: 'Update available',\n updateAvailableHint: 'An update was detected: repos with a release are compared by tag, repos without one by last push time',\n hubUpdateHint: 'A new DSH Plugin Hub version is available — click to view the changelog and update',\n hubUpdateTitle: 'A new DSH Plugin Hub version is available',\n hubUpdateDesc: 'v{version} has been released — click below to update, then restart the host to apply it.',\n hubUpdatePublished: 'Published',\n hubUpdateNotes: \"What's new\",\n hubUpdateLater: 'Later',\n versionHint: 'View version info and changelog',\n hubCurrentTitle: 'Current version',\n hubCurrentDesc: 'You are on v{version} — this is the latest version.',\n hubUpToDate: 'Up to date',\n // Header \"Follow us\" modal: platform intro + user feedback group QR (content pushed via Worker /about Markdown)\n followUs: 'Follow us',\n aboutTitle: 'Follow us',\n aboutDesc: 'Learn what DSH Plugin Hub does and join our user feedback group.',\n aboutEmpty: 'Content not published yet — stay tuned.',\n aboutUpdated: 'Updated',\n empty: 'No plugins in this category yet',\n dataFrom: 'Data from api.dsh-plugin.org · curated daily',\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Install target/command helpers: decide the install channel (npm package\n * vs explicit-HTTPS GitHub), build the display command and normalize a raw\n * install spec back to its owner/repo identity.\n */\nimport type { HubPlugin } from '../types.ts'\n\n/**\n * 安装通道决策(用户无感知):目录探测到 npm 包名 → 用 npm 包名安装\n * (走 npm registry tarball,更快、与 GitHub 网络无关);无 npm 包名 → git 直装。\n * 返回值 target 即传给后端 /install 的安装目标(npm 包名 或 owner/repo)。\n */\nexport function installTargetOf(p: HubPlugin): { target: string; via: 'npm' | 'github' } {\n const pkg = (p.source?.npmPackage ?? '').trim()\n const repo = (p.source?.repo ?? '').trim()\n if (pkg && repo) return { target: pkg, via: 'npm' }\n return { target: repo, via: 'github' }\n}\n\n/** 展示用安装命令(复制/弹窗):目录下发的权威命令优先(CLI-only 插件如 dsh-tui\n * 需专属 profile(--profile dsh-tui),无法从 repo/npm 包名推断,必须用官方命令);\n * 常规插件无目录命令时按通道回退生成:npm 显示包名,git 显示显式 HTTPS URL。 */\nexport function installCommandOf(p: HubPlugin, withProfile = false): string {\n const { target, via } = installTargetOf(p)\n if (via === 'npm') {\n const cmd = p.install?.command\n if (cmd) return cmd\n } else {\n const cmd = p.install?.githubCommand\n if (cmd) return cmd\n }\n return via === 'npm'\n ? `dsh plugin${withProfile ? ' --profile web' : ''} add ${target}`\n : `dsh plugin${withProfile ? ' --profile web' : ''} add git+https://github.com/${target}.git`\n}\n\n/** Normalize a task/install target to its owner/repo display identity. */\nexport function repoFromInstallTarget(value: string): string {\n const input = value.trim()\n if (/^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$/.test(input)) return input\n const patterns = [\n /^github:([^/]+)\\/([^/]+)$/i,\n /^(?:git\\+)?https:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?(?:[?#].*)?$/i,\n /^(?:git\\+)?ssh:\\/\\/(?:git@)?github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?(?:[?#].*)?$/i,\n /^git@github\\.com:([^/]+)\\/([^/]+?)(?:\\.git)?(?:[?#].*)?$/i,\n ]\n for (const pattern of patterns) {\n const match = pattern.exec(input)\n if (match !== null) return `${match[1]}/${match[2]}`\n }\n return value\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Constants: site URLs, category metadata and sort keys. Pure data — no\n * side effects, no network — so every consumer shares one definition.\n */\nimport type { LocaleId } from '../types.ts'\n\n/** 插件中心官网地址。 */\nexport const SITE_URL = 'https://dsh-plugin.org/'\n\n/** 插件中心源码仓库:头部右上角 GitHub 图标的跳转地址 */\nexport const GITHUB_URL = 'https://github.com/dshplugin/dsh-plugin-hub'\n\n/** Hub 自身在目录数据里的仓库标识:头部版本号旁的「可更新」徽标按它定位自己。 */\nexport const HUB_REPO = 'dshplugin/dsh-plugin-hub'\n\n/**\n * Hub 自我更新版本控制(接口中心 Pages:api.dsh-plugin.org,静态 JSON 发布)。\n * 发新版 = 在 api-center 的 releases/ 写发版记录 + 重新部署,hub.json 随之更新,\n * 所有已装用户的「可更新」徽标即可见,不再依赖主站目录数据管道。\n * 响应:{ version: string | null, publishedAt: string | null, notes: string | {zh,en} | null }\n */\nexport const HUB_UPDATE_URL = 'https://api.dsh-plugin.org/hub.json'\n\n/** 接口中心「关注我们」内容(静态 JSON,由 api-center 的 about.md 构建生成,Markdown)。 */\nexport const HUB_ABOUT_URL = 'https://api.dsh-plugin.org/about.json'\n\n/** 构建时由 tsdown 从 package.json 注入的插件版本号(见 tsdown.config.ts define)。 */\ndeclare const __PLUGIN_VERSION__: string\n\n/**\n * 插件当前版本号,供头部标题展示「DSH Plugin Hub v0.1.1」。\n * tsdown 构建时用 define 把 __PLUGIN_VERSION__ 替换成 package.json 的版本号;\n * node --test 直接 import 本模块时该标识符不存在,typeof 守卫兜底为空串。\n */\nexport const PLUGIN_VERSION: string =\n typeof __PLUGIN_VERSION__ === 'string' ? __PLUGIN_VERSION__ : ''\n\nexport const CATEGORY_ORDER = [\n 'interface', 'session', 'memory', 'tools', 'agent', 'workflow',\n 'integration', 'model', 'dev', 'knowledge', 'fun',\n]\n\n/** 分类标签按界面语言取词;未知 key 原样返回。 */\nexport function categoryLabel(\n map: Record<string, { zh: string; en: string }>,\n key: string,\n lang: LocaleId,\n): string {\n return map[key]?.[lang] ?? key\n}\n\nexport const CATEGORY_LABELS: Record<string, { zh: string; en: string }> = {\n interface: { zh: '界面与体验', en: 'UI & Experience' },\n session: { zh: '会话与消息', en: 'Sessions & Messages' },\n memory: { zh: '记忆与上下文', en: 'Memory & Context' },\n tools: { zh: '工具与能力', en: 'Tools & Capabilities' },\n agent: { zh: '技能与智能体', en: 'Skills & Agents' },\n workflow: { zh: '工作流与自动化', en: 'Workflow & Automation' },\n integration: { zh: '集成与连接', en: 'Integrations & Connections' },\n model: { zh: '模型与推理', en: 'Models & Reasoning' },\n dev: { zh: '开发与运维', en: 'Development & Operations' },\n knowledge: { zh: '数据与知识', en: 'Data & Knowledge' },\n fun: { zh: '娱乐', en: 'Entertainment' },\n}\n\n/** 分类 Tab 的紧凑标签(英文模式空间受限时使用)。 */\nexport const CATEGORY_SHORT_LABELS: Record<string, { zh: string; en: string }> = {\n interface: { zh: '界面体验', en: 'UI Exp' },\n session: { zh: '会话消息', en: 'Sessions' },\n memory: { zh: '记忆上下文', en: 'Memory' },\n tools: { zh: '工具能力', en: 'Tools' },\n agent: { zh: '技能智能体', en: 'Agents' },\n workflow: { zh: '工作流', en: 'Workflow' },\n integration: { zh: '集成连接', en: 'Integrations' },\n model: { zh: '模型推理', en: 'Models' },\n dev: { zh: '开发运维', en: 'Dev' },\n knowledge: { zh: '数据知识', en: 'Knowledge' },\n fun: { zh: '娱乐', en: 'Fun' },\n}\n\nexport const SORTS = ['sortStars', 'sortForks', 'sortUpdated', 'sortNewest'] as const\nexport type SortKey = (typeof SORTS)[number]\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Host repository: the local routes served by the DSH harness (installed\n * plugin table + environment snapshot). A host without the plugin's server\n * routes degrades to null / empty tables instead of throwing.\n */\nimport type { EnvInfo } from '../types.ts'\nimport type { InstalledVersionSignal } from '../logic/installed.ts'\n\nexport interface HostInstalled {\n installed: Record<string, string>\n versions: Record<string, InstalledVersionSignal>\n /** 每个依赖在系统上的安装目录(profile/node_modules/<包名>),宿主未提供为 null */\n paths: Record<string, string> | null\n /** 已加载进运行中 loader 的包名(官方 ctx.loader.entries() 对账):装完未重启的新插件不在其中 */\n loaded: string[] | null\n /** 真正的 dsh 插件包名(包内声明 dsh 配置 / 在 profile bundles 清单):非 dsh 插件(如官方示例仓库)装上也不会被宿主加载,不提示待重启 */\n dshCapable: string[] | null\n}\n\n/** 当前 profile 已安装插件表(npm 包名 -> manifest spec)+ 安装时记录的目录信号 + 安装路径 + 运行状态。 */\nexport async function fetchInstalled(): Promise<HostInstalled | null> {\n try {\n const res = await fetch('/dsh-plugin-hub/installed', { cache: 'no-store' })\n if (!res.ok) return null\n const data = await res.json() as {\n installed?: Record<string, string>\n versions?: Record<string, InstalledVersionSignal>\n paths?: Record<string, string>\n loaded?: string[]\n dshCapable?: string[]\n }\n return {\n installed: data.installed ?? {},\n versions: data.versions ?? {},\n paths: data.paths ?? null,\n loaded: data.loaded ?? null,\n dshCapable: data.dshCapable ?? null,\n }\n } catch {\n return null\n }\n}\n\nlet envPromise: Promise<EnvInfo | null> | null = null\n\n/** 在系统文件管理器里定位并打开已安装插件的目录(服务端 spawn open,跨平台);失败返回 false。 */\nexport async function revealInstallFolder(name: string): Promise<boolean> {\n try {\n const res = await fetch('/dsh-plugin-hub/open-path', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name }),\n cache: 'no-store',\n })\n return res.ok\n } catch {\n return false\n }\n}\n\n/** 在系统文件管理器里定位日志文件(服务端 spawn open,跨平台);失败返回 false。 */\nexport async function openLogFile(): Promise<boolean> {\n try {\n const res = await fetch('/dsh-plugin-hub/open-log', {\n method: 'POST',\n cache: 'no-store',\n })\n return res.ok\n } catch {\n return false\n }\n}\n\n/**\n * 系统目录选择器:弹原生文件夹对话框让用户挑日志存放目录(服务端 spawn\n * osascript / FolderBrowserDialog / zenity);选中返回绝对路径,取消或\n * 平台不支持(无 osascript / zenity)时返回 null。\n */\nexport async function chooseLogDir(): Promise<string | null> {\n try {\n const res = await fetch('/dsh-plugin-hub/choose-log-dir', {\n method: 'POST',\n cache: 'no-store',\n })\n if (!res.ok) return null\n const data = await res.json() as { path?: string }\n return typeof data.path === 'string' && data.path !== '' ? data.path : null\n } catch {\n return null\n }\n}\n\n/**\n * 宿主机器环境快照(/dsh-plugin-hub/env):提交 bug 时拼进 issue 正文。\n * 懒加载 + 模块级缓存:环境在会话期间不会变化;拉取失败降级为 null\n * (issue 链接照常生成,只是少环境段)。\n */\nexport function getEnv(): Promise<EnvInfo | null> {\n envPromise ??= fetch('/dsh-plugin-hub/env', { cache: 'no-store' })\n .then((res) => (res.ok ? (res.json() as Promise<EnvInfo>) : null))\n .catch(() => null)\n return envPromise\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Normalizer: maps the online API's short-key payload (s/o/n/vr/c/t/f/d/r/v/u/a/sg/fk)\n * to HubPlugin so rendering only ever sees one shape.\n */\nimport type { HubPlugin } from '../types.ts'\n\nexport function normalize(raw: Record<string, unknown>): HubPlugin {\n if (typeof raw.s === 'string') {\n return {\n slug: raw.s,\n ownerSlug: typeof raw.o === 'string' ? raw.o : undefined,\n displayName: typeof raw.n === 'string' ? raw.n : undefined,\n version: typeof raw.vr === 'string' ? raw.vr : undefined,\n category: typeof raw.c === 'string' ? raw.c : undefined,\n topics: Array.isArray(raw.t) ? (raw.t as string[]) : undefined,\n features: Array.isArray(raw.f) ? (raw.f as string[]) : undefined,\n description: typeof raw.d === 'string' ? raw.d : undefined,\n // source 双形态:字符串 repo,或 { repo, npmPackage } 对象\n source: typeof raw.r === 'string'\n ? { repo: raw.r }\n : raw.r !== null && typeof raw.r === 'object'\n ? {\n repo: typeof (raw.r as { repo?: unknown }).repo === 'string' ? (raw.r as { repo: string }).repo : undefined,\n npmPackage: typeof (raw.r as { npmPackage?: unknown }).npmPackage === 'string' ? (raw.r as { npmPackage: string }).npmPackage : undefined,\n }\n : undefined,\n // 安装信息:wi 仅在 false 时下发(缺省视为 true 可一键安装);\n // ic/igc = 目录下发的权威安装命令(npm/git 通道各一条,CLI-only 插件如 dsh-tui 必须用)\n install: raw.wi === false || typeof raw.ic === 'string' || typeof raw.igc === 'string'\n ? {\n webInstallable: raw.wi === false ? false : undefined,\n command: typeof raw.ic === 'string' ? raw.ic : undefined,\n githubCommand: typeof raw.igc === 'string' ? raw.igc : undefined,\n }\n : undefined,\n compatibility: typeof raw.v === 'string' ? { status: raw.v } : undefined,\n dates: {\n repoUpdatedAt: typeof raw.u === 'string' ? raw.u : undefined,\n addedAt: typeof raw.a === 'string' ? raw.a : undefined,\n },\n stats: {\n stargazers_count: typeof raw.sg === 'number' ? raw.sg : undefined,\n forks_count: typeof raw.fk === 'number' ? raw.fk : undefined,\n },\n }\n }\n return raw as unknown as HubPlugin\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Catalog repository: fetches the plugin directory and the collection stats\n * from the online API and normalizes them. Components never see URLs or\n * fetch — the repository is the only place that knows where data lives.\n */\nimport type { HubPlugin, LocaleId } from '../types.ts'\nimport { normalize } from '../logic/normalize.ts'\n\n// 目录/统计数据经服务端 /catalog 代理路由获取(curl 子进程注入设置里的代理),\n// 与 npm / git 安装通道同一代理口径 —— 浏览器不再直连 api.dsh-plugin.org。\nconst PROXY_BASE = '/dsh-plugin-hub/catalog'\nconst PLUGINS_URL = (lang: LocaleId) => `${PROXY_BASE}?lang=${lang}`\nconst STATS_URL = `${PROXY_BASE}?stats=1`\n\nasync function fetchJson(url: string): Promise<unknown> {\n const res = await fetch(url, { cache: 'no-store' })\n if (!res.ok) throw new Error(String(res.status))\n return res.json()\n}\n\n/** 目录插件列表(在线 API 已只返回 verified;过滤与排序由上层负责)。 */\nexport async function fetchCatalog(lang: LocaleId): Promise<HubPlugin[]> {\n const data = await fetchJson(PLUGINS_URL(lang))\n return (Array.isArray(data) ? data : []).map((item) => normalize(item as Record<string, unknown>))\n}\n\n/** 收录/精选统计(/api/stats.json);字段不完整返回 null。 */\nexport async function fetchStats(): Promise<{ total: number; verified: number } | null> {\n const s = await fetchJson(STATS_URL) as { total?: number; verified?: number }\n if (s && typeof s.total === 'number' && typeof s.verified === 'number') {\n return { total: s.total, verified: s.verified }\n }\n return null\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Hub meta repository: the Cloudflare Worker endpoints behind the self-update\n * check and the \"About us\" content. Failures degrade to null — the caller\n * decides how to fall back (no badge, placeholder copy), never throws.\n */\nimport type { HubAboutInfo, HubUpdateInfo } from '../types.ts'\nimport { HUB_ABOUT_URL, HUB_UPDATE_URL } from '../logic/constants.ts'\n\n/** 版本接口是 Pages 静态文件,默认带 CDN 缓存(Cache-Control: public, max-age=43200,\n * 即 12 小时),客户端 no-store 管不到 CDN 边缘,会拿到旧公告。\n * 静态资产请求免费且无限,因此所有版本检查一律带时间戳 query:URL 每次不同 →\n * CDN 缓存 key 不同 → 强制回源拉到最新公告,无任何配额顾虑。 */\nfunction busted(url: string): string {\n const sep = url.includes('?') ? '&' : '?'\n return `${url}${sep}_t=${Date.now()}`\n}\n\n/** Worker 版本控制中心:最新版本 + Markdown 变更记录;不可用返回 null。 */\nexport async function fetchHubUpdate(): Promise<HubUpdateInfo | null> {\n try {\n const res = await fetch(busted(HUB_UPDATE_URL), { cache: 'no-store' })\n if (!res.ok) return null\n const data = await res.json() as HubUpdateInfo | null\n if (!data) return null\n const version = typeof data.version === 'string' && data.version.length > 0 ? data.version : null\n if (version === null) return null\n return { version, publishedAt: data.publishedAt ?? null, notes: data.notes ?? null }\n } catch {\n return null\n }\n}\n\n/** Worker「关注我们」内容(平台介绍 + 反馈群二维码,Markdown);未推送返回 null。 */\nexport async function fetchHubAbout(): Promise<HubAboutInfo | null> {\n try {\n const res = await fetch(busted(HUB_ABOUT_URL), { cache: 'no-store' })\n if (!res.ok) return null\n const data = await res.json() as HubAboutInfo | null\n if (!data || data.content === null || data.content === undefined) return null\n const content = typeof data.content === 'string' || typeof data.content === 'object' ? data.content : null\n if (content === null) return null\n return { content, updatedAt: data.updatedAt ?? null }\n } catch {\n return null\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Installed-plugin model (pure logic, zero React/UI dependencies).\n *\n * Merges the local installed table (from the host's `/installed` route:\n * npm name → manifest spec) with the catalog projection into a single\n * `InstalledItem` view-model consumed by the Installed view. Also hosts the\n * install matching / update detection used by the market view, so both\n * views share one source of truth.\n */\nimport type { HubPlugin } from '../types.ts'\nimport { HUB_REPO } from './constants.ts'\nimport { repoFromInstallTarget } from './install-command.ts'\n\n/** 安装时记录的目录信号(versions 表项)。 */\nexport interface InstalledVersionSignal {\n version: string\n updatedAt: string\n installedAt?: string\n npmPackage?: string\n}\n\n/** 已安装项统一模型:目录元数据 + 宿主运行时信息的合并视图(驱动「已安装」tab)。 */\nexport interface InstalledItem {\n /** npm 包名(profile 依赖 key) */\n name: string\n /** manifest spec(github:owner/repo、git+https://…、或 npm 版本号) */\n spec: string\n /** 目录里匹配到的插件;目录外/未收录的安装为 null */\n plugin: HubPlugin | null\n /** 仓库身份(owner/repo);纯 npm 安装无法识别时为 null */\n repo: string | null\n /** 安装到系统上的路径(profile/node_modules/<包名>);宿主未提供为 null */\n installPath: string | null\n /** 安装时记录的目录版本(无记录为 null) */\n installedVersion: string | null\n /** 安装时间(ISO,无记录为 null) */\n installedAt: string | null\n /** 目录当前最新版本(仓库无 release 为 null) */\n catalogVersion: string | null\n /** 是否有可用更新(有版本比版本,无版本比仓库更新时间) */\n hasUpdate: boolean\n /** 是否已加载进运行中 loader(官方 ctx.loader 对账);false = 已安装但未挂载(装完未重启) */\n loaded: boolean\n /** 是否真正的 dsh 插件(包内声明 dsh 配置 / 在 profile bundles 清单):\n * 非 dsh 插件(如 GitHub 官方示例仓库)装上也不会被宿主加载,不提示「待重启」 */\n dshCapable: boolean\n}\n\n/** 安装时记录的目录信号(按仓库小写 key 查表)。 */\nfunction signalOf(repo: string | null, versions: Record<string, InstalledVersionSignal>): InstalledVersionSignal | null {\n if (!repo) return null\n return versions[repo.toLowerCase()] ?? null\n}\n\n/** 插件是否已安装:匹配 Git spec 中的 owner/repo,或 npm 通道安装的依赖包名;命中返回 npm 包名。 */\nexport function installedNameOf(\n plugin: HubPlugin,\n installed: Record<string, string>,\n versions: Record<string, InstalledVersionSignal>,\n): string | null {\n const repo = plugin.source?.repo\n if (!repo) return null\n const needle = repo.toLowerCase()\n for (const [name, spec] of Object.entries(installed)) {\n if (repoFromInstallTarget(spec).toLowerCase() === needle) return name\n }\n // npm 通道安装:profile 依赖 key 直接是 npm 包名。包名来源两处——目录数据(npmPackage),\n // 或服务端 npm 优先反查持久化的映射(versions[repo].npmPackage,覆盖组织 scope 与 GitHub\n // 用户名不一致、目录未下发包名的场景);命中任一并依赖 key 真实存在即视为已安装。\n // 只认 npm 安装的依赖(spec 无法解析出仓库身份):git/本地安装的依赖身份由仓库匹配决定,\n // 包名同名不代表同仓库——否则「git 装 A 仓库」会被「npm 包名同名但仓库不同」的目录条目\n // 误认领成已安装(假阳性),installedItems 里出现同 key 双条目,排序一变化就渲染出幽灵行。\n const pkg = ((plugin.source?.npmPackage || versions[repo.toLowerCase()]?.npmPackage) ?? '').toLowerCase()\n if (pkg) {\n for (const [name, spec] of Object.entries(installed)) {\n if (isRepoLike(repoFromInstallTarget(spec))) continue\n if (name.toLowerCase() === pkg) return name\n }\n }\n return null\n}\n\n/** 该插件安装时记录的目录版本(无记录/未安装 → null)。 */\nexport function installedVersionOf(plugin: HubPlugin, versions: Record<string, InstalledVersionSignal>): string | null {\n const repo = plugin.source?.repo\n if (!repo) return null\n return versions[repo.toLowerCase()]?.version ?? null\n}\n\n/**\n * 是否有更新:仅对已安装插件有意义。\n * 双信号判定——有 release 版本的比版本;无版本(repo 不打 tag)的比仓库最近更新时间\n * (repoUpdatedAt,ISO 字符串字典序 = 时间序),更新时间变新说明有新提交。\n */\nexport function hasUpdateOf(\n plugin: HubPlugin,\n installed: Record<string, string>,\n versions: Record<string, InstalledVersionSignal>,\n): boolean {\n if (installedNameOf(plugin, installed, versions) === null) return false\n const repo = plugin.source?.repo\n if (!repo) return false\n const rec = versions[repo.toLowerCase()]\n if (!rec) return false\n if (plugin.version) return plugin.version !== rec.version\n const current = plugin.dates?.repoUpdatedAt\n return Boolean(current && rec.updatedAt && current > rec.updatedAt)\n}\n\n/** 依赖 spec 能否解析出仓库身份(owner/repo 形态才算)。 */\nfunction isRepoLike(value: string): boolean {\n return /^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$/.test(value)\n}\n\n/**\n * 提 Issue 的仓库身份解析:失败目标可能是 owner/repo 也可能是 npm 包名(含 @scope/pkg、\n * 可带 @version,如 dsh-plugin、@scope/pkg@1.2.3)。\n * - 目标本身就能解析出 owner/repo → 直接用;\n * - npm 包名 → 反查仓库身份:先查已安装表(该包名的条目若带仓库身份即命中),再查目录插件\n * (source.npmPackage 与包名一致,取目录收录的仓库身份)。\n * 反查到才返回,查不到返回 null —— 调用方据此不显示「一键提 Issue」按钮,避免把 Issue\n * 提到错误的地址(别人发的 npm 包名不是 GitHub 仓库,直接拼 github.com/<包名> 是打不开的)。\n */\nexport function issueRepoOf(\n target: string,\n installedItems: InstalledItem[],\n plugins: HubPlugin[] | null,\n): string | null {\n const input = target.trim()\n if (!input) return null\n const parsed = repoFromInstallTarget(input)\n if (isRepoLike(parsed)) return parsed\n const pkg = parsed.replace(/@[^@]*$/, '').toLowerCase()\n // 已安装表:包名命中的条目(目录收录条目直接带仓库身份;自定义安装按 github: spec 解析)\n for (const item of installedItems) {\n if (item.name.toLowerCase() !== pkg) continue\n if (item.repo) return item.repo\n const repo = repoFromInstallTarget(item.spec)\n if (isRepoLike(repo)) return repo\n }\n // 目录插件:npmPackage 与包名一致 → 用目录收录的仓库身份\n for (const p of plugins ?? []) {\n const pkgName = (p.source?.npmPackage ?? '').trim()\n if (pkgName !== '' && pkgName.toLowerCase() === pkg && p.source?.repo) return p.source.repo\n }\n return null\n}\n\n/** 已安装项 → 弹窗可用的伪插件对象:卸载确认弹窗只读名称/来源行,\n * 自定义安装(目录外)没有完整目录数据,用它把 InstalledItem 适配成 HubPlugin。 */\nexport function pluginOfItem(item: InstalledItem): HubPlugin {\n return {\n slug: item.name,\n displayName: item.plugin?.displayName ?? item.name,\n source: item.repo ? { repo: item.repo } : undefined,\n description: item.plugin?.description,\n }\n}\n\n/**\n * Hub 自身(本插件 dsh-plugin)的识别:三维互证,杜绝误伤同名第三方包。\n * 1) 依赖 key 固定为 `dsh-plugin`(本插件 npm 包名);\n * 2) spec 为 `file:`/`link:` 本地链接(hub 以 file: 安装进宿主);\n * 3) 或 spec 解析出的仓库身份就是自营仓库 `dshplugin/dsh-plugin-hub`。\n * 命中即视为宿主内置本体:永不出现在「自定义安装」里,卸载接口也早已对\n * 它 400 拒绝(服务端多维防线之一)——显示出来只会让用户误点卸载。\n */\nfunction isHubSelf(name: string, spec: string): boolean {\n if (name !== 'dsh-plugin') return false\n if (spec.startsWith('file:') || spec.startsWith('link:')) return true\n const repo = repoFromInstallTarget(spec)\n if (isRepoLike(repo) && repo.toLowerCase() === HUB_REPO.toLowerCase()) return true\n // npm 通道覆盖重装 hub 自身后,file:/link: 本地链接会被替换成 registry 版本号/范围\n // (如 1.3.0、^1.3.0)——依赖 key `dsh-plugin` 在 npm 上唯一属于本插件(不存在第三方\n // 同名包),版本号形态与仓库身份同样视为 hub 自身:命令窗口「自己装自己」成功后,\n // 条目仍不进已安装列表(卸载接口对它的 400 拒绝是服务端最后一道防线)。\n return !isRepoLike(repo)\n}\n\n/**\n * 构建已安装项列表:目录插件按命中关系合并(拥有完整元数据),\n * 剩余未认领的依赖 key 归为自定义安装(目录外,仅运行时信息)。\n */\nexport function installedItemsOf(\n plugins: HubPlugin[] | null,\n installed: Record<string, string>,\n versions: Record<string, InstalledVersionSignal>,\n paths: Record<string, string> | null,\n loadedNames: string[] | null,\n dshCapableNames: string[] | null,\n): InstalledItem[] {\n const items: InstalledItem[] = []\n // 已被目录条目认领的依赖 key:同一依赖只归属一个目录条目(React key 必须唯一,\n // 否则同名双条目排序一变化就渲染出幽灵行);剩余未认领的归自定义安装。\n const claimed = new Set<string>()\n // 目录匹配:遍历目录插件,命中 installedNameOf 即视为已安装并合并元数据\n for (const p of plugins ?? []) {\n const name = installedNameOf(p, installed, versions)\n if (name === null || claimed.has(name)) continue\n claimed.add(name)\n const repo = p.source?.repo ?? null\n const rec = signalOf(repo, versions)\n items.push({\n name,\n spec: installed[name],\n plugin: p,\n repo,\n installPath: paths?.[name] ?? null,\n installedVersion: rec?.version ?? null,\n installedAt: rec?.installedAt ?? null,\n catalogVersion: p.version ?? null,\n hasUpdate: hasUpdateOf(p, installed, versions),\n loaded: loadedNames?.includes(name) ?? false,\n dshCapable: dshCapableNames?.includes(name) ?? false,\n })\n }\n // 自定义安装:依赖表里没被任何目录插件认领的条目(命令行安装的目录外插件)\n for (const [name, spec] of Object.entries(installed)) {\n if (claimed.has(name)) continue\n // Hub 自身(本插件 dsh-plugin)由宿主内置加载,不是可管理的插件:永不进已安装列表,\n // 避免出现在「自定义安装」里被误点卸载(服务端卸载接口对它的 400 拒绝是最后一道防线)\n if (isHubSelf(name, spec)) continue\n const parsed = repoFromInstallTarget(spec)\n const repo = isRepoLike(parsed) ? parsed : null\n const rec = signalOf(repo, versions)\n items.push({\n name,\n spec,\n plugin: null,\n repo,\n installPath: paths?.[name] ?? null,\n installedVersion: rec?.version ?? null,\n installedAt: rec?.installedAt ?? null,\n catalogVersion: null,\n // 目录外没有目录信号可比,无法判断是否有更新\n hasUpdate: false,\n loaded: loadedNames?.includes(name) ?? false,\n dshCapable: dshCapableNames?.includes(name) ?? false,\n })\n }\n return items\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Catalog data + view state for the Plugin Hub section.\n *\n * Owns the online-data pipeline (live fetch from api.dsh-plugin.org), the local\n * installed-plugin table, and the filter/search/sort/install-status view\n * state, exposing the derived visible list and per-category counts.\n */\nimport { useEffect, useMemo, useState } from 'react'\nimport type { HubPlugin, LocaleId } from '../types.ts'\nimport { HUB_REPO, PLUGIN_VERSION } from '../logic/constants.ts'\nimport type { HubAboutInfo, HubUpdateInfo } from '../types.ts'\nimport type { SortKey } from '../logic/constants.ts'\nimport { fetchCatalog, fetchStats } from '../data/catalog.ts'\nimport { fetchHubAbout, fetchHubUpdate } from '../data/hub.ts'\nimport { fetchInstalled } from '../data/host.ts'\nimport {\n hasUpdateOf, installedItemsOf, installedNameOf, installedVersionOf,\n} from '../logic/installed.ts'\nimport type { InstalledItem, InstalledVersionSignal } from '../logic/installed.ts'\n\n/** 插件市场自身仓库:DSH Plugin Hub 不显示在目录里(自己不进自己的插件列表) */\nconst SELF_REPO = 'dshplugin/dsh-plugin-hub'\n\n/** 市场各排序的默认方向:全部按倒序(Star/Fork 多、更新/收录近的在前) */\nconst SORT_DEFAULT_DIR: Record<SortKey, 'asc' | 'desc'> = {\n sortStars: 'desc', sortForks: 'desc', sortUpdated: 'desc', sortNewest: 'desc',\n}\n\nexport function useCatalog(lang: LocaleId) {\n /** 目录插件(仅保留人工验证通过的条目) */\n const [plugins, setPlugins] = useState<HubPlugin[] | null>(null)\n /** Hub 自身目录条目(dshplugin/dsh-plugin-hub):目录过滤会排除自身(不进插件列表),\n * 此处单独保留,供头部「可更新」徽标 → 「直接更新」覆盖重装使用。 */\n const [hubPlugin, setHubPlugin] = useState<HubPlugin | null>(null)\n /** 收录/精选统计(官网 /api/stats.json 实时拉取) */\n const [stats, setStats] = useState<{ total: number; verified: number } | null>(null)\n const [failed, setFailed] = useState(false)\n const [reloadKey, setReloadKey] = useState(0)\n const [category, setCategory] = useState('all')\n const [query, setQuery] = useState('')\n const [sort, setSort] = useState<SortKey>('sortStars')\n /** 当前排序方向:点同一个排序按钮切换 正序/倒序;点新排序用该排序的默认方向(与已安装视图一致) */\n const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc')\n\n /** 点击排序按钮:同一按钮切换正/倒序,新按钮用默认方向 */\n function toggleSort(key: SortKey) {\n if (key === sort) setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))\n else { setSort(key); setSortDir(SORT_DEFAULT_DIR[key]) }\n }\n /**\n * 强制刷新 Hub 版本与「关注我们」信息:点击头部版本号/徽标时触发。\n * 挂载期的 useEffect 只在进入/reload 时拉一次,发版后已打开的界面点版本号\n * 仍显示旧数据;此处重新拉接口中心,最新版本与变更记录点击即见。\n * 失败静默为 null(弹窗兜底展示当前版本号),与挂载期拉取口径一致。\n */\n const refreshHub = async () => {\n // 版本接口已恒带时间戳绕过 CDN,手动/自动拉取都能拿到最新公告\n const [info, about] = await Promise.all([fetchHubUpdate(), fetchHubAbout()])\n setHubUpdateInfo(info)\n setHubAboutInfo(about)\n }\n\n /** 当前 profile 已安装插件:npm 包名 -> manifest spec(来自宿主本地路由) */\n const [installed, setInstalled] = useState<Record<string, string>>({})\n /** 安装时记录的目录信号:repo(小写) -> { version, updatedAt }(来自宿主本地路由);\n * npmPackage 为 npm 优先通道反查命中的包名映射(目录数据未下发时客户端靠它把依赖 key 匹配回仓库) */\n const [versions, setVersions] = useState<Record<string, InstalledVersionSignal>>({})\n /** 每个依赖在系统上的安装目录(profile/node_modules/<包名>),详情视图展示用 */\n const [installPaths, setInstallPaths] = useState<Record<string, string> | null>(null)\n /** 已加载进运行中 loader 的包名(官方 ctx.loader 对账):装完未重启的新插件不在其中 */\n const [loadedNames, setLoadedNames] = useState<string[] | null>(null)\n /** 真正的 dsh 插件包名(包内声明 dsh 配置 / 在 profile bundles 清单):非 dsh 插件不提示「待重启」 */\n const [dshCapableNames, setDshCapableNames] = useState<string[] | null>(null)\n /** Hub 自我更新信息:来自接口中心 Pages(api.dsh-plugin.org),与目录数据解耦 */\n const [hubUpdateInfo, setHubUpdateInfo] = useState<HubUpdateInfo | null>(null)\n /** 头部「关注我们」弹窗内容(平台介绍 + 反馈群二维码):来自接口中心 /about,Markdown 推送非写死 */\n const [hubAboutInfo, setHubAboutInfo] = useState<HubAboutInfo | null>(null)\n\n // 拉取目录 + 统计。在线 API 已只返回 verified;再过滤一次,保证只展示人工验证通过的插件。\n useEffect(() => {\n let cancelled = false\n setPlugins(null)\n setHubPlugin(null)\n setStats(null)\n setFailed(false)\n // 目录数据直拉:hub 自身版本由独立 Worker 版本控制中心管理,不再依赖主站版本号接口。\n const load = () => Promise.all([fetchCatalog(lang), fetchStats()])\n load()\n .then(([list, stats]) => {\n if (cancelled) return\n // 插件市场不显示自己:DSH Plugin Hub 从目录里排除自身条目,\n // 防止「自己出现在自己的插件列表里、还能自己安装自己」;统计计数同步减 1 保持与列表一致。\n // 目录数据已排除自身,此处再兜底过滤一次,防旧快照仍含自身条目。\n const hadSelf = list.some((p) => p.source?.repo === SELF_REPO)\n // 过滤前单独保留 hub 自身条目:它不进目录列表,但「可更新」徽标的直接更新需要它作为重装目标\n setHubPlugin(list.find((p) => p.source?.repo === SELF_REPO) ?? null)\n setPlugins(list.filter((p) => p.compatibility?.status === 'verified' && p.source?.repo !== SELF_REPO))\n if (stats) {\n setStats(hadSelf\n ? { total: stats.total - 1, verified: stats.verified - 1 }\n : { total: stats.total, verified: stats.verified })\n }\n })\n .catch(() => {\n if (!cancelled) setFailed(true)\n })\n return () => { cancelled = true }\n // lang 必须进依赖:切换界面语言要重新拉对应语言的数据文件,\n // 否则英文模式仍停留在 plugins.zh.json,描述/名称全是中文\n }, [reloadKey, lang])\n\n /** 刷新当前 profile 已安装插件表;宿主未挂本地路由时静默降级为空表。 */\n const refreshInstalled = async () => {\n const data = await fetchInstalled()\n if (data === null) return\n setInstalled(data.installed)\n setVersions(data.versions)\n setInstallPaths(data.paths)\n setLoadedNames(data.loaded)\n setDshCapableNames(data.dshCapable)\n }\n\n // 首次进入拉取已安装表(依赖宿主 webServer 服务)\n useEffect(() => { refreshInstalled() }, [])\n\n // Hub 自身版本检查走独立 Worker(版本控制中心):发新版后写一次 Worker KV,\n // 所有已装用户立即看到「可更新」+ Markdown 变更记录,不再依赖主站目录数据管道。\n // 失败静默降级为 null(徽标不出现,不影响目录本身加载)。\n useEffect(() => {\n let cancelled = false\n void fetchHubUpdate().then((info) => { if (!cancelled) setHubUpdateInfo(info) })\n return () => { cancelled = true }\n }, [reloadKey])\n\n // 「关注我们」内容走同一套 Worker:作者写好 Markdown(平台介绍 + 反馈群二维码)推送 /admin/about,\n // 客户端下次进入拉 /about 即可看到最新,非写死。失败静默为 null(弹窗展示兜底文案,不阻塞)。\n useEffect(() => {\n let cancelled = false\n void fetchHubAbout().then((info) => { if (!cancelled) setHubAboutInfo(info) })\n return () => { cancelled = true }\n }, [reloadKey])\n\n /** 插件是否已安装:匹配 Git spec 中的 owner/repo,或 npm 通道安装的依赖包名;命中返回 npm 包名。 */\n const installedName = (p: HubPlugin): string | null => installedNameOf(p, installed, versions)\n\n /** 该插件安装时记录的目录版本(无记录/未安装 → null)。 */\n const installedVersion = (p: HubPlugin): string | null => installedVersionOf(p, versions)\n\n /**\n * 是否有更新:仅对已安装插件有意义。\n * 双信号判定——有 release 版本的比版本;无版本(repo 不打 tag)的比仓库最近更新时间\n * (repoUpdatedAt,ISO 字符串字典序 = 时间序),更新时间变新说明有新提交。\n */\n const hasUpdate = (p: HubPlugin): boolean => hasUpdateOf(p, installed, versions)\n\n /** 已安装项统一列表(目录元数据 + 运行时信息合并):驱动「已安装」tab。 */\n const installedItems = useMemo<InstalledItem[]>(\n () => installedItemsOf(plugins, installed, versions, installPaths, loadedNames, dshCapableNames),\n [plugins, installed, versions, installPaths, loadedNames, dshCapableNames],\n )\n\n /**\n * Hub 自身是否有可用更新:Hub 就是当前运行的应用(始终已安装,无需 installedName 命中)。\n * 以 Worker 版本控制中心返回的「最新版本」为准,与当前运行的版本号比对——\n * 构建时注入的 PLUGIN_VERSION 是运行 bundle 的真实版本;测试/异常场景缺失时\n * 回退到安装时记录的版本。版本号不等即新版(版本号只在发版时变更,绝无降级场景)。\n */\n const hubHasUpdate = (() => {\n if (!hubUpdateInfo) return false\n const current = PLUGIN_VERSION || versions[HUB_REPO]?.version || null\n return current !== null && hubUpdateInfo.version !== current\n })()\n\n /** 当前分类下的插件(「全部」时为整个目录)。 */\n const categoryPlugins = useMemo(() => {\n if (!plugins) return []\n if (category === 'all') return plugins\n return plugins.filter((p) => p.category === category)\n }, [plugins, category])\n\n const visible = useMemo(() => {\n if (!plugins) return []\n const q = query.trim().toLowerCase()\n const list = plugins.filter((p) => {\n if (category !== 'all' && p.category !== category) return false\n if (!q) return true\n return (\n (p.displayName ?? '').toLowerCase().includes(q) ||\n (p.description ?? '').toLowerCase().includes(q) ||\n (p.topics ?? []).some((topic) => topic.toLowerCase().includes(q))\n )\n })\n const dir = sortDir === 'asc' ? 1 : -1\n return [...list].sort((a, b) => {\n // 比较器统一用「升序写法」再乘 dir:desc 时 dir=-1 翻成降序(Star/Fork 最多、更新/收录最近在前)\n if (sort === 'sortStars') return ((a.stats?.stargazers_count ?? 0) - (b.stats?.stargazers_count ?? 0)) * dir\n if (sort === 'sortForks') return ((a.stats?.forks_count ?? 0) - (b.stats?.forks_count ?? 0)) * dir\n if (sort === 'sortNewest') return (a.dates?.addedAt ?? '').localeCompare(b.dates?.addedAt ?? '') * dir\n return (a.dates?.repoUpdatedAt ?? '').localeCompare(b.dates?.repoUpdatedAt ?? '') * dir\n })\n }, [plugins, category, query, sort, sortDir, installed])\n\n /** Per-category plugin counts shown on the category chips. */\n const categoryCounts = useMemo(() => {\n const counts: Record<string, number> = {}\n for (const p of plugins ?? []) {\n if (p.category) counts[p.category] = (counts[p.category] ?? 0) + 1\n }\n return counts\n }, [plugins])\n\n return {\n plugins,\n hubPlugin,\n stats,\n failed,\n reload: () => setReloadKey((k) => k + 1),\n installed,\n installedItems,\n installedName,\n installedVersion,\n hasUpdate,\n hubHasUpdate,\n hubUpdateInfo,\n hubAboutInfo,\n refreshHub,\n refreshInstalled,\n category,\n setCategory,\n query,\n setQuery,\n sort,\n sortDir,\n toggleSort,\n visible,\n total: plugins?.length ?? 0,\n categoryCounts,\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Failure classification, issue-body summarization and persistent\n * install/remove notifications.\n *\n * Every settled task is recorded two ways: the server-side system log\n * (hub.log) and a client-side localStorage record that feeds the\n * notification center — so a result is never lost even when the dialog\n * was dismissed or nobody was watching the progress strip.\n */\nexport interface NotificationRecord {\n id: number\n kind: 'install' | 'uninstall' | 'update'\n /** true = 成功(轻量记录);false = 失败(message 携带完整错误日志) */\n ok: boolean\n /** owner/repo(可能为空:请求层失败但拿不到仓库时) */\n repo: string\n /** 失败时的完整错误日志;成功记录为空串 */\n message: string\n /** 更新提醒:目录里的新版本号(展示用;其余通知省略) */\n version?: string\n /** 实际执行的安装/卸载命令(issue 预填时如实展示);历史记录可能缺失 */\n command?: string\n /** 尝试过的安装方式(npm registry 反查 + 实际执行命令,按先后顺序):失败提 Issue 时贴给作者,便于反推正确的 npm 包名 */\n attempts?: string[]\n /** 结束时间(epoch ms) */\n at: number\n}\n\nconst KEY = 'gro.ngilp-hsd.failure-records'\nconst MAX = 50\n\n/** 运行时 localStorage 访问:类型上不依赖 DOM lib(Node 测试环境也能编译),浏览器里取 window。 */\nconst storage = (): Storage | undefined =>\n (globalThis as { localStorage?: Storage }).localStorage\n\n/** 读取本地通知记录(损坏/不可用时返回空列表,不抛错)。列表最新在前,全部保留,只由「清空」按钮手动移除。 */\nexport function loadNotifications(): NotificationRecord[] {\n try {\n const raw = storage()?.getItem(KEY)\n if (!raw) return []\n const list = JSON.parse(raw) as unknown\n if (!Array.isArray(list)) return []\n return list\n .filter((r): r is NotificationRecord =>\n !!r && typeof r === 'object' && typeof (r as { message?: unknown }).message === 'string')\n // ok 字段缺省时按失败渲染\n .map((r) => ({ ...r, ok: r.ok === true }))\n } catch {\n return []\n }\n}\n\nfunction save(list: NotificationRecord[]): void {\n try {\n storage()?.setItem(KEY, JSON.stringify(list))\n } catch {\n /* storage full / unavailable:仅保留内存态,界面仍可查看 */\n }\n}\n\n/** 追加一条通知记录并持久化,返回更新后的完整列表(最新在前,超上限裁剪)。\n * 每次成功/失败都各自留痕:同一插件的安装/卸载记录都完整保留、只由「清空」按钮手动移除,\n * 不会因后续操作被自动覆盖清除。 */\nexport function addNotification(record: Omit<NotificationRecord, 'id' | 'at'>): NotificationRecord[] {\n const prev = loadNotifications()\n let id = Date.now()\n while (prev.some((r) => r.id === id)) id += 1\n const next = [{ ...record, id, at: id }, ...prev].slice(0, MAX)\n save(next)\n return next\n}\n\n/** 记录一次失败:携带完整错误日志,供通知中心查看/复制/提 Issue。 */\nexport function addFailure(record: Omit<NotificationRecord, 'id' | 'at' | 'ok'>): NotificationRecord[] {\n return addNotification({ ...record, ok: false })\n}\n\n/** 记录一次成功:轻量记录,不带日志。 */\nexport function addSuccess(record: Omit<NotificationRecord, 'id' | 'at' | 'ok' | 'message'>): NotificationRecord[] {\n return addNotification({ ...record, ok: true, message: '' })\n}\n\n/** 记录一条「发现新版本」更新提醒:成功类轻量记录,携带目录新版本号供通知中心展示。\n * 同一插件同一新版本已在通知中心时跳过:宿主重载会重新触发启动检查,不更新时\n * 通知里已有的提醒保持单条,不重复追加。 */\nexport function addUpdateNotice(record: Omit<NotificationRecord, 'id' | 'at' | 'ok' | 'message'>): NotificationRecord[] {\n const prev = loadNotifications()\n const dup = prev.some((r) =>\n r.kind === 'update' && r.repo === record.repo && (r.version ?? undefined) === (record.version ?? undefined))\n if (dup) return prev\n return addNotification({ ...record, ok: true, message: '' })\n}\n\n/** 已忽略的更新提醒持久化 key:`owner/repo@version` 字符串数组。 */\nconst IGNORE_KEY = 'gro.ngilp-hsd.ignored-updates'\n\n/** 读取已忽略的更新提醒(`owner/repo@version` 字符串集合);损坏/不可用时返回空集合。 */\nexport function loadIgnoredUpdates(): Set<string> {\n try {\n const raw = storage()?.getItem(IGNORE_KEY)\n if (!raw) return new Set()\n const list = JSON.parse(raw) as unknown\n if (!Array.isArray(list)) return new Set()\n return new Set(list.filter((x): x is string => typeof x === 'string'))\n } catch {\n return new Set()\n }\n}\n\nfunction saveIgnoredUpdates(ignored: Set<string>): void {\n try {\n storage()?.setItem(IGNORE_KEY, JSON.stringify([...ignored]))\n } catch {\n /* storage full / unavailable:仅保留内存态 */\n }\n}\n\n/** 忽略某插件本次更新(repo+version 持久化入忽略集):本次版本不再提醒,直到下一个新版本发布。 */\nexport function ignoreUpdate(repo: string, version?: string): Set<string> {\n const next = loadIgnoredUpdates()\n next.add(`${repo}@${version ?? ''}`)\n saveIgnoredUpdates(next)\n return next\n}\n\n/** 移除某插件某版本的更新提醒记录(忽略本次更新时一并清理通知),返回更新后的列表。 */\nexport function removeUpdateNotice(repo: string, version?: string): NotificationRecord[] {\n const next = loadNotifications().filter((r) =>\n !(r.kind === 'update' && r.repo === repo && (r.version ?? undefined) === (version ?? undefined)))\n save(next)\n return next\n}\n\n/** 清空全部通知记录,返回空列表。 */\nexport function clearNotifications(): NotificationRecord[] {\n save([])\n return []\n}\n\n/** 按 id 删除单条通知记录,返回更新后的列表(仅移除该条,不影响其余记录)。 */\nexport function removeNotification(id: number): NotificationRecord[] {\n const next = loadNotifications().filter((r) => r.id !== id)\n save(next)\n return next\n}\n\nexport type FailureKind = 'npmTooOld' | 'pnpmIgnoredBuild' | 'pluginPrepare' | 'repo'\n\n/**\n * 失败归类,四态。无论底层机制如何(pnpm 白名单拦截 / 构建脚本被忽略 / prepare 失败),\n * 对用户而言结果都一样 —— 当前安装通道(npm 或 git)装不上,就是插件分发/依赖的问题,\n * 一律引导提 Issue;唯一例外是本机 npm 自身版本过低导致的内部崩溃(见 npmTooOld):\n * - npmTooOld:失败输出含 npm arborist 的 `edgesOut` 崩溃特征(build-ideal-tree.js 解 peer 依赖时\n * 内部抛错,npm 11.6.0 前必现的已知缺陷,npm/cli#8261、#9787),或服务端已核实本机版本低于\n * 阈值并打了 `[npm-too-low]` 标记 —— 是本机 npm 版本过低/自身缺陷,不是插件问题 → 引导升级 npm\n * - pnpmIgnoredBuild:插件依赖里的原生模块构建脚本被 pnpm 默认拦截(如 node-pty,\n * `ERR_PNPM_IGNORED_BUILDS`)。只影响带原生模块的插件,其他插件不受影响 —— 差异在\n * 插件的依赖选择,属插件依赖/打包问题 → 引导去仓库提 Issue(建议改用预编译版本)\n * - pluginPrepare:插件的 prepare/构建脚本实际执行失败(git tarball 常因缺失子模块或\n * 构建产物导致)—— 属插件打包/分发问题,应引导去仓库提 Issue\n * - repo:其余失败(含 git prepare 被 pnpm 白名单拦截等),默认按插件仓库问题引导提 Issue\n */\nexport function classifyFailure(message: string): FailureKind {\n // npm 内部崩溃(edgesOut)或服务端 [npm-too-low] 标记:是本机 npm 版本过低/自身缺陷,\n // 不是插件问题 —— 必须最先判,否则该报错会被外层 ERR_PNPM_PREPARE_PACKAGE 吞成\n // 「插件打包分发问题」,误导用户去提 Issue\n if (/\\[npm-too-low\\]|edgesOut/i.test(message)) return 'npmTooOld'\n // 装后校验拦截(服务端 verifyInstalledEntry 标记):入口文件缺失 = git 分发缺构建产物,\n // 与 pluginPrepare 同类(插件打包/分发问题),引导去仓库提 Issue\n if (/\\[packaging\\]|entry file missing/i.test(message)) return 'pluginPrepare'\n // 原生模块构建被忽略(IGNORED_BUILDS)要在 prepare 判定之前:dsh 尾部固定提示语带\n // allowBuilds/pnpm-workspace.yaml,不能据此把插件自身问题误判成通用失败\n if (/ERR_PNPM_IGNORED_BUILDS|Ignored build scripts:/i.test(message)) return 'pnpmIgnoredBuild'\n // 再判 prepare 实际执行失败:只有构建脚本真的跑挂了才是插件问题\n if (/ERR_PNPM_PREPARE_PACKAGE|ELIFECYCLE|Command failed|prepare-guard/i.test(message)) return 'pluginPrepare'\n // 其余失败(含 git prepare 被 pnpm 白名单拦截):当前通道装不上 = 插件分发/依赖的问题,一律提 Issue\n return 'repo'\n}\n\n/** 从服务端 `[npm-too-low]` 标记行提取本机 npm 版本(如 `[npm-too-low] npm@11.3.0` → \"11.3.0\");\n * 历史记录无标记时返回 null,前端据此决定提示文案是否带具体版本。 */\nexport function npmTooLowVersion(message: string): string | null {\n const m = message.match(/\\[npm-too-low\\]\\s*npm@(\\d+\\.\\d+\\.\\d+)/i)\n return m ? m[1] : null\n}\n\n/** 核心行特征:错误代码 / 生命周期脚本失败 / prepare 失败 / 描述性报错(子模块缺失、找不到等)/ 退出与宿主提示信息。 */\nconst CORE_LINE_RE = /ERR_[A-Z_]+|ELIFECYCLE|Command failed|prepare-guard|Failed to prepare|exit code|\\bprepare\\b|pnpm failed in profile|git-hosted plugins build|submodule|not found|cannot find|no such|unable to|fatal|missing|error/i\n/** 提交 issue 时正文里错误摘要的上限字符数。GitHub 请求行上限 8192 字节,\n * 固定模板与 URL 编码开销约 1~2K,核心错误(以 ASCII 日志为主)可安全带到 ~5K;\n * 仍超长时 pluginIssueUrl 会逐档缩小核心预算,最终 URL 不会超限。 */\nexport const MAX_CORE_CHARS = 5000\n/** 摘要里单行上限:允许构建 key 等长行也被截短。 */\nconst MAX_LINE_CHARS = 400\n\n/**\n * 核心错误收集器:从完整安装输出里挑出真正说明问题的行(错误代码、构建脚本失败、\n * 退出与宿主提示),去重后拼接,单行与总量都截断 —— 只把「重点 + 原因」带进 issue 正文,\n * 避免完整日志塞进 URL 导致请求过长。无关键行时退化为「头部 + 尾部」快照。\n * maxChars 可由调用方按最终 URL 长度收紧(pluginIssueUrl 超限时逐档缩小)。\n */\nexport function summarizeError(message: string, maxChars: number = MAX_CORE_CHARS): string {\n const seen = new Set<string>()\n const core: string[] = []\n for (const raw of message.split(/\\r?\\n/)) {\n const line = raw.trim()\n if (!line || !CORE_LINE_RE.test(line)) continue\n const short = line.length > MAX_LINE_CHARS ? `${line.slice(0, MAX_LINE_CHARS)}…` : line\n if (!seen.has(short)) {\n seen.add(short)\n core.push(short)\n }\n }\n let out: string\n if (core.length === 0) {\n // 无关键行时退化为「头部 + 尾部」快照:优先保尾部完整,头部按预算压缩,总长不超上限\n const tail = message.trimEnd().slice(-1000)\n const sep = '\\n…\\n'\n const headBudget = Math.max(maxChars - tail.length - sep.length, 0)\n const head = message.slice(0, 500).trim()\n out = `${head.length > headBudget ? head.slice(0, headBudget) : head}${sep}${tail}`\n } else {\n out = core.join('\\n')\n }\n return out.length > maxChars ? `${out.slice(0, maxChars)}\\n… (truncated)` : out\n}\n\n/** 提取首个错误代码(如 ERR_PNPM_PREPARE_PACKAGE),无则 null。 */\nexport function coreErrorCode(message: string): string | null {\n const m = message.match(/\\[?ERR_[A-Z_]+\\]?/)\n return m ? m[0].replace(/^\\[|\\]$/g, '') : null\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * URL builders: catalog detail pages, plugin site links and the pre-filled\n * GitHub issue URL used by the failure modal. Pure functions — the issue\n * URL stays within GitHub's 8192-byte request limit.\n */\nimport type { EnvInfo, HubPlugin, LocaleId } from '../types.ts'\nimport { GITHUB_URL, PLUGIN_VERSION, SITE_URL } from './constants.ts'\nimport { MAX_CORE_CHARS, classifyFailure, coreErrorCode, summarizeError } from './failures.ts'\n\n/** dsh-plugin.org 中文页挂在 /zh/ 前缀下,英文在根路径。 */\nexport function langPathOf(lang: LocaleId): string {\n return lang === 'zh' ? 'zh/' : ''\n}\n\n/**\n * 官网详情页两级路径:/plugins/{ownerSlug}/{slug};\n * 缺 ownerSlug 时从 repo 推导(卡片详情按钮与弹窗来源行共用)。\n */\nexport function pluginDetailUrl(plugin: HubPlugin, langPath: string): string {\n const repo = plugin.source?.repo ?? ''\n return `${SITE_URL}${langPath}plugins/${plugin.ownerSlug ?? repo.split('/')[0]?.toLowerCase() ?? ''}/${plugin.slug}`\n}\n\n/**\n * 失败弹窗里仓库地址的跳转目标:官网详情页(含插件收录信息),\n * 与 issue 正文的 Catalog 链接同一形式(单级 /plugins/{repo})。\n */\nexport function pluginSiteUrl(repo: string): string {\n return `${SITE_URL}plugins/${repo}`\n}\n\n/**\n * 一键反馈 GitHub Issue 的预填链接:标题带「来自 dsh-plugin.org」标识,正文只带\n * 核心信息 —— 原因判定 + 关键错误代码 + 尝试过的安装方式 + 宿主机器环境快照 +\n * 错误核心摘要(完整日志太长,塞进 URL 会被 GitHub 以「request URL too long」拒绝,\n * 故只收集重点)。错误弹窗、失败记录共用此逻辑。\n * env 取不到时为 null,链接照常生成、只是少环境段。\n * attempts(尝试过的安装方式,npm 反查 + 实际执行命令):作者看到我们查过/试过的命令,\n * 组织 scope 与 GitHub 用户名不一致时也能直接指认正确的 npm 包名。\n */\nexport function pluginIssueUrl(repo: string, message: string, env?: EnvInfo | null, command?: string, attempts?: string[]): string {\n const title = `[dsh-plugin.org | dsh-plugin-hub] Install/Remove failed: ${repo}`\n // 原因判定:按失败类型归类,便于作者判断问题是否出在插件侧。\n // [packaging](预检/装后校验拦截)单独列:无论走 npm 还是 git 通道,都是分发物不完整\n // (package.json 声明的入口文件在发布物里缺失),作者照此补齐即可。\n const kind = classifyFailure(message)\n const reason = /\\[packaging\\]/i.test(message)\n ? 'plugin distribution is incomplete — the entry file declared in package.json is missing from the published package (github tarball or npm package); please commit build output or publish a complete package'\n : kind === 'pluginPrepare'\n ? 'plugin prepare/build script failed during install (packaging/distribution issue)'\n : kind === 'pnpmIgnoredBuild'\n ? 'plugin depends on a native module whose build script pnpm blocks by default (use a prebuilt variant)'\n : 'plugin-side install failure'\n const code = coreErrorCode(message)\n // 按给定核心摘要预算构建完整预填 URL(含 URL 编码);预算可调,供超长时逐档缩小\n const build = (coreChars: number): string => {\n const body = [\n '## Summary',\n `- Cause: ${reason}`,\n ...(code ? [`- Key error: \\`${code}\\``] : []),\n '',\n // 来源说明:标题(链官网)+ 一句来源(链仓库)+ 实际执行的安装命令(含 --profile)与执行结果,链接由常量动态拼接\n `## [DSH Plugin 插件中心](${SITE_URL}) · 安装 Plugin 失败错误信息`,\n `本错误信息由 [dsh-plugin-hub](${GITHUB_URL}) 插件中心的安装程序自动生成,随本次安装失败一并提交。`,\n `- 实际执行的安装命令:\\`${command ?? `dsh plugin${env?.profile ? ` --profile ${env.profile}` : ''} add git+https://github.com/${repo}.git`}\\``,\n `- 执行结果:安装失败,未能安装该插件。`,\n // 尝试过的安装方式(npm 反查 + 实际执行命令,按先后顺序):作者据此反推正确的\n // npm 包名 —— 组织 scope 与 GitHub 用户名不一致时仅凭仓库名猜不到,作者看到我们\n // 查过/试过的命令就能直接指认\n ...(attempts && attempts.length > 0\n ? ['', '## Attempted install channels(已尝试的安装方式)', ...attempts.map((a) => `- ${a}`)]\n : []),\n // [packaging] 场景:说明两种官方安装通道(npm 包 / git 直装),当前插件在对应通道下分发不完整\n ...(/\\[packaging\\]/i.test(message)\n ? [\n '',\n '## 安装方式说明',\n 'DSH 插件支持两种官方安装通道:`dsh plugin add <npm-package>`(npm 分发,需发布完整构建产物)与 `dsh plugin add git+https://github.com/owner/repo.git`(Git 直装,仓库需提交构建产物或在 package.json 提供 `prepare` 脚本)。当前插件的分发物缺少 package.json 声明的入口文件,请按所用通道补齐后重新发布。',\n ]\n : []),\n '',\n '## Environment',\n `- Plugin: \\`${repo}\\``,\n // 宿主机器环境快照:便于作者本地复现;某字段缺失时如实写 unknown,不编造\n ...(env\n ? [\n `- DSH: ${env.dshVersion ? `v${env.dshVersion}` : 'unknown'}`,\n `- Plugin Hub: v${PLUGIN_VERSION}`,\n `- Node: ${env.nodeVersion}`,\n `- OS: ${env.platform} ${env.arch} (${env.release})`,\n `- Profile: \\`${env.profile}\\``,\n `- DSH Home: \\`${env.dshHome}\\``,\n ]\n : []),\n // 该插件在插件中心的收录位置(详情页链接)\n `- Catalog: [${pluginSiteUrl(repo)}](${pluginSiteUrl(repo)})`,\n '',\n '## Error (core)',\n '',\n '```',\n // 核心错误收集器:只挑关键行(错误代码/构建失败/退出信息),去重截断,URL 才不至于超长\n summarizeError(message, coreChars),\n '```',\n '',\n '---',\n // 底部署名:报错来自内置在 DeepSeek Harness 里的 dsh-plugin-hub 安装程序\n `This error was produced by the [dsh-plugin-hub](${GITHUB_URL}) installer bundled with DeepSeek Harness.`,\n ].join('\\n')\n return `https://github.com/${repo}/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`\n }\n // GitHub 请求行上限 8192 字节:先用宽松预算(最多 ~5K 核心错误)构建,超长再逐档缩小,保证最终 URL 不超限\n const MAX_URL_CHARS = 7600\n let url = build(MAX_CORE_CHARS)\n if (url.length > MAX_URL_CHARS) {\n for (const budget of [4000, 2500, 1400, 800, 400]) {\n url = build(budget)\n if (url.length <= MAX_URL_CHARS) break\n }\n }\n return url\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Language state for the section: follows the host (system) locale by\n * default, with an optional manual toggle that wins until the user changes\n * it back. Exposes the localized dictionary lookup `t()` plus the zh/en\n * language flag and the /zh/ URL path prefix.\n */\nimport { useState } from 'react'\nimport type { LocaleId, SectionProps } from '../types.ts'\nimport { en, zh } from '../locales.ts'\nimport { langPathOf } from '../logic/urls.ts'\n\nexport function useLanguage(locale: SectionProps['locale']) {\n /** 界面语言:默认跟随宿主(系统)语言;右上角按钮可手动切换,切换后以手动选择为准 */\n const [manualLang, setManualLang] = useState<LocaleId | null>(null)\n const lang: LocaleId = manualLang ?? locale.getSnapshot().active\n const langKey: LocaleId = lang === 'en' ? 'en' : 'zh'\n // dsh-plugin.org keeps zh pages under the /zh/ prefix; en is the root.\n const langPath = langPathOf(lang)\n\n // 界面语言跟随宿主(系统)locale 自动切换;宿主的 t() 绑定宿主 locale,\n // 这里基于本地字典自建翻译函数,与宿主 locale 保持一致。\n // (settings.section 的导航 label 仍在 apply 里用宿主 t(),跟随宿主语言。)\n const dict: Record<string, string> = langKey === 'en' ? en : zh\n const t = (key: string, params?: Record<string, string | number>): string => {\n const raw = dict[key] ?? key\n return params ? raw.replace(/\\{(\\w+)\\}/g, (_, k) => String(params[k] ?? '')) : raw\n }\n\n return {\n lang,\n langKey,\n langPath,\n t,\n toggleLang: () => setManualLang(lang === 'en' ? 'zh' : 'en'),\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Hub settings state: loaded once from the host's local /settings route\n * (persisted at ~/.dsh/profiles/<profile>/hub-settings.json), updated\n * optimistically. Every change POSTs the patch immediately so a toggled\n * switch survives a reload; a host without the server routes falls back to\n * the defaults and keeps working (settings simply do not persist).\n */\nimport { useCallback, useEffect, useState } from 'react'\n\nexport interface HubSettings {\n /** 启动时检查目录插件更新,发现可更新时在通知中心提示(安装不自动进行) */\n checkUpdatesOnStart: boolean\n /** npm 镜像源 registry 地址(空串 = 官方 https://registry.npmjs.org) */\n npmRegistry: string\n /** HTTP(S) 代理地址,用于 npm / git / 目录请求(空串 = 直连) */\n proxy: string\n /** 启用命令行安装 NPM 包(默认开) */\n enableNpmInstall: boolean\n /** 启用命令行安装 GitHub 源码(默认开) */\n enableGitInstall: boolean\n /** 启用命令行粘贴 dsh plugin 命令安装(默认开) */\n enableDshInstall: boolean\n /** 日志存放位置覆盖(空串 = 默认 ~/.dsh/profiles/<profile>/hub.log) */\n logPath: string\n}\n\nexport const DEFAULT_SETTINGS: HubSettings = {\n checkUpdatesOnStart: true,\n npmRegistry: '',\n proxy: '',\n enableNpmInstall: true,\n enableGitInstall: true,\n enableDshInstall: true,\n logPath: '',\n}\n\nasync function loadRemote(): Promise<HubSettings> {\n try {\n const res = await fetch('/dsh-plugin-hub/settings', { cache: 'no-store' })\n if (!res.ok) throw new Error(`settings ${res.status}`)\n const data = await res.json() as Partial<HubSettings>\n return { ...DEFAULT_SETTINGS, ...data }\n } catch {\n return DEFAULT_SETTINGS\n }\n}\n\nexport function useSettings() {\n const [settings, setSettings] = useState<HubSettings>(DEFAULT_SETTINGS)\n /** 服务端配置是否已加载:更新策略等启动期逻辑须等真实值,避免用默认值误触发 */\n const [ready, setReady] = useState(false)\n\n useEffect(() => {\n let alive = true\n void loadRemote().then((s) => {\n if (!alive) return\n setSettings(s)\n setReady(true)\n })\n return () => { alive = false }\n }, [])\n\n /** 部分更新:本地立即生效(乐观),同时 POST 持久化;持久化失败静默(本次会话仍生效)。 */\n const update = useCallback((patch: Partial<HubSettings>) => {\n setSettings((prev) => ({ ...prev, ...patch }))\n void fetch('/dsh-plugin-hub/settings', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(patch),\n cache: 'no-store',\n }).catch(() => { /* 宿主未挂路由:仅本次会话生效 */ })\n }, [])\n\n /** 重置为默认设置:本地立即回默认,同时通知服务端删除设置文件;失败静默。 */\n const reset = useCallback(() => {\n setSettings({ ...DEFAULT_SETTINGS })\n void fetch('/dsh-plugin-hub/settings/reset', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: '{}',\n cache: 'no-store',\n }).catch(() => { /* 宿主未挂路由:仅本次会话回默认 */ })\n }, [])\n\n return { settings, ready, update, reset }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Background install/remove task queue for the Plugin Hub.\n *\n * Mirrors the server-side FIFO active queue by polling /active, settles\n * vanished tasks against /status, and exposes the queue actions (install,\n * uninstall, cancel) plus the modal task lookups used by the dialogs.\n */\nimport { useEffect, useRef, useState } from 'react'\nimport type { HubPlugin, Translate } from '../types.ts'\nimport { installCommandOf, installTargetOf, repoFromInstallTarget } from '../logic/install-command.ts'\nimport type { InstalledItem } from '../logic/installed.ts'\n\n/** 安装/卸载请求超时(ms):服务端 preflight + npm 反查可能耗时(各自都有超时,合计约 20~30s),\n * 给足余量;超时主动中止,避免服务端 preflight 网络挂起时前端永久卡「安装中 0%」。 */\nconst REQUEST_TIMEOUT_MS = 60_000\n\n/** 客户端任务队列项:镜像服务端 active 任务(running 在前、pending 在后)。 */\nexport interface QueueTask {\n id: number\n kind: 'install' | 'uninstall'\n /** 展示目标:owner/repo(安装)或 npm 包名(卸载) */\n target: string\n /** 插件中文简介(入队时从插件数据带过来,轮询合并时保留):展示在仓库名下方,标识排队中的插件 */\n desc?: string\n /** 所属插件仓库(owner/repo):失败时错误弹窗据此提供「去仓库反馈」入口;卸载为 null */\n repo: string | null\n /** 安装时的目录信号快照(版本 + 仓库更新时间):任务成功后在本地记录,供「有更新」比对 */\n version?: string\n updatedAt?: string\n /** pending 排队中 / running 执行中 / cancelling 取消中(客户端乐观过渡态) */\n status: 'pending' | 'running' | 'cancelling'\n progress: number\n lines: string[]\n /** 乐观入队条目:点击安装后立即显示「正在安装中」,等 POST 响应回来再换成真实任务 id。\n * 服务端还没登记(preflight 中),轮询合并/消失检测都必须跳过,避免被当作已结束任务收尾。 */\n optimistic?: boolean\n /** 实际执行的安装命令(npm/git 通道随插件数据决定):失败时 issue 预填如实展示 */\n command?: string\n /** 尝试过的安装方式(npm registry 反查 + 实际执行命令,按先后顺序):失败时 issue 预填一并贴给作者 */\n attempts?: string[]\n /** 完成结果是否需要重启才生效(服务端任务终态带出;默认 true 保持老行为:弹窗给重启选项)。\n * 卸载时 loader 已即时移除 → false,结果视图只显示「完成」;true 时弹窗给「稍后重启/立即重启」,\n * 通知中心待重启条目(服务端登记)同步常驻,直到用户点「立即重启」。 */\n needsRestart: boolean\n}\n\n/** 客户端待重启项:镜像服务端内存列表 + 本地补齐的展示信息(简介/版本)。 */\nexport interface PendingRestart {\n /** owner/repo(展示用,已从安装目标归一化) */\n target: string\n /** 待重启语义:install 装完等挂载 / uninstall 卸完等清理 */\n kind: 'install' | 'uninstall'\n at: number\n desc?: string\n version?: string\n}\n\nexport interface TaskQueueOptions {\n t: Translate\n refreshInstalled: () => void\n /** 任务成功完成:viaModal 表示任务对应当前打开弹窗(弹窗切结果视图),否则走 Toast;repo 供成功通知记录;\n * needsRestart 表示该任务完成后是否仍需宿主重启(结果视图据此给「重启 / 仅完成」)。 */\n onInstallDone: (viaModal: boolean, repo: string | null, needsRestart: boolean) => void\n onUninstallDone: (viaModal: boolean, repo: string | null, needsRestart: boolean) => void\n /** 任务失败:完整输出或兜底文案 + 所属插件仓库 + 操作类型(安装/卸载)+ 实际执行的安装命令(issue 预填用,可缺省)+ 尝试过的安装方式(npm 反查/执行命令,可缺省)。 */\n onError: (message: string, repo: string | null, kind: 'install' | 'uninstall', command?: string, attempts?: string[]) => void\n /** 当前打开的安装/卸载弹窗插件:用于在弹窗内匹配进行中的任务。 */\n installPlugin: HubPlugin | null\n /** 当前打开的自定义安装(命令行)确认弹窗目标:与应用商店同一弹窗机制,匹配进行中的 custom 安装任务。 */\n installCustomTarget?: string | null\n /** 当前打开的全局 npm 安装(`npm install -g <pkgs>`)确认弹窗身份(包列表空格拼接):\n * 匹配服务端登记的全局安装任务(target = 包列表 join(' '))。 */\n installGlobalTarget?: string | null\n uninstallPlugin: HubPlugin | null\n /** 已安装视图发起的卸载目标(npm 包名):目录插件走 uninstallPlugin,自定义安装走包名直卸。 */\n uninstallName: string | null\n installedName: (p: HubPlugin) => string | null\n /** 待重启项展示信息补齐:按 owner/repo 从插件目录解析简介/版本;找不到返回 null。 */\n resolvePending: (repo: string) => { desc?: string; version?: string } | null\n}\n\nexport function useTaskQueue(opts: TaskQueueOptions) {\n const {\n t, refreshInstalled, onInstallDone, onUninstallDone, onError,\n installPlugin, installCustomTarget, installGlobalTarget, uninstallPlugin, uninstallName, installedName, resolvePending,\n } = opts\n const [queue, setQueue] = useState<QueueTask[]>([])\n const queueRef = useRef<QueueTask[]>([])\n /** 待重启列表(服务端内存态 + 本地展示信息补齐);与 queue 一样以 ref 为唯一事实来源。 */\n const [pendingRestarts, setPendingRestarts] = useState<PendingRestart[]>([])\n const pendingRef = useRef<PendingRestart[]>([])\n /** 本次会话内安装成功插件的展示信息(目标 → 简介/版本):轮询合并待重启列表时补齐,刷新后由 resolvePending 兜底。 */\n const pendingInfoRef = useRef<Map<string, { desc?: string; version?: string }>>(new Map())\n /** 保持最新的 resolvePending:轮询闭包捕获的是调用那一刻的目录状态,目录晚加载时也能补齐。 */\n const resolvePendingRef = useRef(resolvePending)\n resolvePendingRef.current = resolvePending\n /** 当前打开弹窗所对应的任务 id:该任务完成时弹窗切换为结果视图 */\n const modalTaskRef = useRef<number | null>(null)\n /** 已开始收尾但尚未结束的任务 id(服务端 /active 已消失 → 查 /status 中):并发轮询时跳过,避免重复收尾 */\n const settlingRef = useRef<Set<number>>(new Set())\n /** 轮询定时器句柄(队列清空/组件卸载时清理) */\n const pollRef = useRef<number | null>(null)\n /** 请求在途的目标集合(同步防重):双击安装/卸载时第二击直接忽略。\n * 本地队列任务要等 fetch 返回后才入队,仅靠 queueRef 检查拦不住请求窗口内的重复点击。 */\n const submittingRef = useRef<Set<string>>(new Set())\n /** 乐观入队临时 id 计数器:递减产生唯一负数,与服务端自增正数 id 永不冲突。 */\n const tempIdRef = useRef(0)\n /** 请求在途标记:弹窗据此禁用确认按钮,避免等待响应期间被再次点击。 */\n const [submitting, setSubmitting] = useState(false)\n\n /** 停止后台任务轮询(任务结束或组件卸载时清理)。 */\n const stopPoll = () => {\n if (pollRef.current !== null) {\n window.clearInterval(pollRef.current)\n pollRef.current = null\n }\n }\n\n /** 队列与待重启都清空才停轮询:待重启期间持续轮询,宿主一重启(内存列表清空)立刻感知并消失。 */\n const maybeStopPoll = () => {\n if (queueRef.current.length === 0 && pendingRef.current.length === 0) stopPoll()\n }\n\n // 组件卸载时兜底清理轮询定时器\n useEffect(() => stopPoll, [])\n\n /** 更新队列(同步镜像到 ref:queueRef 是唯一事实来源,state 只负责触发渲染,\n * 避免依赖 React updater 的异步调度时序导致 gone/stopPoll/防重复入队读到旧值)。 */\n const applyQueue = (updater: (prev: QueueTask[]) => QueueTask[]) => {\n const next = updater(queueRef.current)\n queueRef.current = next\n setQueue(next)\n }\n\n /** 解析服务端待重启列表(安装目标归一化为 owner/repo,与安装任务对齐)。 */\n const parsePendingRestarts = (value: unknown): PendingRestart[] => {\n if (!Array.isArray(value)) return []\n const out: PendingRestart[] = []\n for (const x of value) {\n if (typeof x !== 'object' || x === null) continue\n const target = (x as { target?: unknown }).target\n if (typeof target !== 'string' || target === '') continue\n const at = (x as { at?: unknown }).at\n out.push({\n target: repoFromInstallTarget(target),\n kind: (x as { kind?: unknown }).kind === 'uninstall' ? 'uninstall' : 'install',\n at: typeof at === 'number' ? at : 0,\n })\n }\n return out\n }\n\n /** 合并服务端待重启列表:保留已有展示信息,缺失时用会话内记录 / 目录解析补齐。 */\n const applyPending = (raw: PendingRestart[]) => {\n const prev = pendingRef.current\n const next = raw.map((p) => {\n const old = prev.find((q) => q.target === p.target)\n if (old?.desc !== undefined) return { ...p, desc: old.desc, version: old.version }\n const info = pendingInfoRef.current.get(p.target) ?? resolvePendingRef.current?.(p.target) ?? null\n return info ? { ...p, desc: info.desc, version: info.version } : p\n })\n pendingRef.current = next\n setPendingRestarts(next)\n }\n\n /** 向宿主记录某插件的安装时目录信号(version + updatedAt);version 为空时清除记录(卸载)。 */\n const syncInstalledVersion = async (repo: string | null, version: string | undefined, updatedAt: string | undefined) => {\n if (!repo) return\n try {\n await fetch('/dsh-plugin-hub/installed-version', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo, version: version ?? null, updatedAt }),\n })\n } catch {\n // 宿主未挂本地路由:静默忽略,仅本机展示受影响\n }\n }\n\n /** 后台任务结束(active 中消失后查终态确认):完成 → 刷新安装表 + 结果视图/toast;失败 → 完整错误弹窗 */\n const finishQueueTask = (ok: boolean, q: QueueTask, lines: string[]) => {\n applyQueue((prev) => prev.filter((x) => x.id !== q.id))\n if (ok) {\n refreshInstalled()\n if (q.kind === 'uninstall') {\n // 卸载成功:清掉本地版本记录\n void syncInstalledVersion(q.repo, undefined, undefined)\n onUninstallDone(modalTaskRef.current === q.id, q.repo, q.needsRestart)\n } else {\n // 安装成功:记录安装时的目录信号(版本 + 仓库更新时间),供「有更新」比对;\n // 同时缓存展示信息,待重启列表(服务端已登记)合并时直接补齐简介/版本\n void syncInstalledVersion(q.repo, q.version, q.updatedAt)\n pendingInfoRef.current.set(q.target, { desc: q.desc, version: q.version })\n onInstallDone(modalTaskRef.current === q.id, q.repo, q.needsRestart)\n }\n } else {\n // 失败:完整展示全部输出行(最新在前,逆序为日志阅读顺序),不裁剪\n const detail = lines.length > 0\n ? [...lines].reverse().join('\\n')\n : q.kind === 'uninstall' ? t('uninstallFail') : t('installFail')\n onError(detail, q.repo, q.kind, q.command, q.attempts)\n }\n maybeStopPoll()\n }\n\n /** 卸载成功收尾前的进度过渡:任务已在服务端结束,但保留本地展示,\n * 让进度条在 ~2.4s 内缓缓跑到 100% 再切结果/Toast,给用户一个交互过程,\n * 而不是命令一执行进度条就一闪消失。 */\n const settleDone = (q: QueueTask, lines: string[]) => {\n // 收尾动画期间停止轮询:任务已从服务端 /active 消失,无需再查;\n // 停掉可避免 pollQueue 的 gone 检测把它当「再消失一次」而重复收尾\n stopPoll()\n const from = Math.min(q.progress, 90) // 起点最多 90,给进度条留出跑满的缓冲空间\n const steps = 20\n const stepMs = 120 // 20 步 × 120ms = 2.4s\n let step = 0\n // 动画期间固定显示「卸载中」:任务实已结束,但进度在跑,与「排队中」文案更协调\n applyQueue((prev) => prev.map((x) => (x.id === q.id ? { ...x, status: 'running' as const } : x)))\n const timer = window.setInterval(() => {\n step += 1\n const progress = Math.round(from + (100 - from) * (step / steps))\n applyQueue((prev) => prev.map((x) => (x.id === q.id ? { ...x, progress } : x)))\n if (step >= steps) {\n window.clearInterval(timer)\n finishQueueTask(true, q, lines)\n // 队列若还有其它已在排队/执行的任务,恢复轮询继续盯;已清空则自然停住\n if (queueRef.current.length > 0) pollQueue()\n }\n }, stepMs)\n }\n\n /** 任务在 /active 中消失 = 已结束:查 /status 拿终态并收尾(cancelled 静默移除)。 */\n const settleTask = async (q: QueueTask) => {\n let status = 'failed'\n let lines: string[] = []\n let attempts: string[] | undefined\n try {\n const res = await fetch(`/dsh-plugin-hub/status?task=${q.id}`, { cache: 'no-store' })\n if (res.ok) {\n const data = await res.json() as { task?: { status?: string; lines?: string[]; attempts?: string[]; needsRestart?: unknown } }\n const task = data.task\n if (task !== undefined) {\n status = task.status ?? 'failed'\n lines = task.lines ?? []\n attempts = Array.isArray(task.attempts) ? task.attempts : undefined\n // 终态带出的「是否需要重启」覆盖本地(服务端 done 时按 loader 即时移除情况设置)\n const needsRestart = typeof task.needsRestart === 'boolean' ? task.needsRestart : q.needsRestart\n if (status === 'done') {\n const settled = { ...q, needsRestart }\n // 卸载成功走进度过渡动画;安装成功直接收尾\n if (q.kind === 'uninstall') settleDone(settled, lines)\n else finishQueueTask(true, settled, lines)\n return\n }\n if (status === 'failed') {\n // 服务端终态带出的尝试记录覆盖本地:以实际执行为准\n finishQueueTask(false, { ...q, attempts }, lines)\n return\n }\n }\n }\n } catch { /* 服务端不可达:按失败处理 */ }\n applyQueue((prev) => prev.filter((x) => x.id !== q.id)) // cancelled / 未知\n maybeStopPoll()\n }\n\n /** 轮询整个队列:合并服务端 /active(running 在前、pending 在后),\n * 消失的任务查终态收尾;队列清空即停止轮询。 */\n const pollQueue = () => {\n stopPoll()\n pollRef.current = window.setInterval(async () => {\n try {\n const res = await fetch('/dsh-plugin-hub/active', { cache: 'no-store' })\n if (!res.ok) throw new Error(`active ${res.status}`)\n const data = await res.json() as {\n tasks?: { id?: unknown; action?: unknown; target?: unknown; status?: unknown; progress?: unknown; lines?: unknown; attempts?: unknown; needsRestart?: unknown }[]\n pendingRestarts?: unknown\n }\n const active = (data.tasks ?? []).filter((a) => typeof a.id === 'number')\n const byId = new Map(active.map((a) => [a.id as number, a]))\n // 先捕获旧队列:gone 是「旧队列里服务端已消失的任务」的差集,必须在 applyQueue 更新前取\n const prevQueue = queueRef.current\n // 待重启列表同步(服务端内存态:宿主重启后自然变空,这里随之清空 UI)\n applyPending(parsePendingRestarts(data.pendingRestarts))\n // 合并:running 在前、pending 在后(与服务端一致),新出现任务补入队列\n applyQueue((prev) => {\n const next: QueueTask[] = []\n for (const a of active) {\n const id = a.id as number\n const prevTask = prev.find((q) => q.id === id)\n const isRemove = a.action === 'remove'\n next.push({\n id,\n kind: isRemove ? 'uninstall' : 'install',\n target: typeof a.target === 'string' ? repoFromInstallTarget(a.target) : (prevTask?.target ?? ''),\n desc: prevTask?.desc,\n repo: prevTask?.repo ?? (isRemove ? null : (typeof a.target === 'string' ? repoFromInstallTarget(a.target) : null)),\n // 安装时快照的目录信号:轮询合并时保留,任务成功后记录到本地\n version: prevTask?.version,\n updatedAt: prevTask?.updatedAt,\n status: a.status === 'running' ? 'running' : 'pending',\n progress: typeof a.progress === 'number' ? a.progress : prevTask?.progress ?? 0,\n lines: Array.isArray(a.lines) ? (a.lines as string[]) : (prevTask?.lines ?? []),\n attempts: Array.isArray(a.attempts) ? (a.attempts as string[]) : (prevTask?.attempts ?? []),\n needsRestart: typeof a.needsRestart === 'boolean' ? a.needsRestart : (prevTask?.needsRestart ?? true),\n })\n }\n // 保留乐观条目:服务端尚未登记(preflight 中),无真实 id,不能因 active 缺它就被合并吞掉\n const keepOpt = prev.filter((q) => q.optimistic && !next.some((x) => x.id === q.id))\n if (keepOpt.length > 0) next.push(...keepOpt)\n // 保留「已从服务端消失、但尚未收尾」的任务:收尾(settleTask)负责移除。\n // 若在这里提前摘除,卸载/安装完成的那一瞬队列会先变空,弹窗闪回「确认」态\n // (busy=false 且未 done),表现为「卸载中 → 卸载 → 卸载完成」的中间回退。\n const keepGone = prev.filter((q) =>\n !byId.has(q.id) && !next.some((x) => x.id === q.id) && q.status !== 'cancelling' && !q.optimistic)\n if (keepGone.length > 0) next.push(...keepGone)\n return next\n })\n // 本地有、服务端已消失 → 已结束:逐个查终态收尾\n // (cancelling 是客户端乐观过渡态,交给 cancelTask 的定时移除,不在轮询里提前收敛;\n // optimistic 是点击后尚未登记的占位,服务端 /status 查不到,跳过免误判成失败;\n // settling 是上一轮已开始收尾的任务,并发轮询直接跳过,避免重复收尾)\n const gone = prevQueue.filter((q) =>\n !byId.has(q.id) && q.status !== 'cancelling' && !q.optimistic && !settlingRef.current.has(q.id))\n for (const q of gone) {\n // 防御:同 id 任务可能已被上一轮收尾移除(极端时序下轮询合并出的重复条目),跳过避免重复收尾\n if (!queueRef.current.some((x) => x.id === q.id)) continue\n settlingRef.current.add(q.id)\n try { await settleTask(q) } finally { settlingRef.current.delete(q.id) }\n }\n } catch {\n // 服务端暂不可达:静默等待下一轮\n }\n }, 600)\n }\n\n // 刷新后恢复任务队列与待重启列表:任务注册表在服务端内存里,只要宿主进程没重启就还在;\n // 重新拉取 /active(数组)继续轮询,界面上显示「进行中」状态条,可展开查看实时输出。\n useEffect(() => {\n let cancelled = false\n const restore = async () => {\n try {\n const res = await fetch('/dsh-plugin-hub/active', { cache: 'no-store' })\n if (!res.ok) return\n const data = await res.json() as {\n tasks?: { id?: unknown; action?: unknown; target?: unknown; status?: unknown; progress?: unknown; lines?: unknown; attempts?: unknown; needsRestart?: unknown }[]\n pendingRestarts?: unknown\n }\n if (cancelled) return\n // 待重启:装完没重启的持久提醒,刷新页面也要恢复\n applyPending(parsePendingRestarts(data.pendingRestarts))\n const items: QueueTask[] = (data.tasks ?? [])\n .filter((a) => typeof a.id === 'number')\n .map((a) => {\n const isRemove = a.action === 'remove'\n // 服务端任务的 target:显式 HTTPS Git URL(安装)/ npm 包名(npm 安装/卸载)。\n // 恢复展示统一用 displayTarget(owner/repo,服务端固定传):npm 安装时 target 是包名,\n // 直接展示会让用户看到「安装方式」的内部细节,违背无感知原则;卸载保持包名(匹配已装表)。\n const display = typeof (a as { displayTarget?: unknown }).displayTarget === 'string' ? repoFromInstallTarget((a as { displayTarget: string }).displayTarget) : ''\n const fallback = typeof a.target === 'string' ? repoFromInstallTarget(a.target) : ''\n return {\n id: a.id as number,\n kind: (isRemove ? 'uninstall' : 'install') as 'install' | 'uninstall',\n target: isRemove ? fallback : (display || fallback),\n repo: isRemove ? null : (display || fallback),\n status: a.status === 'running' ? 'running' : 'pending',\n progress: typeof a.progress === 'number' ? a.progress : 0,\n lines: Array.isArray(a.lines) ? (a.lines as string[]) : [],\n attempts: Array.isArray((a as { attempts?: unknown }).attempts) ? ((a as { attempts: string[] }).attempts) : [],\n needsRestart: typeof (a as { needsRestart?: unknown }).needsRestart === 'boolean' ? (a as { needsRestart: boolean }).needsRestart : true,\n }\n })\n if (items.length > 0 || pendingRef.current.length > 0) {\n applyQueue((prev) => [...prev, ...items.filter((n) => !prev.some((p) => p.id === n.id))])\n // 刷新后恢复的任务同样保持折叠:摘要条提示进行中,点开才看明细/日志\n pollQueue()\n }\n } catch { /* host without the plugin's server routes */ }\n }\n void restore()\n return () => { cancelled = true }\n }, [])\n\n /** 弹窗动作:直接安装。请求宿主本地路由,任务进入服务端队列(FIFO),弹窗内实时显示进度。 */\n /** 安装入队核心:目录插件(catalog,后端走目录白名单)与命令行安装(custom,\n * 受安全开关控制)共用。队列条目一律用仓库名(repo)展示/防重,只有发给后端的\n * 实际安装目标(target)随通道变化(npm 包名 / github: 源)。 */\n const submitInstall = async (input: {\n /** 发给后端的实际安装目标:npm 包名或 github: 源(服务端再决定最终通道) */\n target: string\n /** 队列展示与防重用的仓库名 */\n repo: string\n desc?: string\n version?: string\n updatedAt?: string\n command: string\n source: 'catalog' | 'custom'\n /** 更新已安装目标(放行 add 覆盖重装) */\n update?: boolean\n /** 全局 npm 安装包列表(`npm install -g <pkgs>`):非空时服务端执行全局安装,不进任何 profile */\n globalNpm?: string[]\n }) => {\n // 防重复入队:同一目标已在排队/执行中则忽略\n if (queueRef.current.some((q) => q.kind === 'install' && q.target === input.repo)) return\n // 请求在途防重:任务要等响应回来才进本地队列,这之前再次点击(双击)直接忽略\n if (submittingRef.current.has(input.repo)) return\n submittingRef.current.add(input.repo)\n // 乐观入队:点击安装立即显示「正在安装中」,不等 POST 响应。\n // 服务端 /install 会先跑预检(preflight,可能耗时数秒)再入队,若等响应才入队列,\n // 用户点完安装立刻去看任务会看不到 —— 只有刷新后 restore 才拉回来。\n // 用负临时 id 占位,响应回来换成真实 task id;失败/出错则移除该占位。\n tempIdRef.current -= 1\n const tempId = tempIdRef.current\n modalTaskRef.current = tempId\n applyQueue((prev) => [...prev, {\n id: tempId, kind: 'install', target: input.repo, repo: input.repo, desc: input.desc,\n version: input.version, updatedAt: input.updatedAt,\n status: 'running', progress: 0, lines: [], optimistic: true,\n command: input.command,\n // 服务端登记后 /active 会带回真实尝试记录(npm 反查 + 执行命令),先占位空列表\n attempts: [], needsRestart: true,\n }])\n setSubmitting(true)\n const controller = new AbortController()\n const timeout = window.setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS)\n try {\n const res = await fetch('/dsh-plugin-hub/install', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n repo: input.target,\n display: input.repo,\n source: input.source,\n mode: input.update ? 'update' : undefined,\n ...(input.globalNpm && input.globalNpm.length > 0 ? { globalNpm: input.globalNpm } : {}),\n }),\n signal: controller.signal,\n })\n const data = await res.json() as { ok?: boolean; task?: number; error?: string; attempts?: string[] }\n if (!data.ok || typeof data.task !== 'number') {\n // 请求层失败(重复安装 409 / 参数错误 / 安全开关 403 等):移除乐观条目 + 完整错误弹窗\n applyQueue((prev) => prev.filter((x) => x.id !== tempId))\n // 同步 400(如预检拦截)服务端会附上已尝试的安装方式,issue 预填一并展示;\n // 用 || 而非 ?? :error 为空字符串时回退 HTTP 状态,避免复制出来是空白\n onError(data.error || `HTTP ${res.status}`, input.repo, 'install', input.command, data.attempts)\n return\n }\n const taskId = data.task\n modalTaskRef.current = taskId\n // 用真实任务 id 替换乐观占位,解除 optimistic 标记(此后归正常收尾/轮询处理)\n applyQueue((prev) => prev.map((x) => (x.id === tempId\n ? { ...x, id: taskId, optimistic: undefined }\n : x)))\n // 提前缓存展示信息:安装成功后服务端登记待重启,轮询合并时不用等目录解析\n pendingInfoRef.current.set(input.repo, { desc: input.desc, version: input.version })\n // 摘要条常驻顶部(含实时进度),明细面板保持折叠,想看时再点开\n pollQueue()\n } catch (err) {\n // 网络异常:移除乐观条目 + 兜底错误弹窗(附上底层原因,避免只剩一句笼统的「安装失败」)\n applyQueue((prev) => prev.filter((x) => x.id !== tempId))\n const aborted = (err as { name?: string } | null)?.name === 'AbortError'\n const reason = aborted\n ? t('requestTimeout')\n : err instanceof Error && err.message ? err.message : String(err ?? '')\n onError(reason ? `${t('installFail')} — ${reason}` : t('installFail'), input.repo, 'install', input.command)\n } finally {\n window.clearTimeout(timeout)\n submittingRef.current.delete(input.repo)\n setSubmitting(false)\n }\n }\n\n /** 目录插件安装:通道由目录数据(npmPackage)决定,走 catalog 白名单。 */\n const installNow = async (p: HubPlugin, opts?: { update?: boolean }) => {\n const repo = p.source?.repo ?? ''\n if (!repo) return\n // 安装通道决策(用户无感知):有 npm 包名 → 走 npm;否则 git 直装。\n const { target } = installTargetOf(p)\n if (!target) return\n await submitInstall({\n target,\n repo,\n desc: p.description,\n version: p.version,\n updatedAt: p.dates?.repoUpdatedAt,\n command: installCommandOf(p, true),\n source: 'catalog',\n update: opts?.update,\n })\n }\n\n /** 命令行安装:用户手输 npm 包名或 GitHub 地址,走 custom 源(受安全开关控制)。\n * update=true 时对已安装目标放行覆盖重装(与目录插件「更新」同一语义)。\n * 队列展示/防重一律用归一化身份(owner/repo 或 npm 包名):与服务端 /active 合并、\n * 弹窗目标匹配同口径,npm 包名透传不受影响。 */\n const installCustom = async (raw: string, opts?: { update?: boolean }) => {\n const target = raw.trim()\n if (!target) return\n const repo = repoFromInstallTarget(target)\n await submitInstall({\n target,\n repo,\n command: `pnpm add ${target}`,\n source: 'custom',\n update: opts?.update,\n })\n }\n\n /** 全局 npm 安装(官方 README 的 `npm install -g <pkgs>`):不进任何 profile、无需宿主重启。\n * 队列展示/防重用包列表空格拼接的身份(与服务端 target 同口径)。 */\n const installGlobalNpm = async (pkgs: string[], opts?: { update?: boolean }) => {\n const list = (pkgs ?? []).map((p) => p.trim()).filter((p) => p !== '')\n if (list.length === 0) return\n const identity = list.join(' ')\n await submitInstall({\n target: identity,\n repo: identity,\n command: `npm install -g ${identity}`,\n source: 'custom',\n globalNpm: list,\n update: opts?.update,\n })\n }\n\n /** 卸载入队核心:按 npm 包名直卸(目录插件与自定义安装共用,弹窗进度匹配同源)。 */\n const enqueueUninstall = async (name: string, repo: string | null, desc?: string) => {\n if (!name) return\n if (queueRef.current.some((q) => q.kind === 'uninstall' && q.target === name)) return\n // 请求在途防重:与安装一致,响应回来前再次点击直接忽略\n if (submittingRef.current.has(name)) return\n submittingRef.current.add(name)\n setSubmitting(true)\n const controller = new AbortController()\n const timeout = window.setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS)\n try {\n const res = await fetch('/dsh-plugin-hub/uninstall', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name, repo: repo ?? undefined }),\n signal: controller.signal,\n })\n const data = await res.json() as { ok?: boolean; task?: number; error?: string }\n if (!data.ok || typeof data.task !== 'number') {\n onError(data.error || `HTTP ${res.status}`, repo, 'uninstall')\n return\n }\n const taskId = data.task\n modalTaskRef.current = taskId\n applyQueue((prev) => [...prev, { id: taskId, kind: 'uninstall', target: name, desc, repo, status: 'pending', progress: 0, lines: [], needsRestart: true }])\n // 摘要条常驻顶部(含实时进度),明细面板保持折叠,想看时再点开\n pollQueue()\n } catch (err) {\n // 网络异常:附上底层原因,避免只剩一句笼统的「卸载失败」\n const aborted = (err as { name?: string } | null)?.name === 'AbortError'\n const reason = aborted\n ? t('requestTimeout')\n : err instanceof Error && err.message ? err.message : String(err ?? '')\n onError(reason ? `${t('uninstallFail')} — ${reason}` : t('uninstallFail'), repo, 'uninstall')\n } finally {\n window.clearTimeout(timeout)\n submittingRef.current.delete(name)\n setSubmitting(false)\n }\n }\n\n /** 弹窗动作:直接卸载(目录插件入口)。与安装同一队列机制,弹窗内实时显示进度。 */\n const uninstallNow = async (p: HubPlugin) => {\n const name = installedName(p)\n if (!name) return\n await enqueueUninstall(name, p.source?.repo ?? null, p.description)\n }\n\n /** 已安装视图动作:按已安装项卸载(覆盖目录外自定义安装,无目录数据也能卸)。 */\n const uninstallItem = async (item: InstalledItem) => {\n await enqueueUninstall(item.name, item.repo, item.plugin?.description)\n }\n\n /** 取消任务:排队中立即出队,执行中终止子进程;先标记「正在取消」短暂过渡后再移除。 */\n const cancelTask = async (id: number) => {\n if (modalTaskRef.current === id) modalTaskRef.current = null\n // 乐观标记「正在取消」,给用户一个可见反馈,而不是瞬间消失\n applyQueue((prev) => prev.map((q) => (q.id === id ? { ...q, status: 'cancelling' as const } : q)))\n try {\n await fetch('/dsh-plugin-hub/cancel', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n } catch { /* 服务端不可达:仍按取消处理,稍后移除 */ }\n // 短暂展示「正在取消」后移除;队列清空则停止轮询\n window.setTimeout(() => {\n applyQueue((prev) => prev.filter((x) => x.id !== id))\n maybeStopPoll()\n }, 700)\n }\n\n /** 打开新弹窗前清空任务匹配:避免旧任务 id 误匹配到新弹窗。 */\n const clearModalTask = () => { modalTaskRef.current = null }\n\n // 弹窗对应任务:优先当前弹窗发起任务,其次按目标匹配(重新打开弹窗 / 目标已在队列时也能展示实时进度)\n // 目录插件按 source.repo 匹配;命令行安装(custom)按归一化后的仓库身份/包名匹配;\n // 全局 npm 安装按包列表身份(空格拼接)匹配;\n // 排除 cancelling:取消中的任务不再关联到弹窗,弹窗回到「确认」态可重新操作\n const installModalTarget = installPlugin?.source?.repo\n ?? (installCustomTarget ? repoFromInstallTarget(installCustomTarget) : null)\n ?? installGlobalTarget ?? null\n const installModalTask = (installPlugin || installCustomTarget || installGlobalTarget)\n ? (queue.find((q) => q.id === modalTaskRef.current && q.kind === 'install' && q.status !== 'cancelling')\n ?? queue.find((q) => q.kind === 'install' && q.target === installModalTarget && q.status !== 'cancelling')\n ?? null)\n : null\n const uninstallModalTask = (uninstallPlugin || uninstallName)\n ? (queue.find((q) => q.id === modalTaskRef.current && q.status !== 'cancelling')\n ?? queue.find((q) => q.kind === 'uninstall' && q.target === (uninstallName ?? installedName(uninstallPlugin!) ?? '') && q.status !== 'cancelling')\n ?? null)\n : null\n\n return {\n queue,\n pendingRestarts,\n installModalTask,\n uninstallModalTask,\n submitting,\n installNow,\n installCustom,\n installGlobalNpm,\n uninstallNow,\n uninstallItem,\n cancelTask,\n clearModalTask,\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Inline SVG icons used across the client. Icons inherit currentColor so\n * they adapt to themes and disabled states automatically.\n */\nimport { createElement as h } from 'react'\nimport headerStyles from '../../styles/Header.module.css'\nimport modalStyles from '../../styles/Modal.module.css'\n\n/** 弹窗右上角关闭按钮图标:内联 SVG 十字(stroke 继承 currentColor),随按钮禁用态一起变淡。 */\nexport function CloseIcon() {\n return h('svg', {\n className: modalStyles.modalCloseIcon,\n viewBox: '0 0 16 16',\n width: 14,\n height: 14,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M3 3l10 10M13 3L3 13',\n stroke: 'currentColor',\n strokeWidth: 1.6,\n strokeLinecap: 'round',\n }))\n}\n\n/** 来源链接图标:链节(stroke 继承 currentColor),弹窗里官网收录地址旁提示「可点击跳转」。 */\nexport function LinkIcon() {\n return h('svg', {\n className: modalStyles.linkIcon,\n viewBox: '0 0 24 24',\n width: 13,\n height: 13,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71',\n stroke: 'currentColor',\n strokeWidth: 1.8,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71',\n stroke: 'currentColor',\n strokeWidth: 1.8,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }))\n}\n\n/** 帮助图标:圆圈 + 问号(stroke 继承 currentColor),自定义安装卡片标题旁的「帮助」按钮用。 */\nexport function HelpIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 13,\n height: 13,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('circle', {\n cx: 8, cy: 8, r: 6.3,\n stroke: 'currentColor', strokeWidth: 1.4,\n }),\n h('path', {\n d: 'M6.3 6.5a1.9 1.9 0 1 1 2.7 1.7c-.7.3-1 .8-1 1.4',\n stroke: 'currentColor', strokeWidth: 1.4, strokeLinecap: 'round',\n }),\n h('circle', { cx: 8, cy: 11.6, r: 0.95, fill: 'currentColor' }),\n )\n}\n\n/** 品牌 logo 图标:蓝紫渐变圆角方块 + 白色拼图块(2x2 错落),标题左侧的品牌标识。 */\nexport function LogoIcon() {\n return h('svg', {\n className: headerStyles.logoIcon,\n viewBox: '0 0 24 24',\n width: 20,\n height: 20,\n 'aria-hidden': 'true',\n },\n h('defs', null,\n h('linearGradient', { id: 'dshLogoGrad', x1: '0', y1: '0', x2: '1', y2: '1' },\n h('stop', { offset: '0%', stopColor: '#4f46e5' }),\n h('stop', { offset: '100%', stopColor: '#7c3aed' }),\n ),\n ),\n h('rect', { x: 1, y: 1, width: 22, height: 22, rx: 6, fill: 'url(#dshLogoGrad)' }),\n h('rect', { x: 5.5, y: 5.5, width: 5.5, height: 5.5, rx: 1.5, fill: '#ffffff' }),\n h('rect', { x: 13, y: 5.5, width: 5.5, height: 5.5, rx: 1.5, fill: '#ffffff', opacity: 0.55 }),\n h('rect', { x: 5.5, y: 13, width: 5.5, height: 5.5, rx: 1.5, fill: '#ffffff', opacity: 0.55 }),\n h('rect', { x: 13, y: 13, width: 5.5, height: 5.5, rx: 1.5, fill: '#ffffff' }),\n )\n}\n\n/** GitHub 图标:官方 GitHub Mark(octocat),fill 继承 currentColor,头部右上角源码链接用。 */\nexport function GitHubIcon() {\n return h('svg', {\n className: headerStyles.githubIcon,\n viewBox: '0 0 24 24',\n width: 18,\n height: 18,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12',\n }))\n}\n\n/** 复制图标:双层矩形(stroke 继承 currentColor),手动命令旁的复制按钮用。 */\nexport function CopyIcon() {\n return h('svg', {\n className: headerStyles.copyIcon,\n viewBox: '0 0 16 16',\n width: 12,\n height: 12,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('rect', {\n x: 5.5, y: 5.5, width: 7, height: 7, rx: 1.5,\n stroke: 'currentColor', strokeWidth: 1.4,\n }),\n h('path', {\n d: 'M10.5 5.5v-2a1.5 1.5 0 0 0-1.5-1.5H4.5A1.5 1.5 0 0 0 3 3.5v4A1.5 1.5 0 0 0 4.5 9h1',\n stroke: 'currentColor', strokeWidth: 1.4, strokeLinecap: 'round',\n }),\n )\n}\n\n/** 文件夹图标(Material folder):「在文件夹中显示」按钮用,fill 继承 currentColor。 */\nexport function FolderIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 13,\n height: 13,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z',\n }))\n}\n\n/** 下拉箭头图标:向下 V 形(stroke 继承 currentColor),下拉按钮触发器右侧提示可展开。 */\nexport function ChevronDownIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 12,\n height: 12,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M3.5 5.5L8 10l4.5-4.5',\n stroke: 'currentColor',\n strokeWidth: 1.6,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }))\n}\n\n/** 排序方向小箭头:正序(up) 朝上 / 倒序(down) 朝下,随 currentColor 着色,仅当前排序按钮显示 */\nexport function SortArrowIcon({ up }: { up: boolean }) {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 10,\n height: 10,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: up ? 'M4 9.5L8 5.5l4 4' : 'M4 6.5L8 10.5l4-4',\n stroke: 'currentColor',\n strokeWidth: 1.8,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n }))\n}\n\n/** 插件中心图标:店面货架(stroke 继承 currentColor),一级导航「插件中心」tab 用。 */\nexport function MarketIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 16,\n height: 16,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M4 10L5.6 4.5h12.8L20 10',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M4 10a2.2 2.2 0 0 0 4.4 0 2.2 2.2 0 0 0 4.4 0 2.2 2.2 0 0 0 4.4 0',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M5 13v6.5A1.5 1.5 0 0 0 6.5 21h11a1.5 1.5 0 0 0 1.5-1.5V13',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 自定义安装图标:终端窗口 + 提示符(stroke 继承 currentColor),一级导航「自定义安装」tab 用。 */\nexport function TerminalIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 16,\n height: 16,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('rect', {\n x: 3, y: 4.5, width: 18, height: 15, rx: 2.5,\n stroke: 'currentColor', strokeWidth: 1.8,\n }),\n h('path', {\n d: 'M6.8 9.2l3.4 2.8-3.4 2.8',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M12.5 14.8h4.5',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round',\n }),\n )\n}\n\n/** 已安装图标:插件包(圆角方盒 + 盒盖线)+ 对勾(stroke 继承 currentColor),一级导航「已安装」tab 用。 */\nexport function InstalledIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 16,\n height: 16,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('rect', {\n x: 4.5, y: 6.5, width: 15, height: 13, rx: 2.5,\n stroke: 'currentColor', strokeWidth: 1.8,\n }),\n h('path', {\n d: 'M4.5 11h15',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round',\n }),\n h('path', {\n d: 'M9.2 15.2l2.1 2.1 3.6-4',\n stroke: 'currentColor', strokeWidth: 1.8, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 通知铃铛图标:实心铃铛(fill 继承 currentColor),采用 Material 官方 notifications 路径,一级导航通知中心入口用。 */\nexport function BellIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 15,\n height: 15,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M12 22c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z',\n }))\n}\n\n/** 设置图标:实心齿轮(fill 继承 currentColor),采用 Material 官方 settings 路径,齿形清晰、辨识度高。 */\nexport function SettingsIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 16,\n height: 16,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41L9.25 5.35C8.66 5.59 8.12 5.92 7.63 6.29L5.24 5.33c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.22-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61L19.14 12.94zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z',\n }))\n}\n\n/** 更新与通道图标:循环同步箭头(fill 继承 currentColor),采用 Material 官方 sync 路径,设置左侧导航「更新与通道」用。 */\nexport function UpdatesIcon() {\n return h('svg', {\n viewBox: '0 0 24 24',\n width: 15,\n height: 15,\n fill: 'currentColor',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z',\n }))\n}\n\n/** 安全与信任图标:盾牌 + 对勾(stroke 继承 currentColor),设置左侧导航「安全与信任」用。 */\nexport function SecurityIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 15,\n height: 15,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M8 1.8L13.8 3.8v4.3c0 3.5-2.2 6.3-5.8 7.6-3.6-1.3-5.8-4.1-5.8-7.6V3.8L8 1.8z',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M5.6 8.1l1.7 1.7 3.2-3.4',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 诊断图标:心跳脉冲线(stroke 继承 currentColor),设置左侧导航「诊断」用。 */\nexport function DiagnosticsIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 15,\n height: 15,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M1.6 8h3l1.9-4.2 2.9 8.4 1.9-4.2h3.1',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 恢复默认图标:逆时针还原箭头(stroke 继承 currentColor),设置左侧导航「恢复默认」用。 */\nexport function ResetIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 15,\n height: 15,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M3 5.2A5.6 5.6 0 1 1 2.4 9.6',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M2.6 2.6v2.6h2.6',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }))\n}\n\n/** 系统日志图标:文档纸 + 三行文字(stroke 继承 currentColor),设置左侧导航「系统日志」用。 */\nexport function LogsIcon() {\n return h('svg', {\n viewBox: '0 0 16 16',\n width: 15,\n height: 15,\n fill: 'none',\n 'aria-hidden': 'true',\n },\n h('path', {\n d: 'M4.2 1.8h4.8l2.8 2.8v9.6H4.2z',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M9 1.8v2.8h2.8',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round',\n }),\n h('path', {\n d: 'M5.6 9.2h4.8M5.6 11.2h4.8',\n stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round',\n }))\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Inline progress block shared by the install and uninstall dialogs:\n * a real percentage bar (server-estimated, client-polled). No live terminal\n * window — pnpm emits nothing during git clone/build, so a log pane would be\n * empty for most of the run; failures surface their full output in ErrorModal.\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { TaskState } from '../../types.ts'\n\nexport function ProgressView({ task }: { task: TaskState }) {\n return h('div', { className: styles.progress },\n h('div', { className: styles.progressHead },\n h('span', { className: styles.progressText }, `${Math.round(task.progress)}%`),\n ),\n h('div', { className: styles.progressTrack },\n h('div', {\n className: task.status === 'failed' ? `${styles.progressFill} ${styles.progressFillFail}` : styles.progressFill,\n style: { width: `${task.progress}%` },\n }),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Dialog layer for the Plugin Hub: the install-confirm dialog, the uninstall\n * dialog and the global toast. Both dialogs lock themselves while a mutation\n * or restart is running, then switch to a result view offering an immediate\n * restart or a \"later\" deferral.\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { EnvInfo, HubPlugin, TaskState, ToastState, Translate } from '../../types.ts'\nimport { CloseIcon, CopyIcon, LinkIcon } from '../ui/icons.tsx'\nimport { ProgressView } from './ProgressView.tsx'\nimport { installCommandOf } from '../../logic/install-command.ts'\nimport { pluginDetailUrl, pluginIssueUrl, pluginSiteUrl } from '../../logic/urls.ts'\nimport { classifyFailure, npmTooLowVersion } from '../../logic/failures.ts'\n\n/** 完成结果视图:绿色对勾 + 标题/描述;\n * needsRestart=true(插件需重启才生效)→ 「稍后重启 / 立即重启」按钮对,点稍后重启后\n * 通知中心待重启条目常驻(服务端登记,内存态),直到用户点「立即重启」真正重启后才消失;\n * needsRestart=false(卸载已即时生效)→ 仅「完成」关闭。 */\nfunction ResultView({\n title, desc, t, restarting, needsRestart, onRestart, onClose,\n}: {\n title: string\n desc: string\n t: Translate\n restarting: boolean\n needsRestart: boolean\n onRestart: () => void\n onClose: () => void\n}) {\n return h('div', { className: styles.result },\n h('div', { className: styles.resultCheck },\n h('svg', {\n className: styles.resultCheckIcon,\n viewBox: '0 0 16 16',\n width: 20,\n height: 20,\n fill: 'none',\n 'aria-hidden': 'true',\n }, h('path', {\n d: 'M2.5 8.5l3.5 3.5 7.5-7.5',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n })),\n ),\n h('div', { className: styles.resultTitle }, title),\n desc ? h('div', { className: styles.resultDesc }, desc) : null,\n needsRestart\n ? h('div', null, [\n h('div', { className: styles.resultRestarting }, restarting ? t('restarting') : t('restartHint')),\n h('div', { className: styles.modalActions },\n h('button', { className: styles.restartLater, onClick: onClose, disabled: restarting }, t('restartLater')),\n h('button', { className: styles.restartNowWarning, onClick: onRestart, disabled: restarting },\n restarting ? t('restarting') : t('restartNow')),\n ),\n ])\n : h('div', { className: styles.modalActions },\n h('button', { className: styles.restartNow, onClick: onClose }, t('done'))),\n )\n}\n\nexport interface InstallModalProps {\n /** 目录插件(有完整元数据);命令行安装(custom)传 null 走 customTarget 模式 */\n plugin: HubPlugin | null\n /** 命令行安装目标(无目录元数据):提供时按裸目标展示确认/进度/结果,命令条显示 pnpm add <target> */\n customTarget?: string\n /** 全局 npm 安装(官方 README 的 `npm install -g <pkgs>`):提供时按包列表展示确认/进度/结果,\n * 命令条显示 npm install -g <pkgs> —— 装的是系统级 CLI 工具,不进插件列表、无需重启 */\n globalNpm?: string[]\n done: boolean\n task: TaskState | null\n t: Translate\n langPath: string\n restarting: boolean\n /** 已安装插件的覆盖更新(走同一条 add 命令原位重装,文案区分安装/更新) */\n update: boolean\n /** 仅命令行插件(webInstallable=false):不提供一键安装,只展示命令供复制到 dsh 终端 */\n cliOnly: boolean\n /** 安装请求在途(fetch 等待响应):此时任务尚未入队,需禁用确认按钮防止二次点击 */\n submitting: boolean\n /** 完成结果是否需重启才生效:true → 「稍后重启 / 立即重启」;false → 仅「完成」 */\n needsRestart: boolean\n onClose: () => void\n onCopy: () => void\n onInstall: () => void\n onRestart: () => void\n}\n\n/**\n * 信任确认弹窗:安装进入后台队列后弹窗仍可关闭(任务继续),\n * 只在本任务执行中展示实时进度;完成后切换为结果视图,与卸载一致。\n * 目录插件与命令行安装(customTarget 模式)共用同一套确认/进度/结果流程。\n */\nexport function InstallModal(props: InstallModalProps) {\n const { plugin, customTarget, globalNpm, done, task, t, langPath, restarting, submitting, update, cliOnly, needsRestart, onClose, onCopy, onInstall, onRestart } = props\n const busy = submitting || (task !== null && (task.status === 'pending' || task.status === 'running'))\n // 进行中标题带上插件名(中文「XX 插件安装中」;英文状态词在前更自然),并用状态色区分;\n // 命令行安装无插件元数据 → 直接用输入的目标展示;全局 npm 安装 → 包列表空格拼接\n const name = customTarget ?? (globalNpm !== undefined && globalNpm.length > 0 ? globalNpm.join(' ') : undefined) ?? plugin?.displayName ?? plugin?.slug ?? ''\n const busyTitle = (label: string) => langPath === 'zh/' ? `${name} 插件${label}` : `${label} ${name}`\n const title = busy\n ? task && task.status === 'pending'\n ? busyTitle(update ? t('queuedUpdateTitle') : t('queuedTitle'))\n : busyTitle(update ? t('updating') : t('installing'))\n : done\n ? update ? t('updateResultTitle') : t('installResultTitle')\n : update ? t('confirmUpdateTitle') : t('confirmTitle')\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: styles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', {\n className: busy\n ? `${styles.modalTitle} ${task && task.status === 'pending' ? styles.modalTitleQueued : styles.modalTitleBusy}`\n : styles.modalTitle,\n }, title),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: () => onClose(),\n }, h(CloseIcon)),\n ),\n done\n // 安装完成:结果视图(成功即生效,仅「完成」关闭);更新时标题/描述区分语义\n ? h(ResultView, {\n title: update ? t('updateResultTitle') : t('installResultTitle'),\n desc: update ? t('updateResultDesc') : t('installResultDesc'),\n t,\n restarting,\n needsRestart,\n onRestart,\n onClose,\n })\n // 确认/进行中:来源行 + 安装命令 + 实时进度 + 操作按钮\n : h('div', { className: styles.modalBody },\n h('div', { className: styles.trustHint }, t('confirmDesc')),\n h('div', { className: styles.modalRow },\n h('span', { className: styles.modalLabel }, t('confirmPlugin')),\n h('span', { className: styles.modalValue, title: name }, name),\n ),\n plugin?.source?.repo ? h('div', { className: styles.modalRow },\n h('span', { className: styles.modalLabel }, t('confirmSource')),\n // 来源仓库:可点击跳转官网收录详情页(新窗口打开)\n h('a', {\n className: styles.modalLink,\n href: pluginDetailUrl(plugin, langPath),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: plugin.source.repo,\n }, h(LinkIcon), plugin.source.repo),\n ) : null,\n // 手动命令条:整条点击即复制,右侧再放一个显式复制按钮;\n // 命令行安装(无目录数据)直接展示 pnpm add <target>;全局 npm 安装展示 npm install -g <pkgs>\n h('div', {\n className: styles.modalCmd,\n onClick: onCopy,\n title: t('copyInstallCommand'),\n role: 'button',\n tabIndex: 0,\n },\n h('span', { className: styles.modalCmdText },\n globalNpm !== undefined && globalNpm.length > 0\n ? `npm install -g ${globalNpm.join(' ')}`\n : customTarget ? `pnpm add ${customTarget}` : installCommandOf(plugin!)),\n h('span', { className: styles.modalCmdCopy }, h(CopyIcon), t('copyCmdLabel')),\n ),\n // 全局 npm 安装说明:装的是系统级 CLI 工具,不进插件列表、无需重启宿主\n globalNpm !== undefined && globalNpm.length > 0\n ? h('div', { className: styles.cliOnlyHint }, t('globalNpmHint'))\n : null,\n // AI 识别可能需要命令行辅助的插件(webInstallable=false):提示但不拦截,仍允许尝试一键安装\n cliOnly ? h('div', { className: styles.cliOnlyHint }, t('cliOnlyHint')) : null,\n task && task.status === 'pending' ? h('div', { className: styles.queuedHint }, t('queuedHint')) : null,\n task ? h(ProgressView, { task }) : null,\n // 安装失败:引导用户复制上方命令到 dsh 终端手动安装(如 node-pty 等原生依赖构建脚本需人工放行)\n task && task.status === 'failed' ? h('div', { className: styles.failedCopyHint }, t('failedCopyHint')) : null,\n h('div', { className: styles.modalActions },\n h('button', {\n className: styles.modalCopy,\n disabled: busy,\n onClick: onCopy,\n }, t('copyInstallCommand')),\n h('button', {\n className: styles.modalInstall,\n disabled: busy,\n onClick: onInstall,\n }, busy\n ? (task && task.status === 'pending'\n ? (update ? t('queuedUpdateTitle') : t('queuedTitle'))\n : (update ? t('updating') : t('installing')))\n : (update ? t('updateNow') : t('installNow'))),\n ),\n ),\n ),\n )\n}\n\nexport interface UninstallModalProps {\n plugin: HubPlugin\n done: boolean\n task: TaskState | null\n t: Translate\n langPath: string\n restarting: boolean\n /** 卸载请求在途(fetch 等待响应):此时任务尚未入队,需禁用确认按钮防止二次点击 */\n submitting: boolean\n /** 完成结果是否需重启才生效:true → 「稍后重启 / 立即重启」;false(loader 已即时移除)→ 仅「完成」 */\n needsRestart: boolean\n onClose: () => void\n onCancel: () => void\n onCopyCommand: () => void\n onConfirm: () => void\n onRestart: () => void\n}\n\n/** 卸载确认弹窗:确认/进行中(后台队列,可关闭);完成后切换为结果视图(成功即生效,仅「完成」关闭)。 */\nexport function UninstallModal(props: UninstallModalProps) {\n const { plugin, done, task, t, langPath, restarting, submitting, needsRestart, onClose, onCancel, onCopyCommand, onConfirm, onRestart } = props\n const busy = submitting || (task !== null && (task.status === 'pending' || task.status === 'running'))\n // 进行中标题带上插件名,与安装弹窗一致,并用状态色区分\n const name = plugin.displayName ?? plugin.slug\n const busyTitle = (label: string) => langPath === 'zh/' ? `${name} 插件${label}` : `${label} ${name}`\n const title = busy\n ? task && task.status === 'pending' ? busyTitle(t('queuedUninstallTitle')) : busyTitle(t('uninstalling'))\n : done ? t('uninstallResultTitle') : t('uninstallTitle')\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: styles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', {\n className: busy\n // 注意 task 判空:submitting(请求在途)时任务尚未入队,task 为 null,不能直接解引用\n ? `${styles.modalTitle} ${task !== null && task.status === 'pending' ? styles.modalTitleQueued : styles.modalTitleBusy}`\n : styles.modalTitle,\n }, title),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: () => onClose(),\n }, h(CloseIcon)),\n ),\n done\n // 卸载完成:结果视图(成功即生效,仅「完成」关闭)\n ? h(ResultView, {\n title: t('uninstallResultTitle'),\n desc: t('uninstallResultDesc'),\n t,\n restarting,\n needsRestart,\n onRestart,\n onClose,\n })\n // 确认/进行中:来源行 + 实时进度 + 操作按钮\n : h('div', { className: styles.modalBody },\n h('div', { className: styles.modalDesc }, t('uninstallDesc')),\n h('div', { className: styles.modalRow },\n h('span', { className: styles.modalLabel }, t('confirmPlugin')),\n h('span', { className: styles.modalValue, title: plugin.displayName ?? plugin.slug },\n plugin.displayName ?? plugin.slug),\n ),\n // 显示仓库来源:github 用户名 + 仓库名,让用户确认卸载的是哪一个仓库\n plugin.source?.repo ? h('div', { className: styles.modalRow },\n h('span', { className: styles.modalLabel }, t('confirmSource')),\n // 来源仓库:可点击跳转官网收录详情页(新窗口打开)\n h('a', {\n className: styles.modalLink,\n href: pluginDetailUrl(plugin, langPath),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: plugin.source.repo,\n }, h(LinkIcon), plugin.source.repo),\n ) : null,\n task && task.status === 'pending' ? h('div', { className: styles.queuedHint }, t('queuedHint')) : null,\n task ? h(ProgressView, { task }) : null,\n h('div', { className: styles.modalActions },\n // 复制卸载命令:万一直接卸载失败,可去终端手动执行\n h('button', {\n className: styles.modalCopy,\n disabled: busy,\n onClick: onCopyCommand,\n }, t('copyUninstallCommand')),\n // 确认框语义:取消动作需明确指向「卸载」,避免歧义\n h('button', {\n className: styles.modalCancel,\n onClick: onCancel,\n }, t('cancelUninstall')),\n h('button', {\n className: styles.uninstallConfirm,\n disabled: busy,\n onClick: onConfirm,\n }, busy ? (task && task.status === 'pending' ? t('queuedUninstallTitle') : t('uninstalling')) : t('uninstallConfirm')),\n ),\n ),\n ),\n )\n}\n\n/** 预填插件仓库的 GitHub Issue 链接:标题带插件名,正文附完整错误信息,方便用户一键反馈。 */\n/** 安装/卸载失败弹窗:布局与失败记录一致(类型徽标 + 仓库超链接 + 隐蔽复制按钮),报错完整展示,底部一键提交 Issue。 */\nexport function ErrorModal({ message, repo, kind, command, attempts, t, env, onCopy, onClose }: {\n message: string\n repo: string | null\n kind: 'install' | 'uninstall'\n command?: string\n /** 尝试过的安装方式(npm 反查 + 实际执行命令):issue 预填一并贴给作者,便于反推正确的 npm 包名 */\n attempts?: string[]\n t: Translate\n env: EnvInfo | null\n onCopy: (text: string) => void\n onClose: () => void\n}) {\n // 失败归类:当前安装通道(npm/git)装不上 = 插件分发/依赖的问题,一律引导提 Issue\n const failureKind = classifyFailure(message)\n // 服务端 [npm-too-low] 标记里带的本机 npm 版本(无标记为 null,提示文案降级为「怀疑」)\n const npmVersion = npmTooLowVersion(message)\n // 复制完整错误:实际执行/尝试过的安装命令(如有)+ 完整错误正文。\n // 只复制 message 会丢上下文 —— 命令行安装输入的目标、执行过的命令都在 command/attempts 里,\n // 光拷一句「unsupported install target」出去没人看得懂\n const copyText = [\n ...(command ? [command] : []),\n ...(attempts ?? []),\n message,\n ].join('\\n')\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: styles.errorModal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n // 标题按操作类型明确区分:安装失败 / 卸载失败\n h('div', { className: styles.errorTitle }, kind === 'install' ? t('errorTitleInstall') : t('errorTitleUninstall')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n // 与失败记录一致的布局:类型徽标 + 仓库超链接 + 顶部隐蔽复制按钮\n h('div', { className: styles.failRow },\n h('div', { className: styles.failHead },\n h('span', {\n className: kind === 'install' ? styles.failKindInstall : styles.failKindUninstall,\n }, kind === 'install' ? t('install') : t('uninstall')),\n // 仓库地址(用户名/仓库)统一显示为可点击超链接,跳转到官网详情页(含插件收录信息),而非直接跳 GitHub\n repo ? h('a', {\n className: styles.failRepo,\n href: pluginSiteUrl(repo),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: repo,\n }, repo) : null,\n // 复制按钮放最上面、浅灰隐蔽;报错正文不允许鼠标选择复制,只能点这里\n h('button', { className: styles.errorCopySoft, onClick: () => onCopy(copyText) }, t('errorCopy')),\n ),\n // 报错信息完整展示(可滚动),比失败记录的预览看得更多\n h('pre', { className: styles.errorBox }, message),\n // npm 内部崩溃(edgesOut)+ 本机 npm 版本过低:npm 自身已知缺陷,不是插件问题 ——\n // 直接给升级指引,不引导提 Issue(提了也是 npm 的问题,插件作者无法修复)\n failureKind === 'npmTooOld'\n ? h('div', { className: styles.failPrepareHint },\n t(npmVersion ? 'failNpmTooLowV' : 'failNpmTooLow', npmVersion ? { v: npmVersion } : undefined))\n : failureKind === 'pluginPrepare' || failureKind === 'pnpmIgnoredBuild'\n ? h('div', null, [\n // [packaging](预检/装后校验拦截:git 分发缺产物)与\n // prepare 构建脚本实际执行失败 / 原生依赖构建被 pnpm 拦截:都是插件打包分发问题 —— 先说明原因,按钮在下方提交\n h('div', { className: styles.failPrepareHint }, failureKind === 'pnpmIgnoredBuild'\n ? t('failIgnoredBuild')\n : /\\[packaging\\]/i.test(message) ? t('failPackagingHint') : t('failPrepareHint')),\n repo ? h('a', {\n className: styles.failBigIssue,\n href: pluginIssueUrl(repo, message, env, command, attempts),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('failIssueHint'),\n }, t('failIssueBig')) : null,\n ])\n : repo ? h('a', {\n className: styles.failBigIssue,\n href: pluginIssueUrl(repo, message, env, command, attempts),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('failIssueHint'),\n }, t('failIssueBig')) : null,\n ),\n h('div', { className: styles.modalActions },\n h('button', { className: styles.restartLater, onClick: onClose }, t('errorClose')),\n ),\n ),\n ),\n )\n}\n\n/** 全局反馈 Toast:复制成功(反色)/ 安装完成(反色)/ 安装失败(红色)/ 卸载结果 */\nexport function Toast({ toast, t }: { toast: ToastState; t: Translate }) {\n const text = toast.kind === 'copied' ? t('toastCopied')\n : toast.kind === 'errCopied' ? t('errCopied')\n : toast.kind === 'done' ? t('installDone')\n : toast.kind === 'fail' ? t('installFail')\n : toast.kind === 'removed' ? t('uninstallDone')\n : toast.kind === 'revealFail' ? t('openFolderFail')\n : toast.kind === 'updates' ? t('updatesFound', { n: toast.n ?? 0 })\n : t('uninstallFail')\n const fail = toast.kind === 'fail' || toast.kind === 'removeFail' || toast.kind === 'revealFail'\n return h('div', {\n key: toast.id,\n className: fail ? `${styles.toast} ${styles.toastFail}` : styles.toast,\n }, text)\n}\n\n/** 待重启确认弹窗:已安装列表行内「重启」按钮点击后弹出,\n * 与通知中心待重启条目同一交互(说明 + 稍后重启 / 立即重启),\n * 避免行内按钮误触直接触发宿主重启。 */\nexport function RestartConfirmModal({ t, restarting, onClose, onRestartNow }: {\n t: Translate\n restarting: boolean\n onClose: () => void\n onRestartNow: () => void\n}) {\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) onClose() },\n },\n h('div', { className: styles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('sectionPendingRestart')),\n h('button', {\n className: styles.modalClose,\n type: 'button',\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n h('div', { className: styles.failPrepareHint }, t('restartHint')),\n h('div', { className: styles.modalActions },\n h('button', {\n className: styles.restartLater,\n type: 'button',\n disabled: restarting,\n onClick: onClose,\n }, t('restartLater')),\n h('button', {\n className: styles.restartNowWarning,\n type: 'button',\n disabled: restarting,\n onClick: onRestartNow,\n }, restarting ? t('restarting') : t('restartNow')),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * 轻量 Markdown 渲染器:仅用于 Hub 自我更新的变更记录(Worker 下发的 notes)。\n *\n * 内容由插件作者自己编写、属可信内容,但渲染端仍先整体 HTML 转义,再按\n * Markdown 语法输出结构,杜绝任何未转义的原始 HTML 注入;链接仅放行 http(s)。\n *\n * 支持:标题(#~####)、有序/无序列表、代码块(```)、行内代码、加粗、斜体、\n * 链接、图片(![alt](url),如反馈群二维码)、引用(>)、段落;其余语法一律按\n * 纯文本处理,不引入外部依赖。图片仅放行 http(s),限定最大宽度不撑破弹窗。\n */\n\n/** HTML 转义:所有文本先进这里,再进入结构变换,保证输出里没有未转义的用户输入。 */\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\n/** 行内变换:链接 / 加粗 / 斜体 / 行内代码(代码先占位保护,最后还原)。 */\nfunction inline(s: string): string {\n let out = escapeHtml(s)\n // 行内代码先占位:避免其中的 * [ ] 被后续链接/加粗/斜体规则破坏\n const codeSpans: string[] = []\n out = out.replace(/`([^`]+)`/g, (_m, code) => {\n codeSpans.push(String(code))\n return `\\u0000${codeSpans.length - 1}\\u0000`\n })\n // 图片 ![alt](url):仅放行 http(s),用于展示反馈群二维码等;limited by CSS\n out = out.replace(/!\\[([^\\]]*)\\]\\(([^)\\s]+)\\)/g, (m, alt, url) =>\n /^https?:\\/\\//i.test(String(url)) && !/[\\u0000]/.test(String(url))\n ? `<img src=\"${String(url)}\" alt=\"${String(alt)}\" loading=\"lazy\">`\n : m,\n )\n // 链接 [text](url):仅放行 http(s),新窗口打开\n out = out.replace(/\\[([^\\]]+)\\]\\(([^)\\s]+)\\)/g, (m, text, url) =>\n /^https?:\\/\\//i.test(String(url)) && !/[\\u0000]/.test(String(url))\n ? `<a href=\"${String(url)}\" target=\"_blank\" rel=\"noopener noreferrer\">${String(text)}</a>`\n : m,\n )\n out = out.replace(/\\*\\*([^*]+)\\*\\*/g, '<strong>$1</strong>')\n out = out.replace(/(^|[^*])\\*([^*]+)\\*/g, '$1<em>$2</em>')\n return out.replace(/\\u0000(\\d+)\\u0000/g, (_m, idx) => `<code>${codeSpans[Number(idx)]}</code>`)\n}\n\n/** 把变更记录 Markdown 渲染为安全的 HTML 字符串(由弹窗用 dangerouslySetInnerHTML 注入)。 */\nexport function renderMarkdown(md: string): string {\n const lines = md.replace(/\\r\\n?/g, '\\n').split('\\n')\n const blocks: string[] = []\n let i = 0\n while (i < lines.length) {\n const line = lines[i]\n // 围栏代码块\n if (/^\\s*```/.test(line)) {\n const buf: string[] = []\n i++\n while (i < lines.length && !/^\\s*```/.test(lines[i])) {\n buf.push(lines[i])\n i++\n }\n i++ // 跳过闭合围栏\n blocks.push(`<pre><code>${escapeHtml(buf.join('\\n'))}</code></pre>`)\n continue\n }\n // 空行:段落分隔符\n if (line.trim() === '') {\n i++\n continue\n }\n // 标题:# 到 #### 映射为 h2~h5(弹窗标题用 modalTitle,不与其冲突)\n const heading = line.match(/^(#{1,4})\\s+(.*)/)\n if (heading) {\n const level = heading[1].length + 1\n blocks.push(`<h${level}>${inline(heading[2])}</h${level}>`)\n i++\n continue\n }\n // 有序 / 无序列表(连续收集为一个列表块)\n if (/^\\s*[-*+]\\s+/.test(line) || /^\\s*\\d+[.)]\\s+/.test(line)) {\n const ordered = /^\\s*\\d+[.)]\\s+/.test(line)\n const items: string[] = []\n while (i < lines.length && (/^\\s*[-*+]\\s+/.test(lines[i]) || /^\\s*\\d+[.)]\\s+/.test(lines[i]))) {\n items.push(`<li>${inline(lines[i].replace(/^\\s*[-*+]|\\s*\\d+[.)]\\s*/, '').trim())}</li>`)\n i++\n }\n blocks.push(`<${ordered ? 'ol' : 'ul'}>${items.join('')}</${ordered ? 'ol' : 'ul'}>`)\n continue\n }\n // 引用\n if (/^\\s*>\\s?/.test(line)) {\n const buf: string[] = []\n while (i < lines.length && /^\\s*>\\s?/.test(lines[i])) {\n buf.push(inline(lines[i].replace(/^\\s*>\\s?/, '')))\n i++\n }\n blocks.push(`<blockquote>${buf.join('<br>')}</blockquote>`)\n continue\n }\n // 普通段落:收集连续非空、非特殊开头的行\n const buf: string[] = []\n while (\n i < lines.length\n && lines[i].trim() !== ''\n && !/^\\s*```/.test(lines[i])\n && !/^#{1,4}\\s+/.test(lines[i])\n && !/^\\s*([-*+]|\\d+[.)])\\s+/.test(lines[i])\n ) {\n buf.push(inline(lines[i]))\n i++\n }\n blocks.push(`<p>${buf.join('<br>')}</p>`)\n }\n return blocks.join('')\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * 头部「关注我们」弹窗:介绍 DSH Plugin Hub 的功能定位 + 用户反馈群二维码。\n * 内容以 Markdown 形式由 dsh-update Worker 的 /about 接口下发(key = hub:about),\n * 客户端按接口返回渲染,不内置固定文案。\n * 图片(反馈群二维码)经 renderMarkdown 的 ![](url) 语法嵌入,居中、最大高度受控。\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { HubAboutInfo } from '../../types.ts'\nimport type { LocaleId, Translate } from '../../types.ts'\nimport { renderMarkdown } from '../../logic/renderMarkdown.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\nexport function AboutModal({ info, lang, t, onClose }: {\n info: HubAboutInfo | null\n lang: LocaleId\n t: Translate\n onClose: () => void\n}) {\n // 内容:字符串直接使用;{zh,en} 对象按界面语言取,缺哪种补哪种,全缺则展示兜底文案。\n // Worker 未推送(info 为 null / content 为空)时弹窗仍能打开,显示「暂未发布」而非报错。\n const contentRaw = info\n ? typeof info.content === 'string'\n ? info.content\n : info.content && typeof info.content === 'object'\n ? lang === 'en'\n ? (info.content.en ?? info.content.zh ?? '')\n : (info.content.zh ?? info.content.en ?? '')\n : ''\n : ''\n const contentHtml = contentRaw.trim() ? renderMarkdown(contentRaw) : null\n // 更新时间:ISO 字符串转本地可读格式;非法值静默隐藏\n let updated: string | null = null\n if (info?.updatedAt) {\n const d = new Date(info.updatedAt)\n if (!Number.isNaN(d.getTime())) {\n updated = d.toLocaleString(lang === 'en' ? 'en-US' : 'zh-CN')\n }\n }\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.modal} ${styles.aboutModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('aboutTitle')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: () => onClose(),\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalDesc }, t('aboutDesc')),\n contentHtml\n ? h('div', {\n className: styles.aboutContent,\n dangerouslySetInnerHTML: { __html: contentHtml },\n })\n : h('div', { className: styles.aboutContent }, t('aboutEmpty')),\n updated\n ? h('div', { className: styles.aboutMeta }, `${t('aboutUpdated')} ${updated}`)\n : null,\n h('div', { className: styles.modalActions },\n h('button', { className: styles.modalInstall, onClick: onClose }, t('doneBtn')),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Hub 版本信息 / 自我更新说明弹窗:\n * - 有更新(hasUpdate=true):标题「有新版本」,展示新版本号、发布时间与 Worker 下发的\n * Markdown 变更记录(renderMarkdown 渲染,双语言按界面语言取 {zh,en} 对象),\n * 按钮「稍后再说 / 直接更新」,确认后进入安装弹窗执行覆盖重装。\n * - 无更新(hasUpdate=false):标题「当前版本」,展示当前版本信息与更新记录,已是最新。\n * 点击头部版本号(或「可更新」徽标)打开 —— 无论有无更新都能看到更新内容。\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { HubUpdateInfo } from '../../types.ts'\nimport type { LocaleId, Translate } from '../../types.ts'\nimport { renderMarkdown } from '../../logic/renderMarkdown.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\nexport function HubUpdateModal({ info, lang, t, hasUpdate, onProceed, onClose }: {\n info: HubUpdateInfo\n lang: LocaleId\n t: Translate\n /** 是否有可用更新:有则显示「直接更新」,无则显示「已是最新」 */\n hasUpdate: boolean\n /** 点「直接更新」:关闭本弹窗,进入安装弹窗的更新流程 */\n onProceed: () => void\n onClose: () => void\n}) {\n // 变更记录:字符串直接使用;{zh,en} 对象按界面语言取,缺哪种补哪种,全缺则不出记录区\n const notesRaw = typeof info.notes === 'string'\n ? info.notes\n : info.notes && typeof info.notes === 'object'\n ? lang === 'en'\n ? (info.notes.en ?? info.notes.zh ?? '')\n : (info.notes.zh ?? info.notes.en ?? '')\n : ''\n const notesHtml = notesRaw.trim() ? renderMarkdown(notesRaw) : null\n // 发布时间:ISO 字符串转本地可读格式;非法值静默隐藏\n let published: string | null = null\n if (info.publishedAt) {\n const d = new Date(info.publishedAt)\n if (!Number.isNaN(d.getTime())) {\n published = d.toLocaleString(lang === 'en' ? 'en-US' : 'zh-CN')\n }\n }\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.modal} ${styles.hubUpdateModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t(hasUpdate ? 'hubUpdateTitle' : 'hubCurrentTitle')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: () => onClose(),\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalDesc },\n t(hasUpdate ? 'hubUpdateDesc' : 'hubCurrentDesc', { version: info.version })),\n h('div', { className: styles.hubUpdateMeta },\n h('span', { className: styles.hubUpdateMetaItem }, `${t('version')} ${info.version}`),\n published\n ? h('span', { className: styles.hubUpdateMetaItem }, `${t('hubUpdatePublished')} ${published}`)\n : null,\n ),\n notesHtml\n ? h('div', {\n className: styles.hubUpdateNotes,\n dangerouslySetInnerHTML: { __html: notesHtml },\n })\n : null,\n h('div', { className: styles.modalActions },\n hasUpdate\n ? [\n h('button', { className: styles.restartLater, onClick: onClose }, t('hubUpdateLater')),\n h('button', { className: styles.modalInstall, onClick: onProceed }, t('updateNow')),\n ]\n : h('button', { className: styles.modalInstall, onClick: onClose }, t('hubUpToDate')),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Presentation formatters shared across the catalog list and the cards.\n */\nimport type { Translate } from '../types.ts'\n\n/** 星数/分支数的紧凑展示:<1k 原样;千级 1.2k;十万级取整。 */\nexport function fmtStars(count?: number): string {\n if (!count || count <= 0) return '0'\n if (count < 1000) return String(count)\n const k = count / 1000\n return `${k >= 100 ? Math.round(k) : k.toFixed(1).replace(/\\.0$/, '')}k`\n}\n\n/** 相对时间:今天 / N 天前 / N 个月前 / N 年前。 */\nexport function relTime(iso: string | undefined, t: Translate): string {\n if (!iso) return ''\n const days = Math.floor((Date.now() - new Date(iso).getTime()) / 86400000)\n if (days <= 0) return t('today')\n if (days < 30) return t('daysAgo', { days })\n if (days < 365) return t('monthsAgo', { months: Math.floor(days / 30) })\n return t('yearsAgo', { years: Math.floor(days / 365) })\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Installed-plugin detail dialog: opens from the Installed view (row click\n * or the detail button) and shows everything we know about an installed\n * entry — the catalog metadata (category, catalog entry, stars/forks,\n * latest version) merged with the host runtime facts (install path, installed\n * version, install time, last update). Update / uninstall actions are\n * offered from here too, mirroring the row actions.\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { LocaleId, Translate } from '../../types.ts'\nimport type { InstalledItem } from '../../logic/installed.ts'\nimport { CATEGORY_LABELS, categoryLabel } from '../../logic/constants.ts'\nimport { pluginDetailUrl } from '../../logic/urls.ts'\nimport { fmtStars } from '../../logic/format.ts'\nimport { CloseIcon, CopyIcon, FolderIcon, LinkIcon } from '../ui/icons.tsx'\n\n/** ISO 安装时间 → 本地可读;非法值返回 null(行内不显示)。 */\nfunction fmtDate(iso: string | null, lang: LocaleId): string | null {\n if (!iso) return null\n const d = new Date(iso)\n return Number.isNaN(d.getTime()) ? null : d.toLocaleString(lang === 'en' ? 'en-US' : 'zh-CN')\n}\n\nexport function InstalledDetailModal({ item, t, lang, langPath, onClose, onUpdate, onUninstall, onCopyPath, onReveal }: {\n item: InstalledItem\n t: Translate\n lang: LocaleId\n langPath: string\n onClose: () => void\n /** 更新:仅目录插件且有更新时展示(点击后关闭详情、走安装确认弹窗的更新语义) */\n onUpdate: (item: InstalledItem) => void\n onUninstall: (item: InstalledItem) => void\n /** 复制安装路径:成功提示由调用方 toast 反馈 */\n onCopyPath: (path: string) => void\n /** 在系统文件管理器里定位安装目录(服务端 spawn open):失败提示由调用方 toast 反馈 */\n onReveal: (item: InstalledItem) => void\n}) {\n const p = item.plugin\n const name = p?.displayName ?? item.name\n const installedAt = fmtDate(item.installedAt, lang)\n // 最后更新:目录插件取仓库最近提交时间(live 数据);自定义安装无目录信号\n const lastUpdated = fmtDate(p?.dates?.repoUpdatedAt ?? null, lang)\n const hasUpdate = item.hasUpdate && item.plugin !== null\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.modal} ${styles.detailModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, name),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('confirmCancel'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n // 描述:目录收录的插件简介\n p?.description ? h('div', { className: styles.modalDesc }, p.description) : null,\n // 有可用更新:醒目提示条(版本号存在时给出升级路径)\n hasUpdate\n ? h('div', { className: styles.detailUpdateHint },\n item.installedVersion && item.catalogVersion\n ? t('versionUpHint', { from: item.installedVersion, to: item.catalogVersion })\n : t('updateAvailableHint'))\n : null,\n // 详情信息网格:分类 / 状态 / 版本 / 收录入口 / 包名 / 统计 / 安装路径 / 安装时间 / 最后更新\n h('div', { className: styles.detailGrid },\n p?.category\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('detailCategory')),\n h('span', { className: styles.detailValue },\n categoryLabel(CATEGORY_LABELS, p.category, lang)))\n : null,\n h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('statusLabel')),\n h('span', { className: styles.detailValue },\n h('span', {\n className: item.loaded ? styles.detailStatusRunning : styles.detailStatusPending,\n 'aria-hidden': 'true',\n }),\n h('span', { className: styles.detailStatusText },\n item.loaded ? t('statusRunning') : t('statusPending')))),\n item.installedVersion\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('installedVersionLabel')),\n h('span', { className: styles.detailValue },\n h('span', { className: styles.detailMono }, item.installedVersion),\n // 目录有更新版本且与已装版本不同:给出「→ 目录最新」\n item.catalogVersion && item.catalogVersion !== item.installedVersion\n ? h('span', { className: styles.detailArrow },\n '\\u2192', h('span', { className: styles.detailMono }, item.catalogVersion),\n h('span', { className: styles.detailDim }, t('catalogLatest')))\n : null))\n : null,\n // 收录入口:仓库名 → 官网详情页(目录插件跳收录页;自定义安装回退到 GitHub 仓库)\n item.repo\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('detailCatalog')),\n h('a', {\n className: styles.detailLink,\n href: p ? pluginDetailUrl(p, langPath) : `https://github.com/${item.repo}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n title: item.repo,\n }, h(LinkIcon), item.repo))\n : null,\n item.plugin?.source?.npmPackage\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('packageName')),\n h('span', { className: styles.detailValue },\n h('span', { className: styles.detailMono }, item.plugin.source.npmPackage)))\n : null,\n p?.stats && (p.stats.stargazers_count ?? 0) > 0\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('detailStats')),\n h('span', { className: styles.detailValue },\n h('span', { className: styles.detailStars }, '\\u2605 ', fmtStars(p.stats.stargazers_count)),\n h('span', { className: styles.detailDim }, t('fork'), ' ', fmtStars(p.stats.forks_count))))\n : null,\n item.installPath\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('installPath')),\n h('div', { className: styles.detailPath },\n // 整条点击复制路径(等宽文本省略号)\n h('span', {\n className: styles.detailPathText,\n title: t('copyPath'),\n onClick: () => onCopyPath(item.installPath!),\n }, item.installPath),\n h('span', { className: styles.detailPathActions },\n h('button', {\n className: styles.detailPathBtn,\n type: 'button',\n title: t('copyPath'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation()\n onCopyPath(item.installPath!)\n },\n }, h(CopyIcon)),\n h('button', {\n className: styles.detailPathBtn,\n type: 'button',\n title: t('openFolder'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation()\n onReveal(item)\n },\n }, h(FolderIcon)),\n )))\n : null,\n installedAt\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('installedAtLabel')),\n h('span', { className: styles.detailValue }, installedAt))\n : null,\n // 最后更新时间:与安装时间成对展示(目录插件才有)\n lastUpdated\n ? h('div', { className: styles.detailRow },\n h('span', { className: styles.detailLabel }, t('lastUpdatedLabel')),\n h('span', { className: styles.detailValue }, lastUpdated))\n : null,\n ),\n ),\n // 底部操作:完成 / 更新 / 卸载(复制路径与打开文件夹已在路径行内)\n h('div', { className: styles.modalActions },\n h('button', {\n className: styles.restartLater,\n onClick: onClose,\n }, t('done')),\n hasUpdate\n ? h('button', {\n className: styles.modalInstall,\n onClick: () => onUpdate(item),\n }, t('update'))\n : null,\n h('button', {\n className: styles.uninstallConfirm,\n onClick: () => onUninstall(item),\n }, t('uninstall')),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Notification-center dialog: a persistent log of every settled install /\n * remove task — successes and failures alike.\n *\n * Records are written to localStorage at settle time (see logic/failures.ts),\n * so a result is never lost even when the dialog was dismissed or the user\n * was away. Each entry carries a circular status badge (green check for\n * success, red cross for failure) with white glyph and message text;\n * failures keep their copy / fix / file-an-issue actions. Opened from the\n * header entry button (after the Settings tab).\n */\nimport { createElement as h } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport type { EnvInfo, Translate } from '../../types.ts'\nimport type { NotificationRecord } from '../../logic/failures.ts'\nimport { classifyFailure, npmTooLowVersion } from '../../logic/failures.ts'\nimport type { PendingRestart, QueueTask } from '../../hooks/useTaskQueue.ts'\nimport { pluginIssueUrl, pluginSiteUrl } from '../../logic/urls.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\n/** 记录时间完整展示:YYYY-MM-DD HH:mm:ss(每条通知都带精确到秒的时间戳)。 */\nfunction fmtTime(at: number): string {\n const d = new Date(at)\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`\n}\n\n/** 圆形状态徽标内的白色图形:成功为对勾、失败为叉。 */\nfunction BadgeGlyph({ ok }: { ok: boolean }) {\n return h('svg', {\n className: styles.noticeBadgeIcon,\n viewBox: '0 0 16 16',\n width: 12,\n height: 12,\n fill: 'none',\n 'aria-hidden': 'true',\n }, ok\n ? h('path', {\n d: 'M3 8.5l3.5 3.5 6.5-6.5',\n stroke: '#ffffff',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n })\n : h('path', {\n d: 'M4 4l8 8M12 4L4 12',\n stroke: '#ffffff',\n strokeWidth: 2,\n strokeLinecap: 'round',\n }))\n}\n\nexport function NotificationsModal({ records, tasks, pendingRestarts, t, env, onClose, onCopy, onClear, onRemove, onUpdate, onIgnoreUpdate, cancelTask, restarting, onRestart, resolveRepo }: {\n records: NotificationRecord[]\n /** 进行中的安装/卸载任务(实时进度,与队列弹窗同一数据源) */\n tasks: QueueTask[]\n /** 待重启插件:装完没重启的常驻提醒 */\n pendingRestarts: PendingRestart[]\n t: Translate\n env: EnvInfo | null\n onClose: () => void\n onCopy: (text: string) => void\n onClear: () => void\n /** 删除单条通知记录 */\n onRemove: (id: number) => void\n /** 更新提醒通知点击:跳去该插件的更新确认弹窗 */\n onUpdate: (repo: string) => void\n /** 更新提醒「忽略本次更新」:先弹确认,确认后本次版本不再提醒,下一个新版本再通知 */\n onIgnoreUpdate: (repo: string, version?: string) => void\n cancelTask: (id: number) => void\n restarting: boolean\n onRestart: () => void\n /** 失败记录 repo 反查:npm 包名(历史记录存的是裸包名)反查成 owner/repo 再显示/提 Issue;\n * 查不到返回 null,按钮与仓库链接一并隐藏(防提到错误仓库)。不传则按记录原样展示。 */\n resolveRepo?: (repo: string) => string | null\n}) {\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: styles.errorModal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('notifications')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n h('div', { className: styles.errorHint }, t('notificationsDesc')),\n // 进行中的安装/卸载任务实时进度也进通知中心:与队列弹窗同一套行结构,\n // 关掉任务弹窗后仍可在这里盯着进度;待重启插件可在此直接触发重启\n (tasks.length > 0 || pendingRestarts.length > 0)\n ? h('div', null, [\n pendingRestarts.length > 0\n ? h('div', { className: styles.queueSection },\n h('div', { className: styles.queueSectionTitle }, t('sectionPendingRestart')),\n pendingRestarts.map((p) => h('div', { key: `restart-${p.target}`, className: styles.queueRow },\n h('div', { className: styles.queueRowHead },\n h('span', {\n className: `${styles.failKind} ${p.kind === 'uninstall' ? styles.failKindUninstall : styles.failKindInstall}`,\n }, p.kind === 'uninstall' ? t('uninstall') : t('install')),\n h('span', { className: styles.queueRowTarget, title: p.target }, p.target),\n ),\n p.desc ? h('div', { className: styles.queueRowDesc, title: p.desc }, p.desc) : null,\n h('div', { className: styles.queueRowBody },\n h('span', { className: styles.pendingRowStatus },\n p.kind === 'uninstall' ? t('restartPendingHintUninstall') : t('restartPendingHint')),\n h('span', { className: styles.pendingRowActions },\n h('button', {\n className: styles.restartLater,\n disabled: restarting,\n onClick: onClose,\n }, t('restartLater')),\n h('button', {\n className: styles.restartNow,\n disabled: restarting,\n onClick: onRestart,\n }, restarting ? t('restarting') : t('restartNow')),\n ),\n ),\n )),\n )\n : null,\n tasks.length > 0\n ? h('div', { className: styles.queueSection },\n h('div', { className: styles.queueSectionTitle }, t('sectionInProgress')),\n tasks.map((q) => h('div', { key: q.id, className: styles.queueRow },\n h('div', { className: styles.queueRowHead },\n h('span', {\n className: `${styles.failKind} ${q.kind === 'install' ? styles.failKindInstall : styles.failKindUninstall}`,\n }, q.kind === 'install' ? t('install') : t('uninstall')),\n h('span', { className: styles.queueRowTarget, title: q.target }, q.target),\n h('button', {\n className: styles.stripCancel,\n disabled: q.status === 'cancelling',\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); cancelTask(q.id) },\n }, t('cancelTask')),\n ),\n q.desc ? h('div', { className: styles.queueRowDesc, title: q.desc }, q.desc) : null,\n h('div', { className: styles.queueRowBody },\n h('span', { className: styles.queueRowStatus },\n q.status === 'running'\n ? (q.kind === 'install' ? t('installing') : t('uninstalling'))\n : q.status === 'cancelling'\n ? t('cancelling')\n : (q.kind === 'install' ? t('queuedTitle') : t('queuedUninstallTitle'))),\n h('div', { className: `${styles.progressTrack} ${styles.queueRowTrack}` },\n h('div', { className: styles.progressFill, style: { width: `${q.progress}%` } }),\n ),\n h('span', { className: styles.queueRowPct }, `${q.progress}%`),\n ),\n )),\n )\n : null,\n ])\n : null,\n records.length === 0\n ? h('div', { className: styles.failEmpty }, t('notificationsEmpty'))\n : h('div', { className: styles.noticeList },\n records.map((r) => {\n const isUpdate = r.kind === 'update'\n // 展示用仓库:历史记录存的可能是裸 npm 包名,反查成 owner/repo 才显示/提 Issue;\n // 查不到为空 → 仓库链接与提 Issue 按钮都不渲染\n const shownRepo = resolveRepo ? (resolveRepo(r.repo) ?? '') : r.repo\n return h('div', {\n key: r.id,\n // 更新提醒:整行可点击直达更新确认弹窗;install/uninstall 记录维持原交互\n className: r.ok\n ? `${styles.noticeRow} ${styles.noticeRowOk}${isUpdate ? ` ${styles.noticeRowUpdate}` : ''}`\n : styles.noticeRow,\n ...(isUpdate ? { onClick: () => onUpdate(r.repo), title: t('updateNoticeGo') } : {}),\n },\n h('div', { className: styles.noticeRowMain },\n h('div', {\n className: r.ok ? styles.noticeBadgeOk : styles.noticeBadgeFail,\n }, h(BadgeGlyph, { ok: r.ok })),\n h('div', { className: styles.noticeMain },\n h('div', { className: styles.noticeHead },\n h('span', {\n className: r.ok ? styles.noticeTextOk : styles.noticeTextFail,\n }, r.ok\n ? (isUpdate ? t('updateNoticeTitle') : (r.kind === 'install' ? t('installDone') : t('uninstallDone')))\n : (r.kind === 'install' ? t('errorTitleInstall') : t('errorTitleUninstall'))),\n // 更新提醒:新版本号紧随标题展示;repo 为纯文本(整行点击即去更新,不跳官网外链)\n isUpdate && r.version\n ? h('span', { className: styles.noticeVersion, title: r.version }, `v${r.version}`)\n : null,\n r.repo\n ? (isUpdate\n ? h('span', { className: styles.failRepo, title: r.repo }, r.repo)\n : shownRepo\n ? h('a', {\n className: styles.failRepo,\n // 跳转到官网详情页(含插件收录信息),不在通知弹窗直接跳 GitHub\n href: pluginSiteUrl(shownRepo),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: shownRepo,\n }, shownRepo)\n : null)\n : null,\n !r.ok && h('button', {\n className: styles.failCopy,\n onClick: () => onCopy(r.message),\n }, t('failCopy')),\n // 成功通知:时间戳并入本行右侧,与图标/文字垂直居中 ——\n // 不再单独占底部一行,卡片只有一行内容,图标文字整体居中不顶头\n r.ok\n ? h('span', {\n className: styles.noticeTime,\n title: new Date(r.at).toLocaleString(),\n }, fmtTime(r.at))\n : null,\n // 更新提醒:行尾「去更新」按钮直达更新确认弹窗(整行也可点击)\n isUpdate\n ? h('button', {\n className: styles.noticeUpdateGo,\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onUpdate(r.repo) },\n }, t('updateNoticeGo'))\n : null,\n // 更新提醒:「忽略本次更新」按钮 —— 先弹确认,确认后本次版本不再提醒\n isUpdate\n ? h('button', {\n className: styles.noticeIgnore,\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onIgnoreUpdate(r.repo, r.version) },\n }, t('ignoreUpdateRun'))\n : null,\n // 每条通知右侧的删除按钮:单独移除这一条\n h('button', {\n className: styles.noticeRemove,\n 'aria-label': t('removeNotification'),\n title: t('removeNotification'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onRemove(r.id) },\n }, h(CloseIcon)),\n ),\n // 每条失败记录是一个独立卡片:头部(状态/仓库/时间/复制完整日志)→ 修复或提 Issue 动作。\n // 卡片不展示错误日志预览,完整日志靠「复制完整日志」按钮带走,避免每条卡片被日志撑高\n !r.ok && (() => {\n const kind = classifyFailure(r.message)\n if (kind === 'npmTooOld') {\n // npm 内部崩溃(edgesOut)+ 本机 npm 版本过低:npm 自身已知缺陷,不是插件问题 ——\n // 直接给升级指引,不引导提 Issue\n const v = npmTooLowVersion(r.message)\n return h('div', { className: styles.failPrepareHint },\n t(v ? 'failNpmTooLowV' : 'failNpmTooLow', v ? { v } : undefined))\n }\n if (kind === 'pluginPrepare' || kind === 'pnpmIgnoredBuild') {\n // [packaging](预检/装后校验拦截:git 分发缺产物)与\n // prepare 构建脚本实际执行失败 / 原生依赖构建被 pnpm 拦截:都是插件打包分发问题 —— 先说明原因,按钮在下方提交\n return h('div', null, [\n h('div', { className: styles.failPrepareHint }, kind === 'pnpmIgnoredBuild'\n ? t('failIgnoredBuild')\n : /\\[packaging\\]/i.test(r.message) ? t('failPackagingHint') : t('failPrepareHint')),\n r.repo && shownRepo ? h('a', {\n className: styles.failBigIssue,\n href: pluginIssueUrl(shownRepo, r.message, env, r.command, r.attempts),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('failIssueHint'),\n }, t('failIssueBig')) : null,\n ])\n }\n return r.repo && shownRepo ? h('a', {\n className: styles.failBigIssue,\n href: pluginIssueUrl(shownRepo, r.message, env, r.command, r.attempts),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('failIssueHint'),\n }, t('failIssueBig')) : null\n })(),\n ),\n ),\n // 失败通知:时间戳保留独立底部行(右下角);成功通知已并入头部行右侧\n !r.ok\n ? h('div', { className: styles.noticeFoot },\n h('span', {\n className: styles.noticeTime,\n title: new Date(r.at).toLocaleString(),\n }, fmtTime(r.at)),\n )\n : null,\n )\n }),\n ),\n h('div', { className: styles.modalActions },\n records.length > 0 ? h('button', {\n className: styles.failClear,\n onClick: onClear,\n }, t('notificationsClear')) : null,\n h('button', { className: styles.restartNow, onClick: onClose }, t('errorClose')),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Section header: brand title row (H1 + open-site button) + tagline, followed\n * by the purple ad banner that promotes the catalog stats.\n */\nimport { createElement as h, Fragment } from 'react'\nimport styles from '../../styles/Header.module.css'\nimport type { Translate } from '../../types.ts'\nimport { GITHUB_URL, PLUGIN_VERSION, SITE_URL } from '../../logic/constants.ts'\nimport { GitHubIcon, LogoIcon } from '../ui/icons.tsx'\n\nexport function CatalogHeader({ t, langPath, statsTotal, statsVerified, onToggleLang, hubUpdate, onVersionClick, onAboutClick }: {\n t: Translate\n langPath: string\n statsTotal: number\n statsVerified: number\n onToggleLang: () => void\n /** Hub 自身是否有可用更新:有则版本号后紧跟红色「可更新」徽标(整体一个可点入口) */\n hubUpdate: boolean\n /** 点击版本号(含红色徽标,同一入口):无论有无更新都打开更新记录弹窗 */\n onVersionClick: () => void\n /** 点击「关注我们」:打开平台介绍 + 用户反馈群二维码弹窗 */\n onAboutClick: () => void\n}) {\n return h(Fragment, null,\n h('div', { className: styles.header },\n // 第一行:logo + 标题(官网链接)与 GitHub 源码图标同行,GitHub 顶到标题行末尾\n h('div', { className: styles.headerTitleRow },\n h('a', {\n className: styles.brandTitle,\n href: `${SITE_URL}${langPath}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('openHint'),\n 'aria-label': t('openHint'),\n },\n h(LogoIcon),\n h('h1', { className: styles.title }, t('title')),\n ),\n // 版本号:紧跟标题「DSH Plugin Hub」之后,常驻可点入口(<a> 内不能嵌套按钮,故从官网链接里移出放在旁边)。\n // 点击打开更新记录弹窗 —— 有更新看新版本内容,无更新看当前版本内容。\n // 有更新时版本号后直接跟一个红色「可更新」徽标(同一按钮内,不分开成两个元素),静态显示不闪烁。\n h('button', {\n className: styles.versionBtn,\n type: 'button',\n onClick: onVersionClick,\n title: t(hubUpdate ? 'hubUpdateHint' : 'versionHint'),\n 'aria-label': t(hubUpdate ? 'hubUpdateHint' : 'versionHint'),\n },\n `v${PLUGIN_VERSION}`,\n hubUpdate && h('span', { className: styles.hubUpdateBadge }, t('update')),\n ),\n // 右侧控件组:语言切换 + GitHub 源码图标(独立链接,brandTitle 是官网 <a> 不能嵌套),\n // 一起 space-between 顶到标题行最右\n h('div', { className: styles.headerRight },\n // 语言切换:按钮文字始终显示「要切到的语言」,点击即切,无需图标\n h('button', {\n className: styles.langBtn,\n type: 'button',\n onClick: onToggleLang,\n title: t('toggleLangHint'),\n 'aria-label': t('toggleLangHint'),\n }, langPath === 'zh/' ? 'EN' : '中文'),\n // 「关注我们」:点击打开平台介绍 + 用户反馈群二维码弹窗\n h('button', {\n className: styles.aboutBtn,\n type: 'button',\n onClick: onAboutClick,\n title: t('aboutDesc'),\n 'aria-label': t('aboutTitle'),\n }, t('followUs')),\n // GitHub 源码图标:独立链接(brandTitle 是官网 <a> 不能嵌套),放在控件组最后\n h('a', {\n className: styles.githubLink,\n href: GITHUB_URL,\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('githubHint'),\n 'aria-label': t('githubHint'),\n }, h(GitHubIcon)),\n ),\n ),\n // 第二行:副标题仍是官网链接,点击跳 dsh-plugin.org\n h('a', {\n className: styles.taglineLink,\n href: `${SITE_URL}${langPath}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n title: t('openHint'),\n },\n h('div', { className: styles.tagline }, t('tagline', { total: statsTotal, verified: statsVerified })),\n ),\n ),\n h('a', {\n className: styles.adBanner,\n href: `${SITE_URL}${langPath}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n },\n h('span', { className: styles.adBadge }, t('adBadge')),\n h('span', { className: styles.adText }, t('ad', { total: statsTotal, verified: statsVerified })),\n h('span', { className: styles.adArrow }, '\\u2197')),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Category tabs: an \"all\" chip followed by one chip per catalog category.\n * The \"all\" chip carries the total plugin count; the per-category chips\n * carry no counts so their widths stay uniform.\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/Header.module.css'\nimport type { LocaleId } from '../../types.ts'\nimport { CATEGORY_ORDER, CATEGORY_SHORT_LABELS, categoryLabel } from '../../logic/constants.ts'\n\nexport function CategoryTabs({ category, setCategory, allLabel, totalCount, langKey }: {\n category: string\n setCategory: (value: string) => void\n allLabel: string\n totalCount: number\n langKey: LocaleId\n}) {\n return h('div', { className: styles.tabs },\n // 第一个按钮固定为「全部」:展示全部分类,直接显示插件总数;\n // 其余分类按钮不带数量,保持排版整齐\n h('button', {\n key: 'all',\n className: category === 'all' ? styles.tabActive : styles.tab,\n onClick: () => setCategory('all'),\n },\n allLabel,\n h('span', { className: styles.tabCount }, totalCount)),\n CATEGORY_ORDER.map((id) => h('button', {\n key: id,\n className: category === id ? styles.tabActive : styles.tab,\n onClick: () => setCategory(id),\n },\n categoryLabel(CATEGORY_SHORT_LABELS, id, langKey))),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Toolbar above the market list:\n * row 1 — full-width search input;\n * row 2 — result count on the left, sort segmented control on the right\n * (mirrors the Installed view: clicking the same sort toggles\n * ascending/descending, a new sort uses its default order; the active\n * button shows an up/down arrow for the current direction).\n */\nimport { createElement as h, Fragment } from 'react'\nimport type { FormEvent, ReactNode } from 'react'\nimport styles from '../../styles/Header.module.css'\nimport type { Translate } from '../../types.ts'\nimport { SORTS } from '../../logic/constants.ts'\nimport type { SortKey } from '../../logic/constants.ts'\nimport { SortArrowIcon } from '../ui/icons.tsx'\n\n/** 单选按钮组中的一个按钮(segmented control,与已安装视图排序按钮同款) */\nfunction SegBtn({ active, onClick, label, icon }: {\n active: boolean\n onClick: () => void\n label: string\n icon?: ReactNode\n}) {\n return h('button', {\n type: 'button',\n className: active ? `${styles.segBtn} ${styles.segBtnActive}` : styles.segBtn,\n 'aria-pressed': active,\n onClick,\n }, label, icon)\n}\n\nexport function CatalogControls({ query, setQuery, sort, sortDir, toggleSort, t, resultText }: {\n query: string\n setQuery: (value: string) => void\n sort: SortKey\n /** 当前排序方向:决定激活排序按钮上的箭头朝上(正序)/朝下(倒序) */\n sortDir: 'asc' | 'desc'\n toggleSort: (value: SortKey) => void\n t: Translate\n resultText: string | null\n}) {\n return h(Fragment, null,\n // 第一行:搜索框占满整行(搜插件名称、描述、标签)\n h('div', { className: styles.searchRow },\n h('input', {\n className: styles.search,\n type: 'search',\n placeholder: t('search'),\n value: query,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) =>\n setQuery((e.target as HTMLInputElement).value),\n }),\n ),\n // 第二行:左侧筛选结果数「结果 N 条插件」(数字等宽预留 5 位不跳动),\n // 右侧排序按钮组(与已安装视图同款 segmented control,激活按钮带正/倒序箭头)\n h('div', { className: styles.controls },\n resultText ? h('span', { className: styles.resultSeg },\n ...resultText.split(/(\\d+)/).map((part, i) =>\n /^\\d+$/.test(part)\n ? h('span', { key: i, className: styles.resultCount }, part)\n : part)) : null,\n h('div', { className: styles.sortGroup },\n h('span', { className: styles.segLabel }, t('sortByLabel')),\n h('div', { className: styles.segGroup, role: 'radiogroup', 'aria-label': t('sortAria') },\n SORTS.map((key) => SegBtn({\n active: sort === key,\n onClick: () => toggleSort(key),\n label: t(key),\n icon: sort === key ? h(SortArrowIcon, { up: sortDir === 'asc' }) : null,\n })),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Incremental list: renders only the first batch of a (potentially huge)\n * result set and appends the next batch whenever the end sentinel scrolls\n * into view, so the plugin center never mounts thousands of cards at once.\n * The items reference is the list identity — category / search / sort\n * changes produce a new array, which resets the window to the first batch.\n */\nimport { useEffect, useRef, useState } from 'react'\n\n/** 首批渲染条数 & 每次滚到底追加的增量(单卡约 80px 高,100 条已远超一屏) */\nconst PAGE_SIZE = 100\n/** 哨兵进入视口底部前 800px 就提前加载下一批,滚到底时无感知衔接 */\nconst PRELOAD_MARGIN = '800px 0px'\n\nexport function useIncrementalList<T>(items: T[]) {\n const [limit, setLimit] = useState(PAGE_SIZE)\n const sentinelRef = useRef<HTMLDivElement | null>(null)\n\n // 筛选/分类/排序变化 → items 引用变化 → 窗口重置回首批\n useEffect(() => {\n setLimit(PAGE_SIZE)\n }, [items])\n\n // 哨兵进入视口(含预加载区)→ 追加下一批;已全部渲染则不再观察\n useEffect(() => {\n const el = sentinelRef.current\n if (!el || limit >= items.length) return\n const io = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) setLimit((cur) => Math.min(cur + PAGE_SIZE, items.length))\n }\n }, { rootMargin: PRELOAD_MARGIN })\n io.observe(el)\n return () => io.disconnect()\n }, [items.length, limit])\n\n return {\n shown: items.slice(0, limit),\n hasMore: limit < items.length,\n sentinelRef,\n }\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * One plugin card in the catalog list: name/category/verified badge,\n * description + topics, star/fork/date stats, and the detail/install/\n * uninstall actions.\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/List.module.css'\nimport type { HubPlugin, LocaleId, Translate } from '../../types.ts'\nimport { CATEGORY_LABELS, categoryLabel } from '../../logic/constants.ts'\nimport { pluginDetailUrl } from '../../logic/urls.ts'\nimport { fmtStars, relTime } from '../../logic/format.ts'\n\nexport function PluginCard({ plugin: p, copied, installedName, installedVersion, hasUpdate, t, langKey, langPath, onInstall, onUninstall }: {\n plugin: HubPlugin\n copied: string | null\n installedName: (p: HubPlugin) => string | null\n /** 已安装版本号(安装时从目录信号记录;无 release 的仓库为空,无版本号可展示) */\n installedVersion: (p: HubPlugin) => string | null\n /** 已安装且目录有更新(有版本比版本、无版本比仓库更新时间) */\n hasUpdate: (p: HubPlugin) => boolean\n t: Translate\n langKey: LocaleId\n langPath: string\n /** 第二个参数标记「更新」(已安装目标的覆盖安装):按钮/弹窗据此走更新语义 */\n onInstall: (p: HubPlugin, opts?: { update?: boolean }) => void\n onUninstall: (p: HubPlugin) => void\n}) {\n const repo = p.source?.repo ?? ''\n const isCopied = copied === repo\n const pkg = installedName(p)\n const isInstalled = pkg !== null\n const update = hasUpdate(p)\n // 版本号展示:已安装 → 当前已装版本(最能反映用户状态);未安装 → 目录最新版本\n const versionShown = isInstalled ? installedVersion(p) : p.version\n\n return h('div', { className: styles.card },\n h('div', { className: styles.cardMain },\n h('div', { className: styles.cardHead },\n h('div', { className: styles.cardTitle, title: p.description ?? '' }, p.displayName ?? p.slug),\n // 版本号紧跟插件名称:有版本才显示(无 release 的仓库不展示版本号)\n versionShown ? h('span', { className: styles.versionBadge, title: t('version') }, versionShown) : null,\n // 已安装且有更新:醒目提示(有 release 比版本号、无 release 比仓库最近更新时间)\n update ? h('span', { className: styles.updateBadge, title: t('updateAvailableHint') }, t('updateAvailable')) : null,\n p.category ? h('span', { className: styles.categoryBadge }, categoryLabel(CATEGORY_LABELS, p.category, langKey)) : null,\n p.compatibility?.status === 'verified'\n ? h('span', { className: styles.verified }, t('verified'))\n : null,\n ),\n // 描述始终显示:站点英文数据缺翻译时 description 回退成中文也照常展示,\n // 描述是了解插件的第一入口,比隐藏更实用(不再为求语言一致而砍内容)。\n p.description ? h('p', { className: styles.desc }, p.description) : null,\n (p.topics?.length ?? 0) > 0\n ? h('div', { className: styles.topics },\n p.topics!.slice(0, 3).map((topic) => h('span', { key: topic, className: styles.topic }, topic)),\n )\n : null,\n ),\n h('div', { className: styles.cardSide },\n h('div', { className: styles.stats },\n h('span', { className: styles.star }, '\\u2605 ', fmtStars(p.stats?.stargazers_count)),\n h('span', { className: styles.fork }, t('fork'), ' ', fmtStars(p.stats?.forks_count)),\n h('span', { className: styles.date }, relTime(p.dates?.repoUpdatedAt, t)),\n ),\n repo\n ? h('div', { className: styles.actions },\n // 查看详情:未安装/已安装都始终显示,跳转官网详情页\n h('a', {\n className: styles.detailBtn,\n // 两级路径:/plugins/{ownerSlug}/{slug};缺 ownerSlug 时从 repo 推导\n href: pluginDetailUrl(p, langPath),\n target: '_blank',\n rel: 'noopener noreferrer',\n title: p.slug,\n }, t('detail')),\n isInstalled\n // 已安装且有更新:按钮变「可更新」,点击直接覆盖安装(安装完成自动记录新版本)\n ? (update\n ? h('button', {\n className: styles.installBtnUpdate,\n title: t('updateAvailableHint'),\n onClick: () => onInstall(p, { update: true }),\n }, t('update'))\n : h('button', {\n className: styles.installBtnInstalled,\n disabled: true,\n title: t('installed'),\n }, t('installed')))\n // 未安装:按钮恒为「安装」,点击先弹信任确认;AI 识别为「可能需要命令行辅助」\n // 的插件(webInstallable=false)不拦截,允许尝试一键安装,弹窗内会给出提示与\n // 复制命令通道,安装失败时引导去 dsh 终端手动执行\n : h('button', {\n className: isCopied ? styles.installBtnCopied : styles.installBtn,\n // 文字恒定避免按钮宽度变化导致卡片跳动;点击先弹信任确认,\n // 弹窗内可选择复制命令或直接安装\n onClick: () => onInstall(p),\n }, t('install')),\n isInstalled\n // 已安装:卸载按钮(危险色),保留明确状态语义\n ? h('button', {\n className: styles.uninstallBtn,\n onClick: () => onUninstall(p),\n }, t('uninstall'))\n : null,\n )\n : null,\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Catalog list: the scrollable container with the loading / failed / empty\n * states, the plugin cards, and the count footer. Resets scroll position when\n * the category or install-status filter changes so the replaced content is\n * not mistaken for a no-op update.\n */\nimport { createElement as h, useEffect, useRef } from 'react'\nimport styles from '../../styles/List.module.css'\nimport type { HubPlugin, LocaleId, Translate } from '../../types.ts'\nimport { SITE_URL } from '../../logic/constants.ts'\nimport { useIncrementalList } from '../../hooks/useIncrementalList.ts'\nimport { PluginCard } from './PluginCard.tsx'\n\nexport function CatalogList({ plugins, failed, visible, total, t, langPath, reload, category, copied, installedName, installedVersion, hasUpdate, langKey, onInstall, onUninstall }: {\n plugins: HubPlugin[] | null\n failed: boolean\n visible: HubPlugin[]\n total: number\n t: Translate\n langPath: string\n reload: () => void\n category: string\n copied: string | null\n installedName: (p: HubPlugin) => string | null\n installedVersion: (p: HubPlugin) => string | null\n hasUpdate: (p: HubPlugin) => boolean\n langKey: LocaleId\n onInstall: (p: HubPlugin, opts?: { update?: boolean }) => void\n onUninstall: (p: HubPlugin) => void\n}) {\n /** 列表滚动容器:分类/搜索切换后列表内容替换但 scrollTop 保留,会让用户误以为列表没更新,需重置回顶部 */\n const listRef = useRef<HTMLDivElement | null>(null)\n /** 增量渲染:全量目录太大(4400+),只渲染首批,滚动接近底部时自动追加下一批 */\n const { shown, hasMore, sentinelRef } = useIncrementalList(visible)\n\n useEffect(() => {\n listRef.current?.scrollTo({ top: 0 })\n }, [category])\n\n return h('div', { className: styles.body },\n h('div', { ref: listRef, className: styles.list },\n plugins === null && !failed && h('div', { className: styles.state }, t('loading')),\n failed && h('div', { className: styles.state },\n h('div', { className: styles.stateTitle }, t('failed')),\n h('div', { className: styles.stateDesc }, t('failedDesc')),\n h('button', { className: styles.retryBtn, onClick: () => reload() }, t('retry')),\n ),\n plugins !== null && !failed && visible.length === 0 && h('div', { className: styles.state },\n h('div', { className: styles.stateTitle }, t('noResult')),\n h('div', { className: styles.stateDesc }, t('noResultDesc')),\n ),\n plugins !== null && !failed && shown.map((p) => h(PluginCard, {\n // 唯一 key:数据重构后同一 slug 可能对应多个作者仓库,仅用 slug 会撞 key,\n // 导致切换分类时 React 复用旧 DOM、列表不刷新。\n key: p.ownerSlug ? `${p.ownerSlug}/${p.slug}` : p.slug,\n plugin: p,\n copied,\n installedName,\n installedVersion,\n hasUpdate,\n t,\n langKey,\n langPath,\n onInstall,\n onUninstall,\n })),\n // 滚动加载哨兵:透明 1px 元素,进入视口即触发下一批渲染(加载是纯追加,无需按钮)\n hasMore && h('div', { ref: sentinelRef, className: styles.moreSentinel, 'aria-hidden': 'true' }),\n ),\n plugins !== null && !failed && h('div', { className: styles.footer },\n h('a', {\n className: styles.footLink,\n href: `${SITE_URL}${langPath}`,\n target: '_blank',\n rel: 'noopener noreferrer',\n }, t('browseAll', { n: total })),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Market view: the browse experience for the catalog — category tabs,\n * search/sort/install-state controls and the plugin list. Owns nothing;\n * it wires catalog state (query/sort/filter/category) to the small\n * presentational components so PluginHubSection stays free of view internals.\n */\nimport { createElement as h, Fragment } from 'react'\nimport type { HubPlugin, LocaleId } from '../../types.ts'\nimport type { useCatalog } from '../../hooks/useCatalog.ts'\nimport { CategoryTabs } from '../layout/CategoryTabs.tsx'\nimport { CatalogControls } from '../layout/CatalogControls.tsx'\nimport { CatalogList } from '../catalog/CatalogList.tsx'\n\ntype CatalogState = ReturnType<typeof useCatalog>\n\nexport function MarketView({ catalog, t, langPath, langKey, copied, resultText, onInstall, onUninstall }: {\n catalog: CatalogState\n t: (key: string, params?: Record<string, string | number>) => string\n langPath: string\n langKey: LocaleId\n copied: string | null\n resultText: string | null\n onInstall: (p: HubPlugin, opts?: { update?: boolean }) => void\n onUninstall: (p: HubPlugin) => void\n}) {\n return h(Fragment, null,\n // 分类行保持原位原样:全部 + 各分类 chips\n h(CategoryTabs, {\n category: catalog.category,\n setCategory: catalog.setCategory,\n allLabel: t('all'),\n totalCount: catalog.total,\n langKey,\n }),\n h(CatalogControls, {\n query: catalog.query,\n setQuery: catalog.setQuery,\n sort: catalog.sort,\n sortDir: catalog.sortDir,\n toggleSort: catalog.toggleSort,\n t,\n resultText,\n }),\n h(CatalogList, {\n plugins: catalog.plugins,\n failed: catalog.failed,\n visible: catalog.visible,\n total: catalog.total,\n t,\n langPath,\n reload: catalog.reload,\n category: catalog.category,\n copied,\n installedName: catalog.installedName,\n installedVersion: catalog.installedVersion,\n hasUpdate: catalog.hasUpdate,\n langKey,\n onInstall,\n onUninstall,\n }),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Primary navigation: a compact segmented control switching between the\n * four top-level sections — Market (browse), Installed (manage), Custom\n * (manual command installs) and Settings (network sources & preferences).\n * Kept visually distinct from the category chips so the hierarchy reads:\n * section → category → plugin.\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/SectionTabs.module.css'\nimport { BellIcon, InstalledIcon, MarketIcon, SettingsIcon, TerminalIcon } from '../ui/icons.tsx'\n\nexport type SectionView = 'market' | 'installed' | 'custom' | 'settings'\n\nconst ORDER: Array<{ id: SectionView; labelKey: string; hintKey: string; Icon: () => ReturnType<typeof h> }> = [\n { id: 'market', labelKey: 'viewMarket', hintKey: 'viewMarketHint', Icon: MarketIcon },\n { id: 'installed', labelKey: 'viewInstalled', hintKey: 'viewInstalledHint', Icon: InstalledIcon },\n { id: 'custom', labelKey: 'viewCustom', hintKey: 'viewCustomHint', Icon: TerminalIcon },\n { id: 'settings', labelKey: 'viewSettings', hintKey: 'viewSettingsHint', Icon: SettingsIcon },\n]\n\nexport function SectionTabs({ view, setView, installedCount, t, noticeCount, onOpenNotifications }: {\n view: SectionView\n setView: (value: SectionView) => void\n installedCount: number\n t: (key: string) => string\n /** 通知中心红圈计数(记录 + 进行中任务 + 待重启);0 时不显示徽标 */\n noticeCount: number\n /** 点击打开通知中心 */\n onOpenNotifications: () => void\n}) {\n return h('div', { className: styles.root, role: 'tablist' },\n ORDER.map(({ id, labelKey, hintKey, Icon }) => h('button', {\n key: id,\n role: 'tab',\n 'aria-selected': view === id,\n title: t(hintKey),\n className: view === id ? styles.tabActive : styles.tab,\n onClick: () => setView(id),\n },\n h('span', { className: styles.tabIcon }, h(Icon)),\n t(labelKey),\n id === 'installed' && installedCount > 0\n ? h('span', { className: view === id ? styles.tabCountActive : styles.tabCount }, installedCount)\n : null)),\n // 通知入口:设置在最后一个 tab 后边,靠右对齐 —— 铃铛 + 红底白字计数(内联跟在铃铛后,不悬浮)\n h('button', {\n type: 'button',\n className: styles.noticeBtn,\n onClick: onOpenNotifications,\n title: t('notificationsHint'),\n 'aria-label': t('notificationsHint'),\n },\n h('span', { className: styles.noticeIcon }, h(BellIcon)),\n noticeCount > 0 ? h('span', { className: styles.noticeCount }, noticeCount > 99 ? '99+' : String(noticeCount)) : null),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Installed view: manages the plugins installed into the current profile.\n * Follows the mainstream extension-manager pattern (VSCode Installed tab) —\n * a searchable, sortable list of installed entries that mixes catalog\n * plugins (full metadata) and custom command installs (outside the catalog,\n * only runtime info, tagged with a custom badge). The toolbar carries a\n * search box plus two segmented radio-button groups: source filter\n * (all / catalog / custom) and sort (name / recently installed / stars / forks).\n * Each row carries restart (when pending), update and uninstall actions\n * and opens a detail modal with the full install metadata.\n *\n * Pure presentational: owns only local search/sort state; the InstalledItem\n * model arrives from the catalog hook and actions bubble up via callbacks.\n */\nimport { createElement as h, useMemo, useState } from 'react'\nimport type { FormEvent, MouseEvent, ReactNode } from 'react'\nimport styles from '../../styles/InstalledView.module.css'\nimport type { LocaleId, Translate } from '../../types.ts'\nimport type { InstalledItem } from '../../logic/installed.ts'\nimport { CATEGORY_LABELS, categoryLabel } from '../../logic/constants.ts'\nimport { SortArrowIcon } from '../ui/icons.tsx'\n\nconst INSTALLED_SORTS = ['sortName', 'sortInstalledAt', 'sortStars', 'sortForks'] as const\ntype InstalledSortKey = (typeof INSTALLED_SORTS)[number]\n\n/** 各排序的默认方向:名称按字母正序,最近安装 / Star / Fork 按数值倒序 */\nconst SORT_DEFAULT_DIR: Record<InstalledSortKey, 'asc' | 'desc'> = {\n sortName: 'asc', sortInstalledAt: 'desc', sortStars: 'desc', sortForks: 'desc',\n}\n\n/** 已安装列表的来源筛选:全部 / 目录收录 / 自定义安装 */\ntype SourceFilter = 'all' | 'catalog' | 'custom'\n\n/** 单选按钮组中的一个按钮(segmented control,与排序/来源筛选共用);\n 可带尾随图标(排序按钮激活时显示当前方向箭头) */\nfunction SegBtn({ active, onClick, label, icon }: {\n active: boolean\n onClick: () => void\n label: string\n icon?: ReactNode\n}) {\n return h('button', {\n type: 'button',\n className: active ? `${styles.segBtn} ${styles.segBtnActive}` : styles.segBtn,\n 'aria-pressed': active,\n onClick,\n }, label, icon)\n}\n\nfunction InstalledRow({ item, t, langKey, canReveal, revealLabel, onOpenDetail, onReveal, onUpdate, onUninstall, onRestart }: {\n item: InstalledItem\n t: Translate\n langKey: LocaleId\n /** 系统文件管理器可定位安装目录的平台(macOS / Linux):行内显示打开目录按钮 */\n canReveal: boolean\n /** 打开目录按钮文案(macOS = 在 Finder 中显示,Linux = 在文件夹中显示) */\n revealLabel: string\n onOpenDetail: (item: InstalledItem) => void\n /** 在系统文件管理器里定位安装目录(macOS Finder / Linux 文件管理器) */\n onReveal: (item: InstalledItem) => void\n onUpdate: (item: InstalledItem) => void\n onUninstall: (item: InstalledItem) => void\n /** 重启宿主:仅待重启(装完未挂载)条目展示,重启后该插件才生效 */\n onRestart: () => void\n}) {\n const name = item.plugin?.displayName ?? item.name\n const repo = item.repo\n const category = item.plugin?.category\n const desc = item.plugin?.description\n // 命令行安装进来的插件没有目录元数据(plugin === null):列表里打「自定义安装」标签区分\n const isCustom = item.plugin === null\n return h('li', {\n className: styles.row,\n onClick: () => onOpenDetail(item),\n role: 'button',\n tabIndex: 0,\n title: t('detail'),\n onKeyDown: (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n onOpenDetail(item)\n }\n },\n },\n // 第一行:状态点 + 名称/版本/更新徽标 + 行尾来源标签列 + 右侧固定操作按钮组\n h('div', { className: styles.rowTitleLine },\n // 运行状态点:绿 = 已加载进 loader;橙 = 待重启(装完未挂载的 dsh 插件);\n // 灰 = 非 dsh 插件(如官方示例项目,宿主不加载,无需重启)\n h('span', {\n className: item.loaded ? styles.statusDot\n : item.dshCapable ? `${styles.statusDot} ${styles.statusPending}`\n : `${styles.statusDot} ${styles.statusInactive}`,\n title: item.loaded ? t('statusRunning')\n : item.dshCapable ? t('statusPending')\n : t('exampleHint'),\n 'aria-label': item.loaded ? t('statusRunning')\n : item.dshCapable ? t('statusPending')\n : t('exampleHint'),\n }),\n // 主信息:名称 + 已装版本 + 有更新徽标(flex 撑满,超长省略)\n h('div', { className: styles.rowMain },\n h('span', { className: styles.rowTitle }, name),\n item.installedVersion\n ? h('span', { className: styles.versionBadge, title: t('installedVersionLabel') }, item.installedVersion)\n : null,\n item.hasUpdate\n ? h('span', { className: styles.updateBadge, title: t('updateAvailableHint') }, t('updateAvailable'))\n : null,\n ),\n // 来源标签列(行尾、操作按钮前,右对齐固定):目录插件 →「插件中心」(品牌色),\n // 命令行安装 →「手动安装」(琥珀色);两词 4 字等宽,所有条目标签同列对齐\n h('span', {\n className: isCustom\n ? `${styles.rowSourceTag} ${styles.rowSourceTagManual}`\n : `${styles.rowSourceTag} ${styles.rowSourceTagHub}`,\n title: isCustom ? t('manualInstallHint') : t('hubInstallHint'),\n }, isCustom ? t('manualInstall') : t('hubInstall')),\n // 行操作:重启(dsh 插件待重启时)/ 详情 / 更新(有更新时)/ 卸载 —— 按钮点击不触发行打开详情\n h('div', { className: styles.rowActions },\n // 装完未挂载的 dsh 插件:给「重启」入口,点了宿主重启后插件即生效;非 dsh 插件不提示(重启无用)\n !item.loaded && item.dshCapable\n ? h('button', {\n className: styles.rowRestart,\n type: 'button',\n title: t('restartPendingHint'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onRestart() },\n }, t('restart'))\n : null,\n // 支持文件管理器定位的平台(macOS / Linux):行内该位改为打开安装目录按钮;\n // 行点击本身即打开详情弹窗,故不支持的平台(如 Windows)不显示此按钮\n canReveal\n ? h('button', {\n className: styles.rowDetail,\n type: 'button',\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onReveal(item) },\n }, revealLabel)\n : null,\n item.hasUpdate && item.plugin\n ? h('button', {\n className: styles.rowUpdate,\n type: 'button',\n title: t('updateAvailableHint'),\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onUpdate(item) },\n }, t('update'))\n : null,\n h('button', {\n className: styles.rowUninstall,\n type: 'button',\n onClick: (e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onUninstall(item) },\n }, t('uninstall')),\n ),\n ),\n // 示例项目徽标单独一行(非 dsh 插件):标签较长也能完整显示,不挤压名称行\n !item.dshCapable\n ? h('div', { className: styles.exampleRow },\n h('span', { className: styles.exampleBadge, title: t('exampleHint') }, t('exampleLabel')),\n )\n : null,\n // 第二行:仓库 · 分类(与名称左对齐缩进,独立成行不再挤压名称)\n repo || category\n ? h('div', { className: styles.rowMeta },\n item.repo ? h('span', { className: styles.rowRepo }, item.repo) : null,\n category ? h('span', { className: styles.rowCategory },\n categoryLabel(CATEGORY_LABELS, category, langKey)) : null,\n )\n : null,\n // 第三行(仅目录插件):简介单独一行展示,超长以省略号收尾\n desc ? h('div', { className: styles.rowDesc, title: desc }, desc) : null,\n )\n}\n\n/** 行列表:单个已安装列表(自定义安装与目录插件混排,靠徽标区分)。 */\nfunction RowList({ items, t, langKey, canReveal, revealLabel, onOpenDetail, onReveal, onUpdate, onUninstall, onRestart }: {\n items: InstalledItem[]\n t: Translate\n langKey: LocaleId\n canReveal: boolean\n revealLabel: string\n onOpenDetail: (item: InstalledItem) => void\n onReveal: (item: InstalledItem) => void\n onUpdate: (item: InstalledItem) => void\n onUninstall: (item: InstalledItem) => void\n onRestart: () => void\n}) {\n return h('ul', { className: styles.list },\n items.map((item) => h(InstalledRow, {\n key: item.name,\n item,\n t,\n langKey,\n canReveal,\n revealLabel,\n onOpenDetail,\n onReveal,\n onUpdate,\n onUninstall,\n onRestart,\n })),\n )\n}\n\nexport function InstalledView({ items, t, langKey, platform, onOpenDetail, onReveal, onUpdate, onUninstall, onRestart }: {\n items: InstalledItem[]\n t: Translate\n langKey: LocaleId\n /** 宿主系统平台(node process.platform):支持文件管理器定位(macOS / Linux)时行内显示打开目录按钮 */\n platform: string\n onOpenDetail: (item: InstalledItem) => void\n onReveal: (item: InstalledItem) => void\n /** 更新:仅目录插件且有更新时触发(自定义安装无目录信号可比) */\n onUpdate: (item: InstalledItem) => void\n onUninstall: (item: InstalledItem) => void\n /** 重启宿主:待重启条目行内按钮触发(装完未挂载的插件重启后生效) */\n onRestart: () => void\n}) {\n const [query, setQuery] = useState('')\n /** 默认按「最近安装」排序(最新在前);点其他排序按钮用该排序的默认方向(Star/Fork 最多在前、名称正序) */\n const [sort, setSort] = useState<InstalledSortKey>('sortInstalledAt')\n /** 当前排序方向:点同一个排序按钮切换 正/倒序;点新排序用该排序的默认方向 */\n const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc')\n /** 已安装列表的来源筛选:全部 / 目录收录 / 自定义安装(单选按钮组) */\n const [sourceFilter, setSourceFilter] = useState<SourceFilter>('all')\n\n /** 点击排序按钮:同一按钮切换正/倒序,新按钮用默认方向 */\n function pickSort(key: InstalledSortKey) {\n if (key === sort) setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))\n else { setSort(key); setSortDir(SORT_DEFAULT_DIR[key]) }\n }\n\n // 搜索 + 排序后的展示列表:搜索命中名称/包名/仓库/描述;排序支持名称/最近安装/Star/Fork\n const list = useMemo(() => {\n const q = query.trim().toLowerCase()\n const filtered = items.filter((item) => {\n if (!q) return true\n return (item.plugin?.displayName ?? item.name).toLowerCase().includes(q)\n || item.name.toLowerCase().includes(q)\n || (item.repo ?? '').toLowerCase().includes(q)\n || (item.plugin?.description ?? '').toLowerCase().includes(q)\n })\n const dir = sortDir === 'asc' ? 1 : -1\n return [...filtered].sort((a, b) => {\n if (sort === 'sortName') return (a.plugin?.displayName ?? a.name).localeCompare(b.plugin?.displayName ?? b.name) * dir\n // Star / Fork:目录插件按数量比较(正/倒序随 dir);自定义安装(无目录数据,stats 缺失)永远排最后\n if (sort === 'sortStars' || sort === 'sortForks') {\n const metric = sort === 'sortStars' ? 'stargazers_count' : 'forks_count'\n const sa = a.plugin?.stats?.[metric]\n const sb = b.plugin?.stats?.[metric]\n if (sa == null && sb == null) return 0\n if (sa == null) return 1\n if (sb == null) return -1\n return (sa - sb) * dir\n }\n // 最近安装:按安装时间比较;无安装时间记录的永远排最后\n const av = a.installedAt ?? ''\n const bv = b.installedAt ?? ''\n if (av === bv) return 0\n if (av === '') return 1\n if (bv === '') return -1\n return av.localeCompare(bv) * dir\n })\n }, [items, query, sort, sortDir])\n\n const catalogItems = list.filter((item) => item.plugin !== null)\n const customItems = list.filter((item) => item.plugin === null)\n // 已安装列表:搜索 + 排序后,再按来源筛选(全部 / 目录收录 / 自定义安装)\n const filtered = sourceFilter === 'all' ? list\n : sourceFilter === 'catalog' ? catalogItems : customItems\n\n // 行列表公共参数:macOS 文案特指 Finder,Windows / Linux 用通用「在文件夹中显示」\n const rowListProps = {\n t, langKey,\n canReveal: platform === 'darwin' || platform === 'win32' || platform === 'linux',\n revealLabel: platform === 'darwin' ? t('revealFolder') : t('openFolder'),\n onOpenDetail, onReveal, onUpdate, onUninstall, onRestart,\n }\n\n // 工具栏:第一行搜索框撑满,第二行来源筛选按钮组 + 排序按钮组(单选按钮组形态)\n const listToolbar = h('div', { className: styles.toolbar },\n h('div', { className: styles.searchWrap },\n h('input', {\n className: styles.searchInput,\n type: 'search',\n placeholder: t('installedSearch'),\n value: query,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) =>\n setQuery((e.target as HTMLInputElement).value),\n }),\n ),\n h('div', { className: styles.segRow },\n h('span', { className: styles.segLabel }, t('filterByLabel')),\n h('div', { className: styles.segGroup, role: 'radiogroup', 'aria-label': t('filterByLabel') },\n SegBtn({ active: sourceFilter === 'all', onClick: () => setSourceFilter('all'), label: t('all') }),\n SegBtn({ active: sourceFilter === 'catalog', onClick: () => setSourceFilter('catalog'), label: t('installedFilterCatalog') }),\n SegBtn({ active: sourceFilter === 'custom', onClick: () => setSourceFilter('custom'), label: t('customLabel') }),\n ),\n h('span', { className: styles.segLabel }, t('sortByLabel')),\n h('div', { className: styles.segGroup, role: 'radiogroup', 'aria-label': t('sortAria') },\n INSTALLED_SORTS.map((key) => SegBtn({\n active: sort === key,\n onClick: () => pickSort(key),\n label: t(key),\n icon: sort === key ? h(SortArrowIcon, { up: sortDir === 'asc' }) : null,\n })),\n ),\n ),\n )\n\n return h('div', { className: styles.root },\n listToolbar,\n // 筛选后的列表;一个都没装 → 引导空态,搜索/筛选无结果 → 无结果空态\n filtered.length === 0\n ? items.length === 0\n ? h('div', { className: styles.empty },\n h('div', { className: styles.emptyTitle }, t('installedEmpty')),\n h('div', { className: styles.emptyDesc }, t('installedEmptyDesc')),\n )\n : h('div', { className: styles.empty },\n h('div', { className: styles.emptyTitle }, t('noResult')),\n h('div', { className: styles.emptyDesc }, t('noResultDesc')),\n )\n : h(RowList, { items: filtered, ...rowListProps }),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Custom install view: a standalone top-level section for manually\n * installing npm packages or GitHub sources outside the catalog. Three\n * installer cards, one per channel — npm package (bare name or a full\n * npm/pnpm install command, including the official global `npm install -g`),\n * GitHub source and the official `dsh plugin ... add <target>` command —\n * each with a placeholder example above the input and its own format check.\n * The cards stay separate so a user never has to guess which format goes\n * where. Finished installs surface in the Installed view, marked as custom.\n *\n * Pure presentational: owns only the three local input/error states; the\n * actual install (custom source, gated by the security toggles) bubbles up\n * via onInstallCustom.\n */\nimport { createElement as h, useState } from 'react'\nimport type { FormEvent, MouseEvent } from 'react'\nimport styles from '../../styles/CustomInstallView.module.css'\nimport modal from '../../styles/Modal.module.css'\nimport type { Translate } from '../../types.ts'\nimport { CloseIcon, HelpIcon } from '../ui/icons.tsx'\n\n/* —— 自定义安装输入预检 ——\n * 提交前校验「输入是否符合该通道格式」,识别不了的输入不发请求,就地提示推荐格式。\n * 三个通道严格分开:npm 框认裸包名或完整 npm/pnpm 安装命令(含全局 `npm install -g`),\n * git 框只认 GitHub 地址,命令框只认官方 `dsh plugin --profile <name> add <target>`(--profile 必填,无 -p 简写)。\n * 这里只做格式校验,真正归一化/安装由服务端完成。 */\n\n/** GitHub 地址(带前缀形态):github:、https://github.com/、git+https://github.com/、git@github.com: */\nconst GITHUB_URL_RE = /^(?:github:|https?:\\/\\/github\\.com\\/|git\\+https?:\\/\\/github\\.com\\/|git@github\\.com:)([A-Za-z0-9._-]+)\\/([A-Za-z0-9._-]+?)(?:\\.git)?$/\n/** 裸 owner/repo(npm 包名只有 @scope/pkg 才带斜杠,无 @ 前缀的 a/b 一定是 GitHub 仓库) */\nconst GITHUB_BARE_RE = /^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$/\n/** npm 包名(含 @scope/pkg) */\nconst NPM_PACKAGE_RE = /^(?:@[a-z0-9._-]+\\/)?[a-z0-9._-]+$/\n\n/** DSH 命令行前缀(官方唯一形式 `dsh plugin --profile <name> add <target>`)—— 提取其中的安装目标。\n * 官方 CLI(apps/cli/src/args.ts,commander):--profile 为必填长选项(无 -p 简写,省略即报错),\n * 支持 `--profile=<name>` 等号形式;命令大小写不敏感。与 server 端 installTargetOf 口径一致。 */\nconst DSH_PLUGIN_CMD_RE = /^dsh\\s+plugin\\s+--profile(?:\\s+|=)\\S+\\s+add\\s+(.+)$/i\n\n/** npm 全局安装命令(官方 README 格式,如 `npm install -g @deepseek-ai/dsh @deepseek-harness-tui/dsh-tui`)——\n * 提取 -g 之后的包列表;任一包名非法返回 null(交给格式错误提示)。与 server 端 globalNpmPackagesOf 口径一致。 */\nconst NPM_GLOBAL_CMD_RE = /^npm\\s+(?:install|i)\\s+(?:-g|--global)\\s+(.+)$/i\n\n/** 常规 npm/pnpm 安装命令(装进当前 profile,如 `npm install lodash`、`pnpm add @scope/pkg`)——\n * 提取命令后的包列表;包列表在 splitPackages 里逐个校验。 */\nconst NPM_INSTALL_CMD_RE = /^(?:npm\\s+(?:install|i)|pnpm\\s+(?:add|i|install))\\s+(.+)$/i\n\nfunction installTargetOf(raw: string): string {\n const input = raw.trim()\n const match = DSH_PLUGIN_CMD_RE.exec(input)\n return match !== null ? match[1].trim() : input\n}\n\n/** 空格分隔的包列表:逐个按 npm 包名语法校验 + 拒绝以 - 开头的 token(npm 会把 --xxx 当参数而非包名),\n * 任一非法返回 null(交给格式错误提示)。与 server 端 globalNpmPackagesOf 同口径。 */\nfunction splitPackages(raw: string): string[] | null {\n const packages = raw.trim().split(/\\s+/).filter((p) => p !== '')\n if (packages.length === 0 || packages.some((p) => !NPM_PACKAGE_RE.test(p) || p.startsWith('-'))) return null\n return packages\n}\n\n/** NPM 框输入解析结果:\n * - pkg:裸包名或常规安装命令(npm install / npm i / pnpm add / pnpm i),提取单个安装目标;\n * - global:官方全局安装命令(npm install -g <pkgs>),提取包列表走全局通道。 */\ntype NpmInputParse =\n | { kind: 'pkg'; target: string }\n | { kind: 'global'; pkgs: string[] }\n\nfunction parseNpmInput(raw: string): NpmInputParse | null {\n const input = raw.trim()\n // 裸包名(含 @scope/pkg)\n if (NPM_PACKAGE_RE.test(input)) return { kind: 'pkg', target: input }\n // 官方全局安装 npm install -g <pkgs>(装系统级 CLI 工具)\n const global = NPM_GLOBAL_CMD_RE.exec(input)\n if (global !== null) {\n const pkgs = splitPackages(global[1])\n if (pkgs !== null) return { kind: 'global', pkgs }\n return null\n }\n // 常规安装命令 npm install <pkgs> / pnpm add <pkgs> —— 装进当前 profile,一次一个包\n const install = NPM_INSTALL_CMD_RE.exec(input)\n if (install !== null) {\n const pkgs = splitPackages(install[1])\n if (pkgs !== null && pkgs.length === 1) return { kind: 'pkg', target: pkgs[0] }\n return null\n }\n return null\n}\n\nfunction isGitHubInput(raw: string): boolean {\n const input = raw.trim()\n return GITHUB_URL_RE.test(input) || GITHUB_BARE_RE.test(input)\n}\n\nfunction isDshCommand(raw: string): boolean {\n return DSH_PLUGIN_CMD_RE.test(raw.trim())\n}\n\n/** 卡片标题旁的「帮助」弹窗:三块卡片各自的标题与格式清单语言包 key。 */\nconst HELP_CARDS = {\n npm: { titleKey: 'npmInstallLabel', contentKey: 'npmInstallHelp' },\n git: { titleKey: 'gitInstallLabel', contentKey: 'gitInstallHelp' },\n cmd: { titleKey: 'dshCmdLabel', contentKey: 'dshCmdHelp' },\n} as const\n\ntype HelpTarget = keyof typeof HELP_CARDS\n\nexport function CustomInstallView({ t, onInstallCustom, enableNpm, enableGit, enableDsh, onOpenSettings }: {\n t: Translate\n /** 命令行安装:输入 npm 包名 / npm、pnpm 安装命令 / GitHub 地址 / dsh plugin 命令即装\n * (custom 源,受安全设置开关控制);opts.globalNpm 表示官方 npm 全局安装命令(npm install -g),附带解析出的包列表 */\n onInstallCustom: (raw: string, opts?: { globalNpm?: string[] }) => void\n /** 安全信任三通道开关:关掉后对应输入卡片禁用(不提交),并引导去设置打开 */\n enableNpm: boolean\n enableGit: boolean\n enableDsh: boolean\n /** 引导去「设置 → 安全信任」打开被关闭的通道开关 */\n onOpenSettings: () => void\n}) {\n /** 自定义安装:NPM 包输入与格式错误('' = 无错误) */\n const [npmQuery, setNpmQuery] = useState('')\n const [npmError, setNpmError] = useState('')\n /** 自定义安装:GitHub 源码输入与格式错误('' = 无错误) */\n const [gitQuery, setGitQuery] = useState('')\n const [gitError, setGitError] = useState('')\n /** 自定义安装:DSH 命令输入与格式错误('' = 无错误) */\n const [cmdQuery, setCmdQuery] = useState('')\n const [cmdError, setCmdError] = useState('')\n /** 卡片标题旁「帮助」弹窗:null = 未打开;'npm' | 'git' | 'cmd' = 打开对应卡片的格式清单 */\n const [helpFor, setHelpFor] = useState<HelpTarget | null>(null)\n\n /** 通道关闭提示行:开关关掉后替代示例与输入行,引导去设置打开 */\n const channelOffRow = h('div', { className: styles.channelOff },\n h('span', { className: styles.channelOffText }, t('channelDisabledHint')),\n h('button', {\n type: 'button',\n className: styles.channelOffBtn,\n onClick: onOpenSettings,\n }, t('goToSettings')),\n )\n\n // 三个通道分开校验 —— 识别不了的输入不发请求,就地提示推荐写法。\n // NPM 框认裸包名或完整 npm/pnpm 命令(含全局 npm install -g,走 globalNpm 通道);\n // 命令框只认官方 dsh plugin 命令,提交时剥成裸目标发给服务端。\n const submitNpm = () => {\n const raw = npmQuery.trim()\n if (!raw) return\n const parsed = parseNpmInput(raw)\n if (parsed === null) { setNpmError(t('npmInstallInvalid')); return }\n if (parsed.kind === 'global') {\n onInstallCustom(raw, { globalNpm: parsed.pkgs })\n } else {\n onInstallCustom(parsed.target)\n }\n setNpmQuery('')\n setNpmError('')\n }\n const submitGit = () => {\n const target = gitQuery.trim()\n if (!target) return\n if (!isGitHubInput(target)) { setGitError(t('gitInstallInvalid')); return }\n onInstallCustom(target)\n setGitQuery('')\n setGitError('')\n }\n const submitCmd = () => {\n const raw = cmdQuery.trim()\n if (!raw) return\n if (!isDshCommand(raw)) { setCmdError(t('dshCmdInvalid')); return }\n onInstallCustom(installTargetOf(raw))\n setCmdQuery('')\n setCmdError('')\n }\n\n return h('div', { className: styles.root },\n // 页面说明:独立一级导航,交代「装完去哪看」\n h('p', { className: styles.desc }, t('customViewDesc')),\n // 三块卡片(一行一个):label + 文本框上方示例 + 输入行 + 错误区;\n // 安全信任开关关掉对应通道时,卡片禁用并显示「前往设置」提示行\n h('div', { className: styles.installCards },\n // NPM 包:输入包名或原生 npm/pnpm 安装命令即装(含官方全局 npm install -g)\n h('div', { className: enableNpm ? styles.installCard : `${styles.installCard} ${styles.installCardDisabled}` },\n h('div', { className: styles.installCardHead },\n h('span', { className: styles.installLabel }, t('npmInstallLabel')),\n // 标题旁帮助:点开该卡片的格式清单弹窗\n h('button', {\n type: 'button',\n className: styles.installHelpBtn,\n title: t('installHelp'),\n 'aria-label': t('installHelp'),\n onClick: () => setHelpFor('npm'),\n }, h(HelpIcon)),\n ),\n !enableNpm\n ? channelOffRow\n : [\n // 文本框上方的示例:把支持的原生命令模式写清楚(两行)\n h('div', { className: styles.installExample },\n t('npmInstallExample'), h('br'), t('npmInstallExample2')),\n h('div', { className: styles.installRow },\n h('input', {\n className: npmError ? `${styles.installInput} ${styles.installInputError}` : styles.installInput,\n type: 'text',\n placeholder: t('npmInstallPlaceholder'),\n value: npmQuery,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) => {\n setNpmQuery((e.target as HTMLInputElement).value)\n // 重新输入即清掉格式错误提示\n setNpmError('')\n },\n onKeyDown: (e: KeyboardEvent) => { if (e.key === 'Enter') submitNpm() },\n }),\n h('button', {\n className: styles.installBtn,\n type: 'button',\n disabled: npmQuery.trim() === '',\n onClick: submitNpm,\n }, t('installCliBtn')),\n ),\n // 格式错误:识别不了的包名就地说明,并给出推荐写法\n npmError ? h('div', { className: styles.installError }, npmError) : null,\n ],\n ),\n // GitHub 源码:输入仓库地址即装\n h('div', { className: enableGit ? styles.installCard : `${styles.installCard} ${styles.installCardDisabled}` },\n h('div', { className: styles.installCardHead },\n h('span', { className: styles.installLabel }, t('gitInstallLabel')),\n h('button', {\n type: 'button',\n className: styles.installHelpBtn,\n title: t('installHelp'),\n 'aria-label': t('installHelp'),\n onClick: () => setHelpFor('git'),\n }, h(HelpIcon)),\n ),\n !enableGit\n ? channelOffRow\n : [\n h('div', { className: styles.installExample }, t('gitInstallExample')),\n h('div', { className: styles.installRow },\n h('input', {\n className: gitError ? `${styles.installInput} ${styles.installInputError}` : styles.installInput,\n type: 'text',\n placeholder: t('gitInstallPlaceholder'),\n value: gitQuery,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) => {\n setGitQuery((e.target as HTMLInputElement).value)\n setGitError('')\n },\n onKeyDown: (e: KeyboardEvent) => { if (e.key === 'Enter') submitGit() },\n }),\n h('button', {\n className: styles.installBtn,\n type: 'button',\n disabled: gitQuery.trim() === '',\n onClick: submitGit,\n }, t('installCliBtn')),\n ),\n gitError ? h('div', { className: styles.installError }, gitError) : null,\n ],\n ),\n // 命令卡片:粘贴官方 dsh plugin 命令即装 —— 只认完整命令(--profile 必填,可含 = 等号,剥成裸目标安装)\n h('div', { className: enableDsh ? styles.installCard : `${styles.installCard} ${styles.installCardDisabled}` },\n h('div', { className: styles.installCardHead },\n h('span', { className: styles.installLabel }, t('dshCmdLabel')),\n h('button', {\n type: 'button',\n className: styles.installHelpBtn,\n title: t('installHelp'),\n 'aria-label': t('installHelp'),\n onClick: () => setHelpFor('cmd'),\n }, h(HelpIcon)),\n ),\n !enableDsh\n ? channelOffRow\n : [\n h('div', { className: styles.installExample }, t('dshCmdExample')),\n h('div', { className: styles.installRow },\n h('input', {\n className: cmdError ? `${styles.installInput} ${styles.installInputError}` : styles.installInput,\n type: 'text',\n placeholder: t('dshCmdPlaceholder'),\n value: cmdQuery,\n spellCheck: false,\n onInput: (e: FormEvent<HTMLInputElement>) => {\n setCmdQuery((e.target as HTMLInputElement).value)\n setCmdError('')\n },\n onKeyDown: (e: KeyboardEvent) => { if (e.key === 'Enter') submitCmd() },\n }),\n h('button', {\n className: styles.installBtn,\n type: 'button',\n disabled: cmdQuery.trim() === '',\n onClick: submitCmd,\n }, t('installCliBtn')),\n ),\n cmdError ? h('div', { className: styles.installError }, cmdError) : null,\n ],\n ),\n ),\n // 帮助弹窗:点卡片标题旁的问号打开 —— 宽窗(720px)把该通道支持的命令格式整行展示,防止折行\n helpFor !== null\n ? h('div', {\n className: modal.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) setHelpFor(null) },\n },\n h('div', { className: `${modal.errorModal} ${modal.helpModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: modal.modalHead },\n h('div', { className: modal.modalTitle }, `${t(HELP_CARDS[helpFor].titleKey)} · ${t('helpModalTitle')}`),\n h('button', {\n className: modal.modalClose,\n 'aria-label': t('errorClose'),\n onClick: () => setHelpFor(null),\n }, h(CloseIcon)),\n ),\n h('div', { className: modal.modalBody },\n // 格式清单:一行一条;`命令\\t说明` 的说明跟在命令后,纯说明行以 \\t 开头\n h('div', { className: styles.helpBody },\n t(HELP_CARDS[helpFor].contentKey).split('\\n').map((line, i) => {\n const [cmd, note] = line.split('\\t')\n return h('div', { key: i, className: styles.helpLine },\n cmd !== '' ? h('span', { className: styles.helpCmd }, cmd) : null,\n note !== undefined ? h('span', { className: styles.helpNote }, note) : null,\n )\n }),\n ),\n ),\n ),\n )\n : null,\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Button-style dropdown (native <select> replacement).\n *\n * The trigger is a compact toolbar button — hairline border + subtle grey\n * fill + current value + chevron — so it sits naturally next to the other\n * toolbar buttons and takes a single slot of horizontal space. Clicking\n * outside or pressing Esc closes the panel; options get a hover fill and\n * the active one a brand highlight, all driven by the --hub-* tokens.\n */\nimport { createElement as h, useEffect, useRef, useState } from 'react'\nimport type { JSX } from 'react'\nimport styles from '../../styles/Dropdown.module.css'\nimport { ChevronDownIcon } from './icons.tsx'\n\nexport interface DropdownOption<T extends string> {\n value: T\n label: string\n /** 可选计数徽标(如「已安装 12」) */\n count?: number\n}\n\ninterface DropdownProps<T extends string> {\n value: T\n options: DropdownOption<T>[]\n onChange: (value: T) => void\n title?: string\n /** 额外挂到根节点上的类名(如 margin 微调) */\n className?: string\n}\n\nexport function Dropdown<T extends string>({ value, options, onChange, title, className }: DropdownProps<T>): JSX.Element {\n const [open, setOpen] = useState(false)\n const rootRef = useRef<HTMLDivElement | null>(null)\n\n // 面板展开时:点面板外部或按 Esc 关闭。\n useEffect(() => {\n if (!open) return\n const onDoc = (e: MouseEvent) => {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false)\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('mousedown', onDoc)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onDoc)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n const current = options.find((o) => o.value === value)\n\n return h('div', {\n className: className ? `${styles.dropdown} ${className}` : styles.dropdown,\n ref: rootRef,\n },\n h('button', {\n className: styles.dropdownBtn,\n type: 'button',\n title,\n 'aria-haspopup': 'listbox',\n 'aria-expanded': open,\n onClick: () => setOpen((v) => !v),\n },\n h('span', { className: styles.dropdownLabel }, current?.label ?? value),\n h('span', { className: open ? styles.dropdownArrowOpen : styles.dropdownArrow }, h(ChevronDownIcon)),\n ),\n open && h('div', { className: styles.dropdownPanel, role: 'listbox' },\n options.map((o) => h('button', {\n key: o.value,\n type: 'button',\n role: 'option',\n 'aria-selected': o.value === value,\n className: o.value === value ? styles.dropdownItemActive : styles.dropdownItem,\n onClick: () => {\n onChange(o.value)\n setOpen(false)\n },\n },\n h('span', { className: styles.dropdownItemLabel }, o.label),\n typeof o.count === 'number'\n ? h('span', { className: o.value === value ? styles.dropdownCountActive : styles.dropdownCount }, o.count)\n : null,\n )),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Compact switch used by the settings rows. Native-button based so it is\n * keyboard focusable and announces state via aria-checked; styling driven\n * by the --hub-* tokens (on = brand fill, off = neutral track).\n */\nimport { createElement as h } from 'react'\nimport styles from '../../styles/Toggle.module.css'\n\nexport function Toggle({ checked, onChange, title, disabled }: {\n checked: boolean\n onChange: (next: boolean) => void\n title?: string\n disabled?: boolean\n}) {\n return h('button', {\n type: 'button',\n role: 'switch',\n 'aria-checked': checked,\n disabled,\n title,\n className: checked ? styles.toggleOn : styles.toggle,\n onClick: () => onChange(!checked),\n }, h('span', { className: styles.knob }))\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * System diagnostics list: one row per connectivity channel (npm registry /\n * GitHub API / catalog site), each with a live status badge — 200 OK in\n * green, Unreachable in red, Checking… while probing. The list runs\n * automatically when the page opens; every row is a button that re-probes\n * just that channel, so a click always yields visible feedback\n * (row pulses → badge flips → latency refreshes).\n */\nimport { createElement as h, useCallback, useEffect, useRef, useState } from 'react'\nimport styles from '../../styles/DiagnosticsView.module.css'\nimport type { EnvInfo, Translate } from '../../types.ts'\nimport { PLUGIN_VERSION } from '../../logic/constants.ts'\n\ntype ProbeKey = 'npm' | 'github' | 'catalog'\n\n/** 系统版本文本:提交 Issue 时粘贴到正文,方便作者复现。 */\nfunction formatEnv(env: EnvInfo): string {\n return [\n `DSH Plugin Hub ${PLUGIN_VERSION}`,\n `DSH ${env.dshVersion ?? 'unknown'}`,\n `Node ${env.nodeVersion}`,\n `${env.platform} ${env.arch} (${env.release})`,\n `Profile ${env.profile}`,\n env.dshHome ? `Home ${env.dshHome}` : '',\n ].filter(Boolean).join('\\n')\n}\n\ninterface RowState {\n key: ProbeKey\n /** 目标地址展示(registry 地址 / github.com / dsh-plugin.org) */\n display: string\n nameKey: string\n status: 'idle' | 'running' | 'ok' | 'fail'\n ms: number | null\n statusCode: number | null\n}\n\nconst INITIAL_ROWS: RowState[] = [\n { key: 'npm', display: 'registry.npmjs.org', nameKey: 'diagNpm', status: 'idle', ms: null, statusCode: null },\n { key: 'github', display: 'github.com', nameKey: 'diagGithub', status: 'idle', ms: null, statusCode: null },\n { key: 'catalog', display: 'api.dsh-plugin.org', nameKey: 'diagCatalog', status: 'idle', ms: null, statusCode: null },\n]\n\nexport function DiagnosticsView({ t, env, onCopy }: {\n t: Translate\n env: EnvInfo | null\n onCopy: (text: string) => void\n}) {\n const [rows, setRows] = useState<RowState[]>(INITIAL_ROWS)\n /** 当前探测请求:重测/卸载时 abort 旧请求,避免乱序结果覆盖 */\n const runningRef = useRef<AbortController | null>(null)\n\n const patchRows = (key: ProbeKey | undefined, patch: Partial<RowState>) => {\n setRows((prev) => prev.map((r) => (key === undefined || r.key === key ? { ...r, ...patch } : r)))\n }\n\n /** 探测:key 缺省 = 全量串行;传 key = 只重测该通道 */\n const run = useCallback((key?: ProbeKey) => {\n runningRef.current?.abort()\n const controller = new AbortController()\n runningRef.current = controller\n patchRows(key, { status: 'running', ms: null, statusCode: null })\n\n void (async () => {\n try {\n const res = await fetch('/dsh-plugin-hub/diagnostics', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: key === undefined ? '{}' : JSON.stringify({ key }),\n cache: 'no-store',\n signal: controller.signal,\n })\n if (!res.ok || res.body === null) throw new Error(`http ${res.status}`)\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n let nl = buf.indexOf('\\n')\n while (nl !== -1) {\n const raw = buf.slice(0, nl).trim()\n buf = buf.slice(nl + 1)\n if (raw !== '') {\n const ev = JSON.parse(raw) as { type?: string; key?: string; ms?: number | null; status?: number | null }\n if (ev.type === 'ok' || ev.type === 'fail') {\n patchRows(ev.key as ProbeKey, {\n status: ev.type === 'ok' ? 'ok' : 'fail',\n ms: typeof ev.ms === 'number' ? ev.ms : null,\n statusCode: typeof ev.status === 'number' ? ev.status : null,\n })\n }\n }\n nl = buf.indexOf('\\n')\n }\n }\n } catch {\n // 连接本地服务失败:该项标记失败(被新请求 abort 的旧请求直接忽略)\n if (controller.signal.aborted) return\n patchRows(key, { status: 'fail', ms: null, statusCode: null })\n }\n })()\n }, [])\n\n // 进入页面自动全量探测一轮;卸载时中断\n useEffect(() => {\n run()\n return () => runningRef.current?.abort()\n }, [run])\n\n const anyRunning = rows.some((r) => r.status === 'running')\n const allOk = !anyRunning && rows.every((r) => r.status === 'ok')\n const anyFail = !anyRunning && rows.some((r) => r.status === 'fail')\n\n return h('div', { className: styles.panel },\n // 最顶部:系统版本 —— 复制当前宿主版本与系统信息,提 Issue 时粘贴到正文便于复现\n h('div', { className: styles.envRow },\n h('div', { className: styles.envLabel },\n h('div', { className: styles.envTitle }, t('settingsEnvSnapshot')),\n h('div', { className: styles.envDesc }, t('settingsEnvSnapshotDesc')),\n ),\n h('button', {\n type: 'button',\n className: styles.envCopyBtn,\n disabled: env === null,\n onClick: () => { if (env) onCopy(formatEnv(env)) },\n }, t('settingsEnvCopy')),\n ),\n // 头部:右侧「立即诊断」按钮,点击全量重测所有通道\n h('div', { className: styles.head },\n h('span', { className: styles.headHint }, t('diagHeadHint', { n: rows.length })),\n h('button', {\n type: 'button',\n className: styles.runBtn,\n disabled: anyRunning,\n onClick: () => run(),\n }, t('diagRunAll')),\n ),\n rows.map((r) => {\n const badge = r.status === 'running'\n ? h('span', { className: `${styles.badge} ${styles.badgeRunning}` }, t('diagChecking'))\n : r.status === 'ok'\n ? h('span', { className: `${styles.badge} ${styles.badgeOk}` },\n r.statusCode !== null ? `HTTP ${r.statusCode} ${t('diagOk')}` : t('diagOk'))\n : r.status === 'fail'\n ? h('span', { className: `${styles.badge} ${styles.badgeFail}` }, t('settingsDiagFail'))\n : h('span', { className: `${styles.badge} ${styles.badgeIdle}` }, t('diagIdle'))\n return h('button', {\n key: r.key,\n type: 'button',\n className: styles.row,\n disabled: r.status === 'running',\n onClick: () => run(r.key),\n title: t('diagRecheck'),\n },\n h('span', { className: styles.name }, t(r.nameKey)),\n h('span', { className: styles.display }, r.display),\n h('span', { className: styles.meta }, r.status === 'ok' && r.ms !== null ? `${r.ms} ms` : ''),\n badge,\n )\n }),\n // 底部总览:全部通过 / 存在异常 / 检测中,汇总整体状态\n h('div', {\n className: `${styles.summary} ${anyRunning ? styles.summaryRunning : allOk ? styles.summaryOk : styles.summaryFail}`,\n }, anyRunning ? t('diagSummaryRunning') : allOk ? t('diagSummaryOk') : t('diagSummaryFail')),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Built-in log viewer dialog: no external software needed — the app opens\n * its own window and loads the local system log (JSONL at\n * ~/.dsh/profiles/<profile>/hub.log) straight from the server, one page at\n * a time.\n *\n * Every line is categorized twice: a function area (install / uninstall /\n * update / diagnostics / settings / system) and a severity level (debug /\n * info / success / warn / error). Filtering on both axes lets you target,\n * say, only install errors — so the exact incompatible step of an install\n * (or uninstall) is easy to spot. Search narrows by event code or message.\n *\n * Server pagination: GET /dsh-plugin-hub/logs?offset=&limit=&category=\n * &level=&query= → { entries, total, hasMore, path }. The footer shows the\n * real file location and reveals it in the system file manager.\n */\nimport { createElement as h, useCallback, useEffect, useRef, useState } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport view from '../../styles/LogsView.module.css'\nimport type { Translate } from '../../types.ts'\nimport { openLogFile } from '../../data/host.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\n/** 与服务端 /logs 返回的 LogEntry 对齐的客户端投影。 */\nexport interface LogEntryView {\n /** 毫秒时间戳 */\n at: number\n level: 'debug' | 'info' | 'success' | 'warn' | 'error'\n category: 'install' | 'uninstall' | 'update' | 'diagnostics' | 'settings' | 'system'\n /** 机器可读事件码,如 install.start */\n event: string\n message: string\n}\n\nexport type LogCategoryFilter = 'all' | LogEntryView['category']\nexport type LogLevelFilter = 'all' | LogEntryView['level']\n\nconst PAGE = 100\n\n/** 类别筛选标签:值 → 语言包 key(弹窗内 chip 与行内类别徽章共用)。 */\nconst CAT_LABEL: Record<LogEntryView['category'], string> = {\n install: 'logCatInstall',\n uninstall: 'logCatUninstall',\n update: 'logCatUpdate',\n diagnostics: 'logCatDiagnostics',\n settings: 'logCatSettings',\n system: 'logCatSystem',\n}\n\nconst CAT_FILTERS: Array<{ value: LogCategoryFilter; key: string }> = [\n { value: 'all', key: 'logCatAll' },\n { value: 'install', key: 'logCatInstall' },\n { value: 'uninstall', key: 'logCatUninstall' },\n { value: 'update', key: 'logCatUpdate' },\n { value: 'diagnostics', key: 'logCatDiagnostics' },\n { value: 'settings', key: 'logCatSettings' },\n { value: 'system', key: 'logCatSystem' },\n]\n\nconst LEVEL_FILTERS: Array<{ value: LogLevelFilter; key: string }> = [\n { value: 'all', key: 'logLvAll' },\n { value: 'error', key: 'logLvError' },\n { value: 'warn', key: 'logLvWarn' },\n { value: 'success', key: 'logLvSuccess' },\n { value: 'info', key: 'logLvInfo' },\n { value: 'debug', key: 'logLvDebug' },\n]\n\n/** 级别徽章文案:弹窗 chip 与行内级别徽章共用同一语言包 key。 */\nconst LEVEL_LABEL: Record<LogEntryView['level'], string> = {\n debug: 'logLvDebug',\n info: 'logLvInfo',\n success: 'logLvSuccess',\n warn: 'logLvWarn',\n error: 'logLvError',\n}\n\n/** 时间:YYYY-MM-DD HH:mm:ss(每条都精确到秒)。 */\nexport function fmtLogTime(at: number): string {\n const d = new Date(at)\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`\n}\n\n/** 导出文件名时间戳:2026-08-24_21-35-00。 */\nfunction fmtFileStamp(at: number): string {\n const d = new Date(at)\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}_${pad(d.getHours())}-${pad(d.getMinutes())}-${pad(d.getSeconds())}`\n}\n\n/** 单条日志行:时间 + 级别徽章 + 类别徽章 + 事件码 + 描述。查看器弹窗与设置页预览共用。 */\nexport function LogEntryRow({ e, t }: { e: LogEntryView; t: Translate }) {\n return h('div', { className: view.entry, title: e.message },\n h('span', { className: view.time }, fmtLogTime(e.at)),\n h('span', { className: `${view.badge} ${view[`badge${e.level}`]}` }, t(LEVEL_LABEL[e.level])),\n h('span', { className: `${view.catBadge} ${view[`cat${e.category}`]}` }, t(CAT_LABEL[e.category])),\n h('span', { className: view.event }, e.event),\n h('span', { className: view.message }, e.message),\n )\n}\n\nexport function LogsModal({ t, onClose }: {\n t: Translate\n onClose: () => void\n}) {\n const [category, setCategory] = useState<LogCategoryFilter>('all')\n const [level, setLevel] = useState<LogLevelFilter>('all')\n const [query, setQuery] = useState('')\n const [entries, setEntries] = useState<LogEntryView[]>([])\n const [total, setTotal] = useState(0)\n const [hasMore, setHasMore] = useState(false)\n const [path, setPath] = useState('')\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState(false)\n const [opening, setOpening] = useState(false)\n const [openFailed, setOpenFailed] = useState(false)\n const offsetRef = useRef(0)\n\n /** 拉一页:过滤参数取当前 state,偏移量由调用方给出。 */\n const fetchPage = useCallback(async (offset: number): Promise<{ entries: LogEntryView[]; total: number; hasMore: boolean; path: string } | null> => {\n try {\n const qs = new URLSearchParams({ offset: String(offset), limit: String(PAGE) })\n if (category !== 'all') qs.set('category', category)\n if (level !== 'all') qs.set('level', level)\n const q = query.trim()\n if (q !== '') qs.set('query', q)\n const res = await fetch(`/dsh-plugin-hub/logs?${qs.toString()}`, { cache: 'no-store' })\n if (!res.ok) return null\n return await res.json() as { entries: LogEntryView[]; total: number; hasMore: boolean; path: string }\n } catch {\n return null\n }\n }, [category, level, query])\n\n /** 从第一页重新加载(换筛选/搜索时)。 */\n const reload = useCallback(async () => {\n setLoading(true)\n const data = await fetchPage(0)\n if (data === null) {\n setError(true)\n setLoading(false)\n return\n }\n offsetRef.current = data.entries.length\n setEntries(data.entries)\n setTotal(data.total)\n setHasMore(data.hasMore)\n if (data.path !== '') setPath(data.path)\n setError(false)\n setLoading(false)\n }, [fetchPage])\n\n /** 追加下一页(「加载更多」)。 */\n const loadMore = useCallback(async () => {\n if (loading) return\n setLoading(true)\n const data = await fetchPage(offsetRef.current)\n if (data === null) {\n setError(true)\n setLoading(false)\n return\n }\n offsetRef.current += data.entries.length\n setEntries((prev) => [...prev, ...data.entries])\n setTotal(data.total)\n setHasMore(data.hasMore)\n setLoading(false)\n }, [fetchPage, loading])\n\n // 首次进入 + 类别/级别/搜索变化(搜索 280ms 防抖)都重查第一页\n const first = useRef(true)\n useEffect(() => {\n if (first.current) {\n first.current = false\n void reload()\n return\n }\n const id = window.setTimeout(() => { void reload() }, 280)\n return () => window.clearTimeout(id)\n }, [reload])\n\n /** 在系统文件管理器中定位日志文件(服务端 spawn open)。 */\n const openFile = async () => {\n if (opening) return\n setOpening(true)\n setOpenFailed(false)\n const ok = await openLogFile()\n setOpening(false)\n if (!ok) setOpenFailed(true)\n }\n\n /** 导出:拼纯文本 → Blob → 触发浏览器下载 .log 文件 */\n const exportFile = () => {\n const text = entries.map((e) => `[${fmtLogTime(e.at)}] [${e.level}] [${e.category}] [${e.event}] ${e.message}`).join('\\n')\n if (text === '') return\n const blob = new Blob([text], { type: 'text/plain;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `dsh-plugin-hub-log-${fmtFileStamp(Date.now())}.log`\n document.body.appendChild(a)\n a.click()\n a.remove()\n URL.revokeObjectURL(url)\n }\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.errorModal} ${styles.logModal}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('logModalTitle')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n // 类别筛选行:安装/卸载/更新… 功能域区分\n h('div', { className: view.filterBar },\n CAT_FILTERS.map((f) => h('button', {\n key: f.value,\n type: 'button',\n className: category === f.value ? `${view.filterChip} ${view.filterChipActive}` : view.filterChip,\n onClick: () => setCategory(f.value),\n }, t(f.key))),\n ),\n // 级别筛选行 + 搜索框:按级别区分报错与正常,便于针对性排查\n h('div', { className: view.filterBar },\n LEVEL_FILTERS.map((f) => h('button', {\n key: f.value,\n type: 'button',\n className: level === f.value ? `${view.filterChip} ${view.filterChipActive}` : view.filterChip,\n onClick: () => setLevel(f.value),\n }, t(f.key))),\n h('div', { className: view.search },\n h('input', {\n className: view.searchInput,\n type: 'search',\n value: query,\n placeholder: t('logSearchPlaceholder'),\n 'aria-label': t('logSearchPlaceholder'),\n onChange: (e) => setQuery((e.target as HTMLInputElement).value),\n }),\n ),\n ),\n h('div', { className: view.logList },\n error\n ? h('div', { className: view.empty }, t('logsLoadFail'))\n : loading && entries.length === 0\n ? h('div', { className: view.empty }, t('logsLoading'))\n : entries.length === 0\n ? h('div', { className: view.empty }, t('logEmptyFilter'))\n : entries.map((e, i) => h(LogEntryRow, { key: `${e.at}-${i}`, e, t })),\n // 分页:还有就「加载更多」,拉完了给个总数收尾\n entries.length > 0 && (hasMore\n ? h('button', {\n type: 'button',\n className: view.more,\n disabled: loading,\n onClick: () => void loadMore(),\n }, loading ? t('logsLoading') : t('logLoadMore'))\n : h('div', { className: view.moreEnd }, t('logNoMore', { n: total }))),\n ),\n ),\n // 底部:日志真实路径 + 打开文件 / 导出日志\n h('div', { className: view.foot },\n h('span', { className: view.footPath, title: path },\n `${t('logPathLabel')}: ${path === '' ? '…' : path}`),\n openFailed\n ? h('span', { className: view.footFail }, t('logOpenFileFail'))\n : h('span', { className: view.footCount }, t('logCount', { n: total })),\n h('div', { className: view.footActions },\n h('button', {\n type: 'button',\n className: view.btn,\n disabled: opening || path === '',\n title: t('logOpenFileTip'),\n onClick: () => void openFile(),\n }, t('logOpenFile')),\n h('button', {\n type: 'button',\n className: `${view.btn} ${view.btnPrimary}`,\n disabled: entries.length === 0,\n onClick: exportFile,\n }, t('logsExport')),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * 日志存放位置弹窗:设置页不内联长表单(挡视线),点「修改」弹窗编辑。\n * 两种输入方式并存 —— 手输目录 / .log 文件路径,或点「选择目录」调系统\n * 原生文件夹对话框(服务端 spawn osascript / FolderBrowserDialog / zenity)。\n * 文本框预填当前生效位置,目录选择器也从该位置打开 —— 默认地址是动态的\n * (随用户主目录/平台变化,如 ~/.dsh/profiles/<profile>/hub.log),必须实时展示。\n * 留空或点「恢复默认」= 回到默认;保存前服务端预验证可写。\n */\nimport { createElement as h, useEffect, useState } from 'react'\nimport styles from '../../styles/Modal.module.css'\nimport view from '../../styles/LogsView.module.css'\nimport type { Translate } from '../../types.ts'\nimport { chooseLogDir } from '../../data/host.ts'\nimport { CloseIcon } from '../ui/icons.tsx'\n\nexport function LogsPathModal({ t, defaultPath, currentPath, onSaved, onClose }: {\n t: Translate\n /** 真正默认位置(服务端动态算出的 ~/.dsh/profiles/<profile>/hub.log),跨机器/平台不同 */\n defaultPath: string\n /** 当前生效的真实路径(可能已被自定义覆盖) */\n currentPath: string\n /** 保存成功回调(写入设置;父级据此刷新生效路径与日志列表) */\n onSaved: (value: string) => void\n onClose: () => void\n}) {\n // 打开即显示当前生效位置 —— 用户一眼看到日志现在存在哪,也方便在此基础上微调\n const [draft, setDraft] = useState(currentPath)\n const [saving, setSaving] = useState(false)\n const [fail, setFail] = useState(false)\n const [browsing, setBrowsing] = useState(false)\n const [browseFail, setBrowseFail] = useState(false)\n\n // Esc 关闭:与其它弹窗交互一致\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose() }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [onClose])\n\n /** 保存:空串 = 回默认;填回默认位置同样按「未自定义」处理(设置里保持干净)。\n * 服务端预建目录验证可写,失败给出反馈。 */\n const save = async () => {\n if (saving) return\n setSaving(true)\n setFail(false)\n try {\n const value = draft.trim()\n const normalized = value === '' || value === defaultPath ? '' : value\n const res = await fetch('/dsh-plugin-hub/settings', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ logPath: normalized }),\n cache: 'no-store',\n })\n if (!res.ok) {\n setFail(true)\n return\n }\n // 保存成功即关:主界面路径行随即刷新为新位置,本身就是反馈\n onSaved(normalized)\n onClose()\n } catch {\n setFail(true)\n } finally {\n setSaving(false)\n }\n }\n\n /** 选择目录:系统对话框从默认位置打开,选中路径回填输入框(仍可手改)。 */\n const browse = async () => {\n if (browsing) return\n setBrowsing(true)\n setBrowseFail(false)\n const picked = await chooseLogDir()\n setBrowsing(false)\n if (picked !== null) {\n setDraft(picked)\n setFail(false)\n } else {\n setBrowseFail(true)\n }\n }\n\n return h('div', {\n className: styles.overlay,\n onClick: (e: { target: unknown; currentTarget: unknown }) => {\n if (e.target === e.currentTarget) onClose()\n },\n },\n h('div', { className: `${styles.modal} ${styles.modalWide}`, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: styles.modalHead },\n h('div', { className: styles.modalTitle }, t('logPathSettingTitle')),\n h('button', {\n className: styles.modalClose,\n 'aria-label': t('errorClose'),\n onClick: onClose,\n }, h(CloseIcon)),\n ),\n h('div', { className: styles.modalBody },\n h('div', { className: view.pathDialog },\n h('div', { className: view.pathDialogDesc }, t('logPathSettingDesc')),\n // 手输路径 + 系统目录选择器两条路并行\n h('div', { className: view.pathDialogRow },\n h('input', {\n type: 'text',\n className: view.pathDraft,\n value: draft,\n placeholder: t('logPathPlaceholder'),\n spellCheck: false,\n onChange: (e: { currentTarget: HTMLInputElement }) => {\n setDraft(e.currentTarget.value)\n setFail(false)\n setBrowseFail(false)\n },\n }),\n h('button', {\n type: 'button',\n className: view.btn,\n disabled: browsing,\n title: t('logPathBrowse'),\n onClick: () => void browse(),\n }, browsing ? t('logPathSaving') : t('logPathBrowse')),\n ),\n // 提示 + 「恢复默认」:提示左、动作右,一行内不挤\n h('div', { className: view.pathDialogReset },\n h('span', { className: view.pathDialogHint }, t('logPathResetHint')),\n h('button', {\n type: 'button',\n className: view.linkBtn,\n onClick: () => {\n setDraft(defaultPath)\n setFail(false)\n setBrowseFail(false)\n },\n }, t('logPathReset')),\n ),\n browseFail && h('div', { className: view.footFail }, t('logPathBrowseFail')),\n fail && h('div', { className: view.footFail }, t('logPathSaveFail')),\n h('div', { className: view.pathDialogFoot },\n h('button', {\n type: 'button',\n className: view.btn,\n disabled: saving,\n onClick: onClose,\n }, t('confirmCancel')),\n h('button', {\n type: 'button',\n className: `${view.btn} ${view.btnPrimary}`,\n disabled: saving,\n onClick: () => void save(),\n }, saving ? t('logPathSaving') : t('logPathSave')),\n ),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * 系统日志入口视图:不在这里堆全文,而是给出「打开日志查看器」窗口入口 +\n * 日志文件真实路径(可一键在系统文件管理器中定位)+ 最近若干条预览。\n * 完整阅读/筛选/分页在 LogsModal 内置查看器弹窗里完成 —— 无需借助任何\n * 外部软件,点击即弹出自己的窗口加载本地 JSONL 日志。\n */\nimport { createElement as h, useCallback, useEffect, useRef, useState } from 'react'\nimport styles from '../../styles/LogsView.module.css'\nimport type { Translate } from '../../types.ts'\nimport { openLogFile } from '../../data/host.ts'\nimport { LogsModal, LogEntryRow, fmtLogTime, type LogEntryView } from '../modals/LogsModal.tsx'\nimport { LogsPathModal } from '../modals/LogsPathModal.tsx'\n\n/** 设置页预览条数:只放最近一小段,给用户快速感观,完整内容进查看器。 */\nconst PREVIEW = 12\n\nexport function LogsView({ t, logPath, onLogPathSaved }: {\n t: Translate\n /** 设置里已保存的日志位置覆盖(空串 = 默认位置) */\n logPath: string\n /** 保存自定义日志位置(写入设置,服务端同时预建目录验证可写) */\n onLogPathSaved: (value: string) => void\n}) {\n const [entries, setEntries] = useState<LogEntryView[]>([])\n const [path, setPath] = useState('')\n // 真正默认位置(~/.dsh/profiles/<profile>/hub.log,跨机器/平台动态):弹窗「恢复默认」用\n const [defaultPath, setDefaultPath] = useState('')\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState(false)\n const [open, setOpen] = useState(false)\n const [opening, setOpening] = useState(false)\n const [openFailed, setOpenFailed] = useState(false)\n // 日志存放位置弹窗:点「修改」打开,手输或选目录\n const [showPathModal, setShowPathModal] = useState(false)\n const mountedRef = useRef(true)\n\n const load = useCallback(async () => {\n setLoading(true)\n try {\n const res = await fetch('/dsh-plugin-hub/logs', { cache: 'no-store' })\n if (!res.ok) throw new Error(`http ${res.status}`)\n const data = await res.json() as { entries: LogEntryView[]; path: string; defaultPath?: string }\n if (mountedRef.current) {\n setEntries(data.entries)\n if (data.path !== '') setPath(data.path)\n if (data.defaultPath !== undefined) setDefaultPath(data.defaultPath)\n setError(false)\n }\n } catch {\n if (mountedRef.current) setError(true)\n } finally {\n if (mountedRef.current) setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n mountedRef.current = true\n void load()\n return () => { mountedRef.current = false }\n }, [load])\n\n /** 导出:拼纯文本 → Blob → 触发浏览器下载 .log 文件 */\n const exportFile = () => {\n const text = entries.map((e) => `[${fmtLogTime(e.at)}] [${e.level}] [${e.category}] [${e.event}] ${e.message}`).join('\\n')\n if (text === '') return\n const blob = new Blob([text], { type: 'text/plain;charset=utf-8' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = 'dsh-plugin-hub-log.log'\n document.body.appendChild(a)\n a.click()\n a.remove()\n URL.revokeObjectURL(url)\n }\n\n /** 在系统文件管理器中定位日志文件。 */\n const openFile = async () => {\n if (opening) return\n setOpening(true)\n setOpenFailed(false)\n const ok = await openLogFile()\n setOpening(false)\n if (!ok) setOpenFailed(true)\n }\n\n const preview = entries.slice(0, PREVIEW)\n return h('div', { className: styles.panel },\n h('div', { className: styles.head },\n h('span', { className: styles.headHint }, t('logsHeadHint')),\n h('div', { className: styles.actions },\n h('button', {\n type: 'button',\n className: `${styles.btn} ${styles.btnPrimary}`,\n onClick: () => setOpen(true),\n }, t('logViewerOpen')),\n h('button', { type: 'button', className: styles.btn, disabled: entries.length === 0, onClick: exportFile }, t('logsExport')),\n h('button', { type: 'button', className: styles.btn, disabled: loading, onClick: () => void load() }, t('logsRefresh')),\n ),\n ),\n // 日志存放位置:一行展示真实路径 + 「修改」弹窗编辑(手输 / 选目录)+ 一键定位文件\n h('div', { className: styles.pathRow },\n h('span', { className: styles.pathLabel }, t('logPathSettingTitle')),\n h('span', { className: styles.pathText, title: path }, path === '' ? '…' : path),\n openFailed && h('span', { className: styles.footFail }, t('logOpenFileFail')),\n h('button', {\n type: 'button',\n className: styles.btn,\n onClick: () => setShowPathModal(true),\n }, t('logPathChange')),\n h('button', {\n type: 'button',\n className: styles.btn,\n disabled: opening || path === '',\n title: t('logOpenFileTip'),\n onClick: () => void openFile(),\n }, t('logOpenFile')),\n ),\n error\n ? h('div', { className: styles.empty }, t('logsLoadFail'))\n : loading && entries.length === 0\n ? h('div', { className: styles.empty }, t('logsLoading'))\n : entries.length === 0\n ? h('div', { className: styles.empty }, t('logsEmpty'))\n : h('div', { className: styles.list },\n preview.map((e, i) => h('button', {\n key: `${e.at}-${i}`,\n type: 'button',\n className: styles.previewRow,\n onClick: () => setOpen(true),\n title: t('logViewerOpen'),\n }, h(LogEntryRow, { e, t }))),\n ),\n open && h(LogsModal, { t, onClose: () => setOpen(false) }),\n showPathModal && h(LogsPathModal, {\n t,\n defaultPath,\n currentPath: path,\n onSaved: (v: string) => {\n onLogPathSaved(v)\n void load() // 刷新生效路径与最近日志(新位置若已写入则立即可见)\n },\n onClose: () => setShowPathModal(false),\n }),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Settings view: desktop-settings navigation — a fixed left sidebar lists\n * the sections (icon + label, click to switch), the right pane shows the\n * active section's rows. New settings only add rows, new areas only add a\n * sidebar entry.\n *\n * Sections mirror what the local server actually enforces:\n * Updates & Sources — startup update check / npm mirror / HTTP proxy\n * (all wired into the install command path)\n * Security & Trust — restricted custom installs (server 403 gate)\n * Diagnostics — live connectivity probe + environment snapshot\n * Logs — system log viewer + storage location\n */\nimport { createElement as h, useState } from 'react'\nimport type { ChangeEvent, MouseEvent, ReactNode } from 'react'\nimport styles from '../../styles/SettingsView.module.css'\nimport modalStyles from '../../styles/Modal.module.css'\nimport { Dropdown } from '../ui/Dropdown.tsx'\nimport { Toggle } from '../ui/Toggle.tsx'\nimport { DiagnosticsView } from './DiagnosticsView.tsx'\nimport { LogsView } from './LogsView.tsx'\nimport {\n CloseIcon, DiagnosticsIcon, LogsIcon, ResetIcon, SecurityIcon, UpdatesIcon,\n} from '../ui/icons.tsx'\nimport type { EnvInfo, Translate } from '../../types.ts'\nimport type { HubSettings } from '../../hooks/useSettings.ts'\n\ntype SettingsSection = 'updates' | 'security' | 'diagnostics' | 'logs' | 'reset'\n\n/** 左侧导航:顺序即展示顺序;labelKey 是分组标题,icon 是行内小图标。 */\nconst NAV: Array<{ key: SettingsSection; labelKey: string; icon: () => ReturnType<typeof h> }> = [\n { key: 'updates', labelKey: 'settingsUpdate', icon: UpdatesIcon },\n { key: 'security', labelKey: 'settingsSecurity', icon: SecurityIcon },\n { key: 'diagnostics', labelKey: 'settingsDiagnostics', icon: DiagnosticsIcon },\n { key: 'logs', labelKey: 'settingsLogs', icon: LogsIcon },\n { key: 'reset', labelKey: 'settingsReset', icon: ResetIcon },\n]\n\n/** npm 镜像源预设:空串 = 官方源;值相等即视为选中对应预设,其余进入「自定义」输入。 */\nconst MIRROR_PRESETS: Array<{ value: string; labelKey: string }> = [\n { value: '', labelKey: 'mirrorOfficial' },\n { value: 'https://registry.npmmirror.com', labelKey: 'mirrorNpmmirror' },\n { value: 'https://mirrors.cloud.tencent.com/npm/', labelKey: 'mirrorTencent' },\n]\n\n/** 设置行:默认标签左控件右;stack=true 时控件独占一行(文本框整行显示),hairline 分隔。 */\nfunction SettingRow({ title, desc, children, stack = false }: {\n title: string\n desc?: string\n children: ReactNode\n stack?: boolean\n}) {\n return h('div', { className: stack ? styles.settingRowStack : styles.settingRow },\n h('div', { className: styles.settingLabel },\n h('div', { className: styles.settingTitle }, title),\n desc ? h('div', { className: styles.settingDesc }, desc) : null,\n ),\n h('div', { className: stack ? styles.settingControlStack : styles.settingControl }, children),\n )\n}\n\nexport function SettingsView({ t, settings, update, reset, env, onCopy }: {\n t: Translate\n settings: HubSettings\n update: (patch: Partial<HubSettings>) => void\n reset: () => void\n env: EnvInfo | null\n onCopy: (text: string) => void\n}) {\n /** 当前激活的分组:左侧导航点击切换,右侧只渲染这一组 */\n const [section, setSection] = useState<SettingsSection>('updates')\n /** 恢复默认确认弹窗:点按钮先弹窗询问,确认后才真正 reset(不做两段式按钮) */\n const [resetConfirm, setResetConfirm] = useState(false)\n\n const mirrorCustom = !MIRROR_PRESETS.some((p) => p.value === settings.npmRegistry)\n const onMirrorChange = (value: string) => {\n if (value === 'custom') return // 进入自定义输入:保持当前值,下方出现输入框\n update({ npmRegistry: value })\n }\n const onMirrorInput = (e: ChangeEvent<HTMLInputElement>) => update({ npmRegistry: e.target.value })\n const onProxyChange = (e: ChangeEvent<HTMLInputElement>) => update({ proxy: e.target.value })\n\n /** 每个分组的页面副标题(导航标题之上再补一句说明,保持桌面设置质感) */\n const pageDesc: Record<SettingsSection, string> = {\n updates: t('settingsUpdateDesc'),\n security: t('settingsSecurityDesc'),\n diagnostics: t('settingsDiagnosticsDesc'),\n logs: t('settingsLogsDesc'),\n reset: t('settingsResetDesc'),\n }\n const activeNav = NAV.find((n) => n.key === section) ?? NAV[0]\n\n // —— 各分组的设置卡片(一页一个 card,内部一行一设置) ——\n\n const updatesCard = h('div', { className: styles.card },\n h(SettingRow, {\n title: t('settingsCheckOnStart'),\n desc: t('settingsCheckOnStartDesc'),\n children: h(Toggle, {\n checked: settings.checkUpdatesOnStart,\n onChange: (v) => update({ checkUpdatesOnStart: v }),\n title: t('settingsCheckOnStart'),\n }),\n }),\n h(SettingRow, {\n title: t('settingsMirror'),\n desc: t('settingsMirrorDesc'),\n children: h(Dropdown, {\n value: mirrorCustom ? 'custom' : settings.npmRegistry,\n options: [\n ...MIRROR_PRESETS.map((p) => ({ value: p.value, label: t(p.labelKey) })),\n { value: 'custom', label: t('mirrorCustom') },\n ],\n onChange: onMirrorChange,\n title: t('settingsMirror'),\n className: styles.controlDropdown,\n }),\n }),\n // 自定义镜像源:下拉选中「自定义」或已存非预设值时,追加一行输入框(文本框独占一行)\n mirrorCustom && h(SettingRow, {\n title: t('mirrorCustom'),\n stack: true,\n children: h('input', {\n className: styles.textInput,\n type: 'url',\n value: settings.npmRegistry,\n placeholder: 'https://registry.npmjs.org',\n spellCheck: false,\n onChange: onMirrorInput,\n }),\n }),\n // 代理地址:文本框独占一行,整行输入,便于粘贴长代理地址\n h(SettingRow, {\n title: t('settingsProxy'),\n desc: t('settingsProxyDesc'),\n stack: true,\n children: h('input', {\n className: styles.textInput,\n type: 'text',\n value: settings.proxy,\n placeholder: 'http://127.0.0.1:7890',\n spellCheck: false,\n onChange: onProxyChange,\n }),\n }),\n )\n\n const securityCard = h('div', { className: styles.card },\n // 安全与信任:命令行安装的三个通道开关(NPM 包 / GitHub 源码 / DSH 命令)——\n // 服务端按通道门禁 403 拦截(npm 目标吃 enableNpmInstall、git 目标吃 enableGitInstall),\n // DSH 命令框为纯客户端通道:关掉后命令输入卡片禁用并引导去设置打开;\n // 目录内收录的插件安装不受影响(默认全部开启)\n h(SettingRow, {\n title: t('settingsEnableNpm'),\n desc: t('settingsEnableNpmDesc'),\n children: h(Toggle, {\n checked: settings.enableNpmInstall,\n onChange: (v) => update({ enableNpmInstall: v }),\n title: t('settingsEnableNpm'),\n }),\n }),\n h(SettingRow, {\n title: t('settingsEnableGit'),\n desc: t('settingsEnableGitDesc'),\n children: h(Toggle, {\n checked: settings.enableGitInstall,\n onChange: (v) => update({ enableGitInstall: v }),\n title: t('settingsEnableGit'),\n }),\n }),\n h(SettingRow, {\n title: t('settingsEnableDsh'),\n desc: t('settingsEnableDshDesc'),\n children: h(Toggle, {\n checked: settings.enableDshInstall,\n onChange: (v) => update({ enableDshInstall: v }),\n title: t('settingsEnableDsh'),\n }),\n }),\n )\n\n const diagnosticsCard = h('div', { className: styles.card },\n // 系统版本(最顶部)+ 通道状态列表:进入页面自动探测一轮,整行可点击重测单项,实时反馈\n h(DiagnosticsView, { t, env, onCopy }),\n )\n\n const logsCard = h('div', { className: styles.card },\n // 系统日志列表:操作记录(安装/卸载/设置/诊断),可刷新/复制/导出,点击弹窗查看;\n // 日志存放位置可设置(留空用默认),改动会写入设置并立即生效\n h(LogsView, {\n t,\n logPath: settings.logPath,\n onLogPathSaved: (v: string) => update({ logPath: v }),\n }),\n )\n\n const resetCard = h('div', { className: styles.card },\n h(SettingRow, {\n title: t('settingsReset'),\n desc: t('settingsResetDetail'),\n children: h('button', {\n type: 'button',\n className: styles.resetBtn,\n onClick: () => setResetConfirm(true),\n }, t('settingsResetRun')),\n }),\n )\n\n return h('div', { className: styles.root },\n // 左侧导航:固定宽度菜单栏,图标 + 名称,点击切换右侧内容\n h('nav', { className: styles.sidebar, 'aria-label': t('viewSettings') },\n NAV.map((item) => h('button', {\n key: item.key,\n type: 'button',\n className: section === item.key ? styles.navItemActive : styles.navItem,\n onClick: () => setSection(item.key),\n 'aria-current': section === item.key ? 'page' : undefined,\n title: t(item.labelKey),\n },\n h('span', { className: styles.navIcon }, h(item.icon)),\n h('span', { className: styles.navLabel }, t(item.labelKey)),\n )),\n ),\n // 右侧内容:只渲染当前分组,独立滚动\n h('div', { className: styles.content },\n h('div', { className: styles.pageHeader },\n h('div', { className: styles.pageTitle }, t(activeNav.labelKey)),\n h('div', { className: styles.pageDesc }, pageDesc[section]),\n ),\n section === 'updates' ? updatesCard\n : section === 'security' ? securityCard\n : section === 'diagnostics' ? diagnosticsCard\n : section === 'logs' ? logsCard\n : resetCard,\n ),\n // 恢复默认确认弹窗:点「恢复默认」先弹窗确认,确认后才真正 reset(替代两段式按钮)\n resetConfirm && h('div', {\n className: modalStyles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) setResetConfirm(false) },\n },\n h('div', { className: modalStyles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: modalStyles.modalHead },\n h('div', { className: modalStyles.modalTitle }, t('settingsReset')),\n h('button', {\n className: modalStyles.modalClose,\n type: 'button',\n 'aria-label': t('errorClose'),\n onClick: () => setResetConfirm(false),\n }, h(CloseIcon)),\n ),\n h('div', { className: modalStyles.modalBody },\n h('div', { className: modalStyles.failPrepareHint }, t('settingsResetConfirmDetail')),\n h('div', { className: modalStyles.modalActions },\n h('button', {\n className: modalStyles.restartLater,\n type: 'button',\n onClick: () => setResetConfirm(false),\n }, t('cancel')),\n h('button', {\n className: modalStyles.restartNowWarning,\n type: 'button',\n onClick: () => { setResetConfirm(false); reset() },\n }, t('settingsResetConfirm')),\n ),\n ),\n ),\n ),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * Plugin Hub section: wires the catalog data pipeline, the background task\n * queue and the feedback state together. Data/queue logic lives in hooks/,\n * rendering is delegated to the small presentational components in this\n * folder; it hosts the dialogs/toast and the section-level copy actions.\n */\nimport { createElement as h, useEffect, useRef, useState } from 'react'\nimport type { MouseEvent } from 'react'\nimport styles from '../styles/Header.module.css'\nimport modalStyles from '../styles/Modal.module.css'\nimport type { EnvInfo, HubPlugin, SectionProps, ToastState } from '../types.ts'\nimport { installCommandOf, repoFromInstallTarget } from '../logic/install-command.ts'\nimport { PLUGIN_VERSION } from '../logic/constants.ts'\nimport { getEnv, revealInstallFolder } from '../data/host.ts'\nimport { useCatalog } from '../hooks/useCatalog.ts'\nimport { useLanguage } from '../hooks/useLanguage.ts'\nimport { useSettings } from '../hooks/useSettings.ts'\nimport { useTaskQueue } from '../hooks/useTaskQueue.ts'\nimport { ErrorModal, InstallModal, RestartConfirmModal, UninstallModal, Toast } from './modals/modals.tsx'\nimport { AboutModal } from './modals/AboutModal.tsx'\nimport { HubUpdateModal } from './modals/HubUpdateModal.tsx'\nimport { InstalledDetailModal } from './modals/InstalledDetailModal.tsx'\nimport { NotificationsModal } from './modals/NotificationsModal.tsx'\nimport { addFailure, addSuccess, addUpdateNotice, clearNotifications, ignoreUpdate, loadIgnoredUpdates, loadNotifications, removeNotification, removeUpdateNotice } from '../logic/failures.ts'\nimport type { NotificationRecord } from '../logic/failures.ts'\nimport { CatalogHeader } from './layout/CatalogHeader.tsx'\nimport { MarketView } from './views/MarketView.tsx'\nimport { SectionTabs } from './layout/SectionTabs.tsx'\nimport type { SectionView } from './layout/SectionTabs.tsx'\nimport { InstalledView } from './views/InstalledView.tsx'\nimport { CustomInstallView } from './views/CustomInstallView.tsx'\nimport { SettingsView } from './views/SettingsView.tsx'\nimport { CloseIcon } from './ui/icons.tsx'\nimport type { InstalledItem } from '../logic/installed.ts'\nimport { issueRepoOf, pluginOfItem } from '../logic/installed.ts'\n\nexport function PluginHubSection({ t: _hostT, locale }: SectionProps) {\n const { lang, langKey, langPath, t, toggleLang } = useLanguage(locale)\n const catalog = useCatalog(lang)\n /** 设置状态:服务端 hub-settings.json 持久化,本地乐观更新即时生效 */\n const { settings: hubSettings, ready: settingsReady, update: updateSettings, reset: resetSettings } = useSettings()\n\n /** 一级导航:插件中心 / 已安装 / 自定义安装 / 设置 */\n const [view, setView] = useState<SectionView>('market')\n\n /** 全局反馈 Toast:{id} 用于重复触发时重新走入场动画,kind 决定文案与配色 */\n const [toast, setToast] = useState<ToastState | null>(null)\n /** 复制反馈:记录刚复制安装命令的仓库,按钮短暂切换为「已复制」样式 */\n const [copied, setCopied] = useState<string | null>(null)\n /** 信任确认弹窗:记录待安装的插件,确认后才执行复制 */\n const [confirmPlugin, setConfirmPlugin] = useState<HubPlugin | null>(null)\n /** 弹窗动作是否为「更新」:已安装插件点「更新」→ 走同一条 add 命令原位覆盖重装,文案区分安装/更新 */\n const [confirmIsUpdate, setConfirmIsUpdate] = useState(false)\n /** 命令行安装确认弹窗:记录待安装的裸目标(npm 包名 / GitHub 地址,DSH 命令已剥成裸目标)——\n * 与应用商店同一套确认/进度/结果弹窗,提供时 plugin 传 null 走 customTarget 模式 */\n const [confirmCustomTarget, setConfirmCustomTarget] = useState<string | null>(null)\n /** 全局 npm 安装确认弹窗(官方 `npm install -g <pkgs>`):记录原始命令 + 解析出的包列表,\n * 走与应用商店同一套确认/进度/结果弹窗(plugin 传 null,InstallModal 走 globalNpm 模式) */\n const [confirmGlobalNpm, setConfirmGlobalNpm] = useState<{ raw: string; pkgs: string[] } | null>(null)\n /** Hub 自我更新说明弹窗:点「可更新」徽标先展示版本 + Markdown 变更记录,确认后再进安装弹窗 */\n const [showHubUpdate, setShowHubUpdate] = useState(false)\n /** 「关注我们」弹窗:GitHub 图标后按钮点击打开,展示平台介绍 + 用户反馈群二维码(Worker /about 推送) */\n const [showAbout, setShowAbout] = useState(false)\n /** 卸载确认弹窗:记录待卸载的插件(目录内) */\n const [uninstallPlugin, setUninstallPlugin] = useState<HubPlugin | null>(null)\n /** 卸载确认弹窗:记录待卸载的已安装项(自定义安装无目录数据,按包名直卸) */\n const [uninstallItem, setUninstallItem] = useState<InstalledItem | null>(null)\n /** 已安装详情弹窗:记录当前查看的已安装项(行点击 / 详情按钮打开) */\n const [detailItem, setDetailItem] = useState<InstalledItem | null>(null)\n /** 待重启确认弹窗:已安装列表行内「重启」先弹「立即重启 / 稍后重启」确认(与通知中心一致),\n * 确认后才真正触发宿主重启,避免误触 */\n const [showRestartConfirm, setShowRestartConfirm] = useState(false)\n /** 安装/卸载完成后的结果视图:停留弹窗内,点「完成」关闭 */\n const [installDone, setInstallDone] = useState(false)\n const [uninstallDone, setUninstallDone] = useState(false)\n /** 结果视图是否给「立即重启」:服务端任务终态带出(卸载时 loader 已即时移除 → false 只给「完成」;\n * true 时通知中心待重启条目同步常驻,直到用户点「立即重启」真正重启后才消失) */\n const [installNeedsRestart, setInstallNeedsRestart] = useState(true)\n const [uninstallNeedsRestart, setUninstallNeedsRestart] = useState(true)\n /** 结果视图「立即重启」:请求宿主重启后进入等待,服务回来后整页刷新 */\n const [restarting, setRestarting] = useState(false)\n /** 操作失败完整信息 + 所属插件仓库 + 失败类型(决定弹窗标题「安装失败/卸载失败」)+ 实际执行的安装命令 + 尝试过的安装方式(issue 预填用) */\n const [errorMsg, setErrorMsg] = useState<{ message: string; repo: string | null; kind: 'install' | 'uninstall'; command?: string; attempts?: string[] } | null>(null)\n /** 通知中心记录:localStorage 持久化,每次安装/卸载任务成败都留痕(启动时读回) */\n const [notifications, setNotifications] = useState<NotificationRecord[]>(() => loadNotifications())\n /** 通知中心弹窗:一级导航「设置」tab 后边的铃铛入口按钮打开 */\n const [showNotifications, setShowNotifications] = useState(false)\n /** 「忽略本次更新」确认弹窗:{ repo, version };null = 关闭 */\n const [ignoreTarget, setIgnoreTarget] = useState<{ repo: string; version?: string } | null>(null)\n /** 宿主机器环境快照:提交 bug 的 issue 正文附带;取不到为 null(链接少环境段,不阻塞) */\n const [env, setEnv] = useState<EnvInfo | null>(null)\n useEffect(() => {\n let alive = true\n void getEnv().then((info) => { if (alive) setEnv(info) })\n return () => { alive = false }\n }, [])\n\n const queue = useTaskQueue({\n t,\n refreshInstalled: catalog.refreshInstalled,\n onInstallDone: (viaModal, repo, needsRestart) => {\n setInstallNeedsRestart(needsRestart)\n if (viaModal) setInstallDone(true)\n else setToast({ id: Date.now(), kind: 'done' })\n // 安装成功也写入通知记录:通知中心里成功与失败都能看到\n setNotifications(addSuccess({ kind: 'install', repo: repo ?? '' }))\n },\n onUninstallDone: (viaModal, repo, needsRestart) => {\n setUninstallNeedsRestart(needsRestart)\n if (viaModal) setUninstallDone(true)\n else setToast({ id: Date.now(), kind: 'removed' })\n setNotifications(addSuccess({ kind: 'uninstall', repo: repo ?? '' }))\n },\n onError: (message, repo, kind, command, attempts) => {\n // 提 Issue 目标先反查仓库身份:npm 包名能在已安装表/目录里反查到 owner/repo 才保留,\n // 反查不到置 null —— 错误弹窗/通知中心据此不显示「一键提 Issue」按钮(防提到错误仓库)\n const issueRepo = issueRepoOf(repo ?? '', catalog.installedItems, catalog.plugins)\n setErrorMsg({ message, repo: issueRepo, kind, command, attempts })\n // 失败自动写入通知记录:任务在后台结束时没人盯着也能留痕\n setNotifications(addFailure({ kind, repo: issueRepo ?? '', message, command, attempts }))\n },\n installPlugin: confirmPlugin,\n installCustomTarget: confirmCustomTarget,\n installGlobalTarget: confirmGlobalNpm ? confirmGlobalNpm.pkgs.join(' ') : null,\n uninstallPlugin,\n uninstallName: uninstallItem ? uninstallItem.name : null,\n installedName: catalog.installedName,\n // 待重启项展示信息补齐:从目录按 owner/repo 解析插件简介/版本(找不到返回 null,行内只显示仓库名)\n resolvePending: (repo) => {\n const p = catalog.plugins?.find((x) => x.source?.repo === repo)\n return p ? { desc: p.description, version: p.version } : null\n },\n })\n\n /** 补齐更新提醒:把「当前有更新但通知中心还没有」的插件补写进通知(repo+version 去重)。\n * 返回本次实际新增的条数(0 = 无可更新或全部已提示过)。启动检查与打开通知中心共用,\n * 保证通知中心始终反映可更新状态:同一版本只一条、清空/删除后重开恢复、更新完成后消失。 */\n const syncUpdateNotices = (): number => {\n const updatable = catalog.installedItems.filter((i) => i.hasUpdate && i.plugin)\n if (updatable.length === 0) return 0\n const known = new Set(loadIgnoredUpdates())\n // 已忽略(repo+version 持久化)与通知中心已有的更新提醒都不再补写:\n // 忽略本次版本后不再提醒,直到下一个新版本(version 变化)才重新提示\n for (const r of loadNotifications()) {\n if (r.kind === 'update') known.add(`${r.repo}@${r.version ?? ''}`)\n }\n const fresh = updatable.filter((item) =>\n item.repo !== null && !known.has(`${item.repo}@${item.catalogVersion ?? ''}`))\n if (fresh.length === 0) return 0\n for (const item of fresh) {\n if (item.repo) addUpdateNotice({ kind: 'update', repo: item.repo, version: item.catalogVersion ?? undefined })\n }\n setNotifications(loadNotifications())\n return fresh.length\n }\n\n // 启动更新策略:目录数据与设置都就绪后触发一次 —— 开启「启动时检查更新」→ 发现可更新插件\n // 即写入通知中心(每条一条,点击可去更新),toast 同步提示已入通知。\n // 绝不自动安装:是否更新完全由用户决定。\n // ref 守卫保证只跑一次,后续目录刷新/设置变化不会重复打扰。\n const startupCheckedRef = useRef(false)\n useEffect(() => {\n if (startupCheckedRef.current) return\n if (!settingsReady || catalog.plugins === null || catalog.failed) return\n startupCheckedRef.current = true\n if (!hubSettings.checkUpdatesOnStart) return\n const added = syncUpdateNotices()\n if (added > 0) setToast({ id: Date.now(), kind: 'updates', n: added })\n }, [settingsReady, hubSettings, catalog.plugins, catalog.failed, catalog.installedItems, queue])\n\n // 信任/卸载/更新说明弹窗打开时按 Esc 关闭;任务进入后台队列后可随时关闭(任务继续)\n useEffect(() => {\n if (!confirmPlugin && !confirmCustomTarget && !confirmGlobalNpm && !uninstallPlugin && !uninstallItem && !detailItem && !showHubUpdate && !showAbout && !showNotifications && !ignoreTarget) return\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setConfirmPlugin(null)\n setConfirmCustomTarget(null)\n setConfirmGlobalNpm(null)\n setUninstallPlugin(null)\n setUninstallItem(null)\n setDetailItem(null)\n setUninstallDone(false)\n setShowHubUpdate(false)\n setShowAbout(false)\n setShowNotifications(false)\n setIgnoreTarget(null)\n }\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [confirmPlugin, confirmCustomTarget, uninstallPlugin, uninstallItem, detailItem, showHubUpdate, showAbout, showNotifications, ignoreTarget])\n\n // Toast 统一自动消失\n useEffect(() => {\n if (!toast) return\n const timer = window.setTimeout(() => setToast(null), 2400)\n return () => window.clearTimeout(timer)\n }, [toast])\n\n /** 复制文本到剪贴板,返回是否成功(Clipboard API + 隐藏 textarea 兜底)。 */\n const doCopy = async (text: string): Promise<boolean> => {\n try {\n await navigator.clipboard.writeText(text)\n return true\n } catch {\n // Clipboard API unavailable (permissions/iframe) — fall back to the\n // legacy hidden-textarea trick, which works in any context.\n const ta = document.createElement('textarea')\n ta.value = text\n ta.style.position = 'fixed'\n ta.style.opacity = '0'\n document.body.appendChild(ta)\n ta.select()\n let ok = false\n try {\n ok = document.execCommand('copy')\n } catch {\n ok = false\n }\n document.body.removeChild(ta)\n return ok\n }\n }\n\n /** 命令行安装目标是否已安装(与服务端 already 判定同口径):GitHub 地址按仓库身份匹配\n * (归一化后比对已装项的 repo/spec),npm 包名按依赖 key 直查。命中 → 弹窗转「更新」语义\n * (mode=update 放行覆盖重装),避免重复点击撞 409 报错。 */\n const customTargetInstalled = (raw: string): boolean => {\n const target = raw.trim()\n if (!target) return false\n const repo = repoFromInstallTarget(target)\n const isRepo = /^[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+$/.test(repo)\n if (isRepo) {\n const needle = repo.toLowerCase()\n return catalog.installedItems.some((i) =>\n (i.repo !== null && i.repo.toLowerCase() === needle) ||\n repoFromInstallTarget(i.spec).toLowerCase() === needle)\n }\n // npm 包名(可带 @version):剥掉版本号后同时查已安装列表与原始依赖表。\n // Hub 自身(file:/link: 安装)被 installedItems 刻意排除(防误卸载),列表里查不到,\n // 但依赖表真实存在——补齐后「命令窗口重装 hub 自身」也能转「更新」语义,不再撞 already installed\n const pkg = repo.replace(/@[^@]*$/, '').toLowerCase()\n return catalog.installedItems.some((i) => i.name.toLowerCase() === pkg) ||\n Object.keys(catalog.installed).some((k) => k.toLowerCase() === pkg)\n }\n\n /** 弹窗动作一:复制安装命令到剪贴板,引导去终端粘贴执行(npm 通道显示包名命令)。 */\n const copyCommand = async (p: HubPlugin) => {\n const repo = p.source?.repo ?? ''\n const ok = await doCopy(installCommandOf(p))\n if (ok) {\n setCopied(repo)\n setToast({ id: Date.now(), kind: 'copied' })\n window.setTimeout(() => setCopied((cur) => (cur === repo ? null : cur)), 1600)\n }\n setConfirmPlugin(null)\n }\n\n /** 卸载弹窗动作:复制卸载命令,万一直接卸载失败可去终端手动执行。\n * 自定义安装(无目录数据)按已安装项包名直卸,同样给复制通道。 */\n const copyUninstallCommand = async () => {\n const name = uninstallItem ? uninstallItem.name : (uninstallPlugin ? catalog.installedName(uninstallPlugin) : null)\n if (!name) return\n const ok = await doCopy(`dsh plugin remove ${name}`)\n if (ok) setToast({ id: Date.now(), kind: 'copied' })\n }\n\n /** 详情弹窗动作:在系统文件管理器里定位安装目录;服务端失败给 toast 提示。 */\n const revealFolder = async (item: InstalledItem) => {\n const ok = await revealInstallFolder(item.name)\n if (!ok) setToast({ id: Date.now(), kind: 'revealFail' })\n }\n\n /** 「立即重启」:POST 同源 /restart,宿主进程自杀重启;随后轮询服务恢复后整页刷新。 */\n const requestRestart = async () => {\n if (restarting) return\n setRestarting(true)\n try {\n // 响应可能在宿主进程被 kill 前返回,也可能直接断连 —— 两种都属正常\n await fetch('/dsh-plugin-hub/restart', { method: 'POST' })\n } catch {\n /* 服务已终止,无需处理 */\n }\n // 轮询同源端点,服务恢复后整页 reload(让新挂载的 bundle 完全初始化)\n let attempts = 0\n const poll = async () => {\n attempts += 1\n try {\n const res = await fetch('/dsh-plugin-hub/active', { method: 'GET', cache: 'no-store' })\n if (res.ok) {\n window.location.reload()\n return\n }\n } catch {\n /* 服务尚未恢复 */\n }\n if (attempts < 60) {\n window.setTimeout(poll, 1000)\n } else {\n setRestarting(false)\n setToast({ id: Date.now(), kind: 'fail' })\n }\n }\n window.setTimeout(poll, 1200)\n }\n\n const { total, installedName, installedVersion, hasUpdate } = catalog\n // 统计数字:官网 /api/stats.json 优先;拉取失败时用已加载列表兜底,避免展示 undefined。\n const statsTotal = catalog.stats?.total ?? total\n const statsVerified = catalog.stats?.verified ?? 0\n\n const count = catalog.visible.length\n\n // Hub 自身条目(目录数据里的 dshplugin/dsh-plugin-hub):头部「可更新」徽标的更新目标。\n // useCatalog 在过滤目录(自身不进插件列表)前单独保留该条目;目录可能尚未加载(此时为 null,徽标不渲染)。\n const hubEntry = catalog.hubPlugin\n\n return h('div', { className: styles.root },\n h(CatalogHeader, {\n t,\n langPath,\n statsTotal,\n statsVerified,\n onToggleLang: toggleLang,\n // Hub 自身版本信息入口:版本号常驻可点(无更新也看得到当前版本更新内容),\n // 有可用更新时版本号后紧跟红色「可更新」徽标(同一入口),点击都打开同一个更新说明弹窗。\n // 有更新弹窗显示新版本 + Markdown 变更记录,点「直接更新」进安装弹窗覆盖重装。\n hubUpdate: catalog.hubHasUpdate,\n // 点击版本号/徽标:先强制刷新拉取最新版本信息(发版后点击即见新版本),再打开弹窗\n onVersionClick: () => {\n void catalog.refreshHub().then(() => setShowHubUpdate(true))\n },\n onAboutClick: () => setShowAbout(true),\n }),\n // 一级导航行:tab 占满左侧,通知入口靠右(「设置」tab 后边,右对齐)\n h('div', { className: styles.tabsRow },\n // 「已安装」徽标 = 目录插件 + 自定义安装总数(installedItems 已排除 hub 自身)\n h(SectionTabs, {\n view,\n setView,\n installedCount: catalog.installedItems.length,\n t,\n // 通知中心入口:红圈徽标 = 记录数 + 进行中任务 + 待重启(有动静才醒目)\n noticeCount: notifications.length + queue.queue.length + queue.pendingRestarts.length,\n onOpenNotifications: () => {\n // 打开弹窗时补齐更新提醒(受「启动时检查更新」开关约束):同一版本只一条,\n // 清空/删除后重开仍恢复,直到插件更新完成才消失\n if (hubSettings.checkUpdatesOnStart) syncUpdateNotices()\n setShowNotifications(true)\n },\n }),\n ),\n view === 'market'\n ? h(MarketView, {\n catalog,\n t,\n langPath,\n langKey,\n copied,\n // 列表头部「筛选出 N 条」:分类/搜索/安装状态筛选后的结果数;全部视图且未筛选时显示总数\n resultText: catalog.plugins === null || catalog.failed\n ? null\n : catalog.category === 'all' && count === total\n ? t('pluginsTotal', { n: count })\n : t('filterResults', { n: count }),\n onInstall: (p, opts) => {\n setInstallDone(false)\n setConfirmIsUpdate(opts?.update ?? false)\n // 与卸载一致:重置弹窗关联任务,避免新弹窗误匹配到进行中的任务而禁用安装按钮\n queue.clearModalTask()\n setConfirmPlugin(p)\n },\n onUninstall: (p) => {\n setUninstallDone(false)\n queue.clearModalTask()\n setUninstallPlugin(p)\n },\n })\n : view === 'installed'\n ? h(InstalledView, {\n items: catalog.installedItems,\n langKey,\n t,\n // 支持系统文件管理器定位的平台(macOS / Linux)上,行内「打开详情」替换为\n // 打开安装目录按钮(行点击本身即打开详情弹窗);Windows 不支持则按钮不显示\n platform: env?.platform ?? '',\n // 行点击 / 详情按钮:打开已安装详情弹窗(完整元数据 + 运行时信息)\n onOpenDetail: (item) => setDetailItem(item),\n onReveal: (item) => { void revealFolder(item) },\n // 更新:已安装视图的「更新」= 目录插件覆盖重装,与市场列表内更新同一流程\n onUpdate: (item) => {\n if (!item.plugin) return\n setDetailItem(null)\n setInstallDone(false)\n setConfirmIsUpdate(true)\n queue.clearModalTask()\n setConfirmPlugin(item.plugin)\n },\n // 卸载:目录插件与自定义安装统一按已安装项走卸载确认弹窗(自定义无目录数据,按包名直卸)\n onUninstall: (item) => {\n setDetailItem(null)\n setUninstallDone(false)\n queue.clearModalTask()\n setUninstallItem(item)\n },\n // 重启:待重启条目行内按钮 → 先弹「立即重启 / 稍后重启」确认(与通知中心一致),确认后才触发宿主重启\n onRestart: () => setShowRestartConfirm(true),\n })\n : view === 'custom'\n ? h(CustomInstallView, {\n t,\n // 命令行安装:与应用商店同一套确认/进度/结果弹窗 —— 输入 npm 包名 / GitHub 地址 /\n // dsh plugin 命令即装(custom 源,受安全设置三开关控制)。点安装先弹确认窗,\n // 确认后走队列安装(实时进度 + 成功结果视图);目标已安装 → 弹窗转「更新」覆盖重装,\n // 不再撞「already installed」报错(第一次安装没有反馈才导致用户重复点击)。\n // 安全信任开关关掉对应通道 → 卡片禁用并提示去设置打开(onOpenSettings 跳到设置页)。\n enableNpm: hubSettings.enableNpmInstall,\n enableGit: hubSettings.enableGitInstall,\n enableDsh: hubSettings.enableDshInstall,\n onOpenSettings: () => setView('settings'),\n onInstallCustom: (raw, opts) => {\n const target = raw.trim()\n if (!target) return\n setInstallDone(false)\n // 与目录安装一致:重置弹窗关联任务,避免新弹窗误匹配到进行中的任务\n queue.clearModalTask()\n // 官方全局 npm 安装(npm install -g <pkgs>):弹窗走 globalNpm 模式(系统级 CLI 工具,\n // 不进插件列表,不做「已安装→更新」判定 —— npm install -g 对已装包是原位覆盖更新,天然幂等)\n if (opts?.globalNpm && opts.globalNpm.length > 0) {\n setConfirmCustomTarget(null)\n setConfirmIsUpdate(false)\n setConfirmGlobalNpm({ raw, pkgs: opts.globalNpm })\n return\n }\n setConfirmGlobalNpm(null)\n setConfirmIsUpdate(customTargetInstalled(target))\n setConfirmCustomTarget(target)\n },\n })\n : h(SettingsView, {\n t,\n settings: hubSettings,\n update: updateSettings,\n reset: resetSettings,\n env,\n onCopy: (text: string) => {\n doCopy(text)\n setToast({ id: Date.now(), kind: 'copied' })\n },\n }),\n // Hub 版本信息弹窗:版本号/徽标点击打开 —— 有更新显示新版本 + 变更记录 + 「直接更新」,\n // 无更新显示当前版本 + 记录 + 「已是最新」。Worker 拉取失败时兜底展示当前版本号。\n showHubUpdate && h(HubUpdateModal, {\n info: catalog.hubUpdateInfo ?? { version: PLUGIN_VERSION },\n lang,\n t,\n hasUpdate: catalog.hubHasUpdate,\n onClose: () => setShowHubUpdate(false),\n onProceed: () => {\n setShowHubUpdate(false)\n // 与列表内更新同一流程:覆盖重装 dsh-plugin + 结果视图「立即重启」\n if (hubEntry) {\n setInstallDone(false)\n setConfirmIsUpdate(true)\n queue.clearModalTask()\n setConfirmPlugin(hubEntry)\n }\n },\n }),\n // 「关注我们」弹窗:GitHub 图标后按钮点击打开 —— 平台介绍 + 用户反馈群二维码,\n // 内容由 dsh-update Worker 的 /about 接口以 Markdown 形式推送,作者随时可改,非写死。\n // Worker 未推送(info 为 null)时弹窗仍能打开并展示兜底文案,不影响其他功能。\n showAbout && h(AboutModal, {\n info: catalog.hubAboutInfo ?? null,\n lang,\n t,\n onClose: () => setShowAbout(false),\n }),\n // 安装/卸载任务通知中心:本地持久化的成败清单,随时可回来查看/复制/清空;\n // 进行中的任务(实时进度)与待重启插件也一并展示,关掉任务弹窗后仍可盯着\n showNotifications && h(NotificationsModal, {\n records: notifications,\n tasks: queue.queue,\n pendingRestarts: queue.pendingRestarts,\n t,\n env,\n onClose: () => setShowNotifications(false),\n onCopy: (text) => {\n doCopy(text)\n setToast({ id: Date.now(), kind: 'errCopied' })\n },\n onClear: () => setNotifications(clearNotifications()),\n onRemove: (id: number) => setNotifications(removeNotification(id)),\n // 更新提醒通知:点击直接进该插件的更新确认弹窗(与已安装列表「更新」同一流程)\n onUpdate: (repo: string) => {\n const plugin = catalog.installedItems.find((i) => i.repo === repo)?.plugin\n if (!plugin) return\n setShowNotifications(false)\n setInstallDone(false)\n setConfirmIsUpdate(true)\n queue.clearModalTask()\n setConfirmPlugin(plugin)\n },\n // 更新提醒「忽略本次更新」:先弹确认弹窗,确认后该版本不再提醒(持久化),直到下一个新版本\n onIgnoreUpdate: (repo: string, version?: string) => setIgnoreTarget({ repo, version }),\n cancelTask: queue.cancelTask,\n restarting,\n onRestart: () => { void requestRestart() },\n // 失败记录仓库反查:历史记录可能存的是裸 npm 包名,反查成 owner/repo 才显示仓库链接\n // 与提 Issue 按钮;查不到则隐藏(防提到错误仓库)\n resolveRepo: (repo: string) => issueRepoOf(repo, catalog.installedItems, catalog.plugins),\n }),\n // 「忽略本次更新」确认弹窗:确认后该版本写入忽略集(持久化)并从通知中心移除,\n // 本次版本不再提醒,直到插件发布下一个新版本\n ignoreTarget && h('div', {\n className: modalStyles.overlay,\n onClick: (e: MouseEvent<HTMLDivElement>) => { if (e.target === e.currentTarget) setIgnoreTarget(null) },\n },\n h('div', { className: modalStyles.modal, role: 'dialog', 'aria-modal': 'true' },\n h('div', { className: modalStyles.modalHead },\n h('div', { className: modalStyles.modalTitle }, t('ignoreUpdateConfirmTitle')),\n h('button', {\n className: modalStyles.modalClose,\n type: 'button',\n 'aria-label': t('errorClose'),\n onClick: () => setIgnoreTarget(null),\n }, h(CloseIcon)),\n ),\n h('div', { className: modalStyles.modalBody },\n h('div', { className: modalStyles.failPrepareHint }, t('ignoreUpdateConfirmDetail')),\n h('div', { className: modalStyles.modalActions },\n h('button', {\n className: modalStyles.restartLater,\n type: 'button',\n onClick: () => setIgnoreTarget(null),\n }, t('confirmCancel')),\n h('button', {\n className: modalStyles.restartNow,\n type: 'button',\n onClick: () => {\n ignoreUpdate(ignoreTarget.repo, ignoreTarget.version)\n setNotifications(removeUpdateNotice(ignoreTarget.repo, ignoreTarget.version))\n setIgnoreTarget(null)\n },\n }, t('ignoreUpdateConfirm')),\n ),\n ),\n ),\n ),\n // 安装确认弹窗:锁定/进度/结果视图逻辑收敛在 modals.tsx;更新与安装同入口,仅标记 update\n confirmPlugin && h(InstallModal, {\n plugin: confirmPlugin,\n done: installDone,\n task: queue.installModalTask,\n t,\n langPath,\n restarting,\n update: confirmIsUpdate,\n // 仅命令行插件(webInstallable=false):弹窗只展示命令供复制,不提供一键安装\n cliOnly: confirmPlugin.install?.webInstallable === false,\n submitting: queue.submitting,\n needsRestart: installNeedsRestart,\n onClose: () => setConfirmPlugin(null),\n onCopy: () => copyCommand(confirmPlugin),\n onInstall: () => queue.installNow(confirmPlugin, confirmIsUpdate ? { update: true } : undefined),\n onRestart: () => { void requestRestart() },\n }),\n // 命令行安装确认弹窗:与目录安装同一套确认/进度/结果流程(plugin 传 null 走 customTarget 模式)。\n // 已安装目标 → update 标记,确认后走覆盖重装(服务端 mode=update 放行),不再 409 报错。\n confirmCustomTarget && h(InstallModal, {\n plugin: null,\n customTarget: confirmCustomTarget,\n done: installDone,\n task: queue.installModalTask,\n t,\n langPath,\n restarting,\n update: confirmIsUpdate,\n cliOnly: false,\n submitting: queue.submitting,\n needsRestart: installNeedsRestart,\n onClose: () => {\n setInstallDone(false)\n setConfirmCustomTarget(null)\n },\n onCopy: () => {\n doCopy(`pnpm add ${confirmCustomTarget}`)\n setToast({ id: Date.now(), kind: 'copied' })\n },\n onInstall: () => void queue.installCustom(confirmCustomTarget, confirmIsUpdate ? { update: true } : undefined),\n onRestart: () => { void requestRestart() },\n }),\n // 全局 npm 安装确认弹窗(官方 `npm install -g <pkgs>`):与应用商店同一套确认/进度/结果流程。\n // 装的是系统级 CLI 工具(如 @deepseek-ai/dsh),不进任何 profile、无需宿主重启;\n // 服务端任务终态 needsRestart=false → 结果视图仅「完成」。\n confirmGlobalNpm && h(InstallModal, {\n plugin: null,\n globalNpm: confirmGlobalNpm.pkgs,\n done: installDone,\n task: queue.installModalTask,\n t,\n langPath,\n restarting,\n update: false,\n cliOnly: false,\n submitting: queue.submitting,\n needsRestart: installNeedsRestart,\n onClose: () => {\n setInstallDone(false)\n setConfirmGlobalNpm(null)\n },\n onCopy: () => {\n doCopy(`npm install -g ${confirmGlobalNpm.pkgs.join(' ')}`)\n setToast({ id: Date.now(), kind: 'copied' })\n },\n onInstall: () => void queue.installGlobalNpm(confirmGlobalNpm.pkgs),\n onRestart: () => { void requestRestart() },\n }),\n // 卸载确认弹窗:确认/进度/结果视图逻辑收敛在 modals.tsx。\n // 已安装视图的自定义安装(目录外)没有完整目录数据,按已安装项伪插件适配后走同一弹窗\n (uninstallPlugin || uninstallItem) && h(UninstallModal, {\n plugin: uninstallPlugin ?? pluginOfItem(uninstallItem!),\n done: uninstallDone,\n task: queue.uninstallModalTask,\n t,\n langPath,\n restarting,\n submitting: queue.submitting,\n needsRestart: uninstallNeedsRestart,\n onClose: () => {\n setUninstallDone(false)\n setUninstallPlugin(null)\n setUninstallItem(null)\n },\n onCancel: () => {\n setUninstallPlugin(null)\n setUninstallItem(null)\n },\n onCopyCommand: copyUninstallCommand,\n onConfirm: () => {\n if (uninstallItem) void queue.uninstallItem(uninstallItem)\n else if (uninstallPlugin) void queue.uninstallNow(uninstallPlugin)\n },\n onRestart: () => { void requestRestart() },\n }),\n // 已安装详情弹窗:目录元数据 + 宿主运行时信息的完整展示,操作(更新/卸载/复制路径)由此发起\n detailItem && h(InstalledDetailModal, {\n item: detailItem,\n t,\n lang: langKey,\n langPath,\n onClose: () => setDetailItem(null),\n onUpdate: (item) => {\n if (!item.plugin) return\n setDetailItem(null)\n setInstallDone(false)\n setConfirmIsUpdate(true)\n queue.clearModalTask()\n setConfirmPlugin(item.plugin)\n },\n onUninstall: (item) => {\n setDetailItem(null)\n setUninstallDone(false)\n queue.clearModalTask()\n setUninstallItem(item)\n },\n onCopyPath: (path) => {\n doCopy(path)\n setToast({ id: Date.now(), kind: 'copied' })\n },\n onReveal: (item) => { void revealFolder(item) },\n }),\n toast && h(Toast, { toast, t }),\n // 操作失败:完整错误弹窗(重复安装、CLI 失败、请求错误等),可复制并去插件仓库反馈\n errorMsg && h(ErrorModal, {\n message: errorMsg.message,\n repo: errorMsg.repo,\n kind: errorMsg.kind,\n command: errorMsg.command,\n attempts: errorMsg.attempts,\n t,\n env,\n onCopy: (text: string) => {\n doCopy(text)\n setToast({ id: Date.now(), kind: 'errCopied' })\n },\n onClose: () => setErrorMsg(null),\n }),\n // 待重启确认弹窗:已安装列表行内「重启」按钮点击后弹出,稍后重启 / 立即重启\n showRestartConfirm && h(RestartConfirmModal, {\n t,\n restarting,\n onClose: () => setShowRestartConfirm(false),\n onRestartNow: () => {\n setShowRestartConfirm(false)\n void requestRestart()\n },\n }),\n )\n}\n","/**\n * DSH Plugin Hub — the community plugin marketplace for DeepSeek Harness.\n * Website: https://dsh-plugin.org\n * GitHub: https://github.com/dshplugin/dsh-plugin-hub\n *\n * dsh-plugin client entry: wires the Plugin Hub into the host settings via\n * the module-loader bundle (see tsdown.config.ts). All UI logic lives in\n * PluginHubSection; this file only performs the cordis apply wiring.\n */\nimport { createElement as h } from 'react'\nimport type { HubClientContext } from './types.ts'\nimport { en, zh } from './locales.ts'\nimport { PluginHubSection } from './components/PluginHubSection.tsx'\nimport './styles/tokens.module.css'\n\nconst NS = 'dsh-plugin'\n\nexport const name = NS\nexport const inject = ['slots', 'locale']\n\nexport function apply(ctx: HubClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), `${NS}: dictionaries`)\n const t = ctx.locale.bind(NS)\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: NS,\n order: 60,\n label: () => t('nav'),\n locale: NS,\n inject: () => ({ t, locale: ctx.locale }),\n }, () => h(PluginHubSection, { t, locale: ctx.locale })))\n}\n"],"mappings":"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"}