hermes atlas
217·repos hermes·v0.19.0 ★ star this repo

chillerno1/hermes-yt-plugin

A floating YouTube player plugin for Hermes Desktop

★ 2 langJavaScript licenseMIT updated2026-07-30

This plugin provides a compact YouTube player for the Hermes Desktop client that functions in floating or docked modes. It uses an isolated Electron webview to play watch pages, playlists, Shorts, Live, and embed links without requiring an API key.

  • Supports floating or docked pane modes
  • Saves favourites and up to 50 recent videos
  • Uses an isolated webview session
full readme from github

hermes-yt-plugin

A compact, floating or docked YouTube player for the Hermes Desktop client.

Hermes Desktop plugin JavaScript ESM YouTube API key not required Electron webview

Search YouTube or paste a link, keep playback running while you work, and save favourites for later. The plugin uses YouTube's normal watch page in an isolated Electron <webview>, so it requires no API key and does not access media streams directly.

Screenshots

Compact YouTube player showing album artwork Expanded favourites and recent history library
Compact player Expandable library
YouTube player docked in a Hermes layout column Docked YouTube player above a native Hermes review pane
Docked player Native layout integration

Features

  • Search YouTube without configuring an API key.
  • Play watch, playlist, Shorts, Live, embed, and youtu.be links.
  • Keep playback mounted while searching or browsing the library.
  • Save favourites and retain up to 50 recent videos.
  • Configure how many favourites and recent videos each list displays.
  • Float, resize, and reposition the player independently of the workspace.
  • Dock into the native Hermes layout grid, then move, split, tab, or resize the pane.
  • Grow a docked library row smoothly while keeping the neighbouring pane visible.
  • Hide recent history without deleting it.
  • Expand and collapse with smooth pane transitions.
  • Run in a webview session isolated from other Hermes webviews.
  • Check for and install published plugin updates without leaving Hermes.
  • Open, hide, browse favourites, or clear playback from the command palette.

Install

Clone the repository and run the installer:

git clone git@github.com:chillerno1/hermes-yt-plugin.git
cd hermes-yt-plugin
./install.sh

The default destination is ~/.hermes/desktop-plugins/hermes-yt-plugin. Set HERMES_HOME before running the installer to target another Hermes profile:

HERMES_HOME=/path/to/profile ./install.sh

This is a UI-only runtime plugin. It has no backend, build step, or plugin.yaml. Hermes watches the desktop plugin directory and reloads installed changes automatically.

Updates

Open the settings cog and select Check for updates. The plugin checks the latest published GitHub Release and, when a newer version exists, can replace its installed plugin.js directly. The downloaded file must come from the exact release tag and declare the expected plugin ID and version before Hermes will write it.

Hermes hot-reloads the updated file. Favourites, recent history, pane geometry, and the isolated YouTube session remain under the same storage keys. Builds without the required desktop filesystem bridge open the release page for a manual update instead.

Troubleshooting

Installed, but Settings → Plugins shows "0 installed"

If Settings → Plugins reports No desktop plugins installed yet and clicking Open plugins folder raises:

Could not open the plugins folder
ENOENT: no such file or directory, mkdir 'undefined'

then the plugin is installed correctly and Hermes cannot see it. This is a Hermes Desktop bug, not a fault in this plugin — nothing on disk can load while it applies.

Cause. Affected builds ask the connected backend where HERMES_HOME is. Point the desktop client at a remote gateway and the backend answers with a path on the remote machine — or with nothing — so the client resolves its plugin root to the literal string undefined and never looks in your local profile. Upstream issue NousResearch/hermes-agent#66899. From apps/desktop/electron/main.ts on main:

