dsh-xray
X-ray for your DeepSeek Harness: context-tax attribution, entry inspection, dependency cascades
- Stars
- 1
- Language
- JavaScript
- Created
- Aug 20, 2026
- Updated
- Sep 16, 2026
Introduction
The token-ledger panel is measured on the committed fixtures/runtime-basic snapshot; the disable-cascade panel is an illustrative capture from an author profile that no committed fixture reproduces.
X-ray for your DeepSeek Harness — see what's actually loaded, why, and what it costs you.
LLM context-cost observability: token attribution per plugin, prompt-section and tool-schema pricing, skill catalog tax, dependency cascades.
Every plugin you mount quietly bills every LLM request: prompt sections, tool schemas, tokens. dsh-xray sits inside your running harness as an X-Ray tab beside Chat and Trajectory and itemizes that bill — per plugin, per entry, down to the exact text:

Unfold a plugin to see what it registered; click any entry to read the exact text it puts into every request:
|
|
|
Three clicks: plugin rollup → entry list → the actual words. The number stops being an estimate you trust and becomes a fact you checked.
The Problem
dsh --dump-config shows you the composed tree. The plugin panel shows you a flat list. Neither tells you why a plugin is there, what breaks if you disable it, or what it silently costs you on every single request.
dsh-xray does. And when the answer is "this plugin taxes every request and nothing depends on it" — the deps view confirms the disable is safe, one patch line removes it, and attribute verifies it took.
The cost view answers the question no other tool asks: who put this in my context, and what does it cost?
- Attribution — every prompt section and tool schema is joined to the plugin that registered it, reconstructed live from the registries (ambiguous entries stay
unattributed, never guessed). - By-plugin rollup — each plugin's per-request context tax: sections + schemas + tokens + share, ranked.
- Entry inspection —
/xray/api/entryreturns any entry's live text with a chars/tokens ruler. Computed per request, never persisted. - Skill cost — a dedicated view prices every skill twice: its catalog line (resident on every request once any model-invocable skill exists) and its body (billed per load). Pricing only — toggling belongs to the ecosystem's skill managers.
- Per-request ledger — one classified bill per LLM call: system / tool schemas / history / tool results (aggregated per tool), a Δprev growth column, and prefix-stability markers (⚡ system+tools byte-identical to the previous request — KV-cache-friendly; ✂ prefix broken). Compaction and title calls are tagged apart from chat. Only counts, names, and hashes are kept — never message text.
- Explained UI — every view opens with a one-line "what am I looking at"; terms carry plain-language tooltips; the whole tab is localized (English / 中文) through the host locale service.
The same data flows through three surfaces: the X-Ray tab (native GUI), the standalone /xray page (works even when the client-module pipeline it diagnoses is broken), and the CLI.
npx dsh-xray attribute # which layer introduced each row, and who patched it since
npx dsh-xray conflicts # contested fields with per-writer evidence: file:line, value, winner
npx dsh-xray diff # declared (static layers) vs actual (dump-config) tree
npx dsh-xray snapshot # content-addressed lockfile; --against <lock> reports drift, exits 1
npx dsh-xray deps [svc] # service dependency graph: providers, consumers, transitive disable-cascade
npx dsh-xray health # plugin lifecycle health: failed fibers, pending injects, transitions
npx dsh-xray cost # context cost: prompt sections + tool schemas, estimated tokens
npx dsh-xray shadow # services provided by multiple plugins
npx dsh-xray verify # declared (static) rows ↔ runtime registry, exits 1 on mismatch
npx dsh-xray why <tool> # provenance chain for one tool: owner plugin, its injects, their providers
npx dsh-xray audit # static scan of out-of-tree plugins for sensitive touchpoints
The demo transcript is an illustrative capture from an author's web profile (revision unrecorded) — its figures are not reproducible from this repo and drift as the profile gains plugins; the committed fixtures and their pinned outputs live in fixtures/ and tests/golden.spec.js.
attribute, conflicts, and snapshot are static — they replay the on-disk layer stack and work even when dsh cannot boot (snapshot additionally samples dsh --dump-config for the composed hash, and folds in the runtime services/tools when a snapshot exists, degrading honestly to null when it doesn't). All commands take --profile <name> (default web) and --json; every JSON payload carries a versioned schema field (dsh-xray/<view>@N) so machine consumers detect shape changes instead of guessing. snapshot, its --against diff, verify and audit are at @2 (see the changelog for what moved); every other view is still @1. Exit codes slot into CI: diff (trees disagree), health (unhealthy plugin), snapshot --against <lock> (composition drifted), shadow (multi-provider service), verify (declared ↔ runtime mismatch) and why (no tool by that name is attributed) all exit 1.
🔍 Layer AttributionWhich layer introduced each active plugin: kernel bundle, profile dependency, 📊 Declared vs. Actual DiffInstalled-but-inactive, uninstalled-but-lingering patch rows — including patch rows targeting ids that don't exist (dsh warns on stderr and skips them). ⚡ Conflict DetectionPlugins patching the same config row, and which one silently wins. 📸 Composition SnapshotExport the effective composition as a lockfile — bundles, patches, and every installed plugin with its provenance ( |
🌐 Service Dependency GraphWho provides and consumes each service — and the full transitive disable-cascade: not just direct consumers, but everything downstream of the services they re-provide.
Illustrative capture from the author's 💊 Runtime HealthPer-plugin fiber lifecycle state, startup failures, pending injects, transition history. 👥 Service ShadowingSame-name registrations where a later writer silently wins — usually an intended override, occasionally a conflict. 🛡️ Capability AuditHeuristic static scan of out-of-tree plugins: subprocess / shell, network egress, filesystem read and write, environment variables, dynamic code evaluation. Every hit carries 🔗 Tool Provenance
|
Mounted in the tree, dsh-xray registers an xray_composition tool (view: summary | deps | health | cost | shadow | skills | requests), so an agent can answer:
"What capabilities do I have?" / "What plugin provides X?" / "Why is Y unavailable?"
— about itself.
dsh-xray reads; it never runs.
- Loader
!!jsexpressions in patch files are parsed as opaque markers and never evaluated - The CLI never executes plugin code (
auditis a pattern scan over source text) - The mounted plugin writes only under
$DSH_HOME/xray/— entry text is served live, never persisted - The entry endpoint returns composition-layer text only, never session messages
- See SECURITY.md
Analysis modes
Every result names its trust boundary:
| Mode | Commands | Boundary |
|---|---|---|
| Static | attribute, conflicts, snapshot | Exact replay of the on-disk layer stack; works even when dsh cannot boot. snapshot also samples dsh --dump-config for the composed hash when dsh is available. Cannot observe runtime behavior. |
| Static + spawn | diff | Replays the layers, then spawns dsh --dump-config to compare declared vs. actual. |
| Static + runtime | verify | Joins both sides: declared rows that never mounted, disabled rows still running, runtime-only plugins, snapshot staleness — and, per service and per tool, whether its runtime provider/owner is a declared row. |
| Runtime | deps, health, cost, shadow, verify's runtime half, why, tab, /xray panel, agent tool | Observed from the running composition ($DSH_HOME/xray/runtime.json); valid for the current session only. Token counts are estimates (~4 chars/token) unless you open the entry text and count. |
| Heuristic | audit | Pattern scan over source text; false positives and negatives are expected. A flag means "this pattern appears", never "this plugin is malicious". Confidence grades how well the pattern is corroborated, not how dangerous it is. |
Two ways to use it — they're independent:
1. Static CLI only (no install into dsh; works even when dsh cannot boot):
npx dsh-xray attribute # requires Node >= 22
2. Mount the plugin (adds the runtime commands, the X-Ray tab, the /xray panel, and the agent tool):
dsh plugin --profile web add dsh-xray
# bundle plugins take effect on the next start — restart dsh web
Verify it took:
dsh --profile web --dump-config | grep dsh-xray # row present in the composed tree
npx dsh-xray health # reads the runtime snapshot
# then open any session and click the X-Ray tab,
# or http://127.0.0.1:3080/xray (the web app's default bind) for the standalone panel
Uninstall: dsh plugin --profile web remove dsh-xray.
| Command | Exit code |
|---|---|
diff | 1 when the trees disagree |
health | 1 when any plugin is unhealthy |
snapshot --against <lock> | 1 when the composition drifted |
shadow | 1 when any service has multiple providers |
verify | 1 when a declared plugin is not running, or a disabled one is (runtime-only subplugins and per-service/tool provenance are reported, not failures) |
why | 1 when no tool by that name is attributed in the runtime snapshot |
Diagnostic imaging for a running composition — complementary to dsh-doctor (rescue & recovery).
| Feature | Category |
|---|---|
| Context-tax attribution & entry inspection | 💰 Optimization |
| Skill cost (catalog line + body pricing) | 💰 Optimization |
| Per-request ledger (Δprev, prefix stability) | 💰 Optimization |
| Layer attribution | 🔍 Inspection |
| Declared vs. actual diff | 🔍 Inspection |
| Conflict detection | 🔍 Inspection |
| Composition snapshot | 📦 Export |
| Static ↔ runtime verification | 🔍 Inspection |
| Tool provenance chain | 🔍 Inspection |
| Service dependency graph | 🌐 Runtime |
| Runtime health | 🌐 Runtime |
| Service shadowing | 🌐 Runtime |
| Agent self-introspection | 🤖 AI |
| Capability audit | 🛡️ Security |

