DSH Plugins Marketplace

DSH Plugins

Plugins

/

Sessions & Messages

/

dsh-context-keeper

d

dsh-context-keeper

Manifest valid

Watches the context budget of a DeepSeek Harness session: a colour dot in every turn footer (green <50%, yellow 50-65%, orange 65-80%, red >=80%) read from the official contextPressure projection, a r

UI (client)hasBundlePatch

dsh-context-keeper

Two things for a DeepSeek Harness agent:

  • A host plugin that teaches it how to reason well — one persistent system-prompt section, visible on every request.
  • An offline analyzer that reads what it actually thought, from the session files on disk.

It does not cut reasoning short. That was the original goal; measurement killed it. See Why this does not reduce thinking.


Compatibility

  • DeepSeek Harness >= 0.2.0-rc.1 — declared in package.json under dsh.engines.dsh.
  • Node.js >= 22 — the plugin uses the built-in zlib.zstdDecompressSync.
  • Verified on: DSH Desktop 44.7.0 (Windows) — the context badge mounts and renders in the turn footer, and /context-watch / /handoff run against local session files.

The plugin relies on public DSH APIs: systemPrompt.section, commands.register, the conversation.chat.turnTail / conversation.composer.dock seats, and the contextPressure projection. If a future build changes those, the host half warns once and registers nothing instead of taking the host down; the client half simply renders nothing when its projection is unavailable.


What v0.4 adds: a context badge & reminder

A colour dot in every turn's footer (the conversation.chat.turnTail seat — the same place and shape as dsh-cost-meter's usage chip). It reads the official contextPressure projection and paints the band — green (<50%) / yellow (50–65%) / orange (65–80%) / red (≥80%) — with the occupancy percent; the action hint ("建议交接" / "该交接了") only appears from orange up. Hover shows the full sentence.

A reminder panel under the input (conversation.composer.dock) that appears at orange/red only. It states the band and offers an 开新会话 button: it calls the client Remote session.create + session.prompt to make a fresh session in the same workspace and seed it with "read the latest handoff package under .context-keeper/handoff and continue". The new session is a full agent, so it reads the package itself — the button does not inline the package (that would spend tokens again).

Both are pure presentation plus one explicit user click. They never enter the model input on their own and cost zero tokens until you press the button.

