Last time I wrote about keeping a WebSocket alive inside a Manifest V3 extension, and the whole trick was staying awake: heartbeats, reconnects, guards. That solved the session that's already running. It did nothing for the case that actually matters most to a planning-poker tool, which is the teammate who isn't there yet.
Here's the moment. The facilitator points a ticket in Repoker. Three people are in the room. The fourth is deep in an editor somewhere, no GitHub tab open, no room open, nothing. The team either waits or pings them on Slack, which is exactly the busywork this tool exists to remove. I wanted their machine to just... tap them on the shoulder.
You can't hold a connection open for that. Chrome kills an idle extension service worker in about thirty seconds, and no heartbeat can run when there's nothing alive to send it. The primitive for this is the opposite of staying awake: let the worker die, and have the browser's push service resurrect it for one job. That's Web Push, and getting it working from a Cloudflare Worker turned out to be the most interesting crypto detour I've taken in a while.
The extension half is almost suspiciously easy
Extensions have been able to use the standard Push API since Chrome 88. You add the notifications permission, and the background service worker subscribes like any web page would:






