feat(one): bridge in-app notifications to native OS notifications#25
Open
os-zhuang wants to merge 3 commits into
Open
feat(one): bridge in-app notifications to native OS notifications#25os-zhuang wants to merge 3 commits into
os-zhuang wants to merge 3 commits into
Conversation
ObjectOS One is a desktop client, but notifications were in-app only — the Console bell (`sys_inbox_message`, ADR-0030 L5) is invisible when the window is backgrounded, which is exactly when notifications matter. This adds a webview bridge that mirrors new inbox messages to native OS notifications (macOS Notification Center / Windows toast / Linux libnotify). `assets/notification-bridge.js` is injected into every page alongside update-banner.js (combined into one initialization script in windows.rs). It no-ops outside the Console and outside Tauri. On the Console it polls the canonical inbox object via the data API (`GET /api/v1/data/sys_inbox_message` — the dedicated `/api/v1/notifications` route isn't mounted in this runtime), dedupes by id (localStorage, baselined on first load so the backlog isn't replayed), and when the window is backgrounded fires a native notification per new message, badges the dock with the count missed while away (cleared on focus), and focuses + deep-links on click (best-effort via the plugin's action event). No new Rust deps or capabilities needed: tauri-plugin-notification is already registered (lib.rs) and `notification:default` + window show/focus perms are already granted; withGlobalTauri exposes the JS API. Verified the data contract end-to-end against a live 9.7.0 runtime: inserting a real sys_inbox_message row, the bridge's fetch+parse extracts title/body(body_md)/actionUrl(action_url)/id/createdAt correctly. The native firing path (sendNotification/badge/focus) needs an actual Tauri build to exercise — out of reach here (no cargo); the plumbing is in place. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The first cut assumed Tauri plugin/window JS APIs are on `window.__TAURI__` (`.notification.sendNotification`, `.window…setBadgeCount`, `.app`). They are not: this app's `withGlobalTauri` exposes only `core`/`event`, and every native op here goes through a Rust `#[tauri::command]` called via `core.invoke` (see prefs.html / update-banner.js). As written the bridge would have fired nothing — the permission gate (`T.notification`) would stay false. Rework to match the codebase: - add Rust commands `notify_native`, `set_badge`, `notif_request_permission` (commands.rs) and register them (lib.rs); they call the already-registered notification plugin + the main window's badge from Rust, bypassing the JS ACL (no capability changes needed); - the bridge now calls them via `core.invoke` and drops all `T.notification`/ `.window`/`.app` usage; the tested poll/parse path is unchanged. Compiler-verified: `cargo check` passes (toolchain installed locally), so the Tauri APIs (`notification().builder().show()`, `set_badge_count`, `request_permission`) are correct. Still needs a real desktop build to see a toast actually render (and macOS authorization typically wants a signed bundle). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lightweight observability for the notification bridge (content-free — no title/body logged). Verified the app builds and launches via `tauri dev` (toolchain installed locally); the sidecar loads Auth+Audit so sys_notification exists and the inbox path is live. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
ObjectOS One is a desktop client, but notifications were in-app only — the Console bell (
sys_inbox_message, ADR-0030 L5) is invisible when the window is backgrounded, which is exactly when a notification matters most. This is a minimal approach-1 prototype: a webview bridge that mirrors new inbox messages to native OS notifications (macOS Notification Center / Windows toast / Linux libnotify).How
assets/notification-bridge.js— injected into every page alongsideupdate-banner.js(combined into one initialization script inwindows.rs). No-ops outside the Console and outside Tauri.GET /api/v1/data/sys_inbox_message?sort=-created_at) — the dedicated/api/v1/notificationsroute returns 404 in this runtime, and the bell readssys_inbox_messageanyway;document.hidden/ no focus), fires one native notification per new message;No new infra needed
tauri-plugin-notificationis already a dep and registered (lib.rs),notification:default+ window show/focus/unminimize permissions are already granted (capabilities/default.json), andwithGlobalTauriexposes the JS API. So this is a JS file + one injection line.Verification
@objectstack9.7.0 runtime: inserting a realsys_inbox_messagerow, the bridge's exact fetch+parse extractstitle/body(body_md) /actionUrl(action_url) /id/createdAtcorrectly. JS syntax-checked.sendNotification/ dock badge / focus) needs an actual Tauri build (nocargoin this environment; the Tauri build is tag-triggered in CI). The plumbing is all in place; this needs a real desktop build to see toasts.Follow-ups (out of scope for this prototype)
desktop/nativechannel insys_notification_preferenceso it's user-configurable like email/push (approach 2 — needs a framework touch).🤖 Generated with Claude Code