@sonordev/site-kit 5.6.0 → 5.8.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 (632) hide show
  1. package/README.md +3 -3
  2. package/agent-manifest.json +24 -4
  3. package/dist/AnalyticsProvider-OCXRNIVE.js +33 -0
  4. package/dist/{AnalyticsProvider-6PXC7UDP.js.map → AnalyticsProvider-OCXRNIVE.js.map} +1 -1
  5. package/dist/AnalyticsProvider-ZAUONQCX.mjs +12 -0
  6. package/dist/{AnalyticsProvider-FVQIYSLY.mjs.map → AnalyticsProvider-ZAUONQCX.mjs.map} +1 -1
  7. package/dist/{BlogViewTracker-S4HSRCW7.js → BlogViewTracker-HK5C7PU6.js} +14 -11
  8. package/dist/BlogViewTracker-HK5C7PU6.js.map +1 -0
  9. package/dist/{BlogViewTracker-ZUGLBOVI.mjs → BlogViewTracker-KXRZHN3U.mjs} +13 -10
  10. package/dist/BlogViewTracker-KXRZHN3U.mjs.map +1 -0
  11. package/dist/ChatWidget-3OW5LY37.js +24 -0
  12. package/dist/{ChatWidget-2TQWCXWP.js.map → ChatWidget-3OW5LY37.js.map} +1 -1
  13. package/dist/ChatWidget-54GVS27I.mjs +15 -0
  14. package/dist/{ChatWidget-DG52ZIE6.mjs.map → ChatWidget-54GVS27I.mjs.map} +1 -1
  15. package/dist/EngageWidget-7EUP76WE.mjs +12 -0
  16. package/dist/{EngageWidget-2VUJADIU.mjs.map → EngageWidget-7EUP76WE.mjs.map} +1 -1
  17. package/dist/EngageWidget-DDP5UFA4.js +21 -0
  18. package/dist/{EngageWidget-Z7RC2INM.js.map → EngageWidget-DDP5UFA4.js.map} +1 -1
  19. package/dist/{FileField-FSQ7W3A5.mjs → FileField-IQLN6E3C.mjs} +5 -5
  20. package/dist/{FileField-FSQ7W3A5.mjs.map → FileField-IQLN6E3C.mjs.map} +1 -1
  21. package/dist/{FileField-UOQHL25J.js → FileField-SBPL4JHP.js} +6 -6
  22. package/dist/{FileField-UOQHL25J.js.map → FileField-SBPL4JHP.js.map} +1 -1
  23. package/dist/{FormSpotlight-RHL5FWM2.mjs → FormSpotlight-E2LKKHGV.mjs} +11 -7
  24. package/dist/FormSpotlight-E2LKKHGV.mjs.map +1 -0
  25. package/dist/{FormSpotlight-TED32NHP.js → FormSpotlight-YTACNE57.js} +25 -21
  26. package/dist/FormSpotlight-YTACNE57.js.map +1 -0
  27. package/dist/{FormStage-PFEBKHGY.js → FormStage-S277U2CP.js} +20 -15
  28. package/dist/FormStage-S277U2CP.js.map +1 -0
  29. package/dist/{FormStage-DINIRFOX.mjs → FormStage-YSBN5XKL.mjs} +9 -4
  30. package/dist/FormStage-YSBN5XKL.mjs.map +1 -0
  31. package/dist/ManagedForm-I3QVRQ53.mjs +16 -0
  32. package/dist/{ManagedForm-545YAUFC.mjs.map → ManagedForm-I3QVRQ53.mjs.map} +1 -1
  33. package/dist/ManagedForm-TSYKQFLJ.js +25 -0
  34. package/dist/{ManagedForm-43WLCUAK.js.map → ManagedForm-TSYKQFLJ.js.map} +1 -1
  35. package/dist/{ManagedNewsletterForm-ZPY5RRKX.mjs → ManagedNewsletterForm-T3YRAWKZ.mjs} +9 -7
  36. package/dist/ManagedNewsletterForm-T3YRAWKZ.mjs.map +1 -0
  37. package/dist/{ManagedNewsletterForm-I3QN57HB.js → ManagedNewsletterForm-YSOPPKS6.js} +10 -8
  38. package/dist/ManagedNewsletterForm-YSOPPKS6.js.map +1 -0
  39. package/dist/{SignalCore-EEH5IM4U.mjs → SignalCore-PPSIQ4BW.mjs} +8 -14
  40. package/dist/SignalCore-PPSIQ4BW.mjs.map +1 -0
  41. package/dist/{SignalCore-M4AXIMV4.js → SignalCore-SUZH3XWZ.js} +14 -20
  42. package/dist/SignalCore-SUZH3XWZ.js.map +1 -0
  43. package/dist/SitemapSync-HSHCOKCL.mjs +9 -0
  44. package/dist/{SitemapSync-46G7LVZS.mjs.map → SitemapSync-HSHCOKCL.mjs.map} +1 -1
  45. package/dist/SitemapSync-LH6UVP4P.js +18 -0
  46. package/dist/{SitemapSync-XK4JKCS7.js.map → SitemapSync-LH6UVP4P.js.map} +1 -1
  47. package/dist/analytics/AnalyticsProvider.d.ts.map +1 -1
  48. package/dist/analytics/index.js +10 -9
  49. package/dist/analytics/index.mjs +5 -4
  50. package/dist/blog/BlogLayout.d.ts +3 -1
  51. package/dist/blog/BlogLayout.d.ts.map +1 -1
  52. package/dist/blog/BlogList.d.ts +7 -1
  53. package/dist/blog/BlogList.d.ts.map +1 -1
  54. package/dist/blog/BlogPost.d.ts +20 -1
  55. package/dist/blog/BlogPost.d.ts.map +1 -1
  56. package/dist/blog/BlogSidebar.d.ts +3 -1
  57. package/dist/blog/BlogSidebar.d.ts.map +1 -1
  58. package/dist/blog/BlogViewTracker.d.ts +8 -2
  59. package/dist/blog/BlogViewTracker.d.ts.map +1 -1
  60. package/dist/blog/ClusterLandingPage.d.ts +3 -1
  61. package/dist/blog/ClusterLandingPage.d.ts.map +1 -1
  62. package/dist/blog/ClusterNavigation.d.ts +5 -2
  63. package/dist/blog/ClusterNavigation.d.ts.map +1 -1
  64. package/dist/blog/RelatedPosts.d.ts +3 -1
  65. package/dist/blog/RelatedPosts.d.ts.map +1 -1
  66. package/dist/blog/index.d.ts +1 -1
  67. package/dist/blog/index.d.ts.map +1 -1
  68. package/dist/blog/index.js +40 -31
  69. package/dist/blog/index.js.map +1 -1
  70. package/dist/blog/index.mjs +11 -6
  71. package/dist/blog/index.mjs.map +1 -1
  72. package/dist/blog/metadata-images.test.d.ts +2 -0
  73. package/dist/blog/metadata-images.test.d.ts.map +1 -0
  74. package/dist/blog/not-found.test.d.ts +2 -0
  75. package/dist/blog/not-found.test.d.ts.map +1 -0
  76. package/dist/blog/processBlogHtml.d.ts +19 -2
  77. package/dist/blog/processBlogHtml.d.ts.map +1 -1
  78. package/dist/blog/public-reads.d.ts +27 -0
  79. package/dist/blog/public-reads.d.ts.map +1 -0
  80. package/dist/blog/server-core.d.ts +107 -16
  81. package/dist/blog/server-core.d.ts.map +1 -1
  82. package/dist/blog/server-ui.js +29 -23
  83. package/dist/blog/server-ui.js.map +1 -1
  84. package/dist/blog/server-ui.mjs +12 -6
  85. package/dist/blog/server-ui.mjs.map +1 -1
  86. package/dist/blog/server.d.ts +107 -16
  87. package/dist/blog/server.d.ts.map +1 -1
  88. package/dist/blog/server.js +54 -47
  89. package/dist/blog/server.mjs +5 -2
  90. package/dist/blog/site-scope.test.d.ts +2 -0
  91. package/dist/blog/site-scope.test.d.ts.map +1 -0
  92. package/dist/blog/static-params.test.d.ts +2 -0
  93. package/dist/blog/static-params.test.d.ts.map +1 -0
  94. package/dist/brand/extract-brand-profile.d.ts +36 -2
  95. package/dist/brand/extract-brand-profile.d.ts.map +1 -1
  96. package/dist/brand/extract-brand-profile.test.d.ts +2 -0
  97. package/dist/brand/extract-brand-profile.test.d.ts.map +1 -0
  98. package/dist/{chunk-B64AZC6P.js → chunk-2FQG2AHJ.js} +60 -35
  99. package/dist/chunk-2FQG2AHJ.js.map +1 -0
  100. package/dist/{chunk-N2PGTPWN.js → chunk-2OQWLXDO.js} +13 -13
  101. package/dist/{chunk-N2PGTPWN.js.map → chunk-2OQWLXDO.js.map} +1 -1
  102. package/dist/{chunk-T5VTQUNF.js → chunk-2SCDUVFJ.js} +10 -10
  103. package/dist/{chunk-T5VTQUNF.js.map → chunk-2SCDUVFJ.js.map} +1 -1
  104. package/dist/{chunk-S4RC6VAQ.js → chunk-35ERUUH3.js} +6 -6
  105. package/dist/{chunk-S4RC6VAQ.js.map → chunk-35ERUUH3.js.map} +1 -1
  106. package/dist/{chunk-VHZ4LHQT.mjs → chunk-3AUFD7KR.mjs} +3 -3
  107. package/dist/{chunk-VHZ4LHQT.mjs.map → chunk-3AUFD7KR.mjs.map} +1 -1
  108. package/dist/{chunk-DHIWR7CG.js → chunk-3BVCF4ZF.js} +4 -4
  109. package/dist/{chunk-DHIWR7CG.js.map → chunk-3BVCF4ZF.js.map} +1 -1
  110. package/dist/{chunk-EEQYKMGH.mjs → chunk-3EY5E35M.mjs} +57 -86
  111. package/dist/chunk-3EY5E35M.mjs.map +1 -0
  112. package/dist/{chunk-JNABXCLY.mjs → chunk-3SLFT453.mjs} +5 -5
  113. package/dist/{chunk-JNABXCLY.mjs.map → chunk-3SLFT453.mjs.map} +1 -1
  114. package/dist/{chunk-AJQI3WTN.mjs → chunk-4L7OHRWB.mjs} +12 -9
  115. package/dist/chunk-4L7OHRWB.mjs.map +1 -0
  116. package/dist/chunk-4LYW6PMU.mjs +72 -0
  117. package/dist/chunk-4LYW6PMU.mjs.map +1 -0
  118. package/dist/{chunk-R3KTBKSW.js → chunk-4OS6M3V4.js} +6 -12
  119. package/dist/chunk-4OS6M3V4.js.map +1 -0
  120. package/dist/{chunk-AY7JBGYC.js → chunk-4RY7JETY.js} +14 -14
  121. package/dist/{chunk-AY7JBGYC.js.map → chunk-4RY7JETY.js.map} +1 -1
  122. package/dist/chunk-4TLFZ6NR.mjs +16 -0
  123. package/dist/chunk-4TLFZ6NR.mjs.map +1 -0
  124. package/dist/{chunk-4B4S56WJ.mjs → chunk-5B4J3IBX.mjs} +75 -21
  125. package/dist/chunk-5B4J3IBX.mjs.map +1 -0
  126. package/dist/chunk-5O7JSWT6.js +8 -0
  127. package/dist/{chunk-KSL3WA2I.js.map → chunk-5O7JSWT6.js.map} +1 -1
  128. package/dist/chunk-5SANRSX3.mjs +17 -0
  129. package/dist/chunk-5SANRSX3.mjs.map +1 -0
  130. package/dist/{chunk-LCSYJXIO.mjs → chunk-5WGMXSCB.mjs} +3 -3
  131. package/dist/{chunk-LCSYJXIO.mjs.map → chunk-5WGMXSCB.mjs.map} +1 -1
  132. package/dist/chunk-5XFFUP6D.js +100 -0
  133. package/dist/chunk-5XFFUP6D.js.map +1 -0
  134. package/dist/{chunk-AHZR4VGY.mjs → chunk-6HFFTGFP.mjs} +50 -26
  135. package/dist/chunk-6HFFTGFP.mjs.map +1 -0
  136. package/dist/{chunk-USKIL6V6.mjs → chunk-6SBTHS6C.mjs} +3 -3
  137. package/dist/{chunk-USKIL6V6.mjs.map → chunk-6SBTHS6C.mjs.map} +1 -1
  138. package/dist/{chunk-NZSFOZJV.js → chunk-7TC3GRXQ.js} +73 -38
  139. package/dist/chunk-7TC3GRXQ.js.map +1 -0
  140. package/dist/{chunk-HIHAXEPD.mjs → chunk-7THZOAUR.mjs} +4 -4
  141. package/dist/{chunk-HIHAXEPD.mjs.map → chunk-7THZOAUR.mjs.map} +1 -1
  142. package/dist/{chunk-YCI36ZUS.mjs → chunk-AOWJP25J.mjs} +4 -4
  143. package/dist/{chunk-YCI36ZUS.mjs.map → chunk-AOWJP25J.mjs.map} +1 -1
  144. package/dist/{chunk-H44XZUOV.mjs → chunk-B2VFMPVJ.mjs} +4 -4
  145. package/dist/{chunk-H44XZUOV.mjs.map → chunk-B2VFMPVJ.mjs.map} +1 -1
  146. package/dist/{chunk-OA7KKOAK.mjs → chunk-B35OJ7FR.mjs} +4 -4
  147. package/dist/{chunk-OA7KKOAK.mjs.map → chunk-B35OJ7FR.mjs.map} +1 -1
  148. package/dist/{chunk-XR32C47O.js → chunk-BER36QXU.js} +9 -9
  149. package/dist/{chunk-XR32C47O.js.map → chunk-BER36QXU.js.map} +1 -1
  150. package/dist/{chunk-7C7XO5HX.mjs → chunk-BFZNLTWK.mjs} +3 -3
  151. package/dist/{chunk-7C7XO5HX.mjs.map → chunk-BFZNLTWK.mjs.map} +1 -1
  152. package/dist/chunk-BQP6JIE2.mjs +28 -0
  153. package/dist/chunk-BQP6JIE2.mjs.map +1 -0
  154. package/dist/{chunk-5KIO6FXE.js → chunk-C3WU45JT.js} +7 -7
  155. package/dist/{chunk-5KIO6FXE.js.map → chunk-C3WU45JT.js.map} +1 -1
  156. package/dist/chunk-CUNZAD46.js +53 -0
  157. package/dist/chunk-CUNZAD46.js.map +1 -0
  158. package/dist/chunk-CXAXZFFW.js +157 -0
  159. package/dist/chunk-CXAXZFFW.js.map +1 -0
  160. package/dist/{chunk-H4OBGC43.mjs → chunk-DA7IANFG.mjs} +14 -3
  161. package/dist/chunk-DA7IANFG.mjs.map +1 -0
  162. package/dist/{chunk-BWSMUSDB.js → chunk-EIW6YEPY.js} +8 -8
  163. package/dist/{chunk-BWSMUSDB.js.map → chunk-EIW6YEPY.js.map} +1 -1
  164. package/dist/{chunk-UU47DGHE.js → chunk-F6SKG34N.js} +8 -13
  165. package/dist/chunk-F6SKG34N.js.map +1 -0
  166. package/dist/{chunk-LC7AM4J5.js → chunk-FHPW7XVH.js} +77 -20
  167. package/dist/chunk-FHPW7XVH.js.map +1 -0
  168. package/dist/{chunk-JNRHTZL4.js → chunk-FVW6FT6L.js} +73 -29
  169. package/dist/chunk-FVW6FT6L.js.map +1 -0
  170. package/dist/{chunk-KY6M76JW.js → chunk-GNDWTXLU.js} +56 -177
  171. package/dist/chunk-GNDWTXLU.js.map +1 -0
  172. package/dist/{chunk-OZ3FU4BT.js → chunk-H5NBFNND.js} +2 -2
  173. package/dist/chunk-H5NBFNND.js.map +1 -0
  174. package/dist/{chunk-SYGGZZMU.js → chunk-HAKD27AZ.js} +7 -7
  175. package/dist/{chunk-SYGGZZMU.js.map → chunk-HAKD27AZ.js.map} +1 -1
  176. package/dist/chunk-HCN3IKMW.mjs +106 -0
  177. package/dist/chunk-HCN3IKMW.mjs.map +1 -0
  178. package/dist/{chunk-QNPVVWR7.mjs → chunk-HCX343AS.mjs} +4 -4
  179. package/dist/{chunk-QNPVVWR7.mjs.map → chunk-HCX343AS.mjs.map} +1 -1
  180. package/dist/{chunk-C2MSD2UM.mjs → chunk-HEOQT5SM.mjs} +216 -103
  181. package/dist/chunk-HEOQT5SM.mjs.map +1 -0
  182. package/dist/{chunk-RU54J2PY.mjs → chunk-HOJ4J4X2.mjs} +30 -12
  183. package/dist/chunk-HOJ4J4X2.mjs.map +1 -0
  184. package/dist/{chunk-H3D3ZGOJ.js → chunk-HQOHB6QF.js} +15 -15
  185. package/dist/{chunk-H3D3ZGOJ.js.map → chunk-HQOHB6QF.js.map} +1 -1
  186. package/dist/chunk-HRMGITUZ.mjs +6 -0
  187. package/dist/{chunk-DQUBETXH.mjs.map → chunk-HRMGITUZ.mjs.map} +1 -1
  188. package/dist/{chunk-7AUDKXY5.mjs → chunk-HYVEIP2N.mjs} +3 -3
  189. package/dist/{chunk-7AUDKXY5.mjs.map → chunk-HYVEIP2N.mjs.map} +1 -1
  190. package/dist/{chunk-46BMNWE6.js → chunk-I3ND4XYW.js} +12 -9
  191. package/dist/chunk-I3ND4XYW.js.map +1 -0
  192. package/dist/{chunk-53KMRZT7.js → chunk-JDTU2RWC.js} +3 -3
  193. package/dist/{chunk-53KMRZT7.js.map → chunk-JDTU2RWC.js.map} +1 -1
  194. package/dist/{chunk-GZJE23Y5.mjs → chunk-JLVCWC6A.mjs} +2 -2
  195. package/dist/chunk-JLVCWC6A.mjs.map +1 -0
  196. package/dist/chunk-K4TCEAUX.js +52 -0
  197. package/dist/chunk-K4TCEAUX.js.map +1 -0
  198. package/dist/chunk-KV7XXLJV.mjs +30 -0
  199. package/dist/chunk-KV7XXLJV.mjs.map +1 -0
  200. package/dist/{chunk-5UFDHGFE.mjs → chunk-L24RDT6Q.mjs} +3 -3
  201. package/dist/{chunk-5UFDHGFE.mjs.map → chunk-L24RDT6Q.mjs.map} +1 -1
  202. package/dist/{chunk-JE5DWAE6.js → chunk-LBZGYF3B.js} +4 -4
  203. package/dist/{chunk-JE5DWAE6.js.map → chunk-LBZGYF3B.js.map} +1 -1
  204. package/dist/{chunk-746RKQHA.js → chunk-LMEUYRRR.js} +93 -121
  205. package/dist/chunk-LMEUYRRR.js.map +1 -0
  206. package/dist/chunk-LVGSOW2F.js +32 -0
  207. package/dist/chunk-LVGSOW2F.js.map +1 -0
  208. package/dist/{chunk-KPKQKFT4.js → chunk-M45AL7EA.js} +37 -19
  209. package/dist/chunk-M45AL7EA.js.map +1 -0
  210. package/dist/{chunk-XK5AIWQG.js → chunk-MHX6TOAS.js} +3 -3
  211. package/dist/{chunk-XK5AIWQG.js.map → chunk-MHX6TOAS.js.map} +1 -1
  212. package/dist/chunk-MLVHVKFT.mjs +148 -0
  213. package/dist/chunk-MLVHVKFT.mjs.map +1 -0
  214. package/dist/{chunk-RIYAMYLV.mjs → chunk-N2NZBPQ5.mjs} +4 -10
  215. package/dist/chunk-N2NZBPQ5.mjs.map +1 -0
  216. package/dist/chunk-NRBITVDK.js +114 -0
  217. package/dist/chunk-NRBITVDK.js.map +1 -0
  218. package/dist/{chunk-IYCLN3XS.mjs → chunk-O4YBWJHP.mjs} +6 -11
  219. package/dist/chunk-O4YBWJHP.mjs.map +1 -0
  220. package/dist/{chunk-5KIEZHVK.mjs → chunk-O5ZSGBQD.mjs} +4 -4
  221. package/dist/{chunk-5KIEZHVK.mjs.map → chunk-O5ZSGBQD.mjs.map} +1 -1
  222. package/dist/{chunk-TP7H6BSK.mjs → chunk-OE7CTIOU.mjs} +73 -30
  223. package/dist/chunk-OE7CTIOU.mjs.map +1 -0
  224. package/dist/{chunk-UJ6CHZAI.mjs → chunk-OEW2LFOV.js} +169 -25
  225. package/dist/chunk-OEW2LFOV.js.map +1 -0
  226. package/dist/chunk-P4Y75QSU.js +19 -0
  227. package/dist/chunk-P4Y75QSU.js.map +1 -0
  228. package/dist/{chunk-6OP5XSMM.mjs → chunk-PK2OTGW5.mjs} +6 -12
  229. package/dist/chunk-PK2OTGW5.mjs.map +1 -0
  230. package/dist/{chunk-OC7AO7XS.js → chunk-PRTXAIIC.js} +15 -15
  231. package/dist/{chunk-OC7AO7XS.js.map → chunk-PRTXAIIC.js.map} +1 -1
  232. package/dist/{chunk-K2V3ZW36.mjs → chunk-PUAXHYBL.mjs} +3 -3
  233. package/dist/{chunk-K2V3ZW36.mjs.map → chunk-PUAXHYBL.mjs.map} +1 -1
  234. package/dist/chunk-QRHVMTHF.mjs +94 -0
  235. package/dist/chunk-QRHVMTHF.mjs.map +1 -0
  236. package/dist/{chunk-BZLIOT7Q.js → chunk-QTJTDQYR.js} +76 -111
  237. package/dist/chunk-QTJTDQYR.js.map +1 -0
  238. package/dist/{chunk-GJ6NOLGC.mjs → chunk-QVHVL7EX.mjs} +3 -3
  239. package/dist/{chunk-GJ6NOLGC.mjs.map → chunk-QVHVL7EX.mjs.map} +1 -1
  240. package/dist/chunk-R7GHP3FY.js +81 -0
  241. package/dist/chunk-R7GHP3FY.js.map +1 -0
  242. package/dist/chunk-SEP5D4MI.js +116 -0
  243. package/dist/chunk-SEP5D4MI.js.map +1 -0
  244. package/dist/{chunk-GPLCPMVD.mjs → chunk-TXMVU4EY.mjs} +62 -97
  245. package/dist/chunk-TXMVU4EY.mjs.map +1 -0
  246. package/dist/chunk-U2V542EO.mjs +98 -0
  247. package/dist/chunk-U2V542EO.mjs.map +1 -0
  248. package/dist/{chunk-YYN4YZYZ.js → chunk-UWHCHYCX.js} +4 -4
  249. package/dist/{chunk-YYN4YZYZ.js.map → chunk-UWHCHYCX.js.map} +1 -1
  250. package/dist/{chunk-473WDGQZ.mjs → chunk-VJ74275U.mjs} +38 -156
  251. package/dist/chunk-VJ74275U.mjs.map +1 -0
  252. package/dist/{chunk-H7274TKR.mjs → chunk-VJV7WUR2.mjs} +12 -4
  253. package/dist/chunk-VJV7WUR2.mjs.map +1 -0
  254. package/dist/{chunk-CQS5ZYI6.mjs → chunk-VYL6IHJA.mjs} +9 -9
  255. package/dist/{chunk-CQS5ZYI6.mjs.map → chunk-VYL6IHJA.mjs.map} +1 -1
  256. package/dist/{chunk-5B4FABFK.js → chunk-WS7MH3GD.js} +14 -2
  257. package/dist/chunk-WS7MH3GD.js.map +1 -0
  258. package/dist/{chunk-IPV2TUAT.js → chunk-XA2GJFVM.js} +12 -4
  259. package/dist/chunk-XA2GJFVM.js.map +1 -0
  260. package/dist/chunk-XBX2K3GA.js +33 -0
  261. package/dist/chunk-XBX2K3GA.js.map +1 -0
  262. package/dist/{chunk-X5TCH7VZ.js → chunk-XCYKM2SA.js} +6 -13
  263. package/dist/chunk-XCYKM2SA.js.map +1 -0
  264. package/dist/{chunk-6CJP7BFM.js → chunk-XZO5I4RS.mjs} +147 -20
  265. package/dist/chunk-XZO5I4RS.mjs.map +1 -0
  266. package/dist/chunk-Y5QZPUL3.mjs +47 -0
  267. package/dist/chunk-Y5QZPUL3.mjs.map +1 -0
  268. package/dist/{chunk-B6O7D5U4.js → chunk-YECDJDDD.js} +10 -10
  269. package/dist/{chunk-B6O7D5U4.js.map → chunk-YECDJDDD.js.map} +1 -1
  270. package/dist/chunk-YN7QHLWF.js +19 -0
  271. package/dist/chunk-YN7QHLWF.js.map +1 -0
  272. package/dist/chunk-YU7QZ3PP.mjs +45 -0
  273. package/dist/chunk-YU7QZ3PP.mjs.map +1 -0
  274. package/dist/{chunk-CQRLKNHQ.js → chunk-ZEOC26LZ.js} +223 -110
  275. package/dist/chunk-ZEOC26LZ.js.map +1 -0
  276. package/dist/{chunk-AEARU24Q.mjs → chunk-ZVI7MBVF.mjs} +73 -38
  277. package/dist/chunk-ZVI7MBVF.mjs.map +1 -0
  278. package/dist/cli/agent/checks.d.ts +15 -1
  279. package/dist/cli/agent/checks.d.ts.map +1 -1
  280. package/dist/cli/agent/sitemap-trailing-slash.test.d.ts +2 -0
  281. package/dist/cli/agent/sitemap-trailing-slash.test.d.ts.map +1 -0
  282. package/dist/cli/commands/api-routes.d.ts.map +1 -1
  283. package/dist/cli/commands/doctor.d.ts.map +1 -1
  284. package/dist/cli/commands/geo.d.ts +4 -0
  285. package/dist/cli/commands/geo.d.ts.map +1 -1
  286. package/dist/cli/commands/geo.test.d.ts +2 -0
  287. package/dist/cli/commands/geo.test.d.ts.map +1 -0
  288. package/dist/cli/commands/og.d.ts +31 -4
  289. package/dist/cli/commands/og.d.ts.map +1 -1
  290. package/dist/cli/commands/scaffold.d.ts +1 -2
  291. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  292. package/dist/cli/commands/sync.d.ts.map +1 -1
  293. package/dist/cli/generators/index.d.ts +5 -0
  294. package/dist/cli/generators/index.d.ts.map +1 -1
  295. package/dist/cli/generators/index.test.d.ts +2 -0
  296. package/dist/cli/generators/index.test.d.ts.map +1 -0
  297. package/dist/cli/index.js +921 -466
  298. package/dist/cli/index.js.map +1 -1
  299. package/dist/cli/index.mjs +862 -407
  300. package/dist/cli/index.mjs.map +1 -1
  301. package/dist/client/index.js +6 -6
  302. package/dist/client/index.mjs +5 -5
  303. package/dist/commerce/CheckoutForm.d.ts.map +1 -1
  304. package/dist/commerce/ProductDetail.d.ts.map +1 -1
  305. package/dist/commerce/api.d.ts +14 -0
  306. package/dist/commerce/api.d.ts.map +1 -1
  307. package/dist/commerce/discount-checkout.test.d.ts +2 -0
  308. package/dist/commerce/discount-checkout.test.d.ts.map +1 -0
  309. package/dist/commerce/index.d.ts +1 -1
  310. package/dist/commerce/index.d.ts.map +1 -1
  311. package/dist/commerce/index.js +61 -56
  312. package/dist/commerce/index.mjs +6 -5
  313. package/dist/config/index.js +3 -3
  314. package/dist/config/index.mjs +1 -1
  315. package/dist/discover-CYXYKHZ2.mjs +4 -0
  316. package/dist/{discover-BEJRYNFF.mjs.map → discover-CYXYKHZ2.mjs.map} +1 -1
  317. package/dist/discover-NGEPXZOD.js +21 -0
  318. package/dist/{discover-WVDYDUJX.js.map → discover-NGEPXZOD.js.map} +1 -1
  319. package/dist/engage/index.js +12 -10
  320. package/dist/engage/index.js.map +1 -1
  321. package/dist/engage/index.mjs +9 -7
  322. package/dist/engage/index.mjs.map +1 -1
  323. package/dist/fleet/index.js +8 -8
  324. package/dist/fleet/index.mjs +4 -4
  325. package/dist/forms/FormClient.d.ts.map +1 -1
  326. package/dist/forms/FormField.d.ts +7 -1
  327. package/dist/forms/FormField.d.ts.map +1 -1
  328. package/dist/forms/FormSpotlight.d.ts +1 -1
  329. package/dist/forms/FormSpotlight.d.ts.map +1 -1
  330. package/dist/forms/FormStage.d.ts +1 -1
  331. package/dist/forms/FormStage.d.ts.map +1 -1
  332. package/dist/forms/experience-plan.d.ts +0 -1
  333. package/dist/forms/experience-plan.d.ts.map +1 -1
  334. package/dist/forms/field-interactions.d.ts +63 -0
  335. package/dist/forms/field-interactions.d.ts.map +1 -0
  336. package/dist/forms/field-interactions.test.d.ts +8 -0
  337. package/dist/forms/field-interactions.test.d.ts.map +1 -0
  338. package/dist/forms/field-rules.d.ts +41 -0
  339. package/dist/forms/field-rules.d.ts.map +1 -0
  340. package/dist/forms/field-rules.test.d.ts +8 -0
  341. package/dist/forms/field-rules.test.d.ts.map +1 -0
  342. package/dist/forms/form-field-focus.test.d.ts +8 -0
  343. package/dist/forms/form-field-focus.test.d.ts.map +1 -0
  344. package/dist/forms/index.js +25 -23
  345. package/dist/forms/index.js.map +1 -1
  346. package/dist/forms/index.mjs +13 -11
  347. package/dist/forms/index.mjs.map +1 -1
  348. package/dist/forms/server.js +11 -11
  349. package/dist/forms/server.mjs +9 -9
  350. package/dist/forms/static.js +8 -8
  351. package/dist/forms/static.mjs +7 -7
  352. package/dist/forms/tracking-session.d.ts +48 -3
  353. package/dist/forms/tracking-session.d.ts.map +1 -1
  354. package/dist/forms/types.d.ts +11 -0
  355. package/dist/forms/types.d.ts.map +1 -1
  356. package/dist/forms/useForm.d.ts +8 -0
  357. package/dist/forms/useForm.d.ts.map +1 -1
  358. package/dist/forms/useFormTracking.d.ts +29 -4
  359. package/dist/forms/useFormTracking.d.ts.map +1 -1
  360. package/dist/images/index.js +11 -11
  361. package/dist/images/index.mjs +4 -4
  362. package/dist/index.js +72 -68
  363. package/dist/index.js.map +1 -1
  364. package/dist/index.mjs +14 -10
  365. package/dist/index.mjs.map +1 -1
  366. package/dist/layout/client.js +10 -10
  367. package/dist/layout/client.mjs +9 -9
  368. package/dist/layout/index.js +13 -12
  369. package/dist/layout/index.js.map +1 -1
  370. package/dist/layout/index.mjs +11 -10
  371. package/dist/layout/index.mjs.map +1 -1
  372. package/dist/llms/aiRobots.d.ts +24 -5
  373. package/dist/llms/aiRobots.d.ts.map +1 -1
  374. package/dist/llms/api.d.ts +8 -3
  375. package/dist/llms/api.d.ts.map +1 -1
  376. package/dist/llms/discovery-headers.d.ts +24 -0
  377. package/dist/llms/discovery-headers.d.ts.map +1 -1
  378. package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
  379. package/dist/llms/handlers.d.ts +20 -2
  380. package/dist/llms/handlers.d.ts.map +1 -1
  381. package/dist/llms/index.d.ts +2 -2
  382. package/dist/llms/index.d.ts.map +1 -1
  383. package/dist/llms/index.js +54 -98
  384. package/dist/llms/index.js.map +1 -1
  385. package/dist/llms/index.mjs +20 -83
  386. package/dist/llms/index.mjs.map +1 -1
  387. package/dist/llms/links.d.ts +26 -0
  388. package/dist/llms/links.d.ts.map +1 -0
  389. package/dist/llms/links.test.d.ts +2 -0
  390. package/dist/llms/links.test.d.ts.map +1 -0
  391. package/dist/llms/types.d.ts +15 -0
  392. package/dist/llms/types.d.ts.map +1 -1
  393. package/dist/llms/wiring.d.ts +103 -0
  394. package/dist/llms/wiring.d.ts.map +1 -0
  395. package/dist/llms/wiring.test.d.ts +2 -0
  396. package/dist/llms/wiring.test.d.ts.map +1 -0
  397. package/dist/llms/writeLLMsTxt.d.ts +9 -0
  398. package/dist/llms/writeLLMsTxt.d.ts.map +1 -1
  399. package/dist/maps/index.js +5 -5
  400. package/dist/maps/index.mjs +3 -3
  401. package/dist/motion/gsap.d.ts +54 -0
  402. package/dist/motion/gsap.d.ts.map +1 -1
  403. package/dist/motion/gsap.js +34 -4
  404. package/dist/motion/gsap.js.map +1 -1
  405. package/dist/motion/gsap.mjs +33 -5
  406. package/dist/motion/gsap.mjs.map +1 -1
  407. package/dist/motion/gsap.test.d.ts +2 -0
  408. package/dist/motion/gsap.test.d.ts.map +1 -0
  409. package/dist/og/config.d.ts +6 -0
  410. package/dist/og/config.d.ts.map +1 -1
  411. package/dist/og/contrast.d.ts +33 -0
  412. package/dist/og/contrast.d.ts.map +1 -0
  413. package/dist/og/index.d.ts +2 -0
  414. package/dist/og/index.d.ts.map +1 -1
  415. package/dist/og/index.js +26 -8
  416. package/dist/og/index.mjs +3 -1
  417. package/dist/og/pages.d.ts +101 -0
  418. package/dist/og/pages.d.ts.map +1 -1
  419. package/dist/og/route-copy.d.ts +34 -0
  420. package/dist/og/route-copy.d.ts.map +1 -0
  421. package/dist/og/route-fit.d.ts +77 -0
  422. package/dist/og/route-fit.d.ts.map +1 -0
  423. package/dist/og/route.d.ts +80 -20
  424. package/dist/og/route.d.ts.map +1 -1
  425. package/dist/og/route.js +195 -25
  426. package/dist/og/route.js.map +1 -1
  427. package/dist/og/route.mjs +193 -26
  428. package/dist/og/route.mjs.map +1 -1
  429. package/dist/og/route.test.d.ts +2 -0
  430. package/dist/og/route.test.d.ts.map +1 -0
  431. package/dist/og/template.d.ts.map +1 -1
  432. package/dist/og/wiring.d.ts +48 -4
  433. package/dist/og/wiring.d.ts.map +1 -1
  434. package/dist/proxy/index.d.ts +16 -11
  435. package/dist/proxy/index.d.ts.map +1 -1
  436. package/dist/proxy/index.js +15 -10
  437. package/dist/proxy/index.js.map +1 -1
  438. package/dist/proxy/index.mjs +12 -7
  439. package/dist/proxy/index.mjs.map +1 -1
  440. package/dist/proxy/llms-discovery.test.d.ts +2 -0
  441. package/dist/proxy/llms-discovery.test.d.ts.map +1 -0
  442. package/dist/redirects/index.d.ts +25 -1
  443. package/dist/redirects/index.d.ts.map +1 -1
  444. package/dist/redirects/index.js +11 -8
  445. package/dist/redirects/index.mjs +4 -1
  446. package/dist/redirects/index.test.d.ts +2 -0
  447. package/dist/redirects/index.test.d.ts.map +1 -0
  448. package/dist/redirects/not-found.d.ts +14 -29
  449. package/dist/redirects/not-found.d.ts.map +1 -1
  450. package/dist/redirects/not-found.js +15 -5
  451. package/dist/redirects/not-found.js.map +1 -1
  452. package/dist/redirects/not-found.mjs +11 -1
  453. package/dist/redirects/not-found.mjs.map +1 -1
  454. package/dist/robots/index.d.ts +7 -1
  455. package/dist/robots/index.d.ts.map +1 -1
  456. package/dist/robots/index.js +27 -1
  457. package/dist/robots/index.js.map +1 -1
  458. package/dist/robots/index.mjs +4 -1
  459. package/dist/robots/index.mjs.map +1 -1
  460. package/dist/robots/index.test.d.ts +2 -0
  461. package/dist/robots/index.test.d.ts.map +1 -0
  462. package/dist/robots/next-internals.d.ts +22 -0
  463. package/dist/robots/next-internals.d.ts.map +1 -0
  464. package/dist/search/index.js +4 -4
  465. package/dist/search/index.mjs +3 -3
  466. package/dist/seo/ManagedContent.d.ts +4 -2
  467. package/dist/seo/ManagedContent.d.ts.map +1 -1
  468. package/dist/seo/ManagedFAQ.d.ts.map +1 -1
  469. package/dist/seo/ManagedInternalLinks.d.ts.map +1 -1
  470. package/dist/seo/ManagedSchema.d.ts.map +1 -1
  471. package/dist/seo/client.js +6 -6
  472. package/dist/seo/client.mjs +5 -5
  473. package/dist/seo/getManagedMetadata.d.ts.map +1 -1
  474. package/dist/seo/getManagedMetadata.test.d.ts +2 -0
  475. package/dist/seo/getManagedMetadata.test.d.ts.map +1 -0
  476. package/dist/seo/index.js +59 -49
  477. package/dist/seo/index.js.map +1 -1
  478. package/dist/seo/index.mjs +29 -19
  479. package/dist/seo/index.mjs.map +1 -1
  480. package/dist/seo/managed-schema-filter.test.d.ts +2 -0
  481. package/dist/seo/managed-schema-filter.test.d.ts.map +1 -0
  482. package/dist/seo/register-sitemap-cli-impl.d.ts +32 -0
  483. package/dist/seo/register-sitemap-cli-impl.d.ts.map +1 -1
  484. package/dist/seo/register-sitemap-cli.d.ts +7 -0
  485. package/dist/seo/register-sitemap-cli.d.ts.map +1 -1
  486. package/dist/seo/register-sitemap-cli.js +273 -56
  487. package/dist/seo/register-sitemap-cli.js.map +1 -1
  488. package/dist/seo/register-sitemap-cli.mjs +269 -52
  489. package/dist/seo/register-sitemap-cli.mjs.map +1 -1
  490. package/dist/seo/register-sitemap-request.d.ts +36 -0
  491. package/dist/seo/register-sitemap-request.d.ts.map +1 -0
  492. package/dist/seo/register-sitemap-request.test.d.ts +2 -0
  493. package/dist/seo/register-sitemap-request.test.d.ts.map +1 -0
  494. package/dist/seo/routing.d.ts +2 -0
  495. package/dist/seo/routing.d.ts.map +1 -1
  496. package/dist/seo/schema-filter.d.ts +43 -0
  497. package/dist/seo/schema-filter.d.ts.map +1 -0
  498. package/dist/seo/schema-filter.test.d.ts +2 -0
  499. package/dist/seo/schema-filter.test.d.ts.map +1 -0
  500. package/dist/seo/server-api.d.ts +15 -2
  501. package/dist/seo/server-api.d.ts.map +1 -1
  502. package/dist/seo/server.js +23 -18
  503. package/dist/seo/server.mjs +7 -2
  504. package/dist/seo/site-scope.test.d.ts +2 -0
  505. package/dist/seo/site-scope.test.d.ts.map +1 -0
  506. package/dist/seo/types.d.ts +30 -0
  507. package/dist/seo/types.d.ts.map +1 -1
  508. package/dist/seo-meta/contract.d.ts +60 -0
  509. package/dist/seo-meta/contract.d.ts.map +1 -0
  510. package/dist/seo-meta/contract.js +41 -0
  511. package/dist/seo-meta/contract.js.map +1 -0
  512. package/dist/seo-meta/contract.mjs +4 -0
  513. package/dist/seo-meta/contract.mjs.map +1 -0
  514. package/dist/seo-meta/contract.test.d.ts +2 -0
  515. package/dist/seo-meta/contract.test.d.ts.map +1 -0
  516. package/dist/server/index.js +4 -3
  517. package/dist/server/index.mjs +3 -2
  518. package/dist/server/mint-site-token.d.ts +2 -32
  519. package/dist/server/mint-site-token.d.ts.map +1 -1
  520. package/dist/{server-api-RG3ZL3DV.mjs → server-api-A2EFCTZX.mjs} +7 -3
  521. package/dist/{server-api-RG3ZL3DV.mjs.map → server-api-A2EFCTZX.mjs.map} +1 -1
  522. package/dist/{server-api-RYJQAUGO.js → server-api-IWTZ7C3O.js} +25 -21
  523. package/dist/{server-api-RYJQAUGO.js.map → server-api-IWTZ7C3O.js.map} +1 -1
  524. package/dist/shared/build-entries.d.ts +2 -0
  525. package/dist/shared/build-entries.d.ts.map +1 -1
  526. package/dist/shared/fresh-fetch.d.ts +64 -0
  527. package/dist/shared/fresh-fetch.d.ts.map +1 -0
  528. package/dist/shared/fresh-fetch.test.d.ts +2 -0
  529. package/dist/shared/fresh-fetch.test.d.ts.map +1 -0
  530. package/dist/shared/next-files.d.ts +42 -0
  531. package/dist/shared/next-files.d.ts.map +1 -0
  532. package/dist/shared/next-files.test.d.ts +2 -0
  533. package/dist/shared/next-files.test.d.ts.map +1 -0
  534. package/dist/shared/page-leave.d.ts +27 -0
  535. package/dist/shared/page-leave.d.ts.map +1 -0
  536. package/dist/shared/page-leave.test.d.ts +2 -0
  537. package/dist/shared/page-leave.test.d.ts.map +1 -0
  538. package/dist/shared/source-graph.d.ts +63 -0
  539. package/dist/shared/source-graph.d.ts.map +1 -0
  540. package/dist/shared/source-graph.test.d.ts +2 -0
  541. package/dist/shared/source-graph.test.d.ts.map +1 -0
  542. package/dist/shared/version.d.ts +1 -1
  543. package/dist/signal/SignalCore.d.ts.map +1 -1
  544. package/dist/signal/index.js +11 -11
  545. package/dist/signal/index.mjs +2 -2
  546. package/dist/sitemap/discover.d.ts.map +1 -1
  547. package/dist/sitemap/index.d.ts +25 -5
  548. package/dist/sitemap/index.d.ts.map +1 -1
  549. package/dist/sitemap/index.js +54 -51
  550. package/dist/sitemap/index.js.map +1 -1
  551. package/dist/sitemap/index.mjs +39 -36
  552. package/dist/sitemap/index.mjs.map +1 -1
  553. package/dist/sitemap/shared.d.ts +65 -0
  554. package/dist/sitemap/shared.d.ts.map +1 -1
  555. package/dist/sitemap/trailing-slash.test.d.ts +2 -0
  556. package/dist/sitemap/trailing-slash.test.d.ts.map +1 -0
  557. package/dist/sites/resolve.d.ts.map +1 -1
  558. package/dist/sites/site-param.d.ts +16 -0
  559. package/dist/sites/site-param.d.ts.map +1 -0
  560. package/dist/sync/index.js +17 -17
  561. package/dist/sync/index.mjs +4 -4
  562. package/dist/writeLLMsTxt-CQ7A4AAL.js +20 -0
  563. package/dist/writeLLMsTxt-CQ7A4AAL.js.map +1 -0
  564. package/dist/writeLLMsTxt-NX5MSPYX.mjs +11 -0
  565. package/dist/writeLLMsTxt-NX5MSPYX.mjs.map +1 -0
  566. package/package.json +25 -22
  567. package/dist/AnalyticsProvider-6PXC7UDP.js +0 -32
  568. package/dist/AnalyticsProvider-FVQIYSLY.mjs +0 -11
  569. package/dist/BlogViewTracker-S4HSRCW7.js.map +0 -1
  570. package/dist/BlogViewTracker-ZUGLBOVI.mjs.map +0 -1
  571. package/dist/ChatWidget-2TQWCXWP.js +0 -22
  572. package/dist/ChatWidget-DG52ZIE6.mjs +0 -13
  573. package/dist/EngageWidget-2VUJADIU.mjs +0 -12
  574. package/dist/EngageWidget-Z7RC2INM.js +0 -21
  575. package/dist/FormSpotlight-RHL5FWM2.mjs.map +0 -1
  576. package/dist/FormSpotlight-TED32NHP.js.map +0 -1
  577. package/dist/FormStage-DINIRFOX.mjs.map +0 -1
  578. package/dist/FormStage-PFEBKHGY.js.map +0 -1
  579. package/dist/ManagedForm-43WLCUAK.js +0 -23
  580. package/dist/ManagedForm-545YAUFC.mjs +0 -14
  581. package/dist/ManagedNewsletterForm-I3QN57HB.js.map +0 -1
  582. package/dist/ManagedNewsletterForm-ZPY5RRKX.mjs.map +0 -1
  583. package/dist/SignalCore-EEH5IM4U.mjs.map +0 -1
  584. package/dist/SignalCore-M4AXIMV4.js.map +0 -1
  585. package/dist/SitemapSync-46G7LVZS.mjs +0 -9
  586. package/dist/SitemapSync-XK4JKCS7.js +0 -18
  587. package/dist/chunk-46BMNWE6.js.map +0 -1
  588. package/dist/chunk-473WDGQZ.mjs.map +0 -1
  589. package/dist/chunk-4B4S56WJ.mjs.map +0 -1
  590. package/dist/chunk-5B4FABFK.js.map +0 -1
  591. package/dist/chunk-6CJP7BFM.js.map +0 -1
  592. package/dist/chunk-6OP5XSMM.mjs.map +0 -1
  593. package/dist/chunk-746RKQHA.js.map +0 -1
  594. package/dist/chunk-AEARU24Q.mjs.map +0 -1
  595. package/dist/chunk-AHZR4VGY.mjs.map +0 -1
  596. package/dist/chunk-AJQI3WTN.mjs.map +0 -1
  597. package/dist/chunk-B64AZC6P.js.map +0 -1
  598. package/dist/chunk-BZLIOT7Q.js.map +0 -1
  599. package/dist/chunk-C2MSD2UM.mjs.map +0 -1
  600. package/dist/chunk-CQRLKNHQ.js.map +0 -1
  601. package/dist/chunk-DQUBETXH.mjs +0 -6
  602. package/dist/chunk-EEQYKMGH.mjs.map +0 -1
  603. package/dist/chunk-GPLCPMVD.mjs.map +0 -1
  604. package/dist/chunk-GZJE23Y5.mjs.map +0 -1
  605. package/dist/chunk-H4OBGC43.mjs.map +0 -1
  606. package/dist/chunk-H7274TKR.mjs.map +0 -1
  607. package/dist/chunk-IPV2TUAT.js.map +0 -1
  608. package/dist/chunk-IYCLN3XS.mjs.map +0 -1
  609. package/dist/chunk-JEOKDUPQ.js +0 -45
  610. package/dist/chunk-JEOKDUPQ.js.map +0 -1
  611. package/dist/chunk-JNRHTZL4.js.map +0 -1
  612. package/dist/chunk-KPKQKFT4.js.map +0 -1
  613. package/dist/chunk-KSL3WA2I.js +0 -8
  614. package/dist/chunk-KY6M76JW.js.map +0 -1
  615. package/dist/chunk-LC7AM4J5.js.map +0 -1
  616. package/dist/chunk-LOS5D6B3.js +0 -72
  617. package/dist/chunk-LOS5D6B3.js.map +0 -1
  618. package/dist/chunk-NZSFOZJV.js.map +0 -1
  619. package/dist/chunk-OZ3FU4BT.js.map +0 -1
  620. package/dist/chunk-QJU6HBSK.mjs +0 -39
  621. package/dist/chunk-QJU6HBSK.mjs.map +0 -1
  622. package/dist/chunk-R3KTBKSW.js.map +0 -1
  623. package/dist/chunk-RIYAMYLV.mjs.map +0 -1
  624. package/dist/chunk-RU54J2PY.mjs.map +0 -1
  625. package/dist/chunk-TP7H6BSK.mjs.map +0 -1
  626. package/dist/chunk-UJ6CHZAI.mjs.map +0 -1
  627. package/dist/chunk-UU47DGHE.js.map +0 -1
  628. package/dist/chunk-X5TCH7VZ.js.map +0 -1
  629. package/dist/chunk-XIJ4F6IE.mjs +0 -63
  630. package/dist/chunk-XIJ4F6IE.mjs.map +0 -1
  631. package/dist/discover-BEJRYNFF.mjs +0 -4
  632. package/dist/discover-WVDYDUJX.js +0 -21
