aokamoaki / dsh-startup-guard

Listed

Boot-time guard for DeepSeek Harness: repairs corrupt session logs, preflights plugin composition, smoke-tests host apply(), and quarantines crash-causing bundles so a broken plugin never bricks startup.

mainSession View source

Installation

npx -y @deepseek-ai/dsh plugin --profile web add github:aokamoaki/dsh-startup-guard

This installation command is an unverified starting point generated from the GitHub repository address.

README

Maintainer-authored documentation snapshot.

View on GitHub ↗
Commit 82cead8Synced Aug 18, 2026

🛡️ dsh-startup-guard

简体中文 | English

DeepSeek Harness 启动守卫 —— 在启动前修复会话日志、预检插件组合、执行宿主插件冒烟测试并隔离崩溃源,让「插件损坏 / 日志损坏」再也无法把 DSH 卡死在启动。

Check version npm license node dsh tests


📖 简介

DSH 的功能由大量第三方插件组合而成:某个插件包缺失、patch 语法损坏、client 产物未构建、甚至宿主 apply() 抛一个运行时异常,都可能让整个应用启动即崩。dsh-startup-guard 在启动早期异步执行七道检查,能自动修复 / 回滚 / 隔离问题源——它是「解析 → 组合 → 执行 → 崩溃兜底」的四层防线,而不仅仅是一组文件检查。

安装后零配置即生效,日常开销 < 0.5s。

✨ 核心能力

#检查行为
1会话日志修复修复 session.jsonl[.zstd] 的 seq 损坏(删重复行或截断到已提交点);帧级检测 zstd 永久 torn 尾帧并截断;清理已删除会话的过期缓存条目。修复前原件备份repair-backups/
2清单快照 + 指纹每个 profile 的 package.json / cordis.patch.yml / pnpm 清单 + link 插件源码快照到 plugin-snapshots/,记录每 bundle 的 host/client/patch 内容指纹(保留最近 N 份)
3Bundle 预检 + 回滚校验第三方 bundle 目录可解析;缺失时回滚到最新可完全解析的快照(24h 宽限防死循环);坏清单另存为 package.json.broken
4组合预检 + 修复检测 entry id 重复、name: 不可解析、YAML 致命形态;name: 失效的 row 自动禁用(带备份);致命形态在 strict 模式写块标记,启动器拒绝启动
5客户端 bundle 有效性校验 exports["./client"] 存在、注册 __ModuleLoader__.load,并在 vm 沙箱真实执行加载;检测跨 bundle 重复 client id;损坏自动禁用
6宿主 apply() 冒烟在子进程 + mock Cordis 环境执行每个第三方插件的 apply(),识别「启动即抛」的运行时错误(如 ReferenceError);结果按内容指纹缓存
7崩溃隔离启动器/桌面应用检测到上次启动崩溃时写崩溃标记,宿主插件也会自写启动标记dsh-boot-state.json:启动时写入、正常关闭清除、异常退出遗留)——两类证据都让本次启动强制全量冒烟并自动禁用冒烟失败的插件,让「崩溃 → 自动禁用 → 恢复启动」闭环成立。纯 web(dsh web,无任何外壳)同样生效

🚀 快速开始

dsh plugin --profile web add dsh-startup-guard          # npm(预构建,免构建授权)
# 或从源码安装:
dsh plugin --profile web add github:aokamoaki/dsh-startup-guard

已发布到 npm:dsh-startup-guard@1.0.0npm 页面)。

重启 dsh web 后自动生效。首次启动会:

  1. 扫描并(如有需要)修复会话日志;
  2. 快照当前插件清单;
  3. 对每个第三方插件做一次宿主冒烟 + 客户端校验;
  4. 把结果写入 ~/.dsh/dsh-preflight-report.json 供你查看。

⚙️ 模式与配置

配置文件:~/.dsh/dsh-startup-guard.json(缺省使用默认值)。

模式行为
report只检测与报告,绝不修改任何文件
fix(默认)自动修复 / 自动禁用 / 自动回滚
strictfix + 致命组合形态写块标记,启动器拒绝启动并弹窗
{
  "mode": "fix",
  "smoke": true,
  "smokeTimeoutMs": 15000,
  "clientVmCheck": true,
  "clientFactorySmoke": false,
  "quarantineOnCrash": true,
  "autoRepairComposition": true,
  "tornTailGraceMs": 300000,
  "keepSnapshots": 10,
  "exclude": ["some-bundle-i-trust"]
}
配置项默认说明
modefixreport / fix / strict
smoketrue是否执行宿主 apply() 冒烟
smokeTimeoutMs15000单个冒烟子进程超时
clientVmChecktrue是否在 vm 中真实加载 client 产物
clientFactorySmokefalse是否额外调用 client factory(stub require)
quarantineOnCrashtrue崩溃标记在场时强制全量冒烟
autoRepairCompositiontrue自动禁用 name: 失效的 patch row
tornTailGraceMs300000判定"永久 torn 尾帧"的停写时长
keepSnapshots10保留的快照份数
exclude[]永不触碰的 bundle 名单

🛡️ 自动禁用的安全策略

冒烟跑在 mock 环境,失败可能是真实 bug,也可能是插件依赖真实 DSH 服务的环境缺口。因此:

  • 单独的冒烟失败不会自动禁用(只写入报告与 fixNeeded);
  • 上次启动确实崩溃过(崩溃标记在场)→ 冒烟失败插件自动禁用;
  • 插件显式声明 "dsh": { "smoke": true } → 冒烟失败自动禁用;
  • 插件声明 "dsh": { "smoke": false } 或在 exclude 中 → 跳过冒烟;
  • 客户端产物损坏(解析类检查)→ 照常自动禁用。

误禁用时,删除 profile cordis.patch.yml 里对应的 - id: "xxx" / disabled: true 条目即可(原 patch 已备份到 repair-backups/)。

🗂️ 数据位置

~/.dsh/
├── dsh-preflight.log            # 运行日志(超阈值自动轮转 .old)
├── dsh-preflight-state.json     # 扫描状态 + 冒烟指纹缓存
├── dsh-preflight-report.json    # 每次运行的机器可读摘要
├── dsh-crash-state.json         # 崩溃标记(启动器/桌面应用写入,guard 消费后删除)
├── dsh-boot-state.json          # 启动标记(宿主插件写入、正常关闭清除;异常退出时作为崩溃证据)
├── dsh-preflight-block.json     # strict 模式拦截标记(启动器读取)
├── dsh-startup-guard.json       # 配置(可选)
├── repair-backups/              # 修复/禁用前的原文件备份
└── plugin-snapshots/            # 清单 + link 源码 + 指纹快照

🔌 集成

guard 有三个入口,任一崩溃场景都有兜底;纯 web(不经任何外壳直接 dsh web)也具备崩溃隔离——宿主插件自写启动标记,上次启动未正常结束即视为崩溃:

  1. 桌面客户端(dsh-desktop-app):spawn server 前以子进程运行 guard-runner.mjs;server 崩溃时写崩溃标记,正常退出清除启动标记
  2. Web 启动器(dsh-launcher.ps1):启动循环内调用 guard-sessions.mjs;崩溃时写标记;发现 strict 块标记则拒绝启动并弹窗;正常停止清除启动标记
  3. 宿主插件:dsh web 启动早期异步执行;写/清启动标记,并据启动标记触发隔离

CLI:

node guard-sessions.mjs                # fix 模式
node guard-sessions.mjs --dry-run      # 只报告,不修改任何文件
node guard-sessions.mjs --mode report  # 同 dry-run
node guard-sessions.mjs --mode strict  # fix + strict 拦截

核心 API:

import { runGuard } from 'dsh-startup-guard/lib/guard-core.mjs';
const r = await runGuard(home, { dryRun: true });
// r: { repaired, rolledBack, autoDisabled, broken, hostBroken,
//      smokeUnresolved, issues, fixNeeded, blocked, crash, lines, ... }

🛠️ 开发

dsh-startup-guard/
├── lib/
│   ├── index.js          # 宿主入口(fire-and-forget,动态 import)
│   └── guard-core.mjs    # 核心:runGuard + 全部检查
├── test/guard-core.test.mjs  # 73 个用例(node:test,mock home,零依赖)
├── cordis.patch.yml      # bundle 注册
└── package.json
npm test                          # node --test(73 个用例)
node guard-sessions.mjs --dry-run # 对真实 home 干跑(只读)

设计原则

  • fire-and-forget:守卫自身失败只写日志,绝不抛进启动流程;
  • 原子写:所有文件修改均 tmp+rename,中途崩溃不留半写文件;
  • 优雅降级:会话解码器缺失时只跳过会话扫描,其余检查照常;
  • 单实例锁dsh-preflight.lock 串行化多个入口,避免并发写竞态。

📄 许可

MIT


DeepSeek Harness 社区插件,与 DeepSeek 官方无关。

Project files and signals

Shown items are public repository signals detected in the directory snapshot.

TestsDetected
Contributing guideDetected

Repository information

Language
JavaScript
License
MIT
Last updated
Aug 16, 2026, 9:07 AM

Install deliberately

Review source code, permissions, lifecycle hooks, dependencies and network access. Test untrusted plugins in an isolated environment.