@sonordev/site-kit 5.5.0 → 5.7.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 (392) hide show
  1. package/agent-manifest.json +11 -3
  2. package/dist/AnalyticsProvider-EWF7JN2X.mjs +11 -0
  3. package/dist/{AnalyticsProvider-KFXAH4GR.mjs.map → AnalyticsProvider-EWF7JN2X.mjs.map} +1 -1
  4. package/dist/AnalyticsProvider-GJFG7YXA.js +32 -0
  5. package/dist/{AnalyticsProvider-WDDW3IJW.js.map → AnalyticsProvider-GJFG7YXA.js.map} +1 -1
  6. package/dist/{BlogViewTracker-D4DIEP4Q.js → BlogViewTracker-2D3IJPJK.js} +6 -6
  7. package/dist/{BlogViewTracker-D4DIEP4Q.js.map → BlogViewTracker-2D3IJPJK.js.map} +1 -1
  8. package/dist/{BlogViewTracker-ZVEGGH3Y.mjs → BlogViewTracker-CKYG6MYU.mjs} +5 -5
  9. package/dist/{BlogViewTracker-ZVEGGH3Y.mjs.map → BlogViewTracker-CKYG6MYU.mjs.map} +1 -1
  10. package/dist/ChatWidget-AWP6GBVW.js +22 -0
  11. package/dist/{ChatWidget-2ZYPYIMQ.js.map → ChatWidget-AWP6GBVW.js.map} +1 -1
  12. package/dist/ChatWidget-Z5QXDZP3.mjs +13 -0
  13. package/dist/{ChatWidget-FYCCLMQE.mjs.map → ChatWidget-Z5QXDZP3.mjs.map} +1 -1
  14. package/dist/EngageWidget-BKEY5TPO.mjs +12 -0
  15. package/dist/{EngageWidget-6HUZYOY7.mjs.map → EngageWidget-BKEY5TPO.mjs.map} +1 -1
  16. package/dist/EngageWidget-VT4DYXVO.js +21 -0
  17. package/dist/{EngageWidget-MYQTBBW6.js.map → EngageWidget-VT4DYXVO.js.map} +1 -1
  18. package/dist/{FileField-JK2S24XU.js → FileField-62ZWZMQK.js} +6 -6
  19. package/dist/{FileField-JK2S24XU.js.map → FileField-62ZWZMQK.js.map} +1 -1
  20. package/dist/{FileField-OZZHWGPA.mjs → FileField-JJN5QKDL.mjs} +5 -5
  21. package/dist/{FileField-OZZHWGPA.mjs.map → FileField-JJN5QKDL.mjs.map} +1 -1
  22. package/dist/{FormSpotlight-XV42L72H.mjs → FormSpotlight-OTFB6QM5.mjs} +3 -3
  23. package/dist/{FormSpotlight-XV42L72H.mjs.map → FormSpotlight-OTFB6QM5.mjs.map} +1 -1
  24. package/dist/{FormSpotlight-5AXFQU5M.js → FormSpotlight-URS4XRS7.js} +15 -15
  25. package/dist/{FormSpotlight-5AXFQU5M.js.map → FormSpotlight-URS4XRS7.js.map} +1 -1
  26. package/dist/{FormStage-HATUHNRV.js → FormStage-FVKMIV73.js} +13 -13
  27. package/dist/{FormStage-HATUHNRV.js.map → FormStage-FVKMIV73.js.map} +1 -1
  28. package/dist/{FormStage-RUK675HV.mjs → FormStage-VPGOCMAV.mjs} +3 -3
  29. package/dist/{FormStage-RUK675HV.mjs.map → FormStage-VPGOCMAV.mjs.map} +1 -1
  30. package/dist/ManagedForm-CXVDJMHN.mjs +14 -0
  31. package/dist/{ManagedForm-OA3MNGXT.mjs.map → ManagedForm-CXVDJMHN.mjs.map} +1 -1
  32. package/dist/ManagedForm-FGNTDGED.js +23 -0
  33. package/dist/{ManagedForm-JWEXJEXK.js.map → ManagedForm-FGNTDGED.js.map} +1 -1
  34. package/dist/{ManagedNewsletterForm-AAHH63KT.js → ManagedNewsletterForm-3O5L44AZ.js} +8 -8
  35. package/dist/{ManagedNewsletterForm-AAHH63KT.js.map → ManagedNewsletterForm-3O5L44AZ.js.map} +1 -1
  36. package/dist/{ManagedNewsletterForm-HZKTNWLW.mjs → ManagedNewsletterForm-SQYB4BZU.mjs} +7 -7
  37. package/dist/{ManagedNewsletterForm-HZKTNWLW.mjs.map → ManagedNewsletterForm-SQYB4BZU.mjs.map} +1 -1
  38. package/dist/{SignalCore-X3GDGBZD.mjs → SignalCore-M2PKKIGH.mjs} +5 -5
  39. package/dist/{SignalCore-X3GDGBZD.mjs.map → SignalCore-M2PKKIGH.mjs.map} +1 -1
  40. package/dist/{SignalCore-YSNZYBKJ.js → SignalCore-RFBOBNLQ.js} +11 -11
  41. package/dist/{SignalCore-YSNZYBKJ.js.map → SignalCore-RFBOBNLQ.js.map} +1 -1
  42. package/dist/SitemapSync-4OVMIIGC.mjs +9 -0
  43. package/dist/{SitemapSync-2PTDBH5E.mjs.map → SitemapSync-4OVMIIGC.mjs.map} +1 -1
  44. package/dist/SitemapSync-RK3SQ4M2.js +18 -0
  45. package/dist/{SitemapSync-3SFAI546.js.map → SitemapSync-RK3SQ4M2.js.map} +1 -1
  46. package/dist/SitemapSync.d.ts +3 -2
  47. package/dist/SitemapSync.d.ts.map +1 -1
  48. package/dist/analytics/AnalyticsProvider.d.ts +3 -1
  49. package/dist/analytics/AnalyticsProvider.d.ts.map +1 -1
  50. package/dist/analytics/WebVitals.d.ts +3 -1
  51. package/dist/analytics/WebVitals.d.ts.map +1 -1
  52. package/dist/analytics/index.js +13 -13
  53. package/dist/analytics/index.mjs +5 -5
  54. package/dist/analytics/send-gate.d.ts +8 -37
  55. package/dist/analytics/send-gate.d.ts.map +1 -1
  56. package/dist/blog/index.js +20 -20
  57. package/dist/blog/index.mjs +3 -3
  58. package/dist/blog/metadata-images.test.d.ts +2 -0
  59. package/dist/blog/metadata-images.test.d.ts.map +1 -0
  60. package/dist/blog/server-core.d.ts +31 -6
  61. package/dist/blog/server-core.d.ts.map +1 -1
  62. package/dist/blog/server-ui.js +16 -16
  63. package/dist/blog/server-ui.mjs +3 -3
  64. package/dist/blog/server.d.ts +31 -6
  65. package/dist/blog/server.d.ts.map +1 -1
  66. package/dist/blog/server.js +40 -40
  67. package/dist/blog/server.mjs +1 -1
  68. package/dist/blog/static-params.test.d.ts +2 -0
  69. package/dist/blog/static-params.test.d.ts.map +1 -0
  70. package/dist/{chunk-KAUUGRYB.js → chunk-2N27LCZH.js} +26 -32
  71. package/dist/chunk-2N27LCZH.js.map +1 -0
  72. package/dist/{chunk-R4MX6EOM.mjs → chunk-3CLP35TT.mjs} +7 -7
  73. package/dist/{chunk-R4MX6EOM.mjs.map → chunk-3CLP35TT.mjs.map} +1 -1
  74. package/dist/{chunk-SQVYLIIN.js → chunk-3S5JN6KL.js} +16 -19
  75. package/dist/chunk-3S5JN6KL.js.map +1 -0
  76. package/dist/chunk-3UC6JETG.js +32 -0
  77. package/dist/chunk-3UC6JETG.js.map +1 -0
  78. package/dist/{chunk-CT5REGAK.js → chunk-3YQILJKJ.js} +14 -14
  79. package/dist/{chunk-CT5REGAK.js.map → chunk-3YQILJKJ.js.map} +1 -1
  80. package/dist/{chunk-3B6CXGAK.mjs → chunk-47XQWV4S.mjs} +3 -3
  81. package/dist/{chunk-3B6CXGAK.mjs.map → chunk-47XQWV4S.mjs.map} +1 -1
  82. package/dist/{chunk-RZUZMUTN.mjs → chunk-4A5V73SR.mjs} +21 -9
  83. package/dist/chunk-4A5V73SR.mjs.map +1 -0
  84. package/dist/{chunk-FYVLQ3OU.js → chunk-4UVM7E2W.js} +3 -3
  85. package/dist/{chunk-FYVLQ3OU.js.map → chunk-4UVM7E2W.js.map} +1 -1
  86. package/dist/{chunk-HFJQMIFM.js → chunk-4WBTM6YE.js} +4 -4
  87. package/dist/{chunk-HFJQMIFM.js.map → chunk-4WBTM6YE.js.map} +1 -1
  88. package/dist/{chunk-XQYC4KMH.mjs → chunk-57AFHENV.mjs} +48 -42
  89. package/dist/chunk-57AFHENV.mjs.map +1 -0
  90. package/dist/chunk-5RNAUYWE.js +50 -0
  91. package/dist/chunk-5RNAUYWE.js.map +1 -0
  92. package/dist/chunk-5TXXTYXL.js +8 -0
  93. package/dist/{chunk-SUZ3ZLB2.js.map → chunk-5TXXTYXL.js.map} +1 -1
  94. package/dist/{chunk-RU54J2PY.mjs → chunk-6FC5Q4KU.mjs} +3 -3
  95. package/dist/{chunk-RU54J2PY.mjs.map → chunk-6FC5Q4KU.mjs.map} +1 -1
  96. package/dist/{chunk-ZRQFG3L6.mjs → chunk-7ZX6TO6C.mjs} +4 -4
  97. package/dist/{chunk-ZRQFG3L6.mjs.map → chunk-7ZX6TO6C.mjs.map} +1 -1
  98. package/dist/chunk-A6UYV475.mjs +45 -0
  99. package/dist/chunk-A6UYV475.mjs.map +1 -0
  100. package/dist/{chunk-4XGACM7D.mjs → chunk-ABZGEHTC.mjs} +3 -3
  101. package/dist/{chunk-4XGACM7D.mjs.map → chunk-ABZGEHTC.mjs.map} +1 -1
  102. package/dist/chunk-AWK57R5S.mjs +29 -0
  103. package/dist/chunk-AWK57R5S.mjs.map +1 -0
  104. package/dist/{chunk-EEQYKMGH.mjs → chunk-BFJOZ3MU.mjs} +23 -17
  105. package/dist/chunk-BFJOZ3MU.mjs.map +1 -0
  106. package/dist/{chunk-HX3BRMOX.js → chunk-BFM5PEFV.js} +3 -3
  107. package/dist/{chunk-HX3BRMOX.js.map → chunk-BFM5PEFV.js.map} +1 -1
  108. package/dist/{chunk-VYHRAICF.mjs → chunk-BQGEVMIR.mjs} +4 -4
  109. package/dist/{chunk-VYHRAICF.mjs.map → chunk-BQGEVMIR.mjs.map} +1 -1
  110. package/dist/{chunk-S6FEC6UT.mjs → chunk-BUJWXSYZ.mjs} +14 -17
  111. package/dist/chunk-BUJWXSYZ.mjs.map +1 -0
  112. package/dist/{chunk-VAS3LH5W.js → chunk-C4PZ2R3B.js} +55 -49
  113. package/dist/chunk-C4PZ2R3B.js.map +1 -0
  114. package/dist/{chunk-MU7IEPDG.mjs → chunk-C563AHZZ.mjs} +3 -3
  115. package/dist/{chunk-MU7IEPDG.mjs.map → chunk-C563AHZZ.mjs.map} +1 -1
  116. package/dist/{chunk-746RKQHA.js → chunk-CPY74A4F.js} +23 -17
  117. package/dist/chunk-CPY74A4F.js.map +1 -0
  118. package/dist/{chunk-UNPEMSLK.js → chunk-D553G64G.js} +24 -12
  119. package/dist/chunk-D553G64G.js.map +1 -0
  120. package/dist/{chunk-KPKQKFT4.js → chunk-DOB37PV4.js} +3 -3
  121. package/dist/{chunk-KPKQKFT4.js.map → chunk-DOB37PV4.js.map} +1 -1
  122. package/dist/{chunk-2OU4KBUN.js → chunk-ELQ4SRRR.js} +15 -15
  123. package/dist/{chunk-2OU4KBUN.js.map → chunk-ELQ4SRRR.js.map} +1 -1
  124. package/dist/{chunk-Q26VZNM2.js → chunk-F3AKYZOH.js} +3 -3
  125. package/dist/{chunk-Q26VZNM2.js.map → chunk-F3AKYZOH.js.map} +1 -1
  126. package/dist/{chunk-X2XFLYZ3.mjs → chunk-FBDHKYNF.mjs} +3 -3
  127. package/dist/{chunk-X2XFLYZ3.mjs.map → chunk-FBDHKYNF.mjs.map} +1 -1
  128. package/dist/{chunk-BNOQXDPJ.js → chunk-FEWWGEQF.js} +4 -4
  129. package/dist/{chunk-BNOQXDPJ.js.map → chunk-FEWWGEQF.js.map} +1 -1
  130. package/dist/{chunk-NZSFOZJV.js → chunk-FO4KGPGF.js} +2 -2
  131. package/dist/{chunk-NZSFOZJV.js.map → chunk-FO4KGPGF.js.map} +1 -1
  132. package/dist/{chunk-QEGUI2Q2.js → chunk-H65OX263.js} +15 -15
  133. package/dist/{chunk-QEGUI2Q2.js.map → chunk-H65OX263.js.map} +1 -1
  134. package/dist/{chunk-46BMNWE6.js → chunk-H6YVT3BL.js} +2 -2
  135. package/dist/{chunk-46BMNWE6.js.map → chunk-H6YVT3BL.js.map} +1 -1
  136. package/dist/{chunk-TX2QQ7IX.mjs → chunk-HBN4A2N4.mjs} +3 -3
  137. package/dist/{chunk-TX2QQ7IX.mjs.map → chunk-HBN4A2N4.mjs.map} +1 -1
  138. package/dist/{chunk-AJQI3WTN.mjs → chunk-ILNCUSXW.mjs} +2 -2
  139. package/dist/{chunk-AJQI3WTN.mjs.map → chunk-ILNCUSXW.mjs.map} +1 -1
  140. package/dist/{chunk-RMMHWSPP.mjs → chunk-JNAXDFC4.mjs} +3 -3
  141. package/dist/{chunk-RMMHWSPP.mjs.map → chunk-JNAXDFC4.mjs.map} +1 -1
  142. package/dist/{chunk-TALEV3IH.mjs → chunk-JQ7M6CVL.mjs} +3 -3
  143. package/dist/{chunk-TALEV3IH.mjs.map → chunk-JQ7M6CVL.mjs.map} +1 -1
  144. package/dist/{chunk-2CMSWJWC.js → chunk-JTCQJKJE.js} +18 -18
  145. package/dist/{chunk-2CMSWJWC.js.map → chunk-JTCQJKJE.js.map} +1 -1
  146. package/dist/{chunk-7PPNXORV.mjs → chunk-JTF4DFUF.mjs} +25 -31
  147. package/dist/chunk-JTF4DFUF.mjs.map +1 -0
  148. package/dist/{chunk-MCJF2KJ6.js → chunk-KXGD4E7G.js} +5 -5
  149. package/dist/{chunk-MCJF2KJ6.js.map → chunk-KXGD4E7G.js.map} +1 -1
  150. package/dist/chunk-L4V6TKMJ.mjs +94 -0
  151. package/dist/chunk-L4V6TKMJ.mjs.map +1 -0
  152. package/dist/{chunk-W5NVW23S.js → chunk-L7ACQ6PC.js} +4 -4
  153. package/dist/{chunk-W5NVW23S.js.map → chunk-L7ACQ6PC.js.map} +1 -1
  154. package/dist/{chunk-WIZRCI6J.mjs → chunk-M5GY2AI3.mjs} +3 -3
  155. package/dist/{chunk-WIZRCI6J.mjs.map → chunk-M5GY2AI3.mjs.map} +1 -1
  156. package/dist/{chunk-HBI67P7Y.mjs → chunk-MW2M6O7A.mjs} +18 -14
  157. package/dist/chunk-MW2M6O7A.mjs.map +1 -0
  158. package/dist/{chunk-A3F5GRNJ.js → chunk-NOU3JQJK.js} +8 -8
  159. package/dist/{chunk-A3F5GRNJ.js.map → chunk-NOU3JQJK.js.map} +1 -1
  160. package/dist/{chunk-DYULWKDC.mjs → chunk-O2VJZOR2.mjs} +14 -33
  161. package/dist/chunk-O2VJZOR2.mjs.map +1 -0
  162. package/dist/{chunk-FF5N5D3D.js → chunk-OYOO2OO5.js} +8 -8
  163. package/dist/{chunk-FF5N5D3D.js.map → chunk-OYOO2OO5.js.map} +1 -1
  164. package/dist/chunk-P4TB4ROG.js +110 -0
  165. package/dist/chunk-P4TB4ROG.js.map +1 -0
  166. package/dist/{chunk-V6NOM7PJ.mjs → chunk-Q7347KP6.mjs} +3 -3
  167. package/dist/{chunk-V6NOM7PJ.mjs.map → chunk-Q7347KP6.mjs.map} +1 -1
  168. package/dist/chunk-QRBPT6Z6.mjs +6 -0
  169. package/dist/{chunk-WDBCXRTT.mjs.map → chunk-QRBPT6Z6.mjs.map} +1 -1
  170. package/dist/{chunk-G5HUI4BO.mjs → chunk-R2SXXFXZ.mjs} +3 -3
  171. package/dist/{chunk-G5HUI4BO.mjs.map → chunk-R2SXXFXZ.mjs.map} +1 -1
  172. package/dist/{chunk-PIPLBBDH.js → chunk-RCSTDJUH.js} +22 -41
  173. package/dist/chunk-RCSTDJUH.js.map +1 -0
  174. package/dist/{chunk-Z6S4MWSR.js → chunk-RNAGCAIB.js} +21 -17
  175. package/dist/chunk-RNAGCAIB.js.map +1 -0
  176. package/dist/{chunk-AEARU24Q.mjs → chunk-RVRN5U7W.mjs} +2 -2
  177. package/dist/{chunk-AEARU24Q.mjs.map → chunk-RVRN5U7W.mjs.map} +1 -1
  178. package/dist/{chunk-DRLHQQBH.mjs → chunk-TDJKGN5Q.mjs} +4 -4
  179. package/dist/{chunk-DRLHQQBH.mjs.map → chunk-TDJKGN5Q.mjs.map} +1 -1
  180. package/dist/{chunk-MNYM2XU4.js → chunk-TSZIACRC.js} +4 -4
  181. package/dist/{chunk-MNYM2XU4.js.map → chunk-TSZIACRC.js.map} +1 -1
  182. package/dist/{chunk-UZL2QU2V.mjs → chunk-UQ5YULFU.mjs} +4 -4
  183. package/dist/{chunk-UZL2QU2V.mjs.map → chunk-UQ5YULFU.mjs.map} +1 -1
  184. package/dist/{chunk-5TGAUWNO.mjs → chunk-V5THCFPG.mjs} +3 -3
  185. package/dist/{chunk-5TGAUWNO.mjs.map → chunk-V5THCFPG.mjs.map} +1 -1
  186. package/dist/{chunk-YNC5D3FT.js → chunk-VFGEY6FJ.js} +12 -12
  187. package/dist/{chunk-YNC5D3FT.js.map → chunk-VFGEY6FJ.js.map} +1 -1
  188. package/dist/{chunk-OFSA7LUH.mjs → chunk-XLPU3TEE.mjs} +4 -4
  189. package/dist/{chunk-OFSA7LUH.mjs.map → chunk-XLPU3TEE.mjs.map} +1 -1
  190. package/dist/{chunk-YYAFHIY7.js → chunk-YKUEFRZI.js} +14 -14
  191. package/dist/{chunk-YYAFHIY7.js.map → chunk-YKUEFRZI.js.map} +1 -1
  192. package/dist/{chunk-QFNSM77X.js → chunk-YYDZ2TYR.js} +3 -3
  193. package/dist/{chunk-QFNSM77X.js.map → chunk-YYDZ2TYR.js.map} +1 -1
  194. package/dist/cli/agent/checks.d.ts.map +1 -1
  195. package/dist/cli/api/{uptrade.d.ts → sonor.d.ts} +3 -2
  196. package/dist/cli/api/sonor.d.ts.map +1 -0
  197. package/dist/cli/commands/api-routes.d.ts.map +1 -1
  198. package/dist/cli/commands/config-regression.test.d.ts +2 -0
  199. package/dist/cli/commands/config-regression.test.d.ts.map +1 -0
  200. package/dist/cli/commands/faqs.d.ts.map +1 -1
  201. package/dist/cli/commands/geo.d.ts +4 -0
  202. package/dist/cli/commands/geo.d.ts.map +1 -1
  203. package/dist/cli/commands/geo.test.d.ts +2 -0
  204. package/dist/cli/commands/geo.test.d.ts.map +1 -0
  205. package/dist/cli/commands/images.d.ts.map +1 -1
  206. package/dist/cli/commands/locations.d.ts.map +1 -1
  207. package/dist/cli/commands/migrate.d.ts.map +1 -1
  208. package/dist/cli/commands/og.d.ts +10 -1
  209. package/dist/cli/commands/og.d.ts.map +1 -1
  210. package/dist/cli/commands/scaffold.d.ts +1 -2
  211. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  212. package/dist/cli/commands/setup.d.ts.map +1 -1
  213. package/dist/cli/commands/sync.d.ts.map +1 -1
  214. package/dist/cli/config.d.ts +31 -0
  215. package/dist/cli/config.d.ts.map +1 -0
  216. package/dist/cli/config.test.d.ts +2 -0
  217. package/dist/cli/config.test.d.ts.map +1 -0
  218. package/dist/cli/generators/index.d.ts +5 -0
  219. package/dist/cli/generators/index.d.ts.map +1 -1
  220. package/dist/cli/generators/index.test.d.ts +2 -0
  221. package/dist/cli/generators/index.test.d.ts.map +1 -0
  222. package/dist/cli/index.js +717 -634
  223. package/dist/cli/index.js.map +1 -1
  224. package/dist/cli/index.mjs +708 -625
  225. package/dist/cli/index.mjs.map +1 -1
  226. package/dist/cli/migrator/index.d.ts +1 -0
  227. package/dist/cli/migrator/index.d.ts.map +1 -1
  228. package/dist/cli/state.d.ts +7 -0
  229. package/dist/cli/state.d.ts.map +1 -0
  230. package/dist/cli/state.test.d.ts +2 -0
  231. package/dist/cli/state.test.d.ts.map +1 -0
  232. package/dist/client/index.js +4 -4
  233. package/dist/client/index.mjs +3 -3
  234. package/dist/commerce/index.js +57 -57
  235. package/dist/commerce/index.mjs +6 -6
  236. package/dist/discover-FGTKWOL3.mjs +4 -0
  237. package/dist/{discover-BEJRYNFF.mjs.map → discover-FGTKWOL3.mjs.map} +1 -1
  238. package/dist/discover-NJZPWTDL.js +21 -0
  239. package/dist/{discover-WVDYDUJX.js.map → discover-NJZPWTDL.js.map} +1 -1
  240. package/dist/engage/EngageWidget.d.ts +3 -2
  241. package/dist/engage/EngageWidget.d.ts.map +1 -1
  242. package/dist/engage/index.js +11 -10
  243. package/dist/engage/index.js.map +1 -1
  244. package/dist/engage/index.mjs +8 -7
  245. package/dist/engage/index.mjs.map +1 -1
  246. package/dist/fleet/FleetHeartbeat.d.ts +3 -2
  247. package/dist/fleet/FleetHeartbeat.d.ts.map +1 -1
  248. package/dist/fleet/heartbeat.d.ts +3 -2
  249. package/dist/fleet/heartbeat.d.ts.map +1 -1
  250. package/dist/fleet/heartbeat.test.d.ts +2 -0
  251. package/dist/fleet/heartbeat.test.d.ts.map +1 -0
  252. package/dist/fleet/index.js +9 -8
  253. package/dist/fleet/index.mjs +5 -4
  254. package/dist/forms/index.js +16 -16
  255. package/dist/forms/index.mjs +9 -9
  256. package/dist/forms/server.js +10 -10
  257. package/dist/forms/server.mjs +8 -8
  258. package/dist/forms/static.js +7 -7
  259. package/dist/forms/static.mjs +6 -6
  260. package/dist/images/index.js +11 -11
  261. package/dist/images/index.mjs +4 -4
  262. package/dist/index.js +69 -69
  263. package/dist/index.mjs +11 -11
  264. package/dist/layout/SiteKitClientProviders.d.ts.map +1 -1
  265. package/dist/layout/client.d.ts.map +1 -1
  266. package/dist/layout/client.js +9 -8
  267. package/dist/layout/client.mjs +8 -7
  268. package/dist/layout/index.js +11 -10
  269. package/dist/layout/index.js.map +1 -1
  270. package/dist/layout/index.mjs +9 -8
  271. package/dist/layout/index.mjs.map +1 -1
  272. package/dist/layout/types.d.ts +2 -0
  273. package/dist/layout/types.d.ts.map +1 -1
  274. package/dist/llms/aiRobots.d.ts +4 -1
  275. package/dist/llms/aiRobots.d.ts.map +1 -1
  276. package/dist/llms/handlers.d.ts +20 -2
  277. package/dist/llms/handlers.d.ts.map +1 -1
  278. package/dist/llms/index.js +25 -18
  279. package/dist/llms/index.js.map +1 -1
  280. package/dist/llms/index.mjs +15 -8
  281. package/dist/llms/index.mjs.map +1 -1
  282. package/dist/llms/wiring.d.ts +81 -0
  283. package/dist/llms/wiring.d.ts.map +1 -0
  284. package/dist/llms/wiring.test.d.ts +2 -0
  285. package/dist/llms/wiring.test.d.ts.map +1 -0
  286. package/dist/maps/index.js +5 -5
  287. package/dist/maps/index.mjs +3 -3
  288. package/dist/og/wiring.d.ts +5 -1
  289. package/dist/og/wiring.d.ts.map +1 -1
  290. package/dist/proxy/index.d.ts +16 -11
  291. package/dist/proxy/index.d.ts.map +1 -1
  292. package/dist/proxy/index.js +3 -3
  293. package/dist/proxy/index.js.map +1 -1
  294. package/dist/proxy/index.mjs +1 -1
  295. package/dist/proxy/index.mjs.map +1 -1
  296. package/dist/redirects/index.d.ts +1 -1
  297. package/dist/redirects/index.js +8 -8
  298. package/dist/redirects/index.mjs +1 -1
  299. package/dist/redirects/not-found.d.ts +14 -29
  300. package/dist/redirects/not-found.d.ts.map +1 -1
  301. package/dist/redirects/not-found.js +12 -5
  302. package/dist/redirects/not-found.js.map +1 -1
  303. package/dist/redirects/not-found.mjs +8 -1
  304. package/dist/redirects/not-found.mjs.map +1 -1
  305. package/dist/robots/index.d.ts +5 -1
  306. package/dist/robots/index.d.ts.map +1 -1
  307. package/dist/robots/index.js +7 -1
  308. package/dist/robots/index.js.map +1 -1
  309. package/dist/robots/index.mjs +4 -1
  310. package/dist/robots/index.mjs.map +1 -1
  311. package/dist/robots/index.test.d.ts +2 -0
  312. package/dist/robots/index.test.d.ts.map +1 -0
  313. package/dist/robots/next-internals.d.ts +22 -0
  314. package/dist/robots/next-internals.d.ts.map +1 -0
  315. package/dist/search/index.js +4 -4
  316. package/dist/search/index.mjs +3 -3
  317. package/dist/seo/client.js +6 -6
  318. package/dist/seo/client.mjs +5 -5
  319. package/dist/seo/index.js +15 -15
  320. package/dist/seo/index.mjs +7 -7
  321. package/dist/seo/register-sitemap-cli.js +4 -4
  322. package/dist/seo/register-sitemap-cli.mjs +1 -1
  323. package/dist/seo/server.js +5 -5
  324. package/dist/seo/server.mjs +1 -1
  325. package/dist/server/index.js +3 -3
  326. package/dist/server/index.mjs +2 -2
  327. package/dist/shared/next-files.d.ts +35 -0
  328. package/dist/shared/next-files.d.ts.map +1 -0
  329. package/dist/shared/next-files.test.d.ts +2 -0
  330. package/dist/shared/next-files.test.d.ts.map +1 -0
  331. package/dist/shared/reporting-gate.d.ts +43 -0
  332. package/dist/shared/reporting-gate.d.ts.map +1 -0
  333. package/dist/shared/version.d.ts +1 -1
  334. package/dist/signal/index.js +11 -11
  335. package/dist/signal/index.mjs +2 -2
  336. package/dist/sitemap/discover.d.ts.map +1 -1
  337. package/dist/sitemap/index.d.ts +6 -1
  338. package/dist/sitemap/index.d.ts.map +1 -1
  339. package/dist/sitemap/index.js +5 -12
  340. package/dist/sitemap/index.js.map +1 -1
  341. package/dist/sitemap/index.mjs +4 -11
  342. package/dist/sitemap/index.mjs.map +1 -1
  343. package/dist/sync/AddToCalendar.d.ts +19 -0
  344. package/dist/sync/AddToCalendar.d.ts.map +1 -0
  345. package/dist/sync/BookingWidget.d.ts.map +1 -1
  346. package/dist/sync/add-to-calendar.test.d.ts +2 -0
  347. package/dist/sync/add-to-calendar.test.d.ts.map +1 -0
  348. package/dist/sync/api-errors.test.d.ts +2 -0
  349. package/dist/sync/api-errors.test.d.ts.map +1 -0
  350. package/dist/sync/api.d.ts.map +1 -1
  351. package/dist/sync/index.js +17 -17
  352. package/dist/sync/index.mjs +4 -4
  353. package/dist/sync/types.d.ts +14 -0
  354. package/dist/sync/types.d.ts.map +1 -1
  355. package/package.json +22 -24
  356. package/dist/AnalyticsProvider-KFXAH4GR.mjs +0 -11
  357. package/dist/AnalyticsProvider-WDDW3IJW.js +0 -32
  358. package/dist/ChatWidget-2ZYPYIMQ.js +0 -22
  359. package/dist/ChatWidget-FYCCLMQE.mjs +0 -13
  360. package/dist/EngageWidget-6HUZYOY7.mjs +0 -11
  361. package/dist/EngageWidget-MYQTBBW6.js +0 -20
  362. package/dist/ManagedForm-JWEXJEXK.js +0 -23
  363. package/dist/ManagedForm-OA3MNGXT.mjs +0 -14
  364. package/dist/SitemapSync-2PTDBH5E.mjs +0 -9
  365. package/dist/SitemapSync-3SFAI546.js +0 -18
  366. package/dist/chunk-746RKQHA.js.map +0 -1
  367. package/dist/chunk-7PPNXORV.mjs.map +0 -1
  368. package/dist/chunk-DYULWKDC.mjs.map +0 -1
  369. package/dist/chunk-EEQYKMGH.mjs.map +0 -1
  370. package/dist/chunk-HBI67P7Y.mjs.map +0 -1
  371. package/dist/chunk-KAUUGRYB.js.map +0 -1
  372. package/dist/chunk-LOS5D6B3.js +0 -72
  373. package/dist/chunk-LOS5D6B3.js.map +0 -1
  374. package/dist/chunk-NVSWTDWU.mjs +0 -25
  375. package/dist/chunk-NVSWTDWU.mjs.map +0 -1
  376. package/dist/chunk-OL2QBWAU.js +0 -29
  377. package/dist/chunk-OL2QBWAU.js.map +0 -1
  378. package/dist/chunk-PIPLBBDH.js.map +0 -1
  379. package/dist/chunk-RZUZMUTN.mjs.map +0 -1
  380. package/dist/chunk-S6FEC6UT.mjs.map +0 -1
  381. package/dist/chunk-SQVYLIIN.js.map +0 -1
  382. package/dist/chunk-SUZ3ZLB2.js +0 -8
  383. package/dist/chunk-UNPEMSLK.js.map +0 -1
  384. package/dist/chunk-VAS3LH5W.js.map +0 -1
  385. package/dist/chunk-WDBCXRTT.mjs +0 -6
  386. package/dist/chunk-XIJ4F6IE.mjs +0 -63
  387. package/dist/chunk-XIJ4F6IE.mjs.map +0 -1
  388. package/dist/chunk-XQYC4KMH.mjs.map +0 -1
  389. package/dist/chunk-Z6S4MWSR.js.map +0 -1
  390. package/dist/cli/api/uptrade.d.ts.map +0 -1
  391. package/dist/discover-BEJRYNFF.mjs +0 -4
  392. package/dist/discover-WVDYDUJX.js +0 -21
