@reddoorla/maintenance 0.96.0 → 0.98.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 +5 -6
  2. package/dist/{announce-45HVP4J4.js → announce-2FH2KBQQ.js} +39 -31
  3. package/dist/announce-2FH2KBQQ.js.map +1 -0
  4. package/dist/attachments-JFGFQRXQ.js +10 -0
  5. package/dist/{blux-RUFMNOUJ.js → blux-NXQLMS4W.js} +5 -5
  6. package/dist/{bump-deps-EL3TKMIL.js → bump-deps-54K4ECP3.js} +6 -6
  7. package/dist/{chunk-IMYL67JV.js → chunk-3RLDX3Q2.js} +5 -5
  8. package/dist/{chunk-EQQ4H6L3.js → chunk-3YALLSBF.js} +2 -2
  9. package/dist/{chunk-LAJ3FF54.js → chunk-5UI4FERC.js} +16 -5
  10. package/dist/chunk-5UI4FERC.js.map +1 -0
  11. package/dist/{chunk-CA6ADGOC.js → chunk-6PGXKN6F.js} +2 -2
  12. package/dist/{chunk-Y5BVR4HW.js → chunk-6THEZQLA.js} +3 -3
  13. package/dist/chunk-ASLDCWBF.js +41 -0
  14. package/dist/chunk-ASLDCWBF.js.map +1 -0
  15. package/dist/{chunk-DVJNYPFR.js → chunk-AYDQQBNG.js} +2 -2
  16. package/dist/{chunk-OTEVKRAH.js → chunk-B2BRFWJY.js} +7 -16
  17. package/dist/chunk-B2BRFWJY.js.map +1 -0
  18. package/dist/{chunk-GEUC5VGM.js → chunk-BINFZQ2T.js} +49 -4
  19. package/dist/chunk-BINFZQ2T.js.map +1 -0
  20. package/dist/{chunk-T76MA2FH.js → chunk-CP6MVZ5X.js} +27 -1
  21. package/dist/{chunk-T76MA2FH.js.map → chunk-CP6MVZ5X.js.map} +1 -1
  22. package/dist/{chunk-72FJZ6LO.js → chunk-DRNZVORX.js} +26 -22
  23. package/dist/chunk-DRNZVORX.js.map +1 -0
  24. package/dist/{chunk-XY7YV2YQ.js → chunk-DXZRWW2F.js} +65 -10
  25. package/dist/chunk-DXZRWW2F.js.map +1 -0
  26. package/dist/{chunk-SHGIDTYF.js → chunk-DYTYPKFN.js} +2 -2
  27. package/dist/chunk-DZZ5KRTB.js +23 -0
  28. package/dist/chunk-DZZ5KRTB.js.map +1 -0
  29. package/dist/{chunk-NVLREB5R.js → chunk-EN6CTBUN.js} +7 -7
  30. package/dist/{chunk-ZH5LOQET.js → chunk-FHFXJ3EM.js} +7 -5
  31. package/dist/chunk-FHFXJ3EM.js.map +1 -0
  32. package/dist/{chunk-3EA43S3R.js → chunk-GRF2RYEO.js} +12 -12
  33. package/dist/{chunk-RRE74VWI.js → chunk-HSMN35LU.js} +2 -2
  34. package/dist/chunk-ICSRWW5Q.js +148 -0
  35. package/dist/chunk-ICSRWW5Q.js.map +1 -0
  36. package/dist/{chunk-XG2A6GIG.js → chunk-IDBPII6G.js} +4 -4
  37. package/dist/{chunk-XG2A6GIG.js.map → chunk-IDBPII6G.js.map} +1 -1
  38. package/dist/{chunk-ECDJDHKT.js → chunk-JHJNNJLG.js} +2 -2
  39. package/dist/{chunk-QFSL2L2B.js → chunk-L5F3WYIY.js} +81 -31
  40. package/dist/chunk-L5F3WYIY.js.map +1 -0
  41. package/dist/{chunk-XED2DNAI.js → chunk-LAG6IP7Y.js} +7 -7
  42. package/dist/{chunk-UIITN37J.js → chunk-LF2TJN4X.js} +2 -2
  43. package/dist/chunk-LF2TJN4X.js.map +1 -0
  44. package/dist/{chunk-SQ4FSNYL.js → chunk-LUF52EIY.js} +2 -2
  45. package/dist/{chunk-MZZDMBDT.js → chunk-LZMAG73U.js} +19 -19
  46. package/dist/chunk-LZMAG73U.js.map +1 -0
  47. package/dist/{chunk-6INOBNRO.js → chunk-MNRWHSFS.js} +2 -2
  48. package/dist/{chunk-CGQZFQAY.js → chunk-MVKNU4QD.js} +2 -3
  49. package/dist/chunk-MVKNU4QD.js.map +1 -0
  50. package/dist/{chunk-62YWOFVN.js → chunk-ORTOMEYR.js} +3 -3
  51. package/dist/{chunk-62YWOFVN.js.map → chunk-ORTOMEYR.js.map} +1 -1
  52. package/dist/{chunk-44SDGPGQ.js → chunk-PZZ6HM5T.js} +3 -3
  53. package/dist/chunk-RQJFGK3A.js +51 -0
  54. package/dist/chunk-RQJFGK3A.js.map +1 -0
  55. package/dist/{chunk-H445EH33.js → chunk-S2PLX4XK.js} +10 -7
  56. package/dist/chunk-S2PLX4XK.js.map +1 -0
  57. package/dist/{chunk-KN52PM63.js → chunk-TC4GANMX.js} +47 -149
  58. package/dist/chunk-TC4GANMX.js.map +1 -0
  59. package/dist/{chunk-F3JWOPTG.js → chunk-TEMQPSCM.js} +45 -105
  60. package/dist/chunk-TEMQPSCM.js.map +1 -0
  61. package/dist/{chunk-4UTJ4G6P.js → chunk-TJLKWQOX.js} +2 -2
  62. package/dist/{chunk-A5QKNOXW.js → chunk-TTT6HYPW.js} +47 -10
  63. package/dist/chunk-TTT6HYPW.js.map +1 -0
  64. package/dist/{chunk-VEIIUCYL.js → chunk-TV76A6GN.js} +2 -2
  65. package/dist/{chunk-D3CTOCUR.js → chunk-TVZ6QCOE.js} +3 -3
  66. package/dist/chunk-UPE6D4AT.js +69 -0
  67. package/dist/chunk-UPE6D4AT.js.map +1 -0
  68. package/dist/{chunk-BIYQN7FH.js → chunk-VCPTOZ56.js} +31 -1
  69. package/dist/{chunk-BIYQN7FH.js.map → chunk-VCPTOZ56.js.map} +1 -1
  70. package/dist/chunk-VQMAAQ5M.js +53 -0
  71. package/dist/chunk-VQMAAQ5M.js.map +1 -0
  72. package/dist/{chunk-EASYCD6F.js → chunk-WMF5S2MB.js} +1 -1
  73. package/dist/{chunk-EASYCD6F.js.map → chunk-WMF5S2MB.js.map} +1 -1
  74. package/dist/{chunk-37B4LVB3.js → chunk-X56LAKPR.js} +3 -3
  75. package/dist/chunk-X56LAKPR.js.map +1 -0
  76. package/dist/{chunk-IY6256GK.js → chunk-YJBSB4LP.js} +6 -1
  77. package/dist/chunk-YJBSB4LP.js.map +1 -0
  78. package/dist/{chunk-P4A6D6HO.js → chunk-ZEE5WQYU.js} +32 -18
  79. package/dist/chunk-ZEE5WQYU.js.map +1 -0
  80. package/dist/cli/bin.js +92 -50
  81. package/dist/cli/bin.js.map +1 -1
  82. package/dist/cli/commands/audit.d.ts +33 -3
  83. package/dist/cli/commands/audit.js +26 -23
  84. package/dist/cli/commands/audit.js.map +1 -1
  85. package/dist/client-3XGSZMLU.js +11 -0
  86. package/dist/{convert-to-pnpm-4DON7IFS.js → convert-to-pnpm-U2CRNKNY.js} +6 -6
  87. package/dist/{db-5K4CDEGJ.js → db-7XYTBIPH.js} +25 -18
  88. package/dist/db-7XYTBIPH.js.map +1 -0
  89. package/dist/{deadletter-G4M3HSVM.js → deadletter-A7RQVNG3.js} +8 -4
  90. package/dist/{digest-5AJGWS33.js → digest-AMXRGWZA.js} +34 -33
  91. package/dist/digest-AMXRGWZA.js.map +1 -0
  92. package/dist/{digest-collectors-MC5NWEUA.js → digest-collectors-CX2NCGS7.js} +15 -12
  93. package/dist/ensure-site-F2WFCWWA.js +70 -0
  94. package/dist/ensure-site-F2WFCWWA.js.map +1 -0
  95. package/dist/ensure-site-JEKV2ODE.js +105 -0
  96. package/dist/ensure-site-JEKV2ODE.js.map +1 -0
  97. package/dist/{ensure-site-XESZHZEB.js → ensure-site-OO4UPWNQ.js} +19 -42
  98. package/dist/ensure-site-OO4UPWNQ.js.map +1 -0
  99. package/dist/fleet-events-CkOZpMVC.d.ts +435 -0
  100. package/dist/{fleet-state-GJWGKTLD.js → fleet-state-RJROYXKO.js} +17 -7
  101. package/dist/{forms-notify-target-4NPLX2UG.js → forms-notify-target-DK5R326N.js} +17 -13
  102. package/dist/forms-notify-target-DK5R326N.js.map +1 -0
  103. package/dist/{github-signals-DMU74SAX.js → github-signals-RGRPYTUB.js} +20 -15
  104. package/dist/github-signals-RGRPYTUB.js.map +1 -0
  105. package/dist/{header-image-BRTOLHJF.js → header-image-43ZIEJKP.js} +13 -17
  106. package/dist/header-image-43ZIEJKP.js.map +1 -0
  107. package/dist/{health-endpoint-UCLMSSCN.js → health-endpoint-K5LXDPGE.js} +7 -7
  108. package/dist/{health-mirror-ONRT4DQ5.js → health-mirror-WZUHWCCV.js} +10 -10
  109. package/dist/{import-airtable-IIK2QUUF.js → import-airtable-UBF5GYAL.js} +3 -3
  110. package/dist/index.d.ts +102 -494
  111. package/dist/index.js +62 -52
  112. package/dist/index.js.map +1 -1
  113. package/dist/{init-3LMZTCVD.js → init-OFITGMOP.js} +16 -16
  114. package/dist/{launch-XTDMC6LD.js → launch-AJY3TGTQ.js} +37 -35
  115. package/dist/launch-AJY3TGTQ.js.map +1 -0
  116. package/dist/{lighthouse-52WSPZ5D.js → lighthouse-RFMFREEX.js} +2 -2
  117. package/dist/lighthouse-airtable-M45OPVRV.js +14 -0
  118. package/dist/{chunk-IHHAYXKY.js → match-harness-CFELJA57.js} +70 -4
  119. package/dist/match-harness-CFELJA57.js.map +1 -0
  120. package/dist/migrate-EZL55AWA.js +7 -0
  121. package/dist/notify-K3WVH3DM.js +1 -1
  122. package/dist/{onboard-CZYBWVWH.js → onboard-F7RTLMDZ.js} +6 -6
  123. package/dist/{orchestrate-TGDFGY52.js → orchestrate-SAIFXZIW.js} +13 -10
  124. package/dist/parity-2JGVUCZD.js +14 -0
  125. package/dist/{pipeline-UUPXOS2J.js → pipeline-TCSNVDQZ.js} +3 -3
  126. package/dist/{preflight-POZZI3GN.js → preflight-6XGVVO2U.js} +35 -11
  127. package/dist/preflight-6XGVVO2U.js.map +1 -0
  128. package/dist/{prismic-ci-AHY5ULJR.js → prismic-ci-XMX7A5E4.js} +11 -11
  129. package/dist/prismic-ci-XMX7A5E4.js.map +1 -0
  130. package/dist/{prismic-models-URYGODNY.js → prismic-models-7GKFAAFA.js} +19 -16
  131. package/dist/prismic-models-7GKFAAFA.js.map +1 -0
  132. package/dist/prospect/types.d.ts +44 -2
  133. package/dist/prospect/types.js +1 -1
  134. package/dist/{prospect-audit-AJEE3Z4L.js → prospect-audit-KWP5P5U2.js} +37 -5
  135. package/dist/prospect-audit-KWP5P5U2.js.map +1 -0
  136. package/dist/{protection-audit-3J3UEOVT.js → protection-audit-YXJKFU6O.js} +3 -3
  137. package/dist/{protection-audit-3J3UEOVT.js.map → protection-audit-YXJKFU6O.js.map} +1 -1
  138. package/dist/recipes/sync-configs.js +3 -3
  139. package/dist/{render-MHUUHPLN.js → render-NWUAX6RN.js} +3 -3
  140. package/dist/{render-from-row-65DC6ZP3.js → render-from-row-75JTED2Z.js} +6 -4
  141. package/dist/{renovate-dispatch-ONJMBUHJ.js → renovate-dispatch-ZZQXT7DA.js} +13 -8
  142. package/dist/{renovate-dispatch-ONJMBUHJ.js.map → renovate-dispatch-ZZQXT7DA.js.map} +1 -1
  143. package/dist/replay-HB44TAII.js +77 -0
  144. package/dist/replay-HB44TAII.js.map +1 -0
  145. package/dist/{report-RC5LGPU3.js → report-MVPWS7WP.js} +102 -58
  146. package/dist/report-MVPWS7WP.js.map +1 -0
  147. package/dist/{report-mirror-KKZZ6RMZ.js → report-mirror-O6IDFDWU.js} +28 -10
  148. package/dist/report-mirror-O6IDFDWU.js.map +1 -0
  149. package/dist/roster-EJ3ILR52.js +19 -0
  150. package/dist/roster-EJ3ILR52.js.map +1 -0
  151. package/dist/{screenouts-7P5GOZMV.js → screenouts-7NQUWHOJ.js} +14 -1
  152. package/dist/screenouts-7NQUWHOJ.js.map +1 -0
  153. package/dist/{self-updating-RKKIYNV4.js → self-updating-KX5FMGEO.js} +7 -7
  154. package/dist/{selftest-AFLR7YV7.js → selftest-KABY2CYJ.js} +21 -17
  155. package/dist/{selftest-AFLR7YV7.js.map → selftest-KABY2CYJ.js.map} +1 -1
  156. package/dist/site-create-ZU3ACBTO.js +45 -0
  157. package/dist/site-create-ZU3ACBTO.js.map +1 -0
  158. package/dist/{site-mirror-H2FYMN55.js → site-mirror-TKTDWYP3.js} +10 -10
  159. package/dist/site-mirror-TKTDWYP3.js.map +1 -0
  160. package/dist/{smoke-suite-BWHR3XX5.js → smoke-suite-QQMV7TNA.js} +7 -7
  161. package/dist/{submissions-JDZP35JM.js → submissions-4I66W6QK.js} +11 -1
  162. package/dist/{submissions-JDZP35JM.js.map → submissions-4I66W6QK.js.map} +1 -1
  163. package/dist/{submissions-II5J35QM.js → submissions-K5UXGZUN.js} +12 -7
  164. package/dist/submissions-K5UXGZUN.js.map +1 -0
  165. package/dist/{svelte-codemods-QWGIRNN6.js → svelte-codemods-YFN4TEGV.js} +6 -6
  166. package/dist/{sync-NKPDCMYW.js → sync-F4USL4K5.js} +6 -6
  167. package/dist/{sync-configs-HGLQV55H.js → sync-configs-HBXS3D7C.js} +6 -6
  168. package/dist/turso-KQKBBQCK.js +24 -0
  169. package/dist/turso-KQKBBQCK.js.map +1 -0
  170. package/dist/{upgrade-WZ44IARG.js → upgrade-XOJMDIT4.js} +6 -6
  171. package/dist/util/git.d.ts +1 -1
  172. package/dist/util/git.js +1 -1
  173. package/dist/{websites-6DHIHJ2D.js → websites-Y6FN2XFD.js} +26 -21
  174. package/dist/{write-audits-to-airtable-BIK6LNVC.js → write-audits-to-airtable-TI3JMWSY.js} +6 -4
  175. package/package.json +1 -1
  176. package/dist/airtable-SJV4ZSMS.js +0 -9
  177. package/dist/announce-45HVP4J4.js.map +0 -1
  178. package/dist/attachments-NLZIJ5NU.js +0 -9
  179. package/dist/chunk-37B4LVB3.js.map +0 -1
  180. package/dist/chunk-72FJZ6LO.js.map +0 -1
  181. package/dist/chunk-74QRWE6G.js +0 -53
  182. package/dist/chunk-74QRWE6G.js.map +0 -1
  183. package/dist/chunk-A5QKNOXW.js.map +0 -1
  184. package/dist/chunk-CGQZFQAY.js.map +0 -1
  185. package/dist/chunk-F3JWOPTG.js.map +0 -1
  186. package/dist/chunk-GEUC5VGM.js.map +0 -1
  187. package/dist/chunk-H445EH33.js.map +0 -1
  188. package/dist/chunk-IHHAYXKY.js.map +0 -1
  189. package/dist/chunk-IY6256GK.js.map +0 -1
  190. package/dist/chunk-KN52PM63.js.map +0 -1
  191. package/dist/chunk-LAJ3FF54.js.map +0 -1
  192. package/dist/chunk-MZZDMBDT.js.map +0 -1
  193. package/dist/chunk-OTEVKRAH.js.map +0 -1
  194. package/dist/chunk-P4A6D6HO.js.map +0 -1
  195. package/dist/chunk-QFSL2L2B.js.map +0 -1
  196. package/dist/chunk-UIITN37J.js.map +0 -1
  197. package/dist/chunk-XY7YV2YQ.js.map +0 -1
  198. package/dist/chunk-YFAXOD7Z.js +0 -42
  199. package/dist/chunk-YFAXOD7Z.js.map +0 -1
  200. package/dist/chunk-ZH5LOQET.js.map +0 -1
  201. package/dist/client-L7NAUG6J.js +0 -11
  202. package/dist/db-5K4CDEGJ.js.map +0 -1
  203. package/dist/digest-5AJGWS33.js.map +0 -1
  204. package/dist/ensure-site-XESZHZEB.js.map +0 -1
  205. package/dist/fleet-events-cF2Om88w.d.ts +0 -24
  206. package/dist/forms-notify-target-4NPLX2UG.js.map +0 -1
  207. package/dist/github-signals-DMU74SAX.js.map +0 -1
  208. package/dist/header-image-BRTOLHJF.js.map +0 -1
  209. package/dist/launch-XTDMC6LD.js.map +0 -1
  210. package/dist/lighthouse-airtable-3NOFB42B.js +0 -12
  211. package/dist/match-harness-OW45CB5H.js +0 -77
  212. package/dist/match-harness-OW45CB5H.js.map +0 -1
  213. package/dist/migrate-NE3DUMTM.js +0 -7
  214. package/dist/parity-AEKYSLN6.js +0 -14
  215. package/dist/preflight-POZZI3GN.js.map +0 -1
  216. package/dist/prismic-ci-AHY5ULJR.js.map +0 -1
  217. package/dist/prismic-models-URYGODNY.js.map +0 -1
  218. package/dist/prospect-audit-AJEE3Z4L.js.map +0 -1
  219. package/dist/replay-4FVFOMHH.js +0 -54
  220. package/dist/replay-4FVFOMHH.js.map +0 -1
  221. package/dist/report-RC5LGPU3.js.map +0 -1
  222. package/dist/report-mirror-KKZZ6RMZ.js.map +0 -1
  223. package/dist/screenouts-7P5GOZMV.js.map +0 -1
  224. package/dist/site-mirror-H2FYMN55.js.map +0 -1
  225. package/dist/submissions-II5J35QM.js.map +0 -1
  226. package/dist/write-audits-to-airtable-BIK6LNVC.js.map +0 -1
  227. /package/dist/{airtable-SJV4ZSMS.js.map → attachments-JFGFQRXQ.js.map} +0 -0
  228. /package/dist/{blux-RUFMNOUJ.js.map → blux-NXQLMS4W.js.map} +0 -0
  229. /package/dist/{bump-deps-EL3TKMIL.js.map → bump-deps-54K4ECP3.js.map} +0 -0
  230. /package/dist/{chunk-IMYL67JV.js.map → chunk-3RLDX3Q2.js.map} +0 -0
  231. /package/dist/{chunk-EQQ4H6L3.js.map → chunk-3YALLSBF.js.map} +0 -0
  232. /package/dist/{chunk-CA6ADGOC.js.map → chunk-6PGXKN6F.js.map} +0 -0
  233. /package/dist/{chunk-Y5BVR4HW.js.map → chunk-6THEZQLA.js.map} +0 -0
  234. /package/dist/{chunk-DVJNYPFR.js.map → chunk-AYDQQBNG.js.map} +0 -0
  235. /package/dist/{chunk-SHGIDTYF.js.map → chunk-DYTYPKFN.js.map} +0 -0
  236. /package/dist/{chunk-NVLREB5R.js.map → chunk-EN6CTBUN.js.map} +0 -0
  237. /package/dist/{chunk-3EA43S3R.js.map → chunk-GRF2RYEO.js.map} +0 -0
  238. /package/dist/{chunk-RRE74VWI.js.map → chunk-HSMN35LU.js.map} +0 -0
  239. /package/dist/{chunk-ECDJDHKT.js.map → chunk-JHJNNJLG.js.map} +0 -0
  240. /package/dist/{chunk-XED2DNAI.js.map → chunk-LAG6IP7Y.js.map} +0 -0
  241. /package/dist/{chunk-SQ4FSNYL.js.map → chunk-LUF52EIY.js.map} +0 -0
  242. /package/dist/{chunk-6INOBNRO.js.map → chunk-MNRWHSFS.js.map} +0 -0
  243. /package/dist/{chunk-44SDGPGQ.js.map → chunk-PZZ6HM5T.js.map} +0 -0
  244. /package/dist/{chunk-4UTJ4G6P.js.map → chunk-TJLKWQOX.js.map} +0 -0
  245. /package/dist/{chunk-VEIIUCYL.js.map → chunk-TV76A6GN.js.map} +0 -0
  246. /package/dist/{chunk-D3CTOCUR.js.map → chunk-TVZ6QCOE.js.map} +0 -0
  247. /package/dist/{attachments-NLZIJ5NU.js.map → client-3XGSZMLU.js.map} +0 -0
  248. /package/dist/{convert-to-pnpm-4DON7IFS.js.map → convert-to-pnpm-U2CRNKNY.js.map} +0 -0
  249. /package/dist/{client-L7NAUG6J.js.map → deadletter-A7RQVNG3.js.map} +0 -0
  250. /package/dist/{deadletter-G4M3HSVM.js.map → digest-collectors-CX2NCGS7.js.map} +0 -0
  251. /package/dist/{digest-collectors-MC5NWEUA.js.map → fleet-state-RJROYXKO.js.map} +0 -0
  252. /package/dist/{health-endpoint-UCLMSSCN.js.map → health-endpoint-K5LXDPGE.js.map} +0 -0
  253. /package/dist/{health-mirror-ONRT4DQ5.js.map → health-mirror-WZUHWCCV.js.map} +0 -0
  254. /package/dist/{fleet-state-GJWGKTLD.js.map → import-airtable-UBF5GYAL.js.map} +0 -0
  255. /package/dist/{init-3LMZTCVD.js.map → init-OFITGMOP.js.map} +0 -0
  256. /package/dist/{import-airtable-IIK2QUUF.js.map → lighthouse-RFMFREEX.js.map} +0 -0
  257. /package/dist/{lighthouse-52WSPZ5D.js.map → lighthouse-airtable-M45OPVRV.js.map} +0 -0
  258. /package/dist/{lighthouse-airtable-3NOFB42B.js.map → migrate-EZL55AWA.js.map} +0 -0
  259. /package/dist/{onboard-CZYBWVWH.js.map → onboard-F7RTLMDZ.js.map} +0 -0
  260. /package/dist/{migrate-NE3DUMTM.js.map → orchestrate-SAIFXZIW.js.map} +0 -0
  261. /package/dist/{orchestrate-TGDFGY52.js.map → parity-2JGVUCZD.js.map} +0 -0
  262. /package/dist/{parity-AEKYSLN6.js.map → pipeline-TCSNVDQZ.js.map} +0 -0
  263. /package/dist/{render-MHUUHPLN.js.map → render-NWUAX6RN.js.map} +0 -0
  264. /package/dist/{pipeline-UUPXOS2J.js.map → render-from-row-75JTED2Z.js.map} +0 -0
  265. /package/dist/{self-updating-RKKIYNV4.js.map → self-updating-KX5FMGEO.js.map} +0 -0
  266. /package/dist/{smoke-suite-BWHR3XX5.js.map → smoke-suite-QQMV7TNA.js.map} +0 -0
  267. /package/dist/{svelte-codemods-QWGIRNN6.js.map → svelte-codemods-YFN4TEGV.js.map} +0 -0
  268. /package/dist/{sync-NKPDCMYW.js.map → sync-F4USL4K5.js.map} +0 -0
  269. /package/dist/{sync-configs-HGLQV55H.js.map → sync-configs-HBXS3D7C.js.map} +0 -0
  270. /package/dist/{upgrade-WZ44IARG.js.map → upgrade-XOJMDIT4.js.map} +0 -0
  271. /package/dist/{render-from-row-65DC6ZP3.js.map → websites-Y6FN2XFD.js.map} +0 -0
  272. /package/dist/{websites-6DHIHJ2D.js.map → write-audits-to-airtable-TI3JMWSY.js.map} +0 -0
