Goal
Notify users when long-running batch jobs complete, blockers are created, or gate runs fail — without requiring them to keep the tab in focus.
Background
Batch executions can run for hours. There is currently no signal when anything noteworthy happens. Users must babysit the UI.
Scope
Browser Notifications (Web Notifications API):
- On first visit to
/execution, request notification permission with a clear explanation
- Subscribe to the existing WebSocket event stream for three event types:
batch.completed → "Batch {id} finished — {N} tasks done"
blocker.created → "Agent is blocked — your input needed"
gate.run.failed → "Gate run failed: {gate_name}"
- Fire
new Notification(...) when tab is not visible (document.visibilityState !== 'visible')
- Respect permission denial gracefully (no re-prompt)
In-app Notification Center:
- Bell icon in the sidebar with unread count badge (red dot or number)
- Dropdown/panel listing last 20 notifications: icon + message + relative timestamp + "mark read" X
- "Mark all read" action
- Notification history stored in
localStorage (no backend required)
- Clear all action
Out of scope
- Webhook (separate issue)
- Email or Slack integration
Acceptance criteria
Goal
Notify users when long-running batch jobs complete, blockers are created, or gate runs fail — without requiring them to keep the tab in focus.
Background
Batch executions can run for hours. There is currently no signal when anything noteworthy happens. Users must babysit the UI.
Scope
Browser Notifications (Web Notifications API):
/execution, request notification permission with a clear explanationbatch.completed→ "Batch {id} finished — {N} tasks done"blocker.created→ "Agent is blocked — your input needed"gate.run.failed→ "Gate run failed: {gate_name}"new Notification(...)when tab is not visible (document.visibilityState !== 'visible')In-app Notification Center:
localStorage(no backend required)Out of scope
Acceptance criteria
npm testandnpm run buildpass