@reddoorla/maintenance 0.95.0 → 0.96.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 (272) hide show
  1. package/README.md +37 -2
  2. package/dist/airtable-SJV4ZSMS.js +9 -0
  3. package/dist/{announce-PGT4SZZB.js → announce-45HVP4J4.js} +7 -7
  4. package/dist/{blux-4KNXUP2K.js → blux-RUFMNOUJ.js} +5 -5
  5. package/dist/{bump-deps-C5G2EFBB.js → bump-deps-EL3TKMIL.js} +6 -6
  6. package/dist/{chunk-XN37VTDB.js → chunk-37B4LVB3.js} +2 -2
  7. package/dist/{chunk-BVEDKMNG.js → chunk-3EA43S3R.js} +28 -10
  8. package/dist/chunk-3EA43S3R.js.map +1 -0
  9. package/dist/{chunk-XHHMM5HX.js → chunk-43SW3FGW.js} +63 -1
  10. package/dist/chunk-43SW3FGW.js.map +1 -0
  11. package/dist/{chunk-WMBLR5VA.js → chunk-44SDGPGQ.js} +3 -3
  12. package/dist/chunk-4UTJ4G6P.js +52 -0
  13. package/dist/chunk-4UTJ4G6P.js.map +1 -0
  14. package/dist/{chunk-R53VL3RI.js → chunk-5CJVUPJU.js} +1 -1
  15. package/dist/{chunk-R53VL3RI.js.map → chunk-5CJVUPJU.js.map} +1 -1
  16. package/dist/{chunk-4AIYWWKV.js → chunk-62YWOFVN.js} +36 -5
  17. package/dist/chunk-62YWOFVN.js.map +1 -0
  18. package/dist/{chunk-22GKJO5F.js → chunk-6INOBNRO.js} +2 -2
  19. package/dist/{chunk-BYGPUUCT.js → chunk-72FJZ6LO.js} +43 -11
  20. package/dist/chunk-72FJZ6LO.js.map +1 -0
  21. package/dist/{chunk-5GUJ36TL.js → chunk-74QRWE6G.js} +2 -2
  22. package/dist/chunk-A5QKNOXW.js +72 -0
  23. package/dist/chunk-A5QKNOXW.js.map +1 -0
  24. package/dist/{chunk-2NQUCS7O.js → chunk-BIYQN7FH.js} +3 -1
  25. package/dist/{chunk-2NQUCS7O.js.map → chunk-BIYQN7FH.js.map} +1 -1
  26. package/dist/{chunk-S7RYFUIK.js → chunk-CA6ADGOC.js} +2 -2
  27. package/dist/chunk-CGQZFQAY.js +38 -0
  28. package/dist/chunk-CGQZFQAY.js.map +1 -0
  29. package/dist/{chunk-YLYXW5PH.js → chunk-CXICCLNM.js} +34 -4
  30. package/dist/chunk-CXICCLNM.js.map +1 -0
  31. package/dist/{chunk-KZRR4NFG.js → chunk-D3CTOCUR.js} +3 -3
  32. package/dist/{chunk-CWXTNPNZ.js → chunk-DVJNYPFR.js} +3 -3
  33. package/dist/chunk-DVJNYPFR.js.map +1 -0
  34. package/dist/{chunk-AVEQUR44.js → chunk-EASYCD6F.js} +60 -17
  35. package/dist/chunk-EASYCD6F.js.map +1 -0
  36. package/dist/{chunk-BCKEP5S6.js → chunk-ECDJDHKT.js} +2 -2
  37. package/dist/{chunk-DMPHP7UP.js → chunk-EQQ4H6L3.js} +2 -2
  38. package/dist/{chunk-WVNDEYXL.js → chunk-GEUC5VGM.js} +11 -5
  39. package/dist/chunk-GEUC5VGM.js.map +1 -0
  40. package/dist/{chunk-Z2K4JPQ3.js → chunk-H445EH33.js} +2 -2
  41. package/dist/chunk-IHHAYXKY.js +351 -0
  42. package/dist/chunk-IHHAYXKY.js.map +1 -0
  43. package/dist/{chunk-FUWFLAWQ.js → chunk-IMYL67JV.js} +3 -3
  44. package/dist/{chunk-3Z6X3BHU.js → chunk-KN52PM63.js} +7 -2
  45. package/dist/{chunk-3Z6X3BHU.js.map → chunk-KN52PM63.js.map} +1 -1
  46. package/dist/{chunk-WJMPCVOR.js → chunk-LAJ3FF54.js} +12 -4
  47. package/dist/chunk-LAJ3FF54.js.map +1 -0
  48. package/dist/{chunk-5UINJNAJ.js → chunk-MZZDMBDT.js} +16 -3
  49. package/dist/chunk-MZZDMBDT.js.map +1 -0
  50. package/dist/{chunk-DFKBTBO3.js → chunk-NVLREB5R.js} +35 -6
  51. package/dist/chunk-NVLREB5R.js.map +1 -0
  52. package/dist/{chunk-AEUABPAJ.js → chunk-OTEVKRAH.js} +3 -3
  53. package/dist/{chunk-KQB2BX4V.js → chunk-P4A6D6HO.js} +4 -4
  54. package/dist/chunk-P7323YVW.js +134 -0
  55. package/dist/chunk-P7323YVW.js.map +1 -0
  56. package/dist/{chunk-4763KQ6O.js → chunk-PXRN2MER.js} +2 -2
  57. package/dist/{chunk-TR3HFH6J.js → chunk-QFSL2L2B.js} +67 -10
  58. package/dist/chunk-QFSL2L2B.js.map +1 -0
  59. package/dist/{chunk-2LYOAB2E.js → chunk-RRE74VWI.js} +2 -2
  60. package/dist/{chunk-LM2NHRCJ.js → chunk-SHGIDTYF.js} +4 -4
  61. package/dist/chunk-SHGIDTYF.js.map +1 -0
  62. package/dist/{chunk-ZQV7UQNE.js → chunk-SQ4FSNYL.js} +2 -2
  63. package/dist/{chunk-OCNSIBMP.js → chunk-T76MA2FH.js} +135 -1
  64. package/dist/{chunk-OCNSIBMP.js.map → chunk-T76MA2FH.js.map} +1 -1
  65. package/dist/{chunk-6R56OKJZ.js → chunk-UIITN37J.js} +2 -2
  66. package/dist/{chunk-CJ2RMTT7.js → chunk-VEIIUCYL.js} +2 -2
  67. package/dist/{chunk-SVAAONYB.js → chunk-WQLNUEZL.js} +12 -2
  68. package/dist/{chunk-SVAAONYB.js.map → chunk-WQLNUEZL.js.map} +1 -1
  69. package/dist/{chunk-WSJ7RO54.js → chunk-XED2DNAI.js} +23 -5
  70. package/dist/chunk-XED2DNAI.js.map +1 -0
  71. package/dist/{chunk-FSGICFXB.js → chunk-XG2A6GIG.js} +17 -5
  72. package/dist/chunk-XG2A6GIG.js.map +1 -0
  73. package/dist/{chunk-TO7DJYLZ.js → chunk-XY7YV2YQ.js} +178 -39
  74. package/dist/chunk-XY7YV2YQ.js.map +1 -0
  75. package/dist/{chunk-HTABUCF4.js → chunk-Y5BVR4HW.js} +3 -3
  76. package/dist/chunk-Y6FCXRIC.js +3972 -0
  77. package/dist/chunk-Y6FCXRIC.js.map +1 -0
  78. package/dist/{chunk-2SLED3NB.js → chunk-YDZ7XGPZ.js} +1 -1
  79. package/dist/{chunk-2SLED3NB.js.map → chunk-YDZ7XGPZ.js.map} +1 -1
  80. package/dist/{chunk-QF6IQQFP.js → chunk-Z7FDJ35L.js} +18 -12
  81. package/dist/chunk-Z7FDJ35L.js.map +1 -0
  82. package/dist/{chunk-5EEMTJMT.js → chunk-ZH5LOQET.js} +4 -4
  83. package/dist/cli/bin.js +49 -31
  84. package/dist/cli/bin.js.map +1 -1
  85. package/dist/cli/commands/audit.js +18 -18
  86. package/dist/client-L7NAUG6J.js +11 -0
  87. package/dist/configs/eslint.js +27 -1
  88. package/dist/configs/eslint.js.map +1 -1
  89. package/dist/configs/playwright-a11y.d.ts +11 -1
  90. package/dist/configs/playwright-a11y.js +3 -1
  91. package/dist/{convert-to-pnpm-YTFREUJK.js → convert-to-pnpm-4DON7IFS.js} +6 -6
  92. package/dist/{db-BBEM7CBX.js → db-5K4CDEGJ.js} +45 -20
  93. package/dist/db-5K4CDEGJ.js.map +1 -0
  94. package/dist/deadletter-G4M3HSVM.js +17 -0
  95. package/dist/{digest-65BOZ7AT.js → digest-5AJGWS33.js} +45 -22
  96. package/dist/digest-5AJGWS33.js.map +1 -0
  97. package/dist/{digest-collectors-EHFY2OQC.js → digest-collectors-MC5NWEUA.js} +12 -10
  98. package/dist/{digest-state-3KHZF7GD.js → digest-state-ZDPKR7MW.js} +18 -2
  99. package/dist/digest-state-ZDPKR7MW.js.map +1 -0
  100. package/dist/{ensure-site-WIDO6LGU.js → ensure-site-XESZHZEB.js} +39 -11
  101. package/dist/ensure-site-XESZHZEB.js.map +1 -0
  102. package/dist/{fleet-state-UEVZ3X3J.js → fleet-state-GJWGKTLD.js} +6 -4
  103. package/dist/{forms-notify-target-2LWF5C5B.js → forms-notify-target-4NPLX2UG.js} +5 -5
  104. package/dist/{freeze-A6MUCZU4.js → freeze-GUQ43EAU.js} +2 -2
  105. package/dist/{github-signals-GAHNOAHS.js → github-signals-DMU74SAX.js} +10 -10
  106. package/dist/{header-image-YN3AQRY3.js → header-image-BRTOLHJF.js} +6 -5
  107. package/dist/header-image-BRTOLHJF.js.map +1 -0
  108. package/dist/{health-endpoint-KVCJYWET.js → health-endpoint-UCLMSSCN.js} +8 -7
  109. package/dist/{health-endpoint-KVCJYWET.js.map → health-endpoint-UCLMSSCN.js.map} +1 -1
  110. package/dist/{health-mirror-EB76EERV.js → health-mirror-ONRT4DQ5.js} +7 -7
  111. package/dist/{import-airtable-TAKSN4NV.js → import-airtable-IIK2QUUF.js} +3 -3
  112. package/dist/index.d.ts +135 -4
  113. package/dist/index.js +68 -34
  114. package/dist/index.js.map +1 -1
  115. package/dist/{init-FFE4FCO2.js → init-3LMZTCVD.js} +19 -18
  116. package/dist/{init-FFE4FCO2.js.map → init-3LMZTCVD.js.map} +1 -1
  117. package/dist/{launch-4RVWPZGI.js → launch-XTDMC6LD.js} +209 -61
  118. package/dist/launch-XTDMC6LD.js.map +1 -0
  119. package/dist/{lighthouse-VHI77PFB.js → lighthouse-52WSPZ5D.js} +2 -2
  120. package/dist/{lighthouse-airtable-YMH4UA7R.js → lighthouse-airtable-3NOFB42B.js} +3 -3
  121. package/dist/{match-harness-2Q6ISEES.js → match-harness-OW45CB5H.js} +14 -7
  122. package/dist/match-harness-OW45CB5H.js.map +1 -0
  123. package/dist/migrate-NE3DUMTM.js +7 -0
  124. package/dist/{notify-IISTHNBR.js → notify-K3WVH3DM.js} +3 -3
  125. package/dist/{onboard-TM2KESGF.js → onboard-CZYBWVWH.js} +6 -6
  126. package/dist/{orchestrate-MWXENQOS.js → orchestrate-TGDFGY52.js} +8 -8
  127. package/dist/{parity-CAJ477PS.js → parity-AEKYSLN6.js} +5 -5
  128. package/dist/{pipeline-YROAY6DT.js → pipeline-UUPXOS2J.js} +3 -3
  129. package/dist/{preflight-4VQP7JJL.js → preflight-POZZI3GN.js} +9 -9
  130. package/dist/{prismic-ci-6GKKZGB5.js → prismic-ci-AHY5ULJR.js} +38 -8
  131. package/dist/prismic-ci-AHY5ULJR.js.map +1 -0
  132. package/dist/{prismic-models-W6CNLTWH.js → prismic-models-URYGODNY.js} +9 -9
  133. package/dist/prospect/types.d.ts +72 -0
  134. package/dist/prospect/types.js +1 -1
  135. package/dist/{prospect-audit-X4Z67LWW.js → prospect-audit-AJEE3Z4L.js} +16 -7
  136. package/dist/prospect-audit-AJEE3Z4L.js.map +1 -0
  137. package/dist/{prospect-audits-RVYEA4KH.js → prospect-audits-IZVQY3OQ.js} +12 -4
  138. package/dist/protection-audit-3J3UEOVT.js +413 -0
  139. package/dist/protection-audit-3J3UEOVT.js.map +1 -0
  140. package/dist/recipes/sync-configs.js +3 -3
  141. package/dist/{render-YGNGTX3W.js → render-MHUUHPLN.js} +36 -9
  142. package/dist/render-MHUUHPLN.js.map +1 -0
  143. package/dist/{render-from-row-IFSBHWDH.js → render-from-row-65DC6ZP3.js} +4 -4
  144. package/dist/{renovate-dispatch-U5Q52SKT.js → renovate-dispatch-ONJMBUHJ.js} +3 -3
  145. package/dist/{replay-PCSQOGCZ.js → replay-4FVFOMHH.js} +10 -23
  146. package/dist/replay-4FVFOMHH.js.map +1 -0
  147. package/dist/{report-4GFD4MW2.js → report-RC5LGPU3.js} +22 -20
  148. package/dist/report-RC5LGPU3.js.map +1 -0
  149. package/dist/{report-mirror-IP64R7B3.js → report-mirror-KKZZ6RMZ.js} +13 -9
  150. package/dist/{report-mirror-IP64R7B3.js.map → report-mirror-KKZZ6RMZ.js.map} +1 -1
  151. package/dist/{schema-2V7BGYVT.js → schema-KWUQEZ5O.js} +1 -1
  152. package/dist/schema-KWUQEZ5O.js.map +1 -0
  153. package/dist/{self-updating-MWXIZLL7.js → self-updating-RKKIYNV4.js} +8 -7
  154. package/dist/{self-updating-MWXIZLL7.js.map → self-updating-RKKIYNV4.js.map} +1 -1
  155. package/dist/{selftest-MAB2PBXQ.js → selftest-AFLR7YV7.js} +10 -10
  156. package/dist/site-lookup-DTOLJ4EA.js +27 -0
  157. package/dist/site-lookup-DTOLJ4EA.js.map +1 -0
  158. package/dist/{site-mirror-UKHREAD6.js → site-mirror-H2FYMN55.js} +23 -9
  159. package/dist/site-mirror-H2FYMN55.js.map +1 -0
  160. package/dist/{smoke-suite-7DGITCTZ.js → smoke-suite-BWHR3XX5.js} +8 -7
  161. package/dist/{smoke-suite-7DGITCTZ.js.map → smoke-suite-BWHR3XX5.js.map} +1 -1
  162. package/dist/{submissions-5GKJPCIH.js → submissions-II5J35QM.js} +4 -4
  163. package/dist/{submissions-3I3GAQAX.js → submissions-JDZP35JM.js} +49 -9
  164. package/dist/submissions-JDZP35JM.js.map +1 -0
  165. package/dist/{svelte-codemods-WSV2FGNG.js → svelte-codemods-QWGIRNN6.js} +6 -6
  166. package/dist/{sync-K3PKHVLH.js → sync-NKPDCMYW.js} +5 -5
  167. package/dist/{sync-configs-RRIHNLIJ.js → sync-configs-HGLQV55H.js} +6 -6
  168. package/dist/{upgrade-VTD6V4HS.js → upgrade-WZ44IARG.js} +6 -6
  169. package/dist/util/git.d.ts +48 -9
  170. package/dist/util/git.js +1 -1
  171. package/dist/{webflow-IRKOIT7S.js → webflow-624FEBFD.js} +4 -4
  172. package/dist/{websites-TB4TCAWM.js → websites-6DHIHJ2D.js} +4 -2
  173. package/dist/{write-audits-to-airtable-53EVXKMU.js → write-audits-to-airtable-BIK6LNVC.js} +5 -5
  174. package/dist/write-audits-to-airtable-BIK6LNVC.js.map +1 -0
  175. package/package.json +3 -2
  176. package/dist/airtable-JGCPS7JH.js +0 -9
  177. package/dist/chunk-4AIYWWKV.js.map +0 -1
  178. package/dist/chunk-5UINJNAJ.js.map +0 -1
  179. package/dist/chunk-6VKYQATC.js +0 -1708
  180. package/dist/chunk-6VKYQATC.js.map +0 -1
  181. package/dist/chunk-7MKT4I5T.js +0 -62
  182. package/dist/chunk-7MKT4I5T.js.map +0 -1
  183. package/dist/chunk-AVEQUR44.js.map +0 -1
  184. package/dist/chunk-BVEDKMNG.js.map +0 -1
  185. package/dist/chunk-BYGPUUCT.js.map +0 -1
  186. package/dist/chunk-CWXTNPNZ.js.map +0 -1
  187. package/dist/chunk-DFKBTBO3.js.map +0 -1
  188. package/dist/chunk-FSGICFXB.js.map +0 -1
  189. package/dist/chunk-GASBX52O.js +0 -12
  190. package/dist/chunk-GASBX52O.js.map +0 -1
  191. package/dist/chunk-LM2NHRCJ.js.map +0 -1
  192. package/dist/chunk-QF6IQQFP.js.map +0 -1
  193. package/dist/chunk-TO7DJYLZ.js.map +0 -1
  194. package/dist/chunk-TR3HFH6J.js.map +0 -1
  195. package/dist/chunk-WJMPCVOR.js.map +0 -1
  196. package/dist/chunk-WSJ7RO54.js.map +0 -1
  197. package/dist/chunk-WVNDEYXL.js.map +0 -1
  198. package/dist/chunk-XHHMM5HX.js.map +0 -1
  199. package/dist/chunk-YLYXW5PH.js.map +0 -1
  200. package/dist/client-M2V6FHH5.js +0 -11
  201. package/dist/db-BBEM7CBX.js.map +0 -1
  202. package/dist/digest-65BOZ7AT.js.map +0 -1
  203. package/dist/digest-state-3KHZF7GD.js.map +0 -1
  204. package/dist/ensure-site-WIDO6LGU.js.map +0 -1
  205. package/dist/header-image-YN3AQRY3.js.map +0 -1
  206. package/dist/launch-4RVWPZGI.js.map +0 -1
  207. package/dist/match-harness-2Q6ISEES.js.map +0 -1
  208. package/dist/migrate-K4JETR36.js +0 -7
  209. package/dist/prismic-ci-6GKKZGB5.js.map +0 -1
  210. package/dist/prospect-audit-X4Z67LWW.js.map +0 -1
  211. package/dist/protection-audit-SJO53MEQ.js +0 -168
  212. package/dist/protection-audit-SJO53MEQ.js.map +0 -1
  213. package/dist/render-YGNGTX3W.js.map +0 -1
  214. package/dist/replay-PCSQOGCZ.js.map +0 -1
  215. package/dist/report-4GFD4MW2.js.map +0 -1
  216. package/dist/schema-2V7BGYVT.js.map +0 -1
  217. package/dist/site-mirror-UKHREAD6.js.map +0 -1
  218. package/dist/submissions-3I3GAQAX.js.map +0 -1
  219. /package/dist/{airtable-JGCPS7JH.js.map → airtable-SJV4ZSMS.js.map} +0 -0
  220. /package/dist/{announce-PGT4SZZB.js.map → announce-45HVP4J4.js.map} +0 -0
  221. /package/dist/{blux-4KNXUP2K.js.map → blux-RUFMNOUJ.js.map} +0 -0
  222. /package/dist/{bump-deps-C5G2EFBB.js.map → bump-deps-EL3TKMIL.js.map} +0 -0
  223. /package/dist/{chunk-XN37VTDB.js.map → chunk-37B4LVB3.js.map} +0 -0
  224. /package/dist/{chunk-WMBLR5VA.js.map → chunk-44SDGPGQ.js.map} +0 -0
  225. /package/dist/{chunk-22GKJO5F.js.map → chunk-6INOBNRO.js.map} +0 -0
  226. /package/dist/{chunk-5GUJ36TL.js.map → chunk-74QRWE6G.js.map} +0 -0
  227. /package/dist/{chunk-S7RYFUIK.js.map → chunk-CA6ADGOC.js.map} +0 -0
  228. /package/dist/{chunk-KZRR4NFG.js.map → chunk-D3CTOCUR.js.map} +0 -0
  229. /package/dist/{chunk-BCKEP5S6.js.map → chunk-ECDJDHKT.js.map} +0 -0
  230. /package/dist/{chunk-DMPHP7UP.js.map → chunk-EQQ4H6L3.js.map} +0 -0
  231. /package/dist/{chunk-Z2K4JPQ3.js.map → chunk-H445EH33.js.map} +0 -0
  232. /package/dist/{chunk-FUWFLAWQ.js.map → chunk-IMYL67JV.js.map} +0 -0
  233. /package/dist/{chunk-AEUABPAJ.js.map → chunk-OTEVKRAH.js.map} +0 -0
  234. /package/dist/{chunk-KQB2BX4V.js.map → chunk-P4A6D6HO.js.map} +0 -0
  235. /package/dist/{chunk-4763KQ6O.js.map → chunk-PXRN2MER.js.map} +0 -0
  236. /package/dist/{chunk-2LYOAB2E.js.map → chunk-RRE74VWI.js.map} +0 -0
  237. /package/dist/{chunk-ZQV7UQNE.js.map → chunk-SQ4FSNYL.js.map} +0 -0
  238. /package/dist/{chunk-6R56OKJZ.js.map → chunk-UIITN37J.js.map} +0 -0
  239. /package/dist/{chunk-CJ2RMTT7.js.map → chunk-VEIIUCYL.js.map} +0 -0
  240. /package/dist/{chunk-HTABUCF4.js.map → chunk-Y5BVR4HW.js.map} +0 -0
  241. /package/dist/{chunk-5EEMTJMT.js.map → chunk-ZH5LOQET.js.map} +0 -0
  242. /package/dist/{client-M2V6FHH5.js.map → client-L7NAUG6J.js.map} +0 -0
  243. /package/dist/{convert-to-pnpm-YTFREUJK.js.map → convert-to-pnpm-4DON7IFS.js.map} +0 -0
  244. /package/dist/{digest-collectors-EHFY2OQC.js.map → deadletter-G4M3HSVM.js.map} +0 -0
  245. /package/dist/{fleet-state-UEVZ3X3J.js.map → digest-collectors-MC5NWEUA.js.map} +0 -0
  246. /package/dist/{freeze-A6MUCZU4.js.map → fleet-state-GJWGKTLD.js.map} +0 -0
  247. /package/dist/{forms-notify-target-2LWF5C5B.js.map → forms-notify-target-4NPLX2UG.js.map} +0 -0
  248. /package/dist/{import-airtable-TAKSN4NV.js.map → freeze-GUQ43EAU.js.map} +0 -0
  249. /package/dist/{github-signals-GAHNOAHS.js.map → github-signals-DMU74SAX.js.map} +0 -0
  250. /package/dist/{health-mirror-EB76EERV.js.map → health-mirror-ONRT4DQ5.js.map} +0 -0
  251. /package/dist/{lighthouse-VHI77PFB.js.map → import-airtable-IIK2QUUF.js.map} +0 -0
  252. /package/dist/{lighthouse-airtable-YMH4UA7R.js.map → lighthouse-52WSPZ5D.js.map} +0 -0
  253. /package/dist/{migrate-K4JETR36.js.map → lighthouse-airtable-3NOFB42B.js.map} +0 -0
  254. /package/dist/{notify-IISTHNBR.js.map → migrate-NE3DUMTM.js.map} +0 -0
  255. /package/dist/{orchestrate-MWXENQOS.js.map → notify-K3WVH3DM.js.map} +0 -0
  256. /package/dist/{onboard-TM2KESGF.js.map → onboard-CZYBWVWH.js.map} +0 -0
  257. /package/dist/{parity-CAJ477PS.js.map → orchestrate-TGDFGY52.js.map} +0 -0
  258. /package/dist/{pipeline-YROAY6DT.js.map → parity-AEKYSLN6.js.map} +0 -0
  259. /package/dist/{prospect-audits-RVYEA4KH.js.map → pipeline-UUPXOS2J.js.map} +0 -0
  260. /package/dist/{preflight-4VQP7JJL.js.map → preflight-POZZI3GN.js.map} +0 -0
  261. /package/dist/{prismic-models-W6CNLTWH.js.map → prismic-models-URYGODNY.js.map} +0 -0
  262. /package/dist/{render-from-row-IFSBHWDH.js.map → prospect-audits-IZVQY3OQ.js.map} +0 -0
  263. /package/dist/{websites-TB4TCAWM.js.map → render-from-row-65DC6ZP3.js.map} +0 -0
  264. /package/dist/{renovate-dispatch-U5Q52SKT.js.map → renovate-dispatch-ONJMBUHJ.js.map} +0 -0
  265. /package/dist/{selftest-MAB2PBXQ.js.map → selftest-AFLR7YV7.js.map} +0 -0
  266. /package/dist/{submissions-5GKJPCIH.js.map → submissions-II5J35QM.js.map} +0 -0
  267. /package/dist/{svelte-codemods-WSV2FGNG.js.map → svelte-codemods-QWGIRNN6.js.map} +0 -0
  268. /package/dist/{sync-K3PKHVLH.js.map → sync-NKPDCMYW.js.map} +0 -0
  269. /package/dist/{sync-configs-RRIHNLIJ.js.map → sync-configs-HGLQV55H.js.map} +0 -0
  270. /package/dist/{upgrade-VTD6V4HS.js.map → upgrade-WZ44IARG.js.map} +0 -0
  271. /package/dist/{webflow-IRKOIT7S.js.map → webflow-624FEBFD.js.map} +0 -0
  272. /package/dist/{write-audits-to-airtable-53EVXKMU.js.map → websites-6DHIHJ2D.js.map} +0 -0
@@ -18,6 +18,22 @@ async function writeDigestState(db, snap, updatedAt = (/* @__PURE__ */ new Date(
18
18
  await db.insertInto("digest_state").values(row).onConflict((oc) => oc.column("id").doUpdateSet(row)).execute();
19
19
  }
20
20
  var COCKPIT_ROLLUP_ID = "cockpit_rollup";
21
+ function coerceBounces(raw) {
22
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return {};
23
+ const out = {};
24
+ for (const [siteId, v] of Object.entries(raw)) {
25
+ if (typeof v === "number" && Number.isFinite(v)) {
26
+ out[siteId] = { total: v, permanent: 0 };
27
+ continue;
28
+ }
29
+ if (typeof v !== "object" || v === null || Array.isArray(v)) continue;
30
+ const o = v;
31
+ if (typeof o.total === "number" && Number.isFinite(o.total) && typeof o.permanent === "number" && Number.isFinite(o.permanent)) {
32
+ out[siteId] = { total: o.total, permanent: o.permanent };
33
+ }
34
+ }
35
+ return out;
36
+ }
21
37
  async function readCockpitRollup(db) {
22
38
  const row = await db.selectFrom("digest_state").select("snapshot").where("id", "=", COCKPIT_ROLLUP_ID).executeTakeFirst();
23
39
  if (!row) return null;
@@ -26,7 +42,7 @@ async function readCockpitRollup(db) {
26
42
  if (typeof parsed !== "object" || parsed === null || typeof parsed.computedAt !== "string" || typeof parsed.spamTotals !== "object" || parsed.spamTotals === null || typeof parsed.notifyBounces !== "object" || parsed.notifyBounces === null) {
27
43
  return null;
28
44
  }
29
- return parsed;
45
+ return { ...parsed, notifyBounces: coerceBounces(parsed.notifyBounces) };
30
46
  } catch {
31
47
  return null;
32
48
  }
@@ -47,4 +63,4 @@ export {
47
63
  writeCockpitRollup,
48
64
  writeDigestState
49
65
  };
50
- //# sourceMappingURL=digest-state-3KHZF7GD.js.map
66
+ //# sourceMappingURL=digest-state-ZDPKR7MW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/db/digest-state.ts"],"sourcesContent":["/** #609 (#539 Phase 5): the digest's prior-run snapshot, on Turso.\n *\n * Unlike every other Phase 5 slice this is a MIGRATION, not a mirror — there\n * was no Turso table to dual-write into, so these REPLACE the Airtable pair in\n * `src/alerts/digest-state.ts` rather than shadowing them. Nothing writes the\n * Airtable \"Digest State\" table after this, so parity does not cover the new\n * one: it has no counterpart to compare against.\n *\n * The pure half — `diffAttention`, and the `DigestSnapshot` type it is written\n * against — stays exactly where it is. Only the IO moved.\n *\n * Stored as ONE row holding the whole snapshot as JSON. Both readers\n * (`runDigest`'s diff and the fleet homepage's NEW badges) need the entire map,\n * so a keyed table would buy nothing on reads and its \"give me everything\"\n * query would be a raw scan needing a justified entry in the EXPLAIN gate's\n * allowlist. One row by primary key needs neither.\n *\n * Worth stating plainly: the homepage's read of this used to be an AIRTABLE\n * call on a request path — a Phase 2 leftover, since digest state was never in\n * that phase's scope. Moving it removes a live dependency, which is the same\n * failure class as the 2026-08-17 quota outage.\n */\nimport type { Db } from \"./client.js\";\nimport type { DigestSnapshot } from \"../alerts/digest-state.js\";\nimport type { NotifyBounceCounts } from \"./submissions.js\";\n\n/** The singleton row's key. A constant rather than a magic string at each call\n * site, so the \"there is exactly one row\" invariant is visible in one place. */\nexport const DIGEST_STATE_ID = \"default\";\n\n/**\n * The prior snapshot, or `{}` when there is none.\n *\n * A missing row and a malformed blob BOTH read as `{}` — the Airtable reader's\n * contract, kept verbatim. The digest runs unattended on a cron, so a bad blob\n * must cost accurate NEW badges for one run, never the whole send.\n */\nexport async function readDigestState(db: Db): Promise<DigestSnapshot> {\n const row = await db\n .selectFrom(\"digest_state\")\n .select(\"snapshot\")\n .where(\"id\", \"=\", DIGEST_STATE_ID)\n .executeTakeFirst();\n if (!row) return {};\n try {\n return JSON.parse(row.snapshot) as DigestSnapshot;\n } catch {\n return {};\n }\n}\n\n/**\n * Persist the next snapshot, replacing whatever was there.\n *\n * An upsert on the constant id rather than a get-then-create: the Airtable\n * version needed two round-trips to decide, and here the singleton invariant is\n * enforced by the primary key instead of by the code that happens to run.\n */\nexport async function writeDigestState(\n db: Db,\n snap: DigestSnapshot,\n updatedAt: string = new Date().toISOString(),\n): Promise<void> {\n const row = {\n id: DIGEST_STATE_ID,\n snapshot: JSON.stringify(snap),\n updated_at: updatedAt,\n };\n await db\n .insertInto(\"digest_state\")\n .values(row)\n .onConflict((oc) => oc.column(\"id\").doUpdateSet(row))\n .execute();\n}\n\n/**\n * A SECOND row in the same table, holding the cockpit's \"since a window\"\n * roll-ups. Keyed separately rather than folded into the snapshot: the snapshot\n * is the digest's own diff state and has one writer and one meaning; conflating\n * two unrelated payloads in one blob makes a partial write of either look like a\n * corruption of both.\n */\nexport const COCKPIT_ROLLUP_ID = \"cockpit_rollup\";\n\n/**\n * Fleet-wide counts the cockpit renders, computed once by the nightly digest\n * instead of aggregated on every page load.\n *\n * `computedAt` is not decoration. These figures are up to 24h old by\n * construction, and a stale number rendered as though it were live is worse than\n * no number — so the cockpit shows when it was taken.\n */\nexport type CockpitRollup = {\n spamTotals: { honeypot: number; tooFast: number; markedSpam: number };\n /** site id → unacknowledged bounce counts inside the bounce window, split by\n * whether Resend called any of them Permanent (#783). */\n notifyBounces: Record<string, NotifyBounceCounts>;\n /** The windows these were computed over, so a changed constant is visible\n * rather than silently re-labelling old numbers. */\n windowDays: { screenOuts: number; bounces: number };\n computedAt: string;\n};\n\n/**\n * The stored roll-up, or **null** when there is none.\n *\n * Null rather than zeros, deliberately. Every one of these numbers has a\n * legitimate zero, so a reader given `{honeypot: 0, …}` cannot tell \"nothing was\n * screened out\" from \"the digest has never run\". That is the same distinction\n * `FLEET_SMOKE_UNMEASURED` exists to preserve, and the cockpit renders the strip\n * as ABSENT for null rather than drawing a row of zeros.\n *\n * A malformed blob is also null: same reasoning, and it must never throw on a\n * request path.\n */\n/**\n * Normalize the stored per-site bounce map (#783).\n *\n * The shape changed from `{recA: 2}` to `{recA: {total, permanent}}`, and this\n * blob is written by the NIGHTLY digest — so after a deploy the stored payload\n * is the old shape until the next run. Rejecting it outright would blank the\n * whole strip, `spamTotals` included, for a number that is merely less detailed.\n *\n * An old numeric entry reads as `permanent: 0`, which is the honest translation:\n * that writer recorded no classification, and 0 is exactly \"nothing said the\n * address is dead\". It words the alarm as the mail-filter case for one night,\n * which is the safe direction. Anything else is dropped per SITE rather than\n * poisoning the map with NaN or discarding the roll-up.\n */\nfunction coerceBounces(raw: unknown): Record<string, NotifyBounceCounts> {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return {};\n const out: Record<string, NotifyBounceCounts> = {};\n for (const [siteId, v] of Object.entries(raw as Record<string, unknown>)) {\n if (typeof v === \"number\" && Number.isFinite(v)) {\n out[siteId] = { total: v, permanent: 0 };\n continue;\n }\n if (typeof v !== \"object\" || v === null || Array.isArray(v)) continue;\n const o = v as Record<string, unknown>;\n if (\n typeof o.total === \"number\" &&\n Number.isFinite(o.total) &&\n typeof o.permanent === \"number\" &&\n Number.isFinite(o.permanent)\n ) {\n out[siteId] = { total: o.total, permanent: o.permanent };\n }\n }\n return out;\n}\n\nexport async function readCockpitRollup(db: Db): Promise<CockpitRollup | null> {\n const row = await db\n .selectFrom(\"digest_state\")\n .select(\"snapshot\")\n .where(\"id\", \"=\", COCKPIT_ROLLUP_ID)\n .executeTakeFirst();\n if (!row) return null;\n try {\n const parsed = JSON.parse(row.snapshot) as Partial<CockpitRollup>;\n // Shape-check rather than trust: this blob is written by a different process\n // on a different schedule, so an older writer's payload can outlive a type\n // change here. Anything unrecognized reads as \"not measured\".\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n typeof parsed.computedAt !== \"string\" ||\n typeof parsed.spamTotals !== \"object\" ||\n parsed.spamTotals === null ||\n typeof parsed.notifyBounces !== \"object\" ||\n parsed.notifyBounces === null\n ) {\n return null;\n }\n return { ...(parsed as CockpitRollup), notifyBounces: coerceBounces(parsed.notifyBounces) };\n } catch {\n return null;\n }\n}\n\n/** Upsert the roll-up, same singleton-by-PK shape as the snapshot. */\nexport async function writeCockpitRollup(db: Db, rollup: CockpitRollup): Promise<void> {\n const row = {\n id: COCKPIT_ROLLUP_ID,\n snapshot: JSON.stringify(rollup),\n updated_at: rollup.computedAt,\n };\n await db\n .insertInto(\"digest_state\")\n .values(row)\n .onConflict((oc) => oc.column(\"id\").doUpdateSet(row))\n .execute();\n}\n"],"mappings":";AA4BO,IAAM,kBAAkB;AAS/B,eAAsB,gBAAgB,IAAiC;AACrE,QAAM,MAAM,MAAM,GACf,WAAW,cAAc,EACzB,OAAO,UAAU,EACjB,MAAM,MAAM,KAAK,eAAe,EAChC,iBAAiB;AACpB,MAAI,CAAC,IAAK,QAAO,CAAC;AAClB,MAAI;AACF,WAAO,KAAK,MAAM,IAAI,QAAQ;AAAA,EAChC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AASA,eAAsB,iBACpB,IACA,MACA,aAAoB,oBAAI,KAAK,GAAE,YAAY,GAC5B;AACf,QAAM,MAAM;AAAA,IACV,IAAI;AAAA,IACJ,UAAU,KAAK,UAAU,IAAI;AAAA,IAC7B,YAAY;AAAA,EACd;AACA,QAAM,GACH,WAAW,cAAc,EACzB,OAAO,GAAG,EACV,WAAW,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,YAAY,GAAG,CAAC,EACnD,QAAQ;AACb;AASO,IAAM,oBAAoB;AA+CjC,SAAS,cAAc,KAAkD;AACvE,MAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AAC3E,QAAM,MAA0C,CAAC;AACjD,aAAW,CAAC,QAAQ,CAAC,KAAK,OAAO,QAAQ,GAA8B,GAAG;AACxE,QAAI,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,GAAG;AAC/C,UAAI,MAAM,IAAI,EAAE,OAAO,GAAG,WAAW,EAAE;AACvC;AAAA,IACF;AACA,QAAI,OAAO,MAAM,YAAY,MAAM,QAAQ,MAAM,QAAQ,CAAC,EAAG;AAC7D,UAAM,IAAI;AACV,QACE,OAAO,EAAE,UAAU,YACnB,OAAO,SAAS,EAAE,KAAK,KACvB,OAAO,EAAE,cAAc,YACvB,OAAO,SAAS,EAAE,SAAS,GAC3B;AACA,UAAI,MAAM,IAAI,EAAE,OAAO,EAAE,OAAO,WAAW,EAAE,UAAU;AAAA,IACzD;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,kBAAkB,IAAuC;AAC7E,QAAM,MAAM,MAAM,GACf,WAAW,cAAc,EACzB,OAAO,UAAU,EACjB,MAAM,MAAM,KAAK,iBAAiB,EAClC,iBAAiB;AACpB,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI,QAAQ;AAItC,QACE,OAAO,WAAW,YAClB,WAAW,QACX,OAAO,OAAO,eAAe,YAC7B,OAAO,OAAO,eAAe,YAC7B,OAAO,eAAe,QACtB,OAAO,OAAO,kBAAkB,YAChC,OAAO,kBAAkB,MACzB;AACA,aAAO;AAAA,IACT;AACA,WAAO,EAAE,GAAI,QAA0B,eAAe,cAAc,OAAO,aAAa,EAAE;AAAA,EAC5F,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,mBAAmB,IAAQ,QAAsC;AACrF,QAAM,MAAM;AAAA,IACV,IAAI;AAAA,IACJ,UAAU,KAAK,UAAU,MAAM;AAAA,IAC/B,YAAY,OAAO;AAAA,EACrB;AACA,QAAM,GACH,WAAW,cAAc,EACzB,OAAO,GAAG,EACV,WAAW,CAAC,OAAO,GAAG,OAAO,IAAI,EAAE,YAAY,GAAG,CAAC,EACnD,QAAQ;AACb;","names":[]}
@@ -4,10 +4,10 @@ import {
4
4
  } from "./chunk-HN6I2XWI.js";
5
5
  import {
6
6
  WEBSITES_TABLE,
7
- listWebsites,
7
+ mapRow,
8
8
  siteSlug,
9
9
  toAirtableStatus
10
- } from "./chunk-3Z6X3BHU.js";
10
+ } from "./chunk-KN52PM63.js";
11
11
  import "./chunk-6VAL7XJT.js";
12
12
 
13
13
  // src/reports/airtable/ensure-site.ts
@@ -23,8 +23,22 @@ async function ensureSite(base, input, mirror) {
23
23
  throw new Error(
24
24
  `ensure-site: display name '${input.displayName}' slugifies to '${siteSlug(input.displayName)}', not '${slug}' \u2014 the row would not be found on re-run`
25
25
  );
26
- const existing = (await listWebsites(base)).find((w) => siteSlug(w.name) === slug);
27
- if (!existing) {
26
+ const raw = [];
27
+ await base(WEBSITES_TABLE).select({ pageSize: 100 }).eachPage((records, fetchNextPage) => {
28
+ for (const rec of records) raw.push({ id: rec.id, fields: rec.fields });
29
+ fetchNextPage();
30
+ });
31
+ let existing;
32
+ let existingRaw;
33
+ for (const rec of raw) {
34
+ const row = mapRow(rec);
35
+ if (siteSlug(row.name) === slug) {
36
+ existing = row;
37
+ existingRaw = rec;
38
+ break;
39
+ }
40
+ }
41
+ if (!existing || !existingRaw) {
28
42
  const fields = {
29
43
  Name: input.displayName ?? slug,
30
44
  Status: toAirtableStatus("building"),
@@ -39,9 +53,17 @@ async function ensureSite(base, input, mirror) {
39
53
  status: "created",
40
54
  siteId: rec.id,
41
55
  updatedFields: [],
42
- skippedMismatches: []
56
+ skippedMismatches: [],
57
+ // The create path just inserted the row; there is nothing to heal, and a
58
+ // `hasRow` probe here would be a round-trip whose answer is already known.
59
+ healedDbRow: false
43
60
  };
44
61
  }
62
+ let healedDbRow = false;
63
+ if (mirror?.hasRow && !await mirror.hasRow(existingRaw.id)) {
64
+ await mirror.created(existingRaw);
65
+ healedDbRow = true;
66
+ }
45
67
  const updates = {};
46
68
  const skippedMismatches = [];
47
69
  const blank = (v) => v === null || v === void 0 || v === "";
@@ -53,12 +75,15 @@ async function ensureSite(base, input, mirror) {
53
75
  consider(COLS.url, input.url, existing.url || null);
54
76
  consider(COLS.pointOfContact, input.pointOfContact, existing.pointOfContact);
55
77
  consider(COLS.gitRepo, input.gitRepo, existing.gitRepo);
78
+ if (input.displayName && existing.name !== input.displayName) {
79
+ updates["Name"] = input.displayName;
80
+ }
56
81
  const updatedFields = Object.keys(updates);
57
82
  if (updatedFields.length > 0) {
58
83
  await base(WEBSITES_TABLE).update([{ id: existing.id, fields: updates }]);
59
84
  await mirror?.site(existing.id, updates);
60
85
  }
61
- return { status: "exists", siteId: existing.id, updatedFields, skippedMismatches };
86
+ return { status: "exists", siteId: existing.id, updatedFields, skippedMismatches, healedDbRow };
62
87
  }
63
88
 
64
89
  // src/cli/commands/ensure-site.ts
@@ -66,7 +91,7 @@ async function runEnsureSiteCommand(slug, opts) {
66
91
  if (!slug) return { output: "Provide a <slug> (e.g. `ensure-site roalson`).", code: 2 };
67
92
  try {
68
93
  const base = openBase(readAirtableConfig());
69
- const { makeSiteMirror } = await import("./site-mirror-UKHREAD6.js");
94
+ const { makeSiteMirror } = await import("./site-mirror-H2FYMN55.js");
70
95
  const result = await ensureSite(
71
96
  base,
72
97
  {
@@ -78,11 +103,14 @@ async function runEnsureSiteCommand(slug, opts) {
78
103
  },
79
104
  await makeSiteMirror()
80
105
  );
81
- const filled = result.updatedFields.length > 0 ? ` \u2014 filled blank field(s): ${result.updatedFields.join(", ")}` : "";
106
+ const renamed = result.updatedFields.includes("Name") ? ` \u2014 Name set to "${opts.name}"` : "";
107
+ const blanks = result.updatedFields.filter((f) => f !== "Name");
108
+ const filled = blanks.length > 0 ? ` \u2014 filled blank field(s): ${blanks.join(", ")}` : "";
82
109
  const skipped = result.skippedMismatches.length > 0 ? ` \u2014 differs from existing, left untouched (edit in Airtable): ${result.skippedMismatches.join(", ")}` : "";
83
- const nameNote = result.status === "created" && !opts.name ? ` \u2014 Name set to "${slug}"; retitle in Airtable before forms/announce go live (or re-create with --name)` : "";
110
+ const healed = result.healedDbRow ? ` \u2014 HEALED: the Turso row was MISSING and has been inserted; leads for this slug were being dropped (run \`db replay-deadletters\`)` : "";
111
+ const nameNote = result.status === "created" && !opts.name ? ` \u2014 Name set to "${slug}"; retitle in Airtable before forms/announce go live (or re-run with --name)` : "";
84
112
  return {
85
- output: `[${slug}] ${result.status} (${result.siteId})${filled}${skipped}${nameNote}`,
113
+ output: `[${slug}] ${result.status} (${result.siteId})${healed}${renamed}${filled}${skipped}${nameNote}`,
86
114
  code: 0
87
115
  };
88
116
  } catch (err) {
@@ -93,4 +121,4 @@ async function runEnsureSiteCommand(slug, opts) {
93
121
  export {
94
122
  runEnsureSiteCommand
95
123
  };
96
- //# sourceMappingURL=ensure-site-WIDO6LGU.js.map
124
+ //# sourceMappingURL=ensure-site-XESZHZEB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/reports/airtable/ensure-site.ts","../src/cli/commands/ensure-site.ts"],"sourcesContent":["import type { FieldSet, Records } from \"airtable\";\nimport type { AirtableBase } from \"./client.js\";\nimport { WEBSITES_TABLE, mapRow, siteSlug, type WebsiteRow } from \"./websites.js\";\nimport { toAirtableStatus } from \"./site-status.js\";\n\nexport type EnsureSiteInput = {\n /** Canonical slug — matches by siteSlug(Name); the Name on create when no displayName given. */\n slug: string;\n /** Human display name written to Name on create, and — unlike every other\n * input — UPDATED on an existing row when it differs (#664). Name is\n * consumed VERBATIM in client-facing copy (forms auto-reply intro, report\n * subjects), so a bare machine slug there reads as \"Thanks for reaching out\n * to acme-co.\" — and the row that has it is exactly the one created before\n * the name was settled, which only this command re-run can fix. Must\n * slugify to the same slug or the row wouldn't be found on re-run. */\n displayName?: string;\n url?: string;\n pointOfContact?: string;\n /** owner/repo. Default on create: `reddoorla/<slug>`. */\n gitRepo?: string;\n};\n\n/** #539 Phase 5. Structurally typed rather than importing the db layer's\n * `SiteMirror`, so this module stays the leaf it has always been — a real\n * `SiteMirror` satisfies it. Two ops because `ensureSite` has two write paths,\n * and the create one is the reason this exists: every other site mirror is an\n * UPDATE, which does nothing for a row that does not exist yet. */\nexport type EnsureSiteMirror = {\n created: (rec: { id: string; fields: Record<string, unknown> }) => Promise<void>;\n site: (siteId: string, fields: Record<string, unknown>) => Promise<void>;\n /** #645. Does Turso hold a row for this site id? Optional so every pre-#645\n * caller (and every hand-built test mirror) is byte-for-byte unchanged —\n * absent means the heal below never runs. */\n hasRow?: (siteId: string) => Promise<boolean>;\n};\n\nexport type EnsureSiteResult = {\n status: \"created\" | \"exists\";\n siteId: string;\n /** Airtable column names written on the exists path (create path writes all). */\n updatedFields: string[];\n /** Inputs that DIFFERED from an existing non-blank cell and were left\n * untouched (fill-blanks-only) — surfaced so a resumed bootstrap with a\n * corrected value doesn't silently discard it. */\n skippedMismatches: string[];\n /** #645. True when the site existed in Airtable but had NO Turso row and this\n * run inserted one. Surfaced rather than logged-only because it is the\n * difference between \"nothing to do\" and \"this site's leads were being\n * dropped until just now\". */\n healedDbRow: boolean;\n};\n\n/** Column-name map (load-bearing magic strings — see websites.ts's mapRow header). */\nconst COLS = {\n url: \"url\",\n pointOfContact: \"point of contact\",\n gitRepo: \"Git repo\",\n} as const;\n\n/**\n * Find-or-create the Websites row for a slug so a new site exists in the fleet\n * inventory (audits, form-ingest slug resolution, reports) from day one.\n *\n * Fill-blanks-only on the exists path: this command runs from a bootstrap skill\n * that may be re-run to resume — it must never clobber operator-edited cells.\n * The one exception is `displayName` (#664): `--name` targets Name and nothing\n * else, so a differing value IS the operator's edit, and the create message\n * sends them back here to make it. Frequencies are deliberately NOT set\n * (launch flips the lifecycle); Status is only written on create (\"building\" —\n * Airtable's \"in development\" until the stage-2 vocabulary switch flips).\n */\nexport async function ensureSite(\n base: AirtableBase,\n input: EnsureSiteInput,\n mirror?: EnsureSiteMirror,\n): Promise<EnsureSiteResult> {\n const slug = siteSlug(input.slug);\n if (!slug) throw new Error(`ensure-site: '${input.slug}' does not slugify to a usable slug`);\n if (input.displayName && siteSlug(input.displayName) !== slug)\n throw new Error(\n `ensure-site: display name '${input.displayName}' slugifies to '${siteSlug(input.displayName)}', not '${slug}' — the row would not be found on re-run`,\n );\n\n // Paged inline rather than through `listWebsites` so the RAW stored record\n // survives alongside the mapped row: the #645 heal below re-inserts what\n // Airtable STORED (the same contract as the create path's mirror), and a\n // mapped `WebsiteRow` cannot be turned back into a FieldSet. Same single\n // select `listWebsites` issues — no extra Airtable read.\n const raw: Array<{ id: string; fields: Record<string, unknown> }> = [];\n await base(WEBSITES_TABLE)\n .select({ pageSize: 100 })\n .eachPage((records, fetchNextPage) => {\n for (const rec of records) raw.push({ id: rec.id, fields: rec.fields });\n fetchNextPage();\n });\n let existing: WebsiteRow | undefined;\n let existingRaw: { id: string; fields: Record<string, unknown> } | undefined;\n for (const rec of raw) {\n const row = mapRow(rec);\n if (siteSlug(row.name) === slug) {\n existing = row;\n existingRaw = rec;\n break;\n }\n }\n\n if (!existing || !existingRaw) {\n const fields: FieldSet = {\n Name: input.displayName ?? slug,\n Status: toAirtableStatus(\"building\"),\n [COLS.gitRepo]: input.gitRepo ?? `reddoorla/${slug}`,\n };\n if (input.url) fields[COLS.url] = input.url;\n if (input.pointOfContact) fields[COLS.pointOfContact] = input.pointOfContact;\n const created = (await base(WEBSITES_TABLE).create([{ fields }])) as Records<FieldSet>;\n const rec = created[0]!;\n // The mirror gets what Airtable STORED, never the `fields` we sent: parity\n // diffs Turso against the stored record, so mapping our own payload would\n // diverge the moment Airtable normalises a value.\n await mirror?.created({ id: rec.id, fields: rec.fields as Record<string, unknown> });\n return {\n status: \"created\",\n siteId: rec.id,\n updatedFields: [],\n skippedMismatches: [],\n // The create path just inserted the row; there is nothing to heal, and a\n // `hasRow` probe here would be a round-trip whose answer is already known.\n healedDbRow: false,\n };\n }\n\n // #645. THE gap: before this, `exists` meant \"Airtable has it\" and said nothing\n // about Turso. Post-flip (#643) the form-ingest lookup reads Turso ONLY, so a\n // site with an Airtable row and no Turso row has every lead answered\n // `unknown-site` — silently, permanently, and with no alarm once Phase 6 (#646)\n // deletes `mirror_missed`. `ensure-site` is the command an operator already\n // re-runs to finish a half-created site, so the heal belongs here.\n //\n // FIRST, before the fill-blanks update below: `mirror.site` is an UPDATE, and\n // under the freeze a no-match THROWS (`SITE_MIRROR … no such row in Turso`).\n // Healing second would abort ensure-site on exactly the site it exists to\n // repair. `mirrorSiteInsert` is an upsert, so a lost race just re-writes.\n let healedDbRow = false;\n if (mirror?.hasRow && !(await mirror.hasRow(existingRaw.id))) {\n await mirror.created(existingRaw);\n healedDbRow = true;\n }\n\n const updates: FieldSet = {};\n const skippedMismatches: string[] = [];\n const blank = (v: unknown) => v === null || v === undefined || v === \"\";\n const consider = (column: string, provided: string | undefined, current: unknown) => {\n if (!provided) return;\n if (blank(current)) updates[column] = provided;\n else if (current !== provided) skippedMismatches.push(column);\n };\n consider(COLS.url, input.url, existing.url || null);\n consider(COLS.pointOfContact, input.pointOfContact, existing.pointOfContact);\n consider(COLS.gitRepo, input.gitRepo, existing.gitRepo);\n // #664: Name is NOT fill-blanks. It is never blank (the slug match found it),\n // and `--name` is the only way to retitle a row created before the display\n // name was settled — the slugify guard above already proved the new value\n // resolves to the same row. Goes through the same update + mirror below, so\n // Turso gets it too.\n if (input.displayName && existing.name !== input.displayName) {\n updates[\"Name\"] = input.displayName;\n }\n\n const updatedFields = Object.keys(updates);\n if (updatedFields.length > 0) {\n await base(WEBSITES_TABLE).update([{ id: existing.id, fields: updates }]);\n // The fill-blanks path writes real cells too — a resumed bootstrap that only\n // filled a blank `url` would otherwise leave Turso stale until the sync.\n await mirror?.site(existing.id, updates);\n }\n return { status: \"exists\", siteId: existing.id, updatedFields, skippedMismatches, healedDbRow };\n}\n","import { openBase, readAirtableConfig } from \"../../reports/airtable/client.js\";\nimport { ensureSite } from \"../../reports/airtable/ensure-site.js\";\n\nexport type EnsureSiteCommandOptions = {\n name?: string;\n url?: string;\n contact?: string;\n gitRepo?: string;\n cwd?: string;\n};\n\n/**\n * `ensure-site <slug>` — create/verify the fleet-inventory row for a new site.\n * Day-one step of the /new-site bootstrap skill. Fill-blanks-only; safe to re-run.\n */\nexport async function runEnsureSiteCommand(\n slug: string | undefined,\n opts: EnsureSiteCommandOptions,\n): Promise<{ output: string; code: number }> {\n if (!slug) return { output: \"Provide a <slug> (e.g. `ensure-site roalson`).\", code: 2 };\n try {\n const base = openBase(readAirtableConfig());\n // #539 Phase 5: bootstrapping a site CREATES the Websites row, so this is\n // the one site path that needs an INSERT mirror — every other one updates.\n const { makeSiteMirror } = await import(\"../../db/site-mirror.js\");\n const result = await ensureSite(\n base,\n {\n slug,\n ...(opts.name ? { displayName: opts.name } : {}),\n ...(opts.url ? { url: opts.url } : {}),\n ...(opts.contact ? { pointOfContact: opts.contact } : {}),\n ...(opts.gitRepo ? { gitRepo: opts.gitRepo } : {}),\n },\n await makeSiteMirror(),\n );\n // #664: a Name change on the exists path is a rename the operator asked\n // for with --name, not a blank the bootstrap filled — say so.\n const renamed = result.updatedFields.includes(\"Name\") ? ` — Name set to \"${opts.name}\"` : \"\";\n const blanks = result.updatedFields.filter((f) => f !== \"Name\");\n const filled = blanks.length > 0 ? ` — filled blank field(s): ${blanks.join(\", \")}` : \"\";\n const skipped =\n result.skippedMismatches.length > 0\n ? ` — differs from existing, left untouched (edit in Airtable): ${result.skippedMismatches.join(\", \")}`\n : \"\";\n // #645. Loud, and its own clause: a healed row means this site's leads were\n // being answered `unknown-site` and dropped until this run.\n const healed = result.healedDbRow\n ? ` — HEALED: the Turso row was MISSING and has been inserted; leads for this slug were being dropped (run \\`db replay-deadletters\\`)`\n : \"\";\n const nameNote =\n result.status === \"created\" && !opts.name\n ? ` — Name set to \"${slug}\"; retitle in Airtable before forms/announce go live (or re-run with --name)`\n : \"\";\n return {\n output: `[${slug}] ${result.status} (${result.siteId})${healed}${renamed}${filled}${skipped}${nameNote}`,\n code: 0,\n };\n } catch (err) {\n const e = err as { message?: string; exitCode?: number };\n return { output: e.message ?? String(err), code: e.exitCode ?? 1 };\n }\n}\n"],"mappings":"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","names":[]}
@@ -14,12 +14,13 @@ import {
14
14
  mirrorSiteField,
15
15
  mirrorSiteFields,
16
16
  mirrorSiteInsert,
17
+ siteRowExists,
17
18
  storeRenderedHtml
18
- } from "./chunk-WVNDEYXL.js";
19
- import "./chunk-6R56OKJZ.js";
19
+ } from "./chunk-GEUC5VGM.js";
20
+ import "./chunk-UIITN37J.js";
20
21
  import "./chunk-F3JWOPTG.js";
21
22
  import "./chunk-VAD43MOR.js";
22
- import "./chunk-3Z6X3BHU.js";
23
+ import "./chunk-KN52PM63.js";
23
24
  export {
24
25
  REPORT_LIST_COLUMNS,
25
26
  getReportById,
@@ -36,6 +37,7 @@ export {
36
37
  mirrorSiteField,
37
38
  mirrorSiteFields,
38
39
  mirrorSiteInsert,
40
+ siteRowExists,
39
41
  storeRenderedHtml
40
42
  };
41
- //# sourceMappingURL=fleet-state-UEVZ3X3J.js.map
43
+ //# sourceMappingURL=fleet-state-GJWGKTLD.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  describeNotifyTarget
3
- } from "./chunk-4763KQ6O.js";
4
- import "./chunk-QF6IQQFP.js";
3
+ } from "./chunk-PXRN2MER.js";
4
+ import "./chunk-Z7FDJ35L.js";
5
5
  import "./chunk-5ML7FMBD.js";
6
6
  import "./chunk-NO74DXDP.js";
7
7
  import "./chunk-I7NHLVVI.js";
@@ -16,7 +16,7 @@ import {
16
16
  siteSlug,
17
17
  toAirtableStatus,
18
18
  updateSiteField
19
- } from "./chunk-3Z6X3BHU.js";
19
+ } from "./chunk-KN52PM63.js";
20
20
  import "./chunk-2OP4JKIQ.js";
21
21
  import "./chunk-6VAL7XJT.js";
22
22
 
@@ -144,7 +144,7 @@ async function runFormsNotifyTargetCommand(site, opts) {
144
144
  return { output: `--set must be 'on' or 'off' (got '${opts.set}')`, code: 2 };
145
145
  }
146
146
  try {
147
- const { makeSiteMirror } = await import("./site-mirror-UKHREAD6.js");
147
+ const { makeSiteMirror } = await import("./site-mirror-H2FYMN55.js");
148
148
  const result = await formsNotifyTarget({
149
149
  siteMirror: await makeSiteMirror(),
150
150
  site: site.trim(),
@@ -164,4 +164,4 @@ export {
164
164
  formatNotifyTarget,
165
165
  runFormsNotifyTargetCommand
166
166
  };
167
- //# sourceMappingURL=forms-notify-target-2LWF5C5B.js.map
167
+ //# sourceMappingURL=forms-notify-target-4NPLX2UG.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  TURSO_IS_AUTHORITATIVE,
3
3
  mirrorWrite
4
- } from "./chunk-SVAAONYB.js";
4
+ } from "./chunk-WQLNUEZL.js";
5
5
  export {
6
6
  TURSO_IS_AUTHORITATIVE,
7
7
  mirrorWrite
8
8
  };
9
- //# sourceMappingURL=freeze-A6MUCZU4.js.map
9
+ //# sourceMappingURL=freeze-GUQ43EAU.js.map
@@ -3,9 +3,9 @@ import {
3
3
  } from "./chunk-PZQ3WED2.js";
4
4
  import {
5
5
  formatFleetWriteSummary
6
- } from "./chunk-5EEMTJMT.js";
7
- import "./chunk-XN37VTDB.js";
8
- import "./chunk-SVAAONYB.js";
6
+ } from "./chunk-ZH5LOQET.js";
7
+ import "./chunk-37B4LVB3.js";
8
+ import "./chunk-WQLNUEZL.js";
9
9
  import {
10
10
  detectSignalEvents,
11
11
  fleetSweptEvent
@@ -18,15 +18,15 @@ import {
18
18
  listWebsites,
19
19
  siteSlug,
20
20
  updateGitHubSignals
21
- } from "./chunk-3Z6X3BHU.js";
21
+ } from "./chunk-KN52PM63.js";
22
22
  import {
23
23
  makeGitHub
24
- } from "./chunk-XHHMM5HX.js";
24
+ } from "./chunk-43SW3FGW.js";
25
25
  import {
26
26
  recordFleetEventsBestEffort
27
- } from "./chunk-DMPHP7UP.js";
28
- import "./chunk-22GKJO5F.js";
29
- import "./chunk-OCNSIBMP.js";
27
+ } from "./chunk-EQQ4H6L3.js";
28
+ import "./chunk-6INOBNRO.js";
29
+ import "./chunk-T76MA2FH.js";
30
30
  import "./chunk-LBYOLBW7.js";
31
31
  import "./chunk-6VAL7XJT.js";
32
32
 
@@ -91,7 +91,7 @@ async function runGitHubSignalsCommand(opts, deps = {}) {
91
91
  );
92
92
  const sweptAt = (/* @__PURE__ */ new Date()).toISOString();
93
93
  const makeMirror = deps.makeMirror ?? (async () => {
94
- const { makeHealthMirrorBestEffort } = await import("./health-mirror-EB76EERV.js");
94
+ const { makeHealthMirrorBestEffort } = await import("./health-mirror-ONRT4DQ5.js");
95
95
  return makeHealthMirrorBestEffort();
96
96
  });
97
97
  const mirror = await makeMirror();
@@ -156,4 +156,4 @@ export {
156
156
  githubSignalsExitCode,
157
157
  runGitHubSignalsCommand
158
158
  };
159
- //# sourceMappingURL=github-signals-GAHNOAHS.js.map
159
+ //# sourceMappingURL=github-signals-DMU74SAX.js.map
@@ -7,12 +7,12 @@ import {
7
7
  } from "./chunk-HN6I2XWI.js";
8
8
  import {
9
9
  generateHeaderImage
10
- } from "./chunk-5UINJNAJ.js";
10
+ } from "./chunk-MZZDMBDT.js";
11
11
  import {
12
12
  ACTIVE_STATUSES,
13
13
  listWebsites,
14
14
  siteSlug
15
- } from "./chunk-3Z6X3BHU.js";
15
+ } from "./chunk-KN52PM63.js";
16
16
  import "./chunk-6VAL7XJT.js";
17
17
 
18
18
  // src/cli/commands/header-image.ts
@@ -54,7 +54,8 @@ async function generateForTargets(targets, opts, generate = generateHeaderImage)
54
54
  slug: siteSlug(row.name),
55
55
  // `exactOptionalPropertyTypes` rejects an explicit `settleMs: undefined`
56
56
  // against `settleMs?: number`, so omit the key entirely when unset.
57
- ...settleMs === void 0 ? {} : { settleMs }
57
+ ...settleMs === void 0 ? {} : { settleMs },
58
+ ...opts.consentSelector === void 0 ? {} : { consentSelector: opts.consentSelector }
58
59
  });