package/README.md CHANGED
@@ -158,7 +158,7 @@ Installs the matching harness used to rebuild a site against a live reference (a
158
158
  ```bash
159
159
  reddoor-maint match-harness --ref https://client.webflow.io
160
160
  reddoor-maint match-harness acme --ref https://acme.webflow.io --cand http://localhost:4173
161
- reddoor-maint match-harness --fleet airtable --ref https://client.webflow.io --matrix 1440,834,390
161
+ reddoor-maint match-harness --fleet turso --ref https://client.webflow.io --matrix 1440,834,390
162
162
  ```
163
163
 
164
164
  `--ref` is **required**. The harness gates against a live reference; with no reference it can only ever report an absence of errors, so the recipe refuses instead of installing something that goes green on nothing. `--cand` defaults to `http://localhost:5173` and `--matrix` to `1440,834,390`.
@@ -419,10 +419,10 @@ Nothing is written and nothing is sent.
419
419
  0. **Prereq: refresh Lighthouse scores on each Websites row.** From each site's checkout:
420
420
 
421
421
  ```bash
422
- reddoor-maint audit lighthouse --write-airtable
422
+ reddoor-maint audit lighthouse --write-back
423
423
  ```
424
424
 
425
- This runs Lighthouse and writes the 4 scores directly to the matching Websites row (slug auto-derived from `package.json#name`; pass `--write-airtable=<slug>` to override), along with a `Last lighthouse audit at` timestamp. The report orchestrator copies these into the new Reports row — drafting a report for a site missing scores fails with a clear error.
425
+ This runs Lighthouse and writes the 4 scores directly to the matching Websites row (slug auto-derived from `package.json#name`; pass `--write-back=<slug>` to override), along with a `Last lighthouse audit at` timestamp. The report orchestrator copies these into the new Reports row — drafting a report for a site missing scores fails with a clear error.
426
426
 
427
427
  1. **Draft overdue reports**
428
428
 
@@ -481,10 +481,9 @@ This repo's Netlify site hosts the whole dashboard + forms surface: the Resend d
481
481
  | `PROSPECT_EDIT_TOKEN` | Shared secret gating `POST /api/audit-report/:token/overrides`, where an operator's edits to a prospect report are saved — the SAME value is set on the marketing site, which proxies the save. Generate with `openssl rand -base64 32`. **Fails closed**: absent → every save 503s, which looks like a broken editor. Leading/trailing whitespace from a paste is tolerated, and warned about in the function logs |
482
482
  | `DASHBOARD_PASSWORD` | Basic-auth password gating the cockpit, per-site dashboards, and every action endpoint — the dashboard is unauthable without it |
483
483
  | `DASHBOARD_BASE_URL` | Public base URL of this deploy (e.g. `https://<your-site>.netlify.app`) — used to build absolute links such as report approve URLs |
484
- | `RENOVATE_TOKEN` | GitHub PAT with `actions:write` — powers the dashboard's "Trigger Renovate" button (the button 502s without it) |
485
- | `GH_TOKEN` | GitHub token for the dashboard's request-path REST calls (fleet-refresh dispatch + GitHub-sourced signals) |
484
+ | `GH_TOKEN` | GitHub token for the dashboard's request-path REST calls, with `actions:write` — the "Trigger Renovate" button, the fleet-refresh and prospect-audit dispatches (each answers 503 `not-configured` without it), plus GitHub-sourced signals. The only name these functions read: `RENOVATE_TOKEN` was retired with the operator PAT |
486
485
 
487
- > The first seven vars cover the webhook + forms ingest (`TURNSTILE_SECRET_KEY` optional); `PROSPECT_EDIT_TOKEN` is needed only to SAVE edits to a prospect report (serving one needs no secret beyond its URL token); `DASHBOARD_PASSWORD` / `DASHBOARD_BASE_URL` / `RENOVATE_TOKEN` / `GH_TOKEN` are additionally required by the operator **dashboard** this same deploy serves (cockpit at `/`, per-site at `/s/:slug`).
486
+ > The first seven vars cover the webhook + forms ingest (`TURNSTILE_SECRET_KEY` optional); `PROSPECT_EDIT_TOKEN` is needed only to SAVE edits to a prospect report (serving one needs no secret beyond its URL token); `DASHBOARD_PASSWORD` / `DASHBOARD_BASE_URL` / `GH_TOKEN` are additionally required by the operator **dashboard** this same deploy serves (cockpit at `/`, per-site at `/s/:slug`).
488
487
 
489
488
  **3. Trigger a deploy** (Deploys → Trigger deploy → Deploy site). When it goes green, curl the health endpoint:
490
489
 
@@ -1,24 +1,25 @@
1
1
  import {
2
2
  scoresFromRow
3
- } from "./chunk-44SDGPGQ.js";
3
+ } from "./chunk-PZZ6HM5T.js";
4
4
  import {
5
5
  fetchGaUsers,
6
6
  fetchSearch,
7
7
  readGaConfig,
8
8
  refreshHeaderImage
9
- } from "./chunk-72FJZ6LO.js";
9
+ } from "./chunk-DRNZVORX.js";
10
10
  import {
11
+ createReportDraft,
12
+ findReportForPeriod,
11
13
  queueDraft
12
- } from "./chunk-YFAXOD7Z.js";
14
+ } from "./chunk-UPE6D4AT.js";
13
15
  import {
14
- createDraft,
15
- findReportByPeriod,
16
16
  updateReportScores
17
- } from "./chunk-F3JWOPTG.js";
17
+ } from "./chunk-TEMQPSCM.js";
18
+ import "./chunk-ASLDCWBF.js";
18
19
  import "./chunk-VAD43MOR.js";
19
20
  import {
20
21
  uploadAttachment
21
- } from "./chunk-IY6256GK.js";
22
+ } from "./chunk-YJBSB4LP.js";
22
23
  import {
23
24
  openBase,
24
25
  readAirtableConfig
@@ -32,23 +33,26 @@ import {
32
33
  resolveCopy
33
34
  } from "./chunk-KJGKZLCT.js";
34
35
  import "./chunk-BGTYPVLT.js";
35
- import "./chunk-MZZDMBDT.js";
36
+ import "./chunk-LZMAG73U.js";
36
37
  import {
37
- listWebsites,
38
- siteSlug,
39
38
  updateAnalyticsHealth
40
- } from "./chunk-KN52PM63.js";
39
+ } from "./chunk-TC4GANMX.js";
40
+ import {
41
+ siteSlug
42
+ } from "./chunk-ICSRWW5Q.js";
43
+ import "./chunk-RQJFGK3A.js";
41
44
  import "./chunk-RARREDQE.js";
42
45
  import "./chunk-6VAL7XJT.js";
43
46
 
44
47
  // src/recipes/announce.ts
45
48
  var GA_WINDOW_DAYS = 30;
46
49
  async function announce(deps) {
47
- const base = deps?.base ?? openBase(readAirtableConfig());
48
- const now = deps?.now ?? /* @__PURE__ */ new Date();
49
- const websites = await listWebsites(base);
50
+ const base = deps.base ?? openBase(readAirtableConfig());
51
+ const now = deps.now ?? /* @__PURE__ */ new Date();
52
+ const writer = deps.reportMirror;
53
+ const websites = await deps.roster();
50
54
  let targets = websites.filter((w) => w.status === "maintained");
51
- if (deps?.site) {
55
+ if (deps.site) {
52
56
  const wanted = siteSlug(deps.site);
53
57
  targets = targets.filter((w) => siteSlug(w.name) === wanted);
54
58
  }
@@ -61,8 +65,8 @@ async function announce(deps) {
61
65
  results.push({ site: w.name, status: "skipped-no-scores" });
62
66
  continue;
63
67
  }
64
- if (deps?.refreshHeader !== false) {
65
- await refreshHeaderImage(w, deps?.refreshHeader ?? {});
68
+ if (deps.refreshHeader !== false) {
69
+ await refreshHeaderImage(w, deps.refreshHeader ?? {});
66
70
  }
67
71
  const periodEnd = now;
68
72
  const periodStart = new Date(now.getTime() - GA_WINDOW_DAYS * 24 * 60 * 60 * 1e3);
@@ -82,17 +86,17 @@ async function announce(deps) {
82
86
  w.id,
83
87
  gaResult.softFailed || searchResult.softFailed ? now.toISOString() : null
84
88
  );
85
- await deps?.siteMirror?.health(w.id, fields);
89
+ await deps.siteMirror?.health(w.id, fields);
86
90
  } catch (e) {
87
91
  console.warn(`\u26A0 analytics-health write skipped for ${w.name}: ${e.message}`);
88
92
  }
89
93
  }
90
94
  let report;
91
95
  let statusKind;
92
- const existing = await findReportByPeriod(base, w.id, "Announcement", period);
96
+ const existing = await findReportForPeriod(writer, w.id, "Announcement", period);
93
97
  if (existing) {
94
98
  await updateReportScores(base, existing.id, scores, now, enrichment);
95
- await deps?.reportMirror?.patch(existing.id, {
99
+ await writer.patch(existing.id, {
96
100
  lighthouse_performance: scores.performance,
97
101
  lighthouse_accessibility: scores.accessibility,
98
102
  lighthouse_best_practices: scores.bestPractices,
@@ -106,11 +110,9 @@ async function announce(deps) {
106
110
  report = existing;
107
111
  statusKind = "reused";
108
112
  } else {
109
- report = await createDraft(
110
- base,
111
- draftInputFor(w, scores, now, period, enrichment),
112
- deps?.reportMirror?.created
113
- );
113
+ report = await createReportDraft(draftInputFor(w, scores, now, period, enrichment), {
114
+ create: writer.create
115
+ });
114
116
  statusKind = "drafted";
115
117
  }
116
118
  const slug = siteSlug(w.name);
@@ -141,7 +143,7 @@ async function announce(deps) {
141
143
  `${slug}-${now.toISOString().slice(0, 10)}.html`,
142
144
  "text/html"
143
145
  );
144
- await deps?.reportMirror?.body(report.id, html);
146
+ await writer.body(report.id, html);
145
147
  } catch (uploadErr) {
146
148
  console.warn(
147
149
  `\u26A0 Announcement preview upload skipped for ${w.name}: ${uploadErr instanceof Error ? uploadErr.message : String(uploadErr)}`
@@ -150,7 +152,7 @@ async function announce(deps) {
150
152
  const queue = await queueDraft(
151
153
  base,
152
154
  { id: report.id, siteId: w.id, reportType: "Announcement" },
153
- deps?.reportMirror
155
+ writer
154
156
  );
155
157
  const recipientMissing = !(w.reportRecipientsTo && w.reportRecipientsTo.trim());
156
158
  results.push({
@@ -203,11 +205,17 @@ function formatAnnounceResult(result) {
203
205
  return result.results.map(formatSiteResult).join("\n");
204
206
  }
205
207
  async function runAnnounceCommand(site, _opts) {
206
- const { makeReportMirror } = await import("./report-mirror-KKZZ6RMZ.js");
207
- const { makeSiteMirror } = await import("./site-mirror-H2FYMN55.js");
208
+ const { makeReportMirror } = await import("./report-mirror-O6IDFDWU.js");
209
+ const { makeSiteMirror } = await import("./site-mirror-TKTDWYP3.js");
208
210
  const reportMirror = await makeReportMirror();
209
211
  const siteMirror = await makeSiteMirror();
210
- const result = await announce({ ...site ? { site } : {}, reportMirror, siteMirror });
212
+ const { readFleetRoster } = await import("./roster-EJ3ILR52.js");
213
+ const result = await announce({
214
+ ...site ? { site } : {},
215
+ roster: () => readFleetRoster(),
216
+ reportMirror,
217
+ siteMirror
218
+ });
211
219
  const hadError = result.results.some((r) => r.status === "error");
212
220
  return { output: formatAnnounceResult(result), code: hadError ? 1 : 0 };
213
221
  }
@@ -215,4 +223,4 @@ export {
215
223
  formatAnnounceResult,
216
224
  runAnnounceCommand
217
225
  };
218
- //# sourceMappingURL=announce-45HVP4J4.js.map
226
+ //# sourceMappingURL=announce-2FH2KBQQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/recipes/announce.ts","../src/cli/commands/announce.ts"],"sourcesContent":["import { openBase, readAirtableConfig } from \"../reports/airtable/client.js\";\nimport type { AirtableBase } from \"../reports/airtable/client.js\";\nimport { siteSlug, updateAnalyticsHealth } from \"../reports/airtable/websites.js\";\nimport type { WebsiteRow } from \"../reports/airtable/websites.js\";\nimport { readGaConfig } from \"../reports/ga/config.js\";\nimport { updateReportScores, type ReportEnrichment } from \"../reports/airtable/reports.js\";\nimport { createReportDraft, findReportForPeriod } from \"../reports/create-report.js\";\nimport type { DraftInput } from \"../reports/draft-fields.js\";\nimport type { ReportMirror } from \"../reports/report-mirror.js\";\nimport type { SiteMirror } from \"../db/site-mirror.js\";\nimport { queueDraft } from \"../reports/queue.js\";\nimport { uploadAttachment } from \"../reports/airtable/attachments.js\";\nimport { renderReportHtml } from \"../reports/render.js\";\nimport { resolveCopy } from \"../reports/copy.js\";\nimport { fetchGaUsers, fetchSearch, refreshHeaderImage } from \"../reports/draft.js\";\nimport type { RefreshHeaderDeps } from \"../reports/draft.js\";\nimport { announcementSiteExtras } from \"../reports/announcement-email/template.js\";\nimport type { LighthouseScores } from \"../reports/types.js\";\nimport { defaultReportSubject } from \"../reports/subject.js\";\nimport { scoresFromRow } from \"../reports/report-data.js\";\n\nexport type AnnounceSiteResult =\n | {\n site: string;\n status: \"drafted\" | \"reused\";\n reportId: string;\n recipientMissing: boolean;\n /** False when a higher-or-equal-tier report was already queued (single-queue rule). */\n queued: boolean;\n }\n | { site: string; status: \"skipped-no-scores\" }\n | { site: string; status: \"error\"; message: string };\n\nexport type AnnounceResult = { results: AnnounceSiteResult[] };\n\n/** The traffic/search lookback window (days) the announcement reports on. The trend compares it\n * against the equal-length prior window, and the email labels it \"vs the previous N days\". */\nconst GA_WINDOW_DAYS = 30;\n\nexport type AnnounceDeps = {\n /** Airtable handle. Defaults to opening the live base from credentials. */\n base?: AirtableBase;\n /** When set, restrict to the single site whose slug matches. Default: all maintenance sites. */\n site?: string;\n /** Single timestamp driving the period key, render, draft, and preview filename. */\n now?: Date;\n /**\n * Header-image refresh, matching `draftReportForSite`'s opt-out shape: UNSET means\n * refresh (the production default), `false` skips it so unit suites don't launch a\n * browser. Announce previously never refreshed at all, so a site whose stored header\n * predated a plate change kept announcing with the old one until its next\n * Maintenance/Testing draft happened to heal it.\n */\n refreshHeader?: RefreshHeaderDeps | false;\n /** Every site in the fleet, read from TURSO (#646 step 4) — the Airtable\n * roster this replaces could not see a `site_<ULID>` site, so a site created\n * since step 3 was never announced. Required, not defaulted: every unit test\n * calls `announce` with a fake base, and a default would open a real libSQL\n * handle from inside the suite. The CLI composition root wires\n * `readFleetRoster`. */\n roster: () => Promise<WebsiteRow[]>;\n /** #539 Phase 5, and since #646 step 4 the store that MINTS and holds the\n * report row: the created row (or a reused row's refreshed scores), the\n * rendered body, and the queue flag. Required for the same reason `roster`\n * is — a default would open a real libSQL handle from inside the suite. */\n reportMirror: ReportMirror;\n /** #539 Phase 5: the Websites-row twin — announce stamps `Analytics soft-fail\n * at` on the SITE row, a different Turso table from the report. */\n siteMirror?: SiteMirror;\n};\n\n/**\n * Draft the monthly-report ANNOUNCEMENT email for every `maintenance` site (or one,\n * via `deps.site`). Airtable-driven and fleet-wide: unlike `launch`, it runs no audits\n * and takes no `Site`/inventory object — it reads the Lighthouse scores already stored\n * on each Websites row. DRAFTS ONLY; the M3 approve loop sends.\n *\n * One bad site must never abort the run: each site is wrapped in its own try/catch that\n * records an `error` result and continues.\n */\nexport async function announce(deps: AnnounceDeps): Promise<AnnounceResult> {\n const base = deps.base ?? openBase(readAirtableConfig());\n const now = deps.now ?? new Date();\n const writer = deps.reportMirror;\n\n const websites = await deps.roster();\n let targets = websites.filter((w) => w.status === \"maintained\");\n if (deps.site) {\n const wanted = siteSlug(deps.site);\n targets = targets.filter((w) => siteSlug(w.name) === wanted);\n }\n\n const period = now.toISOString().slice(0, 7);\n const results: AnnounceSiteResult[] = [];\n\n for (const w of targets) {\n try {\n const scores = scoresFromRow(w);\n if (scores === null) {\n results.push({ site: w.name, status: \"skipped-no-scores\" });\n continue;\n }\n\n // Refresh BEFORE the render so a queued announcement always has a current header\n // stored — the send re-reads the attachment, so a stale one here reaches the\n // client. Best-effort by construction: refreshHeaderImage returns false and never\n // throws, so a capture failure leaves the stored image and the draft continues.\n if (deps.refreshHeader !== false) {\n await refreshHeaderImage(w, deps.refreshHeader ?? {});\n }\n\n // Traffic + search snapshot over a ~30-day window ending now (fetchPeriodUsers derives\n // the equal-length previous window for the trend). Reuses the report pipeline's\n // soft-failing enrichment: GA/search unconfigured or an API error leaves the numbers\n // null and the email simply omits the traffic section — it never blocks the draft.\n const periodEnd = now;\n const periodStart = new Date(now.getTime() - GA_WINDOW_DAYS * 24 * 60 * 60 * 1000);\n const gaResult = await fetchGaUsers(w, periodStart, periodEnd);\n const searchResult = await fetchSearch(w, periodStart, periodEnd);\n const gaUsers = gaResult.value;\n const search = searchResult.value;\n const enrichment: ReportEnrichment = {\n ...(gaUsers ? { gaUsersCurrent: gaUsers.current, gaUsersPrevious: gaUsers.previous } : {}),\n ...(search ? { searchFoundPage1: search.foundOnPage1 } : {}),\n ...(search?.foundOnPage1 && search.position !== null\n ? { searchPosition: search.position }\n : {}),\n };\n\n // Record this site's GA/Search enrichment health for the per-site analytics-failure\n // signal (cockpit/digest) — exactly as the `--due` draft path does. Without this, an\n // announcement-time GA outage hides the traffic block with NO operator signal (it reads\n // identically to \"site has no GA configured\"). Set the timestamp on a soft-fail, clear\n // it on a clean enrichment so the signal self-heals. Best-effort: the column is\n // operator-added, so until it exists the write throws — which must not break the draft.\n if (readGaConfig() !== null && Boolean(w.ga4PropertyId || w.searchQuery)) {\n try {\n const fields = await updateAnalyticsHealth(\n base,\n w.id,\n gaResult.softFailed || searchResult.softFailed ? now.toISOString() : null,\n );\n // Mirror the EXACT FieldSet Airtable got — see draft.ts.\n await deps.siteMirror?.health(w.id, fields);\n } catch (e) {\n console.warn(`⚠ analytics-health write skipped for ${w.name}: ${(e as Error).message}`);\n }\n }\n\n // Dedupe: reuse an existing Announcement row for this (site, period) rather than\n // stacking a second draft. The reuse path refreshes the stored scores + traffic/search\n // (and Completed on) so the eventually-sent email — which reads the row — isn't stale.\n // The create path writes them via createDraft.\n let report;\n let statusKind: \"drafted\" | \"reused\";\n const existing = await findReportForPeriod(writer, w.id, \"Announcement\", period);\n if (existing) {\n await updateReportScores(base, existing.id, scores, now, enrichment);\n // Mirror the SAME refresh: the reuse path exists so the eventually-sent\n // email is not stale, and the console reads those numbers too.\n await writer.patch(existing.id, {\n lighthouse_performance: scores.performance,\n lighthouse_accessibility: scores.accessibility,\n lighthouse_best_practices: scores.bestPractices,\n lighthouse_seo: scores.seo,\n completed_on: now.toISOString().slice(0, 10),\n ...(enrichment.gaUsersCurrent !== undefined\n ? { ga_users_current: enrichment.gaUsersCurrent }\n : {}),\n ...(enrichment.gaUsersPrevious !== undefined\n ? { ga_users_previous: enrichment.gaUsersPrevious }\n : {}),\n ...(enrichment.searchFoundPage1 !== undefined\n ? { search_found_page1: enrichment.searchFoundPage1 ? 1 : 0 }\n : {}),\n ...(enrichment.searchPosition !== undefined\n ? { search_position: enrichment.searchPosition }\n : {}),\n });\n report = existing;\n statusKind = \"reused\";\n } else {\n // #646 step 4: minted and written in Turso (`report_<ULID>`). The\n // Airtable Reports row this replaces is skipped, not written — see\n // `createReportDraft`.\n report = await createReportDraft(draftInputFor(w, scores, now, period, enrichment), {\n create: writer.create,\n });\n statusKind = \"drafted\";\n }\n\n const slug = siteSlug(w.name);\n const { html } = await renderReportHtml({\n siteName: w.name,\n siteUrl: w.url,\n reportType: \"Announcement\",\n completedOn: now,\n lighthouse: scores,\n gaUsersCurrent: gaUsers?.current,\n gaUsersPrevious: gaUsers?.previous,\n gaPeriodDays: GA_WINDOW_DAYS,\n searchPosition: search?.foundOnPage1 ? (search.position ?? undefined) : undefined,\n lastTestedDate: null,\n commentary: null,\n copy: resolveCopy(w),\n headerImageCid: `${slug}-header`,\n // cadence (the client's go-forward pace, \"None\" omitted) + default-on improvement\n // callouts. Shared with the send re-render via announcementSiteExtras so the sent\n // email matches this reviewed preview.\n ...announcementSiteExtras(w),\n });\n\n // A preview-upload hiccup must NOT fail the site — log and continue.\n try {\n await uploadAttachment(\n report.id,\n \"Rendered HTML\",\n html,\n `${slug}-${now.toISOString().slice(0, 10)}.html`,\n \"text/html\",\n );\n // Store the same body in Turso — the console's preview route reads it\n // there, not from the Airtable attachment (whose URL expires).\n await writer.body(report.id, html);\n } catch (uploadErr) {\n console.warn(\n `⚠ Announcement preview upload skipped for ${w.name}: ${\n uploadErr instanceof Error ? uploadErr.message : String(uploadErr)\n }`,\n );\n }\n\n // Critical: NOT wrapped — without queueing, the draft never enters the approve queue,\n // so a failure here must surface as an error result for the site. queueDraft also\n // supersedes any lower-tier (Maintenance/Testing) drafts queued for this site, and\n // stands down if an equal-or-higher report is already queued (single-queue rule).\n const queue = await queueDraft(\n base,\n { id: report.id, siteId: w.id, reportType: \"Announcement\" },\n writer,\n );\n\n const recipientMissing = !(w.reportRecipientsTo && w.reportRecipientsTo.trim());\n results.push({\n site: w.name,\n status: statusKind,\n reportId: report.id,\n recipientMissing,\n queued: queue.queued,\n });\n } catch (err) {\n results.push({\n site: w.name,\n status: \"error\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return { results };\n}\n\n/** Build the Announcement `DraftInput`. Announcements have no period window and no prior\n * maintenance test, so periodStart/periodEnd/completedOn all collapse to `now` and\n * `lastTestedDate` is null. The subject override gives the email a purpose-built line. */\nfunction draftInputFor(\n w: WebsiteRow,\n scores: LighthouseScores,\n now: Date,\n period: string,\n enrichment: ReportEnrichment,\n): DraftInput {\n return {\n reportId: `${w.name} — Announcement — ${now.toISOString().slice(0, 10)}`,\n siteId: w.id,\n reportType: \"Announcement\",\n period,\n periodStart: now,\n periodEnd: now,\n completedOn: now,\n lighthouse: scores,\n lastTestedDate: null,\n subjectOverride: defaultReportSubject({\n name: w.name,\n url: w.url,\n type: \"Announcement\",\n date: now,\n }),\n ...enrichment,\n };\n}\n","import { announce, type AnnounceResult, type AnnounceSiteResult } from \"../../recipes/announce.js\";\n\nexport type AnnounceCommandOptions = {\n cwd?: string;\n};\n\nfunction formatSiteResult(r: AnnounceSiteResult): string {\n if (r.status === \"skipped-no-scores\") return `[${r.site}] skipped-no-scores`;\n if (r.status === \"error\") return `[${r.site}] error: ${r.message}`;\n const note = r.recipientMissing ? \" ⚠ recipient missing\" : \"\";\n return `[${r.site}] ${r.status}${note}`;\n}\n\nexport function formatAnnounceResult(result: AnnounceResult): string {\n if (result.results.length === 0) return \"No maintenance sites to announce.\";\n return result.results.map(formatSiteResult).join(\"\\n\");\n}\n\n/**\n * `announce [site]` — Airtable-driven and fleet-wide. Draft the monthly-report\n * announcement email for every `maintenance` site (or one, when `site` is given) into\n * the M3 approve queue. Never sends; the operator approves each draft and the next send\n * run delivers it. Reads the Lighthouse scores already stored on each Websites row —\n * no audits are run.\n */\nexport async function runAnnounceCommand(\n site: string | undefined,\n _opts: AnnounceCommandOptions,\n): Promise<{ output: string; code: number }> {\n // #539 Phase 5: the create-side Turso dual-write is wired HERE rather than\n // inside `announce`, so a unit suite calling the recipe with a fake base can\n // never open a real libSQL handle (and, with TURSO_* exported locally, write\n // into production).\n const { makeReportMirror } = await import(\"../../reports/report-mirror.js\");\n const { makeSiteMirror } = await import(\"../../db/site-mirror.js\");\n const reportMirror = await makeReportMirror();\n const siteMirror = await makeSiteMirror();\n // #646 step 4: the fleet roster comes from Turso — an Airtable roster cannot\n // see a `site_<ULID>` site, so one created since step 3 was never announced.\n const { readFleetRoster } = await import(\"../../fleet/roster.js\");\n const result = await announce({\n ...(site ? { site } : {}),\n roster: () => readFleetRoster(),\n reportMirror,\n siteMirror,\n });\n const hadError = result.results.some((r) => r.status === \"error\");\n return { output: formatAnnounceResult(result), code: hadError ? 1 : 0 };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,10 @@
1
+ import {
2
+ fetchAttachmentBytes,
3
+ uploadAttachment
4
+ } from "./chunk-YJBSB4LP.js";
5
+ import "./chunk-RQJFGK3A.js";
6
+ export {
7
+ fetchAttachmentBytes,
8
+ uploadAttachment
9
+ };
10
+ //# sourceMappingURL=attachments-JFGFQRXQ.js.map
@@ -1,13 +1,13 @@
1
+ import {
2
+ assetRef,
3
+ richText
4
+ } from "./chunk-UWJZXL2D.js";
1
5
  import {
2
6
  FROZEN_PAGE_TYPE,
3
7
  extractMapConfig,
4
8
  frozenPageCustomType,
5
9
  makeIsMapMount
6
10
  } from "./chunk-DRDAEELJ.js";
7
- import {
8
- assetRef,
9
- richText
10
- } from "./chunk-UWJZXL2D.js";
11
11
  import {
12
12
  CDN_HOSTS,
13
13
  collectAssetUrls
@@ -4767,4 +4767,4 @@ ${lines.join("\n")}`,
4767
4767
  export {
4768
4768
  runBluxCommand
4769
4769
  };
4770
- //# sourceMappingURL=blux-RUFMNOUJ.js.map
4770
+ //# sourceMappingURL=blux-NXQLMS4W.js.map
@@ -5,19 +5,19 @@ import {
5
5
  appendSkipNotice,
6
6
  fleetWorkdir,
7
7
  prepareFleetSites
8
- } from "./chunk-SHGIDTYF.js";
8
+ } from "./chunk-DYTYPKFN.js";
9
9
  import {
10
10
  resolveSites
11
- } from "./chunk-H445EH33.js";
11
+ } from "./chunk-S2PLX4XK.js";
12
12
  import {
13
13
  bumpDeps
14
- } from "./chunk-VEIIUCYL.js";
15
- import "./chunk-SQ4FSNYL.js";
14
+ } from "./chunk-TV76A6GN.js";
15
+ import "./chunk-LUF52EIY.js";
16
16
  import "./chunk-Z3JXLULD.js";
17
17
  import "./chunk-LBYOLBW7.js";
18
18
  import "./chunk-RARREDQE.js";
19
19
  import "./chunk-XXTZBPUY.js";
20
- import "./chunk-EASYCD6F.js";
20
+ import "./chunk-WMF5S2MB.js";
21
21
 
22
22
  // src/cli/commands/bump-deps.ts
23
23
  import { resolve } from "path";
@@ -57,4 +57,4 @@ async function runBumpDepsCommand(site, opts) {
57
57
  export {
58
58
  runBumpDepsCommand
59
59
  };
60
- //# sourceMappingURL=bump-deps-EL3TKMIL.js.map
60
+ //# sourceMappingURL=bump-deps-54K4ECP3.js.map
@@ -1,6 +1,3 @@
1
- import {
2
- withRecipe
3
- } from "./chunk-SQ4FSNYL.js";
4
1
  import {
5
2
  ALL_TEMPLATES,
6
3
  RENOVATE_ACTION_CONFIG,
@@ -8,10 +5,13 @@ import {
8
5
  templatesByName,
9
6
  withRenovatePinsFrom
10
7
  } from "./chunk-SLFG7Y76.js";
8
+ import {
9
+ withRecipe
10
+ } from "./chunk-LUF52EIY.js";
11
11
  import {
12
12
  listTrackedFiles,
13
13
  removeFromIndex
14
- } from "./chunk-EASYCD6F.js";
14
+ } from "./chunk-WMF5S2MB.js";
15
15
 
16
16
  // src/recipes/sync-configs.ts
17
17
  import { readFile, writeFile, mkdir } from "fs/promises";
@@ -229,4 +229,4 @@ export {
229
229
  planTemplateDiffs,
230
230
  syncConfigs
231
231
  };
232
- //# sourceMappingURL=chunk-IMYL67JV.js.map
232
+ //# sourceMappingURL=chunk-3RLDX3Q2.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  openDb,
3
3
  readDbConfig
4
- } from "./chunk-6INOBNRO.js";
4
+ } from "./chunk-MNRWHSFS.js";
5
5
 
6
6
  // src/db/fleet-events.ts
7
7
  async function recordFleetEvent(db, e) {
@@ -47,4 +47,4 @@ async function recordFleetEventsBestEffort(events, now, open = () => openDb(read
47
47
  export {
48
48
  recordFleetEventsBestEffort
49
49
  };
50
- //# sourceMappingURL=chunk-EQQ4H6L3.js.map
50
+ //# sourceMappingURL=chunk-3YALLSBF.js.map
@@ -99,7 +99,8 @@ function usablePages(pages) {
99
99
  pages: usable,
100
100
  view,
101
101
  excluded: candidates.length - usable.length,
102
- anchorsMeasured: usable.length > 0 && usable.every((p) => p.extract.anchors !== void 0)
102
+ anchorsMeasured: usable.length > 0 && usable.every((p) => p.extract.anchors !== void 0),
103
+ imageSrcsMeasured: usable.length > 0 && usable.every((p) => p.extract.imageSrcs !== void 0)
103
104
  };
104
105
  }
105
106
 
@@ -417,6 +418,9 @@ function pageInteractionDeps(page, url) {
417
418
  // src/prospect/extract.ts
418
419
  import { parse, NodeType } from "node-html-parser";
419
420
  var MAX_ANCHORS = 300;
421
+ function anchorsTruncated(extract) {
422
+ return extract.anchorCount !== void 0 && extract.anchors !== void 0 && extract.anchors.length < extract.anchorCount;
423
+ }
420
424
  var MAX_SCRIPTS = 120;
421
425
  var MAX_INLINE_URLS = 40;
422
426
  var MAX_DATA_TEXT = 2e5;
@@ -1685,16 +1689,22 @@ function buildJourney(pages) {
1685
1689
  internalLinks: outgoing.get(key)?.size ?? 0
1686
1690
  }));
1687
1691
  const reachable = journeys.map((j) => j.clicksToContact).filter((d) => d !== null);
1692
+ const truncated = new Set(
1693
+ [...nodes.values()].filter((e) => anchorsTruncated(e.extract)).map((e) => e.page.url)
1694
+ );
1688
1695
  return {
1689
1696
  affordances,
1690
1697
  pages: journeys,
1691
1698
  // Without recorded anchors there is no evidence either way, so there is no
1692
1699
  // finding — not "every page is a dead end", which is what reading the
1693
- // absent array as an empty one used to produce.
1694
- deadEnds: usable.anchorsMeasured ? journeys.filter((j) => j.clicksToContact === null).map((j) => j.url) : [],
1700
+ // absent array as an empty one used to produce. A TRUNCATED list is the
1701
+ // same claim one page at a time: its footer `/contact` may simply be past
1702
+ // the cap, so it is excluded here rather than accused.
1703
+ deadEnds: usable.anchorsMeasured ? journeys.filter((j) => j.clicksToContact === null && !truncated.has(j.url)).map((j) => j.url) : [],
1695
1704
  worstClicksToContact: reachable.length > 0 ? Math.max(...reachable) : null,
1696
1705
  pagesExamined: journeys.length,
1697
- anchorsMeasured: usable.anchorsMeasured
1706
+ anchorsMeasured: usable.anchorsMeasured,
1707
+ pagesWithTruncatedAnchors: [...truncated]
1698
1708
  };
1699
1709
  }
1700
1710
 
@@ -4208,6 +4218,7 @@ function runSiteChecks(crawl, checks, businessName = null, dns = null, http = nu
4208
4218
  export {
4209
4219
  usablePages,
4210
4220
  summarizeAccessibility,
4221
+ anchorsTruncated,
4211
4222
  AI_AGENTS,
4212
4223
  CLASSICAL_AGENTS,
4213
4224
  USER_AGENT,
@@ -4227,4 +4238,4 @@ export {
4227
4238
  tally,
4228
4239
  runSiteChecks
4229
4240
  };
4230
- //# sourceMappingURL=chunk-LAJ3FF54.js.map
4241
+ //# sourceMappingURL=chunk-5UI4FERC.js.map