> [Česky](README.cs.md) · [English](README.md)

# dsh-watchdog

DeepSeek Harness plugin: freeze watchdog + self-recovery — a "pojistka"
(insurance) against the harness freezing and never coming back.

## What it does

- **Heartbeat**: every few seconds writes `~/.dsh/watchdog/heartbeat.json`
  with the current pid, boot time, and session count.
- **Boot-time recovery**: when a new session starts, it reads the previous
  heartbeat. If the previous instance is still alive but its heartbeat is
  stale (i.e. it froze), the watchdog kills it, cleans up orphaned worker
  processes (`image_worker.py`, `voice_worker.py`, `agent_voice_worker.py`)
  left behind by the frozen instance, and writes a recovery report to
  `~/.dsh/watchdog/recoveries/`.
- **Clean shutdown marker**: on a normal exit the heartbeat is marked
  `clean: true`, so the next boot knows it was not a freeze.
- **Model tool `dsh_watchdog`**: `status` (heartbeat, uptime, sessions, last
  recovery), `recover` (run the recovery routine now), `history` (list past
  recovery reports).
- **UI tab 🛡 Watchdog**: live status, last recovery, and a "recover now"
  button in the main interface.

## Why

If the harness freezes (e.g. a plugin fails at apply time, or a worker hangs),
starting a new session used to fail or leave stale processes behind. With this
plugin, the next session automatically detects the frozen instance, cleans up,
and can continue — the agent is told to check `dsh_watchdog status` after a
freeze and resume interrupted work.

## Install

```sh
dsh plugin --profile web add dsh-watchdog
```

Restart the web profile. The tab appears in the conversation view ring and the
`dsh_watchdog` tool is available to the agent.

## Settings

| Field | Default | Meaning |
|---|---|---|
| `enabled` | `true` | Write the heartbeat at all. |
| `heartbeatSeconds` | `5` | Heartbeat interval. |
| `staleAfterSeconds` | `30` | A heartbeat older than this (with a live pid) means "frozen". |
| `killStaleWorkers` | `true` | Kill orphaned image/voice/agent-voice workers during recovery. |

## Architecture

```
~/.dsh/watchdog/
  heartbeat.json        # current instance liveness
  recoveries/recovery-<ts>.json   # one report per detected freeze/crash
```

- Host: `lib/index.js` (heartbeat + recovery + tool).
- Client: `lib/client.js` (status tab).

## Development

```sh
npm install   # nothing required (peers provided by the harness)
npm publish   # publish a new version
```

## License

MIT