A remote backend reports its own hermes_home over the gateway, which is a path on the REMOTE box; deriving the plugin dir from it yields undefined/desktop-plugins (or a non-existent remote path) and the on-disk plugin door silently breaks (#66899).

Who is affected. Only sessions connected to a remote backend — check for a Remote: <host>:<port> indicator in the status bar. Purely local sessions resolve the path correctly and are unaffected.

Affected versions. Every release up to and including v2026.7.20 (2026-07-20, Hermes Desktop 0.17.0). Verified by inspecting apps/desktop/electron/main.ts at each tag: no release yet contains the hermes:fs:desktopPluginsRoot handler that fixes it.

Fixed in. Unreleased as of 2026-07-30. The fix is on hermes-agent main, landing after v2026.7.20; it moves the resolution into the Electron main process so the plugin root always comes from the local HERMES_HOME, whatever the connection mode.

Workarounds.

  1. Run Hermes locally instead of against a remote backend.
  2. Update Hermes Desktop to a build that includes the fix.
  3. Install into the remote machine's profile instead — HERMES_HOME=/path/on/remote ./install.sh, run there.

Controls

Control Action
Search field Search YouTube or paste a supported link
Enter / play button Play a pasted link or the top search result
Star Add or remove the current video from favourites
List / chevron Show or hide favourites and recent history
Move Enter the Hermes layout editor for the docked pane
Settings cog Choose floating or docked mode, set list length, configure recents, and check for updates
Floating pane Drag the header or resize from the southeast corner
Docked pane Move, split, tab, or resize through the Hermes layout controls
Status bar chip Hide or restore the player
Command palette Show, hide, open favourites, or clear the player

Pane Modes

Mode Behaviour
Floating Draggable overlay with a southeast resize handle and persisted geometry
Docked Native Hermes grid pane with persisted placement and Layout Editor support

The library expands the floating pane to fit its content up to the available viewport height. In a vertical docked split it grows its layout row and pushes the neighbouring pane down, while preserving enough room for that pane. Longer lists then scroll inside the expanded row.

Changing pane location remounts the webview, so active playback is briefly interrupted. Hermes remembers floating geometry and docked grid placement independently, letting each mode return to its previous position.

Supported Links

Accepted targets include YouTube watch pages, youtu.be, playlists, Shorts, Live, and embed URLs, plus bare 11-character video IDs. Start timestamps in t= or start= are honoured, including values such as 1h2m3s.

The current URL, favourites, recent-visibility setting, list length, pane mode, and recent history are stored in Hermes plugin storage. The persist:hermes-yt-plugin partition gives the player its own cookie jar, isolated from other Hermes webviews and persisted across restarts.

Known Limitations

There is no sign-in flow. The player is always signed out, so you get the logged-out YouTube experience: ads, no subscriptions feed, no watch history, no playlists. The partition would persist a session, but nothing can establish one — the masthead (and its sign-in button) is hidden by the pane's CSS, the webview is created without allowpopups, and accounts.google.com rejects Electron's user agent as an insecure embedded browser regardless.

Signing in would not remove ads on a free account — only YouTube Premium does that. This plugin plays YouTube's own player untouched and does not block ads or access media streams.

Playback Lifecycle

Searching and opening the library leave the player mounted, so playback continues through those interactions. Hiding or collapsing the floating pane, disabling a docked pane, or changing pane mode unmounts its body and interrupts playback. This follows the Hermes pane lifecycle.

How It Works

The packaged Hermes renderer runs over file://, which does not provide a suitable referrer for YouTube iframe verification and can cause Error 153. This plugin loads a normal YouTube watch page as a top-level HTTPS document inside a webview instead.

Search also runs inside a hidden webview on the YouTube origin. It fetches the results page same-origin and extracts video entries from ytInitialData. Search failures are isolated from playback and return an empty result list.

Development

desktop-plugins/hermes-yt-plugin/plugin.js # Complete runtime plugin
docs/screenshots/                         # README media
install.sh                                # Hermes profile installer

The runtime plugin is uncompiled ESM and uses react/jsx-runtime rather than JSX. Imports are deliberately limited to @hermes/plugin-sdk, react, and react/jsx-runtime; Hermes validates this list using a raw-source import scan. Styles remain inline because Tailwind does not scan runtime plugin directories.

The plugin ID, install directory, command namespace, and webview partition all use hermes-yt-plugin. This release intentionally starts with fresh pane geometry, plugin storage, history, favourites, and YouTube session state.

Basic local validation:

node --check desktop-plugins/hermes-yt-plugin/plugin.js
bash -n install.sh

Possible Future Work

Nothing here is promised or in progress.

  • Sign-in. Would need the masthead unhidden, a stock browser user agent on the webview, and the auth popup allowed through. Google actively blocks sign-in from embedded webviews, so this may simply not be workable — and it would not remove ads on a free account either. See Known Limitations.

License

MIT