fix: restore vscode native notification behavior
Move VS Code/Cursor desktop notifications onto the webview Notification API instead of the extension-host watcher path, which could not reliably produce native OS notifications. Route OpenCode runtime events from the shared sync pipeline into the VS Code webview so completion, error, question, and permission notifications use the same live event stream as the UI. Respect the OpenChamber notification settings in VS Code, including template rendering, completion cooldowns, permission auto-accept suppression, and the notify-while-focused mode. Use VS Code's window focus signal from the extension host instead of document.hasFocus() inside the webview, so hidden-only notifications are suppressed while Cursor or VS Code is focused across platforms.
This commit is contained in:
@@ -1,23 +1,40 @@
|
||||
import type { NotificationPayload, NotificationsAPI } from '@openchamber/ui/lib/api/types';
|
||||
import { sendBridgeMessage } from './bridge';
|
||||
|
||||
type NotifyResponse = { shown?: boolean };
|
||||
const showWebviewNotification = async (payload?: NotificationPayload): Promise<boolean> => {
|
||||
if (typeof Notification === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Notification.permission === 'default') {
|
||||
const permission = await Notification.requestPermission();
|
||||
if (permission !== 'granted') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Notification.permission !== 'granted') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const title = typeof payload?.title === 'string' && payload.title.trim().length > 0
|
||||
? payload.title.trim()
|
||||
: 'OpenChamber';
|
||||
const body = typeof payload?.body === 'string' ? payload.body : '';
|
||||
|
||||
new Notification(title, { body });
|
||||
return true;
|
||||
};
|
||||
|
||||
export const createVSCodeNotificationsAPI = (): NotificationsAPI => ({
|
||||
async notifyAgentCompletion(payload?: NotificationPayload): Promise<boolean> {
|
||||
try {
|
||||
const response = await sendBridgeMessage<NotifyResponse>('notifications:notify', { payload });
|
||||
return Boolean(response?.shown);
|
||||
return await showWebviewNotification(payload);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
async canNotify(): Promise<boolean> {
|
||||
try {
|
||||
return await sendBridgeMessage<boolean>('notifications:can-notify');
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return typeof Notification !== 'undefined' && Notification.permission !== 'denied';
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user