mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 15:09:42 +02:00
feat(push): plumb hostname-aware prefix into Web Push notifications
Closes the Web Push gap left by #82: in-page Notification API and tab title flash both showed `codeman:<host>` after that PR, but OS-level notifications dispatched via the service worker — the surface that matters most when the tab is closed and the user is reading their system notification center across multiple Codeman instances — still hardcoded the literal "Codeman" prefix. Service workers run in an isolated context with no access to document.title or any in-page state, so the hostname has to ride along in the push payload itself. Server (server.ts:sendPushNotifications): emit `hostTitle: this.windowTitle` in the JSON payload alongside the existing `title` (event-specific text like "Permission Required"). The two stay separate so the SW can compose them — the server knows the host, the SW knows the OS context. Service worker (sw.js): compose `${hostTitle}: ${title}` when both present, mirroring the in-page Notification format from notification-manager.js. Fall back to `title || hostTitle || 'Codeman'` so older servers (which omit hostTitle) keep working — the field is purely additive on the wire. Tests (test/push-payload-host-title.test.ts): mock the `web-push` module via vi.hoisted(), instantiate WebServer without binding a port, stub the push store with one fake subscription, and verify the JSON payload shipped to webpush.sendNotification carries the right hostTitle for both --title-hostname overrides and the os.hostname() default. Also mirrors the SW's title-composition logic in a small helper so any future change to the format breaks the test instead of being caught only by users running multiple Codeman instances. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -110,7 +110,7 @@ self.addEventListener('push', (event) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const { title, body, tag, sessionId, urgency, actions } = payload;
|
||||
const { title, hostTitle, body, tag, sessionId, urgency, actions } = payload;
|
||||
|
||||
const options = {
|
||||
body: body || '',
|
||||
@@ -126,8 +126,15 @@ self.addEventListener('push', (event) => {
|
||||
options.actions = actions;
|
||||
}
|
||||
|
||||
// Match the in-page Notification format: "codeman:<host>: <event title>".
|
||||
// hostTitle is sent by servers >= the hostname-aware push payload change;
|
||||
// older servers omit it and we fall back to the bare title.
|
||||
const displayTitle = hostTitle && title
|
||||
? `${hostTitle}: ${title}`
|
||||
: (title || hostTitle || 'Codeman');
|
||||
|
||||
event.waitUntil(
|
||||
self.registration.showNotification(title || 'Codeman', options)
|
||||
self.registration.showNotification(displayTitle, options)
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1437,6 +1437,10 @@ export class WebServer extends EventEmitter {
|
||||
|
||||
const payload = JSON.stringify({
|
||||
title: template.title,
|
||||
// Hostname-aware prefix so OS-level notifications from multiple Codeman
|
||||
// instances (laptop / dev box / NAS) are unambiguous in the system tray.
|
||||
// Mirrors the in-page Notification format in notification-manager.js.
|
||||
hostTitle: this.windowTitle,
|
||||
body,
|
||||
tag: `codeman-${event}-${sessionId}`,
|
||||
sessionId,
|
||||
|
||||
Reference in New Issue
Block a user