Files
hermes-agent/website/docs/developer-guide
teknium1 e1a6679399 fix(desktop): runtime plugin loader survives hung imports, leaked timers, duplicate ids and broken reloads
Four error-isolation holes in the disk plugin door
(apps/desktop/src/contrib/runtime-loader.ts), found by a static+live audit of
the loader; none had an issue filed.

- A plugin whose module evaluation never settles (top-level `await` on a dead
  host) hung `import()` forever and, through the scan's sequential loop and
  its re-entrancy guard, froze every later plugin and all future scans until
  restart. `import()` now races a 10 s deadline; the plugin errors on its own
  row ("import timed out") and the scan continues.
- Timers and DOM listeners a plugin took out with bare globals survived
  disable and every hot-reload. `ctx.setTimeout` / `ctx.setInterval` /
  `ctx.addEventListener` are tracked with the plugin and torn down on
  unload; the SDK doc says bare globals are not.
- Two folders exporting one plugin id silently last-wins: the second
  disposed the first's registrations and each hot-reload flipped ownership.
  The first (folder-name sorted, so deterministic) owns the id; the later
  file errors on its own row ("duplicate id, already loaded from <path>").
- A save that no longer loads (syntax error, timeout, duplicate) left the old
  incarnation's contributions and activate handle live beside the error
  row, so the Plugins tab showed a broken file as "loaded" and could
  re-enable stale code. The previous incarnation is unloaded and dropped.

Tests: one invariant per fix in runtime-loader.test.ts, all red on base
(the hang case red by timing out).
2026-09-22 00:46:24 -07:00
..