@reddoorla/maintenance 0.95.1 → 0.97.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/README.md +41 -7
- package/dist/{announce-CLQYX5I4.js → announce-5ZD2SBGD.js} +39 -31
- package/dist/announce-5ZD2SBGD.js.map +1 -0
- package/dist/attachments-JFGFQRXQ.js +10 -0
- package/dist/{blux-4KNXUP2K.js → blux-NXQLMS4W.js} +1 -1
- package/dist/{bump-deps-C5G2EFBB.js → bump-deps-775VLDYB.js} +6 -6
- package/dist/{chunk-FUWFLAWQ.js → chunk-3RLDX3Q2.js} +5 -5
- package/dist/{chunk-XHHMM5HX.js → chunk-43SW3FGW.js} +63 -1
- package/dist/chunk-43SW3FGW.js.map +1 -0
- package/dist/{chunk-R53VL3RI.js → chunk-5CJVUPJU.js} +1 -1
- package/dist/{chunk-R53VL3RI.js.map → chunk-5CJVUPJU.js.map} +1 -1
- package/dist/{chunk-S7RYFUIK.js → chunk-6PGXKN6F.js} +2 -2
- package/dist/{chunk-HTABUCF4.js → chunk-6THEZQLA.js} +3 -3
- package/dist/chunk-A5QKNOXW.js +72 -0
- package/dist/chunk-A5QKNOXW.js.map +1 -0
- package/dist/chunk-ASLDCWBF.js +41 -0
- package/dist/chunk-ASLDCWBF.js.map +1 -0
- package/dist/{chunk-CWXTNPNZ.js → chunk-AYDQQBNG.js} +3 -3
- package/dist/chunk-AYDQQBNG.js.map +1 -0
- package/dist/{chunk-WVNDEYXL.js → chunk-BINFZQ2T.js} +57 -6
- package/dist/chunk-BINFZQ2T.js.map +1 -0
- package/dist/{chunk-2NQUCS7O.js → chunk-BIYQN7FH.js} +3 -1
- package/dist/{chunk-2NQUCS7O.js.map → chunk-BIYQN7FH.js.map} +1 -1
- package/dist/{chunk-YLYXW5PH.js → chunk-CXICCLNM.js} +34 -4
- package/dist/chunk-CXICCLNM.js.map +1 -0
- package/dist/{chunk-BYGPUUCT.js → chunk-DRNZVORX.js} +66 -30
- package/dist/chunk-DRNZVORX.js.map +1 -0
- package/dist/{chunk-LM2NHRCJ.js → chunk-DYTYPKFN.js} +4 -4
- package/dist/chunk-DYTYPKFN.js.map +1 -0
- package/dist/{chunk-DFKBTBO3.js → chunk-EN6CTBUN.js} +35 -6
- package/dist/chunk-EN6CTBUN.js.map +1 -0
- package/dist/{chunk-5EEMTJMT.js → chunk-FHFXJ3EM.js} +8 -6
- package/dist/chunk-FHFXJ3EM.js.map +1 -0
- package/dist/{chunk-Z2K4JPQ3.js → chunk-FP6HOW6J.js} +10 -7
- package/dist/chunk-FP6HOW6J.js.map +1 -0
- package/dist/{chunk-2LYOAB2E.js → chunk-HSMN35LU.js} +2 -2
- package/dist/chunk-ICSRWW5Q.js +148 -0
- package/dist/chunk-ICSRWW5Q.js.map +1 -0
- package/dist/{chunk-FSGICFXB.js → chunk-IDBPII6G.js} +17 -5
- package/dist/chunk-IDBPII6G.js.map +1 -0
- package/dist/{chunk-C3IQQKXL.js → chunk-IOTOOTII.js} +121 -1
- package/dist/{chunk-C3IQQKXL.js.map → chunk-IOTOOTII.js.map} +1 -1
- package/dist/{chunk-BCKEP5S6.js → chunk-JHJNNJLG.js} +2 -2
- package/dist/{chunk-TO7DJYLZ.js → chunk-L3S3QZXL.js} +178 -39
- package/dist/chunk-L3S3QZXL.js.map +1 -0
- package/dist/{chunk-WSJ7RO54.js → chunk-LAG6IP7Y.js} +23 -5
- package/dist/chunk-LAG6IP7Y.js.map +1 -0
- package/dist/{chunk-WJMPCVOR.js → chunk-LAJ3FF54.js} +12 -4
- package/dist/chunk-LAJ3FF54.js.map +1 -0
- package/dist/{chunk-2ZAZ7ETT.js → chunk-LDHRIQUW.js} +32 -18
- package/dist/chunk-LDHRIQUW.js.map +1 -0
- package/dist/{chunk-6R56OKJZ.js → chunk-LF2TJN4X.js} +2 -2
- package/dist/chunk-LF2TJN4X.js.map +1 -0
- package/dist/{chunk-ZQV7UQNE.js → chunk-LUF52EIY.js} +2 -2
- package/dist/{chunk-5UINJNAJ.js → chunk-LZMAG73U.js} +34 -21
- package/dist/chunk-LZMAG73U.js.map +1 -0
- package/dist/{chunk-VSGMCCGQ.js → chunk-MMSMZC7S.js} +2 -2
- package/dist/chunk-MVKNU4QD.js +37 -0
- package/dist/chunk-MVKNU4QD.js.map +1 -0
- package/dist/{chunk-XPJQXSC4.js → chunk-P7323YVW.js} +27 -5
- package/dist/chunk-P7323YVW.js.map +1 -0
- package/dist/{chunk-KJRVMMM3.js → chunk-PARKXDXI.js} +36 -5
- package/dist/chunk-PARKXDXI.js.map +1 -0
- package/dist/{chunk-4763KQ6O.js → chunk-PXRN2MER.js} +2 -2
- package/dist/{chunk-WMBLR5VA.js → chunk-PZZ6HM5T.js} +3 -3
- package/dist/{chunk-TR3HFH6J.js → chunk-QFSL2L2B.js} +67 -10
- package/dist/chunk-QFSL2L2B.js.map +1 -0
- package/dist/chunk-RQJFGK3A.js +51 -0
- package/dist/chunk-RQJFGK3A.js.map +1 -0
- package/dist/{chunk-3Z6X3BHU.js → chunk-TC4GANMX.js} +53 -150
- package/dist/chunk-TC4GANMX.js.map +1 -0
- package/dist/{chunk-F3JWOPTG.js → chunk-TEMQPSCM.js} +45 -105
- package/dist/chunk-TEMQPSCM.js.map +1 -0
- package/dist/chunk-TJLKWQOX.js +52 -0
- package/dist/chunk-TJLKWQOX.js.map +1 -0
- package/dist/{chunk-CJ2RMTT7.js → chunk-TV76A6GN.js} +2 -2
- package/dist/{chunk-KZRR4NFG.js → chunk-TVZ6QCOE.js} +3 -3
- package/dist/{chunk-BVEDKMNG.js → chunk-U2ZI6G7H.js} +29 -11
- package/dist/chunk-U2ZI6G7H.js.map +1 -0
- package/dist/chunk-UPE6D4AT.js +69 -0
- package/dist/chunk-UPE6D4AT.js.map +1 -0
- package/dist/{chunk-R5IMFAFR.js → chunk-VMGHQUTV.js} +7 -16
- package/dist/chunk-VMGHQUTV.js.map +1 -0
- package/dist/chunk-VQMAAQ5M.js +53 -0
- package/dist/chunk-VQMAAQ5M.js.map +1 -0
- package/dist/{chunk-AVEQUR44.js → chunk-WMF5S2MB.js} +60 -17
- package/dist/chunk-WMF5S2MB.js.map +1 -0
- package/dist/{chunk-SVAAONYB.js → chunk-WQLNUEZL.js} +12 -2
- package/dist/{chunk-SVAAONYB.js.map → chunk-WQLNUEZL.js.map} +1 -1
- package/dist/{chunk-XN37VTDB.js → chunk-X56LAKPR.js} +3 -3
- package/dist/chunk-X56LAKPR.js.map +1 -0
- package/dist/{chunk-ZCL7C5LH.js → chunk-Y6FCXRIC.js} +1661 -387
- package/dist/chunk-Y6FCXRIC.js.map +1 -0
- package/dist/{chunk-2SLED3NB.js → chunk-YDZ7XGPZ.js} +1 -1
- package/dist/{chunk-2SLED3NB.js.map → chunk-YDZ7XGPZ.js.map} +1 -1
- package/dist/{chunk-IY6256GK.js → chunk-YJBSB4LP.js} +6 -1
- package/dist/chunk-YJBSB4LP.js.map +1 -0
- package/dist/{chunk-BI2VI6EM.js → chunk-YXWBM26P.js} +2 -2
- package/dist/{chunk-QF6IQQFP.js → chunk-Z7FDJ35L.js} +18 -12
- package/dist/chunk-Z7FDJ35L.js.map +1 -0
- package/dist/cli/bin.js +111 -51
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/commands/audit.d.ts +33 -3
- package/dist/cli/commands/audit.js +28 -25
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/client-DGTO65WB.js +11 -0
- package/dist/configs/playwright-a11y.d.ts +11 -1
- package/dist/configs/playwright-a11y.js +3 -1
- package/dist/{convert-to-pnpm-YTFREUJK.js → convert-to-pnpm-KLWA53N5.js} +6 -6
- package/dist/{db-XKZYDCKM.js → db-II5WAK4D.js} +45 -20
- package/dist/db-II5WAK4D.js.map +1 -0
- package/dist/deadletter-G4M3HSVM.js +17 -0
- package/dist/{digest-7UBGUBRK.js → digest-CWKK2DMR.js} +56 -32
- package/dist/digest-CWKK2DMR.js.map +1 -0
- package/dist/{digest-collectors-DJFN5ZDK.js → digest-collectors-CYTN2EUX.js} +17 -12
- package/dist/{digest-state-3KHZF7GD.js → digest-state-ZDPKR7MW.js} +18 -2
- package/dist/digest-state-ZDPKR7MW.js.map +1 -0
- package/dist/ensure-site-2QZHFVQ3.js +70 -0
- package/dist/ensure-site-2QZHFVQ3.js.map +1 -0
- package/dist/ensure-site-JEKV2ODE.js +105 -0
- package/dist/ensure-site-JEKV2ODE.js.map +1 -0
- package/dist/{ensure-site-OAAE5YE2.js → ensure-site-OO4UPWNQ.js} +49 -44
- package/dist/ensure-site-OO4UPWNQ.js.map +1 -0
- package/dist/fleet-events-CkOZpMVC.d.ts +435 -0
- package/dist/{fleet-state-UEVZ3X3J.js → fleet-state-RJROYXKO.js} +19 -7
- package/dist/{forms-notify-target-UC6PF3AE.js → forms-notify-target-X6UEOI2M.js} +19 -15
- package/dist/forms-notify-target-X6UEOI2M.js.map +1 -0
- package/dist/{freeze-A6MUCZU4.js → freeze-GUQ43EAU.js} +2 -2
- package/dist/{github-signals-TX5FPYP6.js → github-signals-QIRTHHET.js} +22 -17
- package/dist/github-signals-QIRTHHET.js.map +1 -0
- package/dist/{header-image-PSPT7CUM.js → header-image-H7ZJAV26.js} +15 -18
- package/dist/header-image-H7ZJAV26.js.map +1 -0
- package/dist/{health-endpoint-KVCJYWET.js → health-endpoint-BJ6BKRHF.js} +8 -7
- package/dist/{health-endpoint-KVCJYWET.js.map → health-endpoint-BJ6BKRHF.js.map} +1 -1
- package/dist/{health-mirror-XJAKA3EY.js → health-mirror-KU3G7V2Y.js} +10 -10
- package/dist/{import-airtable-TAKSN4NV.js → import-airtable-UBF5GYAL.js} +3 -3
- package/dist/index.d.ts +158 -419
- package/dist/index.js +91 -46
- package/dist/index.js.map +1 -1
- package/dist/{init-FFE4FCO2.js → init-GOWDA5QS.js} +19 -18
- package/dist/{init-FFE4FCO2.js.map → init-GOWDA5QS.js.map} +1 -1
- package/dist/{launch-UD36AHUN.js → launch-7N3X2MXB.js} +229 -79
- package/dist/launch-7N3X2MXB.js.map +1 -0
- package/dist/{lighthouse-VHI77PFB.js → lighthouse-52WSPZ5D.js} +2 -2
- package/dist/lighthouse-airtable-M45OPVRV.js +14 -0
- package/dist/match-harness-GBCDSVPS.js +417 -0
- package/dist/match-harness-GBCDSVPS.js.map +1 -0
- package/dist/migrate-XZ7U5DFC.js +7 -0
- package/dist/{notify-IISTHNBR.js → notify-K3WVH3DM.js} +4 -4
- package/dist/{onboard-TM2KESGF.js → onboard-JQQIMQW7.js} +6 -6
- package/dist/{orchestrate-HYVQPRCE.js → orchestrate-L2A5BZFY.js} +13 -10
- package/dist/parity-2JGVUCZD.js +14 -0
- package/dist/{pipeline-YROAY6DT.js → pipeline-UUPXOS2J.js} +3 -3
- package/dist/{preflight-RYIP54NY.js → preflight-O7Q6FWHU.js} +35 -11
- package/dist/preflight-O7Q6FWHU.js.map +1 -0
- package/dist/{prismic-ci-6GKKZGB5.js → prismic-ci-NAPWOXXD.js} +39 -9
- package/dist/prismic-ci-NAPWOXXD.js.map +1 -0
- package/dist/{prismic-models-P6FWWVRS.js → prismic-models-LL6ORTQ2.js} +20 -17
- package/dist/prismic-models-LL6ORTQ2.js.map +1 -0
- package/dist/prospect/types.d.ts +72 -0
- package/dist/prospect/types.js +1 -1
- package/dist/{prospect-audit-PRHU53HS.js → prospect-audit-FMPGQIRQ.js} +16 -7
- package/dist/prospect-audit-FMPGQIRQ.js.map +1 -0
- package/dist/{prospect-audits-R3LWF6U7.js → prospect-audits-IZVQY3OQ.js} +4 -2
- package/dist/protection-audit-YXJKFU6O.js +413 -0
- package/dist/protection-audit-YXJKFU6O.js.map +1 -0
- package/dist/recipes/sync-configs.js +3 -3
- package/dist/{render-YGNGTX3W.js → render-MHUUHPLN.js} +36 -9
- package/dist/render-MHUUHPLN.js.map +1 -0
- package/dist/{render-from-row-IFSBHWDH.js → render-from-row-75JTED2Z.js} +6 -4
- package/dist/{renovate-dispatch-U5Q52SKT.js → renovate-dispatch-2IHAZDVA.js} +14 -9
- package/dist/{renovate-dispatch-U5Q52SKT.js.map → renovate-dispatch-2IHAZDVA.js.map} +1 -1
- package/dist/{replay-PCSQOGCZ.js → replay-4FVFOMHH.js} +10 -23
- package/dist/replay-4FVFOMHH.js.map +1 -0
- package/dist/{report-LQS4ECTM.js → report-IAHXN5CW.js} +103 -57
- package/dist/report-IAHXN5CW.js.map +1 -0
- package/dist/{report-mirror-HDTOJE64.js → report-mirror-4QM57LMS.js} +34 -12
- package/dist/report-mirror-4QM57LMS.js.map +1 -0
- package/dist/roster-GDNSIRAK.js +19 -0
- package/dist/roster-GDNSIRAK.js.map +1 -0
- package/dist/{schema-A4WCPIF4.js → schema-KWUQEZ5O.js} +1 -1
- package/dist/schema-KWUQEZ5O.js.map +1 -0
- package/dist/{self-updating-MWXIZLL7.js → self-updating-ZUWPGYUP.js} +8 -7
- package/dist/{self-updating-MWXIZLL7.js.map → self-updating-ZUWPGYUP.js.map} +1 -1
- package/dist/{selftest-VXTHRPRN.js → selftest-G4W3LIBQ.js} +21 -17
- package/dist/{selftest-VXTHRPRN.js.map → selftest-G4W3LIBQ.js.map} +1 -1
- package/dist/site-create-ZU3ACBTO.js +45 -0
- package/dist/site-create-ZU3ACBTO.js.map +1 -0
- package/dist/site-lookup-DTOLJ4EA.js +27 -0
- package/dist/site-lookup-DTOLJ4EA.js.map +1 -0
- package/dist/{site-mirror-WON4FTJ2.js → site-mirror-WR7ACXOV.js} +26 -12
- package/dist/site-mirror-WR7ACXOV.js.map +1 -0
- package/dist/{smoke-suite-7DGITCTZ.js → smoke-suite-WAUPI6EJ.js} +8 -7
- package/dist/{smoke-suite-7DGITCTZ.js.map → smoke-suite-WAUPI6EJ.js.map} +1 -1
- package/dist/{submissions-OVZPVBYG.js → submissions-2SHCFOKD.js} +12 -7
- package/dist/submissions-2SHCFOKD.js.map +1 -0
- package/dist/{submissions-3I3GAQAX.js → submissions-JDZP35JM.js} +49 -9
- package/dist/submissions-JDZP35JM.js.map +1 -0
- package/dist/{svelte-codemods-WSV2FGNG.js → svelte-codemods-VOLOKKFI.js} +6 -6
- package/dist/{sync-K3PKHVLH.js → sync-F4USL4K5.js} +6 -6
- package/dist/{sync-configs-RRIHNLIJ.js → sync-configs-OXSWKVZ2.js} +6 -6
- package/dist/turso-KQKBBQCK.js +24 -0
- package/dist/turso-KQKBBQCK.js.map +1 -0
- package/dist/{upgrade-VTD6V4HS.js → upgrade-EVAL3JTO.js} +6 -6
- package/dist/util/git.d.ts +49 -10
- package/dist/util/git.js +1 -1
- package/dist/{webflow-IRKOIT7S.js → webflow-624FEBFD.js} +4 -4
- package/dist/{websites-TB4TCAWM.js → websites-Y6FN2XFD.js} +27 -20
- package/dist/{write-audits-to-airtable-53EVXKMU.js → write-audits-to-airtable-TI3JMWSY.js} +7 -5
- package/package.json +3 -2
- package/dist/airtable-JGCPS7JH.js +0 -9
- package/dist/announce-CLQYX5I4.js.map +0 -1
- package/dist/attachments-NLZIJ5NU.js +0 -9
- package/dist/chunk-2ZAZ7ETT.js.map +0 -1
- package/dist/chunk-3Z6X3BHU.js.map +0 -1
- package/dist/chunk-5EEMTJMT.js.map +0 -1
- package/dist/chunk-5GUJ36TL.js +0 -53
- package/dist/chunk-5GUJ36TL.js.map +0 -1
- package/dist/chunk-5UINJNAJ.js.map +0 -1
- package/dist/chunk-6R56OKJZ.js.map +0 -1
- package/dist/chunk-AVEQUR44.js.map +0 -1
- package/dist/chunk-BVEDKMNG.js.map +0 -1
- package/dist/chunk-BYGPUUCT.js.map +0 -1
- package/dist/chunk-CWXTNPNZ.js.map +0 -1
- package/dist/chunk-DFKBTBO3.js.map +0 -1
- package/dist/chunk-F3JWOPTG.js.map +0 -1
- package/dist/chunk-FSGICFXB.js.map +0 -1
- package/dist/chunk-GASBX52O.js +0 -12
- package/dist/chunk-GASBX52O.js.map +0 -1
- package/dist/chunk-IY6256GK.js.map +0 -1
- package/dist/chunk-KJRVMMM3.js.map +0 -1
- package/dist/chunk-LM2NHRCJ.js.map +0 -1
- package/dist/chunk-QF6IQQFP.js.map +0 -1
- package/dist/chunk-R5IMFAFR.js.map +0 -1
- package/dist/chunk-TO7DJYLZ.js.map +0 -1
- package/dist/chunk-TR3HFH6J.js.map +0 -1
- package/dist/chunk-WJMPCVOR.js.map +0 -1
- package/dist/chunk-WSJ7RO54.js.map +0 -1
- package/dist/chunk-WVNDEYXL.js.map +0 -1
- package/dist/chunk-XHHMM5HX.js.map +0 -1
- package/dist/chunk-XN37VTDB.js.map +0 -1
- package/dist/chunk-XPJQXSC4.js.map +0 -1
- package/dist/chunk-YFAXOD7Z.js +0 -42
- package/dist/chunk-YFAXOD7Z.js.map +0 -1
- package/dist/chunk-YLYXW5PH.js.map +0 -1
- package/dist/chunk-Z2K4JPQ3.js.map +0 -1
- package/dist/chunk-ZCL7C5LH.js.map +0 -1
- package/dist/client-G2WGWPCA.js +0 -11
- package/dist/db-XKZYDCKM.js.map +0 -1
- package/dist/digest-7UBGUBRK.js.map +0 -1
- package/dist/digest-state-3KHZF7GD.js.map +0 -1
- package/dist/ensure-site-OAAE5YE2.js.map +0 -1
- package/dist/fleet-events-cF2Om88w.d.ts +0 -24
- package/dist/forms-notify-target-UC6PF3AE.js.map +0 -1
- package/dist/github-signals-TX5FPYP6.js.map +0 -1
- package/dist/header-image-PSPT7CUM.js.map +0 -1
- package/dist/launch-UD36AHUN.js.map +0 -1
- package/dist/lighthouse-airtable-YMH4UA7R.js +0 -12
- package/dist/match-harness-QRG6XZAR.js +0 -70
- package/dist/match-harness-QRG6XZAR.js.map +0 -1
- package/dist/migrate-Y7R4CESL.js +0 -7
- package/dist/parity-CAJ477PS.js +0 -14
- package/dist/preflight-RYIP54NY.js.map +0 -1
- package/dist/prismic-ci-6GKKZGB5.js.map +0 -1
- package/dist/prismic-models-P6FWWVRS.js.map +0 -1
- package/dist/prospect-audit-PRHU53HS.js.map +0 -1
- package/dist/protection-audit-SJO53MEQ.js +0 -168
- package/dist/protection-audit-SJO53MEQ.js.map +0 -1
- package/dist/render-YGNGTX3W.js.map +0 -1
- package/dist/replay-PCSQOGCZ.js.map +0 -1
- package/dist/report-LQS4ECTM.js.map +0 -1
- package/dist/report-mirror-HDTOJE64.js.map +0 -1
- package/dist/schema-A4WCPIF4.js.map +0 -1
- package/dist/site-mirror-WON4FTJ2.js.map +0 -1
- package/dist/submissions-3I3GAQAX.js.map +0 -1
- package/dist/submissions-OVZPVBYG.js.map +0 -1
- /package/dist/{airtable-JGCPS7JH.js.map → attachments-JFGFQRXQ.js.map} +0 -0
- /package/dist/{blux-4KNXUP2K.js.map → blux-NXQLMS4W.js.map} +0 -0
- /package/dist/{bump-deps-C5G2EFBB.js.map → bump-deps-775VLDYB.js.map} +0 -0
- /package/dist/{chunk-FUWFLAWQ.js.map → chunk-3RLDX3Q2.js.map} +0 -0
- /package/dist/{chunk-S7RYFUIK.js.map → chunk-6PGXKN6F.js.map} +0 -0
- /package/dist/{chunk-HTABUCF4.js.map → chunk-6THEZQLA.js.map} +0 -0
- /package/dist/{chunk-2LYOAB2E.js.map → chunk-HSMN35LU.js.map} +0 -0
- /package/dist/{chunk-BCKEP5S6.js.map → chunk-JHJNNJLG.js.map} +0 -0
- /package/dist/{chunk-ZQV7UQNE.js.map → chunk-LUF52EIY.js.map} +0 -0
- /package/dist/{chunk-VSGMCCGQ.js.map → chunk-MMSMZC7S.js.map} +0 -0
- /package/dist/{chunk-4763KQ6O.js.map → chunk-PXRN2MER.js.map} +0 -0
- /package/dist/{chunk-WMBLR5VA.js.map → chunk-PZZ6HM5T.js.map} +0 -0
- /package/dist/{chunk-CJ2RMTT7.js.map → chunk-TV76A6GN.js.map} +0 -0
- /package/dist/{chunk-KZRR4NFG.js.map → chunk-TVZ6QCOE.js.map} +0 -0
- /package/dist/{chunk-BI2VI6EM.js.map → chunk-YXWBM26P.js.map} +0 -0
- /package/dist/{attachments-NLZIJ5NU.js.map → client-DGTO65WB.js.map} +0 -0
- /package/dist/{convert-to-pnpm-YTFREUJK.js.map → convert-to-pnpm-KLWA53N5.js.map} +0 -0
- /package/dist/{client-G2WGWPCA.js.map → deadletter-G4M3HSVM.js.map} +0 -0
- /package/dist/{digest-collectors-DJFN5ZDK.js.map → digest-collectors-CYTN2EUX.js.map} +0 -0
- /package/dist/{fleet-state-UEVZ3X3J.js.map → fleet-state-RJROYXKO.js.map} +0 -0
- /package/dist/{freeze-A6MUCZU4.js.map → freeze-GUQ43EAU.js.map} +0 -0
- /package/dist/{health-mirror-XJAKA3EY.js.map → health-mirror-KU3G7V2Y.js.map} +0 -0
- /package/dist/{import-airtable-TAKSN4NV.js.map → import-airtable-UBF5GYAL.js.map} +0 -0
- /package/dist/{lighthouse-VHI77PFB.js.map → lighthouse-52WSPZ5D.js.map} +0 -0
- /package/dist/{lighthouse-airtable-YMH4UA7R.js.map → lighthouse-airtable-M45OPVRV.js.map} +0 -0
- /package/dist/{migrate-Y7R4CESL.js.map → migrate-XZ7U5DFC.js.map} +0 -0
- /package/dist/{notify-IISTHNBR.js.map → notify-K3WVH3DM.js.map} +0 -0
- /package/dist/{onboard-TM2KESGF.js.map → onboard-JQQIMQW7.js.map} +0 -0
- /package/dist/{orchestrate-HYVQPRCE.js.map → orchestrate-L2A5BZFY.js.map} +0 -0
- /package/dist/{parity-CAJ477PS.js.map → parity-2JGVUCZD.js.map} +0 -0
- /package/dist/{pipeline-YROAY6DT.js.map → pipeline-UUPXOS2J.js.map} +0 -0
- /package/dist/{prospect-audits-R3LWF6U7.js.map → prospect-audits-IZVQY3OQ.js.map} +0 -0
- /package/dist/{render-from-row-IFSBHWDH.js.map → render-from-row-75JTED2Z.js.map} +0 -0
- /package/dist/{svelte-codemods-WSV2FGNG.js.map → svelte-codemods-VOLOKKFI.js.map} +0 -0
- /package/dist/{sync-K3PKHVLH.js.map → sync-F4USL4K5.js.map} +0 -0
- /package/dist/{sync-configs-RRIHNLIJ.js.map → sync-configs-OXSWKVZ2.js.map} +0 -0
- /package/dist/{upgrade-VTD6V4HS.js.map → upgrade-EVAL3JTO.js.map} +0 -0
- /package/dist/{webflow-IRKOIT7S.js.map → webflow-624FEBFD.js.map} +0 -0
- /package/dist/{websites-TB4TCAWM.js.map → websites-Y6FN2XFD.js.map} +0 -0
- /package/dist/{write-audits-to-airtable-53EVXKMU.js.map → write-audits-to-airtable-TI3JMWSY.js.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as AuditResult, S as Site, A as AuditName, b as RecipeResult, R as RecipeName, I as InventoryProvider } from './types-D_bpy89i.js';
|
|
2
2
|
export { C as ConfigName } from './types-D_bpy89i.js';
|
|
3
|
-
import { A as AirtableBase, a as FleetEventType } from './fleet-events-
|
|
3
|
+
import { A as AirtableBase, W as WebsiteRow, a as FleetEventType } from './fleet-events-CkOZpMVC.js';
|
|
4
4
|
import { F as FormType } from './types-RXY-vY-5.js';
|
|
5
5
|
export { SyncConfigsOptions, syncConfigs } from './recipes/sync-configs.js';
|
|
6
6
|
import 'airtable/lib/airtable_base.js';
|
|
@@ -315,14 +315,27 @@ type DependabotAlert = {
|
|
|
315
315
|
scope: "runtime" | "development" | null;
|
|
316
316
|
/** Dependency graph relationship (`dependency.relationship`), or null when GitHub reports
|
|
317
317
|
* "unknown"/nothing. "transitive" means no direct-dep bump can fix it — Renovate's vuln
|
|
318
|
-
* alerts have no fix vehicle until the weekly lockfile-maintenance window.
|
|
319
|
-
|
|
318
|
+
* alerts have no fix vehicle until the weekly lockfile-maintenance window. "inconclusive"
|
|
319
|
+
* is what GitHub stamps on an alert filed against a manifest its dependency graph still
|
|
320
|
+
* tracks but the tree no longer holds (#702) — kept, never folded to null, because it is
|
|
321
|
+
* the secondary tell for a ghost alert. */
|
|
322
|
+
relationship: "direct" | "transitive" | "inconclusive" | null;
|
|
323
|
+
/** The manifest the alert was filed against (`dependency.manifest_path`, e.g.
|
|
324
|
+
* `package-lock.json`), or null when absent. GitHub retains a manifest after the file is
|
|
325
|
+
* deleted from the default branch and keeps filing alerts against that frozen snapshot;
|
|
326
|
+
* the audit resolves this path with {@link GitHubRest.manifestExists} to tell a ghost from
|
|
327
|
+
* a live vulnerability (#702). */
|
|
328
|
+
manifestPath: string | null;
|
|
320
329
|
};
|
|
321
330
|
|
|
322
331
|
/** The Dependabot fetch the security audit needs, injectable for tests. The real default is
|
|
323
332
|
* built from GITHUB_TOKEN; absent token (or a site with no gitRepo) → pnpm/npm audit fallback. */
|
|
324
333
|
type DependabotDeps = {
|
|
325
334
|
listAlerts: (repo: string) => Promise<DependabotAlert[]>;
|
|
335
|
+
/** Whether an alert's `manifestPath` is still on the default branch. Optional: without it
|
|
336
|
+
* every alert counts, which is the loud direction. A lookup that THROWS also counts the
|
|
337
|
+
* alert — an API hiccup must never quietly suppress a real vulnerability (#702). */
|
|
338
|
+
manifestExists?: (repo: string, path: string) => Promise<boolean>;
|
|
326
339
|
};
|
|
327
340
|
declare function securityAudit(ctx: AuditContext): Promise<AuditResult>;
|
|
328
341
|
|
|
@@ -487,407 +500,18 @@ type AirtableInventoryOptions = {
|
|
|
487
500
|
};
|
|
488
501
|
/**
|
|
489
502
|
* Read sites from the Airtable Websites table as an InventoryProvider.
|
|
490
|
-
* Each row becomes one Site; `path` is computed as `{workdir}/{slug}`.
|
|
491
|
-
* Only LIVE `maintenance` sites that have a `url` are included — pre-launch
|
|
492
|
-
* stages ("launching" / "building", via isPreLaunch) are excluded so a
|
|
493
|
-
* not-yet-live site is never audited as production (its deploy/domain/uptime/CMS
|
|
494
|
-
* audits would fail against nothing and red its Airtable row) nor swept by other
|
|
495
|
-
* `--fleet airtable` ops; it re-enters the fleet when a Launch report flips its
|
|
496
|
-
* Status to "maintained". The production URL is exposed as `Site.deployedUrl` so
|
|
497
|
-
* the lighthouse audit can run against it with no checkout. `repoUrl` is
|
|
498
|
-
* intentionally NOT set from `url` — a clone source must come from `gitRepo`
|
|
499
|
-
* (`owner/repo`), never the production URL.
|
|
500
|
-
*/
|
|
501
|
-
declare function fromAirtableBase(base: AirtableBase, opts?: AirtableInventoryOptions): InventoryProvider;
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* The site-status vocabulary — ONE module owns it (#539 Phase 4).
|
|
505
|
-
*
|
|
506
|
-
* The fleet's lifecycle names were inherited from an Airtable single-select
|
|
507
|
-
* written by hand years ago ("probably not our problem"). The operator approved
|
|
508
|
-
* a canonical vocabulary, and the migration is now COMPLETE in both stores:
|
|
509
|
-
* Airtable's "Status" single-select carries exactly the six canonical options
|
|
510
|
-
* and nothing else. This module no longer knows the old names at all.
|
|
511
|
-
*
|
|
512
|
-
* The retired mapping, kept as the record of what was merged into what:
|
|
513
|
-
*
|
|
514
|
-
* old (retired 2026-08-25) new (canonical)
|
|
515
|
-
* ───────────────────────── ───────────────
|
|
516
|
-
* in development building
|
|
517
|
-
* launch period launching
|
|
518
|
-
* maintenance maintained
|
|
519
|
-
* hosting hosted-only
|
|
520
|
-
* probably not our problem external
|
|
521
|
-
* legacy ┐
|
|
522
|
-
* deprecated ┴ archived ← approved MERGE, many-to-one
|
|
523
|
-
*
|
|
524
|
-
* `legacy` and `deprecated` were already treated identically by every PREDICATE
|
|
525
|
-
* (ARCHIVED_STATUSES held both), so collapsing them changes no *selection* — no
|
|
526
|
-
* fleet op gains or loses a site. It is NOT true that collapsing them changes
|
|
527
|
-
* nothing at all, and one surface proved it: the cockpit's Archived lane LABELS
|
|
528
|
-
* each row with its Status cell, and canonicalizing there rendered all 12 live
|
|
529
|
-
* archived rows as "archived". That lane now labels from `statusRaw`, which is
|
|
530
|
-
* exactly why `WebsiteRow.statusRaw` exists. The rule this leaves behind:
|
|
531
|
-
* canonical values decide BEHAVIOUR; anything DISPLAYING a Status cell, or
|
|
532
|
-
* writing one back, uses the raw cell.
|
|
533
503
|
*
|
|
534
|
-
*
|
|
535
|
-
* is
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
504
|
+
* No longer what `--fleet` resolves through: since #646 step 4 the fleet roster
|
|
505
|
+
* is read from Turso (`fromTursoDb`, `src/inventory/turso.ts`), because a site
|
|
506
|
+
* created by the Turso-native `ensure-site` has no Airtable record at all. This
|
|
507
|
+
* stays as the Airtable half of the selection-parity instrument and a public
|
|
508
|
+
* export until the operator approves deleting the Airtable layer (steps 6–8).
|
|
539
509
|
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
* at the two Airtable/Turso seams; writes still emit the OLD
|
|
544
|
-
* Airtable option names. Airtable untouched. No SELECTION
|
|
545
|
-
* change — every predicate picks exactly the sites it picked
|
|
546
|
-
* before (pinned row-by-row in tests/reports/airtable/
|
|
547
|
-
* site-status.test.ts). Displayed labels come from `statusRaw`.
|
|
548
|
-
* stage 2 (DONE) the Airtable "Status" single-select gained the 6 new options
|
|
549
|
-
* and all 44 cells were migrated (verified live: maintained=13,
|
|
550
|
-
* archived=12, external=9, building=6, hosted-only=2,
|
|
551
|
-
* launching=2 — zero old values, zero unrecognized), `db sync`
|
|
552
|
-
* ran clean (mismatches=0), and AIRTABLE_USES_NEW_VOCABULARY
|
|
553
|
-
* flipped to true. Writers now emit canonical names verbatim.
|
|
554
|
-
* The alias map STAYS: the 7 old options still exist in the
|
|
555
|
-
* field, so a human can still pick one in the Airtable UI.
|
|
556
|
-
* stage 3 (DONE) the operator deleted the 7 old options from the Airtable
|
|
557
|
-
* "Status" field on 2026-08-25, which is what made this safe:
|
|
558
|
-
* the gate was always "no old value CAN BE ENTERED", not
|
|
559
|
-
* merely "none is stored". Verified against the live base
|
|
560
|
-
* before any code changed — the field carries exactly the six
|
|
561
|
-
* canonical choices, byte-exact, and all 44 cells still hold a
|
|
562
|
-
* canonical value with ZERO blanks (deleting a single-select
|
|
563
|
-
* option CLEARS the cells using it, so "no cell was blanked"
|
|
564
|
-
* was checked, not assumed). AIRTABLE_STATUS_ALIASES,
|
|
565
|
-
* AIRTABLE_OLD_NAMES and AIRTABLE_USES_NEW_VOCABULARY are
|
|
566
|
-
* gone; both functions reduce to the identity.
|
|
567
|
-
*
|
|
568
|
-
* WHAT CHANGED IN BEHAVIOUR AT STAGE 3, and it is the only thing that did: an
|
|
569
|
-
* old name is no longer translated. `canonicalizeStatus("maintenance")` used to
|
|
570
|
-
* yield `maintained`; it now yields `"maintenance"` verbatim, which
|
|
571
|
-
* `isUnrecognizedStatus` flags and the cockpit surfaces as a watch row. That is
|
|
572
|
-
* intended. The option cannot be selected any more, so a stored old value would
|
|
573
|
-
* mean something went wrong — a restored backup, a scripted write, an API
|
|
574
|
-
* caller with a stale constant — and the fleet should say so rather than absorb
|
|
575
|
-
* it into a status nobody chose.
|
|
576
|
-
*
|
|
577
|
-
* Canonicalization happens on READ, never at rest: `src/db/import-airtable.ts`
|
|
578
|
-
* still stores the raw Airtable cell verbatim in `sites.status`, so the hourly
|
|
579
|
-
* parity check keeps comparing raw-to-raw and the importer stays honest to its
|
|
580
|
-
* source. Both readers — `mapRow` (Airtable) and `rowFromJoined` (Turso) — run
|
|
581
|
-
* the raw value through `canonicalizeStatus`, which is what keeps the #558
|
|
582
|
-
* reader-equivalence instrument green.
|
|
583
|
-
*/
|
|
584
|
-
/** The canonical site lifecycle vocabulary. */
|
|
585
|
-
type Status = "building" | "launching" | "maintained" | "hosted-only" | "external" | "archived";
|
|
586
|
-
|
|
587
|
-
type Frequency = "None" | "Monthly" | "Quarterly" | "Yearly";
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* Per-site notification routing. When present on a `maintained` site, the form
|
|
591
|
-
* notification is addressed by the value of a submission field (`field`, read from
|
|
592
|
-
* `extraFields`) — e.g. route a contact form's `interest` to a different recipient
|
|
593
|
-
* per option, always CC-ing a shared address. Absent (`null`) → the site keeps the
|
|
594
|
-
* default single-POC behavior. Recipients live HERE (server-side Airtable config),
|
|
595
|
-
* never supplied by the submitting site, so the ingest can't be turned into an open
|
|
596
|
-
* relay.
|
|
510
|
+
* The selection rule itself is `selectFleetSites` — shared, so the two providers
|
|
511
|
+
* cannot drift. `meta.airtableRowId` is kept alongside `meta.siteId` for any
|
|
512
|
+
* consumer that still reads the old key.
|
|
597
513
|
*/
|
|
598
|
-
|
|
599
|
-
/** The `extraFields` key whose value selects a route, e.g. "interest". */
|
|
600
|
-
field: string;
|
|
601
|
-
/** Field-value → recipient address(es). */
|
|
602
|
-
routes: Record<string, string | string[]>;
|
|
603
|
-
/** Recipient(s) when the value matches no route. */
|
|
604
|
-
default?: string | string[];
|
|
605
|
-
/** Address(es) CC'd on every routed (maintenance) send. */
|
|
606
|
-
cc?: string[];
|
|
607
|
-
};
|
|
608
|
-
type WebsiteRow = {
|
|
609
|
-
id: string;
|
|
610
|
-
name: string;
|
|
611
|
-
url: string;
|
|
612
|
-
/** Canonical lifecycle status (see ./site-status.ts). Canonicalized at the read
|
|
613
|
-
* boundary, so an old-vocabulary Airtable cell and a new one read identically.
|
|
614
|
-
* A present-but-unrecognized cell survives VERBATIM (blind-cast) rather than
|
|
615
|
-
* becoming null — `isUnrecognizedStatus` flags it, and null would make
|
|
616
|
-
* due.ts/preflight.ts treat the row as eligible-by-default. */
|
|
617
|
-
status: Status | null;
|
|
618
|
-
/** The literal Airtable Status cell behind `status` — same pattern as
|
|
619
|
-
* `maintenanceFreqRaw`. The dashboard status editor round-trips THIS, so its
|
|
620
|
-
* dropdown offers and preselects the values Airtable actually holds while the
|
|
621
|
-
* two vocabularies coexist. Null = blank cell. */
|
|
622
|
-
statusRaw: string | null;
|
|
623
|
-
pointOfContact: string | null;
|
|
624
|
-
maintenanceFreq: Frequency;
|
|
625
|
-
testingFreq: Frequency;
|
|
626
|
-
/** The literal Airtable cell values behind the coerced frequencies. `toFrequency`
|
|
627
|
-
* trims whitespace ("Monthly " reads as Monthly), then maps any still-unrecognized
|
|
628
|
-
* value ("Quaterly") to "None" with a LOUD console.warn so nothing bogus reaches a
|
|
629
|
-
* client email and the drop is never invisible. Preflight validates THESE to surface
|
|
630
|
-
* the same failure as a structured finding. Null = blank cell. */
|
|
631
|
-
maintenanceFreqRaw: string | null;
|
|
632
|
-
testingFreqRaw: string | null;
|
|
633
|
-
/** Last manually-recorded maintenance day (used as fallback when no Reports row exists). */
|
|
634
|
-
maintenanceDay: string | null;
|
|
635
|
-
testingDay: string | null;
|
|
636
|
-
ga4PropertyId: string | null;
|
|
637
|
-
/** Operator-supplied query for the Google search-presence check (e.g. the business name).
|
|
638
|
-
* Null = no query set → the check is skipped for this site. */
|
|
639
|
-
searchQuery: string | null;
|
|
640
|
-
/** Explicit Search Console property for this site (`sc-domain:...` or `https://.../`).
|
|
641
|
-
* Null = auto-resolve from the SA's visible properties by host. */
|
|
642
|
-
searchConsoleProperty: string | null;
|
|
643
|
-
/** ISO timestamp of the last draft run where THIS site's GA/Search enrichment
|
|
644
|
-
* ERRORED (vs a legitimate "not configured" skip). Set by drafting on a soft-fail,
|
|
645
|
-
* cleared (null) on a clean enrichment, so the per-site analytics-failure signal
|
|
646
|
-
* self-heals. Null when the operator-added `Analytics soft-fail at` column is absent. */
|
|
647
|
-
analyticsSoftFailAt: string | null;
|
|
648
|
-
/** GitHub repo identity as `owner/repo`. Null = no git wiring → self-update ops skip
|
|
649
|
-
* (or, for local runs, fall back to the checkout's origin remote). */
|
|
650
|
-
gitRepo: string | null;
|
|
651
|
-
reportRecipientsTo: string | null;
|
|
652
|
-
reportRecipientsCc: string | null;
|
|
653
|
-
acceptedWatchConditions: string[];
|
|
654
|
-
/** First attachment in the Header image field (Airtable's signed URL — fetch before expiry). */
|
|
655
|
-
headerImage: {
|
|
656
|
-
url: string;
|
|
657
|
-
filename: string;
|
|
658
|
-
type: string;
|
|
659
|
-
} | null;
|
|
660
|
-
/** Lighthouse "current state" snapshot, kept fresh by `audit lighthouse --write-airtable`. */
|
|
661
|
-
pScore: number | null;
|
|
662
|
-
rScore: number | null;
|
|
663
|
-
bpScore: number | null;
|
|
664
|
-
seoScore: number | null;
|
|
665
|
-
/** ISO timestamp set by `audit lighthouse --write-airtable` when scores were last refreshed. */
|
|
666
|
-
lastLighthouseAuditAt: string | null;
|
|
667
|
-
/** Last-known counts from non-lighthouse audits, written by
|
|
668
|
-
* `audit --write-airtable`. `null` = never audited (or this audit
|
|
669
|
-
* type was skipped on the last run). 0 = audited, clean. */
|
|
670
|
-
a11yViolations: number | null;
|
|
671
|
-
/** Declared-range drift vs the Reddoor baseline (what package.json asks for). */
|
|
672
|
-
depsDrifted: number | null;
|
|
673
|
-
depsMajorBehind: number | null;
|
|
674
|
-
/** Real installed-version drift: deps behind the registry's latest, from the
|
|
675
|
-
* committed lockfile (`pnpm outdated`). Null = not determined this run. */
|
|
676
|
-
depsOutdated: number | null;
|
|
677
|
-
/** Of {@link depsOutdated}, how many are a *major* version behind the
|
|
678
|
-
* registry's latest — the "majors available on npm" signal, distinct from the
|
|
679
|
-
* baseline-drift {@link depsMajorBehind}. Null = not determined this run. */
|
|
680
|
-
depsMajorOutdated: number | null;
|
|
681
|
-
securityVulnsCritical: number | null;
|
|
682
|
-
securityVulnsHigh: number | null;
|
|
683
|
-
securityVulnsModerate: number | null;
|
|
684
|
-
securityVulnsLow: number | null;
|
|
685
|
-
/** Count of consecutive nightly Renovate auto-fix dispatches for the CURRENT
|
|
686
|
-
* critical/high vuln episode that have NOT yet cleared it. Owned by
|
|
687
|
-
* `renovate-dispatch`: +1 per real dispatch, reset to 0 when vulns clear.
|
|
688
|
-
* Null = field absent / never dispatched → reads as 0. At/above
|
|
689
|
-
* AUTO_FIX_EXHAUSTED_CYCLES the vuln renders as "auto-fix failed". */
|
|
690
|
-
securityAutoFixAttempts: number | null;
|
|
691
|
-
/** ISO timestamp the security audit last ran — gates freshness of the Security Updates auto-tick
|
|
692
|
-
* (clean counts only auto-tick when recent). */
|
|
693
|
-
lastSecurityAuditAt: string | null;
|
|
694
|
-
/** The known advisories behind the counts (severity-sorted, capped), so the dashboard can show
|
|
695
|
-
* WHICH packages are vulnerable, not just the totals. null = never audited / unparseable;
|
|
696
|
-
* empty array = audited clean. Written alongside the counts by the security audit. */
|
|
697
|
-
securityAdvisories: SecurityAdvisory[] | null;
|
|
698
|
-
/** Domain/DNS/SSL probe (the `domain` audit). `certDaysRemaining` is days until the TLS cert
|
|
699
|
-
* expires (null = unresolved or no usable cert); `domainCheckedAt` is when it last ran. */
|
|
700
|
-
certDaysRemaining: number | null;
|
|
701
|
-
domainCheckedAt: string | null;
|
|
702
|
-
/** Netlify site id — the IDENTITY the `netlify-deploy` audit needs to query the
|
|
703
|
-
* Netlify API. Read-only input (operator-set in Airtable); null = not on Netlify
|
|
704
|
-
* (or not wired) → that audit skips. Never derived from the URL. */
|
|
705
|
-
netlifyId: string | null;
|
|
706
|
-
/** Latest PRODUCTION deploy health (the `netlify-deploy` audit). `deployStatus` is
|
|
707
|
-
* Netlify's deploy state lower-cased (`ready`/`error`/`building`/…), null = none / not
|
|
708
|
-
* checked; `lastDeployAt` is when it deployed; `deployLogUrl` links to the deploy/log. */
|
|
709
|
-
deployStatus: string | null;
|
|
710
|
-
lastDeployAt: string | null;
|
|
711
|
-
deployLogUrl: string | null;
|
|
712
|
-
/** When the `netlify-deploy` audit last RAN (freshness stamp for `deployStatus`). The audit
|
|
713
|
-
* already writes "Deploy checked at"; this read-back is the Plan-2 fix so `deployEvidence`
|
|
714
|
-
* (Plan 4) can gate on check time — NOT on `lastDeployAt`, which is deploy time, not check time. */
|
|
715
|
-
deployCheckedAt: string | null;
|
|
716
|
-
/** Function-health verdict (the `function-health` audit): the deployed `/health` function
|
|
717
|
-
* answered `ok:true` (pass) or `ok:false` (fail). Single-select `pass`/`fail`; null = never ran
|
|
718
|
-
* / unreachable (→ Plan 4 maps to unknown/amber). Kept SEPARATE from `deployStatus` so
|
|
719
|
-
* `isFailedDeployStatus` keeps meaning "the build failed". */
|
|
720
|
-
functionHealth: "pass" | "fail" | null;
|
|
721
|
-
/** CMS reachability (server-side), derived from the same `/health` body's `details.prismic ===
|
|
722
|
-
* "ok"`. Single-select `pass`/`fail`; null = never ran. No per-site Prismic token or identity
|
|
723
|
-
* column is ever built — this rides `/health`. */
|
|
724
|
-
cmsReachable: "pass" | "fail" | null;
|
|
725
|
-
/** Does the deployed site's Turnstile widget actually work? Single-select `pass`/`fail`;
|
|
726
|
-
* null = **unverified**, which is the normal state — see below. Freshness gated by
|
|
727
|
-
* `formE2eCheckedAt`, the clock of the audit that writes it. Powers the cockpit Require-Turnstile guardrail: a site with
|
|
728
|
-
* `requireTurnstile` ON but no working widget silently buckets 100% of its real leads.
|
|
729
|
-
*
|
|
730
|
-
* One of the two `"fail"` arms is derived from `/health` (the other is a browser seeing
|
|
731
|
-
* 110200 on the live hostname), whose `forms.turnstile` is a truthiness check
|
|
732
|
-
* on `PUBLIC_TURNSTILE_SITE_KEY` that never contacts Cloudflare (see
|
|
733
|
-
* audits/function-health-airtable.ts for the incident). No key IS proof the widget can't
|
|
734
|
-
* work; a key is NOT proof that it can — a sitekey whose widget is full at Cloudflare's
|
|
735
|
-
* 10-hostname cap sets the var and still mints no token. So a `"pass"` here has to be
|
|
736
|
-
* earned by a real browser rendering the real widget (form-e2e), and until it is, null
|
|
737
|
-
* keeps the site in the cockpit's amber "can't verify" watch rather than claiming health
|
|
738
|
-
* nobody measured. */
|
|
739
|
-
turnstileWidget: "pass" | "fail" | null;
|
|
740
|
-
/** When the `function-health` audit last ran — the freshness gate for `functionHealth`,
|
|
741
|
-
* `cmsReachable`, and `turnstileWidget`. Null = never ran. */
|
|
742
|
-
functionHealthCheckedAt: string | null;
|
|
743
|
-
/** Deployed-URL browser probe (the `browser` audit): cross-engine render OK, mobile render OK,
|
|
744
|
-
* internal-links OK + broken count, and when it last ran (one timestamp gates all three). */
|
|
745
|
-
crossbrowserOk: boolean | null;
|
|
746
|
-
mobileOk: boolean | null;
|
|
747
|
-
linksOk: boolean | null;
|
|
748
|
-
brokenLinks: number | null;
|
|
749
|
-
browserCheckedAt: string | null;
|
|
750
|
-
/** Uptime-reachable verdict (browser audit): every sampled route returned 2xx/3xx. Single-select
|
|
751
|
-
* `pass`/`fail`; null = never ran. Point-in-time. Freshness-gated by `browserCheckedAt`. */
|
|
752
|
-
reachableOk: "pass" | "fail" | null;
|
|
753
|
-
/** Titles & meta verdict (browser audit, chromium): every sampled route has a non-empty `<title>`
|
|
754
|
-
* ≤ 70 chars + a non-empty meta description, and no duplicate titles across the sample.
|
|
755
|
-
* Single-select `pass`/`fail`; null = never ran. Freshness-gated by `browserCheckedAt`. */
|
|
756
|
-
titleMetaOk: "pass" | "fail" | null;
|
|
757
|
-
/** Per-site copy overrides (M6a). Blank → null → the DEFAULT_COPY value. */
|
|
758
|
-
copyIntro: string | null;
|
|
759
|
-
copyContact: string | null;
|
|
760
|
-
copyFooter: string | null;
|
|
761
|
-
/** Go-live timestamp, stamped when a Launch report sends (M6b). Null = not yet launched. */
|
|
762
|
-
launchedAt: string | null;
|
|
763
|
-
/** Optional per-site webhook (e.g. Zapier Catch Hook). When set, the ingest
|
|
764
|
-
* POSTs newsletter-formType submissions here (best-effort). Blank → null. */
|
|
765
|
-
newsletterWebhook: string | null;
|
|
766
|
-
/** Per-site Mailchimp (newsletter). Both must be set for the direct add;
|
|
767
|
-
* blank → skipped. The API key is `key-dc` format; dc is derived from it. */
|
|
768
|
-
mailchimpApiKey: string | null;
|
|
769
|
-
mailchimpAudienceId: string | null;
|
|
770
|
-
/** Per-site Cloudflare Turnstile gate (Airtable checkbox). When true, a submission
|
|
771
|
-
* whose Turnstile token verifies as "fail" (forged) OR "absent" (secret configured
|
|
772
|
-
* centrally but NO token forwarded — the direct-POST-bot signature) is escalated to
|
|
773
|
-
* auto-spam regardless of content score. A present-but-expired token stays
|
|
774
|
-
* "unverifiable" and neutral (a real browser DID render the widget — fail-open).
|
|
775
|
-
* ROLLOUT PRECONDITION: only enable on a site whose DEPLOYED package forwards
|
|
776
|
-
* `_meta.turnstileToken` from EVERY form (widget rendered + `cf-turnstile-response`
|
|
777
|
-
* posted; check the site's `/health` → forms.turnstile:true). A site that never
|
|
778
|
-
* forwards tokens would silently bucket 100% of its real leads — and the form-e2e
|
|
779
|
-
* probe cannot catch that state (testMode bypasses the gate). */
|
|
780
|
-
requireTurnstile: boolean;
|
|
781
|
-
/** GitHub-signals sweep (slice 2a), written nightly by `github-signals --fleet`. */
|
|
782
|
-
renovateFailingCis: number | null;
|
|
783
|
-
defaultBranchCi: string | null;
|
|
784
|
-
lastCommitAt: string | null;
|
|
785
|
-
githubSignalsAt: string | null;
|
|
786
|
-
/** Per-site smoke-suite verdict (the `smoke` audit runs `pnpm test:smoke`).
|
|
787
|
-
* Single-select pass/fail; null = never ran. `lastSmokeAt` gates freshness. */
|
|
788
|
-
smokeOk: "pass" | "fail" | null;
|
|
789
|
-
lastSmokeAt: string | null;
|
|
790
|
-
/** Synthetic form end-to-end verdict (the `form-e2e` audit submits the real prod
|
|
791
|
-
* contact form in test-mode). Single-select pass/fail; null = never ran OR (with
|
|
792
|
-
* a fresh `formE2eCheckedAt`) no contact form → n/a. `formE2eCheckedAt` gates
|
|
793
|
-
* freshness AND encodes the n/a-vs-never-ran distinction. */
|
|
794
|
-
formE2eOk: "pass" | "fail" | null;
|
|
795
|
-
formE2eCheckedAt: string | null;
|
|
796
|
-
/**
|
|
797
|
-
* Nightly Prismic model drift sweep (`prismic-models --fleet --write-airtable`).
|
|
798
|
-
*
|
|
799
|
-
* FOUR-VALUED, unlike every other verdict column in this table, and the extra
|
|
800
|
-
* state is the point:
|
|
801
|
-
*
|
|
802
|
-
* - `pass` — the repo and its Prismic repository were compared and agree.
|
|
803
|
-
* - `fail` — they were compared and DIVERGE (a model to create/update, or
|
|
804
|
-
* one that exists only in Prismic). A finding for a human.
|
|
805
|
-
* - `unknown` — THE CHECK ITSELF FAILED. Unreadable checkout, broken config,
|
|
806
|
-
* missing/expired token, unreadable remote. Nothing at all was
|
|
807
|
-
* established about this site's models.
|
|
808
|
-
* - `null` — no verdict to hold: the sweep has never run for this site, or
|
|
809
|
-
* it ran and found no Prismic config at all (a repo that simply
|
|
810
|
-
* is not a Prismic site). `prismicModelsCheckedAt` separates
|
|
811
|
-
* those two — fresh timestamp, blank verdict = "checked, and
|
|
812
|
-
* there is nothing here to check".
|
|
813
|
-
*
|
|
814
|
-
* `unknown` exists because the alternatives are both wrong in the dangerous
|
|
815
|
-
* direction. Writing `pass` for a site nobody could read is a green tick over
|
|
816
|
-
* an outage; writing NOTHING (the obvious "leave the last known value alone")
|
|
817
|
-
* leaves yesterday's `pass` standing for a site that has been failing every
|
|
818
|
-
* night since — and nothing ages a stale `pass` out, because the digest's
|
|
819
|
-
* freshness gate only ever examines failures. Both make "I could not read this
|
|
820
|
-
* site" indistinguishable from "this site is fine", in the record the cockpit
|
|
821
|
-
* and the digest read.
|
|
822
|
-
*
|
|
823
|
-
* OPERATOR PRECONDITION: `Prismic Models` is a single select whose options are
|
|
824
|
-
* `pass`, `fail`, `unknown`. Until the three columns exist the sweep's writes
|
|
825
|
-
* fail with UNKNOWN_FIELD_NAME and are collected as soft failures — the feature
|
|
826
|
-
* ships dark rather than reddening the nightly.
|
|
827
|
-
*/
|
|
828
|
-
prismicModels: PrismicModelsVerdict | null;
|
|
829
|
-
/** When the sweep last ran for this site — written on EVERY outcome, including
|
|
830
|
-
* `unknown` and blank, so the age of the row is the age of the answer. */
|
|
831
|
-
prismicModelsCheckedAt: string | null;
|
|
832
|
-
/** What the sweep found, verbatim: the drift report for a `fail`, the reason
|
|
833
|
-
* nothing could be established for an `unknown`, the skip reason for a blank,
|
|
834
|
-
* and null for a `pass` (which clears yesterday's finding). */
|
|
835
|
-
prismicModelsDrift: string | null;
|
|
836
|
-
/**
|
|
837
|
-
* An expiry the operator sets to accept a KNOWN, EXPECTED `fail` — most often
|
|
838
|
-
* "I am modelling in Prismic on a branch that has not landed, so Prismic is
|
|
839
|
-
* legitimately ahead of `main`". While this timestamp is in the future the
|
|
840
|
-
* drift item is not raised.
|
|
841
|
-
*
|
|
842
|
-
* It expires on purpose, and nothing renews it automatically. A permanent ack
|
|
843
|
-
* would reproduce this column's own failure mode one step later: once the
|
|
844
|
-
* branch lands, the same acked cell would swallow real drift and "nobody is
|
|
845
|
-
* looking at this" would render as "this is fine". An expiry means the worst
|
|
846
|
-
* case is a silence that ends by itself.
|
|
847
|
-
*
|
|
848
|
-
* Narrow by construction — it mutes only `fail`, the finding the operator
|
|
849
|
-
* actually reviewed. `unknown` (the check could not run) and a verdict too old
|
|
850
|
-
* to be current are never muted by it; see `collectPrismicDriftAlerts`.
|
|
851
|
-
*
|
|
852
|
-
* OPERATOR PRECONDITION: `Prismic Ack Until` is a dateTime column. Until it
|
|
853
|
-
* exists this reads null and nothing is acked, which is the safe direction.
|
|
854
|
-
*/
|
|
855
|
-
prismicAckUntil: string | null;
|
|
856
|
-
notifyRouting: NotifyRouting | null;
|
|
857
|
-
/** The RAW `Notify Routing` cell, verbatim. Same reason `statusRaw` exists: the
|
|
858
|
-
* dashboard editor round-trips this JSON, and re-serializing the PARSED object
|
|
859
|
-
* would drop any key the parser ignores and reformat what the operator typed —
|
|
860
|
-
* a silent rewrite of a cell they only opened to look at. */
|
|
861
|
-
notifyRoutingRaw: string | null;
|
|
862
|
-
/** Read-back of the code-owned next-due dates (date-only, written by the
|
|
863
|
-
* nightly `writeNextDueDates`). These exist so the writer can DIFF the
|
|
864
|
-
* freshly-computed dates against what the row already holds and skip the
|
|
865
|
-
* ~31 no-op writes a night the fleet was paying for (#539 Phase 3). Null =
|
|
866
|
-
* cell blank or the operator-added `Next … at` column absent. */
|
|
867
|
-
nextMaintenanceAt: string | null;
|
|
868
|
-
nextTestingAt: string | null;
|
|
869
|
-
};
|
|
870
|
-
/** The `Prismic Models` cell — see {@link WebsiteRow.prismicModels} for why it
|
|
871
|
-
* carries a third state that no other verdict column in this table has. */
|
|
872
|
-
type PrismicModelsVerdict = "pass" | "fail" | "unknown";
|
|
873
|
-
type Severity = "low" | "moderate" | "high" | "critical";
|
|
874
|
-
/** One known vulnerability behind the security counts, as persisted/rendered. */
|
|
875
|
-
type SecurityAdvisory = {
|
|
876
|
-
module: string;
|
|
877
|
-
severity: Severity;
|
|
878
|
-
title: string;
|
|
879
|
-
cves: string[];
|
|
880
|
-
url: string | null;
|
|
881
|
-
/** GitHub Dependabot dependency scope ("runtime" | "development"), when known. Lets the
|
|
882
|
-
* dashboard flag build-time-only ("development") vulns. Omitted for advisories from the
|
|
883
|
-
* lockfile `pnpm audit` fallback, which carries no per-package graph scope. */
|
|
884
|
-
scope?: "runtime" | "development";
|
|
885
|
-
/** GitHub Dependabot dependency-graph relationship, when known. "transitive" means no
|
|
886
|
-
* direct-dep bump can fix it — Renovate's vuln alerts have no fix vehicle until the weekly
|
|
887
|
-
* lockfile-maintenance window. Omitted when GitHub reports "unknown" or for the
|
|
888
|
-
* `pnpm audit` fallback. Drives {@link allActionableVulnsTransitive}. */
|
|
889
|
-
relationship?: "direct" | "transitive";
|
|
890
|
-
};
|
|
514
|
+
declare function fromAirtableBase(base: AirtableBase, opts?: AirtableInventoryOptions): InventoryProvider;
|
|
891
515
|
|
|
892
516
|
type ResolvedCopy = {
|
|
893
517
|
maintenanceIntro: string;
|
|
@@ -992,6 +616,16 @@ type EvidenceRecord = {
|
|
|
992
616
|
note: string;
|
|
993
617
|
};
|
|
994
618
|
|
|
619
|
+
/**
|
|
620
|
+
* The report-row model and its pure, vendor-neutral coercers.
|
|
621
|
+
*
|
|
622
|
+
* `ReportRow` is what BOTH readers return — `mapRow` over an Airtable record
|
|
623
|
+
* (`src/reports/airtable/reports.ts`) and the Turso report reader in
|
|
624
|
+
* `src/db/fleet-state.ts`. Moved out of the Airtable module in #539 Phase 6
|
|
625
|
+
* step 1 (#646) so the Turso read path does not depend on the directory Phase 6
|
|
626
|
+
* deletes. `src/reports/airtable/reports.ts` re-exports every name.
|
|
627
|
+
*/
|
|
628
|
+
|
|
995
629
|
type DeliveryStatus = "pending" | "delivered" | "bounced" | "complained";
|
|
996
630
|
type ReportRow = {
|
|
997
631
|
id: string;
|
|
@@ -1040,13 +674,6 @@ type ReportRow = {
|
|
|
1040
674
|
overrideBy: string | null;
|
|
1041
675
|
overrideAt: string | null;
|
|
1042
676
|
};
|
|
1043
|
-
/** Called with the record Airtable echoed back from the create, before it is
|
|
1044
|
-
* mapped (#539 Phase 5). Structurally typed rather than importing the db
|
|
1045
|
-
* layer's `RawRecord`, so this module stays the leaf it has always been. */
|
|
1046
|
-
type CreatedDraftMirror = (rec: {
|
|
1047
|
-
id: string;
|
|
1048
|
-
fields: Record<string, unknown>;
|
|
1049
|
-
}) => Promise<void>;
|
|
1050
677
|
|
|
1051
678
|
/** Report rows (migration 0007). PK = Airtable rec id. `checklist` is JSON
|
|
1052
679
|
* keyed by the STABLE checklist key (src/reports/checklist.ts), not the
|
|
@@ -1097,7 +724,10 @@ interface ReportsTable {
|
|
|
1097
724
|
* holding a patch cannot accidentally write megabytes of HTML. */
|
|
1098
725
|
type ReportMirrorPatch = Partial<Pick<ReportsTable, "approved_to_send" | "approved_at" | "approved_by" | "send_override" | "override_reason" | "override_by" | "override_at" | "delivery_status" | "commentary" | "draft_ready" | "lighthouse_performance" | "lighthouse_accessibility" | "lighthouse_best_practices" | "lighthouse_seo" | "ga_users_current" | "ga_users_previous" | "search_found_page1" | "search_position" | "completed_on" | "sent_at" | "resend_message_id">>;
|
|
1099
726
|
|
|
1100
|
-
/** #539 Phase 5: the Turso write-through for the Reports write surface
|
|
727
|
+
/** #539 Phase 5: the Turso write-through for the Reports write surface — and,
|
|
728
|
+
* since #646 step 4, the surface itself: `create` MINTS nothing (the creator
|
|
729
|
+
* does) but it is the only place a report row comes into existence, and
|
|
730
|
+
* `forSite` is the drafting path's read.
|
|
1101
731
|
*
|
|
1102
732
|
* Before this, the only report mirrors were UPDATEs on the request path
|
|
1103
733
|
* (approve, override, delivery status, commentary). Everything the DRAFTING
|
|
@@ -1116,13 +746,38 @@ type ReportMirrorPatch = Partial<Pick<ReportsTable, "approved_to_send" | "approv
|
|
|
1116
746
|
* line means the wiring is gone, not that conditions were quiet.
|
|
1117
747
|
*/
|
|
1118
748
|
|
|
1119
|
-
/** The
|
|
1120
|
-
*
|
|
1121
|
-
* a caller holding `
|
|
1122
|
-
* state (row present, preview 404) this module exists to prevent.
|
|
749
|
+
/** The drafting path's whole report surface. Injected as ONE object rather than
|
|
750
|
+
* as separate parameters because they share a db handle and always travel
|
|
751
|
+
* together: a caller holding `create` but not `body` produces exactly the
|
|
752
|
+
* half-written state (row present, preview 404) this module exists to prevent.
|
|
753
|
+
*
|
|
754
|
+
* Since #646 step 4 this is no longer only a mirror. `create` is the PRIMARY
|
|
755
|
+
* write — Turso mints the report id and owns the row, and there is no Airtable
|
|
756
|
+
* record for it to shadow (see `src/reports/create-report.ts`) — and `forSite`
|
|
757
|
+
* is a READ the drafting path used to make against Airtable, which cannot see a
|
|
758
|
+
* report for a `site_<ULID>` site. `body` and `patch` keep their older meaning:
|
|
759
|
+
* write-throughs for state whose `rec…` rows Airtable may still shadow. The name
|
|
760
|
+
* is kept because every composition root and every injection site already uses
|
|
761
|
+
* it, and a rename would churn ten files to say what this comment says. */
|
|
1123
762
|
type ReportMirror = {
|
|
1124
|
-
/**
|
|
1125
|
-
|
|
763
|
+
/** Insert a brand-new report row and return what Turso stored. Not a mirror:
|
|
764
|
+
* the row exists nowhere else. */
|
|
765
|
+
create: (rec: {
|
|
766
|
+
id: string;
|
|
767
|
+
fields: Record<string, unknown>;
|
|
768
|
+
}) => Promise<ReportRow>;
|
|
769
|
+
/** A row AIRTABLE created, as Airtable echoed it back — the pre-step-4 shape.
|
|
770
|
+
* NO production path calls it any more: it pairs with the legacy Airtable
|
|
771
|
+
* `createDraft`, which nothing calls either. Both are kept rather than
|
|
772
|
+
* deleted because deleting from the Airtable layer is step 6, and both go
|
|
773
|
+
* together when it comes. */
|
|
774
|
+
created: (rec: {
|
|
775
|
+
id: string;
|
|
776
|
+
fields: Record<string, unknown>;
|
|
777
|
+
}) => Promise<void>;
|
|
778
|
+
/** Every report for one site — the single-queue rule's and the period
|
|
779
|
+
* derivation's read. */
|
|
780
|
+
forSite: (siteId: string) => Promise<ReportRow[]>;
|
|
1126
781
|
/** A freshly rendered body for an existing row. */
|
|
1127
782
|
body: (reportId: string, html: string) => Promise<void>;
|
|
1128
783
|
/** Columns just written to an existing row. */
|
|
@@ -1154,7 +809,10 @@ type ReportMirror = {
|
|
|
1154
809
|
* pass the EXACT FieldSet the Airtable writer returned, so the mirror can never
|
|
1155
810
|
* carry a different payload than the write it shadows. */
|
|
1156
811
|
type SiteMirror = {
|
|
1157
|
-
/** A row Airtable just CREATED, as Airtable echoed it back
|
|
812
|
+
/** A row Airtable just CREATED, as Airtable echoed it back. `ensure-site` used
|
|
813
|
+
* this until #646 step 3; it now creates sites in Turso directly
|
|
814
|
+
* (`src/fleet/ensure-site.ts`), and neither this nor `hasRow` has a caller left
|
|
815
|
+
* outside tests — both go with the Airtable layer in step 6.
|
|
1158
816
|
* Every other op is an UPDATE, which does nothing for a row that does not
|
|
1159
817
|
* exist yet — so without this a bootstrapped site is invisible to Turso and
|
|
1160
818
|
* every mirror the rest of the bootstrap fires reports `mirrored=missed`. */
|
|
@@ -1166,6 +824,13 @@ type SiteMirror = {
|
|
|
1166
824
|
health: (siteId: string, fields: Record<string, unknown>) => Promise<void>;
|
|
1167
825
|
/** Columns that live in `sites`. */
|
|
1168
826
|
site: (siteId: string, fields: Record<string, unknown>) => Promise<void>;
|
|
827
|
+
/** #645. Does Turso hold a row for this site id? A pure READ, so it is the one
|
|
828
|
+
* op here that neither logs a SITE_MIRROR line nor throws under the freeze —
|
|
829
|
+
* `ensure-site` uses it to decide whether to heal, and a probe that threw
|
|
830
|
+
* would sink the very command that repairs the gap. Creds-absent answers
|
|
831
|
+
* `true` ("assume present"), so a mirror that cannot read can never provoke
|
|
832
|
+
* a blind insert. */
|
|
833
|
+
hasRow: (siteId: string) => Promise<boolean>;
|
|
1169
834
|
};
|
|
1170
835
|
|
|
1171
836
|
type ShootOptions = {
|
|
@@ -1174,6 +839,9 @@ type ShootOptions = {
|
|
|
1174
839
|
height: number;
|
|
1175
840
|
deviceScaleFactor: number;
|
|
1176
841
|
settleMs: number;
|
|
842
|
+
/** Extra CSS selector(s) hidden before the shutter, for a site whose consent
|
|
843
|
+
* or interstitial UI the class/id heuristic misses. */
|
|
844
|
+
consentSelector?: string;
|
|
1177
845
|
};
|
|
1178
846
|
/** Injected browser IO. The real impl drives Playwright; tests pass a fake. */
|
|
1179
847
|
type Shooter = {
|
|
@@ -1187,8 +855,11 @@ type GenerateInput = {
|
|
|
1187
855
|
slug?: string;
|
|
1188
856
|
/** Injected browser IO (tests). */
|
|
1189
857
|
shooter?: Shooter;
|
|
1190
|
-
/** Per-site settle override for animation-heavy
|
|
858
|
+
/** Per-site settle override for animation-heavy homepages. */
|
|
1191
859
|
settleMs?: number;
|
|
860
|
+
/** Extra CSS selector(s) hidden before the shutter, for consent or
|
|
861
|
+
* interstitial UI the capture's class/id heuristic misses (#654). */
|
|
862
|
+
consentSelector?: string;
|
|
1192
863
|
};
|
|
1193
864
|
type GeneratedHeaderImage = {
|
|
1194
865
|
bytes: Uint8Array;
|
|
@@ -1337,6 +1008,25 @@ type ResendClient = {
|
|
|
1337
1008
|
|
|
1338
1009
|
type OrchestrateOptions = {
|
|
1339
1010
|
resend?: ResendClient;
|
|
1011
|
+
/**
|
|
1012
|
+
* #646 step 4: the send queue and the fleet roster, read from TURSO.
|
|
1013
|
+
*
|
|
1014
|
+
* Required rather than defaulted, for the reason the mirrors below are: this
|
|
1015
|
+
* function is called directly by tests, and a default would let one reach a
|
|
1016
|
+
* live store. The CLI wires `listSendableReports`/`listSites` over one
|
|
1017
|
+
* connection.
|
|
1018
|
+
*/
|
|
1019
|
+
sendable: () => Promise<ReportRow[]>;
|
|
1020
|
+
roster: () => Promise<WebsiteRow[]>;
|
|
1021
|
+
/**
|
|
1022
|
+
* The site's header plate, from `sites.header_image*` (design D5 made Turso its
|
|
1023
|
+
* source; the re-render path has read it from there since #643). `null` means
|
|
1024
|
+
* Turso holds no bytes for that site, and the send falls back to the site's
|
|
1025
|
+
* Airtable attachment — which is the ONLY reason this path still reads
|
|
1026
|
+
* Airtable, and why the fallback fetches ONE site's record rather than the
|
|
1027
|
+
* roster it used to get the signed url from.
|
|
1028
|
+
*/
|
|
1029
|
+
loadHeaderPlate: (siteId: string) => Promise<Uint8Array | null>;
|
|
1340
1030
|
/** #539 Phase 5: Turso write-through for the Websites row a Launch send
|
|
1341
1031
|
* updates. Injected rather than defaulted — this function is called directly
|
|
1342
1032
|
* by tests, and a default would open a real libSQL handle inside the suite. */
|
|
@@ -1349,7 +1039,7 @@ type OrchestrateOptions = {
|
|
|
1349
1039
|
* through `mirrorWrite` so the freeze switch owns the error semantics. */
|
|
1350
1040
|
reportSentMirror?: (reportId: string, sentAt: Date, messageId: string | null) => Promise<void>;
|
|
1351
1041
|
};
|
|
1352
|
-
declare function sendApprovedReports(options
|
|
1042
|
+
declare function sendApprovedReports(options: OrchestrateOptions): Promise<{
|
|
1353
1043
|
output: string;
|
|
1354
1044
|
code: number;
|
|
1355
1045
|
}>;
|
|
@@ -1452,6 +1142,15 @@ type SubmissionRow = {
|
|
|
1452
1142
|
* was attempted: a non-newsletter form, a spam row, a site with no destination
|
|
1453
1143
|
* configured, or a row written before 0005. See ingest.ts for the token grammar. */
|
|
1454
1144
|
fanoutStatus?: string | null;
|
|
1145
|
+
/** Resend's bounce classification, kept so a content rejection by the CLIENT's
|
|
1146
|
+
* mail filter can be told apart from a dead mailbox (#783). Null for a
|
|
1147
|
+
* complaint, and for every row written before migration 0018. */
|
|
1148
|
+
bounceType?: string | null;
|
|
1149
|
+
bounceSubType?: string | null;
|
|
1150
|
+
bounceMessage?: string | null;
|
|
1151
|
+
/** ISO-8601 of the operator saying "this address is not dead" (#783). The row
|
|
1152
|
+
* keeps its bounce record and stops counting toward the alarm. */
|
|
1153
|
+
bounceAckAt?: string | null;
|
|
1455
1154
|
};
|
|
1456
1155
|
|
|
1457
1156
|
type ScreenOutTotals = {
|
|
@@ -1474,6 +1173,13 @@ type AttentionItem = {
|
|
|
1474
1173
|
/** Stable identity for diffing: `vuln:<siteId>`, `delivery:<reportId>`. */
|
|
1475
1174
|
key: string;
|
|
1476
1175
|
kind: "vuln" | "delivery" | "renovate" | "lighthouse" | "ci" | "analytics" | "preflight" | "turnstile" | "notify-bounce"
|
|
1176
|
+
/** #645. Leads captured by the dead-letter because their site could not be
|
|
1177
|
+
* placed — a store outage during the lookup, or (since #645) a slug with no
|
|
1178
|
+
* Turso row at all. Until this kind existed a dropped lead had NO alarm
|
|
1179
|
+
* anywhere: the queue could fill and nothing said so. Keyed by SLUG, not by
|
|
1180
|
+
* site id, because the whole point of the worst case is that the slug
|
|
1181
|
+
* resolves to no site. */
|
|
1182
|
+
| "deadletter"
|
|
1477
1183
|
/** The nightly Prismic model sweep. THREE item flavors share this kind —
|
|
1478
1184
|
* `prismic-drift:` (repo and Prismic diverge), `prismic-unknown:` (the check
|
|
1479
1185
|
* ran and could not answer), `prismic-stale:` (nobody has re-established the
|
|
@@ -1612,6 +1318,17 @@ type CockpitModel = {
|
|
|
1612
1318
|
* invisible to every fleet op, so the Needs-you feed surfaces them as amber watch
|
|
1613
1319
|
* rows (optional for back-compat). */
|
|
1614
1320
|
unrecognizedStatus?: OffFleetSiteEntry[];
|
|
1321
|
+
/** #786. Attention items that belong to NO site card. The grid is built from
|
|
1322
|
+
* the visible sites and items are grouped onto it by `siteName`, so an item
|
|
1323
|
+
* naming a site the fleet does not have matched nothing and was dropped —
|
|
1324
|
+
* silently, on the one surface the operator actually watches.
|
|
1325
|
+
*
|
|
1326
|
+
* The collector that produces them is the one whose entire point is that the
|
|
1327
|
+
* site is missing: a dead letter for a slug resolving to no fleet row means
|
|
1328
|
+
* leads are being dropped RIGHT NOW. Kept general rather than
|
|
1329
|
+
* dead-letter-specific, so a future card-less item lands here instead of
|
|
1330
|
+
* vanishing the same way. Optional for back-compat with hand-built models. */
|
|
1331
|
+
cardless?: AttentionItem[];
|
|
1615
1332
|
};
|
|
1616
1333
|
/** The cockpit's alarm verdict for ONE site, for the /s/<slug> page header. */
|
|
1617
1334
|
type SiteAlarmContext = {
|
|
@@ -1702,4 +1419,26 @@ declare function loadPlate(): Promise<Uint8Array>;
|
|
|
1702
1419
|
/** Read a headline overlay (transparent PNG, ink-box cropped). */
|
|
1703
1420
|
declare function loadHeadline(kind: HeadlineKind): Promise<Uint8Array>;
|
|
1704
1421
|
|
|
1705
|
-
|
|
1422
|
+
/** The plate's pixel dimensions — Figma frame 600x800 exported at 4x. */
|
|
1423
|
+
declare const CANVAS: {
|
|
1424
|
+
readonly width: 2400;
|
|
1425
|
+
readonly height: 3200;
|
|
1426
|
+
};
|
|
1427
|
+
/** The MacBook Pro screen the site screenshot is pasted into — the area inside
|
|
1428
|
+
* the bezel, so the bezel stays visible around the content exactly as it does
|
|
1429
|
+
* in the hand-made headers. Aspect 1.6017 (16:10 to within 0.11%).
|
|
1430
|
+
*
|
|
1431
|
+
* Measured on plate-clean.png: content spans x 310..1655, y 1888..2727, with a
|
|
1432
|
+
* single anti-aliased blend pixel on the outside of the left, top and bottom
|
|
1433
|
+
* edges (x=309 rgb(5,10,8); y=1887 rgb(14,29,24); y=2727 rgb(27,50,74)). The
|
|
1434
|
+
* rect INCLUDES those blend pixels deliberately: each one is part baked
|
|
1435
|
+
* screenshot, so leaving it uncovered leaves a faint tinted line of the other
|
|
1436
|
+
* site, while covering it repaints one pixel of bezel edge and is invisible. */
|
|
1437
|
+
declare const SCREEN: {
|
|
1438
|
+
readonly x: 309;
|
|
1439
|
+
readonly y: 1887;
|
|
1440
|
+
readonly w: 1347;
|
|
1441
|
+
readonly h: 841;
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1444
|
+
export { ALL_AUDIT_NAMES, ALL_RECIPE_NAMES, type AirtableInventoryOptions, AuditName, AuditResult, BLURRED_CID, type BumpDepsOptions, type BundledImage, CANVAS, CHECK_CID, type ConvertToPnpmOptions, DEFAULT_INIT_STEPS, type DraftOptions, type DraftResult, type DueItem, type GenerateInput, type GeneratedHeaderImage, type HeaderImage, type InitOptions, type InitResult, type InitStep, type InitStepResult, InventoryProvider, type LighthouseScores, type LocalPathOptions, type OnboardAudit, type OnboardOptions, type OrchestrateOptions, RecipeName, RecipeResult, type RefreshHeaderDeps, type RenderResult, type ReportData, type ReportType, SCREEN, Site, type UpgradeSvelte4to5Options, a11yAudit, a11yFixturesPage, bumpDeps, convertToPnpm, depsAudit, domainFromUrl, draftReportForSite, findDueReports, fromAirtableBase, fromJsonFile, generateHeaderImage, init, isRecipeName, lighthouseAudit, lintAudit, loadBundledImages, loadHeadline, loadPlate, localPath, onboard, renderCockpitHtml, renderReportHtml, renderSiteDashboardHtml, runAudits, runAuditsAcross, securityAudit, selfCaretRange, selfPackageVersion, sendApprovedReports, svelteCodemods, upgradeSvelte4to5, verifyBasicAuth };
|