dsh-restart
Self-waking host restart as a DeepSeek Harness bundle: a dsh_restart tool that restarts the DSH host, records the decision, and sends a continue message to every active session when the host is listening again.
What it provides
dsh_restart tool — restarts the running DSH host. It derives every path and URL at runtime (nothing device-hardcoded):
- harness dir defaults to the running host's working directory (
fs.resolve('.'))
- web base URL defaults to
DSH_WEB_URL, falling back to http://127.0.0.1:<webServer.port>
- logs dir defaults to
$DSH_HOME/tmp
- sessions = every live session discovered through the session-query corpus (
ctx.sessionQuery.listSessions()), plus optional explicit session_id + the calling agent's own session, deduplicated
reason (required) is recorded to the decision log and relayed to every woken session as a decision record
dry_run: true renders the wake script and returns the plan without touching the host.
- Wake script — a generated, self-contained PowerShell script (
dsh-restart-wake.generated.ps1 in the logs dir) that:
- records the decision (before the host dies),
- kills the current host tree,
- boots a fresh
pnpm dsh web,
- polls until the host answers,
- sends every captured session a continue message via
/api/session.prompt in queue mode (which maps to agent.followup — resuming each session's next turn), carrying the decision record.
Requirements
- A DeepSeek Harness profile that bundles the services this plugin reads:
tools, shell, shellEnv, fs (all present in @deepseek-ai/dsh-base). sessionQuery and sessions are optional (read via ctx.get): sessionQuery is the authoritative session lookup, and sessions is its fallback. webServer is optional.
- Windows host (the wake script is PowerShell;
dsh must be on PATH for pnpm dsh web).
- The
dsh_restart tool launches the wake script detached (cmd.exe /c powershell -File ...), so it survives the host process being killed.
Install
Add this package to the profile and its bundles list, e.g. in ~/.dsh/profiles/<name>/package.json:
{
"dependencies": {
"@try-works/dsh-restart": "^0.1.0"
},
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@try-works/dsh-restart"
]
}
}
}
Then pnpm install in the profile and restart the running DSH process. The bundle ships its src/*.ts sources directly (DSH loads them through tsx), mirroring dsh-paper-design and dsh-recursive-mode.
Restart is required for host/bundle changes: the web client-plugin HMR only rebuilds the web shell, not host plugins.
Usage
Ask the agent to restart the host, e.g.:
Restart the DSH host because we applied plugin changes.
The agent calls dsh_restart with a reason; the tool writes the decision record, launches the wake script, and returns the plan. When the host is back, every session active at trigger time receives a continue message (queued as its next turn):
RESTART-CONTINUE [boot=abc12345] host is UP. pid=12804 | count=3 hasRecursive=true | Please continue your work. DECISION RECORD: applying plugin changes
Development
pnpm install
pnpm run build # type-check (tsc -p tsconfig.build.json)
pnpm run test:unit # vitest unit tests (template substitution)
pnpm run verify # in-process boot + dry-run (needs a live shell/fs environment)
pnpm test # build + verify + unit
Layout
src/index.ts — bundle entry: registers the dsh_restart tool on ctx.tools, resolves runtime defaults, writes the script + decision log, launches the wake script detached.
src/wake-script.ts — template loader + placeholder substitution (pure, unit-tested).
assets/dsh-restart-wake.ps1.template — the wake-script template (placeholder contract in src/wake-script.ts).
tests/ — vitest unit tests.
scripts/verify-restart.mjs — in-process boot + dry-run verification.
cordis.patch.yml — loader patch inserting the plugin into a cordis:group realm.
Notes / gotchas
- PowerShell's
$pid is a read-only automatic variable — the template's kill loop uses $procId and must never assign $pid.
- The wake script redirects the host's stdout/stderr into their own log files (
dsh-restart-host.out.log, dsh-restart-err.log) so the wake log stays clean.
- The
recursive/* event types are unknown to a resumed harness; keep them registered in packages/core/session/src/known-event-types.ts (see the original README.md in the workspace) — don't run gen-persistence-catalog without re-adding them.
License
MIT