Skip to content

Fix notification burst delivery and add context metadata#124

Merged
TraderSamwise merged 6 commits into
masterfrom
notifications-followup
Jun 14, 2026
Merged

Fix notification burst delivery and add context metadata#124
TraderSamwise merged 6 commits into
masterfrom
notifications-followup

Conversation

@TraderSamwise

@TraderSamwise TraderSamwise commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • deliver browser notifications from live alert SSE events instead of delayed notification polling
  • suppress stale poll-catchup records from producing browser notification bursts
  • persist and forward notification category, reason, project, and worktree metadata
  • format OS notification titles with category + project/worktree and keep session-specific detail in the body

Verification

  • yarn typecheck
  • yarn lint
  • yarn test (pre-push: 106 files, 1154 tests)
  • yarn build
  • cd app && yarn typecheck
  • cd app && yarn lint (passes with existing warnings)
  • cd app && yarn vitest run lib/notification-policy.test.ts lib/for-you-feed.test.ts

Summary by CodeRabbit

Release Notes

  • New Features
    • Real-time browser notifications for local projects with automatic heartbeat delivery
    • Enhanced notification display with project, worktree, and category labels for better organization
    • Idle session detection provides alerts when projects become unresponsive
    • Improved interaction request handling in notifications

@vercel

vercel Bot commented Jun 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app Ready Ready Preview, Comment Jun 14, 2026 12:57pm

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@TraderSamwise, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 1 hour, 42 minutes, and 52 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d3c65ecc-f89a-4991-b815-c7709a290da3

📥 Commits

Reviewing files that changed from the base of the PR and between 8af0978 and 34a4b1e.

📒 Files selected for processing (1)
  • app/app/(main)/_layout.tsx
📝 Walkthrough

Walkthrough

This PR enriches the notification and alert system with project/worktree/category/reason metadata and a new interaction_request alert kind carrying structured interaction payloads. It extends persistence, publishing, relay, and mobile-push paths to propagate these fields, adds idle-settle tracking in runtime-state, introduces evaluateAlertEvent and isRecentNotificationRecord in notification policy, expands the For You feed with an actionable flag and location-aware subtitles, and wires heartbeat-driven realtime alert delivery in the app layout.

Changes

Enriched notification metadata, interaction_request alerts, and realtime delivery

Layer / File(s) Summary
Core data contracts
app/lib/events.ts, src/notifications.ts, src/project-events.ts, app/lib/api.ts, src/relay-client.ts
AlertKind adds interaction_request; AlertInteraction and NotificationInteractionRecord interfaces are introduced; AlertEvent, NotificationRecord, and RelayNotificationPush gain optional project/worktree/branch/category/reason/interaction fields.
Alert display formatting
src/alert-display.ts, src/alert-display.test.ts
Adds projectDisplayContext, alertCategoryLabel, alertReasonLabel, alertLocationTitle, and alertMessageBody helpers; contextualizeAlertInput is updated to populate all new label and context fields; tests match updated title/body format.
Notification persistence
src/notifications.ts, src/notifications.test.ts
writeNotification, notificationRecord, addNotification, and upsertNotification are extended to accept and propagate new context fields and interaction through RuntimeExchangeMessage.metadata; tests verify notificationId linkage and interaction object round-trip.
Alert publishing and delivery pipeline
src/project-events.ts, src/mobile-push-bridge.ts, src/main.ts
publishAlert passes enriched metadata into upsertNotification and sets notificationId on the emitted AlertEvent; mobile push bridge forwards all new fields; notify CLI fallback passes enriched fields through upsertNotification and notifyAlert.
notifyAlert gating for interaction_request
src/notify.ts, src/notify.test.ts
notifyAlert unconditionally suppresses interaction_request events with interaction.telemetry and gates the kind under config.onPrompt; tests verify both suppression paths.
Idle-settle notification in runtime-state
src/multiplexer/runtime-state.ts, src/multiplexer/runtime-state.test.ts
Adds IDLE_NOTIFICATION_SETTLE_MS, a per-host WeakMap of idle candidates, and interval logic to publish a needs_input alert after sustained idle and cancel on session resume; tests cover settle, no-alert on brief idle, and cancellation.
Client notification policy
app/lib/notification-policy.ts, app/lib/notification-policy.test.ts
Adds evaluateAlertEvent (live alert→ClientNotificationEvent, filters telemetry), isRecentNotificationRecord (30s window), NEEDS_INPUT_KINDS set, and titleWithProject helper; tests verify live mapping, stale rejection, prefix deduplication, and kind normalization.
For You feed enrichment
app/lib/for-you-feed.ts, app/lib/for-you-feed.test.ts
ForYouCard gains actionable?: boolean; notificationCard sets it from interaction/telemetry state; basenamePath/notificationLocation helpers are added; subtitle is restructured to include categoryLabel and location; classifyNotification returns observation early for telemetry interactions.
Realtime heartbeat in app layout
app/app/(main)/_layout.tsx
Adds a useEffect that starts startHeartbeat for non-relay local projects, handles alert events by calling kickNotificationFeedRefresh and conditionally showing a browser notification via evaluateAlertEvent, and stops the heartbeat on cleanup.
Updated test assertions
src/metadata-server.test.ts, src/metadata-server.interaction.test.ts
Assertions updated to match new [categoryLabel]-prefixed titles, richer message bodies, expanded categoryLabel/reasonLabel/worktreeName response fields, and unquoted SSE match strings.

