Skip to content

feat(desktop): add custom notification sound#296

Merged
Kitenite merged 3 commits intomainfrom
nursing-canidae-2f3951
Dec 9, 2025
Merged

feat(desktop): add custom notification sound#296
Kitenite merged 3 commits intomainfrom
nursing-canidae-2f3951

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Dec 9, 2025

Summary

  • Replace the default system notification sound with a custom shamisen sound
  • Add notification-sound.ts utility that plays sounds cross-platform (macOS, Windows, Linux)
  • Include notification.mp3 with fade-out effect in resources

Test plan

  • Trigger an agent completion notification and verify the custom sound plays
  • Trigger a permission request notification and verify the custom sound plays
  • Build the app and verify the sound file is bundled correctly

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Desktop notifications now include audio alerts on Windows, macOS, and Linux and play automatically when notifications appear.
    • If a notification sound can't be played, the app will gracefully continue without interrupting notifications.

✏️ Tip: You can customize this high-level summary in your review settings.

Replace the default system notification sound with a custom shamisen sound
for agent completion and permission request notifications.

- Add notification-sound.ts utility to play custom sounds cross-platform
- Set notifications to silent and play custom sound instead
- Include notification.mp3 with fade-out effect in resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 9, 2025

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

Project Deployment Preview Comments Updated (UTC)
website Ready Ready Preview Comment Dec 9, 2025 2:10am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 9, 2025

Walkthrough

Adds a new desktop notification sound module and calls it from the main window notification code; native notification sound is disabled and playback is handled via platform-specific commands with development/production path resolution and a missing-file guard.

Changes

Cohort / File(s) Summary
Notification sound module
apps/desktop/src/main/lib/notification-sound.ts
New file exporting playNotificationSound(): void. Resolves sound path differently for dev vs production using Electron app/process info, logs if missing, and plays audio via platform-specific commands: macOS (afplay), Windows (PowerShell + Media.SoundPlayer), Linux (paplay/aplay) using child_process.execFile.
Main window integration
apps/desktop/src/main/windows/main.ts
Imports playNotificationSound. Sets Notification option silent: true and invokes playNotificationSound() immediately after creating the Notification object (before attaching click handler).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify platform-specific playback command correctness and escaping for Windows PowerShell invocation.
  • Confirm resource path resolution for packaged app vs development (Electron app.getAppPath / resources).
  • Check error handling/logging when the sound file is absent and child_process usage in main process.

Possibly related PRs

Poem

🐰 I found a bell beneath the log,
I tapped it twice to wake the bog.
mac, Win, and Linux sing in tune,
A tiny hop—notification boon.
Quiet no more — hooray, sound's begun! 🎶

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive The PR description provides a summary of changes and test plan, but does not follow the repository's template structure with required sections like Type of Change, Testing details, and Related Issues. Consider restructuring the description to match the template: add explicit Type of Change checkbox selection, provide detailed testing steps, and add Related Issues section.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(desktop): add custom notification sound' clearly and concisely summarizes the main change: adding a custom notification sound to the desktop application.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch nursing-canidae-2f3951

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 9, 2025

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/desktop/src/main/windows/main.ts (1)

3-3: Remove unused import.

The app import from electron is not used anywhere in this file. It's used in notification-sound.ts, but not needed here.

Apply this diff to remove the unused import:

-import { Notification, app, screen } from "electron";
+import { Notification, screen } from "electron";
apps/desktop/src/main/lib/notification-sound.ts (1)

32-41: Add error handling for better reliability.

The exec calls don't include error callbacks, which means playback failures will be silent. Adding error handling would improve debugging and reliability.

