15b0b95413
The kanban drawer had grown the only edge-aware masked scroller in the tree, and the next surface that wants one would have copied it. Lift it to components/ui as FadeScroll, export it on the plugin SDK, and leave kanban's ScrollFade as a name its call sites already pass `max` to. The mask math comes out as two pure functions. jsdom's CSS parser drops any gradient containing calc(), so a rendered mask-image can't be read back off the style attribute -- edgeMask/scrollEdges are testable for real where the component's inline style is not.
Bundled plugins
Drop a <name>/plugin.{ts,tsx} here that default-exports a HermesPlugin and
it registers automatically at boot (vite glob in ../contrib/plugins.ts), with
the same inventory + live enable/disable contract as runtime plugins.
None ship in-tree today — reference/demo plugins (the counter example, the
gateway-pill 1:1 rebuild, the runtime-loader hello world) live in the companion
hermes-example-plugins
repo so the shipped app stays uncluttered.
User- and agent-authored plugins load at runtime from
$HERMES_HOME/desktop-plugins/<name>/plugin.js (the disk door) — see the
hermes-desktop-plugins skill.