Skill: hermes-dashboard-subpath-ops


Hermes Dashboard Subpath Operations

Use this skill when managing a Hermes dashboard mounted behind a reverse-proxy subpath like /kanban/, especially when the same host also serves a separate WWW app and root-level dashboard routes must stay private.

When to use

Core workflow

  1. Inspect current mount + service
  2. Confirm reverse-proxy route exists and whether it sets X-Forwarded-Prefix.
  3. Confirm the dashboard service definition, working directory, and PATH include the Node/npm location.
  4. Check whether port 9119 is listening.

  5. Rebuild/reinstall safely

  6. If reinstalling from repo, sync to the intended git revision first.
  7. Ensure the repo is installed in the venv (pip install -e .) when appropriate.
  8. Build the frontend from web/ so hermes_cli/web_dist/ exists.
  9. Recreate/enable the user systemd service if needed.

  10. Verify only prefixed routes

  11. Local prefixed checks with X-Forwarded-Prefix: /kanban should return 200 for:
    • /
    • /api/dashboard/plugins
    • /dashboard-plugins/kanban/dist/index.js
    • /sessions
  12. Confirm the page injects window.__HERMES_BASE_PATH__ = "/kanban".
  13. On mixed hosts, unprefixed public /sessions and /api/dashboard/plugins should remain 404 unless intentionally exposed.

  14. Treat public 403 correctly

  15. If public /kanban/... returns 403 while local prefixed checks pass, that usually means an allowlist or outer proxy rule is blocking access.
  16. Do not widen public access as a debugging shortcut.

Known pitfalls

0) Kanban route broken by corrupt board DB even though dashboard service is running

Symptom pattern: - /kanban/kanban looks broken or renders an empty page after an update - hermes-dashboard.service is still active (running) and port 9119 is listening - dashboard HTML loads, but the Kanban board/plugin fails behind the scenes - systemd logs show KanbanDbCorruptError / database disk image is malformed

Required checks: - inspect systemctl --user status hermes-dashboard --no-pager -l for KanbanDbCorruptError - verify which board DB is corrupt (for example ~/.hermes/kanban/boards/multi-agent/kanban.db) - check backup candidates carefully: extracted daily backup directories can contain an empty per-board DB even when the ZIP snapshot for the same day contains a healthy non-zero board DB - validate candidate backups before restore (PRAGMA integrity_check, non-zero size, expected task count / latest task)

Recovery rule: - restoring a Kanban DB backup changes user data, so get explicit user approval before replacing the live DB - prefer the newest healthy board-specific backup, not merely the newest extracted backup directory

Reference: references/kanban-db-corruption-recovery.md

1) Broken plugin advertised by registry

A plugin can appear in /api/dashboard/plugins even when its bundle does not exist.

Symptoms: - dashboard error about plugin script load - registry includes plugin name - /dashboard-plugins/<name>/dist/index.js returns 404

Preferred fix: - disable the plugin in the local checkout rather than broadening routes - for the bundled example dashboard, renaming manifest.json to manifest.disabled.json is a valid local mitigation

2) Plugin script loads, but plugin API calls still 404 under subpath

A plugin can serve JS/CSS with 200 and still fail at runtime if it hardcodes root-relative API paths like:

fetch('/api/plugins/<plugin-name>/...')

Under /kanban/, that misses the required prefix and often produces browser-side 404 Not Found.

Required pattern:

const base = window.__HERMES_BASE_PATH__ || '';
const url = base + '/api/plugins/<plugin-name>' + path;

When a bundled plugin lacks source files in the checkout, the repo-tracked built dist/index.js may be the only practical patch point.

2b) Mixed subpath pitfall: HTTP and WebSocket paths may need DIFFERENT treatment

The Kanban dashboard plugin has a subtle split-brain path rule on subpath deployments like /kanban/:

If you prefix both HTTP and WS with BASE_PATH, the HTTP side double-prefixes (/kanban/kanban/...) and the browser can fail with errors such as "The string did not match the expected pattern." or board-load failures. If you prefix neither, WebSocket events break under the reverse-proxy subpath.

For bundled Kanban on this repo, the practical hotfix point is: - plugins/kanban/dashboard/dist/index.js

Quick verification after patch: - hard reload the browser - confirm HTTP requests go to /kanban/api/plugins/kanban/... only once after SDK prefixing - confirm WebSocket connects to /kanban/api/plugins/kanban/events?... - restart hermes-dashboard.service after patching the bundled dist file

3) Reinstall can resurrect broken bundled plugins

SDK.fetchJSON(${API}/board); const ws = new WebSocket(${proto}//${window.location.host}${WS_API}/events?...);


Failure mode if you get this wrong:
- patching `API` itself to include the base path can produce malformed/duplicated paths once `SDK.fetchJSON` prefixes it again, leading to browser errors such as `The string did not match the expected pattern.` or requests hitting the wrong URL.

When a bundled plugin lacks source files in the checkout, the repo-tracked built `dist/index.js` may be the only practical patch point.

### 3) Reinstall can resurrect broken bundled plugins


Concrete regression to check immediately after updates:
- `plugins/kanban/dashboard/dist/index.js` can regress from a subpath-aware API base back to a root-relative constant like `const API = "/api/plugins/kanban";`
- symptom pattern: dashboard shell loads at `/kanban/...`, but the Kanban tab is blank/broken because plugin backend calls miss the `/kanban` prefix

After reinstall/update, re-check:
- plugin registry contents
- each advertised plugin bundle route
- subpath-aware API URL construction inside affected plugin bundles
- specifically grep the Kanban bundle for `const API = "/api/plugins/kanban";` and replace it with a base-path-aware form such as:

```js
const BASE_PATH = (window.__HERMES_BASE_PATH__ || "").replace(/\/$/, "");
const API = `${BASE_PATH}/api/plugins/kanban`;

Reference: references/zico-vm-kanban-plugin-subpath-regression.md

Verification checklist

References