feat: introduce notification system and claude notifications (#450)

* feat: introduce notification system and claude notifications

* fix(sw): prevent caching of API requests and WebSocket upgrades

* default to false for webpush notifications and translations for the button

* fix: notifications orchestrator and add a notification when  first enabled

* fix: remove unused state update and dependency in settings controller hook

* fix: show notifications settings tab

* fix: add notifications for response completion for all providers

* feat: show session name in notification and don't reload tab on clicking
--- the notification

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Haileyesus <something@gmail.com>
This commit is contained in:
Simos Mikelatos
2026-03-13 16:59:09 +01:00
committed by GitHub
parent 6f6dacad5e
commit 45e71a0e73
36 changed files with 1629 additions and 69 deletions

View File

@@ -450,9 +450,10 @@ async function cleanupProject(projectPath, sessionId = null) {
* SSE Stream Writer - Adapts SDK/CLI output to Server-Sent Events
*/
class SSEStreamWriter {
constructor(res) {
constructor(res, userId = null) {
this.res = res;
this.sessionId = null;
this.userId = userId;
this.isSSEStreamWriter = true; // Marker for transport detection
}
@@ -485,9 +486,10 @@ class SSEStreamWriter {
* Non-streaming response collector
*/
class ResponseCollector {
constructor() {
constructor(userId = null) {
this.messages = [];
this.sessionId = null;
this.userId = userId;
}
send(data) {
@@ -920,7 +922,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
res.setHeader('Connection', 'keep-alive');
res.setHeader('X-Accel-Buffering', 'no'); // Disable nginx buffering
writer = new SSEStreamWriter(res);
writer = new SSEStreamWriter(res, req.user.id);
// Send initial status
writer.send({
@@ -930,7 +932,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
});
} else {
// Non-streaming mode: collect messages
writer = new ResponseCollector();
writer = new ResponseCollector(req.user.id);
// Collect initial status message
writer.send({
@@ -1219,7 +1221,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.setHeader('X-Accel-Buffering', 'no');
writer = new SSEStreamWriter(res);
writer = new SSEStreamWriter(res, req.user.id);
}
if (!res.writableEnded) {