Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions apps/desktop/src/main/lib/notification-sound.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { execFile } from "node:child_process";
import { existsSync } from "node:fs";
import { join } from "node:path";
import { app } from "electron";

/**
* Gets the path to the notification sound file.
* In development, reads from src/resources. In production, reads from the bundled resources.
*/
function getNotificationSoundPath(): string {
const isDev = !app.isPackaged;

if (isDev) {
return join(app.getAppPath(), "src/resources/sounds/notification.mp3");
}

return join(process.resourcesPath, "resources/sounds/notification.mp3");
}

/**
* Plays the custom notification sound.
* Uses platform-specific commands to play the audio file.
*/
export function playNotificationSound(): void {
const soundPath = getNotificationSoundPath();

if (!existsSync(soundPath)) {
console.warn(`[notification-sound] Sound file not found: ${soundPath}`);
return;
}

if (process.platform === "darwin") {
execFile("afplay", [soundPath]);
} else if (process.platform === "win32") {
execFile("powershell", [
"-c",
`(New-Object Media.SoundPlayer '${soundPath}').PlaySync()`,
]);
} else {
// Linux - try common audio players
execFile("paplay", [soundPath], (error) => {
if (error) {
execFile("aplay", [soundPath]);
}
});
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
5 changes: 4 additions & 1 deletion apps/desktop/src/main/windows/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { createIPCHandler } from "trpc-electron/main";
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.

import {
type AgentCompleteEvent,
notificationsApp,
Expand Down Expand Up @@ -86,9 +87,11 @@ export async function MainWindow() {
body: isPermissionRequest
? `"${event.tabTitle}" needs your attention`
: `"${event.tabTitle}" has finished its task`,
silent: false,
silent: true,
});

playNotificationSound();

notification.on("click", () => {
window.show();
window.focus();
Expand Down
Binary file not shown.