## Feature: Docker Diagnostic Hints on Disconnection

**Problem:** When Docker is unreachable, the UI shows a generic "Docker disconnected" label with no actionable guidance. Users (especially on Windows/macOS where Docker Desktop must be running) have no idea what's wrong or how to fix it.

**Goal:** Enrich the health-check response with a structured diagnostic object so the frontend can display platform-aware, actionable hints.

---

### Backend Changes

**1. Enhance `GET /api/health` response** ([health.go](../internal/api/health.go))

Currently returns `{ "docker": true|false }`. Change to:

```json
{
  "docker": {
    "connected": false,
    "error": "dial unix /var/run/docker.sock: connect: no such file or directory",
    "category": "socket_not_found",
    "hints": [
      "Docker Desktop does not appear to be running.",
      "Start Docker Desktop and wait for it to finish initializing.",
      "If using a custom socket path, check DOCKER_HOST env variable."
    ],
    "platform": "windows",
    "checked_at": "2026-03-30T12:34:56Z"
  }
}
```

**2. Create a Docker diagnostics module** (new file, e.g. `internal/docker/diagnostics.go`)

Classify the Ping error into a diagnostic category and generate platform-specific hints. Follow the pattern already established in [hints.go](../internal/proxy/hints.go) for proxy validation.

Error categories to handle:

| Category | Error signature | Windows hints | Linux hints | macOS hints |
|---|---|---|---|---|
| `socket_not_found` | `no such file or directory`, `The system cannot find the file specified` | Docker Desktop not running; start it from Start Menu or system tray | Docker daemon not running; `sudo systemctl start docker` | Docker Desktop not running; start from Applications or `open -a Docker` |
| `connection_refused` | `connection refused` | Docker Desktop is starting up — wait ~30s and retry | Docker daemon is starting; `sudo systemctl status docker` | Docker Desktop is starting; check the whale icon in the menu bar |
| `permission_denied` | `permission denied` | Run the application as Administrator, or add your user to the `docker-users` group | Add your user to the `docker` group: `sudo usermod -aG docker $USER` then re-login | Check Docker Desktop settings -> Resources -> File Sharing |
| `timeout` | `context deadline exceeded`, `i/o timeout` | Docker Desktop may be overloaded or hanging — restart it | Docker daemon may be overloaded; check `journalctl -u docker` | Docker Desktop may be unresponsive; restart from menu bar |
| `tls_error` | `tls:`, `certificate` | Check Docker TLS cert configuration and `DOCKER_TLS_VERIFY` | Verify certs in `~/.docker/` match daemon config | Check `~/.docker/` TLS configuration |
| `unknown` | (fallback) | Show raw error with link to Docker Desktop troubleshooting docs | Show raw error with `dockerd` docs link | Show raw error with Docker Desktop docs link |

Detect the platform via `runtime.GOOS` in the diagnostics module (the binary runs on the host, so this is accurate).

**3. Expose `runtime.GOOS` once** in diagnostics, don't scatter it through handlers.

**4. Preserve backward compat** — if any external consumer depends on the old `"docker": bool` shape, consider a migration path or version the health endpoint. Internal-only API can break freely.

---

### Frontend Changes

**5. Update the API type** ([api.ts](../web/src/lib/api.ts))

```typescript
interface DockerHealth {
  connected: boolean;
  error?: string;
  category?: string;
  hints?: string[];
  platform?: string;
  checked_at?: string;
}

export function getHealth(): Promise<{ docker: DockerHealth }> {
  return get<{ docker: DockerHealth }>('/api/health');
}
```

**6. Enhance the health indicator** ([+layout.svelte](../web/src/routes/+layout.svelte))

When `dockerConnected === false`:
- Show a clickable/expandable area (tooltip, popover, or collapsible panel) below the red dot.
- Display the `hints` array as a bulleted list.
- Optionally show the raw `error` in a `<details>` collapse for advanced users.
- Show `checked_at` as relative time ("last checked 15s ago").
- Add a manual "Retry now" button that triggers an immediate health check instead of waiting for the 30s poll.

**7. Add i18n keys** ([en.json](../web/src/lib/i18n/en.json), [ru.json](../web/src/lib/i18n/ru.json))

Add keys for each hint category so hints can be translated. The backend should return `category` + `platform` identifiers; the frontend can use them to look up localized hint text instead of displaying raw English strings from the backend. This keeps i18n centralized in the frontend.

---

### Architecture Notes

- The proxy validator ([validator.go](../internal/proxy/validator.go), [hints.go](../internal/proxy/hints.go)) already implements a similar pattern: classifying errors by substring match and returning human-readable hints. Reuse that approach for consistency.
- Keep diagnostics pure — a function that takes an `error` and `runtime.GOOS` and returns `(category string, hints []string)`. No side effects, easy to unit-test.
- Consider caching the diagnostic result for a few seconds to avoid spamming Docker if the frontend retries rapidly.

---

### Testing

- Unit-test the diagnostics function with synthetic errors for each category x platform combination.
- Integration-test the health endpoint with a mock Docker client that returns each error type.
- Frontend: test that the hint UI renders correctly for each category and collapses/expands properly.
