- 홈
- 플러그인
- 개발 및 플러그인 도구
- dsh-market-expand
dsh-market-expand
jackbessaliuz/dsh-market-expand
DSH 플러그인 마켓용 보조 플러그인입니다. DSH가 종료된 뒤 설치된 npm 플러그인을 일괄 업데이트하고 다시 실행하며, 다음 부팅이 실패하면 업데이트로 망가진 플러그인을 롤백합니다. 로컬 링크 플러그인의 업데이트 확인과 스냅샷도 지원합니다. Windows DSH Desktop 전용입니다. 마켓 플러그인 dshmarket를 보완하는 패치이지 대체품이 아닙니다. 마켓 탭을 쓰려면 dshmarket를 설치하세요.
설치
dsh plugin --profile web add github:jackbessaliuz/dsh-market-expandREADME
dsh-market-expand
给 DSH 插件市场补五块缺口:一键更新全部、更新前红绿灯、更新失败自动回退、本地插件更新检测、DSH 本体更新兜底。
这是什么(大白话)
DSH 的插件市场(dshmarket)已经很好用,但有四件事它自己做不了:
- 更新它自己 —— 市场的更新流程是「先卸掉自己、再装新版本」。卸载那一步会把市场从运行中的组合里摘掉,后面「装新版本」的代码根本跑不到。所以官方提示永远是「退出 DSH,去命令行装,再打开」。
- 更新带子进程的插件 —— 比如自带守护进程的插件,运行中更新会被文件占用顶回来。
- 管不了本地插件 —— 用
link:挂进来的本地开发插件,市场不检测它们的更新。 - 装不上 DSH 本体的更新 —— 官方更新器把包装好了,却卡在「宿主优雅退出」这一步(
graceful task teardown),包一直躺在pending\里。本插件接管最后一步:退出后静默安装、验版本、把 DSH 开回来。
这个插件把这四件事接过来:在 DSH 里点一下,退出 DSH,剩下的它自己做完,并把 DSH 开回来。
你能得到
1. 一键更新全部
按钮在哪:市场 「分组」页面里,「本地化插件」 模块的右上角(和「⟳ 检测更新」并排)。
找不到?它会自动兜底,不会因为分组怎么改就消失:
- 有「本地化插件」分组 → 挂它的右上角
- 没有它 → 「未分组」区块(市场内置的,永远存在)
- 连「未分组」都没有 → 第一个分组

上图是兜底位置:把所有分组都删掉时,按钮出现在「未分组」的右上角。
点开后:
- 扫描当前 profile 里所有 npm 插件的 registry 最新版(包括市场自己)
github:安装的插件也在范围内:没有 npm 版本号可查的,就对比仓库的最高 semver tag- 勾选要更新的 → 排队 → 右下角立刻弹出进度窗,显示「已排队 N 个,等待 DSH 退出」
- 你从托盘右键退出 DSH
- 助手在后台用桌面端自带的 CLI 安装(失败自动回退
pnpm),并补写dsh.profile.bundles - 装完自动把 DSH 重新打开
点完没反应是旧版最大的问题——现在排队成功当场就有进度窗和「已排队 N 个」的按钮状态;排队期间再点按钮不会报错,而是打开排队详情(可以取消)。
1.5 更新前红绿灯
勾选面板里逐包标风险,点「更新」之前就能看出来:

