@puddle-code/cli 0.2.21 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -4
- package/README.md +4 -0
- package/dist/host-control.mjs +202 -22
- package/dist/index.js +223 -29
- package/dist/install-cli.sh +13 -2
- package/dist/public/assets/App-XpQccO6u.js +2 -0
- package/dist/public/assets/{Dashboard-BhAek_r4.js → Dashboard-DMEBtYwv.js} +1 -1
- package/dist/public/assets/{EditorTabClose-CSKAGWsA.js → EditorTabClose-PbgNs_rN.js} +1 -1
- package/dist/public/assets/{FindWidget-B6dVpkKr.js → FindWidget-ZDHywlX4.js} +1 -1
- package/dist/public/assets/LazyTerminal-DRgaFViU.js +2 -0
- package/dist/public/assets/{ModelRefcount-CrpDNwTn.js → ModelRefcount-CI3cYeQp.js} +1 -1
- package/dist/public/assets/{NewProjectDialog-D-hVQlA4.js → NewProjectDialog-Bhfj_sYl.js} +1 -1
- package/dist/public/assets/{PaneEditorBody--h9jLt1e.js → PaneEditorBody-Bz74yrKU.js} +3 -3
- package/dist/public/assets/{PdfViewer-CNzO040W.js → PdfViewer-73_UlYnM.js} +2 -2
- package/dist/public/assets/{SettingsDialog-DaxYdggs.js → SettingsDialog-DJmvzJHQ.js} +2 -2
- package/dist/public/assets/{Terminal-DQL8GETy.js → Terminal-BwuoWKED.js} +5 -5
- package/dist/public/assets/{Workspace-BDDSmIKE.js → Workspace-DPL1IKA6.js} +4 -4
- package/dist/public/assets/{abnfDiagram-VCTEODGH-Dj6CI3Nv.js → abnfDiagram-VCTEODGH-AawOhIcj.js} +1 -1
- package/dist/public/assets/architecture-7GRP2DOG-BbAArV9u.js +1 -0
- package/dist/public/assets/{architectureDiagram-5GKGNRK7-7n7HJQxV.js → architectureDiagram-5GKGNRK7-D9vP5DO8.js} +1 -1
- package/dist/public/assets/{blockDiagram-I7D4REHJ-Cmsxv8OS.js → blockDiagram-I7D4REHJ-Cm9i3cTT.js} +1 -1
- package/dist/public/assets/{buffer-store-NeRSjzSg.js → buffer-store-BIpSx_-b.js} +2 -2
- package/dist/public/assets/{button-hdghxls7.js → button-CgZcwDne.js} +1 -1
- package/dist/public/assets/{c4Diagram-7LVT6UL2-D23ryIme.js → c4Diagram-7LVT6UL2-BiN1-NKB.js} +1 -1
- package/dist/public/assets/channel-CUWW1WRo.js +1 -0
- package/dist/public/assets/{chunk-2E4U76K2-usroR3SM.js → chunk-2E4U76K2-BxAMvG2q.js} +1 -1
- package/dist/public/assets/{chunk-4HAMMTFA-B4mxD8f1.js → chunk-4HAMMTFA-D4UgoMR5.js} +1 -1
- package/dist/public/assets/{chunk-75Z2AOVW-BSDNHsOk.js → chunk-75Z2AOVW-ViSC5KeO.js} +1 -1
- package/dist/public/assets/{chunk-CLGD4ZFX-DpUm0L6C.js → chunk-CLGD4ZFX-C1obqh7u.js} +1 -1
- package/dist/public/assets/{chunk-DU6HZSFF-Cin9bFEJ.js → chunk-DU6HZSFF-Dd9xUi9L.js} +1 -1
- package/dist/public/assets/{chunk-F27PBJKO-BWPIZmRh.js → chunk-F27PBJKO-S5xJlLKg.js} +1 -1
- package/dist/public/assets/{chunk-GMAD6QVW-eS27qQYi.js → chunk-GMAD6QVW-DXbO7ojE.js} +1 -1
- package/dist/public/assets/{chunk-GVQU2GXP-DvZzuy44.js → chunk-GVQU2GXP-vZ5Z6XwC.js} +1 -1
- package/dist/public/assets/{chunk-IMKFNOWR-CKfEqBn8.js → chunk-IMKFNOWR-BGcGac3f.js} +1 -1
- package/dist/public/assets/{chunk-L3NEJ4N5-Gq2sL0Oq.js → chunk-L3NEJ4N5-BfxBma0T.js} +1 -1
- package/dist/public/assets/{chunk-OSK3NFVY-DSHFDm2K.js → chunk-OSK3NFVY-BaWjSKfn.js} +1 -1
- package/dist/public/assets/{chunk-P2QGCYS3-B0b6PsO0.js → chunk-P2QGCYS3-Ce8Ukv1J.js} +1 -1
- package/dist/public/assets/{chunk-POPQ4Y6H-B_whPWNN.js → chunk-POPQ4Y6H-lrRlaehc.js} +1 -1
- package/dist/public/assets/{chunk-PWAF6VOD-DfdxoQ_F.js → chunk-PWAF6VOD-DcoK5-E2.js} +1 -1
- package/dist/public/assets/{chunk-SHT3W25Y-CHrnqlvt.js → chunk-SHT3W25Y-BWdHabuP.js} +1 -1
- package/dist/public/assets/{chunk-SVP7TREG-keTkvLck.js → chunk-SVP7TREG-CfpAvBiO.js} +1 -1
- package/dist/public/assets/{chunk-TICWLB2K-ZF0XdA5t.js → chunk-TICWLB2K-BnqQqZIp.js} +1 -1
- package/dist/public/assets/{chunk-TLUHSLCS-B3xiw07r.js → chunk-TLUHSLCS-Cd6EShzW.js} +2 -2
- package/dist/public/assets/classDiagram-ZZMXUADV-Cve4a5Gc.js +1 -0
- package/dist/public/assets/classDiagram-v2-VYDZK3BY-Cve4a5Gc.js +1 -0
- package/dist/public/assets/{context-menu-fGutCa7q.js → context-menu-CtKnUzHa.js} +1 -1
- package/dist/public/assets/{copy-B38GDFbv.js → copy-Xz4fK2YI.js} +1 -1
- package/dist/public/assets/{cssMode-BBPxRrZH.js → cssMode-CNBJ-DrN.js} +1 -1
- package/dist/public/assets/{cynefin-OW5HDTMX-BKwXHhp6.js → cynefin-OW5HDTMX-C1-MjjCZ.js} +1 -1
- package/dist/public/assets/{cynefinDiagram-5FMLGOSQ-B59dmX8D.js → cynefinDiagram-5FMLGOSQ-xt5hQJ88.js} +1 -1
- package/dist/public/assets/{dagre-GXQ25YYZ-BysK_yGg.js → dagre-GXQ25YYZ-Bgahh86t.js} +1 -1
- package/dist/public/assets/{diagram-S7CK7UJ4-BTvgOprS.js → diagram-S7CK7UJ4-Djip7YHP.js} +1 -1
- package/dist/public/assets/{diagram-UQ7AKVKN-C1FXQfFT.js → diagram-UQ7AKVKN-StD7DYFa.js} +1 -1
- package/dist/public/assets/{diagram-VSXAHHWV-CTub3LLw.js → diagram-VSXAHHWV-C6W2XMTF.js} +1 -1
- package/dist/public/assets/{diagram-VX7I27RA-C8YSQsst.js → diagram-VX7I27RA-C5rBIjxM.js} +1 -1
- package/dist/public/assets/{diagram-Z3DM3KII-zBY2ZT-7.js → diagram-Z3DM3KII-DDzmZnRU.js} +1 -1
- package/dist/public/assets/dialog-_JRACgt4.js +41 -0
- package/dist/public/assets/disclosure-DBXM9uBm.js +1 -0
- package/dist/public/assets/{dist-DWt3BCrg.js → dist-Bl7vUoam.js} +1 -1
- package/dist/public/assets/{dist-1iWQMdtt.js → dist-CzEdee3K.js} +1 -1
- package/dist/public/assets/{ebnfDiagram-PWID7BFC-DZbYMMq9.js → ebnfDiagram-PWID7BFC-TJlh5Fea.js} +1 -1
- package/dist/public/assets/{erDiagram-RLTQ6QDP-BufFqh6K.js → erDiagram-RLTQ6QDP-BSNVCw_x.js} +1 -1
- package/dist/public/assets/{errors-0CwhraNS.js → errors-BzfxU_Kw.js} +1 -1
- package/dist/public/assets/eventmodeling-NTZA5JFV-DZ8G1RJ1.js +1 -0
- package/dist/public/assets/flowDiagram-HODETNUW-Dd9WpTU6.js +1 -0
- package/dist/public/assets/{ganttDiagram-EL5Y4UJY-CzBnAVfV.js → ganttDiagram-EL5Y4UJY-BGFNgCoM.js} +1 -1
- package/dist/public/assets/{gitGraph-4MIJSDKK-DzkiKDz3.js → gitGraph-4MIJSDKK-Du3WBCxU.js} +1 -1
- package/dist/public/assets/{gitGraphDiagram-WWUBYQGX-Cg5zqV71.js → gitGraphDiagram-WWUBYQGX-Dq_yAVmM.js} +1 -1
- package/dist/public/assets/{htmlMode-HP2zLptL.js → htmlMode-BWm5ayBQ.js} +1 -1
- package/dist/public/assets/index-BP-EF5G2.js +82 -0
- package/dist/public/assets/index-CAvJOpdz.css +2 -0
- package/dist/public/assets/{info-A6RAGUB7-DrzRcVCp.js → info-A6RAGUB7-V0hlAV3d.js} +1 -1
- package/dist/public/assets/{infoDiagram-27XIBGKW-DKhhQ6Mi.js → infoDiagram-27XIBGKW-DZM1jHkq.js} +1 -1
- package/dist/public/assets/{ishikawaDiagram-5VMMS53U-Sxvy6BP4.js → ishikawaDiagram-5VMMS53U-CZlO72MU.js} +1 -1
- package/dist/public/assets/{journeyDiagram-3NMN7TZE-DLCDGlAt.js → journeyDiagram-3NMN7TZE-DZZieltZ.js} +1 -1
- package/dist/public/assets/{jsonMode-3cqCCYan.js → jsonMode-DA3Di61-.js} +1 -1
- package/dist/public/assets/{kanban-definition-UXKFOSKX-BBHezsUK.js → kanban-definition-UXKFOSKX-BAFfgDCD.js} +1 -1
- package/dist/public/assets/{line-CXD0KIW6.js → line-DNRJuk5l.js} +1 -1
- package/dist/public/assets/{markdown-mermaid-gr78oRak.js → markdown-mermaid-zldCuMow.js} +2 -2
- package/dist/public/assets/{math-DD0qgOf_.js → math-Bl0zHVK2.js} +1 -1
- package/dist/public/assets/{media-refresh-store-DTLvGgrw.js → media-refresh-store-BemN_6sc.js} +1 -1
- package/dist/public/assets/{mermaid-parser.core-CQpv25sY.js → mermaid-parser.core-DpOHgT8D.js} +3 -3
- package/dist/public/assets/{mermaid.core-CO3okgIG.js → mermaid.core-DuO1Atct.js} +3 -3
- package/dist/public/assets/{mindmap-definition-YA3MSWOX-DnuqRR1y.js → mindmap-definition-YA3MSWOX-Bbgshnhk.js} +1 -1
- package/dist/public/assets/notification-delivery-DehaYHWS.js +1 -0
- package/dist/public/assets/{packet-AYTQ26CC--9UnHksn.js → packet-AYTQ26CC-H2b8zBMM.js} +1 -1
- package/dist/public/assets/{pdf-DFR5TvGJ.js → pdf-DTc2umrm.js} +1 -1
- package/dist/public/assets/{pegDiagram-XKGWAZYB-m8JdNNtC.js → pegDiagram-XKGWAZYB-BKdl5Qrn.js} +1 -1
- package/dist/public/assets/{pie-WAS4IAKB-GnDinOP5.js → pie-WAS4IAKB-SB8x1Dpp.js} +1 -1
- package/dist/public/assets/{pieDiagram-E7YTZNPT-u-NA8MFl.js → pieDiagram-E7YTZNPT-YXMNp-5O.js} +1 -1
- package/dist/public/assets/{project-abbrev-Ce2YQx3q.js → project-abbrev-D7aa-LGS.js} +1 -1
- package/dist/public/assets/{protocol-support-DM3D3Owq.js → protocol-support-Dm8bEo7Y.js} +1 -1
- package/dist/public/assets/{quadrantDiagram-AXDQQJYC-si_KhMBB.js → quadrantDiagram-AXDQQJYC-B2TAChhA.js} +1 -1
- package/dist/public/assets/{radar-RG4KPBEZ-CnJwODJt.js → radar-RG4KPBEZ-D2xzXNL8.js} +1 -1
- package/dist/public/assets/{railroad-74A4TZTK-Cgg0LWTI.js → railroad-74A4TZTK-CKug6hj8.js} +1 -1
- package/dist/public/assets/railroad-abnf-HS5TGJTU-cj9XZHow.js +1 -0
- package/dist/public/assets/railroad-ebnf-LZEXJU2U-CCIfyLjg.js +1 -0
- package/dist/public/assets/railroad-peg-WCYAUIDC-DkxYDi7O.js +1 -0
- package/dist/public/assets/{railroadDiagram-O6MQD6OU-DuQX8qaE.js → railroadDiagram-O6MQD6OU-Bft2oh-d.js} +1 -1
- package/dist/public/assets/{requirementDiagram-BXWQKSXE-Chwrn5Tf.js → requirementDiagram-BXWQKSXE-e0GCEfhM.js} +1 -1
- package/dist/public/assets/{sankeyDiagram-P5KCCOFB-FpJ30BIQ.js → sankeyDiagram-P5KCCOFB-Csb70YNA.js} +1 -1
- package/dist/public/assets/{scroll-restoration-B3J09_am.js → scroll-restoration-D7f4DDsJ.js} +1 -1
- package/dist/public/assets/{selection-actions-awCJJCSe.js → selection-actions-D5wKfiBu.js} +1 -1
- package/dist/public/assets/{sequenceDiagram-WJ2MYXX4-DVw87Ucm.js → sequenceDiagram-WJ2MYXX4-DcnD8T30.js} +1 -1
- package/dist/public/assets/{stateDiagram-D77RDMKH-qmBcs9VH.js → stateDiagram-D77RDMKH-GnwFUlNg.js} +1 -1
- package/dist/public/assets/stateDiagram-v2-MP3YSRHH-Bktkoy9c.js +1 -0
- package/dist/public/assets/{swimlanes-42K2YHIH-ts5KQGMt.js → swimlanes-42K2YHIH-CPq_eKyi.js} +1 -1
- package/dist/public/assets/swimlanesDiagram-VR7AAH4N-BmjIwfwd.js +8 -0
- package/dist/public/assets/{switch-DMkSxGf3.js → switch-DZbOKnZ0.js} +1 -1
- package/dist/public/assets/{timeline-definition-24CTP7MA-BDL_pzrt.js → timeline-definition-24CTP7MA-DjUPAJJx.js} +1 -1
- package/dist/public/assets/{treeView-Q6P3EWNA-B1vMOTkl.js → treeView-Q6P3EWNA-DBuhlxaq.js} +1 -1
- package/dist/public/assets/{treemap-WGGIJYW6-wi5T0FIb.js → treemap-WGGIJYW6-3TKwSIeh.js} +1 -1
- package/dist/public/assets/{tsMode-CsaS5imR.js → tsMode-BYwFH3pC.js} +1 -1
- package/dist/public/assets/{use-ui-state-2VprViGF.js → use-ui-state-BXROVbIw.js} +1 -1
- package/dist/public/assets/{vennDiagram-4TSXK5OY-Djvp5-2_.js → vennDiagram-4TSXK5OY-oDrGN_Dh.js} +1 -1
- package/dist/public/assets/{view-state-store-rOwEBYKn.js → view-state-store-vUrDt7wu.js} +1 -1
- package/dist/public/assets/{wardley-WFR3VGLG-Di-PFH_i.js → wardley-WFR3VGLG-Br5CacuJ.js} +1 -1
- package/dist/public/assets/{wardleyDiagram-VM6X3IG4-B5Y8UZiL.js → wardleyDiagram-VM6X3IG4-Cw_uOLXA.js} +1 -1
- package/dist/public/assets/{ws-DsytGlkr.js → ws-Ug1Tr2sh.js} +1 -1
- package/dist/public/assets/{xychartDiagram-S5SC5T6Z-d-pvxFe2.js → xychartDiagram-S5SC5T6Z-Cl8gNx_J.js} +1 -1
- package/dist/public/index.html +2 -2
- package/dist/public/notification-worker.js +104 -6
- package/dist/puddlang.js +17578 -0
- package/package.json +3 -2
- package/dist/public/assets/App-NrJUEV9p.js +0 -2
- package/dist/public/assets/LazyTerminal-fxF4IO4o.js +0 -2
- package/dist/public/assets/architecture-7GRP2DOG-CDcS1iVd.js +0 -1
- package/dist/public/assets/channel-B98_B4F2.js +0 -1
- package/dist/public/assets/classDiagram-ZZMXUADV-CalLaxUD.js +0 -1
- package/dist/public/assets/classDiagram-v2-VYDZK3BY-CalLaxUD.js +0 -1
- package/dist/public/assets/dialog-CVAp0B_q.js +0 -41
- package/dist/public/assets/disclosure-CWTUvRKU.js +0 -1
- package/dist/public/assets/eventmodeling-NTZA5JFV-CC5F0fZk.js +0 -1
- package/dist/public/assets/flowDiagram-HODETNUW-Dmt2DAB8.js +0 -1
- package/dist/public/assets/index-Bwl8S5Du.css +0 -2
- package/dist/public/assets/index-W9vnFL1i.js +0 -82
- package/dist/public/assets/notification-delivery-rQp5tkM8.js +0 -1
- package/dist/public/assets/railroad-abnf-HS5TGJTU-DPqD3hz7.js +0 -1
- package/dist/public/assets/railroad-ebnf-LZEXJU2U-9Jxyrh7e.js +0 -1
- package/dist/public/assets/railroad-peg-WCYAUIDC-gr2ZokSI.js +0 -1
- package/dist/public/assets/stateDiagram-v2-MP3YSRHH-TK5UygAI.js +0 -1
- package/dist/public/assets/swimlanesDiagram-VR7AAH4N-BUMN0oZf.js +0 -8
|
@@ -1,8 +1,81 @@
|
|
|
1
|
-
/* global self, indexedDB */
|
|
1
|
+
/* global self, indexedDB, crypto, TextEncoder, TextDecoder */
|
|
2
2
|
/* Notifications only: no fetch interception or caching of host content. */
|
|
3
3
|
let queue = Promise.resolve();
|
|
4
4
|
let database;
|
|
5
5
|
const uuid = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i;
|
|
6
|
+
function targetOf(value) {
|
|
7
|
+
if (
|
|
8
|
+
!value ||
|
|
9
|
+
!/^[0-9a-f]{10}$/.test(value.project) ||
|
|
10
|
+
!uuid.test(value.session) ||
|
|
11
|
+
(value.host !== undefined && !uuid.test(value.host))
|
|
12
|
+
)
|
|
13
|
+
return undefined;
|
|
14
|
+
return {
|
|
15
|
+
project: value.project,
|
|
16
|
+
session: value.session,
|
|
17
|
+
...(value.host ? { host: value.host } : {}),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function validContent(value) {
|
|
21
|
+
return (
|
|
22
|
+
value &&
|
|
23
|
+
typeof value.title === 'string' &&
|
|
24
|
+
value.title.length > 0 &&
|
|
25
|
+
value.title.length <= 160 &&
|
|
26
|
+
typeof value.body === 'string' &&
|
|
27
|
+
value.body.length > 0 &&
|
|
28
|
+
value.body.length <= 256 &&
|
|
29
|
+
targetOf(value)
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
function bytes(hex) {
|
|
33
|
+
return Uint8Array.from(hex.match(/../g), (byte) => parseInt(byte, 16));
|
|
34
|
+
}
|
|
35
|
+
async function decryptPreview(payload) {
|
|
36
|
+
const preview = payload.preview;
|
|
37
|
+
if (
|
|
38
|
+
!preview ||
|
|
39
|
+
!uuid.test(preview.key) ||
|
|
40
|
+
!/^[a-f0-9]{24}$/.test(preview.iv) ||
|
|
41
|
+
typeof preview.ciphertext !== 'string' ||
|
|
42
|
+
preview.ciphertext.length > 3072 ||
|
|
43
|
+
!/^(?:[a-f0-9]{2}){16,}$/.test(preview.ciphertext)
|
|
44
|
+
)
|
|
45
|
+
return null;
|
|
46
|
+
const db = await new Promise((resolve, reject) => {
|
|
47
|
+
const request = indexedDB.open('puddle-notification-keys', 1);
|
|
48
|
+
request.onupgradeneeded = () => request.result.createObjectStore('keys', { keyPath: 'host' });
|
|
49
|
+
request.onsuccess = () => resolve(request.result);
|
|
50
|
+
request.onerror = () => reject(request.error);
|
|
51
|
+
});
|
|
52
|
+
try {
|
|
53
|
+
const saved = await new Promise((resolve, reject) => {
|
|
54
|
+
const request = db.transaction('keys').objectStore('keys').get(payload.host);
|
|
55
|
+
request.onsuccess = () => resolve(request.result);
|
|
56
|
+
request.onerror = () => reject(request.error);
|
|
57
|
+
});
|
|
58
|
+
if (!saved || saved.id !== preview.key || !/^[a-f0-9]{64}$/.test(saved.secret)) return null;
|
|
59
|
+
const key = await crypto.subtle.importKey('raw', bytes(saved.secret), 'AES-GCM', false, [
|
|
60
|
+
'decrypt',
|
|
61
|
+
]);
|
|
62
|
+
const clear = await crypto.subtle.decrypt(
|
|
63
|
+
{
|
|
64
|
+
name: 'AES-GCM',
|
|
65
|
+
iv: bytes(preview.iv),
|
|
66
|
+
additionalData: new TextEncoder().encode(
|
|
67
|
+
JSON.stringify(['puddle-notification-v1', payload.host, payload.id, preview.key]),
|
|
68
|
+
),
|
|
69
|
+
},
|
|
70
|
+
key,
|
|
71
|
+
bytes(preview.ciphertext),
|
|
72
|
+
);
|
|
73
|
+
const content = JSON.parse(new TextDecoder().decode(clear));
|
|
74
|
+
return validContent(content) ? content : null;
|
|
75
|
+
} finally {
|
|
76
|
+
db.close();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
6
79
|
function receipts() {
|
|
7
80
|
if (!database)
|
|
8
81
|
database = new Promise((resolve, reject) => {
|
|
@@ -46,6 +119,7 @@ async function seen(id, save = false) {
|
|
|
46
119
|
}
|
|
47
120
|
function show(request, host, fromPush = false, client) {
|
|
48
121
|
const task = queue.then(async () => {
|
|
122
|
+
if (typeof request === 'function') request = await request();
|
|
49
123
|
const deduplicate = request.id.startsWith('puddle-event-');
|
|
50
124
|
// Every push must call showNotification: Safari revokes permission for
|
|
51
125
|
// silent pushes. Matching tags replace a racing live alert without renotify.
|
|
@@ -55,7 +129,10 @@ function show(request, host, fromPush = false, client) {
|
|
|
55
129
|
tag: request.id,
|
|
56
130
|
silent: true,
|
|
57
131
|
renotify: false,
|
|
58
|
-
data:
|
|
132
|
+
data: {
|
|
133
|
+
...(host ? { host } : { client }),
|
|
134
|
+
...(targetOf(request.target) ? { target: targetOf(request.target) } : {}),
|
|
135
|
+
},
|
|
59
136
|
icon: '/puddle-app.png',
|
|
60
137
|
});
|
|
61
138
|
if (deduplicate) await seen(request.id, true).catch(() => {});
|
|
@@ -96,7 +173,18 @@ self.addEventListener('push', (event) => {
|
|
|
96
173
|
if (!uuid.test(payload?.id) || !uuid.test(payload?.host)) return;
|
|
97
174
|
event.waitUntil(
|
|
98
175
|
show(
|
|
99
|
-
|
|
176
|
+
async () => {
|
|
177
|
+
// A missing/rotated key or damaged ciphertext must still produce a visible push.
|
|
178
|
+
const content = await decryptPreview(payload).catch(() => null);
|
|
179
|
+
return {
|
|
180
|
+
id: `puddle-event-${payload.id}`,
|
|
181
|
+
title: content?.title ?? 'Puddle',
|
|
182
|
+
body: content?.body ?? 'An agent needs your attention.',
|
|
183
|
+
...(content
|
|
184
|
+
? { target: { project: content.project, session: content.session, host: payload.host } }
|
|
185
|
+
: {}),
|
|
186
|
+
};
|
|
187
|
+
},
|
|
100
188
|
payload.host,
|
|
101
189
|
true,
|
|
102
190
|
),
|
|
@@ -104,8 +192,13 @@ self.addEventListener('push', (event) => {
|
|
|
104
192
|
});
|
|
105
193
|
self.addEventListener('notificationclick', (event) => {
|
|
106
194
|
event.notification.close();
|
|
107
|
-
const
|
|
108
|
-
const
|
|
195
|
+
const destination = targetOf(event.notification.data?.target);
|
|
196
|
+
const host = destination?.host ?? event.notification.data?.host;
|
|
197
|
+
const target = uuid.test(host)
|
|
198
|
+
? `/?notificationHost=${host}${destination ? `¬ificationProject=${destination.project}¬ificationSession=${destination.session}` : ''}`
|
|
199
|
+
: destination
|
|
200
|
+
? `/project/${destination.project}/session/${destination.session}`
|
|
201
|
+
: '/';
|
|
109
202
|
event.waitUntil(
|
|
110
203
|
(async () => {
|
|
111
204
|
const windows = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
|
|
@@ -121,11 +214,16 @@ self.addEventListener('notificationclick', (event) => {
|
|
|
121
214
|
new URL(client.url).pathname === '/preview.html'
|
|
122
215
|
)
|
|
123
216
|
continue;
|
|
124
|
-
|
|
217
|
+
try {
|
|
218
|
+
await client.focus();
|
|
219
|
+
} catch {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
125
222
|
client.postMessage({
|
|
126
223
|
t: 'notification-click',
|
|
127
224
|
id: event.notification.tag,
|
|
128
225
|
...(uuid.test(host) ? { host } : {}),
|
|
226
|
+
...(destination ? { target: destination } : {}),
|
|
129
227
|
});
|
|
130
228
|
return;
|
|
131
229
|
}
|