package/dist/cli/index.js CHANGED
@@ -5,12 +5,12 @@ var chunkJS75ORH7_js = require('../chunk-JS75ORH7.js');
5
5
  var chunkI7AZC5ZQ_js = require('../chunk-I7AZC5ZQ.js');
6
6
  var chunk6CJP7BFM_js = require('../chunk-6CJP7BFM.js');
7
7
  var chunkNN2YE5WT_js = require('../chunk-NN2YE5WT.js');
8
- var chunkLOS5D6B3_js = require('../chunk-LOS5D6B3.js');
9
- var chunkSUZ3ZLB2_js = require('../chunk-SUZ3ZLB2.js');
8
+ var chunkP4TB4ROG_js = require('../chunk-P4TB4ROG.js');
9
+ var chunk5TXXTYXL_js = require('../chunk-5TXXTYXL.js');
10
10
  var chunkSNAQBZPT_js = require('../chunk-SNAQBZPT.js');
11
11
  var events = require('events');
12
12
  var childProcess = require('child_process');
13
- var path10 = require('path');
13
+ var path12 = require('path');
14
14
  var fs = require('fs');
15
15
  var process2 = require('process');
16
16
  var util = require('util');
@@ -48,7 +48,7 @@ function _interopNamespace(e) {
48
48
  }
49
49
 
50
50
  var childProcess__default = /*#__PURE__*/_interopDefault(childProcess);
51
- var path10__default = /*#__PURE__*/_interopDefault(path10);
51
+ var path12__default = /*#__PURE__*/_interopDefault(path12);
52
52
  var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
53
53
  var process2__default = /*#__PURE__*/_interopDefault(process2);
54
54
  var os__default = /*#__PURE__*/_interopDefault(os);
