Carrick-K7/dsh-keep-going0

dsh-keep-going

Restart DSH without losing the task in flight: the current turn finishes, the process exits cleanly for the supervisor to replace, and the next boot wakes the same session to keep going.

包名
dsh-keep-going
版本
0.1.1
许可证
MIT
最近更新
2026年9月12日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:Carrick-K7/dsh-keep-going

dsh-keep-going

English | 中文

Restart DSH without interrupting the work that is running.

Normally a restart costs you the answer being written: DSH stops in the middle of it, and afterwards nothing tells the assistant to continue. This plugin removes both problems.

  1. It waits. When a restart or a shutdown is requested, DSH does not stop immediately. The plugin waits until the running turns have finished, then asks DSH to close itself in an orderly way.
  2. It continues. Before closing, it writes down which conversation asked for the restart. When DSH starts again, the plugin waits for that conversation to come back and sends it a message to carry on — you do not have to say anything.
you or the assistant ask for a restart
        │
        ▼
wait until the running turns have finished
        │
        ▼
write down the conversation to wake, then close DSH in an orderly way
        │
        ▼
the service manager (systemd, a Windows service, …) starts DSH again
        │
        ▼
DSH starts → the conversation is woken → the work continues

What it does not do

Not handled hereHandled by
Starting DSH again after it closesyour service manager — for example systemd with Restart=always
Undoing a plugin installation that stops DSH from startingyou; DSH reports the error and exits, it does not repair itself
A settings page, a browser button, a process dashboardnothing — this plugin has no part in the browser interface
Waking conversations that were already idle when the restart was asked foron purpose: they had nothing to continue

Keeping the scope this small is the point. The name says one thing: after the restart, keep going.

Install

# from npm (once published)
dsh plugin --profile web add dsh-keep-going

# from a local copy
dsh plugin --profile web add /path/to/dsh-keep-going

Then restart DSH once so the plugin is loaded.

One requirement: something must start DSH again after it closes. If nothing does, a restart leaves DSH stopped. See Deployment.

Tools and commands

What you useWhat it doesDoes the conversation continue by itself?
restart_harness (used by the assistant)restarts after the current answer is finishedyes
shutdown_harness (used by the assistant)closes DSH without restartingnot applicable
cancel_harness_action (used by the assistant)cancels a restart or shutdown that has not happened yetnot applicable
/restart (typed by you)restarts after the current answer is finishedno, it waits for you
/shutdown (typed by you)closes DSH without restartingnot applicable

Arguments of restart_harness:

ArgumentMeaning
continuePromptWhat the conversation is told when it wakes up. Replaces the default text from the settings.
waitMsHow long this particular restart waits for running turns, in milliseconds. Replaces drainTimeoutMs.
forceRestart even while other conversations are in the middle of an answer (default: no). Without it, the request is refused and the answer lists the conversations that are busy, so one conversation can never silently cut off another one's work.

Which conversations are woken, and with what

Every conversation whose answer the restart cut off is woken, so nothing is left hanging:

  • the conversation that asked receives its own instruction (its continuePrompt, or the default from the settings);
  • every other interrupted conversation receives a neutral "carry on" notice that names no task, so it decides for itself what it was doing;
  • conversations that were already idle are not woken — they had nothing to continue.

The distinction matters: handing the caller's instruction to another conversation is what once made one conversation start working on someone else's problem.

Settings

These live in the dsh-keep-going section of settings.yaml and can also be edited in the settings page:

dsh-keep-going:
  continuePrompt: DSH 已重启完成,请继续未完成的工作。
  drainTimeoutMs: 600000   # 10 minutes: stop waiting and close anyway
  stuckAgentMs: 60000      # 60 seconds without activity: stop counting a turn as running
  stormLimit: 5            # more than 5 restarts inside the window below: restart, but do not wake
  stormWindowMs: 300000

Two behaviours that matter:

  • A turn that has gone quiet stops blocking; a turn we know nothing about does not. A conversation that is marked as running but has shown no activity for stuckAgentMs no longer holds up the restart. A conversation with no activity recorded at all still counts as running — so a restart can never throw away an answer just because the plugin had not seen that conversation yet.
  • The waiting limit forces the restart, it does not cancel it. When drainTimeoutMs passes, DSH closes anyway, and the note telling the conversation to continue has already been written. A restart you asked for is never quietly dropped.

Files it writes

Everything is inside $DSH_HOME/dsh-keep-going/:

  • restart.json — written just before DSH closes, read and deleted at the next start.
  • state.json — the times of recent restarts, used to stop a restart loop.

Delete that folder if you want to cancel a pending wake-up.

Deployment

Linux with systemd. A service that restarts DSH on exit is enough:

[Service]
ExecStart=/path/to/dsh web --host 127.0.0.1 --port 3080
Restart=always
RestartSec=3

Because the plugin asks DSH to close itself rather than killing it, saved data is written out and the port is released before the process ends. The service manager then starts a fresh DSH, which finds the note and wakes the conversation.

Windows, or no service manager. Use something that starts DSH again when it exits — a Windows service, a scheduled task, or a small launcher in the notification area. The plugin itself never starts a process.

Compatibility

Written and tested against DSH 0.1.5-rc.2. The plugin declares which parts of DSH it uses, so installing it on a very different DSH version reports a mismatch instead of failing silently while starting.

For developers

node --test "test/*.test.js"   # 22 tests
  • lib/policy.js — every decision (when to stop waiting, which turns count as stuck, when to stop waking) as small functions with no side effects.
  • lib/state.js — reading and writing the two files above.
  • lib/index.js — connects the two to DSH.
  • test/smoke.test.js — starts the plugin against a stand-in for DSH, including one test that runs a full restart and wake-up cycle.

License

MIT