DSH Hub

mrzhangkris/dsh-session-pruner

dsh-session-pruner

UIWeb UI1 GitHub stars· updated 2026-08-21

dsh-session-pruner is a community DeepSeek Harness plugin. Read the repository README before installing.

Install

npx @deepseek-ai/dsh plugin --profile web add dsh-session-pruner

Restart `dsh web` after install. Bundle APIs can change during the developer preview.

README badge

dsh-session-pruner DSH Hub badge
[![DSH Hub](https://dshhub.dev/badge/dsh-session-pruner.svg)](https://dshhub.dev/plugins/dsh-session-pruner)

Paste this into your README. The star count updates with every catalog sync.

From the README

Excerpt from mrzhangkris/dsh-session-pruner, cleaned of badges and images.

dsh-session-pruner

DSH session lifecycle management plugin — full-type session lifecycle management: one-shot subagents archived on completion, continuable subagents and main sessions archived when idle, a capacity cap, and projection-cache cleanup. Prevents session-library accumulation stalls at the source.

Every session type has a defined destination: finished one-shot subagents are archived automatically, idle continuable subagents / main sessions are archived, and overflow is recycled by priority. Archive first (recoverable), delete after expiry — the GUI syncs within 30s, fully panel-configured with hot reload.

简体中文 · Apache-2.0 · npm

Why

DSH (DeepSeek Harness) caches a full projection of every session in session_projcache.json (token stats, context pressure, ...), and the storage backend rewrites the whole file atomically on every write. When the session library accumulates thousands of subagent sessions:

  • The cache balloons past 100MB and each checkpoint fully re-serializes → main process CPU 250%+
  • The single-threaded event loop is saturated → every session load stalls, even GET / times out

Managing session lifecycle (this plugin) is the root fix: no session accumulation → no cache rows → no stalls.

Features: full-type lifecycle

Session typeTriggerActionDefault
one-shot subagentlog contains session/end-seed (finished)archive/delete at next scan30min interval
continuable subagentidle over N daysarchive (recoverable)off (0 days)
main sessionidle over N daysarchive (recoverable)off (0 days)
any typetotal exceeds capacity caprecycle by one-shot → continuable → main + oldest400
archive directorykept over N hoursphysically deleted24 hours

Archive mechanism (recoverable)

Cleaned sessions are moved to ~/.dsh/sessions-archive/ first (workspace/session-id structure preserved) — they disappear from the GUI immediately (the list only reads the sessions directory), but the files remain and can be restored manually:

# Restore: mv back into the sessions directory
mv ~/.dsh/sessions-archive/<workspace>/<session-id> ~/.dsh/sessions/<workspace>/

A "delete directly" mode (no archive, irreversible) is also available.

Safety (double protection)

  • Running sessions are never touched: logs without session/end-seed are never cleaned (checked in both the one-shot path and the capacity cap)
  • live protection: sessions still held in the in-memory session store (open/loading) are skipped
  • Main sessions do not participate in capacity recycling by default (configurable)
  • Per-action failure isolation: every action is try/catch wrapped

How it works

scan (scheduled, default 30min)
  ├─ pruneArchive: physically delete expired archive sessions
  ├─ iterate ~/.dsh/sessions/*/ decompress log (system zstd, multi-frame)
  │     ├─ origin: main | subagent       (session header)
  │     ├─ mode: one-shot | continuable  (subagent/descriptor event)
  │     └─ ended: contains session/end-seed
  ├─ one-shot + ended ──→ archive (archiveMode)
  ├─ continuable/main idle N days ──→ archive
  ├─ total > cap ──→ recycle by priority + oldest (skip running/live)
  └─ each archive also: purge projcache row + workspace accounting

Related plugins