dsh-plugin-restart-desktop: One-click restart for DSH Desktop keeping windows

Foreword

The DSH Desktop version (the Electron shell of DeepSeek Harness) lacks a “Restart” action: the bundled version’s menu does not contain a restart item, the tray menu on Windows only has “Open App” and “Exit,” and there is no restart method in the rendering process’s dshDesktop API. To make matters worse, window geometry is never persisted to disk—the main process’s createWindow() hardcodes the size to 1280×820, so restarting after a normal exit always returns the window to the default size. There is also a common pitfall: clicking the window’s close button does not exit the app; the main process simply calls preventDefault followed by hide, tucking the window into the tray.

The dsh-plugin-restart-desktop introduced below is designed to address this gap: maintained by railgun20001, MIT licensed, current version 1.0.0, and published on npm. It provides a sidebar entry; a single click triggers a restart. After restarting, it preserves the window’s position, size, maximized state, and the monitor it is on. Optionally, it can automatically reconnect sessions that were truly interrupted at that moment. The plugin has no settings page; all behavior is controlled by switches on the host side and only supports the Windows Desktop version.

What is This

One-sentence positioning: A one-click restart plugin for DSH Desktop that solves “window position loss after restart” and “manually recovering interrupted sessions after restart.”

It is worth noting that this is not digging up a hidden official feature, but rather acknowledging that the official channel indeed does not provide one. The basis given in the README is the conclusion from unpacking app.asar and reading the main process source code: the complete IPC list consists of only a few limited items like shutdown / quit-inspection / update-tasks, with no interfaces related to restart. Therefore, the plugin’s approach is to spawn a separate helper process, have it terminate the Electron main process, wait for the port to be released, launch a new instance, and then restore the window pixel-by-pixel.

Core Features

The following are verified capabilities, all taken from the plugin README.

  1. Preserve Window Geometry. When restarting, capture the window’s normal rectangle (rcNormalPosition), showCmd (normal/minimized/maximized), and the monitor. After restarting, use SetWindowPos and ShowWindow to put them back, and read back the actual values (including monitor, wanted / actual / onTarget fields) to write into logs and result files. The maximized window is handled by the sequence of “restore to normal rectangle first, then maximize” to avoid being pulled back to the main screen; the minimized window is handled similarly.
  2. One-click Restart. The only entry point is the refresh icon button to the right of the account row at the bottom of the sidebar. A single click directly schedules a restart without secondary confirmation. Host guards (tasks running, plugin installing) do not require an additional click, though they are explained in the button’s hover tooltip as interrupting them.
  3. Auto-resume Interrupted Sessions. The host captures the state at the moment of scheduling, restores active agents that were generating or running tools at that time into live Agents one by one, and injects a factual recovery message for each. It actively excludes idle sessions, history sessions, and sessions with background tasks.
  4. Provides a Slash Command Fallback. /restart-desktop also triggers a restart on a single click; the host-side warning on this path still requires --force to bypass.
  5. No DOM Guessing. The button in the account row is identified by observing the official hardcoded data-signed-out and aria-haspopup="menu" attributes; the criteria do not contain hash-based class names. If unrecognized, it falls back to the official action slot for third-party plugins, sidebar.footer.action, so functionality will not disappear out of thin air.

Installation and Enablement

Install from npm. The official command is as follows. Note that this is a call to DSH’s plugin_manager, not a regular package manager command.

plugin_manager(action: "install_bundle", target: "dsh-plugin-restart-desktop")

You can also write the plugin directly into the profile; it must appear in both bundles and dependencies:

// ~/.dsh/profiles/desktop/package.json
"dsh": { "profile": { "bundles": [ /* … */ "dsh-plugin-restart-desktop" ] } },
"dependencies": { "dsh-plugin-restart-desktop": "^1.0.0" }

When developing this repository, use link: to point to a local directory for immediate effect after code changes:

plugin_manager(action: "install_bundle", target: "link:C:\work\my\dsh\plugins\dsh-plugin-restart-desktop")

After installation, DSH’s HMR will immediately mount the host side and the client side; a restart is generally not needed; if the entry does not appear, refresh the page once. The package.json’s engines.dsh requires >=0.2.0-rc.1, and the author has tested it locally on 0.2.1-rc.5.

Typical Usage

Once installed, there are no extra onboarding steps; just click the entry.

Click the refresh icon to the right of the account row at the bottom of the sidebar to schedule a restart with a single click. The window’s position, size, maximized state, and monitor are preserved, the sessions actually running at that time are resumed one by one, the page disconnects, the app restarts, and returns to its original state.

The plugin has no settings page and does not provide any interface switches. There are two host-side behavior switches with default values (both are on); if needed, modify the plugin config or the host settings file:

// ~/.dsh/profiles/desktop/package.json - config for this plugin
{ "geometry": true, "resume": true }   // Restore window geometry / Auto-resume interrupted sessions

The host settings file ~/.dsh/restart-desktop/settings.json has higher priority than the config; you can also modify the plugin route directly: POST /dsh-plugin-restart-desktop/api/settings?geometry=0&resume=0.

When troubleshooting, you can check these in the browser console:

__DSH_RESTART_DESKTOP__.status()      // Host state snapshot
__DSH_RESTART_DESKTOP__.button()      // Injection status of the account row button (found / injected / lastReason)
__DSH_RESTART_DESKTOP__.sweep()       // Immediately rescan the account row
__DSH_RESTART_DESKTOP__.action()      // Current action state of the button

The host-side handoff records are stored in ~/.dsh/restart-desktop/, keeping the last 20 groups of handoff-*.json, restart-*.log, restart-*.result.json, and restart-*.geometry.json. The geometry result files also show exactly which screen the window landed on.

Applicable Scenarios and Notes

Suitable for these two types of work scenarios:

  • Daily sessions on Windows using the Desktop version, where you want the window layout not to be interrupted during restarts (installing dependencies, upgrading versions, changing configuration).
  • Long tasks running in a session, where you don’t want the historical context interrupted after restart and need to automatically reconnect.

The boundaries that need to be clarified are mainly the behavioral boundaries of the plugin itself, not bugs:

  • The round currently running will definitely break; it will not automatically resume running; the auto-recovery injects a factual report, not a replay of that round.
  • Files being written by tools may stop midway; the plugin does not perform rollback.
  • Background tasks, child Agents, and teammates will all be killed; scheduled tasks will not trigger during the app closing period; killed background tasks will not result in a recovery message, so you need to restart and pull them up yourself if needed.
  • Only supports Windows Desktop version; if capability detection fails, it will explicitly reject.

Additionally, the plugin runs with the permissions of the current DSH process; it can terminate the main process, launch a new instance, and read/write session state. Before installing, it is recommended to read the README, the source code in lib/, and cordis.patch.yml, and confirm the license is MIT before enabling; cordis.patch.yml is a host-side patch, which is a type of installation that modifies host behavior and is worth evaluating separately.

Conclusion

The value of this plugin is concrete: it fills the gap left by the official lack of a restart action and solves the implicit loss of “window geometry not being persisted to disk.” It does not pursue a massive set of configuration items but completes the workflow using two switches on the host side and a separate helper. The boundaries are also written in the README, making it easy to judge whether to enable it based on your own workflow.

Directory: https://www.skillhub.cn/plugins/railgun20001/dsh-plugin-restart-desktop

Repository: https://github.com/railgun20001/dsh-plugin-restart-desktop

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye