You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The installed PWA cannot receive push notifications. The landing page advertises them, but no push code ships. I'd like to see Web Push added, or the claim dropped.
Mobile-first PWA: Full feature parity on desktop, tablet, or phone. Install to home screen, run offline, push notifications.
Of those three, only "install to home screen" works today.
What ships
public/sw.js is 22 lines with three listeners — install, activate, fetch. There is no push listener, and fetch deliberately never calls event.respondWith():
self.addEventListener('fetch',()=>{// Deliberately do not call event.respondWith(). Every request goes to the// browser/network stack directly, so the app never serves stale cached JS/CSS.})
That comment explains the design, and it is a reasonable one — it avoids stale bundles. But it also means "run offline" is not accurate either.
Grepping the built client (v2.3.0, 359 JS files in dist/client):
Symbol
Files
pushManager
0
applicationServerKey
0
PushSubscription
0
requestPermission
0
showNotification
0
The same search across src/, server-entry.js, vite.config.ts and electron/ returns nothing. The app never asks for notification permission, so no subscription can exist.
To rule out a platform problem, I checked the device side on Android 17 (Pixel 6, workspace served over HTTPS through Tailscale, installed as a WebAPK). The OS channel is open:
Hermes is asynchronous by nature. Cron jobs fire on a schedule, agent turns run for minutes, and a Swarm worker reports a checkpoint whenever it reaches one. All of that happens while the phone is in a pocket.
Today the only way to hear about it is to route delivery to Telegram, Discord, or another messaging platform, then switch to the workspace to act. That works — I run it — but it makes the PWA a place you go after a notification rather than the thing that notifies you. For an installed, home-screen app advertised as mobile-first, that's a gap.
Proposed implementation
Generate a VAPID key pair; expose the public key to the client and keep the private key with the gateway.
Call pushManager.subscribe() behind an explicit user action in settings, next to the existing notification preferences.
Store subscriptions per user; the gateway already has the user model to hang them on.
Add a push listener to sw.js that calls showNotification, plus a notificationclick handler that focuses or opens the relevant session.
Send with web-push (RFC 8291 payload encryption — worth using the library rather than hand-rolling).
Reuse the event vocabulary Hermes already has: chat finished, chat failed, cron delivered, swarm checkpoint. An away-only mode, matching what the cron mirror_delivery flow already assumes, would avoid buzzing while the user is looking at the app.
Platform notes
Android / desktop Chrome, Edge, Firefox: works in a normal tab, no install required.
iOS 16.4+: push works only from a home-screen-installed PWA — PushManager does not exist in a Safari tab, and the two contexts do not share storage. Gate the permission prompt on window.matchMedia('(display-mode: standalone)').
EU: Apple removed standalone PWA support under the DMA in iOS 17.4, so EU users get no push at all. That constraint is the same one behind iOS app for all regions in EU please! #444.
A service worker is required, and it must be served over HTTPS with a valid certificate.
Scope
Happy to be told this is out of scope. If it is, I'd suggest editing the landing page so "run offline" and "push notifications" don't set an expectation the build doesn't meet — that's what sent me into the source in the first place.
Environment: v2.3.0 (c1e6ed9), self-hosted, gateway on a VPS reached over Tailscale, PWA installed on Android 17.
Summary
The installed PWA cannot receive push notifications. The landing page advertises them, but no push code ships. I'd like to see Web Push added, or the claim dropped.
What the site promises
hermes-workspace.com, mobile/PWA bullet, verbatim:
Of those three, only "install to home screen" works today.
What ships
public/sw.jsis 22 lines with three listeners —install,activate,fetch. There is nopushlistener, andfetchdeliberately never callsevent.respondWith():That comment explains the design, and it is a reasonable one — it avoids stale bundles. But it also means "run offline" is not accurate either.
Grepping the built client (v2.3.0, 359 JS files in
dist/client):pushManagerapplicationServerKeyPushSubscriptionrequestPermissionshowNotificationThe same search across
src/,server-entry.js,vite.config.tsandelectron/returns nothing. The app never asks for notification permission, so no subscription can exist.To rule out a platform problem, I checked the device side on Android 17 (Pixel 6, workspace served over HTTPS through Tailscale, installed as a WebAPK). The OS channel is open:
Android would deliver. Nothing sends.
Why it matters
Hermes is asynchronous by nature. Cron jobs fire on a schedule, agent turns run for minutes, and a Swarm worker reports a checkpoint whenever it reaches one. All of that happens while the phone is in a pocket.
Today the only way to hear about it is to route delivery to Telegram, Discord, or another messaging platform, then switch to the workspace to act. That works — I run it — but it makes the PWA a place you go after a notification rather than the thing that notifies you. For an installed, home-screen app advertised as mobile-first, that's a gap.
Proposed implementation
pushManager.subscribe()behind an explicit user action in settings, next to the existing notification preferences.pushlistener tosw.jsthat callsshowNotification, plus anotificationclickhandler that focuses or opens the relevant session.web-push(RFC 8291 payload encryption — worth using the library rather than hand-rolling).mirror_deliveryflow already assumes, would avoid buzzing while the user is looking at the app.Platform notes
PushManagerdoes not exist in a Safari tab, and the two contexts do not share storage. Gate the permission prompt onwindow.matchMedia('(display-mode: standalone)').Scope
Happy to be told this is out of scope. If it is, I'd suggest editing the landing page so "run offline" and "push notifications" don't set an expectation the build doesn't meet — that's what sent me into the source in the first place.
Environment: v2.3.0 (
c1e6ed9), self-hosted, gateway on a VPS reached over Tailscale, PWA installed on Android 17.