Apply this diff to add error callbacks:

 	if (process.platform === "darwin") {
-		exec(`afplay "${soundPath}"`);
+		exec(`afplay "${soundPath}"`, (error) => {
+			if (error) {
+				console.warn("[notification-sound] Failed to play sound:", error.message);
+			}
+		});
 	} else if (process.platform === "win32") {
 		exec(
 			`powershell -c "(New-Object Media.SoundPlayer '${soundPath}').PlaySync()"`,
+			(error) => {
+				if (error) {
+					console.warn("[notification-sound] Failed to play sound:", error.message);
+				}
+			},
 		);
 	} else {
 		// Linux - try common audio players
-		exec(`paplay "${soundPath}" || aplay "${soundPath}"`);
+		exec(`paplay "${soundPath}" || aplay "${soundPath}"`, (error) => {
+			if (error) {
+				console.warn("[notification-sound] Failed to play sound:", error.message);
+			}
+		});
 	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a780f54 and 944dd1c.

⛔ Files ignored due to path filters (1)
  • apps/desktop/src/resources/sounds/notification.mp3 is excluded by !**/*.mp3
📒 Files selected for processing (2)
  • apps/desktop/src/main/lib/notification-sound.ts (1 hunks)
  • apps/desktop/src/main/windows/main.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/main/lib/notification-sound.ts
  • apps/desktop/src/main/windows/main.ts
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/main/lib/notification-sound.ts
  • apps/desktop/src/main/windows/main.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Maintain type safety and avoid using any unless absolutely necessary in TypeScript code

Files:

  • apps/desktop/src/main/lib/notification-sound.ts
  • apps/desktop/src/main/windows/main.ts
🧠 Learnings (4)
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx,js,jsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`

Applied to files:

  • apps/desktop/src/main/windows/main.ts
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/lib/**/*.{ts,tsx} : Never import Node.js modules like node:fs, node:path, node:os in src/lib/electron-router-dom.ts or similar shared code

Applied to files:

  • apps/desktop/src/main/windows/main.ts
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules in renderer process or shared code - only in src/main/

Applied to files:

  • apps/desktop/src/main/windows/main.ts
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/shared/ipc-channels.ts : Define IPC channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers

Applied to files:

  • apps/desktop/src/main/windows/main.ts
🧬 Code graph analysis (1)
apps/desktop/src/main/windows/main.ts (1)
apps/desktop/src/main/lib/notification-sound.ts (1)
  • playNotificationSound (24-42)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (2)
apps/desktop/src/main/windows/main.ts (1)

90-93: LGTM!

The integration of the custom notification sound is well-structured. Setting silent: true prevents the native notification sound from playing, and calling playNotificationSound() before showing the notification provides a good user experience.

apps/desktop/src/main/lib/notification-sound.ts (1)

10-18: LGTM!

The path resolution logic correctly handles both development and production environments using Electron's standard APIs.

Comment thread apps/desktop/src/main/lib/notification-sound.ts
Replace exec with execFile for playing notification sounds. execFile
doesn't spawn a shell, making it immune to command injection attacks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/desktop/src/main/windows/main.ts (1)

79-107: Avoid fully silent notifications when custom sound cannot play

Right now, notifications are created with silent: true and rely entirely on playNotificationSound() for audio, but playNotificationSound can no-op (missing file, missing player, spawn error). In that case the user gets a visually-delivered notification with no sound, whereas previously the OS default sound would have played.

Consider one of:

  • Having playNotificationSound() return a boolean and only setting silent: true when it successfully initiates playback, otherwise leaving silent: false to fall back to the OS sound.
  • If you want sounds even where Notification.isSupported() is false, decouple the sound call from that guard so audio can still play in environments without desktop notifications.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 944dd1c and 2725ba7.

📒 Files selected for processing (2)
  • apps/desktop/src/main/lib/notification-sound.ts (1 hunks)
  • apps/desktop/src/main/windows/main.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/main/lib/notification-sound.ts
🧰 Additional context used
📓 Path-based instructions (3)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/main/windows/main.ts
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/main/windows/main.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Maintain type safety and avoid using any unless absolutely necessary in TypeScript code

Files:

  • apps/desktop/src/main/windows/main.ts
🧬 Code graph analysis (1)
apps/desktop/src/main/windows/main.ts (1)
apps/desktop/src/main/lib/notification-sound.ts (1)
  • playNotificationSound (24-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build

import { productName } from "~/package.json";
import { setMainWindow } from "../lib/auto-updater";
import { createApplicationMenu } from "../lib/menu";
import { playNotificationSound } from "../lib/notification-sound";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use TS path alias for notification-sound import and fix Linux fallback typo

  • To match the existing alias usage in this file and the desktop TS guideline, consider importing via the alias (if configured) instead of a relative path, e.g. import { playNotificationSound } from "lib/notification-sound"; for consistency.
  • Related: in apps/desktop/src/main/lib/notification-sound.ts (lines 23–46), the Linux fallback uses execFile("paplay", ...) and then execFile("atray", ...) if that fails. atray looks like a typo for aplay, so on systems without paplay the fallback will never succeed, and with silent: true here the user may get no sound at all.
🤖 Prompt for AI Agents
In apps/desktop/src/main/windows/main.ts around line 11, change the relative
import to use the TS path alias so it reads import { playNotificationSound }
from "lib/notification-sound"; for consistency; also in
apps/desktop/src/main/lib/notification-sound.ts (approx lines 23–46) fix the
Linux fallback by replacing the incorrect "atray" with "aplay" and stop
suppressing errors/sound by removing or disabling silent:true (or set
silent:false) and surface/log any execFile errors so the fallback can actually
play audio and failures are visible.

@Kitenite Kitenite merged commit ef54650 into main Dec 9, 2025
8 checks passed
@Kitenite Kitenite deleted the nursing-canidae-2f3951 branch December 9, 2025 02:14
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