Context-window attribution for DSH Web: a Mini Utility Dock panel that ranks the user messages, assistant turns, reasoning blocks and tool results of a session by the tokens each one occupies, so it is clear which entries hold the window. It also shows the share by entry type, the heaviest entries across the live sessions of the host, and, where the host provides them, provider usage and the estimated system/tools/messages composition. The panel is read-only: it does not estimate cost, modify a session, or trigger compaction.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-ballast
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:xswt442-cmd/dsh-ballast
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
A DSH Web context-window attribution plugin. It shows token occupancy and content previews for each entry on the current surface to identify what fills the window. DSH's built-in context display gives a whole-window share; per-entry attribution, the heaviest entries, and comparison across live sessions come from this plugin. It is read-only and does not estimate spend, modify sessions, or trigger compaction.
Features
- List user messages, assistant messages, and tool results by token occupancy. Text is whitespace-collapsed and truncated, tool results show their tool name, and reasoning blocks and images are counted but not inlined.
- Every row of the current session carries a locate button: clicking it scrolls the chat to that entry and highlights it. The button appears only while the chat is showing the session being measured.
- Locating works through internal DOM attributes of the chat, which are not a public interface. When the host drops those attributes the button is absent, or clicking it does nothing; the entries are still listed.
- Show the current route price and, when the host also supplies a heuristic shadow price, mark the difference. A difference indicates that an image may have been repriced as visual tokens; it is not an anomaly or an importance score.
- Show token share aggregated by message type and the heaviest entry in each live session on the current host.
- Show provider usage, next-request context pressure, and the estimated system/tools/messages mix. The mix and the provider-usage anchor use different accounting bases, and the panel does not add them together.
- List the sessions on the current host: those live in this process, plus those stored with no live agent. When a session title is missing, the row shows the workspace basename and session ID.
- Stored sessions can be measured on demand from their complete event log, by the same accounting as a live session, instead of showing only the possibly stale figures the projection cache holds.
- The panel header names the host process that answered, by PID and port, and the session count covers only that process's sessions.
- Every Sidebar Session row's hover card carries one ballast line; clicking it opens the panel on that session.
- That line shows the occupancy the plugin has already read for the session: its surface total and heaviest entry, or the log length when only the session list has been read.
- Hovering reads nothing from the host, and with nothing cached the line shows no number.
- The panel, the launcher icon, and accessible labels follow DSH's global language setting. Hosts without that setting use the browser language.
Install
# install from npm and register with the web profile (recommended)
dsh plugin --profile web add dsh-ballast
# download the npm package only
npm install dsh-ballast
# or install from GitHub
dsh plugin --profile web add github:xswt442-cmd/dsh-ballast
npm install downloads the package only; using the plugin in DSH still requires adding its bundle to a web profile. Restart DSH Web after installation and open ballast from the dsh-mini-utility-dock launcher at the bottom-left of the work area.
Usage
The panel has two views:
- Current session: inspect occupancy, type, time, and preview for each entry on the current surface. Entries folded away by a compaction
replaceare not shown. - Cross-session top: on demand, measure each live session on the current host once and sort sessions by their heaviest entry. Read cost grows with the number of live sessions. One failed session does not affect the other results. The same view lists stored sessions that no live agent owns, largest on disk first, with the context pressure the projection cache held for each. Event count, size, and revision come from the persistence snapshot and the token figures from the projection cache, so they can be as old as that session's last write; the titles come from one batched log read.
- Every stored row carries a measure action: clicking it reads that session's complete event log, measures it by the same accounting as a live session, and shows its surface total and entry count. Listing the sessions reads no log; only the click does, and that read costs an order of magnitude more than listing a row, so it is per-row and one session at a time. A corrupt log fails on its own row and leaves the others alone.
The panel reads from the same-origin, read-only /dsh-ballast/api route: sessions lists sessions, measure&sessionId= measures one session, top&limit= returns cross-session results, cold returns the stored sessions that no live agent owns, and cold-measure&sessionIds= measures those stored sessions on demand (at most 20 per request). The route accepts GET and HEAD; other methods return 405. Rows without a parseable token price are marked unpriced and excluded from occupancy bars and token shares.
Safety and limits
- Measures live sessions on the current host only; sessions on other hosts are not read, and ended sessions are read only through their persistence snapshot, the projection cache, and one batched title read.
- All operations are read-only: no state writes, no message deletion, and no compaction.
- There are no budgets, price tables, compaction forecasts, or content exports.
- On every supported DSH version (
>=0.2.0-rc.1), the API reuses Connection's Host/Origin checks and signed browser cookie. - Missing or invalid browser authentication returns
401/403. - A host that does not mount Connection falls back to the local guard, which decides by TCP peer, Fetch Metadata,
Origin, and loopbackHost. - Under the local guard, a process that can reach the DSH Web port is inside the trust boundary.
- A missing token meter, an ended session, and a failed per-session measurement each return an explicit error. An ended session is out of
measure's scope and is listed bycoldinstead. - Measuring a stored session needs
ctx.sessionQueryand an@deepseek-ai/dsh-sessionresolvable inside the host process. Without either one the row offers no measure action and nothing else changes. - Stored measurement runs one session at a time and releases that session's log as soon as it is measured. A single request measures at most 20 sessions.
- A host without heuristic shadow prices shows no price difference; basic measurement is still provided.
- The log length and the inherited prefix come from
Session.seqandSession.inheritedEventCount; reading event content by seq and reading titles in bulk go throughctx.sessionQuery(readSession/readTitleSnapshots). When both are absent, the older host's.eventsarray is the fallback. - The deprecated
Session.eventAt(),Session.snapshotEvents(), andSession.ownEvents()are not called.
Platform and compatibility
| Item | Requirement |
|---|---|
| DSH | >=0.2.0-rc.1 |
| Node.js | >=20 |
DSH Desktop is an Electron shell around the same web application; it shares the webServer, the client seats, and the launcher, and its data directory is the same DSH_HOME. This plugin behaves on Desktop as it does on dsh web. The compatibility matrix pins 0.2.0-rc.1 and 0.2.1-rc.2; each version boots a real host once on Windows and once on Linux.
The 0.1.x lines below 0.2.0-rc.1 are no longer tested and are no longer claimed as supported. Host behaviour older than that is still covered by the unit tests, but a real boot is only verified against the two declared lines.
RC1's seq, inheritedEventCount, and events are all supported: with ctx.sessionQuery present, event content is read by seq, and without it the older .events array is used. A missing projection hides the provider-usage and estimated-mix block; per-message token metering is still provided. A contextPressure without a contextWindow stays empty rather than being inferred from elsewhere.
Development
Verification commands are in AGENTS.md at the repository root; release steps are in docs/development/RELEASE.md.
License
Links
More in this category
yjh051108/dsh-routing-suite★ 6991
One repository, three parts: a runtime injector for DSH plugin packages (inject, hot-reload, unload, promote a dev staging tool to the front, route self-heal, plus a settings-page plugin manager that lists, unloads and drags folders in to internalize), a task-aware reasoning-mode router agent preset (router-standard / router-spec / router-react), and a graded two-level task protocol whose six tools (commit_star, lock_stage, revise_do, edit_plan, mark_task, redteam_verdict) pin task state to disk. The injector implementation ships in-tree, so the install carries its own behaviour rather than a dependency list.
strukto-ai/mirage#dsh★ 3715
Swaps the filesystem and bash providers for a mirage virtual workspace: file tools and shell commands run over mounted resources (RAM, S3, Redis, Slack, Gmail, Notion, Postgres) instead of the host disk, with per-mount read/write/exec modes, per-command sandbox routing (monty, pyodide, quickjs in process; docker, e2b, daytona remote), and installed CLIs (git, gh, slack, linear, ntn, gws, or one you register) as head words in the virtual terminal.
first-fluke/oh-my-agent#dsh★ 1352
Runs project OMA checks before and after tool execution and when a turn tries to finish. Installs its OMA CLI dependency and initializes unconfigured projects on first use. Requires Node.js 22+; initial setup needs network access and project write access.
hust-open-atom-club/oh-dsh★ 323
Community distribution: TUI, desktop, and Web UI as one bundle with layered installation.
MichengAI/dsh-skills-manager★ 294
Manages local DeepSeek Harness skills in Settings and shows shared Agent skills as read-only.
Fishquito7/dsh-skill-mcp-panel★ 223
Manages DSH skills and MCP servers from the web settings: skill cards with hot enable/disable, workspace scopes, groups, batch migration and drag-and-drop import, plus stdio/HTTP MCP CRUD with connection tests, secret redaction and the unified dsh-panel CLI.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.