Honest limits (verified against this build's source):

  • DSH's ReasoningRow header (above the thinking block) is hard-wired with no extension seat, so the footer is the nearest always-visible open spot.
  • After creating the new session the button cannot switch you to it — the slot API has no navigation; open it from the sidebar. The panel says so.
  • Command names must match ^[a-z][a-z0-9_-]*$ and third-party commands render their name (no separate display label), so /handoff and /context-watch cannot be shown as Handoff/Context-Watch in the menu. Readability goes into the Chinese one-line description shown next to each name instead.

The client half is plugin/client.js (declared under dsh.client in package.json); the host half is unchanged. No config path needed.


What v0.3 adds: context budget & handoff

v0.2 taught the agent how to think. v0.3 handles whether the window can hold it. Two human commands, both reading the session file DSH already writes and calling a model zero times:

  • /context-watch — occupancy, band (green/yellow/orange/red), headroom, growth per turn, and the last compaction's reclaim.
  • /handoff — write a portable handoff package plus a full faithful archive to <workspace>/.context-keeper/handoff/, so a fresh session can continue without re-deriving anything. It reuses DSH's own compaction/summary checkpoint as the "early context" (free multi-level distillation) and quotes the recent tail verbatim.

A short, static context-budget line is added to the system prompt. It holds no numbers on purpose: a changing number in the system prompt would invalidate the provider's prefix cache on every request, which costs more than it saves.

The design and the two references it distils are in docs/distill-design-v3.md.


Install

As a DSH plugin

dsh plugin --profile <your-profile> add dsh-context-keeper

Then restart the profile. The plugin registers one prompt section named context-keeper:how-to-reason at order 650, which places it with the other policy sections — after the deployment persona, before the tool catalog.

To turn it off without uninstalling, either set enabled: false in the config block, or add a patch row:

- id: context-keeper
  disabled: true

Config options:

OptionDefaultMeaning
enabledtruefalse registers nothing
textbuilt-in ruleReplace the rule text entirely
order650Section position in the assembled prompt
maxChars2000Truncate at a paragraph boundary

As a CLI

git clone https://github.com/Orliba/dsh-context-keeper
cd dsh-context-keeper
node bin/cli.mjs --help

No build step, no dependencies, Node >= 22 (uses built-in zlib.zstdDecompressSync).


The plugin: what it puts in the prompt

The rule is five lines, each naming an observable behaviour rather than a virtue:

Decide before acting. Before the first tool call, settle what you are doing, why, and how you will know it worked. Once you state a plan, execute it; do not reopen the plan mid-execution.

Change a conclusion only with a reason. …

When reasoning stalls, gather evidence instead of thinking harder. …

Match depth to risk. Read-only exploration may be quick. Irreversible actions deserve a second look. …

Say what you do not know. …

Full text and the reasoning behind each line: plugin/rule.mjs and docs/rule-text.md.

Why a prompt section and not a stream interceptor

The first design watched the reasoning stream and reacted — lower the effort tier when a trace looked wasteful, stop a turn that ran away. Three measurements, on real sessions, removed the target:

HypothesisMeasuredResult
Looping traces repeat sentences0.1% sentence repetitiondead
Nearby steps re-derive earlier steps0.3% of step pairs above Jaccard 0.35dead
Early commitment + long tail = wastetop candidates read by hand: both productivedead

It also depended on two fragile places: llm/stream (no in-tree consumer) and agent/turn-stopping (fires only after the turn already ended).

A prompt section is the opposite kind of intervention. It is declared once, it is visible on every request, and it needs no detection — the model does not have to be caught in a bad pattern in order to learn from it. Numbers and raw data: docs/calibration.md.

Failure behaviour

systemPrompt.section() is a public registry method, but this plugin still refuses to take a host down if a future build changes shape. If the method is missing, it warns once and registers nothing — the entry stays loaded so the rest of the profile is unaffected.

Two failure modes were found the hard way during development, both now covered by tests:

  • an undeclared service throws at activation (cannot get property X without inject)
  • a declared but never provided service leaves the entry pending forever (waiting for service: X) — this is what happens if you declare console, which is a Node global, not a harness service

The CLI: reading what it thought

# every session under a DSH home, sorted by thinking volume
node bin/cli.mjs scan "$DSH_HOME/sessions"

# one session, aggregate
node bin/cli.mjs report path/to/session.v4.jsonl.zstd

# longest traces first
node bin/cli.mjs traces path/to/session.v4.jsonl.zstd --limit 20

# export candidates for human review, with a verdict checkbox per sample
node bin/cli.mjs samples path/to/session.v4.jsonl.zstd --n 5 --out ./review

# context budget: occupancy, band, headroom, last compaction
node bin/cli.mjs context path/to/session.v4.jsonl.zstd

# write a portable handoff package + full archive for a session
node bin/cli.mjs handoff path/to/session.v4.jsonl.zstd --out ./handoff

--json works on report, traces, and scan.

MetricMeaning
tokensEstimated thinking tokens
parasParagraphs in the trace
commit@Where the first commitment to a plan lands, as a share of the trace
recommitCommitments appearing after that first one
retractStrong retractions ("scratch that", "I was wrong")
tail-effShare of post-commitment paragraphs naming a new artifact or number
churn0..1 composite of the three above

Verdicts: lean, normal, churn-risk, unclear (no commitment found).

Reading the numbers honestly

  • tokens is an estimate (CJK ≈ 1 char/token, Latin ≈ 4 chars/token). Fine for ratios inside one trace, not billing-grade.
  • commit@ matches English and Chinese commitment patterns. Traces in other languages land in unclear rather than being mis-scored.
  • churn is a heuristic never validated against a corpus where waste is known to exist. Treat churn-risk as "worth a look", not a diagnosis.

Session storage facts

Two things that silently corrupt any independent analysis:

  1. Multi-frame zstd. Session files are a sequence of independently framed zstd blocks, not one stream. Node's zstdDecompressSync reads only the first frame. src/zstd.mjs splits on the magic number and decodes each frame.
  2. Reasoning is stored four times per attempt — content[], replayState.blocks[], chunk.block, and chunk.replayState.blocks[]. Walking the event tree counts every trace 4x, with no error and no symptom. Read data.message.content[] only; src/session.mjs explains why.

Layout

bin/cli.mjs         command wiring
src/session.mjs     session file -> reasoning records + full detail (users/tools/compactions)
src/metrics.mjs     pure metric functions
src/budget.mjs      pure context-budget math (occupancy, bands, ETA)
src/handoff.mjs     pure handoff packaging + archive rendering
src/zstd.mjs        multi-frame decoder
src/render.mjs      table/report formatting
plugin/index.mjs    the host plugin (rule sections + /context-watch + /handoff)
plugin/client.js    the client half (turnTail context badge, colour dot)
plugin/rule.mjs     the rule text
test/               plugin, budget, handoff, client-badge, activation and e2e prompt tests
docs/               calibration data and design notes

Run the tests:

npm test                         # everything below, in order
node test/plugin.test.mjs        # unit: what gets registered
node test/activation.test.mjs    # cordis injection rules
node test/client-badge.test.mjs  # badge math + parity with the host + reminder helpers
node test/client-boot.test.mjs   # mounts the client bundle under the real loader shape

License

MIT

Comments

Loading…

Similar plugins

dsh-context-guard

A DeepSeek Harness plugin that tells you to wrap up and start a new session before the session gets too long: badge + one-shot banner from the official contextPressure projection, and from 45% occupancy it auto-drafts a machine-facts handoff block into your working directory. Zero context tax, bilingual zh/en.

Terminal & ClientsSessions & MessagesManifest valid

★ 1

MIT

JavaScript

dsh plugin --profile web add @2jumpsina/dsh-context-guard

Colors each session title in the DSH sidebar by state: unread (a blue gradient while the model is running, green once it has finished), pinned (yellow), and sessions holding live background shell jobs

UI & ExperienceManifest valid

★ 0

dsh plugin --profile web add dsh-session-colorful-unread-pin-jobs

by ZiOstudio

Session budget brake for DeepSeek Harness — meters every call against the official price table, halts the run when the budget runs out, and leaves a resumable handoff snapshot. · DSH 会话预算刹车

Tools & CapabilitiesDevelopment & InfrastructureManifest valid

★ 1

MIT

TypeScript

Oct 22, 2026

dsh plugin --profile web add dsh-budget-handoff

DSH workspace hub: organize workspaces into color-coded folders in the sidebar (three-level drag reorder for folders/workspaces/sessions, inline edit, one-click expand/collapse, dual-channel search) w

Tools & CapabilitiesModels & ProvidersManifest valid

★ 0

dsh plugin --profile web add dsh-workspace-hub

by baifagg

DeepSeek Harness (dsh) Web GUI plugin: highlight running sessions and pin busy workspaces to the top of the sidebar. Theme-adaptive, zero-config.

UI & ExperienceDevelopment & InfrastructureTerminal & ClientsManifest valid

★ 1

MIT

JavaScript

Oct 14, 2026

dsh plugin --profile web add dsh-plugin-busy-workspace

Context fullness bands, the per-session compaction threshold derived from the model window, per-step cost computed from cache read and cache write rates, cache-hit, DeepSeek balance with the peak/off-

Tools & CapabilitiesManifest valid

★ 0

dsh plugin --profile web add dsh-context-governor