🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

插件崩溃防护 Zlyraz/dsh-ballute

DeepSeek Harness
Zlyraz79 天前有提交已提供中文文档扫描:含敏感能力

捕获插件崩溃并一键禁用,免重启恢复面板

27.8/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/16 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Zlyraz/dsh-ballute
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/09/26·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/03·判据 →
还在维护吗[仓库]—
更新放缓:最近一次提交在 79 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 17 处,展示前 16 条)
  • 读取本地文件
    lib/index.js:102
    text = await readFile(patchPath, 'utf8')
  • 写入本地文件
    lib/index.js:152
    await writeFile(tmp, content, 'utf8')
  • 写入本地文件
    lib/index.js:153
    await rename(tmp, path)
  • 读取本地文件
    lib/index.js:189
    return await readFile(path, 'utf8')
  • 读取本地文件
    lib/index.js:332
    const dir = await realpath(join(profileDirOf(profile), 'node_modules', moduleName)).catch(() => null)
  • 读取本地文件
    lib/index.js:340
    const dir = await realpath(linkPath).catch(() => null)
  • 写入本地文件
    lib/index.js:371
    await mkdir(dirname(path), { recursive: true })
  • 读取本地文件
    lib/index.js:446
    dirents = await readdir(nmDir, { withFileTypes: true })
  • 发起网络请求
    lib/client.js:113
    fetch("/api/ballute/v1/crash", {
  • 写入剪贴板
    lib/client.js:165
    await navigator.clipboard.writeText(`[ballute crash]\nplugin: ${rec.registrant ?? lang.unknown}\nslot: ${rec.slotKey}\nentry: ${rec.entryId ?? "?"}\na
  • 发起网络请求
    lib/client.js:175
    const res = await fetch("/api/ballute/v1/disable", {
  • 发起网络请求
    lib/client.js:229
    const res = await fetch("/api/ballute/v1/state");
  • 发起网络请求
    lib/client.js:242
    const res = await fetch(`/api/ballute/v1/crashes${q}`);
  • 发起网络请求
    lib/client.js:266
    const res = await fetch(`/api/ballute/v1/inspect?module=${encodeURIComponent(target)}`);
  • 写入剪贴板
    lib/client.js:279
    await navigator.clipboard.writeText(`[ballute crash]\nplugin: ${row.registrant ?? lang.unknown}\nslot: ${row.slotKey ?? "?"}\nentry: ${row.entryId ??
  • 发起网络请求
    lib/client.js:294
    const res = await fetch("/api/ballute/v1/disable", {
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 捕获插件崩溃
  • 一键禁用插件
  • 免重启恢复面板

README

由 DeepSeek 最新模型翻译生成
dsh-ballute(Ballute 气囊) DeepSeek Harness 插件崩坏防护:把插件故障从「安静退位」变成 可见 · 可归因 · 可恢复。 ballute = balloon + parachute(气球伞,减速缓冲之意)。 English quickstart dsh-ballute 是 DeepSeek Harness(DSH)的崩溃防护插件。DSH 会静默移除崩溃的插槽条目——你只会看到一个空白面板,标签页悄悄消失,错误只落在控制台里。Ballute 把它变成你能看见、能归因、能恢复的东西: | 防线 | 作用 | | L1 预检 | 静态契约检查(GET /api/ballute/v1/inspect)——在装载前捕获结构性故障 | | L2 隔离 | 通过官方 ctx.slots.onEntryError 钩子在右下角显示崩卡(插件 · 插槽 · 错误)| | L3 黑匣子 | 崩溃遥测 JSONL 日志 + 历史列表,重启不丢,rev 可精确定位代码版本 | | L4 恢复 | 崩卡上一键「禁用」→ 写入补丁层 → HMR 免重启卸载 | | L5 安全模式 | 最小 safe profile + 跨 profile 静态体检/禁用,救回坏掉的主 profile | 安装:
展开完整文档(README 剩余 1 节)
dsh-ballute(Ballute 气囊)

DeepSeek Harness 插件崩坏防护:把插件故障从「安静退位」变成 可见 · 可归因 · 可恢复。
ballute = balloon + parachute(气球伞,减速缓冲之意)。

English quickstart

dsh-ballute 是 DeepSeek Harness(DSH)的崩溃防护插件。DSH 会静默移除崩溃的插槽条目——你只会看到一个空白面板,标签页悄悄消失,错误只落在控制台里。Ballute 把它变成你能看见、能归因、能恢复的东西:

| 防线 | 作用 |
| L1 预检 | 静态契约检查(GET /api/ballute/v1/inspect)——在装载前捕获结构性故障 |
| L2 隔离 | 通过官方 ctx.slots.onEntryError 钩子在右下角显示崩卡(插件 · 插槽 · 错误)|
| L3 黑匣子 | 崩溃遥测 JSONL 日志 + 历史列表,重启不丢,rev 可精确定位代码版本 |
| L4 恢复 | 崩卡上一键「禁用」→ 写入补丁层 → HMR 免重启卸载 |
| L5 安全模式 | 最小 safe profile + 跨 profile 静态体检/禁用,救回坏掉的主 profile |

安装:

dsh plugin add github:Zlyraz/dsh-ballute

诚实边界:覆盖运行时插槽条目崩溃(L2 域)。装载器级故障——client apply 抛错,或 bundle 文件缺失——会在任何 UI 存在之前就杀死 client/host 启动;这些只能从 M4 安全模式救回。完整边界见下方诚实边界,包括 SlotAssemblyError 整页空白的情况。

维护:业余时间爱好维护——欢迎 issue 和 PR,但响应可能较慢。AI 协作者请先读 AGENTS.md。

能力(随里程碑生长)

| 防线 | 状态 | 说明 |
| L2 隔离 | ✅ M1 | 订阅官方 ctx.slots.onEntryError 缝隙 → 右下角崩卡(插件名 · 槽 key · 错误)|
| L4 恢复 | ✅ M1 | 崩卡「关闭插件」→ 写补丁层 disabled: true → HMR 免重启卸载 |
| L1 预检 | ✅ M2 | GET /api/ballute/v1/inspect 静态契约体检(装载前发现结构故障)|
| L3 观测 | ✅ M3 | 崩溃遥测 JSONL 黑匣子 + 历史列表(重启不丢,rev 号可对时)|
| L5 兜底 | ✅ M4 | 安全模式:safe 最小 profile + 跨 profile 静态体检/禁用恢复坏 profile |

诚实边界:M1-M3 只覆盖 L2 域(运行时条目崩溃)。装载器自身故障域分两级——client apply 抛错炸 client boot(host 还活着);bundle 文件缺失(load 档)炸 host 进程本身(curl 都不通)。两者都进不了 UI,只能靠 M4 安全模式从外部救(复现:装验收假人 crash-test-dummy 后开 ?dummyCrash=apply,或把 fixtures/fault-load 真实装进 profile)。

另一个崩卡管不到的缝隙(实测过):插槽组装错误会穿透错误边界卸载整树。DSH 的 SlotErrorBoundary 只吃普通渲染错误(条目退位 → 面板空白);SlotAssemblyError 家族(locale face 未就绪 / 缺 hookContext / session binding provider 外渲染,见 @deepseek-ai/dsh-client-web-react)会被重新抛出,前端无顶层兜底 → React 卸载整棵树 → 整页纯色无内容,偶发于 AI 子代理打开(session-aware 插槽重组装竞态)。此时 Ballute UI 一起没了,取证看 console 的未捕获 SlotAssemblyError,刷新即恢复;根治需官方加顶层错误页(已列入 issue 素材)。

安全模式(L5 兜底)

官方 CLI 暂无 --safe-boot 旗标(已探测,issue 草稿见 docs/issue-safe-boot.md),所以安全模式靠自建一个最小 profile:官方 bundle + 仅 dsh-ballute。主 profile 的 UI 坏死时,用它起一个能打开的实例,从外部救回坏 profile。

一次性搭建——在 $DSH_HOME/profiles/safe/ 下放四个文件:

package.json:

{
"name": "dsh-profile-safe",
"private": true,json
"dependencies": {
"dsh-ballute": "github:Zlyraz/dsh-ballute"
},
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"dsh-ballute"
]
}
}
}

cordis.yml(空树即可,插件树由补丁层组装): yaml []

cordis.patch.yml(保持空数组,别加别的插件进来): yaml []

pnpm-workspace.yaml: yaml packages:
- .
nodeLinker: hoisted
autoInstallPeers: false

然后在该目录 pnpm install。

用法:先停掉坏死的实例——注意 host 进程还活着时会照常响应探测,看起来“没死”,别被骗,确认端口释放后再起:

dsh --profile safe

profile 名为 safe 时 Ballute 自动进入安全模式:tab 顶部多出恢复区,列出目标 profile(默认 web)的全部第三方插件(包名 @版本 #rowId),每行可「体检」(静态 8 项)可「禁用」(写目标 profile 的用户补丁层,下次启动生效)。救完用正常方式重启主 profile 即可。

跨 profile API(safe 实例上):

- GET /v1/state 多返回 safeMode: true + recover: { target: "web", modules: [...] }
- GET /v1/inspect?module=&profile=web — 静态体检目标 profile 里的插件
- POST /v1/disable { "module": ..., "profile": "web" } — 跨 profile 禁用(runtimeEffect: "next-boot");守卫照常(基础设施/ballute 自身/名字格式全拦)

API(仅限本机同源)

- GET /api/ballute/v1/state — 自检状态 + 可体检的第三方模块清单
- GET /api/ballute/v1/inspect?module= — 体检已装插件(8 项检查:bundle 注册 id=包名 / exports.apply / exports.name / inject 服务键 / host 半边 / 补丁 name 守卫…)
- GET /api/ballute/v1/inspect?fixture= — 体检自带夹具:fault-load / fault-apply / fault-mismatch / fault-no-name
- POST /api/ballute/v1/disable { "module": "" } — 写用户补丁层停用(保护名单拦截基础设施行)
- POST /api/ballute/v1/crash — 崩溃遥测上报(client 自动调用):{ registrant, slotKey, entryId, message, stack, abdicated, at, count, rev } → 追加到 $DSH_HOME/ballute/crash-log.jsonl
- GET /api/ballute/v1/crashes?limit=20&plugin= — 崩溃历史(最新在前,每请求重读磁盘;超 600 条自动压实到最近 500)

黑匣子事件格式(schemaVersion: 1,字段版本化,供可视化插件等第三方消费): json { "schemaVersion": 1, "at": 1786814000000, "receivedAt": 1786815667828, "registrant": "crash-test-dummy", "slotKey": "shell.overlay", "entryId": null, "message": "受控 render 崩溃…", "stack": "Error: …", "abdicated": true, "count": 1, "rev": "a436f2444edf" }

rev = 崩溃时启动图内容哈希(window.__DSH_BOOT__.rev),可定位「哪个代码版本崩的」;abdicated: false 表示 chain 型(只上报不摘除)。

安装

dsh plugin add github:Zlyraz/dsh-ballute

维护状态:业余维护,响应可能较慢——欢迎 issue/PR,不承诺时效(AI 协作入口见 AGENTS.md)。

与 dsh-workshop 的配合

两个插件写同一份 cordis.patch.yml,不会互相踩——补丁写入工艺(原子写、串行队列、基础设施保护名单)本来就复用自 workshop。日常增删插件走 workshop;装完新插件可以用 ballute 体检一遍,真崩了就崩卡一键关闭,救不回来再进安全模式。

开发

dev profile 试装工作流(先隔离验证,再扶正)

1. 装进一次性 dev profile(与日常 web profile 隔离,炸了不影响主环境):

dsh plugin --profile dev add /path/to/dsh-ballute
2. 起独立实例验证(不同端口避免冲突;具体旗标以 dsh web --help 为准):

dsh web --profile dev --port 3081
打开 http://127.0.0.1:3081,检查:设置→插件 出现 Ballute tab;再装验收假人 crash-test-dummy 跑一遍崩卡流程。
3. 扶正:验过后再装进日常 profile:

dsh plugin --profile web add /path/to/dsh-ballute
4. 手动 link 方式(开发期改代码即生效,推荐):在 profiles/web/package.json 的 dependencies 加 "dsh-ballute": "link:/abs/path/to/dsh-ballute",dsh.profile.bundles 数组加 "dsh-ballute",然后 profile 目录内 pnpm install,重启 dsh web。

自测

curl 'http://127.0.0.1:3080/api/ballute/v1/inspect?fixture=fault-mismatch'
curl 'http://127.0.0.1:3080/api/ballute/v1/inspect?module=crash-test-dummy'

第二条需要先装验收假人:dsh plugin add github:Zlyraz/crash-test-dummy。

四个夹具各含一种契约违例(缺 client 文件 / 缺 exports.apply / 注册 id≠包名 / 缺 exports.name),体检应逐一报出且归因正确。

踩过的坑

- client bundle 一定要导出 name(= 包名)。cordis 的 fiber 名取自 exports.name,缺了的话崩溃归因会落到内部 fiber 上(面板里只会看到 x6 这种名字,看不出是谁崩的)。
- 手写 bundle 的话,__ModuleLoader__.load({ id }) 的 id 必须等于包名。
- cordis.patch.yml 初始是 [],直接追加会得到非法结构,先剥掉空数组再写;写入走原子写 + 串行队列。

许可

MIT(见 LICENSE)
预览分享卡片长什么样 ↓Zlyraz/dsh-ballute
分享 · DeepSeek Harness Hub
Zlyraz/dsh-ballute

捕获插件崩溃并一键禁用,免重启恢复面板

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部