watch-tail 0.6.1 → 0.7.1
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/README.md +115 -354
- package/build/client/_app/immutable/assets/0.DKleCc0-.css +2 -0
- package/build/client/_app/immutable/assets/0.DKleCc0-.css.br +0 -0
- package/build/client/_app/immutable/assets/0.DKleCc0-.css.gz +0 -0
- package/build/client/_app/immutable/chunks/{CJY9dzlo.js → 1mB5Ee1Q.js} +1 -1
- package/build/client/_app/immutable/chunks/1mB5Ee1Q.js.br +0 -0
- package/build/client/_app/immutable/chunks/1mB5Ee1Q.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{0HQmZBP8.js → 3fFVdy92.js} +1 -1
- package/build/client/_app/immutable/chunks/3fFVdy92.js.br +0 -0
- package/build/client/_app/immutable/chunks/3fFVdy92.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CHWzTWIO.js → 8mpn3Xst.js} +1 -1
- package/build/client/_app/immutable/chunks/8mpn3Xst.js.br +0 -0
- package/build/client/_app/immutable/chunks/8mpn3Xst.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CIRHUa7o.js → B78Vj1az.js} +1 -1
- package/build/client/_app/immutable/chunks/B78Vj1az.js.br +0 -0
- package/build/client/_app/immutable/chunks/B78Vj1az.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DsjX0FWg.js → B7aS9tS2.js} +1 -1
- package/build/client/_app/immutable/chunks/B7aS9tS2.js.br +0 -0
- package/build/client/_app/immutable/chunks/B7aS9tS2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{Bpq3-dbO.js → BF84Orj8.js} +1 -1
- package/build/client/_app/immutable/chunks/BF84Orj8.js.br +0 -0
- package/build/client/_app/immutable/chunks/BF84Orj8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BIdvnjrP.js +1 -0
- package/build/client/_app/immutable/chunks/BIdvnjrP.js.br +1 -0
- package/build/client/_app/immutable/chunks/BIdvnjrP.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BNZjpNgL.js → BPoZrXrH.js} +1 -1
- package/build/client/_app/immutable/chunks/BPoZrXrH.js.br +0 -0
- package/build/client/_app/immutable/chunks/BPoZrXrH.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BPnf3PCq.js → BSy__Jrd.js} +1 -1
- package/build/client/_app/immutable/chunks/BSy__Jrd.js.br +0 -0
- package/build/client/_app/immutable/chunks/BSy__Jrd.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BLIhNWn-.js → BdW_yBQU.js} +1 -1
- package/build/client/_app/immutable/chunks/BdW_yBQU.js.br +0 -0
- package/build/client/_app/immutable/chunks/BdW_yBQU.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BMFtpXWH.js → BnRQs9nz.js} +5 -5
- package/build/client/_app/immutable/chunks/BnRQs9nz.js.br +0 -0
- package/build/client/_app/immutable/chunks/BnRQs9nz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{MQIJFRGs.js → C6r7NvtG.js} +1 -1
- package/build/client/_app/immutable/chunks/C6r7NvtG.js.br +0 -0
- package/build/client/_app/immutable/chunks/C6r7NvtG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{B7Wrulwc.js → CEw1go7g.js} +1 -1
- package/build/client/_app/immutable/chunks/CEw1go7g.js.br +0 -0
- package/build/client/_app/immutable/chunks/CEw1go7g.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BMAPes50.js → CFJEGo4j.js} +1 -1
- package/build/client/_app/immutable/chunks/CFJEGo4j.js.br +0 -0
- package/build/client/_app/immutable/chunks/CFJEGo4j.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CGnVqaBL.js +1 -0
- package/build/client/_app/immutable/chunks/CGnVqaBL.js.br +0 -0
- package/build/client/_app/immutable/chunks/CGnVqaBL.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CknPwNsn.js → CY8zQ4KM.js} +1 -1
- package/build/client/_app/immutable/chunks/CY8zQ4KM.js.br +0 -0
- package/build/client/_app/immutable/chunks/CY8zQ4KM.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DGPOPiag.js → CZ3S843d.js} +1 -1
- package/build/client/_app/immutable/chunks/CZ3S843d.js.br +0 -0
- package/build/client/_app/immutable/chunks/CZ3S843d.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BS49-HdT.js → CgAZPeK7.js} +1 -1
- package/build/client/_app/immutable/chunks/CgAZPeK7.js.br +0 -0
- package/build/client/_app/immutable/chunks/CgAZPeK7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{B5Gt-01T.js → CrmB4MvE.js} +1 -1
- package/build/client/_app/immutable/chunks/CrmB4MvE.js.br +0 -0
- package/build/client/_app/immutable/chunks/CrmB4MvE.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{HbGXDNOY.js → CtWwlW0t.js} +1 -1
- package/build/client/_app/immutable/chunks/CtWwlW0t.js.br +0 -0
- package/build/client/_app/immutable/chunks/CtWwlW0t.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DOY2FQbe.js → D-AkVRH7.js} +1 -1
- package/build/client/_app/immutable/chunks/D-AkVRH7.js.br +0 -0
- package/build/client/_app/immutable/chunks/D-AkVRH7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DeAq2fo8.js → D0CZlpgd.js} +1 -1
- package/build/client/_app/immutable/chunks/D0CZlpgd.js.br +0 -0
- package/build/client/_app/immutable/chunks/D0CZlpgd.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BNe95Eqc.js → D0IZin0e.js} +1 -1
- package/build/client/_app/immutable/chunks/D0IZin0e.js.br +0 -0
- package/build/client/_app/immutable/chunks/D0IZin0e.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{C5DTlk-U.js → DI6o1zMC.js} +1 -1
- package/build/client/_app/immutable/chunks/DI6o1zMC.js.br +0 -0
- package/build/client/_app/immutable/chunks/DI6o1zMC.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{SPw4Pe1k.js → DbWb9_dK.js} +1 -1
- package/build/client/_app/immutable/chunks/DbWb9_dK.js.br +0 -0
- package/build/client/_app/immutable/chunks/DbWb9_dK.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DBvBFE2b.js → Dh3ZWuG8.js} +1 -1
- package/build/client/_app/immutable/chunks/Dh3ZWuG8.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dh3ZWuG8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BZ7frOsj.js → Dp3OTI-g.js} +1 -1
- package/build/client/_app/immutable/chunks/Dp3OTI-g.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dp3OTI-g.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{ByL_HxfT.js → DtdjxckD.js} +1 -1
- package/build/client/_app/immutable/chunks/DtdjxckD.js.br +0 -0
- package/build/client/_app/immutable/chunks/DtdjxckD.js.gz +0 -0
- package/build/client/_app/immutable/chunks/YehCS1lO.js +5 -0
- package/build/client/_app/immutable/chunks/YehCS1lO.js.br +0 -0
- package/build/client/_app/immutable/chunks/YehCS1lO.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BQzvXDmX.js → g-7YfdwH.js} +1 -1
- package/build/client/_app/immutable/chunks/g-7YfdwH.js.br +0 -0
- package/build/client/_app/immutable/chunks/g-7YfdwH.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BVyebcr0.js → zfc2KyIr.js} +1 -1
- package/build/client/_app/immutable/chunks/zfc2KyIr.js.br +0 -0
- package/build/client/_app/immutable/chunks/zfc2KyIr.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.B1Kx6Gr2.js → app.C-KKyvGI.js} +2 -2
- package/build/client/_app/immutable/entry/app.C-KKyvGI.js.br +0 -0
- package/build/client/_app/immutable/entry/app.C-KKyvGI.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.obx3dQT_.js +1 -0
- package/build/client/_app/immutable/entry/start.obx3dQT_.js.br +1 -0
- package/build/client/_app/immutable/entry/start.obx3dQT_.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{0.BN3NguWs.js → 0.2dnHMwE1.js} +1 -1
- package/build/client/_app/immutable/nodes/0.2dnHMwE1.js.br +0 -0
- package/build/client/_app/immutable/nodes/{0.BN3NguWs.js.gz → 0.2dnHMwE1.js.gz} +0 -0
- package/build/client/_app/immutable/nodes/{1.CjbVqPIj.js → 1.D5nbnmDb.js} +1 -1
- package/build/client/_app/immutable/nodes/1.D5nbnmDb.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.D5nbnmDb.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.DAQ4mvAt.js +5 -0
- package/build/client/_app/immutable/nodes/2.DAQ4mvAt.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DAQ4mvAt.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/handler.js +4 -4
- package/build/index.js +4 -4
- package/build/server/chunks/chunks/{EventScatter.js-D3Jaw_Cw.js → EventScatter.js-Du7AJN9m.js} +50 -17
- package/build/server/chunks/chunks/{EventScatter.js-D3Jaw_Cw.js.map → EventScatter.js-Du7AJN9m.js.map} +1 -1
- package/build/server/chunks/chunks/{archive.js-C2D-5edp.js → archive.js-D2jtMmDo.js} +134 -26
- package/build/server/chunks/chunks/archive.js-D2jtMmDo.js.map +1 -0
- package/build/server/chunks/chunks/{aws.js-DkPqAybc.js → env2.js-C5BgBJDY.js} +63 -6
- package/build/server/chunks/chunks/env2.js-C5BgBJDY.js.map +1 -0
- package/build/server/chunks/chunks/identity.js-NmGXxBz3.js +22 -0
- package/build/server/chunks/chunks/identity.js-NmGXxBz3.js.map +1 -0
- package/build/server/chunks/chunks/{internal2.js-V-6GgvEA.js → internal2.js--RCssYze.js} +2 -2
- package/build/server/chunks/chunks/{internal2.js-V-6GgvEA.js.map → internal2.js--RCssYze.js.map} +1 -1
- package/build/server/chunks/chunks/{level-filter.js-B3o2hyWD.js → level-filter.js-D9MNrew3.js} +2 -2
- package/build/server/chunks/chunks/{level-filter.js-B3o2hyWD.js.map → level-filter.js-D9MNrew3.js.map} +1 -1
- package/build/server/chunks/chunks/{log-buffer.js-BI_gQOls.js → log-buffer.js-A9FA-Qv8.js} +18 -3
- package/build/server/chunks/chunks/log-buffer.js-A9FA-Qv8.js.map +1 -0
- package/build/server/chunks/chunks/{regions.js-IQPMyP5C.js → regions.js-COf7DgnH.js} +3 -3
- package/build/server/chunks/chunks/regions.js-COf7DgnH.js.map +1 -0
- package/build/server/chunks/chunks/{series-buckets.js-BjigySff.js → series-buckets.js-BmCYga3F.js} +28 -3
- package/build/server/chunks/chunks/series-buckets.js-BmCYga3F.js.map +1 -0
- package/build/server/chunks/chunks/{state.js-D3IR3OVb.js → state.js-CI2ef6Vi.js} +2 -2
- package/build/server/chunks/chunks/{state.js-D3IR3OVb.js.map → state.js-CI2ef6Vi.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/archive/{_server.ts.js-83Ch7djd.js → _server.ts.js-C4hWyXuu.js} +17 -9
- package/build/server/chunks/entries/endpoints/api/archive/_server.ts.js-C4hWyXuu.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/health/{_server.ts.js-VctnBhIJ.js → _server.ts.js-C5tfrpmC.js} +4 -5
- package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-C5tfrpmC.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/identity/{_server.ts.js-Dt540Sio.js → _server.ts.js-PWRPScuN.js} +6 -24
- package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-PWRPScuN.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/log-groups/{_server.ts.js-drLgUdvB.js → _server.ts.js-D4y43Vwe.js} +14 -11
- package/build/server/chunks/entries/endpoints/api/log-groups/_server.ts.js-D4y43Vwe.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/regions/{_server.ts.js-CBqfN6Pg.js → _server.ts.js-9_g0ojki.js} +8 -9
- package/build/server/chunks/entries/endpoints/api/regions/_server.ts.js-9_g0ojki.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/series/{_server.ts.js-DOvBhEDU.js → _server.ts.js-DibT3Hjc.js} +34 -16
- package/build/server/chunks/entries/endpoints/api/series/_server.ts.js-DibT3Hjc.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/stream/{_server.ts.js-B9_-4ssJ.js → _server.ts.js-3ZYI-Za9.js} +15 -12
- package/build/server/chunks/entries/endpoints/api/stream/_server.ts.js-3ZYI-Za9.js.map +1 -0
- package/build/server/chunks/entries/fallbacks/{error.svelte.js-C9F075al.js → error.svelte.js-DP0OULWi.js} +3 -3
- package/build/server/chunks/entries/fallbacks/{error.svelte.js-C9F075al.js.map → error.svelte.js-DP0OULWi.js.map} +1 -1
- package/build/server/chunks/entries/pages/{_layout.svelte.js-CBQpEToy.js → _layout.svelte.js-8U7ZeKYO.js} +3 -3
- package/build/server/chunks/entries/pages/_layout.svelte.js-8U7ZeKYO.js.map +1 -0
- package/build/server/chunks/entries/pages/{_page.svelte.js-NmVMu4KB.js → _page.svelte.js-hG1agdw-.js} +82 -33
- package/build/server/chunks/entries/pages/_page.svelte.js-hG1agdw-.js.map +1 -0
- package/build/server/chunks/{handler-dtYbHuwP.js → handler-_dxqeJJj.js} +3 -3
- package/build/server/chunks/{handler-dtYbHuwP.js.map → handler-_dxqeJJj.js.map} +1 -1
- package/build/server/chunks/{index.js-C9CJvnha.js → index.js-arX1nCCw.js} +2 -2
- package/build/server/chunks/{index.js-C9CJvnha.js.map → index.js-arX1nCCw.js.map} +1 -1
- package/build/server/chunks/{manifest.js-C_VOyvDI.js → manifest.js-D3447-0_.js} +12 -12
- package/build/server/chunks/{manifest.js-C_VOyvDI.js.map → manifest.js-D3447-0_.js.map} +1 -1
- package/build/server/chunks/nodes/{0.js-CNFDDPj5.js → 0.js-XM75fTfb.js} +4 -4
- package/build/server/chunks/nodes/{0.js-CNFDDPj5.js.map → 0.js-XM75fTfb.js.map} +1 -1
- package/build/server/chunks/nodes/{1.js-bsWFfMNd.js → 1.js-CRIDfcrR.js} +3 -3
- package/build/server/chunks/nodes/{1.js-bsWFfMNd.js.map → 1.js-CRIDfcrR.js.map} +1 -1
- package/build/server/chunks/nodes/{2.js-Cq_bF6lW.js → 2.js-1qmqKlMg.js} +3 -3
- package/build/server/chunks/nodes/{2.js-Cq_bF6lW.js.map → 2.js-1qmqKlMg.js.map} +1 -1
- package/dist/cli/options.js +1 -1
- package/dist/lib/cli/aws.js +4 -4
- package/dist/lib/log-buffer.js +1 -1
- package/package.json +7 -6
- package/build/client/_app/immutable/assets/0.Dfts6BC4.css +0 -2
- package/build/client/_app/immutable/assets/0.Dfts6BC4.css.br +0 -0
- package/build/client/_app/immutable/assets/0.Dfts6BC4.css.gz +0 -0
- package/build/client/_app/immutable/chunks/0HQmZBP8.js.br +0 -0
- package/build/client/_app/immutable/chunks/0HQmZBP8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B5Gt-01T.js.br +0 -0
- package/build/client/_app/immutable/chunks/B5Gt-01T.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B7Wrulwc.js.br +0 -0
- package/build/client/_app/immutable/chunks/B7Wrulwc.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BDcZ4Wyi.js +0 -1
- package/build/client/_app/immutable/chunks/BDcZ4Wyi.js.br +0 -0
- package/build/client/_app/immutable/chunks/BDcZ4Wyi.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BLIhNWn-.js.br +0 -0
- package/build/client/_app/immutable/chunks/BLIhNWn-.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BMAPes50.js.br +0 -0
- package/build/client/_app/immutable/chunks/BMAPes50.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BMFtpXWH.js.br +0 -0
- package/build/client/_app/immutable/chunks/BMFtpXWH.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BNZjpNgL.js.br +0 -0
- package/build/client/_app/immutable/chunks/BNZjpNgL.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BNe95Eqc.js.br +0 -0
- package/build/client/_app/immutable/chunks/BNe95Eqc.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BPnf3PCq.js.br +0 -0
- package/build/client/_app/immutable/chunks/BPnf3PCq.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BQzvXDmX.js.br +0 -0
- package/build/client/_app/immutable/chunks/BQzvXDmX.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BS49-HdT.js.br +0 -0
- package/build/client/_app/immutable/chunks/BS49-HdT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BVyebcr0.js.br +0 -0
- package/build/client/_app/immutable/chunks/BVyebcr0.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BZ7frOsj.js.br +0 -0
- package/build/client/_app/immutable/chunks/BZ7frOsj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BjxZ_neZ.js +0 -5
- package/build/client/_app/immutable/chunks/BjxZ_neZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/BjxZ_neZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bpq3-dbO.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bpq3-dbO.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ByL_HxfT.js.br +0 -0
- package/build/client/_app/immutable/chunks/ByL_HxfT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C5DTlk-U.js.br +0 -0
- package/build/client/_app/immutable/chunks/C5DTlk-U.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CHWzTWIO.js.br +0 -0
- package/build/client/_app/immutable/chunks/CHWzTWIO.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CIRHUa7o.js.br +0 -0
- package/build/client/_app/immutable/chunks/CIRHUa7o.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CJY9dzlo.js.br +0 -0
- package/build/client/_app/immutable/chunks/CJY9dzlo.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CYBzPCyF.js +0 -1
- package/build/client/_app/immutable/chunks/CYBzPCyF.js.br +0 -0
- package/build/client/_app/immutable/chunks/CYBzPCyF.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CknPwNsn.js.br +0 -0
- package/build/client/_app/immutable/chunks/CknPwNsn.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DBvBFE2b.js.br +0 -0
- package/build/client/_app/immutable/chunks/DBvBFE2b.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DGPOPiag.js.br +0 -0
- package/build/client/_app/immutable/chunks/DGPOPiag.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DOY2FQbe.js.br +0 -0
- package/build/client/_app/immutable/chunks/DOY2FQbe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DeAq2fo8.js.br +0 -2
- package/build/client/_app/immutable/chunks/DeAq2fo8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DsjX0FWg.js.br +0 -0
- package/build/client/_app/immutable/chunks/DsjX0FWg.js.gz +0 -0
- package/build/client/_app/immutable/chunks/HbGXDNOY.js.br +0 -0
- package/build/client/_app/immutable/chunks/HbGXDNOY.js.gz +0 -0
- package/build/client/_app/immutable/chunks/MQIJFRGs.js.br +0 -0
- package/build/client/_app/immutable/chunks/MQIJFRGs.js.gz +0 -0
- package/build/client/_app/immutable/chunks/SPw4Pe1k.js.br +0 -0
- package/build/client/_app/immutable/chunks/SPw4Pe1k.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.B1Kx6Gr2.js.br +0 -0
- package/build/client/_app/immutable/entry/app.B1Kx6Gr2.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DUspS8mW.js +0 -1
- package/build/client/_app/immutable/entry/start.DUspS8mW.js.br +0 -0
- package/build/client/_app/immutable/entry/start.DUspS8mW.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.BN3NguWs.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.CjbVqPIj.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.CjbVqPIj.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.B3li1f44.js +0 -4
- package/build/client/_app/immutable/nodes/2.B3li1f44.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.B3li1f44.js.gz +0 -0
- package/build/server/chunks/chunks/archive.js-C2D-5edp.js.map +0 -1
- package/build/server/chunks/chunks/aws.js-DkPqAybc.js.map +0 -1
- package/build/server/chunks/chunks/env2.js-CcIskxOZ.js +0 -60
- package/build/server/chunks/chunks/env2.js-CcIskxOZ.js.map +0 -1
- package/build/server/chunks/chunks/log-buffer.js-BI_gQOls.js.map +0 -1
- package/build/server/chunks/chunks/regions.js-IQPMyP5C.js.map +0 -1
- package/build/server/chunks/chunks/series-buckets.js-BjigySff.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/archive/_server.ts.js-83Ch7djd.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/health/_server.ts.js-VctnBhIJ.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/identity/_server.ts.js-Dt540Sio.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/log-groups/_server.ts.js-drLgUdvB.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/regions/_server.ts.js-CBqfN6Pg.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/series/_server.ts.js-DOvBhEDU.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/stream/_server.ts.js-B9_-4ssJ.js.map +0 -1
- package/build/server/chunks/entries/pages/_layout.svelte.js-CBQpEToy.js.map +0 -1
- package/build/server/chunks/entries/pages/_page.svelte.js-NmVMu4KB.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,100 +2,111 @@
|
|
|
2
2
|
|
|
3
3
|
# watch-tail
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**CloudWatch logs. One command. A clearer picture.**
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
tab fighting the AWS console.
|
|
7
|
+
Tail live logs, investigate an incident across services, and keep what you find in a local archive.
|
|
8
|
+
Uses your existing AWS credentials. Runs on your machine.
|
|
10
9
|
|
|
11
10
|
[](https://www.npmjs.com/package/watch-tail)
|
|
12
|
-
[](https://github.com/antstanley/watch-tail/actions/workflows/ci.yml)
|
|
13
12
|
[](./LICENSE)
|
|
14
13
|
[](package.json)
|
|
15
14
|
|
|
16
|
-
<img src="
|
|
15
|
+
<img src="https://raw.githubusercontent.com/antstanley/watch-tail/v0.7.1/docs/watch-tail-overview.png" alt="watch-tail: historic logs from multiple groups, with severity chart and request grouping" width="1200">
|
|
17
16
|
|
|
18
17
|
</div>
|
|
19
18
|
|
|
19
|
+
## Start here
|
|
20
|
+
|
|
20
21
|
```bash
|
|
21
|
-
npx watch-tail
|
|
22
|
-
npx watch-tail --profile my-profile --region af-south-1
|
|
23
|
-
npx watch-tail --floci
|
|
22
|
+
npx watch-tail # use your existing AWS credentials
|
|
23
|
+
npx watch-tail --profile my-profile --region af-south-1 # choose a profile and region
|
|
24
|
+
npx watch-tail --floci # use a local emulator
|
|
24
25
|
```
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Because the two things you have today are the AWS console and `aws logs tail`, and both make you
|
|
29
|
-
work for every line.
|
|
30
|
-
|
|
31
|
-
- **The console is a form-filling exercise.** Region dropdown, log-group dropdown, sometimes a stream
|
|
32
|
-
dropdown, then a text-only event viewer that forgets where you were. `watch-tail` opens on your
|
|
33
|
-
region, lists every group with its size, and starts streaming the moment you click one.
|
|
34
|
-
- **`aws logs tail` is a wall of text.** `watch-tail` gives you pause with buffering, client-side
|
|
35
|
-
filtering, clear, auto-scroll, a 5 000-line ring buffer, and a stream-name column that is truncated
|
|
36
|
-
with the full value on hover - so a 95-character Lambda stream name cannot push your message off
|
|
37
|
-
screen.
|
|
38
|
-
- **Logs arrive as payloads, not prose.** JSON entries are pretty-printed with syntax colouring by
|
|
39
|
-
default, and one toggle shows the raw line when you need the wire format. With that toggle off,
|
|
40
|
-
**click a line that carries JSON** and just that payload opens beneath it - indented, coloured, and
|
|
41
|
-
without losing the raw line - and clicking again closes it.
|
|
42
|
-
- **"What happened an hour ago?" is the normal question.** Flip to **Historic** and scan 15 min, 1 h,
|
|
43
|
-
3 h, 12 h, 24 h, 5 days - or pick a custom `from`/`to` window. The scan finishes on its own and the
|
|
44
|
-
window lives in the URL, so `…&mode=historic&range=24h` is a shareable view of an incident.
|
|
45
|
-
- **Your credentials never move.** No keys to paste into a SaaS, no CLI to install into your CI, no
|
|
46
|
-
vendor account: it uses the ambient AWS profile you already use, needs only two read-only IAM
|
|
47
|
-
actions, and binds to loopback. Throwaway keys are used for a local emulator and only there.
|
|
48
|
-
- **It is one command and it goes away.** `npx watch-tail`, Ctrl+C. Nothing is deployed, nothing is
|
|
49
|
-
sent anywhere, and there is no agent, sidecar or daemon to clean up.
|
|
50
|
-
- **You keep what you have seen.** Logs you stream are appended to a local DuckDB file, so the incident
|
|
51
|
-
you looked at last week is still there - no re-scanning AWS, no 14-day cliff, no credentials needed
|
|
52
|
-
to read it back. Switch the source to **Local archive** in the UI and the same window controls work
|
|
53
|
-
against that file.
|
|
54
|
-
|
|
55
|
-
Use it when you are debugging a Lambda, chasing an API Gateway 5xx, watching a worker drain a queue,
|
|
56
|
-
or handing a teammate a link that shows exactly the window you are staring at.
|
|
27
|
+
Requires **Node.js 22+**. Prefer a global install? `npm install -g watch-tail` gives you both
|
|
28
|
+
`watch-tail` and the shorter `wt`. Press **Ctrl+C** to stop, including during a live stream or login prompt.
|
|
57
29
|
|
|
58
30
|
## What you get
|
|
59
31
|
|
|
60
|
-
- **
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- **
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
- **
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
32
|
+
- **Live tail and historic scans.** Follow new events or select a preset (15 minutes to 5 days) or
|
|
33
|
+
custom window. Pause with buffering, filter text, clear the view, and toggle auto-scroll.
|
|
34
|
+
- **Several groups, one view.** Select groups in the sidebar to merge their logs and chart. A group
|
|
35
|
+
column keeps each line's source visible.
|
|
36
|
+
- **Requests, not just lines.** **By request** groups matching request IDs into one expandable row,
|
|
37
|
+
showing line count, elapsed span, and highest severity. Lines without an ID stay visible.
|
|
38
|
+
- **Spot the spike.** In Historic mode, the chart shows request counts over time, coloured by severity.
|
|
39
|
+
Drag to zoom into an incident; severity chips filter both chart and logs. Switch off **By request**
|
|
40
|
+
to count individual events. Collapse the chart when you want the space back.
|
|
41
|
+
- **Readable payloads.** Syntax-coloured JSON, expandable payloads, wrapping, horizontal scrolling,
|
|
42
|
+
and resizable sidebar and stream-name columns. The viewer keeps a 5,000-line buffer.
|
|
43
|
+
- **Offline history.** Streamed events are saved to a local DuckDB archive. Browse them later without
|
|
44
|
+
AWS credentials, or query them with SQL.
|
|
45
|
+
- **Reopen the same view.** Region, groups, source, mode, and time window live in the URL. A teammate
|
|
46
|
+
needs their own AWS access or a copy of the archive; the link does not include logs or credentials.
|
|
47
|
+
|
|
48
|
+
## Follow a request
|
|
49
|
+
|
|
50
|
+
Grouping is on by default. Click a request row to expand its lines; use **By request** to return to
|
|
51
|
+
individual events. IDs are detected from `requestId`, `request_id`, `awsRequestId`, `x-request-id`,
|
|
52
|
+
and Lambda's `RequestId:` lines. Each request takes the severity of its most critical line.
|
|
53
|
+
|
|
54
|
+
<img src="https://raw.githubusercontent.com/antstanley/watch-tail/v0.7.1/docs/watch-tail-requests.png" alt="watch-tail: an expanded checkout request showing its JSON payloads and Lambda log lines" width="1200">
|
|
55
|
+
|
|
56
|
+
In **Historic**, drag across the chart to narrow the window. Click to clear the brush, or use
|
|
57
|
+
**Reset zoom** to restore the preset. CloudWatch charts reflect the events loaded into the viewer;
|
|
58
|
+
archive charts query the whole selected window.
|
|
59
|
+
|
|
60
|
+
Switch the chart from **Count** to **Duration (ms)** to see one point per request: X is its first
|
|
61
|
+
observed event timestamp; Y is `(last timestamp + last event duration) − first timestamp` in
|
|
62
|
+
milliseconds. The last event's JSON `duration` (or `durationMs`) is used when present; otherwise it
|
|
63
|
+
adds zero. Hover for the request ID and duration. Severity filters and chart zoom work in both modes.
|
|
64
|
+
Only events with request IDs contribute; incomplete windows can show partial durations.
|
|
65
|
+
|
|
66
|
+
## Keep your history
|
|
67
|
+
|
|
68
|
+
Choose **Local archive** to browse events already captured on this machine, even offline or with an
|
|
69
|
+
expired SSO session. Only events received while streaming are archived; it does not back up your
|
|
70
|
+
whole AWS account.
|
|
86
71
|
|
|
87
72
|
```bash
|
|
88
|
-
|
|
89
|
-
|
|
73
|
+
watch-tail --db ./logs.duckdb # choose an archive file
|
|
74
|
+
watch-tail --no-archive # disable archiving
|
|
90
75
|
```
|
|
91
76
|
|
|
92
|
-
|
|
77
|
+
<img src="https://raw.githubusercontent.com/antstanley/watch-tail/v0.7.1/docs/watch-tail-archive.png" alt="watch-tail: local archive replay with stored event counts and a severity chart" width="1200">
|
|
93
78
|
|
|
94
|
-
|
|
95
|
-
|
|
79
|
+
Each AWS account and region gets its own `<account-id>/<region>/archive.duckdb` beneath:
|
|
80
|
+
|
|
81
|
+
| Platform | Directory |
|
|
82
|
+
| -------- | ---------------------------------------------- |
|
|
83
|
+
| macOS | `~/Library/Application Support/watch-tail/` |
|
|
84
|
+
| Linux | `${XDG_DATA_HOME:-~/.local/share}/watch-tail/` |
|
|
85
|
+
| Windows | `%LOCALAPPDATA%\watch-tail\` |
|
|
86
|
+
|
|
87
|
+
Account IDs come from AWS STS, so two profiles for the same account share its regional archive.
|
|
88
|
+
Changing regions switches files automatically. Emulator endpoints have a separate namespace.
|
|
89
|
+
Account mappings are cached locally for offline reads; a new CloudWatch stream verifies its account
|
|
90
|
+
before archiving. If verification fails, logs still stream but are not archived.
|
|
91
|
+
|
|
92
|
+
Existing `archive.duckdb` files stay untouched. Open a legacy archive with `--db /path/to/archive.duckdb`.
|
|
93
|
+
`--db` deliberately overrides automatic account/region separation: use it to inspect an existing file
|
|
94
|
+
or manage a file yourself. For offline access on another machine, copy the regional database and
|
|
95
|
+
open it with `--db`.
|
|
96
|
+
|
|
97
|
+
DuckDB is optional: if its native driver cannot load, the viewer runs without archiving. One process
|
|
98
|
+
can own an archive file at a time; use separate `--db` paths for concurrent instances. To inspect it
|
|
99
|
+
with a DuckDB client, stop the app first:
|
|
100
|
+
|
|
101
|
+
```sql
|
|
102
|
+
SELECT log_group, level, count(*) AS events
|
|
103
|
+
FROM log_events
|
|
104
|
+
GROUP BY log_group, level
|
|
105
|
+
ORDER BY events DESC;
|
|
96
106
|
```
|
|
97
107
|
|
|
98
|
-
|
|
108
|
+
CloudWatch scans in this app are limited to the last 14 days; actual AWS retention depends on the
|
|
109
|
+
log group's settings. The local archive can retain events beyond that window.
|
|
99
110
|
|
|
100
111
|
## CLI
|
|
101
112
|
|
|
@@ -112,47 +123,30 @@ watch-tail [options]
|
|
|
112
123
|
--print Print the environment that would be used, then exit
|
|
113
124
|
--list List the AWS profiles found on disk, then exit
|
|
114
125
|
--verbose Log the server's own output
|
|
115
|
-
--db <path>
|
|
126
|
+
--db <path> Explicit archive file (default: per account and region)
|
|
116
127
|
--no-archive Do not keep a local history archive
|
|
117
128
|
-h, --help Show this help
|
|
118
129
|
-v, --version Show the version
|
|
119
130
|
```
|
|
120
131
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
stop rather than a "no"), and whether a browser is streaming from it. An open live tail never ends on its
|
|
124
|
-
own, so the app ends its own streams when it is asked to stop instead of letting them hold the shutdown
|
|
125
|
-
open.
|
|
126
|
-
|
|
127
|
-
Shell completions come from [`@bomb.sh/tab`](https://bomb.sh): flags, `--region` values from the
|
|
128
|
-
CloudWatch Logs region list, and `--profile` values from your own `~/.aws/config`. zsh, bash, fish and
|
|
129
|
-
powershell are supported.
|
|
132
|
+
Shell completions support zsh, bash, fish, and PowerShell, including your AWS profile names and
|
|
133
|
+
available regions:
|
|
130
134
|
|
|
131
135
|
```bash
|
|
132
|
-
source <(watch-tail complete zsh)
|
|
133
|
-
watch-tail complete zsh > ~/.watch-tail-completion.zsh # or install it permanently
|
|
134
|
-
echo 'source ~/.watch-tail-completion.zsh' >> ~/.zshrc
|
|
136
|
+
source <(watch-tail complete zsh)
|
|
135
137
|
```
|
|
136
138
|
|
|
137
|
-
The generated script re-invokes `watch-tail complete -- <words>`, so completions keep working after
|
|
138
|
-
you upgrade. Install the [`@bomb.sh/tab`](https://www.npmjs.com/package/@bomb.sh/tab) CLI globally if
|
|
139
|
-
you also want completions for a locally installed copy through your package manager
|
|
140
|
-
(`pnpm watch-tail <TAB>`).
|
|
141
|
-
|
|
142
|
-
`--profile` sets `AWS_PROFILE` for the server process only. Nothing is written to disk, and any local
|
|
143
|
-
emulator settings are neutralized for that run, so a stray `.env.local` cannot redirect a real AWS run.
|
|
144
|
-
|
|
145
139
|
## AWS access
|
|
146
140
|
|
|
147
|
-
|
|
148
|
-
|
|
141
|
+
Uses the AWS SDK credential chain: SSO, shared config, environment variables, or an instance role.
|
|
142
|
+
The server binds to loopback by default. No vendor account or deployed agent is needed.
|
|
149
143
|
|
|
150
144
|
```bash
|
|
151
145
|
aws sso login --profile my-profile
|
|
152
|
-
|
|
146
|
+
wt --profile my-profile
|
|
153
147
|
```
|
|
154
148
|
|
|
155
|
-
|
|
149
|
+
The app reads logs using these IAM actions:
|
|
156
150
|
|
|
157
151
|
```json
|
|
158
152
|
{
|
|
@@ -167,273 +161,40 @@ Two read-only actions are enough; the app never writes logs:
|
|
|
167
161
|
}
|
|
168
162
|
```
|
|
169
163
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
On startup the CLI asks the running app for one log group. If AWS refuses because of credentials, it
|
|
175
|
-
works out which login command fixes it - from how your profile is configured, not from guesswork -
|
|
176
|
-
and offers to run it:
|
|
177
|
-
|
|
178
|
-
```text
|
|
179
|
-
warning: AWS credentials are not usable: ... The SSO session token associated with
|
|
180
|
-
profile=my-profile was not found or is invalid.
|
|
181
|
-
? Sign in to the SSO session for my-profile. Run `aws sso login --profile my-profile` now? › yes
|
|
182
|
-
running aws sso login --profile my-profile
|
|
183
|
-
signed in - credentials work now
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
If you did not name a profile and you have more than one, it asks which one first. The answer decides
|
|
187
|
-
both the login and the profile the app runs with, so a chosen profile is applied by restarting the
|
|
188
|
-
server with it (and with that profile's own region). **A profile that already works is never sent to a
|
|
189
|
-
login prompt**: the CLI asks `sts:GetCallerIdentity` about the chosen profile first, and only offers a
|
|
190
|
-
login when that profile really has nothing usable.
|
|
191
|
-
|
|
192
|
-
```text
|
|
193
|
-
? Which AWS profile should watch-tail use? (type to search, then Enter)
|
|
194
|
-
using profile beyond-mzansi
|
|
195
|
-
restarting with profile beyond-mzansi
|
|
196
|
-
profile beyond-mzansi already works (AWSReservedSSO_AWSAdministratorAccess) - using it
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
```text
|
|
200
|
-
? Which AWS profile should watch-tail use? (type to search, then Enter)
|
|
201
|
-
using profile beyond-mzansi
|
|
202
|
-
? Sign in to the SSO session for beyond-mzansi. Run `aws sso login --profile beyond-mzansi` now? › yes
|
|
203
|
-
restarting with profile beyond-mzansi
|
|
204
|
-
signed in as beyond-mzansi - credentials work now
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
| Your profile | What it runs |
|
|
208
|
-
| -------------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
209
|
-
| `sso_session` / `sso_start_url` | `aws sso login --profile <name>` |
|
|
210
|
-
| `login_session` (console sign-in) | `aws login --profile <name>` |
|
|
211
|
-
| nothing configured yet | `aws login` (which creates the session) |
|
|
212
|
-
| static keys, or a `credential_process` | no login is offered - those are fixed with `aws configure` or where the process is defined |
|
|
213
|
-
|
|
214
|
-
The login runs with your terminal attached, so the browser flow works. `--remote` is added when there
|
|
215
|
-
is no browser (SSH, headless). Decline, or run non-interactively, and the CLI prints the exact command
|
|
216
|
-
instead and keeps the app up - log in elsewhere, then press Refresh. Emulator runs (`--endpoint`,
|
|
217
|
-
`--floci`) skip the check, because those use throwaway credentials by design.
|
|
218
|
-
|
|
219
|
-
**The region is optional.** Precedence is `--region`, then `AWS_REGION`/`AWS_DEFAULT_REGION`, then the
|
|
220
|
-
profile's own region, then `[default]` in `~/.aws/config`. Nothing resolvable produces a clear
|
|
221
|
-
`missing-region` message instead of a silent guess. Log groups, retention and events are per region,
|
|
222
|
-
so a group in `eu-west-1` will not appear under `us-east-2`.
|
|
223
|
-
|
|
224
|
-
### Local emulator
|
|
225
|
-
|
|
226
|
-
```bash
|
|
227
|
-
curl -fsSL https://floci.io/install.sh | sh
|
|
228
|
-
floci start
|
|
229
|
-
npx watch-tail --floci # throwaway credentials are supplied automatically
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
`--floci` is the only thing that points the CLI at an emulator. If an `.env.local` next to the app
|
|
233
|
-
sets `AWS_ENDPOINT_URL` - as this repository's `pnpm floci:up` writes for the dev server - the CLI
|
|
234
|
-
ignores it, says so, and runs against real AWS; your own exported variables always win over that file.
|
|
164
|
+
If credentials fail, the CLI can help you choose a profile and offer `aws sso login` or `aws login`
|
|
165
|
+
as appropriate. Working profiles are checked before offering login. In a non-interactive session it
|
|
166
|
+
prints the command to run instead.
|
|
235
167
|
|
|
236
|
-
|
|
168
|
+
Region precedence: `--region`, `AWS_REGION` / `AWS_DEFAULT_REGION`, the chosen profile, then the
|
|
169
|
+
default profile. Use `--floci` or `--endpoint` to select an emulator explicitly; emulator settings
|
|
170
|
+
from the checkout's `.env.local` do not silently redirect a normal CLI run.
|
|
237
171
|
|
|
238
|
-
|
|
239
|
-
changes: the live tail, the historic scan and the UI work exactly as before. What the archive adds is
|
|
240
|
-
a **second source** you can read later.
|
|
172
|
+
## Local development
|
|
241
173
|
|
|
242
|
-
|
|
243
|
-
available. Choosing it:
|
|
244
|
-
|
|
245
|
-
- lists the log groups the archive holds for the current region, with how many events are stored
|
|
246
|
-
locally,
|
|
247
|
-
- replays a window from the file instead of calling CloudWatch - instant, and **no credentials
|
|
248
|
-
needed**, so it works with an expired SSO session, offline, or on a machine that never had AWS
|
|
249
|
-
access,
|
|
250
|
-
- keeps the same range controls (`15m` … `5d`, or a custom `from`/`to`), and puts the source in the URL
|
|
251
|
-
so `…&source=archive&range=24h` is a shareable view of the archive.
|
|
252
|
-
|
|
253
|
-
```bash
|
|
254
|
-
watch-tail # archive on, file in your app data directory
|
|
255
|
-
watch-tail --db ./logs.duckdb # keep the archive next to the project instead
|
|
256
|
-
watch-tail --no-archive # do not archive anything
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
The default file is `archive.duckdb` inside your platform's data directory:
|
|
260
|
-
|
|
261
|
-
| Platform | Path |
|
|
262
|
-
| -------- | ------------------------------------------------------------ |
|
|
263
|
-
| macOS | `~/Library/Application Support/watch-tail/archive.duckdb` |
|
|
264
|
-
| Linux | `${XDG_DATA_HOME:-~/.local/share}/watch-tail/archive.duckdb` |
|
|
265
|
-
| Windows | `%LOCALAPPDATA%\watch-tail\archive.duckdb` |
|
|
266
|
-
|
|
267
|
-
`WATCH_STREAM_ARCHIVE=off` turns the archive off for the server, and `WATCH_STREAM_ARCHIVE_DB` sets the
|
|
268
|
-
file, for people who drive the server directly.
|
|
269
|
-
|
|
270
|
-
Because it is a DuckDB database, you can point any DuckDB client at the same file - with the app
|
|
271
|
-
stopped, since DuckDB allows one writer:
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
duckdb ~/Library/Application\ Support/watch-tail/archive.duckdb
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
```sql
|
|
278
|
-
SELECT log_group, count(*) AS events, max(timestamp_ms) AS newest
|
|
279
|
-
FROM log_events
|
|
280
|
-
GROUP BY log_group
|
|
281
|
-
ORDER BY events DESC;
|
|
282
|
-
|
|
283
|
-
SELECT to_timestamp(timestamp_ms / 1000) AS at, message
|
|
284
|
-
FROM log_events
|
|
285
|
-
WHERE log_group = '/aws/lambda/checkout' AND message ILIKE '%timeout%'
|
|
286
|
-
ORDER BY timestamp_ms;
|
|
287
|
-
|
|
288
|
-
-- how many errors per group, ignoring levels that were never detected
|
|
289
|
-
SELECT log_group, level, count(*) AS events
|
|
290
|
-
FROM log_events
|
|
291
|
-
WHERE level = 'error'
|
|
292
|
-
GROUP BY log_group, level
|
|
293
|
-
ORDER BY events DESC;
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
Three things worth knowing:
|
|
297
|
-
|
|
298
|
-
- **DuckDB is an optional dependency.** It is a native module (roughly 114 MB installed, prebuilt for
|
|
299
|
-
every supported platform - no compiler needed). If it cannot be installed or loaded, `watch-tail`
|
|
300
|
-
runs exactly as it did before, without history, and says so in the startup banner. To skip it
|
|
301
|
-
deliberately: `npm install -g watch-tail --no-optional`.
|
|
302
|
-
- **One process owns the file.** DuckDB takes an exclusive lock, so a second `watch-tail` on the same
|
|
303
|
-
archive runs without history while the first is up; `--db` is the way to keep two instances
|
|
304
|
-
separate.
|
|
305
|
-
- Levels are detected, not received: CloudWatch Logs does not report a severity, so `error`/`warn`/
|
|
306
|
-
`info`/`debug` come from the line itself, and `NULL` means nothing could be read from it.
|
|
307
|
-
- **The archive is as wide as what you watched.** Events are recorded as they stream, so history covers
|
|
308
|
-
the windows you have actually visited. It is also local, unencrypted and outside your AWS account -
|
|
309
|
-
treat the file like the logs themselves.
|
|
310
|
-
|
|
311
|
-
## Requests, not lines
|
|
312
|
-
|
|
313
|
-
Log lines that belong to the same request are one thing, not twenty. watch-tail reads a request id out
|
|
314
|
-
of each line - a declared `requestId` (also `request_id`, `awsRequestId`, an `x-request-id`) or the
|
|
315
|
-
`RequestId: ...` that a Lambda prints - and groups the lines that share it:
|
|
316
|
-
|
|
317
|
-
- **The log view** collapses each request into a single row: its request id, how many lines it wrote,
|
|
318
|
-
how long it took, and the level of its **most critical line**, so a request with one error among
|
|
319
|
-
twenty info lines reads as an error. Click the row to open it and see every line, indented, in order.
|
|
320
|
-
- **The chart** counts **one mark per request**, placed at the request's first line and coloured by
|
|
321
|
-
that same most critical level, so a spike of failing requests is a spike of marks rather than a spike
|
|
322
|
-
of log volume.
|
|
323
|
-
- **By request** in the log view's toolbar turns it off, and the view goes back to one row per line
|
|
324
|
-
(and the chart back to one mark per line). Your choice is remembered.
|
|
325
|
-
|
|
326
|
-
Grouping is on by default. Lines with no request id are never grouped: each keeps its own row and its
|
|
327
|
-
own mark, so nothing is hidden by a request id the log did not have. A request whose lines span more
|
|
328
|
-
than one bucket is counted once, where it started, which is why the chart's total can be lower than
|
|
329
|
-
the number of lines.
|
|
330
|
-
|
|
331
|
-
## The chart
|
|
332
|
-
|
|
333
|
-
In **Historic** mode (and for the local archive) a scatter chart sits above the log view: X is time, Y
|
|
334
|
-
is the number of requests in a bucket, and each level is its own colour. Drag across it to brush a
|
|
335
|
-
range - the log view, the window chip and the URL all follow, so a brush is a shareable view of the
|
|
336
|
-
spike you just found. Click the chart to clear the brush, or press **Reset zoom** to go back to the
|
|
337
|
-
preset window. The level chips filter the chart and the log view together.
|
|
338
|
-
|
|
339
|
-
A drag only counts as a zoom when it is a real drag: a click, or a pointer that slips a couple of
|
|
340
|
-
pixels, clears the brush instead of zooming into a sliver of a window, and the view is re-scoped when
|
|
341
|
-
you release rather than while you drag - so the stream is not restarted mid-gesture.
|
|
342
|
-
|
|
343
|
-
With several groups selected, the counts cover all of them and the chart's legend splits the totals by
|
|
344
|
-
level. The level chips filter requests by their most critical level, which is the level the marks are
|
|
345
|
-
drawn in, so the legend and the filter never disagree. The archive answers the chart with one SQL query over the whole window; a CloudWatch view has no
|
|
346
|
-
aggregate API, so there the chart counts the events already in the view.
|
|
347
|
-
|
|
348
|
-
The panel has a header you can click to collapse it, and it remembers that choice: collapsed, it is
|
|
349
|
-
just one line of totals and per-level counts, and the space goes back to the log view.
|
|
350
|
-
|
|
351
|
-
The chart is drawn with [layerchart](https://www.layerchart.com), which is **loaded on demand**: the
|
|
352
|
-
charting code is fetched in the browser only once the panel is open, so it never delays the log view's
|
|
353
|
-
first paint. Measured on the production build, an open panel pulls about 235 KiB of chart code after
|
|
354
|
-
the page has started, and a collapsed one pulls none at all.
|
|
355
|
-
|
|
356
|
-
## Development
|
|
174
|
+
With [floci](https://floci.io) installed:
|
|
357
175
|
|
|
358
176
|
```bash
|
|
359
177
|
pnpm install
|
|
360
|
-
pnpm
|
|
361
|
-
|
|
362
|
-
pnpm
|
|
363
|
-
pnpm dev:aws --profile my-profile # dev server against a real profile
|
|
364
|
-
pnpm build # adapter-node build + the CLI in dist/
|
|
365
|
-
pnpm start # run the built CLI
|
|
178
|
+
pnpm floci:up # start the emulator and write its dev environment
|
|
179
|
+
pnpm seed # demo logs; use pnpm seed:watch for live traffic
|
|
180
|
+
pnpm dev # http://localhost:5173
|
|
366
181
|
```
|
|
367
182
|
|
|
368
|
-
|
|
369
|
-
| --------------------------- | ----------------------------------------------------------- |
|
|
370
|
-
| `pnpm check` | `svelte-check` types |
|
|
371
|
-
| `pnpm test:unit` | vitest unit, component and integration projects |
|
|
372
|
-
| `pnpm test:e2e` | floci integration suite (`WATCH_STREAM_E2E=1`) |
|
|
373
|
-
| `pnpm test:cli` | the built CLI serves and stops cleanly (`WATCH_TAIL_E2E=1`) |
|
|
374
|
-
| `pnpm test:ui` | Playwright smoke check of the UI against a running app |
|
|
375
|
-
| `pnpm lint` / `pnpm format` | oxlint / oxfmt |
|
|
376
|
-
| `pnpm knip` | unused files, exports and dependencies |
|
|
377
|
-
| `pnpm verify` | all of the above plus the build |
|
|
378
|
-
| `pnpm publish:check` | publint plus the exact tarball contents |
|
|
379
|
-
|
|
380
|
-
## Releasing
|
|
381
|
-
|
|
382
|
-
Releases use [changesets](https://github.com/changesets/changesets): a changeset is a small file
|
|
383
|
-
that records _what changed and how much it matters_, reviewed with the code. Pending changesets are
|
|
384
|
-
folded into one "Release: version packages" PR; merging it bumps the version and writes
|
|
385
|
-
`CHANGELOG.md`; the release workflow then stages that version to npm and tags the commit.
|
|
183
|
+
Use `pnpm dev:aws --profile my-profile` to develop against AWS instead.
|
|
386
184
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
pnpm
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
one-time setup and the approval flow.
|
|
396
|
-
|
|
397
|
-
## Architecture
|
|
398
|
-
|
|
399
|
-
```
|
|
400
|
-
Browser (SvelteKit client)
|
|
401
|
-
| GET /api/log-groups group list for a region
|
|
402
|
-
| GET /api/stream SSE: ready, log, ping, error, end
|
|
403
|
-
v
|
|
404
|
-
SvelteKit server routes (Node)
|
|
405
|
-
| @aws-sdk/client-cloudwatch-logs DescribeLogGroups + FilterLogEvents polling
|
|
406
|
-
v
|
|
407
|
-
CloudWatch Logs API -- ambient AWS credentials
|
|
408
|
-
or floci on http://localhost:4566
|
|
409
|
-
|
|
410
|
-
Everything streamed is also appended to a local archive,
|
|
411
|
-
which the UI can read back without AWS:
|
|
412
|
-
|
|
413
|
-
SvelteKit server ---- @duckdb/node-api ----> archive.duckdb (DuckDB file)
|
|
414
|
-
^
|
|
415
|
-
Browser -- GET /api/stream?source=archive -+
|
|
416
|
-
```
|
|
185
|
+
| Command | Purpose |
|
|
186
|
+
| --------------------------- | ------------------------------------------------------------- |
|
|
187
|
+
| `pnpm verify` | Types, lint, formatting, tests, unused-code checks, and build |
|
|
188
|
+
| `pnpm test:e2e` | Emulator integration tests (requires floci) |
|
|
189
|
+
| `pnpm test:cli` | Built CLI startup and shutdown checks |
|
|
190
|
+
| `pnpm test:ui` | Browser smoke checks against the running app |
|
|
191
|
+
| `pnpm build` / `pnpm start` | Build and run the production CLI |
|
|
192
|
+
| `pnpm publish:check` | Validate package metadata and tarball contents |
|
|
417
193
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
## Notes and limits
|
|
422
|
-
|
|
423
|
-
- CloudWatch Logs has no push API for reading, so the app polls `FilterLogEvents` (1 s by default,
|
|
424
|
-
250 ms - 15 s configurable). Expect roughly a second of latency and one API call per second per open
|
|
425
|
-
stream.
|
|
426
|
-
- `FilterLogEvents` only returns events from the last 14 days.
|
|
427
|
-
- The local server has no authentication: it binds to loopback and inherits your AWS permissions.
|
|
428
|
-
Binding elsewhere prints a warning - only do it on a trusted network.
|
|
429
|
-
- floci omits `logStreamName` in `FilterLogEvents`, so the stream column stays empty locally; real AWS
|
|
430
|
-
fills it.
|
|
431
|
-
- The archive is written from the same process that serves the UI, so it only grows while something is
|
|
432
|
-
streaming. A window you never opened is not in it, and events dropped by the 10 000-event cap of a
|
|
433
|
-
historic scan are not archived either.
|
|
434
|
-
- Archived events are de-duplicated by CloudWatch event id (or by a hash of timestamp, stream and
|
|
435
|
-
message when an emulator omits ids), so re-scanning the same window does not duplicate rows.
|
|
194
|
+
See [ARCHITECTURE.md](./ARCHITECTURE.md) for internals,
|
|
195
|
+
[CHANGELOG.md](./CHANGELOG.md) for release history, and [RELEASING.md](./RELEASING.md) for the
|
|
196
|
+
Changesets and npm staged-publishing workflow.
|
|
436
197
|
|
|
437
198
|
## License
|
|
438
199
|
|
|
439
|
-
MIT
|
|
200
|
+
[MIT](./LICENSE)
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-amber-950:oklch(27.9% .077 45.635);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-900:oklch(37.8% .077 168.94);--color-emerald-950:oklch(26.2% .051 172.552);--color-teal-300:oklch(85.5% .138 181.071);--color-teal-400:oklch(77.7% .152 181.912);--color-teal-700:oklch(51.1% .096 186.391);--color-teal-900:oklch(38.6% .063 188.416);--color-teal-950:oklch(27.7% .046 192.524);--color-sky-200:oklch(90.1% .058 230.902);--color-sky-300:oklch(82.8% .111 230.318);--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-sky-600:oklch(58.8% .158 241.966);--color-sky-700:oklch(50% .134 242.749);--color-sky-800:oklch(44.3% .11 240.79);--color-sky-900:oklch(39.1% .09 240.876);--color-sky-950:oklch(29.3% .066 243.157);--color-violet-300:oklch(81.1% .111 293.571);--color-violet-900:oklch(38% .189 293.745);--color-violet-950:oklch(28.3% .141 291.089);--color-fuchsia-300:oklch(83.3% .145 321.434);--color-neutral-100:oklch(97% 0 none);--color-neutral-200:oklch(92.2% 0 none);--color-neutral-300:oklch(87% 0 none);--color-neutral-400:oklch(70.8% 0 none);--color-neutral-500:oklch(55.6% 0 none);--color-neutral-600:oklch(43.9% 0 none);--color-neutral-700:oklch(37.1% 0 none);--color-neutral-800:oklch(26.9% 0 none);--color-neutral-900:oklch(20.5% 0 none);--color-neutral-950:oklch(14.5% 0 none);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-wider:.05em;--radius-md:.375rem;--radius-lg:.5rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-y-0{inset-block:0}.isolate{isolation:isolate}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.ml-1{margin-left:var(--spacing)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.h-2{height:calc(var(--spacing) * 2)}.h-5{height:calc(var(--spacing) * 5)}.h-dvh{height:100dvh}.min-h-0{min-height:0}.min-h-\[30rem\]{min-height:30rem}.min-h-full{min-height:100%}.w-2{width:calc(var(--spacing) * 2)}.w-40{width:calc(var(--spacing) * 40)}.w-\[7\.5rem\]{width:7.5rem}.w-\[9rem\]{width:9rem}.w-full{width:100%}.w-max{width:max-content}.max-w-\[22rem\]{max-width:22rem}.min-w-0{min-width:0}.min-w-full{min-width:100%}.flex-1{flex:1}.flex-none{flex:none}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.animate-pulse{animation:var(--animate-pulse)}.cursor-col-resize{cursor:col-resize}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-1{row-gap:var(--spacing)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-amber-700{border-color:var(--color-amber-700)}.border-amber-800{border-color:var(--color-amber-800)}.border-amber-900{border-color:var(--color-amber-900)}.border-emerald-900{border-color:var(--color-emerald-900)}.border-neutral-700{border-color:var(--color-neutral-700)}.border-neutral-800{border-color:var(--color-neutral-800)}.border-neutral-900{border-color:var(--color-neutral-900)}.border-red-800{border-color:var(--color-red-800)}.border-red-900{border-color:var(--color-red-900)}.border-sky-700{border-color:var(--color-sky-700)}.border-sky-800{border-color:var(--color-sky-800)}.border-sky-900{border-color:var(--color-sky-900)}.border-teal-700{border-color:var(--color-teal-700)}.border-teal-900{border-color:var(--color-teal-900)}.border-transparent{border-color:#0000}.border-violet-900{border-color:var(--color-violet-900)}.bg-amber-400{background-color:var(--color-amber-400)}.bg-amber-950\/40{background-color:#46190166}@supports (color:color-mix(in lab, red, red)){.bg-amber-950\/40{background-color:color-mix(in oklab, var(--color-amber-950) 40%, transparent)}}.bg-amber-950\/50{background-color:#46190180}@supports (color:color-mix(in lab, red, red)){.bg-amber-950\/50{background-color:color-mix(in oklab, var(--color-amber-950) 50%, transparent)}}.bg-amber-950\/70{background-color:#461901b3}@supports (color:color-mix(in lab, red, red)){.bg-amber-950\/70{background-color:color-mix(in oklab, var(--color-amber-950) 70%, transparent)}}.bg-emerald-400{background-color:var(--color-emerald-400)}.bg-emerald-950\/70{background-color:#002c22b3}@supports (color:color-mix(in lab, red, red)){.bg-emerald-950\/70{background-color:color-mix(in oklab, var(--color-emerald-950) 70%, transparent)}}.bg-neutral-500{background-color:var(--color-neutral-500)}.bg-neutral-800{background-color:var(--color-neutral-800)}.bg-neutral-800\/60{background-color:#26262699}@supports (color:color-mix(in lab, red, red)){.bg-neutral-800\/60{background-color:color-mix(in oklab, var(--color-neutral-800) 60%, transparent)}}.bg-neutral-800\/80{background-color:#262626cc}@supports (color:color-mix(in lab, red, red)){.bg-neutral-800\/80{background-color:color-mix(in oklab, var(--color-neutral-800) 80%, transparent)}}.bg-neutral-900{background-color:var(--color-neutral-900)}.bg-neutral-900\/40{background-color:#17171766}@supports (color:color-mix(in lab, red, red)){.bg-neutral-900\/40{background-color:color-mix(in oklab, var(--color-neutral-900) 40%, transparent)}}.bg-neutral-900\/60{background-color:#17171799}@supports (color:color-mix(in lab, red, red)){.bg-neutral-900\/60{background-color:color-mix(in oklab, var(--color-neutral-900) 60%, transparent)}}.bg-neutral-900\/70{background-color:#171717b3}@supports (color:color-mix(in lab, red, red)){.bg-neutral-900\/70{background-color:color-mix(in oklab, var(--color-neutral-900) 70%, transparent)}}.bg-neutral-950{background-color:var(--color-neutral-950)}.bg-neutral-950\/60{background-color:#0a0a0a99}@supports (color:color-mix(in lab, red, red)){.bg-neutral-950\/60{background-color:color-mix(in oklab, var(--color-neutral-950) 60%, transparent)}}.bg-neutral-950\/90{background-color:#0a0a0ae6}@supports (color:color-mix(in lab, red, red)){.bg-neutral-950\/90{background-color:color-mix(in oklab, var(--color-neutral-950) 90%, transparent)}}.bg-red-400{background-color:var(--color-red-400)}.bg-red-950\/50{background-color:#46080980}@supports (color:color-mix(in lab, red, red)){.bg-red-950\/50{background-color:color-mix(in oklab, var(--color-red-950) 50%, transparent)}}.bg-red-950\/70{background-color:#460809b3}@supports (color:color-mix(in lab, red, red)){.bg-red-950\/70{background-color:color-mix(in oklab, var(--color-red-950) 70%, transparent)}}.bg-sky-400{background-color:var(--color-sky-400)}.bg-sky-950{background-color:var(--color-sky-950)}.bg-sky-950\/50{background-color:#052f4a80}@supports (color:color-mix(in lab, red, red)){.bg-sky-950\/50{background-color:color-mix(in oklab, var(--color-sky-950) 50%, transparent)}}.bg-sky-950\/60{background-color:#052f4a99}@supports (color:color-mix(in lab, red, red)){.bg-sky-950\/60{background-color:color-mix(in oklab, var(--color-sky-950) 60%, transparent)}}.bg-sky-950\/70{background-color:#052f4ab3}@supports (color:color-mix(in lab, red, red)){.bg-sky-950\/70{background-color:color-mix(in oklab, var(--color-sky-950) 70%, transparent)}}.bg-teal-950\/50{background-color:#022f2e80}@supports (color:color-mix(in lab, red, red)){.bg-teal-950\/50{background-color:color-mix(in oklab, var(--color-teal-950) 50%, transparent)}}.bg-teal-950\/60{background-color:#022f2e99}@supports (color:color-mix(in lab, red, red)){.bg-teal-950\/60{background-color:color-mix(in oklab, var(--color-teal-950) 60%, transparent)}}.bg-transparent{background-color:#0000}.bg-violet-950\/60{background-color:#2f0d6899}@supports (color:color-mix(in lab, red, red)){.bg-violet-950\/60{background-color:color-mix(in oklab, var(--color-violet-950) 60%, transparent)}}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.pr-1{padding-right:var(--spacing)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.625rem\]{font-size:.625rem}.text-\[0\.6875rem\]{font-size:.6875rem}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-200{color:var(--color-amber-200)}.text-amber-300{color:var(--color-amber-300)}.text-amber-300\/80{color:#ffd236cc}@supports (color:color-mix(in lab, red, red)){.text-amber-300\/80{color:color-mix(in oklab, var(--color-amber-300) 80%, transparent)}}.text-amber-400\/80{color:#fcbb00cc}@supports (color:color-mix(in lab, red, red)){.text-amber-400\/80{color:color-mix(in oklab, var(--color-amber-400) 80%, transparent)}}.text-emerald-300{color:var(--color-emerald-300)}.text-emerald-400\/80{color:#00d294cc}@supports (color:color-mix(in lab, red, red)){.text-emerald-400\/80{color:color-mix(in oklab, var(--color-emerald-400) 80%, transparent)}}.text-fuchsia-300{color:var(--color-fuchsia-300)}.text-neutral-100{color:var(--color-neutral-100)}.text-neutral-200{color:var(--color-neutral-200)}.text-neutral-300{color:var(--color-neutral-300)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-neutral-600{color:var(--color-neutral-600)}.text-red-300{color:var(--color-red-300)}.text-red-400{color:var(--color-red-400)}.text-sky-200{color:var(--color-sky-200)}.text-sky-300{color:var(--color-sky-300)}.text-sky-400{color:var(--color-sky-400)}.text-sky-400\/80{color:#00bcfecc}@supports (color:color-mix(in lab, red, red)){.text-sky-400\/80{color:color-mix(in oklab, var(--color-sky-400) 80%, transparent)}}.text-teal-300{color:var(--color-teal-300)}.text-teal-300\/80{color:#46ecd5cc}@supports (color:color-mix(in lab, red, red)){.text-teal-300\/80{color:color-mix(in oklab, var(--color-teal-300) 80%, transparent)}}.text-teal-400\/80{color:#00d3bdcc}@supports (color:color-mix(in lab, red, red)){.text-teal-400\/80{color:color-mix(in oklab, var(--color-teal-400) 80%, transparent)}}.text-violet-300{color:var(--color-violet-300)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.accent-sky-500{accent-color:var(--color-sky-500)}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.selection\:bg-sky-900\/60 ::selection{background-color:#024a7099}@supports (color:color-mix(in lab, red, red)){.selection\:bg-sky-900\/60 ::selection{background-color:color-mix(in oklab, var(--color-sky-900) 60%, transparent)}}.selection\:bg-sky-900\/60::selection{background-color:#024a7099}@supports (color:color-mix(in lab, red, red)){.selection\:bg-sky-900\/60::selection{background-color:color-mix(in oklab, var(--color-sky-900) 60%, transparent)}}.placeholder\:text-neutral-600::placeholder{color:var(--color-neutral-600)}@media (hover:hover){.hover\:border-neutral-700:hover{border-color:var(--color-neutral-700)}.hover\:border-neutral-800:hover{border-color:var(--color-neutral-800)}.hover\:border-sky-600:hover{border-color:var(--color-sky-600)}.hover\:bg-neutral-900\/60:hover{background-color:#17171799}@supports (color:color-mix(in lab, red, red)){.hover\:bg-neutral-900\/60:hover{background-color:color-mix(in oklab, var(--color-neutral-900) 60%, transparent)}}.hover\:bg-sky-500\/30:hover{background-color:#00a5ef4d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-sky-500\/30:hover{background-color:color-mix(in oklab, var(--color-sky-500) 30%, transparent)}}.hover\:text-neutral-100:hover{color:var(--color-neutral-100)}.hover\:text-neutral-200:hover{color:var(--color-neutral-200)}}.focus\:border-sky-600:focus{border-color:var(--color-sky-600)}.focus\:bg-sky-500\/50:focus{background-color:#00a5ef80}@supports (color:color-mix(in lab, red, red)){.focus\:bg-sky-500\/50:focus{background-color:color-mix(in oklab, var(--color-sky-500) 50%, transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=40rem){.sm\:inline{display:inline}.sm\:px-4{padding-inline:calc(var(--spacing) * 4)}}@media (width>=64rem){.lg\:block{display:block}.lg\:w-2{width:calc(var(--spacing) * 2)}.lg\:shrink-0{flex-shrink:0}.lg\:flex-row{flex-direction:row}}@media (width>=80rem){.xl\:inline{display:inline}}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}
|
|
Binary file
|
|
Binary file
|