config_schema pages rendered raw keys as labels, ran the description into the secret note without punctuation, floated Save mid-canvas and laid fields on a two-column grid with an orphan cell. - one ListRow per field (label + helper left, control right; JSON full width) - label: manifest label/title, else the key in sentence case with acronyms kept (maps_api_key -> Maps API key) - helper sentences joined with punctuation (joinSentences) - Save on the page heading row (Passwords & Logins' pattern), disabled until dirty, spinner while saving - only required fields are marked (settingsForm.optional -> .required) - overview: Manage plugins as a heading-row button - rail: a plugin row whose sub-page is open is named, not filled - hello-runtime example: readable Chip style / gateway status copy
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.
Keep this tree for real shipped plugins (and the small authoring fixtures that
dogfood the SDK). One-off demos that rebuild a core chrome piece 1:1 do not
belong here — they double the UI and confuse Capabilities ▸ Plugins. Publish those
in the companion
hermes-example-plugins
repo instead.
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.