Skip to content

feat: add native desktop notifications#180

Merged
nwparker merged 7 commits intomainfrom
nwparker/notis-2
Apr 7, 2026
Merged

feat: add native desktop notifications#180
nwparker merged 7 commits intomainfrom
nwparker/notis-2

Conversation

@nwparker
Copy link
Copy Markdown
Contributor

Summary

  • add native system notifications for Orca agent completion and terminal bell events
  • route notification delivery through main-process IPC so Electron handles macOS, Linux, and Windows consistently
  • add a Notifications settings page with per-trigger toggles, focus suppression, and a test action

Design

  • keep agent-idle and bell detection in the renderer, where terminal title parsing already lives
  • dispatch structured notification events to the main process, which applies settings, focus filtering, and burst deduplication before showing the native notification
  • persist notification preferences in global settings with safe nested merges so future notification options can be added without clobbering sibling values

Test plan

  • pnpm test src/main/ipc/notifications.test.ts src/main/ipc/register-core-handlers.test.ts src/renderer/src/lib/agent-status.test.ts
  • pnpm run typecheck
  • pnpm exec oxlint src/main/ipc/notifications.ts src/main/ipc/notifications.test.ts src/main/ipc/register-core-handlers.ts src/main/ipc/register-core-handlers.test.ts src/main/persistence.ts src/preload/index.ts src/preload/index.d.ts src/shared/types.ts src/shared/constants.ts src/renderer/src/store/slices/settings.ts src/renderer/src/components/terminal-pane/pty-connection.ts src/renderer/src/components/terminal-pane/pty-transport.ts src/renderer/src/components/terminal-pane/use-terminal-pane-lifecycle.ts src/renderer/src/components/terminal-pane/TerminalPane.tsx src/renderer/src/lib/agent-status.ts src/renderer/src/components/settings/NotificationsPane.tsx src/renderer/src/components/settings/Settings.tsx

nwparker and others added 3 commits April 6, 2026 22:13
Dedupe notifications by worktree instead of by source+worktree so that
an agent-task-complete and terminal-bell firing in the same data chunk
only produce one notification. Flatten the NotificationsPane layout,
fix duplicate preload type declarations, and add aria-label to toggles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nwparker and others added 4 commits April 6, 2026 22:53
The allWorktrees() selector in TerminalPane created a new array
reference on every store update (.flat() always returns new), causing
the component to re-render on any state change — likely the blank
screen on worktree open.

Extract to useNotificationDispatch which reads store state at dispatch
time via getState() instead of selectors, making the callback stable
(depends only on worktreeId). Also brings TerminalPane under the
400-line max-lines lint rule.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clicking a notification now brings Orca to the foreground and switches
to the worktree that triggered it, reusing the existing
ui:activateWorktree IPC channel.

Also adds permission status detection via
systemPreferences.getNotificationSettings() on macOS, showing a warning
banner in the settings pane when notifications are blocked with a
button to open System Settings directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Cast systemPreferences through unknown for macOS-only
  getNotificationSettings() which is absent from Electron's
  cross-platform type definitions
- Fix test helper typing for mock.calls.find()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nwparker nwparker merged commit c0b6687 into main Apr 7, 2026
1 check 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