@sonordev/site-kit 5.4.0 → 5.6.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 (381) hide show
  1. package/AGENTS.md +16 -6
  2. package/README.md +9 -7
  3. package/agent-manifest.json +7 -7
  4. package/dist/AnalyticsProvider-6PXC7UDP.js +32 -0
  5. package/dist/{AnalyticsProvider-Y2P2BPOI.js.map → AnalyticsProvider-6PXC7UDP.js.map} +1 -1
  6. package/dist/AnalyticsProvider-FVQIYSLY.mjs +11 -0
  7. package/dist/{AnalyticsProvider-2XIOMRCN.mjs.map → AnalyticsProvider-FVQIYSLY.mjs.map} +1 -1
  8. package/dist/{BlogViewTracker-6EGEDPP3.js → BlogViewTracker-S4HSRCW7.js} +6 -6
  9. package/dist/{BlogViewTracker-6EGEDPP3.js.map → BlogViewTracker-S4HSRCW7.js.map} +1 -1
  10. package/dist/{BlogViewTracker-R4YQ76WP.mjs → BlogViewTracker-ZUGLBOVI.mjs} +5 -5
  11. package/dist/{BlogViewTracker-R4YQ76WP.mjs.map → BlogViewTracker-ZUGLBOVI.mjs.map} +1 -1
  12. package/dist/ChatWidget-2TQWCXWP.js +22 -0
  13. package/dist/{ChatWidget-2OFWPCWF.js.map → ChatWidget-2TQWCXWP.js.map} +1 -1
  14. package/dist/ChatWidget-DG52ZIE6.mjs +13 -0
  15. package/dist/{ChatWidget-4AOGHYXQ.mjs.map → ChatWidget-DG52ZIE6.mjs.map} +1 -1
  16. package/dist/EngageWidget-2VUJADIU.mjs +12 -0
  17. package/dist/{EngageWidget-SFO2XRNG.mjs.map → EngageWidget-2VUJADIU.mjs.map} +1 -1
  18. package/dist/EngageWidget-Z7RC2INM.js +21 -0
  19. package/dist/{EngageWidget-T4KAAD3G.js.map → EngageWidget-Z7RC2INM.js.map} +1 -1
  20. package/dist/{FileField-7DF2SLPF.mjs → FileField-FSQ7W3A5.mjs} +5 -5
  21. package/dist/{FileField-7DF2SLPF.mjs.map → FileField-FSQ7W3A5.mjs.map} +1 -1
  22. package/dist/{FileField-CE2XNBBG.js → FileField-UOQHL25J.js} +6 -6
  23. package/dist/{FileField-CE2XNBBG.js.map → FileField-UOQHL25J.js.map} +1 -1
  24. package/dist/{FormSpotlight-IRLKSZGV.mjs → FormSpotlight-RHL5FWM2.mjs} +3 -3
  25. package/dist/{FormSpotlight-IRLKSZGV.mjs.map → FormSpotlight-RHL5FWM2.mjs.map} +1 -1
  26. package/dist/{FormSpotlight-ZD3WR5BC.js → FormSpotlight-TED32NHP.js} +15 -15
  27. package/dist/{FormSpotlight-ZD3WR5BC.js.map → FormSpotlight-TED32NHP.js.map} +1 -1
  28. package/dist/{FormStage-2OSRNQJL.mjs → FormStage-DINIRFOX.mjs} +3 -3
  29. package/dist/{FormStage-2OSRNQJL.mjs.map → FormStage-DINIRFOX.mjs.map} +1 -1
  30. package/dist/{FormStage-OSPXOUQE.js → FormStage-PFEBKHGY.js} +13 -13
  31. package/dist/{FormStage-OSPXOUQE.js.map → FormStage-PFEBKHGY.js.map} +1 -1
  32. package/dist/ManagedForm-43WLCUAK.js +23 -0
  33. package/dist/{ManagedForm-JCHGBBQW.js.map → ManagedForm-43WLCUAK.js.map} +1 -1
  34. package/dist/ManagedForm-545YAUFC.mjs +14 -0
  35. package/dist/{ManagedForm-5G37EDJT.mjs.map → ManagedForm-545YAUFC.mjs.map} +1 -1
  36. package/dist/{ManagedNewsletterForm-4LVJZROZ.js → ManagedNewsletterForm-I3QN57HB.js} +8 -8
  37. package/dist/{ManagedNewsletterForm-4LVJZROZ.js.map → ManagedNewsletterForm-I3QN57HB.js.map} +1 -1
  38. package/dist/{ManagedNewsletterForm-QJSVH23S.mjs → ManagedNewsletterForm-ZPY5RRKX.mjs} +7 -7
  39. package/dist/{ManagedNewsletterForm-QJSVH23S.mjs.map → ManagedNewsletterForm-ZPY5RRKX.mjs.map} +1 -1
  40. package/dist/{SignalCore-L6Z3YTCF.mjs → SignalCore-EEH5IM4U.mjs} +5 -5
  41. package/dist/{SignalCore-L6Z3YTCF.mjs.map → SignalCore-EEH5IM4U.mjs.map} +1 -1
  42. package/dist/{SignalCore-NQ4YEOI7.js → SignalCore-M4AXIMV4.js} +11 -11
  43. package/dist/{SignalCore-NQ4YEOI7.js.map → SignalCore-M4AXIMV4.js.map} +1 -1
  44. package/dist/SitemapSync-46G7LVZS.mjs +9 -0
  45. package/dist/{SitemapSync-MYSTLJOM.mjs.map → SitemapSync-46G7LVZS.mjs.map} +1 -1
  46. package/dist/SitemapSync-XK4JKCS7.js +18 -0
  47. package/dist/{SitemapSync-3LUZWBTB.js.map → SitemapSync-XK4JKCS7.js.map} +1 -1
  48. package/dist/SitemapSync.d.ts +3 -2
  49. package/dist/SitemapSync.d.ts.map +1 -1
  50. package/dist/analytics/AnalyticsProvider.d.ts +3 -1
  51. package/dist/analytics/AnalyticsProvider.d.ts.map +1 -1
  52. package/dist/analytics/WebVitals.d.ts +3 -1
  53. package/dist/analytics/WebVitals.d.ts.map +1 -1
  54. package/dist/analytics/dispatch.d.ts +4 -4
  55. package/dist/analytics/index.js +19 -19
  56. package/dist/analytics/index.mjs +7 -7
  57. package/dist/analytics/send-gate.d.ts +8 -37
  58. package/dist/analytics/send-gate.d.ts.map +1 -1
  59. package/dist/{api-NTHZ6PAW.mjs → api-D745LGGU.mjs} +3 -3
  60. package/dist/api-D745LGGU.mjs.map +1 -0
  61. package/dist/{api-N5OLQXYN.js → api-XR5APCH3.js} +3 -3
  62. package/dist/api-XR5APCH3.js.map +1 -0
  63. package/dist/blog/index.js +20 -20
  64. package/dist/blog/index.mjs +3 -3
  65. package/dist/blog/server-ui.js +14 -14
  66. package/dist/blog/server-ui.mjs +2 -2
  67. package/dist/{chunk-HMFFAUCD.js → chunk-3DWIYCQX.js} +2 -2
  68. package/dist/chunk-3DWIYCQX.js.map +1 -0
  69. package/dist/{chunk-3EPMDPWI.js → chunk-3SDMJMN2.js} +5 -5
  70. package/dist/{chunk-3EPMDPWI.js.map → chunk-3SDMJMN2.js.map} +1 -1
  71. package/dist/{chunk-LIYSLNEK.mjs → chunk-473WDGQZ.mjs} +3 -3
  72. package/dist/{chunk-LIYSLNEK.mjs.map → chunk-473WDGQZ.mjs.map} +1 -1
  73. package/dist/chunk-4U5NCKQY.mjs +39 -0
  74. package/dist/chunk-4U5NCKQY.mjs.map +1 -0
  75. package/dist/{chunk-ITFZZ6YT.js → chunk-53KMRZT7.js} +3 -3
  76. package/dist/{chunk-ITFZZ6YT.js.map → chunk-53KMRZT7.js.map} +1 -1
  77. package/dist/{chunk-N6AVWMIB.mjs → chunk-5KIEZHVK.mjs} +19 -18
  78. package/dist/chunk-5KIEZHVK.mjs.map +1 -0
  79. package/dist/{chunk-ZLPXFV5Y.js → chunk-5KIO6FXE.js} +5 -5
  80. package/dist/{chunk-ZLPXFV5Y.js.map → chunk-5KIO6FXE.js.map} +1 -1
  81. package/dist/chunk-5RNAUYWE.js +50 -0
  82. package/dist/chunk-5RNAUYWE.js.map +1 -0
  83. package/dist/{chunk-ACTLQ2RH.mjs → chunk-5UFDHGFE.mjs} +4 -4
  84. package/dist/chunk-5UFDHGFE.mjs.map +1 -0
  85. package/dist/{chunk-RO55G3OA.mjs → chunk-64BOVMXG.mjs} +3 -3
  86. package/dist/{chunk-RO55G3OA.mjs.map → chunk-64BOVMXG.mjs.map} +1 -1
  87. package/dist/{chunk-G5I3XEQS.mjs → chunk-6OP5XSMM.mjs} +3 -3
  88. package/dist/{chunk-G5I3XEQS.mjs.map → chunk-6OP5XSMM.mjs.map} +1 -1
  89. package/dist/{chunk-7Y2UPFSY.mjs → chunk-7AUDKXY5.mjs} +3 -3
  90. package/dist/{chunk-7Y2UPFSY.mjs.map → chunk-7AUDKXY5.mjs.map} +1 -1
  91. package/dist/{chunk-A2VLEORI.mjs → chunk-7C7XO5HX.mjs} +3 -3
  92. package/dist/{chunk-A2VLEORI.mjs.map → chunk-7C7XO5HX.mjs.map} +1 -1
  93. package/dist/chunk-A6UYV475.mjs +45 -0
  94. package/dist/chunk-A6UYV475.mjs.map +1 -0
  95. package/dist/{chunk-SZHKNGNR.mjs → chunk-AEARU24Q.mjs} +40 -26
  96. package/dist/chunk-AEARU24Q.mjs.map +1 -0
  97. package/dist/{chunk-ZDFVYSKK.mjs → chunk-AHZR4VGY.mjs} +5 -5
  98. package/dist/{chunk-ZDFVYSKK.mjs.map → chunk-AHZR4VGY.mjs.map} +1 -1
  99. package/dist/{chunk-4WQB2ORG.js → chunk-AY7JBGYC.js} +15 -15
  100. package/dist/chunk-AY7JBGYC.js.map +1 -0
  101. package/dist/{chunk-5737U6DI.js → chunk-B64AZC6P.js} +15 -15
  102. package/dist/{chunk-5737U6DI.js.map → chunk-B64AZC6P.js.map} +1 -1
  103. package/dist/{chunk-ZY5AVC4P.js → chunk-B6O7D5U4.js} +55 -49
  104. package/dist/chunk-B6O7D5U4.js.map +1 -0
  105. package/dist/{chunk-LHYVFWHL.js → chunk-BWSMUSDB.js} +8 -8
  106. package/dist/{chunk-LHYVFWHL.js.map → chunk-BWSMUSDB.js.map} +1 -1
  107. package/dist/{chunk-WSUQ76LN.js → chunk-BZLIOT7Q.js} +18 -18
  108. package/dist/{chunk-WSUQ76LN.js.map → chunk-BZLIOT7Q.js.map} +1 -1
  109. package/dist/{chunk-HH5KGXTK.mjs → chunk-C2MSD2UM.mjs} +4 -4
  110. package/dist/{chunk-HH5KGXTK.mjs.map → chunk-C2MSD2UM.mjs.map} +1 -1
  111. package/dist/{chunk-DPDV5Z4G.js → chunk-CQRLKNHQ.js} +12 -12
  112. package/dist/{chunk-DPDV5Z4G.js.map → chunk-CQRLKNHQ.js.map} +1 -1
  113. package/dist/{chunk-SJXGIUHP.mjs → chunk-CQS5ZYI6.mjs} +22 -9
  114. package/dist/chunk-CQS5ZYI6.mjs.map +1 -0
  115. package/dist/{chunk-LUYUFILE.js → chunk-DHIWR7CG.js} +4 -4
  116. package/dist/{chunk-LUYUFILE.js.map → chunk-DHIWR7CG.js.map} +1 -1
  117. package/dist/chunk-DQUBETXH.mjs +6 -0
  118. package/dist/{chunk-7U7C6XRI.mjs.map → chunk-DQUBETXH.mjs.map} +1 -1
  119. package/dist/chunk-ESP5RMB7.js +42 -0
  120. package/dist/chunk-ESP5RMB7.js.map +1 -0
  121. package/dist/chunk-G6WF4G3E.js +43 -0
  122. package/dist/chunk-G6WF4G3E.js.map +1 -0
  123. package/dist/{chunk-XWF7QPIP.mjs → chunk-GJ6NOLGC.mjs} +3 -3
  124. package/dist/{chunk-XWF7QPIP.mjs.map → chunk-GJ6NOLGC.mjs.map} +1 -1
  125. package/dist/{chunk-MTANHZKJ.mjs → chunk-GPLCPMVD.mjs} +7 -7
  126. package/dist/{chunk-MTANHZKJ.mjs.map → chunk-GPLCPMVD.mjs.map} +1 -1
  127. package/dist/{chunk-QWLL3B6U.js → chunk-H3D3ZGOJ.js} +26 -23
  128. package/dist/chunk-H3D3ZGOJ.js.map +1 -0
  129. package/dist/{chunk-NUH245XK.mjs → chunk-H44XZUOV.mjs} +16 -13
  130. package/dist/chunk-H44XZUOV.mjs.map +1 -0
  131. package/dist/{chunk-MIFP6QEQ.mjs → chunk-HIHAXEPD.mjs} +4 -4
  132. package/dist/{chunk-MIFP6QEQ.mjs.map → chunk-HIHAXEPD.mjs.map} +1 -1
  133. package/dist/{chunk-UOLY4NXK.mjs → chunk-IYCLN3XS.mjs} +15 -34
  134. package/dist/chunk-IYCLN3XS.mjs.map +1 -0
  135. package/dist/{chunk-HBMF3M5F.js → chunk-JE5DWAE6.js} +4 -4
  136. package/dist/{chunk-HBMF3M5F.js.map → chunk-JE5DWAE6.js.map} +1 -1
  137. package/dist/{chunk-KQ3VAOAF.mjs → chunk-JNABXCLY.mjs} +4 -4
  138. package/dist/{chunk-KQ3VAOAF.mjs.map → chunk-JNABXCLY.mjs.map} +1 -1
  139. package/dist/{chunk-3TXX5KIN.js → chunk-JNRHTZL4.js} +2 -2
  140. package/dist/{chunk-3TXX5KIN.js.map → chunk-JNRHTZL4.js.map} +1 -1
  141. package/dist/{chunk-I4PDSDVE.mjs → chunk-K2V3ZW36.mjs} +3 -3
  142. package/dist/{chunk-I4PDSDVE.mjs.map → chunk-K2V3ZW36.mjs.map} +1 -1
  143. package/dist/{chunk-L2LJQIM3.js → chunk-KPKQKFT4.js} +11 -11
  144. package/dist/chunk-KPKQKFT4.js.map +1 -0
  145. package/dist/chunk-KSL3WA2I.js +8 -0
  146. package/dist/{chunk-UTOHMK52.js.map → chunk-KSL3WA2I.js.map} +1 -1
  147. package/dist/{chunk-VWDT7H6L.js → chunk-KY6M76JW.js} +3 -3
  148. package/dist/{chunk-VWDT7H6L.js.map → chunk-KY6M76JW.js.map} +1 -1
  149. package/dist/{chunk-EBMPXFOP.mjs → chunk-LCSYJXIO.mjs} +3 -3
  150. package/dist/{chunk-EBMPXFOP.mjs.map → chunk-LCSYJXIO.mjs.map} +1 -1
  151. package/dist/{chunk-AWFZIXCT.js → chunk-N2PGTPWN.js} +25 -12
  152. package/dist/chunk-N2PGTPWN.js.map +1 -0
  153. package/dist/chunk-NSWO43XW.mjs +39 -0
  154. package/dist/chunk-NSWO43XW.mjs.map +1 -0
  155. package/dist/{chunk-KMGGAL2X.js → chunk-NZSFOZJV.js} +40 -26
  156. package/dist/chunk-NZSFOZJV.js.map +1 -0
  157. package/dist/{chunk-JJ26JKBJ.mjs → chunk-OA7KKOAK.mjs} +25 -31
  158. package/dist/chunk-OA7KKOAK.mjs.map +1 -0
  159. package/dist/{chunk-GQ6CUOLA.js → chunk-OC7AO7XS.js} +15 -15
  160. package/dist/{chunk-GQ6CUOLA.js.map → chunk-OC7AO7XS.js.map} +1 -1
  161. package/dist/{chunk-HDDV63XJ.mjs → chunk-QNPVVWR7.mjs} +3 -3
  162. package/dist/{chunk-HDDV63XJ.mjs.map → chunk-QNPVVWR7.mjs.map} +1 -1
  163. package/dist/{chunk-URVGBWCP.js → chunk-R3KTBKSW.js} +4 -4
  164. package/dist/{chunk-URVGBWCP.js.map → chunk-R3KTBKSW.js.map} +1 -1
  165. package/dist/{chunk-6CUBSQMD.mjs → chunk-RIYAMYLV.mjs} +3 -3
  166. package/dist/{chunk-6CUBSQMD.mjs.map → chunk-RIYAMYLV.mjs.map} +1 -1
  167. package/dist/{chunk-B4BFQSSS.mjs → chunk-RU54J2PY.mjs} +4 -4
  168. package/dist/chunk-RU54J2PY.mjs.map +1 -0
  169. package/dist/{chunk-7IPSQ5JR.js → chunk-S4RC6VAQ.js} +21 -20
  170. package/dist/chunk-S4RC6VAQ.js.map +1 -0
  171. package/dist/{chunk-3DPXOZAU.mjs → chunk-SHLWA6JY.mjs} +2 -2
  172. package/dist/chunk-SHLWA6JY.mjs.map +1 -0
  173. package/dist/{chunk-OXZYP32B.js → chunk-SYGGZZMU.js} +21 -17
  174. package/dist/chunk-SYGGZZMU.js.map +1 -0
  175. package/dist/{chunk-LF4L3ZP5.js → chunk-T5VTQUNF.js} +8 -8
  176. package/dist/{chunk-LF4L3ZP5.js.map → chunk-T5VTQUNF.js.map} +1 -1
  177. package/dist/{chunk-UOTXSWKZ.mjs → chunk-TP7H6BSK.mjs} +2 -2
  178. package/dist/{chunk-UOTXSWKZ.mjs.map → chunk-TP7H6BSK.mjs.map} +1 -1
  179. package/dist/{chunk-N6X76QUF.mjs → chunk-USKIL6V6.mjs} +3 -3
  180. package/dist/{chunk-N6X76QUF.mjs.map → chunk-USKIL6V6.mjs.map} +1 -1
  181. package/dist/{chunk-2KIGFOPM.js → chunk-UU47DGHE.js} +25 -44
  182. package/dist/chunk-UU47DGHE.js.map +1 -0
  183. package/dist/{chunk-B36PTS7B.mjs → chunk-VHZ4LHQT.mjs} +48 -42
  184. package/dist/chunk-VHZ4LHQT.mjs.map +1 -0
  185. package/dist/{chunk-7PLH3H3W.js → chunk-X5TCH7VZ.js} +3 -3
  186. package/dist/{chunk-7PLH3H3W.js.map → chunk-X5TCH7VZ.js.map} +1 -1
  187. package/dist/{chunk-LBS4PRC7.js → chunk-XK5AIWQG.js} +3 -3
  188. package/dist/{chunk-LBS4PRC7.js.map → chunk-XK5AIWQG.js.map} +1 -1
  189. package/dist/{chunk-U53KN4SA.js → chunk-XR32C47O.js} +26 -32
  190. package/dist/chunk-XR32C47O.js.map +1 -0
  191. package/dist/{chunk-DQM5GR2P.mjs → chunk-YCI36ZUS.mjs} +18 -14
  192. package/dist/chunk-YCI36ZUS.mjs.map +1 -0
  193. package/dist/{chunk-VA36CJRV.js → chunk-YYN4YZYZ.js} +4 -4
  194. package/dist/{chunk-VA36CJRV.js.map → chunk-YYN4YZYZ.js.map} +1 -1
  195. package/dist/cli/agent/checks.d.ts.map +1 -1
  196. package/dist/cli/agent/ssr-bailout.d.ts +27 -0
  197. package/dist/cli/agent/ssr-bailout.d.ts.map +1 -0
  198. package/dist/cli/agent/ssr-bailout.test.d.ts +2 -0
  199. package/dist/cli/agent/ssr-bailout.test.d.ts.map +1 -0
  200. package/dist/cli/api/{uptrade.d.ts → sonor.d.ts} +3 -2
  201. package/dist/cli/api/sonor.d.ts.map +1 -0
  202. package/dist/cli/codemod/transforms.d.ts.map +1 -1
  203. package/dist/cli/commands/config-regression.test.d.ts +2 -0
  204. package/dist/cli/commands/config-regression.test.d.ts.map +1 -0
  205. package/dist/cli/commands/faqs.d.ts.map +1 -1
  206. package/dist/cli/commands/images.d.ts.map +1 -1
  207. package/dist/cli/commands/locations.d.ts.map +1 -1
  208. package/dist/cli/commands/migrate.d.ts.map +1 -1
  209. package/dist/cli/commands/setup.d.ts.map +1 -1
  210. package/dist/cli/config.d.ts +31 -0
  211. package/dist/cli/config.d.ts.map +1 -0
  212. package/dist/cli/config.test.d.ts +2 -0
  213. package/dist/cli/config.test.d.ts.map +1 -0
  214. package/dist/cli/index.js +494 -518
  215. package/dist/cli/index.js.map +1 -1
  216. package/dist/cli/index.mjs +487 -511
  217. package/dist/cli/index.mjs.map +1 -1
  218. package/dist/cli/migrator/index.d.ts +1 -0
  219. package/dist/cli/migrator/index.d.ts.map +1 -1
  220. package/dist/cli/state.d.ts +7 -0
  221. package/dist/cli/state.d.ts.map +1 -0
  222. package/dist/cli/state.test.d.ts +2 -0
  223. package/dist/cli/state.test.d.ts.map +1 -0
  224. package/dist/client/index.d.ts +1 -0
  225. package/dist/client/index.d.ts.map +1 -1
  226. package/dist/client/index.js +20 -7
  227. package/dist/client/index.js.map +1 -1
  228. package/dist/client/index.mjs +5 -4
  229. package/dist/client/index.mjs.map +1 -1
  230. package/dist/cms/index.js.map +1 -1
  231. package/dist/cms/index.mjs.map +1 -1
  232. package/dist/cms/sanity-image.d.ts +1 -1
  233. package/dist/commerce/index.js +59 -59
  234. package/dist/commerce/index.mjs +8 -8
  235. package/dist/engage/ChatWidget.d.ts.map +1 -1
  236. package/dist/engage/EngageWidget.d.ts +4 -4
  237. package/dist/engage/EngageWidget.d.ts.map +1 -1
  238. package/dist/engage/chat-launcher.test.d.ts +2 -0
  239. package/dist/engage/chat-launcher.test.d.ts.map +1 -0
  240. package/dist/engage/index.js +13 -10
  241. package/dist/engage/index.js.map +1 -1
  242. package/dist/engage/index.mjs +10 -7
  243. package/dist/engage/index.mjs.map +1 -1
  244. package/dist/engage/launcher-placement.d.ts +56 -0
  245. package/dist/engage/launcher-placement.d.ts.map +1 -0
  246. package/dist/engage/launcher-placement.test.d.ts +2 -0
  247. package/dist/engage/launcher-placement.test.d.ts.map +1 -0
  248. package/dist/engage/types.d.ts +41 -7
  249. package/dist/engage/types.d.ts.map +1 -1
  250. package/dist/fleet/FleetHeartbeat.d.ts +3 -2
  251. package/dist/fleet/FleetHeartbeat.d.ts.map +1 -1
  252. package/dist/fleet/heartbeat.d.ts +3 -2
  253. package/dist/fleet/heartbeat.d.ts.map +1 -1
  254. package/dist/fleet/heartbeat.test.d.ts +2 -0
  255. package/dist/fleet/heartbeat.test.d.ts.map +1 -0
  256. package/dist/fleet/index.js +9 -8
  257. package/dist/fleet/index.mjs +5 -4
  258. package/dist/forms/index.js +16 -16
  259. package/dist/forms/index.mjs +9 -9
  260. package/dist/forms/server.js +10 -10
  261. package/dist/forms/server.mjs +8 -8
  262. package/dist/forms/static.js +7 -7
  263. package/dist/forms/static.mjs +6 -6
  264. package/dist/images/ManagedImage.d.ts.map +1 -1
  265. package/dist/images/index.js +11 -11
  266. package/dist/images/index.mjs +4 -4
  267. package/dist/index.js +66 -66
  268. package/dist/index.mjs +12 -12
  269. package/dist/layout/SiteKitClientProviders.d.ts.map +1 -1
  270. package/dist/layout/client.d.ts.map +1 -1
  271. package/dist/layout/client.js +9 -8
  272. package/dist/layout/client.mjs +8 -7
  273. package/dist/layout/index.js +11 -10
  274. package/dist/layout/index.js.map +1 -1
  275. package/dist/layout/index.mjs +9 -8
  276. package/dist/layout/index.mjs.map +1 -1
  277. package/dist/layout/types.d.ts +9 -3
  278. package/dist/layout/types.d.ts.map +1 -1
  279. package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
  280. package/dist/llms/index.js +12 -12
  281. package/dist/llms/index.mjs +2 -2
  282. package/dist/llms/types.d.ts +7 -1
  283. package/dist/llms/types.d.ts.map +1 -1
  284. package/dist/maps/index.js +5 -5
  285. package/dist/maps/index.mjs +3 -3
  286. package/dist/mcp/WebMcpTools.d.ts +5 -2
  287. package/dist/mcp/WebMcpTools.d.ts.map +1 -1
  288. package/dist/mcp/client.js.map +1 -1
  289. package/dist/mcp/client.mjs.map +1 -1
  290. package/dist/search/index.js +4 -4
  291. package/dist/search/index.mjs +3 -3
  292. package/dist/seo/LocationPageContent.d.ts +6 -5
  293. package/dist/seo/LocationPageContent.d.ts.map +1 -1
  294. package/dist/seo/api.d.ts +4 -5
  295. package/dist/seo/api.d.ts.map +1 -1
  296. package/dist/seo/client.js +6 -6
  297. package/dist/seo/client.mjs +5 -5
  298. package/dist/seo/index.js +43 -43
  299. package/dist/seo/index.js.map +1 -1
  300. package/dist/seo/index.mjs +9 -9
  301. package/dist/seo/index.mjs.map +1 -1
  302. package/dist/seo/routing.d.ts +9 -23
  303. package/dist/seo/routing.d.ts.map +1 -1
  304. package/dist/seo/server-api.d.ts +11 -5
  305. package/dist/seo/server-api.d.ts.map +1 -1
  306. package/dist/seo/server.js +18 -18
  307. package/dist/seo/server.mjs +2 -2
  308. package/dist/server/index.js +3 -3
  309. package/dist/server/index.mjs +2 -2
  310. package/dist/{server-api-HW4PL2L2.mjs → server-api-RG3ZL3DV.mjs} +3 -3
  311. package/dist/{server-api-HW4PL2L2.mjs.map → server-api-RG3ZL3DV.mjs.map} +1 -1
  312. package/dist/{server-api-DB2SIUP4.js → server-api-RYJQAUGO.js} +21 -21
  313. package/dist/{server-api-DB2SIUP4.js.map → server-api-RYJQAUGO.js.map} +1 -1
  314. package/dist/shared/reporting-gate.d.ts +43 -0
  315. package/dist/shared/reporting-gate.d.ts.map +1 -0
  316. package/dist/shared/version.d.ts +1 -1
  317. package/dist/shared/visual-viewport-gap.d.ts +52 -0
  318. package/dist/shared/visual-viewport-gap.d.ts.map +1 -0
  319. package/dist/shared/visual-viewport-gap.test.d.ts +2 -0
  320. package/dist/shared/visual-viewport-gap.test.d.ts.map +1 -0
  321. package/dist/signal/index.js +11 -11
  322. package/dist/signal/index.mjs +2 -2
  323. package/dist/sitemap/index.js +2 -2
  324. package/dist/sitemap/index.mjs +1 -1
  325. package/dist/sync/AddToCalendar.d.ts +19 -0
  326. package/dist/sync/AddToCalendar.d.ts.map +1 -0
  327. package/dist/sync/BookingWidget.d.ts.map +1 -1
  328. package/dist/sync/add-to-calendar.test.d.ts +2 -0
  329. package/dist/sync/add-to-calendar.test.d.ts.map +1 -0
  330. package/dist/sync/api-errors.test.d.ts +2 -0
  331. package/dist/sync/api-errors.test.d.ts.map +1 -0
  332. package/dist/sync/api.d.ts.map +1 -1
  333. package/dist/sync/index.js +17 -17
  334. package/dist/sync/index.mjs +4 -4
  335. package/dist/sync/types.d.ts +14 -0
  336. package/dist/sync/types.d.ts.map +1 -1
  337. package/dist/types.d.ts +9 -0
  338. package/dist/types.d.ts.map +1 -1
  339. package/package.json +4 -4
  340. package/skills/site-kit/SKILL.md +8 -3
  341. package/dist/AnalyticsProvider-2XIOMRCN.mjs +0 -11
  342. package/dist/AnalyticsProvider-Y2P2BPOI.js +0 -32
  343. package/dist/ChatWidget-2OFWPCWF.js +0 -20
  344. package/dist/ChatWidget-4AOGHYXQ.mjs +0 -11
  345. package/dist/EngageWidget-SFO2XRNG.mjs +0 -9
  346. package/dist/EngageWidget-T4KAAD3G.js +0 -18
  347. package/dist/ManagedForm-5G37EDJT.mjs +0 -14
  348. package/dist/ManagedForm-JCHGBBQW.js +0 -23
  349. package/dist/SitemapSync-3LUZWBTB.js +0 -18
  350. package/dist/SitemapSync-MYSTLJOM.mjs +0 -9
  351. package/dist/api-N5OLQXYN.js.map +0 -1
  352. package/dist/api-NTHZ6PAW.mjs.map +0 -1
  353. package/dist/chunk-2KIGFOPM.js.map +0 -1
  354. package/dist/chunk-3DPXOZAU.mjs.map +0 -1
  355. package/dist/chunk-4WQB2ORG.js.map +0 -1
  356. package/dist/chunk-7IPSQ5JR.js.map +0 -1
  357. package/dist/chunk-7U7C6XRI.mjs +0 -6
  358. package/dist/chunk-ACTLQ2RH.mjs.map +0 -1
  359. package/dist/chunk-AWFZIXCT.js.map +0 -1
  360. package/dist/chunk-B36PTS7B.mjs.map +0 -1
  361. package/dist/chunk-B4BFQSSS.mjs.map +0 -1
  362. package/dist/chunk-DQM5GR2P.mjs.map +0 -1
  363. package/dist/chunk-HMFFAUCD.js.map +0 -1
  364. package/dist/chunk-JJ26JKBJ.mjs.map +0 -1
  365. package/dist/chunk-KMGGAL2X.js.map +0 -1
  366. package/dist/chunk-L2LJQIM3.js.map +0 -1
  367. package/dist/chunk-N6AVWMIB.mjs.map +0 -1
  368. package/dist/chunk-NUH245XK.mjs.map +0 -1
  369. package/dist/chunk-NVSWTDWU.mjs +0 -25
  370. package/dist/chunk-NVSWTDWU.mjs.map +0 -1
  371. package/dist/chunk-OL2QBWAU.js +0 -29
  372. package/dist/chunk-OL2QBWAU.js.map +0 -1
  373. package/dist/chunk-OXZYP32B.js.map +0 -1
  374. package/dist/chunk-QWLL3B6U.js.map +0 -1
  375. package/dist/chunk-SJXGIUHP.mjs.map +0 -1
  376. package/dist/chunk-SZHKNGNR.mjs.map +0 -1
  377. package/dist/chunk-U53KN4SA.js.map +0 -1
  378. package/dist/chunk-UOLY4NXK.mjs.map +0 -1
  379. package/dist/chunk-UTOHMK52.js +0 -8
  380. package/dist/chunk-ZY5AVC4P.js.map +0 -1
  381. package/dist/cli/api/uptrade.d.ts.map +0 -1
