The wired tray path (serve.mjs -> tray/index.mjs -> traySystray.mjs) loaded
systray2 via an inline loader calling require("module") inside an ESM .mjs file
(package type:module), which throws ReferenceError: require is not defined and
was silently swallowed -> no tray, no diagnostic (regressed in v3.8.34). Even
when fixed, systray2 is not in node_modules; it is lazily installed into
~/.omniroute/runtime by trayRuntime.ts.
initSystrayUnix now delegates loading to trayRuntime.ts::loadSystray (async),
fixes the icon path (icon.png, not icons/icon.png), sets isTemplateIcon:false
(full-color icon rendered as a white square under macOS template mode), and
serve.mjs surfaces tray-start failures to stderr instead of swallowing them.
TDD: tray-systray-loader-4605.test.ts drives the loader seam via an injected
ctor (native binary can't run in unit tests) and asserts the menu/icon/template
invariants; fail-before confirmed by restoring the broken require() loader.