@@ -1,16 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import { traverse, isJSXIdentifier, isJSXAttribute, isFunctionDeclaration, isVariableDeclarator, isIdentifier, isStringLiteral, isJSXMemberExpression, isJSXExpressionContainer, isTemplateLiteral, isArrayExpression, isObjectExpression, isJSXText } from '../chunk-JOYMIGR2.mjs';
3
3
  import { parse } from '../chunk-5YA6SI4Z.mjs';
4
- import { buildOgHtml, TITLE_MAX_PX, OG_REPORT_ATTR } from '../chunk-UJ6CHZAI.mjs';
4
+ import { paramCardKeys, unmatchedCardKeys, DYNAMIC, PARAM_CARD_DIR, buildOgHtml, pageCardConfig, paramCardUrl } from '../chunk-XZO5I4RS.mjs';
5
+ import { TITLE_MAX_PX, OG_REPORT_ATTR } from '../chunk-YU7QZ3PP.mjs';
5
6
  import { require_main } from '../chunk-NNZDWY3L.mjs';
6
- import { findAppDirForDiscovery, discoverNextJsRoutes } from '../chunk-XIJ4F6IE.mjs';
7
- import { SITE_KIT_VERSION } from '../chunk-DQUBETXH.mjs';
7
+ import { findAppDirForDiscovery, NEXT_PROXY_FILES, NEXT_MIDDLEWARE_FILES, findConventionFile, NEXT_APP_DIRS, findSitemapRoute, findProxyFiles, findNextConfig, findRootLayout, discoverNextJsRoutes, hasPageFile, NEXT_SOURCE_EXTENSIONS } from '../chunk-U2V542EO.mjs';
8
+ import { applyTrailingSlash } from '../chunk-4LYW6PMU.mjs';
9
+ import { SITE_KIT_VERSION } from '../chunk-HRMGITUZ.mjs';
8
10
  import { __commonJS, __require, __toESM, __export, __privateAdd, __publicField, __privateGet, __privateMethod, __privateSet, __privateWrapper } from '../chunk-BEXTDHO4.mjs';