@@ -4,11 +4,11 @@ import { parse } from '../chunk-5YA6SI4Z.mjs';
4
4
  import { buildOgHtml, TITLE_MAX_PX, OG_REPORT_ATTR } from '../chunk-UJ6CHZAI.mjs';
5
5
  import { require_main } from '../chunk-NNZDWY3L.mjs';
6
6
  import { findAppDirForDiscovery, discoverNextJsRoutes } from '../chunk-XIJ4F6IE.mjs';
7
- import { SITE_KIT_VERSION } from '../chunk-7U7C6XRI.mjs';
7
+ import { SITE_KIT_VERSION } from '../chunk-DQUBETXH.mjs';
8
8
  import { __commonJS, __require, __toESM, __export, __privateAdd, __publicField, __privateGet, __privateMethod, __privateSet, __privateWrapper } from '../chunk-BEXTDHO4.mjs';
9
9
  import { EventEmitter } from 'events';
10
10
  import childProcess, { execFile as execFile$1, execSync, spawnSync, spawn } from 'child_process';
11
- import path10, { win32, posix } from 'path';
11
+ import path12, { win32, posix } from 'path';
12
12
  import * as fs from 'fs';
13
13
  import fs__default, { realpathSync, existsSync, readFileSync, readdirSync, statSync, readlinkSync, readdir as readdir$1, lstatSync, rmSync, mkdtempSync, writeFileSync } from 'fs';
14
14
  import process2 from 'process';
