Introduction

When working with DSH (DeepSeek Harness) in its web interface, there is an operation that looks simple but is actually prone to failure: restarting the service. After installing plugins or changing configurations, you want to restart the process, but the result is often “port closed, service didn’t start,” forcing you to go back to the terminal and pull it up manually.

This is not an occasional issue on Windows; it stems from a specific set of process mechanisms. dsh-restart-tool addresses these pitfalls one by one, providing entry points for both agent model tools and GUI buttons. Below is an introduction to what it does, how to install it, and how to use it.

What is this

dsh-restart-tool is a DSH plugin maintained by julensun-ir, under the MIT license. Current version 0.3.0, requires Node >= 20. One-sentence positioning: It provides reliable restart and shutdown for DSH web, covering entry points for agent (model tools restart_dsh / shutdown_dsh) and GUI (sidebar power control).

The core failure mode it targets is the “normal restart resulting in closed port and service not starting” scenario on Windows. The README lists four pitfalls encountered (even if you don’t install this plugin, they are worth referencing):

  1. Async spawn race condition. Node’s child_process.spawn is asynchronous on Windows. If the event loop empties immediately after spawn(...), the helper will exit before the process is created—a new process is never created, leaving only empty logs. The fix is to wait for the 'spawn' event (with retry), or keep the event loop referenced.
  2. Agent sandbox kill-on-close job. DSH wraps the agent’s shell with a JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE job (no breakaway): when the host dies, the agent’s shell and everything it spawns die with it. Therefore, the agent cannot reliably “kill the host and pull it up”; the reliable path is to let the host spawn the helper itself—the host’s child process is not in this job.
  3. SIGTERM is an uncatchable hard kill on Windows. process.kill(pid, 'SIGTERM') maps to TerminateProcess, graceful shutdown handlers won’t execute; only Ctrl+C (SIGINT) is catchable.
  4. taskkill /T /F kills the helper too. If the helper is a child of the host, tree killing takes out the process responsible for pulling up the new instance. You need to kill a single process precisely, or exclude the self chain during tree traversal.

Core Features

Listed by verification status in the README feature table:

Capability Entry Point Verification Status
Restart DSH Model tool restart_dsh, GUI icon button, POST /dsh-restart/restart Tested on Windows
Shutdown Model tool shutdown_dsh, GUI icon button, POST /dsh-restart/shutdown Mechanism tested (fence + route), actual action to be experienced by user
Restart Confirmation GET /dsh-restart/status returns {"restarted":true,"fromInstanceId":…} Tested
Session Auto-Continue Record running sessions before restart, inject continue nudge into new instance Tested (nudge delivered when agent triggers restart)
Health Dot Sidebar status dot, 3-second polling, Green/Red/Gray Rendering tested
Restart Mask + Auto Refresh Full-screen mask, auto location.reload() after new instance ID changes Rendering tested
Watchdog (optional) Config switch control Code ready, not battle-tested

How the Restart Flow Works

Taking restart_dsh as an example, the flow is as follows:

  1. Record running sessions (including the current session when triggered by an agent), write intent markers and continue markers.
  2. Host spawns a detached helper—it is a child process of the host, not in the agent sandbox’s job, so it survives even if the host dies.
  3. Host exits gracefully after 2 seconds (ctx.appExit), with a 12-second hard kill fallback.
  4. Helper waits for the port to be released (up to 90 seconds), then uses the same command line to restart the host (wrapped in a hidden console PowerShell on Windows), waits for the 'spawn' event (retry ×3) to confirm process existence.
  5. Helper updates marker.newPid; the new instance proves restart success based on this; helper then exits after verifying HTTP 200.
  6. New instance reads markers (matched by time window), /dsh-restart/status starts reporting restarted:true; subsequently, tryAutoContinue polls the session recovery status and injects a continue nudge after recovery.

Installation & Enabling

dsh plugin --profile web add github:julensun-ir/DSH-RESTART-TOOL

You can also install locally:

dsh plugin --profile web add file:./dsh-restart-tool

Restart dsh to take effect. Regarding dependencies, three peerDependencies are declared: @deepseek-ai/cordis ^4.0.1, @deepseek-ai/dsh-tools ^0.1.0-rc.6, @deepseek-ai/dsh-llm ^0.1.0-rc.6.

Optional configuration is written in the profile’s cordis.patch.yml:

- id: dsh-restart-tool
  config:
    watchdogEnabled: true      # Watchdog, disabled by default
    watchdogCooldownMs: 60000
    watchdogPollMs: 2000
    autoContinueEnabled: true
    continuePrompt: "The system has restarted. Please continue the work that was in progress."

watchdogEnabled controls the optional watchdog, disabled by default; the rest are cooldown and polling intervals, auto-continue switch, and continue prompt text.

Typical Usage

GUI: Two icon-only buttons appear at the bottom of the sidebar to avoid crowding adjacent items (e.g., the usage statistics row).

  • Refresh icon = Restart: Clicking shows a full-screen “Restarting DeepSeek Harness…” mask; page auto-refreshes when the new instance is up, with a tooltip on hover.
  • Power icon = Shutdown: Graceful shutdown, no auto-restart, requires manual startup of dsh afterwards.
  • Status dot: Green = Online, Red = Offline/Restarting, Gray = Unknown, 3-second polling.

HTTP Routes: POST /dsh-restart/restart and POST /dsh-restart/shutdown trigger actions; GET /dsh-restart/status confirms if restart is complete; routes include request origin verification (the isTrustedRequest fence).

Agent: Agent can directly call restart_dsh; the plugin records running sessions (including the current session triggering the restart) before restart; after the new instance restores, it injects a continue prompt.

Testing: The repository includes a zero-dependency test suite based on Node’s built-in node:test:

npm test

The suite runs in a single process—node --test CLI spawns subprocesses via pipes, which is blocked by the DSH agent sandbox with EPERM. Coverage includes plugin exports, config shape, request fence, marker read/write, tool and route registration, health/status routes, auto-continue nudge, watchdog spawn, and a full restart loop (markers -> helper subprocess -> restart -> newPid -> http200=true).

Use Cases & Notes

Suitable for: Users running dsh web on Windows who don’t want to return to the terminal for restart/shutdown; scenarios where agents need to autonomously complete the “change config -> restart -> continue” loop.

Points to know before use:

  1. Permissions: The plugin runs with the current dsh process’s permissions, capable of starting and terminating processes on your machine. It is recommended to read the source code and confirm the license (MIT) before installing.
  2. Platform: Restart is designed and tested for Windows scenarios; macOS/Linux paths are untested (POSIX branch exists but unverified).
  3. Shutdown: shutdown_dsh is only mechanism-verified (fence, route, flag writing are tested); actual shutdown actions need to be experienced by the user; no auto-restart after shutdown.
  4. Remaining Verification Checklist: The following live checks are unchecked—new/old PIDs are different and HTTP 200, nudge delivery when agent triggers restart, existence of dsh-stopped.flag after shutdown and port listening stops (where helper’s newPid + HTTP 200, nudge injection, and flag writing are covered by the test suite).
  5. Watchdog: Disabled by default, code ready but not battle-tested.

For production-grade guarantees across all platforms, the README also points to two similar projects for reference: dsh-power-button and anweat/dsh-restart.

Conclusion

The value of dsh-restart-tool is not just “being able to restart”—anyone can write a script to kill a process. Rather, it handles every failure point on Windows one by one and turns “whether the restart succeeded” into a verifiable closed loop: the helper confirms spawn, HTTP 200, marker self-proof, and session auto-continue. If your workflow frequently requires restarting DSH, it is worth a look.

Note: DSH’s philosophy is “everything is a plugin”; the directory page above is a community independent site with no official affiliation with DeepSeek or Fenxi.