Deepseek-Harness-Desktop/vendor/dshmarket

127Star9Fork0Issue0Watching

DeepSeek Harness 内的可视化插件市场:浏览精选列表、一键安装、热启用/禁用、主题切换、备份与诊断;预装于 Deepseek-Harness-Desktop 桌面端。

语言
JavaScript
License
MIT
分支
main
deepseekdeepseek-harnessdsh-plugin

安装

$ dsh plugin --profile web add github:ChisaAlter/Deepseek-Harness-Desktop/vendor/dshmarket

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

一句话定位

dshmarket 把 DeepSeek Harness 的插件安装、主题切换、备份与诊断装进了一个可视化的「应用商店」——在 DSH 设置页里点开「插件市场」就能浏览社区精选列表、点一下装好常用插件、随时换主题、把整套配置备份到本机或云端;这个副本是 Deepseek-Harness-Desktop 桌面端预打包的版本。

核心能力

  • 浏览和搜索精选列表中的社区插件,支持分类筛选、最热/最新排序和中英双语描述,跟随界面语言切换(README.md:36)
  • 一键安装并实时显示进度:npm 包走 npm tarball 秒级完成,GitHub 源走整仓下载;多数插件无需重启即可热加载(README.md:38 / lib/hot.js:1-17)
  • 主题独立标签管理:安装立即生效、点一下切换(互斥,跨重启保留),卸载即恢复默认(README.md:38 / lib/themes.js:1-6)
  • 备份与恢复 profile:本地下载 JSON、上传到 WebDAV(仅 https)、或同步到 GitHub 私有 Gist;恢复采用合并方式,写入前校验、失败自动回滚(README.md:40 / lib/backup.js:1-22)
  • 逐插件检测更新(npm latest dist-tag 或 GitHub HEAD 对比),一键更新单个或全部(README.md:41)
  • 自定义插件分组:把常用插件归到一组、组级别一键开关(每次仍走单插件的持久化路径)(lib/groups.js:1-11)
  • 一键重启:当变更无法热加载时,在待重启提示旁提供重启按钮;仅接受同源回环请求,进程管理器托管时可关闭(README.md:43 / lib/restart.js:1-65)
  • 配置文件级诊断:bundle 顺序、loader id 冲突、核心包多版本、覆盖与孤儿行等问题块,并支持「AI fix」一键复制排错提示词到剪贴板(README.md:48-49)