@@ -6202,10 +6202,10 @@ var require_lib2 = __commonJS({
6202
6202
  exports.analyse = analyse;
6203
6203
  var detectFile = (filepath, opts = {}) => new Promise((resolve, reject) => {
6204
6204
  let fd;
6205
- const fs27 = (0, node_1.default)();
6205
+ const fs29 = (0, node_1.default)();
6206
6206
  const handler = (err, buffer) => {
6207
6207
  if (fd) {
6208
- fs27.closeSync(fd);
6208
+ fs29.closeSync(fd);
6209
6209
  }
6210
6210
  if (err) {
6211
6211
  reject(err);
@@ -6217,9 +6217,9 @@ var require_lib2 = __commonJS({
6217
6217
  };
6218
6218
  const sampleSize = (opts === null || opts === void 0 ? void 0 : opts.sampleSize) || 0;
6219
6219
  if (sampleSize > 0) {
6220
- fd = fs27.openSync(filepath, "r");
6220
+ fd = fs29.openSync(filepath, "r");
6221
6221
  let sample = Buffer.allocUnsafe(sampleSize);
6222
- fs27.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
6222
+ fs29.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
6223
6223
  if (err) {
6224
6224
  handler(err, null);
6225
6225
  } else {
@@ -6231,22 +6231,22 @@ var require_lib2 = __commonJS({
6231
6231
  });
6232
6232
  return;
6233
6233
  }
6234
- fs27.readFile(filepath, handler);
6234
+ fs29.readFile(filepath, handler);
6235
6235
  });
6236
6236
  exports.detectFile = detectFile;
6237
6237
  var detectFileSync = (filepath, opts = {}) => {
6238
- const fs27 = (0, node_1.default)();
6238
+ const fs29 = (0, node_1.default)();
6239
6239
  if (opts && opts.sampleSize) {
6240
- const fd = fs27.openSync(filepath, "r");
6240
+ const fd = fs29.openSync(filepath, "r");
6241
6241
  let sample = Buffer.allocUnsafe(opts.sampleSize);
6242
- const bytesRead = fs27.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
6242
+ const bytesRead = fs29.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
6243
6243
  if (bytesRead < opts.sampleSize) {
6244
6244
  sample = sample.subarray(0, bytesRead);
6245
6245
  }
6246
- fs27.closeSync(fd);
6246
+ fs29.closeSync(fd);
6247
6247
  return (0, exports.detect)(sample);
6248
6248
  }
6249
- return (0, exports.detect)(fs27.readFileSync(filepath));
6249
+ return (0, exports.detect)(fs29.readFileSync(filepath));
6250
6250
  };
6251
6251
  exports.detectFileSync = detectFileSync;
6252
6252
  exports.default = {
@@ -10135,7 +10135,7 @@ var require_run_async = __commonJS({
10135
10135
  });
10136
10136
 
10137
10137
  // src/cli/index.ts
10138
- var import_dotenv = __toESM(require_main());
10138
+ var import_dotenv2 = __toESM(require_main());
10139
10139
 
10140
10140
  // node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
10141
10141
  var CommanderError = class extends Error {
@@ -12264,9 +12264,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
12264
12264
  args = args.slice();
12265
12265
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
12266
12266
  function findFile(baseDir, baseName) {
12267
- const localBin = path10.resolve(baseDir, baseName);
12267
+ const localBin = path12.resolve(baseDir, baseName);
12268
12268
  if (fs__default.existsSync(localBin)) return localBin;
12269
- if (sourceExt.includes(path10.extname(baseName))) return void 0;
12269
+ if (sourceExt.includes(path12.extname(baseName))) return void 0;
12270
12270
  const foundExt = sourceExt.find(
12271
12271
  (ext2) => fs__default.existsSync(`${localBin}${ext2}`)
12272
12272
  );
@@ -12284,17 +12284,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
12284
12284
  } catch {
12285
12285
  resolvedScriptPath = this._scriptPath;
12286
12286
  }
12287
- executableDir = path10.resolve(
12288
- path10.dirname(resolvedScriptPath),
12287
+ executableDir = path12.resolve(
12288
+ path12.dirname(resolvedScriptPath),
12289
12289
  executableDir
12290
12290
  );
12291
12291
  }
12292
12292
  if (executableDir) {
12293
12293
  let localFile = findFile(executableDir, executableFile);
12294
12294
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
12295
- const legacyName = path10.basename(
12295
+ const legacyName = path12.basename(
12296
12296
  this._scriptPath,
12297
- path10.extname(this._scriptPath)
12297
+ path12.extname(this._scriptPath)
12298
12298
  );
12299
12299
  if (legacyName !== this._name) {
12300
12300
  localFile = findFile(
@@ -12305,7 +12305,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
12305
12305
  }
12306
12306
  executableFile = localFile || executableFile;
12307
12307
  }
12308
- const launchWithNode = sourceExt.includes(path10.extname(executableFile));
12308
+ const launchWithNode = sourceExt.includes(path12.extname(executableFile));
12309
12309
  let proc;
12310
12310
  if (process2.platform !== "win32") {
12311
12311
  if (launchWithNode) {
@@ -13222,7 +13222,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
13222
13222
  * @return {Command}
13223
13223
  */
13224
13224
  nameFromFilename(filename) {
13225
- this._name = path10.basename(filename, path10.extname(filename));
13225
+ this._name = path12.basename(filename, path12.extname(filename));
13226
13226
  return this;
13227
13227
  }
13228
13228
  /**
@@ -13236,9 +13236,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
13236
13236
  * @param {string} [path]
13237
13237
  * @return {(string|null|Command)}
13238
13238
  */
13239
- executableDir(path27) {
13240
- if (path27 === void 0) return this._executableDir;
13241
- this._executableDir = path27;
13239
+ executableDir(path29) {
13240
+ if (path29 === void 0) return this._executableDir;
13241
+ this._executableDir = path29;
13242
13242
  return this;
13243
13243
  }
13244
13244
  /**
@@ -18747,7 +18747,7 @@ function createPrompt(view) {
18747
18747
  if (nextView === void 0) {
18748
18748
  let callerFilename = callSites[1]?.getFileName();
18749
18749
  if (callerFilename && !callerFilename.startsWith("file://")) {
18750
- callerFilename = path10.resolve(callerFilename);
18750
+ callerFilename = path12.resolve(callerFilename);
18751
18751
  }
18752
18752
  throw new Error(`Prompt functions must return a string.
18753
18753
  at ${callerFilename}`);
@@ -19136,13 +19136,13 @@ var ExternalEditor = class {
19136
19136
  }
19137
19137
  createTempFile() {
19138
19138
  try {
19139
- const baseDir = path10.resolve(this.fileOptions.dir ?? os.tmpdir());
19140
- this.tempDir = mkdtempSync(path10.join(baseDir, "inquirer-editor-"));
19139
+ const baseDir = path12.resolve(this.fileOptions.dir ?? os.tmpdir());
19140
+ this.tempDir = mkdtempSync(path12.join(baseDir, "inquirer-editor-"));
19141
19141
  const id = randomUUID();
19142
19142
  const prefix = sanitizeAffix(this.fileOptions.prefix);
19143
19143
  const postfix = sanitizeAffix(this.fileOptions.postfix);
19144
19144
  const filename = `${prefix}${id}${postfix}`;
19145
- this.tempFile = path10.join(this.tempDir, filename);
19145
+ this.tempFile = path12.join(this.tempDir, filename);
19146
19146
  const opt = { encoding: "utf8", flag: "wx" };
19147
19147
  if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
19148
19148
  opt.mode = this.fileOptions.mode;
@@ -20345,9 +20345,9 @@ function observableToAsyncIterable(source) {
20345
20345
 
20346
20346
  // node_modules/.pnpm/inquirer@14.0.2_@types+node@26.2.0/node_modules/inquirer/dist/ui/prompt.js
20347
20347
  var _ = {
20348
- set: (obj, path27 = "", value) => {
20348
+ set: (obj, path29 = "", value) => {
20349
20349
  let pointer = obj;
20350
- path27.split(".").forEach((key, index, arr) => {
20350
+ path29.split(".").forEach((key, index, arr) => {
20351
20351
  if (key === "__proto__" || key === "constructor")
20352
20352
  return;
20353
20353
  if (index === arr.length - 1) {
@@ -20358,8 +20358,8 @@ var _ = {
20358
20358
  pointer = pointer[key];
20359
20359
  });
20360
20360
  },
20361
- get: (obj, path27 = "", defaultValue) => {
20362
- const travel = (regexp) => String.prototype.split.call(path27, regexp).filter(Boolean).reduce(
20361
+ get: (obj, path29 = "", defaultValue) => {
20362
+ const travel = (regexp) => String.prototype.split.call(path29, regexp).filter(Boolean).reduce(
20363
20363
  // @ts-expect-error implicit any on res[key]
20364
20364
  (res, key) => res == null ? res : res[key],
20365
20365
  obj
@@ -20649,7 +20649,7 @@ async function scanCodebase(rootDir) {
20649
20649
  for (const file of files) {
20650
20650
  try {
20651
20651
  const content = await fs3.readFile(file, "utf-8");
20652
- const relPath = path10.relative(rootDir, file);
20652
+ const relPath = path12.relative(rootDir, file);
20653
20653
  const ast = parse(content, {
20654
20654
  sourceType: "module",
20655
20655
  plugins: ["jsx", "typescript"]
@@ -20698,7 +20698,7 @@ async function scanCodebase(rootDir) {
20698
20698
  async function findSourceFiles(dir, files = []) {
20699
20699
  const entries = await fs3.readdir(dir, { withFileTypes: true });
20700
20700
  for (const entry of entries) {
20701
- const fullPath = path10.join(dir, entry.name);
20701
+ const fullPath = path12.join(dir, entry.name);
20702
20702
  if (entry.isDirectory()) {
20703
20703
  if (["node_modules", ".next", ".git", "dist", "build"].includes(entry.name)) {
20704
20704
  continue;
@@ -20716,18 +20716,18 @@ function scanForForms(ast, content, filePath) {
20716
20716
  const forms = [];
20717
20717
  content.split("\n");
20718
20718
  traverse(ast, {
20719
- JSXElement(path27) {
20720
- const opening = path27.node.openingElement;
20719
+ JSXElement(path29) {
20720
+ const opening = path29.node.openingElement;
20721
20721
  if (isJSXIdentifier(opening.name) && opening.name.name === "form") {
20722
- const fields = extractFieldsFromForm(path27);
20722
+ const fields = extractFieldsFromForm(path29);
20723
20723
  const hasOnSubmit = opening.attributes.some(
20724
20724
  (attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "onSubmit"
20725
20725
  );
20726
20726
  if (hasOnSubmit && fields.length > 0) {
20727
- const startLine = path27.node.loc?.start.line || 0;
20728
- const endLine = path27.node.loc?.end.line || 0;
20727
+ const startLine = path29.node.loc?.start.line || 0;
20728
+ const endLine = path29.node.loc?.end.line || 0;
20729
20729
  let componentName = "UnknownForm";
20730
- let current = path27.parentPath;
20730
+ let current = path29.parentPath;
20731
20731
  while (current) {
20732
20732
  if (isFunctionDeclaration(current.node) && current.node.id) {
20733
20733
  componentName = current.node.id.name;
@@ -20760,7 +20760,7 @@ function scanForForms(ast, content, filePath) {
20760
20760
  }
20761
20761
  if (isJSXIdentifier(opening.name) && opening.name.name === "Form") {
20762
20762
  if (content.includes("Formik") || content.includes("formik")) {
20763
- const fields = extractFieldsFromFormik(path27);
20763
+ const fields = extractFieldsFromFormik(path29);
20764
20764
  if (fields.length > 0) {
20765
20765
  forms.push({
20766
20766
  filePath,
@@ -20771,8 +20771,8 @@ function scanForForms(ast, content, filePath) {
20771
20771
  submitsTo: null,
20772
20772
  complexity: "moderate",
20773
20773
  suggestedAction: "assisted",
20774
- startLine: path27.node.loc?.start.line || 0,
20775
- endLine: path27.node.loc?.end.line || 0
20774
+ startLine: path29.node.loc?.start.line || 0,
20775
+ endLine: path29.node.loc?.end.line || 0
20776
20776
  });
20777
20777
  }
20778
20778
  }
@@ -20790,8 +20790,8 @@ function extractFieldsFromForm(formPath) {
20790
20790
  const radioGroups = /* @__PURE__ */ new Map();
20791
20791
  const checkboxGroups = /* @__PURE__ */ new Map();
20792
20792
  formPath.traverse({
20793
- JSXElement(path27) {
20794
- const opening = path27.node.openingElement;
20793
+ JSXElement(path29) {
20794
+ const opening = path29.node.openingElement;
20795
20795
  const tagName = isJSXIdentifier(opening.name) ? opening.name.name : null;
20796
20796
  if (["input", "textarea", "select"].includes(tagName || "")) {
20797
20797
  const attrs = opening.attributes;
@@ -20838,7 +20838,7 @@ function extractFieldsFromForm(formPath) {
20838
20838
  }
20839
20839
  if (tagName === "select") {
20840
20840
  const selectOptions = [];
20841
- path27.traverse({
20841
+ path29.traverse({
20842
20842
  JSXElement(optionPath) {
20843
20843
  const optOpening = optionPath.node.openingElement;
20844
20844
  const optTagName = isJSXIdentifier(optOpening.name) ? optOpening.name.name : null;
@@ -20913,8 +20913,8 @@ function extractFieldsFromForm(formPath) {
20913
20913
  function extractFieldsFromFormik(formPath, content) {
20914
20914
  const fields = [];
20915
20915
  formPath.traverse({
20916
- JSXElement(path27) {
20917
- const opening = path27.node.openingElement;
20916
+ JSXElement(path29) {
20917
+ const opening = path29.node.openingElement;
20918
20918
  const tagName = isJSXIdentifier(opening.name) ? opening.name.name : null;
20919
20919
  if (tagName === "Field" || tagName === "FastField") {
20920
20920
  const attrs = opening.attributes;
@@ -21033,11 +21033,11 @@ function scanForMetadata(ast, content, filePath) {
21033
21033
  }
21034
21034
  let hasHeadComponent = false;
21035
21035
  traverse(ast, {
21036
- JSXElement(path27) {
21037
- const opening = path27.node.openingElement;
21036
+ JSXElement(path29) {
21037
+ const opening = path29.node.openingElement;
21038
21038
  if (isJSXIdentifier(opening.name) && opening.name.name === "Head") {
21039
21039
  hasHeadComponent = true;
21040
- path27.stop();
21040
+ path29.stop();
21041
21041
  }
21042
21042
  }
21043
21043
  });
@@ -21072,8 +21072,8 @@ function scanForWidgets(ast, content, filePath) {
21072
21072
  for (const { pattern, type } of widgetPatterns) {
21073
21073
  if (pattern.test(content)) {
21074
21074
  traverse(ast, {
21075
- JSXElement(path27) {
21076
- const opening = path27.node.openingElement;
21075
+ JSXElement(path29) {
21076
+ const opening = path29.node.openingElement;
21077
21077
  if (isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
21078
21078
  const srcAttr = opening.attributes.find(
21079
21079
  (attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "src"
@@ -21088,8 +21088,8 @@ function scanForWidgets(ast, content, filePath) {
21088
21088
  filePath,
21089
21089
  widgetType: type,
21090
21090
  scriptTag: src,
21091
- startLine: path27.node.loc?.start.line || 0,
21092
- endLine: path27.node.loc?.end.line || 0
21091
+ startLine: path29.node.loc?.start.line || 0,
21092
+ endLine: path29.node.loc?.end.line || 0
21093
21093
  });
21094
21094
  }
21095
21095
  }
@@ -21163,7 +21163,7 @@ async function scanForSitemapFiles(rootDir) {
21163
21163
  "next-sitemap.config.ts"
21164
21164
  ];
21165
21165
  for (const configPath of configPaths) {
21166
- const fullPath = path10.join(rootDir, configPath);
21166
+ const fullPath = path12.join(rootDir, configPath);
21167
21167
  try {
21168
21168
  await fs3.access(fullPath);
21169
21169
  const content = await fs3.readFile(fullPath, "utf-8");
@@ -21181,7 +21181,7 @@ async function scanForSitemapFiles(rootDir) {
21181
21181
  } catch {
21182
21182
  }
21183
21183
  }
21184
- const staticSitemapPath = path10.join(rootDir, "public", "sitemap.xml");
21184
+ const staticSitemapPath = path12.join(rootDir, "public", "sitemap.xml");
21185
21185
  try {
21186
21186
  await fs3.access(staticSitemapPath);
21187
21187
  const content = await fs3.readFile(staticSitemapPath, "utf-8");
@@ -21204,7 +21204,7 @@ async function scanForSitemapFiles(rootDir) {
21204
21204
  "out/sitemap.xml"
21205
21205
  ];
21206
21206
  for (const genPath of generatedPaths) {
21207
- const fullPath = path10.join(rootDir, genPath);
21207
+ const fullPath = path12.join(rootDir, genPath);
21208
21208
  try {
21209
21209
  await fs3.access(fullPath);
21210
21210
  } catch {
@@ -21228,8 +21228,8 @@ function scanForSchemas(ast, content, filePath) {
21228
21228
  return schemas;
21229
21229
  }
21230
21230
  traverse(ast, {
21231
- JSXElement(path27) {
21232
- const opening = path27.node.openingElement;
21231
+ JSXElement(path29) {
21232
+ const opening = path29.node.openingElement;
21233
21233
  if (isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
21234
21234
  const typeAttr = opening.attributes.find(
21235
21235
  (attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "type"
@@ -21256,8 +21256,8 @@ function scanForSchemas(ast, content, filePath) {
21256
21256
  filePath,
21257
21257
  type: detectedType,
21258
21258
  schemaType,
21259
- startLine: path27.node.loc?.start.line || 0,
21260
- endLine: path27.node.loc?.end.line || 0
21259
+ startLine: path29.node.loc?.start.line || 0,
21260
+ endLine: path29.node.loc?.end.line || 0
21261
21261
  });
21262
21262
  }
21263
21263
  }
@@ -21290,8 +21290,8 @@ function scanForFAQs(ast, content, filePath) {
21290
21290
  /questions?\s*(?:and|&)?\s*answers?/i
21291
21291
  ];
21292
21292
  traverse(ast, {
21293
- JSXElement(path27) {
21294
- const opening = path27.node.openingElement;
21293
+ JSXElement(path29) {
21294
+ const opening = path29.node.openingElement;
21295
21295
  let tagName = "";
21296
21296
  if (isJSXIdentifier(opening.name)) {
21297
21297
  tagName = opening.name.name;
@@ -21304,8 +21304,8 @@ function scanForFAQs(ast, content, filePath) {
21304
21304
  faqs.push({
21305
21305
  filePath,
21306
21306
  type: "details-summary",
21307
- startLine: path27.node.loc?.start.line || 0,
21308
- endLine: path27.node.loc?.end.line || 0,
21307
+ startLine: path29.node.loc?.start.line || 0,
21308
+ endLine: path29.node.loc?.end.line || 0,
21309
21309
  hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
21310
21310
  });
21311
21311
  return;
@@ -21313,7 +21313,7 @@ function scanForFAQs(ast, content, filePath) {
21313
21313
  for (const pattern of faqPatterns) {
21314
21314
  if (pattern.test(tagName)) {
21315
21315
  let itemCount = 0;
21316
- path27.traverse({
21316
+ path29.traverse({
21317
21317
  JSXElement(itemPath) {
21318
21318
  const itemOpening = itemPath.node.openingElement;
21319
21319
  if (isJSXIdentifier(itemOpening.name)) {
@@ -21329,8 +21329,8 @@ function scanForFAQs(ast, content, filePath) {
21329
21329
  type: "accordion",
21330
21330
  componentName: tagName,
21331
21331
  itemCount: itemCount || void 0,
21332
- startLine: path27.node.loc?.start.line || 0,
21333
- endLine: path27.node.loc?.end.line || 0,
21332
+ startLine: path29.node.loc?.start.line || 0,
21333
+ endLine: path29.node.loc?.end.line || 0,
21334
21334
  hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
21335
21335
  });
21336
21336
  return;
@@ -21453,8 +21453,8 @@ function scanForImages(ast, content, filePath) {
21453
21453
  return images;
21454
21454
  }
21455
21455
  traverse(ast, {
21456
- JSXElement(path27) {
21457
- const opening = path27.node.openingElement;
21456
+ JSXElement(path29) {
21457
+ const opening = path29.node.openingElement;
21458
21458
  if (!isJSXIdentifier(opening.name)) return;
21459
21459
  const tagName = opening.name.name;
21460
21460
  if (tagName === "img" || tagName === "Image") {
@@ -21482,8 +21482,8 @@ function scanForImages(ast, content, filePath) {
21482
21482
  src: src || void 0,
21483
21483
  alt: alt || void 0,
21484
21484
  isLocal,
21485
- startLine: path27.node.loc?.start.line || 0,
21486
- endLine: path27.node.loc?.end.line || 0
21485
+ startLine: path29.node.loc?.start.line || 0,
21486
+ endLine: path29.node.loc?.end.line || 0
21487
21487
  });
21488
21488
  }
21489
21489
  }
@@ -21548,15 +21548,11 @@ function addToExistingImport(content, namedExport, modulePath) {
21548
21548
  }
21549
21549
  return content;
21550
21550
  }
21551
- function insertManagedSchemaIntoJSX(content, pagePath, isTypeScript) {
21551
+ function insertManagedSchemaIntoJSX(content, pagePath) {
21552
21552
  if (content.includes("<ManagedSchema")) {
21553
21553
  return content;
21554
21554
  }
21555
- const projectIdSuffix = isTypeScript ? "!" : "";
21556
- const schemaComponent = `<ManagedSchema
21557
- projectId={process.env.SONOR_PROJECT_ID${projectIdSuffix}}
21558
- path="${pagePath}"
21559
- />`;
21555
+ const schemaComponent = `<ManagedSchema path="${pagePath}" />`;
21560
21556
  const returnPatterns = [
21561
21557
  // return (<> ... - fragment
21562
21558
  /return\s*\(\s*<>/,
@@ -21692,7 +21688,7 @@ async function migrateFiles(scanResults, options) {
21692
21688
  }
21693
21689
  async function migrateForm(form, options) {
21694
21690
  const changes = [];
21695
- const fullPath = path10.resolve(process.cwd(), form.filePath);
21691
+ const fullPath = path12.resolve(process.cwd(), form.filePath);
21696
21692
  const formSlug = generateSlug(form.componentName);
21697
21693
  let formId;
21698
21694
  if (!options.dryRun) {
@@ -21831,7 +21827,7 @@ export default ${componentName}
21831
21827
  `;
21832
21828
  }
21833
21829
  async function createFormInUptrade(form, slug, options) {
21834
- const response = await fetch("https://api.sonor.io/forms", {
21830
+ const response = await fetch(`${options.apiUrl || "https://api.sonor.io"}/forms`, {
21835
21831
  method: "POST",
21836
21832
  headers: {
21837
21833
  "Content-Type": "application/json",
@@ -21866,10 +21862,10 @@ async function migrateWidget(filePath, widget, options) {
21866
21862
  const changes = [];
21867
21863
  if (options.dryRun) {
21868
21864
  changes.push(`[DRY RUN] Would remove ${widget.widgetType} script`);
21869
- changes.push("[DRY RUN] Would enable Engage in SiteKitProvider");
21865
+ changes.push("[DRY RUN] Sonor Engage chat would come from SiteKitLayout (engage is on by default)");
21870
21866
  return { filePath, success: true, changes };
21871
21867
  }
21872
- const fullPath = path10.resolve(process.cwd(), filePath);
21868
+ const fullPath = path12.resolve(process.cwd(), filePath);
21873
21869
  let content = await fs3.readFile(fullPath, "utf-8");
21874
21870
  switch (widget.widgetType) {
21875
21871
  case "intercom":
@@ -21885,7 +21881,7 @@ async function migrateWidget(filePath, widget, options) {
21885
21881
  }
21886
21882
  await fs3.writeFile(fullPath, content, "utf-8");
21887
21883
  changes.push(`Removed ${widget.widgetType} script`);
21888
- changes.push("Enable Engage in SiteKitProvider to add chat widget");
21884
+ changes.push("SiteKitLayout adds the Sonor Engage chat widget (engage is on by default)");
21889
21885
  return { filePath, success: true, changes };
21890
21886
  }
21891
21887
  function matchBalancedBraces(content, startIndex) {
@@ -21906,15 +21902,15 @@ function matchBalancedBraces(content, startIndex) {
21906
21902
  }
21907
21903
  async function migrateMetadata(filePath, metadata, options) {
21908
21904
  const changes = [];
21909
- const fullPath = path10.resolve(process.cwd(), filePath);
21905
+ const fullPath = path12.resolve(process.cwd(), filePath);
21910
21906
  let pagePath = filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\/layout\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
21911
21907
  if (pagePath === "") pagePath = "/";
21912
21908
  let content = await fs3.readFile(fullPath, "utf-8");
21913
21909
  const isTypeScript = filePath.endsWith(".tsx") || filePath.endsWith(".ts");
21914
21910
  const ext2 = isTypeScript ? ".tsx" : ".jsx";
21915
21911
  if (isClientComponent(content)) {
21916
- const dir = path10.dirname(fullPath);
21917
- const layoutPath = path10.join(dir, `layout${ext2}`);
21912
+ const dir = path12.dirname(fullPath);
21913
+ const layoutPath = path12.join(dir, `layout${ext2}`);
21918
21914
  try {
21919
21915
  await fs3.access(layoutPath);
21920
21916
  const layoutContent = await fs3.readFile(layoutPath, "utf-8");
@@ -21937,13 +21933,12 @@ async function migrateMetadata(filePath, metadata, options) {
21937
21933
  } catch (error2) {
21938
21934
  changes.push(`Page metadata may already exist: ${pagePath}`);
21939
21935
  }
21940
- const dirName = path10.basename(dir).replace(/^\[\.\.\.([^\]]+)\]$/, "$1").replace(/^\[([^\]]+)\]$/, "$1");
21936
+ const dirName = path12.basename(dir).replace(/^\[\.\.\.([^\]]+)\]$/, "$1").replace(/^\[([^\]]+)\]$/, "$1");
21941
21937
  const layoutName = dirName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("") + "Layout";
21942
21938
  const layoutCode = `import { getManagedMetadata, ManagedSchema } from '@sonordev/site-kit/seo'
21943
21939
 
21944
21940
  export async function generateMetadata() {
21945
21941
  return getManagedMetadata({
21946
- projectId: process.env.SONOR_PROJECT_ID${isTypeScript ? "!" : ""},
21947
21942
  path: '${pagePath}',
21948
21943
  fallback: {
21949
21944
  title: '${(metadata.title || "Page Title").replace(/'/g, "\\'")}',
@@ -21955,10 +21950,7 @@ export async function generateMetadata() {
21955
21950
  export default function ${layoutName}({ children }${isTypeScript ? ": { children: React.ReactNode }" : ""}) {
21956
21951
  return (
21957
21952
  <>
21958
- <ManagedSchema
21959
- projectId={process.env.SONOR_PROJECT_ID${isTypeScript ? "!" : ""}}
21960
- path="${pagePath}"
21961
- />
21953
+ <ManagedSchema path="${pagePath}" />
21962
21954
  {children}
21963
21955
  </>
21964
21956
  )
@@ -21988,7 +21980,6 @@ export default function ${layoutName}({ children }${isTypeScript ? ": { children
21988
21980
  const generateMetadataCode = `
21989
21981
  export async function generateMetadata() {
21990
21982
  return getManagedMetadata({
21991
- projectId: process.env.SONOR_PROJECT_ID${isTypeScript ? "!" : ""},
21992
21983
  path: '${pagePath}',
21993
21984
  fallback: {
21994
21985
  title: '${(metadata.title || "Page Title").replace(/'/g, "\\'")}',
@@ -22010,7 +22001,7 @@ export async function generateMetadata() {
22010
22001
  content = generateMetadataCode + content;
22011
22002
  }
22012
22003
  }
22013
- content = insertManagedSchemaIntoJSX(content, pagePath, isTypeScript);
22004
+ content = insertManagedSchemaIntoJSX(content, pagePath);
22014
22005
  changes.push("Added ManagedSchema component");
22015
22006
  await fs3.writeFile(fullPath, content, "utf-8");
22016
22007
  changes.push("Added generateMetadata function");
@@ -22030,7 +22021,6 @@ export async function generateMetadata() {
22030
22021
  }
22031
22022
  const generateMetadataCode = `export async function generateMetadata() {
22032
22023
  return getManagedMetadata({
22033
- projectId: process.env.SONOR_PROJECT_ID${isTypeScript ? "!" : ""},
22034
22024
  path: '${pagePath}',
22035
22025
  fallback: {
22036
22026
  title: '${(metadata.title || "Page Title").replace(/'/g, "\\'")}',
@@ -22040,7 +22030,7 @@ export async function generateMetadata() {
22040
22030
  }`;
22041
22031
  content = content.replace(fullMatch, generateMetadataCode);
22042
22032
  changes.push("Replaced static metadata with getManagedMetadata");
22043
- content = insertManagedSchemaIntoJSX(content, pagePath, isTypeScript);
22033
+ content = insertManagedSchemaIntoJSX(content, pagePath);
22044
22034
  changes.push("Added ManagedSchema component");
22045
22035
  }
22046
22036
  }
@@ -22052,7 +22042,7 @@ export async function generateMetadata() {
22052
22042
  return { filePath, success: true, changes };
22053
22043
  }
22054
22044
  async function createPageMetadata(pagePath, metadata, options) {
22055
- const response = await fetch("https://api.sonor.io/seo/pages", {
22045
+ const response = await fetch(`${options.apiUrl || "https://api.sonor.io"}/seo/pages`, {
22056
22046
  method: "POST",
22057
22047
  headers: {
22058
22048
  "Content-Type": "application/json",
@@ -22137,7 +22127,7 @@ async function createSchemaRecord(pagePath, schemaType, schemaJson, options) {
22137
22127
  }
22138
22128
  async function migrateSchema(filePath, schema, options) {
22139
22129
  const changes = [];
22140
- const fullPath = path10.resolve(process.cwd(), filePath);
22130
+ const fullPath = path12.resolve(process.cwd(), filePath);
22141
22131
  let pagePath = filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
22142
22132
  if (pagePath === "") pagePath = "/";
22143
22133
  let content = await fs3.readFile(fullPath, "utf-8");
@@ -22164,8 +22154,6 @@ async function migrateSchema(filePath, schema, options) {
22164
22154
  }
22165
22155
  }
22166
22156
  const alreadyHasManagedSchema = content.includes("<ManagedSchema");
22167
- const isTypeScript = filePath.endsWith(".tsx") || filePath.endsWith(".ts");
22168
- const projectIdSuffix = isTypeScript ? "!" : "";
22169
22157
  const jsonLdPattern = /<script\s+type=["']application\/ld\+json["'][^>]*>[\s\S]*?<\/script>/gi;
22170
22158
  const scriptPattern = /<Script\s+[^>]*type=["']application\/ld\+json["'][^>]*>[\s\S]*?<\/Script>/gi;
22171
22159
  const hasJsonLd = jsonLdPattern.test(content) || scriptPattern.test(content);
@@ -22185,14 +22173,8 @@ async function migrateSchema(filePath, schema, options) {
22185
22173
  }
22186
22174
  changes.push("Added ManagedSchema import");
22187
22175
  }
22188
- content = content.replace(jsonLdPattern, `<ManagedSchema
22189
- projectId={process.env.SONOR_PROJECT_ID${projectIdSuffix}}
22190
- path="${pagePath}"
22191
- />`);
22192
- content = content.replace(scriptPattern, `<ManagedSchema
22193
- projectId={process.env.SONOR_PROJECT_ID${projectIdSuffix}}
22194
- path="${pagePath}"
22195
- />`);
22176
+ content = content.replace(jsonLdPattern, `<ManagedSchema path="${pagePath}" />`);
22177
+ content = content.replace(scriptPattern, `<ManagedSchema path="${pagePath}" />`);
22196
22178
  changes.push("Replaced JSON-LD script with ManagedSchema component");
22197
22179
  }
22198
22180
  }
@@ -22256,7 +22238,7 @@ async function createFAQRecord(pagePath, items, options) {
22256
22238
  }
22257
22239
  async function migrateFAQ(filePath, faq, options) {
22258
22240
  const changes = [];
22259
- const fullPath = path10.resolve(process.cwd(), filePath);
22241
+ const fullPath = path12.resolve(process.cwd(), filePath);
22260
22242
  let pagePath = filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
22261
22243
  if (pagePath === "") pagePath = "/";
22262
22244
  let content = await fs3.readFile(fullPath, "utf-8");
@@ -22296,12 +22278,7 @@ async function migrateFAQ(filePath, faq, options) {
22296
22278
  }
22297
22279
  changes.push("Added ManagedFAQ import");
22298
22280
  }
22299
- const isTypeScript = filePath.endsWith(".tsx") || filePath.endsWith(".ts");
22300
- const projectIdSuffix = isTypeScript ? "!" : "";
22301
- const managedFAQComponent = `<ManagedFAQ
22302
- projectId={process.env.SONOR_PROJECT_ID${projectIdSuffix}}
22303
- path="${pagePath}"
22304
- />`;
22281
+ const managedFAQComponent = `<ManagedFAQ path="${pagePath}" />`;
22305
22282
  if (faq.componentName) {
22306
22283
  const componentPattern = new RegExp(`(<${faq.componentName}[^>]*>)`, "i");
22307
22284
  if (componentPattern.test(content)) {
@@ -22329,7 +22306,7 @@ async function migrateFAQ(filePath, faq, options) {
22329
22306
  }
22330
22307
  async function migrateSitemap(filePath, sitemap, options) {
22331
22308
  const changes = [];
22332
- const fullPath = path10.resolve(process.cwd(), filePath);
22309
+ const fullPath = path12.resolve(process.cwd(), filePath);
22333
22310
  if (options.dryRun) {
22334
22311
  changes.push(`[DRY RUN] Would migrate ${sitemap.type} to Site-Kit sitemap`);
22335
22312
  if (sitemap.type === "next-sitemap-config") {
@@ -22354,7 +22331,7 @@ async function migrateSitemap(filePath, sitemap, options) {
22354
22331
  }
22355
22332
  if (sitemap.type === "custom-sitemap" && filePath.includes("sitemap")) {
22356
22333
  changes.push("Custom sitemap detected - consider using Site-Kit's createSitemap helper");
22357
- changes.push("Import: import { createSitemap } from '@sonordev/site-kit/seo'");
22334
+ changes.push("Import: import { createSitemap } from '@sonordev/site-kit/sitemap'");
22358
22335
  }
22359
22336
  return { filePath, success: true, changes };
22360
22337
  }
@@ -22362,17 +22339,17 @@ async function migrateAnalytics(filePath, analytics, options) {
22362
22339
  const changes = [];
22363
22340
  if (options.dryRun) {
22364
22341
  changes.push(`[DRY RUN] Detected ${analytics.type}${analytics.trackingId ? ` (${analytics.trackingId})` : ""}`);
22365
- changes.push("[DRY RUN] Would recommend moving to SiteKitProvider analytics");
22342
+ changes.push("[DRY RUN] Would recommend Sonor analytics from SiteKitLayout (on by default)");
22366
22343
  return { filePath, success: true, changes };
22367
22344
  }
22368
22345
  changes.push(`Detected ${analytics.type}${analytics.trackingId ? ` (${analytics.trackingId})` : ""}`);
22369
- changes.push("SiteKitProvider supports analytics integration");
22346
+ changes.push("SiteKitLayout already tracks Sonor analytics (on by default)");
22370
22347
  changes.push("Configure analytics in project settings to consolidate tracking");
22371
22348
  return { filePath, success: true, changes };
22372
22349
  }
22373
22350
  async function migrateFile(filePath, options) {
22374
- const fullPath = path10.resolve(filePath);
22375
- const relPath = path10.relative(process.cwd(), fullPath);
22351
+ const fullPath = path12.resolve(filePath);
22352
+ const relPath = path12.relative(process.cwd(), fullPath);
22376
22353
  const content = await fs3.readFile(fullPath, "utf-8");
22377
22354
  const hasFormTag = content.includes("<form") || content.includes("onSubmit");
22378
22355
  const hasWidget = /intercom|crisp|drift|hubspot|zendesk/i.test(content);
@@ -22389,26 +22366,26 @@ async function migrateFile(filePath, options) {
22389
22366
  return migrateWidget(relPath, {
22390
22367
  widgetType}, options);
22391
22368
  }
22392
- const { parse: parse2 } = await import('../lib-R7IQ4ZHE.mjs');
22393
- const ast = parse2(content, {
22369
+ const { parse: parse3 } = await import('../lib-R7IQ4ZHE.mjs');
22370
+ const ast = parse3(content, {
22394
22371
  sourceType: "module",
22395
22372
  plugins: ["jsx", "typescript"]
22396
22373
  });
22397
22374
  let componentName = "Form";
22398
22375
  const traverse2 = (await import('../lib-RSDMEKDQ.mjs')).default;
22399
22376
  traverse2(ast, {
22400
- ExportNamedDeclaration(path27) {
22401
- const decl = path27.node.declaration;
22377
+ ExportNamedDeclaration(path29) {
22378
+ const decl = path29.node.declaration;
22402
22379
  if (decl && decl.type === "FunctionDeclaration" && decl.id) {
22403
22380
  componentName = decl.id.name;
22404
- path27.stop();
22381
+ path29.stop();
22405
22382
  }
22406
22383
  },
22407
- ExportDefaultDeclaration(path27) {
22408
- const decl = path27.node.declaration;
22384
+ ExportDefaultDeclaration(path29) {
22385
+ const decl = path29.node.declaration;
22409
22386
  if (decl && decl.type === "FunctionDeclaration" && decl.id) {
22410
22387
  componentName = decl.id.name;
22411
- path27.stop();
22388
+ path29.stop();
22412
22389
  }
22413
22390
  }
22414
22391
  });
@@ -22465,7 +22442,7 @@ function detectFormType(form) {
22465
22442
  return "contact";
22466
22443
  }
22467
22444
  async function generateEnvFile(options) {
22468
- const envPath = path10.join(process.cwd(), ".env.local");
22445
+ const envPath = path12.join(process.cwd(), ".env.local");
22469
22446
  let existingContent = "";
22470
22447
  try {
22471
22448
  existingContent = await fs3.readFile(envPath, "utf-8");
@@ -22565,7 +22542,7 @@ async function findLayoutFile() {
22565
22542
  "app/layout.jsx"
22566
22543
  ];
22567
22544
  for (const relativePath of possiblePaths) {
22568
- const fullPath = path10.join(process.cwd(), relativePath);
22545
+ const fullPath = path12.join(process.cwd(), relativePath);
22569
22546
  try {
22570
22547
  await fs3.access(fullPath);
22571
22548
  return fullPath;
@@ -22735,15 +22712,15 @@ var wslDefaultBrowser = async () => {
22735
22712
  const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
22736
22713
  return stdout.trim();
22737
22714
  };
22738
- var convertWslPathToWindows = async (path27) => {
22739
- if (/^[a-z]+:\/\//i.test(path27)) {
22740
- return path27;
22715
+ var convertWslPathToWindows = async (path29) => {
22716
+ if (/^[a-z]+:\/\//i.test(path29)) {
22717
+ return path29;
22741
22718
  }
22742
22719
  try {
22743
- const { stdout } = await execFile2("wslpath", ["-aw", path27], { encoding: "utf8" });
22720
+ const { stdout } = await execFile2("wslpath", ["-aw", path29], { encoding: "utf8" });
22744
22721
  return stdout.trim();
22745
22722
  } catch {
22746
- return path27;
22723
+ return path29;
22747
22724
  }
22748
22725
  };
22749
22726
 
@@ -22863,8 +22840,8 @@ var is_in_ssh_default = isInSsh;
22863
22840
 
22864
22841
  // node_modules/.pnpm/open@11.0.0/node_modules/open/index.js
22865
22842
  var fallbackAttemptSymbol = /* @__PURE__ */ Symbol("fallbackAttempt");
22866
- var __dirname2 = import.meta.url ? path10.dirname(fileURLToPath(import.meta.url)) : "";
22867
- var localXdgOpenPath = path10.join(__dirname2, "xdg-open");
22843
+ var __dirname2 = import.meta.url ? path12.dirname(fileURLToPath(import.meta.url)) : "";
22844
+ var localXdgOpenPath = path12.join(__dirname2, "xdg-open");
22868
22845
  var { platform, arch } = process2;
22869
22846
  var tryEachApp = async (apps2, opener) => {
22870
22847
  if (apps2.length === 0) {
@@ -23142,8 +23119,37 @@ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
23142
23119
  darwin: "Safari"
23143
23120
  }));
23144
23121
  var open_default = open;
23122
+ var SONOR_STATE_DIR = ".sonor";
23123
+ var IMAGE_MANIFEST = ".sonor-images.json";
23124
+ var LEGACY_IMAGE_MANIFEST = ".uptrade-images.json";
23125
+ var LEGACY_STATE_DIR = ".uptrade";
23126
+ function resolveStateReadPath(relativePath, root = process.cwd()) {
23127
+ return preferCurrent(path12.join(root, SONOR_STATE_DIR, relativePath), path12.join(root, LEGACY_STATE_DIR, relativePath));
23128
+ }
23129
+ function resolveImageManifestReadPath(root) {
23130
+ return preferCurrent(path12.join(root, IMAGE_MANIFEST), path12.join(root, LEGACY_IMAGE_MANIFEST));
23131
+ }
23132
+ function preferCurrent(current, legacy) {
23133
+ return existsSync(current) || !existsSync(legacy) ? current : legacy;
23134
+ }
23135
+ async function listLocalTemplates(root = process.cwd()) {
23136
+ const names = /* @__PURE__ */ new Set();
23137
+ for (const dir of [SONOR_STATE_DIR, LEGACY_STATE_DIR]) {
23138
+ try {
23139
+ const files = await fs3.readdir(path12.join(root, dir, "templates"));
23140
+ for (const file of files) if (file.endsWith(".json")) names.add(file);
23141
+ } catch (error2) {
23142
+ if (error2.code !== "ENOENT") throw error2;
23143
+ }
23144
+ }
23145
+ return [...names].sort();
23146
+ }
23147
+
23148
+ // src/cli/api/sonor.ts
23145
23149
  var PORTAL_URL = "https://app.sonor.io";
23146
- var API_URL = process.env.SONOR_API_URL || "https://api.sonor.io";
23150
+ function getSonorApiUrl() {
23151
+ return (process.env.SONOR_API_URL || "https://api.sonor.io").replace(/\/+$/, "");
23152
+ }
23147
23153
  async function authenticateWithSonor() {
23148
23154
  return new Promise((resolve, reject) => {
23149
23155
  const server = http.createServer(async (req, res) => {
@@ -23170,7 +23176,7 @@ async function authenticateWithSonor() {
23170
23176
  server.close();
23171
23177
  return;
23172
23178
  }
23173
- const tokenResponse = await fetch(`${API_URL}/auth/cli-token`, {
23179
+ const tokenResponse = await fetch(`${getSonorApiUrl()}/auth/cli-token`, {
23174
23180
  method: "POST",
23175
23181
  headers: { "Content-Type": "application/json" },
23176
23182
  body: JSON.stringify({ code, redirect_uri: `http://localhost:${port}/callback` })
@@ -23216,32 +23222,41 @@ async function authenticateWithSonor() {
23216
23222
  }, 5 * 60 * 1e3);
23217
23223
  });
23218
23224
  }
23219
- async function authenticateWithApiKey(apiKey) {
23220
- const response = await fetch(`${API_URL}/api/public/seo/verify-api-key`, {
23221
- headers: { "X-API-Key": apiKey }
23222
- });
23223
- if (response.ok) {
23224
- const data = await response.json();
23225
- if (data.valid) {
23226
- return {
23227
- accessToken: apiKey,
23228
- userId: "api-key-user",
23229
- email: data.project?.name ? `Project: ${data.project.name}` : `API Key verified`,
23230
- projectId: data.project?.id,
23231
- projectName: data.project?.name,
23232
- orgId: data.organization?.id,
23233
- orgName: data.organization?.name,
23234
- isApiKey: true
23235
- };
23236
- }
23225
+ async function authenticateWithApiKey(apiKey, apiUrl = getSonorApiUrl()) {
23226
+ let response;
23227
+ try {
23228
+ response = await fetch(`${apiUrl}/api/public/seo/verify-api-key`, {
23229
+ headers: { "X-API-Key": apiKey },
23230
+ signal: AbortSignal.timeout(15e3)
23231
+ });
23232
+ } catch {
23233
+ throw new NetworkError("PROJECT_LOOKUP_FAILED", "Could not reach the Sonor API to resolve the project. Check SONOR_API_URL and your connection.");
23237
23234
  }
23238
- if (response.status === 401) {
23239
- throw new Error("Invalid API key");
23235
+ if (!response.ok) {
23236
+ throw new NetworkError("PROJECT_LOOKUP_FAILED", `Sonor API verification failed (HTTP ${response.status}). Check SONOR_API_KEY and SONOR_API_URL.`);
23237
+ }
23238
+ let data;
23239
+ try {
23240
+ data = await response.json();
23241
+ } catch {
23242
+ throw new NetworkError("INVALID_PROJECT_RESPONSE", "Sonor API returned an invalid project response.");
23243
+ }
23244
+ 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)) {
23245
+ throw new NetworkError("INVALID_PROJECT_RESPONSE", "Sonor API did not return a valid full project UUID. Check SONOR_API_KEY.");
23240
23246
  }
23241
- throw new Error(`API verification failed: ${response.status}`);
23247
+ return {
23248
+ accessToken: apiKey,
23249
+ userId: "api-key-user",
23250
+ email: data.project.name ? `Project: ${data.project.name}` : "API Key verified",
23251
+ projectId: data.project.id,
23252
+ projectName: data.project.name,
23253
+ orgId: data.organization?.id,
23254
+ orgName: data.organization?.name,
23255
+ isApiKey: true
23256
+ };
23242
23257
  }
23243
23258
  async function fetchOrganizations(accessToken) {
23244
- const response = await fetch(`${API_URL}/organizations`, {
23259
+ const response = await fetch(`${getSonorApiUrl()}/organizations`, {
23245
23260
  headers: { "Authorization": `Bearer ${accessToken}` }
23246
23261
  });
23247
23262
  if (!response.ok) {
@@ -23250,7 +23265,7 @@ async function fetchOrganizations(accessToken) {
23250
23265
  return response.json();
23251
23266
  }
23252
23267
  async function fetchProjects(accessToken, orgId) {
23253
- const response = await fetch(`${API_URL}/organizations/${orgId}/projects`, {
23268
+ const response = await fetch(`${getSonorApiUrl()}/organizations/${orgId}/projects`, {
23254
23269
  headers: { "Authorization": `Bearer ${accessToken}` }
23255
23270
  });
23256
23271
  if (!response.ok) {
@@ -23259,7 +23274,7 @@ async function fetchProjects(accessToken, orgId) {
23259
23274
  return response.json();
23260
23275
  }
23261
23276
  async function createProject(accessToken, orgId, data) {
23262
- const response = await fetch(`${API_URL}/organizations/${orgId}/projects`, {
23277
+ const response = await fetch(`${getSonorApiUrl()}/organizations/${orgId}/projects`, {
23263
23278
  method: "POST",
23264
23279
  headers: {
23265
23280
  "Authorization": `Bearer ${accessToken}`,
@@ -23273,7 +23288,7 @@ async function createProject(accessToken, orgId, data) {
23273
23288
  return response.json();
23274
23289
  }
23275
23290
  async function generateApiKey(accessToken, projectId) {
23276
- const response = await fetch(`${API_URL}/projects/${projectId}/api-keys`, {
23291
+ const response = await fetch(`${getSonorApiUrl()}/projects/${projectId}/api-keys`, {
23277
23292
  method: "POST",
23278
23293
  headers: {
23279
23294
  "Authorization": `Bearer ${accessToken}`,
@@ -23477,7 +23492,7 @@ function progress(ctx, line) {
23477
23492
  // src/cli/commands/init.ts
23478
23493
  async function checkNextJsProject(cwd) {
23479
23494
  try {
23480
- const pkg = JSON.parse(await fs3.readFile(path10.join(cwd, "package.json"), "utf-8"));
23495
+ const pkg = JSON.parse(await fs3.readFile(path12.join(cwd, "package.json"), "utf-8"));
23481
23496
  return !!(pkg.dependencies?.next || pkg.devDependencies?.next);
23482
23497
  } catch {
23483
23498
  return false;
@@ -23557,7 +23572,7 @@ async function run(ctx, options) {
23557
23572
  ]);
23558
23573
  if (chosen === "new") {
23559
23574
  const answers = await dist_default14.prompt([
23560
- { type: "input", name: "name", message: "Project name:", default: path10.basename(ctx.cwd) },
23575
+ { type: "input", name: "name", message: "Project name:", default: path12.basename(ctx.cwd) },
23561
23576
  { type: "input", name: "domain", message: "Project domain (optional):" }
23562
23577
  ]);
23563
23578
  const project = await createProject(auth.accessToken, orgId, { name: answers.name, domain: answers.domain || "" });
@@ -23612,7 +23627,7 @@ async function run(ctx, options) {
23612
23627
  };
23613
23628
  }
23614
23629
  async function ensureSitemapPostbuild(ctx) {
23615
- const pkgPath = path10.join(ctx.cwd, "package.json");
23630
+ const pkgPath = path12.join(ctx.cwd, "package.json");
23616
23631
  try {
23617
23632
  const pkg = JSON.parse(await fs3.readFile(pkgPath, "utf-8"));
23618
23633
  if (!pkg.scripts) pkg.scripts = {};
@@ -23654,7 +23669,7 @@ async function scanCommand(options) {
23654
23669
  console.log("");
23655
23670
  console.log(source_default.bold(" Scanning codebase..."));
23656
23671
  console.log("");
23657
- const targetDir = path10.resolve(options.dir || ".");
23672
+ const targetDir = path12.resolve(options.dir || ".");
23658
23673
  const spinner = ora("Looking for forms, metadata, widgets, schemas, FAQs, analytics, and images...").start();
23659
23674
  let scanResults;
23660
23675
  try {
@@ -23832,6 +23847,48 @@ async function scanCommand(options) {
23832
23847
  process.exit(1);
23833
23848
  }
23834
23849
  }
23850
+
23851
+ // src/cli/config.ts
23852
+ var import_dotenv = __toESM(require_main());
23853
+ async function loadConfig({ resolveProject = false, cwd = process.cwd() } = {}) {
23854
+ const envFile = await readOptionalFile(path12.join(cwd, ".env.local"));
23855
+ const env3 = { ...(0, import_dotenv.parse)(envFile || ""), ...process.env };
23856
+ const configPath = resolveStateReadPath("config.json", cwd);
23857
+ const saved = await readOptionalFile(configPath);
23858
+ let stored = {};
23859
+ if (saved !== void 0) {
23860
+ try {
23861
+ stored = JSON.parse(saved);
23862
+ if (!stored || typeof stored !== "object" || Array.isArray(stored)) throw new Error();
23863
+ } catch {
23864
+ throw new ConfigError("INVALID_CONFIG", `Invalid JSON config: ${configPath}. Fix or remove it, then set SONOR_API_KEY in .env.local.`);
23865
+ }
23866
+ }
23867
+ const apiKey = String(env3.SONOR_API_KEY || stored.apiKey || stored.api_key || "").trim();
23868
+ if (!apiKey) {
23869
+ throw new ConfigError("MISSING_API_KEY", "Set SONOR_API_KEY in .env.local or run `sonor-setup init` first.");
23870
+ }
23871
+ if (!/^sonor_[0-9a-f]{8}_.+$/i.test(apiKey)) {
23872
+ throw new ConfigError("INVALID_API_KEY", "SONOR_API_KEY must be a sonor_ key from app.sonor.io.");
23873
+ }
23874
+ const config2 = {
23875
+ apiKey,
23876
+ apiUrl: (env3.SONOR_API_URL || getSonorApiUrl()).replace(/\/+$/, ""),
23877
+ siteUrl: env3.NEXT_PUBLIC_SITE_URL || env3.SITE_URL || stored.siteUrl || stored.site_url,
23878
+ businessInfo: stored.businessInfo || stored.business_info
23879
+ };
23880
+ if (!resolveProject) return config2;
23881
+ const auth = await authenticateWithApiKey(apiKey, config2.apiUrl);
23882
+ return { ...config2, projectId: auth.projectId };
23883
+ }
23884
+ async function readOptionalFile(file) {
23885
+ try {
23886
+ return await fs3.readFile(file, "utf-8");
23887
+ } catch (error2) {
23888
+ if (error2.code === "ENOENT") return void 0;
23889
+ throw new ConfigError("CONFIG_READ_FAILED", `Could not read ${file}. Check file permissions.`);
23890
+ }
23891
+ }
23835
23892
  var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".ico", ".bmp", ".avif"];
23836
23893
  var MIME_TYPES = {
23837
23894
  ".jpg": "image/jpeg",
@@ -23854,7 +23911,7 @@ function filePathToPagePath(filePath) {
23854
23911
  }
23855
23912
  if (p.startsWith("pages/") || p.startsWith("src/pages/")) {
23856
23913
  p = p.replace(/^pages\//, "").replace(/^src\/pages\//, "");
23857
- const base = path10.basename(p, path10.extname(p));
23914
+ const base = path12.basename(p, path12.extname(p));
23858
23915
  return base === "index" ? "/" : "/" + base;
23859
23916
  }
23860
23917
  p = p.replace(/\.[^.]+$/, "").replace(/^\.\//, "").replace(/\\/g, "/");
@@ -23897,8 +23954,8 @@ async function imagesCommand(subcommand, options) {
23897
23954
  }
23898
23955
  }
23899
23956
  async function scanImages(options) {
23900
- const targetDir = path10.resolve(options.dir || ".");
23901
- const publicDir = path10.join(targetDir, "public");
23957
+ const targetDir = path12.resolve(options.dir || ".");
23958
+ const publicDir = path12.join(targetDir, "public");
23902
23959
  try {
23903
23960
  await fs3.access(publicDir);
23904
23961
  } catch {
@@ -23968,7 +24025,7 @@ async function uploadImages(options) {
23968
24025
  console.log("");
23969
24026
  process.exit(1);
23970
24027
  }
23971
- const targetDir = path10.resolve(options.dir || ".");
24028
+ const targetDir = path12.resolve(options.dir || ".");
23972
24029
  const spinner = ora("Scanning for images...").start();
23973
24030
  const results = await scanPublicImages(targetDir);
23974
24031
  spinner.stop();
@@ -24021,7 +24078,7 @@ async function uploadImages(options) {
24021
24078
  const uploadSpinner = ora(`Uploading ${img.filename}...`).start();
24022
24079
  try {
24023
24080
  const result = await uploadImageToPortal(
24024
- path10.join(targetDir, img.filePath),
24081
+ path12.join(targetDir, img.filePath),
24025
24082
  img,
24026
24083
  { apiUrl, apiKey, category: options.category }
24027
24084
  );
@@ -24040,7 +24097,7 @@ async function uploadImages(options) {
24040
24097
  }
24041
24098
  console.log("");
24042
24099
  if (uploaded.length > 0) {
24043
- const manifestPath = path10.join(targetDir, ".uptrade-images.json");
24100
+ const manifestPath = path12.join(targetDir, IMAGE_MANIFEST);
24044
24101
  await fs3.writeFile(manifestPath, JSON.stringify({
24045
24102
  uploaded,
24046
24103
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
@@ -24053,8 +24110,8 @@ async function uploadImages(options) {
24053
24110
  console.log("");
24054
24111
  }
24055
24112
  async function migrateImages(options) {
24056
- const targetDir = path10.resolve(options.dir || ".");
24057
- const manifestPath = path10.join(targetDir, ".uptrade-images.json");
24113
+ const targetDir = path12.resolve(options.dir || ".");
24114
+ const manifestPath = resolveImageManifestReadPath(targetDir);
24058
24115
  const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
24059
24116
  const apiKey = process.env.SONOR_API_KEY || "";
24060
24117
  if (!apiKey) {
@@ -24157,9 +24214,9 @@ async function migrateImages(options) {
24157
24214
  let successCount = 0;
24158
24215
  let failCount = 0;
24159
24216
  for (const [filePath, fileMigrations] of byFile) {
24160
- const fileSpinner = ora(`Migrating ${path10.basename(filePath)}...`).start();
24217
+ const fileSpinner = ora(`Migrating ${path12.basename(filePath)}...`).start();
24161
24218
  try {
24162
- await migrateFileImages(path10.join(targetDir, filePath), fileMigrations);
24219
+ await migrateFileImages(path12.join(targetDir, filePath), fileMigrations);
24163
24220
  successCount += fileMigrations.length;
24164
24221
  fileSpinner.succeed(`Migrated: ${filePath} (${fileMigrations.length} images)`);
24165
24222
  } catch (error2) {
@@ -24181,7 +24238,7 @@ async function migrateImages(options) {
24181
24238
  console.log("");
24182
24239
  }
24183
24240
  async function uploadAndMigrate(options) {
24184
- const targetDir = path10.resolve(options.dir || ".");
24241
+ const targetDir = path12.resolve(options.dir || ".");
24185
24242
  const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
24186
24243
  const apiKey = process.env.SONOR_API_KEY || "";
24187
24244
  if (!apiKey) {
@@ -24248,7 +24305,7 @@ async function uploadAndMigrate(options) {
24248
24305
  const uploadSpinner = ora(`Uploading ${img.filename}...`).start();
24249
24306
  try {
24250
24307
  const result = await uploadImageToPortal(
24251
- path10.join(targetDir, img.filePath),
24308
+ path12.join(targetDir, img.filePath),
24252
24309
  img,
24253
24310
  { apiUrl, apiKey, category: options.category }
24254
24311
  );
@@ -24320,9 +24377,9 @@ async function uploadAndMigrate(options) {
24320
24377
  let successCount = 0;
24321
24378
  let failCount = 0;
24322
24379
  for (const [filePath, fileMigrations] of byFile) {
24323
- const fileSpinner = ora(`Migrating ${path10.basename(filePath)}...`).start();
24380
+ const fileSpinner = ora(`Migrating ${path12.basename(filePath)}...`).start();
24324
24381
  try {
24325
- await migrateFileImages(path10.join(targetDir, filePath), fileMigrations);
24382
+ await migrateFileImages(path12.join(targetDir, filePath), fileMigrations);
24326
24383
  successCount += fileMigrations.length;
24327
24384
  fileSpinner.succeed(`Migrated: ${filePath} (${fileMigrations.length} images)`);
24328
24385
  } catch (error2) {
@@ -24330,7 +24387,7 @@ async function uploadAndMigrate(options) {
24330
24387
  fileSpinner.fail(`Failed: ${filePath} - ${error2.message}`);
24331
24388
  }
24332
24389
  }
24333
- const manifestPath = path10.join(targetDir, ".uptrade-images.json");
24390
+ const manifestPath = path12.join(targetDir, IMAGE_MANIFEST);
24334
24391
  await fs3.writeFile(manifestPath, JSON.stringify({
24335
24392
  uploaded,
24336
24393
  criticalKeptLocal: criticalImages.map((i) => i.filename),
@@ -24357,8 +24414,8 @@ async function uploadAndMigrate(options) {
24357
24414
  console.log("");
24358
24415
  }
24359
24416
  async function replaceWithCdnUrls(options) {
24360
- const targetDir = path10.resolve(options.dir || ".");
24361
- const manifestPath = path10.join(targetDir, ".uptrade-images.json");
24417
+ const targetDir = path12.resolve(options.dir || ".");
24418
+ const manifestPath = resolveImageManifestReadPath(targetDir);
24362
24419
  let manifest;
24363
24420
  try {
24364
24421
  const content = await fs3.readFile(manifestPath, "utf-8");
@@ -24406,7 +24463,7 @@ async function replaceWithCdnUrls(options) {
24406
24463
  if (!seenFileLines.has(key)) {
24407
24464
  seenFileLines.add(key);
24408
24465
  replacements2.push({
24409
- file: path10.relative(targetDir, file),
24466
+ file: path12.relative(targetDir, file),
24410
24467
  localPath: pattern,
24411
24468
  cdnUrl: img.publicUrl,
24412
24469
  line: i + 1
@@ -24454,9 +24511,9 @@ async function replaceWithCdnUrls(options) {
24454
24511
  let successCount = 0;
24455
24512
  let failCount = 0;
24456
24513
  for (const [filePath, fileReplacements] of byFile) {
24457
- const fileSpinner = ora(`Updating ${path10.basename(filePath)}...`).start();
24514
+ const fileSpinner = ora(`Updating ${path12.basename(filePath)}...`).start();
24458
24515
  try {
24459
- const fullPath = path10.join(targetDir, filePath);
24516
+ const fullPath = path12.join(targetDir, filePath);
24460
24517
  let content = await fs3.readFile(fullPath, "utf-8");
24461
24518
  for (const r of fileReplacements) {
24462
24519
  const escaped = r.localPath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -24484,8 +24541,8 @@ async function replaceWithCdnUrls(options) {
24484
24541
  console.log("");
24485
24542
  }
24486
24543
  async function refreshManifest(options) {
24487
- const targetDir = path10.resolve(options.dir || ".");
24488
- const manifestPath = path10.join(targetDir, ".uptrade-images.json");
24544
+ const targetDir = path12.resolve(options.dir || ".");
24545
+ const manifestPath = path12.join(targetDir, IMAGE_MANIFEST);
24489
24546
  const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
24490
24547
  const apiKey = process.env.SONOR_API_KEY || "";
24491
24548
  if (!apiKey) {
@@ -24494,7 +24551,7 @@ async function refreshManifest(options) {
24494
24551
  }
24495
24552
  let manifest;
24496
24553
  try {
24497
- const content = await fs3.readFile(manifestPath, "utf-8");
24554
+ const content = await fs3.readFile(resolveImageManifestReadPath(targetDir), "utf-8");
24498
24555
  manifest = JSON.parse(content);
24499
24556
  } catch {
24500
24557
  console.log(source_default.yellow(" \u26A0 No upload manifest found"));
@@ -24547,12 +24604,12 @@ async function refreshManifest(options) {
24547
24604
  }
24548
24605
  async function findDataFiles(rootDir) {
24549
24606
  const files = [];
24550
- const excludeFiles = [".uptrade-images.json"];
24607
+ const excludeFiles = [IMAGE_MANIFEST, LEGACY_IMAGE_MANIFEST];
24551
24608
  async function scan(dir) {
24552
24609
  try {
24553
24610
  const entries = await fs3.readdir(dir, { withFileTypes: true });
24554
24611
  for (const entry of entries) {
24555
- const fullPath = path10.join(dir, entry.name);
24612
+ const fullPath = path12.join(dir, entry.name);
24556
24613
  if (entry.isDirectory()) {
24557
24614
  if (["node_modules", ".next", ".git", "dist", "build"].includes(entry.name)) {
24558
24615
  continue;
@@ -24562,7 +24619,7 @@ async function findDataFiles(rootDir) {
24562
24619
  if (excludeFiles.includes(entry.name)) {
24563
24620
  continue;
24564
24621
  }
24565
- const ext2 = path10.extname(entry.name).toLowerCase();
24622
+ const ext2 = path12.extname(entry.name).toLowerCase();
24566
24623
  if ([".js", ".ts", ".json", ".jsx", ".tsx", ".mjs", ".cjs"].includes(ext2)) {
24567
24624
  files.push(fullPath);
24568
24625
  }
@@ -24575,16 +24632,16 @@ async function findDataFiles(rootDir) {
24575
24632
  return files;
24576
24633
  }
24577
24634
  async function scanPublicImages(rootDir) {
24578
- const publicDir = path10.join(rootDir, "public");
24635
+ const publicDir = path12.join(rootDir, "public");
24579
24636
  const images = [];
24580
24637
  let totalSize = 0;
24581
24638
  let usageCount = 0;
24582
24639
  const imageFiles = await findImagesRecursive(publicDir);
24583
24640
  const sourceFiles = await findSourceFiles2(rootDir);
24584
24641
  for (const imagePath of imageFiles) {
24585
- const relPath = path10.relative(rootDir, imagePath);
24586
- const filename = path10.basename(imagePath);
24587
- const ext2 = path10.extname(filename).toLowerCase();
24642
+ const relPath = path12.relative(rootDir, imagePath);
24643
+ const filename = path12.basename(imagePath);
24644
+ const ext2 = path12.extname(filename).toLowerCase();
24588
24645
  const stat = await fs3.stat(imagePath);
24589
24646
  const category = getCategoryFromPath(relPath);
24590
24647
  const suggestedSlotId = generateSlotId(relPath);
@@ -24610,11 +24667,11 @@ async function findImagesRecursive(dir, files = []) {
24610
24667
  try {
24611
24668
  const entries = await fs3.readdir(dir, { withFileTypes: true });
24612
24669
  for (const entry of entries) {
24613
- const fullPath = path10.join(dir, entry.name);
24670
+ const fullPath = path12.join(dir, entry.name);
24614
24671
  if (entry.isDirectory()) {
24615
24672
  await findImagesRecursive(fullPath, files);
24616
24673
  } else if (entry.isFile()) {
24617
- const ext2 = path10.extname(entry.name).toLowerCase();
24674
+ const ext2 = path12.extname(entry.name).toLowerCase();
24618
24675
  if (IMAGE_EXTENSIONS.includes(ext2)) {
24619
24676
  files.push(fullPath);
24620
24677
  }
@@ -24627,7 +24684,7 @@ async function findImagesRecursive(dir, files = []) {
24627
24684
  async function findSourceFiles2(dir, files = []) {
24628
24685
  const entries = await fs3.readdir(dir, { withFileTypes: true });
24629
24686
  for (const entry of entries) {
24630
- const fullPath = path10.join(dir, entry.name);
24687
+ const fullPath = path12.join(dir, entry.name);
24631
24688
  if (entry.isDirectory()) {
24632
24689
  if (["node_modules", ".next", ".git", "dist", "build", "public"].includes(entry.name)) {
24633
24690
  continue;
@@ -24643,8 +24700,8 @@ async function findSourceFiles2(dir, files = []) {
24643
24700
  }
24644
24701
  async function findImageUsages(imagePath, sourceFiles, rootDir) {
24645
24702
  const usages = [];
24646
- const filename = path10.basename(imagePath);
24647
- const relPath = path10.relative(path10.join(rootDir, "public"), imagePath);
24703
+ const filename = path12.basename(imagePath);
24704
+ const relPath = path12.relative(path12.join(rootDir, "public"), imagePath);
24648
24705
  const patterns = [
24649
24706
  `/${relPath}`,
24650
24707
  // /images/hero.jpg
@@ -24666,7 +24723,7 @@ async function findImageUsages(imagePath, sourceFiles, rootDir) {
24666
24723
  const elementType = detectElementType(line);
24667
24724
  const canAutoMigrate = ["img", "Image"].includes(elementType);
24668
24725
  usages.push({
24669
- filePath: path10.relative(rootDir, sourceFile),
24726
+ filePath: path12.relative(rootDir, sourceFile),
24670
24727
  line: i + 1,
24671
24728
  elementType,
24672
24729
  altText: extractAltText(line),
@@ -24738,7 +24795,7 @@ function detectCriticalImage(filename, relPath, usages, fileSize) {
24738
24795
  (u) => u.filePath.includes("layout.") || u.filePath.includes("/layout/")
24739
24796
  );
24740
24797
  const usedInCriticalComponent = usages.some((u) => {
24741
- const fileName = path10.basename(u.filePath).toLowerCase();
24798
+ const fileName = path12.basename(u.filePath).toLowerCase();
24742
24799
  return fileName.includes("header") || fileName.includes("navbar") || fileName.includes("nav.") || fileName.includes("hero") || fileName.includes("footer");
24743
24800
  });
24744
24801
  const isSiteLogo = SITE_LOGO_PATTERNS.some((p) => p.test(filename));
@@ -24874,7 +24931,7 @@ async function uploadAndMigrateImages(scanResults, options) {
24874
24931
  for (const img of scanResults.images) {
24875
24932
  try {
24876
24933
  const uploadResult = await uploadImageToPortal(
24877
- path10.join(rootDir, img.filePath),
24934
+ path12.join(rootDir, img.filePath),
24878
24935
  img,
24879
24936
  {
24880
24937
  apiUrl: options.apiUrl,
@@ -24902,7 +24959,7 @@ async function uploadAndMigrateImages(scanResults, options) {
24902
24959
  }
24903
24960
  for (const [filePath, migrations] of byFile) {
24904
24961
  try {
24905
- await migrateFileImages(path10.join(rootDir, filePath), migrations);
24962
+ await migrateFileImages(path12.join(rootDir, filePath), migrations);
24906
24963
  result.migrated += migrations.length;
24907
24964
  } catch (error2) {
24908
24965
  result.errors.push(`Migration failed for ${filePath}: ${error2.message}`);
@@ -24916,31 +24973,25 @@ async function migrateCommand(options) {
24916
24973
  console.log("");
24917
24974
  console.log(source_default.bold(" Site-Kit Migration"));
24918
24975
  console.log("");
24919
- const apiKey = process.env.SONOR_API_KEY;
24920
- const projectId = process.env.SONOR_PROJECT_ID;
24921
- if (!apiKey || !projectId) {
24922
- console.log(source_default.red(" \u2717 Missing environment variables"));
24923
- console.log(source_default.gray(" Run `sonor-setup init` first to configure your project."));
24924
- console.log("");
24925
- process.exit(1);
24926
- }
24976
+ const { apiKey, projectId, apiUrl } = await loadConfig({ resolveProject: true });
24927
24977
  if (options.dryRun) {
24928
24978
  console.log(source_default.yellow(" Running in dry-run mode - no files will be modified"));
24929
24979
  console.log("");
24930
24980
  }
24931
24981
  if (options.file) {
24932
- const filePath = path10.resolve(options.file);
24982
+ const filePath = path12.resolve(options.file);
24933
24983
  try {
24934
24984
  await fs3.access(filePath);
24935
24985
  } catch {
24936
24986
  console.log(source_default.red(` \u2717 File not found: ${filePath}`));
24937
24987
  process.exit(1);
24938
24988
  }
24939
- const spinner = ora(`Migrating ${path10.basename(filePath)}...`).start();
24989
+ const spinner = ora(`Migrating ${path12.basename(filePath)}...`).start();
24940
24990
  try {
24941
24991
  const result = await migrateFile(filePath, {
24942
24992
  projectId,
24943
24993
  apiKey,
24994
+ apiUrl,
24944
24995
  dryRun: options.dryRun
24945
24996
  });
24946
24997
  if (result.success) {
@@ -25003,6 +25054,7 @@ async function migrateCommand(options) {
25003
25054
  const results = await migrateFiles(scanResults, {
25004
25055
  projectId,
25005
25056
  apiKey,
25057
+ apiUrl,
25006
25058
  dryRun: options.dryRun
25007
25059
  });
25008
25060
  const successful = results.filter((r) => r.success);
@@ -25032,10 +25084,9 @@ async function migrateCommand(options) {
25032
25084
  process.exit(1);
25033
25085
  }
25034
25086
  console.log("");
25035
- await handleImageMigration(options, apiKey);
25087
+ await handleImageMigration(options, apiKey, apiUrl);
25036
25088
  }
25037
- async function handleImageMigration(options, apiKey, projectId) {
25038
- const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
25089
+ async function handleImageMigration(options, apiKey, apiUrl) {
25039
25090
  const imageScanSpinner = ora("Scanning for images...").start();
25040
25091
  let imageResults;
25041
25092
  try {
@@ -25099,17 +25150,11 @@ function formatBytes2(bytes) {
25099
25150
  return `${parseFloat((bytes / Math.pow(k2, i)).toFixed(1))} ${sizes[i]}`;
25100
25151
  }
25101
25152
  var SKIP_PROPS = ["href", "src", "className", "style", "onClick", "ref", "key", "id", "target", "rel", "type", "name", "variant", "size", "icon"];
25102
- var API_URL2 = process.env.SONOR_API_URL || "https://api.sonor.io";
25103
- var TEMPLATES_DIR = ".uptrade/templates";
25153
+ var TEMPLATES_DIR = path12.join(SONOR_STATE_DIR, "templates");
25104
25154
  async function locationsCommand(subcommand, arg, options) {
25105
25155
  console.log("");
25106
25156
  console.log(source_default.bold(" \u{1F4CD} Site-Kit Location Page Manager"));
25107
25157
  console.log("");
25108
- const config2 = await loadConfig();
25109
- if (!config2?.projectId) {
25110
- console.log(source_default.red(" \u2717 Not configured. Run `npx sonor-setup init` first."));
25111
- return;
25112
- }
25113
25158
  switch (subcommand) {
25114
25159
  case "template":
25115
25160
  if (!arg) {
@@ -25117,6 +25162,7 @@ async function locationsCommand(subcommand, arg, options) {
25117
25162
  console.log(source_default.gray(" Example: locations template ./app/services/plumbing/page.tsx"));
25118
25163
  return;
25119
25164
  }
25165
+ await loadConfig();
25120
25166
  await templateCommand(arg, options);
25121
25167
  break;
25122
25168
  case "upload":
@@ -25124,17 +25170,17 @@ async function locationsCommand(subcommand, arg, options) {
25124
25170
  console.log(source_default.red(" \u2717 Usage: locations upload --template <name>"));
25125
25171
  return;
25126
25172
  }
25127
- await uploadCommand(options.template, config2);
25173
+ await uploadCommand(options.template, await loadConfig({ resolveProject: true }));
25128
25174
  break;
25129
25175
  case "generate":
25130
25176
  if (!options.template) {
25131
25177
  console.log(source_default.red(' \u2717 Usage: locations generate --template <name> --locations "City, ST" ...'));
25132
25178
  return;
25133
25179
  }
25134
- await generateCommand(options, config2);
25180
+ await generateCommand(options, await loadConfig({ resolveProject: true }));
25135
25181
  break;
25136
25182
  case "list":
25137
- await listCommand(config2);
25183
+ await listCommand(await loadConfig({ resolveProject: true }));
25138
25184
  break;
25139
25185
  default:
25140
25186
  console.log(source_default.yellow(" Available subcommands:"));
@@ -25146,10 +25192,10 @@ async function locationsCommand(subcommand, arg, options) {
25146
25192
  console.log("");
25147
25193
  }
25148
25194
  }
25149
- async function templateCommand(sourcePath, options, config2) {
25195
+ async function templateCommand(sourcePath, options) {
25150
25196
  const spinner = ora("Analyzing source page...").start();
25151
25197
  try {
25152
- const resolvedPath = path10.resolve(sourcePath);
25198
+ const resolvedPath = path12.resolve(sourcePath);
25153
25199
  if (!existsSync(resolvedPath)) {
25154
25200
  spinner.fail(`File not found: ${sourcePath}`);
25155
25201
  return;
@@ -25162,8 +25208,8 @@ async function templateCommand(sourcePath, options, config2) {
25162
25208
  const slots = [];
25163
25209
  const componentNames = [];
25164
25210
  traverse(ast, {
25165
- JSXElement(path27) {
25166
- const openingElement = path27.node.openingElement;
25211
+ JSXElement(path29) {
25212
+ const openingElement = path29.node.openingElement;
25167
25213
  if (isJSXIdentifier(openingElement.name)) {
25168
25214
  const componentName = openingElement.name.name;
25169
25215
  if (componentName[0] === componentName[0].toUpperCase()) {
@@ -25203,8 +25249,9 @@ async function templateCommand(sourcePath, options, config2) {
25203
25249
  },
25204
25250
  managed_components: ["schema", "faqs", "metadata"]
25205
25251
  };
25206
- await fs3.mkdir(TEMPLATES_DIR, { recursive: true });
25207
- const templatePath = path10.join(TEMPLATES_DIR, `${templateName}.json`);
25252
+ const templatesDir = path12.join(process.cwd(), TEMPLATES_DIR);
25253
+ await fs3.mkdir(templatesDir, { recursive: true });
25254
+ const templatePath = path12.join(templatesDir, `${templateName}.json`);
25208
25255
  await fs3.writeFile(templatePath, JSON.stringify(template, null, 2));
25209
25256
  console.log("");
25210
25257
  console.log(source_default.green(" \u2713 Template created:"), source_default.cyan(templatePath));
@@ -25283,7 +25330,7 @@ function inferGenerationHint(propName) {
25283
25330
  return void 0;
25284
25331
  }
25285
25332
  function inferTemplateName(sourcePath) {
25286
- const parts = sourcePath.split(path10.sep);
25333
+ const parts = sourcePath.split(path12.sep);
25287
25334
  const pageIndex = parts.findIndex((p) => p === "page.tsx" || p === "page.jsx");
25288
25335
  if (pageIndex > 0) {
25289
25336
  return parts[pageIndex - 1];
@@ -25292,14 +25339,14 @@ function inferTemplateName(sourcePath) {
25292
25339
  return filtered[filtered.length - 1] || "template";
25293
25340
  }
25294
25341
  function inferSourcePagePath(sourcePath) {
25295
- const parts = sourcePath.split(path10.sep);
25342
+ const parts = sourcePath.split(path12.sep);
25296
25343
  const appIndex = parts.findIndex((p) => p === "app" || p === "pages");
25297
25344
  if (appIndex >= 0) {
25298
25345
  const pathParts = parts.slice(appIndex + 1);
25299
25346
  const filtered = pathParts.filter((p) => !["page.tsx", "page.jsx", "index.tsx", "index.jsx"].includes(p));
25300
25347
  return "/" + filtered.join("/");
25301
25348
  }
25302
- return "/" + path10.basename(sourcePath, path10.extname(sourcePath));
25349
+ return "/" + path12.basename(sourcePath, path12.extname(sourcePath));
25303
25350
  }
25304
25351
  function toSnakeCase(str) {
25305
25352
  return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
@@ -25311,22 +25358,22 @@ function truncate(str, maxLength) {
25311
25358
  async function uploadCommand(templateName, config2) {
25312
25359
  const spinner = ora("Uploading template to Portal...").start();
25313
25360
  try {
25314
- const templatePath = path10.join(TEMPLATES_DIR, `${templateName}.json`);
25361
+ const templatePath = resolveStateReadPath(path12.join("templates", `${templateName}.json`));
25315
25362
  if (!existsSync(templatePath)) {
25316
25363
  spinner.fail(`Template not found: ${templatePath}`);
25317
25364
  console.log(source_default.gray(` Run: npx sonor-setup locations template <page> --name ${templateName}`));
25318
25365
  return;
25319
25366
  }
25320
25367
  const template = JSON.parse(readFileSync(templatePath, "utf-8"));
25321
- const response = await fetch(`${API_URL2}/seo/location-templates`, {
25368
+ const response = await fetch(`${config2.apiUrl}/seo/location-templates`, {
25322
25369
  method: "POST",
25323
25370
  headers: {
25324
25371
  "Content-Type": "application/json",
25325
25372
  "Authorization": `Bearer ${config2.apiKey}`
25326
25373
  },
25327
25374
  body: JSON.stringify({
25328
- project_id: config2.projectId,
25329
- ...template
25375
+ ...template,
25376
+ project_id: config2.projectId
25330
25377
  })
25331
25378
  });
25332
25379
  if (!response.ok) {
@@ -25334,11 +25381,11 @@ async function uploadCommand(templateName, config2) {
25334
25381
  if (response.status === 409) {
25335
25382
  spinner.text = "Template exists, updating...";
25336
25383
  const existing = await fetch(
25337
- `${API_URL2}/seo/location-templates/by-name/${templateName}?project_id=${config2.projectId}`,
25384
+ `${config2.apiUrl}/seo/location-templates/by-name/${templateName}?project_id=${config2.projectId}`,
25338
25385
  { headers: { "Authorization": `Bearer ${config2.apiKey}` } }
25339
25386
  );
25340
25387
  const existingData = await existing.json();
25341
- const updateResponse = await fetch(`${API_URL2}/seo/location-templates/${existingData.id}`, {
25388
+ const updateResponse = await fetch(`${config2.apiUrl}/seo/location-templates/${existingData.id}`, {
25342
25389
  method: "PUT",
25343
25390
  headers: {
25344
25391
  "Content-Type": "application/json",
@@ -25387,7 +25434,7 @@ async function generateCommand(options, config2) {
25387
25434
  }
25388
25435
  const spinner = ora(`Generating ${type || "service-location"} pages...`).start();
25389
25436
  try {
25390
- const response = await fetch(`${API_URL2}/seo/location-pages/generate`, {
25437
+ const response = await fetch(`${config2.apiUrl}/seo/location-pages/generate`, {
25391
25438
  method: "POST",
25392
25439
  headers: {
25393
25440
  "Content-Type": "application/json",
@@ -25427,7 +25474,7 @@ async function listCommand(config2) {
25427
25474
  const spinner = ora("Fetching templates...").start();
25428
25475
  try {
25429
25476
  const response = await fetch(
25430
- `${API_URL2}/seo/location-templates?project_id=${config2.projectId}`,
25477
+ `${config2.apiUrl}/seo/location-templates?project_id=${config2.projectId}`,
25431
25478
  { headers: { "Authorization": `Bearer ${config2.apiKey}` } }
25432
25479
  );
25433
25480
  if (!response.ok) {
@@ -25452,69 +25499,21 @@ async function listCommand(config2) {
25452
25499
  });
25453
25500
  }
25454
25501
  console.log("");
25455
- if (existsSync(TEMPLATES_DIR)) {
25456
- const files = await fs3.readdir(TEMPLATES_DIR);
25457
- const localTemplates = files.filter((f) => f.endsWith(".json"));
25458
- if (localTemplates.length > 0) {
25459
- console.log(source_default.gray(" Local (not uploaded):"));
25460
- localTemplates.forEach((f) => {
25461
- console.log(source_default.gray(` \u2022 ${f.replace(".json", "")}`));
25462
- });
25463
- console.log("");
25464
- }
25502
+ const localTemplates = await listLocalTemplates();
25503
+ if (localTemplates.length > 0) {
25504
+ console.log(source_default.gray(" Local (not uploaded):"));
25505
+ localTemplates.forEach((f) => {
25506
+ console.log(source_default.gray(` \u2022 ${f.replace(".json", "")}`));
25507
+ });
25508
+ console.log("");
25465
25509
  }
25466
25510
  } catch (error2) {
25467
25511
  spinner.fail(`Failed to fetch templates: ${error2.message}`);
25468
25512
  }
25469
25513
  }
25470
- async function loadConfig() {
25471
- const configPath = path10.join(".uptrade", "config.json");
25472
- if (existsSync(configPath)) {
25473
- try {
25474
- const config2 = JSON.parse(readFileSync(configPath, "utf-8"));
25475
- return {
25476
- projectId: config2.projectId || config2.project_id,
25477
- apiKey: config2.apiKey || config2.api_key
25478
- };
25479
- } catch {
25480
- return null;
25481
- }
25482
- }
25483
- const projectId = process.env.SONOR_PROJECT_ID;
25484
- const apiKey = process.env.SONOR_API_KEY;
25485
- if (projectId && apiKey) {
25486
- return { projectId, apiKey };
25487
- }
25488
- return null;
25489
- }
25490
- var API_URL3 = process.env.SONOR_API_URL || "https://api.sonor.io";
25491
- async function loadConfig2() {
25492
- const configPath = path10.join(".uptrade", "config.json");
25493
- if (existsSync(configPath)) {
25494
- try {
25495
- const config2 = JSON.parse(readFileSync(configPath, "utf-8"));
25496
- return {
25497
- projectId: config2.projectId || config2.project_id,
25498
- apiKey: config2.apiKey || config2.api_key
25499
- };
25500
- } catch {
25501
- return null;
25502
- }
25503
- }
25504
- const projectId = process.env.SONOR_PROJECT_ID;
25505
- const apiKey = process.env.SONOR_API_KEY;
25506
- if (projectId && apiKey) return { projectId, apiKey };
25507
- return null;
25508
- }
25509
25514
  async function faqsCommand(subcommand, options) {
25510
25515
  console.log("");
25511
- const config2 = await loadConfig2();
25512
- if (!config2?.projectId || !config2?.apiKey) {
25513
- console.log(source_default.red(" \u2717 Not configured. Run `npx sonor-setup init` first."));
25514
- console.log(source_default.gray(" Set SONOR_API_KEY, or use .uptrade/config.json"));
25515
- console.log("");
25516
- return;
25517
- }
25516
+ const config2 = await loadConfig({ resolveProject: true });
25518
25517
  switch (subcommand) {
25519
25518
  case "extract":
25520
25519
  await extractCommand(options, config2);
@@ -25564,7 +25563,7 @@ async function extractCommand(options, config2) {
25564
25563
  const faqContexts = [];
25565
25564
  for (const faq of faqSections) {
25566
25565
  try {
25567
- const fullPath = path10.resolve(process.cwd(), faq.filePath);
25566
+ const fullPath = path12.resolve(process.cwd(), faq.filePath);
25568
25567
  const content = await fs3.readFile(fullPath, "utf-8");
25569
25568
  let pagePath = faq.filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
25570
25569
  if (pagePath === "" || pagePath === "/page") pagePath = "/";
@@ -25579,7 +25578,7 @@ async function extractCommand(options, config2) {
25579
25578
  if (importPath.startsWith("@/")) {
25580
25579
  resolvedPath = importPath.replace("@/", "./");
25581
25580
  } else if (importPath.startsWith(".")) {
25582
- resolvedPath = path10.resolve(path10.dirname(fullPath), importPath);
25581
+ resolvedPath = path12.resolve(path12.dirname(fullPath), importPath);
25583
25582
  }
25584
25583
  const extensions = ["", ".js", ".ts", ".jsx", ".tsx", ".json"];
25585
25584
  for (const ext2 of extensions) {
@@ -25624,7 +25623,7 @@ async function extractCommand(options, config2) {
25624
25623
  }
25625
25624
  const extractSpinner = ora("Extracting FAQs via AI...").start();
25626
25625
  try {
25627
- const response = await fetch(`${API_URL3}/seo/managed/faqs/extract`, {
25626
+ const response = await fetch(`${config2.apiUrl}/seo/managed/faqs/extract`, {
25628
25627
  method: "POST",
25629
25628
  headers: {
25630
25629
  "Content-Type": "application/json",
@@ -25659,7 +25658,7 @@ async function extractCommand(options, config2) {
25659
25658
  let failed = 0;
25660
25659
  for (const faq of extractedFaqs) {
25661
25660
  try {
25662
- const res = await fetch(`${API_URL3}/seo/managed/faqs`, {
25661
+ const res = await fetch(`${config2.apiUrl}/seo/managed/faqs`, {
25663
25662
  method: "POST",
25664
25663
  headers: {
25665
25664
  "Content-Type": "application/json",
@@ -25684,7 +25683,7 @@ async function extractCommand(options, config2) {
25684
25683
  uploaded++;
25685
25684
  console.log(source_default.green(` \u2713 ${faq.path}`) + source_default.gray(` (${faq.items.length} items)`));
25686
25685
  } else if (res.status === 409 || res.status === 400) {
25687
- const updateRes = await fetch(`${API_URL3}/seo/managed/faqs/by-path`, {
25686
+ const updateRes = await fetch(`${config2.apiUrl}/seo/managed/faqs/by-path`, {
25688
25687
  method: "PUT",
25689
25688
  headers: {
25690
25689
  "Content-Type": "application/json",
@@ -25754,7 +25753,7 @@ async function syncCommand(options, config2) {
25754
25753
  if (codePaths.length === 0) {
25755
25754
  spinner.warn("No ManagedFAQ components found");
25756
25755
  console.log("");
25757
- console.log(source_default.gray(' Add <ManagedFAQ projectId={...} path="/your-page" /> to your pages, then run:'));
25756
+ console.log(source_default.gray(' Add <ManagedFAQ path="/your-page" /> to your pages, then run:'));
25758
25757
  console.log(source_default.gray(" npx sonor-setup migrate (to add the component)"));
25759
25758
  console.log(source_default.gray(" npx sonor-setup faqs sync (to register paths in Portal)"));
25760
25759
  console.log("");
@@ -25771,7 +25770,7 @@ async function syncCommand(options, config2) {
25771
25770
  const listSpinner = ora("Fetching existing FAQ sections from Portal...").start();
25772
25771
  let existing = [];
25773
25772
  try {
25774
- const res = await fetch(`${API_URL3}/seo/managed/faqs/project/${config2.projectId}`, {
25773
+ const res = await fetch(`${config2.apiUrl}/seo/managed/faqs/project/${config2.projectId}`, {
25775
25774
  headers: { Authorization: `Bearer ${config2.apiKey}` }
25776
25775
  });
25777
25776
  if (!res.ok) {
@@ -25800,7 +25799,7 @@ async function syncCommand(options, config2) {
25800
25799
  let failed = 0;
25801
25800
  for (const p of toCreate) {
25802
25801
  try {
25803
- const res = await fetch(`${API_URL3}/seo/managed/faqs`, {
25802
+ const res = await fetch(`${config2.apiUrl}/seo/managed/faqs`, {
25804
25803
  method: "POST",
25805
25804
  headers: {
25806
25805
  "Content-Type": "application/json",
@@ -25837,44 +25836,12 @@ async function syncCommand(options, config2) {
25837
25836
  console.log(source_default.gray(" Add questions and answers there; they will appear on your site."));
25838
25837
  console.log("");
25839
25838
  }
25840
- function getApiUrl() {
25841
- return process.env.SONOR_API_URL || "https://api.sonor.io";
25842
- }
25843
- async function loadConfig3() {
25844
- const configPath = path10.join(".uptrade", "config.json");
25845
- if (existsSync(configPath)) {
25846
- try {
25847
- const config2 = JSON.parse(readFileSync(configPath, "utf-8"));
25848
- return {
25849
- projectId: config2.projectId || config2.project_id,
25850
- apiKey: config2.apiKey || config2.api_key,
25851
- siteUrl: config2.siteUrl || config2.site_url,
25852
- businessInfo: config2.businessInfo || config2.business_info
25853
- };
25854
- } catch {
25855
- return null;
25856
- }
25857
- }
25858
- const projectId = process.env.SONOR_PROJECT_ID;
25859
- const apiKey = process.env.SONOR_API_KEY;
25860
- const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || process.env.SITE_URL;
25861
- if (projectId && apiKey) {
25862
- return { projectId, apiKey, siteUrl };
25863
- }
25864
- return null;
25865
- }
25866
25839
  async function setupCommand(options) {
25867
25840
  console.log("");
25868
25841
  console.log(source_default.bold.blue(" \u{1F680} Signal-Enhanced SEO Setup"));
25869
25842
  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"));
25870
25843
  console.log("");
25871
- const config2 = await loadConfig3();
25872
- if (!config2?.projectId || !config2?.apiKey) {
25873
- console.log(source_default.red(" \u2717 Not configured. Run `npx sonor-setup init` first."));
25874
- console.log(source_default.gray(" Set SONOR_API_KEY"));
25875
- console.log("");
25876
- return;
25877
- }
25844
+ const config2 = await loadConfig();
25878
25845
  const capabilities = [];
25879
25846
  if (options.faqsOnly) {
25880
25847
  capabilities.push("extract_faqs");
@@ -25972,14 +25939,13 @@ async function setupCommand(options) {
25972
25939
  const batch = batches[batchIndex];
25973
25940
  const batchSpinner = ora(`Batch ${batchIndex + 1}/${batches.length}: Analyzing ${batch.length} pages...`).start();
25974
25941
  try {
25975
- const response = await fetch(`${getApiUrl()}/api/public/seo/site-setup`, {
25942
+ const response = await fetch(`${config2.apiUrl}/api/public/seo/site-setup`, {
25976
25943
  method: "POST",
25977
25944
  headers: {
25978
25945
  "Content-Type": "application/json",
25979
25946
  "x-api-key": config2.apiKey
25980
25947
  },
25981
25948
  body: JSON.stringify({
25982
- project_id: config2.projectId,
25983
25949
  site_url: config2.siteUrl || "https://example.com",
25984
25950
  // Only send business_info on first batch (for org schema)
25985
25951
  business_info: batchIndex === 0 ? config2.businessInfo : void 0,
@@ -26071,10 +26037,10 @@ async function setupCommand(options) {
26071
26037
  }
26072
26038
  async function scanForPageFiles(rootDir) {
26073
26039
  const pages = [];
26074
- const appDir = path10.join(rootDir, "app");
26075
- const srcAppDir = path10.join(rootDir, "src", "app");
26076
- const pagesDir = path10.join(rootDir, "pages");
26077
- const srcPagesDir = path10.join(rootDir, "src", "pages");
26040
+ const appDir = path12.join(rootDir, "app");
26041
+ const srcAppDir = path12.join(rootDir, "src", "app");
26042
+ const pagesDir = path12.join(rootDir, "pages");
26043
+ const srcPagesDir = path12.join(rootDir, "src", "pages");
26078
26044
  const dirs = [appDir, srcAppDir, pagesDir, srcPagesDir];
26079
26045
  for (const dir of dirs) {
26080
26046
  if (existsSync(dir)) {
@@ -26086,7 +26052,7 @@ async function scanForPageFiles(rootDir) {
26086
26052
  async function scanDirectory(dir, baseDir, pages) {
26087
26053
  const entries = await fs3.readdir(dir, { withFileTypes: true });
26088
26054
  for (const entry of entries) {
26089
- const fullPath = path10.join(dir, entry.name);
26055
+ const fullPath = path12.join(dir, entry.name);
26090
26056
  if (entry.isDirectory()) {
26091
26057
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "api") {
26092
26058
  continue;
@@ -26097,8 +26063,8 @@ async function scanDirectory(dir, baseDir, pages) {
26097
26063
  const isLegacyPage = baseDir.includes("/pages") && entry.name.match(/\.(tsx?|jsx?)$/) && !entry.name.startsWith("_");
26098
26064
  if (isPage || isLegacyPage) {
26099
26065
  const content = await fs3.readFile(fullPath, "utf-8");
26100
- const relativePath = path10.relative(baseDir, fullPath);
26101
- let pagePath = "/" + path10.dirname(relativePath).replace(/\\/g, "/").replace(/\/page$/, "");
26066
+ const relativePath = path12.relative(baseDir, fullPath);
26067
+ let pagePath = "/" + path12.dirname(relativePath).replace(/\\/g, "/").replace(/\/page$/, "");
26102
26068
  pagePath = pagePath.replace(/\[([^\]]+)\]/g, ":$1").replace(/^\/\.$/, "/");
26103
26069
  if (pagePath === "/.") pagePath = "/";
26104
26070
  pages.push({
@@ -26118,10 +26084,10 @@ async function gatherImportedFiles(page, rootDir) {
26118
26084
  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")) {
26119
26085
  let resolvedPath = importPath;
26120
26086
  if (importPath.startsWith("@/")) {
26121
- resolvedPath = path10.join(rootDir, importPath.replace("@/", ""));
26087
+ resolvedPath = path12.join(rootDir, importPath.replace("@/", ""));
26122
26088
  } else if (importPath.startsWith(".")) {
26123
- const pageDir = path10.dirname(path10.join(rootDir, "app", page.filePath));
26124
- resolvedPath = path10.resolve(pageDir, importPath);
26089
+ const pageDir = path12.dirname(path12.join(rootDir, "app", page.filePath));
26090
+ resolvedPath = path12.resolve(pageDir, importPath);
26125
26091
  }
26126
26092
  const extensions = ["", ".js", ".ts", ".jsx", ".tsx", ".json"];
26127
26093
  for (const ext2 of extensions) {
@@ -26177,20 +26143,20 @@ async function expandDynamicRoutes(pages, rootDir) {
26177
26143
  async function findDynamicRouteData(page, parentPath, rootDir) {
26178
26144
  const results = [];
26179
26145
  const dataFilePaths = [
26180
- path10.join(rootDir, "data", "practice-areas.js"),
26181
- path10.join(rootDir, "data", "practice-areas.ts"),
26182
- path10.join(rootDir, "data", "personal-injury-pages.js"),
26183
- path10.join(rootDir, "data", "personal-injury-pages.ts"),
26184
- path10.join(rootDir, "data", "pages.js"),
26185
- path10.join(rootDir, "data", "pages.ts"),
26186
- path10.join(rootDir, "data", "content.js"),
26187
- path10.join(rootDir, "data", "content.ts"),
26188
- path10.join(rootDir, "data", "services.js"),
26189
- path10.join(rootDir, "data", "services.ts"),
26190
- path10.join(rootDir, "data", "subpages.js"),
26191
- path10.join(rootDir, "data", "subpages.ts"),
26192
- path10.join(rootDir, "src", "data", "practice-areas.js"),
26193
- path10.join(rootDir, "src", "data", "practice-areas.ts")
26146
+ path12.join(rootDir, "data", "practice-areas.js"),
26147
+ path12.join(rootDir, "data", "practice-areas.ts"),
26148
+ path12.join(rootDir, "data", "personal-injury-pages.js"),
26149
+ path12.join(rootDir, "data", "personal-injury-pages.ts"),
26150
+ path12.join(rootDir, "data", "pages.js"),
26151
+ path12.join(rootDir, "data", "pages.ts"),
26152
+ path12.join(rootDir, "data", "content.js"),
26153
+ path12.join(rootDir, "data", "content.ts"),
26154
+ path12.join(rootDir, "data", "services.js"),
26155
+ path12.join(rootDir, "data", "services.ts"),
26156
+ path12.join(rootDir, "data", "subpages.js"),
26157
+ path12.join(rootDir, "data", "subpages.ts"),
26158
+ path12.join(rootDir, "src", "data", "practice-areas.js"),
26159
+ path12.join(rootDir, "src", "data", "practice-areas.ts")
26194
26160
  ];
26195
26161
  const routeSegment = parentPath.replace(/^\//, "").split("/")[0];
26196
26162
  const routeSegmentNormalized = routeSegment.replace(/-/g, "");
@@ -26282,7 +26248,7 @@ async function uploadFaqs(pages, config2) {
26282
26248
  for (const page of pages) {
26283
26249
  if (!page.faqs?.items?.length) continue;
26284
26250
  try {
26285
- const res = await fetch(`${getApiUrl()}/api/public/seo/register-faq`, {
26251
+ const res = await fetch(`${config2.apiUrl}/api/public/seo/register-faq`, {
26286
26252
  method: "POST",
26287
26253
  headers: {
26288
26254
  "Content-Type": "application/json",
@@ -26317,7 +26283,7 @@ async function uploadFaqs(pages, config2) {
26317
26283
  async function uploadSchemas(pages, globalSchema, config2) {
26318
26284
  if (globalSchema) {
26319
26285
  try {
26320
- const res = await fetch(`${getApiUrl()}/api/public/seo/register-schema`, {
26286
+ const res = await fetch(`${config2.apiUrl}/api/public/seo/register-schema`, {
26321
26287
  method: "POST",
26322
26288
  headers: {
26323
26289
  "Content-Type": "application/json",
@@ -26343,7 +26309,7 @@ async function uploadSchemas(pages, globalSchema, config2) {
26343
26309
  if (!page.schemas?.length) continue;
26344
26310
  for (const schema of page.schemas) {
26345
26311
  try {
26346
- const res = await fetch(`${getApiUrl()}/api/public/seo/register-schema`, {
26312
+ const res = await fetch(`${config2.apiUrl}/api/public/seo/register-schema`, {
26347
26313
  method: "POST",
26348
26314
  headers: {
26349
26315
  "Content-Type": "application/json",
@@ -26367,7 +26333,7 @@ async function uploadSchemas(pages, globalSchema, config2) {
26367
26333
  }
26368
26334
  }
26369
26335
  }
26370
- var APP_DIRS = ["app", path10.join("src", "app")];
26336
+ var APP_DIRS = ["app", path12.join("src", "app")];
26371
26337
  var CARD_FILE = /^(opengraph-image|twitter-image)\b.*\.(png|jpe?g|gif|webp)$/i;
26372
26338
  function safeExists(p) {
26373
26339
  try {
@@ -26387,19 +26353,19 @@ function findPageCards(cwd) {
26387
26353
  }
26388
26354
  for (const entry of entries) {
26389
26355
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
26390
- const full = path10.join(dir, entry.name);
26356
+ const full = path12.join(dir, entry.name);
26391
26357
  if (entry.isDirectory()) walk(full);
26392
26358
  else if (CARD_FILE.test(entry.name)) found.push(full);
26393
26359
  }
26394
26360
  };
26395
- for (const rel of APP_DIRS) walk(path10.join(cwd, rel));
26361
+ for (const rel of APP_DIRS) walk(path12.join(cwd, rel));
26396
26362
  return found;
26397
26363
  }
26398
26364
  function readOgWiring(cwd) {
26399
26365
  const siteCard = ["public/og.png", "public/og.jpg", "public/opengraph.png"].some(
26400
- (rel) => safeExists(path10.join(cwd, rel))
26366
+ (rel) => safeExists(path12.join(cwd, rel))
26401
26367
  );
26402
- const layoutPath = ["app/layout.tsx", "src/app/layout.tsx"].map((rel) => path10.join(cwd, rel)).find(safeExists);
26368
+ const layoutPath = ["app/layout.tsx", "src/app/layout.tsx"].map((rel) => path12.join(cwd, rel)).find(safeExists);
26403
26369
  let layout = "";
26404
26370
  if (layoutPath) {
26405
26371
  try {
@@ -26458,8 +26424,15 @@ function checkOgWiring(cwd) {
26458
26424
  return judgeOgWiring(readOgWiring(cwd));
26459
26425
  }
26460
26426
 
26427
+ // src/cli/agent/ssr-bailout.ts
26428
+ var DEFERRED_SIBLING_SINCE = "3.0.2";
26429
+ var LAYOUT_ALREADY_DEFERS = `plain <SiteKitLayout>{children}</SiteKitLayout> already mounts analytics as a deferred, childless sibling on site-kit >=${DEFERRED_SIBLING_SINCE}`;
26430
+ var LEGACY_STOPGAP = `Only on site-kit <${DEFERRED_SIBLING_SINCE}: upgrade, or as a stopgap run SiteKitLayout with analytics={false} plus a deferred, childless analytics sibling.`;
26431
+ var SSR_BAILOUT_FIX = `Keep the layout: ${LAYOUT_ALREADY_DEFERS}, so it is not the cause. Find what else wraps {children}, usually a next/dynamic({ ssr: false }) component such as a site's own lazy Providers. Import it statically (a client component still server-renders; only ssr: false skips that) or mount it as a childless sibling. ${LEGACY_STOPGAP}`;
26432
+ 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;
26433
+
26461
26434
  // src/cli/agent/checks.ts
26462
- var API_URL4 = process.env.SONOR_API_URL || "https://api.sonor.io";
26435
+ var API_URL = process.env.SONOR_API_URL || "https://api.sonor.io";
26463
26436
  async function readFileOrNull(p) {
26464
26437
  try {
26465
26438
  return await fs3.readFile(p, "utf-8");
@@ -26469,7 +26442,7 @@ async function readFileOrNull(p) {
26469
26442
  }
26470
26443
  async function findFirst(cwd, candidates) {
26471
26444
  for (const rel of candidates) {
26472
- const full = path10.join(cwd, rel);
26445
+ const full = path12.join(cwd, rel);
26473
26446
  if (await readFileOrNull(full)) return full;
26474
26447
  }
26475
26448
  return null;
@@ -26521,7 +26494,7 @@ function checkApiKeyEnv() {
26521
26494
  };
26522
26495
  }
26523
26496
  async function checkPackageInstalled(cwd) {
26524
- const raw = await readFileOrNull(path10.join(cwd, "package.json"));
26497
+ const raw = await readFileOrNull(path12.join(cwd, "package.json"));
26525
26498
  if (!raw) {
26526
26499
  return {
26527
26500
  id: "package.installed",
@@ -26585,7 +26558,7 @@ async function checkSiteKitLayout(cwd) {
26585
26558
  };
26586
26559
  }
26587
26560
  const content = await readFileOrNull(layoutPath) || "";
26588
- const rel = path10.relative(cwd, layoutPath);
26561
+ const rel = path12.relative(cwd, layoutPath);
26589
26562
  if (content.includes("SiteKitLayout")) {
26590
26563
  return {
26591
26564
  id: "layout.sitekit",
@@ -26641,7 +26614,7 @@ async function checkSitemap(cwd) {
26641
26614
  };
26642
26615
  }
26643
26616
  async function checkPostbuildSitemap(cwd) {
26644
- const raw = await readFileOrNull(path10.join(cwd, "package.json"));
26617
+ const raw = await readFileOrNull(path12.join(cwd, "package.json"));
26645
26618
  let pkg = {};
26646
26619
  try {
26647
26620
  pkg = raw ? JSON.parse(raw) : {};
@@ -26678,18 +26651,18 @@ async function checkPostbuildSitemap(cwd) {
26678
26651
  async function checkApiReachable(timeoutMs = 5e3) {
26679
26652
  const key = process.env.SONOR_API_KEY;
26680
26653
  try {
26681
- const res = await fetch(`${API_URL4}/health`, {
26654
+ const res = await fetch(`${API_URL}/health`, {
26682
26655
  headers: key ? { "x-api-key": key } : {},
26683
26656
  signal: AbortSignal.timeout(timeoutMs)
26684
26657
  });
26685
26658
  if (res.ok) {
26686
- return { id: "api.reachable", title: "Sonor API", level: "ok", message: `Reachable (${API_URL4})` };
26659
+ return { id: "api.reachable", title: "Sonor API", level: "ok", message: `Reachable (${API_URL})` };
26687
26660
  }
26688
26661
  return {
26689
26662
  id: "api.reachable",
26690
26663
  title: "Sonor API",
26691
26664
  level: "warn",
26692
- message: `HTTP ${res.status} from ${API_URL4}`
26665
+ message: `HTTP ${res.status} from ${API_URL}`
26693
26666
  };
26694
26667
  } catch (err) {
26695
26668
  return {
@@ -26714,7 +26687,7 @@ async function checkKeyValid(timeoutMs = 8e3) {
26714
26687
  };
26715
26688
  }
26716
26689
  try {
26717
- const res = await fetch(`${API_URL4}/api/public/seo/verify-api-key`, {
26690
+ const res = await fetch(`${API_URL}/api/public/seo/verify-api-key`, {
26718
26691
  headers: { "x-api-key": key },
26719
26692
  signal: AbortSignal.timeout(timeoutMs)
26720
26693
  });
@@ -26817,7 +26790,7 @@ async function checkClientAuth(timeoutMs = 8e3) {
26817
26790
  }
26818
26791
  const qs2 = host ? `?host=${encodeURIComponent(host)}` : "";
26819
26792
  try {
26820
- const res = await fetch(`${API_URL4}/api/public/site-token/status${qs2}`, {
26793
+ const res = await fetch(`${API_URL}/api/public/site-token/status${qs2}`, {
26821
26794
  headers: { "x-api-key": key },
26822
26795
  signal: AbortSignal.timeout(timeoutMs)
26823
26796
  });
@@ -26940,7 +26913,7 @@ async function checkSsrRenderFromUrl(url, timeoutMs = 12e3) {
26940
26913
  level: "error",
26941
26914
  message: "Page bailed to client rendering",
26942
26915
  detail: `Only ${contentTags} content tags in the server HTML \u2014 the route ships an empty shell + RSC flight data.`,
26943
- fix: "Run SiteKitLayout with analytics={false} and mount analytics as a deferred, childless sibling (never wrap {children}).",
26916
+ fix: SSR_BAILOUT_FIX,
26944
26917
  docs: "manifest#failureModes"
26945
26918
  };
26946
26919
  }
@@ -26962,7 +26935,7 @@ async function checkSsrRenderFromUrl(url, timeoutMs = 12e3) {
26962
26935
  }
26963
26936
  }
26964
26937
  async function checkSsrRenderFromBuild(cwd) {
26965
- const appDir = path10.join(cwd, ".next", "server", "app");
26938
+ const appDir = path12.join(cwd, ".next", "server", "app");
26966
26939
  let entries;
26967
26940
  try {
26968
26941
  entries = await fs3.readdir(appDir);
@@ -26985,7 +26958,7 @@ async function checkSsrRenderFromBuild(cwd) {
26985
26958
  detail: "The root route may be fully dynamic. Pass --url to verify a running instance."
26986
26959
  };
26987
26960
  }
26988
- const html = await readFileOrNull(path10.join(appDir, htmlName)) || "";
26961
+ const html = await readFileOrNull(path12.join(appDir, htmlName)) || "";
26989
26962
  const { rendered, contentTags } = looksServerRendered(html);
26990
26963
  if (rendered) {
26991
26964
  return {
@@ -27000,7 +26973,7 @@ async function checkSsrRenderFromBuild(cwd) {
27000
26973
  title: "Server-side rendering",
27001
26974
  level: "error",
27002
26975
  message: `Prerendered HTML has only ${contentTags} content tags \u2014 likely CSR bailout`,
27003
- fix: "Run SiteKitLayout with analytics={false} + a deferred, childless analytics sibling.",
26976
+ fix: SSR_BAILOUT_FIX,
27004
26977
  docs: "manifest#failureModes"
27005
26978
  };
27006
26979
  }
@@ -27008,7 +26981,7 @@ async function checkNetlifyMiddleware(cwd) {
27008
26981
  const runtimeRe = /runtime\s*[:=]\s*['"](nodejs|edge)['"]/;
27009
26982
  const proxyFiles = ["proxy.ts", "proxy.js", "src/proxy.ts", "src/proxy.js"];
27010
26983
  for (const rel of proxyFiles) {
27011
- const content = await readFileOrNull(path10.join(cwd, rel));
26984
+ const content = await readFileOrNull(path12.join(cwd, rel));
27012
26985
  if (content === null) continue;
27013
26986
  if (runtimeRe.test(content)) {
27014
26987
  return {
@@ -27025,7 +26998,7 @@ async function checkNetlifyMiddleware(cwd) {
27025
26998
  }
27026
26999
  const middlewareFiles = ["middleware.ts", "middleware.js", "src/middleware.ts", "src/middleware.js"];
27027
27000
  for (const rel of middlewareFiles) {
27028
- const content = await readFileOrNull(path10.join(cwd, rel));
27001
+ const content = await readFileOrNull(path12.join(cwd, rel));
27029
27002
  if (content === null) continue;
27030
27003
  if (/runtime\s*[:=]\s*['"]nodejs['"]/.test(content)) {
27031
27004
  return {
@@ -27052,7 +27025,7 @@ async function checkNetlifyMiddleware(cwd) {
27052
27025
  }
27053
27026
  async function checkImageDimsDrift(cwd) {
27054
27027
  const scanRoots = ["app", "src/app", "components", "src/components"];
27055
- const publicDir = path10.join(cwd, "public");
27028
+ const publicDir = path12.join(cwd, "public");
27056
27029
  const files = [];
27057
27030
  async function walk(dir, depth) {
27058
27031
  if (depth > 4) return;
@@ -27064,19 +27037,19 @@ async function checkImageDimsDrift(cwd) {
27064
27037
  }
27065
27038
  for (const e of entries) {
27066
27039
  if (e.name === "node_modules" || e.name.startsWith(".")) continue;
27067
- const full = path10.join(dir, e.name);
27040
+ const full = path12.join(dir, e.name);
27068
27041
  if (e.isDirectory()) await walk(full, depth + 1);
27069
27042
  else if (/\.(tsx|jsx)$/.test(e.name)) files.push(full);
27070
27043
  }
27071
27044
  }
27072
- for (const root of scanRoots) await walk(path10.join(cwd, root), 0);
27045
+ for (const root of scanRoots) await walk(path12.join(cwd, root), 0);
27073
27046
  if (files.length === 0) {
27074
27047
  return { id: "images.dims-drift", title: "Image dims vs SVG", level: "skip", message: "No component files found" };
27075
27048
  }
27076
27049
  const viewBoxCache = /* @__PURE__ */ new Map();
27077
27050
  async function svgAspect(publicPath) {
27078
27051
  if (viewBoxCache.has(publicPath)) return viewBoxCache.get(publicPath);
27079
- const svg = await readFileOrNull(path10.join(publicDir, publicPath.replace(/^\//, "")));
27052
+ const svg = await readFileOrNull(path12.join(publicDir, publicPath.replace(/^\//, "")));
27080
27053
  let aspect = null;
27081
27054
  if (svg) {
27082
27055
  const vb = svg.match(/viewBox="([\d.\s-]+)"/);
@@ -27103,7 +27076,7 @@ async function checkImageDimsDrift(cwd) {
27103
27076
  const drift = Math.abs(declared - actual) / actual;
27104
27077
  if (drift > 0.02) {
27105
27078
  drifts.push(
27106
- `${path10.relative(cwd, file)}: ${src} is ${actual.toFixed(2)}:1 but width/height declare ${declared.toFixed(2)}:1 (${Math.round(drift * 100)}% off)`
27079
+ `${path12.relative(cwd, file)}: ${src} is ${actual.toFixed(2)}:1 but width/height declare ${declared.toFixed(2)}:1 (${Math.round(drift * 100)}% off)`
27107
27080
  );
27108
27081
  }
27109
27082
  }
@@ -27219,8 +27192,8 @@ async function statusCommand(options) {
27219
27192
 
27220
27193
  // src/og/pages.ts
27221
27194
  var DYNAMIC = "*";
27222
- function pathSegments(path27) {
27223
- return path27.split("/").filter(Boolean);
27195
+ function pathSegments(path29) {
27196
+ return path29.split("/").filter(Boolean);
27224
27197
  }
27225
27198
  function stripBrandSuffix(title, brand) {
27226
27199
  const cleaned = title.replace(/\s*[|–—-]\s*[^|–—-]+$/, "").trim();
@@ -27228,13 +27201,13 @@ function stripBrandSuffix(title, brand) {
27228
27201
  if (brand && cleaned.toLowerCase() === brand.toLowerCase()) return title.trim();
27229
27202
  return cleaned;
27230
27203
  }
27231
- function titleFromPath(path27) {
27232
- const last = pathSegments(path27).filter((s) => s !== DYNAMIC).pop();
27204
+ function titleFromPath(path29) {
27205
+ const last = pathSegments(path29).filter((s) => s !== DYNAMIC).pop();
27233
27206
  if (!last) return "Home";
27234
27207
  return last.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
27235
27208
  }
27236
- function kickerFromPath(path27, fallback) {
27237
- const parts = pathSegments(path27);
27209
+ function kickerFromPath(path29, fallback) {
27210
+ const parts = pathSegments(path29);
27238
27211
  const section = parts.includes(DYNAMIC) ? parts.filter((s) => s !== DYNAMIC) : parts.slice(0, -1);
27239
27212
  if (!section.length) return fallback;
27240
27213
  return section.join(" / ").replace(/[-_]+/g, " ");
@@ -27258,8 +27231,8 @@ function kickerIsRedundant(kicker, title) {
27258
27231
  const titleWords = new Set(t.split(" "));
27259
27232
  return k2.split(" ").every((w) => titleWords.has(w));
27260
27233
  }
27261
- function slugForPath(path27) {
27262
- const segments = pathSegments(path27);
27234
+ function slugForPath(path29) {
27235
+ const segments = pathSegments(path29);
27263
27236
  if (!segments.length) return "home";
27264
27237
  return segments.map((s) => s === DYNAMIC ? "any" : s).join("-").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
27265
27238
  }
@@ -27313,10 +27286,10 @@ function findChrome() {
27313
27286
  }
27314
27287
  return null;
27315
27288
  }
27316
- async function loadConfig4(cwd) {
27289
+ async function loadConfig2(cwd) {
27317
27290
  const candidates = ["og.config.ts", "og.config.mts", "og.config.mjs", "og.config.js"];
27318
27291
  for (const rel of candidates) {
27319
- const full = path10.join(cwd, rel);
27292
+ const full = path12.join(cwd, rel);
27320
27293
  if (!existsSync(full)) continue;
27321
27294
  try {
27322
27295
  const mod = await import(
@@ -27341,7 +27314,7 @@ async function loadConfig4(cwd) {
27341
27314
  return null;
27342
27315
  }
27343
27316
  async function seedConfig(cwd) {
27344
- let name = path10.basename(cwd).replace(/-nextjs$/, "").replace(/-/g, " ");
27317
+ let name = path12.basename(cwd).replace(/-nextjs$/, "").replace(/-/g, " ");
27345
27318
  let accent = "#111111";
27346
27319
  let logo;
27347
27320
  try {
@@ -27354,7 +27327,7 @@ async function seedConfig(cwd) {
27354
27327
  } catch {
27355
27328
  }
27356
27329
  for (const candidate of ["/logo-mark.svg", "/logo.svg", "/logohorizontal.svg"]) {
27357
- if (existsSync(path10.join(cwd, "public", candidate))) {
27330
+ if (existsSync(path12.join(cwd, "public", candidate))) {
27358
27331
  logo = candidate;
27359
27332
  break;
27360
27333
  }
@@ -27368,14 +27341,14 @@ async function seedConfig(cwd) {
27368
27341
  }
27369
27342
  function inlinePublicPaths(html, cwd) {
27370
27343
  return html.replace(/src="(\/[^"]+)"/g, (_3, p) => {
27371
- const full = path10.join(cwd, "public", p);
27344
+ const full = path12.join(cwd, "public", p);
27372
27345
  return existsSync(full) ? `src="file://${full}"` : `src="${p}"`;
27373
27346
  });
27374
27347
  }
27375
27348
  async function renderCard(config2, outPath, cwd, chrome, tmpSuffix) {
27376
- const tmpHtml = path10.join(cwd, `.sonor-og-${tmpSuffix}.html`);
27349
+ const tmpHtml = path12.join(cwd, `.sonor-og-${tmpSuffix}.html`);
27377
27350
  try {
27378
- await fs3.mkdir(path10.dirname(outPath), { recursive: true });
27351
+ await fs3.mkdir(path12.dirname(outPath), { recursive: true });
27379
27352
  await fs3.writeFile(tmpHtml, inlinePublicPaths(buildOgHtml(config2), cwd));
27380
27353
  const { stdout } = await execFileAsync5(
27381
27354
  chrome,
@@ -27410,7 +27383,7 @@ function parseReport(dom) {
27410
27383
  }
27411
27384
  async function compressCard(pngPath, cwd) {
27412
27385
  try {
27413
- const require_ = (await import('module')).createRequire(path10.join(cwd, "package.json"));
27386
+ const require_ = (await import('module')).createRequire(path12.join(cwd, "package.json"));
27414
27387
  const sharp = require_("sharp");
27415
27388
  const jpgPath = pngPath.replace(/\.png$/, ".jpg");
27416
27389
  await sharp(pngPath).jpeg({ quality: 84, mozjpeg: true }).toFile(jpgPath);
@@ -27427,13 +27400,13 @@ function discoverDynamicSegments(appDir) {
27427
27400
  if (!entry.isDirectory()) continue;
27428
27401
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
27429
27402
  if (entry.name === "api" || entry.name === "node_modules") continue;
27430
- const full = path10.join(dir, entry.name);
27403
+ const full = path12.join(dir, entry.name);
27431
27404
  const isGroup = entry.name.startsWith("(") && entry.name.endsWith(")");
27432
27405
  const isDynamic = entry.name.startsWith("[") && entry.name.endsWith("]");
27433
27406
  const nextUrl = isGroup || isDynamic ? urlSegments : [...urlSegments, entry.name];
27434
27407
  const nextPattern = isGroup ? pattern : [...pattern, isDynamic ? DYNAMIC : entry.name];
27435
27408
  if (isDynamic) {
27436
- const hasPage = ["tsx", "jsx", "ts", "js"].some((ext2) => existsSync(path10.join(full, `page.${ext2}`)));
27409
+ const hasPage = ["tsx", "jsx", "ts", "js"].some((ext2) => existsSync(path12.join(full, `page.${ext2}`)));
27437
27410
  if (hasPage) {
27438
27411
  found.push({ dir: full, path: `/${nextPattern.join("/")}`, parent: `/${urlSegments.join("/")}` });
27439
27412
  }
@@ -27461,7 +27434,7 @@ async function resolveRouteCopy(paths) {
27461
27434
  try {
27462
27435
  if (process.env.SONOR_API_KEY) {
27463
27436
  ;
27464
- ({ getSEOPageData } = await import('../api-NTHZ6PAW.mjs'));
27437
+ ({ getSEOPageData } = await import('../api-D745LGGU.mjs'));
27465
27438
  }
27466
27439
  } catch {
27467
27440
  getSEOPageData = null;
@@ -27509,7 +27482,7 @@ async function runOg(options) {
27509
27482
  errors: [{ code: "chrome_missing", message: "No Chrome or Chromium binary found", fix: "Install Chrome, or set SONOR_CHROME_PATH to its path." }]
27510
27483
  };
27511
27484
  }
27512
- let config2 = await loadConfig4(cwd);
27485
+ let config2 = await loadConfig2(cwd);
27513
27486
  let seeded = false;
27514
27487
  if (!config2) {
27515
27488
  config2 = await seedConfig(cwd);
@@ -27517,7 +27490,7 @@ async function runOg(options) {
27517
27490
  console.log(source_default.yellow(" ! No og.config.ts \u2014 generating a seed card from Sonor brand data."));
27518
27491
  console.log(source_default.gray(" The site owns its theme: add og.config.ts (defineOgCard) with the real palette."));
27519
27492
  }
27520
- const outPath = path10.resolve(cwd, options.out || "public/og.png");
27493
+ const outPath = path12.resolve(cwd, options.out || "public/og.png");
27521
27494
  let clean = true;
27522
27495
  let cardKeyFix = null;
27523
27496
  let pageCardsWritten = 0;
@@ -27527,8 +27500,8 @@ async function runOg(options) {
27527
27500
  const report = await renderCard(config2, outPath, cwd, chrome, "site");
27528
27501
  spinner.stop();
27529
27502
  console.log(source_default.bold(` Site card${seeded ? source_default.gray(" (seed)") : ""}`));
27530
- clean = reportCard(`${path10.relative(cwd, outPath)} \u2014 1200x630`, report) && clean;
27531
- checks.push(cardCheck("site card", path10.relative(cwd, outPath), report));
27503
+ clean = reportCard(`${path12.relative(cwd, outPath)} \u2014 1200x630`, report) && clean;
27504
+ checks.push(cardCheck("site card", path12.relative(cwd, outPath), report));
27532
27505
  } catch (err) {
27533
27506
  const message = err instanceof Error ? err.message.split("\n")[0] : String(err);
27534
27507
  spinner.fail(`Render failed: ${message}`);
@@ -27591,16 +27564,16 @@ async function runOg(options) {
27591
27564
  const pageConfig = pageCardConfig(config2, route, brand);
27592
27565
  const dir = route.dir ?? routeOutputDir(appDir, route.path);
27593
27566
  for (const ext2 of ["png", "jpg", "jpeg"]) {
27594
- await fs3.rm(path10.join(dir, `opengraph-image.${ext2}`), { force: true });
27567
+ await fs3.rm(path12.join(dir, `opengraph-image.${ext2}`), { force: true });
27595
27568
  }
27596
- const png = path10.join(dir, "opengraph-image.png");
27569
+ const png = path12.join(dir, "opengraph-image.png");
27597
27570
  const report = await renderCard(pageConfig, png, cwd, chrome, `page-${i}`);
27598
27571
  const file = await compressCard(png, cwd);
27599
27572
  return { route, file, report };
27600
27573
  });
27601
27574
  for (const { route, file, report } of reports) {
27602
- clean = reportCard(`${route.path} ${source_default.gray(path10.relative(cwd, file))}`, report) && clean;
27603
- checks.push(cardCheck(route.path, path10.relative(cwd, file), report));
27575
+ clean = reportCard(`${route.path} ${source_default.gray(path12.relative(cwd, file))}`, report) && clean;
27576
+ checks.push(cardCheck(route.path, path12.relative(cwd, file), report));
27604
27577
  }
27605
27578
  pageCardsWritten = reports.length;
27606
27579
  const bytes = await totalBytes(reports.map((r) => r.file));
@@ -27611,13 +27584,13 @@ async function runOg(options) {
27611
27584
  }
27612
27585
  if (options.preview !== false) {
27613
27586
  try {
27614
- const require_ = (await import('module')).createRequire(path10.join(cwd, "package.json"));
27587
+ const require_ = (await import('module')).createRequire(path12.join(cwd, "package.json"));
27615
27588
  const sharp = require_("sharp");
27616
- const previewPath = path10.join(cwd, ".sonor", "og-preview.png");
27617
- await fs3.mkdir(path10.dirname(previewPath), { recursive: true });
27589
+ const previewPath = path12.join(cwd, ".sonor", "og-preview.png");
27590
+ await fs3.mkdir(path12.dirname(previewPath), { recursive: true });
27618
27591
  await sharp(outPath).resize(300).toFile(previewPath);
27619
27592
  console.log("");
27620
- console.log(source_default.gray(` Thumbnail check: ${path10.relative(cwd, previewPath)} \u2014 if text is mush there, fix the card.`));
27593
+ console.log(source_default.gray(` Thumbnail check: ${path12.relative(cwd, previewPath)} \u2014 if text is mush there, fix the card.`));
27621
27594
  } catch {
27622
27595
  console.log(source_default.gray(" (sharp not resolvable \u2014 skipped the 300px preview)"));
27623
27596
  }
@@ -27676,15 +27649,15 @@ function routeOutputDir(appDir, urlPath) {
27676
27649
  const segments = urlPath.split("/").filter(Boolean);
27677
27650
  let dir = appDir;
27678
27651
  for (const segment of segments) {
27679
- const direct = path10.join(dir, segment);
27652
+ const direct = path12.join(dir, segment);
27680
27653
  if (existsSync(direct)) {
27681
27654
  dir = direct;
27682
27655
  continue;
27683
27656
  }
27684
27657
  const group = existsSync(dir) ? readdirSync(dir, { withFileTypes: true }).find(
27685
- (e) => e.isDirectory() && e.name.startsWith("(") && e.name.endsWith(")") && existsSync(path10.join(dir, e.name, segment))
27658
+ (e) => e.isDirectory() && e.name.startsWith("(") && e.name.endsWith(")") && existsSync(path12.join(dir, e.name, segment))
27686
27659
  ) : void 0;
27687
- dir = group ? path10.join(dir, group.name, segment) : direct;
27660
+ dir = group ? path12.join(dir, group.name, segment) : direct;
27688
27661
  }
27689
27662
  return dir;
27690
27663
  }
@@ -27699,7 +27672,7 @@ async function totalBytes(files) {
27699
27672
  return total;
27700
27673
  }
27701
27674
  async function siteDomain(cwd) {
27702
- const envFile = path10.join(cwd, ".env.local");
27675
+ const envFile = path12.join(cwd, ".env.local");
27703
27676
  if (existsSync(envFile)) {
27704
27677
  const env3 = await fs3.readFile(envFile, "utf-8").catch(() => "");
27705
27678
  const url = env3.match(/^NEXT_PUBLIC_SITE_URL=(.+)$/m)?.[1]?.trim();
@@ -27824,14 +27797,14 @@ var hs = new RegExp(pe, "g");
27824
27797
  var as = /\\\\/g;
27825
27798
  var ls = /\\{/g;
27826
27799
  var cs = /\\}/g;
27827
- var fs20 = /\\,/g;
27800
+ var fs22 = /\\,/g;
27828
27801
  var us = /\\./g;
27829
27802
  var ds = 1e5;
27830
27803
  function Ht(n5) {
27831
27804
  return isNaN(n5) ? n5.charCodeAt(0) : parseInt(n5, 10);
27832
27805
  }
27833
27806
  function ps(n5) {
27834
- return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs20, de).replace(us, pe);
27807
+ return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs22, de).replace(us, pe);
27835
27808
  }
27836
27809
  function ms(n5) {
27837
27810
  return n5.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(os5, ",").replace(hs, ".");
@@ -30863,10 +30836,10 @@ function unifiedDiff(before, after, filePath, context = 2) {
30863
30836
  return lines.join("\n");
30864
30837
  }
30865
30838
  function ext(filePath) {
30866
- return path10.extname(filePath).toLowerCase();
30839
+ return path12.extname(filePath).toLowerCase();
30867
30840
  }
30868
30841
  function basename(filePath) {
30869
- return path10.basename(filePath).toLowerCase();
30842
+ return path12.basename(filePath).toLowerCase();
30870
30843
  }
30871
30844
  var CODE_EXT = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
30872
30845
  var TEXT_EXT = /* @__PURE__ */ new Set([...CODE_EXT, ".css", ".scss", ".json", ".md", ".mdx"]);
@@ -30966,18 +30939,21 @@ var analyticsSibling = {
30966
30939
  appliesTo(filePath) {
30967
30940
  return LAYOUT_FILE.test(filePath.replace(/\\/g, "/"));
30968
30941
  },
30969
- // Deliberately detect-and-flag, never auto-rewrite: turning an arbitrary
30970
- // layout into the deferred-sibling shape can silently drop analytics or break
30971
- // the tree. We surface the exact fix + reference impls instead of guessing.
30942
+ // Deliberately detect-and-flag, never auto-rewrite: removing a wrapper from
30943
+ // an arbitrary layout can silently drop analytics or break the tree. We
30944
+ // surface the exact fix instead of guessing.
30945
+ //
30946
+ // A plain <SiteKitLayout>{children}</SiteKitLayout> is NOT flagged: it is the
30947
+ // blessed layout, and since 3.0.2 it mounts analytics as a deferred, childless
30948
+ // sibling itself (see ssr-bailout.ts). Flagging it told every correct site to
30949
+ // hand-roll the sibling the package already ships.
30972
30950
  run(source) {
30973
30951
  const flags = [];
30974
- const wrapsChildren = /\{\s*children\s*\}/.test(source);
30975
- const sitekitLayoutOn = /<SiteKitLayout(?![^>]*analytics\s*=\s*\{?\s*false)/.test(source) && /<SiteKitLayout[\s\S]*\{\s*children\s*\}[\s\S]*<\/SiteKitLayout>/.test(source);
30976
30952
  const rawAnalyticsWrapper = /<AnalyticsProvider[\s\S]*\{\s*children\s*\}[\s\S]*<\/AnalyticsProvider>/.test(source);
30977
- if (wrapsChildren && (sitekitLayoutOn || rawAnalyticsWrapper)) {
30953
+ if (rawAnalyticsWrapper) {
30978
30954
  flags.push({
30979
- reason: rawAnalyticsWrapper ? "AnalyticsProvider wraps {children} \u2014 this de-opts the route to client rendering (SSR bailout)" : "SiteKitLayout wraps {children} with analytics enabled \u2014 analytics runs in the hydration path",
30980
- fix: "Run SiteKitLayout with analytics={false} and mount analytics as a deferred, lazy, CHILDLESS sibling (never wrap {children}). Reference: upforge-nextjs/app/deferred-analytics.tsx and true-power-systems-nextjs/src/components/DeferredAnalytics.tsx."
30955
+ reason: "AnalyticsProvider wraps {children}: analytics joins the hydration path, and if the provider is lazy-loaded with next/dynamic({ ssr: false }) the whole route de-opts to client rendering (SSR bailout)",
30956
+ fix: ANALYTICS_WRAPPER_FIX
30981
30957
  });
30982
30958
  }
30983
30959
  return { output: source, changes: [], flags };
@@ -31017,7 +30993,7 @@ var IGNORE = [
31017
30993
  ];
31018
30994
  async function listFiles(cwd, onlyPath) {
31019
30995
  if (onlyPath) {
31020
- const rel = path10.isAbsolute(onlyPath) ? path10.relative(cwd, onlyPath) : onlyPath;
30996
+ const rel = path12.isAbsolute(onlyPath) ? path12.relative(cwd, onlyPath) : onlyPath;
31021
30997
  return [rel];
31022
30998
  }
31023
30999
  const matches = await Ze(SCAN_PATTERNS, { cwd, ignore: IGNORE, dot: true, nodir: true });
@@ -31029,7 +31005,7 @@ async function runCodemod(options) {
31029
31005
  const files = await listFiles(cwd, onlyPath);
31030
31006
  const changes = [];
31031
31007
  for (const rel of files) {
31032
- const full = path10.join(cwd, rel);
31008
+ const full = path12.join(cwd, rel);
31033
31009
  let source;
31034
31010
  try {
31035
31011
  source = await fs3.readFile(full, "utf-8");
@@ -31178,9 +31154,9 @@ function findManifestPath() {
31178
31154
  const baseDir = typeof __dirname !== "undefined" ? __dirname : process.cwd();
31179
31155
  let dir = baseDir;
31180
31156
  for (let i = 0; i < 8; i++) {
31181
- const candidate = path10.join(dir, "agent-manifest.json");
31157
+ const candidate = path12.join(dir, "agent-manifest.json");
31182
31158
  if (fs__default.existsSync(candidate)) return candidate;
31183
- const parent = path10.dirname(dir);
31159
+ const parent = path12.dirname(dir);
31184
31160
  if (parent === dir) break;
31185
31161
  dir = parent;
31186
31162
  }
@@ -31322,8 +31298,8 @@ async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
31322
31298
  }
31323
31299
  function findAppDir() {
31324
31300
  const candidates = [
31325
- path10.join(process.cwd(), "app"),
31326
- path10.join(process.cwd(), "src", "app")
31301
+ path12.join(process.cwd(), "app"),
31302
+ path12.join(process.cwd(), "src", "app")
31327
31303
  ];
31328
31304
  for (const candidate of candidates) {
31329
31305
  if (existsSync(candidate)) {
@@ -31333,7 +31309,7 @@ function findAppDir() {
31333
31309
  return null;
31334
31310
  }
31335
31311
  function discoverPages(appDir, currentPath = "", pages = []) {
31336
- const fullPath = path10.join(appDir, currentPath);
31312
+ const fullPath = path12.join(appDir, currentPath);
31337
31313
  if (!existsSync(fullPath)) {
31338
31314
  return pages;
31339
31315
  }
@@ -31355,7 +31331,7 @@ function discoverPages(appDir, currentPath = "", pages = []) {
31355
31331
  });
31356
31332
  }
31357
31333
  for (const entry of entries) {
31358
- const entryPath = path10.join(fullPath, entry);
31334
+ const entryPath = path12.join(fullPath, entry);
31359
31335
  const stat = statSync(entryPath);
31360
31336
  if (stat.isDirectory()) {
31361
31337
  const folderName = entry.toLowerCase();
@@ -31368,21 +31344,21 @@ function discoverPages(appDir, currentPath = "", pages = []) {
31368
31344
  if (entry.startsWith("_")) {
31369
31345
  continue;
31370
31346
  }
31371
- discoverPages(appDir, path10.join(currentPath, entry), pages);
31347
+ discoverPages(appDir, path12.join(currentPath, entry), pages);
31372
31348
  }
31373
31349
  }
31374
31350
  return pages;
31375
31351
  }
31376
31352
  function findNextBuildDir() {
31377
31353
  const cwd = process.cwd();
31378
- const candidate = path10.join(cwd, ".next", "server", "app");
31354
+ const candidate = path12.join(cwd, ".next", "server", "app");
31379
31355
  return existsSync(candidate) ? candidate : null;
31380
31356
  }
31381
31357
  function extractPageContent(buildDir, pagePath) {
31382
31358
  const baseName = pagePath === "/" ? "index" : pagePath.replace(/^\//, "");
31383
31359
  const htmlCandidates = [
31384
- path10.join(buildDir, `${baseName}.html`),
31385
- path10.join(buildDir, baseName, "index.html")
31360
+ path12.join(buildDir, `${baseName}.html`),
31361
+ path12.join(buildDir, baseName, "index.html")
31386
31362
  ];
31387
31363
  let html = null;
31388
31364
  for (const candidate of htmlCandidates) {
@@ -31396,8 +31372,8 @@ function extractPageContent(buildDir, pagePath) {
31396
31372
  }
31397
31373
  }
31398
31374
  const rscCandidates = [
31399
- path10.join(buildDir, `${baseName}.rsc`),
31400
- path10.join(buildDir, baseName, "index.rsc")
31375
+ path12.join(buildDir, `${baseName}.rsc`),
31376
+ path12.join(buildDir, baseName, "index.rsc")
31401
31377
  ];
31402
31378
  let rsc = null;
31403
31379
  for (const candidate of rscCandidates) {
@@ -31508,7 +31484,7 @@ var BLOG_EXTENSIONS = [".mdx", ".md"];
31508
31484
  function findBlogDir() {
31509
31485
  const cwd = process.cwd();
31510
31486
  for (const dir of BLOG_DIRS) {
31511
- const full = path10.join(cwd, dir);
31487
+ const full = path12.join(cwd, dir);
31512
31488
  if (existsSync(full)) return full;
31513
31489
  }
31514
31490
  return null;
@@ -31518,7 +31494,7 @@ async function discoverBlogPosts(dir) {
31518
31494
  async function walk(currentDir) {
31519
31495
  const entries = readdirSync(currentDir);
31520
31496
  for (const entry of entries) {
31521
- const fullPath = path10.join(currentDir, entry);
31497
+ const fullPath = path12.join(currentDir, entry);
31522
31498
  const stat = statSync(fullPath);
31523
31499
  if (stat.isDirectory()) {
31524
31500
  await walk(fullPath);
@@ -31535,7 +31511,7 @@ async function discoverBlogPosts(dir) {
31535
31511
  date: frontmatter.date,
31536
31512
  tags: frontmatter.tags,
31537
31513
  author: frontmatter.author,
31538
- filePath: path10.relative(process.cwd(), fullPath)
31514
+ filePath: path12.relative(process.cwd(), fullPath)
31539
31515
  });
31540
31516
  }
31541
31517
  }
@@ -31568,7 +31544,7 @@ async function syncBlogToPortal(_apiUrl, _apiKey, _dryRun) {
31568
31544
  }
31569
31545
  const spinner = ora("Discovering blog posts...").start();
31570
31546
  const posts = await discoverBlogPosts(blogDir);
31571
- spinner.succeed(`Found ${posts.length} local markdown post(s) in ${path10.relative(process.cwd(), blogDir)}`);
31547
+ spinner.succeed(`Found ${posts.length} local markdown post(s) in ${path12.relative(process.cwd(), blogDir)}`);
31572
31548
  if (posts.length === 0) return;
31573
31549
  for (const post of posts.slice(0, 10)) {
31574
31550
  console.log(source_default.gray(` ${post.slug}: ${post.title || "(no title)"}`));
@@ -31585,11 +31561,11 @@ async function discoverSchemaUsage(appDir) {
31585
31561
  async function walk(currentDir, currentPath = "") {
31586
31562
  const entries = readdirSync(currentDir);
31587
31563
  for (const entry of entries) {
31588
- const fullPath = path10.join(currentDir, entry);
31564
+ const fullPath = path12.join(currentDir, entry);
31589
31565
  const stat = statSync(fullPath);
31590
31566
  if (stat.isDirectory()) {
31591
31567
  if (entry.startsWith(".") || entry === "node_modules") continue;
31592
- await walk(fullPath, path10.join(currentPath, entry));
31568
+ await walk(fullPath, path12.join(currentPath, entry));
31593
31569
  continue;
31594
31570
  }
31595
31571
  if (!/\.(tsx?|jsx?)$/.test(entry)) continue;
@@ -31603,7 +31579,7 @@ async function discoverSchemaUsage(appDir) {
31603
31579
  pagePath: pathMatch[1],
31604
31580
  schemaTypes: ["managed"],
31605
31581
  source: "ManagedSchema",
31606
- filePath: path10.relative(process.cwd(), fullPath)
31582
+ filePath: path12.relative(process.cwd(), fullPath)
31607
31583
  });
31608
31584
  }
31609
31585
  }
@@ -31621,7 +31597,7 @@ async function discoverSchemaUsage(appDir) {
31621
31597
  pagePath,
31622
31598
  schemaTypes: [...new Set(types)],
31623
31599
  source: "json-ld",
31624
- filePath: path10.relative(process.cwd(), fullPath)
31600
+ filePath: path12.relative(process.cwd(), fullPath)
31625
31601
  });
31626
31602
  }
31627
31603
  }
@@ -31681,8 +31657,8 @@ async function apiRoutesCommand(options) {
31681
31657
  console.log("");
31682
31658
  process.exit(1);
31683
31659
  }
31684
- const routeDir = path10.join(appDir, "_uptrade", "api", "[...path]");
31685
- const routeFile = path10.join(routeDir, "route.ts");
31660
+ const routeDir = path12.join(appDir, "_uptrade", "api", "[...path]");
31661
+ const routeFile = path12.join(routeDir, "route.ts");
31686
31662
  if (existsSync(routeFile) && !options.force) {
31687
31663
  console.log(source_default.yellow(" \u26A0 API routes already exist"));
31688
31664
  console.log(source_default.gray(` ${routeFile}`));
@@ -31719,8 +31695,8 @@ async function apiRoutesCommand(options) {
31719
31695
  }
31720
31696
  function findAppDir2() {
31721
31697
  const candidates = [
31722
- path10.join(process.cwd(), "app"),
31723
- path10.join(process.cwd(), "src", "app")
31698
+ path12.join(process.cwd(), "app"),
31699
+ path12.join(process.cwd(), "src", "app")
31724
31700
  ];
31725
31701
  for (const candidate of candidates) {
31726
31702
  if (existsSync(candidate)) {
@@ -31833,12 +31809,12 @@ async function handleRequest(
31833
31809
  `;
31834
31810
  }
31835
31811
  function detectPackageManager(cwd) {
31836
- if (existsSync(path10.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
31837
- if (existsSync(path10.join(cwd, "yarn.lock"))) return "yarn";
31812
+ if (existsSync(path12.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
31813
+ if (existsSync(path12.join(cwd, "yarn.lock"))) return "yarn";
31838
31814
  return "npm";
31839
31815
  }
31840
31816
  async function run6(ctx, options) {
31841
- if (!existsSync(path10.join(ctx.cwd, "package.json"))) {
31817
+ if (!existsSync(path12.join(ctx.cwd, "package.json"))) {
31842
31818
  throw new UsageError(
31843
31819
  "NO_PACKAGE_JSON",
31844
31820
  "No package.json found",
@@ -31883,12 +31859,12 @@ async function installCommand(options) {
31883
31859
  await runCommand(ctx, (c) => run6(c, options), renderHuman4);
31884
31860
  }
31885
31861
  function detectPackageManager2(cwd) {
31886
- if (existsSync(path10.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
31887
- if (existsSync(path10.join(cwd, "yarn.lock"))) return "yarn";
31862
+ if (existsSync(path12.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
31863
+ if (existsSync(path12.join(cwd, "yarn.lock"))) return "yarn";
31888
31864
  return "npm";
31889
31865
  }
31890
31866
  async function run7(ctx, options) {
31891
- const pkgPath = path10.join(ctx.cwd, "package.json");
31867
+ const pkgPath = path12.join(ctx.cwd, "package.json");
31892
31868
  if (!existsSync(pkgPath)) {
31893
31869
  throw new UsageError("NO_PACKAGE_JSON", "No package.json found", "Run this from your project root.");
31894
31870
  }
@@ -31950,7 +31926,7 @@ async function scaffoldCommand(options) {
31950
31926
  }
31951
31927
  const files = [
31952
31928
  {
31953
- path: path10.join(appDir, "sitemap.ts"),
31929
+ path: path12.join(appDir, "sitemap.ts"),
31954
31930
  label: "Sitemap",
31955
31931
  content: `import { createSitemap } from '@sonordev/site-kit/sitemap'
31956
31932
 
@@ -31965,7 +31941,7 @@ export default createSitemap({
31965
31941
  `
31966
31942
  },
31967
31943
  {
31968
- path: path10.join(appDir, "robots.txt", "route.ts"),
31944
+ path: path12.join(appDir, "robots.txt", "route.ts"),
31969
31945
  label: "Robots.txt",
31970
31946
  content: `import { createRobots } from '@sonordev/site-kit/robots'
31971
31947
 
@@ -31973,7 +31949,7 @@ export const GET = createRobots({})
31973
31949
  `
31974
31950
  },
31975
31951
  {
31976
- path: path10.join(appDir, "llms.txt", "route.ts"),
31952
+ path: path12.join(appDir, "llms.txt", "route.ts"),
31977
31953
  label: "llms.txt",
31978
31954
  content: `import { createLLMsTxtHandler } from '@sonordev/site-kit/llms'
31979
31955
 
@@ -31981,7 +31957,7 @@ export const GET = createLLMsTxtHandler({ preferStatic: true })
31981
31957
  `
31982
31958
  },
31983
31959
  {
31984
- path: path10.join(appDir, "llms-full.txt", "route.ts"),
31960
+ path: path12.join(appDir, "llms-full.txt", "route.ts"),
31985
31961
  label: "llms-full.txt",
31986
31962
  content: `import { createLLMsFullTxtHandler } from '@sonordev/site-kit/llms'
31987
31963
 
@@ -31992,7 +31968,7 @@ export const GET = createLLMsFullTxtHandler({ preferStatic: true })
31992
31968
  if (!options.minimal) {
31993
31969
  files.push(
31994
31970
  {
31995
- path: path10.join(cwd, "proxy.ts"),
31971
+ path: path12.join(cwd, "proxy.ts"),
31996
31972
  label: "Proxy (security headers; redirects resolve at the 404 boundary)",
31997
31973
  content: `import { createProxy } from '@sonordev/site-kit/proxy'
31998
31974
 
@@ -32012,7 +31988,7 @@ export const config = {
32012
31988
  `
32013
31989
  },
32014
31990
  {
32015
- path: path10.join(appDir, "manifest.webmanifest", "route.ts"),
31991
+ path: path12.join(appDir, "manifest.webmanifest", "route.ts"),
32016
31992
  label: "PWA Manifest",
32017
31993
  content: `import { createManifest } from '@sonordev/site-kit/manifest'
32018
31994
 
@@ -32020,7 +31996,7 @@ export const GET = createManifest()
32020
31996
  `
32021
31997
  },
32022
31998
  {
32023
- path: path10.join(appDir, "not-found.tsx"),
31999
+ path: path12.join(appDir, "not-found.tsx"),
32024
32000
  label: "404 Page (resolves managed redirects)",
32025
32001
  content: `import { redirect, permanentRedirect } from 'next/navigation'
32026
32002
  import { resolveManagedRedirect } from '@sonordev/site-kit/redirects/not-found'
@@ -32060,7 +32036,7 @@ export default async function NotFound() {
32060
32036
  `
32061
32037
  },
32062
32038
  {
32063
- path: path10.join(appDir, "error.tsx"),
32039
+ path: path12.join(appDir, "error.tsx"),
32064
32040
  label: "Error Boundary",
32065
32041
  content: `'use client'
32066
32042
 
@@ -32100,7 +32076,7 @@ export default function Error({
32100
32076
  `
32101
32077
  },
32102
32078
  {
32103
- path: path10.join(cwd, "og.config.ts"),
32079
+ path: path12.join(cwd, "og.config.ts"),
32104
32080
  label: "OG card config (run: sonor-setup og)",
32105
32081
  content: `import { defineOgCard } from '@sonordev/site-kit/og'
32106
32082
 
@@ -32129,7 +32105,7 @@ export default defineOgCard({
32129
32105
  // .env.local, not .env.example: one real env file per project. The
32130
32106
  // deployer copies these values into the host's env settings. Skipped
32131
32107
  // when the file already exists, so real keys are never touched.
32132
- path: path10.join(cwd, ".env.local"),
32108
+ path: path12.join(cwd, ".env.local"),
32133
32109
  label: ".env.local",
32134
32110
  content: `# ===================================
32135
32111
  # @sonordev/site-kit \u2014 Environment Variables
@@ -32151,7 +32127,7 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
32151
32127
  if (options.dryRun) {
32152
32128
  console.log(source_default.yellow(" [DRY RUN] Would create:"));
32153
32129
  for (const f of files) {
32154
- const rel = path10.relative(cwd, f.path);
32130
+ const rel = path12.relative(cwd, f.path);
32155
32131
  const exists = existsSync(f.path);
32156
32132
  console.log(
32157
32133
  source_default.gray(` ${rel}`) + (exists ? source_default.yellow(" (exists, would skip)") : "")
@@ -32166,13 +32142,13 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
32166
32142
  for (const f of files) {
32167
32143
  try {
32168
32144
  if (existsSync(f.path) && !options.force) {
32169
- spinner.warn(`Skipped (exists): ${path10.relative(cwd, f.path)}`);
32145
+ spinner.warn(`Skipped (exists): ${path12.relative(cwd, f.path)}`);
32170
32146
  skipped++;
32171
32147
  continue;
32172
32148
  }
32173
- await fs3.mkdir(path10.dirname(f.path), { recursive: true });
32149
+ await fs3.mkdir(path12.dirname(f.path), { recursive: true });
32174
32150
  await fs3.writeFile(f.path, f.content, "utf-8");
32175
- spinner.succeed(`${f.label}: ${path10.relative(cwd, f.path)}`);
32151
+ spinner.succeed(`${f.label}: ${path12.relative(cwd, f.path)}`);
32176
32152
  created++;
32177
32153
  } catch (err) {
32178
32154
  spinner.fail(`Failed: ${f.path}`);
@@ -32221,8 +32197,8 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
32221
32197
  async function findAppDir3() {
32222
32198
  const cwd = process.cwd();
32223
32199
  const candidates = [
32224
- path10.join(cwd, "app"),
32225
- path10.join(cwd, "src", "app")
32200
+ path12.join(cwd, "app"),
32201
+ path12.join(cwd, "src", "app")
32226
32202
  ];
32227
32203
  for (const dir of candidates) {
32228
32204
  if (existsSync(dir)) return dir;
@@ -32246,17 +32222,17 @@ async function readIfExists(p) {
32246
32222
  }
32247
32223
  }
32248
32224
  async function ensureLlmsRouteFiles(appDir, dryRun) {
32249
- const llms = path10.join(appDir, "llms.txt", "route.ts");
32250
- const llmsFull = path10.join(appDir, "llms-full.txt", "route.ts");
32225
+ const llms = path12.join(appDir, "llms.txt", "route.ts");
32226
+ const llmsFull = path12.join(appDir, "llms-full.txt", "route.ts");
32251
32227
  let n5 = 0;
32252
32228
  if (dryRun) return 0;
32253
32229
  if (!existsSync(llms)) {
32254
- await fs3.mkdir(path10.dirname(llms), { recursive: true });
32230
+ await fs3.mkdir(path12.dirname(llms), { recursive: true });
32255
32231
  await fs3.writeFile(llms, LLMS_ROUTE, "utf-8");
32256
32232
  n5++;
32257
32233
  }
32258
32234
  if (!existsSync(llmsFull)) {
32259
- await fs3.mkdir(path10.dirname(llmsFull), { recursive: true });
32235
+ await fs3.mkdir(path12.dirname(llmsFull), { recursive: true });
32260
32236
  await fs3.writeFile(llmsFull, LLMS_FULL_ROUTE, "utf-8");
32261
32237
  n5++;
32262
32238
  }
@@ -32290,9 +32266,9 @@ async function geoCommand(options) {
32290
32266
  console.log(source_default.red(" \u2717 No app directory (app/ or src/app/)"));
32291
32267
  process.exit(1);
32292
32268
  }
32293
- const llms = path10.join(appDir, "llms.txt", "route.ts");
32294
- const llmsFull = path10.join(appDir, "llms-full.txt", "route.ts");
32295
- const sitemap = path10.join(appDir, "sitemap.ts");
32269
+ const llms = path12.join(appDir, "llms.txt", "route.ts");
32270
+ const llmsFull = path12.join(appDir, "llms-full.txt", "route.ts");
32271
+ const sitemap = path12.join(appDir, "sitemap.ts");
32296
32272
  let allOk = true;
32297
32273
  const row = (label, pass) => {
32298
32274
  if (!pass) allOk = false;
@@ -32311,9 +32287,9 @@ async function geoCommand(options) {
32311
32287
  row("sitemap.ts lists llms URLs", false);
32312
32288
  }
32313
32289
  const nextConfigs = [
32314
- path10.join(cwd, "next.config.ts"),
32315
- path10.join(cwd, "next.config.mjs"),
32316
- path10.join(cwd, "next.config.js")
32290
+ path12.join(cwd, "next.config.ts"),
32291
+ path12.join(cwd, "next.config.mjs"),
32292
+ path12.join(cwd, "next.config.js")
32317
32293
  ];
32318
32294
  let nextCfg = "";
32319
32295
  for (const p of nextConfigs) {
@@ -32323,9 +32299,9 @@ async function geoCommand(options) {
32323
32299
  }
32324
32300
  }
32325
32301
  const layoutCandidates = [
32326
- path10.join(appDir, "layout.tsx"),
32327
- path10.join(appDir, "layout.jsx"),
32328
- path10.join(appDir, "layout.js")
32302
+ path12.join(appDir, "layout.tsx"),
32303
+ path12.join(appDir, "layout.jsx"),
32304
+ path12.join(appDir, "layout.js")
32329
32305
  ];
32330
32306
  let layoutTxt = "";
32331
32307
  for (const p of layoutCandidates) {
@@ -32385,8 +32361,8 @@ async function geoCommand(options) {
32385
32361
  }
32386
32362
 
32387
32363
  // src/cli/index.ts
32388
- (0, import_dotenv.config)({ path: ".env.local", quiet: true });
32389
- (0, import_dotenv.config)({ path: ".env", quiet: true });
32364
+ (0, import_dotenv2.config)({ path: ".env.local", quiet: true });
32365
+ (0, import_dotenv2.config)({ path: ".env", quiet: true });
32390
32366
  var program2 = new Command();
32391
32367
  program2.name("sonor-setup").description("Setup + verification toolchain for @sonordev/site-kit").version(SITE_KIT_VERSION);
32392
32368
  withAgentFlags(