The plugin system in DeepSeek Harness (DSH) tends to fail silently when faults occur: after an entry breaks, it quietly withdraws, leaving the panel empty, while errors remain only in the console and are difficult to troubleshoot. dsh-ballute is a crash-protection plugin intended to turn this kind of invisible failure into a visible, attributable, and recoverable state.

Installation and Enablement

Install the plugin using the official CLI:

dsh plugin add github:Zlyraz/dsh-ballute

After installation, Ballute automatically injects L1-L4 protection capabilities and provides crash observation and recovery interfaces at runtime.

Core Capabilities

The plugin builds a protection net through five levels (L1-L5), covering the full flow from pre-loading checks to runtime recovery.

L1 Preflight: Static Contract Check

Before the plugin is loaded, static checks are performed via the GET /api/ballute/v1/inspect endpoint. It can detect structural failures, such as a bundle registration ID that does not match the package name, missing required exports, or a missing name field.

L2 Isolation: Runtime Crash Card Display

It subscribes to the official ctx.slots.onEntryError hook and displays a crash card in the lower-right corner. The crash card includes the plugin name, slot key, and error message, surfacing crashes that would otherwise occur silently in the console to the UI layer.

L3 Observation: Black Box and History

Crash telemetry logs are recorded in JSONL format and stored at $DSH_HOME/ballute/crash-log.jsonl. The logs include timestamps, stacks, startup version hash (rev), and other information, supporting retrospective analysis after a restart. A history list endpoint is also provided for queries.

L4 Recovery: One-click Disable

The crash card UI provides a “Disable Plugin” action. It writes a patch layer (disabled: true) to trigger HMR unmounting, allowing the faulty plugin to be disabled without restarting the DSH instance.

L5 Fallback: Safe Mode

When the main profile is dead, it starts a safe profile containing minimal bundles and Ballute itself. It inspects and disables the faulty plugin through cross-profile APIs, providing external rescue.

Setting Up Safe Mode

The official CLI does not yet provide a --safe-boot flag, so a minimal profile must be built manually.

Place the following files in the $DSH_HOME/profiles/safe/ directory:

package.json

{
  "name": "dsh-profile-safe",
  "private": true,
  "dependencies": {
    "dsh-ballute": "github:Zlyraz/dsh-ballute"
  },
  "dsh": {
    "profile": {
      "bundles": [
        "@deepseek-ai/dsh-base",
        "@deepseek-ai/dsh-web-app",
        "dsh-ballute"
      ]
    }
  }
}

cordis.yml (an empty tree is sufficient)

[]

cordis.patch.yml (keep an empty array)

[]

pnpm-workspace.yaml

packages:
  - .
nodeLinker: hoisted
autoInstallPeers: false

Run pnpm install, then start safe mode with the following command:

dsh --profile safe

After startup, Ballute detects the safe profile and displays a recovery area at the top of the UI, allowing inspection or disable operations on the target profile.

Self-testing and Usage

Fixture Testing

Use the plugin’s built-in fixture to verify the inspection feature:

curl 'http://127.0.0.1:3080/api/ballute/v1/inspect?fixture=fault-mismatch'
curl 'http://127.0.0.1:3080/api/ballute/v1/inspect?fixture=fault-load'

Common fixtures include fault-load (missing file), fault-apply (apply throws an error), fault-mismatch (ID mismatch), and so on.

Development Mode Installation

It is recommended to verify first in an isolated dev profile, then install it into the daily profile.

dsh plugin --profile dev add /path/to/dsh-ballute
dsh web --profile dev --port 3081

During development, using a link-based setup is recommended so that code changes take effect immediately.

Notes

Honest Boundaries

The plugin mainly covers the L2 scope (runtime entry crashes).
* Loader-level failures: For example, if client apply throws an error and startup fails, or if a missing bundle file causes the host process to crash, the UI has not yet rendered, so Ballute cannot capture it. Recovery must rely on safe mode from the outside.
* SlotAssemblyError: This error can break through the error boundary and cause a full-page blank. At that time, the Ballute UI is not visible and cannot capture it; only console logs can be checked, and refreshing can recover.

Maintenance Status

This plugin is maintained as a side project, so responses may be slow. Issues and PRs are welcome.

License

MIT.

Plugin Catalog | GitHub Repository