59
60
  if (opts.writeAirtable) {
60
61
  await uploadAttachment(row.id, "Header image", gen.bytes, gen.filename, gen.contentType, {
@@ -102,7 +103,7 @@ async function runHeaderImageCommand(site, opts) {
102
103
  }
103
104
  let withStore = opts;
104
105
  if (opts.writeAirtable && !opts.storeDb && process.env.TURSO_DATABASE_URL) {
105
- const { openDb, readDbConfig } = await import("./client-M2V6FHH5.js");
106
+ const { openDb, readDbConfig } = await import("./client-L7NAUG6J.js");
106
107
  const { storeHeaderImage } = await import("./header-images-SQBCE5OD.js");
107
108
  const db = await openDb(readDbConfig());
108
109
  withStore = { ...opts, storeDb: (id, img) => storeHeaderImage(db, id, img) };
@@ -115,4 +116,4 @@ export {
115
116
  resolveTargets,
116
117
  runHeaderImageCommand
117
118
  };
118
- //# sourceMappingURL=header-image-YN3AQRY3.js.map
119
+ //# sourceMappingURL=header-image-BRTOLHJF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/header-image.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { openBase, readAirtableConfig } from \"../../reports/airtable/client.js\";\nimport { listWebsites, siteSlug, ACTIVE_STATUSES } from \"../../reports/airtable/websites.js\";\nimport type { WebsiteRow } from \"../../reports/airtable/websites.js\";\nimport { uploadAttachment } from \"../../reports/airtable/attachments.js\";\nimport { generateHeaderImage } from \"../../reports/header-image/index.js\";\nimport type { StoredHeaderImage } from \"../../db/header-images.js\";\n\nexport type HeaderImageOptions = {\n all?: boolean;\n force?: boolean;\n writeAirtable?: boolean;\n outDir?: string;\n settleMs?: string;\n consentSelector?: string;\n /** Injected Turso store for the dual-write (#539, design D5): while Airtable\n * is still written (until the Phase 5 freeze), every upload ALSO lands the\n * bytes in sites.header_image* so the Turso read layer serves a real image.\n * Absent → Airtable-only (a local run without Turso env still works). */\n storeDb?: (siteId: string, img: StoredHeaderImage) => Promise<void>;\n};\n\n/** Which rows this invocation should act on. Pure, so it is unit-tested. */\nexport function resolveTargets(\n rows: readonly WebsiteRow[],\n // `| undefined` spelled out because `exactOptionalPropertyTypes` otherwise\n // rejects the caller passing through possibly-undefined CLI flags.\n opts: { site?: string | undefined; all?: boolean | undefined; force?: boolean | undefined },\n): WebsiteRow[] {\n if (opts.site) {\n const want = siteSlug(opts.site);\n return rows.filter((r) => siteSlug(r.name) === want);\n }\n if (!opts.all) return [];\n return rows.filter((r) => {\n if (!r.url) return false;\n if (r.status === null || !ACTIVE_STATUSES.has(r.status)) return false;\n return opts.force ? true : !r.headerImage;\n });\n}\n\n/** Parse the `--settle-ms <ms>` flag. Unset → undefined (the generator's own\n * default settle). `Number(\"abc\")` is NaN, which would sail through as a NaN\n * timeout and silently skip the settle entirely, so anything non-finite or\n * negative is rejected up front rather than producing a subtly-wrong capture. */\nexport function parseSettleMs(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const n = Number(value);\n if (!Number.isFinite(n) || n < 0) {\n throw Object.assign(\n new Error(`--settle-ms must be a non-negative number of milliseconds, got \"${value}\"`),\n { exitCode: 2 },\n );\n }\n return n;\n}\n\n/** Injected in tests so the file-writing branch can be exercised without\n * driving a real browser (mirrors `GenerateInput.shooter`). */\ntype Generate = typeof generateHeaderImage;\n\n/**\n * Generate a header image per target row and either upload it to Airtable or\n * write it locally for review. Split out of {@link runHeaderImageCommand} so\n * the local-output path is testable without an Airtable base.\n */\nexport async function generateForTargets(\n targets: readonly WebsiteRow[],\n opts: HeaderImageOptions,\n generate: Generate = generateHeaderImage,\n): Promise<{ output: string; code: number }> {\n const outDir = resolve(opts.outDir ?? \"reports\");\n const settleMs = parseSettleMs(opts.settleMs);\n // `reports/` does not exist on a fresh checkout, so the writeFile() below\n // would throw ENOENT for the first operator to run the default (local) path.\n // Create it once, before the loop, rather than per site.\n if (!opts.writeAirtable) await mkdir(outDir, { recursive: true });\n\n const lines: string[] = [];\n let failed = 0;\n\n for (const row of targets) {\n try {\n const gen = await generate({\n url: row.url,\n slug: siteSlug(row.name),\n // `exactOptionalPropertyTypes` rejects an explicit `settleMs: undefined`\n // against `settleMs?: number`, so omit the key entirely when unset.\n ...(settleMs === undefined ? {} : { settleMs }),\n ...(opts.consentSelector === undefined ? {} : { consentSelector: opts.consentSelector }),\n });\n if (opts.writeAirtable) {\n // replaceIn: the field must hold exactly the current header — see\n // uploadAttachment, where appending left readers on a stale [0].\n await uploadAttachment(row.id, \"Header image\", gen.bytes, gen.filename, gen.contentType, {\n replaceIn: \"Websites\",\n });\n let stored = \"\";\n if (opts.storeDb) {\n // Dual-write. A Turso failure must not void the Airtable upload —\n // but it must be VISIBLE, never a silent divergence.\n try {\n await opts.storeDb(row.id, {\n bytes: gen.bytes,\n filename: gen.filename,\n contentType: gen.contentType,\n generatedAt: new Date().toISOString(),\n });\n stored = \" + turso\";\n } catch (err) {\n stored = ` (⚠ turso store FAILED: ${err instanceof Error ? err.message : String(err)})`;\n }\n }\n lines.push(\n `✔ ${row.name} — uploaded ${gen.filename} (${(gen.bytes.byteLength / 1024 / 1024).toFixed(2)} MB)${stored}`,\n );\n } else {\n const path = resolve(outDir, gen.filename);\n await writeFile(path, gen.bytes);\n lines.push(`✔ ${row.name} — wrote ${path} (review, then re-run with --write-airtable)`);\n }\n } catch (err) {\n failed++;\n lines.push(`✖ ${row.name} — ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n lines.push(`${targets.length - failed}/${targets.length} generated.`);\n return { output: lines.join(\"\\n\"), code: failed > 0 ? 1 : 0 };\n}\n\n/**\n * `header-image [site]` — capture a site's live homepage and composite its\n * report header image. Defaults to writing the JPEG locally so the operator can\n * eyeball it; `--write-airtable` uploads it to the Websites row's Header image\n * field. `--all` backfills every live site that has no header image yet.\n */\nexport async function runHeaderImageCommand(\n site: string | undefined,\n opts: HeaderImageOptions,\n): Promise<{ output: string; code: number }> {\n const base = openBase(readAirtableConfig());\n const rows = await listWebsites(base);\n const targets = resolveTargets(rows, { site, all: opts.all, force: opts.force });\n if (targets.length === 0) {\n return {\n output: site ? `No site matched \"${site}\".` : \"No sites need a header image.\",\n code: 1,\n };\n }\n // Wire the Turso dual-write when the env is present; a local run without it\n // still works Airtable-only (the store is per-site error-isolated above).\n let withStore = opts;\n if (opts.writeAirtable && !opts.storeDb && process.env.TURSO_DATABASE_URL) {\n const { openDb, readDbConfig } = await import(\"../../db/client.js\");\n const { storeHeaderImage } = await import(\"../../db/header-images.js\");\n const db = await openDb(readDbConfig());\n withStore = { ...opts, storeDb: (id, img) => storeHeaderImage(db, id, img) };\n }\n return generateForTargets(targets, withStore);\n}\n"],"mappings":"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","names":[]}
@@ -5,20 +5,21 @@ import {
5
5
  appendSkipNotice,
6
6
  fleetWorkdir,
7
7
  prepareFleetSites
8
- } from "./chunk-LM2NHRCJ.js";
8
+ } from "./chunk-SHGIDTYF.js";
9
9
  import {
10
10
  resolveSites
11
- } from "./chunk-Z2K4JPQ3.js";
11
+ } from "./chunk-H445EH33.js";
12
12
  import {
13
13
  healthEndpoint
14
- } from "./chunk-WSJ7RO54.js";
15
- import "./chunk-R53VL3RI.js";
16
- import "./chunk-ZQV7UQNE.js";
14
+ } from "./chunk-XED2DNAI.js";
15
+ import "./chunk-5CJVUPJU.js";
16
+ import "./chunk-4UTJ4G6P.js";
17
+ import "./chunk-SQ4FSNYL.js";
17
18
  import "./chunk-Z3JXLULD.js";
18
19
  import "./chunk-LBYOLBW7.js";
19
20
  import "./chunk-RARREDQE.js";
20
21
  import "./chunk-XXTZBPUY.js";
21
- import "./chunk-AVEQUR44.js";
22
+ import "./chunk-EASYCD6F.js";
22
23
 
23
24
  // src/cli/commands/health-endpoint.ts
24
25
  import { resolve } from "path";
@@ -51,4 +52,4 @@ async function runHealthEndpointCommand(site, opts) {
51
52
  export {
52
53
  runHealthEndpointCommand
53
54
  };
54
- //# sourceMappingURL=health-endpoint-KVCJYWET.js.map
55
+ //# sourceMappingURL=health-endpoint-UCLMSSCN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/commands/health-endpoint.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { healthEndpoint } from \"../../recipes/health-endpoint/index.js\";\nimport type { RecipeResult } from \"../../types.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { runRecipeOverSites } from \"../fleet/run-recipe-over-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\n\nexport type HealthEndpointCommandOptions = {\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"\"}`;\n if (r.status === \"failed\") return `[${r.site}] failed: ${r.notes ?? \"\"}`;\n return `[${r.site}] applied: ${r.commits.length} commit(s)\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runHealthEndpointCommand(\n site: string | undefined,\n opts: HealthEndpointCommandOptions,\n): Promise<{ output: string; code: number }> {\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n ...(opts.workdir !== undefined ? { workdir: opts.workdir } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n const results = await runRecipeOverSites(\"health-endpoint\", sites, (s) => healthEndpoint(s));\n\n const output = results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"failed\") ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AAcxB,SAAS,aAAa,GAAyB;AAC7C,MAAI,EAAE,WAAW,OAAQ,QAAO,IAAI,EAAE,IAAI,WAAW,EAAE,SAAS,EAAE;AAClE,MAAI,EAAE,WAAW,SAAU,QAAO,IAAI,EAAE,IAAI,aAAa,EAAE,SAAS,EAAE;AACtE,SAAO,IAAI,EAAE,IAAI,cAAc,EAAE,QAAQ,MAAM;AAAA,EAAe,EAAE,SAAS,EAAE;AAC7E;AAEA,eAAsB,yBACpB,MACA,MAC2C;AAC3C,QAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,QAAQ,IAAI;AAEvD,MAAI,QAAQ,MAAM,aAAa;AAAA,IAC7B,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IACxD,GAAI,KAAK,YAAY,SAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,IAC9D;AAAA,EACF,CAAC;AAED,MAAI,UAAyB,CAAC;AAC9B,MAAI,KAAK,OAAO;AACd,UAAM,UAAU,KAAK,WAAW,aAAa;AAC7C,UAAM,OAAO,MAAM,kBAAkB,OAAO,EAAE,QAAQ,CAAC;AACvD,YAAQ,KAAK;AACb,cAAU,KAAK;AAAA,EACjB;AAEA,QAAM,UAAU,MAAM,mBAAmB,mBAAmB,OAAO,CAAC,MAAM,eAAe,CAAC,CAAC;AAE3F,QAAM,SAAS,QAAQ,IAAI,YAAY,EAAE,KAAK,IAAI;AAClD,QAAM,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AAC9D,SAAO,EAAE,QAAQ,iBAAiB,QAAQ,OAAO,GAAG,KAAK;AAC3D;","names":[]}
1
+ {"version":3,"sources":["../src/cli/commands/health-endpoint.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { healthEndpoint } from \"../../recipes/health-endpoint/index.js\";\nimport type { RecipeResult } from \"../../types.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { runRecipeOverSites } from \"../fleet/run-recipe-over-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\n\nexport type HealthEndpointCommandOptions = {\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"\"}`;\n if (r.status === \"failed\") return `[${r.site}] failed: ${r.notes ?? \"\"}`;\n return `[${r.site}] applied: ${r.commits.length} commit(s)\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runHealthEndpointCommand(\n site: string | undefined,\n opts: HealthEndpointCommandOptions,\n): Promise<{ output: string; code: number }> {\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n ...(opts.workdir !== undefined ? { workdir: opts.workdir } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n const results = await runRecipeOverSites(\"health-endpoint\", sites, (s) => healthEndpoint(s));\n\n const output = results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"failed\") ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AAcxB,SAAS,aAAa,GAAyB;AAC7C,MAAI,EAAE,WAAW,OAAQ,QAAO,IAAI,EAAE,IAAI,WAAW,EAAE,SAAS,EAAE;AAClE,MAAI,EAAE,WAAW,SAAU,QAAO,IAAI,EAAE,IAAI,aAAa,EAAE,SAAS,EAAE;AACtE,SAAO,IAAI,EAAE,IAAI,cAAc,EAAE,QAAQ,MAAM;AAAA,EAAe,EAAE,SAAS,EAAE;AAC7E;AAEA,eAAsB,yBACpB,MACA,MAC2C;AAC3C,QAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,QAAQ,IAAI;AAEvD,MAAI,QAAQ,MAAM,aAAa;AAAA,IAC7B,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IACxD,GAAI,KAAK,YAAY,SAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,IAC9D;AAAA,EACF,CAAC;AAED,MAAI,UAAyB,CAAC;AAC9B,MAAI,KAAK,OAAO;AACd,UAAM,UAAU,KAAK,WAAW,aAAa;AAC7C,UAAM,OAAO,MAAM,kBAAkB,OAAO,EAAE,QAAQ,CAAC;AACvD,YAAQ,KAAK;AACb,cAAU,KAAK;AAAA,EACjB;AAEA,QAAM,UAAU,MAAM,mBAAmB,mBAAmB,OAAO,CAAC,MAAM,eAAe,CAAC,CAAC;AAE3F,QAAM,SAAS,QAAQ,IAAI,YAAY,EAAE,KAAK,IAAI;AAClD,QAAM,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AAC9D,SAAO,EAAE,QAAQ,iBAAiB,QAAQ,OAAO,GAAG,KAAK;AAC3D;","names":[]}
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  mirrorHealthFields,
3
3
  mirrorScheduleFields
4
- } from "./chunk-WVNDEYXL.js";
5
- import "./chunk-6R56OKJZ.js";
4
+ } from "./chunk-GEUC5VGM.js";
5
+ import "./chunk-UIITN37J.js";
6
6
  import {
7
7
  TURSO_IS_AUTHORITATIVE
8
- } from "./chunk-SVAAONYB.js";
8
+ } from "./chunk-WQLNUEZL.js";
9
9
  import "./chunk-F3JWOPTG.js";
10
10
  import "./chunk-VAD43MOR.js";
11
- import "./chunk-3Z6X3BHU.js";
11
+ import "./chunk-KN52PM63.js";
12
12
  import {
13
13
  openDb,
14
14
  readDbConfig
15
- } from "./chunk-22GKJO5F.js";
16
- import "./chunk-OCNSIBMP.js";
15
+ } from "./chunk-6INOBNRO.js";
16
+ import "./chunk-T76MA2FH.js";
17
17
  import "./chunk-6VAL7XJT.js";
18
18
 
19
19
  // src/audits/health-mirror.ts
@@ -43,4 +43,4 @@ export {
43
43
  makeHealthMirrorBestEffort,
44
44
  makeScheduleMirrorBestEffort
45
45
  };
46
- //# sourceMappingURL=health-mirror-EB76EERV.js.map
46
+ //# sourceMappingURL=health-mirror-ONRT4DQ5.js.map
@@ -14,9 +14,9 @@ import {
14
14
  renderedHtmlUrl,
15
15
  scheduleColumnFor,
16
16
  siteValueFor
17
- } from "./chunk-6R56OKJZ.js";
17
+ } from "./chunk-UIITN37J.js";
18
18
  import "./chunk-VAD43MOR.js";
19
- import "./chunk-3Z6X3BHU.js";
19
+ import "./chunk-KN52PM63.js";
20
20
  export {
21
21
  EXCLUDED_WEBSITE_FIELDS,
22
22
  HEALTH_BOOLEAN,
@@ -34,4 +34,4 @@ export {
34
34
  scheduleColumnFor,
35
35
  siteValueFor
36
36
  };
37
- //# sourceMappingURL=import-airtable-TAKSN4NV.js.map
37
+ //# sourceMappingURL=import-airtable-IIK2QUUF.js.map