@@ -6234,10 +6234,10 @@ var require_lib2 = chunkSNAQBZPT_js.__commonJS({
6234
6234
  exports.analyse = analyse;
6235
6235
  var detectFile = (filepath, opts = {}) => new Promise((resolve, reject) => {
6236
6236
  let fd;
6237
- const fs27 = (0, node_1.default)();
6237
+ const fs30 = (0, node_1.default)();
6238
6238
  const handler = (err, buffer) => {
6239
6239
  if (fd) {
6240
- fs27.closeSync(fd);
6240
+ fs30.closeSync(fd);
6241
6241
  }
6242
6242
  if (err) {
6243
6243
  reject(err);
@@ -6249,9 +6249,9 @@ var require_lib2 = chunkSNAQBZPT_js.__commonJS({
6249
6249
  };
6250
6250
  const sampleSize = (opts === null || opts === void 0 ? void 0 : opts.sampleSize) || 0;
6251
6251
  if (sampleSize > 0) {
6252
- fd = fs27.openSync(filepath, "r");
6252
+ fd = fs30.openSync(filepath, "r");
6253
6253
  let sample = Buffer.allocUnsafe(sampleSize);
6254
- fs27.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
6254
+ fs30.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
6255
6255
  if (err) {
6256
6256
  handler(err, null);
6257
6257
  } else {
@@ -6263,22 +6263,22 @@ var require_lib2 = chunkSNAQBZPT_js.__commonJS({
6263
6263
  });
6264
6264
  return;
6265
6265
  }
6266
- fs27.readFile(filepath, handler);
6266
+ fs30.readFile(filepath, handler);
6267
6267
  });
6268
6268
  exports.detectFile = detectFile;
6269
6269
  var detectFileSync = (filepath, opts = {}) => {
6270
- const fs27 = (0, node_1.default)();
6270
+ const fs30 = (0, node_1.default)();
6271
6271
  if (opts && opts.sampleSize) {
6272
- const fd = fs27.openSync(filepath, "r");
6272
+ const fd = fs30.openSync(filepath, "r");
6273
6273
  let sample = Buffer.allocUnsafe(opts.sampleSize);
6274
- const bytesRead = fs27.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
6274
+ const bytesRead = fs30.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
6275
6275
  if (bytesRead < opts.sampleSize) {
6276
6276
  sample = sample.subarray(0, bytesRead);
6277
6277
  }
6278
- fs27.closeSync(fd);
6278
+ fs30.closeSync(fd);
6279
6279
  return (0, exports.detect)(sample);
6280
6280
  }
6281
- return (0, exports.detect)(fs27.readFileSync(filepath));
6281
+ return (0, exports.detect)(fs30.readFileSync(filepath));
6282
6282
  };
6283
6283
  exports.detectFileSync = detectFileSync;
6284
6284
  exports.default = {
@@ -10167,7 +10167,7 @@ var require_run_async = chunkSNAQBZPT_js.__commonJS({
10167
10167
  });
10168
10168
 
10169
10169
  // src/cli/index.ts
10170
- var import_dotenv = chunkSNAQBZPT_js.__toESM(chunkNN2YE5WT_js.require_main());
10170
+ var import_dotenv2 = chunkSNAQBZPT_js.__toESM(chunkNN2YE5WT_js.require_main());
10171
10171
 
10172
10172
  // node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
10173
10173
  var CommanderError = class extends Error {
@@ -12296,9 +12296,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
12296
12296
  args = args.slice();
12297
12297
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
12298
12298
  function findFile(baseDir, baseName) {
12299
- const localBin = path10__default.default.resolve(baseDir, baseName);
12299
+ const localBin = path12__default.default.resolve(baseDir, baseName);
12300
12300
  if (fs__namespace.default.existsSync(localBin)) return localBin;
12301
- if (sourceExt.includes(path10__default.default.extname(baseName))) return void 0;
12301
+ if (sourceExt.includes(path12__default.default.extname(baseName))) return void 0;
12302
12302
  const foundExt = sourceExt.find(
12303
12303
  (ext2) => fs__namespace.default.existsSync(`${localBin}${ext2}`)
12304
12304
  );
@@ -12316,17 +12316,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
12316
12316
  } catch {
12317
12317
  resolvedScriptPath = this._scriptPath;
12318
12318
  }
12319
- executableDir = path10__default.default.resolve(
12320
- path10__default.default.dirname(resolvedScriptPath),
12319
+ executableDir = path12__default.default.resolve(
12320
+ path12__default.default.dirname(resolvedScriptPath),
12321
12321
  executableDir
12322
12322
  );
12323
12323
  }
12324
12324
  if (executableDir) {
12325
12325
  let localFile = findFile(executableDir, executableFile);
12326
12326
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
12327
- const legacyName = path10__default.default.basename(
12327
+ const legacyName = path12__default.default.basename(
12328
12328
  this._scriptPath,
12329
- path10__default.default.extname(this._scriptPath)
12329
+ path12__default.default.extname(this._scriptPath)
12330
12330
  );
12331
12331
  if (legacyName !== this._name) {
12332
12332
  localFile = findFile(
@@ -12337,7 +12337,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
12337
12337
  }
12338
12338
  executableFile = localFile || executableFile;
12339
12339
  }
12340
- const launchWithNode = sourceExt.includes(path10__default.default.extname(executableFile));
12340
+ const launchWithNode = sourceExt.includes(path12__default.default.extname(executableFile));
12341
12341
  let proc;
12342
12342
  if (process2__default.default.platform !== "win32") {
12343
12343
  if (launchWithNode) {
@@ -13254,7 +13254,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
13254
13254
  * @return {Command}
13255
13255
  */
13256
13256
  nameFromFilename(filename) {
13257
- this._name = path10__default.default.basename(filename, path10__default.default.extname(filename));
13257
+ this._name = path12__default.default.basename(filename, path12__default.default.extname(filename));
13258
13258
  return this;
13259
13259
  }
13260
13260
  /**
@@ -13268,9 +13268,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
13268
13268
  * @param {string} [path]
13269
13269
  * @return {(string|null|Command)}
13270
13270
  */
13271
- executableDir(path27) {
13272
- if (path27 === void 0) return this._executableDir;
13273
- this._executableDir = path27;
13271
+ executableDir(path30) {
13272
+ if (path30 === void 0) return this._executableDir;
13273
+ this._executableDir = path30;
13274
13274
  return this;
13275
13275
  }
13276
13276
  /**
@@ -13543,7 +13543,7 @@ function buildEnvelope(input, nowMs = Date.now()) {
13543
13543
  ok: exitCode === 0 /* OK */,
13544
13544
  command,
13545
13545
  schemaVersion: 1,
13546
- siteKitVersion: chunkSUZ3ZLB2_js.SITE_KIT_VERSION,
13546
+ siteKitVersion: chunk5TXXTYXL_js.SITE_KIT_VERSION,
13547
13547
  exitCode,
13548
13548
  status: statusForCode(exitCode),
13549
13549
  summary,
@@ -18779,7 +18779,7 @@ function createPrompt(view) {
18779
18779
  if (nextView === void 0) {
18780
18780
  let callerFilename = callSites[1]?.getFileName();
18781
18781
  if (callerFilename && !callerFilename.startsWith("file://")) {
18782
- callerFilename = path10__default.default.resolve(callerFilename);
18782
+ callerFilename = path12__default.default.resolve(callerFilename);
18783
18783
  }
18784
18784
  throw new Error(`Prompt functions must return a string.
18785
18785
  at ${callerFilename}`);
@@ -19168,13 +19168,13 @@ var ExternalEditor = class {
19168
19168
  }
19169
19169
  createTempFile() {
19170
19170
  try {
19171
- const baseDir = path10__default.default.resolve(this.fileOptions.dir ?? os__default.default.tmpdir());
19172
- this.tempDir = fs.mkdtempSync(path10__default.default.join(baseDir, "inquirer-editor-"));
19171
+ const baseDir = path12__default.default.resolve(this.fileOptions.dir ?? os__default.default.tmpdir());
19172
+ this.tempDir = fs.mkdtempSync(path12__default.default.join(baseDir, "inquirer-editor-"));
19173
19173
  const id = crypto.randomUUID();
19174
19174
  const prefix = sanitizeAffix(this.fileOptions.prefix);
19175
19175
  const postfix = sanitizeAffix(this.fileOptions.postfix);
19176
19176
  const filename = `${prefix}${id}${postfix}`;
19177
- this.tempFile = path10__default.default.join(this.tempDir, filename);
19177
+ this.tempFile = path12__default.default.join(this.tempDir, filename);
19178
19178
  const opt = { encoding: "utf8", flag: "wx" };
19179
19179
  if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
19180
19180
  opt.mode = this.fileOptions.mode;
@@ -20377,9 +20377,9 @@ function observableToAsyncIterable(source) {
20377
20377
 
20378
20378
  // node_modules/.pnpm/inquirer@14.0.2_@types+node@26.2.0/node_modules/inquirer/dist/ui/prompt.js
20379
20379
  var _ = {
20380
- set: (obj, path27 = "", value) => {
20380
+ set: (obj, path30 = "", value) => {
20381
20381
  let pointer = obj;
20382
- path27.split(".").forEach((key, index, arr) => {
20382
+ path30.split(".").forEach((key, index, arr) => {
20383
20383
  if (key === "__proto__" || key === "constructor")
20384
20384
  return;
20385
20385
  if (index === arr.length - 1) {
@@ -20390,8 +20390,8 @@ var _ = {
20390
20390
  pointer = pointer[key];
20391
20391
  });
20392
20392
  },
20393
- get: (obj, path27 = "", defaultValue) => {
20394
- const travel = (regexp) => String.prototype.split.call(path27, regexp).filter(Boolean).reduce(
20393
+ get: (obj, path30 = "", defaultValue) => {
20394
+ const travel = (regexp) => String.prototype.split.call(path30, regexp).filter(Boolean).reduce(
20395
20395
  // @ts-expect-error implicit any on res[key]
20396
20396
  (res, key) => res == null ? res : res[key],
20397
20397
  obj
@@ -20681,7 +20681,7 @@ async function scanCodebase(rootDir) {
20681
20681
  for (const file of files) {
20682
20682
  try {
20683
20683
  const content = await fs3__default.default.readFile(file, "utf-8");
20684
- const relPath = path10__default.default.relative(rootDir, file);
20684
+ const relPath = path12__default.default.relative(rootDir, file);
20685
20685
  const ast = chunkI7AZC5ZQ_js.parse(content, {
20686
20686
  sourceType: "module",
20687
20687
  plugins: ["jsx", "typescript"]
@@ -20730,7 +20730,7 @@ async function scanCodebase(rootDir) {
20730
20730
  async function findSourceFiles(dir, files = []) {
20731
20731
  const entries = await fs3__default.default.readdir(dir, { withFileTypes: true });
20732
20732
  for (const entry of entries) {
20733
- const fullPath = path10__default.default.join(dir, entry.name);
20733
+ const fullPath = path12__default.default.join(dir, entry.name);
20734
20734
  if (entry.isDirectory()) {
20735
20735
  if (["node_modules", ".next", ".git", "dist", "build"].includes(entry.name)) {
20736
20736
  continue;
@@ -20748,18 +20748,18 @@ function scanForForms(ast, content, filePath) {
20748
20748
  const forms = [];
20749
20749
  content.split("\n");
20750
20750
  chunkJS75ORH7_js.traverse(ast, {
20751
- JSXElement(path27) {
20752
- const opening = path27.node.openingElement;
20751
+ JSXElement(path30) {
20752
+ const opening = path30.node.openingElement;
20753
20753
  if (chunkJS75ORH7_js.isJSXIdentifier(opening.name) && opening.name.name === "form") {
20754
- const fields = extractFieldsFromForm(path27);
20754
+ const fields = extractFieldsFromForm(path30);
20755
20755
  const hasOnSubmit = opening.attributes.some(
20756
20756
  (attr) => chunkJS75ORH7_js.isJSXAttribute(attr) && chunkJS75ORH7_js.isJSXIdentifier(attr.name) && attr.name.name === "onSubmit"
20757
20757
  );
20758
20758
  if (hasOnSubmit && fields.length > 0) {
20759
- const startLine = path27.node.loc?.start.line || 0;
20760
- const endLine = path27.node.loc?.end.line || 0;
20759
+ const startLine = path30.node.loc?.start.line || 0;
20760
+ const endLine = path30.node.loc?.end.line || 0;
20761
20761
  let componentName = "UnknownForm";
20762
- let current = path27.parentPath;
20762
+ let current = path30.parentPath;
20763
20763
  while (current) {
20764
20764
  if (chunkJS75ORH7_js.isFunctionDeclaration(current.node) && current.node.id) {
20765
20765
  componentName = current.node.id.name;
@@ -20792,7 +20792,7 @@ function scanForForms(ast, content, filePath) {
20792
20792
  }
20793
20793
  if (chunkJS75ORH7_js.isJSXIdentifier(opening.name) && opening.name.name === "Form") {
20794
20794
  if (content.includes("Formik") || content.includes("formik")) {
20795
- const fields = extractFieldsFromFormik(path27);
20795
+ const fields = extractFieldsFromFormik(path30);
20796
20796
  if (fields.length > 0) {
20797
20797
  forms.push({
20798
20798
  filePath,
@@ -20803,8 +20803,8 @@ function scanForForms(ast, content, filePath) {
20803
20803
  submitsTo: null,
20804
20804
  complexity: "moderate",
20805
20805
  suggestedAction: "assisted",
20806
- startLine: path27.node.loc?.start.line || 0,
20807
- endLine: path27.node.loc?.end.line || 0
20806
+ startLine: path30.node.loc?.start.line || 0,
20807
+ endLine: path30.node.loc?.end.line || 0
20808
20808
  });
20809
20809
  }
20810
20810
  }
@@ -20822,8 +20822,8 @@ function extractFieldsFromForm(formPath) {
20822
20822
  const radioGroups = /* @__PURE__ */ new Map();
20823
20823
  const checkboxGroups = /* @__PURE__ */ new Map();
20824
20824
  formPath.traverse({
20825
- JSXElement(path27) {
20826
- const opening = path27.node.openingElement;
20825
+ JSXElement(path30) {
20826
+ const opening = path30.node.openingElement;
20827
20827
  const tagName = chunkJS75ORH7_js.isJSXIdentifier(opening.name) ? opening.name.name : null;
20828
20828
  if (["input", "textarea", "select"].includes(tagName || "")) {
20829
20829
  const attrs = opening.attributes;
@@ -20870,7 +20870,7 @@ function extractFieldsFromForm(formPath) {
20870
20870
  }
20871
20871
  if (tagName === "select") {
20872
20872
  const selectOptions = [];
20873
- path27.traverse({
20873
+ path30.traverse({
20874
20874
  JSXElement(optionPath) {
20875
20875
  const optOpening = optionPath.node.openingElement;
20876
20876
  const optTagName = chunkJS75ORH7_js.isJSXIdentifier(optOpening.name) ? optOpening.name.name : null;
@@ -20945,8 +20945,8 @@ function extractFieldsFromForm(formPath) {
20945
20945
  function extractFieldsFromFormik(formPath, content) {
20946
20946
  const fields = [];
20947
20947
  formPath.traverse({
20948
- JSXElement(path27) {
20949
- const opening = path27.node.openingElement;
20948
+ JSXElement(path30) {
20949
+ const opening = path30.node.openingElement;
20950
20950
  const tagName = chunkJS75ORH7_js.isJSXIdentifier(opening.name) ? opening.name.name : null;
20951
20951
  if (tagName === "Field" || tagName === "FastField") {
20952
20952
  const attrs = opening.attributes;
@@ -21065,11 +21065,11 @@ function scanForMetadata(ast, content, filePath) {
21065
21065
  }
21066
21066
  let hasHeadComponent = false;
21067
21067
  chunkJS75ORH7_js.traverse(ast, {
21068
- JSXElement(path27) {
21069
- const opening = path27.node.openingElement;
21068
+ JSXElement(path30) {
21069
+ const opening = path30.node.openingElement;
21070
21070
  if (chunkJS75ORH7_js.isJSXIdentifier(opening.name) && opening.name.name === "Head") {
21071
21071
  hasHeadComponent = true;
21072
- path27.stop();
21072
+ path30.stop();
21073
21073
  }
21074
21074
  }
21075
21075
  });
@@ -21104,8 +21104,8 @@ function scanForWidgets(ast, content, filePath) {
21104
21104
  for (const { pattern, type } of widgetPatterns) {
21105
21105
  if (pattern.test(content)) {
21106
21106
  chunkJS75ORH7_js.traverse(ast, {
21107
- JSXElement(path27) {
21108
- const opening = path27.node.openingElement;
21107
+ JSXElement(path30) {
21108
+ const opening = path30.node.openingElement;
21109
21109
  if (chunkJS75ORH7_js.isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
21110
21110
  const srcAttr = opening.attributes.find(
21111
21111
  (attr) => chunkJS75ORH7_js.isJSXAttribute(attr) && chunkJS75ORH7_js.isJSXIdentifier(attr.name) && attr.name.name === "src"
@@ -21120,8 +21120,8 @@ function scanForWidgets(ast, content, filePath) {
21120
21120
  filePath,
21121
21121
  widgetType: type,
21122
21122
  scriptTag: src,
21123
- startLine: path27.node.loc?.start.line || 0,
21124
- endLine: path27.node.loc?.end.line || 0
21123
+ startLine: path30.node.loc?.start.line || 0,
21124
+ endLine: path30.node.loc?.end.line || 0
21125
21125
  });
21126
21126
  }
21127
21127
  }
@@ -21195,7 +21195,7 @@ async function scanForSitemapFiles(rootDir) {
21195
21195
  "next-sitemap.config.ts"
21196
21196
  ];
21197
21197
  for (const configPath of configPaths) {
21198
- const fullPath = path10__default.default.join(rootDir, configPath);
21198
+ const fullPath = path12__default.default.join(rootDir, configPath);
21199
21199
  try {
21200
21200
  await fs3__default.default.access(fullPath);
21201
21201
  const content = await fs3__default.default.readFile(fullPath, "utf-8");
@@ -21213,7 +21213,7 @@ async function scanForSitemapFiles(rootDir) {
21213
21213
  } catch {
21214
21214
  }
21215
21215
  }
21216
- const staticSitemapPath = path10__default.default.join(rootDir, "public", "sitemap.xml");
21216
+ const staticSitemapPath = path12__default.default.join(rootDir, "public", "sitemap.xml");
21217
21217
  try {
21218
21218
  await fs3__default.default.access(staticSitemapPath);
21219
21219
  const content = await fs3__default.default.readFile(staticSitemapPath, "utf-8");
@@ -21236,7 +21236,7 @@ async function scanForSitemapFiles(rootDir) {
21236
21236
  "out/sitemap.xml"
21237
21237
  ];
21238
21238
  for (const genPath of generatedPaths) {
21239
- const fullPath = path10__default.default.join(rootDir, genPath);
21239
+ const fullPath = path12__default.default.join(rootDir, genPath);
21240
21240
  try {
21241
21241
  await fs3__default.default.access(fullPath);
21242
21242
  } catch {
@@ -21260,8 +21260,8 @@ function scanForSchemas(ast, content, filePath) {
21260
21260
  return schemas;
21261
21261
  }
21262
21262
  chunkJS75ORH7_js.traverse(ast, {
21263
- JSXElement(path27) {
21264
- const opening = path27.node.openingElement;
21263
+ JSXElement(path30) {
21264
+ const opening = path30.node.openingElement;
21265
21265
  if (chunkJS75ORH7_js.isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
21266
21266
  const typeAttr = opening.attributes.find(
21267
21267
  (attr) => chunkJS75ORH7_js.isJSXAttribute(attr) && chunkJS75ORH7_js.isJSXIdentifier(attr.name) && attr.name.name === "type"
@@ -21288,8 +21288,8 @@ function scanForSchemas(ast, content, filePath) {
21288
21288
  filePath,
21289
21289
  type: detectedType,
21290
21290
  schemaType,
21291
- startLine: path27.node.loc?.start.line || 0,
21292
- endLine: path27.node.loc?.end.line || 0
21291
+ startLine: path30.node.loc?.start.line || 0,
21292
+ endLine: path30.node.loc?.end.line || 0
21293
21293
  });
21294
21294
  }
21295
21295
  }
@@ -21322,8 +21322,8 @@ function scanForFAQs(ast, content, filePath) {
21322
21322
  /questions?\s*(?:and|&)?\s*answers?/i
21323
21323
  ];
21324
21324
  chunkJS75ORH7_js.traverse(ast, {
21325
- JSXElement(path27) {
21326
- const opening = path27.node.openingElement;
21325
+ JSXElement(path30) {
21326
+ const opening = path30.node.openingElement;
21327
21327
  let tagName = "";
21328
21328
  if (chunkJS75ORH7_js.isJSXIdentifier(opening.name)) {
21329
21329
  tagName = opening.name.name;
@@ -21336,8 +21336,8 @@ function scanForFAQs(ast, content, filePath) {
21336
21336
  faqs.push({
21337
21337
  filePath,
21338
21338
  type: "details-summary",
21339
- startLine: path27.node.loc?.start.line || 0,
21340
- endLine: path27.node.loc?.end.line || 0,
21339
+ startLine: path30.node.loc?.start.line || 0,
21340
+ endLine: path30.node.loc?.end.line || 0,
21341
21341
  hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
21342
21342
  });
21343
21343
  return;
@@ -21345,7 +21345,7 @@ function scanForFAQs(ast, content, filePath) {
21345
21345
  for (const pattern of faqPatterns) {
21346
21346
  if (pattern.test(tagName)) {
21347
21347
  let itemCount = 0;
21348
- path27.traverse({
21348
+ path30.traverse({
21349
21349
  JSXElement(itemPath) {
21350
21350
  const itemOpening = itemPath.node.openingElement;
21351
21351
  if (chunkJS75ORH7_js.isJSXIdentifier(itemOpening.name)) {
@@ -21361,8 +21361,8 @@ function scanForFAQs(ast, content, filePath) {
21361
21361
  type: "accordion",
21362
21362
  componentName: tagName,
21363
21363
  itemCount: itemCount || void 0,
21364
- startLine: path27.node.loc?.start.line || 0,
21365
- endLine: path27.node.loc?.end.line || 0,
21364
+ startLine: path30.node.loc?.start.line || 0,
21365
+ endLine: path30.node.loc?.end.line || 0,
21366
21366
  hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
21367
21367
  });
21368
21368
  return;
@@ -21485,8 +21485,8 @@ function scanForImages(ast, content, filePath) {
21485
21485
  return images;
21486
21486
  }
21487
21487
  chunkJS75ORH7_js.traverse(ast, {
21488
- JSXElement(path27) {
21489
- const opening = path27.node.openingElement;
21488
+ JSXElement(path30) {
21489
+ const opening = path30.node.openingElement;
21490
21490
  if (!chunkJS75ORH7_js.isJSXIdentifier(opening.name)) return;
21491
21491
  const tagName = opening.name.name;
21492
21492
  if (tagName === "img" || tagName === "Image") {
@@ -21514,8 +21514,8 @@ function scanForImages(ast, content, filePath) {
21514
21514
  src: src || void 0,
21515
21515
  alt: alt || void 0,
21516
21516
  isLocal,
21517
- startLine: path27.node.loc?.start.line || 0,
21518
- endLine: path27.node.loc?.end.line || 0
21517
+ startLine: path30.node.loc?.start.line || 0,
21518
+ endLine: path30.node.loc?.end.line || 0
21519
21519
  });
21520
21520
  }
21521
21521
  }
@@ -21720,7 +21720,7 @@ async function migrateFiles(scanResults, options) {
21720
21720
  }
21721
21721
  async function migrateForm(form, options) {
21722
21722
  const changes = [];
21723
- const fullPath = path10__default.default.resolve(process.cwd(), form.filePath);
21723
+ const fullPath = path12__default.default.resolve(process.cwd(), form.filePath);
21724
21724
  const formSlug = generateSlug(form.componentName);
21725
21725
  let formId;
21726
21726
  if (!options.dryRun) {
@@ -21859,7 +21859,7 @@ export default ${componentName}
21859
21859
  `;
21860
21860
  }
21861
21861
  async function createFormInUptrade(form, slug, options) {
21862
- const response = await fetch("https://api.sonor.io/forms", {
21862
+ const response = await fetch(`${options.apiUrl || "https://api.sonor.io"}/forms`, {
21863
21863
  method: "POST",
21864
21864
  headers: {
21865
21865
  "Content-Type": "application/json",
@@ -21897,7 +21897,7 @@ async function migrateWidget(filePath, widget, options) {
21897
21897
  changes.push("[DRY RUN] Sonor Engage chat would come from SiteKitLayout (engage is on by default)");
21898
21898
  return { filePath, success: true, changes };
21899
21899
  }
21900
- const fullPath = path10__default.default.resolve(process.cwd(), filePath);
21900
+ const fullPath = path12__default.default.resolve(process.cwd(), filePath);
21901
21901
  let content = await fs3__default.default.readFile(fullPath, "utf-8");
21902
21902
  switch (widget.widgetType) {
21903
21903
  case "intercom":
@@ -21934,15 +21934,15 @@ function matchBalancedBraces(content, startIndex) {
21934
21934
  }
21935
21935
  async function migrateMetadata(filePath, metadata, options) {
21936
21936
  const changes = [];
21937
- const fullPath = path10__default.default.resolve(process.cwd(), filePath);
21937
+ const fullPath = path12__default.default.resolve(process.cwd(), filePath);
21938
21938
  let pagePath = filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\/layout\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
21939
21939
  if (pagePath === "") pagePath = "/";
21940
21940
  let content = await fs3__default.default.readFile(fullPath, "utf-8");
21941
21941
  const isTypeScript = filePath.endsWith(".tsx") || filePath.endsWith(".ts");
21942
21942
  const ext2 = isTypeScript ? ".tsx" : ".jsx";
21943
21943
  if (isClientComponent(content)) {
21944
- const dir = path10__default.default.dirname(fullPath);
21945
- const layoutPath = path10__default.default.join(dir, `layout${ext2}`);
21944
+ const dir = path12__default.default.dirname(fullPath);
21945
+ const layoutPath = path12__default.default.join(dir, `layout${ext2}`);
21946
21946
  try {
21947
21947
  await fs3__default.default.access(layoutPath);
21948
21948
  const layoutContent = await fs3__default.default.readFile(layoutPath, "utf-8");
@@ -21965,7 +21965,7 @@ async function migrateMetadata(filePath, metadata, options) {
21965
21965
  } catch (error2) {
21966
21966
  changes.push(`Page metadata may already exist: ${pagePath}`);
21967
21967
  }
21968
- const dirName = path10__default.default.basename(dir).replace(/^\[\.\.\.([^\]]+)\]$/, "$1").replace(/^\[([^\]]+)\]$/, "$1");
21968
+ const dirName = path12__default.default.basename(dir).replace(/^\[\.\.\.([^\]]+)\]$/, "$1").replace(/^\[([^\]]+)\]$/, "$1");
21969
21969
  const layoutName = dirName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("") + "Layout";
21970
21970
  const layoutCode = `import { getManagedMetadata, ManagedSchema } from '@sonordev/site-kit/seo'
21971
21971
 
@@ -22074,7 +22074,7 @@ export async function generateMetadata() {
22074
22074
  return { filePath, success: true, changes };
22075
22075
  }
22076
22076
  async function createPageMetadata(pagePath, metadata, options) {
22077
- const response = await fetch("https://api.sonor.io/seo/pages", {
22077
+ const response = await fetch(`${options.apiUrl || "https://api.sonor.io"}/seo/pages`, {
22078
22078
  method: "POST",
22079
22079
  headers: {
22080
22080
  "Content-Type": "application/json",
@@ -22159,7 +22159,7 @@ async function createSchemaRecord(pagePath, schemaType, schemaJson, options) {
22159
22159
  }
22160
22160
  async function migrateSchema(filePath, schema, options) {
22161
22161
  const changes = [];
22162
- const fullPath = path10__default.default.resolve(process.cwd(), filePath);
22162
+ const fullPath = path12__default.default.resolve(process.cwd(), filePath);
22163
22163
  let pagePath = filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
22164
22164
  if (pagePath === "") pagePath = "/";
22165
22165
  let content = await fs3__default.default.readFile(fullPath, "utf-8");
@@ -22270,7 +22270,7 @@ async function createFAQRecord(pagePath, items, options) {
22270
22270
  }
22271
22271
  async function migrateFAQ(filePath, faq, options) {
22272
22272
  const changes = [];
22273
- const fullPath = path10__default.default.resolve(process.cwd(), filePath);
22273
+ const fullPath = path12__default.default.resolve(process.cwd(), filePath);
22274
22274
  let pagePath = filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
22275
22275
  if (pagePath === "") pagePath = "/";
22276
22276
  let content = await fs3__default.default.readFile(fullPath, "utf-8");
@@ -22338,7 +22338,7 @@ async function migrateFAQ(filePath, faq, options) {
22338
22338
  }
22339
22339
  async function migrateSitemap(filePath, sitemap, options) {
22340
22340
  const changes = [];
22341
- const fullPath = path10__default.default.resolve(process.cwd(), filePath);
22341
+ const fullPath = path12__default.default.resolve(process.cwd(), filePath);
22342
22342
  if (options.dryRun) {
22343
22343
  changes.push(`[DRY RUN] Would migrate ${sitemap.type} to Site-Kit sitemap`);
22344
22344
  if (sitemap.type === "next-sitemap-config") {
@@ -22380,8 +22380,8 @@ async function migrateAnalytics(filePath, analytics, options) {
22380
22380
  return { filePath, success: true, changes };
22381
22381
  }
22382
22382
  async function migrateFile(filePath, options) {
22383
- const fullPath = path10__default.default.resolve(filePath);
22384
- const relPath = path10__default.default.relative(process.cwd(), fullPath);
22383
+ const fullPath = path12__default.default.resolve(filePath);
22384
+ const relPath = path12__default.default.relative(process.cwd(), fullPath);
22385
22385
  const content = await fs3__default.default.readFile(fullPath, "utf-8");
22386
22386
  const hasFormTag = content.includes("<form") || content.includes("onSubmit");
22387
22387
  const hasWidget = /intercom|crisp|drift|hubspot|zendesk/i.test(content);
@@ -22398,26 +22398,26 @@ async function migrateFile(filePath, options) {
22398
22398
  return migrateWidget(relPath, {
22399
22399
  widgetType}, options);
22400
22400
  }
22401
- const { parse: parse2 } = await import('../lib-6HOOMENJ.js');
22402
- const ast = parse2(content, {
22401
+ const { parse: parse3 } = await import('../lib-6HOOMENJ.js');
22402
+ const ast = parse3(content, {
22403
22403
  sourceType: "module",
22404
22404
  plugins: ["jsx", "typescript"]
22405
22405
  });
22406
22406
  let componentName = "Form";
22407
22407
  const traverse2 = (await import('../lib-BGAWCSUH.js')).default;
22408
22408
  traverse2(ast, {
22409
- ExportNamedDeclaration(path27) {
22410
- const decl = path27.node.declaration;
22409
+ ExportNamedDeclaration(path30) {
22410
+ const decl = path30.node.declaration;
22411
22411
  if (decl && decl.type === "FunctionDeclaration" && decl.id) {
22412
22412
  componentName = decl.id.name;
22413
- path27.stop();
22413
+ path30.stop();
22414
22414
  }
22415
22415
  },
22416
- ExportDefaultDeclaration(path27) {
22417
- const decl = path27.node.declaration;
22416
+ ExportDefaultDeclaration(path30) {
22417
+ const decl = path30.node.declaration;
22418
22418
  if (decl && decl.type === "FunctionDeclaration" && decl.id) {
22419
22419
  componentName = decl.id.name;
22420
- path27.stop();
22420
+ path30.stop();
22421
22421
  }
22422
22422
  }
22423
22423
  });
@@ -22474,7 +22474,7 @@ function detectFormType(form) {
22474
22474
  return "contact";
22475
22475
  }
22476
22476
  async function generateEnvFile(options) {
22477
- const envPath = path10__default.default.join(process.cwd(), ".env.local");
22477
+ const envPath = path12__default.default.join(process.cwd(), ".env.local");
22478
22478
  let existingContent = "";
22479
22479
  try {
22480
22480
  existingContent = await fs3__default.default.readFile(envPath, "utf-8");
@@ -22533,7 +22533,7 @@ function addImportSafely2(content, importStatement) {
22533
22533
  async function generateLayout() {
22534
22534
  const layoutPath = await findLayoutFile();
22535
22535
  if (!layoutPath) {
22536
- throw new Error("Could not find layout.tsx file");
22536
+ throw new Error("Could not find a root layout (app/layout.tsx, .jsx, .ts or .js)");
22537
22537
  }
22538
22538
  const content = await fs3__default.default.readFile(layoutPath, "utf-8");
22539
22539
  if (content.includes("SiteKitLayout") || content.includes("SiteKitProvider")) {
@@ -22567,22 +22567,7 @@ async function generateLayout() {
22567
22567
  await fs3__default.default.writeFile(layoutPath, newContent, "utf-8");
22568
22568
  }
22569
22569
  async function findLayoutFile() {
22570
- const possiblePaths = [
22571
- "src/app/layout.tsx",
22572
- "app/layout.tsx",
22573
- "src/app/layout.jsx",
22574
- "app/layout.jsx"
22575
- ];
22576
- for (const relativePath of possiblePaths) {
22577
- const fullPath = path10__default.default.join(process.cwd(), relativePath);
22578
- try {
22579
- await fs3__default.default.access(fullPath);
22580
- return fullPath;
22581
- } catch {
22582
- continue;
22583
- }
22584
- }
22585
- return null;
22570
+ return chunkP4TB4ROG_js.findRootLayout(process.cwd());
22586
22571
  }
22587
22572
  var isDockerCached;
22588
22573
  function hasDockerEnv() {
@@ -22744,15 +22729,15 @@ var wslDefaultBrowser = async () => {
22744
22729
  const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
22745
22730
  return stdout.trim();
22746
22731
  };
22747
- var convertWslPathToWindows = async (path27) => {
22748
- if (/^[a-z]+:\/\//i.test(path27)) {
22749
- return path27;
22732
+ var convertWslPathToWindows = async (path30) => {
22733
+ if (/^[a-z]+:\/\//i.test(path30)) {
22734
+ return path30;
22750
22735
  }
22751
22736
  try {
22752
- const { stdout } = await execFile2("wslpath", ["-aw", path27], { encoding: "utf8" });
22737
+ const { stdout } = await execFile2("wslpath", ["-aw", path30], { encoding: "utf8" });
22753
22738
  return stdout.trim();
22754
22739
  } catch {
22755
- return path27;
22740
+ return path30;
22756
22741
  }
22757
22742
  };
22758
22743
 
@@ -22872,8 +22857,8 @@ var is_in_ssh_default = isInSsh;
22872
22857
 
22873
22858
  // node_modules/.pnpm/open@11.0.0/node_modules/open/index.js
22874
22859
  var fallbackAttemptSymbol = /* @__PURE__ */ Symbol("fallbackAttempt");
22875
- var __dirname2 = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) ? path10__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)))) : "";
22876
- var localXdgOpenPath = path10__default.default.join(__dirname2, "xdg-open");
22860
+ var __dirname2 = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) ? path12__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)))) : "";
22861
+ var localXdgOpenPath = path12__default.default.join(__dirname2, "xdg-open");
22877
22862
  var { platform, arch } = process2__default.default;
22878
22863
  var tryEachApp = async (apps2, opener) => {
22879
22864
  if (apps2.length === 0) {
@@ -23151,8 +23136,37 @@ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
23151
23136
  darwin: "Safari"
23152
23137
  }));
23153
23138
  var open_default = open;
23139
+ var SONOR_STATE_DIR = ".sonor";
23140
+ var IMAGE_MANIFEST = ".sonor-images.json";
23141
+ var LEGACY_IMAGE_MANIFEST = ".uptrade-images.json";
23142
+ var LEGACY_STATE_DIR = ".uptrade";
23143
+ function resolveStateReadPath(relativePath, root = process.cwd()) {
23144
+ return preferCurrent(path12__default.default.join(root, SONOR_STATE_DIR, relativePath), path12__default.default.join(root, LEGACY_STATE_DIR, relativePath));
23145
+ }
23146
+ function resolveImageManifestReadPath(root) {
23147
+ return preferCurrent(path12__default.default.join(root, IMAGE_MANIFEST), path12__default.default.join(root, LEGACY_IMAGE_MANIFEST));
23148
+ }
23149
+ function preferCurrent(current, legacy) {
23150
+ return fs.existsSync(current) || !fs.existsSync(legacy) ? current : legacy;
23151
+ }
23152
+ async function listLocalTemplates(root = process.cwd()) {
23153
+ const names = /* @__PURE__ */ new Set();
23154
+ for (const dir of [SONOR_STATE_DIR, LEGACY_STATE_DIR]) {
23155
+ try {
23156
+ const files = await fs3__default.default.readdir(path12__default.default.join(root, dir, "templates"));
23157
+ for (const file of files) if (file.endsWith(".json")) names.add(file);
23158
+ } catch (error2) {
23159
+ if (error2.code !== "ENOENT") throw error2;
23160
+ }
23161
+ }
23162
+ return [...names].sort();
23163
+ }
23164
+
23165
+ // src/cli/api/sonor.ts
23154
23166
  var PORTAL_URL = "https://app.sonor.io";
23155
- var API_URL = process.env.SONOR_API_URL || "https://api.sonor.io";
23167
+ function getSonorApiUrl() {
23168
+ return (process.env.SONOR_API_URL || "https://api.sonor.io").replace(/\/+$/, "");
23169
+ }
23156
23170
  async function authenticateWithSonor() {
23157
23171
  return new Promise((resolve, reject) => {
23158
23172
  const server = http__default.default.createServer(async (req, res) => {
@@ -23179,7 +23193,7 @@ async function authenticateWithSonor() {
23179
23193
  server.close();
23180
23194
  return;
23181
23195
  }
23182
- const tokenResponse = await fetch(`${API_URL}/auth/cli-token`, {
23196
+ const tokenResponse = await fetch(`${getSonorApiUrl()}/auth/cli-token`, {
23183
23197
  method: "POST",
23184
23198
  headers: { "Content-Type": "application/json" },
23185
23199
  body: JSON.stringify({ code, redirect_uri: `http://localhost:${port}/callback` })
@@ -23225,32 +23239,41 @@ async function authenticateWithSonor() {
23225
23239
  }, 5 * 60 * 1e3);
23226
23240
  });
23227
23241
  }
23228
- async function authenticateWithApiKey(apiKey) {
23229
- const response = await fetch(`${API_URL}/api/public/seo/verify-api-key`, {
23230
- headers: { "X-API-Key": apiKey }
23231
- });
23232
- if (response.ok) {
23233
- const data = await response.json();
23234
- if (data.valid) {
23235
- return {
23236
- accessToken: apiKey,
23237
- userId: "api-key-user",
23238
- email: data.project?.name ? `Project: ${data.project.name}` : `API Key verified`,
23239
- projectId: data.project?.id,
23240
- projectName: data.project?.name,
23241
- orgId: data.organization?.id,
23242
- orgName: data.organization?.name,
23243
- isApiKey: true
23244
- };
23245
- }
23242
+ async function authenticateWithApiKey(apiKey, apiUrl = getSonorApiUrl()) {
23243
+ let response;
23244
+ try {
23245
+ response = await fetch(`${apiUrl}/api/public/seo/verify-api-key`, {
23246
+ headers: { "X-API-Key": apiKey },
23247
+ signal: AbortSignal.timeout(15e3)
23248
+ });
23249
+ } catch {
23250
+ throw new NetworkError("PROJECT_LOOKUP_FAILED", "Could not reach the Sonor API to resolve the project. Check SONOR_API_URL and your connection.");
23246
23251
  }
23247
- if (response.status === 401) {
23248
- throw new Error("Invalid API key");
23252
+ if (!response.ok) {
23253
+ throw new NetworkError("PROJECT_LOOKUP_FAILED", `Sonor API verification failed (HTTP ${response.status}). Check SONOR_API_KEY and SONOR_API_URL.`);
23249
23254
  }
23250
- throw new Error(`API verification failed: ${response.status}`);
23255
+ let data;
23256
+ try {
23257
+ data = await response.json();
23258
+ } catch {
23259
+ throw new NetworkError("INVALID_PROJECT_RESPONSE", "Sonor API returned an invalid project response.");
23260
+ }
23261
+ if (data?.valid !== true || typeof data.project?.id !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(data.project.id)) {
23262
+ throw new NetworkError("INVALID_PROJECT_RESPONSE", "Sonor API did not return a valid full project UUID. Check SONOR_API_KEY.");
23263
+ }
23264
+ return {
23265
+ accessToken: apiKey,
23266
+ userId: "api-key-user",
23267
+ email: data.project.name ? `Project: ${data.project.name}` : "API Key verified",
23268
+ projectId: data.project.id,
23269
+ projectName: data.project.name,
23270
+ orgId: data.organization?.id,
23271
+ orgName: data.organization?.name,
23272
+ isApiKey: true
23273
+ };
23251
23274
  }
23252
23275
  async function fetchOrganizations(accessToken) {
23253
- const response = await fetch(`${API_URL}/organizations`, {
23276
+ const response = await fetch(`${getSonorApiUrl()}/organizations`, {
23254
23277
  headers: { "Authorization": `Bearer ${accessToken}` }
23255
23278
  });
23256
23279
  if (!response.ok) {
@@ -23259,7 +23282,7 @@ async function fetchOrganizations(accessToken) {
23259
23282
  return response.json();
23260
23283
  }
23261
23284
  async function fetchProjects(accessToken, orgId) {
23262
- const response = await fetch(`${API_URL}/organizations/${orgId}/projects`, {
23285
+ const response = await fetch(`${getSonorApiUrl()}/organizations/${orgId}/projects`, {
23263
23286
  headers: { "Authorization": `Bearer ${accessToken}` }
23264
23287
  });
23265
23288
  if (!response.ok) {
@@ -23268,7 +23291,7 @@ async function fetchProjects(accessToken, orgId) {
23268
23291
  return response.json();
23269
23292
  }
23270
23293
  async function createProject(accessToken, orgId, data) {
23271
- const response = await fetch(`${API_URL}/organizations/${orgId}/projects`, {
23294
+ const response = await fetch(`${getSonorApiUrl()}/organizations/${orgId}/projects`, {
23272
23295
  method: "POST",
23273
23296
  headers: {
23274
23297
  "Authorization": `Bearer ${accessToken}`,
@@ -23282,7 +23305,7 @@ async function createProject(accessToken, orgId, data) {
23282
23305
  return response.json();
23283
23306
  }
23284
23307
  async function generateApiKey(accessToken, projectId) {
23285
- const response = await fetch(`${API_URL}/projects/${projectId}/api-keys`, {
23308
+ const response = await fetch(`${getSonorApiUrl()}/projects/${projectId}/api-keys`, {
23286
23309
  method: "POST",
23287
23310
  headers: {
23288
23311
  "Authorization": `Bearer ${accessToken}`,
@@ -23486,7 +23509,7 @@ function progress(ctx, line) {
23486
23509
  // src/cli/commands/init.ts
23487
23510
  async function checkNextJsProject(cwd) {
23488
23511
  try {
23489
- const pkg = JSON.parse(await fs3__default.default.readFile(path10__default.default.join(cwd, "package.json"), "utf-8"));
23512
+ const pkg = JSON.parse(await fs3__default.default.readFile(path12__default.default.join(cwd, "package.json"), "utf-8"));
23490
23513
  return !!(pkg.dependencies?.next || pkg.devDependencies?.next);
23491
23514
  } catch {
23492
23515
  return false;
@@ -23566,7 +23589,7 @@ async function run(ctx, options) {
23566
23589
  ]);
23567
23590
  if (chosen === "new") {
23568
23591
  const answers = await dist_default14.prompt([
23569
- { type: "input", name: "name", message: "Project name:", default: path10__default.default.basename(ctx.cwd) },
23592
+ { type: "input", name: "name", message: "Project name:", default: path12__default.default.basename(ctx.cwd) },
23570
23593
  { type: "input", name: "domain", message: "Project domain (optional):" }
23571
23594
  ]);
23572
23595
  const project = await createProject(auth.accessToken, orgId, { name: answers.name, domain: answers.domain || "" });
@@ -23621,7 +23644,7 @@ async function run(ctx, options) {
23621
23644
  };
23622
23645
  }
23623
23646
  async function ensureSitemapPostbuild(ctx) {
23624
- const pkgPath = path10__default.default.join(ctx.cwd, "package.json");
23647
+ const pkgPath = path12__default.default.join(ctx.cwd, "package.json");
23625
23648
  try {
23626
23649
  const pkg = JSON.parse(await fs3__default.default.readFile(pkgPath, "utf-8"));
23627
23650
  if (!pkg.scripts) pkg.scripts = {};
@@ -23663,7 +23686,7 @@ async function scanCommand(options) {
23663
23686
  console.log("");
23664
23687
  console.log(source_default.bold(" Scanning codebase..."));
23665
23688
  console.log("");
23666
- const targetDir = path10__default.default.resolve(options.dir || ".");
23689
+ const targetDir = path12__default.default.resolve(options.dir || ".");
23667
23690
  const spinner = ora("Looking for forms, metadata, widgets, schemas, FAQs, analytics, and images...").start();
23668
23691
  let scanResults;
23669
23692
  try {
@@ -23841,6 +23864,48 @@ async function scanCommand(options) {
23841
23864
  process.exit(1);
23842
23865
  }
23843
23866
  }
23867
+
23868
+ // src/cli/config.ts
23869
+ var import_dotenv = chunkSNAQBZPT_js.__toESM(chunkNN2YE5WT_js.require_main());
23870
+ async function loadConfig({ resolveProject = false, cwd = process.cwd() } = {}) {
23871
+ const envFile = await readOptionalFile(path12__default.default.join(cwd, ".env.local"));
23872
+ const env3 = { ...(0, import_dotenv.parse)(envFile || ""), ...process.env };
23873
+ const configPath = resolveStateReadPath("config.json", cwd);
23874
+ const saved = await readOptionalFile(configPath);
23875
+ let stored = {};
23876
+ if (saved !== void 0) {
23877
+ try {
23878
+ stored = JSON.parse(saved);
23879
+ if (!stored || typeof stored !== "object" || Array.isArray(stored)) throw new Error();
23880
+ } catch {
23881
+ throw new ConfigError("INVALID_CONFIG", `Invalid JSON config: ${configPath}. Fix or remove it, then set SONOR_API_KEY in .env.local.`);
23882
+ }
23883
+ }
23884
+ const apiKey = String(env3.SONOR_API_KEY || stored.apiKey || stored.api_key || "").trim();
23885
+ if (!apiKey) {
23886
+ throw new ConfigError("MISSING_API_KEY", "Set SONOR_API_KEY in .env.local or run `sonor-setup init` first.");
23887
+ }
23888
+ if (!/^sonor_[0-9a-f]{8}_.+$/i.test(apiKey)) {
23889
+ throw new ConfigError("INVALID_API_KEY", "SONOR_API_KEY must be a sonor_ key from app.sonor.io.");
23890
+ }
23891
+ const config2 = {
23892
+ apiKey,
23893
+ apiUrl: (env3.SONOR_API_URL || getSonorApiUrl()).replace(/\/+$/, ""),
23894
+ siteUrl: env3.NEXT_PUBLIC_SITE_URL || env3.SITE_URL || stored.siteUrl || stored.site_url,
23895
+ businessInfo: stored.businessInfo || stored.business_info
23896
+ };
23897
+ if (!resolveProject) return config2;
23898
+ const auth = await authenticateWithApiKey(apiKey, config2.apiUrl);
23899
+ return { ...config2, projectId: auth.projectId };
23900
+ }
23901
+ async function readOptionalFile(file) {
23902
+ try {
23903
+ return await fs3__default.default.readFile(file, "utf-8");
23904
+ } catch (error2) {
23905
+ if (error2.code === "ENOENT") return void 0;
23906
+ throw new ConfigError("CONFIG_READ_FAILED", `Could not read ${file}. Check file permissions.`);
23907
+ }
23908
+ }
23844
23909
  var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".ico", ".bmp", ".avif"];
23845
23910
  var MIME_TYPES = {
23846
23911
  ".jpg": "image/jpeg",
@@ -23863,7 +23928,7 @@ function filePathToPagePath(filePath) {
23863
23928
  }
23864
23929
  if (p.startsWith("pages/") || p.startsWith("src/pages/")) {
23865
23930
  p = p.replace(/^pages\//, "").replace(/^src\/pages\//, "");
23866
- const base = path10__default.default.basename(p, path10__default.default.extname(p));
23931
+ const base = path12__default.default.basename(p, path12__default.default.extname(p));
23867
23932
  return base === "index" ? "/" : "/" + base;
23868
23933
  }
23869
23934
  p = p.replace(/\.[^.]+$/, "").replace(/^\.\//, "").replace(/\\/g, "/");
@@ -23906,8 +23971,8 @@ async function imagesCommand(subcommand, options) {
23906
23971
  }
23907
23972
  }
23908
23973
  async function scanImages(options) {
23909
- const targetDir = path10__default.default.resolve(options.dir || ".");
23910
- const publicDir = path10__default.default.join(targetDir, "public");
23974
+ const targetDir = path12__default.default.resolve(options.dir || ".");
23975
+ const publicDir = path12__default.default.join(targetDir, "public");
23911
23976
  try {
23912
23977
  await fs3__default.default.access(publicDir);
23913
23978
  } catch {
@@ -23977,7 +24042,7 @@ async function uploadImages(options) {
23977
24042
  console.log("");
23978
24043
  process.exit(1);
23979
24044
  }
23980
- const targetDir = path10__default.default.resolve(options.dir || ".");
24045
+ const targetDir = path12__default.default.resolve(options.dir || ".");
23981
24046
  const spinner = ora("Scanning for images...").start();
23982
24047
  const results = await scanPublicImages(targetDir);
23983
24048
  spinner.stop();
@@ -24030,7 +24095,7 @@ async function uploadImages(options) {
24030
24095
  const uploadSpinner = ora(`Uploading ${img.filename}...`).start();
24031
24096
  try {
24032
24097
  const result = await uploadImageToPortal(
24033
- path10__default.default.join(targetDir, img.filePath),
24098
+ path12__default.default.join(targetDir, img.filePath),
24034
24099
  img,
24035
24100
  { apiUrl, apiKey, category: options.category }
24036
24101
  );
@@ -24049,7 +24114,7 @@ async function uploadImages(options) {
24049
24114
  }
24050
24115
  console.log("");
24051
24116
  if (uploaded.length > 0) {
24052
- const manifestPath = path10__default.default.join(targetDir, ".uptrade-images.json");
24117
+ const manifestPath = path12__default.default.join(targetDir, IMAGE_MANIFEST);
24053
24118
  await fs3__default.default.writeFile(manifestPath, JSON.stringify({
24054
24119
  uploaded,
24055
24120
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
@@ -24062,8 +24127,8 @@ async function uploadImages(options) {
24062
24127
  console.log("");
24063
24128
  }
24064
24129
  async function migrateImages(options) {
24065
- const targetDir = path10__default.default.resolve(options.dir || ".");
24066
- const manifestPath = path10__default.default.join(targetDir, ".uptrade-images.json");
24130
+ const targetDir = path12__default.default.resolve(options.dir || ".");
24131
+ const manifestPath = resolveImageManifestReadPath(targetDir);
24067
24132
  const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
24068
24133
  const apiKey = process.env.SONOR_API_KEY || "";
24069
24134
  if (!apiKey) {
@@ -24166,9 +24231,9 @@ async function migrateImages(options) {
24166
24231
  let successCount = 0;
24167
24232
  let failCount = 0;
24168
24233
  for (const [filePath, fileMigrations] of byFile) {
24169
- const fileSpinner = ora(`Migrating ${path10__default.default.basename(filePath)}...`).start();
24234
+ const fileSpinner = ora(`Migrating ${path12__default.default.basename(filePath)}...`).start();
24170
24235
  try {
24171
- await migrateFileImages(path10__default.default.join(targetDir, filePath), fileMigrations);
24236
+ await migrateFileImages(path12__default.default.join(targetDir, filePath), fileMigrations);
24172
24237
  successCount += fileMigrations.length;
24173
24238
  fileSpinner.succeed(`Migrated: ${filePath} (${fileMigrations.length} images)`);
24174
24239
  } catch (error2) {
@@ -24190,7 +24255,7 @@ async function migrateImages(options) {
24190
24255
  console.log("");
24191
24256
  }
24192
24257
  async function uploadAndMigrate(options) {
24193
- const targetDir = path10__default.default.resolve(options.dir || ".");
24258
+ const targetDir = path12__default.default.resolve(options.dir || ".");
24194
24259
  const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
24195
24260
  const apiKey = process.env.SONOR_API_KEY || "";
24196
24261
  if (!apiKey) {
@@ -24257,7 +24322,7 @@ async function uploadAndMigrate(options) {
24257
24322
  const uploadSpinner = ora(`Uploading ${img.filename}...`).start();
24258
24323
  try {
24259
24324
  const result = await uploadImageToPortal(
24260
- path10__default.default.join(targetDir, img.filePath),
24325
+ path12__default.default.join(targetDir, img.filePath),
24261
24326
  img,
24262
24327
  { apiUrl, apiKey, category: options.category }
24263
24328
  );
@@ -24329,9 +24394,9 @@ async function uploadAndMigrate(options) {
24329
24394
  let successCount = 0;
24330
24395
  let failCount = 0;
24331
24396
  for (const [filePath, fileMigrations] of byFile) {
24332
- const fileSpinner = ora(`Migrating ${path10__default.default.basename(filePath)}...`).start();
24397
+ const fileSpinner = ora(`Migrating ${path12__default.default.basename(filePath)}...`).start();
24333
24398
  try {
24334
- await migrateFileImages(path10__default.default.join(targetDir, filePath), fileMigrations);
24399
+ await migrateFileImages(path12__default.default.join(targetDir, filePath), fileMigrations);
24335
24400
  successCount += fileMigrations.length;
24336
24401
  fileSpinner.succeed(`Migrated: ${filePath} (${fileMigrations.length} images)`);
24337
24402
  } catch (error2) {
@@ -24339,7 +24404,7 @@ async function uploadAndMigrate(options) {
24339
24404
  fileSpinner.fail(`Failed: ${filePath} - ${error2.message}`);
24340
24405
  }
24341
24406
  }
24342
- const manifestPath = path10__default.default.join(targetDir, ".uptrade-images.json");
24407
+ const manifestPath = path12__default.default.join(targetDir, IMAGE_MANIFEST);
24343
24408
  await fs3__default.default.writeFile(manifestPath, JSON.stringify({
24344
24409
  uploaded,
24345
24410
  criticalKeptLocal: criticalImages.map((i) => i.filename),
@@ -24366,8 +24431,8 @@ async function uploadAndMigrate(options) {
24366
24431
  console.log("");
24367
24432
  }
24368
24433
  async function replaceWithCdnUrls(options) {
24369
- const targetDir = path10__default.default.resolve(options.dir || ".");
24370
- const manifestPath = path10__default.default.join(targetDir, ".uptrade-images.json");
24434
+ const targetDir = path12__default.default.resolve(options.dir || ".");
24435
+ const manifestPath = resolveImageManifestReadPath(targetDir);
24371
24436
  let manifest;
24372
24437
  try {
24373
24438
  const content = await fs3__default.default.readFile(manifestPath, "utf-8");
@@ -24415,7 +24480,7 @@ async function replaceWithCdnUrls(options) {
24415
24480
  if (!seenFileLines.has(key)) {
24416
24481
  seenFileLines.add(key);
24417
24482
  replacements2.push({
24418
- file: path10__default.default.relative(targetDir, file),
24483
+ file: path12__default.default.relative(targetDir, file),
24419
24484
  localPath: pattern,
24420
24485
  cdnUrl: img.publicUrl,
24421
24486
  line: i + 1
@@ -24463,9 +24528,9 @@ async function replaceWithCdnUrls(options) {
24463
24528
  let successCount = 0;
24464
24529
  let failCount = 0;
24465
24530
  for (const [filePath, fileReplacements] of byFile) {
24466
- const fileSpinner = ora(`Updating ${path10__default.default.basename(filePath)}...`).start();
24531
+ const fileSpinner = ora(`Updating ${path12__default.default.basename(filePath)}...`).start();
24467
24532
  try {
24468
- const fullPath = path10__default.default.join(targetDir, filePath);
24533
+ const fullPath = path12__default.default.join(targetDir, filePath);
24469
24534
  let content = await fs3__default.default.readFile(fullPath, "utf-8");
24470
24535
  for (const r of fileReplacements) {
24471
24536
  const escaped = r.localPath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -24493,8 +24558,8 @@ async function replaceWithCdnUrls(options) {
24493
24558
  console.log("");
24494
24559
  }
24495
24560
  async function refreshManifest(options) {
24496
- const targetDir = path10__default.default.resolve(options.dir || ".");
24497
- const manifestPath = path10__default.default.join(targetDir, ".uptrade-images.json");
24561
+ const targetDir = path12__default.default.resolve(options.dir || ".");
24562
+ const manifestPath = path12__default.default.join(targetDir, IMAGE_MANIFEST);
24498
24563
  const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
24499
24564
  const apiKey = process.env.SONOR_API_KEY || "";
24500
24565
  if (!apiKey) {
@@ -24503,7 +24568,7 @@ async function refreshManifest(options) {
24503
24568
  }
24504
24569
  let manifest;
24505
24570
  try {
24506
- const content = await fs3__default.default.readFile(manifestPath, "utf-8");
24571
+ const content = await fs3__default.default.readFile(resolveImageManifestReadPath(targetDir), "utf-8");
24507
24572
  manifest = JSON.parse(content);
24508
24573
  } catch {
24509
24574
  console.log(source_default.yellow(" \u26A0 No upload manifest found"));
@@ -24556,12 +24621,12 @@ async function refreshManifest(options) {
24556
24621
  }
24557
24622
  async function findDataFiles(rootDir) {
24558
24623
  const files = [];
24559
- const excludeFiles = [".uptrade-images.json"];
24624
+ const excludeFiles = [IMAGE_MANIFEST, LEGACY_IMAGE_MANIFEST];
24560
24625
  async function scan(dir) {
24561
24626
  try {
24562
24627
  const entries = await fs3__default.default.readdir(dir, { withFileTypes: true });
24563
24628
  for (const entry of entries) {
24564
- const fullPath = path10__default.default.join(dir, entry.name);
24629
+ const fullPath = path12__default.default.join(dir, entry.name);
24565
24630
  if (entry.isDirectory()) {
24566
24631
  if (["node_modules", ".next", ".git", "dist", "build"].includes(entry.name)) {
24567
24632
  continue;
@@ -24571,7 +24636,7 @@ async function findDataFiles(rootDir) {
24571
24636
  if (excludeFiles.includes(entry.name)) {
24572
24637
  continue;
24573
24638
  }
24574
- const ext2 = path10__default.default.extname(entry.name).toLowerCase();
24639
+ const ext2 = path12__default.default.extname(entry.name).toLowerCase();
24575
24640
  if ([".js", ".ts", ".json", ".jsx", ".tsx", ".mjs", ".cjs"].includes(ext2)) {
24576
24641
  files.push(fullPath);
24577
24642
  }
@@ -24584,16 +24649,16 @@ async function findDataFiles(rootDir) {
24584
24649
  return files;
24585
24650
  }
24586
24651
  async function scanPublicImages(rootDir) {
24587
- const publicDir = path10__default.default.join(rootDir, "public");
24652
+ const publicDir = path12__default.default.join(rootDir, "public");
24588
24653
  const images = [];
24589
24654
  let totalSize = 0;
24590
24655
  let usageCount = 0;
24591
24656
  const imageFiles = await findImagesRecursive(publicDir);
24592
24657
  const sourceFiles = await findSourceFiles2(rootDir);
24593
24658
  for (const imagePath of imageFiles) {
24594
- const relPath = path10__default.default.relative(rootDir, imagePath);
24595
- const filename = path10__default.default.basename(imagePath);
24596
- const ext2 = path10__default.default.extname(filename).toLowerCase();
24659
+ const relPath = path12__default.default.relative(rootDir, imagePath);
24660
+ const filename = path12__default.default.basename(imagePath);
24661
+ const ext2 = path12__default.default.extname(filename).toLowerCase();
24597
24662
  const stat = await fs3__default.default.stat(imagePath);
24598
24663
  const category = getCategoryFromPath(relPath);
24599
24664
  const suggestedSlotId = generateSlotId(relPath);
@@ -24619,11 +24684,11 @@ async function findImagesRecursive(dir, files = []) {
24619
24684
  try {
24620
24685
  const entries = await fs3__default.default.readdir(dir, { withFileTypes: true });
24621
24686
  for (const entry of entries) {
24622
- const fullPath = path10__default.default.join(dir, entry.name);
24687
+ const fullPath = path12__default.default.join(dir, entry.name);
24623
24688
  if (entry.isDirectory()) {
24624
24689
  await findImagesRecursive(fullPath, files);
24625
24690
  } else if (entry.isFile()) {
24626
- const ext2 = path10__default.default.extname(entry.name).toLowerCase();
24691
+ const ext2 = path12__default.default.extname(entry.name).toLowerCase();
24627
24692
  if (IMAGE_EXTENSIONS.includes(ext2)) {
24628
24693
  files.push(fullPath);
24629
24694
  }
@@ -24636,7 +24701,7 @@ async function findImagesRecursive(dir, files = []) {
24636
24701
  async function findSourceFiles2(dir, files = []) {
24637
24702
  const entries = await fs3__default.default.readdir(dir, { withFileTypes: true });
24638
24703
  for (const entry of entries) {
24639
- const fullPath = path10__default.default.join(dir, entry.name);
24704
+ const fullPath = path12__default.default.join(dir, entry.name);
24640
24705
  if (entry.isDirectory()) {
24641
24706
  if (["node_modules", ".next", ".git", "dist", "build", "public"].includes(entry.name)) {
24642
24707
  continue;
@@ -24652,8 +24717,8 @@ async function findSourceFiles2(dir, files = []) {
24652
24717
  }
24653
24718
  async function findImageUsages(imagePath, sourceFiles, rootDir) {
24654
24719
  const usages = [];
24655
- const filename = path10__default.default.basename(imagePath);
24656
- const relPath = path10__default.default.relative(path10__default.default.join(rootDir, "public"), imagePath);
24720
+ const filename = path12__default.default.basename(imagePath);
24721
+ const relPath = path12__default.default.relative(path12__default.default.join(rootDir, "public"), imagePath);
24657
24722
  const patterns = [
24658
24723
  `/${relPath}`,
24659
24724
  // /images/hero.jpg
@@ -24675,7 +24740,7 @@ async function findImageUsages(imagePath, sourceFiles, rootDir) {
24675
24740
  const elementType = detectElementType(line);
24676
24741
  const canAutoMigrate = ["img", "Image"].includes(elementType);
24677
24742
  usages.push({
24678
- filePath: path10__default.default.relative(rootDir, sourceFile),
24743
+ filePath: path12__default.default.relative(rootDir, sourceFile),
24679
24744
  line: i + 1,
24680
24745
  elementType,
24681
24746
  altText: extractAltText(line),
@@ -24747,7 +24812,7 @@ function detectCriticalImage(filename, relPath, usages, fileSize) {
24747
24812
  (u) => u.filePath.includes("layout.") || u.filePath.includes("/layout/")
24748
24813
  );
24749
24814
  const usedInCriticalComponent = usages.some((u) => {
24750
- const fileName = path10__default.default.basename(u.filePath).toLowerCase();
24815
+ const fileName = path12__default.default.basename(u.filePath).toLowerCase();
24751
24816
  return fileName.includes("header") || fileName.includes("navbar") || fileName.includes("nav.") || fileName.includes("hero") || fileName.includes("footer");
24752
24817
  });
24753
24818
  const isSiteLogo = SITE_LOGO_PATTERNS.some((p) => p.test(filename));
@@ -24883,7 +24948,7 @@ async function uploadAndMigrateImages(scanResults, options) {
24883
24948
  for (const img of scanResults.images) {
24884
24949
  try {
24885
24950
  const uploadResult = await uploadImageToPortal(
24886
- path10__default.default.join(rootDir, img.filePath),
24951
+ path12__default.default.join(rootDir, img.filePath),
24887
24952
  img,
24888
24953
  {
24889
24954
  apiUrl: options.apiUrl,
@@ -24911,7 +24976,7 @@ async function uploadAndMigrateImages(scanResults, options) {
24911
24976
  }
24912
24977
  for (const [filePath, migrations] of byFile) {
24913
24978
  try {
24914
- await migrateFileImages(path10__default.default.join(rootDir, filePath), migrations);
24979
+ await migrateFileImages(path12__default.default.join(rootDir, filePath), migrations);
24915
24980
  result.migrated += migrations.length;
24916
24981
  } catch (error2) {
24917
24982
  result.errors.push(`Migration failed for ${filePath}: ${error2.message}`);
@@ -24925,31 +24990,25 @@ async function migrateCommand(options) {
24925
24990
  console.log("");
24926
24991
  console.log(source_default.bold(" Site-Kit Migration"));
24927
24992
  console.log("");
24928
- const apiKey = process.env.SONOR_API_KEY;
24929
- const projectId = process.env.SONOR_PROJECT_ID;
24930
- if (!apiKey || !projectId) {
24931
- console.log(source_default.red(" \u2717 Missing environment variables"));
24932
- console.log(source_default.gray(" Run `sonor-setup init` first to configure your project."));
24933
- console.log("");
24934
- process.exit(1);
24935
- }
24993
+ const { apiKey, projectId, apiUrl } = await loadConfig({ resolveProject: true });
24936
24994
  if (options.dryRun) {
24937
24995
  console.log(source_default.yellow(" Running in dry-run mode - no files will be modified"));
24938
24996
  console.log("");
24939
24997
  }
24940
24998
  if (options.file) {
24941
- const filePath = path10__default.default.resolve(options.file);
24999
+ const filePath = path12__default.default.resolve(options.file);
24942
25000
  try {
24943
25001
  await fs3__default.default.access(filePath);
24944
25002
  } catch {
24945
25003
  console.log(source_default.red(` \u2717 File not found: ${filePath}`));
24946
25004
  process.exit(1);
24947
25005
  }
24948
- const spinner = ora(`Migrating ${path10__default.default.basename(filePath)}...`).start();
25006
+ const spinner = ora(`Migrating ${path12__default.default.basename(filePath)}...`).start();
24949
25007
  try {
24950
25008
  const result = await migrateFile(filePath, {
24951
25009
  projectId,
24952
25010
  apiKey,
25011
+ apiUrl,
24953
25012
  dryRun: options.dryRun
24954
25013
  });
24955
25014
  if (result.success) {
@@ -25012,6 +25071,7 @@ async function migrateCommand(options) {
25012
25071
  const results = await migrateFiles(scanResults, {
25013
25072
  projectId,
25014
25073
  apiKey,
25074
+ apiUrl,
25015
25075
  dryRun: options.dryRun
25016
25076
  });
25017
25077
  const successful = results.filter((r) => r.success);
@@ -25041,10 +25101,9 @@ async function migrateCommand(options) {
25041
25101
  process.exit(1);
25042
25102
  }
25043
25103
  console.log("");
25044
- await handleImageMigration(options, apiKey);
25104
+ await handleImageMigration(options, apiKey, apiUrl);
25045
25105
  }
25046
- async function handleImageMigration(options, apiKey, projectId) {
25047
- const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
25106
+ async function handleImageMigration(options, apiKey, apiUrl) {
25048
25107
  const imageScanSpinner = ora("Scanning for images...").start();
25049
25108
  let imageResults;
25050
25109
  try {
@@ -25108,17 +25167,11 @@ function formatBytes2(bytes) {
25108
25167
  return `${parseFloat((bytes / Math.pow(k2, i)).toFixed(1))} ${sizes[i]}`;
25109
25168
  }
25110
25169
  var SKIP_PROPS = ["href", "src", "className", "style", "onClick", "ref", "key", "id", "target", "rel", "type", "name", "variant", "size", "icon"];
25111
- var API_URL2 = process.env.SONOR_API_URL || "https://api.sonor.io";
25112
- var TEMPLATES_DIR = ".uptrade/templates";
25170
+ var TEMPLATES_DIR = path12__default.default.join(SONOR_STATE_DIR, "templates");
25113
25171
  async function locationsCommand(subcommand, arg, options) {
25114
25172
  console.log("");
25115
25173
  console.log(source_default.bold(" \u{1F4CD} Site-Kit Location Page Manager"));
25116
25174
  console.log("");
25117
- const config2 = await loadConfig();
25118
- if (!config2?.projectId) {
25119
- console.log(source_default.red(" \u2717 Not configured. Run `npx sonor-setup init` first."));
25120
- return;
25121
- }
25122
25175
  switch (subcommand) {
25123
25176
  case "template":
25124
25177
  if (!arg) {
@@ -25126,6 +25179,7 @@ async function locationsCommand(subcommand, arg, options) {
25126
25179
  console.log(source_default.gray(" Example: locations template ./app/services/plumbing/page.tsx"));
25127
25180
  return;
25128
25181
  }
25182
+ await loadConfig();
25129
25183
  await templateCommand(arg, options);
25130
25184
  break;
25131
25185
  case "upload":
@@ -25133,17 +25187,17 @@ async function locationsCommand(subcommand, arg, options) {
25133
25187
  console.log(source_default.red(" \u2717 Usage: locations upload --template <name>"));
25134
25188
  return;
25135
25189
  }
25136
- await uploadCommand(options.template, config2);
25190
+ await uploadCommand(options.template, await loadConfig({ resolveProject: true }));
25137
25191
  break;
25138
25192
  case "generate":
25139
25193
  if (!options.template) {
25140
25194
  console.log(source_default.red(' \u2717 Usage: locations generate --template <name> --locations "City, ST" ...'));
25141
25195
  return;
25142
25196
  }
25143
- await generateCommand(options, config2);
25197
+ await generateCommand(options, await loadConfig({ resolveProject: true }));
25144
25198
  break;
25145
25199
  case "list":
25146
- await listCommand(config2);
25200
+ await listCommand(await loadConfig({ resolveProject: true }));
25147
25201
  break;
25148
25202
  default:
25149
25203
  console.log(source_default.yellow(" Available subcommands:"));
@@ -25155,10 +25209,10 @@ async function locationsCommand(subcommand, arg, options) {
25155
25209
  console.log("");
25156
25210
  }
25157
25211
  }
25158
- async function templateCommand(sourcePath, options, config2) {
25212
+ async function templateCommand(sourcePath, options) {
25159
25213
  const spinner = ora("Analyzing source page...").start();
25160
25214
  try {
25161
- const resolvedPath = path10__default.default.resolve(sourcePath);
25215
+ const resolvedPath = path12__default.default.resolve(sourcePath);
25162
25216
  if (!fs.existsSync(resolvedPath)) {
25163
25217
  spinner.fail(`File not found: ${sourcePath}`);
25164
25218
  return;
@@ -25171,8 +25225,8 @@ async function templateCommand(sourcePath, options, config2) {
25171
25225
  const slots = [];
25172
25226
  const componentNames = [];
25173
25227
  chunkJS75ORH7_js.traverse(ast, {
25174
- JSXElement(path27) {
25175
- const openingElement = path27.node.openingElement;
25228
+ JSXElement(path30) {
25229
+ const openingElement = path30.node.openingElement;
25176
25230
  if (chunkJS75ORH7_js.isJSXIdentifier(openingElement.name)) {
25177
25231
  const componentName = openingElement.name.name;
25178
25232
  if (componentName[0] === componentName[0].toUpperCase()) {
@@ -25212,8 +25266,9 @@ async function templateCommand(sourcePath, options, config2) {
25212
25266
  },
25213
25267
  managed_components: ["schema", "faqs", "metadata"]
25214
25268
  };
25215
- await fs3__default.default.mkdir(TEMPLATES_DIR, { recursive: true });
25216
- const templatePath = path10__default.default.join(TEMPLATES_DIR, `${templateName}.json`);
25269
+ const templatesDir = path12__default.default.join(process.cwd(), TEMPLATES_DIR);
25270
+ await fs3__default.default.mkdir(templatesDir, { recursive: true });
25271
+ const templatePath = path12__default.default.join(templatesDir, `${templateName}.json`);
25217
25272
  await fs3__default.default.writeFile(templatePath, JSON.stringify(template, null, 2));
25218
25273
  console.log("");
25219
25274
  console.log(source_default.green(" \u2713 Template created:"), source_default.cyan(templatePath));
@@ -25292,7 +25347,7 @@ function inferGenerationHint(propName) {
25292
25347
  return void 0;
25293
25348
  }
25294
25349
  function inferTemplateName(sourcePath) {
25295
- const parts = sourcePath.split(path10__default.default.sep);
25350
+ const parts = sourcePath.split(path12__default.default.sep);
25296
25351
  const pageIndex = parts.findIndex((p) => p === "page.tsx" || p === "page.jsx");
25297
25352
  if (pageIndex > 0) {
25298
25353
  return parts[pageIndex - 1];
@@ -25301,14 +25356,14 @@ function inferTemplateName(sourcePath) {
25301
25356
  return filtered[filtered.length - 1] || "template";
25302
25357
  }
25303
25358
  function inferSourcePagePath(sourcePath) {
25304
- const parts = sourcePath.split(path10__default.default.sep);
25359
+ const parts = sourcePath.split(path12__default.default.sep);
25305
25360
  const appIndex = parts.findIndex((p) => p === "app" || p === "pages");
25306
25361
  if (appIndex >= 0) {
25307
25362
  const pathParts = parts.slice(appIndex + 1);
25308
25363
  const filtered = pathParts.filter((p) => !["page.tsx", "page.jsx", "index.tsx", "index.jsx"].includes(p));
25309
25364
  return "/" + filtered.join("/");
25310
25365
  }
25311
- return "/" + path10__default.default.basename(sourcePath, path10__default.default.extname(sourcePath));
25366
+ return "/" + path12__default.default.basename(sourcePath, path12__default.default.extname(sourcePath));
25312
25367
  }
25313
25368
  function toSnakeCase(str) {
25314
25369
  return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
@@ -25320,22 +25375,22 @@ function truncate(str, maxLength) {
25320
25375
  async function uploadCommand(templateName, config2) {
25321
25376
  const spinner = ora("Uploading template to Portal...").start();
25322
25377
  try {
25323
- const templatePath = path10__default.default.join(TEMPLATES_DIR, `${templateName}.json`);
25378
+ const templatePath = resolveStateReadPath(path12__default.default.join("templates", `${templateName}.json`));
25324
25379
  if (!fs.existsSync(templatePath)) {
25325
25380
  spinner.fail(`Template not found: ${templatePath}`);
25326
25381
  console.log(source_default.gray(` Run: npx sonor-setup locations template <page> --name ${templateName}`));
25327
25382
  return;
25328
25383
  }
25329
25384
  const template = JSON.parse(fs.readFileSync(templatePath, "utf-8"));
25330
- const response = await fetch(`${API_URL2}/seo/location-templates`, {
25385
+ const response = await fetch(`${config2.apiUrl}/seo/location-templates`, {
25331
25386
  method: "POST",
25332
25387
  headers: {
25333
25388
  "Content-Type": "application/json",
25334
25389
  "Authorization": `Bearer ${config2.apiKey}`
25335
25390
  },
25336
25391
  body: JSON.stringify({
25337
- project_id: config2.projectId,
25338
- ...template
25392
+ ...template,
25393
+ project_id: config2.projectId
25339
25394
  })
25340
25395
  });
25341
25396
  if (!response.ok) {
@@ -25343,11 +25398,11 @@ async function uploadCommand(templateName, config2) {
25343
25398
  if (response.status === 409) {
25344
25399
  spinner.text = "Template exists, updating...";
25345
25400
  const existing = await fetch(
25346
- `${API_URL2}/seo/location-templates/by-name/${templateName}?project_id=${config2.projectId}`,
25401
+ `${config2.apiUrl}/seo/location-templates/by-name/${templateName}?project_id=${config2.projectId}`,
25347
25402
  { headers: { "Authorization": `Bearer ${config2.apiKey}` } }
25348
25403
  );
25349
25404
  const existingData = await existing.json();
25350
- const updateResponse = await fetch(`${API_URL2}/seo/location-templates/${existingData.id}`, {
25405
+ const updateResponse = await fetch(`${config2.apiUrl}/seo/location-templates/${existingData.id}`, {
25351
25406
  method: "PUT",
25352
25407
  headers: {
25353
25408
  "Content-Type": "application/json",
@@ -25396,7 +25451,7 @@ async function generateCommand(options, config2) {
25396
25451
  }
25397
25452
  const spinner = ora(`Generating ${type || "service-location"} pages...`).start();
25398
25453
  try {
25399
- const response = await fetch(`${API_URL2}/seo/location-pages/generate`, {
25454
+ const response = await fetch(`${config2.apiUrl}/seo/location-pages/generate`, {
25400
25455
  method: "POST",
25401
25456
  headers: {
25402
25457
  "Content-Type": "application/json",
@@ -25436,7 +25491,7 @@ async function listCommand(config2) {
25436
25491
  const spinner = ora("Fetching templates...").start();
25437
25492
  try {
25438
25493
  const response = await fetch(
25439
- `${API_URL2}/seo/location-templates?project_id=${config2.projectId}`,
25494
+ `${config2.apiUrl}/seo/location-templates?project_id=${config2.projectId}`,
25440
25495
  { headers: { "Authorization": `Bearer ${config2.apiKey}` } }
25441
25496
  );
25442
25497
  if (!response.ok) {
@@ -25461,69 +25516,21 @@ async function listCommand(config2) {
25461
25516
  });
25462
25517
  }
25463
25518
  console.log("");
25464
- if (fs.existsSync(TEMPLATES_DIR)) {
25465
- const files = await fs3__default.default.readdir(TEMPLATES_DIR);
25466
- const localTemplates = files.filter((f) => f.endsWith(".json"));
25467
- if (localTemplates.length > 0) {
25468
- console.log(source_default.gray(" Local (not uploaded):"));
25469
- localTemplates.forEach((f) => {
25470
- console.log(source_default.gray(` \u2022 ${f.replace(".json", "")}`));
25471
- });
25472
- console.log("");
25473
- }
25519
+ const localTemplates = await listLocalTemplates();
25520
+ if (localTemplates.length > 0) {
25521
+ console.log(source_default.gray(" Local (not uploaded):"));
25522
+ localTemplates.forEach((f) => {
25523
+ console.log(source_default.gray(` \u2022 ${f.replace(".json", "")}`));
25524
+ });
25525
+ console.log("");
25474
25526
  }
25475
25527
  } catch (error2) {
25476
25528
  spinner.fail(`Failed to fetch templates: ${error2.message}`);
25477
25529
  }
25478
25530
  }
25479
- async function loadConfig() {
25480
- const configPath = path10__default.default.join(".uptrade", "config.json");
25481
- if (fs.existsSync(configPath)) {
25482
- try {
25483
- const config2 = JSON.parse(fs.readFileSync(configPath, "utf-8"));
25484
- return {
25485
- projectId: config2.projectId || config2.project_id,
25486
- apiKey: config2.apiKey || config2.api_key
25487
- };
25488
- } catch {
25489
- return null;
25490
- }
25491
- }
25492
- const projectId = process.env.SONOR_PROJECT_ID;
25493
- const apiKey = process.env.SONOR_API_KEY;
25494
- if (projectId && apiKey) {
25495
- return { projectId, apiKey };
25496
- }
25497
- return null;
25498
- }
25499
- var API_URL3 = process.env.SONOR_API_URL || "https://api.sonor.io";
25500
- async function loadConfig2() {
25501
- const configPath = path10__default.default.join(".uptrade", "config.json");
25502
- if (fs.existsSync(configPath)) {
25503
- try {
25504
- const config2 = JSON.parse(fs.readFileSync(configPath, "utf-8"));
25505
- return {
25506
- projectId: config2.projectId || config2.project_id,
25507
- apiKey: config2.apiKey || config2.api_key
25508
- };
25509
- } catch {
25510
- return null;
25511
- }
25512
- }
25513
- const projectId = process.env.SONOR_PROJECT_ID;
25514
- const apiKey = process.env.SONOR_API_KEY;
25515
- if (projectId && apiKey) return { projectId, apiKey };
25516
- return null;
25517
- }
25518
25531
  async function faqsCommand(subcommand, options) {
25519
25532
  console.log("");
25520
- const config2 = await loadConfig2();
25521
- if (!config2?.projectId || !config2?.apiKey) {
25522
- console.log(source_default.red(" \u2717 Not configured. Run `npx sonor-setup init` first."));
25523
- console.log(source_default.gray(" Set SONOR_API_KEY, or use .uptrade/config.json"));
25524
- console.log("");
25525
- return;
25526
- }
25533
+ const config2 = await loadConfig({ resolveProject: true });
25527
25534
  switch (subcommand) {
25528
25535
  case "extract":
25529
25536
  await extractCommand(options, config2);
@@ -25573,7 +25580,7 @@ async function extractCommand(options, config2) {
25573
25580
  const faqContexts = [];
25574
25581
  for (const faq of faqSections) {
25575
25582
  try {
25576
- const fullPath = path10__default.default.resolve(process.cwd(), faq.filePath);
25583
+ const fullPath = path12__default.default.resolve(process.cwd(), faq.filePath);
25577
25584
  const content = await fs3__default.default.readFile(fullPath, "utf-8");
25578
25585
  let pagePath = faq.filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
25579
25586
  if (pagePath === "" || pagePath === "/page") pagePath = "/";
@@ -25588,7 +25595,7 @@ async function extractCommand(options, config2) {
25588
25595
  if (importPath.startsWith("@/")) {
25589
25596
  resolvedPath = importPath.replace("@/", "./");
25590
25597
  } else if (importPath.startsWith(".")) {
25591
- resolvedPath = path10__default.default.resolve(path10__default.default.dirname(fullPath), importPath);
25598
+ resolvedPath = path12__default.default.resolve(path12__default.default.dirname(fullPath), importPath);
25592
25599
  }
25593
25600
  const extensions = ["", ".js", ".ts", ".jsx", ".tsx", ".json"];
25594
25601
  for (const ext2 of extensions) {
@@ -25633,7 +25640,7 @@ async function extractCommand(options, config2) {
25633
25640
  }
25634
25641
  const extractSpinner = ora("Extracting FAQs via AI...").start();
25635
25642
  try {
25636
- const response = await fetch(`${API_URL3}/seo/managed/faqs/extract`, {
25643
+ const response = await fetch(`${config2.apiUrl}/seo/managed/faqs/extract`, {
25637
25644
  method: "POST",
25638
25645
  headers: {
25639
25646
  "Content-Type": "application/json",
@@ -25668,7 +25675,7 @@ async function extractCommand(options, config2) {
25668
25675
  let failed = 0;
25669
25676
  for (const faq of extractedFaqs) {
25670
25677
  try {
25671
- const res = await fetch(`${API_URL3}/seo/managed/faqs`, {
25678
+ const res = await fetch(`${config2.apiUrl}/seo/managed/faqs`, {
25672
25679
  method: "POST",
25673
25680
  headers: {
25674
25681
  "Content-Type": "application/json",
@@ -25693,7 +25700,7 @@ async function extractCommand(options, config2) {
25693
25700
  uploaded++;
25694
25701
  console.log(source_default.green(` \u2713 ${faq.path}`) + source_default.gray(` (${faq.items.length} items)`));
25695
25702
  } else if (res.status === 409 || res.status === 400) {
25696
- const updateRes = await fetch(`${API_URL3}/seo/managed/faqs/by-path`, {
25703
+ const updateRes = await fetch(`${config2.apiUrl}/seo/managed/faqs/by-path`, {
25697
25704
  method: "PUT",
25698
25705
  headers: {
25699
25706
  "Content-Type": "application/json",
@@ -25780,7 +25787,7 @@ async function syncCommand(options, config2) {
25780
25787
  const listSpinner = ora("Fetching existing FAQ sections from Portal...").start();
25781
25788
  let existing = [];
25782
25789
  try {
25783
- const res = await fetch(`${API_URL3}/seo/managed/faqs/project/${config2.projectId}`, {
25790
+ const res = await fetch(`${config2.apiUrl}/seo/managed/faqs/project/${config2.projectId}`, {
25784
25791
  headers: { Authorization: `Bearer ${config2.apiKey}` }
25785
25792
  });
25786
25793
  if (!res.ok) {
@@ -25809,7 +25816,7 @@ async function syncCommand(options, config2) {
25809
25816
  let failed = 0;
25810
25817
  for (const p of toCreate) {
25811
25818
  try {
25812
- const res = await fetch(`${API_URL3}/seo/managed/faqs`, {
25819
+ const res = await fetch(`${config2.apiUrl}/seo/managed/faqs`, {
25813
25820
  method: "POST",
25814
25821
  headers: {
25815
25822
  "Content-Type": "application/json",
@@ -25846,44 +25853,12 @@ async function syncCommand(options, config2) {
25846
25853
  console.log(source_default.gray(" Add questions and answers there; they will appear on your site."));
25847
25854
  console.log("");
25848
25855
  }
25849
- function getApiUrl() {
25850
- return process.env.SONOR_API_URL || "https://api.sonor.io";
25851
- }
25852
- async function loadConfig3() {
25853
- const configPath = path10__default.default.join(".uptrade", "config.json");
25854
- if (fs.existsSync(configPath)) {
25855
- try {
25856
- const config2 = JSON.parse(fs.readFileSync(configPath, "utf-8"));
25857
- return {
25858
- projectId: config2.projectId || config2.project_id,
25859
- apiKey: config2.apiKey || config2.api_key,
25860
- siteUrl: config2.siteUrl || config2.site_url,
25861
- businessInfo: config2.businessInfo || config2.business_info
25862
- };
25863
- } catch {
25864
- return null;
25865
- }
25866
- }
25867
- const projectId = process.env.SONOR_PROJECT_ID;
25868
- const apiKey = process.env.SONOR_API_KEY;
25869
- const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || process.env.SITE_URL;
25870
- if (projectId && apiKey) {
25871
- return { projectId, apiKey, siteUrl };
25872
- }
25873
- return null;
25874
- }
25875
25856
  async function setupCommand(options) {
25876
25857
  console.log("");
25877
25858
  console.log(source_default.bold.blue(" \u{1F680} Signal-Enhanced SEO Setup"));
25878
25859
  console.log(source_default.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
25879
25860
  console.log("");
25880
- const config2 = await loadConfig3();
25881
- if (!config2?.projectId || !config2?.apiKey) {
25882
- console.log(source_default.red(" \u2717 Not configured. Run `npx sonor-setup init` first."));
25883
- console.log(source_default.gray(" Set SONOR_API_KEY"));
25884
- console.log("");
25885
- return;
25886
- }
25861
+ const config2 = await loadConfig();
25887
25862
  const capabilities = [];
25888
25863
  if (options.faqsOnly) {
25889
25864
  capabilities.push("extract_faqs");
@@ -25981,14 +25956,13 @@ async function setupCommand(options) {
25981
25956
  const batch = batches[batchIndex];
25982
25957
  const batchSpinner = ora(`Batch ${batchIndex + 1}/${batches.length}: Analyzing ${batch.length} pages...`).start();
25983
25958
  try {
25984
- const response = await fetch(`${getApiUrl()}/api/public/seo/site-setup`, {
25959
+ const response = await fetch(`${config2.apiUrl}/api/public/seo/site-setup`, {
25985
25960
  method: "POST",
25986
25961
  headers: {
25987
25962
  "Content-Type": "application/json",
25988
25963
  "x-api-key": config2.apiKey
25989
25964
  },
25990
25965
  body: JSON.stringify({
25991
- project_id: config2.projectId,
25992
25966
  site_url: config2.siteUrl || "https://example.com",
25993
25967
  // Only send business_info on first batch (for org schema)
25994
25968
  business_info: batchIndex === 0 ? config2.businessInfo : void 0,
@@ -26080,10 +26054,10 @@ async function setupCommand(options) {
26080
26054
  }
26081
26055
  async function scanForPageFiles(rootDir) {
26082
26056
  const pages = [];
26083
- const appDir = path10__default.default.join(rootDir, "app");
26084
- const srcAppDir = path10__default.default.join(rootDir, "src", "app");
26085
- const pagesDir = path10__default.default.join(rootDir, "pages");
26086
- const srcPagesDir = path10__default.default.join(rootDir, "src", "pages");
26057
+ const appDir = path12__default.default.join(rootDir, "app");
26058
+ const srcAppDir = path12__default.default.join(rootDir, "src", "app");
26059
+ const pagesDir = path12__default.default.join(rootDir, "pages");
26060
+ const srcPagesDir = path12__default.default.join(rootDir, "src", "pages");
26087
26061
  const dirs = [appDir, srcAppDir, pagesDir, srcPagesDir];
26088
26062
  for (const dir of dirs) {
26089
26063
  if (fs.existsSync(dir)) {
@@ -26095,7 +26069,7 @@ async function scanForPageFiles(rootDir) {
26095
26069
  async function scanDirectory(dir, baseDir, pages) {
26096
26070
  const entries = await fs3__default.default.readdir(dir, { withFileTypes: true });
26097
26071
  for (const entry of entries) {
26098
- const fullPath = path10__default.default.join(dir, entry.name);
26072
+ const fullPath = path12__default.default.join(dir, entry.name);
26099
26073
  if (entry.isDirectory()) {
26100
26074
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "api") {
26101
26075
  continue;
@@ -26106,8 +26080,8 @@ async function scanDirectory(dir, baseDir, pages) {
26106
26080
  const isLegacyPage = baseDir.includes("/pages") && entry.name.match(/\.(tsx?|jsx?)$/) && !entry.name.startsWith("_");
26107
26081
  if (isPage || isLegacyPage) {
26108
26082
  const content = await fs3__default.default.readFile(fullPath, "utf-8");
26109
- const relativePath = path10__default.default.relative(baseDir, fullPath);
26110
- let pagePath = "/" + path10__default.default.dirname(relativePath).replace(/\\/g, "/").replace(/\/page$/, "");
26083
+ const relativePath = path12__default.default.relative(baseDir, fullPath);
26084
+ let pagePath = "/" + path12__default.default.dirname(relativePath).replace(/\\/g, "/").replace(/\/page$/, "");
26111
26085
  pagePath = pagePath.replace(/\[([^\]]+)\]/g, ":$1").replace(/^\/\.$/, "/");
26112
26086
  if (pagePath === "/.") pagePath = "/";
26113
26087
  pages.push({
@@ -26127,10 +26101,10 @@ async function gatherImportedFiles(page, rootDir) {
26127
26101
  if (importPath.toLowerCase().includes("faq") || importPath.includes("@/data") || importPath.includes("./data") || importPath.includes("../data") || importPath.includes("/constants") || importPath.includes("/content") || importPath.includes("practice-areas") || importPath.includes("subpages") || importPath.includes("pages-data")) {
26128
26102
  let resolvedPath = importPath;
26129
26103
  if (importPath.startsWith("@/")) {
26130
- resolvedPath = path10__default.default.join(rootDir, importPath.replace("@/", ""));
26104
+ resolvedPath = path12__default.default.join(rootDir, importPath.replace("@/", ""));
26131
26105
  } else if (importPath.startsWith(".")) {
26132
- const pageDir = path10__default.default.dirname(path10__default.default.join(rootDir, "app", page.filePath));
26133
- resolvedPath = path10__default.default.resolve(pageDir, importPath);
26106
+ const pageDir = path12__default.default.dirname(path12__default.default.join(rootDir, "app", page.filePath));
26107
+ resolvedPath = path12__default.default.resolve(pageDir, importPath);
26134
26108
  }
26135
26109
  const extensions = ["", ".js", ".ts", ".jsx", ".tsx", ".json"];
26136
26110
  for (const ext2 of extensions) {
@@ -26186,20 +26160,20 @@ async function expandDynamicRoutes(pages, rootDir) {
26186
26160
  async function findDynamicRouteData(page, parentPath, rootDir) {
26187
26161
  const results = [];
26188
26162
  const dataFilePaths = [
26189
- path10__default.default.join(rootDir, "data", "practice-areas.js"),
26190
- path10__default.default.join(rootDir, "data", "practice-areas.ts"),
26191
- path10__default.default.join(rootDir, "data", "personal-injury-pages.js"),
26192
- path10__default.default.join(rootDir, "data", "personal-injury-pages.ts"),
26193
- path10__default.default.join(rootDir, "data", "pages.js"),
26194
- path10__default.default.join(rootDir, "data", "pages.ts"),
26195
- path10__default.default.join(rootDir, "data", "content.js"),
26196
- path10__default.default.join(rootDir, "data", "content.ts"),
26197
- path10__default.default.join(rootDir, "data", "services.js"),
26198
- path10__default.default.join(rootDir, "data", "services.ts"),
26199
- path10__default.default.join(rootDir, "data", "subpages.js"),
26200
- path10__default.default.join(rootDir, "data", "subpages.ts"),
26201
- path10__default.default.join(rootDir, "src", "data", "practice-areas.js"),
26202
- path10__default.default.join(rootDir, "src", "data", "practice-areas.ts")
26163
+ path12__default.default.join(rootDir, "data", "practice-areas.js"),
26164
+ path12__default.default.join(rootDir, "data", "practice-areas.ts"),
26165
+ path12__default.default.join(rootDir, "data", "personal-injury-pages.js"),
26166
+ path12__default.default.join(rootDir, "data", "personal-injury-pages.ts"),
26167
+ path12__default.default.join(rootDir, "data", "pages.js"),
26168
+ path12__default.default.join(rootDir, "data", "pages.ts"),
26169
+ path12__default.default.join(rootDir, "data", "content.js"),
26170
+ path12__default.default.join(rootDir, "data", "content.ts"),
26171
+ path12__default.default.join(rootDir, "data", "services.js"),
26172
+ path12__default.default.join(rootDir, "data", "services.ts"),
26173
+ path12__default.default.join(rootDir, "data", "subpages.js"),
26174
+ path12__default.default.join(rootDir, "data", "subpages.ts"),
26175
+ path12__default.default.join(rootDir, "src", "data", "practice-areas.js"),
26176
+ path12__default.default.join(rootDir, "src", "data", "practice-areas.ts")
26203
26177
  ];
26204
26178
  const routeSegment = parentPath.replace(/^\//, "").split("/")[0];
26205
26179
  const routeSegmentNormalized = routeSegment.replace(/-/g, "");
@@ -26291,7 +26265,7 @@ async function uploadFaqs(pages, config2) {
26291
26265
  for (const page of pages) {
26292
26266
  if (!page.faqs?.items?.length) continue;
26293
26267
  try {
26294
- const res = await fetch(`${getApiUrl()}/api/public/seo/register-faq`, {
26268
+ const res = await fetch(`${config2.apiUrl}/api/public/seo/register-faq`, {
26295
26269
  method: "POST",
26296
26270
  headers: {
26297
26271
  "Content-Type": "application/json",
@@ -26326,7 +26300,7 @@ async function uploadFaqs(pages, config2) {
26326
26300
  async function uploadSchemas(pages, globalSchema, config2) {
26327
26301
  if (globalSchema) {
26328
26302
  try {
26329
- const res = await fetch(`${getApiUrl()}/api/public/seo/register-schema`, {
26303
+ const res = await fetch(`${config2.apiUrl}/api/public/seo/register-schema`, {
26330
26304
  method: "POST",
26331
26305
  headers: {
26332
26306
  "Content-Type": "application/json",
@@ -26352,7 +26326,7 @@ async function uploadSchemas(pages, globalSchema, config2) {
26352
26326
  if (!page.schemas?.length) continue;
26353
26327
  for (const schema of page.schemas) {
26354
26328
  try {
26355
- const res = await fetch(`${getApiUrl()}/api/public/seo/register-schema`, {
26329
+ const res = await fetch(`${config2.apiUrl}/api/public/seo/register-schema`, {
26356
26330
  method: "POST",
26357
26331
  headers: {
26358
26332
  "Content-Type": "application/json",
@@ -26376,8 +26350,7 @@ async function uploadSchemas(pages, globalSchema, config2) {
26376
26350
  }
26377
26351
  }
26378
26352
  }
26379
- var APP_DIRS = ["app", path10__default.default.join("src", "app")];
26380
- var CARD_FILE = /^(opengraph-image|twitter-image)\b.*\.(png|jpe?g|gif|webp)$/i;
26353
+ var CARD_FILE = /^(opengraph-image|twitter-image)\b.*\.(png|jpe?g|gif|webp|tsx|ts|jsx|js)$/i;
26381
26354
  function safeExists(p) {
26382
26355
  try {
26383
26356
  return fs__namespace.default.existsSync(p);
@@ -26396,19 +26369,19 @@ function findPageCards(cwd) {
26396
26369
  }
26397
26370
  for (const entry of entries) {
26398
26371
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
26399
- const full = path10__default.default.join(dir, entry.name);
26372
+ const full = path12__default.default.join(dir, entry.name);
26400
26373
  if (entry.isDirectory()) walk(full);
26401
26374
  else if (CARD_FILE.test(entry.name)) found.push(full);
26402
26375
  }
26403
26376
  };
26404
- for (const rel of APP_DIRS) walk(path10__default.default.join(cwd, rel));
26377
+ for (const rel of chunkP4TB4ROG_js.NEXT_APP_DIRS) walk(path12__default.default.join(cwd, rel));
26405
26378
  return found;
26406
26379
  }
26407
26380
  function readOgWiring(cwd) {
26408
26381
  const siteCard = ["public/og.png", "public/og.jpg", "public/opengraph.png"].some(
26409
- (rel) => safeExists(path10__default.default.join(cwd, rel))
26382
+ (rel) => safeExists(path12__default.default.join(cwd, rel))
26410
26383
  );
26411
- const layoutPath = ["app/layout.tsx", "src/app/layout.tsx"].map((rel) => path10__default.default.join(cwd, rel)).find(safeExists);
26384
+ const layoutPath = chunkP4TB4ROG_js.findRootLayout(cwd);
26412
26385
  let layout = "";
26413
26386
  if (layoutPath) {
26414
26387
  try {
@@ -26428,7 +26401,12 @@ function readOgWiring(cwd) {
26428
26401
  function judgeOgWiring(facts) {
26429
26402
  const problems = [];
26430
26403
  if (!facts.layoutFound) {
26431
- return [{ message: "no app/layout.tsx found to verify metadata", fix: "Run this from the site root." }];
26404
+ return [
26405
+ {
26406
+ message: "no root layout (app/layout.{tsx,ts,jsx,js} or src/app/layout.*) found to verify metadata",
26407
+ fix: "Run this from the site root."
26408
+ }
26409
+ ];
26432
26410
  }
26433
26411
  if (!facts.siteCard && !facts.pageCards.length) {
26434
26412
  return [
@@ -26475,7 +26453,7 @@ var SSR_BAILOUT_FIX = `Keep the layout: ${LAYOUT_ALREADY_DEFERS}, so it is not t
26475
26453
  var ANALYTICS_WRAPPER_FIX = `Remove the <AnalyticsProvider> wrapper: ${LAYOUT_ALREADY_DEFERS} (configure it with analytics={{ ... }}). Track custom events with trackEvent / trackConversion from @sonordev/site-kit/analytics, which need no provider, instead of useAnalytics(). ` + LEGACY_STOPGAP;
26476
26454
 
26477
26455
  // src/cli/agent/checks.ts
26478
- var API_URL4 = process.env.SONOR_API_URL || "https://api.sonor.io";
26456
+ var API_URL = process.env.SONOR_API_URL || "https://api.sonor.io";
26479
26457
  async function readFileOrNull(p) {
26480
26458
  try {
26481
26459
  return await fs3__default.default.readFile(p, "utf-8");
@@ -26483,26 +26461,6 @@ async function readFileOrNull(p) {
26483
26461
  return null;
26484
26462
  }
26485
26463
  }
26486
- async function findFirst(cwd, candidates) {
26487
- for (const rel of candidates) {
26488
- const full = path10__default.default.join(cwd, rel);
26489
- if (await readFileOrNull(full)) return full;
26490
- }
26491
- return null;
26492
- }
26493
- var LAYOUT_CANDIDATES = [
26494
- "app/layout.tsx",
26495
- "app/layout.jsx",
26496
- "src/app/layout.tsx",
26497
- "src/app/layout.jsx"
26498
- ];
26499
- var SITEMAP_CANDIDATES = [
26500
- "app/sitemap.ts",
26501
- "app/sitemap.tsx",
26502
- "app/sitemap.js",
26503
- "src/app/sitemap.ts",
26504
- "src/app/sitemap.tsx"
26505
- ];
26506
26464
  function checkApiKeyEnv() {
26507
26465
  const key = process.env.SONOR_API_KEY;
26508
26466
  if (key && key.startsWith("sonor_")) {
@@ -26537,7 +26495,7 @@ function checkApiKeyEnv() {
26537
26495
  };
26538
26496
  }
26539
26497
  async function checkPackageInstalled(cwd) {
26540
- const raw = await readFileOrNull(path10__default.default.join(cwd, "package.json"));
26498
+ const raw = await readFileOrNull(path12__default.default.join(cwd, "package.json"));
26541
26499
  if (!raw) {
26542
26500
  return {
26543
26501
  id: "package.installed",
@@ -26589,7 +26547,7 @@ async function checkPackageInstalled(cwd) {
26589
26547
  };
26590
26548
  }
26591
26549
  async function checkSiteKitLayout(cwd) {
26592
- const layoutPath = await findFirst(cwd, LAYOUT_CANDIDATES);
26550
+ const layoutPath = chunkP4TB4ROG_js.findRootLayout(cwd);
26593
26551
  if (!layoutPath) {
26594
26552
  return {
26595
26553
  id: "layout.sitekit",
@@ -26601,7 +26559,7 @@ async function checkSiteKitLayout(cwd) {
26601
26559
  };
26602
26560
  }
26603
26561
  const content = await readFileOrNull(layoutPath) || "";
26604
- const rel = path10__default.default.relative(cwd, layoutPath);
26562
+ const rel = path12__default.default.relative(cwd, layoutPath);
26605
26563
  if (content.includes("SiteKitLayout")) {
26606
26564
  return {
26607
26565
  id: "layout.sitekit",
@@ -26633,8 +26591,8 @@ async function checkSiteKitLayout(cwd) {
26633
26591
  };
26634
26592
  }
26635
26593
  async function checkSitemap(cwd) {
26636
- const sitemapPath = await findFirst(cwd, SITEMAP_CANDIDATES);
26637
- if (!sitemapPath) {
26594
+ const sitemapRel = chunkP4TB4ROG_js.findSitemapRoute(cwd);
26595
+ if (!sitemapRel) {
26638
26596
  return {
26639
26597
  id: "sitemap.managed",
26640
26598
  title: "Sitemap",
@@ -26644,7 +26602,7 @@ async function checkSitemap(cwd) {
26644
26602
  fixCommand: "npx sonor-setup scaffold --yes"
26645
26603
  };
26646
26604
  }
26647
- const content = await readFileOrNull(sitemapPath) || "";
26605
+ const content = await readFileOrNull(path12__default.default.join(cwd, sitemapRel)) || "";
26648
26606
  if (content.includes("createSitemap") || content.includes("@sonordev/site-kit")) {
26649
26607
  return { id: "sitemap.managed", title: "Sitemap", level: "ok", message: "Using Site-Kit sitemap" };
26650
26608
  }
@@ -26657,7 +26615,7 @@ async function checkSitemap(cwd) {
26657
26615
  };
26658
26616
  }
26659
26617
  async function checkPostbuildSitemap(cwd) {
26660
- const raw = await readFileOrNull(path10__default.default.join(cwd, "package.json"));
26618
+ const raw = await readFileOrNull(path12__default.default.join(cwd, "package.json"));
26661
26619
  let pkg = {};
26662
26620
  try {
26663
26621
  pkg = raw ? JSON.parse(raw) : {};
@@ -26694,18 +26652,18 @@ async function checkPostbuildSitemap(cwd) {
26694
26652
  async function checkApiReachable(timeoutMs = 5e3) {
26695
26653
  const key = process.env.SONOR_API_KEY;
26696
26654
  try {
26697
- const res = await fetch(`${API_URL4}/health`, {
26655
+ const res = await fetch(`${API_URL}/health`, {
26698
26656
  headers: key ? { "x-api-key": key } : {},
26699
26657
  signal: AbortSignal.timeout(timeoutMs)
26700
26658
  });
26701
26659
  if (res.ok) {
26702
- return { id: "api.reachable", title: "Sonor API", level: "ok", message: `Reachable (${API_URL4})` };
26660
+ return { id: "api.reachable", title: "Sonor API", level: "ok", message: `Reachable (${API_URL})` };
26703
26661
  }
26704
26662
  return {
26705
26663
  id: "api.reachable",
26706
26664
  title: "Sonor API",
26707
26665
  level: "warn",
26708
- message: `HTTP ${res.status} from ${API_URL4}`
26666
+ message: `HTTP ${res.status} from ${API_URL}`
26709
26667
  };
26710
26668
  } catch (err) {
26711
26669
  return {
@@ -26730,7 +26688,7 @@ async function checkKeyValid(timeoutMs = 8e3) {
26730
26688
  };
26731
26689
  }
26732
26690
  try {
26733
- const res = await fetch(`${API_URL4}/api/public/seo/verify-api-key`, {
26691
+ const res = await fetch(`${API_URL}/api/public/seo/verify-api-key`, {
26734
26692
  headers: { "x-api-key": key },
26735
26693
  signal: AbortSignal.timeout(timeoutMs)
26736
26694
  });
@@ -26833,7 +26791,7 @@ async function checkClientAuth(timeoutMs = 8e3) {
26833
26791
  }
26834
26792
  const qs2 = host ? `?host=${encodeURIComponent(host)}` : "";
26835
26793
  try {
26836
- const res = await fetch(`${API_URL4}/api/public/site-token/status${qs2}`, {
26794
+ const res = await fetch(`${API_URL}/api/public/site-token/status${qs2}`, {
26837
26795
  headers: { "x-api-key": key },
26838
26796
  signal: AbortSignal.timeout(timeoutMs)
26839
26797
  });
@@ -26978,7 +26936,7 @@ async function checkSsrRenderFromUrl(url, timeoutMs = 12e3) {
26978
26936
  }
26979
26937
  }
26980
26938
  async function checkSsrRenderFromBuild(cwd) {
26981
- const appDir = path10__default.default.join(cwd, ".next", "server", "app");
26939
+ const appDir = path12__default.default.join(cwd, ".next", "server", "app");
26982
26940
  let entries;
26983
26941
  try {
26984
26942
  entries = await fs3__default.default.readdir(appDir);
@@ -27001,7 +26959,7 @@ async function checkSsrRenderFromBuild(cwd) {
27001
26959
  detail: "The root route may be fully dynamic. Pass --url to verify a running instance."
27002
26960
  };
27003
26961
  }
27004
- const html = await readFileOrNull(path10__default.default.join(appDir, htmlName)) || "";
26962
+ const html = await readFileOrNull(path12__default.default.join(appDir, htmlName)) || "";
27005
26963
  const { rendered, contentTags } = looksServerRendered(html);
27006
26964
  if (rendered) {
27007
26965
  return {
@@ -27022,9 +26980,8 @@ async function checkSsrRenderFromBuild(cwd) {
27022
26980
  }
27023
26981
  async function checkNetlifyMiddleware(cwd) {
27024
26982
  const runtimeRe = /runtime\s*[:=]\s*['"](nodejs|edge)['"]/;
27025
- const proxyFiles = ["proxy.ts", "proxy.js", "src/proxy.ts", "src/proxy.js"];
27026
- for (const rel of proxyFiles) {
27027
- const content = await readFileOrNull(path10__default.default.join(cwd, rel));
26983
+ for (const rel of chunkP4TB4ROG_js.NEXT_PROXY_FILES) {
26984
+ const content = await readFileOrNull(path12__default.default.join(cwd, rel));
27028
26985
  if (content === null) continue;
27029
26986
  if (runtimeRe.test(content)) {
27030
26987
  return {
@@ -27039,9 +26996,8 @@ async function checkNetlifyMiddleware(cwd) {
27039
26996
  }
27040
26997
  return { id: "middleware.netlify", title: "Proxy / middleware", level: "ok", message: `${rel} present` };
27041
26998
  }
27042
- const middlewareFiles = ["middleware.ts", "middleware.js", "src/middleware.ts", "src/middleware.js"];
27043
- for (const rel of middlewareFiles) {
27044
- const content = await readFileOrNull(path10__default.default.join(cwd, rel));
26999
+ for (const rel of chunkP4TB4ROG_js.NEXT_MIDDLEWARE_FILES) {
27000
+ const content = await readFileOrNull(path12__default.default.join(cwd, rel));
27045
27001
  if (content === null) continue;
27046
27002
  if (/runtime\s*[:=]\s*['"]nodejs['"]/.test(content)) {
27047
27003
  return {
@@ -27068,7 +27024,7 @@ async function checkNetlifyMiddleware(cwd) {
27068
27024
  }
27069
27025
  async function checkImageDimsDrift(cwd) {
27070
27026
  const scanRoots = ["app", "src/app", "components", "src/components"];
27071
- const publicDir = path10__default.default.join(cwd, "public");
27027
+ const publicDir = path12__default.default.join(cwd, "public");
27072
27028
  const files = [];
27073
27029
  async function walk(dir, depth) {
27074
27030
  if (depth > 4) return;
@@ -27080,19 +27036,19 @@ async function checkImageDimsDrift(cwd) {
27080
27036
  }
27081
27037
  for (const e of entries) {
27082
27038
  if (e.name === "node_modules" || e.name.startsWith(".")) continue;
27083
- const full = path10__default.default.join(dir, e.name);
27039
+ const full = path12__default.default.join(dir, e.name);
27084
27040
  if (e.isDirectory()) await walk(full, depth + 1);
27085
27041
  else if (/\.(tsx|jsx)$/.test(e.name)) files.push(full);
27086
27042
  }
27087
27043
  }
27088
- for (const root of scanRoots) await walk(path10__default.default.join(cwd, root), 0);
27044
+ for (const root of scanRoots) await walk(path12__default.default.join(cwd, root), 0);
27089
27045
  if (files.length === 0) {
27090
27046
  return { id: "images.dims-drift", title: "Image dims vs SVG", level: "skip", message: "No component files found" };
27091
27047
  }
27092
27048
  const viewBoxCache = /* @__PURE__ */ new Map();
27093
27049
  async function svgAspect(publicPath) {
27094
27050
  if (viewBoxCache.has(publicPath)) return viewBoxCache.get(publicPath);
27095
- const svg = await readFileOrNull(path10__default.default.join(publicDir, publicPath.replace(/^\//, "")));
27051
+ const svg = await readFileOrNull(path12__default.default.join(publicDir, publicPath.replace(/^\//, "")));
27096
27052
  let aspect = null;
27097
27053
  if (svg) {
27098
27054
  const vb = svg.match(/viewBox="([\d.\s-]+)"/);
@@ -27119,7 +27075,7 @@ async function checkImageDimsDrift(cwd) {
27119
27075
  const drift = Math.abs(declared - actual) / actual;
27120
27076
  if (drift > 0.02) {
27121
27077
  drifts.push(
27122
- `${path10__default.default.relative(cwd, file)}: ${src} is ${actual.toFixed(2)}:1 but width/height declare ${declared.toFixed(2)}:1 (${Math.round(drift * 100)}% off)`
27078
+ `${path12__default.default.relative(cwd, file)}: ${src} is ${actual.toFixed(2)}:1 but width/height declare ${declared.toFixed(2)}:1 (${Math.round(drift * 100)}% off)`
27123
27079
  );
27124
27080
  }
27125
27081
  }
@@ -27235,8 +27191,8 @@ async function statusCommand(options) {
27235
27191
 
27236
27192
  // src/og/pages.ts
27237
27193
  var DYNAMIC = "*";
27238
- function pathSegments(path27) {
27239
- return path27.split("/").filter(Boolean);
27194
+ function pathSegments(path30) {
27195
+ return path30.split("/").filter(Boolean);
27240
27196
  }
27241
27197
  function stripBrandSuffix(title, brand) {
27242
27198
  const cleaned = title.replace(/\s*[|–—-]\s*[^|–—-]+$/, "").trim();
@@ -27244,13 +27200,13 @@ function stripBrandSuffix(title, brand) {
27244
27200
  if (brand && cleaned.toLowerCase() === brand.toLowerCase()) return title.trim();
27245
27201
  return cleaned;
27246
27202
  }
27247
- function titleFromPath(path27) {
27248
- const last = pathSegments(path27).filter((s) => s !== DYNAMIC).pop();
27203
+ function titleFromPath(path30) {
27204
+ const last = pathSegments(path30).filter((s) => s !== DYNAMIC).pop();
27249
27205
  if (!last) return "Home";
27250
27206
  return last.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
27251
27207
  }
27252
- function kickerFromPath(path27, fallback) {
27253
- const parts = pathSegments(path27);
27208
+ function kickerFromPath(path30, fallback) {
27209
+ const parts = pathSegments(path30);
27254
27210
  const section = parts.includes(DYNAMIC) ? parts.filter((s) => s !== DYNAMIC) : parts.slice(0, -1);
27255
27211
  if (!section.length) return fallback;
27256
27212
  return section.join(" / ").replace(/[-_]+/g, " ");
@@ -27274,8 +27230,8 @@ function kickerIsRedundant(kicker, title) {
27274
27230
  const titleWords = new Set(t.split(" "));
27275
27231
  return k2.split(" ").every((w) => titleWords.has(w));
27276
27232
  }
27277
- function slugForPath(path27) {
27278
- const segments = pathSegments(path27);
27233
+ function slugForPath(path30) {
27234
+ const segments = pathSegments(path30);
27279
27235
  if (!segments.length) return "home";
27280
27236
  return segments.map((s) => s === DYNAMIC ? "any" : s).join("-").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
27281
27237
  }
@@ -27329,10 +27285,10 @@ function findChrome() {
27329
27285
  }
27330
27286
  return null;
27331
27287
  }
27332
- async function loadConfig4(cwd) {
27288
+ async function loadConfig2(cwd) {
27333
27289
  const candidates = ["og.config.ts", "og.config.mts", "og.config.mjs", "og.config.js"];
27334
27290
  for (const rel of candidates) {
27335
- const full = path10__default.default.join(cwd, rel);
27291
+ const full = path12__default.default.join(cwd, rel);
27336
27292
  if (!fs.existsSync(full)) continue;
27337
27293
  try {
27338
27294
  const mod = await import(
@@ -27357,7 +27313,7 @@ async function loadConfig4(cwd) {
27357
27313
  return null;
27358
27314
  }
27359
27315
  async function seedConfig(cwd) {
27360
- let name = path10__default.default.basename(cwd).replace(/-nextjs$/, "").replace(/-/g, " ");
27316
+ let name = path12__default.default.basename(cwd).replace(/-nextjs$/, "").replace(/-/g, " ");
27361
27317
  let accent = "#111111";
27362
27318
  let logo;
27363
27319
  try {
@@ -27370,7 +27326,7 @@ async function seedConfig(cwd) {
27370
27326
  } catch {
27371
27327
  }
27372
27328
  for (const candidate of ["/logo-mark.svg", "/logo.svg", "/logohorizontal.svg"]) {
27373
- if (fs.existsSync(path10__default.default.join(cwd, "public", candidate))) {
27329
+ if (fs.existsSync(path12__default.default.join(cwd, "public", candidate))) {
27374
27330
  logo = candidate;
27375
27331
  break;
27376
27332
  }
@@ -27384,14 +27340,14 @@ async function seedConfig(cwd) {
27384
27340
  }
27385
27341
  function inlinePublicPaths(html, cwd) {
27386
27342
  return html.replace(/src="(\/[^"]+)"/g, (_3, p) => {
27387
- const full = path10__default.default.join(cwd, "public", p);
27343
+ const full = path12__default.default.join(cwd, "public", p);
27388
27344
  return fs.existsSync(full) ? `src="file://${full}"` : `src="${p}"`;
27389
27345
  });
27390
27346
  }
27391
27347
  async function renderCard(config2, outPath, cwd, chrome, tmpSuffix) {
27392
- const tmpHtml = path10__default.default.join(cwd, `.sonor-og-${tmpSuffix}.html`);
27348
+ const tmpHtml = path12__default.default.join(cwd, `.sonor-og-${tmpSuffix}.html`);
27393
27349
  try {
27394
- await fs3__default.default.mkdir(path10__default.default.dirname(outPath), { recursive: true });
27350
+ await fs3__default.default.mkdir(path12__default.default.dirname(outPath), { recursive: true });
27395
27351
  await fs3__default.default.writeFile(tmpHtml, inlinePublicPaths(chunk6CJP7BFM_js.buildOgHtml(config2), cwd));
27396
27352
  const { stdout } = await execFileAsync5(
27397
27353
  chrome,
@@ -27426,7 +27382,7 @@ function parseReport(dom) {
27426
27382
  }
27427
27383
  async function compressCard(pngPath, cwd) {
27428
27384
  try {
27429
- const require_ = (await import('module')).createRequire(path10__default.default.join(cwd, "package.json"));
27385
+ const require_ = (await import('module')).createRequire(path12__default.default.join(cwd, "package.json"));
27430
27386
  const sharp = require_("sharp");
27431
27387
  const jpgPath = pngPath.replace(/\.png$/, ".jpg");
27432
27388
  await sharp(pngPath).jpeg({ quality: 84, mozjpeg: true }).toFile(jpgPath);
@@ -27436,6 +27392,9 @@ async function compressCard(pngPath, cwd) {
27436
27392
  return pngPath;
27437
27393
  }
27438
27394
  }
27395
+ function codeOgImageFile(dir) {
27396
+ return chunkP4TB4ROG_js.findConventionFile(dir, "opengraph-image");
27397
+ }
27439
27398
  function discoverDynamicSegments(appDir) {
27440
27399
  const found = [];
27441
27400
  const walk = (dir, urlSegments, pattern) => {
@@ -27443,14 +27402,13 @@ function discoverDynamicSegments(appDir) {
27443
27402
  if (!entry.isDirectory()) continue;
27444
27403
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
27445
27404
  if (entry.name === "api" || entry.name === "node_modules") continue;
27446
- const full = path10__default.default.join(dir, entry.name);
27405
+ const full = path12__default.default.join(dir, entry.name);
27447
27406
  const isGroup = entry.name.startsWith("(") && entry.name.endsWith(")");
27448
27407
  const isDynamic = entry.name.startsWith("[") && entry.name.endsWith("]");
27449
27408
  const nextUrl = isGroup || isDynamic ? urlSegments : [...urlSegments, entry.name];
27450
27409
  const nextPattern = isGroup ? pattern : [...pattern, isDynamic ? DYNAMIC : entry.name];
27451
27410
  if (isDynamic) {
27452
- const hasPage = ["tsx", "jsx", "ts", "js"].some((ext2) => fs.existsSync(path10__default.default.join(full, `page.${ext2}`)));
27453
- if (hasPage) {
27411
+ if (chunkP4TB4ROG_js.hasPageFile(full)) {
27454
27412
  found.push({ dir: full, path: `/${nextPattern.join("/")}`, parent: `/${urlSegments.join("/")}` });
27455
27413
  }
27456
27414
  }
@@ -27525,7 +27483,7 @@ async function runOg(options) {
27525
27483
  errors: [{ code: "chrome_missing", message: "No Chrome or Chromium binary found", fix: "Install Chrome, or set SONOR_CHROME_PATH to its path." }]
27526
27484
  };
27527
27485
  }
27528
- let config2 = await loadConfig4(cwd);
27486
+ let config2 = await loadConfig2(cwd);
27529
27487
  let seeded = false;
27530
27488
  if (!config2) {
27531
27489
  config2 = await seedConfig(cwd);
@@ -27533,7 +27491,7 @@ async function runOg(options) {
27533
27491
  console.log(source_default.yellow(" ! No og.config.ts \u2014 generating a seed card from Sonor brand data."));
27534
27492
  console.log(source_default.gray(" The site owns its theme: add og.config.ts (defineOgCard) with the real palette."));
27535
27493
  }
27536
- const outPath = path10__default.default.resolve(cwd, options.out || "public/og.png");
27494
+ const outPath = path12__default.default.resolve(cwd, options.out || "public/og.png");
27537
27495
  let clean = true;
27538
27496
  let cardKeyFix = null;
27539
27497
  let pageCardsWritten = 0;
@@ -27543,8 +27501,8 @@ async function runOg(options) {
27543
27501
  const report = await renderCard(config2, outPath, cwd, chrome, "site");
27544
27502
  spinner.stop();
27545
27503
  console.log(source_default.bold(` Site card${seeded ? source_default.gray(" (seed)") : ""}`));
27546
- clean = reportCard(`${path10__default.default.relative(cwd, outPath)} \u2014 1200x630`, report) && clean;
27547
- checks.push(cardCheck("site card", path10__default.default.relative(cwd, outPath), report));
27504
+ clean = reportCard(`${path12__default.default.relative(cwd, outPath)} \u2014 1200x630`, report) && clean;
27505
+ checks.push(cardCheck("site card", path12__default.default.relative(cwd, outPath), report));
27548
27506
  } catch (err) {
27549
27507
  const message = err instanceof Error ? err.message.split("\n")[0] : String(err);
27550
27508
  spinner.fail(`Render failed: ${message}`);
@@ -27555,11 +27513,11 @@ async function runOg(options) {
27555
27513
  };
27556
27514
  }
27557
27515
  if (options.pages !== false) {
27558
- const appDir = chunkLOS5D6B3_js.findAppDirForDiscovery(cwd);
27516
+ const appDir = chunkP4TB4ROG_js.findAppDirForDiscovery(cwd);
27559
27517
  if (!appDir) {
27560
27518
  console.log(source_default.yellow(" ! No app/ directory found \u2014 skipped per-page cards."));
27561
27519
  } else {
27562
- const routes = [...new Set(chunkLOS5D6B3_js.discoverNextJsRoutes(appDir).map((r) => r.path))];
27520
+ const routes = [...new Set(chunkP4TB4ROG_js.discoverNextJsRoutes(appDir).map((r) => r.path))];
27563
27521
  if (!routes.length) {
27564
27522
  console.log(source_default.yellow(" ! No static routes discovered \u2014 skipped per-page cards."));
27565
27523
  } else {
@@ -27603,20 +27561,30 @@ async function runOg(options) {
27603
27561
  });
27604
27562
  cardKeyFix = CARD_KEY_FIX;
27605
27563
  }
27606
- const reports = await pooled(targets, RENDER_CONCURRENCY, async (route, i) => {
27564
+ const placed = targets.map((route) => ({ ...route, dir: route.dir ?? routeOutputDir(appDir, route.path) }));
27565
+ const toRender = placed.filter((route) => !codeOgImageFile(route.dir));
27566
+ for (const route of placed.filter((r) => codeOgImageFile(r.dir))) {
27567
+ for (const ext2 of ["png", "jpg", "jpeg"]) {
27568
+ await fs3__default.default.rm(path12__default.default.join(route.dir, `opengraph-image.${ext2}`), { force: true });
27569
+ }
27570
+ const file = path12__default.default.relative(cwd, codeOgImageFile(route.dir));
27571
+ console.log(source_default.gray(` \u21B7 ${route.path} keeps its own ${file}`));
27572
+ checks.push({ id: "og.code-card", title: route.path, level: "ok", message: `Code-based card kept: ${file}` });
27573
+ }
27574
+ const reports = await pooled(toRender, RENDER_CONCURRENCY, async (route, i) => {
27607
27575
  const pageConfig = pageCardConfig(config2, route, brand);
27608
- const dir = route.dir ?? routeOutputDir(appDir, route.path);
27576
+ const dir = route.dir;
27609
27577
  for (const ext2 of ["png", "jpg", "jpeg"]) {
27610
- await fs3__default.default.rm(path10__default.default.join(dir, `opengraph-image.${ext2}`), { force: true });
27578
+ await fs3__default.default.rm(path12__default.default.join(dir, `opengraph-image.${ext2}`), { force: true });
27611
27579
  }
27612
- const png = path10__default.default.join(dir, "opengraph-image.png");
27580
+ const png = path12__default.default.join(dir, "opengraph-image.png");
27613
27581
  const report = await renderCard(pageConfig, png, cwd, chrome, `page-${i}`);
27614
27582
  const file = await compressCard(png, cwd);
27615
27583
  return { route, file, report };
27616
27584
  });
27617
27585
  for (const { route, file, report } of reports) {
27618
- clean = reportCard(`${route.path} ${source_default.gray(path10__default.default.relative(cwd, file))}`, report) && clean;
27619
- checks.push(cardCheck(route.path, path10__default.default.relative(cwd, file), report));
27586
+ clean = reportCard(`${route.path} ${source_default.gray(path12__default.default.relative(cwd, file))}`, report) && clean;
27587
+ checks.push(cardCheck(route.path, path12__default.default.relative(cwd, file), report));
27620
27588
  }
27621
27589
  pageCardsWritten = reports.length;
27622
27590
  const bytes = await totalBytes(reports.map((r) => r.file));
@@ -27627,13 +27595,13 @@ async function runOg(options) {
27627
27595
  }
27628
27596
  if (options.preview !== false) {
27629
27597
  try {
27630
- const require_ = (await import('module')).createRequire(path10__default.default.join(cwd, "package.json"));
27598
+ const require_ = (await import('module')).createRequire(path12__default.default.join(cwd, "package.json"));
27631
27599
  const sharp = require_("sharp");
27632
- const previewPath = path10__default.default.join(cwd, ".sonor", "og-preview.png");
27633
- await fs3__default.default.mkdir(path10__default.default.dirname(previewPath), { recursive: true });
27600
+ const previewPath = path12__default.default.join(cwd, ".sonor", "og-preview.png");
27601
+ await fs3__default.default.mkdir(path12__default.default.dirname(previewPath), { recursive: true });
27634
27602
  await sharp(outPath).resize(300).toFile(previewPath);
27635
27603
  console.log("");
27636
- console.log(source_default.gray(` Thumbnail check: ${path10__default.default.relative(cwd, previewPath)} \u2014 if text is mush there, fix the card.`));
27604
+ console.log(source_default.gray(` Thumbnail check: ${path12__default.default.relative(cwd, previewPath)} \u2014 if text is mush there, fix the card.`));
27637
27605
  } catch {
27638
27606
  console.log(source_default.gray(" (sharp not resolvable \u2014 skipped the 300px preview)"));
27639
27607
  }
@@ -27692,15 +27660,15 @@ function routeOutputDir(appDir, urlPath) {
27692
27660
  const segments = urlPath.split("/").filter(Boolean);
27693
27661
  let dir = appDir;
27694
27662
  for (const segment of segments) {
27695
- const direct = path10__default.default.join(dir, segment);
27663
+ const direct = path12__default.default.join(dir, segment);
27696
27664
  if (fs.existsSync(direct)) {
27697
27665
  dir = direct;
27698
27666
  continue;
27699
27667
  }
27700
27668
  const group = fs.existsSync(dir) ? fs.readdirSync(dir, { withFileTypes: true }).find(
27701
- (e) => e.isDirectory() && e.name.startsWith("(") && e.name.endsWith(")") && fs.existsSync(path10__default.default.join(dir, e.name, segment))
27669
+ (e) => e.isDirectory() && e.name.startsWith("(") && e.name.endsWith(")") && fs.existsSync(path12__default.default.join(dir, e.name, segment))
27702
27670
  ) : void 0;
27703
- dir = group ? path10__default.default.join(dir, group.name, segment) : direct;
27671
+ dir = group ? path12__default.default.join(dir, group.name, segment) : direct;
27704
27672
  }
27705
27673
  return dir;
27706
27674
  }
@@ -27715,7 +27683,7 @@ async function totalBytes(files) {
27715
27683
  return total;
27716
27684
  }
27717
27685
  async function siteDomain(cwd) {
27718
- const envFile = path10__default.default.join(cwd, ".env.local");
27686
+ const envFile = path12__default.default.join(cwd, ".env.local");
27719
27687
  if (fs.existsSync(envFile)) {
27720
27688
  const env3 = await fs3__default.default.readFile(envFile, "utf-8").catch(() => "");
27721
27689
  const url = env3.match(/^NEXT_PUBLIC_SITE_URL=(.+)$/m)?.[1]?.trim();
@@ -27840,14 +27808,14 @@ var hs = new RegExp(pe, "g");
27840
27808
  var as = /\\\\/g;
27841
27809
  var ls = /\\{/g;
27842
27810
  var cs = /\\}/g;
27843
- var fs20 = /\\,/g;
27811
+ var fs22 = /\\,/g;
27844
27812
  var us = /\\./g;
27845
27813
  var ds = 1e5;
27846
27814
  function Ht(n5) {
27847
27815
  return isNaN(n5) ? n5.charCodeAt(0) : parseInt(n5, 10);
27848
27816
  }
27849
27817
  function ps(n5) {
27850
- return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs20, de).replace(us, pe);
27818
+ return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs22, de).replace(us, pe);
27851
27819
  }
27852
27820
  function ms(n5) {
27853
27821
  return n5.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(os5, ",").replace(hs, ".");
@@ -29930,7 +29898,7 @@ var Pt = class n extends R {
29930
29898
  return new n(t, e, this.root, this.roots, this.nocase, this.childrenCache(), s);
29931
29899
  }
29932
29900
  getRootString(t) {
29933
- return path10.win32.parse(t).root;
29901
+ return path12.win32.parse(t).root;
29934
29902
  }
29935
29903
  getRoot(t) {
29936
29904
  if (t = Ri(t.toUpperCase()), t === this.root.name) return this.root;
@@ -30202,13 +30170,13 @@ var It = (_a8 = class {
30202
30170
  var it = class extends It {
30203
30171
  constructor(t = process.cwd(), e = {}) {
30204
30172
  let { nocase: s = true } = e;
30205
- super(t, path10.win32, "\\", { ...e, nocase: s });
30173
+ super(t, path12.win32, "\\", { ...e, nocase: s });
30206
30174
  chunkSNAQBZPT_js.__publicField(this, "sep", "\\");
30207
30175
  this.nocase = s;
30208
30176
  for (let i = this.cwd; i; i = i.parent) i.nocase = this.nocase;
30209
30177
  }
30210
30178
  parseRootPath(t) {
30211
- return path10.win32.parse(t).root.toUpperCase();
30179
+ return path12.win32.parse(t).root.toUpperCase();
30212
30180
  }
30213
30181
  newRoot(t) {
30214
30182
  return new Pt(this.rootPath, U, void 0, this.roots, this.nocase, this.childrenCache(), { fs: t });
@@ -30220,7 +30188,7 @@ var it = class extends It {
30220
30188
  var rt = class extends It {
30221
30189
  constructor(t = process.cwd(), e = {}) {
30222
30190
  let { nocase: s = false } = e;
30223
- super(t, path10.posix, "/", { ...e, nocase: s });
30191
+ super(t, path12.posix, "/", { ...e, nocase: s });
30224
30192
  chunkSNAQBZPT_js.__publicField(this, "sep", "/");
30225
30193
  this.nocase = s;
30226
30194
  }
@@ -30879,10 +30847,10 @@ function unifiedDiff(before, after, filePath, context = 2) {
30879
30847
  return lines.join("\n");
30880
30848
  }
30881
30849
  function ext(filePath) {
30882
- return path10__default.default.extname(filePath).toLowerCase();
30850
+ return path12__default.default.extname(filePath).toLowerCase();
30883
30851
  }
30884
30852
  function basename(filePath) {
30885
- return path10__default.default.basename(filePath).toLowerCase();
30853
+ return path12__default.default.basename(filePath).toLowerCase();
30886
30854
  }
30887
30855
  var CODE_EXT = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
30888
30856
  var TEXT_EXT = /* @__PURE__ */ new Set([...CODE_EXT, ".css", ".scss", ".json", ".md", ".mdx"]);
@@ -31036,7 +31004,7 @@ var IGNORE = [
31036
31004
  ];
31037
31005
  async function listFiles(cwd, onlyPath) {
31038
31006
  if (onlyPath) {
31039
- const rel = path10__default.default.isAbsolute(onlyPath) ? path10__default.default.relative(cwd, onlyPath) : onlyPath;
31007
+ const rel = path12__default.default.isAbsolute(onlyPath) ? path12__default.default.relative(cwd, onlyPath) : onlyPath;
31040
31008
  return [rel];
31041
31009
  }
31042
31010
  const matches = await Ze(SCAN_PATTERNS, { cwd, ignore: IGNORE, dot: true, nodir: true });
@@ -31048,7 +31016,7 @@ async function runCodemod(options) {
31048
31016
  const files = await listFiles(cwd, onlyPath);
31049
31017
  const changes = [];
31050
31018
  for (const rel of files) {
31051
- const full = path10__default.default.join(cwd, rel);
31019
+ const full = path12__default.default.join(cwd, rel);
31052
31020
  let source;
31053
31021
  try {
31054
31022
  source = await fs3__default.default.readFile(full, "utf-8");
@@ -31197,9 +31165,9 @@ function findManifestPath() {
31197
31165
  const baseDir = typeof __dirname !== "undefined" ? __dirname : process.cwd();
31198
31166
  let dir = baseDir;
31199
31167
  for (let i = 0; i < 8; i++) {
31200
- const candidate = path10__default.default.join(dir, "agent-manifest.json");
31168
+ const candidate = path12__default.default.join(dir, "agent-manifest.json");
31201
31169
  if (fs__namespace.default.existsSync(candidate)) return candidate;
31202
- const parent = path10__default.default.dirname(dir);
31170
+ const parent = path12__default.default.dirname(dir);
31203
31171
  if (parent === dir) break;
31204
31172
  dir = parent;
31205
31173
  }
@@ -31278,7 +31246,7 @@ async function syncCommand2(options) {
31278
31246
  }
31279
31247
  async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
31280
31248
  const spinner = ora("Discovering pages...").start();
31281
- const appDir = findAppDir();
31249
+ const appDir = chunkP4TB4ROG_js.findAppDirForDiscovery();
31282
31250
  if (!appDir) {
31283
31251
  spinner.fail("Could not find app directory");
31284
31252
  return;
@@ -31339,20 +31307,8 @@ async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
31339
31307
  syncSpinner.fail(`Sync failed: ${error2.message}`);
31340
31308
  }
31341
31309
  }
31342
- function findAppDir() {
31343
- const candidates = [
31344
- path10__default.default.join(process.cwd(), "app"),
31345
- path10__default.default.join(process.cwd(), "src", "app")
31346
- ];
31347
- for (const candidate of candidates) {
31348
- if (fs.existsSync(candidate)) {
31349
- return candidate;
31350
- }
31351
- }
31352
- return null;
31353
- }
31354
31310
  function discoverPages(appDir, currentPath = "", pages = []) {
31355
- const fullPath = path10__default.default.join(appDir, currentPath);
31311
+ const fullPath = path12__default.default.join(appDir, currentPath);
31356
31312
  if (!fs.existsSync(fullPath)) {
31357
31313
  return pages;
31358
31314
  }
@@ -31374,7 +31330,7 @@ function discoverPages(appDir, currentPath = "", pages = []) {
31374
31330
  });
31375
31331
  }
31376
31332
  for (const entry of entries) {
31377
- const entryPath = path10__default.default.join(fullPath, entry);
31333
+ const entryPath = path12__default.default.join(fullPath, entry);
31378
31334
  const stat = fs.statSync(entryPath);
31379
31335
  if (stat.isDirectory()) {
31380
31336
  const folderName = entry.toLowerCase();
@@ -31387,21 +31343,21 @@ function discoverPages(appDir, currentPath = "", pages = []) {
31387
31343
  if (entry.startsWith("_")) {
31388
31344
  continue;
31389
31345
  }
31390
- discoverPages(appDir, path10__default.default.join(currentPath, entry), pages);
31346
+ discoverPages(appDir, path12__default.default.join(currentPath, entry), pages);
31391
31347
  }
31392
31348
  }
31393
31349
  return pages;
31394
31350
  }
31395
31351
  function findNextBuildDir() {
31396
31352
  const cwd = process.cwd();
31397
- const candidate = path10__default.default.join(cwd, ".next", "server", "app");
31353
+ const candidate = path12__default.default.join(cwd, ".next", "server", "app");
31398
31354
  return fs.existsSync(candidate) ? candidate : null;
31399
31355
  }
31400
31356
  function extractPageContent(buildDir, pagePath) {
31401
31357
  const baseName = pagePath === "/" ? "index" : pagePath.replace(/^\//, "");
31402
31358
  const htmlCandidates = [
31403
- path10__default.default.join(buildDir, `${baseName}.html`),
31404
- path10__default.default.join(buildDir, baseName, "index.html")
31359
+ path12__default.default.join(buildDir, `${baseName}.html`),
31360
+ path12__default.default.join(buildDir, baseName, "index.html")
31405
31361
  ];
31406
31362
  let html = null;
31407
31363
  for (const candidate of htmlCandidates) {
@@ -31415,8 +31371,8 @@ function extractPageContent(buildDir, pagePath) {
31415
31371
  }
31416
31372
  }
31417
31373
  const rscCandidates = [
31418
- path10__default.default.join(buildDir, `${baseName}.rsc`),
31419
- path10__default.default.join(buildDir, baseName, "index.rsc")
31374
+ path12__default.default.join(buildDir, `${baseName}.rsc`),
31375
+ path12__default.default.join(buildDir, baseName, "index.rsc")
31420
31376
  ];
31421
31377
  let rsc = null;
31422
31378
  for (const candidate of rscCandidates) {
@@ -31527,7 +31483,7 @@ var BLOG_EXTENSIONS = [".mdx", ".md"];
31527
31483
  function findBlogDir() {
31528
31484
  const cwd = process.cwd();
31529
31485
  for (const dir of BLOG_DIRS) {
31530
- const full = path10__default.default.join(cwd, dir);
31486
+ const full = path12__default.default.join(cwd, dir);
31531
31487
  if (fs.existsSync(full)) return full;
31532
31488
  }
31533
31489
  return null;
@@ -31537,7 +31493,7 @@ async function discoverBlogPosts(dir) {
31537
31493
  async function walk(currentDir) {
31538
31494
  const entries = fs.readdirSync(currentDir);
31539
31495
  for (const entry of entries) {
31540
- const fullPath = path10__default.default.join(currentDir, entry);
31496
+ const fullPath = path12__default.default.join(currentDir, entry);
31541
31497
  const stat = fs.statSync(fullPath);
31542
31498
  if (stat.isDirectory()) {
31543
31499
  await walk(fullPath);
@@ -31554,7 +31510,7 @@ async function discoverBlogPosts(dir) {
31554
31510
  date: frontmatter.date,
31555
31511
  tags: frontmatter.tags,
31556
31512
  author: frontmatter.author,
31557
- filePath: path10__default.default.relative(process.cwd(), fullPath)
31513
+ filePath: path12__default.default.relative(process.cwd(), fullPath)
31558
31514
  });
31559
31515
  }
31560
31516
  }
@@ -31587,7 +31543,7 @@ async function syncBlogToPortal(_apiUrl, _apiKey, _dryRun) {
31587
31543
  }
31588
31544
  const spinner = ora("Discovering blog posts...").start();
31589
31545
  const posts = await discoverBlogPosts(blogDir);
31590
- spinner.succeed(`Found ${posts.length} local markdown post(s) in ${path10__default.default.relative(process.cwd(), blogDir)}`);
31546
+ spinner.succeed(`Found ${posts.length} local markdown post(s) in ${path12__default.default.relative(process.cwd(), blogDir)}`);
31591
31547
  if (posts.length === 0) return;
31592
31548
  for (const post of posts.slice(0, 10)) {
31593
31549
  console.log(source_default.gray(` ${post.slug}: ${post.title || "(no title)"}`));
@@ -31604,11 +31560,11 @@ async function discoverSchemaUsage(appDir) {
31604
31560
  async function walk(currentDir, currentPath = "") {
31605
31561
  const entries = fs.readdirSync(currentDir);
31606
31562
  for (const entry of entries) {
31607
- const fullPath = path10__default.default.join(currentDir, entry);
31563
+ const fullPath = path12__default.default.join(currentDir, entry);
31608
31564
  const stat = fs.statSync(fullPath);
31609
31565
  if (stat.isDirectory()) {
31610
31566
  if (entry.startsWith(".") || entry === "node_modules") continue;
31611
- await walk(fullPath, path10__default.default.join(currentPath, entry));
31567
+ await walk(fullPath, path12__default.default.join(currentPath, entry));
31612
31568
  continue;
31613
31569
  }
31614
31570
  if (!/\.(tsx?|jsx?)$/.test(entry)) continue;
@@ -31622,7 +31578,7 @@ async function discoverSchemaUsage(appDir) {
31622
31578
  pagePath: pathMatch[1],
31623
31579
  schemaTypes: ["managed"],
31624
31580
  source: "ManagedSchema",
31625
- filePath: path10__default.default.relative(process.cwd(), fullPath)
31581
+ filePath: path12__default.default.relative(process.cwd(), fullPath)
31626
31582
  });
31627
31583
  }
31628
31584
  }
@@ -31640,7 +31596,7 @@ async function discoverSchemaUsage(appDir) {
31640
31596
  pagePath,
31641
31597
  schemaTypes: [...new Set(types)],
31642
31598
  source: "json-ld",
31643
- filePath: path10__default.default.relative(process.cwd(), fullPath)
31599
+ filePath: path12__default.default.relative(process.cwd(), fullPath)
31644
31600
  });
31645
31601
  }
31646
31602
  }
@@ -31650,7 +31606,7 @@ async function discoverSchemaUsage(appDir) {
31650
31606
  return usages;
31651
31607
  }
31652
31608
  async function syncSchemasToPortal(apiUrl, apiKey, dryRun) {
31653
- const appDir = findAppDir();
31609
+ const appDir = chunkP4TB4ROG_js.findAppDirForDiscovery();
31654
31610
  if (!appDir) {
31655
31611
  console.log(source_default.gray(" No app directory found"));
31656
31612
  return;
@@ -31693,15 +31649,15 @@ async function apiRoutesCommand(options) {
31693
31649
  console.log("");
31694
31650
  console.log(source_default.bold(" Site-Kit API Routes"));
31695
31651
  console.log("");
31696
- const appDir = findAppDir2();
31652
+ const appDir = chunkP4TB4ROG_js.findAppDirForDiscovery();
31697
31653
  if (!appDir) {
31698
31654
  console.log(source_default.red(" \u2717 Could not find app directory"));
31699
31655
  console.log(source_default.gray(" Make sure you are in a Next.js project with an app directory"));
31700
31656
  console.log("");
31701
31657
  process.exit(1);
31702
31658
  }
31703
- const routeDir = path10__default.default.join(appDir, "_uptrade", "api", "[...path]");
31704
- const routeFile = path10__default.default.join(routeDir, "route.ts");
31659
+ const routeDir = path12__default.default.join(appDir, "_uptrade", "api", "[...path]");
31660
+ const routeFile = path12__default.default.join(routeDir, "route.ts");
31705
31661
  if (fs.existsSync(routeFile) && !options.force) {
31706
31662
  console.log(source_default.yellow(" \u26A0 API routes already exist"));
31707
31663
  console.log(source_default.gray(` ${routeFile}`));
@@ -31736,18 +31692,6 @@ async function apiRoutesCommand(options) {
31736
31692
  spinner.fail(`Failed to create API routes: ${error2.message}`);
31737
31693
  }
31738
31694
  }
31739
- function findAppDir2() {
31740
- const candidates = [
31741
- path10__default.default.join(process.cwd(), "app"),
31742
- path10__default.default.join(process.cwd(), "src", "app")
31743
- ];
31744
- for (const candidate of candidates) {
31745
- if (fs.existsSync(candidate)) {
31746
- return candidate;
31747
- }
31748
- }
31749
- return null;
31750
- }
31751
31695
  function generateRouteHandler() {
31752
31696
  return `/**
31753
31697
  * Sonor API Proxy
@@ -31852,12 +31796,12 @@ async function handleRequest(
31852
31796
  `;
31853
31797
  }
31854
31798
  function detectPackageManager(cwd) {
31855
- if (fs.existsSync(path10__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
31856
- if (fs.existsSync(path10__default.default.join(cwd, "yarn.lock"))) return "yarn";
31799
+ if (fs.existsSync(path12__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
31800
+ if (fs.existsSync(path12__default.default.join(cwd, "yarn.lock"))) return "yarn";
31857
31801
  return "npm";
31858
31802
  }
31859
31803
  async function run6(ctx, options) {
31860
- if (!fs.existsSync(path10__default.default.join(ctx.cwd, "package.json"))) {
31804
+ if (!fs.existsSync(path12__default.default.join(ctx.cwd, "package.json"))) {
31861
31805
  throw new UsageError(
31862
31806
  "NO_PACKAGE_JSON",
31863
31807
  "No package.json found",
@@ -31902,12 +31846,12 @@ async function installCommand(options) {
31902
31846
  await runCommand(ctx, (c) => run6(c, options), renderHuman4);
31903
31847
  }
31904
31848
  function detectPackageManager2(cwd) {
31905
- if (fs.existsSync(path10__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
31906
- if (fs.existsSync(path10__default.default.join(cwd, "yarn.lock"))) return "yarn";
31849
+ if (fs.existsSync(path12__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
31850
+ if (fs.existsSync(path12__default.default.join(cwd, "yarn.lock"))) return "yarn";
31907
31851
  return "npm";
31908
31852
  }
31909
31853
  async function run7(ctx, options) {
31910
- const pkgPath = path10__default.default.join(ctx.cwd, "package.json");
31854
+ const pkgPath = path12__default.default.join(ctx.cwd, "package.json");
31911
31855
  if (!fs.existsSync(pkgPath)) {
31912
31856
  throw new UsageError("NO_PACKAGE_JSON", "No package.json found", "Run this from your project root.");
31913
31857
  }
@@ -31962,21 +31906,21 @@ async function scaffoldCommand(options) {
31962
31906
  );
31963
31907
  console.log("");
31964
31908
  const cwd = process.cwd();
31965
- const appDir = await findAppDir3();
31909
+ const appDir = chunkP4TB4ROG_js.findAppDirForDiscovery(cwd);
31966
31910
  if (!appDir) {
31967
31911
  console.log(source_default.red(" \u2717 No app directory found (app/ or src/app/)"));
31968
31912
  process.exit(1);
31969
31913
  }
31970
31914
  const files = [
31971
31915
  {
31972
- path: path10__default.default.join(appDir, "sitemap.ts"),
31916
+ path: path12__default.default.join(appDir, "sitemap.ts"),
31973
31917
  label: "Sitemap",
31974
31918
  content: `import { createSitemap } from '@sonordev/site-kit/sitemap'
31975
31919
 
31976
31920
  export default createSitemap({
31977
31921
  // baseUrl auto-resolved from Portal via API key
31978
- includeLlmsTxtInSitemap: true,
31979
- includeLlmsFullTxtInSitemap: true,
31922
+ // llms.txt stays out of the sitemap on purpose: it's a plain-text duplicate
31923
+ // of these pages, and AI crawlers find it at /llms.txt anyway.
31980
31924
  // optimizedLLMsTxt: true, // optional: static build writes optimized llms (CI)
31981
31925
  // llmsPublicSummaryOnly: true, // optional: page list from Portal public summaries only
31982
31926
  // additionalPaths: async () => [...],
@@ -31984,7 +31928,7 @@ export default createSitemap({
31984
31928
  `
31985
31929
  },
31986
31930
  {
31987
- path: path10__default.default.join(appDir, "robots.txt", "route.ts"),
31931
+ path: path12__default.default.join(appDir, "robots.txt", "route.ts"),
31988
31932
  label: "Robots.txt",
31989
31933
  content: `import { createRobots } from '@sonordev/site-kit/robots'
31990
31934
 
@@ -31992,7 +31936,7 @@ export const GET = createRobots({})
31992
31936
  `
31993
31937
  },
31994
31938
  {
31995
- path: path10__default.default.join(appDir, "llms.txt", "route.ts"),
31939
+ path: path12__default.default.join(appDir, "llms.txt", "route.ts"),
31996
31940
  label: "llms.txt",
31997
31941
  content: `import { createLLMsTxtHandler } from '@sonordev/site-kit/llms'
31998
31942
 
@@ -32000,7 +31944,7 @@ export const GET = createLLMsTxtHandler({ preferStatic: true })
32000
31944
  `
32001
31945
  },
32002
31946
  {
32003
- path: path10__default.default.join(appDir, "llms-full.txt", "route.ts"),
31947
+ path: path12__default.default.join(appDir, "llms-full.txt", "route.ts"),
32004
31948
  label: "llms-full.txt",
32005
31949
  content: `import { createLLMsFullTxtHandler } from '@sonordev/site-kit/llms'
32006
31950
 
@@ -32011,14 +31955,14 @@ export const GET = createLLMsFullTxtHandler({ preferStatic: true })
32011
31955
  if (!options.minimal) {
32012
31956
  files.push(
32013
31957
  {
32014
- path: path10__default.default.join(cwd, "proxy.ts"),
32015
- label: "Proxy (security headers; redirects resolve at the 404 boundary)",
31958
+ path: path12__default.default.join(cwd, "proxy.ts"),
31959
+ label: "Proxy (security headers, managed redirects)",
32016
31960
  content: `import { createProxy } from '@sonordev/site-kit/proxy'
32017
31961
 
32018
- // redirects: false \u2014 managed redirects resolve in app/not-found.tsx via
32019
- // resolveManagedRedirect() instead of on every request. The proxy still
32020
- // stamps x-sk-path so the 404 boundary knows the requested URL.
32021
- export default createProxy({ redirects: false })
31962
+ // Sonor-managed redirects apply here. The rule list is cached in memory for
31963
+ // five minutes, so page loads rarely wait on it. Don't move them into
31964
+ // app/not-found.tsx: reading request headers there makes every page dynamic.
31965
+ export default createProxy({ redirects: true })
32022
31966
 
32023
31967
  // Inlined on purpose: Next statically parses \`config.matcher\` at build time
32024
31968
  // and rejects an imported value (Turbopack build error). Keep in sync with
@@ -32031,7 +31975,7 @@ export const config = {
32031
31975
  `
32032
31976
  },
32033
31977
  {
32034
- path: path10__default.default.join(appDir, "manifest.webmanifest", "route.ts"),
31978
+ path: path12__default.default.join(appDir, "manifest.webmanifest", "route.ts"),
32035
31979
  label: "PWA Manifest",
32036
31980
  content: `import { createManifest } from '@sonordev/site-kit/manifest'
32037
31981
 
@@ -32039,19 +31983,12 @@ export const GET = createManifest()
32039
31983
  `
32040
31984
  },
32041
31985
  {
32042
- path: path10__default.default.join(appDir, "not-found.tsx"),
32043
- label: "404 Page (resolves managed redirects)",
32044
- content: `import { redirect, permanentRedirect } from 'next/navigation'
32045
- import { resolveManagedRedirect } from '@sonordev/site-kit/redirects/not-found'
32046
-
32047
- export default async function NotFound() {
32048
- // Sonor-managed redirects resolve here, at the only place they can matter:
32049
- // a URL that would otherwise 404. Successful page loads pay nothing.
32050
- const managed = await resolveManagedRedirect()
32051
- if (managed) {
32052
- ;(managed.permanent ? permanentRedirect : redirect)(managed.destination)
32053
- }
32054
-
31986
+ path: path12__default.default.join(appDir, "not-found.tsx"),
31987
+ label: "404 Page",
31988
+ content: `// Keep this component free of request APIs (headers, cookies). Next
31989
+ // renders the root 404 inside every page, so one headers() call here makes
31990
+ // the whole site dynamic. Managed redirects run in proxy.ts instead.
31991
+ export default function NotFound() {
32055
31992
  return (
32056
31993
  <div style={{ textAlign: 'center', padding: '4rem 1rem' }}>
32057
31994
  <h1 style={{ fontSize: '3rem', fontWeight: 700, marginBottom: '0.5rem' }}>404</h1>
@@ -32079,7 +32016,7 @@ export default async function NotFound() {
32079
32016
  `
32080
32017
  },
32081
32018
  {
32082
- path: path10__default.default.join(appDir, "error.tsx"),
32019
+ path: path12__default.default.join(appDir, "error.tsx"),
32083
32020
  label: "Error Boundary",
32084
32021
  content: `'use client'
32085
32022
 
@@ -32119,7 +32056,7 @@ export default function Error({
32119
32056
  `
32120
32057
  },
32121
32058
  {
32122
- path: path10__default.default.join(cwd, "og.config.ts"),
32059
+ path: path12__default.default.join(cwd, "og.config.ts"),
32123
32060
  label: "OG card config (run: sonor-setup og)",
32124
32061
  content: `import { defineOgCard } from '@sonordev/site-kit/og'
32125
32062
 
@@ -32148,7 +32085,7 @@ export default defineOgCard({
32148
32085
  // .env.local, not .env.example: one real env file per project. The
32149
32086
  // deployer copies these values into the host's env settings. Skipped
32150
32087
  // when the file already exists, so real keys are never touched.
32151
- path: path10__default.default.join(cwd, ".env.local"),
32088
+ path: path12__default.default.join(cwd, ".env.local"),
32152
32089
  label: ".env.local",
32153
32090
  content: `# ===================================
32154
32091
  # @sonordev/site-kit \u2014 Environment Variables
@@ -32170,10 +32107,10 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
32170
32107
  if (options.dryRun) {
32171
32108
  console.log(source_default.yellow(" [DRY RUN] Would create:"));
32172
32109
  for (const f of files) {
32173
- const rel = path10__default.default.relative(cwd, f.path);
32174
- const exists = fs.existsSync(f.path);
32110
+ const rel = path12__default.default.relative(cwd, f.path);
32111
+ const exists2 = fs.existsSync(f.path);
32175
32112
  console.log(
32176
- source_default.gray(` ${rel}`) + (exists ? source_default.yellow(" (exists, would skip)") : "")
32113
+ source_default.gray(` ${rel}`) + (exists2 ? source_default.yellow(" (exists, would skip)") : "")
32177
32114
  );
32178
32115
  }
32179
32116
  console.log("");
@@ -32185,13 +32122,13 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
32185
32122
  for (const f of files) {
32186
32123
  try {
32187
32124
  if (fs.existsSync(f.path) && !options.force) {
32188
- spinner.warn(`Skipped (exists): ${path10__default.default.relative(cwd, f.path)}`);
32125
+ spinner.warn(`Skipped (exists): ${path12__default.default.relative(cwd, f.path)}`);
32189
32126
  skipped++;
32190
32127
  continue;
32191
32128
  }
32192
- await fs3__default.default.mkdir(path10__default.default.dirname(f.path), { recursive: true });
32129
+ await fs3__default.default.mkdir(path12__default.default.dirname(f.path), { recursive: true });
32193
32130
  await fs3__default.default.writeFile(f.path, f.content, "utf-8");
32194
- spinner.succeed(`${f.label}: ${path10__default.default.relative(cwd, f.path)}`);
32131
+ spinner.succeed(`${f.label}: ${path12__default.default.relative(cwd, f.path)}`);
32195
32132
  created++;
32196
32133
  } catch (err) {
32197
32134
  spinner.fail(`Failed: ${f.path}`);
@@ -32237,17 +32174,209 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
32237
32174
  console.log("");
32238
32175
  }
32239
32176
  }
32240
- async function findAppDir3() {
32241
- const cwd = process.cwd();
32242
- const candidates = [
32243
- path10__default.default.join(cwd, "app"),
32244
- path10__default.default.join(cwd, "src", "app")
32245
- ];
32246
- for (const dir of candidates) {
32247
- if (fs.existsSync(dir)) return dir;
32177
+ var LLMS_FILES = [
32178
+ { path: "/llms.txt", handler: "createLLMsTxtHandler" },
32179
+ { path: "/llms-full.txt", handler: "createLLMsFullTxtHandler" }
32180
+ ];
32181
+ var NEXT_CONFIGS = ["next.config.ts", "next.config.mts", "next.config.mjs", "next.config.js", "next.config.cjs"];
32182
+ function read(cwd, rel) {
32183
+ try {
32184
+ return fs__namespace.default.readFileSync(path12__default.default.join(cwd, rel), "utf-8");
32185
+ } catch {
32186
+ return "";
32187
+ }
32188
+ }
32189
+ function exists(cwd, rel) {
32190
+ try {
32191
+ return fs__namespace.default.existsSync(path12__default.default.join(cwd, rel));
32192
+ } catch {
32193
+ return false;
32194
+ }
32195
+ }
32196
+ function patternMatches(pattern, urlPath) {
32197
+ const re2 = pattern.trim().split(/\(\.\*\)|:\w+\*|\*/).map((part) => part.replace(/[.+?^${}()|[\]\\]/g, "\\$&")).join(".*");
32198
+ return new RegExp(`^${re2}$`).test(urlPath);
32199
+ }
32200
+ var NOINDEX = /noindex/i;
32201
+ function netlifyTomlNoindex(toml, urlPath) {
32202
+ const blocks = [];
32203
+ for (const line of toml.split("\n")) {
32204
+ const header = line.match(/^\s*\[\[?\s*([^\]]+?)\s*\]\]?\s*$/);
32205
+ if (header && header[1] !== "headers.values") blocks.push(line);
32206
+ else if (blocks.length) blocks[blocks.length - 1] += `
32207
+ ${line}`;
32208
+ }
32209
+ return blocks.some((block) => {
32210
+ if (!/^\s*\[\[\s*headers\s*\]\]/.test(block)) return false;
32211
+ const pattern = block.match(/^\s*for\s*=\s*["']([^"']+)["']/m)?.[1];
32212
+ const value = block.match(/^\s*["']?X-Robots-Tag["']?\s*=\s*["']([^"']*)["']/im)?.[1];
32213
+ return !!pattern && !!value && NOINDEX.test(value) && patternMatches(pattern, urlPath);
32214
+ });
32215
+ }
32216
+ function headersFileNoindex(text, urlPath) {
32217
+ let current = null;
32218
+ for (const line of text.split("\n")) {
32219
+ if (!line.trim() || line.trim().startsWith("#")) continue;
32220
+ if (!/^\s/.test(line)) {
32221
+ current = line.trim();
32222
+ continue;
32223
+ }
32224
+ const m = line.match(/^\s+X-Robots-Tag\s*:\s*(.+)$/i);
32225
+ if (current && m && NOINDEX.test(m[1]) && patternMatches(current, urlPath)) return true;
32226
+ }
32227
+ return false;
32228
+ }
32229
+ function vercelJsonNoindex(text, urlPath) {
32230
+ try {
32231
+ const json = JSON.parse(text);
32232
+ return (json.headers ?? []).some(
32233
+ (rule) => !!rule.source && patternMatches(rule.source, urlPath) && (rule.headers ?? []).some((h) => /^x-robots-tag$/i.test(h.key ?? "") && NOINDEX.test(h.value ?? ""))
32234
+ );
32235
+ } catch {
32236
+ return false;
32237
+ }
32238
+ }
32239
+ function findHostNoindex(cwd, urlPath) {
32240
+ const toml = read(cwd, "netlify.toml");
32241
+ if (toml && netlifyTomlNoindex(toml, urlPath)) return "netlify.toml";
32242
+ const headers = read(cwd, "public/_headers");
32243
+ if (headers && headersFileNoindex(headers, urlPath)) return "public/_headers";
32244
+ const vercel = read(cwd, "vercel.json");
32245
+ if (vercel && vercelJsonNoindex(vercel, urlPath)) return "vercel.json";
32246
+ return null;
32247
+ }
32248
+ var LINK_DISCOVERY_LINE = /^.*\bLink\b.*(llms[^\n]*describedby|describedby[^\n]*llms).*$/im;
32249
+ function findDiscoverySource(cwd) {
32250
+ for (const rel of chunkP4TB4ROG_js.findProxyFiles(cwd)) {
32251
+ const src = read(cwd, rel);
32252
+ const viaFactory = /\bcreate(Proxy|Middleware)\s*\(/.test(src) && /\bllmsDiscovery\b(?!\s*:\s*false\b)/.test(src);
32253
+ if (viaFactory) return `${rel} (createProxy llmsDiscovery)`;
32254
+ if (src.includes("buildAiDiscoveryHeaders")) return `${rel} (buildAiDiscoveryHeaders)`;
32255
+ }
32256
+ for (const rel of NEXT_CONFIGS) {
32257
+ const src = read(cwd, rel);
32258
+ if (!src) continue;
32259
+ if (/\bllmsTxtDiscoveryLink\s*:(?!\s*false\b)/.test(src)) return `${rel} (llmsTxtDiscoveryLink)`;
32260
+ if (src.includes("buildAiDiscoveryHeaders")) return `${rel} (buildAiDiscoveryHeaders)`;
32261
+ break;
32262
+ }
32263
+ const layout = chunkP4TB4ROG_js.findRootLayout(cwd);
32264
+ if (layout) {
32265
+ const src = read(cwd, path12__default.default.relative(cwd, layout));
32266
+ if (src.includes("buildAiDiscoveryHeaders") || src.includes("llmsTxtDiscoveryLink")) {
32267
+ return path12__default.default.relative(cwd, layout);
32268
+ }
32269
+ }
32270
+ for (const rel of ["netlify.toml", "public/_headers"]) {
32271
+ if (LINK_DISCOVERY_LINE.test(read(cwd, rel))) return rel;
32248
32272
  }
32249
32273
  return null;
32250
32274
  }
32275
+ function readGeoWiring(cwd) {
32276
+ const appDir = chunkP4TB4ROG_js.NEXT_APP_DIRS.find((rel) => exists(cwd, rel)) ?? null;
32277
+ const sitemap = chunkP4TB4ROG_js.findSitemapRoute(cwd);
32278
+ const sitemapSrc = sitemap ? read(cwd, sitemap) : "";
32279
+ const sitemapListsLlms = /\bincludeLlms(Full)?TxtInSitemap\s*:\s*true\b/.test(sitemapSrc) || /['"`/]llms(-full)?\.txt['"`]/.test(sitemapSrc);
32280
+ const sitemapWritesStatic = /\bcreateSitemap\s*\(/.test(sitemapSrc);
32281
+ const writesLlms = sitemapWritesStatic && !/\boptimizedLLMsTxt\s*:\s*false\b/.test(sitemapSrc);
32282
+ const writesLlmsFull = writesLlms && /\boptimizedLLMsFullTxt\s*:\s*true\b/.test(sitemapSrc);
32283
+ const llms = LLMS_FILES.map(({ path: urlPath, handler }) => {
32284
+ const file = urlPath.slice(1);
32285
+ const routeAbs = appDir ? chunkP4TB4ROG_js.findConventionFile(path12__default.default.join(cwd, appDir, file), "route") : null;
32286
+ const route = routeAbs ? path12__default.default.relative(cwd, routeAbs) : null;
32287
+ const routeSrc = route ? read(cwd, route) : "";
32288
+ const publicFile = exists(cwd, path12__default.default.join("public", file));
32289
+ const built = urlPath === "/llms.txt" ? writesLlms : writesLlmsFull;
32290
+ return {
32291
+ path: urlPath,
32292
+ route,
32293
+ routeUsesKitHandler: routeSrc.includes(handler),
32294
+ routeOptsOutOfNoindex: /\bnoindex\s*:\s*false\b/.test(routeSrc),
32295
+ routeSetsNoindex: /X-Robots-Tag/i.test(routeSrc) && NOINDEX.test(routeSrc),
32296
+ servedStatic: publicFile || built,
32297
+ staticReason: publicFile ? `public/${file}` : built ? `public/${file} (written by createSitemap at build)` : null,
32298
+ hostNoindex: findHostNoindex(cwd, urlPath)
32299
+ };
32300
+ });
32301
+ return { appDir, llms, sitemap, sitemapListsLlms, discovery: findDiscoverySource(cwd) };
32302
+ }
32303
+ var DISCOVERY_FIX = "Add llmsDiscovery to the proxy: createProxy({ llmsDiscovery: { siteUrl } }) in proxy.ts. Or withSiteKitConfig({ llmsTxtDiscoveryLink: true }) in next.config.";
32304
+ 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.";
32305
+ function hostNoindexFix(urlPath) {
32306
+ 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"`;
32307
+ }
32308
+ function judgeGeoWiring(facts) {
32309
+ const rows = [];
32310
+ for (const f of facts.llms) {
32311
+ const name = f.path.slice(1);
32312
+ const id = f.path === "/llms.txt" ? "llms" : "llms-full";
32313
+ const served = !!f.route || f.servedStatic;
32314
+ rows.push(
32315
+ served ? { id: `${id}.served`, label: `${name} served`, level: "ok", detail: f.route ?? f.staticReason ?? void 0 } : {
32316
+ id: `${id}.served`,
32317
+ label: `${name} served`,
32318
+ level: "fail",
32319
+ detail: `no ${facts.appDir ?? "app"}/${name}/route.* and no public/${name}`,
32320
+ fix: "Run: sonor-setup geo --ensure-routes"
32321
+ }
32322
+ );
32323
+ }
32324
+ if (!facts.sitemap) {
32325
+ rows.push({ id: "geo.sitemap", label: "sitemap leaves llms files out", level: "info", detail: "no sitemap route to check" });
32326
+ } else if (facts.sitemapListsLlms) {
32327
+ rows.push({
32328
+ id: "geo.sitemap",
32329
+ label: "sitemap leaves llms files out",
32330
+ level: "warn",
32331
+ detail: `${facts.sitemap} lists /llms.txt, inviting search engines to index a thin plain-text duplicate`,
32332
+ fix: SITEMAP_FIX
32333
+ });
32334
+ } else {
32335
+ rows.push({ id: "geo.sitemap", label: "sitemap leaves llms files out", level: "ok", detail: facts.sitemap });
32336
+ }
32337
+ rows.push(
32338
+ facts.discovery ? { id: "geo.discovery", label: 'discovery header (Link rel="describedby")', level: "ok", detail: facts.discovery } : {
32339
+ id: "geo.discovery",
32340
+ label: 'discovery header (Link rel="describedby")',
32341
+ level: "fail",
32342
+ detail: "not wired in proxy, next.config, root layout, or host config",
32343
+ fix: DISCOVERY_FIX
32344
+ }
32345
+ );
32346
+ for (const f of facts.llms) {
32347
+ if (!f.route && !f.servedStatic) continue;
32348
+ const name = f.path.slice(1);
32349
+ const id = `${f.path === "/llms.txt" ? "llms" : "llms-full"}.noindex`;
32350
+ const label = `${name} sends X-Robots-Tag: noindex`;
32351
+ if (f.servedStatic) {
32352
+ rows.push(
32353
+ f.hostNoindex ? { id, label, level: "ok", detail: f.hostNoindex } : { id, label, level: "warn", detail: `${f.staticReason} is served without it`, fix: hostNoindexFix(f.path) }
32354
+ );
32355
+ continue;
32356
+ }
32357
+ if (f.hostNoindex) {
32358
+ rows.push({ id, label, level: "ok", detail: f.hostNoindex });
32359
+ } else if (f.routeUsesKitHandler && !f.routeOptsOutOfNoindex) {
32360
+ rows.push({ id, label, level: "ok", detail: `${f.route} (site-kit handler default)` });
32361
+ } else if (f.routeSetsNoindex) {
32362
+ rows.push({ id, label, level: "ok", detail: f.route });
32363
+ } else {
32364
+ rows.push({
32365
+ id,
32366
+ label,
32367
+ level: "warn",
32368
+ detail: f.routeOptsOutOfNoindex ? `${f.route} passes noindex: false` : `${f.route} doesn't set it`,
32369
+ 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."
32370
+ });
32371
+ }
32372
+ }
32373
+ return rows;
32374
+ }
32375
+ function checkGeoWiring(cwd) {
32376
+ return judgeGeoWiring(readGeoWiring(cwd));
32377
+ }
32378
+
32379
+ // src/cli/commands/geo.ts
32251
32380
  var LLMS_ROUTE = `import { createLLMsTxtHandler } from '@sonordev/site-kit/llms'
32252
32381
 
32253
32382
  export const GET = createLLMsTxtHandler({ preferStatic: true })
@@ -32256,40 +32385,36 @@ var LLMS_FULL_ROUTE = `import { createLLMsFullTxtHandler } from '@sonordev/site-
32256
32385
 
32257
32386
  export const GET = createLLMsFullTxtHandler({ preferStatic: true })
32258
32387
  `;
32259
- async function readIfExists(p) {
32260
- if (!fs.existsSync(p)) return "";
32261
- try {
32262
- return await fs3__default.default.readFile(p, "utf-8");
32263
- } catch {
32264
- return "";
32265
- }
32266
- }
32388
+ var ICON = {
32389
+ ok: source_default.green(" \u2713 "),
32390
+ info: source_default.gray(" \xB7 "),
32391
+ warn: source_default.yellow(" ! "),
32392
+ fail: source_default.red(" \u2717 ")
32393
+ };
32267
32394
  async function ensureLlmsRouteFiles(appDir, dryRun) {
32268
- const llms = path10__default.default.join(appDir, "llms.txt", "route.ts");
32269
- const llmsFull = path10__default.default.join(appDir, "llms-full.txt", "route.ts");
32270
32395
  let n5 = 0;
32271
32396
  if (dryRun) return 0;
32272
- if (!fs.existsSync(llms)) {
32273
- await fs3__default.default.mkdir(path10__default.default.dirname(llms), { recursive: true });
32274
- await fs3__default.default.writeFile(llms, LLMS_ROUTE, "utf-8");
32275
- n5++;
32276
- }
32277
- if (!fs.existsSync(llmsFull)) {
32278
- await fs3__default.default.mkdir(path10__default.default.dirname(llmsFull), { recursive: true });
32279
- await fs3__default.default.writeFile(llmsFull, LLMS_FULL_ROUTE, "utf-8");
32397
+ for (const [dir, source] of [
32398
+ ["llms.txt", LLMS_ROUTE],
32399
+ ["llms-full.txt", LLMS_FULL_ROUTE]
32400
+ ]) {
32401
+ if (chunkP4TB4ROG_js.findConventionFile(path12__default.default.join(appDir, dir), "route")) continue;
32402
+ const file = path12__default.default.join(appDir, dir, "route.ts");
32403
+ await fs3__default.default.mkdir(path12__default.default.dirname(file), { recursive: true });
32404
+ await fs3__default.default.writeFile(file, source, "utf-8");
32280
32405
  n5++;
32281
32406
  }
32282
32407
  return n5;
32283
32408
  }
32284
32409
  async function geoCommand(options) {
32285
32410
  if (options.forInstall) {
32286
- const appDir2 = await findAppDir3();
32411
+ const appDir2 = chunkP4TB4ROG_js.findAppDirForDiscovery();
32287
32412
  if (!appDir2) return;
32288
32413
  const created = await ensureLlmsRouteFiles(appDir2, options.dryRun);
32289
32414
  if (created > 0) {
32290
32415
  console.log(
32291
32416
  source_default.cyan(
32292
- `[@sonordev/site-kit] Created ${created} llms route file(s). Set NEXT_PUBLIC_SITE_URL, use createSitemap({ includeLlmsTxtInSitemap: true }), and withSiteKitConfig({ llmsTxtDiscoveryLink: true }) when ready.`
32417
+ `[@sonordev/site-kit] Created ${created} llms route file(s). Set NEXT_PUBLIC_SITE_URL and add createProxy({ llmsDiscovery: { siteUrl } }) to proxy.ts when ready.`
32293
32418
  )
32294
32419
  );
32295
32420
  }
@@ -32304,59 +32429,20 @@ async function geoCommand(options) {
32304
32429
  )
32305
32430
  );
32306
32431
  console.log("");
32307
- const appDir = await findAppDir3();
32432
+ const appDir = chunkP4TB4ROG_js.findAppDirForDiscovery();
32308
32433
  if (!appDir) {
32309
32434
  console.log(source_default.red(" \u2717 No app directory (app/ or src/app/)"));
32310
32435
  process.exit(1);
32311
32436
  }
32312
- const llms = path10__default.default.join(appDir, "llms.txt", "route.ts");
32313
- const llmsFull = path10__default.default.join(appDir, "llms-full.txt", "route.ts");
32314
- const sitemap = path10__default.default.join(appDir, "sitemap.ts");
32315
32437
  let allOk = true;
32316
- const row = (label, pass) => {
32317
- if (!pass) allOk = false;
32318
- console.log(
32319
- (pass ? source_default.green(" \u2713 ") : source_default.red(" \u2717 ")) + label
32320
- );
32321
- };
32322
- row("llms.txt route", fs.existsSync(llms));
32323
- row("llms-full.txt route", fs.existsSync(llmsFull));
32324
- let sitemapHasLlms = false;
32325
- if (fs.existsSync(sitemap)) {
32326
- const txt = await readIfExists(sitemap);
32327
- sitemapHasLlms = txt.includes("includeLlmsTxtInSitemap") || txt.includes("includeLlmsFullTxtInSitemap");
32328
- row("sitemap.ts lists llms URLs", sitemapHasLlms);
32329
- } else {
32330
- row("sitemap.ts lists llms URLs", false);
32331
- }
32332
- const nextConfigs = [
32333
- path10__default.default.join(cwd, "next.config.ts"),
32334
- path10__default.default.join(cwd, "next.config.mjs"),
32335
- path10__default.default.join(cwd, "next.config.js")
32336
- ];
32337
- let nextCfg = "";
32338
- for (const p of nextConfigs) {
32339
- if (fs.existsSync(p)) {
32340
- nextCfg = await readIfExists(p);
32341
- break;
32438
+ for (const row of checkGeoWiring(cwd)) {
32439
+ if (row.level === "fail") allOk = false;
32440
+ const detail = row.detail ? source_default.gray(` ${row.detail}`) : "";
32441
+ console.log(`${ICON[row.level]}${row.label}${detail}`);
32442
+ if (row.fix && (row.level === "fail" || row.level === "warn")) {
32443
+ console.log(source_default.gray(` ${row.fix}`));
32342
32444
  }
32343
32445
  }
32344
- const layoutCandidates = [
32345
- path10__default.default.join(appDir, "layout.tsx"),
32346
- path10__default.default.join(appDir, "layout.jsx"),
32347
- path10__default.default.join(appDir, "layout.js")
32348
- ];
32349
- let layoutTxt = "";
32350
- for (const p of layoutCandidates) {
32351
- layoutTxt = await readIfExists(p);
32352
- if (layoutTxt) break;
32353
- }
32354
- const hasLayoutDiscovery = layoutTxt.includes("buildAiDiscoveryHeaders") || layoutTxt.includes("llmsTxtDiscoveryLink");
32355
- const hasConfigDiscovery = nextCfg.includes("llmsTxtDiscoveryLink");
32356
- row(
32357
- "discovery header (next.config or root layout)",
32358
- hasConfigDiscovery || hasLayoutDiscovery
32359
- );
32360
32446
  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(/\/$/, "")}` : "");
32361
32447
  if (siteUrl) {
32362
32448
  console.log(source_default.gray(` Public origin (env): ${siteUrl}`));
@@ -32382,19 +32468,16 @@ async function geoCommand(options) {
32382
32468
  console.log(source_default.bold(" Automation"));
32383
32469
  console.log("");
32384
32470
  console.log(
32385
- source_default.gray(
32386
- " \u2022 next.config: withSiteKitConfig({ llmsTxtDiscoveryLink: true })"
32387
- )
32471
+ source_default.gray(' \u2022 proxy.ts: createProxy({ llmsDiscovery: { siteUrl } }) (Link rel="describedby")')
32388
32472
  );
32389
32473
  console.log(
32390
- source_default.gray(
32391
- " (If you define your own headers() on nextConfig, merge Link manually.)"
32392
- )
32474
+ source_default.gray(" or next.config: withSiteKitConfig({ llmsTxtDiscoveryLink: true })")
32393
32475
  );
32394
32476
  console.log(
32395
- source_default.gray(
32396
- " \u2022 createSitemap({ includeLlmsTxtInSitemap: true, includeLlmsFullTxtInSitemap: true })"
32397
- )
32477
+ source_default.gray(" \u2022 createLLMsTxtHandler sends X-Robots-Tag: noindex; a static public/llms.txt needs it in netlify.toml")
32478
+ );
32479
+ console.log(
32480
+ source_default.gray(" \u2022 Keep llms.txt out of the sitemap: AI crawlers find it at /llms.txt")
32398
32481
  );
32399
32482
  console.log(
32400
32483
  source_default.gray(" \u2022 npx sonor-setup scaffold --minimal (routes + sitemap template)")
@@ -32404,10 +32487,10 @@ async function geoCommand(options) {
32404
32487
  }
32405
32488
 
32406
32489
  // src/cli/index.ts
32407
- (0, import_dotenv.config)({ path: ".env.local", quiet: true });
32408
- (0, import_dotenv.config)({ path: ".env", quiet: true });
32490
+ (0, import_dotenv2.config)({ path: ".env.local", quiet: true });
32491
+ (0, import_dotenv2.config)({ path: ".env", quiet: true });
32409
32492
  var program2 = new Command();
32410
- program2.name("sonor-setup").description("Setup + verification toolchain for @sonordev/site-kit").version(chunkSUZ3ZLB2_js.SITE_KIT_VERSION);
32493
+ program2.name("sonor-setup").description("Setup + verification toolchain for @sonordev/site-kit").version(chunk5TXXTYXL_js.SITE_KIT_VERSION);
32411
32494
  withAgentFlags(
32412
32495
  program2.command("verify").description("Verify the integration actually works (health + key + SSR) \u2014 exit 0 = done").option("--url <url>", "Verify a running/deployed URL server-renders (recommended for agents)").option("--offline", "Skip the network key-validity ping").option("--strict", "Treat warnings as failures")
32413
32496
  ).action(verifyCommand);