Sequence Diagram(s)

sequenceDiagram
  participant Agent as Agent / CLI
  participant publishAlert as publishAlert
  participant upsertNotification as upsertNotification
  participant notifyAlert as notifyAlert
  participant MobilePush as forwardAlertToMobilePush
  participant Heartbeat as startHeartbeat (app)
  participant Layout as _layout useEffect
  participant evaluateAlertEvent as evaluateAlertEvent
  participant Browser as Browser Notification API

  Agent->>publishAlert: AlertPublishInput + interaction + labels
  publishAlert->>upsertNotification: enriched metadata (projectName/worktree/category/interaction)
  upsertNotification-->>publishAlert: notification.id
  publishAlert->>notifyAlert: AlertEvent (notificationId + labels + interaction)
  notifyAlert->>MobilePush: payload with notificationId + labels
  publishAlert-->>Heartbeat: SSE alert event emitted
  Heartbeat-->>Layout: alert event received
  Layout->>evaluateAlertEvent: event + notificationSettings
  evaluateAlertEvent-->>Layout: ClientNotificationEvent | null
  Layout->>Browser: showNotification (if enabled + visible)
  Layout->>upsertNotification: kickNotificationFeedRefresh
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • TraderSamwise/aimux#84: Directly extends the mobile-push forwarding and notifyAlert gating pipeline that this PR enriches with interaction_request suppression and additional metadata fields.
  • TraderSamwise/aimux#33: Both PRs modify src/notifications.ts and NotificationRecord, with the retrieved PR establishing the runtime-exchange-backed notification state that this PR extends with interaction and project context fields.
  • TraderSamwise/aimux#15: Introduces NotificationProvider, browser notification utilities, and notificationSettings types that this PR relies on when wiring heartbeat-driven alert display in the app layout.

Poem

🐇 Hop hop, the alerts now carry their name,
A project, a worktree, a label, a claim!
Idle too long? A needs_input will chime,
But telemetry stays silent — no buzz, no rhyme.
The heartbeat ticks on, the feed refreshes bright,
Each interaction delivered with context just right! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.70% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix notification burst delivery and add context metadata' accurately describes the two main changes: addressing notification burst issues and adding metadata enrichment throughout the system.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch notifications-followup

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/app/`(main)/_layout.tsx:
- Around line 311-317: The onError callback in the heartbeat setup (at line 311)
currently only logs the error without attempting to recover. When the heartbeat
encounters permanent failures like 401 (token expiry), it stops retrying and
notifications remain disconnected until dependencies change. Modify the onError
handler to not only log the error but also trigger a reconnection attempt of the
heartbeat. This ensures that when permanent SSE failures occur (such as token
expiry), the system actively re-establishes the connection rather than passively
waiting for external triggers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d219dc15-1b50-4eec-9cba-c9aee19c3efa

📥 Commits

Reviewing files that changed from the base of the PR and between 6e34eaf and 8af0978.

📒 Files selected for processing (21)
  • app/app/(main)/_layout.tsx
  • app/lib/api.ts
  • app/lib/events.ts
  • app/lib/for-you-feed.test.ts
  • app/lib/for-you-feed.ts
  • app/lib/notification-policy.test.ts
  • app/lib/notification-policy.ts
  • src/alert-display.test.ts
  • src/alert-display.ts
  • src/main.ts
  • src/metadata-server.interaction.test.ts
  • src/metadata-server.test.ts
  • src/mobile-push-bridge.ts
  • src/multiplexer/runtime-state.test.ts
  • src/multiplexer/runtime-state.ts
  • src/notifications.test.ts
  • src/notifications.ts
  • src/notify.test.ts
  • src/notify.ts
  • src/project-events.ts
  • src/relay-client.ts

Comment thread app/app/(main)/_layout.tsx
@TraderSamwise
TraderSamwise merged commit c6c26b1 into master Jun 14, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant