npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lanbaolu/dsh-fail-soft

v0.1.17

Published

自动隔离损坏插件,让 DSH 在坏插件面前照常启动:坏插件被禁用、其余插件正常装配,提供隔离管理与一键恢复 UI(deepseek-harness plugin that quarantines broken plugins so the service keeps booting, with status tools, a one-click restore panel and auto patch adaptation)

Readme

@lanbaolu/dsh-fail-soft

当前状态:核心稳定候选(v0.1.17)

仍依赖 DSH 内核补丁:升级 DSH 后请通过 fail_soft_statuspatch 字段 确认补丁健康状态,若显示 needs-adaptation 请先更新 backup/ 模板再继续使用。

插件错误自动隔离:坏插件被禁用、其余插件照常启动,提供隔离管理与恢复 UI。

解决的问题

DSH 的插件装配是 fail-loud:bundle 里任何一个插件加载/激活失败,整个 dsh web 服务就起不来(进程退出,GUI 打不开)。装一个坏插件 = 服务瘫痪, 且报错是一长串内部堆栈。

本插件让服务在坏插件面前照常启动:坏插件被自动隔离(写 disabled patch), 其余插件正常装配;隔离列表可查、可一键恢复(工具 + UI 面板)。

组成

| 部分 | 文件 | 作用 | |---|---|---| | 挂载兜底 | lib/mount.js | 被 DSH 内核(DSH_FAIL_SOFT=1 时)在 include 树挂载前动态加载:坏插件 → 隔离 → 剔除重试 | | 运行期服务 | lib/index.js | failSoft 服务 + fail_soft_* 工具 + /api/fail-soft/* HTTP API | | 上下文工具 | lib/context-utils.js | profileDirOf / 持久化开关读写(零 DSH 依赖) | | UI 面板 | lib/client.js | 设置面板「Fail-soft 隔离」区域:状态 + 一键开关 | | 第 2 层进程兜底 | scripts/failsoft-web.mjs(bin:dsh-failsoft-web) | 进程外启动包装器:内核补丁失效/未装配时仍能自己解析崩溃、自己写隔离、退避重拉 |

前置条件(一次性)

内核需要"fail-soft 委托插槽"补丁(极小,只做发现与委托,逻辑全在本插件)。

  • npm 安装用户(0.0.9+):不需要手动打补丁。npm 包自带 backup/ 补丁模板, 插件每次启动时 heal 会自动检测;若内核是官方原版会自动打上补丁, 首次安装后请重启一次 dsh 让挂载兜底生效。
  • 本地开发:也可用 node patch-apply.mjs(见工作目录 防止插件错误挂不起服务/, sha256 校验,DSH 更新后重打)。

不装内核补丁时:本插件的运行期服务/UI 仍可用(查隔离、手动隔离、恢复), 但挂载期自动隔离不生效(崩溃发生在任何插件加载之前,纯插件无法拦截)。

跟随 DSH 官方更新(内核补丁自愈)

DSH 官方升级 = npx 重新拉包到新的 ~/.npm/_npx/<hash>/ 目录,内核补丁 会被覆盖丢失。本插件每次启动时自动运行 内核补丁自愈lib/heal.js):

  • 动态定位实际运行的 DSH 安装(不硬编码 npx hash:从当前进程 argv 推断; 0.1.17 起支持 Desktop App——dsh 内核跑在 Electron 主进程、argv 无内核 路径时改从 process.resourcesPathapp.asar.unpacked 定位);
  • 检测补丁状态:ok(已打)/ needs-apply(丢失,npx 重装同版本)/ needs-adaptation(官方改了代码结构);
  • 自动重打:仅当目标与"已知原始版"一致时安全重打(含 profile-boot-*.js 文件名 hash 变化的情况);
  • 官方改动结构时报告 needs-adaptation 并提示更新 backup/ 模板,绝不破坏新版代码

补丁健康状态可通过 fail_soft_status 工具、/api/fail-soft/statuspatch 字段)、 UI 面板(🧩 行)查看。命令行重打:node patch-apply.mjs(与插件共用同一套 heal 逻辑)。

版本适配:当官方大幅重构挂载链路、自愈报告 needs-adaptation 时,需要更新 backup/ 里的 orig/patched 模板(抓官方新版 → 重打 → 存模板),通常一个版本一次。

安装(装入 profile)

⚠️ 命名必须与包名完全一致:本插件的包名是 @lanbaolu/dsh-fail-soft(带 scope)。 profile 的 dependencies key、bundles 条目、node_modules 链接、以及 cordis.patch.yml 的 insert name 必须全部使用这个完整包名不要因为仓库/目录名是 dsh-fail-soft 或 tgz 文件名是 lanbaolu-dsh-fail-soft-*.tgz 就注册成裸名 dsh-fail-soft —— 那样 DSH 会按 @lanbaolu/dsh-fail-soft 找模块而找不到,启动直接 ERR_MODULE_NOT_FOUND 崩溃(2026-08-19 事故根因)。

推荐使用 DSH 官方安装(自动按包名注册):

dsh plugin --profile web add @lanbaolu/[email protected]

⚠️ 请带上版本号:pnpm 11 有供应链冷却期(minimumReleaseAge)与元数据 缓存,刚发布的版本用不带版本号的 add 可能解析到旧版;显式 @版本号 一定拿到指定版本(本行版本号随每次发布同步,见下方当前状态)。

# 手动装(务必保留完整包名,以 web profile 为例)
#    ~/.dsh/profiles/web/package.json:
#      "dependencies": { "@lanbaolu/dsh-fail-soft": "link:<本目录>" }
#      "dsh": { "profile": { "bundles": [ ..., "@lanbaolu/dsh-fail-soft" ] } }
# 2. 建 junction:node_modules/@lanbaolu/dsh-fail-soft → 本目录
# 3. 构建时已 link 运行时依赖(@deepseek-ai/dsh-app-boot、@deepseek-ai/dsh-tools
#    进本插件的 node_modules),无需额外安装。

启用 fail-soft

方式一:持久化开关(推荐,终端 / App 通用)

插件 0.0.8+ 提供持久化开关,App 启动(不加载 shell 环境变量)也能用: 内核补丁启动时读取 ~/.dsh/fail-soft.json,无需手动设置任何环境变量。

0.1.14 起首次安装自动启用:开关文件不存在时,插件激活即写入 enabled: true(装防崩溃插件本身即启用同意),下次重启生效;已存在的 开关文件一律尊重(含显式 false)。装完后无需任何手动开启步骤。

⚠️ 唯一例外:若安装时服务已经因坏插件起不来,插件没有机会激活写 开关——先用环境变量进一次安全模式,隔离坏插件后即恢复: DSH_FAIL_SOFT=1 npx @deepseek-ai/dsh web(App 用户可手动创建 ~/.dsh/fail-soft.json,内容 {"enabled": true})。

  • UI(0.0.10+):DSH 设置面板 → 「Fail-soft 隔离」区域,一键开关 (0.1.15 起面板注册改走官方 slots.inject 契约:设置 slot 声明未就位 时等待而非报错——修复部分安装上"装完即 slot 'settings.section' is not declared"崩溃的反馈;即便注册失败也只降级为无面板,核心隔离能力照常);
  • 工具:fail_soft_set_enabled(true) / fail_soft_set_enabled(false)
  • API:POST /api/fail-soft/set-enabled,body { "enabled": true }
  • 效果:写入 ~/.dsh/fail-soft.json重启 dsh 后生效fail_soft_statusswitchEnabled / enabled 字段反映当前开关状态。

方式二:环境变量(原有)

DSH_FAIL_SOFT=1 npx @deepseek-ai/dsh web          # 临时
echo 'export DSH_FAIL_SOFT=1' >> ~/.zshrc          # 永久(仅终端启动生效)

DSH_FAIL_SOFT 取值:1|true|yes|on。可用 DSH_FAIL_SOFT_MODULE 覆盖 内核加载的挂载模块(默认按包名解析本插件)。环境变量与持久化开关二者 任一开启即生效。

使用

  • 自动隔离:坏插件激活失败 → 诊断打印 + 写 - id: <entryId>\n disabled: true(带 # quarantined by @lanbaolu/dsh-fail-soft 注释)到 profile 的 cordis.patch.yml → 剔除重试挂载 → 服务照常起。 写入经 mergePatchBlock 合并(0.1.2 起):patch 是空数组 [](DSH 默认 无补丁形态)时用条目块替换而非追加,产出始终是单个合法 YAML 数组——隔离器 自己不会再写坏 patch。 0.1.14 起分类隔离:只隔离"真坏插件"。瞬态环境错误(EADDRINUSE 端口被占等)与官方核心组件(@deepseek-ai/*)失败不写持久隔离, 改为抛回原始错误 fail-loud——避免把端口冲突误判成坏插件、把官方 webserver 永久隔离导致"服务活着但 GUI 消失"。
  • 工具(模型可直接调用):fail_soft_status / fail_soft_list / fail_soft_restore / fail_soft_quarantine / fail_soft_repair
  • HTTP APIGET /api/fail-soft/statusGET /api/fail-soft/listPOST /api/fail-soft/restore {id}POST /api/fail-soft/quarantine {id,name,reason}POST /api/fail-soft/repair
  • 修复引擎(0.1.8+)fail_soft_repair 一键修复——补丁丢失自动重打; 官方改结构自动回滚到官方原版(挂载兜底不生效但服务能起)并给适配指引; 同时去重 profile patch 里重复的 entry id(集成 dsh-fix / dev_fix_patch 能力)。
  • UI 面板:web 会话侧栏 conversation.view 显示隔离列表与恢复按钮。
  • 恢复:修复插件后删除 patch 文件里对应条目(或用 restore 工具/UI)。

第 2 层:进程级兜底(v0.1.16+)

场景:内核补丁被官方大改回滚、或 fail-soft 插件自身没起来(Desktop App 内嵌 内核不在 heal 扫描范围)时,挂载兜底(第 1 层)兜不住。第 2 层把兜底搬到 进程外:外层进程与一切插件解耦,捕获 dsh 崩溃输出 → 解析坏插件 → 自己写隔离 → 带退避重拉。不依赖内核补丁,也不依赖插件被装配。

# 拉起 dsh web(进程外兜底,退出码透传)
dsh-failsoft-web
# 透传参数给 dsh web / 指定 profile / 指定 dsh 入口
dsh-failsoft-web -- --port 3080
dsh-failsoft-web --dsh /Applications/DSH\ Desktop.app/.../dsh/lib/bin.js
DSH_PROFILE=desktop dsh-failsoft-web --dsh <desktop bin>   # Desktop 场景
# 调参
dsh-failsoft-web --max-restarts 3 --backoff-ms 2000

行为:dsh 正常退出(0) 透传退出;崩溃 + 解析出可隔离插件 → 写 disabled patch 后自动重拉;崩溃 + 无可隔离对象 → 跑 doctor 诊断,最多再给一次机会。

已知边界

  • 只兜"插件加载/激活失败"。profile 的 cordis.patch.yml 用户手写坏(YAML 语法错):fail-soft 下会给出诊断并自动从写前备份恢复(0.1.6 起, 写前备份 .bak.<ISO> + 解析失败自动恢复);非 fail-soft 仍 fail-loud, 但会提示如何恢复。本插件自己的隔离写入由 mergePatchBlock 保证合法 (0.1.2 起,空数组 [] 替换而非追加)。
  • 每轮最多隔离一批失败插件并重试,5 轮后放弃(服务以降级树启动,不崩)。
  • 挂载期自动隔离需要内核补丁 + DSH_FAIL_SOFT=1(崩溃在插件加载前)。
  • 运行期工具/API 采用延迟注册:bundle 装配可能早于 tools/webServer 服务就绪,插件会监听服务注册事件自动补注册;因此重启后 fail_soft_* 工具和 /api/fail-soft/* 会随服务就绪自动出现,不需要手动热重载

开发者

构建 / 发布(TP 自动上传 + preflight 门禁)/ 回归测试等维护流程见 RELEASE.md