@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.
Files changed (316) hide show
  1. package/README.md +41 -7
  2. package/dist/{announce-CLQYX5I4.js → announce-5ZD2SBGD.js} +39 -31
  3. package/dist/announce-5ZD2SBGD.js.map +1 -0
  4. package/dist/attachments-JFGFQRXQ.js +10 -0
  5. package/dist/{blux-4KNXUP2K.js → blux-NXQLMS4W.js} +1 -1
  6. package/dist/{bump-deps-C5G2EFBB.js → bump-deps-775VLDYB.js} +6 -6
  7. package/dist/{chunk-FUWFLAWQ.js → chunk-3RLDX3Q2.js} +5 -5
  8. package/dist/{chunk-XHHMM5HX.js → chunk-43SW3FGW.js} +63 -1
  9. package/dist/chunk-43SW3FGW.js.map +1 -0
  10. package/dist/{chunk-R53VL3RI.js → chunk-5CJVUPJU.js} +1 -1
  11. package/dist/{chunk-R53VL3RI.js.map → chunk-5CJVUPJU.js.map} +1 -1
  12. package/dist/{chunk-S7RYFUIK.js → chunk-6PGXKN6F.js} +2 -2
  13. package/dist/{chunk-HTABUCF4.js → chunk-6THEZQLA.js} +3 -3
  14. package/dist/chunk-A5QKNOXW.js +72 -0
  15. package/dist/chunk-A5QKNOXW.js.map +1 -0
  16. package/dist/chunk-ASLDCWBF.js +41 -0
  17. package/dist/chunk-ASLDCWBF.js.map +1 -0
  18. package/dist/{chunk-CWXTNPNZ.js → chunk-AYDQQBNG.js} +3 -3
  19. package/dist/chunk-AYDQQBNG.js.map +1 -0
  20. package/dist/{chunk-WVNDEYXL.js → chunk-BINFZQ2T.js} +57 -6
  21. package/dist/chunk-BINFZQ2T.js.map +1 -0
  22. package/dist/{chunk-2NQUCS7O.js → chunk-BIYQN7FH.js} +3 -1
  23. package/dist/{chunk-2NQUCS7O.js.map → chunk-BIYQN7FH.js.map} +1 -1
  24. package/dist/{chunk-YLYXW5PH.js → chunk-CXICCLNM.js} +34 -4
  25. package/dist/chunk-CXICCLNM.js.map +1 -0
  26. package/dist/{chunk-BYGPUUCT.js → chunk-DRNZVORX.js} +66 -30
  27. package/dist/chunk-DRNZVORX.js.map +1 -0
  28. package/dist/{chunk-LM2NHRCJ.js → chunk-DYTYPKFN.js} +4 -4
  29. package/dist/chunk-DYTYPKFN.js.map +1 -0
  30. package/dist/{chunk-DFKBTBO3.js → chunk-EN6CTBUN.js} +35 -6
  31. package/dist/chunk-EN6CTBUN.js.map +1 -0
  32. package/dist/{chunk-5EEMTJMT.js → chunk-FHFXJ3EM.js} +8 -6
  33. package/dist/chunk-FHFXJ3EM.js.map +1 -0
  34. package/dist/{chunk-Z2K4JPQ3.js → chunk-FP6HOW6J.js} +10 -7
  35. package/dist/chunk-FP6HOW6J.js.map +1 -0
  36. package/dist/{chunk-2LYOAB2E.js → chunk-HSMN35LU.js} +2 -2
  37. package/dist/chunk-ICSRWW5Q.js +148 -0
  38. package/dist/chunk-ICSRWW5Q.js.map +1 -0
  39. package/dist/{chunk-FSGICFXB.js → chunk-IDBPII6G.js} +17 -5
  40. package/dist/chunk-IDBPII6G.js.map +1 -0
  41. package/dist/{chunk-C3IQQKXL.js → chunk-IOTOOTII.js} +121 -1
  42. package/dist/{chunk-C3IQQKXL.js.map → chunk-IOTOOTII.js.map} +1 -1
  43. package/dist/{chunk-BCKEP5S6.js → chunk-JHJNNJLG.js} +2 -2
  44. package/dist/{chunk-TO7DJYLZ.js → chunk-L3S3QZXL.js} +178 -39
  45. package/dist/chunk-L3S3QZXL.js.map +1 -0
  46. package/dist/{chunk-WSJ7RO54.js → chunk-LAG6IP7Y.js} +23 -5
  47. package/dist/chunk-LAG6IP7Y.js.map +1 -0
  48. package/dist/{chunk-WJMPCVOR.js → chunk-LAJ3FF54.js} +12 -4
  49. package/dist/chunk-LAJ3FF54.js.map +1 -0
  50. package/dist/{chunk-2ZAZ7ETT.js → chunk-LDHRIQUW.js} +32 -18
  51. package/dist/chunk-LDHRIQUW.js.map +1 -0
  52. package/dist/{chunk-6R56OKJZ.js → chunk-LF2TJN4X.js} +2 -2
  53. package/dist/chunk-LF2TJN4X.js.map +1 -0
  54. package/dist/{chunk-ZQV7UQNE.js → chunk-LUF52EIY.js} +2 -2
  55. package/dist/{chunk-5UINJNAJ.js → chunk-LZMAG73U.js} +34 -21
  56. package/dist/chunk-LZMAG73U.js.map +1 -0
  57. package/dist/{chunk-VSGMCCGQ.js → chunk-MMSMZC7S.js} +2 -2
  58. package/dist/chunk-MVKNU4QD.js +37 -0
  59. package/dist/chunk-MVKNU4QD.js.map +1 -0
  60. package/dist/{chunk-XPJQXSC4.js → chunk-P7323YVW.js} +27 -5
  61. package/dist/chunk-P7323YVW.js.map +1 -0
  62. package/dist/{chunk-KJRVMMM3.js → chunk-PARKXDXI.js} +36 -5
  63. package/dist/chunk-PARKXDXI.js.map +1 -0
  64. package/dist/{chunk-4763KQ6O.js → chunk-PXRN2MER.js} +2 -2
  65. package/dist/{chunk-WMBLR5VA.js → chunk-PZZ6HM5T.js} +3 -3
  66. package/dist/{chunk-TR3HFH6J.js → chunk-QFSL2L2B.js} +67 -10
  67. package/dist/chunk-QFSL2L2B.js.map +1 -0
  68. package/dist/chunk-RQJFGK3A.js +51 -0
  69. package/dist/chunk-RQJFGK3A.js.map +1 -0
  70. package/dist/{chunk-3Z6X3BHU.js → chunk-TC4GANMX.js} +53 -150
  71. package/dist/chunk-TC4GANMX.js.map +1 -0
  72. package/dist/{chunk-F3JWOPTG.js → chunk-TEMQPSCM.js} +45 -105
  73. package/dist/chunk-TEMQPSCM.js.map +1 -0
  74. package/dist/chunk-TJLKWQOX.js +52 -0
  75. package/dist/chunk-TJLKWQOX.js.map +1 -0
  76. package/dist/{chunk-CJ2RMTT7.js → chunk-TV76A6GN.js} +2 -2
  77. package/dist/{chunk-KZRR4NFG.js → chunk-TVZ6QCOE.js} +3 -3
  78. package/dist/{chunk-BVEDKMNG.js → chunk-U2ZI6G7H.js} +29 -11
  79. package/dist/chunk-U2ZI6G7H.js.map +1 -0
  80. package/dist/chunk-UPE6D4AT.js +69 -0
  81. package/dist/chunk-UPE6D4AT.js.map +1 -0
  82. package/dist/{chunk-R5IMFAFR.js → chunk-VMGHQUTV.js} +7 -16
  83. package/dist/chunk-VMGHQUTV.js.map +1 -0
  84. package/dist/chunk-VQMAAQ5M.js +53 -0
  85. package/dist/chunk-VQMAAQ5M.js.map +1 -0
  86. package/dist/{chunk-AVEQUR44.js → chunk-WMF5S2MB.js} +60 -17
  87. package/dist/chunk-WMF5S2MB.js.map +1 -0
  88. package/dist/{chunk-SVAAONYB.js → chunk-WQLNUEZL.js} +12 -2
  89. package/dist/{chunk-SVAAONYB.js.map → chunk-WQLNUEZL.js.map} +1 -1
  90. package/dist/{chunk-XN37VTDB.js → chunk-X56LAKPR.js} +3 -3
  91. package/dist/chunk-X56LAKPR.js.map +1 -0
  92. package/dist/{chunk-ZCL7C5LH.js → chunk-Y6FCXRIC.js} +1661 -387
  93. package/dist/chunk-Y6FCXRIC.js.map +1 -0
  94. package/dist/{chunk-2SLED3NB.js → chunk-YDZ7XGPZ.js} +1 -1
  95. package/dist/{chunk-2SLED3NB.js.map → chunk-YDZ7XGPZ.js.map} +1 -1
  96. package/dist/{chunk-IY6256GK.js → chunk-YJBSB4LP.js} +6 -1
  97. package/dist/chunk-YJBSB4LP.js.map +1 -0
  98. package/dist/{chunk-BI2VI6EM.js → chunk-YXWBM26P.js} +2 -2
  99. package/dist/{chunk-QF6IQQFP.js → chunk-Z7FDJ35L.js} +18 -12
  100. package/dist/chunk-Z7FDJ35L.js.map +1 -0
  101. package/dist/cli/bin.js +111 -51
  102. package/dist/cli/bin.js.map +1 -1
  103. package/dist/cli/commands/audit.d.ts +33 -3
  104. package/dist/cli/commands/audit.js +28 -25
  105. package/dist/cli/commands/audit.js.map +1 -1
  106. package/dist/client-DGTO65WB.js +11 -0
  107. package/dist/configs/playwright-a11y.d.ts +11 -1
  108. package/dist/configs/playwright-a11y.js +3 -1
  109. package/dist/{convert-to-pnpm-YTFREUJK.js → convert-to-pnpm-KLWA53N5.js} +6 -6
  110. package/dist/{db-XKZYDCKM.js → db-II5WAK4D.js} +45 -20
  111. package/dist/db-II5WAK4D.js.map +1 -0
  112. package/dist/deadletter-G4M3HSVM.js +17 -0
  113. package/dist/{digest-7UBGUBRK.js → digest-CWKK2DMR.js} +56 -32
  114. package/dist/digest-CWKK2DMR.js.map +1 -0
  115. package/dist/{digest-collectors-DJFN5ZDK.js → digest-collectors-CYTN2EUX.js} +17 -12
  116. package/dist/{digest-state-3KHZF7GD.js → digest-state-ZDPKR7MW.js} +18 -2
  117. package/dist/digest-state-ZDPKR7MW.js.map +1 -0
  118. package/dist/ensure-site-2QZHFVQ3.js +70 -0
  119. package/dist/ensure-site-2QZHFVQ3.js.map +1 -0
  120. package/dist/ensure-site-JEKV2ODE.js +105 -0
  121. package/dist/ensure-site-JEKV2ODE.js.map +1 -0
  122. package/dist/{ensure-site-OAAE5YE2.js → ensure-site-OO4UPWNQ.js} +49 -44
  123. package/dist/ensure-site-OO4UPWNQ.js.map +1 -0
  124. package/dist/fleet-events-CkOZpMVC.d.ts +435 -0
  125. package/dist/{fleet-state-UEVZ3X3J.js → fleet-state-RJROYXKO.js} +19 -7
  126. package/dist/{forms-notify-target-UC6PF3AE.js → forms-notify-target-X6UEOI2M.js} +19 -15
  127. package/dist/forms-notify-target-X6UEOI2M.js.map +1 -0
  128. package/dist/{freeze-A6MUCZU4.js → freeze-GUQ43EAU.js} +2 -2
  129. package/dist/{github-signals-TX5FPYP6.js → github-signals-QIRTHHET.js} +22 -17
  130. package/dist/github-signals-QIRTHHET.js.map +1 -0
  131. package/dist/{header-image-PSPT7CUM.js → header-image-H7ZJAV26.js} +15 -18
  132. package/dist/header-image-H7ZJAV26.js.map +1 -0
  133. package/dist/{health-endpoint-KVCJYWET.js → health-endpoint-BJ6BKRHF.js} +8 -7
  134. package/dist/{health-endpoint-KVCJYWET.js.map → health-endpoint-BJ6BKRHF.js.map} +1 -1
  135. package/dist/{health-mirror-XJAKA3EY.js → health-mirror-KU3G7V2Y.js} +10 -10
  136. package/dist/{import-airtable-TAKSN4NV.js → import-airtable-UBF5GYAL.js} +3 -3
  137. package/dist/index.d.ts +158 -419
  138. package/dist/index.js +91 -46
  139. package/dist/index.js.map +1 -1
  140. package/dist/{init-FFE4FCO2.js → init-GOWDA5QS.js} +19 -18
  141. package/dist/{init-FFE4FCO2.js.map → init-GOWDA5QS.js.map} +1 -1
  142. package/dist/{launch-UD36AHUN.js → launch-7N3X2MXB.js} +229 -79
  143. package/dist/launch-7N3X2MXB.js.map +1 -0
  144. package/dist/{lighthouse-VHI77PFB.js → lighthouse-52WSPZ5D.js} +2 -2
  145. package/dist/lighthouse-airtable-M45OPVRV.js +14 -0
  146. package/dist/match-harness-GBCDSVPS.js +417 -0
  147. package/dist/match-harness-GBCDSVPS.js.map +1 -0
  148. package/dist/migrate-XZ7U5DFC.js +7 -0
  149. package/dist/{notify-IISTHNBR.js → notify-K3WVH3DM.js} +4 -4
  150. package/dist/{onboard-TM2KESGF.js → onboard-JQQIMQW7.js} +6 -6
  151. package/dist/{orchestrate-HYVQPRCE.js → orchestrate-L2A5BZFY.js} +13 -10
  152. package/dist/parity-2JGVUCZD.js +14 -0
  153. package/dist/{pipeline-YROAY6DT.js → pipeline-UUPXOS2J.js} +3 -3
  154. package/dist/{preflight-RYIP54NY.js → preflight-O7Q6FWHU.js} +35 -11
  155. package/dist/preflight-O7Q6FWHU.js.map +1 -0
  156. package/dist/{prismic-ci-6GKKZGB5.js → prismic-ci-NAPWOXXD.js} +39 -9
  157. package/dist/prismic-ci-NAPWOXXD.js.map +1 -0
  158. package/dist/{prismic-models-P6FWWVRS.js → prismic-models-LL6ORTQ2.js} +20 -17
  159. package/dist/prismic-models-LL6ORTQ2.js.map +1 -0
  160. package/dist/prospect/types.d.ts +72 -0
  161. package/dist/prospect/types.js +1 -1
  162. package/dist/{prospect-audit-PRHU53HS.js → prospect-audit-FMPGQIRQ.js} +16 -7
  163. package/dist/prospect-audit-FMPGQIRQ.js.map +1 -0
  164. package/dist/{prospect-audits-R3LWF6U7.js → prospect-audits-IZVQY3OQ.js} +4 -2
  165. package/dist/protection-audit-YXJKFU6O.js +413 -0
  166. package/dist/protection-audit-YXJKFU6O.js.map +1 -0
  167. package/dist/recipes/sync-configs.js +3 -3
  168. package/dist/{render-YGNGTX3W.js → render-MHUUHPLN.js} +36 -9
  169. package/dist/render-MHUUHPLN.js.map +1 -0
  170. package/dist/{render-from-row-IFSBHWDH.js → render-from-row-75JTED2Z.js} +6 -4
  171. package/dist/{renovate-dispatch-U5Q52SKT.js → renovate-dispatch-2IHAZDVA.js} +14 -9
  172. package/dist/{renovate-dispatch-U5Q52SKT.js.map → renovate-dispatch-2IHAZDVA.js.map} +1 -1
  173. package/dist/{replay-PCSQOGCZ.js → replay-4FVFOMHH.js} +10 -23
  174. package/dist/replay-4FVFOMHH.js.map +1 -0
  175. package/dist/{report-LQS4ECTM.js → report-IAHXN5CW.js} +103 -57
  176. package/dist/report-IAHXN5CW.js.map +1 -0
  177. package/dist/{report-mirror-HDTOJE64.js → report-mirror-4QM57LMS.js} +34 -12
  178. package/dist/report-mirror-4QM57LMS.js.map +1 -0
  179. package/dist/roster-GDNSIRAK.js +19 -0
  180. package/dist/roster-GDNSIRAK.js.map +1 -0
  181. package/dist/{schema-A4WCPIF4.js → schema-KWUQEZ5O.js} +1 -1
  182. package/dist/schema-KWUQEZ5O.js.map +1 -0
  183. package/dist/{self-updating-MWXIZLL7.js → self-updating-ZUWPGYUP.js} +8 -7
  184. package/dist/{self-updating-MWXIZLL7.js.map → self-updating-ZUWPGYUP.js.map} +1 -1
  185. package/dist/{selftest-VXTHRPRN.js → selftest-G4W3LIBQ.js} +21 -17
  186. package/dist/{selftest-VXTHRPRN.js.map → selftest-G4W3LIBQ.js.map} +1 -1
  187. package/dist/site-create-ZU3ACBTO.js +45 -0
  188. package/dist/site-create-ZU3ACBTO.js.map +1 -0
  189. package/dist/site-lookup-DTOLJ4EA.js +27 -0
  190. package/dist/site-lookup-DTOLJ4EA.js.map +1 -0
  191. package/dist/{site-mirror-WON4FTJ2.js → site-mirror-WR7ACXOV.js} +26 -12
  192. package/dist/site-mirror-WR7ACXOV.js.map +1 -0
  193. package/dist/{smoke-suite-7DGITCTZ.js → smoke-suite-WAUPI6EJ.js} +8 -7
  194. package/dist/{smoke-suite-7DGITCTZ.js.map → smoke-suite-WAUPI6EJ.js.map} +1 -1
  195. package/dist/{submissions-OVZPVBYG.js → submissions-2SHCFOKD.js} +12 -7
  196. package/dist/submissions-2SHCFOKD.js.map +1 -0
  197. package/dist/{submissions-3I3GAQAX.js → submissions-JDZP35JM.js} +49 -9
  198. package/dist/submissions-JDZP35JM.js.map +1 -0
  199. package/dist/{svelte-codemods-WSV2FGNG.js → svelte-codemods-VOLOKKFI.js} +6 -6
  200. package/dist/{sync-K3PKHVLH.js → sync-F4USL4K5.js} +6 -6
  201. package/dist/{sync-configs-RRIHNLIJ.js → sync-configs-OXSWKVZ2.js} +6 -6
  202. package/dist/turso-KQKBBQCK.js +24 -0
  203. package/dist/turso-KQKBBQCK.js.map +1 -0
  204. package/dist/{upgrade-VTD6V4HS.js → upgrade-EVAL3JTO.js} +6 -6
  205. package/dist/util/git.d.ts +49 -10
  206. package/dist/util/git.js +1 -1
  207. package/dist/{webflow-IRKOIT7S.js → webflow-624FEBFD.js} +4 -4
  208. package/dist/{websites-TB4TCAWM.js → websites-Y6FN2XFD.js} +27 -20
  209. package/dist/{write-audits-to-airtable-53EVXKMU.js → write-audits-to-airtable-TI3JMWSY.js} +7 -5
  210. package/package.json +3 -2
  211. package/dist/airtable-JGCPS7JH.js +0 -9
  212. package/dist/announce-CLQYX5I4.js.map +0 -1
  213. package/dist/attachments-NLZIJ5NU.js +0 -9
  214. package/dist/chunk-2ZAZ7ETT.js.map +0 -1
  215. package/dist/chunk-3Z6X3BHU.js.map +0 -1
  216. package/dist/chunk-5EEMTJMT.js.map +0 -1
  217. package/dist/chunk-5GUJ36TL.js +0 -53
  218. package/dist/chunk-5GUJ36TL.js.map +0 -1
  219. package/dist/chunk-5UINJNAJ.js.map +0 -1
  220. package/dist/chunk-6R56OKJZ.js.map +0 -1
  221. package/dist/chunk-AVEQUR44.js.map +0 -1
  222. package/dist/chunk-BVEDKMNG.js.map +0 -1
  223. package/dist/chunk-BYGPUUCT.js.map +0 -1
  224. package/dist/chunk-CWXTNPNZ.js.map +0 -1
  225. package/dist/chunk-DFKBTBO3.js.map +0 -1
  226. package/dist/chunk-F3JWOPTG.js.map +0 -1
  227. package/dist/chunk-FSGICFXB.js.map +0 -1
  228. package/dist/chunk-GASBX52O.js +0 -12
  229. package/dist/chunk-GASBX52O.js.map +0 -1
  230. package/dist/chunk-IY6256GK.js.map +0 -1
  231. package/dist/chunk-KJRVMMM3.js.map +0 -1
  232. package/dist/chunk-LM2NHRCJ.js.map +0 -1
  233. package/dist/chunk-QF6IQQFP.js.map +0 -1
  234. package/dist/chunk-R5IMFAFR.js.map +0 -1
  235. package/dist/chunk-TO7DJYLZ.js.map +0 -1
  236. package/dist/chunk-TR3HFH6J.js.map +0 -1
  237. package/dist/chunk-WJMPCVOR.js.map +0 -1
  238. package/dist/chunk-WSJ7RO54.js.map +0 -1
  239. package/dist/chunk-WVNDEYXL.js.map +0 -1
  240. package/dist/chunk-XHHMM5HX.js.map +0 -1
  241. package/dist/chunk-XN37VTDB.js.map +0 -1
  242. package/dist/chunk-XPJQXSC4.js.map +0 -1
  243. package/dist/chunk-YFAXOD7Z.js +0 -42
  244. package/dist/chunk-YFAXOD7Z.js.map +0 -1
  245. package/dist/chunk-YLYXW5PH.js.map +0 -1
  246. package/dist/chunk-Z2K4JPQ3.js.map +0 -1
  247. package/dist/chunk-ZCL7C5LH.js.map +0 -1
  248. package/dist/client-G2WGWPCA.js +0 -11
  249. package/dist/db-XKZYDCKM.js.map +0 -1
  250. package/dist/digest-7UBGUBRK.js.map +0 -1
  251. package/dist/digest-state-3KHZF7GD.js.map +0 -1
  252. package/dist/ensure-site-OAAE5YE2.js.map +0 -1
  253. package/dist/fleet-events-cF2Om88w.d.ts +0 -24
  254. package/dist/forms-notify-target-UC6PF3AE.js.map +0 -1
  255. package/dist/github-signals-TX5FPYP6.js.map +0 -1
  256. package/dist/header-image-PSPT7CUM.js.map +0 -1
  257. package/dist/launch-UD36AHUN.js.map +0 -1
  258. package/dist/lighthouse-airtable-YMH4UA7R.js +0 -12
  259. package/dist/match-harness-QRG6XZAR.js +0 -70
  260. package/dist/match-harness-QRG6XZAR.js.map +0 -1
  261. package/dist/migrate-Y7R4CESL.js +0 -7
  262. package/dist/parity-CAJ477PS.js +0 -14
  263. package/dist/preflight-RYIP54NY.js.map +0 -1
  264. package/dist/prismic-ci-6GKKZGB5.js.map +0 -1
  265. package/dist/prismic-models-P6FWWVRS.js.map +0 -1
  266. package/dist/prospect-audit-PRHU53HS.js.map +0 -1
  267. package/dist/protection-audit-SJO53MEQ.js +0 -168
  268. package/dist/protection-audit-SJO53MEQ.js.map +0 -1
  269. package/dist/render-YGNGTX3W.js.map +0 -1
  270. package/dist/replay-PCSQOGCZ.js.map +0 -1
  271. package/dist/report-LQS4ECTM.js.map +0 -1
  272. package/dist/report-mirror-HDTOJE64.js.map +0 -1
  273. package/dist/schema-A4WCPIF4.js.map +0 -1
  274. package/dist/site-mirror-WON4FTJ2.js.map +0 -1
  275. package/dist/submissions-3I3GAQAX.js.map +0 -1
  276. package/dist/submissions-OVZPVBYG.js.map +0 -1
  277. /package/dist/{airtable-JGCPS7JH.js.map → attachments-JFGFQRXQ.js.map} +0 -0
  278. /package/dist/{blux-4KNXUP2K.js.map → blux-NXQLMS4W.js.map} +0 -0
  279. /package/dist/{bump-deps-C5G2EFBB.js.map → bump-deps-775VLDYB.js.map} +0 -0
  280. /package/dist/{chunk-FUWFLAWQ.js.map → chunk-3RLDX3Q2.js.map} +0 -0
  281. /package/dist/{chunk-S7RYFUIK.js.map → chunk-6PGXKN6F.js.map} +0 -0
  282. /package/dist/{chunk-HTABUCF4.js.map → chunk-6THEZQLA.js.map} +0 -0
  283. /package/dist/{chunk-2LYOAB2E.js.map → chunk-HSMN35LU.js.map} +0 -0
  284. /package/dist/{chunk-BCKEP5S6.js.map → chunk-JHJNNJLG.js.map} +0 -0
  285. /package/dist/{chunk-ZQV7UQNE.js.map → chunk-LUF52EIY.js.map} +0 -0
  286. /package/dist/{chunk-VSGMCCGQ.js.map → chunk-MMSMZC7S.js.map} +0 -0
  287. /package/dist/{chunk-4763KQ6O.js.map → chunk-PXRN2MER.js.map} +0 -0
  288. /package/dist/{chunk-WMBLR5VA.js.map → chunk-PZZ6HM5T.js.map} +0 -0
  289. /package/dist/{chunk-CJ2RMTT7.js.map → chunk-TV76A6GN.js.map} +0 -0
  290. /package/dist/{chunk-KZRR4NFG.js.map → chunk-TVZ6QCOE.js.map} +0 -0
  291. /package/dist/{chunk-BI2VI6EM.js.map → chunk-YXWBM26P.js.map} +0 -0
  292. /package/dist/{attachments-NLZIJ5NU.js.map → client-DGTO65WB.js.map} +0 -0
  293. /package/dist/{convert-to-pnpm-YTFREUJK.js.map → convert-to-pnpm-KLWA53N5.js.map} +0 -0
  294. /package/dist/{client-G2WGWPCA.js.map → deadletter-G4M3HSVM.js.map} +0 -0
  295. /package/dist/{digest-collectors-DJFN5ZDK.js.map → digest-collectors-CYTN2EUX.js.map} +0 -0
  296. /package/dist/{fleet-state-UEVZ3X3J.js.map → fleet-state-RJROYXKO.js.map} +0 -0
  297. /package/dist/{freeze-A6MUCZU4.js.map → freeze-GUQ43EAU.js.map} +0 -0
  298. /package/dist/{health-mirror-XJAKA3EY.js.map → health-mirror-KU3G7V2Y.js.map} +0 -0
  299. /package/dist/{import-airtable-TAKSN4NV.js.map → import-airtable-UBF5GYAL.js.map} +0 -0
  300. /package/dist/{lighthouse-VHI77PFB.js.map → lighthouse-52WSPZ5D.js.map} +0 -0
  301. /package/dist/{lighthouse-airtable-YMH4UA7R.js.map → lighthouse-airtable-M45OPVRV.js.map} +0 -0
  302. /package/dist/{migrate-Y7R4CESL.js.map → migrate-XZ7U5DFC.js.map} +0 -0
  303. /package/dist/{notify-IISTHNBR.js.map → notify-K3WVH3DM.js.map} +0 -0
  304. /package/dist/{onboard-TM2KESGF.js.map → onboard-JQQIMQW7.js.map} +0 -0
  305. /package/dist/{orchestrate-HYVQPRCE.js.map → orchestrate-L2A5BZFY.js.map} +0 -0
  306. /package/dist/{parity-CAJ477PS.js.map → parity-2JGVUCZD.js.map} +0 -0
  307. /package/dist/{pipeline-YROAY6DT.js.map → pipeline-UUPXOS2J.js.map} +0 -0
  308. /package/dist/{prospect-audits-R3LWF6U7.js.map → prospect-audits-IZVQY3OQ.js.map} +0 -0
  309. /package/dist/{render-from-row-IFSBHWDH.js.map → render-from-row-75JTED2Z.js.map} +0 -0
  310. /package/dist/{svelte-codemods-WSV2FGNG.js.map → svelte-codemods-VOLOKKFI.js.map} +0 -0
  311. /package/dist/{sync-K3PKHVLH.js.map → sync-F4USL4K5.js.map} +0 -0
  312. /package/dist/{sync-configs-RRIHNLIJ.js.map → sync-configs-OXSWKVZ2.js.map} +0 -0
  313. /package/dist/{upgrade-VTD6V4HS.js.map → upgrade-EVAL3JTO.js.map} +0 -0
  314. /package/dist/{webflow-IRKOIT7S.js.map → webflow-624FEBFD.js.map} +0 -0
  315. /package/dist/{websites-TB4TCAWM.js.map → websites-Y6FN2XFD.js.map} +0 -0
  316. /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-cF2Om88w.js';
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
- relationship: "direct" | "transitive" | null;
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
- * The merge had NO clean reverse map while both vocabularies coexisted, which
535
- * is why `toAirtableStatus` had to pick one archived name deliberately. With the
536
- * old names retired there is nothing left to pick between, and no code path
537
- * feeds operator-supplied text through it anyway (see
538
- * `src/recipes/forms-notify-target.ts`, which writes `--restore` verbatim).
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
- * THE SHAPE OF THE TRANSITION (three stages):
541
- *
542
- * stage 1 (DONE) code speaks the NEW vocabulary internally; reads canonicalize
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
- type NotifyRouting = {
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 three shapes a report write takes. Injected as ONE object rather than
1120
- * three parameters because they share a db handle and always travel together:
1121
- * a caller holding `created` but not `body` produces exactly the half-mirrored
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
- /** A row Airtable just CREATED, as Airtable echoed it back. */
1125
- created: CreatedDraftMirror;
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 (`ensure-site`).
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 or consent-gated homepages. */
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?: OrchestrateOptions): Promise<{
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
- export { ALL_AUDIT_NAMES, ALL_RECIPE_NAMES, type AirtableInventoryOptions, AuditName, AuditResult, BLURRED_CID, type BumpDepsOptions, type BundledImage, 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, 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 };
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 };