Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002) | 1 | // g1t's service worker: browser notifications, nothing else. It caches |
| 2 | // nothing and answers no requests, so pages load exactly as without it. | |
| 3 | // Pushes come from the notify service (services/notify), encrypted for | |
| 4 | // this browser: { title, body, href, tag, kind, urgent }. | |
| 5 | ||
| 6 | self.addEventListener("install", () => self.skipWaiting()); | |
| 7 | self.addEventListener("activate", (event) => event.waitUntil(self.clients.claim())); | |
| 8 | ||
| 9 | self.addEventListener("push", (event) => { | |
| 10 | let data = {}; | |
| 11 | try { | |
| 12 | data = event.data ? event.data.json() : {}; | |
| 13 | } catch { | |
| 14 | data = { title: "g1t", body: event.data ? event.data.text() : "" }; | |
| 15 | } | |
| 16 | const title = data.title || "g1t"; | |
| 17 | event.waitUntil( | |
| 18 | self.registration.showNotification(title, { | |
| 19 | body: data.body || "", | |
| 20 | icon: "/icon-192.png", | |
| 21 | badge: "/badge-96.png", | |
| 22 | // One notification per conversation: a newer message replaces the last. | |
| 23 | tag: data.tag || undefined, | |
| 24 | renotify: Boolean(data.tag), | |
| 25 | data: { href: typeof data.href === "string" && data.href.startsWith("/") && !data.href.startsWith("//") ? data.href : "/" }, | |
| 26 | }), | |
| 27 | ); | |
| 28 | }); | |
| 29 | ||
| 30 | self.addEventListener("notificationclick", (event) => { | |
| 31 | event.notification.close(); | |
| 32 | const href = (event.notification.data && event.notification.data.href) || "/"; | |
| 33 | const target = new URL(href, self.location.origin).href; | |
| 34 | event.waitUntil( | |
| 35 | (async () => { | |
| 36 | const open = await self.clients.matchAll({ type: "window", includeUncontrolled: true }); | |
| 37 | // A tab already on g1t: brought forward and moved there. | |
| 38 | const tab = open.find((client) => new URL(client.url).origin === self.location.origin); | |
| 39 | if (tab) { | |
| 40 | await tab.focus(); | |
| 41 | if ("navigate" in tab) { | |
| 42 | try { | |
| 43 | await tab.navigate(target); | |
| 44 | return; | |
| 45 | } catch { | |
| 46 | // Not ours to navigate (uncontrolled): told instead. | |
| 47 | } | |
| 48 | } | |
| 49 | tab.postMessage({ type: "g1t:navigate", href }); | |
| 50 | return; | |
| 51 | } | |
| 52 | await self.clients.openWindow(target); | |
| 53 | })(), | |
| 54 | ); | |
| 55 | }); |
This file's history is long; its oldest lines are credited to the oldest commit read.