9
11
  import { EventEmitter } from 'events';
10
12
  import childProcess, { execFile as execFile$1, execSync, spawnSync, spawn } from 'child_process';
11
13
  import path12, { win32, posix } from 'path';
12
- import * as fs from 'fs';
13
- import fs__default, { realpathSync, existsSync, readFileSync, readdirSync, statSync, readlinkSync, readdir as readdir$1, lstatSync, rmSync, mkdtempSync, writeFileSync } from 'fs';
14
+ import * as fs20 from 'fs';
15
+ import fs20__default, { realpathSync, existsSync, readFileSync, readdirSync, statSync, readlinkSync, readdir as readdir$1, lstatSync, rmSync, mkdtempSync, writeFileSync } from 'fs';
14
16
  import process2 from 'process';
15
17
  import { styleText, promisify, stripVTControlCharacters } from 'util';
16
18
  import os from 'os';
@@ -19,7 +21,7 @@ import { AsyncLocalStorage, AsyncResource } from 'async_hooks';
19
21
  import * as readline3 from 'readline';
20
22
  import readline3__default from 'readline';
21
23
  import { randomUUID } from 'crypto';
22
- import fs3, { realpath, readlink, readdir, lstat, constants } from 'fs/promises';
24
+ import fs3, { realpath as realpath$1, readlink, readdir, lstat, constants } from 'fs/promises';
23
25
  import { fileURLToPath, URL as URL$1 } from 'url';
24
26
  import { Buffer as Buffer$1 } from 'buffer';
25
27
  import http from 'http';
