Skip to content

Web push / browser notifications for web chat: turn completion and reminders reach the user when the tab is backgrounded or closed #1480

Description

@maxnoller

Problem

Web chat (/chat, console/src/routes/chat/chat-page.tsx) is de facto the primary way people interact with HybridClaw, but it has no back-channel to the user when the tab is not in the foreground. There is no Notification API usage, no service worker, no web app manifest and no VAPID/web-push code anywhere in src/ or console/. The only live channel is the /api/events SSE stream (handleApiEvents, src/gateway/gateway-http-server.ts:10633), which the console consumes via useLiveEvents (console/src/hooks/use-live-events.ts) and which only works while the page is open.

Concrete gaps:

  1. Turn completion: a user sends a long-running request, switches tab or app, and never learns the agent finished. There is no title/badge change, no in-page notification, no push.
  2. Reminders / scheduled output: "erinnere mich morgen 9 Uhr an …" creates a job with channelId: 'web' (src/agent/side-effects.ts:30-34). When the user opens the chat at 9:30 there is no browser notification, and today the message itself is deleted as undeliverable (see Proactive delivery drops scheduled-task output for web, Teams, A2A, heartbeat and queued Signal targets, run still marked success #1462). Even after Proactive delivery drops scheduled-task output for web, Teams, A2A, heartbeat and queued Signal targets, run still marked success #1462 stores it in the session, nothing surfaces it outside the open chat view.
  3. Closed tab: without a service worker + push subscription, none of the above can reach a user whose browser tab is closed, which is the typical reminder case.

Proposed fix

Two stages, the first is cheap and independent of the roadmap primitive:

Stage 1 — in-page notifications (tab open, backgrounded)

  • On turn completion and on a proactive/scheduled message arriving in a web session, fire new Notification(...) when document.visibilityState !== 'visible' and permission is granted; click focuses the tab and the session.
  • Ask for notification permission from the chat page once, via an explicit control (not on load).
  • Unread badge in document.title and in the chat sidebar session list as fallback when permission is denied.
  • Requires a real delivery path for web proactive messages (Proactive delivery drops scheduled-task output for web, Teams, A2A, heartbeat and queued Signal targets, run still marked success #1462): either an SSE event on /api/events scoped to the session, or a session.newMessage event the chat page reacts to with a history refetch.

Stage 2 — real web push (tab closed)

  • Service worker + manifest.webmanifest in console/ so the console is installable and can receive push.
  • Gateway: VAPID key pair in config (generated on first start, stored with the other gateway secrets), POST/DELETE /api/push/subscriptions keyed by operator + browser, web-push send on turn completion, scheduled-task delivery and approval requests for web sessions.
  • Push payload carries session id + agent so the click deep-links to /chat/<session>.
  • Per-operator preference: which events push (turn done, reminders/scheduled, approvals). This is the concrete scope of [Roadmap 12.3] Web push notification primitive #501.

Acceptance: a reminder scheduled from web chat for 09:00 produces a browser notification at 09:00 with the tab closed (stage 2) or backgrounded (stage 1), and clicking it opens the correct session with the message visible.

Related


Source: request from Stephan in #hybridclaw (2026-09-03): web chat is the main interaction path and needs a back-channel; browser notification on turn completion and for reminders.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority/P1High Priority — depth work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions