Frame-level scan diagnostics for session files (torn/corrupt/empty detection).
Install
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:omdsh-dev/dsh-session-health
GitHub-sourced plugins run build scripts on your machine at install time. Only install sources you trust, and pin a commit (github:owner/repo#sha).
README
DSH session health check plugin — performs frame-level scan diagnostics on multi-frame zstd session files under $DSH_HOME/sessions (torn / corrupted / empty sessions / stray files), and outputs a health report with cleanup suggestions. Read-only: never modifies or deletes any file.
Repository: https://github.com/omdsh-dev/dsh-session-health (public)
Motivation
While investigating issue #376 on 8/7, we ran a full decode analysis over 39 session files and discovered a key fact in the process: DSH session files are a concatenation of multiple zstd frames (a 19MB session = 119,952 frames). Reading a multi-frame file with a single-frame decode API only reveals the header — which once caused a false "all sessions empty" judgment. This diagnostic logic deserves to be productized as a tool: the model can directly ask "is my session file healthy" instead of relying on hand-written scripts.
Complementary to dsh-session-repair-skill (which repairs corrupted sessions): this tool discovers via read-only diagnostics → the repair skill repairs.
Security Model
- Read-only guarantee: never modifies/deletes any file (covered by the "file byte counts unchanged after scanning" test, see the files.spec SH-06 case)
- Path fencing: session ids go through a strict directory-name whitelist (prevents
../traversal); both the absolute path and the final file passfs.realpathreal-path containment checks (prevents symlink/junction escape); enumeration uses lstat to reject symlinks - Zero business dependencies: the zstd frame scanner is an independent implementation (reads bytes with DataView, RFC 8878 structure, differential-consistent with the official
scanZstdFrames) - Deep analysis optional: with
deep: truethe official decoder is dynamically imported; on parse failure it explicitly degrades todeep: "unavailable", never silently - Fixed input scope (sessions directory), no network, no execution surface
Tool Declaration
Registers the session_health tool (@deepseek-ai/dsh-session-health, row id tool-session-health), uniformly outputting JSON text.
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
string | ✅ | scan / file / stats |
path |
string | Absolute file path (must be within the sessions root) or session id (required for file/stats) | |
deep |
boolean | Deep analysis (decoded event statistics), default false | |
detail |
boolean | List abnormal files (scan defaults to true); false returns only the summary |
Detection Items
| Category | Determination |
|---|---|
missing |
Session id resolves to no file |
empty |
0-byte file |
not-zstd |
First 4 bytes are not 28 b5 2f fd (plaintext .jsonl or corrupted) |
torn |
EOF interrupts a frame tail (interrupted write) |
reserved-header / reserved-block |
Invalid reserved bits in the frame header/block header (structural corruption) |
bad-header |
deep mode: the first frame is not a session header |
empty-session |
Only 1 frame (header) and not updated for over 1 minute |
oversized-single-frame |
Single frame > 1MB (normal multi-frame writes do not do this) |
interrupted |
deep mode: has turn/start but no turn/end (process killed/crashed) |
stray-file |
*.tmp / leftover files with non-standard names |
The report contains: root / scanned / errors / suspicious / totals(bytes·frame count·event-batch estimate) / detail / deep / suggestions (suggestions give cleanup/repair advice per the issue template, not executed automatically).
Examples
session_health { action: "scan" }
→ {"root":"C:\\Users\\admin\\.dsh\\sessions","scanned":39,"errors":{...},"suspicious":{...},"suggestions":[...]}
session_health { action: "file", path: "session-abc123", deep: true }
→ 单文件报告(含事件分布与中断检测)
npm 0.1.0-rc.6 Compatibility (verified)
This plugin has been migrated to the npm 0.1.0-rc.6 dependency line, and full end-to-end verification was completed in an isolated consumer of @deepseek-ai/dsh@0.1.0-rc.6:
- Types/runtime:
@deepseek-ai/cordis@^4.0.1+@deepseek-ai/dsh-tools@>=0.0.1-rc.1 <0.2.0+@deepseek-ai/dsh-invariants@>=0.0.1-rc.1 <0.2.0(peer); no longer depends on unscopedcordis - Standalone build:
npm install(devDependencies self-contain typescript/vitest/@types/node) →npm run typecheck→npm test→npm run build→npm pack - Consumption verification: tarball loaded into an rc.6 consumer → the plugin's row appears in
dsh --profile compat --dump-config→ real tool registration and execution passed - Startup method:
npx -p @deepseek-ai/dsh@0.1.0-rc.6 dsh web(lib production mode; do notinstall -gglobally)
Known limitation: under npm 0.1.0-rc.6, the
@deepseek-ai/dsh-session-persistence-jsonltarball that deep mode depends on still does not include src/, and its root entry still does not export the zstd API; deep degrades todecoder-unavailable; frame-level scanning is unaffected (reported to dsh-external/issues — that organization is org infrastructure and remains in place).
Installation
Under DSH 0.1.0-rc.6 (npm), plugins are installed via dsh plugin --profile <profile> add <source>; source is a GitHub repository or an npm pack tarball.
Install from GitHub (Recommended)
# 交互式(web)profile
dsh plugin --profile web add github:omdsh-dev/dsh-session-health
# 一次性任务(headless)profile —— dsh run 默认使用 headless
dsh plugin --profile headless add github:omdsh-dev/dsh-session-health
Install from npm pack tarball
The npm pack artifact can be installed directly as source:
dsh plugin --profile web add dsh-session-health-*.tgz
The bundled dsh.bundle.patch automatically adds the plugin to the profile's layer stack after installation (row id: tool-session-health). The plugin's missing peer dependencies (@deepseek-ai/cordis, @deepseek-ai/dsh-tools) are provided by the profile's healed profiles/node_modules fallback installation.
⚠️ web and headless are different profiles: installing into web does not automatically cover headless;
dsh runuses the headless profile by default. Use forward slashes for Windows paths (C:/...).
Verifying the Installation
dsh --profile web --dump-config | grep tool-session-health
Runtime Verification
dsh run "使用 session_health 工具扫描会话目录健康状态"
Legacy Scenario: monorepo / Local-Path Installation
The monorepo approach is now a legacy scenario (local junction/symlink, manually editing the profile layer, legacy snapshots without GitHub/tarball source support):
dsh plugin --profile web add "C:/path/to/dsh-session-health"
Testing
node <monorepo>/node_modules/vitest/vitest.mjs run tests
zstd-scan.spec.ts: boundaries of frames generated by the official compressor / multi-frame / not-zstd / truncated / reserved bits + real-session differentials (large/medium/small files frame-by-frame identical to the officialscanZstdFrames; reads local sessions read-only, not committed to the repo)files.spec.ts: two-level directory enumeration, stray/jsonl identification, path fencing (traversal/symlink/out-of-bounds rejection), session id resolution, read-only guaranteereport.spec.ts: error/suspicious count bucketing, suggestions templates, empty results, deep degradation annotationregister.spec.ts: registration contract (AUDIT-CROSS-02 style)
Known Limitations
deepdepends on dynamically importing the official decoder: at runtime in a profile, if the package cannot be resolved, it explicitly degrades to frame-level scanning (the report is annotated withdeep: "unavailable")- Event-batch estimate = frame count - 1 (each batch has at least 1 frame; not an exact event count, the report notes it is an estimate)
License
MIT
Links
More in this category
hust-open-atom-club/oh-dsh★ 161
Community distribution: TUI, desktop, and Web UI as one bundle with layered installation.
Jayden-X-L/forkprobe★ 65
Compare multiple skills on the same task and pick the winner.
vlln/plugin-registry★ 33
Ecosystem infrastructure: a thin browser console for managing official repository plugins (zero patches) plus a make-dsh-plugin skill for guided plugin development.
forrestchang/dsh-multica-runtime★ 28
Run the dsh runtime on Multica.
DietCokewithSugar/dsh-user-experience★ 18
Finds potential UX issues in your project: automatically reviews React/TypeScript code, pinpoints each problem, and gives concrete suggestions.
omdsh-dev/dsh-plugin-check★ 17
Plugin health checks: manifest protocol / patch format / build traps, zero-dependency and read-only.