@@ -6202,10 +6204,10 @@ var require_lib2 = __commonJS({
6202
6204
  exports.analyse = analyse;
6203
6205
  var detectFile = (filepath, opts = {}) => new Promise((resolve, reject) => {
6204
6206
  let fd;
6205
- const fs29 = (0, node_1.default)();
6207
+ const fs31 = (0, node_1.default)();
6206
6208
  const handler = (err, buffer) => {
6207
6209
  if (fd) {
6208
- fs29.closeSync(fd);
6210
+ fs31.closeSync(fd);
6209
6211
  }
6210
6212
  if (err) {
6211
6213
  reject(err);
@@ -6217,9 +6219,9 @@ var require_lib2 = __commonJS({
6217
6219
  };
6218
6220
  const sampleSize = (opts === null || opts === void 0 ? void 0 : opts.sampleSize) || 0;
6219
6221
  if (sampleSize > 0) {
6220
- fd = fs29.openSync(filepath, "r");
6222
+ fd = fs31.openSync(filepath, "r");
6221
6223
  let sample = Buffer.allocUnsafe(sampleSize);
6222
- fs29.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
6224
+ fs31.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
6223
6225
  if (err) {
6224
6226
  handler(err, null);
6225
6227
  } else {
@@ -6231,22 +6233,22 @@ var require_lib2 = __commonJS({
6231
6233
  });
6232
6234
  return;
6233
6235
  }
6234
- fs29.readFile(filepath, handler);
6236
+ fs31.readFile(filepath, handler);
6235
6237
  });
6236
6238
  exports.detectFile = detectFile;
6237
6239
  var detectFileSync = (filepath, opts = {}) => {
6238
- const fs29 = (0, node_1.default)();
6240
+ const fs31 = (0, node_1.default)();
6239
6241
  if (opts && opts.sampleSize) {
6240
- const fd = fs29.openSync(filepath, "r");
6242
+ const fd = fs31.openSync(filepath, "r");
6241
6243
  let sample = Buffer.allocUnsafe(opts.sampleSize);
6242
- const bytesRead = fs29.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
6244
+ const bytesRead = fs31.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
6243
6245
  if (bytesRead < opts.sampleSize) {
6244
6246
  sample = sample.subarray(0, bytesRead);
6245
6247
  }
6246
- fs29.closeSync(fd);
6248
+ fs31.closeSync(fd);
6247
6249
  return (0, exports.detect)(sample);
6248
6250
  }
6249
- return (0, exports.detect)(fs29.readFileSync(filepath));
6251
+ return (0, exports.detect)(fs31.readFileSync(filepath));
6250
6252
  };
6251
6253
  exports.detectFileSync = detectFileSync;
6252
6254
  exports.default = {
@@ -12247,7 +12249,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
12247
12249
  * @param {string} subcommandName
12248
12250
  */
12249
12251
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
12250
- if (fs__default.existsSync(executableFile)) return;
12252
+ if (fs20__default.existsSync(executableFile)) return;
12251
12253
  const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
12252
12254
  const executableMissing = `'${executableFile}' does not exist
12253
12255
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
@@ -12265,10 +12267,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
12265
12267
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
12266
12268
  function findFile(baseDir, baseName) {
12267
12269
  const localBin = path12.resolve(baseDir, baseName);
12268
- if (fs__default.existsSync(localBin)) return localBin;
12270
+ if (fs20__default.existsSync(localBin)) return localBin;
12269
12271
  if (sourceExt.includes(path12.extname(baseName))) return void 0;
12270
12272
  const foundExt = sourceExt.find(
12271
- (ext2) => fs__default.existsSync(`${localBin}${ext2}`)
12273
+ (ext2) => fs20__default.existsSync(`${localBin}${ext2}`)
12272
12274
  );
12273
12275
  if (foundExt) return `${localBin}${foundExt}`;
12274
12276
  return void 0;
@@ -12280,7 +12282,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
12280
12282
  if (this._scriptPath) {
12281
12283
  let resolvedScriptPath;
12282
12284
  try {
12283
- resolvedScriptPath = fs__default.realpathSync(this._scriptPath);
12285
+ resolvedScriptPath = fs20__default.realpathSync(this._scriptPath);
12284
12286
  } catch {
12285
12287
  resolvedScriptPath = this._scriptPath;
12286
12288
  }
@@ -13236,9 +13238,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
13236
13238
  * @param {string} [path]
13237
13239
  * @return {(string|null|Command)}
13238
13240
  */
13239
- executableDir(path29) {
13240
- if (path29 === void 0) return this._executableDir;
13241
- this._executableDir = path29;
13241
+ executableDir(path31) {
13242
+ if (path31 === void 0) return this._executableDir;
13243
+ this._executableDir = path31;
13242
13244
  return this;
13243
13245
  }
13244
13246
  /**
@@ -20345,9 +20347,9 @@ function observableToAsyncIterable(source) {
20345
20347
 
20346
20348
  // node_modules/.pnpm/inquirer@14.0.2_@types+node@26.2.0/node_modules/inquirer/dist/ui/prompt.js
20347
20349
  var _ = {
20348
- set: (obj, path29 = "", value) => {
20350
+ set: (obj, path31 = "", value) => {
20349
20351
  let pointer = obj;
20350
- path29.split(".").forEach((key, index, arr) => {
20352
+ path31.split(".").forEach((key, index, arr) => {
20351
20353
  if (key === "__proto__" || key === "constructor")
20352
20354
  return;
20353
20355
  if (index === arr.length - 1) {
@@ -20358,8 +20360,8 @@ var _ = {
20358
20360
  pointer = pointer[key];
20359
20361
  });
20360
20362
  },
20361
- get: (obj, path29 = "", defaultValue) => {
20362
- const travel = (regexp) => String.prototype.split.call(path29, regexp).filter(Boolean).reduce(
20363
+ get: (obj, path31 = "", defaultValue) => {
20364
+ const travel = (regexp) => String.prototype.split.call(path31, regexp).filter(Boolean).reduce(
20363
20365
  // @ts-expect-error implicit any on res[key]
20364
20366
  (res, key) => res == null ? res : res[key],
20365
20367
  obj
@@ -20716,18 +20718,18 @@ function scanForForms(ast, content, filePath) {
20716
20718
  const forms = [];
20717
20719
  content.split("\n");
20718
20720
  traverse(ast, {
20719
- JSXElement(path29) {
20720
- const opening = path29.node.openingElement;
20721
+ JSXElement(path31) {
20722
+ const opening = path31.node.openingElement;
20721
20723
  if (isJSXIdentifier(opening.name) && opening.name.name === "form") {
20722
- const fields = extractFieldsFromForm(path29);
20724
+ const fields = extractFieldsFromForm(path31);
20723
20725
  const hasOnSubmit = opening.attributes.some(
20724
20726
  (attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "onSubmit"
20725
20727
  );
20726
20728
  if (hasOnSubmit && fields.length > 0) {
20727
- const startLine = path29.node.loc?.start.line || 0;
20728
- const endLine = path29.node.loc?.end.line || 0;
20729
+ const startLine = path31.node.loc?.start.line || 0;
20730
+ const endLine = path31.node.loc?.end.line || 0;
20729
20731
  let componentName = "UnknownForm";
20730
- let current = path29.parentPath;
20732
+ let current = path31.parentPath;
20731
20733
  while (current) {
20732
20734
  if (isFunctionDeclaration(current.node) && current.node.id) {
20733
20735
  componentName = current.node.id.name;
@@ -20760,7 +20762,7 @@ function scanForForms(ast, content, filePath) {
20760
20762
  }
20761
20763
  if (isJSXIdentifier(opening.name) && opening.name.name === "Form") {
20762
20764
  if (content.includes("Formik") || content.includes("formik")) {
20763
- const fields = extractFieldsFromFormik(path29);
20765
+ const fields = extractFieldsFromFormik(path31);
20764
20766
  if (fields.length > 0) {
20765
20767
  forms.push({
20766
20768
  filePath,
@@ -20771,8 +20773,8 @@ function scanForForms(ast, content, filePath) {
20771
20773
  submitsTo: null,
20772
20774
  complexity: "moderate",
20773
20775
  suggestedAction: "assisted",
20774
- startLine: path29.node.loc?.start.line || 0,
20775
- endLine: path29.node.loc?.end.line || 0
20776
+ startLine: path31.node.loc?.start.line || 0,
20777
+ endLine: path31.node.loc?.end.line || 0
20776
20778
  });
20777
20779
  }
20778
20780
  }
@@ -20790,8 +20792,8 @@ function extractFieldsFromForm(formPath) {
20790
20792
  const radioGroups = /* @__PURE__ */ new Map();
20791
20793
  const checkboxGroups = /* @__PURE__ */ new Map();
20792
20794
  formPath.traverse({
20793
- JSXElement(path29) {
20794
- const opening = path29.node.openingElement;
20795
+ JSXElement(path31) {
20796
+ const opening = path31.node.openingElement;
20795
20797
  const tagName = isJSXIdentifier(opening.name) ? opening.name.name : null;
20796
20798
  if (["input", "textarea", "select"].includes(tagName || "")) {
20797
20799
  const attrs = opening.attributes;
@@ -20838,7 +20840,7 @@ function extractFieldsFromForm(formPath) {
20838
20840
  }
20839
20841
  if (tagName === "select") {
20840
20842
  const selectOptions = [];
20841
- path29.traverse({
20843
+ path31.traverse({
20842
20844
  JSXElement(optionPath) {
20843
20845
  const optOpening = optionPath.node.openingElement;
20844
20846
  const optTagName = isJSXIdentifier(optOpening.name) ? optOpening.name.name : null;
@@ -20913,8 +20915,8 @@ function extractFieldsFromForm(formPath) {
20913
20915
  function extractFieldsFromFormik(formPath, content) {
20914
20916
  const fields = [];
20915
20917
  formPath.traverse({
20916
- JSXElement(path29) {
20917
- const opening = path29.node.openingElement;
20918
+ JSXElement(path31) {
20919
+ const opening = path31.node.openingElement;
20918
20920
  const tagName = isJSXIdentifier(opening.name) ? opening.name.name : null;
20919
20921
  if (tagName === "Field" || tagName === "FastField") {
20920
20922
  const attrs = opening.attributes;
@@ -21033,11 +21035,11 @@ function scanForMetadata(ast, content, filePath) {
21033
21035
  }
21034
21036
  let hasHeadComponent = false;
21035
21037
  traverse(ast, {
21036
- JSXElement(path29) {
21037
- const opening = path29.node.openingElement;
21038
+ JSXElement(path31) {
21039
+ const opening = path31.node.openingElement;
21038
21040
  if (isJSXIdentifier(opening.name) && opening.name.name === "Head") {
21039
21041
  hasHeadComponent = true;
21040
- path29.stop();
21042
+ path31.stop();
21041
21043
  }
21042
21044
  }
21043
21045
  });
@@ -21072,8 +21074,8 @@ function scanForWidgets(ast, content, filePath) {
21072
21074
  for (const { pattern, type } of widgetPatterns) {
21073
21075
  if (pattern.test(content)) {
21074
21076
  traverse(ast, {
21075
- JSXElement(path29) {
21076
- const opening = path29.node.openingElement;
21077
+ JSXElement(path31) {
21078
+ const opening = path31.node.openingElement;
21077
21079
  if (isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
21078
21080
  const srcAttr = opening.attributes.find(
21079
21081
  (attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "src"
@@ -21088,8 +21090,8 @@ function scanForWidgets(ast, content, filePath) {
21088
21090
  filePath,
21089
21091
  widgetType: type,
21090
21092
  scriptTag: src,
21091
- startLine: path29.node.loc?.start.line || 0,
21092
- endLine: path29.node.loc?.end.line || 0
21093
+ startLine: path31.node.loc?.start.line || 0,
21094
+ endLine: path31.node.loc?.end.line || 0
21093
21095
  });
21094
21096
  }
21095
21097
  }
@@ -21228,8 +21230,8 @@ function scanForSchemas(ast, content, filePath) {
21228
21230
  return schemas;
21229
21231
  }
21230
21232
  traverse(ast, {
21231
- JSXElement(path29) {
21232
- const opening = path29.node.openingElement;
21233
+ JSXElement(path31) {
21234
+ const opening = path31.node.openingElement;
21233
21235
  if (isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
21234
21236
  const typeAttr = opening.attributes.find(
21235
21237
  (attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "type"
@@ -21256,8 +21258,8 @@ function scanForSchemas(ast, content, filePath) {
21256
21258
  filePath,
21257
21259
  type: detectedType,
21258
21260
  schemaType,
21259
- startLine: path29.node.loc?.start.line || 0,
21260
- endLine: path29.node.loc?.end.line || 0
21261
+ startLine: path31.node.loc?.start.line || 0,
21262
+ endLine: path31.node.loc?.end.line || 0
21261
21263
  });
21262
21264
  }
21263
21265
  }
@@ -21290,8 +21292,8 @@ function scanForFAQs(ast, content, filePath) {
21290
21292
  /questions?\s*(?:and|&)?\s*answers?/i
21291
21293
  ];
21292
21294
  traverse(ast, {
21293
- JSXElement(path29) {
21294
- const opening = path29.node.openingElement;
21295
+ JSXElement(path31) {
21296
+ const opening = path31.node.openingElement;
21295
21297
  let tagName = "";
21296
21298
  if (isJSXIdentifier(opening.name)) {
21297
21299
  tagName = opening.name.name;
@@ -21304,8 +21306,8 @@ function scanForFAQs(ast, content, filePath) {
21304
21306
  faqs.push({
21305
21307
  filePath,
21306
21308
  type: "details-summary",
21307
- startLine: path29.node.loc?.start.line || 0,
21308
- endLine: path29.node.loc?.end.line || 0,
21309
+ startLine: path31.node.loc?.start.line || 0,
21310
+ endLine: path31.node.loc?.end.line || 0,
21309
21311
  hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
21310
21312
  });
21311
21313
  return;
@@ -21313,7 +21315,7 @@ function scanForFAQs(ast, content, filePath) {
21313
21315
  for (const pattern of faqPatterns) {
21314
21316
  if (pattern.test(tagName)) {
21315
21317
  let itemCount = 0;
21316
- path29.traverse({
21318
+ path31.traverse({
21317
21319
  JSXElement(itemPath) {
21318
21320
  const itemOpening = itemPath.node.openingElement;
21319
21321
  if (isJSXIdentifier(itemOpening.name)) {
@@ -21329,8 +21331,8 @@ function scanForFAQs(ast, content, filePath) {
21329
21331
  type: "accordion",
21330
21332
  componentName: tagName,
21331
21333
  itemCount: itemCount || void 0,
21332
- startLine: path29.node.loc?.start.line || 0,
21333
- endLine: path29.node.loc?.end.line || 0,
21334
+ startLine: path31.node.loc?.start.line || 0,
21335
+ endLine: path31.node.loc?.end.line || 0,
21334
21336
  hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
21335
21337
  });
21336
21338
  return;
@@ -21453,8 +21455,8 @@ function scanForImages(ast, content, filePath) {
21453
21455
  return images;
21454
21456
  }
21455
21457
  traverse(ast, {
21456
- JSXElement(path29) {
21457
- const opening = path29.node.openingElement;
21458
+ JSXElement(path31) {
21459
+ const opening = path31.node.openingElement;
21458
21460
  if (!isJSXIdentifier(opening.name)) return;
21459
21461
  const tagName = opening.name.name;
21460
21462
  if (tagName === "img" || tagName === "Image") {
@@ -21482,8 +21484,8 @@ function scanForImages(ast, content, filePath) {
21482
21484
  src: src || void 0,
21483
21485
  alt: alt || void 0,
21484
21486
  isLocal,
21485
- startLine: path29.node.loc?.start.line || 0,
21486
- endLine: path29.node.loc?.end.line || 0
21487
+ startLine: path31.node.loc?.start.line || 0,
21488
+ endLine: path31.node.loc?.end.line || 0
21487
21489
  });
21488
21490
  }
21489
21491
  }
@@ -22374,18 +22376,18 @@ async function migrateFile(filePath, options) {
22374
22376
  let componentName = "Form";
22375
22377
  const traverse2 = (await import('../lib-RSDMEKDQ.mjs')).default;
22376
22378
  traverse2(ast, {
22377
- ExportNamedDeclaration(path29) {
22378
- const decl = path29.node.declaration;
22379
+ ExportNamedDeclaration(path31) {
22380
+ const decl = path31.node.declaration;
22379
22381
  if (decl && decl.type === "FunctionDeclaration" && decl.id) {
22380
22382
  componentName = decl.id.name;
22381
- path29.stop();
22383
+ path31.stop();
22382
22384
  }
22383
22385
  },
22384
- ExportDefaultDeclaration(path29) {
22385
- const decl = path29.node.declaration;
22386
+ ExportDefaultDeclaration(path31) {
22387
+ const decl = path31.node.declaration;
22386
22388
  if (decl && decl.type === "FunctionDeclaration" && decl.id) {
22387
22389
  componentName = decl.id.name;
22388
- path29.stop();
22390
+ path31.stop();
22389
22391
  }
22390
22392
  }
22391
22393
  });
@@ -22501,7 +22503,7 @@ function addImportSafely2(content, importStatement) {
22501
22503
  async function generateLayout() {
22502
22504
  const layoutPath = await findLayoutFile();
22503
22505
  if (!layoutPath) {
22504
- throw new Error("Could not find layout.tsx file");
22506
+ throw new Error("Could not find a root layout (app/layout.tsx, .jsx, .ts or .js)");
22505
22507
  }
22506
22508
  const content = await fs3.readFile(layoutPath, "utf-8");
22507
22509
  if (content.includes("SiteKitLayout") || content.includes("SiteKitProvider")) {
@@ -22535,27 +22537,12 @@ async function generateLayout() {
22535
22537
  await fs3.writeFile(layoutPath, newContent, "utf-8");
22536
22538
  }
22537
22539
  async function findLayoutFile() {
22538
- const possiblePaths = [
22539
- "src/app/layout.tsx",
22540
- "app/layout.tsx",
22541
- "src/app/layout.jsx",
22542
- "app/layout.jsx"
22543
- ];
22544
- for (const relativePath of possiblePaths) {
22545
- const fullPath = path12.join(process.cwd(), relativePath);
22546
- try {
22547
- await fs3.access(fullPath);
22548
- return fullPath;
22549
- } catch {
22550
- continue;
22551
- }
22552
- }
22553
- return null;
22540
+ return findRootLayout(process.cwd());
22554
22541
  }
22555
22542
  var isDockerCached;
22556
22543
  function hasDockerEnv() {
22557
22544
  try {
22558
- fs__default.statSync("/.dockerenv");
22545
+ fs20__default.statSync("/.dockerenv");
22559
22546
  return true;
22560
22547
  } catch {
22561
22548
  return false;
@@ -22563,7 +22550,7 @@ function hasDockerEnv() {
22563
22550
  }
22564
22551
  function hasDockerCGroup() {
22565
22552
  try {
22566
- return fs__default.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
22553
+ return fs20__default.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
22567
22554
  } catch {
22568
22555
  return false;
22569
22556
  }
@@ -22579,7 +22566,7 @@ function isDocker() {
22579
22566
  var cachedResult;
22580
22567
  var hasContainerEnv = () => {
22581
22568
  try {
22582
- fs__default.statSync("/run/.containerenv");
22569
+ fs20__default.statSync("/run/.containerenv");
22583
22570
  return true;
22584
22571
  } catch {
22585
22572
  return false;
@@ -22604,12 +22591,12 @@ var isWsl = () => {
22604
22591
  return true;
22605
22592
  }
22606
22593
  try {
22607
- if (fs__default.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
22594
+ if (fs20__default.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
22608
22595
  return !isInsideContainer();
22609
22596
  }
22610
22597
  } catch {
22611
22598
  }
22612
- if (fs__default.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs__default.existsSync("/run/WSL")) {
22599
+ if (fs20__default.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs20__default.existsSync("/run/WSL")) {
22613
22600
  return !isInsideContainer();
22614
22601
  }
22615
22602
  return false;
@@ -22712,15 +22699,15 @@ var wslDefaultBrowser = async () => {
22712
22699
  const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
22713
22700
  return stdout.trim();
22714
22701
  };
22715
- var convertWslPathToWindows = async (path29) => {
22716
- if (/^[a-z]+:\/\//i.test(path29)) {
22717
- return path29;
22702
+ var convertWslPathToWindows = async (path31) => {
22703
+ if (/^[a-z]+:\/\//i.test(path31)) {
22704
+ return path31;
22718
22705
  }
22719
22706
  try {
22720
- const { stdout } = await execFile2("wslpath", ["-aw", path29], { encoding: "utf8" });
22707
+ const { stdout } = await execFile2("wslpath", ["-aw", path31], { encoding: "utf8" });
22721
22708
  return stdout.trim();
22722
22709
  } catch {
22723
- return path29;
22710
+ return path31;
22724
22711
  }
22725
22712
  };
22726
22713
 
@@ -25208,8 +25195,8 @@ async function templateCommand(sourcePath, options) {
25208
25195
  const slots = [];
25209
25196
  const componentNames = [];
25210
25197
  traverse(ast, {
25211
- JSXElement(path29) {
25212
- const openingElement = path29.node.openingElement;
25198
+ JSXElement(path31) {
25199
+ const openingElement = path31.node.openingElement;
25213
25200
  if (isJSXIdentifier(openingElement.name)) {
25214
25201
  const componentName = openingElement.name.name;
25215
25202
  if (componentName[0] === componentName[0].toUpperCase()) {
@@ -26333,11 +26320,230 @@ async function uploadSchemas(pages, globalSchema, config2) {
26333
26320
  }
26334
26321
  }
26335
26322
  }
26336
- var APP_DIRS = ["app", path12.join("src", "app")];
26337
- var CARD_FILE = /^(opengraph-image|twitter-image)\b.*\.(png|jpe?g|gif|webp)$/i;
26323
+ var SOURCE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
26324
+ function stripComments(source) {
26325
+ return source.replace(
26326
+ /("(?:\\.|[^"\\\n])*"|'(?:\\.|[^'\\\n])*'|`(?:\\.|[^`\\])*`)|\/\*[\s\S]*?\*\/|\/\/[^\n]*/g,
26327
+ (match, literal) => literal ?? (match.startsWith("/*") ? match.replace(/[^\n]/g, "") : "")
26328
+ );
26329
+ }
26330
+ function readText(file) {
26331
+ try {
26332
+ return fs20__default.readFileSync(file, "utf-8");
26333
+ } catch {
26334
+ return null;
26335
+ }
26336
+ }
26337
+ function isFile(p) {
26338
+ try {
26339
+ return fs20__default.statSync(p).isFile();
26340
+ } catch {
26341
+ return false;
26342
+ }
26343
+ }
26344
+ function realpath(p) {
26345
+ try {
26346
+ return fs20__default.realpathSync(p);
26347
+ } catch {
26348
+ return null;
26349
+ }
26350
+ }
26351
+ function resolveFile(base) {
26352
+ if (isFile(base) && SOURCE_EXTENSIONS.includes(path12.extname(base))) return base;
26353
+ const stem = base.replace(/\.(m|c)?js$/, "");
26354
+ for (const ext2 of SOURCE_EXTENSIONS) {
26355
+ if (isFile(stem + ext2)) return stem + ext2;
26356
+ }
26357
+ for (const ext2 of SOURCE_EXTENSIONS) {
26358
+ const index = path12.join(base, `index${ext2}`);
26359
+ if (isFile(index)) return index;
26360
+ }
26361
+ return null;
26362
+ }
26363
+ function importSpecifiers(source) {
26364
+ const found = /* @__PURE__ */ new Set();
26365
+ const patterns = [
26366
+ /\b(?:import|export)\s+(?:type\s+)?[^'"`;]*?\bfrom\s*['"]([^'"]+)['"]/g,
26367
+ /\bimport\s*['"]([^'"]+)['"]/g,
26368
+ /\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
26369
+ /\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g
26370
+ ];
26371
+ for (const re2 of patterns) {
26372
+ for (const m of source.matchAll(re2)) found.add(m[1]);
26373
+ }
26374
+ return [...found];
26375
+ }
26376
+ function readLooseJson(file) {
26377
+ const text = readText(file);
26378
+ if (!text) return null;
26379
+ try {
26380
+ return JSON.parse(text);
26381
+ } catch {
26382
+ try {
26383
+ const stripped = text.replace(/("(?:\\.|[^"\\])*")|\/\*[\s\S]*?\*\/|\/\/[^\n]*/g, (_m4, str) => str ?? "").replace(/,(\s*[}\]])/g, "$1");
26384
+ return JSON.parse(stripped);
26385
+ } catch {
26386
+ return null;
26387
+ }
26388
+ }
26389
+ }
26390
+ function loadScope(root) {
26391
+ const tsconfig = readLooseJson(path12.join(root, "tsconfig.json")) ?? readLooseJson(path12.join(root, "jsconfig.json"));
26392
+ const options = tsconfig?.compilerOptions ?? {};
26393
+ const baseUrl = path12.resolve(root, options.baseUrl ?? ".");
26394
+ const aliases = [];
26395
+ for (const [key, value] of Object.entries(options.paths ?? {})) {
26396
+ const star = key.indexOf("*");
26397
+ aliases.push({
26398
+ prefix: star === -1 ? key : key.slice(0, star),
26399
+ suffix: star === -1 ? "" : key.slice(star + 1),
26400
+ exact: star === -1,
26401
+ targets: (Array.isArray(value) ? value : [value]).map((t) => path12.resolve(baseUrl, t))
26402
+ });
26403
+ }
26404
+ return { root, aliases };
26405
+ }
26406
+ function packageRoot(dir) {
26407
+ let current = dir;
26408
+ for (; ; ) {
26409
+ if (["package.json", "tsconfig.json", "jsconfig.json"].some((f) => isFile(path12.join(current, f)))) return current;
26410
+ const parent = path12.dirname(current);
26411
+ if (parent === current) return dir;
26412
+ current = parent;
26413
+ }
26414
+ }
26415
+ function pickExportTarget(value) {
26416
+ if (typeof value === "string") return value;
26417
+ if (Array.isArray(value)) {
26418
+ for (const v2 of value) {
26419
+ const t = pickExportTarget(v2);
26420
+ if (t) return t;
26421
+ }
26422
+ return null;
26423
+ }
26424
+ if (value && typeof value === "object") {
26425
+ const conditions = value;
26426
+ for (const key of ["source", "import", "default", "require", "node", "types"]) {
26427
+ if (key in conditions) {
26428
+ const t = pickExportTarget(conditions[key]);
26429
+ if (t) return t;
26430
+ }
26431
+ }
26432
+ }
26433
+ return null;
26434
+ }
26435
+ function resolvePackageSubpath(pkgRoot, subpath) {
26436
+ const pkg = readLooseJson(path12.join(pkgRoot, "package.json")) ?? {};
26437
+ const exportsField = pkg.exports;
26438
+ if (exportsField !== void 0) {
26439
+ const map = typeof exportsField === "string" || Array.isArray(exportsField) || !Object.keys(exportsField).some((k2) => k2.startsWith(".")) ? { ".": exportsField } : exportsField;
26440
+ if (subpath in map) {
26441
+ const target = pickExportTarget(map[subpath]);
26442
+ if (target) return resolveFile(path12.resolve(pkgRoot, target));
26443
+ }
26444
+ for (const [key, value] of Object.entries(map)) {
26445
+ const star = key.indexOf("*");
26446
+ if (star === -1) continue;
26447
+ const prefix = key.slice(0, star);
26448
+ const suffix = key.slice(star + 1);
26449
+ if (subpath.startsWith(prefix) && subpath.endsWith(suffix) && subpath.length >= prefix.length + suffix.length) {
26450
+ const matched = subpath.slice(prefix.length, subpath.length - suffix.length);
26451
+ const target = pickExportTarget(value);
26452
+ if (target) return resolveFile(path12.resolve(pkgRoot, target.replace("*", matched)));
26453
+ }
26454
+ }
26455
+ }
26456
+ if (subpath === ".") {
26457
+ const main = pkg.source ?? pkg.module ?? pkg.main;
26458
+ if (typeof main === "string") {
26459
+ const hit = resolveFile(path12.resolve(pkgRoot, main));
26460
+ if (hit) return hit;
26461
+ }
26462
+ return resolveFile(path12.join(pkgRoot, "index"));
26463
+ }
26464
+ return resolveFile(path12.resolve(pkgRoot, subpath));
26465
+ }
26466
+ function workspacePackage(fromDir, name) {
26467
+ let current = fromDir;
26468
+ for (; ; ) {
26469
+ const candidate = path12.join(current, "node_modules", name);
26470
+ if (fs20__default.existsSync(candidate)) {
26471
+ const real = realpath(candidate);
26472
+ if (!real || real.split(path12.sep).includes("node_modules")) return null;
26473
+ return real;
26474
+ }
26475
+ const parent = path12.dirname(current);
26476
+ if (parent === current) return null;
26477
+ current = parent;
26478
+ }
26479
+ }
26480
+ function splitBare(specifier) {
26481
+ const parts = specifier.split("/");
26482
+ const nameParts = specifier.startsWith("@") ? parts.slice(0, 2) : parts.slice(0, 1);
26483
+ const rest = parts.slice(nameParts.length);
26484
+ return { name: nameParts.join("/"), subpath: rest.length ? `./${rest.join("/")}` : "." };
26485
+ }
26486
+ function readSourceGraph(entries, options = {}) {
26487
+ const { maxDepth = 4, maxFiles = 300 } = options;
26488
+ const scopes = /* @__PURE__ */ new Map();
26489
+ const scopeFor = (file) => {
26490
+ const root = packageRoot(path12.dirname(file));
26491
+ let scope = scopes.get(root);
26492
+ if (!scope) {
26493
+ scope = loadScope(root);
26494
+ scopes.set(root, scope);
26495
+ }
26496
+ return scope;
26497
+ };
26498
+ const resolve = (specifier, fromFile) => {
26499
+ const fromDir = path12.dirname(fromFile);
26500
+ if (specifier.startsWith(".")) return resolveFile(path12.resolve(fromDir, specifier));
26501
+ if (specifier.startsWith("/") || /^[a-z]+:/i.test(specifier)) return null;
26502
+ const scope = scopeFor(fromFile);
26503
+ for (const alias of scope.aliases) {
26504
+ const hit = alias.exact ? specifier === alias.prefix : specifier.startsWith(alias.prefix) && specifier.endsWith(alias.suffix);
26505
+ if (!hit) continue;
26506
+ const matched = alias.exact ? "" : specifier.slice(alias.prefix.length, specifier.length - alias.suffix.length);
26507
+ for (const target of alias.targets) {
26508
+ const hit2 = resolveFile(target.replace("*", matched));
26509
+ if (hit2) return hit2;
26510
+ }
26511
+ }
26512
+ const { name, subpath } = splitBare(specifier);
26513
+ const pkg = workspacePackage(fromDir, name);
26514
+ return pkg ? resolvePackageSubpath(pkg, subpath) : null;
26515
+ };
26516
+ const seen = /* @__PURE__ */ new Set();
26517
+ const out = [];
26518
+ let frontier = entries.map((e) => path12.resolve(e));
26519
+ for (let depth = 0; depth <= maxDepth && frontier.length && out.length < maxFiles; depth++) {
26520
+ const next = [];
26521
+ for (const file of frontier) {
26522
+ if (seen.has(file) || out.length >= maxFiles) continue;
26523
+ seen.add(file);
26524
+ const raw = readText(file);
26525
+ if (raw === null) continue;
26526
+ const source = stripComments(raw);
26527
+ out.push({ file, source });
26528
+ if (depth === maxDepth) continue;
26529
+ for (const specifier of importSpecifiers(source)) {
26530
+ const hit = resolve(specifier, file);
26531
+ if (hit && !seen.has(hit)) next.push(hit);
26532
+ }
26533
+ }
26534
+ frontier = next;
26535
+ }
26536
+ return out;
26537
+ }
26538
+ function readWithImports(cwd, rel, options) {
26539
+ return readSourceGraph([path12.join(cwd, rel)], options).map((f) => f.source).join("\n");
26540
+ }
26541
+
26542
+ // src/og/wiring.ts
26543
+ var CARD_FILE = /^(opengraph-image|twitter-image)\b.*\.(png|jpe?g|gif|webp|tsx|ts|jsx|js)$/i;
26338
26544
  function safeExists(p) {
26339
26545
  try {
26340
- return fs__default.existsSync(p);
26546
+ return fs20__default.existsSync(p);
26341
26547
  } catch {
26342
26548
  return false;
26343
26549
  }
@@ -26347,7 +26553,7 @@ function findPageCards(cwd) {
26347
26553
  const walk = (dir) => {
26348
26554
  let entries;
26349
26555
  try {
26350
- entries = fs__default.readdirSync(dir, { withFileTypes: true });
26556
+ entries = fs20__default.readdirSync(dir, { withFileTypes: true });
26351
26557
  } catch {
26352
26558
  return;
26353
26559
  }
@@ -26358,34 +26564,97 @@ function findPageCards(cwd) {
26358
26564
  else if (CARD_FILE.test(entry.name)) found.push(full);
26359
26565
  }
26360
26566
  };
26361
- for (const rel of APP_DIRS) walk(path12.join(cwd, rel));
26567
+ for (const rel of NEXT_APP_DIRS) walk(path12.join(cwd, rel));
26362
26568
  return found;
26363
26569
  }
26364
- function readOgWiring(cwd) {
26570
+ function findPageFiles(cwd) {
26571
+ const found = [];
26572
+ const pageFile = new RegExp(`^page\\.(${NEXT_SOURCE_EXTENSIONS.join("|")})$`);
26573
+ const walk = (dir) => {
26574
+ let entries;
26575
+ try {
26576
+ entries = fs20__default.readdirSync(dir, { withFileTypes: true });
26577
+ } catch {
26578
+ return;
26579
+ }
26580
+ for (const entry of entries) {
26581
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
26582
+ const full = path12.join(dir, entry.name);
26583
+ if (entry.isDirectory()) walk(full);
26584
+ else if (pageFile.test(entry.name)) found.push(full);
26585
+ }
26586
+ };
26587
+ for (const rel of NEXT_APP_DIRS) walk(path12.join(cwd, rel));
26588
+ return found;
26589
+ }
26590
+ function routeOf(cwd, dir) {
26591
+ const appRoot = NEXT_APP_DIRS.map((rel2) => path12.join(cwd, rel2)).find((root) => dir === root || dir.startsWith(root + path12.sep));
26592
+ const rel = appRoot ? path12.relative(appRoot, dir) : dir;
26593
+ const segments = rel.split(path12.sep).filter((s) => s && !(s.startsWith("(") && s.endsWith(")"))).map((s) => s.startsWith("[") && s.endsWith("]") ? "*" : s);
26594
+ return `/${segments.join("/")}`;
26595
+ }
26596
+ function readCodeCards(cwd, pageCards) {
26597
+ const code = pageCards.filter((f) => /^opengraph-image\.(tsx|ts|jsx|js)$/.test(path12.basename(f)));
26598
+ return code.map((file) => {
26599
+ const dir = path12.dirname(file);
26600
+ const page = findConventionFile(dir, "page");
26601
+ const source = page ? readSourceGraph([page], { maxDepth: 2, maxFiles: 40 }).map((f) => f.source).join("\n") : "";
26602
+ const pageOwn = page ? readSourceGraph([page], { maxDepth: 0 })[0]?.source ?? "" : "";
26603
+ return {
26604
+ file: path12.relative(cwd, file),
26605
+ route: routeOf(cwd, dir),
26606
+ declaresUrl: /\bcodeCardImage\s*\(/.test(source),
26607
+ // A page that deletes the key itself (the pre-`images: false` workaround)
26608
+ // is fine too.
26609
+ blogDeclaresImages: /\bgenerateBlogPostMetadata\s*\(/.test(pageOwn) && !/\bimages\s*:\s*false\b/.test(pageOwn) && !/\bdelete\s+[\w.]+\.images\b/.test(pageOwn)
26610
+ };
26611
+ });
26612
+ }
26613
+ function readTrailingSlash(cwd) {
26614
+ const rel = findNextConfig(cwd);
26615
+ if (!rel) return false;
26616
+ try {
26617
+ return /\btrailingSlash\s*:\s*true\b/.test(fs20__default.readFileSync(path12.join(cwd, rel), "utf-8"));
26618
+ } catch {
26619
+ return false;
26620
+ }
26621
+ }
26622
+ function readOgWiring(cwd, known = {}) {
26365
26623
  const siteCard = ["public/og.png", "public/og.jpg", "public/opengraph.png"].some(
26366
26624
  (rel) => safeExists(path12.join(cwd, rel))
26367
26625
  );
26368
- const layoutPath = ["app/layout.tsx", "src/app/layout.tsx"].map((rel) => path12.join(cwd, rel)).find(safeExists);
26626
+ const layoutPath = findRootLayout(cwd);
26369
26627
  let layout = "";
26370
26628
  if (layoutPath) {
26371
26629
  try {
26372
- layout = fs__default.readFileSync(layoutPath, "utf-8");
26630
+ layout = fs20__default.readFileSync(layoutPath, "utf-8");
26373
26631
  } catch {
26374
26632
  }
26375
26633
  }
26634
+ const pageCards = findPageCards(cwd);
26635
+ const entries = [...layoutPath ? [layoutPath] : [], ...findPageFiles(cwd)];
26636
+ const largeCard = /summary_large_image/.test(layout) || pageCards.some((f) => /^twitter-image\b/.test(path12.basename(f))) || readSourceGraph(entries, { maxDepth: 3, maxFiles: 400 }).some((f) => /summary_large_image/.test(f.source));
26376
26637
  return {
26377
26638
  siteCard,
26378
- pageCards: findPageCards(cwd),
26639
+ pageCards,
26379
26640
  layoutDeclaresImages: /images:\s*\[/.test(layout),
26380
- largeCard: /summary_large_image/.test(layout),
26641
+ largeCard,
26381
26642
  referencesImage: /og\.png|opengraph-image|og:image|images:\s*\[/.test(layout),
26382
- layoutFound: !!layoutPath
26643
+ layoutFound: !!layoutPath,
26644
+ trailingSlash: readTrailingSlash(cwd),
26645
+ codeCards: readCodeCards(cwd, pageCards),
26646
+ ...known.managedOgImages && { managedOgImages: known.managedOgImages }
26383
26647
  };
26384
26648
  }
26385
26649
  function judgeOgWiring(facts) {
26386
26650
  const problems = [];
26387
26651
  if (!facts.layoutFound) {
26388
- return [{ message: "no app/layout.tsx found to verify metadata", fix: "Run this from the site root." }];
26652
+ return [
26653
+ {
26654
+ message: "no root layout (app/layout.{tsx,ts,jsx,js} or src/app/layout.*) found to verify metadata",
26655
+ fix: "Run this from the site root."
26656
+ }
26657
+ ];
26389
26658
  }
26390
26659
  if (!facts.siteCard && !facts.pageCards.length) {
26391
26660
  return [
@@ -26402,10 +26671,13 @@ function judgeOgWiring(facts) {
26402
26671
  fix: "Remove the images arrays from the root layout metadata and let Next serve each route its own opengraph-image file."
26403
26672
  });
26404
26673
  }
26405
- problems.push({
26406
- message: "seo_pages.managed_og_image (if set in Sonor) overrides per-page cards the same way",
26407
- fix: "Clear managed_og_image for this project so each page serves its own card."
26408
- });
26674
+ const managed = facts.managedOgImages ?? [];
26675
+ if (managed.length) {
26676
+ problems.push({
26677
+ message: `seo_pages.managed_og_image is set for ${managed.length} page${managed.length === 1 ? "" : "s"} (${managed.slice(0, 5).join(", ")}${managed.length > 5 ? ", \u2026" : ""}), which overrides ${managed.length === 1 ? "its" : "their"} own card`,
26678
+ fix: "Clear managed_og_image on those pages in Sonor so each serves its own card."
26679
+ });
26680
+ }
26409
26681
  } else if (!facts.referencesImage) {
26410
26682
  problems.push({
26411
26683
  message: "card asset exists but layout metadata never references it",
@@ -26418,10 +26690,24 @@ function judgeOgWiring(facts) {
26418
26690
  fix: "Set twitter: { card: 'summary_large_image' } in the root layout metadata."
26419
26691
  });
26420
26692
  }
26693
+ for (const card of facts.codeCards ?? []) {
26694
+ if (card.blogDeclaresImages) {
26695
+ problems.push({
26696
+ message: `${card.route} has its own card (${card.file}), but its page's generateBlogPostMetadata declares the featured image, which beats the card`,
26697
+ fix: "Pass images: false to generateBlogPostMetadata in that page."
26698
+ });
26699
+ }
26700
+ if (facts.trailingSlash && !card.declaresUrl) {
26701
+ problems.push({
26702
+ message: `${card.route}'s card (${card.file}) is served at \u2026/opengraph-image with no extension, which trailingSlash: true 308-redirects`,
26703
+ fix: "Declare the slashed URL from the page's metadata: openGraph.images = [codeCardImage(path)] from @sonordev/site-kit/og. Or, for cards that can be rendered ahead of time, key them in og.config.ts `cards` by URL and use paramCardImage."
26704
+ });
26705
+ }
26706
+ }
26421
26707
  return problems;
26422
26708
  }
26423
- function checkOgWiring(cwd) {
26424
- return judgeOgWiring(readOgWiring(cwd));
26709
+ function checkOgWiring(cwd, known = {}) {
26710
+ return judgeOgWiring(readOgWiring(cwd, known));
26425
26711
  }
26426
26712
 
26427
26713
  // src/cli/agent/ssr-bailout.ts
@@ -26440,26 +26726,6 @@ async function readFileOrNull(p) {
26440
26726
  return null;
26441
26727
  }
26442
26728
  }
26443
- async function findFirst(cwd, candidates) {
26444
- for (const rel of candidates) {
26445
- const full = path12.join(cwd, rel);
26446
- if (await readFileOrNull(full)) return full;
26447
- }
26448
- return null;
26449
- }
26450
- var LAYOUT_CANDIDATES = [
26451
- "app/layout.tsx",
26452
- "app/layout.jsx",
26453
- "src/app/layout.tsx",
26454
- "src/app/layout.jsx"
26455
- ];
26456
- var SITEMAP_CANDIDATES = [
26457
- "app/sitemap.ts",
26458
- "app/sitemap.tsx",
26459
- "app/sitemap.js",
26460
- "src/app/sitemap.ts",
26461
- "src/app/sitemap.tsx"
26462
- ];
26463
26729
  function checkApiKeyEnv() {
26464
26730
  const key = process.env.SONOR_API_KEY;
26465
26731
  if (key && key.startsWith("sonor_")) {
@@ -26546,7 +26812,7 @@ async function checkPackageInstalled(cwd) {
26546
26812
  };
26547
26813
  }
26548
26814
  async function checkSiteKitLayout(cwd) {
26549
- const layoutPath = await findFirst(cwd, LAYOUT_CANDIDATES);
26815
+ const layoutPath = findRootLayout(cwd);
26550
26816
  if (!layoutPath) {
26551
26817
  return {
26552
26818
  id: "layout.sitekit",
@@ -26590,8 +26856,8 @@ async function checkSiteKitLayout(cwd) {
26590
26856
  };
26591
26857
  }
26592
26858
  async function checkSitemap(cwd) {
26593
- const sitemapPath = await findFirst(cwd, SITEMAP_CANDIDATES);
26594
- if (!sitemapPath) {
26859
+ const sitemapRel = findSitemapRoute(cwd);
26860
+ if (!sitemapRel) {
26595
26861
  return {
26596
26862
  id: "sitemap.managed",
26597
26863
  title: "Sitemap",
@@ -26601,7 +26867,7 @@ async function checkSitemap(cwd) {
26601
26867
  fixCommand: "npx sonor-setup scaffold --yes"
26602
26868
  };
26603
26869
  }
26604
- const content = await readFileOrNull(sitemapPath) || "";
26870
+ const content = await readFileOrNull(path12.join(cwd, sitemapRel)) || "";
26605
26871
  if (content.includes("createSitemap") || content.includes("@sonordev/site-kit")) {
26606
26872
  return { id: "sitemap.managed", title: "Sitemap", level: "ok", message: "Using Site-Kit sitemap" };
26607
26873
  }
@@ -26648,6 +26914,90 @@ async function checkPostbuildSitemap(cwd) {
26648
26914
  fix: 'Add "postbuild": "sonor-register-sitemap --auto-discover || true" to package.json scripts.'
26649
26915
  };
26650
26916
  }
26917
+ var TRAILING_SLASH_ON = /\btrailingSlash\s*:\s*true\b/;
26918
+ async function readBuiltSitemaps(cwd) {
26919
+ const appDir = path12.join(cwd, ".next", "server", "app");
26920
+ const single = await readFileOrNull(path12.join(appDir, "sitemap.xml.body"));
26921
+ if (single !== null) return [single];
26922
+ let shards;
26923
+ try {
26924
+ shards = (await fs3.readdir(path12.join(appDir, "sitemap"))).filter((f) => f.endsWith(".xml.body"));
26925
+ } catch {
26926
+ return null;
26927
+ }
26928
+ if (shards.length === 0) return null;
26929
+ const bodies = await Promise.all(shards.map((f) => readFileOrNull(path12.join(appDir, "sitemap", f))));
26930
+ return bodies.filter((b) => b !== null);
26931
+ }
26932
+ function locPath(loc) {
26933
+ try {
26934
+ return new URL(loc).pathname;
26935
+ } catch {
26936
+ return loc;
26937
+ }
26938
+ }
26939
+ async function checkSitemapTrailingSlash(cwd) {
26940
+ const id = "sitemap.trailing-slash";
26941
+ const title = "Sitemap trailing slash";
26942
+ const configRel = findNextConfig(cwd);
26943
+ const config2 = configRel ? await readFileOrNull(path12.join(cwd, configRel)) || "" : "";
26944
+ if (!TRAILING_SLASH_ON.test(config2)) {
26945
+ return { id, title, level: "ok", message: "next.config leaves trailingSlash off" };
26946
+ }
26947
+ const sitemapRel = findSitemapRoute(cwd);
26948
+ const source = sitemapRel ? await readFileOrNull(path12.join(cwd, sitemapRel)) || "" : "";
26949
+ const forcesOff = /\btrailingSlash\s*:\s*false\b/.test(source);
26950
+ const removeForcedOff = `Remove trailingSlash: false from ${sitemapRel}. createSitemap follows next.config.`;
26951
+ const built = await readBuiltSitemaps(cwd);
26952
+ if (built) {
26953
+ const locs = built.flatMap((xml) => [...xml.matchAll(/<loc>\s*([^<\s]+)\s*<\/loc>/g)].map((m) => m[1]));
26954
+ const unslashed = locs.filter((loc) => {
26955
+ const p = locPath(loc);
26956
+ return applyTrailingSlash(p, true) !== p;
26957
+ });
26958
+ if (unslashed.length === 0) {
26959
+ return { id, title, level: "ok", message: `All ${locs.length} URLs in the built sitemap match trailingSlash: true` };
26960
+ }
26961
+ const fix = forcesOff ? removeForcedOff : source.includes("createSitemap") ? "Upgrade @sonordev/site-kit: createSitemap now follows next.config trailingSlash. If it's already current, something loads the kit outside Next's bundler (serverExternalPackages), so pass createSitemap({ trailingSlash: true })." : `End every <loc> except / and files like /llms.txt in "/", or switch ${sitemapRel ?? "the sitemap route"} to createSitemap.`;
26962
+ return {
26963
+ id,
26964
+ title,
26965
+ level: "warn",
26966
+ message: `${unslashed.length} of ${locs.length} built sitemap URLs lack the trailing slash ${configRel} requires`,
26967
+ detail: `Each one 308-redirects. ${unslashed.slice(0, 5).join(", ")}`,
26968
+ fix: `${fix} Then rebuild.`
26969
+ };
26970
+ }
26971
+ if (!sitemapRel) {
26972
+ return { id, title, level: "skip", message: "No sitemap route to check" };
26973
+ }
26974
+ if (forcesOff) {
26975
+ return {
26976
+ id,
26977
+ title,
26978
+ level: "warn",
26979
+ message: `${sitemapRel} passes trailingSlash: false but ${configRel} sets trailingSlash: true`,
26980
+ detail: "Every sitemap URL except / will 308-redirect.",
26981
+ fix: removeForcedOff
26982
+ };
26983
+ }
26984
+ if (source.includes("createSitemap")) {
26985
+ return {
26986
+ id,
26987
+ title,
26988
+ level: "ok",
26989
+ message: "createSitemap follows next.config trailingSlash",
26990
+ detail: "No build to confirm against. Run `next build`, then doctor again to check the emitted URLs."
26991
+ };
26992
+ }
26993
+ return {
26994
+ id,
26995
+ title,
26996
+ level: "skip",
26997
+ message: "Custom sitemap and no build to check",
26998
+ fix: 'Run `next build`, then doctor again. Every <loc> except / and files like /llms.txt must end in "/".'
26999
+ };
27000
+ }
26651
27001
  async function checkApiReachable(timeoutMs = 5e3) {
26652
27002
  const key = process.env.SONOR_API_KEY;
26653
27003
  try {
@@ -26979,8 +27329,7 @@ async function checkSsrRenderFromBuild(cwd) {
26979
27329
  }
26980
27330
  async function checkNetlifyMiddleware(cwd) {
26981
27331
  const runtimeRe = /runtime\s*[:=]\s*['"](nodejs|edge)['"]/;
26982
- const proxyFiles = ["proxy.ts", "proxy.js", "src/proxy.ts", "src/proxy.js"];
26983
- for (const rel of proxyFiles) {
27332
+ for (const rel of NEXT_PROXY_FILES) {
26984
27333
  const content = await readFileOrNull(path12.join(cwd, rel));
26985
27334
  if (content === null) continue;
26986
27335
  if (runtimeRe.test(content)) {
@@ -26996,8 +27345,7 @@ async function checkNetlifyMiddleware(cwd) {
26996
27345
  }
26997
27346
  return { id: "middleware.netlify", title: "Proxy / middleware", level: "ok", message: `${rel} present` };
26998
27347
  }
26999
- const middlewareFiles = ["middleware.ts", "middleware.js", "src/middleware.ts", "src/middleware.js"];
27000
- for (const rel of middlewareFiles) {
27348
+ for (const rel of NEXT_MIDDLEWARE_FILES) {
27001
27349
  const content = await readFileOrNull(path12.join(cwd, rel));
27002
27350
  if (content === null) continue;
27003
27351
  if (/runtime\s*[:=]\s*['"]nodejs['"]/.test(content)) {
@@ -27093,8 +27441,8 @@ async function checkImageDimsDrift(cwd) {
27093
27441
  }
27094
27442
  return { id: "images.dims-drift", title: "Image dims vs SVG", level: "ok", message: "Declared dims match SVG viewBoxes" };
27095
27443
  }
27096
- async function checkOgCard(cwd) {
27097
- const problems = judgeOgWiring(readOgWiring(cwd));
27444
+ async function checkOgCard(cwd, known = {}) {
27445
+ const problems = judgeOgWiring(readOgWiring(cwd, known));
27098
27446
  if (!problems.length) {
27099
27447
  return { id: "og.card", title: "Open Graph card", level: "ok", message: "Cards present and wired" };
27100
27448
  }
@@ -27115,12 +27463,59 @@ async function staticChecks(cwd) {
27115
27463
  await checkSiteKitLayout(cwd),
27116
27464
  await checkSitemap(cwd),
27117
27465
  await checkPostbuildSitemap(cwd),
27466
+ await checkSitemapTrailingSlash(cwd),
27118
27467
  await checkNetlifyMiddleware(cwd),
27119
27468
  await checkImageDimsDrift(cwd),
27120
27469
  await checkOgCard(cwd)
27121
27470
  ];
27122
27471
  }
27123
27472
 
27473
+ // src/og/route-copy.ts
27474
+ var RENDER_CONCURRENCY = 4;
27475
+ async function pooled(items, limit, fn) {
27476
+ const results = new Array(items.length);
27477
+ let cursor = 0;
27478
+ const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
27479
+ while (cursor < items.length) {
27480
+ const i = cursor++;
27481
+ results[i] = await fn(items[i], i);
27482
+ }
27483
+ });
27484
+ await Promise.all(workers);
27485
+ return results;
27486
+ }
27487
+ async function resolveRouteCopy(paths) {
27488
+ let getSEOPageData = null;
27489
+ try {
27490
+ if (process.env.SONOR_API_KEY) {
27491
+ ;
27492
+ ({ getSEOPageData } = await import('../api-D745LGGU.mjs'));
27493
+ }
27494
+ } catch {
27495
+ getSEOPageData = null;
27496
+ }
27497
+ if (!getSEOPageData) return paths.map((p) => ({ path: p }));
27498
+ return pooled(paths, RENDER_CONCURRENCY, async (p) => {
27499
+ try {
27500
+ const page = await getSEOPageData("", p);
27501
+ const title = page?.managed_title ?? page?.managed_og_title;
27502
+ const description = page?.managed_meta_description ?? page?.managed_og_description;
27503
+ const managedOgImage = page?.managed_og_image || void 0;
27504
+ return { path: p, title: title || void 0, description: description || void 0, managedOgImage };
27505
+ } catch {
27506
+ return { path: p };
27507
+ }
27508
+ });
27509
+ }
27510
+ async function readManagedOgImages(cwd) {
27511
+ if (!process.env.SONOR_API_KEY) return void 0;
27512
+ const appDir = findAppDirForDiscovery(cwd);
27513
+ if (!appDir) return void 0;
27514
+ const routes = [...new Set(discoverNextJsRoutes(appDir).map((r) => r.path))];
27515
+ const copy = await resolveRouteCopy(routes);
27516
+ return copy.filter((r) => r.managedOgImage).map((r) => r.path);
27517
+ }
27518
+
27124
27519
  // src/cli/commands/doctor.ts
27125
27520
  function countLevels(checks) {
27126
27521
  return {
@@ -27133,6 +27528,11 @@ function countLevels(checks) {
27133
27528
  async function collectChecks(cwd, online) {
27134
27529
  const checks = await staticChecks(cwd);
27135
27530
  if (online) {
27531
+ const managedOgImages = await readManagedOgImages(cwd).catch(() => void 0);
27532
+ if (managedOgImages) {
27533
+ const i = checks.findIndex((c) => c.id === "og.card");
27534
+ if (i !== -1) checks[i] = await checkOgCard(cwd, { managedOgImages });
27535
+ }
27136
27536
  checks.push(await checkApiReachable(), await checkKeyValid(), await checkLlmsTxt());
27137
27537
  checks.push(...await checkClientAuth());
27138
27538
  }
@@ -27189,87 +27589,7 @@ async function statusCommand(options) {
27189
27589
  const online = options.offline ? false : true;
27190
27590
  await runCommand(ctx, (c) => run2(c, online), renderChecksHuman("Site-Kit Integration Status"));
27191
27591
  }
27192
-
27193
- // src/og/pages.ts
27194
- var DYNAMIC = "*";
27195
- function pathSegments(path29) {
27196
- return path29.split("/").filter(Boolean);
27197
- }
27198
- function stripBrandSuffix(title, brand) {
27199
- const cleaned = title.replace(/\s*[|–—-]\s*[^|–—-]+$/, "").trim();
27200
- if (!cleaned) return title.trim();
27201
- if (brand && cleaned.toLowerCase() === brand.toLowerCase()) return title.trim();
27202
- return cleaned;
27203
- }
27204
- function titleFromPath(path29) {
27205
- const last = pathSegments(path29).filter((s) => s !== DYNAMIC).pop();
27206
- if (!last) return "Home";
27207
- return last.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
27208
- }
27209
- function kickerFromPath(path29, fallback) {
27210
- const parts = pathSegments(path29);
27211
- const section = parts.includes(DYNAMIC) ? parts.filter((s) => s !== DYNAMIC) : parts.slice(0, -1);
27212
- if (!section.length) return fallback;
27213
- return section.join(" / ").replace(/[-_]+/g, " ");
27214
- }
27215
- function clampSubtitle(text, max = 100) {
27216
- if (!text) return void 0;
27217
- const flat = text.replace(/\s+/g, " ").trim();
27218
- if (!flat) return void 0;
27219
- if (flat.length <= max) return flat;
27220
- const sentence = flat.slice(0, max + 1).match(/^.*[.!?](?=\s|$)/)?.[0];
27221
- if (sentence && sentence.length >= 30) return sentence.trim();
27222
- return void 0;
27223
- }
27224
- function kickerIsRedundant(kicker, title) {
27225
- if (!kicker) return false;
27226
- const norm = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
27227
- const k2 = norm(kicker);
27228
- const t = norm(title);
27229
- if (!k2) return true;
27230
- if (t.includes(k2) || k2.includes(t)) return true;
27231
- const titleWords = new Set(t.split(" "));
27232
- return k2.split(" ").every((w) => titleWords.has(w));
27233
- }
27234
- function slugForPath(path29) {
27235
- const segments = pathSegments(path29);
27236
- if (!segments.length) return "home";
27237
- return segments.map((s) => s === DYNAMIC ? "any" : s).join("-").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
27238
- }
27239
- function unmatchedCardKeys(cards, paths) {
27240
- if (!cards) return [];
27241
- const known = new Set(paths.flatMap((p) => [p, slugForPath(p)]));
27242
- return Object.keys(cards).filter((key) => !known.has(key));
27243
- }
27244
- function pageCardConfig(base, route, brand) {
27245
- const override = base.cards?.[route.path] ?? base.cards?.[slugForPath(route.path)];
27246
- const isHome = route.path === "/";
27247
- const derived = isHome ? { ...base, cards: void 0 } : (() => {
27248
- const title = route.title ? stripBrandSuffix(route.title, brand) : titleFromPath(route.path);
27249
- const kicker = kickerFromPath(route.path, base.content.kicker);
27250
- return {
27251
- ...base,
27252
- // `cards` is a build-time instruction, not part of a rendered card.
27253
- cards: void 0,
27254
- content: {
27255
- ...base.content,
27256
- kicker: kickerIsRedundant(kicker, title) ? void 0 : kicker,
27257
- title,
27258
- subtitle: clampSubtitle(route.description) ?? base.content.subtitle
27259
- }
27260
- };
27261
- })();
27262
- if (!override) return derived;
27263
- return {
27264
- ...derived,
27265
- ...override,
27266
- content: { ...derived.content, ...override.content }
27267
- };
27268
- }
27269
-
27270
- // src/cli/commands/og.ts
27271
27592
  var execFileAsync5 = promisify(execFile$1);
27272
- var RENDER_CONCURRENCY = 4;
27273
27593
  var CARD_KEY_FIX = "Key `cards` by route path (`/services/garage`) or slug (`services-garage`). A dynamic route is one `*` per dynamic level \u2014 `/services/*` for `[slug]`, plus a star for each nested `[param]`.";
27274
27594
  var CHROME_CANDIDATES = [
27275
27595
  process.env.SONOR_CHROME_PATH,
@@ -27393,6 +27713,9 @@ async function compressCard(pngPath, cwd) {
27393
27713
  return pngPath;
27394
27714
  }
27395
27715
  }
27716
+ function codeOgImageFile(dir) {
27717
+ return findConventionFile(dir, "opengraph-image") ?? findConventionFile(path12.join(dir, "opengraph-image"), "route");
27718
+ }
27396
27719
  function discoverDynamicSegments(appDir) {
27397
27720
  const found = [];
27398
27721
  const walk = (dir, urlSegments, pattern) => {
@@ -27406,10 +27729,11 @@ function discoverDynamicSegments(appDir) {
27406
27729
  const nextUrl = isGroup || isDynamic ? urlSegments : [...urlSegments, entry.name];
27407
27730
  const nextPattern = isGroup ? pattern : [...pattern, isDynamic ? DYNAMIC : entry.name];
27408
27731
  if (isDynamic) {
27409
- const hasPage = ["tsx", "jsx", "ts", "js"].some((ext2) => existsSync(path12.join(full, `page.${ext2}`)));
27410
- if (hasPage) {
27732
+ if (hasPageFile(full)) {
27411
27733
  found.push({ dir: full, path: `/${nextPattern.join("/")}`, parent: `/${urlSegments.join("/")}` });
27412
27734
  }
27735
+ } else if (!isGroup && nextPattern.includes(DYNAMIC) && hasPageFile(full)) {
27736
+ found.push({ dir: full, path: `/${nextPattern.join("/")}`, parent: null });
27413
27737
  }
27414
27738
  walk(full, nextUrl, nextPattern);
27415
27739
  }
@@ -27417,40 +27741,6 @@ function discoverDynamicSegments(appDir) {
27417
27741
  walk(appDir, [], []);
27418
27742
  return found;
27419
27743
  }
27420
- async function pooled(items, limit, fn) {
27421
- const results = new Array(items.length);
27422
- let cursor = 0;
27423
- const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
27424
- while (cursor < items.length) {
27425
- const i = cursor++;
27426
- results[i] = await fn(items[i], i);
27427
- }
27428
- });
27429
- await Promise.all(workers);
27430
- return results;
27431
- }
27432
- async function resolveRouteCopy(paths) {
27433
- let getSEOPageData = null;
27434
- try {
27435
- if (process.env.SONOR_API_KEY) {
27436
- ;
27437
- ({ getSEOPageData } = await import('../api-D745LGGU.mjs'));
27438
- }
27439
- } catch {
27440
- getSEOPageData = null;
27441
- }
27442
- if (!getSEOPageData) return paths.map((p) => ({ path: p }));
27443
- return pooled(paths, RENDER_CONCURRENCY, async (p) => {
27444
- try {
27445
- const page = await getSEOPageData("", p);
27446
- const title = page?.managed_title ?? page?.managed_og_title;
27447
- const description = page?.managed_meta_description ?? page?.managed_og_description;
27448
- return { path: p, title: title || void 0, description: description || void 0 };
27449
- } catch {
27450
- return { path: p };
27451
- }
27452
- });
27453
- }
27454
27744
  function reportCard(label, report) {
27455
27745
  if (report.fits && !report.issues.length) {
27456
27746
  const shrunk = report.titlePx < TITLE_MAX_PX ? source_default.gray(` (title fitted to ${report.titlePx}px)`) : "";
@@ -27495,6 +27785,7 @@ async function runOg(options) {
27495
27785
  let cardKeyFix = null;
27496
27786
  let pageCardsWritten = 0;
27497
27787
  let totalCardBytes = 0;
27788
+ let managedOgImages;
27498
27789
  const spinner = ora("Rendering the site card...").start();
27499
27790
  try {
27500
27791
  const report = await renderCard(config2, outPath, cwd, chrome, "site");
@@ -27526,6 +27817,9 @@ async function runOg(options) {
27526
27817
  const withCopy = await resolveRouteCopy(routes);
27527
27818
  const named = withCopy.filter((r) => r.title).length;
27528
27819
  copySpinner.stop();
27820
+ if (process.env.SONOR_API_KEY) {
27821
+ managedOgImages = withCopy.filter((r) => r.managedOgImage).map((r) => r.path);
27822
+ }
27529
27823
  if (named) {
27530
27824
  console.log(source_default.gray(` ${named}/${routes.length} titled from Sonor, the rest from the route path`));
27531
27825
  } else {
@@ -27534,11 +27828,13 @@ async function runOg(options) {
27534
27828
  const brand = config2.content.title.replace(/\n/g, " ").trim();
27535
27829
  const copyByPath = new Map(withCopy.map((r) => [r.path, r]));
27536
27830
  const dynamic = discoverDynamicSegments(appDir).map((seg) => ({
27537
- ...copyByPath.get(seg.parent) ?? {},
27831
+ ...seg.parent !== null && copyByPath.get(seg.parent) || {},
27538
27832
  path: seg.path,
27539
27833
  dir: seg.dir
27540
27834
  }));
27541
27835
  const targets = [...withCopy, ...dynamic];
27836
+ const paramKeys = paramCardKeys(config2.cards, targets.map((t) => t.path));
27837
+ const paramRoutes = paramKeys.length ? await resolveRouteCopy(paramKeys.map((k2) => k2.path)) : [];
27542
27838
  const strayKeys = unmatchedCardKeys(config2.cards, targets.map((t) => t.path));
27543
27839
  if (strayKeys.length) {
27544
27840
  const patterns = targets.filter((t) => t.path.includes(DYNAMIC)).map((t) => t.path);
@@ -27560,9 +27856,19 @@ async function runOg(options) {
27560
27856
  });
27561
27857
  cardKeyFix = CARD_KEY_FIX;
27562
27858
  }
27563
- const reports = await pooled(targets, RENDER_CONCURRENCY, async (route, i) => {
27859
+ const placed = targets.map((route) => ({ ...route, dir: route.dir ?? routeOutputDir(appDir, route.path) }));
27860
+ const toRender = placed.filter((route) => !codeOgImageFile(route.dir));
27861
+ for (const route of placed.filter((r) => codeOgImageFile(r.dir))) {
27862
+ for (const ext2 of ["png", "jpg", "jpeg"]) {
27863
+ await fs3.rm(path12.join(route.dir, `opengraph-image.${ext2}`), { force: true });
27864
+ }
27865
+ const file = path12.relative(cwd, codeOgImageFile(route.dir));
27866
+ console.log(source_default.gray(` \u21B7 ${route.path} keeps its own ${file}`));
27867
+ checks.push({ id: "og.code-card", title: route.path, level: "ok", message: `Code-based card kept: ${file}` });
27868
+ }
27869
+ const reports = await pooled(toRender, RENDER_CONCURRENCY, async (route, i) => {
27564
27870
  const pageConfig = pageCardConfig(config2, route, brand);
27565
- const dir = route.dir ?? routeOutputDir(appDir, route.path);
27871
+ const dir = route.dir;
27566
27872
  for (const ext2 of ["png", "jpg", "jpeg"]) {
27567
27873
  await fs3.rm(path12.join(dir, `opengraph-image.${ext2}`), { force: true });
27568
27874
  }
@@ -27575,10 +27881,36 @@ async function runOg(options) {
27575
27881
  clean = reportCard(`${route.path} ${source_default.gray(path12.relative(cwd, file))}`, report) && clean;
27576
27882
  checks.push(cardCheck(route.path, path12.relative(cwd, file), report));
27577
27883
  }
27578
- pageCardsWritten = reports.length;
27579
- const bytes = await totalBytes(reports.map((r) => r.file));
27884
+ const paramDir = path12.join(cwd, "public", PARAM_CARD_DIR);
27885
+ await fs3.rm(paramDir, { recursive: true, force: true });
27886
+ let paramReports = [];
27887
+ if (paramRoutes.length) {
27888
+ console.log("");
27889
+ console.log(source_default.bold(" Per-URL cards") + source_default.gray(` public/${PARAM_CARD_DIR}/, declare with paramCardImage()`));
27890
+ paramReports = await pooled(paramRoutes, RENDER_CONCURRENCY, async (route, i) => {
27891
+ const pageConfig = pageCardConfig(config2, route, brand);
27892
+ const jpg = path12.join(cwd, "public", paramCardUrl(route.path));
27893
+ const png = jpg.replace(/\.jpg$/, ".png");
27894
+ const report = await renderCard(pageConfig, png, cwd, chrome, `param-${i}`);
27895
+ const file = await compressCard(png, cwd);
27896
+ if (file !== jpg) {
27897
+ report.fits = false;
27898
+ report.issues = [...report.issues, "sharp is needed to write per-URL cards as .jpg. Add it: pnpm add -D sharp"];
27899
+ }
27900
+ return { route, file, report };
27901
+ });
27902
+ for (const { route, file, report } of paramReports) {
27903
+ clean = reportCard(`${route.path} ${source_default.gray(path12.relative(cwd, file))}`, report) && clean;
27904
+ checks.push(cardCheck(route.path, path12.relative(cwd, file), report));
27905
+ }
27906
+ }
27907
+ pageCardsWritten = reports.length + paramReports.length;
27908
+ const bytes = await totalBytes([...reports, ...paramReports].map((r) => r.file));
27580
27909
  totalCardBytes = bytes;
27581
- console.log(source_default.gray(` ${(bytes / 1024 / 1024).toFixed(1)} MB of cards. Next serves these automatically \u2014 no per-page metadata needed.`));
27910
+ console.log(source_default.gray(` ${(bytes / 1024 / 1024).toFixed(1)} MB of cards. Next serves the route cards automatically \u2014 no per-page metadata needed.`));
27911
+ if (paramReports.length) {
27912
+ console.log(source_default.gray(" Per-URL cards need the page to declare them: openGraph.images = [paramCardImage(path, { config })]."));
27913
+ }
27582
27914
  }
27583
27915
  }
27584
27916
  }
@@ -27595,7 +27927,7 @@ async function runOg(options) {
27595
27927
  console.log(source_default.gray(" (sharp not resolvable \u2014 skipped the 300px preview)"));
27596
27928
  }
27597
27929
  }
27598
- const problems = checkOgWiring(cwd);
27930
+ const problems = checkOgWiring(cwd, { managedOgImages });
27599
27931
  console.log("");
27600
27932
  if (problems.length) {
27601
27933
  console.log(source_default.yellow(" Metadata wiring:"));
@@ -27797,14 +28129,14 @@ var hs = new RegExp(pe, "g");
27797
28129
  var as = /\\\\/g;
27798
28130
  var ls = /\\{/g;
27799
28131
  var cs = /\\}/g;
27800
- var fs22 = /\\,/g;
28132
+ var fs23 = /\\,/g;
27801
28133
  var us = /\\./g;
27802
28134
  var ds = 1e5;
27803
28135
  function Ht(n5) {
27804
28136
  return isNaN(n5) ? n5.charCodeAt(0) : parseInt(n5, 10);
27805
28137
  }
27806
28138
  function ps(n5) {
27807
- return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs22, de).replace(us, pe);
28139
+ return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs23, de).replace(us, pe);
27808
28140
  }
27809
28141
  function ms(n5) {
27810
28142
  return n5.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(os5, ",").replace(hs, ".");
@@ -29425,8 +29757,8 @@ var V = class extends EventEmitter {
29425
29757
  }
29426
29758
  };
29427
29759
  var vi = realpathSync.native;
29428
- var wt = { lstatSync: lstatSync, readdir: readdir$1, readdirSync: readdirSync, readlinkSync: readlinkSync, realpathSync: vi, promises: { lstat: lstat, readdir: readdir, readlink: readlink, realpath: realpath } };
29429
- var Ue = (n5) => !n5 || n5 === wt || n5 === fs ? wt : { ...wt, ...n5, promises: { ...wt.promises, ...n5.promises || {} } };
29760
+ var wt = { lstatSync: lstatSync, readdir: readdir$1, readdirSync: readdirSync, readlinkSync: readlinkSync, realpathSync: vi, promises: { lstat: lstat, readdir: readdir, readlink: readlink, realpath: realpath$1 } };
29761
+ var Ue = (n5) => !n5 || n5 === wt || n5 === fs20 ? wt : { ...wt, ...n5, promises: { ...wt.promises, ...n5.promises || {} } };
29430
29762
  var $e = /^\\\\\?\\([a-z]:)\\?$/i;
29431
29763
  var Ri = (n5) => n5.replace(/\//g, "\\").replace($e, "$1\\");
29432
29764
  var Oi = /[\\\/]/;
@@ -31155,7 +31487,7 @@ function findManifestPath() {
31155
31487
  let dir = baseDir;
31156
31488
  for (let i = 0; i < 8; i++) {
31157
31489
  const candidate = path12.join(dir, "agent-manifest.json");
31158
- if (fs__default.existsSync(candidate)) return candidate;
31490
+ if (fs20__default.existsSync(candidate)) return candidate;
31159
31491
  const parent = path12.dirname(dir);
31160
31492
  if (parent === dir) break;
31161
31493
  dir = parent;
@@ -31171,7 +31503,7 @@ async function run5(ctx, options) {
31171
31503
  "Reinstall @sonordev/site-kit, or run `npm run build` if working from source."
31172
31504
  );
31173
31505
  }
31174
- const manifest = JSON.parse(fs__default.readFileSync(manifestPath, "utf-8"));
31506
+ const manifest = JSON.parse(fs20__default.readFileSync(manifestPath, "utf-8"));
31175
31507
  if (options.section) {
31176
31508
  const section = options.section;
31177
31509
  if (!(section in manifest)) {
@@ -31235,7 +31567,7 @@ async function syncCommand2(options) {
31235
31567
  }
31236
31568
  async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
31237
31569
  const spinner = ora("Discovering pages...").start();
31238
- const appDir = findAppDir();
31570
+ const appDir = findAppDirForDiscovery();
31239
31571
  if (!appDir) {
31240
31572
  spinner.fail("Could not find app directory");
31241
31573
  return;
@@ -31296,18 +31628,6 @@ async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
31296
31628
  syncSpinner.fail(`Sync failed: ${error2.message}`);
31297
31629
  }
31298
31630
  }
31299
- function findAppDir() {
31300
- const candidates = [
31301
- path12.join(process.cwd(), "app"),
31302
- path12.join(process.cwd(), "src", "app")
31303
- ];
31304
- for (const candidate of candidates) {
31305
- if (existsSync(candidate)) {
31306
- return candidate;
31307
- }
31308
- }
31309
- return null;
31310
- }
31311
31631
  function discoverPages(appDir, currentPath = "", pages = []) {
31312
31632
  const fullPath = path12.join(appDir, currentPath);
31313
31633
  if (!existsSync(fullPath)) {
@@ -31607,7 +31927,7 @@ async function discoverSchemaUsage(appDir) {
31607
31927
  return usages;
31608
31928
  }
31609
31929
  async function syncSchemasToPortal(apiUrl, apiKey, dryRun) {
31610
- const appDir = findAppDir();
31930
+ const appDir = findAppDirForDiscovery();
31611
31931
  if (!appDir) {
31612
31932
  console.log(source_default.gray(" No app directory found"));
31613
31933
  return;
@@ -31650,7 +31970,7 @@ async function apiRoutesCommand(options) {
31650
31970
  console.log("");
31651
31971
  console.log(source_default.bold(" Site-Kit API Routes"));
31652
31972
  console.log("");
31653
- const appDir = findAppDir2();
31973
+ const appDir = findAppDirForDiscovery();
31654
31974
  if (!appDir) {
31655
31975
  console.log(source_default.red(" \u2717 Could not find app directory"));
31656
31976
  console.log(source_default.gray(" Make sure you are in a Next.js project with an app directory"));
@@ -31693,18 +32013,6 @@ async function apiRoutesCommand(options) {
31693
32013
  spinner.fail(`Failed to create API routes: ${error2.message}`);
31694
32014
  }
31695
32015
  }
31696
- function findAppDir2() {
31697
- const candidates = [
31698
- path12.join(process.cwd(), "app"),
31699
- path12.join(process.cwd(), "src", "app")
31700
- ];
31701
- for (const candidate of candidates) {
31702
- if (existsSync(candidate)) {
31703
- return candidate;
31704
- }
31705
- }
31706
- return null;
31707
- }
31708
32016
  function generateRouteHandler() {
31709
32017
  return `/**
31710
32018
  * Sonor API Proxy
@@ -31919,7 +32227,7 @@ async function scaffoldCommand(options) {
31919
32227
  );
31920
32228
  console.log("");
31921
32229
  const cwd = process.cwd();
31922
- const appDir = await findAppDir3();
32230
+ const appDir = findAppDirForDiscovery(cwd);
31923
32231
  if (!appDir) {
31924
32232
  console.log(source_default.red(" \u2717 No app directory found (app/ or src/app/)"));
31925
32233
  process.exit(1);
@@ -31932,8 +32240,8 @@ async function scaffoldCommand(options) {
31932
32240
 
31933
32241
  export default createSitemap({
31934
32242
  // baseUrl auto-resolved from Portal via API key
31935
- includeLlmsTxtInSitemap: true,
31936
- includeLlmsFullTxtInSitemap: true,
32243
+ // llms.txt stays out of the sitemap on purpose: it's a plain-text duplicate
32244
+ // of these pages, and AI crawlers find it at /llms.txt anyway.
31937
32245
  // optimizedLLMsTxt: true, // optional: static build writes optimized llms (CI)
31938
32246
  // llmsPublicSummaryOnly: true, // optional: page list from Portal public summaries only
31939
32247
  // additionalPaths: async () => [...],
@@ -31969,13 +32277,13 @@ export const GET = createLLMsFullTxtHandler({ preferStatic: true })
31969
32277
  files.push(
31970
32278
  {
31971
32279
  path: path12.join(cwd, "proxy.ts"),
31972
- label: "Proxy (security headers; redirects resolve at the 404 boundary)",
32280
+ label: "Proxy (security headers, managed redirects)",
31973
32281
  content: `import { createProxy } from '@sonordev/site-kit/proxy'
31974
32282
 
31975
- // redirects: false \u2014 managed redirects resolve in app/not-found.tsx via
31976
- // resolveManagedRedirect() instead of on every request. The proxy still
31977
- // stamps x-sk-path so the 404 boundary knows the requested URL.
31978
- export default createProxy({ redirects: false })
32283
+ // Sonor-managed redirects apply here. The rule list is cached in memory for
32284
+ // five minutes, so page loads rarely wait on it. Don't move them into
32285
+ // app/not-found.tsx: reading request headers there makes every page dynamic.
32286
+ export default createProxy({ redirects: true })
31979
32287
 
31980
32288
  // Inlined on purpose: Next statically parses \`config.matcher\` at build time
31981
32289
  // and rejects an imported value (Turbopack build error). Keep in sync with
@@ -31997,18 +32305,11 @@ export const GET = createManifest()
31997
32305
  },
31998
32306
  {
31999
32307
  path: path12.join(appDir, "not-found.tsx"),
32000
- label: "404 Page (resolves managed redirects)",
32001
- content: `import { redirect, permanentRedirect } from 'next/navigation'
32002
- import { resolveManagedRedirect } from '@sonordev/site-kit/redirects/not-found'
32003
-
32004
- export default async function NotFound() {
32005
- // Sonor-managed redirects resolve here, at the only place they can matter:
32006
- // a URL that would otherwise 404. Successful page loads pay nothing.
32007
- const managed = await resolveManagedRedirect()
32008
- if (managed) {
32009
- ;(managed.permanent ? permanentRedirect : redirect)(managed.destination)
32010
- }
32011
-
32308
+ label: "404 Page",
32309
+ content: `// Keep this component free of request APIs (headers, cookies). Next
32310
+ // renders the root 404 inside every page, so one headers() call here makes
32311
+ // the whole site dynamic. Managed redirects run in proxy.ts instead.
32312
+ export default function NotFound() {
32012
32313
  return (
32013
32314
  <div style={{ textAlign: 'center', padding: '4rem 1rem' }}>
32014
32315
  <h1 style={{ fontSize: '3rem', fontWeight: 700, marginBottom: '0.5rem' }}>404</h1>
@@ -32128,9 +32429,9 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
32128
32429
  console.log(source_default.yellow(" [DRY RUN] Would create:"));
32129
32430
  for (const f of files) {
32130
32431
  const rel = path12.relative(cwd, f.path);
32131
- const exists = existsSync(f.path);
32432
+ const exists2 = existsSync(f.path);
32132
32433
  console.log(
32133
- source_default.gray(` ${rel}`) + (exists ? source_default.yellow(" (exists, would skip)") : "")
32434
+ source_default.gray(` ${rel}`) + (exists2 ? source_default.yellow(" (exists, would skip)") : "")
32134
32435
  );
32135
32436
  }
32136
32437
  console.log("");
@@ -32194,17 +32495,217 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
32194
32495
  console.log("");
32195
32496
  }
32196
32497
  }
32197
- async function findAppDir3() {
32198
- const cwd = process.cwd();
32199
- const candidates = [
32200
- path12.join(cwd, "app"),
32201
- path12.join(cwd, "src", "app")
32202
- ];
32203
- for (const dir of candidates) {
32204
- if (existsSync(dir)) return dir;
32498
+ var LLMS_FILES = [
32499
+ { path: "/llms.txt", handler: "createLLMsTxtHandler" },
32500
+ { path: "/llms-full.txt", handler: "createLLMsFullTxtHandler" }
32501
+ ];
32502
+ function read(cwd, rel) {
32503
+ try {
32504
+ return fs20__default.readFileSync(path12.join(cwd, rel), "utf-8");
32505
+ } catch {
32506
+ return "";
32205
32507
  }
32508
+ }
32509
+ function exists(cwd, rel) {
32510
+ try {
32511
+ return fs20__default.existsSync(path12.join(cwd, rel));
32512
+ } catch {
32513
+ return false;
32514
+ }
32515
+ }
32516
+ function patternMatches(pattern, urlPath) {
32517
+ const re2 = pattern.trim().split(/\(\.\*\)|:\w+\*|\*/).map((part) => part.replace(/[.+?^${}()|[\]\\]/g, "\\$&")).join(".*");
32518
+ return new RegExp(`^${re2}$`).test(urlPath);
32519
+ }
32520
+ var NOINDEX = /noindex/i;
32521
+ function netlifyTomlNoindex(toml, urlPath) {
32522
+ const blocks = [];
32523
+ for (const line of toml.split("\n")) {
32524
+ const header = line.match(/^\s*\[\[?\s*([^\]]+?)\s*\]\]?\s*$/);
32525
+ if (header && header[1] !== "headers.values") blocks.push(line);
32526
+ else if (blocks.length) blocks[blocks.length - 1] += `
32527
+ ${line}`;
32528
+ }
32529
+ return blocks.some((block) => {
32530
+ if (!/^\s*\[\[\s*headers\s*\]\]/.test(block)) return false;
32531
+ const pattern = block.match(/^\s*for\s*=\s*["']([^"']+)["']/m)?.[1];
32532
+ const value = block.match(/^\s*["']?X-Robots-Tag["']?\s*=\s*["']([^"']*)["']/im)?.[1];
32533
+ return !!pattern && !!value && NOINDEX.test(value) && patternMatches(pattern, urlPath);
32534
+ });
32535
+ }
32536
+ function headersFileNoindex(text, urlPath) {
32537
+ let current = null;
32538
+ for (const line of text.split("\n")) {
32539
+ if (!line.trim() || line.trim().startsWith("#")) continue;
32540
+ if (!/^\s/.test(line)) {
32541
+ current = line.trim();
32542
+ continue;
32543
+ }
32544
+ const m = line.match(/^\s+X-Robots-Tag\s*:\s*(.+)$/i);
32545
+ if (current && m && NOINDEX.test(m[1]) && patternMatches(current, urlPath)) return true;
32546
+ }
32547
+ return false;
32548
+ }
32549
+ function vercelJsonNoindex(text, urlPath) {
32550
+ try {
32551
+ const json = JSON.parse(text);
32552
+ return (json.headers ?? []).some(
32553
+ (rule) => !!rule.source && patternMatches(rule.source, urlPath) && (rule.headers ?? []).some((h) => /^x-robots-tag$/i.test(h.key ?? "") && NOINDEX.test(h.value ?? ""))
32554
+ );
32555
+ } catch {
32556
+ return false;
32557
+ }
32558
+ }
32559
+ function findHostNoindex(cwd, urlPath) {
32560
+ const toml = read(cwd, "netlify.toml");
32561
+ if (toml && netlifyTomlNoindex(toml, urlPath)) return "netlify.toml";
32562
+ const headers = read(cwd, "public/_headers");
32563
+ if (headers && headersFileNoindex(headers, urlPath)) return "public/_headers";
32564
+ const vercel = read(cwd, "vercel.json");
32565
+ if (vercel && vercelJsonNoindex(vercel, urlPath)) return "vercel.json";
32206
32566
  return null;
32207
32567
  }
32568
+ function readGraph(cwd, rel) {
32569
+ return exists(cwd, rel) ? readWithImports(cwd, rel, { maxDepth: 3, maxFiles: 60 }) : "";
32570
+ }
32571
+ var LINK_DISCOVERY_LINE = /^.*\bLink\b.*(llms[^\n]*describedby|describedby[^\n]*llms).*$/im;
32572
+ function findDiscoverySource(cwd) {
32573
+ for (const rel of findProxyFiles(cwd)) {
32574
+ const src = readGraph(cwd, rel);
32575
+ const viaFactory = /\bcreate(Proxy|Middleware)\s*\(/.test(src) && /\bllmsDiscovery\b(?!\s*:\s*false\b)/.test(src);
32576
+ if (viaFactory) return `${rel} (createProxy llmsDiscovery)`;
32577
+ if (src.includes("buildAiDiscoveryHeaders")) return `${rel} (buildAiDiscoveryHeaders)`;
32578
+ }
32579
+ const nextConfig = findNextConfig(cwd);
32580
+ if (nextConfig) {
32581
+ const src = read(cwd, nextConfig);
32582
+ if (/\bllmsTxtDiscoveryLink\s*:(?!\s*false\b)/.test(src)) return `${nextConfig} (llmsTxtDiscoveryLink)`;
32583
+ if (src.includes("buildAiDiscoveryHeaders")) return `${nextConfig} (buildAiDiscoveryHeaders)`;
32584
+ }
32585
+ for (const rel of ["netlify.toml", "public/_headers"]) {
32586
+ if (LINK_DISCOVERY_LINE.test(read(cwd, rel))) return rel;
32587
+ }
32588
+ return null;
32589
+ }
32590
+ function findLayoutHeadersAttempt(cwd) {
32591
+ const layout = findRootLayout(cwd);
32592
+ if (!layout) return null;
32593
+ const src = read(cwd, path12.relative(cwd, layout));
32594
+ return src.includes("buildAiDiscoveryHeaders") || /\bexport\s+(async\s+)?function\s+headers\b/.test(src) ? path12.relative(cwd, layout) : null;
32595
+ }
32596
+ function readGeoWiring(cwd) {
32597
+ const appDir = NEXT_APP_DIRS.find((rel) => exists(cwd, rel)) ?? null;
32598
+ const sitemap = findSitemapRoute(cwd);
32599
+ const sitemapSrc = sitemap ? readGraph(cwd, sitemap) : "";
32600
+ const sitemapListsLlms = /\bincludeLlms(Full)?TxtInSitemap\s*:\s*true\b/.test(sitemapSrc) || /['"`/]llms(-full)?\.txt['"`]/.test(sitemapSrc);
32601
+ const sitemapWritesStatic = /\bcreateSitemap\s*\(/.test(sitemapSrc);
32602
+ const writesLlms = sitemapWritesStatic && !/\boptimizedLLMsTxt\s*:\s*false\b/.test(sitemapSrc);
32603
+ const writesLlmsFull = writesLlms && /\boptimizedLLMsFullTxt\s*:\s*true\b/.test(sitemapSrc);
32604
+ const llms = LLMS_FILES.map(({ path: urlPath, handler }) => {
32605
+ const file = urlPath.slice(1);
32606
+ const routeAbs = appDir ? findConventionFile(path12.join(cwd, appDir, file), "route") : null;
32607
+ const route = routeAbs ? path12.relative(cwd, routeAbs) : null;
32608
+ const routeSrc = route ? readGraph(cwd, route) : "";
32609
+ const publicFile = exists(cwd, path12.join("public", file));
32610
+ const built = urlPath === "/llms.txt" ? writesLlms : writesLlmsFull;
32611
+ return {
32612
+ path: urlPath,
32613
+ route,
32614
+ routeUsesKitHandler: routeSrc.includes(handler),
32615
+ routeOptsOutOfNoindex: /\bnoindex\s*:\s*false\b/.test(routeSrc),
32616
+ routeSetsNoindex: /X-Robots-Tag/i.test(routeSrc) && NOINDEX.test(routeSrc),
32617
+ servedStatic: publicFile || built,
32618
+ staticReason: publicFile ? `public/${file}` : built ? `public/${file} (written by createSitemap at build)` : null,
32619
+ hostNoindex: findHostNoindex(cwd, urlPath)
32620
+ };
32621
+ });
32622
+ const discovery = findDiscoverySource(cwd);
32623
+ return {
32624
+ appDir,
32625
+ llms,
32626
+ sitemap,
32627
+ sitemapListsLlms,
32628
+ discovery,
32629
+ layoutHeadersAttempt: discovery ? null : findLayoutHeadersAttempt(cwd)
32630
+ };
32631
+ }
32632
+ var DISCOVERY_FIX = "Add llmsDiscovery to the proxy: createProxy({ llmsDiscovery: { siteUrl } }) in proxy.ts. Or withSiteKitConfig({ llmsTxtDiscoveryLink: true }) in next.config.";
32633
+ var SITEMAP_FIX = "Drop includeLlmsTxtInSitemap / includeLlmsFullTxtInSitemap (and any hand-added /llms*.txt entry) from the sitemap. A sitemap lists indexable HTML pages; AI crawlers find llms.txt at /llms.txt.";
32634
+ function hostNoindexFix(urlPath) {
32635
+ return `The CDN serves it before any route handler runs, so set the header in host config. netlify.toml: [[headers]] for = "${urlPath}" [headers.values] X-Robots-Tag = "noindex"`;
32636
+ }
32637
+ function judgeGeoWiring(facts) {
32638
+ const rows = [];
32639
+ for (const f of facts.llms) {
32640
+ const name = f.path.slice(1);
32641
+ const id = f.path === "/llms.txt" ? "llms" : "llms-full";
32642
+ const served = !!f.route || f.servedStatic;
32643
+ rows.push(
32644
+ served ? { id: `${id}.served`, label: `${name} served`, level: "ok", detail: f.route ?? f.staticReason ?? void 0 } : {
32645
+ id: `${id}.served`,
32646
+ label: `${name} served`,
32647
+ level: "fail",
32648
+ detail: `no ${facts.appDir ?? "app"}/${name}/route.* and no public/${name}`,
32649
+ fix: "Run: sonor-setup geo --ensure-routes"
32650
+ }
32651
+ );
32652
+ }
32653
+ if (!facts.sitemap) {
32654
+ rows.push({ id: "geo.sitemap", label: "sitemap leaves llms files out", level: "info", detail: "no sitemap route to check" });
32655
+ } else if (facts.sitemapListsLlms) {
32656
+ rows.push({
32657
+ id: "geo.sitemap",
32658
+ label: "sitemap leaves llms files out",
32659
+ level: "warn",
32660
+ detail: `${facts.sitemap} lists /llms.txt, inviting search engines to index a thin plain-text duplicate`,
32661
+ fix: SITEMAP_FIX
32662
+ });
32663
+ } else {
32664
+ rows.push({ id: "geo.sitemap", label: "sitemap leaves llms files out", level: "ok", detail: facts.sitemap });
32665
+ }
32666
+ rows.push(
32667
+ facts.discovery ? { id: "geo.discovery", label: 'discovery header (Link rel="describedby")', level: "ok", detail: facts.discovery } : {
32668
+ id: "geo.discovery",
32669
+ label: 'discovery header (Link rel="describedby")',
32670
+ level: "fail",
32671
+ detail: facts.layoutHeadersAttempt ? `${facts.layoutHeadersAttempt} exports headers(), which is a next.config API: from a layout it's never called and sends nothing` : "not wired in proxy, next.config, or host config",
32672
+ fix: DISCOVERY_FIX
32673
+ }
32674
+ );
32675
+ for (const f of facts.llms) {
32676
+ if (!f.route && !f.servedStatic) continue;
32677
+ const name = f.path.slice(1);
32678
+ const id = `${f.path === "/llms.txt" ? "llms" : "llms-full"}.noindex`;
32679
+ const label = `${name} sends X-Robots-Tag: noindex`;
32680
+ if (f.servedStatic) {
32681
+ rows.push(
32682
+ f.hostNoindex ? { id, label, level: "ok", detail: f.hostNoindex } : { id, label, level: "warn", detail: `${f.staticReason} is served without it`, fix: hostNoindexFix(f.path) }
32683
+ );
32684
+ continue;
32685
+ }
32686
+ if (f.hostNoindex) {
32687
+ rows.push({ id, label, level: "ok", detail: f.hostNoindex });
32688
+ } else if (f.routeUsesKitHandler && !f.routeOptsOutOfNoindex) {
32689
+ rows.push({ id, label, level: "ok", detail: `${f.route} (site-kit handler default)` });
32690
+ } else if (f.routeSetsNoindex) {
32691
+ rows.push({ id, label, level: "ok", detail: f.route });
32692
+ } else {
32693
+ rows.push({
32694
+ id,
32695
+ label,
32696
+ level: "warn",
32697
+ detail: f.routeOptsOutOfNoindex ? `${f.route} passes noindex: false` : `${f.route} doesn't set it`,
32698
+ fix: f.routeOptsOutOfNoindex ? "Drop noindex: false unless you want llms.txt in search results." : "Serve it with createLLMsTxtHandler (sends the header by default), or add X-Robots-Tag: noindex to the response."
32699
+ });
32700
+ }
32701
+ }
32702
+ return rows;
32703
+ }
32704
+ function checkGeoWiring(cwd) {
32705
+ return judgeGeoWiring(readGeoWiring(cwd));
32706
+ }
32707
+
32708
+ // src/cli/commands/geo.ts
32208
32709
  var LLMS_ROUTE = `import { createLLMsTxtHandler } from '@sonordev/site-kit/llms'
32209
32710
 
32210
32711
  export const GET = createLLMsTxtHandler({ preferStatic: true })
@@ -32213,40 +32714,36 @@ var LLMS_FULL_ROUTE = `import { createLLMsFullTxtHandler } from '@sonordev/site-
32213
32714
 
32214
32715
  export const GET = createLLMsFullTxtHandler({ preferStatic: true })
32215
32716
  `;
32216
- async function readIfExists(p) {
32217
- if (!existsSync(p)) return "";
32218
- try {
32219
- return await fs3.readFile(p, "utf-8");
32220
- } catch {
32221
- return "";
32222
- }
32223
- }
32717
+ var ICON = {
32718
+ ok: source_default.green(" \u2713 "),
32719
+ info: source_default.gray(" \xB7 "),
32720
+ warn: source_default.yellow(" ! "),
32721
+ fail: source_default.red(" \u2717 ")
32722
+ };
32224
32723
  async function ensureLlmsRouteFiles(appDir, dryRun) {
32225
- const llms = path12.join(appDir, "llms.txt", "route.ts");
32226
- const llmsFull = path12.join(appDir, "llms-full.txt", "route.ts");
32227
32724
  let n5 = 0;
32228
32725
  if (dryRun) return 0;
32229
- if (!existsSync(llms)) {
32230
- await fs3.mkdir(path12.dirname(llms), { recursive: true });
32231
- await fs3.writeFile(llms, LLMS_ROUTE, "utf-8");
32232
- n5++;
32233
- }
32234
- if (!existsSync(llmsFull)) {
32235
- await fs3.mkdir(path12.dirname(llmsFull), { recursive: true });
32236
- await fs3.writeFile(llmsFull, LLMS_FULL_ROUTE, "utf-8");
32726
+ for (const [dir, source] of [
32727
+ ["llms.txt", LLMS_ROUTE],
32728
+ ["llms-full.txt", LLMS_FULL_ROUTE]
32729
+ ]) {
32730
+ if (findConventionFile(path12.join(appDir, dir), "route")) continue;
32731
+ const file = path12.join(appDir, dir, "route.ts");
32732
+ await fs3.mkdir(path12.dirname(file), { recursive: true });
32733
+ await fs3.writeFile(file, source, "utf-8");
32237
32734
  n5++;
32238
32735
  }
32239
32736
  return n5;
32240
32737
  }
32241
32738
  async function geoCommand(options) {
32242
32739
  if (options.forInstall) {
32243
- const appDir2 = await findAppDir3();
32740
+ const appDir2 = findAppDirForDiscovery();
32244
32741
  if (!appDir2) return;
32245
32742
  const created = await ensureLlmsRouteFiles(appDir2, options.dryRun);
32246
32743
  if (created > 0) {
32247
32744
  console.log(
32248
32745
  source_default.cyan(
32249
- `[@sonordev/site-kit] Created ${created} llms route file(s). Set NEXT_PUBLIC_SITE_URL, use createSitemap({ includeLlmsTxtInSitemap: true }), and withSiteKitConfig({ llmsTxtDiscoveryLink: true }) when ready.`
32746
+ `[@sonordev/site-kit] Created ${created} llms route file(s). Set NEXT_PUBLIC_SITE_URL and add createProxy({ llmsDiscovery: { siteUrl } }) to proxy.ts when ready.`
32250
32747
  )
32251
32748
  );
32252
32749
  }
@@ -32261,59 +32758,20 @@ async function geoCommand(options) {
32261
32758
  )
32262
32759
  );
32263
32760
  console.log("");
32264
- const appDir = await findAppDir3();
32761
+ const appDir = findAppDirForDiscovery();
32265
32762
  if (!appDir) {
32266
32763
  console.log(source_default.red(" \u2717 No app directory (app/ or src/app/)"));
32267
32764
  process.exit(1);
32268
32765
  }
32269
- const llms = path12.join(appDir, "llms.txt", "route.ts");
32270
- const llmsFull = path12.join(appDir, "llms-full.txt", "route.ts");
32271
- const sitemap = path12.join(appDir, "sitemap.ts");
32272
32766
  let allOk = true;
32273
- const row = (label, pass) => {
32274
- if (!pass) allOk = false;
32275
- console.log(
32276
- (pass ? source_default.green(" \u2713 ") : source_default.red(" \u2717 ")) + label
32277
- );
32278
- };
32279
- row("llms.txt route", existsSync(llms));
32280
- row("llms-full.txt route", existsSync(llmsFull));
32281
- let sitemapHasLlms = false;
32282
- if (existsSync(sitemap)) {
32283
- const txt = await readIfExists(sitemap);
32284
- sitemapHasLlms = txt.includes("includeLlmsTxtInSitemap") || txt.includes("includeLlmsFullTxtInSitemap");
32285
- row("sitemap.ts lists llms URLs", sitemapHasLlms);
32286
- } else {
32287
- row("sitemap.ts lists llms URLs", false);
32288
- }
32289
- const nextConfigs = [
32290
- path12.join(cwd, "next.config.ts"),
32291
- path12.join(cwd, "next.config.mjs"),
32292
- path12.join(cwd, "next.config.js")
32293
- ];
32294
- let nextCfg = "";
32295
- for (const p of nextConfigs) {
32296
- if (existsSync(p)) {
32297
- nextCfg = await readIfExists(p);
32298
- break;
32767
+ for (const row of checkGeoWiring(cwd)) {
32768
+ if (row.level === "fail") allOk = false;
32769
+ const detail = row.detail ? source_default.gray(` ${row.detail}`) : "";
32770
+ console.log(`${ICON[row.level]}${row.label}${detail}`);
32771
+ if (row.fix && (row.level === "fail" || row.level === "warn")) {
32772
+ console.log(source_default.gray(` ${row.fix}`));
32299
32773
  }
32300
32774
  }
32301
- const layoutCandidates = [
32302
- path12.join(appDir, "layout.tsx"),
32303
- path12.join(appDir, "layout.jsx"),
32304
- path12.join(appDir, "layout.js")
32305
- ];
32306
- let layoutTxt = "";
32307
- for (const p of layoutCandidates) {
32308
- layoutTxt = await readIfExists(p);
32309
- if (layoutTxt) break;
32310
- }
32311
- const hasLayoutDiscovery = layoutTxt.includes("buildAiDiscoveryHeaders") || layoutTxt.includes("llmsTxtDiscoveryLink");
32312
- const hasConfigDiscovery = nextCfg.includes("llmsTxtDiscoveryLink");
32313
- row(
32314
- "discovery header (next.config or root layout)",
32315
- hasConfigDiscovery || hasLayoutDiscovery
32316
- );
32317
32775
  const siteUrl = process.env.NEXT_PUBLIC_SITE_URL?.trim() || process.env.SITE_BASE_URL?.trim() || (process.env.VERCEL_URL?.trim() ? `https://${process.env.VERCEL_URL.replace(/\/$/, "")}` : "");
32318
32776
  if (siteUrl) {
32319
32777
  console.log(source_default.gray(` Public origin (env): ${siteUrl}`));
@@ -32339,19 +32797,16 @@ async function geoCommand(options) {
32339
32797
  console.log(source_default.bold(" Automation"));
32340
32798
  console.log("");
32341
32799
  console.log(
32342
- source_default.gray(
32343
- " \u2022 next.config: withSiteKitConfig({ llmsTxtDiscoveryLink: true })"
32344
- )
32800
+ source_default.gray(' \u2022 proxy.ts: createProxy({ llmsDiscovery: { siteUrl } }) (Link rel="describedby")')
32345
32801
  );
32346
32802
  console.log(
32347
- source_default.gray(
32348
- " (If you define your own headers() on nextConfig, merge Link manually.)"
32349
- )
32803
+ source_default.gray(" or next.config: withSiteKitConfig({ llmsTxtDiscoveryLink: true })")
32350
32804
  );
32351
32805
  console.log(
32352
- source_default.gray(
32353
- " \u2022 createSitemap({ includeLlmsTxtInSitemap: true, includeLlmsFullTxtInSitemap: true })"
32354
- )
32806
+ source_default.gray(" \u2022 createLLMsTxtHandler sends X-Robots-Tag: noindex; a static public/llms.txt needs it in netlify.toml")
32807
+ );
32808
+ console.log(
32809
+ source_default.gray(" \u2022 Keep llms.txt out of the sitemap: AI crawlers find it at /llms.txt")
32355
32810
  );
32356
32811
  console.log(
32357
32812
  source_default.gray(" \u2022 npx sonor-setup scaffold --minimal (routes + sitemap template)")