技术实现

  • 语言: TypeScript(Node.js ESM);客户端 UI 由 React 18 + ui-primitives 写成单文件 bundle client/client.js(client/client.js:1037 / package.json:91-93)
  • 关键依赖: @deepseek-ai/cordis ^4.0.1(peerDep,宿主框架);js-yaml ^4.1.0(解析 bundle patch YAML);undici ^7.29.0(HTTP 客户端);@deepseek-ai/dsh-settings ^0.1.0-rc.7(peerDep 可选,仅 dsh 0.1.0-rc.7+ 可用)
  • 架构模式: 宿主 + 客户端双形态 —— 宿主侧 apply(ctx, config)cordis.webServer 上挂载 /dsh-market/* HTTP 路由,客户端侧通过 cordis slots 在「设置」页注册「插件市场」section 和安装完成 toast;安装通过 node:child_process 调起 dsh plugin 子进程,主题与补丁通过 cordis 的 user patch layer + 自定义 hot mount 实现「无需重启」的活体切换;检测到宿主暴露 desktopProfiles 时走桌面端路径(用宿主自带的 desktopPnpm 而不是再 spawn 一个 pnpm,allowRestart 强制 false)(lib/index.js:26-69)
  • 入口文件: 宿主入口 lib/index.js(导出 nameConfigapply);客户端入口 client/client.js(UI 单文件 bundle);HTTP 路由表在 lib/routes.jscordis.patch.ymlid: dsh-market 的 bundle 层插入 profile 的层栈

适用场景

日常用 DSH web 或 Deepseek-Harness-Desktop 桌面端、想从社区里挑插件而不是手敲 dsh plugin add 命令的用户;想在多台机器间同步 profile、或在出问题时快速拿到「脱敏日志 + 诊断」反馈给开发者的用户;以及想把主题、功能插件归组管理、按需开关的运维型用户。在桌面端,DHH Desktop 内置的 dsh 通常可能比 npm 上拿到的旧(README.md 提到的 #139),所以桌面端用户更需要这个市场来统一更新插件。

前置依赖与兼容性

依赖最低版本说明
DSH>= 0.1.0-rc.6客户端 UI 需要 ui-primitives 导出 Menu/DisclosureRow/Tooltip/Toast;旧宿主会让市场 section 自动跳过注册而不致白屏(README.md:28-30)
DSH(可选 settings 卡片)>= 0.1.0-rc.70.1.0-rc.7+ 才有 dsh-settings 服务,市场才会在「插件配置」页面管理自己(选 channel、看版本、移除)(lib/settings.js:1-34)
Node.js未声明package.json 未设 engines;宿主 Node 由 dsh web 决定
pnpm任意安装时调用 dsh plugin,依赖宿主自带的 pnpm;若缺失会触发一键自动安装
平台macOS / Windows / Linux跨平台代码;Windows 单独处理 .cmd shim、PowerShell 隐藏窗口重启、taskkill 杀进程树
原生模块仅用 Node.js 内建模块(node:fs / node:child_process / node:https / node:os / node:path / node:dns

安装方式

dsh plugin --profile web add github:ChisaAlter/Deepseek-Harness-Desktop/vendor/dshmarket

配置项

市场支持两层配置:插件级(写在 profile 的 cordis patch 配置里)和环境变量级。

插件配置(在 cordis 传入 apply(ctx, config)

配置类型说明默认值
profile字符串告诉市场要操作的 profile 名称;不传时自动从 dsh 启动参数 --profile 推断argv 里的 --profile 值,否则 web
allowRestart布尔是否允许一键重启;被 systemd/launchd/pm2 托管时请设为 falsetrue(桌面端模式下强制为 false

环境变量

变量说明
DSH_HOMEDSH 主目录;不设时默认 ~/.dsh,profile 解析到 <home>/profiles/<name>
DSHM_REGISTRY_URL覆盖精选列表来源(默认 https://awesome-dsh-plugin.com/plugins.json);仅用于 e2e 测试指向本地 fixture
DSH_MARKET_INSTALL_TIMEOUT_MS一次 pnpm 操作的最长等待时间(毫秒),超时后自动杀进程树
DSH_MARKET_HOT_MOUNT_TIMEOUT_MS一次插件热挂载激活的最长等待时间,超时后回退到「重启后生效」
DSH_GITHUB_TOKENGitHub Gist 同步用的 token;不设时可粘贴 token(仅会话内存)或使用已登录的 gh CLI

常见问题

Q: dshmarket 和 awesome-dsh-plugin.com 是什么关系?

A: 市场只显示 awesome-dsh-plugin.com/plugins.json 精选列表里的插件,安装请求只接受列表内的来源;想上架插件需要去 awesome-dsh-plugin 仓库提 PR,本仓库只读该列表。

Q: 安装后需要重启 DSH 吗?

A: 大多数纯 insert 形式的插件可以热加载(无需重启、刷新页面即可用);含配置行/表达式的 bundle patch、纯客户端插件、或激活超过 10 秒未就绪的插件会被提示「重启后生效」,界面提供一键重启按钮。

Q: 主题和工作组件有什么不同?

A: 主题属于互斥资源,同一时间只能激活一个(装新主题自动停用旧主题,卸载即恢复),仅在「Themes」标签管理;普通插件则可独立开关并归入自定义分组。

Q: 备份能跨机器同步吗?

A: 可以。三种通道:本地 JSON 下载、WebDAV 上传/拉取(仅 https、拒绝内网地址)、GitHub 私有 Gist(需 gh CLI 已登录或 DSH_GITHUB_TOKEN 环境变量)。恢复采用合并方式——备份后装的插件会保留。

Q: 一键重启在什么情况下不可用?

A: 当 DSH 由 systemd、launchd、pm2 等进程管理器托管时,请在插件配置里设 allowRestart: false,交由管理器负责重启;市场显示待重启提示但隐藏按钮。此外重启接口只接受本机同源回环请求,无法远程触发。

Q: 市场对宿主基础插件(如 HMR、webserver)会怎么处理?

A: 这类插件被锁定禁止开关。市场会显示「属于宿主基础设施,禁止开关」,避免误关 HMR/传输/存储链导致整个宿主无法热加载。

Q: 怎么排查安装失败?

A: 页面顶部「导出日志」按钮生成一份脱敏的纯文本日志(home 路径和密钥形状已遮盖),可贴到 GitHub issue;诊断页(Diagnostics)会展示 bundle 顺序、loader id 冲突、核心包多版本、覆盖与孤儿行等问题块。

Q: Deepseek-Harness-Desktop 里这个市场和别处装的 dshmarket 是一回事吗?

A: 是同一个插件(package.json 中 name=dshmarket、插件 id dsh-market,cordis.patch.yml 把 id=dsh-market 的层注入 profile 的层栈),版本 1.14.0;只是被预打包到 Deepseek-Harness-Desktop 的 vendor/ 目录随桌面端一起分发,安装命令使用 github: 路径指向 vendor 子目录。

上手难度

入门 — 安装即用、零配置,主页三个标签覆盖了 80% 的日常需求;遇到 pnpm / 网络 / 构建脚本等具体错误时市场会用中英双语给出可操作的指引,无需查文档。

已知问题与限制

  • config/expression 行的 bundle patch、纯客户端插件(仅 dsh.clientdsh.bundle)、或激活超过 10 秒未就绪的插件只能「重启后生效」,市场会在界面给出具体原因而不是统一提示(lib/hot.js:33-38)
  • 通过 link: / file: 链接安装的本地插件无法在 UI 里更新(要从 checkout 目录手动同步)
  • pnpm 11 默认的 minimumReleaseAge(约 24 小时)会拦截刚发布的版本,市场会自动重试一次 --config.minimumReleaseAge=0(lib/install.js:43-79);但若 registry latest 指向一个旧版本,「更新」按钮会拒绝把已装的精确版本降级到 @latest
  • 大型 GitHub 源插件(下载整仓)在慢网下会触发 pnpm 60 秒下载超时,市场会自动用 --config.fetchTimeout=600000 重试一次,仍超时则报错(lib/install.js:43-79)
  • 重启接口只接受 127.0.0.1 / ::1 同源回环请求,禁止任何代理转发头;远程重启场景不可用(lib/restart.js:40-61)
  • 同一 profile 里两个插件声明了相同的 loader entry id 时安装会被拒绝并自动移除新插件(防止下次启动失败),需要单独建 profile 给这类插件
  • 备份的 JSON 体积上限 2 MB、文件数上限 256;GitHub Gist 单文件上限 1 MB;超出会被拒(lib/backup.js:16-17)
  • 在 macOS 通过 Finder/Dock 等图形入口启动 DSH 时,子进程拿不到终端 PATH,市场会自动补 /opt/homebrew/bin/usr/local/bin~/.local/bin,但极少数 PATH 完全为空的场景仍需在终端里启动
  • 桌面端(DHH Desktop / Deepseek-Harness-Desktop 类)内置的 dsh 可能比 npm 上拿到的旧(README.md 提到的 #139),所以桌面端用户使用本市场更新其它插件前,可能需要先解决宿主 dsh 的版本问题