- 🔴 跨大版本 / 预发布版(-beta / -rc) / 会改动官方预设注入 —— 更可能要单独处理
- ⚪ 新版本发布不足 24 小时 —— 市场里也显示「新版等待中」,社区还没验证过;和红灯一样默认不勾选
- 🟡 GitHub 源 —— 只是装得慢(要 clone 仓库),不是危险
- 🟢 普通升级 —— 每行都带灯,不再"全绿时看着像没灯"
红灯和白灯默认不勾选:它们表示「这个包更可能出问题 / 还没被验证」,不是禁止更新。想装就手动勾上;真出问题有下面的启动自检 + 自动回退兜底。
1.6 装完再验一次 + 失败自动重试(v1.4.0)
- 装完再验一次:安装命令跑完会读一遍
node_modules/<包名>/package.json里的真实版本。pnpm 有时因为engines之类的问题返回非零退出码、可文件其实已经写进去了——以前会被误判成失败,现在按真实结果记账。 - 失败自动重试:第一遍跑完,对「换个条件可能有救」的失败(写锁被占、超时、构建脚本未放行、网络、普通失败)自动再试一次,只重试这些包;第二次成功就以第二次为准。目标版本根本不存在(404 / 无匹配版本)不重试——重试多少次都没用,直接报原因。
- 两遍之后仍失败的,报告里单列「需手动处理」,附原始错误。
2. 更新安全网(重点)
更新完重启,如果 DSH 起不来:
重启 → 60 秒自检 → 发现新的 crash-*-web-boot.log
→ 解析出是哪个插件崩的 → 只回退「本次更新过的」
→ 抢在「禁用全部插件」对话框被点之前结束进程
→ 装回旧版本 → 重启 → 再自检一次
为什么需要:桌面端启动失败会弹一个只有「禁用全部插件」按钮的窗口,点下去 sanitizeProfile() 会改名 patch 文件、重置 bundles —— 你的定制会全部失效。这个助手会在你点它之前,自己把问题处理掉。
如果新起的宿主进程提前退出(常见于旧实例的子进程还没退干净、被单实例锁顶掉),助手会等 8 秒确认是否已有实例接管,不会像旧版那样直接放行。
2.5 组合破坏检查(2026-10-21 新增)
有些插件更新后不会让 DSH 崩溃,却会把 Agent 预设弄没:它们的 dsh.bundle.patch.yml 会给官方 preset 注入某个服务,或者依赖自己 insert 的条目。一旦那个服务被你在 patch 里 disabled: true,四个 preset 会全部停在 pending —— 设置页「Agent 预设」整页空白、旧会话报 Unknown agent preset: xxx。
这类失败不写 crash log,启动自检看不见。所以更新完、重启前,助手会扫一遍本次更新包自带的 bundle patch,把风险点名写进日志和进度窗,例如:
⚠ 组合风险:billion-context 依赖自己 insert 的条目 "bili-native",
而你的 profile 把它禁用了 —— 可能导致插件或 preset 失效
更新前还会备份 package.json / cordis.patch.yml / .dsh-market/state.json,万一真被 sanitize 了也能捞回来。
3. 本地插件检测与快照
先在市场「分组」页新建一个名为「本地化插件」的分组,把 link: 插件加进去,再点 ⟳ 检测更新:
从 v1.2.4 起这个分组不再由插件自动创建——插件只读
state.json,不写它。原因是这个文件由市场和一个长期运行的内存对象共同维护,插件再插一脚会造成groups/groupOrder错位(表现为"分组还在,但点分配到报分组不存在")。分组和成员现在完全归你自己管。
- 按每个插件各自配置的 npm 包名或 GitHub 仓库比对版本
- 有更新时行内出现 ⬆,升级走「自动快照 → 合并 → 校验」,冲突会转成「建议手动」
- 保留最近 3 份快照,出问题可一键回滚
进度看得见
点完按钮右下角就会弹一个原生小窗,四步轨:更新 → 自检 → 回退 → 重启,每个阶段换颜色,不用盯着黑屏猜它有没有在跑。
v1.2.0 起:
- 点完 1 秒内就弹(显示「等待 DSH 退出」),不用等宿主退出才出现
- 窗口里滚动显示真实日志行(每条
dsh plugin add … → ok/FAIL)——DSH 关掉后,这是唯一能看到进度的地方 - 完成保留 60 秒、失败永久停留(右上角 × 自己关);旧版完成 3 秒就关,人一走开就错过
- 失败时在桌面写一份
market-expand-更新失败-<时间>.txt:失败包、自检结论、组合风险、日志和备份路径全在里面,DSH 起不来也不用翻.dsh
左:更新中(蓝色,显示 4/6 · 包名 → 版本)
右上:启动失败后自动回退(橙色,前两步已绿,正在回退肇事插件)
右下:完成(全绿)
三张截图为 v1.0 的旧布局;v1.2 窗口更高,中间多了滚动的日志区。
和 dshmarket 的关系
不是替代品,是补丁层。 dshmarket 负责「逛、装、卸、分组、备份、诊断」这些日常;本插件只补它做不了的三件事。两者可以同时安装,互不干扰。
5. 🖥 更新 DSH 本体
为什么需要它:官方 electron-updater 负责下载和校验,但最后一步「退出 DSH 后安装」经常卡在 Host did not complete graceful task teardown——包完整下在 %LOCALAPPDATA%\@deepseek-aidsh-desktop-updater\pending\,就是装不上。
怎么用:市场「分组」页面,「⬆ 更新全部」旁边多出「🖥 更新 DSH」。
- 没有已下载的包 → 会提示你先去官方更新提示里点一次「更新」
- 有包 → 确认后排队,界面显示「已排队 · DSH 本体 0.2.2-rc.1」
- 退出 DSH → 助手依次做:校验 sha512 → 清掉残留同名进程 → 静默安装
/S --updated→ 读app.asar验版本 → 重新打开 DSH - 安装失败不会重启(避免把装了一半的 DSH 开起来),原因写进
~/.dsh/market-expand/update.log
服务端接口:GET /desktop-update-pending(只读探测)、POST /desktop-update(排队)。
安装
dsh plugin --profile <profile> add github:Jackbessaliuz/dsh-market-expand
走 GitHub 分发,没有发到 npm(npm 上搜
dsh-market-expand是 404,别用add dsh-market-expand)。 想锁版本就加#v1.4.0;不带 tag 会锁到当时的 commit,之后不会自动跟 main。
官方桌面端请在应用自己的「设置 → 插件」里安装——那个 profile 归应用的插件管理器所有。
代理
检测 GitHub 源、查询 registry 时可能需要代理。本插件从环境变量读取,不写死任何地址:
| 变量 | 说明 |
|---|---|
DSH_GIT_PROXY | 优先级最高,如 http://127.0.0.1:7890 |
HTTPS_PROXY / HTTP_PROXY | 标准变量,兜底 |
DSH_GIT_INSECURE=1 | 自签证书环境才需要,放宽 git 的 TLS 校验(默认不放宽) |
一个都没有就直连。也可以写在 ~/.dsh/.env 里,插件启动时会自动读。
它动了哪些文件
只在需要更新时、且 DSH 完全退出之后:
~/.dsh/market-expand/—— 队列、报告、日志、更新前备份、进度状态- 当前 profile 的
package.json(依赖与 bundles)与node_modules - 只读
crash-*-web-boot.log,不修改 - 更新失败时在桌面写一份
market-expand-更新失败-<时间>.txt
不会碰你的 cordis.patch.yml、会话和记忆库。
版本历史
- v1.4.1(2026-11-08):DSH 本体更新兜底。①市场「分组」页「⬆ 更新全部」旁边新增「🖥 更新 DSH」按钮;②官方 electron-updater 把包下好却卡在「优雅退出」时,由本插件在 DSH 退出后接管:校验 sha512 → 清残留同名进程 → 静默安装
/S --updated→ 读app.asar验版本 → 重新打开 DSH;③安装失败不重启(不把装了一半的 DSH 开起来),原因写进~/.dsh/market-expand/update.log;④README 安装段改为 GitHub 源命令(npm 上没有这个包,照 npm 名装会 404)。 - v1.4.0(2026-10-25):四色红绿灯 + 两轮重试 + 安装后校验。①每行都带灯:🔴 高风险 / ⚪ 新版本发布不足 24 小时(市场也在等) / 🟡 GitHub 源 / 🟢 普通升级(以前全绿时看着像没灯);②红灯与白灯默认不勾选,面板显示顺序也是「绿黄 → 白 → 红」;③第二轮重试:第一遍失败后只挑「换条件可能有救」的(写锁被占 / 超时 / 构建脚本未放行 / 网络 / 普通失败)自动再试一次,目标版本不存在(404)不重试;④安装后校验:pnpm 因
engines等返回非零、但文件其实已写入时,按node_modules里真实版本记账,不再误判失败;⑤pnpm 11 的allowBuilds自动放行(v1.3.1 起)+ git 源连不上时走 codeload 快照兜底(先探包入口文件,仓库不带构建产物的跳过)。 - v1.3.1(2026-10-24):修 pnpm 11 装 git 源插件时的两个新坑。①
ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED——pnpm 11 要求在 profile 的pnpm-workspace.yaml里按「包名@精确 tarball URL」放行该包的 build scripts,而按 commit 钉版本的 git 依赖每换一个 commit 键就变一次,于是每次更新都撞同一处、回滚也一样装不上。现在从 pnpm 报错里解析出精确 key,追加到allowBuilds(只加不删,旧 commit 的键留给回滚;已存在不写;改前备份pnpm-workspace.yaml.bak-<时间戳>)后原地重试一次;解析不出就只报告、不乱改配置。②失败分类新增allow-builds(构建脚本未放行)与network(git fetch 128 / 域名解析失败 / 连接超时),不再混进「没有可用的更新通道」;文案直接说清是「没放行」还是「连不上 GitHub」、下一步该做什么。 - v1.3.0(2026-10-22):新增更新前红绿灯——勾选面板逐包标风险:🔴 跨大版本 / 预发布版 / 会改动官方预设注入;🟡 GitHub 源(只是慢);绿=普通升级。红灯默认仍勾选,只提示「更可能要单独处理」。修掉「慢包把后续包连带卡死」——单个包的安装上限 300 秒 → 600 秒(与官方
idleTimeoutMs对齐,GitHub 源的包本来就可能装 5 分钟以上);超时后用taskkill /T /F杀整棵进程树(旧版只杀外层cmd.exe,残留的node会一直占着 profile 写锁,导致后面每个包都白等 120 秒后失败);遇到写锁被占用时先等锁释放、再重试一次;回退pnpm前确认没有残留的官方 CLI 进程(两条通道并发写会把 profile 写坏);失败报告按超时 / 写锁占用 / 通道不可用分类,不再一律写「没有可用的更新通道」。补掉**「重启假阳性」:旧自检只看「进程存活 + 没 crash 日志」,进程活着但窗口没出来也会报「通过」——现在查主窗口句柄,90 秒没窗口就判定卡住,杀进程重开一次,并把窗口恢复到前台**(不再只留任务栏);窗口一出现立即收尾;启动期间进度窗每 4 秒刷新「已等 N 秒」。另外修掉 2026-10-22 的「认证 cookie 撑爆」事故:桌面版每次启动新增一条dsh-auth-*(随机端口命名、60 天有效、从不清理),攒到 71 条时 Cookie 头超过 Node 默认 16KB 上限 → host 拒收 → Electron 欢迎页认证失败 → 窗口不出现(手动双击也打不开)。现在每次重启宿主前自动清理dsh-auth-*并备份 cookie 库;no-window时读宿主 stdout,识别到Web authentication failed就标记auth-cookie-overflow并清理后重试。 - v1.2.4(2026-10-21):插件不再写
state.json(不自动建组、不清理分组),彻底避免与市场内存状态冲突导致的分组错位;「本地化插件」分组改为由用户手动创建;检测时若分组为空会给出明确提示。 - v1.2.3(2026-10-21):「⬆ 更新全部」改用三级锚点——「本地化插件」分组 → 市场内置的「未分组」区块 → 第一个分组,从此不会再"装了看不到";修掉诊断徽标在 MutationObserver 回调里写 DOM 导致的界面卡死(幂等化 + observer 单例);扫描面板「全部已是最新」文字改琥珀黄。
- v1.2.1(2026-10-21):排队面板加「⚡ 立即重启并更新」;进度窗改用
conhost.exe启动(桌面端终于能看到)、贴右下角、实时滚动日志、关闭按钮无焦点框、成功后保留 5 分钟;按钮状态每 4 秒轮询;自检时长按包数动态(1 个 10 秒 → 10 个 30 秒);README 加「更新按钮在哪」。 - v1.2.0(2026-10-21):进度窗提前到点完即弹 + 实时日志行 + 完成 60 秒/失败常驻;新增组合破坏检查(识别会改写官方 preset inject、或依赖被禁用条目的更新包);自检修正「宿主进程提前退出直接放行」;失败时桌面写报告;「更新全部」按钮挪进「本地化插件」分组;
/update不再二次扫描(避免静默丢包);排队中可取消。 - v1.0.0(2026-10-21):首个开源版,含一键更新全部 + 启动自检自动回退 + github 源支持。
License
MIT